Example #1
0
	def testDerivedClassParsing( self ) :
	
		class DerivedParameter( IECore.StringParameter ) :
		
			def __init__( self, name, description, defaultValue ) :
			
				IECore.StringParameter.__init__( self, name, description, defaultValue )

		IECore.registerRunTimeTyped( DerivedParameter )

		p = IECore.CompoundParameter(
			members = [
				DerivedParameter( "n", "", "" ),
			],
		)

		p["n"].setTypedValue( "test" )
		
		s = IECore.ParameterParser().serialise( p )
		
		p["n"].setTypedValue( "ohDear" )
		
		IECore.ParameterParser().parse( s, p )
		
		self.assertEqual( p["n"].getTypedValue(), "test" )
Example #2
0
	def doOperation( self, args ) :

		# take a copy of our input parameter
		prim = args['input'].copy()

		# check for P & N
		if not "P" in prim:
			raise Exception("Must have primvar 'P' in primitive!")
		if not "N" in prim:
			IECore.error( "Must have primvar 'N' in primitive!" )
			return IECoreScene.PointsPrimitive( 1 )

		# get our magnitude & frequency parameters
		mag = args['magnitude'].value
		freq = args['frequency'].value

		# calculate a new set of positions
		p_data = prim['P'].data
		new_p = []
		for p in p_data:
			noise_val = mag * ( hou.hmath.noise3d( [p.x * freq.x, p.y * freq.y, p.z * freq.z] ) - hou.Vector3(.5,.5,.5) ) * 2
			new_p.append( p + imath.V3f( noise_val[0], noise_val[1], noise_val[2] ) )

		# overwrite with our new P and return from the Op
		prim['P'] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Vertex, IECore.V3fVectorData( new_p ) )

		# recalculate normals
		if prim.typeId()==IECoreScene.TypeId.MeshPrimitive:
			IECoreScene.MeshNormalsOp()( input=prim, copyInput=False )

		return prim
	def testMissingDoRender( self ) :
		
		## This test exercises a problem in boost::python::wrapper::get_override
		# whereby failing to find an override would incorrectly set python error
		# flags (PyErr_Occurred() would return True), and we'd get really bizarre
		# errors erroneously reporting themselves later in execution. although in
		# the case of ParameterisedProcedural.doRender() the override should always
		# be present, we don't want to confuse people with really off the wall errors,
		# and outside of cortex we have other code where it's perfectly reasonable
		# not to provide an override - this is where the problem was first found.
		
		class MyProcedural( IECore.ParameterisedProcedural ) :
		
			def __init__( self ) :
			
				IECore.ParameterisedProcedural.__init__( self, "" )
		
			## oops! we forgot the doRender() method.
		
		IECore.registerRunTimeTyped( MyProcedural )
								
		c = IECore.CapturingRenderer()
		
		g = IECore.Group()
		g.addChild( MyProcedural() )
		
		with IECore.WorldBlock( c ) :
			g.render( c )
Example #4
0
	def testBadAffects( self ) :

		class BadAffects( Gaffer.DependencyNode ) :

			def __init__( self, name = "BadAffects" ) :

				Gaffer.DependencyNode.__init__( self, name )

				self["in"] = Gaffer.IntPlug()

			def affects( self, input ) :

				outputs = Gaffer.DependencyNode.affects( self, input )
				if input == self["in"] :
					outputs.append( None ) # Error!

				return outputs

		IECore.registerRunTimeTyped( BadAffects )

		n = BadAffects()

		with IECore.CapturingMessageHandler() as mh :
			n["in"].setValue( 1 )

		self.assertEqual( len( mh.messages ), 1 )
		self.assertEqual( mh.messages[0].level, IECore.Msg.Level.Error )
		self.assertEqual( mh.messages[0].context, "BadAffects::affects()" )
		self.assertEqual( mh.messages[0].message, "TypeError: No registered converter was able to extract a C++ reference to type Gaffer::Plug from this Python object of type NoneType\n" )
Example #5
0
	def testDerivingInPython( self ) :

		class DerivedBox( Gaffer.Box ) :

			def __init__( self, name = "DerivedBox" ) :

				Gaffer.Box.__init__( self, name )

		IECore.registerRunTimeTyped( DerivedBox )

		# check that the typeid can be seen from the C++ side.

		b = DerivedBox()
		b["c"] = Gaffer.Node()

		a = b["c"].ancestor( DerivedBox )
		self.assertTrue( a.isSame( b ) )

		# check that adding the node to a script and getting
		# it back gives the same object, with the correct
		# typeids etc.

		s = Gaffer.ScriptNode()
		s["b"] = b

		self.assertTrue( s["b"] is b )
		self.assertEqual( s["b"].typeId(), DerivedBox.staticTypeId() )
		self.assertEqual( s["b"].typeName(), DerivedBox.staticTypeName() )
Example #6
0
	def __applyCompoundParameterChanges( parameter, data, paramPath ) :

		if data["_type_"].value != "CompoundParameter" :
			IECore.msg(
				IECore.Msg.Level.Warning,
				"IECore.RelativePreset",
				"Unable to set preset on '%s'. Expected %s but found CompoundParameter."
					% ( paramPath, data["_type_"].value )
			)
			return

		for p in data.keys() :
			if p in [ "_type_", "_class_" ] :
				continue

			if paramPath :
				newParamPath = paramPath + "." + p
			else :
				newParamPath = p

			if p not in parameter :
				IECore.msg(
					IECore.Msg.Level.Warning,
					"IECore.RelativePreset",
					"Could not find parameter '%s'. Preset value ignored." % newParamPath
				)
				continue

			RelativePreset.__applyParameterChanges( parameter[p], data[p], newParamPath )
Example #7
0
def __plugPopupMenu( menuDefinition, plugValueWidget ) :
	
	plug = plugValueWidget.getPlug()
	node = plug.node()
	if node is None :
		return

	box = node.ancestor( Gaffer.Box )
	if box is None :
		return

	if box.canPromotePlug( plug ) :
		
		menuDefinition.append( "/BoxDivider", { "divider" : True } )
		menuDefinition.append( "/Promote to %s" % box.getName(), {
			"command" : IECore.curry( __promoteToBox, box, plug ),
			"active" : not plugValueWidget.getReadOnly(),
		} )

	elif box.plugIsPromoted( plug ) :
	
		# Add a menu item to unpromote the plug, replacing the "Remove input" menu item if it exists
		
		with IECore.IgnoredExceptions( Exception ) :
			menuDefinition.remove( "/Remove input" )
			
		menuDefinition.append( "/BoxDivider", { "divider" : True } )
		menuDefinition.append( "/Unpromote from %s" % box.getName(), {
			"command" : IECore.curry( __unpromoteFromBox, box, plug ),
			"active" : not plugValueWidget.getReadOnly(),
		} )
Example #8
0
	def __appendConnectionMenuDefinitions( self, definition, **kw ) :

		connections = cmds.listConnections(
			kw['attributeName'],
			d = False,
			s = True,
			plugs = True,
			connections = True,
			skipConversionNodes = True
		)
		
		definition.append( "/Connection Editor...", { "command" : IECore.curry( self.__connectionEditor ) } )

		if connections :
			
			definition.append( "/Open AE...",
				{ "command" : IECore.curry( self.__showEditor, attributeName = connections[1] ) }
			)				

			definition.append( "/Break Connection",
				{ 
					"command" : IECore.curry(
						self.__disconnect,
						source = connections[1],
						destination = connections[0],
						refreshAE = self.nodeName()
					)
				}
			)
						
			return True

		else:

			return False
Example #9
0
	def registerUI( parameterTypeId, handlerType, uiTypeHint = None ):

		key = (parameterTypeId, uiTypeHint)
		if key in ParameterUI.handlers :
			IECore.msg( IECore.Msg.Level.Warning, "ParameterUI.registerUI", "Handler for %s already registered." % str( key ) )

		ParameterUI.handlers[key] = handlerType
Example #10
0
def __plugValueWidgetCreator( plug ) :

	global __creators

	annotations = _shaderAnnotations( plug.node() )
	parameterName = plug.getName()
		
	widgetType = annotations.get( parameterName + ".widget", None )
	widgetCreator = None
	if widgetType is not None :
		widgetCreator = __creators.get( widgetType.value, None )
		if widgetCreator is None :
			IECore.msg(
				IECore.Msg.Level.Warning,
				"RenderManShaderUI",
				"Shader parameter \"%s.%s\" has unsupported widget type \"%s\"" %
					( plug.node()["name"].getValue(), parameterName, widgetType )
			)
			
	if widgetCreator is not None :
		try :
			return widgetCreator( plug, annotations )
		except Exception, e :
			IECore.msg(
				IECore.Msg.Level.Warning,
				"RenderManShaderUI",
				"Error creating UI for parameter \"%s.%s\" : \"%s\"" %
					( plug.node()["name"].getValue(), parameterName, str( e ) )
			)
Example #11
0
	def testContainsPoint( self ) :

		r = imath.Rand32()
		v0 = imath.V3f( 0, 0, 0 )
		v1 = imath.V3f( 1, 0, 0 )
		v2 = imath.V3f( 0, 1, 0 )
		for i in range( 0, 10000 ) :

			p = imath.V3f( r.nextf( -1, 1 ), r.nextf( -1, 1 ), 0 )
			if p.x < 0 or p.y < 0 or p.x + p.y > 1 :
				self.failIf( IECore.triangleContainsPoint( v0, v1, v2, p ) )
			else :
				self.failUnless( IECore.triangleContainsPoint( v0, v1, v2, p ) )

		r = imath.Rand32()
		for i in range( 0, 10000 ) :

			v0 = imath.V3f( r.nextf(), r.nextf(), r.nextf() )
			v1 = imath.V3f( r.nextf(), r.nextf(), r.nextf() )
			v2 = imath.V3f( r.nextf(), r.nextf(), r.nextf() )
			if IECore.triangleArea( v0, v1, v2 ) > 0.01 :

				u = r.nextf( 0, 1 )
				v = r.nextf( 0, 1 )
				if u + v < 1 :

					w = 1 - ( u + v )
					p = u * v0 + v * v1 + w * v2
					self.failUnless( IECore.triangleContainsPoint( v0, v1, v2, p ) )
Example #12
0
	def _applyClassParameter( self, parameterised, parameter, data, parameterList=[], invertList=False ) :
		
		if not isinstance( parameter, IECore.ClassParameter ) :
			IECore.msg(
				IECore.Msg.Level.Warning, 
				"IECore.BasicPreset", 
				"Unable to restore to '%s' (%s) as it isnt a ClassParameter"
					% ( parameter.name, parameter )
			)
			return
		
		c = parameter.getClass( True )
		
		className = data["_className_"].value
		classVersion = data["_classVersion_"].value
		classPaths = data["_classSearchPaths_"].value
		

		if self.parameters()["replaceClasses"].getTypedValue() :
			
			if c[1] != className or c[2] != classVersion or c[3] != classPaths:
				parameter.setClass( className, classVersion, classPaths )

		else :
			if c[1] != className :
				# class name is different, we don't change it and we don't process it's 
				# parameters since they will differ anyways...
				return
			
		c = parameter.getClass( False )
		if c and "_classValue_" in data :	
			self._applyHierarchy( parameterised, c.parameters(), data["_classValue_"], parameterList, invertList )		
Example #13
0
	def __init__( self, classLoader, classNamesMatchString = "*", reportErrors=True ) :

		# these are filled with tuples of the form ( opClass, parameter, parameterPath )
		self.__ops = []

		for className in classLoader.classNames( classNamesMatchString ) :

			try :
				opClass = classLoader.load( className )
				opInstance = opClass()
			except Exception, m :
				if reportErrors :
					IECore.msg( IECore.Msg.Level.Error, "Gaffer.OpMatcher", "Error loading op \"%s\" : %s" % ( className, traceback.format_exc() ) )
				continue

			ignore = False
			with IECore.IgnoredExceptions( KeyError ) :
				# backwards compatibility with something proprietary
				ignore = opInstance.userData()["UI"]["OpMatcher"]["ignore"].value
			with IECore.IgnoredExceptions( KeyError ) :
				ignore = opInstance.userData()["OpMatcher"]["ignore"].value
			if ignore :
				continue

			parameters = []
			self.__findParameters( opInstance.parameters(), parameters )
			if len( parameters ) :
				self.__ops.append( ( opClass, parameters ) )
Example #14
0
	def testExactPreferredToWildcards( self ) :

		class MetadataTestNodeD( Gaffer.Node ) :

			def __init__( self, name = "MetadataTestNodeD" ) :

				Gaffer.Node.__init__( self, name )

				self["a"] = Gaffer.IntPlug()
				self["b"] = Gaffer.IntPlug()

		IECore.registerRunTimeTyped( MetadataTestNodeD )

		Gaffer.Metadata.registerNode(

			MetadataTestNodeD,

			plugs = {
				"*" : [
					"test", "wildcard",
				],
				"a" :[
					"test", "exact",
				],
			}

		)

		n = MetadataTestNodeD()

		self.assertEqual( Gaffer.Metadata.value( n["a"], "test" ), "exact" )
		self.assertEqual( Gaffer.Metadata.value( n["b"], "test" ), "wildcard" )
Example #15
0
	def _applyHierarchy( self, parameterised, parameter, data, parameterList=[], invertList=False ) :
				
		if parameterList :
			if invertList : # its a 'skipList'
				if parameter in parameterList :
					return
			else :
				if parameter not in parameterList :
					return
		
		if "_className_" in data :
							
			self._applyClassParameter( parameterised, parameter, data, parameterList, invertList )
			
		elif "_classNames_" in data :
		
			self._applyClassVector( parameterised, parameter, data, parameterList, invertList )
		
		elif "_value_" in data :
				
			self._applyParameter( parameterised, parameter, data )
			
		else : # CompoundParameter
					
			for p in data.keys() :
			
				if p not in parameter :
					IECore.msg( 
						IECore.Msg.Level.Warning, 
						"IECore.BasicPreset", 
						"'%s' is missing from '%s' (%s)" % ( p, parameter.name, parameter ) 
					)
					continue
				
				self._applyHierarchy( parameterised, parameter[p], data[p], parameterList, invertList )
def __parameterPopupMenu( menuDefinition, parameterValueWidget ) :

	parameterHandler = parameterValueWidget.parameterHandler()

	if isinstance( parameterHandler.parameter(), IECore.CompoundVectorParameter ) :
		# the default value and overall presets don't currently work very well
		# for CompoundVectorParameters.
		return

	# replace plug default item with parameter default item. they
	# differ in that the parameter default applies to all children
	# of things like V3iParameters rather than just a single one.
	menuDefinition.remove( "/Default", raiseIfMissing=False )
	menuDefinition.append(
		"/Default",
		{
			"command" : IECore.curry( __setValue, parameterHandler, parameterHandler.parameter().defaultValue ),
			"active" : parameterValueWidget.plugValueWidget()._editable(),
		}
	)

	# add menu items for presets
	menuDefinition.remove( "/Preset", raiseIfMissing=False )
	if len( parameterHandler.parameter().presetNames() ) :
		menuDefinition.append( "/PresetDivider", { "divider" : True } )

	for name in parameterHandler.parameter().presetNames() :
		menuDefinition.append( "/" + name, { "command" : IECore.curry( __setValue, parameterHandler, name ) } )
Example #17
0
	def __writeTask( self, script, args ) :

		import GafferDispatch

		task = script.descendant( args["task"].value )
		if isinstance( task, GafferDispatch.TaskNode.TaskPlug ) :
			task = task.node()

		if task is None :
			IECore.msg( IECore.Msg.Level.Error, "stats", "Task \"%s\" does not exist" % args["task"].value )
			return

		dispatcher = GafferDispatch.LocalDispatcher()
		dispatcher["jobsDirectory"].setValue( tempfile.mkdtemp( prefix = "gafferStats" ) )

		memory = _Memory.maxRSS()
		with _Timer() as taskTimer :
			with self.__performanceMonitor or _NullContextManager(), self.__contextMonitor or _NullContextManager() :
				with Gaffer.Context( script.context() ) as context :
					for frame in self.__frames( script, args ) :
						context.setFrame( frame )
						dispatcher.dispatch( [ task ] )

		self.__timers["Task execution"] = taskTimer
		self.__memory["Task execution"] = _Memory.maxRSS() - memory
Example #18
0
	def __menuDefinition( self, widget ) :
	
		if widget is self.__diff().frame( 0 ) :
			target = self.__targets[0]
		else :
			target = self.__targets[1]

		m = IECore.MenuDefinition()
		
		m.append(
			"/Show History",
			{
				"command" : IECore.curry( Gaffer.WeakMethod( self.__showHistory ), target ),
			}
		)
		
		if self.__inspector.inspectsAttributes() :
		
			m.append(
				"/Show Inheritance",
				{
					"command" : IECore.curry( Gaffer.WeakMethod( self.__showInheritance ), target ),
				}
			)
	
		return m
	def testNestedNodules( self ) :

		class DeeplyNestedNode( Gaffer.Node ) :

			def __init__( self, name = "DeeplyNestedNode" ) :

				Gaffer.Node.__init__( self, name )

				self["c1"] = Gaffer.Plug()
				self["c1"]["i1"] = Gaffer.IntPlug()
				self["c1"]["c2"] = Gaffer.Plug()
				self["c1"]["c2"]["i2"] = Gaffer.IntPlug()
				self["c1"]["c2"]["c3"] = Gaffer.Plug()
				self["c1"]["c2"]["c3"]["i3"] = Gaffer.IntPlug()

		IECore.registerRunTimeTyped( DeeplyNestedNode )

		n = DeeplyNestedNode()

		def noduleType( plug ) :
			if plug.typeId() == Gaffer.Plug.staticTypeId() :
				return "GafferUI::CompoundNodule"
			else :
				return "GafferUI::StandardNodule"

		Gaffer.Metadata.registerValue( DeeplyNestedNode, "*", "nodule:type", noduleType )

		g = GafferUI.StandardNodeGadget( n )

		self.assertTrue( g.nodule( n["c1"] ).plug().isSame( n["c1"] ) )
		self.assertTrue( g.nodule( n["c1"]["i1"] ).plug().isSame( n["c1"]["i1"] ) )
		self.assertTrue( g.nodule( n["c1"]["c2"] ).plug().isSame( n["c1"]["c2"] ) )
		self.assertTrue( g.nodule( n["c1"]["c2"]["i2"] ).plug().isSame( n["c1"]["c2"]["i2"] ) )
		self.assertTrue( g.nodule( n["c1"]["c2"]["c3"] ).plug().isSame( n["c1"]["c2"]["c3"] ) )
		self.assertTrue( g.nodule( n["c1"]["c2"]["c3"]["i3"] ).plug().isSame( n["c1"]["c2"]["c3"]["i3"] ) )
Example #20
0
	def testNestedNodules( self ) :
	
		class DeeplyNestedNode( Gaffer.Node ) :
		
			def __init__( self, name = "DeeplyNestedNode" ) :
			
				Gaffer.Node.__init__( self, name )
				
				self["c1"] = Gaffer.CompoundPlug()
				self["c1"]["i1"] = Gaffer.IntPlug()
				self["c1"]["c2"] = Gaffer.CompoundPlug()
				self["c1"]["c2"]["i2"] = Gaffer.IntPlug()
				self["c1"]["c2"]["c3"] = Gaffer.CompoundPlug()
				self["c1"]["c2"]["c3"]["i3"] = Gaffer.IntPlug()
				
		IECore.registerRunTimeTyped( DeeplyNestedNode )
				
		n = DeeplyNestedNode()
		
		def noduleCreator( plug ) :
			if isinstance( plug, Gaffer.CompoundPlug ) :
				return GafferUI.CompoundNodule( plug )
			else :
				return GafferUI.StandardNodule( plug )
			
		GafferUI.Nodule.registerNodule( DeeplyNestedNode.staticTypeId(), ".*", noduleCreator )
		
		g = GafferUI.StandardNodeGadget( n )
		
		self.assertTrue( g.nodule( n["c1"] ).plug().isSame( n["c1"] ) )
		self.assertTrue( g.nodule( n["c1"]["i1"] ).plug().isSame( n["c1"]["i1"] ) )
		self.assertTrue( g.nodule( n["c1"]["c2"] ).plug().isSame( n["c1"]["c2"] ) )
		self.assertTrue( g.nodule( n["c1"]["c2"]["i2"] ).plug().isSame( n["c1"]["c2"]["i2"] ) )
		self.assertTrue( g.nodule( n["c1"]["c2"]["c3"] ).plug().isSame( n["c1"]["c2"]["c3"] ) )
		self.assertTrue( g.nodule( n["c1"]["c2"]["c3"]["i3"] ).plug().isSame( n["c1"]["c2"]["c3"]["i3"] ) )
Example #21
0
	def testForwarding( self ) :

		w = GafferUI.MessageWidget()

		h = IECore.CapturingMessageHandler()
		w.forwardingMessageHandler().addHandler( h )

		self.assertEqual( w.messageCount( IECore.Msg.Level.Error ), 0 )
		self.assertEqual( len( h.messages ), 0 )

		with w.messageHandler() :
			IECore.msg( IECore.Msg.Level.Error, "test", "test" )
			self.waitForIdle( 10 )

		self.assertEqual( w.messageCount( IECore.Msg.Level.Error ), 1 )
		self.assertEqual( len( h.messages ), 1 )

		w.forwardingMessageHandler().removeHandler( h )

		with w.messageHandler() :
			IECore.msg( IECore.Msg.Level.Error, "test", "test" )
			self.waitForIdle( 10 )

		self.assertEqual( w.messageCount( IECore.Msg.Level.Error ), 2 )
		self.assertEqual( len( h.messages ), 1 )
	def testTopLevelProceduralThreading( self ) :
	
		# this is necessary so python will allow threads created by the renderer
		# to enter into python when those threads execute procedurals.
		IECore.initThreads()
		
		self.SnowflakeProcedural.threadUse.clear()
		
		r = IECore.CapturingRenderer()
	
		with IECore.WorldBlock( r ) :
		
			for i in range( 0, 1000 ) :
				r.procedural( self.SnowflakeProcedural( maxLevel = 0 ) )
		
		self.failUnless( len( self.SnowflakeProcedural.threadUse ) > 1 )
		self.assertEqual( sum( self.SnowflakeProcedural.threadUse.values() ), 1000 )
		
		w = r.world()
		self.assertEqual( len( w.state() ), 0 )
		self.assertEqual( len( w.children() ), 1000 )
		
		for c in w.children() :
		
			self.failUnless( isinstance( c, IECore.Group ) )
			self.assertEqual( len( c.children() ), 1 )
			self.failUnless( isinstance( c.children()[0], IECore.SpherePrimitive ) )
Example #23
0
	def testMinLength( self ) :

		"""Verify that single files on their own aren't treated as sequences even
		if the name matches the something.#.ext pattern."""

		self.tearDown()
		os.system( "mkdir -p test/sequences/lsTest" )

		l = IECore.findSequences( [ "a.0001.tif", "b.0010.gif", "b.0011.gif" ] )
		self.assertEqual( len( l ), 1 )
		self.assertEqual( l[0], IECore.FileSequence( "b.####.gif", IECore.FrameRange( 10, 11 ) ) )

		# test minSequenceSize for findSequences
		l = IECore.findSequences( [ "a.0001.tif", "b.0010.gif", "b.0011.gif", "c.tif" ], 1 )
		self.assertEqual( len( l ), 2 )
		self.assertTrue( IECore.FileSequence( "a.####.tif", IECore.FrameRange( 1, 1 ) ) in l )
		self.assertTrue( IECore.FileSequence( "b.####.gif", IECore.FrameRange( 10, 11 ) ) in l )

		l = IECore.findSequences( [ "a.0001.tif", "b.0010.gif", "b.0011.gif", "b.0012.gif", "c.tif" ], 3 )
		self.assertEqual( len( l ), 1 )
		self.assertTrue( IECore.FileSequence( "b.####.gif", IECore.FrameRange( 10, 12 ) ) in l )

		s1 = IECore.FileSequence( "test/sequences/lsTest/a.#.tif", IECore.FrameRange( 1, 1 ) )
		for f in s1.fileNames() :
			os.system( "touch '" + f + "'" )

		l = IECore.ls( "test/sequences/lsTest/a.#.tif" )
		self.assertEqual( None, l )

		l = IECore.ls( "test/sequences/lsTest/a.#.tif", 1 )
		self.assertEqual( s1, l )
Example #24
0
			def addTagSubMenuItems( command ):

				import copy
				copiedTagTree = copy.deepcopy( tagTree )

				for tag in tags :
					
					subtags = copiedTagTree[tag]
					subtags.sort()

					if "" in subtags:
						maya.cmds.menuItem(
							label = tag,
							command = IECore.curry( command, sceneShapes, tag )
						)
						subtags.remove("")
					
					if subtags:
						maya.cmds.menuItem(
							label = tag,
							subMenu = True
						)

						for tagSuffix in subtags :
							maya.cmds.menuItem(
								label = tagSuffix,
								command = IECore.curry( command, sceneShapes, tag + ":" + tagSuffix )
							)
						maya.cmds.setParent( "..", menu=True )	
Example #25
0
	def testDerivingInPython( self ) :

		class DerivedImageWriter( GafferImage.ImageWriter ) :

			def __init__( self, name = "DerivedImageWriter" ) :

				GafferImage.ImageWriter.__init__( self, name )

				self["copyFileName"] = Gaffer.StringPlug()

			def execute( self ) :

				GafferImage.ImageWriter.execute( self )

				shutil.copyfile( self["fileName"].getValue(), self["copyFileName"].getValue() )

		IECore.registerRunTimeTyped( DerivedImageWriter )

		c = GafferImage.Constant()

		w = DerivedImageWriter()
		w["in"].setInput( c["out"] )
		w["fileName"].setValue( os.path.join( self.temporaryDirectory(), "test.exr" ) )
		w["copyFileName"].setValue( os.path.join( self.temporaryDirectory(), "test2.exr" ) )

		w["task"].execute()

		self.assertTrue( os.path.isfile( w["fileName"].getValue() ) )
		self.assertTrue( os.path.isfile( w["copyFileName"].getValue() ) )
Example #26
0
	def __addMenuDefinition( self ) :

		node = self.getPlug().node()
		currentNames = set( [ output["name"].getValue() for output in node["outputs"].children() ] )

		m = IECore.MenuDefinition()

		registeredOutputs = node.registeredOutputs()
		for name in registeredOutputs :
			menuPath = name
			if not menuPath.startswith( "/" ) :
				menuPath = "/" + menuPath
			m.append(
				menuPath,
				{
					"command" : IECore.curry( node.addOutput, name ),
					"active" : name not in currentNames
				}
			)

		if len( registeredOutputs ) :
			m.append( "/BlankDivider", { "divider" : True } )

		m.append( "/Blank", { "command" : IECore.curry( node.addOutput, "", IECoreScene.Display( "", "", "" ) ) } )

		return m
Example #27
0
	def testPlugDestructionDuringComputation( self ) :

		class PlugDestructionNode( GafferTest.AddNode ) :

			def __init__( self, name="PlugDestructionNode" ) :

				GafferTest.AddNode.__init__( self, name )

			def compute( self, plug, context ) :

				# It's not particularly smart to create a plug from
				# inside a compute, but here we're doing it to emulate
				# a situation which can occur when the python
				# garbage collector kicks in during computation.
				# When that happens, the garbage collector might
				# collect and destroy plugs from other graphs, and
				# we need the computation framework to be robust to
				# that. See #1576 for details of the original garbage
				# collection manifesting itself.
				v = Gaffer.ValuePlug()
				del v

				GafferTest.AddNode.compute( self, plug, context )

		IECore.registerRunTimeTyped( PlugDestructionNode )

		n = PlugDestructionNode()
		n["op1"].setValue( 1 )
		self.assertEqual( n["sum"].getValue(), 1 )
Example #28
0
		def __foregroundDispatch( self, batch ) :

			for upstreamBatch in batch.preTasks() :
				if not self.__foregroundDispatch( upstreamBatch ) :
					return False

			if batch.blindData().get( "killed" ) :
				self.__reportKilled( batch )
				return False

			if not batch.plug() or self.__getStatus( batch ) == LocalDispatcher.Job.Status.Complete :
				self.__setStatus( batch, LocalDispatcher.Job.Status.Complete )
				return True

			description = "executing %s on %s" % ( batch.blindData()["nodeName"].value, str(batch.frames()) )
			IECore.msg( IECore.MessageHandler.Level.Info, self.__messageTitle, description )

			try :
				self.__setStatus( batch, LocalDispatcher.Job.Status.Running )
				batch.execute()
			except :
				traceback.print_exc()
				self.__reportFailed( batch )
				return False

			self.__setStatus( batch, LocalDispatcher.Job.Status.Complete )

			return True
Example #29
0
	def __drawConnection( self, plugName ) :

		fieldWidth = IECoreMaya.ParameterUI.singleWidgetWidthIndex * 3 - 40

		maya.cmds.rowLayout(
			numberOfColumns = 3,
			columnWidth3 = [ fieldWidth , 20, 20 ]
		)

		name = maya.cmds.text( l=plugName, font="tinyBoldLabelFont", align="left",
							   width=fieldWidth, height = 20, ann=plugName )

		self._addPopupMenu( parentUI=name, attributeName = self.plugName() )
		self._addPopupMenu( parentUI=name, attributeName = self.plugName(), button1=True )

		maya.cmds.iconTextButton(
			annotation = "Clicking this takes you the connection editor for this connection.",
			style = "iconOnly",
			image = "viewList.xpm",
			font = "boldLabelFont",
			command = IECore.curry( self.__connectionEditor, leftHandNode = plugName ),
			height = 20,
			width = 20
		)

		maya.cmds.iconTextButton(
			annotation = "Clicking this will take you to the node sourcing this connection.",
			style = "iconOnly",
			image = "navButtonConnected.xpm",
			command = IECore.curry( self.__showEditor, plugName ),
			height = 20,
		)

		maya.cmds.setParent( ".." )
	def testDisableProceduralThreading( self ) :
	
		# this is necessary so python will allow threads created by the renderer
		# to enter into python when those threads execute procedurals.
		IECore.initThreads()
		
		self.SnowflakeProcedural.threadUse.clear()
		
		rThreaded = IECore.CapturingRenderer()
	
		with IECore.WorldBlock( rThreaded ) :
		
			rThreaded.procedural( self.SnowflakeProcedural( maxLevel = 3 ) )
		
		self.failUnless( len( self.SnowflakeProcedural.threadUse ) > 1 )
		self.assertEqual( sum( self.SnowflakeProcedural.threadUse.values() ), 156 )

		self.SnowflakeProcedural.threadUse.clear()
		
		rNonthreaded = IECore.CapturingRenderer()
	
		with IECore.WorldBlock( rNonthreaded ) :
			rNonthreaded.setAttribute( "cp:procedural:reentrant", IECore.BoolData( False ) )		
			rNonthreaded.procedural( self.SnowflakeProcedural( maxLevel = 3 ) )
		
		self.failUnless( len( self.SnowflakeProcedural.threadUse ) == 1 )
		self.assertEqual( sum( self.SnowflakeProcedural.threadUse.values() ), 156 )
Example #31
0
        def msg(level):

            IECore.msg(level, "test", "test")
            self.waitForIdle(10)
Example #32
0
GafferUI.Examples.appendExamplesSubmenuDefinition( scriptWindowMenu, "/Help/Examples" )

addHelpMenuItems( [
		( "License", "$GAFFER_ROOT/doc/gaffer/html/Appendices/License/index.html" ),
		( "LocalDocsDivider", None ),
		( "Forum", "https://groups.google.com/forum/#!forum/gaffer-dev" ),
		( "Issue Tracker", "https://github.com/GafferHQ/gaffer/issues" ),
		( "CoreDocsDivider", None )
] )


## Node creation menu
###########################################################################

moduleSearchPath = IECore.SearchPath( os.environ["PYTHONPATH"] )

nodeMenu = GafferUI.NodeMenu.acquire( application )

# Arnold nodes

if moduleSearchPath.find( "arnold" ) :

	try :

		import GafferArnold
		import GafferArnoldUI

		GafferArnoldUI.ShaderMenu.appendShaders( nodeMenu.definition() )

		nodeMenu.append( "/Arnold/Globals/Options", GafferArnold.ArnoldOptions, searchText = "ArnoldOptions" )
			def hash( self ):
			
				h = IECore.MurmurHash()
				return h
			def render( self, renderer ) :
			
				IECore.MeshPrimitive.createPlane( IECore.Box2f( IECore.V2f( -10 ), IECore.V2f( 10 ) ) ).render( renderer )
			def bound( self ) :
			
				return IECore.Box3f( IECore.V3f( -10, -10, -0.01 ), IECore.V3f( 10, 10, 0.01 ) )
Example #36
0
	def test( self ) :

		dataWindow = IECore.Box2i( IECore.V2i( 0 ), IECore.V2i( 74 ) )
		image = IECore.ImagePrimitive( dataWindow, dataWindow )
		red = IECore.FloatVectorData()
		green = IECore.FloatVectorData()
		blue = IECore.FloatVectorData()
		image["R"] = IECore.PrimitiveVariable( IECore.PrimitiveVariable.Interpolation.Vertex, red )
		image["G"] = IECore.PrimitiveVariable( IECore.PrimitiveVariable.Interpolation.Vertex, green )
		image["B"] = IECore.PrimitiveVariable( IECore.PrimitiveVariable.Interpolation.Vertex, blue )
		for y in range( 0, 75 ) :
			for x in range( 0, 75 ) :
				red.append( x )
				green.append( y )
				blue.append( 0 )

		imageNode = GafferImage.ObjectToImage()
		imageNode["object"].setValue( image )

		sampler = GafferImage.ImageSampler()
		sampler["image"].setInput( imageNode["out"] )

		hashes = set()
		for x in range( 0, 75 ) :
			for y in range( 0, 75 ) :
				sampler["pixel"].setValue( IECore.V2f( x + 0.5, y + 0.5 ) )
				# the flip in y is necessary as gaffer image coordinates run bottom->top and
				# cortex image coordinates run top->bottom.
				self.assertEqual( sampler["color"].getValue(), IECore.Color4f( x, 74 - y, 0, 0 ) )
				hashes.add( str( sampler["color"].hash() ) )

		self.assertEqual( len( hashes ), 75 * 75 )
Example #37
0
    def testMesh(self):
        """Check that anticlockwise winding order is considered front facing by default."""

        outputFileName = os.path.dirname(
            __file__) + "/output/testOrientation.tif"

        # render a single sided plane that shouldn't be backface culled
        r = IECoreGL.Renderer()
        r.setOption("gl:mode", IECore.StringData("immediate"))
        r.display(outputFileName, "tiff", "rgba", {})
        r.camera("main", {"resolution": IECore.V2iData(IECore.V2i(256))})
        r.worldBegin()
        r.setAttribute("doubleSided", IECore.BoolData(False))
        r.concatTransform(IECore.M44f.createTranslated(IECore.V3f(0, 0, -5)))
        self.makePlane().render(r)
        r.worldEnd()

        # check that something appears in the output image
        i = IECore.Reader.create(outputFileName).read()
        dimensions = i.dataWindow.size() + IECore.V2i(1)
        index = dimensions.x * int(dimensions.y * 0.5) + int(
            dimensions.x * 0.5)
        self.assertEqual(i["A"][index], 1)

        # render a plane that should be backface culled
        r = IECoreGL.Renderer()
        r.setOption("gl:mode", IECore.StringData("immediate"))
        r.display(outputFileName, "tiff", "rgba", {})
        r.camera("main", {"resolution": IECore.V2iData(IECore.V2i(256))})
        r.worldBegin()
        r.setAttribute("doubleSided", IECore.BoolData(False))
        r.concatTransform(IECore.M44f.createTranslated(IECore.V3f(0, 0, -5)))
        r.concatTransform(IECore.M44f.createRotated(IECore.V3f(0, math.pi, 0)))
        self.makePlane().render(r)
        r.worldEnd()

        # check that nothing appears in the output image
        i = IECore.Reader.create(outputFileName).read()
        dimensions = i.dataWindow.size() + IECore.V2i(1)
        index = dimensions.x * int(dimensions.y * 0.5) + int(
            dimensions.x * 0.5)
        self.assertEqual(i["A"][index], 0)
Example #38
0
import math

import IECore
import Gaffer

Gaffer.Metadata.registerValue("as:light:latlong_map_environment_edf", "type",
                              "environment")
Gaffer.Metadata.registerValue("as:light:latlong_map_environment_edf",
                              "textureNameParameter", "radiance_map")
Gaffer.Metadata.registerValue("as:light:latlong_map_environment_edf",
                              "intensityParameter", "radiance_multiplier")
Gaffer.Metadata.registerValue("as:light:latlong_map_environment_edf",
                              "exposureParameter", "exposure")
Gaffer.Metadata.registerValue(
    "as:light:latlong_map_environment_edf", "visualiserOrientation",
    IECore.M44f().rotate(IECore.V3f(0, 0.5 * math.pi, 0)))

Gaffer.Metadata.registerValue("as:light:hosek_environment_edf", "type",
                              "environment")

Gaffer.Metadata.registerValue("as:light:spot_light", "type", "spot")
Gaffer.Metadata.registerValue("as:light:spot_light", "coneAngleParameter",
                              "outer_angle")
Gaffer.Metadata.registerValue("as:light:spot_light", "penumbraAngleParameter",
                              "inner_angle")
Gaffer.Metadata.registerValue("as:light:spot_light", "penumbraType",
                              "absolute")
Gaffer.Metadata.registerValue("as:light:spot_light", "intensityParameter",
                              "intensity_multiplier")
Gaffer.Metadata.registerValue("as:light:spot_light", "exposureParameter",
                              "exposure")
Example #39
0
class OpDialogue( GafferUI.Dialogue ) :

	## Defines what happens when the op has been successfully executed :
	#
	# FromUserData : Get behaviour from ["UI"]["postExecuteBehaviour"] userData, which should
	#	contain a string value specifying one of the other Enum values. If no userData is found,
	#	it defaults to DisplayResult.
	#
	# None : Do nothing. The dialogue returns to the parameter editing state.
	#
	# Close : The dialogue is closed immediately.
	#
	# DisplayResult : The result is displayed, with a button for returning to the parameter editing state.
	#
	# DisplayResultAndClose : The result is displayed, with a button for closing the dialogue.
	#
	# NoneByDefault : deprecated - the same as DisplayResult
	# CloseByDefault : deprecated - the same as DisplayResult
	PostExecuteBehaviour = IECore.Enum.create( "FromUserData", "None", "Close", "DisplayResult", "DisplayResultAndClose", "NoneByDefault", "CloseByDefault" )

	## Defines which button has the focus when the op is displayed for editing.
	#
	# FromUserData : Gets the default button from ["UI"]["defaultButton"] userData, which
	#	should contain a string value specifying one of the other Enum values. If no userData is found,
	#	it defaults to OK.
	#
	# None : Neither button has the focus.
	#
	# OK : The OK button has the focus.
	#
	# Cancel : The cancel button has the focus.
	DefaultButton = IECore.Enum.create( "FromUserData", "None", "OK", "Cancel" )

	# If executeInBackground is True, then the Op will be executed on another
	# thread, allowing the UI to remain responsive during execution. This is
	# the preferred method of operation, but it is currently not the default
	# in case certain clients are relying on running the Op on the main thread.
	def __init__(
		self,
		opInstanceOrOpHolderInstance,
		title=None,
		sizeMode=GafferUI.Window.SizeMode.Manual,
		postExecuteBehaviour = PostExecuteBehaviour.FromUserData,
		executeInBackground = False,
		defaultButton = DefaultButton.FromUserData,
		executeImmediately = False,
		**kw
	) :

		# sort out our op and op holder

		if isinstance( opInstanceOrOpHolderInstance, IECore.Op ) :
			opInstance = opInstanceOrOpHolderInstance
			self.__node = Gaffer.ParameterisedHolderNode()
			self.__node.setParameterised( opInstance )
			# set the current plug values as userDefaults to provide
			# a clean NodeUI based on the initial settings of the Op.
			# we assume that if an OpHolder was passed directly then
			# the metadata has already been setup as preferred.
			self.__setUserDefaults( self.__node )
		else :
			self.__node = opInstanceOrOpHolderInstance
			opInstance = self.__node.getParameterised()[0]

		# initialise the dialogue

		if title is None :
			title = IECore.CamelCase.toSpaced( opInstance.typeName() )

		GafferUI.Dialogue.__init__( self, title, sizeMode=sizeMode, **kw )

		# decide what we'll do after execution.

		if postExecuteBehaviour == self.PostExecuteBehaviour.FromUserData :

			postExecuteBehaviour = self.PostExecuteBehaviour.DisplayResult

			d = None
			with IECore.IgnoredExceptions( KeyError ) :
				d = opInstance.userData()["UI"]["postExecuteBehaviour"]
			if d is not None :
				for v in self.PostExecuteBehaviour.values() :
					if str( v ).lower() == d.value.lower() :
						postExecuteBehaviour = v
						break
			else :
				# backwards compatibility with batata
				with IECore.IgnoredExceptions( KeyError ) :
					d = opInstance.userData()["UI"]["closeAfterExecution"]
				if d is not None :
					postExecuteBehaviour = self.PostExecuteBehaviour.Close if d.value else self.PostExecuteBehaviour.DisplayResult

		self.__postExecuteBehaviour = postExecuteBehaviour
		self.__executeInBackground = executeInBackground
		self.__defaultButton = defaultButton

		# make a frame to contain our main ui element. this will
		# contain different elements depending on our state.

		self.__frame = GafferUI.Frame()
		self._setWidget( self.__frame )

		# get the ui for the op - we'll use this when we want
		# the user to edit parameters.

		self.__parameterEditingUI = GafferUI.NodeUI.create( self.__node )

		# build a ui element for progress feedback and suchlike.
		# we'll use this when executing and displaying the result.

		with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical, spacing = 4 ) as self.__progressUI :

			GafferUI.Spacer( IECore.V2i( 1 ), parenting = { "expand" : True } )

			self.__progressIconFrame = GafferUI.Frame(
				borderStyle = GafferUI.Frame.BorderStyle.None,
				parenting = {
					"horizontalAlignment" : GafferUI.HorizontalAlignment.Center
				}
			)

			self.__progressLabel = GafferUI.Label(
				parenting = {
					"expand" : True,
					"horizontalAlignment" : GafferUI.HorizontalAlignment.Center,
				}
			)

			GafferUI.Spacer( IECore.V2i( 250, 1 ), parenting = { "expand"  : True } )

			with GafferUI.Collapsible( "Details", collapsed = True ) as self.__messageCollapsible :

				self.__messageWidget = GafferUI.MessageWidget()

				# connect to the collapsible state change so we can increase the window
				# size when the details pane is first shown.
				self.__messageCollapsibleStateChangedConnection = self.__messageCollapsible.stateChangedSignal().connect(
					Gaffer.WeakMethod( self.__messageCollapsibleStateChanged )
				)

		# add buttons. our buttons mean different things depending on our current state,
		# but they equate roughly to going forwards or going backwards.

		self.__backButton = self._addButton( "Back" )
		self.__forwardButton = self._addButton( "Forward" )

		self.__preExecuteSignal = GafferUI.WidgetSignal()
		self.__postExecuteSignal = Gaffer.Signal2()
		self.__opExecutedSignal = Gaffer.Signal1()
		self.__haveResizedToFitParameters = False

		if executeImmediately :
			self.__initiateExecution()
		else :
			self.__initiateParameterEditing()

	## Returns the ParameterisedHolder used to store the Op.
	# This may be used to edit parameter values.
	def parameterisedHolder( self ) :

		return self.__node

	## Signal emitted before executing the Op.
	# Slots should have the signature `bool slot( opDialogue )`,
	# and may return True to cancel execution, or False to
	# allow it to continue.
	def preExecuteSignal( self ) :

		return self.__preExecuteSignal

	## Signal emitted after executing the Op.
	# Slots should have the signature `slot( opDialogue, result )`.
	def postExecuteSignal( self ) :

		return self.__postExecuteSignal

	## A signal called when the user has pressed the execute button
	# and the Op has been successfully executed. This is passed the
	# result of the execution.
	## \deprecated Use postExecuteSignal() instead.
	def opExecutedSignal( self ) :

		return self.__opExecutedSignal

	## Returns the internal MessageWidget used for displaying messages
	# output by the Op.
	def messageWidget( self ) :

		return self.__messageWidget

	## Causes the dialogue to enter a modal state, returning the result
	# of executing the Op, or None if the user cancelled the operation. Any
	# validation or execution errors will be reported to the user and return
	# to the dialogue for them to cancel or try again.
	def waitForResult( self, **kw ) :

		self.__resultOfWait = None
		self.setModal( True, **kw ) # will return when the dialogue is closed
		return self.__resultOfWait

	def _acceptsClose( self ) :

		# we mustn't allow the window to be closed while
		# the op is running in the background.
		return self.__state != self.__State.Execution

	__State = IECore.Enum.create( "ParameterEditing", "Execution", "ErrorDisplay", "ResultDisplay" )

	def __initiateParameterEditing( self, *unused ) :

		self.__backButton.setText( "Cancel" )
		self.__backButton.setEnabled( True )
		self.__backButton.setVisible( True )
		self.__backButtonClickedConnection = self.__backButton.clickedSignal().connect( 0, Gaffer.WeakMethod( self.__close ) )

		executeLabel = "OK"
		with IECore.IgnoredExceptions( KeyError ) :
			executeLabel = self.__node.getParameterised()[0].userData()["UI"]["buttonLabel"].value

		self.__forwardButton.setText( executeLabel )
		self.__forwardButton.setEnabled( True )
		self.__forwardButton.setVisible( True )
		self.__forwardButtonClickedConnection = self.__forwardButton.clickedSignal().connect( 0, Gaffer.WeakMethod( self.__initiateExecution ) )

		self.__frame.setChild( self.__parameterEditingUI )

		self.__focusDefaultButton()

		self.__state = self.__State.ParameterEditing

		# when we first display our parameters, we want to ensure that the window
		# is big enough to fit them nicely. we don't do this the next time we show
		# the parameters, because the user may have deliberately resized the window.
		if not self.__haveResizedToFitParameters :
			self.resizeToFitChild( shrink = False )
			self.__haveResizedToFitParameters = True

	def __close( self, *unused ) :

		self.__state = self.__State.ParameterEditing
		self.close()

	def __initiateExecution( self, *unused ) :

		if self.preExecuteSignal()( self ) :
			return

		self.__progressIconFrame.setChild( GafferUI.BusyWidget() )
		self.__progressLabel.setText( "<h3>Processing...</h3>" )
		self.__backButton.setEnabled( False )
		self.__backButton.setText( "Cancel" )
		self.__forwardButton.setVisible( False )
		self.__messageWidget.clear()
		self.__messageCollapsible.setCollapsed( True )

		self.__state = self.__State.Execution

		if self.__executeInBackground :
			self.__frame.setChild( self.__progressUI )
			threading.Thread( target = self.__execute ).start()
		else :
			# we don't display progress when we're not threaded,
			# because we have no way of updating it.
			self.__execute()

	def __execute( self ) :

		try :

			self.__node.setParameterisedValues()

			with self.__messageWidget.messageHandler() :
				result = self.__node.getParameterised()[0]()

		except Exception, e :

			result = sys.exc_info()

		if self.__executeInBackground :
			GafferUI.EventLoop.executeOnUIThread( IECore.curry( self.__finishExecution, result ) )
		else :
			# We're being called on the main gui thread, most likely from a button click on
			# the forward button. If we called __finishExecution() immediately, it would add
			# new slots to the button click signal, and these would be executed immediately
			# for the _current_ click - this is not what we want! So we defer __finishExecution
			# to the next idle event, when the current click is a thing of the past.
			## \todo The documentation for boost::signals2 seems to imply that it has a different
			# behaviour, and that slots added during signal emission are ignored until the next
			# emission. If we move to using signals2, we may be able to revert this change.
			GafferUI.EventLoop.addIdleCallback( IECore.curry( self.__finishExecution, result ) )
Example #40
0
	def testROI( self ) :

		r = GafferImage.ImageReader()
		r["fileName"].setValue( self.__rgbFilePath )

		s = GafferImage.ImageStats()
		s["in"].setInput( r["out"] )
		s["channels"].setValue( IECore.StringVectorData( [ "R", "G", "B", "A" ] ) )

		s["area"].setValue( IECore.Box2i( IECore.V2i( 20, 20 ), IECore.V2i( 25, 25 ) ) )
		self.__assertColour( s["average"].getValue(), IECore.Color4f( 0.5, 0, 0, 0.5 ) )
		self.__assertColour( s["max"].getValue(), IECore.Color4f( 0.5, 0, 0, 0.5 ) )
		self.__assertColour( s["min"].getValue(), IECore.Color4f( 0.5, 0, 0, 0.5 ) )

		s["area"].setValue( IECore.Box2i( IECore.V2i( 20, 20 ), IECore.V2i( 41, 30 ) ) )
		self.__assertColour( s["average"].getValue(), IECore.Color4f( 0.4048, 0.1905, 0, 0.5952 ) )
		self.__assertColour( s["min"].getValue(), IECore.Color4f( 0.25, 0, 0, 0.5 ) )
		self.__assertColour( s["max"].getValue(), IECore.Color4f( 0.5, 0.5, 0, 0.75 ) )
Example #41
0
    def doOperation(self, operands):

        return IECore.StringData(operands['name'].value)
Example #42
0
	def __init__(
		self,
		opInstanceOrOpHolderInstance,
		title=None,
		sizeMode=GafferUI.Window.SizeMode.Manual,
		postExecuteBehaviour = PostExecuteBehaviour.FromUserData,
		executeInBackground = False,
		defaultButton = DefaultButton.FromUserData,
		executeImmediately = False,
		**kw
	) :

		# sort out our op and op holder

		if isinstance( opInstanceOrOpHolderInstance, IECore.Op ) :
			opInstance = opInstanceOrOpHolderInstance
			self.__node = Gaffer.ParameterisedHolderNode()
			self.__node.setParameterised( opInstance )
			# set the current plug values as userDefaults to provide
			# a clean NodeUI based on the initial settings of the Op.
			# we assume that if an OpHolder was passed directly then
			# the metadata has already been setup as preferred.
			self.__setUserDefaults( self.__node )
		else :
			self.__node = opInstanceOrOpHolderInstance
			opInstance = self.__node.getParameterised()[0]

		# initialise the dialogue

		if title is None :
			title = IECore.CamelCase.toSpaced( opInstance.typeName() )

		GafferUI.Dialogue.__init__( self, title, sizeMode=sizeMode, **kw )

		# decide what we'll do after execution.

		if postExecuteBehaviour == self.PostExecuteBehaviour.FromUserData :

			postExecuteBehaviour = self.PostExecuteBehaviour.DisplayResult

			d = None
			with IECore.IgnoredExceptions( KeyError ) :
				d = opInstance.userData()["UI"]["postExecuteBehaviour"]
			if d is not None :
				for v in self.PostExecuteBehaviour.values() :
					if str( v ).lower() == d.value.lower() :
						postExecuteBehaviour = v
						break
			else :
				# backwards compatibility with batata
				with IECore.IgnoredExceptions( KeyError ) :
					d = opInstance.userData()["UI"]["closeAfterExecution"]
				if d is not None :
					postExecuteBehaviour = self.PostExecuteBehaviour.Close if d.value else self.PostExecuteBehaviour.DisplayResult

		self.__postExecuteBehaviour = postExecuteBehaviour
		self.__executeInBackground = executeInBackground
		self.__defaultButton = defaultButton

		# make a frame to contain our main ui element. this will
		# contain different elements depending on our state.

		self.__frame = GafferUI.Frame()
		self._setWidget( self.__frame )

		# get the ui for the op - we'll use this when we want
		# the user to edit parameters.

		self.__parameterEditingUI = GafferUI.NodeUI.create( self.__node )

		# build a ui element for progress feedback and suchlike.
		# we'll use this when executing and displaying the result.

		with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical, spacing = 4 ) as self.__progressUI :

			GafferUI.Spacer( IECore.V2i( 1 ), parenting = { "expand" : True } )

			self.__progressIconFrame = GafferUI.Frame(
				borderStyle = GafferUI.Frame.BorderStyle.None,
				parenting = {
					"horizontalAlignment" : GafferUI.HorizontalAlignment.Center
				}
			)

			self.__progressLabel = GafferUI.Label(
				parenting = {
					"expand" : True,
					"horizontalAlignment" : GafferUI.HorizontalAlignment.Center,
				}
			)

			GafferUI.Spacer( IECore.V2i( 250, 1 ), parenting = { "expand"  : True } )

			with GafferUI.Collapsible( "Details", collapsed = True ) as self.__messageCollapsible :

				self.__messageWidget = GafferUI.MessageWidget()

				# connect to the collapsible state change so we can increase the window
				# size when the details pane is first shown.
				self.__messageCollapsibleStateChangedConnection = self.__messageCollapsible.stateChangedSignal().connect(
					Gaffer.WeakMethod( self.__messageCollapsibleStateChanged )
				)

		# add buttons. our buttons mean different things depending on our current state,
		# but they equate roughly to going forwards or going backwards.

		self.__backButton = self._addButton( "Back" )
		self.__forwardButton = self._addButton( "Forward" )

		self.__preExecuteSignal = GafferUI.WidgetSignal()
		self.__postExecuteSignal = Gaffer.Signal2()
		self.__opExecutedSignal = Gaffer.Signal1()
		self.__haveResizedToFitParameters = False

		if executeImmediately :
			self.__initiateExecution()
		else :
			self.__initiateParameterEditing()
Example #43
0
 def __init__(self):
     IECore.Op.__init__(self, "opDescription",
                        GreaterThenOp.MyCompound(),
                        IECore.StringParameter("result", "", ""))
    def testPlane(self):

        verticesPerFace = IECore.IntVectorData()

        vertexIds = IECore.IntVectorData()

        verticesPerFace.append(3)
        vertexIds.append(0)
        vertexIds.append(1)
        vertexIds.append(2)

        verticesPerFace.append(3)
        vertexIds.append(1)
        vertexIds.append(3)
        vertexIds.append(2)

        m = IECoreScene.MeshPrimitive(verticesPerFace, vertexIds)

        p = IECore.V3fVectorData()
        p.append(imath.V3f(-1, -1, 0))
        p.append(imath.V3f(1, -1, 0))
        p.append(imath.V3f(-1, 1, 0))
        p.append(imath.V3f(1, 1, 0))

        s = IECore.FloatVectorData()
        s.append(0)
        s.append(1)
        s.append(0)

        s.append(1)
        s.append(1)
        s.append(0)

        t = IECore.FloatVectorData()
        t.append(0)
        t.append(0)
        t.append(1)

        t.append(0)
        t.append(1)
        t.append(1)

        uni = IECore.IntVectorData()
        uni.append(0)
        uni.append(1)

        m["P"] = IECoreScene.PrimitiveVariable(
            IECoreScene.PrimitiveVariable.Interpolation.Vertex, p)
        m["s"] = IECoreScene.PrimitiveVariable(
            IECoreScene.PrimitiveVariable.Interpolation.FaceVarying, s)
        m["t"] = IECoreScene.PrimitiveVariable(
            IECoreScene.PrimitiveVariable.Interpolation.FaceVarying, t)
        m["uni"] = IECoreScene.PrimitiveVariable(
            IECoreScene.PrimitiveVariable.Interpolation.Uniform, uni)

        self.assertTrue(m.arePrimitiveVariablesValid())

        op = IECoreScene.MeshVertexReorderOp()

        result = op(input=m, startingVertices=imath.V3i(2, 3, 1))

        expectedVerticesPerFace = IECore.IntVectorData()
        expectedVerticesPerFace.append(3)
        expectedVerticesPerFace.append(3)

        self.assertEqual(result.verticesPerFace, expectedVerticesPerFace)

        expectedVertexIds = IECore.IntVectorData()
        expectedVertexIds.append(0)
        expectedVertexIds.append(1)
        expectedVertexIds.append(2)
        expectedVertexIds.append(0)
        expectedVertexIds.append(2)
        expectedVertexIds.append(3)

        self.assertEqual(result.vertexIds, expectedVertexIds)

        expectedP = IECore.V3fVectorData()
        expectedP.append(imath.V3f(-1, 1, 0))
        expectedP.append(imath.V3f(1, 1, 0))
        expectedP.append(imath.V3f(1, -1, 0))
        expectedP.append(imath.V3f(-1, -1, 0))

        self.assertEqual(result["P"].data, expectedP)

        expectedS = IECore.FloatVectorData()
        expectedS.append(0)
        expectedS.append(1)
        expectedS.append(1)

        expectedS.append(0)
        expectedS.append(1)
        expectedS.append(0)

        self.assertEqual(result["s"].data, expectedS)

        expectedT = IECore.FloatVectorData()
        expectedT.append(1)
        expectedT.append(1)
        expectedT.append(0)

        expectedT.append(1)
        expectedT.append(0)
        expectedT.append(0)

        self.assertEqual(result["t"].data, expectedT)

        expectedUni = IECore.IntVectorData()
        expectedUni.append(1)
        expectedUni.append(0)

        self.assertEqual(result["uni"].data, expectedUni)

        self.assertTrue(result.arePrimitiveVariablesValid())
Example #45
0
    def doOperation(self, args):

        inFile = IECoreAlembic.AlembicInput(args["inputFile"].value)
        outFile = IECore.ModelCache(args["outputFile"].value,
                                    IECore.IndexedIO.OpenMode.Write)

        time = inFile.timeAtSample(0)

        def walk(alembicInput, modelCache):

            o = alembicInput.objectAtTime(time,
                                          IECore.Primitive.staticTypeId())
            if o is not None:
                modelCache.writeObject(o)

            t = alembicInput.transformAtTime(time)
            modelCache.writeTransform(t)

            numChildren = alembicInput.numChildren()
            for i in range(0, numChildren):
                alembicChild = alembicInput.child(i)
                modelCacheChild = modelCache.writableChild(alembicChild.name())
                walk(alembicChild, modelCacheChild)

        walk(inFile, outFile)

        return args["outputFile"].value


IECore.registerRunTimeTyped(ABCToMDC)
Example #46
0
 def doOperation(self, operands):
     return IECore.StringData("Yes!")
Example #47
0
    def testMissingFrameMode(self):

        testSequence = IECore.FileSequence(self.temporaryDirectory() +
                                           "/incompleteSequence.####.exr")
        shutil.copyfile(self.fileName, testSequence.fileNameForFrame(1))
        shutil.copyfile(self.offsetDataWindowFileName,
                        testSequence.fileNameForFrame(3))

        reader = GafferImage.ImageReader()
        reader["fileName"].setValue(testSequence.fileName)

        oiio = GafferImage.OpenImageIOReader()
        oiio["fileName"].setValue(testSequence.fileName)

        def assertMatch():

            self.assertEqual(reader["out"]["format"].getValue(),
                             oiio["out"]["format"].getValue())
            self.assertEqual(reader["out"]["dataWindow"].getValue(),
                             oiio["out"]["dataWindow"].getValue())
            self.assertEqual(reader["out"]["metadata"].getValue(),
                             oiio["out"]["metadata"].getValue())
            self.assertEqual(reader["out"]["channelNames"].getValue(),
                             oiio["out"]["channelNames"].getValue())

            # It is only valid to query the data inside the data window
            if not GafferImage.BufferAlgo.empty(
                    reader["out"]["dataWindow"].getValue()):
                self.assertEqual(reader["out"].channelData("R", imath.V2i(0)),
                                 oiio["out"].channelData("R", imath.V2i(0)))
            self.assertImagesEqual(reader["out"], oiio["out"])

        context = Gaffer.Context()

        # set to a missing frame
        context.setFrame(2)

        # everything throws
        reader["missingFrameMode"].setValue(
            GafferImage.ImageReader.MissingFrameMode.Error)
        with context:
            six.assertRaisesRegex(self, RuntimeError,
                                  ".*incompleteSequence.*.exr.*",
                                  reader["out"]["format"].getValue)
            six.assertRaisesRegex(self, RuntimeError,
                                  ".*incompleteSequence.*.exr.*",
                                  reader["out"]["dataWindow"].getValue)
            six.assertRaisesRegex(self, RuntimeError,
                                  ".*incompleteSequence.*.exr.*",
                                  reader["out"]["metadata"].getValue)
            six.assertRaisesRegex(self, RuntimeError,
                                  ".*incompleteSequence.*.exr.*",
                                  reader["out"]["channelNames"].getValue)
            six.assertRaisesRegex(self, RuntimeError,
                                  ".*incompleteSequence.*.exr.*",
                                  reader["out"].channelData, "R", imath.V2i(0))
            six.assertRaisesRegex(self, RuntimeError,
                                  ".*incompleteSequence.*.exr.*",
                                  GafferImage.ImageAlgo.image, reader["out"])

        # Hold mode matches OpenImageIOReader
        reader["missingFrameMode"].setValue(
            GafferImage.ImageReader.MissingFrameMode.Hold)
        oiio["missingFrameMode"].setValue(
            GafferImage.OpenImageIOReader.MissingFrameMode.Hold)
        with context:
            assertMatch()

        # Black mode matches OpenImageIOReader
        reader["missingFrameMode"].setValue(
            GafferImage.ImageReader.MissingFrameMode.Black)
        oiio["missingFrameMode"].setValue(
            GafferImage.OpenImageIOReader.MissingFrameMode.Black)
        with context:
            assertMatch()

        # set to a different missing frame
        context.setFrame(4)

        # Hold mode matches OpenImageIOReader
        reader["missingFrameMode"].setValue(
            GafferImage.ImageReader.MissingFrameMode.Hold)
        oiio["missingFrameMode"].setValue(
            GafferImage.OpenImageIOReader.MissingFrameMode.Hold)
        with context:
            assertMatch()

        # Black mode matches OpenImageIOReader
        reader["missingFrameMode"].setValue(
            GafferImage.ImageReader.MissingFrameMode.Black)
        oiio["missingFrameMode"].setValue(
            GafferImage.OpenImageIOReader.MissingFrameMode.Black)
        with context:
            assertMatch()

        # set to a missing frame before the start of the sequence
        context.setFrame(0)

        # Hold mode matches OpenImageIOReader
        reader["missingFrameMode"].setValue(
            GafferImage.ImageReader.MissingFrameMode.Hold)
        oiio["missingFrameMode"].setValue(
            GafferImage.OpenImageIOReader.MissingFrameMode.Hold)
        with context:
            assertMatch()

        # Black mode matches OpenImageIOReader
        reader["missingFrameMode"].setValue(
            GafferImage.ImageReader.MissingFrameMode.Black)
        oiio["missingFrameMode"].setValue(
            GafferImage.OpenImageIOReader.MissingFrameMode.Black)
        with context:
            assertMatch()

        # explicit fileNames do not support MissingFrameMode
        reader["fileName"].setValue(testSequence.fileNameForFrame(0))
        reader["missingFrameMode"].setValue(
            GafferImage.OpenImageIOReader.MissingFrameMode.Hold)
        with context:
            six.assertRaisesRegex(self, RuntimeError,
                                  ".*incompleteSequence.*.exr.*",
                                  GafferImage.ImageAlgo.image, reader["out"])
            six.assertRaisesRegex(self, RuntimeError,
                                  ".*incompleteSequence.*.exr.*",
                                  reader["out"]["format"].getValue)
            six.assertRaisesRegex(self, RuntimeError,
                                  ".*incompleteSequence.*.exr.*",
                                  reader["out"]["dataWindow"].getValue)
            six.assertRaisesRegex(self, RuntimeError,
                                  ".*incompleteSequence.*.exr.*",
                                  reader["out"]["metadata"].getValue)
            six.assertRaisesRegex(self, RuntimeError,
                                  ".*incompleteSequence.*.exr.*",
                                  reader["out"]["channelNames"].getValue)
            six.assertRaisesRegex(self, RuntimeError,
                                  ".*incompleteSequence.*.exr.*",
                                  reader["out"].channelData, "R", imath.V2i(0))

        reader["missingFrameMode"].setValue(
            GafferImage.OpenImageIOReader.MissingFrameMode.Black)
        oiio["missingFrameMode"].setValue(
            GafferImage.OpenImageIOReader.MissingFrameMode.Black)
        with context:
            six.assertRaisesRegex(self, RuntimeError,
                                  ".*incompleteSequence.*.exr.*",
                                  GafferImage.ImageAlgo.image, reader["out"])
            six.assertRaisesRegex(self, RuntimeError,
                                  ".*incompleteSequence.*.exr.*",
                                  reader["out"]["format"].getValue)
            self.assertEqual(reader["out"]["dataWindow"].getValue(),
                             oiio["out"]["dataWindow"].getValue())
            self.assertEqual(reader["out"]["metadata"].getValue(),
                             oiio["out"]["metadata"].getValue())
            self.assertEqual(reader["out"]["channelNames"].getValue(),
                             oiio["out"]["channelNames"].getValue())
            self.assertTrue(
                GafferImage.BufferAlgo.empty(
                    reader["out"]['dataWindow'].getValue()))
            self.assertTrue(
                GafferImage.BufferAlgo.empty(
                    oiio["out"]['dataWindow'].getValue()))
Example #48
0
        IECore.Op.__init__(
            self, "opDescription",
            IECore.StringParameter(name="result",
                                   description="",
                                   defaultValue=""))
        self.parameters().addParameter(
            IECore.StringParameter(name="name",
                                   description="",
                                   defaultValue="john"))

    def doOperation(self, operands):

        return IECore.StringData(operands['name'].value)


IECore.registerRunTimeTyped(PythonOp)


class TestPythonOp(unittest.TestCase):
    def testNewOp(self):

        o = PythonOp()
        self.assertEqual(o.operate(), IECore.StringData("john"))
        o.parameters()["name"].setValue(IECore.StringData("jim"))
        self.assertEqual(o.operate(), IECore.StringData("jim"))
        self.assertEqual(o(), IECore.StringData("jim"))

    def testSmartOp(self):
        """ test smart operate function"""
        o = PythonOp()
        self.assertEqual(o(name="jim"), IECore.StringData("jim"))
    def testMotionBlurredBounds(self):

        script = Gaffer.ScriptNode()

        script["plane"] = GafferScene.Plane()

        script["expression1"] = Gaffer.Expression()
        script["expression1"]["engine"].setValue("python")
        script["expression1"]["expression"].setValue(
            'parent["plane"]["transform"]["translate"]["x"] = context.getFrame()'
        )

        script["expression2"] = Gaffer.Expression()
        script["expression2"]["engine"].setValue("python")
        script["expression2"]["expression"].setValue(
            'parent["plane"]["dimensions"]["x"] = 1 + context.getFrame()')

        script["options"] = GafferScene.StandardOptions()
        script["options"]["in"].setInput(script["plane"]["out"])

        for path, frame, bound in [
            ("/plane", 1,
             IECore.Box3f(IECore.V3f(0, -.5, 0), IECore.V3f(2, .5, 0))),
            ("/plane", 2,
             IECore.Box3f(IECore.V3f(0.5, -.5, 0), IECore.V3f(3.5, .5, 0))),
        ]:
            context = Gaffer.Context()
            context.setFrame(frame)
            procedural = GafferScene.SceneProcedural(script["options"]["out"],
                                                     context, path)
            self.assertEqual(procedural.bound(), bound)

        script["options"]["options"]["transformBlur"]["enabled"].setValue(True)
        script["options"]["options"]["transformBlur"]["value"].setValue(True)
        script["options"]["options"]["deformationBlur"]["enabled"].setValue(
            True)
        script["options"]["options"]["deformationBlur"]["value"].setValue(True)
        script["options"]["options"]["shutter"]["enabled"].setValue(True)
        script["options"]["options"]["shutter"]["value"].setValue(
            IECore.V2f(0, 1))

        for path, frame, bound in [
            ("/plane", 1,
             IECore.Box3f(IECore.V3f(0, -.5, 0), IECore.V3f(3.5, .5, 0))),
            ("/plane", 2,
             IECore.Box3f(IECore.V3f(0.5, -.5, 0), IECore.V3f(5, .5, 0))),
        ]:
            context = Gaffer.Context()
            context.setFrame(frame)
            procedural = GafferScene.SceneProcedural(script["options"]["out"],
                                                     context, path)
            self.assertEqual(procedural.bound(), bound)
Example #50
0
    def testFrameRangeMask(self):

        testSequence = IECore.FileSequence(self.temporaryDirectory() +
                                           "/incompleteSequence.####.exr")
        shutil.copyfile(self.fileName, testSequence.fileNameForFrame(1))
        shutil.copyfile(self.fileName, testSequence.fileNameForFrame(3))
        shutil.copyfile(self.offsetDataWindowFileName,
                        testSequence.fileNameForFrame(5))
        shutil.copyfile(self.offsetDataWindowFileName,
                        testSequence.fileNameForFrame(7))

        reader = GafferImage.ImageReader()
        reader["fileName"].setValue(testSequence.fileName)
        reader["missingFrameMode"].setValue(
            GafferImage.ImageReader.MissingFrameMode.Hold)

        oiio = GafferImage.OpenImageIOReader()
        oiio["fileName"].setValue(testSequence.fileName)
        oiio["missingFrameMode"].setValue(
            GafferImage.ImageReader.MissingFrameMode.Hold)

        context = Gaffer.Context()

        # make sure the tile we're comparing isn't black
        # so we can tell if BlackOutside is working.
        blackTile = IECore.FloatVectorData([0] *
                                           GafferImage.ImagePlug.tileSize() *
                                           GafferImage.ImagePlug.tileSize())
        with context:
            for i in range(1, 11):
                context.setFrame(i)
                self.assertNotEqual(
                    reader["out"].channelData("R", imath.V2i(0)), blackTile)

        def assertBlack():

            # format and data window still match
            self.assertEqual(reader["out"]["format"].getValue(),
                             oiio["out"]["format"].getValue())
            self.assertEqual(reader["out"]["dataWindow"].getValue(),
                             oiio["out"]["dataWindow"].getValue())
            self.assertNotEqual(GafferImage.ImageAlgo.image(reader["out"]),
                                GafferImage.ImageAlgo.image(oiio["out"]))
            # the metadata and channel names are at the defaults
            self.assertEqual(reader["out"]["metadata"].getValue(),
                             reader["out"]["metadata"].defaultValue())
            self.assertEqual(reader["out"]["channelNames"].getValue(),
                             reader["out"]["channelNames"].defaultValue())
            # channel data is black
            self.assertEqual(reader["out"].channelData("R", imath.V2i(0)),
                             blackTile)

        def assertMatch():

            self.assertEqual(reader["out"]["format"].getValue(),
                             oiio["out"]["format"].getValue())
            self.assertEqual(reader["out"]["dataWindow"].getValue(),
                             oiio["out"]["dataWindow"].getValue())
            self.assertEqual(reader["out"]["metadata"].getValue(),
                             oiio["out"]["metadata"].getValue())
            self.assertEqual(reader["out"]["channelNames"].getValue(),
                             oiio["out"]["channelNames"].getValue())
            self.assertEqual(reader["out"].channelData("R", imath.V2i(0)),
                             oiio["out"].channelData("R", imath.V2i(0)))
            self.assertImagesEqual(reader["out"], oiio["out"])

        def assertHold(holdFrame):

            context = Gaffer.Context()
            context.setFrame(holdFrame)
            with context:
                holdImage = GafferImage.ImageAlgo.image(reader["out"])
                holdFormat = reader["out"]["format"].getValue()
                holdDataWindow = reader["out"]["dataWindow"].getValue()
                holdMetadata = reader["out"]["metadata"].getValue()
                holdChannelNames = reader["out"]["channelNames"].getValue()
                holdTile = reader["out"].channelData("R", imath.V2i(0))

            self.assertEqual(reader["out"]["format"].getValue(), holdFormat)
            self.assertEqual(reader["out"]["dataWindow"].getValue(),
                             holdDataWindow)
            self.assertEqual(reader["out"]["metadata"].getValue(),
                             holdMetadata)
            self.assertEqual(reader["out"]["channelNames"].getValue(),
                             holdChannelNames)
            self.assertEqual(reader["out"].channelData("R", imath.V2i(0)),
                             holdTile)
            self.assertEqual(GafferImage.ImageAlgo.image(reader["out"]),
                             holdImage)

        reader["start"]["frame"].setValue(4)
        reader["end"]["frame"].setValue(7)

        # frame 0 errors, match from 1-10
        reader["start"]["mode"].setValue(
            GafferImage.ImageReader.FrameMaskMode.None)
        reader["end"]["mode"].setValue(
            GafferImage.ImageReader.FrameMaskMode.None)
        with context:

            for i in range(0, 11):
                context.setFrame(i)
                assertMatch()

        # black from 0-3, match from 4-10
        reader["start"]["mode"].setValue(
            GafferImage.ImageReader.FrameMaskMode.BlackOutside)
        with context:

            for i in range(0, 4):
                context.setFrame(i)
                assertBlack()

            for i in range(4, 11):
                context.setFrame(i)
                assertMatch()

        # black from 0-3, match from 4-7, black from 8-10
        reader["end"]["mode"].setValue(
            GafferImage.ImageReader.FrameMaskMode.BlackOutside)
        with context:

            for i in range(0, 4):
                context.setFrame(i)
                assertBlack()

            for i in range(4, 8):
                context.setFrame(i)
                assertMatch()

            for i in range(8, 11):
                context.setFrame(i)
                assertBlack()

        # hold frame 4 from 0-3, match from 4-7, black from 8-10
        reader["start"]["mode"].setValue(
            GafferImage.ImageReader.FrameMaskMode.ClampToFrame)
        with context:

            for i in range(0, 4):
                context.setFrame(i)
                assertHold(4)

            for i in range(4, 8):
                context.setFrame(i)
                assertMatch()

            for i in range(8, 11):
                context.setFrame(i)
                assertBlack()

        # hold frame 4 from 0-3, match from 4-7, hold frame 7 from 8-10
        reader["end"]["mode"].setValue(
            GafferImage.ImageReader.FrameMaskMode.ClampToFrame)
        with context:

            for i in range(0, 4):
                context.setFrame(i)
                assertHold(4)

            for i in range(4, 8):
                context.setFrame(i)
                assertMatch()

            for i in range(8, 11):
                context.setFrame(i)
                assertHold(7)
Example #51
0
from IgnoredExceptionsTest import IgnoredExceptionsTest
from PrimitiveVariableTest import PrimitiveVariableTest
from FaceVaryingPromotionOpTest import FaceVaryingPromotionOpTest
from MeshDistortionsOpTest import TestMeshDistortionsOp
from PointVelocityDisplaceOp import *
from HexConversionTest import HexConversionTest
from CompressAndDecompressSmoothSkinningDataOpsTest import CompressAndDecompressSmoothSkinningDataOpsTest
from BasicPreset import TestBasicPreset
from ReorderSmoothSkinningInfluencesOpTest import ReorderSmoothSkinningInfluencesOpTest
from NormalizeSmoothSkinningWeightsOpTest import NormalizeSmoothSkinningWeightsOpTest
from LimitSmoothSkinningInfluencesOpTest import LimitSmoothSkinningInfluencesOpTest
from MixSmoothSkinningWeightsOpTest import MixSmoothSkinningWeightsOpTest
from SmoothSmoothSkinningWeightsOpTest import SmoothSmoothSkinningWeightsOpTest
from SkeletonPrimitiveTest import SkeletonPrimitiveTests
from PointSmoothSkinningOpTest import TestPointSmoothSkinningOpTest
from AddAndRemoveSmoothSkinningInfluencesOpTest import AddAndRemoveSmoothSkinningInfluencesOpTest
from LookupTest import LookupTest
from ParameterAlgoTest import ParameterAlgoTest
from PointsPrimitiveEvaluatorTest import PointsPrimitiveEvaluatorTest

if IECore.withASIO():
    from DisplayDriverTest import *

if IECore.withFreeType():
    from FontTest import *

unittest.TestProgram(
    testRunner=unittest.TextTestRunner(stream=IECore.CompoundStream(
        [sys.stderr, open("test/IECore/resultsPython.txt", "w")]),
                                       verbosity=2))
    def testAllRenderedSignal(self):
        class AllRenderedTest:
            allRenderedSignalCalled = False

            def allRendered(self):
                self.allRenderedSignalCalled = True

        script = Gaffer.ScriptNode()
        script["plane"] = GafferScene.Plane()

        # test creating/deleting a single procedural:
        t = AllRenderedTest()
        allRenderedConnection = GafferScene.SceneProcedural.allRenderedSignal(
        ).connect(t.allRendered)

        procedural = GafferScene.SceneProcedural(script["plane"]["out"],
                                                 Gaffer.Context(), "/")
        self.assertEqual(t.allRenderedSignalCalled, False)
        del procedural
        self.assertEqual(t.allRenderedSignalCalled, True)

        # create/delete two of 'em:
        t = AllRenderedTest()
        allRenderedConnection = GafferScene.SceneProcedural.allRenderedSignal(
        ).connect(t.allRendered)
        procedural1 = GafferScene.SceneProcedural(script["plane"]["out"],
                                                  Gaffer.Context(), "/")
        procedural2 = GafferScene.SceneProcedural(script["plane"]["out"],
                                                  Gaffer.Context(), "/")

        self.assertEqual(t.allRenderedSignalCalled, False)
        del procedural1
        self.assertEqual(t.allRenderedSignalCalled, False)
        del procedural2
        self.assertEqual(t.allRenderedSignalCalled, True)

        # now actually render them:
        renderer = IECore.CapturingRenderer()
        t = AllRenderedTest()
        allRenderedConnection = GafferScene.SceneProcedural.allRenderedSignal(
        ).connect(t.allRendered)
        procedural1 = GafferScene.SceneProcedural(script["plane"]["out"],
                                                  Gaffer.Context(), "/")
        procedural2 = GafferScene.SceneProcedural(script["plane"]["out"],
                                                  Gaffer.Context(), "/")

        self.assertEqual(t.allRenderedSignalCalled, False)
        with IECore.WorldBlock(renderer):
            renderer.procedural(procedural1)

        self.assertEqual(t.allRenderedSignalCalled, False)
        with IECore.WorldBlock(renderer):
            renderer.procedural(procedural2)

        self.assertEqual(t.allRenderedSignalCalled, True)

        # now render one and delete one:
        renderer = IECore.CapturingRenderer()
        t = AllRenderedTest()
        allRenderedConnection = GafferScene.SceneProcedural.allRenderedSignal(
        ).connect(t.allRendered)
        procedural1 = GafferScene.SceneProcedural(script["plane"]["out"],
                                                  Gaffer.Context(), "/")
        procedural2 = GafferScene.SceneProcedural(script["plane"]["out"],
                                                  Gaffer.Context(), "/")

        self.assertEqual(t.allRenderedSignalCalled, False)
        del procedural1
        self.assertEqual(t.allRenderedSignalCalled, False)
        with IECore.WorldBlock(renderer):
            renderer.procedural(procedural2)

        self.assertEqual(t.allRenderedSignalCalled, True)
Example #53
0
    def testHashIncludesBlackPixels(self):

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

        crop = GafferImage.Crop()
        crop["in"].setInput(constant["out"])
        crop["areaSource"].setValue(crop.AreaSource.Area)
        crop["area"].setValue(IECore.Box2i(IECore.V2i(0), IECore.V2i(200)))
        crop["affectDisplayWindow"].setValue(False)
        crop["affectDataWindow"].setValue(False)

        # Samples the whole data window
        sampler1 = GafferImage.Sampler(
            crop["out"],
            "R",
            IECore.Box2i(IECore.V2i(0), IECore.V2i(200)),
            boundingMode=GafferImage.Sampler.BoundingMode.Black)
        # Samples the whole data window and then some.
        sampler2 = GafferImage.Sampler(
            crop["out"],
            "R",
            IECore.Box2i(IECore.V2i(0), IECore.V2i(210)),
            boundingMode=GafferImage.Sampler.BoundingMode.Black)
        # Samples the whole data window and then some and then some more.
        sampler3 = GafferImage.Sampler(
            crop["out"],
            "R",
            IECore.Box2i(IECore.V2i(0), IECore.V2i(220)),
            boundingMode=GafferImage.Sampler.BoundingMode.Black)

        # The hashes must take account of the additional pixels being sampled.
        self.assertNotEqual(sampler1.hash(), sampler2.hash())
        self.assertNotEqual(sampler2.hash(), sampler3.hash())
        self.assertNotEqual(sampler3.hash(), sampler1.hash())
Example #54
0
    def testEditSubdivisionAttributes(self):

        script = Gaffer.ScriptNode()

        script["cube"] = GafferScene.Cube()
        script["cube"]["dimensions"].setValue(IECore.V3f(2))

        script["meshType"] = GafferScene.MeshType()
        script["meshType"]["in"].setInput(script["cube"]["out"])
        script["meshType"]["meshType"].setValue("catmullClark")

        script["attributes"] = GafferArnold.ArnoldAttributes()
        script["attributes"]["in"].setInput(script["meshType"]["out"])
        script["attributes"]["attributes"]["subdivIterations"][
            "enabled"].setValue(True)

        script["outputs"] = GafferScene.Outputs()
        script["outputs"].addOutput(
            "beauty",
            IECore.Display(
                "test", "ieDisplay", "rgba", {
                    "driverType": "ClientDisplayDriver",
                    "displayType": "IECore::ClientDisplayDriver",
                    "displayHost": "localhost",
                    "displayPort": "2500",
                    "remoteDisplayType": "GafferImage::GafferDisplayDriver",
                }))
        script["outputs"]["in"].setInput(script["attributes"]["out"])

        # Emulate the connection the UI makes, so the Display knows someone is listening and
        # it needs to actually make servers.
        dataReceivedConnection = GafferImage.Display.dataReceivedSignal(
        ).connect(lambda plug: None)

        script["display"] = GafferImage.Display()
        script["display"]["port"].setValue(2500)

        script["imageStats"] = GafferImage.ImageStats()
        script["imageStats"]["in"].setInput(script["display"]["out"])
        script["imageStats"]["channels"].setValue(
            IECore.StringVectorData(["R", "G", "B", "A"]))
        script["imageStats"]["regionOfInterest"].setValue(
            IECore.Box2i(IECore.V2i(0), IECore.V2i(640, 480)))

        script["render"] = self._createInteractiveRender()
        script["render"]["in"].setInput(script["outputs"]["out"])

        # Render the cube with one level of subdivision. Check we get roughly the
        # alpha coverage we expect.

        script["render"]["state"].setValue(script["render"].State.Running)
        time.sleep(1)

        self.assertAlmostEqual(script["imageStats"]["average"][3].getValue(),
                               0.381,
                               delta=0.001)

        # Now up the number of subdivision levels. The alpha coverage should
        # increase as the shape tends towards the limit surface.

        script["attributes"]["attributes"]["subdivIterations"][
            "value"].setValue(4)
        time.sleep(1)

        self.assertAlmostEqual(script["imageStats"]["average"][3].getValue(),
                               0.424,
                               delta=0.001)
Example #55
0
    def __annotationsMenu(self):

        graphGadget = self.graphGadget()
        annotationsGadget = graphGadget["__annotations"]

        annotations = Gaffer.MetadataAlgo.annotationTemplates() + [
            "user", annotationsGadget.untemplatedAnnotations
        ]
        visiblePattern = annotationsGadget.getVisibleAnnotations()
        visibleAnnotations = {
            a
            for a in annotations
            if IECore.StringAlgo.matchMultiple(a, visiblePattern)
        }

        result = IECore.MenuDefinition()

        result.append(
            "All", {
                "checkBox":
                len(visibleAnnotations) == len(annotations),
                "command":
                functools.partial(Gaffer.WeakMethod(
                    self.__setVisibleAnnotations),
                                  annotations={"*"})
            })

        result.append(
            "None", {
                "checkBox":
                len(visibleAnnotations) == 0,
                "command":
                functools.partial(Gaffer.WeakMethod(
                    self.__setVisibleAnnotations),
                                  annotations=set())
            })

        result.append("__annotationsDivider__", {"divider": True})

        def appendMenuItem(annotation, label=None):

            if label is None:
                # Support snake_case and CamelCase for conversion of name to label,
                # since not all extensions use the Gaffer convention.
                labelParts = annotation.split(":")
                label = "/".join(
                    (" ".join(x.title() for x in p.split("_"))
                     ) if "_" in p else IECore.CamelCase.toSpaced(p)
                    for p in labelParts)

            if annotation in visibleAnnotations:
                toggled = visibleAnnotations - {annotation}
            else:
                toggled = visibleAnnotations | {annotation}

            result.append(
                "/" + label, {
                    "checkBox":
                    annotation in visibleAnnotations,
                    "command":
                    functools.partial(Gaffer.WeakMethod(
                        self.__setVisibleAnnotations),
                                      annotations=toggled)
                })

        userAnnotations = set(
            Gaffer.MetadataAlgo.annotationTemplates(userOnly=True))
        for annotation in sorted(userAnnotations):
            appendMenuItem(annotation)

        if len(userAnnotations):
            result.append("__userDivider__", {"divider": True})
        appendMenuItem("user")

        result.append("__nonUserDivider__", {"divider": True})

        for annotation in sorted(Gaffer.MetadataAlgo.annotationTemplates()):
            if annotation not in userAnnotations:
                appendMenuItem(annotation)

        result.append("__otherDivider__", {"divider": True})
        appendMenuItem(annotationsGadget.untemplatedAnnotations, label="Other")

        return result
Example #56
0
#  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
#  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
##########################################################################

import IECore

import Gaffer


class TaskContextVariables(Gaffer.TaskContextProcessor):
    def __init__(self, name="TaskContextVariables"):

        Gaffer.TaskContextProcessor.__init__(self, name)

        self["variables"] = Gaffer.CompoundDataPlug()

    def _processedContexts(self, context):

        context = Gaffer.Context(context)
        for variable in self["variables"].values():
            data, name = self["variables"].memberDataAndName(variable)
            if data is not None:
                context[name] = data

        return [context]


IECore.registerRunTimeTyped(TaskContextVariables,
                            typeName="Gaffer::TaskContextVariables")
Example #57
0
    def testNPrimitiveVariable(self):

        c = IECore.CurvesPrimitive(IECore.IntVectorData([4]),
                                   IECore.CubicBasisf.catmullRom())
        c["P"] = IECore.PrimitiveVariable(
            IECore.PrimitiveVariable.Interpolation.Vertex,
            IECore.V3fVectorData([IECore.V3f(x, 0, 0) for x in range(0, 4)]))

        with IECoreArnold.UniverseBlock(writable=True):

            # No N - should be a ribbon

            n = IECoreArnold.NodeAlgo.convert(c)
            self.assertEqual(arnold.AiNodeGetStr(n, "mode"), "ribbon")
            self.assertEqual(
                arnold.AiNodeGetArray(n, "orientations").contents.nelements, 0)

            # N - should be oriented

            c["N"] = IECore.PrimitiveVariable(
                IECore.PrimitiveVariable.Interpolation.Vertex,
                IECore.V3fVectorData([
                    IECore.V3f(0, math.sin(x), math.cos(x))
                    for x in range(0, 4)
                ]))

            n = IECoreArnold.NodeAlgo.convert(c)
            self.assertEqual(arnold.AiNodeGetStr(n, "mode"), "oriented")
            orientations = arnold.AiNodeGetArray(n, "orientations")
            self.assertEqual(orientations.contents.nelements, 4)

            for i in range(0, 4):
                self.assertEqual(arnold.AiArrayGetVec(orientations, i),
                                 arnold.AtVector(0, math.sin(i), math.cos(i)))

            # Motion blurred N - should be oriented and deforming

            c2 = c.copy()
            c2["N"] = IECore.PrimitiveVariable(
                IECore.PrimitiveVariable.Interpolation.Vertex,
                IECore.V3fVectorData([
                    IECore.V3f(0, math.sin(x + 0.2), math.cos(x + 0.2))
                    for x in range(0, 4)
                ]))

            n = IECoreArnold.NodeAlgo.convert([c, c2], [0.0, 1.0])
            self.assertEqual(arnold.AiNodeGetStr(n, "mode"), "oriented")

            orientations = arnold.AiNodeGetArray(n, "orientations")
            self.assertEqual(orientations.contents.nelements, 4)
            self.assertEqual(orientations.contents.nkeys, 2)

            for i in range(0, 4):
                self.assertEqual(arnold.AiArrayGetVec(orientations, i),
                                 arnold.AtVector(0, math.sin(i), math.cos(i)))
                self.assertEqual(
                    arnold.AiArrayGetVec(orientations, i + 4),
                    arnold.AtVector(0, math.sin(i + 0.2), math.cos(i + 0.2)))
Example #58
0
    def test2x2Checker(self):

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

        # As long as the sample region includes the valid range of our image, and all
        # the pixels we're going to request, it should have no effect on our sampling.
        # So test with a few such ranges.
        sampleRegions = [
            IECore.Box2i(IECore.V2i(0),
                         IECore.V2i(GafferImage.ImagePlug.tileSize())),
            IECore.Box2i(-IECore.V2i(GafferImage.ImagePlug.tileSize()),
                         IECore.V2i(GafferImage.ImagePlug.tileSize())),
            IECore.Box2i(IECore.V2i(-1), IECore.V2i(4)),
        ]

        # List of positions inside and outside of the image, along
        # with expected values if outside points are clamped inside.
        samples = [
            (IECore.V2i(0, 0), 1),
            (IECore.V2i(1, 0), 0),
            (IECore.V2i(1, 1), 1),
            (IECore.V2i(0, 1), 0),
            (IECore.V2i(-1, 0), 1),
            (IECore.V2i(2, 0), 0),
            (IECore.V2i(0, 3), 0),
            (IECore.V2i(0, -1), 1),
            (IECore.V2i(3, 3), 1),
            (IECore.V2i(-1, -1), 1),
            (IECore.V2i(-1, 2), 0),
            (IECore.V2i(2, 2), 1),
            (IECore.V2f(1, 1), 0.5),
        ]

        # Assert all is as expected for all combos of region and sample.
        for region in sampleRegions:
            sampler = GafferImage.Sampler(
                reader["out"],
                "R",
                region,
                boundingMode=GafferImage.Sampler.BoundingMode.Clamp)
            for position, value in samples:
                self.assertEqual(sampler.sample(position.x, position.y), value)
Example #59
0
    def testPassThrough(self):

        sphere = IECoreScene.SpherePrimitive()
        input = GafferSceneTest.CompoundObjectSource()
        input["in"].setValue(
            IECore.CompoundObject({
                "bound": IECore.Box3fData(sphere.bound()),
                "children": {
                    "groupA": {
                        "bound": IECore.Box3fData(sphere.bound()),
                        "children": {
                            "sphereAA": {
                                "bound": IECore.Box3fData(sphere.bound()),
                                "object": sphere,
                            },
                            "sphereAB": {
                                "bound": IECore.Box3fData(sphere.bound()),
                                "object": sphere,
                            },
                        },
                    },
                    "groupB": {
                        "bound": IECore.Box3fData(sphere.bound()),
                        "children": {
                            "sphereBA": {
                                "bound": IECore.Box3fData(sphere.bound()),
                                "object": sphere,
                            },
                            "sphereBB": {
                                "bound": IECore.Box3fData(sphere.bound()),
                                "object": sphere,
                            },
                        },
                    },
                },
            }), )

        isolate = GafferScene.Isolate()
        isolate["in"].setInput(input["out"])

        self.assertSceneValid(input["out"])
        self.assertSceneValid(isolate["out"])

        # with no filter applied, nothing should be isolated so we should have a perfect pass through

        self.assertScenesEqual(input["out"], isolate["out"])
        self.assertSceneHashesEqual(input["out"], isolate["out"])
        self.assertTrue(input["out"].object(
            "/groupA/sphereAA",
            _copy=False).isSame(isolate["out"].object("/groupA/sphereAA",
                                                      _copy=False)))

        # and even with a filter applied, we should have a perfect pass through if the node is disabled.

        filter = GafferScene.PathFilter()
        filter["paths"].setValue(IECore.StringVectorData(["/*"]))
        isolate["filter"].setInput(filter["out"])

        isolate["enabled"].setValue(False)

        self.assertScenesEqual(input["out"], isolate["out"])
        self.assertSceneHashesEqual(input["out"], isolate["out"])
        self.assertTrue(input["out"].object(
            "/groupA/sphereAA",
            _copy=False).isSame(isolate["out"].object("/groupA/sphereAA",
                                                      _copy=False)))
Example #60
0
            def bound(self):

                return IECore.Box3f(IECore.V3f(-20, 10, 2),
                                    IECore.V3f(10, 15, 5))