Tue, 06/24/2014 - 18:21
Forums:
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
Tue, 06/24/2014 - 18:52
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
Tue, 06/24/2014 - 19:34
thanks Jelle, I'll have a go with that.
Jouke
Tue, 06/24/2014 - 20:57
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.
Tue, 06/24/2014 - 21:08
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
Wed, 06/25/2014 - 01:07
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