I have come across a few simple models that the offset api just 'chokes' on, so I started into it. Test code is below, attached a picture showing face to offset, attached brep file. After many hours: The first thing I learned is that every face gets extended and re-trimmed regardless of offset values. I found that surprising, but I can see how that would help alleviate hidden conditions. Then I found out that the face intersections get cached and re-used as the algo iterates around the face edges. The problem is .... I should say ONE problem is .... the caching of intersections doesn't consider a condition where the face intersection produces to independent curves like the cylinder and the 'left' face producing 2 different lines. One piece of evidence for this theory was: The exact same model, with the exception being the cylinder seam edge was present in the subraction creating 2 cylindrical faces insted of one, works as expected. The final piece of evidence for that theory is: I broke into the execution with gdb and dumped out all the intersection curves and one of the expected cylinder to planar intersection curves was missing. As I was hacking away trying to add support for this condition, I found a different bug that sent me off in a different direction for days/weeks. I did find the problem and fixed that second bug. Back to the missing intersection: I got to the point where I felt confident I had the extra intersection curve handled for the intersection portion of the algo. That wasn't enough and the boundary detection portion was suffering from the same lack of support of the condition. I had to step away from that code, as a padded room was being prepared especially for me.What is your current focus on OpenCascade? Just curious.
While I was working on that offset problem, I had a thought I wanted to explore: "What if we untrimmed all the faces and just dumped everything into BOPAlgo_MakerVolume. Can we interpret those results to get the expected offset face result?". That is what I have been doing the last few weeks.
C++:
TEST_CASE("000026", "[known]")
{
path inputPath = getTestPath() / "000026/offsetBugPlaneFail.brep";
REQUIRE(std::filesystem::exists(inputPath));
auto inputShape = ocs::readBRep(inputPath.string());
REQUIRE(!inputShape.IsNull());
ocs::Solids inputSolids = ocs::getTypedIndexed<ocs::Solids>(inputShape);
REQUIRE(inputSolids.size() == 1);
auto inputFaces = ocs::getTypedIndexed<ocs::Faces>(inputSolids.front(), {2});
REQUIRE(inputFaces.size() == 1);
BRepOffset_MakeOffset builder;
builder.Initialize
(
inputSolids.front(),
0.0,
1.0e-06,
BRepOffset_Skin, //offset mode
Standard_False, //intersection
Standard_False, //self intersection
GeomAbs_Intersection, //join type.
Standard_False, //thickening.
Standard_False //remove internal edges
);
builder.SetOffsetOnFace(TopoDS::Face(inputFaces.front()), 0.1);
builder.MakeOffsetShape();
CHECK(builder.IsDone());
CHECK(builder.Error() == BRepOffset_NoError);
REQUIRE(!builder.Shape().IsNull());
BRepCheck_Analyzer checker(builder.Shape());
CHECK(checker.IsValid());
ocs::writeBRep(builder.Shape(), "offsetTestOut.brep");
}