From: age Date: Tue, 24 Nov 2020 13:14:19 +0000 (+0300) Subject: 0030737: Visualization - implementing new selection schemes in context X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=d79a0af18714704a00290f33591a5f707a6c8293;p=occt-copy.git 0030737: Visualization - implementing new selection schemes in context Improved AIS_SelectionScheme_ReplaceExtra scheme (now is a part of AIS_SelectionScheme_Replace) Replaced AIS_NListOfEntityOwner with AIS_NArray1OfEntityOwner Fixed bug with incorrect highlighting in xor mode (select several times the same objects) Fixed selections filters Cherry picked a new highlighting logic from 75cf82505b83f6c85f43b1327e13bd5b88355ff5 --- diff --git a/src/AIS/AIS_InteractiveContext.hxx b/src/AIS/AIS_InteractiveContext.hxx index fc34f7f603..c88e2be568 100644 --- a/src/AIS/AIS_InteractiveContext.hxx +++ b/src/AIS/AIS_InteractiveContext.hxx @@ -568,7 +568,7 @@ public: //! @name Selection management //! @param theOwners owners to change selection state //! @param theSelScheme selection scheme //! @return picking status - Standard_EXPORT AIS_StatusOfPick Select (const AIS_NListOfEntityOwner& theOwners, + Standard_EXPORT AIS_StatusOfPick Select (const AIS_NArray1OfEntityOwner& theOwners, const AIS_SelectionScheme theSelScheme); //! Fits the view correspondingly to the bounds of selected objects. diff --git a/src/AIS/AIS_InteractiveContext_1.cxx b/src/AIS/AIS_InteractiveContext_1.cxx index 99626570ca..bfb2f27766 100644 --- a/src/AIS/AIS_InteractiveContext_1.cxx +++ b/src/AIS/AIS_InteractiveContext_1.cxx @@ -202,6 +202,7 @@ void AIS_InteractiveContext::unhighlightOwners (const AIS_NListOfEntityOwner& th { (*aStatusPtr)->SetHilightStatus (Standard_False); } + (*aStatusPtr)->SetHilightStyle (Handle(Prs3d_Drawer)()); } for (NCollection_IndexedMap::Iterator anIter (anObjToClear); anIter.More(); anIter.Next()) { @@ -501,16 +502,16 @@ AIS_StatusOfPick AIS_InteractiveContext::SelectRectangle (const Graphic3d_Vec2i& } myLastActiveView = theView.get(); - if (myAutoHilight) - { - UnhilightSelected (Standard_False); - } myMainSel->Pick (thePntMin.x(), thePntMin.y(), thePntMax.x(), thePntMax.y(), theView); - AIS_NListOfEntityOwner aPickedOwners; - for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter) + AIS_NArray1OfEntityOwner aPickedOwners; + if (myMainSel->NbPicked() > 0) { - aPickedOwners.Append (myMainSel->Picked (aPickIter)); + aPickedOwners.Resize (1, myMainSel->NbPicked(), Standard_False); + for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter) + { + aPickedOwners.ChangeValue (aPickIter) = myMainSel->Picked (aPickIter); + } } return Select (aPickedOwners, theSelScheme); @@ -530,16 +531,16 @@ AIS_StatusOfPick AIS_InteractiveContext::SelectPolygon (const TColgp_Array1OfPnt } myLastActiveView = theView.get(); - if (myAutoHilight) - { - UnhilightSelected (Standard_False); - } myMainSel->Pick (thePolyline, theView); - AIS_NListOfEntityOwner aPickedOwners; - for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter) + AIS_NArray1OfEntityOwner aPickedOwners; + if (myMainSel->NbPicked() > 0) { - aPickedOwners.Append (myMainSel->Picked (aPickIter)); + aPickedOwners.Resize (1, myMainSel->NbPicked(), Standard_False); + for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter) + { + aPickedOwners.ChangeValue (aPickIter) = myMainSel->Picked (aPickIter); + } } return Select (aPickedOwners, theSelScheme); @@ -558,18 +559,17 @@ AIS_StatusOfPick AIS_InteractiveContext::SelectPoint (const Graphic3d_Vec2i& throw Standard_ProgramError ("AIS_InteractiveContext::SelectPoint() - invalid argument"); } - if (myAutoHilight) - { - UnhilightSelected (Standard_False); - } - myLastActiveView = theView.get(); myMainSel->Pick (thePnt.x(), thePnt.y(), theView); - AIS_NListOfEntityOwner aPickedOwners; - for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter) + AIS_NArray1OfEntityOwner aPickedOwners; + if (myMainSel->NbPicked() > 0) { - aPickedOwners.Append (myMainSel->Picked (aPickIter)); + aPickedOwners.Resize (1, myMainSel->NbPicked(), Standard_False); + for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter) + { + aPickedOwners.ChangeValue (aPickIter) = myMainSel->Picked (aPickIter); + } } return Select (aPickedOwners, theSelScheme); @@ -595,13 +595,8 @@ AIS_StatusOfPick AIS_InteractiveContext::SelectDetected (const AIS_SelectionSche } } - if (myAutoHilight && theSelScheme != AIS_SelectionScheme_XOR) - { - UnhilightSelected (Standard_False); - } - - AIS_NListOfEntityOwner aPickedOwners; - aPickedOwners.Append (myLastPicked); + AIS_NArray1OfEntityOwner aPickedOwners(1, 1); + aPickedOwners.ChangeValue (1) = myLastPicked; return Select (aPickedOwners, theSelScheme); } @@ -712,21 +707,64 @@ AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const TColgp_Array1OfPnt2d //function : Select //purpose : //======================================================================= -AIS_StatusOfPick AIS_InteractiveContext::Select (const AIS_NListOfEntityOwner& theOwners, +AIS_StatusOfPick AIS_InteractiveContext::Select (const AIS_NArray1OfEntityOwner& theOwners, const AIS_SelectionScheme theSelScheme) { - // all objects detected by the selector are taken, previous current objects are emptied, - // new objects are put... + NCollection_IndexedMap aSelOwnerMap (myAutoHilight ? mySelection->Objects().Size() : 0); if (myAutoHilight) { clearDynamicHighlight(); + + // collect currently selected owners + for (AIS_NListOfEntityOwner::Iterator anOwnerIter (mySelection->Objects()); anOwnerIter.More(); anOwnerIter.Next()) + { + aSelOwnerMap.Add (anOwnerIter.Value()); + } } mySelection->SelectOwners (theOwners, theSelScheme, myFilters); if (myAutoHilight) { - HilightSelected (Standard_False); + // collect lists of owners to unhighlight (unselected) and to highlight (selected) + AIS_NListOfEntityOwner anOwnersToUnhighlight, anOwnersToHighlight; + for (AIS_NListOfEntityOwner::Iterator anOwnerIter (mySelection->Objects()); anOwnerIter.More(); anOwnerIter.Next()) + { + // add newly selected owners + const Handle(SelectMgr_EntityOwner)& anOwner = anOwnerIter.Value(); + if (!aSelOwnerMap.RemoveKey (anOwner)) + { + // newly selected owner + anOwnersToHighlight.Append (anOwner); + } + else + { + // already selected owner + if (!anOwner->IsAutoHilight() + && theSelScheme != AIS_SelectionScheme_XOR + && theSelScheme != AIS_SelectionScheme_Add) + { + // hack to perform AIS_InteractiveObject::ClearSelected() before highlighting + anOwnersToUnhighlight.Append (anOwner); + anOwnersToHighlight.Append (anOwner); + } + else if (anOwner->IsForcedHilight() + || !anOwner->IsAutoHilight()) + { + anOwnersToHighlight.Append (anOwner); + } + } + } + + for (NCollection_IndexedMap::Iterator anOwnerIter (aSelOwnerMap); anOwnerIter.More(); anOwnerIter.Next()) + { + // owners removed from selection + const Handle(SelectMgr_EntityOwner)& anOwner = anOwnerIter.Value(); + anOwnersToUnhighlight.Append (anOwner); + } + + unhighlightOwners (anOwnersToUnhighlight); + highlightOwners (anOwnersToHighlight); } Standard_Integer aSelNum = NbSelected(); diff --git a/src/AIS/AIS_NArray1OfEntityOwner.hxx b/src/AIS/AIS_NArray1OfEntityOwner.hxx new file mode 100644 index 0000000000..87bd4bffcf --- /dev/null +++ b/src/AIS/AIS_NArray1OfEntityOwner.hxx @@ -0,0 +1,24 @@ +// Created on: 2003-05-04 +// Created by: Alexander Grigoriev (a-grigoriev@opencascade.com) +// Copyright (c) 2003-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. + +#ifndef _AIS_NArray1Transient_HeaderFile +#define _AIS_NArray1Transient_HeaderFile + +#include +#include + +typedef NCollection_Array1 AIS_NArray1OfEntityOwner; + +#endif diff --git a/src/AIS/AIS_Selection.cxx b/src/AIS/AIS_Selection.cxx index 10b1410367..659b67d0d9 100644 --- a/src/AIS/AIS_Selection.cxx +++ b/src/AIS/AIS_Selection.cxx @@ -137,7 +137,7 @@ AIS_SelectStatus AIS_Selection::AddSelect (const Handle(SelectMgr_EntityOwner)& //function : SelectOwners //purpose : //======================================================================= -void AIS_Selection::SelectOwners (const AIS_NListOfEntityOwner& thePickedOwners, +void AIS_Selection::SelectOwners (const AIS_NArray1OfEntityOwner& thePickedOwners, const AIS_SelectionScheme theSelScheme, const Handle(SelectMgr_Filter)& theFilter) { @@ -147,10 +147,32 @@ void AIS_Selection::SelectOwners (const AIS_NListOfEntityOwner& thePickedOwners, { return; } + case AIS_SelectionScheme_ReplaceExtra: + { + // If picked owners is equivalent to the selected then just clear selected + // Else go to AIS_SelectionScheme_Replace + if (thePickedOwners.Size() == myresult.Size()) + { + Standard_Boolean isTheSame = Standard_True; + for (AIS_NArray1OfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next()) + { + if (!myResultMap.IsBound (aSelIter.Value())) + { + isTheSame = Standard_False; + break; + } + } + if (isTheSame) + { + Clear(); + return; + } + } + } case AIS_SelectionScheme_Replace: { Clear(); - for (AIS_NListOfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next()) + for (AIS_NArray1OfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next()) { appendOwner (aSelIter.Value(), theFilter); } @@ -159,7 +181,7 @@ void AIS_Selection::SelectOwners (const AIS_NListOfEntityOwner& thePickedOwners, } case AIS_SelectionScheme_Add: { - for (AIS_NListOfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next()) + for (AIS_NArray1OfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next()) { appendOwner (aSelIter.Value(), theFilter); } @@ -167,7 +189,7 @@ void AIS_Selection::SelectOwners (const AIS_NListOfEntityOwner& thePickedOwners, } case AIS_SelectionScheme_Remove: { - for (AIS_NListOfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next()) + for (AIS_NArray1OfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next()) { if (myResultMap.IsBound (aSelIter.Value())) { @@ -178,12 +200,12 @@ void AIS_Selection::SelectOwners (const AIS_NListOfEntityOwner& thePickedOwners, } case AIS_SelectionScheme_XOR: { - for (AIS_NListOfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next()) + for (AIS_NArray1OfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next()) { const Handle(SelectMgr_EntityOwner)& anOwner = aSelIter.Value(); if (anOwner.IsNull() || !anOwner->HasSelectable() - || !theFilter->IsOk (anOwner)) + || !theFilter->IsOk (anOwner, SelectMgr_FilterReaction_Select)) { continue; } @@ -197,35 +219,6 @@ void AIS_Selection::SelectOwners (const AIS_NListOfEntityOwner& thePickedOwners, Clear(); return; } - case AIS_SelectionScheme_ReplaceExtra: - { - AIS_NListOfEntityOwner aPrevSelected = Objects(); - Clear(); - - Standard_Boolean toAppend = false; - if (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) - toAppend = Standard_True; - } - for (AIS_NListOfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next()) - { - if (toAppend) - appendOwner (aSelIter.Value(), theFilter); - else - XOROwner(aSelIter.Value(), aPrevSelected, theFilter); - } - return; - } } } @@ -238,7 +231,7 @@ AIS_SelectStatus AIS_Selection::appendOwner (const Handle(SelectMgr_EntityOwner) { if (theOwner.IsNull() || !theOwner->HasSelectable() - || !theFilter->IsOk (theOwner)) + || !theFilter->IsOk (theOwner, SelectMgr_FilterReaction_Select)) { return AIS_SS_NotDone; } @@ -254,7 +247,7 @@ AIS_SelectStatus AIS_Selection::XOROwner (const Handle(SelectMgr_EntityOwner)& t const AIS_NListOfEntityOwner& thePreviousSelected, const Handle(SelectMgr_Filter)& theFilter) { - if (theOwner.IsNull() || !theOwner->HasSelectable() || !theFilter->IsOk (theOwner)) + if (theOwner.IsNull() || !theOwner->HasSelectable() || !theFilter->IsOk (theOwner, SelectMgr_FilterReaction_Select)) return AIS_SS_NotDone; if (thePreviousSelected.Contains (theOwner)) // was selected, should not be now diff --git a/src/AIS/AIS_Selection.hxx b/src/AIS/AIS_Selection.hxx index 2e0bca8380..d6b481f587 100644 --- a/src/AIS/AIS_Selection.hxx +++ b/src/AIS/AIS_Selection.hxx @@ -18,6 +18,7 @@ #define _AIS_Selection_HeaderFile #include +#include #include #include #include @@ -82,7 +83,7 @@ public: //! @param theOwners [in] elements to change selection state //! @param theSelScheme [in] selection scheme, defines how owner is selected //! @param theFilter [in] context filter to skip not acceptable owners - Standard_EXPORT virtual void SelectOwners (const AIS_NListOfEntityOwner& thePickedOwners, + Standard_EXPORT virtual void SelectOwners (const AIS_NArray1OfEntityOwner& thePickedOwners, const AIS_SelectionScheme theSelScheme, const Handle(SelectMgr_Filter)& theFilter); diff --git a/src/AIS/FILES b/src/AIS/FILES index f73a277e72..19217209da 100644 --- a/src/AIS/FILES +++ b/src/AIS/FILES @@ -73,6 +73,7 @@ AIS_MultipleConnectedInteractive.hxx AIS_MultipleConnectedInteractive.lxx AIS_NavigationMode.hxx AIS_NListOfEntityOwner.hxx +AIS_NArray1OfEntityOwner.hxx AIS_Plane.cxx AIS_Plane.hxx AIS_PlaneTrihedron.cxx @@ -89,7 +90,6 @@ AIS_Selection.hxx AIS_SelectStatus.hxx AIS_SelectionModesConcurrency.hxx AIS_SelectionScheme.hxx -AIS_SequenceOfDimension.hxx AIS_SequenceOfInteractive.hxx AIS_Shape.cxx AIS_Shape.hxx