ATLAS Offline Software
Loading...
Searching...
No Matches
SoGenericBox.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5
7// //
8// Implementation of class SoGenericBox //
9// //
10// Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch) //
11// Initial version: December 2008 //
12// //
14
16
17#include <Inventor/SbBox.h>
18#include <Inventor/actions/SoPickAction.h>
19#include <Inventor/nodes/SoSeparator.h>
20#include <Inventor/nodes/SoIndexedFaceSet.h>
21#include <Inventor/nodes/SoIndexedLineSet.h>
22//#include <Inventor/nodes/SoLightModel.h>
23#include <Inventor/SoPrimitiveVertex.h>
24#include <Inventor/C/glue/gl.h>
25#include <Inventor/elements/SoGLCacheContextElement.h>
26#include <iostream>
27
28SO_NODE_SOURCE(SoGenericBox)
29
32
34{
35 3, 2, 1, 0,
36 4, 5, 6, 7,
37 0, 1, 5, 4,
38 1, 2, 6, 5,
39 2, 3, 7, 6,
40 3, 0, 4, 7
41};
42
44{
45 3, 2, 1, 0, SO_END_FACE_INDEX,
46 4, 5, 6, 7, SO_END_FACE_INDEX,
47 0, 1, 5, 4, SO_END_FACE_INDEX,
48 1, 2, 6, 5, SO_END_FACE_INDEX,
49 2, 3, 7, 6, SO_END_FACE_INDEX,
50 3, 0, 4, 7, SO_END_FACE_INDEX
51};
52
54{
55 0, 1, 2, 3, 0, 4, 5, 6, 7, 4, SO_END_LINE_INDEX,
56 3, 7, SO_END_LINE_INDEX,
57 6, 2, SO_END_LINE_INDEX,
58 5, 1, SO_END_LINE_INDEX,
59};
60
61//____________________________________________________________________
63{
64 [[maybe_unused]] static const bool didInit = [&]() {
65 SO_NODE_INIT_CLASS(SoGenericBox, SoShape, "Shape");
66 return true;
67 }();
68}
69
70//____________________________________________________________________
72 : m_points(0), m_normals(0)
73{
74 SO_NODE_CONSTRUCTOR(SoGenericBox);
75 SO_NODE_ADD_FIELD(drawEdgeLines, (false));
76 SO_NODE_ADD_FIELD(forceEdgeLinesInBaseColour, (true));
77 SO_NODE_ADD_FIELD(alternateRep,(NULL));
78 setNodeType(EXTENSION);
79}
80
81//____________________________________________________________________
83{
84 delete [] m_normals;
85 delete [] m_points;
86}
87
88//____________________________________________________________________
89void SoGenericBox::generatePrimitives(SoAction *action) {
90
91 if (!m_points)
93
94 // Access the state from the action
95 SoState *state = action->getState();
96
97 if ( action->getTypeId().isDerivedFrom(SoPickAction::getClassTypeId()) ) {
98 //For picking:
99
100 SoPrimitiveVertex vertex;
101 beginShape(action,QUADS);
102 int *iptr = sogenericbox_vindices;
103 for (int i=0;i<SOGENERICBOX_NFACES;++i) {
104 for (int j = 0; j < 4; ++j) {
105 const int ivert = *iptr++;
106 vertex.setPoint(SbVec3f(m_points[ivert*3+0], m_points[ivert*3+1], m_points[ivert*3+2]));
107 shapeVertex(&vertex);
108 }
109 }
110 endShape();
111 } else {
112
113 glBegin(GL_QUADS);
114 int *iptr = sogenericbox_vindices;
115 for (int i=0;i<SOGENERICBOX_NFACES;i++) {
116 glNormal3fv(static_cast<const GLfloat*>(&m_normals[i*3]));
117 for (int j = 0; j < 4; j++)
118 glVertex3fv(static_cast<const GLfloat*>(&m_points[(*iptr++)*3]));
119 }
120 glEnd();
121
122
123 if (drawEdgeLines.getValue()) {
124
125 const bool disableLighting(forceEdgeLinesInBaseColour.getValue()&&glIsEnabled(GL_LIGHTING));
126 const bool transparencyOn = glIsEnabled(GL_BLEND);
127
128 if (disableLighting) glDisable(GL_LIGHTING);
129 if (transparencyOn) glDisable(GL_BLEND);
130#define trdV(i) glVertex3fv(static_cast<const GLfloat*>(&m_points[i*3]));
131 glBegin(GL_LINE_STRIP);
132 trdV(0)trdV(1)trdV(2)trdV(3)trdV(0)trdV(4)trdV(5)trdV(6)trdV(7)trdV(4)
133 glEnd();
134
135 glBegin(GL_LINES);
136 trdV(3)trdV(7)
137 trdV(6)trdV(2)
138 trdV(5)trdV(1)
139 glEnd();
140
141 if (disableLighting) glEnable(GL_LIGHTING);
142 if (transparencyOn) glEnable(GL_BLEND);
143 }
144 }
145
146 if (state&&state->isElementEnabled(SoGLCacheContextElement::getClassStackIndex())) {
147 //Encourage auto caching
148 SoGLCacheContextElement::shouldAutoCache(state, SoGLCacheContextElement::DO_AUTO_CACHE);
149#if ((COIN_MAJOR_VERSION>=3)||((COIN_MAJOR_VERSION==2)&&(COIN_MINOR_VERSION>=5)))
150 SoGLCacheContextElement::incNumShapes(state);
151#endif
152 }
153
154}
155
156//____________________________________________________________________
158{
159 if (!m_points)
160 m_points = new float[SOGENERICBOX_NPOINTS*3];
161}
162
163//____________________________________________________________________
165{
166 setParametersForBox( 0.5, 0.5, 0.5 );
167}
168
169//____________________________________________________________________
170void SoGenericBox::computeBBox(SoAction *, SbBox3f &box, SbVec3f &center ){
171 if (!m_points)
173 box = m_bbox;
174 center = m_center;
175}
176
177//____________________________________________________________________
178void SoGenericBox::setParametersForBox( float dx, float dy, float dz,
179 float xcenter, float ycenter, float zcenter ) {
181 m_points[0*3+0] = xcenter+dx; m_points[0*3+1] = ycenter+dy; m_points[0*3+2] = zcenter-dz;
182 m_points[1*3+0] = xcenter-dx; m_points[1*3+1] = ycenter+dy; m_points[1*3+2] = zcenter-dz;
183 m_points[2*3+0] = xcenter-dx; m_points[2*3+1] = ycenter-dy; m_points[2*3+2] = zcenter-dz;
184 m_points[3*3+0] = xcenter+dx; m_points[3*3+1] = ycenter-dy; m_points[3*3+2] = zcenter-dz;
185 m_points[4*3+0] = xcenter+dx; m_points[4*3+1] = ycenter+dy; m_points[4*3+2] = zcenter+dz;
186 m_points[5*3+0] = xcenter-dx; m_points[5*3+1] = ycenter+dy; m_points[5*3+2] = zcenter+dz;
187 m_points[6*3+0] = xcenter-dx; m_points[6*3+1] = ycenter-dy; m_points[6*3+2] = zcenter+dz;
188 m_points[7*3+0] = xcenter+dx; m_points[7*3+1] = ycenter-dy; m_points[7*3+2] = zcenter+dz;
190}
191
192//____________________________________________________________________
193void SoGenericBox::internalSetParametersForEtaPhiCell( bool barrel, double etaMin, double etaMax,
194 double phiMin, double phiMax,
195 double cellDepth, double cellDistance,
196 double etasqueezefact, double phisqueezefact )
197{
199 if (phiMax<phiMin) std::swap(phiMin,phiMax);
200 if (etaMax<etaMin) std::swap(etaMin,etaMax);
201
202 if (etasqueezefact!=1.0) {
203 double etashift(0.5*(1.0-etasqueezefact)*fabs(etaMax-etaMin));
204 etaMax -= etashift;
205 etaMin += etashift;
206 }
207 if (phisqueezefact!=1.0) {
208 double phishift(0.5*(1.0-phisqueezefact)*fabs(phiMax-phiMin));
209 phiMax -= phishift;
210 phiMin += phishift;
211 }
212
213 if (cellDistance<0) cellDistance = -cellDistance;
214 if (cellDepth<0) cellDistance = std::max(cellDistance-cellDepth,0.0);
215 double tantheta2 = tan(2*atan(exp(-etaMin)));
216 double tantheta1 = tan(2*atan(exp(-etaMax)));
217 const double cpMin(cos(phiMin));
218 const double cpMax(cos(phiMax));
219 const double spMin(sin(phiMin));
220 const double spMax(sin(phiMax));
221 if (barrel) {
222 const double rf = cellDistance;
223 const double rb = cellDistance+cellDepth;
224 const double rfdivtantheta1(rf/tantheta1);
225 const double rbdivtantheta1(rb/tantheta1);
226 const double rfdivtantheta2(rf/tantheta2);
227 const double rbdivtantheta2(rb/tantheta2);
228 m_points[0*3+0] = rf*cpMin; m_points[0*3+1] = rf*spMin; m_points[0*3+2] = rfdivtantheta1;
229 m_points[1*3+0] = rf*cpMin; m_points[1*3+1] = rf*spMin; m_points[1*3+2] = rfdivtantheta2;
230 m_points[2*3+0] = rf*cpMax; m_points[2*3+1] = rf*spMax; m_points[2*3+2] = rfdivtantheta2;
231 m_points[3*3+0] = rf*cpMax; m_points[3*3+1] = rf*spMax; m_points[3*3+2] = rfdivtantheta1;
232 m_points[4*3+0] = rb*cpMin; m_points[4*3+1] = rb*spMin; m_points[4*3+2] = rbdivtantheta1;
233 m_points[5*3+0] = rb*cpMin; m_points[5*3+1] = rb*spMin; m_points[5*3+2] = rbdivtantheta2;
234 m_points[6*3+0] = rb*cpMax; m_points[6*3+1] = rb*spMax; m_points[6*3+2] = rbdivtantheta2;
235 m_points[7*3+0] = rb*cpMax; m_points[7*3+1] = rb*spMax; m_points[7*3+2] = rbdivtantheta1;
236 } else {
237 const double eta(0.5*(etaMin+etaMax));
238 const double zf(eta>0?cellDistance:-cellDistance);
239 double zb = (zf > 0 ? zf+cellDepth: zf-cellDepth);
240 m_points[0*3+0] = zf*tantheta1*cpMin; m_points[0*3+1] = zf*tantheta1*spMin; m_points[0*3+2] = zf;
241 m_points[1*3+0] = zf*tantheta2*cpMin; m_points[1*3+1] = zf*tantheta2*spMin; m_points[1*3+2] = zf;
242 m_points[2*3+0] = zf*tantheta2*cpMax; m_points[2*3+1] = zf*tantheta2*spMax; m_points[2*3+2] = zf;
243 m_points[3*3+0] = zf*tantheta1*cpMax; m_points[3*3+1] = zf*tantheta1*spMax; m_points[3*3+2] = zf;
244 m_points[4*3+0] = zb*tantheta1*cpMin; m_points[4*3+1] = zb*tantheta1*spMin; m_points[4*3+2] = zb;
245 m_points[5*3+0] = zb*tantheta2*cpMin; m_points[5*3+1] = zb*tantheta2*spMin; m_points[5*3+2] = zb;
246 m_points[6*3+0] = zb*tantheta2*cpMax; m_points[6*3+1] = zb*tantheta2*spMax; m_points[6*3+2] = zb;
247 m_points[7*3+0] = zb*tantheta1*cpMax; m_points[7*3+1] = zb*tantheta1*spMax; m_points[7*3+2] = zb;
248 }
249
251}
252
253
254//____________________________________________________________________
255void SoGenericBox::setParametersForBarrelEtaPhiCell( double etaMin, double etaMax,
256 double phiMin, double phiMax,
257 double cellDepth, double cellDistance,
258 double etasqueezefact, double phisqueezefact )
259{
260 internalSetParametersForEtaPhiCell( true, etaMin, etaMax, phiMin, phiMax,
261 cellDepth, cellDistance, etasqueezefact, phisqueezefact );
262}
263
264//____________________________________________________________________
265void SoGenericBox::setParametersForEndCapEtaPhiCell( double etaMin, double etaMax,
266 double phiMin, double phiMax,
267 double cellDepth, double cellDistance,
268 double etasqueezefact, double phisqueezefact )
269{
270 internalSetParametersForEtaPhiCell( false, etaMin, etaMax, phiMin, phiMax,
271 cellDepth, cellDistance, etasqueezefact, phisqueezefact );
272}
273
274//____________________________________________________________________
275void SoGenericBox::setParametersForTrd( float dx1, float dx2,
276 float dy1, float dy2,
277 float dz )
278{
280 m_points[0*3+0] = dx1; m_points[0*3+1] = dy1; m_points[0*3+2] = -dz;
281 m_points[1*3+0] = -dx1; m_points[1*3+1] = dy1; m_points[1*3+2] = -dz;
282 m_points[2*3+0] = -dx1; m_points[2*3+1] = -dy1; m_points[2*3+2] = -dz;
283 m_points[3*3+0] = dx1; m_points[3*3+1] = -dy1; m_points[3*3+2] = -dz;
284 m_points[4*3+0] = dx2; m_points[4*3+1] = dy2; m_points[4*3+2] = dz;
285 m_points[5*3+0] = -dx2; m_points[5*3+1] = dy2; m_points[5*3+2] = dz;
286 m_points[6*3+0] = -dx2; m_points[6*3+1] = -dy2; m_points[6*3+2] = dz;
287 m_points[7*3+0] = dx2; m_points[7*3+1] = -dy2; m_points[7*3+2] = dz;
289}
290
291//____________________________________________________________________
292void SoGenericBox::setParametersForTrapezoid( float dz, float theta, float phi, float dy1,
293 float dx1, float dx2, float dy2, float dx3,
294 float dx4, float alp1, float alp2 )
295
296{
298 const float tanTheta(tan(theta));
299 const float TthetaCphi = tanTheta*cos(phi);
300 const float TthetaSphi = tanTheta*sin(phi);
301 const float Talp1 = tan(alp1);
302 const float Talp2 = tan(alp2);
303
304 m_points[0*3+0] = dx2+dy1*Talp1;
305 m_points[0*3+1] = dy1;
306 m_points[0*3+2] = -dz;
307
308 m_points[1*3+0] = -dx2+dy1*Talp1;
309 m_points[1*3+1] = dy1;
310 m_points[1*3+2] = -dz;
311
312 m_points[2*3+0] = -dx1-dy1*Talp1;
313 m_points[2*3+1] = -dy1;
314 m_points[2*3+2] = -dz;
315
316 m_points[3*3+0] = dx1-dy1*Talp1;
317 m_points[3*3+1] = -dy1;
318 m_points[3*3+2] = -dz;
319
320 m_points[4*3+0] = dx4+dy2*Talp2;
321 m_points[4*3+1] = dy2;
322 m_points[4*3+2] = dz;
323
324 m_points[5*3+0] = -dx4+dy2*Talp2;
325 m_points[5*3+1] = dy2;
326 m_points[5*3+2] = dz;
327
328 m_points[6*3+0] = -dx3-dy2*Talp2;
329 m_points[6*3+1] = -dy2;
330 m_points[6*3+2] = dz;
331
332 m_points[7*3+0] = dx3-dy2*Talp2;
333 m_points[7*3+1] = -dy2;
334 m_points[7*3+2] = dz;
335
336 const float dzTthetaCphi(dz*TthetaCphi);
337 const float dzTthetaSphi(dz*TthetaSphi);
338 int i;
339 for (i=0;i<4;i++) {
340 m_points[i*3+0] -= dzTthetaCphi;
341 m_points[i*3+1] -= dzTthetaSphi;
342 }
343 for (i=4;i<8;i++) {
344 m_points[i*3+0] += dzTthetaCphi;
345 m_points[i*3+1] += dzTthetaSphi;
346 }
348}
349
350
351//____________________________________________________________________
352void SoGenericBox::setGenericParameters( float x0, float y0, float z0,
353 float x1, float y1, float z1,
354 float x2, float y2, float z2,
355 float x3, float y3, float z3,
356 float x4, float y4, float z4,
357 float x5, float y5, float z5,
358 float x6, float y6, float z6,
359 float x7, float y7, float z7 )
360{
362 m_points[0*3+0] = x0; m_points[0*3+1] = y0; m_points[0*3+2] = z0;
363 m_points[1*3+0] = x1; m_points[1*3+1] = y1; m_points[1*3+2] = z1;
364 m_points[2*3+0] = x2; m_points[2*3+1] = y2; m_points[2*3+2] = z2;
365 m_points[3*3+0] = x3; m_points[3*3+1] = y3; m_points[3*3+2] = z3;
366 m_points[4*3+0] = x4; m_points[4*3+1] = y4; m_points[4*3+2] = z4;
367 m_points[5*3+0] = x5; m_points[5*3+1] = y5; m_points[5*3+2] = z5;
368 m_points[6*3+0] = x6; m_points[6*3+1] = y6; m_points[6*3+2] = z6;
369 m_points[7*3+0] = x7; m_points[7*3+1] = y7; m_points[7*3+2] = z7;
371}
372
373//____________________________________________________________________
375{
376 //Normals:
377 if (!m_normals)
378 m_normals = new float[SOGENERICBOX_NFACES*3];
379 for (int iface = 0; iface < SOGENERICBOX_NFACES; ++iface) {
380 const int index_v1 = sogenericbox_vindices[iface*4+0];
381 const int index_v2 = sogenericbox_vindices[iface*4+1];
382 const int index_v3 = sogenericbox_vindices[iface*4+2];
383
384 //Figure out normal: (v2-v1)(x)(v3-v1)
385 const double v1X(m_points[index_v1*3+0]), v1Y(m_points[index_v1*3+1]), v1Z(m_points[index_v1*3+2]);
386 const double edge1X(m_points[index_v2*3+0]-v1X), edge1Y(m_points[index_v2*3+1]-v1Y), edge1Z(m_points[index_v2*3+2]-v1Z);
387 const double edge2X(m_points[index_v3*3+0]-v1X), edge2Y(m_points[index_v3*3+1]-v1Y), edge2Z(m_points[index_v3*3+2]-v1Z);
388
389 double nx(edge1Y*edge2Z-edge1Z*edge2Y);
390 double ny(edge1Z*edge2X-edge1X*edge2Z);
391 double nz(edge1X*edge2Y-edge1Y*edge2X);
392 double nl(nx*nx+ny*ny+nz*nz);
393 if (nl<=0) {
394 std::cout<<"SoGenericBox::Error Could not calculate normal due to degenerate face edge"<<std::endl;
395 nx=1.0;ny=0.0;nz=0.0;nl=1;
396 //Fixme: We should try to use index_v4 instead of one vertex,
397 //to get the normal (this would allow faces where one edge was
398 //collapsed).
399 //const int index_v4 = sogenericbox_vindices[iface*4+3];
400 }
401 const double s(1.0/sqrt(nl));
402 m_normals[iface*3+0] = nx*s;
403 m_normals[iface*3+1] = ny*s;
404 m_normals[iface*3+2] = nz*s;
405 }
406
407 //BBox:
408 float xmin(1.0e99), ymin(1.0e99), zmin(1.0e99);//fixme: -> inf
409 float xmax(-1.0e99), ymax(-1.0e99), zmax(-1.0e99);
410 for (int i=0;i<SOGENERICBOX_NPOINTS;++i) {
411 const float x(m_points[i*3+0]), y(m_points[i*3+1]), z(m_points[i*3+2]);
412 xmin = std::min(xmin,x); xmax = std::max(xmax,x);
413 ymin = std::min(ymin,y); ymax = std::max(ymax,y);
414 zmin = std::min(zmin,z); zmax = std::max(zmax,z);
415 }
416 m_bbox.setBounds (xmin, ymin, zmin, xmax, ymax, zmax);
417 m_center.setValue(0.5*(xmin+xmax),0.5*(ymin+ymax),0.5*(zmin+zmax));
418
419 drawEdgeLines.touch();
420}
421
422
424// Stuff for alternate rep //
426
427//____________________________________________________________________
429{
430 if (!m_points)
432 if (alternateRep.getValue())
434 SoSeparator * sep = new SoSeparator;
435
436 //Vertice coordinates:
437 SoVertexProperty *vertices = new SoVertexProperty();
438 for (int i=0;i<SOGENERICBOX_NPOINTS;++i)
439 vertices->vertex.set1Value ( i, m_points[i*3+0],m_points[i*3+1],m_points[i*3+2] );
440 SoIndexedFaceSet * faceset = new SoIndexedFaceSet;
441 faceset->coordIndex.setValues(0,5*6, sogenericbox_vindices_foraltrepfaces);
442 faceset->vertexProperty = vertices;
443 sep->addChild(faceset);
444
445 if (drawEdgeLines.getValue()) {
446//Disable the lightmodel now since we in any case gets baselightning with the lineset defined this way...
447// if (forceEdgeLinesInBaseColour.getValue()) {
448// SoLightModel * lm = new SoLightModel;//Fixme: share
449// lm->model = SoLightModel::BASE_COLOR;
450// sep->addChild(lm);
451// }
452 SoIndexedLineSet * lineset = new SoIndexedLineSet;
453 lineset->coordIndex.setValues(0,20,sogenericbox_vindices_foraltreplines);
454 lineset->vertexProperty = vertices;
455 sep->addChild(lineset);
456 }
457
458 alternateRep.setValue(sep);
459
460}
461
462//____________________________________________________________________
464{
465 alternateRep.setValue(NULL);
466 //Hmm... no ref/unref??
467}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
Scalar theta() const
theta method
static const int SOGENERICBOX_NPOINTS
static const int SOGENERICBOX_NFACES
static int sogenericbox_vindices[]
static int sogenericbox_vindices_foraltreplines[20]
static int sogenericbox_vindices_foraltrepfaces[5 *SOGENERICBOX_NFACES]
#define trdV(i)
#define y
#define x
#define z
SoSFNode alternateRep
virtual void clearAlternateRep()
void setParametersForBox(float dx, float dy, float dz, float xcenter=0.0, float ycenter=0.0, float zcenter=0.0)
void internalSetParametersForEtaPhiCell(bool barrel, double etaMin, double etaMax, double phiMin, double phiMax, double cellDepth, double cellDistance, double etasqueezefact, double phisqueezefact)
void ensurePointsAllocated()
virtual ~SoGenericBox()
void setParametersForTrapezoid(float dz, float theta, float phi, float dy1, float dx1, float dx2, float dy2, float dx3, float dx4, float alp1, float alp2)
float * m_points
void setParametersForTrd(float dx1, float dx2, float dy1, float dy2, float dz)
void setGenericParameters(float x0, float y0, float z0, float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4, float x5, float y5, float z5, float x6, float y6, float z6, float x7, float y7, float z7)
SoSFBool forceEdgeLinesInBaseColour
virtual void computeBBox(SoAction *action, SbBox3f &box, SbVec3f &center)
void setParametersForBarrelEtaPhiCell(double etaMin, double etaMax, double phiMin, double phiMax, double cellDepth, double cellDistance, double etasqueezefact=1.0, double phisqueezefact=1.0)
static void initClass()
void setupDefaultPoints()
float * m_normals
virtual void generatePrimitives(SoAction *action)
SoSFBool drawEdgeLines
SbVec3f m_center
void setParametersForEndCapEtaPhiCell(double etaMin, double etaMax, double phiMin, double phiMax, double cellDepth, double cellDistance, double etasqueezefact=1.0, double phisqueezefact=1.0)
virtual void generateAlternateRep()
double xmax
Definition listroot.cxx:61
double ymin
Definition listroot.cxx:63
double xmin
Definition listroot.cxx:60
double ymax
Definition listroot.cxx:64
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)