source: trunk/source/visualization/OpenInventor/src/SoPolyhedron.cc @ 1348

Last change on this file since 1348 was 1348, checked in by garnier, 13 years ago

update

  • Property svn:mime-type set to text/cpp
File size: 18.4 KB
Line 
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
49#include <HEPVis/actions/SoAlternateRepAction.h>
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//////////////////////////////////////////////////////////////////////////////
61void Geant4_SoPolyhedron::initClass(
62)
63//////////////////////////////////////////////////////////////////////////////
64//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
65{
66  SO_NODE_INIT_CLASS(Geant4_SoPolyhedron,SoShape,"Shape");
67}
68//////////////////////////////////////////////////////////////////////////////
69Geant4_SoPolyhedron::Geant4_SoPolyhedron(
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//////////////////////////////////////////////////////////////////////////////
81Geant4_SoPolyhedron::Geant4_SoPolyhedron(
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//////////////////////////////////////////////////////////////////////////////
96Geant4_SoPolyhedron::Geant4_SoPolyhedron(
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//////////////////////////////////////////////////////////////////////////////
109Geant4_SoPolyhedron::~Geant4_SoPolyhedron(
110)
111//////////////////////////////////////////////////////////////////////////////
112//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
113{
114  delete fPolyhedron;
115}
116//////////////////////////////////////////////////////////////////////////////
117void Geant4_SoPolyhedron::generatePrimitives(
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//////////////////////////////////////////////////////////////////////////////
250void Geant4_SoPolyhedron::computeBBox(
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//////////////////////////////////////////////////////////////////////////////
321void Geant4_SoPolyhedron::generateAlternateRep(
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//////////////////////////////////////////////////////////////////////////////
537void Geant4_SoPolyhedron::clearAlternateRep(
538)
539//////////////////////////////////////////////////////////////////////////////
540//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
541{
542  alternateRep.setValue(NULL);
543}
544//////////////////////////////////////////////////////////////////////////////
545void Geant4_SoPolyhedron::doAction(
546 SoAction* aAction
547)
548//////////////////////////////////////////////////////////////////////////////
549//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
550{
551  SO_ALTERNATEREP_DO_ACTION(aAction)
552  SoShape::doAction(aAction);
553}
554
555#endif
Note: See TracBrowser for help on using the repository browser.