1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00

0031777: Visualization - improve SelectMgr_EntityOwner to process selection scheme

The selection scheme has been propagated to Owner object interface, and the
AIS_Selection::Select() method has been replaced to unify the logic.
This commit is contained in:
mzernova 2023-02-07 02:17:58 +00:00 committed by vglukhik
parent b6388d8b34
commit e3a803bbaf
6 changed files with 157 additions and 95 deletions

View File

@ -3228,6 +3228,30 @@ void AIS_InteractiveContext::ClearSelected (const Standard_Boolean theToUpdateVi
} }
} }
//=======================================================================
//function : isDetected
//purpose :
//=======================================================================
Standard_Boolean AIS_InteractiveContext::isDetected (const Handle(AIS_InteractiveObject)& theObject)
{
for (Standard_Integer aDetIter = myDetectedSeq.Lower(); aDetIter <= myDetectedSeq.Upper(); aDetIter++)
{
Handle(SelectMgr_EntityOwner) aPicked = MainSelector()->Picked(myDetectedSeq(aDetIter));
Handle(AIS_InteractiveObject) anObj;
if (!aPicked.IsNull())
{
anObj = Handle(AIS_InteractiveObject)::DownCast(aPicked->Selectable());
}
if (!anObj.IsNull()
&& anObj == theObject)
{
return Standard_True;
}
}
return Standard_False;
}
//======================================================================= //=======================================================================
//function : SetSelected //function : SetSelected
//purpose : Sets the whole object as selected and highlights it with selection color //purpose : Sets the whole object as selected and highlights it with selection color
@ -3288,7 +3312,8 @@ void AIS_InteractiveContext::SetSelected (const Handle(AIS_InteractiveObject)& t
} }
// added to avoid untimely viewer update... // added to avoid untimely viewer update...
mySelection->ClearAndSelect (anOwner); const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
mySelection->ClearAndSelect (anOwner, myFilters, isDetected (anObj));
if (myAutoHilight) if (myAutoHilight)
{ {
@ -3350,7 +3375,7 @@ void AIS_InteractiveContext::SetSelected (const Handle(SelectMgr_EntityOwner)& t
unhighlightSelected(); unhighlightSelected();
} }
mySelection->ClearAndSelect (theOwner); mySelection->ClearAndSelect (theOwner, myFilters, isDetected (anObject));
if (myAutoHilight) if (myAutoHilight)
{ {
Handle(Prs3d_Drawer) aCustomStyle; Handle(Prs3d_Drawer) aCustomStyle;
@ -3401,16 +3426,17 @@ void AIS_InteractiveContext::AddOrRemoveSelected (const Handle(SelectMgr_EntityO
return; return;
} }
if (!myFilters->IsOk(theOwner) && !theOwner->IsSelected()) if (!myFilters->IsOk (theOwner) && !theOwner->IsSelected())
{ {
return; return;
} }
mySelection->Select (theOwner); AIS_SelectionScheme aSelScheme = theOwner->IsSelected() ? AIS_SelectionScheme_Remove : AIS_SelectionScheme_Add;
const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
mySelection->Select (theOwner, myFilters, aSelScheme, isDetected (anObj));
if (myAutoHilight) if (myAutoHilight)
{ {
const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
Handle(AIS_GlobalStatus)* aStatusPtr = myObjects.ChangeSeek (anObj); Handle(AIS_GlobalStatus)* aStatusPtr = myObjects.ChangeSeek (anObj);
if (!aStatusPtr) if (!aStatusPtr)
{ {
@ -3469,7 +3495,8 @@ Standard_Boolean AIS_InteractiveContext::SetSelectedState (const Handle(SelectMg
} }
else else
{ {
const AIS_SelectStatus aSelStatus = mySelection->Select (theEntity); const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast(theEntity->Selectable());
const AIS_SelectStatus aSelStatus = mySelection->Select (theEntity, myFilters, AIS_SelectionScheme_Remove, isDetected (anObj));
theEntity->SetSelected (false); theEntity->SetSelected (false);
return aSelStatus == AIS_SS_Removed; return aSelStatus == AIS_SS_Removed;
} }

View File

@ -1302,6 +1302,9 @@ protected: //! @name internal methods
Standard_EXPORT AIS_StatusOfDetection moveTo (const Handle(V3d_View)& theView, Standard_EXPORT AIS_StatusOfDetection moveTo (const Handle(V3d_View)& theView,
const Standard_Boolean theToRedrawOnUpdate); const Standard_Boolean theToRedrawOnUpdate);
//! Returns True if the object is detected.
Standard_EXPORT Standard_Boolean isDetected (const Handle(AIS_InteractiveObject)& theObject);
//! Helper function to unhighlight all entity owners currently highlighted with seleciton color. //! Helper function to unhighlight all entity owners currently highlighted with seleciton color.
Standard_EXPORT void unselectOwners (const Handle(AIS_InteractiveObject)& theObject); Standard_EXPORT void unselectOwners (const Handle(AIS_InteractiveObject)& theObject);

View File

@ -55,24 +55,38 @@ void AIS_Selection::Clear()
//function : Select //function : Select
//purpose : //purpose :
//======================================================================= //=======================================================================
AIS_SelectStatus AIS_Selection::Select (const Handle(SelectMgr_EntityOwner)& theObject) AIS_SelectStatus AIS_Selection::Select (const Handle(SelectMgr_EntityOwner)& theOwner,
const Handle(SelectMgr_Filter)& theFilter,
const AIS_SelectionScheme theSelScheme,
const Standard_Boolean theIsDetected)
{ {
if (theObject.IsNull() if (theOwner.IsNull()
|| !theObject->HasSelectable()) || !theOwner->HasSelectable())
{ {
return AIS_SS_NotDone; return AIS_SS_NotDone;
} }
if (!myResultMap.IsBound (theObject)) const Standard_Boolean isDetected = theIsDetected
&& (theFilter.IsNull() || theFilter->IsOk (theOwner));
const Standard_Boolean wasSelected = theOwner->IsSelected();
const Standard_Boolean toSelect = theOwner->Select (theSelScheme, isDetected);
if (toSelect && !wasSelected)
{ {
AIS_NListOfEntityOwner::Iterator aListIter; AIS_NListOfEntityOwner::Iterator aListIter;
myresult.Append (theObject, aListIter); myresult.Append (theOwner, aListIter);
myResultMap.Bind (theObject, aListIter); myResultMap.Bind (theOwner, aListIter);
theObject->SetSelected (Standard_True); theOwner->SetSelected (Standard_True);
return AIS_SS_Added; return AIS_SS_Added;
} }
AIS_NListOfEntityOwner::Iterator aListIter = myResultMap.Find (theObject); if (!toSelect && !wasSelected)
{
return AIS_SS_NotDone;
}
AIS_NListOfEntityOwner::Iterator aListIter = myResultMap.Find (theOwner);
if (myIterator == aListIter) if (myIterator == aListIter)
{ {
if (myIterator.More()) if (myIterator.More())
@ -88,14 +102,14 @@ AIS_SelectStatus AIS_Selection::Select (const Handle(SelectMgr_EntityOwner)& the
// In the mode of advanced mesh selection only one owner is created for all selection modes. // In the mode of advanced mesh selection only one owner is created for all selection modes.
// It is necessary to check the current detected entity // It is necessary to check the current detected entity
// and remove the owner from map only if the detected entity is the same as previous selected (IsForcedHilight call) // and remove the owner from map only if the detected entity is the same as previous selected (IsForcedHilight call)
if (theObject->IsForcedHilight()) if (theOwner->IsForcedHilight())
{ {
return AIS_SS_Added; return AIS_SS_Added;
} }
myresult.Remove (aListIter); myresult.Remove (aListIter);
myResultMap.UnBind (theObject); myResultMap.UnBind (theOwner);
theObject->SetSelected (Standard_False); theOwner->SetSelected (Standard_False);
// update list iterator for next object in <myresult> list if any // update list iterator for next object in <myresult> list if any
if (aListIter.More()) if (aListIter.More())
@ -142,86 +156,39 @@ void AIS_Selection::SelectOwners (const AIS_NArray1OfEntityOwner& thePickedOwner
const Standard_Boolean theToAllowSelOverlap, const Standard_Boolean theToAllowSelOverlap,
const Handle(SelectMgr_Filter)& theFilter) const Handle(SelectMgr_Filter)& theFilter)
{ {
(void )theToAllowSelOverlap; (void)theToAllowSelOverlap;
switch (theSelScheme)
if (theSelScheme == AIS_SelectionScheme_ReplaceExtra
&& thePickedOwners.Size() == myresult.Size())
{ {
case AIS_SelectionScheme_UNKNOWN: // If picked owners is equivalent to the selected then just clear selected.
Standard_Boolean isTheSame = Standard_True;
for (AIS_NArray1OfEntityOwner::Iterator aPickedIter (thePickedOwners); aPickedIter.More(); aPickedIter.Next())
{ {
return; if (!myResultMap.IsBound (aPickedIter.Value()))
}
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; isTheSame = Standard_False;
for (AIS_NArray1OfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next()) break;
{
if (!myResultMap.IsBound (aSelIter.Value()))
{
isTheSame = Standard_False;
break;
}
}
if (isTheSame)
{
Clear();
return;
}
} }
} }
Standard_FALLTHROUGH if (isTheSame)
case AIS_SelectionScheme_Replace:
{ {
Clear(); Clear();
for (AIS_NArray1OfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next()) return;
{ }
appendOwner (aSelIter.Value(), theFilter); }
}
return; if (theSelScheme == AIS_SelectionScheme_Replace
} || theSelScheme == AIS_SelectionScheme_ReplaceExtra
case AIS_SelectionScheme_Add: || theSelScheme == AIS_SelectionScheme_Clear)
{ {
for (AIS_NArray1OfEntityOwner::Iterator aSelIter (thePickedOwners); aSelIter.More(); aSelIter.Next()) Clear();
{ }
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); for (AIS_NArray1OfEntityOwner::Iterator aPickedIter (thePickedOwners); aPickedIter.More(); aPickedIter.Next())
} {
return; const Handle(SelectMgr_EntityOwner)& anOwner = aPickedIter.Value();
} Select (anOwner, theFilter, theSelScheme, true);
case AIS_SelectionScheme_Clear:
{
Clear();
return;
}
} }
} }

View File

@ -40,17 +40,30 @@ public:
//! if the object is not yet in the selection, it will be added. //! if the object is not yet in the selection, it will be added.
//! if the object is already in the selection, it will be removed. //! if the object is already in the selection, it will be removed.
Standard_EXPORT virtual AIS_SelectStatus Select (const Handle(SelectMgr_EntityOwner)& theObject); //! @param[in] theOwner element to change selection state
//! @param[in] theFilter context filter
//! @param[in] theSelScheme selection scheme
//! @param[in] theIsDetected flag of object detection
//! @return result of selection
Standard_EXPORT virtual AIS_SelectStatus Select (const Handle(SelectMgr_EntityOwner)& theOwner,
const Handle(SelectMgr_Filter)& theFilter,
const AIS_SelectionScheme theSelScheme,
const Standard_Boolean theIsDetected);
//! the object is always add int the selection. //! the object is always add int the selection.
//! faster when the number of objects selected is great. //! faster when the number of objects selected is great.
Standard_EXPORT virtual AIS_SelectStatus AddSelect (const Handle(SelectMgr_EntityOwner)& theObject); Standard_EXPORT virtual AIS_SelectStatus AddSelect (const Handle(SelectMgr_EntityOwner)& theObject);
//! clears the selection and adds the object in the selection. //! clears the selection and adds the object in the selection.
virtual void ClearAndSelect (const Handle(SelectMgr_EntityOwner)& theObject) //! @param[in] theObject element to change selection state
//! @param[in] theFilter context filter
//! @param[in] theIsDetected flag of object detection
virtual void ClearAndSelect (const Handle(SelectMgr_EntityOwner)& theObject,
const Handle(SelectMgr_Filter)& theFilter,
const Standard_Boolean theIsDetected)
{ {
Clear(); Clear();
Select (theObject); Select (theObject, theFilter, AIS_SelectionScheme_Add, theIsDetected);
} }
//! checks if the object is in the selection. //! checks if the object is in the selection.

View File

@ -83,6 +83,51 @@ void SelectMgr_EntityOwner::HilightWithColor (const Handle(PrsMgr_PresentationMa
} }
} }
// =======================================================================
// function : Select
// purpose :
// =======================================================================
Standard_Boolean SelectMgr_EntityOwner::Select (const AIS_SelectionScheme theSelScheme,
const Standard_Boolean theIsDetected) const
{
switch (theSelScheme)
{
case AIS_SelectionScheme_UNKNOWN:
{
return myIsSelected;
}
case AIS_SelectionScheme_Replace:
{
return theIsDetected;
}
case AIS_SelectionScheme_Add:
{
return !myIsSelected || theIsDetected || IsForcedHilight();
}
case AIS_SelectionScheme_Remove:
{
return myIsSelected && !theIsDetected;
}
case AIS_SelectionScheme_XOR:
{
if (theIsDetected)
{
return !myIsSelected && !IsForcedHilight();
}
return myIsSelected;
}
case AIS_SelectionScheme_Clear:
{
return Standard_False;
}
case AIS_SelectionScheme_ReplaceExtra:
{
return theIsDetected;
}
}
return Standard_False;
}
// ======================================================================= // =======================================================================
// function : DumpJson // function : DumpJson
// purpose : // purpose :

View File

@ -17,6 +17,7 @@
#ifndef _SelectMgr_EntityOwner_HeaderFile #ifndef _SelectMgr_EntityOwner_HeaderFile
#define _SelectMgr_EntityOwner_HeaderFile #define _SelectMgr_EntityOwner_HeaderFile
#include <AIS_SelectionScheme.hxx>
#include <Aspect_VKey.hxx> #include <Aspect_VKey.hxx>
#include <PrsMgr_PresentationManager.hxx> #include <PrsMgr_PresentationManager.hxx>
#include <SelectMgr_SelectableObject.hxx> #include <SelectMgr_SelectableObject.hxx>
@ -139,6 +140,12 @@ public:
//! @param theIsSelected [in] shows if owner is selected. //! @param theIsSelected [in] shows if owner is selected.
void SetSelected (const Standard_Boolean theIsSelected) { myIsSelected = theIsSelected; } void SetSelected (const Standard_Boolean theIsSelected) { myIsSelected = theIsSelected; }
//! If the object needs to be selected, it returns true.
//! @param[in] theSelScheme selection scheme
//! @param[in] theIsDetected flag of object detection
Standard_EXPORT Standard_Boolean Select (const AIS_SelectionScheme theSelScheme,
const Standard_Boolean theIsDetected) const;
//! Returns selection state. //! Returns selection state.
Standard_DEPRECATED ("Deprecated method - IsSelected() should be used instead") Standard_DEPRECATED ("Deprecated method - IsSelected() should be used instead")
Standard_Integer State() const { return myIsSelected ? 1 : 0; } Standard_Integer State() const { return myIsSelected ? 1 : 0; }