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