Files
create/src/Mod/MeshPart/App/AppMeshPartPy.cpp
Markus Reitböck 015896f4e4 MeshPart: use CMake to generate precompiled headers on all platforms
"Professional CMake" book suggest the following:

"Targets should build successfully with or without compiler support for precompiled headers. It
 should be considered an optimization, not a requirement. In particular, do not explicitly include a
 precompile header (e.g. stdafx.h) in the source code, let CMake force-include an automatically
 generated precompile header on the compiler command line instead. This is more portable across
 the major compilers and is likely to be easier to maintain. It will also avoid warnings being
 generated from certain code checking tools like iwyu (include what you use)."

Therefore, removed the "#include <PreCompiled.h>" from sources, also
there is no need for the "#ifdef _PreComp_" anymore
2025-09-23 22:39:36 +02:00

650 lines
29 KiB
C++

/***************************************************************************
* Copyright (c) 2008 Jürgen Riegel <juergen.riegel@web.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 <BRepBuilderAPI_MakePolygon.hxx>
#include <TopoDS.hxx>
#include <Base/Console.h>
#include <Base/Converter.h>
#include <Base/GeometryPyCXX.h>
#include <Base/Interpreter.h>
#include <Base/PyWrapParseTupleAndKeywords.h>
#include <Base/Vector3D.h>
#include <Base/VectorPy.h>
#include <Mod/Mesh/App/Core/Algorithm.h>
#include <Mod/Mesh/App/Core/MeshKernel.h>
#include <Mod/Mesh/App/MeshPy.h>
#include <Mod/Part/App/TopoShapeEdgePy.h>
#include <Mod/Part/App/TopoShapePy.h>
#include <Mod/Part/App/TopoShapeWirePy.h>
#include "MeshAlgos.h"
#include "Mesher.h"
// clang-format off
namespace MeshPart {
class Module : public Py::ExtensionModule<Module>
{
public:
Module() : Py::ExtensionModule<Module>("MeshPart")
{
add_varargs_method("loftOnCurve",&Module::loftOnCurve,
"Creates a mesh loft based on a curve and an up vector\n"
"\n"
"loftOnCurve(curve, poly, upVector, MaxSize)\n"
"\n"
"Args:\n"
" curve (topology):\n"
" poly (list of (x, y z) or (x, y) tuples of floats):\n"
" upVector ((x, y, z) tuple):\n"
" MaxSize (float):\n"
);
add_varargs_method("findSectionParameters",&Module::findSectionParameters,
"Find the parameters of the edge where when projecting the corresponding point\n"
"will lie on an edge of the mesh\n"
"\n"
"findSectionParameters(Edge, Mesh, Vector) -> list\n"
);
add_keyword_method("projectShapeOnMesh",&Module::projectShapeOnMesh,
"Projects a shape onto a mesh with a given maximum distance\n"
"projectShapeOnMesh(Shape, Mesh, float) -> polygon\n"
"or projects the shape in a given direction\n"
"\n"
"Multiple signatures are available:\n"
"\n"
"projectShapeOnMesh(Shape, Mesh, float) -> list of polygons\n"
"projectShapeOnMesh(Shape, Mesh, Vector) -> list of polygons\n"
"projectShapeOnMesh(list of polygons, Mesh, Vector) -> list of polygons\n"
);
add_varargs_method("projectPointsOnMesh",&Module::projectPointsOnMesh,
"Projects points onto a mesh with a given direction\n"
"and tolerance."
"projectPointsOnMesh(list of points, Mesh, Vector, [float]) -> list of points\n"
);
add_varargs_method("wireFromSegment",&Module::wireFromSegment,
"Create wire(s) from boundary of a mesh segment\n"
);
add_varargs_method("wireFromMesh",&Module::wireFromMesh,
"Create wire(s) from boundary of a mesh\n"
);
add_keyword_method("meshFromShape",&Module::meshFromShape,
"Create surface mesh from shape\n"
"\n"
"Multiple signatures are available:\n"
"\n"
" meshFromShape(Shape)\n"
" meshFromShape(Shape, LinearDeflection,\n"
" AngularDeflection=0.5,\n"
" Relative=False,"
" Segments=False,\n"
" GroupColors=[])\n"
" meshFromShape(Shape, MaxLength)\n"
" meshFromShape(Shape, MaxArea)\n"
" meshFromShape(Shape, LocalLength)\n"
" meshFromShape(Shape, Deflection)\n"
" meshFromShape(Shape, MinLength, MaxLength)\n"
"\n"
"Additionally, when FreeCAD is built with netgen, the following\n"
"signatures are also available (they are "
#ifndef HAVE_NETGEN
"NOT "
#endif
"currently):\n"
"\n"
" meshFromShape(Shape, Fineness, SecondOrder=0,\n"
" Optimize=1, AllowQuad=0, MaxLength=0, MinLength=0)\n"
" meshFromShape(Shape, GrowthRate=0, SegPerEdge=0,\n"
" SegPerRadius=0, SecondOrder=0, Optimize=1,\n"
" AllowQuad=0)\n"
"\n"
"Args:\n"
" Shape (required, topology) - TopoShape to create mesh of.\n"
" LinearDeflection (required, float)\n"
" AngularDeflection (optional, float)\n"
" Segments (optional, boolean)\n"
" GroupColors (optional, list of (Red, Green, Blue) tuples)\n"
" MaxLength (required, float)\n"
" MaxArea (required, float)\n"
" LocalLength (required, float)\n"
" Deflection (required, float)\n"
" MinLength (required, float)\n"
" Fineness (required, integer)\n"
" SecondOrder (optional, integer boolean)\n"
" Optimize (optional, integer boolean)\n"
" AllowQuad (optional, integer boolean)\n"
" GrowthRate (optional, float)\n"
" SegPerEdge (optional, float)\n"
" SegPerRadius (optional, float)\n"
);
initialize("This module is the MeshPart module."); // register with Python
}
private:
Py::Object invoke_method_varargs(void *method_def, const Py::Tuple &args) override
{
try {
return Py::ExtensionModule<Module>::invoke_method_varargs(method_def, args);
}
catch (const Standard_Failure &e) {
std::string str;
Standard_CString msg = e.GetMessageString();
str += typeid(e).name();
str += " ";
if (msg) {str += msg;}
else {str += "No OCCT Exception Message";}
Base::Console().error("%s\n", str.c_str());
throw Py::Exception(Base::PyExc_FC_GeneralError, str);
}
catch (const Base::Exception &e) {
std::string str;
str += "FreeCAD exception thrown (";
str += e.what();
str += ")";
e.reportException();
throw Py::RuntimeError(str);
}
catch (const std::exception &e) {
std::string str;
str += "C++ exception thrown (";
str += e.what();
str += ")";
Base::Console().error("%s\n", str.c_str());
throw Py::RuntimeError(str);
}
}
Py::Object loftOnCurve(const Py::Tuple& args)
{
Part::TopoShapePy *pcObject;
PyObject *pcTopoObj,*pcListObj;
float x=0.0f,y=0.0f,z=1.0f,size = 0.1f;
if (!PyArg_ParseTuple(args.ptr(), "O!O(fff)f", &(Part::TopoShapePy::Type), &pcTopoObj,&pcListObj,&x,&y,&z,&size))
throw Py::Exception();
pcObject = static_cast<Part::TopoShapePy*>(pcTopoObj);
MeshCore::MeshKernel M;
std::vector<Base::Vector3f> poly;
auto exText( "List of Tuples of three or two floats needed as second parameter!" );
if (!PyList_Check(pcListObj))
throw Py::TypeError(exText);
int nSize = PyList_Size(pcListObj);
for (int i=0; i<nSize;++i) {
PyObject* item = PyList_GetItem(pcListObj, i);
if (!PyTuple_Check(item))
throw Py::TypeError(exText);
int nTSize = PyTuple_Size(item);
if (nTSize != 2 && nTSize != 3)
throw Py::ValueError(exText);
Base::Vector3f vec(0,0,0);
for(int l = 0; l < nTSize;l++) {
PyObject* item2 = PyTuple_GetItem(item, l);
if (!PyFloat_Check(item2))
throw Py::TypeError(exText);
vec[l] = (float)PyFloat_AS_DOUBLE(item2);
}
poly.push_back(vec);
}
TopoDS_Shape aShape = pcObject->getTopoShapePtr()->getShape();
// use the MeshAlgos
MeshPart::MeshAlgos::LoftOnCurve(M,aShape,poly,Base::Vector3f(x,y,z),size);
return Py::asObject(new Mesh::MeshPy(new Mesh::MeshObject(M)));
}
Py::Object findSectionParameters(const Py::Tuple& args)
{
PyObject *e, *m, *v;
if (!PyArg_ParseTuple(args.ptr(), "O!O!O!", &(Part::TopoShapeEdgePy::Type), &e,
&(Mesh::MeshPy::Type), &m,
&(Base::VectorPy::Type),&v))
throw Py::Exception();
TopoDS_Shape shape = static_cast<Part::TopoShapePy*>(e)->getTopoShapePtr()->getShape();
const Mesh::MeshObject* mesh = static_cast<Mesh::MeshPy*>(m)->getMeshObjectPtr();
MeshCore::MeshKernel kernel(mesh->getKernel());
kernel.Transform(mesh->getTransform());
Base::Vector3d* vec = static_cast<Base::VectorPy*>(v)->getVectorPtr();
Base::Vector3f dir = Base::convertTo<Base::Vector3f>(*vec);
MeshProjection proj(kernel);
std::set<double> parameters;
proj.findSectionParameters(TopoDS::Edge(shape), dir, parameters);
Py::List list;
for (auto it : parameters) {
Py::Float val(it);
list.append(val);
}
return list;
}
Py::Object projectShapeOnMesh(const Py::Tuple& args, const Py::Dict& kwds)
{
static const std::array<const char *, 4> kwds_maxdist{"Shape", "Mesh", "MaxDistance", nullptr};
PyObject *s, *m;
double maxDist;
if (Base::Wrapped_ParseTupleAndKeywords(args.ptr(), kwds.ptr(),
"O!O!d", kwds_maxdist,
&Part::TopoShapePy::Type, &s,
&Mesh::MeshPy::Type, &m,
&maxDist)) {
TopoDS_Shape shape = static_cast<Part::TopoShapePy*>(s)->getTopoShapePtr()->getShape();
const Mesh::MeshObject* mesh = static_cast<Mesh::MeshPy*>(m)->getMeshObjectPtr();
MeshCore::MeshKernel kernel(mesh->getKernel());
kernel.Transform(mesh->getTransform());
MeshProjection proj(kernel);
std::vector<MeshProjection::PolyLine> polylines;
proj.projectToMesh(shape, maxDist, polylines);
Py::List list;
for (const auto& it : polylines) {
Py::List poly;
for (auto jt : it.points) {
Py::Vector v(jt);
poly.append(v);
}
list.append(poly);
}
return list;
}
static const std::array<const char *, 4> kwds_dir {"Shape", "Mesh", "Direction", nullptr};
PyErr_Clear();
PyObject *v;
if (Base::Wrapped_ParseTupleAndKeywords(args.ptr(), kwds.ptr(),
"O!O!O!", kwds_dir,
&Part::TopoShapePy::Type, &s,
&Mesh::MeshPy::Type, &m,
&Base::VectorPy::Type, &v)) {
TopoDS_Shape shape = static_cast<Part::TopoShapePy*>(s)->getTopoShapePtr()->getShape();
const Mesh::MeshObject* mesh = static_cast<Mesh::MeshPy*>(m)->getMeshObjectPtr();
Base::Vector3d* vec = static_cast<Base::VectorPy*>(v)->getVectorPtr();
Base::Vector3f dir = Base::convertTo<Base::Vector3f>(*vec);
MeshCore::MeshKernel kernel(mesh->getKernel());
kernel.Transform(mesh->getTransform());
MeshProjection proj(kernel);
std::vector<MeshProjection::PolyLine> polylines;
proj.projectParallelToMesh(shape, dir, polylines);
Py::List list;
for (const auto& it : polylines) {
Py::List poly;
for (auto jt : it.points) {
Py::Vector v(jt);
poly.append(v);
}
list.append(poly);
}
return list;
}
static const std::array<const char *, 4> kwds_poly {"Polygons", "Mesh", "Direction", nullptr};
PyErr_Clear();
PyObject *seq;
if (Base::Wrapped_ParseTupleAndKeywords(args.ptr(), kwds.ptr(),
"OO!O!", kwds_poly,
&seq,
&Mesh::MeshPy::Type, &m,
&Base::VectorPy::Type, &v)) {
std::vector<MeshProjection::PolyLine> polylinesIn;
Py::Sequence edges(seq);
polylinesIn.reserve(edges.size());
// collect list of sampled input edges
for (Py::Sequence::iterator it = edges.begin(); it != edges.end(); ++it) {
Py::Sequence edge(*it);
MeshProjection::PolyLine poly;
poly.points.reserve(edge.size());
for (Py::Sequence::iterator jt = edge.begin(); jt != edge.end(); ++jt) {
Py::Vector pnt(*jt);
poly.points.push_back(Base::convertTo<Base::Vector3f>(pnt.toVector()));
}
polylinesIn.push_back(poly);
}
const Mesh::MeshObject* mesh = static_cast<Mesh::MeshPy*>(m)->getMeshObjectPtr();
Base::Vector3d* vec = static_cast<Base::VectorPy*>(v)->getVectorPtr();
Base::Vector3f dir = Base::convertTo<Base::Vector3f>(*vec);
MeshCore::MeshKernel kernel(mesh->getKernel());
kernel.Transform(mesh->getTransform());
MeshProjection proj(kernel);
std::vector<MeshProjection::PolyLine> polylines;
proj.projectParallelToMesh(polylinesIn, dir, polylines);
Py::List list;
for (const auto& it : polylines) {
Py::List poly;
for (auto jt : it.points) {
Py::Vector v(jt);
poly.append(v);
}
list.append(poly);
}
return list;
}
throw Py::TypeError("Expected arguments are:\n"
"Shape, Mesh, float or\n"
"Shape, Mesh, Vector or\n"
"Polygons, Mesh, Vector\n");
}
Py::Object projectPointsOnMesh(const Py::Tuple& args)
{
PyObject *seq, *m, *v;
double precision = -1;
if (PyArg_ParseTuple(args.ptr(), "OO!O!|d",
&seq,
&Mesh::MeshPy::Type, &m,
&Base::VectorPy::Type, &v,
&precision)) {
std::vector<Base::Vector3f> pointsIn;
Py::Sequence points(seq);
pointsIn.reserve(points.size());
// collect list of input points
for (Py::Sequence::iterator it = points.begin(); it != points.end(); ++it) {
Py::Vector pnt(*it);
pointsIn.push_back(Base::convertTo<Base::Vector3f>(pnt.toVector()));
}
const Mesh::MeshObject* mesh = static_cast<Mesh::MeshPy*>(m)->getMeshObjectPtr();
Base::Vector3d* vec = static_cast<Base::VectorPy*>(v)->getVectorPtr();
Base::Vector3f dir = Base::convertTo<Base::Vector3f>(*vec);
MeshCore::MeshKernel kernel(mesh->getKernel());
kernel.Transform(mesh->getTransform());
MeshProjection proj(kernel);
std::vector<Base::Vector3f> pointsOut;
proj.projectOnMesh(pointsIn, dir, static_cast<float>(precision), pointsOut);
Py::List list;
for (auto it : pointsOut) {
Py::Vector v(it);
list.append(v);
}
return list;
}
throw Py::Exception();
}
Py::Object wireFromSegment(const Py::Tuple& args)
{
PyObject *o, *m;
if (!PyArg_ParseTuple(args.ptr(), "O!O!", &(Mesh::MeshPy::Type), &m,&PyList_Type,&o))
throw Py::Exception();
Py::List list(o);
Mesh::MeshObject* mesh = static_cast<Mesh::MeshPy*>(m)->getMeshObjectPtr();
std::vector<MeshCore::FacetIndex> segm;
segm.reserve(list.size());
for (Py_ssize_t i=0; i<list.size(); i++) {
segm.push_back((long)Py::Long(list[i]));
}
std::list<std::vector<Base::Vector3f> > bounds;
MeshCore::MeshAlgorithm algo(mesh->getKernel());
algo.GetFacetBorders(segm, bounds);
Py::List wires;
std::list<std::vector<Base::Vector3f> >::iterator bt;
for (bt = bounds.begin(); bt != bounds.end(); ++bt) {
BRepBuilderAPI_MakePolygon mkPoly;
for (std::vector<Base::Vector3f>::reverse_iterator it = bt->rbegin(); it != bt->rend(); ++it) {
mkPoly.Add(gp_Pnt(it->x,it->y,it->z));
}
if (mkPoly.IsDone()) {
PyObject* wire = new Part::TopoShapeWirePy(new Part::TopoShape(mkPoly.Wire()));
wires.append(Py::Object(wire, true));
}
}
return wires;
}
Py::Object wireFromMesh(const Py::Tuple& args)
{
PyObject *m;
if (!PyArg_ParseTuple(args.ptr(), "O!", &(Mesh::MeshPy::Type), &m))
throw Py::Exception();
Mesh::MeshObject* mesh = static_cast<Mesh::MeshPy*>(m)->getMeshObjectPtr();
std::list<std::vector<Base::Vector3f> > bounds;
MeshCore::MeshAlgorithm algo(mesh->getKernel());
algo.GetMeshBorders(bounds);
Py::List wires;
std::list<std::vector<Base::Vector3f> >::iterator bt;
for (bt = bounds.begin(); bt != bounds.end(); ++bt) {
BRepBuilderAPI_MakePolygon mkPoly;
for (std::vector<Base::Vector3f>::reverse_iterator it = bt->rbegin(); it != bt->rend(); ++it) {
mkPoly.Add(gp_Pnt(it->x,it->y,it->z));
}
if (mkPoly.IsDone()) {
PyObject* wire = new Part::TopoShapeWirePy(new Part::TopoShape(mkPoly.Wire()));
wires.append(Py::Object(wire, true));
}
}
return wires;
}
Py::Object meshFromShape(const Py::Tuple& args, const Py::Dict& kwds)
{
PyObject *shape;
auto runMesher = [](const MeshPart::Mesher& mesher) {
Mesh::MeshObject* mesh;
{
Base::PyGILStateRelease releaser{};
mesh = mesher.createMesh();
}
return Py::asObject(new Mesh::MeshPy(mesh));
};
static const std::array<const char *, 7> kwds_lindeflection{"Shape", "LinearDeflection", "AngularDeflection",
"Relative", "Segments", "GroupColors", nullptr};
PyErr_Clear();
double lindeflection=0;
double angdeflection=0.5;
PyObject* relative = Py_False;
PyObject* segment = Py_False;
PyObject* groupColors = nullptr;
if (Base::Wrapped_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "O!d|dO!O!O", kwds_lindeflection,
&(Part::TopoShapePy::Type), &shape, &lindeflection,
&angdeflection, &(PyBool_Type), &relative,
&(PyBool_Type), &segment, &groupColors)) {
MeshPart::Mesher mesher(static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->getShape());
mesher.setMethod(MeshPart::Mesher::Standard);
mesher.setDeflection(lindeflection);
mesher.setAngularDeflection(angdeflection);
mesher.setRegular(true);
mesher.setRelative(Base::asBoolean(relative));
mesher.setSegments(Base::asBoolean(segment));
if (groupColors) {
Py::Sequence list(groupColors);
std::vector<uint32_t> colors;
colors.reserve(list.size());
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
Py::Tuple t(*it);
Py::Float r(t[0]);
Py::Float g(t[1]);
Py::Float b(t[2]);
Base::Color c(static_cast<float>(r),
static_cast<float>(g),
static_cast<float>(b));
colors.push_back(c.getPackedValue());
}
mesher.setColors(colors);
}
return runMesher(mesher);
}
static const std::array<const char *, 3> kwds_maxLength{"Shape", "MaxLength", nullptr};
PyErr_Clear();
double maxLength=0;
if (Base::Wrapped_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "O!d", kwds_maxLength,
&(Part::TopoShapePy::Type), &shape, &maxLength)) {
MeshPart::Mesher mesher(static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->getShape());
mesher.setMethod(MeshPart::Mesher::Mefisto);
mesher.setMaxLength(maxLength);
mesher.setRegular(true);
return runMesher(mesher);
}
static const std::array<const char *, 3> kwds_maxArea{"Shape", "MaxArea", nullptr};
PyErr_Clear();
double maxArea=0;
if (Base::Wrapped_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "O!d", kwds_maxArea,
&(Part::TopoShapePy::Type), &shape, &maxArea)) {
MeshPart::Mesher mesher(static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->getShape());
mesher.setMethod(MeshPart::Mesher::Mefisto);
mesher.setMaxArea(maxArea);
mesher.setRegular(true);
return runMesher(mesher);
}
static const std::array<const char *, 3> kwds_localLen{"Shape", "LocalLength", nullptr};
PyErr_Clear();
double localLen=0;
if (Base::Wrapped_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "O!d", kwds_localLen,
&(Part::TopoShapePy::Type), &shape, &localLen)) {
MeshPart::Mesher mesher(static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->getShape());
mesher.setMethod(MeshPart::Mesher::Mefisto);
mesher.setLocalLength(localLen);
mesher.setRegular(true);
return runMesher(mesher);
}
static const std::array<const char *, 3> kwds_deflection{"Shape", "Deflection", nullptr};
PyErr_Clear();
double deflection=0;
if (Base::Wrapped_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "O!d", kwds_deflection,
&(Part::TopoShapePy::Type), &shape, &deflection)) {
MeshPart::Mesher mesher(static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->getShape());
mesher.setMethod(MeshPart::Mesher::Mefisto);
mesher.setDeflection(deflection);
mesher.setRegular(true);
return runMesher(mesher);
}
static const std::array<const char *, 4> kwds_minmaxLen{"Shape", "MinLength", "MaxLength", nullptr};
PyErr_Clear();
double minLen=0, maxLen=0;
if (Base::Wrapped_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "O!dd", kwds_minmaxLen,
&(Part::TopoShapePy::Type), &shape, &minLen, &maxLen)) {
MeshPart::Mesher mesher(static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->getShape());
mesher.setMethod(MeshPart::Mesher::Mefisto);
mesher.setMinMaxLengths(minLen, maxLen);
mesher.setRegular(true);
return runMesher(mesher);
}
static const std::array<const char *, 8> kwds_fineness{"Shape", "Fineness", "SecondOrder", "Optimize",
"AllowQuad", "MinLength", "MaxLength", nullptr};
PyErr_Clear();
int fineness=0, secondOrder=0, optimize=1, allowquad=0;
if (Base::Wrapped_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "O!i|iiidd", kwds_fineness,
&(Part::TopoShapePy::Type), &shape, &fineness,
&secondOrder, &optimize, &allowquad, &minLen, &maxLen)) {
#if defined (HAVE_NETGEN)
MeshPart::Mesher mesher(static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->getShape());
mesher.setMethod(MeshPart::Mesher::Netgen);
mesher.setFineness(fineness);
mesher.setSecondOrder(secondOrder != 0);
mesher.setOptimize(optimize != 0);
mesher.setQuadAllowed(allowquad != 0);
mesher.setMinMaxLengths(minLen, maxLen);
return runMesher(mesher);
#else
throw Py::RuntimeError("SMESH was built without NETGEN support");
#endif
}
static const std::array<const char *, 10> kwds_user{"Shape", "GrowthRate", "SegPerEdge", "SegPerRadius",
"SecondOrder", "Optimize", "AllowQuad", "MinLength",
"MaxLength", nullptr};
PyErr_Clear();
double growthRate=0, nbSegPerEdge=0, nbSegPerRadius=0;
if (Base::Wrapped_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "O!|dddiiidd", kwds_user,
&(Part::TopoShapePy::Type), &shape,
&growthRate, &nbSegPerEdge, &nbSegPerRadius,
&secondOrder, &optimize, &allowquad, &minLen, &maxLen)) {
#if defined (HAVE_NETGEN)
MeshPart::Mesher mesher(static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->getShape());
mesher.setMethod(MeshPart::Mesher::Netgen);
mesher.setGrowthRate(growthRate);
mesher.setNbSegPerEdge(nbSegPerEdge);
mesher.setNbSegPerRadius(nbSegPerRadius);
mesher.setSecondOrder(secondOrder != 0);
mesher.setOptimize(optimize != 0);
mesher.setQuadAllowed(allowquad != 0);
mesher.setMinMaxLengths(minLen, maxLen);
return runMesher(mesher);
#else
throw Py::RuntimeError("SMESH was built without NETGEN support");
#endif
}
PyErr_Clear();
if (PyArg_ParseTuple(args.ptr(), "O!", &(Part::TopoShapePy::Type), &shape)) {
MeshPart::Mesher mesher(static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->getShape());
#if defined (HAVE_NETGEN)
mesher.setMethod(MeshPart::Mesher::Netgen);
#else
mesher.setMethod(MeshPart::Mesher::Mefisto);
mesher.setRegular(true);
#endif
return runMesher(mesher);
}
throw Py::TypeError("Wrong arguments");
}
};
PyObject* initModule()
{
return Base::Interpreter().addModule(new Module);
}
} // namespace MeshPart
// clang-format on