Ejemplo n.º 1
0
	def testBlurRange( self ):

		constant = GafferImage.Constant()
		constant["format"].setValue( GafferImage.Format( 5, 5, 1.000 ) )
		constant["color"].setValue( IECore.Color4f( 1, 1, 1, 1 ) )

		

		cropDot = GafferImage.Crop()
		cropDot["area"].setValue( IECore.Box2i( IECore.V2i( 2, 2 ), IECore.V2i( 3, 3 ) ) )
		cropDot["affectDisplayWindow"].setValue( False )
		cropDot["in"].setInput( constant["out"] )

		blur = GafferImage.Blur()
		blur["expandDataWindow"].setValue( True )
		blur["in"].setInput( cropDot["out"] )
		blur["radius"]["y"].setInput( blur["radius"]["x"] )

		expression = Gaffer.Expression()
		blur.addChild( expression )
		expression.setExpression( 'parent["radius"]["x"] = context[ "loop:index" ] * 0.2', "python" )

		loopInit = GafferImage.Constant()
		loopInit["format"].setValue( GafferImage.Format( 5, 5, 1.000 ) )

		imageLoop = GafferImage.ImageLoop()
		imageLoop["in"].setInput( loopInit["out"] )

		merge = GafferImage.Merge()
		merge["in"].addChild( GafferImage.ImagePlug( "in2", flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) )
		merge["in"]["in0"].setInput( blur["out"] )
		merge["in"]["in1"].setInput( imageLoop["previous"] )

		offset = GafferImage.Offset()
		offset["offset"].setValue( IECore.V2i( -5, 0 ) )
		offset["in"].setInput( merge["out"] )

		imageLoop["next"].setInput( offset["out"] )

		deleteChannels = GafferImage.DeleteChannels()
		deleteChannels["mode"].setValue( GafferImage.DeleteChannels.Mode.Keep )
		deleteChannels["channels"].setValue( IECore.StringVectorData( [ 'R' ] ) )
		deleteChannels["in"].setInput( imageLoop["out"] )

		finalCrop = GafferImage.Crop()
		finalCrop["areaSource"].setValue( 1 )
		finalCrop["in"].setInput( deleteChannels["out"] )

		# Enable to write out images for visual comparison
		if False:
			testWriter = GafferImage.ImageWriter()
			testWriter["in"].setInput( finalCrop["out"] )
			testWriter["fileName"].setValue( "/tmp/blurRange.exr" )
			testWriter["openexr"]["dataType"].setValue( 'float' )
			testWriter["task"].execute()

		expectedReader = GafferImage.ImageReader()
		expectedReader["fileName"].setValue( os.path.dirname( __file__ ) + "/images/blurRange.exr" )

		self.assertImagesEqual( finalCrop["out"], expectedReader["out"], maxDifference = 0.00001, ignoreMetadata = True )
Ejemplo n.º 2
0
    def testIterationsContext(self):

        script = Gaffer.ScriptNode()

        script["c"] = GafferImage.Constant()
        script["loop"] = GafferImage.ImageLoop()
        script["loop"]["in"].setInput(script["c"]["out"])

        script["grade"] = GafferImage.Grade()
        script["grade"]["offset"].setValue(imath.Color3f(.1))
        script["grade"]["in"].setInput(script["loop"]["previous"])
        script["loop"]["next"].setInput(script["grade"]["out"])

        script["sampler"] = GafferImage.ImageSampler()
        script["sampler"]["pixel"].setValue(imath.V2f(10))
        script["sampler"]["image"].setInput(script["loop"]["out"])

        script["expression"] = Gaffer.Expression()
        script["expression"].setExpression(
            inspect.cleandoc("""
			assert( context.get( "image:channelName", None ) is None )
			assert( context.get( "image:tileOrigin", None ) is None )
			parent["loop"]["iterations"] = 4
			"""))

        with script.context():

            self.assertAlmostEqual(script["sampler"]["color"]["r"].getValue(),
                                   .4)
Ejemplo n.º 3
0
    def testLoop(self):

        script = Gaffer.ScriptNode()

        script["c"] = GafferImage.Constant()
        script["loop"] = GafferImage.ImageLoop()
        script["loop"]["in"].setInput(script["c"]["out"])

        script["grade"] = GafferImage.Grade()
        script["grade"]["offset"].setValue(IECore.Color3f(.1))
        script["grade"]["in"].setInput(script["loop"]["previous"])
        script["loop"]["next"].setInput(script["grade"]["out"])

        script["sampler"] = GafferImage.ImageSampler()
        script["sampler"]["pixel"].setValue(IECore.V2f(10))
        script["sampler"]["image"].setInput(script["loop"]["out"])

        with script.context():

            script["loop"]["iterations"].setValue(2)
            self.assertAlmostEqual(script["sampler"]["color"]["r"].getValue(),
                                   .2)

            script["loop"]["iterations"].setValue(4)
            self.assertAlmostEqual(script["sampler"]["color"]["r"].getValue(),
                                   .4)

        script2 = Gaffer.ScriptNode()
        script2.execute(script.serialise())

        with script2.context():

            script2["loop"]["iterations"].setValue(3)
            self.assertAlmostEqual(script2["sampler"]["color"]["r"].getValue(),
                                   .3)

            script2["loop"]["iterations"].setValue(5)
            self.assertAlmostEqual(script2["sampler"]["color"]["r"].getValue(),
                                   .5)
Ejemplo n.º 4
0
    def __init__(self, name='BleedFill'):

        GafferImage.ImageProcessor.__init__(self, name)

        self.addChild(Gaffer.BoolPlug("expandDataWindow"))

        self.addChild(Gaffer.IntPlug("__blurIterations"))
        self['__blurIterations'].setFlags(Gaffer.Plug.Flags.Serialisable,
                                          False)

        self["__blurIterationsExpression"] = Gaffer.Expression()
        self["__blurIterationsExpression"].setExpression(
            inspect.cleandoc("""
			import math
			f = parent["in"]["format"]
			parent["__blurIterations"] = int( math.log( min( f.width(), f.height() ), 2 ) )
			"""), "python")

        self["__displayWindowConstant"] = GafferImage.Constant()
        self["__displayWindowConstant"]["color"].setValue(
            imath.Color4f(0, 0, 0, 0))

        self["__displayWindowExpression"] = Gaffer.Expression()
        self["__displayWindowExpression"].setExpression(
            'parent["__displayWindowConstant"]["format"] = parent["in"]["format"]',
            "python")

        self["__expandMerge"] = GafferImage.Merge()
        self["__expandMerge"]["in"][0].setInput(self["in"])
        self["__expandMerge"]["in"][1].setInput(
            self["__displayWindowConstant"]["out"])
        self["__expandMerge"]["operation"].setValue(
            GafferImage.Merge.Operation.Over)

        self["__expandSwitch"] = Gaffer.Switch()
        self["__expandSwitch"].setup(self["in"])
        self["__expandSwitch"]["in"][0].setInput(self["in"])
        self["__expandSwitch"]["in"][1].setInput(self["__expandMerge"]["out"])
        self["__expandSwitch"]["index"].setInput(self["expandDataWindow"])

        # First blur via repeated downsampling
        self["__blurLoop"] = GafferImage.ImageLoop()
        self["__blurLoop"]["iterations"].setInput(self["__blurIterations"])
        self["__blurLoop"]["in"].setInput(self["__expandSwitch"]["out"])

        self["__downsample"] = GafferImage.Resize()
        self["__downsample"]["in"].setInput(self["__blurLoop"]["previous"])
        self["__downsample"]["filter"].setValue("sharp-gaussian")

        self["__downsampleExpression"] = Gaffer.Expression()
        self["__downsampleExpression"].setExpression(
            inspect.cleandoc("""
			import GafferImage
			import IECore

			f = parent["in"]["format"]

			divisor = 2 <<  context.get("loop:index", 0)

			parent["__downsample"]["format"] =  GafferImage.Format( imath.Box2i( f.getDisplayWindow().min() / divisor, f.getDisplayWindow().max() / divisor ), 1.0 )
			"""), "python")

        # Multiply each successive octave by a falloff factor so that we prioritize higher frequencies when they exist
        self["__grade"] = GafferImage.Grade("Grade")
        self["__grade"]['channels'].setValue("*")
        self["__grade"]['multiply'].setValue(imath.Color4f(0.1))
        self["__grade"]["in"].setInput(self["__downsample"]["out"])

        self["__blurLoop"]["next"].setInput(self["__grade"]["out"])

        self["__reverseLoopContext"] = GafferImage.ImageContextVariables()
        self["__reverseLoopContext"]["in"].setInput(
            self["__blurLoop"]["previous"])
        self["__reverseLoopContext"]["variables"].addMember(
            "loop:index", IECore.IntData(0), "loopIndex")

        self["__reverseLoopExpression"] = Gaffer.Expression()
        self["__reverseLoopExpression"].setExpression(
            inspect.cleandoc("""
			parent["__reverseLoopContext"]["variables"]["loopIndex"]["value"] = parent["__blurIterations"] - context.get( "loop:index", 0 )
			"""), "python")

        # Loop through image resolution levels combining the most downsampled image with less downsampled versions,
        # one level at a time
        self["__combineLoop"] = GafferImage.ImageLoop()

        self["__combineLoopExpression"] = Gaffer.Expression()
        self["__combineLoopExpression"].setExpression(
            'parent["__combineLoop"]["iterations"] = parent["__blurIterations"] + 1',
            "python")

        self["__upsample"] = GafferImage.Resize()
        self["__upsample"]["in"].setInput(self["__combineLoop"]["previous"])
        self["__upsample"]["filter"].setValue("smoothGaussian")

        self["__upsampleExpression"] = Gaffer.Expression()
        self["__upsampleExpression"].setExpression(
            inspect.cleandoc("""
			import GafferImage
			import IECore

			f = parent["in"]["format"]

			divisor = 1 <<  (  parent["__blurIterations"] - context.get("loop:index", 0) )

			parent["__upsample"]["format"] =  GafferImage.Format( imath.Box2i( f.getDisplayWindow().min() / divisor, f.getDisplayWindow().max() / divisor ), 1.0 )
			"""), "python")

        self["__merge"] = GafferImage.Merge()
        self["__merge"]["operation"].setValue(GafferImage.Merge.Operation.Over)
        self["__merge"]["in"][0].setInput(self["__upsample"]["out"])
        self["__merge"]["in"][1].setInput(self["__reverseLoopContext"]["out"])

        self["__combineLoop"]["next"].setInput(self["__merge"]["out"])

        # When downsampling to target display window sizes with a non-square image,
        # the data window size gets rounded up to the nearest integer, potentially introducing
        # a small error in data window size that gets amplified during repeated upsampling.
        # To fix this, crop to the data window after scaling.
        self["__restoreDataSize"] = GafferImage.Crop()
        self["__restoreDataSize"]["in"].setInput(self["__combineLoop"]["out"])
        self["__restoreDataSize"]["affectDisplayWindow"].setValue(False)

        self["__restoreDataExpression"] = Gaffer.Expression()
        self["__restoreDataExpression"].setExpression(
            'parent["__restoreDataSize"]["area"] = parent["__expandSwitch"]["out"]["dataWindow"]',
            "python")

        self["__unpremult"] = GafferImage.Unpremultiply()
        self["__unpremult"]['channels'].setValue("*")
        self["__unpremult"]["in"].setInput(self["__restoreDataSize"]["out"])

        self["__resetAlpha"] = GafferImage.Shuffle()
        self["__resetAlpha"]["channels"].addChild(
            GafferImage.Shuffle.ChannelPlug("A", "__white"))
        self["__resetAlpha"]["in"].setInput(self["__unpremult"]["out"])

        self["__disableSwitch"] = Gaffer.Switch()
        self["__disableSwitch"].setup(self["in"])
        self["__disableSwitch"]["in"][0].setInput(self["in"])
        self["__disableSwitch"]["in"][1].setInput(self["__resetAlpha"]["out"])
        self["__disableSwitch"]["index"].setInput(self["enabled"])

        self['out'].setFlags(Gaffer.Plug.Flags.Serialisable, False)
        self["out"].setInput(self["__disableSwitch"]["out"])
Ejemplo n.º 5
0
    def testDefaultName(self):

        l = GafferImage.ImageLoop()
        self.assertEqual(l.getName(), "ImageLoop")