How to build an arc wire without triggering precision errors

Hi,

I have a closed 2D polygon data structure consisting of straight lines and arcs. Basically it looks like this:

  1. Start at (10, 20)
  2. Line to (30, 40)
  3. Arc to (50, 60) with 45° angle
  4. ...
  5. Line to (10, 20)

Now I need to build a 3D shape by extruding this polygon in a reliable way. I already managed to do this by converting my polygon structure to a face. Pseudo code:

  BRepBuilderAPI_MakeWire wire;
  for (const auto& vertex : polygon) {
    const gp_Pnt startPos = vertex.getStartPos();
    const gp_Pnt endPos = vertex.getEndPos();
    if (vertex.isArc()) {
      const gp_Pnt arcCenter = vertex.calculateArcCenter();
      const float arcRadius = vertex.calculateArcRadius();
      const gp_Dir arcDir(0.0, 0.0, (vertex.getArcAngle() < 0) ? -1.0 : 1.0);
      gp_Circ arc(gp_Ax2(arcCenter, arcDir), arcRadius);
      wire.Add(BRepBuilderAPI_MakeEdge(arc, startPos, endPos));
    } else {
      wire.Add(BRepBuilderAPI_MakeEdge(startPos, endPos));
    }
  }
  auto face = BRepBuilderAPI_MakeFace(wire);

Generally this works. However, since the arc center and radius are calculated to convert from a different representation of arcs, they won't be perfectly accurate. Especially if the start and end points are close together, the calculations can lead into relatively large errors. This makes BRepBuilderAPI_MakeEdge(arc, startPos, endPos) throwing an exception with message "BRep_API: command not done".

So I need to find a way to create the arc edges in a reliable way. Increasing BRepBuilderAPI::Precision() does help, but not really well because due to arbitrary input polygons it's impossible to find a precision which makes sense for every case.

I do not care too much about inaccurate arcs in the output shape, I just can't accept fatal failures like the "command not done". It would even be okay to do some arc where the end point does not match accurately, and then add a straight line segment to connect the arc to the desired end point. But how can I build an arc which will always succeed, no matter of numerical inaccuracies, and then know what was the end point of that arc?

Or is there any other way to build an arc in a reliable way?

Thanks

Pedro Ferreira's picture

Hi, did you solve the problem? I'm the same situation and cannot find a solution

Nabru B.'s picture

I couldn't solve it in a nice way but I am now catching the exception StdFail_NotDone and fallback then to approximate the arc manually with straight line segments instead. It's an ugly workaround, but seems to work for me.

Pedro Ferreira's picture

Maybe doing it the other way around, saving 1 extra segment. First draw the arcs, and then approximate the line instead, to connect it to the arc. If the arc is connected to another arc, the only solution might be to connect both arcs with a line, as you mentioned.