0028469: Visualization, StdPrs_ShadedShape - do not create redundant copy of normal...
authorkgv <kgv@opencascade.com>
Fri, 17 Feb 2017 08:30:42 +0000 (11:30 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 2 Mar 2017 09:31:58 +0000 (12:31 +0300)
src/StdPrs/StdPrs_ShadedShape.cxx
src/StdPrs/StdPrs_ToolTriangulatedShape.cxx
src/StdPrs/StdPrs_ToolTriangulatedShape.hxx

index 2895a02..59ea4c2 100644 (file)
@@ -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);
         }
       }
 
index e5ba469..6d9eaa0 100644 (file)
@@ -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)
   {
index 22c3e66..0ea94a2 100644 (file)
@@ -39,6 +39,13 @@ public:
   //! @return true if shape is closed manifold Solid or compound of such Solids. <br>
   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.