ATLAS Offline Software
SoPcons.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /*-----------------------------Hepvis---------------------------------------*/
6 /* */
7 /* Node: SoPcons */
8 /* Description: Represents the G4Pcons Geant Geometry entity */
9 /* Author: Joe Boudreau Nov 11 1996 */
10 /* Update: Giorgi Gvaberidze (ggvaberi@cern.ch) */
11 /* April 2011 */
12 /* Fixed: Generating of alternate rep, for export in *.iv file */
13 /* */
14 /*--------------------------------------------------------------------------*/
16 #include "RevolutionSurfaceUtil.h"
17 
18 #include <cassert>
19 #include <cmath>
20 #include <Inventor/SbBox.h>
21 #include <Inventor/actions/SoAction.h>
22 #include <Inventor/misc/SoChildList.h>
23 #include <Inventor/nodes/SoSeparator.h>
24 #include <Inventor/nodes/SoIndexedFaceSet.h>
25 #include <Inventor/nodes/SoNormal.h>
26 #include <Inventor/nodes/SoCoordinate3.h>
27 #include <Inventor/nodes/SoNormalBinding.h>
28 #include <Inventor/SoPrimitiveVertex.h>
29 #include <Inventor/elements/SoTextureCoordinateElement.h>
30 #include <Inventor/elements/SoGLCacheContextElement.h>
31 #include <Inventor/C/glue/gl.h>
32 
33 
34 // This statement is required
35 SO_NODE_SOURCE(SoPcons)
36 
37 // Pconstructor
39  // This statement is required
40  SO_NODE_CONSTRUCTOR(SoPcons);
41 
42  // Data fields are initialized like this:
43  SO_NODE_ADD_FIELD(fRmin, (0.0));
44  SO_NODE_ADD_FIELD(fRmax, (0.0));
45  SO_NODE_ADD_FIELD(fDz, (0.0));
46  SO_NODE_ADD_FIELD(fSPhi, (0.0));
47  SO_NODE_ADD_FIELD(fDPhi, ((float)(2*M_PI)));
48  SO_NODE_ADD_FIELD(smoothDraw, (TRUE));
49  SO_NODE_ADD_FIELD(pOverrideNPhi, (0));
50  SO_NODE_ADD_FIELD(alternateRep, (NULL));
51  SO_NODE_ADD_FIELD(drawEdgeLines, (false));
52 
53  m_children = std::make_unique<SoChildList>(this);
54 
55  float rMinDef[]={10.0, 15.0, 10.0};
56  float rMaxDef[]={11.0, 17.0, 12.0};
57  float zDef []={-10.0, 0.0, 10.0};
58 
59  fRmin.setValues(0,2,rMinDef);
60  fRmax.setValues(0,2,rMaxDef);
61  fDz.setValues(0,2,zDef);
62  setNodeType(EXTENSION);
63 }
64 
65 
66 //____________________________________________________________________
68 {
69  [[maybe_unused]] static const bool didInit = [&]() {
70  SO_NODE_INIT_CLASS(SoPcons,SoShape,"Shape");
71  return true;
72  }();
73 }
74 
75 // generatePrimitives
77  // This variable is used to store each vertex
78  SoPrimitiveVertex pv;
79 
80  // Access the stat from the action
81  SoState *state = action->getState();
82  if (!state)
83  return;
84 
85  // See if we have to use a texture coordinate function,
86  // rather than generating explicit texture coordinates.
87  SbBool useTexFunction=
89  SoTextureCoordinateElement::FUNCTION);
90 
91  // If we need to generate texture coordinates with a function,
92  // we'll need an SoGLTextureCoordinateElement. Otherwise, we'll
93  // set up the coordinates directly.
94  const SoTextureCoordinateElement *tce = NULL;
95  SbVec4f texCoord;
96  if (useTexFunction) {
97  tce = SoTextureCoordinateElement::getInstance(state);
98  } else {
99  texCoord[2] = 0.0;
100  texCoord[3] = 1.0;
101  }
102  SbVec3f point, normal;
103 
105  //-----------------------------------------------------
106 #define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \
107 point.setValue((float)(x),(float)(y),(float)(z)); \
108 normal.setValue((float)(nx),(float)(ny),(float)(nz)); \
109 if (useTexFunction) { \
110 texCoord=tce->get(point,normal); \
111 } else { \
112 texCoord[0]=(float)(s); \
113 texCoord[1]=(float)(t); \
114 } \
115 pv.setPoint(point); \
116 pv.setNormal(normal); \
117 pv.setTextureCoords(texCoord); \
118 shapeVertex(&pv);
119  //-----------------------------------------------------
121 
122  if (fRmin.getNum()!=fRmax.getNum() || fRmax.getNum() != fDz.getNum()) {
123  return;
124  }
125 
126  int nSeg = fRmin.getNum()-1;
127  if (nSeg<1) {
128  return;
129  }
130 
131  for (int p=0;p<nSeg;p++) {
132 
133  double rMin1= fRmin[p];
134  double rMin2= fRmin[p+1];
135 
136  double rMax1= fRmax[p];
137  double rMax2= fRmax[p+1];
138 
139  double zMin = fDz[p];
140  double zMax= fDz[p+1];
141 
142  int NPHI = RevolutionSurfaceUtil::nphiDivisions( fDPhi.getValue(), this->getComplexityValue(action), pOverrideNPhi.getValue() );
143 
144  double deltaPhi = fDPhi.getValue()/NPHI;
145  double phi0 = fSPhi.getValue();
146  double phi1 = phi0 + fDPhi.getValue();
147  double cosPhi0 = cos(phi0);
148  double sinPhi0 = sin(phi0);
149  double cosPhi1 = cos(phi1);
150  double sinPhi1 = sin(phi1);
151  double cosDeltaPhi = cos(deltaPhi);
152  double sinDeltaPhi = sin(deltaPhi);
153 
154  int i;
155  double sinPhi;
156  double cosPhi;
157 
158  const bool noPhiCutout=fabs(fDPhi.getValue())==0.F || fabs(fabs(fDPhi.getValue())-2.0*M_PI)<0.01; // FIXME - better way to do this?
159  const bool disableLighting(glIsEnabled(GL_LIGHTING));
160  const bool transparencyOn(glIsEnabled(GL_BLEND));
161 
162 
163  //
164  // The outer surface!
165  //
166  // if (1)
167  // {
168  double dR =rMax2-rMax1;
169  double dZ =zMax-zMin;
170  double cosTheta = -dR/sqrt(dR*dR+dZ*dZ);
171  double sinTheta = dZ/sqrt(dR*dR+dZ*dZ);
172 
173  beginShape(action,TRIANGLE_STRIP);
174  sinPhi=sinPhi0;
175  cosPhi=cosPhi0;
176  for (i = 0; i<=NPHI; i++) {
177  GEN_VERTEX(pv,rMax2*cosPhi,rMax2*sinPhi,zMax,0.0,0.0,sinTheta*cosPhi,sinTheta*sinPhi,cosTheta);
178  GEN_VERTEX(pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,sinTheta*cosPhi,sinTheta*sinPhi,cosTheta);
179  inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
180  }
181  endShape();
182 
183  if (drawEdgeLines.getValue()) {
184  if (disableLighting) glDisable(GL_LIGHTING);
185  if (transparencyOn) glDisable(GL_BLEND);
186  glBegin(GL_LINE_STRIP);
187  sinPhi=sinPhi0;
188  cosPhi=cosPhi0;
189  if (!noPhiCutout && p==0) glVertex3f(rMin1*cosPhi,rMin1*sinPhi,zMin); // only draw if phi range
190  for (i = 0; i<=NPHI; i++) {
191  glVertex3f(rMax1*cosPhi,rMax1*sinPhi,zMin);
192  inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
193  }
194  if (!noPhiCutout && p==0) glVertex3f(rMin1*cosPhi1,rMin1*sinPhi1,zMin); // only draw if phi range
195  glEnd();
196  if (disableLighting) glEnable(GL_LIGHTING);
197  if (transparencyOn) glEnable(GL_BLEND);
198  }
199 
200  //}
201  // if (1)
202  //
203  // The inner surface!
204  //
205  // {
206  beginShape(action,TRIANGLE_STRIP);
207  sinPhi=sinPhi0;
208  cosPhi=cosPhi0;
209 
210  dR =rMin2-rMin1;
211  dZ =zMax-zMin;
212  cosTheta = -dR/sqrt(dR*dR+dZ*dZ);
213  sinTheta = dZ/sqrt(dR*dR+dZ*dZ);
214 
215  for (i = 0; i<=NPHI; i++) {
216  GEN_VERTEX(pv,rMin2*cosPhi,rMin2*sinPhi,zMax,0.0,0.0,-cosPhi*sinTheta,-sinPhi*sinTheta,-cosTheta);
217  GEN_VERTEX(pv,rMin1*cosPhi,rMin1*sinPhi,zMin,1.0,1.0,-cosPhi*sinTheta,-sinPhi*sinTheta,-cosTheta);
218  inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
219  }
220  endShape();
221 
222  if (drawEdgeLines.getValue()) {
223  if (disableLighting) glDisable(GL_LIGHTING);
224  if (transparencyOn) glDisable(GL_BLEND);
225  glBegin(GL_LINE_STRIP);
226  sinPhi=sinPhi0;
227  cosPhi=cosPhi0;
228 // if (!noPhiCutout) glVertex3f(rMin1*cosPhi,rMin1*sinPhi,zMin); // only draw if phi range
229  for (i = 0; i<=NPHI; i++) {
230  glVertex3f(rMin1*cosPhi,rMin1*sinPhi,zMin);
231  inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
232  }
233 // if (!noPhiCutout) glVertex3f(rMin1*cosPhi1,rMin1*sinPhi1,zMin); // only draw if phi range
234  glEnd();
235  if (disableLighting) glEnable(GL_LIGHTING);
236  if (transparencyOn) glEnable(GL_BLEND);
237  }
238 
239  // }
240 
241 // if (1) {
242  if (!noPhiCutout) {
243  //
244  // The end
245  //
246  beginShape(action,TRIANGLE_STRIP);
247  sinPhi=sinPhi0;
248  cosPhi=cosPhi0;
249  GEN_VERTEX(pv,rMax2*cosPhi,rMax2*sinPhi,zMax,0.0,0.0,sinPhi,-cosPhi,0);
250  GEN_VERTEX(pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,sinPhi,-cosPhi,0);
251  GEN_VERTEX(pv,rMin2*cosPhi,rMin2*sinPhi,zMax,1.0,0.0,sinPhi,-cosPhi,0);
252  GEN_VERTEX(pv,rMin1*cosPhi,rMin1*sinPhi,zMin,0.0,1.0,sinPhi,-cosPhi,0);
253  endShape();
254  //
255  // The other end
256  //
257  beginShape(action,TRIANGLE_STRIP);
258  sinPhi=sinPhi1;
259  cosPhi=cosPhi1;
260  GEN_VERTEX(pv,rMax2*cosPhi,rMax2*sinPhi, zMax,0.0,0.0,-sinPhi,+cosPhi,0);
261  GEN_VERTEX(pv,rMax1*cosPhi,rMax1*sinPhi, zMin,1.0,1.0,-sinPhi,+cosPhi,0);
262  GEN_VERTEX(pv,rMin2*cosPhi,rMin2*sinPhi, zMax,1.0,0.0,-sinPhi,+cosPhi,0);
263  GEN_VERTEX(pv,rMin1*cosPhi,rMin1*sinPhi, zMin,0.0,1.0,-sinPhi,+cosPhi,0);
264  endShape();
265 
266  if (drawEdgeLines.getValue()) {
267  if (disableLighting) glDisable(GL_LIGHTING);
268  if (transparencyOn) glDisable(GL_BLEND);
269 
270  glBegin(GL_LINES);
271  glVertex3f(rMax2*cosPhi0,rMax2*sinPhi0, zMax);
272  glVertex3f(rMax1*cosPhi0,rMax1*sinPhi0, zMin);
273  glVertex3f(rMin2*cosPhi0,rMin2*sinPhi0, zMax);
274  glVertex3f(rMin1*cosPhi0,rMin1*sinPhi0, zMin);
275  glVertex3f(rMax2*cosPhi1,rMax2*sinPhi1, zMax);
276  glVertex3f(rMax1*cosPhi1,rMax1*sinPhi1, zMin);
277  glVertex3f(rMin2*cosPhi1,rMin2*sinPhi1, zMax);
278  glVertex3f(rMin1*cosPhi1,rMin1*sinPhi1, zMin);
279  glEnd();
280  if (disableLighting) glEnable(GL_LIGHTING);
281  if (transparencyOn) glEnable(GL_BLEND);
282  }
283 
284  }
285 // }
286  if (p==(nSeg-1)) {
287  //
288  // The outer surface at z=+PDZ
289  //
290  beginShape(action,TRIANGLE_STRIP);
291  sinPhi=sinPhi0;
292  cosPhi=cosPhi0;
293  for (i = 0; i<=NPHI; i++) {
294  GEN_VERTEX(pv,rMin2*cosPhi,rMin2*sinPhi,zMax,0.0,0.0,0,0,1);
295  GEN_VERTEX(pv,rMax2*cosPhi,rMax2*sinPhi,zMax,1.0,1.0,0,0,1);
296  inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
297  }
298  endShape();
299 
300  if (drawEdgeLines.getValue()) {
301  if (disableLighting) glDisable(GL_LIGHTING);
302  if (transparencyOn) glDisable(GL_BLEND);
303  glBegin(GL_LINE_STRIP);
304  sinPhi=sinPhi0;
305  cosPhi=cosPhi0;
306  if (!noPhiCutout) glVertex3f(rMin1*cosPhi,rMin1*sinPhi,zMax); // only draw if phi range
307  for (i = 0; i<=NPHI; i++) {
308  glVertex3f(rMax1*cosPhi,rMax1*sinPhi,zMax);
309  inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
310  }
311  if (!noPhiCutout) glVertex3f(rMin1*cosPhi1,rMin1*sinPhi1,zMax); // only draw if phi range
312  glEnd();
313  if (disableLighting) glEnable(GL_LIGHTING);
314  if (transparencyOn) glEnable(GL_BLEND);
315  }
316 
317  }
318  if (p==0) {
319  //
320  // The outer surface at z=-PDZ
321  //
322  beginShape(action,TRIANGLE_STRIP);
323  sinPhi=sinPhi0;
324  cosPhi=cosPhi0;
325  for (i = 0; i<=NPHI; i++) {
326  GEN_VERTEX(pv,rMin1*cosPhi,rMin1*sinPhi,zMin,0.0,0.0,0,0,-1);
327  GEN_VERTEX(pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,0,0,-1);
328  inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
329  }
330  endShape();
331  }
332  }
333 
334  if (state&&state->isElementEnabled(SoGLCacheContextElement::getClassStackIndex())) {
335  //Encourage auto caching
336  SoGLCacheContextElement::shouldAutoCache(state, SoGLCacheContextElement::DO_AUTO_CACHE);
337 #if ((COIN_MAJOR_VERSION>=3)||((COIN_MAJOR_VERSION==2)&&(COIN_MINOR_VERSION>=5)))
338  SoGLCacheContextElement::incNumShapes(state);
339 #endif
340  }
341 }
342 
343 // getChildren
344 SoChildList *SoPcons::getChildren() const {
345  return m_children.get();
346 }
347 
348 
349 // computeBBox
350 void SoPcons::computeBBox(SoAction *, SbBox3f &box, SbVec3f &center ){
351  if (fRmax.getNum()< 2) return;
352  if (fRmin.getNum()< 2) return;
353  if (fDz.getNum() < 2) return;
354 
355  double MinMin = fRmin[0];
356  double MaxMax = fRmax[0];
357 
358  double ZMin = fDz[0];
359  double ZMax = fDz[0];
360 
361 
362  for (int i=1;i<fRmin.getNum();++i) {
363  if (fRmin[i]<MinMin) MinMin=fRmin[i];
364  }
365 
366  for (int i=1;i<fRmax.getNum();++i) {
367  if (fRmax[i]>MaxMax) MaxMax=fRmax[i];
368  }
369 
370  for (int i=1;i<fDz.getNum();++i) {
371  if (fDz[i]>ZMax) ZMax=fDz[i];
372  if (fDz[i]<ZMin) ZMin=fDz[i];
373  }
374 
375  RevolutionSurfaceUtil::setBBoxPars(fSPhi.getValue(), fDPhi.getValue(),
376  MinMin, MaxMax,
377  ZMin,ZMax,
378  box, center );
379 }
380 
381 
382 
383 
384 // updateChildren
386 
387 #ifdef IMPLEMENTED
388 
389  // (Not implemented so you do not get an alternate rep. Too bad.)
390 
391  // Redraw the G4Pcons....
392 
393  assert(m_children->getLength()==1);
394  SoSeparator *sep = (SoSeparator *) ( *m_children)[0];
395  SoCoordinate3 *theCoordinates = (SoCoordinate3 *) ( sep->getChild(0));
396  SoNormal *theNormals = (SoNormal *) ( sep->getChild(1));
397  SoNormalBinding *theNormalBinding = (SoNormalBinding *) ( sep->getChild(2));
398  SoIndexedFaceSet *theFaceSet = (SoIndexedFaceSet *) ( sep->getChild(3));
399 
400  const int NPHI=96, NPOINTS=2*(2*NPHI+2), NFACES=4*NPHI+2, NINDICES = NFACES*5;
401  float points[NPOINTS][3], normals[NFACES][3];
402 #ifdef INVENTOR2_0
403  static long indices[NINDICES];
404 #else
405  static int32_t indices[NINDICES];
406 #endif
407  static int init=0;
408  double phi, pp, DeltaPhi;
409 
410  double fRmax1,
411  fRmax2,
412  fRMin1,
413  fRmin2;
414  // Indices need to be generated once! This is here to keep it close to the point
415  // generation, since otherwise it will be confusing.
416 
417  int i;
418  if (!init) {
419  init = 1;
420  // Outer face
421  for (i = 0; i< NPHI; i++) {
422  // 0 1 3 2;
423  indices[5*i+0] = 2*i+0;
424  indices[5*i+1] = 2*i+1;
425  indices[5*i+2] = 2*i+3;
426  indices[5*i+3] = 2*i+2;
427  indices[5*i+4] = SO_END_FACE_INDEX;
428  }
429  // the inner face
430  for (i=0;i<NPHI;i++) {
431  indices[5*1*NPHI + 5*i+0] = 2*NPHI+2 + 2*i+0;
432  indices[5*1*NPHI + 5*i+1] = 2*NPHI+2 + 2*i+1;
433  indices[5*1*NPHI + 5*i+2] = 2*NPHI+2 + 2*i+3;
434  indices[5*1*NPHI + 5*i+3] = 2*NPHI+2 + 2*i+2;
435  indices[5*1*NPHI + 5*i+4] = SO_END_FACE_INDEX;
436  }
437  // the top side
438  for (i=0;i<NPHI;i++) {
439  indices[5*2*NPHI + 5*i+0] = 2*i+0;
440  indices[5*2*NPHI + 5*i+1] = 2*i+2;
441  indices[5*2*NPHI + 5*i+2] = NPOINTS - (2*i+4);
442  indices[5*2*NPHI + 5*i+3] = NPOINTS - (2*i+2);
443  indices[5*2*NPHI + 5*i+4] = SO_END_FACE_INDEX;
444  }
445  // the bottom side
446  for (i=0;i<NPHI;i++) {
447  indices[5*3*NPHI + 5*i+0] = 2*i+1;
448  indices[5*3*NPHI + 5*i+1] = NPOINTS - (2*i+1);
449  indices[5*3*NPHI + 5*i+2] = NPOINTS - (2*i+3);
450  indices[5*3*NPHI + 5*i+3] = 2*i+3;
451  indices[5*3*NPHI + 5*i+4] = SO_END_FACE_INDEX;
452  }
453  // the odd side
454  indices[5*4*NPHI +0] = 2*NPHI;
455  indices[5*4*NPHI +1] = 2*NPHI+1;
456  indices[5*4*NPHI +2] = 2*NPHI+3;
457  indices[5*4*NPHI +3] = 2*NPHI+2;
458  indices[5*4*NPHI +4] = SO_END_FACE_INDEX;
459  // aother odd side
460  indices[5*4*NPHI +5 +0] = 0;
461  indices[5*4*NPHI +5 +1] = NPOINTS-2;
462  indices[5*4*NPHI +5 +2] = NPOINTS-1;
463  indices[5*4*NPHI +5 +3] = 1;
464  indices[5*4*NPHI +5 +4] = SO_END_FACE_INDEX;
465  }
466  // Points need to be generated each time:
467  // The outer surface
468  DeltaPhi = fDPhi.getValue()/NPHI, phi = fSPhi.getValue();
469  float t,st,ct;
470  t = FATAN((fRmax2.getValue()-fRmax1.getValue())/(2*fDz.getValue()));
471  st = FSIN(t);
472  ct = FCOS(t);
473  for (i = 0; i<=NPHI; i++) {
474  points[2*i+0][0] = fRmax2.getValue()*FCOS(phi);
475  points[2*i+0][1] = fRmax2.getValue()*FSIN(phi);
476  points[2*i+0][2] = +fDz.getValue();
477  points[2*i+1][0] = fRmax1.getValue()*FCOS(phi);
478  points[2*i+1][1] = fRmax1.getValue()*FSIN(phi);
479  points[2*i+1][2] = -fDz.getValue();
480  pp = phi+DeltaPhi/2.0;
481  if (i!=NPHI) {
482  normals[i][0] = ct * FCOS(pp);
483  normals[i][1] = ct * FSIN(pp);
484  normals[i][2] = -st;
485  }
486  phi+=DeltaPhi;
487  }
488  // The inner surface
489  phi = fSPhi.getValue() + fDPhi.getValue();
490  t = FATAN((fRmin2.getValue()-fRmin1.getValue())/(2*fDz.getValue()));
491  st = FSIN(t);
492  ct = FCOS(t);
493  for (i = 0; i<=NPHI; i++) {
494  points[2*NPHI+2+2*i+0][0] = fRmin2.getValue()*FCOS(phi);
495  points[2*NPHI+2+2*i+0][1] = fRmin2.getValue()*FSIN(phi);
496  points[2*NPHI+2+2*i+0][2] = +fDz.getValue();
497  points[2*NPHI+2+2*i+1][0] = fRmin1.getValue()*FCOS(phi);
498  points[2*NPHI+2+2*i+1][1] = fRmin1.getValue()*FSIN(phi);
499  points[2*NPHI+2+2*i+1][2] = -fDz.getValue();
500  pp = phi-DeltaPhi/2.0;
501  if (i!=NPHI) {
502  normals[NPHI+i][0] = -ct*FCOS(pp);
503  normals[NPHI+i][1] = -ct*FSIN(pp);
504  normals[NPHI+i][2] = st;
505  }
506  phi-=DeltaPhi;
507  }
508  // The top side
509  for (i=0;i<NPHI;i++) {
510  normals[2*NPHI+i][0]=normals[2*NPHI+i][1]=0;
511  normals[2*NPHI+i][2]= 1.0;
512  }
513  // The bottom side
514  for (i=0;i<NPHI;i++) {
515  normals[3*NPHI+i][0]=normals[3*NPHI+i][1]=0;
516  normals[3*NPHI+i][2]= -1.0;
517  }
518  // The odd side
519  phi = fSPhi.getValue();
520  normals[4*NPHI+0][0]= FSIN(phi);
521  normals[4*NPHI+0][1]= -FCOS(phi);
522  normals[4*NPHI+0][2]= 0;
523 
524  // Another odd side
525  phi = fSPhi.getValue()+fDPhi.getValue();
526  normals[4*NPHI+1][0]= -FSIN(phi);
527  normals[4*NPHI+1][1]= +FCOS(phi);
528  normals[4*NPHI+1][2]=0;
529 
530  for (int np=0;np<NPOINTS;np++) theCoordinates->point.set1Value(np,points[np][0],points[np][1],points[np][2]);
531  theFaceSet->coordIndex.setValues(0,NINDICES,indices);
532  if (smoothDraw.getValue()) {
533  // This Line is replaced by the next one because of an apparent Bug in Inventor (mem. leak).
534  // theNormals->vector.deleteValues(0);
535  for (int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
536  theNormalBinding->value=SoNormalBinding::PER_FACE;
537  }
538  else {
539  for (int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
540  theNormalBinding->value=SoNormalBinding::PER_FACE;
541  }
542 #endif
543 }
544 
545 // generateChildren
547 #ifdef IMPLEMENTED
548  // (Not implemented so you do not get an alternate rep. Too bad.)
549 
550 
551  // This routines creates one SoSeparator, one SoCoordinate3, and
552  // one SoLineSet, and puts it in the child list. This is done only
553  // once, whereas redrawing the position of the coordinates occurs each
554  // time an update is necessary, in the updateChildren routine.
555 
556  assert(m_children->getLength() ==0);
557  SoSeparator *sep = new SoSeparator();
558  SoCoordinate3 *theCoordinates = new SoCoordinate3();
559  SoNormal *theNormals = new SoNormal();
560  SoNormalBinding *theNormalBinding = new SoNormalBinding();
561  SoIndexedFaceSet *theFaceSet = new SoIndexedFaceSet();
562  //
563  // This line costs some in render quality! but gives speed.
564  //
565  sep->addChild(theCoordinates);
566  sep->addChild(theNormals);
567  sep->addChild(theNormalBinding);
568  sep->addChild(theFaceSet);
569  m_children->append(sep);
570 #endif
571 }
572 
573 // generateAlternateRep
574 #include <vector>
575 
577 
578  // This routine sets the alternate representation to the child
579  // list of this mode.
580 
581  //if (m_children->getLength() == 0) generateChildren();
582  //updateChildren();
583  // alternateRep.setValue((SoSeparator *) ( *m_children)[0]);
584 
585 
586  /* updated for generate fullfill alternaterep
587  ***********************************************
588  As First we collect point and triangle strip
589  bounds same as in draw function.
590  there is copied draw function contents and
591  replased unused part;
592 
593  Source code was taked from render part, and modified
594  for collect nessesary information, and build alternate
595  geometry.
596  **********************************************
597  */
598  const int NPHI = 96;
599 
600  // This variable is used to store each vertex
601  SoPrimitiveVertex pv;
602 
603  //For collect points in Pcon geometry chunk
604  std::vector<SoPrimitiveVertex> vls; //Vertex List
605 
606  //For collect all triangles
607  std::vector<SoPrimitiveVertex> fls; //Face list. face here is qudrangle
608 
609  // See if we have to use a texture coordinate function,
610  // rather than generating explicit texture coordinates.
611 
612  SbVec4f texCoord;
613  texCoord[2] = 0.0;
614  texCoord[3] = 1.0;
615  SbVec3f point, normal;
616 
618  //-----------------------------------------------------
619 #define N_GEN_VERTEX(ls, pv,x,y,z,s,t,nx,ny,nz) \
620  point.setValue((float)(x),(float)(y),(float)(z)); \
621  normal.setValue((float)(nx),(float)(ny),(float)(nz)); \
622  texCoord[0]=(float)(s); \
623  texCoord[1]=(float)(t); \
624  pv.setPoint(point); \
625  pv.setNormal(normal); \
626  pv.setTextureCoords(texCoord); \
627  ls.push_back(pv);
628  //-----------------------------------------------------
630  if (fRmin.getNum()!=fRmax.getNum() || fRmax.getNum() != fDz.getNum()) {
631  return;
632  }
633 
634  int nSeg = fRmin.getNum()-1;
635  if (nSeg<1) {
636  return;
637  }
638 
639  for (int p=0;p<nSeg;p++) {
640 
641  double rMin1= fRmin[p];
642  double rMin2= fRmin[p+1];
643 
644  double rMax1= fRmax[p];
645  double rMax2= fRmax[p+1];
646 
647  double zMin = fDz[p];
648  double zMax= fDz[p+1];
649 
650  double deltaPhi = fDPhi.getValue()/NPHI;
651  double phi0 = fSPhi.getValue();
652  double phi1 = phi0 + fDPhi.getValue();
653  double cosPhi0 = cos(phi0);
654  double sinPhi0 = sin(phi0);
655  double cosPhi1 = cos(phi1);
656  double sinPhi1 = sin(phi1);
657  double cosDeltaPhi = cos(deltaPhi);
658  double sinDeltaPhi = sin(deltaPhi);
659 
660  int i;
661  double sinPhi;
662  double cosPhi;
663 
664  const bool noPhiCutout=fabs(fDPhi.getValue())==0.F || fabs(fabs(fDPhi.getValue())-2.0*M_PI)<0.01; // FIXME - better way to do this?
665 
666  //
667  // The outer surface!
668  //
669  double dR =rMax2-rMax1;
670  double dZ =zMax-zMin;
671  double cosTheta = -dR/sqrt(dR*dR+dZ*dZ);
672  double sinTheta = dZ/sqrt(dR*dR+dZ*dZ);
673 
674  sinPhi=sinPhi0;
675  cosPhi=cosPhi0;
676  for (i = 0; i<=NPHI; i++) {
677  N_GEN_VERTEX(vls,pv,rMax2*cosPhi,rMax2*sinPhi,zMax,0.0,0.0,sinTheta*cosPhi,sinTheta*sinPhi,cosTheta);
678  N_GEN_VERTEX(vls,pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,sinTheta*cosPhi,sinTheta*sinPhi,cosTheta);
679  inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
680  }
681 
682  for(i = 0; i < ((int)vls.size() - 2); i += 2){
683  fls.push_back(vls[i + 0]);
684  fls.push_back(vls[i + 1]);
685  fls.push_back(vls[i + 3]);
686  fls.push_back(vls[i + 2]);
687  }
688  vls.clear();
689 
690  //
691  // The inner surface!
692  //
693  sinPhi=sinPhi0;
694  cosPhi=cosPhi0;
695 
696  dR =rMin2-rMin1;
697  dZ =zMax-zMin;
698  cosTheta = -dR/sqrt(dR*dR+dZ*dZ);
699  sinTheta = dZ/sqrt(dR*dR+dZ*dZ);
700 
701  for (i = 0; i<=NPHI; i++) {
702  N_GEN_VERTEX(vls,pv,rMin2*cosPhi,rMin2*sinPhi,zMax,0.0,0.0,-cosPhi*sinTheta,-sinPhi*sinTheta,-cosTheta);
703  N_GEN_VERTEX(vls,pv,rMin1*cosPhi,rMin1*sinPhi,zMin,1.0,1.0,-cosPhi*sinTheta,-sinPhi*sinTheta,-cosTheta);
704  inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
705  }
706  for(i = 0; i < ((int)vls.size() - 2); i += 2){
707  fls.push_back(vls[i + 1]);
708  fls.push_back(vls[i + 0]);
709  fls.push_back(vls[i + 2]);
710  fls.push_back(vls[i + 3]);
711  }
712  vls.clear();
713 
714 
715  if (!noPhiCutout) {
716  //
717  // The end
718  //
719  sinPhi=sinPhi0;
720  cosPhi=cosPhi0;
721  N_GEN_VERTEX(vls, pv,rMax2*cosPhi,rMax2*sinPhi,zMax,0.0,0.0,sinPhi,-cosPhi,0);
722  N_GEN_VERTEX(vls, pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,sinPhi,-cosPhi,0);
723  N_GEN_VERTEX(vls, pv,rMin2*cosPhi,rMin2*sinPhi,zMax,1.0,0.0,sinPhi,-cosPhi,0);
724  N_GEN_VERTEX(vls, pv,rMin1*cosPhi,rMin1*sinPhi,zMin,0.0,1.0,sinPhi,-cosPhi,0);
725  fls.push_back(vls[1]);
726  fls.push_back(vls[0]);
727  fls.push_back(vls[2]);
728  fls.push_back(vls[3]);
729  vls.clear();
730 
731  //
732  // The other end
733  //
734  sinPhi=sinPhi1;
735  cosPhi=cosPhi1;
736  N_GEN_VERTEX(vls, pv,rMax2*cosPhi,rMax2*sinPhi, zMax,0.0,0.0,-sinPhi,+cosPhi,0);
737  N_GEN_VERTEX(vls, pv,rMax1*cosPhi,rMax1*sinPhi, zMin,1.0,1.0,-sinPhi,+cosPhi,0);
738  N_GEN_VERTEX(vls, pv,rMin2*cosPhi,rMin2*sinPhi, zMax,1.0,0.0,-sinPhi,+cosPhi,0);
739  N_GEN_VERTEX(vls, pv,rMin1*cosPhi,rMin1*sinPhi, zMin,0.0,1.0,-sinPhi,+cosPhi,0);
740  fls.push_back(vls[0]);
741  fls.push_back(vls[1]);
742  fls.push_back(vls[3]);
743  fls.push_back(vls[2]);
744  vls.clear();
745  }
746  if (p==(nSeg-1)) {
747  //
748  // The outer surface at z=+PDZ
749  //
750  sinPhi=sinPhi0;
751  cosPhi=cosPhi0;
752  for (i = 0; i<=NPHI; i++) {
753  N_GEN_VERTEX(vls, pv,rMin2*cosPhi,rMin2*sinPhi,zMax,0.0,0.0,0,0,1);
754  N_GEN_VERTEX(vls, pv,rMax2*cosPhi,rMax2*sinPhi,zMax,1.0,1.0,0,0,1);
755  inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
756  }
757  for(i = 0; i < ((int)vls.size() - 2); i += 2){
758  fls.push_back(vls[i + 0]);
759  fls.push_back(vls[i + 1]);
760  fls.push_back(vls[i + 3]);
761  fls.push_back(vls[i + 2]);
762  }
763  vls.clear();
764  }
765  if (p==0) {
766  //
767  // The outer surface at z=-PDZ
768  //
769  sinPhi=sinPhi0;
770  cosPhi=cosPhi0;
771  for (i = 0; i<=NPHI; i++) {
772  N_GEN_VERTEX(vls, pv,rMin1*cosPhi,rMin1*sinPhi,zMin,0.0,0.0,0,0,-1);
773  N_GEN_VERTEX(vls, pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,0,0,-1);
774  inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
775  }
776  for(i = 0; i < ((int)vls.size() - 2); i += 2){
777  fls.push_back(vls[i + 1]);
778  fls.push_back(vls[i + 0]);
779  fls.push_back(vls[i + 2]);
780  fls.push_back(vls[i + 3]);
781  }
782  vls.clear();
783  }
784  }
785  /*
786  *********************************************
787  After finish colecting points of quadrangles,
788  must be builded one monolit geometry,
789  with indexed triangles
790  *********************************************
791  */
792  int numFaces = fls.size() / 4; //Becouse used quadrangular primitives
793  if(numFaces < 0)
794  numFaces = 0;
795 
796  SoVertexProperty *vertices = new SoVertexProperty();
797  for(int i = 0; i < (int)fls.size(); i++){
798  vertices->vertex.set1Value (i, fls[i].getPoint()[0],
799  fls[i].getPoint()[1],
800  fls[i].getPoint()[2]);
801  }
802  fls.clear(); //clearing collected vertices
803 
804  int* faces = new int[5 * numFaces];
805  fprintf(stderr, "\nallocate Faces: %i", numFaces);
806  for(int i = 0; i < numFaces; i++){
807  faces[5 * i] = 4 * i;
808  faces[5 * i + 1] = 4 * i + 1;
809  faces[5 * i + 2] = 4 * i + 2;
810  faces[5 * i + 3] = 4 * i + 3;
811  faces[5 * i + 4] = -1;
812  }
813 
814  SoIndexedFaceSet * faceset = new SoIndexedFaceSet;
815  faceset->coordIndex.setValues(0, 5 * numFaces, faces);
816  delete [] faces;
817  faceset->vertexProperty = vertices;
818  alternateRep.setValue(faceset);
819  fprintf(stderr, "\n");
820  /*
821  *********************************************
822  Finish
823  *********************************************
824  */
825 }
826 
827 // clearAlternateRep
829  alternateRep.setValue(NULL);
830 }
FATAN
#define FATAN(x)
Definition: SbMath.h:18
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
SoPcons
SoPcons - Inventor version of the G4Cons Geant Geometry entity.
Definition: SoPcons.h:42
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
FCOS
#define FCOS(x)
Definition: SbMath.h:13
SoPcons::smoothDraw
SoSFBool smoothDraw
An Inventor option - slightly better render, worse performance.
Definition: SoPcons.h:72
xAOD::deltaPhi
setSAddress setEtaMS setDirPhiMS setDirZMS setBarrelRadius setEndcapAlpha setEndcapRadius setInterceptInner setEtaMap setEtaBin setIsTgcFailure setDeltaPt deltaPhi
Definition: L2StandAloneMuon_v1.cxx:160
SoPcons::inc
void inc(double &sinPhi, double &cosPhi, double sinDeltaPhi, double cosDeltaPhi) const
help with trigonometry. increments sines an cosines by an angle.
Definition: SoPcons.h:148
Trk::indices
std::pair< long int, long int > indices
Definition: AlSymMatBase.h:24
InDetAccessor::phi0
@ phi0
Definition: InDetAccessor.h:33
M_PI
#define M_PI
Definition: ActiveFraction.h:11
get_generator_info.stderr
stderr
Definition: get_generator_info.py:40
SoPcons::clearAlternateRep
virtual void clearAlternateRep()
We better be able to clear it, too!
Definition: SoPcons.cxx:828
SoPcons::fSPhi
SoSFFloat fSPhi
Starting angle, in radians.
Definition: SoPcons.h:64
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
PlotPulseshapeFromCool.np
np
Definition: PlotPulseshapeFromCool.py:64
RevolutionSurfaceUtil::nphiDivisions
static int nphiDivisions(const float &dphi, const float &complexity, int OverrideNPhi=0)
Definition: RevolutionSurfaceUtil.h:21
SoPcons::fDz
SoMFFloat fDz
Z Positions.
Definition: SoPcons.h:60
SoPcons.h
SoPcons::fRmax
SoMFFloat fRmax
Outside radii.
Definition: SoPcons.h:56
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
lumiFormat.i
int i
Definition: lumiFormat.py:85
RevolutionSurfaceUtil::setBBoxPars
static void setBBoxPars(const float &sphi, const float &dphi, const float &rmin, const float &rmax, const float &zmin, const float &zmax, SbBox3f &box, SbVec3f &center)
Definition: RevolutionSurfaceUtil.h:40
SoPcons::updateChildren
void updateChildren()
Used to modify hidden children when a data field is changed.
Definition: SoPcons.cxx:385
SoPcons::initClass
static void initClass()
Class Initializer, required.
Definition: SoPcons.cxx:67
python.Constants.TRUE
bool TRUE
for job options legacy (TODO: get rid of these!) ----------------------—
Definition: Control/AthenaCommon/python/Constants.py:22
SoPcons::fRmin
SoMFFloat fRmin
Inside radii.
Definition: SoPcons.h:52
SoPcons::getChildren
virtual SoChildList * getChildren() const
GetChildList, required whenever the class has hidden children.
Definition: SoPcons.cxx:344
SoPcons::alternateRep
SoSFNode alternateRep
Alternate rep required - for use by users without HEPVis shared objects.
Definition: SoPcons.h:81
SoPcons::drawEdgeLines
SoSFBool drawEdgeLines
Definition: SoPcons.h:83
calibdata.ct
ct
Definition: calibdata.py:418
SoPcons::generateChildren
void generateChildren()
Generate Children.
Definition: SoPcons.cxx:546
grepfile.sep
sep
Definition: grepfile.py:38
FSIN
#define FSIN(x)
Definition: SbMath.h:14
GEN_VERTEX
#define GEN_VERTEX(pv, x, y, z, s, t, nx, ny, nz)
SoPcons::generateAlternateRep
virtual void generateAlternateRep()
Generate AlternateRep, required.
Definition: SoPcons.cxx:576
SoPcons::pOverrideNPhi
SoSFInt32 pOverrideNPhi
Override number of phi subdivision used for rendering shape (i.e.
Definition: SoPcons.h:77
N_GEN_VERTEX
#define N_GEN_VERTEX(ls, pv, x, y, z, s, t, nx, ny, nz)
python.PyKernel.init
def init(v_theApp, v_rootStream=None)
Definition: PyKernel.py:45
SoPcons::fDPhi
SoSFFloat fDPhi
Delta-angle, in radians.
Definition: SoPcons.h:68
python.CaloScaleNoiseConfig.action
action
Definition: CaloScaleNoiseConfig.py:77
RevolutionSurfaceUtil.h
SoPcons::computeBBox
virtual void computeBBox(SoAction *action, SbBox3f &box, SbVec3f &center)
compute bounding Box, required
Definition: SoPcons.cxx:350
python.changerun.pv
pv
Definition: changerun.py:81
SoPcons::m_children
std::unique_ptr< SoChildList > m_children
ChildList. Required whenever the class has hidden children.
Definition: SoPcons.h:143
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
Ringer::getType
T getType(const char *cStr)
Return Ringer enumeration of type T identifying string type:
jobOptions.points
points
Definition: jobOptions.GenevaPy8_Zmumu.py:97
SoPcons::generatePrimitives
virtual void generatePrimitives(SoAction *action)
Generate Primitives, required.
Definition: SoPcons.cxx:76