1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0026147: Visualization - restore the ability to pick only fully included objects in rectangular selection

2 modes of rectangular selection are available: inclusion-only and overlap-allowing;
The modes can be switched using method AllowOverlapDetection from StdSelect_ViewerSelector3d;
BVH for sensitive entities now builds if there is more than max number of leafs in collection;
Added option -allowoverlap to command vselect;
Interactive rectangular selection in Draw is now available in 2 modes:
- if the user starts selection from upper corners, only fully included objects will be selected;
- if the user starts selection from lower corners, both partially and fully overlapped objects will be selected.
This commit is contained in:
vpa
2015-05-07 18:53:21 +03:00
committed by abv
parent 35c4a17c46
commit 2157d6ac63
44 changed files with 728 additions and 547 deletions

View File

@@ -37,9 +37,19 @@ is
ShiftSelect(me:mutable) is virtual;
Select(me:mutable;xmin,ymin,xmax,ymax:Integer) is virtual;
Select (me : mutable;
theXPressed : Integer;
theYPressed : Integer;
theXMotion : Integer;
theYMotion : Integer;
theIsAutoAllowOverlap : Boolean from Standard = Standard_True) is virtual;
ShiftSelect(me:mutable;xmin,ymin,xmax,ymax:Integer) is virtual;
ShiftSelect (me : mutable;
theXPressed : Integer;
theYPressed : Integer;
theXMotion : Integer;
theYMotion : Integer;
theIsAutoAllowOverlap : Boolean from Standard = Standard_True) is virtual;
Select(me:mutable;thePolyline:Array1OfPnt2d from TColgp) is virtual;

View File

@@ -84,27 +84,56 @@ void ViewerTest_EventManager::MoveTo (const Standard_Integer theXPix,
//purpose :
//=======================================================================
void ViewerTest_EventManager::Select (const Standard_Integer theXPMin,
const Standard_Integer theYPMin,
const Standard_Integer theXPMax,
const Standard_Integer theYPMax)
void ViewerTest_EventManager::Select (const Standard_Integer theXPressed,
const Standard_Integer theYPressed,
const Standard_Integer theXMotion,
const Standard_Integer theYMotion,
const Standard_Boolean theIsAutoAllowOverlap)
{
#define IS_FULL_INCLUSION Standard_True
if (myView.IsNull()
|| Abs (theXPMax - theXPMin) < 2
|| Abs (theYPMax - theYPMin) < 2)
|| Abs (theXPressed - theXMotion) < 2
|| Abs (theYPressed - theYMotion) < 2)
{
return;
}
else if (!myCtx.IsNull())
{
myCtx->Select (theXPMin, theYPMin, theXPMax, theYPMax, myView, Standard_False);
if (theIsAutoAllowOverlap)
{
if (theYPressed == Min (theYPressed, theYMotion))
{
myCtx->MainSelector()->AllowOverlapDetection (Standard_False);
}
else
{
myCtx->MainSelector()->AllowOverlapDetection (Standard_True);
}
}
myCtx->Select (Min (theXPressed, theXMotion),
Min (theYPressed, theYMotion),
Max (theXPressed, theXMotion),
Max (theYPressed, theYMotion),
myView,
Standard_False);
// to restore default state of viewer selector
if (theIsAutoAllowOverlap)
{
myCtx->MainSelector()->AllowOverlapDetection (Standard_False);
}
}
const Handle(NIS_View) aView = Handle(NIS_View)::DownCast (myView);
if (!aView.IsNull())
{
aView->Select (theXPMin, theYPMin, theXPMax, theYPMax, Standard_False, IS_FULL_INCLUSION, Standard_False);
aView->Select (Min (theXPressed, theXMotion),
Min (theYPressed, theYMotion),
Max (theXPressed, theXMotion),
Max (theYPressed, theYMotion),
Standard_False,
IS_FULL_INCLUSION,
Standard_False);
}
myView->Redraw();
}
@@ -114,25 +143,54 @@ void ViewerTest_EventManager::Select (const Standard_Integer theXPMin,
//purpose :
//=======================================================================
void ViewerTest_EventManager::ShiftSelect (const Standard_Integer theXPMin,
const Standard_Integer theYPMin,
const Standard_Integer theXPMax,
const Standard_Integer theYPMax)
void ViewerTest_EventManager::ShiftSelect (const Standard_Integer theXPressed,
const Standard_Integer theYPressed,
const Standard_Integer theXMotion,
const Standard_Integer theYMotion,
const Standard_Boolean theIsAutoAllowOverlap)
{
if (myView.IsNull()
|| Abs (theXPMax - theXPMin) < 2
|| Abs (theYPMax - theYPMin) < 2)
|| Abs (theXPressed - theXMotion) < 2
|| Abs (theYPressed - theYMotion) < 2)
{
return;
}
else if (!myCtx.IsNull())
{
myCtx->AIS_InteractiveContext::ShiftSelect (theXPMin, theYPMin, theXPMax, theYPMax, myView, Standard_False);
if (theIsAutoAllowOverlap)
{
if (theYPressed == Min (theYPressed, theYMotion))
{
myCtx->MainSelector()->AllowOverlapDetection (Standard_False);
}
else
{
myCtx->MainSelector()->AllowOverlapDetection (Standard_True);
}
}
myCtx->ShiftSelect (Min (theXPressed, theXMotion),
Min (theYPressed, theYMotion),
Max (theXPressed, theXMotion),
Max (theYPressed, theYMotion),
myView,
Standard_False);
// to restore default state of viewer selector
if (theIsAutoAllowOverlap)
{
myCtx->MainSelector()->AllowOverlapDetection (Standard_False);
}
}
const Handle(NIS_View) aView = Handle(NIS_View)::DownCast (myView);
if (!aView.IsNull())
{
aView->Select (theXPMin, theYPMin, theXPMax, theYPMax, Standard_True, IS_FULL_INCLUSION, Standard_False);
aView->Select (Min (theXPressed, theXMotion),
Min (theYPressed, theYMotion),
Max (theXPressed, theXMotion),
Max (theYPressed, theYMotion),
Standard_True,
IS_FULL_INCLUSION,
Standard_False);
}
myView->Redraw();
}

View File

@@ -1606,13 +1606,13 @@ void VT_ProcessButton1Release (Standard_Boolean theIsShift)
Handle(ViewerTest_EventManager) EM = ViewerTest::CurrentEventManager();
if (theIsShift)
{
EM->ShiftSelect (Min (X_ButtonPress, X_Motion), Max (Y_ButtonPress, Y_Motion),
Max (X_ButtonPress, X_Motion), Min (Y_ButtonPress, Y_Motion));
EM->ShiftSelect (X_ButtonPress, Y_ButtonPress,
X_Motion, Y_Motion);
}
else
{
EM->Select (Min (X_ButtonPress, X_Motion), Max (Y_ButtonPress, Y_Motion),
Max (X_ButtonPress, X_Motion), Min (Y_ButtonPress, Y_Motion));
EM->Select (X_ButtonPress, Y_ButtonPress,
X_Motion, Y_Motion);
}
}
}
@@ -5767,34 +5767,48 @@ static Standard_Integer VSelect (Draw_Interpretor& di,
di << "use 'vinit' command before " << argv[0] << "\n";
return 1;
}
const Standard_Boolean isShiftSelection = (argc>3 && !(argc%2) && (atoi(argv[argc-1])==1));
const Standard_Boolean isShiftSelection = (argc > 3 && !(argc % 2) && (atoi (argv[argc - 1]) == 1));
Standard_Integer aCoordsNb = isShiftSelection ? argc - 2 : argc - 1;
TCollection_AsciiString anArg;
anArg = isShiftSelection ? argv[argc - 3] : argv[argc - 2];
anArg.LowerCase();
if (anArg == "-allowoverlap")
{
Standard_Boolean isValidated = isShiftSelection ? argc == 8
: argc == 7;
if (!isValidated)
{
di << "Wrong number of arguments! -allowoverlap key is applied only for rectangle selection";
return 1;
}
Standard_Integer isToAllow = isShiftSelection ? Draw::Atoi(argv[argc - 2]) : Draw::Atoi(argv[argc - 1]);
myAIScontext->MainSelector()->AllowOverlapDetection((Standard_Boolean)isToAllow);
aCoordsNb -= 2;
}
Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
aCurrentEventManager->MoveTo(atoi(argv[1]),atoi(argv[2]));
if(argc <= 4)
if(aCoordsNb == 2)
{
if(isShiftSelection)
aCurrentEventManager->ShiftSelect();
else
aCurrentEventManager->Select();
}
else if(argc <= 6)
else if(aCoordsNb == 4)
{
if(isShiftSelection)
aCurrentEventManager->ShiftSelect(atoi(argv[1]),atoi(argv[2]),atoi(argv[3]),atoi(argv[4]));
aCurrentEventManager->ShiftSelect (atoi (argv[1]), atoi (argv[2]), atoi (argv[3]), atoi (argv[4]), Standard_False);
else
aCurrentEventManager->Select(atoi(argv[1]),atoi(argv[2]),atoi(argv[3]),atoi(argv[4]));
aCurrentEventManager->Select (atoi (argv[1]), atoi (argv[2]), atoi (argv[3]), atoi (argv[4]), Standard_False);
}
else
{
Standard_Integer anUpper = 0;
TColgp_Array1OfPnt2d aPolyline (1,aCoordsNb / 2);
if(isShiftSelection)
anUpper = (argc-1)/2;
else
anUpper = argc/2;
TColgp_Array1OfPnt2d aPolyline(1,anUpper);
for(Standard_Integer i=1;i<=anUpper;++i)
for(Standard_Integer i=1;i<=aCoordsNb / 2;++i)
aPolyline.SetValue(i,gp_Pnt2d(atoi(argv[2*i-1]),atoi(argv[2*i])));
if(isShiftSelection)
@@ -8626,12 +8640,14 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
"diffimage : diffimage imageFile1 imageFile2 toleranceOfColor(0..1) blackWhite(1|0) borderFilter(1|0) [diffImageFile]",
__FILE__, VDiffImage, group);
theCommands.Add ("vselect",
"vselect x1 y1 [x2 y2 [x3 y3 ... xn yn]] [shift_selection = 0|1]\n"
"vselect x1 y1 [x2 y2 [x3 y3 ... xn yn]] [-allowoverlap 0|1] [shift_selection = 0|1]\n"
"- emulates different types of selection:\n"
"- 1) single click selection\n"
"- 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)\n"
"- 3) selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn)\n"
"- 4) any of these selections with shift button pressed",
"- 4) -allowoverlap determines will partially included objects be selected in rectangular selection"
" (partial inclusion - overlap - is not allowed by default)\n"
"- 5) any of these selections with shift button pressed",
__FILE__, VSelect, group);
theCommands.Add ("vmoveto",
"vmoveto x y"