OP_Node *HoudiniScene::retrieveNode( bool content, MissingBehaviour missingBehaviour ) const { OP_Node *node = OPgetDirector()->findNode( m_nodePath ); if ( node && content ) { if ( OP_Node *contentNode = locateContent( node ) ) { node = contentNode; } } if ( missingBehaviour == ThrowIfMissing ) { if ( !node ) { throw Exception( "IECoreHoudini::HoudiniScene: Node \"" + m_nodePath.toStdString() + "\" no longer exists." ); } if ( !node->isManager() && !node->castToOBJNode() ) { throw Exception( "IECoreHoudini::HoudiniScene: Node \"" + m_nodePath.toStdString() + "\" is not a valid OBJ." ); } } return node; }
Imath::M44d HoudiniScene::readTransformAsMatrix( double time ) const { OP_Node *node = retrieveNode(); if ( node->isManager() ) { return Imath::M44d(); } OBJ_Node *objNode = node->castToOBJNode(); if ( !objNode ) { return Imath::M44d(); } // paths embedded within a sop always have identity transforms if ( m_contentIndex ) { return Imath::M44d(); } UT_DMatrix4 matrix; OP_Context context( time ); if ( !objNode->getLocalTransform( context, matrix ) ) { return Imath::M44d(); } return IECore::convert<Imath::M44d>( matrix ); }
bool HoudiniScene::hasObject() const { OP_Node *node = retrieveNode( true ); if ( node->isManager() ) { return false; } OBJ_Node *objNode = node->castToOBJNode(); if ( !objNode ) { return false; } OBJ_OBJECT_TYPE type = objNode->getObjectType(); if ( type == OBJ_GEOMETRY ) { OP_Context context( getDefaultTime() ); const GU_Detail *geo = objNode->getRenderGeometry( context, false ); // multiple named shapes define children that contain each object /// \todo: similar attribute logic is repeated in several places. unify in a single function if possible GA_ROAttributeRef nameAttrRef = geo->findStringTuple( GA_ATTRIB_PRIMITIVE, "name" ); if ( !nameAttrRef.isValid() ) { return true; } const GA_Attribute *nameAttr = nameAttrRef.getAttribute(); const GA_AIFSharedStringTuple *tuple = nameAttr->getAIFSharedStringTuple(); GA_Size numShapes = tuple->getTableEntries( nameAttr ); if ( !numShapes ) { return true; } for ( GA_Size i=0; i < numShapes; ++i ) { const char *currentName = tuple->getTableString( nameAttr, tuple->validateTableHandle( nameAttr, i ) ); const char *match = matchPath( currentName ); if ( match && *match == *emptyString ) { // exact match return true; } } return false; } /// \todo: need to account for OBJ_CAMERA and OBJ_LIGHT return false; }
Imath::M44d LiveScene::readWorldTransformAsMatrix( double time ) const { OP_Node *node = retrieveNode(); if ( node->isManager() ) { return Imath::M44d(); } OBJ_Node *objNode = node->castToOBJNode(); if ( !objNode ) { return Imath::M44d(); } UT_DMatrix4 matrix; OP_Context context( adjustTime( time ) ); if ( !objNode->getWorldTransform( matrix, context ) ) { return Imath::M44d(); } return IECore::convert<Imath::M44d>( matrix ); }
OP_Node *HoudiniScene::retrieveChild( const Name &name, Path &contentPath, MissingBehaviour missingBehaviour ) const { OP_Node *node = retrieveNode( false, missingBehaviour ); OP_Node *contentBaseNode = retrieveNode( true, missingBehaviour ); if ( !node || !contentBaseNode ) { return 0; } OBJ_Node *objNode = node->castToOBJNode(); OBJ_Node *contentNode = contentBaseNode->castToOBJNode(); // check subnet children if ( node->isManager() || ( objNode && objNode->getObjectType() == OBJ_SUBNET ) ) { for ( int i=0; i < node->getNchildren(); ++i ) { OP_Node *child = node->getChild( i ); // the contentNode is actually an extension of ourself if ( child == contentNode ) { continue; } if ( child->getName().equal( name.c_str() ) && !hasInput( child ) ) { return child; } } } if ( contentNode ) { // check connected outputs for ( unsigned i=0; i < contentNode->nOutputs(); ++i ) { OP_Node *child = contentNode->getOutput( i ); if ( child->getName().equal( name.c_str() ) ) { return child; } } // check child shapes within the geo if ( contentNode->getObjectType() == OBJ_GEOMETRY ) { OP_Context context( getDefaultTime() ); const GU_Detail *geo = contentNode->getRenderGeometry( context, false ); GA_ROAttributeRef nameAttrRef = geo->findStringTuple( GA_ATTRIB_PRIMITIVE, "name" ); if ( nameAttrRef.isValid() ) { const GA_Attribute *nameAttr = nameAttrRef.getAttribute(); const GA_AIFSharedStringTuple *tuple = nameAttr->getAIFSharedStringTuple(); GA_Size numShapes = tuple->getTableEntries( nameAttr ); for ( GA_Size i=0; i < numShapes; ++i ) { const char *currentName = tuple->getTableString( nameAttr, tuple->validateTableHandle( nameAttr, i ) ); const char *match = matchPath( currentName ); if ( match && *match != *emptyString ) { std::pair<const char *, size_t> childMarker = nextWord( match ); std::string child( childMarker.first, childMarker.second ); if ( name == child ) { size_t contentSize = ( m_contentIndex ) ? m_path.size() - m_contentIndex : 0; if ( contentSize ) { contentPath.resize( contentSize ); std::copy( m_path.begin() + m_contentIndex, m_path.end(), contentPath.begin() ); } contentPath.push_back( name ); return contentNode; } } } } } } if ( missingBehaviour == SceneInterface::ThrowIfMissing ) { Path p; path( p ); std::string pStr; pathToString( p, pStr ); throw Exception( "IECoreHoudini::HoudiniScene::retrieveChild: Path \"" + pStr + "\" has no child named " + name.string() + "." ); } return 0; }
void HoudiniScene::childNames( NameList &childNames ) const { OP_Node *node = retrieveNode(); OBJ_Node *objNode = node->castToOBJNode(); OBJ_Node *contentNode = retrieveNode( true )->castToOBJNode(); // add subnet children if ( node->isManager() || ( objNode && objNode->getObjectType() == OBJ_SUBNET ) ) { for ( int i=0; i < node->getNchildren(); ++i ) { OP_Node *child = node->getChild( i ); // ignore children that have incoming connections, as those are actually grandchildren // also ignore the contentNode, which is actually an extension of ourself if ( child != contentNode && !hasInput( child ) ) { childNames.push_back( Name( child->getName() ) ); } } } if ( !contentNode ) { return; } // add connected outputs for ( unsigned i=0; i < contentNode->nOutputs(); ++i ) { childNames.push_back( Name( contentNode->getOutput( i )->getName() ) ); } // add child shapes within the geometry if ( contentNode->getObjectType() == OBJ_GEOMETRY ) { OP_Context context( getDefaultTime() ); const GU_Detail *geo = contentNode->getRenderGeometry( context, false ); GA_ROAttributeRef nameAttrRef = geo->findStringTuple( GA_ATTRIB_PRIMITIVE, "name" ); if ( !nameAttrRef.isValid() ) { return; } const GA_Attribute *nameAttr = nameAttrRef.getAttribute(); const GA_AIFSharedStringTuple *tuple = nameAttr->getAIFSharedStringTuple(); GA_Size numShapes = tuple->getTableEntries( nameAttr ); for ( GA_Size i=0; i < numShapes; ++i ) { const char *currentName = tuple->getTableString( nameAttr, tuple->validateTableHandle( nameAttr, i ) ); const char *match = matchPath( currentName ); if ( match && *match != *emptyString ) { std::pair<const char *, size_t> childMarker = nextWord( match ); std::string child( childMarker.first, childMarker.second ); if ( std::find( childNames.begin(), childNames.end(), child ) == childNames.end() ) { childNames.push_back( child ); } } } } }
void HoudiniScene::calculatePath( const Path &contentPath, const Path &rootPath ) { OP_Node *node = retrieveNode(); if ( node->isManager() ) { return; } UT_String tmp( m_nodePath ); UT_WorkArgs workArgs; tmp.tokenize( workArgs, "/" ); OP_Node *current = dynamic_cast<MOT_Director *>( OPgetDirector() )->getObjectManager(); // skipping the token for the OBJ manager for ( int i = 1; i < workArgs.getArgc(); ++i ) { current = current->getChild( workArgs[i] ); /// recursively collect all input connections OP_Node *parent = current->getInput( 0 ); UT_StringArray parentNames; while ( parent ) { parentNames.append( parent->getName() ); parent = parent->getInput( 0 ); } // add them in reverse order for ( int j = parentNames.entries() - 1; j >= 0; --j ) { m_path.push_back( Name( parentNames( j ) ) ); } if ( ( i < workArgs.getArgc() - 1 ) || Name( workArgs[i] ) != contentName ) { m_path.push_back( Name( workArgs[i] ) ); } } if ( !contentPath.empty() ) { m_contentIndex = m_path.size(); m_path.resize( m_path.size() + contentPath.size() ); std::copy( contentPath.begin(), contentPath.end(), m_path.begin() + m_contentIndex ); } if ( m_path.size() < rootPath.size() ) { std::string pStr, rStr; pathToString( m_path, pStr ); pathToString( rootPath, rStr ); throw Exception( "IECoreHoudini::HoudiniScene: Path \"" + pStr + "\" is not a valid child of root \"" + rStr + "\"." ); } for ( size_t i = 0; i < rootPath.size(); ++i ) { if ( rootPath[i] != m_path[i] ) { std::string pStr, rStr; pathToString( m_path, pStr ); pathToString( rootPath, rStr ); throw Exception( "IECoreHoudini::HoudiniScene: Path \"" + pStr + "\" is not a valid child of root \"" + rStr + "\"." ); } } m_rootIndex = rootPath.size(); }