From: nds Date: Thu, 23 May 2019 16:58:59 +0000 (+0300) Subject: 0030737: Visualization - implementing new selection schemes in context X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=73794e88be9ceec26767bada4b52d255f7262446;p=occt-copy.git 0030737: Visualization - implementing new selection schemes in context (cherry picked from commit f9d4ea66dbba0c6fb70d0232d9fd326722e83fbc) (cherry picked from commit 1c7d53e55ac3c0c75ee828e2817b96434104d291) (cherry picked from commit e2b319869af281f741ad97595c23de6d3128bce2) # Conflicts: # src/AIS/AIS_InteractiveContext_1.cxx --- diff --git a/src/AIS/AIS_InteractiveContext.cxx b/src/AIS/AIS_InteractiveContext.cxx index 2167506cbc..7cc82a3524 100644 --- a/src/AIS/AIS_InteractiveContext.cxx +++ b/src/AIS/AIS_InteractiveContext.cxx @@ -161,6 +161,12 @@ myIsAutoActivateSelMode(Standard_True) aStyle->SetMethod(Aspect_TOHM_COLOR); aStyle->SetColor (Quantity_NOC_GRAY40); } + SetSelectionScheme (AIS_SelectionType_Select, AIS_SelectionScheme_ClearAndAdd); + SetSelectionScheme (AIS_SelectionType_SelectInRect, AIS_SelectionScheme_ClearAndAdd); + SetSelectionScheme (AIS_SelectionType_SelectInPoly, AIS_SelectionScheme_ClearAndAdd); + SetSelectionScheme (AIS_SelectionType_ShiftSelect, AIS_SelectionScheme_Switch); + SetSelectionScheme (AIS_SelectionType_ShiftSelectInRect, AIS_SelectionScheme_Switch); + SetSelectionScheme (AIS_SelectionType_ShiftSelectInPoly, AIS_SelectionScheme_Switch); InitAttributes(); } diff --git a/src/AIS/AIS_InteractiveContext.hxx b/src/AIS/AIS_InteractiveContext.hxx index 06dc107f9b..1a5597531c 100644 --- a/src/AIS/AIS_InteractiveContext.hxx +++ b/src/AIS/AIS_InteractiveContext.hxx @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include #include #include @@ -467,6 +469,14 @@ public: //! @name Selection management return AddSelect (theObject->GlobalSelOwner()); } + //! Returns selection scheme used in Select + AIS_SelectionScheme SelectionScheme (const AIS_SelectionType theType) const + { return mySelectionSchemes.Find (theType); } + + //! Returns selection scheme used in Select + void SetSelectionScheme (const AIS_SelectionType theType, const AIS_SelectionScheme theScheme) + { mySelectionSchemes.Bind (theType, theScheme); } + //! Selects everything found in the bounding rectangle defined by the pixel minima and maxima, XPMin, YPMin, XPMax, and YPMax in the view. //! The objects detected are passed to the main viewer, which is then updated. Standard_EXPORT AIS_StatusOfPick Select (const Standard_Integer theXPMin, @@ -1390,6 +1400,7 @@ protected: //! @name internal fields Standard_Boolean myAutoHilight; Standard_Boolean myIsAutoActivateSelMode; + NCollection_DataMap mySelectionSchemes; }; DEFINE_STANDARD_HANDLE(AIS_InteractiveContext, Standard_Transient) diff --git a/src/AIS/AIS_InteractiveContext_1.cxx b/src/AIS/AIS_InteractiveContext_1.cxx index cfac0ebdc6..aec3d2a25d 100644 --- a/src/AIS/AIS_InteractiveContext_1.cxx +++ b/src/AIS/AIS_InteractiveContext_1.cxx @@ -461,16 +461,20 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Integer theXPMi // all objects detected by the selector are taken, previous current objects are emptied, // new objects are put... - ClearSelected (Standard_False); + if (myAutoHilight) + { + clearDynamicHighlight(); + UnhilightSelected (Standard_False); + } + myMainSel->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView); + + AIS_NListOfEntityOwner aPickedOwners; for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter) { - const Handle(SelectMgr_EntityOwner)& aCurOwner = myMainSel->Picked (aPickIter); - if (aCurOwner.IsNull() || !aCurOwner->HasSelectable() || !myFilters->IsOk (aCurOwner)) - continue; - - mySelection->Select (aCurOwner); + aPickedOwners.Append (myMainSel->Picked (aPickIter)); } + mySelection->SelectOwners (aPickedOwners, SelectionScheme (AIS_SelectionType_SelectInRect), myFilters); if (myAutoHilight) { @@ -500,16 +504,20 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const TColgp_Array1OfPnt2d& the // all objects detected by the selector are taken, previous current objects are emptied, // new objects are put... - ClearSelected (Standard_False); + if (myAutoHilight) + { + clearDynamicHighlight(); + UnhilightSelected (Standard_False); + } + myMainSel->Pick (thePolyline, theView); + + AIS_NListOfEntityOwner aPickedOwners; for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter) { - const Handle(SelectMgr_EntityOwner) anOwner = myMainSel->Picked (aPickIter); - if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner)) - continue; - - mySelection->Select (anOwner); + aPickedOwners.Append (myMainSel->Picked (aPickIter)); } + mySelection->SelectOwners (aPickedOwners, SelectionScheme (AIS_SelectionType_SelectInPoly), myFilters); if (myAutoHilight) { @@ -530,26 +538,34 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const TColgp_Array1OfPnt2d& the //======================================================================= AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Boolean toUpdateViewer) { - if (!myLastPicked.IsNull()) + // special case: single selection of detected owner - is it necessary ? + /*if (myWasLastMain && !myLastinMain.IsNull() && !myAutoHilight && + (myLastinMain->IsSelected() + && !myLastinMain->IsForcedHilight() + && NbSelected() <= 1)) { - if (myAutoHilight) - { - clearDynamicHighlight(); - } - if (!myLastPicked->IsSelected() - || myLastPicked->IsForcedHilight() - || NbSelected() > 1) - { - SetSelected (myLastPicked, Standard_False); - if(toUpdateViewer) - { - UpdateCurrentViewer(); - } - } + mySelection->selectOwner(myLastinMain, aPrevSelected, SelectionScheme (AIS_SelectionType_Select)); + return getStatusOfPick (NbSelected()); + }*/ + + if (myAutoHilight) + { + clearDynamicHighlight(); + UnhilightSelected (Standard_False); } - else + + AIS_NListOfEntityOwner aPickedOwners; + aPickedOwners.Append (myLastinMain); + mySelection->SelectOwners (aPickedOwners, SelectionScheme (AIS_SelectionType_Select), myFilters); + + if (myAutoHilight) { - ClearSelected (toUpdateViewer); + HilightSelected (toUpdateViewer); + } + + if(toUpdateViewer) + { + UpdateCurrentViewer(); } Standard_Integer aSelNum = NbSelected(); @@ -565,15 +581,25 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Boolean toUpdate //======================================================================= AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Boolean toUpdateViewer) { + AIS_NListOfEntityOwner aPrevSelected = mySelection->Objects(); if (myAutoHilight) { clearDynamicHighlight(); + UnhilightSelected (Standard_False); } - if (!myLastPicked.IsNull()) + + AIS_NListOfEntityOwner aPickedOwners; + aPickedOwners.Append (myLastinMain); + mySelection->SelectOwners (aPickedOwners, SelectionScheme (AIS_SelectionType_ShiftSelect), myFilters); + + if (myAutoHilight) { - AddOrRemoveSelected (myLastPicked, toUpdateViewer); + HilightSelected (toUpdateViewer); } + if (toUpdateViewer) + UpdateCurrentViewer(); + Standard_Integer aSelNum = NbSelected(); return (aSelNum == 0) ? AIS_SOP_NothingSelected @@ -597,19 +623,20 @@ AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Integer the throw Standard_ProgramError ("AIS_InteractiveContext::ShiftSelect() - invalid argument"); } + AIS_NListOfEntityOwner aPrevSelected = mySelection->Objects(); if (myAutoHilight) { + clearDynamicHighlight(); UnhilightSelected (Standard_False); } myMainSel->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView); + + AIS_NListOfEntityOwner aPickedOwners; for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter) { - const Handle(SelectMgr_EntityOwner) anOwner = myMainSel->Picked (aPickIter); - if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner)) - continue; - - mySelection->Select (anOwner); + aPickedOwners.Append (myMainSel->Picked (aPickIter)); } + mySelection->SelectOwners (aPickedOwners, SelectionScheme (AIS_SelectionType_ShiftSelectInRect), myFilters); if (myAutoHilight) { @@ -637,19 +664,20 @@ AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const TColgp_Array1OfPnt2d throw Standard_ProgramError ("AIS_InteractiveContext::ShiftSelect() - invalid argument"); } + AIS_NListOfEntityOwner aPrevSelected = mySelection->Objects(); if (myAutoHilight) { + clearDynamicHighlight(); UnhilightSelected (Standard_False); } myMainSel->Pick (thePolyline, theView); + + AIS_NListOfEntityOwner aPickedOwners; for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter) { - const Handle(SelectMgr_EntityOwner) anOwner = myMainSel->Picked (aPickIter); - if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner)) - continue; - - mySelection->Select (anOwner); + aPickedOwners.Append (myMainSel->Picked (aPickIter)); } + mySelection->SelectOwners (aPickedOwners, SelectionScheme (AIS_SelectionType_ShiftSelectInPoly), myFilters); if (myAutoHilight) { diff --git a/src/AIS/AIS_Selection.cxx b/src/AIS/AIS_Selection.cxx index e26bddf828..8569e8a2b7 100644 --- a/src/AIS/AIS_Selection.cxx +++ b/src/AIS/AIS_Selection.cxx @@ -15,6 +15,8 @@ #include #include +#include +#include IMPLEMENT_STANDARD_RTTIEXT(AIS_Selection, Standard_Transient) @@ -130,3 +132,71 @@ AIS_SelectStatus AIS_Selection::AddSelect (const Handle(SelectMgr_EntityOwner)& theObject->SetSelected (Standard_True); return AIS_SS_Added; } + +//======================================================================= +//function : SelectOwners +//purpose : +//======================================================================= +void AIS_Selection::SelectOwners (const AIS_NListOfEntityOwner& thePickedOwners, + const int theSelScheme, + const Handle(SelectMgr_Filter)& theFilter) +{ + int aSelScheme = theSelScheme; + AIS_NListOfEntityOwner aPrevSelected = Objects(); + if (theSelScheme & AIS_SelectionScheme_Clear) + { + Clear(); + + if (theSelScheme & AIS_SelectionScheme_Switch && + theSelScheme & AIS_SelectionScheme_PickedIfEmpty && + thePickedOwners.Size() < aPrevSelected.Size()) + { + // check if all picked objects are in previous selected list, if so, all objects will be deselected, + // but in mode AIS_SelectionScheme_PickedIfEmpty new picked objects should be selected, here, after Clear, Add + Standard_Boolean anOtherFound = Standard_False; + for (AIS_NListOfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next()) + { + anOtherFound = !aPrevSelected.Contains (aSelIter.Value()); + if (anOtherFound) + break; + } + if (!anOtherFound) + aSelScheme = AIS_SelectionScheme_Add; + } + } + + for (AIS_NListOfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next()) + { + selectOwner(aSelIter.Value(), aPrevSelected, aSelScheme, theFilter); + } +} + +//======================================================================= +//function : selectOwner +//purpose : +//======================================================================= +AIS_SelectStatus AIS_Selection::selectOwner (const Handle(SelectMgr_EntityOwner)& theOwner, + const AIS_NListOfEntityOwner& thePreviousSelected, + const int theSelScheme, + const Handle(SelectMgr_Filter)& theFilter) +{ + if (theOwner.IsNull() || !theOwner->HasSelectable() || !theFilter->IsOk (theOwner)) + return AIS_SS_NotDone; + + if (theSelScheme & AIS_SelectionScheme_Add) + { + return AddSelect (theOwner); + } + else if (theSelScheme & AIS_SelectionScheme_Switch) + { + if (thePreviousSelected.Contains (theOwner)) // was selected, should not be now + { + if (theOwner->IsSelected()) + return Select (theOwner); // deselect + } + else + return AddSelect (theOwner); // was not selected, should be now + } + + return AIS_SS_NotDone; +} diff --git a/src/AIS/AIS_Selection.hxx b/src/AIS/AIS_Selection.hxx index 8e7cf50e91..dc56d6dad6 100644 --- a/src/AIS/AIS_Selection.hxx +++ b/src/AIS/AIS_Selection.hxx @@ -22,6 +22,8 @@ #include #include +class SelectMgr_Filter; + //! Class holding the list of selected owners. class AIS_Selection : public Standard_Transient { @@ -75,6 +77,28 @@ public: //! Return selected object at iterator position. const Handle(SelectMgr_EntityOwner)& Value() const { return myIterator.Value(); } + //! Select or deselect owners depending on the selection scheme + //! \param theOwners elements to change selection state + //! \param theSelScheme selection scheme, defines how owner is selected + //! \param theFilter context filter to skip not acceptable owners + //! \return result of selection + Standard_EXPORT virtual void SelectOwners (const AIS_NListOfEntityOwner& thePickedOwners, + const int theSelScheme, + const Handle(SelectMgr_Filter)& theFilter); + +protected: + //! Select or deselect owner depending on the selection scheme + //! \param theOwner element to change selection state + //! \param thePreviousSelected previous selected objects + //! \param theSelScheme selection scheme, defines how owner is selected + //! \param theFilter context filter to skip not acceptable owners + //! \return result of selection + Standard_EXPORT virtual AIS_SelectStatus selectOwner (const Handle(SelectMgr_EntityOwner)& theOwner, + const AIS_NListOfEntityOwner& thePreviousSelected, + const int theSelScheme, + const Handle(SelectMgr_Filter)& theFilter); + + private: AIS_NListOfEntityOwner myresult; diff --git a/src/AIS/AIS_SelectionScheme.hxx b/src/AIS/AIS_SelectionScheme.hxx new file mode 100644 index 0000000000..d34c3f40c3 --- /dev/null +++ b/src/AIS/AIS_SelectionScheme.hxx @@ -0,0 +1,31 @@ +// Copyright (c) 2019 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. + + +#ifndef _AIS_SelectionScheme_HeaderFile +#define _AIS_SelectionScheme_HeaderFile + + +//! Sets selection schemes for interactive contexts. +//! It is possible to use combination of schemes. +enum AIS_SelectionScheme +{ + AIS_SelectionScheme_Clear = 0x0001, // clears current selection + AIS_SelectionScheme_Add = 0x0002, // add detected object to current selection + AIS_SelectionScheme_Switch = 0x0004, // switch selection state in values selected/deselected + AIS_SelectionScheme_PickedIfEmpty = 0x0008, // if after switch, result selection is empty, select picked objects + AIS_SelectionScheme_ClearAndSwitch = AIS_SelectionScheme_Clear | AIS_SelectionScheme_Switch, + AIS_SelectionScheme_ClearAndAdd = AIS_SelectionScheme_Clear | AIS_SelectionScheme_Add +}; + +#endif // _AIS_SelectionScheme_HeaderFile diff --git a/src/AIS/AIS_SelectionType.hxx b/src/AIS/AIS_SelectionType.hxx new file mode 100644 index 0000000000..22c11aa386 --- /dev/null +++ b/src/AIS/AIS_SelectionType.hxx @@ -0,0 +1,31 @@ +// Copyright (c) 2019 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. + + +#ifndef _AIS_SelectionType_HeaderFile +#define _AIS_SelectionType_HeaderFile + + +//! Sets selection schemes for interactive contexts. +//! It is possible to use combination of schemes. +enum AIS_SelectionType +{ + AIS_SelectionType_Select, + AIS_SelectionType_SelectInRect, + AIS_SelectionType_SelectInPoly, + AIS_SelectionType_ShiftSelect, + AIS_SelectionType_ShiftSelectInRect, + AIS_SelectionType_ShiftSelectInPoly +}; + +#endif // _AIS_SelectionType_HeaderFile diff --git a/src/AIS/FILES b/src/AIS/FILES index b8555d373f..5328697ca3 100644 --- a/src/AIS/FILES +++ b/src/AIS/FILES @@ -141,6 +141,8 @@ AIS_Selection.cxx AIS_Selection.hxx AIS_SelectStatus.hxx AIS_SelectionModesConcurrency.hxx +AIS_SelectionScheme.hxx +AIS_SelectionType.hxx AIS_SequenceOfDimension.hxx AIS_SequenceOfInteractive.hxx AIS_Shape.cxx