1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-29 14:00:49 +03:00

0030737: Visualization - implementing new selection schemes in context

AIS_SelectionScheme enumeration is defined to set which selection behaviour is used in Select of context
AIS_InteractiveContext is corrected to use single Select method instead of combination of Select/ShiftSelect methods with a selection scheme parameter.
Upgrade: Select() -> SelectDetected/Rectangle/Polygon(AIS_SelectionScheme_Replace), ShiftSelect -> SelectDetected/Rectangle/Polygon(AIS_SelectionScheme_XOR)
This commit is contained in:
nds
2020-09-18 21:36:05 +03:00
committed by bugmaster
parent b735354545
commit 75cf82505b
25 changed files with 656 additions and 224 deletions

View File

@@ -25,10 +25,12 @@
#include <AIS_ListOfInteractive.hxx>
#include <AIS_Selection.hxx>
#include <AIS_SelectionModesConcurrency.hxx>
#include <AIS_SelectionScheme.hxx>
#include <AIS_StatusOfDetection.hxx>
#include <AIS_StatusOfPick.hxx>
#include <AIS_TypeOfIso.hxx>
#include <Aspect_TypeOfFacingModel.hxx>
#include <Graphic3d_Vec2.hxx>
#include <Prs3d_Drawer.hxx>
#include <Prs3d_TypeOfHighlight.hxx>
#include <PrsMgr_PresentationManager3d.hxx>
@@ -470,8 +472,49 @@ public: //! @name Selection management
return AddSelect (theObject->GlobalSelOwner());
}
//! Selects objects within the bounding rectangle.
//! Viewer should be explicitly redrawn after selection.
//! @param thePntMin [in] rectangle lower point (in pixels)
//! @param thePntMax [in] rectangle upper point (in pixels)
//! @param theView [in] active view where rectangle is defined
//! @param theSelScheme [in] selection scheme
//! @return picking status
//! @sa StdSelect_ViewerSelector3d::AllowOverlapDetection()
Standard_EXPORT AIS_StatusOfPick SelectRectangle (const Graphic3d_Vec2i& thePntMin,
const Graphic3d_Vec2i& thePntMax,
const Handle(V3d_View)& theView,
const AIS_SelectionScheme theSelScheme = AIS_SelectionScheme_Replace);
//! Select everything found in the polygon defined by bounding polyline.
//! Viewer should be explicitly redrawn after selection.
//! @param thePolyline [in] polyline defining polygon bounds (in pixels)
//! @param theView [in] active view where polyline is defined
//! @param theSelScheme [in] selection scheme
//! @return picking status
Standard_EXPORT AIS_StatusOfPick SelectPolygon (const TColgp_Array1OfPnt2d& thePolyline,
const Handle(V3d_View)& theView,
const AIS_SelectionScheme theSelScheme = AIS_SelectionScheme_Replace);
//! Selects the topmost object picked by the point in the view,
//! Viewer should be explicitly redrawn after selection.
//! @param thePnt [in] point pixel coordinates within the view
//! @param theView [in] active view where point is defined
//! @param theSelScheme [in] selection scheme
//! @return picking status
Standard_EXPORT AIS_StatusOfPick SelectPoint (const Graphic3d_Vec2i& thePnt,
const Handle(V3d_View)& theView,
const AIS_SelectionScheme theSelScheme = AIS_SelectionScheme_Replace);
//! Select and hilights the previous detected via AIS_InteractiveContext::MoveTo() method;
//! unhilights the previous picked.
//! Viewer should be explicitly redrawn after selection.
//! @param theSelScheme [in] selection scheme
//! @return picking status
Standard_EXPORT AIS_StatusOfPick SelectDetected (const AIS_SelectionScheme theSelScheme = AIS_SelectionScheme_Replace);
//! 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_DEPRECATED("This method is deprecated - SelectRectangle() taking AIS_SelectionScheme_Replace should be called instead")
Standard_EXPORT AIS_StatusOfPick Select (const Standard_Integer theXPMin,
const Standard_Integer theYPMin,
const Standard_Integer theXPMax,
@@ -480,27 +523,32 @@ public: //! @name Selection management
const Standard_Boolean theToUpdateViewer);
//! polyline selection; clears the previous picked list
Standard_DEPRECATED("This method is deprecated - SelectPolygon() taking AIS_SelectionScheme_Replace should be called instead")
Standard_EXPORT AIS_StatusOfPick Select (const TColgp_Array1OfPnt2d& thePolyline,
const Handle(V3d_View)& theView,
const Standard_Boolean theToUpdateViewer);
//! Stores and hilights the previous detected; Unhilights the previous picked.
//! @sa MoveTo().
Standard_DEPRECATED("This method is deprecated - SelectDetected() taking AIS_SelectionScheme_Replace should be called instead")
Standard_EXPORT AIS_StatusOfPick Select (const Standard_Boolean theToUpdateViewer);
//! Adds the last detected to the list of previous picked.
//! If the last detected was already declared as picked, removes it from the Picked List.
//! @sa MoveTo().
Standard_DEPRECATED("This method is deprecated - SelectDetected() taking AIS_SelectionScheme_XOR should be called instead")
Standard_EXPORT AIS_StatusOfPick ShiftSelect (const Standard_Boolean theToUpdateViewer);
//! Adds the last detected to the list of previous picked.
//! If the last detected was already declared as picked, removes it from the Picked List.
Standard_DEPRECATED("This method is deprecated - SelectPolygon() taking AIS_SelectionScheme_XOR should be called instead")
Standard_EXPORT AIS_StatusOfPick ShiftSelect (const TColgp_Array1OfPnt2d& thePolyline,
const Handle(V3d_View)& theView,
const Standard_Boolean theToUpdateViewer);
//! Rectangle of selection; adds new detected entities into the picked list,
//! removes the detected entities that were already stored.
Standard_DEPRECATED("This method is deprecated - SelectRectangle() taking AIS_SelectionScheme_XOR should be called instead")
Standard_EXPORT AIS_StatusOfPick ShiftSelect (const Standard_Integer theXPMin,
const Standard_Integer theYPMin,
const Standard_Integer theXPMax,
@@ -511,6 +559,13 @@ public: //! @name Selection management
//! Returns bounding box of selected objects.
Standard_EXPORT Bnd_Box BoundingBoxOfSelection() const;
//! Sets list of owner selected/deselected using specified selection scheme.
//! @param theOwners owners to change selection state
//! @param theSelScheme selection scheme
//! @return picking status
Standard_EXPORT AIS_StatusOfPick Select (const AIS_NArray1OfEntityOwner& theOwners,
const AIS_SelectionScheme theSelScheme);
//! Fits the view correspondingly to the bounds of selected objects.
//! Infinite objects are ignored if infinite state of AIS_InteractiveObject is set to true.
Standard_EXPORT void FitSelected (const Handle(V3d_View)& theView,

View File

@@ -198,6 +198,7 @@ void AIS_InteractiveContext::unhighlightOwners (const AIS_NListOfEntityOwner& th
{
(*aStatusPtr)->SetHilightStatus (Standard_False);
}
(*aStatusPtr)->SetHilightStyle (Handle(Prs3d_Drawer)());
}
for (NCollection_IndexedMap<Handle(AIS_InteractiveObject)>::Iterator anIter (anObjToClear); anIter.More(); anIter.Next())
{
@@ -482,95 +483,100 @@ AIS_StatusOfPick AIS_InteractiveContext::AddSelect (const Handle(SelectMgr_Entit
}
//=======================================================================
//function : Select
//purpose :
//function : SelectRectangle
//purpose :
//=======================================================================
AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Integer theXPMin,
const Standard_Integer theYPMin,
const Standard_Integer theXPMax,
const Standard_Integer theYPMax,
const Handle(V3d_View)& theView,
const Standard_Boolean toUpdateViewer)
AIS_StatusOfPick AIS_InteractiveContext::SelectRectangle (const Graphic3d_Vec2i& thePntMin,
const Graphic3d_Vec2i& thePntMax,
const Handle(V3d_View)& theView,
const AIS_SelectionScheme theSelScheme)
{
if (theView->Viewer() != myMainVwr)
{
throw Standard_ProgramError ("AIS_InteractiveContext::Select() - invalid argument");
throw Standard_ProgramError ("AIS_InteractiveContext::SelectRectangle() - invalid argument");
}
// all objects detected by the selector are taken, previous current objects are emptied,
// new objects are put...
ClearSelected (Standard_False);
myLastActiveView = theView.get();
myMainSel->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
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;
myMainSel->Pick (thePntMin.x(), thePntMin.y(), thePntMax.x(), thePntMax.y(), theView);
mySelection->Select (aCurOwner);
AIS_NArray1OfEntityOwner aPickedOwners;
if (myMainSel->NbPicked() > 0)
{
aPickedOwners.Resize (1, myMainSel->NbPicked(), false);
for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter)
{
aPickedOwners.SetValue (aPickIter, myMainSel->Picked (aPickIter));
}
}
if (myAutoHilight)
{
HilightSelected (toUpdateViewer);
}
Standard_Integer aSelNum = NbSelected();
return (aSelNum == 0) ? AIS_SOP_NothingSelected
: (aSelNum == 1) ? AIS_SOP_OneSelected
: AIS_SOP_SeveralSelected;
return Select (aPickedOwners, theSelScheme);
}
//=======================================================================
//function : Select
//purpose : Selection by polyline
//function : SelectPolygon
//purpose :
//=======================================================================
AIS_StatusOfPick AIS_InteractiveContext::Select (const TColgp_Array1OfPnt2d& thePolyline,
const Handle(V3d_View)& theView,
const Standard_Boolean toUpdateViewer)
AIS_StatusOfPick AIS_InteractiveContext::SelectPolygon (const TColgp_Array1OfPnt2d& thePolyline,
const Handle(V3d_View)& theView,
const AIS_SelectionScheme theSelScheme)
{
if (theView->Viewer() != myMainVwr)
{
throw Standard_ProgramError ("AIS_InteractiveContext::Select() - invalid argument");
throw Standard_ProgramError ("AIS_InteractiveContext::SelectPolygon() - invalid argument");
}
// all objects detected by the selector are taken, previous current objects are emptied,
// new objects are put...
ClearSelected (Standard_False);
myLastActiveView = theView.get();
myMainSel->Pick (thePolyline, theView);
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);
AIS_NArray1OfEntityOwner aPickedOwners;
if (myMainSel->NbPicked() > 0)
{
aPickedOwners.Resize (1, myMainSel->NbPicked(), false);
for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter)
{
aPickedOwners.SetValue (aPickIter, myMainSel->Picked (aPickIter));
}
}
if (myAutoHilight)
{
HilightSelected (toUpdateViewer);
}
Standard_Integer aSelNum = NbSelected();
return (aSelNum == 0) ? AIS_SOP_NothingSelected
: (aSelNum == 1) ? AIS_SOP_OneSelected
: AIS_SOP_SeveralSelected;
return Select (aPickedOwners, theSelScheme);
}
//=======================================================================
//function : Select
//purpose :
//function : SelectPoint
//purpose :
//=======================================================================
AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Boolean toUpdateViewer)
AIS_StatusOfPick AIS_InteractiveContext::SelectPoint (const Graphic3d_Vec2i& thePnt,
const Handle(V3d_View)& theView,
const AIS_SelectionScheme theSelScheme)
{
if (!myLastPicked.IsNull())
if (theView->Viewer() != myMainVwr)
{
throw Standard_ProgramError ("AIS_InteractiveContext::SelectPoint() - invalid argument");
}
myLastActiveView = theView.get();
myMainSel->Pick (thePnt.x(), thePnt.y(), theView);
AIS_NArray1OfEntityOwner aPickedOwners;
if (myMainSel->NbPicked() > 0)
{
aPickedOwners.Resize (1, myMainSel->NbPicked(), false);
for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter)
{
aPickedOwners.SetValue (aPickIter, myMainSel->Picked (aPickIter));
}
}
return Select (aPickedOwners, theSelScheme);
}
//=======================================================================
//function : SelectDetected
//purpose :
//=======================================================================
AIS_StatusOfPick AIS_InteractiveContext::SelectDetected (const AIS_SelectionScheme theSelScheme)
{
if (theSelScheme == AIS_SelectionScheme_Replace && !myLastPicked.IsNull())
{
Graphic3d_Vec2i aMousePos (-1, -1);
if (myMainSel->GetManager().GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Point)
@@ -582,54 +588,76 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Boolean toUpdate
{
return AIS_SOP_NothingSelected;
}
if (myAutoHilight)
{
clearDynamicHighlight();
}
if (!myLastPicked->IsSelected()
|| myLastPicked->IsForcedHilight()
|| NbSelected() > 1)
{
SetSelected (myLastPicked, Standard_False);
if(toUpdateViewer)
{
UpdateCurrentViewer();
}
}
}
else
AIS_NArray1OfEntityOwner aPickedOwners (1, 1);
aPickedOwners.SetValue (1, myLastPicked);
return Select (aPickedOwners, theSelScheme);
}
//=======================================================================
//function : Select
//purpose :
//=======================================================================
AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Integer theXPMin,
const Standard_Integer theYPMin,
const Standard_Integer theXPMax,
const Standard_Integer theYPMax,
const Handle(V3d_View)& theView,
const Standard_Boolean theToUpdateViewer)
{
AIS_StatusOfPick aStatus = SelectRectangle (Graphic3d_Vec2i (theXPMin, theYPMin),
Graphic3d_Vec2i (theXPMax, theYPMax),
theView);
if (theToUpdateViewer)
{
ClearSelected (toUpdateViewer);
UpdateCurrentViewer();
}
return aStatus;
}
Standard_Integer aSelNum = NbSelected();
//=======================================================================
//function : Select
//purpose : Selection by polyline
//=======================================================================
AIS_StatusOfPick AIS_InteractiveContext::Select (const TColgp_Array1OfPnt2d& thePolyline,
const Handle(V3d_View)& theView,
const Standard_Boolean theToUpdateViewer)
{
AIS_StatusOfPick aStatus = SelectPolygon (thePolyline, theView);
if (theToUpdateViewer)
{
UpdateCurrentViewer();
}
return aStatus;
}
return (aSelNum == 0) ? AIS_SOP_NothingSelected
: (aSelNum == 1) ? AIS_SOP_OneSelected
: AIS_SOP_SeveralSelected;
//=======================================================================
//function : Select
//purpose :
//=======================================================================
AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Boolean theToUpdateViewer)
{
AIS_StatusOfPick aStatus = SelectDetected();
if (theToUpdateViewer)
{
UpdateCurrentViewer();
}
return aStatus;
}
//=======================================================================
//function : ShiftSelect
//purpose :
//=======================================================================
AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Boolean toUpdateViewer)
AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Boolean theToUpdateViewer)
{
if (myAutoHilight)
AIS_StatusOfPick aStatus = SelectDetected (AIS_SelectionScheme_XOR);
if (theToUpdateViewer)
{
clearDynamicHighlight();
UpdateCurrentViewer();
}
if (!myLastPicked.IsNull())
{
AddOrRemoveSelected (myLastPicked, toUpdateViewer);
}
Standard_Integer aSelNum = NbSelected();
return (aSelNum == 0) ? AIS_SOP_NothingSelected
: (aSelNum == 1) ? AIS_SOP_OneSelected
: AIS_SOP_SeveralSelected;
return aStatus;
}
//=======================================================================
@@ -641,39 +669,17 @@ AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Integer the
const Standard_Integer theXPMax,
const Standard_Integer theYPMax,
const Handle(V3d_View)& theView,
const Standard_Boolean toUpdateViewer)
const Standard_Boolean theToUpdateViewer)
{
if (theView->Viewer() != myMainVwr)
AIS_StatusOfPick aStatus = SelectRectangle (Graphic3d_Vec2i (theXPMin, theYPMin),
Graphic3d_Vec2i (theXPMax, theYPMax),
theView,
AIS_SelectionScheme_XOR);
if (theToUpdateViewer)
{
throw Standard_ProgramError ("AIS_InteractiveContext::ShiftSelect() - invalid argument");
UpdateCurrentViewer();
}
myLastActiveView = theView.get();
if (myAutoHilight)
{
UnhilightSelected (Standard_False);
}
myMainSel->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
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);
}
if (myAutoHilight)
{
HilightSelected (toUpdateViewer);
}
Standard_Integer aSelNum = NbSelected();
return (aSelNum == 0) ? AIS_SOP_NothingSelected
: (aSelNum == 1) ? AIS_SOP_OneSelected
: AIS_SOP_SeveralSelected;
return aStatus;
}
//=======================================================================
@@ -682,35 +688,81 @@ AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Integer the
//=======================================================================
AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const TColgp_Array1OfPnt2d& thePolyline,
const Handle(V3d_View)& theView,
const Standard_Boolean toUpdateViewer)
const Standard_Boolean theToUpdateViewer)
{
if (theView->Viewer() != myMainVwr)
AIS_StatusOfPick aStatus = SelectPolygon (thePolyline, theView, AIS_SelectionScheme_XOR);
if (theToUpdateViewer)
{
throw Standard_ProgramError ("AIS_InteractiveContext::ShiftSelect() - invalid argument");
UpdateCurrentViewer();
}
return aStatus;
}
myLastActiveView = theView.get();
//=======================================================================
//function : Select
//purpose :
//=======================================================================
AIS_StatusOfPick AIS_InteractiveContext::Select (const AIS_NArray1OfEntityOwner& theOwners,
const AIS_SelectionScheme theSelScheme)
{
NCollection_IndexedMap<Handle(SelectMgr_EntityOwner)> aSelOwnerMap (myAutoHilight ? mySelection->Objects().Size() : 0);
if (myAutoHilight)
{
UnhilightSelected (Standard_False);
}
myMainSel->Pick (thePolyline, theView);
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;
clearDynamicHighlight();
mySelection->Select (anOwner);
// collect currently selected owners
for (AIS_NListOfEntityOwner::Iterator anOwnerIter (mySelection->Objects()); anOwnerIter.More(); anOwnerIter.Next())
{
aSelOwnerMap.Add (anOwnerIter.Value());
}
}
mySelection->SelectOwners (theOwners, theSelScheme, myMainSel->GetManager().IsOverlapAllowed(), myFilters);
if (myAutoHilight)
{
HilightSelected (toUpdateViewer);
// 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<Handle(SelectMgr_EntityOwner)>::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, Handle(Prs3d_Drawer)());
}
Standard_Integer aSelNum = NbSelected();
return (aSelNum == 0) ? AIS_SOP_NothingSelected
: (aSelNum == 1) ? AIS_SOP_OneSelected
: AIS_SOP_SeveralSelected;

View File

@@ -0,0 +1,22 @@
// Copyright (c) 2020 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_NArray1OfEntityOwner_HeaderFile
#define _AIS_NArray1OfEntityOwner_HeaderFile
#include <NCollection_Array1.hxx>
#include <SelectMgr_EntityOwner.hxx>
typedef NCollection_Array1<Handle(SelectMgr_EntityOwner)> AIS_NArray1OfEntityOwner;
#endif // _AIS_NArray1OfEntityOwner_HeaderFile

View File

@@ -15,6 +15,8 @@
#include <AIS_Selection.hxx>
#include <AIS_InteractiveObject.hxx>
#include <AIS_SelectionScheme.hxx>
#include <SelectMgr_Filter.hxx>
IMPLEMENT_STANDARD_RTTIEXT(AIS_Selection, Standard_Transient)
@@ -130,3 +132,89 @@ 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_NArray1OfEntityOwner& thePickedOwners,
const AIS_SelectionScheme theSelScheme,
const Standard_Boolean theToAllowSelOverlap,
const Handle(SelectMgr_Filter)& theFilter)
{
(void )theToAllowSelOverlap;
switch (theSelScheme)
{
case AIS_SelectionScheme_UNKNOWN:
{
return;
}
case AIS_SelectionScheme_Replace:
{
Clear();
for (AIS_NArray1OfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next())
{
appendOwner (aSelIter.Value(), theFilter);
}
return;
}
case AIS_SelectionScheme_Add:
{
for (AIS_NArray1OfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next())
{
appendOwner (aSelIter.Value(), theFilter);
}
return;
}
case AIS_SelectionScheme_Remove:
{
for (AIS_NArray1OfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next())
{
if (myResultMap.IsBound (aSelIter.Value()))
{
Select (aSelIter.Value());
}
}
return;
}
case AIS_SelectionScheme_XOR:
{
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))
{
continue;
}
Select (anOwner);
}
return;
}
case AIS_SelectionScheme_Clear:
{
Clear();
return;
}
}
}
//=======================================================================
//function : appendOwner
//purpose :
//=======================================================================
AIS_SelectStatus AIS_Selection::appendOwner (const Handle(SelectMgr_EntityOwner)& theOwner,
const Handle(SelectMgr_Filter)& theFilter)
{
if (theOwner.IsNull()
|| !theOwner->HasSelectable()
|| !theFilter->IsOk (theOwner))
{
return AIS_SS_NotDone;
}
return AddSelect (theOwner);
}

View File

@@ -17,11 +17,15 @@
#ifndef _AIS_Selection_HeaderFile
#define _AIS_Selection_HeaderFile
#include <AIS_NArray1OfEntityOwner.hxx>
#include <AIS_NListOfEntityOwner.hxx>
#include <AIS_SelectionScheme.hxx>
#include <AIS_SelectStatus.hxx>
#include <Standard.hxx>
#include <Standard_Type.hxx>
class SelectMgr_Filter;
//! Class holding the list of selected owners.
class AIS_Selection : public Standard_Transient
{
@@ -75,7 +79,26 @@ public:
//! Return selected object at iterator position.
const Handle(SelectMgr_EntityOwner)& Value() const { return myIterator.Value(); }
private:
//! Select or deselect owners depending on the selection scheme.
//! @param theOwners [in] elements to change selection state
//! @param theSelScheme [in] selection scheme, defines how owner is selected
//! @param theToAllowSelOverlap [in] selection flag, if true - overlapped entities are allowed
//! @param theFilter [in] context filter to skip not acceptable owners
Standard_EXPORT virtual void SelectOwners (const AIS_NArray1OfEntityOwner& thePickedOwners,
const AIS_SelectionScheme theSelScheme,
const Standard_Boolean theToAllowSelOverlap,
const Handle(SelectMgr_Filter)& theFilter);
protected:
//! Append the owner into the current selection if filter is Ok.
//! @param theOwner [in] element to change selection state
//! @param theFilter [in] context filter to skip not acceptable owners
//! @return result of selection
Standard_EXPORT virtual AIS_SelectStatus appendOwner (const Handle(SelectMgr_EntityOwner)& theOwner,
const Handle(SelectMgr_Filter)& theFilter);
protected:
AIS_NListOfEntityOwner myresult;
AIS_NListOfEntityOwner::Iterator myIterator;

View File

@@ -0,0 +1,28 @@
// 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.
enum AIS_SelectionScheme
{
AIS_SelectionScheme_UNKNOWN = -1, //!< undefined scheme
AIS_SelectionScheme_Replace = 0, //!< clears current selection and select detected objects
AIS_SelectionScheme_Add, //!< adds detected object to current selection
AIS_SelectionScheme_Remove, //!< removes detected object from the current selection
AIS_SelectionScheme_XOR, //!< performs XOR for detected objects, other selected not touched
AIS_SelectionScheme_Clear //!< clears current selection
};
#endif // _AIS_SelectionScheme_HeaderFile

View File

@@ -2571,7 +2571,7 @@ void AIS_ViewController::handleXRPicking (const Handle(AIS_InteractiveContext)&
&& aTrigClick.IsPressed
&& aTrigClick.IsChanged)
{
theCtx->Select (false);
theCtx->SelectDetected();
OnSelectionChanged (theCtx, theView);
if (const Handle(Aspect_XRAction)& aHaptic = theView->View()->XRSession()->GenericAction (myXRLastPickingHand, Aspect_XRGenericAction_OutputHaptic))
{
@@ -2755,14 +2755,7 @@ void AIS_ViewController::handleSelectionPick (const Handle(AIS_InteractiveContex
ResetPreviousMoveTo();
}
if (myGL.Selection.IsXOR)
{
theCtx->ShiftSelect (false);
}
else
{
theCtx->Select (false);
}
theCtx->SelectDetected (myGL.Selection.IsXOR ? AIS_SelectionScheme_XOR : AIS_SelectionScheme_Replace);
// selection affects all Views
theView->Viewer()->Invalidate();
@@ -2864,18 +2857,10 @@ void AIS_ViewController::handleSelectionPoly (const Handle(AIS_InteractiveContex
else
{
theCtx->MainSelector()->AllowOverlapDetection (aPnt1.y() != Min (aPnt1.y(), aPnt2.y()));
if (myGL.Selection.IsXOR)
{
theCtx->ShiftSelect (Min (aPnt1.x(), aPnt2.x()), Min (aPnt1.y(), aPnt2.y()),
Max (aPnt1.x(), aPnt2.x()), Max (aPnt1.y(), aPnt2.y()),
theView, false);
}
else
{
theCtx->Select (Min (aPnt1.x(), aPnt2.x()), Min (aPnt1.y(), aPnt2.y()),
Max (aPnt1.x(), aPnt2.x()), Max (aPnt1.y(), aPnt2.y()),
theView, false);
}
theCtx->SelectRectangle (Graphic3d_Vec2i (Min (aPnt1.x(), aPnt2.x()), Min (aPnt1.y(), aPnt2.y())),
Graphic3d_Vec2i (Max (aPnt1.x(), aPnt2.x()), Max (aPnt1.y(), aPnt2.y())),
theView,
myGL.Selection.IsXOR ? AIS_SelectionScheme_XOR : AIS_SelectionScheme_Replace);
theCtx->MainSelector()->AllowOverlapDetection (false);
}
}
@@ -2890,14 +2875,8 @@ void AIS_ViewController::handleSelectionPoly (const Handle(AIS_InteractiveContex
aPolyIter.ChangeValue() = gp_Pnt2d (aNewPnt.x(), -aNewPnt.y());
}
if (myGL.Selection.IsXOR)
{
theCtx->ShiftSelect (aPolyline, theView, false);
}
else
{
theCtx->Select (aPolyline, theView, false);
}
theCtx->SelectPolygon (aPolyline, theView,
myGL.Selection.IsXOR ? AIS_SelectionScheme_XOR : AIS_SelectionScheme_Replace);
theCtx->MainSelector()->AllowOverlapDetection (false);
}
}

View File

@@ -72,6 +72,7 @@ AIS_MultipleConnectedInteractive.cxx
AIS_MultipleConnectedInteractive.hxx
AIS_MultipleConnectedInteractive.lxx
AIS_NavigationMode.hxx
AIS_NArray1OfEntityOwner.hxx
AIS_NListOfEntityOwner.hxx
AIS_Plane.cxx
AIS_Plane.hxx
@@ -88,6 +89,7 @@ AIS_Selection.cxx
AIS_Selection.hxx
AIS_SelectStatus.hxx
AIS_SelectionModesConcurrency.hxx
AIS_SelectionScheme.hxx
AIS_SequenceOfInteractive.hxx
AIS_Shape.cxx
AIS_Shape.hxx

View File

@@ -188,7 +188,9 @@ static Standard_Integer BUC60774 (Draw_Interpretor& theDi,
Standard_Integer aXPixMax = aWinWidth;
Standard_Integer aYPixMax = aWinHeight;
AIS_StatusOfPick aPickStatus = anAISContext->Select (aXPixMin, aYPixMin, aXPixMax, aYPixMax, aV3dView, Standard_False);
AIS_StatusOfPick aPickStatus = anAISContext->SelectRectangle (Graphic3d_Vec2i (aXPixMin, aYPixMin),
Graphic3d_Vec2i (aXPixMax, aYPixMax),
aV3dView);
theDi << (aPickStatus == AIS_SOP_NothingSelected
? "status = AIS_SOP_NothingSelected : OK"
: "status = AIS_SOP_NothingSelected : bugged - Faulty ");
@@ -197,7 +199,9 @@ static Standard_Integer BUC60774 (Draw_Interpretor& theDi,
theDi.Eval ("box b 10 10 10");
theDi.Eval (" vdisplay b");
aPickStatus = anAISContext->Select (aXPixMin, aYPixMin, aXPixMax, aYPixMax, aV3dView, Standard_False);
aPickStatus = anAISContext->SelectRectangle (Graphic3d_Vec2i (aXPixMin, aYPixMin),
Graphic3d_Vec2i (aXPixMax, aYPixMax),
aV3dView);
theDi << (aPickStatus == AIS_SOP_OneSelected
? "status = AIS_SOP_OneSelected : OK"
: "status = AIS_SOP_OneSelected : bugged - Faulty ");
@@ -206,7 +210,10 @@ static Standard_Integer BUC60774 (Draw_Interpretor& theDi,
theDi.Eval ("box w 20 20 20 20 20 20");
theDi.Eval (" vdisplay w");
aPickStatus = anAISContext->Select (aXPixMin, aYPixMin, aXPixMax, aYPixMax, aV3dView, Standard_True);
aPickStatus = anAISContext->SelectRectangle (Graphic3d_Vec2i (aXPixMin, aYPixMin),
Graphic3d_Vec2i (aXPixMax, aYPixMax),
aV3dView);
anAISContext->UpdateCurrentViewer();
theDi << (aPickStatus == AIS_SOP_SeveralSelected
? "status = AIS_SOP_SeveralSelected : OK"
: "status = AIS_SOP_SeveralSelected : bugged - Faulty ");

View File

@@ -4250,9 +4250,9 @@ static Standard_Integer OCC26462 (Draw_Interpretor& theDI, Standard_Integer /*th
aCtx->SetWidth (aBox2, 3, Standard_False);
aCtx->MoveTo (305, 322, ViewerTest::CurrentView(), Standard_False);
aCtx->ShiftSelect (Standard_False);
aCtx->SelectDetected (AIS_SelectionScheme_XOR);
aCtx->MoveTo (103, 322, ViewerTest::CurrentView(), Standard_False);
aCtx->ShiftSelect (Standard_False);
aCtx->SelectDetected (AIS_SelectionScheme_XOR);
if (aCtx->NbSelected() != 0)
{
theDI << "ERROR: no boxes must be selected!\n";
@@ -4262,14 +4262,14 @@ static Standard_Integer OCC26462 (Draw_Interpretor& theDI, Standard_Integer /*th
aCtx->SetSelectionSensitivity (aBox1, 2, 5);
aCtx->MoveTo (305, 322, ViewerTest::CurrentView(), Standard_False);
aCtx->ShiftSelect (Standard_False);
aCtx->SelectDetected (AIS_SelectionScheme_XOR);
if (aCtx->NbSelected() != 1)
{
theDI << "ERROR: b1 was not selected\n";
return 1;
}
aCtx->MoveTo (103, 322, ViewerTest::CurrentView(), Standard_False);
aCtx->ShiftSelect (Standard_True);
aCtx->SelectDetected (AIS_SelectionScheme_XOR);
if (aCtx->NbSelected() != 1)
{
theDI << "ERROR: b2 is selected after b1's tolerance increased\n";
@@ -5203,7 +5203,8 @@ static Standard_Integer OCC28310 (Draw_Interpretor& /*theDI*/, Standard_Integer
aCtx->Display (aBoxObj, AIS_Shaded, 0, Standard_False);
ViewerTest::CurrentView()->FitAll();
aCtx->MoveTo (200, 200, ViewerTest::CurrentView(), Standard_True);
aCtx->Select(Standard_True);
aCtx->SelectDetected();
aCtx->UpdateCurrentViewer();
aCtx->Remove (aBoxObj, Standard_True);
// nullify the object explicitly to simulate situation in project,

View File

@@ -26,7 +26,7 @@ class V3d_View;
DEFINE_STANDARD_HANDLE(ViewerTest_EventManager, Standard_Transient)
//! used to manage mouse event (move,select,shiftselect)
//! used to manage mouse event (move,select)
//! By default the events are transmitted to interactive context.
class ViewerTest_EventManager : public Standard_Transient, public AIS_ViewController
{

View File

@@ -7560,7 +7560,8 @@ static Standard_Integer VSelect (Draw_Interpretor& ,
}
NCollection_Sequence<Graphic3d_Vec2i> aPnts;
bool isShiftSelection = false, toAllowOverlap = false;
bool toAllowOverlap = false;
AIS_SelectionScheme aSelScheme = AIS_SelectionScheme_Replace;
for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
{
TCollection_AsciiString anArg (theArgVec[anArgIter]);
@@ -7584,7 +7585,10 @@ static Standard_Integer VSelect (Draw_Interpretor& ,
else if (anArgIter + 1 == theNbArgs
&& anArg.IsIntegerValue())
{
isShiftSelection = anArg.IntegerValue() == 1;
if (anArg.IntegerValue() == 1)
{
aSelScheme = AIS_SelectionScheme_XOR;
}
}
else
{
@@ -7601,14 +7605,7 @@ static Standard_Integer VSelect (Draw_Interpretor& ,
Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
if (aPnts.IsEmpty())
{
if (isShiftSelection)
{
aCtx->ShiftSelect (false);
}
else
{
aCtx->Select (false);
}
aCtx->SelectDetected (aSelScheme);
aCtx->CurrentViewer()->Invalidate();
}
else if (aPnts.Length() == 2)
@@ -7623,11 +7620,11 @@ static Standard_Integer VSelect (Draw_Interpretor& ,
{
std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
}
aCurrentEventManager->SelectInViewer (aPnts, isShiftSelection);
aCurrentEventManager->SelectInViewer (aPnts, aSelScheme == AIS_SelectionScheme_XOR);
}
else
{
aCurrentEventManager->SelectInViewer (aPnts, isShiftSelection);
aCurrentEventManager->SelectInViewer (aPnts, aSelScheme == AIS_SelectionScheme_XOR);
}
aCurrentEventManager->FlushViewEvents (aCtx, ViewerTest::CurrentView(), true);
return 0;