Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sometimes the code crashes on operations like chamfer, fillet etc, instead of handling errors gracefully. #172

Open
aerosayan opened this issue May 14, 2024 · 7 comments

Comments

@aerosayan
Copy link

Hello,

I'm trying to create small example codes to understand the library well.

When I try to use a 0.05 mm chamfer to create this shape, the code crashes with StdFail_NotDone error.

pub fn test_0007() {
    let box1 = Shape::box_with_dimensions(1.0, 1.0, 1.0);
    let sphere = Shape::sphere(0.2).at((0.0, 0.5, 0.5).into()).build();

    let shape = box1.subtract(&sphere).chamfer(0.05);
    shape.write_step("shape.step").unwrap();
}

The error I got was:

terminate called after throwing an instance of 'StdFail_NotDone'
Aborted (core dumped)

Errors can happen obviously, there's nothing wrong with that, but there must be some way we can prevent the code from crashing.

I suspect, that most likely the ffi functions being called for chamfer crashes the code, so rust can't handle the error gracefully.

When we remove the chamfer operation, it works correctly.

This chamfer operation should be possible, and should not cause an error.

In FreeCAD, I tried the chamfer operation with 0.05 mm on all edges, and it worked correctly, as shown in the picture below.

Since this operation seems to work in FreeCAD, but not in the opencascade code, maybe something is wrong?

It could be possible that I made a mistake in using the opencascade library, but even then, would it be possible for the error to be handled gracefully with an idiomatic Result<T, Error> method?

Thanks :)

3

@aerosayan
Copy link
Author

Looking more into this topic shows that the bug could be in OCCT.

  1. A frustrated user who blames OCCT for not fixing this bug for over a decade
  2. Freecad forum post on how chamfers and fillet crashes the app

For my work (CFD/FEM mesh generation), I don't need chamfer or fillet, so I can work without them.

Although, it might be good to submit patches to OCCT when we find such bugs.

Shown in the code below, one developer from the freecad forum submitted a patch to emit an exception if the fillet or chamfer operation fails.

Although, since freecad can recover from such errors, it shows that OCCT is trying to improve, and maybe cxx-rust bridge can't handle the exceptions properly, that's why the rust code crashes.

I don't know much about cxx.rs, so I will have to study more about how it handles exceptions.

--- src/ChFi3d/ChFi3d_Builder_C1.cxx	2020-11-03 08:49:55.000000000 -0600
+++ /c/Users/chennes/Desktop/ChFi3d_Builder_C1.cxx	2021-01-27 09:21:50.537703200 -0600
@@ -1459,20 +1459,30 @@
 //	Ecur1=TopoDS::Edge(TopoDS_Shape (MapE1(i)));
         for ( j=1; j<= MapE2.Extent()&&!trouve; j++)
             {
 	      aLocalShape = TopoDS_Shape (MapE2(j));
 	      Ecur2=TopoDS::Edge(aLocalShape);
 //	      Ecur2=TopoDS::Edge(TopoDS_Shape (MapE2(j)));
             if (Ecur2.IsSame(Ecur1))
                {Edge=Ecur1;trouve=Standard_True;}
             }
       }
+  // BEGIN FREECAD CUSTOM PATCH
+  // This patch is to address FreeCAD Bug #4543
+  // https://tracker.freecadweb.org/view.php?id=4543
+  // If this function failed to find a matching edge between two faces, throw an exception: later
+  // code assumes that Edge has been populated, but in this case it is in an invalid state.
+  // - Chris Hennes, 1/26/2021
+  if (trouve != Standard_True) {
+      throw Standard_Failure("Failed to find matching edge between two faces.");
+  }
+  // END FREECAD CUSTOM PATCH
 }

@bschwind
Copy link
Owner

Hi, yes we should be using Result for fallible calls. This is tracked in #24 and it can be achieved with cxx.rs and the use of exceptions.

@aerosayan
Copy link
Author

Cool!

I don't know cxx.rs right now, but if anyone could show a single example of how to handle exceptions for OCCT errors, perhaps for a commonly used function like chamfer or fillet, then one by one we could implement the error handling for the other failable functions, and send PRs.

PS: Also I'm trying to understand how to implement interactive selection of sub-shapes (faces, wires, vertex) using mouse, and once I'm done learning wgpu rendering, I would try to send some PRs for it. It is little bit complicated, so no promises. haha. 😅

@DanielJoyce
Copy link

dtolnay/cxx#53

Trapping exceptions as result.

Checking opencascade, it does seem that if an operation is not done, simply calling some apis will raise exceptions

@bschwind
Copy link
Owner

PS: Also I'm trying to understand how to implement interactive selection of sub-shapes (faces, wires, vertex) using mouse, and once I'm done learning wgpu rendering, I would try to send some PRs for it

This is usually accomplished by "unprojecting" the mouse coordinates from screen-space, back through the camera matrix transforms. Here is an article on the subject, but there are plenty of references about it all over.

Checking opencascade, it does seem that if an operation is not done, simply calling some apis will raise exceptions

Yes, many operations have an "isDone" function that you use to check if the operation was successful. These can be pretty easily added to the various fallible operations, I've just been too lazy to implement it yet.

@DanielJoyce
Copy link

Can't we use the wrapper generation code to generate them?

@bschwind
Copy link
Owner

@DanielJoyce which generation code are you referring to? cxx.rs?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants