Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
ddad201
IE Config : Add solidangle_LICENSE to ENV_VARS_TO_IMPORT
danieldresser Sep 14, 2017
ba7a2f9
SConstruct : Arnold tests depend on Arnold lib
danieldresser Sep 21, 2017
6e51598
IECoreArnold::PointsTest and RenderTest : This test could never have …
danieldresser Sep 14, 2017
1d3e5df
IECoreArnold::ProceduralTest : Need a tiny tolerance when checking va…
danieldresser Sep 14, 2017
574ec8a
IECoreArnold::RendererTest : With extreme motion blur, we need more s…
danieldresser Sep 18, 2017
cacc56c
IECoreArnold tests : Don't dump render output during tests
danieldresser Sep 22, 2017
5320eae
IECoreArnold tests : When testing example parameters, use ones that …
danieldresser Sep 15, 2017
86fcb48
IECoreArnold tests : Signature of AiNodeGetMatrix changed in Arnold 5
danieldresser Sep 15, 2017
efa1b5d
IECoreArnold::UniverseBlockTest : Accessing Metadata from Python now …
danieldresser Sep 18, 2017
4130ffa
IECoreArnold::RendererTest : Use correct types so we don't get warnings
danieldresser Sep 22, 2017
73f9798
IECoreArnold : Arnold 5 removes point types, and just uses vectors
danieldresser Sep 14, 2017
f8d2571
IECoreArnold : Arnold 5 replaces AtByte with uint8_t
danieldresser Sep 14, 2017
c146478
IECoreArnold : Arnold 5 replaces AtColor with AtRGB
danieldresser Sep 15, 2017
2f06053
IECoreArnold : In Arnold 5, member variables of AtArray are not decla…
danieldresser Sep 14, 2017
e1cdb1e
IECoreArnold::OutputDriver : Many API changes in Arnold 5
danieldresser Sep 15, 2017
5765d45
IECoreAnold::Parameter Algo : Use AtString
danieldresser Sep 15, 2017
3ab0ea5
IECoreArnold : Update M44f to AtMatrix casts for Arnold 5
danieldresser Sep 15, 2017
4acc625
IECoreArnold::RendererImplementation : Updated visibility attributes …
danieldresser Sep 15, 2017
45a5156
IECoreArnold : Arnold 5 doesn't support non-uniform sample times
danieldresser Sep 15, 2017
dde6223
IECoreArnold : Arnold 5 renamed aspect_ratio to pixel_aspect_ratio
danieldresser Sep 15, 2017
a78e362
IECoreArnold::RenderImplemenation : Update for Arnold 5 procedural in…
danieldresser Sep 18, 2017
c3771b6
IECoreArnold::Procedural : Update for Arnold 5, remove obselete test
danieldresser Sep 18, 2017
7ad6595
IECoreArnold::RendererImplemention : Remove duplicate AiEnd - the des…
danieldresser Sep 19, 2017
eeb3f92
IECoreArnold::ParameterAlgo : Support V3i and V2i parameters by casti…
danieldresser Sep 20, 2017
5ad3e9e
ICoreArnold : Without any options for setting log verbosity, default …
danieldresser Sep 22, 2017
96b708e
IECoreArnold::AutomaticInstancingTest : Force on console output so we…
danieldresser Sep 22, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -3101,7 +3101,7 @@ if doConfigure :
arnoldTestEnv["ENV"]["ARNOLD_PLUGIN_PATH"] = "contrib/IECoreArnold/test/IECoreArnold/plugins"
arnoldTest = arnoldTestEnv.Command( "contrib/IECoreArnold/test/IECoreArnold/results.txt", arnoldPythonModule, pythonExecutable + " $TEST_ARNOLD_SCRIPT" )
NoCache( arnoldTest )
arnoldTestEnv.Depends( arnoldTest, [ arnoldPythonModule + arnoldProceduralForTest + arnoldDriverForTest ] )
arnoldTestEnv.Depends( arnoldTest, [ arnoldPythonModule + arnoldProceduralForTest + arnoldDriverForTest + arnoldLibrary ] )

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised this is necessary, since arnoldPythonModule already depends on arnoldLibrary.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue is the cache. If you make a change to arnoldLibrary that does not produce any changes in the python/IECoreArnold/_IECoreArnold.so binary, then the cache considers the test to have already been run with this exact set of inputs.

arnoldTestEnv.Depends( arnoldTest, glob.glob( "contrib/IECoreArnold/test/IECoreArnold/*.py" ) )
arnoldTestEnv.Alias( "testArnold", arnoldTest )

Expand Down
2 changes: 1 addition & 1 deletion config/ie/options
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ HDF5_LIB_PATH = os.path.join( "/software/apps/hdf5", hdf5Version, platform, comp
DOXYGEN = os.path.join( "/software/apps/doxygen", os.environ["DOXYGEN_VERSION"], platform, "bin", "doxygen" )

# import vars we need to get our doxygen and python wrappers working
ENV_VARS_TO_IMPORT="PATH COMPILER COMPILER_VERSION PYTHONPATH IEENV_ROOT IEENV_WORKING_PATH IEENV_LIBRARY_PREFIX_PATH DOXYGEN_VERSION IEENV_DEBUG IEENV_DEBUG_PYTHON IEENV_DEBUGGER IEENV_DEBUGGER_ARGS DELIGHT_CONF SCONS_VERSION DL_VERSION DL_SHADERS_PATH DL_DISPLAYS_PATH"
ENV_VARS_TO_IMPORT="PATH COMPILER COMPILER_VERSION PYTHONPATH IEENV_ROOT IEENV_WORKING_PATH IEENV_LIBRARY_PREFIX_PATH DOXYGEN_VERSION IEENV_DEBUG IEENV_DEBUG_PYTHON IEENV_DEBUGGER IEENV_DEBUGGER_ARGS DELIGHT_CONF SCONS_VERSION DL_VERSION DL_SHADERS_PATH DL_DISPLAYS_PATH solidangle_LICENSE"

# make sure the tests can run
testLibs = [ pythonReg["location"] + "/" + compiler + "/" + compilerVersion + "/lib", compilerReg["location"] + "/lib" ]
Expand Down
2 changes: 1 addition & 1 deletion contrib/IECoreArnold/include/IECoreArnold/CurvesAlgo.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace CurvesAlgo
{

AtNode *convert( const IECore::CurvesPrimitive *curves );
AtNode *convert( const std::vector<const IECore::CurvesPrimitive *> &samples, const std::vector<float> &sampleTimes );
AtNode *convert( const std::vector<const IECore::CurvesPrimitive *> &samples, float motionStart, float motionEnd );

} // namespace CurvesAlgo

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ class IECOREARNOLD_API InstancingConverter : public IECore::RefCounted
AtNode *convert( const IECore::Primitive *primitive, const IECore::MurmurHash &additionalHash );

/// Motion blurred versions of the above conversion functions.
AtNode *convert( const std::vector<const IECore::Primitive *> &samples, const std::vector<float> &sampleTimes );
AtNode *convert( const std::vector<const IECore::Primitive *> &samples, const std::vector<float> &sampleTimes, const IECore::MurmurHash &additionalHash );
AtNode *convert( const std::vector<const IECore::Primitive *> &samples, float motionStart, float motionEnd );
AtNode *convert( const std::vector<const IECore::Primitive *> &samples, float motionStart, float motionEnd, const IECore::MurmurHash &additionalHash );

private :

Expand Down
2 changes: 1 addition & 1 deletion contrib/IECoreArnold/include/IECoreArnold/MeshAlgo.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace MeshAlgo
{

AtNode *convert( const IECore::MeshPrimitive *mesh );
AtNode *convert( const std::vector<const IECore::MeshPrimitive *> &samples, const std::vector<float> &sampleTimes );
AtNode *convert( const std::vector<const IECore::MeshPrimitive *> &samples, float motionStart, float motionEnd );

} // namespace MeshAlgo

Expand Down
11 changes: 8 additions & 3 deletions contrib/IECoreArnold/include/IECoreArnold/NodeAlgo.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ AtNode *convert( const IECore::Object *object );
/// equivalent moving Arnold object. If no motion converter
/// is available, then returns a standard conversion of the
/// first sample.
AtNode *convert( const std::vector<const IECore::Object *> &samples, const std::vector<float> &sampleTimes );
AtNode *convert( const std::vector<const IECore::Object *> &samples, float motionStart, float motionEnd );

/// Signature of a function which can convert an IECore::Object
/// into an Arnold object.
typedef AtNode * (*Converter)( const IECore::Object * );
/// Signature of a function which can convert a series of IECore::Object
/// samples into a moving Arnold object.
typedef AtNode * (*MotionConverter)( const std::vector<const IECore::Object *> &samples, const std::vector<float> &sampleTimes );
typedef AtNode * (*MotionConverter)( const std::vector<const IECore::Object *> &samples, float motionStart, float motionEnd );

/// Registers a converter for a specific type.
/// Use the ConverterDescription utility class in preference to
Expand All @@ -77,7 +77,7 @@ class ConverterDescription

/// Type-specific conversion functions.
typedef AtNode *(*Converter)( const T * );
typedef AtNode *(*MotionConverter)( const std::vector<const T *> &, const std::vector<float> & );
typedef AtNode *(*MotionConverter)( const std::vector<const T *> &, float, float );

ConverterDescription( Converter converter, MotionConverter motionConverter = NULL )
{
Expand All @@ -90,6 +90,11 @@ class ConverterDescription

};

/// Arnold does not support non-uniform sampling. It just takes a start and end time, and assume
/// the samples are distributed evenly between them. We need to throw an exception if given data
/// we can't render.
void ensureUniformTimeSamples( const std::vector<float> &times );

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just make this internal to the Renderer class? I'm trying to minimise the API surface area...

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I currently use this from both IECoreArnold::RendererImplementation and GafferArnold::IECoreArnoldPreview::Renderer, so I need it to be public. I can add a /todo to make it private in Cortex 10 when we don't have this split.


} // namespace NodeAlgo

} // namespace IECoreArnold
Expand Down
2 changes: 2 additions & 0 deletions contrib/IECoreArnold/include/IECoreArnold/ParameterAlgo.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,13 @@ namespace ParameterAlgo
{

IECOREARNOLD_API void setParameter( AtNode *node, const AtParamEntry *parameter, const IECore::Data *value );
IECOREARNOLD_API void setParameter( AtNode *node, AtString name, const IECore::Data *value );
IECOREARNOLD_API void setParameter( AtNode *node, const char *name, const IECore::Data *value );
IECOREARNOLD_API void setParameters( AtNode *node, const IECore::CompoundDataMap &values );

IECOREARNOLD_API IECore::DataPtr getParameter( AtNode *node, const AtParamEntry *parameter );
IECOREARNOLD_API IECore::DataPtr getParameter( AtNode *node, const AtUserParamEntry *parameter );
IECOREARNOLD_API IECore::DataPtr getParameter( AtNode *node, AtString name );
IECOREARNOLD_API IECore::DataPtr getParameter( AtNode *node, const char *name );
IECOREARNOLD_API void getParameters( AtNode *node, IECore::CompoundDataMap &values );

Expand Down
2 changes: 1 addition & 1 deletion contrib/IECoreArnold/include/IECoreArnold/PointsAlgo.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace PointsAlgo
{

AtNode *convert( const IECore::PointsPrimitive *points );
AtNode *convert( const std::vector<const IECore::PointsPrimitive *> &samples, const std::vector<float> &sampleTimes );
AtNode *convert( const std::vector<const IECore::PointsPrimitive *> &samples, float motionStart, float motionEnd );

} // namespace PointsAlgo

Expand Down
10 changes: 6 additions & 4 deletions contrib/IECoreArnold/include/IECoreArnold/Renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,12 @@ class IECOREARNOLD_API Renderer : public IECore::Renderer
///
/// \li <b>"ai:visibility:camera" BoolData( true )</b>
/// \li <b>"ai:visibility:shadow" BoolData( true )</b>
/// \li <b>"ai:visibility:reflected" BoolData( true )</b>
/// \li <b>"ai:visibility:refracted" BoolData( true )</b>
/// \li <b>"ai:visibility:diffuse" BoolData( true )</b>
/// \li <b>"ai:visibility:glossy" BoolData( true )</b>
/// \li <b>"ai:visibility:diffuseReflect" BoolData( true )</b>
/// \li <b>"ai:visibility:specularReflect" BoolData( true )</b>
/// \li <b>"ai:visibility:diffuseTransmit" BoolData( true )</b>
/// \li <b>"ai:visibility:specularTransmit" BoolData( true )</b>
/// \li <b>"ai:visibility:volume" BoolData( true )</b>
/// \li <b>"ai:visibility:subsurface" BoolData( true )</b>
///
/// \li <b>"ai:*:*" Data</b><br>
/// Mapped to shape node parameters, such that "ai:nodeType:parameterName"
Expand Down
2 changes: 1 addition & 1 deletion contrib/IECoreArnold/include/IECoreArnold/SphereAlgo.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace SphereAlgo
{

AtNode *convert( const IECore::SpherePrimitive *sphere );
AtNode *convert( const std::vector<const IECore::SpherePrimitive *> &samples, const std::vector<float> &sampleTimes );
AtNode *convert( const std::vector<const IECore::SpherePrimitive *> &samples, float motionStart, float motionEnd );

} // namespace SphereAlgo

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,11 @@ class RendererImplementation : public IECore::Renderer
RendererPtr renderer;
};

static int procLoader( AtProcVtable *vTable );
static int procFunc( AtProceduralNodeMethods *methods );
static int procInit( AtNode *node, void **userPtr );
static int procCleanup( void *userPtr );
static int procNumNodes( void *userPtr );
static AtNode *procGetNode( void *userPtr, int i );
static int procCleanup( const AtNode *node, void *userPtr );
static int procNumNodes( const AtNode *node, void *userPtr );
static AtNode *procGetNode( const AtNode *node, void *userPtr, int i );

boost::shared_ptr<UniverseBlock> m_universe;
InstancingConverterPtr m_instancingConverter;
Expand Down Expand Up @@ -195,7 +195,9 @@ class RendererImplementation : public IECore::Renderer
AttributeStack m_attributeStack;

// motion blur stuff
std::vector<float> m_motionTimes;
unsigned int m_motionBlockSize;
float m_motionStart;
float m_motionEnd;
std::vector<IECore::ConstPrimitivePtr> m_motionPrimitives;

// list of nodes that have been output so far. we have
Expand Down
4 changes: 2 additions & 2 deletions contrib/IECoreArnold/src/IECoreArnold/CameraAlgo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ AtNode *CameraAlgo::convert( const IECore::Camera *camera )
const Imath::V2i &resolution = cameraCopy->parametersData()->member<V2iData>( "resolution", true )->readable();
const float pixelAspectRatio = cameraCopy->parametersData()->member<FloatData>( "pixelAspectRatio", true )->readable();
float aspect = pixelAspectRatio * (float)resolution.x / (float)resolution.y;
AiNodeSetPnt2( result, "screen_window_min", screenWindow.min.x, screenWindow.min.y * aspect );
AiNodeSetPnt2( result, "screen_window_max", screenWindow.max.x, screenWindow.max.y * aspect );
AiNodeSetVec2( result, "screen_window_min", screenWindow.min.x, screenWindow.min.y * aspect );
AiNodeSetVec2( result, "screen_window_max", screenWindow.max.x, screenWindow.max.y * aspect );

// Set any Arnold-specific parameters

Expand Down
5 changes: 3 additions & 2 deletions contrib/IECoreArnold/src/IECoreArnold/CurvesAlgo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ AtNode *CurvesAlgo::convert( const IECore::CurvesPrimitive *curves )
return result;
}

AtNode *CurvesAlgo::convert( const std::vector<const IECore::CurvesPrimitive *> &samples, const std::vector<float> &sampleTimes )
AtNode *CurvesAlgo::convert( const std::vector<const IECore::CurvesPrimitive *> &samples, float motionStart, float motionEnd )
{
AtNode *result = convertCommon( samples.front() );

Expand Down Expand Up @@ -155,7 +155,8 @@ AtNode *CurvesAlgo::convert( const std::vector<const IECore::CurvesPrimitive *>
IECore::msg( IECore::Msg::Warning, "CurvesAlgo::convert", "Missing sample for primitive variable \"N\" - not setting orientations." );
}

AiNodeSetArray( result, "deform_time_samples", AiArrayConvert( sampleTimes.size(), 1, AI_TYPE_FLOAT, &sampleTimes.front() ) );
AiNodeSetFlt( result, "motion_start", motionStart );
AiNodeSetFlt( result, "motion_end", motionEnd );

return result;
}
Expand Down
8 changes: 4 additions & 4 deletions contrib/IECoreArnold/src/IECoreArnold/InstancingConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,12 @@ AtNode *InstancingConverter::convert( const IECore::Primitive *primitive, const
return NULL;
}

AtNode *InstancingConverter::convert( const std::vector<const IECore::Primitive *> &samples, const std::vector<float> &sampleTimes )
AtNode *InstancingConverter::convert( const std::vector<const IECore::Primitive *> &samples, float motionStart, float motionEnd )
{
return convert( samples, sampleTimes, IECore::MurmurHash() );
return convert( samples, motionStart, motionEnd, IECore::MurmurHash() );
}

AtNode *InstancingConverter::convert( const std::vector<const IECore::Primitive *> &samples, const std::vector<float> &sampleTimes, const IECore::MurmurHash &additionalHash )
AtNode *InstancingConverter::convert( const std::vector<const IECore::Primitive *> &samples, float motionStart, float motionEnd, const IECore::MurmurHash &additionalHash )
{
IECore::MurmurHash h;
for( std::vector<const IECore::Primitive *>::const_iterator it = samples.begin(), eIt = samples.end(); it != eIt; ++it )
Expand All @@ -106,7 +106,7 @@ AtNode *InstancingConverter::convert( const std::vector<const IECore::Primitive
if( m_data->cache.insert( a, h ) )
{
std::vector<const IECore::Object *> objectSamples( samples.begin(), samples.end() );
a->second = NodeAlgo::convert( objectSamples, sampleTimes );
a->second = NodeAlgo::convert( objectSamples, motionStart, motionEnd );
return a->second;
}
else
Expand Down
17 changes: 9 additions & 8 deletions contrib/IECoreArnold/src/IECoreArnold/MeshAlgo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,13 @@ void convertIndexedUVSet( const std::string &setName, PrimitiveVariableMap &vari
const vector<int> &indices = indicesData->readable();

int numUVs = 1 + *max_element( indices.begin(), indices.end() );
AtArray *uvsArray = AiArrayAllocate( numUVs, 1, AI_TYPE_POINT2 );
AtArray *uvsArray = AiArrayAllocate( numUVs, 1, AI_TYPE_VECTOR2 );
AtArray *indicesArray = AiArrayAllocate( indices.size(), 1, AI_TYPE_UINT );

for( size_t i = 0, e = indices.size(); i < e; ++i )
{
AtPoint2 uv = { s[i], 1.0f - t[i] };
AiArraySetPnt2( uvsArray, indices[i], uv );
AtVector2 uv( s[i], 1.0f - t[i] );
AiArraySetVec2( uvsArray, indices[i], uv );
AiArraySetUInt( indicesArray, i, indices[i] );
}

Expand Down Expand Up @@ -190,11 +190,11 @@ void convertUVSet( const std::string &setName, PrimitiveVariableMap &variables,
const vector<float> &s = sData->readable();
const vector<float> &t = tData->readable();

AtArray *uvsArray = AiArrayAllocate( s.size(), 1, AI_TYPE_POINT2 );
AtArray *uvsArray = AiArrayAllocate( s.size(), 1, AI_TYPE_VECTOR2 );
for( size_t i = 0, e = s.size(); i < e; ++i )
{
AtPoint2 uv = { s[i], 1.0f - t[i] };
AiArraySetPnt2( uvsArray, i, uv );
AtVector2 uv( s[i], 1.0f - t[i] );
AiArraySetVec2( uvsArray, i, uv );
}

AtArray *indicesArray = NULL;
Expand Down Expand Up @@ -391,7 +391,7 @@ AtNode *MeshAlgo::convert( const IECore::MeshPrimitive *mesh )
return result;
}

AtNode *MeshAlgo::convert( const std::vector<const IECore::MeshPrimitive *> &samples, const std::vector<float> &sampleTimes )
AtNode *MeshAlgo::convert( const std::vector<const IECore::MeshPrimitive *> &samples, float motionStart, float motionEnd )
{
AtNode *result = convertCommon( samples.front() );

Expand Down Expand Up @@ -428,7 +428,8 @@ AtNode *MeshAlgo::convert( const std::vector<const IECore::MeshPrimitive *> &sam

// add time sampling

AiNodeSetArray( result, "deform_time_samples", AiArrayConvert( sampleTimes.size(), 1, AI_TYPE_FLOAT, &sampleTimes.front() ) );
AiNodeSetFlt( result, "motion_start", motionStart );
AiNodeSetFlt( result, "motion_end", motionEnd );

return result;
}
Expand Down
40 changes: 38 additions & 2 deletions contrib/IECoreArnold/src/IECoreArnold/NodeAlgo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ AtNode *convert( const IECore::Object *object )
return it->second.converter( object );
}

AtNode *convert( const std::vector<const IECore::Object *> &samples, const std::vector<float> &sampleTimes )
AtNode *convert( const std::vector<const IECore::Object *> &samples, float motionStart, float motionEnd )
{
if( samples.empty() )
{
Expand All @@ -115,7 +115,7 @@ AtNode *convert( const std::vector<const IECore::Object *> &samples, const std::

if( it->second.motionConverter )
{
return it->second.motionConverter( samples, sampleTimes );
return it->second.motionConverter( samples, motionStart, motionEnd );
}
else
{
Expand All @@ -128,6 +128,42 @@ void registerConverter( IECore::TypeId fromType, Converter converter, MotionConv
registry().insert( Registry::value_type( fromType, Converters( converter, motionConverter ) ) );
}

void ensureUniformTimeSamples( const std::vector<float> &times )
{
if( times.size() == 0 )
{
throw IECore::Exception( "Motion block times must not be empty" );
}

float motionStart = times[0];
float motionEnd = times[ times.size() - 1 ];

for( unsigned int i = 0; i < times.size(); i++ )
{
// Use a really coarse epsilon to check if the values are uniform - if someone is sloppy with
// floating point precision when computing their sample times, we don't want to stop them from rendering.
// But we should warn someone if they are actually trying to use a feature Arnold doesn't support.
const float uniformity_epsilon = 0.01;
float expectedTime = motionStart + ( motionEnd - motionStart ) / ( times.size() - 1 ) * i;
if( times[i] < expectedTime - uniformity_epsilon || times[i] > expectedTime + uniformity_epsilon )
{
std::stringstream text;
text << "Arnold does not support non-uniform motion blocks.\n";
text << "Invalid motion block: [ " << times[0];
for( unsigned int j = 1; j < times.size(); j++ )
{
text << ", " << times[j];
}
text << " ]\n";
text << "( sample " << i << ", with value " << times[i] << " does not match " << expectedTime << ")\n";
throw IECore::Exception( text.str() );


}
}

}

} // namespace NodeAlgo

} // namespace IECoreArnold
Loading