Esempio n. 1
0
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 );
	}
}
Esempio n. 2
0
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;
	}
}
Esempio n. 3
0
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();
		}
	}
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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 );
}
Esempio n. 6
0
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 );
	}
}
Esempio n. 7
0
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 );
		}
	}
}
Esempio n. 8
0
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 ) );
	}
}