Skip to content

Commit e1baaca

Browse files
committed
ShaderNetworkAlgo : Support endpoint duplication for "constant" splines
1 parent 5d59dc1 commit e1baaca

File tree

2 files changed

+49
-12
lines changed

2 files changed

+49
-12
lines changed

src/IECoreScene/ShaderNetworkAlgo.cpp

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,8 @@ template<typename Spline>
564564
void expandSpline( const InternedString &name, const Spline &spline, CompoundDataMap &newParameters )
565565
{
566566
const char *basis = "catmull-rom";
567-
bool duplicateEndPoints = false;
567+
size_t duplicateStartPoints = 0;
568+
size_t duplicateEndPoints = 0;
568569
if( spline.basis == Spline::Basis::bezier() )
569570
{
570571
basis = "bezier";
@@ -578,9 +579,18 @@ void expandSpline( const InternedString &name, const Spline &spline, CompoundDat
578579
// OSL discards the first and last segment of linear curves
579580
// "To maintain consistency with the other spline types"
580581
// so we need to duplicate the end points to preserve all provided segments
581-
duplicateEndPoints = true;
582+
duplicateStartPoints = 1;
583+
duplicateEndPoints = 1;
582584
basis = "linear";
583585
}
586+
else if( spline.basis == Spline::Basis::constant() )
587+
{
588+
// Also, "To maintain consistency", "constant splines ignore the first and the two last
589+
// data values."
590+
duplicateStartPoints = 1;
591+
duplicateEndPoints = 2;
592+
basis = "constant";
593+
}
584594

585595
typedef TypedData< vector<typename Spline::XType> > XTypedVectorData;
586596
typename XTypedVectorData::Ptr positionsData = new XTypedVectorData();
@@ -589,22 +599,28 @@ void expandSpline( const InternedString &name, const Spline &spline, CompoundDat
589599
typedef TypedData< vector<typename Spline::YType> > YTypedVectorData;
590600
typename YTypedVectorData::Ptr valuesData = new YTypedVectorData();
591601
auto &values = valuesData->writable();
592-
values.reserve( spline.points.size() + 2 * duplicateEndPoints );
602+
values.reserve( spline.points.size() + duplicateStartPoints + duplicateEndPoints );
593603

594-
if( duplicateEndPoints && spline.points.size() )
604+
if( spline.points.size() )
595605
{
596-
positions.push_back( spline.points.begin()->first );
597-
values.push_back( spline.points.begin()->second );
606+
for( size_t i = 0; i < duplicateStartPoints; i++ )
607+
{
608+
positions.push_back( spline.points.begin()->first );
609+
values.push_back( spline.points.begin()->second );
610+
}
598611
}
599612
for( typename Spline::PointContainer::const_iterator it = spline.points.begin(), eIt = spline.points.end(); it != eIt; ++it )
600613
{
601614
positions.push_back( it->first );
602615
values.push_back( it->second );
603616
}
604-
if( duplicateEndPoints && spline.points.size() )
617+
if( spline.points.size() )
605618
{
606-
positions.push_back( spline.points.rbegin()->first );
607-
values.push_back( spline.points.rbegin()->second );
619+
for( size_t i = 0; i < duplicateEndPoints; i++ )
620+
{
621+
positions.push_back( spline.points.rbegin()->first );
622+
values.push_back( spline.points.rbegin()->second );
623+
}
608624
}
609625

610626
newParameters[ name.string() + "Positions" ] = positionsData;
@@ -622,7 +638,8 @@ IECore::DataPtr loadSpline(
622638
typename SplineData::Ptr resultData = new SplineData();
623639
auto &result = resultData->writable();
624640

625-
bool unduplicateEndPoints = false;
641+
size_t unduplicateStartPoints = 0;
642+
size_t unduplicateEndPoints = 0;
626643

627644
const std::string &basis = basisData->readable();
628645
if( basis == "bezier" )
@@ -636,9 +653,17 @@ IECore::DataPtr loadSpline(
636653
else if( basis == "linear" )
637654
{
638655
// Reverse the duplication we do when expanding splines
639-
unduplicateEndPoints = true;
656+
unduplicateStartPoints = 1;
657+
unduplicateEndPoints = 1;
640658
result.basis = SplineData::ValueType::Basis::linear();
641659
}
660+
else if( basis == "constant" )
661+
{
662+
// Reverse the duplication we do when expanding splines
663+
unduplicateStartPoints = 1;
664+
unduplicateEndPoints = 2;
665+
result.basis = SplineData::ValueType::Basis::constant();
666+
}
642667
else
643668
{
644669
result.basis = SplineData::ValueType::Basis::catmullRom();
@@ -650,7 +675,7 @@ IECore::DataPtr loadSpline(
650675
size_t n = std::min( positions.size(), values.size() );
651676
for( size_t i = 0; i < n; ++i )
652677
{
653-
if( unduplicateEndPoints && ( i == 0 || i == n - 1 ) )
678+
if( i < unduplicateStartPoints || i >= n - unduplicateEndPoints )
654679
{
655680
continue;
656681
}

test/IECoreScene/ShaderNetworkAlgoTest.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,8 @@ def testSplineConversion( self ):
397397
( ( 0, imath.Color3f(1) ), ( 10, imath.Color3f(2) ), ( 20, imath.Color3f(0) ), ( 30, imath.Color3f(5) ), ( 40, imath.Color3f(2) ), ( 50, imath.Color3f(6) ) ) ) )
398398
parms["testfColor3flinear"] = IECore.SplinefColor3fData( IECore.SplinefColor3f( IECore.CubicBasisf.linear(),
399399
( ( 0, imath.Color3f(1) ), ( 10, imath.Color3f(2) ), ( 20, imath.Color3f(0) ) ) ) )
400+
parms["testffconstant"] = IECore.SplineffData( IECore.Splineff( IECore.CubicBasisf.constant(),
401+
( ( 0, 1 ), ( 0.2, 6 ), ( 0.3, 7 ) ) ) )
400402

401403
parmsExpanded = IECoreScene.ShaderNetworkAlgo.expandSplineParameters( parms )
402404

@@ -406,6 +408,15 @@ def testSplineConversion( self ):
406408
self.assertEqual( type( parmsExpanded["testffbSplineValues"] ), IECore.FloatVectorData )
407409
self.assertEqual( type( parmsExpanded["testfColor3fcatmullRomValues"] ), IECore.Color3fVectorData )
408410

411+
for name, extra in [
412+
( "testffbSpline", 0 ),
413+
( "testffbezier", 0 ),
414+
( "testfColor3fcatmullRom", 0 ),
415+
( "testfColor3flinear", 2 ),
416+
( "testffconstant", 3 )
417+
]:
418+
self.assertEqual( len( parms[name].value.keys() ) + extra, len( parmsExpanded[name + "Positions"] ) )
419+
409420
parmsCollapsed = IECoreScene.ShaderNetworkAlgo.collapseSplineParameters( parmsExpanded )
410421

411422
self.assertEqual( parmsCollapsed, parms )
@@ -414,6 +425,7 @@ def testSplineConversion( self ):
414425
del parmsExpanded["testffbezierValues"]
415426
del parmsExpanded["testfColor3fcatmullRomPositions"]
416427
del parmsExpanded["testfColor3flinearBasis"]
428+
del parmsExpanded["testffconstantPositions"]
417429

418430
parmsCollapsed = IECoreScene.ShaderNetworkAlgo.collapseSplineParameters( parmsExpanded )
419431

0 commit comments

Comments
 (0)