0025695: Visualization, AIS_InteractiveContext - define default HilightMode
[occt.git] / src / AIS / AIS_ColoredShape.cxx
1 // Created on: 2014-04-24
2 // Created by: Kirill Gavrilov
3 // Copyright (c) 2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <AIS_ColoredShape.hxx>
17
18 #include <AIS_InteractiveContext.hxx>
19 #include <BRep_Builder.hxx>
20 #include <BRepTools.hxx>
21 #include <gp_Pnt2d.hxx>
22 #include <Graphic3d_AspectFillArea3d.hxx>
23 #include <Graphic3d_AspectLine3d.hxx>
24 #include <Graphic3d_ArrayOfTriangles.hxx>
25 #include <Graphic3d_ArrayOfSegments.hxx>
26 #include <Graphic3d_Group.hxx>
27 #include <Graphic3d_StructureManager.hxx>
28 #include <Graphic3d_Texture2Dmanual.hxx>
29 #include <Precision.hxx>
30 #include <Prs3d.hxx>
31 #include <Prs3d_LineAspect.hxx>
32 #include <Prs3d_IsoAspect.hxx>
33 #include <Prs3d_Presentation.hxx>
34 #include <Prs3d_ShadingAspect.hxx>
35 #include <Prs3d_Root.hxx>
36 #include <PrsMgr_PresentationManager3d.hxx>
37 #include <Standard_ErrorHandler.hxx>
38 #include <StdPrs_ShadedShape.hxx>
39 #include <StdPrs_ToolTriangulatedShape.hxx>
40 #include <StdPrs_WFShape.hxx>
41 #include <TopExp_Explorer.hxx>
42 #include <TopoDS.hxx>
43 #include <TopoDS_Compound.hxx>
44 #include <TopoDS_Iterator.hxx>
45
46 IMPLEMENT_STANDARD_RTTIEXT(AIS_ColoredShape,AIS_Shape)
47 IMPLEMENT_STANDARD_RTTIEXT(AIS_ColoredDrawer,Prs3d_Drawer)
48
49 namespace
50 {
51   //! Collect all sub-compounds into map.
52   static void collectSubCompounds (TopTools_MapOfShape& theMap,
53                                    const TopoDS_Shape&  theShape)
54   {
55     for (TopoDS_Iterator aChildIter (theShape); aChildIter.More(); aChildIter.Next())
56     {
57       const TopoDS_Shape& aShape = aChildIter.Value();
58       if (aShape.ShapeType() == TopAbs_COMPOUND
59        && theMap.Add (aShape))
60       {
61         collectSubCompounds (theMap, theShape);
62       }
63     }
64   }
65 }
66
67 //=======================================================================
68 //function : AIS_ColoredShape
69 //purpose  :
70 //=======================================================================
71 AIS_ColoredShape::AIS_ColoredShape (const TopoDS_Shape& theShape)
72 : AIS_Shape (theShape)
73 {
74   // disable dedicated line aspects
75   myDrawer->SetFreeBoundaryAspect  (myDrawer->LineAspect());
76   myDrawer->SetUnFreeBoundaryAspect(myDrawer->LineAspect());
77   myDrawer->SetSeenLineAspect      (myDrawer->LineAspect());
78 }
79
80 //=======================================================================
81 //function : AIS_ColoredShape
82 //purpose  :
83 //=======================================================================
84 AIS_ColoredShape::AIS_ColoredShape (const Handle(AIS_Shape)& theShape)
85 : AIS_Shape (theShape->Shape())
86 {
87   // disable dedicated line aspects
88   myDrawer->SetFreeBoundaryAspect  (myDrawer->LineAspect());
89   myDrawer->SetUnFreeBoundaryAspect(myDrawer->LineAspect());
90   myDrawer->SetSeenLineAspect      (myDrawer->LineAspect());
91   if (theShape->HasMaterial())
92   {
93     SetMaterial (theShape->Material());
94   }
95   if (theShape->HasColor())
96   {
97     SetColor (theShape->Color());
98   }
99   if (theShape->HasWidth())
100   {
101     SetWidth (theShape->Width());
102   }
103   if (theShape->IsTransparent())
104   {
105     SetTransparency (theShape->Transparency());
106   }
107 }
108
109 //=======================================================================
110 //function : CustomAspects
111 //purpose  :
112 //=======================================================================
113 Handle(AIS_ColoredDrawer) AIS_ColoredShape::CustomAspects (const TopoDS_Shape& theShape)
114 {
115   Handle(AIS_ColoredDrawer) aDrawer;
116   myShapeColors.Find (theShape, aDrawer);
117   if (aDrawer.IsNull())
118   {
119     aDrawer = new AIS_ColoredDrawer (myDrawer);
120     myShapeColors.Bind (theShape, aDrawer);
121     LoadRecomputable (AIS_WireFrame);
122     LoadRecomputable (AIS_Shaded);
123   }
124   return aDrawer;
125 }
126
127 //=======================================================================
128 //function : ClearCustomAspects
129 //purpose  :
130 //=======================================================================
131 void AIS_ColoredShape::ClearCustomAspects()
132 {
133   if (myShapeColors.IsEmpty())
134   {
135     return;
136   }
137   myShapeColors.Clear();
138   LoadRecomputable (AIS_WireFrame);
139   LoadRecomputable (AIS_Shaded);
140 }
141
142 //=======================================================================
143 //function : UnsetCustomAspects
144 //purpose  :
145 //=======================================================================
146 void AIS_ColoredShape::UnsetCustomAspects (const TopoDS_Shape&    theShape,
147                                            const Standard_Boolean theToUnregister)
148 {
149   if (!myShapeColors.IsBound (theShape))
150   {
151     return;
152   }
153
154   LoadRecomputable (AIS_WireFrame);
155   LoadRecomputable (AIS_Shaded);
156   if (theToUnregister)
157   {
158     myShapeColors.UnBind (theShape);
159     return;
160   }
161
162   myShapeColors.ChangeFind (theShape) = new AIS_ColoredDrawer (myDrawer);
163 }
164
165 //=======================================================================
166 //function : SetCustomColor
167 //purpose  :
168 //=======================================================================
169 void AIS_ColoredShape::SetCustomColor (const TopoDS_Shape&   theShape,
170                                        const Quantity_Color& theColor)
171 {
172   if (theShape.IsNull())
173   {
174     return;
175   }
176
177   const Handle(AIS_ColoredDrawer)& aDrawer = CustomAspects (theShape);
178   setColor (aDrawer, theColor);
179   aDrawer->SetOwnColor (theColor);
180   LoadRecomputable (AIS_WireFrame);
181   LoadRecomputable (AIS_Shaded);
182 }
183
184 //=======================================================================
185 //function : SetCustomWidth
186 //purpose  :
187 //=======================================================================
188 void AIS_ColoredShape::SetCustomWidth (const TopoDS_Shape& theShape,
189                                        const Standard_Real theLineWidth)
190 {
191   if (theShape.IsNull())
192   {
193     return;
194   }
195
196   const Handle(AIS_ColoredDrawer)& aDrawer = CustomAspects (theShape);
197   setWidth (CustomAspects (theShape), theLineWidth);
198   aDrawer->SetOwnWidth (theLineWidth);
199   LoadRecomputable (AIS_WireFrame);
200   LoadRecomputable (AIS_Shaded);
201 }
202
203 //=======================================================================
204 //function : SetColor
205 //purpose  :
206 //=======================================================================
207
208 void AIS_ColoredShape::SetColor (const Quantity_Color&  theColor)
209 {
210   setColor (myDrawer, theColor);
211   myDrawer->SetColor (theColor);
212   hasOwnColor = Standard_True;
213   LoadRecomputable (AIS_WireFrame);
214   LoadRecomputable (AIS_Shaded);
215   for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
216   {
217     const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
218     if (aDrawer->HasOwnColor())
219     {
220       continue;
221     }
222
223     if (aDrawer->HasOwnShadingAspect())
224     {
225       aDrawer->ShadingAspect()->SetColor (theColor, myCurrentFacingModel);
226     }
227     if (aDrawer->HasOwnLineAspect())
228     {
229       aDrawer->LineAspect()->SetColor (theColor);
230     }
231     if (aDrawer->HasOwnWireAspect())
232     {
233       aDrawer->WireAspect()->SetColor (theColor);
234     }
235   }
236 }
237
238 //=======================================================================
239 //function : SetWidth
240 //purpose  :
241 //=======================================================================
242
243 void AIS_ColoredShape::SetWidth (const Standard_Real    theLineWidth)
244 {
245   setWidth (myDrawer, theLineWidth);
246   myOwnWidth = theLineWidth;
247   LoadRecomputable (AIS_WireFrame);
248   LoadRecomputable (AIS_Shaded);
249   for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
250   {
251     const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
252     if (aDrawer->HasOwnWidth())
253     {
254       continue;
255     }
256
257     if (aDrawer->HasOwnLineAspect())
258     {
259       aDrawer->LineAspect()->SetWidth (theLineWidth);
260     }
261     if (aDrawer->HasOwnWireAspect())
262     {
263       aDrawer->WireAspect()->SetWidth (theLineWidth);
264     }
265   }
266 }
267
268 //=======================================================================
269 //function : SetTransparency
270 //purpose  :
271 //=======================================================================
272
273 void AIS_ColoredShape::SetTransparency (const Standard_Real theValue)
274 {
275   setTransparency (myDrawer, theValue);
276   myDrawer->SetTransparency ((Standard_ShortReal )theValue);
277   LoadRecomputable (AIS_WireFrame);
278   LoadRecomputable (AIS_Shaded);
279   for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
280   {
281     const Handle(Prs3d_Drawer)& aDrawer = anIter.Value();
282     if (aDrawer->HasOwnShadingAspect())
283     {
284       aDrawer->ShadingAspect()->SetTransparency (theValue, myCurrentFacingModel);
285     }
286   }
287 }
288
289 //=======================================================================
290 //function : SetMaterial
291 //purpose  :
292 //=======================================================================
293
294 void AIS_ColoredShape::SetMaterial (const Graphic3d_MaterialAspect& theMaterial)
295 {
296   setMaterial (myDrawer, theMaterial, HasColor(), IsTransparent());
297   //myOwnMaterial = theMaterial;
298   hasOwnMaterial = Standard_True;
299   LoadRecomputable (AIS_Shaded);
300   for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
301   {
302     const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
303     //if (aDrawer->HasOwnMaterial()) continue;
304     if (aDrawer->HasOwnShadingAspect())
305     {
306       setMaterial (aDrawer, theMaterial, aDrawer->HasOwnColor(), Standard_False); // aDrawer->IsTransparent()
307     }
308   }
309 }
310
311 //=======================================================================
312 //function : Compute
313 //purpose  :
314 //=======================================================================
315 void AIS_ColoredShape::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
316                                 const Handle(Prs3d_Presentation)&           thePrs,
317                                 const Standard_Integer                      theMode)
318 {
319   if (myshape.IsNull())
320   {
321     return;
322   }
323
324   if (IsInfinite())
325   {
326     thePrs->SetInfiniteState (Standard_True);
327   }
328
329   if (theMode == AIS_Shaded)
330   {
331     if (myDrawer->IsAutoTriangulation())
332     {
333       // compute mesh for entire shape beforehand to ensure consistency and optimizations (parallelization)
334       StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (myshape, myDrawer, Standard_True);
335
336       // After this call if type of deflection is relative
337       // computed deflection coefficient is stored as absolute.
338       Standard_Boolean wasRecomputed = StdPrs_ToolTriangulatedShape::Tessellate (myshape, myDrawer);
339
340       // Set to update wireframe presentation on triangulation.
341       if (myDrawer->IsoOnTriangulation() && wasRecomputed)
342       {
343         SetToUpdate (AIS_WireFrame);
344       }
345     }
346   }
347   else // WireFrame mode
348   {
349     StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (myshape, myDrawer, Standard_True);
350
351     // After this call if type of deflection is relative
352     // computed deflection coefficient is stored as absolute.
353     Prs3d::GetDeflection (myshape, myDrawer);
354   }
355
356   // Extract myShapeColors map (KeyshapeColored -> Color)
357   // to subshapes map (Subshape -> Color).
358   // This needed when colored shape is not part of BaseShape
359   // (but subshapes are) and actually container for subshapes.
360   AIS_DataMapOfShapeDrawer aSubshapeDrawerMap;
361   {
362     // unroll compounds specified for grouping sub-shapes with the same style
363     // (e.g. the compounds that are not a part of the main shape)
364     TopTools_MapOfShape aMapOfOwnCompounds;
365     if (myshape.ShapeType() == TopAbs_COMPOUND)
366     {
367       aMapOfOwnCompounds.Add (myshape);
368       collectSubCompounds (aMapOfOwnCompounds, myshape);
369     }
370     for (AIS_DataMapOfShapeDrawer::Iterator aKeyShapeIter (myShapeColors);
371          aKeyShapeIter.More(); aKeyShapeIter.Next())
372     {
373       const TopoDS_Shape& aKeyShape = aKeyShapeIter.Key();
374       if (aKeyShape.ShapeType() != TopAbs_COMPOUND
375        || aMapOfOwnCompounds.Contains (aKeyShape))
376       {
377         continue;
378       }
379
380       for (TopoDS_Iterator aChildIter (aKeyShape); aChildIter.More(); aChildIter.Next())
381       {
382         const TopoDS_Shape& aShape = aChildIter.Value();
383         if (!myShapeColors.IsBound (aShape))
384         {
385           bindSubShapes (aSubshapeDrawerMap, aShape, aKeyShapeIter.Value());
386         }
387       }
388     }
389
390     // assign other sub-shapes with styles
391     for (AIS_DataMapOfShapeDrawer::Iterator aKeyShapeIter (myShapeColors);
392          aKeyShapeIter.More(); aKeyShapeIter.Next())
393     {
394       const TopoDS_Shape& aKeyShape = aKeyShapeIter.Key();
395       if (myshape == aKeyShape
396       || (aKeyShape.ShapeType() == TopAbs_COMPOUND
397       && !aMapOfOwnCompounds.Contains (aKeyShape)))
398       {
399         continue;
400       }
401
402       bindSubShapes (aSubshapeDrawerMap, aKeyShape, aKeyShapeIter.Value());
403     }
404   }
405
406   Handle(AIS_ColoredDrawer) aBaseDrawer;
407   myShapeColors.Find (myshape, aBaseDrawer);
408
409   // myShapeColors + anOpened --> array[TopAbs_ShapeEnum] of map of color-to-compound
410   DataMapOfDrawerCompd aDispatchedOpened[(size_t)TopAbs_SHAPE];
411   DataMapOfDrawerCompd aDispatchedClosed;
412   dispatchColors (aBaseDrawer, myshape,
413                   aSubshapeDrawerMap, TopAbs_COMPOUND, Standard_False,
414                   aDispatchedOpened, theMode == AIS_Shaded ? aDispatchedClosed : aDispatchedOpened[TopAbs_FACE]);
415   addShapesWithCustomProps (thePrs, aDispatchedOpened, aDispatchedClosed, theMode);
416 }
417
418 //=======================================================================
419 //function : addShapesWithCustomProps
420 //purpose  :
421 //=======================================================================
422 void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation)& thePrs,
423                                                  const DataMapOfDrawerCompd* theDrawerOpenedShapePerType,
424                                                  const DataMapOfDrawerCompd& theDrawerClosedFaces,
425                                                  const Standard_Integer theMode)
426 {
427   Handle(Graphic3d_Group) anOpenGroup, aClosedGroup;
428   for (size_t aShType = 0; aShType <= (size_t )TopAbs_SHAPE; ++aShType)
429   {
430     const Standard_Boolean isClosed = aShType == TopAbs_SHAPE;
431     Handle(Graphic3d_Group)& aShadedGroup = isClosed ? aClosedGroup : anOpenGroup;
432     const DataMapOfDrawerCompd& aDrawerShapeMap = isClosed
433                                                 ? theDrawerClosedFaces
434                                                 : theDrawerOpenedShapePerType[aShType];
435     for (DataMapOfDrawerCompd::Iterator aMapIter (aDrawerShapeMap);
436          aMapIter.More(); aMapIter.Next())
437     {
438       const Handle(AIS_ColoredDrawer)& aCustomDrawer = aMapIter.Key();
439       const TopoDS_Compound& aShapeDraw = aMapIter.Value(); // compound of subshapes with <aShType> type
440       Handle(Prs3d_Drawer) aDrawer;
441       if (!aCustomDrawer.IsNull())
442       {
443         aDrawer = aCustomDrawer;
444         if (aCustomDrawer->IsHidden())
445         {
446           continue;
447         }
448       }
449       else
450       {
451         aDrawer = myDrawer;
452       }
453
454       // It is supposed that absolute deflection contains previously computed relative deflection
455       // (if deflection type is relative).
456       // In case of CustomDrawer it is taken from Link().
457       Aspect_TypeOfDeflection aPrevType = aDrawer->TypeOfDeflection();
458       aDrawer->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
459
460       // Draw each kind of subshapes and personal-colored shapes in a separate group
461       // since it's necessary to set transparency/material for all subshapes
462       // without affecting their unique colors
463       if (theMode == AIS_Shaded
464        && aShapeDraw.ShapeType() <= TopAbs_FACE
465        && !IsInfinite())
466       {
467         // add wireframe presentation for isolated edges and vertices
468         StdPrs_ShadedShape::AddWireframeForFreeElements (thePrs, aShapeDraw, aDrawer);
469
470         // add special wireframe presentation for faces without triangulation
471         StdPrs_ShadedShape::AddWireframeForFacesWithoutTriangles (thePrs, aShapeDraw, aDrawer);
472
473         Handle(Graphic3d_ArrayOfTriangles) aTriangles = StdPrs_ShadedShape::FillTriangles (aShapeDraw);
474         if (!aTriangles.IsNull())
475         {
476           if (aShadedGroup.IsNull())
477           {
478             aShadedGroup = Prs3d_Root::NewGroup (thePrs);
479             aShadedGroup->SetClosed (isClosed);
480           }
481           aShadedGroup->SetPrimitivesAspect (aDrawer->ShadingAspect()->Aspect());
482           aShadedGroup->AddPrimitiveArray (aTriangles);
483         }
484
485         if (aDrawer->FaceBoundaryDraw())
486         {
487           Handle(Graphic3d_ArrayOfSegments) aBndSegments = StdPrs_ShadedShape::FillFaceBoundaries (aShapeDraw);
488           if (!aBndSegments.IsNull())
489           {
490             if (aShadedGroup.IsNull())
491             {
492               aShadedGroup = Prs3d_Root::NewGroup (thePrs);
493               aShadedGroup->SetClosed (isClosed);
494             }
495
496             Handle(Graphic3d_AspectLine3d) aBoundaryAspect = aDrawer->FaceBoundaryAspect()->Aspect();
497             aShadedGroup->SetPrimitivesAspect (aBoundaryAspect);
498             aShadedGroup->AddPrimitiveArray (aBndSegments);
499           }
500         }
501       }
502       else
503       {
504         StdPrs_WFShape::Add (thePrs, aShapeDraw, aDrawer);
505       }
506       aDrawer->SetTypeOfDeflection (aPrevType);
507     }
508   }
509 }
510
511 //=======================================================================
512 //function : dispatchColors
513 //purpose  :
514 //=======================================================================
515 Standard_Boolean AIS_ColoredShape::dispatchColors (const Handle(AIS_ColoredDrawer)& theParentDrawer,
516                                                    const TopoDS_Shape& theShapeToParse,
517                                                    const AIS_DataMapOfShapeDrawer& theShapeDrawerMap,
518                                                    const TopAbs_ShapeEnum theParentType,
519                                                    const Standard_Boolean theIsParentClosed,
520                                                    DataMapOfDrawerCompd* theDrawerOpenedShapePerType,
521                                                    DataMapOfDrawerCompd& theDrawerClosedFaces)
522 {
523   const TopAbs_ShapeEnum aShapeType = theShapeToParse.ShapeType();
524   if (aShapeType == TopAbs_SHAPE)
525   {
526     return Standard_False;
527   }
528
529   // check own setting of current shape
530   Handle(AIS_ColoredDrawer) aDrawer = theParentDrawer;
531   const Standard_Boolean isOverriden = theShapeDrawerMap.Find (theShapeToParse, aDrawer);
532   if (isOverriden
533    && aDrawer->IsHidden())
534   {
535     return Standard_True;
536   }
537
538   // handle compounds, solids and shells
539   Standard_Boolean isSubOverride = Standard_False;
540   if (aShapeType <= TopAbs_SHELL)
541   {
542     // detect parts of closed solids
543     Standard_Boolean isClosedShell = theParentType == TopAbs_SOLID
544                                   && aShapeType == TopAbs_SHELL
545                                   && BRep_Tool::IsClosed (theShapeToParse)
546                                   && StdPrs_ToolTriangulatedShape::IsTriangulated (theShapeToParse);
547     if (isClosedShell)
548     {
549       for (TopoDS_Iterator aFaceIter (theShapeToParse); aFaceIter.More(); aFaceIter.Next())
550       {
551         const TopoDS_Shape& aFace = aFaceIter.Value();
552         Handle(AIS_ColoredDrawer) aFaceDrawer;
553         if (aFace.ShapeType() == TopAbs_FACE
554          && theShapeDrawerMap.Find (aFace, aFaceDrawer)
555          && aFaceDrawer->IsHidden())
556         {
557           isClosedShell = Standard_False;
558           break;
559         }
560       }
561     }
562
563     for (TopoDS_Iterator aSubShapeIter (theShapeToParse); aSubShapeIter.More(); aSubShapeIter.Next())
564     {
565       const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
566       if (dispatchColors (aDrawer, aSubShape,
567                           theShapeDrawerMap, aShapeType,
568                           isClosedShell,
569                           theDrawerOpenedShapePerType,
570                           theDrawerClosedFaces))
571       {
572         isSubOverride = Standard_True;
573       }
574     }
575     return isOverriden || isSubOverride;
576   }
577
578   // iterate on sub-shapes
579   BRep_Builder aBBuilder;
580   TopoDS_Shape aShapeCopy = theShapeToParse.EmptyCopied();
581   aShapeCopy.Closed (theShapeToParse.Closed());
582   Standard_Integer nbDef = 0;
583   for (TopoDS_Iterator aSubShapeIter (theShapeToParse); aSubShapeIter.More(); aSubShapeIter.Next())
584   {
585     const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
586     if (dispatchColors (aDrawer, aSubShape,
587                         theShapeDrawerMap, aShapeType,
588                         theIsParentClosed,
589                         theDrawerOpenedShapePerType,
590                         theDrawerClosedFaces))
591     {
592       isSubOverride = Standard_True;
593     }
594     else
595     {
596       aBBuilder.Add (aShapeCopy, aSubShape);
597       ++nbDef;
598     }
599   }
600   if (aShapeType == TopAbs_FACE || !isSubOverride)
601   {
602     aShapeCopy = theShapeToParse;
603   }
604   else if (nbDef == 0)
605   {
606     return isOverriden || isSubOverride; // empty compound
607   }
608
609   // if any of styles is overridden regarding to default one, add rest to map
610   if (isOverriden
611   || (isSubOverride && theParentType != TopAbs_WIRE  // avoid drawing edges when vertex color is overridden
612                     && theParentType != TopAbs_FACE) // avoid drawing edges of the same color as face
613   || (theParentType <= TopAbs_SHELL && !(isOverriden || isSubOverride))) // bind original shape to default color
614   {
615     TopoDS_Compound aCompound;
616     DataMapOfDrawerCompd& aDrawerShapeMap = theIsParentClosed
617                                          && aShapeType == TopAbs_FACE
618                                           ? theDrawerClosedFaces
619                                           : theDrawerOpenedShapePerType[(size_t)aShapeType];
620     if (!aDrawerShapeMap.FindFromKey (aDrawer, aCompound))
621     {
622       aBBuilder.MakeCompound (aCompound);
623       aDrawerShapeMap.Add (aDrawer, aCompound);
624     }
625     aBBuilder.Add (aCompound, aShapeCopy);
626   }
627   return isOverriden || isSubOverride;
628 }
629
630 //=======================================================================
631 //function : isShapeEntirelyVisible
632 //purpose  :
633 //=======================================================================
634 Standard_Boolean AIS_ColoredShape::isShapeEntirelyVisible() const
635 {
636   for (AIS_DataMapOfShapeDrawer::Iterator aMapIter (myShapeColors); aMapIter.More(); aMapIter.Next())
637   {
638     if (aMapIter.Value()->IsHidden())
639     {
640       return Standard_False;
641     }
642   }
643   return Standard_True;
644 }
645
646 //=======================================================================
647 //function : bindSubShapes
648 //purpose  :
649 //=======================================================================
650 void AIS_ColoredShape::bindSubShapes (AIS_DataMapOfShapeDrawer& theShapeDrawerMap,
651                                       const TopoDS_Shape& theKeyShape,
652                                       const Handle(AIS_ColoredDrawer)& theDrawer)
653 {
654   TopAbs_ShapeEnum aShapeWithColorType = theKeyShape.ShapeType();
655   if (aShapeWithColorType == TopAbs_COMPOUND)
656   {
657     theShapeDrawerMap.Bind (theKeyShape, theDrawer);
658   }
659   else if (aShapeWithColorType == TopAbs_SOLID || aShapeWithColorType == TopAbs_SHELL)
660   {
661     for (TopExp_Explorer anExp (theKeyShape, TopAbs_FACE); anExp.More(); anExp.Next())
662     {
663       if (!theShapeDrawerMap.IsBound (anExp.Current()))
664       {
665         theShapeDrawerMap.Bind (anExp.Current(), theDrawer);
666       }
667     }
668   }
669   else if (aShapeWithColorType == TopAbs_WIRE)
670   {
671     for (TopExp_Explorer anExp (theKeyShape, TopAbs_EDGE); anExp.More(); anExp.Next())
672     {
673       if (!theShapeDrawerMap.IsBound (anExp.Current()))
674       {
675         theShapeDrawerMap.Bind (anExp.Current(), theDrawer);
676       }
677     }
678   }
679   else
680   {
681     // bind single face, edge and vertex
682     // force rebind if required due to the color of single shape has
683     // higher priority than the color of "compound" shape (wire is a
684     // compound of edges, shell is a compound of faces) that contains
685     // this single shape.
686     theShapeDrawerMap.Bind (theKeyShape, theDrawer);
687   }
688 }