0025687: Visualization, XCAF - eliminate visual artifacts at the edges of faces
[occt.git] / src / StdPrs / StdPrs_ShadedShape.cxx
index cfbb5eb..d6e8403 100644 (file)
@@ -149,6 +149,10 @@ namespace
         continue;
       }
       const gp_Trsf& aTrsf = aLoc.Transformation();
+
+      // Determinant of transform matrix less then 0 means that mirror transform applied.
+      Standard_Boolean isMirrored = aTrsf.VectorialPart().Determinant() < 0;
+
       Poly_Connect aPolyConnect (aT);
       // Extracts vertices & normals from nodes
       const TColgp_Array1OfPnt&   aNodes   = aT->Nodes();
@@ -170,7 +174,8 @@ namespace
         if (!aLoc.IsIdentity())
         {
           aPoint.Transform (aTrsf);
-          aNormals (aNodeIter).Transform (aTrsf);
+
+          aNormals (aNodeIter) = aNormals (aNodeIter).Transformed (aTrsf);
         }
 
         if (theHasTexels && aUVNodes.Upper() == aNodes.Upper())
@@ -190,7 +195,7 @@ namespace
       Standard_Integer anIndex[3];
       for (Standard_Integer aTriIter = 1; aTriIter <= aT->NbTriangles(); ++aTriIter)
       {
-        if (aFace.Orientation() == TopAbs_REVERSED)
+        if ((aFace.Orientation() == TopAbs_REVERSED) ^ isMirrored)
         {
           aTriangles (aTriIter).Get (anIndex[0], anIndex[2], anIndex[1]);
         }
@@ -232,56 +237,6 @@ namespace
     return anArray;
   }
 
-  //! Searches closed and unclosed subshapes in shape structure
-  //! and puts them into two compounds for separate processing of closed and unclosed sub-shapes.
-  static void exploreSolids (const TopoDS_Shape& theShape,
-                             const BRep_Builder& theBuilder,
-                             TopoDS_Compound&    theCompoundForClosed,
-                             TopoDS_Compound&    theCompoundForOpened)
-  {
-    if (theShape.IsNull())
-    {
-      return;
-    }
-
-    switch (theShape.ShapeType())
-    {
-      case TopAbs_COMPOUND:
-      case TopAbs_COMPSOLID:
-      {
-        for (TopoDS_Iterator anIter (theShape); anIter.More(); anIter.Next())
-        {
-          exploreSolids (anIter.Value(), theBuilder, theCompoundForClosed, theCompoundForOpened);
-        }
-        return;
-      }
-      case TopAbs_SOLID:
-      {
-        for (TopoDS_Iterator anIter (theShape); anIter.More(); anIter.Next())
-        {
-          const TopoDS_Shape& aSubShape   = anIter.Value();
-          const Standard_Boolean isClosed = aSubShape.ShapeType() == TopAbs_SHELL &&
-                                            BRep_Tool::IsClosed (aSubShape) &&
-                                            StdPrs_ToolShadedShape::IsTriangulated (aSubShape);
-          theBuilder.Add (isClosed ? theCompoundForClosed : theCompoundForOpened, aSubShape);
-        }
-        return;
-      }
-      case TopAbs_SHELL:
-      case TopAbs_FACE:
-      {
-        theBuilder.Add (theCompoundForOpened, theShape);
-        return;
-      }
-      case TopAbs_WIRE:
-      case TopAbs_EDGE:
-      case TopAbs_VERTEX:
-      case TopAbs_SHAPE:
-      default:
-        return;
-    }
-  }
-
   //! Prepare shaded presentation for specified shape
   static Standard_Boolean shadeFromShape (const TopoDS_Shape&               theShape,
                                           const Handle(Prs3d_Presentation)& thePrs,
@@ -430,6 +385,66 @@ namespace
   }
 };
 
+// =======================================================================
+// function : ExploreSolids
+// purpose  :
+// =======================================================================
+void StdPrs_ShadedShape::ExploreSolids (const TopoDS_Shape&    theShape,
+                                        const BRep_Builder&    theBuilder,
+                                        TopoDS_Compound&       theClosed,
+                                        TopoDS_Compound&       theOpened,
+                                        const Standard_Boolean theIgnore1DSubShape)
+{
+  if (theShape.IsNull())
+  {
+    return;
+  }
+
+  switch (theShape.ShapeType())
+  {
+    case TopAbs_COMPOUND:
+    case TopAbs_COMPSOLID:
+    {
+      for (TopoDS_Iterator anIter (theShape); anIter.More(); anIter.Next())
+      {
+        ExploreSolids (anIter.Value(), theBuilder, theClosed, theOpened, theIgnore1DSubShape);
+      }
+      return;
+    }
+    case TopAbs_SOLID:
+    {
+      for (TopoDS_Iterator anIter (theShape); anIter.More(); anIter.Next())
+      {
+        const TopoDS_Shape& aSubShape   = anIter.Value();
+        const Standard_Boolean isClosed = aSubShape.ShapeType() == TopAbs_SHELL &&
+                                          BRep_Tool::IsClosed (aSubShape)       &&
+                                          StdPrs_ToolShadedShape::IsTriangulated (aSubShape);
+        theBuilder.Add (isClosed ? theClosed : theOpened, aSubShape);
+      }
+      return;
+    }
+    case TopAbs_SHELL:
+    case TopAbs_FACE:
+    {
+      theBuilder.Add (theOpened, theShape);
+      return;
+    }
+    case TopAbs_WIRE:
+    case TopAbs_EDGE:
+    case TopAbs_VERTEX:
+    {
+      if (!theIgnore1DSubShape)
+      {
+        theBuilder.Add (theOpened, theShape);
+      }
+      return;
+    }
+    case TopAbs_SHAPE:
+    default:
+      return;
+  }
+}
+
 // =======================================================================
 // function : Add
 // purpose  :
@@ -437,11 +452,11 @@ namespace
 void StdPrs_ShadedShape::Add (const Handle(Prs3d_Presentation)& thePrs,
                               const TopoDS_Shape&               theShape,
                               const Handle(Prs3d_Drawer)&       theDrawer,
-                              const Standard_Boolean            theToExploreSolids)
+                              const StdPrs_Volume               theVolume)
 {
   gp_Pnt2d aDummy;
   StdPrs_ShadedShape::Add (thePrs, theShape, theDrawer,
-                           Standard_False, aDummy, aDummy, aDummy, theToExploreSolids);
+                           Standard_False, aDummy, aDummy, aDummy, theVolume);
 }
 
 // =======================================================================
@@ -479,7 +494,7 @@ void StdPrs_ShadedShape::Add (const Handle (Prs3d_Presentation)& thePrs,
                               const gp_Pnt2d&                    theUVOrigin,
                               const gp_Pnt2d&                    theUVRepeat,
                               const gp_Pnt2d&                    theUVScale,
-                              const Standard_Boolean             theToExploreSolids)
+                              const StdPrs_Volume                theVolume)
 {
   if (theShape.IsNull())
   {
@@ -498,14 +513,14 @@ void StdPrs_ShadedShape::Add (const Handle (Prs3d_Presentation)& thePrs,
   if ((theShape.ShapeType() == TopAbs_COMPOUND
     || theShape.ShapeType() == TopAbs_COMPSOLID
     || theShape.ShapeType() == TopAbs_SOLID)
-   &&  theToExploreSolids)
+   &&  theVolume == StdPrs_Volume_Autodetection)
   {
     // collect two compounds: for opened and closed (solid) sub-shapes
     TopoDS_Compound anOpened, aClosed;
     BRep_Builder aBuilder;
     aBuilder.MakeCompound (aClosed);
     aBuilder.MakeCompound (anOpened);
-    exploreSolids (theShape, aBuilder, aClosed, anOpened);
+    ExploreSolids (theShape, aBuilder, aClosed, anOpened, Standard_True);
 
     TopoDS_Iterator aShapeIter (aClosed);
     if (aShapeIter.More())
@@ -523,9 +538,10 @@ void StdPrs_ShadedShape::Add (const Handle (Prs3d_Presentation)& thePrs,
   }
   else
   {
+    // if the shape type is not compound, composolid or solid, use autodetection back-facing filled
     shadeFromShape (theShape, thePrs, theDrawer,
                     theHasTexels, theUVOrigin, theUVRepeat, theUVScale,
-                    StdPrs_ToolShadedShape::IsClosed (theShape));
+                    (theVolume == StdPrs_Volume_Closed ? Standard_True : Standard_False));
   }
 
   if (theDrawer->IsFaceBoundaryDraw())