ATLAS Offline Software
Loading...
Searching...
No Matches
SoPolyhedron.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6// //
7// Header file for class SoPolyhedron //
8// //
9// Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch) //
10// //
11// Initial version: November 2008 //
12// //
13// Update: Giorgi Gvaberidze (ggvaberi@cern.ch) //
14// November 2010 //
15// //
16// Riccardo-Maria BIANCHI (rbianchi@cern.ch) //
17// 13.12.2012 //
18// //
20
22
23#include <Inventor/SbBox.h>
24#include <Inventor/actions/SoAction.h>
25#include <Inventor/actions/SoPickAction.h>
26#include <Inventor/SoPrimitiveVertex.h>
27#include <Inventor/elements/SoTextureCoordinateElement.h>
28#include <Inventor/elements/SoGLCacheContextElement.h>
29
30#include <Inventor/nodes/SoSeparator.h>
31#include <Inventor/nodes/SoIndexedFaceSet.h>
32#include <Inventor/nodes/SoVertexProperty.h>
33
34#include <Inventor/C/glue/gl.h>
35
36#include "SbMath.h"
38
40//#include "VP1Base/VP1Msg.h"
41//#include <QString>
42
43
44SO_NODE_SOURCE(SoPolyhedron)
45
46//____________________________________________________________________
48{
49 [[maybe_unused]] static const bool didInit = [&]() {
50 SO_NODE_INIT_CLASS(SoPolyhedron,SoShape,"Shape");
51 return true;
52 }();
53}
54
57)
60{
61 SO_NODE_CONSTRUCTOR(SoPolyhedron);
62 // SO_NODE_ADD_FIELD(solid,(TRUE));
63 // SO_NODE_ADD_FIELD(reducedWireFrame,(TRUE));
64 SO_NODE_ADD_FIELD(alternateRep,(NULL));
65 setNodeType(EXTENSION);
66}
67
69 const SbPolyhedron& aPolyhedron
70)
73{
74 SO_NODE_CONSTRUCTOR(SoPolyhedron);
75 // SO_NODE_ADD_FIELD(solid,(TRUE));
76 // SO_NODE_ADD_FIELD(reducedWireFrame,(TRUE));
77 SO_NODE_ADD_FIELD(alternateRep,(NULL));
78
79 m_polyhedron = std::make_unique<SbPolyhedron>(aPolyhedron);
80 setNodeType(EXTENSION);
82}
83
85 const SbPolyhedron* aPolyhedron
86)
89{
90 SO_NODE_CONSTRUCTOR(SoPolyhedron);
91 // SO_NODE_ADD_FIELD(solid,(TRUE));
92 // SO_NODE_ADD_FIELD(reducedWireFrame,(TRUE));
93 SO_NODE_ADD_FIELD(alternateRep,(NULL));
94
95 m_polyhedron = std::make_unique<SbPolyhedron>(*aPolyhedron);
96 setNodeType(EXTENSION);
98}
99
101)
104{
105 if(m_vertices)
106 delete [] m_vertices;
107 if(m_indices)
108 delete [] m_indices;
109}
110
112 SoAction* aAction
113)
116{
117 if(!m_polyhedron) return;
118 if(m_polyhedron->GetNoFacets()<=0) return; // Abnormal polyhedron.
119
120 SoState *state = aAction->getState();
121 if (!state)
122 return;
123 SbBool useTexFunction =
124 (SoTextureCoordinateElement::getType(state) ==
125 SoTextureCoordinateElement::FUNCTION);
126 const SoTextureCoordinateElement *tce = NULL;
127 SbVec4f texCoord;
128 if (useTexFunction) {
129 tce = SoTextureCoordinateElement::getInstance(state);
130 } else {
131 texCoord[2] = 0.0;
132 texCoord[3] = 1.0;
133 }
134
135 // if(solid.getValue()==TRUE) {
136 if(true) {
137 SoPrimitiveVertex pv;
138 SbVec3f point, normal;
140 //----------------------------------------
141#define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \
142 point.setValue(x,y,z); \
143 normal.setValue(nx,ny,nz); \
144 if (useTexFunction) { \
145 texCoord=tce->get(point,normal); \
146 } else { \
147 texCoord[0]=s; \
148 texCoord[1]=t; \
149 } \
150 pv.setPoint(point); \
151 pv.setNormal(normal); \
152 pv.setTextureCoords(texCoord); \
153 shapeVertex(&pv);
154 //----------------------------------------
157 // For pick action use old method, for for see selected lines
159 if ( aAction->getTypeId().isDerivedFrom(SoPickAction::getClassTypeId()) ){ //comment this line to return on old method
160 // Assume all facets are convex quadrilaterals :
161 bool notLastFace;
162 do {
163 HVNormal3D unitNormal;
164 notLastFace = m_polyhedron->GetNextUnitNormal(unitNormal);
165
166 beginShape(aAction,POLYGON);
167 bool notLastEdge;
168 int edgeFlag = 1;
169 do {
170 HVPoint3D vertex;
171 notLastEdge = m_polyhedron->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 }
184 else
185 {
186 if(m_vertices){
187 glEnableClientState(GL_VERTEX_ARRAY);
188 glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &m_vertices[0].pos);
189 glEnableClientState(GL_NORMAL_ARRAY);
190 glNormalPointer(GL_FLOAT, sizeof(Vertex), &m_vertices[0].nor);
192 //For I-Method. Comment it if u use II-Method
194 //glDrawElements(GL_TRIANGLES, m_icount, GL_UNSIGNED_INT, m_indices); //comment it if u use II-Method
196 //For II-Method. Comment it if u use I-Method
198 glDrawArrays(GL_TRIANGLES, 0, m_vcount); //comment it if u use I-Method
199 glDisableClientState(GL_VERTEX_ARRAY);
200 glDisableClientState(GL_NORMAL_ARRAY);
201 }
202 } //End of comment for return to old method */
203 } else {//lala
204// SoPrimitiveVertex pvb,pve;
205// pve.setTextureCoords(texCoord);
206// pvb.setTextureCoords(texCoord);
207
208// #ifdef __COIN__ // To bypass a bug in invokeLineSegment when picking.
209// beginShape(aAction,POLYGON);
210// endShape();
211// #endif
212
213// SbVec3f point;
214// bool notLastFace;
215// do {
216// HVNormal3D unitNormal;
217// notLastFace = m_polyhedron->GetNextUnitNormal(unitNormal);
218
219// SbVec3f normal;
220// if( false ) {
221// normal.setValue(0,0,1);
222// } else {
223// normal.setValue(unitNormal[0],unitNormal[1],unitNormal[2]);
224// }
225
226// // Treat edges :
227// int edgeFlag = 1;
228// int prevEdgeFlag = edgeFlag;
229// bool notLastEdge;
230// SbBool firstEdge = TRUE;
231// do {
232// HVPoint3D vertex;
233// notLastEdge = m_polyhedron->GetNextVertex(vertex,edgeFlag);
234// if(reducedWireFrame.getValue()==FALSE) edgeFlag = 1;
235// if(firstEdge) {
236// if(edgeFlag) {
237// pvb.setNormal(normal);
238// point.setValue(vertex[0],vertex[1],vertex[2]);
239// //DONOTHING projector.project(1,&point);
240// pvb.setPoint(point);
241// } else {
242// }
243// firstEdge = FALSE;
244// prevEdgeFlag = edgeFlag;
245// } else {
246// if(edgeFlag!=prevEdgeFlag) {
247// if(edgeFlag) { // Pass to a visible edge :
248// pvb.setNormal(normal);
249// point.setValue(vertex[0],vertex[1],vertex[2]);
250// //DONOTHING projector.project(1,&point);
251// pvb.setPoint(point);
252// } else { // Pass to an invisible edge :
253// pve.setNormal(normal);
254// point.setValue(vertex[0],vertex[1],vertex[2]);
255// //DONOTHING projector.project(1,&point);
256// pve.setPoint(point);
257// invokeLineSegmentCallbacks(aAction,&pvb,&pve);
258// }
259// prevEdgeFlag = edgeFlag;
260// } else {
261// if(edgeFlag) {
262// pve.setNormal(normal);
263// point.setValue(vertex[0],vertex[1],vertex[2]);
264// //DONOTHING projector.project(1,&point);
265// pve.setPoint(point);
266// invokeLineSegmentCallbacks(aAction,&pvb,&pve);
267// pvb = pve;
268// } else {
269// }
270// }
271// }
272// } while (notLastEdge);
273// } while (notLastFace);
274 }
275
276 if (state&&state->isElementEnabled(SoGLCacheContextElement::getClassStackIndex())) {
277 //Encourage auto caching
278 SoGLCacheContextElement::shouldAutoCache(state, SoGLCacheContextElement::DO_AUTO_CACHE);
279#if ((COIN_MAJOR_VERSION>=3)||((COIN_MAJOR_VERSION==2)&&(COIN_MINOR_VERSION>=5)))
280 SoGLCacheContextElement::incNumShapes(state);
281#endif
282 }
283}
284
286 SoAction*
287,SbBox3f& aBox
288,SbVec3f& aCenter
289)
292{
293 if(!m_polyhedron) return;
294 if(m_polyhedron->GetNoFacets()<=0) { // Abnormal polyhedron.
295 SbVec3f vmin(-1,-1,-1);
296 SbVec3f vmax( 1, 1, 1);
297 aBox.setBounds(vmin,vmax);
298 aCenter.setValue(0,0,0);
299 } else {
300 // SbBool wireFrame = (solid.getValue()==TRUE ? FALSE : TRUE);
301 //DONOTHING HEPVis::SbProjector projector(wireFrame?fProjection:SbProjectionNone);
302 SbBool first = TRUE;
303 float xmn = 0,ymn = 0,zmn = 0;
304 float xmx = 0,ymx = 0,zmx = 0;
305 float xct = 0,yct = 0,zct = 0;
306 SbVec3f point;
307 int count = 0;
308 // Assume all facets are convex quadrilaterals :
309 bool notLastFace;
310 do {
311 HVNormal3D unitNormal;
312 notLastFace = m_polyhedron->GetNextUnitNormal(unitNormal);
313 bool notLastEdge;
314 do {
315 HVPoint3D vertex;
316 int edgeFlag = 1;
317 notLastEdge = m_polyhedron->GetNextVertex(vertex,edgeFlag);
318 point.setValue(vertex[0],vertex[1],vertex[2]);
319 //DONOTHING projector.project(1,&point);
320 if(first==TRUE) {
321 xct = xmx = xmn = point[0];
322 yct = ymx = ymn = point[1];
323 zct = zmx = zmn = point[2];
324 count++;
325 first = FALSE;
326 } else {
327 xmn = SbMinimum(xmn,point[0]);
328 ymn = SbMinimum(ymn,point[1]);
329 zmn = SbMinimum(zmn,point[2]);
330 //
331 xmx = SbMaximum(xmx,point[0]);
332 ymx = SbMaximum(ymx,point[1]);
333 zmx = SbMaximum(zmx,point[2]);
334 //
335 xct += point[0];
336 yct += point[1];
337 zct += point[2];
338 count++;
339 }
340 //
341 } while (notLastEdge);
342 } while (notLastFace);
343 SbVec3f vmin(xmn,ymn,zmn);
344 SbVec3f vmax(xmx,ymx,zmx);
345 aBox.setBounds(vmin,vmax);
346
347 if(count==0) {
348 aCenter.setValue(0,0,0);
349 }
350 else {
351 aCenter.setValue(xct/count,yct/count,zct/count);
352 }
353 //DEBUG
354// std::cout << "vmin: " << xmn << " " << ymn << " " << zmn << std::endl;
355// std::cout << "vmax: " << xmx << " " << ymx << " " << zmx << std::endl;
356 }
357
358
359}
360
361//---
362//____________________________________________________________________
363
364/*
365void SoPolyhedron::getPrimitiveCount(SoGetPrimitiveCountAction * action)
366{
367 if(action)
368 action->addNumTriangles(10);
369}
370//*/
371
374{
375 if (alternateRep.getValue())
377 if( m_polyhedron && ( m_polyhedron->GetNoFacets() > 0 ) ){
378 //SoSeparator *sep = new SoSeparator;
379 SoVertexProperty *vertices = new SoVertexProperty();
380
381 //Retreive geometry from polyhedron
382 int vno = m_polyhedron->GetNoVertices();
383 for(int i = 0; i < vno; i++){
384 HVPoint3D vertex;
385 vertex = m_polyhedron->GetVertex(i + 1);
386 vertices->vertex.set1Value (i, vertex[0], vertex[1], vertex[2]);
387 }
388
389 int fno = m_polyhedron->GetNoFacets();
390 int fcr = 0;
391 int* aface = new int[8 * fno];
392 for(int i = 0; i < fno; i++){
393 int n, inodes[4];
394 //SbVec3d nr = m_polyhedron->GetNormal(i + 1); // not used, gives warning, commenting out:
395 //---
396 m_polyhedron->GetFacet(i + 1, n, inodes);
397 aface[fcr] = (inodes[0] <= vno) ? (inodes[0] - 1) : (0); fcr++;
398 aface[fcr] = (inodes[1] <= vno) ? (inodes[1] - 1) : (0); fcr++;
399 aface[fcr] = (inodes[2] <= vno) ? (inodes[2] - 1) : (0); fcr++;
400 if(n == 4) { aface[fcr] = (inodes[3] <= vno) ? (inodes[3] - 1) : (0); fcr++; }
401 aface[fcr] = -1; fcr++;
402 }
403 SoIndexedFaceSet * faceset = new SoIndexedFaceSet;
404 faceset->coordIndex.setValues(0, fcr, aface);
405 delete [] aface;
406 faceset->vertexProperty = vertices;
407 //sep->addChild(faceset);
408 alternateRep.setValue(faceset);
409 }
410}
411//*/
412
413//____________________________________________________________________
416{
417 alternateRep.setValue(NULL);
418 //Hmm... no ref/unref??
419}
420//*/
421
422//____________________________________________________________________
424inline long SoPolyhedron::hasVertex(Vertex* vertices, long len, Vertex& v){
425 for(long i = 0; i < len; i++){
426 if((v.pos[0] == vertices[i].pos[0]) && (v.pos[1] == vertices[i].pos[1]) && (v.pos[2] == vertices[i].pos[2]) &&
427 (v.nor[0] == vertices[i].nor[0]) && (v.nor[1] == vertices[i].nor[1]) && (v.nor[2] == vertices[i].nor[2]))
428 return i;
429 }
430 return -1;
431}
432//*/
433
435// I - Method, cooment it if u use II - Method
437/*
438void SoPolyhedron::makeShape(SbPolyhedron* sp)
439{
440 if(!sp || (m_polyhedron->GetNoFacets() < 1))
441 return;
442
443 if(m_vertices){
444 delete [] m_vertices;
445 m_vertices = 0;
446 m_vcount = 0;
447 }
448
449 if(m_indices){
450 delete [] m_indices;
451 m_indices = 0;
452 m_icount = 0;
453 }
454
455 int fno = m_polyhedron->GetNoFacets();
456 long faces = 0; //this is primitive face(triangle)
457 for(int i = 0; i < fno; i++){
458 int n, inodes[4];
459 m_polyhedron->GetFacet(i + 1, n, inodes);
460 if(n == 3)
461 faces += 1;
462 else if(n == 4)
463 faces += 2;
464 }
465
466 if(faces < 1)
467 return;
468
469 long fcr = 0;
470 m_icount = 3 * faces;
471 m_indices = new long[m_icount];
472
473 Vertex* varr = new Vertex[m_icount];
474 long vidx = 0;
475 for(int i = 0; i < fno; i++){
476 int n, inodes[4];
477 SbVec3f nor = m_polyhedron->GetNormal(i + 1);
478 m_polyhedron->GetFacet(i + 1, n, inodes);
479
480 for(int j = 0; j < n; j++){
481 Vertex v;
482 SbVec3f pos = m_polyhedron->GetVertex(inodes[j]);
483 v.pos[0] = pos[0], v.pos[1] = pos[1], v.pos[2] = pos[2];
484 v.nor[0] = nor[0], v.nor[1] = nor[1], v.nor[2] = nor[2];
485 long iarr = hasVertex(varr, vidx, v);
486 if(iarr < 0){
487 varr[vidx] = v;
488 inodes[j] = vidx;
489 vidx++;
490 }else{
491 inodes[j] = iarr;
492 }
493 }
494
495 if(n >= 3){
496 m_indices[fcr] = (inodes[0] <= m_icount) ? (inodes[0]) : (0); fcr++;
497 m_indices[fcr] = (inodes[1] <= m_icount) ? (inodes[1]) : (0); fcr++;
498 m_indices[fcr] = (inodes[2] <= m_icount) ? (inodes[2]) : (0); fcr++;
499 if(n == 4){
500 m_indices[fcr] = (inodes[0] <= m_icount) ? (inodes[0]) : (0); fcr++;
501 m_indices[fcr] = (inodes[1] <= m_icount) ? (inodes[2]) : (0); fcr++;
502 m_indices[fcr] = (inodes[2] <= m_icount) ? (inodes[3]) : (0); fcr++;
503 }
504 }
505 }
506 m_vcount = vidx;
507 m_vertices = new Vertex[m_vcount];
508 memcpy(m_vertices, varr, m_vcount * sizeof(Vertex));
509 delete [] varr;
510}
511//*/
512
514// II - Method, comment it if u use I - Method
518{
519 if(!sp || (m_polyhedron->GetNoFacets() < 1))
520 return;
521
522 if(m_vertices){
523 delete [] m_vertices;
524 m_vertices = 0;
525 m_vcount = 0;
526 }
527
528 if(m_indices){
529 delete [] m_indices;
530 m_indices = 0;
531 m_icount = 0;
532 }
533
534 int fno = m_polyhedron->GetNoFacets();
535 long faces = 0; //this is primitive face(triangle)
536 for(int i = 0; i < fno; i++){
537 int n, inodes[4];
538 m_polyhedron->GetFacet(i + 1, n, inodes);
539 if(n == 3)
540 faces += 1;
541 else if(n == 4)
542 faces += 2;
543 }
544
545 if(faces < 1)
546 return;
547
548 long fcr = 0;
549 long vno = m_polyhedron->GetNoVertices();
550 m_vcount = 3 * faces;
552 for(int i = 0; i < fno; i++){
553 int n, inodes[4];
554 HVPoint3D pos[4];
555
556 // rbianchi
557 // SbVec3f nor = m_polyhedron->GetNormal(i + 1);
558 HVNormal3D nor = m_polyhedron->GetNormal(i + 1);
559 //---
560 m_polyhedron->GetFacet(i + 1, n, inodes);
561 pos[0] = (inodes[0] <= vno) ? (m_polyhedron->GetVertex(inodes[0])) : (m_polyhedron->GetVertex(1));
562 pos[1] = (inodes[1] <= vno) ? (m_polyhedron->GetVertex(inodes[1])) : (m_polyhedron->GetVertex(1));
563 pos[2] = (inodes[2] <= vno) ? (m_polyhedron->GetVertex(inodes[2])) : (m_polyhedron->GetVertex(1));
564 if(n == 4)
565 pos[3] = (inodes[3] <= vno) ? (m_polyhedron->GetVertex(inodes[3])) : (m_polyhedron->GetVertex(1));
566
567 if(n >= 3){
568 m_vertices[fcr].pos[0] = pos[0][0]; m_vertices[fcr].nor[0] = nor[0];
569 m_vertices[fcr].pos[1] = pos[0][1]; m_vertices[fcr].nor[1] = nor[1];
570 m_vertices[fcr].pos[2] = pos[0][2]; m_vertices[fcr].nor[2] = nor[2];
571 fcr++;
572 m_vertices[fcr].pos[0] = pos[1][0]; m_vertices[fcr].nor[0] = nor[0];
573 m_vertices[fcr].pos[1] = pos[1][1]; m_vertices[fcr].nor[1] = nor[1];
574 m_vertices[fcr].pos[2] = pos[1][2]; m_vertices[fcr].nor[2] = nor[2];
575 fcr++;
576 m_vertices[fcr].pos[0] = pos[2][0]; m_vertices[fcr].nor[0] = nor[0];
577 m_vertices[fcr].pos[1] = pos[2][1]; m_vertices[fcr].nor[1] = nor[1];
578 m_vertices[fcr].pos[2] = pos[2][2]; m_vertices[fcr].nor[2] = nor[2];
579 fcr++;
580 if(n == 4){
581 m_vertices[fcr].pos[0] = pos[0][0]; m_vertices[fcr].nor[0] = nor[0];
582 m_vertices[fcr].pos[1] = pos[0][1]; m_vertices[fcr].nor[1] = nor[1];
583 m_vertices[fcr].pos[2] = pos[0][2]; m_vertices[fcr].nor[2] = nor[2];
584 fcr++;
585 m_vertices[fcr].pos[0] = pos[2][0]; m_vertices[fcr].nor[0] = nor[0];
586 m_vertices[fcr].pos[1] = pos[2][1]; m_vertices[fcr].nor[1] = nor[1];
587 m_vertices[fcr].pos[2] = pos[2][2]; m_vertices[fcr].nor[2] = nor[2];
588 fcr++;
589 m_vertices[fcr].pos[0] = pos[3][0]; m_vertices[fcr].nor[0] = nor[0];
590 m_vertices[fcr].pos[1] = pos[3][1]; m_vertices[fcr].nor[1] = nor[1];
591 m_vertices[fcr].pos[2] = pos[3][2]; m_vertices[fcr].nor[2] = nor[2];
592 fcr++;
593 }
594 }
595 }
596}
597//*/
static Double_t sp
#define SbMaximum(a, b)
Definition SbMath.h:11
#define SbMinimum(a, b)
Definition SbMath.h:10
HVPoint3D HVNormal3D
#define GEN_VERTEX(pv, x, y, z, s, t, nx, ny, nz)
SoPolyhedron is an Inventor encapsulation of the HepPolyedron class written by E.Chernyaev.
SoPolyhedron()
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
virtual void clearAlternateRep()
std::unique_ptr< SbPolyhedron > m_polyhedron
SoSFNode alternateRep
Vertex * m_vertices
virtual void generateAlternateRep()
long * m_indices
void makeShape(SbPolyhedron *)
virtual void generatePrimitives(SoAction *)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
virtual ~SoPolyhedron()
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
virtual void computeBBox(SoAction *, SbBox3f &, SbVec3f &)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
static void initClass()
long hasVertex(Vertex *vertices, long len, Vertex &v)
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146