Point on Face: TopAbs_State Is Inconsistent


I am doing computations on a TopoDS_Shell by stepping over its TopoDS_Faces. Right now my algorithm has problems since several methods give inconsistent position informations. Can anyone tell me whether this is "normal" for numerical reasons or whether I have understood something wrong or have an error in reasoning.

The situtation is like that: two TopoDS_Faces (let's call them "old face" and "new face") of my TopoDS_Shell are adjacent and therefore share a common TopoDS_Edge. On the old face I have computed a gp_Pnt2d that is very close to the common TopoDS_Edge. I want to compute a new gp_Pnt2d representation on the new edge.

I use BRepTopAdaptor_FClass2d with precision Precision::Confusion() to compute whether my gp_Pnt2d lies in the face (TopAbs_IN), on the face boundary (TopAbs_ON) or out of the face (TopAbs_OUT). Even though my gp_Pnt2d on the old face is very close to the boundary edge, the state may be TopAbs_IN instead of TopAbs_ON. I have found out, that I can "fix" that by projecting the point onto the boundary curve.


gp_Pnt2d position; // Position on old face

double first, last;
Handle(Geom2d_Curve) edgeCurve = BRep_Tool::CurveOnSurface(edge, oldFace, first, last);
Geom2dAPI_ProjectPointOnCurve projector(position, edgeCurve, first, last);

gp_Pnt2d projectedPosition = projector.NearestPoint();


This works and my BRepTopAdaptor_FClass2d instance will always return TopAbs_ON for the projected position.

Now I compute the representation on the new face by computing a 3D representation of the point on the old face and then computing the 2D representation on the new face.


gp_Pnt spacePoint;
BRep_Tool::Surface(oldFace)->D0(projectedPosition.X(), projectedPosition.Y(), spacePoint);

gp_Pnt2d positionOnNewFace = ShapeAnalysis_Surface(BRep_Tool::Surface(newFace)).ValueOfUV(spacePoint, Precision::Confusion());


Unfortunately when I compute the TopAbs_State of positionOnNewFace now with respect to the new face, it is not TopAbs_ON, but sometimes TopAbs_OUT. This confuses my algorithm, since I have just computed a new representation of the same position which was on the common edge of both faces.

What surprises me even more: if I try to do the projection again, but with the same edge (the boundary edge of the old face that was closest to the old position), the projected position is still TopAbs_OUT!!! When I compute the distance of the space point (I use BRepBuilderAPI_MakeVertex to create a vertex of the spacePoint) from above to the new face with BRepExtrema_DistShapeShape, then the distance is 5.7e-14. This seems inconsistent to me.

Do I use some inaccurate methods for my computations? Would the results be consistent, if I used better computation methods? Can I expect consistency when I set the precision of BRepTopAdaptor_FClass2d to Precision::Confusion() or can such computations for numerical reasons be not precise enough? Am I right that a point on a common edge of two faces should be TopAbs_ON with respect to both faces?

Thank you very much for any answer!


Benjamin Bihler's picture

Here is an intermediate answer to my own question: if I lower the precision of BRepTopAdaptor_FClass2d to 1.0e-2, then the computations become "consistent".

Different from what I have written before, I have also found examples where I have projected a point on a face onto an edge from that face and still the state was not TopAbs_ON, when the precision of BRepTopAdaptor_FClass2d was Precision::Confusion().

It seems to me as if such computations suffer from numerical instabilities and I have to reduce the precision, if I don't want my algorithms to get confused (which is okay for me in this case).

Are there any comments or does this also correspond to your experiences?

Thank you.