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 // 27 // 28 // 29 /*-----------------------------HEPVis--------- 30 /* 31 /* Node: SoTrap 32 /* Description: Represents the G4Trap Gea 33 /* Author: Joe Boudreau Nov 11 1996 34 /* 35 /* 36 /*-------------------------------------------- 37 38 // this : 39 #include "HEPVis/nodes/SoTrap.h" 40 41 #include <assert.h> 42 #include <cmath> 43 #include <Inventor/SbBox.h> 44 #include <Inventor/actions/SoGLRenderAction.h> 45 #include <Inventor/actions/SoAction.h> 46 #include <Inventor/fields/SoSFFloat.h> 47 #include <Inventor/misc/SoChildList.h> 48 #include <Inventor/nodes/SoSeparator.h> 49 #include <Inventor/nodes/SoIndexedFaceSet.h> 50 #include <Inventor/nodes/SoNormal.h> 51 #include <Inventor/nodes/SoCoordinate3.h> 52 #include <Inventor/nodes/SoNormalBinding.h> 53 #include <Inventor/SoPrimitiveVertex.h> 54 #include <Inventor/elements/SoTextureCoordinat 55 56 #include "HEPVis/SbMath.h" 57 58 // This statement is required 59 SO_NODE_SOURCE(SoTrap) 60 61 // Constructor 62 SoTrap::SoTrap() { 63 // This statement is required 64 SO_NODE_CONSTRUCTOR(SoTrap); 65 66 // Data fields are initialized like this: 67 SO_NODE_ADD_FIELD(pDz, (1.0) 68 SO_NODE_ADD_FIELD(pTheta, (0.0) 69 SO_NODE_ADD_FIELD(pPhi, (0.0) 70 SO_NODE_ADD_FIELD(pDy1, (1.0) 71 SO_NODE_ADD_FIELD(pDx1, (1.0) 72 SO_NODE_ADD_FIELD(pDx2, (1.0) 73 SO_NODE_ADD_FIELD(pDy2, (1.0) 74 SO_NODE_ADD_FIELD(pDx3, (1.0) 75 SO_NODE_ADD_FIELD(pDx4, (1.0) 76 SO_NODE_ADD_FIELD(pAlp1, (0.0) 77 SO_NODE_ADD_FIELD(pAlp2, (0.0) 78 SO_NODE_ADD_FIELD(alternateRep, (NULL 79 children = new SoChildList(this); 80 } 81 82 // Destructor 83 SoTrap::~SoTrap() { 84 delete children; 85 } 86 87 88 // initClass 89 void SoTrap::initClass(){ 90 // This statement is required. 91 static bool first = true; 92 if (first) { 93 first = false; 94 SO_NODE_INIT_CLASS(SoTrap,SoShape,"Shape") 95 } 96 } 97 98 99 // generatePrimitives 100 void SoTrap::generatePrimitives(SoAction *acti 101 // This variable is used to store each verte 102 SoPrimitiveVertex pv; 103 104 // Access the stat from the action 105 SoState *state = action->getState(); 106 107 // See if we have to use a texture coordinat 108 // rather than generating explicit texture c 109 SbBool useTexFunction= 110 (SoTextureCoordinateElement::getType(state 111 SoTextureCoordinateElement::FUNCTION); 112 113 // If we need to generate texture coordinate 114 // we'll need an SoGLTextureCoordinateElemen 115 // set up the coordinates directly. 116 const SoTextureCoordinateElement *tce = NULL 117 SbVec4f texCoord; 118 if (useTexFunction) { 119 tce = SoTextureCoordinateElement::getInsta 120 } 121 else { 122 texCoord[2] = 0.0; 123 texCoord[3] = 1.0; 124 } 125 SbVec3f point, normal; 126 127 128 ////////////////////////////////////////// 129 //---------------------------------------- 130 #define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \ 131 point.setValue(x,y,z); \ 132 normal.setValue(nx,ny,nz); \ 133 if (useTexFunction) { \ 134 texCoord=tce->get(point,normal); \ 135 } \ 136 else { \ 137 texCoord[0]=s; \ 138 texCoord[1]=t; \ 139 } \ 140 pv.setPoint(point); \ 141 pv.setNormal(normal); \ 142 pv.setTextureCoords(texCoord); \ 143 shapeVertex(&pv); 144 //---------------------------------------- 145 ////////////////////////////////////////// 146 147 const int NPOINTS=8, NFACES=6, NINDICES = NF 148 int indices[NINDICES] = {3,2,1,0, SO_END_FAC 149 4,5,6,7, SO_END_FACE_INDEX, //z fron 150 0,1,5,4, SO_END_FACE_INDEX, //y up. 151 1,2,6,5, SO_END_FACE_INDEX, //x left 152 2,3,7,6, SO_END_FACE_INDEX, //y down 153 3,0,4,7, SO_END_FACE_INDEX}; //x righ 154 155 // points for the eight vertices 156 float TthetaCphi = FTAN(pTheta.getValue())*F 157 float TthetaSphi = FTAN(pTheta.getValue())*F 158 float Talp1 = FTAN(pAlp1.getValue()); 159 float Talp2 = FTAN(pAlp2.getValue()); 160 161 float points[NPOINTS][3]; 162 points[0][0] = pDx2.getValue()+pDy1.getValu 163 points[0][1] = pDy1.getValue(); 164 points[0][2] = -pDz.getValue(); 165 166 points[1][0] = -pDx2.getValue()+pDy1.getValu 167 points[1][1] = pDy1.getValue(); 168 points[1][2] = -pDz.getValue(); 169 170 points[2][0] = -pDx1.getValue()-pDy1.getValu 171 points[2][1] = -pDy1.getValue(); 172 points[2][2] = -pDz.getValue(); 173 174 points[3][0] = pDx1.getValue()-pDy1.getValu 175 points[3][1] = -pDy1.getValue(); 176 points[3][2] = -pDz.getValue(); 177 178 points[4][0] = pDx4.getValue()+pDy2.getValu 179 points[4][1] = pDy2.getValue(); 180 points[4][2] = pDz.getValue(); 181 182 points[5][0] = -pDx4.getValue()+pDy2.getValu 183 points[5][1] = pDy2.getValue(); 184 points[5][2] = pDz.getValue(); 185 186 points[6][0] = -pDx3.getValue()-pDy2.getValu 187 points[6][1] = -pDy2.getValue(); 188 points[6][2] = pDz.getValue(); 189 190 points[7][0] = pDx3.getValue()-pDy2.getValu 191 points[7][1] = -pDy2.getValue(); 192 points[7][2] = pDz.getValue(); 193 194 int i; 195 for (i=0;i<4;i++) { 196 points[i][0] -= pDz.getValue()*TthetaCphi; 197 points[i][1] -= pDz.getValue()*TthetaSphi; 198 } 199 for (i=4;i<8;i++) { 200 points[i][0] += pDz.getValue()*TthetaCphi; 201 points[i][1] += pDz.getValue()*TthetaSphi; 202 } 203 204 SbVec3f normals[NFACES]; 205 int nf; 206 for (nf=0;nf<NFACES;nf++) { 207 int j0 = indices[5*nf + 0]; 208 int j1 = indices[5*nf + 1]; 209 int j2 = indices[5*nf + 2]; 210 SbVec3f p0(points[j0][0],points[j0][1],poi 211 SbVec3f p1(points[j1][0],points[j1][1],poi 212 SbVec3f p2(points[j2][0],points[j2][1],poi 213 normals[nf] = (p1-p0).cross(p2-p0); 214 normals[nf].normalize(); 215 } 216 217 float x,y,z; 218 int index; 219 for (nf=0;nf<NFACES;nf++) { 220 beginShape(action,TRIANGLE_FAN); 221 index = indices[nf * 5]; 222 x = points[index][0]; 223 y = points[index][1]; 224 z = points[index][2]; 225 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0] 226 index = indices[nf * 5 + 1]; 227 x = points[index][0]; 228 y = points[index][1]; 229 z = points[index][2]; 230 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0] 231 index = indices[nf * 5 + 2]; 232 x = points[index][0]; 233 y = points[index][1]; 234 z = points[index][2]; 235 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0] 236 index = indices[nf * 5 + 3]; 237 x = points[index][0]; 238 y = points[index][1]; 239 z = points[index][2]; 240 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0] 241 endShape(); 242 } 243 } 244 245 // getChildren 246 SoChildList *SoTrap::getChildren() const { 247 return children; 248 } 249 250 251 // computeBBox 252 void SoTrap::computeBBox(SoAction *, SbBox3f & 253 float pDx= pDx1.getValue(),pDy=pDy1.getValue 254 255 if (pDx2.getValue() > pDx) pDx = pDx2.getVal 256 if (pDx3.getValue() > pDx) pDx = pDx3.getVal 257 if (pDx4.getValue() > pDx) pDx = pDx4.getVal 258 if (pDy2.getValue() > pDy) pDy = pDy2.getVal 259 float TthetaCphi = FTAN(pTheta.getValue())*F 260 float TthetaSphi = FTAN(pTheta.getValue())*F 261 float Xalp = FFABS(std::tan(pAlp1.getValue() 262 float Xalp2 = FFABS(std::tan(pAlp2.getValue( 263 if (Xalp< Xalp2) Xalp=Xalp2; 264 pDx += FFABS(TthetaCphi*pDz.getValue()); 265 pDx += Xalp; 266 pDy += FFABS(TthetaSphi*pDz.getValue()); 267 268 269 center.setValue(0,0,0); 270 box.setBounds(SbVec3f(-pDx,-pDy,-pDz.getValu 271 SbVec3f( pDx, pDy, pDz.getValue())); 272 } 273 274 275 276 277 // updateChildren 278 void SoTrap::updateChildren() { 279 280 281 // Redraw the G4Trap.... 282 283 assert(children->getLength()==1); 284 SoSeparator *sep = (SoS 285 SoCoordinate3 *theCoordinates = (SoC 286 SoNormal *theNormals = (SoN 287 SoNormalBinding *theNormalBinding = (SoN 288 SoIndexedFaceSet *theFaceSet = (SoI 289 290 const int NPOINTS=8, NFACES=6, NINDICES = NF 291 float points[NPOINTS][3]; 292 // Indices for the eight faces 293 #ifdef INVENTOR2_0 294 static long 295 #else 296 static int32_t 297 #endif 298 indices[NINDICES] = {3,2,1,0, SO_END_FACE_IN 299 4,5,6,7, SO_END_FACE_INDE 300 0,1,5,4, SO_END_FACE_INDE 301 1,2,6,5, SO_END_FACE_INDE 302 2,3,7,6, SO_END_FACE_INDE 303 3,0,4,7, SO_END_FACE_INDE 304 305 306 // points for the eight vertices 307 float TthetaCphi = FTAN(pTheta.getValue())*F 308 float TthetaSphi = FTAN(pTheta.getValue())*F 309 float Talp1 = FTAN(pAlp1.getValue()); 310 float Talp2 = FTAN(pAlp2.getValue()); 311 312 points[0][0] = pDx2.getValue()+pDy1.getValu 313 points[0][1] = pDy1.getValue(); 314 points[0][2] = -pDz.getValue(); 315 316 points[1][0] = -pDx2.getValue()+pDy1.getValu 317 points[1][1] = pDy1.getValue(); 318 points[1][2] = -pDz.getValue(); 319 320 points[2][0] = -pDx1.getValue()-pDy1.getValu 321 points[2][1] = -pDy1.getValue(); 322 points[2][2] = -pDz.getValue(); 323 324 points[3][0] = pDx1.getValue()-pDy1.getValu 325 points[3][1] = -pDy1.getValue(); 326 points[3][2] = -pDz.getValue(); 327 328 points[4][0] = pDx4.getValue()+pDy2.getValu 329 points[4][1] = pDy2.getValue(); 330 points[4][2] = pDz.getValue(); 331 332 points[5][0] = -pDx4.getValue()+pDy2.getValu 333 points[5][1] = pDy2.getValue(); 334 points[5][2] = pDz.getValue(); 335 336 points[6][0] = -pDx3.getValue()-pDy2.getValu 337 points[6][1] = -pDy2.getValue(); 338 points[6][2] = pDz.getValue(); 339 340 points[7][0] = pDx3.getValue()-pDy2.getValu 341 points[7][1] = -pDy2.getValue(); 342 points[7][2] = pDz.getValue(); 343 344 int i; 345 for (i=0;i<4;i++) { 346 points[i][0] -= pDz.getValue()*TthetaCphi; 347 points[i][1] -= pDz.getValue()*TthetaSphi; 348 } 349 for (i=4;i<8;i++) { 350 points[i][0] += pDz.getValue()*TthetaCphi; 351 points[i][1] += pDz.getValue()*TthetaSphi; 352 } 353 354 for (int np=0;np<NPOINTS;np++) theCoordinate 355 theFaceSet->coordIndex.setValues(0,NINDICES, 356 theNormals->vector.deleteValues(0); 357 theNormals->vector.insertSpace(0,6); 358 for (int n=0;n<6;n++) { 359 int i0 = 5*n+0,i1=5*n+1,i2=5*n+2; 360 int j0 = theFaceSet->coordIndex[i0]; 361 int j1 = theFaceSet->coordIndex[i1]; 362 int j2 = theFaceSet->coordIndex[i2]; 363 SbVec3f p0= theCoordinates->point[j0]; 364 SbVec3f p1= theCoordinates->point[j1]; 365 SbVec3f p2= theCoordinates->point[j2]; 366 SbVec3f normal = (p1-p0).cross(p2-p0); 367 normal.normalize(); 368 theNormals->vector.set1Value(n,normal); 369 } 370 theNormalBinding->value=SoNormalBinding::PER 371 } 372 373 // generateChildren 374 void SoTrap::generateChildren() { 375 376 // This routines creates one SoSeparator, on 377 // one SoLineSet, and puts it in the child l 378 // once, whereas redrawing the position of t 379 // time an update is necessary, in the updat 380 381 assert(children->getLength() ==0); 382 SoSeparator *sep = new SoS 383 SoCoordinate3 *theCoordinates = new SoC 384 SoNormal *theNormals = new SoN 385 SoNormalBinding *theNormalBinding = new SoN 386 SoIndexedFaceSet *theFaceSet = new SoI 387 // 388 // This line costs some in render quality! b 389 // 390 sep->addChild(theCoordinates); 391 sep->addChild(theNormals); 392 sep->addChild(theNormalBinding); 393 sep->addChild(theFaceSet); 394 children->append(sep); 395 } 396 397 // generateAlternateRep 398 void SoTrap::generateAlternateRep() { 399 400 // This routine sets the alternate represent 401 // list of this mode. 402 403 if (children->getLength() == 0) generateChil 404 updateChildren(); 405 alternateRep.setValue((SoSeparator *) ( *ch 406 } 407 408 // clearAlternateRep 409 void SoTrap::clearAlternateRep() { 410 alternateRep.setValue(NULL); 411 } 412