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