diff --git a/src/Mod/Part/App/GeometryCurvePy.xml b/src/Mod/Part/App/GeometryCurvePy.xml index a70c115fb..039578f8a 100644 --- a/src/Mod/Part/App/GeometryCurvePy.xml +++ b/src/Mod/Part/App/GeometryCurvePy.xml @@ -89,6 +89,27 @@ length([uMin,uMax,Tol]) -> Float of the nearest orthogonal projection of the point. + + + + Returns all intersection points and curve segments between the curve and the curve/surface. + + + + + + + Returns all intersection points and curve segments between the curve and the surface. + + + + + + + Returns all intersection points between this curve and the given curve. + + + diff --git a/src/Mod/Part/App/GeometryCurvePyImp.cpp b/src/Mod/Part/App/GeometryCurvePyImp.cpp index ca96b9b77..77378944d 100644 --- a/src/Mod/Part/App/GeometryCurvePyImp.cpp +++ b/src/Mod/Part/App/GeometryCurvePyImp.cpp @@ -51,6 +51,8 @@ # include # include # include +# include +# include #endif #include @@ -62,6 +64,7 @@ #include "RectangularTrimmedSurfacePy.h" #include "BSplineSurfacePy.h" #include "PlanePy.h" +#include "PointPy.h" #include "BSplineCurvePy.h" #include "OCCError.h" @@ -69,6 +72,9 @@ #include "TopoShapePy.h" #include "TopoShapeEdgePy.h" +// TODO: This should be somewhere globally, but where? Currently located in GeometrySurfacePyImp.cpp +extern const Py::Object makeGeometryCurvePy(const Handle_Geom_Curve& c); + using namespace Part; // returns a string which represents the object e.g. when printed in python @@ -606,3 +612,117 @@ int GeometryCurvePy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/ { return 0; } + +// Specialized intersection functions + +PyObject* GeometryCurvePy::intersectCS(PyObject *args) +{ + Handle_Geom_Curve curve = Handle_Geom_Curve::DownCast(getGeometryPtr()->handle()); + try { + if (!curve.IsNull()) { + PyObject *p; + double prec = Precision::Confusion(); + if (!PyArg_ParseTuple(args, "O!|d", &(Part::GeometrySurfacePy::Type), &p, &prec)) + return 0; + Handle_Geom_Surface surf = Handle_Geom_Surface::DownCast(static_cast(p)->getGeometryPtr()->handle()); + GeomAPI_IntCS intersector(curve, surf); + if (!intersector.IsDone()) { + PyErr_SetString(PyExc_Exception, "Intersection of curve and surface failed"); + return 0; + } + + Py::List points; + for (int i = 1; i <= intersector.NbPoints(); i++) { + gp_Pnt p = intersector.Point(i); + points.append(Py::Object(new PointPy(new GeomPoint(Base::Vector3d(p.X(), p.Y(), p.Z()))))); + } + Py::List segments; + for (int i = 1; i <= intersector.NbSegments(); i++) { + Handle_Geom_Curve seg = intersector.Segment(i); + segments.append(makeGeometryCurvePy(seg)); + } + + Py::Tuple tuple(2); + tuple.setItem(0, points); + tuple.setItem(1, segments); + return Py::new_reference_to(tuple); + } + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(PyExc_Exception, e->GetMessageString()); + return 0; + } + + PyErr_SetString(PyExc_Exception, "Geometry is not a curve"); + return 0; +} + +PyObject* GeometryCurvePy::intersectCC(PyObject *args) +{ + Handle_Geom_Curve curve1 = Handle_Geom_Curve::DownCast(getGeometryPtr()->handle()); + try { + if (!curve1.IsNull()) { + PyObject *p; + double prec = Precision::Confusion(); + if (!PyArg_ParseTuple(args, "O!|d", &(Part::GeometrySurfacePy::Type), &p, &prec)) + return 0; + Handle_Geom_Curve curve2 = Handle_Geom_Curve::DownCast(static_cast(p)->getGeometryPtr()->handle()); + GeomAPI_ExtremaCurveCurve intersector(curve1, curve2); + if (intersector.LowerDistance() > Precision::Confusion()) { + // No intersection + return Py::new_reference_to(Py::List()); + } + + Py::List points; + for (int i = 1; i <= intersector.NbExtrema(); i++) { + if (intersector.Distance(i) > Precision::Confusion()) + continue; + gp_Pnt p1, p2; + intersector.Points(i, p1, p2); + points.append(Py::Object(new PointPy(new GeomPoint(Base::Vector3d(p1.X(), p1.Y(), p1.Z()))))); + } + + return Py::new_reference_to(points); + } + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(PyExc_Exception, e->GetMessageString()); + return 0; + } + + PyErr_SetString(PyExc_Exception, "Geometry is not a curve"); + return 0; +} + +// General intersection function + +PyObject* GeometryCurvePy::intersect(PyObject *args) +{ + Handle_Geom_Curve curve = Handle_Geom_Curve::DownCast(getGeometryPtr()->handle()); + try { + if (!curve.IsNull()) { + PyObject *p; + double prec = Precision::Confusion(); + try { + if (PyArg_ParseTuple(args, "O!|d", &(Part::GeometryCurvePy::Type), &p, &prec)) + return intersectCC(args); + } catch(...) {} + PyErr_Clear(); + + if (PyArg_ParseTuple(args, "O!|d", &(Part::GeometrySurfacePy::Type), &p, &prec)) + return intersectCS(args); + else + return 0; + } + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(PyExc_Exception, e->GetMessageString()); + return 0; + } + + PyErr_SetString(PyExc_Exception, "Geometry is not a curve"); + return 0; +} diff --git a/src/Mod/Part/App/GeometrySurfacePy.xml b/src/Mod/Part/App/GeometrySurfacePy.xml index 3090e5cb0..ddc964d79 100644 --- a/src/Mod/Part/App/GeometrySurfacePy.xml +++ b/src/Mod/Part/App/GeometrySurfacePy.xml @@ -105,5 +105,22 @@ The required arguments are: + + + + Returns all intersection points/curves between the surface and the curve/surface. + + + + + + + Returns all intersection curves of this surface and the given surface. +The required arguments are: +* Second surface +* precision code (optional, default=0) + + + diff --git a/src/Mod/Part/App/GeometrySurfacePyImp.cpp b/src/Mod/Part/App/GeometrySurfacePyImp.cpp index 8e10a218e..792d6f158 100644 --- a/src/Mod/Part/App/GeometrySurfacePyImp.cpp +++ b/src/Mod/Part/App/GeometrySurfacePyImp.cpp @@ -34,6 +34,7 @@ # include # include # include +# include #endif #include @@ -43,12 +44,62 @@ #include "Geometry.h" #include "GeometrySurfacePy.h" #include "GeometrySurfacePy.cpp" +#include "GeometryCurvePy.h" #include "BSplineSurfacePy.h" #include "TopoShape.h" #include "TopoShapePy.h" #include "TopoShapeFacePy.h" +// TODO: This should be somewhere globally, but where? +// ------------------------------ +# include +# include +# include +# include +# include +# include +# include + +const Py::Object makeGeometryCurvePy(const Handle_Geom_Curve& c) +{ + if (c->IsKind(STANDARD_TYPE(Geom_Circle))) { + Handle_Geom_Circle circ = Handle_Geom_Circle::DownCast(c); + return Py::Object(new GeometryCurvePy(new GeomCircle(circ))); + } else if (c->IsKind(STANDARD_TYPE(Geom_Ellipse))) { + Handle_Geom_Ellipse ell = Handle_Geom_Ellipse::DownCast(c); + return Py::Object(new GeometryCurvePy(new GeomEllipse(ell))); + } else if (c->IsKind(STANDARD_TYPE(Geom_Hyperbola))) { + Handle_Geom_Hyperbola hyp = Handle_Geom_Hyperbola::DownCast(c); + return Py::Object(new GeometryCurvePy(new GeomHyperbola(hyp))); + } else if (c->IsKind(STANDARD_TYPE(Geom_Line))) { + Handle_Geom_Line lin = Handle_Geom_Line::DownCast(c); + return Py::Object(new GeometryCurvePy(new GeomLine(lin))); + } else if (c->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) { + Handle_Geom_OffsetCurve oc = Handle_Geom_OffsetCurve::DownCast(c); + return Py::Object(new GeometryCurvePy(new GeomOffsetCurve(oc))); + } else if (c->IsKind(STANDARD_TYPE(Geom_Parabola))) { + Handle_Geom_Parabola par = Handle_Geom_Parabola::DownCast(c); + return Py::Object(new GeometryCurvePy(new GeomParabola(par))); + } else if (c->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { + Handle_Geom_TrimmedCurve trc = Handle_Geom_TrimmedCurve::DownCast(c); + return Py::Object(new GeometryCurvePy(new GeomTrimmedCurve(trc))); + } else/* if (c->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) { + Handle_Geom_BoundedCurve bc = Handle_Geom_BoundedCurve::DownCast(c); + return Py::Object(new GeometryCurvePy(new GeomBoundedCurve(bc))); + } else */if (c->IsKind(STANDARD_TYPE(Geom_BezierCurve))) { + Handle_Geom_BezierCurve bezier = Handle_Geom_BezierCurve::DownCast(c); + return Py::Object(new GeometryCurvePy(new GeomBezierCurve(bezier))); + } else if (c->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) { + Handle_Geom_BSplineCurve bspline = Handle_Geom_BSplineCurve::DownCast(c); + return Py::Object(new GeometryCurvePy(new GeomBSplineCurve(bspline))); + } + + PyErr_SetString(PyExc_Exception, "Unknown curve type"); + return Py::Object(); +} +// --------------------------------------- + using namespace Part; // returns a string which represents the object e.g. when printed in python @@ -388,3 +439,77 @@ int GeometrySurfacePy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj { return 0; } + +// Specialized intersection functions + +PyObject* GeometrySurfacePy::intersectSS(PyObject *args) +{ + Handle_Geom_Surface surf1 = Handle_Geom_Surface::DownCast(getGeometryPtr()->handle()); + try { + if (!surf1.IsNull()) { + PyObject *p; + double prec = Precision::Confusion(); + if (!PyArg_ParseTuple(args, "O!|d", &(Part::GeometrySurfacePy::Type), &p, &prec)) + return 0; + Handle_Geom_Surface surf2 = Handle_Geom_Surface::DownCast(static_cast(p)->getGeometryPtr()->handle()); + GeomAPI_IntSS intersector(surf1, surf2, prec); + if (!intersector.IsDone()) { + PyErr_SetString(PyExc_Exception, "Intersection of surfaces failed"); + return 0; + } + + Py::List result; + for (int i = 1; i <= intersector.NbLines(); i++) { + Handle_Geom_Curve line = intersector.Line(i); + result.append(makeGeometryCurvePy(line)); + } + + return Py::new_reference_to(result); + } + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(PyExc_Exception, e->GetMessageString()); + return 0; + } + + PyErr_SetString(PyExc_Exception, "intersectSS(): Geometry is not a surface"); + return 0; +} + +// General intersection function + +PyObject* GeometrySurfacePy::intersect(PyObject *args) +{ + Handle_Geom_Surface surf = Handle_Geom_Surface::DownCast(getGeometryPtr()->handle()); + try { + if (!surf.IsNull()) { + PyObject *p; + double prec = Precision::Confusion(); + + try { + if (PyArg_ParseTuple(args, "O!|d", &(Part::GeometrySurfacePy::Type), &p, &prec)) + return intersectSS(args); + } catch(...) {}; + PyErr_Clear(); + + if (PyArg_ParseTuple(args, "O!|d", &(Part::GeometryCurvePy::Type), &p, &prec)) { + GeometryCurvePy* curve = static_cast(p); + PyObject* t = PyTuple_New(2); + PyTuple_SetItem(t, 0, this); + PyTuple_SetItem(t, 1, PyFloat_FromDouble(prec)); + return curve->intersectCS(t); + } else { + return 0; + } + } + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(PyExc_Exception, e->GetMessageString()); + return 0; + } + + PyErr_SetString(PyExc_Exception, "intersect(): Geometry is not a surface"); + return 0; +}