// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-#include <Standard_NotImplemented.hxx>
-#include <SelectMgr_SelectableObject.ixx>
-#include <Standard_NoSuchObject.hxx>
-#include <SelectMgr_Selection.hxx>
-#include <Select3D_SensitiveEntity.hxx>
-#include <SelectBasics_EntityOwner.hxx>
-#include <SelectMgr_EntityOwner.hxx>
-#include <PrsMgr_PresentationManager3d.hxx>
-#include <Prs3d_Drawer.hxx>
-#include <Prs3d_LineAspect.hxx>
-#include <Prs3d_PointAspect.hxx>
#include <Aspect_TypeOfMarker.hxx>
-#include <Prs3d_PlaneAspect.hxx>
+#include <Bnd_Box.hxx>
+#include <gp_Pnt.hxx>
#include <Graphic3d_AspectLine3d.hxx>
#include <Graphic3d_AspectMarker3d.hxx>
-
+#include <Prs3d_Drawer.hxx>
+#include <Prs3d_LineAspect.hxx>
+#include <Prs3d_PlaneAspect.hxx>
+#include <Prs3d_PointAspect.hxx>
+#include <Prs3d_Presentation.hxx>
+#include <PrsMgr_PresentableObjectPointer.hxx>
+#include <PrsMgr_PresentationManager3d.hxx>
+#include <Select3D_SensitiveEntity.hxx>
+#include <SelectBasics_EntityOwner.hxx>
+#include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_IndexedMapOfOwner.hxx>
+#include <SelectMgr_SelectableObject.hxx>
+#include <SelectMgr_Selection.hxx>
+#include <SelectMgr_SelectionManager.hxx>
+#include <Standard_NoSuchObject.hxx>
+#include <Standard_NotImplemented.hxx>
+#include <Standard_Type.hxx>
#include <TopLoc_Location.hxx>
-#include <gp_Pnt.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_SelectableObject,PrsMgr_PresentableObject)
static Standard_Integer Search (const SelectMgr_SequenceOfSelection& seq,
const Handle (SelectMgr_Selection)& theSel)
// Purpose :
//==================================================
-SelectMgr_SelectableObject::SelectMgr_SelectableObject( const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d):
- PrsMgr_PresentableObject (aTypeOfPresentation3d),
+SelectMgr_SelectableObject::SelectMgr_SelectableObject (const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d)
+: PrsMgr_PresentableObject (aTypeOfPresentation3d),
myDrawer (new Prs3d_Drawer()),
myHilightDrawer (new Prs3d_Drawer()),
- myAutoHilight (Standard_True)
+ myAssemblyOwner (NULL),
+ myAutoHilight (Standard_True),
+ myGlobalSelMode (0)
{
InitDefaultHilightAttributes (myHilightDrawer);
myHilightDrawer->Link (myDrawer);
//==================================================
-// Function:
+// Function: HasSelection
// Purpose :
//==================================================
-
-Standard_Boolean SelectMgr_SelectableObject
-::HasSelection(const Standard_Integer aMode) const
+Standard_Boolean SelectMgr_SelectableObject::HasSelection (const Standard_Integer theMode) const
{
- Standard_Boolean Found=Standard_False;
- for (Standard_Integer I=1;I<= myselections.Length() && !Found;I++)
- { if(((myselections.Value(I))->Mode())==aMode)
- return Standard_True;
- }
+ for (Standard_Integer aSelIdx = 1; aSelIdx <= myselections.Length(); ++aSelIdx)
+ {
+ if (((myselections.Value (aSelIdx))->Mode()) == theMode)
+ return Standard_True;
+ }
return Standard_False;
}
//==================================================
-// Function: UpdateSelection
-// Purpose :
+// Function: RecomputePrimitives
+// Purpose : IMPORTANT: Do not use this method to update
+// selection primitives except implementing custom
+// selection manager! This method does not take
+// into account necessary BVH updates, but may
+// invalidate the pointers it refers to.
+// TO UPDATE SELECTION properly from outside classes,
+// use method UpdateSelection.
//==================================================
-void SelectMgr_SelectableObject::UpdateSelection()
+void SelectMgr_SelectableObject::RecomputePrimitives()
{
- for (Standard_Integer I=1;I<=myselections.Length();I++)
+ for (Standard_Integer aSelIdx = 1; aSelIdx <= myselections.Length(); aSelIdx++)
{
- UpdateSelection(myselections.ChangeValue(I)->Mode());
+ RecomputePrimitives (myselections.ChangeValue (aSelIdx)->Mode());
}
}
-Standard_Integer SelectMgr_SelectableObject::NbPossibleSelection() const
-{return 0;}
-
//==================================================
-// Function: UpdateSelection
-// Purpose :
+// Function: RecomputePrimitives
+// Purpose : IMPORTANT: Do not use this method to update
+// selection primitives except implementing custom
+// selection manager! This method does not take
+// into account necessary BVH updates, but may
+// invalidate the pointers it refers to.
+// TO UPDATE SELECTION properly from outside classes,
+// use method UpdateSelection.
//==================================================
-void SelectMgr_SelectableObject::UpdateSelection(const Standard_Integer aMode)
+void SelectMgr_SelectableObject::RecomputePrimitives (const Standard_Integer theMode)
{
- for (Standard_Integer i =1; i<= myselections.Length(); i++ ) {
- if (myselections.Value(i)->Mode() == aMode) {
- myselections(i)->Clear();
- ComputeSelection(myselections(i),aMode);
- myselections(i)->UpdateStatus(SelectMgr_TOU_Partial);
+ Handle(PrsMgr_PresentableObject) aPrsParent (Parent());
+ Handle(SelectMgr_SelectableObject) aSelParent = Handle(SelectMgr_SelectableObject)::DownCast (aPrsParent);
+
+ for (Standard_Integer aSelIdx =1; aSelIdx <= myselections.Length(); aSelIdx++ )
+ {
+ if (myselections.Value (aSelIdx)->Mode() == theMode)
+ {
+ myselections (aSelIdx)->Clear();
+ ComputeSelection (myselections (aSelIdx), theMode);
+ myselections (aSelIdx)->UpdateStatus (SelectMgr_TOU_Partial);
+ myselections (aSelIdx)->UpdateBVHStatus (SelectMgr_TBU_Renew);
+ if (theMode == 0 && ! aSelParent.IsNull() && ! aSelParent->GetAssemblyOwner().IsNull())
+ {
+ SetAssemblyOwner (aSelParent->GetAssemblyOwner(), theMode);
+ }
return;
}
}
- Handle(SelectMgr_Selection) S = new SelectMgr_Selection(aMode);
- ComputeSelection(S,aMode);
- S->UpdateStatus(SelectMgr_TOU_Partial);
-
- myselections.Append(S);
-
+
+ Handle(SelectMgr_Selection) aNewSel = new SelectMgr_Selection (theMode);
+ ComputeSelection (aNewSel, theMode);
+
+ if (theMode == 0 && ! aSelParent.IsNull() && ! aSelParent->GetAssemblyOwner().IsNull())
+ {
+ SetAssemblyOwner (aSelParent->GetAssemblyOwner(), theMode);
+ }
+
+ aNewSel->UpdateStatus (SelectMgr_TOU_Partial);
+ aNewSel->UpdateBVHStatus (SelectMgr_TBU_Add);
+
+ myselections.Append (aNewSel);
}
//==================================================
{
for (Standard_Integer i =1; i<= myselections.Length(); i++ ) {
myselections.Value(i)->Clear();
+ myselections.Value (i)->UpdateBVHStatus (SelectMgr_TBU_Remove);
if(update)
+ {
myselections.Value(i)->UpdateStatus(SelectMgr_TOU_Full);
+ }
}
}
::AddSelection(const Handle(SelectMgr_Selection)& aSel,
const Standard_Integer aMode)
{
- if(aSel->IsEmpty()){
- ComputeSelection(aSel,aMode);
+ Standard_Boolean isReplaced = Standard_False;
+ if(aSel->IsEmpty())
+ {
+ ComputeSelection(aSel, aMode);
aSel->UpdateStatus(SelectMgr_TOU_Partial);
+ aSel->UpdateBVHStatus (SelectMgr_TBU_Add);
}
- if(HasSelection(aMode))
+ if (HasSelection(aMode))
+ {
+ const Handle(SelectMgr_Selection)& temp= Selection(aMode);
+ Standard_Integer I = Search(myselections,temp);
+ if(I!=0)
{
- const Handle(SelectMgr_Selection)& temp= Selection(aMode);
- Standard_Integer I = Search(myselections,temp);
- if(I!=0) myselections.Remove(I);
+ myselections.Remove(I);
+ isReplaced = Standard_True;
}
+ }
+
myselections.Append(aSel);
-
+ if (isReplaced)
+ {
+ myselections.Last()->UpdateBVHStatus (SelectMgr_TBU_Renew);
+ }
+
+ if (aMode == 0)
+ {
+ Handle(PrsMgr_PresentableObject) aPrsParent (Parent());
+ Handle(SelectMgr_SelectableObject) aSelParent = Handle(SelectMgr_SelectableObject)::DownCast (aPrsParent);
+ if (! aSelParent.IsNull() && ! aSelParent->GetAssemblyOwner().IsNull())
+ {
+ SetAssemblyOwner (aSelParent->GetAssemblyOwner(), aMode);
+ }
+ }
}
//=======================================================================
void SelectMgr_SelectableObject::ResetTransformation()
{
- TopLoc_Location aLoc;
-
- TopLoc_Location aSelfLocation (Transformation());
-
- // les selections
- Handle(Select3D_SensitiveEntity) SE;
- for(Init();More();Next()){
- const Handle(SelectMgr_Selection) & Sel = CurrentSelection();
- for(Sel->Init();Sel->More();Sel->Next()){
- SE = *((Handle(Select3D_SensitiveEntity)*) &(Sel->Sensitive()));
- if(!SE.IsNull()){
- if(SE->HasLocation()) {
- if( SE->Location()==aSelfLocation){
- SE->ResetLocation();
- const Handle(SelectBasics_EntityOwner)& EO = SE->OwnerId();
- (*((Handle(SelectMgr_EntityOwner)*)&EO))->ResetLocation();}
- else{
- const TopLoc_Location& iniloc =SE->Location();
- SE->SetLocation(iniloc*aSelfLocation.Inverted());
- const Handle(SelectBasics_EntityOwner)& EO = SE->OwnerId();
- (*((Handle(SelectMgr_EntityOwner)*)&EO))->SetLocation(SE->Location());}
- }
- }
+ for (Init(); More(); Next())
+ {
+ const Handle(SelectMgr_Selection) & aSel = CurrentSelection();
+ for (aSel->Init(); aSel->More(); aSel->Next())
+ {
+ aSel->UpdateStatus(SelectMgr_TOU_Partial);
+ aSel->UpdateBVHStatus (SelectMgr_TBU_None);
}
- Sel->UpdateStatus(SelectMgr_TOU_None);
}
PrsMgr_PresentableObject::ResetTransformation();
}
-
//=======================================================================
//function : UpdateTransformation
//purpose :
//=======================================================================
-void SelectMgr_SelectableObject::UpdateTransformation()
+void SelectMgr_SelectableObject::UpdateTransformation()
{
-
- Handle(Select3D_SensitiveEntity) SE;
- for(Init();More();Next()){
- const Handle(SelectMgr_Selection) & Sel = CurrentSelection();
- Sel->UpdateStatus(SelectMgr_TOU_Partial);
+ for (Init(); More(); Next())
+ {
+ CurrentSelection()->UpdateStatus (SelectMgr_TOU_Partial);
}
- PrsMgr_PresentableObject::UpdateTransformation();
+ PrsMgr_PresentableObject::UpdateTransformation();
}
-
//=======================================================================
//function : UpdateTransformation
//purpose :
Handle(Select3D_SensitiveEntity) SE;
if(aSelfLocation.IsIdentity()) return;
for(Sel->Init();Sel->More();Sel->Next()){
- SE = Handle(Select3D_SensitiveEntity)::DownCast(Sel->Sensitive());
+ SE = Handle(Select3D_SensitiveEntity)::DownCast (Sel->Sensitive()->BaseSensitive());
if(!SE.IsNull()){
- SE->UpdateLocation(aSelfLocation);
const Handle(SelectBasics_EntityOwner)& aEOwner = SE->OwnerId();
Handle(SelectMgr_EntityOwner) aMgrEO =
Handle(SelectMgr_EntityOwner)::DownCast (aEOwner);
for (aSel->Init (); aSel->More (); aSel->Next ())
{
Handle(Select3D_SensitiveEntity) aEntity =
- Handle(Select3D_SensitiveEntity)::DownCast (aSel->Sensitive());
+ Handle(Select3D_SensitiveEntity)::DownCast (aSel->Sensitive()->BaseSensitive());
if (!aEntity.IsNull())
{
Handle(SelectMgr_EntityOwner) aOwner =
}
}
+//=======================================================================
+//function : UpdateSelection
+//purpose : Sets update status FULL to selections of the object. Must be
+// used as the only method of UpdateSelection from outer classes
+// to prevent BVH structures from being outdated.
+//=======================================================================
+void SelectMgr_SelectableObject::UpdateSelection (const Standard_Integer theMode)
+{
+ if (theMode == -1)
+ {
+ for (Init(); More(); Next())
+ {
+ const Handle(SelectMgr_Selection)& aSel = CurrentSelection();
+ aSel->UpdateStatus (SelectMgr_TOU_Full);
+ }
+
+ return;
+ }
+
+ for (Init(); More(); Next())
+ {
+ if (CurrentSelection()->Mode() == theMode)
+ {
+ CurrentSelection()->UpdateStatus (SelectMgr_TOU_Full);
+ return;
+ }
+ }
+}
+
//=======================================================================
//function : SetAttributes
//purpose :
// computed in ::Compute() call for whole shape and stored in base drawer.
theDrawer->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
}
+
+//=======================================================================
+//function : SetAssemblyOwner
+//purpose : Sets common entity owner for assembly sensitive object entities
+//=======================================================================
+void SelectMgr_SelectableObject::SetAssemblyOwner (const Handle(SelectMgr_EntityOwner)& theOwner,
+ const Standard_Integer theMode)
+{
+ if (theMode == -1)
+ {
+ for (Standard_Integer aModeIter = 1; aModeIter <= myselections.Length(); ++aModeIter)
+ {
+ Handle(SelectMgr_Selection)& aSel = myselections.ChangeValue (aModeIter);
+ for (aSel->Init(); aSel->More(); aSel->Next())
+ {
+ aSel->Sensitive()->BaseSensitive()->Set (theOwner);
+ }
+ }
+
+ return;
+ }
+
+ if (!HasSelection (theMode))
+ return;
+
+ for (Standard_Integer aModeIter = 1; aModeIter <= myselections.Length(); ++aModeIter)
+ {
+ if (myselections.Value (aModeIter)->Mode() == theMode)
+ {
+ Handle(SelectMgr_Selection)& aSel = myselections.ChangeValue (aModeIter);
+ for (aSel->Init(); aSel->More(); aSel->Next())
+ {
+ aSel->Sensitive()->BaseSensitive()->Set (theOwner);
+ }
+ return;
+ }
+ }
+}
+
+//=======================================================================
+//function : GetAssemblyOwner
+//purpose : Returns common entity owner if it is an assembly
+//=======================================================================
+const Handle(SelectMgr_EntityOwner)& SelectMgr_SelectableObject::GetAssemblyOwner() const
+{
+ return myAssemblyOwner;
+}
+
+//=======================================================================
+//function : BndBoxOfSelected
+//purpose : Returns a bounding box of sensitive entities with the owners given
+// if they are a part of activated selection
+//=======================================================================
+Bnd_Box SelectMgr_SelectableObject::BndBoxOfSelected (Handle(SelectMgr_IndexedMapOfOwner)& theOwners)
+{
+ Bnd_Box aBnd;
+
+ if (theOwners->IsEmpty())
+ return aBnd;
+
+ for (Init(); More(); Next())
+ {
+ const Handle(SelectMgr_Selection)& aSel = CurrentSelection();
+ if (aSel->GetSelectionState() != SelectMgr_SOS_Activated)
+ continue;
+
+ for (aSel->Init(); aSel->More(); aSel->Next())
+ {
+ const Handle(SelectMgr_EntityOwner) anOwner =
+ Handle(SelectMgr_EntityOwner)::DownCast (aSel->Sensitive()->BaseSensitive()->OwnerId());
+ if (theOwners->Contains (anOwner))
+ {
+ Select3D_BndBox3d aBox = aSel->Sensitive()->BaseSensitive()->BoundingBox();
+ Bnd_Box aTmpBnd;
+ aTmpBnd.Update (aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
+ aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
+ aBnd.Add (aTmpBnd);
+
+ Standard_Integer anOwnerIdx = theOwners->FindIndex (anOwner);
+ if (theOwners->Size() != anOwnerIdx)
+ {
+ theOwners->Swap (anOwnerIdx, theOwners->Size());
+ }
+ theOwners->RemoveLast();
+
+ if (theOwners->IsEmpty())
+ return aBnd;
+ }
+ }
+ }
+
+ return aBnd;
+}
+
+//=======================================================================
+//function : GlobalSelOwner
+//purpose : Returns entity owner corresponding to selection of the object as a whole
+//=======================================================================
+Handle(SelectMgr_EntityOwner) SelectMgr_SelectableObject::GlobalSelOwner() const
+{
+ Handle(SelectMgr_EntityOwner) anOwner;
+
+ if (!HasSelection (myGlobalSelMode))
+ return anOwner;
+
+ const Handle(SelectMgr_Selection)& aGlobalSel = Selection (myGlobalSelMode);
+ if (aGlobalSel->IsEmpty())
+ return anOwner;
+
+ aGlobalSel->Init();
+ anOwner =
+ Handle(SelectMgr_EntityOwner)::DownCast (aGlobalSel->Sensitive()->BaseSensitive()->OwnerId());
+
+ return anOwner;
+}