X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FXGUI%2FXGUI_Selection.cpp;h=9e29e8b1b08bf729dd70ae701143b374d9bef318;hb=0dbe381518ba8993c2c4fa0fcb3ddd8fe5b8479b;hp=0dd985f977c8c8c5c7a4aac0b3007b1f0c51079b;hpb=acebef0bc5fb22dc9672e0046085b896e957af56;p=modules%2Fshaper.git diff --git a/src/XGUI/XGUI_Selection.cpp b/src/XGUI/XGUI_Selection.cpp index 0dd985f97..9e29e8b1b 100644 --- a/src/XGUI/XGUI_Selection.cpp +++ b/src/XGUI/XGUI_Selection.cpp @@ -1,6 +1,21 @@ -// File: XGUI_Selection.cpp -// Created: 8 July 2014 -// Author: Vitaly SMETANNIKOV +// Copyright (C) 2014-2019 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 "XGUI_Selection.h" #include "XGUI_Workshop.h" @@ -8,93 +23,357 @@ #include "XGUI_ViewerProxy.h" #include "XGUI_ObjectsBrowser.h" +#include "ModuleBase_BRepOwner.h" +#include "ModuleBase_ResultPrs.h" +#include "ModuleBase_ViewerPrs.h" + #include +#include +#include +#include +#include #include +#ifdef BEFORE_TRIHEDRON_PATCH +#include +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include + +#include +#include #include +#define DEBUG_DELIVERY + XGUI_Selection::XGUI_Selection(XGUI_Workshop* theWorkshop) : myWorkshop(theWorkshop) { } -QList XGUI_Selection::getSelected(int theShapeTypeToSkip) const +QList XGUI_Selection::getSelected(const SelectionPlace& thePlace) const { - //std::set aPrsFeatures; - QList aPresentations; - XGUI_Displayer* aDisplayer = myWorkshop->displayer(); + QList aPresentations; + QList aToRemove; - Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); - for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) { - ModuleBase_ViewerPrs aPrs; - - Handle(AIS_InteractiveObject) anIO = aContext->SelectedInteractive(); - aPrs.setInteractive(anIO); - - ObjectPtr aFeature = aDisplayer->getObject(anIO); - // we should not check the appearance of this feature because there can be some selected shapes - // for one feature - //if (aPrsFeatures.find(aFeature) == aPrsFeatures.end()) { - aPrs.setFeature(aFeature); - //aPrsFeatures.insert(aFeature); - //} - if (aContext->HasOpenedContext()) { - TopoDS_Shape aShape = aContext->SelectedShape(); - if (!aShape.IsNull() && (aShape.ShapeType() != theShapeTypeToSkip)) - aPrs.setShape(aShape); - } - Handle(SelectMgr_EntityOwner) anOwner = aContext->SelectedOwner(); - aPrs.setOwner(anOwner); - aPresentations.append(aPrs); + switch (thePlace) { + case Browser: + getSelectedInBrowser(aPresentations); + break; + case Viewer: + getSelectedInViewer(aPresentations); + break; + case AllControls: + // Get selection from object browser + getSelectedInBrowser(aPresentations); + + // Filter out all objects except feature if there is no selected results in object browser + // Filter out all features if in object browser there are selected features and their results + bool aHasFeature = false; + bool aHasResult = false; + foreach(ModuleBase_ViewerPrsPtr aVal, aPresentations) { + if (aVal->object().get()) { + FeaturePtr aFeature = std::dynamic_pointer_cast(aVal->object()); + if (aFeature.get()) { + aHasFeature = true; + std::list aResList = aFeature->results(); + std::list::const_iterator aIt; + for (aIt = aResList.cbegin(); aIt != aResList.cend(); aIt++) { + foreach(ModuleBase_ViewerPrsPtr aSel, aPresentations) { + if (aSel->object() == (*aIt)) { + aHasResult = true; + break; + } + } + if (aHasResult) + break; + } + } + } + if (aHasFeature && aHasResult) + break; + } + //Get selection from a viewer + getSelectedInViewer(aPresentations); + + // Filter out extra objects + if (aHasFeature && aHasResult) { + foreach(ModuleBase_ViewerPrsPtr aVal, aPresentations) { + if (aVal->object().get()) { + FeaturePtr aFeature = std::dynamic_pointer_cast(aVal->object()); + if (aFeature.get()) { + aToRemove.append(aVal); + } + } + } + } + else if (aHasFeature && (!aHasResult)) { + foreach(ModuleBase_ViewerPrsPtr aVal, aPresentations) { + if (aVal->object().get()) { + FeaturePtr aFeature = std::dynamic_pointer_cast(aVal->object()); + if (!aFeature.get()) { + aToRemove.append(aVal); + } + } + } + } + foreach(ModuleBase_ViewerPrsPtr aVal, aToRemove) { + aPresentations.removeAll(aVal); + } + break; } return aPresentations; } -QList XGUI_Selection::getHighlighted(int theShapeTypeToSkip) const +Handle(AIS_InteractiveObject) XGUI_Selection::getIO(const ModuleBase_ViewerPrsPtr& thePrs) { - //std::set aPrsFeatures; - QList aPresentations; + Handle(AIS_InteractiveObject) anIO = thePrs->interactive(); + if (anIO.IsNull()) { + Handle(SelectMgr_EntityOwner) anOwner = thePrs->owner(); + if (!anOwner.IsNull()) + anIO = Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable()); + + if (anIO.IsNull() && thePrs->object()) { + XGUI_Displayer* aDisplayer = myWorkshop->displayer(); + AISObjectPtr anAISObject = aDisplayer->getAISObject(thePrs->object()); + if (anAISObject.get()) + anIO = anAISObject->impl(); + } + } + return anIO; +} + +void XGUI_Selection::getSelectedInViewer(QList& thePresentations) const +{ + Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); + if (!aContext.IsNull()) { + QList aSelectedIds; // Remember of selected address in order to avoid duplicates + for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) { + ModuleBase_ViewerPrsPtr aPrs(new ModuleBase_ViewerPrs()); + Handle(SelectMgr_EntityOwner) anOwner = aContext->SelectedOwner(); + + if (aSelectedIds.contains((size_t)anOwner.get())) + continue; + aSelectedIds.append((size_t)anOwner.get()); + + fillPresentation(aPrs, anOwner); + + if (!thePresentations.contains(aPrs)) // TODO: check whether the presentation in a list + thePresentations.append(aPrs); + } + } +} + +void XGUI_Selection::getSelectedInBrowser(QList& thePresentations) const +{ + // collect the objects of the parameter presentation to avoid a repeted objects in the result + QObjectPtrList aPresentationObjects; + QList::const_iterator aPrsIt = thePresentations.begin(), + aPrsLast = thePresentations.end(); + for (; aPrsIt != aPrsLast; aPrsIt++) { + aPresentationObjects.push_back((*aPrsIt)->object()); + } + + QObjectPtrList anObjects = selectedObjects(); + QObjectPtrList::const_iterator anIt = anObjects.begin(), aLast = anObjects.end(); + for (; anIt != aLast; anIt++) { + ObjectPtr anObject = *anIt; + if (anObject.get() != NULL && !aPresentationObjects.contains(anObject)) { + thePresentations.append(std::shared_ptr( + new ModuleBase_ViewerPrs(anObject, GeomShapePtr(), NULL))); + } + } +} + +void XGUI_Selection::fillPresentation(ModuleBase_ViewerPrsPtr& thePrs, + const Handle(SelectMgr_EntityOwner)& theOwner) const +{ + thePrs->setOwner(theOwner); + Handle(AIS_InteractiveObject) anIO = + Handle(AIS_InteractiveObject)::DownCast(theOwner->Selectable()); + thePrs->setInteractive(anIO); + + // we should not check the appearance of this feature because there can be some selected shapes + // for one feature + Handle(StdSelect_BRepOwner) aBRO = Handle(StdSelect_BRepOwner)::DownCast(theOwner); + if( !aBRO.IsNull() && aBRO->HasShape() ) { + // the located method is called in the context to obtain the shape by the SelectedShape() + // method, so the shape is located by the same rules + TopoDS_Shape aShape = aBRO->Shape().Located (aBRO->Location() * aBRO->Shape().Location()); +#ifdef BEFORE_TRIHEDRON_PATCH +#ifndef DEBUG_DELIVERY + if (aShape.IsNull()) + aShape = findAxisShape(anIO); +#endif +#endif + if (!aShape.IsNull()) { + std::shared_ptr aGeomShape = + std::shared_ptr(new GeomAPI_Shape()); + aGeomShape->setImpl(new TopoDS_Shape(aShape)); + thePrs->setShape(aGeomShape); + } + } else { +#ifdef DEBUG_DELIVERY + // Fill by trihedron shapes +#ifdef BEFORE_TRIHEDRON_PATCH + Handle(AIS_Axis) aAxis = Handle(AIS_Axis)::DownCast(anIO); + DocumentPtr aDoc = ModelAPI_Session::get()->moduleDocument(); + int aSize = aDoc->size(ModelAPI_ResultConstruction::group()); + ObjectPtr aObj; + if (!aAxis.IsNull()) { + // an Axis from Trihedron + gp_Lin aLine = aAxis->Component()->Lin(); + gp_Dir aDir = aLine.Direction(); + std::string aAxName; + if (aDir.X() == 1.) + aAxName = "OX"; + else if (aDir.Y() == 1.) + aAxName = "OY"; + else if (aDir.Z() == 1.) + aAxName = "OZ"; + if (aAxName.length() > 0) { + ResultPtr aAx; + for (int i = 0; i < aSize; i++) { + aObj = aDoc->object(ModelAPI_ResultConstruction::group(), i); + if (aObj->data()->name() == aAxName) { + aAx = std::dynamic_pointer_cast(aObj); + break; + } + } + if (aAx.get()) { + thePrs->setObject(aAx); + thePrs->setShape(aAx->shape()); + return; + } + } + } else { + Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast(anIO); + if (!aPoint.IsNull()) { + // An origin point from trihedron + ResultPtr aOrigin; + for (int i = 0; i < aSize; i++) { + aObj = aDoc->object(ModelAPI_ResultConstruction::group(), i); + if (aObj->data()->name() == "Origin") { + aOrigin = std::dynamic_pointer_cast(aObj); + break; + } + } + if (aOrigin.get()) { + thePrs->setObject(aOrigin); + thePrs->setShape(aOrigin->shape()); + return; + } + } + } +#else + /// find axis direction + Handle(AIS_TrihedronOwner) aTrihedronOwner = Handle(AIS_TrihedronOwner)::DownCast(theOwner); + if (!aTrihedronOwner.IsNull()) { + const Prs3d_DatumParts& aPart = aTrihedronOwner->DatumPart(); + std::string aName; + switch (aPart) { + case Prs3d_DP_Origin: aName = "Origin"; break; + case Prs3d_DP_XAxis: aName = "OX"; break; + case Prs3d_DP_YAxis: aName = "OY"; break; + case Prs3d_DP_ZAxis: aName = "OZ"; break; + default: break; + } + if (aName.length() > 0) { + DocumentPtr aDoc = ModelAPI_Session::get()->moduleDocument(); + int aSize = aDoc->size(ModelAPI_ResultConstruction::group()); + ObjectPtr aObj; + ResultPtr aResult; + for (int i = 0; i < aSize; i++) { + aObj = aDoc->object(ModelAPI_ResultConstruction::group(), i); + if (aObj->data()->name() == aName) { + aResult = std::dynamic_pointer_cast(aObj); + break; + } + } + if (aResult.get()) { + thePrs->setObject(aResult); + thePrs->setShape(aResult->shape()); + return; + } + } + } +#endif +#endif + } + XGUI_Displayer* aDisplayer = myWorkshop->displayer(); + ObjectPtr aFeature = aDisplayer->getObject(anIO); + + Handle(ModuleBase_BRepOwner) aCompSolidBRO = Handle(ModuleBase_BRepOwner)::DownCast(theOwner); + if (!aCompSolidBRO.IsNull()) { + // If ModuleBase_BRepOwner object is created then it means that TopAbs_COMPSOLID selection mode + // is On and we have to use parent result which corresponds to the CompSolid shape + ResultPtr aResult = std::dynamic_pointer_cast(aFeature); + if (aResult.get()) { + ResultBodyPtr aCompSolid = ModelAPI_Tools::bodyOwner(aResult); + if (aCompSolid.get()) { + GeomShapePtr aShape = aCompSolid->shape(); + if (aShape.get() && aShape->isEqual(thePrs->shape())) { + thePrs->setObject(aCompSolid); + return; + } + } + } + } + thePrs->setObject(aFeature); +} +QList XGUI_Selection::getHighlighted() const +{ + QList aPresentations; Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); + if (aContext.IsNull()) + return aPresentations; + + QList aSelectedIds; // Remember of selected address in order to avoid duplicates + XGUI_Displayer* aDisplayer = myWorkshop->displayer(); for (aContext->InitDetected(); aContext->MoreDetected(); aContext->NextDetected()) { - ModuleBase_ViewerPrs aPrs; - Handle(AIS_InteractiveObject) anIO = aContext->DetectedInteractive(); - aPrs.setInteractive(anIO); - - ObjectPtr aResult = aDisplayer->getObject(anIO); - // we should not check the appearance of this feature because there can be some selected shapes - // for one feature - //if (aPrsFeatures.find(aResult) == aPrsFeatures.end()) { - aPrs.setFeature(aResult); - //aPrsFeatures.insert(aResult); - //} - if (aContext->HasOpenedContext()) { - TopoDS_Shape aShape = aContext->DetectedShape(); - if (!aShape.IsNull() && aShape.ShapeType() != theShapeTypeToSkip) - aPrs.setShape(aShape); - } - aPresentations.push_back(aPrs); + Handle(SelectMgr_EntityOwner) anOwner = aContext->DetectedOwner(); + if (!anOwner.IsNull()) { + if (aSelectedIds.contains((size_t)anOwner.get())) + continue; + aSelectedIds.append((size_t)anOwner.get()); + + ModuleBase_ViewerPrsPtr aPrs(new ModuleBase_ViewerPrs()); + fillPresentation(aPrs, anOwner); + aPresentations.push_back(aPrs); + } } return aPresentations; } -QList XGUI_Selection::selectedObjects() const +QObjectPtrList XGUI_Selection::selectedObjects() const { - return myWorkshop->objectBrowser()->selectedObjects(); + if (myWorkshop->objectBrowser()) + return myWorkshop->objectBrowser()->selectedObjects(); + return QObjectPtrList(); } -QList XGUI_Selection::selectedPresentations() const +QObjectPtrList XGUI_Selection::selectedPresentations() const { - QList aSelectedList; + QObjectPtrList aSelectedList; Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); - for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) { - Handle(AIS_InteractiveObject) anIO = aContext->SelectedInteractive(); - ObjectPtr aResult = myWorkshop->displayer()->getObject(anIO); - if (aResult) - aSelectedList.append(aResult); + if (!aContext.IsNull()) { + for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) { + Handle(AIS_InteractiveObject) anIO = aContext->SelectedInteractive(); + ObjectPtr aResult = myWorkshop->displayer()->getObject(anIO); + if (aResult) + aSelectedList.append(aResult); + } } return aSelectedList; } @@ -106,29 +385,93 @@ QModelIndexList XGUI_Selection::selectedIndexes() const } //************************************************************** -void XGUI_Selection::selectedAISObjects(AIS_ListOfInteractive& theList) const +ObjectPtr XGUI_Selection::getSelectableObject(const Handle(SelectMgr_EntityOwner)& theOwner) const +{ + ObjectPtr anObject; + + Handle(SelectMgr_EntityOwner) aEO = theOwner; + if (!aEO.IsNull()) { + Handle(AIS_InteractiveObject) anObj = + Handle(AIS_InteractiveObject)::DownCast(aEO->Selectable()); + anObject = myWorkshop->displayer()->getObject(anObj); + } + return anObject; +} + +//************************************************************** +void XGUI_Selection::selectedOwners(SelectMgr_IndexedMapOfOwner& theSelectedOwners) const { Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); - theList.Clear(); - for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) - theList.Append(aContext->SelectedInteractive()); + if (!aContext.IsNull()) { + for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) { + theSelectedOwners.Add(aContext->SelectedOwner()); + } + } } //************************************************************** -void XGUI_Selection::selectedShapes(NCollection_List& theList, - std::list& theOwners) const +void XGUI_Selection::entityOwners(const Handle(AIS_InteractiveObject)& theObject, + SelectMgr_IndexedMapOfOwner& theOwners) const { - theList.Clear(); Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); - for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) { - TopoDS_Shape aShape = aContext->SelectedShape(); - if (!aShape.IsNull()) { - theList.Append(aShape); - Handle(SelectMgr_EntityOwner) aEO = aContext->SelectedOwner(); - Handle(AIS_InteractiveObject) anObj = - Handle(AIS_InteractiveObject)::DownCast(aEO->Selectable()); - ObjectPtr anObject = myWorkshop->displayer()->getObject(anObj); - theOwners.push_back(anObject); + if (aContext.IsNull() || theObject.IsNull()) + return; + + TColStd_ListOfInteger aModes; + aContext->ActivatedModes(theObject, aModes); + + TColStd_ListIteratorOfListOfInteger anIt(aModes); + for (; anIt.More(); anIt.Next()) { + int aMode = anIt.Value(); + if (!theObject->HasSelection(aMode)) + continue; + + Handle(SelectMgr_Selection) aSelection = theObject->Selection(aMode); + NCollection_Vector anEntities = aSelection->Entities(); + for (NCollection_Vector::Iterator anIt(anEntities); + anIt.More(); + anIt.Next()) { + Handle(SelectMgr_SensitiveEntity) anEntity = anIt.Value(); + if (anEntity.IsNull()) + continue; + Handle(SelectMgr_EntityOwner) anOwner = + Handle(SelectMgr_EntityOwner)::DownCast(anEntity->BaseSensitive()->OwnerId()); + if (!anOwner.IsNull()) + theOwners.Add(anOwner); + } + } +} + +//************************************************************** +#ifdef BEFORE_TRIHEDRON_PATCH +TopoDS_Shape XGUI_Selection::findAxisShape(Handle(AIS_InteractiveObject) theIO) const +{ + TopoDS_Shape aShape; + // Fill by trihedron shapes + Handle(AIS_Axis) aAxis = Handle(AIS_Axis)::DownCast(theIO); + if (!aAxis.IsNull()) { + // an Axis from Trihedron + Handle(Geom_Line) aLine = aAxis->Component(); + Handle(Prs3d_DatumAspect) DA = aAxis->Attributes()->DatumAspect(); + Handle(Geom_TrimmedCurve) aTLine = new Geom_TrimmedCurve(aLine, 0, DA->FirstAxisLength()); + + BRep_Builder aBuilder; + TopoDS_Edge aEdge; + aBuilder.MakeEdge(aEdge, aTLine, Precision::Confusion()); + if (!aEdge.IsNull()) + aShape = aEdge; + } else { + Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast(theIO); + if (!aPoint.IsNull()) { + // A point from trihedron + Handle(Geom_Point) aPnt = aPoint->Component(); + BRep_Builder aBuilder; + TopoDS_Vertex aVertex; + aBuilder.MakeVertex(aVertex, aPnt->Pnt(), Precision::Confusion()); + if (!aVertex.IsNull()) + aShape = aVertex; } } + return aShape; } +#endif