26 #ifdef G4VIS_BUILD_OI_DRIVER
37 #include "Geant4_SoPolyhedron.h"
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>
46 #define SbMinimum(a,b) ((a)<(b)?a:b)
47 #define SbMaximum(a,b) ((a)>(b)?a:b)
49 #include <HEPVis/actions/SoAlternateRepAction.h>
56 typedef HepGeom::Point3D<double> HVPoint3D;
57 typedef HepGeom::Normal3D<double> HVNormal3D;
59 SO_NODE_SOURCE(Geant4_SoPolyhedron)
60 void Geant4_SoPolyhedron::initClass(
66 SO_NODE_INIT_CLASS(Geant4_SoPolyhedron,SoShape,
"Shape");
69 Geant4_SoPolyhedron::Geant4_SoPolyhedron(
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));
81 Geant4_SoPolyhedron::Geant4_SoPolyhedron(
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));
96 Geant4_SoPolyhedron::Geant4_SoPolyhedron(
99 :fPolyhedron(aPolyhedron)
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));
109 Geant4_SoPolyhedron::~Geant4_SoPolyhedron(
117 void Geant4_SoPolyhedron::generatePrimitives(
123 if(!fPolyhedron)
return;
124 if(fPolyhedron->GetNoFacets()<=0)
return;
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);
139 if(solid.getValue()==
TRUE) {
140 SoPrimitiveVertex pv;
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); \
153 pv.setPoint(point); \
154 pv.setNormal(normal); \
155 pv.setTextureCoords(texCoord); \
163 HVNormal3D unitNormal;
164 notLastFace = fPolyhedron->GetNextUnitNormal(unitNormal);
166 beginShape(aAction,POLYGON);
171 notLastEdge = fPolyhedron->GetNextVertex(vertex,edgeFlag);
180 }
while (notLastEdge);
182 }
while (notLastFace);
184 SoPrimitiveVertex pvb,pve;
185 pve.setTextureCoords(texCoord);
186 pvb.setTextureCoords(texCoord);
188 #ifdef __COIN__ // To bypass a bug in invokeLineSegment when picking.
189 beginShape(aAction,POLYGON);
196 HVNormal3D unitNormal;
197 notLastFace = fPolyhedron->GetNextUnitNormal(unitNormal);
200 normal.setValue(unitNormal[0],unitNormal[1],unitNormal[2]);
204 int prevEdgeFlag = edgeFlag;
206 SbBool firstEdge =
TRUE;
209 notLastEdge = fPolyhedron->GetNextVertex(vertex,edgeFlag);
210 if(reducedWireFrame.getValue()==
FALSE) edgeFlag = 1;
213 pvb.setNormal(normal);
214 point.setValue(vertex[0],vertex[1],vertex[2]);
219 prevEdgeFlag = edgeFlag;
221 if(edgeFlag!=prevEdgeFlag) {
223 pvb.setNormal(normal);
224 point.setValue(vertex[0],vertex[1],vertex[2]);
227 pve.setNormal(normal);
228 point.setValue(vertex[0],vertex[1],vertex[2]);
230 invokeLineSegmentCallbacks(aAction,&pvb,&pve);
232 prevEdgeFlag = edgeFlag;
235 pve.setNormal(normal);
236 point.setValue(vertex[0],vertex[1],vertex[2]);
238 invokeLineSegmentCallbacks(aAction,&pvb,&pve);
244 }
while (notLastEdge);
245 }
while (notLastFace);
250 void Geant4_SoPolyhedron::computeBBox(
258 if(!fPolyhedron)
return;
259 if(fPolyhedron->GetNoFacets()<=0) {
260 SbVec3f vmin(-1,-1,-1);
261 SbVec3f vmax( 1, 1, 1);
262 aBox.setBounds(vmin,vmax);
263 aCenter.setValue(0,0,0);
266 float xmn = 0,ymn = 0,zmn = 0;
267 float xmx = 0,ymx = 0,zmx = 0;
268 float xct = 0,yct = 0,zct = 0;
274 HVNormal3D unitNormal;
275 notLastFace = fPolyhedron->GetNextUnitNormal(unitNormal);
280 notLastEdge = fPolyhedron->GetNextVertex(vertex,edgeFlag);
281 point.setValue(vertex[0],vertex[1],vertex[2]);
283 xct = xmx = xmn = point[0];
284 yct = ymx = ymn = point[1];
285 zct = zmx = zmn = point[2];
289 xmn = SbMinimum(xmn,point[0]);
290 ymn = SbMinimum(ymn,point[1]);
291 zmn = SbMinimum(zmn,point[2]);
293 xmx = SbMaximum(xmx,point[0]);
294 ymx = SbMaximum(ymx,point[1]);
295 zmx = SbMaximum(zmx,point[2]);
303 }
while (notLastEdge);
304 }
while (notLastFace);
305 SbVec3f vmin(xmn,ymn,zmn);
306 SbVec3f vmax(xmx,ymx,zmx);
307 aBox.setBounds(vmin,vmax);
309 aCenter.setValue(0,0,0);
311 aCenter.setValue(xct/count,yct/count,zct/count);
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>
321 void Geant4_SoPolyhedron::generateAlternateRep(
326 if(!fPolyhedron)
return;
327 if(fPolyhedron->GetNoFacets()<=0)
return;
328 if(fPolyhedron->GetNoVertices()<=0)
return;
330 if(solid.getValue()==
TRUE) {
332 SoSeparator* separator =
new SoSeparator;
334 SoNormalBinding* normalBinding =
new SoNormalBinding;
335 normalBinding->value = SoNormalBinding::PER_FACE;
336 separator->addChild(normalBinding);
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);
345 int nvert = fPolyhedron->GetNoVertices();
346 int nface = fPolyhedron->GetNoFacets();
348 SbVec3f* normals =
new SbVec3f[nface];
350 SbVec3f* points =
new SbVec3f[nvert];
351 int32_t* coords =
new int32_t[nvert+1];
360 HVNormal3D unitNormal;
361 notLastFace = fPolyhedron->GetNextUnitNormal(unitNormal);
370 notLastEdge = fPolyhedron->GetNextVertex(vertex,edgeFlag);
371 points[ipoint].setValue(vertex[0],vertex[1],vertex[2]);
372 coords[ipoint] = icoord + ipoint;
374 }
while (notLastEdge);
377 coords[ipoint] = SO_END_FACE_INDEX;
378 coordinate3->point.setValues(icoord,ipoint,points);
381 normals[inormal].setValue(unitNormal[0],unitNormal[1],unitNormal[2]);
384 indexedFaceSet->coordIndex.setValues(iindex,(ipoint+1),coords);
387 }
while (notLastFace);
389 normal->vector.setValues(0,inormal,normals);
395 alternateRep.setValue(separator);
399 SoSeparator* separator =
new SoSeparator;
401 int nvert = fPolyhedron->GetNoVertices();
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];
410 SbVec3f pvb(0.,0.,0.), pve(0.,0.,0.);
418 HVNormal3D unitNormal;
419 notLastFace = fPolyhedron->GetNextUnitNormal(unitNormal);
430 int prevEdgeFlag = edgeFlag;
432 SbBool firstEdge =
TRUE;
435 notLastEdge = fPolyhedron->GetNextVertex(vertex,edgeFlag);
436 if(reducedWireFrame.getValue()==
FALSE) edgeFlag = 1;
439 pvb.setValue(vertex[0],vertex[1],vertex[2]);
443 prevEdgeFlag = edgeFlag;
445 if(edgeFlag!=prevEdgeFlag) {
447 pvb.setValue(vertex[0],vertex[1],vertex[2]);
449 pve.setValue(vertex[0],vertex[1],vertex[2]);
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];
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];
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;
478 prevEdgeFlag = edgeFlag;
481 pve.setValue(vertex[0],vertex[1],vertex[2]);
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];
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];
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;
515 }
while (notLastEdge);
516 }
while (notLastFace);
518 SoCoordinate3* coordinate3 =
new SoCoordinate3;
519 coordinate3->point.setValues(0,ipoint,points);
520 separator->addChild(coordinate3);
522 SoIndexedLineSet* indexedLineSet =
new SoIndexedLineSet;
523 indexedLineSet->coordIndex.setValues(0,icoord,coords);
524 separator->addChild(indexedLineSet);
532 alternateRep.setValue(separator);
537 void Geant4_SoPolyhedron::clearAlternateRep(
542 alternateRep.setValue(NULL);
545 void Geant4_SoPolyhedron::doAction(
551 SO_ALTERNATEREP_DO_ACTION(aAction)
552 SoShape::doAction(aAction);
static double normal(HepRandomEngine *eptr)