display the point on an edge from a near one

Hello!
I have an edge and when I click near this, I want a point on the edge to be displayed (the closer point to the one I click). Converting mouse coordinates is solved. I've been using this:

//Convert the edge to a curve
curve = BRep_Tool::Curve(edge, location, pFirst, pLast);

curve->Value(/*Here I put one of the mouse converted coordinates (gp_Pnt), but in fact I don't know what to put in here; the result is almost exact but fails*/);

Any idea?
Thanks in advance.

Sparse's picture

Hello,
I can not answer your question but in you poster you said you had solved the Converting mouse coordinates problem. I wonder you could help me on this. When i convert the mouse position in the CView::MouseMove(...),using the myView->Convert(...) function and just get the wrong coordinate in the 3d space. The coordinate seems to be in the position of the screen, not just in the shape's face. Can you help me out?
Thank you for giving me any clue!
Sparse

José Manuel Domínguez Ramos's picture

Hello,
Take a look at this:
http://www.opencascade.org/org/forum/thread_3185/
That's what I used. Hope this helps.
Sincerely,
Jose Manuel

P Dolbey's picture

As far as I can tell, there seems to be 3 interpretations for the 2d->3d transform issue: -

1. The point is transformed onto a specified working plane (I use the view privilege plane) - this plane does need to be parallel to the viewport. My implemenation for this is given here http://www.opencascade.org/org/forum/thread_2785/
2. The point is transformed on to a plane parallel to the viewport passing through a point (specified depth point or model centre). I think this is at the heart of Stephane's algorithm.
3. The point is tranformed onto the surface of an existing object - I haven't found a specific implementation on this forum but it should theoretically be possible using GeomAPI_ProjectPointOnSurface and some of the code from the 1. and 2. algorithms. However this API call does have reported performance issues. From your post its seems you're after this option. Is that correct?

Pete

P Dolbey's picture

Oh for an edit option on this forum - option 1 should say "..this plane does NOT need to be parallel..."

Pete

Sparse's picture

hello, everyone here
First of all, thanks to Pete for giving me the detailed methods( and links too), I have solved the Converting problem, and I think it is corrrect sometime. It's a strange way to say so, I know. Now I am in the Step3. I want to get the point on the surface with the left click. I use the following codes:

// Make a plane perpendicular to the projection orientation.
Standard_Real x_ori, y_ori, z_ori;
aView->Proj (x_ori, y_ori, z_ori);
gp_Dir proj_orientation (x_ori, y_ori, z_ori);
gp_Pln view_plane = gp_Pln (gp_Pnt (0, 0, 0), proj_orientation);
// Convert the 2d point into a 3d point.
Standard_Real xp, yp, zp;
aView->Convert (x, y, xp, yp, zp);
gp_Pnt converted_pnt (xp, yp, zp);
// Project the converted point in the plane.
gp_Pnt2d projected_pnt = ProjLib::Project (view_plane, converted_pnt);
// Get a 3d point from this 2d point.
gp_Pnt ResultPoint=ElSLib::Value (projected_pnt.X (), projected_pnt.Y (), view_plane);
GC_MakeLine line(ResultPoint,proj_orientation);
gp_Pnt a3dPnt;
for(exp.Init(aShape,TopAbs_FACE);exp.More();exp.Next())
{
TopoDS_Face aFace=TopoDS::Face(exp.Current());
BRepAdaptor_Surface aSurface(aFace);
const GeomAdaptor_Surface &geomAdapSurf=aSurface.Surface();
const Handle_Geom_Surface &geomSurf=geomAdapSurf.Surface();
GeomAPI_IntCS intCS;
intCS.Perform(line.Value(),geomSurf);
if(intCS.IsDone())
{
if(intCS.NbPoints()!=0)
a3dPnt=gp_Pnt(intCS.Point(1).XYZ());
}
}
return a3dPnt;

The aShape is a Cube, and I want to click on a face and to retrieve the point on the face. I use the BRepPrimAPI_MakeSphere in the LButtonDown to draw a small red sphere to indicate the point, and find out that all the points I clicked are in the top face(not just in the bounds of the top face but in the infinite top face), wherever i clicked. It seems that the iterator doesnot move down to every single face in the cube. Can anyone know what's wrong?

Best regards
Sparse

Rob Bachrach's picture

You might want to look at BRepIntCurveSurface_Inter. This computes the intersection of a curve (your line) with a face, rather than an infinite surface. This should take into account the limits of the face.

Sparse's picture

Hello, Rob, I tried your suggestion, and nothing changes. The red spheres are all in the top surface, just like the GeomAPI_IntCS.
I think in this situation, there is something wrong about the iterator, if the iterator could move down or up cleverly to select the most right surface, the problem will be solved.

P Dolbey's picture

The API shows an additional "Parameter" function on GeomAPI_IntCS - you might need to add additional test to see if the retured U, V coords on the surface are in the correct min, max UV ranges for the surface, instead of exiting your loop just on an IsDone.

Parameters(me; Index: Integer from Standard;
U,V,W : out Parameter from Quantity)
---Purpose: Returns parameter W on the curve
-- and (parameters U,V) on the surface of the computed intersection point
-- of index Index in case of cross intersection.
-- Exceptions
-- StdFail_NotDone if intersection algorithm fails or is not initialized.
-- Standard_OutOfRange if Index is not in the range [ 1,NbPoints ], where
-- NbPoints is the number of computed intersection points.

Sparse's picture

hello,
I used the Parameters(....) of the GeomAPI_IntCS and finally solved the problem that the spheres out of the range of the surface. Thanks to Pete.
And now another question about this selecting arises. I can display my small red spheres in the faces of the cube, but not always the correct one. When the mouse clicks in one position where the projecting line intersects with more than one face, the red sphere would place in the behind face but not the closer one in front.
Do I should check some more conditions? And What are they?
Regards!
Sparse

CloneX's picture

Try projecting the mouse click point onto the curve using GeomAPI_ProjectPointOnCurve. The function NearestPoint() should give you what you need.

Hope that helps,

Chris

P Dolbey's picture

Chris,

I think its "Sparse" who has the problem now - Jose Manuel seems pretty well sorted.

Pete