diff --git a/SConstruct b/SConstruct index 38a0e392a6..b25a1fb4d5 100644 --- a/SConstruct +++ b/SConstruct @@ -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 ] ) arnoldTestEnv.Depends( arnoldTest, glob.glob( "contrib/IECoreArnold/test/IECoreArnold/*.py" ) ) arnoldTestEnv.Alias( "testArnold", arnoldTest ) diff --git a/config/ie/options b/config/ie/options index 07dff23cb9..f4d227d783 100644 --- a/config/ie/options +++ b/config/ie/options @@ -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" ] diff --git a/contrib/IECoreArnold/include/IECoreArnold/CurvesAlgo.h b/contrib/IECoreArnold/include/IECoreArnold/CurvesAlgo.h index d7051ba4c3..ec0df2cfbe 100644 --- a/contrib/IECoreArnold/include/IECoreArnold/CurvesAlgo.h +++ b/contrib/IECoreArnold/include/IECoreArnold/CurvesAlgo.h @@ -46,7 +46,7 @@ namespace CurvesAlgo { AtNode *convert( const IECore::CurvesPrimitive *curves ); -AtNode *convert( const std::vector &samples, const std::vector &sampleTimes ); +AtNode *convert( const std::vector &samples, float motionStart, float motionEnd ); } // namespace CurvesAlgo diff --git a/contrib/IECoreArnold/include/IECoreArnold/InstancingConverter.h b/contrib/IECoreArnold/include/IECoreArnold/InstancingConverter.h index 1451f46a6b..25687af9ea 100644 --- a/contrib/IECoreArnold/include/IECoreArnold/InstancingConverter.h +++ b/contrib/IECoreArnold/include/IECoreArnold/InstancingConverter.h @@ -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 &samples, const std::vector &sampleTimes ); - AtNode *convert( const std::vector &samples, const std::vector &sampleTimes, const IECore::MurmurHash &additionalHash ); + AtNode *convert( const std::vector &samples, float motionStart, float motionEnd ); + AtNode *convert( const std::vector &samples, float motionStart, float motionEnd, const IECore::MurmurHash &additionalHash ); private : diff --git a/contrib/IECoreArnold/include/IECoreArnold/MeshAlgo.h b/contrib/IECoreArnold/include/IECoreArnold/MeshAlgo.h index 16d840ab25..4b23ee12bf 100644 --- a/contrib/IECoreArnold/include/IECoreArnold/MeshAlgo.h +++ b/contrib/IECoreArnold/include/IECoreArnold/MeshAlgo.h @@ -46,7 +46,7 @@ namespace MeshAlgo { AtNode *convert( const IECore::MeshPrimitive *mesh ); -AtNode *convert( const std::vector &samples, const std::vector &sampleTimes ); +AtNode *convert( const std::vector &samples, float motionStart, float motionEnd ); } // namespace MeshAlgo diff --git a/contrib/IECoreArnold/include/IECoreArnold/NodeAlgo.h b/contrib/IECoreArnold/include/IECoreArnold/NodeAlgo.h index 232fb5fe85..634fe9f442 100644 --- a/contrib/IECoreArnold/include/IECoreArnold/NodeAlgo.h +++ b/contrib/IECoreArnold/include/IECoreArnold/NodeAlgo.h @@ -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 &samples, const std::vector &sampleTimes ); +AtNode *convert( const std::vector &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 &samples, const std::vector &sampleTimes ); +typedef AtNode * (*MotionConverter)( const std::vector &samples, float motionStart, float motionEnd ); /// Registers a converter for a specific type. /// Use the ConverterDescription utility class in preference to @@ -77,7 +77,7 @@ class ConverterDescription /// Type-specific conversion functions. typedef AtNode *(*Converter)( const T * ); - typedef AtNode *(*MotionConverter)( const std::vector &, const std::vector & ); + typedef AtNode *(*MotionConverter)( const std::vector &, float, float ); ConverterDescription( Converter converter, MotionConverter motionConverter = NULL ) { @@ -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 × ); + } // namespace NodeAlgo } // namespace IECoreArnold diff --git a/contrib/IECoreArnold/include/IECoreArnold/ParameterAlgo.h b/contrib/IECoreArnold/include/IECoreArnold/ParameterAlgo.h index bcf9017f7a..778d7aed3b 100644 --- a/contrib/IECoreArnold/include/IECoreArnold/ParameterAlgo.h +++ b/contrib/IECoreArnold/include/IECoreArnold/ParameterAlgo.h @@ -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 ); diff --git a/contrib/IECoreArnold/include/IECoreArnold/PointsAlgo.h b/contrib/IECoreArnold/include/IECoreArnold/PointsAlgo.h index 76f1f46d3d..319011a1ad 100644 --- a/contrib/IECoreArnold/include/IECoreArnold/PointsAlgo.h +++ b/contrib/IECoreArnold/include/IECoreArnold/PointsAlgo.h @@ -46,7 +46,7 @@ namespace PointsAlgo { AtNode *convert( const IECore::PointsPrimitive *points ); -AtNode *convert( const std::vector &samples, const std::vector &sampleTimes ); +AtNode *convert( const std::vector &samples, float motionStart, float motionEnd ); } // namespace PointsAlgo diff --git a/contrib/IECoreArnold/include/IECoreArnold/Renderer.h b/contrib/IECoreArnold/include/IECoreArnold/Renderer.h index 2d6e9aeee1..186eac2da5 100644 --- a/contrib/IECoreArnold/include/IECoreArnold/Renderer.h +++ b/contrib/IECoreArnold/include/IECoreArnold/Renderer.h @@ -95,10 +95,12 @@ class IECOREARNOLD_API Renderer : public IECore::Renderer /// /// \li "ai:visibility:camera" BoolData( true ) /// \li "ai:visibility:shadow" BoolData( true ) - /// \li "ai:visibility:reflected" BoolData( true ) - /// \li "ai:visibility:refracted" BoolData( true ) - /// \li "ai:visibility:diffuse" BoolData( true ) - /// \li "ai:visibility:glossy" BoolData( true ) + /// \li "ai:visibility:diffuseReflect" BoolData( true ) + /// \li "ai:visibility:specularReflect" BoolData( true ) + /// \li "ai:visibility:diffuseTransmit" BoolData( true ) + /// \li "ai:visibility:specularTransmit" BoolData( true ) + /// \li "ai:visibility:volume" BoolData( true ) + /// \li "ai:visibility:subsurface" BoolData( true ) /// /// \li "ai:*:*" Data
/// Mapped to shape node parameters, such that "ai:nodeType:parameterName" diff --git a/contrib/IECoreArnold/include/IECoreArnold/SphereAlgo.h b/contrib/IECoreArnold/include/IECoreArnold/SphereAlgo.h index 3c1c1cf17f..66f5428a0a 100644 --- a/contrib/IECoreArnold/include/IECoreArnold/SphereAlgo.h +++ b/contrib/IECoreArnold/include/IECoreArnold/SphereAlgo.h @@ -46,7 +46,7 @@ namespace SphereAlgo { AtNode *convert( const IECore::SpherePrimitive *sphere ); -AtNode *convert( const std::vector &samples, const std::vector &sampleTimes ); +AtNode *convert( const std::vector &samples, float motionStart, float motionEnd ); } // namespace SphereAlgo diff --git a/contrib/IECoreArnold/include/IECoreArnold/private/RendererImplementation.h b/contrib/IECoreArnold/include/IECoreArnold/private/RendererImplementation.h index 154daa9913..2f45734d14 100644 --- a/contrib/IECoreArnold/include/IECoreArnold/private/RendererImplementation.h +++ b/contrib/IECoreArnold/include/IECoreArnold/private/RendererImplementation.h @@ -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 m_universe; InstancingConverterPtr m_instancingConverter; @@ -195,7 +195,9 @@ class RendererImplementation : public IECore::Renderer AttributeStack m_attributeStack; // motion blur stuff - std::vector m_motionTimes; + unsigned int m_motionBlockSize; + float m_motionStart; + float m_motionEnd; std::vector m_motionPrimitives; // list of nodes that have been output so far. we have diff --git a/contrib/IECoreArnold/src/IECoreArnold/CameraAlgo.cpp b/contrib/IECoreArnold/src/IECoreArnold/CameraAlgo.cpp index 64503f0906..6d2a3c14f2 100644 --- a/contrib/IECoreArnold/src/IECoreArnold/CameraAlgo.cpp +++ b/contrib/IECoreArnold/src/IECoreArnold/CameraAlgo.cpp @@ -89,8 +89,8 @@ AtNode *CameraAlgo::convert( const IECore::Camera *camera ) const Imath::V2i &resolution = cameraCopy->parametersData()->member( "resolution", true )->readable(); const float pixelAspectRatio = cameraCopy->parametersData()->member( "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 diff --git a/contrib/IECoreArnold/src/IECoreArnold/CurvesAlgo.cpp b/contrib/IECoreArnold/src/IECoreArnold/CurvesAlgo.cpp index 820ae7730c..1a6a6bfcc4 100644 --- a/contrib/IECoreArnold/src/IECoreArnold/CurvesAlgo.cpp +++ b/contrib/IECoreArnold/src/IECoreArnold/CurvesAlgo.cpp @@ -124,7 +124,7 @@ AtNode *CurvesAlgo::convert( const IECore::CurvesPrimitive *curves ) return result; } -AtNode *CurvesAlgo::convert( const std::vector &samples, const std::vector &sampleTimes ) +AtNode *CurvesAlgo::convert( const std::vector &samples, float motionStart, float motionEnd ) { AtNode *result = convertCommon( samples.front() ); @@ -155,7 +155,8 @@ AtNode *CurvesAlgo::convert( const std::vector 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; } diff --git a/contrib/IECoreArnold/src/IECoreArnold/InstancingConverter.cpp b/contrib/IECoreArnold/src/IECoreArnold/InstancingConverter.cpp index 6cf30ae1d7..0ace65b14a 100644 --- a/contrib/IECoreArnold/src/IECoreArnold/InstancingConverter.cpp +++ b/contrib/IECoreArnold/src/IECoreArnold/InstancingConverter.cpp @@ -88,12 +88,12 @@ AtNode *InstancingConverter::convert( const IECore::Primitive *primitive, const return NULL; } -AtNode *InstancingConverter::convert( const std::vector &samples, const std::vector &sampleTimes ) +AtNode *InstancingConverter::convert( const std::vector &samples, float motionStart, float motionEnd ) { - return convert( samples, sampleTimes, IECore::MurmurHash() ); + return convert( samples, motionStart, motionEnd, IECore::MurmurHash() ); } -AtNode *InstancingConverter::convert( const std::vector &samples, const std::vector &sampleTimes, const IECore::MurmurHash &additionalHash ) +AtNode *InstancingConverter::convert( const std::vector &samples, float motionStart, float motionEnd, const IECore::MurmurHash &additionalHash ) { IECore::MurmurHash h; for( std::vector::const_iterator it = samples.begin(), eIt = samples.end(); it != eIt; ++it ) @@ -106,7 +106,7 @@ AtNode *InstancingConverter::convert( const std::vectorcache.insert( a, h ) ) { std::vector objectSamples( samples.begin(), samples.end() ); - a->second = NodeAlgo::convert( objectSamples, sampleTimes ); + a->second = NodeAlgo::convert( objectSamples, motionStart, motionEnd ); return a->second; } else diff --git a/contrib/IECoreArnold/src/IECoreArnold/MeshAlgo.cpp b/contrib/IECoreArnold/src/IECoreArnold/MeshAlgo.cpp index 60cd924784..a57fbbd9e2 100644 --- a/contrib/IECoreArnold/src/IECoreArnold/MeshAlgo.cpp +++ b/contrib/IECoreArnold/src/IECoreArnold/MeshAlgo.cpp @@ -126,13 +126,13 @@ void convertIndexedUVSet( const std::string &setName, PrimitiveVariableMap &vari const vector &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] ); } @@ -190,11 +190,11 @@ void convertUVSet( const std::string &setName, PrimitiveVariableMap &variables, const vector &s = sData->readable(); const vector &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; @@ -391,7 +391,7 @@ AtNode *MeshAlgo::convert( const IECore::MeshPrimitive *mesh ) return result; } -AtNode *MeshAlgo::convert( const std::vector &samples, const std::vector &sampleTimes ) +AtNode *MeshAlgo::convert( const std::vector &samples, float motionStart, float motionEnd ) { AtNode *result = convertCommon( samples.front() ); @@ -428,7 +428,8 @@ AtNode *MeshAlgo::convert( const std::vector &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; } diff --git a/contrib/IECoreArnold/src/IECoreArnold/NodeAlgo.cpp b/contrib/IECoreArnold/src/IECoreArnold/NodeAlgo.cpp index 284a319d11..1d99d8be5b 100644 --- a/contrib/IECoreArnold/src/IECoreArnold/NodeAlgo.cpp +++ b/contrib/IECoreArnold/src/IECoreArnold/NodeAlgo.cpp @@ -89,7 +89,7 @@ AtNode *convert( const IECore::Object *object ) return it->second.converter( object ); } -AtNode *convert( const std::vector &samples, const std::vector &sampleTimes ) +AtNode *convert( const std::vector &samples, float motionStart, float motionEnd ) { if( samples.empty() ) { @@ -115,7 +115,7 @@ AtNode *convert( const std::vector &samples, const std:: if( it->second.motionConverter ) { - return it->second.motionConverter( samples, sampleTimes ); + return it->second.motionConverter( samples, motionStart, motionEnd ); } else { @@ -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 × ) +{ + 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 diff --git a/contrib/IECoreArnold/src/IECoreArnold/ParameterAlgo.cpp b/contrib/IECoreArnold/src/IECoreArnold/ParameterAlgo.cpp index e08303d3cd..f1a90e0f61 100644 --- a/contrib/IECoreArnold/src/IECoreArnold/ParameterAlgo.cpp +++ b/contrib/IECoreArnold/src/IECoreArnold/ParameterAlgo.cpp @@ -65,7 +65,7 @@ inline const T *dataCast( const char *name, const IECore::Data *data ) return NULL; } -void setParameterInternal( AtNode *node, const char *name, int parameterType, bool array, const IECore::Data *value ) +void setParameterInternal( AtNode *node, AtString name, int parameterType, bool array, const IECore::Data *value ) { if( array ) { @@ -75,7 +75,7 @@ void setParameterInternal( AtNode *node, const char *name, int parameterType, bo msg( Msg::Warning, "setParameter", boost::format( "Unable to create array from data of type \"%s\" for parameter \"%s\"" ) % value->typeName() % name ); return; } - if( a->type != parameterType ) + if( AiArrayGetType( a ) != parameterType ) { msg( Msg::Warning, "setParameter", boost::format( "Unable to create array of type %s from data of type \"%s\" for parameter \"%s\"" ) % AiParamGetTypeName( parameterType ) % value->typeName() % name ); return; @@ -148,32 +148,39 @@ void setParameterInternal( AtNode *node, const char *name, int parameterType, bo AiNodeSetBool( node, name, data->readable() ); } break; - case AI_TYPE_POINT2 : - if( const V2fData *data = dataCast( name, value ) ) + case AI_TYPE_VECTOR2 : + if( const V2iData *data = runTimeCast( value ) ) + { + // Accept a V2i as an alternate since Arnold has + // no integer vector type to store these in. + const Imath::V2i &v = data->readable(); + AiNodeSetVec2( node, name, v.x, v.y ); + } + else if( const V2fData *data = dataCast( name, value ) ) { const Imath::V2f &v = data->readable(); - AiNodeSetPnt2( node, name, v.x, v.y ); + AiNodeSetVec2( node, name, v.x, v.y ); } break; case AI_TYPE_VECTOR : - if( const V3fData *data = dataCast( name, value ) ) + if( const V3iData *data = runTimeCast( value ) ) { - const Imath::V3f &v = data->readable(); + // Accept a V3i as an alternate since Arnold has + // no integer vector type to store these in. + const Imath::V3i &v = data->readable(); AiNodeSetVec( node, name, v.x, v.y, v.z ); } - break; - case AI_TYPE_POINT : - if( const V3fData *data = dataCast( name, value ) ) + else if( const V3fData *data = dataCast( name, value ) ) { const Imath::V3f &v = data->readable(); - AiNodeSetPnt( node, name, v.x, v.y, v.z ); + AiNodeSetVec( node, name, v.x, v.y, v.z ); } break; case AI_TYPE_MATRIX : if( const M44dData *data = runTimeCast( value ) ) { const Imath::M44f v( data->readable() ); - AiNodeSetMatrix( node, name, const_cast( v.x ) ); + AiNodeSetMatrix( node, name, *reinterpret_cast( const_cast( &v.x ) ) ); } else if( const M44fData *data = dataCast( name, value ) ) { @@ -181,7 +188,7 @@ void setParameterInternal( AtNode *node, const char *name, int parameterType, bo // Can't see any reason why AiNodeSetMatrix couldn't have been declared const, // this const_cast seems safe - AiNodeSetMatrix( node, name, const_cast( v.x ) ); + AiNodeSetMatrix( node, name, *reinterpret_cast( const_cast( &v.x ) ) ); } break; default : @@ -206,8 +213,8 @@ IECore::DataPtr arrayToDataInternal( AtArray *array, F f ) typename DataType::Ptr data = new DataType; VectorType &v = data->writable(); - v.reserve( array->nelements ); - for( size_t i = 0; i < array->nelements; ++i ) + v.reserve( AiArrayGetNumElements(array) ); + for( size_t i = 0; i < AiArrayGetNumElements(array); ++i ) { v.push_back( f( array, i, __AI_FILE__, __AI_LINE__ ) ); } @@ -215,11 +222,17 @@ IECore::DataPtr arrayToDataInternal( AtArray *array, F f ) return data; } +const char* getStrWrapperFunc( const AtArray* a, uint32_t i, const char* file, int line ) +{ + return AiArrayGetStrFunc( a, i, file, line ).c_str(); +} + + /// \todo Flesh this out to support more types and then /// consider exposing it in the public API. IECore::DataPtr arrayToData( AtArray *array ) { - if( array->nkeys > 1 ) + if( AiArrayGetNumKeys( array ) > 1 ) { /// \todo Decide how to deal with more /// than one key - is it more useful to return multiple Data @@ -227,7 +240,7 @@ IECore::DataPtr arrayToData( AtArray *array ) return NULL; } - switch( array->type ) + switch( AiArrayGetType( array ) ) { case AI_TYPE_BOOLEAN : return arrayToDataInternal( array, AiArrayGetBoolFunc ); @@ -236,7 +249,7 @@ IECore::DataPtr arrayToData( AtArray *array ) case AI_TYPE_FLOAT : return arrayToDataInternal( array, AiArrayGetFltFunc ); case AI_TYPE_STRING : - return arrayToDataInternal( array, AiArrayGetStrFunc ); + return arrayToDataInternal( array, getStrWrapperFunc ); default : return NULL; } @@ -253,7 +266,7 @@ IECore::DataPtr getParameterInternal( AtNode *node, const char *name, int parame case AI_TYPE_FLOAT : return new FloatData( AiNodeGetFlt( node, name ) ); case AI_TYPE_STRING : - return new StringData( AiNodeGetStr( node, name ) ); + return new StringData( AiNodeGetStr( node, name ).c_str() ); case AI_TYPE_RGB : { AtRGB rgb = AiNodeGetRGB( node, name ); @@ -293,14 +306,14 @@ void setParameter( AtNode *node, const AtParamEntry *parameter, const IECore::Da int type = AiParamGetType( parameter ); if( type == AI_TYPE_ARRAY ) { - type = AiParamGetDefault( parameter )->ARRAY->type; + type = AiArrayGetType( AiParamGetDefault( parameter )->ARRAY() ); isArray = true; } setParameterInternal( node, AiParamGetName( parameter ), type, isArray, value ); } -void setParameter( AtNode *node, const char *name, const IECore::Data *value ) +void setParameter( AtNode *node, AtString name, const IECore::Data *value ) { const AtParamEntry *parameter = AiNodeEntryLookUpParameter( AiNodeGetNodeEntry( node ), name ); if( parameter ) @@ -336,6 +349,11 @@ void setParameter( AtNode *node, const char *name, const IECore::Data *value ) } } +void setParameter( AtNode *node, const char* name, const IECore::Data *value ) +{ + setParameter( node, AtString( name ), value ); +} + void setParameters( AtNode *node, const IECore::CompoundDataMap &values ) { for( CompoundDataMap::const_iterator it=values.begin(); it!=values.end(); it++ ) @@ -354,7 +372,7 @@ IECore::DataPtr getParameter( AtNode *node, const AtUserParamEntry *parameter ) return getParameterInternal( node, AiUserParamGetName( parameter ), AiUserParamGetType( parameter ) ); } -IECore::DataPtr getParameter( AtNode *node, const char *name ) +IECore::DataPtr getParameter( AtNode *node, AtString name ) { const AtParamEntry *parameter = AiNodeEntryLookUpParameter( AiNodeGetNodeEntry( node ), name ); if( parameter ) @@ -373,6 +391,11 @@ IECore::DataPtr getParameter( AtNode *node, const char *name ) return NULL; } +IECore::DataPtr getParameter( AtNode *node, const char *name ) +{ + return getParameter( node, AtString( name ) ); +} + void getParameters( AtNode *node, IECore::CompoundDataMap &values ) { /// \todo Non-user parameters @@ -422,7 +445,12 @@ int parameterType( IECore::TypeId dataType, bool &array ) case BoolDataTypeId : array = false; return AI_TYPE_BOOLEAN; + case V2fDataTypeId : + case V2iDataTypeId : + array = false; + return AI_TYPE_VECTOR2; case V3fDataTypeId : + case V3iDataTypeId : array = false; return AI_TYPE_VECTOR; case M44fDataTypeId : @@ -447,7 +475,12 @@ int parameterType( IECore::TypeId dataType, bool &array ) case BoolVectorDataTypeId : array = true; return AI_TYPE_BOOLEAN; + case V2fVectorDataTypeId : + case V2iVectorDataTypeId : + array = true; + return AI_TYPE_VECTOR2; case V3fVectorDataTypeId : + case V3iVectorDataTypeId : array = true; return AI_TYPE_VECTOR; case M44fVectorDataTypeId : @@ -460,19 +493,7 @@ int parameterType( IECore::TypeId dataType, bool &array ) int parameterType( const IECore::Data *data, bool &array ) { - int type = parameterType( data->typeId(), array ); - - // if we have data of type vector, its interpretation matters - if( type == AI_TYPE_VECTOR ) - { - GeometricData::Interpretation interpretation = getGeometricInterpretation( data ); - if( interpretation == GeometricData::Point ) - { - type = AI_TYPE_POINT; - } - } - - return type; + return parameterType( data->typeId(), array ); } AtArray *dataToArray( const IECore::Data *data, int aiType ) diff --git a/contrib/IECoreArnold/src/IECoreArnold/PointsAlgo.cpp b/contrib/IECoreArnold/src/IECoreArnold/PointsAlgo.cpp index 263a5daab6..8cdbd8cda6 100644 --- a/contrib/IECoreArnold/src/IECoreArnold/PointsAlgo.cpp +++ b/contrib/IECoreArnold/src/IECoreArnold/PointsAlgo.cpp @@ -116,7 +116,7 @@ AtNode *convert( const IECore::PointsPrimitive *points ) return result; } -AtNode *convert( const std::vector &samples, const std::vector &sampleTimes ) +AtNode *convert( const std::vector &samples, float motionStart, float motionEnd ) { AtNode *result = convertCommon( samples.front() ); @@ -124,7 +124,9 @@ AtNode *convert( const std::vector &samples, co ShapeAlgo::convertP( primitiveSamples, result, "points" ); ShapeAlgo::convertRadius( primitiveSamples, result ); - AiNodeSetArray( result, "deform_time_samples", AiArrayConvert( sampleTimes.size(), 1, AI_TYPE_FLOAT, &sampleTimes.front() ) ); + + AiNodeSetFlt( result, "motion_start", motionStart ); + AiNodeSetFlt( result, "motion_end", motionEnd ); /// \todo Aspect, rotation diff --git a/contrib/IECoreArnold/src/IECoreArnold/RendererImplementation.cpp b/contrib/IECoreArnold/src/IECoreArnold/RendererImplementation.cpp index 65307a0d08..69bfeb9b16 100644 --- a/contrib/IECoreArnold/src/IECoreArnold/RendererImplementation.cpp +++ b/contrib/IECoreArnold/src/IECoreArnold/RendererImplementation.cpp @@ -81,10 +81,12 @@ RendererImplementation::AttributeState::AttributeState() attributes = new CompoundData; attributes->writable()["ai:visibility:camera"] = new BoolData( true ); attributes->writable()["ai:visibility:shadow"] = new BoolData( true ); - attributes->writable()["ai:visibility:reflected"] = new BoolData( true ); - attributes->writable()["ai:visibility:refracted"] = new BoolData( true ); - attributes->writable()["ai:visibility:diffuse"] = new BoolData( true ); - attributes->writable()["ai:visibility:glossy"] = new BoolData( true ); + attributes->writable()["ai:visibility:diffuseReflect"] = new BoolData( true ); + attributes->writable()["ai:visibility:specularReflect"] = new BoolData( true ); + attributes->writable()["ai:visibility:diffuseTransmit"] = new BoolData( true ); + attributes->writable()["ai:visibility:specularTransmit"] = new BoolData( true ); + attributes->writable()["ai:visibility:volume"] = new BoolData( true ); + attributes->writable()["ai:visibility:subsurface"] = new BoolData( true ); } RendererImplementation::AttributeState::AttributeState( const AttributeState &other ) @@ -102,20 +104,20 @@ RendererImplementation::AttributeState::AttributeState( const AttributeState &ot extern AtNodeMethods *ieDisplayDriverMethods; IECoreArnold::RendererImplementation::RendererImplementation() - : m_defaultFilter( 0 ) + : m_defaultFilter( 0 ), m_motionBlockSize( 0 ) { constructCommon( Render ); } IECoreArnold::RendererImplementation::RendererImplementation( const std::string &assFileName ) - : m_defaultFilter( 0 ) + : m_defaultFilter( 0 ), m_motionBlockSize( 0 ) { m_assFileName = assFileName; constructCommon( AssGen ); } IECoreArnold::RendererImplementation::RendererImplementation( const RendererImplementation &other ) - : m_transformStack( other.m_transformStack, /* flatten = */ true ) + : m_transformStack( other.m_transformStack, /* flatten = */ true ), m_motionBlockSize( 0 ) { constructCommon( Procedural ); m_instancingConverter = other.m_instancingConverter; @@ -123,6 +125,7 @@ IECoreArnold::RendererImplementation::RendererImplementation( const RendererImpl } IECoreArnold::RendererImplementation::RendererImplementation( const AtNode *proceduralNode ) + : m_motionBlockSize( 0 ) { constructCommon( Procedural ); m_instancingConverter = new InstancingConverter; @@ -142,9 +145,6 @@ void IECoreArnold::RendererImplementation::constructCommon( Mode mode ) m_universe = boost::shared_ptr( new UniverseBlock( /* writable = */ true ) ); m_instancingConverter = new InstancingConverter; - /// \todo Control with an option - AiMsgSetConsoleFlags( AI_LOG_ALL ); - // create a generic filter we can use for all displays m_defaultFilter = AiNode( "gaussian_filter" ); AiNodeSetStr( m_defaultFilter, "name", "ieCoreArnold:defaultFilter" ); @@ -155,10 +155,6 @@ void IECoreArnold::RendererImplementation::constructCommon( Mode mode ) IECoreArnold::RendererImplementation::~RendererImplementation() { - if( m_mode != Procedural ) - { - AiEnd(); - } } //////////////////////////////////////////////////////////////////////// @@ -235,7 +231,7 @@ void IECoreArnold::RendererImplementation::camera( const std::string &name, cons AiNodeSetInt( options, "yres", resolution->readable().y ); const FloatData *pixelAspectRatio = cortexCamera->parametersData()->member( "pixelAspectRatio" ); - AiNodeSetFlt( options, "aspect_ratio", 1.0f / pixelAspectRatio->readable() ); // arnold is y/x, we're x/y + AiNodeSetFlt( options, "pixel_aspect_ratio", 1.0f / pixelAspectRatio->readable() ); // arnold is y/x, we're x/y } void IECoreArnold::RendererImplementation::display( const std::string &name, const std::string &type, const std::string &data, const IECore::CompoundDataMap ¶meters ) @@ -355,9 +351,12 @@ void IECoreArnold::RendererImplementation::transformEnd() void IECoreArnold::RendererImplementation::setTransform( const Imath::M44f &m ) { - if( m_motionTimes.size() && !m_transformStack.inMotion() ) + if( m_motionBlockSize && !m_transformStack.inMotion() ) { - m_transformStack.motionBegin( m_motionTimes ); + // We call motionBegin on the transform stack with a dummy time sample vector of the correct size + // Arnold doesn't support non-uniform time sampling, so we won't use the actual values, we just + // need the transform block to know how many values to expect. + m_transformStack.motionBegin( std::vector( m_motionBlockSize, 0.0f ) ); } m_transformStack.set( m ); } @@ -380,9 +379,10 @@ Imath::M44f IECoreArnold::RendererImplementation::getTransform( const std::strin void IECoreArnold::RendererImplementation::concatTransform( const Imath::M44f &m ) { - if( m_motionTimes.size() && !m_transformStack.inMotion() ) + if( m_motionBlockSize && !m_transformStack.inMotion() ) { - m_transformStack.motionBegin( m_motionTimes ); + // See comment in setTransform + m_transformStack.motionBegin( std::vector( m_motionBlockSize, 0.0f ) ); } m_transformStack.concatenate( m ); } @@ -540,24 +540,32 @@ void IECoreArnold::RendererImplementation::illuminate( const std::string &lightH void IECoreArnold::RendererImplementation::motionBegin( const std::set × ) { - if( !m_motionTimes.empty() ) + if( m_motionBlockSize ) { msg( Msg::Error, "IECoreArnold::RendererImplementation::motionBegin", "Already in a motion block." ); return; } - m_motionTimes.insert( m_motionTimes.end(), times.begin(), times.end() ); + // TODO - is it worth the time to do this, in order to avoid silently giving incorrect results? + std::vector timesVector; + timesVector.insert( timesVector.end(), times.begin(), times.end() ); + NodeAlgo::ensureUniformTimeSamples( timesVector ); + + m_motionStart = *times.begin(); + m_motionEnd = *(--times.end()); + m_motionBlockSize = times.size(); + } void IECoreArnold::RendererImplementation::motionEnd() { - if( m_motionTimes.empty() ) + if( !m_motionBlockSize ) { msg( Msg::Error, "IECoreArnold::RendererImplementation::motionEnd", "Not in a motion block." ); return; } - m_motionTimes.clear(); + m_motionBlockSize = 0; m_motionPrimitives.clear(); if( m_transformStack.inMotion() ) { @@ -630,14 +638,12 @@ void IECoreArnold::RendererImplementation::geometry( const std::string &type, co ///////////////////////////////////////////////////////////////////////////////////////// // procedurals ///////////////////////////////////////////////////////////////////////////////////////// - -int IECoreArnold::RendererImplementation::procLoader( AtProcVtable *vTable ) +int IECoreArnold::RendererImplementation::procFunc( AtProceduralNodeMethods *methods ) { - vTable->Init = procInit; - vTable->Cleanup = procCleanup; - vTable->NumNodes = procNumNodes; - vTable->GetNode = procGetNode; - strcpy( vTable->version, AI_VERSION ); + methods->Init = procInit; + methods->Cleanup = procCleanup; + methods->NumNodes = procNumNodes; + methods->GetNode = procGetNode; return 1; } @@ -650,20 +656,20 @@ int IECoreArnold::RendererImplementation::procInit( AtNode *node, void **userPtr return 1; } -int IECoreArnold::RendererImplementation::procCleanup( void *userPtr ) +int IECoreArnold::RendererImplementation::procCleanup( const AtNode *node, void *userPtr ) { ProceduralData *data = (ProceduralData *)( userPtr ); delete data; return 1; } -int IECoreArnold::RendererImplementation::procNumNodes( void *userPtr ) +int IECoreArnold::RendererImplementation::procNumNodes( const AtNode *node, void *userPtr ) { ProceduralData *data = (ProceduralData *)( userPtr ); return data->renderer->m_implementation->m_nodes.size(); } -AtNode* IECoreArnold::RendererImplementation::procGetNode( void *userPtr, int i ) +AtNode* IECoreArnold::RendererImplementation::procGetNode( const AtNode *node, void *userPtr, int i ) { ProceduralData *data = (ProceduralData *)( userPtr ); return data->renderer->m_implementation->m_nodes[i]; @@ -682,17 +688,12 @@ void IECoreArnold::RendererImplementation::procedural( IECore::Renderer::Procedu if( const ExternalProcedural *externalProc = dynamic_cast( proc.get() ) ) { - // Allow a parameter "ai:nodeType" == "volume" to create a volume shape rather - // than a procedural shape. Volume shapes provide "dso", "min" and "max" parameters - // just as procedural shapes do, so the mapping is a fairly natural one. - CompoundDataMap::const_iterator nodeTypeIt = externalProc->parameters().find( "ai:nodeType" ); - if( nodeTypeIt != externalProc->parameters().end() && nodeTypeIt->second->isInstanceOf( StringData::staticTypeId() ) ) - { - nodeType = static_cast( nodeTypeIt->second.get() )->readable(); - } - node = AiNode( nodeType.c_str() ); - - AiNodeSetStr( node, "dso", externalProc->fileName().c_str() ); + // \todo In Arnold, external procedurals register node types, and then we use the node types + // just like built in nodes - we don't reference the filename of the dso that defines the node type. + // So here we just interpret "filename" as the node type to create. + // Where should this be documented. Should we change the name of the parameter to ExternalProcedural + // to be something other than "filename" in Cortex 10? + node = AiNode( externalProc->fileName().c_str() ); ParameterAlgo::setParameters( node, externalProc->parameters() ); applyTransformToNode( node ); } @@ -713,7 +714,7 @@ void IECoreArnold::RendererImplementation::procedural( IECore::Renderer::Procedu bound = transformedBound; } - AiNodeSetPtr( node, "funcptr", (void *)procLoader ); + AiNodeSetPtr( node, "funcptr", (void *)procFunc ); ProceduralData *data = new ProceduralData; data->procedural = proc; @@ -722,17 +723,6 @@ void IECoreArnold::RendererImplementation::procedural( IECore::Renderer::Procedu AiNodeSetPtr( node, "userptr", data ); } - if( bound != Procedural::noBound ) - { - AiNodeSetPnt( node, "min", bound.min.x, bound.min.y, bound.min.z ); - AiNodeSetPnt( node, "max", bound.max.x, bound.max.y, bound.max.z ); - } - else - { - // No bound available - expand procedural immediately. - AiNodeSetBool( node, "load_at_init", true ); - } - if( nodeType == "procedural" ) { // We call addNode() rather than addShape() as we don't want to apply transforms and @@ -767,12 +757,12 @@ bool IECoreArnold::RendererImplementation::automaticInstancing() const void IECoreArnold::RendererImplementation::addPrimitive( const IECore::Primitive *primitive, const std::string &attributePrefix ) { - if( !m_motionTimes.empty() ) + if( m_motionBlockSize ) { // We're in a motion block. Just store samples // until we have all of them. m_motionPrimitives.push_back( primitive ); - if( m_motionPrimitives.size() != m_motionTimes.size() ) + if( m_motionPrimitives.size() != m_motionBlockSize ) { return; } @@ -795,14 +785,14 @@ void IECoreArnold::RendererImplementation::addPrimitive( const IECore::Primitive it->second->hash( hash ); } } - if( !m_motionTimes.empty() ) + if( m_motionBlockSize ) { vector prims; for( vector::const_iterator it = m_motionPrimitives.begin(), eIt = m_motionPrimitives.end(); it != eIt; ++it ) { prims.push_back( it->get() ); } - shape = m_instancingConverter->convert( prims, m_motionTimes, hash ); + shape = m_instancingConverter->convert( prims, m_motionStart, m_motionEnd, hash ); } else { @@ -811,14 +801,14 @@ void IECoreArnold::RendererImplementation::addPrimitive( const IECore::Primitive } else { - if( !m_motionTimes.empty() ) + if( m_motionBlockSize ) { vector prims; for( vector::const_iterator it = m_motionPrimitives.begin(), eIt = m_motionPrimitives.end(); it != eIt; ++it ) { prims.push_back( it->get() ); } - shape = NodeAlgo::convert( prims, m_motionTimes ); + shape = NodeAlgo::convert( prims, m_motionStart, m_motionEnd ); } else { @@ -874,32 +864,26 @@ void IECoreArnold::RendererImplementation::applyTransformToNode( AtNode *node ) const size_t numSamples = m_transformStack.numSamples(); if( numSamples == 1 ) { - AiNodeSetMatrix( node, "matrix", m_transformStack.get().x ); + M44f m = m_transformStack.get(); + AiNodeSetMatrix( node, "matrix", *reinterpret_cast( (float(*)[4][4])&m.x ) ); } else { - AtArray *times = AiArrayAllocate( numSamples, 1, AI_TYPE_FLOAT ); AtArray *matrices = AiArrayAllocate( 1, numSamples, AI_TYPE_MATRIX ); for( size_t i = 0; i < numSamples; ++i ) { - AiArraySetFlt( times, i, m_transformStack.sampleTime( i ) ); - AiArraySetMtx( matrices, i, m_transformStack.sample( i ).x ); + M44f m = m_transformStack.sample( i ); + AiArraySetMtx( matrices, i, *reinterpret_cast( (float(*)[4][4])&m.x ) ); } AiNodeSetArray( node, "matrix", matrices ); - if( AiNodeEntryLookUpParameter( AiNodeGetNodeEntry( node ), "transform_time_samples" ) ) - { - AiNodeSetArray( node, "transform_time_samples", times ); - } - else - { - AiNodeSetArray( node, "time_samples", times ); - } + AiNodeSetFlt( node, "motion_start", m_motionStart ); + AiNodeSetFlt( node, "motion_end", m_motionEnd ); } } void IECoreArnold::RendererImplementation::applyVisibilityToNode( AtNode *node ) { - AtByte visibility = 0; + uint8_t visibility = 0; const BoolData *visData = m_attributeStack.top().attributes->member( "ai:visibility:camera" ); if( visData->readable() ) { @@ -912,28 +896,40 @@ void IECoreArnold::RendererImplementation::applyVisibilityToNode( AtNode *node ) visibility |= AI_RAY_SHADOW; } - visData = m_attributeStack.top().attributes->member( "ai:visibility:reflected" ); + visData = m_attributeStack.top().attributes->member( "ai:visibility:diffuseReflect" ); + if( visData->readable() ) + { + visibility |= AI_RAY_DIFFUSE_REFLECT; + } + + visData = m_attributeStack.top().attributes->member( "ai:visibility:specularReflect" ); + if( visData->readable() ) + { + visibility |= AI_RAY_SPECULAR_REFLECT; + } + + visData = m_attributeStack.top().attributes->member( "ai:visibility:diffuseTransmit" ); if( visData->readable() ) { - visibility |= AI_RAY_REFLECTED; + visibility |= AI_RAY_DIFFUSE_TRANSMIT; } - visData = m_attributeStack.top().attributes->member( "ai:visibility:refracted" ); + visData = m_attributeStack.top().attributes->member( "ai:visibility:specularTransmit" ); if( visData->readable() ) { - visibility |= AI_RAY_REFRACTED; + visibility |= AI_RAY_SPECULAR_TRANSMIT; } - visData = m_attributeStack.top().attributes->member( "ai:visibility:diffuse" ); + visData = m_attributeStack.top().attributes->member( "ai:visibility:volume" ); if( visData->readable() ) { - visibility |= AI_RAY_DIFFUSE; + visibility |= AI_RAY_VOLUME; } - visData = m_attributeStack.top().attributes->member( "ai:visibility:glossy" ); + visData = m_attributeStack.top().attributes->member( "ai:visibility:subsurface" ); if( visData->readable() ) { - visibility |= AI_RAY_GLOSSY; + visibility |= AI_RAY_SUBSURFACE; } AiNodeSetByte( node, "visibility", visibility ); diff --git a/contrib/IECoreArnold/src/IECoreArnold/ShapeAlgo.cpp b/contrib/IECoreArnold/src/IECoreArnold/ShapeAlgo.cpp index 01cfb2ad99..8408d03067 100644 --- a/contrib/IECoreArnold/src/IECoreArnold/ShapeAlgo.cpp +++ b/contrib/IECoreArnold/src/IECoreArnold/ShapeAlgo.cpp @@ -121,7 +121,7 @@ void convertP( const IECore::Primitive *primitive, AtNode *shape, const char *na AiNodeSetArray( shape, name, - AiArrayConvert( p->readable().size(), 1, AI_TYPE_POINT, (void *)&( p->readable()[0] ) ) + AiArrayConvert( p->readable().size(), 1, AI_TYPE_VECTOR, (void *)&( p->readable()[0] ) ) ); } @@ -140,7 +140,7 @@ void convertP( const std::vector &samples, AtNode *sh dataSamples.push_back( p ); } - AtArray *array = ParameterAlgo::dataToArray( dataSamples, AI_TYPE_POINT ); + AtArray *array = ParameterAlgo::dataToArray( dataSamples, AI_TYPE_VECTOR ); AiNodeSetArray( shape, name, array ); } @@ -282,7 +282,7 @@ void convertPrimitiveVariable( const IECore::Primitive *primitive, const Primiti AiNodeSetArray( shape, (name + string("idxs")).c_str(), - identityIndices( array->nelements ) + identityIndices( AiArrayGetNumElements( array ) ) ); } } diff --git a/contrib/IECoreArnold/src/IECoreArnold/SphereAlgo.cpp b/contrib/IECoreArnold/src/IECoreArnold/SphereAlgo.cpp index 72686c9d7a..78fdc5db72 100644 --- a/contrib/IECoreArnold/src/IECoreArnold/SphereAlgo.cpp +++ b/contrib/IECoreArnold/src/IECoreArnold/SphereAlgo.cpp @@ -87,7 +87,7 @@ AtNode *SphereAlgo::convert( const IECore::SpherePrimitive *sphere ) return result; } -AtNode *SphereAlgo::convert( const std::vector &samples, const std::vector &sampleTimes ) +AtNode *SphereAlgo::convert( const std::vector &samples, float motionStart, float motionEnd ) { AtNode *result = AiNode( "sphere" ); ShapeAlgo::convertPrimitiveVariables( samples.front(), result ); @@ -102,7 +102,8 @@ AtNode *SphereAlgo::convert( const std::vector } AiNodeSetArray( result, "radius", radiusSamples ); - 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; } diff --git a/contrib/IECoreArnold/src/IECoreArnold/UniverseBlock.cpp b/contrib/IECoreArnold/src/IECoreArnold/UniverseBlock.cpp index 8a7abf59f6..e5c404887c 100644 --- a/contrib/IECoreArnold/src/IECoreArnold/UniverseBlock.cpp +++ b/contrib/IECoreArnold/src/IECoreArnold/UniverseBlock.cpp @@ -80,6 +80,10 @@ void loadMetadata( const std::string &pluginPaths ) void begin() { AiBegin(); + // Default to logging errors / warnings only - we may not even be using this universe block to perform a render, + // we might just be loading some shader metadata or something, so we don't want to be dumping lots of + // unnecessary output + AiMsgSetConsoleFlags( AI_LOG_ERRORS | AI_LOG_WARNINGS ); const char *pluginPaths = getenv( "ARNOLD_PLUGIN_PATH" ); if( pluginPaths ) diff --git a/contrib/IECoreArnold/src/IECoreArnold/bindings/InstancingConverterBinding.cpp b/contrib/IECoreArnold/src/IECoreArnold/bindings/InstancingConverterBinding.cpp index deb38cb751..b83fed02e4 100644 --- a/contrib/IECoreArnold/src/IECoreArnold/bindings/InstancingConverterBinding.cpp +++ b/contrib/IECoreArnold/src/IECoreArnold/bindings/InstancingConverterBinding.cpp @@ -55,32 +55,28 @@ using namespace IECoreArnoldBindings; namespace { -object convertWrapper1( InstancingConverter &c, object pythonSamples, object pythonSampleTimes ) +object convertWrapper1( InstancingConverter &c, object pythonSamples, float motionStart, float motionEnd ) { vector samples; - vector sampleTimes; boost::python::container_utils::extend_container( samples, pythonSamples ); - boost::python::container_utils::extend_container( sampleTimes, pythonSampleTimes ); AtNode *node; { IECorePython::ScopedGILRelease gilRelease; - node = c.convert( samples, sampleTimes ); + node = c.convert( samples, motionStart, motionEnd ); } return atNodeToPythonObject( node ); } -object convertWrapper2( InstancingConverter &c, object pythonSamples, object pythonSampleTimes, const IECore::MurmurHash &h ) +object convertWrapper2( InstancingConverter &c, object pythonSamples, float motionStart, float motionEnd, const IECore::MurmurHash &h ) { vector samples; - vector sampleTimes; boost::python::container_utils::extend_container( samples, pythonSamples ); - boost::python::container_utils::extend_container( sampleTimes, pythonSampleTimes ); AtNode *node; { IECorePython::ScopedGILRelease gilRelease; - node = c.convert( samples, sampleTimes, h ); + node = c.convert( samples, motionStart, motionEnd, h ); } return atNodeToPythonObject( node ); } diff --git a/contrib/IECoreArnold/src/IECoreArnold/bindings/NodeAlgoBinding.cpp b/contrib/IECoreArnold/src/IECoreArnold/bindings/NodeAlgoBinding.cpp index c9baed8060..ac4c9cc89c 100644 --- a/contrib/IECoreArnold/src/IECoreArnold/bindings/NodeAlgoBinding.cpp +++ b/contrib/IECoreArnold/src/IECoreArnold/bindings/NodeAlgoBinding.cpp @@ -51,14 +51,12 @@ object convertWrapper( const IECore::Object *object ) return atNodeToPythonObject( NodeAlgo::convert( object ) ); } -object convertWrapper2( object pythonSamples, object pythonSampleTimes ) +object convertWrapper2( object pythonSamples, float motionStart, float motionEnd ) { std::vector samples; - std::vector sampleTimes; container_utils::extend_container( samples, pythonSamples ); - container_utils::extend_container( sampleTimes, pythonSampleTimes ); - return atNodeToPythonObject( NodeAlgo::convert( samples, sampleTimes ) ); + return atNodeToPythonObject( NodeAlgo::convert( samples, motionStart, motionEnd ) ); } } // namespace diff --git a/contrib/IECoreArnold/src/IECoreArnold/mtoaExtension/ProceduralHolderTranslator.cpp b/contrib/IECoreArnold/src/IECoreArnold/mtoaExtension/ProceduralHolderTranslator.cpp index fbc1a82612..79251e6b96 100644 --- a/contrib/IECoreArnold/src/IECoreArnold/mtoaExtension/ProceduralHolderTranslator.cpp +++ b/contrib/IECoreArnold/src/IECoreArnold/mtoaExtension/ProceduralHolderTranslator.cpp @@ -62,7 +62,7 @@ class ProceduralHolderTranslator : public CShapeTranslator if (m_isMasterDag) { - return AddArnoldNode( "procedural" ); + return AddArnoldNode( "ieProcedural" ); } else { @@ -158,16 +158,6 @@ class ProceduralHolderTranslator : public CShapeTranslator MFnDagNode fnDagNode( m_dagPath ); MBoundingBox bound = fnDagNode.boundingBox(); - AiNodeSetPnt( node, "min", bound.min().x, bound.min().y, bound.min().z ); - AiNodeSetPnt( node, "max", bound.max().x, bound.max().y, bound.max().z ); - - const char *dsoPath = getenv( "IECOREARNOLD_PROCEDURAL_PATH" ); - AiNodeSetStr( node, "dso", dsoPath ? dsoPath : "ieProcedural.so" ); - - AiNodeDeclare( node, "className", "constant STRING" ); - AiNodeDeclare( node, "classVersion", "constant INT" ); - AiNodeDeclare( node, "parameterValues", "constant ARRAY STRING" ); - // cast should be ok as we're registered to only work on procedural holders IECoreMaya::ProceduralHolder *pHolder = static_cast( fnDagNode.userNode() ); diff --git a/contrib/IECoreArnold/src/IECoreArnold/outputDriver/OutputDriver.cpp b/contrib/IECoreArnold/src/IECoreArnold/outputDriver/OutputDriver.cpp index 99314d7ade..890c43f622 100644 --- a/contrib/IECoreArnold/src/IECoreArnold/outputDriver/OutputDriver.cpp +++ b/contrib/IECoreArnold/src/IECoreArnold/outputDriver/OutputDriver.cpp @@ -54,7 +54,7 @@ namespace // Stores a Cortex DisplayDriver and the parameters // used to create it. This forms the private data -// accessed via AiDriverGetLocalData. +// accessed via AiNodeGetLocalData. struct LocalData { @@ -89,25 +89,26 @@ struct LocalData }; -void driverParameters( AtList *params, AtMetaDataStore *metaData ) +void driverParameters( AtList *params, AtNodeEntry *nentry ) { - AiParameterSTR( "driverType", "" ); + AiParameterStr( "driverType", "" ); // we need to specify this metadata to keep MtoA happy. - AiMetaDataSetStr( metaData, 0, "maya.attr_prefix", "" ); - AiMetaDataSetStr( metaData, 0, "maya.translator", "ie" ); + AiMetaDataSetStr( nentry, 0, "maya.attr_prefix", "" ); + AiMetaDataSetStr( nentry, 0, "maya.translator", "ie" ); } -void driverInitialize( AtNode *node, AtParamValue *parameters ) +void driverInitialize( AtNode *node ) { - AiDriverInitialize( node, true, new LocalData ); + AiDriverInitialize( node, true ); + AiNodeSetLocalData( node, new LocalData ); } -void driverUpdate( AtNode *node, AtParamValue *parameters ) +void driverUpdate( AtNode *node ) { } -bool driverSupportsPixelType( const AtNode *node, AtByte pixelType ) +bool driverSupportsPixelType( const AtNode *node, uint8_t pixelType ) { switch( pixelType ) { @@ -115,7 +116,6 @@ bool driverSupportsPixelType( const AtNode *node, AtByte pixelType ) case AI_TYPE_RGBA : case AI_TYPE_FLOAT : case AI_TYPE_VECTOR : - case AI_TYPE_POINT : return true; default: return false; @@ -129,7 +129,7 @@ const char **driverExtension() void driverOpen( AtNode *node, struct AtOutputIterator *iterator, AtBBox2 displayWindow, AtBBox2 dataWindow, int bucketSize ) { - LocalData *localData = (LocalData *)AiDriverGetLocalData( node ); + LocalData *localData = (LocalData *)AiNodeGetLocalData( node ); localData->numOutputs = 0; std::vector channelNames; @@ -157,7 +157,6 @@ void driverOpen( AtNode *node, struct AtOutputIterator *iterator, AtBBox2 displa { case AI_TYPE_RGB : case AI_TYPE_VECTOR : - case AI_TYPE_POINT : channelNames.push_back( namePrefix + "R" ); channelNames.push_back( namePrefix + "G" ); channelNames.push_back( namePrefix + "B" ); @@ -194,10 +193,10 @@ void driverOpen( AtNode *node, struct AtOutputIterator *iterator, AtBBox2 displa // window. parameters->writable()["pixelAspect"] = new FloatData( // Arnold is y/x, we're x/y - 1.0f / AiNodeGetFlt( AiUniverseGetOptions(), "aspect_ratio" ) + 1.0f / AiNodeGetFlt( AiUniverseGetOptions(), "pixel_aspect_ratio" ) ); - const std::string driverType = AiNodeGetStr( node, "driverType" ); + const std::string driverType = AiNodeGetStr( node, "driverType" ).c_str(); // We reuse the previous driver if we can - this allows us to use // the same driver for every stage of a progressive render. @@ -235,22 +234,22 @@ void driverOpen( AtNode *node, struct AtOutputIterator *iterator, AtBBox2 displa } } -bool driverNeedsBucket( AtNode *node, int x, int y, int sx, int sy, int tId ) +bool driverNeedsBucket( AtNode *node, int x, int y, int sx, int sy, uint16_t tId ) { return true; } -void driverPrepareBucket( AtNode *node, int x, int y, int sx, int sy, int tId ) +void driverPrepareBucket( AtNode *node, int x, int y, int sx, int sy, uint16_t tId ) { } -void driverProcessBucket( AtNode *node, struct AtOutputIterator *iterator, struct AtAOVSampleIterator *sample_iterator, int x, int y, int sx, int sy, int tId ) +void driverProcessBucket( AtNode *node, struct AtOutputIterator *iterator, struct AtAOVSampleIterator *sample_iterator, int x, int y, int sx, int sy, uint16_t tId ) { } void driverWriteBucket( AtNode *node, struct AtOutputIterator *iterator, struct AtAOVSampleIterator *sampleIterator, int x, int y, int sx, int sy ) { - LocalData *localData = (LocalData *)AiDriverGetLocalData( node ); + LocalData *localData = (LocalData *)AiNodeGetLocalData( node ); if( !localData->displayDriver ) { return; @@ -283,7 +282,6 @@ void driverWriteBucket( AtNode *node, struct AtOutputIterator *iterator, struct { case AI_TYPE_RGB : case AI_TYPE_VECTOR : - case AI_TYPE_POINT : numChannels = 3; break; case AI_TYPE_RGBA : @@ -333,7 +331,7 @@ void driverWriteBucket( AtNode *node, struct AtOutputIterator *iterator, struct void driverClose( AtNode *node, struct AtOutputIterator *iterator ) { - LocalData *localData = (LocalData *)AiDriverGetLocalData( node ); + LocalData *localData = (LocalData *)AiNodeGetLocalData( node ); // We only close the display immediately if it doesn't accept // repeated data (progressive renders). This is so we can reuse it in // driverOpen if it appears that a progressive render is taking place. @@ -345,11 +343,10 @@ void driverClose( AtNode *node, struct AtOutputIterator *iterator ) void driverFinish( AtNode *node ) { - LocalData *localData = (LocalData *)AiDriverGetLocalData( node ); + LocalData *localData = (LocalData *)AiNodeGetLocalData( node ); // Perform any pending close we may have deferred in driverClose(). localData->imageClose(); delete localData; - AiDriverDestroy( node ); } } // namespace @@ -359,6 +356,8 @@ AI_EXPORT_LIB bool NodeLoader( int i, AtNodeLib *node ) if( i==0 ) { static AtCommonMethods commonMethods = { + NULL, // Whole plugin init + NULL, // Whole plugin cleanup driverParameters, driverInitialize, driverUpdate, diff --git a/contrib/IECoreArnold/src/IECoreArnold/procedural/Procedural.cpp b/contrib/IECoreArnold/src/IECoreArnold/procedural/Procedural.cpp index dbb4ec2a95..0041cad73b 100644 --- a/contrib/IECoreArnold/src/IECoreArnold/procedural/Procedural.cpp +++ b/contrib/IECoreArnold/src/IECoreArnold/procedural/Procedural.cpp @@ -99,7 +99,16 @@ static void initialisePython() PyEval_ReleaseThread( PyThreadState_Get() ); } -static int procInit( AtNode *node, void **userPtr ) +AI_PROCEDURAL_NODE_EXPORT_METHODS(IECoreProcedural); + +node_parameters +{ + AiParameterStr( "className", "" ); + AiParameterInt( "classVersion", 1 ); + AiParameterArray( "parameterValues", AiArray(0, 1, AI_TYPE_STRING) ); +} + +procedural_init { // load the class @@ -120,11 +129,11 @@ static int procInit( AtNode *node, void **userPtr ) if( parameterValues ) { boost::python::list toParse; - for( unsigned i=0; inelements; i++ ) + for( unsigned i=0; irender( renderer.get() ); renderer->addRef(); - *userPtr = renderer.get(); + *user_ptr = renderer.get(); } else { - *userPtr = 0; + *user_ptr = 0; } return 1; } -static int procCleanup( void *userPtr ) +procedural_cleanup { - IECoreArnold::Renderer *renderer = (IECoreArnold::Renderer *)( userPtr ); + IECoreArnold::Renderer *renderer = (IECoreArnold::Renderer *)( user_ptr ); if( renderer ) { renderer->removeRef(); @@ -183,27 +192,29 @@ static int procCleanup( void *userPtr ) return 1; } -static int procNumNodes( void *userPtr ) +procedural_num_nodes { - IECoreArnold::Renderer *renderer = (IECoreArnold::Renderer *)( userPtr ); + IECoreArnold::Renderer *renderer = (IECoreArnold::Renderer *)( user_ptr ); return renderer ? renderer->numProceduralNodes() : 0; } -static AtNode* procGetNode( void *userPtr, int i ) +procedural_get_node { - IECoreArnold::Renderer *renderer = (IECoreArnold::Renderer *)( userPtr ); + IECoreArnold::Renderer *renderer = (IECoreArnold::Renderer *)( user_ptr ); return renderer ? (AtNode *)renderer->proceduralNode( i ) : 0; } -AI_EXPORT_LIB int ProcLoader( AtProcVtable *vTable ) +node_loader { + if (i>0) + return false; - vTable->Init = procInit; - vTable->Cleanup = procCleanup; - vTable->NumNodes = procNumNodes; - vTable->GetNode = procGetNode; - strcpy( vTable->version, AI_VERSION ); + node->methods = IECoreProcedural; + node->output_type = AI_TYPE_NONE; + node->name = "ieProcedural"; + node->node_type = AI_NODE_SHAPE_PROCEDURAL; + strcpy(node->version, AI_VERSION); - return 1; + return true; } diff --git a/contrib/IECoreArnold/test/IECoreArnold/AutomaticInstancingTest.py b/contrib/IECoreArnold/test/IECoreArnold/AutomaticInstancingTest.py index c68d92908d..24d419550b 100644 --- a/contrib/IECoreArnold/test/IECoreArnold/AutomaticInstancingTest.py +++ b/contrib/IECoreArnold/test/IECoreArnold/AutomaticInstancingTest.py @@ -143,11 +143,11 @@ def arnoldMessageCallback( logMask, severity, msg, tabs ) : self.__arnoldMessages.append( msg ) r = IECoreArnold.Renderer() - r.display( "test", "driver_null", "rgba", {} ) messageCallback = arnold.AtMsgCallBack( arnoldMessageCallback ) arnold.AiMsgSetCallback( messageCallback ) self.__arnoldMessages = [] + arnold.AiMsgSetConsoleFlags( arnold.AI_LOG_ALL ) with IECore.WorldBlock( r ) : diff --git a/contrib/IECoreArnold/test/IECoreArnold/CameraAlgoTest.py b/contrib/IECoreArnold/test/IECoreArnold/CameraAlgoTest.py index 758f308abe..381f89ccbb 100644 --- a/contrib/IECoreArnold/test/IECoreArnold/CameraAlgoTest.py +++ b/contrib/IECoreArnold/test/IECoreArnold/CameraAlgoTest.py @@ -59,8 +59,8 @@ def testConvertPerspective( self ) : self.assertTrue( arnold.AiNodeEntryGetName( arnold.AiNodeGetNodeEntry( n ) ), "persp_camera" ) self.assertEqual( arnold.AiNodeGetFlt( n, "fov" ), 45.0 ) - self.assertEqual( arnold.AiNodeGetPnt2( n, "screen_window_min" ), arnold.AtPoint2( -1, -0.5 ) ) - self.assertEqual( arnold.AiNodeGetPnt2( n, "screen_window_max" ), arnold.AtPoint2( 1, 0.5 ) ) + self.assertEqual( arnold.AiNodeGetVec2( n, "screen_window_min" ), arnold.AtVector2( -1, -0.5 ) ) + self.assertEqual( arnold.AiNodeGetVec2( n, "screen_window_max" ), arnold.AtVector2( 1, 0.5 ) ) def testConvertCustomProjection( self ) : diff --git a/contrib/IECoreArnold/test/IECoreArnold/CurvesTest.py b/contrib/IECoreArnold/test/IECoreArnold/CurvesTest.py index 2ec3ac4b41..565668b2be 100644 --- a/contrib/IECoreArnold/test/IECoreArnold/CurvesTest.py +++ b/contrib/IECoreArnold/test/IECoreArnold/CurvesTest.py @@ -59,22 +59,19 @@ def testMotion( self ) : with IECoreArnold.UniverseBlock( writable = True ) : - n = IECoreArnold.NodeAlgo.convert( [ c1, c2 ], [ -0.25, 0.25 ] ) + n = IECoreArnold.NodeAlgo.convert( [ c1, c2 ], -0.25, 0.25 ) a = arnold.AiNodeGetArray( n, "points" ) - self.assertEqual( a.contents.nelements, 4 ) - self.assertEqual( a.contents.nkeys, 2 ) + self.assertEqual( arnold.AiArrayGetNumElements( a.contents ), 4 ) + self.assertEqual( arnold.AiArrayGetNumKeys( a.contents ), 2 ) for i in range( 0, 4 ) : - self.assertEqual( arnold.AiArrayGetPnt( a, i ), arnold.AtPoint( 1 ) ) + self.assertEqual( arnold.AiArrayGetVec( a, i ), arnold.AtVector( 1 ) ) for i in range( 4, 8 ) : - self.assertEqual( arnold.AiArrayGetPnt( a, i ), arnold.AtPoint( 2 ) ) + self.assertEqual( arnold.AiArrayGetVec( a, i ), arnold.AtVector( 2 ) ) - a = arnold.AiNodeGetArray( n, "deform_time_samples" ) - self.assertEqual( a.contents.nelements, 2 ) - self.assertEqual( a.contents.nkeys, 1 ) - self.assertEqual( arnold.AiArrayGetFlt( a, 0 ), -0.25 ) - self.assertEqual( arnold.AiArrayGetFlt( a, 1 ), 0.25 ) + self.assertEqual( arnold.AiNodeGetFlt( n, "motion_start" ), -0.25 ) + self.assertEqual( arnold.AiNodeGetFlt( n, "motion_end" ), 0.25 ) def testNPrimitiveVariable( self ) : @@ -90,7 +87,7 @@ def testNPrimitiveVariable( self ) : n = IECoreArnold.NodeAlgo.convert( c ) self.assertEqual( arnold.AiNodeGetStr( n, "mode" ), "ribbon" ) - self.assertEqual( arnold.AiNodeGetArray( n, "orientations" ).contents.nelements, 0 ) + self.assertEqual( arnold.AiArrayGetNumElements( arnold.AiNodeGetArray( n, "orientations" ).contents ), 0 ) # N - should be oriented @@ -102,7 +99,7 @@ def testNPrimitiveVariable( self ) : n = IECoreArnold.NodeAlgo.convert( c ) self.assertEqual( arnold.AiNodeGetStr( n, "mode" ), "oriented" ) orientations = arnold.AiNodeGetArray( n, "orientations" ) - self.assertEqual( orientations.contents.nelements, 4 ) + self.assertEqual( arnold.AiArrayGetNumElements( orientations.contents ), 4 ) for i in range( 0, 4 ) : self.assertEqual( arnold.AiArrayGetVec( orientations, i ), arnold.AtVector( 0, math.sin( i ), math.cos( i ) ) ) @@ -115,12 +112,12 @@ def testNPrimitiveVariable( self ) : IECore.V3fVectorData( [ IECore.V3f( 0, math.sin( x + 0.2 ), math.cos( x + 0.2 ) ) for x in range( 0, 4 ) ] ) ) - n = IECoreArnold.NodeAlgo.convert( [ c, c2 ], [ 0.0, 1.0 ] ) + n = IECoreArnold.NodeAlgo.convert( [ c, c2 ], 0.0, 1.0 ) self.assertEqual( arnold.AiNodeGetStr( n, "mode" ), "oriented" ) orientations = arnold.AiNodeGetArray( n, "orientations" ) - self.assertEqual( orientations.contents.nelements, 4 ) - self.assertEqual( orientations.contents.nkeys, 2 ) + self.assertEqual( arnold.AiArrayGetNumElements( orientations.contents ), 4 ) + self.assertEqual( arnold.AiArrayGetNumKeys( orientations.contents ), 2 ) for i in range( 0, 4 ) : self.assertEqual( arnold.AiArrayGetVec( orientations, i ), arnold.AtVector( 0, math.sin( i ), math.cos( i ) ) ) diff --git a/contrib/IECoreArnold/test/IECoreArnold/InstancingConverterTest.py b/contrib/IECoreArnold/test/IECoreArnold/InstancingConverterTest.py index 5a1b7662f7..c4bac5d870 100644 --- a/contrib/IECoreArnold/test/IECoreArnold/InstancingConverterTest.py +++ b/contrib/IECoreArnold/test/IECoreArnold/InstancingConverterTest.py @@ -152,21 +152,21 @@ def testMotion( self ) : m1 = IECore.MeshPrimitive.createPlane( IECore.Box2f( IECore.V2f( -1 ), IECore.V2f( 1 ) ) ) m2 = IECore.MeshPrimitive.createPlane( IECore.Box2f( IECore.V2f( -2 ), IECore.V2f( 2 ) ) ) - n1 = c.convert( [ m1, m2 ], [ -0.25, 0.25 ] ) + n1 = c.convert( [ m1, m2 ], -0.25, 0.25 ) self.assertEqual( arnold.AiNodeEntryGetName( arnold.AiNodeGetNodeEntry( n1 ) ), "polymesh" ) - self.assertEqual( arnold.AiNodeGetArray( n1, "vlist" ).contents.nkeys, 2 ) + self.assertEqual( arnold.AiArrayGetNumKeys( arnold.AiNodeGetArray( n1, "vlist" ).contents ), 2 ) - n2 = c.convert( [ m1, m2 ], [ -0.25, 0.25 ] ) + n2 = c.convert( [ m1, m2 ], -0.25, 0.25 ) self.assertEqual( arnold.AiNodeEntryGetName( arnold.AiNodeGetNodeEntry( n2 ) ), "ginstance" ) self.assertEqual( arnold.AiNodeGetPtr( n2, "node" ), ctypes.addressof( n1.contents ) ) - n3 = c.convert( [ m2, m1 ], [ -0.25, 0.25 ] ) + n3 = c.convert( [ m2, m1 ], -0.25, 0.25 ) self.assertEqual( arnold.AiNodeEntryGetName( arnold.AiNodeGetNodeEntry( n1 ) ), "polymesh" ) - self.assertEqual( arnold.AiNodeGetArray( n1, "vlist" ).contents.nkeys, 2 ) + self.assertEqual( arnold.AiArrayGetNumKeys( arnold.AiNodeGetArray( n1, "vlist" ).contents ), 2 ) - n4 = c.convert( [ m1, m2 ], [ -0.5, 0.5 ] ) + n4 = c.convert( [ m1, m2 ], -0.5, 0.5 ) self.assertEqual( arnold.AiNodeEntryGetName( arnold.AiNodeGetNodeEntry( n1 ) ), "polymesh" ) - self.assertEqual( arnold.AiNodeGetArray( n1, "vlist" ).contents.nkeys, 2 ) + self.assertEqual( arnold.AiArrayGetNumKeys( arnold.AiNodeGetArray( n1, "vlist" ).contents ), 2 ) if __name__ == "__main__": unittest.main() diff --git a/contrib/IECoreArnold/test/IECoreArnold/MeshTest.py b/contrib/IECoreArnold/test/IECoreArnold/MeshTest.py index c5b0bb6238..836d024fc9 100644 --- a/contrib/IECoreArnold/test/IECoreArnold/MeshTest.py +++ b/contrib/IECoreArnold/test/IECoreArnold/MeshTest.py @@ -55,14 +55,14 @@ def testUVs( self ) : n = IECoreArnold.NodeAlgo.convert( m ) uvs = arnold.AiNodeGetArray( n, "uvlist" ) - self.assertEqual( uvs.contents.nelements, 4 ) + self.assertEqual( arnold.AiArrayGetNumElements( uvs.contents ), 4 ) uvIndices = arnold.AiNodeGetArray( n, "uvidxs" ) - self.assertEqual( uvIndices.contents.nelements, 4 ) + self.assertEqual( arnold.AiArrayGetNumElements( uvIndices.contents ), 4 ) for i in range( 0, 4 ) : - p = arnold.AiArrayGetPnt2( uvs, i ) - self.assertEqual( arnold.AiArrayGetPnt2( uvs, i ), arnold.AtPoint2( s[i], 1 - t[i] ) ) + p = arnold.AiArrayGetVec2( uvs, i ) + self.assertEqual( arnold.AiArrayGetVec2( uvs, i ), arnold.AtVector2( s[i], 1 - t[i] ) ) self.assertEqual( arnold.AiArrayGetInt( uvIndices, i ), i ) def testAdditionalUVs( self ) : @@ -78,14 +78,14 @@ def testAdditionalUVs( self ) : n = IECoreArnold.NodeAlgo.convert( m ) uvs = arnold.AiNodeGetArray( n, "myMap" ) - self.assertEqual( uvs.contents.nelements, 4 ) + self.assertEqual( arnold.AiArrayGetNumElements( uvs.contents ), 4 ) uvIndices = arnold.AiNodeGetArray( n, "myMapidxs" ) - self.assertEqual( uvIndices.contents.nelements, 4 ) + self.assertEqual( arnold.AiArrayGetNumElements( uvIndices.contents ), 4 ) for i in range( 0, 4 ) : - p = arnold.AiArrayGetPnt2( uvs, i ) - self.assertEqual( arnold.AiArrayGetPnt2( uvs, i ), arnold.AtPoint2( s[i], 1 - t[i] ) ) + p = arnold.AiArrayGetVec2( uvs, i ) + self.assertEqual( arnold.AiArrayGetVec2( uvs, i ), arnold.AtVector2( s[i], 1 - t[i] ) ) self.assertEqual( arnold.AiArrayGetInt( uvIndices, i ), i ) @@ -134,7 +134,7 @@ def testVertexPrimitiveVariables( self ) : n = IECoreArnold.NodeAlgo.convert( m ) a = arnold.AiNodeGetArray( n, "myPrimVar" ) v = arnold.AiNodeGetArray( n, "myV3fPrimVar" ) - self.assertEqual( a.contents.nelements, 4 ) + self.assertEqual( arnold.AiArrayGetNumElements( a.contents ), 4 ) for i in range( 0, 4 ) : self.assertEqual( arnold.AiArrayGetFlt( a, i ), i ) self.assertEqual( arnold.AiArrayGetVec( v, i ), i ) @@ -157,8 +157,8 @@ def testFaceVaryingPrimitiveVariables( self ) : n = IECoreArnold.NodeAlgo.convert( m ) a = arnold.AiNodeGetArray( n, "myPrimVar" ) ia = arnold.AiNodeGetArray( n, "myPrimVaridxs" ) - self.assertEqual( a.contents.nelements, 16 ) - self.assertEqual( ia.contents.nelements, 16 ) + self.assertEqual( arnold.AiArrayGetNumElements( a.contents ), 16 ) + self.assertEqual( arnold.AiArrayGetNumElements( ia.contents ), 16 ) for i in range( 0, 16 ) : self.assertEqual( arnold.AiArrayGetFlt( a, i ), i ) self.assertEqual( arnold.AiArrayGetUInt( ia, i ), i ) @@ -175,33 +175,30 @@ def testMotion( self ) : with IECoreArnold.UniverseBlock( writable = True ) : - node = IECoreArnold.NodeAlgo.convert( [ m1, m2 ], [ -0.25, 0.25 ] ) + node = IECoreArnold.NodeAlgo.convert( [ m1, m2 ], -0.25, 0.25 ) vList = arnold.AiNodeGetArray( node, "vlist" ) - self.assertEqual( vList.contents.nelements, 4 ) - self.assertEqual( vList.contents.nkeys, 2 ) + self.assertEqual( arnold.AiArrayGetNumElements( vList.contents ), 4 ) + self.assertEqual( arnold.AiArrayGetNumKeys( vList.contents ), 2 ) nList = arnold.AiNodeGetArray( node, "nlist" ) - self.assertEqual( nList.contents.nelements, 4 ) - self.assertEqual( nList.contents.nkeys, 2 ) + self.assertEqual( arnold.AiArrayGetNumElements( nList.contents ), 4 ) + self.assertEqual( arnold.AiArrayGetNumKeys( nList.contents ), 2 ) for i in range( 0, 4 ) : - p = arnold.AiArrayGetPnt( vList, i ) + p = arnold.AiArrayGetVec( vList, i ) self.assertEqual( IECore.V3f( p.x, p.y, p.z ), m1["P"].data[i] ) - n = arnold.AiArrayGetPnt( nList, i ) + n = arnold.AiArrayGetVec( nList, i ) self.assertEqual( IECore.V3f( n.x, n.y, n.z ), m1["N"].data[i] ) for i in range( 4, 8 ) : - p = arnold.AiArrayGetPnt( vList, i ) + p = arnold.AiArrayGetVec( vList, i ) self.assertEqual( IECore.V3f( p.x, p.y, p.z ), m2["P"].data[i-4] ) - n = arnold.AiArrayGetPnt( nList, i ) + n = arnold.AiArrayGetVec( nList, i ) self.assertEqual( IECore.V3f( n.x, n.y, n.z ), m2["N"].data[i-4] ) - a = arnold.AiNodeGetArray( node, "deform_time_samples" ) - self.assertEqual( a.contents.nelements, 2 ) - self.assertEqual( a.contents.nkeys, 1 ) - self.assertEqual( arnold.AiArrayGetFlt( a, 0 ), -0.25 ) - self.assertEqual( arnold.AiArrayGetFlt( a, 1 ), 0.25 ) + self.assertEqual( arnold.AiNodeGetFlt( node, "motion_start" ), -0.25 ) + self.assertEqual( arnold.AiNodeGetFlt( node, "motion_end" ), 0.25 ) def testClashingPrimitiveVariables( self ) : # make sure that names of arnold built-in's can't be used as names for primitive variables @@ -238,10 +235,10 @@ def testPointTypePrimitiveVariables( self ) : with IECoreArnold.UniverseBlock( writable = True ) : node = IECoreArnold.NodeAlgo.convert( m ) p = arnold.AiNodeGetArray( node, "points" ) - self.assertEqual( p.contents.type, arnold.AI_TYPE_POINT ) + self.assertEqual( arnold.AiArrayGetType( p.contents ), arnold.AI_TYPE_VECTOR ) v = arnold.AiNodeGetArray( node, "vectors" ) - self.assertEqual( v.contents.type, arnold.AI_TYPE_VECTOR ) + self.assertEqual( arnold.AiArrayGetType( v.contents ), arnold.AI_TYPE_VECTOR ) def testBoolVectorPrimitiveVariables( self ) : @@ -256,7 +253,7 @@ def testBoolVectorPrimitiveVariables( self ) : n = IECoreArnold.NodeAlgo.convert( m ) a = arnold.AiNodeGetArray( n, "myBoolPrimVar" ) - self.assertEqual( a.contents.nelements, 4 ) + self.assertEqual( arnold.AiArrayGetNumElements( a.contents ), 4 ) self.assertEqual( arnold.AiArrayGetBool( a, 0 ), True ) self.assertEqual( arnold.AiArrayGetBool( a, 1 ), False ) self.assertEqual( arnold.AiArrayGetBool( a, 2 ), True ) diff --git a/contrib/IECoreArnold/test/IECoreArnold/OutputDriverTest.py b/contrib/IECoreArnold/test/IECoreArnold/OutputDriverTest.py index 60a9962b83..9c5e7ce16c 100644 --- a/contrib/IECoreArnold/test/IECoreArnold/OutputDriverTest.py +++ b/contrib/IECoreArnold/test/IECoreArnold/OutputDriverTest.py @@ -48,7 +48,7 @@ def testMergedDisplays( self ) : server = IECore.DisplayDriverServer( 1559 ) time.sleep( 2 ) - os.system( "kick -dw -dp contrib/IECoreArnold/test/IECoreArnold/data/assFiles/mergedDisplays.ass" ) + os.system( "kick -v 0 -dw -dp contrib/IECoreArnold/test/IECoreArnold/data/assFiles/mergedDisplays.ass" ) image = IECore.ImageDisplayDriver.removeStoredImage( "mergedImage" ) channelNames = image.keys() @@ -67,7 +67,7 @@ def testVectorAndPointDisplays( self ) : server = IECore.DisplayDriverServer( 1559 ) time.sleep( 2 ) - os.system( "kick -dw -dp contrib/IECoreArnold/test/IECoreArnold/data/assFiles/vectorAndPointDisplays.ass" ) + os.system( "kick -v 0 -dw -dp contrib/IECoreArnold/test/IECoreArnold/data/assFiles/vectorAndPointDisplays.ass" ) image = IECore.ImageDisplayDriver.removeStoredImage( "vectorAndPointImage" ) channelNames = image.keys() diff --git a/contrib/IECoreArnold/test/IECoreArnold/ParameterAlgoTest.py b/contrib/IECoreArnold/test/IECoreArnold/ParameterAlgoTest.py index 98b9a306b2..9f9be1b5a3 100644 --- a/contrib/IECoreArnold/test/IECoreArnold/ParameterAlgoTest.py +++ b/contrib/IECoreArnold/test/IECoreArnold/ParameterAlgoTest.py @@ -53,48 +53,48 @@ def testSetParameter( self ) : with IECoreArnold.UniverseBlock( writable = True ) : - n = arnold.AiNode( "standard" ) + n = arnold.AiNode( "standard_surface" ) - IECoreArnold.ParameterAlgo.setParameter( n, "Kd", IECore.FloatData( 0.25 ) ) - IECoreArnold.ParameterAlgo.setParameter( n, "aov_emission", IECore.StringData( "test" ) ) + IECoreArnold.ParameterAlgo.setParameter( n, "base", IECore.FloatData( 0.25 ) ) + IECoreArnold.ParameterAlgo.setParameter( n, "customString", IECore.StringData( "test" ) ) - self.assertEqual( arnold.AiNodeGetFlt( n, "Kd" ), 0.25 ) - self.assertEqual( arnold.AiNodeGetStr( n, "aov_emission" ), "test" ) + self.assertEqual( arnold.AiNodeGetFlt( n, "base" ), 0.25 ) + self.assertEqual( arnold.AiNodeGetStr( n, "customString" ), "test" ) def testGetParameter( self ) : with IECoreArnold.UniverseBlock( writable = True ) : - n = arnold.AiNode( "standard" ) + n = arnold.AiNode( "standard_surface" ) self.assertEqual( - IECoreArnold.ParameterAlgo.getParameter( n, "Kd" ), - IECore.FloatData( arnold.AiNodeGetFlt( n, "Kd" ) ) + IECoreArnold.ParameterAlgo.getParameter( n, "base" ), + IECore.FloatData( arnold.AiNodeGetFlt( n, "base" ) ) ) + IECore.FloatData( arnold.AiNodeSetStr( n, "name", "testString" ) ) self.assertEqual( - IECoreArnold.ParameterAlgo.getParameter( n, "aov_emission" ), - IECore.StringData( "emission" ), + IECoreArnold.ParameterAlgo.getParameter( n, "name" ), + IECore.StringData( "testString" ), ) def testDoubleData( self ) : with IECoreArnold.UniverseBlock( writable = True ) : - n = arnold.AiNode( "standard" ) + n = arnold.AiNode( "standard_surface" ) - IECoreArnold.ParameterAlgo.setParameter( n, "Kd", IECore.DoubleData( 0.25 ) ) - self.assertEqual( arnold.AiNodeGetFlt( n, "Kd" ), 0.25 ) + IECoreArnold.ParameterAlgo.setParameter( n, "base", IECore.DoubleData( 0.25 ) ) + self.assertEqual( arnold.AiNodeGetFlt( n, "base" ), 0.25 ) IECoreArnold.ParameterAlgo.setParameter( n, "customFloat", IECore.DoubleData( 0.25 ) ) self.assertEqual( arnold.AiNodeGetFlt( n, "customFloat" ), 0.25 ) IECoreArnold.ParameterAlgo.setParameter( n, "customMatrix", IECore.M44dData( IECore.M44d( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ) ) ) - m = arnold.AtMatrix() - arnold.AiNodeGetMatrix( n, "customMatrix", m ) + m = arnold.AiNodeGetMatrix( n, "customMatrix" ) self.assertEqual( - [ getattr( m, f[0] ) for f in m._fields_ ], - [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ], + [ list( i ) for i in m.data ], + [ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16] ], ) def testStringArray( self ) : @@ -105,9 +105,22 @@ def testStringArray( self ) : IECoreArnold.ParameterAlgo.setParameter( n, "trace_sets", IECore.StringVectorData( [ "a", "b" ] ) ) a = arnold.AiNodeGetArray( n, "trace_sets" ) - self.assertEqual( a.contents.nelements, 2 ) + self.assertEqual( arnold.AiArrayGetNumElements( a.contents ), 2 ) self.assertEqual( arnold.AiArrayGetStr( a, 0 ), "a" ) self.assertEqual( arnold.AiArrayGetStr( a, 1 ), "b" ) + def testVectorIntData( self ) : + + with IECoreArnold.UniverseBlock( writable = True ) : + + n = arnold.AiNode( "standard_surface" ) + + IECoreArnold.ParameterAlgo.setParameter( n, "customV2i", IECore.V2iData( IECore.V2i( 3, 4 ) ) ) + self.assertEqual( arnold.AiNodeGetVec2( n, "customV2i" ), arnold.AtVector2( 3, 4 ) ) + + IECoreArnold.ParameterAlgo.setParameter( n, "customV3i", IECore.V3iData( IECore.V3i( 3, 4, 5 ) ) ) + self.assertEqual( arnold.AiNodeGetVec( n, "customV3i" ), arnold.AtVector( 3, 4, 5 ) ) + + if __name__ == "__main__": unittest.main() diff --git a/contrib/IECoreArnold/test/IECoreArnold/PointsTest.py b/contrib/IECoreArnold/test/IECoreArnold/PointsTest.py index b2fa525fa8..f25c8c3eb7 100644 --- a/contrib/IECoreArnold/test/IECoreArnold/PointsTest.py +++ b/contrib/IECoreArnold/test/IECoreArnold/PointsTest.py @@ -106,9 +106,6 @@ def testDiskRendering( self ) : image = IECore.ImageDisplayDriver.removeStoredImage( "testHandle" ) del image["A"] - # raise blackPoint massively to remove possible watermark - IECore.Grade()( input = image, copyInput = False, blackPoint = IECore.Color3f( 0.9 ) ) - expectedImage = IECore.Reader.create( os.path.dirname( __file__ ) + "/data/pointsImages/points.tif" ).read() IECore.ImageWriter.create( image, "/tmp/test.tif" ).write() @@ -134,7 +131,7 @@ def testConstantArrayPrimitiveVariable( self ) : n = IECoreArnold.NodeAlgo.convert( p ) a = arnold.AiNodeGetArray( n, "myPrimVar" ) - self.assertEqual( a.contents.nelements, 10 ) + self.assertEqual( arnold.AiArrayGetNumElements( a.contents ), 10 ) for i in range( 0, 10 ) : self.assertEqual( arnold.AiArrayGetInt( a, i ), i ) @@ -161,7 +158,7 @@ def testVertexPrimitiveVariable( self ) : n = IECoreArnold.NodeAlgo.convert( p ) a = arnold.AiNodeGetArray( n, "myPrimVar" ) - self.assertEqual( a.contents.nelements, 10 ) + self.assertEqual( arnold.AiArrayGetNumElements( a.contents ), 10 ) for i in range( 0, 10 ) : self.assertEqual( arnold.AiArrayGetInt( a, i ), i ) @@ -193,28 +190,25 @@ def testMotion( self ) : with IECoreArnold.UniverseBlock( writable = True ) : - n = IECoreArnold.NodeAlgo.convert( [ p1, p2 ], [ -0.25, 0.25 ] ) + n = IECoreArnold.NodeAlgo.convert( [ p1, p2 ], -0.25, 0.25 ) a = arnold.AiNodeGetArray( n, "points" ) - self.assertEqual( a.contents.nelements, 10 ) - self.assertEqual( a.contents.nkeys, 2 ) + self.assertEqual( arnold.AiArrayGetNumElements( a.contents ), 10 ) + self.assertEqual( arnold.AiArrayGetNumKeys( a.contents ), 2 ) r = arnold.AiNodeGetArray( n, "radius" ) - self.assertEqual( a.contents.nelements, 10 ) - self.assertEqual( a.contents.nkeys, 2 ) + self.assertEqual( arnold.AiArrayGetNumElements( a.contents ), 10 ) + self.assertEqual( arnold.AiArrayGetNumKeys( a.contents ), 2 ) for i in range( 0, 10 ) : - self.assertEqual( arnold.AiArrayGetPnt( a, i ), arnold.AtPoint( 10 ) ) + self.assertEqual( arnold.AiArrayGetVec( a, i ), arnold.AtVector( 10 ) ) self.assertEqual( arnold.AiArrayGetFlt( r, i ), 0.5 ) for i in range( 11, 20 ) : - self.assertEqual( arnold.AiArrayGetPnt( a, i ), arnold.AtPoint( 20 ) ) + self.assertEqual( arnold.AiArrayGetVec( a, i ), arnold.AtVector( 20 ) ) self.assertEqual( arnold.AiArrayGetFlt( r, i ), 1 ) - a = arnold.AiNodeGetArray( n, "deform_time_samples" ) - self.assertEqual( a.contents.nelements, 2 ) - self.assertEqual( a.contents.nkeys, 1 ) - self.assertEqual( arnold.AiArrayGetFlt( a, 0 ), -0.25 ) - self.assertEqual( arnold.AiArrayGetFlt( a, 1 ), 0.25 ) + self.assertEqual( arnold.AiNodeGetFlt( n, "motion_start" ), -0.25 ) + self.assertEqual( arnold.AiNodeGetFlt( n, "motion_end" ), 0.25 ) if __name__ == "__main__": unittest.main() diff --git a/contrib/IECoreArnold/test/IECoreArnold/ProceduralDSOTest.py b/contrib/IECoreArnold/test/IECoreArnold/ProceduralDSOTest.py index 0ac2758efd..e36885b165 100644 --- a/contrib/IECoreArnold/test/IECoreArnold/ProceduralDSOTest.py +++ b/contrib/IECoreArnold/test/IECoreArnold/ProceduralDSOTest.py @@ -44,7 +44,7 @@ class ProceduralDSOTest( unittest.TestCase ) : def test( self ) : - os.system( "kick -dw -dp contrib/IECoreArnold/test/IECoreArnold/data/assFiles/proceduralDSO.ass" ) + os.system( "kick -v 0 -dw -dp contrib/IECoreArnold/test/IECoreArnold/data/assFiles/proceduralDSO.ass" ) image = IECore.EXRImageReader( "testProceduralDSO.exr" ).read() evaluator = IECore.ImagePrimitiveEvaluator( image ) diff --git a/contrib/IECoreArnold/test/IECoreArnold/ProceduralTest.py b/contrib/IECoreArnold/test/IECoreArnold/ProceduralTest.py index f5ae55cf93..25c72ffdd0 100644 --- a/contrib/IECoreArnold/test/IECoreArnold/ProceduralTest.py +++ b/contrib/IECoreArnold/test/IECoreArnold/ProceduralTest.py @@ -186,9 +186,9 @@ def testProceduralInheritsShader( self ) : e = IECore.ImagePrimitiveEvaluator( i ) r = e.createResult() self.assertEqual( e.pointAtUV( IECore.V2f( 0.5 ), r ), True ) - self.assertEqual( r.floatPrimVar( e.R() ), 0 ) - self.assertEqual( r.floatPrimVar( e.G() ), 1 ) - self.assertEqual( r.floatPrimVar( e.B() ), 0 ) + self.assertAlmostEqual( r.floatPrimVar( e.R() ), 0, 6 ) + self.assertAlmostEqual( r.floatPrimVar( e.G() ), 1, 6 ) + self.assertAlmostEqual( r.floatPrimVar( e.B() ), 0, 6 ) def testEmptyProceduralIsIgnored( self ) : @@ -224,27 +224,5 @@ def hash( self ): self.failIf( "ignoring parameter max" in self.__arnoldMessages ) - def testNoBound( self ) : - - r = IECoreArnold.Renderer( "/tmp/test.ass" ) - - with IECore.WorldBlock( r ) : - - r.procedural( - r.ExternalProcedural( - "test.so", - r.Procedural.noBound, - {} - ) - ) - - l = "".join( open( "/tmp/test.ass" ).readlines() ) - - self.assertTrue( "procedural" in l ) - self.assertFalse( "inf" in l ) - self.assertFalse( re.search( r"\bmin\b", l ) ) - self.assertFalse( re.search( r"\bmax\b", l ) ) - self.assertTrue( "load_at_init" in l ) - if __name__ == "__main__": unittest.main() diff --git a/contrib/IECoreArnold/test/IECoreArnold/RendererTest.py b/contrib/IECoreArnold/test/IECoreArnold/RendererTest.py index 63c1bb7df9..c64e0861bd 100644 --- a/contrib/IECoreArnold/test/IECoreArnold/RendererTest.py +++ b/contrib/IECoreArnold/test/IECoreArnold/RendererTest.py @@ -68,9 +68,9 @@ def testOptions( self ) : self.assertEqual( r.getOption( "ai:AA_samples" ), IECore.IntData( 11 ) ) # check we can set an already existing float - self.assertEqual( r.getOption( "ai:auto_transparency_threshold" ), IECore.FloatData( .99 ) ) - r.setOption( "ai:auto_transparency_threshold", IECore.FloatData( .9 ) ) - self.assertEqual( r.getOption( "ai:auto_transparency_threshold" ), IECore.FloatData( .9 ) ) + self.assertEqual( r.getOption( "ai:texture_max_sharpen" ), IECore.FloatData( 1.5 ) ) + r.setOption( "ai:texture_max_sharpen", IECore.FloatData( .9 ) ) + self.assertEqual( r.getOption( "ai:texture_max_sharpen" ), IECore.FloatData( .9 ) ) # check tbat trying to set nonexistent options yields a message m = IECore.CapturingMessageHandler() @@ -166,7 +166,7 @@ def testShader( self ) : with IECore.WorldBlock( r ) : - r.shader( "surface", "standard", { "emission" : 1.0, "emission_color" : IECore.Color3f( 1, 0, 0 ) } ) + r.shader( "surface", "standard_surface", { "emission" : 1.0, "emission_color" : IECore.Color3f( 1, 0, 0 ) } ) r.sphere( 1, -1, 1, 360, {} ) image = IECore.ImageDisplayDriver.removeStoredImage( "test" ) @@ -187,7 +187,7 @@ def testReferenceExistingShader( self ) : with IECore.WorldBlock( r ) : - shader = arnold.AiNode( "standard" ) + shader = arnold.AiNode( "standard_surface" ) arnold.AiNodeSetStr( shader, "name", "red_shader" ) arnold.AiNodeSetFlt( shader, "emission", 1 ) arnold.AiNodeSetRGB( shader, "emission_color", 1, 0, 0 ) @@ -487,9 +487,6 @@ def performCurvesTest( self, curvesPrimitive, expectedImage ) : image = IECore.ImageDisplayDriver.removeStoredImage( "test" ) del image["A"] - # raise blackPoint massively to remove possible watermark - IECore.Grade()( input = image, copyInput = False, blackPoint = IECore.Color3f( 0.9 ) ) - expectedImage = IECore.Reader.create( expectedImage ).read() self.assertEqual( IECore.ImageDiffOp()( imageA=image, imageB=expectedImage, maxError=0.01 ), IECore.BoolData( False ) ) @@ -541,10 +538,12 @@ def testVisibilityAttributes( self ) : r = IECoreArnold.Renderer() self.assertEqual( r.getAttribute( "ai:visibility:camera" ), IECore.BoolData( True ) ) self.assertEqual( r.getAttribute( "ai:visibility:shadow" ), IECore.BoolData( True ) ) - self.assertEqual( r.getAttribute( "ai:visibility:reflected" ), IECore.BoolData( True ) ) - self.assertEqual( r.getAttribute( "ai:visibility:refracted" ), IECore.BoolData( True ) ) - self.assertEqual( r.getAttribute( "ai:visibility:diffuse" ), IECore.BoolData( True ) ) - self.assertEqual( r.getAttribute( "ai:visibility:glossy" ), IECore.BoolData( True ) ) + self.assertEqual( r.getAttribute( "ai:visibility:diffuseReflect" ), IECore.BoolData( True ) ) + self.assertEqual( r.getAttribute( "ai:visibility:specularReflect" ), IECore.BoolData( True ) ) + self.assertEqual( r.getAttribute( "ai:visibility:diffuseTransmit" ), IECore.BoolData( True ) ) + self.assertEqual( r.getAttribute( "ai:visibility:specularTransmit" ), IECore.BoolData( True ) ) + self.assertEqual( r.getAttribute( "ai:visibility:volume" ), IECore.BoolData( True ) ) + self.assertEqual( r.getAttribute( "ai:visibility:subsurface" ), IECore.BoolData( True ) ) r.setAttribute( "ai:visibility:shadow", IECore.BoolData( False ) ) self.assertEqual( r.getAttribute( "ai:visibility:shadow" ), IECore.BoolData( False ) ) @@ -616,7 +615,7 @@ def testShapeAttributes( self ) : shapes = self.__allNodes( type = arnold.AI_NODE_SHAPE ) self.assertEqual( len( shapes ), 1 ) - self.assertEqual( arnold.AiNodeGetInt( shapes[0], "subdiv_iterations" ), 10 ) + self.assertEqual( arnold.AiNodeGetByte( shapes[0], "subdiv_iterations" ), 10 ) def testEnumAttributes( self ) : @@ -657,7 +656,7 @@ def testShaderConnections( self ) : r.concatTransform( IECore.M44f.createTranslated( IECore.V3f( 0, 0, -5 ) ) ) r.shader( "shader", "flat", { "color" : IECore.Color3f( 1, 0, 0 ), "__handle" : "myInputShader" } ) - r.shader( "surface", "standard", { "emission" : 1.0, "emission_color" : "link:myInputShader" } ) + r.shader( "surface", "standard_surface", { "emission" : 1.0, "emission_color" : "link:myInputShader" } ) mesh = IECore.MeshPrimitive.createPlane( IECore.Box2f( IECore.V2f( -1 ), IECore.V2f( 1 ) ) ) mesh.render( r ) @@ -684,7 +683,7 @@ def testMissingShaderConnectionWarnings( self ) : m = IECore.CapturingMessageHandler() with m : r.shader( "shader", "flat", { "color" : IECore.Color3f( 1, 0, 0 ), "__handle" : "myInputShader" } ) - r.shader( "surface", "standard", { "emission" : 1.0, "emission_color" : "link:oopsWrongOne" } ) + r.shader( "surface", "standard_surface", { "emission" : 1.0, "emission_color" : "link:oopsWrongOne" } ) self.assertEqual( len( m.messages ), 1 ) self.assertEqual( m.messages[0].level, IECore.Msg.Level.Warning ) @@ -698,11 +697,11 @@ def testLight( self ) : with IECore.WorldBlock( r ) : - r.light( "point_light", "handle", { "intensity" : 1, "color" : IECore.Color3f( 1, 0.5, 0.25 ) } ) + r.light( "point_light", "handle", { "intensity" : 1.0, "color" : IECore.Color3f( 1, 0.5, 0.25 ) } ) r.concatTransform( IECore.M44f.createTranslated( IECore.V3f( 0, 0, -1 ) ) ) - r.shader( "surface", "standard", {} ) + r.shader( "surface", "standard_surface", {} ) mesh = IECore.MeshPrimitive.createPlane( IECore.Box2f( IECore.V2f( -1 ), IECore.V2f( 1 ) ) ) mesh.render( r ) @@ -724,7 +723,7 @@ def testExternalProcedural( self ) : r.procedural( r.ExternalProcedural( - "test.so", + "volume", IECore.Box3f( IECore.V3f( 1, 2, 3 ), IECore.V3f( 4, 5, 6 ) @@ -740,10 +739,7 @@ def testExternalProcedural( self ) : ass = "".join( file( self.__assFileName ).readlines() ) - self.assertTrue( "procedural" in ass ) - self.assertTrue( "min 1 2 3" in ass ) - self.assertTrue( "max 4 5 6" in ass ) - self.assertTrue( "dso \"test.so\"" in ass ) + self.assertTrue( "volume" in ass ) self.assertTrue( "declare stringParm constant STRING" in ass ) self.assertTrue( "declare floatParm constant FLOAT" in ass ) self.assertTrue( "declare intParm constant INT" in ass ) @@ -763,7 +759,7 @@ def testPixelAspectRatio( self ) : pass ass = "".join( file( self.__assFileName ).readlines() ) - self.assertTrue( "aspect_ratio 0.5" in ass ) + self.assertTrue( "pixel_aspect_ratio 0.5" in ass ) def testLightPrefixes( self ) : @@ -786,7 +782,7 @@ def testDeformationMotionBlur( self ) : r = IECoreArnold.Renderer() r.display( "test", "ieDisplay", "rgba", { "driverType" : "ImageDisplayDriver", "handle" : "test" } ) - r.setOption( "ai:AA_samples", IECore.IntData( 10 ) ) + r.setOption( "ai:AA_samples", IECore.IntData( 20 ) ) r.camera( "main", { "resolution" : IECore.V2i( 128, 128 ), "shutter" : IECore.V2f( 0, 1 ) } ) @@ -814,7 +810,7 @@ def testTransformationMotionBlur( self ) : r = IECoreArnold.Renderer() r.display( "test", "ieDisplay", "rgba", { "driverType" : "ImageDisplayDriver", "handle" : "test" } ) - r.setOption( "ai:AA_samples", IECore.IntData( 10 ) ) + r.setOption( "ai:AA_samples", IECore.IntData( 20 ) ) r.camera( "main", { "resolution" : IECore.V2i( 128, 128 ), "shutter" : IECore.V2f( 0, 1 ) } ) @@ -838,18 +834,57 @@ def testTransformationMotionBlur( self ) : e.pointAtUV( IECore.V2f( 0.5 ), result ) self.assertAlmostEqual( result.floatPrimVar( e.A() ), 0.5, 2 ) + def testNonUniformMotionBlur( self ) : + + r = IECoreArnold.Renderer() + + r.display( "test", "ieDisplay", "rgba", { "driverType" : "ImageDisplayDriver", "handle" : "test" } ) + r.setOption( "ai:AA_samples", IECore.IntData( 20 ) ) + + r.camera( "main", { "resolution" : IECore.V2i( 128, 128 ), "shutter" : IECore.V2f( 0, 1 ) } ) + + with IECore.WorldBlock( r ) : + + r.concatTransform( IECore.M44f.createTranslated( IECore.V3f( 0, 0, -5 ) ) ) + + # A motion block that has slightly non-uniform sampling, but not enough to notice + # We should allow it, since the user won't notice that Arnold is ignoring the non-uniformity + with IECore.MotionBlock( r, [ 0, 0.3333, 0.6666, 1 ] ) : + r.concatTransform( IECore.M44f.createTranslated( IECore.V3f( -1, 0, 0 ) ) ) + r.concatTransform( IECore.M44f.createTranslated( IECore.V3f( -0.3333333333, 0, 0 ) ) ) + r.concatTransform( IECore.M44f.createTranslated( IECore.V3f( 0.33333333333, 0, 0 ) ) ) + r.concatTransform( IECore.M44f.createTranslated( IECore.V3f( 1, 0, 0 ) ) ) + + with self.assertRaises( RuntimeError ): + # This block is actually non-uniform, and won't render correctly, so we should fail + with IECore.MotionBlock( r, [ 0, 0.333, 0.666, 2 ] ): + pass + + mesh = IECore.MeshPrimitive.createPlane( IECore.Box2f( IECore.V2f( -0.5 ), IECore.V2f( 0.5 ) ) ) + mesh.render( r ) + + + image = IECore.ImageDisplayDriver.removeStoredImage( "test" ) + e = IECore.PrimitiveEvaluator.create( image ) + result = e.createResult() + + e.pointAtUV( IECore.V2f( 0.5 ), result ) + self.assertAlmostEqual( result.floatPrimVar( e.A() ), 0.5, 2 ) + def testProcedural( self ) : r = IECoreArnold.Renderer( "/tmp/test.ass" ) with IECore.WorldBlock( r ) : + # In Arnold 5, external procedurals register node types that look just like the built-in + # ones. So we need to be able to use ExternalProcedural to create an arbitrary node type, + # instead of passing in a filename. Test with a volume, because this node type exists by default. r.procedural( r.ExternalProcedural( - "someVolumeThing.so", + "volume", IECore.Box3f( IECore.V3f( -1, -2, -3 ), IECore.V3f( 4, 5, 6 ) ), { - "ai:nodeType" : "volume", "testFloat" : 0.5 } ) @@ -858,9 +893,6 @@ def testProcedural( self ) : volume = self.__allNodes( type = arnold.AI_NODE_SHAPE )[-1] self.assertEqual( arnold.AiNodeEntryGetName( arnold.AiNodeGetNodeEntry( volume ) ), "volume" ) - self.assertEqual( arnold.AiNodeGetPnt( volume, "min" ), arnold.AtPoint( -1, -2, -3 ) ) - self.assertEqual( arnold.AiNodeGetPnt( volume, "max" ), arnold.AtPoint( 4, 5, 6 ) ) - self.assertEqual( arnold.AiNodeGetStr( volume, "dso" ), "someVolumeThing.so" ) self.assertEqual( arnold.AiNodeGetFlt( volume, "testFloat" ), 0.5 ) def tearDown( self ) : diff --git a/contrib/IECoreArnold/test/IECoreArnold/SphereAlgoTest.py b/contrib/IECoreArnold/test/IECoreArnold/SphereAlgoTest.py index 56d7b94112..34a890b726 100644 --- a/contrib/IECoreArnold/test/IECoreArnold/SphereAlgoTest.py +++ b/contrib/IECoreArnold/test/IECoreArnold/SphereAlgoTest.py @@ -56,16 +56,15 @@ def testConvertWithMotion( self ) : with IECoreArnold.UniverseBlock( writable = True ) : - n = IECoreArnold.NodeAlgo.convert( s, [ 0, 1 ] ) + n = IECoreArnold.NodeAlgo.convert( s, 0, 1 ) self.assertEqual( arnold.AiNodeEntryGetName( arnold.AiNodeGetNodeEntry( n ) ), "sphere" ) a = arnold.AiNodeGetArray( n, "radius" ) self.assertEqual( arnold.AiArrayGetFlt( a, 0 ), 0.25 ) self.assertEqual( arnold.AiArrayGetFlt( a, 1 ), 0.5 ) - a = arnold.AiNodeGetArray( n, "deform_time_samples" ) - self.assertEqual( arnold.AiArrayGetFlt( a, 0 ), 0 ) - self.assertEqual( arnold.AiArrayGetFlt( a, 1 ), 1 ) + self.assertEqual( arnold.AiNodeGetFlt( n, "motion_start" ), 0 ) + self.assertEqual( arnold.AiNodeGetFlt( n, "motion_end" ), 1 ) def testPrimitiveVariables( self ) : @@ -82,18 +81,18 @@ def testPrimitiveVariables( self ) : n = IECoreArnold.NodeAlgo.convert( s ) self.assertEqual( arnold.AiNodeGetVec( n, "v" ), arnold.AtVector( 1, 2, 3 ) ) - self.assertEqual( arnold.AiNodeGetRGB( n, "c" ), arnold.AtColor( 1, 2, 3 ) ) + self.assertEqual( arnold.AiNodeGetRGB( n, "c" ), arnold.AtRGB( 1, 2, 3 ) ) self.assertEqual( arnold.AiNodeGetStr( n, "s" ), "test" ) self.assertEqual( arnold.AiNodeGetInt( n, "i" ), 11 ) self.assertEqual( arnold.AiNodeGetBool( n, "b" ), True ) self.assertEqual( arnold.AiNodeGetFlt( n, "f" ), 2.5 ) - m = arnold.AtMatrix() - arnold.AiNodeGetMatrix( n, "m", m ) + m = arnold.AiNodeGetMatrix( n, "m" ) self.assertEqual( - [ getattr( m, f[0] ) for f in m._fields_ ], - [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ], + [ list( i ) for i in m.data ], + [ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16] ], ) + if __name__ == "__main__": unittest.main() diff --git a/contrib/IECoreArnold/test/IECoreArnold/UniverseBlockTest.py b/contrib/IECoreArnold/test/IECoreArnold/UniverseBlockTest.py index 8dc082e7b3..532f9cf8ed 100644 --- a/contrib/IECoreArnold/test/IECoreArnold/UniverseBlockTest.py +++ b/contrib/IECoreArnold/test/IECoreArnold/UniverseBlockTest.py @@ -91,17 +91,18 @@ def testMetadataLoading( self ) : e = arnold.AiNodeEntryLookUp( "options" ) - s = ctypes.c_char_p() + s = arnold.AtStringReturn() i = ctypes.c_int() + arnold.AiMetaDataGetStr( e, "", "cortex.testString", s ) - self.assertEqual( s.value, "test" ) + self.assertEqual( arnold.AtStringToStr( s ), "test" ) arnold.AiMetaDataGetInt( e, "", "cortex.testInt", i ) self.assertEqual( i.value, 25 ) arnold.AiMetaDataGetStr( e, "AA_samples", "cortex.testString", s ) - self.assertEqual( s.value, "test2" ) + self.assertEqual( arnold.AtStringToStr( s ), "test2" ) arnold.AiMetaDataGetInt( e, "AA_samples", "cortex.testInt", i ) self.assertEqual( i.value, 12 ) diff --git a/contrib/IECoreArnold/test/IECoreArnold/data/assFiles/proceduralDSO.ass b/contrib/IECoreArnold/test/IECoreArnold/data/assFiles/proceduralDSO.ass index a92b9a5665..397e905eef 100644 --- a/contrib/IECoreArnold/test/IECoreArnold/data/assFiles/proceduralDSO.ass +++ b/contrib/IECoreArnold/test/IECoreArnold/data/assFiles/proceduralDSO.ass @@ -24,17 +24,8 @@ persp_camera name camera } -procedural +ieProcedural { - - dso contrib/IECoreArnold/test/IECoreArnold/plugins/ieProcedural.so - min -100 -100 -100 - max 100 100 100 - - declare className constant STRING - declare classVersion constant INT - declare parameterValues constant ARRAY STRING - matrix 1 0 0 0 0 1 0 0 0 0 1 0 0 0 -20 1 className "read" diff --git a/contrib/IECoreArnold/test/IECoreArnold/data/curveImages/bSpline.exr b/contrib/IECoreArnold/test/IECoreArnold/data/curveImages/bSpline.exr index 56c02244cc..b229dd26ab 100644 Binary files a/contrib/IECoreArnold/test/IECoreArnold/data/curveImages/bSpline.exr and b/contrib/IECoreArnold/test/IECoreArnold/data/curveImages/bSpline.exr differ diff --git a/contrib/IECoreArnold/test/IECoreArnold/data/curveImages/bezier.exr b/contrib/IECoreArnold/test/IECoreArnold/data/curveImages/bezier.exr index ea675b78d4..036f125b96 100644 Binary files a/contrib/IECoreArnold/test/IECoreArnold/data/curveImages/bezier.exr and b/contrib/IECoreArnold/test/IECoreArnold/data/curveImages/bezier.exr differ diff --git a/contrib/IECoreArnold/test/IECoreArnold/data/pointsImages/points.tif b/contrib/IECoreArnold/test/IECoreArnold/data/pointsImages/points.tif index d84412347e..dc2967a30d 100644 Binary files a/contrib/IECoreArnold/test/IECoreArnold/data/pointsImages/points.tif and b/contrib/IECoreArnold/test/IECoreArnold/data/pointsImages/points.tif differ