@@ -564,7 +564,8 @@ template<typename Spline>
564564void 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 }
0 commit comments