From b3fbcd6a66cbbdf24fe06ad22d46f4e2c5fd3a9e Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Thu, 4 Jun 2026 13:25:28 +1000 Subject: [PATCH] refactor: extract src/ifcutil/ from src/ifcviewer/ (Unit, Geolocation, Placement) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unit / Geolocation / Placement are schema-agnostic IFC helpers ported from ifcopenshell.util.{unit,geolocation,placement}. Nothing about them is viewer-specific: pure IfcParse + Eigen, no Qt, no IfcGeom, no renderer. Living under src/ifcviewer/ implies an unwanted dependency direction every time a non-viewer caller (test_federation, the bonsai SettingsView georef readout, a future standalone IFC tool) wants to use them. Move them to a new `src/ifcutil/` static lib (IfcUtil). The lib has PUBLIC `target_include_directories(${CMAKE_CURRENT_SOURCE_DIR})` so callers that link IfcUtil can keep `#include "Unit.h"` etc. without relative-path adjustments — the include dir propagates transitively via IfcViewer's PUBLIC link. ## Changes * `git mv src/ifcviewer/{Geolocation,Placement,Unit}.{h,cpp} → src/ifcutil/` (history follows the rename). * `src/ifcutil/CMakeLists.txt`: IfcUtil static lib, PUBLIC links IfcParse + Eigen3::Eigen, PUBLIC include dir. * `cmake/CMakeLists.txt`: `add_subdirectory(../src/ifcutil ifcutil)` before ifcviewer/ so the link target exists when IfcViewer's CMakeLists runs. * `src/ifcviewer/CMakeLists.txt`: IfcUtil added to IfcViewer's PUBLIC link_libraries. * `src/ifcviewer/tests/CMakeLists.txt`: test_federation drops the explicit `${IFCVIEWER_SRC}/{Unit,Geolocation,Placement}.cpp` source list and links `IfcUtil` instead (matches how production code resolves the symbols). * `src/bonsaiviewer/modules/models/SettingsView.cpp`: the two explicit `#include "../../../ifcviewer/{Geolocation,Unit}.h"` paths swap to `../../../ifcutil/…`. All other callers use bare `#include "Unit.h"` style and continue to work via the propagated include dir. ## Verification * `ninja -C build-viewer` builds clean: IfcUtil + IfcViewer + IfcViewerMinimal + BonsaiViewer + all four pre-existing ifcviewer tests + the two from-wgpu tests. * `test_federation` runs green: 226 assertions in 22 test cases pass with IfcUtil linked instead of the explicit-source compile. * `git log --follow` traces e.g. `Geolocation.cpp` back through the rename to its prior location in src/ifcviewer/. Co-Authored-By: Claude Opus 4.7 --- cmake/CMakeLists.txt | 5 ++ .../modules/models/SettingsView.cpp | 4 +- src/ifcutil/CMakeLists.txt | 60 +++++++++++++++++++ src/{ifcviewer => ifcutil}/Geolocation.cpp | 0 src/{ifcviewer => ifcutil}/Geolocation.h | 0 src/{ifcviewer => ifcutil}/Placement.cpp | 0 src/{ifcviewer => ifcutil}/Placement.h | 0 src/{ifcviewer => ifcutil}/Unit.cpp | 0 src/{ifcviewer => ifcutil}/Unit.h | 0 src/ifcviewer/CMakeLists.txt | 1 + src/ifcviewer/tests/CMakeLists.txt | 16 ++--- 11 files changed, 74 insertions(+), 12 deletions(-) create mode 100644 src/ifcutil/CMakeLists.txt rename src/{ifcviewer => ifcutil}/Geolocation.cpp (100%) rename src/{ifcviewer => ifcutil}/Geolocation.h (100%) rename src/{ifcviewer => ifcutil}/Placement.cpp (100%) rename src/{ifcviewer => ifcutil}/Placement.h (100%) rename src/{ifcviewer => ifcutil}/Unit.cpp (100%) rename src/{ifcviewer => ifcutil}/Unit.h (100%) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 1ccb4931e9..85b6c37eb1 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -700,6 +700,11 @@ if(BUILD_BONSAIVIEWER_TESTS) endif() if(BUILD_BONSAIVIEWER) + # IfcUtil first — schema-agnostic helpers (Unit, Geolocation, + # Placement) that IfcViewer's Federation links against. Adding here + # before ifcviewer/ so the link target exists when IfcViewer's + # CMakeLists runs. + add_subdirectory(../src/ifcutil ifcutil) # IfcViewer is the unified scene + render lib since the wgpu/ifcviewer # merge — wgpu-native is fetched inside its CMakeLists.txt. add_subdirectory(../src/ifcviewer ifcviewer) diff --git a/src/bonsaiviewer/modules/models/SettingsView.cpp b/src/bonsaiviewer/modules/models/SettingsView.cpp index 2428a39a7d..31ef07f973 100644 --- a/src/bonsaiviewer/modules/models/SettingsView.cpp +++ b/src/bonsaiviewer/modules/models/SettingsView.cpp @@ -23,9 +23,9 @@ #include "../../SessionState.h" #include "../../../ifcviewer/Federation.h" -#include "../../../ifcviewer/Geolocation.h" +#include "../../../ifcutil/Geolocation.h" #include "../../../ifcviewer/SceneLoader.h" -#include "../../../ifcviewer/Unit.h" +#include "../../../ifcutil/Unit.h" #include diff --git a/src/ifcutil/CMakeLists.txt b/src/ifcutil/CMakeLists.txt new file mode 100644 index 0000000000..cea59f6993 --- /dev/null +++ b/src/ifcutil/CMakeLists.txt @@ -0,0 +1,60 @@ +################################################################################ +# # +# This file is part of IfcOpenShell. # +# # +# IfcOpenShell is free software: you can redistribute it and/or modify # +# it under the terms of the Lesser GNU General Public License as published by # +# the Free Software Foundation, either version 3.0 of the License, or # +# (at your option) any later version. # +# # +# IfcOpenShell is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# Lesser GNU General Public License for more details. # +# # +# You should have received a copy of the Lesser GNU General Public License # +# along with this program. If not, see . # +# # +################################################################################ + +message("Running CMakeLists.txt in /src/ifcutil") + +# Schema-agnostic IFC helpers ported from ifcopenshell.util.*. Pure +# IfcParse + Eigen, no Qt, no IfcGeom, no viewer/renderer deps — so unit +# tests and standalone IFC tools can pull them in without dragging +# OpenCASCADE or Qt6 into the link. +# +# Currently: +# * Unit — unit conversions (ifcopenshell.util.unit) +# * Geolocation — IfcMapConversion / WCS / helmert helpers +# (ifcopenshell.util.geolocation) +# * Placement — IfcLocalPlacement / IfcAxis2Placement reduction +# (ifcopenshell.util.placement) + +find_package(Eigen3 REQUIRED) + +file(GLOB IFCUTIL_CPP_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) +file(GLOB IFCUTIL_H_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.h) + +add_library(IfcUtil STATIC ${IFCUTIL_CPP_FILES} ${IFCUTIL_H_FILES}) + +set_target_properties(IfcUtil PROPERTIES + VERSION "${PROJECT_VERSION}" + SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}" +) + +# PUBLIC: callers (IfcViewer, test_federation, future tools) get +# `#include "Unit.h"` etc. via this directory automatically, no +# `#include "../ifcutil/Unit.h"` ugliness at call sites. +target_include_directories(IfcUtil PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +target_link_libraries(IfcUtil PUBLIC + IfcParse + Eigen3::Eigen +) + +install(TARGETS IfcUtil EXPORT ${IFCOPENSHELL_EXPORT_TARGETS}) + +install(FILES ${IFCUTIL_H_FILES} + DESTINATION ${INCLUDEDIR}/ifcutil +) diff --git a/src/ifcviewer/Geolocation.cpp b/src/ifcutil/Geolocation.cpp similarity index 100% rename from src/ifcviewer/Geolocation.cpp rename to src/ifcutil/Geolocation.cpp diff --git a/src/ifcviewer/Geolocation.h b/src/ifcutil/Geolocation.h similarity index 100% rename from src/ifcviewer/Geolocation.h rename to src/ifcutil/Geolocation.h diff --git a/src/ifcviewer/Placement.cpp b/src/ifcutil/Placement.cpp similarity index 100% rename from src/ifcviewer/Placement.cpp rename to src/ifcutil/Placement.cpp diff --git a/src/ifcviewer/Placement.h b/src/ifcutil/Placement.h similarity index 100% rename from src/ifcviewer/Placement.h rename to src/ifcutil/Placement.h diff --git a/src/ifcviewer/Unit.cpp b/src/ifcutil/Unit.cpp similarity index 100% rename from src/ifcviewer/Unit.cpp rename to src/ifcutil/Unit.cpp diff --git a/src/ifcviewer/Unit.h b/src/ifcutil/Unit.h similarity index 100% rename from src/ifcviewer/Unit.h rename to src/ifcutil/Unit.h diff --git a/src/ifcviewer/CMakeLists.txt b/src/ifcviewer/CMakeLists.txt index ea97fa4a4a..f284dd2d82 100644 --- a/src/ifcviewer/CMakeLists.txt +++ b/src/ifcviewer/CMakeLists.txt @@ -140,6 +140,7 @@ target_include_directories(IfcViewer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) add_dependencies(IfcViewer ${kernel_libraries} ${mapping_libraries}) target_link_libraries(IfcViewer PUBLIC + IfcUtil IfcGeom IfcParse ${OpenCASCADE_LIBRARIES} diff --git a/src/ifcviewer/tests/CMakeLists.txt b/src/ifcviewer/tests/CMakeLists.txt index 6a71821c8f..d349803b33 100644 --- a/src/ifcviewer/tests/CMakeLists.txt +++ b/src/ifcviewer/tests/CMakeLists.txt @@ -66,15 +66,6 @@ find_package(Eigen3 REQUIRED) add_executable(test_federation test_federation.cpp ${IFCVIEWER_SRC}/Federation.cpp - # Federation pulls in Unit::convert for federationUnitToMeters and - # Geolocation helpers (helmertMetersFromParameters, getWcs, getMapUnit) - # for computeModelGeoref; compile both directly so the test doesn't - # have to link the whole IfcViewer library (which would drag in - # Qt6::OpenGL, OpenCASCADE, etc.). Placement.cpp provides - # getAxis2Placement, called from Geolocation::getWcs. - ${IFCVIEWER_SRC}/Unit.cpp - ${IFCVIEWER_SRC}/Geolocation.cpp - ${IFCVIEWER_SRC}/Placement.cpp ) set_target_properties(test_federation PROPERTIES AUTOMOC ON) target_include_directories(test_federation PRIVATE ${IFCVIEWER_SRC}) @@ -84,6 +75,11 @@ target_link_libraries(test_federation PRIVATE Qt${QT_VERSION}::Gui # Federation::HomeView uses QVector3D from QtGui Qt${QT_VERSION}::Test # QSignalSpy Eigen3::Eigen # Federation.h: composed matrices use Eigen - IfcParse # Unit.cpp uses express::Base / file APIs + # IfcUtil provides Unit::convert + Geolocation helpers + # (helmertMetersFromParameters, getWcs, getMapUnit) + Placement + # (getAxis2Placement, called from Geolocation::getWcs). Linking the + # static lib avoids re-compiling those .cpp files here and pulls + # the IfcUtil include dir + IfcParse transitively. + IfcUtil ) catch_discover_tests(test_federation)