diff --git a/src/ifcwrap/CMakeLists.txt b/src/ifcwrap/CMakeLists.txt index e94759fa6d..12c6f97999 100644 --- a/src/ifcwrap/CMakeLists.txt +++ b/src/ifcwrap/CMakeLists.txt @@ -64,10 +64,6 @@ INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}) SET(CMAKE_SWIG_FLAGS ${SWIG_DEFINES}) -if (WITH_CGAL) - set(LIBSVGFILL svgfill) -endif() - SET_SOURCE_FILES_PROPERTIES(IfcPython.i PROPERTIES CPLUSPLUS ON) # Rebuild on changes in other .i files. SET_PROPERTY( @@ -120,6 +116,9 @@ else() endif() target_link_libraries(ifcopenshell_wrapper PRIVATE Python::Module) +if(WITH_CGAL) + target_sources(ifcopenshell_wrapper PRIVATE ../svgfill/src/linework_processing_facade.cpp) +endif() if(WITH_ROCKSDB) target_link_libraries(ifcopenshell_wrapper PRIVATE document_serializer_rdb) endif() @@ -144,9 +143,9 @@ if (WASM_BUILD) 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}) -if(schema_libraries OR kernel_libraries OR tree_libraries OR mapping_libraries OR geometry_serializer_libraries OR document_serializer_libraries) - add_dependencies(ifcopenshell_wrapper ${schema_libraries} ${kernel_libraries} ${tree_libraries} ${mapping_libraries} ${geometry_serializer_libraries} ${document_serializer_libraries}) +target_link_libraries(ifcopenshell_wrapper PRIVATE IfcGeom IfcParse ${Boost_LIBRARIES}) +if(schema_libraries OR kernel_libraries OR tree_libraries OR mapping_libraries OR geometry_serializer_libraries OR document_serializer_libraries OR linework_processing_libraries) + add_dependencies(ifcopenshell_wrapper ${schema_libraries} ${kernel_libraries} ${tree_libraries} ${mapping_libraries} ${geometry_serializer_libraries} ${document_serializer_libraries} ${linework_processing_libraries}) endif() if(NOT WIN32) SET_INSTALL_RPATHS(ifcopenshell_wrapper "${IFCDIRS};${OCC_LIBRARY_DIR}") @@ -221,7 +220,7 @@ IF(Python_Interpreter_FOUND OR PYTHON_MODULE_INSTALL_DIR) ${mapping_libraries} ${geometry_serializer_libraries} ${document_serializer_libraries} - ${LIBSVGFILL} + ${linework_processing_libraries} plugin ) diff --git a/src/plugin/plugin.cpp b/src/plugin/plugin.cpp index f713a61cee..288622d4c7 100644 --- a/src/plugin/plugin.cpp +++ b/src/plugin/plugin.cpp @@ -77,6 +77,8 @@ namespace { return "geometry_serializer"; case ifcopenshell::plugin::kind::opencascade_geometry_ifc_writer: return "opencascade_geometry_ifc_writer"; + case ifcopenshell::plugin::kind::linework_processing: + return "linework_processing"; default: return "unknown"; } diff --git a/src/plugin/plugin.h b/src/plugin/plugin.h index 05886d4900..398af12514 100644 --- a/src/plugin/plugin.h +++ b/src/plugin/plugin.h @@ -40,7 +40,8 @@ enum class kind { tree, document_serializer, geometry_serializer, - opencascade_geometry_ifc_writer + opencascade_geometry_ifc_writer, + linework_processing }; struct PLUGIN_API abi_info { diff --git a/src/svgfill/CMakeLists.txt b/src/svgfill/CMakeLists.txt index df2e4006cb..4cb1549e63 100644 --- a/src/svgfill/CMakeLists.txt +++ b/src/svgfill/CMakeLists.txt @@ -46,14 +46,18 @@ endif() include_directories(${Boost_INCLUDE_DIRS} ${SVGPP_INCLUDE}) file(GLOB LIB_H_FILES src/*.h) -file(GLOB LIB_CPP_FILES src/svgfill.cpp src/arrange_polygons.cpp) +file(GLOB LIB_CPP_FILES src/svgfill.cpp src/arrange_polygons.cpp src/svgfill_plugin.cpp) set(LIB_SRC_FILES ${LIB_H_FILES} ${LIB_CPP_FILES}) -add_library(svgfill ${LIB_SRC_FILES}) -target_link_libraries(svgfill ${Boost_LIBRARIES} ${BCRYPT_LIBRARIES} LibXml2::LibXml2 IFCOPENSHELL_CGAL) -if(BUILD_SHARED_LIBS) - target_compile_definitions(svgfill PUBLIC IFC_SHARED_BUILD) +add_library(svgfill SHARED ${LIB_SRC_FILES}) +target_compile_definitions(svgfill PRIVATE BOOST_DLL_USE_STD_FS) +if(NOT WASM_BUILD) + target_link_libraries(svgfill PRIVATE plugin) endif() +target_link_libraries(svgfill PRIVATE ${Boost_LIBRARIES} ${BCRYPT_LIBRARIES} LibXml2::LibXml2 IFCOPENSHELL_CGAL) +target_compile_definitions(svgfill PUBLIC IFC_SHARED_BUILD) set_target_properties(svgfill PROPERTIES PUBLIC_HEADER "${LIB_H_FILES}") +set_target_properties(svgfill PROPERTIES OUTPUT_NAME "ifcopenshell.geometry.svgfill") +ifcopenshell_wasm_plugin_link_options(svgfill ifcopenshell_register_linework_processing_plugin_v1) add_executable(svgfill_exe src/main.cpp) target_link_libraries(svgfill_exe svgfill) @@ -69,6 +73,8 @@ if(WIN32) target_link_options(svgfill_exe PRIVATE "/NOIMPLIB") endif() +set(linework_processing_libraries svgfill PARENT_SCOPE) + install( TARGETS svgfill_exe svgfill EXPORT ${IFCOPENSHELL_EXPORT_TARGETS} diff --git a/src/svgfill/src/svgfill.cpp b/src/svgfill/src/svgfill.cpp index ed1d725766..d8d1f6d015 100644 --- a/src/svgfill/src/svgfill.cpp +++ b/src/svgfill/src/svgfill.cpp @@ -19,6 +19,7 @@ ****************************************************************************/ #include "svgfill.h" +#include "linework_processing_plugin.h" #include @@ -615,23 +616,32 @@ std::string svgfill::polygons_to_svg(const std::vector& polygons, boo return polygons_to_svg(pps, random_color); } +svgfill::abstract_arrangement* svgfill::create_arrangement(solver s) { + if (s == CARTESIAN_DOUBLE) { + return new cgal_arrangement>; + } else if (s == CARTESIAN_QUOTIENT) { + return new cgal_arrangement>>; + } else if (s == FILTERED_CARTESIAN_QUOTIENT) { + return new cgal_arrangement>>>; + } else if (s == EXACT_PREDICATES) { + return new cgal_arrangement; + } else if (s == EXACT_CONSTRUCTIONS) { + return new cgal_arrangement; + } + return nullptr; +} + +void svgfill::destroy_arrangement(abstract_arrangement* arrangement) { + delete arrangement; +} + void svgfill::context::add(const std::vector& segments) { segments_.insert(segments_.end(), segments.begin(), segments.end()); } bool svgfill::context::build() { - if (solver_ == CARTESIAN_DOUBLE) { - arr_ = new cgal_arrangement>; - } else if (solver_ == CARTESIAN_QUOTIENT) { - arr_ = new cgal_arrangement>>; - } else if (solver_ == FILTERED_CARTESIAN_QUOTIENT) { - arr_ = new cgal_arrangement>>>; - } else if (solver_ == EXACT_PREDICATES) { - arr_ = new cgal_arrangement; - } else if (solver_ == EXACT_CONSTRUCTIONS) { - arr_ = new cgal_arrangement; - } - return (*arr_)(eps_, segments_, progress_); + arr_ = create_arrangement(solver_); + return arr_ && (*arr_)(eps_, segments_, progress_); } void svgfill::context::merge(const std::vector& edge_indices) { @@ -643,3 +653,7 @@ void svgfill::context::write(std::vector>& p) { arr_->write(polygons, progress_); p.push_back(polygons); } + +svgfill::context::~context() { + destroy_arrangement(arr_); +} diff --git a/src/svgfill/src/svgfill.h b/src/svgfill/src/svgfill.h index e7b9028d00..8a84231c76 100644 --- a/src/svgfill/src/svgfill.h +++ b/src/svgfill/src/svgfill.h @@ -105,9 +105,7 @@ namespace svgfill { size_t num_faces() { return arr_->num_faces(); } size_t delete_same_facet_edge_pairs() { return arr_->delete_same_facet_edge_pairs(); } - ~context() { - delete arr_; - } + ~context(); }; SVGFILL_API bool svg_to_line_segments(const std::string& data, const std::optional& class_name, std::vector>& segments); diff --git a/win/build-all-win.py b/win/build-all-win.py index 94cc2329c2..5a04134153 100644 --- a/win/build-all-win.py +++ b/win/build-all-win.py @@ -216,7 +216,7 @@ def archive_executables() -> None: roots = {file} # IfcOpenShell plugins are loaded by name at runtime, so dumpbin cannot discover them. - # svgfill does not require plugins. + # svgfill links its provider plugin directly, so dumpbin can discover that dependency. if not file.name.lower().startswith("svgfill"): roots.update(ifc_runtime_plugins) for plugin in ifc_runtime_plugins: