SoFCBoundingBox.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2007 Werner Mayer <wmayer[at]users.sourceforge.net>     *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 #include "PreCompiled.h"
00024 
00025 #ifndef _PreComp_
00026 # include <sstream>
00027 #endif
00028 
00029 #include <Inventor/SbBox.h>
00030 #include <Inventor/SoPrimitiveVertex.h>
00031 #include <Inventor/actions/SoGLRenderAction.h>
00032 #include <Inventor/bundles/SoMaterialBundle.h>
00033 #include <Inventor/elements/SoLightModelElement.h>
00034 #include <Inventor/elements/SoLazyElement.h>
00035 #include <Inventor/elements/SoMaterialBindingElement.h>
00036 #include <Inventor/elements/SoModelMatrixElement.h>
00037 #include <Inventor/misc/SoState.h>
00038 
00039 #include <string.h>
00040 #include <iostream>
00041 
00042 #include "SoFCBoundingBox.h"
00043 
00044 using namespace Gui;
00045 
00046 SO_NODE_SOURCE(SoFCBoundingBox);
00047 
00048 // vertices used to create a box
00049 static const int32_t bBoxVerts[8][3] =
00050 {
00051     {0, 0, 0},
00052     {1, 0, 0},
00053     {1, 1, 0},
00054     {0, 1, 0},
00055     {0, 0, 1},
00056     {1, 0, 1},
00057     {1, 1, 1},
00058     {0, 1, 1}
00059 };
00060 
00061 // indexes used to create the edges
00062 static const int32_t bBoxEdges[36] =
00063 {
00064     0,1,-1, 1,2,-1, 2,3,-1, 3,0,-1,
00065     4,5,-1, 5,6,-1, 6,7,-1, 7,4,-1,
00066     0,4,-1, 1,5,-1, 2,6,-1, 3,7,-1
00067 };
00068 
00069 void SoFCBoundingBox::initClass ()
00070 {
00071     SO_NODE_INIT_CLASS(SoFCBoundingBox, SoShape, "Shape");
00072 }
00073 
00074 SoFCBoundingBox::SoFCBoundingBox ()
00075 {
00076     SO_NODE_CONSTRUCTOR(SoFCBoundingBox);
00077 
00078     SO_NODE_ADD_FIELD(minBounds, (-1.0, -1.0, -1.0));
00079     SO_NODE_ADD_FIELD(maxBounds, ( 1.0,  1.0,  1.0));
00080     SO_NODE_ADD_FIELD(coordsOn, (TRUE));
00081     SO_NODE_ADD_FIELD(dimensionsOn, (TRUE));
00082 
00083     root = new SoSeparator();
00084     SoSeparator *bboxSep = new SoSeparator();
00085 
00086     bboxCoords = new SoCoordinate3();
00087     bboxCoords->point.setNum(8);
00088     bboxSep->addChild(bboxCoords);
00089     root->addChild(bboxSep);
00090 
00091     // the lines of the box
00092     bboxLines  = new SoIndexedLineSet();
00093     bboxLines->coordIndex.setNum(36);
00094     bboxLines->coordIndex.setValues(0, 36, bBoxEdges);
00095     bboxSep->addChild(bboxLines);
00096   
00097 
00098     // create the text nodes, including a transform for each vertice offset
00099     textSep = new SoSeparator();
00100     for (int i = 0; i < 8; i++) {
00101         SoSeparator *temp = new SoSeparator();
00102         SoTransform *trans = new SoTransform();
00103         temp->addChild(trans);
00104         SoText2* text = new SoText2();
00105         text->justification.setValue(SoText2::CENTER);
00106         temp->addChild(text);
00107         textSep->addChild(temp);
00108     }
00109 
00110     // create the text nodes, including a transform for each dimension
00111     dimSep = new SoSeparator();
00112     for (int i = 0; i < 3; i++) {
00113         SoSeparator *temp = new SoSeparator();
00114         SoTransform *trans = new SoTransform();
00115         temp->addChild(trans);
00116         SoText2* text = new SoText2();
00117         text->justification.setValue(SoText2::CENTER);
00118         temp->addChild(text);
00119         dimSep->addChild(temp);
00120     }
00121 
00122     root->addChild(textSep);
00123     root->addChild(dimSep);
00124     root->ref();
00125 }
00126 
00127 SoFCBoundingBox::~SoFCBoundingBox ()
00128 {
00129     root->unref();
00130 }
00131 
00132 void SoFCBoundingBox::GLRender (SoGLRenderAction *action)
00133 {
00134     SbVec3f corner[2], ctr, *vptr;
00135     SbBool coord, dimension;
00136 
00137     // grab the current state
00138     //SoState *state = action->getState();
00139 
00140     if (!shouldGLRender(action))
00141         return;
00142 
00143     // get the latest values from the fields
00144     corner[0] = minBounds.getValue();
00145     corner[1] = maxBounds.getValue();
00146     coord     = coordsOn.getValue();
00147     dimension = dimensionsOn.getValue();
00148 
00149     // set the coordinates for the LineSet to point to
00150     vptr = bboxCoords->point.startEditing();
00151     for (int i = 0; i < 8; i++) {
00152         for (int j = 0; j < 3; j++) {
00153             vptr[i][j] = corner[bBoxVerts[i][j]][j];
00154         }
00155     }
00156 
00157     // if coord is true then set the text nodes
00158     if (coord) {
00159         ctr = (corner[1] - corner[0]) / 2.0f;
00160         for (int i = 0; i < 8; i++) {
00161             // create the string for the text
00162             std::stringstream str;
00163             str.precision(2);
00164             str.setf(std::ios::fixed | std::ios::showpoint);
00165             str << "(" << vptr[i][0] << "," << vptr[i][1] << "," << vptr[i][2] << ")";
00166 
00167             SoSeparator *sep   = (SoSeparator *)textSep->getChild(i);
00168             SoTransform *trans = (SoTransform *)sep->getChild(0);
00169 
00170             trans->translation.setValue(vptr[i].getValue());
00171             SoText2* t = (SoText2 *)sep->getChild(1);
00172             t->string.setValue(str.str().c_str());
00173         }
00174 
00175         textSep->ref();
00176         if (root->findChild(textSep) < 0)
00177             root->addChild(textSep);
00178     } else {
00179         if (root->findChild(textSep) >= 0)
00180             root->removeChild(textSep);
00181     }
00182 
00183     // if dimension is true then set the text nodes
00184     if (dimension) {
00185         ctr = (corner[1] - corner[0]) / 2.0f;
00186         for (int i = 0; i < 3; i++) {
00187             // create the string for the text
00188             std::stringstream str;
00189             str.precision(2);
00190             str.setf(std::ios::fixed | std::ios::showpoint);
00191             str << (2.0f * ctr[i]);
00192 
00193             SoSeparator *sep   = (SoSeparator *)dimSep->getChild(i);
00194             SoTransform *trans = (SoTransform *)sep->getChild(0);
00195 
00196             SbVec3f point = corner[0];
00197             point[i] += ctr[i];
00198             trans->translation.setValue(point.getValue());
00199             SoText2* t = (SoText2 *)sep->getChild(1);
00200             t->string.setValue(str.str().c_str());
00201         }
00202 
00203         dimSep->ref();
00204         if (root->findChild(dimSep) < 0)
00205             root->addChild(dimSep);
00206     } else {
00207         if (root->findChild(dimSep) >= 0)
00208             root->removeChild(dimSep);
00209     }
00210 
00211     bboxCoords->point.finishEditing();
00212 
00213     // Avoid shading
00214     SoState * state = action->getState();
00215     state->push();
00216     SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR);
00217     root->GLRender(action);
00218     state->pop();
00219 }
00220 
00221 void SoFCBoundingBox::generatePrimitives (SoAction *action)
00222 {
00223 }
00224 
00225 void SoFCBoundingBox::computeBBox (SoAction *action, SbBox3f &box, SbVec3f &center)
00226 {
00227     center = (minBounds.getValue() + maxBounds.getValue()) / 2.0f;
00228     box.setBounds(minBounds.getValue(), maxBounds.getValue());
00229 }
00230 
00231 void SoFCBoundingBox::finish()
00232 {
00233   atexit_cleanup();
00234 }
00235 
00236 // ---------------------------------------------------------------
00237 
00238 SO_NODE_SOURCE(SoSkipBoundingGroup);
00239 
00243 SoSkipBoundingGroup::SoSkipBoundingGroup()
00244 {
00245     SO_NODE_CONSTRUCTOR(SoSkipBoundingGroup);
00246 
00247     SO_NODE_ADD_FIELD(mode,          (INCLUDE_BBOX));
00248 
00249     SO_NODE_DEFINE_ENUM_VALUE(Modes, INCLUDE_BBOX);
00250     SO_NODE_DEFINE_ENUM_VALUE(Modes, EXCLUDE_BBOX);
00251     SO_NODE_SET_SF_ENUM_TYPE (mode, Modes);
00252 }
00253 
00257 SoSkipBoundingGroup::~SoSkipBoundingGroup()
00258 {
00259 }
00260 
00261 void
00262 SoSkipBoundingGroup::initClass(void)
00263 {
00264     SO_NODE_INIT_CLASS(SoSkipBoundingGroup,SoGroup,"Group");
00265 }
00266 
00267 void SoSkipBoundingGroup::finish()
00268 {
00269     atexit_cleanup();
00270 }
00271 
00272 void SoSkipBoundingGroup::getBoundingBox(SoGetBoundingBoxAction *action)
00273 {
00274     if (mode.getValue() == INCLUDE_BBOX)
00275         inherited::getBoundingBox(action);
00276 }
00277 

Generated on Wed Nov 23 19:00:39 2011 for FreeCAD by  doxygen 1.6.1