fixes in tab generator
This commit is contained in:
parent
d9922309c2
commit
8040fdaa70
@ -4,9 +4,10 @@
|
|||||||
<id>fablabchemnitz.de.tab_generator</id>
|
<id>fablabchemnitz.de.tab_generator</id>
|
||||||
<param name="usermenu" type="notebook">
|
<param name="usermenu" type="notebook">
|
||||||
<page name="settings" gui-text="Settings">
|
<page name="settings" gui-text="Settings">
|
||||||
<param name="tabangle" type="float" min="0.0" max="90.0" gui-text="Angle of tab edges (degrees):">45.0</param>
|
<label appearance="header">Measures and tab generation</label>
|
||||||
<param name="tabheight" type="float" min="0.01" max="9999.0" gui-text="Height of tab:">0.4</param>
|
<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="dashlength" type="float" min="0.0" max="9999.0" gui-text="Length of dashline (zero for solid line):">0.1</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="tabsets" type="optiongroup" appearance="combo" gui-text="Tab placement on polygons with cutouts:">
|
<param name="tabsets" type="optiongroup" appearance="combo" gui-text="Tab placement on polygons with cutouts:">
|
||||||
<option value="outside">outside</option>
|
<option value="outside">outside</option>
|
||||||
<option value="inside">inside</option>
|
<option value="inside">inside</option>
|
||||||
@ -23,9 +24,11 @@
|
|||||||
<option value="ft">ft</option>
|
<option value="ft">ft</option>
|
||||||
<option value="yd">yd</option>
|
<option value="yd">yd</option>
|
||||||
</param>
|
</param>
|
||||||
<param name="strokewidth" min="0.0" max="10000.0" precision="3" gui-text="Stroke width (px)" type="float">1.0</param>
|
<label appearance="header">Styles</label>
|
||||||
<param name="color_solid" type="color" appearance="colorbutton" gui-text="Solid line color">3419879935</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_dash" type="color" appearance="colorbutton" gui-text="Dash line color">1592519679</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>
|
||||||
|
<label appearance="header">Other settings</label>
|
||||||
<param name="print_debug" type="bool" gui-text="Print debug info">true</param>
|
<param name="print_debug" type="bool" gui-text="Print debug info">true</param>
|
||||||
<param name="keep_original" type="bool" gui-text="Keep original elements">false</param>
|
<param name="keep_original" type="bool" gui-text="Keep original elements">false</param>
|
||||||
</page>
|
</page>
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#
|
#
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Given a closed path of straight lines, this program generates a paper model containing
|
Given a closed path of straight lines, this program generates a paper model containing
|
||||||
tabs and score lines for each straight edge.
|
tabs and score lines for each straight edge.
|
||||||
@ -75,16 +76,19 @@ class Tabgen(inkex.EffectExtension):
|
|||||||
pars.add_argument("--tabangle", type=float, default=45.0, help="Angle of tab edges in degrees")
|
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("--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.25, 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("--tabsets", default="both", help="Tab placement on polygons with cutouts")
|
||||||
pars.add_argument("--unit", default="in", help="Dimensional units of selected paths")
|
pars.add_argument("--unit", default="in", help="Dimensional units of selected paths")
|
||||||
pars.add_argument("--strokewidth", type=float, default=1.0, help="Stroke width (px)")
|
pars.add_argument("--color_solid", type=Color, default='4278190335', help="Solid line color")
|
||||||
pars.add_argument("--color_solid", type=Color, default='3419879935', help="Solid line color")
|
pars.add_argument("--color_dash", type=Color, default='65535', help="Solid line dash")
|
||||||
pars.add_argument("--color_dash", type=Color, default='1592519679', help="Solid line dash")
|
|
||||||
pars.add_argument("--print_debug", type=inkex.Boolean, default=True, help="Print debug info")
|
pars.add_argument("--print_debug", type=inkex.Boolean, default=True, help="Print debug info")
|
||||||
pars.add_argument("--keep_original", type=inkex.Boolean, default=False, help="Keep original elements")
|
pars.add_argument("--keep_original", type=inkex.Boolean, default=False, help="Keep original elements")
|
||||||
|
|
||||||
#draw SVG line segment(s) between the given (raw) points
|
|
||||||
def drawline(self, dstr, name, parent, sstr=None):
|
def drawline(self, dstr, name, parent, sstr=None):
|
||||||
|
'''
|
||||||
|
draw SVG line segment(s) between the given (raw) points
|
||||||
|
'''
|
||||||
line_style = {'stroke':'#000000','stroke-width':'1','fill':'none'}
|
line_style = {'stroke':'#000000','stroke-width':'1','fill':'none'}
|
||||||
if sstr == None:
|
if sstr == None:
|
||||||
stylestr = str(inkex.Style(line_style))
|
stylestr = str(inkex.Style(line_style))
|
||||||
@ -95,6 +99,7 @@ class Tabgen(inkex.EffectExtension):
|
|||||||
el.style = sstr
|
el.style = sstr
|
||||||
el.label = name
|
el.label = name
|
||||||
|
|
||||||
|
|
||||||
def pathInsidePath(self, path, testpath):
|
def pathInsidePath(self, path, testpath):
|
||||||
enclosed = True
|
enclosed = True
|
||||||
for tp in testpath:
|
for tp in testpath:
|
||||||
@ -104,6 +109,7 @@ class Tabgen(inkex.EffectExtension):
|
|||||||
return enclosed # True if testpath is fully enclosed in path
|
return enclosed # True if testpath is fully enclosed in path
|
||||||
return enclosed
|
return enclosed
|
||||||
|
|
||||||
|
|
||||||
def insidePath(self, path, p):
|
def insidePath(self, path, p):
|
||||||
point = pnPoint((p.x, p.y))
|
point = pnPoint((p.x, p.y))
|
||||||
pverts = []
|
pverts = []
|
||||||
@ -112,6 +118,7 @@ class Tabgen(inkex.EffectExtension):
|
|||||||
isInside = point.InPolygon(pverts, True)
|
isInside = point.InPolygon(pverts, True)
|
||||||
return isInside # True if point p is inside path
|
return isInside # True if point p is inside path
|
||||||
|
|
||||||
|
|
||||||
def makescore(self, pt1, pt2, dashlength):
|
def makescore(self, pt1, pt2, dashlength):
|
||||||
# Draws a dashed line of dashlength between two points
|
# Draws a dashed line of dashlength between two points
|
||||||
# Dash = dashlength (in inches) space followed by dashlength mark
|
# Dash = dashlength (in inches) space followed by dashlength mark
|
||||||
@ -200,17 +207,20 @@ class Tabgen(inkex.EffectExtension):
|
|||||||
done = True
|
done = True
|
||||||
return ddash
|
return ddash
|
||||||
|
|
||||||
|
|
||||||
def detectIntersect(self, x1, y1, x2, y2, x3, y3, x4, y4):
|
def detectIntersect(self, x1, y1, x2, y2, x3, y3, x4, y4):
|
||||||
td = (x1-x2)*(y3-y4)-(y1-y2)*(x3-x4)
|
td = (x1-x2)*(y3-y4)-(y1-y2)*(x3-x4)
|
||||||
if td == 0:
|
if td == 0:
|
||||||
# These line segments are parallel
|
# These line segments are parallel
|
||||||
return False
|
return False
|
||||||
t = ((x1-x3)*(y3-y4)-(y1-y3)*(x3-x4))/td
|
t = ((x1-x3)*(y3-y4)-(y1-y3)*(x3-x4))/td
|
||||||
|
|
||||||
if (0.0 <= t) and (t <= 1.0):
|
if (0.0 <= t) and (t <= 1.0):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def makeTab(self, tpath, pt1, pt2, tabht, taba):
|
def makeTab(self, tpath, pt1, pt2, tabht, taba):
|
||||||
# tpath - the pathstructure containing pt1 and pt2
|
# tpath - the pathstructure containing pt1 and pt2
|
||||||
# pt1, pt2 - the two points where the tab will be inserted
|
# pt1, pt2 - the two points where the tab will be inserted
|
||||||
@ -467,6 +477,7 @@ class Tabgen(inkex.EffectExtension):
|
|||||||
tpt1.y = thetal1[1].y
|
tpt1.y = thetal1[1].y
|
||||||
tpt2.x = thetal2[1].x
|
tpt2.x = thetal2[1].x
|
||||||
tpt2.y = thetal2[1].y
|
tpt2.y = thetal2[1].y
|
||||||
|
|
||||||
# Check to see if any tabs intersect each other
|
# 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):
|
if self.detectIntersect(pt1.x, pt1.y, tpt1.x, tpt1.y, pt2.x, pt2.y, tpt2.x, tpt2.y):
|
||||||
# Found an intersection.
|
# Found an intersection.
|
||||||
@ -504,10 +515,6 @@ class Tabgen(inkex.EffectExtension):
|
|||||||
elems = []
|
elems = []
|
||||||
pc = 0
|
pc = 0
|
||||||
|
|
||||||
solidLineStyle = {'stroke': str(self.options.color_solid), 'fill': 'none', 'stroke-width': self.options.strokewidth}
|
|
||||||
dashLineStyle = {'stroke': str(self.options.color_dash), 'fill': 'none', 'stroke-width': self.options.strokewidth}
|
|
||||||
|
|
||||||
|
|
||||||
for selem in self.svg.selection.filter(inkex.PathElement):
|
for selem in self.svg.selection.filter(inkex.PathElement):
|
||||||
elems.append(selem)
|
elems.append(selem)
|
||||||
if len(elems) == 0:
|
if len(elems) == 0:
|
||||||
@ -526,6 +533,18 @@ class Tabgen(inkex.EffectExtension):
|
|||||||
idmod = 0
|
idmod = 0
|
||||||
elementPath = Path(elem.path.to_absolute().transform(elem.getparent().composed_transform()))
|
elementPath = Path(elem.path.to_absolute().transform(elem.getparent().composed_transform()))
|
||||||
|
|
||||||
|
isClosed = False
|
||||||
|
raw = elementPath.to_arrays()
|
||||||
|
if raw[-1][0] == 'Z' or \
|
||||||
|
(raw[-1][0] == 'L' and raw[0][1] == raw[-1][1]) or \
|
||||||
|
(raw[-1][0] == 'C' and raw[0][1] == [raw[-1][1][-2], raw[-1][1][-1]]) \
|
||||||
|
: #if first is last point the path is also closed. The "Z" command is not required
|
||||||
|
isClosed = True
|
||||||
|
if isClosed is False:
|
||||||
|
if self.options.print_debug is True:
|
||||||
|
self.msg("Warning! Path {} is not closed. Skipping ...".format(elem.get('id')))
|
||||||
|
continue
|
||||||
|
|
||||||
for ptoken in elementPath: # For each point in the path
|
for ptoken in elementPath: # For each point in the path
|
||||||
ptx2 = None
|
ptx2 = None
|
||||||
pty2 = None
|
pty2 = None
|
||||||
@ -566,12 +585,9 @@ class Tabgen(inkex.EffectExtension):
|
|||||||
else:
|
else:
|
||||||
raise inkex.AbortExtension("Unrecognized path command {0}".format(ptoken.letter))
|
raise inkex.AbortExtension("Unrecognized path command {0}".format(ptoken.letter))
|
||||||
npath.path.append(inkex.paths.Line(ptx2,pty2))
|
npath.path.append(inkex.paths.Line(ptx2,pty2))
|
||||||
npath.style = solidLineStyle
|
|
||||||
if ptoken.letter == 'Z':
|
if ptoken.letter == 'Z':
|
||||||
npaths.append(npath)
|
npaths.append(npath)
|
||||||
else:
|
|
||||||
if self.options.print_debug is True:
|
|
||||||
self.msg("Warning! Path {} is not closed. Skipping ...".format(elem.get('id')))
|
|
||||||
last_letter = ptoken.letter
|
last_letter = ptoken.letter
|
||||||
# check for cutouts
|
# check for cutouts
|
||||||
if idmod > 1:
|
if idmod > 1:
|
||||||
@ -580,6 +596,7 @@ class Tabgen(inkex.EffectExtension):
|
|||||||
if apath.id != bpath.id:
|
if apath.id != bpath.id:
|
||||||
if self.pathInsidePath(bpath.path, apath.path):
|
if self.pathInsidePath(bpath.path, apath.path):
|
||||||
apath.enclosed = True
|
apath.enclosed = True
|
||||||
|
|
||||||
# add tabs to current path(s)
|
# add tabs to current path(s)
|
||||||
if 'style' in elem.attrib:
|
if 'style' in elem.attrib:
|
||||||
sstr = elem.attrib['style']
|
sstr = elem.attrib['style']
|
||||||
@ -600,6 +617,7 @@ class Tabgen(inkex.EffectExtension):
|
|||||||
dsub = '' # Used for building sub-paths
|
dsub = '' # Used for building sub-paths
|
||||||
dprop = '' # Used for building the main path
|
dprop = '' # Used for building the main path
|
||||||
dscore = '' # Used for building dashlines
|
dscore = '' # Used for building dashlines
|
||||||
|
|
||||||
for apath in npaths:
|
for apath in npaths:
|
||||||
mpath = [apath.path[0]] # init output path with first point of input path
|
mpath = [apath.path[0]] # init output path with first point of input path
|
||||||
for ptn in range(len(apath.path)-1):
|
for ptn in range(len(apath.path)-1):
|
||||||
@ -628,17 +646,17 @@ class Tabgen(inkex.EffectExtension):
|
|||||||
## and close the path
|
## and close the path
|
||||||
dsub = dsub + ' Z'
|
dsub = dsub + ' Z'
|
||||||
dprop = dprop + dsub # combine all the paths
|
dprop = dprop + dsub # combine all the paths
|
||||||
if math.isclose(dashlength, 0.0):
|
# lump together all the score lines
|
||||||
# lump together all the score lines
|
group = inkex.elements._groups.Group()
|
||||||
group = inkex.elements._groups.Group()
|
group.label = 'group'+str(pc)+'ms'
|
||||||
group.label = 'group'+str(pc)+'ms'
|
self.drawline(dprop,'model'+str(pc),group,sstr+';stroke:{}'.format(self.options.color_solid)) # Output the model
|
||||||
self.drawline(dprop,'model'+str(pc),group,sstr) # Output the model
|
if dscore != '':
|
||||||
if dscore != '':
|
dscore_style = sstr+';stroke:{}'.format(self.options.color_dash)
|
||||||
self.drawline(dscore,'score'+str(pc),group,sstr) # Output the scorelines separately
|
if self.options.cosmetic_dash_style is True:
|
||||||
layer.append(group)
|
dscore_style += ';stroke-dasharray:{}'.format(3, 3)
|
||||||
else:
|
self.drawline(dscore,'score'+str(pc),group,dscore_style) # Output the scorelines separately
|
||||||
dprop = dprop + dscore
|
layer.append(group)
|
||||||
self.drawline(dprop,savid+'ms',layer,sstr)
|
|
||||||
pc += 1
|
pc += 1
|
||||||
|
|
||||||
if self.options.keep_original is False:
|
if self.options.keep_original is False:
|
||||||
|
Reference in New Issue
Block a user