# edge ordering for a torus

When I go around the edges of a torus, the order seems to be wrong.

This is the code i use to go around the edges in the parameter space (notice I do use WireExplorer):

#include "occ_header.h"

int main() {

TopExp_Explorer Ex;

TopExp_Explorer Ex2;

TopExp_Explorer Ex3;

BRepTools_WireExplorer Ex4;

TopoDS_Shell Shell;

TopoDS_Face Face;

TopoDS_Wire Wire;

TopoDS_Edge Edge;

Standard_Real First;

Standard_Real Last;

gp_Pnt2d P;

TopoDS_Solid Solid= BRepPrimAPI_MakeTorus(10.,1.);

for (Ex.Init(Solid, TopAbs_SHELL); Ex.More(); Ex.Next())

{

Shell= TopoDS::Shell(Ex.Current());

for (Ex2.Init(Shell, TopAbs_FACE); Ex2.More(); Ex2.Next())

{

Face= TopoDS::Face(Ex2.Current());

for (Ex3.Init(Face, TopAbs_WIRE); Ex3.More(); Ex3.Next())

{

Wire= TopoDS::Wire(Ex3.Current());

for (Ex4.Init(Wire); Ex4.More(); Ex4.Next())

{

Edge= TopoDS::Edge(Ex4.Current());

cout

//const Handle(Geom_Curve)& Curve=BRep_Tool::Curve(Edge,First,Last);

const Handle(Geom2d_Curve)& Curve2d=BRep_Tool::CurveOnSurface(Edge,Face,First,Last);

Curve2d->D0(First,P);

cout cout

Curve2d->D0(Last,P);

cout
cout
}

}

}

}

return 0;

}

and here's the output

for each edge, i compute the (u,v) at beginning and end of underlying curve

Orient is the edge orientation

recall that 0 means FORWARD and 1 means REVERSED

if it says FORWARD, you have to go from First to Last

if it says REVERSED, you have to go from Last to First in order to loop around the torus.

Orient= 1

First= 0

u= 0 v= 6.28319

Last= 6.28319

u= 6.28319 v= 6.28319

Orient= 0

First= 0

u= 6.28319 v= 0

Last= 6.28319

u= 6.28319 v= 6.28319

Orient= 0

First= 0

u= 0 v= 0

Last= 6.28319

u= 6.28319 v= 0

Orient= 1

First= 0

u= 0 v= 0

Last= 6.28319

u= 0 v= 6.28319

So, the loop goes like this:

(6.28,6.28) to (0,6.28) to (6.28,0) which is wrong!

Can somebody take a loop? Either i am doing something wrong or this is a bug.

anybody?

is what i am doing correct to get a discretized representation of the model face's boundary in the (u,v) parameter space? In the example above, i am just looking at the beginning and end of each bounding edge (in real life, i may be taking more samples along each bounding edge).

i have been using this method for all types of faces and it seems to work alright except for a full torus.

Hi Ugo,

First off, you are not doing anything wrong - you are exploring the model correctly. As improvement suggestion:

you can explore wires directly using

TopExp_Explorer anExp (aShape, TopAbs_WIRE) instead of going level-by-level from shells.

Secondly, Open CASCADE does NOT require a wire to be clock-wise, anti-clockwise, tail-to-head, etc oriented. Edges can be in any arbitrary order, of course ensuring that each edge is correctly oriented. Torus, sphere (and probably other elementary shapes) are created such that their edges go in head-to-tail (instead of more logical tail-to-head) order. See in Draw:

pload MODELING

av2d

ptorus p 100 50

fit

explode p f

pcurve p_1

2dfit

whatis . . . . #then click 4 times on each pcurve to get their names

Same works for 'psphere 50'.

BRepTools_WireExplore is aimed to facilitate the edge ordering tail-to-head during exploration. If it fails in this case, it sounds like a bug.

Shape Healing's ShapeAnalysis_Wire has stronger capabilities to check and orient wire's edges - working for 2D or 3D modes, closed and open wires, etc. The usage model would be either:

- create ShapeFix_Wire feeding a wire and a face

- call ::FixReOrder()

- retrieve ShapeBuild_WireData using ::WireData()

- explore edges

or

- create ShapeExtend_WireData from a wire

- create ShapeAnalysis_Wire feeding a WireData and a face

- Call CheckConnected() specifying a 2D mode flag, retrieve an object ShapeAnalysis_WireOrder

- request index of each edge in original WireData object using ShapeAnalysis_WireOrder::Ordered().

Hope this helps.

Roman

thank you Roman for your detailed answer.

Does this thread constitute a proper "bug report" or is there a more formal way of doing so?

Hopefully OCC team could pay attention to this trying to reproduce/refute?

Hi Ugo,

I tried to reproduce your case (using Draw commands ptorus, pcurve,2dcvalue, dval), but didn't get any wrong result.

See the attached picture presenting pcurves of torus. By green color presented coordinates,

by yellow - names of the corresponding pcurves.

More over your debugging output is correct too!

Just conclusion seems wrong. Below I am going along your output.

1. p_1_1: (0, 6.28) --> (6.28,6.28); OR = 1

2. p_1_2: (6.28, 0) --> (6.28, 6.28); OR = 0

3. p_1_3: (0, 0) --> (6.28, 0); OR = 0

4. p_1_4: (0, 0) --> (0, 6.28); OR = 1

Edges oriented in next order: (p_1_3, p_1_2, p_1_1, p_1_4) ==> counterclockwise.

It looks Ok(see the attached picture). You may check it once again.

Regards

Sergey

Sorry, the analysis is still not finished.

It sent by mistake.

Regards

sorry, I didn't catch that you are using WireExplorer.

I checked it once again. So, we didn't consider it as a bug of algorithm.

Rather it is a documentation bug. From current description it is not very clear which constructor should be used. We will take care to fix it.

If a wire to be analyzed has underlying face you should use the appropriate constructor with two parameters:

BRepTools_WireExplorer exp(wire, face).

In this case you will get expected by you order.

Regards

Sergey

Sergey:

Thanks for taking a look. I did as you suggested but i get the exact same result.

it goes from (6.28,6.28) to (0,6.28) for the 1st Edge in the Wire

and then from (6.28,0) to (6.28,6.28) for the 2nd Edge in the Wire, same as before.

Do you actually get the right behavior when you do it?

I now use the proper constructor BRepTools_WireExplorer Ex4(Wire,Face) but am I missing something else?

Hi Ugo,

I actually got the right order - see the attached pictures.

Besides you may easy reproduce it in Draw:

ptorus p 10 1

explo p F

explo p_1 ## p_1 is a face

whatis p_1_1 ## p_1_1 is a Wire

wexplo p_1_1 p_1

directory ## => p_1_1 WEDGE_1 WEDGE_2 WEDGE_3 WEDGE_4 pi minf axes2d pinf p axes grid p_1

av2d

pcurve p1 WEDGE_1 p_1

2dfit

pcurve p2 WEDGE_2 p_1 ## the first picture present this point

2dfit

pcurve p3 WEDGE_3 p_1 ## the second picture presents this point

2dfit

pcurve p4 WEDGE_4 p_1

2dfit

So, probably you should check your code once again.

Regards

ok, Sergey, you're absolutely right, it does give the correct ordering when you construct the wire explorer with the pair (Wire,Face). Thanks for checking this!