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

Last change on this file since 1202 was 609, checked in by garnier, 17 years ago

r659@mac-90108: laurentgarnier | 2007-11-16 12:02:01 +0100
mise a jour de Geant4 au head ET qq mise a jour pour Qt de mon cote

  • Property svn:mime-type set to text/cpp
File size: 18.5 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    SbBool empty = TRUE;
346
347    int nvert = fPolyhedron->GetNoVertices();
348    int nface = fPolyhedron->GetNoFacets();
349
350    SbVec3f* normals = new SbVec3f[nface];
351    //FIXME : have the exact booking.
352    SbVec3f* points = new SbVec3f[nvert];
353    int32_t* coords = new int32_t[nvert+1];
354
355    int inormal = 0;
356    int icoord = 0;
357    int iindex = 0;
358
359    // Assume all facets are convex quadrilaterals :
360    bool notLastFace;
361    do {
362      HVNormal3D unitNormal;
363      notLastFace = fPolyhedron->GetNextUnitNormal(unitNormal);
364
365      // begin face POLYGON
366      int ipoint = 0;
367
368      bool notLastEdge;
369      int edgeFlag = 1;
370      do {
371        HVPoint3D vertex;
372        notLastEdge = fPolyhedron->GetNextVertex(vertex,edgeFlag);
373        points[ipoint].setValue(vertex[0],vertex[1],vertex[2]);
374        coords[ipoint] = icoord + ipoint;
375        ipoint++;
376        empty = FALSE;
377
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    if(empty==TRUE) {
400      separator->unref();
401    } else {
402      alternateRep.setValue(separator);
403    }
404
405  } else {
406
407    SoSeparator* separator = new SoSeparator;
408
409    int nvert = fPolyhedron->GetNoVertices();
410
411    //FIXME : have the exact booking.
412    int nedge = nvert * 3;
413    int npoint = nedge*2;
414    SbVec3f* points = new SbVec3f[npoint];
415    int ncoord = nedge*3;
416    int32_t* coords = new int32_t[ncoord];
417
418    SbVec3f pvb(0.,0.,0.), pve(0.,0.,0.);
419
420    SbBool empty = TRUE;
421    int ipoint = 0;
422    int icoord = 0;
423
424    bool notLastFace;
425    do {
426      HVNormal3D unitNormal;
427      notLastFace = fPolyhedron->GetNextUnitNormal(unitNormal);
428
429      //SbVec3f normal;
430      //if( (fProjection==SbProjectionRZ) || (fProjection==SbProjectionZR) ) {
431        //normal.setValue(0,0,1);
432      //} else {
433        //normal.setValue(unitNormal[0],unitNormal[1],unitNormal[2]);
434      //}
435
436      // Treat edges :
437      int edgeFlag = 1;
438      int prevEdgeFlag = edgeFlag;
439      bool notLastEdge;
440      SbBool firstEdge = TRUE;
441      do {
442        HVPoint3D vertex;
443        notLastEdge = fPolyhedron->GetNextVertex(vertex,edgeFlag);
444        if(reducedWireFrame.getValue()==FALSE) edgeFlag = 1;       
445        if(firstEdge) {
446          if(edgeFlag > 0) {
447            pvb.setValue(vertex[0],vertex[1],vertex[2]);
448          } else {
449          }
450          firstEdge = FALSE;
451          prevEdgeFlag = edgeFlag;
452        } else {
453          if(edgeFlag!=prevEdgeFlag) {
454            if(edgeFlag > 0) { // Pass to a visible edge :
455              pvb.setValue(vertex[0],vertex[1],vertex[2]);
456            } else { // Pass to an invisible edge :
457              pve.setValue(vertex[0],vertex[1],vertex[2]);
458
459              if((ipoint+1)>=npoint) {
460                int new_npoint = 2 * npoint;
461                SbVec3f* new_points = new SbVec3f[new_npoint];
462                for(int i=0;i<npoint;i++) new_points[i] = points[i];
463                delete [] points;
464                npoint = new_npoint;
465                points = new_points;
466              }
467
468              if((icoord+2)>=ncoord) {
469                int new_ncoord = 2 * ncoord;
470                int32_t* new_coords = new int32_t[new_ncoord];
471                for(int i=0;i<ncoord;i++) new_coords[i] = coords[i];
472                delete [] coords;
473                ncoord = new_ncoord;
474                coords = new_coords;
475              }
476
477              points[ipoint+0] = pvb;
478              points[ipoint+1] = pve;
479              coords[icoord+0] = ipoint + 0;
480              coords[icoord+1] = ipoint + 1;
481              coords[icoord+2] = SO_END_LINE_INDEX;
482              ipoint += 2;
483              icoord += 3;
484              empty = FALSE;
485            }
486            prevEdgeFlag = edgeFlag;
487          } else {
488            if(edgeFlag > 0) {
489              pve.setValue(vertex[0],vertex[1],vertex[2]);
490
491              if((ipoint+1)>=npoint) {
492                int new_npoint = 2 * npoint;
493                SbVec3f* new_points = new SbVec3f[new_npoint];
494                for(int i=0;i<npoint;i++) new_points[i] = points[i];
495                delete [] points;
496                npoint = new_npoint;
497                points = new_points;
498              }
499
500              if((icoord+2)>=ncoord) {
501                int new_ncoord = 2 * ncoord;
502                int32_t* new_coords = new int32_t[new_ncoord];
503                for(int i=0;i<ncoord;i++) new_coords[i] = coords[i];
504                delete [] coords;
505                ncoord = new_ncoord;
506                coords = new_coords;
507              }
508
509              points[ipoint+0] = pvb;
510              points[ipoint+1] = pve;
511              coords[icoord+0] = ipoint + 0;
512              coords[icoord+1] = ipoint + 1;
513              coords[icoord+2] = SO_END_LINE_INDEX;
514              ipoint += 2;
515              icoord += 3;
516              empty = FALSE;
517
518              pvb = pve;
519            } else {
520            }
521          }
522        }
523      } while (notLastEdge);
524    } while (notLastFace);
525
526    SoCoordinate3* coordinate3 = new SoCoordinate3;
527    coordinate3->point.setValues(0,ipoint,points);
528    separator->addChild(coordinate3);
529
530    SoIndexedLineSet* indexedLineSet = new SoIndexedLineSet;
531    indexedLineSet->coordIndex.setValues(0,icoord,coords);
532    separator->addChild(indexedLineSet);
533
534    delete [] coords;
535    delete [] points;
536
537    if(empty==TRUE) {
538      separator->unref();
539    } else {
540      alternateRep.setValue(separator);
541    }
542  }
543}
544//////////////////////////////////////////////////////////////////////////////
545void Geant4_SoPolyhedron::clearAlternateRep(
546)
547//////////////////////////////////////////////////////////////////////////////
548//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
549{
550  alternateRep.setValue(NULL);
551}
552//////////////////////////////////////////////////////////////////////////////
553void Geant4_SoPolyhedron::doAction(
554 SoAction* aAction
555)
556//////////////////////////////////////////////////////////////////////////////
557//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
558{
559  SO_ALTERNATEREP_DO_ACTION(aAction)
560  SoShape::doAction(aAction);
561}
562
563#endif
Note: See TracBrowser for help on using the repository browser.