diff --git a/src/Mod/Part/App/AppPart.cpp b/src/Mod/Part/App/AppPart.cpp index a8a9a0f0f8..342a67bb65 100644 --- a/src/Mod/Part/App/AppPart.cpp +++ b/src/Mod/Part/App/AppPart.cpp @@ -53,6 +53,7 @@ #include "Mod/Part/App/BSplineSurfacePy.h" #include #include +#include #include #include "Mod/Part/App/CirclePy.h" #include "Mod/Part/App/ConePy.h" @@ -344,6 +345,7 @@ PyMOD_INIT_FUNC(Part) PyObject* chFi2d(module.getAttr("ChFi2d").ptr()); Base::Interpreter().addType(&Part::ChFi2d_AnaFilletAlgoPy::Type, chFi2d, "AnaFilletAlgo"); Base::Interpreter().addType(&Part::ChFi2d_FilletAlgoPy::Type, chFi2d, "FilletAlgo"); + Base::Interpreter().addType(&Part::ChFi2d_ChamferAPIPy::Type, chFi2d, "ChamferAPI"); Base::Interpreter().addType(&Part::ChFi2d_FilletAPIPy::Type, chFi2d, "FilletAPI"); Part::TopoShape ::init(); diff --git a/src/Mod/Part/App/CMakeLists.txt b/src/Mod/Part/App/CMakeLists.txt index 76ed9c7633..9eef362d42 100644 --- a/src/Mod/Part/App/CMakeLists.txt +++ b/src/Mod/Part/App/CMakeLists.txt @@ -105,6 +105,7 @@ generate_from_xml(BRepFeat/MakePrismPy) generate_from_xml(ChFi2d/ChFi2d_AnaFilletAlgoPy) generate_from_xml(ChFi2d/ChFi2d_FilletAlgoPy) +generate_from_xml(ChFi2d/ChFi2d_ChamferAPIPy) generate_from_xml(ChFi2d/ChFi2d_FilletAPIPy) generate_from_xml(Geom2d/ArcOfCircle2dPy) @@ -343,6 +344,8 @@ SET(ChFi2dPy_SRCS ChFi2d/ChFi2d_AnaFilletAlgoPyImp.cpp ChFi2d/ChFi2d_FilletAlgoPy.xml ChFi2d/ChFi2d_FilletAlgoPyImp.cpp + ChFi2d/ChFi2d_ChamferAPIPy.xml + ChFi2d/ChFi2d_ChamferAPIPyImp.cpp ChFi2d/ChFi2d_FilletAPIPy.xml ChFi2d/ChFi2d_FilletAPIPyImp.cpp ) diff --git a/src/Mod/Part/App/ChFi2d/ChFi2d_ChamferAPIPy.xml b/src/Mod/Part/App/ChFi2d/ChFi2d_ChamferAPIPy.xml new file mode 100644 index 0000000000..80e069a193 --- /dev/null +++ b/src/Mod/Part/App/ChFi2d/ChFi2d_ChamferAPIPy.xml @@ -0,0 +1,39 @@ + + + + + + Algorithm that creates a chamfer between two linear edges + + + + Initializes a chamfer algorithm: accepts a wire consisting of two edges in a plane + + + + + perform(radius) -> bool + +Constructs a chamfer edge + + + + + result(point, solution=-1) + +Returns result (chamfer edge, modified edge1, modified edge2) + + + + diff --git a/src/Mod/Part/App/ChFi2d/ChFi2d_ChamferAPIPyImp.cpp b/src/Mod/Part/App/ChFi2d/ChFi2d_ChamferAPIPyImp.cpp new file mode 100644 index 0000000000..ad790e600c --- /dev/null +++ b/src/Mod/Part/App/ChFi2d/ChFi2d_ChamferAPIPyImp.cpp @@ -0,0 +1,156 @@ +/*************************************************************************** + * Copyright (c) 2022 Werner Mayer * + * * + * 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 +# include +# include +# include +# include +#endif + +#include +#include +#include +#include +#include +#include "Tools.h" + +using namespace Part; + + +PyObject *ChFi2d_ChamferAPIPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper +{ + // create a new instance of ChFi2d_ChamferAPIPy and the Twin object + return new ChFi2d_ChamferAPIPy(new ChFi2d_ChamferAPI); +} + +// constructor method +int ChFi2d_ChamferAPIPy::PyInit(PyObject* args, PyObject* /*kwd*/) +{ + // Note: Although the C++ class has a default constructor it would cause a crash + // if the algorithm is not initialized with a wire/edges. + // Thus, in the Python API it is disabled. + PyObject* wire; + if (PyArg_ParseTuple(args, "O!", &TopoShapeWirePy::Type, &wire)) { + TopoDS_Shape shape = static_cast(wire)->getTopoShapePtr()->getShape(); + getChFi2d_ChamferAPIPtr()->Init(TopoDS::Wire(shape)); + return 0; + } + + PyErr_Clear(); + PyObject* edge1; + PyObject* edge2; + if (PyArg_ParseTuple(args, "O!O!", &TopoShapeEdgePy::Type, &edge1, + &TopoShapeEdgePy::Type, &edge2)) { + TopoDS_Shape shape1 = static_cast(edge1)->getTopoShapePtr()->getShape(); + TopoDS_Shape shape2 = static_cast(edge2)->getTopoShapePtr()->getShape(); + getChFi2d_ChamferAPIPtr()->Init(TopoDS::Edge(shape1), TopoDS::Edge(shape2)); + return 0; + } + + PyErr_SetString(PyExc_TypeError, "Wrong arguments:\n" + "-- ChamferAPI()\n" + "-- ChamferAPI(wire)" + "-- ChamferAPI(edge, edge)\n"); + return -1; +} + +// returns a string which represents the object e.g. when printed in python +std::string ChFi2d_ChamferAPIPy::representation() const +{ + return std::string(""); +} + +PyObject* ChFi2d_ChamferAPIPy::init(PyObject *args) +{ + PyObject* wire; + if (PyArg_ParseTuple(args, "O!", &TopoShapeWirePy::Type, &wire)) { + TopoDS_Shape shape = static_cast(wire)->getTopoShapePtr()->getShape(); + getChFi2d_ChamferAPIPtr()->Init(TopoDS::Wire(shape)); + Py_Return; + } + + PyErr_Clear(); + PyObject* edge1; + PyObject* edge2; + if (PyArg_ParseTuple(args, "O!O!", &TopoShapeEdgePy::Type, &edge1, + &TopoShapeEdgePy::Type, &edge2)) { + TopoDS_Shape shape1 = static_cast(edge1)->getTopoShapePtr()->getShape(); + TopoDS_Shape shape2 = static_cast(edge2)->getTopoShapePtr()->getShape(); + getChFi2d_ChamferAPIPtr()->Init(TopoDS::Edge(shape1), TopoDS::Edge(shape2)); + Py_Return; + } + + PyErr_SetString(PyExc_TypeError, "Wrong arguments:\n" + "-- init(wire)" + "-- init(edge, edge)\n"); + return nullptr; +} + +PyObject* ChFi2d_ChamferAPIPy::perform(PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) + return nullptr; + + try { + bool ok = getChFi2d_ChamferAPIPtr()->Perform(); + return Py::new_reference_to(Py::Boolean(ok)); + } + catch (Standard_Failure& e) { + PyErr_SetString(Base::PyExc_FC_CADKernelError, e.GetMessageString()); + return nullptr; + } +} + +PyObject* ChFi2d_ChamferAPIPy::result(PyObject *args) +{ + double length1, length2; + if (!PyArg_ParseTuple(args, "dd", &length1, &length2)) + return nullptr; + + try { + TopoDS_Edge theEdge1, theEdge2; + TopoDS_Shape res_edge = getChFi2d_ChamferAPIPtr()->Result(theEdge1, theEdge2, length1, length2); + + Py::TupleN tuple(Py::asObject(TopoShape(res_edge).getPyObject()), + Py::asObject(TopoShape(theEdge1).getPyObject()), + Py::asObject(TopoShape(theEdge2).getPyObject())); + return Py::new_reference_to(tuple); + } + catch (Standard_Failure& e) { + PyErr_SetString(Base::PyExc_FC_CADKernelError, e.GetMessageString()); + return nullptr; + } +} + +PyObject *ChFi2d_ChamferAPIPy::getCustomAttributes(const char* /*attr*/) const +{ + return nullptr; +} + +int ChFi2d_ChamferAPIPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) +{ + return 0; +} diff --git a/src/Mod/Part/TestPartApp.py b/src/Mod/Part/TestPartApp.py index be5671b03e..4b69cdcda1 100644 --- a/src/Mod/Part/TestPartApp.py +++ b/src/Mod/Part/TestPartApp.py @@ -231,7 +231,7 @@ class PartTestCone(unittest.TestCase): self.assertAlmostEqual(v2.getAngle(w2), 0) self.assertAlmostEqual(v3.getAngle(w3), 0) -class PartTestFilletAlgo(unittest.TestCase): +class PartTestChFi2dAlgos(unittest.TestCase): def testChFi2d_FilletAlgo(self): v = FreeCAD.Vector edge1 = Part.makeLine(v(0,0,0), v(0,10,0)) @@ -309,3 +309,35 @@ class PartTestFilletAlgo(unittest.TestCase): curve = result[0].Curve self.assertEqual(type(curve), Part.Circle) self.assertEqual(curve.Radius, 1.0) + + def testChFi2d_ChamferAPI(self): + v = FreeCAD.Vector + edge1 = Part.makeLine(v(0,0,0), v(0,10,0)) + edge2 = Part.makeLine(v(0,10,0), v(10,10,0)) + wire = Part.Wire([edge1, edge2]) + + with self.assertRaises(TypeError): + alg = Part.ChFi2d.ChamferAPI(edge1) + + alg = Part.ChFi2d.ChamferAPI(wire) + with self.assertRaises(TypeError): + alg.init() + + print (alg) + + with self.assertRaises(TypeError): + alg.perform(1) + + alg = Part.ChFi2d.ChamferAPI(wire) + alg.init(edge1, edge2) + alg.init(wire) + + alg = Part.ChFi2d.ChamferAPI(edge1, edge2) + alg.perform() + + with self.assertRaises(TypeError): + alg.result(1) + + result = alg.result(1.0, 1.0) + curve = result[0].Curve + self.assertEqual(type(curve), Part.Line)