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