"width": 30 }, "note": { "color": imath.Color3f(0.3479, 0.4386, 0.5), "title": "Note: ", "width": 30 }, "general": { "color": None, "width": 40 } } # Just using a default node size for those without __uiBound. This should # really go ask its NodeGadget. defaultNodeSize = imath.Box2f(imath.V2f(0.0), imath.V2f(10, 5)) def conform(node, type_="default"): """ Conform a Backdrop's color, title prefix and width based on the style guide. """ with Gaffer.UndoScope(node.ancestor(Gaffer.ScriptNode)): defaults = backdropDefaults.get(type_, {}) setColor(node, defaults.get("color", None)) w = defaults.get("width", None) if w:
def encloseSelectionWithBackdrop(parent, padding=2): """ Roughly encloses the selection in a backdrop node. If there are other backdrops in the selection, they will be re-layered on top of the new one. """ scriptNode = parent.ancestor(Gaffer.ScriptNode) or parent sel = scriptNode.selection() if len(sel) == 0: return with Gaffer.UndoScope(scriptNode): extents = imath.Box2f() extents.makeEmpty() color = None existingBackdrops = [] for s in sel: p = s["__uiPosition"].getValue() b = s["__uiBound"].getValue( ) if "__uiBound" in s else defaultNodeSize extents.extendBy(p + b.min()) extents.extendBy(p + b.max()) if isinstance(s, Gaffer.Backdrop): color = Gaffer.Metadata.value(s, "nodeGadget:color") existingBackdrops.append(s) extents.extendBy(extents.min() - imath.V2f(padding)) extents.extendBy(extents.max() + imath.V2f(padding)) # We need to remove the existing backdrops, add the underlying one # then add the old ones back, otherwise the new one will be on top for b in existingBackdrops: parent.removeChild(b) backdrop = Gaffer.Backdrop() backdrop["title"].setValue("") setColor(backdrop, color) backdrop.addChild( Gaffer.V2fPlug( "__uiPosition", defaultValue=imath.V2f(0, 0), flags=Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, )) backdrop.addChild( Gaffer.Box2fPlug( "__uiBound", defaultValue=imath.Box2f(imath.V2f(-10, -10), imath.V2f(10, 10)), flags=Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, )) backdrop["__uiPosition"].setValue(extents.min()) backdrop["__uiBound"].setValue( imath.Box2f(imath.V2f(0.0), extents.max() - extents.min())) parent.addChild(backdrop) for b in existingBackdrops: parent.addChild(b) return backdrop
floating=True) __nodeEditorWindow._qtWidget().setFocus() GafferUI.WidgetAlgo.grab(widget=__nodeEditorWindow, imagePath=__tempImagePath) __dispatchScript(script="scripts/{}_edit.gfr".format(__imageName), tasks=["ImageWriter"], settings=[ "-ImageReader.fileName '\"{}\"'".format(__tempImagePath), "-ImageWriter.fileName '\"{}\"'".format( os.path.abspath("images/{}.png".format(__imageName))) ]) # Task: the Aperture and Focal Length projection mode in the Node Editor __imageName = "taskCameraApertureFocalLengthPlugs" __tempImagePath = __getTempFilePath("{}.png".format(__imageName)) script["Camera"]["perspectiveMode"].setValue(1) script["Camera"]["aperture"].setValue(imath.V2f(36.0, 24.0)) script["Camera"]["focalLength"].setValue(50.0) GafferUI.WidgetAlgo.grab(widget=__nodeEditorWindow, imagePath=__tempImagePath) __dispatchScript(script="scripts/{}_edit.gfr".format(__imageName), tasks=["ImageWriter"], settings=[ "-ImageReader.fileName '\"{}\"'".format(__tempImagePath), "-ImageWriter.fileName '\"{}\"'".format( os.path.abspath("images/{}.png".format(__imageName))) ]) # Task: the Custom aperture mode and aperture.x and aperture.y plugs in the Node Editor __imageName = "taskCameraCustomAperturePlugs" __tempImagePath = __getTempFilePath("{}.png".format(__imageName)) script["Camera"]["aperture"].setValue(imath.V2f(40.96, 21.6)) Gaffer.Metadata.registerValue(script["Camera"]["aperture"],
def testContextChangedAndGIL(self): script = Gaffer.ScriptNode() script["plane"] = GafferScene.Plane() script["plane"]["divisions"].setValue(imath.V2i(20)) script["sphere"] = GafferScene.Sphere() script["expression"] = Gaffer.Expression() script["expression"].setExpression( "parent['sphere']['radius'] = context.get( 'minRadius', 0.1 ) + context.getFrame()" ) script["instancer"] = GafferScene.Instancer() script["instancer"]["in"].setInput(script["plane"]["out"]) script["instancer"]["instances"].setInput(script["sphere"]["out"]) script["instancer"]["parent"].setValue("/plane") context = Gaffer.Context() traverseConnection = Gaffer.ScopedConnection( GafferSceneTest.connectTraverseSceneToContextChangedSignal( script["instancer"]["out"], context)) with context: context.setFrame(10) context.setFramesPerSecond(50) context.setTime(1) context.set("a", 1) context.set("a", 2.0) context.set("a", "a") context.set("a", imath.V2i()) context.set("a", imath.V3i()) context.set("a", imath.V2f()) context.set("a", imath.V3f()) context.set("a", imath.Color3f()) context.set("a", IECore.BoolData(True)) context["b"] = 1 context["b"] = 2.0 context["b"] = "b" context["b"] = imath.V2i() context["b"] = imath.V3i() context["b"] = imath.V2f() context["b"] = imath.V3f() context["b"] = imath.Color3f() context["b"] = IECore.BoolData(True) with Gaffer.BlockedConnection(traverseConnection): # Must add it with the connection disabled, otherwise # the addition causes a traversal, and then remove() gets # all its results from the cache. context["minRadius"] = 0.2 context.remove("minRadius") with Gaffer.BlockedConnection(traverseConnection): context["minRadius"] = 0.3 del context["minRadius"]
def testBasic(self): g = GafferScene.Group() inputs = [] for shader, name in [ ("spot_light", "spot1"), ("spot_light", "spot2"), ("distant_light", "distant1"), ("skydome_light", "env1"), ]: l = GafferArnold.ArnoldLight() l.loadShader(shader) l["name"].setValue(name) inputs.append(l) inputs.append(GafferScene.Camera()) for i in inputs: g["in"][-1].setInput(i["out"]) f = GafferScene.PathFilter() f['paths'].setValue( IECore.StringVectorData( ["/group/spot1", "/group/env1", "/group/distant1"])) lc = GafferScene.LightToCamera() lc["in"].setInput(g["out"]) lc["filter"].setInput(f["out"]) # Test spot to persp cam self.assertEqual( lc["out"].object("/group/spot1").parameters(), IECore.CompoundData({ 'projection:fov': IECore.FloatData(65), 'clippingPlanes': IECore.V2fData(imath.V2f(0.01, 100000)), 'projection': IECore.StringData('perspective'), 'resolutionOverride': IECore.V2iData(imath.V2i(512, 512)), 'screenWindow': IECore.Box2fData( imath.Box2f(imath.V2f(-1, -1), imath.V2f(1, 1))) })) # Test distant to ortho cam self.assertEqual( lc["out"].object("/group/distant1").parameters(), IECore.CompoundData({ 'clippingPlanes': IECore.V2fData(imath.V2f(-100000, 100000)), 'projection': IECore.StringData('orthographic'), 'resolutionOverride': IECore.V2iData(imath.V2i(512, 512)), 'screenWindow': IECore.Box2fData( imath.Box2f(imath.V2f(-1, -1), imath.V2f(1, 1))) })) # Test light with no corresponding camera ( gets default cam ) self.assertEqual( lc["out"].object("/group/env1").parameters(), IECore.CompoundData({ 'projection': IECore.StringData('perspective'), 'resolutionOverride': IECore.V2iData(imath.V2i(512, 512)) })) self.assertEqual(lc["out"].set("__lights").value.paths(), ["/group/spot2"]) self.assertEqual( set(lc["out"].set("__cameras").value.paths()), set([ "/group/camera", "/group/spot1", "/group/distant1", "/group/env1" ]))
def test(self): # Build network to perform closest point queries # from a plane, against a copy of the same plane # converted to a points primitive. Closest points # should be exact vertices. plane = GafferScene.Plane() plane["dimensions"].setValue(imath.V2f(2)) planeFilter = GafferScene.PathFilter() planeFilter["paths"].setValue(IECore.StringVectorData(["/plane"])) planeTransform = GafferScene.Transform() planeTransform["in"].setInput(plane["out"]) planeTransform["filter"].setInput(planeFilter["out"]) points = GafferScene.MeshToPoints() points["in"].setInput(plane["out"]) points["filter"].setInput(planeFilter["out"]) pointsTransform = GafferScene.Transform() pointsTransform["in"].setInput(points["out"]) pointsTransform["filter"].setInput(planeFilter["out"]) sampler = GafferScene.ClosestPointSampler() sampler["in"].setInput(planeTransform["out"]) sampler["source"].setInput(pointsTransform["out"]) sampler["filter"].setInput(planeFilter["out"]) sampler["sourceLocation"].setValue("/plane") sampler["prefix"].setValue("sampled:") self.assertScenesEqual(sampler["out"], plane["out"]) # Identical transforms. Closest point should # be the same as the query point. sampler["primitiveVariables"].setValue("P") self.assertSceneValid(sampler["out"]) inMesh = sampler["in"].object("/plane") outMesh = sampler["out"].object("/plane") self.assertEqual(set(outMesh.keys()), set(inMesh.keys() + ["sampled:P"])) self.assertEqual(outMesh["sampled:P"], inMesh["P"]) # Translate source off to one side. A single # point is the closest for all query points. pointsTransform["transform"]["translate"].setValue(imath.V3f(5, 5, 0)) outMesh = sampler["out"].object("/plane") self.assertEqual( outMesh["sampled:P"].data, IECore.V3fVectorData([imath.V3f(4, 4, 0)] * 4, IECore.GeometricData.Interpretation.Point)) # Translate the plane too. Sampled results should # be adjusted so that they are relative to the local # space of the plane. planeTransform["transform"]["translate"].setValue(imath.V3f(-1, 0, 0)) outMesh = sampler["out"].object("/plane") self.assertEqual( outMesh["sampled:P"].data, IECore.V3fVectorData([imath.V3f(5, 4, 0)] * 4, IECore.GeometricData.Interpretation.Point))
def testExceptionsDuringCompute(self): # Make this scene # # - bigSphere # - littleSphere (with exception in attributes expression) s = Gaffer.ScriptNode() s["s1"] = GafferScene.Sphere() s["s1"]["name"].setValue("bigSphere") s["s2"] = GafferScene.Sphere() s["s2"]["name"].setValue("littleSphere") s["s2"]["radius"].setValue(0.1) s["p"] = GafferScene.Parent() s["p"]["in"].setInput(s["s1"]["out"]) s["p"]["children"][0].setInput(s["s2"]["out"]) s["p"]["parent"].setValue("/bigSphere") s["a"] = GafferScene.StandardAttributes() s["a"]["in"].setInput(s["p"]["out"]) s["a"]["attributes"]["doubleSided"]["enabled"].setValue(True) s["e"] = Gaffer.Expression() s["e"].setExpression( 'parent["a"]["attributes"]["doubleSided"]["value"] = context["nonexistent"]' ) s["f"] = GafferScene.PathFilter() s["f"]["paths"].setValue( IECore.StringVectorData(["/bigSphere/littleSphere"])) s["a"]["filter"].setInput(s["f"]["out"]) # Try to view it sg = GafferSceneUI.SceneGadget() sg.setScene(s["a"]["out"]) sg.setMinimumExpansionDepth(4) with GafferUI.Window() as w: gw = GafferUI.GadgetWidget(sg) gw.getViewportGadget().setPlanarMovement(False) gw.getViewportGadget().setCamera( IECoreScene.Camera(parameters={ "projection": "perspective", })) originalMessageHandler = IECore.MessageHandler.getDefaultHandler() mh = IECore.CapturingMessageHandler() IECore.MessageHandler.setDefaultHandler( IECore.LevelFilteredMessageHandler( mh, IECore.LevelFilteredMessageHandler.defaultLevel())) try: w.setVisible(True) self.waitForIdle(1000) sg.waitForCompletion() # Check we were told about the problem self.assertEqual(len(mh.messages), 1) self.assertEqual(mh.messages[0].level, mh.Level.Error) self.assertTrue("nonexistent" in mh.messages[0].message) # And that there isn't some half-assed partial scene # being displayed. self.assertTrue(sg.bound().isEmpty()) gw.getViewportGadget().frame( imath.Box3f(imath.V3f(-1), imath.V3f(1))) self.assertObjectAt(sg, imath.V2f(0.5), None) # And that redraws don't cause more fruitless attempts # to compute the scene. gw.getViewportGadget().frame( imath.Box3f(imath.V3f(-1.1), imath.V3f(1.1))) self.waitForIdle(1000) self.assertEqual(len(mh.messages), 1) self.assertObjectAt(sg, imath.V2f(0.5), None) self.assertTrue(sg.bound().isEmpty()) # Fix the problem with the scene, and check that we can see something now s["f"]["enabled"].setValue(False) sg.waitForCompletion() self.assertEqual(len(mh.messages), 1) self.assertFalse(sg.bound().isEmpty()) self.assertObjectAt(sg, imath.V2f(0.5), IECore.InternedStringVectorData(["bigSphere"])) finally: IECore.MessageHandler.setDefaultHandler(originalMessageHandler)
def testLayerMapping( self ) : constant1 = GafferImage.Constant() constant1['color'].setValue( imath.Color4f( 0.1, 0.2, 0.3, 0.4 ) ) constant1["format"].setValue( GafferImage.Format( 10, 10, 1.000 ) ) metadata1 = GafferImage.ImageMetadata() metadata1["in"].setInput( constant1["out"] ) metadata1["metadata"].addMember( "test", 1 ) constant2 = GafferImage.Constant() constant2['color'].setValue( imath.Color4f( 0.2, 0.4, 0.6, 0.8 ) ) constant2["format"].setValue( GafferImage.Format( 20, 20, 1.000 ) ) metadata2 = GafferImage.ImageMetadata() metadata2["in"].setInput( constant2["out"] ) metadata2["metadata"].addMember( "test", 2 ) switch = GafferImage.ImageSwitch() switch["in"][0].setInput( metadata1["out"] ) switch["in"][1].setInput( metadata2["out"] ) e = Gaffer.Expression() switch.addChild( e ) e.setExpression( 'parent["index"] = context["collect:layerName"] != "A"', "python" ) collect = GafferImage.CollectImages() collect["in"].setInput( switch["out"] ) # Metadata and format are driven by the first layer collect["rootLayers"].setValue( IECore.StringVectorData( [ 'A', 'B' ] ) ) self.assertEqual( collect["out"]["format"].getValue(), GafferImage.Format( 10, 10, 1) ) self.assertEqual( collect["out"]["metadata"].getValue(), IECore.CompoundData( { "test" : 1 } ) ) collect["rootLayers"].setValue( IECore.StringVectorData( [ 'B', 'A' ] ) ) self.assertEqual( collect["out"]["format"].getValue(), GafferImage.Format( 20, 20, 1) ) self.assertEqual( collect["out"]["metadata"].getValue(), IECore.CompoundData( { "test" : 2 } ) ) collect["rootLayers"].setValue( IECore.StringVectorData( [] ) ) self.assertEqual( collect["out"]["format"].getValue(), constant1["format"].getDefaultFormat( Gaffer.Context.current() ) ) self.assertEqual( collect["out"]["metadata"].getValue(), IECore.CompoundData() ) sampler = GafferImage.ImageSampler( "ImageSampler" ) sampler["pixel"].setValue( imath.V2f( 1, 1 ) ) sampler["channels"].setValue( IECore.StringVectorData( [ "A.R", "A.G","A.B","A.A" ] ) ) sampler["image"].setInput( collect["out"] ) collect["rootLayers"].setValue( IECore.StringVectorData( [ 'A' ] ) ) self.assertEqual( list(collect["out"]["channelNames"].getValue()), [ "A.R", "A.G", "A.B", "A.A" ] ) self.assertEqual( sampler["color"].getValue(), imath.Color4f( 0.1, 0.2, 0.3, 0.4 ) ) # Test simple duplicate collect["rootLayers"].setValue( IECore.StringVectorData( [ 'A', 'A' ] ) ) self.assertEqual( list(collect["out"]["channelNames"].getValue()), [ "A.R", "A.G", "A.B", "A.A" ] ) self.assertEqual( sampler["color"].getValue(), imath.Color4f( 0.1, 0.2, 0.3, 0.4 ) ) collect["rootLayers"].setValue( IECore.StringVectorData( [ 'A', 'B' ] ) ) self.assertEqual( list(collect["out"]["channelNames"].getValue()), [ "A.R", "A.G", "A.B", "A.A", "B.R", "B.G", "B.B", "B.A" ] ) self.assertEqual( sampler["color"].getValue(), imath.Color4f( 0.1, 0.2, 0.3, 0.4 ) ) sampler["channels"].setValue( IECore.StringVectorData( [ "B.R", "B.G","B.B","B.A" ] ) ) self.assertEqual( sampler["color"].getValue(), imath.Color4f( 0.2, 0.4, 0.6, 0.8 ) ) # Test overlapping names take the first layer constant1["layer"].setValue( "B" ) collect["rootLayers"].setValue( IECore.StringVectorData( [ 'A', 'A.B' ] ) ) sampler["channels"].setValue( IECore.StringVectorData( [ "A.B.R", "A.B.G","A.B.B","A.B.A" ] ) ) self.assertEqual( list(collect["out"]["channelNames"].getValue()), [ "A.B.R", "A.B.G", "A.B.B", "A.B.A" ] ) self.assertEqual( sampler["color"].getValue(), imath.Color4f( 0.1, 0.2, 0.3, 0.4 ) ) collect["rootLayers"].setValue( IECore.StringVectorData( [ 'A.B', 'A' ] ) ) self.assertEqual( list(collect["out"]["channelNames"].getValue()), [ "A.B.R", "A.B.G", "A.B.B", "A.B.A" ] ) self.assertEqual( sampler["color"].getValue(), imath.Color4f( 0.2, 0.4, 0.6, 0.8 ) )
def testAttributes(self): p = GafferScene.Plane() a = GafferScene.CustomAttributes() a["attributes"].addChild(Gaffer.NameValuePlug("a", 42.5)) a["attributes"].addChild(Gaffer.NameValuePlug("b", 12)) a["attributes"].addChild(Gaffer.NameValuePlug("c", True)) a["attributes"].addChild(Gaffer.NameValuePlug("d", "blah")) a["attributes"].addChild( Gaffer.NameValuePlug("e", imath.V3f(0.1, 0.2, 0.3))) a["attributes"].addChild(Gaffer.NameValuePlug("f", imath.V2f(0.4, 0.5))) a["attributes"].addChild( Gaffer.NameValuePlug("g", imath.Color3f(0.6, 0.7, 0.8))) a["attributes"].addChild(Gaffer.NameValuePlug("h", imath.M44f(3))) # There's no Color4f type in OSL, so We can't currently get the 4th component, but we can # get the first 3 a["attributes"].addChild( Gaffer.NameValuePlug("i", imath.Color4f(0.6, 0.7, 0.8, 0.9))) a["in"].setInput(p["out"]) o = GafferOSL.OSLObject() o["in"].setInput(p["out"]) o["in"].setInput(a["out"]) # shading network to output attributes as formatted string. inPoint = GafferOSL.OSLShader() inPoint.loadShader("ObjectProcessing/InPoint") code = GafferOSL.OSLCode() code["out"].addChild( Gaffer.StringPlug("testString", direction=Gaffer.Plug.Direction.Out)) o["primitiveVariables"].addChild(Gaffer.NameValuePlug( "testString", "")) o["primitiveVariables"][0]["value"].setInput(code["out"]["testString"]) f = GafferScene.PathFilter() f["paths"].setValue(IECore.StringVectorData(["/plane"])) a["filter"].setInput(f["out"]) o["filter"].setInput(f["out"]) code["code"].setValue( inspect.cleandoc(""" float a = -1; getattribute( "a", a ); float ax = -1; getattribute( "ax", ax ); int b = -1; getattribute( "b", b ); int c = -1; getattribute( "c", c ); string d = ""; getattribute( "d", d ); vector e = -1; getattribute( "e", e ); vector f = -1; getattribute( "f", f ); color g = -1; getattribute( "g", g ); matrix h = -1; getattribute( "h", h ); color i = -1; getattribute( "i", i ); testString = format( "TEST STRING : <%.2f><%.2f><%i><%i><%s><%.2f><%.2f><%.2f><%.2f %.2f %.2f %.2f><%.2f>", a, ax, b, c, d, e, f, g, h[0][0], h[0][1], h[1][0], h[1][1], i ); """)) self.assertEqual( o["out"].object("/plane")["testString"].data[0], "TEST STRING : <-1.00><-1.00><-1><-1><><-1.00 -1.00 -1.00><-1.00 -1.00 -1.00><-1.00 -1.00 -1.00><-1.00 0.00 0.00 -1.00><-1.00 -1.00 -1.00>" ) o["useAttributes"].setValue(True) self.assertEqual( o["out"].object("/plane")["testString"].data[0], "TEST STRING : <42.50><-1.00><12><1><blah><0.10 0.20 0.30><0.40 0.50 0.00><0.60 0.70 0.80><3.00 3.00 3.00 3.00><0.60 0.70 0.80>" ) # Try some bogus attributes code["code"].setValue( inspect.cleandoc(""" string badAttribute = "NOT FOUND"; getattribute( "badAttribute", badAttribute ); testString = badAttribute; """)) a["attributes"].addChild( Gaffer.NameValuePlug("badAttribute", imath.Box2f(imath.V2f(-0.5), imath.V2f(0.5)))) # Check that bad attribute isn't found self.assertEqual(o["out"].object("/plane")["testString"].data[0], "NOT FOUND") while a["attributes"].children(): del a["attributes"][0] a["attributes"].addChild( Gaffer.NameValuePlug("badAttribute", IECore.FloatVectorData([0, 1, 2]))) self.assertEqual(o["out"].object("/plane")["testString"].data[0], "NOT FOUND") # Try something that isn't even data code["code"].setValue( inspect.cleandoc(""" string badAttribute = "NOT FOUND"; getattribute( "osl:surface", badAttribute ); testString = badAttribute; """)) c = GafferOSL.OSLShader() c.loadShader("Surface/Constant") s = GafferScene.ShaderAssignment() s["shader"].setInput(c["out"]) s["filter"].setInput(f["out"]) s["in"].setInput(p["out"]) o["in"].setInput(s["out"]) self.assertEqual(o["out"].object("/plane")["testString"].data[0], "NOT FOUND")
def testAllTypes(self): s = Gaffer.ScriptNode() c = GafferScene.Cube() s.addChild(c) o = GafferOSL.OSLObject() s.addChild(o) f = GafferScene.PathFilter("PathFilter") s.addChild(f) f["paths"].setValue(IECore.StringVectorData(['/cube'])) o["filter"].setInput(f["out"]) o['in'].setInput(c["out"]) o["primitiveVariables"].addChild( Gaffer.NameValuePlug("testString", "blah")) o["primitiveVariables"].addChild(Gaffer.NameValuePlug("testInt", 42)) o["primitiveVariables"].addChild( Gaffer.NameValuePlug("testFloat", 42.42)) o["primitiveVariables"].addChild( Gaffer.NameValuePlug( "testVector", IECore.V3fData(imath.V3f(1, 2, 3), IECore.GeometricData.Interpretation.Vector))) o["primitiveVariables"].addChild( Gaffer.NameValuePlug( "testPoint", IECore.V3fData(imath.V3f(4, 5, 6), IECore.GeometricData.Interpretation.Point))) o["primitiveVariables"].addChild( Gaffer.NameValuePlug( "testNormal", IECore.V3fData(imath.V3f(7, 8, 9), IECore.GeometricData.Interpretation.Normal))) o["primitiveVariables"].addChild( Gaffer.NameValuePlug( "testUV", IECore.V3fData(imath.V3f(10, 11, -42), IECore.GeometricData.Interpretation.UV))) o["primitiveVariables"].addChild( Gaffer.NameValuePlug("testColor", imath.Color3f(12, 13, 14))) o["primitiveVariables"].addChild( Gaffer.NameValuePlug("testMatrix", imath.M44f(15))) cubeObject = s['OSLObject']['out'].object("/cube") self.assertEqual(cubeObject["testString"].data, IECore.StringVectorData(["blah"] * 8)) self.assertEqual(cubeObject["testInt"].data, IECore.IntVectorData([42] * 8)) self.assertEqual(cubeObject["testFloat"].data, IECore.FloatVectorData([42.42] * 8)) self.assertEqual( cubeObject["testVector"].data, IECore.V3fVectorData([imath.V3f(1, 2, 3)] * 8, IECore.GeometricData.Interpretation.Vector)) self.assertEqual( cubeObject["testPoint"].data, IECore.V3fVectorData([imath.V3f(4, 5, 6)] * 8, IECore.GeometricData.Interpretation.Point)) self.assertEqual( cubeObject["testNormal"].data, IECore.V3fVectorData([imath.V3f(7, 8, 9)] * 8, IECore.GeometricData.Interpretation.Normal)) self.assertEqual( cubeObject["testUV"].data, IECore.V2fVectorData([imath.V2f(10, 11)] * 8, IECore.GeometricData.Interpretation.UV)) self.assertEqual( cubeObject["testColor"].data, IECore.Color3fVectorData([imath.Color3f(12, 13, 14)] * 8)) self.assertEqual(cubeObject["testMatrix"].data, IECore.M44fVectorData([imath.M44f(15)] * 8))
def __nodeGadgetAt( self, position ) : viewport = self.__gadgetWidget.getViewportGadget() line = viewport.rasterToGadgetSpace( imath.V2f( position.x, position.y ), gadget = self.graphGadget() ) return self.graphGadget().nodeGadgetAt( line )
def testDetailAttributes(self): attr = self.testSetupAttributes() attr.parm("class").set(0) # detail attribute result = IECoreHoudini.FromHoudiniPolygonsConverter(attr).convert() attr.parm("value1").set(123.456) self.assertEqual(result["test_attribute"].data.typeId(), IECore.TypeId.FloatData) self.assert_(result["test_attribute"].data > IECore.FloatData(123.0)) self.assertEqual(result["test_attribute"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.Constant) self.assert_(result.arePrimitiveVariablesValid()) attr.parm("type").set(1) # integer result = IECoreHoudini.FromHoudiniPolygonsConverter(attr).convert() self.assertEqual(result["test_attribute"].data.typeId(), IECore.TypeId.IntData) self.assertEqual(result["test_attribute"].data, IECore.IntData(123)) self.assertEqual(result["test_attribute"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.Constant) self.assert_(result.arePrimitiveVariablesValid()) attr.parm("type").set(0) # float attr.parm("size").set(2) # 2 elementS attr.parm("value2").set(456.789) result = IECoreHoudini.FromHoudiniPolygonsConverter(attr).convert() self.assertEqual(result["test_attribute"].data.typeId(), IECore.TypeId.V2fData) self.assertEqual(result["test_attribute"].data.value, imath.V2f(123.456, 456.789)) self.assertEqual(result["test_attribute"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.Constant) self.assert_(result.arePrimitiveVariablesValid()) attr.parm("type").set(1) # int result = IECoreHoudini.FromHoudiniPolygonsConverter(attr).convert() self.assertEqual(result["test_attribute"].data.typeId(), IECore.TypeId.V2iData) self.assertEqual(result["test_attribute"].data.value, imath.V2i(123, 456)) self.assertEqual(result["test_attribute"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.Constant) self.assert_(result.arePrimitiveVariablesValid()) attr.parm("type").set(0) # float attr.parm("size").set(3) # 3 elements attr.parm("value3").set(999.999) result = IECoreHoudini.FromHoudiniPolygonsConverter(attr).convert() self.assertEqual(result["test_attribute"].data.typeId(), IECore.TypeId.V3fData) self.assertEqual(result["test_attribute"].data.value, imath.V3f(123.456, 456.789, 999.999)) self.assertEqual(result["test_attribute"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.Constant) self.assert_(result.arePrimitiveVariablesValid()) attr.parm("type").set(1) # int result = IECoreHoudini.FromHoudiniPolygonsConverter(attr).convert() self.assertEqual(result["test_attribute"].data.typeId(), IECore.TypeId.V3iData) self.assertEqual(result["test_attribute"].data.value, imath.V3i(123, 456, 999)) self.assertEqual(result["test_attribute"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.Constant) self.assert_(result.arePrimitiveVariablesValid()) attr.parm("type").set(3) # string attr.parm("string").set("string!") result = IECoreHoudini.FromHoudiniPointsConverter(attr).convert() self.assertEqual(result["test_attribute"].data.typeId(), IECore.TypeId.StringData) self.assertEqual(result["test_attribute"].data.value, "string!") self.assertEqual(result["test_attribute"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.Constant) self.assert_(result.arePrimitiveVariablesValid())
def testPointAttributes(self): attr = self.testSetupAttributes() result = IECoreHoudini.FromHoudiniPolygonsConverter(attr).convert() attr.parm("value1").set(123.456) self.assertEqual(result["test_attribute"].data.typeId(), IECore.TypeId.FloatVectorData) self.assert_(result["test_attribute"].data[0] > 123.0) self.assertEqual(result["test_attribute"].data.size(), 100) self.assertEqual(result["test_attribute"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.Vertex) self.assert_(result.arePrimitiveVariablesValid()) attr.parm("type").set(1) # integer result = IECoreHoudini.FromHoudiniPolygonsConverter(attr).convert() self.assertEqual(result["test_attribute"].data.typeId(), IECore.TypeId.IntVectorData) self.assertEqual(result["test_attribute"].data[0], 123) self.assertEqual(result["test_attribute"].data.size(), 100) self.assertEqual(result["test_attribute"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.Vertex) self.assert_(result.arePrimitiveVariablesValid()) attr.parm("type").set(0) # float attr.parm("size").set(2) # 2 elementS attr.parm("value2").set(456.789) result = IECoreHoudini.FromHoudiniPolygonsConverter(attr).convert() self.assertEqual(result["test_attribute"].data.typeId(), IECore.TypeId.V2fVectorData) self.assertEqual(result["test_attribute"].data[0], imath.V2f(123.456, 456.789)) self.assertEqual(result["test_attribute"].data.size(), 100) self.assertEqual(result["test_attribute"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.Vertex) self.assert_(result.arePrimitiveVariablesValid()) attr.parm("type").set(1) # int result = IECoreHoudini.FromHoudiniPolygonsConverter(attr).convert() self.assertEqual(result["test_attribute"].data.typeId(), IECore.TypeId.V2iVectorData) self.assertEqual(result["test_attribute"].data[0], imath.V2i(123, 456)) self.assertEqual(result["test_attribute"].data.size(), 100) self.assertEqual(result["test_attribute"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.Vertex) self.assert_(result.arePrimitiveVariablesValid()) attr.parm("type").set(0) # float attr.parm("size").set(3) # 3 elements attr.parm("value3").set(999.999) result = IECoreHoudini.FromHoudiniPolygonsConverter(attr).convert() self.assertEqual(result["test_attribute"].data.typeId(), IECore.TypeId.V3fVectorData) self.assertEqual(result["test_attribute"].data[0], imath.V3f(123.456, 456.789, 999.999)) self.assertEqual(result["test_attribute"].data.size(), 100) self.assertEqual(result["test_attribute"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.Vertex) self.assert_(result.arePrimitiveVariablesValid()) attr.parm("type").set(1) # int result = IECoreHoudini.FromHoudiniPolygonsConverter(attr).convert() self.assertEqual(result["test_attribute"].data.typeId(), IECore.TypeId.V3iVectorData) self.assertEqual(result["test_attribute"].data[0], imath.V3i(123, 456, 999)) self.assertEqual(result["test_attribute"].data.size(), 100) self.assertEqual(result["test_attribute"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.Vertex) self.assert_(result.arePrimitiveVariablesValid()) attr.parm("type").set(3) # string attr.parm("string").setExpression( "'string %06d!' % pwd().curPoint().number()", hou.exprLanguage.Python) result = IECoreHoudini.FromHoudiniPointsConverter(attr).convert() self.assertEqual(result["test_attribute"].data.typeId(), IECore.TypeId.StringVectorData) self.assertEqual(result["test_attribute"].data[10], "string 000010!") self.assertEqual(result["test_attribute"].data.size(), 100) self.assertEqual(result["test_attribute"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.Vertex) self.assertEqual(result["test_attribute"].indices[10], 10) self.assertEqual(result["test_attribute"].indices.size(), 100) self.assert_(result.arePrimitiveVariablesValid())
def testSimple(self): verticesPerFace = IECore.IntVectorData([4, 4, 4, 4, 4, 4]) vertexIds = IECore.IntVectorData([ 0, 1, 5, 4, 1, 2, 6, 5, 2, 3, 7, 6, 4, 5, 9, 8, 5, 6, 10, 9, 6, 7, 11, 10 ]) pRef = IECore.V3fVectorData([ imath.V3f(-1, -1, 0), imath.V3f(0, -1, 0), imath.V3f(1, -1, 0), imath.V3f(2, -1, 0), imath.V3f(-1, 0, 0), imath.V3f(0, 0, 0), imath.V3f(1, 0, 0), imath.V3f(2, 0, 0), imath.V3f(-1, 1, 0), imath.V3f(0, 1, 0), imath.V3f(1, 1, 0), imath.V3f(2, 1, 0), ]) # p moves vertex from (0,0,0) to (0.5,0.5,0) p = pRef.copy() p[5] = imath.V3f(0.5, 0.5, 0) uvs = IECore.V2fVectorData() for v in vertexIds: uvs.append(imath.V2f(p[v][0], p[v][1])) m = IECoreScene.MeshPrimitive(verticesPerFace, vertexIds, "linear", p) m['Pref'] = IECoreScene.PrimitiveVariable(m['P'].interpolation, pRef) m['uv'] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.FaceVarying, uvs) distortion, uvDistortion = IECoreScene.MeshAlgo.calculateDistortion(m) self.assertTrue(m.isPrimitiveVariableValid(distortion)) self.assertTrue(m.isPrimitiveVariableValid(uvDistortion)) expected = IECore.FloatVectorData([ 0, 0.290569, 0, 0, 0.290569, 0.0834627, -0.103553, 0, 0, -0.207107, 0, 0 ]) for i in range(0, len(expected)): self.assertAlmostEqual(distortion.data[i], expected[i], 6) def vec2Err(vec): acc = [0.0, 0.0] for v in vec: for i in (0, 1): acc[i] += v[i] * v[i] return acc uvExpected = IECore.V2fVectorData([ imath.V2f(0, 0), imath.V2f(0.0918861, 0.275658), imath.V2f(0.367544, 0.367544), imath.V2f(0.275658, 0.0918861), imath.V2f(0.0918861, 0.275658), imath.V2f(0, 0), imath.V2f(-0.146447, -0.146447), imath.V2f(-0.0545605, 0.129212), imath.V2f(0, 0), imath.V2f(0, 0), imath.V2f(0, 0), imath.V2f(0, 0), imath.V2f(0.275658, 0.0918861), imath.V2f(0.129212, -0.0545605), imath.V2f(-0.146447, -0.146447), imath.V2f(0, 0), imath.V2f(-0.292893, -0.292893), imath.V2f(-0.146447, -0.146447), imath.V2f(0, 0), imath.V2f(-0.146447, -0.146447), imath.V2f(0, 0), imath.V2f(0, 0), imath.V2f(0, 0), imath.V2f(0, 0), ]) self.assertEqual(len(uvExpected), len(uvDistortion.data)) for i in range(0, len(uvExpected)): self.assertAlmostEqual(uvDistortion.data[i][0], uvExpected[i][0], 6) self.assertAlmostEqual(uvDistortion.data[i][1], uvExpected[i][1], 6)
def testObjectAtLine(self): cubes = [] names = ("left", "center", "right") for i in range(3): cube = GafferScene.Cube() cube["transform"]["translate"].setValue( imath.V3f((i - 1) * 2.0, 0.0, -2.5)) cube["name"].setValue(names[i]) cubes.append(cube) group = GafferScene.Group() for i, cube in enumerate(cubes): group["in"][i].setInput(cube["out"]) sg = GafferSceneUI.SceneGadget() sg.setScene(group["out"]) sg.setMinimumExpansionDepth(100) with GafferUI.Window() as w: gw = GafferUI.GadgetWidget(sg) w.setVisible(True) self.waitForIdle(10000) vp = gw.getViewportGadget() # This is the single most important line in this test. If you don't set # this to false, you get an orthographic camera, even if you set a # perspective projection. vp.setPlanarMovement(False) c = IECoreScene.Camera() c.setProjection("perspective") c.setFocalLength(35) c.setAperture(imath.V2f(36, 24)) vp.setCamera(c) cameraTransform = imath.M44f() cameraTransform.translate(imath.V3f(0, 0, 2)) vp.setCameraTransform(cameraTransform) self.waitForIdle(10000) # We assume in this case, that gadget space is world space leftCubeDir = IECore.LineSegment3f(imath.V3f(0, 0, 2), imath.V3f(-2, 0, -2)) pathA = sg.objectAt(leftCubeDir) pathB, hitPoint = sg.objectAndIntersectionAt(leftCubeDir) self.assertIsNotNone(pathA) self.assertEqual(pathA, IECore.InternedStringVectorData(["group", "left"])) self.assertEqual(pathA, pathB) self.assertAlmostEqual(hitPoint.x, -2, delta=0.01) self.assertAlmostEqual(hitPoint.y, 0, delta=0.01) self.assertAlmostEqual(hitPoint.z, -2, delta=0.01) centerCubeDir = IECore.LineSegment3f(imath.V3f(0, 0, 1), imath.V3f(0, 0, -1)) pathA = sg.objectAt(centerCubeDir) pathB, hitPoint = sg.objectAndIntersectionAt(centerCubeDir) self.assertIsNotNone(pathA) self.assertEqual(pathA, IECore.InternedStringVectorData(["group", "center"])) self.assertEqual(pathA, pathB) self.assertAlmostEqual(hitPoint.x, 0, delta=0.01) self.assertAlmostEqual(hitPoint.y, 0, delta=0.01) self.assertAlmostEqual(hitPoint.z, -2, delta=0.01) rightCubeDir = IECore.LineSegment3f(imath.V3f(0, 0, 2), imath.V3f(2, 0, -2)) pathA = sg.objectAt(rightCubeDir) pathB, hitPoint = sg.objectAndIntersectionAt(rightCubeDir) self.assertIsNotNone(pathA) self.assertEqual(pathA, IECore.InternedStringVectorData(["group", "right"])) self.assertEqual(pathA, pathB) self.assertAlmostEqual(hitPoint.x, 2, delta=0.01) self.assertAlmostEqual(hitPoint.y, 0, delta=0.01) self.assertAlmostEqual(hitPoint.z, -2, delta=0.01) missDir = IECore.LineSegment3f(imath.V3f(0, 0, 2), imath.V3f(0, 10, -2)) pathA = sg.objectAt(missDir) pathB, hitPoint = sg.objectAndIntersectionAt(missDir) self.assertIsNone(pathA) self.assertIsNone(pathB)
import IECore import IECoreScene import Gaffer import GafferUI import GafferScene import GafferSceneUI import GafferImageUI # add plugs to the preferences node preferences = application.root()["preferences"] preferences["viewer"] = Gaffer.Plug() preferences["viewer"]["gridDimensions"] = Gaffer.V2fPlug( defaultValue=imath.V2f(10), minValue=imath.V2f(0)) Gaffer.Metadata.registerValue(preferences["viewer"], "plugValueWidget:type", "GafferUI.LayoutPlugValueWidget", persistent=False) Gaffer.Metadata.registerValue(preferences["viewer"], "layout:section", "Viewer", persistent=False) # register a customised view for viewing scenes def __sceneView(plug):
def testPrimitiveVariableTypes(self): pointsPrimitive = IECoreScene.PointsPrimitive( IECore.V3fVectorData([imath.V3f(0)])) pointsPrimitive["vector"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Vertex, IECore.V3fVectorData([imath.V3f(1, 2, 3)], IECore.GeometricData.Interpretation.Vector), ) pointsPrimitive["normal"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Vertex, IECore.V3fVectorData([imath.V3f(4, 5, 6)], IECore.GeometricData.Interpretation.Normal), ) pointsPrimitive["point"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Vertex, IECore.V3fVectorData([imath.V3f(4, 5, 6)], IECore.GeometricData.Interpretation.Point), ) pointsPrimitive["uv"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Vertex, IECore.V2fVectorData([imath.V2f(0, 1)], IECore.GeometricData.Interpretation.UV), ) pointsPrimitive["Cs"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Vertex, IECore.Color3fVectorData([imath.Color3f(0, 0, 1)]), ) pointsPrimitive["float"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Vertex, IECore.FloatVectorData([0.5]), ) pointsPrimitive["int"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Vertex, IECore.IntVectorData([10]), ) points = GafferScene.ObjectToScene() points["object"].setValue(pointsPrimitive) plane = GafferScene.Plane() plane["transform"]["translate"]["x"].setValue(1) planeFilter = GafferScene.PathFilter() planeFilter["paths"].setValue(IECore.StringVectorData(["/plane"])) sampler = GafferScene.ClosestPointSampler() sampler["in"].setInput(plane["out"]) sampler["source"].setInput(points["out"]) sampler["filter"].setInput(planeFilter["out"]) sampler["sourceLocation"].setValue("/object") sampler["primitiveVariables"].setValue("*") sampler["prefix"].setValue("sampled:") p = sampler["out"].object("/plane") for name in pointsPrimitive.keys(): primVar = pointsPrimitive[name] sampledName = "sampled:" + name self.assertIn(sampledName, p) sampledPrimVar = p[sampledName] self.assertIsInstance(sampledPrimVar.data, primVar.data.__class__) if hasattr(primVar.data, "getInterpretation"): self.assertEqual(sampledPrimVar.data.getInterpretation(), primVar.data.getInterpretation()) self.assertEqual(p["sampled:vector"].data[0], imath.V3f(1, 2, 3)) self.assertEqual(p["sampled:normal"].data[0], imath.V3f(4, 5, 6)) self.assertEqual(p["sampled:point"].data[0], imath.V3f(3, 5, 6)) self.assertEqual(p["sampled:uv"].data[0], imath.V2f(0, 1)) self.assertEqual(p["sampled:Cs"].data[0], imath.Color3f(0, 0, 1)) self.assertEqual(p["sampled:float"].data[0], 0.5) self.assertEqual(p["sampled:int"].data[0], 10)
def testSimpleMesh( self ) : """ Testing MeshPrimitiveEvaluator with mesh containing single triangle""" verticesPerFace = IECore.IntVectorData() verticesPerFace.append( 3 ) vertexIds = IECore.IntVectorData() vertexIds.append( 0 ) vertexIds.append( 1 ) vertexIds.append( 2 ) translation = imath.V3f( 3, 3, 3 ) P = IECore.V3fVectorData() P.append( imath.V3f( -1, 0, 0 ) + translation ) P.append( imath.V3f( 0, 0, -1 ) + translation ) P.append( imath.V3f( -1, 0, -1 ) + translation ) uOffset = 7 uv = IECore.V2fVectorData() vOffset = 12 for p in P : uv.append( imath.V2f( p.x + uOffset, p.z + vOffset ) ) self.assertEqual( len( P ), len( uv ) ) m = IECoreScene.MeshPrimitive( verticesPerFace, vertexIds ) m["P"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Vertex, P ) # We use Varying interpolation here because the tests which use pSphereShape1.cob exercise FaceVarying m["uv"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Varying, uv ) mpe = IECoreScene.PrimitiveEvaluator.create( m ) r = mpe.createResult() # For each point verify that the closest point to it is itself for p in P: foundClosest = mpe.closestPoint( p , r ) self.assert_( foundClosest ) self.assertAlmostEqual( ( p - r.point() ).length(), 0 ) foundClosest = mpe.closestPoint( imath.V3f( 0, 10, 0 ) + translation , r ) self.assert_( foundClosest ) self.assertAlmostEqual( ( imath.V3f( -0.5, 0, -0.5 ) + translation - r.point()).length(), 0 ) self.assertAlmostEqual( math.fabs( r.normal().dot( imath.V3f(0, 1, 0 ) ) ) , 1, places = 3 ) # For each point verify that the UV data is exactly what we specified at those vertices for p in P: foundClosest = mpe.closestPoint( p , r ) self.assert_( foundClosest ) testUV = imath.V2f( p.x + uOffset, p.z + vOffset ) self.assertAlmostEqual( ( testUV - r.uv() ).length(), 0 ) # Now when we looking up that UV in reverse we should get back the point again! found = mpe.pointAtUV( testUV, r ) self.assert_( found ) self.assertAlmostEqual( ( p - r.point()).length(), 0 ) # test the uvBound method uvb = imath.Box2f() for i in range( 0, len( uv ) ) : uvb.extendBy( uv[i] ) self.assertEqual( mpe.uvBound(), uvb )
def testAttributeFilter(self): mesh = self.mesh() sop = self.emptySop() converter = IECoreHoudini.ToHoudiniCortexObjectConverter(mesh) self.assertTrue(converter.convert(sop)) result = IECoreHoudini.FromHoudiniCortexObjectConverter(sop).convert() self.assertEqual(result.keys(), [ 'P', 'color3fPoint', 'color3fPrim', 'color3fVert', 'floatPoint', 'floatPrim', 'floatVert', 'stringPoint', 'stringPrim', 'stringVert' ]) converter.parameters()["attributeFilter"].setTypedValue("P *3f*") self.assertTrue(converter.convert(sop)) result = IECoreHoudini.FromHoudiniCortexObjectConverter(sop).convert() self.assertEqual(result.keys(), ['P', 'color3fPoint', 'color3fPrim', 'color3fVert']) converter.parameters()["attributeFilter"].setTypedValue( "* ^color* ^string*") self.assertTrue(converter.convert(sop)) result = IECoreHoudini.FromHoudiniCortexObjectConverter(sop).convert() self.assertEqual(result.keys(), ['P', 'floatPoint', 'floatPrim', 'floatVert']) # verify From filter works as well fromConverter = IECoreHoudini.FromHoudiniCortexObjectConverter(sop) fromConverter.parameters()["attributeFilter"].setTypedValue("P *Prim") result = fromConverter.convert() self.assertEqual(result.keys(), ['P', 'floatPrim']) # verify we can filter uvs mesh = IECoreScene.MeshPrimitive.createPlane( imath.Box2f(imath.V2f(0), imath.V2f(1))) mesh = IECoreScene.MeshAlgo.triangulate(mesh) IECoreScene.MeshNormalsOp()(input=mesh, copyInput=False) mesh["Cs"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.FaceVarying, IECore.V3fVectorData([imath.V3f(1, 0, 0)] * 6, IECore.GeometricData.Interpretation.Color)) mesh["width"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Vertex, IECore.FloatVectorData([1] * 4)) mesh["Pref"] = mesh["P"] # have to filter the source attrs converter = IECoreHoudini.ToHoudiniCortexObjectConverter(mesh) converter.parameters()["attributeFilter"].setTypedValue( "* ^uv ^pscale ^rest") self.assertTrue(converter.convert(sop)) result = IECoreHoudini.FromHoudiniCortexObjectConverter(sop).convert() self.assertEqual(result.keys(), ['Cs', 'N', 'P', 'Pref', 'width']) converter.parameters()["attributeFilter"].setTypedValue( "* ^uv ^width ^Pref") self.assertTrue(converter.convert(sop)) result = IECoreHoudini.FromHoudiniCortexObjectConverter(sop).convert() self.assertEqual(result.keys(), ['Cs', 'N', 'P']) # verify non-primitives do not break converter = IECoreHoudini.ToHoudiniCortexObjectConverter( IECore.IntData(1)) converter.parameters()["attributeFilter"].setTypedValue( "* ^uv ^pscale ^rest") self.assertTrue(converter.convert(sop)) self.assertEqual( IECoreHoudini.FromHoudiniCortexObjectConverter(sop).convert(), IECore.IntData(1))