void Expression::addPlug( ValuePlug *parentPlug, const std::string &plugPath ) { Node *p = parent<Node>(); if( !p ) { throw IECore::Exception( "No parent" ); } ValuePlug *plug = p->descendant<ValuePlug>( plugPath ); if( !plug ) { throw IECore::Exception( boost::str( boost::format( "Plug \"%s\" does not exist" ) % plugPath ) ); } PlugPtr childPlug = plug->createCounterpart( "p0", parentPlug->direction() ); childPlug->setFlags( Plug::Dynamic, true ); parentPlug->addChild( childPlug ); if( childPlug->direction() == Plug::In ) { childPlug->setInput( plug ); } else { plug->setInput( childPlug ); } }
bool ValuePlug::settable() const { if( getFlags( ReadOnly ) ) { return false; } if( getInput<Plug>() ) { return false; } if( const Process *process = Process::current() ) { return process->type() == ComputeProcess::staticType && process->plug() == this; } else { if( direction() != Plug::In ) { return false; } for( PlugIterator it( this ); !it.done(); ++it ) { ValuePlug *valuePlug = IECore::runTimeCast<ValuePlug>( it->get() ); if( !valuePlug || !valuePlug->settable() ) { return false; } } return true; } }
void CompoundPlug::setToDefault() { ChildContainer::const_iterator it; for( it=children().begin(); it!=children().end(); it++ ) { ValuePlug *valuePlug = IECore::runTimeCast<ValuePlug>( it->get() ); if( valuePlug ) { valuePlug->setToDefault(); } } }
bool CompoundPlug::settable() const { ChildContainer::const_iterator it, eIt; for( it=children().begin(), eIt=children().end(); it!=eIt; ++it ) { ValuePlug *valuePlug = IECore::runTimeCast<ValuePlug>( it->get() ); if( !valuePlug || !valuePlug->settable() ) { return false; } } return true; }
void Expression::updatePlugs( const std::string &dstPlugPath, std::vector<std::string> &srcPlugPaths ) { Node *p = parent<Node>(); // if the expression was invalid, remove our plugs if( !dstPlugPath.size() ) { Plug *in = getChild<Plug>( "in" ); if( in ) { removeChild( in ); } Plug *out = getChild<Plug>( "out" ); if( out ) { removeChild( out ); } return; } // otherwise try to create connections to the plugs the expression wants ValuePlug *dstPlug = p->descendant<ValuePlug>( dstPlugPath ); if( !dstPlug ) { throw IECore::Exception( boost::str( boost::format( "Destination plug \"%s\" does not exist" ) % dstPlugPath ) ); } CompoundPlugPtr inPlugs = new CompoundPlug( "in", Plug::In, Plug::Default | Plug::Dynamic ); setChild( "in", inPlugs ); for( std::vector<std::string>::const_iterator it = srcPlugPaths.begin(); it!=srcPlugPaths.end(); it++ ) { ValuePlug *srcPlug = p->descendant<ValuePlug>( *it ); if( !srcPlug ) { throw IECore::Exception( boost::str( boost::format( "Source plug \"%s\" does not exist" ) % *it ) ); } PlugPtr inPlug = srcPlug->createCounterpart( "plug", Plug::In ); inPlugs->addChild( inPlug ); inPlug->setInput( srcPlug ); } PlugPtr outPlug = dstPlug->createCounterpart( "out", Plug::Out ); setChild( "out", outPlug ); dstPlug->setInput( outPlug ); }
void ValuePlug::setFrom( const ValuePlug *other ) { const ValuePlug *typedOther = IECore::runTimeCast<const ValuePlug>( other ); if( !typedOther ) { throw IECore::Exception( "Unsupported plug type" ); } ChildContainer::const_iterator it, otherIt; for( it = children().begin(), otherIt = typedOther->children().begin(); it!=children().end() && otherIt!=typedOther->children().end(); it++, otherIt++ ) { ValuePlug *child = IECore::runTimeCast<ValuePlug>( it->get() ); const ValuePlug *otherChild = IECore::runTimeCast<ValuePlug>( otherIt->get() ); if( !child || !otherChild ) { throw IECore::Exception( "Children are not ValuePlugs" ); } child->setFrom( otherChild ); } }
static void transferConnectionOrValue( Plug *sourcePlug, Plug *destinationPlug ) { if( !sourcePlug ) { return; } if( Plug *input = sourcePlug->getInput<Plug>() ) { destinationPlug->setInput( input ); } else { ValuePlug *sourceValuePlug = runTimeCast<ValuePlug>( sourcePlug ); ValuePlug *destinationValuePlug = runTimeCast<ValuePlug>( destinationPlug ); if( destinationValuePlug && sourceValuePlug ) { destinationValuePlug->setFrom( sourceValuePlug ); } } }
void Reference::load( const std::string &fileName ) { ScriptNode *script = scriptNode(); if( !script ) { throw IECore::Exception( "Reference::load called without ScriptNode" ); } // if we're doing a reload, then we want to maintain any values and // connections that our external plugs might have. but we also need to // get those existing plugs out of the way during the load, so that the // incoming plugs don't get renamed. std::map<std::string, Plug *> previousPlugs; for( PlugIterator it( this ); it != it.end(); ++it ) { Plug *plug = it->get(); if( isReferencePlug( plug ) ) { previousPlugs[plug->getName()] = plug; plug->setName( "__tmp__" + plug->getName().string() ); } } for( PlugIterator it( userPlug() ); it != it.end(); ++it ) { Plug *plug = it->get(); previousPlugs[plug->relativeName( this )] = plug; plug->setName( "__tmp__" + plug->getName().string() ); } // if we're doing a reload, then we also need to delete all our child // nodes to make way for the incoming nodes. int i = (int)(children().size()) - 1; while( i >= 0 ) { if( Node *node = getChild<Node>( i ) ) { removeChild( node ); } i--; } // load the reference. we use continueOnError=true to get everything possible // loaded, but if any errors do occur we throw an exception at the end of this // function. this means that the caller is still notified of errors via the // exception mechanism, but we leave ourselves in the best state possible for // the case where ScriptNode::load( continueOnError = true ) will ignore the // exception that we throw. const bool errors = script->executeFile( fileName, this, /* continueOnError = */ true ); fileNamePlug()->setValue( fileName ); // transfer connections and values from the old plugs onto the corresponding new ones. for( std::map<std::string, Plug *>::const_iterator it = previousPlugs.begin(), eIt = previousPlugs.end(); it != eIt; ++it ) { Plug *oldPlug = it->second; Plug *newPlug = descendant<Plug>( it->first ); if( newPlug ) { try { if( newPlug->direction() == Plug::In && oldPlug->direction() == Plug::In ) { if( Plug *oldInput = oldPlug->getInput<Plug>() ) { newPlug->setInput( oldInput ); } else { ValuePlug *oldValuePlug = runTimeCast<ValuePlug>( oldPlug ); ValuePlug *newValuePlug = runTimeCast<ValuePlug>( newPlug ); if( oldValuePlug && newValuePlug ) { newValuePlug->setFrom( oldValuePlug ); } } } else if( newPlug->direction() == Plug::Out && oldPlug->direction() == Plug::Out ) { for( Plug::OutputContainer::const_iterator oIt = oldPlug->outputs().begin(), oeIt = oldPlug->outputs().end(); oIt != oeIt; ) { Plug *outputPlug = *oIt; ++oIt; // increment now because the setInput() call invalidates our iterator. outputPlug->setInput( newPlug ); } } } catch( const std::exception &e ) { msg( Msg::Warning, boost::str( boost::format( "Loading \"%s\" onto \"%s\"" ) % fileName % getName().c_str() ), e.what() ); } } // remove the old plug now we're done with it. oldPlug->parent<GraphComponent>()->removeChild( oldPlug ); } // make the loaded plugs non-dynamic, because we don't want them // to be serialised in the script the reference is in - the whole // point is that they are referenced. for( RecursivePlugIterator it( this ); it != it.end(); ++it ) { if( isReferencePlug( it->get() ) ) { (*it)->setFlags( Plug::Dynamic, false ); } } if( errors ) { throw Exception( boost::str( boost::format( "Error loading reference \"%s\"" ) % fileName ) ); } }