19 #include <Inventor/SbBox.h>
20 #include <Inventor/actions/SoGLRenderAction.h>
22 #include <Inventor/misc/SoChildList.h>
23 #include <Inventor/nodes/SoSeparator.h>
24 #include <Inventor/nodes/SoIndexedFaceSet.h>
25 #include <Inventor/nodes/SoNormal.h>
26 #include <Inventor/nodes/SoCoordinate3.h>
27 #include <Inventor/nodes/SoNormalBinding.h>
28 #include <Inventor/SoPrimitiveVertex.h>
29 #include <Inventor/elements/SoTextureCoordinateElement.h>
30 #include <Inventor/elements/SoGLCacheContextElement.h>
31 #include <Inventor/C/glue/gl.h>
44 SO_NODE_CONSTRUCTOR(
SoTubs);
47 SO_NODE_ADD_FIELD(pRMin, (0));
48 SO_NODE_ADD_FIELD(pRMax, (1));
49 SO_NODE_ADD_FIELD(pDz, (10));
50 SO_NODE_ADD_FIELD(pSPhi, (0));
51 SO_NODE_ADD_FIELD(pDPhi, ((
float)(2*
M_PI)));
52 SO_NODE_ADD_FIELD(pOverrideNPhi, (0));
53 SO_NODE_ADD_FIELD(alternateRep, (NULL));
54 SO_NODE_ADD_FIELD(drawEdgeLines, (
false));
56 m_children =
new SoChildList(
this);
58 setNodeType(EXTENSION);
70 [[maybe_unused]]
static const bool didInit = [&]() {
71 SO_NODE_INIT_CLASS(
SoTubs,SoShape,
"Shape");
82 SoState *state =
action->getState();
88 SbBool useTexFunction=
90 SoTextureCoordinateElement::FUNCTION);
95 const SoTextureCoordinateElement* tce = NULL;
98 tce = SoTextureCoordinateElement::getInstance(state);
104 SbVec3f point, normal;
109 #define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \
110 point.setValue((float)(x),(float)(y),(float)(z)); \
111 normal.setValue((float)(nx),(float)(ny),(float)(nz)); \
112 if (useTexFunction) { \
113 texCoord=tce->get(point,normal); \
115 texCoord[0]=(float)(s); \
116 texCoord[1]=(float)(t); \
118 pv.setPoint(point); \
119 pv.setNormal(normal); \
120 pv.setTextureCoords(texCoord); \
128 double rMax=
pRMax.getValue(),rMin=
pRMin.getValue();
129 double zMax=
pDz.getValue(),zMin=-zMax;
131 double cosPhi1=
cos(phi1), sinPhi1=
sin(phi1);
133 const bool noPhiCutout=fabs(
pDPhi.getValue())==0.F || fabs(fabs(
pDPhi.getValue())-2.0*
M_PI)<0.01;
134 const bool disableLighting(glIsEnabled(GL_LIGHTING));
135 const bool transparencyOn(glIsEnabled(GL_BLEND));
141 double sinPhi,cosPhi;
142 beginShape(
action,TRIANGLE_STRIP);
145 for (
i = 0;
i<=NPHI;
i++) {
146 GEN_VERTEX(
pv,rMax*cosPhi,rMax*sinPhi,zMax,0.0,0.0,cosPhi,sinPhi,0);
147 GEN_VERTEX(
pv,rMax*cosPhi,rMax*sinPhi,zMin,1.0,1.0,cosPhi,sinPhi,0);
148 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
155 beginShape(
action,TRIANGLE_STRIP);
158 for (
i = 0;
i<=NPHI;
i++) {
159 GEN_VERTEX(
pv,rMin*cosPhi,rMin*sinPhi,zMax,0.0,0.0,-cosPhi,-sinPhi,0);
160 GEN_VERTEX(
pv,rMin*cosPhi,rMin*sinPhi,zMin,1.0,1.0,-cosPhi,-sinPhi,0);
161 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
175 beginShape(
action,TRIANGLE_STRIP);
178 GEN_VERTEX(
pv,rMax*cosPhi,rMax*sinPhi,zMax,0.0,0.0,sinPhi,-cosPhi,0);
179 GEN_VERTEX(
pv,rMax*cosPhi,rMax*sinPhi,zMin,1.0,1.0,sinPhi,-cosPhi,0);
180 GEN_VERTEX(
pv,rMin*cosPhi,rMin*sinPhi,zMax,1.0,0.0,sinPhi,-cosPhi,0);
181 GEN_VERTEX(
pv,rMin*cosPhi,rMin*sinPhi,zMin,0.0,1.0,sinPhi,-cosPhi,0);
186 beginShape(
action,TRIANGLE_STRIP);
189 GEN_VERTEX(
pv,rMax*cosPhi,rMax*sinPhi, zMax,0.0,0.0,-sinPhi,+cosPhi,0);
190 GEN_VERTEX(
pv,rMax*cosPhi,rMax*sinPhi, zMin,1.0,1.0,-sinPhi,+cosPhi,0);
191 GEN_VERTEX(
pv,rMin*cosPhi,rMin*sinPhi, zMax,1.0,0.0,-sinPhi,+cosPhi,0);
192 GEN_VERTEX(
pv,rMin*cosPhi,rMin*sinPhi, zMin,0.0,1.0,-sinPhi,+cosPhi,0);
196 if (disableLighting) glDisable(GL_LIGHTING);
197 if (transparencyOn) glDisable(GL_BLEND);
200 glVertex3f(rMax*cosPhi0,rMax*sinPhi0, zMax);
201 glVertex3f(rMax*cosPhi0,rMax*sinPhi0, zMin);
202 glVertex3f(rMin*cosPhi0,rMin*sinPhi0, zMax);
203 glVertex3f(rMin*cosPhi0,rMin*sinPhi0, zMin);
204 glVertex3f(rMax*cosPhi1,rMax*sinPhi1, zMax);
205 glVertex3f(rMax*cosPhi1,rMax*sinPhi1, zMin);
206 glVertex3f(rMin*cosPhi1,rMin*sinPhi1, zMax);
207 glVertex3f(rMin*cosPhi1,rMin*sinPhi1, zMin);
209 if (disableLighting) glEnable(GL_LIGHTING);
210 if (transparencyOn) glEnable(GL_BLEND);
218 beginShape(
action,TRIANGLE_FAN);
222 for (
i = 0;
i<=NPHI;
i++) {
223 GEN_VERTEX(
pv,rMax*cosPhi,rMax*sinPhi,zMax,1.0,1.0,0,0,1);
224 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
230 beginShape(
action,TRIANGLE_FAN);
234 for (
i = 0;
i<=NPHI;
i++) {
235 GEN_VERTEX(
pv,rMax*cosPhi,rMax*sinPhi,zMin,1.0,1.0,0,0,-1);
236 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
242 if (disableLighting) glDisable(GL_LIGHTING);
243 if (transparencyOn) glDisable(GL_BLEND);
244 glBegin(GL_LINE_STRIP);
247 if (!noPhiCutout) glVertex3f(0,0,zMax);
248 for (
i = 0;
i<=NPHI;
i++) {
249 glVertex3f(rMax*cosPhi,rMax*sinPhi,zMax);
250 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
252 if (!noPhiCutout) glVertex3f(0,0,zMax);
256 glBegin(GL_LINE_STRIP);
259 if (!noPhiCutout) glVertex3f(0,0,zMin);
260 for (
i = 0;
i<=NPHI;
i++) {
261 glVertex3f(rMax*cosPhi,rMax*sinPhi,zMin);
262 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
264 if (!noPhiCutout) glVertex3f(0,0,zMin);
268 if (disableLighting) glEnable(GL_LIGHTING);
269 if (transparencyOn) glEnable(GL_BLEND);
273 beginShape(
action,TRIANGLE_STRIP);
276 for (
i = 0;
i<=NPHI;
i++) {
277 GEN_VERTEX(
pv,rMin*cosPhi,rMin*sinPhi,zMax,0.0,0.0,0,0,1);
278 GEN_VERTEX(
pv,rMax*cosPhi,rMax*sinPhi,zMax,1.0,1.0,0,0,1);
279 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
285 beginShape(
action,TRIANGLE_STRIP);
288 for (
i = 0;
i<=NPHI;
i++) {
289 GEN_VERTEX(
pv,rMin*cosPhi,rMin*sinPhi,zMin,0.0,0.0,0,0,-1);
290 GEN_VERTEX(
pv,rMax*cosPhi,rMax*sinPhi,zMin,1.0,1.0,0,0,-1);
291 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
296 if (disableLighting) glDisable(GL_LIGHTING);
297 if (transparencyOn) glDisable(GL_BLEND);
298 glBegin(GL_LINE_STRIP);
301 if (!noPhiCutout) glVertex3f(rMin*cosPhi,rMin*sinPhi,zMax);
302 for (
i = 0;
i<=NPHI;
i++) {
303 glVertex3f(rMax*cosPhi,rMax*sinPhi,zMax);
304 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
306 if (!noPhiCutout) glVertex3f(rMin*cosPhi1,rMin*sinPhi1,zMax);
309 glBegin(GL_LINE_STRIP);
312 for (
i = 0;
i<=NPHI;
i++) {
313 glVertex3f(rMin*cosPhi,rMin*sinPhi,zMax);
314 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
318 glBegin(GL_LINE_STRIP);
321 if (!noPhiCutout) glVertex3f(rMin*cosPhi,rMin*sinPhi,zMin);
322 for (
i = 0;
i<=NPHI;
i++) {
323 glVertex3f(rMax*cosPhi,rMax*sinPhi,zMin);
324 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
326 if (!noPhiCutout) glVertex3f(rMin*cosPhi1,rMin*sinPhi1,zMin);
329 glBegin(GL_LINE_STRIP);
332 for (
i = 0;
i<=NPHI;
i++) {
333 glVertex3f(rMin*cosPhi,rMin*sinPhi,zMin);
334 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
338 if (disableLighting) glEnable(GL_LIGHTING);
339 if (transparencyOn) glEnable(GL_BLEND);
344 if (state&&state->isElementEnabled(SoGLCacheContextElement::getClassStackIndex())) {
346 SoGLCacheContextElement::shouldAutoCache(state, SoGLCacheContextElement::DO_AUTO_CACHE);
347 #if ((COIN_MAJOR_VERSION>=3)||((COIN_MAJOR_VERSION==2)&&(COIN_MINOR_VERSION>=5)))
348 SoGLCacheContextElement::incNumShapes(state);
363 -
pDz.getValue(),
pDz.getValue(),
375 SoCoordinate3 *theCoordinates = (SoCoordinate3 *) (
sep->getChild(0));
376 SoNormal *theNormals = (SoNormal *) (
sep->getChild(1));
377 SoNormalBinding *theNormalBinding = (SoNormalBinding *) (
sep->getChild(2));
378 SoIndexedFaceSet *theFaceSet = (SoIndexedFaceSet *) (
sep->getChild(3));
381 const int NPHI=96, NPOINTS=2*(2*NPHI+2), NFACES=4*NPHI+2, NINDICES = NFACES*5;
382 float points[NPOINTS][3],normals[NFACES][3];
386 static int32_t
indices[NINDICES];
390 double phi, pp, DeltaPhi;
399 for (
i = 0;
i< NPHI;
i++) {
408 for (
i=0;
i<NPHI;
i++) {
409 indices[5*1*NPHI + 5*
i+0] = 2*NPHI+2 + 2*
i+0;
410 indices[5*1*NPHI + 5*
i+1] = 2*NPHI+2 + 2*
i+1;
411 indices[5*1*NPHI + 5*
i+2] = 2*NPHI+2 + 2*
i+3;
412 indices[5*1*NPHI + 5*
i+3] = 2*NPHI+2 + 2*
i+2;
413 indices[5*1*NPHI + 5*
i+4] = SO_END_FACE_INDEX;
416 for (
i=0;
i<NPHI;
i++) {
419 indices[5*2*NPHI + 5*
i+2] = NPOINTS - (2*
i+4);
420 indices[5*2*NPHI + 5*
i+3] = NPOINTS - (2*
i+2);
421 indices[5*2*NPHI + 5*
i+4] = SO_END_FACE_INDEX;
424 for (
i=0;
i<NPHI;
i++) {
426 indices[5*3*NPHI + 5*
i+1] = NPOINTS - (2*
i+1);
427 indices[5*3*NPHI + 5*
i+2] = NPOINTS - (2*
i+3);
429 indices[5*3*NPHI + 5*
i+4] = SO_END_FACE_INDEX;
433 indices[5*4*NPHI +1] = 2*NPHI+1;
434 indices[5*4*NPHI +2] = 2*NPHI+3;
435 indices[5*4*NPHI +3] = 2*NPHI+2;
436 indices[5*4*NPHI +4] = SO_END_FACE_INDEX;
439 indices[5*4*NPHI +5 +1] = NPOINTS-2;
440 indices[5*4*NPHI +5 +2] = NPOINTS-1;
442 indices[5*4*NPHI +5 +4] = SO_END_FACE_INDEX;
448 indices[5*4*NPHI +1] = 2*NPHI+1;
449 indices[5*4*NPHI +2] = 2*NPHI+3;
450 indices[5*4*NPHI +3] = 2*NPHI+2;
451 indices[5*4*NPHI +4] = SO_END_FACE_INDEX;
454 indices[5*4*NPHI +5 +1] = NPOINTS-2;
455 indices[5*4*NPHI +5 +2] = NPOINTS-1;
457 indices[5*4*NPHI +5 +4] = SO_END_FACE_INDEX;
461 indices[5*4*NPHI +0] = SO_END_FACE_INDEX;
462 indices[5*4*NPHI +1] = SO_END_FACE_INDEX;
463 indices[5*4*NPHI +2] = SO_END_FACE_INDEX;
464 indices[5*4*NPHI +3] = SO_END_FACE_INDEX;
465 indices[5*4*NPHI +4] = SO_END_FACE_INDEX;
467 indices[5*4*NPHI +5 +0] = SO_END_FACE_INDEX;
468 indices[5*4*NPHI +5 +1] = SO_END_FACE_INDEX;
469 indices[5*4*NPHI +5 +2] = SO_END_FACE_INDEX;
470 indices[5*4*NPHI +5 +3] = SO_END_FACE_INDEX;
471 indices[5*4*NPHI +5 +4] = SO_END_FACE_INDEX;
475 for (
i = 0;
i<=NPHI;
i++) {
484 pp =
phi+DeltaPhi/2.0;
486 normals[
i][0] =
FCOS(pp);
487 normals[
i][1] =
FSIN(pp);
494 for (
i = 0;
i<=NPHI;
i++) {
501 pp =
phi-DeltaPhi/2.0;
503 normals[NPHI+
i][0] = -
FCOS(pp);
504 normals[NPHI+
i][1] = -
FSIN(pp);
505 normals[NPHI+
i][2] = 0;
510 for (
i=0;
i<NPHI;
i++) {
511 normals[2*NPHI+
i][0]=normals[2*NPHI+
i][1]=0;
512 normals[2*NPHI+
i][2]= 1.0;
515 for (
i=0;
i<NPHI;
i++) {
516 normals[3*NPHI+
i][0]=normals[3*NPHI+
i][1]=0;
517 normals[3*NPHI+
i][2]= -1.0;
521 normals[4*NPHI+0][0]=
FSIN(
phi);
522 normals[4*NPHI+0][1]= -
FCOS(
phi);
523 normals[4*NPHI+0][2]=0;
527 normals[4*NPHI+1][0]= -
FSIN(
phi);
528 normals[4*NPHI+1][1]= +
FCOS(
phi);
529 normals[4*NPHI+1][2]=0;
532 for (
int ni=0;ni<NINDICES;ni++) theFaceSet->coordIndex.set1Value(ni,
indices[ni]);
533 for (
int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
534 theNormalBinding->value=SoNormalBinding::PER_FACE;
546 SoSeparator *
sep =
new SoSeparator();
547 SoCoordinate3 *theCoordinates =
new SoCoordinate3();
548 SoNormal *theNormals =
new SoNormal();
549 SoNormalBinding *theNormalBinding =
new SoNormalBinding();
550 SoIndexedFaceSet *theFaceSet =
new SoIndexedFaceSet();
554 sep->addChild(theCoordinates);
555 sep->addChild(theNormals);
556 sep->addChild(theNormalBinding);
557 sep->addChild(theFaceSet);