Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 /*----------------------------HEPVis---------- 27 /* 28 /* Node: SoPolyhedron 29 /* Description: SoNode to represent HepPo 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/SoTextureCoordinat 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. 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,SoS 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; // 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::getInsta 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 quadrilate 163 bool notLastFace; 164 do { 165 HVNormal3D unitNormal; 166 notLastFace = fPolyhedron->GetNextUnitNo 167 168 beginShape(aAction,POLYGON); 169 bool notLastEdge; 170 int edgeFlag = 1; 171 do { 172 HVPoint3D vertex; 173 notLastEdge = fPolyhedron->GetNextVert 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 invokeLi 191 beginShape(aAction,POLYGON); 192 endShape(); 193 #endif 194 195 SbVec3f point; 196 bool notLastFace; 197 do { 198 HVNormal3D unitNormal; 199 notLastFace = fPolyhedron->GetNextUnitNo 200 201 SbVec3f normal; 202 normal.setValue(unitNormal[0],unitNormal 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->GetNextVert 212 if(reducedWireFrame.getValue()==FALSE) 213 if(firstEdge) { 214 if(edgeFlag > 0) { 215 pvb.setNormal(normal); 216 point.setValue(vertex[0],vertex[1] 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 vi 225 pvb.setNormal(normal); 226 point.setValue(vertex[0],vertex[ 227 pvb.setPoint(point); 228 } else { // Pass to an invisible e 229 pve.setNormal(normal); 230 point.setValue(vertex[0],vertex[ 231 pve.setPoint(point); 232 invokeLineSegmentCallbacks(aActi 233 } 234 prevEdgeFlag = edgeFlag; 235 } else { 236 if(edgeFlag > 0) { 237 pve.setNormal(normal); 238 point.setValue(vertex[0],vertex[ 239 pve.setPoint(point); 240 invokeLineSegmentCallbacks(aActi 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) { // Abnor 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 quadrilate 274 bool notLastFace; 275 do { 276 HVNormal3D unitNormal; 277 notLastFace = fPolyhedron->GetNextUnitNo 278 bool notLastEdge; 279 do { 280 HVPoint3D vertex; 281 int edgeFlag = 1; 282 notLastEdge = fPolyhedron->GetNextVert 283 point.setValue(vertex[0],vertex[1],ver 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 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; // 330 if(fPolyhedron->GetNoVertices()<=0) return; 331 332 if(solid.getValue()==TRUE) { 333 334 SoSeparator* separator = new SoSeparator; 335 336 SoNormalBinding* normalBinding = new SoNor 337 normalBinding->value = SoNormalBinding::PE 338 separator->addChild(normalBinding); 339 340 SoCoordinate3* coordinate3 = new SoCoordin 341 separator->addChild(coordinate3); 342 SoNormal* normal = new SoNormal; 343 separator->addChild(normal); 344 SoIndexedFaceSet* indexedFaceSet = new SoI 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 quadrilate 360 bool notLastFace; 361 do { 362 HVNormal3D unitNormal; 363 notLastFace = fPolyhedron->GetNextUnitNo 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->GetNextVert 373 points[ipoint].setValue(vertex[0],vert 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,ipoi 381 icoord += ipoint; 382 383 normals[inormal].setValue(unitNormal[0], 384 inormal++; 385 386 indexedFaceSet->coordIndex.setValues(iin 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->GetNextUnitNo 422 423 //SbVec3f normal; 424 //if( (fProjection==SbProjectionRZ) || ( 425 //normal.setValue(0,0,1); 426 //} else { 427 //normal.setValue(unitNormal[0],unitNo 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->GetNextVert 438 if(reducedWireFrame.getValue()==FALSE) 439 if(firstEdge) { 440 if(edgeFlag > 0) { 441 pvb.setValue(vertex[0],vertex[1],v 442 } else { 443 } 444 firstEdge = FALSE; 445 prevEdgeFlag = edgeFlag; 446 } else { 447 if(edgeFlag!=prevEdgeFlag) { 448 if(edgeFlag > 0) { // Pass to a vi 449 pvb.setValue(vertex[0],vertex[1] 450 } else { // Pass to an invisible e 451 pve.setValue(vertex[0],vertex[1] 452 453 if((ipoint+1)>=npoint) { 454 int new_npoint = 2 * npoint; 455 SbVec3f* new_points = new SbVe 456 for(int i=0;i<npoint;i++) new_ 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 int3 465 for(int i=0;i<ncoord;i++) new_ 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_I 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] 484 485 if((ipoint+1)>=npoint) { 486 int new_npoint = 2 * npoint; 487 SbVec3f* new_points = new SbVe 488 for(int i=0;i<npoint;i++) new_ 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 int3 497 for(int i=0;i<ncoord;i++) new_ 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_I 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 SoCoordin 521 coordinate3->point.setValues(0,ipoint,poin 522 separator->addChild(coordinate3); 523 524 SoIndexedLineSet* indexedLineSet = new SoI 525 indexedLineSet->coordIndex.setValues(0,ico 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