Part: add convenience function to convert TColgp_Array1OfDir to std::vector

This commit is contained in:
wmayer
2021-10-09 11:37:18 +02:00
parent d61887c10b
commit 87c70167be
2 changed files with 111 additions and 0 deletions

View File

@@ -420,6 +420,7 @@ void Part::Tools::getPointNormals(const std::vector<gp_Pnt>& points, const TopoD
void Part::Tools::getPointNormals(const TopoDS_Face& theFace, Handle(Poly_Triangulation) aPolyTri, TColgp_Array1OfDir& theNormals)
{
#if OCC_VERSION_HEX < 0x070600
const TColgp_Array1OfPnt& aNodes = aPolyTri->Nodes();
if(aPolyTri->HasNormals())
@@ -500,4 +501,91 @@ void Part::Tools::getPointNormals(const TopoDS_Face& theFace, Handle(Poly_Triang
}
}
}
#else
Standard_Integer numNodes = aPolyTri->NbNodes();
if(aPolyTri->HasNormals())
{
for(Standard_Integer aNodeIter = 1; aNodeIter <= numNodes; ++aNodeIter)
{
theNormals(aNodeIter) = aPolyTri->Normal(aNodeIter);
}
if(theFace.Orientation() == TopAbs_REVERSED)
{
for(Standard_Integer aNodeIter = 1; aNodeIter <= numNodes; ++aNodeIter)
{
theNormals.ChangeValue(aNodeIter).Reverse();
}
}
}
else {
// take in face the surface location
Poly_Connect thePolyConnect(aPolyTri);
const TopoDS_Face aZeroFace = TopoDS::Face(theFace.Located(TopLoc_Location()));
Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aZeroFace);
const Standard_Real aTol = Precision::Confusion();
Standard_Boolean hasNodesUV = aPolyTri->HasUVNodes() && !aSurf.IsNull();
Standard_Integer aTri[3];
for(Standard_Integer aNodeIter = 1; aNodeIter <= numNodes; ++aNodeIter)
{
// try to retrieve normal from real surface first, when UV coordinates are available
if (!hasNodesUV || GeomLib::NormEstim(aSurf, aPolyTri->UVNode(aNodeIter), aTol, theNormals(aNodeIter)) > 1)
{
// compute flat normals
gp_XYZ eqPlan(0.0, 0.0, 0.0);
for(thePolyConnect.Initialize(aNodeIter); thePolyConnect.More(); thePolyConnect.Next())
{
aPolyTri->Triangle(thePolyConnect.Value()).Get(aTri[0], aTri[1], aTri[2]);
const gp_XYZ v1(aPolyTri->Node(aTri[1]).Coord() - aPolyTri->Node(aTri[0]).Coord());
const gp_XYZ v2(aPolyTri->Node(aTri[2]).Coord() - aPolyTri->Node(aTri[1]).Coord());
const gp_XYZ vv = v1 ^ v2;
const Standard_Real aMod = vv.Modulus();
if(aMod >= aTol)
{
eqPlan += vv / aMod;
}
}
const Standard_Real aModMax = eqPlan.Modulus();
theNormals(aNodeIter) = (aModMax > aTol) ? gp_Dir(eqPlan) : gp::DZ();
}
aPolyTri->SetNormal(aNodeIter, theNormals(aNodeIter));
}
if(theFace.Orientation() == TopAbs_REVERSED)
{
for(Standard_Integer aNodeIter = 1; aNodeIter <= numNodes; ++aNodeIter)
{
theNormals.ChangeValue(aNodeIter).Reverse();
}
}
}
#endif
}
void Part::Tools::getPointNormals(const TopoDS_Face& face, Handle(Poly_Triangulation) aPoly, std::vector<gp_Vec>& normals)
{
TColgp_Array1OfDir dirs (1, aPoly->NbNodes());
getPointNormals(face, aPoly, dirs);
normals.reserve(aPoly->NbNodes());
for (int i = dirs.Lower(); i <= dirs.Upper(); ++i) {
normals.emplace_back(dirs(i).XYZ());
}
}
void Part::Tools::applyTransformationOnNormals(const TopLoc_Location& loc, std::vector<gp_Vec>& normals)
{
if (!loc.IsIdentity()) {
gp_Trsf myTransf = loc.Transformation();
for (auto& it : normals) {
it.Transform(myTransf);
}
}
}

View File

@@ -34,6 +34,7 @@
#include <Poly_Triangulation.hxx>
#include <TColStd_ListOfTransient.hxx>
#include <TColgp_Array1OfDir.hxx>
#include <TopLoc_Location.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <vector>
@@ -153,7 +154,29 @@ public:
* \param vertexnormals
*/
static void getPointNormals(const std::vector<gp_Pnt>& points, const TopoDS_Face& face, std::vector<gp_Vec>& vertexnormals);
/*!
* \brief getPointNormals
* Computes the exact surface normals for the points by using the UV coordinates of the mesh vertexes.
* \param face
* \param aPoly
* \param vertexnormals
*/
static void getPointNormals(const TopoDS_Face& face, Handle(Poly_Triangulation) aPoly, TColgp_Array1OfDir& normals);
/*!
* \brief getPointNormals
* Computes the exact surface normals for the points by using the UV coordinates of the mesh vertexes.
* \param face
* \param aPoly
* \param vertexnormals
*/
static void getPointNormals(const TopoDS_Face& face, Handle(Poly_Triangulation) aPoly, std::vector<gp_Vec>& normals);
/*!
* \brief applyTransformationOnNormals
* Apply the transformation to the vectors
* \param loc
* \param normals
*/
static void applyTransformationOnNormals(const TopLoc_Location& loc, std::vector<gp_Vec>& normals);
};
} //namespace Part