1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0030737: Visualization - implementing new selection schemes in context

(cherry picked from commit f9d4ea66dbba0c6fb70d0232d9fd326722e83fbc)
(cherry picked from commit 1c7d53e55a)
(cherry picked from commit e2b319869af281f741ad97595c23de6d3128bce2)

# Conflicts:
#	src/AIS/AIS_InteractiveContext_1.cxx
This commit is contained in:
nds
2019-05-23 19:58:59 +03:00
parent 9e9c9c84bd
commit 73794e88be
8 changed files with 244 additions and 41 deletions

View File

@@ -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();
}

View File

@@ -25,6 +25,8 @@
#include <AIS_ListOfInteractive.hxx>
#include <AIS_Selection.hxx>
#include <AIS_SelectionModesConcurrency.hxx>
#include <AIS_SelectionScheme.hxx>
#include <AIS_SelectionType.hxx>
#include <AIS_StatusOfDetection.hxx>
#include <AIS_StatusOfPick.hxx>
#include <AIS_TypeOfIso.hxx>
@@ -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<AIS_SelectionType, AIS_SelectionScheme> mySelectionSchemes;
};
DEFINE_STANDARD_HANDLE(AIS_InteractiveContext, Standard_Transient)

View File

@@ -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)
{

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,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;
}

View File

@@ -22,6 +22,8 @@
#include <Standard.hxx>
#include <Standard_Type.hxx>
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;

View File

@@ -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

View File

@@ -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

View File

@@ -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