示例#1
0
void BoxIO::insert( Box *box )
{
	// Must take a copy of children because adding a child
	// would invalidate our PlugIterator.
	GraphComponent::ChildContainer children = box->children();
	for( PlugIterator it( children ); !it.done(); ++it )
	{
		Plug *plug = it->get();
		if( plug->direction() == Plug::In )
		{
			std::vector<Plug *> outputsNeedingBoxIn;
			const Plug::OutputContainer &outputs = plug->outputs();
			for( Plug::OutputContainer::const_iterator oIt = outputs.begin(), oeIt = outputs.end(); oIt != oeIt; ++oIt )
			{
				if( hasNodule( *oIt ) && !runTimeCast<BoxIO>( (*oIt)->node() ) )
				{
					outputsNeedingBoxIn.push_back( *oIt );
				}
			}

			if( outputsNeedingBoxIn.empty() )
			{
				continue;
			}

			BoxInPtr boxIn = new BoxIn;
			boxIn->namePlug()->setValue( plug->getName() );
			boxIn->setup( plug );
			box->addChild( boxIn );

			boxIn->inPlugInternal()->setInput( plug );
			for( std::vector<Plug *>::const_iterator oIt = outputsNeedingBoxIn.begin(), oeIt = outputsNeedingBoxIn.end(); oIt != oeIt; ++oIt )
			{
				(*oIt)->setInput( boxIn->plug() );
			}
		}
		else
		{
			// Output plug

			Plug *input = plug->getInput();
			if( !input || !hasNodule( input ) || runTimeCast<BoxIO>( input->node() ) )
			{
				continue;
			}

			BoxOutPtr boxOut = new BoxOut;
			boxOut->namePlug()->setValue( plug->getName() );
			boxOut->setup( plug );
			box->addChild( boxOut );

			boxOut->plug()->setInput( input );
			plug->setInput( boxOut->outPlugInternal() );
		}
	}

}
示例#2
0
void BoxIO::setupPromotedPlug()
{
	Plug *toPromote = m_direction == Plug::In ? inPlugInternal() : outPlugInternal();
	if( toPromote && parent<Box>() )
	{
		Plug *promoted = PlugAlgo::promoteWithName( toPromote, namePlug()->getValue() );
		namePlug()->setValue( promoted->getName() );
	}
}
示例#3
0
std::vector<NoduleLayout::GadgetKey> NoduleLayout::layoutOrder()
{
	typedef pair<int, GadgetKey> SortItem;
	vector<SortItem> toSort;

	// Add any plugs which should be visible

	for( PlugIterator plugIt( m_parent.get() ); !plugIt.done(); ++plugIt )
	{
		Plug *plug = plugIt->get();
		if( boost::starts_with( plug->getName().string(), "__" ) )
		{
			continue;
		}
		if( !::visible( plug, m_section ) )
		{
			continue;
		}

		toSort.push_back( SortItem( index( plug, toSort.size() ), plug ) );
	}

	// Then any custom gadgets specified by the metadata

	vector<InternedString> metadata;
	Metadata::registeredValues( m_parent.get(), metadata );
	boost::regex customGadgetRegex( "noduleLayout:customGadget:(.+):gadgetType" );
	for( vector<InternedString>::const_iterator it = metadata.begin(), eIt = metadata.end(); it != eIt; ++it )
	{
		boost::cmatch match;
		if( !boost::regex_match( it->c_str(), match, customGadgetRegex ) )
		{
			continue;
		}
		const InternedString name = match[1].str();
		if( !::visible( m_parent.get(), name, m_section ) )
		{
			continue;
		}

		toSort.push_back( SortItem( index( m_parent.get(), name, toSort.size() ), name ) );
	}

	// Sort and return the result

	sort( toSort.begin(), toSort.end() );

	vector<GadgetKey> result;
	result.reserve( toSort.size() );
	for( vector<SortItem>::const_iterator it = toSort.begin(), eIt = toSort.end(); it != eIt; ++it )
	{
		result.push_back( it->second );
	}

	return result;
}
示例#4
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 ) );
	}
}
void StandardNodeGadget::updateNodules( std::vector<Nodule *> &nodules, std::vector<Nodule *> &added, std::vector<NodulePtr> &removed )
{
	// Update the nodules for all our plugs, and build a vector
	// of IndexAndNodule to sort ready for layout.
	vector<IndexAndNodule> sortedNodules;
	for( PlugIterator plugIt( node() ); plugIt != plugIt.end(); ++plugIt )
	{
		Plug *plug = plugIt->get();
		if( plug->getName().string().compare( 0, 2, "__" )==0 )
		{
			continue;
		}

		IECore::ConstStringDataPtr typeData = Metadata::plugValue<IECore::StringData>( plug, g_noduleTypeKey );
		IECore::InternedString type = typeData ? typeData->readable() : "GafferUI::StandardNodule";

		Nodule *nodule = NULL;
		NoduleMap::iterator it = m_nodules.find( plug );
		if( it != m_nodules.end() && it->second.type == type )
		{
			nodule = it->second.nodule.get();
		}
		else
		{
			if( it != m_nodules.end() && it->second.nodule )
			{
				removed.push_back( it->second.nodule );
			}
			NodulePtr n = Nodule::create( plug );
			m_nodules[plug] = TypeAndNodule( type, n );
			if( n )
			{
				added.push_back( n.get() );
				nodule = n.get();
			}
		}

		if( nodule )
		{
			int index = sortedNodules.size();
			if( IECore::ConstIntDataPtr indexData = Metadata::plugValue<IECore::IntData>( plug, g_noduleIndexKey ) )
			{
				index = indexData->readable();
			}
			sortedNodules.push_back( IndexAndNodule( index, nodule ) );
		}
	}

	// Remove any nodules for which a plug no longer exists.
	for( NoduleMap::iterator it = m_nodules.begin(); it != m_nodules.end(); )
	{
		NoduleMap::iterator next = it; next++;
		if( it->first->parent<Node>() != node() )
		{
			if( it->second.nodule )
			{
				removed.push_back( it->second.nodule );
			}
			m_nodules.erase( it );
		}
		it = next;
	}

	// Sort ready for layout.
	sort( sortedNodules.begin(), sortedNodules.end() );
	for( vector<IndexAndNodule>::const_iterator it = sortedNodules.begin(), eIt = sortedNodules.end(); it != eIt; ++it )
	{
		nodules.push_back( it->nodule );
	}
}