Beispiel #1
0
void SceneCacheNode<BaseType>::descendantNames( const IECoreScene::SceneInterface *scene, std::vector<std::string> &descendants )
{
	if ( !scene )
	{
		return;
	}

	SceneInterface::NameList children;
	scene->childNames( children );

	std::string current = "";
	if ( scene->name() != SceneInterface::rootName )
	{
		SceneInterface::Path p;
		scene->path( p );
		SceneInterface::pathToString( p, current );
	}

	for ( SceneInterface::NameList::const_iterator it=children.begin(); it != children.end(); ++it )
	{
		descendants.push_back( current + "/" + it->value() );
	}

	for ( SceneInterface::NameList::const_iterator it=children.begin(); it != children.end(); ++it )
	{
		descendantNames( scene->child( *it ).get(), descendants );
	}
};
Beispiel #2
0
void SceneShape::sceneShapeAttributeNames( const MDagPath &p, SceneInterface::NameList &attributeNames )
{
	MDagPath dagPath;
	SceneShape *sceneShape = findScene( p, false, &dagPath );
	if ( !sceneShape )
	{
		return;
	}
	
	SceneInterface::NameList sceneAttrNames;
	ConstSceneInterfacePtr scene = sceneShape->getSceneInterface();
	if ( !scene )
	{
		return;
	}
	scene->attributeNames( sceneAttrNames );
	attributeNames.insert( attributeNames.end(), sceneAttrNames.begin(), sceneAttrNames.end() );
	
	MFnDagNode fnChildDag( dagPath );
	if( !fnChildDag.isIntermediateObject() && hasSceneShapeLink( p ) )
	{
		attributeNames.push_back( LinkedScene::linkAttribute );
	}
	
}
Beispiel #3
0
IECore::ConstCompoundObjectPtr SceneReader::computeAttributes( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent ) const
{
	std::string fileName = fileNamePlug()->getValue();
	if( !fileName.size() )
	{
		return parent->attributesPlug()->defaultValue();
	}
	
	ConstSceneInterfacePtr s = SharedSceneInterfaces::get( fileName );
	s = s->scene( path );
	
	// read attributes
	
	SceneInterface::NameList nameList;
	s->attributeNames( nameList );
	
	CompoundObjectPtr result = new CompoundObject;
	
	for( SceneInterface::NameList::iterator it = nameList.begin(); it != nameList.end(); ++it )
	{
		// these internal attributes should be ignored:
		if( *it == SceneCache::animatedObjectTopologyAttribute )
		{
			continue;
		}
		if( *it == SceneCache::animatedObjectPrimVarsAttribute )
		{
			continue;
		}
		
		// the const cast is ok, because we're only using it to put the object into a CompoundObject that will
		// be treated as forever const after being returned from this function.
		result->members()[ std::string( *it ) ] = constPointerCast<Object>( s->readAttribute( *it, context->getFrame() / g_frameRate ) );
	}

	// read tags and turn them into attributes of the form "user:tag:tagName"
	
	nameList.clear();
	s->readTags( nameList, IECore::SceneInterface::LocalTag );
	for( SceneInterface::NameList::const_iterator it = nameList.begin(); it != nameList.end(); ++it )
	{
		if( it->string().compare( 0, 11, "ObjectType:" ) == 0 )
		{
			continue;
		}
		result->members()["user:tag:"+it->string()] = g_trueBoolData;
	}

	return result;
}
Beispiel #4
0
IECore::ConstCompoundObjectPtr SceneReader::computeAttributes( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent ) const
{
	ConstSceneInterfacePtr s = scene( path );
	if( !s )
	{
		return parent->attributesPlug()->defaultValue();
	}

	// read attributes
	SceneInterface::NameList nameList;
	s->attributeNames( nameList );

	CompoundObjectPtr result = new CompoundObject;

	for( SceneInterface::NameList::iterator it = nameList.begin(); it != nameList.end(); ++it )
	{
		// these internal attributes should be ignored:
		if( *it == SceneCache::animatedObjectTopologyAttribute )
		{
			continue;
		}
		if( *it == SceneCache::animatedObjectPrimVarsAttribute )
		{
			continue;
		}

		// the const cast is ok, because we're only using it to put the object into a CompoundObject that will
		// be treated as forever const after being returned from this function.
		result->members()[ std::string( *it ) ] = boost::const_pointer_cast<Object>( s->readAttribute( *it, context->getTime() ) );
	}

	return result;
}
Beispiel #5
0
static void loadSetWalk( const SceneInterface *s, const InternedString &setName, PathMatcher &set, const vector<InternedString> &path )
{
	if( s->hasTag( setName, SceneInterface::LocalTag ) )
	{
		set.addPath( path );
	}

	// Figure out if we need to recurse by querying descendant tags to see if they include
	// anything we're interested in.

	if( !s->hasTag( setName, SceneInterface::DescendantTag ) )
	{
		return;
	}

	// Recurse to the children.

	SceneInterface::NameList childNames;
	s->childNames( childNames );
	vector<InternedString> childPath( path );
	childPath.push_back( InternedString() ); // room for the child name
	for( SceneInterface::NameList::const_iterator it = childNames.begin(), eIt = childNames.end(); it != eIt; ++it )
	{
		ConstSceneInterfacePtr child = s->child( *it );
		childPath.back() = *it;
		loadSetWalk( child.get(), setName, set, childPath );
	}
}
void SOP_SceneCacheSource::loadObjects( const IECore::SceneInterface *scene, Imath::M44d transform, double time, Space space, const UT_StringMMPattern &shapeFilter, const std::string &attributeFilter, size_t rootSize )
{
	if ( scene->hasObject() && UT_String( scene->name() ).multiMatch( shapeFilter ) )
	{
		ObjectPtr object = scene->readObject( time );
		std::string name = relativePath( scene, rootSize );
		
		bool hasAnimatedTopology = scene->hasAttribute( SceneCache::animatedObjectTopologyAttribute );
		bool hasAnimatedPrimVars = scene->hasAttribute( SceneCache::animatedObjectPrimVarsAttribute );
		std::vector<InternedString> animatedPrimVars;
		if ( hasAnimatedPrimVars )
		{
			const ObjectPtr animatedPrimVarObj = scene->readAttribute( SceneCache::animatedObjectPrimVarsAttribute, 0 );
			const InternedStringVectorData *animatedPrimVarData = IECore::runTimeCast<const InternedStringVectorData>( animatedPrimVarObj );
			if ( animatedPrimVarData )
			{
				const std::vector<InternedString> &values = animatedPrimVarData->readable();
				animatedPrimVars.resize( values.size() );
				std::copy( values.begin(), values.end(), animatedPrimVars.begin() );
			}
		}
		
		modifyObject( object, name, hasAnimatedTopology, hasAnimatedPrimVars, animatedPrimVars );
		
		Imath::M44d currentTransform;
		if ( space == Local )
		{
			currentTransform = scene->readTransformAsMatrix( time );
		}
		else if ( space != Object )
		{
			currentTransform = transform;
		}
		
		// transform the object unless its an identity
		if ( currentTransform != Imath::M44d() )
		{
			transformObject( object, currentTransform, hasAnimatedTopology, hasAnimatedPrimVars, animatedPrimVars );
		}
		
		// convert the object to Houdini
		if ( !convertObject( object, name, attributeFilter, hasAnimatedTopology, hasAnimatedPrimVars, animatedPrimVars ) )
		{
			addError( SOP_LOAD_UNKNOWN_BINARY_FLAG, ( "Could not convert " + name + " to houdini" ).c_str() );
		}
	}
	
	SceneInterface::NameList children;
	scene->childNames( children );
	for ( SceneInterface::NameList::const_iterator it=children.begin(); it != children.end(); ++it )
	{
		ConstSceneInterfacePtr child = scene->child( *it );
		loadObjects( child, child->readTransformAsMatrix( time ) * transform, time, space, shapeFilter, attributeFilter, rootSize );
	}
}
Beispiel #7
0
IECore::ConstInternedStringVectorDataPtr SceneReader::computeChildNames( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent ) const
{
	ConstSceneInterfacePtr s = scene( path );
	if( !s )
	{
		return parent->childNamesPlug()->defaultValue();
	}

	// get the child names
	
	InternedStringVectorDataPtr resultData = new InternedStringVectorData;
	vector<InternedString> &result = resultData->writable();
	s->childNames( result );
	
	// filter out any which don't have the right tags
	
	std::string tagsString = tagsPlug()->getValue();
	if( !tagsString.empty() )
	{
		typedef boost::tokenizer<boost::char_separator<char> > Tokenizer;
		Tokenizer tagsTokenizer( tagsString, boost::char_separator<char>( " " ) );
		
		vector<InternedString> tags;
		std::copy( tagsTokenizer.begin(), tagsTokenizer.end(), back_inserter( tags ) );
		
		vector<InternedString>::iterator newResultEnd = result.begin();
		SceneInterface::NameList childTags;
		for( vector<InternedString>::const_iterator cIt = result.begin(), cEIt = result.end(); cIt != cEIt; ++cIt )
		{
			ConstSceneInterfacePtr child = s->child( *cIt );
			childTags.clear();
			child->readTags( childTags, IECore::SceneInterface::EveryTag );
			
			bool childMatches = false;
			for( SceneInterface::NameList::const_iterator tIt = childTags.begin(), tEIt = childTags.end(); tIt != tEIt; ++tIt )
			{
				if( find( tags.begin(), tags.end(), *tIt ) != tags.end() )
				{
					childMatches = true;
					break;
				}
			}
		
			if( childMatches )
			{
				*newResultEnd++ = *cIt;
			}
		}
		
		result.erase( newResultEnd, result.end() );
	}
	
	return resultData;
}
Beispiel #8
0
void SceneCacheNode<BaseType>::objectNames( const IECore::SceneInterface *scene, std::vector<std::string> &objects )
{
	if ( scene->hasObject() )
	{
		objects.push_back( scene->name() );
	}
	
	SceneInterface::NameList children;
	scene->childNames( children );
	for ( SceneInterface::NameList::const_iterator it=children.begin(); it != children.end(); ++it )
	{
		objectNames( scene->child( *it ), objects );
	}
};
Beispiel #9
0
void SceneReader::hashAttributes( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent, IECore::MurmurHash &h ) const
{
	ConstSceneInterfacePtr s = scene( path );
	if( !s )
	{
		h = parent->attributesPlug()->defaultValue()->Object::hash();
		return;
	}
	
	SceneInterface::NameList attributeNames;
	s->attributeNames( attributeNames );
	SceneInterface::NameList tagNames;
	s->readTags( tagNames, IECore::SceneInterface::LocalTag );
	
	if( !attributeNames.size() && !tagNames.size() )
	{
		h = parent->attributesPlug()->defaultValue()->Object::hash();
		return;
	}

	FileSource::hashAttributes( path, context, parent, h );

	bool animated = false;
	const SampledSceneInterface *ss = runTimeCast<const SampledSceneInterface>( s.get() );
	if( !ss )
	{
		animated = true;
	}
	else
	{
		for( SceneInterface::NameList::iterator it = attributeNames.begin(); it != attributeNames.end(); ++it )
		{
			if( ss->numAttributeSamples( *it ) > 1 )
			{
				animated = true;
				break;
			}
		}
	}
				
	if( animated )
	{
		h.append( context->getFrame() );
	}
}
Beispiel #10
0
bool SceneCacheNode<BaseType>::tagged( const IECore::SceneInterface *scene, const UT_StringMMPattern &filter )
{
	SceneInterface::NameList tags;
	scene->readTags( tags );
	for ( SceneInterface::NameList::const_iterator it=tags.begin(); it != tags.end(); ++it )
	{
		if ( UT_String( *it ).multiMatch( filter ) )
		{
			return true;
		}
	}
	
	// an empty list should be equivalent to matching an empty string
	if ( tags.empty() && UT_String( "" ).multiMatch( filter ) )
	{
		return true;
	}
	
	return false;
}
ROP_RENDER_CODE ROP_SceneCacheWriter::doWrite( const SceneInterface *liveScene, SceneInterface *outScene, double time )
{
	if ( liveScene != m_liveScene )
	{
		outScene->writeTransform( liveScene->readTransform( time ), time );
	}
	
	if ( liveScene->hasObject() )
	{
		try
		{
			/// \todo: does an invisible node mean there is no object?
			outScene->writeObject( liveScene->readObject( time ), time );
		}
		catch ( IECore::Exception &e )
		{
			addError( ROP_MESSAGE, e.what() );
			return ROP_ABORT_RENDER;
		}
	}
	
	SceneInterface::NameList children;
	liveScene->childNames( children );
	for ( SceneInterface::NameList::iterator it = children.begin(); it != children.end(); ++it )
	{
		/// \todo: does an invisible node mean its not a child?
		ConstSceneInterfacePtr liveChild = liveScene->child( *it );
		SceneInterfacePtr outChild = outScene->child( *it, SceneInterface::CreateIfMissing );
		ROP_RENDER_CODE status = doWrite( liveChild, outChild, time );
		if ( status != ROP_CONTINUE_RENDER )
		{
			return status;
		}
	}
	
	return ROP_CONTINUE_RENDER;
}
Beispiel #12
0
void SceneCacheNode<BaseType>::buildTagFilterMenu( void *data, PRM_Name *menu, int maxSize, const PRM_SpareData *, const PRM_Parm * )
{
	SceneCacheNode<BaseType> *node = reinterpret_cast<SceneCacheNode<BaseType>*>( data );
	if ( !node )
	{
		return;
	}
	
	menu[0].setToken( "*" );
	menu[0].setLabel( "*" );
	
	std::string file;
	if ( !node->ensureFile( file ) )
	{
		// mark the end of our menu
		menu[1].setToken( 0 );
		return;
	}
	
	ConstSceneInterfacePtr scene = node->scene( file, node->getPath() );
	if ( !scene )
	{
		// mark the end of our menu
		menu[1].setToken( 0 );
		return;
	}
	
	SceneInterface::NameList tags;
	scene->readTags( tags );
	std::vector<std::string> tagStrings;
	for ( SceneInterface::NameList::const_iterator it=tags.begin(); it != tags.end(); ++it )
	{
		tagStrings.push_back( *it );
	}
	
	node->createMenu( menu, tagStrings );
}
void SOP_SceneCacheSource::loadObjects( const IECore::SceneInterface *scene, Imath::M44d transform, double time, Space space, const UT_StringMMPattern &shapeFilter, const std::string &attributeFilter, GeometryType geometryType, size_t rootSize )
{
	UT_Interrupt *progress = UTgetInterrupt();
	progress->setLongOpText( ( "Loading " + scene->name().string() ).c_str() );
	if ( progress->opInterrupt() )
	{
		return;
	}
	
	if ( scene->hasObject() && UT_String( scene->name() ).multiMatch( shapeFilter ) )
	{
		// \todo See if there are ways to avoid the Object copy below.
		ObjectPtr object = scene->readObject( time )->copy();
		std::string name = relativePath( scene, rootSize );
		
		bool hasAnimatedTopology = scene->hasAttribute( SceneCache::animatedObjectTopologyAttribute );
		bool hasAnimatedPrimVars = scene->hasAttribute( SceneCache::animatedObjectPrimVarsAttribute );
		std::vector<InternedString> animatedPrimVars;
		if ( hasAnimatedPrimVars )
		{
			const ConstObjectPtr animatedPrimVarObj = scene->readAttribute( SceneCache::animatedObjectPrimVarsAttribute, 0 );
			const InternedStringVectorData *animatedPrimVarData = IECore::runTimeCast<const InternedStringVectorData>( animatedPrimVarObj );
			if ( animatedPrimVarData )
			{
				const std::vector<InternedString> &values = animatedPrimVarData->readable();
				animatedPrimVars.resize( values.size() );
				std::copy( values.begin(), values.end(), animatedPrimVars.begin() );
			}
		}
		
		modifyObject( object, name, attributeFilter, hasAnimatedTopology, hasAnimatedPrimVars, animatedPrimVars );
		
		Imath::M44d currentTransform;
		if ( space == Local )
		{
			currentTransform = scene->readTransformAsMatrix( time );
		}
		else if ( space != Object )
		{
			currentTransform = transform;
		}
		
		// transform the object unless its an identity
		if ( currentTransform != Imath::M44d() )
		{
			transformObject( object, currentTransform, hasAnimatedTopology, hasAnimatedPrimVars, animatedPrimVars );
		}
		
		// load the Cortex object directly
		if ( geometryType == Cortex )
		{
			holdObject( object, name, hasAnimatedTopology, hasAnimatedPrimVars, animatedPrimVars );
		}
		else
		{
			// convert the object to Houdini
			if ( !convertObject( object, name, attributeFilter, geometryType, hasAnimatedTopology, hasAnimatedPrimVars, animatedPrimVars ) )
			{
				std::string fullName;
				SceneInterface::Path path;
				scene->path( path );
				SceneInterface::pathToString( path, fullName );
				addWarning( SOP_MESSAGE, ( "Could not convert " + fullName + " to houdini" ).c_str() );
			}
		}
	}
	
	if ( evalInt( pObjectOnly.getToken(), 0, 0 ) )
	{
		return;
	}
	
	SceneInterface::NameList children;
	scene->childNames( children );
	for ( SceneInterface::NameList::const_iterator it=children.begin(); it != children.end(); ++it )
	{
		ConstSceneInterfacePtr child = scene->child( *it );
		loadObjects( child, child->readTransformAsMatrix( time ) * transform, time, space, shapeFilter, attributeFilter, geometryType, rootSize );
	}
}
void SOP_SceneCacheSource::loadObjects( const IECore::SceneInterface *scene, Imath::M44d transform, double time, Space space, Parameters &params, size_t rootSize )
{
	UT_Interrupt *progress = UTgetInterrupt();
	progress->setLongOpText( ( "Loading " + scene->name().string() ).c_str() );
	if ( progress->opInterrupt() )
	{
		return;
	}
	
	if ( scene->hasObject() && UT_String( scene->name() ).multiMatch( params.shapeFilter ) && tagged( scene, params.tagFilter ) )
	{
		std::string name = relativePath( scene, rootSize );
		
		Imath::M44d currentTransform;
		if ( space == Local )
		{
			currentTransform = scene->readTransformAsMatrix( time );
		}
		else if ( space != Object )
		{
			currentTransform = transform;
		}
		
		ConstObjectPtr object = 0;
		if ( params.geometryType == BoundingBox )
		{
			Imath::Box3d bound = scene->readBound( time );
			object = MeshPrimitive::createBox( Imath::Box3f( bound.min, bound.max ) );
			
			params.hasAnimatedTopology = false;
			params.hasAnimatedPrimVars = true;
			params.animatedPrimVars.clear();
			params.animatedPrimVars.push_back( "P" );
		}
		else if ( params.geometryType == PointCloud )
		{
			std::vector<Imath::V3f> point( 1, scene->readBound( time ).center() );
			PointsPrimitivePtr points = new PointsPrimitive( new V3fVectorData( point ) );
			std::vector<Imath::V3f> basis1( 1, Imath::V3f( currentTransform[0][0], currentTransform[0][1], currentTransform[0][2] ) );
			std::vector<Imath::V3f> basis2( 1, Imath::V3f( currentTransform[1][0], currentTransform[1][1], currentTransform[1][2] ) );
			std::vector<Imath::V3f> basis3( 1, Imath::V3f( currentTransform[2][0], currentTransform[2][1], currentTransform[2][2] ) );
			points->variables["basis1"] = PrimitiveVariable( PrimitiveVariable::Vertex, new V3fVectorData( basis1 ) );
			points->variables["basis2"] = PrimitiveVariable( PrimitiveVariable::Vertex, new V3fVectorData( basis2 ) );
			points->variables["basis3"] = PrimitiveVariable( PrimitiveVariable::Vertex, new V3fVectorData( basis3 ) );
			
			params.hasAnimatedTopology = false;
			params.hasAnimatedPrimVars = true;
			params.animatedPrimVars.clear();
			params.animatedPrimVars.push_back( "P" );
			params.animatedPrimVars.push_back( "basis1" );
			params.animatedPrimVars.push_back( "basis2" );
			params.animatedPrimVars.push_back( "basis3" );
			
			object = points;
		}
		else
		{
			object = scene->readObject( time );
			
			params.hasAnimatedTopology = scene->hasAttribute( SceneCache::animatedObjectTopologyAttribute );
			params.hasAnimatedPrimVars = scene->hasAttribute( SceneCache::animatedObjectPrimVarsAttribute );
			if ( params.hasAnimatedPrimVars )
			{
				const ConstObjectPtr animatedPrimVarObj = scene->readAttribute( SceneCache::animatedObjectPrimVarsAttribute, 0 );
				const InternedStringVectorData *animatedPrimVarData = IECore::runTimeCast<const InternedStringVectorData>( animatedPrimVarObj.get() );
				if ( animatedPrimVarData )
				{
					const std::vector<InternedString> &values = animatedPrimVarData->readable();
					params.animatedPrimVars.clear();
					params.animatedPrimVars.resize( values.size() );
					std::copy( values.begin(), values.end(), params.animatedPrimVars.begin() );
				}
			}
		}
		
		// modify the object if necessary
		object = modifyObject( object.get(), params );
		
		// transform the object unless its an identity
		if ( currentTransform != Imath::M44d() )
		{
			object = transformObject( object.get(), currentTransform, params );
		}
		
		// convert the object to Houdini
		if ( !convertObject( object.get(), name, scene, params ) )
		{
			std::string fullName;
			SceneInterface::Path path;
			scene->path( path );
			SceneInterface::pathToString( path, fullName );
			addWarning( SOP_MESSAGE, ( "Could not convert " + fullName + " to Houdini" ).c_str() );
		}
	}
	
	if ( evalInt( pObjectOnly.getToken(), 0, 0 ) )
	{
		return;
	}
	
	SceneInterface::NameList children;
	scene->childNames( children );
	std::sort( children.begin(), children.end(), InternedStringSort() );
	for ( SceneInterface::NameList::const_iterator it=children.begin(); it != children.end(); ++it )
	{
		ConstSceneInterfacePtr child = scene->child( *it );
		if ( tagged( child.get(), params.tagFilter ) )
		{
			loadObjects( child.get(), child->readTransformAsMatrix( time ) * transform, time, space, params, rootSize );
		}
	}
}
void OBJ_SceneCacheTransform::doExpandChildren( const SceneInterface *scene, OP_Network *parent, const Parameters &params )
{
	UT_Interrupt *progress = UTgetInterrupt();
	progress->setLongOpText( ( "Expanding " + scene->name().string() ).c_str() );
	if ( progress->opInterrupt() )
	{
		return;
	}

	OP_Network *inputNode = parent;
	if ( params.hierarchy == Parenting )
	{
		parent = parent->getParent();
	}

	SceneInterface::NameList children;
	scene->childNames( children );
	for ( SceneInterface::NameList::const_iterator it=children.begin(); it != children.end(); ++it )
	{
		ConstSceneInterfacePtr child = scene->child( *it );

		OBJ_Node *childNode = 0;
		if ( params.hierarchy == SubNetworks )
		{
			childNode = doExpandChild( child.get(), parent, params );
			if ( params.depth == AllDescendants && child->hasObject() && tagged( child.get(), params.tagFilter ) )
			{
				Parameters childParams( params );
				childParams.depth = Children;
				doExpandObject( child.get(), childNode, childParams );
			}
		}
		else if ( params.hierarchy == Parenting )
		{
			if ( child->hasObject() )
			{
				Parameters childParams( params );
				childParams.depth = Children;
				childNode = doExpandObject( child.get(), parent, childParams );
			}
			else
			{
				childNode = doExpandChild( child.get(), parent, params );
			}

			childNode->setInput( 0, inputNode );
		}

		if ( params.depth == AllDescendants )
		{
			if ( params.hierarchy == SubNetworks && !tagged( child.get(), params.tagFilter ) )
			{
				// we don't expand non-tagged children for SubNetwork mode, but we
				// do for Parenting mode, because otherwise the hierarchy would be
				// stuck in an un-expandable state.
				continue;
			}

			doExpandChildren( child.get(), childNode, params );
			childNode->setInt( pExpanded.getToken(), 0, 0, 1 );
		}
	}

	OP_Layout layout( parent );

#if UT_MAJOR_VERSION_INT >= 16

	OP_SubnetIndirectInput *parentInput = parent->getParentInput( 0 );
	layout.addLayoutItem( parentInput->getInputItem() );
	for ( int i=0; i < parent->getNchildren(); ++i )
	{
		layout.addLayoutItem( parent->getChild( i ) );
	}

#else

	layout.addLayoutOp( parent->getParentInput( 0 ) );
	for ( int i=0; i < parent->getNchildren(); ++i )
	{
		layout.addLayoutOp( parent->getChild( i ) );
	}

#endif

	layout.layoutOps( OP_LAYOUT_TOP_TO_BOT, parent, parent->getParentInput( 0 ) );
}
Beispiel #16
0
static void loadSetsWalk( const SceneInterface *s, const vector<InternedString> &tags, const vector<PathMatcher *> &sets, const vector<InternedString> &path )
{
	// For each tag we wish to load, we need to determine if it exists at the current
	// location. The natural way to do this would be to call s->hasTag( tag ), but that
	// actually has pretty poor performance when calling hasTag() for many tags. So
	// we load all the local tags with readTags(), and then for each of them test to see
	// if they exist in the list of tags we wish to load. We test the local tags against
	// the tags because we're in control of the tags and can sort them beforehand for faster
	// searching, whereas the localTags just come as-is. Using binary search over linear
	// search isn't actually that big a win for a typical number of tags, simply because
	// InternedString equality tests are so quick, but there's a very slight benefit, which
	// should be more apparent should anyone create a very large number of tags at some point.
	
	vector<InternedString> sceneTags;
	s->readTags( sceneTags, SceneInterface::LocalTag );

	for( vector<InternedString>::const_iterator it = sceneTags.begin(), eIt = sceneTags.end(); it != eIt; ++it )
	{
		vector<InternedString>::const_iterator t = lower_bound( tags.begin(), tags.end(), *it );
		if( t != tags.end() && *t == *it )
		{
			/// \todo addPath() is doing a search to find the right node to insert at.
			/// If nodes were exposed by the PathMatcher, we could provide the right
			/// node to insert at by tracking it as we recurse the hierarchy.
			sets[t - tags.begin()]->addPath( path );
		}
	}
	
	// Figure out if we need to recurse by querying descendant tags to see if they include
	// anything we're interested in.
	
	sceneTags.clear();
	s->readTags( sceneTags, SceneInterface::DescendantTag );
	
	bool recurse = false;
	for( vector<InternedString>::const_iterator it = sceneTags.begin(), eIt = sceneTags.end(); it != eIt; ++it )
	{
		vector<InternedString>::const_iterator t = lower_bound( tags.begin(), tags.end(), *it );
		if( t != tags.end() && *t == *it )
		{
			recurse = true;
			break;
		}
	}
	
	if( !recurse )
	{
		return;
	}
	
	// Recurse to the children.
	
	SceneInterface::NameList childNames;
	s->childNames( childNames );
	vector<InternedString> childPath( path );
	childPath.push_back( InternedString() ); // room for the child name
	for( SceneInterface::NameList::const_iterator it = childNames.begin(), eIt = childNames.end(); it != eIt; ++it )
	{
		ConstSceneInterfacePtr child = s->child( *it );
		childPath[path.size()] = *it;
		loadSetsWalk( child.get(), tags, sets, childPath );
	}
}
bool SOP_SceneCacheSource::convertObject( const IECore::Object *object, const std::string &name, const SceneInterface *scene, Parameters &params )
{
	ToHoudiniGeometryConverterPtr converter = nullptr;
	if ( params.geometryType == Cortex )
	{
		converter = new ToHoudiniCortexObjectConverter( object );
	}
	else
	{
		const VisibleRenderable *renderable = IECore::runTimeCast<const VisibleRenderable>( object );
		if ( !renderable )
		{
			return false;
		}

		converter = ToHoudiniGeometryConverter::create( renderable );
	}

	if ( !converter )
	{
		return false;
	}

	// we need to set the name regardless of whether
	// we're reusing prims or doing the full conversion
	// because this parameter can have an affect in
	// transferAttribs() as well as convert()
	converter->nameParameter()->setTypedValue( name );

	// check the primitve range map to see if this shape exists already
	std::map<std::string, GA_Range>::iterator rIt = params.namedRanges.find( name );
	if ( rIt != params.namedRanges.end() && !rIt->second.isEmpty() )
	{
		GA_Range primRange = rIt->second;
		const Primitive *primitive = IECore::runTimeCast<const Primitive>( object );
		if ( primitive && !params.hasAnimatedTopology && params.hasAnimatedPrimVars )
		{
			// this means constant topology and primitive variables, even though multiple samples were written
			if ( params.animatedPrimVars.empty() )
			{
				return true;
			}

			GA_Range pointRange( *gdp, primRange, GA_ATTRIB_POINT, GA_Range::primitiveref(), false );

			// update the animated primitive variables only
			std::string animatedPrimVarStr = "";
			for ( std::vector<InternedString>::const_iterator it = params.animatedPrimVars.begin(); it != params.animatedPrimVars.end(); ++it )
			{
				animatedPrimVarStr += it->string() + " ";
			}

			converter->attributeFilterParameter()->setTypedValue( animatedPrimVarStr );

			try
			{
				converter->transferAttribs( gdp, pointRange, primRange );
				return true;
			}
			catch ( std::exception &e )
			{
				addWarning( SOP_MESSAGE, e.what() );
				return false;
			}
			catch ( ... )
			{
				addWarning( SOP_MESSAGE, "Attribute transfer failed for unknown reasons" );
				return false;
			}
		}
		else
		{
			// topology is changing, so destroy the exisiting primitives
			gdp->destroyPrimitives( primRange, true );
		}
	}

	// fallback to full conversion
	converter->attributeFilterParameter()->setTypedValue( params.attributeFilter );

	try
	{
		GA_Offset firstNewPrim = gdp->getPrimitiveMap().lastOffset() + 1;

		bool status = converter->convert( myGdpHandle );

		// adds the full path in addition to the relative name
		const GA_IndexMap &primMap = gdp->getPrimitiveMap();
		GA_Range newPrims( primMap, firstNewPrim, primMap.lastOffset() + 1 );

		if ( params.fullPathName != "" )
		{
			if ( newPrims.isValid() )
			{
				std::string fullName;
				SceneInterface::Path path;
				scene->path( path );
				SceneInterface::pathToString( path, fullName );

				GA_RWAttributeRef pathAttribRef = ToHoudiniStringVectorAttribConverter::convertString( params.fullPathName, fullName, gdp, newPrims );
				status = status && pathAttribRef.isValid();
			}
		}

		if ( params.tagGroups )
		{
			static UT_StringMMPattern convertTagFilter;
			if( convertTagFilter.isEmpty() )
			{
				convertTagFilter.compile( "ObjectType:*" );
			}
			SceneInterface::NameList tags;
			scene->readTags( tags, IECoreScene::SceneInterface::LocalTag );
			for ( SceneInterface::NameList::const_iterator it=tags.begin(); it != tags.end(); ++it )
			{
				UT_String tag( *it );
				// skip this tag because it's used behind the scenes
				if ( tag.multiMatch( convertTagFilter ) )
				{
					continue;
				}

				// replace this special character found in SCC tags that will prevent the group from being created
				tag.substitute(":", "_");

				tag.prepend("ieTag_");

				GA_PrimitiveGroup *group = gdp->findPrimitiveGroup(tag);
				if ( !group )
				{
					group = gdp->newPrimitiveGroup(tag);
				}
				group->addRange(newPrims);
			}
		}

		return status;
	}
	catch ( std::exception &e )
	{
		addWarning( SOP_MESSAGE, e.what() );
		return false;
	}
	catch ( ... )
	{
		addWarning( SOP_MESSAGE, "Conversion failed for unknown reasons" );
		return false;
	}
}