[Mesh] remove unused file
- unused since a while and also don't compile when adding them to CMake
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,195 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2006 Werner Mayer <werner.wm.mayer@gmx.de> *
|
||||
* *
|
||||
* 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 <Inventor/elements/SoReplacedElement.h>
|
||||
#include <Inventor/fields/SoMFInt32.h>
|
||||
#include <Inventor/fields/SoMFVec3f.h>
|
||||
#include <Inventor/fields/SoSField.h>
|
||||
#include <Inventor/nodes/SoNode.h>
|
||||
#include <Inventor/nodes/SoShape.h>
|
||||
|
||||
#include <Mod/Mesh/App/Core/Elements.h>
|
||||
|
||||
|
||||
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
|
||||
|
||||
@@ -1,763 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2006 Werner Mayer <werner.wm.mayer@gmx.de> *
|
||||
* *
|
||||
* 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 <windows.h>
|
||||
# endif
|
||||
# ifdef FC_OS_MACOSX
|
||||
# include <OpenGL/gl.h>
|
||||
# else
|
||||
# include <GL/gl.h>
|
||||
# endif
|
||||
# include <Inventor/SbBox.h>
|
||||
# include <Inventor/SoOutput.h>
|
||||
# include <Inventor/SoPrimitiveVertex.h>
|
||||
# include <Inventor/actions/SoGLRenderAction.h>
|
||||
# include <Inventor/actions/SoGetPrimitiveCountAction.h>
|
||||
# include <Inventor/actions/SoWriteAction.h>
|
||||
# include <Inventor/bundles/SoMaterialBundle.h>
|
||||
# include <Inventor/bundles/SoTextureCoordinateBundle.h>
|
||||
# include <Inventor/details/SoFaceDetail.h>
|
||||
# include <Inventor/details/SoPointDetail.h>
|
||||
# include <Inventor/elements/SoGLCacheContextElement.h>
|
||||
# include <Inventor/elements/SoLazyElement.h>
|
||||
# include <Inventor/misc/SoState.h>
|
||||
#endif
|
||||
|
||||
#include <Gui/SoFCInteractiveElement.h>
|
||||
#include <Mod/Mesh/App/Mesh.h>
|
||||
#include <Mod/Mesh/App/Core/Algorithm.h>
|
||||
#include <Mod/Mesh/App/Core/Elements.h>
|
||||
#include <Mod/Mesh/App/Core/Grid.h>
|
||||
|
||||
#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<float>(fAvgLen, (cBox.MaxX-cBox.MinX)/50.0f);
|
||||
fAvgLen = std::max<float>(fAvgLen, (cBox.MaxY-cBox.MinY)/50.0f);
|
||||
fAvgLen = std::max<float>(fAvgLen, (cBox.MaxZ-cBox.MinZ)/50.0f);
|
||||
|
||||
MeshCore::MeshGeomFacet face;
|
||||
std::vector<MeshCore::MeshGeomFacet> 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>((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<coordIndex.getNum() )
|
||||
{
|
||||
const SbVec3f& v0 = point[coordIndex[i++]];
|
||||
const SbVec3f& v1 = point[coordIndex[i++]];
|
||||
const SbVec3f& v2 = point[coordIndex[i++]];
|
||||
|
||||
// Calculate the normal n = (v1-v0)x(v2-v0)
|
||||
SbVec3f n;
|
||||
n[0] = (v1[1]-v0[1])*(v2[2]-v0[2])-(v1[2]-v0[2])*(v2[1]-v0[1]);
|
||||
n[1] = (v1[2]-v0[2])*(v2[0]-v0[0])-(v1[0]-v0[0])*(v2[2]-v0[2]);
|
||||
n[2] = (v1[0]-v0[0])*(v2[1]-v0[1])-(v1[1]-v0[1])*(v2[0]-v0[0]);
|
||||
|
||||
// Set the normal
|
||||
vertex.setNormal(n);
|
||||
|
||||
vertex.setPoint( v0 );
|
||||
shapeVertex(&vertex);
|
||||
vertex.setPoint( v1 );
|
||||
shapeVertex(&vertex);
|
||||
vertex.setPoint( v2 );
|
||||
shapeVertex(&vertex);
|
||||
}
|
||||
endShape();
|
||||
} else {
|
||||
// Create the information when moving over or picking into the scene
|
||||
SoPrimitiveVertex vertex;
|
||||
SoPointDetail pointDetail;
|
||||
SoFaceDetail faceDetail;
|
||||
|
||||
vertex.setDetail(&pointDetail);
|
||||
|
||||
beginShape(action, TRIANGLES, &faceDetail);
|
||||
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
|
||||
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; i<point.getNum(); ++i) {
|
||||
const SbVec3f& pt = point[i];
|
||||
cPoints[i].Set(pt[0],pt[1],pt[2]);
|
||||
}
|
||||
|
||||
MeshCore::MeshFacetArray cFacets;
|
||||
cFacets.resize(coordIndex.getNum()/3);
|
||||
unsigned long k=0;
|
||||
for (int j=0; j<coordIndex.getNum(); ++k) {
|
||||
cFacets[k]._aulPoints[0] = coordIndex[j++];
|
||||
cFacets[k]._aulPoints[1] = coordIndex[j++];
|
||||
cFacets[k]._aulPoints[2] = coordIndex[j++];
|
||||
}
|
||||
|
||||
point.deleteValues(0);
|
||||
coordIndex.deleteValues(0);
|
||||
|
||||
MeshCore::MeshKernel kernel;
|
||||
kernel.Adopt(cPoints, cFacets, true);
|
||||
_mesh = new Mesh::MeshObject(kernel);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
|
||||
SO_NODE_SOURCE(SoFCMeshOpenEdge);
|
||||
|
||||
void SoFCMeshOpenEdge::initClass()
|
||||
{
|
||||
SO_NODE_INIT_CLASS(SoFCMeshOpenEdge, SoShape, "Shape");
|
||||
}
|
||||
|
||||
SoFCMeshOpenEdge::SoFCMeshOpenEdge() : _mesh(0)
|
||||
{
|
||||
SO_NODE_CONSTRUCTOR(SoFCMeshOpenEdge);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the mesh.
|
||||
*/
|
||||
void SoFCMeshOpenEdge::setMesh(const Mesh::MeshObject* mesh)
|
||||
{
|
||||
_mesh = mesh;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the open edges only.
|
||||
*/
|
||||
void SoFCMeshOpenEdge::GLRender(SoGLRenderAction *action)
|
||||
{
|
||||
if (_mesh && shouldGLRender(action))
|
||||
{
|
||||
SoState* state = action->getState();
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2006 Werner Mayer <werner.wm.mayer@gmx.de> *
|
||||
* *
|
||||
* 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 <Inventor/fields/SoMFInt32.h>
|
||||
#include <Inventor/fields/SoMFVec3f.h>
|
||||
#include <Inventor/nodes/SoShape.h>
|
||||
|
||||
|
||||
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
|
||||
|
||||
@@ -1,340 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2006 Werner Mayer <werner.wm.mayer@gmx.de> *
|
||||
* *
|
||||
* 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 <windows.h>
|
||||
# endif
|
||||
# ifdef FC_OS_MACOSX
|
||||
# include <OpenGL/gl.h>
|
||||
# else
|
||||
# include <GL/gl.h>
|
||||
# endif
|
||||
|
||||
# include <Inventor/actions/SoCallbackAction.h>
|
||||
# include <Inventor/actions/SoGetBoundingBoxAction.h>
|
||||
# include <Inventor/actions/SoGetPrimitiveCountAction.h>
|
||||
# include <Inventor/actions/SoGLRenderAction.h>
|
||||
# include <Inventor/actions/SoPickAction.h>
|
||||
# include <Inventor/errors/SoReadError.h>
|
||||
# include <Inventor/misc/SoState.h>
|
||||
#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<MeshCore::MeshPointArray*>(&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);
|
||||
}
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2006 Werner Mayer <werner.wm.mayer@gmx.de> *
|
||||
* *
|
||||
* 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 <Inventor/elements/SoReplacedElement.h>
|
||||
#include <Inventor/fields/SoSField.h>
|
||||
|
||||
#include <Mod/Mesh/App/Core/Elements.h>
|
||||
|
||||
|
||||
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
|
||||
|
||||
@@ -1,404 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2006 Werner Mayer <werner.wm.mayer@gmx.de> *
|
||||
* *
|
||||
* 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 <Inventor/nodes/SoBaseColor.h>
|
||||
# include <Inventor/nodes/SoDrawStyle.h>
|
||||
# include <Inventor/nodes/SoMaterial.h>
|
||||
# include <Inventor/nodes/SoShapeHints.h>
|
||||
# include <Inventor/nodes/SoOrthographicCamera.h>
|
||||
# include <qmessagebox.h>
|
||||
#endif
|
||||
|
||||
/// Here the FreeCAD includes sorted by Base,App,Gui......
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/Sequencer.h>
|
||||
#include <Base/Tools2D.h>
|
||||
#include <Base/ViewProj.h>
|
||||
|
||||
#include <App/Document.h>
|
||||
#include <App/PropertyLinks.h>
|
||||
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/SoFCSelection.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
#include <Gui/MouseModel.h>
|
||||
#include <Gui/Selection.h>
|
||||
#include <Gui/Window.h>
|
||||
#include <Gui/View3DInventor.h>
|
||||
#include <Gui/View3DInventorViewer.h>
|
||||
|
||||
#include <Mod/Mesh/App/Core/Algorithm.h>
|
||||
#include <Mod/Mesh/App/Core/Evaluation.h>
|
||||
#include <Mod/Mesh/App/Core/Grid.h>
|
||||
#include <Mod/Mesh/App/Core/Iterator.h>
|
||||
#include <Mod/Mesh/App/Core/MeshIO.h>
|
||||
#include <Mod/Mesh/App/Core/Visitor.h>
|
||||
#include <Mod/Mesh/App/Mesh.h>
|
||||
#include <Mod/Mesh/App/MeshFeature.h>
|
||||
#include <Mod/Mesh/Gui/SoFCMeshNode.h>
|
||||
|
||||
#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<ParameterGrp> 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<Mesh::Feature*>(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<ParameterGrp> 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<std::string> ViewProviderMeshNode::getDisplayModes(void) const
|
||||
{
|
||||
std::vector<std::string> 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<SbVec2f> 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<MeshCore::MeshGeomFacet> 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<unsigned long> 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<Mesh::Feature*>(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<Mesh::Feature*>(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
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2006 Werner Mayer <werner.wm.mayer@gmx.de> *
|
||||
* *
|
||||
* 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 <Gui/ViewProviderGeometryObject.h>
|
||||
#include <Mod/Mesh/App/Core/Elements.h>
|
||||
|
||||
#include <vector>
|
||||
#include <Inventor/fields/SoSFVec2f.h>
|
||||
|
||||
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<std::string> 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
|
||||
|
||||
Reference in New Issue
Block a user