X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModuleBase%2FModuleBase_ResultPrs.cpp;h=9d3a5c616c0662116967b4c7d7057910804bef7e;hb=b8b95142d694359c9c4fbd2766f04815ad4aa4d6;hp=63a571ca7e25a2c4671a8e402cb6cb8b49170688;hpb=a4c5ad394d277931acdbf98e8cae94d0752032af;p=modules%2Fshaper.git diff --git a/src/ModuleBase/ModuleBase_ResultPrs.cpp b/src/ModuleBase/ModuleBase_ResultPrs.cpp old mode 100755 new mode 100644 index 63a571ca7..9d3a5c616 --- a/src/ModuleBase/ModuleBase_ResultPrs.cpp +++ b/src/ModuleBase/ModuleBase_ResultPrs.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2020 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -12,30 +12,34 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or -// email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "ModuleBase_ResultPrs.h" +#include "ModuleBase_IViewer.h" #include +#include #include #include #include -#include +#include +#include #include "ModuleBase_Tools.h" #include "ModuleBase_BRepOwner.h" #include #include +#include #include #include #include +#include #include #include #include @@ -43,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +58,8 @@ #include #include #include +#include +#include //******************************************************************************************* @@ -62,28 +69,95 @@ IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_ResultPrs, ViewerData_AISShape); //******************************************************************** ModuleBase_ResultPrs::ModuleBase_ResultPrs(ResultPtr theResult) - : ViewerData_AISShape(TopoDS_Shape()), myResult(theResult), myAdditionalSelectionPriority(0), - myTransparency(1) + : ViewerData_AISShape(TopoDS_Shape()), + myResult(theResult), + myIsSubstituted(false), + myTransparency(1), + myAdditionalSelectionPriority(0) { - std::shared_ptr aShapePtr = ModelAPI_Tools::shape(theResult); + + GeomShapePtr aShapePtr = ModelAPI_Tools::shape(theResult); TopoDS_Shape aShape = aShapePtr->impl(); + // Workaround for Sketch subshapes which has no discrete representation + // until sketch faces are built and displayed. + // Thus, perform discretization of such edges. + if (theResult->groupName() == ModelAPI_ResultConstruction::group() && + aShape.ShapeType() == TopAbs_EDGE) { + GeomEdgePtr anEdgePtr = GeomEdgePtr(new GeomAPI_Edge(aShapePtr)); + if (anEdgePtr->isCircle() || anEdgePtr->isArc()) { + TopoDS_Edge anEdge = TopoDS::Edge(aShape); + TopLoc_Location aLoc; + Handle(Poly_Polygon3D) aPoly3D = BRep_Tool::Polygon3D(anEdge, aLoc); + if (aPoly3D.IsNull()) { + double aDeflection = Config_PropManager::real("Visualization", "construction_deflection"); + BRepMesh_IncrementalMesh(aShape, aDeflection); + } + } + } Set(aShape); + + // Activate individual repaintng if this is a part of compsolid + ResultBodyPtr aResOwner = ModelAPI_Tools::bodyOwner(myResult); + SetAutoHilight(aResOwner.get() == NULL); + + // Set own free boundaries aspect in order to have free + // and unfree boundaries with different colors Handle(Prs3d_Drawer) aDrawer = Attributes(); + aDrawer->SetUnFreeBoundaryAspect( + new Prs3d_LineAspect(Quantity_NOC_YELLOW, Aspect_TOL_SOLID, 1)); + aDrawer->SetFreeBoundaryAspect(new Prs3d_LineAspect(Quantity_NOC_GREEN, Aspect_TOL_SOLID, 1)); + aDrawer->SetFaceBoundaryAspect(new Prs3d_LineAspect(Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1)); + + Quantity_Color aColor; + Color(aColor); + + std::vector aIsoValues; + bool isIsoVisible; + ModelAPI_Tools::getIsoLines(myResult, isIsoVisible, aIsoValues); + if (isIsoVisible) { + if (aIsoValues.size() == 0) { + aIsoValues.push_back(1); + aIsoValues.push_back(1); + } + } + else { + aIsoValues.push_back(0); + aIsoValues.push_back(0); + } + myUIsoAspect = new Prs3d_IsoAspect(aColor, Aspect_TOL_SOLID, 1, aIsoValues[0]); + myVIsoAspect = new Prs3d_IsoAspect(aColor, Aspect_TOL_SOLID, 1, aIsoValues[1]); + aDrawer->SetUIsoAspect(myUIsoAspect); + aDrawer->SetVIsoAspect(myVIsoAspect); + if (aDrawer->HasOwnPointAspect()) aDrawer->PointAspect()->SetTypeOfMarker(Aspect_TOM_PLUS); else aDrawer->SetPointAspect(new Prs3d_PointAspect(Aspect_TOM_PLUS, Quantity_NOC_YELLOW, 1.)); - // Activate individual repaintng if this is a part of compsolid - ResultCompSolidPtr aCompSolid = ModelAPI_Tools::compSolidOwner(myResult); - SetAutoHilight(aCompSolid.get() == NULL); + aDrawer = DynamicHilightAttributes(); + if (aDrawer.IsNull()) { + if (!ModuleBase_IViewer::DefaultHighlightDrawer.IsNull()) { + aDrawer = new Prs3d_Drawer(*ModuleBase_IViewer::DefaultHighlightDrawer); + aDrawer->SetUIsoAspect(myUIsoAspect); + aDrawer->SetVIsoAspect(myVIsoAspect); + SetDynamicHilightAttributes(aDrawer); + } + } - myHiddenSubShapesDrawer = new AIS_ColoredDrawer (myDrawer); + myHiddenSubShapesDrawer = new AIS_ColoredDrawer(myDrawer); Handle(Prs3d_ShadingAspect) aShadingAspect = new Prs3d_ShadingAspect(); aShadingAspect->SetMaterial(Graphic3d_NOM_BRASS); //default value of context material + aShadingAspect->Aspect()->SetEdgeColor(Quantity_NOC_BLACK); myHiddenSubShapesDrawer->SetShadingAspect(aShadingAspect); ModuleBase_Tools::setPointBallHighlighting(this); + + // Define colors for wireframe mode + setEdgesDefaultColor(); + + ModuleBase_Tools::setDefaultDeviationCoefficient(Shape(), DynamicHilightAttributes()); + ModuleBase_Tools::setDefaultDeviationCoefficient(Shape(), Attributes()); + Attributes()->UpdatePreviousDeviationCoefficient(); } //******************************************************************** @@ -97,65 +171,84 @@ void ModuleBase_ResultPrs::SetColor (const Quantity_Color& theColor) { ViewerData_AISShape::SetColor(theColor); myHiddenSubShapesDrawer->ShadingAspect()->SetColor (theColor, myCurrentFacingModel); + setEdgesDefaultColor(); + myUIsoAspect->SetColor(theColor); + myVIsoAspect->SetColor(theColor); } -//******************************************************************** -bool ModuleBase_ResultPrs::setSubShapeHidden(const NCollection_List& theShapes) +void ModuleBase_ResultPrs::setEdgesDefaultColor() { - bool isModified = false; + if (myResult.get()) { + AttributeIntArrayPtr aColorAttr = myResult->data()->intArray(ModelAPI_Result::COLOR_ID()); + bool aHasColor = aColorAttr.get() && aColorAttr->isInitialized(); + + Handle(Prs3d_Drawer) aDrawer = Attributes(); + aDrawer->SetFaceBoundaryDraw(Standard_True); + aDrawer->FaceBoundaryAspect()->SetColor(Quantity_NOC_BLACK); + + if (!aHasColor) { + aDrawer->UnFreeBoundaryAspect()->SetColor(Quantity_NOC_YELLOW); + aDrawer->FreeBoundaryAspect()->SetColor(Quantity_NOC_GREEN); + aDrawer->WireAspect()->SetColor(Quantity_NOC_RED); + + aDrawer->SetUnFreeBoundaryDraw(Standard_True); + aDrawer->SetFreeBoundaryDraw(Standard_True); + aDrawer->SetWireDraw(Standard_True); + } + } +} + +//******************************************************************** +void ModuleBase_ResultPrs::setSubShapeHidden(const TopoDS_ListOfShape& theShapes) +{ TopoDS_Compound aCompound; BRep_Builder aBBuilder; aBBuilder.MakeCompound (aCompound); - // restore hidden shapes if there are not the shapes in parameter container - NCollection_List aVisibleSubShapes; - for (NCollection_List::Iterator aHiddenIt(myHiddenSubShapes); aHiddenIt.More(); - aHiddenIt.Next()) { - if (!theShapes.Contains(aHiddenIt.Value())) - aVisibleSubShapes.Append(aHiddenIt.Value()); - else - aBBuilder.Add (aCompound, aHiddenIt.Value()); - } - isModified = !aVisibleSubShapes.IsEmpty(); - for (NCollection_List::Iterator aVisibleIt(aVisibleSubShapes); aVisibleIt.More(); - aVisibleIt.Next()) - myHiddenSubShapes.Remove(aVisibleIt.Value()); - - // append hidden shapes into internal container if there are not these shapes - for (NCollection_List::Iterator aShapeIt(theShapes); aShapeIt.More(); - aShapeIt.Next()) - { - if (aShapeIt.Value().ShapeType() != TopAbs_FACE) // only face shape can be hidden - continue; - - if (!myHiddenSubShapes.Contains(aShapeIt.Value())) { - myHiddenSubShapes.Append(aShapeIt.Value()); - aBBuilder.Add (aCompound, aShapeIt.Value()); - isModified = true; - } + + myHiddenSubShapes = theShapes; + collectSubShapes(aBBuilder, aCompound, myOriginalShape, myHiddenSubShapes); + myVisibleCompound = aCompound; + + aBBuilder.MakeCompound (aCompound); + TopoDS_ListOfShape::Iterator aIt(myHiddenSubShapes); + for (; aIt.More(); aIt.Next()) { + aBBuilder.Add(aCompound, aIt.Value()); } myHiddenCompound = aCompound; - return isModified; } //******************************************************************** -bool ModuleBase_ResultPrs::hasSubShapeVisible(const TopoDS_Shape& theShape) +bool ModuleBase_ResultPrs::isSubShapeHidden(const TopoDS_Shape& theShape) { - int aNbOfHiddenSubShapes = myHiddenSubShapes.Size(); - - if (!myHiddenSubShapes.Contains(theShape)) - aNbOfHiddenSubShapes++; // the shape to be hidden later - - TopExp_Explorer anExp(myOriginalShape, TopAbs_FACE); - bool aHasVisibleShape = false; - for(TopExp_Explorer anExp(myOriginalShape, TopAbs_FACE); anExp.More() && !aHasVisibleShape; - anExp.Next()) - { - aNbOfHiddenSubShapes--; - if (aNbOfHiddenSubShapes < 0) - aHasVisibleShape = true; + if (theShape.IsNull() || theShape.ShapeType() != TopAbs_FACE) // only face shape can be hidden + return false; + + // orientation of parameter shape(come from selection) may be wrong, check isEqual() to be sure + TopoDS_ListOfShape::Iterator aShapeIt(myHiddenSubShapes); + for (; aShapeIt.More(); aShapeIt.Next()) { + if (theShape.IsSame(aShapeIt.Value())) + return true; } - return aHasVisibleShape; + + return true; +} + +//******************************************************************** +bool ModuleBase_ResultPrs::hasSubShapeVisible( + const TopoDS_ListOfShape& theShapesToSkip) +{ + TopoDS_Compound aCompound; + BRep_Builder aBuilder; + aBuilder.MakeCompound (aCompound); + TopoDS_ListOfShape aShapesToSkip; + TopoDS_ListOfShape aHiddenCopy(myHiddenSubShapes); + aShapesToSkip.Append(aHiddenCopy); + for (TopoDS_ListOfShape::Iterator anIt(theShapesToSkip); anIt.More(); anIt.Next()) + aShapesToSkip.Append(anIt.Value()); + + collectSubShapes(aBuilder, aCompound, myOriginalShape, aShapesToSkip); + return !BOPTools_AlgoTools3D::IsEmptyShape(aCompound); } //******************************************************************** @@ -175,45 +268,86 @@ void ModuleBase_ResultPrs::Compute( const Handle(Prs3d_Presentation)& thePresentation, const Standard_Integer theMode) { - std::shared_ptr aShapePtr = ModelAPI_Tools::shape(myResult); + std::shared_ptr aShapePtr = myResult->shape(); bool aReadyToDisplay = aShapePtr.get(); if (aReadyToDisplay) { myOriginalShape = aShapePtr->impl(); if (myHiddenSubShapes.IsEmpty() || myOriginalShape.ShapeType() > TopAbs_FACE ) { - if (!myOriginalShape.IsNull()) + if (!myOriginalShape.IsNull()) { Set(myOriginalShape); + myIsSubstituted = false; + } } else { // convert shape into SHELL - TopoDS_Shell aShell; - BRep_Builder aShellBuilder; - aShellBuilder.MakeShell(aShell); - bool isEmptyShape = true; - for(TopExp_Explorer anExp(myOriginalShape, TopAbs_FACE); anExp.More(); anExp.Next()) { - if (myHiddenSubShapes.Contains(anExp.Current())) - continue; - aShellBuilder.Add(aShell, anExp.Current()); - isEmptyShape = false; - } - Set(aShell); + bool isEmptyShape = BOPTools_AlgoTools3D::IsEmptyShape(myVisibleCompound); + Set(myVisibleCompound); + myIsSubstituted = true; if (isEmptyShape) aReadyToDisplay = false; } } // change deviation coefficient to provide more precise circle - //ModuleBase_Tools::setDefaultDeviationCoefficient(myResult, Attributes()); - AIS_Shape::Compute(thePresentationManager, thePresentation, theMode); + try { + AIS_Shape::Compute(thePresentationManager, thePresentation, theMode); + } + catch (...) { + return; + } // visualize hidden sub-shapes transparent - if (myTransparency < 1 && !myHiddenSubShapes.IsEmpty()) - { - StdPrs_ShadedShape::Add (thePresentation, myHiddenCompound, myHiddenSubShapesDrawer); + if (myResult.get()) { + if (myTransparency < 1 && !myHiddenSubShapes.IsEmpty()) + { + StdPrs_ShadedShape::Add(thePresentation, myHiddenCompound, myHiddenSubShapesDrawer); + aReadyToDisplay = true; + } + + if (!aReadyToDisplay) { + Events_InfoMessage("ModuleBase_ResultPrs", + "An empty AIS presentation: ModuleBase_ResultPrs").send(); + static const Events_ID anEvent = Events_Loop::eventByName(EVENT_EMPTY_AIS_PRESENTATION); + ModelAPI_EventCreator::get()->sendUpdated(myResult, anEvent); + } } +} - if (!aReadyToDisplay) { - Events_InfoMessage("ModuleBase_ResultPrs", - "An empty AIS presentation: ModuleBase_ResultPrs").send(); - static const Events_ID anEvent = Events_Loop::eventByName(EVENT_EMPTY_AIS_PRESENTATION); - ModelAPI_EventCreator::get()->sendUpdated(myResult, anEvent); +//******************************************************************** +void ModuleBase_ResultPrs::collectSubShapes(BRep_Builder& theBuilder, + TopoDS_Shape& theCompound, const TopoDS_Shape& theShape, + const TopoDS_ListOfShape& theHiddenSubShapes) +{ + switch (theShape.ShapeType()) { + case TopAbs_COMPSOLID: + case TopAbs_COMPOUND: { + for (TopoDS_Iterator aChildIter (theShape); aChildIter.More(); aChildIter.Next()) + collectSubShapes(theBuilder, theCompound, aChildIter.Value(), theHiddenSubShapes); + } + break; + case TopAbs_SOLID: + case TopAbs_SHELL: { + for (TopExp_Explorer anExp (theShape, TopAbs_FACE); anExp.More(); anExp.Next()) { + collectSubShapes(theBuilder, theCompound, anExp.Current(), theHiddenSubShapes); + } + } + break; + case TopAbs_WIRE: { + for (TopExp_Explorer anExp (theShape, TopAbs_EDGE); anExp.More(); anExp.Next()) { + collectSubShapes(theBuilder, theCompound, anExp.Current(), theHiddenSubShapes); + } + } + break; + case TopAbs_FACE: { + if (theHiddenSubShapes.Contains(theShape)) + return; // remove hidden shape + theBuilder.Add(theCompound, theShape); + } + break; + case TopAbs_EDGE: + case TopAbs_VERTEX: { + theBuilder.Add(theCompound, theShape); + } + default: + break; } } @@ -242,50 +376,52 @@ void ModuleBase_ResultPrs::ComputeSelection(const Handle(SelectMgr_Selection)& a return; } - if (theMode == AIS_Shape::SelectionMode(TopAbs_COMPSOLID)) { - // Limit selection area only by actual object (Shape) - ResultCompSolidPtr aCompSolid = ModelAPI_Tools::compSolidOwner(myResult); - if (aCompSolid.get()) { - std::shared_ptr aShapePtr = ModelAPI_Tools::shape(aCompSolid); - if (aShapePtr.get()) { - TopoDS_Shape aShape = aShapePtr->impl(); - int aPriority = StdSelect_BRepSelectionTool::GetStandardPriority(aShape, TopAbs_COMPSOLID); - /// It is important to have priority for the shape of comp solid result less than priority - /// for the presentation shape which is a sub-result. - /// Reason is to select the sub-objects before: #1592 - aPriority = aPriority - 1; - double aDeflection = Prs3d::GetDeflection(aShape, myDrawer); - - Handle(ModuleBase_BRepOwner) aOwner = new ModuleBase_BRepOwner(aShape, aPriority); - StdSelect_BRepSelectionTool::ComputeSensitive(aShape, aOwner, aSelection, - aDeflection, myDrawer->HLRAngle(), 9, 500); - - for (aSelection->Init(); aSelection->More(); aSelection->Next()) { - Handle(SelectMgr_EntityOwner) anOwner = - Handle(SelectMgr_EntityOwner) - ::DownCast(aSelection->Sensitive()->BaseSensitive()->OwnerId()); - anOwner->Set(this); - } - return; - } - } - //AIS_Shape::ComputeSelection(aSelection, 0); - } + // bug 2110: if (theMode == AIS_Shape::SelectionMode(TopAbs_COMPSOLID)) { + // // Limit selection area only by actual object (Shape) + // ResultCompSolidPtr aCompSolid = ModelAPI_Tools::compSolidOwner(myResult); + // if (aCompSolid.get()) { + // std::shared_ptr aShapePtr = ModelAPI_Tools::shape(aCompSolid); + // if (aShapePtr.get()) { + // TopoDS_Shape aShape = aShapePtr->impl(); + // int aPriority = StdSelect_BRepSelectionTool::GetStandardPriority(aShape, TopAbs_COMPSOLID); + // /// It is important to have priority for the shape of comp solid result less than priority + // /// for the presentation shape which is a sub-result. + // /// Reason is to select the sub-objects before: #1592 + // aPriority = aPriority - 1; + // double aDeflection = Prs3d::GetDeflection(aShape, myDrawer); + + // Handle(ModuleBase_BRepOwner) aOwner = new ModuleBase_BRepOwner(aShape, aPriority); + // StdSelect_BRepSelectionTool::ComputeSensitive(aShape, aOwner, aSelection, + // aDeflection, myDrawer->HLRAngle(), 9, 500); + + // for (aSelection->Init(); aSelection->More(); aSelection->Next()) { + // Handle(SelectMgr_EntityOwner) anOwner = + // Handle(SelectMgr_EntityOwner) + // ::DownCast(aSelection->Sensitive()->BaseSensitive()->OwnerId()); + // anOwner->Set(this); + // } + // return; + // } + // } + //} AIS_Shape::ComputeSelection(aSelection, theMode); if (myAdditionalSelectionPriority > 0) { - for (aSelection->Init(); aSelection->More(); aSelection->Next()) { - Handle(SelectBasics_EntityOwner) aBasicsOwner = - aSelection->Sensitive()->BaseSensitive()->OwnerId(); + NCollection_Vector anEntities = aSelection->Entities(); + for (NCollection_Vector::Iterator anIt(anEntities); + anIt.More(); + anIt.Next()) { + Handle(SelectMgr_SensitiveEntity) anEntity = anIt.Value(); + Handle(SelectBasics_EntityOwner) aBasicsOwner = anEntity->BaseSensitive()->OwnerId(); if (!aBasicsOwner.IsNull()) - aBasicsOwner->Set(aBasicsOwner->Priority() + myAdditionalSelectionPriority); + aBasicsOwner->SetPriority(aBasicsOwner->Priority() + myAdditionalSelectionPriority); } } } //******************************************************************** bool ModuleBase_ResultPrs::appendVertexSelection(const Handle(SelectMgr_Selection)& aSelection, - const Standard_Integer theMode) + const Standard_Integer /*theMode*/) { if (Shape().ShapeType() == TopAbs_VERTEX) { const TopoDS_Shape& aShape = Shape(); @@ -300,12 +436,16 @@ bool ModuleBase_ResultPrs::appendVertexSelection(const Handle(SelectMgr_Selectio StdSelect_BRepSelectionTool::ComputeSensitive(aShape, aOwner, aSelection, aDeflection, myDrawer->HLRAngle(), 9, 500); - for (aSelection->Init(); aSelection->More(); aSelection->Next()) { - Handle(SelectMgr_EntityOwner) anOwner = - Handle(SelectMgr_EntityOwner) - ::DownCast(aSelection->Sensitive()->BaseSensitive()->OwnerId()); - anOwner->Set(this); + + NCollection_Vector anEntities = aSelection->Entities(); + for (NCollection_Vector::Iterator anIt(anEntities); + anIt.More(); + anIt.Next()) { + Handle(SelectMgr_SensitiveEntity) anEntity = anIt.Value(); + Handle(SelectMgr_EntityOwner) anOwner = anEntity->BaseSensitive()->OwnerId(); + anOwner->SetSelectable(this); } + return true; } return false; @@ -340,7 +480,7 @@ void ModuleBase_ResultPrs::HilightSelected(const Handle(PrsMgr_PresentationManag //******************************************************************** void ModuleBase_ResultPrs::HilightOwnerWithColor(const Handle(PrsMgr_PresentationManager3d)& thePM, - const Handle(Graphic3d_HighlightStyle)& theStyle, + const Handle(Prs3d_Drawer)& theStyle, const Handle(SelectMgr_EntityOwner)& theOwner) { Handle(StdSelect_BRepOwner) aOwner = Handle(StdSelect_BRepOwner)::DownCast(theOwner); @@ -361,3 +501,30 @@ void ModuleBase_ResultPrs::HilightOwnerWithColor(const Handle(PrsMgr_Presentatio thePM->AddToImmediateList(aHilightPrs); } } + + +//******************************************************************** +void ModuleBase_ResultPrs::updateIsoLines() +{ + std::vector aIsoValues; + bool isIsoVisible; + ModelAPI_Tools::getIsoLines(myResult, isIsoVisible, aIsoValues); + if (isIsoVisible) { + if (aIsoValues.size() == 0) { + aIsoValues.push_back(1); + aIsoValues.push_back(1); + } + } + else { + if (aIsoValues.size() == 0) { + aIsoValues.push_back(0); + aIsoValues.push_back(0); + } + else { + aIsoValues[0] = 0; + aIsoValues[1] = 0; + } + } + myUIsoAspect->SetNumber(aIsoValues[0]); + myVIsoAspect->SetNumber(aIsoValues[1]); +}