diff --git a/src/Mod/Part/App/GeometrySurfacePy.xml b/src/Mod/Part/App/GeometrySurfacePy.xml
index 6c6937ab75..16fbc7135e 100644
--- a/src/Mod/Part/App/GeometrySurfacePy.xml
+++ b/src/Mod/Part/App/GeometrySurfacePy.xml
@@ -40,6 +40,21 @@ Computes the tangent of parameter (u,v) on this geometry
Computes the normal of parameter (u,v) on this geometry
+
+
+
+Computes the projection of a point on the surface
+
+projectPoint(Point=Vector,[Method=\"NearestPoint\"])
+projectPoint(Vector,\"NearestPoint\") -> Vector
+projectPoint(Vector,\"LowerDistance\") -> float
+projectPoint(Vector,\"LowerDistanceParameters\") -> tuple of floats (u,v)
+projectPoint(Vector,\"Distance\") -> list of floats
+projectPoint(Vector,\"Parameters\") -> list of tuples of floats
+projectPoint(Vector,\"Point\") -> list of points
+
+
+
isUmbillic(u,v) -> bool
diff --git a/src/Mod/Part/App/GeometrySurfacePyImp.cpp b/src/Mod/Part/App/GeometrySurfacePyImp.cpp
index 60dc42b71e..5dd47e04c8 100644
--- a/src/Mod/Part/App/GeometrySurfacePyImp.cpp
+++ b/src/Mod/Part/App/GeometrySurfacePyImp.cpp
@@ -34,6 +34,7 @@
# include
# include
# include
+# include
# include
# include
# include
@@ -356,7 +357,6 @@ PyObject* GeometrySurfacePy::normal(PyObject *args)
}
}
catch (Standard_Failure& e) {
-
PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
return 0;
}
@@ -365,6 +365,86 @@ PyObject* GeometrySurfacePy::normal(PyObject *args)
return 0;
}
+PyObject* GeometrySurfacePy::projectPoint(PyObject *args, PyObject* kwds)
+{
+ PyObject* v;
+ const char* meth = "NearestPoint";
+ static char *kwlist[] = {"Point", "Method", NULL};
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|s", kwlist,
+ &Base::VectorPy::Type, &v, &meth))
+ return nullptr;
+
+ try {
+ Base::Vector3d vec = Py::Vector(v, false).toVector();
+ gp_Pnt pnt(vec.x, vec.y, vec.z);
+ std::string method = meth;
+
+ Handle(Geom_Geometry) geom = getGeometryPtr()->handle();
+ Handle(Geom_Surface) surf = Handle(Geom_Surface)::DownCast(geom);
+
+ GeomAPI_ProjectPointOnSurf proj(pnt, surf);
+ if (method == "NearestPoint") {
+ pnt = proj.NearestPoint();
+ vec.Set(pnt.X(), pnt.Y(), pnt.Z());
+ return new Base::VectorPy(vec);
+ }
+ else if (method == "LowerDistance") {
+ Py::Float dist(proj.LowerDistance());
+ return Py::new_reference_to(dist);
+ }
+ else if (method == "LowerDistanceParameters") {
+ Standard_Real u, v;
+ proj.LowerDistanceParameters(u, v);
+ Py::Tuple par(2);
+ par.setItem(0, Py::Float(u));
+ par.setItem(1, Py::Float(v));
+ return Py::new_reference_to(par);
+ }
+ else if (method == "Distance") {
+ Standard_Integer num = proj.NbPoints();
+ Py::List list;
+ for (Standard_Integer i=1; i <= num; i++) {
+ list.append(Py::Float(proj.Distance(i)));
+ }
+ return Py::new_reference_to(list);
+ }
+ else if (method == "Parameters") {
+ Standard_Integer num = proj.NbPoints();
+ Py::List list;
+ for (Standard_Integer i=1; i <= num; i++) {
+ Standard_Real u, v;
+ proj.Parameters(i, u, v);
+ Py::Tuple par(2);
+ par.setItem(0, Py::Float(u));
+ par.setItem(1, Py::Float(v));
+ list.append(par);
+ }
+ return Py::new_reference_to(list);
+ }
+ else if (method == "Point") {
+ Standard_Integer num = proj.NbPoints();
+ Py::List list;
+ for (Standard_Integer i=1; i <= num; i++) {
+ gp_Pnt pnt = proj.Point(i);
+ Base::Vector3d vec(pnt.X(), pnt.Y(), pnt.Z());
+ list.append(Py::Vector(vec));
+ }
+ return Py::new_reference_to(list);
+ }
+ else {
+ PyErr_SetString(PartExceptionOCCError, "Unsupported method");
+ return nullptr;
+ }
+ }
+ catch (Standard_Failure& e) {
+ PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
+ return nullptr;
+ }
+
+ PyErr_SetString(PartExceptionOCCError, "Geometry is not a surface");
+ return nullptr;
+}
+
PyObject* GeometrySurfacePy::isUmbillic(PyObject *args)
{
try {