// Created on: 2014-04-24 // Created by: Kirill Gavrilov // Copyright (c) 2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include IMPLEMENT_STANDARD_RTTIEXT(AIS_ColoredShape,AIS_Shape) IMPLEMENT_STANDARD_RTTIEXT(AIS_ColoredDrawer,Prs3d_Drawer) namespace { //! Collect all sub-compounds into map. static void collectSubCompounds (TopTools_MapOfShape& theMap, const TopoDS_Shape& theShape) { for (TopoDS_Iterator aChildIter (theShape); aChildIter.More(); aChildIter.Next()) { const TopoDS_Shape& aShape = aChildIter.Value(); if (aShape.ShapeType() == TopAbs_COMPOUND && theMap.Add (aShape)) { collectSubCompounds (theMap, aShape); } } } } //======================================================================= //function : AIS_ColoredShape //purpose : //======================================================================= AIS_ColoredShape::AIS_ColoredShape (const TopoDS_Shape& theShape) : AIS_Shape (theShape) { // disable dedicated line aspects myDrawer->SetFreeBoundaryAspect (myDrawer->LineAspect()); myDrawer->SetUnFreeBoundaryAspect(myDrawer->LineAspect()); myDrawer->SetSeenLineAspect (myDrawer->LineAspect()); myDrawer->SetFaceBoundaryAspect (myDrawer->LineAspect()); } //======================================================================= //function : AIS_ColoredShape //purpose : //======================================================================= AIS_ColoredShape::AIS_ColoredShape (const Handle(AIS_Shape)& theShape) : AIS_Shape (theShape->Shape()) { // disable dedicated line aspects myDrawer->SetFreeBoundaryAspect (myDrawer->LineAspect()); myDrawer->SetUnFreeBoundaryAspect(myDrawer->LineAspect()); myDrawer->SetSeenLineAspect (myDrawer->LineAspect()); myDrawer->SetFaceBoundaryAspect (myDrawer->LineAspect()); if (theShape->HasMaterial()) { SetMaterial (theShape->Material()); } if (theShape->HasColor()) { Quantity_Color aColor; theShape->Color (aColor); SetColor (aColor); } if (theShape->HasWidth()) { SetWidth (theShape->Width()); } if (theShape->IsTransparent()) { SetTransparency (theShape->Transparency()); } } //======================================================================= //function : CustomAspects //purpose : //======================================================================= Handle(AIS_ColoredDrawer) AIS_ColoredShape::CustomAspects (const TopoDS_Shape& theShape) { Handle(AIS_ColoredDrawer) aDrawer; myShapeColors.Find (theShape, aDrawer); if (aDrawer.IsNull()) { aDrawer = new AIS_ColoredDrawer (myDrawer); myShapeColors.Bind (theShape, aDrawer); SetToUpdate(); } return aDrawer; } //======================================================================= //function : ClearCustomAspects //purpose : //======================================================================= void AIS_ColoredShape::ClearCustomAspects() { if (myShapeColors.IsEmpty()) { return; } myShapeColors.Clear(); SetToUpdate(); } //======================================================================= //function : UnsetCustomAspects //purpose : //======================================================================= void AIS_ColoredShape::UnsetCustomAspects (const TopoDS_Shape& theShape, const Standard_Boolean theToUnregister) { if (!myShapeColors.IsBound (theShape)) { return; } SetToUpdate(); if (theToUnregister) { myShapeColors.UnBind (theShape); return; } myShapeColors.ChangeFind (theShape) = new AIS_ColoredDrawer (myDrawer); } //======================================================================= //function : SetCustomColor //purpose : //======================================================================= void AIS_ColoredShape::SetCustomColor (const TopoDS_Shape& theShape, const Quantity_Color& theColor) { if (theShape.IsNull()) { return; } const Handle(AIS_ColoredDrawer)& aDrawer = CustomAspects (theShape); setColor (aDrawer, theColor); aDrawer->SetOwnColor (theColor); } //======================================================================= //function : SetCustomTransparency //purpose : //======================================================================= void AIS_ColoredShape::SetCustomTransparency (const TopoDS_Shape& theShape, Standard_Real theTransparency) { if (theShape.IsNull()) { return; } const Handle(AIS_ColoredDrawer)& aDrawer = CustomAspects (theShape); setTransparency (aDrawer, theTransparency); aDrawer->SetOwnTransparency (theTransparency); } //======================================================================= //function : SetCustomWidth //purpose : //======================================================================= void AIS_ColoredShape::SetCustomWidth (const TopoDS_Shape& theShape, const Standard_Real theLineWidth) { if (theShape.IsNull()) { return; } const Handle(AIS_ColoredDrawer)& aDrawer = CustomAspects (theShape); setWidth (aDrawer, theLineWidth); aDrawer->SetOwnWidth (theLineWidth); } //======================================================================= //function : SetColor //purpose : //======================================================================= void AIS_ColoredShape::SetColor (const Quantity_Color& theColor) { for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next()) { const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value(); if (aDrawer->HasOwnColor()) { continue; } if (aDrawer->HasOwnShadingAspect()) { aDrawer->ShadingAspect()->SetColor (theColor, myCurrentFacingModel); } if (aDrawer->HasOwnLineAspect()) { aDrawer->LineAspect()->SetColor (theColor); } if (aDrawer->HasOwnWireAspect()) { aDrawer->WireAspect()->SetColor (theColor); } if (aDrawer->HasOwnFaceBoundaryAspect()) { aDrawer->FaceBoundaryAspect()->SetColor (theColor); } } AIS_Shape::SetColor (theColor); } //======================================================================= //function : SetWidth //purpose : //======================================================================= void AIS_ColoredShape::SetWidth (const Standard_Real theLineWidth) { for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next()) { const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value(); if (aDrawer->HasOwnWidth()) { continue; } if (aDrawer->HasOwnLineAspect()) { aDrawer->LineAspect()->SetWidth (theLineWidth); } if (aDrawer->HasOwnWireAspect()) { aDrawer->WireAspect()->SetWidth (theLineWidth); } if (aDrawer->HasOwnFaceBoundaryAspect()) { aDrawer->FaceBoundaryAspect()->SetWidth (theLineWidth); } } AIS_Shape::SetWidth (theLineWidth); } //======================================================================= //function : UnsetWidth //purpose : //======================================================================= void AIS_ColoredShape::UnsetWidth() { SetWidth (1.0f); } //======================================================================= //function : SetTransparency //purpose : //======================================================================= void AIS_ColoredShape::SetTransparency (const Standard_Real theValue) { for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next()) { const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value(); if (aDrawer->HasOwnTransparency()) { continue; } if (aDrawer->HasOwnShadingAspect()) { aDrawer->ShadingAspect()->SetTransparency (theValue, myCurrentFacingModel); } } AIS_Shape::SetTransparency (theValue); } //======================================================================= //function : UnsetTransparency //purpose : //======================================================================= void AIS_ColoredShape::UnsetTransparency() { SetTransparency (0.0f); } //======================================================================= //function : SetMaterial //purpose : //======================================================================= void AIS_ColoredShape::SetMaterial (const Graphic3d_MaterialAspect& theMaterial) { for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next()) { const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value(); if (aDrawer->HasOwnMaterial()) { continue; } if (aDrawer->HasOwnShadingAspect()) { setMaterial (aDrawer, theMaterial, aDrawer->HasOwnColor(), aDrawer->HasOwnTransparency()); } } AIS_Shape::SetMaterial (theMaterial); } //======================================================================= //function : Compute //purpose : //======================================================================= void AIS_ColoredShape::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr, const Handle(Prs3d_Presentation)& thePrs, const Standard_Integer theMode) { if (myshape.IsNull()) { return; } if (IsInfinite()) { thePrs->SetInfiniteState (Standard_True); } switch (theMode) { case AIS_WireFrame: { StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (myshape, myDrawer, Standard_True); // After this call if type of deflection is relative // computed deflection coefficient is stored as absolute. StdPrs_ToolTriangulatedShape::GetDeflection (myshape, myDrawer); break; } case AIS_Shaded: { if (myDrawer->IsAutoTriangulation()) { // compute mesh for entire shape beforehand to ensure consistency and optimizations (parallelization) StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (myshape, myDrawer, Standard_True); // After this call if type of deflection is relative // computed deflection coefficient is stored as absolute. Standard_Boolean wasRecomputed = StdPrs_ToolTriangulatedShape::Tessellate (myshape, myDrawer); // Set to update wireframe presentation on triangulation. if (myDrawer->IsoOnTriangulation() && wasRecomputed) { SetToUpdate (AIS_WireFrame); } } break; } case 2: { AIS_Shape::Compute (thePrsMgr, thePrs, theMode); return; } default: { return; } } // Extract myShapeColors map (KeyshapeColored -> Color) to subshapes map (Subshape -> Color). // This needed when colored shape is not part of BaseShape (but subshapes are) and actually container for subshapes. AIS_DataMapOfShapeDrawer aSubshapeDrawerMap; fillSubshapeDrawerMap (aSubshapeDrawerMap); Handle(AIS_ColoredDrawer) aBaseDrawer; myShapeColors.Find (myshape, aBaseDrawer); // myShapeColors + anOpened --> array[TopAbs_ShapeEnum] of map of color-to-compound DataMapOfDrawerCompd aDispatchedOpened[(size_t)TopAbs_SHAPE]; DataMapOfDrawerCompd aDispatchedClosed; dispatchColors (aBaseDrawer, myshape, aSubshapeDrawerMap, TopAbs_COMPOUND, Standard_False, aDispatchedOpened, theMode == AIS_Shaded ? aDispatchedClosed : aDispatchedOpened[TopAbs_FACE]); addShapesWithCustomProps (thePrs, aDispatchedOpened, aDispatchedClosed, theMode); } //======================================================================= //function : fillSubshapeDrawerMap //purpose : //======================================================================= void AIS_ColoredShape::fillSubshapeDrawerMap (AIS_DataMapOfShapeDrawer& theSubshapeDrawerMap) const { // unroll compounds specified for grouping sub-shapes with the same style // (e.g. the compounds that are not a part of the main shape) TopTools_MapOfShape aMapOfOwnCompounds; if (myshape.ShapeType() == TopAbs_COMPOUND) { aMapOfOwnCompounds.Add (myshape); collectSubCompounds (aMapOfOwnCompounds, myshape); } for (AIS_DataMapOfShapeDrawer::Iterator aKeyShapeIter (myShapeColors); aKeyShapeIter.More(); aKeyShapeIter.Next()) { const TopoDS_Shape& aKeyShape = aKeyShapeIter.Key(); if (aKeyShape.ShapeType() != TopAbs_COMPOUND || aMapOfOwnCompounds.Contains (aKeyShape)) { continue; } for (TopoDS_Iterator aChildIter (aKeyShape); aChildIter.More(); aChildIter.Next()) { const TopoDS_Shape& aShape = aChildIter.Value(); if (!myShapeColors.IsBound (aShape)) { bindSubShapes (theSubshapeDrawerMap, aShape, aKeyShapeIter.Value()); } } } // assign other sub-shapes with styles for (AIS_DataMapOfShapeDrawer::Iterator aKeyShapeIter (myShapeColors); aKeyShapeIter.More(); aKeyShapeIter.Next()) { const TopoDS_Shape& aKeyShape = aKeyShapeIter.Key(); if (myshape == aKeyShape || (aKeyShape.ShapeType() == TopAbs_COMPOUND && !aMapOfOwnCompounds.Contains (aKeyShape))) { continue; } bindSubShapes (theSubshapeDrawerMap, aKeyShape, aKeyShapeIter.Value()); } } //======================================================================= //function : ComputeSelection //purpose : //======================================================================= void AIS_ColoredShape::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection, const Standard_Integer theMode) { if (myshape.IsNull()) { return; } else if (isShapeEntirelyVisible()) { base_type::ComputeSelection (theSelection, theMode); return; } const TopAbs_ShapeEnum aTypOfSel = AIS_Shape::SelectionType (theMode); const Standard_Real aDeflection = StdPrs_ToolTriangulatedShape::GetDeflection (myshape, myDrawer); const Standard_Real aDeviationAngle = myDrawer->DeviationAngle(); const Standard_Integer aPriority = StdSelect_BRepSelectionTool::GetStandardPriority (myshape, aTypOfSel); if (myDrawer->IsAutoTriangulation() && !BRepTools::Triangulation (myshape, Precision::Infinite())) { BRepMesh_IncrementalMesh aMesher (myshape, aDeflection, Standard_False, aDeviationAngle); } AIS_DataMapOfShapeDrawer aSubshapeDrawerMap; fillSubshapeDrawerMap (aSubshapeDrawerMap); Handle(StdSelect_BRepOwner) aBrepOwner = new StdSelect_BRepOwner (myshape, aPriority); if (aTypOfSel == TopAbs_SHAPE) { aBrepOwner = new StdSelect_BRepOwner (myshape, aPriority); } Handle(AIS_ColoredDrawer) aBaseDrawer; myShapeColors.Find (myshape, aBaseDrawer); computeSubshapeSelection (aBaseDrawer, aSubshapeDrawerMap, myshape, aBrepOwner, theSelection, aTypOfSel, aPriority, aDeflection, aDeviationAngle); Handle(SelectMgr_SelectableObject) aThis (this); for (NCollection_Vector::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next()) { const Handle(SelectMgr_EntityOwner)& anOwner = aSelEntIter.Value()->BaseSensitive()->OwnerId(); anOwner->SetSelectable (aThis); } StdSelect_BRepSelectionTool::PreBuildBVH (theSelection); } //======================================================================= //function : computeSubshapeSelection //purpose : //======================================================================= void AIS_ColoredShape::computeSubshapeSelection (const Handle(AIS_ColoredDrawer)& theParentDrawer, const AIS_DataMapOfShapeDrawer& theShapeDrawerMap, const TopoDS_Shape& theShape, const Handle(StdSelect_BRepOwner)& theOwner, const Handle(SelectMgr_Selection)& theSelection, const TopAbs_ShapeEnum theTypOfSel, const Standard_Integer thePriority, const Standard_Real theDeflection, const Standard_Real theDeflAngle) { Handle(AIS_ColoredDrawer) aDrawer = theParentDrawer; theShapeDrawerMap.Find (theShape, aDrawer); if (!aDrawer.IsNull() && aDrawer->IsHidden()) { return; } const Standard_Integer aNbPOnEdge = 9; const Standard_Real aMaximalParameter = 500.0; if (theTypOfSel == TopAbs_SHAPE && theShape.ShapeType() >= TopAbs_FACE) { StdSelect_BRepSelectionTool::ComputeSensitive (theShape, theOwner, theSelection, theDeflection, theDeflAngle, aNbPOnEdge, aMaximalParameter, myDrawer->IsAutoTriangulation()); return; } else if (theShape.ShapeType() == theTypOfSel) { const Standard_Boolean isComesFromDecomposition = !theShape.IsEqual (myshape); Handle(StdSelect_BRepOwner) aBrepOwner = new StdSelect_BRepOwner (theShape, thePriority, isComesFromDecomposition); StdSelect_BRepSelectionTool::ComputeSensitive (theShape, aBrepOwner, theSelection, theDeflection, theDeflAngle, aNbPOnEdge, aMaximalParameter, myDrawer->IsAutoTriangulation()); return; } for (TopoDS_Iterator aSubShapeIter (theShape); aSubShapeIter.More(); aSubShapeIter.Next()) { const TopoDS_Shape& aSubShape = aSubShapeIter.Value(); computeSubshapeSelection (aDrawer, theShapeDrawerMap, aSubShape, theOwner, theSelection, theTypOfSel, thePriority, theDeflection, theDeflAngle); } } //======================================================================= //function : addShapesWithCustomProps //purpose : //======================================================================= void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation)& thePrs, const DataMapOfDrawerCompd* theDrawerOpenedShapePerType, const DataMapOfDrawerCompd& theDrawerClosedFaces, const Standard_Integer theMode) { Handle(Graphic3d_Group) anOpenGroup, aClosedGroup, anEdgesGroup; for (size_t aShType = 0; aShType <= (size_t )TopAbs_SHAPE; ++aShType) { const Standard_Boolean isClosed = aShType == TopAbs_SHAPE; Handle(Graphic3d_Group)& aShadedGroup = isClosed ? aClosedGroup : anOpenGroup; const DataMapOfDrawerCompd& aDrawerShapeMap = isClosed ? theDrawerClosedFaces : theDrawerOpenedShapePerType[aShType]; for (DataMapOfDrawerCompd::Iterator aMapIter (aDrawerShapeMap); aMapIter.More(); aMapIter.Next()) { const Handle(AIS_ColoredDrawer)& aCustomDrawer = aMapIter.Key(); const TopoDS_Compound& aShapeDraw = aMapIter.Value(); // compound of subshapes with type Handle(Prs3d_Drawer) aDrawer; if (!aCustomDrawer.IsNull()) { aDrawer = aCustomDrawer; if (aCustomDrawer->IsHidden()) { continue; } } else { aDrawer = myDrawer; } // It is supposed that absolute deflection contains previously computed relative deflection // (if deflection type is relative). // In case of CustomDrawer it is taken from Link(). Aspect_TypeOfDeflection aPrevType = aDrawer->TypeOfDeflection(); aDrawer->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE); // Draw each kind of subshapes and personal-colored shapes in a separate group // since it's necessary to set transparency/material for all subshapes // without affecting their unique colors if (theMode == AIS_Shaded && aShapeDraw.ShapeType() <= TopAbs_FACE && !IsInfinite()) { // add wireframe presentation for isolated edges and vertices StdPrs_ShadedShape::AddWireframeForFreeElements (thePrs, aShapeDraw, aDrawer); // add special wireframe presentation for faces without triangulation StdPrs_ShadedShape::AddWireframeForFacesWithoutTriangles (thePrs, aShapeDraw, aDrawer); Handle(Graphic3d_ArrayOfTriangles) aTriangles = StdPrs_ShadedShape::FillTriangles (aShapeDraw, aDrawer->ShadingAspect()->Aspect()->ToMapTexture() && !aDrawer->ShadingAspect()->Aspect()->TextureMap().IsNull(), myUVOrigin, myUVRepeat, myUVScale); if (!aTriangles.IsNull()) { if (aShadedGroup.IsNull()) { aShadedGroup = thePrs->NewGroup(); aShadedGroup->SetClosed (isClosed); } aShadedGroup->SetPrimitivesAspect (aDrawer->ShadingAspect()->Aspect()); aShadedGroup->AddPrimitiveArray (aTriangles); } if (aDrawer->FaceBoundaryDraw()) { if (Handle(Graphic3d_ArrayOfSegments) aBndSegments = StdPrs_ShadedShape::FillFaceBoundaries (aShapeDraw, aDrawer->FaceBoundaryUpperContinuity())) { if (anEdgesGroup.IsNull()) { anEdgesGroup = thePrs->NewGroup(); } anEdgesGroup->SetPrimitivesAspect (aDrawer->FaceBoundaryAspect()->Aspect()); anEdgesGroup->AddPrimitiveArray (aBndSegments); } } } else { StdPrs_WFShape::Add (thePrs, aShapeDraw, aDrawer); } aDrawer->SetTypeOfDeflection (aPrevType); } } } //======================================================================= //function : dispatchColors //purpose : //======================================================================= Standard_Boolean AIS_ColoredShape::dispatchColors (const Handle(AIS_ColoredDrawer)& theParentDrawer, const TopoDS_Shape& theShapeToParse, const AIS_DataMapOfShapeDrawer& theShapeDrawerMap, const TopAbs_ShapeEnum theParentType, const Standard_Boolean theIsParentClosed, DataMapOfDrawerCompd* theDrawerOpenedShapePerType, DataMapOfDrawerCompd& theDrawerClosedFaces) { const TopAbs_ShapeEnum aShapeType = theShapeToParse.ShapeType(); if (aShapeType == TopAbs_SHAPE) { return Standard_False; } // check own setting of current shape Handle(AIS_ColoredDrawer) aDrawer = theParentDrawer; const Standard_Boolean isOverriden = theShapeDrawerMap.Find (theShapeToParse, aDrawer); if (isOverriden && aDrawer->IsHidden()) { return Standard_True; } // handle compounds, solids and shells Standard_Boolean isSubOverride = Standard_False; if (aShapeType <= TopAbs_SHELL) { // detect parts of closed solids Standard_Boolean isClosedShell = theParentType == TopAbs_SOLID && aShapeType == TopAbs_SHELL && BRep_Tool::IsClosed (theShapeToParse) && StdPrs_ToolTriangulatedShape::IsTriangulated (theShapeToParse); if (isClosedShell) { for (TopoDS_Iterator aFaceIter (theShapeToParse); aFaceIter.More(); aFaceIter.Next()) { const TopoDS_Shape& aFace = aFaceIter.Value(); Handle(AIS_ColoredDrawer) aFaceDrawer; if (aFace.ShapeType() != TopAbs_FACE || !theShapeDrawerMap.Find (aFace, aFaceDrawer)) { continue; } if (aFaceDrawer->IsHidden()) { isClosedShell = Standard_False; break; } else if (aFaceDrawer->HasOwnShadingAspect() && aFaceDrawer->ShadingAspect()->Aspect()->AlphaMode() != Graphic3d_AlphaMode_Opaque) { if (aFaceDrawer->ShadingAspect()->Aspect()->AlphaMode() != Graphic3d_AlphaMode_BlendAuto || aFaceDrawer->ShadingAspect()->Aspect()->FrontMaterial().Alpha() < 1.0f || (aFaceDrawer->ShadingAspect()->Aspect()->Distinguish() && aFaceDrawer->ShadingAspect()->Aspect()->BackMaterial().Alpha() < 1.0f)) { isClosedShell = Standard_False; break; } } } } for (TopoDS_Iterator aSubShapeIter (theShapeToParse); aSubShapeIter.More(); aSubShapeIter.Next()) { const TopoDS_Shape& aSubShape = aSubShapeIter.Value(); if (dispatchColors (aDrawer, aSubShape, theShapeDrawerMap, aShapeType, isClosedShell, theDrawerOpenedShapePerType, theDrawerClosedFaces)) { isSubOverride = Standard_True; } } return isOverriden || isSubOverride; } // iterate on sub-shapes BRep_Builder aBBuilder; TopoDS_Shape aShapeCopy = theShapeToParse.EmptyCopied(); aShapeCopy.Closed (theShapeToParse.Closed()); Standard_Integer nbDef = 0; for (TopoDS_Iterator aSubShapeIter (theShapeToParse); aSubShapeIter.More(); aSubShapeIter.Next()) { const TopoDS_Shape& aSubShape = aSubShapeIter.Value(); if (dispatchColors (aDrawer, aSubShape, theShapeDrawerMap, aShapeType, theIsParentClosed, theDrawerOpenedShapePerType, theDrawerClosedFaces)) { isSubOverride = Standard_True; } else { aBBuilder.Add (aShapeCopy, aSubShape); ++nbDef; } } if (aShapeType == TopAbs_FACE || !isSubOverride) { aShapeCopy = theShapeToParse; } else if (nbDef == 0) { return isOverriden || isSubOverride; // empty compound } // if any of styles is overridden regarding to default one, add rest to map if (isOverriden || (isSubOverride && theParentType != TopAbs_WIRE // avoid drawing edges when vertex color is overridden && theParentType != TopAbs_FACE) // avoid drawing edges of the same color as face || (theParentType <= TopAbs_SHELL && !(isOverriden || isSubOverride))) // bind original shape to default color { TopoDS_Compound aCompound; DataMapOfDrawerCompd& aDrawerShapeMap = theIsParentClosed && aShapeType == TopAbs_FACE ? theDrawerClosedFaces : theDrawerOpenedShapePerType[(size_t)aShapeType]; if (!aDrawerShapeMap.FindFromKey (aDrawer, aCompound)) { aBBuilder.MakeCompound (aCompound); aDrawerShapeMap.Add (aDrawer, aCompound); } aBBuilder.Add (aCompound, aShapeCopy); } return isOverriden || isSubOverride; } //======================================================================= //function : isShapeEntirelyVisible //purpose : //======================================================================= Standard_Boolean AIS_ColoredShape::isShapeEntirelyVisible() const { for (AIS_DataMapOfShapeDrawer::Iterator aMapIter (myShapeColors); aMapIter.More(); aMapIter.Next()) { if (aMapIter.Value()->IsHidden()) { return Standard_False; } } return Standard_True; } //======================================================================= //function : bindSubShapes //purpose : //======================================================================= void AIS_ColoredShape::bindSubShapes (AIS_DataMapOfShapeDrawer& theShapeDrawerMap, const TopoDS_Shape& theKeyShape, const Handle(AIS_ColoredDrawer)& theDrawer) const { TopAbs_ShapeEnum aShapeWithColorType = theKeyShape.ShapeType(); if (aShapeWithColorType == TopAbs_COMPOUND) { theShapeDrawerMap.Bind (theKeyShape, theDrawer); } else if (aShapeWithColorType == TopAbs_SOLID || aShapeWithColorType == TopAbs_SHELL) { for (TopExp_Explorer anExp (theKeyShape, TopAbs_FACE); anExp.More(); anExp.Next()) { if (!theShapeDrawerMap.IsBound (anExp.Current())) { theShapeDrawerMap.Bind (anExp.Current(), theDrawer); } } } else if (aShapeWithColorType == TopAbs_WIRE) { for (TopExp_Explorer anExp (theKeyShape, TopAbs_EDGE); anExp.More(); anExp.Next()) { if (!theShapeDrawerMap.IsBound (anExp.Current())) { theShapeDrawerMap.Bind (anExp.Current(), theDrawer); } } } else { // bind single face, edge and vertex // force rebind if required due to the color of single shape has // higher priority than the color of "compound" shape (wire is a // compound of edges, shell is a compound of faces) that contains // this single shape. theShapeDrawerMap.Bind (theKeyShape, theDrawer); } }