From cd2899bb209cdf083ee72a198d20ac766380b591 Mon Sep 17 00:00:00 2001 From: Skyler Lehmkuhl Date: Mon, 22 Apr 2013 00:02:48 -0400 Subject: [PATCH 01/17] Preliminary shape editing --- lightningbeam.py | 28 ++++++++++-- svlgui.py | 115 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+), 4 deletions(-) diff --git a/lightningbeam.py b/lightningbeam.py index 35bc0fd..0cd3137 100755 --- a/lightningbeam.py +++ b/lightningbeam.py @@ -110,6 +110,7 @@ def onMouseDownGroup(self, x, y,button=1,clicks=1): if svlgui.MODE in [" ", "s"]: if self.hitTest(x, y): self.clicked = True + elif svlgui.MODE in ["r", "e", "p"]: if svlgui.MODE=="r": # 'c' stands for 'current' @@ -117,7 +118,17 @@ def onMouseDownGroup(self, x, y,button=1,clicks=1): elif svlgui.MODE=="e": self.cshape = ellipse(x, y, 0, 0) elif svlgui.MODE=="p": - self.cshape = shape(x, y) + # self.cshape = shape(x, y) + self.cshape = svlgui.Line(svlgui.Point(x, y),svlgui.Point(x,y)) + for i in self.lines: + if abs(self.cshape.endpoint1.x-i.endpoint1.x)<10 and abs(self.cshape.endpoint1.y-i.endpoint1.y)<10: + self.cshape.connection1 = i.endpoint1 + break + elif abs(self.cshape.endpoint1.x-i.endpoint2.x)<10 and abs(self.cshape.endpoint1.y-i.endpoint2.y)<10: + self.cshape.connection1 = i.endpoint2 + break + self.lines.append(self.cshape) + return #self.cshape.rotation = 5 self.cshape.initx,self.cshape.inity = x, y self.add(self.cshape) @@ -184,9 +195,16 @@ def onMouseUpGroup(self, x, y,button=1,clicks=1): undo_stack[-1] = undo_stack[-1].complete({"obj":cobj, "frame":self.activelayer.currentframe, "layer":self.activelayer}) clear(redo_stack) elif svlgui.MODE=="p": - print len(self.cshape.shapedata) + '''print len(self.cshape.shapedata) self.cshape.shapedata = misc_funcs.simplify_shape(self.cshape.shapedata, svlgui.PMODE.split()[-1],1) - print len(self.cshape.shapedata) + print len(self.cshape.shapedata)''' + for i in self.lines: + if abs(self.cshape.endpoint2.x-i.endpoint1.x)<10 and abs(self.cshape.endpoint2.y-i.endpoint1.y)<10: + self.cshape.connection2 = i.endpoint1 + break + elif abs(self.cshape.endpoint2.x-i.endpoint2.x)<10 and abs(self.cshape.endpoint2.y-i.endpoint2.y)<10: + self.cshape.connection2 = i.endpoint2 + break self.cshape = None MainWindow.stage.draw() def onMouseUpObj(self, x, y,button=1,clicks=1): @@ -245,7 +263,9 @@ def onMouseDragGroup(self, x, y,button=1,clicks=1): y=y-self.cshape.inity self.cshape.shapedata = [["M",x/2,0],["C",4*x/5,0,x,y/5,x,y/2],["C",x,4*y/5,4*x/5,y,x/2,y],["C",x/5,y,0,4*y/5,0,y/2],["C",0,y/5,x/5,0,x/2,0]] elif svlgui.MODE == "p": - self.cshape.shapedata.append(["L",x-self.cshape.initx,y-self.cshape.inity]) + # self.cshape.shapedata.append(["L",x-self.cshape.initx,y-self.cshape.inity]) + self.cshape.endpoint2.x = x + self.cshape.endpoint2.y = y def onMouseDragObj(self, x, y,button=1,clicks=1): if svlgui.MODE==" ": self.x = x-self.initx diff --git a/svlgui.py b/svlgui.py index 6305dd8..f7da3b5 100644 --- a/svlgui.py +++ b/svlgui.py @@ -176,6 +176,8 @@ LINECOLOR = Color("#990099") FILLCOLOR = Color("#00FF00") TEXTCOLOR = Color("#000000") +LINEWIDTH = 2 + #Magic. Detect platform and select appropriate toolkit. To be used throughout code. if sys.platform=="linux2": id = platform.machine() @@ -2548,6 +2550,9 @@ class Group (object): self.tempgroup = None self.is_mc = False self.name = "g"+str(int(random.random()*10000))+str(SITER) + self.lines = [] + self.fills = [] + self.activepoint = None if "onload" in kwargs: kwargs["onload"](self) def draw(self,cr=None,transform=None,rect=None): @@ -2568,6 +2573,8 @@ class Group (object): cr.pencolor = Color([0,0,1]).pygui cr.stroke_rect([sorted([self.startx,self.cx])[0], sorted([self.starty,self.cy])[0], \ sorted([self.startx,self.cx])[1], sorted([self.starty,self.cy])[1]]) + for i in self.lines: + i.draw(cr, rect=rect) def add(self, *args): self.activelayer.add(*args) def add_frame(self, populate): @@ -2639,6 +2646,18 @@ class Group (object): self.tempgroup = None self.activelayer.currentselect = None self.startx, self.starty = x, y + if MODE in " s": + for i in self.lines: + if abs(x-i.endpoint1.x)<10 and abs(y-i.endpoint1.y)<10: + i.endpoint1.x = x + i.endpoint1.y = y + self.activepoint = i.endpoint1 + return + elif abs(x-i.endpoint2.x)<10 and abs(y-i.endpoint2.y)<10: + i.endpoint2.x = x + i.endpoint2.y = y + self.activepoint = i.endpoint2 + return self.selecting = True else: self.onMouseDown(self, x, y, button=button, clicks=clicks) @@ -2656,6 +2675,25 @@ class Group (object): if self.activelayer.level and MODE in [" ", "s"]: if self.activelayer.currentselect: self.activelayer.currentselect._onMouseUp(x, y, button=button, clicks=clicks) + elif self.activepoint: + for i in self.lines: + if abs(self.activepoint.x-i.endpoint1.x)<10 and abs(self.activepoint.y-i.endpoint1.y)<10: + try: + [j for j in self.lines if self.activepoint==j.endpoint1][0].assign(i.endpoint1, 1) + except IndexError: + try: + [j for j in self.lines if self.activepoint==j.endpoint2][0].assign(i.endpoint1, 2) + break + except IndexError: pass + if abs(self.activepoint.x-i.endpoint2.x)<10 and abs(self.activepoint.y-i.endpoint2.y)<10: + try: + [j for j in self.lines if self.activepoint==j.endpoint1][0].assign(i.endpoint2, 1) + except IndexError: + try: + [j for j in self.lines if self.activepoint==j.endpoint2][0].assign(i.endpoint2, 2) + break + except IndexError: pass + break elif abs(self.startx-x)>4 or abs(self.starty-y)>4: objs = [] for i in reversed(self.currentFrame()): @@ -2690,6 +2728,9 @@ class Group (object): if self.activelayer.level and MODE in [" ", "s"]: if self.activelayer.currentselect: self.activelayer.currentselect._onMouseDrag(x, y, button=button) + elif self.activepoint: + self.activepoint.x = x + self.activepoint.y = y else: self.onMouseDrag(self, x, y, button=button) def onMouseDrag(self, self1, x, y, button=1, clicks=1): @@ -2828,6 +2869,80 @@ class TemporaryGroup(Group): elif key=="down_arrow": self1.y+=1 +class Point(object): + """represents an x,y point, might store other data in the future""" + def __init__(self, x, y): + super(Point, self).__init__() + self.x = x + self.y = y + + +class Line(object): + """Use Lines to build Shapes while allowing paintbucketing.""" + def __init__(self, endpoint1, endpoint2, connection1 = None, connection2 = None): + super(Line, self).__init__() + self.endpoint1 = endpoint1 + self.endpoint2 = endpoint2 + self.connection1 = connection1 + self.connection2 = connection2 + self.linecolor = LINECOLOR + self.linewidth = LINEWIDTH + def assign(self, point, which): + if which==1: + self.connection1 = point + elif which==2: + self.connection2 = point + def draw(self, cr=None, transform=None, rect=None): + if self.connection1: + self.endpoint1 = self.connection1 + if self.connection2: + self.endpoint2 = self.connection2 + if SYSTEM=="gtk": + cr.save() + cr.set_source(self.linecolor.cairo) + cr.set_line_width(max(self.linewidth,1)) + cr.move_to(self.endpoint1.x,self.endpoint2.y) + cr.line_to(self.endpoint2.x,self.endpoint2.y) + cr.stroke() + cr.restore() + elif SYSTEM=="android": + global tb + tb+="cr.save()\n" + tb+="cr.lineWidth = "+str(max(self.linewidth,1))+"\n" + tb+="cr.moveTo("+str(self.endpoint1.x)+","+str(self.endpoint1.y)+")\n" + tb+="cr.lineTo("+str(self.endpoint2.x)+","+str(self.endpoint2.y)+")\n" + tb+="cr.stroke()\n" + tb+="cr.restore()\n" + elif SYSTEM=="osx": + if USING_GL: + cr.save() + glColor3f(1.0,0.0,0.0) + glBegin(GL_LINES) + cr.x, cr.y = (self.endpoint1.x, self.endpoint1.y) + glVertex2f(cr.x, -cr.y) + point = (self.endpoint2.x, self.endpoint2.y) + glVertex2f(point[0], -point[1]) # because OpenGL swaps y coords + cr.x, cr.y = point + glEnd() + cr.restore() + else: + cr.gsave() + cr.newpath() + cr.pencolor = self.linecolor.pygui + cr.pensize = max(self.linewidth,1) + cr.moveto(self.endpoint1.x, self.endpoint1.y) + cr.lineto(self.endpoint2.x,self.endpoint2.y) + cr.stroke() + cr.grestore() + elif SYSTEM=="html": + tb = "" + tb+="cr.save()\n" + tb+="cr.lineWidth = "+str(max(self.linewidth,1))+"\n" + tb+="cr.moveTo("+str(self.endpoint1.x)+","+str(self.endpoint1.y)+")\n" + tb+="cr.lineTo("+str(self.endpoint2.x)+","+str(self.endpoint2.y)+")\n" + tb+="cr.stroke()\n" + tb+="cr.restore()\n" + jscommunicate(tb) def set_cursor(curs, widget=None): if SYSTEM == "osx": From 148d9f17823c897a8a06741bcd543b497669acf4 Mon Sep 17 00:00:00 2001 From: Skyler Lehmkuhl Date: Sat, 27 Apr 2013 16:18:25 -0400 Subject: [PATCH 02/17] Work on paint bucketing algorithm --- lightningbeam.py | 4 +++ misc_funcs.py | 22 ++++++++++++++ svlgui.py | 78 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+) diff --git a/lightningbeam.py b/lightningbeam.py index 0cd3137..551cd41 100755 --- a/lightningbeam.py +++ b/lightningbeam.py @@ -123,9 +123,11 @@ def onMouseDownGroup(self, x, y,button=1,clicks=1): for i in self.lines: if abs(self.cshape.endpoint1.x-i.endpoint1.x)<10 and abs(self.cshape.endpoint1.y-i.endpoint1.y)<10: self.cshape.connection1 = i.endpoint1 + self.cshape.connection1.lines.add(self.cshape) break elif abs(self.cshape.endpoint1.x-i.endpoint2.x)<10 and abs(self.cshape.endpoint1.y-i.endpoint2.y)<10: self.cshape.connection1 = i.endpoint2 + self.cshape.connection1.lines.add(self.cshape) break self.lines.append(self.cshape) return @@ -201,9 +203,11 @@ def onMouseUpGroup(self, x, y,button=1,clicks=1): for i in self.lines: if abs(self.cshape.endpoint2.x-i.endpoint1.x)<10 and abs(self.cshape.endpoint2.y-i.endpoint1.y)<10: self.cshape.connection2 = i.endpoint1 + self.cshape.connection2.lines.add(self.cshape) break elif abs(self.cshape.endpoint2.x-i.endpoint2.x)<10 and abs(self.cshape.endpoint2.y-i.endpoint2.y)<10: self.cshape.connection2 = i.endpoint2 + self.cshape.connection2.lines.add(self.cshape) break self.cshape = None MainWindow.stage.draw() diff --git a/misc_funcs.py b/misc_funcs.py index 336f251..d007ac2 100644 --- a/misc_funcs.py +++ b/misc_funcs.py @@ -96,8 +96,30 @@ def lastval(arr,index): return i +def angle_to_point(point1, point2): + deltaX = point2.x-point1.x + deltaY = point2.y-point1.y + angleInDegrees = math.atan2(-deltaY, deltaX) * 180 / math.pi + if angleInDegrees<0: angleInDegrees = 360+angleInDegrees + return angleInDegrees +def sqr(x) : + return x * x +def dist2(v, w): + return sqr(v.x - w.x) + sqr(v.y - w.y) +def distToSegmentSquared(p, v, w): + l2 = dist2(v, w) + if l2 == 0: + return dist2(p, v) + t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2 + if t < 0: + return dist2(p, v) + if t > 1: + return dist2(p, w) + return dist2(p, svlgui.Point(x=(v.x+t*(w.x-v.x)), y=(v.y+t*(w.y-v.y)))) +def distToSegment(p, v, w): + return math.sqrt(distToSegmentSquared(p, v, w)) def catmullRom2bezier( points ) : #crp = points.split(/[,\s]/); diff --git a/svlgui.py b/svlgui.py index f7da3b5..9d6e4a0 100644 --- a/svlgui.py +++ b/svlgui.py @@ -2658,6 +2658,45 @@ class Group (object): i.endpoint2.y = y self.activepoint = i.endpoint2 return + elif MODE=="b": + nlines = [i for i in self.lines] + endsleft = True + while endsleft: + endsleft = False + print nlines + for i in reversed(nlines): + if not (i.endpoint1 in [j.endpoint1 for j in nlines if not j==i]+[j.endpoint2 for j in nlines if not j==i]): + nlines.remove(i) + endsleft = True + elif not (i.endpoint2 in [j.endpoint1 for j in nlines if not j==i]+[j.endpoint2 for j in nlines if not j==i]): + nlines.remove(i) + endsleft = True + if nlines: + mindist = sys.maxint + point = Point(x, y) + closestsegment = None + for i in nlines: + d = misc_funcs.distToSegment(point,i.endpoint1,i.endpoint2) + if d" class Line(object): @@ -2883,15 +2925,51 @@ class Line(object): super(Line, self).__init__() self.endpoint1 = endpoint1 self.endpoint2 = endpoint2 + self.endpoint1.lines.add(self) + self.endpoint2.lines.add(self) self.connection1 = connection1 self.connection2 = connection2 + if self.connection1: self.connection1.lines.add(self) + if self.connection2: self.connection2.lines.add(self) self.linecolor = LINECOLOR self.linewidth = LINEWIDTH + def __repr__(self): + return "" def assign(self, point, which): if which==1: self.connection1 = point + self.connection1.lines.add(self) elif which==2: self.connection2 = point + self.connection2.lines.add(self) + def angle(self, other): + if self.endpoint1==other.endpoint1: + x1 = self.endpoint2.x-self.endpoint1.x + y1 = self.endpoint2.y-self.endpoint1.y + x2 = other.endpoint2.x-other.endpoint1.x + y2 = other.endpoint2.y-other.endpoint1.y + elif self.endpoint2==other.endpoint1: + x1 = self.endpoint1.x-self.endpoint2.x + y1 = self.endpoint1.y-self.endpoint2.y + x2 = other.endpoint2.x-other.endpoint1.x + y2 = other.endpoint2.y-other.endpoint1.y + elif self.endpoint1==other.endpoint2: + x1 = self.endpoint2.x-self.endpoint1.x + y1 = self.endpoint2.y-self.endpoint1.y + x2 = other.endpoint1.x-other.endpoint2.x + y2 = other.endpoint1.y-other.endpoint2.y + elif self.endpoint2==other.endpoint2: + x1 = self.endpoint1.x-self.endpoint2.x + y1 = self.endpoint1.y-self.endpoint2.y + x2 = other.endpoint1.x-other.endpoint2.x + y2 = other.endpoint1.y-other.endpoint2.y + dot = x1*x2+y1*y2 + mag1 = math.sqrt(x1**2+y1**2) + mag2 = math.sqrt(x2**2+y2**2) + angle = math.acos(dot/(mag1*mag2))/math.pi*180 + cz = x1*y2-y1*x2 + if cz>0: angle=360-angle + return angle def draw(self, cr=None, transform=None, rect=None): if self.connection1: self.endpoint1 = self.connection1 From 9a228aba7eb4d5786f054dc351491334bf76e024 Mon Sep 17 00:00:00 2001 From: Skyler Lehmkuhl Date: Sat, 27 Apr 2013 23:02:16 -0400 Subject: [PATCH 03/17] Added more code to paint bucket algorithm, but it doesn't really work yet. --- svlgui.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/svlgui.py b/svlgui.py index 9d6e4a0..9fba160 100644 --- a/svlgui.py +++ b/svlgui.py @@ -2689,12 +2689,21 @@ class Group (object): else: startpoint = closestsegment.endpoint1 print startpoint.lines - linelist = [] - for i in startpoint.lines: - if i != closestsegment: - print closestsegment.angle(i) - # nextline = min([[i]]) + linelist = [closestsegment] + # nextline = max([[closestsegment.angle(i),i] for i in startpoint.lines if not i in linelist]) + # print nextline # Then, follow clockwise-most segment leading off from said point + while True: + try: + nextline = max([[closestsegment.angle(i),i] for i in startpoint.lines if not i==closestsegment])[1] + except: + break + closestsegment = nextline + if not nextline in linelist: + linelist.append(nextline) + else: + break + print "*****",linelist # Continue until closestsegment is reached. I _think_ this is inevitable. self.selecting = True From c366230144c9d4a5e11e7de6d07caaa0f8129bff Mon Sep 17 00:00:00 2001 From: Skyler Lehmkuhl Date: Tue, 6 Aug 2013 11:43:19 -0400 Subject: [PATCH 04/17] control --- control | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/control b/control index 94f631e..55c9e74 100644 --- a/control +++ b/control @@ -4,6 +4,7 @@ Section: graphics Priority: optional Architecture: all Installed-size: 27000 -Depends: bash, python, python-imaging +Depends: bash, python, python-imaging, imagemagick, libzzip-0-13, sox, python-numpy, mplayer Maintainer: skycooler@gmail.com Description: Lightningbeam is an open-source animated content creation tool. + From f40c99472d55e771ed2f07959a8f369281f68a27 Mon Sep 17 00:00:00 2001 From: Skyler Lehmkuhl Date: Tue, 6 Aug 2013 11:55:56 -0400 Subject: [PATCH 05/17] Disabled buggy syntax highlighting --- lightningbeam_windows.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lightningbeam_windows.py b/lightningbeam_windows.py index 63d79ae..642adad 100755 --- a/lightningbeam_windows.py +++ b/lightningbeam_windows.py @@ -9,6 +9,7 @@ import misc_funcs from misc_funcs import * class MainWindow: + ''' GTK UI. Not currently used. ''' def __init__(self): self.window = svlgui.Window("Lightningbeam") self.window.maximize() @@ -134,6 +135,7 @@ class MainWindow: class MainWindowAndroid: + ''' Android UI. Not currently used. Will be replaced with Kivy. ''' def __init__(self): class stagewrapper: def add(self, obj, x, y): @@ -231,7 +233,8 @@ class MainWindowOSX: # self.toolbox.buttons[1][0]._int().enabled = False self.toolbox.buttons[3][0]._int().enabled = False self.toolbox.buttons[4][0]._int().enabled = False - self.scriptwindow = svlgui.TextView(code=True) + # self.scriptwindow = svlgui.TextView(code=True) + self.scriptwindow = svlgui.TextView(code=False) self.paintgroup = svlgui.RadioGroup("Draw straight", "Draw smooth", "Draw as inked") def setmode(self): svlgui.PMODE = self.value From e7de822f427faff06f5b81104f75ab498816f37a Mon Sep 17 00:00:00 2001 From: Skyler Lehmkuhl Date: Tue, 6 Aug 2013 21:03:24 -0400 Subject: [PATCH 06/17] more work on Kivy --- kt.py | 12 ++++---- lightningbeam.kv | 8 ++++-- lightningbeam.py | 2 ++ lightningbeam_windows.py | 5 +++- svlgui.py | 60 ++++++++++++++++++++++++++++++++++++++-- 5 files changed, 77 insertions(+), 10 deletions(-) diff --git a/kt.py b/kt.py index 6036c9c..664d545 100644 --- a/kt.py +++ b/kt.py @@ -9,16 +9,18 @@ from kivy.graphics import Color, Ellipse, Line Builder.load_file("lightningbeam.kv") -class Lightningbeam(TabbedPanel): +class LightningbeamPanel(TabbedPanel): pass +class KivyCanvas(Widget): + def on_touch_down(self, touch): + print touch.button -class MyPaintApp(App): +class LightningbeamApp(App): def build(self): - return Lightningbeam() - + return LightningbeamPanel() if __name__ == '__main__': - MyPaintApp().run() \ No newline at end of file + LightningbeamApp().run() \ No newline at end of file diff --git a/lightningbeam.kv b/lightningbeam.kv index d786086..6322c4d 100644 --- a/lightningbeam.kv +++ b/lightningbeam.kv @@ -1,12 +1,16 @@ #:kivy 1.0 #:import ActionScriptLexer pygments.lexers.ActionScriptLexer -: +: + + +: do_default_tab: False TabbedPanelItem: text: 'Drawing' BoxLayout: orientation: "vertical" + KivyCanvas: TabbedPanelItem: text: 'Tools' @@ -25,7 +29,7 @@ Button: text: "Ellipse" Button: - text: "Painbrush" + text: "Paintbrush" TabbedPanelItem: text: 'ActionScript' CodeInput: diff --git a/lightningbeam.py b/lightningbeam.py index 551cd41..fc44e72 100755 --- a/lightningbeam.py +++ b/lightningbeam.py @@ -569,6 +569,8 @@ if svlgui.SYSTEM == "gtk": MainWindow = lightningbeam_windows.MainWindow() elif svlgui.SYSTEM=="osx": MainWindow = lightningbeam_windows.MainWindowOSX() +elif svlgui.SYSTEM=="kivy": + MainWindow = lightningbeam_windows.MainWindowKivy() elif svlgui.SYSTEM=="html": MainWindow = lightningbeam_windows.MainWindowHTML() elif svlgui.SYSTEM=="pyglet": diff --git a/lightningbeam_windows.py b/lightningbeam_windows.py index 642adad..a7f2a3a 100755 --- a/lightningbeam_windows.py +++ b/lightningbeam_windows.py @@ -438,7 +438,10 @@ class MainWindowHTML: [self.stage,self.toolbox._int(),self.scriptwindow._int(),self.timelinebox._int()+2,0,"nsew", "hv"] ) self.window.add(self.frame) - +class MainWindowKivy: + def __init__(self): + from kivy.lang import Builder + Builder.load_file("lightningbeam.kv") if __name__=="__main__": a = MainWindow() diff --git a/svlgui.py b/svlgui.py index 9fba160..b85f7f7 100644 --- a/svlgui.py +++ b/svlgui.py @@ -136,6 +136,8 @@ class Color (object): retval = "var "+self.val.split('/')[-1].replace(' ','_').replace('.','_')+" = new Image();\n" retval = retval+self.val.split('/')[-1].replace(' ','_').replace('.','_')+".src = \""+self.val.split("/")[-1]+"\";\n" return retval + def print_json(self): + return {'type':'Color','arguments':{'val':self.val}} def rgb2hex(r, g, b, a=1): r=hex(int(r*255)).split("x")[1].zfill(2) g=hex(int(g*255)).split("x")[1].zfill(2) @@ -203,6 +205,7 @@ if sys.platform=="linux2": import pickle import tarfile import tempfile + ''' import GUI # Using PyGUI. Experimental. from GUI import Window as OSXWindow, Button as OSXButton, Image as OSXImage from GUI import Frame as OSXFrame, Color as OSXColor, Grid as OSXGrid, CheckBox as OSXCheckBox @@ -220,7 +223,16 @@ if sys.platform=="linux2": from PIL import Image as PILImage except ImportError: import Image as PILImage - from GUI.Geometry import offset_rect, rect_sized + SYSTEM="osx" + from GUI.Geometry import offset_rect, rect_sized''' + + from kivy.app import App # Using Kivy. Very experimental. + from kivy.uix.widget import Widget + from kivy.uix.codeinput import CodeInput + from kivy.uix.tabbedpanel import TabbedPanel + from kivy.uix.button import Button + from kivy.graphics import Color, Ellipse, Line + SYSTEM="kivy" #If we can import this, we are in the install directory. Mangle media paths accordingly. try: @@ -228,7 +240,6 @@ if sys.platform=="linux2": except: media_path = "" #app = GUI.application() - SYSTEM="osx" TEMPDIR = "/tmp" FONT = u'Times New Roman' ''' @@ -379,6 +390,31 @@ if SYSTEM=="osx": app = Lightningbeam() +elif SYSTEM=="kivy": + class Lightningbeam(App): + def build(self): + return LightningbeamPanel() + class LightningbeamPanel(TabbedPanel): + pass + class KivyCanvas(Widget): + def draw(self): + with self.canvas: + for i in self.objs: + try: + i.draw(None) + except: + traceback.print_exc() + def on_touch_down(self, touch): + x, y = touch.x, touch.y + try: + try: + for i in self.objs: + i._onMouseDown(x,y,button=touch.button, clicks=(3 if touch.is_triple_click else (2 if touch.is_double_click else 1))) + except ObjectDeletedError: + return + except: + traceback.print_exc() + self.draw() elif SYSTEM=="html": app = "" @@ -1153,6 +1189,9 @@ class Canvas(Widget): pass self.canvas = OSXCanvas(extent = (width, height), scrolling = 'hv') self.canvas.objs = self.objs + elif SYSTEM=="kivy": + + self.canvas = KivyCanvas() elif SYSTEM=="html": global ids while True: @@ -1185,6 +1224,8 @@ class Canvas(Widget): def draw(self): if SYSTEM=="gtk": self.expose_event(self.canvas, "draw_event", self.objs) + elif SYSTEM=="kivy": + self.canvas.draw() elif SYSTEM in ["osx", "android"]: self.canvas.invalidate_rect((0,0,self.canvas.extent[0],self.canvas.extent[1])) elif SYSTEM=="html": @@ -1192,6 +1233,8 @@ class Canvas(Widget): def is_focused(self): if SYSTEM=="osx": return self.canvas.is_target() + else: + return false def add(self, obj, x, y): obj.x = x obj.y = y @@ -1493,6 +1536,8 @@ class Image(object): pass def print_sc(self): return ".png "+self.name+" \""+self.path+"\"\n" + def print_json(self): + return {'type':'Image','arguments':{'image':self.image,'x':self.x,'y':self.y,'animated':self.animated,'canvas':None,'htiles':self.htiles,'vtiles':self.vtiles,'skipl':false}} class Shape (object): def __init__(self,x=0,y=0,rotation=0,fillcolor=None,linecolor=None): @@ -1638,6 +1683,10 @@ class Shape (object): else: cr.stroke() cr.grestore() + elif SYSTEM=="kivy": + Color(1, 1, 0) + d = 30. + Ellipse(pos=(self.x - d / 2, self.y - d / 2), size=(d, d)) elif SYSTEM=="html": tb = "" tb+="cr.save()\n" @@ -1768,6 +1817,13 @@ class Shape (object): retval += self.name+".fill = \""+self.fillcolor.rgb+"\";\n"+self.name+".line = \""+self.linecolor.rgb+"\";\n" retval += self.name+".filled = "+str(self.filled).lower()+";\n" return retval + def print_json(self): + return {'type':'Shape','arguments':{'x':self.x, + 'y':self.y, + 'rotation':self.rotation, + 'linecolor':self.linecolor.print_json(), + 'fillcolor':self.fillcolor.print_json()}, + 'properties':{'shapedata':self.shapedata}} class Text (object): def __init__(self,text="",x=0,y=0): From be70f40abede9d117061746a170e14c2d0296b3c Mon Sep 17 00:00:00 2001 From: Skyler Lehmkuhl Date: Thu, 28 Nov 2013 00:02:16 -0500 Subject: [PATCH 07/17] Added some comments --- svlgui.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/svlgui.py b/svlgui.py index b85f7f7..42ceeae 100644 --- a/svlgui.py +++ b/svlgui.py @@ -205,7 +205,7 @@ if sys.platform=="linux2": import pickle import tarfile import tempfile - ''' + import GUI # Using PyGUI. Experimental. from GUI import Window as OSXWindow, Button as OSXButton, Image as OSXImage from GUI import Frame as OSXFrame, Color as OSXColor, Grid as OSXGrid, CheckBox as OSXCheckBox @@ -224,7 +224,8 @@ if sys.platform=="linux2": except ImportError: import Image as PILImage SYSTEM="osx" - from GUI.Geometry import offset_rect, rect_sized''' + from GUI.Geometry import offset_rect, rect_sized + ''' from kivy.app import App # Using Kivy. Very experimental. from kivy.uix.widget import Widget @@ -232,7 +233,7 @@ if sys.platform=="linux2": from kivy.uix.tabbedpanel import TabbedPanel from kivy.uix.button import Button from kivy.graphics import Color, Ellipse, Line - SYSTEM="kivy" + SYSTEM="kivy"''' #If we can import this, we are in the install directory. Mangle media paths accordingly. try: @@ -2776,9 +2777,12 @@ class Group (object): self.dragging = False self.selecting = False x, y = self.localtransform(x, y) + # If we are in selection mode and the current level (i.e. what we're inside of) is this layer if self.activelayer.level and MODE in [" ", "s"]: + # If we have a selection if self.activelayer.currentselect: self.activelayer.currentselect._onMouseUp(x, y, button=button, clicks=clicks) + # COMMENT PLZ elif self.activepoint: for i in self.lines: if abs(self.activepoint.x-i.endpoint1.x)<10 and abs(self.activepoint.y-i.endpoint1.y)<10: @@ -2798,7 +2802,9 @@ class Group (object): break except IndexError: pass break + # if neither of those, but we've dragged the mouse at least 4 pixels in either axis elif abs(self.startx-x)>4 or abs(self.starty-y)>4: + # this should make a temporary group containing all the objects within the area we dragged objs = [] for i in reversed(self.currentFrame()): if self.startx Date: Thu, 28 Nov 2013 00:08:18 -0500 Subject: [PATCH 08/17] Fixed TemporaryGroup initialization --- svlgui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svlgui.py b/svlgui.py index 42ceeae..20703f3 100644 --- a/svlgui.py +++ b/svlgui.py @@ -2922,7 +2922,7 @@ class Group (object): class TemporaryGroup(Group): """Created when selecting multiple items, for ease of use.""" def __init__(self, *args, **kwargs): - (TemporaryGroup, self).__init__(*args, **kwargs) + super(TemporaryGroup, self).__init__(*args, **kwargs) # def draw(self, cr=None, transform=None, rect=None): # super(TemporaryGroup, self).draw(cr, transform, rect) # print self.x, self.activelayer.x From 7318989db3c15f520865db0811fe41c13dd6a259 Mon Sep 17 00:00:00 2001 From: Skyler Lehmkuhl Date: Thu, 28 Nov 2013 00:39:28 -0500 Subject: [PATCH 09/17] HAAAAAAAAAAAAAAAAAAAAAAANDS --- misc_funcs.py | 1 - 1 file changed, 1 deletion(-) diff --git a/misc_funcs.py b/misc_funcs.py index d007ac2..bd422b3 100644 --- a/misc_funcs.py +++ b/misc_funcs.py @@ -206,7 +206,6 @@ def simplify_shape(shape,mode,iterations): del shape[j] if mode=="smooth": shape = catmullRom2bezier([shape[0]]*2+shape+[shape[-1]]) - print shape return shape#+nshape From 2044659c3c37ea439a8353b02cc36057697181db Mon Sep 17 00:00:00 2001 From: Skyler Lehmkuhl Date: Thu, 28 Nov 2013 00:41:43 -0500 Subject: [PATCH 10/17] Returning to actual shape drawing, cleaned up a print --- lightningbeam.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/lightningbeam.py b/lightningbeam.py index fc44e72..a5d4f2e 100755 --- a/lightningbeam.py +++ b/lightningbeam.py @@ -118,8 +118,15 @@ def onMouseDownGroup(self, x, y,button=1,clicks=1): elif svlgui.MODE=="e": self.cshape = ellipse(x, y, 0, 0) elif svlgui.MODE=="p": - # self.cshape = shape(x, y) - self.cshape = svlgui.Line(svlgui.Point(x, y),svlgui.Point(x,y)) + for i in self.lines: + if abs(x-i.endpoint1.x)<10 and abs(y-i.endpoint1.y)<10: + x, y = i.endpoint1.x, i.endpoint1.y + break + elif abs(x-i.endpoint2.x)<10 and abs(i.endpoint2.y)<10: + x, y = i.endpoint2.x, i.endpoint2.y + break + self.cshape = shape(x, y) + '''self.cshape = svlgui.Line(svlgui.Point(x, y),svlgui.Point(x,y)) for i in self.lines: if abs(self.cshape.endpoint1.x-i.endpoint1.x)<10 and abs(self.cshape.endpoint1.y-i.endpoint1.y)<10: self.cshape.connection1 = i.endpoint1 @@ -130,7 +137,7 @@ def onMouseDownGroup(self, x, y,button=1,clicks=1): self.cshape.connection1.lines.add(self.cshape) break self.lines.append(self.cshape) - return + return''' #self.cshape.rotation = 5 self.cshape.initx,self.cshape.inity = x, y self.add(self.cshape) @@ -197,10 +204,11 @@ def onMouseUpGroup(self, x, y,button=1,clicks=1): undo_stack[-1] = undo_stack[-1].complete({"obj":cobj, "frame":self.activelayer.currentframe, "layer":self.activelayer}) clear(redo_stack) elif svlgui.MODE=="p": - '''print len(self.cshape.shapedata) + prelen = len(self.cshape.shapedata) self.cshape.shapedata = misc_funcs.simplify_shape(self.cshape.shapedata, svlgui.PMODE.split()[-1],1) - print len(self.cshape.shapedata)''' - for i in self.lines: + postlen = len(self.cshape.shapedata) + print str((prelen-postlen)*100/prelen)+"% reduction: started at "+str(prelen)+" vertices, ended at "+str(postlen)+" vertices" + '''for i in self.lines: if abs(self.cshape.endpoint2.x-i.endpoint1.x)<10 and abs(self.cshape.endpoint2.y-i.endpoint1.y)<10: self.cshape.connection2 = i.endpoint1 self.cshape.connection2.lines.add(self.cshape) @@ -208,7 +216,7 @@ def onMouseUpGroup(self, x, y,button=1,clicks=1): elif abs(self.cshape.endpoint2.x-i.endpoint2.x)<10 and abs(self.cshape.endpoint2.y-i.endpoint2.y)<10: self.cshape.connection2 = i.endpoint2 self.cshape.connection2.lines.add(self.cshape) - break + break''' self.cshape = None MainWindow.stage.draw() def onMouseUpObj(self, x, y,button=1,clicks=1): @@ -267,9 +275,9 @@ def onMouseDragGroup(self, x, y,button=1,clicks=1): y=y-self.cshape.inity self.cshape.shapedata = [["M",x/2,0],["C",4*x/5,0,x,y/5,x,y/2],["C",x,4*y/5,4*x/5,y,x/2,y],["C",x/5,y,0,4*y/5,0,y/2],["C",0,y/5,x/5,0,x/2,0]] elif svlgui.MODE == "p": - # self.cshape.shapedata.append(["L",x-self.cshape.initx,y-self.cshape.inity]) - self.cshape.endpoint2.x = x - self.cshape.endpoint2.y = y + self.cshape.shapedata.append(["L",x-self.cshape.initx,y-self.cshape.inity]) + # self.cshape.endpoint2.x = x + # self.cshape.endpoint2.y = y def onMouseDragObj(self, x, y,button=1,clicks=1): if svlgui.MODE==" ": self.x = x-self.initx From 2bb407c7dae001db31b983bcce389a3069c0f2f7 Mon Sep 17 00:00:00 2001 From: Skyler Lehmkuhl Date: Thu, 28 Nov 2013 01:17:16 -0500 Subject: [PATCH 11/17] Convert shapes in 'straight' smoothing mode to Lines --- lightningbeam.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lightningbeam.py b/lightningbeam.py index a5d4f2e..a41c515 100755 --- a/lightningbeam.py +++ b/lightningbeam.py @@ -208,6 +208,17 @@ def onMouseUpGroup(self, x, y,button=1,clicks=1): self.cshape.shapedata = misc_funcs.simplify_shape(self.cshape.shapedata, svlgui.PMODE.split()[-1],1) postlen = len(self.cshape.shapedata) print str((prelen-postlen)*100/prelen)+"% reduction: started at "+str(prelen)+" vertices, ended at "+str(postlen)+" vertices" + if svlgui.PMODE.split()[-1]=="straight": + lastline = None + x, y = self.cshape.x, self.cshape.y + for a, b in misc_funcs.pairwise(self.cshape.shapedata): + l = svlgui.Line(svlgui.Point(a[1]+x,a[2]+y),svlgui.Point(b[1]+x,b[2]+y)) + if lastline: + l.connection1 = lastline.endpoint2 + l.connection1.lines.add(l) + lastline = l + self.lines.append(l) + self.delete(self.activelayer.frames[self.currentframe].objs[-1]) '''for i in self.lines: if abs(self.cshape.endpoint2.x-i.endpoint1.x)<10 and abs(self.cshape.endpoint2.y-i.endpoint1.y)<10: self.cshape.connection2 = i.endpoint1 From c3bed8df3647d16772d7bf060c1ef988d2fb1cba Mon Sep 17 00:00:00 2001 From: Skyler Lehmkuhl Date: Thu, 28 Nov 2013 01:22:38 -0500 Subject: [PATCH 12/17] Added function to step in pairs --- misc_funcs.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/misc_funcs.py b/misc_funcs.py index bd422b3..fa301ce 100644 --- a/misc_funcs.py +++ b/misc_funcs.py @@ -5,6 +5,7 @@ import svlgui from threading import Event, Thread +from itertools import tee, izip import math import subprocess import re @@ -258,3 +259,10 @@ class RepeatTimer(Thread): def cancel(self): self.finished.set() + + +def pairwise(iterable): + "s -> (s0,s1), (s1,s2), (s2, s3), ..." + a, b = tee(iterable) + next(b, None) + return izip(a, b) From 879a7c18a9b6dcf982a460641518f199dafbf287 Mon Sep 17 00:00:00 2001 From: Skyler Lehmkuhl Date: Thu, 28 Nov 2013 01:23:45 -0500 Subject: [PATCH 13/17] Added Group-level delete function, fixed selection being broken after vector editing --- svlgui.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/svlgui.py b/svlgui.py index 20703f3..64d15d8 100644 --- a/svlgui.py +++ b/svlgui.py @@ -2413,6 +2413,7 @@ class Layer: print "#>>",i for j in self.frames[self.currentframe].objs: if j == i: + print "Deleting",j del self.currentFrame()[self.currentFrame().index(j)] def add_frame(self,populate): if self.activeframe>len(self.frames): @@ -2634,6 +2635,8 @@ class Group (object): i.draw(cr, rect=rect) def add(self, *args): self.activelayer.add(*args) + def delete(self, *args): + self.activelayer.delete(*args) def add_frame(self, populate): self.activelayer.add_frame(populate) def add_layer(self, index): @@ -2782,7 +2785,7 @@ class Group (object): # If we have a selection if self.activelayer.currentselect: self.activelayer.currentselect._onMouseUp(x, y, button=button, clicks=clicks) - # COMMENT PLZ + # If we have a point that we're dragging around (vector editing) elif self.activepoint: for i in self.lines: if abs(self.activepoint.x-i.endpoint1.x)<10 and abs(self.activepoint.y-i.endpoint1.y)<10: @@ -2802,6 +2805,7 @@ class Group (object): break except IndexError: pass break + self.activepoint = None # if neither of those, but we've dragged the mouse at least 4 pixels in either axis elif abs(self.startx-x)>4 or abs(self.starty-y)>4: # this should make a temporary group containing all the objects within the area we dragged From 664d0e67ac1d0b97c81fdf5d85149f612a51c684 Mon Sep 17 00:00:00 2001 From: Skyler Lehmkuhl Date: Thu, 28 Nov 2013 02:52:13 -0500 Subject: [PATCH 14/17] Paint bucketing shapes mostly working --- misc_funcs.py | 25 ++++++++++++ svlgui.py | 109 ++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 122 insertions(+), 12 deletions(-) diff --git a/misc_funcs.py b/misc_funcs.py index fa301ce..5cf511f 100644 --- a/misc_funcs.py +++ b/misc_funcs.py @@ -10,6 +10,7 @@ import math import subprocess import re import os +import sys def select_any(self): svlgui.MODE = " " @@ -266,3 +267,27 @@ def pairwise(iterable): a, b = tee(iterable) next(b, None) return izip(a, b) + +def hittest(linelist,x,y): + hits = False + def IsOnLeft(a, b, c): + return Area2(a, b, c) > 0 + def IsOnRight(a, b, c): + return Area2(a, b, c) < 0 + def IsCollinear(a, b, c): + return Area2(a, b, c) == 0 + # calculates the triangle's size (formed by the "anchor" segment and additional point) + def Area2(a, b, c): + return (b[0]-a[0])*(c[1]-a[1])-(c[0]-a[0])*(b[1]-a[1]) + def intersects(a,b,c,d): + return not (IsOnLeft(a,b,c) != IsOnRight(a,b,d)) + def ccw(a,b,c): + return (c[1]-a[1])*(b[0]-a[0]) > (b[1]-a[1])*(c[0]-a[0]) + def intersect(a,b,c,d): + return ccw(a,c,d) != ccw(b,c,d) and ccw(a,b,c) != ccw(a,b,d) + for i in xrange(len(linelist)): + hits = hits != intersect([linelist[i-1].endpoint1.x,linelist[i-1].endpoint1.y], + [linelist[i].endpoint1.x,linelist[i].endpoint1.y],[x,y],[x,sys.maxint]) + print hits, x, y + return hits + diff --git a/svlgui.py b/svlgui.py index 64d15d8..0612ea7 100644 --- a/svlgui.py +++ b/svlgui.py @@ -2631,6 +2631,8 @@ class Group (object): cr.pencolor = Color([0,0,1]).pygui cr.stroke_rect([sorted([self.startx,self.cx])[0], sorted([self.starty,self.cy])[0], \ sorted([self.startx,self.cx])[1], sorted([self.starty,self.cy])[1]]) + for i in self.fills: + i.draw(cr, rect=rect) for i in self.lines: i.draw(cr, rect=rect) def add(self, *args): @@ -2720,17 +2722,15 @@ class Group (object): return elif MODE=="b": nlines = [i for i in self.lines] - endsleft = True - while endsleft: - endsleft = False - print nlines - for i in reversed(nlines): - if not (i.endpoint1 in [j.endpoint1 for j in nlines if not j==i]+[j.endpoint2 for j in nlines if not j==i]): - nlines.remove(i) - endsleft = True - elif not (i.endpoint2 in [j.endpoint1 for j in nlines if not j==i]+[j.endpoint2 for j in nlines if not j==i]): - nlines.remove(i) - endsleft = True + # First, remove all line segments that have at least one free endpoit, not coincident with any other segment. + # Do that repeatedly until no such segment remains. + for i in reversed(nlines): + if not (i.endpoint1 in [j.endpoint1 for j in nlines if not j==i]+[j.endpoint2 for j in nlines if not j==i]): + nlines.remove(i) + elif not (i.endpoint2 in [j.endpoint1 for j in nlines if not j==i]+[j.endpoint2 for j in nlines if not j==i]): + nlines.remove(i) + + # Find the closest segment to the point. if nlines: mindist = sys.maxint point = Point(x, y) @@ -2740,6 +2740,71 @@ class Group (object): if d Date: Thu, 28 Nov 2013 13:41:42 -0500 Subject: [PATCH 15/17] Fixed paint bucket skipping points --- svlgui.py | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/svlgui.py b/svlgui.py index 0612ea7..f36f4d0 100644 --- a/svlgui.py +++ b/svlgui.py @@ -2770,8 +2770,26 @@ class Group (object): # Check if the polygon encloses the given point. If it is not, then we've found an "island" if misc_funcs.hittest(linelist,x,y): f = Fill() - f.lines = linelist - print linelist + dic = {} + for i in linelist: + dic[i.endpoint1]=i + + def walk(list_of_lines, starting_point): + lookup_map = {} + for i in list_of_lines: + lookup_map[i.endpoint1]=i + cur_point = starting_point + visited_points = [] + print lookup_map + while cur_point.endpoint2 in lookup_map and not cur_point in visited_points: + visited_points.append(cur_point) + cur_point = lookup_map[cur_point.endpoint2] + yield cur_point + + + # f.lines = linelist + f.lines = [x for x in walk(linelist,linelist[0])] + print f.lines self.fills.append(f) else: print "No hit" @@ -3176,9 +3194,9 @@ class Fill(object): cr.gsave() cr.newpath() cr.fillcolor = self.fillcolor.pygui - cr.moveto(self.lines[0].endpoint2.x,self.lines[0].endpoint2.y) + cr.moveto(self.lines[0].endpoint1.x,self.lines[0].endpoint1.y) for i in self.lines: - cr.lineto(i.endpoint1.x,i.endpoint1.y) + cr.lineto(i.endpoint2.x,i.endpoint2.y) cr.fill() cr.grestore() From 1c10240f5795adecc11dbebd14a8097a960924cb Mon Sep 17 00:00:00 2001 From: Skyler Lehmkuhl Date: Thu, 28 Nov 2013 14:33:31 -0500 Subject: [PATCH 16/17] work on breaking intersecting lines. Doesn't work. --- lightningbeam.py | 20 ++++++++++++++++++++ svlgui.py | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/lightningbeam.py b/lightningbeam.py index a41c515..dfa59ef 100755 --- a/lightningbeam.py +++ b/lightningbeam.py @@ -219,6 +219,26 @@ def onMouseUpGroup(self, x, y,button=1,clicks=1): lastline = l self.lines.append(l) self.delete(self.activelayer.frames[self.currentframe].objs[-1]) + for line in self.lines: + for otherline in self.lines: + if not otherline is line: + if line.connection1 and otherline in line.connection1.lines: continue + if line.connection2 and otherline in line.connection2.lines: continue + inter = line.intersects(otherline) + if inter: + print "INTERSECTION" + inter = svlgui.Point(*inter) + l1 = svlgui.Line(line.endpoint1,inter,line.connection1,inter) + l2 = svlgui.Line(line.endpoint2,inter,line.connection2,inter) + l3 = svlgui.Line(otherline.endpoint1,inter,otherline.connection1,inter) + l4 = svlgui.Line(otherline.endpoint2,inter,otherline.connection2,inter) + inter.lines.add(l1) + inter.lines.add(l2) + inter.lines.add(l3) + inter.lines.add(l4) + self.lines[self.lines.index(line):self.lines.index(line)+1]=[l1,l2] + self.lines[self.lines.index(otherline):self.lines.index(otherline)+1]=[l3,l4] + break '''for i in self.lines: if abs(self.cshape.endpoint2.x-i.endpoint1.x)<10 and abs(self.cshape.endpoint2.y-i.endpoint1.y)<10: self.cshape.connection2 = i.endpoint1 diff --git a/svlgui.py b/svlgui.py index f36f4d0..6ecafe8 100644 --- a/svlgui.py +++ b/svlgui.py @@ -3128,6 +3128,52 @@ class Line(object): cz = x1*y2-y1*x2 if cz>0: angle=360-angle return angle + def intersects(self,other): + '''def IsOnLeft(a,b,c): + return Area2(a,b,c) > 0 + def IsOnRight(a,b,c): + return Area2(a,b,c) < 0 + def IsCollinear(a,b,c): + return Area2(a,b,c) == 0 + def Area2 (a,b,c): + return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y) + if (IsOnLeft(self.endpoint1,self.endpoint2,other.endpoint1) and IsOnRight(self.endpoint1,self.endpoint2,other.endpoint2)) + or (IsOnLeft(self.endpoint1,self.endpoint2,other.endpoint2) and IsOnRight(self.endpoint1,self.endpoint2,other.endpoint1): + if (IsOnLeft(other.endpoint1,other.endpoint2,self.endpoint1) and IsOnRight(other.endpoint1,other.endpoint2,self.endpoint2)) + or (IsOnLeft(other.endpoint1,other.endpoint2,self.endpoint2) and IsOnRight(other.endpoint1,other.endpoint2,self.endpoint1): + return True''' + # Formula for line is y = mx + b + try: + sm = (self.endpoint1.y-self.endpoint2.y)/(self.endpoint1.x-self.endpoint1.y) + om = (other.endpoint1.y-other.endpoint2.y)/(other.endpoint1.x-other.endpoint1.y) + sb = self.endpoint1.y-sm*self.endpoint1.x + ob = other.endpoint1.y-sm*other.endpoint1.x + if sm == om: return False + x = (ob-sb)/(sm-om) + y = sm*x + sb + if min(self.endpoint1.x,self.endpoint2.x) Date: Sat, 30 Nov 2013 01:42:03 -0500 Subject: [PATCH 17/17] Flash export working with Lines and Fills --- svlgui.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/svlgui.py b/svlgui.py index 6ecafe8..ddb175b 100644 --- a/svlgui.py +++ b/svlgui.py @@ -2965,6 +2965,17 @@ class Group (object): # retval+=i.print_sc(True, False) if not self.name=="_root": retval+=".sprite "+self.name+"\n" + if self.fills: + for i in self.fills: + retval+=i.print_sc() + retval+=".put fill_"+str(i.__hash__())+"\n" + if self.lines: + for i in self.lines: + retval+=".outline "+self.name+"_line_"+str(i.__hash__())+"_outline:\n" + retval+=" "+i.print_sc() + retval+="\n.end\n" + retval+=".filled "+self.name+"_line_"+str(i.__hash__())+" outline="+self.name+"_line_"+str(i.__hash__())+"_outline color="+i.linecolor.rgb+"\n" + retval+=".put "+self.name+"_line_"+str(i.__hash__())+"\n" for i in xrange(self.maxframe()): for j in self.layers: if j.frames[i]: @@ -3225,6 +3236,8 @@ class Line(object): tb+="cr.stroke()\n" tb+="cr.restore()\n" jscommunicate(tb) + def print_sc(self): + return "M "+str(self.endpoint1.x)+" "+str(self.endpoint1.y)+" L "+str(self.endpoint2.x)+" "+str(self.endpoint2.y) class Fill(object): """Fills are Shapes without edges, built from Lines""" @@ -3245,6 +3258,14 @@ class Fill(object): cr.lineto(i.endpoint2.x,i.endpoint2.y) cr.fill() cr.grestore() + def print_sc(self): + retval = ".outline fill_"+str(self.__hash__())+"_outline:\n" + retval += "M "+str(self.lines[0].endpoint1.x)+" "+str(self.lines[0].endpoint1.y) + for i in self.lines: + retval += " L "+str(i.endpoint2.x)+" "+str(i.endpoint2.y) + retval += "\n.end\n" + retval += ".filled fill_"+str(self.__hash__())+" outline=fill_"+str(self.__hash__())+"_outline fill="+self.fillcolor.rgb+"\n" + return retval def set_cursor(curs, widget=None): if SYSTEM == "osx":