SoFCMeshVertex.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2006 Werner Mayer <werner.wm.mayer@gmx.de>              *
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 <Inventor/actions/SoCallbackAction.h>
00036 # include <Inventor/actions/SoGetBoundingBoxAction.h>
00037 # include <Inventor/actions/SoGetPrimitiveCountAction.h>
00038 # include <Inventor/actions/SoGLRenderAction.h>
00039 # include <Inventor/actions/SoPickAction.h>
00040 # include <Inventor/actions/SoWriteAction.h>
00041 # include <Inventor/errors/SoReadError.h>
00042 # include <Inventor/misc/SoState.h>
00043 #endif
00044 
00045 #include "SoFCMeshVertex.h"
00046 
00047 using namespace MeshGui;
00048 
00049 
00050 // Defines all required member variables and functions for a
00051 // single-value field
00052 SO_SFIELD_SOURCE(SoSFMeshPointArray, MeshCore::MeshPointArray*, MeshCore::MeshPointArray*);
00053 
00054 
00055 void SoSFMeshPointArray::initClass()
00056 {
00057    // This macro takes the name of the class and the name of the
00058    // parent class
00059    SO_SFIELD_INIT_CLASS(SoSFMeshPointArray, SoSField);
00060 }
00061 
00062 void SoSFMeshPointArray::setValue(const MeshCore::MeshPointArray& p)
00063 {
00064   SoSFMeshPointArray::setValue(const_cast<MeshCore::MeshPointArray*>(&p));
00065 }
00066 
00067 // This reads the value of a field from a file. It returns FALSE if the value could not be read
00068 // successfully.
00069 SbBool SoSFMeshPointArray::readValue(SoInput *in)
00070 {
00071   // This macro is convenient for reading with error detection.
00072 #define READ_VAL(val) \
00073   if (!in->read(val)) { \
00074     SoReadError::post(in, "Premature end of file"); \
00075     return FALSE; \
00076   }
00077 
00078   value = new MeshCore::MeshPointArray();
00079 
00080   // ** Binary format ******************************************************
00081   if (in->isBinary()) {
00082     int numtoread;
00083     READ_VAL(numtoread);
00084 
00085     // Sanity checking on the value, to avoid barfing on corrupt
00086     // files.
00087     if (numtoread < 0) {
00088       SoReadError::post(in, "invalid number of values in field: %d",
00089                         numtoread);
00090       return FALSE;
00091     }
00092 
00093     value->resize(numtoread);
00094     if (!this->readBinaryValues(in, numtoread)) { return FALSE; }
00095   }
00096 
00097   // ** ASCII format *******************************************************
00098   else {
00099     char c;
00100     READ_VAL(c);
00101     if (c == '[') {
00102       unsigned long currentidx = 0;
00103 
00104       READ_VAL(c);
00105       if (c == ']') {
00106         // Zero values -- done. :^)
00107       }
00108       else {
00109         in->putBack(c);
00110 
00111         while (TRUE) {
00112           // makeRoom() makes sure the allocation strategy is decent.
00113           if (currentidx >= value->size()) value->resize(currentidx + 1);
00114 
00115           if (!this->read1Value(in, currentidx++)) return FALSE;
00116 
00117           READ_VAL(c);
00118           if (c == ',') { READ_VAL(c); } // Treat trailing comma as whitespace.
00119 
00120           // That was the last array element, we're done.
00121           if (c == ']') { break; }
00122 
00123           if (c == '}') {
00124             SoReadError::post(in, "Premature end of array, got '%c'", c);
00125             return FALSE;
00126           }
00127 
00128           in->putBack(c);
00129         }
00130       }
00131 
00132       // Fit array to number of items.
00133       value->resize(currentidx);
00134     }
00135     else {
00136       in->putBack(c);
00137       value->resize(1);
00138       if (!this->read1Value(in, 0)) return FALSE;
00139     }
00140   }
00141 
00142 #undef READ_VAL
00143 
00144   // We need to trigger the notification chain here, as this function
00145   // can be used on a node in a scene graph in any state -- not only
00146   // during initial scene graph import.
00147   this->valueChanged();
00148   
00149   return TRUE;
00150 }
00151 
00152 SbBool SoSFMeshPointArray::readBinaryValues(SoInput * in, unsigned long numarg)
00153 {
00154   assert(in->isBinary());
00155   assert(numarg >= 0);
00156 
00157   for (unsigned long i=0; i < numarg; i++) if (!this->read1Value(in, i)) return FALSE;
00158   return TRUE;
00159 }
00160 
00161 SbBool SoSFMeshPointArray::read1Value(SoInput * in, unsigned long idx)
00162 {
00163   assert(idx < value->size());
00164   MeshCore::MeshPoint& v = (*value)[idx];
00165   return (in->read(v.x) && in->read(v.y) && in->read(v.z));
00166 }
00167 
00168 int SoSFMeshPointArray::getNumValuesPerLine() const
00169 {
00170   return 1;
00171 }
00172 
00173 // This writes the value of a field to a file.
00174 void SoSFMeshPointArray::writeValue(SoOutput *out) const
00175 {
00176   if (out->isBinary()) {
00177     this->writeBinaryValues(out);
00178     return;
00179   }
00180 
00181   const unsigned long count = value->size();
00182   if ((count > 1) || (count == 0)) out->write("[ ");
00183 
00184   out->incrementIndent();
00185 
00186   for (unsigned long i=0; i < count; i++) {
00187     this->write1Value(out, i);
00188 
00189     if (i != count-1) {
00190       if (((i+1) % this->getNumValuesPerLine()) == 0) {
00191         out->write(",\n");
00192         out->indent();
00193         // for alignment
00194         out->write("  ");
00195       }
00196       else {
00197         out->write(", ");
00198       }
00199     }
00200   }
00201   if ((count > 1) || (count == 0)) out->write(" ]");
00202 
00203   out->decrementIndent();
00204 }
00205 
00206 void SoSFMeshPointArray::writeBinaryValues(SoOutput * out) const
00207 {
00208   assert(out->isBinary());
00209 
00210   const unsigned int count = (unsigned int)value->size();
00211   out->write(count);
00212   for (unsigned int i=0; i < count; i++) this->write1Value(out, i);
00213 }
00214 
00215 void SoSFMeshPointArray::write1Value(SoOutput * out, unsigned long idx) const
00216 {
00217   const MeshCore::MeshPoint& v = (*value)[idx];
00218   out->write(v.x);
00219   if (!out->isBinary()) out->write(' ');
00220   out->write(v.y);
00221   if (!out->isBinary()) out->write(' ');
00222   out->write(v.z);
00223 }
00224 
00225 // -------------------------------------------------------
00226 
00227 SO_ELEMENT_SOURCE(SoFCMeshVertexElement);
00228 
00229 void SoFCMeshVertexElement::initClass()
00230 {
00231    SO_ELEMENT_INIT_CLASS(SoFCMeshVertexElement, inherited);
00232 }
00233 
00234 void SoFCMeshVertexElement::init(SoState * state)
00235 {
00236   inherited::init(state);
00237   this->coords3D = 0;
00238 }
00239 
00240 SoFCMeshVertexElement::~SoFCMeshVertexElement()
00241 {
00242 }
00243 
00244 void SoFCMeshVertexElement::set(SoState * const state, SoNode * const node, const MeshCore::MeshPointArray * const coords)
00245 {
00246   SoFCMeshVertexElement * elem = (SoFCMeshVertexElement *)
00247     SoReplacedElement::getElement(state, classStackIndex, node);
00248   if (elem) {
00249     elem->coords3D = coords;
00250     elem->nodeId = node->getNodeId();
00251   }
00252 }
00253 
00254 const MeshCore::MeshPointArray * SoFCMeshVertexElement::get(SoState * const state)
00255 {
00256   return SoFCMeshVertexElement::getInstance(state)->coords3D;
00257 }
00258 
00259 const SoFCMeshVertexElement * SoFCMeshVertexElement::getInstance(SoState * state)
00260 {
00261   return (const SoFCMeshVertexElement *) SoElement::getConstElement(state, classStackIndex);
00262 }
00263 
00264 void SoFCMeshVertexElement::print(FILE * /* file */) const
00265 {
00266 }
00267 
00268 // -------------------------------------------------------
00269 
00270 SO_NODE_SOURCE(SoFCMeshVertex);
00271 
00275 SoFCMeshVertex::SoFCMeshVertex(void)
00276 {
00277   SO_NODE_CONSTRUCTOR(SoFCMeshVertex);
00278 
00279   SO_NODE_ADD_FIELD(point, (0));
00280 }
00281 
00285 SoFCMeshVertex::~SoFCMeshVertex()
00286 {
00287 }
00288 
00289 // Doc from superclass.
00290 void SoFCMeshVertex::initClass(void)
00291 {
00292   SO_NODE_INIT_CLASS(SoFCMeshVertex, SoNode, "Node");
00293 
00294   SO_ENABLE(SoGetBoundingBoxAction, SoFCMeshVertexElement);
00295   SO_ENABLE(SoGLRenderAction, SoFCMeshVertexElement);
00296   SO_ENABLE(SoPickAction, SoFCMeshVertexElement);
00297   SO_ENABLE(SoCallbackAction, SoFCMeshVertexElement);
00298   SO_ENABLE(SoGetPrimitiveCountAction, SoFCMeshVertexElement);
00299 }
00300 
00301 // Doc from superclass.
00302 void SoFCMeshVertex::doAction(SoAction * action)
00303 {
00304   SoFCMeshVertexElement::set(action->getState(), this, point.getValue());
00305 //  SoCoordinateElement::set3(action->getState(), this,
00306 //                            point.getNum(), point.getValues(0));
00307 }
00308 
00309 // Doc from superclass.
00310 void SoFCMeshVertex::GLRender(SoGLRenderAction * action)
00311 {
00312   SoFCMeshVertex::doAction(action);
00313 }
00314 
00315 // Doc from superclass.
00316 void SoFCMeshVertex::callback(SoCallbackAction * action)
00317 {
00318   SoFCMeshVertex::doAction(action);
00319 }
00320 
00321 // Doc from superclass.
00322 void SoFCMeshVertex::pick(SoPickAction * action)
00323 {
00324   SoFCMeshVertex::doAction(action);
00325 }
00326 
00327 // Doc from superclass.
00328 void SoFCMeshVertex::getBoundingBox(SoGetBoundingBoxAction * action)
00329 {
00330   SoFCMeshVertex::doAction(action);
00331 }
00332 
00333 // Doc from superclass.
00334 void SoFCMeshVertex::getPrimitiveCount(SoGetPrimitiveCountAction * action)
00335 {
00336   SoFCMeshVertex::doAction(action);
00337 }
00338 

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