From 3fee9bad3e96b2dc6c5f5b238abea9885ebd1400 Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 14 Aug 2017 12:24:42 +0200 Subject: [PATCH] add methods to get normal and curvature information from surfaces --- src/Mod/Part/App/Geometry.cpp | 66 +++++++++++- src/Mod/Part/App/Geometry.h | 15 +++ src/Mod/Part/App/GeometrySurfacePy.xml | 38 ++++++- src/Mod/Part/App/GeometrySurfacePyImp.cpp | 123 +++++++++++++++++++++- 4 files changed, 236 insertions(+), 6 deletions(-) diff --git a/src/Mod/Part/App/Geometry.cpp b/src/Mod/Part/App/Geometry.cpp index c6d6d54dfd..561d3a78da 100644 --- a/src/Mod/Part/App/Geometry.cpp +++ b/src/Mod/Part/App/Geometry.cpp @@ -3657,7 +3657,7 @@ TopoDS_Shape GeomSurface::toShape() const bool GeomSurface::tangentU(double u, double v, gp_Dir& dirU) const { Handle(Geom_Surface) s = Handle(Geom_Surface)::DownCast(handle()); - GeomLProp_SLProps prop(s,u,v,1,Precision::Confusion()); + GeomLProp_SLProps prop(s,u,v,2,Precision::Confusion()); if (prop.IsTangentUDefined()) { prop.TangentU(dirU); return true; @@ -3669,7 +3669,7 @@ bool GeomSurface::tangentU(double u, double v, gp_Dir& dirU) const bool GeomSurface::tangentV(double u, double v, gp_Dir& dirV) const { Handle(Geom_Surface) s = Handle(Geom_Surface)::DownCast(handle()); - GeomLProp_SLProps prop(s,u,v,1,Precision::Confusion()); + GeomLProp_SLProps prop(s,u,v,2,Precision::Confusion()); if (prop.IsTangentVDefined()) { prop.TangentV(dirV); return true; @@ -3678,6 +3678,68 @@ bool GeomSurface::tangentV(double u, double v, gp_Dir& dirV) const return false; } +bool GeomSurface::normal(double u, double v, gp_Dir& dir) const +{ + Handle(Geom_Surface) s = Handle(Geom_Surface)::DownCast(handle()); + GeomLProp_SLProps prop(s,u,v,2,Precision::Confusion()); + if (prop.IsNormalDefined()) { + dir = prop.Normal(); + return true; + } + + return false; +} + +bool GeomSurface::isUmbillic(double u, double v) const +{ + Handle(Geom_Surface) s = Handle(Geom_Surface)::DownCast(handle()); + GeomLProp_SLProps prop(s,u,v,2,Precision::Confusion()); + if (prop.IsCurvatureDefined()) { + return prop.IsUmbilic(); + } + + throw Base::RuntimeError("No curvature defined"); +} + +double GeomSurface::curvature(double u, double v, Curvature type) const +{ + Handle(Geom_Surface) s = Handle(Geom_Surface)::DownCast(handle()); + GeomLProp_SLProps prop(s,u,v,2,Precision::Confusion()); + if (prop.IsCurvatureDefined()) { + double value = 0; + switch (type) { + case Maximum: + value = prop.MaxCurvature(); + break; + case Minimum: + value = prop.MinCurvature(); + break; + case Mean: + value = prop.MeanCurvature(); + break; + case Gaussian: + value = prop.GaussianCurvature(); + break; + } + + return value; + } + + throw Base::RuntimeError("No curvature defined"); +} + +void GeomSurface::curvatureDirections(double u, double v, gp_Dir& maxD, gp_Dir& minD) const +{ + Handle(Geom_Surface) s = Handle(Geom_Surface)::DownCast(handle()); + GeomLProp_SLProps prop(s,u,v,2,Precision::Confusion()); + if (prop.IsCurvatureDefined()) { + prop.CurvatureDirections(maxD, minD); + return; + } + + throw Base::RuntimeError("No curvature defined"); +} + // ------------------------------------------------- TYPESYSTEM_SOURCE(Part::GeomBezierSurface,Part::GeomSurface) diff --git a/src/Mod/Part/App/Geometry.h b/src/Mod/Part/App/Geometry.h index ddf0f519c9..63eb9b19f5 100644 --- a/src/Mod/Part/App/Geometry.h +++ b/src/Mod/Part/App/Geometry.h @@ -727,12 +727,27 @@ class PartExport GeomSurface : public Geometry { TYPESYSTEM_HEADER(); public: + enum Curvature { + Maximum, + Minimum, + Mean, + Gaussian + }; + GeomSurface(); virtual ~GeomSurface(); TopoDS_Shape toShape() const; bool tangentU(double u, double v, gp_Dir& dirU) const; bool tangentV(double u, double v, gp_Dir& dirV) const; + bool normal(double u, double v, gp_Dir& dir) const; + + /** @name Curvature information */ + //@{ + bool isUmbillic(double u, double v) const; + double curvature(double u, double v, Curvature) const; + void curvatureDirections(double u, double v, gp_Dir& maxD, gp_Dir& minD) const; + //@} }; class PartExport GeomBezierSurface : public GeomSurface diff --git a/src/Mod/Part/App/GeometrySurfacePy.xml b/src/Mod/Part/App/GeometrySurfacePy.xml index 856b80dd9c..7d80c7c935 100644 --- a/src/Mod/Part/App/GeometrySurfacePy.xml +++ b/src/Mod/Part/App/GeometrySurfacePy.xml @@ -24,15 +24,47 @@ - Computes the point of parameter (u,v) on this surface + value(u,v) -> Point +Computes the point of parameter (u,v) on this surface - Computes the tangent of parameter (u,v) on this geometry + tangent(u,v) -> (Vector,Vector) +Computes the tangent of parameter (u,v) on this geometry - + + + normal(u,v) -> Vector +Computes the normal of parameter (u,v) on this geometry + + + + + isUmbillic(u,v) -> bool +Check if the geometry on parameter is an umbillic point, +i.e. maximum and minimum curvature are equal. + + + + + curvature(u,v,type) -> float +The value of type must be one of this: Max, Min, Mean or Gauss +Computes the curvature of parameter (u,v) on this geometry + + + + + curvatureDirections(u,v) -> (Vector,Vector) +Computes the directions of maximum and minimum curvature +of parameter (u,v) on this geometry. +The first vector corresponds to the maximum curvature, +the second vector corresponds to the minimum curvature. + + + + Returns the parametric bounds (U1, U2, V1, V2) of this trimmed surface. diff --git a/src/Mod/Part/App/GeometrySurfacePyImp.cpp b/src/Mod/Part/App/GeometrySurfacePyImp.cpp index 01d534a0b0..2ba852f1d3 100644 --- a/src/Mod/Part/App/GeometrySurfacePyImp.cpp +++ b/src/Mod/Part/App/GeometrySurfacePyImp.cpp @@ -312,7 +312,7 @@ PyObject* GeometrySurfacePy::tangent(PyObject *args) return 0; gp_Dir dir; Py::Tuple tuple(2); - GeomLProp_SLProps prop(s,u,v,1,Precision::Confusion()); + GeomLProp_SLProps prop(s,u,v,2,Precision::Confusion()); if (prop.IsTangentUDefined()) { prop.TangentU(dir); tuple.setItem(0, Py::Vector(Base::Vector3d(dir.X(),dir.Y(),dir.Z()))); @@ -335,6 +335,127 @@ PyObject* GeometrySurfacePy::tangent(PyObject *args) return 0; } +PyObject* GeometrySurfacePy::normal(PyObject *args) +{ + try { + GeomSurface* s = getGeomSurfacePtr(); + if (s) { + double u,v; + if (!PyArg_ParseTuple(args, "dd", &u,&v)) + return 0; + gp_Dir d; + if (s->normal(u,v,d)) { + return new Base::VectorPy(Base::Vector3d(d.X(),d.Y(),d.Z())); + } + else { + PyErr_SetString(PyExc_RuntimeError, "normal at this point is not defined"); + return 0; + } + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) e = Standard_Failure::Caught(); + PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); + return 0; + } + + PyErr_SetString(PartExceptionOCCError, "Geometry is not a surface"); + return 0; +} + +PyObject* GeometrySurfacePy::isUmbillic(PyObject *args) +{ + try { + GeomSurface* s = getGeomSurfacePtr(); + if (s) { + double u,v; + if (!PyArg_ParseTuple(args, "dd", &u,&v)) + return 0; + + bool val = s->isUmbillic(u,v); + return PyBool_FromLong(val ? 1 : 0); + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) e = Standard_Failure::Caught(); + PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); + return 0; + } + + PyErr_SetString(PartExceptionOCCError, "Geometry is not a surface"); + return 0; +} + +PyObject* GeometrySurfacePy::curvatureDirections(PyObject *args) +{ + try { + GeomSurface* s = getGeomSurfacePtr(); + if (s) { + double u,v; + if (!PyArg_ParseTuple(args, "dd", &u,&v)) + return 0; + + gp_Dir maxd, mind; + s->curvatureDirections(u,v,maxd,mind); + + Py::Tuple tuple(2); + tuple.setItem(0, Py::Vector(Base::Vector3d(maxd.X(),maxd.Y(),maxd.Z()))); + tuple.setItem(1, Py::Vector(Base::Vector3d(mind.X(),mind.Y(),mind.Z()))); + return Py::new_reference_to(tuple); + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) e = Standard_Failure::Caught(); + PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); + return 0; + } + + PyErr_SetString(PartExceptionOCCError, "Geometry is not a surface"); + return 0; +} + +PyObject* GeometrySurfacePy::curvature(PyObject *args) +{ + try { + GeomSurface* s = getGeomSurfacePtr(); + if (s) { + double u,v; + char* type; + if (!PyArg_ParseTuple(args, "dds", &u,&v,&type)) + return 0; + + GeomSurface::Curvature t; + if (strcmp(type,"Max") == 0) { + t = GeomSurface::Maximum; + } + else if (strcmp(type,"Min") == 0) { + t = GeomSurface::Minimum; + } + else if (strcmp(type,"Mean") == 0) { + t = GeomSurface::Mean; + } + else if (strcmp(type,"Gauss") == 0) { + t = GeomSurface::Gaussian; + } + else { + PyErr_SetString(PyExc_ValueError, "unknown curvature type"); + return 0; + } + + double c = s->curvature(u,v,t); + return PyFloat_FromDouble(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 surface"); + return 0; +} + PyObject* GeometrySurfacePy::parameter(PyObject *args) { Handle(Geom_Surface) surf = Handle(Geom_Surface)