Edge on the Boundary of a face

Good morning !
In OCC, does it exist a function to know whether a TopoDS_Edge is on a Face, and is on its boundary ?
Thank you very much !

George Feng's picture

As far as I know there is no such function. But you can implement it by

yourself.
1. Get the boundary of the face.
There is a function called BRepTools::OutWire(), but sometimes it does not work.
aOuterWire = BRepTools::OuterWire(aFace);
2. Compare the edge with edges on the boundary.
If the edge share the same TEdge with an edge on the boundary, you can just

compare the TEdges and locations of the two edges.
Edge1.TShape() == Edge2.TShape() && Loc1 == Loc2

Timo Roth's picture

For shape (here: edge) comparison, you can also use the following functions of TopoDS_Shape:

IsPartner (const TopoDS_Shape &other) const
IsSame (const TopoDS_Shape &other) const
IsEqual (const TopoDS_Shape &other) const

See corresponding Doxygen documentation for details.

Bayard's picture

Ok !

Thank you for this answer. I tried this with a square face and an edge corresponding of one of the "sub-edges" of my face, but they returned false.

Using TopExp::FirstVertex / LastVertex, I discovered that :
- the extremities (equal in my CAO) had not exactly the same coordinates (an error about 1e-17) Is there a way to define the tolerance ?
- they were reversed (first vertex of one corresponding to last vertex of the other). Is there any way to fix that ?
Thank you !

Timo Roth's picture

The TopoDS_Shape functions are only helpful if two edges share the same TEdge object as George Feng explained. I don't know when exactly this is the case. Probably, e.g. when you sew two faces they share the same common edge. Or if you copy an edge or transform it.

In your case, you probably have to compare geometrical properties, e.g. the position of first and last vertex, the type of geometry,...

Does somebody know if there is a standard way to do such comparisons?

Bayard's picture

I think the error is caused by approximation of the initial CAO (STEP created by Rhino).

After trying using some different classes (IntToolsEdgeEdge, BRepExtrema_ExtCC, GeomAPI_ExtremaCurveCurve), without any success), I thought that the only way was to compare two Edges A et B was

- to performe bool operations : C = CUT( A, COMMON(A,B) )
- to test C.IsNull, or C is a compound of vertex or very small edges.

Do you think it will work ? Is there a less complex operation possible ?

George Feng's picture

I have seen a part of codes in OCC, where the first and last parametersand, and points at u=0.3*C1f+0.7*C1l of two edges are compared.
//=======================================================================
//function : SameCurve
//purpose :
//=======================================================================
Standard_Boolean SameCurve(const Handle_Adaptor2d_HCurve2d& C1,const Handle_Adaptor2d_HCurve2d& C2)
{
Standard_Real C1f = C1->FirstParameter();
Standard_Real C2f = C2->FirstParameter();
if(C1f!=C2f) return(Standard_False);
Standard_Real C1l = C1->LastParameter();
Standard_Real C2l = C2->LastParameter();
if(C1l!=C2l) return(Standard_False);
Standard_Real u=0.3*C1f+0.7*C1l;
gp_Pnt2d P1 = C1->Value(u);
gp_Pnt2d P2 = C2->Value(u);
if(P1.X()!=P2.X()) return(Standard_False);
if(P1.Y()!=P2.Y()) return(Standard_False);
return(Standard_True);
}
You can also compare the types of the two edges as suggested by Timo.

The above method is only an approximate justification whether two edges are the same.

George Feng's picture

I also test three points in my program. If someone get some better methods to justify whether two edges are the same, please post here and thanks a lot.

int OccUtility::IsCurveEqual(TopoDS_Edge &aEdge_1, TopoDS_Edge &aEdge_2)
{
int nResult = 0;
int IsSatisfied_1 = 1, IsSatisfied_2 = 1;

Handle(Geom_Curve) theCurve_1,theCurve_2;
TopLoc_Location L_1, L_2;
Standard_Real First_1, Last_1;
Standard_Real First_2, Last_2;
// L_1可能为NULL,所以曲线的位置不能用此变量判断
// 当L_1与L_2都为空时,尽管两个变量相等,但是曲线在空间的位置并不相同
theCurve_1 = BRep_Tool::Curve(aEdge_1, L_1, First_1, Last_1);
theCurve_2 = BRep_Tool::Curve(aEdge_2, L_2, First_2, Last_2);

IsSatisfied_1 = fabs(First_1-First_2)