20 #include <Inventor/SbBox.h>
21 #include <Inventor/actions/SoAction.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>
43 SO_NODE_ADD_FIELD(fRmin, (0.0));
44 SO_NODE_ADD_FIELD(fRmax, (0.0));
45 SO_NODE_ADD_FIELD(fDz, (0.0));
46 SO_NODE_ADD_FIELD(fSPhi, (0.0));
47 SO_NODE_ADD_FIELD(fDPhi, ((
float)(2*
M_PI)));
48 SO_NODE_ADD_FIELD(smoothDraw, (
TRUE));
49 SO_NODE_ADD_FIELD(pOverrideNPhi, (0));
50 SO_NODE_ADD_FIELD(alternateRep, (NULL));
51 SO_NODE_ADD_FIELD(drawEdgeLines, (
false));
53 m_children = std::make_unique<SoChildList>(
this);
55 float rMinDef[]={10.0, 15.0, 10.0};
56 float rMaxDef[]={11.0, 17.0, 12.0};
57 float zDef []={-10.0, 0.0, 10.0};
59 fRmin.setValues(0,2,rMinDef);
60 fRmax.setValues(0,2,rMaxDef);
61 fDz.setValues(0,2,zDef);
62 setNodeType(EXTENSION);
69 [[maybe_unused]]
static const bool didInit = [&]() {
70 SO_NODE_INIT_CLASS(
SoPcons,SoShape,
"Shape");
81 SoState *state =
action->getState();
87 SbBool useTexFunction=
89 SoTextureCoordinateElement::FUNCTION);
94 const SoTextureCoordinateElement *tce = NULL;
97 tce = SoTextureCoordinateElement::getInstance(state);
102 SbVec3f point, normal;
106 #define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \
107 point.setValue((float)(x),(float)(y),(float)(z)); \
108 normal.setValue((float)(nx),(float)(ny),(float)(nz)); \
109 if (useTexFunction) { \
110 texCoord=tce->get(point,normal); \
112 texCoord[0]=(float)(s); \
113 texCoord[1]=(float)(t); \
115 pv.setPoint(point); \
116 pv.setNormal(normal); \
117 pv.setTextureCoords(texCoord); \
126 int nSeg =
fRmin.getNum()-1;
131 for (
int p=0;
p<nSeg;
p++) {
139 double zMin =
fDz[
p];
140 double zMax=
fDz[
p+1];
149 double cosPhi1 =
cos(phi1);
150 double sinPhi1 =
sin(phi1);
158 const bool noPhiCutout=fabs(
fDPhi.getValue())==0.F || fabs(fabs(
fDPhi.getValue())-2.0*
M_PI)<0.01;
159 const bool disableLighting(glIsEnabled(GL_LIGHTING));
160 const bool transparencyOn(glIsEnabled(GL_BLEND));
168 double dR =rMax2-rMax1;
169 double dZ =zMax-zMin;
170 double cosTheta = -dR/sqrt(dR*dR+dZ*dZ);
171 double sinTheta = dZ/sqrt(dR*dR+dZ*dZ);
173 beginShape(
action,TRIANGLE_STRIP);
176 for (
i = 0;
i<=NPHI;
i++) {
177 GEN_VERTEX(
pv,rMax2*cosPhi,rMax2*sinPhi,zMax,0.0,0.0,sinTheta*cosPhi,sinTheta*sinPhi,cosTheta);
178 GEN_VERTEX(
pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,sinTheta*cosPhi,sinTheta*sinPhi,cosTheta);
179 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
184 if (disableLighting) glDisable(GL_LIGHTING);
185 if (transparencyOn) glDisable(GL_BLEND);
186 glBegin(GL_LINE_STRIP);
189 if (!noPhiCutout &&
p==0) glVertex3f(rMin1*cosPhi,rMin1*sinPhi,zMin);
190 for (
i = 0;
i<=NPHI;
i++) {
191 glVertex3f(rMax1*cosPhi,rMax1*sinPhi,zMin);
192 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
194 if (!noPhiCutout &&
p==0) glVertex3f(rMin1*cosPhi1,rMin1*sinPhi1,zMin);
196 if (disableLighting) glEnable(GL_LIGHTING);
197 if (transparencyOn) glEnable(GL_BLEND);
206 beginShape(
action,TRIANGLE_STRIP);
212 cosTheta = -dR/sqrt(dR*dR+dZ*dZ);
213 sinTheta = dZ/sqrt(dR*dR+dZ*dZ);
215 for (
i = 0;
i<=NPHI;
i++) {
216 GEN_VERTEX(
pv,rMin2*cosPhi,rMin2*sinPhi,zMax,0.0,0.0,-cosPhi*sinTheta,-sinPhi*sinTheta,-cosTheta);
217 GEN_VERTEX(
pv,rMin1*cosPhi,rMin1*sinPhi,zMin,1.0,1.0,-cosPhi*sinTheta,-sinPhi*sinTheta,-cosTheta);
218 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
223 if (disableLighting) glDisable(GL_LIGHTING);
224 if (transparencyOn) glDisable(GL_BLEND);
225 glBegin(GL_LINE_STRIP);
229 for (
i = 0;
i<=NPHI;
i++) {
230 glVertex3f(rMin1*cosPhi,rMin1*sinPhi,zMin);
231 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
235 if (disableLighting) glEnable(GL_LIGHTING);
236 if (transparencyOn) glEnable(GL_BLEND);
246 beginShape(
action,TRIANGLE_STRIP);
249 GEN_VERTEX(
pv,rMax2*cosPhi,rMax2*sinPhi,zMax,0.0,0.0,sinPhi,-cosPhi,0);
250 GEN_VERTEX(
pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,sinPhi,-cosPhi,0);
251 GEN_VERTEX(
pv,rMin2*cosPhi,rMin2*sinPhi,zMax,1.0,0.0,sinPhi,-cosPhi,0);
252 GEN_VERTEX(
pv,rMin1*cosPhi,rMin1*sinPhi,zMin,0.0,1.0,sinPhi,-cosPhi,0);
257 beginShape(
action,TRIANGLE_STRIP);
260 GEN_VERTEX(
pv,rMax2*cosPhi,rMax2*sinPhi, zMax,0.0,0.0,-sinPhi,+cosPhi,0);
261 GEN_VERTEX(
pv,rMax1*cosPhi,rMax1*sinPhi, zMin,1.0,1.0,-sinPhi,+cosPhi,0);
262 GEN_VERTEX(
pv,rMin2*cosPhi,rMin2*sinPhi, zMax,1.0,0.0,-sinPhi,+cosPhi,0);
263 GEN_VERTEX(
pv,rMin1*cosPhi,rMin1*sinPhi, zMin,0.0,1.0,-sinPhi,+cosPhi,0);
267 if (disableLighting) glDisable(GL_LIGHTING);
268 if (transparencyOn) glDisable(GL_BLEND);
271 glVertex3f(rMax2*cosPhi0,rMax2*sinPhi0, zMax);
272 glVertex3f(rMax1*cosPhi0,rMax1*sinPhi0, zMin);
273 glVertex3f(rMin2*cosPhi0,rMin2*sinPhi0, zMax);
274 glVertex3f(rMin1*cosPhi0,rMin1*sinPhi0, zMin);
275 glVertex3f(rMax2*cosPhi1,rMax2*sinPhi1, zMax);
276 glVertex3f(rMax1*cosPhi1,rMax1*sinPhi1, zMin);
277 glVertex3f(rMin2*cosPhi1,rMin2*sinPhi1, zMax);
278 glVertex3f(rMin1*cosPhi1,rMin1*sinPhi1, zMin);
280 if (disableLighting) glEnable(GL_LIGHTING);
281 if (transparencyOn) glEnable(GL_BLEND);
290 beginShape(
action,TRIANGLE_STRIP);
293 for (
i = 0;
i<=NPHI;
i++) {
294 GEN_VERTEX(
pv,rMin2*cosPhi,rMin2*sinPhi,zMax,0.0,0.0,0,0,1);
295 GEN_VERTEX(
pv,rMax2*cosPhi,rMax2*sinPhi,zMax,1.0,1.0,0,0,1);
296 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
301 if (disableLighting) glDisable(GL_LIGHTING);
302 if (transparencyOn) glDisable(GL_BLEND);
303 glBegin(GL_LINE_STRIP);
306 if (!noPhiCutout) glVertex3f(rMin1*cosPhi,rMin1*sinPhi,zMax);
307 for (
i = 0;
i<=NPHI;
i++) {
308 glVertex3f(rMax1*cosPhi,rMax1*sinPhi,zMax);
309 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
311 if (!noPhiCutout) glVertex3f(rMin1*cosPhi1,rMin1*sinPhi1,zMax);
313 if (disableLighting) glEnable(GL_LIGHTING);
314 if (transparencyOn) glEnable(GL_BLEND);
322 beginShape(
action,TRIANGLE_STRIP);
325 for (
i = 0;
i<=NPHI;
i++) {
326 GEN_VERTEX(
pv,rMin1*cosPhi,rMin1*sinPhi,zMin,0.0,0.0,0,0,-1);
327 GEN_VERTEX(
pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,0,0,-1);
328 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
334 if (state&&state->isElementEnabled(SoGLCacheContextElement::getClassStackIndex())) {
336 SoGLCacheContextElement::shouldAutoCache(state, SoGLCacheContextElement::DO_AUTO_CACHE);
337 #if ((COIN_MAJOR_VERSION>=3)||((COIN_MAJOR_VERSION==2)&&(COIN_MINOR_VERSION>=5)))
338 SoGLCacheContextElement::incNumShapes(state);
351 if (
fRmax.getNum()< 2)
return;
352 if (
fRmin.getNum()< 2)
return;
353 if (
fDz.getNum() < 2)
return;
355 double MinMin =
fRmin[0];
356 double MaxMax =
fRmax[0];
358 double ZMin =
fDz[0];
359 double ZMax =
fDz[0];
362 for (
int i=1;
i<
fRmin.getNum();++
i) {
366 for (
int i=1;
i<
fRmax.getNum();++
i) {
370 for (
int i=1;
i<
fDz.getNum();++
i) {
395 SoCoordinate3 *theCoordinates = (SoCoordinate3 *) (
sep->getChild(0));
396 SoNormal *theNormals = (SoNormal *) (
sep->getChild(1));
397 SoNormalBinding *theNormalBinding = (SoNormalBinding *) (
sep->getChild(2));
398 SoIndexedFaceSet *theFaceSet = (SoIndexedFaceSet *) (
sep->getChild(3));
400 const int NPHI=96, NPOINTS=2*(2*NPHI+2), NFACES=4*NPHI+2, NINDICES = NFACES*5;
401 float points[NPOINTS][3], normals[NFACES][3];
405 static int32_t
indices[NINDICES];
408 double phi, pp, DeltaPhi;
421 for (
i = 0;
i< NPHI;
i++) {
430 for (
i=0;
i<NPHI;
i++) {
431 indices[5*1*NPHI + 5*
i+0] = 2*NPHI+2 + 2*
i+0;
432 indices[5*1*NPHI + 5*
i+1] = 2*NPHI+2 + 2*
i+1;
433 indices[5*1*NPHI + 5*
i+2] = 2*NPHI+2 + 2*
i+3;
434 indices[5*1*NPHI + 5*
i+3] = 2*NPHI+2 + 2*
i+2;
435 indices[5*1*NPHI + 5*
i+4] = SO_END_FACE_INDEX;
438 for (
i=0;
i<NPHI;
i++) {
441 indices[5*2*NPHI + 5*
i+2] = NPOINTS - (2*
i+4);
442 indices[5*2*NPHI + 5*
i+3] = NPOINTS - (2*
i+2);
443 indices[5*2*NPHI + 5*
i+4] = SO_END_FACE_INDEX;
446 for (
i=0;
i<NPHI;
i++) {
448 indices[5*3*NPHI + 5*
i+1] = NPOINTS - (2*
i+1);
449 indices[5*3*NPHI + 5*
i+2] = NPOINTS - (2*
i+3);
451 indices[5*3*NPHI + 5*
i+4] = SO_END_FACE_INDEX;
455 indices[5*4*NPHI +1] = 2*NPHI+1;
456 indices[5*4*NPHI +2] = 2*NPHI+3;
457 indices[5*4*NPHI +3] = 2*NPHI+2;
458 indices[5*4*NPHI +4] = SO_END_FACE_INDEX;
461 indices[5*4*NPHI +5 +1] = NPOINTS-2;
462 indices[5*4*NPHI +5 +2] = NPOINTS-1;
464 indices[5*4*NPHI +5 +4] = SO_END_FACE_INDEX;
470 t =
FATAN((fRmax2.getValue()-fRmax1.getValue())/(2*
fDz.getValue()));
473 for (
i = 0;
i<=NPHI;
i++) {
480 pp =
phi+DeltaPhi/2.0;
490 t =
FATAN((fRmin2.getValue()-fRmin1.getValue())/(2*
fDz.getValue()));
493 for (
i = 0;
i<=NPHI;
i++) {
500 pp =
phi-DeltaPhi/2.0;
502 normals[NPHI+
i][0] = -
ct*
FCOS(pp);
503 normals[NPHI+
i][1] = -
ct*
FSIN(pp);
504 normals[NPHI+
i][2] = st;
509 for (
i=0;
i<NPHI;
i++) {
510 normals[2*NPHI+
i][0]=normals[2*NPHI+
i][1]=0;
511 normals[2*NPHI+
i][2]= 1.0;
514 for (
i=0;
i<NPHI;
i++) {
515 normals[3*NPHI+
i][0]=normals[3*NPHI+
i][1]=0;
516 normals[3*NPHI+
i][2]= -1.0;
520 normals[4*NPHI+0][0]=
FSIN(
phi);
521 normals[4*NPHI+0][1]= -
FCOS(
phi);
522 normals[4*NPHI+0][2]= 0;
526 normals[4*NPHI+1][0]= -
FSIN(
phi);
527 normals[4*NPHI+1][1]= +
FCOS(
phi);
528 normals[4*NPHI+1][2]=0;
531 theFaceSet->coordIndex.setValues(0,NINDICES,
indices);
535 for (
int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
536 theNormalBinding->value=SoNormalBinding::PER_FACE;
539 for (
int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
540 theNormalBinding->value=SoNormalBinding::PER_FACE;
557 SoSeparator *
sep =
new SoSeparator();
558 SoCoordinate3 *theCoordinates =
new SoCoordinate3();
559 SoNormal *theNormals =
new SoNormal();
560 SoNormalBinding *theNormalBinding =
new SoNormalBinding();
561 SoIndexedFaceSet *theFaceSet =
new SoIndexedFaceSet();
565 sep->addChild(theCoordinates);
566 sep->addChild(theNormals);
567 sep->addChild(theNormalBinding);
568 sep->addChild(theFaceSet);
601 SoPrimitiveVertex
pv;
604 std::vector<SoPrimitiveVertex> vls;
607 std::vector<SoPrimitiveVertex> fls;
615 SbVec3f point, normal;
619 #define N_GEN_VERTEX(ls, pv,x,y,z,s,t,nx,ny,nz) \
620 point.setValue((float)(x),(float)(y),(float)(z)); \
621 normal.setValue((float)(nx),(float)(ny),(float)(nz)); \
622 texCoord[0]=(float)(s); \
623 texCoord[1]=(float)(t); \
624 pv.setPoint(point); \
625 pv.setNormal(normal); \
626 pv.setTextureCoords(texCoord); \
634 int nSeg =
fRmin.getNum()-1;
639 for (
int p=0;
p<nSeg;
p++) {
647 double zMin =
fDz[
p];
648 double zMax=
fDz[
p+1];
655 double cosPhi1 =
cos(phi1);
656 double sinPhi1 =
sin(phi1);
664 const bool noPhiCutout=fabs(
fDPhi.getValue())==0.F || fabs(fabs(
fDPhi.getValue())-2.0*
M_PI)<0.01;
669 double dR =rMax2-rMax1;
670 double dZ =zMax-zMin;
671 double cosTheta = -dR/sqrt(dR*dR+dZ*dZ);
672 double sinTheta = dZ/sqrt(dR*dR+dZ*dZ);
676 for (
i = 0;
i<=NPHI;
i++) {
677 N_GEN_VERTEX(vls,
pv,rMax2*cosPhi,rMax2*sinPhi,zMax,0.0,0.0,sinTheta*cosPhi,sinTheta*sinPhi,cosTheta);
678 N_GEN_VERTEX(vls,
pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,sinTheta*cosPhi,sinTheta*sinPhi,cosTheta);
679 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
682 for(
i = 0;
i < ((
int)vls.size() - 2);
i += 2){
683 fls.push_back(vls[
i + 0]);
684 fls.push_back(vls[
i + 1]);
685 fls.push_back(vls[
i + 3]);
686 fls.push_back(vls[
i + 2]);
698 cosTheta = -dR/sqrt(dR*dR+dZ*dZ);
699 sinTheta = dZ/sqrt(dR*dR+dZ*dZ);
701 for (
i = 0;
i<=NPHI;
i++) {
702 N_GEN_VERTEX(vls,
pv,rMin2*cosPhi,rMin2*sinPhi,zMax,0.0,0.0,-cosPhi*sinTheta,-sinPhi*sinTheta,-cosTheta);
703 N_GEN_VERTEX(vls,
pv,rMin1*cosPhi,rMin1*sinPhi,zMin,1.0,1.0,-cosPhi*sinTheta,-sinPhi*sinTheta,-cosTheta);
704 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
706 for(
i = 0;
i < ((
int)vls.size() - 2);
i += 2){
707 fls.push_back(vls[
i + 1]);
708 fls.push_back(vls[
i + 0]);
709 fls.push_back(vls[
i + 2]);
710 fls.push_back(vls[
i + 3]);
721 N_GEN_VERTEX(vls,
pv,rMax2*cosPhi,rMax2*sinPhi,zMax,0.0,0.0,sinPhi,-cosPhi,0);
722 N_GEN_VERTEX(vls,
pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,sinPhi,-cosPhi,0);
723 N_GEN_VERTEX(vls,
pv,rMin2*cosPhi,rMin2*sinPhi,zMax,1.0,0.0,sinPhi,-cosPhi,0);
724 N_GEN_VERTEX(vls,
pv,rMin1*cosPhi,rMin1*sinPhi,zMin,0.0,1.0,sinPhi,-cosPhi,0);
725 fls.push_back(vls[1]);
726 fls.push_back(vls[0]);
727 fls.push_back(vls[2]);
728 fls.push_back(vls[3]);
736 N_GEN_VERTEX(vls,
pv,rMax2*cosPhi,rMax2*sinPhi, zMax,0.0,0.0,-sinPhi,+cosPhi,0);
737 N_GEN_VERTEX(vls,
pv,rMax1*cosPhi,rMax1*sinPhi, zMin,1.0,1.0,-sinPhi,+cosPhi,0);
738 N_GEN_VERTEX(vls,
pv,rMin2*cosPhi,rMin2*sinPhi, zMax,1.0,0.0,-sinPhi,+cosPhi,0);
739 N_GEN_VERTEX(vls,
pv,rMin1*cosPhi,rMin1*sinPhi, zMin,0.0,1.0,-sinPhi,+cosPhi,0);
740 fls.push_back(vls[0]);
741 fls.push_back(vls[1]);
742 fls.push_back(vls[3]);
743 fls.push_back(vls[2]);
752 for (
i = 0;
i<=NPHI;
i++) {
753 N_GEN_VERTEX(vls,
pv,rMin2*cosPhi,rMin2*sinPhi,zMax,0.0,0.0,0,0,1);
754 N_GEN_VERTEX(vls,
pv,rMax2*cosPhi,rMax2*sinPhi,zMax,1.0,1.0,0,0,1);
755 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
757 for(
i = 0;
i < ((
int)vls.size() - 2);
i += 2){
758 fls.push_back(vls[
i + 0]);
759 fls.push_back(vls[
i + 1]);
760 fls.push_back(vls[
i + 3]);
761 fls.push_back(vls[
i + 2]);
771 for (
i = 0;
i<=NPHI;
i++) {
772 N_GEN_VERTEX(vls,
pv,rMin1*cosPhi,rMin1*sinPhi,zMin,0.0,0.0,0,0,-1);
773 N_GEN_VERTEX(vls,
pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,0,0,-1);
774 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
776 for(
i = 0;
i < ((
int)vls.size() - 2);
i += 2){
777 fls.push_back(vls[
i + 1]);
778 fls.push_back(vls[
i + 0]);
779 fls.push_back(vls[
i + 2]);
780 fls.push_back(vls[
i + 3]);
792 int numFaces = fls.size() / 4;
796 SoVertexProperty *vertices =
new SoVertexProperty();
797 for(
int i = 0;
i < (
int)fls.size();
i++){
798 vertices->vertex.set1Value (
i, fls[
i].getPoint()[0],
799 fls[
i].getPoint()[1],
800 fls[
i].getPoint()[2]);
804 int* faces =
new int[5 * numFaces];
805 fprintf(
stderr,
"\nallocate Faces: %i", numFaces);
806 for(
int i = 0;
i < numFaces;
i++){
807 faces[5 *
i] = 4 *
i;
808 faces[5 *
i + 1] = 4 *
i + 1;
809 faces[5 *
i + 2] = 4 *
i + 2;
810 faces[5 *
i + 3] = 4 *
i + 3;
811 faces[5 *
i + 4] = -1;
814 SoIndexedFaceSet * faceset =
new SoIndexedFaceSet;
815 faceset->coordIndex.setValues(0, 5 * numFaces, faces);
817 faceset->vertexProperty = vertices;