def testCustomMemoryCache(): graph = tuttle.Graph() n = [ tuttle.NodeInit( "tuttle.exrreader", filename="TuttleOFX-data/image/openexr/DisplayWindow/t##.exr"), tuttle.NodeInit("tuttle.invert"), tuttle.NodeInit("tuttle.gamma", master=.5), tuttle.NodeInit("tuttle.jpegwriter", filename=".tests/fromExr/output-####.jpg"), ] nodes = graph.addConnectedNodes(n) procOptions = tuttle.ComputeOptions() internCache = tuttle.MemoryCache() procGraph = tuttle.ProcessGraph(procOptions, graph, [], internCache) print("before compute") outputCache = tuttle.MemoryCache() timeRange = tuttle.TimeRange(1, 16, 10) print("setup") procGraph.setup() print("beginSequence") procGraph.beginSequence(timeRange) for time in range(timeRange._begin, timeRange._end, timeRange._step): print("time:", time) procGraph.setupAtTime(time) procGraph.processAtTime(outputCache, time) print("endSequence") procGraph.endSequence() print("after compute")
def testMergeWithSameChildrens(): g = tuttle.Graph() read = g.createNode("tuttle.checkerboard", size=[100, 200], explicitConversion="8i") scale = g.createNode("tuttle.swscale", width=150) effect = g.createNode("tuttle.invert") merge = g.createNode("tuttle.merge", offsetA=[150, 0], mergingFunction="copy", rod="union") write = g.createNode("tuttle.invert") # read -> scale -> effect # \ \ # -----------> merge -> write g.connect([read, scale, effect]) g.connect(scale, merge.getAttribute("B")) g.connect(effect, merge.getAttribute("A")) g.connect(merge, write) outputCache = tuttle.MemoryCache() g.compute(outputCache, write, tuttle.ComputeOptions(5)) # We retrieve the output image buffer, and we could read the image size rodMerge = outputCache.get(0).getROD() print(rodMerge.x1, rodMerge.y1, rodMerge.x2, rodMerge.y2) assert rodMerge.x1 == 0 assert rodMerge.y1 == 0 assert rodMerge.x2 == 300 assert rodMerge.y2 == 300
def computeNode(self, node, frame): """ Computes the node (displayed in the viewer) at the frame indicated. """ buttleData = ButtleDataSingleton().get() graphTuttle = buttleData.getGraph().getGraphTuttle() #Get the output where we save the result self._tuttleImageCache = tuttle.MemoryCache() if buttleData.getVideoIsPlaying(): # if a video is playing processGraph = buttleData.getProcessGraph() processGraph.setupAtTime(frame) processGraph.processAtTime(self._tuttleImageCache, frame) else: # if it's an image only processOptions = tuttle.ComputeOptions(int(frame)) processGraph = tuttle.ProcessGraph(processOptions, graphTuttle, [node]) processGraph.setup() timeRange = tuttle.TimeRange(frame, frame, 1) # buttleData.getTimeRange() processGraph.beginSequence(timeRange) processGraph.setupAtTime(frame) processGraph.processAtTime(self._tuttleImageCache, frame) processGraph.endSequence() self._computedImage = self._tuttleImageCache.get(0) #Add the computedImage to the map hashMap = tuttle.NodeHashContainer() graphTuttle.computeGlobalHashAtTime(hashMap, frame) hasCode = hashMap.getHash(node, frame) #Max 15 computedImages saved in memory if hasCode not in buttleData._mapNodeNameToComputedImage.keys( ) and len(buttleData._mapNodeNameToComputedImage) < 15: buttleData._mapNodeNameToComputedImage.update( {hasCode: self._computedImage}) elif hasCode not in buttleData._mapNodeNameToComputedImage.keys( ) and len(buttleData._mapNodeNameToComputedImage) >= 15: #Delete a computed image from the memory (random) buttleData._mapNodeNameToComputedImage.popitem() buttleData._mapNodeNameToComputedImage.update( {hasCode: self._computedImage}) return self._computedImage
def testOutputMemoryCache(): outputCache = tuttle.MemoryCache() tuttle.compute( outputCache, [ tuttle.NodeInit( "tuttle.checkerboard", format="PAL", explicitConversion="8i" ), tuttle.NodeInit( "tuttle.blur", size=.2 ), tuttle.NodeInit( "tuttle.invert" ), ] ) #print 'invert name:', invert.getName() imgRes = outputCache.get(0); print('type imgRes:', type( imgRes )) print('imgRes:', dir( imgRes )) print('FullName:', imgRes.getFullName()) print('MemorySize:', imgRes.getMemorySize())
def testMergeWithDynamicOffset(): g = tuttle.Graph() read1 = g.createNode("tuttle.checkerboard", size=[20, 137]).asImageEffectNode() read2 = g.createNode("tuttle.checkerboard", size=[234, 357]).asImageEffectNode() merge = g.createNode("tuttle.merge", rod="union").asImageEffectNode() g.connect(read1, merge.getClip("A")) g.connect(read2, merge.getClip("B")) time = 1.0 # After the setup at time we could read the image size on the node g.setupAtTime(time, [read1, read2]) rodA = read1.getRegionOfDefinition(time) rodB = read2.getRegionOfDefinition(time) assert rodA.x1 == 0 assert rodA.y1 == 0 assert rodA.x2 == 20 assert rodA.y2 == 137 assert rodB.x1 == 0 assert rodB.y1 == 0 assert rodB.x2 == 234 assert rodB.y2 == 357 merge.getParam("offsetB").setValue([int(rodA.x2), 0]) outputCache = tuttle.MemoryCache() g.compute(outputCache, merge) # We retrieve the output image buffer, and we could read the image size rodMerge = outputCache.get(0).getROD() print(rodMerge.x1, rodMerge.y1, rodMerge.x2, rodMerge.y2) assert rodMerge.x1 == 0 assert rodMerge.y1 == 0 assert rodMerge.x2 == (rodA.x2 + rodB.x2) assert rodMerge.y2 == rodB.y2
def testUnusedNodes(): """ It should not have any impact, if there are invalid but unused nodes in the graph. Nodes could be invalid if they have unconnected mandatory clips. And the other hand, if you ask to compute those invalid nodes, it should raise an exception. """ g = tuttle.Graph() read1 = g.createNode("tuttle.checkerboard", size=[20, 137]).asImageEffectNode() read2 = g.createNode("tuttle.checkerboard", size=[234, 357]).asImageEffectNode() merge = g.createNode("tuttle.merge", rod="union").asImageEffectNode() # Unconnected but unused nodes should not impede the computation pushpixel_unused = g.createNode("tuttle.pushpixel").asImageEffectNode() invert_unused = g.createNode("tuttle.invert").asImageEffectNode() g.connect(read1, merge.getClip("A")) g.connect(read2, merge.getClip("B")) hashMap = tuttle.NodeHashContainer() g.computeGlobalHashAtTime(hashMap, 0, [merge]) ## TODO: Should not raise, even if there are invalid nodes. # g.computeGlobalHashAtTime(hashMap, 0) outputCache = tuttle.MemoryCache() g.compute(outputCache, merge) # Trying to compute all nodes should raise an error # on unconnected filters (invert and pushpixel). assert_raises(Exception, g.compute, outputCache)
from pyTuttle import tuttle tuttle.core().preload() g = tuttle.Graph() read = g.createNode("tuttle.pngreader", "data/input.png") invert = g.createNode("tuttle.invert") g.connect([read, invert]) outputCache = tuttle.MemoryCache() g.compute(outputCache, invert) print 'blur name:', invert.getName() imgRes = outputCache.get(invert.getName(), 0) print 'type imgRes:', type(imgRes) print 'imgRes:', dir(imgRes) print 'MemorySize:', imgRes.getMemorySize()