0029491: Visualization, AIS_Shape - filter unsupported Display Modes within ::AcceptD...
[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 <BRepMesh_IncrementalMesh.hxx>
22 #include <gp_Pnt2d.hxx>
23 #include <Graphic3d_AspectFillArea3d.hxx>
24 #include <Graphic3d_AspectLine3d.hxx>
25 #include <Graphic3d_ArrayOfTriangles.hxx>
26 #include <Graphic3d_ArrayOfSegments.hxx>
27 #include <Graphic3d_Group.hxx>
28 #include <Graphic3d_StructureManager.hxx>
29 #include <Graphic3d_Texture2Dmanual.hxx>
30 #include <Precision.hxx>
31 #include <Prs3d.hxx>
32 #include <Prs3d_LineAspect.hxx>
33 #include <Prs3d_IsoAspect.hxx>
34 #include <Prs3d_Presentation.hxx>
35 #include <Prs3d_ShadingAspect.hxx>
36 #include <Prs3d_Root.hxx>
37 #include <PrsMgr_PresentationManager3d.hxx>
38 #include <Standard_ErrorHandler.hxx>
39 #include <StdSelect_BRepSelectionTool.hxx>
40 #include <StdPrs_ShadedShape.hxx>
41 #include <StdPrs_ToolTriangulatedShape.hxx>
42 #include <StdPrs_WFShape.hxx>
43 #include <TopExp_Explorer.hxx>
44 #include <TopoDS.hxx>
45 #include <TopoDS_Compound.hxx>
46 #include <TopoDS_Iterator.hxx>
47
48 IMPLEMENT_STANDARD_RTTIEXT(AIS_ColoredShape,AIS_Shape)
49 IMPLEMENT_STANDARD_RTTIEXT(AIS_ColoredDrawer,Prs3d_Drawer)
50
51 namespace
52 {
53   //! Collect all sub-compounds into map.
54   static void collectSubCompounds (TopTools_MapOfShape& theMap,
55                                    const TopoDS_Shape&  theShape)
56   {
57     for (TopoDS_Iterator aChildIter (theShape); aChildIter.More(); aChildIter.Next())
58     {
59       const TopoDS_Shape& aShape = aChildIter.Value();
60       if (aShape.ShapeType() == TopAbs_COMPOUND
61        && theMap.Add (aShape))
62       {
63         collectSubCompounds (theMap, aShape);
64       }
65     }
66   }
67 }
68
69 //=======================================================================
70 //function : AIS_ColoredShape
71 //purpose  :
72 //=======================================================================
73 AIS_ColoredShape::AIS_ColoredShape (const TopoDS_Shape& theShape)
74 : AIS_Shape (theShape)
75 {
76   // disable dedicated line aspects
77   myDrawer->SetFreeBoundaryAspect  (myDrawer->LineAspect());
78   myDrawer->SetUnFreeBoundaryAspect(myDrawer->LineAspect());
79   myDrawer->SetSeenLineAspect      (myDrawer->LineAspect());
80 }
81
82 //=======================================================================
83 //function : AIS_ColoredShape
84 //purpose  :
85 //=======================================================================
86 AIS_ColoredShape::AIS_ColoredShape (const Handle(AIS_Shape)& theShape)
87 : AIS_Shape (theShape->Shape())
88 {
89   // disable dedicated line aspects
90   myDrawer->SetFreeBoundaryAspect  (myDrawer->LineAspect());
91   myDrawer->SetUnFreeBoundaryAspect(myDrawer->LineAspect());
92   myDrawer->SetSeenLineAspect      (myDrawer->LineAspect());
93   if (theShape->HasMaterial())
94   {
95     SetMaterial (theShape->Material());
96   }
97   if (theShape->HasColor())
98   {
99     Quantity_Color aColor;
100     theShape->Color (aColor);
101     SetColor (aColor);
102   }
103   if (theShape->HasWidth())
104   {
105     SetWidth (theShape->Width());
106   }
107   if (theShape->IsTransparent())
108   {
109     SetTransparency (theShape->Transparency());
110   }
111 }
112
113 //=======================================================================
114 //function : CustomAspects
115 //purpose  :
116 //=======================================================================
117 Handle(AIS_ColoredDrawer) AIS_ColoredShape::CustomAspects (const TopoDS_Shape& theShape)
118 {
119   Handle(AIS_ColoredDrawer) aDrawer;
120   myShapeColors.Find (theShape, aDrawer);
121   if (aDrawer.IsNull())
122   {
123     aDrawer = new AIS_ColoredDrawer (myDrawer);
124     myShapeColors.Bind (theShape, aDrawer);
125     LoadRecomputable (AIS_WireFrame);
126     LoadRecomputable (AIS_Shaded);
127   }
128   return aDrawer;
129 }
130
131 //=======================================================================
132 //function : ClearCustomAspects
133 //purpose  :
134 //=======================================================================
135 void AIS_ColoredShape::ClearCustomAspects()
136 {
137   if (myShapeColors.IsEmpty())
138   {
139     return;
140   }
141   myShapeColors.Clear();
142   LoadRecomputable (AIS_WireFrame);
143   LoadRecomputable (AIS_Shaded);
144 }
145
146 //=======================================================================
147 //function : UnsetCustomAspects
148 //purpose  :
149 //=======================================================================
150 void AIS_ColoredShape::UnsetCustomAspects (const TopoDS_Shape&    theShape,
151                                            const Standard_Boolean theToUnregister)
152 {
153   if (!myShapeColors.IsBound (theShape))
154   {
155     return;
156   }
157
158   LoadRecomputable (AIS_WireFrame);
159   LoadRecomputable (AIS_Shaded);
160   if (theToUnregister)
161   {
162     myShapeColors.UnBind (theShape);
163     return;
164   }
165
166   myShapeColors.ChangeFind (theShape) = new AIS_ColoredDrawer (myDrawer);
167 }
168
169 //=======================================================================
170 //function : SetCustomColor
171 //purpose  :
172 //=======================================================================
173 void AIS_ColoredShape::SetCustomColor (const TopoDS_Shape&   theShape,
174                                        const Quantity_Color& theColor)
175 {
176   if (theShape.IsNull())
177   {
178     return;
179   }
180
181   const Handle(AIS_ColoredDrawer)& aDrawer = CustomAspects (theShape);
182   setColor (aDrawer, theColor);
183   aDrawer->SetOwnColor (theColor);
184   LoadRecomputable (AIS_WireFrame);
185   LoadRecomputable (AIS_Shaded);
186 }
187
188 //=======================================================================
189 //function : SetCustomWidth
190 //purpose  :
191 //=======================================================================
192 void AIS_ColoredShape::SetCustomWidth (const TopoDS_Shape& theShape,
193                                        const Standard_Real theLineWidth)
194 {
195   if (theShape.IsNull())
196   {
197     return;
198   }
199
200   const Handle(AIS_ColoredDrawer)& aDrawer = CustomAspects (theShape);
201   setWidth (CustomAspects (theShape), theLineWidth);
202   aDrawer->SetOwnWidth (theLineWidth);
203   LoadRecomputable (AIS_WireFrame);
204   LoadRecomputable (AIS_Shaded);
205 }
206
207 //=======================================================================
208 //function : SetColor
209 //purpose  :
210 //=======================================================================
211
212 void AIS_ColoredShape::SetColor (const Quantity_Color&  theColor)
213 {
214   setColor (myDrawer, theColor);
215   myDrawer->SetColor (theColor);
216   hasOwnColor = Standard_True;
217   LoadRecomputable (AIS_WireFrame);
218   LoadRecomputable (AIS_Shaded);
219   for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
220   {
221     const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
222     if (aDrawer->HasOwnColor())
223     {
224       continue;
225     }
226
227     if (aDrawer->HasOwnShadingAspect())
228     {
229       aDrawer->ShadingAspect()->SetColor (theColor, myCurrentFacingModel);
230     }
231     if (aDrawer->HasOwnLineAspect())
232     {
233       aDrawer->LineAspect()->SetColor (theColor);
234     }
235     if (aDrawer->HasOwnWireAspect())
236     {
237       aDrawer->WireAspect()->SetColor (theColor);
238     }
239   }
240 }
241
242 //=======================================================================
243 //function : SetWidth
244 //purpose  :
245 //=======================================================================
246
247 void AIS_ColoredShape::SetWidth (const Standard_Real    theLineWidth)
248 {
249   setWidth (myDrawer, theLineWidth);
250   myOwnWidth = theLineWidth;
251   LoadRecomputable (AIS_WireFrame);
252   LoadRecomputable (AIS_Shaded);
253   for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
254   {
255     const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
256     if (aDrawer->HasOwnWidth())
257     {
258       continue;
259     }
260
261     if (aDrawer->HasOwnLineAspect())
262     {
263       aDrawer->LineAspect()->SetWidth (theLineWidth);
264     }
265     if (aDrawer->HasOwnWireAspect())
266     {
267       aDrawer->WireAspect()->SetWidth (theLineWidth);
268     }
269   }
270 }
271
272 //=======================================================================
273 //function : SetTransparency
274 //purpose  :
275 //=======================================================================
276
277 void AIS_ColoredShape::SetTransparency (const Standard_Real theValue)
278 {
279   setTransparency (myDrawer, theValue);
280   myDrawer->SetTransparency ((Standard_ShortReal )theValue);
281   LoadRecomputable (AIS_WireFrame);
282   LoadRecomputable (AIS_Shaded);
283   for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
284   {
285     const Handle(Prs3d_Drawer)& aDrawer = anIter.Value();
286     if (aDrawer->HasOwnShadingAspect())
287     {
288       aDrawer->ShadingAspect()->SetTransparency (theValue, myCurrentFacingModel);
289     }
290   }
291 }
292
293 //=======================================================================
294 //function : UnsetTransparency
295 //purpose  :
296 //=======================================================================
297 void AIS_ColoredShape::UnsetTransparency()
298 {
299   myDrawer->SetTransparency (0.0f);
300   if (myDrawer->HasOwnShadingAspect())
301   {
302     myDrawer->ShadingAspect()->SetTransparency (0.0, myCurrentFacingModel);
303     if (!HasColor()
304      && !HasMaterial()
305      && !myDrawer->ShadingAspect()->Aspect()->ToMapTexture())
306     {
307       myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
308     }
309   }
310
311   for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
312   {
313     const Handle(Prs3d_Drawer)& aDrawer = anIter.Value();
314     if (aDrawer->HasOwnShadingAspect())
315     {
316       aDrawer->ShadingAspect()->SetTransparency (0.0, myCurrentFacingModel);
317     }
318   }
319   SynchronizeAspects();
320 }
321
322 //=======================================================================
323 //function : SetMaterial
324 //purpose  :
325 //=======================================================================
326
327 void AIS_ColoredShape::SetMaterial (const Graphic3d_MaterialAspect& theMaterial)
328 {
329   setMaterial (myDrawer, theMaterial, HasColor(), IsTransparent());
330   //myOwnMaterial = theMaterial;
331   hasOwnMaterial = Standard_True;
332   LoadRecomputable (AIS_Shaded);
333   for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
334   {
335     const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
336     //if (aDrawer->HasOwnMaterial()) continue;
337     if (aDrawer->HasOwnShadingAspect())
338     {
339       setMaterial (aDrawer, theMaterial, aDrawer->HasOwnColor(), Standard_False); // aDrawer->IsTransparent()
340     }
341   }
342 }
343
344 //=======================================================================
345 //function : Compute
346 //purpose  :
347 //=======================================================================
348 void AIS_ColoredShape::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
349                                 const Handle(Prs3d_Presentation)&           thePrs,
350                                 const Standard_Integer                      theMode)
351 {
352   if (myshape.IsNull())
353   {
354     return;
355   }
356
357   if (IsInfinite())
358   {
359     thePrs->SetInfiniteState (Standard_True);
360   }
361
362   switch (theMode)
363   {
364     case AIS_WireFrame:
365     {
366       StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (myshape, myDrawer, Standard_True);
367
368       // After this call if type of deflection is relative
369       // computed deflection coefficient is stored as absolute.
370       Prs3d::GetDeflection (myshape, myDrawer);
371       break;
372     }
373     case AIS_Shaded:
374     {
375       if (myDrawer->IsAutoTriangulation())
376       {
377         // compute mesh for entire shape beforehand to ensure consistency and optimizations (parallelization)
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         Standard_Boolean wasRecomputed = StdPrs_ToolTriangulatedShape::Tessellate (myshape, myDrawer);
383
384         // Set to update wireframe presentation on triangulation.
385         if (myDrawer->IsoOnTriangulation() && wasRecomputed)
386         {
387           SetToUpdate (AIS_WireFrame);
388         }
389       }
390       break;
391     }
392     case 2:
393     {
394       AIS_Shape::Compute (thePrsMgr, thePrs, theMode);
395       return;
396     }
397     default:
398     {
399       return;
400     }
401   }
402
403   // Extract myShapeColors map (KeyshapeColored -> Color) to subshapes map (Subshape -> Color).
404   // This needed when colored shape is not part of BaseShape (but subshapes are) and actually container for subshapes.
405   AIS_DataMapOfShapeDrawer aSubshapeDrawerMap;
406   fillSubshapeDrawerMap (aSubshapeDrawerMap);
407
408   Handle(AIS_ColoredDrawer) aBaseDrawer;
409   myShapeColors.Find (myshape, aBaseDrawer);
410
411   // myShapeColors + anOpened --> array[TopAbs_ShapeEnum] of map of color-to-compound
412   DataMapOfDrawerCompd aDispatchedOpened[(size_t)TopAbs_SHAPE];
413   DataMapOfDrawerCompd aDispatchedClosed;
414   dispatchColors (aBaseDrawer, myshape,
415                   aSubshapeDrawerMap, TopAbs_COMPOUND, Standard_False,
416                   aDispatchedOpened, theMode == AIS_Shaded ? aDispatchedClosed : aDispatchedOpened[TopAbs_FACE]);
417   addShapesWithCustomProps (thePrs, aDispatchedOpened, aDispatchedClosed, theMode);
418 }
419
420 //=======================================================================
421 //function : fillSubshapeDrawerMap
422 //purpose  :
423 //=======================================================================
424 void AIS_ColoredShape::fillSubshapeDrawerMap (AIS_DataMapOfShapeDrawer& theSubshapeDrawerMap) const
425 {
426   // unroll compounds specified for grouping sub-shapes with the same style
427   // (e.g. the compounds that are not a part of the main shape)
428   TopTools_MapOfShape aMapOfOwnCompounds;
429   if (myshape.ShapeType() == TopAbs_COMPOUND)
430   {
431     aMapOfOwnCompounds.Add (myshape);
432     collectSubCompounds (aMapOfOwnCompounds, myshape);
433   }
434   for (AIS_DataMapOfShapeDrawer::Iterator aKeyShapeIter (myShapeColors);
435         aKeyShapeIter.More(); aKeyShapeIter.Next())
436   {
437     const TopoDS_Shape& aKeyShape = aKeyShapeIter.Key();
438     if (aKeyShape.ShapeType() != TopAbs_COMPOUND
439      || aMapOfOwnCompounds.Contains (aKeyShape))
440     {
441       continue;
442     }
443
444     for (TopoDS_Iterator aChildIter (aKeyShape); aChildIter.More(); aChildIter.Next())
445     {
446       const TopoDS_Shape& aShape = aChildIter.Value();
447       if (!myShapeColors.IsBound (aShape))
448       {
449         bindSubShapes (theSubshapeDrawerMap, aShape, aKeyShapeIter.Value());
450       }
451     }
452   }
453
454   // assign other sub-shapes with styles
455   for (AIS_DataMapOfShapeDrawer::Iterator aKeyShapeIter (myShapeColors);
456         aKeyShapeIter.More(); aKeyShapeIter.Next())
457   {
458     const TopoDS_Shape& aKeyShape = aKeyShapeIter.Key();
459     if (myshape == aKeyShape
460     || (aKeyShape.ShapeType() == TopAbs_COMPOUND
461     && !aMapOfOwnCompounds.Contains (aKeyShape)))
462     {
463       continue;
464     }
465
466     bindSubShapes (theSubshapeDrawerMap, aKeyShape, aKeyShapeIter.Value());
467   }
468 }
469
470 //=======================================================================
471 //function : ComputeSelection
472 //purpose  :
473 //=======================================================================
474 void AIS_ColoredShape::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
475                                          const Standard_Integer theMode)
476 {
477   if (myshape.IsNull())
478   {
479     return;
480   }
481   else if (isShapeEntirelyVisible())
482   {
483     base_type::ComputeSelection (theSelection, theMode);
484     return;
485   }
486
487   const TopAbs_ShapeEnum aTypOfSel   = AIS_Shape::SelectionType (theMode);
488   const Standard_Real    aDeflection = Prs3d::GetDeflection (myshape, myDrawer);
489   const Standard_Real    aDeviationAngle = myDrawer->HLRAngle();
490   const Standard_Integer aPriority   = StdSelect_BRepSelectionTool::GetStandardPriority (myshape, aTypOfSel);
491   if (myDrawer->IsAutoTriangulation()
492   && !BRepTools::Triangulation (myshape, Precision::Infinite()))
493   {
494     BRepMesh_IncrementalMesh aMesher (myshape, aDeflection, Standard_False, aDeviationAngle);
495   }
496
497   AIS_DataMapOfShapeDrawer aSubshapeDrawerMap;
498   fillSubshapeDrawerMap (aSubshapeDrawerMap);
499
500   Handle(StdSelect_BRepOwner) aBrepOwner = new StdSelect_BRepOwner (myshape, aPriority);
501   if (aTypOfSel == TopAbs_SHAPE)
502   {
503     aBrepOwner = new StdSelect_BRepOwner (myshape, aPriority);
504   }
505
506   Handle(AIS_ColoredDrawer) aBaseDrawer;
507   myShapeColors.Find (myshape, aBaseDrawer);
508   computeSubshapeSelection (aBaseDrawer, aSubshapeDrawerMap, myshape, aBrepOwner, theSelection,
509                             aTypOfSel, aPriority, aDeflection, aDeviationAngle);
510
511   Handle(SelectMgr_SelectableObject) aThis (this);
512   for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
513   {
514     Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aSelEntIter.Value()->BaseSensitive()->OwnerId());
515     anOwner->Set (aThis);
516   }
517
518   StdSelect_BRepSelectionTool::PreBuildBVH (theSelection);
519 }
520
521 //=======================================================================
522 //function : computeSubshapeSelection
523 //purpose  :
524 //=======================================================================
525 void AIS_ColoredShape::computeSubshapeSelection (const Handle(AIS_ColoredDrawer)& theParentDrawer,
526                                                  const AIS_DataMapOfShapeDrawer& theShapeDrawerMap,
527                                                  const TopoDS_Shape& theShape,
528                                                  const Handle(StdSelect_BRepOwner)& theOwner,
529                                                  const Handle(SelectMgr_Selection)& theSelection,
530                                                  const TopAbs_ShapeEnum theTypOfSel,
531                                                  const Standard_Integer thePriority,
532                                                  const Standard_Real theDeflection,
533                                                  const Standard_Real theDeflAngle)
534 {
535   Handle(AIS_ColoredDrawer) aDrawer = theParentDrawer;
536   theShapeDrawerMap.Find (theShape, aDrawer);
537   if (!aDrawer.IsNull()
538     && aDrawer->IsHidden())
539   {
540     return;
541   }
542
543   const Standard_Integer aNbPOnEdge = 9;
544   const Standard_Real    aMaximalParameter = 500.0;
545   if (theTypOfSel == TopAbs_SHAPE
546    && theShape.ShapeType() >= TopAbs_FACE)
547   {
548     StdSelect_BRepSelectionTool::ComputeSensitive (theShape, theOwner, theSelection,
549                                                    theDeflection, theDeflAngle, aNbPOnEdge, aMaximalParameter, myDrawer->IsAutoTriangulation());
550     return;
551   }
552   else if (theShape.ShapeType() == theTypOfSel)
553   {
554     const Standard_Boolean isComesFromDecomposition = !theShape.IsEqual (myshape);
555     Handle(StdSelect_BRepOwner) aBrepOwner = new StdSelect_BRepOwner (theShape, thePriority, isComesFromDecomposition);
556     StdSelect_BRepSelectionTool::ComputeSensitive (theShape, aBrepOwner, theSelection,
557                                                    theDeflection, theDeflAngle, aNbPOnEdge, aMaximalParameter, myDrawer->IsAutoTriangulation());
558     return;
559   }
560
561   for (TopoDS_Iterator aSubShapeIter (theShape); aSubShapeIter.More(); aSubShapeIter.Next())
562   {
563     const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
564     computeSubshapeSelection (aDrawer, theShapeDrawerMap, aSubShape,
565                               theOwner, theSelection, theTypOfSel, thePriority,
566                               theDeflection, theDeflAngle);
567   }
568 }
569
570 //=======================================================================
571 //function : addShapesWithCustomProps
572 //purpose  :
573 //=======================================================================
574 void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation)& thePrs,
575                                                  const DataMapOfDrawerCompd* theDrawerOpenedShapePerType,
576                                                  const DataMapOfDrawerCompd& theDrawerClosedFaces,
577                                                  const Standard_Integer theMode)
578 {
579   Handle(Graphic3d_Group) anOpenGroup, aClosedGroup;
580   for (size_t aShType = 0; aShType <= (size_t )TopAbs_SHAPE; ++aShType)
581   {
582     const Standard_Boolean isClosed = aShType == TopAbs_SHAPE;
583     Handle(Graphic3d_Group)& aShadedGroup = isClosed ? aClosedGroup : anOpenGroup;
584     const DataMapOfDrawerCompd& aDrawerShapeMap = isClosed
585                                                 ? theDrawerClosedFaces
586                                                 : theDrawerOpenedShapePerType[aShType];
587     for (DataMapOfDrawerCompd::Iterator aMapIter (aDrawerShapeMap);
588          aMapIter.More(); aMapIter.Next())
589     {
590       const Handle(AIS_ColoredDrawer)& aCustomDrawer = aMapIter.Key();
591       const TopoDS_Compound& aShapeDraw = aMapIter.Value(); // compound of subshapes with <aShType> type
592       Handle(Prs3d_Drawer) aDrawer;
593       if (!aCustomDrawer.IsNull())
594       {
595         aDrawer = aCustomDrawer;
596         if (aCustomDrawer->IsHidden())
597         {
598           continue;
599         }
600       }
601       else
602       {
603         aDrawer = myDrawer;
604       }
605
606       // It is supposed that absolute deflection contains previously computed relative deflection
607       // (if deflection type is relative).
608       // In case of CustomDrawer it is taken from Link().
609       Aspect_TypeOfDeflection aPrevType = aDrawer->TypeOfDeflection();
610       aDrawer->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
611
612       // Draw each kind of subshapes and personal-colored shapes in a separate group
613       // since it's necessary to set transparency/material for all subshapes
614       // without affecting their unique colors
615       if (theMode == AIS_Shaded
616        && aShapeDraw.ShapeType() <= TopAbs_FACE
617        && !IsInfinite())
618       {
619         // add wireframe presentation for isolated edges and vertices
620         StdPrs_ShadedShape::AddWireframeForFreeElements (thePrs, aShapeDraw, aDrawer);
621
622         // add special wireframe presentation for faces without triangulation
623         StdPrs_ShadedShape::AddWireframeForFacesWithoutTriangles (thePrs, aShapeDraw, aDrawer);
624
625         Handle(Graphic3d_ArrayOfTriangles) aTriangles = StdPrs_ShadedShape::FillTriangles (aShapeDraw,
626                                                                                            aDrawer->ShadingAspect()->Aspect()->ToMapTexture()
627                                                                                        && !aDrawer->ShadingAspect()->Aspect()->TextureMap().IsNull(),
628                                                                                            myUVOrigin, myUVRepeat, myUVScale);
629         if (!aTriangles.IsNull())
630         {
631           if (aShadedGroup.IsNull())
632           {
633             aShadedGroup = Prs3d_Root::NewGroup (thePrs);
634             aShadedGroup->SetClosed (isClosed);
635           }
636           aShadedGroup->SetPrimitivesAspect (aDrawer->ShadingAspect()->Aspect());
637           aShadedGroup->AddPrimitiveArray (aTriangles);
638         }
639
640         if (aDrawer->FaceBoundaryDraw())
641         {
642           Handle(Graphic3d_ArrayOfSegments) aBndSegments = StdPrs_ShadedShape::FillFaceBoundaries (aShapeDraw);
643           if (!aBndSegments.IsNull())
644           {
645             if (aShadedGroup.IsNull())
646             {
647               aShadedGroup = Prs3d_Root::NewGroup (thePrs);
648               aShadedGroup->SetClosed (isClosed);
649             }
650
651             Handle(Graphic3d_AspectLine3d) aBoundaryAspect = aDrawer->FaceBoundaryAspect()->Aspect();
652             aShadedGroup->SetPrimitivesAspect (aBoundaryAspect);
653             aShadedGroup->AddPrimitiveArray (aBndSegments);
654           }
655         }
656       }
657       else
658       {
659         StdPrs_WFShape::Add (thePrs, aShapeDraw, aDrawer);
660       }
661       aDrawer->SetTypeOfDeflection (aPrevType);
662     }
663   }
664 }
665
666 //=======================================================================
667 //function : dispatchColors
668 //purpose  :
669 //=======================================================================
670 Standard_Boolean AIS_ColoredShape::dispatchColors (const Handle(AIS_ColoredDrawer)& theParentDrawer,
671                                                    const TopoDS_Shape& theShapeToParse,
672                                                    const AIS_DataMapOfShapeDrawer& theShapeDrawerMap,
673                                                    const TopAbs_ShapeEnum theParentType,
674                                                    const Standard_Boolean theIsParentClosed,
675                                                    DataMapOfDrawerCompd* theDrawerOpenedShapePerType,
676                                                    DataMapOfDrawerCompd& theDrawerClosedFaces)
677 {
678   const TopAbs_ShapeEnum aShapeType = theShapeToParse.ShapeType();
679   if (aShapeType == TopAbs_SHAPE)
680   {
681     return Standard_False;
682   }
683
684   // check own setting of current shape
685   Handle(AIS_ColoredDrawer) aDrawer = theParentDrawer;
686   const Standard_Boolean isOverriden = theShapeDrawerMap.Find (theShapeToParse, aDrawer);
687   if (isOverriden
688    && aDrawer->IsHidden())
689   {
690     return Standard_True;
691   }
692
693   // handle compounds, solids and shells
694   Standard_Boolean isSubOverride = Standard_False;
695   if (aShapeType <= TopAbs_SHELL)
696   {
697     // detect parts of closed solids
698     Standard_Boolean isClosedShell = theParentType == TopAbs_SOLID
699                                   && aShapeType == TopAbs_SHELL
700                                   && BRep_Tool::IsClosed (theShapeToParse)
701                                   && StdPrs_ToolTriangulatedShape::IsTriangulated (theShapeToParse);
702     if (isClosedShell)
703     {
704       for (TopoDS_Iterator aFaceIter (theShapeToParse); aFaceIter.More(); aFaceIter.Next())
705       {
706         const TopoDS_Shape& aFace = aFaceIter.Value();
707         Handle(AIS_ColoredDrawer) aFaceDrawer;
708         if (aFace.ShapeType() == TopAbs_FACE
709          && theShapeDrawerMap.Find (aFace, aFaceDrawer)
710          && aFaceDrawer->IsHidden())
711         {
712           isClosedShell = Standard_False;
713           break;
714         }
715       }
716     }
717
718     for (TopoDS_Iterator aSubShapeIter (theShapeToParse); aSubShapeIter.More(); aSubShapeIter.Next())
719     {
720       const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
721       if (dispatchColors (aDrawer, aSubShape,
722                           theShapeDrawerMap, aShapeType,
723                           isClosedShell,
724                           theDrawerOpenedShapePerType,
725                           theDrawerClosedFaces))
726       {
727         isSubOverride = Standard_True;
728       }
729     }
730     return isOverriden || isSubOverride;
731   }
732
733   // iterate on sub-shapes
734   BRep_Builder aBBuilder;
735   TopoDS_Shape aShapeCopy = theShapeToParse.EmptyCopied();
736   aShapeCopy.Closed (theShapeToParse.Closed());
737   Standard_Integer nbDef = 0;
738   for (TopoDS_Iterator aSubShapeIter (theShapeToParse); aSubShapeIter.More(); aSubShapeIter.Next())
739   {
740     const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
741     if (dispatchColors (aDrawer, aSubShape,
742                         theShapeDrawerMap, aShapeType,
743                         theIsParentClosed,
744                         theDrawerOpenedShapePerType,
745                         theDrawerClosedFaces))
746     {
747       isSubOverride = Standard_True;
748     }
749     else
750     {
751       aBBuilder.Add (aShapeCopy, aSubShape);
752       ++nbDef;
753     }
754   }
755   if (aShapeType == TopAbs_FACE || !isSubOverride)
756   {
757     aShapeCopy = theShapeToParse;
758   }
759   else if (nbDef == 0)
760   {
761     return isOverriden || isSubOverride; // empty compound
762   }
763
764   // if any of styles is overridden regarding to default one, add rest to map
765   if (isOverriden
766   || (isSubOverride && theParentType != TopAbs_WIRE  // avoid drawing edges when vertex color is overridden
767                     && theParentType != TopAbs_FACE) // avoid drawing edges of the same color as face
768   || (theParentType <= TopAbs_SHELL && !(isOverriden || isSubOverride))) // bind original shape to default color
769   {
770     TopoDS_Compound aCompound;
771     DataMapOfDrawerCompd& aDrawerShapeMap = theIsParentClosed
772                                          && aShapeType == TopAbs_FACE
773                                           ? theDrawerClosedFaces
774                                           : theDrawerOpenedShapePerType[(size_t)aShapeType];
775     if (!aDrawerShapeMap.FindFromKey (aDrawer, aCompound))
776     {
777       aBBuilder.MakeCompound (aCompound);
778       aDrawerShapeMap.Add (aDrawer, aCompound);
779     }
780     aBBuilder.Add (aCompound, aShapeCopy);
781   }
782   return isOverriden || isSubOverride;
783 }
784
785 //=======================================================================
786 //function : isShapeEntirelyVisible
787 //purpose  :
788 //=======================================================================
789 Standard_Boolean AIS_ColoredShape::isShapeEntirelyVisible() const
790 {
791   for (AIS_DataMapOfShapeDrawer::Iterator aMapIter (myShapeColors); aMapIter.More(); aMapIter.Next())
792   {
793     if (aMapIter.Value()->IsHidden())
794     {
795       return Standard_False;
796     }
797   }
798   return Standard_True;
799 }
800
801 //=======================================================================
802 //function : bindSubShapes
803 //purpose  :
804 //=======================================================================
805 void AIS_ColoredShape::bindSubShapes (AIS_DataMapOfShapeDrawer& theShapeDrawerMap,
806                                       const TopoDS_Shape& theKeyShape,
807                                       const Handle(AIS_ColoredDrawer)& theDrawer) const
808 {
809   TopAbs_ShapeEnum aShapeWithColorType = theKeyShape.ShapeType();
810   if (aShapeWithColorType == TopAbs_COMPOUND)
811   {
812     theShapeDrawerMap.Bind (theKeyShape, theDrawer);
813   }
814   else if (aShapeWithColorType == TopAbs_SOLID || aShapeWithColorType == TopAbs_SHELL)
815   {
816     for (TopExp_Explorer anExp (theKeyShape, TopAbs_FACE); anExp.More(); anExp.Next())
817     {
818       if (!theShapeDrawerMap.IsBound (anExp.Current()))
819       {
820         theShapeDrawerMap.Bind (anExp.Current(), theDrawer);
821       }
822     }
823   }
824   else if (aShapeWithColorType == TopAbs_WIRE)
825   {
826     for (TopExp_Explorer anExp (theKeyShape, TopAbs_EDGE); anExp.More(); anExp.Next())
827     {
828       if (!theShapeDrawerMap.IsBound (anExp.Current()))
829       {
830         theShapeDrawerMap.Bind (anExp.Current(), theDrawer);
831       }
832     }
833   }
834   else
835   {
836     // bind single face, edge and vertex
837     // force rebind if required due to the color of single shape has
838     // higher priority than the color of "compound" shape (wire is a
839     // compound of edges, shell is a compound of faces) that contains
840     // this single shape.
841     theShapeDrawerMap.Bind (theKeyShape, theDrawer);
842   }
843 }