0028621: Visualization - AIS_ColoredShape::UnsetTransparency() is not implemented
[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     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 : UnsetTransparency
291 //purpose  :
292 //=======================================================================
293 void AIS_ColoredShape::UnsetTransparency()
294 {
295   myDrawer->SetTransparency (0.0f);
296   if (myDrawer->HasOwnShadingAspect())
297   {
298     myDrawer->ShadingAspect()->SetTransparency (0.0, myCurrentFacingModel);
299   }
300   if (!HasColor() && !HasMaterial())
301   {
302     myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
303   }
304
305   for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
306   {
307     const Handle(Prs3d_Drawer)& aDrawer = anIter.Value();
308     if (aDrawer->HasOwnShadingAspect())
309     {
310       aDrawer->ShadingAspect()->SetTransparency (0.0, myCurrentFacingModel);
311     }
312   }
313   SynchronizeAspects();
314 }
315
316 //=======================================================================
317 //function : SetMaterial
318 //purpose  :
319 //=======================================================================
320
321 void AIS_ColoredShape::SetMaterial (const Graphic3d_MaterialAspect& theMaterial)
322 {
323   setMaterial (myDrawer, theMaterial, HasColor(), IsTransparent());
324   //myOwnMaterial = theMaterial;
325   hasOwnMaterial = Standard_True;
326   LoadRecomputable (AIS_Shaded);
327   for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
328   {
329     const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
330     //if (aDrawer->HasOwnMaterial()) continue;
331     if (aDrawer->HasOwnShadingAspect())
332     {
333       setMaterial (aDrawer, theMaterial, aDrawer->HasOwnColor(), Standard_False); // aDrawer->IsTransparent()
334     }
335   }
336 }
337
338 //=======================================================================
339 //function : Compute
340 //purpose  :
341 //=======================================================================
342 void AIS_ColoredShape::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
343                                 const Handle(Prs3d_Presentation)&           thePrs,
344                                 const Standard_Integer                      theMode)
345 {
346   if (myshape.IsNull())
347   {
348     return;
349   }
350
351   if (IsInfinite())
352   {
353     thePrs->SetInfiniteState (Standard_True);
354   }
355
356   if (theMode == AIS_Shaded)
357   {
358     if (myDrawer->IsAutoTriangulation())
359     {
360       // compute mesh for entire shape beforehand to ensure consistency and optimizations (parallelization)
361       StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (myshape, myDrawer, Standard_True);
362
363       // After this call if type of deflection is relative
364       // computed deflection coefficient is stored as absolute.
365       Standard_Boolean wasRecomputed = StdPrs_ToolTriangulatedShape::Tessellate (myshape, myDrawer);
366
367       // Set to update wireframe presentation on triangulation.
368       if (myDrawer->IsoOnTriangulation() && wasRecomputed)
369       {
370         SetToUpdate (AIS_WireFrame);
371       }
372     }
373   }
374   else // WireFrame mode
375   {
376     StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (myshape, myDrawer, Standard_True);
377
378     // After this call if type of deflection is relative
379     // computed deflection coefficient is stored as absolute.
380     Prs3d::GetDeflection (myshape, myDrawer);
381   }
382
383   // Extract myShapeColors map (KeyshapeColored -> Color)
384   // to subshapes map (Subshape -> Color).
385   // This needed when colored shape is not part of BaseShape
386   // (but subshapes are) and actually container for subshapes.
387   AIS_DataMapOfShapeDrawer aSubshapeDrawerMap;
388   {
389     // unroll compounds specified for grouping sub-shapes with the same style
390     // (e.g. the compounds that are not a part of the main shape)
391     TopTools_MapOfShape aMapOfOwnCompounds;
392     if (myshape.ShapeType() == TopAbs_COMPOUND)
393     {
394       aMapOfOwnCompounds.Add (myshape);
395       collectSubCompounds (aMapOfOwnCompounds, myshape);
396     }
397     for (AIS_DataMapOfShapeDrawer::Iterator aKeyShapeIter (myShapeColors);
398          aKeyShapeIter.More(); aKeyShapeIter.Next())
399     {
400       const TopoDS_Shape& aKeyShape = aKeyShapeIter.Key();
401       if (aKeyShape.ShapeType() != TopAbs_COMPOUND
402        || aMapOfOwnCompounds.Contains (aKeyShape))
403       {
404         continue;
405       }
406
407       for (TopoDS_Iterator aChildIter (aKeyShape); aChildIter.More(); aChildIter.Next())
408       {
409         const TopoDS_Shape& aShape = aChildIter.Value();
410         if (!myShapeColors.IsBound (aShape))
411         {
412           bindSubShapes (aSubshapeDrawerMap, aShape, aKeyShapeIter.Value());
413         }
414       }
415     }
416
417     // assign other sub-shapes with styles
418     for (AIS_DataMapOfShapeDrawer::Iterator aKeyShapeIter (myShapeColors);
419          aKeyShapeIter.More(); aKeyShapeIter.Next())
420     {
421       const TopoDS_Shape& aKeyShape = aKeyShapeIter.Key();
422       if (myshape == aKeyShape
423       || (aKeyShape.ShapeType() == TopAbs_COMPOUND
424       && !aMapOfOwnCompounds.Contains (aKeyShape)))
425       {
426         continue;
427       }
428
429       bindSubShapes (aSubshapeDrawerMap, aKeyShape, aKeyShapeIter.Value());
430     }
431   }
432
433   Handle(AIS_ColoredDrawer) aBaseDrawer;
434   myShapeColors.Find (myshape, aBaseDrawer);
435
436   // myShapeColors + anOpened --> array[TopAbs_ShapeEnum] of map of color-to-compound
437   DataMapOfDrawerCompd aDispatchedOpened[(size_t)TopAbs_SHAPE];
438   DataMapOfDrawerCompd aDispatchedClosed;
439   dispatchColors (aBaseDrawer, myshape,
440                   aSubshapeDrawerMap, TopAbs_COMPOUND, Standard_False,
441                   aDispatchedOpened, theMode == AIS_Shaded ? aDispatchedClosed : aDispatchedOpened[TopAbs_FACE]);
442   addShapesWithCustomProps (thePrs, aDispatchedOpened, aDispatchedClosed, theMode);
443 }
444
445 //=======================================================================
446 //function : addShapesWithCustomProps
447 //purpose  :
448 //=======================================================================
449 void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation)& thePrs,
450                                                  const DataMapOfDrawerCompd* theDrawerOpenedShapePerType,
451                                                  const DataMapOfDrawerCompd& theDrawerClosedFaces,
452                                                  const Standard_Integer theMode)
453 {
454   Handle(Graphic3d_Group) anOpenGroup, aClosedGroup;
455   for (size_t aShType = 0; aShType <= (size_t )TopAbs_SHAPE; ++aShType)
456   {
457     const Standard_Boolean isClosed = aShType == TopAbs_SHAPE;
458     Handle(Graphic3d_Group)& aShadedGroup = isClosed ? aClosedGroup : anOpenGroup;
459     const DataMapOfDrawerCompd& aDrawerShapeMap = isClosed
460                                                 ? theDrawerClosedFaces
461                                                 : theDrawerOpenedShapePerType[aShType];
462     for (DataMapOfDrawerCompd::Iterator aMapIter (aDrawerShapeMap);
463          aMapIter.More(); aMapIter.Next())
464     {
465       const Handle(AIS_ColoredDrawer)& aCustomDrawer = aMapIter.Key();
466       const TopoDS_Compound& aShapeDraw = aMapIter.Value(); // compound of subshapes with <aShType> type
467       Handle(Prs3d_Drawer) aDrawer;
468       if (!aCustomDrawer.IsNull())
469       {
470         aDrawer = aCustomDrawer;
471         if (aCustomDrawer->IsHidden())
472         {
473           continue;
474         }
475       }
476       else
477       {
478         aDrawer = myDrawer;
479       }
480
481       // It is supposed that absolute deflection contains previously computed relative deflection
482       // (if deflection type is relative).
483       // In case of CustomDrawer it is taken from Link().
484       Aspect_TypeOfDeflection aPrevType = aDrawer->TypeOfDeflection();
485       aDrawer->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
486
487       // Draw each kind of subshapes and personal-colored shapes in a separate group
488       // since it's necessary to set transparency/material for all subshapes
489       // without affecting their unique colors
490       if (theMode == AIS_Shaded
491        && aShapeDraw.ShapeType() <= TopAbs_FACE
492        && !IsInfinite())
493       {
494         // add wireframe presentation for isolated edges and vertices
495         StdPrs_ShadedShape::AddWireframeForFreeElements (thePrs, aShapeDraw, aDrawer);
496
497         // add special wireframe presentation for faces without triangulation
498         StdPrs_ShadedShape::AddWireframeForFacesWithoutTriangles (thePrs, aShapeDraw, aDrawer);
499
500         Handle(Graphic3d_ArrayOfTriangles) aTriangles = StdPrs_ShadedShape::FillTriangles (aShapeDraw);
501         if (!aTriangles.IsNull())
502         {
503           if (aShadedGroup.IsNull())
504           {
505             aShadedGroup = Prs3d_Root::NewGroup (thePrs);
506             aShadedGroup->SetClosed (isClosed);
507           }
508           aShadedGroup->SetPrimitivesAspect (aDrawer->ShadingAspect()->Aspect());
509           aShadedGroup->AddPrimitiveArray (aTriangles);
510         }
511
512         if (aDrawer->FaceBoundaryDraw())
513         {
514           Handle(Graphic3d_ArrayOfSegments) aBndSegments = StdPrs_ShadedShape::FillFaceBoundaries (aShapeDraw);
515           if (!aBndSegments.IsNull())
516           {
517             if (aShadedGroup.IsNull())
518             {
519               aShadedGroup = Prs3d_Root::NewGroup (thePrs);
520               aShadedGroup->SetClosed (isClosed);
521             }
522
523             Handle(Graphic3d_AspectLine3d) aBoundaryAspect = aDrawer->FaceBoundaryAspect()->Aspect();
524             aShadedGroup->SetPrimitivesAspect (aBoundaryAspect);
525             aShadedGroup->AddPrimitiveArray (aBndSegments);
526           }
527         }
528       }
529       else
530       {
531         StdPrs_WFShape::Add (thePrs, aShapeDraw, aDrawer);
532       }
533       aDrawer->SetTypeOfDeflection (aPrevType);
534     }
535   }
536 }
537
538 //=======================================================================
539 //function : dispatchColors
540 //purpose  :
541 //=======================================================================
542 Standard_Boolean AIS_ColoredShape::dispatchColors (const Handle(AIS_ColoredDrawer)& theParentDrawer,
543                                                    const TopoDS_Shape& theShapeToParse,
544                                                    const AIS_DataMapOfShapeDrawer& theShapeDrawerMap,
545                                                    const TopAbs_ShapeEnum theParentType,
546                                                    const Standard_Boolean theIsParentClosed,
547                                                    DataMapOfDrawerCompd* theDrawerOpenedShapePerType,
548                                                    DataMapOfDrawerCompd& theDrawerClosedFaces)
549 {
550   const TopAbs_ShapeEnum aShapeType = theShapeToParse.ShapeType();
551   if (aShapeType == TopAbs_SHAPE)
552   {
553     return Standard_False;
554   }
555
556   // check own setting of current shape
557   Handle(AIS_ColoredDrawer) aDrawer = theParentDrawer;
558   const Standard_Boolean isOverriden = theShapeDrawerMap.Find (theShapeToParse, aDrawer);
559   if (isOverriden
560    && aDrawer->IsHidden())
561   {
562     return Standard_True;
563   }
564
565   // handle compounds, solids and shells
566   Standard_Boolean isSubOverride = Standard_False;
567   if (aShapeType <= TopAbs_SHELL)
568   {
569     // detect parts of closed solids
570     Standard_Boolean isClosedShell = theParentType == TopAbs_SOLID
571                                   && aShapeType == TopAbs_SHELL
572                                   && BRep_Tool::IsClosed (theShapeToParse)
573                                   && StdPrs_ToolTriangulatedShape::IsTriangulated (theShapeToParse);
574     if (isClosedShell)
575     {
576       for (TopoDS_Iterator aFaceIter (theShapeToParse); aFaceIter.More(); aFaceIter.Next())
577       {
578         const TopoDS_Shape& aFace = aFaceIter.Value();
579         Handle(AIS_ColoredDrawer) aFaceDrawer;
580         if (aFace.ShapeType() == TopAbs_FACE
581          && theShapeDrawerMap.Find (aFace, aFaceDrawer)
582          && aFaceDrawer->IsHidden())
583         {
584           isClosedShell = Standard_False;
585           break;
586         }
587       }
588     }
589
590     for (TopoDS_Iterator aSubShapeIter (theShapeToParse); aSubShapeIter.More(); aSubShapeIter.Next())
591     {
592       const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
593       if (dispatchColors (aDrawer, aSubShape,
594                           theShapeDrawerMap, aShapeType,
595                           isClosedShell,
596                           theDrawerOpenedShapePerType,
597                           theDrawerClosedFaces))
598       {
599         isSubOverride = Standard_True;
600       }
601     }
602     return isOverriden || isSubOverride;
603   }
604
605   // iterate on sub-shapes
606   BRep_Builder aBBuilder;
607   TopoDS_Shape aShapeCopy = theShapeToParse.EmptyCopied();
608   aShapeCopy.Closed (theShapeToParse.Closed());
609   Standard_Integer nbDef = 0;
610   for (TopoDS_Iterator aSubShapeIter (theShapeToParse); aSubShapeIter.More(); aSubShapeIter.Next())
611   {
612     const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
613     if (dispatchColors (aDrawer, aSubShape,
614                         theShapeDrawerMap, aShapeType,
615                         theIsParentClosed,
616                         theDrawerOpenedShapePerType,
617                         theDrawerClosedFaces))
618     {
619       isSubOverride = Standard_True;
620     }
621     else
622     {
623       aBBuilder.Add (aShapeCopy, aSubShape);
624       ++nbDef;
625     }
626   }
627   if (aShapeType == TopAbs_FACE || !isSubOverride)
628   {
629     aShapeCopy = theShapeToParse;
630   }
631   else if (nbDef == 0)
632   {
633     return isOverriden || isSubOverride; // empty compound
634   }
635
636   // if any of styles is overridden regarding to default one, add rest to map
637   if (isOverriden
638   || (isSubOverride && theParentType != TopAbs_WIRE  // avoid drawing edges when vertex color is overridden
639                     && theParentType != TopAbs_FACE) // avoid drawing edges of the same color as face
640   || (theParentType <= TopAbs_SHELL && !(isOverriden || isSubOverride))) // bind original shape to default color
641   {
642     TopoDS_Compound aCompound;
643     DataMapOfDrawerCompd& aDrawerShapeMap = theIsParentClosed
644                                          && aShapeType == TopAbs_FACE
645                                           ? theDrawerClosedFaces
646                                           : theDrawerOpenedShapePerType[(size_t)aShapeType];
647     if (!aDrawerShapeMap.FindFromKey (aDrawer, aCompound))
648     {
649       aBBuilder.MakeCompound (aCompound);
650       aDrawerShapeMap.Add (aDrawer, aCompound);
651     }
652     aBBuilder.Add (aCompound, aShapeCopy);
653   }
654   return isOverriden || isSubOverride;
655 }
656
657 //=======================================================================
658 //function : isShapeEntirelyVisible
659 //purpose  :
660 //=======================================================================
661 Standard_Boolean AIS_ColoredShape::isShapeEntirelyVisible() const
662 {
663   for (AIS_DataMapOfShapeDrawer::Iterator aMapIter (myShapeColors); aMapIter.More(); aMapIter.Next())
664   {
665     if (aMapIter.Value()->IsHidden())
666     {
667       return Standard_False;
668     }
669   }
670   return Standard_True;
671 }
672
673 //=======================================================================
674 //function : bindSubShapes
675 //purpose  :
676 //=======================================================================
677 void AIS_ColoredShape::bindSubShapes (AIS_DataMapOfShapeDrawer& theShapeDrawerMap,
678                                       const TopoDS_Shape& theKeyShape,
679                                       const Handle(AIS_ColoredDrawer)& theDrawer)
680 {
681   TopAbs_ShapeEnum aShapeWithColorType = theKeyShape.ShapeType();
682   if (aShapeWithColorType == TopAbs_COMPOUND)
683   {
684     theShapeDrawerMap.Bind (theKeyShape, theDrawer);
685   }
686   else if (aShapeWithColorType == TopAbs_SOLID || aShapeWithColorType == TopAbs_SHELL)
687   {
688     for (TopExp_Explorer anExp (theKeyShape, TopAbs_FACE); anExp.More(); anExp.Next())
689     {
690       if (!theShapeDrawerMap.IsBound (anExp.Current()))
691       {
692         theShapeDrawerMap.Bind (anExp.Current(), theDrawer);
693       }
694     }
695   }
696   else if (aShapeWithColorType == TopAbs_WIRE)
697   {
698     for (TopExp_Explorer anExp (theKeyShape, TopAbs_EDGE); anExp.More(); anExp.Next())
699     {
700       if (!theShapeDrawerMap.IsBound (anExp.Current()))
701       {
702         theShapeDrawerMap.Bind (anExp.Current(), theDrawer);
703       }
704     }
705   }
706   else
707   {
708     // bind single face, edge and vertex
709     // force rebind if required due to the color of single shape has
710     // higher priority than the color of "compound" shape (wire is a
711     // compound of edges, shell is a compound of faces) that contains
712     // this single shape.
713     theShapeDrawerMap.Bind (theKeyShape, theDrawer);
714   }
715 }