Exemple #1
0
		static MurmurHash hashFn( const ComputeParameters &params )
		{
			const std::string &filePath = params.first;
			MurmurHash h;
			h.append( filePath );
			return h;
		}
OP_ERROR SOP_SceneCacheSource::cookMySop( OP_Context &context )
{
	flags().setTimeDep( true );
	
	std::string file;
	if ( !ensureFile( file ) )
	{
		addError( SOP_ATTRIBUTE_INVALID, ( file + " is not a valid .scc" ).c_str() );
		gdp->clearAndDestroy();
		return error();
	}
	
	std::string path = getPath();
	Space space = getSpace();
	
	UT_String shapeFilterStr;
	evalString( shapeFilterStr, pShapeFilter.getToken(), 0, 0 );
	UT_StringMMPattern shapeFilter;
	shapeFilter.compile( shapeFilterStr );
	
	UT_String p( "P" );
	UT_String attributeFilter;
	evalString( attributeFilter, pAttributeFilter.getToken(), 0, 0 );
	if ( !p.match( attributeFilter ) )
	{
		attributeFilter += " P";
	}
	
	ConstSceneInterfacePtr scene = this->scene( file, path );
	if ( !scene )
	{
		addError( SOP_ATTRIBUTE_INVALID, ( path + " is not a valid location in " + file ).c_str() );
		gdp->clearAndDestroy();
		return error();
	}
	
	MurmurHash hash;
	hash.append( file );
	hash.append( path );
	hash.append( space );
	hash.append( shapeFilterStr );
	hash.append( attributeFilter );
	
	if ( !m_loaded || m_hash != hash )
	{
		gdp->clearAndDestroy();
	}
	
	Imath::M44d transform = ( space == World ) ? worldTransform( file, path, context.getTime() ) : Imath::M44d();
	
	SceneInterface::Path rootPath;
	scene->path( rootPath );
	
	loadObjects( scene, transform, context.getTime(), space, shapeFilter, attributeFilter.toStdString(), rootPath.size() );
	
	m_loaded = true;
	m_hash = hash;
	
	return error();
}
	static MurmurHash hash( const ComputationParams &params )
	{
		int id = params;
		MurmurHash h;
		h.append(id);
		return h;
	}
Exemple #4
0
IECore::MurmurHash Dispatcher::batchHash( const ExecutableNode::Task &task )
{
	MurmurHash result;
	result.append( (uint64_t)task.node() );

	if ( task.hash() == MurmurHash() )
	{
		return result;
	}

	const Context *context = task.context();
	std::vector<IECore::InternedString> names;
	context->names( names );
	for ( std::vector<IECore::InternedString>::const_iterator it = names.begin(); it != names.end(); ++it )
	{
		// ignore the frame and the ui values
		if ( ( *it != g_frame ) && it->string().compare( 0, 3, "ui:" ) )
		{
			result.append( *it );
			if ( const IECore::Data *data = context->get<const IECore::Data>( *it ) )
			{
				data->hash( result );
			}
		}
	}

	return result;
}
Exemple #5
0
IECore::MurmurHash ImagePlug::imageHash() const
{
    const Box2i dataWindow = dataWindowPlug()->getValue();
    ConstStringVectorDataPtr channelNamesData = channelNamesPlug()->getValue();
    const vector<string> &channelNames = channelNamesData->readable();

    MurmurHash result = formatPlug()->hash();
    result.append( dataWindowPlug()->hash() );
    result.append( metadataPlug()->hash() );
    result.append( channelNamesPlug()->hash() );

    V2i minTileOrigin = tileOrigin( dataWindow.min );
    V2i maxTileOrigin = tileOrigin( dataWindow.max );

    ContextPtr context = new Context( *Context::current(), Context::Borrowed );
    Context::Scope scope( context.get() );

    for( vector<string>::const_iterator it = channelNames.begin(), eIt = channelNames.end(); it!=eIt; it++ )
    {
        context->set( ImagePlug::channelNameContextName, *it );
        for( int tileOriginY = minTileOrigin.y; tileOriginY<=maxTileOrigin.y; tileOriginY += tileSize() )
        {
            for( int tileOriginX = minTileOrigin.x; tileOriginX<=maxTileOrigin.x; tileOriginX += tileSize() )
            {
                context->set( ImagePlug::tileOriginContextName, V2i( tileOriginX, tileOriginY ) );
                channelDataPlug()->hash( result );
            }
        }
    }

    return result;
}
Exemple #6
0
IECore::MurmurHash ImagePlug::imageHash() const
{
	const Box2i dataWindow = dataWindowPlug()->getValue();
	ConstStringVectorDataPtr channelNamesData = channelNamesPlug()->getValue();
	const vector<string> &channelNames = channelNamesData->readable();

	MurmurHash result = formatPlug()->hash();
	result.append( dataWindowPlug()->hash() );
	result.append( metadataPlug()->hash() );
	result.append( channelNamesPlug()->hash() );

	ImageAlgo::parallelGatherTiles(
		this, channelNames,
		// Tile
		[] ( const ImagePlug *imagePlug, const string &channelName, const V2i &tileOrigin )
		{
			return imagePlug->channelDataPlug()->hash();
		},
		// Gather
		[ &result ] ( const ImagePlug *imagePlug, const string &channelName, const V2i &tileOrigin, const IECore::MurmurHash &tileHash )
		{
			result.append( tileHash );
		},
		dataWindow,
		ImageAlgo::BottomToTop
	);

	return result;
}
Exemple #7
0
	void SimpleDataHolder<Format>::hash( MurmurHash &h ) const
	{
		Format f = readable();
		h.append( f.getDisplayWindow().min );
		h.append( f.getDisplayWindow().max );
		h.append( f.getPixelAspect() );
	}
MurmurHash ExecutableNode::Task::hash() const
{
	MurmurHash h;
	const Node *nodePtr = node.get();
	h.append( (const char *)nodePtr, sizeof(Node*) );
	h.append( context->hash() );
	return h;
}
Exemple #9
0
void Display::hash( MurmurHash &h ) const
{
	PreWorldRenderable::hash( h );
	h.append( m_name );
	h.append( m_type );
	h.append( m_data );
	m_parameters->hash( h );
}
void CurvesPrimitive::topologyHash( MurmurHash &h ) const
{
	h.append( m_basis.matrix );
	h.append( m_basis.step );
	h.append( m_linear );
	h.append( m_periodic );
	m_vertsPerCurve->hash( h );
}
void MatrixMotionTransform::hash( MurmurHash &h ) const
{
	Transform::hash( h );
	for( SnapshotMap::const_iterator it=m_snapshots.begin(); it!=m_snapshots.end(); it++ )
	{
		h.append( it->first );
		h.append( it->second );
	}
}
Exemple #12
0
		// Hash used to determine how to coalesce tasks into batches.
		// If `batchHash( task1 ) == batchHash( task2 )` then the two
		// tasks can be placed in the same batch.
		IECore::MurmurHash batchHash( const TaskNode::Task &task )
		{
			MurmurHash result;
			result.append( (uint64_t)task.node() );
			// We ignore the frame because the whole point of batching
			// is to allow multiple frames to be placed in the same
			// batch if the context is otherwise identical.
			result.append( contextHash( task.context(), /* ignoreFrame = */ true ) );
			return result;
		}
Exemple #13
0
MurmurHash Renderer::ExternalProcedural::hash() const
{
	MurmurHash h;
	h.append( m_fileName );
	for( CompoundDataMap::const_iterator it = m_parameters.begin(), eIt = m_parameters.end(); it != eIt; ++it )
	{
		h.append( it->first );
		it->second->hash( h );
	}
	return h;
}
void NURBSPrimitive::topologyHash( MurmurHash &h ) const
{
	h.append( m_uOrder );
	m_uKnot->hash( h );
	h.append( m_uMin );
	h.append( m_uMax );
	h.append( m_vOrder );
	m_vKnot->hash( h );
	h.append( m_vMin );
	h.append( m_vMax );
}
Exemple #15
0
void Primitive::hash( MurmurHash &h ) const
{
    VisibleRenderable::hash( h );
    for( PrimitiveVariableMap::const_iterator it=variables.begin(); it!=variables.end(); it++ )
    {
        h.append( it->first );
        h.append( it->second.interpolation );
        it->second.data->hash( h );
    }

    topologyHash( h );
}
Exemple #16
0
Dispatcher::TaskBatchPtr Dispatcher::acquireBatch( const ExecutableNode::Task &task, BatchMap &currentBatches, TaskToBatchMap &tasksToBatches )
{
	MurmurHash taskToBatchMapHash = task.hash();
	taskToBatchMapHash.append( (uint64_t)task.node() );
	TaskToBatchMap::iterator it = tasksToBatches.find( taskToBatchMapHash );
	if ( it != tasksToBatches.end() )
	{
		return it->second;
	}

	MurmurHash batchMapHash = batchHash( task );
	BatchMap::iterator bIt = currentBatches.find( batchMapHash );
	if ( bIt != currentBatches.end() )
	{
		TaskBatchPtr batch = bIt->second;

		std::vector<float> &frames = batch->frames();
		const Plug *dispatcherPlug = task.node()->dispatcherPlug();
		const IntPlug *batchSizePlug = dispatcherPlug->getChild<const IntPlug>( g_batchSize );
		size_t batchSize = ( batchSizePlug ) ? batchSizePlug->getValue() : 1;

		if ( task.node()->requiresSequenceExecution() || ( frames.size() < batchSize ) )
		{
			if ( task.hash() != MurmurHash() )
			{
				float frame = task.context()->getFrame();
				if ( std::find( frames.begin(), frames.end(), frame ) == frames.end() )
				{
					if ( task.node()->requiresSequenceExecution() )
					{
						frames.insert( std::lower_bound( frames.begin(), frames.end(), frame ), frame );
					}
					else
					{
						frames.push_back( frame );
					}
				}
			}
			
			tasksToBatches[taskToBatchMapHash] = batch;
			
			return batch;
		}
	}

	TaskBatchPtr batch = new TaskBatch( task );
	currentBatches[batchMapHash] = batch;
	tasksToBatches[taskToBatchMapHash] = batch;
	
	return batch;
}
void SimpleDataHolder<CompoundDataMap>::hash( MurmurHash &h ) const
{
	// the CompoundDataMap is sorted by InternedString::operator <,
	// which just compares addresses of the underlying interned object.
	// this isn't stable between multiple processes.
	const CompoundDataMap &m = readable();
	std::vector<CompoundDataMap::const_iterator> iterators;
	iterators.reserve( m.size() );
	for( CompoundDataMap::const_iterator it=m.begin(); it!=m.end(); it++ )
	{
		iterators.push_back( it );
	}

	// so we have to sort again based on the string values
	// themselves.
	sort( iterators.begin(), iterators.end(), comp );

	// and then hash everything in the stable order.
	std::vector<CompoundDataMap::const_iterator>::const_iterator it;
	for( it=iterators.begin(); it!=iterators.end(); it++ )
	{
		if ( !((*it)->second) )
		{
			throw Exception( "Cannot compute hash from a CompoundData will NULL data pointers!" );
		}

		h.append( (*it)->first.value() );
		(*it)->second->hash( h );
	}
}
Exemple #18
0
void Shader::hash( MurmurHash &h ) const
{
	StateRenderable::hash( h );
	h.append( m_name );
	h.append( m_type );
	m_parameters->hash( h );
}
asf::auto_release_ptr<asr::Object> IECoreAppleseed::BatchPrimitiveConverter::doConvertPrimitive( PrimitivePtr primitive, const string &name )
{
	MurmurHash primitiveHash;
	primitiveHash.append( name );
	primitive->hash( primitiveHash );

	if( primitive->typeId() == MeshPrimitiveTypeId )
	{
		// Check if we already have a mesh saved for this object.
		string fileName = string( "_geometry/" ) + primitiveHash.toString() + m_meshGeomExtension;
		filesystem::path p = m_projectPath / fileName;

		if( !filesystem::exists( p ) )
		{
			ToAppleseedConverterPtr converter = ToAppleseedConverter::create( primitive.get() );

			if( !converter )
			{
				msg( Msg::Warning, "IECoreAppleseed::BatchPrimitiveConverter", "Couldn't convert primitive." );
				return asf::auto_release_ptr<asr::Object>();
			}

			asf::auto_release_ptr<asr::Object> entity;
			entity.reset( static_cast<asr::Object*>( converter->convert() ) );

			if( entity.get() == 0 )
			{
				msg( Msg::Warning, "IECoreAppleseed::BatchPrimitiveConverter", "Couldn't convert primitive." );
				return asf::auto_release_ptr<asr::Object>();
			}

			// Write the mesh to a file.
			p = m_projectPath / fileName;
			if( !asr::MeshObjectWriter::write( static_cast<const asr::MeshObject&>( *entity ), name.c_str(), p.string().c_str() ) )
			{
				msg( Msg::Warning, "IECoreAppleseed::BatchPrimitiveConverter", "Couldn't save mesh primitive." );
				return asf::auto_release_ptr<asr::Object>();
			}
		}

		asf::auto_release_ptr<asr::MeshObject> meshObj( asr::MeshObjectFactory().create( name.c_str(), asr::ParamArray().insert( "filename", fileName.c_str() ) ) );
		return asf::auto_release_ptr<asr::Object>( meshObj.release() );
	}

	return asf::auto_release_ptr<asr::Object>();
}
void MotionPrimitive::hash( MurmurHash &h ) const
{
	VisibleRenderable::hash( h );
	for( SnapshotMap::const_iterator it=m_snapshots.begin(); it!=m_snapshots.end(); it++ )
	{
		h.append( it->first );
		it->second->hash( h );	
	}
}
Exemple #21
0
void SetVisualiser::hashProcessedAttributes( const ScenePath &path, const Gaffer::Context *context, MurmurHash &h ) const
{
	ConstCompoundDataPtr outSetsData = outSetsPlug()->getValue();

	outSetsData->hash( h );
	includeInheritedPlug()->hash( h );

	// We also need to consider each of our candidate sets membership
	// definition (which we didn't need to when computing outSets).
	// outSetsData is map of names -> colors.
	ConstInternedStringVectorDataPtr setNames = outSetsData->member<InternedStringVectorData>( "names" );
	for( auto &setName : setNames->readable() )
	{
		h.append( inPlug()->setHash( setName ) );
	}

	h.append( path.data(), path.size() );
	stripeWidthPlug()->hash( h );
}
Exemple #22
0
void SetVisualiser::hash( const ValuePlug *output, const Context *context, MurmurHash &h ) const
{
	SceneElementProcessor::hash( output, context, h );

	if( output == outSetsPlug() )
	{
		setsPlug()->hash( h );
		colorOverridesPlug()->hash( h );
		// We don't care about a set's hash here as we're only computing which
		// sets we will consider and their corresponding colors - which depends
		// solely on their names.
		h.append( inPlug()->setNamesHash() );
	}
}
void ObjectVector::hash( MurmurHash &h ) const
{
	Object::hash( h );
	for( MemberContainer::const_iterator it=m_members.begin(); it!=m_members.end(); it++ )
	{
		if( *it )
		{
			(*it)->hash( h );
		}
		else
		{
			h.append( 0 );
		}
	}
}
Exemple #24
0
    // Hash used to determine how to coalesce tasks into batches.
    // If `batchHash( task1 ) == batchHash( task2 )` then the two
    // tasks can be placed in the same batch.
    IECore::MurmurHash batchHash( const TaskNode::Task &task )
    {
        MurmurHash result;
        result.append( (uint64_t)task.node() );

        const Context *context = task.context();
        std::vector<IECore::InternedString> names;
        context->names( names );
        for( std::vector<IECore::InternedString>::const_iterator it = names.begin(); it != names.end(); ++it )
        {
            // Ignore the UI values since they should be irrelevant
            // to execution.
            if( it->string().compare( 0, 3, "ui:" ) == 0 )
            {
                continue;
            }
            // Ignore the frame, since the whole point of batching
            // is to allow multiple frames to be placed in the same
            // batch if the context is otherwise identical.
            ///
            // There is one exception to this though - if the task is
            // a no-op, then we don't want to coalesce, because then
            // every single frame of the no-op would be placed in the
            // same batch, and all downstream frames would then be forced
            // to depend unnecessarily on all upstream frames.
            if( *it == g_frame && task.hash() != MurmurHash() )
            {
                continue;
            }

            result.append( *it );
            context->get<const IECore::Data>( *it )->hash( result );
        }

        return result;
    }
OP_ERROR SOP_SceneCacheSource::cookMySop( OP_Context &context )
{
	// make sure the state is valid
	if ( boost::indeterminate( m_static ) )
	{
		sceneChanged();
	}
	
	flags().setTimeDep( bool( !m_static ) );
	
	std::string file;
	if ( !ensureFile( file ) )
	{
		addError( SOP_ATTRIBUTE_INVALID, ( file + " is not a valid .scc" ).c_str() );
		gdp->clearAndDestroy();
		return error();
	}
	
	std::string path = getPath();
	Space space = getSpace();
	GeometryType geometryType = (GeometryType)this->evalInt( pGeometryType.getToken(), 0, 0 );
	
	UT_String tagFilterStr;
	getTagFilter( tagFilterStr );
	UT_StringMMPattern tagFilter;
	tagFilter.compile( tagFilterStr );
	
	UT_String shapeFilterStr;
	getShapeFilter( shapeFilterStr );
	UT_StringMMPattern shapeFilter;
	shapeFilter.compile( shapeFilterStr );
	
	UT_String p( "P" );
	UT_String attributeFilter;
	getAttributeFilter( attributeFilter );
	if ( !p.match( attributeFilter ) )
	{
		attributeFilter += " P";
	}
	
	UT_String attributeCopy;
	getAttributeCopy( attributeCopy );
	
	UT_String fullPathName;
	getFullPathName( fullPathName );
	
	ConstSceneInterfacePtr scene = this->scene( file, path );
	if ( !scene )
	{
		addError( SOP_ATTRIBUTE_INVALID, ( path + " is not a valid location in " + file ).c_str() );
		gdp->clearAndDestroy();
		return error();
	}
	
	MurmurHash hash;
	hash.append( file );
	hash.append( path );
	hash.append( space );
	hash.append( tagFilterStr );
	hash.append( shapeFilterStr );
	hash.append( attributeFilter );
	hash.append( attributeCopy );
	hash.append( fullPathName );
	hash.append( geometryType );
	hash.append( getObjectOnly() );
	
	if ( !m_loaded || m_hash != hash )
	{
		gdp->clearAndDestroy();
	}
	
	double readTime = time( context );
	Imath::M44d transform = ( space == World ) ? worldTransform( file, path, readTime ) : Imath::M44d();
	
	SceneInterface::Path rootPath;
	scene->path( rootPath );
	
	UT_Interrupt *progress = UTgetInterrupt();
	if ( !progress->opStart( ( "Cooking objects for " + getPath() ).c_str() ) )
	{
		addError( SOP_ATTRIBUTE_INVALID, "Cooking interrupted before it started" );
		gdp->clearAndDestroy();
		return error();
	}
	
	Parameters params;
	UT_String attribFilter;
	getAttributeFilter( attribFilter );
	params.attributeFilter = attribFilter.toStdString();
	params.attributeCopy = attributeCopy.toStdString();
	params.fullPathName = fullPathName.toStdString();
	params.geometryType = getGeometryType();
	getShapeFilter( params.shapeFilter );
	getTagFilter( params.tagFilter );
	
	// Building a map from shape name to primitive range, which will be used during
	// convertObject() to do a lazy update of animated primvars where possible, and
	// to destroy changing topology shapes when necessary.
	GA_ROAttributeRef nameAttrRef = gdp->findStringTuple( GA_ATTRIB_PRIMITIVE, "name" );
	if ( nameAttrRef.isValid() )
	{
		const GA_Attribute *attr = nameAttrRef.getAttribute();
		const GA_AIFSharedStringTuple *tuple = attr->getAIFSharedStringTuple();
		
		std::map<std::string, GA_OffsetList> offsets;
		GA_Range primRange = gdp->getPrimitiveRange();
		for ( GA_Iterator it = primRange.begin(); !it.atEnd(); ++it )
		{
			std::string current = "";
			if ( const char *value = tuple->getString( attr, it.getOffset() ) )
			{
				current = value;
			}
			
			std::map<std::string, GA_OffsetList>::iterator oIt = offsets.find( current );
			if ( oIt == offsets.end() )
			{
				oIt = offsets.insert( std::pair<std::string, GA_OffsetList>( current, GA_OffsetList() ) ).first;
			}
			
			oIt->second.append( it.getOffset() );
		}
		
		for ( std::map<std::string, GA_OffsetList>::iterator oIt = offsets.begin(); oIt != offsets.end(); ++oIt )
		{
			params.namedRanges[oIt->first] = GA_Range( gdp->getPrimitiveMap(), oIt->second );
		}
	}
	
	loadObjects( scene.get(), transform, readTime, space, params, rootPath.size() );
	
	if ( progress->opInterrupt( 100 ) )
	{
		addError( SOP_ATTRIBUTE_INVALID, "Cooking interrupted" );
		gdp->clearAndDestroy();		
		m_loaded = false;
		m_hash = MurmurHash();
	}
	else
	{
		m_loaded = true;
		m_hash = hash;
	}
	
	progress->opEnd();
	
	return error();
}
Exemple #26
0
void SimpleDataHolder<TimePeriod>::hash( MurmurHash &h ) const
{
	h.append( boost::posix_time::to_iso_string( readable().begin() ) );
	h.append( boost::posix_time::to_iso_string( readable().end() ) );
}
Exemple #27
0
void IECoreAppleseed::ShadingState::materialHash( MurmurHash &hash ) const
{
	shaderGroupHash( hash );
	hash.append( m_shadingSamples );
}
OP_ERROR SOP_SceneCacheSource::cookMySop( OP_Context &context )
{
	// make sure the state is valid
	if ( boost::indeterminate( m_static ) )
	{
		sceneChanged();
	}
	
	flags().setTimeDep( bool( !m_static ) );
	
	std::string file;
	if ( !ensureFile( file ) )
	{
		addError( SOP_ATTRIBUTE_INVALID, ( file + " is not a valid .scc" ).c_str() );
		gdp->clearAndDestroy();
		return error();
	}
	
	std::string path = getPath();
	Space space = getSpace();
	GeometryType geometryType = (GeometryType)this->evalInt( pGeometryType.getToken(), 0, 0 );
	
	UT_String shapeFilterStr;
	evalString( shapeFilterStr, pShapeFilter.getToken(), 0, 0 );
	UT_StringMMPattern shapeFilter;
	shapeFilter.compile( shapeFilterStr );
	
	UT_String p( "P" );
	UT_String attributeFilter;
	evalString( attributeFilter, pAttributeFilter.getToken(), 0, 0 );
	if ( !p.match( attributeFilter ) )
	{
		attributeFilter += " P";
	}
	
	ConstSceneInterfacePtr scene = this->scene( file, path );
	if ( !scene )
	{
		addError( SOP_ATTRIBUTE_INVALID, ( path + " is not a valid location in " + file ).c_str() );
		gdp->clearAndDestroy();
		return error();
	}
	
	MurmurHash hash;
	hash.append( file );
	hash.append( path );
	hash.append( space );
	hash.append( shapeFilterStr );
	hash.append( attributeFilter );
	hash.append( geometryType );
	hash.append( getObjectOnly() );
	
	if ( !m_loaded || m_hash != hash )
	{
		gdp->clearAndDestroy();
	}
	
	Imath::M44d transform = ( space == World ) ? worldTransform( file, path, context.getTime() ) : Imath::M44d();
	
	SceneInterface::Path rootPath;
	scene->path( rootPath );
	
	UT_Interrupt *progress = UTgetInterrupt();
	if ( !progress->opStart( ( "Cooking objects for " + getPath() ).c_str() ) )
	{
		addError( SOP_ATTRIBUTE_INVALID, "Cooking interrupted before it started" );
		gdp->clearAndDestroy();
		return error();
	}
	
	loadObjects( scene, transform, context.getTime(), space, shapeFilter, attributeFilter.toStdString(), geometryType, rootPath.size() );
	
	if ( progress->opInterrupt( 100 ) )
	{
		addError( SOP_ATTRIBUTE_INVALID, "Cooking interrupted" );
		gdp->clearAndDestroy();		
		m_loaded = false;
		m_hash = MurmurHash();
	}
	else
	{
		m_loaded = true;
		m_hash = hash;
	}
	
	progress->opEnd();
	
	return error();
}
void ImagePrimitive::topologyHash( MurmurHash &h ) const
{
	h.append( m_dataWindow );
	h.append( m_displayWindow );
}
void SimpleDataHolder<Imf::TimeCode>::hash( MurmurHash &h ) const
{
	const Imf::TimeCode &timeCode = readable();
	h.append( Imath::V2i( timeCode.timeAndFlags(), timeCode.userData() ) );
}