Part: expose ShapeFix and ShapeFix_Face to Python
This commit is contained in:
@@ -101,6 +101,7 @@
|
||||
#include <Mod/Part/App/PrecisionPy.h>
|
||||
#include <Mod/Part/App/RectangularTrimmedSurfacePy.h>
|
||||
#include <Mod/Part/App/ShapeFix/ShapeFix_RootPy.h>
|
||||
#include <Mod/Part/App/ShapeFix/ShapeFix_FacePy.h>
|
||||
#include <Mod/Part/App/ShapeFix/ShapeFix_ShellPy.h>
|
||||
#include <Mod/Part/App/ShapeUpgrade/UnifySameDomainPy.h>
|
||||
#include "Mod/Part/App/SpherePy.h"
|
||||
@@ -342,6 +343,7 @@ PyMOD_INIT_FUNC(Part)
|
||||
// ShapeFix sub-module
|
||||
PyObject* shapeFix(module.getAttr("ShapeFix").ptr());
|
||||
Base::Interpreter().addType(&Part::ShapeFix_RootPy::Type, shapeFix, "Root");
|
||||
Base::Interpreter().addType(&Part::ShapeFix_FacePy::Type, shapeFix, "Face");
|
||||
Base::Interpreter().addType(&Part::ShapeFix_ShellPy::Type, shapeFix, "Shell");
|
||||
|
||||
// ShapeUpgrade sub-module
|
||||
|
||||
@@ -58,6 +58,8 @@
|
||||
# include <Interface_Static.hxx>
|
||||
# include <NCollection_List.hxx>
|
||||
# include <Precision.hxx>
|
||||
# include <ShapeFix.hxx>
|
||||
# include <ShapeBuild_ReShape.hxx>
|
||||
# include <ShapeUpgrade_ShellSewing.hxx>
|
||||
# include <Standard_ConstructionError.hxx>
|
||||
# include <Standard_DomainError.hxx>
|
||||
@@ -308,10 +310,87 @@ class ShapeFixModule : public Py::ExtensionModule<ShapeFixModule>
|
||||
public:
|
||||
ShapeFixModule() : Py::ExtensionModule<ShapeFixModule>("ShapeFix")
|
||||
{
|
||||
add_varargs_method("sameParameter",&ShapeFixModule::sameParameter,
|
||||
"sameParameter(shape, enforce, prec=0.0)"
|
||||
);
|
||||
add_varargs_method("encodeRegularity",&ShapeFixModule::encodeRegularity,
|
||||
"encodeRegularity(shape, tolerance = 1e-10)\n"
|
||||
);
|
||||
add_varargs_method("removeSmallEdges",&ShapeFixModule::removeSmallEdges,
|
||||
"removeSmallEdges(shape, tolerance, ReShapeContext)\n"
|
||||
"Removes edges which are less than given tolerance from shape"
|
||||
);
|
||||
add_varargs_method("fixVertexPosition",&ShapeFixModule::fixVertexPosition,
|
||||
"fixVertexPosition(shape, tolerance, ReShapeContext)\n"
|
||||
"Fix position of the vertices having tolerance more tnan specified one"
|
||||
);
|
||||
add_varargs_method("leastEdgeSize",&ShapeFixModule::leastEdgeSize,
|
||||
"leastEdgeSize(shape)\n"
|
||||
"Calculate size of least edge"
|
||||
);
|
||||
initialize("This is a module working with the ShapeFix framework."); // register with Python
|
||||
}
|
||||
|
||||
virtual ~ShapeFixModule() {}
|
||||
|
||||
private:
|
||||
Py::Object sameParameter(const Py::Tuple& args)
|
||||
{
|
||||
PyObject* shape;
|
||||
PyObject* enforce;
|
||||
double prec = 0.0;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O!O!|d", &TopoShapePy::Type, &shape, &PyBool_Type, &enforce, &prec))
|
||||
throw Py::Exception();
|
||||
|
||||
TopoDS_Shape sh = static_cast<TopoShapePy*>(shape)->getTopoShapePtr()->getShape();
|
||||
bool ok = ShapeFix::SameParameter(sh, PyObject_IsTrue(enforce) ? Standard_True : Standard_False, prec);
|
||||
return Py::Boolean(ok);
|
||||
}
|
||||
Py::Object encodeRegularity(const Py::Tuple& args)
|
||||
{
|
||||
PyObject* shape;
|
||||
double tolang = 1.0e-10;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O!|d", &TopoShapePy::Type, &shape, &tolang))
|
||||
throw Py::Exception();
|
||||
|
||||
TopoDS_Shape sh = static_cast<TopoShapePy*>(shape)->getTopoShapePtr()->getShape();
|
||||
ShapeFix::EncodeRegularity(sh, tolang);
|
||||
return Py::None();
|
||||
}
|
||||
Py::Object removeSmallEdges(const Py::Tuple& args)
|
||||
{
|
||||
PyObject* shape;
|
||||
double tol;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O!d", &TopoShapePy::Type, &shape, &tol))
|
||||
throw Py::Exception();
|
||||
|
||||
TopoDS_Shape sh = static_cast<TopoShapePy*>(shape)->getTopoShapePtr()->getShape();
|
||||
Handle(ShapeBuild_ReShape) reshape = new ShapeBuild_ReShape();
|
||||
TopoShape res = ShapeFix::RemoveSmallEdges(sh, tol, reshape);
|
||||
return Py::asObject(res.getPyObject());
|
||||
}
|
||||
Py::Object fixVertexPosition(const Py::Tuple& args)
|
||||
{
|
||||
PyObject* shape;
|
||||
double tol;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O!d", &TopoShapePy::Type, &shape, &tol))
|
||||
throw Py::Exception();
|
||||
|
||||
TopoDS_Shape sh = static_cast<TopoShapePy*>(shape)->getTopoShapePtr()->getShape();
|
||||
Handle(ShapeBuild_ReShape) reshape = new ShapeBuild_ReShape();
|
||||
bool ok = ShapeFix::FixVertexPosition(sh, tol, reshape);
|
||||
return Py::Boolean(ok);
|
||||
}
|
||||
Py::Object leastEdgeSize(const Py::Tuple& args)
|
||||
{
|
||||
PyObject* shape;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O!", &TopoShapePy::Type, &shape))
|
||||
throw Py::Exception();
|
||||
|
||||
TopoDS_Shape sh = static_cast<TopoShapePy*>(shape)->getTopoShapePtr()->getShape();
|
||||
double len = ShapeFix::LeastEdgeSize(sh);
|
||||
return Py::Float(len);
|
||||
}
|
||||
};
|
||||
|
||||
class ShapeUpgradeModule : public Py::ExtensionModule<ShapeUpgradeModule>
|
||||
|
||||
@@ -137,6 +137,7 @@ generate_from_xml(HLRBRep/HLRBRep_PolyAlgoPy)
|
||||
generate_from_xml(HLRBRep/PolyHLRToShapePy)
|
||||
|
||||
generate_from_xml(ShapeFix/ShapeFix_RootPy)
|
||||
generate_from_xml(ShapeFix/ShapeFix_FacePy)
|
||||
generate_from_xml(ShapeFix/ShapeFix_ShellPy)
|
||||
|
||||
generate_from_xml(ShapeUpgrade/UnifySameDomainPy)
|
||||
@@ -425,6 +426,8 @@ SOURCE_GROUP("HLRBRep" FILES ${HLRBRepPy_SRCS})
|
||||
SET(ShapeFixPy_SRCS
|
||||
ShapeFix/ShapeFix_RootPy.xml
|
||||
ShapeFix/ShapeFix_RootPyImp.cpp
|
||||
ShapeFix/ShapeFix_FacePy.xml
|
||||
ShapeFix/ShapeFix_FacePyImp.cpp
|
||||
ShapeFix/ShapeFix_ShellPy.xml
|
||||
ShapeFix/ShapeFix_ShellPyImp.cpp
|
||||
)
|
||||
|
||||
203
src/Mod/Part/App/ShapeFix/ShapeFix_FacePy.xml
Normal file
203
src/Mod/Part/App/ShapeFix/ShapeFix_FacePy.xml
Normal file
@@ -0,0 +1,203 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="ShapeFix_RootPy"
|
||||
Name="ShapeFix_FacePy"
|
||||
PythonName="Part.ShapeFix.Face"
|
||||
Twin="ShapeFix_Face"
|
||||
TwinPointer="ShapeFix_Face"
|
||||
Include="ShapeFix_Face.hxx"
|
||||
Namespace="Part"
|
||||
FatherInclude="Mod/Part/App/ShapeFix/ShapeFix_RootPy.h"
|
||||
FatherNamespace="Part"
|
||||
Constructor="true">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Werner Mayer" EMail="wmayer@users.sourceforge.net" />
|
||||
<UserDocu>Class for fixing operations on faces</UserDocu>
|
||||
</Documentation>
|
||||
<Methode Name="init">
|
||||
<Documentation>
|
||||
<UserDocu>Initializes by face</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="clearModes">
|
||||
<Documentation>
|
||||
<UserDocu>Iterates on subshapes and performs fixes</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="add">
|
||||
<Documentation>
|
||||
<UserDocu>Add a wire to current face using BRep_Builder.
|
||||
Wire is added without taking into account orientation of face
|
||||
(as if face were FORWARD)
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="fixOrientation">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Fixes orientation of wires on the face
|
||||
It tries to make all wires lie outside all others (according
|
||||
to orientation) by reversing orientation of some of them.
|
||||
If face lying on sphere or torus has single wire and
|
||||
AddNaturalBoundMode is True, that wire is not reversed in
|
||||
any case (supposing that natural bound will be added).
|
||||
Returns True if wires were reversed
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="fixAddNaturalBound">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Adds natural boundary on face if it is missing.
|
||||
Two cases are supported:
|
||||
- face has no wires
|
||||
- face lies on geometrically double-closed surface
|
||||
(sphere or torus) and none of wires is left-oriented
|
||||
Returns True if natural boundary was added
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="fixMissingSeam">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Detects and fixes the special case when face on a closed
|
||||
surface is given by two wires closed in 3d but with gap in 2d.
|
||||
In that case it creates a new wire from the two, and adds a
|
||||
missing seam edge
|
||||
Returns True if missing seam was added
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="fixSmallAreaWire">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Detects wires with small area (that is less than
|
||||
100*Precision.PConfusion(). Removes these wires if they are internal.
|
||||
Returns True if at least one small wire removed, False nothing is done.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="fixLoopWire">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Detects if wire has a loop and fixes this situation by splitting on the few parts.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="fixIntersectingWires">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Detects and fixes the special case when face has more than one wire
|
||||
and this wires have intersection point
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="fixWiresTwoCoincidentEdges">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
If wire contains two coincidence edges it must be removed
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="fixPeriodicDegenerated">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Fixes topology for a specific case when face is composed
|
||||
by a single wire belting a periodic surface. In that case
|
||||
a degenerated edge is reconstructed in the degenerated pole
|
||||
of the surface. Initial wire gets consistent orientation.
|
||||
Must be used in couple and before FixMissingSeam routine
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="perform">
|
||||
<Documentation>
|
||||
<UserDocu>Iterates on subshapes and performs fixes</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="face">
|
||||
<Documentation>
|
||||
<UserDocu>Returns a face which corresponds to the current state</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="result">
|
||||
<Documentation>
|
||||
<UserDocu>Returns resulting shape (Face or Shell if splitted)
|
||||
To be used instead of face() if FixMissingSeam involved
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Attribute Name="FixWireMode" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Mode for applying fixes of ShapeFix_Wire</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="FixWireMode" Type="Boolean"/>
|
||||
</Attribute>
|
||||
<Attribute Name="FixOrientationMode" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Mode for applying fixes of orientation
|
||||
If True, wires oriented to border limited square
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="FixOrientationMode" Type="Boolean"/>
|
||||
</Attribute>
|
||||
<Attribute Name="FixAddNaturalBoundMode" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>If true, natural boundary is added on faces that miss them.
|
||||
Default is False for faces with single wire (they are
|
||||
handled by FixOrientation in that case) and True for others.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="FixAddNaturalBoundMode" Type="Boolean"/>
|
||||
</Attribute>
|
||||
<Attribute Name="FixMissingSeamMode" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>If True, tries to insert seam if missing</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="FixMissingSeamMode" Type="Boolean"/>
|
||||
</Attribute>
|
||||
<Attribute Name="FixSmallAreaWireMode" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>If True, drops small wires</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="FixSmallAreaWireMode" Type="Boolean"/>
|
||||
</Attribute>
|
||||
<Attribute Name="RemoveSmallAreaFaceMode" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>If True, drops small wires</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="RemoveSmallAreaFaceMode" Type="Boolean"/>
|
||||
</Attribute>
|
||||
<Attribute Name="FixIntersectingWiresMode" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Mode for applying fixes of intersecting wires</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="FixIntersectingWiresMode" Type="Boolean"/>
|
||||
</Attribute>
|
||||
<Attribute Name="FixLoopWiresMode" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Mode for applying fixes of loop wires</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="FixLoopWiresMode" Type="Boolean"/>
|
||||
</Attribute>
|
||||
<Attribute Name="FixSplitFaceMode" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Mode for applying fixes of split face</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="FixSplitFaceMode" Type="Boolean"/>
|
||||
</Attribute>
|
||||
<Attribute Name="AutoCorrectPrecisionMode" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Mode for applying auto-corrected precision</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="AutoCorrectPrecisionMode" Type="Boolean"/>
|
||||
</Attribute>
|
||||
<Attribute Name="FixPeriodicDegeneratedMode" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Mode for applying periodic degeneration</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="FixPeriodicDegeneratedMode" Type="Boolean"/>
|
||||
</Attribute>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
354
src/Mod/Part/App/ShapeFix/ShapeFix_FacePyImp.cpp
Normal file
354
src/Mod/Part/App/ShapeFix/ShapeFix_FacePyImp.cpp
Normal file
@@ -0,0 +1,354 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2022 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* 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 <TopoDS.hxx>
|
||||
#endif
|
||||
|
||||
#include "ShapeFix/ShapeFix_FacePy.h"
|
||||
#include "ShapeFix/ShapeFix_FacePy.cpp"
|
||||
#include <Mod/Part/App/GeometrySurfacePy.h>
|
||||
#include <Mod/Part/App/TopoShapeFacePy.h>
|
||||
#include <Mod/Part/App/TopoShapeWirePy.h>
|
||||
|
||||
using namespace Part;
|
||||
|
||||
// returns a string which represents the object e.g. when printed in python
|
||||
std::string ShapeFix_FacePy::representation() const
|
||||
{
|
||||
return "<ShapeFix_Face object>";
|
||||
}
|
||||
|
||||
PyObject *ShapeFix_FacePy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
|
||||
{
|
||||
// create a new instance of ShapeFix_FacePy
|
||||
return new ShapeFix_FacePy(new ShapeFix_Face);
|
||||
}
|
||||
|
||||
// constructor method
|
||||
int ShapeFix_FacePy::PyInit(PyObject* args, PyObject* /*kwds*/)
|
||||
{
|
||||
PyObject* face = nullptr;
|
||||
if (PyArg_ParseTuple(args, "|O!", &TopoShapeFacePy::Type, &face)) {
|
||||
if (face) {
|
||||
getShapeFix_FacePtr()->Init(TopoDS::Face(static_cast<TopoShapePy*>(face)->getTopoShapePtr()->getShape()));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
double prec;
|
||||
PyObject* fwd = Py_True;
|
||||
if (PyArg_ParseTuple(args, "O!d|O!", &GeometrySurfacePy::Type, &face, &prec, &PyBool_Type, &fwd)) {
|
||||
if (face) {
|
||||
Handle(Geom_Surface) surf = Handle(Geom_Surface)::DownCast(static_cast<GeometrySurfacePy*>(face)->getGeomSurfacePtr()->handle());
|
||||
getShapeFix_FacePtr()->Init(surf, prec, PyObject_IsTrue(fwd) ? Standard_True : Standard_False);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Supported arguments are:\n"
|
||||
"-- Face\n"
|
||||
"-- Surface, Precision, [Forward=True}\n"
|
||||
" Precision is a Float\n"
|
||||
" If Forward is the orientation will be FORWARD or REVERSED otherwise"
|
||||
);
|
||||
return -1;
|
||||
}
|
||||
|
||||
PyObject* ShapeFix_FacePy::init(PyObject *args)
|
||||
{
|
||||
PyObject* face;
|
||||
if (PyArg_ParseTuple(args, "O!", &TopoShapeFacePy::Type, &face)) {
|
||||
getShapeFix_FacePtr()->Init(TopoDS::Face(static_cast<TopoShapePy*>(face)->getTopoShapePtr()->getShape()));
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
double prec;
|
||||
PyObject* fwd = Py_True;
|
||||
if (PyArg_ParseTuple(args, "O!d|O!", &GeometrySurfacePy::Type, &face, &prec, &PyBool_Type, &fwd)) {
|
||||
if (face) {
|
||||
Handle(Geom_Surface) surf = Handle(Geom_Surface)::DownCast(static_cast<GeometrySurfacePy*>(face)->getGeomSurfacePtr()->handle());
|
||||
getShapeFix_FacePtr()->Init(surf, prec, PyObject_IsTrue(fwd) ? Standard_True : Standard_False);
|
||||
}
|
||||
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Supported arguments are:\n"
|
||||
"-- Face\n"
|
||||
"-- Surface, Precision, [Forward=True}\n"
|
||||
" Precision is a Float\n"
|
||||
" If Forward is the orientation will be FORWARD or REVERSED otherwise"
|
||||
);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* ShapeFix_FacePy::clearModes(PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
|
||||
getShapeFix_FacePtr()->ClearModes();
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* ShapeFix_FacePy::add(PyObject *args)
|
||||
{
|
||||
PyObject* wire;
|
||||
if (!PyArg_ParseTuple(args, "O!", &TopoShapeWirePy::Type, &wire))
|
||||
return nullptr;
|
||||
|
||||
getShapeFix_FacePtr()->Add(TopoDS::Wire(static_cast<TopoShapePy*>(wire)->getTopoShapePtr()->getShape()));
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* ShapeFix_FacePy::fixOrientation(PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
|
||||
Standard_Boolean ok = getShapeFix_FacePtr()->FixOrientation();
|
||||
return Py::new_reference_to(Py::Boolean(ok));
|
||||
}
|
||||
|
||||
PyObject* ShapeFix_FacePy::fixAddNaturalBound(PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
|
||||
Standard_Boolean ok = getShapeFix_FacePtr()->FixAddNaturalBound();
|
||||
return Py::new_reference_to(Py::Boolean(ok));
|
||||
}
|
||||
|
||||
PyObject* ShapeFix_FacePy::fixMissingSeam(PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
|
||||
Standard_Boolean ok = getShapeFix_FacePtr()->FixMissingSeam();
|
||||
return Py::new_reference_to(Py::Boolean(ok));
|
||||
}
|
||||
|
||||
PyObject* ShapeFix_FacePy::fixSmallAreaWire(PyObject *args)
|
||||
{
|
||||
PyObject* removeSmall;
|
||||
if (!PyArg_ParseTuple(args, "O!", &PyBool_Type, &removeSmall))
|
||||
return nullptr;
|
||||
|
||||
Standard_Boolean ok = getShapeFix_FacePtr()->FixSmallAreaWire(PyObject_IsTrue(removeSmall) ? Standard_True : Standard_False);
|
||||
return Py::new_reference_to(Py::Boolean(ok));
|
||||
}
|
||||
|
||||
PyObject* ShapeFix_FacePy::fixLoopWire(PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
|
||||
TopTools_SequenceOfShape aResWires;
|
||||
Standard_Boolean ok = getShapeFix_FacePtr()->FixLoopWire(aResWires);
|
||||
Py::List list;
|
||||
for (int index = aResWires.Lower(); index <= aResWires.Upper(); index++) {
|
||||
TopoShape sh = aResWires(index);
|
||||
list.append(Py::asObject(sh.getPyObject()));
|
||||
}
|
||||
return Py::new_reference_to(Py::TupleN(Py::Boolean(ok), list));
|
||||
}
|
||||
|
||||
PyObject* ShapeFix_FacePy::fixIntersectingWires(PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
|
||||
Standard_Boolean ok = getShapeFix_FacePtr()->FixIntersectingWires();
|
||||
return Py::new_reference_to(Py::Boolean(ok));
|
||||
}
|
||||
|
||||
PyObject* ShapeFix_FacePy::fixWiresTwoCoincidentEdges(PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
|
||||
Standard_Boolean ok = getShapeFix_FacePtr()->FixWiresTwoCoincEdges();
|
||||
return Py::new_reference_to(Py::Boolean(ok));
|
||||
}
|
||||
|
||||
PyObject* ShapeFix_FacePy::fixPeriodicDegenerated(PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
|
||||
Standard_Boolean ok = getShapeFix_FacePtr()->FixPeriodicDegenerated();
|
||||
return Py::new_reference_to(Py::Boolean(ok));
|
||||
}
|
||||
|
||||
PyObject* ShapeFix_FacePy::perform(PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
|
||||
Standard_Boolean ok = getShapeFix_FacePtr()->Perform();
|
||||
return Py::new_reference_to(Py::Boolean(ok));
|
||||
}
|
||||
|
||||
PyObject* ShapeFix_FacePy::face(PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
|
||||
TopoShape shape = getShapeFix_FacePtr()->Face();
|
||||
return shape.getPyObject();
|
||||
}
|
||||
|
||||
PyObject* ShapeFix_FacePy::result(PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
|
||||
TopoShape shape = getShapeFix_FacePtr()->Result();
|
||||
return shape.getPyObject();
|
||||
}
|
||||
|
||||
Py::Boolean ShapeFix_FacePy::getFixWireMode() const
|
||||
{
|
||||
return Py::Boolean(getShapeFix_FacePtr()->FixWireMode());
|
||||
}
|
||||
|
||||
void ShapeFix_FacePy::setFixWireMode(Py::Boolean arg)
|
||||
{
|
||||
getShapeFix_FacePtr()->FixWireMode() = arg;
|
||||
}
|
||||
|
||||
Py::Boolean ShapeFix_FacePy::getFixOrientationMode() const
|
||||
{
|
||||
return Py::Boolean(getShapeFix_FacePtr()->FixOrientationMode());
|
||||
}
|
||||
|
||||
void ShapeFix_FacePy::setFixOrientationMode(Py::Boolean arg)
|
||||
{
|
||||
getShapeFix_FacePtr()->FixOrientationMode() = arg;
|
||||
}
|
||||
|
||||
Py::Boolean ShapeFix_FacePy::getFixAddNaturalBoundMode() const
|
||||
{
|
||||
return Py::Boolean(getShapeFix_FacePtr()->FixAddNaturalBoundMode());
|
||||
}
|
||||
|
||||
void ShapeFix_FacePy::setFixAddNaturalBoundMode(Py::Boolean arg)
|
||||
{
|
||||
getShapeFix_FacePtr()->FixAddNaturalBoundMode() = arg;
|
||||
}
|
||||
|
||||
Py::Boolean ShapeFix_FacePy::getFixMissingSeamMode() const
|
||||
{
|
||||
return Py::Boolean(getShapeFix_FacePtr()->FixMissingSeamMode());
|
||||
}
|
||||
|
||||
void ShapeFix_FacePy::setFixMissingSeamMode(Py::Boolean arg)
|
||||
{
|
||||
getShapeFix_FacePtr()->FixMissingSeamMode() = arg;
|
||||
}
|
||||
|
||||
Py::Boolean ShapeFix_FacePy::getFixSmallAreaWireMode() const
|
||||
{
|
||||
return Py::Boolean(getShapeFix_FacePtr()->FixSmallAreaWireMode());
|
||||
}
|
||||
|
||||
void ShapeFix_FacePy::setFixSmallAreaWireMode(Py::Boolean arg)
|
||||
{
|
||||
getShapeFix_FacePtr()->FixSmallAreaWireMode() = arg;
|
||||
}
|
||||
|
||||
Py::Boolean ShapeFix_FacePy::getRemoveSmallAreaFaceMode() const
|
||||
{
|
||||
return Py::Boolean(getShapeFix_FacePtr()->RemoveSmallAreaFaceMode());
|
||||
}
|
||||
|
||||
void ShapeFix_FacePy::setRemoveSmallAreaFaceMode(Py::Boolean arg)
|
||||
{
|
||||
getShapeFix_FacePtr()->RemoveSmallAreaFaceMode() = arg;
|
||||
}
|
||||
|
||||
Py::Boolean ShapeFix_FacePy::getFixIntersectingWiresMode() const
|
||||
{
|
||||
return Py::Boolean(getShapeFix_FacePtr()->FixIntersectingWiresMode());
|
||||
}
|
||||
|
||||
void ShapeFix_FacePy::setFixIntersectingWiresMode(Py::Boolean arg)
|
||||
{
|
||||
getShapeFix_FacePtr()->FixIntersectingWiresMode() = arg;
|
||||
}
|
||||
|
||||
Py::Boolean ShapeFix_FacePy::getFixLoopWiresMode() const
|
||||
{
|
||||
return Py::Boolean(getShapeFix_FacePtr()->FixLoopWiresMode());
|
||||
}
|
||||
|
||||
void ShapeFix_FacePy::setFixLoopWiresMode(Py::Boolean arg)
|
||||
{
|
||||
getShapeFix_FacePtr()->FixLoopWiresMode() = arg;
|
||||
}
|
||||
|
||||
Py::Boolean ShapeFix_FacePy::getFixSplitFaceMode() const
|
||||
{
|
||||
return Py::Boolean(getShapeFix_FacePtr()->FixSplitFaceMode());
|
||||
}
|
||||
|
||||
void ShapeFix_FacePy::setFixSplitFaceMode(Py::Boolean arg)
|
||||
{
|
||||
getShapeFix_FacePtr()->FixSplitFaceMode() = arg;
|
||||
}
|
||||
|
||||
Py::Boolean ShapeFix_FacePy::getAutoCorrectPrecisionMode() const
|
||||
{
|
||||
return Py::Boolean(getShapeFix_FacePtr()->AutoCorrectPrecisionMode());
|
||||
}
|
||||
|
||||
void ShapeFix_FacePy::setAutoCorrectPrecisionMode(Py::Boolean arg)
|
||||
{
|
||||
getShapeFix_FacePtr()->AutoCorrectPrecisionMode() = arg;
|
||||
}
|
||||
|
||||
Py::Boolean ShapeFix_FacePy::getFixPeriodicDegeneratedMode() const
|
||||
{
|
||||
return Py::Boolean(getShapeFix_FacePtr()->FixPeriodicDegeneratedMode());
|
||||
}
|
||||
|
||||
void ShapeFix_FacePy::setFixPeriodicDegeneratedMode(Py::Boolean arg)
|
||||
{
|
||||
getShapeFix_FacePtr()->FixPeriodicDegeneratedMode() = arg;
|
||||
}
|
||||
|
||||
PyObject *ShapeFix_FacePy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int ShapeFix_FacePy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -45,8 +45,11 @@ PyObject *ShapeFix_RootPy::PyMake(struct _typeobject *, PyObject *, PyObject *)
|
||||
}
|
||||
|
||||
// constructor method
|
||||
int ShapeFix_RootPy::PyInit(PyObject* /*args*/, PyObject* /*kwds*/)
|
||||
int ShapeFix_RootPy::PyInit(PyObject* args, PyObject* /*kwds*/)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -394,3 +394,99 @@ class PartTestRuledSurface(unittest.TestCase):
|
||||
|
||||
def tearDown(self):
|
||||
FreeCAD.closeDocument(self.Doc.Name)
|
||||
|
||||
class PartTestShapeFix(unittest.TestCase):
|
||||
def testShapeFix_Root(self):
|
||||
with self.assertRaises(TypeError):
|
||||
Part.ShapeFix.Root([])
|
||||
|
||||
fix = Part.ShapeFix.Root()
|
||||
print (fix)
|
||||
|
||||
fix.Precision = 0.0
|
||||
self.assertEqual(fix.Precision, 0.0)
|
||||
|
||||
fix.MinTolerance = 0.0
|
||||
self.assertEqual(fix.MinTolerance, 0.0)
|
||||
|
||||
fix.MaxTolerance = 0.5
|
||||
self.assertEqual(fix.MaxTolerance, 0.5)
|
||||
|
||||
self.assertEqual(fix.limitTolerance(0.25), 0.25)
|
||||
|
||||
def testShapeFix_Face(self):
|
||||
surface = Part.Plane()
|
||||
face = surface.toShape(-1, 1, -1, 1)
|
||||
|
||||
Part.ShapeFix.Face()
|
||||
Part.ShapeFix.Face(surface, 0.00001, True)
|
||||
with self.assertRaises(TypeError):
|
||||
Part.ShapeFix.Face([])
|
||||
|
||||
fix = Part.ShapeFix.Face(face)
|
||||
print (fix)
|
||||
|
||||
fix.fixOrientation()
|
||||
fix.fixAddNaturalBound()
|
||||
fix.fixMissingSeam()
|
||||
fix.fixSmallAreaWire(True)
|
||||
fix.fixLoopWire()
|
||||
fix.fixIntersectingWires()
|
||||
fix.fixWiresTwoCoincidentEdges()
|
||||
fix.fixPeriodicDegenerated()
|
||||
fix.perform()
|
||||
|
||||
fix.add(face.OuterWire)
|
||||
current = fix.face()
|
||||
result = fix.result()
|
||||
|
||||
fix.FixWireMode = True
|
||||
self.assertEqual(fix.FixWireMode, True)
|
||||
|
||||
fix.FixOrientationMode = True
|
||||
self.assertEqual(fix.FixOrientationMode, True)
|
||||
|
||||
fix.FixAddNaturalBoundMode = True
|
||||
self.assertEqual(fix.FixAddNaturalBoundMode, True)
|
||||
|
||||
fix.FixMissingSeamMode = True
|
||||
self.assertEqual(fix.FixMissingSeamMode, True)
|
||||
|
||||
fix.FixSmallAreaWireMode = True
|
||||
self.assertEqual(fix.FixSmallAreaWireMode, True)
|
||||
|
||||
fix.RemoveSmallAreaFaceMode = True
|
||||
self.assertEqual(fix.RemoveSmallAreaFaceMode, True)
|
||||
|
||||
fix.FixIntersectingWiresMode = True
|
||||
self.assertEqual(fix.FixIntersectingWiresMode, True)
|
||||
|
||||
fix.FixLoopWiresMode = True
|
||||
self.assertEqual(fix.FixLoopWiresMode, True)
|
||||
|
||||
fix.FixSplitFaceMode = True
|
||||
self.assertEqual(fix.FixSplitFaceMode, True)
|
||||
|
||||
fix.AutoCorrectPrecisionMode = True
|
||||
self.assertEqual(fix.AutoCorrectPrecisionMode, True)
|
||||
|
||||
fix.FixPeriodicDegeneratedMode = True
|
||||
self.assertEqual(fix.FixPeriodicDegeneratedMode, True)
|
||||
|
||||
fix.clearModes()
|
||||
|
||||
def testShapeFix_Shell(self):
|
||||
surface = Part.Plane()
|
||||
face = surface.toShape(-1, 1, -1, 1)
|
||||
shell = Part.Shell([face])
|
||||
|
||||
Part.ShapeFix.Shell()
|
||||
with self.assertRaises(TypeError):
|
||||
Part.ShapeFix.Face([])
|
||||
|
||||
fix = Part.ShapeFix.Shell(shell)
|
||||
fix.init(shell)
|
||||
print (fix)
|
||||
fix.perform()
|
||||
fix.shell()
|
||||
fix.shape()
|
||||
|
||||
Reference in New Issue
Block a user