Skip to content

Commit 6320c39

Browse files
committed
Merge pull request #192 from andrewkaufman/sccSopPrimVarTransform
SceneCache SOP transforms all Point and Normal primitive variables.
2 parents 0155195 + 0652a45 commit 6320c39

File tree

3 files changed

+73
-6
lines changed

3 files changed

+73
-6
lines changed

include/IECoreHoudini/SOP_SceneCacheSource.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,15 @@ class SOP_SceneCacheSource : public SceneCacheNode<SOP_Node>
104104
{
105105
bool operator() ( const IECore::SceneInterface::Name &i, const IECore::SceneInterface::Name &j );
106106
};
107+
108+
/// Utility for detecting geometric primitive variables that need transforming
109+
struct TransformGeometricData
110+
{
111+
typedef bool ReturnType;
112+
113+
template<typename T>
114+
ReturnType operator()( typename T::ConstPtr data ) const;
115+
};
107116

108117
};
109118

src/IECoreHoudini/SOP_SceneCacheSource.cpp

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,12 @@
3939
#include "UT/UT_WorkArgs.h"
4040

4141
#include "IECore/CoordinateSystem.h"
42+
#include "IECore/DespatchTypedData.h"
4243
#include "IECore/Group.h"
4344
#include "IECore/MeshPrimitive.h"
4445
#include "IECore/PointsPrimitive.h"
4546
#include "IECore/TransformOp.h"
47+
#include "IECore/TypeTraits.h"
4648
#include "IECore/VisibleRenderable.h"
4749

4850
#include "IECoreHoudini/GU_CortexPrimitive.h"
@@ -451,6 +453,13 @@ ConstObjectPtr SOP_SceneCacheSource::modifyObject( const IECore::Object *object,
451453
return result;
452454
}
453455

456+
template<typename T>
457+
SOP_SceneCacheSource::TransformGeometricData::ReturnType SOP_SceneCacheSource::TransformGeometricData::operator()( typename T::ConstPtr data ) const
458+
{
459+
GeometricData::Interpretation interp = data->getInterpretation();
460+
return ( interp == GeometricData::Point || interp == GeometricData::Normal || interp == GeometricData::Vector );
461+
}
462+
454463
ConstObjectPtr SOP_SceneCacheSource::transformObject( const IECore::Object *object, const Imath::M44d &transform, Parameters &params )
455464
{
456465
if ( const Primitive *primitive = IECore::runTimeCast<const Primitive>( object ) )
@@ -459,19 +468,27 @@ ConstObjectPtr SOP_SceneCacheSource::transformObject( const IECore::Object *obje
459468
transformer->inputParameter()->setValue( const_cast<Primitive*>( primitive ) ); // safe because we set the copy parameter
460469
transformer->copyParameter()->setTypedValue( true );
461470
transformer->matrixParameter()->setValue( new M44dData( transform ) );
462-
ObjectPtr result = transformer->operate();
463471

472+
// add all Point and Normal prim vars to the transformation list
473+
const PrimitiveVariableMap &variables = primitive->variables;
464474
std::vector<std::string> &primVars = transformer->primVarsParameter()->getTypedValue();
465-
for ( std::vector<std::string>::iterator it = primVars.begin(); it != primVars.end(); ++it )
475+
primVars.clear();
476+
for ( PrimitiveVariableMap::const_iterator it = variables.begin(); it != variables.end(); ++it )
466477
{
467-
if ( std::find( params.animatedPrimVars.begin(), params.animatedPrimVars.end(), *it ) == params.animatedPrimVars.end() )
478+
if ( despatchTypedData<TransformGeometricData, IECore::TypeTraits::IsGeometricTypedData, DespatchTypedDataIgnoreError>( it->second.data ) )
468479
{
469-
params.animatedPrimVars.push_back( *it );
470-
params.hasAnimatedPrimVars = true;
480+
primVars.push_back( it->first );
481+
482+
// add the transforming prim vars to the animated list
483+
if ( std::find( params.animatedPrimVars.begin(), params.animatedPrimVars.end(), it->first ) == params.animatedPrimVars.end() )
484+
{
485+
params.animatedPrimVars.push_back( it->first );
486+
params.hasAnimatedPrimVars = true;
487+
}
471488
}
472489
}
473490

474-
return result;
491+
return transformer->operate();
475492
}
476493
else if ( const Group *group = IECore::runTimeCast<const Group>( object ) )
477494
{

test/IECoreHoudini/SceneCacheTest.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,47 @@ def testSopSpaceModes( self ) :
496496
self.assertEqual( prims[1].vertices()[0].point().position(), hou.Vector3( 0.5, 0.5, 0.5 ) )
497497
self.assertEqual( prims[2].vertices()[0].point().position(), hou.Vector3( 0.5, 0.5, 0.5 ) )
498498

499+
def testSopTransformsPrimvars( self ) :
500+
501+
def writeTestFile() :
502+
503+
scene = IECore.SceneCache( TestSceneCache.__testFile, IECore.IndexedIO.OpenMode.Write )
504+
505+
sc = scene.createChild( str( 1 ) )
506+
matrix = IECore.M44d.createTranslated( IECore.V3d( 1, 0, 0 ) )
507+
sc.writeTransform( IECore.M44dData( matrix ), 0 )
508+
509+
sc = sc.createChild( str( 2 ) )
510+
matrix = IECore.M44d.createTranslated( IECore.V3d( 2, 0, 0 ) )
511+
sc.writeTransform( IECore.M44dData( matrix ), 0 )
512+
513+
sc = sc.createChild( str( 3 ) )
514+
matrix = IECore.M44d.createTranslated( IECore.V3d( 3, 0, 0 ) )
515+
sc.writeTransform( IECore.M44dData( matrix ), 0 )
516+
517+
mesh = IECore.MeshPrimitive.createBox(IECore.Box3f(IECore.V3f(0),IECore.V3f(1)))
518+
mesh["Pref"] = IECore.PrimitiveVariable( IECore.PrimitiveVariable.Interpolation.Vertex, mesh["P"].data.copy() )
519+
mesh["otherP"] = IECore.PrimitiveVariable( IECore.PrimitiveVariable.Interpolation.Vertex, mesh["P"].data.copy() )
520+
mesh["Cs"] = IECore.PrimitiveVariable( IECore.PrimitiveVariable.Interpolation.Vertex, IECore.V3fVectorData( [ IECore.V3f( 0, 0, 1 ) ] * 8 ) )
521+
sc.writeObject( mesh, 0 )
522+
523+
writeTestFile()
524+
525+
node = self.sop()
526+
node.parm( "geometryType" ).set( IECoreHoudini.SceneCacheNode.GeometryType.Houdini )
527+
node.parm( "space" ).set( IECoreHoudini.SceneCacheNode.Space.World )
528+
prims = node.geometry().prims()
529+
self.assertEqual( len(prims), 6 )
530+
self.assertEqual( sorted( [ x.name() for x in node.geometry().pointAttribs() ] ), ["Cd", "P", "Pw", "otherP", "rest"] )
531+
532+
# P is transformed
533+
self.assertEqual( prims[0].vertex( 0 ).point().position(), hou.Vector3( 6, 0, 0 ) )
534+
# other Point data is as well
535+
self.assertEqual( prims[0].vertex( 0 ).point().attribValue( "rest" ), ( 6, 0, 0 ) )
536+
self.assertEqual( prims[0].vertex( 0 ).point().attribValue( "otherP" ), ( 6, 0, 0 ) )
537+
# other data is not
538+
self.assertEqual( prims[0].vertex( 0 ).point().attribValue( "Cd" ), ( 0, 0, 1 ) )
539+
499540
def testSopShapeFilter( self ) :
500541

501542
self.writeSCC()

0 commit comments

Comments
 (0)