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