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