removed "Ofsplot" and "boundingbox" due to unresolved license status, re-added "netting" and "scatter"

This commit is contained in:
Mario Voigt 2019-12-23 01:56:48 +01:00
parent 3f8da06b73
commit bfe8c6b7a6
8 changed files with 239 additions and 198 deletions

5
extensions/desktop.ini Normal file
View 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

View File

@ -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()

View File

@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<_name>Bounding Box</_name>
<id>fablabchemnitz.de.boundingbox</id>
<_name>Netting</_name>
<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">fablabchemnitz_boundingbox.py</dependency>
<param name="help_text" type="description">Draws bounding boxes around selected objects, useful for debugging. Author: Pawel Mosakowski</param>
<_param name="title" type="description">This effect net in the a path alternately.</_param>
<param name="s_width" type="float" _gui-text="Stroke Width, px">1.0</param>
<effect>
<object-type>all</object-type>
<object-type>path</object-type>
<effects-menu>
<submenu _name="FabLab Chemnitz">
<submenu _name="Shape/Pattern from existing Path(s)" />
@ -14,6 +15,6 @@
</effects-menu>
</effect>
<script>
<command reldir="extensions" interpreter="python">fablabchemnitz_boundingbox.py</command>
<command reldir="extensions" interpreter="python">fablabchemnitz_netting.py</command>
</script>
</inkscape-extension>

View 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()

View File

@ -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>

View File

@ -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()

View 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>

View 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()