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