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() ); } } }
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() ); } }
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; }
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 ); } }