diff --git a/src/Mod/Part/App/GeometryCurvePy.xml b/src/Mod/Part/App/GeometryCurvePy.xml
index 6ef4e76c6..d58fc31c5 100644
--- a/src/Mod/Part/App/GeometryCurvePy.xml
+++ b/src/Mod/Part/App/GeometryCurvePy.xml
@@ -95,6 +95,21 @@ parameterAtDistance([abscissa, startingParameter]) -> Float the
of the nearest orthogonal projection of the point.
+
+
+ Vector = normal(pos) - Get the normal vector at the given parameter [First|Last] if defined
+
+
+
+
+ Float = curvature(pos) - Get the curvature at the given parameter [First|Last] if defined
+
+
+
+
+ Vector = centerOfCurvature(float pos) - Get the center of curvature at the given parameter [First|Last] if defined
+
+
diff --git a/src/Mod/Part/App/GeometryCurvePyImp.cpp b/src/Mod/Part/App/GeometryCurvePyImp.cpp
index 438590de3..e81ae9e4e 100644
--- a/src/Mod/Part/App/GeometryCurvePyImp.cpp
+++ b/src/Mod/Part/App/GeometryCurvePyImp.cpp
@@ -383,7 +383,7 @@ PyObject* GeometryCurvePy::tangent(PyObject *args)
return 0;
gp_Dir dir;
Py::Tuple tuple(1);
- GeomLProp_CLProps prop(c,u,1,Precision::Confusion());
+ GeomLProp_CLProps prop(c,u,2,Precision::Confusion());
if (prop.IsTangentDefined()) {
prop.Tangent(dir);
tuple.setItem(0, Py::Vector(Base::Vector3d(dir.X(),dir.Y(),dir.Z())));
@@ -402,6 +402,80 @@ PyObject* GeometryCurvePy::tangent(PyObject *args)
return 0;
}
+PyObject* GeometryCurvePy::normal(PyObject *args)
+{
+ Handle_Geom_Geometry g = getGeometryPtr()->handle();
+ Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(g);
+ try {
+ if (!c.IsNull()) {
+ double u;
+ if (!PyArg_ParseTuple(args, "d", &u))
+ return 0;
+ gp_Dir dir;
+ GeomLProp_CLProps prop(c,u,2,Precision::Confusion());
+ prop.Normal(dir);
+ return new Base::VectorPy(new Base::Vector3d(dir.X(),dir.Y(),dir.Z()));
+ }
+ }
+ catch (Standard_Failure) {
+ Handle_Standard_Failure e = Standard_Failure::Caught();
+ PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
+ return 0;
+ }
+
+ PyErr_SetString(PartExceptionOCCError, "Geometry is not a curve");
+ return 0;
+}
+
+PyObject* GeometryCurvePy::curvature(PyObject *args)
+{
+ Handle_Geom_Geometry g = getGeometryPtr()->handle();
+ Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(g);
+ try {
+ if (!c.IsNull()) {
+ double u;
+ if (!PyArg_ParseTuple(args, "d", &u))
+ return 0;
+ GeomLProp_CLProps prop(c,u,2,Precision::Confusion());
+ double C = prop.Curvature();
+ return Py::new_reference_to(Py::Float(C));
+ }
+ }
+ catch (Standard_Failure) {
+ Handle_Standard_Failure e = Standard_Failure::Caught();
+ PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
+ return 0;
+ }
+
+ PyErr_SetString(PartExceptionOCCError, "Geometry is not a curve");
+ return 0;
+}
+
+PyObject* GeometryCurvePy::centerOfCurvature(PyObject *args)
+{
+ Handle_Geom_Geometry g = getGeometryPtr()->handle();
+ Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(g);
+ try {
+ if (!c.IsNull()) {
+ double u;
+ if (!PyArg_ParseTuple(args, "d", &u))
+ return 0;
+ GeomLProp_CLProps prop(c,u,2,Precision::Confusion());
+ gp_Pnt V ;
+ prop.CentreOfCurvature(V);
+ return new Base::VectorPy(new Base::Vector3d(V.X(),V.Y(),V.Z()));
+ }
+ }
+ catch (Standard_Failure) {
+ Handle_Standard_Failure e = Standard_Failure::Caught();
+ PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
+ return 0;
+ }
+
+ PyErr_SetString(PartExceptionOCCError, "Geometry is not a curve");
+ return 0;
+}
+
PyObject* GeometryCurvePy::parameter(PyObject *args)
{
Handle_Geom_Geometry g = getGeometryPtr()->handle();