@@ -564,7 +564,8 @@ template<typename Spline>
564
564
void expandSpline ( const InternedString &name, const Spline &spline, CompoundDataMap &newParameters )
565
565
{
566
566
const char *basis = " catmull-rom" ;
567
- bool duplicateEndPoints = false ;
567
+ size_t duplicateStartPoints = 0 ;
568
+ size_t duplicateEndPoints = 0 ;
568
569
if ( spline.basis == Spline::Basis::bezier () )
569
570
{
570
571
basis = " bezier" ;
@@ -578,9 +579,18 @@ void expandSpline( const InternedString &name, const Spline &spline, CompoundDat
578
579
// OSL discards the first and last segment of linear curves
579
580
// "To maintain consistency with the other spline types"
580
581
// so we need to duplicate the end points to preserve all provided segments
581
- duplicateEndPoints = true ;
582
+ duplicateStartPoints = 1 ;
583
+ duplicateEndPoints = 1 ;
582
584
basis = " linear" ;
583
585
}
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
+ }
584
594
585
595
typedef TypedData< vector<typename Spline::XType> > XTypedVectorData;
586
596
typename XTypedVectorData::Ptr positionsData = new XTypedVectorData ();
@@ -589,22 +599,28 @@ void expandSpline( const InternedString &name, const Spline &spline, CompoundDat
589
599
typedef TypedData< vector<typename Spline::YType> > YTypedVectorData;
590
600
typename YTypedVectorData::Ptr valuesData = new YTypedVectorData ();
591
601
auto &values = valuesData->writable ();
592
- values.reserve ( spline.points .size () + 2 * duplicateEndPoints );
602
+ values.reserve ( spline.points .size () + duplicateStartPoints + duplicateEndPoints );
593
603
594
- if ( duplicateEndPoints && spline.points .size () )
604
+ if ( spline.points .size () )
595
605
{
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
+ }
598
611
}
599
612
for ( typename Spline::PointContainer::const_iterator it = spline.points .begin (), eIt = spline.points .end (); it != eIt; ++it )
600
613
{
601
614
positions.push_back ( it->first );
602
615
values.push_back ( it->second );
603
616
}
604
- if ( duplicateEndPoints && spline.points .size () )
617
+ if ( spline.points .size () )
605
618
{
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
+ }
608
624
}
609
625
610
626
newParameters[ name.string () + " Positions" ] = positionsData;
@@ -622,7 +638,8 @@ IECore::DataPtr loadSpline(
622
638
typename SplineData::Ptr resultData = new SplineData ();
623
639
auto &result = resultData->writable ();
624
640
625
- bool unduplicateEndPoints = false ;
641
+ size_t unduplicateStartPoints = 0 ;
642
+ size_t unduplicateEndPoints = 0 ;
626
643
627
644
const std::string &basis = basisData->readable ();
628
645
if ( basis == " bezier" )
@@ -636,9 +653,17 @@ IECore::DataPtr loadSpline(
636
653
else if ( basis == " linear" )
637
654
{
638
655
// Reverse the duplication we do when expanding splines
639
- unduplicateEndPoints = true ;
656
+ unduplicateStartPoints = 1 ;
657
+ unduplicateEndPoints = 1 ;
640
658
result.basis = SplineData::ValueType::Basis::linear ();
641
659
}
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
+ }
642
667
else
643
668
{
644
669
result.basis = SplineData::ValueType::Basis::catmullRom ();
@@ -650,7 +675,7 @@ IECore::DataPtr loadSpline(
650
675
size_t n = std::min ( positions.size (), values.size () );
651
676
for ( size_t i = 0 ; i < n; ++i )
652
677
{
653
- if ( unduplicateEndPoints && ( i == 0 || i == n - 1 ) )
678
+ if ( i < unduplicateStartPoints || i >= n - unduplicateEndPoints )
654
679
{
655
680
continue ;
656
681
}
0 commit comments