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
SoPolyhedron.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#ifdef G4VIS_BUILD_OI_DRIVER
27
28/*----------------------------HEPVis----------------------------------------*/
29/* */
30/* Node: SoPolyhedron */
31/* Description: SoNode to represent HepPolyhedron */
32/* Author: Guy Barrand */
33/* */
34/*--------------------------------------------------------------------------*/
35
36// this :
37#include "Geant4_SoPolyhedron.h"
38
39#include <Inventor/SbBox.h>
40#include <Inventor/actions/SoAction.h>
41#include <Inventor/SoPrimitiveVertex.h>
42#include <Inventor/elements/SoTextureCoordinateElement.h>
43#include <Inventor/nodes/SoSeparator.h>
44
45//#include <HEPVis/SbMath.h>
46#define SbMinimum(a,b) ((a)<(b)?a:b)
47#define SbMaximum(a,b) ((a)>(b)?a:b)
48
50
51#include "G4Polyhedron.hh"
52
53//typedef SbVec3f HVPoint3D;
54//typedef SbVec3f HVNormal3D;
55
56typedef HepGeom::Point3D<double> HVPoint3D;
57typedef HepGeom::Normal3D<double> HVNormal3D;
58
59SO_NODE_SOURCE(Geant4_SoPolyhedron)
60//////////////////////////////////////////////////////////////////////////////
62)
63//////////////////////////////////////////////////////////////////////////////
64//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
65{
66 SO_NODE_INIT_CLASS(Geant4_SoPolyhedron,SoShape,"Shape");
67}
68//////////////////////////////////////////////////////////////////////////////
70)
71:fPolyhedron(0)
72//////////////////////////////////////////////////////////////////////////////
73//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
74{
75 SO_NODE_CONSTRUCTOR(Geant4_SoPolyhedron);
76 SO_NODE_ADD_FIELD(solid,(TRUE));
77 SO_NODE_ADD_FIELD(reducedWireFrame,(TRUE));
78 SO_NODE_ADD_FIELD(alternateRep,(NULL));
79}
80//////////////////////////////////////////////////////////////////////////////
82 const G4Polyhedron& aPolyhedron
83)
84:fPolyhedron(0)
85//////////////////////////////////////////////////////////////////////////////
86//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
87{
88 SO_NODE_CONSTRUCTOR(Geant4_SoPolyhedron);
89 SO_NODE_ADD_FIELD(solid,(TRUE));
90 SO_NODE_ADD_FIELD(reducedWireFrame,(TRUE));
91 SO_NODE_ADD_FIELD(alternateRep,(NULL));
92
93 fPolyhedron = new G4Polyhedron(aPolyhedron);
94}
95//////////////////////////////////////////////////////////////////////////////
97 G4Polyhedron* aPolyhedron
98)
99:fPolyhedron(aPolyhedron)
100//////////////////////////////////////////////////////////////////////////////
101//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
102{
103 SO_NODE_CONSTRUCTOR(Geant4_SoPolyhedron);
104 SO_NODE_ADD_FIELD(solid,(TRUE));
105 SO_NODE_ADD_FIELD(reducedWireFrame,(TRUE));
106 SO_NODE_ADD_FIELD(alternateRep,(NULL));
107}
108//////////////////////////////////////////////////////////////////////////////
110)
111//////////////////////////////////////////////////////////////////////////////
112//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
113{
114 delete fPolyhedron;
115}
116//////////////////////////////////////////////////////////////////////////////
118 SoAction* aAction
119)
120//////////////////////////////////////////////////////////////////////////////
121//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
122{
123 if(!fPolyhedron) return;
124 if(fPolyhedron->GetNoFacets()<=0) return; // Abnormal polyhedron.
125
126 SoState *state = aAction->getState();
127 SbBool useTexFunction =
128 (SoTextureCoordinateElement::getType(state) ==
129 SoTextureCoordinateElement::FUNCTION);
130 const SoTextureCoordinateElement *tce = NULL;
131 SbVec4f texCoord(0.,0.,0.,0.);
132 if (useTexFunction) {
133 tce = SoTextureCoordinateElement::getInstance(state);
134 } else {
135 texCoord[2] = 0.0;
136 texCoord[3] = 1.0;
137 }
138
139 if(solid.getValue()==TRUE) {
140 SoPrimitiveVertex pv;
141 SbVec3f point, normal;
142 //////////////////////////////////////////
143 //----------------------------------------
144#define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \
145 point.setValue(x,y,z); \
146 normal.setValue(nx,ny,nz); \
147 if (useTexFunction) { \
148 texCoord=tce->get(point,normal); \
149 } else { \
150 texCoord[0]=s; \
151 texCoord[1]=t; \
152 } \
153 pv.setPoint(point); \
154 pv.setNormal(normal); \
155 pv.setTextureCoords(texCoord); \
156 shapeVertex(&pv);
157 //----------------------------------------
158 //////////////////////////////////////////
159
160 // Assume all facets are convex quadrilaterals :
161 bool notLastFace;
162 do {
163 HVNormal3D unitNormal;
164 notLastFace = fPolyhedron->GetNextUnitNormal(unitNormal);
165
166 beginShape(aAction,POLYGON);
167 bool notLastEdge;
168 int edgeFlag = 1;
169 do {
170 HVPoint3D vertex;
171 notLastEdge = fPolyhedron->GetNextVertex(vertex,edgeFlag);
172 GEN_VERTEX(pv,
173 vertex[0],
174 vertex[1],
175 vertex[2],
176 0.0,0.0,
177 unitNormal[0],
178 unitNormal[1],
179 unitNormal[2]);
180 } while (notLastEdge);
181 endShape();
182 } while (notLastFace);
183 } else {
184 SoPrimitiveVertex pvb,pve;
185 pve.setTextureCoords(texCoord);
186 pvb.setTextureCoords(texCoord);
187
188#ifdef __COIN__ // To bypass a bug in invokeLineSegment when picking.
189 beginShape(aAction,POLYGON);
190 endShape();
191#endif
192
193 SbVec3f point;
194 bool notLastFace;
195 do {
196 HVNormal3D unitNormal;
197 notLastFace = fPolyhedron->GetNextUnitNormal(unitNormal);
198
199 SbVec3f normal;
200 normal.setValue(unitNormal[0],unitNormal[1],unitNormal[2]);
201
202 // Treat edges :
203 int edgeFlag = 1;
204 int prevEdgeFlag = edgeFlag;
205 bool notLastEdge;
206 SbBool firstEdge = TRUE;
207 do {
208 HVPoint3D vertex;
209 notLastEdge = fPolyhedron->GetNextVertex(vertex,edgeFlag);
210 if(reducedWireFrame.getValue()==FALSE) edgeFlag = 1;
211 if(firstEdge) {
212 if(edgeFlag > 0) {
213 pvb.setNormal(normal);
214 point.setValue(vertex[0],vertex[1],vertex[2]);
215 pvb.setPoint(point);
216 } else {
217 }
218 firstEdge = FALSE;
219 prevEdgeFlag = edgeFlag;
220 } else {
221 if(edgeFlag!=prevEdgeFlag) {
222 if(edgeFlag > 0) { // Pass to a visible edge :
223 pvb.setNormal(normal);
224 point.setValue(vertex[0],vertex[1],vertex[2]);
225 pvb.setPoint(point);
226 } else { // Pass to an invisible edge :
227 pve.setNormal(normal);
228 point.setValue(vertex[0],vertex[1],vertex[2]);
229 pve.setPoint(point);
230 invokeLineSegmentCallbacks(aAction,&pvb,&pve);
231 }
232 prevEdgeFlag = edgeFlag;
233 } else {
234 if(edgeFlag > 0) {
235 pve.setNormal(normal);
236 point.setValue(vertex[0],vertex[1],vertex[2]);
237 pve.setPoint(point);
238 invokeLineSegmentCallbacks(aAction,&pvb,&pve);
239 pvb = pve;
240 } else {
241 }
242 }
243 }
244 } while (notLastEdge);
245 } while (notLastFace);
246 }
247
248}
249//////////////////////////////////////////////////////////////////////////////
251 SoAction*
252,SbBox3f& aBox
253,SbVec3f& aCenter
254)
255//////////////////////////////////////////////////////////////////////////////
256//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
257{
258 if(!fPolyhedron) return;
259 if(fPolyhedron->GetNoFacets()<=0) { // Abnormal polyhedron.
260 SbVec3f vmin(-1,-1,-1);
261 SbVec3f vmax( 1, 1, 1);
262 aBox.setBounds(vmin,vmax);
263 aCenter.setValue(0,0,0);
264 } else {
265 SbBool first = TRUE;
266 float xmn = 0,ymn = 0,zmn = 0;
267 float xmx = 0,ymx = 0,zmx = 0;
268 float xct = 0,yct = 0,zct = 0;
269 SbVec3f point;
270 int count = 0;
271 // Assume all facets are convex quadrilaterals :
272 bool notLastFace;
273 do {
274 HVNormal3D unitNormal;
275 notLastFace = fPolyhedron->GetNextUnitNormal(unitNormal);
276 bool notLastEdge;
277 do {
278 HVPoint3D vertex;
279 int edgeFlag = 1;
280 notLastEdge = fPolyhedron->GetNextVertex(vertex,edgeFlag);
281 point.setValue(vertex[0],vertex[1],vertex[2]);
282 if(first==TRUE) {
283 xct = xmx = xmn = point[0];
284 yct = ymx = ymn = point[1];
285 zct = zmx = zmn = point[2];
286 count++;
287 first = FALSE;
288 } else {
289 xmn = SbMinimum(xmn,point[0]);
290 ymn = SbMinimum(ymn,point[1]);
291 zmn = SbMinimum(zmn,point[2]);
292 //
293 xmx = SbMaximum(xmx,point[0]);
294 ymx = SbMaximum(ymx,point[1]);
295 zmx = SbMaximum(zmx,point[2]);
296 //
297 xct += point[0];
298 yct += point[1];
299 zct += point[2];
300 count++;
301 }
302 //
303 } while (notLastEdge);
304 } while (notLastFace);
305 SbVec3f vmin(xmn,ymn,zmn);
306 SbVec3f vmax(xmx,ymx,zmx);
307 aBox.setBounds(vmin,vmax);
308 if(count==0)
309 aCenter.setValue(0,0,0);
310 else
311 aCenter.setValue(xct/count,yct/count,zct/count);
312 }
313}
314
315#include <Inventor/nodes/SoNormalBinding.h>
316#include <Inventor/nodes/SoNormal.h>
317#include <Inventor/nodes/SoCoordinate3.h>
318#include <Inventor/nodes/SoIndexedFaceSet.h>
319#include <Inventor/nodes/SoIndexedLineSet.h>
320//////////////////////////////////////////////////////////////////////////////
322)
323//////////////////////////////////////////////////////////////////////////////
324//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
325{
326 if(!fPolyhedron) return;
327 if(fPolyhedron->GetNoFacets()<=0) return; // Abnormal polyhedron.
328 if(fPolyhedron->GetNoVertices()<=0) return; // Abnormal polyhedron.
329
330 if(solid.getValue()==TRUE) {
331
332 SoSeparator* separator = new SoSeparator;
333
334 SoNormalBinding* normalBinding = new SoNormalBinding;
335 normalBinding->value = SoNormalBinding::PER_FACE;
336 separator->addChild(normalBinding);
337
338 SoCoordinate3* coordinate3 = new SoCoordinate3;
339 separator->addChild(coordinate3);
340 SoNormal* normal = new SoNormal;
341 separator->addChild(normal);
342 SoIndexedFaceSet* indexedFaceSet = new SoIndexedFaceSet;
343 separator->addChild(indexedFaceSet);
344
345 int nvert = fPolyhedron->GetNoVertices();
346 int nface = fPolyhedron->GetNoFacets();
347
348 SbVec3f* normals = new SbVec3f[nface];
349 //FIXME : have the exact booking.
350 SbVec3f* points = new SbVec3f[nvert];
351 int32_t* coords = new int32_t[nvert+1];
352
353 int inormal = 0;
354 int icoord = 0;
355 int iindex = 0;
356
357 // Assume all facets are convex quadrilaterals :
358 bool notLastFace;
359 do {
360 HVNormal3D unitNormal;
361 notLastFace = fPolyhedron->GetNextUnitNormal(unitNormal);
362
363 // begin face POLYGON
364 int ipoint = 0;
365
366 bool notLastEdge;
367 int edgeFlag = 1;
368 do {
369 HVPoint3D vertex;
370 notLastEdge = fPolyhedron->GetNextVertex(vertex,edgeFlag);
371 points[ipoint].setValue(vertex[0],vertex[1],vertex[2]);
372 coords[ipoint] = icoord + ipoint;
373 ipoint++;
374 } while (notLastEdge);
375
376 // end face.
377 coords[ipoint] = SO_END_FACE_INDEX;
378 coordinate3->point.setValues(icoord,ipoint,points);
379 icoord += ipoint;
380
381 normals[inormal].setValue(unitNormal[0],unitNormal[1],unitNormal[2]);
382 inormal++;
383
384 indexedFaceSet->coordIndex.setValues(iindex,(ipoint+1),coords);
385 iindex += ipoint+1;
386
387 } while (notLastFace);
388
389 normal->vector.setValues(0,inormal,normals);
390
391 delete [] normals;
392 delete [] coords;
393 delete [] points;
394
395 alternateRep.setValue(separator);
396
397 } else {
398
399 SoSeparator* separator = new SoSeparator;
400
401 int nvert = fPolyhedron->GetNoVertices();
402
403 //FIXME : have the exact booking.
404 int nedge = nvert * 3;
405 int npoint = nedge*2;
406 SbVec3f* points = new SbVec3f[npoint];
407 int ncoord = nedge*3;
408 int32_t* coords = new int32_t[ncoord];
409
410 SbVec3f pvb(0.,0.,0.), pve(0.,0.,0.);
411
412 SbBool empty = TRUE;
413 int ipoint = 0;
414 int icoord = 0;
415
416 bool notLastFace;
417 do {
418 HVNormal3D unitNormal;
419 notLastFace = fPolyhedron->GetNextUnitNormal(unitNormal);
420
421 //SbVec3f normal;
422 //if( (fProjection==SbProjectionRZ) || (fProjection==SbProjectionZR) ) {
423 //normal.setValue(0,0,1);
424 //} else {
425 //normal.setValue(unitNormal[0],unitNormal[1],unitNormal[2]);
426 //}
427
428 // Treat edges :
429 int edgeFlag = 1;
430 int prevEdgeFlag = edgeFlag;
431 bool notLastEdge;
432 SbBool firstEdge = TRUE;
433 do {
434 HVPoint3D vertex;
435 notLastEdge = fPolyhedron->GetNextVertex(vertex,edgeFlag);
436 if(reducedWireFrame.getValue()==FALSE) edgeFlag = 1;
437 if(firstEdge) {
438 if(edgeFlag > 0) {
439 pvb.setValue(vertex[0],vertex[1],vertex[2]);
440 } else {
441 }
442 firstEdge = FALSE;
443 prevEdgeFlag = edgeFlag;
444 } else {
445 if(edgeFlag!=prevEdgeFlag) {
446 if(edgeFlag > 0) { // Pass to a visible edge :
447 pvb.setValue(vertex[0],vertex[1],vertex[2]);
448 } else { // Pass to an invisible edge :
449 pve.setValue(vertex[0],vertex[1],vertex[2]);
450
451 if((ipoint+1)>=npoint) {
452 int new_npoint = 2 * npoint;
453 SbVec3f* new_points = new SbVec3f[new_npoint];
454 for(int i=0;i<npoint;i++) new_points[i] = points[i];
455 delete [] points;
456 npoint = new_npoint;
457 points = new_points;
458 }
459
460 if((icoord+2)>=ncoord) {
461 int new_ncoord = 2 * ncoord;
462 int32_t* new_coords = new int32_t[new_ncoord];
463 for(int i=0;i<ncoord;i++) new_coords[i] = coords[i];
464 delete [] coords;
465 ncoord = new_ncoord;
466 coords = new_coords;
467 }
468
469 points[ipoint+0] = pvb;
470 points[ipoint+1] = pve;
471 coords[icoord+0] = ipoint + 0;
472 coords[icoord+1] = ipoint + 1;
473 coords[icoord+2] = SO_END_LINE_INDEX;
474 ipoint += 2;
475 icoord += 3;
476 empty = FALSE;
477 }
478 prevEdgeFlag = edgeFlag;
479 } else {
480 if(edgeFlag > 0) {
481 pve.setValue(vertex[0],vertex[1],vertex[2]);
482
483 if((ipoint+1)>=npoint) {
484 int new_npoint = 2 * npoint;
485 SbVec3f* new_points = new SbVec3f[new_npoint];
486 for(int i=0;i<npoint;i++) new_points[i] = points[i];
487 delete [] points;
488 npoint = new_npoint;
489 points = new_points;
490 }
491
492 if((icoord+2)>=ncoord) {
493 int new_ncoord = 2 * ncoord;
494 int32_t* new_coords = new int32_t[new_ncoord];
495 for(int i=0;i<ncoord;i++) new_coords[i] = coords[i];
496 delete [] coords;
497 ncoord = new_ncoord;
498 coords = new_coords;
499 }
500
501 points[ipoint+0] = pvb;
502 points[ipoint+1] = pve;
503 coords[icoord+0] = ipoint + 0;
504 coords[icoord+1] = ipoint + 1;
505 coords[icoord+2] = SO_END_LINE_INDEX;
506 ipoint += 2;
507 icoord += 3;
508 empty = FALSE;
509
510 pvb = pve;
511 } else {
512 }
513 }
514 }
515 } while (notLastEdge);
516 } while (notLastFace);
517
518 SoCoordinate3* coordinate3 = new SoCoordinate3;
519 coordinate3->point.setValues(0,ipoint,points);
520 separator->addChild(coordinate3);
521
522 SoIndexedLineSet* indexedLineSet = new SoIndexedLineSet;
523 indexedLineSet->coordIndex.setValues(0,icoord,coords);
524 separator->addChild(indexedLineSet);
525
526 delete [] coords;
527 delete [] points;
528
529 if(empty==TRUE) {
530 separator->unref();
531 } else {
532 alternateRep.setValue(separator);
533 }
534 }
535}
536//////////////////////////////////////////////////////////////////////////////
538)
539//////////////////////////////////////////////////////////////////////////////
540//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
541{
542 alternateRep.setValue(NULL);
543}
544//////////////////////////////////////////////////////////////////////////////
546 SoAction* aAction
547)
548//////////////////////////////////////////////////////////////////////////////
549//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
550{
552 SoShape::doAction(aAction);
553}
554
555#endif
#define SbMaximum(a, b)
Definition: SbMath.h:39
#define SbMinimum(a, b)
Definition: SbMath.h:38
#define SO_ALTERNATEREP_DO_ACTION(aAction)
virtual void generateAlternateRep()
static void initClass()
virtual void computeBBox(SoAction *, SbBox3f &, SbVec3f &)
virtual ~Geant4_SoPolyhedron()
virtual void generatePrimitives(SoAction *)
virtual void doAction(SoAction *)
virtual void clearAlternateRep()
G4bool GetNextVertex(G4Point3D &vertex, G4int &edgeFlag) const
G4int GetNoFacets() const
G4bool GetNextUnitNormal(G4Normal3D &normal) const
G4int GetNoVertices() const
#define TRUE
Definition: globals.hh:55
#define FALSE
Definition: globals.hh:52