# Is mapping from TopoDS_Face to space not bijective?

Hello,

I am doing two-dimensional computations on a TopoDS_Face. When I want to have the three-dimensional representations of my two-dimensional data, I use:

gp_Pnt spacePoint;

BRep_Tool::Surface(face)->D0(position.X(), position.Y(), spacePoint);

Now I was really surprised to find two two-dimensional positions on my surface that differ a lot (more than 6.0 length units), but are identical in the space (distance less than 1.0e-8). I thought that there might be a numerical instability, but at least with a tolerance of 1.0e-2 my BRepTopAdaptor_FClass2d claims that they are both TopAbs_ON the face.

Isn't the mapping from a Geom_Surface made out of a TopoDS_Face to the three-dimensional space bijective (one-to-one)???

Any hint is greatly appreciated!

Greetings,

Benjamin

I have found out more about this topic: no, in general the mapping from a Geom_Surface made out of a TopoDS_Face to the three-dimensional space is not bijective.

Please see the attached picture. You see a shell here (the yellow area) and a face (with green boundary edges) that is part of the shell. One edge of the face (visualized with red color shining through) is exciting. The edge and its p-curve are not closed. The first point of the edge (visualized with white color on the left) has the coordinates (0 / 1.5708), the last point (visualized with blue color and on the right) has the coordinates (1.5708 / 1.5708) with respect to the Geom_Surface made out of the face.

I have a position (6.28319 / 1.5708) on the surface now that was computed by some algorithm before. This position obviously has a great distance from the first point of the edge (exactly 6.28319 length units). But when I compute their three-dimensional equivalents, the distance is zero. Also both points, (0 / 1.5708) and (6.28319 / 1.5708), are TopAbs_ON with respect to the face.

It is striking, that the coordinates look like 2 * M_PI and M_PI / 2. Could it be that the p-curve of the edge is a segment of a circle and therefore is somehow periodic?

For checking now whether two two-dimensional points on the Geom_Surface are identical, it does not suffice to compute their distance, because the mapping to the space is not one-to-one. Instead I have to compute the three-dimensional representations with BRep_Tool::Surface(face)->D0(position.X(), position.Y(), spacePoint) and then compute the distance in the space. This works, but might be costly from a performance point of view.

Still I would like to ask you: is this an OCC bug? Or is this usual behaviour? Is there a cheaper way to find out whether two different two-dimensional coordinates represent the same space point than using D0 of the Geom_Surface?

Thank you.

Benjamin,

surfaces may be periodic (cylinders, surfaces of revolution, ...) or just closed (e.g. a NURBS surface with the last column of control points coincident with the first).

They also may have a degenerate side (e.g. a "triangular" surface of revolution built from a curve with an end on the rotation axis), where all the UV's on a side of the domain map on the same 3d point.

In all these cases the UV-3d mapping is not bijective.

Mauro

Thanks for the answer. Can I very easily and cheaply recognize those cases in my algorithms? Then my distance check in the 3d space was only necessary in such cases and I could use the cheap 2d distance measurement in the other cases. Or is it best to always measure distance in the 3d space?

In Geom_Surface you have methods IsUPeriodic/IsVPeriodic and IsUClosed/IsVClosed.

For "triangular" surfaces I don't know; so, if you can encounter them in your application, I am afraid that you need either to write some code to recognize them or alwasy measure distances in 3d space.

Great! Doing the computation in space only when either U or V are periodic really speeds up the check. I have added an assert to ensure that the results are the same. With this I am confident to find out situations where this check does not suffice, if such situations exist at all.

Thank you again.

## Hi,

Hi,

I still have problems with periodic surfaces. When I create a Geom2d_BSplineCurve interpolating two points on a surface that are taken from different periods and then create a 3d curve with Adaptor3d_CurveOnSurface, the curve leaves the face and forms something like a complementary circle to the actually expected curve. In the attached picture the green/red curve should stay on the surface. But because of the described problem it changes direction, leaves the surface and approaches the target point from the other side.

If I could force all 2d points onto the same period of the Geom_Surface, this should be solved. Is there a way to do that or at least recognize such a situation? To be clearer: in my example the point (6.28319, 134.072) and the point (0.0, 134.072) have the same 3d coordinates. I can create a curve from (0.0, 134.072) to (1.0, 134.072), but creating a curve from (6.28319, 134.072) to (1.0, 134.072) leads to the error you see in Curve.png.

Sometimes computing the 3d representation of a 2d point and projecting it onto the Geom_Surface again helps, but not always. :-(

Any help is greatly appreciated!

Benjamin

## I guess I have found a

I guess I have found a solution: ShapeAnalysis::AdjustByPeriod can be used to get rid of the period. I use it like this:

double newX = point.X() + ShapeAnalysis::AdjustByPeriod(point.X(), 0.0, surface->UPeriod());

and the same for Y. This seems to move all points into the same period and then the curve interpolation works fine!

## Dear Mauro,

Dear Mauro,

I have a bijective similar issue related on this post : http://www.opencascade.com/content/geomlibtoolparameters-failure

In my case it is not a periodic surface or surface of revolution, it is a quarter of disk-like surface that gives the same parameter for 2 distincts points on the real space.

Any idea ?

Thanks,

Sâm