diff --git a/src/AIS/AIS_Trihedron.cdl b/src/AIS/AIS_Trihedron.cdl index 9cb3e1ff26..8b5ad47e2e 100755 --- a/src/AIS/AIS_Trihedron.cdl +++ b/src/AIS/AIS_Trihedron.cdl @@ -28,7 +28,11 @@ class Trihedron from AIS inherits InteractiveObject from AIS -- for length are stocked. For trihedra, this is -- AIS_Drawer_FirstAxisAspect. You change the -- values inside this Aspect and recalculate the presentation. - -- + -- If you want to use extended selection modes, different than 0, + -- you should take care of removing of the shapes from the interactive + -- context that has been computed for selection; it might be necessary + -- when you change selection mode. You can use methods Axis, Point, + -- Plane to retrieve the shapes. uses Axis2Placement from Geom, @@ -46,7 +50,8 @@ uses Plane from AIS, KindOfInteractive from AIS, InteractiveContext from AIS, - Array1OfPnt from TColgp + Array1OfPnt from TColgp, + Location from TopLoc is Create(aComponent : Axis2Placement from Geom) @@ -140,6 +145,12 @@ is -- WARNING : must be applied -- to the object to display before computation !!! +-- Methods from PresentableObject + + SetLocation(me : mutable; + aLoc : Location from TopLoc) + is redefined static; + -- Methods from SelectableObject ComputeSelection(me : mutable; diff --git a/src/AIS/AIS_Trihedron.cxx b/src/AIS/AIS_Trihedron.cxx index 03c08ca436..5b0ad1b5c5 100755 --- a/src/AIS/AIS_Trihedron.cxx +++ b/src/AIS/AIS_Trihedron.cxx @@ -71,9 +71,41 @@ myHasOwnSize(Standard_False) void AIS_Trihedron::SetComponent(const Handle(Geom_Axis2Placement)& aComponent) { myComponent = aComponent; + + // Remove from current context and nullify objects to update + Handle(AIS_InteractiveContext) anAISContext = GetContext(); + Standard_Boolean hasContext = (anAISContext.IsNull() == Standard_False); + Standard_Integer anIdx; + for (anIdx = 0; anIdx < 7; anIdx++) + { + // Deselect object + if (hasContext) + { + if (anAISContext->IsSelected (myShapes[anIdx])) + anAISContext->AddOrRemoveSelected (myShapes[anIdx], Standard_False); + + anAISContext->Remove (myShapes[anIdx], Standard_False); + } + myShapes[anIdx].Nullify(); + } + LoadSubObjects(); } +//======================================================================= +//function : SetLocation +//purpose : +//======================================================================= + +void AIS_Trihedron::SetLocation(const TopLoc_Location& aLoc) +{ + // Update location to the subshapes + Standard_Integer anIdx; + for (anIdx = 0; anIdx < 7; anIdx++) + myShapes[anIdx]->SetLocation (aLoc); + + AIS_InteractiveObject::SetLocation (aLoc); +} //======================================================================= //function : SetSize @@ -266,10 +298,23 @@ void AIS_Trihedron::ComputeSelection(const Handle(SelectMgr_Selection)& aSelecti const Standard_Integer aMode) { // retrieve the tops of the trihedron. - Standard_Integer Prior; + Standard_Integer Prior, anIdx; Handle(SelectMgr_EntityOwner) eown; TColgp_Array1OfPnt PP(1,4),PO(1,4); ExtremityPoints(PP); + + // remove shapes from active selections + Handle(AIS_InteractiveContext) anAISContext = GetContext(); + if (!anAISContext.IsNull()) + for (anIdx = 0; anIdx < 7; anIdx++) + { + // Deselect object + if (anAISContext->IsSelected (myShapes[anIdx])) + anAISContext->AddOrRemoveSelected (myShapes[anIdx], Standard_False); + + anAISContext->Remove (myShapes[anIdx], Standard_False); + } + switch (aMode) { case 0: { // complete triedron only 1 owner : this... priority 5 (same as faces) @@ -285,7 +330,15 @@ void AIS_Trihedron::ComputeSelection(const Handle(SelectMgr_Selection)& aSelecti eown= new SelectMgr_EntityOwner(myShapes[0],Prior); aSelection->Add(new Select3D_SensitivePoint (eown,myComponent->Location())); - + // If the trihedron's shapes display and selection modes are the same + // the shapes are still displayed after selection, so we need to + // use different presentation and hide it by nullifying + if (!anAISContext.IsNull()) + { + anAISContext->Display (myShapes[0], 1, 0, Standard_False); + anAISContext->ClearPrs (myShapes[0], 1, Standard_False); + } + break; } case 2: @@ -296,6 +349,29 @@ void AIS_Trihedron::ComputeSelection(const Handle(SelectMgr_Selection)& aSelecti aSelection->Add(new Select3D_SensitiveSegment(eown,PP(1),PP(i+1))); } + + // If the trihedron's shapes display and selection modes are the same + // the shapes are still displayed after selection, so we need to + // use different presentation and hide it by nullifying + AIS_TypeOfAxis anAxisType; + if (!anAISContext.IsNull()) + for (anIdx = 1; anIdx <= 3; anIdx++) + { + // update AIS_Axis for selection + Handle(AIS_Axis) anAxis = Handle(AIS_Axis)::DownCast(myShapes[anIdx]); + Handle(AIS_Drawer) aDrawer = anAxis->Attributes(); + Handle(Prs3d_DatumAspect) aDatum = myDrawer->DatumAspect(); + aDrawer->DatumAspect()->SetAxisLength (aDatum->FirstAxisLength(), + aDatum->SecondAxisLength(), + aDatum->ThirdAxisLength()); + anAxisType = anAxis->TypeOfAxis(); + anAxis->SetAxis2Placement (myComponent, anAxisType); + + // display + anAISContext->Display (myShapes[anIdx], 1, 0, Standard_False); + anAISContext->ClearPrs (myShapes[anIdx], 1, Standard_False); + } + break; } @@ -318,6 +394,15 @@ void AIS_Trihedron::ComputeSelection(const Handle(SelectMgr_Selection)& aSelecti // PO(2) = PP(4);PO(3) = PP(2); aSelection->Add(new Select3D_SensitiveTriangle(eown,PP(1),PP(3),PP(4))); + // If the trihedron's shapes display and selection modes are the same + // the shapes are still displayed after selection, so we need to + // use different presentation and hide it by nullifying + if (!anAISContext.IsNull()) + for (anIdx = 4; anIdx < 7; anIdx++) + { + anAISContext->Display (myShapes[anIdx], 1, 0, Standard_False); + anAISContext->ClearPrs (myShapes[anIdx], 1, Standard_False); + } } } @@ -550,9 +635,26 @@ void AIS_Trihedron::SetContext(const Handle(AIS_InteractiveContext)& Ctx) { // Standard_Boolean same_DA = myDrawer->Link() == Ctx->DefaultDrawer(); - AIS_InteractiveObject::SetContext(Ctx); + // Remove subobjects from current context + Handle(AIS_InteractiveContext) anAISContext = GetContext(); + Standard_Boolean hasContext = (anAISContext.IsNull() == Standard_False); + Standard_Integer anIdx; + for (anIdx = 0; anIdx < 7; anIdx++) + { + // Deselect object + if (hasContext) + { + if (anAISContext->IsSelected (myShapes[anIdx])) + anAISContext->AddOrRemoveSelected (myShapes[anIdx]); + + anAISContext->Remove (myShapes[anIdx], Standard_False); + } + myShapes[anIdx].Nullify(); + } + + AIS_InteractiveObject::SetContext (Ctx); LoadSubObjects(); for(Standard_Integer i= 0;i<=6;i++) - myShapes[i]->SetContext(Ctx); + myShapes[i]->SetContext (Ctx); } diff --git a/src/SelectMgr/SelectMgr_SelectableObject.cxx b/src/SelectMgr/SelectMgr_SelectableObject.cxx index adef86b8a6..ac0dbeaf59 100755 --- a/src/SelectMgr/SelectMgr_SelectableObject.cxx +++ b/src/SelectMgr/SelectMgr_SelectableObject.cxx @@ -216,6 +216,11 @@ void SelectMgr_SelectableObject::UpdateLocation(const Handle(SelectMgr_Selection SE = *((Handle(Select3D_SensitiveEntity)*) &(Sel->Sensitive())); if(!SE.IsNull()){ SE->UpdateLocation(myLocation); + const Handle(SelectBasics_EntityOwner)& aEOwner = SE->OwnerId(); + Handle(SelectMgr_EntityOwner) aMgrEO = + Handle(SelectMgr_EntityOwner)::DownCast (aEOwner); + if (!aMgrEO.IsNull()) + aMgrEO->SetLocation (myLocation); } } } diff --git a/src/StdSelect/StdSelect_BRepOwner.cxx b/src/StdSelect/StdSelect_BRepOwner.cxx index 7e3bd1bf79..706f5ffb5b 100755 --- a/src/StdSelect/StdSelect_BRepOwner.cxx +++ b/src/StdSelect/StdSelect_BRepOwner.cxx @@ -78,10 +78,21 @@ void StdSelect_BRepOwner::Hilight(const Handle(PrsMgr_PresentationManager)& PM, #else Standard_Integer M = (myCurMode==-1) ? aMode:myCurMode; #endif - if(myFromDecomposition) + if (myFromDecomposition) + { + // do the update flag check + if (!myPrsSh.IsNull()) + { + TColStd_ListOfInteger aModesList; + myPrsSh->ToBeUpdated (aModesList); + if (!aModesList.IsEmpty()) + myPrsSh.Nullify(); + } + if(myPrsSh.IsNull()) - myPrsSh = new StdSelect_Shape(myShape); - + myPrsSh = new StdSelect_Shape (myShape); + } + if(myPrsSh.IsNull()) PM->Highlight(Selectable(),M); else @@ -100,7 +111,17 @@ void StdSelect_BRepOwner::HilightWithColor(const Handle(PrsMgr_PresentationManag #else Standard_Integer M = (myCurMode==-1) ? aMode:myCurMode; #endif - if(myFromDecomposition){ + if (myFromDecomposition) + { + // do the update flag check + if (!myPrsSh.IsNull()) + { + TColStd_ListOfInteger aModesList; + myPrsSh->ToBeUpdated (aModesList); + if (!aModesList.IsEmpty()) + myPrsSh.Nullify(); + } + if(myPrsSh.IsNull()){ if(HasLocation()){ TopLoc_Location lbid = Location() * myShape.Location(); @@ -147,13 +168,20 @@ void StdSelect_BRepOwner::Clear(const Handle(PrsMgr_PresentationManager)& PM, void StdSelect_BRepOwner::SetLocation(const TopLoc_Location& aLoc) { SelectMgr_EntityOwner::SetLocation(aLoc); - if(!myPrsSh.IsNull()) - myPrsSh.Nullify(); - + // we must not nullify the myPrsSh here, because unhilight method + // will be working with wrong entity in this case, the best is to + // set the update flag and then recompute myPrsSh on hilighting + if (!myPrsSh.IsNull()) + myPrsSh->SetToUpdate(); + } void StdSelect_BRepOwner::ResetLocation() { SelectMgr_EntityOwner::ResetLocation(); - if(!myPrsSh.IsNull()) - myPrsSh.Nullify(); + // we must not nullify the myPrsSh here, because unhilight method + // will be working with wrong entity in this case, the best is to + // set the update flag and then recompute myPrsSh on hilighting + if (!myPrsSh.IsNull()) + myPrsSh->SetToUpdate(); + } diff --git a/src/ViewerTest/ViewerTest_ObjectCommands.cxx b/src/ViewerTest/ViewerTest_ObjectCommands.cxx index d60832b913..98f06a7e99 100755 --- a/src/ViewerTest/ViewerTest_ObjectCommands.cxx +++ b/src/ViewerTest/ViewerTest_ObjectCommands.cxx @@ -76,6 +76,8 @@ #include #include #include +#include +#include #include #include @@ -3197,6 +3199,62 @@ static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char* return 0; } +//======================================================================= +//function : VSetLocation +//purpose : Change location of AIS interactive object +//======================================================================= + +static Standard_Integer VSetLocation (Draw_Interpretor& di, + Standard_Integer argc, + const char ** argv) +{ + Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext(); + if (aContext.IsNull()) + { + di << argv[0] << "ERROR : use 'vinit' command before " << "\n"; + return 1; + } + + if (argc != 5) + { + di << "ERROR : Usage : " << argv[0] << " name x y z; new location" << "\n"; + return 1; + } + + TCollection_AsciiString aName (argv[1]); + Standard_Real aX = atof (argv[2]); + Standard_Real aY = atof (argv[3]); + Standard_Real aZ = atof (argv[4]); + + // find object + ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS(); + Handle(AIS_InteractiveObject) anIObj; + if (!aMap.IsBound2 (aName)) + { + di << "Use 'vdisplay' before" << "\n"; + return 1; + } + else + { + anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName)); + + // not an AIS_InteractiveObject + if (anIObj.IsNull()) + { + di << argv[1] << " : Not an AIS interactive object" << "\n"; + return 1; + } + + gp_Trsf aTrsf; + aTrsf.SetTranslation (gp_Vec (aX, aY, aZ)); + TopLoc_Location aLocation (aTrsf); + aContext->SetLocation (anIObj, aLocation); + aContext->UpdateCurrentViewer(); + } + + return 0; +} + //======================================================================= //function : ObjectsCommands //purpose : @@ -3269,6 +3327,10 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands) "vclipplane : vclipplane [x y z dx dy dz] [planeId {on/off/del/display/hide}]", __FILE__,VClipPlane,group); + theCommands.Add ("vsetlocation", + "vsetlocation : name x y z; set new location for an interactive object", + __FILE__, VSetLocation, group); + theCommands.Add ( "vcomputehlr", "vcomputehlr: shape hlrname [ eyex eyey eyez lookx looky lookz ]",