Selection rectangle problem

I want to select edges when the rectangle we draw intersects the edges. Currently open cascade supports selecting edges only when the rectangle we draw included the edges totally.
For this I came up with a method by getting all the points to a 2D plane. First I get the mouse up and down coordinates to a 2D plane.
Then I get all the edges in the model and check at least one point of each curve is inside the rectangle in that 2D plane.
This is not the best approach. But as I couldn't find another way to achieve this I came up with this.

//Creating a 2D plane
// get the eye and the target points
V3d_Coordinate xEye, yEye, zEye, xAt, yAt, zAt;

aView->Eye(xEye, yEye, zEye);
aView->At(xAt, yAt, zAt);
gp_Pnt EyePoint(xEye, yEye, zEye);
gp_Pnt AtPoint(xAt, yAt, zAt);

// create the direction
gp_Vec EyeVector(EyePoint, AtPoint);
gp_Dir EyeDir(EyeVector);

// make a plane perpendicular to this direction
gp_Pln thePlaneOfTheView = gp_Pln(AtPoint, EyeDir);

//end creating the plane

//mouse button down even
static Standard_Integer theButtonDownX=0;
static Standard_Integer theButtonDownY=0;

if (TheState == -1)
{

theButtonDownX=x;
theButtonDownY=y;

//vk

//Convert the 2d point into 3d
Standard_Real theX, theY, theZ;
aView->Convert(theButtonDownX, theButtonDownY, theX, theY, theZ);
gp_Pnt theConvertedPoint(theX, theY, theZ);

// project the converted point to the plane
theConvertedPointOnPlaneButtonDown = ProjLib::Project(thePlaneOfTheView, theConvertedPoint);
//vk

}
//end mouse button down

//mouse buttonup
if (TheState == 1)
{
//vk
//Convert the 2d point into 3d
Standard_Real theX, theY, theZ;
aView->Convert(x, y, theX, theY, theZ);
gp_Pnt theConvertedPoint(theX, theY, theZ);

// project the converted point to the plane
theConvertedPointOnPlaneButtonUp = ProjLib::Project(thePlaneOfTheView, theConvertedPoint);
//vk

Standard_Real minXPoint;
Standard_Real minYPoint;
Standard_Real maxXPoint;
Standard_Real maxYPoint;

//initialize the minX, minY, maxX, maxY in the rectangle we draw
minXPoint = theConvertedPointOnPlaneButtonDown.X();
maxXPoint = theConvertedPointOnPlaneButtonUp.X();

minYPoint = theConvertedPointOnPlaneButtonUp.Y();
maxYPoint = theConvertedPointOnPlaneButtonDown.Y();

//As the X Y axis is going to change according to how we rotate the model, we need recalculate our minX, minY, maxX,maxY
if(theConvertedPointOnPlaneButtonDown.X()>theConvertedPointOnPlaneButtonUp.X())
{
minXPoint = theConvertedPointOnPlaneButtonUp.X();
maxXPoint = theConvertedPointOnPlaneButtonDown.X();
}

if(theConvertedPointOnPlaneButtonDown.Y()
{
minYPoint = theConvertedPointOnPlaneButtonDown.Y();
maxYPoint = theConvertedPointOnPlaneButtonUp.Y();
}

//select all edges of all displayed objects and define number of points you needed. Here I have given the number same as the curve's
//length
AIS_ListOfInteractive aDisplayedList;
Standard_Boolean aNeutralPointOnly = Standard_True;
myAISContext->DisplayedObjects (aDisplayedList, aNeutralPointOnly);
AIS_ListIteratorOfListOfInteractive anIter (aDisplayedList);
for (; anIter.More(); anIter.Next())
{
Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (anIter.Value());
if (!aShape.IsNull())
{
TopExp_Explorer anExp (aShape->Shape(), TopAbs_EDGE);
for (; anExp.More(); anExp.Next())
{
TopoDS_Edge edge = TopoDS::Edge(anExp.Current()/*myAISContext->SelectedShape()*/);
Standard_Real c_start;
Standard_Real c_end;
Handle(Geom_Curve) c = BRep_Tool::Curve(edge, c_start, c_end);

gp_Pnt p;

GProp_GProps system;
BRepGProp::LinearProperties(edge, system);
Standard_Real length = system.Mass();
Standard_Real length1 = GCPnts_AbscissaPoint::Length (GeomAdaptor_Curve (c));
Standard_Real stepWidth = 1;
int n = length / stepWidth; //number of points

BRepAdaptor_Curve gac(edge);
GCPnts_UniformAbscissa algo(gac, n); // create n new points
if (algo.IsDone())
{
const Standard_Real Xp=0;
const Standard_Real Yp=0;
// show the new points
for (int i = 1; i {
c->D0(algo.Parameter(i), p);

// project the converted point to the plane
gp_Pnt2d theConvertedPointOnPlanePoints = ProjLib::Project(thePlaneOfTheView, p);

//check whether atleast one point on a curve is in the rectangle we draw. If so check the next edge
if(((minXPoint
theConvertedPointOnPlanePoints.X() ))&&((minYPoint
{

myAISContext->AddOrRemoveSelected (anExp.Current(), Standard_True);
break;
}

}
}
}
}
}

}

myAISContext->UpdateCurrentViewer();

//end mouse button up

vidura's picture

I want to select edges when the rectangle we draw intersects the edges. Currently open cascade supports selecting edges only when the rectangle we draw included the edges totally.
For this I came up with a method by getting all the points to a 2D plane. First I get the mouse up and down coordinates to a 2D plane.
Then I get all the edges in the model and check at least one point of each curve is inside the rectangle in that 2D plane.
This is not the best approach. But as I couldn't find another way to achieve this I came up with this.

//Creating a 2D plane
// get the eye and the target points
V3d_Coordinate xEye, yEye, zEye, xAt, yAt, zAt;

aView->Eye(xEye, yEye, zEye);
aView->At(xAt, yAt, zAt);
gp_Pnt EyePoint(xEye, yEye, zEye);
gp_Pnt AtPoint(xAt, yAt, zAt);

// create the direction
gp_Vec EyeVector(EyePoint, AtPoint);
gp_Dir EyeDir(EyeVector);

// make a plane perpendicular to this direction
gp_Pln thePlaneOfTheView = gp_Pln(AtPoint, EyeDir);

//end creating the plane

//mouse button down even
static Standard_Integer theButtonDownX=0;
static Standard_Integer theButtonDownY=0;

if (TheState == -1)
{

theButtonDownX=x;
theButtonDownY=y;

//vk

//Convert the 2d point into 3d
Standard_Real theX, theY, theZ;
aView->Convert(theButtonDownX, theButtonDownY, theX, theY, theZ);
gp_Pnt theConvertedPoint(theX, theY, theZ);

// project the converted point to the plane
theConvertedPointOnPlaneButtonDown = ProjLib::Project(thePlaneOfTheView, theConvertedPoint);
//vk

}
//end mouse button down

//mouse buttonup
if (TheState == 1)
{
//vk
//Convert the 2d point into 3d
Standard_Real theX, theY, theZ;
aView->Convert(x, y, theX, theY, theZ);
gp_Pnt theConvertedPoint(theX, theY, theZ);

// project the converted point to the plane
theConvertedPointOnPlaneButtonUp = ProjLib::Project(thePlaneOfTheView, theConvertedPoint);
//vk

Standard_Real minXPoint;
Standard_Real minYPoint;
Standard_Real maxXPoint;
Standard_Real maxYPoint;

//initialize the minX, minY, maxX, maxY in the rectangle we draw
minXPoint = theConvertedPointOnPlaneButtonDown.X();
maxXPoint = theConvertedPointOnPlaneButtonUp.X();

minYPoint = theConvertedPointOnPlaneButtonUp.Y();
maxYPoint = theConvertedPointOnPlaneButtonDown.Y();

//As the X Y axis is going to change according to how we rotate the model, we need recalculate our minX, minY, maxX, maxY
if(theConvertedPointOnPlaneButtonDown.X()>theConvertedPointOnPlaneButtonUp.X())
{
minXPoint = theConvertedPointOnPlaneButtonUp.X();
maxXPoint = theConvertedPointOnPlaneButtonDown.X();
}

if(theConvertedPointOnPlaneButtonDown.Y()DisplayedObjects (aDisplayedList, aNeutralPointOnly);
AIS_ListIteratorOfListOfInteractive anIter (aDisplayedList);
for (; anIter.More(); anIter.Next())
{
Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (anIter.Value());
if (!aShape.IsNull())
{
TopExp_Explorer anExp (aShape->Shape(), TopAbs_EDGE);
for (; anExp.More(); anExp.Next())
{
TopoDS_Edge edge = TopoDS::Edge(anExp.Current()/*myAISContext->SelectedShape()*/);
Standard_Real c_start;
Standard_Real c_end;
Handle(Geom_Curve) c = BRep_Tool::Curve(edge, c_start, c_end);

gp_Pnt p;

GProp_GProps system;
BRepGProp::LinearProperties(edge, system);
Standard_Real length = system.Mass();
Standard_Real length1 = GCPnts_AbscissaPoint::Length (GeomAdaptor_Curve (c));
Standard_Real stepWidth = 1;
int n = length / stepWidth; //number of points

BRepAdaptor_Curve gac(edge);
GCPnts_UniformAbscissa algo(gac, n); // create n new points
if (algo.IsDone())
{
const Standard_Real Xp=0;
const Standard_Real Yp=0;
// show the new points
for (int i = 1; i <= algo.NbPoints(); i++)
{
c->D0(algo.Parameter(i), p);

// project the converted point to the plane
gp_Pnt2d theConvertedPointOnPlanePoints = ProjLib::Project(thePlaneOfTheView, p/*theConvertedPoint*/);

//check whether atleast one point on a curve is in the rectangle we draw. If so check the next edge
if(((minXPoint theConvertedPointOnPlanePoints.X() ))&&((minYPointAddOrRemoveSelected (anExp.Current(), Standard_True);
break;
}

}
}
}
}
}

}

myAISContext->UpdateCurrentViewer();

//end mouse button up

vidura's picture

Sorry I couldnt mention the problem with the above method. For some rotations of the model when we select a larger rectangle even without intersecting edges it is still selected the edges. Other than that it works fine.
Can somebody please check with the code and tell what am I doing wrong.
Thank you very much in advance.