Skip to content

Commit 0ff77bb

Browse files
Merge pull request #1499 from danieldresser-ie/splinesRound2
Replace Spline With Ramp For Shader Parameters
2 parents 2ae560c + 2330dbb commit 0ff77bb

File tree

30 files changed

+2036
-562
lines changed

30 files changed

+2036
-562
lines changed

Changes

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
10.x.x.x (relative to 10.6.x.x)
22
========
33

4+
Features
5+
--------
6+
7+
- IECore : Added Rampff, RampfColor3f, RampfColor4f and corresponding Ramp*Data classes, for representing user facing shader ramp parameters.
8+
9+
Breaking Changes
10+
----------------
411

12+
- IECoreScene::ShaderNetworkAlgo :
13+
- Removed deprecated functions componentConnectionAdapterLabel, convertOSLComponentConnections, collapseSplineParameters, expandSplineParameters.
14+
- Switch support for Spline parameters to support for Ramp parameters.
515

616
10.6.x.x (relative to 10.6.1.0)
717
========

contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,12 @@ namespace
6565
{
6666

6767
const pxr::TfToken g_blindDataToken( "cortex:blindData" );
68-
pxr::TfToken g_legacyAdapterLabelToken( IECoreScene::ShaderNetworkAlgo::componentConnectionAdapterLabel().string() );
68+
69+
// Hardcoded to match an old name used by Cortex when writing USD with OSL version earlier than 1.10 (
70+
// ie. a pre-2021 version of gafferDependencies ). We no longer expose this in the API, but I'm not sure
71+
// if we're ready to drop support for loading these old files.
72+
IECore::InternedString g_legacyAdapterLabelString( "cortex_autoAdapter" );
73+
pxr::TfToken g_legacyAdapterLabelToken( g_legacyAdapterLabelString.string() );
6974

7075
std::pair<pxr::TfToken, std::string> shaderIdAndType( const pxr::UsdShadeConnectableAPI &connectable )
7176
{
@@ -267,7 +272,7 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co
267272
pxr::VtValue metadataValue;
268273
if( usdShader.GetPrim().GetMetadata( g_legacyAdapterLabelToken, &metadataValue ) && metadataValue.Get<bool>() )
269274
{
270-
newShader->blindData()->writable()[ IECoreScene::ShaderNetworkAlgo::componentConnectionAdapterLabel() ] = new IECore::BoolData( true );
275+
newShader->blindData()->writable()[ g_legacyAdapterLabelString ] = new IECore::BoolData( true );
271276
}
272277

273278
shaderNetwork.addShader( handle, std::move( newShader ) );
@@ -297,7 +302,7 @@ IECoreScene::ShaderNetwork::Parameter readShaderNetworkWalk( const pxr::SdfPath
297302
IECoreScene::ConstShaderNetworkPtr adaptShaderNetworkForWriting( const IECoreScene::ShaderNetwork *shaderNetwork )
298303
{
299304
IECoreScene::ShaderNetworkPtr result = shaderNetwork->copy();
300-
IECoreScene::ShaderNetworkAlgo::expandSplines( result.get() );
305+
IECoreScene::ShaderNetworkAlgo::expandRamps( result.get() );
301306
IECoreScene::ShaderNetworkAlgo::addComponentConnectionAdapters( result.get() );
302307
return result;
303308
}
@@ -524,7 +529,7 @@ IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork( const px
524529
result->setOutput( outputHandle );
525530

526531
IECoreScene::ShaderNetworkAlgo::removeComponentConnectionAdapters( result.get() );
527-
IECoreScene::ShaderNetworkAlgo::collapseSplines( result.get() );
532+
IECoreScene::ShaderNetworkAlgo::collapseRamps( result.get() );
528533

529534
return result;
530535
}

contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2917,12 +2917,13 @@ def testShaders( self ) :
29172917
surface.parameters["c"] = IECore.StringData( "42" )
29182918
surface.parameters["d"] = IECore.Color3fData( imath.Color3f( 3 ) )
29192919
surface.parameters["e"] = IECore.V3fVectorData( [ imath.V3f( 7 ) ] )
2920-
surface.parameters["f"] = IECore.SplineffData( IECore.Splineff( IECore.CubicBasisf.bSpline(),
2921-
( ( 0, 1 ), ( 10, 2 ), ( 20, 0 ), ( 21, 2 ) ) )
2922-
)
2923-
surface.parameters["g"] = IECore.SplinefColor3fData( IECore.SplinefColor3f( IECore.CubicBasisf.linear(),
2924-
( ( 0, imath.Color3f(1) ), ( 10, imath.Color3f(2) ), ( 20, imath.Color3f(0) ) ) )
2925-
)
2920+
surface.parameters["f"] = IECore.RampffData( IECore.Rampff(
2921+
( ( 0, 1 ), ( 10, 2 ), ( 20, 0 ), ( 21, 2 ) ), IECore.RampInterpolation.BSpline
2922+
) )
2923+
surface.parameters["g"] = IECore.RampfColor3fData( IECore.RampfColor3f(
2924+
( ( 0, imath.Color3f(1) ), ( 10, imath.Color3f(2) ), ( 20, imath.Color3f(0) ) ),
2925+
IECore.RampInterpolation.Linear
2926+
) )
29262927

29272928
add1 = IECoreScene.Shader( "add", "ai:shader" )
29282929
add1.parameters["b"] = IECore.FloatData( 3.0 )
@@ -2978,11 +2979,13 @@ def testShaders( self ) :
29782979
dest.parameters["a"] = IECore.Color3fData( imath.Color3f( 0.0 ) )
29792980
dest.parameters["b"] = IECore.Color3fData( imath.Color3f( 0.0 ) )
29802981
dest.parameters["c"] = IECore.FloatData( 0.0 )
2981-
dest.parameters["sf"] = IECore.SplineffData( IECore.Splineff( IECore.CubicBasisf.catmullRom(),
2982-
( ( 0, 1 ), ( 10, 2 ), ( 20, 0 ), ( 30, 1 ) )
2982+
dest.parameters["sf"] = IECore.RampffData( IECore.Rampff(
2983+
( ( 0, 1 ), ( 10, 2 ), ( 20, 0 ), ( 30, 1 ) ),
2984+
IECore.RampInterpolation.CatmullRom
29832985
) )
2984-
dest.parameters["sc"] = IECore.SplinefColor3fData( IECore.SplinefColor3f( IECore.CubicBasisf.linear(),
2985-
( ( 0, imath.Color3f(1) ), ( 10, imath.Color3f(2) ), ( 20, imath.Color3f(0) ) )
2986+
dest.parameters["sc"] = IECore.RampfColor3fData( IECore.RampfColor3f(
2987+
( ( 0, imath.Color3f(1) ), ( 10, imath.Color3f(2) ), ( 20, imath.Color3f(0) ) ),
2988+
IECore.RampInterpolation.Linear
29862989
) )
29872990

29882991
componentConnectionNetwork = IECoreScene.ShaderNetwork()
@@ -3016,19 +3019,19 @@ def testShaders( self ) :
30163019
) )
30173020
componentConnectionNetwork.setOutput( IECoreScene.ShaderNetwork.Parameter( "dest", "" ) )
30183021

3019-
# Float to spline element connection
3022+
# Float to ramp element connection
30203023
componentConnectionNetwork.addConnection( IECoreScene.ShaderNetwork.Connection(
30213024
IECoreScene.ShaderNetwork.Parameter( "source1", "out" ),
30223025
IECoreScene.ShaderNetwork.Parameter( "dest", "sf[3].y" )
30233026
) )
30243027

3025-
# Color to spline element connection
3028+
# Color to ramp element connection
30263029
componentConnectionNetwork.addConnection( IECoreScene.ShaderNetwork.Connection(
30273030
IECoreScene.ShaderNetwork.Parameter( "source3", "out" ),
30283031
IECoreScene.ShaderNetwork.Parameter( "dest", "sc[2].y" )
30293032
) )
30303033

3031-
# Float to spline element component connection
3034+
# Float to ramp element component connection
30323035
componentConnectionNetwork.addConnection( IECoreScene.ShaderNetwork.Connection(
30333036
IECoreScene.ShaderNetwork.Parameter( "source1", "out" ),
30343037
IECoreScene.ShaderNetwork.Parameter( "dest", "sc[0].y.g" )

include/IECore/DataAlgo.inl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "IECore/PathMatcherData.h"
4040
#include "IECore/SimpleTypedData.h"
4141
#include "IECore/SplineData.h"
42+
#include "IECore/RampData.h"
4243
#include "IECore/TransformationMatrixData.h"
4344
#include "IECore/VectorTypedData.h"
4445

@@ -132,6 +133,12 @@ typename std::invoke_result_t<F, Data *, Args&&...> dispatch( Data *data, F &&fu
132133
return functor( static_cast<SplinefColor3fData *>( data ), std::forward<Args>( args )... );
133134
case SplinefColor4fDataTypeId :
134135
return functor( static_cast<SplinefColor4fData *>( data ), std::forward<Args>( args )... );
136+
case RampffDataTypeId :
137+
return functor( static_cast<RampffData *>( data ), std::forward<Args>( args )... );
138+
case RampfColor3fDataTypeId :
139+
return functor( static_cast<RampfColor3fData *>( data ), std::forward<Args>( args )... );
140+
case RampfColor4fDataTypeId :
141+
return functor( static_cast<RampfColor4fData *>( data ), std::forward<Args>( args )... );
135142
case DateTimeDataTypeId :
136143
return functor( static_cast<DateTimeData *>( data ), std::forward<Args>( args )... );
137144
case BoolVectorDataTypeId :
@@ -286,6 +293,12 @@ typename std::invoke_result_t<F, const Data *, Args&&...> dispatch( const Data *
286293
return functor( static_cast<const SplinefColor3fData *>( data ), std::forward<Args>( args )... );
287294
case SplinefColor4fDataTypeId :
288295
return functor( static_cast<const SplinefColor4fData *>( data ), std::forward<Args>( args )... );
296+
case RampffDataTypeId :
297+
return functor( static_cast<const RampffData *>( data ), std::forward<Args>( args )... );
298+
case RampfColor3fDataTypeId :
299+
return functor( static_cast<const RampfColor3fData *>( data ), std::forward<Args>( args )... );
300+
case RampfColor4fDataTypeId :
301+
return functor( static_cast<const RampfColor4fData *>( data ), std::forward<Args>( args )... );
289302
case DateTimeDataTypeId :
290303
return functor( static_cast<const DateTimeData *>( data ), std::forward<Args>( args )... );
291304
case BoolVectorDataTypeId :

include/IECore/Ramp.h

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
//////////////////////////////////////////////////////////////////////////
2+
//
3+
// Copyright (c) 2025, Image Engine Design Inc. All rights reserved.
4+
//
5+
// Redistribution and use in source and binary forms, with or without
6+
// modification, are permitted provided that the following conditions are
7+
// met:
8+
//
9+
// * Redistributions of source code must retain the above copyright
10+
// notice, this list of conditions and the following disclaimer.
11+
//
12+
// * Redistributions in binary form must reproduce the above copyright
13+
// notice, this list of conditions and the following disclaimer in the
14+
// documentation and/or other materials provided with the distribution.
15+
//
16+
// * Neither the name of Image Engine Design nor the names of any
17+
// other contributors to this software may be used to endorse or
18+
// promote products derived from this software without specific prior
19+
// written permission.
20+
//
21+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22+
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23+
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24+
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25+
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26+
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27+
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28+
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29+
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30+
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31+
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32+
//
33+
//////////////////////////////////////////////////////////////////////////
34+
35+
#ifndef IECORE_RAMP_H
36+
#define IECORE_RAMP_H
37+
38+
#include "IECore/Export.h"
39+
#include "IECore/Spline.h"
40+
#include "IECore/MessageHandler.h"
41+
42+
IECORE_PUSH_DEFAULT_VISIBILITY
43+
#include "Imath/ImathColor.h"
44+
IECORE_POP_DEFAULT_VISIBILITY
45+
46+
#include <map>
47+
48+
namespace IECore
49+
{
50+
51+
// This lives outside the class because we don't want multiple incompatible templated versions of
52+
// the same enum floating around
53+
enum class RampInterpolation
54+
{
55+
Linear = 0,
56+
CatmullRom = 1,
57+
BSpline = 2,
58+
MonotoneCubic = 3,
59+
Constant = 4,
60+
};
61+
62+
/// A Ramp represents a spline-like curve as it is represented in a simple UI: with a set of independent
63+
/// control points, and an interpolation type selected from RampInterpolation.
64+
///
65+
/// Rather than storing the lower level IECore::Spline*, we now store this Ramp type in shader networks,
66+
/// and only convert to the lower level class with the evaluator() function when evaluation is needed.
67+
///
68+
/// This was chosen as superior to IECore::Spline* because IECoreS::spline* requires duplicating the
69+
/// end points in order to make the curve reach the first and last control point.
70+
template<typename X, typename Y>
71+
class IECORE_EXPORT Ramp
72+
{
73+
74+
public :
75+
76+
using XType = X;
77+
using YType = Y;
78+
79+
using PointContainer = std::multimap<X, Y>;
80+
using Point = typename PointContainer::value_type;
81+
82+
Ramp() : interpolation( RampInterpolation::CatmullRom )
83+
{
84+
}
85+
86+
Ramp( const PointContainer &p, RampInterpolation i )
87+
: points( p ), interpolation( i )
88+
{
89+
}
90+
91+
PointContainer points;
92+
RampInterpolation interpolation;
93+
94+
95+
// Convert to Cortex Spline
96+
// In the future, IECore::Spline may be replaced with IECore::SplineEvaluator, and this
97+
// function would be the only way to setup one.
98+
IECore::Spline<X, Y> evaluator() const;
99+
100+
// Convert to and from a set of arguments that could be passed to a pair of spline() and
101+
// splineinverse() functions in OSL. This can be useful in converting ramps to parameters
102+
// for OSL shaders.
103+
//
104+
// Some shader libraries use these arguments directly as shader parameters ( i.e. Gaffer ).
105+
// Some shader libraries preprocess shader parameters before passing them to spline(),
106+
// so they don't need some aspects of this conversion ( like endpoint duplication ), but
107+
// the extra endpoint duplication doesn't cause problems ( i.e. PRMan ).
108+
// Some shader libraries are doing their own thing, implementing their own custom math,
109+
// but convention is still similar enough that these function can be a useful building
110+
// block in converting to something that mostly works ( i.e. 3delight ).
111+
void fromOSL( const std::string &basis, const std::vector<X> &positions, const std::vector<Y> &values, const std::string &identifier );
112+
void toOSL( std::string &basis, std::vector<X> &positions, std::vector<Y> &values ) const;
113+
114+
/// The number of times `toOSL()` repeats the initial point.
115+
int oslStartPointMultiplicity() const;
116+
117+
// In Cortex 10.6 and earlier, shader parameters were represented uing IECore::Spline*Data instead of
118+
// IECore::Ramp*Data. This is used in converting SCC files to the new standard.
119+
// \todo : This can probably be removed in the next major version - we're not actually aware of any
120+
// significant users of Cortex who both use SCC files, and cache shaders, so this compatibility shim
121+
// is only needed theoretically.
122+
void fromDeprecatedSpline( const IECore::Spline<X, Y> &deprecated );
123+
124+
bool operator==( const Ramp<X,Y> &rhs ) const;
125+
bool operator!=( const Ramp<X,Y> &rhs ) const;
126+
127+
};
128+
129+
using Rampff = Ramp<float, float>;
130+
using RampfColor3f = Ramp<float, Imath::Color3f>;
131+
using RampfColor4f = Ramp<float, Imath::Color4f>;
132+
133+
template<typename X, typename Y>
134+
inline void murmurHashAppend( IECore::MurmurHash &h, const Ramp<X,Y> &data )
135+
{
136+
h.append( data.interpolation );
137+
for ( auto &p : data.points )
138+
{
139+
h.append( p.first );
140+
h.append( p.second );
141+
}
142+
}
143+
144+
} // namespace IECore
145+
146+
#endif // IECORE_RAMP_H

include/IECore/RampData.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//////////////////////////////////////////////////////////////////////////
2+
//
3+
// Copyright (c) 2025, Image Engine Design Inc. All rights reserved.
4+
//
5+
// Redistribution and use in source and binary forms, with or without
6+
// modification, are permitted provided that the following conditions are
7+
// met:
8+
//
9+
// * Redistributions of source code must retain the above copyright
10+
// notice, this list of conditions and the following disclaimer.
11+
//
12+
// * Redistributions in binary form must reproduce the above copyright
13+
// notice, this list of conditions and the following disclaimer in the
14+
// documentation and/or other materials provided with the distribution.
15+
//
16+
// * Neither the name of Image Engine Design nor the names of any
17+
// other contributors to this software may be used to endorse or
18+
// promote products derived from this software without specific prior
19+
// written permission.
20+
//
21+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22+
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23+
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24+
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25+
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26+
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27+
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28+
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29+
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30+
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31+
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32+
//
33+
//////////////////////////////////////////////////////////////////////////
34+
35+
#ifndef IECORE_RAMPDATA_H
36+
#define IECORE_RAMPDATA_H
37+
38+
#include "IECore/Ramp.h"
39+
#include "IECore/TypedData.h"
40+
41+
namespace IECore
42+
{
43+
44+
// Ramp data types.
45+
46+
IECORE_DECLARE_TYPEDDATA( RampffData, Rampff, void, SharedDataHolder )
47+
IECORE_DECLARE_TYPEDDATA( RampfColor3fData, RampfColor3f, void, SharedDataHolder )
48+
IECORE_DECLARE_TYPEDDATA( RampfColor4fData, RampfColor4f, void, SharedDataHolder )
49+
50+
}
51+
52+
#endif // IECORE_RAMPDATA_H

include/IECore/SplineParameter.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@
4141
namespace IECore
4242
{
4343

44+
// NOTE : Using Spline*Data has basically been deprecated in favour of Ramp*Data.
45+
// Setting up shader data this way will no longer work with renderer backends.
46+
//
47+
// We do not plan to update this because Parameter itself is on the way to
48+
// deprecation ( in favour of using Gaffer to build UIs ).
49+
4450
typedef TypedParameter<Splineff> SplineffParameter;
4551
typedef TypedParameter<Splinedd> SplineddParameter;
4652
typedef TypedParameter<SplinefColor3f> SplinefColor3fParameter;

include/IECore/TypeIds.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,9 @@ enum TypeId
203203
YUVImageWriterTypeId = 265,
204204
DateTimeDataTypeId = 269,
205205
DateTimeParameterTypeId = 270,
206-
TimeDurationDataTypeId = 272, // Obsolete
207-
TimeDurationParameterTypeId = 273, // Obsolete
208-
TimePeriodDataTypeId = 274, // Obsolete
206+
RampffDataTypeId = 272,
207+
RampfColor3fDataTypeId = 273,
208+
RampfColor4fDataTypeId = 274,
209209
TimePeriodParameterTypeId = 275, // Obsolete
210210
FrameListTypeId = 279,
211211
EmptyFrameListTypeId = 280,

0 commit comments

Comments
 (0)