find a point on a face that is not on an edge

Hi all,

I have a problem with my code that is doing my head in. In order to 'color' certain faces I need to define a point on a face that is not on an edge. Using ShapeAnalysis_Surface.bounds and taking the average of U and V works for a lot of surfaces but not for those with a hole (like a washer or a disk with a hole at its center). Does anybody have an idea hod to do this right, any point that is not on an edge will do.

Thanks,

Jouke

jelle's picture

Jouke,

To test whether a u,v coordinate lies on a trimmed part of the surface, have a look here [1] and grep for "IsPointOnFace" ( post: Mark Blome ).
Hope that helps,

-jelle

[1] http://www.opencascade.org/org/forum/thread_26203/?forum=3

hylkema's picture

thanks Jelle, I'll have a go with that.

Jouke

hylkema's picture

I tried to think of an implementation but the problem is not to test if a point lies on a face it's to devise a strategie to find a point on the face.

Mauro Mariotti's picture

We do it this way, but I would be glad if someone has a better idea:

Take a 2d curve (CurveOnSurface) on a wire of the face.
If it the edge orientation is "reversed", reverse the curve.
Evaluate a 2d point in the middle of it and move it SLIGHTLY to the left of the curve, which is the "in" side (the movement direction is computed by rotating the curve derivative counterclockwise by 90 degrees).

If the movement is too large, you could cross another limiting curve and get out of the face.
If performance is not an issue, you can check it by BRepTopAdaptor_FClass2d or IntTools_FClass2d.

Bye.
Mauro

Mark Blome's picture

I use the following method, which is from OCC class TopOpeBRepTool_ShapeClassifier.cxx (private method):

Standard_Boolean FindAPointInTheFace(const TopoDS_Face& _face, gp_Pnt& APoint, Standard_Real& u, Standard_Real& v)
{
TopoDS_Face face=_face;
face.Orientation(TopAbs_FORWARD);
TopExp_Explorer faceexplorer;
BRepAdaptor_Curve2d c;
gp_Vec2d T;
gp_Pnt2d P;
Standard_Boolean Ok = Standard_False;
Standard_Integer nbiter=0;
Standard_Real myParamOnEdge = 0.5;
do {
nbiter++;
if(myParamOnEdge==0.5) myParamOnEdge = 0.4;
else if(myParamOnEdge==0.4) myParamOnEdge = 0.6;
else if(myParamOnEdge==0.6) myParamOnEdge = 0.3;
else if(myParamOnEdge==0.3) myParamOnEdge = 0.7;
else if(myParamOnEdge==0.7) myParamOnEdge = 0.2;
else if(myParamOnEdge==0.2) myParamOnEdge = 0.8;
else if(myParamOnEdge==0.8) myParamOnEdge = 0.1;
else if(myParamOnEdge==0.1) myParamOnEdge = 0.9;
else { myParamOnEdge*=0.5; }

for (faceexplorer.Init(face,TopAbs_EDGE);
faceexplorer.More();
faceexplorer.Next()) {
TopoDS_Edge Edge = TopoDS::Edge(faceexplorer.Current());
c.Initialize(Edge,face);
Standard_Integer nbinterval = c.NbIntervals(GeomAbs_C1);
c.D1((c.LastParameter() - c.FirstParameter()) * myParamOnEdge + c.FirstParameter(),P,T);

Standard_Real x=T.X();
Standard_Real y=T.Y();
//-- cout<<"Param:"<<(c.IntervalFirst() + c.IntervalLast()) * param<<" U:"< Edge : "< FClassifier.Parameter()) {
ParamInit = FClassifier.Parameter();
APointExist = Standard_True;
}
}
}
}
if(APointExist) {
ParamInit*=0.5;
u = P.X() + ParamInit* T.X();
v = P.Y() + ParamInit* T.Y();
BRepAdaptor_Surface s;
Standard_Boolean computerestriction = Standard_False;
s.Initialize(face,computerestriction);
s.D0(u,v,APoint);
//-- cout<<" u="< ("<Bounds(SUmin,SUmax,SVmin,SVmax);
v=std::min(SVmin,SVmax) + fabs(SVmax-SVmin)/2.0;
u=std::min(SUmin,SUmax) + fabs(SUmax-SUmin)/2.0;
P=surf->Value(u,v);

Not sure how good this is in terms of performance, I use it to identify points inside solids and for that purpose
it seems not to represent a bottleneck. It works reliably for my cases.

Regards,
Mark