Ultimaker / CuraEngine

Powerful, fast and robust engine for converting 3D models into g-code instructions for 3D printers. It is part of the larger open source project Cura.
https://ultimaker.com/en/products/cura-software
GNU Affero General Public License v3.0
1.68k stars 882 forks source link

Np 5 wasupppp #2025

Closed jellespijker closed 7 months ago

jellespijker commented 8 months ago

Description

Compiling CuraEngine for wasm and Emscripten, requires the usage of the cura_wasm.jinja conan profile ( see https://github.com/Ultimaker/conan-config/pull/11 )

For this to work I had to remove the CuraEngine plugin logic. Since GRPC currently doesn't compile for wasm (see https://github.com/grpc/grpc/issues/24166 ). The plugin logic is enabled conditionally based on the definition of the __EMSCRIPTEN__ compiler definition. To API of the plugins and slots are empty facades in that case and will be optimized away by the compiler.

Building the CuraEngine.js is as simple as:

conan install . --build=missing --update -pr:b cura_build.jinja -pr:h cura_wasm.jinja
cmake --preset release
cmake --build --preset release

The resulting JS binary has as entry point the commandline which can be used with the regular syntax in the consuming React project. It also adds an progress handler which is exposed to the consumer.

[!NOTE] The current changes serve as a starting point and still contain a couple of FXIME's which will be resolved in due time. Just not now to limit scope creep.

[!IMPORTANT] Multi-threading has also been disabled since it resulted in some issues with running it in the browser which are far out of my comfort zone. I will add a Jira ticket to re-enable this at a later time.

[!CAUTION] Sentry support hasn't been tested with this

Type of change

How Has This Been Tested?

Test Configuration:

Checklist:

jellespijker commented 7 months ago

I would just like to know more about the slots. What exactly do they represent?

Slots are hooks into the slicing process in which CuraEngine plugins can subscribe to. We send over data to a separate process (plugin) using Google Remote Procedure Calls, such as shape outlines and we receive data back. Either modified or newly generated. This is all done async at the location of such a slot. These slots and plugins allow us to extend the inner workings of the actual slicing process with very custom behavior.

See alternative A in this discussion: https://github.com/Ultimaker/Cura/discussions/15629

Same for split paths.

Split Paths is a lazily executed view over a range of characters in this case. In which any type of character range (string, string_view, array<char>, vector<char>, etc.) is split up on the path separation character ; or : and converted to a range of string_view which are basically pointers to the start of the first character and the size.

These kind of views can be piped together and are only executed once your are actually working on the data. This would allow us to build up a more complex view in which we could split up a range of paths, reverse the order, only take the first n-paths for instance in a very generic way;

constexpr auto user_defined_paths = "\dir1\dir2\dir3:\dir1\dir4:\dir5"sv;

// Only process the last two paths
for (const auto& path : user_defined_paths | split_paths | ranges::views::reverse | ranges::views::take(2)) {
    fmt::print("Path: {}", path);
}

// Will print the following:
// \dir5
// \dir1\dir4