Geant4 9.6.0
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#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