1
/***************************************************************************
2
* Copyright (c) 2007 Werner Mayer <wmayer[at]users.sourceforge.net> *
4
* This file is part of the FreeCAD CAx development system. *
6
* This library is free software; you can redistribute it and/or *
7
* modify it under the terms of the GNU Library General Public *
8
* License as published by the Free Software Foundation; either *
9
* version 2 of the License, or (at your option) any later version. *
11
* This library is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU Library General Public License for more details. *
16
* You should have received a copy of the GNU Library General Public *
17
* License along with this library; see the file COPYING.LIB. If not, *
18
* write to the Free Software Foundation, Inc., 59 Temple Place, *
19
* Suite 330, Boston, MA 02111-1307, USA *
21
***************************************************************************/
23
#include "PreCompiled.h"
28
#include <Inventor/SbBox.h>
29
#include <Inventor/actions/SoGLRenderAction.h>
30
#include <Inventor/elements/SoLazyElement.h>
31
#include <Inventor/misc/SoState.h>
32
#include <Inventor/nodes/SoText2.h>
33
#include <Inventor/nodes/SoTransform.h>
38
#include "SoFCBoundingBox.h"
43
SO_NODE_SOURCE(SoFCBoundingBox)
45
// vertices used to create a box
46
static const int32_t bBoxVerts[8][3] =
58
// indexes used to create the edges
59
static const int32_t bBoxEdges[36] =
61
0,1,-1, 1,2,-1, 2,3,-1, 3,0,-1,
62
4,5,-1, 5,6,-1, 6,7,-1, 7,4,-1,
63
0,4,-1, 1,5,-1, 2,6,-1, 3,7,-1
66
void SoFCBoundingBox::initClass ()
68
SO_NODE_INIT_CLASS(SoFCBoundingBox, SoShape, "Shape");
71
SoFCBoundingBox::SoFCBoundingBox ()
73
SO_NODE_CONSTRUCTOR(SoFCBoundingBox);
75
SO_NODE_ADD_FIELD(minBounds, (-1.0, -1.0, -1.0));
76
SO_NODE_ADD_FIELD(maxBounds, ( 1.0, 1.0, 1.0));
77
SO_NODE_ADD_FIELD(coordsOn, (true));
78
SO_NODE_ADD_FIELD(dimensionsOn, (true));
80
root = new SoSeparator();
81
auto bboxSep = new SoSeparator();
83
bboxCoords = new SoCoordinate3();
84
bboxCoords->point.setNum(8);
85
bboxSep->addChild(bboxCoords);
86
root->addChild(bboxSep);
88
// the lines of the box
89
bboxLines = new SoIndexedLineSet();
90
bboxLines->coordIndex.setNum(36);
91
bboxLines->coordIndex.setValues(0, 36, bBoxEdges);
92
bboxSep->addChild(bboxLines);
95
// create the text nodes, including a transform for each vertice offset
96
textSep = new SoSeparator();
97
for (int i = 0; i < 8; i++) {
98
auto temp = new SoSeparator();
99
auto trans = new SoTransform();
100
temp->addChild(trans);
101
auto text = new SoText2();
102
text->justification.setValue(SoText2::CENTER);
103
temp->addChild(text);
104
textSep->addChild(temp);
107
// create the text nodes, including a transform for each dimension
108
dimSep = new SoSeparator();
109
for (int i = 0; i < 3; i++) {
110
auto temp = new SoSeparator();
111
auto trans = new SoTransform();
112
temp->addChild(trans);
113
auto text = new SoText2();
114
text->justification.setValue(SoText2::CENTER);
115
temp->addChild(text);
116
dimSep->addChild(temp);
119
root->addChild(textSep);
120
root->addChild(dimSep);
124
SoFCBoundingBox::~SoFCBoundingBox ()
129
void SoFCBoundingBox::GLRender (SoGLRenderAction *action)
131
SbVec3f corner[2], ctr, *vptr;
132
SbBool coord, dimension;
134
// grab the current state
135
//SoState *state = action->getState();
137
if (!shouldGLRender(action))
140
// get the latest values from the fields
141
corner[0] = minBounds.getValue();
142
corner[1] = maxBounds.getValue();
143
coord = coordsOn.getValue();
144
dimension = dimensionsOn.getValue();
146
// set the coordinates for the LineSet to point to
147
vptr = bboxCoords->point.startEditing();
148
for (int i = 0; i < 8; i++) {
149
for (int j = 0; j < 3; j++) {
150
vptr[i][j] = corner[bBoxVerts[i][j]][j];
154
// if coord is true then set the text nodes
156
ctr = (corner[1] - corner[0]) / 2.0f;
157
for (int i = 0; i < 8; i++) {
158
// create the string for the text
159
std::stringstream str;
161
str.setf(std::ios::fixed | std::ios::showpoint);
162
str << "(" << vptr[i][0] << "," << vptr[i][1] << "," << vptr[i][2] << ")";
164
SoSeparator *sep = static_cast<SoSeparator *>(textSep->getChild(i));
165
SoTransform *trans = static_cast<SoTransform *>(sep->getChild(0));
167
trans->translation.setValue(vptr[i].getValue());
168
SoText2* t = static_cast<SoText2 *>(sep->getChild(1));
169
t->string.setValue(str.str().c_str());
173
if (root->findChild(textSep) < 0)
174
root->addChild(textSep);
176
if (root->findChild(textSep) >= 0)
177
root->removeChild(textSep);
180
// if dimension is true then set the text nodes
182
ctr = (corner[1] - corner[0]) / 2.0f;
183
for (int i = 0; i < 3; i++) {
184
// create the string for the text
185
std::stringstream str;
187
str.setf(std::ios::fixed | std::ios::showpoint);
188
str << (2.0f * ctr[i]);
190
SoSeparator *sep = static_cast<SoSeparator *>(dimSep->getChild(i));
191
SoTransform *trans = static_cast<SoTransform *>(sep->getChild(0));
193
SbVec3f point = corner[0];
195
trans->translation.setValue(point.getValue());
196
SoText2* t = static_cast<SoText2 *>(sep->getChild(1));
197
t->string.setValue(str.str().c_str());
201
if (root->findChild(dimSep) < 0)
202
root->addChild(dimSep);
204
if (root->findChild(dimSep) >= 0)
205
root->removeChild(dimSep);
208
bboxCoords->point.finishEditing();
211
SoState * state = action->getState();
213
SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR);
214
root->GLRender(action);
218
void SoFCBoundingBox::generatePrimitives (SoAction * /*action*/)
222
void SoFCBoundingBox::computeBBox (SoAction * /*action*/, SbBox3f &box, SbVec3f ¢er)
224
center = (minBounds.getValue() + maxBounds.getValue()) / 2.0f;
225
box.setBounds(minBounds.getValue(), maxBounds.getValue());
228
void SoFCBoundingBox::finish()
233
// ---------------------------------------------------------------
235
SO_NODE_SOURCE(SoSkipBoundingGroup)
240
SoSkipBoundingGroup::SoSkipBoundingGroup()
242
SO_NODE_CONSTRUCTOR(SoSkipBoundingGroup);
244
SO_NODE_ADD_FIELD(mode, (INCLUDE_BBOX));
246
SO_NODE_DEFINE_ENUM_VALUE(Modes, INCLUDE_BBOX);
247
SO_NODE_DEFINE_ENUM_VALUE(Modes, EXCLUDE_BBOX);
248
SO_NODE_SET_SF_ENUM_TYPE (mode, Modes);
254
SoSkipBoundingGroup::~SoSkipBoundingGroup() = default;
257
SoSkipBoundingGroup::initClass()
259
SO_NODE_INIT_CLASS(SoSkipBoundingGroup,SoGroup,"Group");
262
void SoSkipBoundingGroup::finish()
267
void SoSkipBoundingGroup::getBoundingBox(SoGetBoundingBoxAction *action)
269
if (mode.getValue() == INCLUDE_BBOX)
270
inherited::getBoundingBox(action);