diff --git a/src/Mod/Mesh/App/CMakeLists.txt b/src/Mod/Mesh/App/CMakeLists.txt
index d8b34dab47..96ece0f970 100644
--- a/src/Mod/Mesh/App/CMakeLists.txt
+++ b/src/Mod/Mesh/App/CMakeLists.txt
@@ -36,6 +36,12 @@ generate_from_xml(MeshFeaturePy)
generate_from_xml(MeshPointPy)
generate_from_xml(MeshPy)
+generate_from_py_(EdgePy)
+generate_from_py_(FacetPy)
+generate_from_py_(MeshFeaturePy)
+generate_from_py_(MeshPointPy)
+generate_from_py_(MeshPy)
+
SET(Mesh_XML_SRCS
EdgePy.xml
FacetPy.xml
diff --git a/src/Mod/Mesh/App/EdgePy.pyi b/src/Mod/Mesh/App/EdgePy.pyi
new file mode 100644
index 0000000000..f2dc9872de
--- /dev/null
+++ b/src/Mod/Mesh/App/EdgePy.pyi
@@ -0,0 +1,63 @@
+from typing import Final
+
+from Base.Metadata import export
+from Base.PyObjectBase import PyObjectBase
+
+@export(
+ Father="PyObjectBase",
+ Name="EdgePy",
+ Twin="Edge",
+ TwinPointer="Edge",
+ Include="Mod/Mesh/App/Edge.h",
+ Namespace="Mesh",
+ FatherInclude="Base/PyObjectBase.h",
+ FatherNamespace="Base",
+ Constructor=True,
+ Delete=True,
+)
+class EdgePy(PyObjectBase):
+ """
+ Edge in mesh
+ This is an edge of a facet in a MeshObject. You can get it by e.g. iterating over the facets of a
+ mesh and calling getEdge(index).
+ """
+
+ def intersectWithEdge(self) -> Any:
+ """intersectWithEdge(Edge) -> list
+ Get a list of intersection points with another edge."""
+ ...
+
+ def isParallel(self) -> Any:
+ """isParallel(Edge) -> bool
+ Checks if the two edges are parallel."""
+ ...
+
+ def isCollinear(self) -> Any:
+ """isCollinear(Edge) -> bool
+ Checks if the two edges are collinear."""
+ ...
+
+ def unbound(self) -> Any:
+ """method unbound()
+ Cut the connection to a MeshObject. The edge becomes
+ free and is more or less a simple edge.
+ After calling unbound() no topological operation will
+ work!"""
+ ...
+ Index: Final[int]
+ """The index of this edge of the facet"""
+
+ Points: Final[list]
+ """A list of points of the edge"""
+
+ PointIndices: Final[tuple]
+ """The index tuple of point vertices of the mesh this edge is built of"""
+
+ NeighbourIndices: Final[tuple]
+ """The index tuple of neighbour facets of the mesh this edge is adjacent with"""
+
+ Length: Final[float]
+ """The length of the edge"""
+
+ Bound: Final[bool]
+ """Bound state of the edge"""
diff --git a/src/Mod/Mesh/App/FacetPy.pyi b/src/Mod/Mesh/App/FacetPy.pyi
new file mode 100644
index 0000000000..3768508193
--- /dev/null
+++ b/src/Mod/Mesh/App/FacetPy.pyi
@@ -0,0 +1,92 @@
+from typing import Any, Final
+
+from Base.Metadata import export
+from Base.PyObjectBase import PyObjectBase
+
+@export(
+ Father="PyObjectBase",
+ Name="FacetPy",
+ Twin="Facet",
+ TwinPointer="Facet",
+ Include="Mod/Mesh/App/Facet.h",
+ Namespace="Mesh",
+ FatherInclude="Base/PyObjectBase.h",
+ FatherNamespace="Base",
+ Constructor=True,
+ Delete=True,
+)
+class FacetPy(PyObjectBase):
+ """
+ Facet in mesh
+ This is a facet in a MeshObject. You can get it by e.g. iterating a
+ mesh. The facet has a connection to its mesh and allows therefore
+ topological operations. It is also possible to create an unbounded facet e.g. to create
+ a mesh. In this case the topological operations will fail. The same is
+ when you cut the bound to the mesh by calling unbound().
+ """
+
+ def unbound(self) -> Any:
+ """method unbound()
+ Cut the connection to a MeshObject. The facet becomes
+ free and is more or less a simple facet.
+ After calling unbound() no topological operation will
+ work!"""
+ ...
+
+ def intersect(self) -> Any:
+ """intersect(Facet) -> list
+ Get a list of intersection points with another triangle."""
+ ...
+
+ def isDegenerated(self) -> Any:
+ """isDegenerated([float]) -> boolean
+ Returns true if the facet is degenerated, otherwise false."""
+ ...
+
+ def isDeformed(self) -> Any:
+ """isDegenerated(MinAngle, MaxAngle) -> boolean
+ Returns true if the facet is deformed, otherwise false.
+ A triangle is considered deformed if an angle is less than MinAngle
+ or higher than MaxAngle.
+ The two angles are given in radian."""
+ ...
+
+ def getEdge(self) -> Any:
+ """getEdge(int) -> Edge
+ Returns the edge of the facet."""
+ ...
+ Index: Final[int]
+ """The index of this facet in the MeshObject"""
+
+ Bound: Final[bool]
+ """Bound state of the facet"""
+
+ Normal: Final[Any]
+ """Normal vector of the facet."""
+
+ Points: Final[list]
+ """A list of points of the facet"""
+
+ PointIndices: Final[tuple]
+ """The index tuple of point vertices of the mesh this facet is built of"""
+
+ NeighbourIndices: Final[tuple]
+ """The index tuple of neighbour facets of the mesh this facet is adjacent with"""
+
+ Area: Final[float]
+ """The area of the facet"""
+
+ AspectRatio: Final[float]
+ """The aspect ratio of the facet computed by longest edge and its height"""
+
+ AspectRatio2: Final[float]
+ """The aspect ratio of the facet computed by radius of circum-circle and in-circle"""
+
+ Roundness: Final[float]
+ """The roundness of the facet"""
+
+ CircumCircle: Final[tuple]
+ """The center and radius of the circum-circle"""
+
+ InCircle: Final[tuple]
+ """The center and radius of the in-circle"""
diff --git a/src/Mod/Mesh/App/MeshFeaturePy.pyi b/src/Mod/Mesh/App/MeshFeaturePy.pyi
new file mode 100644
index 0000000000..13237b3284
--- /dev/null
+++ b/src/Mod/Mesh/App/MeshFeaturePy.pyi
@@ -0,0 +1,92 @@
+from typing import Any
+
+from Base.Metadata import export
+
+from App.GeoFeature import GeoFeature
+
+@export(
+ Father="GeoFeaturePy",
+ Name="MeshFeaturePy",
+ Twin="Feature",
+ TwinPointer="Feature",
+ Include="Mod/Mesh/App/MeshFeature.h",
+ Namespace="Mesh",
+ FatherInclude="App/GeoFeaturePy.h",
+ FatherNamespace="App",
+)
+class MeshFeaturePy(GeoFeature):
+ """
+ The Mesh::Feature class handles meshes.
+ The Mesh.MeshFeature() function is for internal use only and cannot be used to create instances of this class.
+ Therefore you must have a reference to a document, e.g. 'd' then you can create an instance with
+ d.addObject("Mesh::Feature").
+ """
+
+ def countPoints(self) -> Any:
+ """Return the number of vertices of the mesh object"""
+ ...
+
+ def countFacets(self) -> Any:
+ """Return the number of facets of the mesh object"""
+ ...
+
+ def harmonizeNormals(self) -> Any:
+ """Adjust wrong oriented facets"""
+ ...
+
+ def smooth(self) -> Any:
+ """Smooth the mesh data"""
+ ...
+
+ def decimate(self) -> Any:
+ """
+ Decimate the mesh
+ decimate(tolerance(Float), reduction(Float))
+ tolerance: maximum error
+ reduction: reduction factor must be in the range [0.0,1.0]
+ Example:
+ mesh.decimate(0.5, 0.1) # reduction by up to 10 percent
+ mesh.decimate(0.5, 0.9) # reduction by up to 90 percent
+
+ or
+
+ decimate(targwt size(int))
+ mesh.decimate(mesh.CountFacets/2)
+ """
+ ...
+
+ def removeNonManifolds(self) -> Any:
+ """Remove non-manifolds"""
+ ...
+
+ def removeNonManifoldPoints(self) -> Any:
+ """Remove non-manifold points"""
+ ...
+
+ def fixIndices(self) -> Any:
+ """Repair any invalid indices"""
+ ...
+
+ def fixDegenerations(self) -> Any:
+ """Remove degenerated facets"""
+ ...
+
+ def removeDuplicatedFacets(self) -> Any:
+ """Remove duplicated facets"""
+ ...
+
+ def removeDuplicatedPoints(self) -> Any:
+ """Remove duplicated points"""
+ ...
+
+ def fixSelfIntersections(self) -> Any:
+ """Repair self-intersections"""
+ ...
+
+ def removeFoldsOnSurface(self) -> Any:
+ """Remove folds on surfaces"""
+ ...
+
+ def removeInvalidPoints(self) -> Any:
+ """Remove points with invalid coordinates (NaN)"""
+ ...
diff --git a/src/Mod/Mesh/App/MeshFeaturePy.xml b/src/Mod/Mesh/App/MeshFeaturePy.xml
index 6a6292e202..3049d4296e 100644
--- a/src/Mod/Mesh/App/MeshFeaturePy.xml
+++ b/src/Mod/Mesh/App/MeshFeaturePy.xml
@@ -40,18 +40,18 @@ d.addObject("Mesh::Feature").
- Decimate the mesh
- decimate(tolerance(Float), reduction(Float))
- tolerance: maximum error
- reduction: reduction factor must be in the range [0.0,1.0]
- Example:
- mesh.decimate(0.5, 0.1) # reduction by up to 10 percent
- mesh.decimate(0.5, 0.9) # reduction by up to 90 percent
+Decimate the mesh
+decimate(tolerance(Float), reduction(Float))
+tolerance: maximum error
+reduction: reduction factor must be in the range [0.0,1.0]
+Example:
+mesh.decimate(0.5, 0.1) # reduction by up to 10 percent
+mesh.decimate(0.5, 0.9) # reduction by up to 90 percent
- or
+or
- decimate(targwt size(int))
- mesh.decimate(mesh.CountFacets/2)
+decimate(targwt size(int))
+mesh.decimate(mesh.CountFacets/2)
diff --git a/src/Mod/Mesh/App/MeshPointPy.pyi b/src/Mod/Mesh/App/MeshPointPy.pyi
new file mode 100644
index 0000000000..90df79a66d
--- /dev/null
+++ b/src/Mod/Mesh/App/MeshPointPy.pyi
@@ -0,0 +1,54 @@
+from typing import Any, Final
+
+from Base.Metadata import export
+from Base.PyObjectBase import PyObjectBase
+
+@export(
+ Father="PyObjectBase",
+ Name="MeshPointPy",
+ Twin="MeshPoint",
+ TwinPointer="MeshPoint",
+ Include="Mod/Mesh/App/MeshPoint.h",
+ Namespace="Mesh",
+ FatherInclude="Base/PyObjectBase.h",
+ FatherNamespace="Base",
+ Constructor=True,
+ Delete=True,
+)
+class MeshPointPy(PyObjectBase):
+ """
+ Point in mesh
+ This is a point in a MeshObject. You can get it by e.g. iterating a
+ mesh. The point has a connection to its mesh and allows therefore
+ topological operations. It is also possible to create an unbounded mesh point e.g. to create
+ a mesh. In this case the topological operations will fail. The same is
+ when you cut the bound to the mesh by calling unbound().
+ """
+
+ def unbound(self) -> Any:
+ """method unbound()
+ Cut the connection to a MeshObject. The point becomes
+ free and is more or less a simple vector/point.
+ After calling unbound() no topological operation will
+ work!"""
+ ...
+ Index: Final[int]
+ """The index of this point in the MeshObject"""
+
+ Bound: Final[bool]
+ """Bound state of the point"""
+
+ Normal: Final[Any]
+ """Normal vector of the point computed by the surrounding mesh."""
+
+ Vector: Final[Any]
+ """Vector of the point."""
+
+ x: Final[float]
+ """The X component of the point."""
+
+ y: Final[float]
+ """The Y component of the point."""
+
+ z: Final[float]
+ """The Z component of the point."""
diff --git a/src/Mod/Mesh/App/MeshPy.pyi b/src/Mod/Mesh/App/MeshPy.pyi
new file mode 100644
index 0000000000..fe925667b6
--- /dev/null
+++ b/src/Mod/Mesh/App/MeshPy.pyi
@@ -0,0 +1,534 @@
+from typing import Any, Final
+
+from Base.Metadata import constmethod, export
+
+from App.ComplexGeoData import ComplexGeoData
+
+@export(
+ Father="ComplexGeoDataPy",
+ Name="MeshPy",
+ Twin="MeshObject",
+ TwinPointer="MeshObject",
+ Include="Mod/Mesh/App/Mesh.h",
+ Namespace="Mesh",
+ FatherInclude="App/ComplexGeoDataPy.h",
+ FatherNamespace="Data",
+ Constructor=True,
+)
+@class_declarations(
+ """
+ private:
+ friend class PropertyMeshKernel;
+ class PropertyMeshKernel* parentProperty = nullptr;"""
+)
+class MeshPy(ComplexGeoData):
+ """Mesh() -- Create an empty mesh object.
+
+ This class allows one to manipulate the mesh object by adding new facets, deleting facets, importing from an STL file,
+ transforming the mesh and much more.
+ For a complete overview of what can be done see also the documentation of mesh.
+ A mesh object cannot be added to an existing document directly. Therefore the document must create an object
+ with a property class that supports meshes.
+ Example:
+ m = Mesh.Mesh()
+ ... # Manipulate the mesh
+ d = FreeCAD.activeDocument() # Get a reference to the actie document
+ f = d.addObject("Mesh::Feature", "Mesh") # Create a mesh feature
+ f.Mesh = m # Assign the mesh object to the internal property
+ d.recompute()
+ """
+
+ def read(self, **kwargs) -> Any:
+ """Read in a mesh object from file.
+ mesh.read(Filename='mymesh.stl')
+ mesh.read(Stream=file,Format='STL')"""
+ ...
+
+ @constmethod
+ def write(self, **kwargs) -> Any:
+ """Write the mesh object into file.
+ mesh.write(Filename='mymesh.stl',[Format='STL',Name='Object name',Material=colors])
+ mesh.write(Stream=file,Format='STL',[Name='Object name',Material=colors])"""
+ ...
+
+ @constmethod
+ def writeInventor(self) -> Any:
+ """Write the mesh in OpenInventor format to a string."""
+ ...
+
+ @constmethod
+ def copy(self) -> Any:
+ """Create a copy of this mesh"""
+ ...
+
+ def offset(self) -> Any:
+ """Move the point along their normals"""
+ ...
+
+ def offsetSpecial(self) -> Any:
+ """Move the point along their normals"""
+ ...
+
+ @constmethod
+ def crossSections(self) -> Any:
+ """Get cross-sections of the mesh through several planes"""
+ ...
+
+ @constmethod
+ def unite(self) -> Any:
+ """Union of this and the given mesh object."""
+ ...
+
+ @constmethod
+ def intersect(self) -> Any:
+ """Intersection of this and the given mesh object."""
+ ...
+
+ @constmethod
+ def difference(self) -> Any:
+ """Difference of this and the given mesh object."""
+ ...
+
+ @constmethod
+ def inner(self) -> Any:
+ """Get the part inside of the intersection"""
+ ...
+
+ @constmethod
+ def outer(self) -> Any:
+ """Get the part outside the intersection"""
+ ...
+
+ @constmethod
+ def section(self, **kwargs) -> Any:
+ """Get the section curves of this and the given mesh object.
+ lines = mesh.section(mesh2, [ConnectLines=True, MinDist=0.0001])"""
+ ...
+
+ def translate(self) -> Any:
+ """Apply a translation to the mesh"""
+ ...
+
+ def rotate(self) -> Any:
+ """Apply a rotation to the mesh"""
+ ...
+
+ def transform(self) -> Any:
+ """Apply a transformation to the mesh"""
+ ...
+
+ def transformToEigen(self) -> Any:
+ """Transform the mesh to its eigenbase"""
+ ...
+
+ @constmethod
+ def getEigenSystem(self) -> Any:
+ """Get Eigen base of the mesh"""
+ ...
+
+ def addFacet(self) -> Any:
+ """Add a facet to the mesh"""
+ ...
+
+ def addFacets(self) -> Any:
+ """Add a list of facets to the mesh"""
+ ...
+
+ def removeFacets(self) -> Any:
+ """Remove a list of facet indices from the mesh"""
+ ...
+
+ def removeNeedles(self) -> Any:
+ """Remove all edges that are smaller than a given length"""
+ ...
+
+ def removeFullBoundaryFacets(self) -> Any:
+ """Remove facets whose all three points are on the boundary"""
+ ...
+
+ @constmethod
+ def getInternalFacets(self) -> Any:
+ """Builds a list of facet indices with triangles that are inside a volume mesh"""
+ ...
+
+ def rebuildNeighbourHood(self) -> Any:
+ """Repairs the neighbourhood which might be broken"""
+ ...
+
+ def addMesh(self) -> Any:
+ """Combine this mesh with another mesh."""
+ ...
+
+ def setPoint(self) -> Any:
+ """setPoint(int, Vector)
+ Sets the point at index."""
+ ...
+
+ def movePoint(self) -> Any:
+ """movePoint(int, Vector)
+ This method moves the point in the mesh along the
+ given vector. This affects the geometry of the mesh.
+ Be aware that moving points may cause self-intersections."""
+ ...
+
+ @constmethod
+ def getPointNormals(self) -> Any:
+ """getPointNormals()
+ Get the normals of the points."""
+ ...
+
+ def addSegment(self) -> Any:
+ """Add a list of facet indices that describes a segment to the mesh"""
+ ...
+
+ @constmethod
+ def countSegments(self) -> Any:
+ """Get the number of segments which may also be 0"""
+ ...
+
+ @constmethod
+ def getSegment(self) -> Any:
+ """Get a list of facet indices that describes a segment"""
+ ...
+
+ @constmethod
+ def getSeparateComponents(self) -> Any:
+ """Returns a list containing the different
+ components (separated areas) of the mesh as separate meshes
+
+ import Mesh
+ for c in mesh.getSeparatecomponents():
+ Mesh.show(c)"""
+ ...
+
+ @constmethod
+ def getFacetSelection(self) -> Any:
+ """Get a list of the indices of selected facets"""
+ ...
+
+ @constmethod
+ def getPointSelection(self) -> Any:
+ """Get a list of the indices of selected points"""
+ ...
+
+ @constmethod
+ def meshFromSegment(self) -> Any:
+ """Create a mesh from segment"""
+ ...
+
+ def clear(self) -> Any:
+ """Clear the mesh"""
+ ...
+
+ @constmethod
+ def isSolid(self) -> Any:
+ """Check if the mesh is a solid"""
+ ...
+
+ @constmethod
+ def hasNonManifolds(self) -> Any:
+ """Check if the mesh has non-manifolds"""
+ ...
+
+ def removeNonManifolds(self) -> Any:
+ """Remove non-manifolds"""
+ ...
+
+ def removeNonManifoldPoints(self) -> Any:
+ """Remove non-manifold points"""
+ ...
+
+ @constmethod
+ def hasSelfIntersections(self) -> Any:
+ """Check if the mesh intersects itself"""
+ ...
+
+ @constmethod
+ def getSelfIntersections(self) -> Any:
+ """Returns a tuple of indices of intersecting triangles"""
+ ...
+
+ def fixSelfIntersections(self) -> Any:
+ """Repair self-intersections"""
+ ...
+
+ def removeFoldsOnSurface(self) -> Any:
+ """Remove folds on surfaces"""
+ ...
+
+ @constmethod
+ def hasNonUniformOrientedFacets(self) -> Any:
+ """Check if the mesh has facets with inconsistent orientation"""
+ ...
+
+ @constmethod
+ def countNonUniformOrientedFacets(self) -> Any:
+ """Get the number of wrong oriented facets"""
+ ...
+
+ @constmethod
+ def getNonUniformOrientedFacets(self) -> Any:
+ """Get a tuple of wrong oriented facets"""
+ ...
+
+ @constmethod
+ def hasInvalidPoints(self) -> Any:
+ """Check if the mesh has points with invalid coordinates (NaN)"""
+ ...
+
+ def removeInvalidPoints(self) -> Any:
+ """Remove points with invalid coordinates (NaN)"""
+ ...
+
+ @constmethod
+ def hasPointsOnEdge(self) -> Any:
+ """Check if points lie on edges"""
+ ...
+
+ def removePointsOnEdge(self, **kwargs) -> Any:
+ """removePointsOnEdge(FillBoundary=False)
+ Remove points that lie on edges.
+ If FillBoundary is True then the holes by removing the affected facets
+ will be re-filled."""
+ ...
+
+ @constmethod
+ def hasInvalidNeighbourhood(self) -> Any:
+ """Check if the mesh has invalid neighbourhood indices"""
+ ...
+
+ @constmethod
+ def hasPointsOutOfRange(self) -> Any:
+ """Check if the mesh has point indices that are out of range"""
+ ...
+
+ @constmethod
+ def hasFacetsOutOfRange(self) -> Any:
+ """Check if the mesh has facet indices that are out of range"""
+ ...
+
+ @constmethod
+ def hasCorruptedFacets(self) -> Any:
+ """Check if the mesh has corrupted facets"""
+ ...
+
+ @constmethod
+ def countComponents(self) -> Any:
+ """Get the number of topologic independent areas"""
+ ...
+
+ def removeComponents(self) -> Any:
+ """Remove components with less or equal to number of given facets"""
+ ...
+
+ def fixIndices(self) -> Any:
+ """Repair any invalid indices"""
+ ...
+
+ def fixCaps(self) -> Any:
+ """Repair caps by swapping the edge"""
+ ...
+
+ def fixDeformations(self) -> Any:
+ """Repair deformed facets"""
+ ...
+
+ def fixDegenerations(self) -> Any:
+ """Remove degenerated facets"""
+ ...
+
+ def removeDuplicatedPoints(self) -> Any:
+ """Remove duplicated points"""
+ ...
+
+ def removeDuplicatedFacets(self) -> Any:
+ """Remove duplicated facets"""
+ ...
+
+ def refine(self) -> Any:
+ """Refine the mesh"""
+ ...
+
+ def splitEdges(self) -> Any:
+ """Split all edges"""
+ ...
+
+ def splitEdge(self) -> Any:
+ """Split edge"""
+ ...
+
+ def splitFacet(self) -> Any:
+ """Split facet"""
+ ...
+
+ def swapEdge(self) -> Any:
+ """Swap the common edge with the neighbour"""
+ ...
+
+ def collapseEdge(self) -> Any:
+ """Remove an edge and both facets that share this edge"""
+ ...
+
+ def collapseFacet(self) -> Any:
+ """Remove a facet"""
+ ...
+
+ def collapseFacets(self) -> Any:
+ """Remove a list of facets"""
+ ...
+
+ def insertVertex(self) -> Any:
+ """Insert a vertex into a facet"""
+ ...
+
+ def snapVertex(self) -> Any:
+ """Insert a new facet at the border"""
+ ...
+
+ @constmethod
+ def printInfo(self) -> Any:
+ """Get detailed information about the mesh"""
+ ...
+
+ @constmethod
+ def foraminate(self) -> Any:
+ """Get a list of facet indices and intersection points"""
+ ...
+
+ def cut(self) -> Any:
+ """Cuts the mesh with a given closed polygon
+ cut(list, int) -> None
+ The argument list is an array of points, a polygon
+ The argument int is the mode: 0=inner, 1=outer"""
+ ...
+
+ def trim(self) -> Any:
+ """Trims the mesh with a given closed polygon
+ trim(list, int) -> None
+ The argument list is an array of points, a polygon
+ The argument int is the mode: 0=inner, 1=outer"""
+ ...
+
+ def trimByPlane(self) -> Any:
+ """Trims the mesh with a given plane
+ trimByPlane(Vector, Vector) -> None
+ The plane is defined by a base and normal vector. Depending on the
+ direction of the normal the part above or below will be kept."""
+ ...
+
+ @constmethod
+ def harmonizeNormals(self) -> Any:
+ """Adjust wrong oriented facets"""
+ ...
+
+ @constmethod
+ def flipNormals(self) -> Any:
+ """Flip the mesh normals"""
+ ...
+
+ @constmethod
+ def fillupHoles(self) -> Any:
+ """Fillup holes"""
+ ...
+
+ @constmethod
+ def smooth(self, **kwargs) -> Any:
+ """Smooth the mesh
+ smooth([iteration=1,maxError=FLT_MAX])"""
+ ...
+
+ def decimate(self) -> Any:
+ """Decimate the mesh
+ decimate(tolerance(Float), reduction(Float))
+ tolerance: maximum error
+ reduction: reduction factor must be in the range [0.0,1.0]
+ Example:
+ mesh.decimate(0.5, 0.1) # reduction by up to 10 percent
+ mesh.decimate(0.5, 0.9) # reduction by up to 90 percent"""
+ ...
+
+ def mergeFacets(self) -> Any:
+ """Merge facets to optimize topology"""
+ ...
+
+ @constmethod
+ def optimizeTopology(self) -> Any:
+ """Optimize the edges to get nicer facets"""
+ ...
+
+ @constmethod
+ def optimizeEdges(self) -> Any:
+ """Optimize the edges to get nicer facets"""
+ ...
+
+ @constmethod
+ def nearestFacetOnRay(self) -> Any:
+ """nearestFacetOnRay(tuple, tuple) -> dict
+ Get the index and intersection point of the nearest facet to a ray.
+ The first parameter is a tuple of three floats the base point of the ray,
+ the second parameter is ut uple of three floats for the direction.
+ The result is a dictionary with an index and the intersection point or
+ an empty dictionary if there is no intersection."""
+ ...
+
+ @constmethod
+ def getPlanarSegments(self) -> Any:
+ """getPlanarSegments(dev,[min faces=0]) -> list
+ Get all planes of the mesh as segment.
+ In the worst case each triangle can be regarded as single
+ plane if none of its neighbours is coplanar."""
+ ...
+
+ @constmethod
+ def getSegmentsOfType(self) -> Any:
+ """getSegmentsOfType(type, dev,[min faces=0]) -> list
+ Get all segments of type.
+ Type can be Plane, Cylinder or Sphere"""
+ ...
+
+ @constmethod
+ def getSegmentsByCurvature(self) -> Any:
+ """getSegmentsByCurvature(list) -> list
+ The argument list gives a list if tuples where it defines the preferred maximum curvature,
+ the preferred minimum curvature, the tolerances and the number of minimum faces for the segment.
+ Example:
+ c=(1.0, 0.0, 0.1, 0.1, 500) # search for a cylinder with radius 1.0
+ p=(0.0, 0.0, 0.1, 0.1, 500) # search for a plane
+ mesh.getSegmentsByCurvature([c,p])"""
+ ...
+
+ @constmethod
+ def getCurvaturePerVertex(self) -> Any:
+ """getCurvaturePerVertex() -> list
+ The items in the list contains minimum and maximum curvature with their directions
+ """
+ ...
+ Points: Final[list]
+ """A collection of the mesh points
+With this attribute it is possible to get access to the points of the mesh
+for p in mesh.Points:
+ print p.x, p.y, p.z"""
+
+ CountPoints: Final[int]
+ """Return the number of vertices of the mesh object."""
+
+ CountEdges: Final[int]
+ """Return the number of edges of the mesh object."""
+
+ Facets: Final[list]
+ """A collection of facets
+With this attribute it is possible to get access to the facets of the mesh
+for p in mesh.Facets:
+ print p"""
+
+ CountFacets: Final[int]
+ """Return the number of facets of the mesh object."""
+
+ Topology: Final[tuple]
+ """Return the points and face indices as tuple."""
+
+ Area: Final[float]
+ """Return the area of the mesh object."""
+
+ Volume: Final[float]
+ """Return the volume of the mesh object."""
diff --git a/src/Mod/Mesh/App/MeshPy.xml b/src/Mod/Mesh/App/MeshPy.xml
index 7acbb5f69a..d68f43574f 100644
--- a/src/Mod/Mesh/App/MeshPy.xml
+++ b/src/Mod/Mesh/App/MeshPy.xml
@@ -20,12 +20,12 @@ For a complete overview of what can be done see also the documentation of mesh.
A mesh object cannot be added to an existing document directly. Therefore the document must create an object
with a property class that supports meshes.
Example:
- m = Mesh.Mesh()
- ... # Manipulate the mesh
- d = FreeCAD.activeDocument() # Get a reference to the actie document
- f = d.addObject("Mesh::Feature", "Mesh") # Create a mesh feature
- f.Mesh = m # Assign the mesh object to the internal property
- d.recompute()
+m = Mesh.Mesh()
+... # Manipulate the mesh
+d = FreeCAD.activeDocument() # Get a reference to the actie document
+f = d.addObject("Mesh::Feature", "Mesh") # Create a mesh feature
+f.Mesh = m # Assign the mesh object to the internal property
+d.recompute()
@@ -166,25 +166,26 @@ lines = mesh.section(mesh2, [ConnectLines=True, MinDist=0.0001])
- setPoint(int, Vector)
- Sets the point at index.
+setPoint(int, Vector)
+Sets the point at index.
- movePoint(int, Vector)
- This method moves the point in the mesh along the
- given vector. This affects the geometry of the mesh.
- Be aware that moving points may cause self-intersections.
+
+movePoint(int, Vector)
+This method moves the point in the mesh along the
+given vector. This affects the geometry of the mesh.
+Be aware that moving points may cause self-intersections.
- getPointNormals()
- Get the normals of the points.
+getPointNormals()
+Get the normals of the points.
@@ -205,12 +206,13 @@ lines = mesh.section(mesh2, [ConnectLines=True, MinDist=0.0001])
- Returns a list containing the different
+
+Returns a list containing the different
components (separated areas) of the mesh as separate meshes
import Mesh
for c in mesh.getSeparatecomponents():
- Mesh.show(c)
+Mesh.show(c)
@@ -485,13 +487,13 @@ smooth([iteration=1,maxError=FLT_MAX])
- Decimate the mesh
- decimate(tolerance(Float), reduction(Float))
- tolerance: maximum error
- reduction: reduction factor must be in the range [0.0,1.0]
- Example:
- mesh.decimate(0.5, 0.1) # reduction by up to 10 percent
- mesh.decimate(0.5, 0.9) # reduction by up to 90 percent
+Decimate the mesh
+decimate(tolerance(Float), reduction(Float))
+tolerance: maximum error
+reduction: reduction factor must be in the range [0.0,1.0]
+Example:
+mesh.decimate(0.5, 0.1) # reduction by up to 10 percent
+mesh.decimate(0.5, 0.9) # reduction by up to 90 percent
@@ -611,9 +613,9 @@ for p in mesh.Facets:
- private:
+
+ private:
friend class PropertyMeshKernel;
- class PropertyMeshKernel* parentProperty = nullptr;
-
+ class PropertyMeshKernel* parentProperty = nullptr;
diff --git a/src/Mod/Mesh/Gui/CMakeLists.txt b/src/Mod/Mesh/Gui/CMakeLists.txt
index 0c3506cd26..4bda63c12a 100644
--- a/src/Mod/Mesh/Gui/CMakeLists.txt
+++ b/src/Mod/Mesh/Gui/CMakeLists.txt
@@ -16,6 +16,7 @@ set(MeshGui_LIBS
)
generate_from_xml(ViewProviderMeshPy)
+generate_from_py_(ViewProviderMeshPy)
SET(MeshGui_XML_SRCS
ViewProviderMeshPy.xml
diff --git a/src/Mod/Mesh/Gui/ViewProviderMeshPy.pyi b/src/Mod/Mesh/Gui/ViewProviderMeshPy.pyi
new file mode 100644
index 0000000000..f5fa59bc01
--- /dev/null
+++ b/src/Mod/Mesh/Gui/ViewProviderMeshPy.pyi
@@ -0,0 +1,44 @@
+from typing import Any
+from Gui.ViewProviderGeometryObject import ViewProviderGeometryObject
+from Base.Metadata import export
+
+@export(
+ Father="ViewProviderGeometryObjectPy",
+ Name="ViewProviderMeshPy",
+ Twin="ViewProviderMesh",
+ TwinPointer="ViewProviderMesh",
+ Include="Mod/Mesh/Gui/ViewProvider.h",
+ Namespace="MeshGui",
+ FatherInclude="Gui/ViewProviderGeometryObjectPy.h",
+ FatherNamespace="Gui",
+)
+class ViewProviderMeshPy(ViewProviderGeometryObject):
+ """
+ This is the ViewProvider base class
+ """
+
+ def setSelection(self) -> Any:
+ """Select list of facets"""
+ ...
+
+ def addSelection(self) -> Any:
+ """Add list of facets to selection"""
+ ...
+
+ def removeSelection(self) -> Any:
+ """Remove list of facets from selection"""
+ ...
+
+ def invertSelection(self) -> Any:
+ """Invert the selection"""
+ ...
+
+ def clearSelection(self) -> Any:
+ """Clear the selection"""
+ ...
+
+ def highlightSegments(self) -> Any:
+ """Highlights the segments of a mesh with a given list of colors.
+ The number of elements of this list must be equal to the number of mesh segments.
+ """
+ ...