Skip to content

Commit 7021953

Browse files
authored
Merge pull request #1536 from lucienfostier/nukeLiveSceneAttribute
Nuke live scene attribute
2 parents 37e1fe5 + 1bc1de8 commit 7021953

7 files changed

Lines changed: 338 additions & 0 deletions

File tree

include/IECoreNuke/Convert.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
#include "DDImage/Box.h"
4343
#include "DDImage/Box3.h"
44+
#include "DDImage/Matrix3.h"
4445
#include "DDImage/Matrix4.h"
4546
#include "DDImage/Vector2.h"
4647
#include "DDImage/Vector3.h"
@@ -119,6 +120,12 @@ IECORENUKE_API Imath::Color4f convert( const DD::Image::Vector4 &from );
119120
template<>
120121
IECORENUKE_API Imath::V3d convert( const DD::Image::Vector4 &from );
121122

123+
template<>
124+
IECORENUKE_API Imath::M33f convert( const DD::Image::Matrix3 &from );
125+
126+
template<>
127+
IECORENUKE_API Imath::M33d convert( const DD::Image::Matrix3 &from );
128+
122129
template<>
123130
IECORENUKE_API Imath::M44f convert( const DD::Image::Matrix4 &from );
124131

include/IECoreNuke/ToNukeGeometryConverter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,11 @@
3737

3838
#include "IECoreNuke/ToNukeConverter.h"
3939

40+
#include "IECore/CompoundObject.h"
4041
#include "IECore/NumericParameter.h"
4142
#include "IECore/Object.h"
4243
#include "IECore/SimpleTypedParameter.h"
44+
#include "IECore/TypedObjectParameter.h"
4345

4446
#include "DDImage/GeometryList.h"
4547

@@ -99,6 +101,7 @@ class IECORENUKE_API ToNukeGeometryConverter : public ToNukeConverter
99101

100102
IECore::IntParameterPtr m_objIndexParameter;
101103
IECore::StringParameterPtr m_pathParameter;
104+
IECore::CompoundObjectParameterPtr m_attributesParameter;
102105

103106
};
104107

src/IECoreNuke/Convert.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,34 @@ Imath::Color4f convert( const DD::Image::Vector4 &from )
127127
return Imath::Color4f( from.x, from.y, from.z, from.w );
128128
}
129129

130+
template<>
131+
Imath::M33f convert( const DD::Image::Matrix3 &from )
132+
{
133+
Imath::M33f result;
134+
for( unsigned int i=0; i<3; i++ )
135+
{
136+
for( unsigned int j=0; j<3; j++ )
137+
{
138+
result[j][i] = from[j][i];
139+
}
140+
}
141+
return result;
142+
}
143+
144+
template<>
145+
Imath::M33d convert( const DD::Image::Matrix3 &from )
146+
{
147+
Imath::M33d result;
148+
for( unsigned int i=0; i<3; i++ )
149+
{
150+
for( unsigned int j=0; j<3; j++ )
151+
{
152+
result[j][i] = from[j][i];
153+
}
154+
}
155+
return result;
156+
}
157+
130158
template<>
131159
Imath::M44f convert( const DD::Image::Matrix4 &from )
132160
{

src/IECoreNuke/LiveScene.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444

4545
#include "IECore/Exception.h"
4646
#include "IECore/NullObject.h"
47+
#include "IECore/SimpleTypedData.h"
4748
#include "IECore/TransformationMatrixData.h"
4849

4950
#include "OpenEXR/OpenEXRConfig.h"
@@ -81,6 +82,38 @@ IECore::TransformationMatrixd convertTransformMatrix( DD::Image::Matrix4& from )
8182

8283
tbb::recursive_mutex g_mutex;
8384

85+
IECore::ConstObjectPtr convertAttribute( const DD::Image::Attribute *attribute )
86+
{
87+
switch( attribute->type() )
88+
{
89+
case DD::Image::FLOAT_ATTRIB :
90+
return new IECore::FloatData( attribute->flt( 0 ) );
91+
case DD::Image::INT_ATTRIB :
92+
return new IECore::IntData( attribute->integer( 0 ) );
93+
case DD::Image::STD_STRING_ATTRIB :
94+
return new IECore::StringData( attribute->stdstring( 0 ) );
95+
case DD::Image::STRING_ATTRIB :
96+
{
97+
const char *s = attribute->string( 0 );
98+
return new IECore::StringData( s ? s : "" );
99+
}
100+
case DD::Image::VECTOR2_ATTRIB :
101+
return new IECore::V2fData( IECore::convert<Imath::V2f>( attribute->vector2( 0 ) ) );
102+
case DD::Image::VECTOR3_ATTRIB :
103+
return new IECore::V3fData( IECore::convert<Imath::V3f>( attribute->vector3( 0 ) ) );
104+
case DD::Image::NORMAL_ATTRIB :
105+
return new IECore::V3fData( IECore::convert<Imath::V3f>( attribute->normal( 0 ) ) );
106+
case DD::Image::VECTOR4_ATTRIB :
107+
return new IECore::Color4fData( IECore::convert<Imath::Color4f>( attribute->vector4( 0 ) ) );
108+
case DD::Image::MATRIX3_ATTRIB :
109+
return new IECore::M33fData( IECore::convert<Imath::M33f>( attribute->matrix3( 0 ) ) );
110+
case DD::Image::MATRIX4_ATTRIB :
111+
return new IECore::M44fData( IECore::convert<Imath::M44f>( attribute->matrix4( 0 ) ) );
112+
default :
113+
return nullptr;
114+
}
115+
}
116+
84117
LiveScene::LiveSceneGeometryCache &cachedGeometryListMap()
85118
{
86119
static LiveScene::LiveSceneGeometryCache *cache = new LiveScene::LiveSceneGeometryCache();
@@ -424,15 +457,85 @@ void LiveScene::writeTransform( const Data *transform, double time )
424457

425458
bool LiveScene::hasAttribute( const Name &name ) const
426459
{
460+
const unsigned numObjects = objectNum();
461+
for( unsigned i = 0; i < numObjects; ++i )
462+
{
463+
if( m_pathMatcher.match( geoInfoPath( i ) ) != IECore::PathMatcher::ExactMatch )
464+
{
465+
continue;
466+
}
467+
auto geoInfo = object( i );
468+
if( !geoInfo )
469+
{
470+
return false;
471+
}
472+
// we only support Group_Object because they are only one that makes sense to match to IECoreScene Attributes
473+
// other type of attributes are more akin to PrimitiveVariables
474+
// so we could consider adding support for Group_Primitive/Vertex and Point as such.
475+
auto attr = geoInfo->get_group_attribute( GroupType::Group_Object, name.c_str() );
476+
return attr && attr->size() > 0;
477+
}
427478
return false;
428479
}
429480

430481
void LiveScene::attributeNames( NameList &attrs ) const
431482
{
483+
attrs.clear();
484+
const unsigned numObjects = objectNum();
485+
for( unsigned i = 0; i < numObjects; ++i )
486+
{
487+
if( m_pathMatcher.match( geoInfoPath( i ) ) != IECore::PathMatcher::ExactMatch )
488+
{
489+
continue;
490+
}
491+
auto geoInfo = object( i );
492+
if( !geoInfo )
493+
{
494+
return;
495+
}
496+
const int count = geoInfo->get_attribcontext_count();
497+
for( int j = 0; j < count; ++j )
498+
{
499+
auto context = geoInfo->get_attribcontext( j );
500+
// we only support Group_Object because they are only one that makes sense to match to IECoreScene Attributes
501+
// other type of attributes are more akin to PrimitiveVariables
502+
// so we could consider adding support for Group_Primitive/Vertex and Point as such.
503+
if( context && !context->empty() && context->group == GroupType::Group_Object && context->name )
504+
{
505+
attrs.push_back( context->name );
506+
}
507+
}
508+
return;
509+
}
432510
}
433511

434512
ConstObjectPtr LiveScene::readAttribute( const Name &name, double time ) const
435513
{
514+
const unsigned numObjects = objectNum( &time );
515+
for( unsigned i = 0; i < numObjects; ++i )
516+
{
517+
if( m_pathMatcher.match( geoInfoPath( i ) ) != IECore::PathMatcher::ExactMatch )
518+
{
519+
continue;
520+
}
521+
auto geoInfo = object( i, &time );
522+
if( !geoInfo )
523+
{
524+
return IECore::NullObject::defaultNullObject();
525+
}
526+
// we only support Group_Object because they are only one that makes sense to match to IECoreScene Attributes
527+
// other type of attributes are more akin to PrimitiveVariables
528+
// so we could consider adding support for Group_Primitive/Vertex and Point as such.
529+
auto attr = geoInfo->get_group_attribute( GroupType::Group_Object, name.c_str() );
530+
if( attr && attr->size() > 0 )
531+
{
532+
if( auto converted = convertAttribute( attr ) )
533+
{
534+
return converted;
535+
}
536+
}
537+
return IECore::NullObject::defaultNullObject();
538+
}
436539
return IECore::NullObject::defaultNullObject();
437540
}
438541

src/IECoreNuke/SceneCacheReader.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
#include "IECoreNuke/Hash.h"
3939
#include "IECoreNuke/ToNukeGeometryConverter.h"
4040

41+
#include "IECore/CompoundObject.h"
42+
4143
#include "IECoreGL/BoxPrimitive.h"
4244
#include "IECoreGL/Camera.h"
4345
#include "IECoreGL/Exception.h"
@@ -1094,6 +1096,18 @@ void SceneCacheReader::loadPrimitive( DD::Image::GeometryList &out, const std::s
10941096
if (converter)
10951097
{
10961098
converter->parameters()->parameter<IECore::StringParameter>( "path" )->setValue( new IECore::StringData( itemPath ) );
1099+
1100+
IECore::CompoundObjectPtr sceneAttributes = new IECore::CompoundObject();
1101+
IECoreScene::SceneInterface::NameList attrNames;
1102+
sceneInterface->attributeNames( attrNames );
1103+
for( const auto &attrName : attrNames )
1104+
{
1105+
// Safe to cast away const as the CompoundObject is only used to pass
1106+
// attribute values through to the converter, which only reads them.
1107+
sceneAttributes->members()[attrName] = boost::const_pointer_cast<IECore::Object>( sceneInterface->readAttribute( attrName, time ) );
1108+
}
1109+
converter->parameters()->parameter<IECore::CompoundObjectParameter>( "attributes" )->setValue( sceneAttributes );
1110+
10971111
converter->convert( out );
10981112
// store the world matrix to apply in geometry_engine because
10991113
// somewhere after the create_geometry nuke reset the matrix in the SourceGeo base class.

src/IECoreNuke/ToNukeGeometryConverter.cpp

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,124 @@
3333
//////////////////////////////////////////////////////////////////////////
3434

3535
#include "IECoreNuke/ToNukeGeometryConverter.h"
36+
#include "IECoreNuke/Convert.h"
3637
#include "IECoreNuke/LiveScene.h"
3738

3839
#include "IECore/CompoundData.h"
40+
#include "IECore/MessageHandler.h"
41+
#include "IECore/CompoundObject.h"
3942
#include "IECore/CompoundParameter.h"
43+
#include "IECore/SimpleTypedData.h"
4044

4145
#include <cassert>
4246

47+
#include "boost/format.hpp"
48+
4349
using namespace IECoreNuke;
4450
using namespace IECore;
4551
using namespace DD::Image;
4652

53+
namespace
54+
{
55+
56+
void writeAttribute( DD::Image::GeometryList &geoList, int objIndex, const char *name, const IECore::Object *value )
57+
{
58+
switch( value->typeId() )
59+
{
60+
case IECore::FloatDataTypeId :
61+
{
62+
auto attr = geoList.writable_attribute( objIndex, GroupType::Group_Object, name, AttribType::FLOAT_ATTRIB );
63+
attr->flt() = static_cast<const IECore::FloatData *>( value )->readable();
64+
break;
65+
}
66+
case IECore::IntDataTypeId :
67+
{
68+
auto attr = geoList.writable_attribute( objIndex, GroupType::Group_Object, name, AttribType::INT_ATTRIB );
69+
attr->integer() = static_cast<const IECore::IntData *>( value )->readable();
70+
break;
71+
}
72+
case IECore::BoolDataTypeId :
73+
{
74+
auto attr = geoList.writable_attribute( objIndex, GroupType::Group_Object, name, AttribType::INT_ATTRIB );
75+
attr->integer() = static_cast<const IECore::BoolData *>( value )->readable() ? 1 : 0;
76+
break;
77+
}
78+
case IECore::StringDataTypeId :
79+
{
80+
auto attr = geoList.writable_attribute( objIndex, GroupType::Group_Object, name, AttribType::STD_STRING_ATTRIB );
81+
attr->stdstring() = static_cast<const IECore::StringData *>( value )->readable();
82+
break;
83+
}
84+
case IECore::V2fDataTypeId :
85+
{
86+
auto attr = geoList.writable_attribute( objIndex, GroupType::Group_Object, name, AttribType::VECTOR2_ATTRIB );
87+
const auto &v = static_cast<const IECore::V2fData *>( value )->readable();
88+
attr->vector2() = DD::Image::Vector2( v.x, v.y );
89+
break;
90+
}
91+
case IECore::V3fDataTypeId :
92+
{
93+
auto attr = geoList.writable_attribute( objIndex, GroupType::Group_Object, name, AttribType::VECTOR3_ATTRIB );
94+
attr->vector3() = IECore::convert<DD::Image::Vector3>( static_cast<const IECore::V3fData *>( value )->readable() );
95+
break;
96+
}
97+
case IECore::Color4fDataTypeId :
98+
{
99+
auto attr = geoList.writable_attribute( objIndex, GroupType::Group_Object, name, AttribType::VECTOR4_ATTRIB );
100+
const auto &c = static_cast<const IECore::Color4fData *>( value )->readable();
101+
attr->vector4() = DD::Image::Vector4( c.r, c.g, c.b, c.a );
102+
break;
103+
}
104+
case IECore::M33fDataTypeId :
105+
{
106+
auto attr = geoList.writable_attribute( objIndex, GroupType::Group_Object, name, AttribType::MATRIX3_ATTRIB );
107+
const auto &m = static_cast<const IECore::M33fData *>( value )->readable();
108+
DD::Image::Matrix3 result;
109+
for( int i = 0; i < 3; i++ )
110+
{
111+
for( int j = 0; j < 3; j++ )
112+
{
113+
result[j][i] = m[j][i];
114+
}
115+
}
116+
attr->matrix3() = result;
117+
break;
118+
}
119+
case IECore::M44fDataTypeId :
120+
{
121+
auto attr = geoList.writable_attribute( objIndex, GroupType::Group_Object, name, AttribType::MATRIX4_ATTRIB );
122+
attr->matrix4() = IECore::convert<DD::Image::Matrix4>( Imath::M44d( static_cast<const IECore::M44fData *>( value )->readable() ) );
123+
break;
124+
}
125+
case IECore::M44dDataTypeId :
126+
{
127+
auto attr = geoList.writable_attribute( objIndex, GroupType::Group_Object, name, AttribType::MATRIX4_ATTRIB );
128+
attr->matrix4() = IECore::convert<DD::Image::Matrix4>( static_cast<const IECore::M44dData *>( value )->readable() );
129+
break;
130+
}
131+
case IECore::M33dDataTypeId :
132+
{
133+
auto attr = geoList.writable_attribute( objIndex, GroupType::Group_Object, name, AttribType::MATRIX3_ATTRIB );
134+
const auto &m = static_cast<const IECore::M33dData *>( value )->readable();
135+
DD::Image::Matrix3 result;
136+
for( int i = 0; i < 3; i++ )
137+
{
138+
for( int j = 0; j < 3; j++ )
139+
{
140+
result[j][i] = m[j][i];
141+
}
142+
}
143+
attr->matrix3() = result;
144+
break;
145+
}
146+
default :
147+
IECore::msg( IECore::Msg::Warning, "ToNukeGeometryConverter", boost::format( "Unsupported attribute type \"%s\" for \"%s\"" ) % value->typeName() % name );
148+
break;
149+
}
150+
}
151+
152+
} // namespace
153+
47154
IE_CORE_DEFINERUNTIMETYPED( ToNukeGeometryConverter );
48155

49156
ToNukeGeometryConverter::ToNukeGeometryConverter( const std::string &description, IECore::TypeId fromType, ConstObjectPtr object )
@@ -57,6 +164,9 @@ ToNukeGeometryConverter::ToNukeGeometryConverter( const std::string &description
57164
m_pathParameter = new StringParameter( "path", "The object path in the hierarchy.", new StringData() );
58165
parameters()->addParameter( m_pathParameter );
59166

167+
m_attributesParameter = new CompoundObjectParameter( "attributes", "Scene attributes to write as Group_Object attributes.", new CompoundObject() );
168+
parameters()->addParameter( m_attributesParameter );
169+
60170
}
61171

62172
void ToNukeGeometryConverter::convert( GeometryList &geoList ) const
@@ -72,6 +182,13 @@ void ToNukeGeometryConverter::convert( GeometryList &geoList ) const
72182
auto nameAttribute = geoList.writable_attribute( objIndex, GroupType::Group_Object, IECoreNuke::LiveScene::nameAttribute.data(), AttribType::STD_STRING_ATTRIB);
73183
nameAttribute->stdstring() = m_pathParameter->getTypedValue();
74184

185+
// add scene attributes as Group_Object attributes
186+
ConstCompoundObjectPtr attributes = m_attributesParameter->getTypedValue<CompoundObject>();
187+
for( const auto &attr : attributes->members() )
188+
{
189+
writeAttribute( geoList, objIndex, attr.first.c_str(), attr.second.get() );
190+
}
191+
75192
ConstCompoundObjectPtr operands = parameters()->getTypedValidatedValue<CompoundObject>();
76193
doConversion( srcParameter()->getValidatedValue(), geoList, objIndex, operands.get() );
77194
}

0 commit comments

Comments
 (0)