Geant4.10
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
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 )
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
virtual void generatePrimitives(SoAction *)
G4bool GetNextUnitNormal(G4Normal3D &normal) const
typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData
#define SO_ALTERNATEREP_DO_ACTION(aAction)
virtual ~Geant4_SoPolyhedron()
#define SbMinimum(a, b)
Definition: SbMath.h:38
#define FALSE
Definition: globals.hh:52
#define SbMaximum(a, b)
Definition: SbMath.h:39
#define TRUE
Definition: globals.hh:55
virtual void computeBBox(SoAction *, SbBox3f &, SbVec3f &)
G4int GetNoVertices() const
virtual void generateAlternateRep()
G4bool GetNextVertex(G4Point3D &vertex, G4int &edgeFlag) const
G4int GetNoFacets() const
virtual void clearAlternateRep()
virtual void doAction(SoAction *)