Пример #1
0
bool SceneGadget::objectAt( const IECore::LineSegment3f &lineInGadgetSpace, GafferScene::ScenePlug::ScenePath &path ) const
{
	std::vector<IECoreGL::HitRecord> selection;
	{
		ViewportGadget::SelectionScope selectionScope( lineInGadgetSpace, this, selection, IECoreGL::Selector::IDRender );
		renderScene();
	}

	if( !selection.size() )
	{
		return false;
	}

	float depthMin = selection[0].depthMin;
	unsigned int name = selection[0].name;
	for( const auto &i : selection )
	{
		if( i.depthMin < depthMin )
		{
			depthMin = i.depthMin;
			name = i.name;
		}
	}

	PathMatcher paths = convertSelection( new UIntVectorData( { name } ) );
	if( paths.isEmpty() )
	{
		return false;
	}

	path = *PathMatcher::Iterator( paths.begin() );
	return true;
}
Пример #2
0
void GafferSceneTest::testPathMatcherRawIterator()
{
	vector<InternedString> root;
	vector<InternedString> a = assign::list_of( "a" );
	vector<InternedString> ab = assign::list_of( "a" )( "b" );
	vector<InternedString> abc = assign::list_of( "a" )( "b" )( "c" );

	PathMatcher m;
	PathMatcher::RawIterator it = m.begin();
	GAFFERTEST_ASSERT( it == m.end() );

	m.addPath( abc );
	it = m.begin();
	GAFFERTEST_ASSERT( *it == root );
	GAFFERTEST_ASSERT( it.exactMatch() == false );
	GAFFERTEST_ASSERT( it != m.end() );
	++it;
	GAFFERTEST_ASSERT( *it == a );
	GAFFERTEST_ASSERT( it.exactMatch() == false );
	GAFFERTEST_ASSERT( it != m.end() );
	++it;
	GAFFERTEST_ASSERT( *it == ab );
	GAFFERTEST_ASSERT( it.exactMatch() == false );
	GAFFERTEST_ASSERT( it != m.end() );
	++it;
	GAFFERTEST_ASSERT( *it == abc );
	GAFFERTEST_ASSERT( it.exactMatch() == true );
	GAFFERTEST_ASSERT( it != m.end() );
	++it;
	GAFFERTEST_ASSERT( it == m.end() );
}
Пример #3
0
GafferScene::ConstPathMatcherDataPtr Duplicate::computeBranchSet( const ScenePath &parentPath, const IECore::InternedString &setName, const Gaffer::Context *context ) const
{
	ConstPathMatcherDataPtr inputSetData = inPlug()->set( setName );
	const PathMatcher &inputSet = inputSetData->readable();
	if( inputSet.isEmpty() )
	{
		return outPlug()->setPlug()->defaultValue();
	}

	PathMatcher subTree = inputSet.subTree( targetPlug()->getValue() );
	if( subTree.isEmpty() )
	{
		return outPlug()->setPlug()->defaultValue();
	}

	ConstInternedStringVectorDataPtr childNamesData = childNamesPlug()->getValue();
	const vector<InternedString> &childNames = childNamesData->readable();

	PathMatcherDataPtr resultData = new PathMatcherData;
	PathMatcher &result = resultData->writable();
	ScenePath prefix( 1 );
	for( vector<InternedString>::const_iterator it = childNames.begin(), eIt = childNames.end(); it != eIt; ++it )
	{
		prefix.back() = *it;
		result.addPaths( subTree, prefix );
	}

	return resultData;
}
Пример #4
0
MurmurHash SharedDataHolder<PathMatcher>::hash() const
{
	IECore::MurmurHash result;

	HashStack stack;
	PathMatcher m = readable();
	for( PathMatcher::RawIterator it = m.begin(), eIt = m.end(); it != eIt; ++it )
	{
		// The iterator is recursive, so we use a stack to keep
		// track of where we are. Resize the stack to match our
		// current depth. The required size has the +1 because
		// we need a stack entry for the root item.
		size_t requiredStackSize = it->size() + 1;
		if( requiredStackSize > stack.size() )
		{
			// Going a level deeper.
			stack.push( HashNodes() );
			assert( stack.size() == requiredStackSize );
		}
		else if( requiredStackSize < stack.size() )
		{
			// Returning from recursion to the child nodes.
			// Output the hashes for the children we visited
			// and stored on the stack previously.
			popHashNodes( stack, requiredStackSize, result );
		}

		stack.top().push_back( HashNode( it->size() ? it->back().c_str() : "", it.exactMatch() ) );
	}
	popHashNodes( stack, 0, result );

	return result;
}
Пример #5
0
void expand( Context *context, const PathMatcher &paths, bool expandAncestors )
{
	GafferScene::PathMatcherData *expandedPaths = const_cast<GafferScene::PathMatcherData *>( context->get<GafferScene::PathMatcherData>( g_expandedPathsName, nullptr ) );
	if( !expandedPaths )
	{
		expandedPaths = new GafferScene::PathMatcherData();
		context->set( g_expandedPathsName, expandedPaths );
	}

	GafferScene::PathMatcher &expanded = expandedPaths->writable();

	bool needUpdate = false;
	if( expandAncestors )
	{
		for( GafferScene::PathMatcher::RawIterator it = paths.begin(), eIt = paths.end(); it != eIt; ++it )
		{
			needUpdate |= expanded.addPath( *it );
		}
	}
	else
	{
		for( GafferScene::PathMatcher::Iterator it = paths.begin(), eIt = paths.end(); it != eIt; ++it )
		{
			needUpdate |= expanded.addPath( *it );
		}
	}

	if( needUpdate )
	{
		// We modified the expanded paths in place to avoid unecessary copying,
		// so the context doesn't know they've changed. So we emit the changed
		// signal ourselves
		context->changedSignal()( context, g_expandedPathsName );
	}
}
Пример #6
0
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 );
	}
}
Пример #7
0
// we don't actually wrap the existing init, but rather reimplement it
// here using clear() and addPath(), so that we can support a mixture
// of strings and InternedStringVectorData.
static void initWrapper( PathMatcher &m, boost::python::object paths )
{
	m.clear();
	for( size_t i = 0, e = len( paths ); i < e; ++i )
	{
		object path = paths[i];
		extract<const char *> stringExtractor( path );
		if( stringExtractor.check() )
		{
			m.addPath( stringExtractor() );
		}
		else
		{
			IECore::ConstInternedStringVectorDataPtr d = extract<IECore::ConstInternedStringVectorDataPtr>( path );
			m.addPath( d->readable() );
		}
	}
}
Пример #8
0
static list paths( const PathMatcher &p )
{
	std::vector<std::string> paths;
	p.paths( paths );
	list result;
	for( std::vector<std::string>::const_iterator it = paths.begin(), eIt = paths.end(); it != eIt; it++ )
	{
		result.append( *it );
	}
	return result;
}
Пример #9
0
bool SceneView::expandWalk( const GafferScene::ScenePlug::ScenePath &path, size_t depth, PathMatcher &expanded, PathMatcher &selected )
{
	bool result = false;

	ConstInternedStringVectorDataPtr childNamesData = preprocessedInPlug<ScenePlug>()->childNames( path );
	const vector<InternedString> &childNames = childNamesData->readable();

	if( childNames.size() )
	{
		// expand ourselves to show our children, and make sure we're
		// not selected - we only want selection at the leaf levels of
		// our expansion.
		result |= expanded.addPath( path );
		result |= selected.removePath( path );

		ScenePlug::ScenePath childPath = path;
		childPath.push_back( InternedString() ); // room for the child name
		for( vector<InternedString>::const_iterator cIt = childNames.begin(), ceIt = childNames.end(); cIt != ceIt; cIt++ )
		{
			childPath.back() = *cIt;
			if( depth == 1 )
			{
				// at the bottom of the expansion - just select the child
				result |= selected.addPath( childPath );
			}
			else
			{
				// continue the expansion
				result |= expandWalk( childPath, depth - 1, expanded, selected );
			}
		}
	}
	else
	{
		// we have no children, just make sure we're selected to mark the
		// leaf of the expansion.
		result |= selected.addPath( path );
	}

	return result;
}
Пример #10
0
status_t PathMatcher :: PutPathsFromMatcher(const PathMatcher & matcher)
{
   TCHECKPOINT;

   for (HashtableIterator<String, PathMatcherEntry> iter(matcher.GetEntries(), HTIT_FLAG_NOREGISTER); iter.HasData(); iter++)
   {
      if (_entries.Put(iter.GetKey(), iter.GetValue()) == B_NO_ERROR)
      {
         if (iter.GetValue().GetFilter()()) _numFilters++;
      }
      else return B_ERROR;
   }
   return B_NO_ERROR;
}
Пример #11
0
		void applySelectionWalk( const PathMatcher &selection, const ScenePlug::ScenePath &path, bool check )
		{
			const unsigned m = check ? selection.match( path ) : 0;

			m_selected = m & Filter::ExactMatch;

			ScenePlug::ScenePath childPath = path;
			childPath.push_back( IECore::InternedString() ); // space for the child name
			for( std::vector<SceneGraph *>::const_iterator it = m_children.begin(), eIt = m_children.end(); it != eIt; ++it )
			{
				childPath.back() = (*it)->m_name;
				(*it)->applySelectionWalk( selection, childPath, m & Filter::DescendantMatch );
			}
		}
Пример #12
0
IECore::PathMatcher SceneGadget::convertSelection( IECore::UIntVectorDataPtr ids ) const
{
	CompoundDataMap parameters = { { "selection", ids } };
	if( m_selectionMask )
	{
		parameters["mask"] = m_selectionMask;
	}

	auto pathsData = static_pointer_cast<PathMatcherData>(
		m_renderer->command(
			"gl:querySelection",
			parameters
		)
	);

	PathMatcher result = pathsData->readable();

	// Unexpanded locations are represented with
	// objects named __unexpandedChildren__ to allow
	// locations to have an object _and_ children.
	// We want to replace any such locations with their
	// parent location.
	const InternedString unexpandedChildren = "__unexpandedChildren__";
	vector<InternedString> parent;

	PathMatcher toAdd;
	PathMatcher toRemove;
	for( PathMatcher::Iterator it = result.begin(), eIt = result.end(); it != eIt; ++it )
	{
		if( it->size() && it->back() == unexpandedChildren )
		{
			toRemove.addPath( *it );
			parent.assign( it->begin(), it->end() - 1 );
			toAdd.addPath( parent );
		}
	}

	result.addPaths( toAdd );
	result.removePaths( toRemove );

	return result;
}
Пример #13
0
size_t SceneGadget::objectsAt(
	const Imath::V3f &corner0InGadgetSpace,
	const Imath::V3f &corner1InGadgetSpace,
	IECore::PathMatcher &paths
) const
{

	vector<IECoreGL::HitRecord> selection;
	{
		ViewportGadget::SelectionScope selectionScope( corner0InGadgetSpace, corner1InGadgetSpace, this, selection, IECoreGL::Selector::OcclusionQuery );
		renderScene();
	}

	UIntVectorDataPtr ids = new UIntVectorData;
	std::transform(
		selection.begin(), selection.end(), std::back_inserter( ids->writable() ),
		[]( const IECoreGL::HitRecord &h ) { return h.name; }
	);

	PathMatcher selectedPaths = convertSelection( ids );
	paths.addPaths( selectedPaths );

	return selectedPaths.size();
}
Пример #14
0
bool SceneView::expandWalk( const std::string &path, size_t depth, PathMatcher &expanded, RenderableGadget::Selection &selected )
{
	bool result = false;
	
	ScenePlug::ScenePath scenePath;
	ScenePlug::stringToPath( path, scenePath );
	ConstInternedStringVectorDataPtr childNamesData = preprocessedInPlug<ScenePlug>()->childNames( scenePath );
	const vector<InternedString> &childNames = childNamesData->readable();

	if( childNames.size() )
	{
		// expand ourselves to show our children, and make sure we're
		// not selected - we only want selection at the leaf levels of
		// our expansion.
		result |= expanded.addPath( path );
		result |= selected.erase( path );
		for( vector<InternedString>::const_iterator cIt = childNames.begin(), ceIt = childNames.end(); cIt != ceIt; cIt++ )
		{
			std::string childPath( path );
			if( *childPath.rbegin() != '/' )
			{
				childPath += '/';
			}
			childPath += cIt->string();
			if( depth == 1 )
			{
				// at the bottom of the expansion - just select the child
				result |= selected.insert( childPath ).second;
			}
			else
			{
				// continue the expansion
				result |= expandWalk( childPath, depth - 1, expanded, selected );
			}
		}
	}
	else
	{
		// we have no children, just make sure we're selected to mark the
		// leaf of the expansion.
		result |= selected.insert( path ).second;
	}

	return result;
}
Пример #15
0
void GafferSceneTest::testPathMatcherIteratorPrune()
{
	vector<InternedString> root;
	vector<InternedString> abc = assign::list_of( "a" )( "b" )( "c" );

	// Prune an empty iterator range.
	PathMatcher m;
	PathMatcher::Iterator it = m.begin();
	GAFFERTEST_ASSERT( it == m.end() );
	it.prune();
	GAFFERTEST_ASSERT( it == m.end() );

	// Prune the root iterator itself.
	m.addPath( root );
	it = m.begin();
	GAFFERTEST_ASSERT( *it == root );
	GAFFERTEST_ASSERT( it != m.end() );
	it.prune();
	GAFFERTEST_ASSERT( *it == root );
	GAFFERTEST_ASSERT( it != m.end() );
	++it;
	GAFFERTEST_ASSERT( it == m.end() );

	// As above, but actually with some
	// descendants to be pruned.
	m.addPath( abc );
	it = m.begin();
	GAFFERTEST_ASSERT( *it == root );
	GAFFERTEST_ASSERT( it != m.end() );
	it.prune();
	GAFFERTEST_ASSERT( *it == root );
	GAFFERTEST_ASSERT( it != m.end() );
	++it;
	GAFFERTEST_ASSERT( it == m.end() );

}
Пример #16
0
static unsigned matchInternedStringVectorData( const PathMatcher &p, const IECore::InternedStringVectorData *d )
{
	return p.match( d->readable() );
}
Пример #17
0
static bool addPathInternedStringVectorData( PathMatcher &p, const IECore::InternedStringVectorData *d )
{
	return p.addPath( d->readable() );
}