Part: add methods to get the point normals of the triangulation or surface

This commit is contained in:
wmayer
2021-10-08 15:28:22 +02:00
parent 1027ef56ce
commit bc1bec296e
2 changed files with 75 additions and 0 deletions

View File

@@ -29,6 +29,7 @@
# include <Geom_BSplineSurface.hxx>
# include <Geom_Plane.hxx>
# include <GeomAPI_IntSS.hxx>
# include <GeomAPI_ProjectPointOnSurf.hxx>
# include <Geom_Line.hxx>
# include <Geom_Point.hxx>
# include <GeomAdaptor_Curve.hxx>
@@ -356,3 +357,60 @@ bool Part::Tools::getPolygon3D(const TopoDS_Edge& edge, std::vector<gp_Pnt>& poi
return true;
}
void Part::Tools::getPointNormals(const std::vector<gp_Pnt>& points, const std::vector<Poly_Triangle>& facets, std::vector<gp_Vec>& vertexnormals)
{
vertexnormals.resize(points.size());
for (const auto& it : facets) {
// Get the triangle
Standard_Integer n1,n2,n3;
it.Get(n1,n2,n3);
// Calculate triangle normal
gp_Vec v1(points[n1].XYZ());
gp_Vec v2(points[n2].XYZ());
gp_Vec v3(points[n3].XYZ());
gp_Vec n = (v2 - v1) ^ (v3 - v1);
// add the triangle normal to the vertex normal for all points of this triangle
vertexnormals[n1] += n;
vertexnormals[n2] += n;
vertexnormals[n3] += n;
}
for (auto& it : vertexnormals)
it.Normalize();
}
void Part::Tools::getPointNormals(const std::vector<gp_Pnt>& points, const TopoDS_Face& face, std::vector<gp_Vec>& vertexnormals)
{
if (points.size() != vertexnormals.size())
return;
Handle(Geom_Surface) hSurface = BRep_Tool::Surface(face);
if (hSurface.IsNull())
return;
// normalize all vertex normals
for (std::size_t i = 0; i < points.size(); i++) {
try {
GeomAPI_ProjectPointOnSurf ProPntSrf(points[i], hSurface);
Standard_Real u, v;
ProPntSrf.Parameters(1, u, v);
GeomLProp_SLProps propOfFace(hSurface, u, v, 2, gp::Resolution());
gp_Dir normal = propOfFace.Normal();
gp_Vec temp = normal;
if (temp * vertexnormals[i] < 0.0)
temp = -temp;
vertexnormals[i] = temp;
}
catch (...) {
}
vertexnormals[i].Normalize();
}
}

View File

@@ -134,6 +134,23 @@ public:
* \return true if a polygon exists or false otherwise
*/
static bool getPolygon3D(const TopoDS_Edge& edge, std::vector<gp_Pnt>& points);
/*!
* \brief getPointNormals
* Calculate the point normals of the given triangulation.
* \param points
* \param facets
* \param normals
*/
static void getPointNormals(const std::vector<gp_Pnt>& points, const std::vector<Poly_Triangle>& facets, std::vector<gp_Vec>& vertexnormals);
/*!
* \brief getPointNormals
* Computes the more accurate surface normals for the points. If the calculation for a point fails then the precomputed
* point normal of the triangulation is used.
* \param points
* \param face
* \param vertexnormals
*/
static void getPointNormals(const std::vector<gp_Pnt>& points, const TopoDS_Face& face, std::vector<gp_Vec>& vertexnormals);
};
} //namespace Part