forked from root-project/root
-
Notifications
You must be signed in to change notification settings - Fork 0
/
TEveTriangleSet.cxx
192 lines (156 loc) · 5.52 KB
/
TEveTriangleSet.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
// @(#)root/eve:$Id$
// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
/*************************************************************************
* Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#include "TEveTriangleSet.h"
#include "TEveRGBAPalette.h"
#include "TEveManager.h"
#include "TMath.h"
#include "TVector3.h"
#include "TRandom3.h"
/** \class TEveTriangleSet
\ingroup TEve
Made from a list of vertices and a list of triangles (triplets of
vertex indices).
If input is composed from triangles with direct vertex coordinates
one should consider finding all occurrences of the same vertex
and specifying it only once.
*/
ClassImp(TEveTriangleSet);
////////////////////////////////////////////////////////////////////////////////
/// Constructor.
TEveTriangleSet::TEveTriangleSet(Int_t nv, Int_t nt, Bool_t norms, Bool_t cols) :
TEveElementList("TEveTriangleSet", "", kTRUE),
fNVerts (nv), fVerts(nullptr),
fNTrings (nt), fTrings(nullptr), fTringNorms(nullptr), fTringCols(nullptr)
{
InitMainTrans();
fVerts = new Float_t[3*fNVerts];
fTrings = new Int_t [3*fNTrings];
fTringNorms = (norms) ? new Float_t[3*fNTrings] : nullptr;
fTringCols = (cols) ? new UChar_t[3*fNTrings] : nullptr;
}
////////////////////////////////////////////////////////////////////////////////
/// Destructor.
TEveTriangleSet::~TEveTriangleSet()
{
delete [] fVerts;
delete [] fTrings;
delete [] fTringNorms;
delete [] fTringCols;
}
////////////////////////////////////////////////////////////////////////////////
/// Generate triangle normals via cross product of triangle edges.
void TEveTriangleSet::GenerateTriangleNormals()
{
if (fTringNorms == nullptr) fTringNorms = new Float_t[3*fNTrings];
TVector3 e1, e2, n;
Float_t *norm = fTringNorms;
Int_t *tring = fTrings;
for(Int_t t=0; t<fNTrings; ++t, norm+=3, tring+=3)
{
Float_t* v0 = Vertex(tring[0]);
Float_t* v1 = Vertex(tring[1]);
Float_t* v2 = Vertex(tring[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(norm);
}
}
////////////////////////////////////////////////////////////////////////////////
/// Assign random colors to all triangles.
void TEveTriangleSet::GenerateRandomColors()
{
if (fTringCols == nullptr) fTringCols = new UChar_t[3*fNTrings];
TRandom r;
r.SetSeed(0);
UChar_t *col = fTringCols;
for(Int_t t=0; t<fNTrings; ++t, col+=3)
{
col[0] = (UChar_t) r.Uniform(60, 255);
col[1] = (UChar_t) r.Uniform(60, 255);
col[2] = (UChar_t) r.Uniform(60, 255);
}
}
////////////////////////////////////////////////////////////////////////////////
/// Generate triangle colors by the z-component of the normal.
/// Current palette is taken from gStyle.
void TEveTriangleSet::GenerateZNormalColors(Float_t fac, Int_t min, Int_t max,
Bool_t interp, Bool_t wrap)
{
if (fTringCols == nullptr) fTringCols = new UChar_t[3*fNTrings];
if (fTringNorms == nullptr) GenerateTriangleNormals();
TEveRGBAPalette pal(min, max, interp, wrap);
UChar_t *col = fTringCols;
Float_t *norm = fTringNorms;
for(Int_t t=0; t<fNTrings; ++t, col+=3, norm+=3)
{
Int_t v = TMath::Nint(fac * norm[2]);
pal.ColorFromValue(v, col, kFALSE);
}
gEve->Redraw3D();
}
////////////////////////////////////////////////////////////////////////////////
/// Compute bounding box.
/// Virtual from TAttBBox.
void TEveTriangleSet::ComputeBBox()
{
if (fNVerts <= 0) {
BBoxZero();
return;
}
BBoxInit();
Float_t* v = fVerts;
for (Int_t i=0; i<fNVerts; ++i, v += 3)
BBoxCheckPoint(v);
}
////////////////////////////////////////////////////////////////////////////////
/// Paint this object. Only direct rendering is supported.
void TEveTriangleSet::Paint(Option_t*)
{
PaintStandard(this);
}
////////////////////////////////////////////////////////////////////////////////
/// Read a simple ascii input file describing vertices and triangles.
TEveTriangleSet* TEveTriangleSet::ReadTrivialFile(const char* file)
{
static const TEveException kEH("TEveTriangleSet::ReadTrivialFile ");
FILE* f = fopen(file, "r");
if (f == nullptr) {
::Error(kEH, "file '%s' not found.", file);
return nullptr;
}
Int_t nv, nt;
if (fscanf(f, "%d %d", &nv, &nt) != 2) {
fclose(f);
throw kEH + "Reading nv, nt failed.";
}
if (nv < 0 || nt < 0) {
fclose(f);
throw kEH + "Negative number of vertices / triangles specified.";
}
TEveTriangleSet* ts = new TEveTriangleSet(nv, nt);
Float_t *vtx = ts->Vertex(0);
for (Int_t i=0; i<nv; ++i, vtx+=3) {
if (fscanf(f, "%f %f %f", &vtx[0], &vtx[1], &vtx[2]) != 3) {
fclose(f);
throw kEH + TString::Format("Reading vertex data %d failed.", i);
}
}
Int_t *tngl = ts->Triangle(0);
for (Int_t i=0; i<nt; ++i, tngl+=3) {
if (fscanf(f, "%d %d %d", &tngl[0], &tngl[1], &tngl[2]) != 3) {
fclose(f);
throw kEH + TString::Format("Reading triangle data %d failed.", i);
}
}
fclose(f);
return ts;
}