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() ); } }
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; }
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 ); }
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; }
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() ); } } } } } }
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; }