17 #include <Inventor/SbBox.h>
18 #include <Inventor/actions/SoPickAction.h>
19 #include <Inventor/nodes/SoSeparator.h>
20 #include <Inventor/nodes/SoIndexedFaceSet.h>
21 #include <Inventor/nodes/SoIndexedLineSet.h>
23 #include <Inventor/SoPrimitiveVertex.h>
24 #include <Inventor/C/glue/gl.h>
25 #include <Inventor/elements/SoGLCacheContextElement.h>
30 static const int SOGENERICBOX_NPOINTS=8;
31 static const int SOGENERICBOX_NFACES=6;
33 static int sogenericbox_vindices[] =
43 static int sogenericbox_vindices_foraltrepfaces[5*SOGENERICBOX_NFACES] =
45 3, 2, 1, 0, SO_END_FACE_INDEX,
46 4, 5, 6, 7, SO_END_FACE_INDEX,
47 0, 1, 5, 4, SO_END_FACE_INDEX,
48 1, 2, 6, 5, SO_END_FACE_INDEX,
49 2, 3, 7, 6, SO_END_FACE_INDEX,
50 3, 0, 4, 7, SO_END_FACE_INDEX
53 static int sogenericbox_vindices_foraltreplines[20] =
55 0, 1, 2, 3, 0, 4, 5, 6, 7, 4, SO_END_LINE_INDEX,
56 3, 7, SO_END_LINE_INDEX,
57 6, 2, SO_END_LINE_INDEX,
58 5, 1, SO_END_LINE_INDEX,
64 [[maybe_unused]]
static const bool didInit = [&]() {
72 : m_points(0), m_normals(0)
78 setNodeType(EXTENSION);
95 SoState *state =
action->getState();
97 if (
action->getTypeId().isDerivedFrom(SoPickAction::getClassTypeId()) ) {
102 int *iptr = sogenericbox_vindices;
103 for (
int i=0;
i<SOGENERICBOX_NFACES;++
i) {
104 for (
int j = 0; j < 4; ++j) {
105 const int ivert = *iptr++;
114 int *iptr = sogenericbox_vindices;
115 for (
int i=0;
i<SOGENERICBOX_NFACES;
i++) {
116 glNormal3fv(
static_cast<const GLfloat*
>(&
m_normals[
i*3]));
117 for (
int j = 0; j < 4; j++)
118 glVertex3fv(
static_cast<const GLfloat*
>(&
m_points[(*iptr++)*3]));
126 const bool transparencyOn = glIsEnabled(GL_BLEND);
128 if (disableLighting) glDisable(GL_LIGHTING);
129 if (transparencyOn) glDisable(GL_BLEND);
130 #define trdV(i) glVertex3fv(static_cast<const GLfloat*>(&m_points[i*3]));
131 glBegin(GL_LINE_STRIP);
141 if (disableLighting) glEnable(GL_LIGHTING);
142 if (transparencyOn) glEnable(GL_BLEND);
146 if (state&&state->isElementEnabled(SoGLCacheContextElement::getClassStackIndex())) {
148 SoGLCacheContextElement::shouldAutoCache(state, SoGLCacheContextElement::DO_AUTO_CACHE);
149 #if ((COIN_MAJOR_VERSION>=3)||((COIN_MAJOR_VERSION==2)&&(COIN_MINOR_VERSION>=5)))
150 SoGLCacheContextElement::incNumShapes(state);
160 m_points =
new float[SOGENERICBOX_NPOINTS*3];
179 float xcenter,
float ycenter,
float zcenter ) {
194 double phiMin,
double phiMax,
195 double cellDepth,
double cellDistance,
196 double etasqueezefact,
double phisqueezefact )
199 if (phiMax<phiMin)
std::swap(phiMin,phiMax);
202 if (etasqueezefact!=1.0) {
203 double etashift(0.5*(1.0-etasqueezefact)*fabs(
etaMax-
etaMin));
207 if (phisqueezefact!=1.0) {
208 double phishift(0.5*(1.0-phisqueezefact)*fabs(phiMax-phiMin));
213 if (cellDistance<0) cellDistance = -cellDistance;
214 if (cellDepth<0) cellDistance =
std::max(cellDistance-cellDepth,0.0);
217 const double cpMin(
cos(phiMin));
218 const double cpMax(
cos(phiMax));
219 const double spMin(
sin(phiMin));
220 const double spMax(
sin(phiMax));
222 const double rf = cellDistance;
223 const double rb = cellDistance+cellDepth;
224 const double rfdivtantheta1(rf/tantheta1);
225 const double rbdivtantheta1(
rb/tantheta1);
226 const double rfdivtantheta2(rf/tantheta2);
227 const double rbdivtantheta2(
rb/tantheta2);
238 const double zf(
eta>0?cellDistance:-cellDistance);
239 double zb = (
zf > 0 ?
zf+cellDepth:
zf-cellDepth);
256 double phiMin,
double phiMax,
257 double cellDepth,
double cellDistance,
258 double etasqueezefact,
double phisqueezefact )
261 cellDepth, cellDistance, etasqueezefact, phisqueezefact );
266 double phiMin,
double phiMax,
267 double cellDepth,
double cellDistance,
268 double etasqueezefact,
double phisqueezefact )
271 cellDepth, cellDistance, etasqueezefact, phisqueezefact );
276 float dy1,
float dy2,
293 float dx1,
float dx2,
float dy2,
float dx3,
294 float dx4,
float alp1,
float alp2 )
299 const float TthetaCphi = tanTheta*
cos(
phi);
300 const float TthetaSphi = tanTheta*
sin(
phi);
301 const float Talp1 =
tan(alp1);
302 const float Talp2 =
tan(alp2);
336 const float dzTthetaCphi(dz*TthetaCphi);
337 const float dzTthetaSphi(dz*TthetaSphi);
353 float x1,
float y1,
float z1,
354 float x2,
float y2,
float z2,
355 float x3,
float y3,
float z3,
356 float x4,
float y4,
float z4,
357 float x5,
float y5,
float z5,
358 float x6,
float y6,
float z6,
359 float x7,
float y7,
float z7 )
378 m_normals =
new float[SOGENERICBOX_NFACES*3];
379 for (
int iface = 0; iface < SOGENERICBOX_NFACES; ++iface) {
380 const int index_v1 = sogenericbox_vindices[iface*4+0];
381 const int index_v2 = sogenericbox_vindices[iface*4+1];
382 const int index_v3 = sogenericbox_vindices[iface*4+2];
386 const double edge1X(
m_points[index_v2*3+0]-v1X), edge1Y(
m_points[index_v2*3+1]-v1Y), edge1Z(
m_points[index_v2*3+2]-v1Z);
387 const double edge2X(
m_points[index_v3*3+0]-v1X), edge2Y(
m_points[index_v3*3+1]-v1Y), edge2Z(
m_points[index_v3*3+2]-v1Z);
389 double nx(edge1Y*edge2Z-edge1Z*edge2Y);
390 double ny(edge1Z*edge2X-edge1X*edge2Z);
391 double nz(edge1X*edge2Y-edge1Y*edge2X);
392 double nl(nx*nx+ny*ny+nz*nz);
394 std::cout<<
"SoGenericBox::Error Could not calculate normal due to degenerate face edge"<<std::endl;
395 nx=1.0;ny=0.0;nz=0.0;nl=1;
401 const double s(1.0/sqrt(nl));
410 for (
int i=0;
i<SOGENERICBOX_NPOINTS;++
i) {
434 SoSeparator *
sep =
new SoSeparator;
437 SoVertexProperty *vertices =
new SoVertexProperty();
438 for (
int i=0;
i<SOGENERICBOX_NPOINTS;++
i)
440 SoIndexedFaceSet * faceset =
new SoIndexedFaceSet;
441 faceset->coordIndex.setValues(0,5*6, sogenericbox_vindices_foraltrepfaces);
442 faceset->vertexProperty = vertices;
443 sep->addChild(faceset);
452 SoIndexedLineSet * lineset =
new SoIndexedLineSet;
453 lineset->coordIndex.setValues(0,20,sogenericbox_vindices_foraltreplines);
454 lineset->vertexProperty = vertices;
455 sep->addChild(lineset);