--- /dev/null
+// $Header$
+
+#include "TriangleSet.h"
+
+#include <TVector3.h>
+#include <TRandom3.h>
+#include <TVirtualPad.h>
+#include <TVirtualViewer3D.h>
+#include <TBuffer3D.h>
+#include <TBuffer3DTypes.h>
+#include <TGeoMatrix.h>
+
+using namespace Reve;
+
+
+ClassImp(TriangleSet)
+
+TriangleSet::TriangleSet(Int_t nv, Int_t nt, Bool_t norms, Bool_t cols) :
+ RenderElement(fColor),
+ TNamed("TriangleSet", 0),
+ fNVerts (nv),
+ fNTrings (nt),
+ fColor (2)
+{
+ fVerts = new Float_t[3*fNVerts];
+ fTrings = new Int_t [3*fNTrings];
+ fTringNorms = (norms) ? new Float_t[3*fNTrings] : 0;
+ fTringCols = (cols) ? new UChar_t[3*fNTrings] : 0;
+}
+
+TriangleSet::~TriangleSet()
+{
+ delete [] fVerts;
+ delete [] fTrings;
+ delete [] fTringNorms;
+ delete [] fTringCols;
+}
+
+/**************************************************************************/
+
+void TriangleSet::GenerateTriangleNormals()
+{
+ if (fTringNorms == 0) fTringNorms = new Float_t[3*fNTrings];
+
+ TVector3 e1, e2, n;
+ Float_t *N = fTringNorms;
+ Int_t *T = fTrings;
+ for(Int_t t=0; t<fNTrings; ++t, N+=3, T+=3)
+ {
+ Float_t* v0 = Vertex(T[0]);
+ Float_t* v1 = Vertex(T[1]);
+ Float_t* v2 = Vertex(T[2]);
+ e1.SetXYZ(v1[0]-v0[0], v1[1]-v0[1], v1[2]-v0[2]);
+ e2.SetXYZ(v2[0]-v0[0], v2[1]-v0[1], v2[2]-v0[2]);
+ n = e1.Cross(e2);
+ n.SetMag(1);
+ n.GetXYZ(N);
+ }
+}
+
+void TriangleSet::GenerateRandomColors()
+{
+ if (fTringCols == 0) fTringCols = new UChar_t[3*fNTrings];
+
+ TRandom r;
+ r.SetSeed(0);
+ UChar_t *C = fTringCols;
+ for(Int_t t=0; t<fNTrings; ++t, C+=3)
+ {
+ C[0] = (UChar_t) r.Uniform(60, 255);
+ C[1] = (UChar_t) r.Uniform(60, 255);
+ C[2] = (UChar_t) r.Uniform(60, 255);
+ }
+}
+
+/**************************************************************************/
+
+void TriangleSet::ComputeBBox()
+{
+ if (fNVerts <= 0) {
+ BBoxZero();
+ return;
+ }
+
+ BBoxInit();
+ Float_t* v = fVerts;
+ for (Int_t i=0; i<fNVerts; ++i, v += 3)
+ BBoxCheckPoint(v);
+}
+
+void TriangleSet::Paint(Option_t* )
+{
+ TBuffer3D buffer(TBuffer3DTypes::kGeneric);
+
+ // Section kCore
+ buffer.fID = this;
+ buffer.fColor = fColor;
+ buffer.fTransparency = 0;
+ fHMTrans.SetBuffer3D(buffer);
+ buffer.SetSectionsValid(TBuffer3D::kCore);
+
+ // We fill kCore on first pass and try with viewer
+ Int_t reqSections = gPad->GetViewer3D()->AddObject(buffer);
+ if (reqSections == TBuffer3D::kNone) {
+ return;
+ }
+
+ Error("TriangleSet::Paint", "only direct OpenGL rendering supported.");
+}
+
+/**************************************************************************/
+
+#include <stdio.h>
+
+TriangleSet* TriangleSet::ReadTrivialFile(const char* file)
+{
+ FILE* f = fopen(file, "r");
+
+ Int_t nv, nt;
+ fscanf(f, "%d %d", &nv, &nt);
+
+ TriangleSet* ts = new TriangleSet(nv, nt);
+
+ Float_t *V = ts->Vertex(0);
+ for (Int_t i=0; i<nv; ++i) {
+ fscanf(f, "%f %f %f", V++, V++, V++);
+ }
+
+ Int_t *T = ts->Triangle(0);
+ for (Int_t i=0; i<nt; ++i) {
+ fscanf(f, "%d %d %d", T++, T++, T++);
+ }
+
+ fclose(f);
+
+ return ts;
+}
--- /dev/null
+// $Header$
+
+#ifndef REVE_TriangleSet_H
+#define REVE_TriangleSet_H
+
+#include "RenderElement.h"
+#include <TNamed.h>
+#include <TAttBBox.h>
+
+#include "ZTrans.h"
+
+class TGeoMatrix;
+
+namespace Reve {
+
+class TriangleSet : public RenderElement,
+ public TNamed,
+ public TAttBBox
+{
+ friend class TriangleSetEditor;
+ friend class TriangleSetGL;
+
+protected:
+
+ // Vertex data
+ Int_t fNVerts;
+ Float_t* fVerts; //[3*fNVerts]
+
+ // Triangle data
+ Int_t fNTrings;
+ Int_t* fTrings; //[3*fNTrings]
+ Float_t* fTringNorms; //[3*fNTrings]
+ UChar_t* fTringCols; //[3*fNTrings]
+
+ // --------------------------------------------------------------
+
+ Color_t fColor;
+ ZTrans fHMTrans;
+
+public:
+
+ TriangleSet(Int_t nv, Int_t nt, Bool_t norms=false, Bool_t cols=false);
+ ~TriangleSet();
+
+ virtual Bool_t CanEditMainColor() { return kTRUE; }
+
+ Float_t* Vertex(Int_t i) { return &(fVerts[3*i]); }
+ Int_t* Triangle(Int_t i) { return &(fTrings[3*i]); }
+ Float_t* TriangleNormal(Int_t i) { return &(fTringNorms[3*i]); }
+ UChar_t* TriangleColor(Int_t i) { return &(fTringCols[3*i]); }
+
+ void SetVertex(Int_t i, Float_t x, Float_t y, Float_t z)
+ { Float_t* v = Vertex(i); v[0] = x; v[1] = y; v[2] = z; }
+ void SetTriangle(Int_t i, Int_t v0, Int_t v1, Int_t v2)
+ { Int_t* t = Triangle(i); t[0] = v0; t[1] = v1; t[2] = v2; }
+ void SetTriangleColor(Int_t i, UChar_t r, UChar_t g, UChar_t b, UChar_t a=255)
+ { UChar_t* c = TriangleColor(i); c[0] = r; c[1] = g; c[2] = b; c[3] = a; }
+
+ void GenerateTriangleNormals();
+ void GenerateRandomColors();
+
+ virtual void ComputeBBox();
+ virtual void Paint(Option_t* = "");
+
+ Color_t GetColor() const { return fColor; }
+ void SetColor(Color_t c) { fColor = c; }
+
+ ZTrans& RefHMTrans() { return fHMTrans; }
+ void SetTransMatrix(Double_t* carr) { fHMTrans.SetFrom(carr); }
+ void SetTransMatrix(const TGeoMatrix& mat) { fHMTrans.SetFrom(mat); }
+
+ static TriangleSet* ReadTrivialFile(const char* file);
+
+ ClassDef(TriangleSet, 0)
+}; // endclass TriangleSet
+
+}
+
+#endif
--- /dev/null
+// $Header$
+
+#include "TriangleSetEditor.h"
+#include <Reve/TriangleSet.h>
+#include <Reve/ZTransEditor.h>
+
+#include <TVirtualPad.h>
+#include <TColor.h>
+
+#include <TGLabel.h>
+#include <TGButton.h>
+#include <TGNumberEntry.h>
+#include <TGColorSelect.h>
+#include <TGDoubleSlider.h>
+
+using namespace Reve;
+
+//______________________________________________________________________
+// TriangleSetEditor
+//
+
+ClassImp(TriangleSetEditor)
+
+TriangleSetEditor::TriangleSetEditor(const TGWindow *p, Int_t width, Int_t height,
+ UInt_t options, Pixel_t back) :
+ TGedFrame(p, width, height, options | kVerticalFrame, back),
+ fM(0),
+ fHMTrans(0)
+{
+ MakeTitle("TriangleSet");
+
+ fHMTrans = new ZTransSubEditor(this);
+ fHMTrans->Connect("UseTrans()", "Reve::TriangleSetEditor", this, "Update()");
+ fHMTrans->Connect("TransChanged()", "Reve::TriangleSetEditor", this, "Update()");
+ AddFrame(fHMTrans, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 2, 0, 0, 0));
+}
+
+TriangleSetEditor::~TriangleSetEditor()
+{
+ delete fHMTrans;
+}
+
+/**************************************************************************/
+
+void TriangleSetEditor::SetModel(TObject* obj)
+{
+ fM = dynamic_cast<TriangleSet*>(obj);
+
+ fHMTrans->SetDataFromTrans(&fM->fHMTrans);
+}
--- /dev/null
+// $Header$
+
+#ifndef REVE_TriangleSetEditor_H
+#define REVE_TriangleSetEditor_H
+
+#include <TGedFrame.h>
+
+class TGCheckButton;
+class TGNumberEntry;
+class TGColorSelect;
+
+namespace Reve {
+
+class ZTransSubEditor;
+class TriangleSet;
+
+class TriangleSetEditor : public TGedFrame
+{
+private:
+ TriangleSetEditor(const TriangleSetEditor&); // Not implemented
+ TriangleSetEditor& operator=(const TriangleSetEditor&); // Not implemented
+
+protected:
+ TriangleSet* fM; // fModel dynamic-casted to TriangleSetEditor
+
+ ZTransSubEditor *fHMTrans;
+
+public:
+ TriangleSetEditor(const TGWindow* p=0, Int_t width=170, Int_t height=30, UInt_t options = kChildFrame, Pixel_t back=GetDefaultFrameBackground());
+ virtual ~TriangleSetEditor();
+
+ virtual void SetModel(TObject* obj);
+
+ ClassDef(TriangleSetEditor, 1); // Editor for TriangleSet
+}; // endclass TriangleSetEditor
+
+}
+
+#endif
--- /dev/null
+// $Header$
+
+#include "TriangleSetGL.h"
+#include "TriangleSet.h"
+#include <TVector3.h>
+
+#include <TGLDrawFlags.h>
+
+#ifdef WIN32
+#include "Windows4root.h"
+#endif
+#include <GL/gl.h>
+
+//______________________________________________________________________
+// TriangleSetGL
+//
+
+using namespace Reve;
+
+ClassImp(TriangleSetGL)
+
+TriangleSetGL::TriangleSetGL() : TGLObject(), fM(0)
+{
+ // fCached = false; // Disable display list.
+}
+
+TriangleSetGL::~TriangleSetGL()
+{}
+
+/**************************************************************************/
+
+Bool_t TriangleSetGL::SetModel(TObject* obj)
+{
+ if(SetModelCheckClass(obj, TriangleSet::Class())) {
+ fM = dynamic_cast<TriangleSet*>(obj);
+ return kTRUE;
+ }
+ return kFALSE;
+}
+
+void TriangleSetGL::SetBBox()
+{
+ // !! This ok if master sub-classed from TAttBBox
+ SetAxisAlignedBBox(((TriangleSet*)fExternalObj)->AssertBBox());
+}
+
+/**************************************************************************/
+
+void TriangleSetGL::DirectDraw(const TGLDrawFlags& /*flags*/) const
+{
+ TriangleSet& TS = *fM;
+ Bool_t isScaled = TS.fHMTrans.IsScale();
+
+ GLint ex_shade_model;
+ glGetIntegerv(GL_SHADE_MODEL, &ex_shade_model);
+ glShadeModel(GL_FLAT);
+
+ glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
+
+ glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+ glEnable(GL_COLOR_MATERIAL);
+ glPolygonMode(GL_FRONT, GL_FILL);
+ glPolygonMode(GL_BACK, GL_LINE);
+ glDisable(GL_CULL_FACE);
+ if (isScaled) glEnable(GL_NORMALIZE);
+ glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
+ glVertexPointer(3, GL_FLOAT, 0, TS.fVerts);
+ glEnableClientState(GL_VERTEX_ARRAY);
+
+ Int_t* T = TS.fTrings;
+ Float_t* N = TS.fTringNorms;
+ UChar_t* C = TS.fTringCols;
+
+ TVector3 e1, e2, n;
+
+ glBegin(GL_TRIANGLES);
+ for(Int_t t=0; t<TS.fNTrings; ++t) {
+ if (N) {
+ glNormal3fv(N); N += 3;
+ } else {
+ Float_t* v0 = TS.Vertex(T[0]);
+ Float_t* v1 = TS.Vertex(T[1]);
+ Float_t* v2 = TS.Vertex(T[2]);
+ e1.SetXYZ(v1[0]-v0[0], v1[1]-v0[1], v1[2]-v0[2]);
+ e2.SetXYZ(v2[0]-v0[0], v2[1]-v0[1], v2[2]-v0[2]);
+ n = e1.Cross(e2);
+ if (!isScaled) n.SetMag(1);
+ glNormal3d(n.x(), n.y(), n.z());
+ }
+ if (C) {
+ glColor3ubv(C); C += 3;
+ }
+ glArrayElement(T[0]);
+ glArrayElement(T[1]);
+ glArrayElement(T[2]);
+ T += 3;
+ }
+ glEnd();
+
+ glPopClientAttrib();
+ glPopAttrib();
+ glShadeModel(ex_shade_model);
+}
--- /dev/null
+// $Header$
+
+#ifndef REVE_TriangleSetGL_H
+#define REVE_TriangleSetGL_H
+
+#include <TGLObject.h>
+
+class TGLViewer;
+class TGLScene;
+
+namespace Reve {
+
+class TriangleSet;
+
+class TriangleSetGL : public TGLObject
+{
+private:
+ TriangleSetGL(const TriangleSetGL&); // Not implemented
+ TriangleSetGL& operator=(const TriangleSetGL&); // Not implemented
+
+protected:
+ TriangleSet* fM; // fModel dynamic-casted to TriangleSetGL
+
+ virtual void DirectDraw(const TGLDrawFlags & flags) const;
+
+public:
+ TriangleSetGL();
+ virtual ~TriangleSetGL();
+
+ virtual Bool_t SetModel(TObject* obj);
+ virtual void SetBBox();
+
+ // To support two-level selection
+ // virtual Bool_t SupportsSecondarySelect() const { return kTRUE; }
+ // virtual void ProcessSelection(UInt_t* ptr, TGLViewer*, TGLScene*);
+
+ ClassDef(TriangleSetGL, 0);
+}; // endclass TriangleSetGL
+
+}
+
+#endif