added collar
This commit is contained in:
parent
b4cd212908
commit
21ba44021a
2
extensions/fablabchemnitz/collar/.gitattributes
vendored
Normal file
2
extensions/fablabchemnitz/collar/.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
48
extensions/fablabchemnitz/collar/collar.inx
Normal file
48
extensions/fablabchemnitz/collar/collar.inx
Normal file
@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>Collar</name>
|
||||
<id>fablabchemnitz.de.collar</id>
|
||||
<param name="usermenu" type="notebook">
|
||||
<page name="settings" gui-text="Settings">
|
||||
<label appearance="header">General</label>
|
||||
<param name="polysides" type="int" min="3" max="360" gui-text="Number of Polygon Sides:">6</param>
|
||||
<param name="poly1size" type="float" min="0.2" max="9999.0" gui-text="Size of Polygon 1 (in Dimensional Units):">5.0</param>
|
||||
<param name="poly2size" type="float" min="0.2" max="9999.0" gui-text="Size of Polygon 2 (in Dimensional Units):">3.0</param>
|
||||
<param name="collarheight" type="float" min="0.2" max="9999.0" gui-text="Height of Collar (in Dimensional Units):">5.0</param>
|
||||
<param name="collarparts" type="int" min="1" max="10" gui-text="Number of parts to divide collar into:">1</param>
|
||||
<param name="tabangle" type="float" min="0.0" max="90.0" gui-text="Angle of tab edges (degrees):">45.0</param>
|
||||
<param name="tabheight" type="float" min="0.01" max="9999.0" gui-text="Height of tab (in Dimensional Units):">0.4</param>
|
||||
<param name="dashlength" type="float" precision="3" min="0.0" max="9999.0" gui-text="Length of dashline(zero for solid line) (in Dimensional Units):">0.1</param>
|
||||
<param name="unit" type="optiongroup" appearance="combo" gui-text="Dimensional units:">
|
||||
<option value="mm">mm</option>
|
||||
<option value="cm">cm</option>
|
||||
<option value="m">m</option>
|
||||
<option value="km">km</option>
|
||||
<option value="px">px</option>
|
||||
<option value="pt">pt</option>
|
||||
<option value="in">in</option>
|
||||
<option value="ft">ft</option>
|
||||
<option value="yd">yd</option>
|
||||
</param>
|
||||
<label appearance="header">Styles</label>
|
||||
<param name="generate_decorative_wrapper" type="bool" gui-text="Generate decorative wrapper">false</param>
|
||||
<param name="cosmetic_dash_style" type="bool" gui-text="Cosmetic dash lines" gui-description="If entered dash line length is zero we can apply some cosmetic style only">false</param>
|
||||
<param name="color_solid" type="color" appearance="colorbutton" gui-text="Solid line color">4278190335</param>
|
||||
<param name="color_dash" type="color" appearance="colorbutton" gui-text="Dash line color">65535</param>
|
||||
</page>
|
||||
<page name="help" gui-text="Help">
|
||||
<label xml:space="preserve">Given the number of sides and sizes of two polygons, this program generates (1) a paper model of a collar with tabs to assemble between the polygons; (2) the two polygons themselves; and (3) strips for covering the tabbed collar. You can also specify certain tab parameters, but be aware that the program might adjust them to avoid problems.</label>
|
||||
</page>
|
||||
</param>
|
||||
<effect needs-live-preview="true">
|
||||
<object-type>all</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="FabLab Chemnitz">
|
||||
<submenu name="Paper/Cardboard Boxes"/>
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command location="inx" interpreter="python">collar.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
753
extensions/fablabchemnitz/collar/collar.py
Normal file
753
extensions/fablabchemnitz/collar/collar.py
Normal file
@ -0,0 +1,753 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (C) [2021] [Joseph Zakar], [observing@gmail.com]
|
||||
#
|
||||
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
"""
|
||||
Given a set of parameters for two polygons, this program generates paper
|
||||
models of (1) the two polygons; (2) a collar (divided into segments if desired)
|
||||
represented by a strip with tabs and score lines; and (3) wrapper(s) for
|
||||
covering the tabbed strip(s).
|
||||
"""
|
||||
|
||||
import inkex
|
||||
from inkex import Color
|
||||
import math
|
||||
import copy
|
||||
|
||||
class pathStruct(object):
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.id="path0000"
|
||||
self.path=[]
|
||||
self.enclosed=False
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return self.path
|
||||
|
||||
class pnPoint(object):
|
||||
# This class came from https://github.com/JoJocoder/PNPOLY
|
||||
|
||||
|
||||
def __init__(self,p):
|
||||
self.p=p
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return self.p
|
||||
|
||||
|
||||
|
||||
|
||||
def InPolygon(self,polygon,BoundCheck=False):
|
||||
inside=False
|
||||
if BoundCheck:
|
||||
minX=polygon[0][0]
|
||||
maxX=polygon[0][0]
|
||||
minY=polygon[0][1]
|
||||
maxY=polygon[0][1]
|
||||
for p in polygon:
|
||||
minX=min(p[0],minX)
|
||||
maxX=max(p[0],maxX)
|
||||
minY=min(p[1],minY)
|
||||
maxY=max(p[1],maxY)
|
||||
if self.p[0]<minX or self.p[0]>maxX or self.p[1]<minY or self.p[1]>maxY:
|
||||
return False
|
||||
j=len(polygon)-1
|
||||
for i in range(len(polygon)):
|
||||
if ((polygon[i][1]>self.p[1])!=(polygon[j][1]>self.p[1]) and (self.p[0]<(polygon[j][0]-polygon[i][0])*(self.p[1]-polygon[i][1])/( polygon[j][1] - polygon[i][1] ) + polygon[i][0])):
|
||||
inside =not inside
|
||||
j=i
|
||||
return inside
|
||||
|
||||
|
||||
class Collar(inkex.EffectExtension):
|
||||
|
||||
|
||||
def add_arguments(self, pars):
|
||||
pars.add_argument("--usermenu")
|
||||
pars.add_argument("--unit", default="in",help="Dimensional units")
|
||||
pars.add_argument("--polysides", type=int, default=6,help="Number of Polygon Sides")
|
||||
pars.add_argument("--poly1size", type=float, default=5.0, help="Size of Polygon 1 in dimensional units")
|
||||
pars.add_argument("--poly2size", type=float, default=3.0, help="Size of Polygon 2 in dimensional units")
|
||||
pars.add_argument("--collarheight", type=float, default=2.0, help="Height of collar in dimensional units")
|
||||
pars.add_argument("--collarparts", type=int, default=1,help="Number of parts to divide collar into")
|
||||
pars.add_argument("--dashlength", type=float, default=0.1, help="Length of dashline in dimensional units (zero for solid line)")
|
||||
pars.add_argument("--tabangle", type=float, default=45.0, help="Angle of tab edges in degrees")
|
||||
pars.add_argument("--tabheight", type=float, default=0.4, help="Height of tab in dimensional units")
|
||||
pars.add_argument("--generate_decorative_wrapper", type=inkex.Boolean, default=False, help="Generate decorative wrapper")
|
||||
pars.add_argument("--cosmetic_dash_style", type=inkex.Boolean, default=False, help="Cosmetic dash lines")
|
||||
pars.add_argument("--color_solid", type=Color, default='4278190335', help="Solid line color")
|
||||
pars.add_argument("--color_dash", type=Color, default='65535', help="Solid line dash")
|
||||
|
||||
|
||||
#draw SVG line segment(s) between the given (raw) points
|
||||
def drawline(self, dstr, name, parent, sstr=None):
|
||||
line_style = {'stroke':self.options.color_solid,'stroke-width':'0.25','fill':'#eeeeee'}
|
||||
if sstr == None:
|
||||
stylestr = str(inkex.Style(line_style))
|
||||
else:
|
||||
stylestr = sstr
|
||||
el = parent.add(inkex.PathElement())
|
||||
el.path = dstr
|
||||
el.style = stylestr
|
||||
el.label = name
|
||||
|
||||
def makepoly(self, toplength, numpoly):
|
||||
r = toplength/(2*math.sin(math.pi/numpoly))
|
||||
pstr = ''
|
||||
for ppoint in range(0,numpoly):
|
||||
xn = r*math.cos(2*math.pi*ppoint/numpoly)
|
||||
yn = r*math.sin(2*math.pi*ppoint/numpoly)
|
||||
if ppoint == 0:
|
||||
pstr = 'M '
|
||||
else:
|
||||
pstr += ' L '
|
||||
pstr += str(xn) + ',' + str(yn)
|
||||
pstr = pstr + ' Z'
|
||||
return pstr
|
||||
|
||||
# Thanks to Gabriel Eng for his python implementation of https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
|
||||
def findIntersection(self, x1,y1,x2,y2,x3,y3,x4,y4):
|
||||
px= ( (x1*y2-y1*x2)*(x3-x4)-(x1-x2)*(x3*y4-y3*x4) ) / ( (x1-x2)*(y3-y4)-(y1-y2)*(x3-x4) )
|
||||
py= ( (x1*y2-y1*x2)*(y3-y4)-(y1-y2)*(x3*y4-y3*x4) ) / ( (x1-x2)*(y3-y4)-(y1-y2)*(x3-x4) )
|
||||
return px, py
|
||||
|
||||
def insidePath(self, path, p):
|
||||
point = pnPoint((p.x, p.y))
|
||||
pverts = []
|
||||
for pnum in path:
|
||||
pverts.append((pnum.x, pnum.y))
|
||||
isInside = point.InPolygon(pverts, True)
|
||||
return isInside # True if point p is inside path
|
||||
|
||||
def makescore(self, pt1, pt2, dashlength):
|
||||
# Draws a dashed line of dashlength between two points
|
||||
# Dash = dashlength (in inches) space followed by dashlength mark
|
||||
# if dashlength is zero, we want a solid line
|
||||
apt1 = inkex.paths.Line(0.0,0.0)
|
||||
apt2 = inkex.paths.Line(0.0,0.0)
|
||||
ddash = ''
|
||||
if math.isclose(dashlength, 0.0):
|
||||
#inkex.utils.debug("Draw solid dashline")
|
||||
ddash = ' M '+str(pt1.x)+','+str(pt1.y)+' L '+str(pt2.x)+','+str(pt2.y)
|
||||
else:
|
||||
if math.isclose(pt1.y, pt2.y):
|
||||
#inkex.utils.debug("Draw horizontal dashline")
|
||||
if pt1.x < pt2.x:
|
||||
xcushion = pt2.x - dashlength
|
||||
xpt = pt1.x
|
||||
ypt = pt1.y
|
||||
else:
|
||||
xcushion = pt1.x - dashlength
|
||||
xpt = pt2.x
|
||||
ypt = pt2.y
|
||||
ddash = ''
|
||||
done = False
|
||||
while not(done):
|
||||
if (xpt + dashlength*2) <= xcushion:
|
||||
xpt = xpt + dashlength
|
||||
ddash = ddash + ' M ' + str(xpt) + ',' + str(ypt)
|
||||
xpt = xpt + dashlength
|
||||
ddash = ddash + ' L ' + str(xpt) + ',' + str(ypt)
|
||||
else:
|
||||
done = True
|
||||
elif math.isclose(pt1.x, pt2.x):
|
||||
#inkex.utils.debug("Draw vertical dashline")
|
||||
if pt1.y < pt2.y:
|
||||
ycushion = pt2.y - dashlength
|
||||
xpt = pt1.x
|
||||
ypt = pt1.y
|
||||
else:
|
||||
ycushion = pt1.y - dashlength
|
||||
xpt = pt2.x
|
||||
ypt = pt2.y
|
||||
ddash = ''
|
||||
done = False
|
||||
while not(done):
|
||||
if(ypt + dashlength*2) <= ycushion:
|
||||
ypt = ypt + dashlength
|
||||
ddash = ddash + ' M ' + str(xpt) + ',' + str(ypt)
|
||||
ypt = ypt + dashlength
|
||||
ddash = ddash + ' L ' + str(xpt) + ',' + str(ypt)
|
||||
else:
|
||||
done = True
|
||||
else:
|
||||
#inkex.utils.debug("Draw sloping dashline")
|
||||
if pt1.y > pt2.y:
|
||||
apt1.x = pt1.x
|
||||
apt1.y = pt1.y
|
||||
apt2.x = pt2.x
|
||||
apt2.y = pt2.y
|
||||
else:
|
||||
apt1.x = pt2.x
|
||||
apt1.y = pt2.y
|
||||
apt2.x = pt1.x
|
||||
apt2.y = pt1.y
|
||||
m = (apt1.y-apt2.y)/(apt1.x-apt2.x)
|
||||
theta = math.atan(m)
|
||||
msign = (m>0) - (m<0)
|
||||
ycushion = apt2.y + dashlength*math.sin(theta)
|
||||
xcushion = apt2.x + msign*dashlength*math.cos(theta)
|
||||
ddash = ''
|
||||
xpt = apt1.x
|
||||
ypt = apt1.y
|
||||
done = False
|
||||
while not(done):
|
||||
nypt = ypt - dashlength*2*math.sin(theta)
|
||||
nxpt = xpt - msign*dashlength*2*math.cos(theta)
|
||||
if (nypt >= ycushion) and (((m<0) and (nxpt <= xcushion)) or ((m>0) and (nxpt >= xcushion))):
|
||||
# move to end of space / beginning of mark
|
||||
xpt = xpt - msign*dashlength*math.cos(theta)
|
||||
ypt = ypt - msign*dashlength*math.sin(theta)
|
||||
ddash = ddash + ' M ' + str(xpt) + ',' + str(ypt)
|
||||
# draw the mark
|
||||
xpt = xpt - msign*dashlength*math.cos(theta)
|
||||
ypt = ypt - msign*dashlength*math.sin(theta)
|
||||
ddash = ddash + ' L ' + str(xpt) + ',' + str(ypt)
|
||||
else:
|
||||
done = True
|
||||
return ddash
|
||||
|
||||
def detectIntersect(self, x1, y1, x2, y2, x3, y3, x4, y4):
|
||||
td = (x1-x2)*(y3-y4)-(y1-y2)*(x3-x4)
|
||||
if td == 0:
|
||||
# These line segments are parallel
|
||||
return False
|
||||
t = ((x1-x3)*(y3-y4)-(y1-y3)*(x3-x4))/td
|
||||
if (0.0 <= t) and (t <= 1.0):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def makeTab(self, tpath, pt1, pt2, tabht, taba):
|
||||
# tpath - the pathstructure containing pt1 and pt2
|
||||
# pt1, pt2 - the two points where the tab will be inserted
|
||||
# tabht - the height of the tab
|
||||
# taba - the angle of the tab sides
|
||||
# returns the two tab points in order of closest to pt1
|
||||
tpt1 = inkex.paths.Line(0.0,0.0)
|
||||
tpt2 = inkex.paths.Line(0.0,0.0)
|
||||
currTabHt = tabht
|
||||
currTabAngle = taba
|
||||
testAngle = 1.0
|
||||
testHt = currTabHt * 0.001
|
||||
adjustTab = 0
|
||||
tabDone = False
|
||||
while not tabDone:
|
||||
# Let's find out the orientation of the tab
|
||||
if math.isclose(pt1.x, pt2.x):
|
||||
# It's vertical. Let's try the right side
|
||||
if pt1.y < pt2.y:
|
||||
tpt1.x = pt1.x + testHt
|
||||
tpt2.x = pt2.x + testHt
|
||||
tpt1.y = pt1.y + testHt/math.tan(math.radians(testAngle))
|
||||
tpt2.y = pt2.y - testHt/math.tan(math.radians(testAngle))
|
||||
pnpt1 = inkex.paths.Move(tpt1.x, tpt1.y)
|
||||
pnpt2 = inkex.paths.Move(tpt2.x, tpt2.y)
|
||||
if ((not tpath.enclosed) and (self.insidePath(tpath.path, pnpt1) or self.insidePath(tpath.path, pnpt2))) or \
|
||||
(tpath.enclosed and ((not self.insidePath(tpath.path, pnpt1)) and (not self.insidePath(tpath.path, pnpt2)))):
|
||||
tpt1.x = pt1.x - currTabHt
|
||||
tpt2.x = pt2.x - currTabHt
|
||||
else:
|
||||
tpt1.x = pt1.x + currTabHt
|
||||
tpt2.x = pt2.x + currTabHt
|
||||
tpt1.y = pt1.y + currTabHt/math.tan(math.radians(currTabAngle))
|
||||
tpt2.y = pt2.y - currTabHt/math.tan(math.radians(currTabAngle))
|
||||
else: # pt2.y < pt1.y
|
||||
tpt1.x = pt1.x + testHt
|
||||
tpt2.x = pt2.x + testHt
|
||||
tpt1.y = pt1.y - testHt/math.tan(math.radians(testAngle))
|
||||
tpt2.y = pt2.y + testHt/math.tan(math.radians(testAngle))
|
||||
pnpt1 = inkex.paths.Move(tpt1.x, tpt1.y)
|
||||
pnpt2 = inkex.paths.Move(tpt2.x, tpt2.y)
|
||||
if ((not tpath.enclosed) and (self.insidePath(tpath.path, pnpt1) or self.insidePath(tpath.path, pnpt2))) or \
|
||||
(tpath.enclosed and ((not self.insidePath(tpath.path, pnpt1)) and (not self.insidePath(tpath.path, pnpt2)))):
|
||||
tpt1.x = pt1.x - currTabHt
|
||||
tpt2.x = pt2.x - currTabHt
|
||||
else:
|
||||
tpt1.x = pt1.x + currTabHt
|
||||
tpt2.x = pt2.x + currTabHt
|
||||
tpt1.y = pt1.y - currTabHt/math.tan(math.radians(currTabAngle))
|
||||
tpt2.y = pt2.y + currTabHt/math.tan(math.radians(currTabAngle))
|
||||
elif math.isclose(pt1.y, pt2.y):
|
||||
# It's horizontal. Let's try the top
|
||||
if pt1.x < pt2.x:
|
||||
tpt1.y = pt1.y - testHt
|
||||
tpt2.y = pt2.y - testHt
|
||||
tpt1.x = pt1.x + testHt/math.tan(math.radians(testAngle))
|
||||
tpt2.x = pt2.x - testHt/math.tan(math.radians(testAngle))
|
||||
pnpt1 = inkex.paths.Move(tpt1.x, tpt1.y)
|
||||
pnpt2 = inkex.paths.Move(tpt2.x, tpt2.y)
|
||||
if ((not tpath.enclosed) and (self.insidePath(tpath.path, pnpt1) or self.insidePath(tpath.path, pnpt2))) or \
|
||||
(tpath.enclosed and ((not self.insidePath(tpath.path, pnpt1)) and (not self.insidePath(tpath.path, pnpt2)))):
|
||||
tpt1.y = pt1.y + currTabHt
|
||||
tpt2.y = pt2.y + currTabHt
|
||||
else:
|
||||
tpt1.y = pt1.y - currTabHt
|
||||
tpt2.y = pt2.y - currTabHt
|
||||
tpt1.x = pt1.x + currTabHt/math.tan(math.radians(currTabAngle))
|
||||
tpt2.x = pt2.x - currTabHt/math.tan(math.radians(currTabAngle))
|
||||
else: # pt2.x < pt1.x
|
||||
tpt1.y = pt1.y - testHt
|
||||
tpt2.y = pt2.y - testHt
|
||||
tpt1.x = pt1.x - testHt/math.tan(math.radians(testAngle))
|
||||
tpt2.x = pt2.x + testHt/math.tan(math.radians(testAngle))
|
||||
pnpt1 = inkex.paths.Move(tpt1.x, tpt1.y)
|
||||
pnpt2 = inkex.paths.Move(tpt2.x, tpt2.y)
|
||||
if ((not tpath.enclosed) and (self.insidePath(tpath.path, pnpt1) or self.insidePath(tpath.path, pnpt2))) or \
|
||||
(tpath.enclosed and ((not self.insidePath(tpath.path, pnpt1)) and (not self.insidePath(tpath.path, pnpt2)))):
|
||||
tpt1.y = pt1.y + currTabHt
|
||||
tpt2.y = pt2.y + currTabHt
|
||||
else:
|
||||
tpt1.y = pt1.y - currTabHt
|
||||
tpt2.y = pt2.y - currTabHt
|
||||
tpt1.x = pt1.x - currTabHt/math.tan(math.radians(currTabAngle))
|
||||
tpt2.x = pt2.x + currTabHt/math.tan(math.radians(currTabAngle))
|
||||
|
||||
else: # the orientation is neither horizontal nor vertical
|
||||
# Let's get the slope of the line between the points
|
||||
# Because Inkscape's origin is in the upper-left corner,
|
||||
# a positive slope (/) will yield a negative value
|
||||
slope = (pt2.y - pt1.y)/(pt2.x - pt1.x)
|
||||
# Let's get the angle to the horizontal
|
||||
theta = math.degrees(math.atan(slope))
|
||||
# Let's construct a horizontal tab
|
||||
seglength = math.sqrt((pt1.x-pt2.x)**2 +(pt1.y-pt2.y)**2)
|
||||
if slope < 0.0:
|
||||
if pt1.x < pt2.x:
|
||||
tpt1.y = pt1.y - testHt
|
||||
tpt2.y = pt2.y - testHt
|
||||
tpt1.x = pt1.x + testHt/math.tan(math.radians(testAngle))
|
||||
tpt2.x = pt2.x - testHt/math.tan(math.radians(testAngle))
|
||||
tl1 = [('M', [pt1.x,pt1.y])]
|
||||
tl1 += [('L', [tpt1.x, tpt1.y])]
|
||||
ele1 = inkex.Path(tl1)
|
||||
tl2 = [('M', [pt1.x,pt1.y])]
|
||||
tl2 += [('L', [tpt2.x, tpt2.y])]
|
||||
ele2 = inkex.Path(tl2)
|
||||
thetal1 = ele1.rotate(theta, [pt1.x,pt1.y])
|
||||
thetal2 = ele2.rotate(theta, [pt2.x,pt2.y])
|
||||
tpt1.x = thetal1[1].x
|
||||
tpt1.y = thetal1[1].y
|
||||
tpt2.x = thetal2[1].x
|
||||
tpt2.y = thetal2[1].y
|
||||
pnpt1 = inkex.paths.Move(tpt1.x, tpt1.y)
|
||||
pnpt2 = inkex.paths.Move(tpt2.x, tpt2.y)
|
||||
if ((not tpath.enclosed) and (self.insidePath(tpath.path, pnpt1) or self.insidePath(tpath.path, pnpt2))) or \
|
||||
(tpath.enclosed and ((not self.insidePath(tpath.path, pnpt1)) and (not self.insidePath(tpath.path, pnpt2)))):
|
||||
tpt1.y = pt1.y + currTabHt
|
||||
tpt2.y = pt2.y + currTabHt
|
||||
else:
|
||||
tpt1.y = pt1.y - currTabHt
|
||||
tpt2.y = pt2.y - currTabHt
|
||||
tpt1.x = pt1.x + currTabHt/math.tan(math.radians(currTabAngle))
|
||||
tpt2.x = pt2.x - currTabHt/math.tan(math.radians(currTabAngle))
|
||||
tl1 = [('M', [pt1.x,pt1.y])]
|
||||
tl1 += [('L', [tpt1.x, tpt1.y])]
|
||||
ele1 = inkex.Path(tl1)
|
||||
tl2 = [('M', [pt1.x,pt1.y])]
|
||||
tl2 += [('L', [tpt2.x, tpt2.y])]
|
||||
ele2 = inkex.Path(tl2)
|
||||
thetal1 = ele1.rotate(theta, [pt1.x,pt1.y])
|
||||
thetal2 = ele2.rotate(theta, [pt2.x,pt2.y])
|
||||
tpt1.x = thetal1[1].x
|
||||
tpt1.y = thetal1[1].y
|
||||
tpt2.x = thetal2[1].x
|
||||
tpt2.y = thetal2[1].y
|
||||
else: # pt1.x > pt2.x
|
||||
tpt1.y = pt1.y - testHt
|
||||
tpt2.y = pt2.y - testHt
|
||||
tpt1.x = pt1.x - testHt/math.tan(math.radians(testAngle))
|
||||
tpt2.x = pt2.x + testHt/math.tan(math.radians(testAngle))
|
||||
tl1 = [('M', [pt1.x,pt1.y])]
|
||||
tl1 += [('L', [tpt1.x, tpt1.y])]
|
||||
ele1 = inkex.Path(tl1)
|
||||
tl2 = [('M', [pt1.x,pt1.y])]
|
||||
tl2 += [('L', [tpt2.x, tpt2.y])]
|
||||
ele2 = inkex.Path(tl2)
|
||||
thetal1 = ele1.rotate(theta, [pt1.x,pt1.y])
|
||||
thetal2 = ele2.rotate(theta, [pt2.x,pt2.y])
|
||||
tpt1.x = thetal1[1].x
|
||||
tpt1.y = thetal1[1].y
|
||||
tpt2.x = thetal2[1].x
|
||||
tpt2.y = thetal2[1].y
|
||||
pnpt1 = inkex.paths.Move(tpt1.x, tpt1.y)
|
||||
pnpt2 = inkex.paths.Move(tpt2.x, tpt2.y)
|
||||
if ((not tpath.enclosed) and (self.insidePath(tpath.path, pnpt1) or self.insidePath(tpath.path, pnpt2))) or \
|
||||
(tpath.enclosed and ((not self.insidePath(tpath.path, pnpt1)) and (not self.insidePath(tpath.path, pnpt2)))):
|
||||
tpt1.y = pt1.y + currTabHt
|
||||
tpt2.y = pt2.y + currTabHt
|
||||
else:
|
||||
tpt1.y = pt1.y - currTabHt
|
||||
tpt2.y = pt2.y - currTabHt
|
||||
tpt1.x = pt1.x - currTabHt/math.tan(math.radians(currTabAngle))
|
||||
tpt2.x = pt2.x + currTabHt/math.tan(math.radians(currTabAngle))
|
||||
tl1 = [('M', [pt1.x,pt1.y])]
|
||||
tl1 += [('L', [tpt1.x, tpt1.y])]
|
||||
ele1 = inkex.Path(tl1)
|
||||
tl2 = [('M', [pt1.x,pt1.y])]
|
||||
tl2 += [('L', [tpt2.x, tpt2.y])]
|
||||
ele2 = inkex.Path(tl2)
|
||||
thetal1 = ele1.rotate(theta, [pt1.x,pt1.y])
|
||||
thetal2 = ele2.rotate(theta, [pt2.x,pt2.y])
|
||||
tpt1.x = thetal1[1].x
|
||||
tpt1.y = thetal1[1].y
|
||||
tpt2.x = thetal2[1].x
|
||||
tpt2.y = thetal2[1].y
|
||||
else: # slope > 0.0
|
||||
if pt1.x < pt2.x:
|
||||
tpt1.y = pt1.y - testHt
|
||||
tpt2.y = pt2.y - testHt
|
||||
tpt1.x = pt1.x + testHt/math.tan(math.radians(testAngle))
|
||||
tpt2.x = pt2.x - testHt/math.tan(math.radians(testAngle))
|
||||
tl1 = [('M', [pt1.x,pt1.y])]
|
||||
tl1 += [('L', [tpt1.x, tpt1.y])]
|
||||
ele1 = inkex.Path(tl1)
|
||||
tl2 = [('M', [pt1.x,pt1.y])]
|
||||
tl2 += [('L', [tpt2.x, tpt2.y])]
|
||||
ele2 = inkex.Path(tl2)
|
||||
thetal1 = ele1.rotate(theta, [pt1.x,pt1.y])
|
||||
thetal2 = ele2.rotate(theta, [pt2.x,pt2.y])
|
||||
tpt1.x = thetal1[1].x
|
||||
tpt1.y = thetal1[1].y
|
||||
tpt2.x = thetal2[1].x
|
||||
tpt2.y = thetal2[1].y
|
||||
pnpt1 = inkex.paths.Move(tpt1.x, tpt1.y)
|
||||
pnpt2 = inkex.paths.Move(tpt2.x, tpt2.y)
|
||||
if ((not tpath.enclosed) and (self.insidePath(tpath.path, pnpt1) or self.insidePath(tpath.path, pnpt2))) or \
|
||||
(tpath.enclosed and ((not self.insidePath(tpath.path, pnpt1)) and (not self.insidePath(tpath.path, pnpt2)))):
|
||||
tpt1.y = pt1.y + currTabHt
|
||||
tpt2.y = pt2.y + currTabHt
|
||||
else:
|
||||
tpt1.y = pt1.y - currTabHt
|
||||
tpt2.y = pt2.y - currTabHt
|
||||
tpt1.x = pt1.x + currTabHt/math.tan(math.radians(currTabAngle))
|
||||
tpt2.x = pt2.x - currTabHt/math.tan(math.radians(currTabAngle))
|
||||
tl1 = [('M', [pt1.x,pt1.y])]
|
||||
tl1 += [('L', [tpt1.x, tpt1.y])]
|
||||
ele1 = inkex.Path(tl1)
|
||||
tl2 = [('M', [pt1.x,pt1.y])]
|
||||
tl2 += [('L', [tpt2.x, tpt2.y])]
|
||||
ele2 = inkex.Path(tl2)
|
||||
thetal1 = ele1.rotate(theta, [pt1.x,pt1.y])
|
||||
thetal2 = ele2.rotate(theta, [pt2.x,pt2.y])
|
||||
tpt1.x = thetal1[1].x
|
||||
tpt1.y = thetal1[1].y
|
||||
tpt2.x = thetal2[1].x
|
||||
tpt2.y = thetal2[1].y
|
||||
else: # pt1.x > pt2.x
|
||||
tpt1.y = pt1.y - testHt
|
||||
tpt2.y = pt2.y - testHt
|
||||
tpt1.x = pt1.x - testHt/math.tan(math.radians(testAngle))
|
||||
tpt2.x = pt2.x + testHt/math.tan(math.radians(testAngle))
|
||||
tl1 = [('M', [pt1.x,pt1.y])]
|
||||
tl1 += [('L', [tpt1.x, tpt1.y])]
|
||||
ele1 = inkex.Path(tl1)
|
||||
tl2 = [('M', [pt1.x,pt1.y])]
|
||||
tl2 += [('L', [tpt2.x, tpt2.y])]
|
||||
ele2 = inkex.Path(tl2)
|
||||
thetal1 = ele1.rotate(theta, [pt1.x,pt1.y])
|
||||
thetal2 = ele2.rotate(theta, [pt2.x,pt2.y])
|
||||
tpt1.x = thetal1[1].x
|
||||
tpt1.y = thetal1[1].y
|
||||
tpt2.x = thetal2[1].x
|
||||
tpt2.y = thetal2[1].y
|
||||
pnpt1 = inkex.paths.Move(tpt1.x, tpt1.y)
|
||||
pnpt2 = inkex.paths.Move(tpt2.x, tpt2.y)
|
||||
if ((not tpath.enclosed) and (self.insidePath(tpath.path, pnpt1) or self.insidePath(tpath.path, pnpt2))) or \
|
||||
(tpath.enclosed and ((not self.insidePath(tpath.path, pnpt1)) and (not self.insidePath(tpath.path, pnpt2)))):
|
||||
tpt1.y = pt1.y + currTabHt
|
||||
tpt2.y = pt2.y + currTabHt
|
||||
else:
|
||||
tpt1.y = pt1.y - currTabHt
|
||||
tpt2.y = pt2.y - currTabHt
|
||||
tpt1.x = pt1.x - currTabHt/math.tan(math.radians(currTabAngle))
|
||||
tpt2.x = pt2.x + currTabHt/math.tan(math.radians(currTabAngle))
|
||||
tl1 = [('M', [pt1.x,pt1.y])]
|
||||
tl1 += [('L', [tpt1.x, tpt1.y])]
|
||||
ele1 = inkex.Path(tl1)
|
||||
tl2 = [('M', [pt1.x,pt1.y])]
|
||||
tl2 += [('L', [tpt2.x, tpt2.y])]
|
||||
ele2 = inkex.Path(tl2)
|
||||
thetal1 = ele1.rotate(theta, [pt1.x,pt1.y])
|
||||
thetal2 = ele2.rotate(theta, [pt2.x,pt2.y])
|
||||
tpt1.x = thetal1[1].x
|
||||
tpt1.y = thetal1[1].y
|
||||
tpt2.x = thetal2[1].x
|
||||
tpt2.y = thetal2[1].y
|
||||
# Check to see if any tabs intersect each other
|
||||
if self.detectIntersect(pt1.x, pt1.y, tpt1.x, tpt1.y, pt2.x, pt2.y, tpt2.x, tpt2.y):
|
||||
# Found an intersection.
|
||||
if adjustTab == 0:
|
||||
# Try increasing the tab angle in one-degree increments
|
||||
currTabAngle = currTabAngle + 1.0
|
||||
if currTabAngle > 88.0: # We're not increasing the tab angle above 89 degrees
|
||||
adjustTab = 1
|
||||
currTabAngle = taba
|
||||
if adjustTab == 1:
|
||||
# So, try reducing the tab height in 20% increments instead
|
||||
currTabHt = currTabHt - tabht*0.2 # Could this lead to a zero tab_height?
|
||||
if currTabHt <= 0.0:
|
||||
# Give up
|
||||
currTabHt = tabht
|
||||
adjustTab = 2
|
||||
if adjustTab == 2:
|
||||
tabDone = True # Just show the failure
|
||||
else:
|
||||
tabDone = True
|
||||
|
||||
return tpt1,tpt2
|
||||
|
||||
def effect(self):
|
||||
layer = self.svg.get_current_layer()
|
||||
scale = self.svg.unittouu('1'+self.options.unit)
|
||||
polysides = int(self.options.polysides)
|
||||
poly1size = float(self.options.poly1size) * scale
|
||||
poly2size = float(self.options.poly2size) * scale
|
||||
collarht = float(self.options.collarheight) * scale
|
||||
partcnt = int(self.options.collarparts)
|
||||
tab_angle = float(self.options.tabangle)
|
||||
tab_height = float(self.options.tabheight) * scale
|
||||
dashlength = float(self.options.dashlength) * scale
|
||||
polylarge = max(poly1size, poly2size) # Larger of the two polygons
|
||||
polysmall = min(poly1size, poly2size) # Smaller of the two polygons
|
||||
polysmallR = polysmall/2
|
||||
polysmallr = polysmallR*math.cos(math.pi/polysides)
|
||||
polysmalltabht = tab_height
|
||||
if polysmallr < polysmalltabht:
|
||||
polysmalltabht = polysmallr
|
||||
wpaths = []
|
||||
done = 0
|
||||
# We go through this loop twice
|
||||
# First time for the wrapper / decorative strip
|
||||
# Second time for the model, scorelines, and the lids
|
||||
while done < 2:
|
||||
w1 = (polylarge)*(math.sin(math.pi/polysides))
|
||||
w2 = (polysmall)*(math.sin(math.pi/polysides))
|
||||
if done == 0:
|
||||
# First time through, init the storage areas
|
||||
pieces = []
|
||||
nodes = []
|
||||
nd = []
|
||||
for i in range(4):
|
||||
nd.append(inkex.paths.Line(0.0,0.0))
|
||||
else:
|
||||
# Second time through, empty the storage areas
|
||||
i = 0
|
||||
while i < polysides:
|
||||
j = 0
|
||||
while j < 4:
|
||||
del pieces[i][0]
|
||||
j = j + 1
|
||||
i = i + 1
|
||||
i = 0
|
||||
while len(pieces) > 0:
|
||||
del pieces[0]
|
||||
i = i + 1
|
||||
i = 0
|
||||
while i < 4:
|
||||
del nodes[0]
|
||||
i = i + 1
|
||||
for pn in range(polysides):
|
||||
nodes.clear()
|
||||
#what we need here is to skip the rotatation and just move the x and y if there is no difference between the polygon sizes.
|
||||
#Added by Sue to handle equal polygons
|
||||
if poly1size == poly2size:
|
||||
nd[0].x = pn * w1
|
||||
nd[0].y = collarht
|
||||
nd[1].x = nd[0].x + w1
|
||||
nd[1].y = nd[0].y
|
||||
nd[2].x = nd[1].x
|
||||
nd[2].y = nd[0].y - collarht
|
||||
nd[3].x = nd[0].x
|
||||
nd[3].y = nd[2].y
|
||||
else:
|
||||
if pn == 0:
|
||||
nd[3].x = -w2/2
|
||||
nd[3].y = (polysmall/2)*math.cos(math.pi/polysides)
|
||||
nd[0].x = -w1/2
|
||||
nd[0].y = (polylarge/2)*math.cos(math.pi/polysides)
|
||||
vlen = math.sqrt(collarht**2 + (nd[0].y-nd[3].y)**2)
|
||||
nd[0].y = nd[0].y + (vlen-(nd[0].y-nd[3].y))
|
||||
nd[2].x = w2/2
|
||||
nd[2].y = nd[3].y
|
||||
nd[1].x = w1/2
|
||||
nd[1].y = nd[0].y
|
||||
ox,oy = self.findIntersection(nd[0].x,nd[0].y,nd[3].x,nd[3].y,nd[1].x,nd[1].y,nd[2].x,nd[2].y)
|
||||
Q2 = math.degrees(math.atan((nd[0].y - oy)/(w1/2 - ox)))
|
||||
Q1 = 90 - Q2
|
||||
else:
|
||||
dl = ''
|
||||
for j in range(4):
|
||||
if j == 0:
|
||||
dl += 'M '
|
||||
else:
|
||||
dl += ' L '
|
||||
dl += str(nd[j].x) + ',' + str(nd[j].y)
|
||||
dl += ' Z'
|
||||
p1 = inkex.paths.Path(path_d=dl)
|
||||
p2 = p1.rotate(-2*Q1, (ox,oy))
|
||||
for j in range(4):
|
||||
nd[j].x = p2[j].x
|
||||
nd[j].y = p2[j].y
|
||||
for i in range(4):
|
||||
nodes.append(copy.deepcopy(nd[i]))
|
||||
pieces.append(copy.deepcopy(nodes))
|
||||
dscores = []
|
||||
if done == 0:
|
||||
wpath = pathStruct() # We'll need this for makeTab
|
||||
wpath.id = "c1"
|
||||
for pc in range(partcnt):
|
||||
dwrap = '' # Create the wrapper
|
||||
dscores.clear()
|
||||
sidecnt = math.ceil(polysides/partcnt)
|
||||
if pc == partcnt - 1:
|
||||
# Last time through creates the remainder of the pieces
|
||||
sidecnt = polysides - math.ceil(polysides/partcnt)*pc
|
||||
startpc = pc*math.ceil(polysides/partcnt)
|
||||
endpc = startpc + sidecnt
|
||||
for pn in range(startpc, endpc):
|
||||
# First half
|
||||
if(pn == startpc):
|
||||
ppt0 = inkex.paths.Move(pieces[pn][0].x,pieces[pn][0].y)
|
||||
dwrap +='M '+str(ppt0.x)+','+str(ppt0.y)
|
||||
# We're also creating wpath for later use in creating the model
|
||||
wpath.path.append(ppt0)
|
||||
ppt1 = inkex.paths.Line(pieces[pn][1].x,pieces[pn][1].y)
|
||||
dwrap +=' L '+str(ppt1.x)+','+str(ppt1.y)
|
||||
wpath.path.append(ppt1)
|
||||
if pn < endpc - 1:
|
||||
# Put scorelines across the collar
|
||||
ppt2 = inkex.paths.Line(pieces[pn][2].x,pieces[pn][2].y)
|
||||
spaths = self.makescore(ppt1, ppt2,dashlength)
|
||||
dscores.append(spaths)
|
||||
for pn in range(endpc-1, startpc-1, -1):
|
||||
# Second half
|
||||
if(pn == (endpc-1)):
|
||||
ppt2 = inkex.paths.Line(pieces[pn][2].x,pieces[pn][2].y)
|
||||
dwrap +=' L '+str(pieces[pn][2].x)+','+str(pieces[pn][2].y)
|
||||
wpath.path.append(inkex.paths.Line(pieces[pn][2].x,pieces[pn][2].y))
|
||||
ppt3 = inkex.paths.Line(pieces[pn][3].x,pieces[pn][3].y)
|
||||
dwrap +=' L '+str(ppt3.x)+','+str(ppt3.y)
|
||||
wpath.path.append(inkex.paths.Line(pieces[pn][3].x,pieces[pn][3].y))
|
||||
dwrap +=' Z' # Close off the wrapper's path
|
||||
wpath.path.append(ppt0)
|
||||
if math.isclose(dashlength, 0.0):
|
||||
# lump together all the score lines
|
||||
dscore = ''
|
||||
for dndx in range(len(dscores)):
|
||||
if dndx == 0:
|
||||
dscore = dscores[dndx][1:]
|
||||
else:
|
||||
dscore += dscores[dndx]
|
||||
group = inkex.elements._groups.Group()
|
||||
group.label = 'group'+str(pc)+'ws'
|
||||
if self.options.generate_decorative_wrapper is True:
|
||||
self.drawline(dwrap,'wrapper'+str(pc),group,sstr="fill:#ffdddd;stroke:{};stroke-width:0.25".format(self.options.color_solid)) # Output the wrapper
|
||||
self.drawline(dscore,'score'+str(pc)+'w',group,sstr="fill:#ffdddd;stroke:{};stroke-width:0.25".format(self.options.color_dash)) # Output the scorelines separately
|
||||
layer.append(group)
|
||||
else:
|
||||
# lump together all the score lines with the model
|
||||
for dndx in dscores:
|
||||
dwrap = dwrap + dndx
|
||||
self.drawline(dwrap,'wrapper'+str(pc),layer,sstr="fill:#ffdddd;stroke:{};stroke-width:0.25".format(self.options.color_solid)) # Output the wrapper
|
||||
wpaths.append(copy.deepcopy(wpath))
|
||||
wpath.path.clear()
|
||||
done = 1
|
||||
else:
|
||||
# Create the model
|
||||
for pc in range(partcnt):
|
||||
dprop = ''
|
||||
dscores.clear()
|
||||
sidecnt = math.ceil(polysides/partcnt)
|
||||
if pc == partcnt - 1:
|
||||
sidecnt = polysides - math.ceil(polysides/partcnt)*pc
|
||||
startpc = pc*math.ceil(polysides/partcnt)
|
||||
endpc = startpc + sidecnt
|
||||
for pn in range(startpc, endpc):
|
||||
# First half
|
||||
if pn == startpc:
|
||||
dprop = 'M '+str(pieces[pn][0].x)+','+str(pieces[pn][0].y)
|
||||
cpt1 = inkex.paths.Move(pieces[pn][0].x, pieces[pn][0].y)
|
||||
cpt2 = inkex.paths.Move(pieces[pn][1].x, pieces[pn][1].y)
|
||||
tabpt1, tabpt2 = self.makeTab(wpaths[pc], cpt1, cpt2, tab_height, tab_angle)
|
||||
dprop +=' L '+str(tabpt1.x)+','+str(tabpt1.y)
|
||||
dprop +=' L '+str(tabpt2.x)+','+str(tabpt2.y)
|
||||
dprop += ' L '+str(pieces[pn][1].x)+','+str(pieces[pn][1].y)
|
||||
# As long as we're here, create a scoreline along the tab...
|
||||
spaths = self.makescore(pieces[pn][0], pieces[pn][1],dashlength)
|
||||
dscores.append(spaths)
|
||||
# ...and across the collar
|
||||
spaths = self.makescore(pieces[pn][1], pieces[pn][2],dashlength)
|
||||
dscores.append(spaths)
|
||||
for pn in range(endpc-1, startpc-1, -1):
|
||||
# Second half
|
||||
if(pn == (endpc-1)):
|
||||
# Since we're starting on the last piece, put a tab on the end of it, too
|
||||
cpt1 = inkex.paths.Move(pieces[pn][1].x, pieces[pn][1].y)
|
||||
cpt2 = inkex.paths.Move(pieces[pn][2].x, pieces[pn][2].y)
|
||||
tabpt1, tabpt2 = self.makeTab(wpaths[pc], cpt1, cpt2, tab_height, tab_angle)
|
||||
dprop +=' L '+str(tabpt1.x)+','+str(tabpt1.y)
|
||||
dprop +=' L '+str(tabpt2.x)+','+str(tabpt2.y)
|
||||
# Create a scoreline along the tab
|
||||
#spaths = self.makescore(pieces[pn][1], pieces[pn][2],dashlength)
|
||||
#dscores.append(spaths)
|
||||
dprop +=' L '+str(pieces[pn][2].x)+','+str(pieces[pn][2].y)
|
||||
cpt1 = inkex.paths.Move(pieces[pn][2].x, pieces[pn][2].y)
|
||||
cpt2 = inkex.paths.Move(pieces[pn][3].x, pieces[pn][3].y)
|
||||
tabpt1, tabpt2 = self.makeTab(wpaths[pc], cpt1, cpt2, polysmalltabht, tab_angle)
|
||||
dprop +=' L '+str(tabpt1.x)+','+str(tabpt1.y)
|
||||
dprop +=' L '+str(tabpt2.x)+','+str(tabpt2.y)
|
||||
dprop += ' L '+str(pieces[pn][3].x)+','+str(pieces[pn][3].y)
|
||||
# Create a scoreline along the tab
|
||||
spaths = self.makescore(pieces[pn][2], pieces[pn][3],dashlength)
|
||||
dscores.append(spaths)
|
||||
dprop += ' Z' # Close off the model's path
|
||||
# lump together all the score lines
|
||||
dscore = ''
|
||||
for dndx in range(len(dscores)):
|
||||
if dndx == 0:
|
||||
dscore = dscores[dndx][1:]
|
||||
else:
|
||||
dscore += dscores[dndx]
|
||||
group = inkex.elements._groups.Group()
|
||||
group.label = 'group'+str(pc)+'ms'
|
||||
self.drawline(dprop,'model'+str(pc),group,sstr='stroke:{};stroke-width:0.25;fill:#eeeeee'.format(self.options.color_solid)) # Output the model
|
||||
|
||||
#self.drawline(dprop,'model'+str(pc),group,sstr=None) # Output the model
|
||||
#self.drawline(dscore,'score'+str(pc)+'m',group,sstr=None) # Output the scorelines separately
|
||||
|
||||
|
||||
if dscore != '':
|
||||
dscore_style = 'stroke:{};stroke-width:0.25;fill:#eeeeee'.format(self.options.color_dash)
|
||||
if self.options.cosmetic_dash_style is True:
|
||||
dscore_style += ';stroke-dasharray:{}'.format(3, 3)
|
||||
self.drawline(dscore,'score'+str(pc),group,dscore_style) # Output the scorelines separately
|
||||
|
||||
layer.append(group)
|
||||
|
||||
# At this point, we can generate the top and bottom polygons
|
||||
# r = sidelength/(2*sin(PI/numpoly))
|
||||
self.drawline(self.makepoly(w1, polysides),'biglid',layer,sstr=None) # Output the bigger polygon
|
||||
sp = self.makepoly(w2, polysides)
|
||||
self.drawline(sp,'smalllid',layer,sstr=None) # Output the smaller polygon
|
||||
done = 2
|
||||
|
||||
if __name__ == '__main__':
|
||||
Collar().run()
|
@ -7,7 +7,7 @@
|
||||
<label appearance="header">Measures and tab generation</label>
|
||||
<param name="tabangle" type="float" min="0.01" max="90.0" precision="2" gui-text="Angle of tab edges (degrees):">45.00</param>
|
||||
<param name="tabheight" type="float" min="0.01" max="9999.0" precision="2" gui-text="Height of tab:">0.40</param>
|
||||
<param name="dashlength" type="float" min="0.0" max="9999.0" precision="2" gui-text="Length of dash line (zero for solid line):" gui-description="If value larger than zero the line will split up into real dash lines (no cosmetic one's)">0.1</param>
|
||||
<param name="dashlength" type="float" min="0.0" max="9999.0" precision="3" gui-text="Length of dash line (zero for solid line):" gui-description="If value larger than zero the line will split up into real dash lines (no cosmetic one's)">0.1</param>
|
||||
<param name="tabsets" type="optiongroup" appearance="combo" gui-text="Tab placement on polygons with cutouts:">
|
||||
<option value="outside">outside</option>
|
||||
<option value="inside">inside</option>
|
||||
|
@ -75,7 +75,7 @@ class Tabgen(inkex.EffectExtension):
|
||||
pars.add_argument("--usermenu")
|
||||
pars.add_argument("--tabangle", type=float, default=45.0, help="Angle of tab edges in degrees")
|
||||
pars.add_argument("--tabheight", type=float, default=0.4, help="Height of tab in dimensional units")
|
||||
pars.add_argument("--dashlength", type=float, default=0.25, help="Length of dashline in dimentional units (zero for solid line)")
|
||||
pars.add_argument("--dashlength", type=float, default=0.1, help="Length of dashline in dimentional units (zero for solid line)")
|
||||
pars.add_argument("--cosmetic_dash_style", type=inkex.Boolean, default=False, help="Cosmetic dash lines")
|
||||
pars.add_argument("--tabsets", default="both", help="Tab placement on polygons with cutouts")
|
||||
pars.add_argument("--unit", default="in", help="Dimensional units of selected paths")
|
||||
|
Reference in New Issue
Block a user