diff --git a/extensions/fablabchemnitz/tab_generator/tab_generator.inx b/extensions/fablabchemnitz/tab_generator/tab_generator.inx
index 808b4116..bdccc7d7 100644
--- a/extensions/fablabchemnitz/tab_generator/tab_generator.inx
+++ b/extensions/fablabchemnitz/tab_generator/tab_generator.inx
@@ -4,9 +4,10 @@
fablabchemnitz.de.tab_generator
- 45.0
- 0.4
- 0.1
+
+ 45.00
+ 0.40
+ 0.1
@@ -23,9 +24,11 @@
- 1.0
- 3419879935
- 1592519679
+
+ false
+ 4278190335
+ 65535
+
true
false
diff --git a/extensions/fablabchemnitz/tab_generator/tab_generator.py b/extensions/fablabchemnitz/tab_generator/tab_generator.py
index 454b69ab..fe233d2b 100644
--- a/extensions/fablabchemnitz/tab_generator/tab_generator.py
+++ b/extensions/fablabchemnitz/tab_generator/tab_generator.py
@@ -16,6 +16,7 @@
# 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 closed path of straight lines, this program generates a paper model containing
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("--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("--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")
- pars.add_argument("--strokewidth", type=float, default=1.0, help="Stroke width (px)")
- pars.add_argument("--color_solid", type=Color, default='3419879935', help="Solid line color")
- pars.add_argument("--color_dash", type=Color, default='1592519679', help="Solid line dash")
+ 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")
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")
- #draw SVG line segment(s) between the given (raw) points
+
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'}
if sstr == None:
stylestr = str(inkex.Style(line_style))
@@ -95,6 +99,7 @@ class Tabgen(inkex.EffectExtension):
el.style = sstr
el.label = name
+
def pathInsidePath(self, path, testpath):
enclosed = True
for tp in testpath:
@@ -103,6 +108,7 @@ class Tabgen(inkex.EffectExtension):
enclosed = False
return enclosed # True if testpath is fully enclosed in path
return enclosed
+
def insidePath(self, path, p):
point = pnPoint((p.x, p.y))
@@ -112,6 +118,7 @@ class Tabgen(inkex.EffectExtension):
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
@@ -200,17 +207,20 @@ class Tabgen(inkex.EffectExtension):
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
@@ -467,6 +477,7 @@ class Tabgen(inkex.EffectExtension):
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.
@@ -503,11 +514,7 @@ class Tabgen(inkex.EffectExtension):
savid = ''
elems = []
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):
elems.append(selem)
if len(elems) == 0:
@@ -526,6 +533,18 @@ class Tabgen(inkex.EffectExtension):
idmod = 0
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
ptx2 = None
pty2 = None
@@ -566,12 +585,9 @@ class Tabgen(inkex.EffectExtension):
else:
raise inkex.AbortExtension("Unrecognized path command {0}".format(ptoken.letter))
npath.path.append(inkex.paths.Line(ptx2,pty2))
- npath.style = solidLineStyle
if ptoken.letter == 'Z':
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
# check for cutouts
if idmod > 1:
@@ -580,6 +596,7 @@ class Tabgen(inkex.EffectExtension):
if apath.id != bpath.id:
if self.pathInsidePath(bpath.path, apath.path):
apath.enclosed = True
+
# add tabs to current path(s)
if 'style' in elem.attrib:
sstr = elem.attrib['style']
@@ -600,6 +617,7 @@ class Tabgen(inkex.EffectExtension):
dsub = '' # Used for building sub-paths
dprop = '' # Used for building the main path
dscore = '' # Used for building dashlines
+
for apath in npaths:
mpath = [apath.path[0]] # init output path with first point of input path
for ptn in range(len(apath.path)-1):
@@ -628,17 +646,17 @@ class Tabgen(inkex.EffectExtension):
## and close the path
dsub = dsub + ' Z'
dprop = dprop + dsub # combine all the paths
- if math.isclose(dashlength, 0.0):
- # lump together all the score lines
- group = inkex.elements._groups.Group()
- group.label = 'group'+str(pc)+'ms'
- self.drawline(dprop,'model'+str(pc),group,sstr) # Output the model
- if dscore != '':
- self.drawline(dscore,'score'+str(pc),group,sstr) # Output the scorelines separately
- layer.append(group)
- else:
- dprop = dprop + dscore
- self.drawline(dprop,savid+'ms',layer,sstr)
+ # lump together all the score lines
+ group = inkex.elements._groups.Group()
+ group.label = 'group'+str(pc)+'ms'
+ self.drawline(dprop,'model'+str(pc),group,sstr+';stroke:{}'.format(self.options.color_solid)) # Output the model
+ if dscore != '':
+ dscore_style = sstr+';stroke:{}'.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)
+
pc += 1
if self.options.keep_original is False: