SoFCShapeObject.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2008 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 
00024 #include "PreCompiled.h"
00025 
00026 #ifndef _PreComp_
00027 # ifdef FC_OS_WIN32
00028 # include <windows.h>
00029 # endif
00030 # ifdef FC_OS_MACOSX
00031 # include <OpenGL/gl.h>
00032 # else
00033 # include <GL/gl.h>
00034 # endif
00035 # include <float.h>
00036 # include <algorithm>
00037 # include <Inventor/actions/SoCallbackAction.h>
00038 # include <Inventor/actions/SoGetBoundingBoxAction.h>
00039 # include <Inventor/actions/SoGetPrimitiveCountAction.h>
00040 # include <Inventor/actions/SoGLRenderAction.h>
00041 # include <Inventor/actions/SoPickAction.h>
00042 # include <Inventor/actions/SoWriteAction.h>
00043 # include <Inventor/bundles/SoMaterialBundle.h>
00044 # include <Inventor/bundles/SoTextureCoordinateBundle.h>
00045 # include <Inventor/elements/SoCoordinateElement.h>
00046 # include <Inventor/elements/SoGLCacheContextElement.h>
00047 # include <Inventor/errors/SoReadError.h>
00048 # include <Inventor/misc/SoState.h>
00049 #endif
00050 
00051 #include "SoFCShapeObject.h"
00052 
00053 using namespace PartGui;
00054 
00055 
00056 SO_NODE_SOURCE(SoFCControlPoints);
00057 
00058 void SoFCControlPoints::initClass()
00059 {
00060     SO_NODE_INIT_CLASS(SoFCControlPoints, SoShape, "Shape");
00061 }
00062 
00063 SoFCControlPoints::SoFCControlPoints()
00064 {
00065     SO_NODE_CONSTRUCTOR(SoFCControlPoints);
00066 
00067     SbVec3f c(1.0f, 0.447059f, 0.337255f);
00068     SO_NODE_ADD_FIELD(numPolesU, (0));
00069     SO_NODE_ADD_FIELD(numPolesV, (0));
00070     SO_NODE_ADD_FIELD(numKnotsU, (0));
00071     SO_NODE_ADD_FIELD(numKnotsV, (0));
00072     SO_NODE_ADD_FIELD(lineColor, (c));
00073 }
00074 
00078 void SoFCControlPoints::GLRender(SoGLRenderAction *action)
00079 {
00080     if (shouldGLRender(action))
00081     {
00082         SoState*  state = action->getState();
00083         const SoCoordinateElement * coords = SoCoordinateElement::getInstance(state);
00084         if (!coords) return;
00085         const SbVec3f * points = coords->getArrayPtr3();
00086         if (!points) return;
00087 
00088         SoMaterialBundle mb(action);
00089         SoTextureCoordinateBundle tb(action, TRUE, FALSE);
00090         SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR);
00091         mb.sendFirst();  // make sure we have the correct material
00092 
00093         int32_t len = coords->getNum();
00094         drawControlPoints(points, len);
00095     }
00096 }
00097 
00101 void SoFCControlPoints::drawControlPoints(const SbVec3f * points,int32_t len) const
00102 {
00103     glLineWidth(1.0f);
00104     glColor3fv(lineColor.getValue().getValue());
00105 
00106     uint32_t nCtU=numPolesU.getValue();
00107     uint32_t nCtV=numPolesV.getValue();
00108     uint32_t poles = nCtU * nCtV;
00109     if (poles > (uint32_t)len)
00110         return; // wrong setup, too few points
00111     // draw control mesh
00112     glBegin(GL_LINES);
00113     for (uint32_t u = 0; u < nCtU-1; ++u) {
00114         for (uint32_t v = 0; v < nCtV -1; ++v) {
00115             glVertex3fv(points[u*nCtV+v].getValue());
00116             glVertex3fv(points[u*nCtV+v+1].getValue());
00117             glVertex3fv(points[u*nCtV+v].getValue());
00118             glVertex3fv(points[(u+1)*nCtV+v].getValue());
00119         }
00120         glVertex3fv(points[(u+1)*nCtV-1].getValue());
00121         glVertex3fv(points[(u+2)*nCtV-1].getValue());
00122     }
00123     for (uint32_t v = 0; v < nCtV -1; ++v) {
00124         glVertex3fv(points[(nCtU-1)*nCtV+v].getValue());
00125         glVertex3fv(points[(nCtU-1)*nCtV+v+1].getValue());
00126     }
00127     glEnd();
00128 
00129     // draw poles
00130     glPointSize(5.0f);
00131     glBegin(GL_POINTS);
00132     for (uint32_t p=0; p<poles; p++) {
00133         glVertex3fv(points[p].getValue());
00134     }
00135     glEnd();
00136 
00137     // draw knots if available
00138     uint32_t knots=numKnotsU.getValue() * numKnotsV.getValue();
00139     uint32_t index = poles + knots;
00140     if (index > (uint32_t)len)
00141         return; // wrong setup, too few points
00142     glColor3f(1.0f, 1.0f, 0.0f);
00143     glPointSize(6.0f);
00144     glBegin(GL_POINTS);
00145     for (uint32_t p=poles; p<index; p++) {
00146         glVertex3fv(points[p].getValue());
00147     }
00148     glEnd();
00149 }
00150 
00151 void SoFCControlPoints::generatePrimitives(SoAction* action)
00152 {
00153 }
00154 
00158 void SoFCControlPoints::computeBBox(SoAction *action, SbBox3f &box, SbVec3f &center)
00159 {
00160     SoState*  state = action->getState();
00161     const SoCoordinateElement * coords = SoCoordinateElement::getInstance(state);
00162     if (!coords) return;
00163     const SbVec3f * points = coords->getArrayPtr3();
00164     if (!points) return;
00165     float maxX=-FLT_MAX, minX=FLT_MAX,
00166           maxY=-FLT_MAX, minY=FLT_MAX,
00167           maxZ=-FLT_MAX, minZ=FLT_MAX;
00168     int32_t len = coords->getNum();
00169     if (len > 0) {
00170         for (int32_t i=0; i<len; i++) {
00171             maxX = std::max<float>(maxX,points[i][0]);
00172             minX = std::min<float>(minX,points[i][0]);
00173             maxY = std::max<float>(maxY,points[i][1]);
00174             minY = std::min<float>(minY,points[i][1]);
00175             maxZ = std::max<float>(maxZ,points[i][2]);
00176             minZ = std::min<float>(minZ,points[i][2]);
00177         }
00178 
00179         box.setBounds(minX,minY,minZ,maxX,maxY,maxZ);
00180         center.setValue(0.5f*(minX+maxX),0.5f*(minY+maxY),0.5f*(minZ+maxZ));
00181     }
00182     else {
00183         box.setBounds(SbVec3f(0,0,0), SbVec3f(0,0,0));
00184         center.setValue(0.0f,0.0f,0.0f);
00185     }
00186 }

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