Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SoCons.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27//
28//
29/*-----------------------------HEPVis---------------------------------------*/
30/* */
31/* Node: SoCons */
32/* Description: Represents the G4Cons Geant Geometry entity */
33/* Author: Joe Boudreau Nov 11 1996 */
34/* */
35/*--------------------------------------------------------------------------*/
36
37// this :
38#include "HEPVis/nodes/SoCons.h"
39
40#include <assert.h>
41#include <cmath>
42#include <Inventor/SbBox.h>
43#include <Inventor/actions/SoAction.h>
44#include <Inventor/fields/SoSFFloat.h>
45#include <Inventor/misc/SoChildList.h>
46#include <Inventor/nodes/SoSeparator.h>
47#include <Inventor/nodes/SoIndexedFaceSet.h>
48#include <Inventor/nodes/SoNormal.h>
49#include <Inventor/nodes/SoCoordinate3.h>
50#include <Inventor/nodes/SoNormalBinding.h>
51#include <Inventor/SoPrimitiveVertex.h>
52#include <Inventor/elements/SoTextureCoordinateElement.h>
53
54#include "HEPVis/SbMath.h"
55
56// This statement is required
57SO_NODE_SOURCE(SoCons)
58
59// Constructor
61 // This statement is required
62 SO_NODE_CONSTRUCTOR(SoCons);
63
64 // Data fields are initialized like this:
65 SO_NODE_ADD_FIELD(fRmin1, (0.0));
66 SO_NODE_ADD_FIELD(fRmin2, (0.0));
67 SO_NODE_ADD_FIELD(fRmax1, (1.0));
68 SO_NODE_ADD_FIELD(fRmax2, (1.0));
69 SO_NODE_ADD_FIELD(fDz, (10.0));
70 SO_NODE_ADD_FIELD(fSPhi, (0.0));
71 SO_NODE_ADD_FIELD(fDPhi, ((float)(2*M_PI)));
72 SO_NODE_ADD_FIELD(smoothDraw, (TRUE));
73 SO_NODE_ADD_FIELD(alternateRep, (NULL));
74 children = new SoChildList(this);
75}
76
77// Destructor
79 delete children;
80}
81
82
83// initClass
85 // This statement is required.
86 static bool first = true;
87 if (first) {
88 first = false;
89 SO_NODE_INIT_CLASS(SoCons,SoShape,"Shape");
90 }
91}
92
93
94// generatePrimitives
95void SoCons::generatePrimitives(SoAction *action) {
96 // This variable is used to store each vertex
97 SoPrimitiveVertex pv;
98
99 // Access the stat from the action
100 SoState *state = action->getState();
101
102 // See if we have to use a texture coordinate function,
103 // rather than generating explicit texture coordinates.
104 SbBool useTexFunction=
105 (SoTextureCoordinateElement::getType(state) ==
106 SoTextureCoordinateElement::FUNCTION);
107
108 // If we need to generate texture coordinates with a function,
109 // we'll need an SoGLTextureCoordinateElement. Otherwise, we'll
110 // set up the coordinates directly.
111 const SoTextureCoordinateElement *tce = NULL;
112 SbVec4f texCoord;
113 if (useTexFunction) {
114 tce = SoTextureCoordinateElement::getInstance(state);
115 } else {
116 texCoord[2] = 0.0;
117 texCoord[3] = 1.0;
118 }
119 SbVec3f point, normal;
120
121 ///////////////////////////////////////////////////////
122 //-----------------------------------------------------
123#define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \
124 point.setValue((float)(x),(float)(y),(float)(z)); \
125 normal.setValue((float)(nx),(float)(ny),(float)(nz)); \
126 if (useTexFunction) { \
127 texCoord=tce->get(point,normal); \
128 } else { \
129 texCoord[0]=(float)(s); \
130 texCoord[1]=(float)(t); \
131 } \
132 pv.setPoint(point); \
133 pv.setNormal(normal); \
134 pv.setTextureCoords(texCoord); \
135 shapeVertex(&pv);
136 //-----------------------------------------------------
137 ///////////////////////////////////////////////////////
138
139
140 int NPHI = (int)(2+22*std::fabs(fDPhi.getValue()/(2.0*M_PI)));
141 double deltaPhi = fDPhi.getValue()/NPHI;
142 double phi0 = fSPhi.getValue();
143 double phi1 = phi0 + fDPhi.getValue();
144 double rMax1 = fRmax1.getValue();
145 double rMin1 = fRmin1.getValue();
146 double rMax2 = fRmax2.getValue();
147 double rMin2 = fRmin2.getValue();
148 double zMax = fDz.getValue();
149 double zMin = -zMax;
150 double cosPhi0 = std::cos(phi0);
151 double sinPhi0 = std::sin(phi0);
152 double cosPhi1 = std::cos(phi1);
153 double sinPhi1 = std::sin(phi1);
154 double cosDeltaPhi = std::cos(deltaPhi);
155 double sinDeltaPhi = std::sin(deltaPhi);
156 //
157 // The outer surface!
158 //
159 beginShape(action,TRIANGLE_STRIP);
160 int i;
161 double sinPhi=sinPhi0;
162 double cosPhi=cosPhi0;
163 for (i = 0; i<=NPHI; i++) {
164 GEN_VERTEX(pv,rMax2*cosPhi,rMax2*sinPhi,zMax,0.0,0.0,cosPhi,sinPhi,0);
165 GEN_VERTEX(pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,cosPhi,sinPhi,0);
166 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
167 }
168 endShape();
169 //
170 // The inner surface!
171 //
172 beginShape(action,TRIANGLE_STRIP);
173 sinPhi=sinPhi0;
174 cosPhi=cosPhi0;
175 for (i = 0; i<=NPHI; i++) {
176 GEN_VERTEX(pv,rMin2*cosPhi,rMin2*sinPhi,zMax,0.0,0.0,-cosPhi,-sinPhi,0);
177 GEN_VERTEX(pv,rMin1*cosPhi,rMin1*sinPhi,zMin,1.0,1.0,-cosPhi,-sinPhi,0);
178 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
179 }
180 endShape();
181 if (std::fabs(deltaPhi)<2.0*M_PI) {
182 //
183 // The end
184 //
185 beginShape(action,TRIANGLE_STRIP);
186 sinPhi=sinPhi0;
187 cosPhi=cosPhi0;
188 GEN_VERTEX(pv,rMax2*cosPhi,rMax2*sinPhi,zMax,0.0,0.0,sinPhi,-cosPhi,0);
189 GEN_VERTEX(pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,sinPhi,-cosPhi,0);
190 GEN_VERTEX(pv,rMin2*cosPhi,rMin2*sinPhi,zMax,1.0,0.0,sinPhi,-cosPhi,0);
191 GEN_VERTEX(pv,rMin1*cosPhi,rMin1*sinPhi,zMin,0.0,1.0,sinPhi,-cosPhi,0);
192 endShape();
193 //
194 // The other end
195 //
196 beginShape(action,TRIANGLE_STRIP);
197 sinPhi=sinPhi1;
198 cosPhi=cosPhi1;
199 GEN_VERTEX(pv,rMax2*cosPhi,rMax2*sinPhi, zMax,0.0,0.0,-sinPhi,+cosPhi,0);
200 GEN_VERTEX(pv,rMax1*cosPhi,rMax1*sinPhi, zMin,1.0,1.0,-sinPhi,+cosPhi,0);
201 GEN_VERTEX(pv,rMin2*cosPhi,rMin2*sinPhi, zMax,1.0,0.0,-sinPhi,+cosPhi,0);
202 GEN_VERTEX(pv,rMin1*cosPhi,rMin1*sinPhi, zMin,0.0,1.0,-sinPhi,+cosPhi,0);
203 endShape();
204 }
205
206 //
207 // The outer surface at z=+PDZ
208 //
209 beginShape(action,TRIANGLE_STRIP);
210 sinPhi=sinPhi0;
211 cosPhi=cosPhi0;
212 for (i = 0; i<=NPHI; i++) {
213 GEN_VERTEX(pv,rMin2*cosPhi,rMin2*sinPhi,zMax,0.0,0.0,0,0,1);
214 GEN_VERTEX(pv,rMax2*cosPhi,rMax2*sinPhi,zMax,1.0,1.0,0,0,1);
215 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
216 }
217 endShape();
218 //
219 // The outer surface at z=-PDZ
220 //
221 beginShape(action,TRIANGLE_STRIP);
222 sinPhi=sinPhi0;
223 cosPhi=cosPhi0;
224 for (i = 0; i<=NPHI; i++) {
225 GEN_VERTEX(pv,rMin1*cosPhi,rMin1*sinPhi,zMin,0.0,0.0,0,0,-1);
226 GEN_VERTEX(pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,0,0,-1);
227 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
228 }
229 endShape();
230
231}
232
233// getChildren
234SoChildList *SoCons::getChildren() const {
235 return children;
236}
237
238
239// computeBBox
240void SoCons::computeBBox(SoAction *, SbBox3f &box, SbVec3f &center ){
241 float fRmax= fRmax1.getValue();
242 if (fRmax2.getValue() > fRmax) fRmax = fRmax2.getValue();
243
244 SbVec3f vmin(-fRmax,-fRmax,-fDz.getValue()),
245 vmax( fRmax, fRmax, fDz.getValue());
246 center.setValue(0,0,0);
247 box.setBounds(vmin,vmax);
248}
249
250
251
252
253// updateChildren
254void SoCons::updateChildren() {
255
256
257 // Redraw the G4Cons....
258
259 assert(children->getLength()==1);
260 SoSeparator *sep = (SoSeparator *) ( *children)[0];
261 SoCoordinate3 *theCoordinates = (SoCoordinate3 *) ( sep->getChild(0));
262 SoNormal *theNormals = (SoNormal *) ( sep->getChild(1));
263 SoNormalBinding *theNormalBinding = (SoNormalBinding *) ( sep->getChild(2));
264 SoIndexedFaceSet *theFaceSet = (SoIndexedFaceSet *) ( sep->getChild(3));
265
266 const int NPHI=24, NPOINTS=2*(2*NPHI+2), NFACES=4*NPHI+2, NINDICES = NFACES*5;
267 float points[NPOINTS][3], normals[NFACES][3];
268#ifdef INVENTOR2_0
269 static long indices[NINDICES];
270#else
271 static int32_t indices[NINDICES];
272#endif
273 static int init=0;
274 double phi, pp, DeltaPhi;
275
276 // Indices need to be generated once! This is here to keep it close to the point
277 // generation, since otherwise it will be confusing.
278
279 int i;
280 if (!init) {
281 init = 1;
282 // Outer face
283 for (i = 0; i< NPHI; i++) {
284 // 0 1 3 2;
285 indices[5*i+0] = 2*i+0;
286 indices[5*i+1] = 2*i+1;
287 indices[5*i+2] = 2*i+3;
288 indices[5*i+3] = 2*i+2;
289 indices[5*i+4] = SO_END_FACE_INDEX;
290 }
291 // the inner face
292 for (i=0;i<NPHI;i++) {
293 indices[5*1*NPHI + 5*i+0] = 2*NPHI+2 + 2*i+0;
294 indices[5*1*NPHI + 5*i+1] = 2*NPHI+2 + 2*i+1;
295 indices[5*1*NPHI + 5*i+2] = 2*NPHI+2 + 2*i+3;
296 indices[5*1*NPHI + 5*i+3] = 2*NPHI+2 + 2*i+2;
297 indices[5*1*NPHI + 5*i+4] = SO_END_FACE_INDEX;
298 }
299 // the top side
300 for (i=0;i<NPHI;i++) {
301 indices[5*2*NPHI + 5*i+0] = 2*i+0;
302 indices[5*2*NPHI + 5*i+1] = 2*i+2;
303 indices[5*2*NPHI + 5*i+2] = NPOINTS - (2*i+4);
304 indices[5*2*NPHI + 5*i+3] = NPOINTS - (2*i+2);
305 indices[5*2*NPHI + 5*i+4] = SO_END_FACE_INDEX;
306 }
307 // the bottom side
308 for (i=0;i<NPHI;i++) {
309 indices[5*3*NPHI + 5*i+0] = 2*i+1;
310 indices[5*3*NPHI + 5*i+1] = NPOINTS - (2*i+1);
311 indices[5*3*NPHI + 5*i+2] = NPOINTS - (2*i+3);
312 indices[5*3*NPHI + 5*i+3] = 2*i+3;
313 indices[5*3*NPHI + 5*i+4] = SO_END_FACE_INDEX;
314 }
315 // the odd side
316 indices[5*4*NPHI +0] = 2*NPHI;
317 indices[5*4*NPHI +1] = 2*NPHI+1;
318 indices[5*4*NPHI +2] = 2*NPHI+3;
319 indices[5*4*NPHI +3] = 2*NPHI+2;
320 indices[5*4*NPHI +4] = SO_END_FACE_INDEX;
321 // aother odd side
322 indices[5*4*NPHI +5 +0] = 0;
323 indices[5*4*NPHI +5 +1] = NPOINTS-2;
324 indices[5*4*NPHI +5 +2] = NPOINTS-1;
325 indices[5*4*NPHI +5 +3] = 1;
326 indices[5*4*NPHI +5 +4] = SO_END_FACE_INDEX;
327 }
328 // Points need to be generated each time:
329 // The outer surface
330 DeltaPhi = fDPhi.getValue()/NPHI, phi = fSPhi.getValue();
331 float t,st,ct;
332 t = FATAN((fRmax2.getValue()-fRmax1.getValue())/(2*fDz.getValue()));
333 st = FSIN(t);
334 ct = FCOS(t);
335 for (i = 0; i<=NPHI; i++) {
336 points[2*i+0][0] = fRmax2.getValue()*FCOS(phi);
337 points[2*i+0][1] = fRmax2.getValue()*FSIN(phi);
338 points[2*i+0][2] = +fDz.getValue();
339 points[2*i+1][0] = fRmax1.getValue()*FCOS(phi);
340 points[2*i+1][1] = fRmax1.getValue()*FSIN(phi);
341 points[2*i+1][2] = -fDz.getValue();
342 pp = phi+DeltaPhi/2.0;
343 if (i!=NPHI) {
344 normals[i][0] = ct * FCOS(pp);
345 normals[i][1] = ct * FSIN(pp);
346 normals[i][2] = -st;
347 }
348 phi+=DeltaPhi;
349 }
350 // The inner surface
351 phi = fSPhi.getValue() + fDPhi.getValue();
352 t = FATAN((fRmin2.getValue()-fRmin1.getValue())/(2*fDz.getValue()));
353 st = FSIN(t);
354 ct = FCOS(t);
355 for (i = 0; i<=NPHI; i++) {
356 points[2*NPHI+2+2*i+0][0] = fRmin2.getValue()*FCOS(phi);
357 points[2*NPHI+2+2*i+0][1] = fRmin2.getValue()*FSIN(phi);
358 points[2*NPHI+2+2*i+0][2] = +fDz.getValue();
359 points[2*NPHI+2+2*i+1][0] = fRmin1.getValue()*FCOS(phi);
360 points[2*NPHI+2+2*i+1][1] = fRmin1.getValue()*FSIN(phi);
361 points[2*NPHI+2+2*i+1][2] = -fDz.getValue();
362 pp = phi-DeltaPhi/2.0;
363 if (i!=NPHI) {
364 normals[NPHI+i][0] = -ct*FCOS(pp);
365 normals[NPHI+i][1] = -ct*FSIN(pp);
366 normals[NPHI+i][2] = st;
367 }
368 phi-=DeltaPhi;
369 }
370 // The top side
371 for (i=0;i<NPHI;i++) {
372 normals[2*NPHI+i][0]=normals[2*NPHI+i][1]=0;
373 normals[2*NPHI+i][2]= 1.0;
374 }
375 // The bottom side
376 for (i=0;i<NPHI;i++) {
377 normals[3*NPHI+i][0]=normals[3*NPHI+i][1]=0;
378 normals[3*NPHI+i][2]= -1.0;
379 }
380 // The odd side
381 phi = fSPhi.getValue();
382 normals[4*NPHI+0][0]= FSIN(phi);
383 normals[4*NPHI+0][1]= -FCOS(phi);
384 normals[4*NPHI+0][2]= 0;
385
386 // Another odd side
387 phi = fSPhi.getValue()+fDPhi.getValue();
388 normals[4*NPHI+1][0]= -FSIN(phi);
389 normals[4*NPHI+1][1]= +FCOS(phi);
390 normals[4*NPHI+1][2]=0;
391
392 for (int np=0;np<NPOINTS;np++) theCoordinates->point.set1Value(np,points[np][0],points[np][1],points[np][2]);
393 theFaceSet->coordIndex.setValues(0,NINDICES,indices);
394 if (smoothDraw.getValue()) {
395 // This Line is replaced by the next one because of an apparent Bug in Inventor (mem. leak).
396 // theNormals->vector.deleteValues(0);
397 for (int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
398 theNormalBinding->value=SoNormalBinding::PER_FACE;
399 }
400 else {
401 for (int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
402 theNormalBinding->value=SoNormalBinding::PER_FACE;
403 }
404}
405
406// generateChildren
407void SoCons::generateChildren() {
408
409 // This routines creates one SoSeparator, one SoCoordinate3, and
410 // one SoLineSet, and puts it in the child list. This is done only
411 // once, whereas redrawing the position of the coordinates occurs each
412 // time an update is necessary, in the updateChildren routine.
413
414 assert(children->getLength() ==0);
415 SoSeparator *sep = new SoSeparator();
416 SoCoordinate3 *theCoordinates = new SoCoordinate3();
417 SoNormal *theNormals = new SoNormal();
418 SoNormalBinding *theNormalBinding = new SoNormalBinding();
419 SoIndexedFaceSet *theFaceSet = new SoIndexedFaceSet();
420 //
421 // This line costs some in render quality! but gives speed.
422 //
423 sep->addChild(theCoordinates);
424 sep->addChild(theNormals);
425 sep->addChild(theNormalBinding);
426 sep->addChild(theFaceSet);
427 children->append(sep);
428}
429
430// generateAlternateRep
432
433 // This routine sets the alternate representation to the child
434 // list of this mode.
435
436 if (children->getLength() == 0) generateChildren();
437 updateChildren();
438 alternateRep.setValue((SoSeparator *) ( *children)[0]);
439}
440
441// clearAlternateRep
443 alternateRep.setValue(NULL);
444}
#define FCOS(x)
Definition: SbMath.h:40
#define FSIN(x)
Definition: SbMath.h:41
#define FATAN(x)
Definition: SbMath.h:45
#define M_PI
Definition: SbMath.h:33
#define GEN_VERTEX(pv, x, y, z, s, t, nx, ny, nz)
Definition: SoCons.h:71
virtual void computeBBox(SoAction *action, SbBox3f &box, SbVec3f &center)
compute bounding Box, required
Definition: SoCons.cc:240
SoSFFloat fDPhi
Delta-angle, in radians.
Definition: SoCons.h:105
virtual void generateAlternateRep()
Definition: SoCons.cc:431
virtual void clearAlternateRep()
We better be able to clear it, too!
Definition: SoCons.cc:442
static void initClass()
Class Initializer, required.
Definition: SoCons.cc:84
SoSFFloat fSPhi
Starting angle, in radians.
Definition: SoCons.h:101
SoSFFloat fRmax2
Outside radius at +fDz.
Definition: SoCons.h:93
virtual void generatePrimitives(SoAction *action)
Generate Primitives, required.
Definition: SoCons.cc:95
SoSFFloat fRmax1
Outside radius at -fDz.
Definition: SoCons.h:89
SoSFFloat fRmin1
Inside radius at -fDz.
Definition: SoCons.h:81
SoSFFloat fRmin2
Inside radius at +fDz.
Definition: SoCons.h:85
SoSFNode alternateRep
Alternate rep required - for use by users without HEPVis shared objects.
Definition: SoCons.h:113
SoSFFloat fDz
Half-length along Z.
Definition: SoCons.h:97
virtual SoChildList * getChildren() const
GetChildList, required whenever the class has hidden children.
Definition: SoCons.cc:234
virtual ~SoCons()
Destructor, required.
Definition: SoCons.cc:78
SoSFBool smoothDraw
An Inventor option - slightly better render, worse performance.
Definition: SoCons.h:109
#define TRUE
Definition: globals.hh:41