def effect(self): self.vx = math.cos(math.radians( self.options.angle)) * self.options.magnitude self.vy = math.sin(math.radians( self.options.angle)) * self.options.magnitude for id, node in self.selected.iteritems(): if node.tag == inkex.addNS('path', 'svg'): group = inkex.etree.SubElement(node.getparent(), inkex.addNS('g', 'svg')) self.facegroup = inkex.etree.SubElement( group, inkex.addNS('g', 'svg')) group.append(node) t = node.get('transform') if t: group.set('transform', t) node.set('transform', '') s = node.get('style') self.facegroup.set('style', s) p = simplepath.parsePath(node.get('d')) for cmd, params in p: tees = [] if cmd == 'C': bez = (last, params[:2], params[2:4], params[-2:]) tees = [ t for t in bezmisc.beziertatslope( bez, (self.vy, self.vx)) if 0 < t < 1 ] tees.sort() segments = [] if len(tees) == 0 and cmd in ['L', 'C']: segments.append([cmd, params[:]]) elif len(tees) == 1: one, two = bezmisc.beziersplitatt(bez, tees[0]) segments.append([cmd, list(one[1] + one[2] + one[3])]) segments.append([cmd, list(two[1] + two[2] + two[3])]) elif len(tees) == 2: one, two = bezmisc.beziersplitatt(bez, tees[0]) two, three = bezmisc.beziersplitatt(two, tees[1]) segments.append([cmd, list(one[1] + one[2] + one[3])]) segments.append([cmd, list(two[1] + two[2] + two[3])]) segments.append( [cmd, list(three[1] + three[2] + three[3])]) for seg in segments: self.makeface(last, seg) last = seg[1][-2:] if cmd == 'M': subPathStart = params[-2:] if cmd == 'Z': last = subPathStart else: last = params[-2:]
def effect(self): self.vx = math.cos(math.radians(self.options.angle))*self.options.magnitude self.vy = math.sin(math.radians(self.options.angle))*self.options.magnitude for id, node in self.selected.iteritems(): if node.tagName == 'path': group = self.document.createElement('svg:g') self.facegroup = self.document.createElement('svg:g') node.parentNode.appendChild(group) group.appendChild(self.facegroup) group.appendChild(node) try: t = node.attributes.getNamedItem('transform').value group.setAttribute('transform', t) node.attributes.getNamedItem('transform').value="" except AttributeError: pass s = node.attributes.getNamedItem('style').value self.facegroup.setAttribute('style', s) p = simplepath.parsePath(node.attributes.getNamedItem('d').value) for cmd,params in p: tees = [] if cmd == 'C': bez = (last,params[:2],params[2:4],params[-2:]) tees = [t for t in bezmisc.beziertatslope(bez,(self.vy,self.vx)) if 0<t<1] tees.sort() segments = [] if len(tees) == 0 and cmd in ['L','C']: segments.append([cmd,params[:]]) elif len(tees) == 1: one,two = bezmisc.beziersplitatt(bez,tees[0]) segments.append([cmd,list(one[1]+one[2]+one[3])]) segments.append([cmd,list(two[1]+two[2]+two[3])]) elif len(tees) == 2: one,two = bezmisc.beziersplitatt(bez,tees[0]) two,three = bezmisc.beziersplitatt(two,tees[1]) segments.append([cmd,list(one[1]+one[2]+one[3])]) segments.append([cmd,list(two[1]+two[2]+two[3])]) segments.append([cmd,list(three[1]+three[2]+three[3])]) for seg in segments: self.makeface(last,seg) last = seg[1][-2:] if cmd == 'M': subPathStart = params[-2:] if cmd == 'Z': last = subPathStart else: last = params[-2:]
def effect(self): self.vx = math.cos(math.radians(self.options.angle))*self.options.magnitude self.vy = math.sin(math.radians(self.options.angle))*self.options.magnitude for id, node in self.selected.iteritems(): if node.tag == inkex.addNS('path','svg'): group = inkex.etree.SubElement(node.getparent(),inkex.addNS('g','svg')) self.facegroup = inkex.etree.SubElement(group, inkex.addNS('g','svg')) group.append(node) t = node.get('transform') if t: group.set('transform', t) node.set('transform','') s = node.get('style') self.facegroup.set('style', s) p = simplepath.parsePath(node.get('d')) for cmd,params in p: tees = [] if cmd == 'C': bez = (last,params[:2],params[2:4],params[-2:]) tees = [t for t in bezmisc.beziertatslope(bez,(self.vy,self.vx)) if 0<t<1] tees.sort() segments = [] if len(tees) == 0 and cmd in ['L','C']: segments.append([cmd,params[:]]) elif len(tees) == 1: one,two = bezmisc.beziersplitatt(bez,tees[0]) segments.append([cmd,list(one[1]+one[2]+one[3])]) segments.append([cmd,list(two[1]+two[2]+two[3])]) elif len(tees) == 2: one,two = bezmisc.beziersplitatt(bez,tees[0]) two,three = bezmisc.beziersplitatt(two,tees[1]) segments.append([cmd,list(one[1]+one[2]+one[3])]) segments.append([cmd,list(two[1]+two[2]+two[3])]) segments.append([cmd,list(three[1]+three[2]+three[3])]) for seg in segments: self.makeface(last,seg) last = seg[1][-2:] if cmd == 'M': subPathStart = params[-2:] if cmd == 'Z': last = subPathStart else: last = params[-2:]
def linearize(p, tolerance=0.001): ''' This function receives a component of a 'cubicsuperpath' and returns two things: The path subdivided in many straight segments, and an array containing the length of each segment. We could work with bezier path as well, but bezier arc lengths are (re)computed for each point in the deformed object. For complex paths, this might take a while. ''' zero = 0.000001 i = 0 d = 0 lengths = [] while i < len(p) - 1: box = bezmisc.pointdistance(p[i][1], p[i][2]) box += bezmisc.pointdistance(p[i][2], p[i + 1][0]) box += bezmisc.pointdistance(p[i + 1][0], p[i + 1][1]) chord = bezmisc.pointdistance(p[i][1], p[i + 1][1]) if (box - chord) > tolerance: b1, b2 = bezmisc.beziersplitatt( [p[i][1], p[i][2], p[i + 1][0], p[i + 1][1]], 0.5) p[i][2][0], p[i][2][1] = b1[1] p[i + 1][0][0], p[i + 1][0][1] = b2[2] p.insert(i + 1, [[b1[2][0], b1[2][1]], [b1[3][0], b1[3][1]], [b2[1][0], b2[1][1]]]) else: d = (box + chord) / 2 lengths.append(d) i += 1 new = [p[i][1] for i in range(0, len(p) - 1) if lengths[i] > zero] new.append(p[-1][1]) lengths = [l for l in lengths if l > zero] return (new, lengths)
def subdivideCubicPath( sp, flat, i=1 ): """ Break up a bezier curve into smaller curves, each of which is approximately a straight line within a given tolerance (the "smoothness" defined by [flat]). This is a modified version of cspsubdiv.cspsubdiv() rewritten to avoid recurrence. """ while True: while True: if i >= len( sp ): return p0 = sp[i - 1][1] p1 = sp[i - 1][2] p2 = sp[i][0] p3 = sp[i][1] b = ( p0, p1, p2, p3 ) if cspsubdiv.maxdist( b ) > flat: break i += 1 one, two = bezmisc.beziersplitatt( b, 0.5 ) sp[i - 1][2] = one[1] sp[i][0] = two[2] p = [one[2], one[3], two[1]] sp[i:1] = [p]
def subdivideCubicPath(sp, flat, i=1): ''' [ Lifted from eggbot.py with impunity ] Break up a bezier curve into smaller curves, each of which is approximately a straight line within a given tolerance (the "smoothness" defined by [flat]). This is a modified version of cspsubdiv.cspsubdiv(): rewritten because recursion-depth errors on complicated line segments could occur with cspsubdiv.cspsubdiv(). ''' while True: while True: if i >= len(sp): return p0 = sp[i - 1][1] p1 = sp[i - 1][2] p2 = sp[i][0] p3 = sp[i][1] b = (p0, p1, p2, p3) if cspsubdiv.maxdist(b) > flat: break i += 1 one, two = bezmisc.beziersplitatt(b, 0.5) sp[i - 1][2] = one[1] sp[i][0] = two[2] p = [one[2], one[3], two[1]] sp[i:1] = [p]
def subdivideCubicPath(sp, flat, i=1): """ [ Lifted from eggbot.py with impunity ] Break up a bezier curve into smaller curves, each of which is approximately a straight line within a given tolerance (the "smoothness" defined by [flat]). This is a modified version of cspsubdiv.cspsubdiv(): rewritten because recursion-depth errors on complicated line segments could occur with cspsubdiv.cspsubdiv(). """ while True: while True: if i >= len(sp): return p0 = sp[i - 1][1] p1 = sp[i - 1][2] p2 = sp[i][0] p3 = sp[i][1] b = (p0, p1, p2, p3) if cspsubdiv.maxdist(b) > flat: break i += 1 one, two = bezmisc.beziersplitatt(b, 0.5) sp[i - 1][2] = one[1] sp[i][0] = two[2] p = [one[2], one[3], two[1]] sp[i:1] = [p]
def subdivideCubicPath(sp, flat, i=1): """ Break up a bezier curve into smaller curves, each of which is approximately a straight line within a given tolerance (the "smoothness" defined by [flat]). This is a modified version of cspsubdiv.cspsubdiv(). From Openscad plugins """ while True: while True: if i >= len(sp): return p0 = sp[i - 1][1] p1 = sp[i - 1][2] p2 = sp[i][0] p3 = sp[i][1] b = (p0, p1, p2, p3) if cspsubdiv.maxdist(b) > flat: break i += 1 one, two = bezmisc.beziersplitatt(b, 0.5) sp[i - 1][2] = one[1] sp[i][0] = two[2] p = [one[2], one[3], two[1]] sp[i:1] = [p]
def subdivide_cubic_path(sp, flat, i=1): """ Break up a bezier curve into smaller curves, each of which is approximately a straight line within a given tolerance (the "smoothness" defined by [flat]). This is a modified version of cspsubdiv.cspsubdiv(). I rewrote the recursive call because it caused recursion-depth errors on complicated line segments. """ b = None while True: while True: if i >= len( sp ): return p0 = sp[i - 1][1] p1 = sp[i - 1][2] p2 = sp[i][0] p3 = sp[i][1] b = ( p0, p1, p2, p3 ) if cspsubdiv.maxdist( b ) > flat: break i += 1 if b is not None: one, two = beziersplitatt( b, 0.5 ) sp[i - 1][2] = one[1] sp[i][0] = two[2] p = [one[2], one[3], two[1]] sp[i:1] = [p]
def linearize(p,tolerance=0.001): ''' This function receives a component of a 'cubicsuperpath' and returns two things: The path subdivided in many straight segments, and an array containing the length of each segment. We could work with bezier path as well, but bezier arc lengths are (re)computed for each point in the deformed object. For complex paths, this might take a while. ''' zero=0.000001 i=0 d=0 lengths=[] while i<len(p)-1: box = bezmisc.pointdistance(p[i ][1],p[i ][2]) box += bezmisc.pointdistance(p[i ][2],p[i+1][0]) box += bezmisc.pointdistance(p[i+1][0],p[i+1][1]) chord = bezmisc.pointdistance(p[i][1], p[i+1][1]) if (box - chord) > tolerance: b1, b2 = bezmisc.beziersplitatt([p[i][1],p[i][2],p[i+1][0],p[i+1][1]], 0.5) p[i ][2][0],p[i ][2][1]=b1[1] p[i+1][0][0],p[i+1][0][1]=b2[2] p.insert(i+1,[[b1[2][0],b1[2][1]],[b1[3][0],b1[3][1]],[b2[1][0],b2[1][1]]]) else: d=(box+chord)/2 lengths.append(d) i+=1 new=[p[i][1] for i in range(0,len(p)-1) if lengths[i]>zero] new.append(p[-1][1]) lengths=[l for l in lengths if l>zero] return(new,lengths)
def split(self, t=0.5): (((p0x, p0y), (p1x, p1y), (p2x, p2y), (pnx, pny)), ((q1x, q1y), (q2x, q2y), (q3x, q3y), (q4x, q4y))) = beziersplitatt( ((self.p0.x, self.p0.y), (self.p1.x, self.p1.y), (self.p2.x, self.p2.y), (self.pn.x, self.pn.y)), t) return CubicBezier.fromCoords(p0x, p0y, p1x, p1y, p2x, p2y, pnx, pny), CubicBezier.fromCoords( q1x, q1y, q2x, q2y, q3x, q3y, q4x, q4y)
def cspbezsplit(sp1, sp2, t = 0.5): s1,s2 = bezmisc.beziersplitatt((sp1[1],sp1[2],sp2[0],sp2[1]),t) return [ [sp1[0][:], sp1[1][:], list(s1[1])], [list(s1[2]), list(s1[3]), list(s2[1])], [list(s2[2]), sp2[1][:], sp2[2][:]] ]
def split(self,t=0.5): (((p0x,p0y),(p1x,p1y),(p2x,p2y),(pnx,pny)), ((q1x,q1y),(q2x,q2y),(q3x,q3y),(q4x,q4y))) = beziersplitatt( ((self.p0.x,self.p0.y), (self.p1.x,self.p1.y),(self.p2.x,self.p2.y),(self.pn.x,self.pn.y)), t) return CubicBezier.fromCoords(p0x,p0y,p1x,p1y,p2x,p2y,pnx,pny),CubicBezier.fromCoords(q1x,q1y,q2x,q2y,q3x,q3y,q4x,q4y)
def cspbezsplit(sp1, sp2, t=0.5): s1, s2 = bezmisc.beziersplitatt((sp1[1], sp1[2], sp2[0], sp2[1]), t) return [[sp1[0][:], sp1[1][:], list(s1[1])], [list(s1[2]), list(s1[3]), list(s2[1])], [list(s2[2]), sp2[1][:], sp2[2][:]]]
def splitAtT(seg, t): if (ver == 1.0): return bezier.beziersplitatt((seg[0], seg[1], seg[2], seg[3]), t) else: return bezmisc.beziersplitatt((seg[0], seg[1], seg[2], seg[3]), t)