diff --git a/CMakeLists.txt b/CMakeLists.txt index 49ffd6b52b..e2618d9348 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1043,34 +1043,28 @@ function(orcaslicer_copy_dlls target config postfix output_dlls) ${TOP_LEVEL_PROJECT_DIR}/deps/WebView2/lib/win-${_arch}/WebView2Loader.dll DESTINATION ${_out_dir}) - # Copy EVERY OCCT DLL the deps build produced. Do NOT hand-maintain an explicit - # list here: it silently drifts from what libslic3r links (src/libslic3r OCCT_LIBS) - # and their transitive OCCT deps, yielding a portable/installer that fails at launch - # with "OrcaSlicer.dll error 126 (dependency not found)" — e.g. missing TKFillet/ - # TKOffset/TKBool/TKFeat. Glob everything instead; the built occt/ dir is the one - # source of truth. (OCCT is Shared only on Windows — deps/OCCT/OCCT.cmake.) - file(GLOB _occt_dlls "${CMAKE_PREFIX_PATH}/bin/occt/*.dll") - # The glob degrades silently: it ships whatever the deps prefix holds. That is not the - # same as shipping what we link. A deps tree built with BUILD_MODULE_ModelingAlgorithms=OFF - # (upstream OrcaSlicer's setting) simply has no TKFillet.dll / TKOffset.dll, so the glob - # copies 40 of 42 DLLs, the build succeeds, and the slicer dies at launch with - # "error 126 (dependency not found)". The explicit per-file list this replaced failed - # the configure instead. Assert the real invariant: every linked toolkit has a DLL. + # Stage the OCCT toolkits libslic3r links (published as OCCT_LIBS), not whatever the + # deps prefix happens to hold, and fail the configure if one of them is missing. if (NOT OCCT_LIBS) message(FATAL_ERROR "OCCT_LIBS is not set; libslic3r must be configured first.") endif () + set(_occt_bin "${CMAKE_PREFIX_PATH}/bin/occt") + set(_occt_dlls "") + set(_occt_staged "") set(_missing_occt "") foreach (_tk IN LISTS OCCT_LIBS) - if (NOT EXISTS "${CMAKE_PREFIX_PATH}/bin/occt/${_tk}.dll") + if (EXISTS "${_occt_bin}/${_tk}.dll") + list(APPEND _occt_dlls "${_occt_bin}/${_tk}.dll") + list(APPEND _occt_staged "${_out_dir}/${_tk}.dll") + else () list(APPEND _missing_occt "${_tk}.dll") endif () endforeach () if (_missing_occt) message(FATAL_ERROR - "OCCT DLLs missing from ${CMAKE_PREFIX_PATH}/bin/occt/: ${_missing_occt}\n" - "Rebuild the dependencies (build_release_vs2022.bat deps). This fork sets " - "BUILD_MODULE_ModelingAlgorithms=ON, so a deps tree built from upstream " - "OrcaSlicer lacks TKFillet/TKOffset and the slicer would fail at startup.") + "OCCT DLLs missing from ${_occt_bin}/: ${_missing_occt}\n" + "Rebuild the dependencies (build_release_vs2022.bat deps) with the same " + "SLIC3R_CAD setting as this project.") endif () file(COPY ${_occt_dlls} ${CMAKE_PREFIX_PATH}/bin/freetype.dll @@ -1083,9 +1077,6 @@ function(orcaslicer_copy_dlls target config postfix output_dlls) ${_out_dir}/freetype.dll ) - # Mirror every OCCT DLL staged above (all OpenCASCADE toolkits are named TK*) into - # the install/portable manifest, so this list can never drift from what was copied. - file(GLOB _occt_staged "${_out_dir}/TK*.dll") list(APPEND _dll_list ${_occt_staged}) set(${output_dlls} ${_dll_list} PARENT_SCOPE) diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index 3ec9c4d06a..c253d5a024 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -55,6 +55,7 @@ endif () set(DEP_DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/DL_CACHE CACHE PATH "Path for downloaded source packages.") set(FLATPAK FALSE CACHE BOOL "Toggles various build settings for flatpak, like /usr/local in DESTDIR or not building wxwidgets") +option(SLIC3R_CAD "Build the SolveSpace solver and OCCT ModelingAlgorithms module the parametric Design/CAD tab needs. Must match the main project's SLIC3R_CAD." ON) if ("${DESTDIR}" STREQUAL "" OR "${DESTDIR}" STREQUAL "${AUTOGENERATED_DESTDIR}") if (LINUX AND (NOT DEFINED USE_OLD_DESTDIR_PREV OR USE_OLD_DESTDIR_PREV) AND EXISTS "${CMAKE_BINARY_DIR}/destdir/usr/local" AND NOT EXISTS "${CMAKE_BINARY_DIR}/OrcaSlicer_dep/usr/local") @@ -350,7 +351,11 @@ include(GLEW/GLEW.cmake) include(GLFW/GLFW.cmake) include(OpenCSG/OpenCSG.cmake) -include(SLVS/SLVS.cmake) +set(SLVS_PKG "") +if (SLIC3R_CAD) + include(SLVS/SLVS.cmake) + set(SLVS_PKG dep_SLVS) +endif () include(TBB/TBB.cmake) @@ -440,7 +445,7 @@ set(_dep_list dep_NLopt dep_OpenVDB dep_OpenCSG - dep_SLVS + ${SLVS_PKG} dep_OpenCV dep_Eigen dep_CGAL diff --git a/deps/OCCT/OCCT.cmake b/deps/OCCT/OCCT.cmake index 16337f4276..696548d440 100644 --- a/deps/OCCT/OCCT.cmake +++ b/deps/OCCT/OCCT.cmake @@ -4,8 +4,9 @@ else() set(library_build_type "Static") endif() -# The parametric Design/CAD tab is the only consumer of OCCT's ModelingAlgorithms -# module (fillet/offset/loft). With it OFF the deps prefix matches upstream exactly. +# SLIC3R_CAD (declared in deps/CMakeLists.txt) builds OCCT's ModelingAlgorithms module +# (fillet/offset/loft), whose only consumer is the parametric Design/CAD tab. With it OFF +# the deps prefix matches upstream exactly. # # With it ON the delta is THREE toolkits, not two: TKFillet (7.40 MiB archive, used via # BRepFilletAPI), TKOffset (5.38 MiB, used via BRepOffsetAPI) and TKFeat (4.42 MiB), which @@ -17,9 +18,6 @@ endif() # shipped bytes. The Windows figure is a real DLL cost and has NOT been measured -- an # earlier "3.77 MiB, Windows only" note here covered only two of the three toolkits and is # not a number to quote. See docs/cad_dependency_weight.md. -# -# Must match the SLIC3R_CAD passed to the main project. -option(SLIC3R_CAD "Build OCCT's ModelingAlgorithms module (required by the Design/CAD tab)" ON) if (IN_GIT_REPO) set(OCCT_DIRECTORY_FLAG --directory ${BINARY_DIR_REL}/dep_OCCT-prefix/src/dep_OCCT) diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index b00834e9f0..a47ecff1b5 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -310,12 +310,14 @@ void AppConfig::set_defaults() if (get("zoom_to_mouse").empty()) set_bool("zoom_to_mouse", false); +#ifdef SLIC3R_CAD // Design tab: draw a mate connector as a face rather than as the abstract disc + roll // quadrant. Defaults ON — face orientation is hardwired perception, so the roll and the // verse read without being learned, which no abstract glyph achieves. Turning it off // restores the conventional CAD representation for users who expect it (snaporca-x0kd). if (get("design_connector_face_glyph").empty()) set_bool("design_connector_face_glyph", true); +#endif //#ifdef SUPPORT_SHOW_HINTS if (get("show_hints").empty()) diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index f7d19efb0e..80cf080bf4 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -604,7 +604,6 @@ find_package(JPEG REQUIRED) find_package(Draco REQUIRED) set(OCCT_LIBS - TKBool TKXDESTEP TKSTEP TKSTEP209 @@ -632,23 +631,29 @@ set(OCCT_LIBS TKMath TKernel ) -# The CAD kernel is the only consumer of OCCT's ModelingAlgorithms module. Upstream's -# DataExchange already pulls TKBool in transitively, so the true delta is these two. +# The CAD kernel is the only consumer of OCCT's ModelingAlgorithms module: TKFillet +# (BRepFilletAPI), TKOffset (BRepOffsetAPI) and TKBool, which the other two need. # # PREPEND, never append: this list is single-pass static link order, dependents before # dependencies — note TKernel, which everything needs, is deliberately last. TKOffset # references BRepAlgo_Loop, which TKBool defines, so TKOffset must come BEFORE TKBool. -# Appending put it after, and the Snapmaker fork's Flatpak build — the one configuration -# whose linker is strictly single-pass — failed with +# Appending put it after, and a strictly single-pass linker (the Flatpak build) failed with # libTKOffset.a(BRepOffset_MakeLoops.cxx.o): undefined reference to # `BRepAlgo_Loop::BRepAlgo_Loop()' # while the ordinary Linux, macOS and Windows links resolved it anyway. Use set() rather # than list(PREPEND), which needs CMake 3.15 and this project supports 3.13. if (SLIC3R_CAD) - set(OCCT_LIBS TKFillet TKOffset ${OCCT_LIBS}) + set(OCCT_LIBS TKFillet TKOffset TKBool ${OCCT_LIBS}) + # deps is configured separately, so its SLIC3R_CAD can differ from ours. The module is + # all-or-nothing, so one absent toolkit proves it; fail here rather than at link time. + if (NOT TARGET TKFillet) + message(FATAL_ERROR + "SLIC3R_CAD is ON, but the OpenCASCADE in ${CMAKE_PREFIX_PATH} was built without " + "BUILD_MODULE_ModelingAlgorithms. Rebuild the dependencies with -DSLIC3R_CAD=ON, " + "or configure this project with -DSLIC3R_CAD=OFF.") + endif () endif () -# Publish the link list so the Windows packaging step can assert it ships a DLL for -# every toolkit we link, instead of shipping whatever the deps prefix happens to hold. +# Published for the Windows packaging step in the top-level CMakeLists.txt. set(OCCT_LIBS "${OCCT_LIBS}" CACHE INTERNAL "OCCT toolkits linked by libslic3r") target_link_libraries(libslic3r diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index db758f6dc3..e1ef82bc68 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -1817,11 +1817,13 @@ void PreferencesDialog::create_items() auto reverse_mouse_zoom = create_item_checkbox(_L("Reverse mouse zoom"), _L("If enabled, reverses the direction of zoom with mouse wheel."), "reverse_mouse_wheel_zoom"); g_sizer->Add(reverse_mouse_zoom); +#ifdef SLIC3R_CAD auto item_connector_face_glyph = create_item_checkbox(_L("Draw mate connectors as a face"), _L("In the Design tab, draw a mate connector as a small face instead of the conventional " "disc with a roll quadrant. A face's orientation is read without being learned. " "Turn this off for the conventional CAD representation."), "design_connector_face_glyph"); g_sizer->Add(item_connector_face_glyph); +#endif std::vector ButtonDragActions = {_L("None"), _L("Pan"), _L("Rotate")}; auto item_left_mouse_drag = create_item_combobox(_L("Left Mouse Drag"), _L("Set the action that dragging the left mouse button should perform."), "left_mouse_drag_action", ButtonDragActions);