0028036: Visualization, AIS_ColoredShape - handle correctly nested compounds within...
authorkgv <kgv@opencascade.com>
Tue, 1 Nov 2016 18:36:24 +0000 (21:36 +0300)
committerabv <abv@opencascade.com>
Tue, 8 Nov 2016 16:29:58 +0000 (19:29 +0300)
AIS_ColoredShape::Compute() now parses nested compounds in two passes
to handle complex cases with compounds used for grouping styles.

src/AIS/AIS_ColoredShape.cxx
src/AIS/AIS_ColoredShape.hxx
src/StdPrs/StdPrs_ShadedShape.cxx
src/StdPrs/StdPrs_ShadedShape.hxx
src/XCAFPrs/XCAFPrs.cxx
tests/bugs/vis/bug28036_1 [new file with mode: 0644]
tests/bugs/vis/bug28036_2 [new file with mode: 0644]

index d092581..370a032 100644 (file)
@@ -21,6 +21,8 @@
 #include <gp_Pnt2d.hxx>
 #include <Graphic3d_AspectFillArea3d.hxx>
 #include <Graphic3d_AspectLine3d.hxx>
+#include <Graphic3d_ArrayOfTriangles.hxx>
+#include <Graphic3d_ArrayOfSegments.hxx>
 #include <Graphic3d_Group.hxx>
 #include <Graphic3d_StructureManager.hxx>
 #include <Graphic3d_Texture2Dmanual.hxx>
 #include <TopoDS_Compound.hxx>
 #include <TopoDS_Iterator.hxx>
 
-
-
-
 IMPLEMENT_STANDARD_RTTIEXT(AIS_ColoredShape,AIS_Shape)
 IMPLEMENT_STANDARD_RTTIEXT(AIS_ColoredDrawer,Prs3d_Drawer)
 
+namespace
+{
+  //! Collect all sub-compounds into map.
+  static void collectSubCompounds (TopTools_MapOfShape& theMap,
+                                   const TopoDS_Shape&  theShape)
+  {
+    for (TopoDS_Iterator aChildIter (theShape); aChildIter.More(); aChildIter.Next())
+    {
+      const TopoDS_Shape& aShape = aChildIter.Value();
+      if (aShape.ShapeType() == TopAbs_COMPOUND
+       && theMap.Add (aShape))
+      {
+        collectSubCompounds (theMap, theShape);
+      }
+    }
+  }
+}
+
 //=======================================================================
 //function : AIS_ColoredShape
 //purpose  :
@@ -336,44 +353,66 @@ void AIS_ColoredShape::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
     Prs3d::GetDeflection (myshape, myDrawer);
   }
 
-  TopoDS_Compound anOpened, aClosed;
-  BRep_Builder aBuilder;
-  aBuilder.MakeCompound (aClosed);
-  aBuilder.MakeCompound (anOpened);
-  if (theMode == AIS_Shaded && myshape.ShapeType() <= TopAbs_SOLID)
-  {
-    StdPrs_ShadedShape::ExploreSolids (myshape, aBuilder, aClosed, anOpened, Standard_False);
-  }
-  else
-  {
-    aBuilder.Add (anOpened, myshape);
-  }
-
-  // myShapeColors + anOpened --> array[TopAbs_ShapeEnum] of map of color-to-compound
-  DataMapOfShapeCompd aDispatchedOpened [(size_t)TopAbs_SHAPE];
-  dispatchColors (anOpened, myShapeColors, aDispatchedOpened);
-  addShapesWithCustomProps (thePrs, aDispatchedOpened, theMode, StdPrs_Volume_Opened);
-
-  if (theMode == AIS_Shaded)
+  // Extract myShapeColors map (KeyshapeColored -> Color)
+  // to subshapes map (Subshape -> Color).
+  // This needed when colored shape is not part of BaseShape
+  // (but subshapes are) and actually container for subshapes.
+  AIS_DataMapOfShapeDrawer aSubshapeDrawerMap;
   {
-    if (isShapeEntirelyVisible())
+    // unroll compounds specified for grouping sub-shapes with the same style
+    // (e.g. the compounds that are not a part of the main shape)
+    TopTools_MapOfShape aMapOfOwnCompounds;
+    if (myshape.ShapeType() == TopAbs_COMPOUND)
     {
-      // myShapeColors + aClosed --> array[TopAbs_ShapeEnum] of map of color-to-compound
-      DataMapOfShapeCompd aDispatchedClosed [(size_t)TopAbs_SHAPE];
-      dispatchColors (aClosed, myShapeColors, aDispatchedClosed);
-      addShapesWithCustomProps (thePrs, aDispatchedClosed, theMode, StdPrs_Volume_Closed);
+      aMapOfOwnCompounds.Add (myshape);
+      collectSubCompounds (aMapOfOwnCompounds, myshape);
     }
-    else
+    for (AIS_DataMapOfShapeDrawer::Iterator aKeyShapeIter (myShapeColors);
+         aKeyShapeIter.More(); aKeyShapeIter.Next())
     {
-      for (TopoDS_Iterator aSolidIter (aClosed); aSolidIter.More(); aSolidIter.Next())
+      const TopoDS_Shape& aKeyShape = aKeyShapeIter.Key();
+      if (aKeyShape.ShapeType() != TopAbs_COMPOUND
+       || aMapOfOwnCompounds.Contains (aKeyShape))
       {
-        DataMapOfShapeCompd aDispatchedClosed [(size_t)TopAbs_SHAPE];
-        dispatchColors (aSolidIter.Value(), myShapeColors, aDispatchedClosed);
-        addShapesWithCustomProps (thePrs, aDispatchedClosed, theMode,
-                                  isShapeEntirelyVisible (aDispatchedClosed) ? StdPrs_Volume_Closed : StdPrs_Volume_Opened);
+        continue;
+      }
+
+      for (TopoDS_Iterator aChildIter (aKeyShape); aChildIter.More(); aChildIter.Next())
+      {
+        const TopoDS_Shape& aShape = aChildIter.Value();
+        if (!myShapeColors.IsBound (aShape))
+        {
+          bindSubShapes (aSubshapeDrawerMap, aShape, aKeyShapeIter.Value());
+        }
       }
     }
+
+    // assign other sub-shapes with styles
+    for (AIS_DataMapOfShapeDrawer::Iterator aKeyShapeIter (myShapeColors);
+         aKeyShapeIter.More(); aKeyShapeIter.Next())
+    {
+      const TopoDS_Shape& aKeyShape = aKeyShapeIter.Key();
+      if (myshape == aKeyShape
+      || (aKeyShape.ShapeType() == TopAbs_COMPOUND
+      && !aMapOfOwnCompounds.Contains (aKeyShape)))
+      {
+        continue;
+      }
+
+      bindSubShapes (aSubshapeDrawerMap, aKeyShape, aKeyShapeIter.Value());
+    }
   }
+
+  Handle(AIS_ColoredDrawer) aBaseDrawer;
+  myShapeColors.Find (myshape, aBaseDrawer);
+
+  // myShapeColors + anOpened --> array[TopAbs_ShapeEnum] of map of color-to-compound
+  DataMapOfDrawerCompd aDispatchedOpened[(size_t)TopAbs_SHAPE];
+  DataMapOfDrawerCompd aDispatchedClosed;
+  dispatchColors (aBaseDrawer, myshape,
+                  aSubshapeDrawerMap, TopAbs_COMPOUND, Standard_False,
+                  aDispatchedOpened, theMode == AIS_Shaded ? aDispatchedClosed : aDispatchedOpened[TopAbs_FACE]);
+  addShapesWithCustomProps (thePrs, aDispatchedOpened, aDispatchedClosed, theMode);
 }
 
 //=======================================================================
@@ -381,21 +420,25 @@ void AIS_ColoredShape::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
 //purpose  :
 //=======================================================================
 void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation)& thePrs,
-                                                 DataMapOfShapeCompd*              theDispatched,
-                                                 const Standard_Integer            theMode,
-                                                 const StdPrs_Volume               theVolume)
+                                                 const DataMapOfDrawerCompd* theDrawerOpenedShapePerType,
+                                                 const DataMapOfDrawerCompd& theDrawerClosedFaces,
+                                                 const Standard_Integer theMode)
 {
-  Handle(AIS_ColoredDrawer) aCustomDrawer;
-  for (size_t aShType = 0; aShType < (size_t )TopAbs_SHAPE; ++aShType)
-  {
-    DataMapOfShapeCompd& aKeyshapeDrawshapeMap = theDispatched[aShType];
-    for (DataMapOfShapeCompd::Iterator aMapIter (aKeyshapeDrawshapeMap);
+  Handle(Graphic3d_Group) anOpenGroup, aClosedGroup;
+  for (size_t aShType = 0; aShType <= (size_t )TopAbs_SHAPE; ++aShType)
+  {
+    const Standard_Boolean isClosed = aShType == TopAbs_SHAPE;
+    Handle(Graphic3d_Group)& aShadedGroup = isClosed ? aClosedGroup : anOpenGroup;
+    const DataMapOfDrawerCompd& aDrawerShapeMap = isClosed
+                                                ? theDrawerClosedFaces
+                                                : theDrawerOpenedShapePerType[aShType];
+    for (DataMapOfDrawerCompd::Iterator aMapIter (aDrawerShapeMap);
          aMapIter.More(); aMapIter.Next())
     {
-      const TopoDS_Shape&    aShapeKey  = aMapIter.Key();   // key shape with detailed color or a base shape
+      const Handle(AIS_ColoredDrawer)& aCustomDrawer = aMapIter.Key();
       const TopoDS_Compound& aShapeDraw = aMapIter.Value(); // compound of subshapes with <aShType> type
       Handle(Prs3d_Drawer) aDrawer;
-      if (myShapeColors.Find (aShapeKey, aCustomDrawer))
+      if (!aCustomDrawer.IsNull())
       {
         aDrawer = aCustomDrawer;
         if (aCustomDrawer->IsHidden())
@@ -421,7 +464,40 @@ void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation
        && aShapeDraw.ShapeType() <= TopAbs_FACE
        && !IsInfinite())
       {
-        StdPrs_ShadedShape::Add (thePrs, aShapeDraw, aDrawer, theVolume);
+        // add wireframe presentation for isolated edges and vertices
+        StdPrs_ShadedShape::AddWireframeForFreeElements (thePrs, aShapeDraw, aDrawer);
+
+        // add special wireframe presentation for faces without triangulation
+        StdPrs_ShadedShape::AddWireframeForFacesWithoutTriangles (thePrs, aShapeDraw, aDrawer);
+
+        Handle(Graphic3d_ArrayOfTriangles) aTriangles = StdPrs_ShadedShape::FillTriangles (aShapeDraw);
+        if (!aTriangles.IsNull())
+        {
+          if (aShadedGroup.IsNull())
+          {
+            aShadedGroup = Prs3d_Root::NewGroup (thePrs);
+            aShadedGroup->SetClosed (isClosed);
+          }
+          aShadedGroup->SetPrimitivesAspect (aDrawer->ShadingAspect()->Aspect());
+          aShadedGroup->AddPrimitiveArray (aTriangles);
+        }
+
+        if (aDrawer->FaceBoundaryDraw())
+        {
+          Handle(Graphic3d_ArrayOfSegments) aBndSegments = StdPrs_ShadedShape::FillFaceBoundaries (aShapeDraw);
+          if (!aBndSegments.IsNull())
+          {
+            if (aShadedGroup.IsNull())
+            {
+              aShadedGroup = Prs3d_Root::NewGroup (thePrs);
+              aShadedGroup->SetClosed (isClosed);
+            }
+
+            Handle(Graphic3d_AspectLine3d) aBoundaryAspect = aDrawer->FaceBoundaryAspect()->Aspect();
+            aShadedGroup->SetPrimitivesAspect (aBoundaryAspect);
+            aShadedGroup->AddPrimitiveArray (aBndSegments);
+          }
+        }
       }
       else
       {
@@ -436,45 +512,94 @@ void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation
 //function : dispatchColors
 //purpose  :
 //=======================================================================
-Standard_Boolean AIS_ColoredShape::dispatchColors (const TopoDS_Shape&        theBaseKey,
-                                                   const TopoDS_Shape&        theSubshapeToParse,
-                                                   const DataMapOfShapeShape& theSubshapeKeyshapeMap,
-                                                   const TopAbs_ShapeEnum     theParentType,
-                                                   DataMapOfShapeCompd*       theTypeKeyshapeDrawshapeArray)
+Standard_Boolean AIS_ColoredShape::dispatchColors (const Handle(AIS_ColoredDrawer)& theParentDrawer,
+                                                   const TopoDS_Shape& theShapeToParse,
+                                                   const AIS_DataMapOfShapeDrawer& theShapeDrawerMap,
+                                                   const TopAbs_ShapeEnum theParentType,
+                                                   const Standard_Boolean theIsParentClosed,
+                                                   DataMapOfDrawerCompd* theDrawerOpenedShapePerType,
+                                                   DataMapOfDrawerCompd& theDrawerClosedFaces)
 {
-  TopAbs_ShapeEnum aShType = theSubshapeToParse.ShapeType();
-  if (aShType == TopAbs_SHAPE)
+  const TopAbs_ShapeEnum aShapeType = theShapeToParse.ShapeType();
+  if (aShapeType == TopAbs_SHAPE)
   {
     return Standard_False;
   }
 
   // check own setting of current shape
-  TopoDS_Shape     aKeyShape   = theBaseKey;
-  Standard_Boolean isOverriden = theSubshapeKeyshapeMap.Find (theSubshapeToParse, aKeyShape);
+  Handle(AIS_ColoredDrawer) aDrawer = theParentDrawer;
+  const Standard_Boolean isOverriden = theShapeDrawerMap.Find (theShapeToParse, aDrawer);
+  if (isOverriden
+   && aDrawer->IsHidden())
+  {
+    return Standard_True;
+  }
+
+  // handle compounds, solids and shells
+  Standard_Boolean isSubOverride = Standard_False;
+  if (aShapeType <= TopAbs_SHELL)
+  {
+    // detect parts of closed solids
+    Standard_Boolean isClosedShell = theParentType == TopAbs_SOLID
+                                  && aShapeType == TopAbs_SHELL
+                                  && BRep_Tool::IsClosed (theShapeToParse)
+                                  && StdPrs_ToolTriangulatedShape::IsTriangulated (theShapeToParse);
+    if (isClosedShell)
+    {
+      for (TopoDS_Iterator aFaceIter (theShapeToParse); aFaceIter.More(); aFaceIter.Next())
+      {
+        const TopoDS_Shape& aFace = aFaceIter.Value();
+        Handle(AIS_ColoredDrawer) aFaceDrawer;
+        if (aFace.ShapeType() == TopAbs_FACE
+         && theShapeDrawerMap.Find (aFace, aFaceDrawer)
+         && aFaceDrawer->IsHidden())
+        {
+          isClosedShell = Standard_False;
+          break;
+        }
+      }
+    }
+
+    for (TopoDS_Iterator aSubShapeIter (theShapeToParse); aSubShapeIter.More(); aSubShapeIter.Next())
+    {
+      const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
+      if (dispatchColors (aDrawer, aSubShape,
+                          theShapeDrawerMap, aShapeType,
+                          isClosedShell,
+                          theDrawerOpenedShapePerType,
+                          theDrawerClosedFaces))
+      {
+        isSubOverride = Standard_True;
+      }
+    }
+    return isOverriden || isSubOverride;
+  }
 
   // iterate on sub-shapes
   BRep_Builder aBBuilder;
-  TopoDS_Shape aShapeCopy = theSubshapeToParse.EmptyCopied();
-  aShapeCopy.Closed (theSubshapeToParse.Closed());
-  Standard_Boolean isSubOverride = Standard_False;
+  TopoDS_Shape aShapeCopy = theShapeToParse.EmptyCopied();
+  aShapeCopy.Closed (theShapeToParse.Closed());
   Standard_Integer nbDef = 0;
-  for (TopoDS_Iterator it (theSubshapeToParse); it.More(); it.Next())
-  {
-    if (dispatchColors (theBaseKey, it.Value(),
-                        theSubshapeKeyshapeMap, aShType,
-                        theTypeKeyshapeDrawshapeArray))
+  for (TopoDS_Iterator aSubShapeIter (theShapeToParse); aSubShapeIter.More(); aSubShapeIter.Next())
+  {
+    const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
+    if (dispatchColors (aDrawer, aSubShape,
+                        theShapeDrawerMap, aShapeType,
+                        theIsParentClosed,
+                        theDrawerOpenedShapePerType,
+                        theDrawerClosedFaces))
     {
       isSubOverride = Standard_True;
     }
     else
     {
-      aBBuilder.Add (aShapeCopy, it.Value());
+      aBBuilder.Add (aShapeCopy, aSubShape);
       ++nbDef;
     }
   }
-  if (aShType == TopAbs_FACE || !isSubOverride)
+  if (aShapeType == TopAbs_FACE || !isSubOverride)
   {
-    aShapeCopy = theSubshapeToParse;
+    aShapeCopy = theShapeToParse;
   }
   else if (nbDef == 0)
   {
@@ -485,94 +610,23 @@ Standard_Boolean AIS_ColoredShape::dispatchColors (const TopoDS_Shape&        th
   if (isOverriden
   || (isSubOverride && theParentType != TopAbs_WIRE  // avoid drawing edges when vertex color is overridden
                     && theParentType != TopAbs_FACE) // avoid drawing edges of the same color as face
-  || (theParentType == TopAbs_SHAPE && !(isOverriden || isSubOverride))) // bind original shape to default color
+  || (theParentType <= TopAbs_SHELL && !(isOverriden || isSubOverride))) // bind original shape to default color
   {
     TopoDS_Compound aCompound;
-    DataMapOfShapeCompd& aKeyshapeDrawshapeMap = theTypeKeyshapeDrawshapeArray[(size_t )aShType];
-    if (!aKeyshapeDrawshapeMap.FindFromKey (aKeyShape, aCompound))
+    DataMapOfDrawerCompd& aDrawerShapeMap = theIsParentClosed
+                                         && aShapeType == TopAbs_FACE
+                                          ? theDrawerClosedFaces
+                                          : theDrawerOpenedShapePerType[(size_t)aShapeType];
+    if (!aDrawerShapeMap.FindFromKey (aDrawer, aCompound))
     {
       aBBuilder.MakeCompound (aCompound);
-      aKeyshapeDrawshapeMap.Add (aKeyShape, aCompound);
+      aDrawerShapeMap.Add (aDrawer, aCompound);
     }
     aBBuilder.Add (aCompound, aShapeCopy);
   }
   return isOverriden || isSubOverride;
 }
 
-//! Function to check if specified compound is sub-shape of another one
-inline Standard_Boolean isFirstCmpContainSecondOne (const TopoDS_Shape& theFirstCmp,
-                                                    const TopoDS_Shape& theSecondCmp)
-{
-  if (theFirstCmp.ShapeType()  != TopAbs_COMPOUND
-   || theSecondCmp.ShapeType() != TopAbs_COMPOUND)
-  {
-    return Standard_False;
-  }
-
-  for (TopoDS_Iterator aFirstCmpIter (theFirstCmp); aFirstCmpIter.More(); aFirstCmpIter.Next())
-  {
-    if (aFirstCmpIter.Value().ShapeType() != TopAbs_COMPOUND)
-    {
-      continue;
-    }
-    else if (aFirstCmpIter.Value() == theSecondCmp
-          || isFirstCmpContainSecondOne (aFirstCmpIter.Value(), theSecondCmp))
-    {
-      return Standard_True;
-    }
-  }
-  return Standard_False;
-}
-
-//=======================================================================
-//function : dispatchColors
-//purpose  :
-//=======================================================================
-void AIS_ColoredShape::dispatchColors (const TopoDS_Shape&  theBaseShape,
-                                       const AIS_DataMapOfShapeDrawer& theKeyshapeColorMap,
-                                       DataMapOfShapeCompd* theTypeKeyshapeDrawshapeArray)
-{
-  // Extract <theShapeColors> map (KeyshapeColored -> Color)
-  // to subshapes map (Subshape -> KeyshapeColored).
-  // This needed when colored shape is not part of <theBaseShape>
-  // (but subshapes are) and actually container for subshapes.
-  DataMapOfShapeShape aSubshapeKeyshapeMap;
-  for (AIS_DataMapOfShapeDrawer::Iterator aKeyShapeIter (theKeyshapeColorMap);
-       aKeyShapeIter.More(); aKeyShapeIter.Next())
-  {
-    const TopoDS_Shape& aKeyShape = aKeyShapeIter.Key();
-    bindSubShapes (aSubshapeKeyshapeMap, theBaseShape, aKeyShape, aKeyShape);
-  }
-
-  // Fill the array of maps per shape type
-  dispatchColors (theBaseShape, theBaseShape,
-                  aSubshapeKeyshapeMap, TopAbs_SHAPE,
-                  theTypeKeyshapeDrawshapeArray);
-}
-
-//=======================================================================
-//function : isShapeEntirelyVisible
-//purpose  :
-//=======================================================================
-Standard_Boolean AIS_ColoredShape::isShapeEntirelyVisible (DataMapOfShapeCompd* theDispatched) const
-{
-  Handle(AIS_ColoredDrawer) aCustomDrawer;
-  for (size_t aShType = (size_t )TopAbs_COMPOUND; aShType <= (size_t )TopAbs_FACE; ++aShType)
-  {
-    const DataMapOfShapeCompd& aKeyshapeDrawshapeMap = theDispatched[aShType];
-    for (DataMapOfShapeCompd::Iterator aMapIter (aKeyshapeDrawshapeMap); aMapIter.More(); aMapIter.Next())
-    {
-      if (myShapeColors.Find (aMapIter.Key(), aCustomDrawer)
-      && !aCustomDrawer.IsNull()
-      &&  aCustomDrawer->IsHidden())
-      {
-        return Standard_False;
-      }
-    }
-  }
-  return Standard_True;
-}
-
 //=======================================================================
 //function : isShapeEntirelyVisible
 //purpose  :
@@ -593,46 +647,32 @@ Standard_Boolean AIS_ColoredShape::isShapeEntirelyVisible() const
 //function : bindSubShapes
 //purpose  :
 //=======================================================================
-void AIS_ColoredShape::bindSubShapes (DataMapOfShapeShape& theSubshapeKeyshapeMap,
-                                      const TopoDS_Shape&  theBaseShape,
-                                      const TopoDS_Shape&  theShapeWithColor,
-                                      const TopoDS_Shape&  theColorKeyShape)
+void AIS_ColoredShape::bindSubShapes (AIS_DataMapOfShapeDrawer& theShapeDrawerMap,
+                                      const TopoDS_Shape& theKeyShape,
+                                      const Handle(AIS_ColoredDrawer)& theDrawer)
 {
-  TopAbs_ShapeEnum aShapeWithColorType = theShapeWithColor.ShapeType();
+  TopAbs_ShapeEnum aShapeWithColorType = theKeyShape.ShapeType();
   if (aShapeWithColorType == TopAbs_COMPOUND)
   {
-    if (isFirstCmpContainSecondOne (theBaseShape, theShapeWithColor))
-    {
-      if (!theSubshapeKeyshapeMap.IsBound (theShapeWithColor))
-      {
-        theSubshapeKeyshapeMap.Bind (theShapeWithColor, theColorKeyShape);
-      }
-    }
-    else
-    {
-      for (TopoDS_Iterator aSubShapeIter (theShapeWithColor); aSubShapeIter.More(); aSubShapeIter.Next())
-      {
-        bindSubShapes (theSubshapeKeyshapeMap, theBaseShape, aSubShapeIter.Value(), theColorKeyShape);
-      }
-    }
+    theShapeDrawerMap.Bind (theKeyShape, theDrawer);
   }
   else if (aShapeWithColorType == TopAbs_SOLID || aShapeWithColorType == TopAbs_SHELL)
   {
-    for (TopExp_Explorer anExp (theShapeWithColor, TopAbs_FACE); anExp.More(); anExp.Next())
+    for (TopExp_Explorer anExp (theKeyShape, TopAbs_FACE); anExp.More(); anExp.Next())
     {
-      if (!theSubshapeKeyshapeMap.IsBound (anExp.Current()))
+      if (!theShapeDrawerMap.IsBound (anExp.Current()))
       {
-        theSubshapeKeyshapeMap.Bind (anExp.Current(), theColorKeyShape);
+        theShapeDrawerMap.Bind (anExp.Current(), theDrawer);
       }
     }
   }
   else if (aShapeWithColorType == TopAbs_WIRE)
   {
-    for (TopExp_Explorer anExp (theShapeWithColor, TopAbs_EDGE); anExp.More(); anExp.Next())
+    for (TopExp_Explorer anExp (theKeyShape, TopAbs_EDGE); anExp.More(); anExp.Next())
     {
-      if (!theSubshapeKeyshapeMap.IsBound (anExp.Current()))
+      if (!theShapeDrawerMap.IsBound (anExp.Current()))
       {
-        theSubshapeKeyshapeMap.Bind (anExp.Current(), theColorKeyShape);
+        theShapeDrawerMap.Bind (anExp.Current(), theDrawer);
       }
     }
   }
@@ -643,7 +683,6 @@ void AIS_ColoredShape::bindSubShapes (DataMapOfShapeShape& theSubshapeKeyshapeMa
     // higher priority than the color of "compound" shape (wire is a
     // compound of edges, shell is a compound of faces) that contains
     // this single shape.
-    theSubshapeKeyshapeMap.Bind (theShapeWithColor, theColorKeyShape);
+    theShapeDrawerMap.Bind (theKeyShape, theDrawer);
   }
 }
-
index 4132fc8..604808b 100644 (file)
@@ -21,6 +21,8 @@
 #include <NCollection_IndexedDataMap.hxx>
 #include <StdPrs_Volume.hxx>
 #include <TopoDS_Compound.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TColStd_MapTransientHasher.hxx>
 
 //! Presentation of the shape with customizable sub-shapes properties.
 class AIS_ColoredShape : public AIS_Shape
@@ -84,57 +86,49 @@ protected: //! @name override presentation computation
 
 protected:
 
-  typedef NCollection_DataMap<TopoDS_Shape, TopoDS_Shape,           TopTools_ShapeMapHasher> DataMapOfShapeShape;
-  typedef NCollection_IndexedDataMap<TopoDS_Shape, TopoDS_Compound, TopTools_ShapeMapHasher> DataMapOfShapeCompd;
+  typedef NCollection_IndexedDataMap<Handle(AIS_ColoredDrawer), TopoDS_Compound, TColStd_MapTransientHasher> DataMapOfDrawerCompd;
 
 protected:
 
   //! Recursive function to map shapes.
-  //! @param theBaseKey                    the key to be used for undetailed shapes (default colors)
-  //! @param theSubshapeToParse            the subshape to be parsed
-  //! @param theSubshapeKeyshapeMap        shapes map Subshape (in the base shape) -> Keyshape (detailed shape)
-  //! @param theParentType                 the parent subshape type
-  //! @param theTypeKeyshapeDrawshapeArray the array of shape types to fill
-  Standard_EXPORT static Standard_Boolean dispatchColors (const TopoDS_Shape&        theBaseKey,
-                                                          const TopoDS_Shape&        theSubshapeToParse,
-                                                          const DataMapOfShapeShape& theSubshapeKeyshapeMap,
-                                                          const TopAbs_ShapeEnum     theParentType,
-                                                          DataMapOfShapeCompd*       theTypeKeyshapeDrawshapeArray);
-
-  Standard_EXPORT static void dispatchColors (const TopoDS_Shape&             theBaseShape,
-                                              const AIS_DataMapOfShapeDrawer& theKeyshapeColorMap,
-                                              DataMapOfShapeCompd*            theTypeKeyshapeDrawshapeArray);
-
+  //! @param theParentDrawer   the drawer to be used for undetailed shapes (default colors)
+  //! @param theShapeToParse   the subshape to be recursively parsed
+  //! @param theShapeDrawerMap shapes map Subshape (in the base shape) -> Drawer
+  //! @param theParentType     the parent subshape type
+  //! @param theIsParentClosed flag indicating that specified shape is part of closed Solid
+  //! @param theDrawerOpenedShapePerType the array of shape types to fill
+  //! @param theDrawerClosedFaces        the map for closed faces
+  Standard_EXPORT static Standard_Boolean dispatchColors (const Handle(AIS_ColoredDrawer)& theParentDrawer,
+                                                          const TopoDS_Shape& theShapeToParse,
+                                                          const AIS_DataMapOfShapeDrawer& theShapeDrawerMap,
+                                                          const TopAbs_ShapeEnum theParentType,
+                                                          const Standard_Boolean theIsParentClosed,
+                                                          DataMapOfDrawerCompd* theDrawerOpenedShapePerType,
+                                                          DataMapOfDrawerCompd& theDrawerClosedFaces);
 protected:
 
   //! Add shape to presentation
-  //! @param thePrs         the presentation
-  //! @param theDispatched  the shapes map with unique attributes
-  //! @param theMode        display mode
-  //! @param theVolume      how to interpret theDispatched shapes - as Closed volumes, as Open volumes
-  //!                       or to perform Autodetection
+  //! @param thePrs the presentation
+  //! @param theDrawerOpenedShapePerType the shapes map with unique attributes
+  //! @param theDrawerClosedFaces the map of attributes for closed faces
+  //! @param theMode display mode
   Standard_EXPORT void addShapesWithCustomProps (const Handle(Prs3d_Presentation)& thePrs,
-                                                 DataMapOfShapeCompd*              theDispatched,
-                                                 const Standard_Integer            theMode,
-                                                 const StdPrs_Volume               theVolume);
+                                                 const DataMapOfDrawerCompd* theDrawerOpenedShapePerType,
+                                                 const DataMapOfDrawerCompd& theDrawerClosedFaces,
+                                                 const Standard_Integer theMode);
 
   //! Check all shapes from myShapeColorsfor visibility
   Standard_EXPORT Standard_Boolean isShapeEntirelyVisible() const;
 
-  //! Check a shape with unique attributes for visibility of all 2d subshape
-  Standard_EXPORT Standard_Boolean isShapeEntirelyVisible (DataMapOfShapeCompd* theDispatched) const;
-
   //! Resolve (parse) theKeyShape into subshapes, search in they for theBaseShape,
-  //! bind all resolved subshapes with theOriginKeyShape and store all binds in theSubshapeKeyshapeMap
-  //! @param theSubshapeKeyshapeMap        shapes map: resolved and found theBaseShape subshape -> theOriginKeyShape 
-  //! @param theBaseShape                  a shape to be sought
-  //! @param theBaseKey                    a shape to be resolved (parse) into smaller (in topological sense)
-  //!                                      subshapes for new bind cycle
-  //! @param theOriginKeyShape             the key to be used for undetailed shapes (default colors)
-  Standard_EXPORT static void bindSubShapes (DataMapOfShapeShape& theSubshapeKeyshapeMap,
-                                             const TopoDS_Shape&  theBaseShape,
-                                             const TopoDS_Shape&  theKeyShape,
-                                             const TopoDS_Shape&  theOriginKeyShape);
+  //! bind all resolved subshapes with theOriginKeyShape and store all binds in theShapeDrawerMap
+  //! @param theShapeDrawerMap shapes map: resolved and found theBaseShape subshape -> theOriginKeyShape
+  //! @param theKeyShape       a shape to be resolved (parse) into smaller (in topological sense)
+  //!                          subshapes for new bind cycle
+  //! @param theDrawer         assigned drawer
+  Standard_EXPORT void bindSubShapes (AIS_DataMapOfShapeDrawer& theShapeDrawerMap,
+                                      const TopoDS_Shape& theKeyShape,
+                                      const Handle(AIS_ColoredDrawer)& theDrawer);
 
 protected:
 
index 243ee8e..e8c6810 100644 (file)
@@ -296,13 +296,10 @@ namespace
   }
 
   //! Compute boundary presentation for faces of the shape.
-  static void computeFaceBoundaries (const TopoDS_Shape&               theShape,
-                                     const Handle(Prs3d_Presentation)& thePrs,
-                                     const Handle(Prs3d_Drawer)&       theDrawer)
+  static Handle(Graphic3d_ArrayOfSegments) fillFaceBoundaries (const TopoDS_Shape& theShape)
   {
     // collection of all triangulation nodes on edges
     // for computing boundaries presentation
-    NCollection_List<Handle(TColgp_HArray1OfPnt)> aNodeCollection;
     Standard_Integer aNodeNumber = 0;
     Standard_Integer aNbPolylines = 0;
 
@@ -338,7 +335,7 @@ namespace
     }
     if (aNodeNumber == 0)
     {
-      return;
+      return Handle(Graphic3d_ArrayOfSegments)();
     }
 
     // create indexed segments array to pack polylines from different edges into single array
@@ -391,13 +388,7 @@ namespace
         }
       }
     }
-
-    // set up aspect and add polyline data
-    Handle(Graphic3d_AspectLine3d) aBoundaryAspect = theDrawer->FaceBoundaryAspect()->Aspect();
-
-    Handle(Graphic3d_Group) aPrsGrp = Prs3d_Root::CurrentGroup (thePrs);
-    aPrsGrp->SetGroupPrimitivesAspect (aBoundaryAspect);
-    aPrsGrp->AddPrimitiveArray (aSegments);
+    return aSegments;
   }
 
 } // anonymous namespace
@@ -546,6 +537,57 @@ void StdPrs_ShadedShape::Add (const Handle (Prs3d_Presentation)& thePrs,
 
   if (theDrawer->FaceBoundaryDraw())
   {
-    computeFaceBoundaries (theShape, thePrs, theDrawer);
+    Handle(Graphic3d_ArrayOfSegments) aBndSegments = fillFaceBoundaries (theShape);
+    if (!aBndSegments.IsNull())
+    {
+      Handle(Graphic3d_AspectLine3d) aBoundaryAspect = theDrawer->FaceBoundaryAspect()->Aspect();
+      Handle(Graphic3d_Group) aPrsGrp = Prs3d_Root::CurrentGroup (thePrs);
+      aPrsGrp->SetGroupPrimitivesAspect (aBoundaryAspect);
+      aPrsGrp->AddPrimitiveArray (aBndSegments);
+    }
   }
 }
+
+// =======================================================================
+// function : FillTriangles
+// purpose  :
+// =======================================================================
+Handle(Graphic3d_ArrayOfTriangles) StdPrs_ShadedShape::FillTriangles (const TopoDS_Shape&    theShape,
+                                                                      const Standard_Boolean theHasTexels,
+                                                                      const gp_Pnt2d&        theUVOrigin,
+                                                                      const gp_Pnt2d&        theUVRepeat,
+                                                                      const gp_Pnt2d&        theUVScale)
+{
+  return fillTriangles (theShape, theHasTexels, theUVOrigin, theUVRepeat, theUVScale);
+}
+
+// =======================================================================
+// function : FillFaceBoundaries
+// purpose  :
+// =======================================================================
+Handle(Graphic3d_ArrayOfSegments) StdPrs_ShadedShape::FillFaceBoundaries (const TopoDS_Shape& theShape)
+{
+  return fillFaceBoundaries (theShape);
+}
+
+// =======================================================================
+// function : AddWireframeForFreeElements
+// purpose  :
+// =======================================================================
+void StdPrs_ShadedShape::AddWireframeForFreeElements (const Handle (Prs3d_Presentation)& thePrs,
+                                                      const TopoDS_Shape&                theShape,
+                                                      const Handle (Prs3d_Drawer)&       theDrawer)
+{
+  wireframeFromShape (thePrs, theShape, theDrawer);
+}
+
+// =======================================================================
+// function : AddWireframeForFacesWithoutTriangles
+// purpose  :
+// =======================================================================
+void StdPrs_ShadedShape::AddWireframeForFacesWithoutTriangles (const Handle(Prs3d_Presentation)& thePrs,
+                                                               const TopoDS_Shape&               theShape,
+                                                               const Handle(Prs3d_Drawer)&       theDrawer)
+{
+  wireframeNoTriangFacesFromShape (thePrs, theShape, theDrawer);
+}
index 8d0ec72..cbb2a7d 100644 (file)
 #include <Prs3d_Drawer.hxx>
 #include <StdPrs_Volume.hxx>
 #include <Standard_Boolean.hxx>
+
+class Graphic3d_ArrayOfSegments;
+class Graphic3d_ArrayOfTriangles;
 class Prs3d_Presentation;
 class TopoDS_Shape;
 class gp_Pnt2d;
 class BRep_Builder;
 class TopoDS_Compound;
 
-
 //! Auxiliary procedures to prepare Shaded presentation of specified shape.
-class StdPrs_ShadedShape  : public Prs3d_Root
+class StdPrs_ShadedShape : public Prs3d_Root
 {
 public:
-
-  DEFINE_STANDARD_ALLOC
-
   
   //! Shades <theShape>.
   //! @param theVolumeType defines the way how to interpret input shapes - as Closed volumes (to activate back-face
@@ -56,27 +55,43 @@ public:
   //! into two compounds for separate processing of closed and unclosed sub-shapes
   Standard_EXPORT static void ExploreSolids (const TopoDS_Shape& theShape, const BRep_Builder& theBuilder, TopoDS_Compound& theClosed, TopoDS_Compound& theOpened, const Standard_Boolean theIgnore1DSubShape);
 
+  //! Computes wireframe presentation for free wires and vertices
+  Standard_EXPORT static void AddWireframeForFreeElements (const Handle(Prs3d_Presentation)& thePrs,
+                                                           const TopoDS_Shape&               theShape,
+                                                           const Handle(Prs3d_Drawer)&       theDrawer);
 
+  //! Computes special wireframe presentation for faces without triangulation.
+  Standard_EXPORT static void AddWireframeForFacesWithoutTriangles (const Handle(Prs3d_Presentation)& thePrs,
+                                                                    const TopoDS_Shape&               theShape,
+                                                                    const Handle(Prs3d_Drawer)&       theDrawer);
 
+public:
 
-protected:
-
-
-
-
-
-private:
-
-
-
-
+  //! Create primitive array with triangles for specified shape.
+  //! @param theShape [in] the shape with precomputed triangulation
+  static Handle(Graphic3d_ArrayOfTriangles) FillTriangles (const TopoDS_Shape& theShape)
+  {
+    gp_Pnt2d aDummy;
+    return FillTriangles (theShape, Standard_False, aDummy, aDummy, aDummy);
+  }
+
+  //! Create primitive array of triangles for specified shape.
+  //! @param theShape     the shape with precomputed triangulation
+  //! @param theHasTexels define UV coordinates in primitive array
+  //! @param theUVOrigin  origin for UV coordinates
+  //! @param theUVRepeat  repeat parameters  for UV coordinates
+  //! @param theUVScale   scale coefficients for UV coordinates
+  //! @return triangles array or NULL if specified face does not have computed triangulation
+  Standard_EXPORT static Handle(Graphic3d_ArrayOfTriangles) FillTriangles (const TopoDS_Shape&    theShape,
+                                                                           const Standard_Boolean theHasTexels,
+                                                                           const gp_Pnt2d&        theUVOrigin,
+                                                                           const gp_Pnt2d&        theUVRepeat,
+                                                                           const gp_Pnt2d&        theUVScale);
+
+  //! Define primitive array of boundary segments for specified shape.
+  //! @param theShape segments array or NULL if specified face does not have computed triangulation
+  Standard_EXPORT static Handle(Graphic3d_ArrayOfSegments) FillFaceBoundaries (const TopoDS_Shape& theShape);
 
 };
 
-
-
-
-
-
-
 #endif // _StdPrs_ShadedShape_HeaderFile
index f5ba073..a90c685 100644 (file)
@@ -85,134 +85,195 @@ static Standard_Boolean getShapesOfSHUO (TopLoc_IndexedMapOfLocation& theaPrevLo
 //purpose  : 
 //=======================================================================
 
-void XCAFPrs::CollectStyleSettings (const TDF_Label &L, 
-                                   const TopLoc_Location &loc, 
-                                   XCAFPrs_DataMapOfShapeStyle &settings)
+void XCAFPrs::CollectStyleSettings (const TDF_Label& theLabel,
+                                                           const TopLoc_Location& theLoc,
+                                                           XCAFPrs_DataMapOfShapeStyle& theSettings)
 {
-  Handle(XCAFDoc_ColorTool) CTool = XCAFDoc_DocumentTool::ColorTool( L );
-
   // for references, first collect colors of referred shape
-  TDF_Label Lref;
-  if ( XCAFDoc_ShapeTool::GetReferredShape ( L, Lref ) ) {
-    TopLoc_Location locSub = loc.Multiplied ( XCAFDoc_ShapeTool::GetLocation ( L ) );
-    CollectStyleSettings ( Lref, locSub, settings );
+  {
+    TDF_Label aLabelRef;
+    if (XCAFDoc_ShapeTool::GetReferredShape (theLabel, aLabelRef))
+    {
+      TopLoc_Location aLocSub = theLoc.Multiplied (XCAFDoc_ShapeTool::GetLocation (theLabel));
+      CollectStyleSettings (aLabelRef, aLocSub, theSettings);
+    }
   }
-  
+
   // for assemblies, first collect colors defined in components
-  TDF_LabelSequence seq;
-  if ( XCAFDoc_ShapeTool::GetComponents ( L, seq ) && seq.Length() >0 ) {
-    for ( Standard_Integer i = 1; i <= seq.Length(); i++ ) {
-      CollectStyleSettings ( seq.Value(i), loc, settings );
+  {
+    TDF_LabelSequence aComponentLabSeq;
+    if (XCAFDoc_ShapeTool::GetComponents (theLabel, aComponentLabSeq)
+    && !aComponentLabSeq.IsEmpty())
+    {
+      for (TDF_LabelSequence::Iterator aComponentIter (aComponentLabSeq); aComponentIter.More(); aComponentIter.Next())
+      {
+        const TDF_Label& aComponentLab = aComponentIter.Value();
+        CollectStyleSettings (aComponentLab, theLoc, theSettings);
+      }
     }
   }
 
-  // collect settings on subshapes and the shape itself
-  seq.Clear();
-  XCAFDoc_ShapeTool::GetSubShapes ( L, seq );
-  seq.Append ( L );
-  for ( Standard_Integer i = 1; i <= seq.Length(); i++ ) {
-    TDF_Label lab = seq.Value(i);
-    XCAFPrs_Style style;
-    Handle(XCAFDoc_LayerTool) LTool = XCAFDoc_DocumentTool::LayerTool( lab );
-    Handle(TColStd_HSequenceOfExtendedString) LayNames = new TColStd_HSequenceOfExtendedString;
-
-    LTool->GetLayers(lab, LayNames);
-    Standard_Integer InVisCount = 0;
-    for ( Standard_Integer iL = 1; iL <= LayNames->Length(); iL++) {
-      if ( !LTool->IsVisible( LTool->FindLayer(LayNames->Value(iL)) ) ) InVisCount++;
+  // collect settings on subshapes
+  Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool(theLabel);
+  TDF_LabelSequence aLabSeq;
+  XCAFDoc_ShapeTool::GetSubShapes (theLabel, aLabSeq);
+  // and add the shape itself
+  aLabSeq.Append (theLabel);
+  for (TDF_LabelSequence::Iterator aLabIter (aLabSeq); aLabIter.More(); aLabIter.Next())
+  {
+    const TDF_Label& aLabel = aLabIter.Value();
+    XCAFPrs_Style aStyle;
+
+    Standard_Boolean isVisible = aColorTool->IsVisible (aLabel);
+    if (isVisible)
+    {
+      Handle(XCAFDoc_LayerTool) aLayerTool = XCAFDoc_DocumentTool::LayerTool (aLabel);
+      Handle(TColStd_HSequenceOfExtendedString) aLayerNames = new TColStd_HSequenceOfExtendedString();
+      aLayerTool->GetLayers (aLabel, aLayerNames);
+      Standard_Integer aNbHidden = 0;
+      for (TColStd_HSequenceOfExtendedString::Iterator aLayerIter (*aLayerNames); aLayerIter.More(); aLayerIter.Next())
+      {
+        const TCollection_ExtendedString& aLayerName = aLayerIter.Value();
+        if (!aLayerTool->IsVisible (aLayerTool->FindLayer (aLayerName)))
+        {
+          ++aNbHidden;
+        }
+      }
+      isVisible = aNbHidden == 0
+               || aNbHidden != aLayerNames->Length();
     }
-    if ( (InVisCount >0 && InVisCount == LayNames->Length()) ||
-         !CTool->IsVisible(lab) ) {
-      style.SetVisibility(Standard_False);
+
+    if (!isVisible)
+    {
+      aStyle.SetVisibility (Standard_False);
     }
-    else {
-      Quantity_Color C;
-      if ( CTool->GetColor ( lab, XCAFDoc_ColorGen, C ) ) {
-       style.SetColorCurv ( C );
-       style.SetColorSurf ( C );
+    else
+    {
+      Quantity_Color aColor;
+      if (aColorTool->GetColor (aLabel, XCAFDoc_ColorGen, aColor))
+      {
+        aStyle.SetColorCurv (aColor);
+        aStyle.SetColorSurf (aColor);
+      }
+      if (aColorTool->GetColor (aLabel, XCAFDoc_ColorSurf, aColor))
+      {
+        aStyle.SetColorSurf (aColor);
+      }
+      if (aColorTool->GetColor (aLabel, XCAFDoc_ColorCurv, aColor))
+      {
+        aStyle.SetColorCurv (aColor);
       }
-      if ( CTool->GetColor ( lab, XCAFDoc_ColorSurf, C ) )
-       style.SetColorSurf ( C );
-      if ( CTool->GetColor ( lab, XCAFDoc_ColorCurv, C ) )
-       style.SetColorCurv ( C );
     }
+
     // PTV try to set color from SHUO structure
-    Handle(XCAFDoc_ShapeTool) STool = CTool->ShapeTool();
-    Handle(XCAFDoc_GraphNode) SHUO;
-    TDF_AttributeSequence theSHUOAttrs;
-    if (STool->IsComponent( lab ) ) {
-      STool->GetAllComponentSHUO( lab, theSHUOAttrs );
-      for (Standard_Integer shuoIndx = 1; shuoIndx <= theSHUOAttrs.Length(); shuoIndx++) {
-        SHUO = Handle(XCAFDoc_GraphNode)::DownCast(theSHUOAttrs.Value(shuoIndx));
-        if ( SHUO.IsNull() )
+    Handle(XCAFDoc_ShapeTool) aShapeTool = aColorTool->ShapeTool();
+    if (aShapeTool->IsComponent (aLabel))
+    {
+      TDF_AttributeSequence aShuoAttribSeq;
+      aShapeTool->GetAllComponentSHUO (aLabel, aShuoAttribSeq);
+      for (TDF_AttributeSequence::Iterator aShuoAttribIter (aShuoAttribSeq); aShuoAttribIter.More(); aShuoAttribIter.Next())
+      {
+        Handle(XCAFDoc_GraphNode) aShuoNode = Handle(XCAFDoc_GraphNode)::DownCast (aShuoAttribIter.Value());
+        if (aShuoNode.IsNull())
+        {
           continue;
-        TDF_Label aSHUOlab = SHUO->Label();
+        }
 
-        TDF_LabelSequence aLabSeq;
-        STool->GetSHUONextUsage( aSHUOlab, aLabSeq );
-        if (aLabSeq.Length() < 1 )
-          continue;
-      
-        Quantity_Color C;
-        XCAFPrs_Style SHUOstyle;
-        if (!CTool->IsVisible( aSHUOlab ) )
-          SHUOstyle.SetVisibility(Standard_False);
-        else {
-          if ( CTool->GetColor ( aSHUOlab, XCAFDoc_ColorGen, C ) ) {
-            SHUOstyle.SetColorCurv ( C );
-            SHUOstyle.SetColorSurf ( C );
+        const TDF_Label aShuolab = aShuoNode->Label();
+        {
+          TDF_LabelSequence aShuoLabSeq;
+          aShapeTool->GetSHUONextUsage (aShuolab, aShuoLabSeq);
+          if (aShuoLabSeq.IsEmpty())
+          {
+            continue;
           }
-          if ( CTool->GetColor ( aSHUOlab, XCAFDoc_ColorSurf, C ) )
-            SHUOstyle.SetColorSurf ( C );
-          if ( CTool->GetColor ( aSHUOlab, XCAFDoc_ColorCurv, C ) )
-            SHUOstyle.SetColorCurv ( C );
         }
-        if ( !SHUOstyle.IsSetColorCurv() && 
-            !SHUOstyle.IsSetColorSurf() &&
-            SHUOstyle.IsVisible() )
+
+        Quantity_Color aColor;
+        XCAFPrs_Style aShuoStyle;
+        if (!aColorTool->IsVisible (aShuolab))
+        {
+          aShuoStyle.SetVisibility (Standard_False);
+        }
+        else
+        {
+          if (aColorTool->GetColor (aShuolab, XCAFDoc_ColorGen, aColor))
+          {
+            aShuoStyle.SetColorCurv (aColor);
+            aShuoStyle.SetColorSurf (aColor);
+          }
+          if (aColorTool->GetColor (aShuolab, XCAFDoc_ColorSurf, aColor))
+          {
+            aShuoStyle.SetColorSurf (aColor);
+          }
+          if (aColorTool->GetColor (aShuolab, XCAFDoc_ColorCurv, aColor))
+          {
+            aShuoStyle.SetColorCurv (aColor);
+          }
+        }
+        if (!aShuoStyle.IsSetColorCurv()
+         && !aShuoStyle.IsSetColorSurf()
+         &&  aShuoStyle.IsVisible())
+        {
           continue;
-      
-      // set style for all component from Next Usage Occurrence.
-#ifdef OCCT_DEBUG
+        }
+
+        // set style for all component from Next Usage Occurrence.
+      #ifdef OCCT_DEBUG
         cout << "Set the style for SHUO next_usage-occurrance" << endl;
-#endif
+      #endif
         /* 
         // may be work, but static it returns excess shapes. It is more faster to use OLD version.
         // PTV 14.02.2003 NEW version using API of ShapeTool
-        TopTools_SequenceOfShape aSHUOShapeSeq;
-        STool->GetAllStyledComponents( SHUO, aSHUOShapeSeq );
-        for (Standard_Integer si= 1; si <= aSHUOShapeSeq.Length(); si++) {
-          TopoDS_Shape aSHUOSh = aSHUOShapeSeq.Value(si);
-          if (!aSHUOSh.IsNull())
-            settings.Bind ( aSHUOSh, SHUOstyle );
-        }
-        */
-        // OLD version that was written before ShapeTool API, and ti FASTER for presentation
+        TopTools_SequenceOfShape aShuoShapeSeq;
+        aShapeTool->GetAllStyledComponents (aShuoNode, aShuoShapeSeq);
+        for (TopTools_SequenceOfShape::Iterator aShuoShapeIter (aShuoShapeSeq); aShuoShapeIter.More(); aShuoShapeIter.Next())
+        {
+          const TopoDS_Shape& aShuoShape = aShuoShapeIter.Value();
+          if (!aShuoShape.IsNull())
+            theSettings.Bind (aShuoShape, aShuoStyle);
+        }*/
+        // OLD version that was written before ShapeTool API, and it FASTER for presentation
         // get TOP location of SHUO component
-        TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( lab );
+        TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation (aLabel);
         TopLoc_IndexedMapOfLocation aPrevLocMap;
-        // get previous setted location 
-        if ( !loc.IsIdentity() )
-          aPrevLocMap.Add( loc );
-      
-        aPrevLocMap.Add( compLoc );
-        TopTools_SequenceOfShape aSHUOShapeSeq;
+        // get previous set location
+        if (!theLoc.IsIdentity())
+        {
+          aPrevLocMap.Add (theLoc);
+        }
+        aPrevLocMap.Add (compLoc);
+
         // get shapes of SHUO Next_Usage components
-        getShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aSHUOShapeSeq );
-        for (Standard_Integer n = 1; n <= aSHUOShapeSeq.Length(); n++ ) {
-          TopoDS_Shape aSHUOSh = aSHUOShapeSeq.Value( n );
-          settings.Bind ( aSHUOSh, SHUOstyle );
+        TopTools_SequenceOfShape aShuoShapeSeq;
+        getShapesOfSHUO (aPrevLocMap, aShapeTool, aShuolab, aShuoShapeSeq);
+        for (TopTools_SequenceOfShape::Iterator aShuoShapeIter (aShuoShapeSeq); aShuoShapeIter.More(); aShuoShapeIter.Next())
+        {
+          const TopoDS_Shape& aShuoShape = aShuoShapeIter.Value();
+          theSettings.Bind (aShuoShape, aShuoStyle);
         }
         continue;
       }
     }
-    if ( !style.IsSetColorCurv() && 
-         !style.IsSetColorSurf() &&
-          style.IsVisible() )
+
+    if (!aStyle.IsSetColorCurv()
+     && !aStyle.IsSetColorSurf()
+     &&  aStyle.IsVisible())
+    {
       continue;
-    TopoDS_Shape sub = XCAFDoc_ShapeTool::GetShape ( lab );
-    sub.Move ( loc );
-    settings.Bind ( sub, style );
+    }
+
+    TopoDS_Shape aSubshape = XCAFDoc_ShapeTool::GetShape (aLabel);
+    if (aSubshape.ShapeType() == TopAbs_COMPOUND)
+    {
+      const TopoDS_Iterator aShapeIter (aSubshape);
+      if (!aShapeIter.More())
+      {
+        continue;
+      }
+    }
+    aSubshape.Move (theLoc);
+    theSettings.Bind (aSubshape, aStyle);
   }
 }
 
diff --git a/tests/bugs/vis/bug28036_1 b/tests/bugs/vis/bug28036_1
new file mode 100644 (file)
index 0000000..f2a610c
--- /dev/null
@@ -0,0 +1,28 @@
+puts "==========="
+puts "OCC28036"
+puts "Visualization, AIS_ColoredShape - handle correctly nested compounds within Shaded display mode"
+puts "==========="
+puts ""
+
+pload MODELING VISUALIZATION
+box b1 0 0 0 1 2 3
+box b2 0 3 0 2 1 3
+box b3 3 0 0 3 2 1
+compound b1 b2 c12
+compound c12 b3 c
+
+vclear
+vinit View1
+vaxo
+vdisplay -dispMode 1 c
+vfit
+
+vaspects c                -setColor BLUE1
+vaspects c -subshapes b1  -setColor RED
+vaspects c -subshapes c12 -setColor GREEN
+
+if { [vreadpixel 100 100 rgb name] != "RED3"   } { puts "Error: wrong subshape color" }
+if { [vreadpixel 200 100 rgb name] != "GREEN3" } { puts "Error: wrong subshape color" }
+if { [vreadpixel 200 300 rgb name] != "BLUE3"  } { puts "Error: wrong subshape color" }
+
+vdump $imagedir/${casename}.png
diff --git a/tests/bugs/vis/bug28036_2 b/tests/bugs/vis/bug28036_2
new file mode 100644 (file)
index 0000000..6f4e15a
--- /dev/null
@@ -0,0 +1,72 @@
+puts "==========="
+puts "OCC28036"
+puts "Visualization, AIS_ColoredShape - handle correctly nested compounds within Shaded display mode"
+puts "==========="
+puts ""
+
+pload MODELING VISUALIZATION
+
+clear
+box b1   0  0 0 100 200 1
+box b2 150  0 0 100  50 1
+box b3 150 50 0 100 150 1
+
+for {set i 1} {$i <= 3} {incr i} { tcopy b${i} b1_${i}; ttranslate b1_${i} 0 -300 0 }
+for {set i 1} {$i <= 3} {incr i} { tcopy b${i} b2_${i}; ttranslate b2_${i} 0    0 0 }
+for {set i 1} {$i <= 3} {incr i} { tcopy b${i} b3_${i}; ttranslate b3_${i} 0  300 0 }
+
+# make a reference scene with per-object colors
+vclear
+vinit View1
+vsetdispmode 1
+vaxo
+
+vdisplay b1_1 b1_2 b1_3
+vsetcolor b1_1 RED
+vsetcolor b1_2 GREEN
+vsetcolor b1_3 BLUE1
+
+vdisplay b2_1 b2_2 b2_3
+vsetcolor b2_1 RED
+vsetcolor b2_2 GREEN
+vsetcolor b2_3 BLUE1
+
+vdisplay b3_1 b3_2 b3_3
+vsetcolor b3_1 RED
+vsetcolor b3_2 GREEN
+vsetcolor b3_3 BLUE1
+vfit
+vdump $imagedir/${casename}_ref.png
+
+# make a scene with sub-colors and nested compounds
+for {set j 1} {$j <= 3} {incr j} { compound b${j}_2 b${j}_3  b${j}_23  }
+for {set j 1} {$j <= 3} {incr j} { compound b${j}_1 b${j}_23 b${j}_123 }
+compound b1_123 b2_123 b3_123 b123_123
+
+vclear
+vdisplay b123_123
+
+compound b1_23 b2_23 b3_23 b123_23
+vaspects b123_123 -subshapes b123_23 -setColor GREEN
+
+vaspects b123_123 -subshapes b1_123  -setColor RED
+vaspects b123_123 -subshapes b2_123  -setColor RED
+vaspects b123_123 -subshapes b3_123  -setColor RED
+
+compound b2_3 b3_3 b23_3
+vaspects b123_123 -subshapes b1_3    -setColor BLUE1
+vaspects b123_123 -subshapes b23_3   -setColor BLUE1
+
+if { [vreadpixel  50 250 rgb name] != "RED3"  } { puts "Error: wrong color" }
+if { [vreadpixel 175 175 rgb name] != "RED3"  } { puts "Error: wrong color" }
+if { [vreadpixel 300 100 rgb name] != "RED3"  } { puts "Error: wrong color" }
+
+if { [vreadpixel 100 310 rgb name] != "GREEN3"} { puts "Error: wrong color" }
+if { [vreadpixel 200 230 rgb name] != "GREEN3"} { puts "Error: wrong color" }
+if { [vreadpixel 320 170 rgb name] != "GREEN3"} { puts "Error: wrong color" }
+
+if { [vreadpixel 130 280 rgb name] != "BLUE3" } { puts "Error: wrong color" }
+if { [vreadpixel 250 200 rgb name] != "BLUE3" } { puts "Error: wrong color" }
+if { [vreadpixel 350 150 rgb name] != "BLUE3" } { puts "Error: wrong color" }
+
+vdump $imagedir/${casename}.png