OCC BRepOffsetAPI_MakeOffset seems to be able to deal with 3D wire offset on non-planar faces. However, its algorithm is not well documented, overly complicated, and buggy. Part.makeOffset2D only deals with co-planar 2D objects, which requires a much more simplified algorithm. This commit adds two alternative algorithms provided by libarea (currently part of Path Mod) to do the 2D offset. libarea, from HeeksCNC, in turn, uses the execllent and well documented ClipperLib to do the actual work.
An extra parameter, algo, is added to Part.makeOffset2D to select the algorithm,
- 0 = OCC BRepOffsetAPI_MakeOffset
- 1 = libarea's own MakeLoop for offset, and ClipperLib::Clipper to clean the edge
- 2 = Same as above, but without final Arc fitting (mostly for debugging purpose)
- 3 = use libarea's wrapping of ClipperLib::ClipperOffset
- 4 = Same as above, but without final Arc fitting (mostly for debugging purpose)
- Allow FaceMaker to fail, and return a wire compound for debugging purpose.
- Unify all faces created by FaceMakerBullsEye and return a single face shape if the use pass in a single input face.
Here are some pictures showing OCC's problem, and what libarea/ClipperLib is capable of. I currently goal is investigate the possibility of doing PCB milling using FreeCAD. The test file is in the attachment. The test FACE is extracted from a PCB, partly shown below, First, to make it clear, this is not a compound, but a single FACE. If it were a compound, makeOffset2D will offset each face individually, and won't fuse the result afterwards. FreeCAD can't do FACE fusing at the moment AFAIK.
When doing an offset of 0.1, BRepOffsetAPI_MakeOffset failed to construct a proper face, showing only individual vertexes, as shown below, After investigating, it seems that BRepOffsetAPI_MakeOffset somehow has flipped certain edges. After adjusting those edges, it was able to construct the face. If that's all the problem, I won't go further. However, BRepOffsetAPI_MakeOffset crashes for offset beyond 0.1. It seems BRepOffsetAPI_MakeOffset can't handle faces with inner faces. So I removed those inner faces. And it now produces result with intersected edges. To fix that problem, one might as well wrote a 2D offset algorithm from scratch, which at its core is to determine and eliminate intersected offset edges. This is when I decide to abandon BRepOffsetAPI_MakeOffset. Now, libarea is able to do 0.1, 0.2, and 0.3 without any problem. Here is three offset result super imposed together. Note that each offset result is also a single FACE, not compound, which makes it trivial to convert to Path for milling. Path Mod is already using libarea for pocketing, but still uses makeOffset2D to do profiling. My patch shall greatly simplify isolation routing using FreeCAD.