19 #include <Inventor/SbBox.h>
20 #include <Inventor/actions/SoAction.h>
21 #include <Inventor/misc/SoChildList.h>
22 #include <Inventor/nodes/SoSeparator.h>
23 #include <Inventor/nodes/SoIndexedFaceSet.h>
24 #include <Inventor/nodes/SoNormal.h>
25 #include <Inventor/nodes/SoCoordinate3.h>
26 #include <Inventor/nodes/SoNormalBinding.h>
27 #include <Inventor/SoPrimitiveVertex.h>
28 #include <Inventor/elements/SoTextureCoordinateElement.h>
29 #include <Inventor/elements/SoGLCacheContextElement.h>
37 SO_NODE_CONSTRUCTOR(
SoLAr);
40 SO_NODE_ADD_FIELD(fRmin, (0.0));
41 SO_NODE_ADD_FIELD(fRmax, (0.0));
42 SO_NODE_ADD_FIELD(fDz, (0.0));
43 SO_NODE_ADD_FIELD(fSPhi, (0.0));
44 SO_NODE_ADD_FIELD(fDPhi, ((
float)(2*
M_PI)));
45 SO_NODE_ADD_FIELD(smoothDraw, (
TRUE));
46 SO_NODE_ADD_FIELD(pOverrideNPhi, (0));
47 SO_NODE_ADD_FIELD(alternateRep, (NULL));
48 m_children = std::make_unique<SoChildList>(
this);
50 float rMinDef[]={10.0, 15.0, 10.0};
51 float rMaxDef[]={11.0, 17.0, 12.0};
52 float zDef []={-10.0, 0.0, 10.0};
54 fRmin.setValues(0,2,rMinDef);
55 fRmax.setValues(0,2,rMaxDef);
56 fDz.setValues(0,2,zDef);
57 setNodeType(EXTENSION);
64 [[maybe_unused]]
static const bool didInit = [&]() {
65 SO_NODE_INIT_CLASS(
SoLAr,SoShape,
"Shape");
77 SoState *state =
action->getState();
83 SbBool useTexFunction=
85 SoTextureCoordinateElement::FUNCTION);
90 const SoTextureCoordinateElement *tce = NULL;
93 tce = SoTextureCoordinateElement::getInstance(state);
98 SbVec3f point, normal;
102 #define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \
103 point.setValue((float)(x),(float)(y),(float)(z)); \
104 normal.setValue((float)(nx),(float)(ny),(float)(nz)); \
105 if (useTexFunction) { \
106 texCoord=tce->get(point,normal); \
108 texCoord[0]=(float)(s); \
109 texCoord[1]=(float)(t); \
111 pv.setPoint(point); \
112 pv.setNormal(normal); \
113 pv.setTextureCoords(texCoord); \
122 int nSeg =
fRmin.getNum()-1;
127 for (
int p=0;
p<nSeg;
p++) {
135 double zMin =
fDz[
p];
136 double zMax=
fDz[
p+1];
145 double cosPhi1 =
cos(phi1);
146 double sinPhi1 =
sin(phi1);
159 double dR =rMax2-rMax1;
160 double dZ =zMax-zMin;
161 double cosTheta = -dR/sqrt(dR*dR+dZ*dZ);
162 double sinTheta = dZ/sqrt(dR*dR+dZ*dZ);
164 beginShape(
action,TRIANGLE_STRIP);
167 for (
i = 0;
i<=NPHI;
i++) {
168 GEN_VERTEX(
pv,rMax2*cosPhi,rMax2*sinPhi,zMax,0.0,0.0,sinTheta*cosPhi,sinTheta*sinPhi,cosTheta);
169 GEN_VERTEX(
pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,sinTheta*cosPhi,sinTheta*sinPhi,cosTheta);
170 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
179 beginShape(
action,TRIANGLE_STRIP);
183 double dR =rMin2-rMin1;
184 double dZ =zMax-zMin;
185 double cosTheta = -dR/sqrt(dR*dR+dZ*dZ);
186 double sinTheta = dZ/sqrt(dR*dR+dZ*dZ);
188 for (
i = 0;
i<=NPHI;
i++) {
189 GEN_VERTEX(
pv,rMin2*cosPhi,rMin2*sinPhi,zMax,0.0,0.0,-cosPhi*sinTheta,-sinPhi*sinTheta,-cosTheta);
190 GEN_VERTEX(
pv,rMin1*cosPhi,rMin1*sinPhi,zMin,1.0,1.0,-cosPhi*sinTheta,-sinPhi*sinTheta,-cosTheta);
191 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
202 beginShape(
action,TRIANGLE_STRIP);
205 GEN_VERTEX(
pv,rMax2*cosPhi,rMax2*sinPhi,zMax,0.0,0.0,sinPhi,-cosPhi,0);
206 GEN_VERTEX(
pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,sinPhi,-cosPhi,0);
207 GEN_VERTEX(
pv,rMin2*cosPhi,rMin2*sinPhi,zMax,1.0,0.0,sinPhi,-cosPhi,0);
208 GEN_VERTEX(
pv,rMin1*cosPhi,rMin1*sinPhi,zMin,0.0,1.0,sinPhi,-cosPhi,0);
213 beginShape(
action,TRIANGLE_STRIP);
216 GEN_VERTEX(
pv,rMax2*cosPhi,rMax2*sinPhi, zMax,0.0,0.0,-sinPhi,+cosPhi,0);
217 GEN_VERTEX(
pv,rMax1*cosPhi,rMax1*sinPhi, zMin,1.0,1.0,-sinPhi,+cosPhi,0);
218 GEN_VERTEX(
pv,rMin2*cosPhi,rMin2*sinPhi, zMax,1.0,0.0,-sinPhi,+cosPhi,0);
219 GEN_VERTEX(
pv,rMin1*cosPhi,rMin1*sinPhi, zMin,0.0,1.0,-sinPhi,+cosPhi,0);
227 beginShape(
action,TRIANGLE_STRIP);
230 for (
i = 0;
i<=NPHI;
i++) {
231 GEN_VERTEX(
pv,rMin2*cosPhi,rMin2*sinPhi,zMax,0.0,0.0,0,0,1);
232 GEN_VERTEX(
pv,rMax2*cosPhi,rMax2*sinPhi,zMax,1.0,1.0,0,0,1);
233 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
241 beginShape(
action,TRIANGLE_STRIP);
244 for (
i = 0;
i<=NPHI;
i++) {
245 GEN_VERTEX(
pv,rMin1*cosPhi,rMin1*sinPhi,zMin,0.0,0.0,0,0,-1);
246 GEN_VERTEX(
pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,0,0,-1);
247 inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
253 if (state&&state->isElementEnabled(SoGLCacheContextElement::getClassStackIndex())) {
255 SoGLCacheContextElement::shouldAutoCache(state, SoGLCacheContextElement::DO_AUTO_CACHE);
256 #if ((COIN_MAJOR_VERSION>=3)||((COIN_MAJOR_VERSION==2)&&(COIN_MINOR_VERSION>=5)))
257 SoGLCacheContextElement::incNumShapes(state);
270 if (
fRmax.getNum()< 2)
return;
271 if (
fRmin.getNum()< 2)
return;
272 if (
fDz.getNum() < 2)
return;
274 double MinMin =
fRmin[0];
275 double MaxMax =
fRmax[0];
277 double ZMin =
fDz[0];
278 double ZMax =
fDz[0];
281 for (
int i=1;
i<
fRmin.getNum();
i++) {
285 for (
int i=1;
i<
fRmax.getNum();
i++) {
289 for (
int i=1;
i<
fDz.getNum();
i++) {
314 SoCoordinate3 *theCoordinates = (SoCoordinate3 *) (
sep->getChild(0));
315 SoNormal *theNormals = (SoNormal *) (
sep->getChild(1));
316 SoNormalBinding *theNormalBinding = (SoNormalBinding *) (
sep->getChild(2));
317 SoIndexedFaceSet *theFaceSet = (SoIndexedFaceSet *) (
sep->getChild(3));
319 const int NPHI=96, NPOINTS=2*(2*NPHI+2), NFACES=4*NPHI+2, NINDICES = NFACES*5;
320 float points[NPOINTS][3], normals[NFACES][3];
324 static int32_t
indices[NINDICES];
327 double phi, pp, DeltaPhi;
336 for (
i = 0;
i< NPHI;
i++) {
345 for (
i=0;
i<NPHI;
i++) {
346 indices[5*1*NPHI + 5*
i+0] = 2*NPHI+2 + 2*
i+0;
347 indices[5*1*NPHI + 5*
i+1] = 2*NPHI+2 + 2*
i+1;
348 indices[5*1*NPHI + 5*
i+2] = 2*NPHI+2 + 2*
i+3;
349 indices[5*1*NPHI + 5*
i+3] = 2*NPHI+2 + 2*
i+2;
350 indices[5*1*NPHI + 5*
i+4] = SO_END_FACE_INDEX;
353 for (
i=0;
i<NPHI;
i++) {
356 indices[5*2*NPHI + 5*
i+2] = NPOINTS - (2*
i+4);
357 indices[5*2*NPHI + 5*
i+3] = NPOINTS - (2*
i+2);
358 indices[5*2*NPHI + 5*
i+4] = SO_END_FACE_INDEX;
361 for (
i=0;
i<NPHI;
i++) {
363 indices[5*3*NPHI + 5*
i+1] = NPOINTS - (2*
i+1);
364 indices[5*3*NPHI + 5*
i+2] = NPOINTS - (2*
i+3);
366 indices[5*3*NPHI + 5*
i+4] = SO_END_FACE_INDEX;
370 indices[5*4*NPHI +1] = 2*NPHI+1;
371 indices[5*4*NPHI +2] = 2*NPHI+3;
372 indices[5*4*NPHI +3] = 2*NPHI+2;
373 indices[5*4*NPHI +4] = SO_END_FACE_INDEX;
376 indices[5*4*NPHI +5 +1] = NPOINTS-2;
377 indices[5*4*NPHI +5 +2] = NPOINTS-1;
379 indices[5*4*NPHI +5 +4] = SO_END_FACE_INDEX;
385 t =
FATAN((fRmax2.getValue()-fRmax1.getValue())/(2*
fDz.getValue()));
388 for (
i = 0;
i<=NPHI;
i++) {
395 pp =
phi+DeltaPhi/2.0;
405 t =
FATAN((fRmin2.getValue()-fRmin1.getValue())/(2*
fDz.getValue()));
408 for (
i = 0;
i<=NPHI;
i++) {
415 pp =
phi-DeltaPhi/2.0;
417 normals[NPHI+
i][0] = -
ct*
FCOS(pp);
418 normals[NPHI+
i][1] = -
ct*
FSIN(pp);
419 normals[NPHI+
i][2] = st;
424 for (
i=0;
i<NPHI;
i++) {
425 normals[2*NPHI+
i][0]=normals[2*NPHI+
i][1]=0;
426 normals[2*NPHI+
i][2]= 1.0;
429 for (
i=0;
i<NPHI;
i++) {
430 normals[3*NPHI+
i][0]=normals[3*NPHI+
i][1]=0;
431 normals[3*NPHI+
i][2]= -1.0;
435 normals[4*NPHI+0][0]=
FSIN(
phi);
436 normals[4*NPHI+0][1]= -
FCOS(
phi);
437 normals[4*NPHI+0][2]= 0;
441 normals[4*NPHI+1][0]= -
FSIN(
phi);
442 normals[4*NPHI+1][1]= +
FCOS(
phi);
443 normals[4*NPHI+1][2]=0;
446 theFaceSet->coordIndex.setValues(0,NINDICES,
indices);
450 for (
int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
451 theNormalBinding->value=SoNormalBinding::PER_FACE;
454 for (
int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
455 theNormalBinding->value=SoNormalBinding::PER_FACE;
472 SoSeparator *
sep =
new SoSeparator();
473 SoCoordinate3 *theCoordinates =
new SoCoordinate3();
474 SoNormal *theNormals =
new SoNormal();
475 SoNormalBinding *theNormalBinding =
new SoNormalBinding();
476 SoIndexedFaceSet *theFaceSet =
new SoIndexedFaceSet();
480 sep->addChild(theCoordinates);
481 sep->addChild(theNormals);
482 sep->addChild(theNormalBinding);
483 sep->addChild(theFaceSet);