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" )
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 )
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" )
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() )
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 )
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(), } )
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
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
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 ) ) )
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 ) )
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 )
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 ) )
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" )
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 ) } )
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
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"] ) )
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"] ) )
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 ) )
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 )
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 )
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() ) )
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
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 )
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
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 )
def msg(level): IECore.msg(level, "test", "test") self.waitForIdle(10)
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 ) )
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 )
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)
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")
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 ) )
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 ) )
def doOperation(self, operands): return IECore.StringData(operands['name'].value)
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()
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())
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)
def doOperation(self, operands): return IECore.StringData("Yes!")
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()))
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)
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)
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)
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())
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)
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
# 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")
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)))
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)
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)))
def bound(self): return IECore.Box3f(IECore.V3f(-20, 10, 2), IECore.V3f(10, 15, 5))