From ec7f62310ef2765bf8b35d490f9674e84ab702c8 Mon Sep 17 00:00:00 2001 From: Uwe Date: Sun, 4 Dec 2022 17:09:41 +0100 Subject: [PATCH] [Mesh] remove unused file - unused since a while and also don't compile when adding them to CMake --- src/Mod/Mesh/Gui/SoFCMeshFaceSet.cpp | 1214 --------------------- src/Mod/Mesh/Gui/SoFCMeshFaceSet.h | 195 ---- src/Mod/Mesh/Gui/SoFCMeshNode.cpp | 763 ------------- src/Mod/Mesh/Gui/SoFCMeshNode.h | 110 -- src/Mod/Mesh/Gui/SoFCMeshVertex.cpp | 340 ------ src/Mod/Mesh/Gui/SoFCMeshVertex.h | 100 -- src/Mod/Mesh/Gui/ViewProviderMeshNode.cpp | 404 ------- src/Mod/Mesh/Gui/ViewProviderMeshNode.h | 97 -- 8 files changed, 3223 deletions(-) delete mode 100644 src/Mod/Mesh/Gui/SoFCMeshFaceSet.cpp delete mode 100644 src/Mod/Mesh/Gui/SoFCMeshFaceSet.h delete mode 100644 src/Mod/Mesh/Gui/SoFCMeshNode.cpp delete mode 100644 src/Mod/Mesh/Gui/SoFCMeshNode.h delete mode 100644 src/Mod/Mesh/Gui/SoFCMeshVertex.cpp delete mode 100644 src/Mod/Mesh/Gui/SoFCMeshVertex.h delete mode 100644 src/Mod/Mesh/Gui/ViewProviderMeshNode.cpp delete mode 100644 src/Mod/Mesh/Gui/ViewProviderMeshNode.h diff --git a/src/Mod/Mesh/Gui/SoFCMeshFaceSet.cpp b/src/Mod/Mesh/Gui/SoFCMeshFaceSet.cpp deleted file mode 100644 index af063502ee..0000000000 --- a/src/Mod/Mesh/Gui/SoFCMeshFaceSet.cpp +++ /dev/null @@ -1,1214 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2006 Werner Mayer * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - -#include "PreCompiled.h" -#ifndef _PreComp_ -# ifdef FC_OS_WIN32 -# include -# endif -# ifdef FC_OS_MACOSX -# include -# else -# include -# endif -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#include -#include -#include -#include -#include -#include - -#include "SoFCMeshFaceSet.h" -#include "SoFCMeshVertex.h" - - -using namespace MeshGui; - - -// Defines all required member variables and functions for a -// single-value field -SO_SFIELD_SOURCE(SoSFMeshFacetArray, MeshCore::MeshFacetArray*, MeshCore::MeshFacetArray*); - - -void SoSFMeshFacetArray::initClass() -{ - // This macro takes the name of the class and the name of the - // parent class - SO_SFIELD_INIT_CLASS(SoSFMeshFacetArray, SoSField); -} - -void SoSFMeshFacetArray::setValue(const MeshCore::MeshFacetArray& p) -{ - SoSFMeshFacetArray::setValue(const_cast(&p)); -} - -// This reads the value of a field from a file. It returns FALSE if the value could not be read -// successfully. -SbBool SoSFMeshFacetArray::readValue(SoInput *in) -{ - // This macro is convenient for reading with error detection. -#define READ_VAL(val) \ - if (!in->read(val)) { \ - SoReadError::post(in, "Premature end of file"); \ - return FALSE; \ - } - - value = new MeshCore::MeshFacetArray(); - - // ** Binary format ****************************************************** - if (in->isBinary()) { - int numtoread; - READ_VAL(numtoread); - - // Sanity checking on the value, to avoid barfing on corrupt - // files. - if (numtoread < 0) { - SoReadError::post(in, "invalid number of values in field: %d", - numtoread); - return FALSE; - } - - value->resize(numtoread); - if (!this->readBinaryValues(in, numtoread)) { - return FALSE; - } - } - - // ** ASCII format ******************************************************* - else { - char c; - READ_VAL(c); - if (c == '[') { - unsigned long currentidx = 0; - - READ_VAL(c); - if (c == ']') { - // Zero values -- done. :^) - } - else { - in->putBack(c); - - while (TRUE) { - // makeRoom() makes sure the allocation strategy is decent. - if (currentidx >= value->size()) value->resize(currentidx + 1); - - if (!this->read1Value(in, currentidx++)) - return FALSE; - - READ_VAL(c); - if (c == ',') { READ_VAL(c); } // Treat trailing comma as whitespace. - - // That was the last array element, we're done. - if (c == ']') { break; } - - if (c == '}') { - SoReadError::post(in, "Premature end of array, got '%c'", c); - return FALSE; - } - - in->putBack(c); - } - } - - // Fit array to number of items. - value->resize(currentidx); - } - else { - in->putBack(c); - value->resize(1); - if (!this->read1Value(in, 0)) - return FALSE; - } - } - -#undef READ_VAL - - // Create a dummy point array - MeshCore::MeshPointArray vertex; - MeshCore::MeshKernel mesh; - // Let the mesh kernel restore the neighbourhoods of the facets for us - mesh.Adopt(vertex, *value, true); - // Give us back the face data - mesh.Adopt(vertex, *value, false); - - // We need to trigger the notification chain here, as this function - // can be used on a node in a scene graph in any state -- not only - // during initial scene graph import. - this->valueChanged(); - - return TRUE; -} - -SbBool SoSFMeshFacetArray::readBinaryValues(SoInput * in, unsigned long numarg) -{ - assert(in->isBinary()); - assert(numarg >= 0); - - for (unsigned long i=0; i < numarg; i++) if (!this->read1Value(in, i)) return FALSE; - return TRUE; -} - -SbBool SoSFMeshFacetArray::read1Value(SoInput * in, unsigned long idx) -{ - assert(idx < value->size()); - MeshCore::MeshFacet& v = (*value)[idx]; - int32_t p0{}, p1{}, p2{}; - SbBool ret = (in->read(p0) && in->read(p1) && in->read(p2)); - if ( ret ) { - v._aulPoints[0] = p0; - v._aulPoints[1] = p1; - v._aulPoints[2] = p2; - } - - return ret; -} - -int SoSFMeshFacetArray::getNumValuesPerLine() const -{ - return 2; -} - -// This writes the value of a field to a file. -void SoSFMeshFacetArray::writeValue(SoOutput *out) const -{ - if (out->isBinary()) { - this->writeBinaryValues(out); - return; - } - - const unsigned long count = value->size(); - if ((count > 1) || (count == 0)) out->write("[ "); - - out->incrementIndent(); - - for (unsigned long i=0; i < count; i++) { - this->write1Value(out, i); - - if (i != count-1) { - if (((i+1) % this->getNumValuesPerLine()) == 0) { - out->write(",\n"); - out->indent(); - // for alignment - out->write(" "); - } - else { - out->write(", "); - } - } - } - if ((count > 1) || (count == 0)) out->write(" ]"); - - out->decrementIndent(); -} - -void SoSFMeshFacetArray::writeBinaryValues(SoOutput * out) const -{ - assert(out->isBinary()); - - const unsigned int count = (unsigned int)value->size(); - out->write(count); - for (unsigned int i=0; i < count; i++) this->write1Value(out, i); -} - -void SoSFMeshFacetArray::write1Value(SoOutput * out, unsigned long idx) const -{ - const MeshCore::MeshFacet& v = (*value)[idx]; - out->write((int32_t)(v._aulPoints[0])); - if (!out->isBinary()) out->write(' '); - out->write((int32_t)(v._aulPoints[1])); - if (!out->isBinary()) out->write(' '); - out->write((int32_t)(v._aulPoints[2])); -} - -// ------------------------------------------------------- - -SO_ELEMENT_SOURCE(SoFCMeshFacetElement); - -void SoFCMeshFacetElement::initClass() -{ - SO_ELEMENT_INIT_CLASS(SoFCMeshFacetElement, inherited); -} - -void SoFCMeshFacetElement::init(SoState * state) -{ - inherited::init(state); - this->coordIndex = 0; -} - -SoFCMeshFacetElement::~SoFCMeshFacetElement() -{ -} - -void SoFCMeshFacetElement::set(SoState * const state, SoNode * const node, const MeshCore::MeshFacetArray * const coords) -{ - SoFCMeshFacetElement * elem = (SoFCMeshFacetElement *) - SoReplacedElement::getElement(state, classStackIndex, node); - if (elem) { - elem->coordIndex = coords; - elem->nodeId = node->getNodeId(); - } -} - -const MeshCore::MeshFacetArray * SoFCMeshFacetElement::get(SoState * const state) -{ - return SoFCMeshFacetElement::getInstance(state)->coordIndex; -} - -const SoFCMeshFacetElement * SoFCMeshFacetElement::getInstance(SoState * state) -{ - return (const SoFCMeshFacetElement *) SoElement::getConstElement(state, classStackIndex); -} - -void SoFCMeshFacetElement::print(FILE * /* file */) const -{ -} - -// ------------------------------------------------------- - -SO_NODE_SOURCE(SoFCMeshFacet); - -/*! - Constructor. -*/ -SoFCMeshFacet::SoFCMeshFacet(void) -{ - SO_NODE_CONSTRUCTOR(SoFCMeshFacet); - - SO_NODE_ADD_FIELD(coordIndex, (0)); -} - -/*! - Destructor. -*/ -SoFCMeshFacet::~SoFCMeshFacet() -{ -} - -// Doc from superclass. -void SoFCMeshFacet::initClass(void) -{ - SO_NODE_INIT_CLASS(SoFCMeshFacet, SoNode, "Node"); - - SO_ENABLE(SoGetBoundingBoxAction, SoFCMeshFacetElement); - SO_ENABLE(SoGLRenderAction, SoFCMeshFacetElement); - SO_ENABLE(SoPickAction, SoFCMeshFacetElement); - SO_ENABLE(SoCallbackAction, SoFCMeshFacetElement); - SO_ENABLE(SoGetPrimitiveCountAction, SoFCMeshFacetElement); -} - -// Doc from superclass. -void SoFCMeshFacet::doAction(SoAction * action) -{ - SoFCMeshFacetElement::set(action->getState(), this, coordIndex.getValue()); -} - -// Doc from superclass. -void SoFCMeshFacet::GLRender(SoGLRenderAction * action) -{ - SoFCMeshFacet::doAction(action); -} - -// Doc from superclass. -void SoFCMeshFacet::callback(SoCallbackAction * action) -{ - SoFCMeshFacet::doAction(action); -} - -// Doc from superclass. -void SoFCMeshFacet::pick(SoPickAction * action) -{ - SoFCMeshFacet::doAction(action); -} - -// Doc from superclass. -void SoFCMeshFacet::getBoundingBox(SoGetBoundingBoxAction * action) -{ - SoFCMeshFacet::doAction(action); -} - -// Doc from superclass. -void SoFCMeshFacet::getPrimitiveCount(SoGetPrimitiveCountAction * action) -{ - SoFCMeshFacet::doAction(action); -} - -// ------------------------------------------------------- - -/** - * class SoFCMeshFaceSet - * \brief The SoFCMeshNode class is designed to render huge meshes. - * - * The SoFCMeshNode is an Inventor shape node that is designed to render huge meshes. If the mesh exceeds a certain number of triangles - * and the user does some intersections (e.g. moving, rotating, zooming, spinning, etc.) with the mesh then the GLRender() method renders - * only the gravity points of a subset of the triangles. - * If there is no user interaction with the mesh then all triangles are rendered. - * The limit of maximum allowed triangles can be specified in \a MaximumTriangles, the default value is set to 100.000. - * - * The GLRender() method checks the status of the SoFCInteractiveElement to decide to be in interactive mode or not. - * To take advantage of this facility the client programmer must set the status of the SoFCInteractiveElement to \a true - * if there is a user interaction and set the status to \a false if not. This can be done e.g. in the actualRedraw() method of - * the viewer. - * \author Werner Mayer - */ - -// Helper functions: draw vertices -inline void glVertex(const MeshCore::MeshPoint& _v) -{ - float v[3]; - v[0]=_v.x; v[1]=_v.y;v[2]=_v.z; - glVertex3fv(v); -} - -// Helper functions: draw normal -inline void glNormal(const Base::Vector3f& _n) -{ - float n[3]; - n[0]=_n.x; n[1]=_n.y;n[2]=_n.z; - glNormal3fv(n); -} - -// Helper functions: draw normal -inline void glNormal(float* n) -{ - glNormal3fv(n); -} - -// Helper function: convert Vec to SbVec3f -inline SbVec3f sbvec3f(const Base::Vector3f& _v) { - return SbVec3f(_v.x, _v.y, _v.z); -} - -SO_NODE_SOURCE(SoFCMeshFaceSet); - -void SoFCMeshFaceSet::initClass() -{ - SO_NODE_INIT_CLASS(SoFCMeshFaceSet, SoShape, "Shape"); -} - -SoFCMeshFaceSet::SoFCMeshFaceSet() : MaximumTriangles(100000), meshChanged(true) -{ - SO_NODE_CONSTRUCTOR(SoFCMeshFaceSet); -} - -void SoFCMeshFaceSet::notify(SoNotList * node) -{ - SoShape::notify(node); - meshChanged = true; -} - -/** - * Creates a rough proxy mesh model from the original data attached to a grid in case \a simplest is false. The number of grids - * in each direction doesn't exceed 50. - * If \a simplest is true then the model is built from the bounding box instead. - * - * For every move event the complete data set must be iterated to refresh internal Inventor data @see generatePrimitives(). - * Doing this very often for very huge data sets slows down the system noticeably. Using a rough model as proxy instead of the original - * data set can speed up the user interaction extremely. - * @note The proxy will never be displayed. It's just used for the picking mechanism. - * @note The usage of the proxy might be confusing a little bit due to the fact that some details get lost. So it'll be possible - * to pick the data set where no data seem to be. - */ -void SoFCMeshFaceSet::createProxyModel(const MeshCore::MeshPointArray* rPoints, const MeshCore::MeshFacetArray* rFaces, SbBool simplest) -{ - Base::BoundBox3f cBox; - for (MeshCore::MeshPointArray::_TConstIterator it = rPoints->begin(); it != rPoints->end(); ++it) - cBox &= (*it); - - if ( simplest ) { - int triangles[36] = { - 0,1,2,0,2,3, - 0,1,5,0,5,4, - 0,4,7,0,7,3, - 6,7,4,6,4,5, - 6,2,3,6,3,7, - 6,1,2,6,5,1 - }; - SbVec3f points[8] = { - SbVec3f(cBox.MinX, cBox.MinY, cBox.MinZ), - SbVec3f(cBox.MaxX, cBox.MinY, cBox.MinZ), - SbVec3f(cBox.MaxX, cBox.MaxY, cBox.MinZ), - SbVec3f(cBox.MinX, cBox.MaxY, cBox.MinZ), - SbVec3f(cBox.MinX, cBox.MinY, cBox.MaxZ), - SbVec3f(cBox.MaxX, cBox.MinY, cBox.MaxZ), - SbVec3f(cBox.MaxX, cBox.MaxY, cBox.MaxZ), - SbVec3f(cBox.MinX, cBox.MaxY, cBox.MaxZ) - }; - - coordIndex.setValues(0,36,triangles); - point.setValues (0,8,points); - } else { - - // takes the point and facet arrays under it's wings for a short moment - MeshCore::MeshKernel mesh; - mesh.Assign(*rPoints, *rFaces,false); - - // Check the boundings and the average edge length - float fAvgLen = 5.0f * MeshCore::MeshAlgorithm(mesh).GetAverageEdgeLength(); - - // create maximum 50 grids in each direction - fAvgLen = std::max(fAvgLen, (cBox.MaxX-cBox.MinX)/50.0f); - fAvgLen = std::max(fAvgLen, (cBox.MaxY-cBox.MinY)/50.0f); - fAvgLen = std::max(fAvgLen, (cBox.MaxZ-cBox.MinZ)/50.0f); - - MeshCore::MeshGeomFacet face; - std::vector facets; - - MeshCore::MeshPointGrid cGrid(mesh, fAvgLen); - unsigned long ulMaxX, ulMaxY, ulMaxZ; - cGrid.GetCtGrids(ulMaxX, ulMaxY, ulMaxZ); - MeshCore::MeshGridIterator cIter(cGrid); - - for ( cIter.Init(); cIter.More(); cIter.Next() ) { - if ( cIter.GetCtElements() > 0 ) { - unsigned long ulX, ulY, ulZ; - cIter.GetGridPos(ulX, ulY, ulZ); - Base::BoundBox3f cBox = cIter.GetBoundBox(); - - if ( ulX == 0 || (ulX-1 >= 0 && cGrid.GetCtElements(ulX-1,ulY, ulZ) == 0) ) { - face._aclPoints[0].Set(cBox.MinX,cBox.MinY,cBox.MinZ); - face._aclPoints[1].Set(cBox.MinX,cBox.MinY,cBox.MaxZ); - face._aclPoints[2].Set(cBox.MinX,cBox.MaxY,cBox.MinZ); - facets.push_back(face); - face._aclPoints[0].Set(cBox.MinX,cBox.MaxY,cBox.MaxZ); - face._aclPoints[1].Set(cBox.MinX,cBox.MaxY,cBox.MinZ); - face._aclPoints[2].Set(cBox.MinX,cBox.MinY,cBox.MaxZ); - facets.push_back(face); - } - if ( ulX+1 == ulMaxX || (ulX+1 < ulMaxX && cGrid.GetCtElements(ulX+1,ulY, ulZ) == 0) ) { - face._aclPoints[0].Set(cBox.MaxX,cBox.MinY,cBox.MinZ); - face._aclPoints[1].Set(cBox.MaxX,cBox.MaxY,cBox.MinZ); - face._aclPoints[2].Set(cBox.MaxX,cBox.MinY,cBox.MaxZ); - facets.push_back(face); - face._aclPoints[0].Set(cBox.MaxX,cBox.MaxY,cBox.MaxZ); - face._aclPoints[1].Set(cBox.MaxX,cBox.MinY,cBox.MaxZ); - face._aclPoints[2].Set(cBox.MaxX,cBox.MaxY,cBox.MinZ); - facets.push_back(face); - } - if ( ulY == 0 || (ulY-1 >= 0 && cGrid.GetCtElements(ulX,ulY-1, ulZ) == 0) ) { - face._aclPoints[0].Set(cBox.MinX,cBox.MinY,cBox.MaxZ); - face._aclPoints[1].Set(cBox.MinX,cBox.MinY,cBox.MinZ); - face._aclPoints[2].Set(cBox.MaxX,cBox.MinY,cBox.MaxZ); - facets.push_back(face); - face._aclPoints[0].Set(cBox.MaxX,cBox.MinY,cBox.MinZ); - face._aclPoints[1].Set(cBox.MaxX,cBox.MinY,cBox.MaxZ); - face._aclPoints[2].Set(cBox.MinX,cBox.MinY,cBox.MinZ); - facets.push_back(face); - } - if ( ulY+1 == ulMaxY || (ulY+1 < ulMaxY && cGrid.GetCtElements(ulX,ulY+1, ulZ) == 0) ) { - face._aclPoints[0].Set(cBox.MaxX,cBox.MaxY,cBox.MinZ); - face._aclPoints[1].Set(cBox.MinX,cBox.MaxY,cBox.MinZ); - face._aclPoints[2].Set(cBox.MaxX,cBox.MaxY,cBox.MaxZ); - facets.push_back(face); - face._aclPoints[0].Set(cBox.MinX,cBox.MaxY,cBox.MaxZ); - face._aclPoints[1].Set(cBox.MaxX,cBox.MaxY,cBox.MaxZ); - face._aclPoints[2].Set(cBox.MinX,cBox.MaxY,cBox.MinZ); - facets.push_back(face); - } - if ( ulZ == 0 || (ulZ-1 >= 0 && cGrid.GetCtElements(ulX,ulY, ulZ-1) == 0) ) { - face._aclPoints[0].Set(cBox.MaxX,cBox.MinY,cBox.MinZ); - face._aclPoints[1].Set(cBox.MinX,cBox.MinY,cBox.MinZ); - face._aclPoints[2].Set(cBox.MaxX,cBox.MaxY,cBox.MinZ); - facets.push_back(face); - face._aclPoints[0].Set(cBox.MinX,cBox.MaxY,cBox.MinZ); - face._aclPoints[1].Set(cBox.MaxX,cBox.MaxY,cBox.MinZ); - face._aclPoints[2].Set(cBox.MinX,cBox.MinY,cBox.MinZ); - facets.push_back(face); - } - if ( ulZ+1 == ulMaxZ || (ulZ+1 < ulMaxZ && cGrid.GetCtElements(ulX,ulY, ulZ+1) == 0) ) { - face._aclPoints[0].Set(cBox.MaxX,cBox.MinY,cBox.MaxZ); - face._aclPoints[1].Set(cBox.MaxX,cBox.MaxY,cBox.MaxZ); - face._aclPoints[2].Set(cBox.MinX,cBox.MinY,cBox.MaxZ); - facets.push_back(face); - face._aclPoints[0].Set(cBox.MinX,cBox.MaxY,cBox.MaxZ); - face._aclPoints[1].Set(cBox.MinX,cBox.MinY,cBox.MaxZ); - face._aclPoints[2].Set(cBox.MaxX,cBox.MaxY,cBox.MaxZ); - facets.push_back(face); - } - } - } - - MeshCore::MeshKernel kernel; kernel = facets; - const MeshCore::MeshPointArray& rPoints = kernel.GetPoints(); - const MeshCore::MeshFacetArray& rFacets = kernel.GetFacets(); - - point.enableNotify(false); - point.setNum(rPoints.size()); - unsigned int pos=0; - for (MeshCore::MeshPointArray::_TConstIterator cP=rPoints.begin(); cP!=rPoints.end(); ++cP) - point.set1Value(pos++,cP->x,cP->y,cP->z); - point.enableNotify(true); - - coordIndex.enableNotify(false); - coordIndex.setNum(3*rFacets.size()); - pos=0; - for (MeshCore::MeshFacetArray::_TConstIterator cF=rFacets.begin(); cF!=rFacets.end(); ++cF){ - coordIndex.set1Value(pos++,cF->_aulPoints[0]); - coordIndex.set1Value(pos++,cF->_aulPoints[1]); - coordIndex.set1Value(pos++,cF->_aulPoints[2]); - } - coordIndex.enableNotify(true); - - point.touch(); - coordIndex.touch(); - -#ifdef FC_DEBUG - std::ofstream str( "bbox.stl", std::ios::out | std::ios::binary ); - MeshCore::MeshOutput aWriter(kernel); - aWriter.SaveBinarySTL( str ); -#endif - } -} - -/** - * Either renders the complete mesh or only a subset of the points. - */ -void SoFCMeshFaceSet::GLRender(SoGLRenderAction *action) -{ - if (shouldGLRender(action)) - { - SoState* state = action->getState(); - - SbBool mode = Gui::SoFCInteractiveElement::get(state); - const MeshCore::MeshPointArray * coords = SoFCMeshVertexElement::get(state); - const MeshCore::MeshFacetArray * index = SoFCMeshFacetElement::get(state); - - Binding mbind = this->findMaterialBinding(state); - - SoMaterialBundle mb(action); - //SoTextureCoordinateBundle tb(action, true, false); - - SbBool needNormals = !mb.isColorOnly()/* || tb.isFunction()*/; - mb.sendFirst(); // make sure we have the correct material - - SbBool ccw = TRUE; - if (SoShapeHintsElement::getVertexOrdering(state) == SoShapeHintsElement::CLOCKWISE) - ccw = FALSE; - - if ( mode == false || index->size() <= this->MaximumTriangles ) { - if ( mbind != OVERALL ) - drawFaces(coords, index, &mb, mbind, needNormals, ccw); - else - drawFaces(coords, index, 0, mbind, needNormals, ccw); - } else { - drawPoints(coords, index, needNormals, ccw); - } - - // Disable caching for this node - SoGLCacheContextElement::shouldAutoCache(state, SoGLCacheContextElement::DONT_AUTO_CACHE); - } -} - -/** - * Translates current material binding into the internal Binding enum. - */ -SoFCMeshFaceSet::Binding SoFCMeshFaceSet::findMaterialBinding(SoState * const state) const -{ - Binding binding = OVERALL; - SoMaterialBindingElement::Binding matbind = SoMaterialBindingElement::get(state); - - switch (matbind) { - case SoMaterialBindingElement::OVERALL: - binding = OVERALL; - break; - case SoMaterialBindingElement::PER_VERTEX: - binding = PER_VERTEX_INDEXED; - break; - case SoMaterialBindingElement::PER_VERTEX_INDEXED: - binding = PER_VERTEX_INDEXED; - break; - case SoMaterialBindingElement::PER_PART: - case SoMaterialBindingElement::PER_FACE: - binding = PER_FACE_INDEXED; - break; - case SoMaterialBindingElement::PER_PART_INDEXED: - case SoMaterialBindingElement::PER_FACE_INDEXED: - binding = PER_FACE_INDEXED; - break; - default: - break; - } - return binding; -} - -/** - * Renders the triangles of the complete mesh. - * FIXME: Do it the same way as Coin did to have only one implementation which is controlled by defines - * FIXME: Implement using different values of transparency for each vertex or face - */ -void SoFCMeshFaceSet::drawFaces(const MeshCore::MeshPointArray * rPoints, const MeshCore::MeshFacetArray* rFacets, - SoMaterialBundle* mb, Binding bind, SbBool needNormals, SbBool ccw) const -{ - bool perVertex = (mb && bind == PER_VERTEX_INDEXED); - bool perFace = (mb && bind == PER_FACE_INDEXED); - - if (needNormals) - { - glBegin(GL_TRIANGLES); - if ( ccw ) { - // counterclockwise ordering - for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets->begin(); it != rFacets->end(); ++it ) - { - const MeshCore::MeshPoint& v0 = (*rPoints)[it->_aulPoints[0]]; - const MeshCore::MeshPoint& v1 = (*rPoints)[it->_aulPoints[1]]; - const MeshCore::MeshPoint& v2 = (*rPoints)[it->_aulPoints[2]]; - - // Calculate the normal n = (v1-v0)x(v2-v0) - float n[3]; - n[0] = (v1.y-v0.y)*(v2.z-v0.z)-(v1.z-v0.z)*(v2.y-v0.y); - n[1] = (v1.z-v0.z)*(v2.x-v0.x)-(v1.x-v0.x)*(v2.z-v0.z); - n[2] = (v1.x-v0.x)*(v2.y-v0.y)-(v1.y-v0.y)*(v2.x-v0.x); - - if(perFace) - mb->send(it-rFacets->begin(), TRUE); - glNormal(n); - if(perVertex) - mb->send(it->_aulPoints[0], TRUE); - glVertex(v0); - if(perVertex) - mb->send(it->_aulPoints[1], TRUE); - glVertex(v1); - if(perVertex) - mb->send(it->_aulPoints[2], TRUE); - glVertex(v2); - } - } else { - // clockwise ordering - for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets->begin(); it != rFacets->end(); ++it ) - { - const MeshCore::MeshPoint& v0 = (*rPoints)[it->_aulPoints[0]]; - const MeshCore::MeshPoint& v1 = (*rPoints)[it->_aulPoints[1]]; - const MeshCore::MeshPoint& v2 = (*rPoints)[it->_aulPoints[2]]; - - // Calculate the normal n = -(v1-v0)x(v2-v0) - float n[3]; - n[0] = -((v1.y-v0.y)*(v2.z-v0.z)-(v1.z-v0.z)*(v2.y-v0.y)); - n[1] = -((v1.z-v0.z)*(v2.x-v0.x)-(v1.x-v0.x)*(v2.z-v0.z)); - n[2] = -((v1.x-v0.x)*(v2.y-v0.y)-(v1.y-v0.y)*(v2.x-v0.x)); - - glNormal(n); - glVertex(v0); - glVertex(v1); - glVertex(v2); - } - } - glEnd(); - } - else - { - glBegin(GL_TRIANGLES); - for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets->begin(); it != rFacets->end(); ++it ) - { - glVertex((*rPoints)[it->_aulPoints[0]]); - glVertex((*rPoints)[it->_aulPoints[1]]); - glVertex((*rPoints)[it->_aulPoints[2]]); - } - glEnd(); - } -} - -/** - * Renders the gravity points of a subset of triangles. - */ -void SoFCMeshFaceSet::drawPoints(const MeshCore::MeshPointArray * rPoints, - const MeshCore::MeshFacetArray* rFacets, SbBool needNormals, SbBool ccw) const -{ - int mod = rFacets->size()/MaximumTriangles+1; - - float size = std::min((float)mod,3.0f); - glPointSize(size); - - if (needNormals) - { - glBegin(GL_POINTS); - int ct=0; - if ( ccw ) { - for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets->begin(); it != rFacets->end(); ++it, ct++ ) - { - if ( ct%mod==0 ) { - const MeshCore::MeshPoint& v0 = (*rPoints)[it->_aulPoints[0]]; - const MeshCore::MeshPoint& v1 = (*rPoints)[it->_aulPoints[1]]; - const MeshCore::MeshPoint& v2 = (*rPoints)[it->_aulPoints[2]]; - - // Calculate the normal n = (v1-v0)x(v2-v0) - float n[3]; - n[0] = (v1.y-v0.y)*(v2.z-v0.z)-(v1.z-v0.z)*(v2.y-v0.y); - n[1] = (v1.z-v0.z)*(v2.x-v0.x)-(v1.x-v0.x)*(v2.z-v0.z); - n[2] = (v1.x-v0.x)*(v2.y-v0.y)-(v1.y-v0.y)*(v2.x-v0.x); - - // Calculate the center point p=(v0+v1+v2)/3 - float p[3]; - p[0] = (v0.x+v1.x+v2.x)/3.0f; - p[1] = (v0.y+v1.y+v2.y)/3.0f; - p[2] = (v0.z+v1.z+v2.z)/3.0f; - glNormal3fv(n); - glVertex3fv(p); - } - } - } else { - for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets->begin(); it != rFacets->end(); ++it, ct++ ) - { - if ( ct%mod==0 ) { - const MeshCore::MeshPoint& v0 = (*rPoints)[it->_aulPoints[0]]; - const MeshCore::MeshPoint& v1 = (*rPoints)[it->_aulPoints[1]]; - const MeshCore::MeshPoint& v2 = (*rPoints)[it->_aulPoints[2]]; - - // Calculate the normal n = -(v1-v0)x(v2-v0) - float n[3]; - n[0] = -((v1.y-v0.y)*(v2.z-v0.z)-(v1.z-v0.z)*(v2.y-v0.y)); - n[1] = -((v1.z-v0.z)*(v2.x-v0.x)-(v1.x-v0.x)*(v2.z-v0.z)); - n[2] = -((v1.x-v0.x)*(v2.y-v0.y)-(v1.y-v0.y)*(v2.x-v0.x)); - - // Calculate the center point p=(v0+v1+v2)/3 - float p[3]; - p[0] = (v0.x+v1.x+v2.x)/3.0f; - p[1] = (v0.y+v1.y+v2.y)/3.0f; - p[2] = (v0.z+v1.z+v2.z)/3.0f; - glNormal3fv(n); - glVertex3fv(p); - } - } - } - glEnd(); - } - else - { - glBegin(GL_POINTS); - int ct=0; - for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets->begin(); it != rFacets->end(); ++it, ct++ ) - { - if (ct%mod==0) { - const MeshCore::MeshPoint& v0 = (*rPoints)[it->_aulPoints[0]]; - const MeshCore::MeshPoint& v1 = (*rPoints)[it->_aulPoints[1]]; - const MeshCore::MeshPoint& v2 = (*rPoints)[it->_aulPoints[2]]; - // Calculate the center point p=(v0+v1+v2)/3 - float p[3]; - p[0] = (v0.x+v1.x+v2.x)/3.0f; - p[1] = (v0.y+v1.y+v2.y)/3.0f; - p[2] = (v0.z+v1.z+v2.z)/3.0f; - glVertex3fv(p); - } - } - glEnd(); - } -} - -// test bbox intersection -//static SbBool -//SoFCMeshFaceSet_ray_intersect(SoRayPickAction * action, const SbBox3f & box) -//{ -// if (box.isEmpty()) return FALSE; -// return action->intersect(box, TRUE); -//} - -/** - * Calculates picked point based on primitives generated by subclasses. - */ -void -SoFCMeshFaceSet::rayPick(SoRayPickAction * action) -{ - //if (this->shouldRayPick(action)) { - // this->computeObjectSpaceRay(action); - - // const SoBoundingBoxCache* bboxcache = getBoundingBoxCache(); - // if (!bboxcache || !bboxcache->isValid(action->getState()) || - // SoFCMeshFaceSet_ray_intersect(action, bboxcache->getProjectedBox())) { - // this->generatePrimitives(action); - // } - //} - inherited::rayPick(action); -} - -/** Sets the point indices, the geometric points and the normal for each triangle. - * If the number of triangles exceeds \a MaximumTriangles then only a triangulation of - * a rough model is filled in instead. This is due to performance issues. - * \see createTriangleDetail(). - */ -void SoFCMeshFaceSet::generatePrimitives(SoAction* action) -{ - SoState* state = action->getState(); - const MeshCore::MeshPointArray * rPoints = SoFCMeshVertexElement::get(state); - const MeshCore::MeshFacetArray * rFacets = SoFCMeshFacetElement::get(state); - if ( !rPoints || rPoints->size() < 3 ) - return; - if ( !rFacets || rPoints->size() < 1 ) - return; - -#if 0 - // In case we have too many triangles we just create a rough model of the original mesh - if ( this->MaximumTriangles < rFacets->size() ) { - // We notify this shape when the data has changed because just counting the number of triangles won't always work. - // - if ( meshChanged ) { - try { - createProxyModel(rPoints, rFacets, FALSE); - meshChanged = false; - } catch (const Base::MemoryException&) { - Base::Console().Log("Not enough memory to create a proxy model, use its bounding box instead\n"); - try { - // try to create a triangulation of the bbox instead - createProxyModel(rPoints, rFacets, TRUE); - meshChanged = false; - } catch (const Base::MemoryException&) { - Base::Console().Log("Not enough memory to make the object pickable\n"); - return; - } - } - } - SoPrimitiveVertex vertex; - beginShape(action, TRIANGLES, 0); - try - { - int i=0; - while ( ifindMaterialBinding(state); - - // Create the information when moving over or picking into the scene - SoPrimitiveVertex vertex; - SoPointDetail pointDetail; - SoFaceDetail faceDetail; - - vertex.setDetail(&pointDetail); - - beginShape(action, TRIANGLES, &faceDetail); - try - { - for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets->begin(); it != rFacets->end(); ++it ) - { - const MeshCore::MeshPoint& v0 = (*rPoints)[it->_aulPoints[0]]; - const MeshCore::MeshPoint& v1 = (*rPoints)[it->_aulPoints[1]]; - const MeshCore::MeshPoint& v2 = (*rPoints)[it->_aulPoints[2]]; - - // Calculate the normal n = (v1-v0)x(v2-v0) - SbVec3f n; - n[0] = (v1.y-v0.y)*(v2.z-v0.z)-(v1.z-v0.z)*(v2.y-v0.y); - n[1] = (v1.z-v0.z)*(v2.x-v0.x)-(v1.x-v0.x)*(v2.z-v0.z); - n[2] = (v1.x-v0.x)*(v2.y-v0.y)-(v1.y-v0.y)*(v2.x-v0.x); - - // Set the normal - vertex.setNormal(n); - - // Vertex 0 - if (mbind == PER_VERTEX_INDEXED || mbind == PER_FACE_INDEXED) { - pointDetail.setMaterialIndex(it->_aulPoints[0]); - vertex.setMaterialIndex(it->_aulPoints[0]); - } - pointDetail.setCoordinateIndex(it->_aulPoints[0]); - vertex.setPoint(sbvec3f(v0)); - shapeVertex(&vertex); - - // Vertex 1 - if (mbind == PER_VERTEX_INDEXED || mbind == PER_FACE_INDEXED) { - pointDetail.setMaterialIndex(it->_aulPoints[1]); - vertex.setMaterialIndex(it->_aulPoints[1]); - } - pointDetail.setCoordinateIndex(it->_aulPoints[1]); - vertex.setPoint(sbvec3f(v1)); - shapeVertex(&vertex); - - // Vertex 2 - if (mbind == PER_VERTEX_INDEXED || mbind == PER_FACE_INDEXED) { - pointDetail.setMaterialIndex(it->_aulPoints[2]); - vertex.setMaterialIndex(it->_aulPoints[2]); - } - pointDetail.setCoordinateIndex(it->_aulPoints[2]); - vertex.setPoint(sbvec3f(v2)); - shapeVertex(&vertex); - - // Increment for the next face - faceDetail.incFaceIndex(); - } - } catch (const Base::MemoryException&) { - Base::Console().Log("Not enough memory to generate primitives\n"); - } - - endShape(); -#if 0 - } -#endif -} - -/** - * If the number of triangles exceeds \a MaximumTriangles 0 is returned. This means that the client programmer needs to implement itself to get the - * index of the picked triangle. If the number of triangles doesn't exceed \a MaximumTriangles SoShape::createTriangleDetail() gets called. - * Against the default OpenInventor implementation which returns 0 as well Coin3d fills in the point and face indices. - */ -SoDetail * SoFCMeshFaceSet::createTriangleDetail(SoRayPickAction * action, - const SoPrimitiveVertex * v1, - const SoPrimitiveVertex * v2, - const SoPrimitiveVertex * v3, - SoPickedPoint * pp) -{ -#if 0 - if ( this->MaximumTriangles < countTriangles(action) ) { - return 0; - } else { -#endif - SoDetail* detail = inherited::createTriangleDetail(action, v1, v2, v3, pp); - return detail; -#if 0 - } -#endif -} - -/** - * Sets the bounding box of the mesh to \a box and its center to \a center. - */ -void SoFCMeshFaceSet::computeBBox(SoAction *action, SbBox3f &box, SbVec3f ¢er) -{ - SoState* state = action->getState(); - const MeshCore::MeshPointArray * rPoints = SoFCMeshVertexElement::get(state); - if (rPoints && rPoints->size() > 0) { - Base::BoundBox3f cBox; - for (MeshCore::MeshPointArray::_TConstIterator it = rPoints->begin(); it != rPoints->end(); - cBox &= (*it); - box.setBounds(SbVec3f(cBox.MinX,cBox.MinY,cBox.MinZ), - SbVec3f(cBox.MaxX,cBox.MaxY,cBox.MaxZ)); - Base::Vector3f mid = cBox.GetCenter(); - center.setValue(mid.x,mid.y,mid.z); - } - else { - box.setBounds(SbVec3f(0,0,0), SbVec3f(0,0,0)); - center.setValue(0.0f,0.0f,0.0f); - } -} - -/** - * Adds the number of the triangles to the \a SoGetPrimitiveCountAction. - */ -void SoFCMeshFaceSet::getPrimitiveCount(SoGetPrimitiveCountAction * action) -{ - if (!this->shouldPrimitiveCount(action)) - return; - SoState* state = action->getState(); - const MeshCore::MeshFacetArray * coordIndex = SoFCMeshFacetElement::get(state); - action->addNumTriangles(coordIndex->size()); -} - -/** - * Counts the number of triangles. If a mesh is not set yet it returns 0. - */ -unsigned int SoFCMeshFaceSet::countTriangles(SoAction * action) const -{ - SoState* state = action->getState(); - const MeshCore::MeshFacetArray * coordIndex = SoFCMeshFacetElement::get(state); - return coordIndex->size(); -} - -// ------------------------------------------------------- - -SO_NODE_SOURCE(SoFCMeshOpenEdgeSet); - -void SoFCMeshOpenEdgeSet::initClass() -{ - SO_NODE_INIT_CLASS(SoFCMeshOpenEdgeSet, SoShape, "Shape"); -} - -SoFCMeshOpenEdgeSet::SoFCMeshOpenEdgeSet() -{ - SO_NODE_CONSTRUCTOR(SoFCMeshOpenEdgeSet); -} - -/** - * Renders the open edges only. - */ -void SoFCMeshOpenEdgeSet::GLRender(SoGLRenderAction *action) -{ - if (shouldGLRender(action)) - { - SoState* state = action->getState(); - const MeshCore::MeshPointArray * coords = SoFCMeshVertexElement::get(state); - const MeshCore::MeshFacetArray * index = SoFCMeshFacetElement::get(state); - - SoMaterialBundle mb(action); - SoTextureCoordinateBundle tb(action, TRUE, FALSE); - SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR); - mb.sendFirst(); // make sure we have the correct material - - drawLines(coords,index); - - // Disable caching for this node - SoGLCacheContextElement::shouldAutoCache(state, SoGLCacheContextElement::DONT_AUTO_CACHE); - } -} - -/** - * Renders the triangles of the complete mesh. - */ -void SoFCMeshOpenEdgeSet::drawLines(const MeshCore::MeshPointArray * rPoints, - const MeshCore::MeshFacetArray* rFacets) const -{ - // When rendering open edges use the given line width * 3 - GLfloat lineWidth; - glGetFloatv(GL_LINE_WIDTH, &lineWidth); - glLineWidth(3.0f*lineWidth); - - // Use the data structure directly and not through MeshFacetIterator as this - // class is quite slowly (at least for rendering) - glBegin(GL_LINES); - for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets->begin(); it != rFacets->end(); ++it ) { - for ( int i=0; i<3; i++ ) { - if ( it->_aulNeighbours[i] == ULONG_MAX ) { - glVertex((*rPoints)[it->_aulPoints[i]]); - glVertex((*rPoints)[it->_aulPoints[(i+1)%3]]); - } - } - } - - glEnd(); -} - -void SoFCMeshOpenEdgeSet::generatePrimitives(SoAction* action) -{ - // do not create primitive information as an SoFCMeshFaceSet should already be used that delivers the information - SoState* state = action->getState(); - const MeshCore::MeshPointArray * rPoints = SoFCMeshVertexElement::get(state); - const MeshCore::MeshFacetArray * rFacets = SoFCMeshFacetElement::get(state); - - // Create the information when moving over or picking into the scene - SoPrimitiveVertex vertex; - SoPointDetail pointDetail; - SoLineDetail lineDetail; - - vertex.setDetail(&pointDetail); - - beginShape(action, LINES, &lineDetail); - for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets->begin(); it != rFacets->end(); ++it ) - { - for ( int i=0; i<3; i++ ) { - if ( it->_aulNeighbours[i] == ULONG_MAX ) { - const MeshCore::MeshPoint& v0 = (*rPoints)[it->_aulPoints[i]]; - const MeshCore::MeshPoint& v1 = (*rPoints)[it->_aulPoints[(i+1)%3]]; - - // Vertex 0 - pointDetail.setCoordinateIndex(it->_aulPoints[i]); - vertex.setPoint(sbvec3f(v0)); - shapeVertex(&vertex); - - // Vertex 1 - pointDetail.setCoordinateIndex(it->_aulPoints[(i+1)%3]); - vertex.setPoint(sbvec3f(v1)); - shapeVertex(&vertex); - - // Increment for the next open edge - lineDetail.incLineIndex(); - } - } - } - - endShape(); -} - -/** - * Sets the bounding box of the mesh to \a box and its center to \a center. - */ -void SoFCMeshOpenEdgeSet::computeBBox(SoAction *action, SbBox3f &box, SbVec3f ¢er) -{ - SoState* state = action->getState(); - const MeshCore::MeshPointArray * rPoints = SoFCMeshVertexElement::get(state); - if (rPoints && rPoints->size() > 0) { - Base::BoundBox3f cBox; - for (MeshCore::MeshPointArray::_TConstIterator it = rPoints->begin(); it != rPoints->end(); - ++it) - ; - //cBox &= (*it); - box.setBounds(SbVec3f(cBox.MinX,cBox.MinY,cBox.MinZ), - SbVec3f(cBox.MaxX,cBox.MaxY,cBox.MaxZ)); - Base::Vector3f mid = cBox.GetCenter(); - center.setValue(mid.x,mid.y,mid.z); - } - else { - box.setBounds(SbVec3f(0,0,0), SbVec3f(0,0,0)); - center.setValue(0.0f,0.0f,0.0f); - } -} - -/** - * Adds the number of the triangles to the \a SoGetPrimitiveCountAction. - */ -void SoFCMeshOpenEdgeSet::getPrimitiveCount(SoGetPrimitiveCountAction * action) -{ - if (!this->shouldPrimitiveCount(action)) - return; - SoState* state = action->getState(); - const MeshCore::MeshFacetArray * rFaces = SoFCMeshFacetElement::get(state); - - // Count number of open edges first - int ctEdges=0; - for ( MeshCore::MeshFacetArray::_TConstIterator jt = rFaces->begin(); jt != rFaces->end(); ++jt ) { - for ( int i=0; i<3; i++ ) { - if ( jt->_aulNeighbours[i] == ULONG_MAX ) { - ctEdges++; - } - } - } - - action->addNumLines(ctEdges); -} diff --git a/src/Mod/Mesh/Gui/SoFCMeshFaceSet.h b/src/Mod/Mesh/Gui/SoFCMeshFaceSet.h deleted file mode 100644 index 14d3837ed9..0000000000 --- a/src/Mod/Mesh/Gui/SoFCMeshFaceSet.h +++ /dev/null @@ -1,195 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2006 Werner Mayer * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - -#ifndef MESHGUI_SOFC_MESHFACESET_H -#define MESHGUI_SOFC_MESHFACESET_H - -#include -#include -#include -#include -#include -#include - -#include - - -class SoMaterialBundle; - -namespace Mesh { -class Feature; -} - -namespace MeshGui { - -class MeshGuiExport SoSFMeshFacetArray : public SoSField { - using inherited = SoSField; - - SO_SFIELD_HEADER(SoSFMeshFacetArray, MeshCore::MeshFacetArray*, MeshCore::MeshFacetArray*) - -public: - static void initClass(void); - void setValue(const MeshCore::MeshFacetArray& p); - -protected: - SbBool readBinaryValues(SoInput * in, unsigned long numarg); - SbBool read1Value(SoInput * in, unsigned long idx); - void writeBinaryValues(SoOutput * out) const; - void write1Value(SoOutput * out, unsigned long idx) const; - int getNumValuesPerLine() const; -}; - -// ------------------------------------------------------- - -class MeshGuiExport SoFCMeshFacetElement : public SoReplacedElement { - using inherited = SoReplacedElement; - - SO_ELEMENT_HEADER(SoFCMeshFacetElement); - -public: - static void initClass(void); - - virtual void init(SoState * state); - static void set(SoState * const state, SoNode * const node, const MeshCore::MeshFacetArray * const coords); - static const MeshCore::MeshFacetArray * get(SoState * const state); - static const SoFCMeshFacetElement * getInstance(SoState * state); - virtual void print(FILE * file) const; - -protected: - virtual ~SoFCMeshFacetElement(); - const MeshCore::MeshFacetArray *coordIndex; -}; - -// ------------------------------------------------------- - -class MeshGuiExport SoFCMeshFacet : public SoNode { - using inherited = SoSField; - - SO_NODE_HEADER(SoFCMeshFacet); - -public: - static void initClass(void); - SoFCMeshFacet(void); - - SoSFMeshFacetArray coordIndex; - - virtual void doAction(SoAction * action); - virtual void GLRender(SoGLRenderAction * action); - virtual void callback(SoCallbackAction * action); - virtual void getBoundingBox(SoGetBoundingBoxAction * action); - virtual void pick(SoPickAction * action); - virtual void getPrimitiveCount(SoGetPrimitiveCountAction * action); - -protected: - virtual ~SoFCMeshFacet(); -}; - -// ------------------------------------------------------- - -/** - * \brief The SoFCMeshFaceSet class renders the mesh data structure. - * It does basically the same as SoFCMeshNode by rendering directly the FreeCAD mesh structure whereas this class follows more the Inventor way. - * While SoFCMeshFaceSet has a pointer to the mesh structure as a whole for SoFCMeshFaceSet the mesh is split into two nodes: - * an SoFCMeshVertex has a field that holds a pointer to vertex array and SoFCMeshFacet has a field that holds a pointer to the face array. - * - * The advantage of separating the mesh structure is higher flexibility. E.g. to render open edges the class SoFCMeshOpenEdgeSet just takes the - * SoFCMeshVertex and SoFCMeshFaceSet nodes from the stack and does the rendering. The client programmer just has to add the an SoFCMeshOpenEdgeSet - * instance to the Inventor tree -- nothing more. Another advantage is that memory is saved when writing the scene to a file. - * The actual data is only hold and written by SoFCMeshVertex and SoFCMeshFaceSet. Normally, no shape nodes have to save further data to the file. - * @author Werner Mayer - */ -class MeshGuiExport SoFCMeshFaceSet : public SoShape { - using inherited = SoShape; - - SO_NODE_HEADER(SoFCMeshFaceSet); - -public: - static void initClass(); - SoFCMeshFaceSet(); - - unsigned int MaximumTriangles; - -protected: - virtual void GLRender(SoGLRenderAction *action); - virtual void computeBBox(SoAction *action, SbBox3f &box, SbVec3f ¢er); - virtual void getPrimitiveCount(SoGetPrimitiveCountAction * action); - virtual void rayPick (SoRayPickAction *action); - virtual void generatePrimitives(SoAction *action); - virtual SoDetail * createTriangleDetail(SoRayPickAction * action, - const SoPrimitiveVertex * v1, - const SoPrimitiveVertex * v2, - const SoPrimitiveVertex * v3, - SoPickedPoint * pp); - -private: - enum Binding { - OVERALL = 0, - PER_FACE_INDEXED, - PER_VERTEX_INDEXED, - NONE = OVERALL - }; - -private: - // Force using the reference count mechanism. - virtual ~SoFCMeshFaceSet() {} - virtual void notify(SoNotList * list); - Binding findMaterialBinding(SoState * const state) const; - // Draw faces - void drawFaces(const MeshCore::MeshPointArray *, const MeshCore::MeshFacetArray*, SoMaterialBundle* mb, Binding bind, - SbBool needNormals, SbBool ccw) const; - void drawPoints(const MeshCore::MeshPointArray *, const MeshCore::MeshFacetArray*, SbBool needNormals, SbBool ccw) const; - unsigned int countTriangles(SoAction * action) const; - void createProxyModel(const MeshCore::MeshPointArray *, const MeshCore::MeshFacetArray*, SbBool simplest); - -private: - bool meshChanged; - SoMFVec3f point; - SoMFInt32 coordIndex; -}; - -// ------------------------------------------------------------ - -class MeshGuiExport SoFCMeshOpenEdgeSet : public SoShape { - using inherited = SoShape; - - SO_NODE_HEADER(SoFCMeshOpenEdgeSet); - -public: - static void initClass(); - SoFCMeshOpenEdgeSet(); - -protected: - virtual void GLRender(SoGLRenderAction *action); - virtual void computeBBox(SoAction *action, SbBox3f &box, SbVec3f ¢er); - virtual void getPrimitiveCount(SoGetPrimitiveCountAction * action); - virtual void generatePrimitives(SoAction *action); -private: - // Force using the reference count mechanism. - virtual ~SoFCMeshOpenEdgeSet() {} - void drawLines(const MeshCore::MeshPointArray *, const MeshCore::MeshFacetArray*) const ; -}; - -} // namespace MeshGui - - -#endif // MESHGUI_SOFC_MESHFACESET_H - diff --git a/src/Mod/Mesh/Gui/SoFCMeshNode.cpp b/src/Mod/Mesh/Gui/SoFCMeshNode.cpp deleted file mode 100644 index 0214454e84..0000000000 --- a/src/Mod/Mesh/Gui/SoFCMeshNode.cpp +++ /dev/null @@ -1,763 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2006 Werner Mayer * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - -#include "PreCompiled.h" -#ifndef _PreComp_ -# ifdef FC_OS_WIN32 -# include -# endif -# ifdef FC_OS_MACOSX -# include -# else -# include -# endif -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#include -#include -#include -#include -#include - -#include "SoFCMeshNode.h" - - -using namespace MeshGui; - -/** - * class SoFCMeshNode - * \brief The SoFCMeshNode class is designed to render huge meshes. - * - * The SoFCMeshNode is an Inventor shape node that is designed to render huge meshes. If the mesh exceeds a certain number of triangles - * and the user does some intersections (e.g. moving, rotating, zooming, spinning, etc.) with the mesh then the GLRender() method renders - * only the gravity points of a subset of the triangles. - * If there is no user interaction with the mesh then all triangles are rendered. - * The limit of maximum allowed triangles can be specified in \a MaximumTriangles, the default value is set to 500.000. - * - * The GLRender() method checks the status of the SoFCInteractiveElement to decide to be in interactive mode or not. - * To take advantage of this facility the client programmer must set the status of the SoFCInteractiveElement to \a true - * if there is a user interaction and set the status to \a false if not. This can be done e.g. in the actualRedraw() method of - * the viewer. - * \author Werner Mayer - */ - -// Helper functions: draw vertices -inline void glVertex(const MeshCore::MeshPoint& _v) -{ - float v[3]; - v[0]=_v.x; v[1]=_v.y;v[2]=_v.z; - glVertex3fv(v); -} - -// Helper functions: draw normal -inline void glNormal(const Base::Vector3f& _n) -{ - float n[3]; - n[0]=_n.x; n[1]=_n.y;n[2]=_n.z; - glNormal3fv(n); -} - -// Helper functions: draw normal -inline void glNormal(float* n) -{ - glNormal3fv(n); -} - -// Helper function: convert Vec to SbVec3f -inline SbVec3f sbvec3f(const Base::Vector3f& _v) { - return SbVec3f(_v.x, _v.y, _v.z); -} - -SO_NODE_SOURCE(SoFCMeshNode); - -void SoFCMeshNode::initClass() -{ - SO_NODE_INIT_CLASS(SoFCMeshNode, SoShape, "Shape"); -} - -SoFCMeshNode::SoFCMeshNode() : MaximumTriangles(500000), _mesh(0), _ctPrimitives(0) -{ - SO_NODE_CONSTRUCTOR(SoFCMeshNode); - SO_NODE_ADD_FIELD(point, (0.0f, 0.0f, 0.0f)); - SO_NODE_ADD_FIELD(coordIndex,(0)); -} - -void SoFCMeshNode::notify(SoNotList * node) -{ - SoShape::notify(node); -} - -/** - * Sets the mesh. - */ -void SoFCMeshNode::setMesh(const Mesh::MeshObject* mesh) -{ - _mesh = mesh; -} - -/** - * Creates a rough mesh model from the original data attached to a grid in case \a simplest is false. The number of grids - * in each direction doesn't exceed 50. - * If \a simplest is true then the model is built from the bounding box instead. - * - * For every move event the complete data set must be iterated to refresh internal Inventor data @see generatePrimitives(). - * Doing this very often for very huge data sets slows down the system noticeably. Using a rough model as proxy instead of the original - * data set can speed up the user interaction extremely. - * @note The proxy will never be displayed. It's just used for the picking mechanism. - * @note The usage of the proxy might be confusing a little bit due to the fact that some details get lost. So it'll be possible - * to pick the data set where no data seem to be. - */ -void SoFCMeshNode::createRoughModel(bool simplest) -{ - const Base::BoundBox3f& cBox = _mesh->getKernel().GetBoundBox(); - - if ( simplest ) { - int triangles[36] = { - 0,1,2,0,2,3, - 0,1,5,0,5,4, - 0,4,7,0,7,3, - 6,7,4,6,4,5, - 6,2,3,6,3,7, - 6,1,2,6,5,1 - }; - SbVec3f points[8] = { - SbVec3f(cBox.MinX,cBox.MinY,cBox.MinZ), - SbVec3f(cBox.MaxX,cBox.MinY,cBox.MinZ), - SbVec3f(cBox.MaxX,cBox.MaxY,cBox.MinZ), - SbVec3f(cBox.MinX,cBox.MaxY,cBox.MinZ), - SbVec3f(cBox.MinX,cBox.MinY,cBox.MaxZ), - SbVec3f(cBox.MaxX,cBox.MinY,cBox.MaxZ), - SbVec3f(cBox.MaxX,cBox.MaxY,cBox.MaxZ), - SbVec3f(cBox.MinX,cBox.MaxY,cBox.MaxZ) - }; - - coordIndex.setValues(0,36,triangles); - point.setValues (0,8,points); - } else { - // Check the boundings and the average edge length - float fAvgLen = 5.0f * MeshCore::MeshAlgorithm(_mesh->getKernel()).GetAverageEdgeLength(); - - // create maximum 50 grids in each direction - fAvgLen = std::max(fAvgLen, (cBox.MaxX-cBox.MinX)/50.0f); - fAvgLen = std::max(fAvgLen, (cBox.MaxY-cBox.MinY)/50.0f); - fAvgLen = std::max(fAvgLen, (cBox.MaxZ-cBox.MinZ)/50.0f); - - MeshCore::MeshGeomFacet face; - std::vector facets; - - MeshCore::MeshPointGrid cGrid(_mesh->getKernel(), fAvgLen); - unsigned long ulMaxX, ulMaxY, ulMaxZ; - cGrid.GetCtGrids(ulMaxX, ulMaxY, ulMaxZ); - MeshCore::MeshGridIterator cIter(cGrid); - - for ( cIter.Init(); cIter.More(); cIter.Next() ) { - if ( cIter.GetCtElements() > 0 ) { - unsigned long ulX, ulY, ulZ; - cIter.GetGridPos(ulX, ulY, ulZ); - Base::BoundBox3f cBox = cIter.GetBoundBox(); - - if ( ulX == 0 || (ulX-1 >= 0 && cGrid.GetCtElements(ulX-1,ulY, ulZ) == 0) ) { - face._aclPoints[0].Set(cBox.MinX,cBox.MinY,cBox.MinZ); - face._aclPoints[1].Set(cBox.MinX,cBox.MinY,cBox.MaxZ); - face._aclPoints[2].Set(cBox.MinX,cBox.MaxY,cBox.MinZ); - facets.push_back(face); - face._aclPoints[0].Set(cBox.MinX,cBox.MaxY,cBox.MaxZ); - face._aclPoints[1].Set(cBox.MinX,cBox.MaxY,cBox.MinZ); - face._aclPoints[2].Set(cBox.MinX,cBox.MinY,cBox.MaxZ); - facets.push_back(face); - } - if ( ulX+1 == ulMaxX || (ulX+1 < ulMaxX && cGrid.GetCtElements(ulX+1,ulY, ulZ) == 0) ) { - face._aclPoints[0].Set(cBox.MaxX,cBox.MinY,cBox.MinZ); - face._aclPoints[1].Set(cBox.MaxX,cBox.MaxY,cBox.MinZ); - face._aclPoints[2].Set(cBox.MaxX,cBox.MinY,cBox.MaxZ); - facets.push_back(face); - face._aclPoints[0].Set(cBox.MaxX,cBox.MaxY,cBox.MaxZ); - face._aclPoints[1].Set(cBox.MaxX,cBox.MinY,cBox.MaxZ); - face._aclPoints[2].Set(cBox.MaxX,cBox.MaxY,cBox.MinZ); - facets.push_back(face); - } - if ( ulY == 0 || (ulY-1 >= 0 && cGrid.GetCtElements(ulX,ulY-1, ulZ) == 0) ) { - face._aclPoints[0].Set(cBox.MinX,cBox.MinY,cBox.MaxZ); - face._aclPoints[1].Set(cBox.MinX,cBox.MinY,cBox.MinZ); - face._aclPoints[2].Set(cBox.MaxX,cBox.MinY,cBox.MaxZ); - facets.push_back(face); - face._aclPoints[0].Set(cBox.MaxX,cBox.MinY,cBox.MinZ); - face._aclPoints[1].Set(cBox.MaxX,cBox.MinY,cBox.MaxZ); - face._aclPoints[2].Set(cBox.MinX,cBox.MinY,cBox.MinZ); - facets.push_back(face); - } - if ( ulY+1 == ulMaxY || (ulY+1 < ulMaxY && cGrid.GetCtElements(ulX,ulY+1, ulZ) == 0) ) { - face._aclPoints[0].Set(cBox.MaxX,cBox.MaxY,cBox.MinZ); - face._aclPoints[1].Set(cBox.MinX,cBox.MaxY,cBox.MinZ); - face._aclPoints[2].Set(cBox.MaxX,cBox.MaxY,cBox.MaxZ); - facets.push_back(face); - face._aclPoints[0].Set(cBox.MinX,cBox.MaxY,cBox.MaxZ); - face._aclPoints[1].Set(cBox.MaxX,cBox.MaxY,cBox.MaxZ); - face._aclPoints[2].Set(cBox.MinX,cBox.MaxY,cBox.MinZ); - facets.push_back(face); - } - if ( ulZ == 0 || (ulZ-1 >= 0 && cGrid.GetCtElements(ulX,ulY, ulZ-1) == 0) ) { - face._aclPoints[0].Set(cBox.MaxX,cBox.MinY,cBox.MinZ); - face._aclPoints[1].Set(cBox.MinX,cBox.MinY,cBox.MinZ); - face._aclPoints[2].Set(cBox.MaxX,cBox.MaxY,cBox.MinZ); - facets.push_back(face); - face._aclPoints[0].Set(cBox.MinX,cBox.MaxY,cBox.MinZ); - face._aclPoints[1].Set(cBox.MaxX,cBox.MaxY,cBox.MinZ); - face._aclPoints[2].Set(cBox.MinX,cBox.MinY,cBox.MinZ); - facets.push_back(face); - } - if ( ulZ+1 == ulMaxZ || (ulZ+1 < ulMaxZ && cGrid.GetCtElements(ulX,ulY, ulZ+1) == 0) ) { - face._aclPoints[0].Set(cBox.MaxX,cBox.MinY,cBox.MaxZ); - face._aclPoints[1].Set(cBox.MaxX,cBox.MaxY,cBox.MaxZ); - face._aclPoints[2].Set(cBox.MinX,cBox.MinY,cBox.MaxZ); - facets.push_back(face); - face._aclPoints[0].Set(cBox.MinX,cBox.MaxY,cBox.MaxZ); - face._aclPoints[1].Set(cBox.MinX,cBox.MinY,cBox.MaxZ); - face._aclPoints[2].Set(cBox.MaxX,cBox.MaxY,cBox.MaxZ); - facets.push_back(face); - } - } - } - - MeshCore::MeshKernel kernel; kernel = facets; - const MeshCore::MeshPointArray& rPoints = kernel.GetPoints(); - const MeshCore::MeshFacetArray& rFacets = kernel.GetFacets(); - - point.enableNotify(false); - point.setNum(rPoints.size()); - unsigned int pos=0; - for (MeshCore::MeshPointArray::_TConstIterator cP=rPoints.begin(); cP!=rPoints.end(); ++cP) - point.set1Value(pos++,cP->x,cP->y,cP->z); - point.enableNotify(true); - - coordIndex.enableNotify(false); - coordIndex.setNum(3*rFacets.size()); - pos=0; - for (MeshCore::MeshFacetArray::_TConstIterator cF=rFacets.begin(); cF!=rFacets.end(); ++cF){ - coordIndex.set1Value(pos++,cF->_aulPoints[0]); - coordIndex.set1Value(pos++,cF->_aulPoints[1]); - coordIndex.set1Value(pos++,cF->_aulPoints[2]); - } - coordIndex.enableNotify(true); - - point.touch(); - coordIndex.touch(); - -#ifdef FC_DEBUG - std::ofstream str( "bbox.stl", std::ios::out | std::ios::binary ); - MeshCore::MeshOutput aWriter(kernel); - aWriter.SaveBinarySTL( str ); -#endif - } -} - -/** - * Either renders the complete mesh or only a subset of the points. - */ -void SoFCMeshNode::GLRender(SoGLRenderAction *action) -{ - if (_mesh && shouldGLRender(action)) - { - SoState* state = action->getState(); - - SbBool mode = Gui::SoFCInteractiveElement::get(state); - - //Binding mbind = this->findMaterialBinding(state); - - SoMaterialBundle mb(action); - //SoTextureCoordinateBundle tb(action, true, false); - - SbBool needNormals = !mb.isColorOnly()/* || tb.isFunction()*/; - mb.sendFirst(); // make sure we have the correct material - - //SbBool ccw = TRUE; - //if (SoShapeHintsElement::getVertexOrdering(state) == SoShapeHintsElement::CLOCKWISE) - // ccw = FALSE; - - if ( mode == false || countTriangles() <= this->MaximumTriangles ) - drawFaces(needNormals); - else - drawPoints(needNormals); - - // Disable caching for this node - SoGLCacheContextElement::shouldAutoCache(state, SoGLCacheContextElement::DONT_AUTO_CACHE); - } -} - -/** - * Renders the triangles of the complete mesh. - */ -void SoFCMeshNode::drawFaces(SbBool needNormals) const -{ - // Use the data structure directly and not through MeshFacetIterator as this - // class is quite slowly (at least for rendering) - const MeshCore::MeshPointArray& rPoints = _mesh->getKernel().GetPoints(); - const MeshCore::MeshFacetArray& rFacets = _mesh->getKernel().GetFacets(); - - if (needNormals) - { - glBegin(GL_TRIANGLES); - for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); ++it ) - { - const MeshCore::MeshPoint& v0 = rPoints[it->_aulPoints[0]]; - const MeshCore::MeshPoint& v1 = rPoints[it->_aulPoints[1]]; - const MeshCore::MeshPoint& v2 = rPoints[it->_aulPoints[2]]; - - // Calculate the normal n = (v1-v0)x(v2-v0) - float n[3]; - n[0] = (v1.y-v0.y)*(v2.z-v0.z)-(v1.z-v0.z)*(v2.y-v0.y); - n[1] = (v1.z-v0.z)*(v2.x-v0.x)-(v1.x-v0.x)*(v2.z-v0.z); - n[2] = (v1.x-v0.x)*(v2.y-v0.y)-(v1.y-v0.y)*(v2.x-v0.x); - - glNormal(n); - glVertex(v0); - glVertex(v1); - glVertex(v2); - } - glEnd(); - } - else - { - glBegin(GL_TRIANGLES); - for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); ++it ) - { - glVertex(rPoints[it->_aulPoints[0]]); - glVertex(rPoints[it->_aulPoints[1]]); - glVertex(rPoints[it->_aulPoints[2]]); - } - glEnd(); - } -} - -/** - * Renders the gravity points of a subset of triangles. - */ -void SoFCMeshNode::drawPoints(SbBool needNormals) const -{ - // Use the data structure directly and not through MeshFacetIterator as this - // class is quite slowly (at least for rendering) - const MeshCore::MeshPointArray& rPoints = _mesh->getKernel().GetPoints(); - const MeshCore::MeshFacetArray& rFacets = _mesh->getKernel().GetFacets(); - int mod = rFacets.size()/MaximumTriangles+1; - - float size = std::min((float)mod,3.0f); - glPointSize(size); - - if (needNormals) - { - glBegin(GL_POINTS); - int ct=0; - for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); ++it, ct++ ) - { - if ( ct%mod==0 ) { - const MeshCore::MeshPoint& v0 = rPoints[it->_aulPoints[0]]; - const MeshCore::MeshPoint& v1 = rPoints[it->_aulPoints[1]]; - const MeshCore::MeshPoint& v2 = rPoints[it->_aulPoints[2]]; - - // Calculate the normal n = (v1-v0)x(v2-v0) - float n[3]; - n[0] = (v1.y-v0.y)*(v2.z-v0.z)-(v1.z-v0.z)*(v2.y-v0.y); - n[1] = (v1.z-v0.z)*(v2.x-v0.x)-(v1.x-v0.x)*(v2.z-v0.z); - n[2] = (v1.x-v0.x)*(v2.y-v0.y)-(v1.y-v0.y)*(v2.x-v0.x); - - // Calculate the center point p=(v0+v1+v2)/3 - float p[3]; - p[0] = (v0.x+v1.x+v2.x)/3.0f; - p[1] = (v0.y+v1.y+v2.y)/3.0f; - p[2] = (v0.z+v1.z+v2.z)/3.0f; - glNormal3fv(n); - glVertex3fv(p); - } - } - glEnd(); - } - else - { - glBegin(GL_POINTS); - int ct=0; - for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); ++it, ct++ ) - { - if (ct%mod==0) { - const MeshCore::MeshPoint& v0 = rPoints[it->_aulPoints[0]]; - const MeshCore::MeshPoint& v1 = rPoints[it->_aulPoints[1]]; - const MeshCore::MeshPoint& v2 = rPoints[it->_aulPoints[2]]; - // Calculate the center point p=(v0+v1+v2)/3 - float p[3]; - p[0] = (v0.x+v1.x+v2.x)/3.0f; - p[1] = (v0.y+v1.y+v2.y)/3.0f; - p[2] = (v0.z+v1.z+v2.z)/3.0f; - glVertex3fv(p); - } - } - glEnd(); - } -} - -/** Sets the point indices, the geometric points and the normal for each triangle. - * If the number of triangles exceeds \a MaximumTriangles then only a triangulation of - * a rough model is filled in instead. This is due to performance issues. - * \see createTriangleDetail(). - */ -void SoFCMeshNode::generatePrimitives(SoAction* action) -{ - if (_mesh) - { - // Use the data structure directly and not through MeshFacetIterator as this - // class is quite slowly (at least for rendering) - const MeshCore::MeshPointArray& rPoints = _mesh->getKernel().GetPoints(); - const MeshCore::MeshFacetArray& rFacets = _mesh->getKernel().GetFacets(); - - // In case we have too many triangles we just create a rough model of the original mesh - if ( this->MaximumTriangles < rFacets.size() ) { - //FIXME: We should notify this shape when the data has changed. - //Just counting the number of triangles won't always work. - if ( rFacets.size() != _ctPrimitives ) { - _ctPrimitives = rFacets.size(); - createRoughModel(false); - } - SoPrimitiveVertex vertex; - beginShape(action, TRIANGLES, 0); - int i=0; - while ( i_aulPoints[0]]; - const MeshCore::MeshPoint& v1 = rPoints[it->_aulPoints[1]]; - const MeshCore::MeshPoint& v2 = rPoints[it->_aulPoints[2]]; - - // Calculate the normal n = (v1-v0)x(v2-v0) - SbVec3f n; - n[0] = (v1.y-v0.y)*(v2.z-v0.z)-(v1.z-v0.z)*(v2.y-v0.y); - n[1] = (v1.z-v0.z)*(v2.x-v0.x)-(v1.x-v0.x)*(v2.z-v0.z); - n[2] = (v1.x-v0.x)*(v2.y-v0.y)-(v1.y-v0.y)*(v2.x-v0.x); - - // Set the normal - vertex.setNormal(n); - - // Vertex 0 - pointDetail.setCoordinateIndex(it->_aulPoints[0]); - vertex.setPoint(sbvec3f(v0)); - shapeVertex(&vertex); - - // Vertex 1 - pointDetail.setCoordinateIndex(it->_aulPoints[1]); - vertex.setPoint(sbvec3f(v1)); - shapeVertex(&vertex); - - // Vertex 2 - pointDetail.setCoordinateIndex(it->_aulPoints[2]); - vertex.setPoint(sbvec3f(v2)); - shapeVertex(&vertex); - - // Increment for the next face - faceDetail.incFaceIndex(); - } - - endShape(); - } - } -} - -/** - * If the number of triangles exceeds \a MaximumTriangles 0 is returned. This means that the client programmer needs to implement itself to get the - * index of the picked triangle. If the number of triangles doesn't exceed \a MaximumTriangles SoShape::createTriangleDetail() gets called. - * Against the default OpenInventor implementation which returns 0 as well Coin3d fills in the point and face indices. - */ -SoDetail * SoFCMeshNode::createTriangleDetail(SoRayPickAction * action, - const SoPrimitiveVertex * v1, - const SoPrimitiveVertex * v2, - const SoPrimitiveVertex * v3, - SoPickedPoint * pp) -{ - if ( this->MaximumTriangles < countTriangles() ) { - return 0; - } else { - SoDetail* detail = inherited::createTriangleDetail(action, v1, v2, v3, pp); - return detail; - } -} - -/** - * Sets the bounding box of the mesh to \a box and its center to \a center. - */ -void SoFCMeshNode::computeBBox(SoAction *action, SbBox3f &box, SbVec3f ¢er) -{ - // Get the bbox directly from the mesh kernel - if (countTriangles() > 0) { - const Base::BoundBox3f& cBox = _mesh->getKernel().GetBoundBox(); - box.setBounds(SbVec3f(cBox.MinX,cBox.MinY,cBox.MinZ), - SbVec3f(cBox.MaxX,cBox.MaxY,cBox.MaxZ)); - Base::Vector3f mid = cBox.GetCenter(); - center.setValue(mid.x,mid.y,mid.z); - } - else { - box.setBounds(SbVec3f(0,0,0), SbVec3f(0,0,0)); - center.setValue(0.0f,0.0f,0.0f); - } -} - -/** - * Adds the number of the triangles to the \a SoGetPrimitiveCountAction. - */ -void SoFCMeshNode::getPrimitiveCount(SoGetPrimitiveCountAction * action) -{ - if (!this->shouldPrimitiveCount(action)) - return; - action->addNumTriangles(countTriangles()); -} - -/** - * Counts the number of triangles. If a mesh is not set yet it returns 0. - */ -unsigned int SoFCMeshNode::countTriangles() const -{ - return (_mesh ? _mesh->countFacets() : 0); -} - -/** - * Writes out the mesh node. - */ -void SoFCMeshNode::write( SoWriteAction* action ) -{ - SoOutput * out = action->getOutput(); - - if (out->getStage() == SoOutput::COUNT_REFS) { - this->addWriteReference(out, FALSE); - } - else if (out->getStage() == SoOutput::WRITE) { - const MeshCore::MeshPointArray& rPoints = _mesh->getKernel().GetPoints(); - const MeshCore::MeshFacetArray& rFacets = _mesh->getKernel().GetFacets(); - if (this->writeHeader(out, FALSE, FALSE)) - return; - point.setNum(rPoints.size()); - unsigned int pos=0; - for (MeshCore::MeshPointArray::_TConstIterator cP=rPoints.begin(); cP!=rPoints.end(); ++cP) - point.set1Value(pos++,cP->x,cP->y,cP->z); - coordIndex.setNum(3*rFacets.size()); - pos=0; - for (MeshCore::MeshFacetArray::_TConstIterator cF=rFacets.begin(); cF!=rFacets.end(); ++cF){ - coordIndex.set1Value(pos++,cF->_aulPoints[0]); - coordIndex.set1Value(pos++,cF->_aulPoints[1]); - coordIndex.set1Value(pos++,cF->_aulPoints[2]); - } - this->getFieldData()->write(out, this); - this->writeFooter(out); - point.deleteValues(0); - coordIndex.deleteValues(0); - } -} - -/** - * Reads in the mesh node from the input stream. - */ -SbBool SoFCMeshNode::readInstance( SoInput* in, unsigned short flags ) -{ - SbBool ret = inherited::readInstance(in, flags); - - MeshCore::MeshPointArray cPoints; - cPoints.resize(point.getNum()); - for (int i=0; igetState(); - - SoMaterialBundle mb(action); - SoTextureCoordinateBundle tb(action, TRUE, FALSE); - SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR); - mb.sendFirst(); // make sure we have the correct material - - drawLines(); - - // Disable caching for this node - SoGLCacheContextElement::shouldAutoCache(state, SoGLCacheContextElement::DONT_AUTO_CACHE); - } -} - -/** - * Renders the triangles of the complete mesh. - */ -void SoFCMeshOpenEdge::drawLines() const -{ - // Use the data structure directly and not through MeshFacetIterator as this - // class is quite slowly (at least for rendering) - const MeshCore::MeshPointArray& rPoints = _mesh->getKernel().GetPoints(); - const MeshCore::MeshFacetArray& rFacets = _mesh->getKernel().GetFacets(); - - // When rendering open edges use the given line width * 3 - GLfloat lineWidth; - glGetFloatv(GL_LINE_WIDTH, &lineWidth); - glLineWidth(3.0f*lineWidth); - - - glBegin(GL_LINES); - for ( MeshCore::MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); ++it ) { - for ( int i=0; i<3; i++ ) { - if ( it->_aulNeighbours[i] == ULONG_MAX ) { - glVertex(rPoints[it->_aulPoints[i]]); - glVertex(rPoints[it->_aulPoints[(i+1)%3]]); - } - } - } - - glEnd(); -} - -void SoFCMeshOpenEdge::generatePrimitives(SoAction* action) -{ - // do not create primitive information as an SoFCMeshNode should already be used that delivers the information -} - -/** - * Sets the bounding box of the mesh to \a box and its center to \a center. - */ -void SoFCMeshOpenEdge::computeBBox(SoAction *action, SbBox3f &box, SbVec3f ¢er) -{ - // Get the bbox directly from the mesh kernel - if (_mesh) { - const Base::BoundBox3f& cBox = _mesh->getKernel().GetBoundBox(); - box.setBounds(SbVec3f(cBox.MinX,cBox.MinY,cBox.MinZ), - SbVec3f(cBox.MaxX,cBox.MaxY,cBox.MaxZ)); - Base::Vector3f mid = cBox.GetCenter(); - center.setValue(mid.x,mid.y,mid.z); - } - else { - box.setBounds(SbVec3f(0,0,0), SbVec3f(0,0,0)); - center.setValue(0.0f,0.0f,0.0f); - } -} - -/** - * Adds the number of the triangles to the \a SoGetPrimitiveCountAction. - */ -void SoFCMeshOpenEdge::getPrimitiveCount(SoGetPrimitiveCountAction * action) -{ - if (!this->shouldPrimitiveCount(action)) - return; - - // Count number of open edges first - int ctEdges=0; - - const MeshCore::MeshFacetArray& rFaces = _mesh->getKernel().GetFacets(); - for ( MeshCore::MeshFacetArray::_TConstIterator jt = rFaces.begin(); jt != rFaces.end(); ++jt ) { - for ( int i=0; i<3; i++ ) { - if ( jt->_aulNeighbours[i] == ULONG_MAX ) { - ctEdges++; - } - } - } - - action->addNumLines(ctEdges); -} diff --git a/src/Mod/Mesh/Gui/SoFCMeshNode.h b/src/Mod/Mesh/Gui/SoFCMeshNode.h deleted file mode 100644 index 8a8a687ca2..0000000000 --- a/src/Mod/Mesh/Gui/SoFCMeshNode.h +++ /dev/null @@ -1,110 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2006 Werner Mayer * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - -#ifndef MESHGUI_SOFC_MESH_NODE_H -#define MESHGUI_SOFC_MESH_NODE_H - -#include -#include -#include - - -namespace Mesh { -class MeshObject; -} - -namespace MeshGui { - -class MeshGuiExport SoFCMeshNode : public SoShape { - using inherited = SoShape; - - SO_NODE_HEADER(SoFCMeshNode); - -public: - static void initClass(); - SoFCMeshNode(); - void setMesh(const Mesh::MeshObject* mesh); - - virtual void write( SoWriteAction* action ); - unsigned int MaximumTriangles; - -protected: - virtual void GLRender(SoGLRenderAction *action); - virtual void computeBBox(SoAction *action, SbBox3f &box, SbVec3f ¢er); - virtual void getPrimitiveCount(SoGetPrimitiveCountAction * action); - virtual void generatePrimitives(SoAction *action); - virtual SoDetail * createTriangleDetail(SoRayPickAction * action, - const SoPrimitiveVertex * v1, - const SoPrimitiveVertex * v2, - const SoPrimitiveVertex * v3, - SoPickedPoint * pp); - - virtual SbBool readInstance( SoInput* in, unsigned short flags ); - -private: - // Force using the reference count mechanism. - virtual ~SoFCMeshNode() {} - virtual void notify(SoNotList * list); - // Draw faces - void drawFaces(SbBool needNormals) const; - void drawPoints(SbBool needNormals) const; - unsigned int countTriangles() const; - void createRoughModel(bool simplest); - -private: - const Mesh::MeshObject* _mesh; - unsigned int _ctPrimitives; - SoMFVec3f point; - SoMFInt32 coordIndex; -}; - -// ------------------------------------------------------------ - -class MeshGuiExport SoFCMeshOpenEdge : public SoShape { - using inherited = SoShape; - - SO_NODE_HEADER(SoFCMeshOpenEdge); - -public: - static void initClass(); - SoFCMeshOpenEdge(); - void setMesh(const Mesh::MeshObject* mesh); - -protected: - virtual void GLRender(SoGLRenderAction *action); - virtual void computeBBox(SoAction *action, SbBox3f &box, SbVec3f ¢er); - virtual void getPrimitiveCount(SoGetPrimitiveCountAction * action); - virtual void generatePrimitives(SoAction *action); -private: - // Force using the reference count mechanism. - virtual ~SoFCMeshOpenEdge() {} - void drawLines() const ; - -private: - const Mesh::MeshObject* _mesh; -}; - -} // namespace MeshGui - - -#endif // MESHGUI_SOFC_MESH_NODE_H - diff --git a/src/Mod/Mesh/Gui/SoFCMeshVertex.cpp b/src/Mod/Mesh/Gui/SoFCMeshVertex.cpp deleted file mode 100644 index 0a14ac526b..0000000000 --- a/src/Mod/Mesh/Gui/SoFCMeshVertex.cpp +++ /dev/null @@ -1,340 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2006 Werner Mayer * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - -#include "PreCompiled.h" -#ifndef _PreComp_ -# ifdef FC_OS_WIN32 -# include -# endif -# ifdef FC_OS_MACOSX -# include -# else -# include -# endif - -# include -# include -# include -# include -# include -# include -# include -#endif - -#include "SoFCMeshVertex.h" - - -using namespace MeshGui; - -// Defines all required member variables and functions for a -// single-value field -SO_SFIELD_SOURCE(SoSFMeshPointArray, MeshCore::MeshPointArray*, MeshCore::MeshPointArray*); - - -void SoSFMeshPointArray::initClass() -{ - // This macro takes the name of the class and the name of the - // parent class - SO_SFIELD_INIT_CLASS(SoSFMeshPointArray, SoSField); -} - -void SoSFMeshPointArray::setValue(const MeshCore::MeshPointArray& p) -{ - SoSFMeshPointArray::setValue(const_cast(&p)); -} - -// This reads the value of a field from a file. It returns FALSE if the value could not be read -// successfully. -SbBool SoSFMeshPointArray::readValue(SoInput *in) -{ - // This macro is convenient for reading with error detection. -#define READ_VAL(val) \ - if (!in->read(val)) { \ - SoReadError::post(in, "Premature end of file"); \ - return FALSE; \ - } - - value = new MeshCore::MeshPointArray(); - - // ** Binary format ****************************************************** - if (in->isBinary()) { - int numtoread; - READ_VAL(numtoread); - - // Sanity checking on the value, to avoid barfing on corrupt - // files. - if (numtoread < 0) { - SoReadError::post(in, "invalid number of values in field: %d", - numtoread); - return FALSE; - } - - value->resize(numtoread); - if (!this->readBinaryValues(in, numtoread)) { - return FALSE; - } - } - - // ** ASCII format ******************************************************* - else { - char c; - READ_VAL(c); - if (c == '[') { - unsigned long currentidx = 0; - - READ_VAL(c); - if (c == ']') { - // Zero values -- done. :^) - } - else { - in->putBack(c); - - while (TRUE) { - // makeRoom() makes sure the allocation strategy is decent. - if (currentidx >= value->size()) value->resize(currentidx + 1); - - if (!this->read1Value(in, currentidx++)) - return FALSE; - - READ_VAL(c); - if (c == ',') { READ_VAL(c); } // Treat trailing comma as whitespace. - - // That was the last array element, we're done. - if (c == ']') { break; } - - if (c == '}') { - SoReadError::post(in, "Premature end of array, got '%c'", c); - return FALSE; - } - - in->putBack(c); - } - } - - // Fit array to number of items. - value->resize(currentidx); - } - else { - in->putBack(c); - value->resize(1); - if (!this->read1Value(in, 0)) - return FALSE; - } - } - -#undef READ_VAL - - // We need to trigger the notification chain here, as this function - // can be used on a node in a scene graph in any state -- not only - // during initial scene graph import. - this->valueChanged(); - - return TRUE; -} - -SbBool SoSFMeshPointArray::readBinaryValues(SoInput * in, unsigned long numarg) -{ - assert(in->isBinary()); - assert(numarg >= 0); - - for (unsigned long i=0; i < numarg; i++) if (!this->read1Value(in, i)) return FALSE; - return TRUE; -} - -SbBool SoSFMeshPointArray::read1Value(SoInput * in, unsigned long idx) -{ - assert(idx < value->size()); - MeshCore::MeshPoint& v = (*value)[idx]; - return (in->read(v.x) && in->read(v.y) && in->read(v.z)); -} - -int SoSFMeshPointArray::getNumValuesPerLine() const -{ - return 1; -} - -// This writes the value of a field to a file. -void SoSFMeshPointArray::writeValue(SoOutput *out) const -{ - if (out->isBinary()) { - this->writeBinaryValues(out); - return; - } - - const unsigned long count = value->size(); - if ((count > 1) || (count == 0)) out->write("[ "); - - out->incrementIndent(); - - for (unsigned long i=0; i < count; i++) { - this->write1Value(out, i); - - if (i != count-1) { - if (((i+1) % this->getNumValuesPerLine()) == 0) { - out->write(",\n"); - out->indent(); - // for alignment - out->write(" "); - } - else { - out->write(", "); - } - } - } - if ((count > 1) || (count == 0)) out->write(" ]"); - - out->decrementIndent(); -} - -void SoSFMeshPointArray::writeBinaryValues(SoOutput * out) const -{ - assert(out->isBinary()); - - const unsigned int count = (unsigned int)value->size(); - out->write(count); - for (unsigned int i=0; i < count; i++) this->write1Value(out, i); -} - -void SoSFMeshPointArray::write1Value(SoOutput * out, unsigned long idx) const -{ - const MeshCore::MeshPoint& v = (*value)[idx]; - out->write(v.x); - if (!out->isBinary()) out->write(' '); - out->write(v.y); - if (!out->isBinary()) out->write(' '); - out->write(v.z); -} - -// ------------------------------------------------------- - -SO_ELEMENT_SOURCE(SoFCMeshVertexElement); - -void SoFCMeshVertexElement::initClass() -{ - SO_ELEMENT_INIT_CLASS(SoFCMeshVertexElement, inherited); -} - -void SoFCMeshVertexElement::init(SoState * state) -{ - inherited::init(state); - this->coords3D = 0; -} - -SoFCMeshVertexElement::~SoFCMeshVertexElement() -{ -} - -void SoFCMeshVertexElement::set(SoState * const state, SoNode * const node, const MeshCore::MeshPointArray * const coords) -{ - SoFCMeshVertexElement * elem = (SoFCMeshVertexElement *) - SoReplacedElement::getElement(state, classStackIndex, node); - if (elem) { - elem->coords3D = coords; - elem->nodeId = node->getNodeId(); - } -} - -const MeshCore::MeshPointArray * SoFCMeshVertexElement::get(SoState * const state) -{ - return SoFCMeshVertexElement::getInstance(state)->coords3D; -} - -const SoFCMeshVertexElement * SoFCMeshVertexElement::getInstance(SoState * state) -{ - return (const SoFCMeshVertexElement *) SoElement::getConstElement(state, classStackIndex); -} - -void SoFCMeshVertexElement::print(FILE * /* file */) const -{ -} - -// ------------------------------------------------------- - -SO_NODE_SOURCE(SoFCMeshVertex); - -/*! - Constructor. -*/ -SoFCMeshVertex::SoFCMeshVertex(void) -{ - SO_NODE_CONSTRUCTOR(SoFCMeshVertex); - - SO_NODE_ADD_FIELD(point, (0)); -} - -/*! - Destructor. -*/ -SoFCMeshVertex::~SoFCMeshVertex() -{ -} - -// Doc from superclass. -void SoFCMeshVertex::initClass(void) -{ - SO_NODE_INIT_CLASS(SoFCMeshVertex, SoNode, "Node"); - - SO_ENABLE(SoGetBoundingBoxAction, SoFCMeshVertexElement); - SO_ENABLE(SoGLRenderAction, SoFCMeshVertexElement); - SO_ENABLE(SoPickAction, SoFCMeshVertexElement); - SO_ENABLE(SoCallbackAction, SoFCMeshVertexElement); - SO_ENABLE(SoGetPrimitiveCountAction, SoFCMeshVertexElement); -} - -// Doc from superclass. -void SoFCMeshVertex::doAction(SoAction * action) -{ - SoFCMeshVertexElement::set(action->getState(), this, point.getValue()); -// SoCoordinateElement::set3(action->getState(), this, -// point.getNum(), point.getValues(0)); -} - -// Doc from superclass. -void SoFCMeshVertex::GLRender(SoGLRenderAction * action) -{ - SoFCMeshVertex::doAction(action); -} - -// Doc from superclass. -void SoFCMeshVertex::callback(SoCallbackAction * action) -{ - SoFCMeshVertex::doAction(action); -} - -// Doc from superclass. -void SoFCMeshVertex::pick(SoPickAction * action) -{ - SoFCMeshVertex::doAction(action); -} - -// Doc from superclass. -void SoFCMeshVertex::getBoundingBox(SoGetBoundingBoxAction * action) -{ - SoFCMeshVertex::doAction(action); -} - -// Doc from superclass. -void SoFCMeshVertex::getPrimitiveCount(SoGetPrimitiveCountAction * action) -{ - SoFCMeshVertex::doAction(action); -} - diff --git a/src/Mod/Mesh/Gui/SoFCMeshVertex.h b/src/Mod/Mesh/Gui/SoFCMeshVertex.h deleted file mode 100644 index 13c4adafdf..0000000000 --- a/src/Mod/Mesh/Gui/SoFCMeshVertex.h +++ /dev/null @@ -1,100 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2006 Werner Mayer * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - -#ifndef MESHGUI_SOFCMESHVERTEX_H -#define MESHGUI_SOFCMESHVERTEX_H - -#include -#include - -#include - - -namespace MeshGui { - -class MeshGuiExport SoSFMeshPointArray : public SoSField { - using inherited = SoSField; - - SO_SFIELD_HEADER(SoSFMeshPointArray, MeshCore::MeshPointArray*, MeshCore::MeshPointArray*) - -public: - static void initClass(void); - void setValue(const MeshCore::MeshPointArray& p); - -protected: - SbBool readBinaryValues(SoInput * in, unsigned long numarg); - SbBool read1Value(SoInput * in, unsigned long idx); - void writeBinaryValues(SoOutput * out) const; - void write1Value(SoOutput * out, unsigned long idx) const; - int getNumValuesPerLine() const; -}; - -// ------------------------------------------------------- - -class MeshGuiExport SoFCMeshVertexElement : public SoReplacedElement { - using inherited = SoReplacedElement; - - SO_ELEMENT_HEADER(SoFCMeshVertexElement); - -public: - static void initClass(void); - - virtual void init(SoState * state); - static void set(SoState * const state, SoNode * const node, const MeshCore::MeshPointArray * const coords); - static const MeshCore::MeshPointArray * get(SoState * const state); - static const SoFCMeshVertexElement * getInstance(SoState * state); - virtual void print(FILE * file) const; - -protected: - virtual ~SoFCMeshVertexElement(); - const MeshCore::MeshPointArray *coords3D; -}; - -// ------------------------------------------------------- - -class MeshGuiExport SoFCMeshVertex : public SoNode { - using inherited = SoSField; - - SO_NODE_HEADER(SoFCMeshVertex); - -public: - static void initClass(void); - SoFCMeshVertex(void); - - SoSFMeshPointArray point; - - virtual void doAction(SoAction * action); - virtual void GLRender(SoGLRenderAction * action); - virtual void callback(SoCallbackAction * action); - virtual void getBoundingBox(SoGetBoundingBoxAction * action); - virtual void pick(SoPickAction * action); - virtual void getPrimitiveCount(SoGetPrimitiveCountAction * action); - -protected: - virtual ~SoFCMeshVertex(); -}; - -} // namespace MeshGui - - -#endif // MESHGUI_SOFCMESHVERTEX_H - diff --git a/src/Mod/Mesh/Gui/ViewProviderMeshNode.cpp b/src/Mod/Mesh/Gui/ViewProviderMeshNode.cpp deleted file mode 100644 index 45849a2efa..0000000000 --- a/src/Mod/Mesh/Gui/ViewProviderMeshNode.cpp +++ /dev/null @@ -1,404 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2006 Werner Mayer * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#include "PreCompiled.h" - -#ifndef _PreComp_ -# include -# include -# include -# include -# include -# include -#endif - -/// Here the FreeCAD includes sorted by Base,App,Gui...... -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ViewProvider.h" -#include "ViewProviderMeshNode.h" - - -using namespace MeshGui; - - -App::PropertyFloatConstraint::Constraints ViewProviderMeshNode::floatRange = {1.0f,64.0f,1.0f}; - -PROPERTY_SOURCE(MeshGui::ViewProviderMeshNode, Gui::ViewProviderGeometryObject) - -ViewProviderMeshNode::ViewProviderMeshNode() : pcOpenEdge(0), m_bEdit(false) -{ - ADD_PROPERTY(LineWidth,(2.0f)); - LineWidth.setConstraints(&floatRange); - ADD_PROPERTY(PointSize,(2.0f)); - PointSize.setConstraints(&floatRange); - ADD_PROPERTY(OpenEdges,(false)); - - pOpenColor = new SoBaseColor(); - setOpenEdgeColorFrom(ShapeColor.getValue()); - pOpenColor->ref(); - - pcLineStyle = new SoDrawStyle(); - pcLineStyle->ref(); - pcLineStyle->style = SoDrawStyle::LINES; - pcLineStyle->lineWidth = LineWidth.getValue(); - - pcPointStyle = new SoDrawStyle(); - pcPointStyle->ref(); - pcPointStyle->style = SoDrawStyle::POINTS; - pcPointStyle->pointSize = PointSize.getValue(); - - // read the correct shape color from the preferences - Base::Reference hGrp = Gui::WindowParameter::getDefaultParameter()->GetGroup("Mod/Mesh"); - App::Color color = ShapeColor.getValue(); - unsigned long current = color.getPackedValue(); - unsigned long setting = hGrp->GetUnsigned("MeshColor", current); - if ( current != setting ) - { - color.setPackedValue((uint32_t)setting); - ShapeColor.setValue(color); - } -} - -ViewProviderMeshNode::~ViewProviderMeshNode() -{ - pOpenColor->unref(); - pcLineStyle->unref(); - pcPointStyle->unref(); -} - -void ViewProviderMeshNode::onChanged(const App::Property* prop) -{ - if ( prop == &LineWidth ) { - pcLineStyle->lineWidth = LineWidth.getValue(); - } else if ( prop == &PointSize ) { - pcPointStyle->pointSize = PointSize.getValue(); - } else if ( prop == &OpenEdges ) { - showOpenEdges( OpenEdges.getValue() ); - } else { - // Set the inverse color for open edges - if ( prop == &ShapeColor ) { - setOpenEdgeColorFrom(ShapeColor.getValue()); - } else if ( prop == &ShapeMaterial ) { - setOpenEdgeColorFrom(ShapeMaterial.getValue().diffuseColor); - } - ViewProviderGeometryObject::onChanged(prop); - } -} - -void ViewProviderMeshNode::setOpenEdgeColorFrom( const App::Color& c ) -{ - float r=1.0f-c.r; r = r < 0.5f ? 0.0f : 1.0f; - float g=1.0f-c.g; g = g < 0.5f ? 0.0f : 1.0f; - float b=1.0f-c.b; b = b < 0.5f ? 0.0f : 1.0f; - pOpenColor->rgb.setValue(r, g, b); -} - -void ViewProviderMeshNode::attach(App::DocumentObject *pcFeat) -{ - ViewProviderGeometryObject::attach(pcFeat); - - // only one selection node for the mesh - const Mesh::Feature* meshFeature = dynamic_cast(pcFeat); - MeshGui::SoFCMeshNode* mesh = new MeshGui::SoFCMeshNode(); - mesh->setMesh(meshFeature->Mesh.getValuePtr()); - pcHighlight->addChild(mesh); - - - // faces - SoGroup* pcFlatRoot = new SoGroup(); - - // read the correct shape color from the preferences - Base::Reference hGrp = Gui::WindowParameter::getDefaultParameter()->GetGroup("Mod/Mesh"); - bool twoSide = hGrp->GetBool("TwoSideRendering", true); - if ( twoSide ) - { - // enable two-side rendering - SoShapeHints * flathints = new SoShapeHints; - flathints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE; - flathints->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE; - pcFlatRoot->addChild(flathints); - } - - pcFlatRoot->addChild(pcShapeMaterial); - pcFlatRoot->addChild(pcHighlight); - addDisplayMaskMode(pcFlatRoot, "Flat"); - - // points - SoGroup* pcPointRoot = new SoGroup(); - pcPointRoot->addChild(pcPointStyle); - pcPointRoot->addChild(pcFlatRoot); - addDisplayMaskMode(pcPointRoot, "Point"); - - // wires - SoLightModel* pcLightModel = new SoLightModel(); - pcLightModel->model = SoLightModel::BASE_COLOR; - SoGroup* pcWireRoot = new SoGroup(); - pcWireRoot->addChild(pcLineStyle); - pcWireRoot->addChild(pcLightModel); - pcWireRoot->addChild(pcShapeMaterial); - pcWireRoot->addChild(pcHighlight); - addDisplayMaskMode(pcWireRoot, "Wireframe"); - - // faces+wires - SoGroup* pcFlatWireRoot = new SoGroup(); - pcFlatWireRoot->addChild(pcFlatRoot); - pcFlatWireRoot->addChild(pcWireRoot); - addDisplayMaskMode(pcFlatWireRoot, "FlatWireframe"); -} - -void ViewProviderMeshNode::updateData(const App::Property*) -{ - // Needs to update internal bounding box caches - pcHighlight->touch(); -} - -QIcon ViewProviderMeshNode::getIcon() const -{ - const char * Mesh_Feature_xpm[] = { - "16 16 4 1", - ". c None", - "# c #000000", - "s c #BEC2FC", - "g c #00FF00", - ".......##.......", - "....#######.....", - "..##ggg#ggg#....", - "##ggggg#gggg##..", - "#g#ggg#gggggg##.", - "#gg#gg#gggg###s.", - "#gg#gg#gg##gg#s.", - "#ggg#####ggg#ss.", - "#gggg##gggg#ss..", - ".#g##g#gggg#s...", - ".##ggg#ggg#ss...", - ".##gggg#g#ss....", - "..s#####g#s.....", - "....sss##ss.....", - "........ss......", - "................"}; - QPixmap px(Mesh_Feature_xpm); - return px; -} - -void ViewProviderMeshNode::setDisplayMode(const char* ModeName) -{ - if ( strcmp("Shaded",ModeName)==0 ) - setDisplayMaskMode("Flat"); - else if ( strcmp("Points",ModeName)==0 ) - setDisplayMaskMode("Point"); - else if ( strcmp("Shaded+Wireframe",ModeName)==0 ) - setDisplayMaskMode("FlatWireframe"); - else if ( strcmp("Wireframe",ModeName)==0 ) - setDisplayMaskMode("Wireframe"); - - ViewProviderGeometryObject::setDisplayMode( ModeName ); -} - -std::vector ViewProviderMeshNode::getDisplayModes(void) const -{ - std::vector StrList; - - // add your own modes - StrList.push_back("Shaded"); - StrList.push_back("Wireframe"); - StrList.push_back("Shaded+Wireframe"); - StrList.push_back("Points"); - - return StrList; -} - -bool ViewProviderMeshNode::setEdit(int ModNum) -{ - if ( m_bEdit ) - return true; - m_bEdit = true; - return true; -} - -void ViewProviderMeshNode::unsetEdit(void) -{ - m_bEdit = false; -} - -const char* ViewProviderMeshNode::getEditModeName(void) -{ - return "Polygon picking"; -} - -bool ViewProviderMeshNode::handleEvent(const SoEvent * const ev,Gui::View3DInventorViewer &Viewer) -{ - if ( m_bEdit ) - { - unsetEdit(); - std::vector clPoly = Viewer.getPickedPolygon(); - if ( clPoly.size() < 3 ) - return true; - if ( clPoly.front() != clPoly.back() ) - clPoly.push_back(clPoly.front()); - - // get the normal of the front clipping plane - SbVec3f b,n; - Viewer.getNearPlane(b, n); - Base::Vector3f cPoint(b[0],b[1],b[2]), cNormal(n[0],n[1],n[2]); - SoCamera* pCam = Viewer.getCamera(); - SbViewVolume vol = pCam->getViewVolume (); - - // create a tool shape from these points - std::vector aFaces; - bool ok = ViewProviderMesh::createToolMesh( clPoly, vol, cNormal, aFaces ); - - // Get the attached mesh property - Mesh::PropertyMeshKernel& meshProp = ((Mesh::Feature*)pcObject)->Mesh; - - // Get the facet indices inside the tool mesh - std::vector indices; - MeshCore::MeshKernel cToolMesh; - cToolMesh = aFaces; - MeshCore::MeshFacetGrid cGrid(meshProp.getValue().getKernel()); - MeshCore::MeshAlgorithm cAlg(meshProp.getValue().getKernel()); - cAlg.GetFacetsFromToolMesh(cToolMesh, cNormal, cGrid, indices); - meshProp.deleteFacetIndices( indices ); - - // update open edge display if needed -// if ( pcOpenEdge ) -// { -// showOpenEdges(false); -// showOpenEdges(true); -// } - - Viewer.render(); - if ( !ok ) // note: the mouse grabbing needs to be released - //QMessageBox::warning(Viewer.getWidget(),"Invalid polygon","The picked polygon seems to have self-overlappings.\n\nThis could lead to strange rersults."); - Base::Console().Message("The picked polygon seems to have self-overlappings. This could lead to strange results."); - } - - return false; -} - -void ViewProviderMeshNode::showOpenEdges(bool show) -{ -#if 1 - if ( show ) { - pcOpenEdge = new SoSeparator(); - pcOpenEdge->addChild(pcLineStyle); - pcOpenEdge->addChild(pOpenColor); - - const Mesh::Feature* meshFeature = dynamic_cast(pcObject); - MeshGui::SoFCMeshOpenEdge* mesh = new MeshGui::SoFCMeshOpenEdge(); - mesh->setMesh(meshFeature->Mesh.getValuePtr()); - pcOpenEdge->addChild(mesh); - - // add to the highlight node - pcHighlight->addChild(pcOpenEdge); - } else if (pcOpenEdge) { - // remove the node and destroy the data - pcHighlight->removeChild(pcOpenEdge); - pcOpenEdge = 0; - } -#else - if ( show ) { - pcOpenEdge = new SoSeparator(); - pcOpenEdge->addChild(pcLineStyle); - pcOpenEdge->addChild(pOpenColor); - SoCoordinate3* points = new SoCoordinate3(); - pcOpenEdge->addChild(points); - SoLineSet* lines = new SoLineSet(); - pcOpenEdge->addChild(lines); - // add to the highlight node - pcHighlight->addChild(pcOpenEdge); - - // Build up the array of border points - int index=0; - const MeshCore::MeshKernel& rMesh = dynamic_cast(pcObject)->getMesh(); - const MeshCore::MeshFacetArray& rFaces = rMesh.GetFacets(); - const MeshCore::MeshPointArray& rPoint = rMesh.GetPoints(); - - // Count number of open edges first - int ctEdges=0; - for ( MeshCore::MeshFacetArray::_TConstIterator jt = rFaces.begin(); jt != rFaces.end(); ++jt ) { - for ( int i=0; i<3; i++ ) { - if ( jt->_aulNeighbours[i] == ULONG_MAX ) { - ctEdges++; - } - } - } - - // disable internal notification for speedup - points->enableNotify(false); - lines->enableNotify(false); - - points->point.setNum(2*ctEdges); - lines->numVertices.setNum(ctEdges); - for ( MeshCore::MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it ) { - for ( int i=0; i<3; i++ ) { - if ( it->_aulNeighbours[i] == ULONG_MAX ) { - const MeshCore::MeshPoint& cP0 = rPoint[it->_aulPoints[i]]; - const MeshCore::MeshPoint& cP1 = rPoint[it->_aulPoints[(i+1)%3]]; - points->point.set1Value(index++, cP0.x, cP0.y, cP0.z); - points->point.set1Value(index++, cP1.x, cP1.y, cP1.z); - lines->numVertices.set1Value(index/2-1,2); - } - } - } - - // enable notification - points->enableNotify(true); - lines->enableNotify(true); - points->touch(); - lines->touch(); - } else { - // remove the node and destroy the data - pcHighlight->removeChild(pcOpenEdge); - pcOpenEdge = 0; - } -#endif -} diff --git a/src/Mod/Mesh/Gui/ViewProviderMeshNode.h b/src/Mod/Mesh/Gui/ViewProviderMeshNode.h deleted file mode 100644 index 674cf48e4f..0000000000 --- a/src/Mod/Mesh/Gui/ViewProviderMeshNode.h +++ /dev/null @@ -1,97 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2006 Werner Mayer * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - -#ifndef MESHGUI_VIEWPROVIDERMESHNODE_H -#define MESHGUI_VIEWPROVIDERMESHNODE_H - -#include -#include - -#include -#include - -class SbViewVolume; -class SoBaseColor; - -namespace Gui { - class SoFCSelection; - class AbstractMouseModel; -} -namespace MeshGui { - -/** - * The ViewProviderMeshNode class creates a node representing the mesh data structure. - * @author Werner Mayer - */ -class MeshGuiExport ViewProviderMeshNode : public Gui::ViewProviderGeometryObject -{ - PROPERTY_HEADER(TriangulationGui::ViewProviderMeshNode); - -public: - ViewProviderMeshNode(); - virtual ~ViewProviderMeshNode(); - - // Display properties - App::PropertyFloatConstraint LineWidth; - App::PropertyFloatConstraint PointSize; - App::PropertyBool OpenEdges; - - void attach(App::DocumentObject *pcFeat); - virtual void updateData(const App::Property*); - virtual QIcon getIcon() const; - virtual void setDisplayMode(const char* ModeName); - virtual std::vector getDisplayModes() const; - - /** @name Polygon picking */ - //@{ - // Draws the picked polygon - bool handleEvent(const SoEvent * const ev,Gui::View3DInventorViewer &Viewer); - /// Sets the edit mnode - bool setEdit(int ModNum=0); - /// Unsets the edit mode - void unsetEdit(void); - /// Returns the edit mode - const char* getEditModeName(void); - //@} - -protected: - /// get called by the container whenever a property has been changed - void onChanged(const App::Property* prop); - void showOpenEdges( bool ); - void setOpenEdgeColorFrom( const App::Color& col ); - - SoDrawStyle *pcLineStyle; - SoDrawStyle *pcPointStyle; - SoSeparator *pcOpenEdge; - SoBaseColor *pOpenColor; - -private: - bool m_bEdit; - - static App::PropertyFloatConstraint::Constraints floatRange; -}; - -} // namespace MeshGui - - -#endif // MESHGUI_VIEWPROVIDERMESHNODE_H -