ConstObjectPtr SceneShape::readSceneShapeAttribute( const MDagPath &p, SceneInterface::Name attributeName ) { MDagPath dagPath; SceneShape *sceneShape = findScene( p, false, &dagPath ); if ( !sceneShape ) { return 0; } MFnDagNode fnChildDag( dagPath ); if( attributeName == LinkedScene::linkAttribute ) { if( !fnChildDag.isIntermediateObject() ) { return readSceneShapeLink(p); } } ConstSceneInterfacePtr scene = sceneShape->getSceneInterface(); if ( !scene ) { return 0; } MPlug timePlug = fnChildDag.findPlug( aTime ); MTime time; timePlug.getValue( time ); return scene->readAttribute( attributeName, time.as( MTime::kSeconds ) ); }
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 ); } }
void SceneCacheNode<BaseType>::buildShapeFilterMenu( 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; } std::vector<std::string> objects; node->objectNames( scene.get(), objects ); std::sort( objects.begin(), objects.end() ); node->createMenu( menu, objects ); }
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; }
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 ); } }
ConstSceneInterfacePtr SceneCacheNode<BaseType>::scene( const std::string &fileName, const std::string &path ) { ConstSceneInterfacePtr result = 0; try { result = SharedSceneInterfaces::get( fileName ); if ( path != SceneInterface::rootName.string() ) { SceneInterface::Path p; SceneInterface::stringToPath( path, p ); result = result->scene( p, SceneInterface::NullIfMissing ); } } catch ( std::exception &e ) { std::cerr << "Error loading \"" << fileName << "\" at location \"" << path << "\": " << e.what() << std::endl; } catch ( ... ) { std::cerr << "Unknown error loading \"" << fileName << "\" at location \"" << path << "\": " << std::endl; } return result; }
Imath::Box3d HoudiniScene::readBound( double time ) const { OP_Node *node = retrieveNode( true ); Imath::Box3d bounds; UT_BoundingBox box; OP_Context context( time ); /// \todo: this doesn't account for SOPs containing multiple shapes /// if we fix it, we need to fix the condition below as well if ( node->getBoundingBox( box, context ) ) { bounds = IECore::convert<Imath::Box3d>( box ); } // paths embedded within a sop already have bounds accounted for if ( m_contentIndex ) { return bounds; } NameList children; childNames( children ); for ( NameList::iterator it=children.begin(); it != children.end(); ++it ) { ConstSceneInterfacePtr childScene = child( *it ); Imath::Box3d childBound = childScene->readBound( time ); if ( !childBound.isEmpty() ) { bounds.extendBy( Imath::transform( childBound, childScene->readTransformAsMatrix( time ) ) ); } } return bounds; }
ConstSceneInterfacePtr LinkedScene::expandLink( const StringData *fileName, const InternedStringVectorData *root, int &linkDepth ) { if ( fileName && root ) { ConstSceneInterfacePtr l = 0; try { l = SharedSceneInterfaces::get( fileName->readable() ); } catch ( IECore::Exception &e ) { IECore::msg( IECore::MessageHandler::Error, "LinkedScene::expandLink", std::string( e.what() ) + " when expanding link from file \"" + m_mainScene->fileName() + "\"" ); linkDepth = 0; return 0; } linkDepth = root->readable().size(); l = l->scene(root->readable(), NullIfMissing); if ( !l ) { // \todo Consider throwing or printing error message. linkDepth = 0; } return l; } linkDepth = 0; return 0; }
OP_ERROR SOP_SceneCacheSource::cookMySop( OP_Context &context ) { flags().setTimeDep( true ); std::string file; if ( !ensureFile( file ) ) { addError( SOP_ATTRIBUTE_INVALID, ( file + " is not a valid .scc" ).c_str() ); gdp->clearAndDestroy(); return error(); } std::string path = getPath(); Space space = getSpace(); UT_String shapeFilterStr; evalString( shapeFilterStr, pShapeFilter.getToken(), 0, 0 ); UT_StringMMPattern shapeFilter; shapeFilter.compile( shapeFilterStr ); UT_String p( "P" ); UT_String attributeFilter; evalString( attributeFilter, pAttributeFilter.getToken(), 0, 0 ); if ( !p.match( attributeFilter ) ) { attributeFilter += " P"; } ConstSceneInterfacePtr scene = this->scene( file, path ); if ( !scene ) { addError( SOP_ATTRIBUTE_INVALID, ( path + " is not a valid location in " + file ).c_str() ); gdp->clearAndDestroy(); return error(); } MurmurHash hash; hash.append( file ); hash.append( path ); hash.append( space ); hash.append( shapeFilterStr ); hash.append( attributeFilter ); if ( !m_loaded || m_hash != hash ) { gdp->clearAndDestroy(); } Imath::M44d transform = ( space == World ) ? worldTransform( file, path, context.getTime() ) : Imath::M44d(); SceneInterface::Path rootPath; scene->path( rootPath ); loadObjects( scene, transform, context.getTime(), space, shapeFilter, attributeFilter.toStdString(), rootPath.size() ); m_loaded = true; m_hash = hash; return error(); }
IECore::ConstCompoundObjectPtr SceneReader::computeGlobals( const Gaffer::Context *context, const ScenePlug *parent ) const { ConstSceneInterfacePtr s = scene( ScenePath() ); if( !s ) { return parent->globalsPlug()->defaultValue(); } CompoundObjectPtr result = new CompoundObject; // figure out which tags we want to convert into sets vector<InternedString> allTags; s->readTags( allTags, SceneInterface::LocalTag | SceneInterface::DescendantTag ); const std::string setsString = setsPlug()->getValue(); Tokenizer setsTokenizer( setsString, boost::char_separator<char>( " " ) ); vector<InternedString> tagsToLoadAsSets; for( vector<InternedString>::const_iterator tIt = allTags.begin(), tEIt = allTags.end(); tIt != tEIt; ++tIt ) { for( Tokenizer::const_iterator sIt = setsTokenizer.begin(), sEIt = setsTokenizer.end(); sIt != sEIt; ++sIt ) { if( match( tIt->value(), *sIt ) ) { tagsToLoadAsSets.push_back( *tIt ); } } } // sort so that we can use lower_bound() in loadSetsWalk(). sort( tagsToLoadAsSets.begin(), tagsToLoadAsSets.end() ); // make sets for each of them, and then defer to loadSetsWalk() // to do the work. IECore::CompoundDataPtr sets = result->member<IECore::CompoundData>( "gaffer:sets", /* throwExceptions = */ false, /* createIfMissing = */ true ); vector<PathMatcher *> pathMatchers; for( vector<InternedString>::const_iterator it = tagsToLoadAsSets.begin(), eIt = tagsToLoadAsSets.end(); it != eIt; ++it ) { PathMatcherDataPtr d = sets->member<PathMatcherData>( *it, /* throwExceptions = */ false, /* createIfMissing = */ true ); pathMatchers.push_back( &(d->writable()) ); } loadSetsWalk( s.get(), tagsToLoadAsSets, pathMatchers, vector<InternedString>() ); return result; }
IECore::ConstObjectPtr SceneReader::computeObject( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent ) const { ConstSceneInterfacePtr s = scene( path ); if( !s || !s->hasObject() ) { return parent->objectPlug()->defaultValue(); } return s->readObject( context->getTime() ); }
GafferScene::ConstPathMatcherDataPtr SceneReader::computeSet( const IECore::InternedString &setName, const Gaffer::Context *context, const ScenePlug *parent ) const { PathMatcherDataPtr result = new PathMatcherData; ConstSceneInterfacePtr rootScene = scene( ScenePath() ); if( rootScene ) { loadSetWalk( rootScene.get(), setName, result->writable(), ScenePath() ); } return result; }
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 ); } }
void SceneReader::hashBound( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent, IECore::MurmurHash &h ) const { FileSource::hashBound( path, context, parent, h ); ConstSceneInterfacePtr s = scene( path ); const SampledSceneInterface *ss = runTimeCast<const SampledSceneInterface>( s.get() ); if( !ss || ss->numBoundSamples() > 1 ) { h.append( context->getFrame() ); } }
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; }
ConstSceneInterfacePtr SceneCacheNode<BaseType>::scene( const std::string &fileName, const std::string &path ) { ConstSceneInterfacePtr result = SharedSceneInterfaces::get( fileName ); if ( path != SceneInterface::rootName.string() ) { SceneInterface::Path p; SceneInterface::stringToPath( path, p ); result = result->scene( p, SceneInterface::NullIfMissing ); } return result; }
IECore::ConstInternedStringVectorDataPtr SceneReader::computeSetNames( const Gaffer::Context *context, const ScenePlug *parent ) const { ConstSceneInterfacePtr s = scene( ScenePath() ); if( !s ) { return parent->setNamesPlug()->defaultValue(); } InternedStringVectorDataPtr result = new InternedStringVectorData(); s->readTags( result->writable(), SceneInterface::LocalTag | SceneInterface::DescendantTag ); return result; }
void SceneReader::hashTransform( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent, IECore::MurmurHash &h ) const { SceneNode::hashTransform( path, context, parent, h ); ConstSceneInterfacePtr s = scene( path ); if( !s ) { return; } refreshCountPlug()->hash( h ); s->hash( SceneInterface::TransformHash, context->getTime(), h ); }
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; }
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; } SceneNode::hashAttributes( path, context, parent, h ); refreshCountPlug()->hash( h ); s->hash( SceneInterface::AttributesHash, context->getTime(), h ); }
void SceneReader::hashObject( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent, IECore::MurmurHash &h ) const { ConstSceneInterfacePtr s = scene( path ); if( !s || !s->hasObject() ) { // no object h = parent->objectPlug()->defaultValue()->hash(); return; } SceneNode::hashObject( path, context, parent, h ); refreshCountPlug()->hash( h ); s->hash( SceneInterface::ObjectHash, context->getTime(), h ); }
IECore::ConstInternedStringVectorDataPtr SceneReader::computeChildNames( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent ) const { std::string fileName = fileNamePlug()->getValue(); if( !fileName.size() ) { return parent->childNamesPlug()->defaultValue(); } ConstSceneInterfacePtr s = SharedSceneInterfaces::get( fileName ); s = s->scene( path ); InternedStringVectorDataPtr result = new InternedStringVectorData; s->childNames( result->writable() ); return result; }
Imath::Box3f SceneReader::computeBound( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent ) const { ConstSceneInterfacePtr s = scene( path ); if( !s ) { return Box3f(); } Box3d b = s->readBound( context->getFrame() / g_frameRate ); if( b.isEmpty() ) { return Box3f(); } return Box3f( b.min, b.max ); }
void SceneReader::hashObject( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent, IECore::MurmurHash &h ) const { ConstSceneInterfacePtr s = scene( path ); if( !s || !s->hasObject() ) { // no object h = parent->objectPlug()->defaultValue()->hash(); return; } FileSource::hashObject( path, context, parent, h ); const SampledSceneInterface *ss = runTimeCast<const SampledSceneInterface>( s.get() ); if( !ss || ss->numObjectSamples() > 1 ) { h.append( context->getFrame() ); } }
Imath::M44f SceneReader::computeTransform( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent ) const { ConstSceneInterfacePtr s = scene( path ); if( !s ) { return M44f(); } M44d t = s->readTransformAsMatrix( context->getTime() ); return M44f( t[0][0], t[0][1], t[0][2], t[0][3], t[1][0], t[1][1], t[1][2], t[1][3], t[2][0], t[2][1], t[2][2], t[2][3], t[3][0], t[3][1], t[3][2], t[3][3] ); }
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() ); } }
void OBJ_SceneCacheTransform::readTags( const OP_Node *node, SceneInterface::NameList &tags, int filter ) { // make sure its a SceneCacheNode if ( !node->hasParm( pFile.getToken() ) || !node->hasParm( pRoot.getToken() ) ) { return; } const SceneCacheNode<OP_Node> *sceneNode = reinterpret_cast< const SceneCacheNode<OP_Node>* >( node ); /// \todo: do we need to ensure the file exists first? ConstSceneInterfacePtr scene = OBJ_SceneCacheTransform::scene( sceneNode->getFile(), sceneNode->getPath() ); if ( !scene ) { return; } scene->readTags( tags, filter ); }
void SceneReader::hashChildNames( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent, IECore::MurmurHash &h ) const { ConstSceneInterfacePtr s = scene( path ); if( !s ) { h = parent->childNamesPlug()->defaultValue()->Object::hash(); return; } SceneNode::hashChildNames( path, context, parent, h ); refreshCountPlug()->hash( h ); // append a hash of the tags plug, as restricting the tags can affect the hierarchy tagsPlug()->hash( h ); s->hash( SceneInterface::ChildNamesHash, context->getTime(), h ); }
LinkedScene::LinkedScene( ConstSceneInterfacePtr mainScene ) : m_mainScene(const_cast<SceneInterface*>(mainScene.get())), m_linkedScene(0), m_rootLinkDepth(0), m_readOnly(true), m_atLink(false), m_timeRemapped(false) { if( SceneCachePtr scc = runTimeCast<SceneCache>( m_mainScene ) ) { m_readOnly = scc->readOnly(); } m_sampled = (runTimeCast<const SampledSceneInterface>(mainScene.get()) != NULL); }
ConstObjectPtr SceneShape::readSceneShapeLink( const MDagPath &p ) { MDagPath dagPath; SceneShape *sceneShape = findScene( p, true, &dagPath ); if ( !sceneShape ) { throw Exception("readSceneShapeLink: Could not find SceneShape!"); } ConstSceneInterfacePtr scene = sceneShape->getSceneInterface(); if ( !scene ) { throw Exception( "Empty scene!"); } MFnDagNode fnChildDag( dagPath ); MStatus st; MPlug timePlug = fnChildDag.findPlug( aTime, &st ); if( !st ) { throw Exception( "Could not find 'time' plug in SceneShape!"); } // if time plug is connected to maya global time, then we assume there's no time remapping between the Maya scene and the loaded scene. MPlugArray array; timePlug.connectedTo( array, true, false, &st ); if( !st ) { throw Exception( "Could not find 'time' plug connections in SceneShape!"); } for ( unsigned int i = 0; i < array.length(); i++ ) { if ( array[i].name() == "time1.outTime" ) { /// connected to time, so no time remapping between maya scene and loaded scene. return LinkedScene::linkAttributeData( scene.get() ); } } /// couldn't find connection to maya time, so this node is mapping the time some other way. MTime time; timePlug.getValue( time ); return LinkedScene::linkAttributeData( scene.get(), time.as( MTime::kSeconds ) ); }