Exception "Geom_BSplineSurface: Weights values too small" when reading STEP file

Hi!

I have been testing various STEP files with OpenCascade with generally great results.
However, I came across this file, which results in an exception in this line. The value of Weights(i,j) in this line is -2.07786.

The code that I'm using to load the STEP file is very simple (I'm using OpenCascade.js)

const reader = new oc.STEPCAFControl_Reader_1();
reader.ReadFile("./file.stp");
reader.Transfer_1(doc, p.Start_1());

I also tried to open the file in OpenCascade's CadAssistant, which works without issues. Therefore, I think that I'm probably just missing certain settings. Any help or tips would be much appreciated!

Sebastian Alff's picture

...my suspicion is that the error might have to do with this section in the STEP file, as this is the only occurrence of the magic number -2.07786:

// (starting at line 979697)
 GEOMETRIC_REPRESENTATION_ITEM ( )  RATIONAL_B_SPLINE_SURFACE ( (
 ( 3.400450733080581323, -2.077861492284087674, 3.974413173868763582),
 ( 3.373204234758431674, -2.042925991700952792, 3.940651871279065688),
 ( 3.348145074567353774, -2.010795099315540568, 3.909600912735637479),
 ( 3.310913803712574488, -1.963057108573416087, 3.863467417478179122),
 ( 3.298264439034085171, -1.946838074410687014, 3.847793512397660542),
 ( 3.278816539105890548, -1.921901948261593329, 3.823695500739546560),
 ( 3.272352215527178476, -1.913613382975752231, 3.815685517886037381),
 ( 3.260778221369672103, -1.898773190490903984, 3.801344110990262593),
 ( 3.255530745263142123, -1.892044868839728444, 3.794841931276375036),
 ( 3.245517963372582582, -1.879206465040436314, 3.782435032042022804),
 ( 3.240316994584560462, -1.872537775142067540, 3.775990479830729996),
 ( 3.229076570844181759, -1.858125287141088045, 3.762062402077456902),
 ( 3.222730168670852269, -1.849987920856228651, 3.754198536358041238),
 ( 3.210402926223692166, -1.834181912296546813, 3.738923774903032182),
 ( 3.204195029893585733, -1.826222138409411944, 3.731231532620438163),
 ( 3.193353196473067701, -1.812320723508075382, 3.717797350568515125),
 ( 3.188000267104304619, -1.805457189527569728, 3.711164503072911014),
 ( 2.970539133596314052, -1.526628201425921372, 3.441707083515487042),
 ( 2.787209096010096587, -1.291562155166746440, 3.214541713509321497),
 ( 2.448236633370457049, -0.8569311605239956497, 2.794518863397257746) ) ) 
 REPRESENTATION_ITEM ( '' )  SURFACE ( )  );
Sebastian Alff's picture

Nevermind, I managed to resolve the problem!
This was a problem with my own custom build and not with OpenCascade itself. Long story short: I have been building OpenCascade.js with globally disabled exception catching (`-sDISABLE_EXCEPTION_CATCHING=0`). However, in this case exception catching is required when loading this particular STEP file. Re-enabling that feature solved the issue.

Thanks a lot for your great work on OpenCascade :-)!

Kirill Gavrilov's picture

It is not just for reading a particular STEP file - modeling algorithms in OCCT considerably depend on C++ exceptions within a normal workflow (e.g. not just for near-to-crash situations and internal errors). So, indeed, you cannot use OCCT with DISABLE_EXCEPTION_CATCHING=0 option, as it will be break the logic.

Sebastian Alff's picture

The problem with exception support in Emscripten (from the experiences I had with OpenCascade.js at least) is that it comes with an extreme performance penalty. I just made a simple benchmark in which open and display some random STEP file.

  1. With global support for exceptions disabled and the build option -sEXCEPTION_CATCHING_ALLOWED=["_ZN10StepToGeom11MakeSurfaceERKN11opencascade6handleI16StepGeom_SurfaceEE"] (i.e. support enabled only for specific functions), the file loads in ~2 min.
  2. With global support for exceptions enabled, i.e. -sDISABLE_EXCEPTION_CATCHING=0, the file loads in ~10 min.

Global exception support also comes with a size penalty.

My plan is to only enable exception support in the functions where it's necessary for my use case - and disable it everywhere else.

Kirill Gavrilov's picture

How could you know in advance which functions need exception handling and which wouldn't raise exceptions?
I guess this could be feasible only for a predefined set of STEP files (and don'tI think that only STEP import would suffer from this problem).

Sebastian Alff's picture

Hmm, yeah, I understand your point. But also: For a five fold performance gain, it might be worth trying to understand the whole exception problem a bit better and try to optimize it for my particular scenario. Of course, this wouldn't make sense for a general-purpose version of the library, as I wouldn't know which functions are used and how.

Here is what I'm thinking about:

  • maybe testing a large number of STEP files will give some insights on where exception catching is likely to be required for my specific use case
  • maybe profiling and comparing executions with and without exception support will give some insights. For example, I could imagine that there might be a hand full of low level exception-catching functions, which are called with a high frequency. And maybe, disabling exception catching there wouldn't be an issue in my case?!

But maybe I'm wrong and this will lead nowhere... However, I'm still going to research this a bit further.

Kirill Gavrilov's picture

Sebastian, have you seen some bugs / feature requests in Emscripten project with planned improvements in exception handling performance or elaborating why it will be always that slow?

Sebastian Alff's picture

I haven't seen any news on that subject from the Emscripten side. However, in my understanding exception support in Emscripten is more or less a workaround anyways, as native Exception support is not yet part of the WebAssembly standard. According to WebAssembly/propsals, Exception handling support is currently being standardized and developed and should then hopefully be one of the next big features to be released soon.

Kirill Gavrilov's picture

Great, so that there are some trials in Firefox night builds and Chrome, but proposal is still not finished and we don't have any dates when it might be finished. Hopefully at some not that distant day C++ exceptions will not be that slow in WebAssembly...

Sebastian Alff's picture

I just tried to reply several times, but the forum keeps telling me that I'm using "blacklisted" words in my post. Not sure what those could be :-). My reply should hopefully appear here, soon.

Sebastian Alff's picture

I didn't know that there is already experimental support in some browsers. That's definitely a good sign!

Until exception support can effectively be used with OpenCascade, there probably needs to be work done by

  • the WebAssembly standard
  • Emscripten
  • LLVM
  • V8 / SpiderMonkey / Webkit

I also hope this will land soon! :-)

Kirill Gavrilov's picture

Well, some obvious features waited for several years before become available in all major browsers. So probably not that soon as we would like to...

Sebastian Alff's picture

There is now experimental support for "native" WASM exceptions in Emscripten + Chrome / V8 (behind a flag). I haven't tested it yet, but it might be worth checking out.
Here is the page in the Emscripten docs: https://emscripten.org/docs/porting/exceptions.html

frank pian's picture

I want to try disabling Exception or using '-fwasm-exceptions' flag. Do I only need to change here under "occt_defs_flags. cmake"?

if (MSVC)
  add_definitions (-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
else()
  set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions -fPIC")
  set (CMAKE_C_FLAGS   "${CMAKE_C_FLAGS}   -fexceptions -fPIC")
  add_definitions(-DOCC_CONVERT_SIGNALS)
endif()