diff --git a/cmake/utilities.cmake b/cmake/utilities.cmake index 3e8877c724..78be5271f6 100644 --- a/cmake/utilities.cmake +++ b/cmake/utilities.cmake @@ -41,6 +41,28 @@ macro(SET_INSTALL_RPATHS _target _paths) set_target_properties(${_target} PROPERTIES INSTALL_RPATH "${${_target}_rpaths}") endmacro() +function(ifcopenshell_wasm_plugin_link_options TARGET REGISTRATION_SYMBOL) + if(NOT WASM_BUILD) + return() + endif() + + cmake_parse_arguments(PLUGIN "" "OPTIMIZATION" "" ${ARGN}) + if(NOT PLUGIN_OPTIMIZATION) + set(PLUGIN_OPTIMIZATION -O1) + endif() + + set(plugin_symbols + ifcopenshell_plugin_abi_v1 + ifcopenshell_plugin_metadata_v1 + ${REGISTRATION_SYMBOL} + ) + + target_link_options(${TARGET} PRIVATE "SHELL:-s SIDE_MODULE=2" ${PLUGIN_OPTIMIZATION}) + foreach(symbol IN LISTS plugin_symbols) + target_link_options(${TARGET} PRIVATE "LINKER:--export=${symbol}") + endforeach() +endfunction() + # Get a list of all OPTION flags from the CMakeLists.txt and store in an output LIST function(get_all_option_flags output_list) # Read the contents of the CMakeLists.txt diff --git a/src/ifcgeom/Serialization/schema/CMakeLists.txt b/src/ifcgeom/Serialization/schema/CMakeLists.txt index c9e77debe6..c6eec889b2 100644 --- a/src/ifcgeom/Serialization/schema/CMakeLists.txt +++ b/src/ifcgeom/Serialization/schema/CMakeLists.txt @@ -9,6 +9,10 @@ foreach(schema ${SCHEMA_VERSIONS}) RUNTIME_OUTPUT_DIRECTORY "${geometry_serialization_plugin_runtime_dir}" LIBRARY_OUTPUT_DIRECTORY "${geometry_serialization_plugin_runtime_dir}" ) + ifcopenshell_wasm_plugin_link_options( + geometry_serializer_ifc${schema} + ifcopenshell_register_opencascade_geometry_ifc_writer_plugin_v1 + ) list(APPEND geometry_serializer_libraries geometry_serializer_ifc${schema}) endforeach() set(geometry_serializer_libraries ${geometry_serializer_libraries} PARENT_SCOPE) diff --git a/src/ifcgeom/kernels/CMakeLists.txt b/src/ifcgeom/kernels/CMakeLists.txt index a7bb486847..c134ab2cca 100644 --- a/src/ifcgeom/kernels/CMakeLists.txt +++ b/src/ifcgeom/kernels/CMakeLists.txt @@ -23,11 +23,10 @@ foreach(kernel ${GEOMETRY_KERNELS}) set(KERNEL_TARGET "geometry_kernel_${kernel}") add_library(${KERNEL_TARGET} SHARED ${IFCGEOM_FILES}) - if (WASM_BUILD) - target_link_options( - ${KERNEL_TARGET} - PRIVATE "SHELL:-s -s SIDE_MODULE=1" - ) + if(${kernel} STREQUAL "opencascade") + ifcopenshell_wasm_plugin_link_options(${KERNEL_TARGET} ifcopenshell_register_kernel_plugin_v1 OPTIMIZATION -O0) + else() + ifcopenshell_wasm_plugin_link_options(${KERNEL_TARGET} ifcopenshell_register_kernel_plugin_v1) endif() set_target_properties(${KERNEL_TARGET} PROPERTIES @@ -39,26 +38,6 @@ foreach(kernel ${GEOMETRY_KERNELS}) list(APPEND kernel_libraries ${KERNEL_TARGET}) target_link_libraries(${KERNEL_TARGET} PRIVATE ${plugin_when_not_wasm} IfcGeom ${${KERNEL_UPPER}_LIBRARIES} Eigen3::Eigen) - if (WASM_BUILD AND ${kernel} STREQUAL "opencascade") - # Try to disable wasm-opt: - # - # 2026-04-25T09:53:53.3073297Z [parse exception: popping from empty stack (at - # 0:32668981)] 2026-04-25T09:53:53.3073431Z Fatal: error parsing wasm (try - # --debug for more info) 2026-04-25T09:53:53.3075545Z em++: error: - # '/home/runner/.cache/.pyodide-xbuildenv-0.33.0/0.29.3/emsdk/upstream/bin/wasm-opt - # --strip-target-features --post-emscripten - # --pass-arg=post-emscripten-side-module -O3 --low-memory-unused - # --pass-arg=directize-initial-contents-immutable --no-stack-ir - # ../Release/libgeometry.kernel.opencascade.so -o - # ../Release/libgeometry.kernel.opencascade.so --mvp-features - # --enable-bulk-memory --enable-bulk-memory-opt --enable-call-indirect-overlong - # --enable-exception-handling --enable-multivalue --enable-mutable-globals - # --enable-nontrapping-float-to-int --enable-reference-types --enable-sign-ext' - # failed (returned 1) - target_link_options(${KERNEL_TARGET} PRIVATE -O0) - endif() - - install(TARGETS ${KERNEL_TARGET}) if(${kernel} STREQUAL "cgal") @@ -67,12 +46,7 @@ foreach(kernel ${GEOMETRY_KERNELS}) set(KERNEL_TARGET_SIMPLE "${KERNEL_TARGET}_simple") add_library(${KERNEL_TARGET_SIMPLE} SHARED ${IFCGEOM_FILES}) - if (WASM_BUILD) - target_link_options( - ${KERNEL_TARGET_SIMPLE} - PRIVATE "SHELL:-s -s SIDE_MODULE=1" - ) - endif() + ifcopenshell_wasm_plugin_link_options(${KERNEL_TARGET_SIMPLE} ifcopenshell_register_kernel_plugin_v1) set_target_properties(${KERNEL_TARGET_SIMPLE} PROPERTIES COMPILE_FLAGS "-DIFC_GEOMLIBRARY_EXPORTS -DIFOPSH_SIMPLE_KERNEL -DCGAL_HAS_THREADS" @@ -108,6 +82,7 @@ foreach(kernel ${GEOMETRY_KERNELS}) ) list(APPEND tree_libraries ${TREE_TARGET}) target_link_libraries(${TREE_TARGET} PRIVATE plugin IfcGeom geometry_kernel_opencascade ${OpenCASCADE_LIBRARIES} Eigen3::Eigen) + ifcopenshell_wasm_plugin_link_options(${TREE_TARGET} ifcopenshell_register_tree_plugin_v1) install(TARGETS ${TREE_TARGET}) endforeach() endif() diff --git a/src/ifcgeom/mapping/CMakeLists.txt b/src/ifcgeom/mapping/CMakeLists.txt index b218453248..798b7199ff 100644 --- a/src/ifcgeom/mapping/CMakeLists.txt +++ b/src/ifcgeom/mapping/CMakeLists.txt @@ -22,12 +22,7 @@ foreach(schema ${SCHEMA_VERSIONS}) LIBRARY_OUTPUT_DIRECTORY "${mapping_plugin_runtime_dir}" ) - if (WASM_BUILD) - target_link_options( - geometry_mapping_ifc${schema} - PRIVATE "SHELL:-s -s SIDE_MODULE=1" - ) - endif() + ifcopenshell_wasm_plugin_link_options(geometry_mapping_ifc${schema} ifcopenshell_register_mapping_plugin_v1) target_link_libraries(geometry_mapping_ifc${schema} PRIVATE ${plugin_when_not_wasm} IfcGeom IfcParse Eigen3::Eigen) diff --git a/src/ifcopenshell-python/ifcopenshell/geom/main.py b/src/ifcopenshell-python/ifcopenshell/geom/main.py index 30c2233a89..a2c9fb9c9f 100644 --- a/src/ifcopenshell-python/ifcopenshell/geom/main.py +++ b/src/ifcopenshell-python/ifcopenshell/geom/main.py @@ -23,8 +23,8 @@ from collections.abc import Generator, Iterable from typing import TYPE_CHECKING, Any, Literal, Optional, TypeVar, Union, cast, overload from .. import ifcopenshell_wrapper, open -from ..entity_instance import entity_instance -from ..file import file +from .. import entity_instance +from .. import file from . import has_occ if TYPE_CHECKING: @@ -625,8 +625,9 @@ def make_shape_function(fn): return _ -serialise = make_shape_function(ifcopenshell_wrapper.serialise) -tesselate = make_shape_function(ifcopenshell_wrapper.tesselate) +# @todo, plug-ins now +# serialise = make_shape_function(ifcopenshell_wrapper.serialise) +# tesselate = make_shape_function(ifcopenshell_wrapper.tesselate) def transform_string(v: Union[str, serializers.buffer]) -> serializers.buffer: @@ -659,7 +660,7 @@ class serializers: # Hdf- Xml- and glTF- serializers don't support writing to a buffer, only to filename # so no wrap_buffer_creation() for these serializers - xml = ifcopenshell_wrapper.XmlSerializer + # xml = ifcopenshell_wrapper.XmlSerializer buffer = ifcopenshell_wrapper.buffer # gltf, hdf5, collada and json availability depend on IfcOpenShell configuration settings try: diff --git a/src/ifcopenshell-python/ifcopenshell/stream.py b/src/ifcopenshell-python/ifcopenshell/stream.py index c9556fa708..3b9e8bfe42 100644 --- a/src/ifcopenshell-python/ifcopenshell/stream.py +++ b/src/ifcopenshell-python/ifcopenshell/stream.py @@ -29,8 +29,8 @@ try: import ifcopenshell.util.schema from . import ifcopenshell_wrapper - from .entity_instance import entity_instance - from .file import file + from . import entity_instance + from . import file class StreamTransformer(Transformer): file: file diff --git a/src/ifcopenshell-python/ifcopenshell/util/pset.py b/src/ifcopenshell-python/ifcopenshell/util/pset.py index 68fc84a5b1..ececba7dd1 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/pset.py +++ b/src/ifcopenshell-python/ifcopenshell/util/pset.py @@ -25,7 +25,6 @@ import ifcopenshell import ifcopenshell.ifcopenshell_wrapper as W import ifcopenshell.util.schema import ifcopenshell.util.type -from ifcopenshell.entity_instance import entity_instance templates: dict[ifcopenshell.util.schema.IFC_SCHEMA, "PsetQto"] = {} @@ -78,7 +77,7 @@ class PsetQto: pset_only=False, qto_only=False, schema: ifcopenshell.util.schema.IFC_SCHEMA = "IFC4", - ) -> list[entity_instance]: + ) -> list[ifcopenshell.entity_instance]: """Get applicable property set templates.""" any_class = not ifc_class entity = None @@ -179,7 +178,7 @@ class PsetQto: return False @lru_cache - def get_by_name(self, name: str) -> Optional[entity_instance]: + def get_by_name(self, name: str) -> Optional[ifcopenshell.entity_instance]: for template in self.templates: for prop_set in template.by_type("IfcPropertySetTemplate"): if prop_set.Name == name: @@ -190,7 +189,7 @@ class PsetQto: return bool(self.get_by_name(name)) -def get_pset_template_type(pset_template: entity_instance) -> Literal["PSET", "QTO", None]: +def get_pset_template_type(pset_template: ifcopenshell.entity_instance) -> Literal["PSET", "QTO", None]: """Get the type of the pset template. If type is mixed or not defined, return None.""" diff --git a/src/ifcwrap/CMakeLists.txt b/src/ifcwrap/CMakeLists.txt index be8f6590cd..e86b17c110 100644 --- a/src/ifcwrap/CMakeLists.txt +++ b/src/ifcwrap/CMakeLists.txt @@ -142,7 +142,7 @@ if (WASM_BUILD) endif() target_link_options( ifcopenshell_wrapper - PRIVATE "SHELL:-s EXPORTED_FUNCTIONS=_PyInit__ifcopenshell_wrapper -s SIDE_MODULE=2" + PRIVATE "SHELL:-s EXPORTED_FUNCTIONS=_PyInit__ifcopenshell_wrapper -s SIDE_MODULE=2" -O1 ) endif() target_link_libraries(ifcopenshell_wrapper PRIVATE IfcGeom IfcParse ${Boost_LIBRARIES} ${LIBSVGFILL}) diff --git a/src/pyodide/demo-app/index.html b/src/pyodide/demo-app/index.html index d13e8c6697..98bc440b73 100644 --- a/src/pyodide/demo-app/index.html +++ b/src/pyodide/demo-app/index.html @@ -77,7 +77,7 @@ const micropip = pyodide.pyimport("micropip"); await micropip.install("typing-extensions"); document.querySelector("#status2").innerHTML = "Loading IfcOpenShell"; - await micropip.install("wheels/ifcopenshell-0.8.3+34a1bc6-cp313-cp313-emscripten_4_0_9_wasm32.whl"); + await micropip.install("wheels/ifcopenshell-0.8.6-cp313-cp313-pyodide_2025_0_wasm32.whl"); document.body.className = ''; diff --git a/src/serializers/CMakeLists.txt b/src/serializers/CMakeLists.txt index 093a931094..9c3f76ba5a 100644 --- a/src/serializers/CMakeLists.txt +++ b/src/serializers/CMakeLists.txt @@ -25,12 +25,7 @@ function(add_document_serializer_plugin target output_name) list(APPEND document_serializer_libraries ${target}) set(document_serializer_libraries ${document_serializer_libraries} PARENT_SCOPE) - if (WASM_BUILD) - target_link_options( - ${target} - PRIVATE "SHELL:-s -s SIDE_MODULE=1" - ) - endif() + ifcopenshell_wasm_plugin_link_options(${target} ifcopenshell_register_document_serializer_plugin_v1) endfunction() function(add_geometry_serializer_plugin target output_name) @@ -56,12 +51,7 @@ function(add_geometry_serializer_plugin target output_name) list(APPEND geometry_serializer_libraries ${target}) set(geometry_serializer_libraries ${geometry_serializer_libraries} PARENT_SCOPE) - if (WASM_BUILD) - target_link_options( - ${target} - PRIVATE "SHELL:-s -s SIDE_MODULE=1" - ) - endif() + ifcopenshell_wasm_plugin_link_options(${target} ifcopenshell_register_geometry_serializer_plugin_v1) endfunction()