From e4e8625a4bbfc49a8fc76dd7507b952d95440231 Mon Sep 17 00:00:00 2001 From: Ian 'z0r0' Abreu Date: Fri, 18 Jul 2025 18:27:08 -0400 Subject: [PATCH] initial commit --- src/Mod/CAM/App/AreaPy.pyi | 106 +++++++++++++++++++++ src/Mod/CAM/App/AreaPy.xml | 6 +- src/Mod/CAM/App/CMakeLists.txt | 10 ++ src/Mod/CAM/App/CommandPy.pyi | 48 ++++++++++ src/Mod/CAM/App/CommandPy.xml | 4 +- src/Mod/CAM/App/FeatureAreaPy.pyi | 31 ++++++ src/Mod/CAM/App/FeaturePathCompoundPy.pyi | 26 ++++++ src/Mod/CAM/App/PathPy.pyi | 70 ++++++++++++++ src/Mod/CAM/App/VoronoiCellPy.pyi | 67 +++++++++++++ src/Mod/CAM/App/VoronoiEdgePy.pyi | 109 ++++++++++++++++++++++ src/Mod/CAM/App/VoronoiPy.pyi | 93 ++++++++++++++++++ src/Mod/CAM/App/VoronoiVertexPy.pyi | 43 +++++++++ 12 files changed, 608 insertions(+), 5 deletions(-) create mode 100644 src/Mod/CAM/App/AreaPy.pyi create mode 100644 src/Mod/CAM/App/CommandPy.pyi create mode 100644 src/Mod/CAM/App/FeatureAreaPy.pyi create mode 100644 src/Mod/CAM/App/FeaturePathCompoundPy.pyi create mode 100644 src/Mod/CAM/App/PathPy.pyi create mode 100644 src/Mod/CAM/App/VoronoiCellPy.pyi create mode 100644 src/Mod/CAM/App/VoronoiEdgePy.pyi create mode 100644 src/Mod/CAM/App/VoronoiPy.pyi create mode 100644 src/Mod/CAM/App/VoronoiVertexPy.pyi diff --git a/src/Mod/CAM/App/AreaPy.pyi b/src/Mod/CAM/App/AreaPy.pyi new file mode 100644 index 0000000000..37542345b6 --- /dev/null +++ b/src/Mod/CAM/App/AreaPy.pyi @@ -0,0 +1,106 @@ +from typing import Final, List, Any +from Base import object +from Base.Metadata import export + +@export( + Father="BaseClassPy", + Name="AreaPy", + Twin="Area", + TwinPointer="Area", + Include="Mod/CAM/App/Area.h", + Namespace="Path", + FatherInclude="Base/BaseClassPy.h", + FatherNamespace="Base", + ReadOnly=["Sections", "Shapes"], + Constructor=True, # Allow constructing this object + Delete=True, # Allow deleting this object +) +class AreaPy(object): + """ + FreeCAD python wrapper of libarea + + Path.Area(key=value ...) + + The constructor accepts the same parameters as setParams(...) to configure the object + All arguments are optional. + """ + + def add(self, **kwargs) -> Any: + """""" + ... + + def setPlane(self) -> Any: + """setPlane(shape): Set the working plane. + + The supplied shape does not need to be planar. Area will try to find planar + sub-shape (face, wire or edge). If more than one planar sub-shape is found, it + will prefer the top plane parallel to XY0 plane. If no working plane are set, + Area will try to find a working plane from the added children shape using the + same algorithm""" + ... + + def getShape(self, **kwargs) -> Any: + """getShape(index=-1,rebuild=False): Return the resulting shape + + + * index (-1): the index of the section. -1 means all sections. No effect on planar shape. + + + * rebuild: clean the internal cache and rebuild""" + ... + + def makeOffset(self, **kwargs) -> Any: + """Make an offset of the shape.""" + ... + + def makePocket(self, **kwargs) -> Any: + """Generate pocket toolpath of the shape.""" + ... + + def makeSections(self, **kwargs) -> Any: + """Make a list of area holding the sectioned children shapes on given heights.""" + ... + + def getClearedArea(self) -> Any: + """Gets the area cleared when a tool of the specified diameter follows the gcode represented in the path, ignoring cleared space above zmax and path segments that don't affect space within the x/y space of bbox.""" + ... + + def getRestArea(self) -> Any: + """Rest machining: Gets the area left to be machined, assuming some of this area has already been cleared by previous tool paths.""" + ... + + def toTopoShape(self) -> Any: + """Convert the Area object to a TopoShape.""" + ... + + def setParams(self, **kwargs) -> Any: + """Set algorithm parameters.""" + ... + + def setDefaultParams(self, **kwargs) -> Any: + """Static method to set the default parameters of all following Path.Area, plus the following additional parameters.""" + ... + + def getDefaultParams(self) -> Any: + """Static method to return the current default parameters.""" + ... + + def getParamsDesc(self, **kwargs) -> Any: + """Returns a list of supported parameters and their descriptions.""" + ... + + def getParams(self) -> Any: + """Get current algorithm parameters as a dictionary.""" + ... + + def abort(self, **kwargs) -> Any: + """Abort the current operation.""" + ... + Sections: Final[List] # ReadOnly + """List of sections in this area.""" + + Workplane: Any + """The current workplane. If no plane is set, it is derived from the added shapes.""" + + Shapes: Final[List] # ReadOnly + """A list of tuple: [(shape,op), ...] containing the added shapes together with their operation code""" diff --git a/src/Mod/CAM/App/AreaPy.xml b/src/Mod/CAM/App/AreaPy.xml index 9d420af481..32ecad002f 100644 --- a/src/Mod/CAM/App/AreaPy.xml +++ b/src/Mod/CAM/App/AreaPy.xml @@ -13,12 +13,14 @@ Delete="true"> - FreeCAD python wrapper of libarea + +FreeCAD python wrapper of libarea Path.Area(key=value ...) The constructor accepts the same parameters as setParams(...) to configure the object -All arguments are optional. +All arguments are optional. + diff --git a/src/Mod/CAM/App/CMakeLists.txt b/src/Mod/CAM/App/CMakeLists.txt index 7aea97cc19..616896c5a6 100644 --- a/src/Mod/CAM/App/CMakeLists.txt +++ b/src/Mod/CAM/App/CMakeLists.txt @@ -31,6 +31,16 @@ generate_from_xml(VoronoiCellPy) generate_from_xml(VoronoiEdgePy) generate_from_xml(VoronoiVertexPy) +generate_from_py_(CommandPy) +generate_from_py_(PathPy) +generate_from_py_(FeaturePathCompoundPy) +generate_from_py_(AreaPy) +generate_from_py_(FeatureAreaPy) +generate_from_py_(VoronoiPy) +generate_from_py_(VoronoiCellPy) +generate_from_py_(VoronoiEdgePy) +generate_from_py_(VoronoiVertexPy) + SET(Python_SRCS CommandPy.xml CommandPyImp.cpp diff --git a/src/Mod/CAM/App/CommandPy.pyi b/src/Mod/CAM/App/CommandPy.pyi new file mode 100644 index 0000000000..5cee727d3c --- /dev/null +++ b/src/Mod/CAM/App/CommandPy.pyi @@ -0,0 +1,48 @@ +from typing import Dict +from Base import PersistencePy # Use the correct parent class +from Base.Metadata import export +from Base.Metadata import constmethod, class_declarations +from Base.Placement import Placement # Import Placement explicitly + +@export( + Father="PersistencePy", + Name="CommandPy", + Twin="Command", + TwinPointer="Command", + Include="Mod/CAM/App/Command.h", + Namespace="Path", + FatherInclude="Base/PersistencePy.h", + FatherNamespace="Base", + Delete=True, + Constructor=True, # Allow constructing this object +) +@class_declarations("mutable Py::Dict parameters_copy_dict;") +class CommandPy(PersistencePy): + """ + Command([name],[parameters]): Represents a basic Gcode command + name (optional) is the name of the command, ex. G1 + parameters (optional) is a dictionary containing string:number + pairs, or a placement, or a vector + """ + + @constmethod + def toGCode(self) -> str: + """toGCode(): returns a GCode representation of the command""" + ... + + def setFromGCode(self, gcode: str) -> None: + """setFromGCode(): sets the path from the contents of the given GCode string""" + ... + + def transform(self, placement: Placement) -> "CommandPy": + """transform(Placement): returns a copy of this command transformed by the given placement""" + ... + # Define properties as attributes, not methods + Name: str + """The name of the command""" + + Parameters: Dict[str, float] + """The parameters of the command""" + + Placement: Placement + """The coordinates of the endpoint of the command""" diff --git a/src/Mod/CAM/App/CommandPy.xml b/src/Mod/CAM/App/CommandPy.xml index e0500ec9b0..0c933c2334 100644 --- a/src/Mod/CAM/App/CommandPy.xml +++ b/src/Mod/CAM/App/CommandPy.xml @@ -51,8 +51,6 @@ pairs, or a placement, or a vector transform(Placement): returns a copy of this command transformed by the given placement - - mutable Py::Dict parameters_copy_dict; - + mutable Py::Dict parameters_copy_dict; diff --git a/src/Mod/CAM/App/FeatureAreaPy.pyi b/src/Mod/CAM/App/FeatureAreaPy.pyi new file mode 100644 index 0000000000..2d18829738 --- /dev/null +++ b/src/Mod/CAM/App/FeatureAreaPy.pyi @@ -0,0 +1,31 @@ +from typing import Any +from App import object +from Base.Metadata import export + +@export( + Father="DocumentObjectPy", + Name="FeatureAreaPy", + Twin="FeatureArea", + TwinPointer="FeatureArea", + Include="Mod/CAM/App/FeatureArea.h", + Namespace="Path", + FatherInclude="App/DocumentObjectPy.h", + FatherNamespace="App", +) +class FeatureAreaPy(object): + """ + This class handles Path Area features + """ + + def getArea(self) -> Any: + """Return a copy of the encapsulated Python Area object.""" + ... + + def setParams(self, **kwargs) -> Any: + """setParams(key=value...): Convenient function to configure this feature. + + Same usage as Path.Area.setParams(). This function stores the parameters in the properties. + """ + ... + WorkPlane: Any + """The current workplane. If no plane is set, it is derived from the added shapes.""" diff --git a/src/Mod/CAM/App/FeaturePathCompoundPy.pyi b/src/Mod/CAM/App/FeaturePathCompoundPy.pyi new file mode 100644 index 0000000000..2bdca04e36 --- /dev/null +++ b/src/Mod/CAM/App/FeaturePathCompoundPy.pyi @@ -0,0 +1,26 @@ +from typing import Any +from App import object +from Base.Metadata import export + +@export( + Father="DocumentObjectPy", + Name="FeaturePathCompoundPy", + Twin="FeaturePathCompound", + TwinPointer="FeatureCompound", + Include="Mod/CAM/App/FeaturePathCompound.h", + Namespace="Path", + FatherInclude="App/DocumentObjectPy.h", + FatherNamespace="App", +) +class FeaturePathCompoundPy(object): + """ + This class handles Path Compound features + """ + + def addObject(self) -> Any: + """Add an object to the group""" + ... + + def removeObject(self) -> Any: + """Remove an object from the group""" + ... diff --git a/src/Mod/CAM/App/PathPy.pyi b/src/Mod/CAM/App/PathPy.pyi new file mode 100644 index 0000000000..fce66b09b6 --- /dev/null +++ b/src/Mod/CAM/App/PathPy.pyi @@ -0,0 +1,70 @@ +from typing import Final, List, Any +from Base import object +from Base.Metadata import export +from Base.Metadata import constmethod + +@export( + Father="PersistencePy", + Name="PathPy", + Twin="Toolpath", + TwinPointer="Toolpath", + Include="Mod/CAM/App/Path.h", + Namespace="Path", + FatherInclude="Base/PersistencePy.h", + FatherNamespace="Base", + ReadOnly=["Length", "Size", "BoundBox"], + Delete=True, # Allow deleting this object + Constructor=True, # Allow constructing this object +) +class PathPy(object): + """ + Path([commands]): Represents a basic Gcode path + commands (optional) is a list of Path commands + """ + + def addCommands(self) -> Any: + """adds a command or a list of commands at the end of the path""" + ... + + def insertCommand(self) -> Any: + """insertCommand(Command,[int]): + adds a command at the given position or at the end of the path""" + ... + + def deleteCommand(self) -> Any: + """deleteCommand([int]): + deletes the command found at the given position or from the end of the path""" + ... + + def setFromGCode(self) -> Any: + """sets the contents of the path from a gcode string""" + ... + + @constmethod + def toGCode(self) -> Any: + """returns a gcode string representing the path""" + ... + + @constmethod + def copy(self) -> Any: + """returns a copy of this path""" + ... + + @constmethod + def getCycleTime(self) -> Any: + """return the cycle time estimation for this path in s""" + ... + Length: Final[float] # ReadOnly + """the total length of this path in mm""" + + Size: Final[int] # ReadOnly + """the number of commands in this path""" + + Commands: List + """the list of commands of this path""" + + Center: Any + """the center position for all rotational parameters""" + + BoundBox: Final[Any] # ReadOnly + """the extent of this path""" diff --git a/src/Mod/CAM/App/VoronoiCellPy.pyi b/src/Mod/CAM/App/VoronoiCellPy.pyi new file mode 100644 index 0000000000..76ef80bddb --- /dev/null +++ b/src/Mod/CAM/App/VoronoiCellPy.pyi @@ -0,0 +1,67 @@ +from typing import Final, Any +from Base import object +from Base.Metadata import export +from Base.Metadata import constmethod + +@export( + Father="BaseClassPy", + Name="VoronoiCellPy", + Twin="VoronoiCell", + PythonName="Path.Voronoi.Cell", + TwinPointer="VoronoiCell", + Include="Mod/CAM/App/VoronoiCell.h", + Namespace="Path", + FatherInclude="Base/BaseClassPy.h", + FatherNamespace="Base", + ReadOnly=[ + "Index", + "SourceIndex", + "SourceCategory", + "SourceCategoryName", + "IncidentEdge", + ], + Constructor=True, + RichCompare=True, + Delete=True, +) +class VoronoiCellPy(object): + """ + Cell of a Voronoi diagram + """ + + @constmethod + def containsPoint(self) -> Any: + """Returns true if the cell contains a point site""" + ... + + @constmethod + def containsSegment(self) -> Any: + """Returns true if the cell contains a segment site""" + ... + + @constmethod + def isDegenerate(self) -> Any: + """Returns true if the cell doesn't have an incident edge""" + ... + + @constmethod + def getSource(self) -> Any: + """Returns the Source for the cell""" + ... + Index: Final[int] # ReadOnly + """Internal id of the element.""" + + Color: int + """Assigned color of the receiver.""" + + SourceIndex: Final[int] # ReadOnly + """Returns the index of the cell's source""" + + SourceCategory: Final[int] # ReadOnly + """Returns the cell's category as an integer""" + + SourceCategoryName: Final[str] # ReadOnly + """Returns the cell's category as a string""" + + IncidentEdge: Final[Any] # ReadOnly + """Incident edge of the cell - if exists""" diff --git a/src/Mod/CAM/App/VoronoiEdgePy.pyi b/src/Mod/CAM/App/VoronoiEdgePy.pyi new file mode 100644 index 0000000000..9fbdc9c6c4 --- /dev/null +++ b/src/Mod/CAM/App/VoronoiEdgePy.pyi @@ -0,0 +1,109 @@ +from typing import Final, List, Any +from Base import object +from Base.Metadata import export +from Base.Metadata import constmethod + +@export( + Father="BaseClassPy", + Name="VoronoiEdgePy", + Twin="VoronoiEdge", + TwinPointer="VoronoiEdge", + PythonName="Path.Voronoi.Edge", + Include="Mod/CAM/App/VoronoiEdge.h", + Namespace="Path", + FatherInclude="Base/BaseClassPy.h", + FatherNamespace="Base", + ReadOnly=[ + "Index", + "Cell", + "Vertices", + "Next", + "Prev", + "RotNext", + "RotPrev", + "Twin", + ], + RichCompare=True, + Constructor=True, + Delete=True, +) +class VoronoiEdgePy(object): + """ + Edge of a Voronoi diagram + """ + + @constmethod + def isFinite(self) -> Any: + """Returns true if both vertices are finite""" + ... + + @constmethod + def isInfinite(self) -> Any: + """Returns true if the end vertex is infinite""" + ... + + @constmethod + def isLinear(self) -> Any: + """Returns true if edge is straight""" + ... + + @constmethod + def isCurved(self) -> Any: + """Returns true if edge is curved""" + ... + + @constmethod + def isPrimary(self) -> Any: + """Returns false if edge goes through endpoint of the segment site""" + ... + + @constmethod + def isSecondary(self) -> Any: + """Returns true if edge goes through endpoint of the segment site""" + ... + + @constmethod + def isBorderline(self) -> Any: + """Returns true if the point is on the segment""" + ... + + @constmethod + def toShape(self) -> Any: + """Returns a shape for the edge""" + ... + + @constmethod + def getDistances(self) -> Any: + """Returns the distance of the vertices to the input source""" + ... + + @constmethod + def getSegmentAngle(self) -> Any: + """Returns the angle (in degree) of the segments if the edge was formed by two segments""" + ... + Index: Final[int] # ReadOnly + """Internal id of the element.""" + + Color: int + """Assigned color of the receiver.""" + + Cell: Final[Any] # ReadOnly + """cell the edge belongs to""" + + Vertices: Final[List] # ReadOnly + """Begin and End voronoi vertex""" + + Next: Final[Any] # ReadOnly + """CCW next edge within voronoi cell""" + + Prev: Final[Any] # ReadOnly + """CCW previous edge within voronoi cell""" + + RotNext: Final[Any] # ReadOnly + """Rotated CCW next edge within voronoi cell""" + + RotPrev: Final[Any] # ReadOnly + """Rotated CCW previous edge within voronoi cell""" + + Twin: Final[Any] # ReadOnly + """Twin edge""" diff --git a/src/Mod/CAM/App/VoronoiPy.pyi b/src/Mod/CAM/App/VoronoiPy.pyi new file mode 100644 index 0000000000..a7eb86cf66 --- /dev/null +++ b/src/Mod/CAM/App/VoronoiPy.pyi @@ -0,0 +1,93 @@ +from typing import Final, List, Any +from Base import object +from Base.Metadata import export +from Base.Metadata import constmethod + +@export( + Father="BaseClassPy", + Name="VoronoiPy", + PythonName="Path.Voronoi.Diagram", + Twin="Voronoi", + TwinPointer="Voronoi", + Include="Mod/CAM/App/Voronoi.h", + Namespace="Path", + FatherInclude="Base/BaseClassPy.h", + FatherNamespace="Base", + Constructor=True, + Delete=True, +) +class VoronoiPy(object): + """ + Voronoi([segments]): Create voronoi for given collection of line segments + """ + + @constmethod + def numCells(self) -> Any: + """Return number of cells""" + ... + + @constmethod + def numEdges(self) -> Any: + """Return number of edges""" + ... + + @constmethod + def numVertices(self) -> Any: + """Return number of vertices""" + ... + + def addPoint(self) -> Any: + """addPoint(vector|vector2d) add given point to input collection""" + ... + + def addSegment(self) -> Any: + """addSegment(vector|vector2d, vector|vector2d) add given segment to input collection""" + ... + + def construct(self) -> Any: + """constructs the voronoi diagram from the input collections""" + ... + + def colorExterior(self) -> Any: + """assign given color to all exterior edges and vertices""" + ... + + def colorTwins(self) -> Any: + """assign given color to all twins of edges (which one is considered a twin is arbitrary)""" + ... + + def colorColinear(self) -> Any: + """assign given color to all edges sourced by two segments almost in line with each other (optional angle in degrees)""" + ... + + def resetColor(self) -> Any: + """assign color 0 to all elements with the given color""" + ... + + @constmethod + def getPoints(self) -> Any: + """Get list of all input points.""" + ... + + @constmethod + def numPoints(self) -> Any: + """Return number of input points""" + ... + + @constmethod + def getSegments(self) -> Any: + """Get list of all input segments.""" + ... + + @constmethod + def numSegments(self) -> Any: + """Return number of input segments""" + ... + Cells: Final[List] # ReadOnly + """List of all cells of the voronoi diagram""" + + Edges: Final[List] # ReadOnly + """List of all edges of the voronoi diagram""" + + Vertices: Final[List] # ReadOnly + """List of all vertices of the voronoi diagram""" diff --git a/src/Mod/CAM/App/VoronoiVertexPy.pyi b/src/Mod/CAM/App/VoronoiVertexPy.pyi new file mode 100644 index 0000000000..34208e9f67 --- /dev/null +++ b/src/Mod/CAM/App/VoronoiVertexPy.pyi @@ -0,0 +1,43 @@ +from typing import Final, Any +from Base import object +from Base.Metadata import export +from Base.Metadata import constmethod + +@export( + Father="BaseClassPy", + Name="VoronoiVertexPy", + PythonName="Path.Voronoi.Vertex", + Twin="VoronoiVertex", + TwinPointer="VoronoiVertex", + Include="Mod/CAM/App/VoronoiVertex.h", + Namespace="Path", + FatherInclude="Base/BaseClassPy.h", + FatherNamespace="Base", + ReadOnly=["Index", "X", "Y", "IncidentEdge"], + Constructor=True, + RichCompare=True, + Delete=True, +) +class VoronoiVertexPy(object): + """ + Vertex of a Voronoi diagram + """ + + @constmethod + def toPoint(self) -> Any: + """Returns a Vector - or None if not possible""" + ... + Index: Final[int] # ReadOnly + """Internal id of the element.""" + + Color: int + """Assigned color of the receiver.""" + + X: Final[float] # ReadOnly + """X position""" + + Y: Final[float] # ReadOnly + """Y position""" + + IncidentEdge: Final[Any] # ReadOnly + """Y position"""