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

Last change on this file since 1152 was 609, checked in by garnier, 18 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.