add OCC standard meshing algorithm to Mesher class

This commit is contained in:
wmayer 2016-09-07 16:39:54 +02:00
parent f37b70b141
commit 1ed35628ab
4 changed files with 172 additions and 1 deletions

View File

@ -177,6 +177,20 @@ private:
{
PyObject *shape;
static char* kwds_lindeflection[] = {"Shape", "LinearDeflection", "AngularDeflection", NULL};
PyErr_Clear();
double lindeflection=0;
double angdeflection=0.5;
if (PyArg_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "O!d|d", kwds_lindeflection,
&(Part::TopoShapePy::Type), &shape, &lindeflection, &angdeflection)) {
MeshPart::Mesher mesher(static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->getShape());
mesher.setMethod(MeshPart::Mesher::Standard);
mesher.setDeflection(lindeflection);
mesher.setAngularDeflection(angdeflection);
mesher.setRegular(true);
return Py::asObject(new Mesh::MeshPy(mesher.createMesh()));
}
static char* kwds_maxLength[] = {"Shape", "MaxLength",NULL};
PyErr_Clear();
double maxLength=0;

View File

@ -21,13 +21,21 @@
***************************************************************************/
#include "PreCompiled.h"
#include <algorithm>
#include "Mesher.h"
#include <Base/Console.h>
#include <Base/Exception.h>
#include <Base/Tools.h>
#include <Mod/Mesh/App/Mesh.h>
#include <TopoDS_Shape.hxx>
#include <BRepTools.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <StlTransfer.hxx>
#include <StlMesh_Mesh.hxx>
#include <StlMesh_MeshExplorer.hxx>
#include <Standard_Version.hxx>
#ifdef HAVE_SMESH
#include <SMESH_Gen.hxx>
@ -88,6 +96,43 @@ int MeshingOutput::sync()
return 0;
}
// ----------------------------------------------------------------------------
struct Mesher::Vertex {
static const double deflection;
Standard_Real x,y,z;
Standard_Integer i;
mutable MeshCore::MeshPoint p;
Vertex(Standard_Real X, Standard_Real Y, Standard_Real Z)
: x(X),y(Y),z(Z),i(0)
{
p.x = static_cast<float>(x);
p.y = static_cast<float>(y);
p.z = static_cast<float>(z);
}
const MeshCore::MeshPoint& toPoint() const
{
return p;
}
bool operator < (const Vertex &v) const
{
if (fabs ( this->x - v.x) >= deflection)
return this->x < v.x;
if (fabs ( this->y - v.y) >= deflection)
return this->y < v.y;
if (fabs ( this->z - v.z) >= deflection)
return this->z < v.z;
return false; // points are considered to be equal
}
};
const double Mesher::Vertex::deflection = gp::Resolution();
// ----------------------------------------------------------------------------
Mesher::Mesher(const TopoDS_Shape& s)
: shape(s)
, method(None)
@ -95,6 +140,7 @@ Mesher::Mesher(const TopoDS_Shape& s)
, maxArea(0)
, localLength(0)
, deflection(0)
, angularDeflection(0.5)
, minLen(0)
, maxLen(0)
, regular(false)
@ -116,6 +162,110 @@ Mesher::~Mesher()
Mesh::MeshObject* Mesher::createMesh() const
{
// OCC standard mesher
if (method == Standard) {
Handle_StlMesh_Mesh aMesh = new StlMesh_Mesh();
if (!shape.IsNull()) {
BRepTools::Clean(shape);
#if OCC_VERSION_HEX >= 0x060801
BRepMesh_IncrementalMesh bMesh(shape, deflection, Standard_False, angularDeflection);
StlTransfer::RetrieveMesh(shape,aMesh);
#else
StlTransfer::BuildIncrementalMesh(shape, deflection,
#if OCC_VERSION_HEX >= 0x060503
Standard_True,
#endif
aMesh);
#endif
}
MeshCore::MeshFacetArray faces;
faces.reserve(aMesh->NbTriangles());
std::set<Vertex> vertices;
Standard_Real x1, y1, z1;
Standard_Real x2, y2, z2;
Standard_Real x3, y3, z3;
std::list< std::vector<unsigned long> > meshSegments;
std::size_t numMeshFaces = 0;
StlMesh_MeshExplorer xp(aMesh);
for (Standard_Integer nbd=1;nbd<=aMesh->NbDomains();nbd++) {
std::size_t numDomainFaces = 0;
for (xp.InitTriangle(nbd); xp.MoreTriangle(); xp.NextTriangle()) {
xp.TriangleVertices(x1,y1,z1,x2,y2,z2,x3,y3,z3);
std::set<Vertex>::iterator it;
MeshCore::MeshFacet face;
// 1st vertex
Vertex v1(x1,y1,z1);
it = vertices.find(v1);
if (it == vertices.end()) {
v1.i = vertices.size();
face._aulPoints[0] = v1.i;
vertices.insert(v1);
}
else {
face._aulPoints[0] = it->i;
}
// 2nd vertex
Vertex v2(x2,y2,z2);
it = vertices.find(v2);
if (it == vertices.end()) {
v2.i = vertices.size();
face._aulPoints[1] = v2.i;
vertices.insert(v2);
}
else {
face._aulPoints[1] = it->i;
}
// 3rd vertex
Vertex v3(x3,y3,z3);
it = vertices.find(v3);
if (it == vertices.end()) {
v3.i = vertices.size();
face._aulPoints[2] = v3.i;
vertices.insert(v3);
}
else {
face._aulPoints[2] = it->i;
}
// make sure that we don't insert invalid facets
if (face._aulPoints[0] != face._aulPoints[1] &&
face._aulPoints[1] != face._aulPoints[2] &&
face._aulPoints[2] != face._aulPoints[0]) {
faces.push_back(face);
numDomainFaces++;
}
}
// add a segment for the face
std::vector<unsigned long> segment(numDomainFaces);
std::generate(segment.begin(), segment.end(), Base::iotaGen<unsigned long>(numMeshFaces));
numMeshFaces += numDomainFaces;
meshSegments.push_back(segment);
}
MeshCore::MeshPointArray verts;
verts.resize(vertices.size());
for (auto it : vertices)
verts[it.i] = it.toPoint();
MeshCore::MeshKernel kernel;
kernel.Adopt(verts, faces, true);
Mesh::MeshObject* meshdata = new Mesh::MeshObject();
meshdata->swap(kernel);
for (auto it : meshSegments) {
meshdata->addSegment(it);
}
return meshdata;
}
#ifndef HAVE_SMESH
throw Base::Exception("SMESH is not available on this platform");
#else

View File

@ -40,6 +40,7 @@ public:
#if defined (HAVE_NETGEN)
Netgen = 2,
#endif
Standard = 3
};
Mesher(const TopoDS_Shape&);
@ -68,6 +69,10 @@ public:
{ deflection = s; }
double getDeflection() const
{ return deflection; }
void setAngularDeflection(double s)
{ angularDeflection = s; }
double getAngularDeflection() const
{ return angularDeflection; }
void setMinMaxLengths(double f, double l)
{ minLen = f; maxLen = l; }
void getMinMaxLengths(double& f, double& l) const
@ -121,6 +126,7 @@ private:
double maxArea;
double localLength;
double deflection;
double angularDeflection;
double minLen, maxLen;
bool regular;
#if defined (HAVE_NETGEN)
@ -132,6 +138,7 @@ private:
bool optimize;
bool allowquad;
#endif
struct Vertex;
};
class MeshingOutput : public std::streambuf

View File

@ -249,7 +249,7 @@ bool Tessellation::accept()
cmd = QString::fromLatin1(
"__doc__=FreeCAD.getDocument(\"%1\")\n"
"__mesh__=__doc__.addObject(\"Mesh::Feature\",\"Mesh\")\n"
"__mesh__.Mesh=Mesh.Mesh(__doc__.getObject(\"%2\").Shape.tessellate(%3))\n"
"__mesh__.Mesh=MeshPart.meshFromShape(Shape=__doc__.getObject(\"%2\").Shape,LinearDeflection=%3)\n"
"__mesh__.Label=\"%4 (Meshed)\"\n"
"__mesh__.ViewObject.CreaseAngle=25.0\n"
"del __doc__, __mesh__\n")