removed "Ofsplot" and "boundingbox" due to unresolved license status, re-added "netting" and "scatter"
This commit is contained in:
parent
3f8da06b73
commit
bfe8c6b7a6
5
extensions/desktop.ini
Normal file
5
extensions/desktop.ini
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[LocalizedFileNames]
|
||||||
|
fablabchemnitz_scatter.inx=@fablabchemnitz_scatter.inx,0
|
||||||
|
fablabchemnitz_scatter.py=@fablabchemnitz_scatter.py,0
|
||||||
|
fablabchemnitz_netting.inx=@fablabchemnitz_netting.inx,0
|
||||||
|
fablabchemnitz_netting.py=@fablabchemnitz_netting.py,0
|
@ -1,58 +0,0 @@
|
|||||||
#!/usr/bin/env python2
|
|
||||||
|
|
||||||
import sys
|
|
||||||
sys.path.append('/usr/share/inkscape/extensions')
|
|
||||||
|
|
||||||
from collections import defaultdict
|
|
||||||
|
|
||||||
from inkex import Effect as InkscapeEffect
|
|
||||||
from inkex import etree, addNS
|
|
||||||
|
|
||||||
from simpletransform import computeBBox, applyTransformToNode
|
|
||||||
from simplestyle import formatStyle
|
|
||||||
from simplepath import parsePath, translatePath, formatPath
|
|
||||||
|
|
||||||
class DrawBBoxes(InkscapeEffect):
|
|
||||||
def __init__(self):
|
|
||||||
InkscapeEffect.__init__(self)
|
|
||||||
self.filename = sys.argv[-1]
|
|
||||||
|
|
||||||
def effect(self):
|
|
||||||
if len(self.selected) > 0:
|
|
||||||
bboxes = self.calculate_bboxes(self.selected)
|
|
||||||
for id, node, bbox in bboxes:
|
|
||||||
self.draw_bbox(bbox)
|
|
||||||
|
|
||||||
def calculate_bboxes(self, nodes):
|
|
||||||
bboxes = [(id, node, computeBBox([node]))
|
|
||||||
for id, node in nodes.items()]
|
|
||||||
|
|
||||||
return bboxes
|
|
||||||
|
|
||||||
def draw_bbox(self, bbox):
|
|
||||||
(x1, x2, y1, y2) = bbox
|
|
||||||
width = x2 - x1
|
|
||||||
height = y2 - y1
|
|
||||||
self.draw_rect(x1, y1, width, height)
|
|
||||||
|
|
||||||
#SVG element generation routine
|
|
||||||
def draw_rect(self, x, y, width, height):
|
|
||||||
layer = self.current_layer
|
|
||||||
|
|
||||||
style = { 'stroke' : '#ff0000',
|
|
||||||
'stroke-width' : '1',
|
|
||||||
'fill' : 'none',
|
|
||||||
}
|
|
||||||
|
|
||||||
attribs = {
|
|
||||||
'style' : formatStyle(style),
|
|
||||||
'x' : str(x),
|
|
||||||
'y' : str(y),
|
|
||||||
'width' : str(width),
|
|
||||||
'height' : str(height),
|
|
||||||
}
|
|
||||||
|
|
||||||
rect = etree.SubElement(layer, addNS('rect','svg'), attribs )
|
|
||||||
|
|
||||||
effect = DrawBBoxes()
|
|
||||||
effect.affect()
|
|
@ -1,12 +1,13 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||||
<_name>Bounding Box</_name>
|
<_name>Netting</_name>
|
||||||
<id>fablabchemnitz.de.boundingbox</id>
|
<id>fablabchemnitz.de.netting</id>
|
||||||
|
<dependency type="executable" location="extensions">fablabchemnitz_netting.py</dependency>
|
||||||
<dependency type="executable" location="extensions">inkex.py</dependency>
|
<dependency type="executable" location="extensions">inkex.py</dependency>
|
||||||
<dependency type="executable" location="extensions">fablabchemnitz_boundingbox.py</dependency>
|
<_param name="title" type="description">This effect net in the a path alternately.</_param>
|
||||||
<param name="help_text" type="description">Draws bounding boxes around selected objects, useful for debugging. Author: Pawel Mosakowski</param>
|
<param name="s_width" type="float" _gui-text="Stroke Width, px">1.0</param>
|
||||||
<effect>
|
<effect>
|
||||||
<object-type>all</object-type>
|
<object-type>path</object-type>
|
||||||
<effects-menu>
|
<effects-menu>
|
||||||
<submenu _name="FabLab Chemnitz">
|
<submenu _name="FabLab Chemnitz">
|
||||||
<submenu _name="Shape/Pattern from existing Path(s)" />
|
<submenu _name="Shape/Pattern from existing Path(s)" />
|
||||||
@ -14,6 +15,6 @@
|
|||||||
</effects-menu>
|
</effects-menu>
|
||||||
</effect>
|
</effect>
|
||||||
<script>
|
<script>
|
||||||
<command reldir="extensions" interpreter="python">fablabchemnitz_boundingbox.py</command>
|
<command reldir="extensions" interpreter="python">fablabchemnitz_netting.py</command>
|
||||||
</script>
|
</script>
|
||||||
</inkscape-extension>
|
</inkscape-extension>
|
63
extensions/fablabchemnitz_netting.py
Normal file
63
extensions/fablabchemnitz_netting.py
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
'''
|
||||||
|
netting.py
|
||||||
|
Sunabe kazumichi 2010/3/4
|
||||||
|
http://dp48069596.lolipop.jp/
|
||||||
|
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
this program nets in the line.
|
||||||
|
'''
|
||||||
|
import random, math, inkex, simplestyle, cubicsuperpath
|
||||||
|
|
||||||
|
|
||||||
|
class RadiusRandomize(inkex.Effect):
|
||||||
|
def __init__(self):
|
||||||
|
inkex.Effect.__init__(self)
|
||||||
|
self.OptionParser.add_option("-w", "--s_width",
|
||||||
|
action="store", type="float",
|
||||||
|
dest="s_width", default=1.0,
|
||||||
|
help="atrke width")
|
||||||
|
self.OptionParser.add_option("--title")
|
||||||
|
|
||||||
|
def effect(self):
|
||||||
|
path_strings = []
|
||||||
|
net_strings= ["M"]
|
||||||
|
my_path = inkex.etree.Element(inkex.addNS('path','svg'))
|
||||||
|
s = {'stroke-width': self.options.s_width, 'stroke': '#000000', 'fill': 'none' }
|
||||||
|
my_path.set('style', simplestyle.formatStyle(s))
|
||||||
|
for id, node in self.selected.iteritems():
|
||||||
|
if node.tag == inkex.addNS('path','svg'):
|
||||||
|
d = node.get('d')
|
||||||
|
p = cubicsuperpath.parsePath(d)
|
||||||
|
for subpath in p:
|
||||||
|
for i, csp in enumerate(subpath):
|
||||||
|
path_strings.append("%f,%f" % ( csp[1][0], csp[1][1]))
|
||||||
|
node.set('d',cubicsuperpath.formatPath(p))
|
||||||
|
|
||||||
|
while len(path_strings)>0 :
|
||||||
|
net_strings.append(path_strings.pop(0))
|
||||||
|
if len(path_strings)>0 :
|
||||||
|
net_strings.append(path_strings.pop())
|
||||||
|
my_path.set('d', " ".join(net_strings))
|
||||||
|
self.current_layer.append( my_path )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
e = RadiusRandomize()
|
||||||
|
e.affect()
|
||||||
|
|
@ -1,23 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
|
||||||
<_name>Ofsplot (Offset Paths)</_name>
|
|
||||||
<id>fablabchemnitz.de.ofsplot</id>
|
|
||||||
<dependency type="executable" location="extensions">fablabchemnitz_ofsplot.py</dependency>
|
|
||||||
<param name="count" type="int" min="0" max="100000" _gui-text="Number of offset paths:">10</param>
|
|
||||||
<param name="ofs" type="float" min="-1000" max="+1000" _gui-text="Offset between two paths:">0.8</param>
|
|
||||||
<param name="init_ofs" type="float" min="-1000" max="+1000" _gui-text="Initial offset from original path:">0.8</param>
|
|
||||||
<param name="copy_org" type="boolean" _gui-text="Copy original path (=keep it)">0</param>
|
|
||||||
<param name="ofs_incr" type="float" min="-1000" max="+1000" _gui-text="Offset increase per iteration:">0.8</param>
|
|
||||||
<_param name="settingsHelp" type="description">Python library pyclipper needs to be installed. Use Flatten Bezier plugin in advance of this plugin.</_param>
|
|
||||||
<effect>
|
|
||||||
<object-type>all</object-type>
|
|
||||||
<effects-menu>
|
|
||||||
<submenu _name="FabLab Chemnitz">
|
|
||||||
<submenu _name="Shape/Pattern from existing Path(s)"/>
|
|
||||||
</submenu>
|
|
||||||
</effects-menu>
|
|
||||||
</effect>
|
|
||||||
<script>
|
|
||||||
<command reldir="extensions" interpreter="python">fablabchemnitz_ofsplot.py</command>
|
|
||||||
</script>
|
|
||||||
</inkscape-extension>
|
|
@ -1,111 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import inkex
|
|
||||||
import cubicsuperpath, simplestyle, copy, math, re, bezmisc, simplepath
|
|
||||||
import pyclipper
|
|
||||||
import sys
|
|
||||||
|
|
||||||
def eprint(*args, **kwargs):
|
|
||||||
print(*args, file=sys.stderr, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ofsplot(inkex.Effect):
|
|
||||||
def __init__(self):
|
|
||||||
inkex.Effect.__init__(self)
|
|
||||||
self.OptionParser.add_option("--count",
|
|
||||||
action="store", type="int",
|
|
||||||
dest="count", default=10,
|
|
||||||
help="Number of offset operations")
|
|
||||||
self.OptionParser.add_option("--ofs",
|
|
||||||
action="store", type="float",
|
|
||||||
dest="offset", default=2,
|
|
||||||
help="Offset amount")
|
|
||||||
self.OptionParser.add_option("--init_ofs",
|
|
||||||
action="store", type="float",
|
|
||||||
dest="init_offset", default=2,
|
|
||||||
help="Initial Offset Amount")
|
|
||||||
self.OptionParser.add_option("--copy_org",
|
|
||||||
action="store", type="inkbool",
|
|
||||||
dest="copy_org", default=True,
|
|
||||||
help="copy original path")
|
|
||||||
self.OptionParser.add_option("--ofs_incr",
|
|
||||||
action="store", type="float",
|
|
||||||
dest="offset_increase", default=2,
|
|
||||||
help="Offset increase between iterations")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def effect(self):
|
|
||||||
|
|
||||||
for id, node in self.selected.iteritems():
|
|
||||||
if node.tag == inkex.addNS('path','svg'):
|
|
||||||
p = cubicsuperpath.parsePath(node.get('d'))
|
|
||||||
|
|
||||||
scale_factor=5.0
|
|
||||||
|
|
||||||
|
|
||||||
pco = pyclipper.PyclipperOffset()
|
|
||||||
|
|
||||||
new = []
|
|
||||||
|
|
||||||
|
|
||||||
# load in initial paths
|
|
||||||
for sub in p:
|
|
||||||
sub_simple = []
|
|
||||||
h1_simple = []
|
|
||||||
h2_simple = []
|
|
||||||
for item in sub:
|
|
||||||
itemx = [float(z)*scale_factor for z in item[1]]
|
|
||||||
sub_simple.append(itemx)
|
|
||||||
#eprint(itemx)
|
|
||||||
#h1_simple.append(item[0]-item[1]) # handle 1 offset
|
|
||||||
#h2_simple.append(item[2]-item[1]) # handle 2 offset
|
|
||||||
|
|
||||||
pco.AddPath(sub_simple, pyclipper.JT_ROUND, pyclipper.ET_CLOSEDPOLYGON)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# calculate offset paths for different offset amounts
|
|
||||||
offset_list = []
|
|
||||||
offset_list.append(self.options.init_offset)
|
|
||||||
for i in range(0,self.options.count+1):
|
|
||||||
ofs_inc = +math.pow(float(i)*self.options.offset_increase,2)
|
|
||||||
if self.options.offset_increase <0:
|
|
||||||
ofs_inc = -ofs_inc
|
|
||||||
offset_list.append(offset_list[0]+float(i)*self.options.offset+ofs_inc)
|
|
||||||
|
|
||||||
|
|
||||||
solutions = []
|
|
||||||
for offset in offset_list:
|
|
||||||
solution = pco.Execute(offset*scale_factor)
|
|
||||||
solutions.append(solution)
|
|
||||||
if len(solution)<=0:
|
|
||||||
continue # no more loops to go, will provide no results.
|
|
||||||
|
|
||||||
|
|
||||||
# re-arrange solutions to fit expected format & add to array
|
|
||||||
for solution in solutions:
|
|
||||||
for sol in solution:
|
|
||||||
solx = [[float(s[0])/scale_factor, float(s[1])/scale_factor] for s in sol]
|
|
||||||
sol_p = [[a,a,a] for a in solx]
|
|
||||||
sol_p.append(sol_p[0][:])
|
|
||||||
new.append(sol_p)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# add old, just to keep (make optional!)
|
|
||||||
if self.options.copy_org:
|
|
||||||
for sub in p:
|
|
||||||
new.append(sub)
|
|
||||||
|
|
||||||
node.set('d',cubicsuperpath.formatPath(new))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
e = ofsplot()
|
|
||||||
e.affect()
|
|
||||||
|
|
24
extensions/fablabchemnitz_scatter.inx
Normal file
24
extensions/fablabchemnitz_scatter.inx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||||
|
<_name>Scatter 2</_name>
|
||||||
|
<id>fablabchemnitz.de.scatter2</id>
|
||||||
|
<dependency type="executable" location="extensions">pathmodifier.py</dependency>
|
||||||
|
<dependency type="executable" location="extensions">fablabchemnitz_scatter.py</dependency>
|
||||||
|
<dependency type="executable" location="extensions">inkex.py</dependency>
|
||||||
|
<param name="title" type="description">This effect scatters pattern objects randomly around segment points of arbitrary "skeleton" paths. The pattern is the top most object in the selection. Random_off:density=1,offset=0</param>
|
||||||
|
<param name="random" type="boolean" _gui-text="Random : off : density=1 offset=0">true</param>
|
||||||
|
<param name="density" type="float" _gui-text="Density : random only" min="1" max="100">6</param>
|
||||||
|
<param name="offset" type="float" _gui-text="Offset : random: offset area px" min="0" max="1000">3</param>
|
||||||
|
<param name="scale" type="float" _gui-text="Scale : random:from value to 100%" min="1" max="100">20.0</param>
|
||||||
|
<param name="rotation" type="float" _gui-text="Rotation : random: from -30 to 30 dgree" min="-30" max="30">20.0</param>
|
||||||
|
<effect>
|
||||||
|
<effects-menu>
|
||||||
|
<submenu _name="FabLab Chemnitz">
|
||||||
|
<submenu _name="Shape/Pattern from existing Path(s)"/>
|
||||||
|
</submenu>
|
||||||
|
</effects-menu>
|
||||||
|
</effect>
|
||||||
|
<script>
|
||||||
|
<command reldir="extensions" interpreter="python">fablabchemnitz_scatter.py</command>
|
||||||
|
</script>
|
||||||
|
</inkscape-extension>
|
140
extensions/fablabchemnitz_scatter.py
Normal file
140
extensions/fablabchemnitz_scatter.py
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
'''
|
||||||
|
scatter.py
|
||||||
|
Sunabe kazumichi 2009/9/29
|
||||||
|
http://dp48069596.lolipop.jp/
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
|
||||||
|
attention:when rotation degree become large, patterns are deformed largely.
|
||||||
|
therefore,restricted the rotation in range -30<deg<30.
|
||||||
|
|
||||||
|
'''
|
||||||
|
import inkex, cubicsuperpath, bezmisc
|
||||||
|
import pathmodifier,simpletransform
|
||||||
|
import copy, math, re, random
|
||||||
|
|
||||||
|
def translate(pathcomp,dx,dy):
|
||||||
|
for ctl in pathcomp:
|
||||||
|
for pt in ctl:
|
||||||
|
pt[0]+=dx
|
||||||
|
pt[1]+=dy
|
||||||
|
|
||||||
|
def scale(pathcomp,scale,org):
|
||||||
|
for ctl in pathcomp:
|
||||||
|
for pt in ctl:
|
||||||
|
pt[0]=org[0]+(pt[0]-org[0])*scale
|
||||||
|
pt[1]=org[1]+(pt[1]-org[1])*scale
|
||||||
|
|
||||||
|
def rotate(pathcomp,angle):
|
||||||
|
for ctl in pathcomp:
|
||||||
|
for pt in ctl:
|
||||||
|
pt[0]=pt[0]*math.cos(angle)-pt[1]*math.sin(angle)
|
||||||
|
pt[1]=pt[0]*math.sin(angle)+pt[1]*math.cos(angle)
|
||||||
|
|
||||||
|
class ScatterAlongPath(pathmodifier.Diffeo):
|
||||||
|
def __init__(self):
|
||||||
|
pathmodifier.Diffeo.__init__(self)
|
||||||
|
self.OptionParser.add_option("--title")
|
||||||
|
self.OptionParser.add_option("-r", "--random",
|
||||||
|
action="store", type="inkbool",
|
||||||
|
dest="random", default=True,
|
||||||
|
help="random pattern on the skeleton")
|
||||||
|
self.OptionParser.add_option("-d", "--density",
|
||||||
|
action="store", type="int",
|
||||||
|
dest="density", default=3)
|
||||||
|
self.OptionParser.add_option("-o", "--offset",
|
||||||
|
action="store", type="float",
|
||||||
|
dest="offset", default=0.0, help="offset")
|
||||||
|
self.OptionParser.add_option("-s", "--scale",
|
||||||
|
action="store", type="float",
|
||||||
|
dest="scale", default=100, help="scale")
|
||||||
|
self.OptionParser.add_option("-p", "--rotation",
|
||||||
|
action="store", type="float",
|
||||||
|
dest="rotation", default=0,
|
||||||
|
help="rotation pattern on the skeleton")
|
||||||
|
|
||||||
|
def prepareSelectionList(self):
|
||||||
|
idList=self.options.ids
|
||||||
|
idList=pathmodifier.zSort(self.document.getroot(),idList)
|
||||||
|
id = idList[-1]
|
||||||
|
self.patterns={id:self.selected[id]}
|
||||||
|
self.patterns=self.duplicateNodes(self.patterns)
|
||||||
|
self.expandGroupsUnlinkClones(self.patterns, True, True)
|
||||||
|
self.objectsToPaths(self.patterns)
|
||||||
|
del self.selected[id]
|
||||||
|
self.skeletons=self.selected
|
||||||
|
self.expandGroupsUnlinkClones(self.skeletons, True, False)
|
||||||
|
self.objectsToPaths(self.skeletons)
|
||||||
|
|
||||||
|
def effect(self):
|
||||||
|
if len(self.options.ids)<2:
|
||||||
|
inkex.debug("This extension requires that you select two paths.")
|
||||||
|
return
|
||||||
|
self.prepareSelectionList()
|
||||||
|
bbox=simpletransform.computeBBox(self.patterns.values())
|
||||||
|
for id, node in self.patterns.iteritems():
|
||||||
|
if node.tag == inkex.addNS('path','svg') or node.tag=='path':
|
||||||
|
d = node.get('d')
|
||||||
|
p0 = cubicsuperpath.parsePath(d)
|
||||||
|
newp=[]
|
||||||
|
for skelnode in self.skeletons.itervalues():
|
||||||
|
self.curSekeleton=cubicsuperpath.parsePath(skelnode.get('d'))
|
||||||
|
den=1
|
||||||
|
while den <= self.options.density:
|
||||||
|
for comp in self.curSekeleton:
|
||||||
|
p=copy.deepcopy(p0)
|
||||||
|
if self.options.random:
|
||||||
|
xoffset=-bbox[0]-(bbox[1]-bbox[0])/2+random.uniform(-self.options.offset, self.options.offset)
|
||||||
|
yoffset=-(bbox[2]+bbox[3])/2-random.uniform(-self.options.offset, self.options.offset)
|
||||||
|
else:
|
||||||
|
self.options.density=1
|
||||||
|
self.options.offset=0
|
||||||
|
xoffset=-bbox[0]-(bbox[1]-bbox[0])/2+self.options.offset
|
||||||
|
yoffset=-(bbox[2]+bbox[3])/2-self.options.offset
|
||||||
|
|
||||||
|
NbCopies=len(comp)
|
||||||
|
new=[]
|
||||||
|
for sub in p:
|
||||||
|
for i in range(0,NbCopies,1):
|
||||||
|
new.append(copy.deepcopy(sub))
|
||||||
|
p=new
|
||||||
|
for sub in p:
|
||||||
|
translate(sub,xoffset,yoffset)
|
||||||
|
for sub in p:
|
||||||
|
if self.options.random:
|
||||||
|
scale(sub,random.uniform(self.options.scale, 100)/100,(0,0))
|
||||||
|
else:
|
||||||
|
scale(sub,self.options.scale/100,(0,0))
|
||||||
|
for sub in p:
|
||||||
|
if self.options.random:
|
||||||
|
rotate(sub,random.uniform(-self.options.rotation*math.pi/180, self.options.rotation*math.pi/180))
|
||||||
|
else:
|
||||||
|
rotate(sub,self.options.rotation*math.pi/180)
|
||||||
|
for i,sub in enumerate(p):
|
||||||
|
try:
|
||||||
|
translate(sub,comp[i][1][0],comp[i][1][1])
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
newp+=p
|
||||||
|
den+=1
|
||||||
|
|
||||||
|
|
||||||
|
node.set('d', cubicsuperpath.formatPath(newp))
|
||||||
|
e = ScatterAlongPath()
|
||||||
|
e.affect()
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user