예제 #1
0
void SOP_CortexConverter::doConvert( const GU_DetailHandle &handle, const std::string &name, ResultType type, const std::string &attributeFilter, bool convertStandardAttributes )
{
	if ( handle.isNull() )
	{
		addError( SOP_MESSAGE, ( "Could not extract the geometry named " + name ).c_str() );
		return;
	}
	
	FromHoudiniGeometryConverterPtr fromConverter = FromHoudiniGeometryConverter::create( handle );
	if ( !fromConverter )
	{
		addError( SOP_MESSAGE, ( "Could not convert the geometry named " + name ).c_str() );
		return;
	}
	
	IECore::ObjectPtr result = fromConverter->convert();
	if ( !result )
	{
		addError( SOP_MESSAGE, ( "Could not find Cortex Object named " + name + " on input geometry" ).c_str() );
		return;
	}
	
	if ( IECore::ParameterisedProcedural *procedural = IECore::runTimeCast<IECore::ParameterisedProcedural>( result.get() ) )
	{
		IECore::CapturingRendererPtr renderer = new IECore::CapturingRenderer();
		// We are acquiring and releasing the GIL here to ensure that it is released when we render. This has
		// to be done because a procedural might jump between c++ and python a few times (i.e. if it spawns
		// subprocedurals that are implemented in python). In a normal call to cookMySop, this wouldn't be an
		// issue, but if cookMySop was called from HOM, hou.Node.cook appears to be holding onto the GIL.
		IECorePython::ScopedGILLock gilLock;
		{
			IECorePython::ScopedGILRelease gilRelease;
			{
				IECore::WorldBlock worldBlock( renderer );
				procedural->render( renderer.get() );
			}
		}
		
		result = boost::const_pointer_cast<IECore::Object>( IECore::runTimeCast<const IECore::Object>( renderer->world() ) );
	}
	
	ToHoudiniGeometryConverterPtr converter = ( type == Cortex ) ? new ToHoudiniCortexObjectConverter( result.get() ) : ToHoudiniGeometryConverter::create( result.get() );
	converter->nameParameter()->setTypedValue( name );
	converter->attributeFilterParameter()->setTypedValue( attributeFilter );
	converter->convertStandardAttributesParameter()->setTypedValue( convertStandardAttributes );
	
	if ( !converter->convert( myGdpHandle ) )
	{
		addError( SOP_MESSAGE, ( "Could not convert the Cortex Object named " + name + " to Houdini geometry" ).c_str() );
	}
}
예제 #2
0
GU_DetailHandle LiveScene::contentHandle() const
{
	std::string name;
	SceneInterface::Path path;
	relativeContentPath( path );
	pathToString( path, name );
	
	GU_DetailHandle handle = m_splitter->split( name.c_str() );
	
	// we need to try again, in case the user didn't use a / prefix on the shape name
	if ( handle.isNull() && m_contentIndex == 1 && !path.empty() && path[0] != "" )
	{
		handle = m_splitter->split( &name.c_str()[1] );
	}
	
	return handle;
}
예제 #3
0
void SOP_CortexConverter::doPassThrough( const GU_DetailHandle &handle, const std::string &name )
{
	if ( handle.isNull() )
	{
		addError( SOP_MESSAGE, ( "Could not pass through the geometry named " + name ).c_str() );
		return;
	}
	
	GU_DetailHandleAutoReadLock readHandle( handle );
	const GU_Detail *inputGeo = readHandle.getGdp();
	if ( !inputGeo )
	{
		addError( SOP_MESSAGE, ( "Could not pass through the geometry named " + name ).c_str() );
		return;
	}
	
	gdp->merge( *inputGeo );
}
예제 #4
0
ConstObjectPtr HoudiniScene::readObject( double time ) const
{
	OBJ_Node *objNode = retrieveNode( true )->castToOBJNode();
	if ( !objNode )
	{
		return 0;
	}
	
	if ( objNode->getObjectType() == OBJ_GEOMETRY )
	{
		OP_Context context( time );
		GU_DetailHandle handle = objNode->getRenderGeometryHandle( context, false );
		
		if ( !m_splitter || ( handle != m_splitter->handle() ) )
		{
			m_splitter = new DetailSplitter( handle );
		}
		
		GU_DetailHandle newHandle = m_splitter->split( contentPathValue() );
		FromHoudiniGeometryConverterPtr converter = FromHoudiniGeometryConverter::create( ( newHandle.isNull() ) ? handle : newHandle );
		if ( !converter )
		{
			return 0;
		}
		
		return converter->convert();
	}
	
	/// \todo: need to account for cameras and lights
	
	return 0;
}
예제 #5
0
void HoudiniScene::readTags( NameList &tags, bool includeChildren ) const
{
	tags.clear();
	
	const OP_Node *node = retrieveNode();
	if ( !node )
	{
		return;
	}
	
	// add user supplied tags if we're not inside a SOP
	if ( !m_contentIndex && node->hasParm( pTags.getToken() ) )
	{
		UT_String parmTagStr;
		node->evalString( parmTagStr, pTags.getToken(), 0, 0 );
		if ( !parmTagStr.equal( UT_String::getEmptyString() ) )
		{
			UT_WorkArgs tokens;
			parmTagStr.tokenize( tokens, " " );
			for ( int i = 0; i < tokens.getArgc(); ++i )
			{
				tags.push_back( tokens[i] );
			}
		}
	}
	
	// add tags from the registered tag readers
	std::vector<CustomTagReader> &tagReaders = customTagReaders();
	for ( std::vector<CustomTagReader>::const_iterator it = tagReaders.begin(); it != tagReaders.end(); ++it )
	{
		NameList values;
		it->m_read( node, values, includeChildren );
		tags.insert( tags.end(), values.begin(), values.end() );
	}
	
	// add tags based on primitive groups
	OBJ_Node *contentNode = retrieveNode( true )->castToOBJNode();
	if ( contentNode && contentNode->getObjectType() == OBJ_GEOMETRY && m_splitter )
	{
		GU_DetailHandle newHandle = m_splitter->split( contentPathValue() );
		if ( !newHandle.isNull() )
		{
			GU_DetailHandleAutoReadLock readHandle( newHandle );
			if ( const GU_Detail *geo = readHandle.getGdp() )
			{
				GA_Range prims = geo->getPrimitiveRange();
				for ( GA_GroupTable::iterator<GA_ElementGroup> it=geo->primitiveGroups().beginTraverse(); !it.atEnd(); ++it )
				{
					GA_PrimitiveGroup *group = static_cast<GA_PrimitiveGroup*>( it.group() );
					if ( group->getInternal() || group->isEmpty() )
					{
						continue;
					}
					
					const UT_String &groupName = group->getName();
					if ( groupName.startsWith( tagGroupPrefix ) && group->containsAny( prims ) )
					{
						UT_String tag;
						groupName.substr( tag, tagGroupPrefix.length() );
						tag.substitute( "_", ":" );
						tags.push_back( tag.buffer() );
					}
				}
			}
		}
	}
}
예제 #6
0
bool HoudiniScene::hasTag( const Name &name, bool includeChildren ) const
{
	const OP_Node *node = retrieveNode();
	if ( !node )
	{
		return false;
	}
	
	// check for user supplied tags if we're not inside a SOP
	if ( !m_contentIndex && node->hasParm( pTags.getToken() ) )
	{
		UT_String parmTags;
		node->evalString( parmTags, pTags.getToken(), 0, 0 );
		if ( UT_String( name.c_str() ).multiMatch( parmTags ) )
		{
			return true;
		}
	}
	
	// check with the registered tag readers
	std::vector<CustomTagReader> &tagReaders = customTagReaders();
	for ( std::vector<CustomTagReader>::const_iterator it = tagReaders.begin(); it != tagReaders.end(); ++it )
	{
		if ( it->m_has( node, name ) )
		{
			return true;
		}
	}
	
	// check tags based on primitive groups
	OBJ_Node *contentNode = retrieveNode( true )->castToOBJNode();
	if ( contentNode && contentNode->getObjectType() == OBJ_GEOMETRY && m_splitter )
	{
		GU_DetailHandle newHandle = m_splitter->split( contentPathValue() );
		if ( !newHandle.isNull() )
		{
			GU_DetailHandleAutoReadLock readHandle( newHandle );
			if ( const GU_Detail *geo = readHandle.getGdp() )
			{
				GA_Range prims = geo->getPrimitiveRange();
				for ( GA_GroupTable::iterator<GA_ElementGroup> it=geo->primitiveGroups().beginTraverse(); !it.atEnd(); ++it )
				{
					GA_PrimitiveGroup *group = static_cast<GA_PrimitiveGroup*>( it.group() );
					if ( group->getInternal() || group->isEmpty() )
					{
						continue;
					}
					
					const UT_String &groupName = group->getName();
					if ( groupName.startsWith( tagGroupPrefix ) && group->containsAny( prims ) )
					{
						UT_String tag;
						groupName.substr( tag, tagGroupPrefix.length() );
						tag.substitute( "_", ":" );
						if ( tag.equal( name.c_str() ) )
						{
							return true;
						}
					}
				}
			}
		}
	}
	
	return false;
}
ObjectPtr FromHoudiniGroupConverter::doConversion( ConstCompoundObjectPtr operands ) const
{
	GroupPtr result = new Group();
	
	if ( operands->member<const IntData>( "groupingMode" )->readable() == NameAttribute )
	{
		DetailSplitterPtr splitter = new DetailSplitter( handle() );
		std::vector<std::string> children;
		splitter->values( children );
		
		if ( children.empty() )
		{
			doUnnamedConversion( GU_DetailHandleAutoReadLock( handle() ).getGdp(), result, operands );
			return result;
		}
		
		for ( std::vector<std::string>::iterator it = children.begin(); it != children.end(); ++it )
		{
			const std::string &name = *it;
			GU_DetailHandle childHandle = splitter->split( name );
			if ( childHandle.isNull() )
			{
				continue;
			}
			
			GU_DetailHandleAutoReadLock readHandle( childHandle );
			const GU_Detail *childGeo = readHandle.getGdp();
			ObjectPtr child = doDetailConversion( childGeo, operands );
			if ( !child )
			{
				// this happens when mismatched primitives share the same name
				doUnnamedConversion( childGeo, result, operands, name );
			}
			else if ( VisibleRenderablePtr renderable = IECore::runTimeCast<VisibleRenderable>( child ) )
			{
				if ( name != "" )
				{
					renderable->blindData()->member<StringData>( "name", false, true )->writable() = name;
				}
				
				result->addChild( renderable );
			}
		}
	}
	else
	{
		GU_DetailHandleAutoReadLock readHandle( handle() );
		const GU_Detail *geo = readHandle.getGdp();
		if ( !geo )
		{
			return 0;
		}

		size_t numResultPrims = 0;
		size_t numOrigPrims = geo->getNumPrimitives();

		for ( GA_GroupTable::iterator<GA_ElementGroup> it=geo->primitiveGroups().beginTraverse(); !it.atEnd(); ++it )
		{
			GA_PrimitiveGroup *group = static_cast<GA_PrimitiveGroup*>( it.group() );
			if ( group->getInternal() || group->isEmpty() )
			{
				continue;
			}

			VisibleRenderablePtr renderable = 0;
			numResultPrims += doGroupConversion( geo, group, renderable, operands );
			if( !renderable )
			{
				continue;
			}
			
			renderable->blindData()->member<StringData>( "name", false, true )->writable() = group->getName().toStdString();
			result->addChild( renderable );
		}

		if ( numOrigPrims == numResultPrims )
		{
			return result;
		}

		GU_Detail ungroupedGeo( (GU_Detail*)geo );
		GA_PrimitiveGroup *ungrouped = static_cast<GA_PrimitiveGroup*>( ungroupedGeo.createInternalElementGroup( GA_ATTRIB_PRIMITIVE, "FromHoudiniGroupConverter__ungroupedPrimitives" ) );
		for ( GA_GroupTable::iterator<GA_ElementGroup> it=geo->primitiveGroups().beginTraverse(); !it.atEnd(); ++it )
		{
			*ungrouped |= *static_cast<GA_PrimitiveGroup*>( it.group() );
		}
		ungrouped->toggleRange( ungroupedGeo.getPrimitiveRange() );

		if ( ungrouped->isEmpty() )
		{
			return result;
		}

		VisibleRenderablePtr renderable = 0;
		doGroupConversion( &ungroupedGeo, ungrouped, renderable, operands );
		if ( renderable )
		{
			result->addChild( renderable );
		}
	}
	
	return result;
}