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++) {
117 for (
int j = 0; j < 4; j++)
118 glVertex3fv((
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);
131 #define trdV(i) glVertex3fv((const GLfloat*)&m_points[i*3]);
132 glBegin(GL_LINE_STRIP);
142 if (disableLighting) glEnable(GL_LIGHTING);
143 if (transparencyOn) glEnable(GL_BLEND);
147 if (state&&state->isElementEnabled(SoGLCacheContextElement::getClassStackIndex())) {
149 SoGLCacheContextElement::shouldAutoCache(state, SoGLCacheContextElement::DO_AUTO_CACHE);
150 #if ((COIN_MAJOR_VERSION>=3)||((COIN_MAJOR_VERSION==2)&&(COIN_MINOR_VERSION>=5)))
151 SoGLCacheContextElement::incNumShapes(state);
161 m_points =
new float[SOGENERICBOX_NPOINTS*3];
180 float xcenter,
float ycenter,
float zcenter ) {
195 double phiMin,
double phiMax,
196 double cellDepth,
double cellDistance,
197 double etasqueezefact,
double phisqueezefact )
200 if (phiMax<phiMin)
std::swap(phiMin,phiMax);
203 if (etasqueezefact!=1.0) {
204 double etashift(0.5*(1.0-etasqueezefact)*fabs(
etaMax-
etaMin));
208 if (phisqueezefact!=1.0) {
209 double phishift(0.5*(1.0-phisqueezefact)*fabs(phiMax-phiMin));
214 if (cellDistance<0) cellDistance = -cellDistance;
215 if (cellDepth<0) cellDistance =
std::max(cellDistance-cellDepth,0.0);
218 const double cpMin(
cos(phiMin));
219 const double cpMax(
cos(phiMax));
220 const double spMin(
sin(phiMin));
221 const double spMax(
sin(phiMax));
223 const double rf = cellDistance;
224 const double rb = cellDistance+cellDepth;
225 const double rfdivtantheta1(rf/tantheta1);
226 const double rbdivtantheta1(
rb/tantheta1);
227 const double rfdivtantheta2(rf/tantheta2);
228 const double rbdivtantheta2(
rb/tantheta2);
239 const double zf(
eta>0?cellDistance:-cellDistance);
240 double zb = (
zf > 0 ?
zf+cellDepth:
zf-cellDepth);
257 double phiMin,
double phiMax,
258 double cellDepth,
double cellDistance,
259 double etasqueezefact,
double phisqueezefact )
262 cellDepth, cellDistance, etasqueezefact, phisqueezefact );
267 double phiMin,
double phiMax,
268 double cellDepth,
double cellDistance,
269 double etasqueezefact,
double phisqueezefact )
272 cellDepth, cellDistance, etasqueezefact, phisqueezefact );
277 float dy1,
float dy2,
294 float dx1,
float dx2,
float dy2,
float dx3,
295 float dx4,
float alp1,
float alp2 )
300 const float TthetaCphi = tanTheta*
cos(
phi);
301 const float TthetaSphi = tanTheta*
sin(
phi);
302 const float Talp1 =
tan(alp1);
303 const float Talp2 =
tan(alp2);
337 const float dzTthetaCphi(dz*TthetaCphi);
338 const float dzTthetaSphi(dz*TthetaSphi);
354 float x1,
float y1,
float z1,
355 float x2,
float y2,
float z2,
356 float x3,
float y3,
float z3,
357 float x4,
float y4,
float z4,
358 float x5,
float y5,
float z5,
359 float x6,
float y6,
float z6,
360 float x7,
float y7,
float z7 )
379 m_normals =
new float[SOGENERICBOX_NFACES*3];
380 for (
int iface = 0; iface < SOGENERICBOX_NFACES; ++iface) {
381 const int index_v1 = sogenericbox_vindices[iface*4+0];
382 const int index_v2 = sogenericbox_vindices[iface*4+1];
383 const int index_v3 = sogenericbox_vindices[iface*4+2];
387 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);
388 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);
390 double nx(edge1Y*edge2Z-edge1Z*edge2Y);
391 double ny(edge1Z*edge2X-edge1X*edge2Z);
392 double nz(edge1X*edge2Y-edge1Y*edge2X);
393 double nl(nx*nx+ny*ny+nz*nz);
395 std::cout<<
"SoGenericBox::Error Could not calculate normal due to degenerate face edge"<<std::endl;
396 nx=1.0;ny=0.0;nz=0.0;nl=1;
402 const double s(1.0/sqrt(nl));
411 for (
int i=0;
i<SOGENERICBOX_NPOINTS;++
i) {
435 SoSeparator *
sep =
new SoSeparator;
438 SoVertexProperty *vertices =
new SoVertexProperty();
439 for (
int i=0;
i<SOGENERICBOX_NPOINTS;++
i)
441 SoIndexedFaceSet * faceset =
new SoIndexedFaceSet;
442 faceset->coordIndex.setValues(0,5*6, sogenericbox_vindices_foraltrepfaces);
443 faceset->vertexProperty = vertices;
444 sep->addChild(faceset);
453 SoIndexedLineSet * lineset =
new SoIndexedLineSet;
454 lineset->coordIndex.setValues(0,20,sogenericbox_vindices_foraltreplines);
455 lineset->vertexProperty = vertices;
456 sep->addChild(lineset);