From f40644350e78c08c954049d8144b7c2bea1e48a9 Mon Sep 17 00:00:00 2001 From: kgv Date: Fri, 17 Feb 2017 11:30:42 +0300 Subject: [PATCH] 0028469: Visualization, StdPrs_ShadedShape - do not create redundant copy of normal array --- src/StdPrs/StdPrs_ShadedShape.cxx | 18 ++++-- src/StdPrs/StdPrs_ToolTriangulatedShape.cxx | 67 ++++++++++++--------- src/StdPrs/StdPrs_ToolTriangulatedShape.hxx | 7 +++ 3 files changed, 57 insertions(+), 35 deletions(-) diff --git a/src/StdPrs/StdPrs_ShadedShape.cxx b/src/StdPrs/StdPrs_ShadedShape.cxx index 2895a02388..59ea4c2c90 100644 --- a/src/StdPrs/StdPrs_ShadedShape.cxx +++ b/src/StdPrs/StdPrs_ShadedShape.cxx @@ -190,8 +190,9 @@ namespace // Extracts vertices & normals from nodes const TColgp_Array1OfPnt& aNodes = aT->Nodes(); const TColgp_Array1OfPnt2d& aUVNodes = aT->UVNodes(); - TColgp_Array1OfDir aNormals (aNodes.Lower(), aNodes.Upper()); - StdPrs_ToolTriangulatedShape::Normal (aFace, aPolyConnect, aNormals); + StdPrs_ToolTriangulatedShape::Normal (aFace, aPolyConnect); + const TShort_Array1OfShortReal& aNormals = aT->Normals(); + const Standard_ShortReal* aNormArr = &aNormals.First(); if (theHasTexels) { @@ -204,22 +205,27 @@ namespace for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter) { aPoint = aNodes (aNodeIter); + const Standard_Integer anId = 3 * (aNodeIter - aNodes.Lower()); + gp_Dir aNorm (aNormArr[anId + 0], aNormArr[anId + 1], aNormArr[anId + 2]); + if (aFace.Orientation() == TopAbs_REVERSED) + { + aNorm.Reverse(); + } if (!aLoc.IsIdentity()) { aPoint.Transform (aTrsf); - - aNormals (aNodeIter) = aNormals (aNodeIter).Transformed (aTrsf); + aNorm.Transform (aTrsf); } if (theHasTexels && aUVNodes.Upper() == aNodes.Upper()) { const gp_Pnt2d aTexel = gp_Pnt2d ((-theUVOrigin.X() + (theUVRepeat.X() * (aUVNodes (aNodeIter).X() - aUmin)) / dUmax) / theUVScale.X(), (-theUVOrigin.Y() + (theUVRepeat.Y() * (aUVNodes (aNodeIter).Y() - aVmin)) / dVmax) / theUVScale.Y()); - anArray->AddVertex (aPoint, aNormals (aNodeIter), aTexel); + anArray->AddVertex (aPoint, aNorm, aTexel); } else { - anArray->AddVertex (aPoint, aNormals (aNodeIter)); + anArray->AddVertex (aPoint, aNorm); } } diff --git a/src/StdPrs/StdPrs_ToolTriangulatedShape.cxx b/src/StdPrs/StdPrs_ToolTriangulatedShape.cxx index e5ba469c55..6d9eaa02b9 100644 --- a/src/StdPrs/StdPrs_ToolTriangulatedShape.cxx +++ b/src/StdPrs/StdPrs_ToolTriangulatedShape.cxx @@ -134,33 +134,13 @@ Standard_Boolean StdPrs_ToolTriangulatedShape::IsClosed (const TopoDS_Shape& the //function : Normal //purpose : //======================================================================= -void StdPrs_ToolTriangulatedShape::Normal (const TopoDS_Face& theFace, - Poly_Connect& thePolyConnect, - TColgp_Array1OfDir& theNormals) +void StdPrs_ToolTriangulatedShape::Normal (const TopoDS_Face& theFace, + Poly_Connect& thePolyConnect) { const Handle(Poly_Triangulation)& aPolyTri = thePolyConnect.Triangulation(); - const TColgp_Array1OfPnt& aNodes = aPolyTri->Nodes(); - if (aPolyTri->HasNormals()) + if (aPolyTri.IsNull() + || aPolyTri->HasNormals()) { - // normals pre-computed in triangulation structure - const TShort_Array1OfShortReal& aNormals = aPolyTri->Normals(); - const Standard_ShortReal* aNormArr = &(aNormals.Value (aNormals.Lower())); - for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter) - { - const Standard_Integer anId = 3 * (aNodeIter - aNodes.Lower()); - const gp_Dir aNorm (aNormArr[anId + 0], - aNormArr[anId + 1], - aNormArr[anId + 2]); - theNormals (aNodeIter) = aNorm; - } - - if (theFace.Orientation() == TopAbs_REVERSED) - { - for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter) - { - theNormals.ChangeValue (aNodeIter).Reverse(); - } - } return; } @@ -174,11 +154,13 @@ void StdPrs_ToolTriangulatedShape::Normal (const TopoDS_Face& theFace, ? &aPolyTri->UVNodes() : NULL; Standard_Integer aTri[3]; + const TColgp_Array1OfPnt& aNodes = aPolyTri->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, theNormals (aNodeIter)) > 1) + || GeomLib::NormEstim (aSurf, aNodesUV->Value (aNodeIter), aTol, aNorm) > 1) { // compute flat normals gp_XYZ eqPlan (0.0, 0.0, 0.0); @@ -195,15 +177,42 @@ void StdPrs_ToolTriangulatedShape::Normal (const TopoDS_Face& theFace, } } const Standard_Real aModMax = eqPlan.Modulus(); - theNormals (aNodeIter) = (aModMax > aTol) ? gp_Dir (eqPlan) : gp::DZ(); + aNorm = (aModMax > aTol) ? gp_Dir (eqPlan) : gp::DZ(); } const Standard_Integer anId = (aNodeIter - aNodes.Lower()) * 3; - aNormals->SetValue (anId + 1, (Standard_ShortReal )theNormals (aNodeIter).X()); - aNormals->SetValue (anId + 2, (Standard_ShortReal )theNormals (aNodeIter).Y()); - aNormals->SetValue (anId + 3, (Standard_ShortReal )theNormals (aNodeIter).Z()); + aNormals->SetValue (anId + 1, (Standard_ShortReal )aNorm.X()); + aNormals->SetValue (anId + 2, (Standard_ShortReal )aNorm.Y()); + aNormals->SetValue (anId + 3, (Standard_ShortReal )aNorm.Z()); } aPolyTri->SetNormals (aNormals); +} + +//======================================================================= +//function : Normal +//purpose : +//======================================================================= +void StdPrs_ToolTriangulatedShape::Normal (const TopoDS_Face& theFace, + Poly_Connect& thePolyConnect, + TColgp_Array1OfDir& theNormals) +{ + const Handle(Poly_Triangulation)& aPolyTri = thePolyConnect.Triangulation(); + if (!aPolyTri->HasNormals()) + { + Normal (theFace, thePolyConnect); + } + + const TColgp_Array1OfPnt& aNodes = aPolyTri->Nodes(); + const TShort_Array1OfShortReal& aNormals = aPolyTri->Normals(); + const Standard_ShortReal* aNormArr = &aNormals.First(); + for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter) + { + const Standard_Integer anId = 3 * (aNodeIter - aNodes.Lower()); + const gp_Dir aNorm (aNormArr[anId + 0], + aNormArr[anId + 1], + aNormArr[anId + 2]); + theNormals (aNodeIter) = aNorm; + } if (theFace.Orientation() == TopAbs_REVERSED) { diff --git a/src/StdPrs/StdPrs_ToolTriangulatedShape.hxx b/src/StdPrs/StdPrs_ToolTriangulatedShape.hxx index 22c3e6617a..0ea94a2245 100644 --- a/src/StdPrs/StdPrs_ToolTriangulatedShape.hxx +++ b/src/StdPrs/StdPrs_ToolTriangulatedShape.hxx @@ -39,6 +39,13 @@ public: //! @return true if shape is closed manifold Solid or compound of such Solids.
Standard_EXPORT static Standard_Boolean IsClosed (const TopoDS_Shape& theShape); + //! Computes nodal normals for Poly_Triangulation structure using UV coordinates and surface. + //! Does nothing if triangulation already defines normals. + //! @param theFace [in] the face + //! @param thePolyConnect [in] the definition of a face triangulation + Standard_EXPORT static void Normal (const TopoDS_Face& theFace, + Poly_Connect& thePolyConnect); + //! Evaluate normals for a triangle of a face. //! @param theFace [in] the face. //! @param thePolyConnect [in] the definition of a face triangulation.