From 95a231d02411903e70d65f75c2973f692c9f8782 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Sun, 23 Nov 2025 10:36:38 +0300 Subject: [PATCH 01/56] build-test-linux-vcpkg: remove skip_mrbind --- .github/workflows/build-test-linux-vcpkg.yml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build-test-linux-vcpkg.yml b/.github/workflows/build-test-linux-vcpkg.yml index eaa930893832..20c16c1e542e 100644 --- a/.github/workflows/build-test-linux-vcpkg.yml +++ b/.github/workflows/build-test-linux-vcpkg.yml @@ -74,7 +74,6 @@ jobs: os: ubuntu-24.04-arm - arch: arm64 compiler: GCC 11 - skip_mrbind: true # GCC + ARM64 build has unresolved problems permissions: id-token: write # This is required for requesting the JWT contents: read # This is required for actions/checkout @@ -121,7 +120,7 @@ jobs: git submodule update --init --recursive --depth 1 thirdparty/imgui thirdparty/mrbind-pybind11 thirdparty/mrbind - name: Install MRBind - if: ${{ (inputs.mrbind || inputs.mrbind_c) && !matrix.skip_mrbind }} + if: ${{ inputs.mrbind || inputs.mrbind_c }} run: scripts/mrbind/install_mrbind_rockylinux.sh - name: Create virtualenv @@ -136,7 +135,7 @@ jobs: run: python3 -m pip install -r ./requirements/python.txt - name: Generate C bindings - if: ${{ inputs.mrbind_c && !matrix.skip_mrbind }} + if: ${{ inputs.mrbind_c }} env: CXX: ${{ matrix.cxx-compiler }} run: make -f scripts/mrbind/generate.mk -B --trace TARGET=c DEPS_BASE_DIR=/opt/vcpkg/installed/${{ matrix.arch }}-linux-meshlib CXX_FOR_BINDINGS=/usr/bin/clang++ @@ -154,11 +153,11 @@ jobs: -DMR_CXX_STANDARD=${{ matrix.cxx-standard }} -DMR_PCH_USE_EXTRA_HEADERS=ON -DCMAKE_CUDA_HOST_COMPILER=/opt/rh/gcc-toolset-11/root/usr/bin/g++ - -DMESHLIB_BUILD_GENERATED_C_BINDINGS=${{ fromJSON('["OFF", "ON"]')[inputs.mrbind_c && !matrix.skip_mrbind] }} + -DMESHLIB_BUILD_GENERATED_C_BINDINGS=${{ fromJSON('["OFF", "ON"]')[inputs.mrbind_c] }} -DMRVIEWER_NO_GTK=ON - name: Generate and build Python bindings - if: ${{ inputs.mrbind && !matrix.skip_mrbind }} + if: ${{ inputs.mrbind }} env: CXX: ${{ matrix.cxx-compiler }} run: make -f scripts/mrbind/generate.mk MODE=none -B --trace MESHLIB_SHLIB_DIR=build/${{matrix.config}}/bin CXX_FOR_BINDINGS=/usr/bin/clang++ DEPS_BASE_DIR=/opt/vcpkg/installed/${{ matrix.arch }}-linux-meshlib @@ -178,27 +177,27 @@ jobs: run: xvfb-run -a ./build/${{ matrix.config }}/bin/MeshViewer -hidden -noEventLoop -unloadPluginsAtEnd - name: Unit Tests - run: ./build/${{ matrix.config }}/bin/MRTest ${{ matrix.skip_mrbind && '--no-python-tests' || '' }} + run: ./build/${{ matrix.config }}/bin/MRTest - name: C Unit Tests (old bindings) run: ./build/${{ matrix.config }}/bin/MRTestC - name: C Unit Tests - if: ${{ inputs.mrbind_c && !matrix.skip_mrbind }} + if: ${{ inputs.mrbind_c }} run: ./build/${{ matrix.config }}/bin/MRTestC2 - name: Python Sanity Tests - if: ${{ inputs.mrbind && !matrix.skip_mrbind }} + if: ${{ inputs.mrbind }} timeout-minutes: 8 working-directory: ./build/${{ matrix.config }}/bin run: python3 ./../../../scripts/run_python_test_script.py -d '../test_python' - name: Python Regression Tests - if: ${{ inputs.internal_build && inputs.mrbind && !matrix.skip_mrbind }} + if: ${{ inputs.internal_build && inputs.mrbind }} uses: ./.github/actions/python-regression-tests with: build_config: ${{ matrix.config }} - mrbind: ${{ inputs.mrbind && !matrix.skip_mrbind }} + mrbind: ${{ inputs.mrbind }} pytest_args: "--run-cuda=negative" smoke: ${{ !inputs.full_config_build && matrix.config == 'Debug' }} test_artifacts_path: linux-vcpkg-${{ matrix.arch }}/${{ matrix.config }}/${{ matrix.compiler }} From 4f61b4d2bd275849c05b07b8298d1dfdb311f95d Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Sun, 23 Nov 2025 20:24:57 +0300 Subject: [PATCH 02/56] debug logging --- source/MRMesh/MRICP.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 2cbd12f83a2c..fb2a315bb06d 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -7,6 +7,7 @@ #include "MRQuaternion.h" #include "MRBestFit.h" #include "MRBitSetParallelFor.h" +#include "MRStreamOperators.h" #include namespace MR @@ -117,6 +118,8 @@ void ICP::updatePointPairs() MR::updatePointPairs( flt2refPairs_, flt_, ref_, prop_.cosThreshold, prop_.distThresholdSq, prop_.mutualClosest ); MR::updatePointPairs( ref2fltPairs_, ref_, flt_, prop_.cosThreshold, prop_.distThresholdSq, prop_.mutualClosest ); deactivatefarDistPairs_(); + std::cout << "flt2refPairs_.active=" << MR::getNumActivePairs( flt2refPairs_ ) << std::endl; + std::cout << "ref2fltPairs_.active=" << MR::getNumActivePairs( ref2fltPairs_ ) << std::endl; } std::string getICPStatusInfo( int iterations, ICPExitType exitType ) @@ -378,15 +381,32 @@ bool ICP::p2plIter_() AffineXf3f ICP::calculateTransformation() { + std::cout << "method=" << (int)prop_.method << '\n'; + std::cout << "p2plAngleLimit=" << prop_.p2plAngleLimit << '\n'; + std::cout << "p2plScaleLimit=" << prop_.p2plScaleLimit << '\n'; + std::cout << "cosThreshold=" << prop_.cosThreshold << '\n'; + std::cout << "distThresholdSq=" << prop_.distThresholdSq << '\n'; + std::cout << "farDistFactor=" << prop_.farDistFactor << '\n'; + std::cout << "icpMode=" << (int)prop_.icpMode << '\n'; + std::cout << "fixedRotationAxis=" << prop_.fixedRotationAxis << '\n'; + std::cout << "iterLimit=" << prop_.iterLimit << '\n'; + std::cout << "badIterStopCount=" << prop_.badIterStopCount << '\n'; + std::cout << "exitVal=" << prop_.exitVal << '\n'; + std::cout << "mutualClosest=" << prop_.mutualClosest << std::endl; + float minDist = std::numeric_limits::max(); int badIterCount = 0; resultType_ = ICPExitType::MaxIterations; AffineXf3f resXf = flt_.xf; for ( iter_ = 1; iter_ <= prop_.iterLimit; ++iter_ ) { + std::cout << "Iter #" << iter_ << '\n'; + std::cout << "ref_.xf:\n" << ref_.xf << '\n'; + std::cout << "flt_.xf:\n" << flt_.xf << std::endl; updatePointPairs(); const bool pt2pt = ( prop_.method == ICPMethod::Combined && iter_ < 3 ) || prop_.method == ICPMethod::PointToPoint; + std::cout << "pt2pt=" << pt2pt << std::endl; if ( iter_ == 1 ) minDist = pt2pt ? getMeanSqDistToPoint() : getMeanSqDistToPlane(); // update initial metric before doing iteration @@ -398,6 +418,7 @@ AffineXf3f ICP::calculateTransformation() } const float curDist = pt2pt ? getMeanSqDistToPoint() : getMeanSqDistToPlane(); + std::cout << "curDist=" << curDist << std::endl; // exit if several(3) iterations didn't decrease minimization parameter if (curDist < minDist) From 7991f2036f391a5d2ac5b6168f38fcc7abf9b9de Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Sun, 23 Nov 2025 21:08:17 +0300 Subject: [PATCH 03/56] #include --- source/MRMesh/MRICP.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index fb2a315bb06d..ab9a2e96aa49 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -9,6 +9,7 @@ #include "MRBitSetParallelFor.h" #include "MRStreamOperators.h" #include +#include namespace MR { From b99742ac572a25f5fa280ba0f2cf636d7fbfb93b Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Sun, 23 Nov 2025 22:00:01 +0300 Subject: [PATCH 04/56] log minDist --- source/MRMesh/MRICP.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index ab9a2e96aa49..d2da48044aba 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -410,7 +410,10 @@ AffineXf3f ICP::calculateTransformation() std::cout << "pt2pt=" << pt2pt << std::endl; if ( iter_ == 1 ) + { minDist = pt2pt ? getMeanSqDistToPoint() : getMeanSqDistToPlane(); // update initial metric before doing iteration + std::cout << "minDist0=" << minDist << std::endl; + } if ( !( pt2pt ? p2ptIter_() : p2plIter_() ) ) { @@ -426,6 +429,7 @@ AffineXf3f ICP::calculateTransformation() { resXf = flt_.xf; minDist = curDist; + std::cout << "minDist=" << minDist << std::endl; badIterCount = 0; if ( prop_.exitVal > curDist ) @@ -444,6 +448,8 @@ AffineXf3f ICP::calculateTransformation() badIterCount++; } } + std::cout << "final minDist=" << minDist << std::endl; + std::cout << "resXf:\n" << resXf << std::endl; flt_.xf = resXf; return resXf; } From be658e9a6af294869ae38096c0a7eec88ad7aca2 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Mon, 24 Nov 2025 10:18:10 +0300 Subject: [PATCH 05/56] updatePointPairs before getMeanSqDistToPoint() --- source/MRMesh/MRICP.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index d2da48044aba..22e66a3f5e9e 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -395,31 +395,30 @@ AffineXf3f ICP::calculateTransformation() std::cout << "exitVal=" << prop_.exitVal << '\n'; std::cout << "mutualClosest=" << prop_.mutualClosest << std::endl; - float minDist = std::numeric_limits::max(); + bool pt2pt = prop_.method == ICPMethod::Combined || prop_.method == ICPMethod::PointToPoint; + updatePointPairs(); + float minDist = pt2pt ? getMeanSqDistToPoint() : getMeanSqDistToPlane(); + std::cout << "minDist0=" << minDist << std::endl; + int badIterCount = 0; resultType_ = ICPExitType::MaxIterations; AffineXf3f resXf = flt_.xf; + for ( iter_ = 1; iter_ <= prop_.iterLimit; ++iter_ ) { std::cout << "Iter #" << iter_ << '\n'; std::cout << "ref_.xf:\n" << ref_.xf << '\n'; std::cout << "flt_.xf:\n" << flt_.xf << std::endl; - updatePointPairs(); - const bool pt2pt = ( prop_.method == ICPMethod::Combined && iter_ < 3 ) + pt2pt = ( prop_.method == ICPMethod::Combined && iter_ < 3 ) || prop_.method == ICPMethod::PointToPoint; std::cout << "pt2pt=" << pt2pt << std::endl; - if ( iter_ == 1 ) - { - minDist = pt2pt ? getMeanSqDistToPoint() : getMeanSqDistToPlane(); // update initial metric before doing iteration - std::cout << "minDist0=" << minDist << std::endl; - } - if ( !( pt2pt ? p2ptIter_() : p2plIter_() ) ) { resultType_ = ICPExitType::NotFoundSolution; break; } + updatePointPairs(); const float curDist = pt2pt ? getMeanSqDistToPoint() : getMeanSqDistToPlane(); std::cout << "curDist=" << curDist << std::endl; From 7a57e8efb0cf6064db87891f8c3b7a1b7ceadbae Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Mon, 24 Nov 2025 11:48:57 +0300 Subject: [PATCH 06/56] spdlog --- source/MRMesh/MRICP.cpp | 51 +++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 22e66a3f5e9e..1969998627cc 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -8,8 +8,8 @@ #include "MRBestFit.h" #include "MRBitSetParallelFor.h" #include "MRStreamOperators.h" +#include "MRPch/MRSpdlog.h" #include -#include namespace MR { @@ -380,25 +380,32 @@ bool ICP::p2plIter_() return true; } +static void logXf( const char* var, const AffineXf3f& xf ) +{ + spdlog::info( "{} x: {} {} {} {}\n", var, xf.A.x.x, xf.A.x.y, xf.A.x.z, xf.b.x ); + spdlog::info( "{} y: {} {} {} {}\n", var, xf.A.y.x, xf.A.y.y, xf.A.y.z, xf.b.y ); + spdlog::info( "{} z: {} {} {} {}\n", var, xf.A.z.x, xf.A.z.y, xf.A.z.z, xf.b.z ); +} + AffineXf3f ICP::calculateTransformation() { - std::cout << "method=" << (int)prop_.method << '\n'; - std::cout << "p2plAngleLimit=" << prop_.p2plAngleLimit << '\n'; - std::cout << "p2plScaleLimit=" << prop_.p2plScaleLimit << '\n'; - std::cout << "cosThreshold=" << prop_.cosThreshold << '\n'; - std::cout << "distThresholdSq=" << prop_.distThresholdSq << '\n'; - std::cout << "farDistFactor=" << prop_.farDistFactor << '\n'; - std::cout << "icpMode=" << (int)prop_.icpMode << '\n'; - std::cout << "fixedRotationAxis=" << prop_.fixedRotationAxis << '\n'; - std::cout << "iterLimit=" << prop_.iterLimit << '\n'; - std::cout << "badIterStopCount=" << prop_.badIterStopCount << '\n'; - std::cout << "exitVal=" << prop_.exitVal << '\n'; - std::cout << "mutualClosest=" << prop_.mutualClosest << std::endl; + spdlog::info( "method = {}\n", ( int )prop_.method ); + spdlog::info( "p2plAngleLimit = {}\n", prop_.p2plAngleLimit ); + spdlog::info( "p2plScaleLimit = {}\n", prop_.p2plScaleLimit ); + spdlog::info( "cosThreshold = {}\n", prop_.cosThreshold ); + spdlog::info( "distThresholdSq = {}\n", prop_.distThresholdSq ); + spdlog::info( "farDistFactor = {}\n", prop_.farDistFactor ); + spdlog::info( "icpMode = {}\n", (int)prop_.icpMode ); + spdlog::info( "fixedRotationAxis = {} {} {}\n", prop_.fixedRotationAxis.x, prop_.fixedRotationAxis.y, prop_.fixedRotationAxis.z ); + spdlog::info( "iterLimit = {}\n", prop_.iterLimit ); + spdlog::info( "badIterStopCount = {}\n", prop_.badIterStopCount ); + spdlog::info( "exitVal = {}\n", prop_.exitVal ); + spdlog::info( "mutualClosest = {}\n", prop_.mutualClosest ); bool pt2pt = prop_.method == ICPMethod::Combined || prop_.method == ICPMethod::PointToPoint; updatePointPairs(); float minDist = pt2pt ? getMeanSqDistToPoint() : getMeanSqDistToPlane(); - std::cout << "minDist0=" << minDist << std::endl; + spdlog::info( "minDist0 = {}\n", minDist ); int badIterCount = 0; resultType_ = ICPExitType::MaxIterations; @@ -406,12 +413,12 @@ AffineXf3f ICP::calculateTransformation() for ( iter_ = 1; iter_ <= prop_.iterLimit; ++iter_ ) { - std::cout << "Iter #" << iter_ << '\n'; - std::cout << "ref_.xf:\n" << ref_.xf << '\n'; - std::cout << "flt_.xf:\n" << flt_.xf << std::endl; + spdlog::info( "Iter #{}\n", iter_ ); + logXf( "ref_.xf", ref_.xf ); + logXf( "flt_.xf", flt_.xf ); pt2pt = ( prop_.method == ICPMethod::Combined && iter_ < 3 ) || prop_.method == ICPMethod::PointToPoint; - std::cout << "pt2pt=" << pt2pt << std::endl; + spdlog::info( "pt2pt = {}\n", pt2pt ); if ( !( pt2pt ? p2ptIter_() : p2plIter_() ) ) { @@ -421,14 +428,14 @@ AffineXf3f ICP::calculateTransformation() updatePointPairs(); const float curDist = pt2pt ? getMeanSqDistToPoint() : getMeanSqDistToPlane(); - std::cout << "curDist=" << curDist << std::endl; + spdlog::info( "curDist = {}\n", curDist ); // exit if several(3) iterations didn't decrease minimization parameter if (curDist < minDist) { resXf = flt_.xf; minDist = curDist; - std::cout << "minDist=" << minDist << std::endl; + spdlog::info( "minDist = {}\n", minDist ); badIterCount = 0; if ( prop_.exitVal > curDist ) @@ -447,8 +454,8 @@ AffineXf3f ICP::calculateTransformation() badIterCount++; } } - std::cout << "final minDist=" << minDist << std::endl; - std::cout << "resXf:\n" << resXf << std::endl; + spdlog::info( "minDist1 = {}\n", minDist ); + logXf( "resXf", resXf ); flt_.xf = resXf; return resXf; } From bcb076615f55f4c1d789c09372429cfb97113d8b Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Mon, 24 Nov 2025 11:58:42 +0300 Subject: [PATCH 07/56] more --- source/MRMesh/MRICP.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 1969998627cc..ab612bf87b05 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -119,8 +119,8 @@ void ICP::updatePointPairs() MR::updatePointPairs( flt2refPairs_, flt_, ref_, prop_.cosThreshold, prop_.distThresholdSq, prop_.mutualClosest ); MR::updatePointPairs( ref2fltPairs_, ref_, flt_, prop_.cosThreshold, prop_.distThresholdSq, prop_.mutualClosest ); deactivatefarDistPairs_(); - std::cout << "flt2refPairs_.active=" << MR::getNumActivePairs( flt2refPairs_ ) << std::endl; - std::cout << "ref2fltPairs_.active=" << MR::getNumActivePairs( ref2fltPairs_ ) << std::endl; + spdlog::info( "flt2refPairs_.active = {}\n", MR::getNumActivePairs( flt2refPairs_ ) ); + spdlog::info( "ref2fltPairs_.active = {}\n", MR::getNumActivePairs( ref2fltPairs_ ) ); } std::string getICPStatusInfo( int iterations, ICPExitType exitType ) From 86e090ed5e7804c3ca8b35102c77c70ce511dfe8 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Mon, 24 Nov 2025 12:25:47 +0300 Subject: [PATCH 08/56] remove \n --- source/MRMesh/MRICP.cpp | 46 ++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index ab612bf87b05..627a98e47fb6 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -119,8 +119,8 @@ void ICP::updatePointPairs() MR::updatePointPairs( flt2refPairs_, flt_, ref_, prop_.cosThreshold, prop_.distThresholdSq, prop_.mutualClosest ); MR::updatePointPairs( ref2fltPairs_, ref_, flt_, prop_.cosThreshold, prop_.distThresholdSq, prop_.mutualClosest ); deactivatefarDistPairs_(); - spdlog::info( "flt2refPairs_.active = {}\n", MR::getNumActivePairs( flt2refPairs_ ) ); - spdlog::info( "ref2fltPairs_.active = {}\n", MR::getNumActivePairs( ref2fltPairs_ ) ); + spdlog::info( "flt2refPairs_.active = {}", MR::getNumActivePairs( flt2refPairs_ ) ); + spdlog::info( "ref2fltPairs_.active = {}", MR::getNumActivePairs( ref2fltPairs_ ) ); } std::string getICPStatusInfo( int iterations, ICPExitType exitType ) @@ -382,30 +382,30 @@ bool ICP::p2plIter_() static void logXf( const char* var, const AffineXf3f& xf ) { - spdlog::info( "{} x: {} {} {} {}\n", var, xf.A.x.x, xf.A.x.y, xf.A.x.z, xf.b.x ); - spdlog::info( "{} y: {} {} {} {}\n", var, xf.A.y.x, xf.A.y.y, xf.A.y.z, xf.b.y ); - spdlog::info( "{} z: {} {} {} {}\n", var, xf.A.z.x, xf.A.z.y, xf.A.z.z, xf.b.z ); + spdlog::info( "{} x: {} {} {} {}", var, xf.A.x.x, xf.A.x.y, xf.A.x.z, xf.b.x ); + spdlog::info( "{} y: {} {} {} {}", var, xf.A.y.x, xf.A.y.y, xf.A.y.z, xf.b.y ); + spdlog::info( "{} z: {} {} {} {}", var, xf.A.z.x, xf.A.z.y, xf.A.z.z, xf.b.z ); } AffineXf3f ICP::calculateTransformation() { - spdlog::info( "method = {}\n", ( int )prop_.method ); - spdlog::info( "p2plAngleLimit = {}\n", prop_.p2plAngleLimit ); - spdlog::info( "p2plScaleLimit = {}\n", prop_.p2plScaleLimit ); - spdlog::info( "cosThreshold = {}\n", prop_.cosThreshold ); - spdlog::info( "distThresholdSq = {}\n", prop_.distThresholdSq ); - spdlog::info( "farDistFactor = {}\n", prop_.farDistFactor ); - spdlog::info( "icpMode = {}\n", (int)prop_.icpMode ); - spdlog::info( "fixedRotationAxis = {} {} {}\n", prop_.fixedRotationAxis.x, prop_.fixedRotationAxis.y, prop_.fixedRotationAxis.z ); - spdlog::info( "iterLimit = {}\n", prop_.iterLimit ); - spdlog::info( "badIterStopCount = {}\n", prop_.badIterStopCount ); - spdlog::info( "exitVal = {}\n", prop_.exitVal ); - spdlog::info( "mutualClosest = {}\n", prop_.mutualClosest ); + spdlog::info( "method = {}", ( int )prop_.method ); + spdlog::info( "p2plAngleLimit = {}", prop_.p2plAngleLimit ); + spdlog::info( "p2plScaleLimit = {}", prop_.p2plScaleLimit ); + spdlog::info( "cosThreshold = {}", prop_.cosThreshold ); + spdlog::info( "distThresholdSq = {}", prop_.distThresholdSq ); + spdlog::info( "farDistFactor = {}", prop_.farDistFactor ); + spdlog::info( "icpMode = {}", (int)prop_.icpMode ); + spdlog::info( "fixedRotationAxis = {} {} {}", prop_.fixedRotationAxis.x, prop_.fixedRotationAxis.y, prop_.fixedRotationAxis.z ); + spdlog::info( "iterLimit = {}", prop_.iterLimit ); + spdlog::info( "badIterStopCount = {}", prop_.badIterStopCount ); + spdlog::info( "exitVal = {}", prop_.exitVal ); + spdlog::info( "mutualClosest = {}", prop_.mutualClosest ); bool pt2pt = prop_.method == ICPMethod::Combined || prop_.method == ICPMethod::PointToPoint; updatePointPairs(); float minDist = pt2pt ? getMeanSqDistToPoint() : getMeanSqDistToPlane(); - spdlog::info( "minDist0 = {}\n", minDist ); + spdlog::info( "minDist0 = {}", minDist ); int badIterCount = 0; resultType_ = ICPExitType::MaxIterations; @@ -413,12 +413,12 @@ AffineXf3f ICP::calculateTransformation() for ( iter_ = 1; iter_ <= prop_.iterLimit; ++iter_ ) { - spdlog::info( "Iter #{}\n", iter_ ); + spdlog::info( "Iter #{}", iter_ ); logXf( "ref_.xf", ref_.xf ); logXf( "flt_.xf", flt_.xf ); pt2pt = ( prop_.method == ICPMethod::Combined && iter_ < 3 ) || prop_.method == ICPMethod::PointToPoint; - spdlog::info( "pt2pt = {}\n", pt2pt ); + spdlog::info( "pt2pt = {}", pt2pt ); if ( !( pt2pt ? p2ptIter_() : p2plIter_() ) ) { @@ -428,14 +428,14 @@ AffineXf3f ICP::calculateTransformation() updatePointPairs(); const float curDist = pt2pt ? getMeanSqDistToPoint() : getMeanSqDistToPlane(); - spdlog::info( "curDist = {}\n", curDist ); + spdlog::info( "curDist = {}", curDist ); // exit if several(3) iterations didn't decrease minimization parameter if (curDist < minDist) { resXf = flt_.xf; minDist = curDist; - spdlog::info( "minDist = {}\n", minDist ); + spdlog::info( "minDist = {}", minDist ); badIterCount = 0; if ( prop_.exitVal > curDist ) @@ -454,7 +454,7 @@ AffineXf3f ICP::calculateTransformation() badIterCount++; } } - spdlog::info( "minDist1 = {}\n", minDist ); + spdlog::info( "minDist1 = {}", minDist ); logXf( "resXf", resXf ); flt_.xf = resXf; return resXf; From 14efa44eb8d5062b09915a1d7ce8ba2de8f274b7 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Mon, 24 Nov 2025 13:07:34 +0300 Subject: [PATCH 09/56] setupLoggerByDefault --- source/MRMesh/MRICP.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 627a98e47fb6..b1fd33fcc1bc 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -10,6 +10,7 @@ #include "MRStreamOperators.h" #include "MRPch/MRSpdlog.h" #include +#include "MRSystem.h" namespace MR { @@ -389,6 +390,8 @@ static void logXf( const char* var, const AffineXf3f& xf ) AffineXf3f ICP::calculateTransformation() { + static bool init = []{ MR::setupLoggerByDefault(); return true; }(); + spdlog::info( "method = {}", ( int )prop_.method ); spdlog::info( "p2plAngleLimit = {}", prop_.p2plAngleLimit ); spdlog::info( "p2plScaleLimit = {}", prop_.p2plScaleLimit ); From 2d1c788832f9a4c6f8162ac39696aeaff7559beb Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Mon, 24 Nov 2025 13:17:56 +0300 Subject: [PATCH 10/56] [[maybe_unused]] --- source/MRMesh/MRICP.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index b1fd33fcc1bc..199c6d252f4a 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -390,7 +390,7 @@ static void logXf( const char* var, const AffineXf3f& xf ) AffineXf3f ICP::calculateTransformation() { - static bool init = []{ MR::setupLoggerByDefault(); return true; }(); + [[maybe_unused]] static bool init = []{ MR::setupLoggerByDefault(); return true; }(); spdlog::info( "method = {}", ( int )prop_.method ); spdlog::info( "p2plAngleLimit = {}", prop_.p2plAngleLimit ); From f810f95b340ce6220d1368e92e16a1f9a71dc525 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Mon, 24 Nov 2025 13:43:49 +0300 Subject: [PATCH 11/56] simple call --- source/MRMesh/MRICP.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 199c6d252f4a..ac551e3f6f51 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -390,7 +390,7 @@ static void logXf( const char* var, const AffineXf3f& xf ) AffineXf3f ICP::calculateTransformation() { - [[maybe_unused]] static bool init = []{ MR::setupLoggerByDefault(); return true; }(); + MR::setupLoggerByDefault(); spdlog::info( "method = {}", ( int )prop_.method ); spdlog::info( "p2plAngleLimit = {}", prop_.p2plAngleLimit ); From 4498f46eac77fee8e49a6356a8b86a447cac99f6 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Tue, 25 Nov 2025 10:17:18 +0300 Subject: [PATCH 12/56] rounding and stacktrace --- source/MRMesh/MRICP.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index ac551e3f6f51..532fc8842036 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -11,6 +11,7 @@ #include "MRPch/MRSpdlog.h" #include #include "MRSystem.h" +#include namespace MR { @@ -391,6 +392,10 @@ static void logXf( const char* var, const AffineXf3f& xf ) AffineXf3f ICP::calculateTransformation() { MR::setupLoggerByDefault(); + spdlog::info( "fegetround() = {}", fegetround() ); +#ifndef __EMSCRIPTEN__ + spdlog::info( "stacktrace:\n{}", getCurrentStacktrace() ); +#endif spdlog::info( "method = {}", ( int )prop_.method ); spdlog::info( "p2plAngleLimit = {}", prop_.p2plAngleLimit ); From 7ca1778e826d9346c300d86f693b25595cbdd7f5 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Tue, 25 Nov 2025 11:59:04 +0300 Subject: [PATCH 13/56] more logs, no parallel --- source/MRMesh/MRICP.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 532fc8842036..1172abb06af3 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -172,7 +172,8 @@ void updatePointPairs( PointPairs & pairs, pairs.active.resize( pairs.vec.size(), true ); // calculate pairs - BitSetParallelForAll( pairs.active, [&] ( size_t idx ) + //BitSetParallelForAll( pairs.active, [&] ( size_t idx ) + for( size_t idx : pairs.active ) { auto & res = pairs.vec[idx]; const auto p0 = srcPoints[res.srcVertId]; @@ -226,7 +227,7 @@ void updatePointPairs( PointPairs & pairs, if ( prj.closestVert != res.srcVertId ) pairs.active.reset( idx ); } - } ); + }// ); } void ICP::deactivatefarDistPairs_() @@ -237,6 +238,7 @@ void ICP::deactivatefarDistPairs_() { const auto avgDist = getMeanSqDistToPoint(); const auto maxDistSq = sqr( prop_.farDistFactor * avgDist ); + spdlog::info( "avgDist = {}, maxDistSq = {}", avgDist, maxDistSq ); if ( maxDistSq >= prop_.distThresholdSq ) break; @@ -396,6 +398,14 @@ AffineXf3f ICP::calculateTransformation() #ifndef __EMSCRIPTEN__ spdlog::info( "stacktrace:\n{}", getCurrentStacktrace() ); #endif + auto* refMeshPart = ref_.obj.asMeshPart(); + auto* fltMeshPart = flt_.obj.asMeshPart(); + spdlog::info( "ref mesh = {}, flt mesh = {}", refMeshPart != nullptr, fltMeshPart != nullptr ); + if ( refMeshPart && fltMeshPart ) + { + spdlog::info( "ref region = {}, flt region = {}", (void*)refMeshPart->region, (void*)fltMeshPart->region ); + spdlog::info( "same meshes = {}", refMeshPart->mesh == fltMeshPart->mesh ); + } spdlog::info( "method = {}", ( int )prop_.method ); spdlog::info( "p2plAngleLimit = {}", prop_.p2plAngleLimit ); From 2f29788f5d66fa7262b233405b1d000c1876a8ed Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Tue, 25 Nov 2025 12:26:10 +0300 Subject: [PATCH 14/56] fix seq --- source/MRMesh/MRICP.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 1172abb06af3..c6f45684f517 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -198,7 +198,7 @@ void updatePointPairs( PointPairs & pairs, { // no target point found within distance threshold pairs.active.reset( idx ); - return; + continue; } const auto p1 = prj.point; @@ -217,7 +217,7 @@ void updatePointPairs( PointPairs & pairs, if ( prj.isBd || vp.normalsAngleCos < cosThreshold || vp.distSq > distThresholdSq ) { pairs.active.reset( idx ); - return; + continue; } if ( mutualClosest ) { From ea634f376695eb6154a36e9a583ba05c3c258cca Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Tue, 25 Nov 2025 13:16:11 +0300 Subject: [PATCH 15/56] caches, both distances --- source/MRMesh/MRICP.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index c6f45684f517..cf9ba9bd7349 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -405,6 +405,8 @@ AffineXf3f ICP::calculateTransformation() { spdlog::info( "ref region = {}, flt region = {}", (void*)refMeshPart->region, (void*)fltMeshPart->region ); spdlog::info( "same meshes = {}", refMeshPart->mesh == fltMeshPart->mesh ); + const_cast(refMeshPart->mesh).invalidateCaches(); + const_cast(fltMeshPart->mesh).invalidateCaches(); } spdlog::info( "method = {}", ( int )prop_.method ); @@ -422,6 +424,8 @@ AffineXf3f ICP::calculateTransformation() bool pt2pt = prop_.method == ICPMethod::Combined || prop_.method == ICPMethod::PointToPoint; updatePointPairs(); + spdlog::info( "getMeanSqDistToPoint = {}", getMeanSqDistToPoint() ); + spdlog::info( "getMeanSqDistToPlane = {}", getMeanSqDistToPlane() ); float minDist = pt2pt ? getMeanSqDistToPoint() : getMeanSqDistToPlane(); spdlog::info( "minDist0 = {}", minDist ); From e769ee61204d01b3f9001334cfc6061de7024610 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Tue, 25 Nov 2025 15:32:08 +0300 Subject: [PATCH 16/56] point-to-point --- source/MRTest/MRICPTests.cpp | 3 ++- test_python/test_icp.py | 25 +++++++++++++------------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/source/MRTest/MRICPTests.cpp b/source/MRTest/MRICPTests.cpp index 8e4d372b770f..1e44600fb888 100644 --- a/source/MRTest/MRICPTests.cpp +++ b/source/MRTest/MRICPTests.cpp @@ -24,13 +24,14 @@ TEST( MRMesh, ICPTorus ) ICPProperties props { + .method = ICPMethod::PointToPoint, .iterLimit = 20 }; icp.setParams( props ); auto newXf = icp.calculateTransformation(); std::cout << icp.getStatusInfo() << '\n'; - constexpr float eps = 1e-6f; + constexpr float eps = 1e-3f; EXPECT_NEAR( ( newXf.A - Matrix3f::identity() ).norm(), 0., eps ); EXPECT_NEAR( newXf.b.length(), 0., eps ); } diff --git a/test_python/test_icp.py b/test_python/test_icp.py index 08e981eea5ee..27d95b99dd09 100644 --- a/test_python/test_icp.py +++ b/test_python/test_icp.py @@ -23,6 +23,7 @@ def test_icp(): props = mrmesh.ICPProperties() props.iterLimit = 20 + props.method = mrmesh.ICPMethod.PointToPoint icp.setParams(props) newXf = icp.calculateTransformation() print(icp.getStatusInfo()) @@ -31,18 +32,18 @@ def test_icp(): diffXf.A -= newXf.A diffXf.b -= newXf.b - assert abs(diffXf.A.x.x) < 1e-6 - assert abs(diffXf.A.x.y) < 1e-6 - assert abs(diffXf.A.x.z) < 1e-6 + assert abs(diffXf.A.x.x) < 1e-3 + assert abs(diffXf.A.x.y) < 1e-3 + assert abs(diffXf.A.x.z) < 1e-3 - assert abs(diffXf.A.y.x) < 1e-6 - assert abs(diffXf.A.y.y) < 1e-6 - assert abs(diffXf.A.y.z) < 1e-6 + assert abs(diffXf.A.y.x) < 1e-3 + assert abs(diffXf.A.y.y) < 1e-3 + assert abs(diffXf.A.y.z) < 1e-3 - assert abs(diffXf.A.z.x) < 1e-6 - assert abs(diffXf.A.z.y) < 1e-6 - assert abs(diffXf.A.z.z) < 1e-6 + assert abs(diffXf.A.z.x) < 1e-3 + assert abs(diffXf.A.z.y) < 1e-3 + assert abs(diffXf.A.z.z) < 1e-3 - assert abs(diffXf.b.x) < 1e-6 - assert abs(diffXf.b.y) < 1e-6 - assert abs(diffXf.b.z) < 1e-6 + assert abs(diffXf.b.x) < 1e-3 + assert abs(diffXf.b.y) < 1e-3 + assert abs(diffXf.b.z) < 1e-3 From 0cc719784a951a7e5aa1baefd9a8a588b532a537 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Tue, 25 Nov 2025 16:21:27 +0300 Subject: [PATCH 17/56] Revert "point-to-point" This reverts commit e769ee61204d01b3f9001334cfc6061de7024610. --- source/MRTest/MRICPTests.cpp | 3 +-- test_python/test_icp.py | 25 ++++++++++++------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/source/MRTest/MRICPTests.cpp b/source/MRTest/MRICPTests.cpp index 1e44600fb888..8e4d372b770f 100644 --- a/source/MRTest/MRICPTests.cpp +++ b/source/MRTest/MRICPTests.cpp @@ -24,14 +24,13 @@ TEST( MRMesh, ICPTorus ) ICPProperties props { - .method = ICPMethod::PointToPoint, .iterLimit = 20 }; icp.setParams( props ); auto newXf = icp.calculateTransformation(); std::cout << icp.getStatusInfo() << '\n'; - constexpr float eps = 1e-3f; + constexpr float eps = 1e-6f; EXPECT_NEAR( ( newXf.A - Matrix3f::identity() ).norm(), 0., eps ); EXPECT_NEAR( newXf.b.length(), 0., eps ); } diff --git a/test_python/test_icp.py b/test_python/test_icp.py index 27d95b99dd09..08e981eea5ee 100644 --- a/test_python/test_icp.py +++ b/test_python/test_icp.py @@ -23,7 +23,6 @@ def test_icp(): props = mrmesh.ICPProperties() props.iterLimit = 20 - props.method = mrmesh.ICPMethod.PointToPoint icp.setParams(props) newXf = icp.calculateTransformation() print(icp.getStatusInfo()) @@ -32,18 +31,18 @@ def test_icp(): diffXf.A -= newXf.A diffXf.b -= newXf.b - assert abs(diffXf.A.x.x) < 1e-3 - assert abs(diffXf.A.x.y) < 1e-3 - assert abs(diffXf.A.x.z) < 1e-3 + assert abs(diffXf.A.x.x) < 1e-6 + assert abs(diffXf.A.x.y) < 1e-6 + assert abs(diffXf.A.x.z) < 1e-6 - assert abs(diffXf.A.y.x) < 1e-3 - assert abs(diffXf.A.y.y) < 1e-3 - assert abs(diffXf.A.y.z) < 1e-3 + assert abs(diffXf.A.y.x) < 1e-6 + assert abs(diffXf.A.y.y) < 1e-6 + assert abs(diffXf.A.y.z) < 1e-6 - assert abs(diffXf.A.z.x) < 1e-3 - assert abs(diffXf.A.z.y) < 1e-3 - assert abs(diffXf.A.z.z) < 1e-3 + assert abs(diffXf.A.z.x) < 1e-6 + assert abs(diffXf.A.z.y) < 1e-6 + assert abs(diffXf.A.z.z) < 1e-6 - assert abs(diffXf.b.x) < 1e-3 - assert abs(diffXf.b.y) < 1e-3 - assert abs(diffXf.b.z) < 1e-3 + assert abs(diffXf.b.x) < 1e-6 + assert abs(diffXf.b.y) < 1e-6 + assert abs(diffXf.b.z) < 1e-6 From 6b93d9191c8b8fe9444d3b3a63a947bbdaac3d4c Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Tue, 25 Nov 2025 16:29:15 +0300 Subject: [PATCH 18/56] logXfHex --- source/MRMesh/MRICP.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index cf9ba9bd7349..8e106f32cb77 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -391,6 +391,17 @@ static void logXf( const char* var, const AffineXf3f& xf ) spdlog::info( "{} z: {} {} {} {}", var, xf.A.z.x, xf.A.z.y, xf.A.z.z, xf.b.z ); } +static void logXfHex( const char* var, const AffineXf3f& xf ) +{ + auto d = [] ( float f ) + { + return std::bit_cast( f ); + }; + spdlog::info( "{} x: {:08x} {:08x} {:08x} {:08x}", var, d( xf.A.x.x ), d( xf.A.x.y ), d( xf.A.x.z ), d( xf.b.x ) ); + spdlog::info( "{} y: {:08x} {:08x} {:08x} {:08x}", var, d( xf.A.y.x ), d( xf.A.y.y ), d( xf.A.y.z ), d( xf.b.y ) ); + spdlog::info( "{} z: {:08x} {:08x} {:08x} {:08x}", var, d( xf.A.z.x ), d( xf.A.z.y ), d( xf.A.z.z ), d( xf.b.z ) ); +} + AffineXf3f ICP::calculateTransformation() { MR::setupLoggerByDefault(); @@ -408,6 +419,8 @@ AffineXf3f ICP::calculateTransformation() const_cast(refMeshPart->mesh).invalidateCaches(); const_cast(fltMeshPart->mesh).invalidateCaches(); } + logXf( "flt_.xf", flt_.xf ); + logXfHex( "flt_.xf", flt_.xf ); spdlog::info( "method = {}", ( int )prop_.method ); spdlog::info( "p2plAngleLimit = {}", prop_.p2plAngleLimit ); From 82a7ce33ea55f0e006f78f684610a6658cae6060 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Tue, 25 Nov 2025 17:30:42 +0300 Subject: [PATCH 19/56] logPointPairs --- source/MRMesh/MRICP.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 8e106f32cb77..303fa924b21e 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -150,6 +150,21 @@ std::string getICPStatusInfo( int iterations, ICPExitType exitType ) return result; } +void logPointPairs( const PointPairs& pairs ) +{ + for ( int i = 0; i < pairs.vec.size(); ++i ) + { + const auto& pair = pairs.vec[i]; + spdlog::info( "#{}: active={}, srcVertId={}, tgtCloseVert={}, srcPoint=({} {} {}), srcNorm=({} {} {}), tgtPoint=({} {} {}), tgtNorm=({} {} {}), distSq={}, weight={}, normalsAngleCos={}, tgtOnBd={}", + i, pairs.active.test( i ), (int)pair.srcVertId, (int)pair.tgtCloseVert, + pair.srcPoint.x, pair.srcPoint.y, pair.srcPoint.z, + pair.srcNorm.x, pair.srcNorm.y, pair.srcNorm.z, + pair.tgtPoint.x, pair.tgtPoint.y, pair.tgtPoint.z, + pair.tgtNorm.x, pair.tgtNorm.y, pair.tgtNorm.z, + pair.distSq, pair.weight, pair.normalsAngleCos, pair.tgtOnBd ); + } +} + void updatePointPairs( PointPairs & pairs, const MeshOrPointsXf& src, const MeshOrPointsXf& tgt, float cosThreshold, float distThresholdSq, bool mutualClosest ) @@ -437,6 +452,11 @@ AffineXf3f ICP::calculateTransformation() bool pt2pt = prop_.method == ICPMethod::Combined || prop_.method == ICPMethod::PointToPoint; updatePointPairs(); + spdlog::info( "flt2refPairs" ); + logPointPairs( flt2refPairs_ ); + spdlog::info( "ref2fltPairs" ); + logPointPairs( ref2fltPairs_ ); + spdlog::info( "getMeanSqDistToPoint = {}", getMeanSqDistToPoint() ); spdlog::info( "getMeanSqDistToPlane = {}", getMeanSqDistToPlane() ); float minDist = pt2pt ? getMeanSqDistToPoint() : getMeanSqDistToPlane(); From 99eb480eecea8486d1a7d633076f744ecb973a2b Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Tue, 25 Nov 2025 19:04:37 +0300 Subject: [PATCH 20/56] more xf logging --- source/MRMesh/MRICP.cpp | 52 ++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 303fa924b21e..e69beae7b435 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -118,7 +118,9 @@ void ICP::sampleRefPoints( float samplingVoxelSize ) void ICP::updatePointPairs() { MR_TIMER; + spdlog::info( "updatePointPairs flt->ref" ); MR::updatePointPairs( flt2refPairs_, flt_, ref_, prop_.cosThreshold, prop_.distThresholdSq, prop_.mutualClosest ); + spdlog::info( "updatePointPairs ref->flt" ); MR::updatePointPairs( ref2fltPairs_, ref_, flt_, prop_.cosThreshold, prop_.distThresholdSq, prop_.mutualClosest ); deactivatefarDistPairs_(); spdlog::info( "flt2refPairs_.active = {}", MR::getNumActivePairs( flt2refPairs_ ) ); @@ -165,6 +167,24 @@ void logPointPairs( const PointPairs& pairs ) } } +static void logXf( const char* var, const AffineXf3f& xf ) +{ + spdlog::info( "{} x: {} {} {} {}", var, xf.A.x.x, xf.A.x.y, xf.A.x.z, xf.b.x ); + spdlog::info( "{} y: {} {} {} {}", var, xf.A.y.x, xf.A.y.y, xf.A.y.z, xf.b.y ); + spdlog::info( "{} z: {} {} {} {}", var, xf.A.z.x, xf.A.z.y, xf.A.z.z, xf.b.z ); +} + +static void logXfHex( const char* var, const AffineXf3f& xf ) +{ + auto d = [] ( float f ) + { + return std::bit_cast< std::uint32_t >( f ); + }; + spdlog::info( "{} x: {:08x} {:08x} {:08x} {:08x}", var, d( xf.A.x.x ), d( xf.A.x.y ), d( xf.A.x.z ), d( xf.b.x ) ); + spdlog::info( "{} y: {:08x} {:08x} {:08x} {:08x}", var, d( xf.A.y.x ), d( xf.A.y.y ), d( xf.A.y.z ), d( xf.b.y ) ); + spdlog::info( "{} z: {:08x} {:08x} {:08x} {:08x}", var, d( xf.A.z.x ), d( xf.A.z.y ), d( xf.A.z.z ), d( xf.b.z ) ); +} + void updatePointPairs( PointPairs & pairs, const MeshOrPointsXf& src, const MeshOrPointsXf& tgt, float cosThreshold, float distThresholdSq, bool mutualClosest ) @@ -172,6 +192,10 @@ void updatePointPairs( PointPairs & pairs, MR_TIMER; const auto src2tgtXf = tgt.xf.inverse() * src.xf; const auto tgt2srcXf = src.xf.inverse() * tgt.xf; + logXf( "src2tgtXf", src2tgtXf ); + logXfHex( "src2tgtXf", src2tgtXf ); + logXf( "tgt2srcXf", tgt2srcXf ); + logXfHex( "tgt2srcXf", tgt2srcXf ); const VertCoords& srcPoints = src.obj.points(); const VertCoords& tgtPoints = tgt.obj.points(); @@ -399,24 +423,6 @@ bool ICP::p2plIter_() return true; } -static void logXf( const char* var, const AffineXf3f& xf ) -{ - spdlog::info( "{} x: {} {} {} {}", var, xf.A.x.x, xf.A.x.y, xf.A.x.z, xf.b.x ); - spdlog::info( "{} y: {} {} {} {}", var, xf.A.y.x, xf.A.y.y, xf.A.y.z, xf.b.y ); - spdlog::info( "{} z: {} {} {} {}", var, xf.A.z.x, xf.A.z.y, xf.A.z.z, xf.b.z ); -} - -static void logXfHex( const char* var, const AffineXf3f& xf ) -{ - auto d = [] ( float f ) - { - return std::bit_cast( f ); - }; - spdlog::info( "{} x: {:08x} {:08x} {:08x} {:08x}", var, d( xf.A.x.x ), d( xf.A.x.y ), d( xf.A.x.z ), d( xf.b.x ) ); - spdlog::info( "{} y: {:08x} {:08x} {:08x} {:08x}", var, d( xf.A.y.x ), d( xf.A.y.y ), d( xf.A.y.z ), d( xf.b.y ) ); - spdlog::info( "{} z: {:08x} {:08x} {:08x} {:08x}", var, d( xf.A.z.x ), d( xf.A.z.y ), d( xf.A.z.z ), d( xf.b.z ) ); -} - AffineXf3f ICP::calculateTransformation() { MR::setupLoggerByDefault(); @@ -434,6 +440,8 @@ AffineXf3f ICP::calculateTransformation() const_cast(refMeshPart->mesh).invalidateCaches(); const_cast(fltMeshPart->mesh).invalidateCaches(); } + logXf( "ref_.xf", ref_.xf ); + logXfHex( "ref_.xf", ref_.xf ); logXf( "flt_.xf", flt_.xf ); logXfHex( "flt_.xf", flt_.xf ); @@ -452,10 +460,10 @@ AffineXf3f ICP::calculateTransformation() bool pt2pt = prop_.method == ICPMethod::Combined || prop_.method == ICPMethod::PointToPoint; updatePointPairs(); - spdlog::info( "flt2refPairs" ); - logPointPairs( flt2refPairs_ ); - spdlog::info( "ref2fltPairs" ); - logPointPairs( ref2fltPairs_ ); + //spdlog::info( "flt2refPairs" ); + //logPointPairs( flt2refPairs_ ); + //spdlog::info( "ref2fltPairs" ); + //logPointPairs( ref2fltPairs_ ); spdlog::info( "getMeanSqDistToPoint = {}", getMeanSqDistToPoint() ); spdlog::info( "getMeanSqDistToPlane = {}", getMeanSqDistToPlane() ); From 170de6b1aa34666fcf2402cbadffd4d621bb295e Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Tue, 25 Nov 2025 20:12:09 +0300 Subject: [PATCH 21/56] edgeWithOrg --- source/MRMesh/MRICP.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index e69beae7b435..bac597b6da9e 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -437,8 +437,12 @@ AffineXf3f ICP::calculateTransformation() { spdlog::info( "ref region = {}, flt region = {}", (void*)refMeshPart->region, (void*)fltMeshPart->region ); spdlog::info( "same meshes = {}", refMeshPart->mesh == fltMeshPart->mesh ); - const_cast(refMeshPart->mesh).invalidateCaches(); - const_cast(fltMeshPart->mesh).invalidateCaches(); + const auto& refTopology = refMeshPart->mesh.topology; + const auto& fltTopology = fltMeshPart->mesh.topology; + for ( auto v = 0_v; v < refTopology.vertSize(); ++v ) + { + spdlog::info( "{}_v: refE={} fltE={}", (int)v, (int)refTopology.edgeWithOrg( v ), (int)fltTopology.edgeWithOrg( v ) ); + } } logXf( "ref_.xf", ref_.xf ); logXfHex( "ref_.xf", ref_.xf ); From c84767b03ad23b84d98b223683a8f93afaeb9b30 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Tue, 25 Nov 2025 21:03:34 +0300 Subject: [PATCH 22/56] fltNN --- source/MRMesh/MRICP.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index bac597b6da9e..f28d6721bd98 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -438,10 +438,16 @@ AffineXf3f ICP::calculateTransformation() spdlog::info( "ref region = {}, flt region = {}", (void*)refMeshPart->region, (void*)fltMeshPart->region ); spdlog::info( "same meshes = {}", refMeshPart->mesh == fltMeshPart->mesh ); const auto& refTopology = refMeshPart->mesh.topology; - const auto& fltTopology = fltMeshPart->mesh.topology; + //const auto& fltTopology = fltMeshPart->mesh.topology; for ( auto v = 0_v; v < refTopology.vertSize(); ++v ) { - spdlog::info( "{}_v: refE={} fltE={}", (int)v, (int)refTopology.edgeWithOrg( v ), (int)fltTopology.edgeWithOrg( v ) ); + auto refN = refMeshPart->mesh.pseudonormal( v ); + auto fltN = fltMeshPart->mesh.pseudonormal( v ); + auto fltNN = refN.normalized(); + spdlog::info( "{}_v: refN=({} {} {}) fltN=({} {} {}) fltNN=({} {} {})", (int)v, + refN.x, refN.y, refN.z, + fltN.x, fltN.y, fltN.z, + fltNN.x, fltNN.y, fltNN.z ); } } logXf( "ref_.xf", ref_.xf ); From 6bd148315f460ba69d74fb7f8322247961a823ff Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Tue, 25 Nov 2025 22:04:26 +0300 Subject: [PATCH 23/56] 0_v nei verts --- source/MRMesh/MRICP.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index f28d6721bd98..7bb190284493 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -12,6 +12,7 @@ #include #include "MRSystem.h" #include +#include "MRRingIterator.h" namespace MR { @@ -439,7 +440,7 @@ AffineXf3f ICP::calculateTransformation() spdlog::info( "same meshes = {}", refMeshPart->mesh == fltMeshPart->mesh ); const auto& refTopology = refMeshPart->mesh.topology; //const auto& fltTopology = fltMeshPart->mesh.topology; - for ( auto v = 0_v; v < refTopology.vertSize(); ++v ) +/* for ( auto v = 0_v; v < refTopology.vertSize(); ++v ) { auto refN = refMeshPart->mesh.pseudonormal( v ); auto fltN = fltMeshPart->mesh.pseudonormal( v ); @@ -448,6 +449,24 @@ AffineXf3f ICP::calculateTransformation() refN.x, refN.y, refN.z, fltN.x, fltN.y, fltN.z, fltNN.x, fltNN.y, fltNN.z ); + }*/ + { + std::ostringstream s; + s << "0_v nei verts: "; + for ( auto e : orgRing( refTopology, 0_v ) ) + { + s << (int)refTopology.dest( e ) << ' '; + } + spdlog::info( "{}", s.str() ); + } + { + std::ostringstream s; + s << "0_v nei faces: "; + for ( auto e : orgRing( refTopology, 0_v ) ) + { + s << ( int )refTopology.left( e ) << ' '; + } + spdlog::info( "{}", s.str() ); } } logXf( "ref_.xf", ref_.xf ); From 8fb3e82832a47bffad10c7c10c8d7c29ad94243c Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Tue, 25 Nov 2025 22:46:11 +0300 Subject: [PATCH 24/56] more logs --- source/MRMesh/MRICP.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 7bb190284493..2e6e381fd571 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -438,6 +438,7 @@ AffineXf3f ICP::calculateTransformation() { spdlog::info( "ref region = {}, flt region = {}", (void*)refMeshPart->region, (void*)fltMeshPart->region ); spdlog::info( "same meshes = {}", refMeshPart->mesh == fltMeshPart->mesh ); + const auto& refPoints = refMeshPart->mesh.points; const auto& refTopology = refMeshPart->mesh.topology; //const auto& fltTopology = fltMeshPart->mesh.topology; /* for ( auto v = 0_v; v < refTopology.vertSize(); ++v ) @@ -450,12 +451,17 @@ AffineXf3f ICP::calculateTransformation() fltN.x, fltN.y, fltN.z, fltNN.x, fltNN.y, fltNN.z ); }*/ + auto n0 = refMeshPart->mesh.pseudonormal( 0_v ); + spdlog::info( "pseudonormal 0: {} {} {}", n0.x, n0.y, n0.z ); + spdlog::info( "point 0: {} {} {}", refPoints[0_v].x, refPoints[0_v].y, refPoints[0_v].z ); { std::ostringstream s; s << "0_v nei verts: "; for ( auto e : orgRing( refTopology, 0_v ) ) { - s << (int)refTopology.dest( e ) << ' '; + auto d = refTopology.dest( e ); + spdlog::info( "point {}: {} {} {}", (int)d, refPoints[d].x, refPoints[d].y, refPoints[d].z ); + s << (int)d << ' '; } spdlog::info( "{}", s.str() ); } From 72b55e3374b72f5756c385501426ca373c694133 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Wed, 26 Nov 2025 00:23:01 +0300 Subject: [PATCH 25/56] pseudonormalLog --- source/MRMesh/MRICP.cpp | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 2e6e381fd571..1cb30e0fd2bd 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -424,6 +424,34 @@ bool ICP::p2plIter_() return true; } +inline float angleLog( const Vector3f& a, const Vector3f& b ) +{ + auto x = cross( a, b ).length(); + auto y = dot( a, b ); + auto r = std::atan2( x, y ); + spdlog::info( "std::atan2( {}, {} ) = {}", x, y, r ); + return r; +} + +static Vector3f pseudonormalLog( const MeshTopology& topology, const VertCoords& points, VertId v, const FaceBitSet* region = nullptr ) +{ + Vector3f sum; + for ( EdgeId e : orgRing( topology, v ) ) + { + const auto l = topology.left( e ); + if ( l && ( !region || region->test( l ) ) ) + { + auto d0 = edgeVector( topology, points, e ); + auto d1 = edgeVector( topology, points, topology.next( e ) ); + auto angle = MR::angleLog( d0, d1 ); + auto n = cross( d0, d1 ); + sum += angle * n.normalized(); + } + } + + return sum.normalized(); +} + AffineXf3f ICP::calculateTransformation() { MR::setupLoggerByDefault(); @@ -451,7 +479,7 @@ AffineXf3f ICP::calculateTransformation() fltN.x, fltN.y, fltN.z, fltNN.x, fltNN.y, fltNN.z ); }*/ - auto n0 = refMeshPart->mesh.pseudonormal( 0_v ); + auto n0 = pseudonormalLog( refTopology, refPoints, 0_v ); spdlog::info( "pseudonormal 0: {} {} {}", n0.x, n0.y, n0.z ); spdlog::info( "point 0: {} {} {}", refPoints[0_v].x, refPoints[0_v].y, refPoints[0_v].z ); { From b0053f2ee3f0eb0cdbdf44deb42c97d7017965fd Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Wed, 26 Nov 2025 00:56:01 +0300 Subject: [PATCH 26/56] abc --- source/MRMesh/MRICP.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 1cb30e0fd2bd..553d23f3717a 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -426,7 +426,12 @@ bool ICP::p2plIter_() inline float angleLog( const Vector3f& a, const Vector3f& b ) { - auto x = cross( a, b ).length(); + const auto c = cross( a, b ); + spdlog::info( "a=({} {} {}), b=({} {} {}), c=({} {} {})", + a.x, a.y, a.z, + b.x, b.y, b.z, + c.x, c.y, c.z ); + auto x = c.length(); auto y = dot( a, b ); auto r = std::atan2( x, y ); spdlog::info( "std::atan2( {}, {} ) = {}", x, y, r ); From 93a058fc81e35ca17c0afb63aefe009a93fc88ab Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Wed, 26 Nov 2025 10:02:27 +0300 Subject: [PATCH 27/56] length --- source/MRMesh/MRICP.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 553d23f3717a..90cb312f15b2 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -424,6 +424,11 @@ bool ICP::p2plIter_() return true; } +inline float myLength( const Vector3f& a ) +{ + return std::sqrt( a.x * a.x + a.y * a.y + a.z * a.z ); +} + inline float angleLog( const Vector3f& a, const Vector3f& b ) { const auto c = cross( a, b ); @@ -431,7 +436,7 @@ inline float angleLog( const Vector3f& a, const Vector3f& b ) a.x, a.y, a.z, b.x, b.y, b.z, c.x, c.y, c.z ); - auto x = c.length(); + auto x = myLength( c ); auto y = dot( a, b ); auto r = std::atan2( x, y ); spdlog::info( "std::atan2( {}, {} ) = {}", x, y, r ); @@ -471,6 +476,10 @@ AffineXf3f ICP::calculateTransformation() { spdlog::info( "ref region = {}, flt region = {}", (void*)refMeshPart->region, (void*)fltMeshPart->region ); spdlog::info( "same meshes = {}", refMeshPart->mesh == fltMeshPart->mesh ); + + Vector3f c( -0.02146666f, 0.0014069901f, 0.0014069926f ); + spdlog::info( "({} {} {}).length() = {}", c.x, c.y, c.z, c.length() ); + const auto& refPoints = refMeshPart->mesh.points; const auto& refTopology = refMeshPart->mesh.topology; //const auto& fltTopology = fltMeshPart->mesh.topology; From 5eee64c872530c8253cb2fa2d82bb7af58f09770 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Wed, 26 Nov 2025 11:21:31 +0300 Subject: [PATCH 28/56] lengthSq --- source/MRMesh/MRICP.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 90cb312f15b2..d216a85795f8 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -478,7 +478,7 @@ AffineXf3f ICP::calculateTransformation() spdlog::info( "same meshes = {}", refMeshPart->mesh == fltMeshPart->mesh ); Vector3f c( -0.02146666f, 0.0014069901f, 0.0014069926f ); - spdlog::info( "({} {} {}).length() = {}", c.x, c.y, c.z, c.length() ); + spdlog::info( "({} {} {}).lengthSq() = {}, length = {}", c.x, c.y, c.z, c.lengthSq(), c.length() ); const auto& refPoints = refMeshPart->mesh.points; const auto& refTopology = refMeshPart->mesh.topology; From 718820c94b9f3cbe279f72f7a693d1ef195230d2 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Wed, 26 Nov 2025 12:17:37 +0300 Subject: [PATCH 29/56] dladdr --- source/MRMesh/MRICP.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index d216a85795f8..34b9fe7e74e0 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -13,6 +13,8 @@ #include "MRSystem.h" #include #include "MRRingIterator.h" +#include +#include namespace MR { @@ -477,6 +479,14 @@ AffineXf3f ICP::calculateTransformation() spdlog::info( "ref region = {}, flt region = {}", (void*)refMeshPart->region, (void*)fltMeshPart->region ); spdlog::info( "same meshes = {}", refMeshPart->mesh == fltMeshPart->mesh ); + using A = std::array; + void* symbol = std::bit_cast(&Vector3f::lengthSq)[0]; + Dl_info info; + if ( !dladdr( symbol, &info ) ) + spdlog::error( "Failed to get library path" ); + else + spdlog::info( "Vector3f::lengthSq: fname={}, sname={}", info.dli_fname, info.dli_sname ); + Vector3f c( -0.02146666f, 0.0014069901f, 0.0014069926f ); spdlog::info( "({} {} {}).lengthSq() = {}, length = {}", c.x, c.y, c.z, c.lengthSq(), c.length() ); From cca1f69327f3ca691664ccf1e1bbc4022f75af26 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Wed, 26 Nov 2025 12:48:17 +0300 Subject: [PATCH 30/56] -fvisibility-inlines-hidden --- scripts/mrbind/generate.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mrbind/generate.mk b/scripts/mrbind/generate.mk index 66610e48c812..1feabe3a0fe7 100644 --- a/scripts/mrbind/generate.mk +++ b/scripts/mrbind/generate.mk @@ -601,7 +601,7 @@ ifeq ($(TARGET),python) # Linux or MacOS. ifneq ($(IS_LINUX)$(IS_MACOS),) -COMPILER += -fvisibility=hidden +COMPILER += -fvisibility=hidden -fvisibility-inlines-hidden COMPILER_FLAGS += -fPIC # Override Pybind ABI identifiers to force compatibility with `mrviewerpy` (which is compiled with some other compiler, but is also made to define those). From e75b618d9130cdc70bfbb671bdcbbb63923e4e3b Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Wed, 26 Nov 2025 13:42:22 +0300 Subject: [PATCH 31/56] #ifdef linux --- source/MRMesh/MRICP.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 34b9fe7e74e0..279c62cbad8a 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -14,7 +14,9 @@ #include #include "MRRingIterator.h" #include +#ifdef __linux__ #include +#endif namespace MR { @@ -479,6 +481,7 @@ AffineXf3f ICP::calculateTransformation() spdlog::info( "ref region = {}, flt region = {}", (void*)refMeshPart->region, (void*)fltMeshPart->region ); spdlog::info( "same meshes = {}", refMeshPart->mesh == fltMeshPart->mesh ); +#ifdef __linux__ using A = std::array; void* symbol = std::bit_cast(&Vector3f::lengthSq)[0]; Dl_info info; @@ -486,6 +489,7 @@ AffineXf3f ICP::calculateTransformation() spdlog::error( "Failed to get library path" ); else spdlog::info( "Vector3f::lengthSq: fname={}, sname={}", info.dli_fname, info.dli_sname ); +#endif Vector3f c( -0.02146666f, 0.0014069901f, 0.0014069926f ); spdlog::info( "({} {} {}).lengthSq() = {}, length = {}", c.x, c.y, c.z, c.lengthSq(), c.length() ); From f75bd857065a946ec7cff34e871cd10192eb606d Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Wed, 26 Nov 2025 23:24:11 +0300 Subject: [PATCH 32/56] objdump -T --- .github/workflows/build-test-linux-vcpkg.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-test-linux-vcpkg.yml b/.github/workflows/build-test-linux-vcpkg.yml index 1267e6a657ee..31ad02d0a2a3 100644 --- a/.github/workflows/build-test-linux-vcpkg.yml +++ b/.github/workflows/build-test-linux-vcpkg.yml @@ -175,7 +175,9 @@ jobs: run: xvfb-run -a ./build/${{ matrix.config }}/bin/MeshViewer -hidden -noEventLoop -unloadPluginsAtEnd - name: Unit Tests - run: ./build/${{ matrix.config }}/bin/MRTest + run: | + objdump -T ./build/${{ matrix.config }}/bin/MRTest + ./build/${{ matrix.config }}/bin/MRTest - name: C Unit Tests (old bindings) run: ./build/${{ matrix.config }}/bin/MRTestC From 5a141886db3b4a7d978036323ab381acf33a2480 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Thu, 27 Nov 2025 00:10:16 +0300 Subject: [PATCH 33/56] inline void foo() {} --- source/MRTest/MRTestApp.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/MRTest/MRTestApp.cpp b/source/MRTest/MRTestApp.cpp index f9dc62ab9012..1e281b097d0d 100644 --- a/source/MRTest/MRTestApp.cpp +++ b/source/MRTest/MRTestApp.cpp @@ -35,8 +35,11 @@ TEST(MRMesh, QuadraticForm) } //namespace MR +inline void foo() {} + int main( int argc, char** argv ) { + foo(); //! If `flag` exists in `argv`, returns true and removes it from there. [[maybe_unused]] auto consumeFlag = [&]( std::string_view flag ) -> bool { From df1cf457e99a86e3113063a3f94a602490983a06 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Thu, 27 Nov 2025 00:41:06 +0300 Subject: [PATCH 34/56] restore inlines --- cmake/Modules/CompilerOptions.cmake | 2 -- 1 file changed, 2 deletions(-) diff --git a/cmake/Modules/CompilerOptions.cmake b/cmake/Modules/CompilerOptions.cmake index 0817b2b5dd6b..6d3eada31e15 100644 --- a/cmake/Modules/CompilerOptions.cmake +++ b/cmake/Modules/CompilerOptions.cmake @@ -84,8 +84,6 @@ IF(MSVC) set(MESHLIB_COMMON_C_CXX_FLAGS "${MESHLIB_COMMON_C_CXX_FLAGS} /wd4061 /wd4250 /wd4324 /wd4365 /wd4371 /wd4388 /wd4435 /wd4514 /wd4582 /wd4583 /wd4599 /wd4605 /wd4623 /wd4625 /wd4626 /wd4668 /wd4686 /wd4710 /wd4711 /wd4820 /wd4865 /wd4866 /wd4868 /wd5026 /wd5027 /wd5031 /wd5039 /wd5045 /wd5104 /wd5105 /wd5219 /wd5243 /wd5246 /wd5262 /wd5264 /wd26451") ELSE() set(MESHLIB_COMMON_C_CXX_FLAGS "${MESHLIB_COMMON_C_CXX_FLAGS} -Wall -Wextra -Wno-missing-field-initializers -Wno-unknown-pragmas -Wno-sign-compare -Werror -fvisibility=hidden -pedantic-errors") - # command line option '-fvisibility-inlines-hidden' is valid for C++/ObjC++ but not for C, so we cannot put it in MESHLIB_COMMON_C_CXX_FLAGS - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden") IF(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") set(MESHLIB_COMMON_C_CXX_FLAGS "${MESHLIB_COMMON_C_CXX_FLAGS} -Wno-newline-eof") From fc331e1649f2f8facfef2000f6e26de2cd49162c Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Thu, 27 Nov 2025 10:09:58 +0300 Subject: [PATCH 35/56] foo(T) --- source/MRTest/MRTestApp.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/MRTest/MRTestApp.cpp b/source/MRTest/MRTestApp.cpp index 1e281b097d0d..49712f8ff1c8 100644 --- a/source/MRTest/MRTestApp.cpp +++ b/source/MRTest/MRTestApp.cpp @@ -35,11 +35,12 @@ TEST(MRMesh, QuadraticForm) } //namespace MR -inline void foo() {} +template +void foo(T) {} int main( int argc, char** argv ) { - foo(); + foo(1); //! If `flag` exists in `argv`, returns true and removes it from there. [[maybe_unused]] auto consumeFlag = [&]( std::string_view flag ) -> bool { From 04fb3ff269897c6f47076739008e10e1343a28d2 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Thu, 27 Nov 2025 11:47:33 +0300 Subject: [PATCH 36/56] in MRMesh --- .github/workflows/build-test-linux-vcpkg.yml | 3 ++- source/MRMesh/MRICP.cpp | 3 +++ source/MRTest/MRTestApp.cpp | 4 ---- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-test-linux-vcpkg.yml b/.github/workflows/build-test-linux-vcpkg.yml index bbc7672eae0e..c6e445870ca0 100644 --- a/.github/workflows/build-test-linux-vcpkg.yml +++ b/.github/workflows/build-test-linux-vcpkg.yml @@ -177,7 +177,8 @@ jobs: - name: Unit Tests run: | - objdump -T ./build/${{ matrix.config }}/bin/MRTest + objdump -T ./build/Debug/bin/libMRMesh.so + objdump -T ./build/Debug/bin/libMRMesh.so | c++filt ./build/${{ matrix.config }}/bin/MRTest - name: C Unit Tests (old bindings) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 279c62cbad8a..f4e7c1008c5e 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -466,8 +466,11 @@ static Vector3f pseudonormalLog( const MeshTopology& topology, const VertCoords& return sum.normalized(); } +inline void foo() {} + AffineXf3f ICP::calculateTransformation() { + foo(); MR::setupLoggerByDefault(); spdlog::info( "fegetround() = {}", fegetround() ); #ifndef __EMSCRIPTEN__ diff --git a/source/MRTest/MRTestApp.cpp b/source/MRTest/MRTestApp.cpp index 49712f8ff1c8..f9dc62ab9012 100644 --- a/source/MRTest/MRTestApp.cpp +++ b/source/MRTest/MRTestApp.cpp @@ -35,12 +35,8 @@ TEST(MRMesh, QuadraticForm) } //namespace MR -template -void foo(T) {} - int main( int argc, char** argv ) { - foo(1); //! If `flag` exists in `argv`, returns true and removes it from there. [[maybe_unused]] auto consumeFlag = [&]( std::string_view flag ) -> bool { From 2ee9efa2cf75ea37477558f0e37372e5d10a7ad8 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Thu, 27 Nov 2025 12:38:07 +0300 Subject: [PATCH 37/56] A{}.foo(); --- .github/workflows/build-test-linux-vcpkg.yml | 3 +-- source/MRMesh/MRICP.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-test-linux-vcpkg.yml b/.github/workflows/build-test-linux-vcpkg.yml index c6e445870ca0..bf228c3a8a1d 100644 --- a/.github/workflows/build-test-linux-vcpkg.yml +++ b/.github/workflows/build-test-linux-vcpkg.yml @@ -177,8 +177,7 @@ jobs: - name: Unit Tests run: | - objdump -T ./build/Debug/bin/libMRMesh.so - objdump -T ./build/Debug/bin/libMRMesh.so | c++filt + objdump -T ./build/${{ matrix.config }}/bin/libMRMesh.so | c++filt ./build/${{ matrix.config }}/bin/MRTest - name: C Unit Tests (old bindings) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index f4e7c1008c5e..a355a9ec3f85 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -466,11 +466,13 @@ static Vector3f pseudonormalLog( const MeshTopology& topology, const VertCoords& return sum.normalized(); } -inline void foo() {} +struct A { + void foo() {} +}; AffineXf3f ICP::calculateTransformation() { - foo(); + A{}.foo(); MR::setupLoggerByDefault(); spdlog::info( "fegetround() = {}", fegetround() ); #ifndef __EMSCRIPTEN__ From aab0f29e60863ef951f85958abd27f90cc9535c7 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Thu, 27 Nov 2025 13:15:17 +0300 Subject: [PATCH 38/56] struct __attribute__((visibility("default"))) A --- .github/workflows/build-test-linux-vcpkg.yml | 2 +- source/MRMesh/MRICP.cpp | 5 ----- source/MRTest/MRTestApp.cpp | 9 +++++++++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-test-linux-vcpkg.yml b/.github/workflows/build-test-linux-vcpkg.yml index bf228c3a8a1d..ed4e2453afd0 100644 --- a/.github/workflows/build-test-linux-vcpkg.yml +++ b/.github/workflows/build-test-linux-vcpkg.yml @@ -177,7 +177,7 @@ jobs: - name: Unit Tests run: | - objdump -T ./build/${{ matrix.config }}/bin/libMRMesh.so | c++filt + objdump -T ./build/${{ matrix.config }}/bin/MRTest | c++filt ./build/${{ matrix.config }}/bin/MRTest - name: C Unit Tests (old bindings) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index a355a9ec3f85..279c62cbad8a 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -466,13 +466,8 @@ static Vector3f pseudonormalLog( const MeshTopology& topology, const VertCoords& return sum.normalized(); } -struct A { - void foo() {} -}; - AffineXf3f ICP::calculateTransformation() { - A{}.foo(); MR::setupLoggerByDefault(); spdlog::info( "fegetround() = {}", fegetround() ); #ifndef __EMSCRIPTEN__ diff --git a/source/MRTest/MRTestApp.cpp b/source/MRTest/MRTestApp.cpp index f9dc62ab9012..da74da379342 100644 --- a/source/MRTest/MRTestApp.cpp +++ b/source/MRTest/MRTestApp.cpp @@ -35,8 +35,17 @@ TEST(MRMesh, QuadraticForm) } //namespace MR +struct __attribute__((visibility("default"))) A { + void foo() {} + void bar(); +}; + +void A::bar() {} + int main( int argc, char** argv ) { + A{}.foo(); + A{}.bar(); //! If `flag` exists in `argv`, returns true and removes it from there. [[maybe_unused]] auto consumeFlag = [&]( std::string_view flag ) -> bool { From 4fc54c9dd468fa90322f86dd813a48ca91ed39f8 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Thu, 27 Nov 2025 14:33:35 +0300 Subject: [PATCH 39/56] all configurations --- .github/workflows/build-test-linux-vcpkg.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/build-test-linux-vcpkg.yml b/.github/workflows/build-test-linux-vcpkg.yml index ed4e2453afd0..00a72eb38f51 100644 --- a/.github/workflows/build-test-linux-vcpkg.yml +++ b/.github/workflows/build-test-linux-vcpkg.yml @@ -50,15 +50,6 @@ jobs: compiler: [Clang 19, GCC 11] full_config_build: - ${{ fromJSON( inputs.full_config_build ) }} - exclude: - # Do not run Debug Clang 19 build on every commit (but only once a day) - - full_config_build: false - compiler: Clang 19 - config: Debug - # Do not run Release GCC 11 build on every commit (but only once a day) - - full_config_build: false - compiler: GCC 11 - config: Release include: - compiler: Clang 19 cxx-compiler: /usr/bin/clang++-19 From 1dbbf28d90b6d6a381ec4f7ae7d91d0fe612bfa8 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Thu, 27 Nov 2025 15:20:11 +0300 Subject: [PATCH 40/56] x*x + y*y --- source/MRTest/MRTestApp.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/MRTest/MRTestApp.cpp b/source/MRTest/MRTestApp.cpp index da74da379342..3a6cd1b7e93b 100644 --- a/source/MRTest/MRTestApp.cpp +++ b/source/MRTest/MRTestApp.cpp @@ -36,16 +36,16 @@ TEST(MRMesh, QuadraticForm) } //namespace MR struct __attribute__((visibility("default"))) A { - void foo() {} - void bar(); + float foo( float x, float y ) { return x*x + y*y; } + float bar( float x, float y ); }; -void A::bar() {} +float A::bar( float x, float y ) { return x*x + y*y; } int main( int argc, char** argv ) { - A{}.foo(); - A{}.bar(); + A{}.foo( 1, 2 ); + A{}.bar( 1, 2 ); //! If `flag` exists in `argv`, returns true and removes it from there. [[maybe_unused]] auto consumeFlag = [&]( std::string_view flag ) -> bool { From 042ce558c2d3e816363ffc3c95ebbd788cc0c36d Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Thu, 27 Nov 2025 15:49:05 +0300 Subject: [PATCH 41/56] template --- source/MRTest/MRTestApp.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/source/MRTest/MRTestApp.cpp b/source/MRTest/MRTestApp.cpp index 3a6cd1b7e93b..5084d60004cd 100644 --- a/source/MRTest/MRTestApp.cpp +++ b/source/MRTest/MRTestApp.cpp @@ -35,17 +35,19 @@ TEST(MRMesh, QuadraticForm) } //namespace MR +template struct __attribute__((visibility("default"))) A { - float foo( float x, float y ) { return x*x + y*y; } - float bar( float x, float y ); + T foo( T x, T y ) { return x*x + y*y; } + T bar( T x, T y ); }; -float A::bar( float x, float y ) { return x*x + y*y; } +template +T A::bar( T x, T y ) { return x*x + y*y; } int main( int argc, char** argv ) { - A{}.foo( 1, 2 ); - A{}.bar( 1, 2 ); + A{}.foo( 1, 2 ); + A{}.bar( 1, 2 ); //! If `flag` exists in `argv`, returns true and removes it from there. [[maybe_unused]] auto consumeFlag = [&]( std::string_view flag ) -> bool { From cadb1046b14ec69cf9e9219936c428f20aec947c Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Thu, 27 Nov 2025 16:24:56 +0300 Subject: [PATCH 42/56] data members --- source/MRTest/MRTestApp.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/source/MRTest/MRTestApp.cpp b/source/MRTest/MRTestApp.cpp index 5084d60004cd..921b7d0d8b2a 100644 --- a/source/MRTest/MRTestApp.cpp +++ b/source/MRTest/MRTestApp.cpp @@ -37,17 +37,19 @@ TEST(MRMesh, QuadraticForm) template struct __attribute__((visibility("default"))) A { - T foo( T x, T y ) { return x*x + y*y; } - T bar( T x, T y ); + T x, y; + T foo() const { return x*x + y*y; } + T bar() const; }; +float uu = A{ 1.0f, 2.0f }.foo(); +float vv = A{ 1.0f, 2.0f }.bar(); + template -T A::bar( T x, T y ) { return x*x + y*y; } +T A::bar() const { return x*x + y*y; } int main( int argc, char** argv ) { - A{}.foo( 1, 2 ); - A{}.bar( 1, 2 ); //! If `flag` exists in `argv`, returns true and removes it from there. [[maybe_unused]] auto consumeFlag = [&]( std::string_view flag ) -> bool { From 65b8d161293ba528ce52bd4187d992eca269ef72 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Thu, 27 Nov 2025 17:04:50 +0300 Subject: [PATCH 43/56] &A::foo --- source/MRTest/MRTestApp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/MRTest/MRTestApp.cpp b/source/MRTest/MRTestApp.cpp index 921b7d0d8b2a..ccc1231ea868 100644 --- a/source/MRTest/MRTestApp.cpp +++ b/source/MRTest/MRTestApp.cpp @@ -42,8 +42,8 @@ struct __attribute__((visibility("default"))) A { T bar() const; }; -float uu = A{ 1.0f, 2.0f }.foo(); -float vv = A{ 1.0f, 2.0f }.bar(); +auto pfoo = &A::foo; +auto pbar = &A::bar; template T A::bar() const { return x*x + y*y; } From 81fe3e457e5bdcb40d8f7c28c64b4f41f7edca1c Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Thu, 27 Nov 2025 17:28:44 +0300 Subject: [PATCH 44/56] in libMRMesh --- .github/workflows/build-test-linux-vcpkg.yml | 2 +- source/MRMesh/MRICP.cpp | 13 +++++++++++++ source/MRTest/MRTestApp.cpp | 13 ------------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build-test-linux-vcpkg.yml b/.github/workflows/build-test-linux-vcpkg.yml index 00a72eb38f51..a87d0ead4178 100644 --- a/.github/workflows/build-test-linux-vcpkg.yml +++ b/.github/workflows/build-test-linux-vcpkg.yml @@ -168,7 +168,7 @@ jobs: - name: Unit Tests run: | - objdump -T ./build/${{ matrix.config }}/bin/MRTest | c++filt + objdump -T ./build/${{ matrix.config }}/bin/libMRMesh.so | c++filt ./build/${{ matrix.config }}/bin/MRTest - name: C Unit Tests (old bindings) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 279c62cbad8a..46f281f4c397 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -384,6 +384,19 @@ AffineXf3f getAligningXf( const PointToPlaneAligningTransform & p2pl, return res; } +template +struct __attribute__((visibility("default"))) A { + T x, y; + T foo() const { return x*x + y*y; } + T bar() const; +}; + +auto pfoo = &A::foo; +auto pbar = &A::bar; + +template +T A::bar() const { return x*x + y*y; } + bool ICP::p2plIter_() { MR_TIMER; diff --git a/source/MRTest/MRTestApp.cpp b/source/MRTest/MRTestApp.cpp index ccc1231ea868..f9dc62ab9012 100644 --- a/source/MRTest/MRTestApp.cpp +++ b/source/MRTest/MRTestApp.cpp @@ -35,19 +35,6 @@ TEST(MRMesh, QuadraticForm) } //namespace MR -template -struct __attribute__((visibility("default"))) A { - T x, y; - T foo() const { return x*x + y*y; } - T bar() const; -}; - -auto pfoo = &A::foo; -auto pbar = &A::bar; - -template -T A::bar() const { return x*x + y*y; } - int main( int argc, char** argv ) { //! If `flag` exists in `argv`, returns true and removes it from there. From dbdb934098e5793807d1eb13cba7a5accf7c0829 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Thu, 27 Nov 2025 18:02:08 +0300 Subject: [PATCH 45/56] not-template --- source/MRMesh/MRICP.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 46f281f4c397..1d3a1fc2980f 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -384,18 +384,16 @@ AffineXf3f getAligningXf( const PointToPlaneAligningTransform & p2pl, return res; } -template struct __attribute__((visibility("default"))) A { - T x, y; - T foo() const { return x*x + y*y; } - T bar() const; + float x, y; + float foo() const { return x*x + y*y; } + float bar() const; }; -auto pfoo = &A::foo; -auto pbar = &A::bar; +auto pfoo = &A::foo; +auto pbar = &A::bar; -template -T A::bar() const { return x*x + y*y; } +float A::bar() const { return x*x + y*y; } bool ICP::p2plIter_() { From b7724c8e4a62e6aa710db34a64d66793cc03a7d6 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Thu, 27 Nov 2025 18:40:48 +0300 Subject: [PATCH 46/56] simplify --- source/MRMesh/MRICP.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 1d3a1fc2980f..93c955a8e90f 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -385,15 +385,14 @@ AffineXf3f getAligningXf( const PointToPlaneAligningTransform & p2pl, } struct __attribute__((visibility("default"))) A { - float x, y; - float foo() const { return x*x + y*y; } - float bar() const; + void foo() {} + void bar(); }; auto pfoo = &A::foo; auto pbar = &A::bar; -float A::bar() const { return x*x + y*y; } +void A::bar() {} bool ICP::p2plIter_() { From 33b8a5754e1e5dc14bb6cdd0be3924e2c09de7d5 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Thu, 27 Nov 2025 19:44:25 +0300 Subject: [PATCH 47/56] Revert "restore inlines" This reverts commit df1cf457e99a86e3113063a3f94a602490983a06. --- cmake/Modules/CompilerOptions.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/Modules/CompilerOptions.cmake b/cmake/Modules/CompilerOptions.cmake index 6d3eada31e15..0817b2b5dd6b 100644 --- a/cmake/Modules/CompilerOptions.cmake +++ b/cmake/Modules/CompilerOptions.cmake @@ -84,6 +84,8 @@ IF(MSVC) set(MESHLIB_COMMON_C_CXX_FLAGS "${MESHLIB_COMMON_C_CXX_FLAGS} /wd4061 /wd4250 /wd4324 /wd4365 /wd4371 /wd4388 /wd4435 /wd4514 /wd4582 /wd4583 /wd4599 /wd4605 /wd4623 /wd4625 /wd4626 /wd4668 /wd4686 /wd4710 /wd4711 /wd4820 /wd4865 /wd4866 /wd4868 /wd5026 /wd5027 /wd5031 /wd5039 /wd5045 /wd5104 /wd5105 /wd5219 /wd5243 /wd5246 /wd5262 /wd5264 /wd26451") ELSE() set(MESHLIB_COMMON_C_CXX_FLAGS "${MESHLIB_COMMON_C_CXX_FLAGS} -Wall -Wextra -Wno-missing-field-initializers -Wno-unknown-pragmas -Wno-sign-compare -Werror -fvisibility=hidden -pedantic-errors") + # command line option '-fvisibility-inlines-hidden' is valid for C++/ObjC++ but not for C, so we cannot put it in MESHLIB_COMMON_C_CXX_FLAGS + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden") IF(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") set(MESHLIB_COMMON_C_CXX_FLAGS "${MESHLIB_COMMON_C_CXX_FLAGS} -Wno-newline-eof") From e0d2d3d0fb9f2367cdd4b2fcb0ea14ed435a305b Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Thu, 27 Nov 2025 21:43:22 +0300 Subject: [PATCH 48/56] no pointers --- source/MRMesh/MRICP.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 93c955a8e90f..35253f510b12 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -389,9 +389,6 @@ struct __attribute__((visibility("default"))) A { void bar(); }; -auto pfoo = &A::foo; -auto pbar = &A::bar; - void A::bar() {} bool ICP::p2plIter_() From e6707eee9b4b54eb534d074ec3d46783abaa702c Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Thu, 27 Nov 2025 22:19:03 +0300 Subject: [PATCH 49/56] remove -fvisibility-inlines-hidden --- cmake/Modules/CompilerOptions.cmake | 2 -- 1 file changed, 2 deletions(-) diff --git a/cmake/Modules/CompilerOptions.cmake b/cmake/Modules/CompilerOptions.cmake index 0817b2b5dd6b..6d3eada31e15 100644 --- a/cmake/Modules/CompilerOptions.cmake +++ b/cmake/Modules/CompilerOptions.cmake @@ -84,8 +84,6 @@ IF(MSVC) set(MESHLIB_COMMON_C_CXX_FLAGS "${MESHLIB_COMMON_C_CXX_FLAGS} /wd4061 /wd4250 /wd4324 /wd4365 /wd4371 /wd4388 /wd4435 /wd4514 /wd4582 /wd4583 /wd4599 /wd4605 /wd4623 /wd4625 /wd4626 /wd4668 /wd4686 /wd4710 /wd4711 /wd4820 /wd4865 /wd4866 /wd4868 /wd5026 /wd5027 /wd5031 /wd5039 /wd5045 /wd5104 /wd5105 /wd5219 /wd5243 /wd5246 /wd5262 /wd5264 /wd26451") ELSE() set(MESHLIB_COMMON_C_CXX_FLAGS "${MESHLIB_COMMON_C_CXX_FLAGS} -Wall -Wextra -Wno-missing-field-initializers -Wno-unknown-pragmas -Wno-sign-compare -Werror -fvisibility=hidden -pedantic-errors") - # command line option '-fvisibility-inlines-hidden' is valid for C++/ObjC++ but not for C, so we cannot put it in MESHLIB_COMMON_C_CXX_FLAGS - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden") IF(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") set(MESHLIB_COMMON_C_CXX_FLAGS "${MESHLIB_COMMON_C_CXX_FLAGS} -Wno-newline-eof") From 5263be5fde647d92dfd8e0139891b51d381f091e Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Fri, 28 Nov 2025 11:51:25 +0300 Subject: [PATCH 50/56] test mac --- cmake/Modules/CompilerOptions.cmake | 2 ++ source/MRMesh/MRICP.cpp | 3 +++ 2 files changed, 5 insertions(+) diff --git a/cmake/Modules/CompilerOptions.cmake b/cmake/Modules/CompilerOptions.cmake index 6d3eada31e15..0817b2b5dd6b 100644 --- a/cmake/Modules/CompilerOptions.cmake +++ b/cmake/Modules/CompilerOptions.cmake @@ -84,6 +84,8 @@ IF(MSVC) set(MESHLIB_COMMON_C_CXX_FLAGS "${MESHLIB_COMMON_C_CXX_FLAGS} /wd4061 /wd4250 /wd4324 /wd4365 /wd4371 /wd4388 /wd4435 /wd4514 /wd4582 /wd4583 /wd4599 /wd4605 /wd4623 /wd4625 /wd4626 /wd4668 /wd4686 /wd4710 /wd4711 /wd4820 /wd4865 /wd4866 /wd4868 /wd5026 /wd5027 /wd5031 /wd5039 /wd5045 /wd5104 /wd5105 /wd5219 /wd5243 /wd5246 /wd5262 /wd5264 /wd26451") ELSE() set(MESHLIB_COMMON_C_CXX_FLAGS "${MESHLIB_COMMON_C_CXX_FLAGS} -Wall -Wextra -Wno-missing-field-initializers -Wno-unknown-pragmas -Wno-sign-compare -Werror -fvisibility=hidden -pedantic-errors") + # command line option '-fvisibility-inlines-hidden' is valid for C++/ObjC++ but not for C, so we cannot put it in MESHLIB_COMMON_C_CXX_FLAGS + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden") IF(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") set(MESHLIB_COMMON_C_CXX_FLAGS "${MESHLIB_COMMON_C_CXX_FLAGS} -Wno-newline-eof") diff --git a/source/MRMesh/MRICP.cpp b/source/MRMesh/MRICP.cpp index 35253f510b12..93c955a8e90f 100644 --- a/source/MRMesh/MRICP.cpp +++ b/source/MRMesh/MRICP.cpp @@ -389,6 +389,9 @@ struct __attribute__((visibility("default"))) A { void bar(); }; +auto pfoo = &A::foo; +auto pbar = &A::bar; + void A::bar() {} bool ICP::p2plIter_() From 1cb581041502efe24ada9b55223e368ad81d569b Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Fri, 28 Nov 2025 12:07:35 +0300 Subject: [PATCH 51/56] objdump --- .github/workflows/build-test-macos.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-test-macos.yml b/.github/workflows/build-test-macos.yml index ab6861a1571d..1c2994f9266a 100644 --- a/.github/workflows/build-test-macos.yml +++ b/.github/workflows/build-test-macos.yml @@ -168,9 +168,11 @@ jobs: run: ./build/${{ matrix.config }}/bin/MeshViewer -tryHidden -noEventLoop -unloadPluginsAtEnd - name: Unit Tests - run: ./build/${{ matrix.config }}/bin/MRTest + run: | + objdump -T ./build/${{ matrix.config }}/bin/libMRMesh.dylib | c++filt + ./build/${{ matrix.config }}/bin/MRTest - - name: C Unit Tests (old bindings) + - name: C Unit Tests (old bindings) run: ./build/${{ matrix.config }}/bin/MRTestC - name: C Unit Tests From 5027c8e0e7db12cb1e0a0b3c1a2e8cbcbb9b8ce7 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Fri, 28 Nov 2025 12:10:41 +0300 Subject: [PATCH 52/56] fix indent --- .github/workflows/build-test-macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-test-macos.yml b/.github/workflows/build-test-macos.yml index 1c2994f9266a..e87371212a2a 100644 --- a/.github/workflows/build-test-macos.yml +++ b/.github/workflows/build-test-macos.yml @@ -172,7 +172,7 @@ jobs: objdump -T ./build/${{ matrix.config }}/bin/libMRMesh.dylib | c++filt ./build/${{ matrix.config }}/bin/MRTest - - name: C Unit Tests (old bindings) + - name: C Unit Tests (old bindings) run: ./build/${{ matrix.config }}/bin/MRTestC - name: C Unit Tests From 8729b52e5ab8cc678b428e07ee1a3d6697283d66 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Fri, 28 Nov 2025 13:08:38 +0300 Subject: [PATCH 53/56] nm -DC --- .github/workflows/build-test-macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-test-macos.yml b/.github/workflows/build-test-macos.yml index e87371212a2a..68c715c923ea 100644 --- a/.github/workflows/build-test-macos.yml +++ b/.github/workflows/build-test-macos.yml @@ -169,7 +169,7 @@ jobs: - name: Unit Tests run: | - objdump -T ./build/${{ matrix.config }}/bin/libMRMesh.dylib | c++filt + nm -DC ./build/${{ matrix.config }}/bin/libMRMesh.dylib | c++filt ./build/${{ matrix.config }}/bin/MRTest - name: C Unit Tests (old bindings) From fbff883113d75ab48c0c70fe8082ad6b5b43b241 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Fri, 28 Nov 2025 13:31:42 +0300 Subject: [PATCH 54/56] nm -gU --- .github/workflows/build-test-macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-test-macos.yml b/.github/workflows/build-test-macos.yml index 68c715c923ea..e236e5880040 100644 --- a/.github/workflows/build-test-macos.yml +++ b/.github/workflows/build-test-macos.yml @@ -169,7 +169,7 @@ jobs: - name: Unit Tests run: | - nm -DC ./build/${{ matrix.config }}/bin/libMRMesh.dylib | c++filt + nm -gU ./build/${{ matrix.config }}/bin/libMRMesh.dylib | c++filt ./build/${{ matrix.config }}/bin/MRTest - name: C Unit Tests (old bindings) From 853e17cdefb53dda36ab77f294e9118b650e8475 Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Fri, 28 Nov 2025 14:15:05 +0300 Subject: [PATCH 55/56] llvm-cxxfilt --- .github/workflows/build-test-macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-test-macos.yml b/.github/workflows/build-test-macos.yml index e236e5880040..c839d190f2fc 100644 --- a/.github/workflows/build-test-macos.yml +++ b/.github/workflows/build-test-macos.yml @@ -169,7 +169,7 @@ jobs: - name: Unit Tests run: | - nm -gU ./build/${{ matrix.config }}/bin/libMRMesh.dylib | c++filt + nm -gU ./build/${{ matrix.config }}/bin/libMRMesh.dylib | llvm-cxxfilt ./build/${{ matrix.config }}/bin/MRTest - name: C Unit Tests (old bindings) From 75fce7c1c8304a72f1e454e790a00472e9b12ced Mon Sep 17 00:00:00 2001 From: Fedor Chelnokov Date: Fri, 28 Nov 2025 14:56:19 +0300 Subject: [PATCH 56/56] export PATH="$(brew --prefix llvm@18)/bin:$PATH" --- .github/workflows/build-test-macos.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-test-macos.yml b/.github/workflows/build-test-macos.yml index c839d190f2fc..676312ecc0b1 100644 --- a/.github/workflows/build-test-macos.yml +++ b/.github/workflows/build-test-macos.yml @@ -169,6 +169,7 @@ jobs: - name: Unit Tests run: | + export PATH="$(brew --prefix llvm@18)/bin:$PATH" nm -gU ./build/${{ matrix.config }}/bin/libMRMesh.dylib | llvm-cxxfilt ./build/${{ matrix.config }}/bin/MRTest