Buildung surface from 2 wires fails..

Hello,
can someone please confirm a bug - when building a face with 2 wires.

Here my base:

Build 2 polylines:
First polyline with the following points:
P1(+15, +5,0)
P2(+15, -5,0)
P3(+ 5, -5,0)
P4(+ 5,-15,0)
P5(- 5,-15,0)
P6(- 5,- 5,0)
P7(-15,- 5,0)
P8(-15,+ 5,0)
P9(+15,+ 5,0)

Second polyline with the following points:
P1(+13, +3,0)
P2(+13, -3,0)
P3(+ 3, -3,0)
P4(+ 3,-13,0)
P5(- 3,-13,0)
P6(- 3,- 3,0)
P7(-13,- 3,0)
P8(-13,+ 3,0)
P9(+13,+ 3,0)

Then make use of Approx_Curve3d to handle the resulting wires from the polygones as curves. Use
GeomFill_BSplineCurves to build a surface. The result is not correct and looks like this:

http://img14.imageshack.us/img14/9719/wrongface.jpg

Has someone an idea whats wrong???
Best regards - Stefan

Steven Diehl's picture

Hi Stefan,

If I understand correctly, you are approximating a polyline with a B-Spline. So first, have you tried increasing the number of segments in approx_curve3d?

Why are you not building a face out of your polyline directly? Should be faster and more accurate. I am thinking of polylines -> Edges via BRepBuilderAPI_MakeEdge, then the Edges to a wire (BRepBuilderAPI_MakeWire) and then to a face (BRepBuilderAPI_MakeFace). So, essentially what the bottle tutorial does at the very beginning. If you need to cut a one by another, you can use the boolean tools.

- Steven

StefanKunze's picture

Hi Steven,
the answer is quite simple - BRepBuilderAPI_MakeWire never gives an result with this example. After calling the Build-function of the BRepBuilderAPI_MakeWire object - the return value of IsDone is never trough (it seems to cycle infinitly). Moreover BRepBuilderAPI_MakeWire made problems in some other special cases.
Any ideas what causing the trouble with such an easy wire???

- Stefan

Here the code so that you could try yourself:
BRepBuilderAPI_MakePolygon lMakePolygonOne,lMakePolygonTwo;

lMakePolygonOne.Add(gp_Pnt(+15, +5,0));
lMakePolygonOne.Add(gp_Pnt(+15, -5,0));
lMakePolygonOne.Add(gp_Pnt(+ 5, -5,0));
lMakePolygonOne.Add(gp_Pnt(+ 5,-15,0));
lMakePolygonOne.Add(gp_Pnt(- 5,-15,0));
lMakePolygonOne.Add(gp_Pnt(- 5,- 5,0));
lMakePolygonOne.Add(gp_Pnt(-15,- 5,0));
lMakePolygonOne.Add(gp_Pnt(-15,+ 5,0));
lMakePolygonOne.Add(gp_Pnt(+15,+ 5,0));
lMakePolygonOne.Build();
while(!lMakePolygonOne.IsDone()){};
lMakePolygonOne.Check();

lMakePolygonTwo.Add(gp_Pnt(+13, +3,0));
lMakePolygonTwo.Add(gp_Pnt(+13, -3,0));
lMakePolygonTwo.Add(gp_Pnt(+ 3, -3,0));
lMakePolygonTwo.Add(gp_Pnt(+ 3,-13,0));
lMakePolygonTwo.Add(gp_Pnt(- 3,-13,0));
lMakePolygonTwo.Add(gp_Pnt(- 3,- 3,0));
lMakePolygonTwo.Add(gp_Pnt(-13,- 3,0));
lMakePolygonTwo.Add(gp_Pnt(-13,+ 3,0));
lMakePolygonTwo.Add(gp_Pnt(+13,+ 3,0));
lMakePolygonTwo.Build();
while(!lMakePolygonTwo.IsDone()){};
lMakePolygonTwo.Check();

BRepBuilderAPI_MakeWire lMakeWire;
lMakeWire.Add(lMakePolygonOne.Wire());
lMakeWire.Add(lMakePolygonTwo.Wire());
lMakeWire.Build();
while (!lMakeWire.IsDone()){};
lMakeWire.Check(); -> he never get here
lResult = BRepBuilderAPI_MakeFace(lMakeWire.Wire()).Face();

Steven Diehl's picture

Hmm, I have to check this out later. Just a quick question... did you try the "Close()" function for the polygon? (I haven't used BRepBuilderAPI_MakePolygon before, this might be the same as adding the first vertex again).

Steven

StefanKunze's picture

Yeah it´s absolutely the same. Changed it just to be sure - and the result is the same.

Francois Lauzon's picture

Hello Stefan,
you're not too far from a good result, try this:

BRepBuilderAPI_MakePolygon lMakePolygonOne,lMakePolygonTwo;
lMakePolygonOne.Add(gp_Pnt(+15, +5,0));
lMakePolygonOne.Add(gp_Pnt(+15, -5,0));
lMakePolygonOne.Add(gp_Pnt(+ 5, -5,0));
lMakePolygonOne.Add(gp_Pnt(+ 5,-15,0));
lMakePolygonOne.Add(gp_Pnt(- 5,-15,0));
lMakePolygonOne.Add(gp_Pnt(- 5,- 5,0));
lMakePolygonOne.Add(gp_Pnt(-15,- 5,0));
lMakePolygonOne.Add(gp_Pnt(-15,+ 5,0));
lMakePolygonOne.Add(gp_Pnt(+15,+ 5,0));
lMakePolygonOne.Build();

lMakePolygonTwo.Add(gp_Pnt(+13, +3,0));
lMakePolygonTwo.Add(gp_Pnt(+13, -3,0));
lMakePolygonTwo.Add(gp_Pnt(+ 3, -3,0));
lMakePolygonTwo.Add(gp_Pnt(+ 3,-13,0));
lMakePolygonTwo.Add(gp_Pnt(- 3,-13,0));
lMakePolygonTwo.Add(gp_Pnt(- 3,- 3,0));
lMakePolygonTwo.Add(gp_Pnt(-13,- 3,0));
lMakePolygonTwo.Add(gp_Pnt(-13,+ 3,0));
lMakePolygonTwo.Add(gp_Pnt(+13,+ 3,0));
lMakePolygonTwo.Build();

BRepBuilderAPI_MakeFace aFace(lMakePolygonOne.Wire(), Standard_True);
aFace.Add(lMakePolygonTwo.Wire());
aFace.Build();
TopoDS_Face aTrimmedFace=aFace.Face();

Good Luck,
Francois.

StefanKunze's picture

Hi François,
I know that this is working but it want to develop a function creating a surface between two wire in generell. This function only works if both wire lie in the same plane. It won´t work if polygonOne lies in plane z = 0 and polygonTwo in z = 100. Correct???

Some strange behaviour regarding my method by using Approx_Curve3d. When I rotate the polygons in the same matter (so that they lie it the same plane - not the x-y-plane) - it´s working. I have absolutely no idea whats the difference?!?!?!

Francois Lauzon's picture

Ok, so you want something like this then:

BRepOffsetAPI_ThruSections sections(Standard_False,Standard_True);
sections.AddWire(lMakePolygonOne.Wire());
sections.AddWire(lMakePolygonTwo.Wire());
sections.Build();

TopoDS_Shape aShellBetweenWire=sections.Shape();

StefanKunze's picture

Hello Francois,
I also tried this way to build the shell - unfortunately it´s much slower than my way. In my sample - your way to build the shell took 4 times so long as my one. I try to build an interactive application so this performance deficit is not acceptable. :(

Francois Lauzon's picture

Hello Stefan,
you seem to have sharp edge in your wires, if that's the case and you need to keep it that way, using only 1 NURBS curve to represent your wire won't gives you good results, even if it's faster... if it's not the case, then what you did is another option, but I'm not sure you will get a good surface from it. You should build small radius into your wire at each sharp edge, this will help.

Good Luck,
Francois.

StefanKunze's picture

Building small radius at the sharp edges is not an option. :(
It will have negative influence on performance and it will result in "not really big - but visible" errors.

Francois Lauzon's picture

Well, if you have "sharp edges" and you use Approx_Curve3d, you will have "not really big - but visible" errors, or if you're lucky, by creating a really complex NURBS curve using Approx_Curve3d for a set of curves with "sharp edges" (which will have a negative influence on performance and memory footprint of your shape), you might get "really really small errors - almost not visible" but still errors. And I'm not talking about the kind of surface you will get from thoses curves.
It's your choice! ;)

Good luck in anycase,
Francois.

StefanKunze's picture

THX

StefanKunze's picture

One more problem with BRepOffsetAPI_ThruSections - the algorithm doesn´t seem to work if the underlying wires have a different number of edges.