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