From 5a2c48b593a46d47af9a69d30413e40efc1e4a84 Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Sun, 28 May 2023 11:44:02 +0200 Subject: [PATCH] Sketcher: new toPythonCommand sketcher Python method ==================================================== This commit leverages PythonConverter to produce the Python commands necessary to replicate a sketch. The output is a tuple comprising line by line the python commands. Limitations: Only internal geometry is replicated. No external links. Usage: ActiveSketch.toPythonCommands() Example output: ('geoList = []', 'geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(0.000000, 0.000000, 0.000000), App.Vector(0.000000, 0.000000, 1.000000), 65.000000), 3.926991, 8.639380))', 'geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(-70.304056, -14.307964, 0.000000), App.Vector(0.000000, 0.000000, 1.000000), 65.000000), 1.186945, 1.992409))', 'ActiveSketch.addGeometry(geoList,False)', 'del geoList', 'constrGeoList = []', 'constrGeoList.append(Part.LineSegment(App.Vector(-45.961941,45.961941,0.000000),App.Vector(0.000000,0.000000,0.000000)))', 'constrGeoList.append(Part.LineSegment(App.Vector(0.000000,0.000000,0.000000),App.Vector(-45.961941,-45.961941,0.000000)))', 'ActiveSketch.addGeometry(constrGeoList,True)', 'del constrGeoList', 'geoList = []', 'geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(-70.304056, 14.307964, 0.000000), App.Vector(0.000000, 0.000000, 1.000000), 65.000000), 4.290776, 5.096240))', 'geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(-50.000000, 0.000000, 0.000000), App.Vector(0.000000, 0.000000, 1.000000), 65.000000), 2.376910, 3.906275))', 'ActiveSketch.addGeometry(geoList,False)', 'del geoList', 'constraintList = []', "constraintList.append(Sketcher.Constraint('Coincident', 0, 3, -1, 1))", "constraintList.append(Sketcher.Constraint('Coincident', 1, 1, 0, 2))", "constraintList.append(Sketcher.Constraint('Coincident', 2, 1, 0, 2))", "constraintList.append(Sketcher.Constraint('Coincident', 2, 2, 0, 3))", "constraintList.append(Sketcher.Constraint('Coincident', 3, 1, 0, 3))", "constraintList.append(Sketcher.Constraint('Coincident', 3, 2, 0, 1))", "constraintList.append(Sketcher.Constraint('Symmetric', 0, 1, 0, 2, -1))", "constraintList.append(Sketcher.Constraint('Coincident', 4, 2, 0, 1))", "constraintList.append(Sketcher.Constraint('Symmetric', 1, 3, 4, 3, -1))", "constraintList.append(Sketcher.Constraint('Symmetric', 4, 1, 1, 2, -1))", "constraintList.append(Sketcher.Constraint('Coincident', 5, 1, 1, 2))", "constraintList.append(Sketcher.Constraint('Coincident', 5, 2, 4, 1))", "constraintList.append(Sketcher.Constraint('DistanceY', 4, 1, 1, 2, 90.000000))", "constraintList.append(Sketcher.Constraint('Radius', 5, 65.000000))", "constraintList.append(Sketcher.Constraint('DistanceX', 5, 3, 0, 3, 50.000000))", "constraintList.append(Sketcher.Constraint('Equal', 5, 4))", "constraintList.append(Sketcher.Constraint('Equal', 4, 0))", "constraintList.append(Sketcher.Constraint('Perpendicular', 2, 3))", 'ActiveSketch.addConstraint(constraintList)', 'del constraintList', '') A list directly copiable into the console of a new sketch can be obtained, for example: for i in ActiveSketch.toPythonCommands(): print(i) Example output: geoList = [] geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(0.000000, 0.000000, 0.000000), App.Vector(0.000000, 0.000000, 1.000000), 65.000000), 3.926991, 8.639380)) geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(-70.304056, -14.307964, 0.000000), App.Vector(0.000000, 0.000000, 1.000000), 65.000000), 1.186945, 1.992409)) ActiveSketch.addGeometry(geoList,False) del geoList constrGeoList = [] constrGeoList.append(Part.LineSegment(App.Vector(-45.961941,45.961941,0.000000),App.Vector(0.000000,0.000000,0.000000))) constrGeoList.append(Part.LineSegment(App.Vector(0.000000,0.000000,0.000000),App.Vector(-45.961941,-45.961941,0.000000))) ActiveSketch.addGeometry(constrGeoList,True) del constrGeoList geoList = [] geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(-70.304056, 14.307964, 0.000000), App.Vector(0.000000, 0.000000, 1.000000), 65.000000), 4.290776, 5.096240)) geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(-50.000000, 0.000000, 0.000000), App.Vector(0.000000, 0.000000, 1.000000), 65.000000), 2.376910, 3.906275)) ActiveSketch.addGeometry(geoList,False) del geoList constraintList = [] constraintList.append(Sketcher.Constraint('Coincident', 0, 3, -1, 1)) constraintList.append(Sketcher.Constraint('Coincident', 1, 1, 0, 2)) constraintList.append(Sketcher.Constraint('Coincident', 2, 1, 0, 2)) constraintList.append(Sketcher.Constraint('Coincident', 2, 2, 0, 3)) constraintList.append(Sketcher.Constraint('Coincident', 3, 1, 0, 3)) constraintList.append(Sketcher.Constraint('Coincident', 3, 2, 0, 1)) constraintList.append(Sketcher.Constraint('Symmetric', 0, 1, 0, 2, -1)) constraintList.append(Sketcher.Constraint('Coincident', 4, 2, 0, 1)) constraintList.append(Sketcher.Constraint('Symmetric', 1, 3, 4, 3, -1)) constraintList.append(Sketcher.Constraint('Symmetric', 4, 1, 1, 2, -1)) constraintList.append(Sketcher.Constraint('Coincident', 5, 1, 1, 2)) constraintList.append(Sketcher.Constraint('Coincident', 5, 2, 4, 1)) constraintList.append(Sketcher.Constraint('DistanceY', 4, 1, 1, 2, 90.000000)) constraintList.append(Sketcher.Constraint('Radius', 5, 65.000000)) constraintList.append(Sketcher.Constraint('DistanceX', 5, 3, 0, 3, 50.000000)) constraintList.append(Sketcher.Constraint('Equal', 5, 4)) constraintList.append(Sketcher.Constraint('Equal', 4, 0)) constraintList.append(Sketcher.Constraint('Perpendicular', 2, 3)) ActiveSketch.addConstraint(constraintList) del constraintList --- src/Mod/Sketcher/App/SketchObjectPy.xml | 8 ++++- src/Mod/Sketcher/App/SketchObjectPyImp.cpp | 36 ++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/Mod/Sketcher/App/SketchObjectPy.xml b/src/Mod/Sketcher/App/SketchObjectPy.xml index 9314b262ff..5554dc1c0f 100644 --- a/src/Mod/Sketcher/App/SketchObjectPy.xml +++ b/src/Mod/Sketcher/App/SketchObjectPy.xml @@ -419,7 +419,13 @@ If there is no such constraint an exception is raised. - + + + + Prints the commands that should be executed to recreate the Geometry and Constraints of the present sketch (excluding any External Geometry). + + + diff --git a/src/Mod/Sketcher/App/SketchObjectPyImp.cpp b/src/Mod/Sketcher/App/SketchObjectPyImp.cpp index c9628e54e1..4151b5a422 100644 --- a/src/Mod/Sketcher/App/SketchObjectPyImp.cpp +++ b/src/Mod/Sketcher/App/SketchObjectPyImp.cpp @@ -36,6 +36,8 @@ #include #include +#include "PythonConverter.h" + // inclusion of the generated files (generated out of SketchObjectSFPy.xml) #include "SketchObjectPy.h" @@ -1766,6 +1768,40 @@ PyObject* SketchObjectPy::autoRemoveRedundants(PyObject* args) Py_Return; } +PyObject* SketchObjectPy::toPythonCommands(PyObject* args) +{ + if (!PyArg_ParseTuple(args, "")) + return nullptr; + + auto sketch = this->getSketchObjectPtr(); + + std::string geometry = PythonConverter::convert("ActiveSketch", sketch->Geometry.getValues()); + std::string constraints = + PythonConverter::convert("ActiveSketch", sketch->Constraints.getValues()); + + auto geometrymulti = PythonConverter::multiLine(std::move(geometry)); + auto constraintmulti = PythonConverter::multiLine(std::move(constraints)); + + size_t numelements = geometrymulti.size() + constraintmulti.size(); + + Py::Tuple tuple(numelements); + + std::size_t i = 0; + + for (const auto& str : geometrymulti) { + tuple.setItem(i, Py::String(str)); + i++; + } + + for (const auto& str : constraintmulti) { + tuple.setItem(i, Py::String(str)); + i++; + } + + return Py::new_reference_to(tuple); +} + + Py::List SketchObjectPy::getMissingPointOnPointConstraints() const { std::vector constraints =