#12957 Sector Model Export: add linear and logarithmic non-uniform refinement sub-modes

Add NonUniformSubMode enum (Custom Widths, Linear Equal Split, Logarithmic
Towards Center) to give users simpler alternatives to manually entering
comma-separated fractional widths.

Linear mode splits each cell in the range into N equal subcells.
Logarithmic mode auto-computes widths with finer resolution near the
center of the range using a geometric series.
This commit is contained in:
Kristian Bendiksen committed 2026-03-30 11:24:56 +02:00
1 parent a9918f814e
commit 282175bdb4
7 files changed
+402 -74

No files matched your search

@@ -19,6 +19,7 @@
#include "RigNonUniformRefinement.h"
#include <algorithm>
#include <cmath>
#include <numeric>
//--------------------------------------------------------------------------------------------------
@@ -185,8 +186,10 @@ void RigNonUniformRefinement::distributeWidthsAcrossCells( Dimension dim, size_t
// Always add 1.0 as the final boundary (the cell end)
localFractions.push_back( 1.0 );
setCumulativeFractions( dim, startIndex + c, localFractions );
m_fractions[dim][startIndex + c] = localFractions;
}
rebuildOffsets( dim );
}
//--------------------------------------------------------------------------------------------------
@@ -201,6 +204,72 @@ bool RigNonUniformRefinement::hasNonUniformRefinement() const
return false;
}
//--------------------------------------------------------------------------------------------------
/// Generate N equal cumulative fractions: {1/N, 2/N, ..., 1.0}.
//--------------------------------------------------------------------------------------------------
std::vector<double> RigNonUniformRefinement::generateEqualFractions( size_t subcellCount )
{
if ( subcellCount == 0 ) return { 1.0 };
std::vector<double> fractions;
fractions.reserve( subcellCount );
for ( size_t i = 1; i <= subcellCount; ++i )
{
fractions.push_back( static_cast<double>( i ) / static_cast<double>( subcellCount ) );
}
fractions.back() = 1.0;
return fractions;
}
//--------------------------------------------------------------------------------------------------
/// Generate logarithmic widths with finer resolution near the center.
/// Uses a geometric series with ratio ~2.0 for one half, then mirrors for symmetry.
/// Center cells get the smallest widths, edge cells the largest.
//--------------------------------------------------------------------------------------------------
std::vector<double> RigNonUniformRefinement::generateLogarithmicWidths( size_t totalCells )
{
if ( totalCells == 0 ) return {};
if ( totalCells == 1 ) return { 1.0 };
const double ratio = 2.0;
// Build widths for the first half (edge to center: large to small)
size_t halfCount = totalCells / 2;
std::vector<double> halfWidths;
halfWidths.reserve( halfCount );
for ( size_t i = 0; i < halfCount; ++i )
{
// Largest at index 0 (edge), smallest at index halfCount-1 (center)
halfWidths.push_back( std::pow( ratio, static_cast<double>( halfCount - 1 - i ) ) );
}
// Build full symmetric widths vector
std::vector<double> widths;
widths.reserve( totalCells );
// First half: edge to center
for ( size_t i = 0; i < halfCount; ++i )
{
widths.push_back( halfWidths[i] );
}
// If odd number of cells, add center cell with smallest width
if ( totalCells % 2 == 1 )
{
widths.push_back( 1.0 );
}
// Second half: center to edge (mirror)
for ( size_t i = halfCount; i > 0; --i )
{
widths.push_back( halfWidths[i - 1] );
}
return widths;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -214,14 +283,7 @@ RigNonUniformRefinement RigNonUniformRefinement::fromUniform( const cvf::Vec3st&
{
if ( refCount[dim] <= 1 ) continue;
// Create uniform cumulative fractions
std::vector<double> uniformFractions;
uniformFractions.reserve( refCount[dim] );
for ( size_t i = 1; i <= refCount[dim]; ++i )
{
uniformFractions.push_back( static_cast<double>( i ) / static_cast<double>( refCount[dim] ) );
}
uniformFractions.back() = 1.0;
auto uniformFractions = generateEqualFractions( refCount[dim] );
for ( size_t idx = 0; idx < result.m_sectorSize[dim]; ++idx )
{