From bb55c15629ea06ba4fb36a8ef42f352407685e60 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Tue, 12 Jul 2022 13:14:31 +0500 Subject: [PATCH 01/15] Simple algorithm --- source/MRMesh/MRPolylineRelax.cpp | 64 +++++++++++++++++++++++++++++++ source/MRMesh/MRPolylineRelax.h | 27 +++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 source/MRMesh/MRPolylineRelax.cpp create mode 100644 source/MRMesh/MRPolylineRelax.h diff --git a/source/MRMesh/MRPolylineRelax.cpp b/source/MRMesh/MRPolylineRelax.cpp new file mode 100644 index 000000000000..814727bdd927 --- /dev/null +++ b/source/MRMesh/MRPolylineRelax.cpp @@ -0,0 +1,64 @@ +#include "MRBitSetParallelFor.h" +#include "MRPolyline.h" +#include "MRPolylineRelax.h" +#include "MRTimer.h" + +namespace MR +{ + +bool relax( Polyline3 &polyline, const PolylineRelaxParams ¶ms, ProgressCallback cb ) +{ + if ( params.iterations <= 0 ) + return true; + + MR_TIMER + + VertCoords newPoints; + const auto& zone = polyline.topology.getValidVerts(); + + bool keepGoing = true; + for ( int i = 0; i < params.iterations; ++i ) + { + ProgressCallback internalCb; + if ( cb ) + { + internalCb = [&]( float p ) + { + return cb(( float( i ) + p ) / float( params.iterations )); + }; + } + + newPoints = polyline.points; + keepGoing = BitSetParallelFor( zone, [&]( VertId v ) + { + auto e0 = polyline.topology.edgeWithOrg( v ); + auto e1 = polyline.topology.next( e0 ); + if ( !e0.valid() || !e1.valid() ) + return; + + Vector3d sum; + sum += Vector3d( polyline.points[polyline.topology.dest( e0 )] ); + sum += Vector3d( polyline.points[polyline.topology.dest( e1 )] ); + + auto& np = newPoints[v]; + auto pushForce = params.force * ( Vector3f{sum / 2.} - np ); + np += pushForce; + }, internalCb ); + polyline.points.swap( newPoints ); + if ( !keepGoing ) + break; + } + return keepGoing; +} + +bool relaxKeepVolume( Polyline3 &polyline, const PolylineRelaxParams ¶ms, ProgressCallback cb ) +{ + if ( params.iterations <= 0 ) + return true; + + MR_TIMER + + return false; +} + +} // namespace MR \ No newline at end of file diff --git a/source/MRMesh/MRPolylineRelax.h b/source/MRMesh/MRPolylineRelax.h new file mode 100644 index 000000000000..b7192d862d73 --- /dev/null +++ b/source/MRMesh/MRPolylineRelax.h @@ -0,0 +1,27 @@ +#pragma once +#include "MRMeshFwd.h" +#include "MRMeshRelax.h" + +namespace MR +{ + +/// \addtogroup PolylineGroup +/// \{ + +struct PolylineRelaxParams : RelaxParams +{ + // +}; + +/// applies given number of relaxation iterations to the whole pointCloud ( or some region if it is specified ) +/// \return true if was finished successfully, false if was interrupted by progress callback +MRMESH_API bool relax( Polyline3& polyline, const PolylineRelaxParams& params = {}, ProgressCallback cb = {} ); + +/// applies given number of relaxation iterations to the whole pointCloud ( or some region if it is specified ) +/// do not really keeps volume but tries hard +/// \return true if was finished successfully, false if was interrupted by progress callback +MRMESH_API bool relaxKeepVolume( Polyline3& polyline, const PolylineRelaxParams& params = {}, ProgressCallback cb = {} ); + +/// \} + +} // namespace MR From 73de5774f3087a8878404e1fa75f8d12efaaf5a0 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Tue, 12 Jul 2022 13:57:04 +0500 Subject: [PATCH 02/15] Keep Area algorithm --- source/MRMesh/MRPolylineRelax.cpp | 62 ++++++++++++++++++++++++++++++- source/MRMesh/MRPolylineRelax.h | 8 ++-- 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/source/MRMesh/MRPolylineRelax.cpp b/source/MRMesh/MRPolylineRelax.cpp index 814727bdd927..796a5abbe9cf 100644 --- a/source/MRMesh/MRPolylineRelax.cpp +++ b/source/MRMesh/MRPolylineRelax.cpp @@ -2,6 +2,7 @@ #include "MRPolyline.h" #include "MRPolylineRelax.h" #include "MRTimer.h" +#include "MRWriter.h" namespace MR { @@ -12,6 +13,7 @@ bool relax( Polyline3 &polyline, const PolylineRelaxParams ¶ms, ProgressCall return true; MR_TIMER + MR_WRITER(polyline) VertCoords newPoints; const auto& zone = polyline.topology.getValidVerts(); @@ -51,14 +53,70 @@ bool relax( Polyline3 &polyline, const PolylineRelaxParams ¶ms, ProgressCall return keepGoing; } -bool relaxKeepVolume( Polyline3 &polyline, const PolylineRelaxParams ¶ms, ProgressCallback cb ) +bool relaxKeepArea( Polyline3 &polyline, const PolylineRelaxParams ¶ms, ProgressCallback cb ) { if ( params.iterations <= 0 ) return true; MR_TIMER + MR_WRITER(polyline) - return false; + VertCoords newPoints; + const auto& zone = polyline.topology.getValidVerts(); + std::vector vertPushForces( zone.size() ); + + bool keepGoing = true; + for ( int i = 0; i < params.iterations; ++i ) + { + ProgressCallback internalCb1, internalCb2; + if ( cb ) + { + internalCb1 = [&] ( float p ) + { + return cb( ( float( i ) + p * 0.5f ) / float( params.iterations ) ); + }; + internalCb2 = [&] ( float p ) + { + return cb( ( float( i ) + p * 0.5f + 0.5f ) / float( params.iterations ) ); + }; + } + + keepGoing = BitSetParallelFor( zone, [&]( VertId v ) + { + auto e0 = polyline.topology.edgeWithOrg( v ); + auto e1 = polyline.topology.next( e0 ); + if ( !e0.valid() || !e1.valid() ) + return; + + Vector3d sum; + sum += Vector3d( polyline.points[polyline.topology.dest( e0 )] ); + sum += Vector3d( polyline.points[polyline.topology.dest( e1 )] ); + + vertPushForces[v] = params.force * ( Vector3f{sum / 2.} - polyline.points[v] ); + }, internalCb1 ); + if ( !keepGoing ) + break; + + newPoints = polyline.points; + keepGoing = BitSetParallelFor( zone, [&]( VertId v ) + { + auto e0 = polyline.topology.edgeWithOrg( v ); + auto e1 = polyline.topology.next( e0 ); + if ( !e0.valid() || !e1.valid() ) + return; + + auto& np = newPoints[v]; + np += vertPushForces[v]; + auto modifier = 1.0f / 2.0f; + np -= ( vertPushForces[polyline.topology.dest( e0 )] * modifier ); + np -= ( vertPushForces[polyline.topology.dest( e1 )] * modifier ); + }, internalCb2 ); + polyline.points.swap( newPoints ); + if ( !keepGoing ) + break; + } + + return keepGoing; } } // namespace MR \ No newline at end of file diff --git a/source/MRMesh/MRPolylineRelax.h b/source/MRMesh/MRPolylineRelax.h index b7192d862d73..51b9393276c3 100644 --- a/source/MRMesh/MRPolylineRelax.h +++ b/source/MRMesh/MRPolylineRelax.h @@ -13,14 +13,14 @@ struct PolylineRelaxParams : RelaxParams // }; -/// applies given number of relaxation iterations to the whole pointCloud ( or some region if it is specified ) +/// applies given number of relaxation iterations to the whole polyline ( or some region if it is specified ) /// \return true if was finished successfully, false if was interrupted by progress callback MRMESH_API bool relax( Polyline3& polyline, const PolylineRelaxParams& params = {}, ProgressCallback cb = {} ); -/// applies given number of relaxation iterations to the whole pointCloud ( or some region if it is specified ) -/// do not really keeps volume but tries hard +/// applies given number of relaxation iterations to the whole polyline ( or some region if it is specified ) +/// do not really keeps area but tries hard /// \return true if was finished successfully, false if was interrupted by progress callback -MRMESH_API bool relaxKeepVolume( Polyline3& polyline, const PolylineRelaxParams& params = {}, ProgressCallback cb = {} ); +MRMESH_API bool relaxKeepArea( Polyline3& polyline, const PolylineRelaxParams& params = {}, ProgressCallback cb = {} ); /// \} From f96daae77846af66d7d4c29ecbc37c71d246f698 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Tue, 12 Jul 2022 15:24:09 +0500 Subject: [PATCH 03/15] Use more relevant method --- source/MRMesh/MRPolylineRelax.cpp | 4 ++-- source/MRMesh/MRPolylineRelax.h | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/source/MRMesh/MRPolylineRelax.cpp b/source/MRMesh/MRPolylineRelax.cpp index 796a5abbe9cf..afb8a7692412 100644 --- a/source/MRMesh/MRPolylineRelax.cpp +++ b/source/MRMesh/MRPolylineRelax.cpp @@ -16,7 +16,7 @@ bool relax( Polyline3 &polyline, const PolylineRelaxParams ¶ms, ProgressCall MR_WRITER(polyline) VertCoords newPoints; - const auto& zone = polyline.topology.getValidVerts(); + const auto& zone = polyline.topology.getVertIds( params.region ); bool keepGoing = true; for ( int i = 0; i < params.iterations; ++i ) @@ -62,7 +62,7 @@ bool relaxKeepArea( Polyline3 &polyline, const PolylineRelaxParams ¶ms, Prog MR_WRITER(polyline) VertCoords newPoints; - const auto& zone = polyline.topology.getValidVerts(); + const auto& zone = polyline.topology.getVertIds( params.region ); std::vector vertPushForces( zone.size() ); bool keepGoing = true; diff --git a/source/MRMesh/MRPolylineRelax.h b/source/MRMesh/MRPolylineRelax.h index 51b9393276c3..ad1fe9359e6f 100644 --- a/source/MRMesh/MRPolylineRelax.h +++ b/source/MRMesh/MRPolylineRelax.h @@ -10,7 +10,6 @@ namespace MR struct PolylineRelaxParams : RelaxParams { - // }; /// applies given number of relaxation iterations to the whole polyline ( or some region if it is specified ) From 27ea00769ee0b01854b19a5db859695f96f52c5a Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Tue, 12 Jul 2022 18:00:44 +0500 Subject: [PATCH 04/15] Update Visual Studio project --- source/MRMesh/MRMesh.vcxproj | 2 ++ source/MRMesh/MRMesh.vcxproj.filters | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/source/MRMesh/MRMesh.vcxproj b/source/MRMesh/MRMesh.vcxproj index 8e948f8493a3..846c58daef83 100644 --- a/source/MRMesh/MRMesh.vcxproj +++ b/source/MRMesh/MRMesh.vcxproj @@ -257,6 +257,7 @@ + @@ -459,6 +460,7 @@ + diff --git a/source/MRMesh/MRMesh.vcxproj.filters b/source/MRMesh/MRMesh.vcxproj.filters index 143b3846d8cd..086fc91b41bc 100644 --- a/source/MRMesh/MRMesh.vcxproj.filters +++ b/source/MRMesh/MRMesh.vcxproj.filters @@ -843,6 +843,9 @@ Source Files\History + + Source Files\Polyline + @@ -1427,6 +1430,9 @@ Source Files\Polyline + + Source Files\Polyline + From 6cb4e9948665804a9beda0500cffb6721fd84c30 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Tue, 12 Jul 2022 18:08:17 +0500 Subject: [PATCH 05/15] Reuse code for 2D polylines --- source/MRMesh/MRPolylineRelax.cpp | 67 +++++++++++++++++++++++++------ source/MRMesh/MRPolylineRelax.h | 2 + 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/source/MRMesh/MRPolylineRelax.cpp b/source/MRMesh/MRPolylineRelax.cpp index afb8a7692412..6ff4c6f707c5 100644 --- a/source/MRMesh/MRPolylineRelax.cpp +++ b/source/MRMesh/MRPolylineRelax.cpp @@ -2,12 +2,30 @@ #include "MRPolyline.h" #include "MRPolylineRelax.h" #include "MRTimer.h" +#include "MRVector2.h" #include "MRWriter.h" +namespace +{ + +template +struct SubstType +{ +}; + +template typename C, typename B> +struct SubstType> +{ + using type = C; +}; + +} + namespace MR { -bool relax( Polyline3 &polyline, const PolylineRelaxParams ¶ms, ProgressCallback cb ) +template +bool relaxImpl( Polyline &polyline, const PolylineRelaxParams ¶ms, ProgressCallback cb ) { if ( params.iterations <= 0 ) return true; @@ -15,7 +33,7 @@ bool relax( Polyline3 &polyline, const PolylineRelaxParams ¶ms, ProgressCall MR_TIMER MR_WRITER(polyline) - VertCoords newPoints; + Vector newPoints; const auto& zone = polyline.topology.getVertIds( params.region ); bool keepGoing = true; @@ -38,12 +56,13 @@ bool relax( Polyline3 &polyline, const PolylineRelaxParams ¶ms, ProgressCall if ( !e0.valid() || !e1.valid() ) return; - Vector3d sum; - sum += Vector3d( polyline.points[polyline.topology.dest( e0 )] ); - sum += Vector3d( polyline.points[polyline.topology.dest( e1 )] ); + using VectorD = typename SubstType::type; + VectorD sum; + sum += VectorD( polyline.points[polyline.topology.dest( e0 )] ); + sum += VectorD( polyline.points[polyline.topology.dest( e1 )] ); auto& np = newPoints[v]; - auto pushForce = params.force * ( Vector3f{sum / 2.} - np ); + auto pushForce = params.force * ( V( sum / 2. ) - np ); np += pushForce; }, internalCb ); polyline.points.swap( newPoints ); @@ -53,7 +72,8 @@ bool relax( Polyline3 &polyline, const PolylineRelaxParams ¶ms, ProgressCall return keepGoing; } -bool relaxKeepArea( Polyline3 &polyline, const PolylineRelaxParams ¶ms, ProgressCallback cb ) +template +bool relaxKeepAreaImpl( Polyline &polyline, const PolylineRelaxParams ¶ms, ProgressCallback cb ) { if ( params.iterations <= 0 ) return true; @@ -61,9 +81,9 @@ bool relaxKeepArea( Polyline3 &polyline, const PolylineRelaxParams ¶ms, Prog MR_TIMER MR_WRITER(polyline) - VertCoords newPoints; + Vector newPoints; const auto& zone = polyline.topology.getVertIds( params.region ); - std::vector vertPushForces( zone.size() ); + std::vector vertPushForces( zone.size() ); bool keepGoing = true; for ( int i = 0; i < params.iterations; ++i ) @@ -88,11 +108,12 @@ bool relaxKeepArea( Polyline3 &polyline, const PolylineRelaxParams ¶ms, Prog if ( !e0.valid() || !e1.valid() ) return; - Vector3d sum; - sum += Vector3d( polyline.points[polyline.topology.dest( e0 )] ); - sum += Vector3d( polyline.points[polyline.topology.dest( e1 )] ); + using VectorD = typename SubstType::type; + VectorD sum; + sum += VectorD( polyline.points[polyline.topology.dest( e0 )] ); + sum += VectorD( polyline.points[polyline.topology.dest( e1 )] ); - vertPushForces[v] = params.force * ( Vector3f{sum / 2.} - polyline.points[v] ); + vertPushForces[v] = params.force * ( V( sum / 2. ) - polyline.points[v] ); }, internalCb1 ); if ( !keepGoing ) break; @@ -119,4 +140,24 @@ bool relaxKeepArea( Polyline3 &polyline, const PolylineRelaxParams ¶ms, Prog return keepGoing; } +bool relax( Polyline2 &polyline, const PolylineRelaxParams ¶ms, ProgressCallback cb ) +{ + return relaxImpl( polyline, params, std::move(cb) ); +} + +bool relax( Polyline3 &polyline, const PolylineRelaxParams ¶ms, ProgressCallback cb ) +{ + return relaxImpl( polyline, params, std::move(cb) ); +} + +bool relaxKeepArea( Polyline2 &polyline, const PolylineRelaxParams ¶ms, ProgressCallback cb ) +{ + return relaxKeepAreaImpl( polyline, params, std::move(cb) ); +} + +bool relaxKeepArea( Polyline3 &polyline, const PolylineRelaxParams ¶ms, ProgressCallback cb ) +{ + return relaxKeepAreaImpl( polyline, params, std::move(cb) ); +} + } // namespace MR \ No newline at end of file diff --git a/source/MRMesh/MRPolylineRelax.h b/source/MRMesh/MRPolylineRelax.h index ad1fe9359e6f..dadf74f4b1da 100644 --- a/source/MRMesh/MRPolylineRelax.h +++ b/source/MRMesh/MRPolylineRelax.h @@ -14,11 +14,13 @@ struct PolylineRelaxParams : RelaxParams /// applies given number of relaxation iterations to the whole polyline ( or some region if it is specified ) /// \return true if was finished successfully, false if was interrupted by progress callback +MRMESH_API bool relax( Polyline2& polyline, const PolylineRelaxParams& params = {}, ProgressCallback cb = {} ); MRMESH_API bool relax( Polyline3& polyline, const PolylineRelaxParams& params = {}, ProgressCallback cb = {} ); /// applies given number of relaxation iterations to the whole polyline ( or some region if it is specified ) /// do not really keeps area but tries hard /// \return true if was finished successfully, false if was interrupted by progress callback +MRMESH_API bool relaxKeepArea( Polyline2& polyline, const PolylineRelaxParams& params = {}, ProgressCallback cb = {} ); MRMESH_API bool relaxKeepArea( Polyline3& polyline, const PolylineRelaxParams& params = {}, ProgressCallback cb = {} ); /// \} From 168350c1af32a6bc74e5245a84b6530eba5115ab Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Tue, 12 Jul 2022 18:10:09 +0500 Subject: [PATCH 06/15] Use more relevant method --- source/MRMesh/MRPolylineRelax.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/MRMesh/MRPolylineRelax.cpp b/source/MRMesh/MRPolylineRelax.cpp index 6ff4c6f707c5..ebf59a0c7d45 100644 --- a/source/MRMesh/MRPolylineRelax.cpp +++ b/source/MRMesh/MRPolylineRelax.cpp @@ -58,8 +58,8 @@ bool relaxImpl( Polyline &polyline, const PolylineRelaxParams ¶ms, Progre using VectorD = typename SubstType::type; VectorD sum; - sum += VectorD( polyline.points[polyline.topology.dest( e0 )] ); - sum += VectorD( polyline.points[polyline.topology.dest( e1 )] ); + sum += VectorD( polyline.destPnt( e0 ) ); + sum += VectorD( polyline.destPnt( e1 ) ); auto& np = newPoints[v]; auto pushForce = params.force * ( V( sum / 2. ) - np ); @@ -110,8 +110,8 @@ bool relaxKeepAreaImpl( Polyline &polyline, const PolylineRelaxParams ¶ms using VectorD = typename SubstType::type; VectorD sum; - sum += VectorD( polyline.points[polyline.topology.dest( e0 )] ); - sum += VectorD( polyline.points[polyline.topology.dest( e1 )] ); + sum += VectorD( polyline.destPnt( e0 ) ); + sum += VectorD( polyline.destPnt( e1 ) ); vertPushForces[v] = params.force * ( V( sum / 2. ) - polyline.points[v] ); }, internalCb1 ); From b54a7950f3616686639a8230be284169677eae56 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Tue, 12 Jul 2022 18:14:08 +0500 Subject: [PATCH 07/15] Remove empty struct --- source/MRMesh/MRPolylineRelax.cpp | 12 ++++++------ source/MRMesh/MRPolylineRelax.h | 12 ++++-------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/source/MRMesh/MRPolylineRelax.cpp b/source/MRMesh/MRPolylineRelax.cpp index ebf59a0c7d45..7f74d61ecfbb 100644 --- a/source/MRMesh/MRPolylineRelax.cpp +++ b/source/MRMesh/MRPolylineRelax.cpp @@ -25,7 +25,7 @@ namespace MR { template -bool relaxImpl( Polyline &polyline, const PolylineRelaxParams ¶ms, ProgressCallback cb ) +bool relaxImpl( Polyline &polyline, const RelaxParams ¶ms, ProgressCallback cb ) { if ( params.iterations <= 0 ) return true; @@ -73,7 +73,7 @@ bool relaxImpl( Polyline &polyline, const PolylineRelaxParams ¶ms, Progre } template -bool relaxKeepAreaImpl( Polyline &polyline, const PolylineRelaxParams ¶ms, ProgressCallback cb ) +bool relaxKeepAreaImpl( Polyline &polyline, const RelaxParams ¶ms, ProgressCallback cb ) { if ( params.iterations <= 0 ) return true; @@ -140,22 +140,22 @@ bool relaxKeepAreaImpl( Polyline &polyline, const PolylineRelaxParams ¶ms return keepGoing; } -bool relax( Polyline2 &polyline, const PolylineRelaxParams ¶ms, ProgressCallback cb ) +bool relax( Polyline2 &polyline, const RelaxParams ¶ms, ProgressCallback cb ) { return relaxImpl( polyline, params, std::move(cb) ); } -bool relax( Polyline3 &polyline, const PolylineRelaxParams ¶ms, ProgressCallback cb ) +bool relax( Polyline3 &polyline, const RelaxParams ¶ms, ProgressCallback cb ) { return relaxImpl( polyline, params, std::move(cb) ); } -bool relaxKeepArea( Polyline2 &polyline, const PolylineRelaxParams ¶ms, ProgressCallback cb ) +bool relaxKeepArea( Polyline2 &polyline, const RelaxParams ¶ms, ProgressCallback cb ) { return relaxKeepAreaImpl( polyline, params, std::move(cb) ); } -bool relaxKeepArea( Polyline3 &polyline, const PolylineRelaxParams ¶ms, ProgressCallback cb ) +bool relaxKeepArea( Polyline3 &polyline, const RelaxParams ¶ms, ProgressCallback cb ) { return relaxKeepAreaImpl( polyline, params, std::move(cb) ); } diff --git a/source/MRMesh/MRPolylineRelax.h b/source/MRMesh/MRPolylineRelax.h index dadf74f4b1da..06d7bbf7559b 100644 --- a/source/MRMesh/MRPolylineRelax.h +++ b/source/MRMesh/MRPolylineRelax.h @@ -8,20 +8,16 @@ namespace MR /// \addtogroup PolylineGroup /// \{ -struct PolylineRelaxParams : RelaxParams -{ -}; - /// applies given number of relaxation iterations to the whole polyline ( or some region if it is specified ) /// \return true if was finished successfully, false if was interrupted by progress callback -MRMESH_API bool relax( Polyline2& polyline, const PolylineRelaxParams& params = {}, ProgressCallback cb = {} ); -MRMESH_API bool relax( Polyline3& polyline, const PolylineRelaxParams& params = {}, ProgressCallback cb = {} ); +MRMESH_API bool relax( Polyline2& polyline, const RelaxParams& params = {}, ProgressCallback cb = {} ); +MRMESH_API bool relax( Polyline3& polyline, const RelaxParams& params = {}, ProgressCallback cb = {} ); /// applies given number of relaxation iterations to the whole polyline ( or some region if it is specified ) /// do not really keeps area but tries hard /// \return true if was finished successfully, false if was interrupted by progress callback -MRMESH_API bool relaxKeepArea( Polyline2& polyline, const PolylineRelaxParams& params = {}, ProgressCallback cb = {} ); -MRMESH_API bool relaxKeepArea( Polyline3& polyline, const PolylineRelaxParams& params = {}, ProgressCallback cb = {} ); +MRMESH_API bool relaxKeepArea( Polyline2& polyline, const RelaxParams& params = {}, ProgressCallback cb = {} ); +MRMESH_API bool relaxKeepArea( Polyline3& polyline, const RelaxParams& params = {}, ProgressCallback cb = {} ); /// \} From 2653f7bc1c1bd65f4047ebf994640da51e11c353 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Tue, 12 Jul 2022 18:16:41 +0500 Subject: [PATCH 08/15] Fix lone edge check --- source/MRMesh/MRPolylineRelax.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/MRMesh/MRPolylineRelax.cpp b/source/MRMesh/MRPolylineRelax.cpp index 7f74d61ecfbb..ab014493f8c8 100644 --- a/source/MRMesh/MRPolylineRelax.cpp +++ b/source/MRMesh/MRPolylineRelax.cpp @@ -52,9 +52,9 @@ bool relaxImpl( Polyline &polyline, const RelaxParams ¶ms, ProgressCallba keepGoing = BitSetParallelFor( zone, [&]( VertId v ) { auto e0 = polyline.topology.edgeWithOrg( v ); - auto e1 = polyline.topology.next( e0 ); - if ( !e0.valid() || !e1.valid() ) + if ( polyline.topology.isLoneEdge( e0 ) ) return; + auto e1 = polyline.topology.next( e0 ); using VectorD = typename SubstType::type; VectorD sum; @@ -104,9 +104,9 @@ bool relaxKeepAreaImpl( Polyline &polyline, const RelaxParams ¶ms, Progre keepGoing = BitSetParallelFor( zone, [&]( VertId v ) { auto e0 = polyline.topology.edgeWithOrg( v ); - auto e1 = polyline.topology.next( e0 ); - if ( !e0.valid() || !e1.valid() ) + if ( polyline.topology.isLoneEdge( e0 ) ) return; + auto e1 = polyline.topology.next( e0 ); using VectorD = typename SubstType::type; VectorD sum; @@ -122,9 +122,9 @@ bool relaxKeepAreaImpl( Polyline &polyline, const RelaxParams ¶ms, Progre keepGoing = BitSetParallelFor( zone, [&]( VertId v ) { auto e0 = polyline.topology.edgeWithOrg( v ); - auto e1 = polyline.topology.next( e0 ); - if ( !e0.valid() || !e1.valid() ) + if ( polyline.topology.isLoneEdge( e0 ) ) return; + auto e1 = polyline.topology.next( e0 ); auto& np = newPoints[v]; np += vertPushForces[v]; From 3047b0f4be5c98c3a279a7e9aefc36642514e688 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Tue, 12 Jul 2022 18:33:33 +0500 Subject: [PATCH 09/15] Fix open polyline check --- source/MRMesh/MRPolylineRelax.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/source/MRMesh/MRPolylineRelax.cpp b/source/MRMesh/MRPolylineRelax.cpp index ab014493f8c8..eb2df2f17d57 100644 --- a/source/MRMesh/MRPolylineRelax.cpp +++ b/source/MRMesh/MRPolylineRelax.cpp @@ -52,9 +52,10 @@ bool relaxImpl( Polyline &polyline, const RelaxParams ¶ms, ProgressCallba keepGoing = BitSetParallelFor( zone, [&]( VertId v ) { auto e0 = polyline.topology.edgeWithOrg( v ); - if ( polyline.topology.isLoneEdge( e0 ) ) - return; + assert( !polyline.topology.isLoneEdge( e0 ) ); auto e1 = polyline.topology.next( e0 ); + if ( e0 == e1 ) + return; using VectorD = typename SubstType::type; VectorD sum; @@ -104,9 +105,10 @@ bool relaxKeepAreaImpl( Polyline &polyline, const RelaxParams ¶ms, Progre keepGoing = BitSetParallelFor( zone, [&]( VertId v ) { auto e0 = polyline.topology.edgeWithOrg( v ); - if ( polyline.topology.isLoneEdge( e0 ) ) - return; + assert( !polyline.topology.isLoneEdge( e0 ) ); auto e1 = polyline.topology.next( e0 ); + if ( e0 == e1 ) + return; using VectorD = typename SubstType::type; VectorD sum; @@ -122,9 +124,10 @@ bool relaxKeepAreaImpl( Polyline &polyline, const RelaxParams ¶ms, Progre keepGoing = BitSetParallelFor( zone, [&]( VertId v ) { auto e0 = polyline.topology.edgeWithOrg( v ); - if ( polyline.topology.isLoneEdge( e0 ) ) - return; + assert( !polyline.topology.isLoneEdge( e0 ) ); auto e1 = polyline.topology.next( e0 ); + if ( e0 == e1 ) + return; auto& np = newPoints[v]; np += vertPushForces[v]; From 23828ec064b1568696adf71c1b6052de6618590d Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Tue, 12 Jul 2022 19:06:34 +0500 Subject: [PATCH 10/15] Simplify code --- source/MRMesh/MRPolylineRelax.cpp | 30 ++++-------------------------- 1 file changed, 4 insertions(+), 26 deletions(-) diff --git a/source/MRMesh/MRPolylineRelax.cpp b/source/MRMesh/MRPolylineRelax.cpp index eb2df2f17d57..c5b403217104 100644 --- a/source/MRMesh/MRPolylineRelax.cpp +++ b/source/MRMesh/MRPolylineRelax.cpp @@ -5,22 +5,6 @@ #include "MRVector2.h" #include "MRWriter.h" -namespace -{ - -template -struct SubstType -{ -}; - -template typename C, typename B> -struct SubstType> -{ - using type = C; -}; - -} - namespace MR { @@ -57,13 +41,10 @@ bool relaxImpl( Polyline &polyline, const RelaxParams ¶ms, ProgressCallba if ( e0 == e1 ) return; - using VectorD = typename SubstType::type; - VectorD sum; - sum += VectorD( polyline.destPnt( e0 ) ); - sum += VectorD( polyline.destPnt( e1 ) ); + auto mp = ( polyline.destPnt( e0 ) + polyline.destPnt( e1 ) ) / 2.f; auto& np = newPoints[v]; - auto pushForce = params.force * ( V( sum / 2. ) - np ); + auto pushForce = params.force * ( mp - np ); np += pushForce; }, internalCb ); polyline.points.swap( newPoints ); @@ -110,12 +91,9 @@ bool relaxKeepAreaImpl( Polyline &polyline, const RelaxParams ¶ms, Progre if ( e0 == e1 ) return; - using VectorD = typename SubstType::type; - VectorD sum; - sum += VectorD( polyline.destPnt( e0 ) ); - sum += VectorD( polyline.destPnt( e1 ) ); + auto mp = ( polyline.destPnt( e0 ) + polyline.destPnt( e1 ) ) / 2.f; - vertPushForces[v] = params.force * ( V( sum / 2. ) - polyline.points[v] ); + vertPushForces[v] = params.force * ( mp - polyline.points[v] ); }, internalCb1 ); if ( !keepGoing ) break; From 55d78a53b381efbe329dcc06c434ae5dd10894f0 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Tue, 12 Jul 2022 19:19:50 +0500 Subject: [PATCH 11/15] Fix template initialization --- source/MRMesh/MRPolylineRelax.cpp | 26 ++++++-------------------- source/MRMesh/MRPolylineRelax.h | 8 ++++---- 2 files changed, 10 insertions(+), 24 deletions(-) diff --git a/source/MRMesh/MRPolylineRelax.cpp b/source/MRMesh/MRPolylineRelax.cpp index c5b403217104..60e0bae79003 100644 --- a/source/MRMesh/MRPolylineRelax.cpp +++ b/source/MRMesh/MRPolylineRelax.cpp @@ -9,7 +9,7 @@ namespace MR { template -bool relaxImpl( Polyline &polyline, const RelaxParams ¶ms, ProgressCallback cb ) +bool relax( Polyline &polyline, const RelaxParams ¶ms, ProgressCallback cb ) { if ( params.iterations <= 0 ) return true; @@ -55,7 +55,7 @@ bool relaxImpl( Polyline &polyline, const RelaxParams ¶ms, ProgressCallba } template -bool relaxKeepAreaImpl( Polyline &polyline, const RelaxParams ¶ms, ProgressCallback cb ) +bool relaxKeepArea( Polyline &polyline, const RelaxParams ¶ms, ProgressCallback cb ) { if ( params.iterations <= 0 ) return true; @@ -121,24 +121,10 @@ bool relaxKeepAreaImpl( Polyline &polyline, const RelaxParams ¶ms, Progre return keepGoing; } -bool relax( Polyline2 &polyline, const RelaxParams ¶ms, ProgressCallback cb ) -{ - return relaxImpl( polyline, params, std::move(cb) ); -} - -bool relax( Polyline3 &polyline, const RelaxParams ¶ms, ProgressCallback cb ) -{ - return relaxImpl( polyline, params, std::move(cb) ); -} +template bool relax<>( Polyline2& polyline, const RelaxParams& params, ProgressCallback cb ); +template bool relax<>( Polyline3& polyline, const RelaxParams& params, ProgressCallback cb ); -bool relaxKeepArea( Polyline2 &polyline, const RelaxParams ¶ms, ProgressCallback cb ) -{ - return relaxKeepAreaImpl( polyline, params, std::move(cb) ); -} - -bool relaxKeepArea( Polyline3 &polyline, const RelaxParams ¶ms, ProgressCallback cb ) -{ - return relaxKeepAreaImpl( polyline, params, std::move(cb) ); -} +template bool relaxKeepArea<>( Polyline2 &polyline, const RelaxParams ¶ms, ProgressCallback cb ); +template bool relaxKeepArea<>( Polyline3 &polyline, const RelaxParams ¶ms, ProgressCallback cb ); } // namespace MR \ No newline at end of file diff --git a/source/MRMesh/MRPolylineRelax.h b/source/MRMesh/MRPolylineRelax.h index 06d7bbf7559b..53f6136e714f 100644 --- a/source/MRMesh/MRPolylineRelax.h +++ b/source/MRMesh/MRPolylineRelax.h @@ -10,14 +10,14 @@ namespace MR /// applies given number of relaxation iterations to the whole polyline ( or some region if it is specified ) /// \return true if was finished successfully, false if was interrupted by progress callback -MRMESH_API bool relax( Polyline2& polyline, const RelaxParams& params = {}, ProgressCallback cb = {} ); -MRMESH_API bool relax( Polyline3& polyline, const RelaxParams& params = {}, ProgressCallback cb = {} ); +template +MRMESH_API bool relax( Polyline& polyline, const RelaxParams& params = {}, ProgressCallback cb = {} ); /// applies given number of relaxation iterations to the whole polyline ( or some region if it is specified ) /// do not really keeps area but tries hard /// \return true if was finished successfully, false if was interrupted by progress callback -MRMESH_API bool relaxKeepArea( Polyline2& polyline, const RelaxParams& params = {}, ProgressCallback cb = {} ); -MRMESH_API bool relaxKeepArea( Polyline3& polyline, const RelaxParams& params = {}, ProgressCallback cb = {} ); +template +MRMESH_API bool relaxKeepArea( Polyline& polyline, const RelaxParams& params = {}, ProgressCallback cb = {} ); /// \} From 680357c4ddecaa3ae010ebdfbf3a3efb6fa30658 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Tue, 12 Jul 2022 19:46:28 +0500 Subject: [PATCH 12/15] Move common relax parameters to separate header --- source/MRMesh/MRMesh.vcxproj | 1 + source/MRMesh/MRMesh.vcxproj.filters | 3 +++ source/MRMesh/MRMeshRelax.h | 11 +---------- source/MRMesh/MRPointCloudRelax.h | 3 ++- source/MRMesh/MRPolylineRelax.h | 3 ++- source/MRMesh/MRRelaxParams.h | 17 +++++++++++++++++ 6 files changed, 26 insertions(+), 12 deletions(-) create mode 100644 source/MRMesh/MRRelaxParams.h diff --git a/source/MRMesh/MRMesh.vcxproj b/source/MRMesh/MRMesh.vcxproj index 846c58daef83..ccc6bd59c3cd 100644 --- a/source/MRMesh/MRMesh.vcxproj +++ b/source/MRMesh/MRMesh.vcxproj @@ -258,6 +258,7 @@ + diff --git a/source/MRMesh/MRMesh.vcxproj.filters b/source/MRMesh/MRMesh.vcxproj.filters index 086fc91b41bc..0fa4571dd6da 100644 --- a/source/MRMesh/MRMesh.vcxproj.filters +++ b/source/MRMesh/MRMesh.vcxproj.filters @@ -846,6 +846,9 @@ Source Files\Polyline + + Source Files + diff --git a/source/MRMesh/MRMeshRelax.h b/source/MRMesh/MRMeshRelax.h index f9b52723128a..848247c65286 100644 --- a/source/MRMesh/MRMeshRelax.h +++ b/source/MRMesh/MRMeshRelax.h @@ -1,6 +1,7 @@ #pragma once #include "MRMeshFwd.h" #include "MRProgressCallback.h" +#include "MRRelaxParams.h" namespace MR { @@ -9,16 +10,6 @@ namespace MR /// \ingroup MeshAlgorithmGroup /// \{ -struct RelaxParams -{ - /// number of iterations - int iterations{ 1 }; - /// region to relax - const VertBitSet* region{ nullptr }; - /// speed of relaxing, typical values (0.0, 0.5] - float force{ 0.5f }; -}; - struct MeshRelaxParams : RelaxParams { /// smooth tetrahedron verts (with complete three edges ring) to base triangle (based on its edges destinations) diff --git a/source/MRMesh/MRPointCloudRelax.h b/source/MRMesh/MRPointCloudRelax.h index 89ea45e4404e..21488a75ac5b 100644 --- a/source/MRMesh/MRPointCloudRelax.h +++ b/source/MRMesh/MRPointCloudRelax.h @@ -1,6 +1,7 @@ #pragma once #include "MRMeshFwd.h" -#include "MRMeshRelax.h" +#include "MRProgressCallback.h" +#include "MRRelaxParams.h" namespace MR { diff --git a/source/MRMesh/MRPolylineRelax.h b/source/MRMesh/MRPolylineRelax.h index 53f6136e714f..d182433f96c4 100644 --- a/source/MRMesh/MRPolylineRelax.h +++ b/source/MRMesh/MRPolylineRelax.h @@ -1,6 +1,7 @@ #pragma once #include "MRMeshFwd.h" -#include "MRMeshRelax.h" +#include "MRProgressCallback.h" +#include "MRRelaxParams.h" namespace MR { diff --git a/source/MRMesh/MRRelaxParams.h b/source/MRMesh/MRRelaxParams.h new file mode 100644 index 000000000000..3d43bd92fee5 --- /dev/null +++ b/source/MRMesh/MRRelaxParams.h @@ -0,0 +1,17 @@ +#pragma once +#include "MRMeshFwd.h" + +namespace MR +{ + +struct RelaxParams +{ + /// number of iterations + int iterations{1}; + /// region to relax + const VertBitSet *region{nullptr}; + /// speed of relaxing, typical values (0.0, 0.5] + float force{0.5f}; +}; + +} // namespace MR \ No newline at end of file From 8463dbdfabcd2065aa96709f7924be659c31f7cf Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Tue, 12 Jul 2022 19:53:01 +0500 Subject: [PATCH 13/15] Reorganize includes --- source/MRMesh/MRPolylineRelax.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/MRMesh/MRPolylineRelax.cpp b/source/MRMesh/MRPolylineRelax.cpp index 60e0bae79003..783e84c1da49 100644 --- a/source/MRMesh/MRPolylineRelax.cpp +++ b/source/MRMesh/MRPolylineRelax.cpp @@ -1,6 +1,6 @@ +#include "MRPolylineRelax.h" #include "MRBitSetParallelFor.h" #include "MRPolyline.h" -#include "MRPolylineRelax.h" #include "MRTimer.h" #include "MRVector2.h" #include "MRWriter.h" From 59423febb8dbcde1e142042025dd16f4bf350905 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Tue, 12 Jul 2022 19:55:27 +0500 Subject: [PATCH 14/15] Introduce Relax filter --- source/MRMesh/MRMesh.vcxproj.filters | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/MRMesh/MRMesh.vcxproj.filters b/source/MRMesh/MRMesh.vcxproj.filters index 0fa4571dd6da..886fc545462d 100644 --- a/source/MRMesh/MRMesh.vcxproj.filters +++ b/source/MRMesh/MRMesh.vcxproj.filters @@ -604,7 +604,7 @@ Source Files\AABBTree - Source Files\PointCloud + Source Files\Relax Source Files\Math @@ -733,7 +733,7 @@ Source Files\Mesh - Source Files\MeshAlgorithm + Source Files\Relax Source Files\MeshAlgorithm @@ -844,10 +844,10 @@ Source Files\History - Source Files\Polyline + Source Files\Relax - Source Files + Source Files\Relax From dc6cc087821e85eec3b671f1d90d0f0ca629f684 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Tue, 12 Jul 2022 19:57:38 +0500 Subject: [PATCH 15/15] Fix build --- source/MRMesh/MRMeshRelax.h | 6 ------ source/MRMesh/MRRelaxParams.h | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/MRMesh/MRMeshRelax.h b/source/MRMesh/MRMeshRelax.h index 848247c65286..6f89d55d9145 100644 --- a/source/MRMesh/MRMeshRelax.h +++ b/source/MRMesh/MRMeshRelax.h @@ -25,12 +25,6 @@ MRMESH_API bool relax( Mesh& mesh, const MeshRelaxParams& params = {}, ProgressC /// \return true if was finished successfully, false if was interrupted by progress callback MRMESH_API bool relaxKeepVolume( Mesh& mesh, const MeshRelaxParams& params = {}, ProgressCallback cb = {} ); -enum class RelaxApproxType -{ - Planar, - Quadric -}; - struct MeshApproxRelaxParams : MeshRelaxParams { /// radius to find neighbors by surface diff --git a/source/MRMesh/MRRelaxParams.h b/source/MRMesh/MRRelaxParams.h index 3d43bd92fee5..e3a764156901 100644 --- a/source/MRMesh/MRRelaxParams.h +++ b/source/MRMesh/MRRelaxParams.h @@ -14,4 +14,10 @@ struct RelaxParams float force{0.5f}; }; +enum class RelaxApproxType +{ + Planar, + Quadric, +}; + } // namespace MR \ No newline at end of file