TopLoc_Location::IsEqual and BRep_CurveOnSurface::IsCurveOnSurface seem to not match with each other


I'm trying to use BRep_Tool::CurveOnSurface to retrieve a Handle(Geom2d_Curve).

I'm working with a step model i imported using STEPControl_Reader.

The model is correctly displayed.

I also checked the TopoDS_Edge and the TopoDS_Face i'm passing to BRep_Tool::CurveOnSurface with BRepCheck_Analyzer and it returns IsValid() == true for both.

When debugging i can see that the BRep_TEdge contains four BRep_CurveRepresentation, a BRep_Curve3D, two BRep_CurveOnSurface and a BRep_CurveOn2Surfaces.

BRep_Tool::CurveOnSurface iterates through all BRep_CurveRepresentation of the TopoDS_Edge and calls BRep_CurveOnSurface::IsCurveOnSurface for each BRep_CurveRepresentation.

BRep_CurveOnSurface::IsCurveOnSurface compares the surfaces by pointers and the TopLoc_Locations using this Equal implementation which, and this is the reason why in this case BRep_Tool::CurveOnSurface returns a null Handle, returns false if one returns true for IsIdentity().

I honestly don't know what's the reasoning behind this implementation.

I was thinking that maybe transformations are not supposed to be empty (because that's what TopLoc_Location::IsIdentity() checks) but STEPControl_Reader doesn't report any errors and BRepCheck_Analyzer says everything is valid.

I might be able to work around this by looping through all curves myself and replacing empty location with actual identity transformations but it feels wrong.

What am i missing?

I'm unsure what's the better place; i also posted this in mantis


Mikhail Sazonov's picture


If you are not sure whether this is a bug of OCCT or your misuse of OCCT then the right place is here on the forum, not the bugtracker.

In order to know what is wrong it is not enough just words. You need to present your shape and exact piece of code you wrote to reproduce the wrong behavior.

Lion G.'s picture

It's a inconsistency because STEPControl_Reader doesn't report an error, BRepCheck_Analyzer thinks all is ok and yet BRep_Tool::CurveOnSurface refuses to give me an instance because of how TopLoc_Location::IsEqual is implemented. Either STEPControl_Reader is allowed to deliver what from a brep perspective or just the BRep_Tool::CurveOnSurface is inconsistent, or BRep_Tool::CurveOnSurface doesn't handle all cases, or TopLoc_Location::IsEqual doesn't handle all cases.

I can't provide test data atm but will try to create some which i'm allowed to share. But since i provided links to all the relevant implementations, i guess the most important question is whether TopLoc_Location::IsEqual reflects what the design intents. If it does it would imply that step import alone is not enough to meet all brep requirements because empty transformations are not allowed and render shapes incomplete.

I exported the imported step shape to brep and read it in again and the error disappeared. This hints that the step importer is allowed to result in something which is from a brep point of view insufficient and needs additional fixes. But BRepCheck_Analyzer should point them out; the docs say that it checks "BRepCheck_InvalidCurveOnSurface" for edges.

Kirill Gavrilov's picture

i guess the most important question is whether TopLoc_Location::IsEqual reflects what the design intents

TopLoc_Location::IsEqual() does what it is supposed to do.

Lion G.'s picture

I guess i lack some fundamental understanding about the semantic difference between a empty location (= IsIdentity()) and a explicit identity transformation (unity matrix, no translation, scale=1).

Is it a fundamental principle in occt? What's the rationale behind it? I'd have expected IsCurveOnSurface to do something like

Standard_Boolean  BRep_CurveOnSurface::IsCurveOnSurface(const Handle(Geom_Surface)& S, const TopLoc_Location& L)const {
  return (S == mySurface) && (L == myLocation || L.IsIdentity() && myLocation.IsIdentity());

Im not sure about the implications yet and haven't yet found the my code which causes this divergence in locations but it boils down to this i think.

Kirill Gavrilov's picture

IsIdentity() just means transformation has no geometrical effect - e.g final geometrical transformation matrix gp_Trsf is identity one. But TopLoc_Location is NOT a geometrical information, it is a topological information. TopLoc_Location are compared as pointers, not by value, so that two TopLoc_Location might define exactly the same geometrical transformation (identity or not) but might not be equal.

The following post might be helpful for understanding OCCT concept and difference between TopLoc_Location and gp_Trsf.