X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModuleBase%2FModuleBase_ResultPrs.cpp;h=ad9ca2febdeae5b830ca78d4ee4c119f4215015a;hb=827d67208d2bb221aebe9adb9ef4a4c914789136;hp=29648d9b255aa304681681d75efb60a0e1bb93f2;hpb=1d64873130c0d536eb04bfe533ae58fe1caac916;p=modules%2Fshaper.git diff --git a/src/ModuleBase/ModuleBase_ResultPrs.cpp b/src/ModuleBase/ModuleBase_ResultPrs.cpp old mode 100644 new mode 100755 index 29648d9b2..ad9ca2feb --- a/src/ModuleBase/ModuleBase_ResultPrs.cpp +++ b/src/ModuleBase/ModuleBase_ResultPrs.cpp @@ -1,87 +1,364 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: ModuleBase_ResultPrs.cpp -// Created: 21 October 2014 -// Author: Vitaly SMETANNIKOV +// Copyright (C) 2014-2017 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 +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// 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 +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// #include "ModuleBase_ResultPrs.h" +#include + +#include #include #include -#include +#include + +#include "ModuleBase_Tools.h" +#include "ModuleBase_BRepOwner.h" +#include +#include + +#include +#include +#include #include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -IMPLEMENT_STANDARD_HANDLE(ModuleBase_ResultPrs, ViewerData_AISShape); +//******************************************************************************************* + IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_ResultPrs, ViewerData_AISShape); + + +//******************************************************************** ModuleBase_ResultPrs::ModuleBase_ResultPrs(ResultPtr theResult) - : ViewerData_AISShape(TopoDS_Shape()), myResult(theResult), myIsSketchMode(false) + : ViewerData_AISShape(TopoDS_Shape()), myResult(theResult), myAdditionalSelectionPriority(0), + myTransparency(1) { std::shared_ptr aShapePtr = ModelAPI_Tools::shape(theResult); - std::shared_ptr aWirePtr = - std::dynamic_pointer_cast(aShapePtr); - if (aWirePtr) { - if (aWirePtr->hasPlane() ) { - // If this is a wire with plane defined thin it is a sketch-like object - // It must have invisible faces - myIsSketchMode = true; + TopoDS_Shape aShape = aShapePtr->impl(); + Set(aShape); + Handle(Prs3d_Drawer) aDrawer = Attributes(); + 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); + + myHiddenSubShapesDrawer = new AIS_ColoredDrawer (myDrawer); + Handle(Prs3d_ShadingAspect) aShadingAspect = new Prs3d_ShadingAspect(); + aShadingAspect->SetMaterial(Graphic3d_NOM_BRASS); //default value of context material + myHiddenSubShapesDrawer->SetShadingAspect(aShadingAspect); + + ModuleBase_Tools::setPointBallHighlighting(this); +} + +//******************************************************************** +void ModuleBase_ResultPrs::setAdditionalSelectionPriority(const int thePriority) +{ + myAdditionalSelectionPriority = thePriority; +} + +//******************************************************************** +void ModuleBase_ResultPrs::SetColor (const Quantity_Color& theColor) +{ + ViewerData_AISShape::SetColor(theColor); + myHiddenSubShapesDrawer->ShadingAspect()->SetColor (theColor, myCurrentFacingModel); +} + +//******************************************************************** +bool ModuleBase_ResultPrs::setSubShapeHidden(const NCollection_List& theShapes) +{ + bool isModified = false; + + 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; } } - Set(aShapePtr->impl()); + myHiddenCompound = aCompound; + return isModified; } +//******************************************************************** +bool ModuleBase_ResultPrs::hasSubShapeVisible(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; + } + return aHasVisibleShape; +} -void ModuleBase_ResultPrs::Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager, - const Handle(Prs3d_Presentation)& thePresentation, - const Standard_Integer theMode) +//******************************************************************** +bool ModuleBase_ResultPrs::setHiddenSubShapeTransparency(double theTransparency) +{ + if (myTransparency == theTransparency || theTransparency > 1 || theTransparency < 0) + return false; + + myTransparency = theTransparency; + myHiddenSubShapesDrawer->ShadingAspect()->SetTransparency (theTransparency, myCurrentFacingModel); + return true; +} + +//******************************************************************** +void ModuleBase_ResultPrs::Compute( + const Handle(PrsMgr_PresentationManager3d)& thePresentationManager, + const Handle(Prs3d_Presentation)& thePresentation, + const Standard_Integer theMode) { std::shared_ptr aShapePtr = ModelAPI_Tools::shape(myResult); - if (!aShapePtr) - return; - if (myIsSketchMode) { - myFacesList.clear(); - ResultConstructionPtr aConstruction = - std::dynamic_pointer_cast(myResult); - if (aConstruction.get()) { - int aFacesNum = aConstruction->facesNum(); - for(int aFaceIndex = 0; aFaceIndex < aFacesNum; aFaceIndex++) { - myFacesList.push_back(aConstruction->face(aFaceIndex)); + bool aReadyToDisplay = aShapePtr.get(); + if (aReadyToDisplay) { + myOriginalShape = aShapePtr->impl(); + if (myHiddenSubShapes.IsEmpty() || myOriginalShape.ShapeType() > TopAbs_FACE ) { + if (!myOriginalShape.IsNull()) + Set(myOriginalShape); + } + 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); + if (isEmptyShape) + aReadyToDisplay = false; } } - myOriginalShape = aShapePtr->impl(); - if (!myOriginalShape.IsNull()) { - Set(myOriginalShape); - AIS_Shape::Compute(thePresentationManager, thePresentation, theMode); + // change deviation coefficient to provide more precise circle + //ModuleBase_Tools::setDefaultDeviationCoefficient(myResult, Attributes()); + AIS_Shape::Compute(thePresentationManager, thePresentation, theMode); + + // visualize hidden sub-shapes transparent + 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); + } +} +//******************************************************************** void ModuleBase_ResultPrs::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection, - const Standard_Integer aMode) + const Standard_Integer theMode) { - if (aMode > TopAbs_SHAPE) + if (appendVertexSelection(aSelection, theMode)) + return; + + if (theMode > TopAbs_SHAPE) { // In order to avoid using custom selection modes + if (theMode == ModuleBase_ResultPrs::Sel_Result) { + AIS_Shape::ComputeSelection(aSelection, TopAbs_COMPOUND); + } return; + } - if (myIsSketchMode) { - if (aMode == TopAbs_FACE) { - BRep_Builder aBuilder; - TopoDS_Compound aComp; - aBuilder.MakeCompound(aComp); - aBuilder.Add(aComp, myOriginalShape); - std::list>::const_iterator aIt; - for (aIt = myFacesList.cbegin(); aIt != myFacesList.cend(); ++aIt) { - TopoDS_Shape aFace = (*aIt)->impl(); - aBuilder.Add(aComp, aFace); + // TODO: OCCT issue should be created for the COMPOUND processing + // before it is fixed, the next workaround in necessary + if (theMode == AIS_Shape::SelectionMode(TopAbs_COMPOUND)) { + const TopoDS_Shape& aShape = Shape(); + TopExp_Explorer aCompExp(aShape, TopAbs_COMPOUND); + // do not activate in compound mode shapes which do not contain compounds + if (!aCompExp.More()) + 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; } - Set(aComp); - } else { - Set(myOriginalShape); + } + //AIS_Shape::ComputeSelection(aSelection, 0); + } + AIS_Shape::ComputeSelection(aSelection, theMode); + + if (myAdditionalSelectionPriority > 0) { + for (aSelection->Init(); aSelection->More(); aSelection->Next()) { + Handle(SelectBasics_EntityOwner) aBasicsOwner = + aSelection->Sensitive()->BaseSensitive()->OwnerId(); + if (!aBasicsOwner.IsNull()) + aBasicsOwner->Set(aBasicsOwner->Priority() + myAdditionalSelectionPriority); + } + } +} + +//******************************************************************** +bool ModuleBase_ResultPrs::appendVertexSelection(const Handle(SelectMgr_Selection)& aSelection, + const Standard_Integer theMode) +{ + if (Shape().ShapeType() == TopAbs_VERTEX) { + const TopoDS_Shape& aShape = Shape(); + + int aPriority = StdSelect_BRepSelectionTool::GetStandardPriority(aShape, TopAbs_VERTEX); + double aDeflection = Prs3d::GetDeflection(aShape, myDrawer); + + /// The cause of this method is the last parameter of BRep owner setting into True. + /// That means that owner should behave like it comes from decomposition. (In this case, OCCT + /// visualizes it in Ring style) OCCT version is 7.0.0 with path for SHAPER module. + Handle(StdSelect_BRepOwner) aOwner = new StdSelect_BRepOwner(aShape, aPriority, Standard_True); + 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 true; + } + return false; +} + +//******************************************************************** +void ModuleBase_ResultPrs::HilightSelected(const Handle(PrsMgr_PresentationManager3d)& thePM, + const SelectMgr_SequenceOfOwner& theOwners) +{ + Handle(SelectMgr_EntityOwner) anOwner; + Handle(ModuleBase_BRepOwner) aCompOwner; + for (int i = 1; i <= theOwners.Length(); i++) { + anOwner = theOwners.Value(i); + aCompOwner = Handle(ModuleBase_BRepOwner)::DownCast(anOwner); + if (aCompOwner.IsNull()) { + thePM->Color(anOwner->Selectable(), GetContext()->SelectionStyle()); + } + else { + TopoDS_Shape aShape = aCompOwner->Shape(); + Handle( Prs3d_Presentation ) aSelectionPrs = GetSelectPresentation( thePM ); + aSelectionPrs->Clear(); + + StdPrs_WFShape::Add(aSelectionPrs, aShape, myDrawer); + + aSelectionPrs->SetDisplayPriority(9); + aSelectionPrs->Highlight(GetContext()->SelectionStyle()); + aSelectionPrs->Display(); + thePM->Color(this, GetContext()->SelectionStyle()); } } - AIS_Shape::ComputeSelection(aSelection, aMode); -} \ No newline at end of file +} + +//******************************************************************** +void ModuleBase_ResultPrs::HilightOwnerWithColor(const Handle(PrsMgr_PresentationManager3d)& thePM, + const Handle(Graphic3d_HighlightStyle)& theStyle, + const Handle(SelectMgr_EntityOwner)& theOwner) +{ + Handle(StdSelect_BRepOwner) aOwner = Handle(StdSelect_BRepOwner)::DownCast(theOwner); + if (aOwner.IsNull()) + return; + + TopoDS_Shape aShape = aOwner->Shape(); + if (!aShape.IsNull()) { + thePM->Color(this, theStyle); + + Handle( Prs3d_Presentation ) aHilightPrs = GetHilightPresentation( thePM ); + aHilightPrs->Clear(); + + StdPrs_WFShape::Add(aHilightPrs, aShape, myDrawer); + aHilightPrs->Highlight(theStyle); + + if (thePM->IsImmediateModeOn()) + thePM->AddToImmediateList(aHilightPrs); + } +}