#!/usr/bin/python # ===-- TreeGraph.py ------------------------------------------------------===## # # The KLEE Symbolic Virtual Machine # # This file is distributed under the University of Illinois Open Source # License. See LICENSE.TXT for details. # # ===----------------------------------------------------------------------===## from __future__ import division import sys from types import GeneratorType import DumpTreeStream from Graphics.Canvas import PdfCanvas from Graphics.Geometry import vec2 import os, time import math, os, random def generator_fold(it): """generator_fold(it) -> iterator Given _it_, return a new iterator over the elements of _it_, (recursively) folding in any elements whenever an iterator result happens to also be a generator. This simplifies the writing of iterators over recursive data structures. """ for res in it: if isinstance(res,GeneratorType): for res in generator_fold(res): yield res else: yield res def drawTree(a, b, maxDepth, sizes, depth=0): yield (a, b) if depth3: paths.append(pts) for i in range(0,len(pts)-1): p0 = pts[max(0,i-1)] p1 = pts[i] p2 = pts[min(len(pts)-1,i+1)] p3 = pts[min(len(pts)-1,i+2)] #segments[(p1,p2)] = segments.get((p1,p2),[]) + [(p0,p1)] if (p1,p2) not in side: segments.add((p0,p1,p2,p3)) side.add((p1,p2)) # drawPoints((b,vec2.add(b,vec2.mulN(vec2.normalizeOrZero(vec2.sub(b,a)),l*.4)), # cx,cx)) # c.drawLineStrip(pts) # for a,b in zip(pts,pts[1:]): # lines.add((a,b)) for a,b in lines: c.drawLine(a,b) for (p1,p2),extra in segments2.items(): a,b = zip(*extra) a = vec2.divN(reduce(vec2.add, a),len(a)) b = vec2.divN(reduce(vec2.add, b),len(b)) c.drawLineStrip([catmullRom2((a,p1,p2,b),x/10.) for x in range(10+1)]) if 1: side = set() nPaths = [] for path in paths: path = list(path) path = [(0.,-.9)] + path depth = 0 while len(path)>3 and (path[1],path[2]) in side: depth += 1 path = path[1:] nPaths.append((depth,path)) side |= set(zip(path,path[1:])) # for path in nPaths: # c.drawLineStrip(path) for depth,path in nPaths: ppts = [] for i in range(1,len(path)-1): p0 = path[max(0,i-1)] p1 = path[i] p2 = path[min(len(path)-1,i+1)] p3 = path[min(len(path)-1,i+2)] for x in range(10): ppts.append(catmullRom2((p0,p1,p2,p3),x/10.)) #ppts.append(p1) ppts.append(path[-1]) if 1: up = [] down = [] ref = path[0] for i,pt in enumerate(ppts): ref = ppts[min(len(ppts)-1,i+1)] vec = vec2.sub(pt,ref) l = vec2.length(vec) if l<.000001: vec = (1.,0.) else: vec = vec2.rotate90(vec2.divN(vec,l)) width = .001 * (1. - (depth + i/20.)/N) up.append(vec2.add(pt, vec2.mulN(vec, width))) down.append(vec2.add(pt, vec2.mulN(vec, -width))) ref = pt # c.drawLineStrip(up) # c.drawLineStrip(down) c.drawFilledPolygon(down + up[::-1]) else: c.drawLineStrip(ppts) # print len(paths),sum(map(len,paths)) # print len(nPaths),sum(map(len,nPaths)) else: for P in segments: c.drawLineStrip([catmullRom2(P,x/10.) for x in range(10+1)]) if 0: c.setPointSize(10) c.drawPoints(allPoints) if 0: N = 20 for i in range(N+1): t = 2*i/N - 1 c.drawLine(m((t,0)), m((t,1))) c.endDrawing() def main(): from optparse import OptionParser op = OptionParser("usage: %prog [options] ") op.add_option('','--count', dest='count', type=int, default=-1, help="number of distinct paths to draw") op.add_option('','--shuffle', dest='shuffle', action='store_true', default=False) opts,args = op.parse_args() if len(args) != 2: parser.error('invalid number of arguments') symPath,output = args makeTreeGraph(output, symPath, opts.count, opts.shuffle) if __name__=='__main__': try: main() except: import sys,traceback traceback.print_exc(file= sys.__stdout__) sys.__stdout__.flush()