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