ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SoPolyhedron.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SoPolyhedron.cc
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 
56 typedef HepGeom::Point3D<double> HVPoint3D;
57 typedef HepGeom::Normal3D<double> HVNormal3D;
58 
59 SO_NODE_SOURCE(Geant4_SoPolyhedron)
60 
61 void Geant4_SoPolyhedron::initClass(
62 )
65 {
66  SO_NODE_INIT_CLASS(Geant4_SoPolyhedron,SoShape,"Shape");
67 }
70 )
71 :fPolyhedron(0)
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 }
82  const G4Polyhedron& aPolyhedron
83 )
84 :fPolyhedron(0)
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 }
97  G4Polyhedron* aPolyhedron
98 )
99 :fPolyhedron(aPolyhedron)
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 }
110 )
113 {
114  delete fPolyhedron;
115 }
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;
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  //----------------------------------------
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 }
251  SoAction*
252 ,SbBox3f& aBox
253 ,SbVec3f& aCenter
254 )
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>
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 }
538 )
539 
540 
541 {
542  alternateRep.setValue(NULL);
543 }
546  SoAction* aAction
547 )
550 {
552  SoShape::doAction(aAction);
553 }
554 
555 #endif