ATLAS Offline Software
Loading...
Searching...
No Matches
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/*--------------------------------------------------------------------------*/
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
35SO_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
76void SoPcons::generatePrimitives(SoAction *action) {
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=
88 (SoTextureCoordinateElement::getType(state) ==
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) \
107point.setValue((float)(x),(float)(y),(float)(z)); \
108normal.setValue((float)(nx),(float)(ny),(float)(nz)); \
109if (useTexFunction) { \
110texCoord=tce->get(point,normal); \
111} else { \
112texCoord[0]=(float)(s); \
113texCoord[1]=(float)(t); \
114} \
115pv.setPoint(point); \
116pv.setNormal(normal); \
117pv.setTextureCoords(texCoord); \
118shapeVertex(&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
344SoChildList *SoPcons::getChildren() const {
345 return m_children.get();
346}
347
348
349// computeBBox
350void 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}
#define M_PI
Scalar deltaPhi(const MatrixBase< Derived > &vec) const
Scalar phi() const
phi method
#define FCOS(x)
Definition SbMath.h:13
#define FSIN(x)
Definition SbMath.h:14
#define FATAN(x)
Definition SbMath.h:18
#define GEN_VERTEX(pv, x, y, z, s, t, nx, ny, nz)
#define N_GEN_VERTEX(ls, pv, x, y, z, s, t, nx, ny, nz)
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)
static int nphiDivisions(const float &dphi, const float &complexity, int OverrideNPhi=0)
SoPcons - Inventor version of the G4Cons Geant Geometry entity.
Definition SoPcons.h:42
SoMFFloat fRmax
Outside radii.
Definition SoPcons.h:56
SoSFFloat fDPhi
Delta-angle, in radians.
Definition SoPcons.h:68
SoSFNode alternateRep
Alternate rep required - for use by users without HEPVis shared objects.
Definition SoPcons.h:81
SoSFFloat fSPhi
Starting angle, in radians.
Definition SoPcons.h:64
SoSFBool drawEdgeLines
Definition SoPcons.h:83
virtual void clearAlternateRep()
We better be able to clear it, too!
Definition SoPcons.cxx:828
std::unique_ptr< SoChildList > m_children
ChildList. Required whenever the class has hidden children.
Definition SoPcons.h:143
SoPcons()
Constructor, required.
Definition SoPcons.cxx:38
SoMFFloat fRmin
Inside radii.
Definition SoPcons.h:52
virtual void generatePrimitives(SoAction *action)
Generate Primitives, required.
Definition SoPcons.cxx:76
SoSFInt32 pOverrideNPhi
Override number of phi subdivision used for rendering shape (i.e.
Definition SoPcons.h:77
void updateChildren()
Used to modify hidden children when a data field is changed.
Definition SoPcons.cxx:385
static void initClass()
Class Initializer, required.
Definition SoPcons.cxx:67
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
virtual void computeBBox(SoAction *action, SbBox3f &box, SbVec3f &center)
compute bounding Box, required
Definition SoPcons.cxx:350
void generateChildren()
Generate Children.
Definition SoPcons.cxx:546
virtual SoChildList * getChildren() const
GetChildList, required whenever the class has hidden children.
Definition SoPcons.cxx:344
SoSFBool smoothDraw
An Inventor option - slightly better render, worse performance.
Definition SoPcons.h:72
SoMFFloat fDz
Z Positions.
Definition SoPcons.h:60
virtual void generateAlternateRep()
Generate AlternateRep, required.
Definition SoPcons.cxx:576