add OCC standard meshing algorithm to Mesher class
This commit is contained in:
parent
f37b70b141
commit
1ed35628ab
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue
Block a user