1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00
Files
occt/src/AIS/AIS_Selection.cxx
nds e76471b558 0032205: Visualization - implementing new selection scheme in context - replace extra
- implementation of additional selection scheme, mainly to deselect single selected object.
2021-04-15 19:05:56 +03:00

244 lines
7.1 KiB
C++

// Copyright (c) 1998-1999 Matra Datavision
// Copyright (c) 1999-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.
#include <AIS_Selection.hxx>
#include <AIS_InteractiveObject.hxx>
#include <AIS_SelectionScheme.hxx>
#include <SelectMgr_Filter.hxx>
IMPLEMENT_STANDARD_RTTIEXT(AIS_Selection, Standard_Transient)
namespace
{
static const Standard_Integer THE_MaxSizeOfResult = 100000;
}
//=======================================================================
//function : AIS_Selection
//purpose :
//=======================================================================
AIS_Selection::AIS_Selection()
{
// for maximum performance on medium selections (< 100000 objects)
myResultMap.ReSize (THE_MaxSizeOfResult);
}
//=======================================================================
//function : Clear
//purpose :
//=======================================================================
void AIS_Selection::Clear()
{
for (AIS_NListOfEntityOwner::Iterator aSelIter (Objects()); aSelIter.More(); aSelIter.Next())
{
const Handle(SelectMgr_EntityOwner) anObject = aSelIter.Value();
anObject->SetSelected (Standard_False);
}
myresult.Clear();
myResultMap.Clear();
myIterator = AIS_NListOfEntityOwner::Iterator();
}
//=======================================================================
//function : Select
//purpose :
//=======================================================================
AIS_SelectStatus AIS_Selection::Select (const Handle(SelectMgr_EntityOwner)& theObject)
{
if (theObject.IsNull()
|| !theObject->HasSelectable())
{
return AIS_SS_NotDone;
}
if (!myResultMap.IsBound (theObject))
{
AIS_NListOfEntityOwner::Iterator aListIter;
myresult.Append (theObject, aListIter);
myResultMap.Bind (theObject, aListIter);
theObject->SetSelected (Standard_True);
return AIS_SS_Added;
}
AIS_NListOfEntityOwner::Iterator aListIter = myResultMap.Find (theObject);
if (myIterator == aListIter)
{
if (myIterator.More())
{
myIterator.Next();
}
else
{
myIterator = AIS_NListOfEntityOwner::Iterator();
}
}
// 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
// and remove the owner from map only if the detected entity is the same as previous selected (IsForcedHilight call)
if (theObject->IsForcedHilight())
{
return AIS_SS_Added;
}
myresult.Remove (aListIter);
myResultMap.UnBind (theObject);
theObject->SetSelected (Standard_False);
// update list iterator for next object in <myresult> list if any
if (aListIter.More())
{
const Handle(SelectMgr_EntityOwner)& aNextObject = aListIter.Value();
if (myResultMap.IsBound (aNextObject))
{
myResultMap (aNextObject) = aListIter;
}
else
{
myResultMap.Bind (aNextObject, aListIter);
}
}
return AIS_SS_Removed;
}
//=======================================================================
//function : AddSelect
//purpose :
//=======================================================================
AIS_SelectStatus AIS_Selection::AddSelect (const Handle(SelectMgr_EntityOwner)& theObject)
{
if (theObject.IsNull()
|| !theObject->HasSelectable()
|| myResultMap.IsBound (theObject))
{
return AIS_SS_NotDone;
}
AIS_NListOfEntityOwner::Iterator aListIter;
myresult.Append (theObject, aListIter);
myResultMap.Bind (theObject, aListIter);
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_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;
}
}
}
Standard_FALLTHROUGH
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);
}