0028987: Visualization, SelectMgr_SelectableObject - move out iterator from object
[occt.git] / src / AIS / AIS_ColoredShape.cxx
CommitLineData
ad3217cd 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>
6985e642 21#include <BRepMesh_IncrementalMesh.hxx>
ad3217cd 22#include <gp_Pnt2d.hxx>
23#include <Graphic3d_AspectFillArea3d.hxx>
24#include <Graphic3d_AspectLine3d.hxx>
9c86076b 25#include <Graphic3d_ArrayOfTriangles.hxx>
26#include <Graphic3d_ArrayOfSegments.hxx>
ad3217cd 27#include <Graphic3d_Group.hxx>
28#include <Graphic3d_StructureManager.hxx>
29#include <Graphic3d_Texture2Dmanual.hxx>
30#include <Precision.hxx>
6262338c 31#include <Prs3d.hxx>
ad3217cd 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>
6985e642 39#include <StdSelect_BRepSelectionTool.hxx>
ad3217cd 40#include <StdPrs_ShadedShape.hxx>
5ad8c033 41#include <StdPrs_ToolTriangulatedShape.hxx>
42#include <StdPrs_WFShape.hxx>
ad3217cd 43#include <TopExp_Explorer.hxx>
44#include <TopoDS.hxx>
45#include <TopoDS_Compound.hxx>
46#include <TopoDS_Iterator.hxx>
47
92efcf78 48IMPLEMENT_STANDARD_RTTIEXT(AIS_ColoredShape,AIS_Shape)
49IMPLEMENT_STANDARD_RTTIEXT(AIS_ColoredDrawer,Prs3d_Drawer)
50
9c86076b 51namespace
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 {
478ad1d1 63 collectSubCompounds (theMap, aShape);
9c86076b 64 }
65 }
66 }
67}
68
ad3217cd 69//=======================================================================
70//function : AIS_ColoredShape
71//purpose :
72//=======================================================================
73AIS_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//=======================================================================
86AIS_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 {
87432b82 99 Quantity_Color aColor;
100 theShape->Color (aColor);
101 SetColor (aColor);
ad3217cd 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//=======================================================================
117Handle(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//=======================================================================
135void 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//=======================================================================
150void 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//=======================================================================
173void 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//=======================================================================
192void 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
212void AIS_ColoredShape::SetColor (const Quantity_Color& theColor)
213{
214 setColor (myDrawer, theColor);
f838dac4 215 myDrawer->SetColor (theColor);
ad3217cd 216 hasOwnColor = Standard_True;
217 LoadRecomputable (AIS_WireFrame);
218 LoadRecomputable (AIS_Shaded);
fb66bb28 219 for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
ad3217cd 220 {
221 const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
222 if (aDrawer->HasOwnColor())
223 {
224 continue;
225 }
226
6262338c 227 if (aDrawer->HasOwnShadingAspect())
ad3217cd 228 {
229 aDrawer->ShadingAspect()->SetColor (theColor, myCurrentFacingModel);
230 }
6262338c 231 if (aDrawer->HasOwnLineAspect())
ad3217cd 232 {
233 aDrawer->LineAspect()->SetColor (theColor);
234 }
6262338c 235 if (aDrawer->HasOwnWireAspect())
ad3217cd 236 {
237 aDrawer->WireAspect()->SetColor (theColor);
238 }
239 }
240}
241
242//=======================================================================
243//function : SetWidth
244//purpose :
245//=======================================================================
246
247void AIS_ColoredShape::SetWidth (const Standard_Real theLineWidth)
248{
249 setWidth (myDrawer, theLineWidth);
250 myOwnWidth = theLineWidth;
251 LoadRecomputable (AIS_WireFrame);
252 LoadRecomputable (AIS_Shaded);
fb66bb28 253 for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
ad3217cd 254 {
255 const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
256 if (aDrawer->HasOwnWidth())
257 {
258 continue;
259 }
260
6262338c 261 if (aDrawer->HasOwnLineAspect())
ad3217cd 262 {
263 aDrawer->LineAspect()->SetWidth (theLineWidth);
264 }
6262338c 265 if (aDrawer->HasOwnWireAspect())
ad3217cd 266 {
267 aDrawer->WireAspect()->SetWidth (theLineWidth);
268 }
269 }
270}
271
272//=======================================================================
273//function : SetTransparency
274//purpose :
275//=======================================================================
276
277void AIS_ColoredShape::SetTransparency (const Standard_Real theValue)
278{
279 setTransparency (myDrawer, theValue);
f838dac4 280 myDrawer->SetTransparency ((Standard_ShortReal )theValue);
ad3217cd 281 LoadRecomputable (AIS_WireFrame);
282 LoadRecomputable (AIS_Shaded);
fb66bb28 283 for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
ad3217cd 284 {
6262338c 285 const Handle(Prs3d_Drawer)& aDrawer = anIter.Value();
286 if (aDrawer->HasOwnShadingAspect())
ad3217cd 287 {
288 aDrawer->ShadingAspect()->SetTransparency (theValue, myCurrentFacingModel);
289 }
290 }
291}
292
f6d4c5cf 293//=======================================================================
294//function : UnsetTransparency
295//purpose :
296//=======================================================================
297void AIS_ColoredShape::UnsetTransparency()
298{
299 myDrawer->SetTransparency (0.0f);
300 if (myDrawer->HasOwnShadingAspect())
301 {
302 myDrawer->ShadingAspect()->SetTransparency (0.0, myCurrentFacingModel);
a6dee93d 303 if (!HasColor()
304 && !HasMaterial()
305 && !myDrawer->ShadingAspect()->Aspect()->ToMapTexture())
306 {
307 myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
308 }
f6d4c5cf 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
e0608a8d 322//=======================================================================
323//function : SetMaterial
324//purpose :
325//=======================================================================
326
327void 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);
fb66bb28 333 for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
e0608a8d 334 {
335 const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
336 //if (aDrawer->HasOwnMaterial()) continue;
6262338c 337 if (aDrawer->HasOwnShadingAspect())
e0608a8d 338 {
339 setMaterial (aDrawer, theMaterial, aDrawer->HasOwnColor(), Standard_False); // aDrawer->IsTransparent()
340 }
341 }
342}
343
ad3217cd 344//=======================================================================
345//function : Compute
346//purpose :
347//=======================================================================
348void AIS_ColoredShape::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
349 const Handle(Prs3d_Presentation)& thePrs,
350 const Standard_Integer theMode)
351{
ede89abc 352 if (myshape.IsNull())
353 {
354 return;
355 }
356
ad3217cd 357 if (IsInfinite())
358 {
359 thePrs->SetInfiniteState (Standard_True);
360 }
361
ad3217cd 362 if (theMode == AIS_Shaded)
363 {
4c513386 364 if (myDrawer->IsAutoTriangulation())
ad3217cd 365 {
4c513386 366 // compute mesh for entire shape beforehand to ensure consistency and optimizations (parallelization)
83b0f13a 367 StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (myshape, myDrawer, Standard_True);
368
306f5893 369 // After this call if type of deflection is relative
370 // computed deflection coefficient is stored as absolute.
5ad8c033 371 Standard_Boolean wasRecomputed = StdPrs_ToolTriangulatedShape::Tessellate (myshape, myDrawer);
372
373 // Set to update wireframe presentation on triangulation.
374 if (myDrawer->IsoOnTriangulation() && wasRecomputed)
375 {
376 SetToUpdate (AIS_WireFrame);
377 }
ad3217cd 378 }
7f917335 379 }
380 else // WireFrame mode
381 {
83b0f13a 382 StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (myshape, myDrawer, Standard_True);
383
7f917335 384 // After this call if type of deflection is relative
385 // computed deflection coefficient is stored as absolute.
386 Prs3d::GetDeflection (myshape, myDrawer);
ad3217cd 387 }
388
6985e642 389 // Extract myShapeColors map (KeyshapeColored -> Color) to subshapes map (Subshape -> Color).
390 // This needed when colored shape is not part of BaseShape (but subshapes are) and actually container for subshapes.
9c86076b 391 AIS_DataMapOfShapeDrawer aSubshapeDrawerMap;
6985e642 392 fillSubshapeDrawerMap (aSubshapeDrawerMap);
393
394 Handle(AIS_ColoredDrawer) aBaseDrawer;
395 myShapeColors.Find (myshape, aBaseDrawer);
396
397 // myShapeColors + anOpened --> array[TopAbs_ShapeEnum] of map of color-to-compound
398 DataMapOfDrawerCompd aDispatchedOpened[(size_t)TopAbs_SHAPE];
399 DataMapOfDrawerCompd aDispatchedClosed;
400 dispatchColors (aBaseDrawer, myshape,
401 aSubshapeDrawerMap, TopAbs_COMPOUND, Standard_False,
402 aDispatchedOpened, theMode == AIS_Shaded ? aDispatchedClosed : aDispatchedOpened[TopAbs_FACE]);
403 addShapesWithCustomProps (thePrs, aDispatchedOpened, aDispatchedClosed, theMode);
404}
405
406//=======================================================================
407//function : fillSubshapeDrawerMap
408//purpose :
409//=======================================================================
410void AIS_ColoredShape::fillSubshapeDrawerMap (AIS_DataMapOfShapeDrawer& theSubshapeDrawerMap) const
411{
412 // unroll compounds specified for grouping sub-shapes with the same style
413 // (e.g. the compounds that are not a part of the main shape)
414 TopTools_MapOfShape aMapOfOwnCompounds;
415 if (myshape.ShapeType() == TopAbs_COMPOUND)
5bffb882 416 {
6985e642 417 aMapOfOwnCompounds.Add (myshape);
418 collectSubCompounds (aMapOfOwnCompounds, myshape);
419 }
420 for (AIS_DataMapOfShapeDrawer::Iterator aKeyShapeIter (myShapeColors);
421 aKeyShapeIter.More(); aKeyShapeIter.Next())
422 {
423 const TopoDS_Shape& aKeyShape = aKeyShapeIter.Key();
424 if (aKeyShape.ShapeType() != TopAbs_COMPOUND
425 || aMapOfOwnCompounds.Contains (aKeyShape))
5bffb882 426 {
6985e642 427 continue;
5bffb882 428 }
9c86076b 429
6985e642 430 for (TopoDS_Iterator aChildIter (aKeyShape); aChildIter.More(); aChildIter.Next())
431 {
432 const TopoDS_Shape& aShape = aChildIter.Value();
433 if (!myShapeColors.IsBound (aShape))
9c86076b 434 {
6985e642 435 bindSubShapes (theSubshapeDrawerMap, aShape, aKeyShapeIter.Value());
5bffb882 436 }
437 }
6985e642 438 }
9c86076b 439
6985e642 440 // assign other sub-shapes with styles
441 for (AIS_DataMapOfShapeDrawer::Iterator aKeyShapeIter (myShapeColors);
442 aKeyShapeIter.More(); aKeyShapeIter.Next())
443 {
444 const TopoDS_Shape& aKeyShape = aKeyShapeIter.Key();
445 if (myshape == aKeyShape
446 || (aKeyShape.ShapeType() == TopAbs_COMPOUND
447 && !aMapOfOwnCompounds.Contains (aKeyShape)))
9c86076b 448 {
6985e642 449 continue;
9c86076b 450 }
6985e642 451
452 bindSubShapes (theSubshapeDrawerMap, aKeyShape, aKeyShapeIter.Value());
453 }
454}
455
456//=======================================================================
457//function : ComputeSelection
458//purpose :
459//=======================================================================
460void AIS_ColoredShape::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
461 const Standard_Integer theMode)
462{
463 if (myshape.IsNull())
464 {
465 return;
466 }
467 else if (isShapeEntirelyVisible())
468 {
469 base_type::ComputeSelection (theSelection, theMode);
470 return;
471 }
472
473 const TopAbs_ShapeEnum aTypOfSel = AIS_Shape::SelectionType (theMode);
474 const Standard_Real aDeflection = Prs3d::GetDeflection (myshape, myDrawer);
475 const Standard_Real aDeviationAngle = myDrawer->HLRAngle();
476 const Standard_Integer aPriority = StdSelect_BRepSelectionTool::GetStandardPriority (myshape, aTypOfSel);
477 if (myDrawer->IsAutoTriangulation()
478 && !BRepTools::Triangulation (myshape, Precision::Infinite()))
479 {
480 BRepMesh_IncrementalMesh aMesher (myshape, aDeflection, Standard_False, aDeviationAngle);
481 }
482
483 AIS_DataMapOfShapeDrawer aSubshapeDrawerMap;
484 fillSubshapeDrawerMap (aSubshapeDrawerMap);
485
486 Handle(StdSelect_BRepOwner) aBrepOwner = new StdSelect_BRepOwner (myshape, aPriority);
487 if (aTypOfSel == TopAbs_SHAPE)
488 {
489 aBrepOwner = new StdSelect_BRepOwner (myshape, aPriority);
5bffb882 490 }
9c86076b 491
492 Handle(AIS_ColoredDrawer) aBaseDrawer;
493 myShapeColors.Find (myshape, aBaseDrawer);
6985e642 494 computeSubshapeSelection (aBaseDrawer, aSubshapeDrawerMap, myshape, aBrepOwner, theSelection,
495 aTypOfSel, aPriority, aDeflection, aDeviationAngle);
9c86076b 496
6985e642 497 Handle(SelectMgr_SelectableObject) aThis (this);
b5cce1ab 498 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
6985e642 499 {
b5cce1ab 500 Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aSelEntIter.Value()->BaseSensitive()->OwnerId());
6985e642 501 anOwner->Set (aThis);
502 }
503
504 StdSelect_BRepSelectionTool::PreBuildBVH (theSelection);
505}
506
507//=======================================================================
508//function : computeSubshapeSelection
509//purpose :
510//=======================================================================
511void AIS_ColoredShape::computeSubshapeSelection (const Handle(AIS_ColoredDrawer)& theParentDrawer,
512 const AIS_DataMapOfShapeDrawer& theShapeDrawerMap,
513 const TopoDS_Shape& theShape,
514 const Handle(StdSelect_BRepOwner)& theOwner,
515 const Handle(SelectMgr_Selection)& theSelection,
516 const TopAbs_ShapeEnum theTypOfSel,
517 const Standard_Integer thePriority,
518 const Standard_Real theDeflection,
519 const Standard_Real theDeflAngle)
520{
521 Handle(AIS_ColoredDrawer) aDrawer = theParentDrawer;
522 theShapeDrawerMap.Find (theShape, aDrawer);
523 if (!aDrawer.IsNull()
524 && aDrawer->IsHidden())
525 {
526 return;
527 }
528
529 const Standard_Integer aNbPOnEdge = 9;
530 const Standard_Real aMaximalParameter = 500.0;
531 if (theTypOfSel == TopAbs_SHAPE
532 && theShape.ShapeType() >= TopAbs_FACE)
533 {
534 StdSelect_BRepSelectionTool::ComputeSensitive (theShape, theOwner, theSelection,
535 theDeflection, theDeflAngle, aNbPOnEdge, aMaximalParameter, myDrawer->IsAutoTriangulation());
536 return;
537 }
538 else if (theShape.ShapeType() == theTypOfSel)
539 {
540 const Standard_Boolean isComesFromDecomposition = !theShape.IsEqual (myshape);
541 Handle(StdSelect_BRepOwner) aBrepOwner = new StdSelect_BRepOwner (theShape, thePriority, isComesFromDecomposition);
542 StdSelect_BRepSelectionTool::ComputeSensitive (theShape, aBrepOwner, theSelection,
543 theDeflection, theDeflAngle, aNbPOnEdge, aMaximalParameter, myDrawer->IsAutoTriangulation());
544 return;
545 }
546
547 for (TopoDS_Iterator aSubShapeIter (theShape); aSubShapeIter.More(); aSubShapeIter.Next())
548 {
549 const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
550 computeSubshapeSelection (aDrawer, theShapeDrawerMap, aSubShape,
551 theOwner, theSelection, theTypOfSel, thePriority,
552 theDeflection, theDeflAngle);
553 }
5bffb882 554}
ad3217cd 555
5bffb882 556//=======================================================================
557//function : addShapesWithCustomProps
558//purpose :
559//=======================================================================
560void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation)& thePrs,
9c86076b 561 const DataMapOfDrawerCompd* theDrawerOpenedShapePerType,
562 const DataMapOfDrawerCompd& theDrawerClosedFaces,
563 const Standard_Integer theMode)
5bffb882 564{
9c86076b 565 Handle(Graphic3d_Group) anOpenGroup, aClosedGroup;
566 for (size_t aShType = 0; aShType <= (size_t )TopAbs_SHAPE; ++aShType)
567 {
568 const Standard_Boolean isClosed = aShType == TopAbs_SHAPE;
569 Handle(Graphic3d_Group)& aShadedGroup = isClosed ? aClosedGroup : anOpenGroup;
570 const DataMapOfDrawerCompd& aDrawerShapeMap = isClosed
571 ? theDrawerClosedFaces
572 : theDrawerOpenedShapePerType[aShType];
573 for (DataMapOfDrawerCompd::Iterator aMapIter (aDrawerShapeMap);
ad3217cd 574 aMapIter.More(); aMapIter.Next())
575 {
9c86076b 576 const Handle(AIS_ColoredDrawer)& aCustomDrawer = aMapIter.Key();
ad3217cd 577 const TopoDS_Compound& aShapeDraw = aMapIter.Value(); // compound of subshapes with <aShType> type
6262338c 578 Handle(Prs3d_Drawer) aDrawer;
9c86076b 579 if (!aCustomDrawer.IsNull())
86766b0e 580 {
581 aDrawer = aCustomDrawer;
582 if (aCustomDrawer->IsHidden())
583 {
584 continue;
585 }
586 }
587 else
588 {
589 aDrawer = myDrawer;
590 }
ad3217cd 591
7f917335 592 // It is supposed that absolute deflection contains previously computed relative deflection
593 // (if deflection type is relative).
594 // In case of CustomDrawer it is taken from Link().
595 Aspect_TypeOfDeflection aPrevType = aDrawer->TypeOfDeflection();
596 aDrawer->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
597
ad3217cd 598 // Draw each kind of subshapes and personal-colored shapes in a separate group
599 // since it's necessary to set transparency/material for all subshapes
600 // without affecting their unique colors
5bffb882 601 if (theMode == AIS_Shaded
602 && aShapeDraw.ShapeType() <= TopAbs_FACE
603 && !IsInfinite())
ad3217cd 604 {
9c86076b 605 // add wireframe presentation for isolated edges and vertices
606 StdPrs_ShadedShape::AddWireframeForFreeElements (thePrs, aShapeDraw, aDrawer);
607
608 // add special wireframe presentation for faces without triangulation
609 StdPrs_ShadedShape::AddWireframeForFacesWithoutTriangles (thePrs, aShapeDraw, aDrawer);
610
a6dee93d 611 Handle(Graphic3d_ArrayOfTriangles) aTriangles = StdPrs_ShadedShape::FillTriangles (aShapeDraw,
612 aDrawer->ShadingAspect()->Aspect()->ToMapTexture()
613 && !aDrawer->ShadingAspect()->Aspect()->TextureMap().IsNull(),
614 myUVOrigin, myUVRepeat, myUVScale);
9c86076b 615 if (!aTriangles.IsNull())
616 {
617 if (aShadedGroup.IsNull())
618 {
619 aShadedGroup = Prs3d_Root::NewGroup (thePrs);
620 aShadedGroup->SetClosed (isClosed);
621 }
622 aShadedGroup->SetPrimitivesAspect (aDrawer->ShadingAspect()->Aspect());
623 aShadedGroup->AddPrimitiveArray (aTriangles);
624 }
625
626 if (aDrawer->FaceBoundaryDraw())
627 {
628 Handle(Graphic3d_ArrayOfSegments) aBndSegments = StdPrs_ShadedShape::FillFaceBoundaries (aShapeDraw);
629 if (!aBndSegments.IsNull())
630 {
631 if (aShadedGroup.IsNull())
632 {
633 aShadedGroup = Prs3d_Root::NewGroup (thePrs);
634 aShadedGroup->SetClosed (isClosed);
635 }
636
637 Handle(Graphic3d_AspectLine3d) aBoundaryAspect = aDrawer->FaceBoundaryAspect()->Aspect();
638 aShadedGroup->SetPrimitivesAspect (aBoundaryAspect);
639 aShadedGroup->AddPrimitiveArray (aBndSegments);
640 }
641 }
5bffb882 642 }
643 else
644 {
5ad8c033 645 StdPrs_WFShape::Add (thePrs, aShapeDraw, aDrawer);
ad3217cd 646 }
7f917335 647 aDrawer->SetTypeOfDeflection (aPrevType);
ad3217cd 648 }
649 }
650}
651
652//=======================================================================
653//function : dispatchColors
654//purpose :
655//=======================================================================
9c86076b 656Standard_Boolean AIS_ColoredShape::dispatchColors (const Handle(AIS_ColoredDrawer)& theParentDrawer,
657 const TopoDS_Shape& theShapeToParse,
658 const AIS_DataMapOfShapeDrawer& theShapeDrawerMap,
659 const TopAbs_ShapeEnum theParentType,
660 const Standard_Boolean theIsParentClosed,
661 DataMapOfDrawerCompd* theDrawerOpenedShapePerType,
662 DataMapOfDrawerCompd& theDrawerClosedFaces)
ad3217cd 663{
9c86076b 664 const TopAbs_ShapeEnum aShapeType = theShapeToParse.ShapeType();
665 if (aShapeType == TopAbs_SHAPE)
ad3217cd 666 {
667 return Standard_False;
668 }
669
670 // check own setting of current shape
9c86076b 671 Handle(AIS_ColoredDrawer) aDrawer = theParentDrawer;
672 const Standard_Boolean isOverriden = theShapeDrawerMap.Find (theShapeToParse, aDrawer);
673 if (isOverriden
674 && aDrawer->IsHidden())
675 {
676 return Standard_True;
677 }
678
679 // handle compounds, solids and shells
680 Standard_Boolean isSubOverride = Standard_False;
681 if (aShapeType <= TopAbs_SHELL)
682 {
683 // detect parts of closed solids
684 Standard_Boolean isClosedShell = theParentType == TopAbs_SOLID
685 && aShapeType == TopAbs_SHELL
686 && BRep_Tool::IsClosed (theShapeToParse)
687 && StdPrs_ToolTriangulatedShape::IsTriangulated (theShapeToParse);
688 if (isClosedShell)
689 {
690 for (TopoDS_Iterator aFaceIter (theShapeToParse); aFaceIter.More(); aFaceIter.Next())
691 {
692 const TopoDS_Shape& aFace = aFaceIter.Value();
693 Handle(AIS_ColoredDrawer) aFaceDrawer;
694 if (aFace.ShapeType() == TopAbs_FACE
695 && theShapeDrawerMap.Find (aFace, aFaceDrawer)
696 && aFaceDrawer->IsHidden())
697 {
698 isClosedShell = Standard_False;
699 break;
700 }
701 }
702 }
703
704 for (TopoDS_Iterator aSubShapeIter (theShapeToParse); aSubShapeIter.More(); aSubShapeIter.Next())
705 {
706 const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
707 if (dispatchColors (aDrawer, aSubShape,
708 theShapeDrawerMap, aShapeType,
709 isClosedShell,
710 theDrawerOpenedShapePerType,
711 theDrawerClosedFaces))
712 {
713 isSubOverride = Standard_True;
714 }
715 }
716 return isOverriden || isSubOverride;
717 }
ad3217cd 718
719 // iterate on sub-shapes
720 BRep_Builder aBBuilder;
9c86076b 721 TopoDS_Shape aShapeCopy = theShapeToParse.EmptyCopied();
722 aShapeCopy.Closed (theShapeToParse.Closed());
ad3217cd 723 Standard_Integer nbDef = 0;
9c86076b 724 for (TopoDS_Iterator aSubShapeIter (theShapeToParse); aSubShapeIter.More(); aSubShapeIter.Next())
725 {
726 const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
727 if (dispatchColors (aDrawer, aSubShape,
728 theShapeDrawerMap, aShapeType,
729 theIsParentClosed,
730 theDrawerOpenedShapePerType,
731 theDrawerClosedFaces))
ad3217cd 732 {
733 isSubOverride = Standard_True;
734 }
735 else
736 {
9c86076b 737 aBBuilder.Add (aShapeCopy, aSubShape);
ad3217cd 738 ++nbDef;
739 }
740 }
9c86076b 741 if (aShapeType == TopAbs_FACE || !isSubOverride)
ad3217cd 742 {
9c86076b 743 aShapeCopy = theShapeToParse;
ad3217cd 744 }
745 else if (nbDef == 0)
746 {
747 return isOverriden || isSubOverride; // empty compound
748 }
749
750 // if any of styles is overridden regarding to default one, add rest to map
751 if (isOverriden
752 || (isSubOverride && theParentType != TopAbs_WIRE // avoid drawing edges when vertex color is overridden
753 && theParentType != TopAbs_FACE) // avoid drawing edges of the same color as face
9c86076b 754 || (theParentType <= TopAbs_SHELL && !(isOverriden || isSubOverride))) // bind original shape to default color
ad3217cd 755 {
756 TopoDS_Compound aCompound;
9c86076b 757 DataMapOfDrawerCompd& aDrawerShapeMap = theIsParentClosed
758 && aShapeType == TopAbs_FACE
759 ? theDrawerClosedFaces
760 : theDrawerOpenedShapePerType[(size_t)aShapeType];
761 if (!aDrawerShapeMap.FindFromKey (aDrawer, aCompound))
ad3217cd 762 {
763 aBBuilder.MakeCompound (aCompound);
9c86076b 764 aDrawerShapeMap.Add (aDrawer, aCompound);
ad3217cd 765 }
766 aBBuilder.Add (aCompound, aShapeCopy);
767 }
768 return isOverriden || isSubOverride;
769}
770
5bffb882 771//=======================================================================
772//function : isShapeEntirelyVisible
773//purpose :
774//=======================================================================
775Standard_Boolean AIS_ColoredShape::isShapeEntirelyVisible() const
776{
fb66bb28 777 for (AIS_DataMapOfShapeDrawer::Iterator aMapIter (myShapeColors); aMapIter.More(); aMapIter.Next())
5bffb882 778 {
779 if (aMapIter.Value()->IsHidden())
780 {
781 return Standard_False;
782 }
783 }
784 return Standard_True;
785}
786
787//=======================================================================
788//function : bindSubShapes
789//purpose :
790//=======================================================================
9c86076b 791void AIS_ColoredShape::bindSubShapes (AIS_DataMapOfShapeDrawer& theShapeDrawerMap,
792 const TopoDS_Shape& theKeyShape,
6985e642 793 const Handle(AIS_ColoredDrawer)& theDrawer) const
5bffb882 794{
9c86076b 795 TopAbs_ShapeEnum aShapeWithColorType = theKeyShape.ShapeType();
5bffb882 796 if (aShapeWithColorType == TopAbs_COMPOUND)
797 {
9c86076b 798 theShapeDrawerMap.Bind (theKeyShape, theDrawer);
ad3217cd 799 }
5bffb882 800 else if (aShapeWithColorType == TopAbs_SOLID || aShapeWithColorType == TopAbs_SHELL)
801 {
9c86076b 802 for (TopExp_Explorer anExp (theKeyShape, TopAbs_FACE); anExp.More(); anExp.Next())
5bffb882 803 {
9c86076b 804 if (!theShapeDrawerMap.IsBound (anExp.Current()))
5bffb882 805 {
9c86076b 806 theShapeDrawerMap.Bind (anExp.Current(), theDrawer);
5bffb882 807 }
808 }
809 }
810 else if (aShapeWithColorType == TopAbs_WIRE)
811 {
9c86076b 812 for (TopExp_Explorer anExp (theKeyShape, TopAbs_EDGE); anExp.More(); anExp.Next())
5bffb882 813 {
9c86076b 814 if (!theShapeDrawerMap.IsBound (anExp.Current()))
5bffb882 815 {
9c86076b 816 theShapeDrawerMap.Bind (anExp.Current(), theDrawer);
5bffb882 817 }
818 }
819 }
820 else
821 {
822 // bind single face, edge and vertex
823 // force rebind if required due to the color of single shape has
824 // higher priority than the color of "compound" shape (wire is a
825 // compound of edges, shell is a compound of faces) that contains
826 // this single shape.
9c86076b 827 theShapeDrawerMap.Bind (theKeyShape, theDrawer);
5bffb882 828 }
ad3217cd 829}