00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifdef G4VIS_BUILD_OI_DRIVER
00039
00040
00041 #include "HEPVis/nodes/SoTubs.h"
00042
00043 #include <assert.h>
00044 #include <cmath>
00045
00046 #include <Inventor/SbBox.h>
00047 #include <Inventor/actions/SoGLRenderAction.h>
00048 #include <Inventor/fields/SoSFFloat.h>
00049 #include <Inventor/misc/SoChildList.h>
00050 #include <Inventor/nodes/SoSeparator.h>
00051 #include <Inventor/nodes/SoIndexedFaceSet.h>
00052 #include <Inventor/nodes/SoNormal.h>
00053 #include <Inventor/nodes/SoCoordinate3.h>
00054 #include <Inventor/nodes/SoNormalBinding.h>
00055 #include <Inventor/SoPrimitiveVertex.h>
00056 #include <Inventor/elements/SoTextureCoordinateElement.h>
00057
00058 #include "HEPVis/SbMath.h"
00059
00060
00061 SO_NODE_SOURCE(SoTubs)
00062
00063
00064 SoTubs::SoTubs() {
00065
00066
00067
00068 SO_NODE_CONSTRUCTOR(SoTubs);
00069
00070
00071 SO_NODE_ADD_FIELD(pRMin, (0));
00072 SO_NODE_ADD_FIELD(pRMax, (1));
00073 SO_NODE_ADD_FIELD(pDz, (10));
00074 SO_NODE_ADD_FIELD(pSPhi, (0));
00075 SO_NODE_ADD_FIELD(pDPhi, ((float)(2*M_PI)));
00076 SO_NODE_ADD_FIELD(alternateRep, (NULL));
00077 children = new SoChildList(this);
00078 }
00079
00080
00081 SoTubs::~SoTubs() {
00082 delete children;
00083 }
00084
00085
00086
00087 void SoTubs::initClass(){
00088
00089 SO_NODE_INIT_CLASS(SoTubs,SoShape,"Shape");
00090 }
00091
00092
00093 void SoTubs::generatePrimitives(SoAction *action) {
00094
00095 SoPrimitiveVertex pv;
00096
00097
00098 SoState *state = action->getState();
00099
00100
00101
00102 SbBool useTexFunction=
00103 (SoTextureCoordinateElement::getType(state) ==
00104 SoTextureCoordinateElement::FUNCTION);
00105
00106
00107
00108
00109 const SoTextureCoordinateElement* tce = NULL;
00110 SbVec4f texCoord;
00111 if (useTexFunction) {
00112 tce = SoTextureCoordinateElement::getInstance(state);
00113 }
00114 else {
00115 texCoord[2] = 0.0;
00116 texCoord[3] = 1.0;
00117 }
00118 SbVec3f point, normal;
00119
00120
00122
00123 #define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \
00124 point.setValue((float)(x),(float)(y),(float)(z)); \
00125 normal.setValue((float)(nx),(float)(ny),(float)(nz)); \
00126 if (useTexFunction) { \
00127 texCoord=tce->get(point,normal); \
00128 } else { \
00129 texCoord[0]=(float)(s); \
00130 texCoord[1]=(float)(t); \
00131 } \
00132 pv.setPoint(point); \
00133 pv.setNormal(normal); \
00134 pv.setTextureCoords(texCoord); \
00135 shapeVertex(&pv);
00136
00138
00139 int NPHI = (int)(2+22*std::fabs(pDPhi.getValue()/(2.0*M_PI)));
00140 double deltaPhi = pDPhi.getValue()/NPHI, phi0 = pSPhi.getValue(),phi1=phi0+pDPhi.getValue();
00141 double rMax=pRMax.getValue(),rMin=pRMin.getValue();
00142 double zMax=pDz.getValue(),zMin=-zMax;
00143 double cosPhi0=std::cos(phi0), sinPhi0=std::sin(phi0);
00144 double cosPhi1=std::cos(phi1), sinPhi1=std::sin(phi1);
00145 double cosDeltaPhi=std::cos(deltaPhi),sinDeltaPhi=std::sin(deltaPhi);
00146
00147
00148
00149 int i;
00150 double sinPhi,cosPhi;
00151 beginShape(action,TRIANGLE_STRIP);
00152 sinPhi=sinPhi0;
00153 cosPhi=cosPhi0;
00154 for (i = 0; i<=NPHI; i++) {
00155 GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMax,0.0,0.0,cosPhi,sinPhi,0);
00156 GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMin,1.0,1.0,cosPhi,sinPhi,0);
00157 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
00158 }
00159 endShape();
00160
00161
00162
00163 if(rMin!=0.F) {
00164 beginShape(action,TRIANGLE_STRIP);
00165 sinPhi=sinPhi0;
00166 cosPhi=cosPhi0;
00167 for (i = 0; i<=NPHI; i++) {
00168 GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi,zMax,0.0,0.0,-cosPhi,-sinPhi,0);
00169 GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi,zMin,1.0,1.0,-cosPhi,-sinPhi,0);
00170 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
00171 }
00172 endShape();
00173 }
00174 if (std::fabs(deltaPhi)<2.0*M_PI) {
00175
00176
00177
00178 beginShape(action,TRIANGLE_STRIP);
00179 sinPhi=sinPhi0;
00180 cosPhi=cosPhi0;
00181 GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMax,0.0,0.0,sinPhi,-cosPhi,0);
00182 GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMin,1.0,1.0,sinPhi,-cosPhi,0);
00183 GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi,zMax,1.0,0.0,sinPhi,-cosPhi,0);
00184 GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi,zMin,0.0,1.0,sinPhi,-cosPhi,0);
00185 endShape();
00186
00187
00188
00189 beginShape(action,TRIANGLE_STRIP);
00190 sinPhi=sinPhi1;
00191 cosPhi=cosPhi1;
00192 GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi, zMax,0.0,0.0,-sinPhi,+cosPhi,0);
00193 GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi, zMin,1.0,1.0,-sinPhi,+cosPhi,0);
00194 GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi, zMax,1.0,0.0,-sinPhi,+cosPhi,0);
00195 GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi, zMin,0.0,1.0,-sinPhi,+cosPhi,0);
00196 endShape();
00197 }
00198
00199
00200
00201 if(rMin==0.F) {
00202 beginShape(action,TRIANGLE_FAN);
00203 sinPhi=sinPhi0;
00204 cosPhi=cosPhi0;
00205 GEN_VERTEX(pv,0,0,zMax,0.0,0.0,0,0,1);
00206 for (i = 0; i<=NPHI; i++) {
00207 GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMax,1.0,1.0,0,0,1);
00208 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
00209 }
00210 endShape();
00211
00212
00213
00214 beginShape(action,TRIANGLE_FAN);
00215 sinPhi=sinPhi0;
00216 cosPhi=cosPhi0;
00217 GEN_VERTEX(pv,0,0,zMin,0.0,0.0,0,0,-1);
00218 for (i = 0; i<=NPHI; i++) {
00219 GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMin,1.0,1.0,0,0,-1);
00220 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
00221 }
00222 endShape();
00223 } else {
00224 beginShape(action,TRIANGLE_STRIP);
00225 sinPhi=sinPhi0;
00226 cosPhi=cosPhi0;
00227 for (i = 0; i<=NPHI; i++) {
00228 GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi,zMax,0.0,0.0,0,0,1);
00229 GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMax,1.0,1.0,0,0,1);
00230 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
00231 }
00232 endShape();
00233
00234
00235
00236 beginShape(action,TRIANGLE_STRIP);
00237 sinPhi=sinPhi0;
00238 cosPhi=cosPhi0;
00239 for (i = 0; i<=NPHI; i++) {
00240 GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi,zMin,0.0,0.0,0,0,-1);
00241 GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMin,1.0,1.0,0,0,-1);
00242 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
00243 }
00244 endShape();
00245 }
00246 }
00247
00248
00249 SoChildList *SoTubs::getChildren() const {
00250 return children;
00251 }
00252
00253
00254
00255 void SoTubs::computeBBox(SoAction *, SbBox3f &box, SbVec3f ¢er ){
00256 SbVec3f vmin(-pRMax.getValue(),-pRMax.getValue(),-pDz.getValue()),
00257 vmax( pRMax.getValue(), pRMax.getValue(), pDz.getValue());
00258 center.setValue(0,0,0);
00259 box.setBounds(vmin,vmax);
00260 }
00261
00262
00263
00264 void SoTubs::updateChildren() {
00265
00266
00267
00268 assert(children->getLength()==1);
00269 SoSeparator *sep = (SoSeparator *) ( *children)[0];
00270 SoCoordinate3 *theCoordinates = (SoCoordinate3 *) ( sep->getChild(0));
00271 SoNormal *theNormals = (SoNormal *) ( sep->getChild(1));
00272 SoNormalBinding *theNormalBinding = (SoNormalBinding *) ( sep->getChild(2));
00273 SoIndexedFaceSet *theFaceSet = (SoIndexedFaceSet *) ( sep->getChild(3));
00274
00275
00276 const int NPHI=24, NPOINTS=2*(2*NPHI+2), NFACES=4*NPHI+2, NINDICES = NFACES*5;
00277 float points[NPOINTS][3],normals[NFACES][3];
00278 #ifdef INVENTOR2_0
00279 static long indices[NINDICES];
00280 #else
00281 static int32_t indices[NINDICES];
00282 #endif
00283
00284 static int init=0;
00285 double phi, pp, DeltaPhi;
00286
00287
00288
00289
00290 int i;
00291 if (!init) {
00292 init = 1;
00293
00294 for (i = 0; i< NPHI; i++) {
00295
00296 indices[5*i+0] = 2*i+0;
00297 indices[5*i+1] = 2*i+1;
00298 indices[5*i+2] = 2*i+3;
00299 indices[5*i+3] = 2*i+2;
00300 indices[5*i+4] = SO_END_FACE_INDEX;
00301 }
00302
00303 for (i=0;i<NPHI;i++) {
00304 indices[5*1*NPHI + 5*i+0] = 2*NPHI+2 + 2*i+0;
00305 indices[5*1*NPHI + 5*i+1] = 2*NPHI+2 + 2*i+1;
00306 indices[5*1*NPHI + 5*i+2] = 2*NPHI+2 + 2*i+3;
00307 indices[5*1*NPHI + 5*i+3] = 2*NPHI+2 + 2*i+2;
00308 indices[5*1*NPHI + 5*i+4] = SO_END_FACE_INDEX;
00309 }
00310
00311 for (i=0;i<NPHI;i++) {
00312 indices[5*2*NPHI + 5*i+0] = 2*i+0;
00313 indices[5*2*NPHI + 5*i+1] = 2*i+2;
00314 indices[5*2*NPHI + 5*i+2] = NPOINTS - (2*i+4);
00315 indices[5*2*NPHI + 5*i+3] = NPOINTS - (2*i+2);
00316 indices[5*2*NPHI + 5*i+4] = SO_END_FACE_INDEX;
00317 }
00318
00319 for (i=0;i<NPHI;i++) {
00320 indices[5*3*NPHI + 5*i+0] = 2*i+1;
00321 indices[5*3*NPHI + 5*i+1] = NPOINTS - (2*i+1);
00322 indices[5*3*NPHI + 5*i+2] = NPOINTS - (2*i+3);
00323 indices[5*3*NPHI + 5*i+3] = 2*i+3;
00324 indices[5*3*NPHI + 5*i+4] = SO_END_FACE_INDEX;
00325 }
00326
00327 indices[5*4*NPHI +0] = 2*NPHI;
00328 indices[5*4*NPHI +1] = 2*NPHI+1;
00329 indices[5*4*NPHI +2] = 2*NPHI+3;
00330 indices[5*4*NPHI +3] = 2*NPHI+2;
00331 indices[5*4*NPHI +4] = SO_END_FACE_INDEX;
00332
00333 indices[5*4*NPHI +5 +0] = 0;
00334 indices[5*4*NPHI +5 +1] = NPOINTS-2;
00335 indices[5*4*NPHI +5 +2] = NPOINTS-1;
00336 indices[5*4*NPHI +5 +3] = 1;
00337 indices[5*4*NPHI +5 +4] = SO_END_FACE_INDEX;
00338 }
00339
00340 if (pDPhi.getValue()<2*M_PI) {
00341
00342 indices[5*4*NPHI +0] = 2*NPHI;
00343 indices[5*4*NPHI +1] = 2*NPHI+1;
00344 indices[5*4*NPHI +2] = 2*NPHI+3;
00345 indices[5*4*NPHI +3] = 2*NPHI+2;
00346 indices[5*4*NPHI +4] = SO_END_FACE_INDEX;
00347
00348 indices[5*4*NPHI +5 +0] = 0;
00349 indices[5*4*NPHI +5 +1] = NPOINTS-2;
00350 indices[5*4*NPHI +5 +2] = NPOINTS-1;
00351 indices[5*4*NPHI +5 +3] = 1;
00352 indices[5*4*NPHI +5 +4] = SO_END_FACE_INDEX;
00353 }
00354 else {
00355
00356 indices[5*4*NPHI +0] = SO_END_FACE_INDEX;
00357 indices[5*4*NPHI +1] = SO_END_FACE_INDEX;
00358 indices[5*4*NPHI +2] = SO_END_FACE_INDEX;
00359 indices[5*4*NPHI +3] = SO_END_FACE_INDEX;
00360 indices[5*4*NPHI +4] = SO_END_FACE_INDEX;
00361
00362 indices[5*4*NPHI +5 +0] = SO_END_FACE_INDEX;
00363 indices[5*4*NPHI +5 +1] = SO_END_FACE_INDEX;
00364 indices[5*4*NPHI +5 +2] = SO_END_FACE_INDEX;
00365 indices[5*4*NPHI +5 +3] = SO_END_FACE_INDEX;
00366 indices[5*4*NPHI +5 +4] = SO_END_FACE_INDEX;
00367 }
00368
00369 DeltaPhi = pDPhi.getValue()/NPHI, phi = pSPhi.getValue();
00370 for (i = 0; i<=NPHI; i++) {
00371 points[2*i+0][0] = pRMax.getValue()*FCOS(phi);
00372 points[2*i+0][1]= pRMax.getValue()*FSIN(phi);
00373 points[2*i+0][2] = +pDz.getValue();
00374
00375 points[2*i+1][0] = pRMax.getValue()*FCOS(phi);
00376 points[2*i+1][1]= pRMax.getValue()*FSIN(phi);
00377 points[2*i+1][2] = -pDz.getValue();
00378
00379 pp = phi+DeltaPhi/2.0;
00380 if (i!=NPHI) {
00381 normals[i][0] = FCOS(pp);
00382 normals[i][1] = FSIN(pp);
00383 normals[i][2] = 0;
00384 }
00385 phi+=DeltaPhi;
00386 }
00387
00388 phi = pSPhi.getValue() + pDPhi.getValue();
00389 for (i = 0; i<=NPHI; i++) {
00390 points[2*NPHI+2+2*i+0][0] = pRMin.getValue()*FCOS(phi);
00391 points[2*NPHI+2+2*i+0][1] = pRMin.getValue()*FSIN(phi);
00392 points[2*NPHI+2+2*i+0][2] = +pDz.getValue();
00393 points[2*NPHI+2+2*i+1][0] = pRMin.getValue()*FCOS(phi);
00394 points[2*NPHI+2+2*i+1][1] = pRMin.getValue()*FSIN(phi);
00395 points[2*NPHI+2+2*i+1][2] = -pDz.getValue();
00396 pp = phi-DeltaPhi/2.0;
00397 if (i!=NPHI) {
00398 normals[NPHI+i][0] = -FCOS(pp);
00399 normals[NPHI+i][1] = -FSIN(pp);
00400 normals[NPHI+i][2] = 0;
00401 }
00402 phi-=DeltaPhi;
00403 }
00404
00405 for (i=0;i<NPHI;i++) {
00406 normals[2*NPHI+i][0]=normals[2*NPHI+i][1]=0;
00407 normals[2*NPHI+i][2]= 1.0;
00408 }
00409
00410 for (i=0;i<NPHI;i++) {
00411 normals[3*NPHI+i][0]=normals[3*NPHI+i][1]=0;
00412 normals[3*NPHI+i][2]= -1.0;
00413 }
00414
00415 phi = pSPhi.getValue();
00416 normals[4*NPHI+0][0]= FSIN(phi);
00417 normals[4*NPHI+0][1]= -FCOS(phi);
00418 normals[4*NPHI+0][2]=0;
00419
00420
00421 phi = pSPhi.getValue()+pDPhi.getValue();
00422 normals[4*NPHI+1][0]= -FSIN(phi);
00423 normals[4*NPHI+1][1]= +FCOS(phi);
00424 normals[4*NPHI+1][2]=0;
00425
00426 for (int np=0;np<NPOINTS; np++) theCoordinates->point.set1Value(np,points[np][0],points[np][1],points[np][2]);
00427 for (int ni=0;ni<NINDICES;ni++) theFaceSet->coordIndex.set1Value(ni,indices[ni]);
00428 for (int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
00429 theNormalBinding->value=SoNormalBinding::PER_FACE;
00430 }
00431
00432
00433 void SoTubs::generateChildren() {
00434
00435
00436
00437
00438
00439
00440 assert(children->getLength() ==0);
00441 SoSeparator *sep = new SoSeparator();
00442 SoCoordinate3 *theCoordinates = new SoCoordinate3();
00443 SoNormal *theNormals = new SoNormal();
00444 SoNormalBinding *theNormalBinding = new SoNormalBinding();
00445 SoIndexedFaceSet *theFaceSet = new SoIndexedFaceSet();
00446
00447
00448
00449 sep->addChild(theCoordinates);
00450 sep->addChild(theNormals);
00451 sep->addChild(theNormalBinding);
00452 sep->addChild(theFaceSet);
00453 children->append(sep);
00454 }
00455
00456
00457 void SoTubs::generateAlternateRep() {
00458
00459
00460
00461
00462 if (children->getLength() == 0) generateChildren();
00463 updateChildren();
00464 alternateRep.setValue((SoSeparator *) ( *children)[0]);
00465 }
00466
00467
00468 void SoTubs::clearAlternateRep() {
00469 alternateRep.setValue(NULL);
00470 }
00471
00472 #endif