0028621: Visualization - AIS_ColoredShape::UnsetTransparency() is not implemented
[occt.git] / src / AIS / AIS_ColoredShape.cxx
index d6ea641..223864d 100644 (file)
 #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 <Precision.hxx>
+#include <Prs3d.hxx>
 #include <Prs3d_LineAspect.hxx>
 #include <Prs3d_IsoAspect.hxx>
 #include <Prs3d_Presentation.hxx>
 #include <PrsMgr_PresentationManager3d.hxx>
 #include <Standard_ErrorHandler.hxx>
 #include <StdPrs_ShadedShape.hxx>
-#include <StdPrs_ToolShadedShape.hxx>
-#include <StdPrs_WFDeflectionShape.hxx>
+#include <StdPrs_ToolTriangulatedShape.hxx>
 #include <StdPrs_WFShape.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Compound.hxx>
 #include <TopoDS_Iterator.hxx>
 
-IMPLEMENT_STANDARD_HANDLE (AIS_ColoredDrawer, AIS_Drawer)
-IMPLEMENT_STANDARD_RTTIEXT(AIS_ColoredDrawer, AIS_Drawer)
+IMPLEMENT_STANDARD_RTTIEXT(AIS_ColoredShape,AIS_Shape)
+IMPLEMENT_STANDARD_RTTIEXT(AIS_ColoredDrawer,Prs3d_Drawer)
 
-IMPLEMENT_STANDARD_HANDLE (AIS_ColoredShape, AIS_Shape)
-IMPLEMENT_STANDARD_RTTIEXT(AIS_ColoredShape, AIS_Shape)
+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, aShape);
+      }
+    }
+  }
+}
 
 //=======================================================================
 //function : AIS_ColoredShape
@@ -191,11 +208,11 @@ void AIS_ColoredShape::SetCustomWidth (const TopoDS_Shape& theShape,
 void AIS_ColoredShape::SetColor (const Quantity_Color&  theColor)
 {
   setColor (myDrawer, theColor);
-  myOwnColor  = theColor;
+  myDrawer->SetColor (theColor);
   hasOwnColor = Standard_True;
   LoadRecomputable (AIS_WireFrame);
   LoadRecomputable (AIS_Shaded);
-  for (DataMapOfShapeColor::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
+  for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
   {
     const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
     if (aDrawer->HasOwnColor())
@@ -203,15 +220,15 @@ void AIS_ColoredShape::SetColor (const Quantity_Color&  theColor)
       continue;
     }
 
-    if (aDrawer->HasShadingAspect())
+    if (aDrawer->HasOwnShadingAspect())
     {
       aDrawer->ShadingAspect()->SetColor (theColor, myCurrentFacingModel);
     }
-    if (aDrawer->HasLineAspect())
+    if (aDrawer->HasOwnLineAspect())
     {
       aDrawer->LineAspect()->SetColor (theColor);
     }
-    if (aDrawer->HasWireAspect())
+    if (aDrawer->HasOwnWireAspect())
     {
       aDrawer->WireAspect()->SetColor (theColor);
     }
@@ -229,7 +246,7 @@ void AIS_ColoredShape::SetWidth (const Standard_Real    theLineWidth)
   myOwnWidth = theLineWidth;
   LoadRecomputable (AIS_WireFrame);
   LoadRecomputable (AIS_Shaded);
-  for (DataMapOfShapeColor::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
+  for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
   {
     const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
     if (aDrawer->HasOwnWidth())
@@ -237,11 +254,11 @@ void AIS_ColoredShape::SetWidth (const Standard_Real    theLineWidth)
       continue;
     }
 
-    if (aDrawer->HasLineAspect())
+    if (aDrawer->HasOwnLineAspect())
     {
       aDrawer->LineAspect()->SetWidth (theLineWidth);
     }
-    if (aDrawer->HasWireAspect())
+    if (aDrawer->HasOwnWireAspect())
     {
       aDrawer->WireAspect()->SetWidth (theLineWidth);
     }
@@ -256,19 +273,46 @@ void AIS_ColoredShape::SetWidth (const Standard_Real    theLineWidth)
 void AIS_ColoredShape::SetTransparency (const Standard_Real theValue)
 {
   setTransparency (myDrawer, theValue);
-  myTransparency = theValue;
+  myDrawer->SetTransparency ((Standard_ShortReal )theValue);
   LoadRecomputable (AIS_WireFrame);
   LoadRecomputable (AIS_Shaded);
-  for (DataMapOfShapeColor::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
+  for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
   {
-    const Handle(AIS_Drawer)& aDrawer = anIter.Value();
-    if (aDrawer->HasShadingAspect())
+    const Handle(Prs3d_Drawer)& aDrawer = anIter.Value();
+    if (aDrawer->HasOwnShadingAspect())
     {
       aDrawer->ShadingAspect()->SetTransparency (theValue, myCurrentFacingModel);
     }
   }
 }
 
+//=======================================================================
+//function : UnsetTransparency
+//purpose  :
+//=======================================================================
+void AIS_ColoredShape::UnsetTransparency()
+{
+  myDrawer->SetTransparency (0.0f);
+  if (myDrawer->HasOwnShadingAspect())
+  {
+    myDrawer->ShadingAspect()->SetTransparency (0.0, myCurrentFacingModel);
+  }
+  if (!HasColor() && !HasMaterial())
+  {
+    myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
+  }
+
+  for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
+  {
+    const Handle(Prs3d_Drawer)& aDrawer = anIter.Value();
+    if (aDrawer->HasOwnShadingAspect())
+    {
+      aDrawer->ShadingAspect()->SetTransparency (0.0, myCurrentFacingModel);
+    }
+  }
+  SynchronizeAspects();
+}
+
 //=======================================================================
 //function : SetMaterial
 //purpose  :
@@ -280,11 +324,11 @@ void AIS_ColoredShape::SetMaterial (const Graphic3d_MaterialAspect& theMaterial)
   //myOwnMaterial = theMaterial;
   hasOwnMaterial = Standard_True;
   LoadRecomputable (AIS_Shaded);
-  for (DataMapOfShapeColor::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
+  for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
   {
     const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
     //if (aDrawer->HasOwnMaterial()) continue;
-    if (aDrawer->HasShadingAspect())
+    if (aDrawer->HasOwnShadingAspect())
     {
       setMaterial (aDrawer, theMaterial, aDrawer->HasOwnColor(), Standard_False); // aDrawer->IsTransparent()
     }
@@ -299,43 +343,129 @@ void AIS_ColoredShape::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
                                 const Handle(Prs3d_Presentation)&           thePrs,
                                 const Standard_Integer                      theMode)
 {
-  thePrs->Clear();
+  if (myshape.IsNull())
+  {
+    return;
+  }
+
   if (IsInfinite())
   {
     thePrs->SetInfiniteState (Standard_True);
   }
 
-  const Standard_Boolean isClosed = StdPrs_ToolShadedShape::IsClosed (myshape);
   if (theMode == AIS_Shaded)
   {
-    // compute mesh for entire shape beforehand to ensure consistency and optimizations (parallelization)
-    Standard_Real anAnglePrev, anAngleNew, aCoeffPrev, aCoeffNew;
-    Standard_Boolean isOwnDeviationAngle       = OwnDeviationAngle      (anAngleNew, anAnglePrev);
-    Standard_Boolean isOwnDeviationCoefficient = OwnDeviationCoefficient(aCoeffNew,  aCoeffPrev);
-    if ((isOwnDeviationAngle       && Abs (anAngleNew - anAnglePrev) > Precision::Angular())
-     || (isOwnDeviationCoefficient && Abs (aCoeffNew  - aCoeffPrev)  > Precision::Confusion()))
+    if (myDrawer->IsAutoTriangulation())
     {
-      BRepTools::Clean (myshape);
+      // compute mesh for entire shape beforehand to ensure consistency and optimizations (parallelization)
+      StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (myshape, myDrawer, Standard_True);
+
+      // After this call if type of deflection is relative
+      // computed deflection coefficient is stored as absolute.
+      Standard_Boolean wasRecomputed = StdPrs_ToolTriangulatedShape::Tessellate (myshape, myDrawer);
+
+      // Set to update wireframe presentation on triangulation.
+      if (myDrawer->IsoOnTriangulation() && wasRecomputed)
+      {
+        SetToUpdate (AIS_WireFrame);
+      }
     }
-    StdPrs_ShadedShape::Tessellate (myshape, myDrawer);
   }
+  else // WireFrame mode
+  {
+    StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (myshape, myDrawer, Standard_True);
 
-  // 1) myShapeColors + myshape --> array[TopAbs_ShapeEnum] of map of color-to-compound
-  DataMapOfShapeCompd aTypeKeyshapeDrawshapeArray[(size_t )TopAbs_SHAPE];
-  dispatchColors (myshape, myShapeColors, aTypeKeyshapeDrawshapeArray);
+    // After this call if type of deflection is relative
+    // computed deflection coefficient is stored as absolute.
+    Prs3d::GetDeflection (myshape, myDrawer);
+  }
 
-  // 2) finally add appropriate presentations (1 color -- 1 compound) according to theMode
-  Handle(AIS_ColoredDrawer) aCustomDrawer;
-  for (size_t aShType = 0; aShType < (size_t )TopAbs_SHAPE; ++aShType)
+  // 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;
+  {
+    // 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)
+    {
+      aMapOfOwnCompounds.Add (myshape);
+      collectSubCompounds (aMapOfOwnCompounds, myshape);
+    }
+    for (AIS_DataMapOfShapeDrawer::Iterator aKeyShapeIter (myShapeColors);
+         aKeyShapeIter.More(); aKeyShapeIter.Next())
+    {
+      const TopoDS_Shape& aKeyShape = aKeyShapeIter.Key();
+      if (aKeyShape.ShapeType() != TopAbs_COMPOUND
+       || aMapOfOwnCompounds.Contains (aKeyShape))
+      {
+        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);
+}
+
+//=======================================================================
+//function : addShapesWithCustomProps
+//purpose  :
+//=======================================================================
+void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation)& thePrs,
+                                                 const DataMapOfDrawerCompd* theDrawerOpenedShapePerType,
+                                                 const DataMapOfDrawerCompd& theDrawerClosedFaces,
+                                                 const Standard_Integer theMode)
+{
+  Handle(Graphic3d_Group) anOpenGroup, aClosedGroup;
+  for (size_t aShType = 0; aShType <= (size_t )TopAbs_SHAPE; ++aShType)
   {
-    DataMapOfShapeCompd& aKeyshapeDrawshapeMap = aTypeKeyshapeDrawshapeArray[aShType];
-    for (DataMapOfShapeCompd::Iterator aMapIter (aKeyshapeDrawshapeMap);
+    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(AIS_Drawer)     aDrawer;
-      if (myShapeColors.Find (aShapeKey, aCustomDrawer))
+      Handle(Prs3d_Drawer) aDrawer;
+      if (!aCustomDrawer.IsNull())
       {
         aDrawer = aCustomDrawer;
         if (aCustomDrawer->IsHidden())
@@ -348,34 +478,59 @@ void AIS_ColoredShape::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
         aDrawer = myDrawer;
       }
 
+      // It is supposed that absolute deflection contains previously computed relative deflection
+      // (if deflection type is relative).
+      // In case of CustomDrawer it is taken from Link().
+      Aspect_TypeOfDeflection aPrevType = aDrawer->TypeOfDeflection();
+      aDrawer->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
+
       // Draw each kind of subshapes and personal-colored shapes in a separate group
       // since it's necessary to set transparency/material for all subshapes
       // without affecting their unique colors
-      Handle(Graphic3d_Group) aCurrGroup = Prs3d_Root::NewGroup (thePrs);
-      switch (theMode)
+      if (theMode == AIS_Shaded
+       && aShapeDraw.ShapeType() <= TopAbs_FACE
+       && !IsInfinite())
       {
-        default:
-        case AIS_Shaded:
+        // 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 ((Standard_Integer )aShapeDraw.ShapeType() <= TopAbs_FACE
-           && !IsInfinite())
+          if (aShadedGroup.IsNull())
           {
-            StdPrs_ShadedShape::Add (thePrs, aShapeDraw, aDrawer);
-
-            aDrawer->SetShadingAspectGlobal (Standard_False);
-            Handle(Graphic3d_AspectFillArea3d) anAsp = aDrawer->ShadingAspect()->Aspect();
-            isClosed ? anAsp->SuppressBackFace() : anAsp->AllowBackFace();
-            aCurrGroup->SetGroupPrimitivesAspect (anAsp);
-            break;
+            aShadedGroup = Prs3d_Root::NewGroup (thePrs);
+            aShadedGroup->SetClosed (isClosed);
           }
-          // compute wire-frame otherwise
+          aShadedGroup->SetPrimitivesAspect (aDrawer->ShadingAspect()->Aspect());
+          aShadedGroup->AddPrimitiveArray (aTriangles);
         }
-        case AIS_WireFrame:
+
+        if (aDrawer->FaceBoundaryDraw())
         {
-          StdPrs_WFDeflectionShape::Add (thePrs, aShapeDraw, aDrawer);
-          break;
+          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
+      {
+        StdPrs_WFShape::Add (thePrs, aShapeDraw, aDrawer);
+      }
+      aDrawer->SetTypeOfDeflection (aPrevType);
     }
   }
 }
@@ -384,45 +539,94 @@ void AIS_ColoredShape::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
 //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())
+  for (TopoDS_Iterator aSubShapeIter (theShapeToParse); aSubShapeIter.More(); aSubShapeIter.Next())
   {
-    if (dispatchColors (theBaseKey, it.Value(),
-                        theSubshapeKeyshapeMap, aShType,
-                        theTypeKeyshapeDrawshapeArray))
+    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)
   {
@@ -433,14 +637,17 @@ 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);
   }
@@ -448,48 +655,61 @@ Standard_Boolean AIS_ColoredShape::dispatchColors (const TopoDS_Shape&        th
 }
 
 //=======================================================================
-//function : dispatchColors
+//function : isShapeEntirelyVisible
 //purpose  :
 //=======================================================================
-void AIS_ColoredShape::dispatchColors (const TopoDS_Shape&        theBaseShape,
-                                       const DataMapOfShapeColor& theKeyshapeColorMap,
-                                       DataMapOfShapeCompd*       theTypeKeyshapeDrawshapeArray)
+Standard_Boolean AIS_ColoredShape::isShapeEntirelyVisible() const
 {
-  // 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 (DataMapOfShapeColor::Iterator anIt (theKeyshapeColorMap);
-       anIt.More(); anIt.Next())
-  {
-    const TopoDS_Shape&   aSh = anIt.Key();
-    TopAbs_ShapeEnum    aType = aSh.ShapeType();
-    TopAbs_ShapeEnum aSubType = (aType == TopAbs_SOLID || aType == TopAbs_SHELL)
-                              ? TopAbs_FACE
-                              : (aType == TopAbs_WIRE ? TopAbs_EDGE : TopAbs_SHAPE);
-    switch (aSubType)
+  for (AIS_DataMapOfShapeDrawer::Iterator aMapIter (myShapeColors); aMapIter.More(); aMapIter.Next())
+  {
+    if (aMapIter.Value()->IsHidden())
     {
-      case TopAbs_SHAPE:
+      return Standard_False;
+    }
+  }
+  return Standard_True;
+}
+
+//=======================================================================
+//function : bindSubShapes
+//purpose  :
+//=======================================================================
+void AIS_ColoredShape::bindSubShapes (AIS_DataMapOfShapeDrawer& theShapeDrawerMap,
+                                      const TopoDS_Shape& theKeyShape,
+                                      const Handle(AIS_ColoredDrawer)& theDrawer)
+{
+  TopAbs_ShapeEnum aShapeWithColorType = theKeyShape.ShapeType();
+  if (aShapeWithColorType == TopAbs_COMPOUND)
+  {
+    theShapeDrawerMap.Bind (theKeyShape, theDrawer);
+  }
+  else if (aShapeWithColorType == TopAbs_SOLID || aShapeWithColorType == TopAbs_SHELL)
+  {
+    for (TopExp_Explorer anExp (theKeyShape, TopAbs_FACE); anExp.More(); anExp.Next())
+    {
+      if (!theShapeDrawerMap.IsBound (anExp.Current()))
       {
-        aSubshapeKeyshapeMap.Bind (aSh, aSh);
-        break;
+        theShapeDrawerMap.Bind (anExp.Current(), theDrawer);
       }
-      default:
+    }
+  }
+  else if (aShapeWithColorType == TopAbs_WIRE)
+  {
+    for (TopExp_Explorer anExp (theKeyShape, TopAbs_EDGE); anExp.More(); anExp.Next())
+    {
+      if (!theShapeDrawerMap.IsBound (anExp.Current()))
       {
-        for (TopExp_Explorer anExp (aSh, aSubType); anExp.More(); anExp.Next())
-        {
-          if (!aSubshapeKeyshapeMap.IsBound (anExp.Current()))
-          {
-            aSubshapeKeyshapeMap.Bind (anExp.Current(), aSh);
-          }
-        }
+        theShapeDrawerMap.Bind (anExp.Current(), theDrawer);
       }
     }
   }
-
-  // Fill the array of maps per shape type
-  dispatchColors (theBaseShape, theBaseShape,
-                  aSubshapeKeyshapeMap, TopAbs_SHAPE,
-                  theTypeKeyshapeDrawshapeArray);
+  else
+  {
+    // bind single face, edge and vertex
+    // force rebind if required due to the color of single shape has
+    // 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.
+    theShapeDrawerMap.Bind (theKeyShape, theDrawer);
+  }
 }