ATLAS Offline Software
SoTessellated.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include <Inventor/SbBox.h>
8 #include <Inventor/actions/SoPickAction.h>
9 #include <Inventor/nodes/SoSeparator.h>
10 #include <Inventor/nodes/SoIndexedFaceSet.h>
11 #include <Inventor/nodes/SoIndexedLineSet.h>
12 #include <Inventor/SoPrimitiveVertex.h>
13 #include <Inventor/C/glue/gl.h>
14 #include <Inventor/elements/SoGLCacheContextElement.h>
15 
16 SO_NODE_SOURCE(SoTessellated)
17 
18 //____________________________________________________________________
19 void SoTessellated::initClass()
20 {
21  [[maybe_unused]] static const bool didInit = [&]() {
22  SO_NODE_INIT_CLASS(SoTessellated, SoShape, "Shape");
23  return true;
24  }();
25 }
26 
27 //____________________________________________________________________
29 {
30  SO_NODE_CONSTRUCTOR(SoTessellated);
31  SO_NODE_ADD_FIELD(drawEdgeLines, (false));
32  SO_NODE_ADD_FIELD(forceEdgeLinesInBaseColour, (true));
33  SO_NODE_ADD_FIELD(alternateRep,(NULL));
34  setNodeType(EXTENSION);
35 }
36 
37 //____________________________________________________________________
39 {
40 }
41 
42 //____________________________________________________________________
43 void SoTessellated::addTriangularFacet(double x1, double y1, double z1,
44  double x2, double y2, double z2,
45  double x3, double y3, double z3)
46 {
47  m_points.push_back(x1);
48  m_points.push_back(y1);
49  m_points.push_back(z1);
50  m_points.push_back(x2);
51  m_points.push_back(y2);
52  m_points.push_back(z2);
53  m_points.push_back(x3);
54  m_points.push_back(y3);
55  m_points.push_back(z3);
56 
57  // Normal (v2-v1)(x)(v3-v1)
58  const double edge1X(x2-x1), edge1Y(y2-y1), edge1Z(z2-z1);
59  const double edge2X(x3-x1), edge2Y(y3-y1), edge2Z(z3-z1);
60  double nx(edge1Y*edge2Z-edge1Z*edge2Y);
61  double ny(edge1Z*edge2X-edge1X*edge2Z);
62  double nz(edge1X*edge2Y-edge1Y*edge2X);
63  double nl(nx*nx+ny*ny+nz*nz);
64  const double s(1.0/sqrt(nl));
65  m_normals.push_back(nx*s);
66  m_normals.push_back(ny*s);
67  m_normals.push_back(nz*s);
68 }
69 
70 //____________________________________________________________________
71 void SoTessellated::addQuadrangularFacet(double x1, double y1, double z1,
72  double x2, double y2, double z2,
73  double x3, double y3, double z3,
74  double x4, double y4, double z4)
75 {
76  addTriangularFacet(x1,y1,z1,x2,y2,z2,x3,y3,z3);
77  addTriangularFacet(x3,y3,z3,x4,y4,z4,x1,y1,z1);
78 }
79 
80 //____________________________________________________________________
82 {
83  if(m_points.size()==0)
85 
86  //Bounding Box and Center
87  float xmin(m_points[0]), ymin(m_points[1]), zmin(m_points[2]);
88  float xmax(xmin), ymax(ymin), zmax(zmin);
89 
90  int nVertices = m_points.size()/3;
91  for (int i=1;i<nVertices;i++) {
92  xmin = std::min(xmin,m_points[i*3]);
93  xmax = std::max(xmax,m_points[i*3]);
94  ymin = std::min(ymin,m_points[i*3+1]);
95  ymax = std::max(ymax,m_points[i*3+1]);
96  zmin = std::min(zmin,m_points[i*3+2]);
97  zmax = std::max(zmax,m_points[i*3+2]);
98  }
99 
100  m_bbox.setBounds (xmin, ymin, zmin, xmax, ymax, zmax);
101  m_center.setValue(0.5*(xmin+xmax),0.5*(ymin+ymax),0.5*(zmin+zmax));
102 
103  drawEdgeLines.touch();
104 }
105 
106 
107 //____________________________________________________________________
109 {
110  if(m_points.size()==0)
112 
113  // Access the state from the action
114  SoState *state = action->getState();
115 
116  if(action->getTypeId().isDerivedFrom(SoPickAction::getClassTypeId())) {
117 
118  //For picking:
119  SoPrimitiveVertex vertex;
120  beginShape(action,TRIANGLES);
121  for(size_t i=0;i<m_points.size();i+=3) {
122  vertex.setPoint(SbVec3f(m_points[i],m_points[i+1],m_points[i+2]));
123  shapeVertex(&vertex);
124  }
125  endShape();
126 
127  }else{
128 
129  // Draw the shape itself
130  glBegin(GL_TRIANGLES);
131  int nFaces = m_normals.size()/3;
132  for (int i=0;i<nFaces;i++) {
133  glNormal3fv((const GLfloat*)&m_normals[i*3]);
134  for (int j = 0; j < 3; j++)
135  glVertex3fv((const GLfloat*)&m_points[i*9+j*3]);
136  }
137  glEnd();
138 
139  // Draw edges if required
140  //
141  // -- ToDo: this can be optimizid. We are currently drawing edges twice
142  // -- and we could also eliminate 'diagonal' lines coming from
143  // -- quadrangular shapes
144  //
145  if(drawEdgeLines.getValue()){
146  const bool disableLighting(forceEdgeLinesInBaseColour.getValue()&&glIsEnabled(GL_LIGHTING));
147  const bool transparencyOn = glIsEnabled(GL_BLEND);
148 
149  if (disableLighting) glDisable(GL_LIGHTING);
150  if (transparencyOn) glDisable(GL_BLEND);
151 
152  for(size_t i=0;i<m_points.size()-9;i+=9) {
153  glBegin(GL_LINE_STRIP);
154  glVertex3fv((const GLfloat*)&m_points[i]);
155  glVertex3fv((const GLfloat*)&m_points[i+3]);
156  glVertex3fv((const GLfloat*)&m_points[i+6]);
157  glVertex3fv((const GLfloat*)&m_points[i]);
158  glEnd();
159  }
160 
161  if (disableLighting) glEnable(GL_LIGHTING);
162  if (transparencyOn) glEnable(GL_BLEND);
163  }
164  }
165 
166  if (state&&state->isElementEnabled(SoGLCacheContextElement::getClassStackIndex())) {
167  //Encourage auto caching
168  SoGLCacheContextElement::shouldAutoCache(state, SoGLCacheContextElement::DO_AUTO_CACHE);
169 #if ((COIN_MAJOR_VERSION>=3)||((COIN_MAJOR_VERSION==2)&&(COIN_MINOR_VERSION>=5)))
170  SoGLCacheContextElement::incNumShapes(state);
171 #endif
172  }
173 
174 }
175 
176 //____________________________________________________________________
178 {
179  double targetSize = 100.;
180  addTriangularFacet(-targetSize,-targetSize,0.,targetSize,-targetSize,0.,0.,0.,targetSize);
181  addTriangularFacet(targetSize,-targetSize,0.,targetSize,targetSize,0.,0.,0.,targetSize);
182  addTriangularFacet(targetSize,targetSize,0.,-targetSize,targetSize,0.,0.,0.,targetSize);
183  addTriangularFacet(-targetSize,targetSize,0.,-targetSize,-targetSize,0.,0.,0.,targetSize);
184  addQuadrangularFacet(-targetSize,-targetSize,0.,-targetSize,targetSize,0.,targetSize,targetSize,0.,targetSize,-targetSize,0.);
185 }
186 
187 //____________________________________________________________________
188 void SoTessellated::computeBBox(SoAction *, SbBox3f &box, SbVec3f &center ){
189  if(m_points.size()==0)
191  box = m_bbox;
192  center = m_center;
193 }
194 
195 //____________________________________________________________________
197 {
198  if(m_points.size()==0)
200  if (alternateRep.getValue())
202 
203  SoSeparator * sep = new SoSeparator;
204 
205  // Faceset representing the shape
206  SoVertexProperty* vertices = new SoVertexProperty();
207  for(size_t i=0;i<m_normals.size();++i)
208  vertices->vertex.set1Value(i,m_points[i*3+0],m_points[i*3+1],m_points[i*3+2]);
209  SoIndexedFaceSet* faceset = new SoIndexedFaceSet;
210  int j=0;
211  for(size_t i=0;i<m_normals.size();++i) {
212  faceset->coordIndex.set1Value(j++,i);
213  if((i>1) && ((i-2)%3==0)) {
214  faceset->coordIndex.set1Value(j++,SO_END_FACE_INDEX);
215  }
216  }
217 
218  faceset->vertexProperty = vertices;
219  sep->addChild(faceset);
220 
221  // Lineset representing the outline
222  //
223  // -- ToDo: this can be optimizid. We are currently drawing edges twice
224  // -- and we could also eliminate 'diagonal' lines coming from
225  // -- quadrangular shapes
226  //
227  if (drawEdgeLines.getValue()) {
228  SoVertexProperty* verticesL = new SoVertexProperty();
229  SoIndexedLineSet* lineset = new SoIndexedLineSet;
230  int kk=0, jj=0;
231  for(size_t i=0;i<m_points.size()-9;i+=9) {
232  verticesL->vertex.set1Value(kk,m_points[i],m_points[i+1],m_points[i+2]);
233  lineset->coordIndex.set1Value(jj++,kk++);
234  verticesL->vertex.set1Value(kk,m_points[i+3],m_points[i+4],m_points[i+5]);
235  lineset->coordIndex.set1Value(jj++,kk++);
236  verticesL->vertex.set1Value(kk,m_points[i+6],m_points[i+7],m_points[i+8]);
237  lineset->coordIndex.set1Value(jj++,kk++);
238  verticesL->vertex.set1Value(kk,m_points[i],m_points[i+1],m_points[i+2]);
239  lineset->coordIndex.set1Value(jj++,kk++);
240  lineset->coordIndex.set1Value(jj++,SO_END_LINE_INDEX);
241  }
242  lineset->vertexProperty = verticesL;
243  sep->addChild(lineset);
244  }
245 
246  alternateRep.setValue(sep);
247 }
248 
249 //____________________________________________________________________
251 {
252  alternateRep.setValue(NULL);
253 }
254 
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
ymin
double ymin
Definition: listroot.cxx:63
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
SoTessellated::generateAlternateRep
virtual void generateAlternateRep()
Definition: SoTessellated.cxx:196
NSWL1::nVertices
int nVertices(const Polygon &p)
Definition: GeoUtils.cxx:35
SoTessellated::finalize
void finalize()
Definition: SoTessellated.cxx:81
PixelAthClusterMonAlgCfg.zmin
zmin
Definition: PixelAthClusterMonAlgCfg.py:169
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
SoTessellated::setupDefaultPoints
void setupDefaultPoints()
Definition: SoTessellated.cxx:177
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
SoTessellated::drawEdgeLines
SoSFBool drawEdgeLines
Definition: SoTessellated.h:31
plotBeamSpotCompare.x2
x2
Definition: plotBeamSpotCompare.py:218
SoTessellated::m_bbox
SbBox3f m_bbox
Definition: SoTessellated.h:74
SoTessellated::generatePrimitives
virtual void generatePrimitives(SoAction *action)
Definition: SoTessellated.cxx:108
SoTessellated::forceEdgeLinesInBaseColour
SoSFBool forceEdgeLinesInBaseColour
Definition: SoTessellated.h:32
SoTessellated::alternateRep
SoSFNode alternateRep
Definition: SoTessellated.h:33
makeTRTBarrelCans.y1
tuple y1
Definition: makeTRTBarrelCans.py:15
SoTessellated::addQuadrangularFacet
void addQuadrangularFacet(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, double x4, double y4, double z4)
Definition: SoTessellated.cxx:71
python.changerun.kk
list kk
Definition: changerun.py:41
SoTessellated
Definition: SoTessellated.h:24
lumiFormat.i
int i
Definition: lumiFormat.py:85
xmin
double xmin
Definition: listroot.cxx:60
SoTessellated.h
makeTRTBarrelCans.y2
tuple y2
Definition: makeTRTBarrelCans.py:18
PixelAthClusterMonAlgCfg.zmax
zmax
Definition: PixelAthClusterMonAlgCfg.py:169
SoTessellated::~SoTessellated
virtual ~SoTessellated()
Definition: SoTessellated.cxx:38
SoTessellated::m_normals
std::vector< float > m_normals
Definition: SoTessellated.h:73
grepfile.sep
sep
Definition: grepfile.py:38
SoTessellated::computeBBox
virtual void computeBBox(SoAction *action, SbBox3f &box, SbVec3f &center)
Definition: SoTessellated.cxx:188
SoTessellated::clearAlternateRep
virtual void clearAlternateRep()
Definition: SoTessellated.cxx:250
SoTessellated::m_points
std::vector< float > m_points
Definition: SoTessellated.h:72
Trk::vertex
@ vertex
Definition: MeasurementType.h:21
SoTessellated::SoTessellated
SoTessellated()
Definition: SoTessellated.cxx:28
python.CaloScaleNoiseConfig.action
action
Definition: CaloScaleNoiseConfig.py:77
xmax
double xmax
Definition: listroot.cxx:61
SoTessellated::addTriangularFacet
void addTriangularFacet(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3)
Definition: SoTessellated.cxx:43
ymax
double ymax
Definition: listroot.cxx:64
SoTessellated::m_center
SbVec3f m_center
Definition: SoTessellated.h:75