diff --git a/src/AIS/AIS_InteractiveContext.cxx b/src/AIS/AIS_InteractiveContext.cxx index 10da2d29c5..e2672112b2 100644 --- a/src/AIS/AIS_InteractiveContext.cxx +++ b/src/AIS/AIS_InteractiveContext.cxx @@ -2728,6 +2728,23 @@ Standard_Integer AIS_InteractiveContext::PixelTolerance() const : myMainSel->PixelTolerance(); } +//======================================================================= +//function : SetSelectionSensitivity +//purpose : Allows to manage sensitivity of a particular selection of interactive object theObject +//======================================================================= +void AIS_InteractiveContext::SetSelectionSensitivity (const Handle(AIS_InteractiveObject)& theObject, + const Standard_Integer theMode, + const Standard_Integer theNewSensitivity) +{ + if (HasOpenedContext()) + { + myLocalContexts (myCurLocalIndex)->SetSelectionSensitivity (theObject, theMode, theNewSensitivity); + return; + } + + mgrSelector->SetSelectionSensitivity (theObject, theMode, theNewSensitivity); +} + //======================================================================= //function : IsInLocal //purpose : diff --git a/src/AIS/AIS_InteractiveContext.hxx b/src/AIS/AIS_InteractiveContext.hxx index bb711b9bc1..9e7c60f55d 100644 --- a/src/AIS/AIS_InteractiveContext.hxx +++ b/src/AIS/AIS_InteractiveContext.hxx @@ -371,6 +371,13 @@ public: //! Returns the pixel tolerance. Standard_EXPORT Standard_Integer PixelTolerance() const; + + //! Allows to manage sensitivity of a particular selection of interactive object theObject + //! and changes previous sensitivity value of all sensitive entities in selection with theMode + //! to the given theNewSensitivity. + Standard_EXPORT void SetSelectionSensitivity (const Handle(AIS_InteractiveObject)& theObject, + const Standard_Integer theMode, + const Standard_Integer theNewSensitivity); //! Puts the location aLocation on the initial graphic //! representation and the selection for the entity aniobj. diff --git a/src/AIS/AIS_LocalContext.cxx b/src/AIS/AIS_LocalContext.cxx index 6505689783..d4c400f9f0 100644 --- a/src/AIS/AIS_LocalContext.cxx +++ b/src/AIS/AIS_LocalContext.cxx @@ -1153,3 +1153,14 @@ Standard_Integer AIS_LocalContext::PixelTolerance() const { return myMainVS->PixelTolerance(); } + +//======================================================================= +//function : SetSelectionSensitivity +//purpose : Allows to manage sensitivity of a particular selection of interactive object theObject +//======================================================================= +void AIS_LocalContext::SetSelectionSensitivity (const Handle(AIS_InteractiveObject)& theObject, + const Standard_Integer theMode, + const Standard_Integer theNewSensitivity) +{ + mySM->SetSelectionSensitivity (theObject, theMode, theNewSensitivity); +} diff --git a/src/AIS/AIS_LocalContext.hxx b/src/AIS/AIS_LocalContext.hxx index 6a4c66f218..eed643be10 100644 --- a/src/AIS/AIS_LocalContext.hxx +++ b/src/AIS/AIS_LocalContext.hxx @@ -317,7 +317,14 @@ public: //! Returns the pixel tolerance. Standard_EXPORT Standard_Integer PixelTolerance() const; - + + //! Allows to manage sensitivity of a particular selection of interactive object theObject + //! and changes previous sensitivity value of all sensitive entities in selection with theMode + //! to the given theNewSensitivity. + Standard_EXPORT void SetSelectionSensitivity (const Handle(AIS_InteractiveObject)& theObject, + const Standard_Integer theMode, + const Standard_Integer theNewSensitivity); + //! Resets the transient list of presentations previously displayed in immediate mode //! and begins accumulation of new list by following AddToImmediateList()/Color()/Highlight() calls. Standard_EXPORT Standard_Boolean BeginImmediateDraw(); diff --git a/src/QABugs/QABugs_19.cxx b/src/QABugs/QABugs_19.cxx index b9a02cb804..c3966728ee 100644 --- a/src/QABugs/QABugs_19.cxx +++ b/src/QABugs/QABugs_19.cxx @@ -4034,6 +4034,61 @@ static Standard_Integer OCC26195 (Draw_Interpretor& theDI, Standard_Integer theA return 0; } +//======================================================================= +//function : OCC26462 +//purpose : +//======================================================================= +static Standard_Integer OCC26462 (Draw_Interpretor& theDI, Standard_Integer /*theArgNb*/, const char** /*theArgVec*/) +{ + if (ViewerTest::GetAISContext().IsNull()) + { + std::cerr << "Error: No opened context!\n"; + return 1; + } + + BRepPrimAPI_MakeBox aBuilder1 (gp_Pnt (10.0, 10.0, 0.0), 10.0, 10.0, 10.0); + BRepPrimAPI_MakeBox aBuilder2 (10.0, 10.0, 10.0); + Handle(AIS_InteractiveObject) aBox1 = new AIS_Shape (aBuilder1.Shape()); + Handle(AIS_InteractiveObject) aBox2 = new AIS_Shape (aBuilder2.Shape()); + + const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext(); + aCtx->OpenLocalContext(); + aCtx->Display (aBox1, 0, 2); + aCtx->Display (aBox2, 0, 2); + ViewerTest::CurrentView()->FitAll(); + aCtx->SetWidth (aBox1, 3); + aCtx->SetWidth (aBox2, 3); + + aCtx->MoveTo (305, 322, ViewerTest::CurrentView()); + aCtx->ShiftSelect(); + aCtx->MoveTo (103, 322, ViewerTest::CurrentView()); + aCtx->ShiftSelect(); + if (aCtx->NbSelected() != 0) + { + theDI << "ERROR: no boxes must be selected!\n"; + return 1; + } + + aCtx->SetSelectionSensitivity (aBox1, 2, 5); + + aCtx->MoveTo (305, 322, ViewerTest::CurrentView()); + aCtx->ShiftSelect(); + if (aCtx->NbSelected() != 1) + { + theDI << "ERROR: b1 was not selected\n"; + return 1; + } + aCtx->MoveTo (103, 322, ViewerTest::CurrentView()); + aCtx->ShiftSelect(); + if (aCtx->NbSelected() != 1) + { + theDI << "ERROR: b2 is selected after b1's tolerance increased\n"; + return 1; + } + + return 0; +} + void QABugs::Commands_19(Draw_Interpretor& theCommands) { const char *group = "QABugs"; @@ -4118,5 +4173,8 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) { "\n\t\t: [toPrintPixelCoord 0|1] - prints 3d projection of pixel coordinate or center of" "\n\t\t: selecting rectangle onto near and far view frustum planes", __FILE__, OCC26195, group); + theCommands.Add ("OCC26462", + "OCC26462: Checks the ability to manage sensitivity of a particular selection mode in local context", + __FILE__, OCC26462, group); return; } diff --git a/src/SelectBasics/SelectBasics_SensitiveEntity.cxx b/src/SelectBasics/SelectBasics_SensitiveEntity.cxx index eea56949da..02392cc9aa 100644 --- a/src/SelectBasics/SelectBasics_SensitiveEntity.cxx +++ b/src/SelectBasics/SelectBasics_SensitiveEntity.cxx @@ -45,3 +45,15 @@ const Handle(SelectBasics_EntityOwner)& SelectBasics_SensitiveEntity::OwnerId() { return myOwnerId; } + +//======================================================================= +// function : SetSensitivityFactor +// purpose : Allows to manage sensitivity of a particular entity +//======================================================================= +void SelectBasics_SensitiveEntity::SetSensitivityFactor (const Standard_Integer theNewSens) +{ + Standard_ASSERT_RAISE (theNewSens > 0, + "Error! Selection sensitivity have positive value."); + + mySFactor = theNewSens; +} diff --git a/src/SelectBasics/SelectBasics_SensitiveEntity.hxx b/src/SelectBasics/SelectBasics_SensitiveEntity.hxx index 75897ade27..36b5a6cbc3 100644 --- a/src/SelectBasics/SelectBasics_SensitiveEntity.hxx +++ b/src/SelectBasics/SelectBasics_SensitiveEntity.hxx @@ -58,6 +58,9 @@ public: //! a specific entity in selection algorithms //! useful for small sized entities. Standard_EXPORT Standard_Integer SensitivityFactor() const; + + //! Allows to manage sensitivity of a particular sensitive entity + Standard_EXPORT void SetSensitivityFactor (const Standard_Integer theNewSens); //! Returns the number of sub-entities or elements in //! sensitive entity. Is used to determine if entity is @@ -88,9 +91,6 @@ protected: Standard_EXPORT SelectBasics_SensitiveEntity (const Handle(SelectBasics_EntityOwner)& theOwnerId); - //! Allows to manage the sensitivity of the entity - void SetSensitivityFactor (const Standard_Integer theSensFactor); - Handle(SelectBasics_EntityOwner) myOwnerId; diff --git a/src/SelectBasics/SelectBasics_SensitiveEntity.lxx b/src/SelectBasics/SelectBasics_SensitiveEntity.lxx index 380ceb17fc..9d134fecc1 100644 --- a/src/SelectBasics/SelectBasics_SensitiveEntity.lxx +++ b/src/SelectBasics/SelectBasics_SensitiveEntity.lxx @@ -12,15 +12,6 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -//======================================================================= -// function : SetSensitivityFactor -// purpose : Allows to manage the sensitivity of the entity -//======================================================================= -inline void SelectBasics_SensitiveEntity::SetSensitivityFactor (const Standard_Integer theSensFactor) -{ - mySFactor = theSensFactor; -} - //======================================================================= // function : SensitivityFactor // purpose : Gets sensitivity factor for the entity diff --git a/src/SelectMgr/SelectMgr_Selection.cxx b/src/SelectMgr/SelectMgr_Selection.cxx index 1ed7f78fcb..e7237fbbb9 100644 --- a/src/SelectMgr/SelectMgr_Selection.cxx +++ b/src/SelectMgr/SelectMgr_Selection.cxx @@ -27,7 +27,8 @@ SelectMgr_Selection::SelectMgr_Selection (const Standard_Integer theModeIdx) : myMode (theModeIdx), mySelectionState (SelectMgr_SOS_Unknown), myBVHUpdateStatus (SelectMgr_TBU_None), - mySensFactor (2) + mySensFactor (2), + myIsCustomSens (Standard_False) {} SelectMgr_Selection::~SelectMgr_Selection() @@ -71,8 +72,15 @@ void SelectMgr_Selection::Add (const Handle(SelectBasics_SensitiveEntity)& theSe anEntity->SetActiveForSelection(); } - mySensFactor = Max (mySensFactor, - anEntity->BaseSensitive()->SensitivityFactor()); + if (myIsCustomSens) + { + anEntity->BaseSensitive()->SetSensitivityFactor (mySensFactor); + } + else + { + mySensFactor = Max (mySensFactor, + anEntity->BaseSensitive()->SensitivityFactor()); + } } } @@ -136,3 +144,20 @@ Standard_Integer SelectMgr_Selection::Sensitivity() const { return mySensFactor; } + +//================================================== +// function: SetSensitivity +// purpose : Changes sensitivity of the selection and all its entities to the given value. +// IMPORTANT: This method does not update any outer selection structures, so for +// proper updates use SelectMgr_SelectionManager::SetSelectionSensitivity method. +//================================================== +void SelectMgr_Selection::SetSensitivity (const Standard_Integer theNewSens) +{ + mySensFactor = theNewSens; + myIsCustomSens = Standard_True; + for (Standard_Integer anIdx = 0; anIdx < myEntities.Size(); ++anIdx) + { + Handle(SelectMgr_SensitiveEntity)& anEntity = myEntities.ChangeValue (anIdx); + anEntity->BaseSensitive()->SetSensitivityFactor (theNewSens); + } +} diff --git a/src/SelectMgr/SelectMgr_Selection.hxx b/src/SelectMgr/SelectMgr_Selection.hxx index 1eaa243405..59c8eab60e 100644 --- a/src/SelectMgr/SelectMgr_Selection.hxx +++ b/src/SelectMgr/SelectMgr_Selection.hxx @@ -132,6 +132,11 @@ public: //! Returns sensitivity of the selection Standard_EXPORT Standard_Integer Sensitivity() const; + //! Changes sensitivity of the selection and all its entities to the given value. + //! IMPORTANT: This method does not update any outer selection structures, so for + //! proper updates use SelectMgr_SelectionManager::SetSelectionSensitivity method. + Standard_EXPORT void SetSensitivity (const Standard_Integer theNewSens); + DEFINE_STANDARD_RTTI (SelectMgr_Selection, MMgt_TShared) protected: @@ -148,6 +153,7 @@ private: mutable SelectMgr_StateOfSelection mySelectionState; mutable SelectMgr_TypeOfBVHUpdate myBVHUpdateStatus; Standard_Integer mySensFactor; + Standard_Boolean myIsCustomSens; }; DEFINE_STANDARD_HANDLE(SelectMgr_Selection, MMgt_TShared) diff --git a/src/SelectMgr/SelectMgr_SelectionManager.cxx b/src/SelectMgr/SelectMgr_SelectionManager.cxx index bc96515bce..154c2c63c0 100644 --- a/src/SelectMgr/SelectMgr_SelectionManager.cxx +++ b/src/SelectMgr/SelectMgr_SelectionManager.cxx @@ -905,3 +905,51 @@ void SelectMgr_SelectionManager::SetUpdateMode (const Handle(SelectMgr_Selectabl theObject->Selection (theMode)->UpdateStatus (theType); } +//======================================================================= +//function : SetSelectionSensitivity +//purpose : Allows to manage sensitivity of a particular selection of interactive object theObject and +// changes previous sensitivity value of all sensitive entities in selection with theMode +// to the given theNewSensitivity. +//======================================================================= +void SelectMgr_SelectionManager::SetSelectionSensitivity (const Handle(SelectMgr_SelectableObject)& theObject, + const Standard_Integer theMode, + const Standard_Integer theNewSens) +{ + Standard_ASSERT_RAISE (theNewSens > 0, + "Error! Selection sensitivity have positive value."); + + if (theObject.IsNull() || !theObject->HasSelection (theMode)) + return; + + Handle(SelectMgr_Selection) aSel = theObject->Selection (theMode); + const Standard_Integer aPrevSens = aSel->Sensitivity(); + aSel->SetSensitivity (theNewSens); + + if (!(myGlobal.Contains (theObject) || myLocal.IsBound (theObject))) + return; + + if (myGlobal.Contains (theObject)) + { + for (TColStd_MapIteratorOfMapOfTransient aSelectorsIter (mySelectors); aSelectorsIter.More(); aSelectorsIter.Next()) + { + Handle(SelectMgr_ViewerSelector) aSelector = Handle(SelectMgr_ViewerSelector)::DownCast (aSelectorsIter.Key()); + if (aSelector->Contains (theObject)) + { + aSelector->myTolerances.Decrement (aPrevSens); + aSelector->myTolerances.Add (theNewSens); + aSelector->myToUpdateTolerance = Standard_True; + } + } + } + if (myLocal.IsBound (theObject)) + { + const SelectMgr_SequenceOfSelector& aSelectors = myLocal (theObject); + for (SelectMgr_SequenceOfSelector::Iterator aLocalIter (aSelectors); aLocalIter.More(); aLocalIter.Next()) + { + Handle(SelectMgr_ViewerSelector)& aCurSel = aLocalIter.ChangeValue(); + aCurSel->myTolerances.Decrement (aPrevSens); + aCurSel->myTolerances.Add (theNewSens); + aCurSel->myToUpdateTolerance = Standard_True; + } + } +} diff --git a/src/SelectMgr/SelectMgr_SelectionManager.hxx b/src/SelectMgr/SelectMgr_SelectionManager.hxx index c0f40ca385..16a85c94a0 100644 --- a/src/SelectMgr/SelectMgr_SelectionManager.hxx +++ b/src/SelectMgr/SelectMgr_SelectionManager.hxx @@ -118,8 +118,12 @@ public: //! Sets type of update of selection with theMode of theObject to the given theType. Standard_EXPORT void SetUpdateMode (const Handle(SelectMgr_SelectableObject)& theObject, const Standard_Integer theMode, const SelectMgr_TypeOfUpdate theType); - - + //! Allows to manage sensitivity of a particular selection of interactive object theObject and + //! changes previous sensitivity value of all sensitive entities in selection with theMode + //! to the given theNewSensitivity. + Standard_EXPORT void SetSelectionSensitivity (const Handle(SelectMgr_SelectableObject)& theObject, + const Standard_Integer theMode, + const Standard_Integer theNewSens); DEFINE_STANDARD_RTTI(SelectMgr_SelectionManager,MMgt_TShared) diff --git a/src/ViewerTest/ViewerTest.cxx b/src/ViewerTest/ViewerTest.cxx index 47242fe29e..be00157302 100644 --- a/src/ViewerTest/ViewerTest.cxx +++ b/src/ViewerTest/ViewerTest.cxx @@ -1474,6 +1474,10 @@ struct ViewerTest_AspectsChangeSet Standard_Integer ToSetMaxParamValue; Standard_Real MaxParamValue; + Standard_Integer ToSetSensitivity; + Standard_Integer SelectionMode; + Standard_Integer Sensitivity; + //! Empty constructor ViewerTest_AspectsChangeSet() : ToSetVisibility (0), @@ -1495,7 +1499,10 @@ struct ViewerTest_AspectsChangeSet FreeBoundaryColor (DEFAULT_FREEBOUNDARY_COLOR), ToEnableIsoOnTriangulation (-1), ToSetMaxParamValue (0), - MaxParamValue (500000) {} + MaxParamValue (500000), + ToSetSensitivity (0), + SelectionMode (-1), + Sensitivity (-1) {} //! @return true if no changes have been requested Standard_Boolean IsEmpty() const @@ -1508,7 +1515,8 @@ struct ViewerTest_AspectsChangeSet && ToSetShowFreeBoundary == 0 && ToSetFreeBoundaryColor == 0 && ToSetFreeBoundaryWidth == 0 - && ToSetMaxParamValue == 0; + && ToSetMaxParamValue == 0 + && ToSetSensitivity == 0; } //! @return true if properties are valid @@ -1555,6 +1563,11 @@ struct ViewerTest_AspectsChangeSet std::cout << "Error: the max parameter value should be greater than zero (specified " << MaxParamValue << ")\n"; isOk = Standard_False; } + if (Sensitivity <= 0 && ToSetSensitivity) + { + std::cout << "Error: sensitivity parameter value should be positive (specified " << Sensitivity << ")\n"; + isOk = Standard_False; + } return isOk; } @@ -2120,6 +2133,29 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, aChangeSet->ToSetMaxParamValue = 1; aChangeSet->MaxParamValue = Draw::Atof (theArgVec[anArgIter]); } + else if (anArg == "-setsensitivity") + { + if (isDefaults) + { + std::cout << "Error: wrong syntax. -setSensitivity can not be used together with -defaults call!\n"; + return 1; + } + + if (aNames.IsEmpty()) + { + std::cout << "Error: object and selection mode should specified explicitly when -setSensitivity is used!\n"; + return 1; + } + + if (anArgIter + 2 >= theArgNb) + { + std::cout << "Error: wrong syntax at " << anArg << "\n"; + return 1; + } + aChangeSet->ToSetSensitivity = 1; + aChangeSet->SelectionMode = Draw::Atoi (theArgVec[++anArgIter]); + aChangeSet->Sensitivity = Draw::Atoi (theArgVec[++anArgIter]); + } else { std::cout << "Error: wrong syntax at " << anArg << "\n"; @@ -2293,6 +2329,10 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, aCtx->IsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1, aPrs); toRedisplay = Standard_True; } + else if (aChangeSet->ToSetSensitivity != 0) + { + aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity); + } if (!aDrawer.IsNull()) { if (aChangeSet->ToSetShowFreeBoundary == 1) @@ -2368,6 +2408,10 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape); aCurColDrawer->SetMaximalParameterValue (aChangeSet->MaxParamValue); } + if (aChangeSet->ToSetSensitivity != 0) + { + aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity); + } } } if (toDisplay) @@ -5541,6 +5585,7 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands) "\n\t\t: [-subshapes subname1 [subname2 [...]]]" "\n\t\t: [-isoontriangulation 0|1]" "\n\t\t: [-setMaxParamValue {value}]" + "\n\t\t: [-setSensitivity {selection_mode} {value}]" "\n\t\t: Manage presentation properties of all, selected or named objects." "\n\t\t: When -subshapes is specified than following properties will be" "\n\t\t: assigned to specified sub-shapes." diff --git a/tests/bugs/vis/bug26462_1 b/tests/bugs/vis/bug26462_1 new file mode 100644 index 0000000000..ac2bb31351 --- /dev/null +++ b/tests/bugs/vis/bug26462_1 @@ -0,0 +1,51 @@ +puts "============" +puts "CR26462" +puts "============" +puts "" + +########################################################################################## +puts "Visualization - selection does not adapt to line width change" +########################################################################################## + +pload VISUALIZATION MODELING + +vinit +box b1 10 10 10 +box b2 10 10 10 + +vdisplay b1 b2 +vsetlocation b1 10 10 0 +vfit + +vaspects b1 b2 -setWidth 3 + +vselmode 2 1 +# try to select b1 and b2 +vselect 305 322 1 +vselect 103 322 1 +# check that both boxes were not selected with default tolerance value +set aNbSelected [vnbselected] +if {$aNbSelected != "0"} { + puts "ERROR: no boxes must be selected!" +} + +# increase tolerance for b1 +vaspects b1 -setSensitivity 2 4 + +# select edge of b1 +vselect 305 322 +# check that b1's edge was selected +set aNbSelected [vnbselected] +if {$aNbSelected != "1"} { + puts "ERROR: b1 was not selected" +} +# try to select b2 +vselect 103 322 1 +# check that increase of tolerance for b1 doesn't influence +# on b2 +set aNbSelected [vnbselected] +if {$aNbSelected != "1"} { + puts "ERROR: b2 is selected after b1's tolerance increased" +} + +set only_screen 1 diff --git a/tests/bugs/vis/bug26462_2 b/tests/bugs/vis/bug26462_2 new file mode 100644 index 0000000000..78407185cc --- /dev/null +++ b/tests/bugs/vis/bug26462_2 @@ -0,0 +1,15 @@ +puts "============" +puts "CR26462" +puts "============" +puts "" + +########################################################################################## +puts "Visualization - selection does not adapt to line width change" +########################################################################################## + +pload VISUALIZATION QAcommands + +vinit +OCC26462 + +set only_screen 1