mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-05-06 10:36:12 +03:00
424 lines
13 KiB
C++
Executable File
424 lines
13 KiB
C++
Executable File
// Copyright (c) 1998-1999 Matra Datavision
|
|
// Copyright (c) 1999-2012 OPEN CASCADE SAS
|
|
//
|
|
// The content of this file is subject to the Open CASCADE Technology Public
|
|
// License Version 6.5 (the "License"). You may not use the content of this file
|
|
// except in compliance with the License. Please obtain a copy of the License
|
|
// at http://www.opencascade.org and read it completely before using this file.
|
|
//
|
|
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
|
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
|
//
|
|
// The Original Code and all software distributed under the License is
|
|
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
|
// Initial Developer hereby disclaims all such warranties, including without
|
|
// limitation, any warranties of merchantability, fitness for a particular
|
|
// purpose or non-infringement. Please see the License for the specific terms
|
|
// and conditions governing the rights and limitations under the License.
|
|
|
|
#include <AIS_Selection.ixx>
|
|
#include <TCollection_AsciiString.hxx>
|
|
#include <TColStd_SequenceOfTransient.hxx>
|
|
|
|
#define BUC60953 // SAV_050701 : the array of selected objects has always the same length
|
|
// independently of number of objects selected. Thus, if there were selected
|
|
// more than MaxSizeOfResult objects we have got an exception.
|
|
// Moreover, Select method was optimized a little bit.
|
|
// Now it checks the state of incoming owner. If the state is 0
|
|
// there is no searching for object in <myresult> array.
|
|
|
|
#define OCC138
|
|
|
|
#define OCC189 //SAV: 18//03/02 array was replaced with list.
|
|
|
|
#define OCC1039 //SAV: 25/11/02 clearing selected objects if any on the AIS_Selection remove.
|
|
|
|
#define USE_MAP //san : 18/04/03 USE_MAP - additional datamap is used to speed up access
|
|
//to certain owners in <myresult> list
|
|
|
|
#ifdef BUC60953
|
|
#include <SelectMgr_EntityOwner.hxx>
|
|
#endif
|
|
|
|
#ifdef OCC138 //VTN Avoding infinit loop in AddOrRemoveSelected and AddOrRemoveCurrentObject methods.
|
|
#include <AIS_InteractiveObject.hxx>
|
|
#endif
|
|
|
|
#ifndef USE_MAP
|
|
#define MaxSizeOfResult 10000
|
|
#else
|
|
#define MaxSizeOfResult 100000
|
|
#endif
|
|
|
|
static void AIS_Sel_CurrentSelection (Handle(AIS_Selection)& InputSel)
|
|
{
|
|
static Handle(AIS_Selection) theCurrentSelection;
|
|
if(!InputSel.IsNull())
|
|
theCurrentSelection = InputSel;
|
|
else
|
|
InputSel = theCurrentSelection;
|
|
}
|
|
|
|
static TColStd_SequenceOfTransient& AIS_Sel_GetSelections()
|
|
{
|
|
static TColStd_SequenceOfTransient Selections;
|
|
return Selections;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : AIS_Selection
|
|
//purpose :
|
|
//=======================================================================
|
|
AIS_Selection::AIS_Selection(const Standard_CString aName) :
|
|
myName(TCollection_AsciiString(aName)),
|
|
#if !defined USE_MAP && !defined OCC189
|
|
myresult(new TColStd_HArray1OfTransient(1,MaxSizeOfResult)),
|
|
#endif
|
|
myNb(0)
|
|
{
|
|
#ifdef USE_MAP
|
|
myResultMap.ReSize( MaxSizeOfResult ); // for maximum performnace on medium selections ( < 100000 objects )
|
|
#endif
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : CreateSelection
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Boolean AIS_Selection::CreateSelection(const Standard_CString aName)
|
|
{
|
|
Handle(AIS_Selection) S = AIS_Selection::Selection(aName);
|
|
if(!S.IsNull())
|
|
return Standard_False;
|
|
S = new AIS_Selection(aName);
|
|
AIS_Sel_GetSelections().Prepend(S);
|
|
AIS_Sel_CurrentSelection(S);
|
|
return Standard_True;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Selection
|
|
//purpose :
|
|
//=======================================================================
|
|
Handle(AIS_Selection) AIS_Selection::Selection(const Standard_CString aName)
|
|
{
|
|
Handle(AIS_Selection) S;
|
|
if(AIS_Sel_GetSelections().IsEmpty()) return S;
|
|
|
|
Handle(Standard_Transient) curobj;
|
|
Handle(AIS_Selection) Sel;
|
|
// Standard_Boolean found(Standard_False);
|
|
for(Standard_Integer I =1; I<= AIS_Sel_GetSelections().Length();I++){
|
|
curobj = AIS_Sel_GetSelections().Value(I);
|
|
Sel = *((Handle(AIS_Selection)*)&curobj);
|
|
if(Sel->myName.IsEqual(aName))
|
|
return Sel;
|
|
}
|
|
|
|
return S;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Find
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Boolean AIS_Selection::Find(const Standard_CString aName)
|
|
{
|
|
Handle(AIS_Selection) S = AIS_Selection::Selection(aName);
|
|
return !S.IsNull();
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : SetCurrentSelection
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Boolean AIS_Selection::SetCurrentSelection (const Standard_CString aName)
|
|
{
|
|
AIS_Selection::CreateSelection(aName);
|
|
|
|
|
|
Handle(AIS_Selection) anAISSelection = AIS_Selection::Selection(aName) ;
|
|
AIS_Sel_CurrentSelection ( anAISSelection ) ;
|
|
return Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Select
|
|
//purpose :
|
|
//=======================================================================
|
|
void AIS_Selection::Select()
|
|
{
|
|
Handle(AIS_Selection) S;
|
|
AIS_Sel_CurrentSelection (S);
|
|
if(!S.IsNull()){
|
|
S->myNb=0;
|
|
#if defined OCC189 || defined USE_MAP
|
|
S->myresult.Clear();
|
|
#ifdef USE_MAP
|
|
S->myResultMap.Clear();
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : CurrentSelection
|
|
//purpose :
|
|
//=======================================================================
|
|
Handle(AIS_Selection) AIS_Selection::CurrentSelection() {
|
|
Handle(AIS_Selection) S;
|
|
AIS_Sel_CurrentSelection (S);
|
|
return S;
|
|
}
|
|
//=======================================================================
|
|
//function : Select
|
|
//purpose :
|
|
//=======================================================================
|
|
AIS_SelectStatus AIS_Selection::Select(const Handle(Standard_Transient)& anObject)
|
|
{
|
|
Handle(AIS_Selection) S;
|
|
AIS_Sel_CurrentSelection (S);
|
|
if(S.IsNull()) return AIS_SS_NotDone;
|
|
Handle(AIS_InteractiveObject) anAISObj;
|
|
Handle(SelectMgr_EntityOwner) owner = Handle(SelectMgr_EntityOwner)::DownCast( anObject );
|
|
if ( owner.IsNull() )
|
|
anAISObj = Handle(AIS_InteractiveObject)::DownCast( anObject );
|
|
#ifndef OCC189
|
|
TColStd_Array1OfTransient& arr = S->myresult->ChangeArray1();
|
|
|
|
Standard_Integer Found(-1);
|
|
Standard_Integer i ;
|
|
|
|
#ifdef BUC60953
|
|
|
|
Standard_Boolean selected = Standard_False;
|
|
if ( !owner.IsNull() )
|
|
selected = owner->State() != 0;
|
|
#ifdef OCC138
|
|
else if(!anAISObj.IsNull())
|
|
selected = anAISObj->State();
|
|
}
|
|
#endif
|
|
|
|
if ( selected ) // looking up index of object
|
|
#endif
|
|
|
|
for( i=arr.Lower() && Found==-1;i<=S->myNb;i++){
|
|
if(arr(i)==anObject)
|
|
Found=i;
|
|
}
|
|
// If it is not inside, it is added...
|
|
|
|
#ifdef BUC60953
|
|
if ( !selected || Found == -1 ) {
|
|
#else
|
|
if(Found==-1){
|
|
#endif
|
|
if((S->myNb)+1>arr.Length()){
|
|
Handle(TColStd_HArray1OfTransient) NiouTab = new TColStd_HArray1OfTransient(1,arr.Length()+MaxSizeOfResult);
|
|
for(i=arr.Lower();i<=S->myNb;i++){
|
|
const Handle(Standard_Transient)& T = S->myresult->Value(i);
|
|
NiouTab->SetValue(i,T);
|
|
}
|
|
#ifdef BUC60953
|
|
S->myresult = NiouTab;
|
|
#endif
|
|
}
|
|
(S->myNb)++;
|
|
S->myresult->SetValue(S->myNb,anObject);
|
|
return AIS_SS_Added;
|
|
}
|
|
// it was inside and it is removed...
|
|
for(i=Found;i<=S->myNb;i++)
|
|
arr(i)=arr(i+1);
|
|
S->myNb--;
|
|
#elif !defined USE_MAP //OCC189
|
|
AIS_NListTransient::Iterator anIter ( S->myresult );
|
|
for ( ; anIter.More(); anIter.Next() )
|
|
if ( anIter.Value() == anObject ) {
|
|
S->myresult.Remove( anIter );
|
|
return AIS_SS_Removed;
|
|
}
|
|
|
|
S->myresult.Append( anObject );
|
|
return AIS_SS_Added;
|
|
#else //USE_MAP
|
|
if ( S->myResultMap.IsBound( anObject ) ){
|
|
AIS_NListTransient::Iterator aListIter = S->myResultMap.Find( anObject );
|
|
//skt-----------------------------------------------------------------
|
|
if( S->myIterator == aListIter ) {
|
|
if( S->myIterator.More() )
|
|
S->myIterator.Next();
|
|
else
|
|
S->myIterator = AIS_NListTransient::Iterator();
|
|
}
|
|
//--------------------------------------------------------------------
|
|
#ifdef BUC60953
|
|
// 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( !anAISObj.IsNull() || ( !owner.IsNull() && !owner->IsForcedHilight() ) )
|
|
{
|
|
#endif
|
|
S->myresult.Remove( aListIter );
|
|
S->myResultMap.UnBind( anObject );
|
|
|
|
// update list iterator for next object in <myresult> list if any
|
|
if ( aListIter.More() ){
|
|
const Handle(Standard_Transient)& aNextObject = aListIter.Value();
|
|
if ( S->myResultMap.IsBound( aNextObject ) )
|
|
S->myResultMap( aNextObject ) = aListIter;
|
|
else
|
|
S->myResultMap.Bind( aNextObject, aListIter );
|
|
}
|
|
return AIS_SS_Removed;
|
|
}
|
|
else
|
|
return AIS_SS_Added;
|
|
}
|
|
|
|
AIS_NListTransient::Iterator aListIter;
|
|
S->myresult.Append( anObject, aListIter );
|
|
S->myResultMap.Bind( anObject, aListIter );
|
|
return AIS_SS_Added;
|
|
#endif //USE_MAP
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : AddSelect
|
|
//purpose : Always add int the selection
|
|
//=======================================================================
|
|
AIS_SelectStatus AIS_Selection::AddSelect(const Handle(Standard_Transient)& anObject)
|
|
{
|
|
Handle(AIS_Selection) S;
|
|
AIS_Sel_CurrentSelection (S);
|
|
if(S.IsNull()) return AIS_SS_NotDone;
|
|
|
|
#ifndef OCC189
|
|
TColStd_Array1OfTransient& arr = S->myresult->ChangeArray1();
|
|
Standard_Integer i;
|
|
if((S->myNb)+1>arr.Length()){
|
|
Handle(TColStd_HArray1OfTransient) NiouTab = new TColStd_HArray1OfTransient(1,arr.Length()+MaxSizeOfResult);
|
|
for(i=arr.Lower();i<=S->myNb;i++){
|
|
const Handle(Standard_Transient)& T = S->myresult->Value(i);
|
|
NiouTab->SetValue(i,T);
|
|
}
|
|
S->myresult = NiouTab;
|
|
}
|
|
(S->myNb)++;
|
|
S->myresult->SetValue(S->myNb,anObject);
|
|
#elif !defined USE_MAP //OCC189
|
|
S->myresult.Append( anObject );
|
|
#else //USE_MAP
|
|
if ( S->myResultMap.IsBound( anObject ) )
|
|
return AIS_SS_NotDone;
|
|
|
|
AIS_NListTransient::Iterator aListIter;
|
|
S->myresult.Append( anObject, aListIter );
|
|
S->myResultMap.Bind( anObject, aListIter );
|
|
#endif
|
|
return AIS_SS_Added;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : ClearAndSelect
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void AIS_Selection::ClearAndSelect(const Handle(Standard_Transient)& anObject) {
|
|
Handle(AIS_Selection) S;
|
|
AIS_Sel_CurrentSelection (S);
|
|
if(S.IsNull()) return;
|
|
|
|
Select();
|
|
Select(anObject);
|
|
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Extent
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Integer AIS_Selection::Extent() {
|
|
Handle(AIS_Selection) S;
|
|
AIS_Sel_CurrentSelection (S);
|
|
#if !defined OCC189 && !defined USE_MAP
|
|
return S->myNb;
|
|
#else
|
|
return S->myresult.Extent();
|
|
#endif
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Single
|
|
//purpose :
|
|
//=======================================================================
|
|
Handle(Standard_Transient) AIS_Selection::Single()
|
|
{
|
|
Handle(AIS_Selection) S;
|
|
AIS_Sel_CurrentSelection (S);
|
|
|
|
S->Init();
|
|
return S->Value();
|
|
}
|
|
//=======================================================================
|
|
//function : IsSelected
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Boolean AIS_Selection::IsSelected(const Handle(Standard_Transient)& anObject)
|
|
{
|
|
Handle(AIS_Selection) S;
|
|
AIS_Sel_CurrentSelection (S);
|
|
if(S.IsNull()) return Standard_False;
|
|
#ifndef USE_MAP
|
|
for(S->Init();S->More();S->Next()){
|
|
if(S->Value()==anObject)
|
|
return Standard_True;
|
|
}
|
|
return Standard_False;
|
|
#else
|
|
return S->myResultMap.IsBound( anObject );
|
|
#endif
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Index
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Integer AIS_Selection::Index(const Standard_CString aName)
|
|
{
|
|
Handle (Standard_Transient) curobj;
|
|
for(Standard_Integer I =1; I<= AIS_Sel_GetSelections().Length();I++){
|
|
curobj = AIS_Sel_GetSelections().Value(I);
|
|
if((*((Handle(AIS_Selection)*)&curobj))->myName.IsEqual(aName))
|
|
return I;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Remove
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void AIS_Selection::Remove(const Standard_CString aName)
|
|
{
|
|
Standard_Integer I = AIS_Selection::Index(aName);
|
|
if(I!=0) {
|
|
#ifdef OCC1039
|
|
Handle(AIS_Selection) selection = Handle(AIS_Selection)::DownCast( AIS_Sel_GetSelections().Value(I) );
|
|
Standard_Integer stored = selection->NbStored();
|
|
if ( stored )
|
|
selection->Select();
|
|
#endif
|
|
AIS_Sel_GetSelections().Remove(I);
|
|
}
|
|
|
|
}
|
|
|