1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0028945: Visualization - StdPrs_ToolTriangulatedShape::ComputeNormals() is extremely slow for triangulation-only surface

StdPrs_ToolTriangulatedShape::ComputeNormals() now calls Poly::ComputeNormals() for triangulation-only surfaces.
Poly::ComputeNormals() now averages normal considering triangle size.
This commit is contained in:
kgv
2017-07-25 15:49:53 +03:00
committed by bugmaster
parent 1f9eb89082
commit dc2cc1350e
2 changed files with 69 additions and 61 deletions

View File

@@ -23,6 +23,7 @@
#include <GeomAbs_SurfaceType.hxx>
#include <GeomLib.hxx>
#include <gp_XYZ.hxx>
#include <Poly.hxx>
#include <Poly_Connect.hxx>
#include <Poly_Triangulation.hxx>
#include <Precision.hxx>
@@ -145,22 +146,26 @@ void StdPrs_ToolTriangulatedShape::ComputeNormals (const TopoDS_Face& theFace,
}
// take in face the surface location
const TopoDS_Face aZeroFace = TopoDS::Face (theFace.Located (TopLoc_Location()));
Handle(Geom_Surface) aSurf = BRep_Tool::Surface (aZeroFace);
const Standard_Real aTol = Precision::Confusion();
Handle(TShort_HArray1OfShortReal) aNormals = new TShort_HArray1OfShortReal (1, theTris->NbNodes() * 3);
const TopoDS_Face aZeroFace = TopoDS::Face (theFace.Located (TopLoc_Location()));
Handle(Geom_Surface) aSurf = BRep_Tool::Surface (aZeroFace);
const Poly_Array1OfTriangle& aTriangles = theTris->Triangles();
const TColgp_Array1OfPnt2d* aNodesUV = theTris->HasUVNodes() && !aSurf.IsNull()
? &theTris->UVNodes()
: NULL;
if (!theTris->HasUVNodes() || aSurf.IsNull())
{
// compute normals by averaging triangulation normals sharing the same vertex
Poly::ComputeNormals (theTris);
return;
}
const Standard_Real aTol = Precision::Confusion();
Handle(TShort_HArray1OfShortReal) aNormals = new TShort_HArray1OfShortReal (1, theTris->NbNodes() * 3);
const TColgp_Array1OfPnt2d& aNodesUV = theTris->UVNodes();
Standard_Integer aTri[3];
const TColgp_Array1OfPnt& aNodes = theTris->Nodes();
gp_Dir aNorm;
for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
{
// try to retrieve normal from real surface first, when UV coordinates are available
if (aNodesUV == NULL
|| GeomLib::NormEstim (aSurf, aNodesUV->Value (aNodeIter), aTol, aNorm) > 1)
if (GeomLib::NormEstim (aSurf, aNodesUV.Value (aNodeIter), aTol, aNorm) > 1)
{
if (thePolyConnect.Triangulation() != theTris)
{