Geant4 Cross Reference |
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 /*----------------------------HEPVis----------------------------------------*/ 27 /* */ 28 /* Node: SoPolyhedron */ 29 /* Description: SoNode to represent HepPolyhedron */ 30 /* Author: Guy Barrand */ 31 /* */ 32 /*--------------------------------------------------------------------------*/ 33 34 // this : 35 #include "Geant4_SoPolyhedron.h" 36 37 #include <Inventor/SbBox.h> 38 #include <Inventor/actions/SoAction.h> 39 #include <Inventor/SoPrimitiveVertex.h> 40 #include <Inventor/elements/SoTextureCoordinateElement.h> 41 #include <Inventor/nodes/SoSeparator.h> 42 43 //#include <HEPVis/SbMath.h> 44 #define SbMinimum(a,b) ((a)<(b)?a:b) 45 #define SbMaximum(a,b) ((a)>(b)?a:b) 46 47 #include <HEPVis/actions/SoAlternateRepAction.h> 48 49 #include "G4Polyhedron.hh" 50 51 //typedef SbVec3f HVPoint3D; 52 //typedef SbVec3f HVNormal3D; 53 54 typedef HepGeom::Point3D<double> HVPoint3D; 55 typedef HepGeom::Normal3D<double> HVNormal3D; 56 57 SO_NODE_SOURCE(Geant4_SoPolyhedron) 58 ////////////////////////////////////////////////////////////////////////////// 59 void Geant4_SoPolyhedron::initClass( 60 ) 61 ////////////////////////////////////////////////////////////////////////////// 62 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// 63 { 64 static bool first = true; 65 if (first) { 66 first = false; 67 SO_NODE_INIT_CLASS(Geant4_SoPolyhedron,SoShape,"Shape"); 68 } 69 } 70 ////////////////////////////////////////////////////////////////////////////// 71 Geant4_SoPolyhedron::Geant4_SoPolyhedron( 72 ) 73 :fPolyhedron(0) 74 ////////////////////////////////////////////////////////////////////////////// 75 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// 76 { 77 SO_NODE_CONSTRUCTOR(Geant4_SoPolyhedron); 78 SO_NODE_ADD_FIELD(solid,(TRUE)); 79 SO_NODE_ADD_FIELD(reducedWireFrame,(TRUE)); 80 SO_NODE_ADD_FIELD(alternateRep,(NULL)); 81 } 82 ////////////////////////////////////////////////////////////////////////////// 83 Geant4_SoPolyhedron::Geant4_SoPolyhedron( 84 const G4Polyhedron& aPolyhedron 85 ) 86 :fPolyhedron(0) 87 ////////////////////////////////////////////////////////////////////////////// 88 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// 89 { 90 SO_NODE_CONSTRUCTOR(Geant4_SoPolyhedron); 91 SO_NODE_ADD_FIELD(solid,(TRUE)); 92 SO_NODE_ADD_FIELD(reducedWireFrame,(TRUE)); 93 SO_NODE_ADD_FIELD(alternateRep,(NULL)); 94 95 fPolyhedron = new G4Polyhedron(aPolyhedron); 96 } 97 ////////////////////////////////////////////////////////////////////////////// 98 Geant4_SoPolyhedron::Geant4_SoPolyhedron( 99 G4Polyhedron* aPolyhedron 100 ) 101 :fPolyhedron(aPolyhedron) 102 ////////////////////////////////////////////////////////////////////////////// 103 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// 104 { 105 SO_NODE_CONSTRUCTOR(Geant4_SoPolyhedron); 106 SO_NODE_ADD_FIELD(solid,(TRUE)); 107 SO_NODE_ADD_FIELD(reducedWireFrame,(TRUE)); 108 SO_NODE_ADD_FIELD(alternateRep,(NULL)); 109 } 110 ////////////////////////////////////////////////////////////////////////////// 111 Geant4_SoPolyhedron::~Geant4_SoPolyhedron( 112 ) 113 ////////////////////////////////////////////////////////////////////////////// 114 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// 115 { 116 delete fPolyhedron; 117 } 118 ////////////////////////////////////////////////////////////////////////////// 119 void Geant4_SoPolyhedron::generatePrimitives( 120 SoAction* aAction 121 ) 122 ////////////////////////////////////////////////////////////////////////////// 123 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// 124 { 125 if(!fPolyhedron) return; 126 if(fPolyhedron->GetNoFacets()<=0) return; // Abnormal polyhedron. 127 128 SoState *state = aAction->getState(); 129 SbBool useTexFunction = 130 (SoTextureCoordinateElement::getType(state) == 131 SoTextureCoordinateElement::FUNCTION); 132 const SoTextureCoordinateElement *tce = NULL; 133 SbVec4f texCoord(0.,0.,0.,0.); 134 if (useTexFunction) { 135 tce = SoTextureCoordinateElement::getInstance(state); 136 } else { 137 texCoord[2] = 0.0; 138 texCoord[3] = 1.0; 139 } 140 141 if(solid.getValue()==TRUE) { 142 SoPrimitiveVertex pv; 143 SbVec3f point, normal; 144 ////////////////////////////////////////// 145 //---------------------------------------- 146 #define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \ 147 point.setValue(x,y,z); \ 148 normal.setValue(nx,ny,nz); \ 149 if (useTexFunction) { \ 150 texCoord=tce->get(point,normal); \ 151 } else { \ 152 texCoord[0]=s; \ 153 texCoord[1]=t; \ 154 } \ 155 pv.setPoint(point); \ 156 pv.setNormal(normal); \ 157 pv.setTextureCoords(texCoord); \ 158 shapeVertex(&pv); 159 //---------------------------------------- 160 ////////////////////////////////////////// 161 162 // Assume all facets are convex quadrilaterals : 163 bool notLastFace; 164 do { 165 HVNormal3D unitNormal; 166 notLastFace = fPolyhedron->GetNextUnitNormal(unitNormal); 167 168 beginShape(aAction,POLYGON); 169 bool notLastEdge; 170 int edgeFlag = 1; 171 do { 172 HVPoint3D vertex; 173 notLastEdge = fPolyhedron->GetNextVertex(vertex,edgeFlag); 174 GEN_VERTEX(pv, 175 vertex[0], 176 vertex[1], 177 vertex[2], 178 0.0,0.0, 179 unitNormal[0], 180 unitNormal[1], 181 unitNormal[2]); 182 } while (notLastEdge); 183 endShape(); 184 } while (notLastFace); 185 } else { 186 SoPrimitiveVertex pvb,pve; 187 pve.setTextureCoords(texCoord); 188 pvb.setTextureCoords(texCoord); 189 190 #ifdef __COIN__ // To bypass a bug in invokeLineSegment when picking. 191 beginShape(aAction,POLYGON); 192 endShape(); 193 #endif 194 195 SbVec3f point; 196 bool notLastFace; 197 do { 198 HVNormal3D unitNormal; 199 notLastFace = fPolyhedron->GetNextUnitNormal(unitNormal); 200 201 SbVec3f normal; 202 normal.setValue(unitNormal[0],unitNormal[1],unitNormal[2]); 203 204 // Treat edges : 205 int edgeFlag = 1; 206 int prevEdgeFlag = edgeFlag; 207 bool notLastEdge; 208 SbBool firstEdge = TRUE; 209 do { 210 HVPoint3D vertex; 211 notLastEdge = fPolyhedron->GetNextVertex(vertex,edgeFlag); 212 if(reducedWireFrame.getValue()==FALSE) edgeFlag = 1; 213 if(firstEdge) { 214 if(edgeFlag > 0) { 215 pvb.setNormal(normal); 216 point.setValue(vertex[0],vertex[1],vertex[2]); 217 pvb.setPoint(point); 218 } else { 219 } 220 firstEdge = FALSE; 221 prevEdgeFlag = edgeFlag; 222 } else { 223 if(edgeFlag!=prevEdgeFlag) { 224 if(edgeFlag > 0) { // Pass to a visible edge : 225 pvb.setNormal(normal); 226 point.setValue(vertex[0],vertex[1],vertex[2]); 227 pvb.setPoint(point); 228 } else { // Pass to an invisible edge : 229 pve.setNormal(normal); 230 point.setValue(vertex[0],vertex[1],vertex[2]); 231 pve.setPoint(point); 232 invokeLineSegmentCallbacks(aAction,&pvb,&pve); 233 } 234 prevEdgeFlag = edgeFlag; 235 } else { 236 if(edgeFlag > 0) { 237 pve.setNormal(normal); 238 point.setValue(vertex[0],vertex[1],vertex[2]); 239 pve.setPoint(point); 240 invokeLineSegmentCallbacks(aAction,&pvb,&pve); 241 pvb = pve; 242 } else { 243 } 244 } 245 } 246 } while (notLastEdge); 247 } while (notLastFace); 248 } 249 250 } 251 ////////////////////////////////////////////////////////////////////////////// 252 void Geant4_SoPolyhedron::computeBBox( 253 SoAction* 254 ,SbBox3f& aBox 255 ,SbVec3f& aCenter 256 ) 257 ////////////////////////////////////////////////////////////////////////////// 258 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// 259 { 260 if(!fPolyhedron) return; 261 if(fPolyhedron->GetNoFacets()<=0) { // Abnormal polyhedron. 262 SbVec3f vmin(-1,-1,-1); 263 SbVec3f vmax( 1, 1, 1); 264 aBox.setBounds(vmin,vmax); 265 aCenter.setValue(0,0,0); 266 } else { 267 SbBool first = TRUE; 268 float xmn = 0,ymn = 0,zmn = 0; 269 float xmx = 0,ymx = 0,zmx = 0; 270 float xct = 0,yct = 0,zct = 0; 271 SbVec3f point; 272 int count = 0; 273 // Assume all facets are convex quadrilaterals : 274 bool notLastFace; 275 do { 276 HVNormal3D unitNormal; 277 notLastFace = fPolyhedron->GetNextUnitNormal(unitNormal); 278 bool notLastEdge; 279 do { 280 HVPoint3D vertex; 281 int edgeFlag = 1; 282 notLastEdge = fPolyhedron->GetNextVertex(vertex,edgeFlag); 283 point.setValue(vertex[0],vertex[1],vertex[2]); 284 if(first==TRUE) { 285 xct = xmx = xmn = point[0]; 286 yct = ymx = ymn = point[1]; 287 zct = zmx = zmn = point[2]; 288 count++; 289 first = FALSE; 290 } else { 291 xmn = SbMinimum(xmn,point[0]); 292 ymn = SbMinimum(ymn,point[1]); 293 zmn = SbMinimum(zmn,point[2]); 294 // 295 xmx = SbMaximum(xmx,point[0]); 296 ymx = SbMaximum(ymx,point[1]); 297 zmx = SbMaximum(zmx,point[2]); 298 // 299 xct += point[0]; 300 yct += point[1]; 301 zct += point[2]; 302 count++; 303 } 304 // 305 } while (notLastEdge); 306 } while (notLastFace); 307 SbVec3f vmin(xmn,ymn,zmn); 308 SbVec3f vmax(xmx,ymx,zmx); 309 aBox.setBounds(vmin,vmax); 310 if(count==0) 311 aCenter.setValue(0,0,0); 312 else 313 aCenter.setValue(xct/count,yct/count,zct/count); 314 } 315 } 316 317 #include <Inventor/nodes/SoNormalBinding.h> 318 #include <Inventor/nodes/SoNormal.h> 319 #include <Inventor/nodes/SoCoordinate3.h> 320 #include <Inventor/nodes/SoIndexedFaceSet.h> 321 #include <Inventor/nodes/SoIndexedLineSet.h> 322 ////////////////////////////////////////////////////////////////////////////// 323 void Geant4_SoPolyhedron::generateAlternateRep( 324 ) 325 ////////////////////////////////////////////////////////////////////////////// 326 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// 327 { 328 if(!fPolyhedron) return; 329 if(fPolyhedron->GetNoFacets()<=0) return; // Abnormal polyhedron. 330 if(fPolyhedron->GetNoVertices()<=0) return; // Abnormal polyhedron. 331 332 if(solid.getValue()==TRUE) { 333 334 SoSeparator* separator = new SoSeparator; 335 336 SoNormalBinding* normalBinding = new SoNormalBinding; 337 normalBinding->value = SoNormalBinding::PER_FACE; 338 separator->addChild(normalBinding); 339 340 SoCoordinate3* coordinate3 = new SoCoordinate3; 341 separator->addChild(coordinate3); 342 SoNormal* normal = new SoNormal; 343 separator->addChild(normal); 344 SoIndexedFaceSet* indexedFaceSet = new SoIndexedFaceSet; 345 separator->addChild(indexedFaceSet); 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 } while (notLastEdge); 377 378 // end face. 379 coords[ipoint] = SO_END_FACE_INDEX; 380 coordinate3->point.setValues(icoord,ipoint,points); 381 icoord += ipoint; 382 383 normals[inormal].setValue(unitNormal[0],unitNormal[1],unitNormal[2]); 384 inormal++; 385 386 indexedFaceSet->coordIndex.setValues(iindex,(ipoint+1),coords); 387 iindex += ipoint+1; 388 389 } while (notLastFace); 390 391 normal->vector.setValues(0,inormal,normals); 392 393 delete [] normals; 394 delete [] coords; 395 delete [] points; 396 397 alternateRep.setValue(separator); 398 399 } else { 400 401 SoSeparator* separator = new SoSeparator; 402 403 int nvert = fPolyhedron->GetNoVertices(); 404 405 //FIXME : have the exact booking. 406 int nedge = nvert * 3; 407 int npoint = nedge*2; 408 SbVec3f* points = new SbVec3f[npoint]; 409 int ncoord = nedge*3; 410 int32_t* coords = new int32_t[ncoord]; 411 412 SbVec3f pvb(0.,0.,0.), pve(0.,0.,0.); 413 414 SbBool empty = TRUE; 415 int ipoint = 0; 416 int icoord = 0; 417 418 bool notLastFace; 419 do { 420 HVNormal3D unitNormal; 421 notLastFace = fPolyhedron->GetNextUnitNormal(unitNormal); 422 423 //SbVec3f normal; 424 //if( (fProjection==SbProjectionRZ) || (fProjection==SbProjectionZR) ) { 425 //normal.setValue(0,0,1); 426 //} else { 427 //normal.setValue(unitNormal[0],unitNormal[1],unitNormal[2]); 428 //} 429 430 // Treat edges : 431 int edgeFlag = 1; 432 int prevEdgeFlag = edgeFlag; 433 bool notLastEdge; 434 SbBool firstEdge = TRUE; 435 do { 436 HVPoint3D vertex; 437 notLastEdge = fPolyhedron->GetNextVertex(vertex,edgeFlag); 438 if(reducedWireFrame.getValue()==FALSE) edgeFlag = 1; 439 if(firstEdge) { 440 if(edgeFlag > 0) { 441 pvb.setValue(vertex[0],vertex[1],vertex[2]); 442 } else { 443 } 444 firstEdge = FALSE; 445 prevEdgeFlag = edgeFlag; 446 } else { 447 if(edgeFlag!=prevEdgeFlag) { 448 if(edgeFlag > 0) { // Pass to a visible edge : 449 pvb.setValue(vertex[0],vertex[1],vertex[2]); 450 } else { // Pass to an invisible edge : 451 pve.setValue(vertex[0],vertex[1],vertex[2]); 452 453 if((ipoint+1)>=npoint) { 454 int new_npoint = 2 * npoint; 455 SbVec3f* new_points = new SbVec3f[new_npoint]; 456 for(int i=0;i<npoint;i++) new_points[i] = points[i]; 457 delete [] points; 458 npoint = new_npoint; 459 points = new_points; 460 } 461 462 if((icoord+2)>=ncoord) { 463 int new_ncoord = 2 * ncoord; 464 int32_t* new_coords = new int32_t[new_ncoord]; 465 for(int i=0;i<ncoord;i++) new_coords[i] = coords[i]; 466 delete [] coords; 467 ncoord = new_ncoord; 468 coords = new_coords; 469 } 470 471 points[ipoint+0] = pvb; 472 points[ipoint+1] = pve; 473 coords[icoord+0] = ipoint + 0; 474 coords[icoord+1] = ipoint + 1; 475 coords[icoord+2] = SO_END_LINE_INDEX; 476 ipoint += 2; 477 icoord += 3; 478 empty = FALSE; 479 } 480 prevEdgeFlag = edgeFlag; 481 } else { 482 if(edgeFlag > 0) { 483 pve.setValue(vertex[0],vertex[1],vertex[2]); 484 485 if((ipoint+1)>=npoint) { 486 int new_npoint = 2 * npoint; 487 SbVec3f* new_points = new SbVec3f[new_npoint]; 488 for(int i=0;i<npoint;i++) new_points[i] = points[i]; 489 delete [] points; 490 npoint = new_npoint; 491 points = new_points; 492 } 493 494 if((icoord+2)>=ncoord) { 495 int new_ncoord = 2 * ncoord; 496 int32_t* new_coords = new int32_t[new_ncoord]; 497 for(int i=0;i<ncoord;i++) new_coords[i] = coords[i]; 498 delete [] coords; 499 ncoord = new_ncoord; 500 coords = new_coords; 501 } 502 503 points[ipoint+0] = pvb; 504 points[ipoint+1] = pve; 505 coords[icoord+0] = ipoint + 0; 506 coords[icoord+1] = ipoint + 1; 507 coords[icoord+2] = SO_END_LINE_INDEX; 508 ipoint += 2; 509 icoord += 3; 510 empty = FALSE; 511 512 pvb = pve; 513 } else { 514 } 515 } 516 } 517 } while (notLastEdge); 518 } while (notLastFace); 519 520 SoCoordinate3* coordinate3 = new SoCoordinate3; 521 coordinate3->point.setValues(0,ipoint,points); 522 separator->addChild(coordinate3); 523 524 SoIndexedLineSet* indexedLineSet = new SoIndexedLineSet; 525 indexedLineSet->coordIndex.setValues(0,icoord,coords); 526 separator->addChild(indexedLineSet); 527 528 delete [] coords; 529 delete [] points; 530 531 if(empty==TRUE) { 532 separator->unref(); 533 } else { 534 alternateRep.setValue(separator); 535 } 536 } 537 } 538 ////////////////////////////////////////////////////////////////////////////// 539 void Geant4_SoPolyhedron::clearAlternateRep( 540 ) 541 ////////////////////////////////////////////////////////////////////////////// 542 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// 543 { 544 alternateRep.setValue(NULL); 545 } 546 ////////////////////////////////////////////////////////////////////////////// 547 void Geant4_SoPolyhedron::doAction( 548 SoAction* aAction 549 ) 550 ////////////////////////////////////////////////////////////////////////////// 551 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// 552 { 553 SO_ALTERNATEREP_DO_ACTION(aAction) 554 SoShape::doAction(aAction); 555 } 556