diff --git a/extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Bendy_Straw.py b/extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Bendy_Straw.py
new file mode 100644
index 00000000..9e1a4977
--- /dev/null
+++ b/extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Bendy_Straw.py
@@ -0,0 +1,369 @@
+#! /usr/bin/env python3
+
+import numpy as np
+from math import pi, sin, cos, tan, asin, acos, atan, sqrt
+
+import inkex
+
+from Path import Path
+from Pattern import Pattern
+
+# Select name of class, inherits from Pattern
+# TODO:
+# 1) Implement __init__ method to get all custom options and then call Pattern's __init__
+# 2) Implement generate_path_tree to define all of the desired strokes
+MIN = 0.0001
+
+
+class Bendy_Straw(Pattern):
+
+ def __init__(self):
+ Pattern.__init__(self) # Must be called in order to parse common options
+
+ # save all custom parameters defined on .inx file
+ self.add_argument('--pattern', default='bendy_straw')
+ self.add_argument('--pattern_type', default='origami')
+ self.add_argument('--parameter_type', default='angles')
+ self.add_argument('--n', type=int, default=6)
+ self.add_argument('--lines', type=int, default=3)
+ self.add_argument('--radius', type=float, default=25.0)
+ self.add_argument('--radial_ratio', type=float, default=0.75)
+
+ self.add_argument('--alpha1', type=int, default=45)
+ self.add_argument('--alpha2', type=int, default=35)
+ self.add_argument('--h1', type=float, default=1)
+ self.add_argument('--h2', type=float, default=2)
+
+ self.add_argument('--vertex_base_outer_bool', type=inkex.Boolean, default=False)
+ self.add_argument('--vertex_base_inner_bool', type=inkex.Boolean, default=False)
+ self.add_argument('--vertex_radius_outer_bool', type=inkex.Boolean, default=False)
+ self.add_argument('--vertex_radius_inner_bool', type=inkex.Boolean, default=False)
+
+ self.add_argument('--add_attachment', type=inkex.Boolean, default=False)
+
+ # slot options for support ring
+ self.add_argument('--base_height', type=float, default=5.0)
+ self.add_argument('--add_base_slot', type=inkex.Boolean, default=False)
+ self.add_argument('--center_base_slot', type=inkex.Boolean, default=False)
+ self.add_argument('--base_slot_height', type=float, default=3.0)
+ self.add_argument('--base_slot_width', type=float, default=3.0)
+ self.add_argument('--distance', type=float, default=3.0)
+ self.add_argument('--add_distance_slot', type=inkex.Boolean, default=False)
+ self.add_argument('--distance_slot_height', type=float, default=3.0)
+ self.add_argument('--distance_slot_width', type=float, default=3.0)
+
+ def generate_path_tree(self):
+ """ Specialized path generation for your origami pattern
+ """
+ # retrieve conversion factor for selected unit
+ unit_factor = self.calc_unit_factor()
+ vertex_radius = self.options.vertex_radius * unit_factor
+
+ # retrieve saved parameters, and apply unit factor where needed
+ pattern_type = self.options.pattern_type
+ n = self.options.n
+ lines = self.options.lines
+ radial_ratio = self.options.radial_ratio
+ R = self.options.radius * unit_factor
+ distance = self.options.distance * unit_factor
+ base_height = self.options.base_height * unit_factor
+ # add_attachment = self.options.add_attachment
+ # attachment_length = self.options.attachment_length * unit_factor
+ r = R * radial_ratio
+
+ if (self.options.parameter_type == 'angles'):
+ alpha1 = self.options.alpha1 * pi / 180
+ alpha2 = self.options.alpha2 * pi / 180
+ elif (self.options.parameter_type == 'heights'):
+ alpha1 = atan(self.options.h1 * unit_factor / (R - r))
+ alpha2 = atan(self.options.h2 * unit_factor / (R - r))
+
+ # calculating pattern parameters
+ l1 = (R - r) / cos(alpha1)
+ l2 = (R - r) / cos(alpha2)
+ A = 2 * R * sin(pi / n)
+ # attachment_length = 0.01 * self.options.attachment_length * A
+ a = A * radial_ratio
+ dx = (A - a) / 2
+ beta1 = acos(cos(alpha1) * sin(pi / n))
+ beta2 = acos(cos(alpha2) * sin(pi / n))
+ b1 = l1 * sin(beta1)
+ b2 = l2 * sin(beta2)
+ height = (b1 + b2) * lines + distance * (lines - 1)
+
+ if self.options.add_attachment: n = n+1
+
+ #
+ # big horizontal mountains grid
+ #
+ mountain_horizontal_stroke = Path([(0, base_height), (A * n, base_height)], 'm')
+ horizontal_grid_mountain = []
+ for i in range(1, lines):
+ horizontal_grid_mountain.append(
+ mountain_horizontal_stroke + (0, distance * (i - 1) + b1 * (i + 0) + b2 * (i + 0)))
+ horizontal_grid_mountain.append(
+ mountain_horizontal_stroke + (0, distance * (i + 0) + b1 * (i + 0) + b2 * (i + 0)))
+ if distance < MIN:
+ horizontal_grid_mountain = horizontal_grid_mountain[::2]
+ if base_height > MIN:
+ horizontal_grid_mountain.insert(0, mountain_horizontal_stroke)
+ horizontal_grid_mountain.append(
+ mountain_horizontal_stroke + (0, distance * (lines - 1) + b1 * lines + b2 * lines))
+
+ # reverse every other horizontal stroke for faster laser-cutting
+ for i in range(len(horizontal_grid_mountain)):
+ if (i % 2 == 0):
+ horizontal_grid_mountain[i].points.reverse()
+
+ #
+ # diamond shapes
+ #
+
+ # full diamond patterns styles, depending on pattern type
+ style_diag_left = 'm'
+ style_diag_right = 'm'
+ style_diag = 'v'
+ style_vert = 'm'
+ style_hori_left = 'm'
+ style_hori_right = 'm'
+ if pattern_type == 'origami' or pattern_type == 'origami_bent':
+ style_hori_left = 'v'
+ style_diag_left = 'n'
+ style_diag_right = 'v'
+ elif pattern_type == 'origami2':
+ style_hori_right = 'v'
+ style_diag_left = 'v'
+ style_diag_right = 'n'
+ elif pattern_type == 'kirigami1':
+ style_vert = 'v'
+ style_hori_left = 'c'
+ style_hori_right = 'c'
+ elif pattern_type == 'kirigami2':
+ style_diag_left = 'c'
+ style_diag_right = 'c'
+ style_hori_left = 'n'
+ style_hori_right = 'n'
+ style_vert = 'n'
+
+ # diamond pattern with strokes of different styles
+ stroke_base = Path([(0, 0), (0, base_height)], 'm')
+ diamond_diagonals_left = Path([(0, base_height), (-dx, base_height + b1), (0, base_height + b1 + b2)],
+ style_diag_left)
+ diamond_diagonals_right = Path([(0, base_height + b1 + b2), (dx, base_height + b1), (0, base_height)],
+ style_diag_right)
+ diamond_vertical = Path([(0, base_height), (0, base_height + b1 + b2)], style_vert)
+ stroke_distance = Path([(0, base_height + b1 + b2), (0, distance + base_height + b1 + b2)], 'm')
+ diamond_horizontal_left = Path([(-dx, 0), (0, 0)], style_hori_left)
+ diamond_horizontal_right = Path([(0, 0), (dx, 0)], style_hori_right)
+
+ diamond = [diamond_diagonals_left, diamond_diagonals_right, diamond_vertical]
+
+ if pattern_type == 'origami_bent':
+ bent_diagonal = Path([(0, base_height + b1 + b2), (dx, base_height + b1), (0, base_height)], 'm')
+ bent_horizontal = Path([(0, 0), (dx, 0)], 'v')
+ line_bent = []
+
+
+ # drawing lines with the diamond shapes
+ line_left = []
+ line_middle = []
+ line_right = []
+ if base_height > MIN:
+ line_middle.append(stroke_base)
+ if pattern_type == 'origami_bent':
+ line_bent.append(stroke_base)
+ for i in range(lines):
+ delta = (0, (distance + b1 + b2) * i)
+ if pattern_type != 'kirigami2':
+ line_left.append(diamond_diagonals_right + delta)
+ line_middle = line_middle + Path.list_add(diamond, delta)
+ if pattern_type != 'kirigami2':
+ line_right.append(diamond_diagonals_left + delta)
+ if distance > MIN and i < lines - 1:
+ line_middle.append(stroke_distance + delta)
+
+ if pattern_type == 'origami_bent':
+ line_bent = line_bent + [bent_diagonal + delta]
+ if distance > MIN and i < lines - 1:
+ line_bent.append(stroke_distance + delta)
+
+ if base_height > MIN:
+ line_middle.append(stroke_base + (0, base_height + height))
+ if pattern_type == 'origami_bent':
+ line_bent.append(stroke_base + (0, base_height + height))
+
+ # creating full diamond patterns
+ line_left = line_left[::-1]
+ diamond_patterns_full = [line_left]
+ for i in range(n - 1):
+ delta = (A * (i + 1), 0)
+ if pattern_type == 'origami_bent' and i == 2:
+ diamond_patterns_full.append(Path.list_add(line_bent, delta))
+ else:
+ diamond_patterns_full.append(Path.list_add(line_middle, delta))
+ diamond_patterns_full.append(Path.list_add(line_right, (A * n, 0)))
+
+ #
+ # small horizontal alternate style grid
+ #
+ valley_points = [(dx, 0),
+ (dx + a, 0)]
+ valley_stroke = Path(valley_points, 'v')
+ if pattern_type == 'kirigami2':
+ horizontal_line = []
+ else:
+ horizontal_line = [diamond_horizontal_right + (0, 0)]
+ for i in range(n):
+ if not (pattern_type == 'origami_bent' and i == 3):
+ horizontal_line.append(valley_stroke + ((a + 2 * dx) * i, 0))
+ if (pattern_type != 'kirigami2'):
+ if not (pattern_type == 'origami_bent' and i == 3):
+ horizontal_line.append(diamond_horizontal_left + (A + (a + 2 * dx) * i, 0))
+ if pattern_type == 'origami_bent' and i==2:
+ horizontal_line.append(bent_horizontal + (A + (a + 2 * dx) * i, 0))
+ elif i < n - 1:
+ horizontal_line.append(diamond_horizontal_right + (A + (a + 2 * dx) * i, 0))
+ horizontal_grid_alternate = []
+ for i in range(lines):
+ horizontal_grid_alternate.append(
+ Path.list_add(horizontal_line, (0, base_height + distance * (i + 0) + b1 * (i + 1) + b2 * (i + 0))))
+
+ # reverse every other horizontal stroke for faster laser-cutting
+ for i in range(len(horizontal_grid_alternate)):
+ if (i % 2 == 0):
+ horizontal_grid_alternate[i] = Path.list_invert(horizontal_grid_alternate[i])
+
+ # for i in range(len(horizontal_grid_alternate)):
+ # inkex.debug(i)
+ # Path.debug_points(horizontal_grid_alternate[i])
+ # inkex.debug('\n')
+
+ #
+ # edge drawing
+ #
+ self.edge_points = [(0, 0)]
+ self.edge_points.append((A * n, 0))
+
+ # rectangles for attachments at base and between cells
+
+ # add upper base attachment
+ self.edge_points.append((A * n, base_height))
+
+ # draw attachment between cells and inside cells
+ for i in range(lines):
+ self.edge_points.append((A * n + 0, base_height + (b1 + b2) * (i + 0) + distance * i))
+ if pattern_type == 'kirigami2':
+ self.edge_points.append((A * n - dx, base_height + b1 * (i + 1) + (b2 + distance) * i))
+ self.edge_points.append((A * n + 0, base_height + (b1 + b2) * (i + 1) + distance * i))
+
+ self.edge_points.append((A * n, height + 2 * base_height))
+ self.edge_points.append((0, height + 2 * base_height))
+
+ # if full kirigami selected, cut left side next to cells
+ if pattern_type == 'kirigami2':
+ for i in range(lines):
+ self.edge_points.append((0, height + base_height - (b1 + b2) * (i + 0) - distance * i))
+ self.edge_points.append((dx, height + base_height - b2 * (i + 1) - (b1 + distance) * i))
+ self.edge_points.append((0, height + base_height - (b1 + b2) * (i + 1) - distance * i))
+
+ #
+ # slots drawing
+ #
+ center_slot = self.options.center_base_slot
+ base_slots = []
+ if self.options.add_base_slot:
+ base_slot_height = self.options.base_slot_height
+ base_slot_width = self.options.base_slot_width
+ if base_slot_height > base_height or base_slot_width > A:
+ inkex.debug('Base slot dimensions are too big')
+ base_slot_height = min(base_height, base_slot_height)
+ base_slot_width = min(A, base_slot_width)
+ if base_slot_height > 0 and base_slot_width > 0:
+ points = [(0, 0),
+ (0, base_slot_height),
+ (base_slot_width, base_slot_height),
+ (base_slot_width, 0,)]
+ base_slot = Path(points, 'c', closed=True) + ((A - base_slot_width)/2, (base_height - base_slot_height)/(1+center_slot))
+ base_slots_line = []
+ for i in range(n):
+ base_slots_line.append(base_slot + (A*i, 0))
+ base_slots = [base_slots_line]
+ base_slots.append(Path.list_add(base_slots_line, (0, height+base_slot_height + (base_height - base_slot_height)*center_slot)))
+
+ dist_slots = []
+ if self.options.add_distance_slot:
+ dist_slot_height = self.options.distance_slot_height
+ dist_slot_width = self.options.distance_slot_width
+ if dist_slot_height > distance or dist_slot_width > A:
+ inkex.debug('Dimensions of slots between cells are too big')
+ dist_slot_height = min(distance, dist_slot_height)
+ dist_slot_width = min(A, dist_slot_width)
+
+ if dist_slot_height > 0 and dist_slot_width > 0:
+ points = [(0, 0),
+ (0, dist_slot_height),
+ (dist_slot_width, dist_slot_height),
+ (dist_slot_width, 0,)]
+ dist_slot = Path(points, 'c', closed=True) + ((A - dist_slot_width)/2, base_height+b1+b2 + (distance - dist_slot_height)/2)
+ dist_slots_line = []
+ for i in range(n):
+ dist_slots_line.append(dist_slot + (A*i, 0))
+
+ for i in range(lines-1):
+ dist_slots.append(Path.list_add(dist_slots_line, (0, i*(b1+b2+distance))))
+
+
+
+ # sending lines to draw
+ self.path_tree = [horizontal_grid_mountain, horizontal_grid_alternate, diamond_patterns_full, base_slots, dist_slots]
+
+ #
+ # vertices drawing
+ #
+ # outer base vertices?
+ if self.options.vertex_base_outer_bool:
+ self.vertex_points = self.vertex_points + [(A * i, height + base_height * 2) for i in range(n + 1)]
+ self.vertex_points = self.vertex_points + [(A*i, 0) for i in range(n+1)]
+
+ # inner base vertices?
+ if self.options.vertex_base_inner_bool:
+ self.vertex_points = self.vertex_points + [(A*i, base_height) for i in range(n+1)]
+ self.vertex_points = self.vertex_points + [(A*i, height+base_height) for i in range(n+1)]
+ for j in range(lines-1):
+ self.vertex_points = self.vertex_points + [(A*i, base_height+((b1+b2)*(j+1))+distance*j) for i in range(n+1)] + \
+ [(A*i, base_height+((b1+b2)*(j+1))+distance*(j+1)) for i in range(n+1)]
+
+ # radius vertices?
+ if self.options.vertex_radius_outer_bool and pattern_type != 'kirigami2':
+ for j in range(lines):
+ i_range = list(range(3)) + list(range(3+(pattern_type=='origami_bent'), n + 1))
+ self.vertex_points = self.vertex_points + [(A * i, base_height + b1*(j+1) + (b2+distance)*j) for i in i_range]
+ if self.options.vertex_radius_inner_bool:
+ for j in range(lines):
+ if pattern_type != 'origami2':
+ # pass
+ self.vertex_points = self.vertex_points + [(dx + A * i, base_height + b1*(j+1) + (b2+distance)*j) for i in range(n)]
+ if pattern_type[:7] != 'origami':
+ # pass
+ self.vertex_points = self.vertex_points + [(-dx + A * (i + 1), base_height + b1 * (j + 1) + (b2 + distance) * j) for i in range(n)]
+ # for j in range(lines):
+
+
+
+
+ # self.vertex_points = self.vertex_points + vertices_base
+
+ # self.vertex_points = self.vertex_points + self.edge_points
+ # diamond_patterns_full_simple = Path.list_simplify(diamond_patterns_full)
+ # for path in diamond_patterns_full:
+ # # path = Path.list_simplify(path)
+ # # path = Path.list_simplify(path[0])
+ # if path.style != 'n':
+ # self.vertex_points = self.vertex_points + path.points
+
+
+
+#
+
+if __name__ == '__main__':
+ Bendy_Straw().run()
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Kresling_full.py b/extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Kresling_full.py
index 5d55d004..8a3d9b3b 100644
--- a/extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Kresling_full.py
+++ b/extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Kresling_full.py
@@ -10,8 +10,6 @@ from Kresling import Kresling
class Kresling_Full(Kresling):
def __init__(self):
- """ Constructor
- """
Kresling.__init__(self) # Must be called in order to parse common options
self.add_argument('--measure_value', type=float, default=10.0, help="Length")
diff --git a/extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Path.py b/extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Path.py
index ceab873c..a9cf8aca 100644
--- a/extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Path.py
+++ b/extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Path.py
@@ -1,9 +1,35 @@
#! /usr/bin/env python3
-import inkex
-from lxml import etree
+"""
+Path Class
+
+Defines a path and what it is supposed to be (mountain, valley, edge)
+
+"""
+
+import inkex # Required
+import simplestyle # will be needed here for styles support
+
+# compatibility hack
+try:
+ from lxml import etree
+ inkex.etree = etree
+except:
+ pass
+
from math import sin, cos, pi
+# compatibility hack for formatStyle
+def format_style(style):
+ try:
+ return str(inkex.Style(style)) # new
+ except:
+ return simplestyle.formatStyle(style) # old
+# def format_style(style):
+ # return simplestyle.formatStyle(style)
+
+
+
class Path:
""" Class that defines an svg stroke to be drawn in Inkscape
@@ -47,6 +73,7 @@ class Path:
of the style. Ex.:
if path_tree[i].style = 'm', styles_dict must have an element 'm'.
+
generate_hgrid(cls, xlims, ylims, nb_of_divisions, style, include_edge=False)
Generate list of Path instances, in which each Path is a stroke defining a horizontal grid dividing the space
xlims * ylims nb_of_divisions times.
@@ -70,8 +97,16 @@ class Path:
list_add(cls, paths, offsets)
Generate list of new Path instances, adding a different tuple for each list
+
+ list_simplify(cls, paths)
+ Gets complicated path-tree list and converts it into
+ a simple list.
+ list_invert(cls, paths)
+ Invert list of paths and points of each path.
+ debug_points(cls, paths):
+ Plots points of path tree in drawing order.
"""
def __init__(self, points, style, closed=False, invert=False, radius=0.1, separated=False):
@@ -126,7 +161,7 @@ class Path:
- Draws strokes defined on "path_tree" to "group"
- Inputs:
-- path_tree [nested list] of Path instances
- -- group [etree.SubElement]
+ -- group [inkex.etree.SubElement]
-- styles_dict [dict] containing all styles for path_tree
"""
@staticmethod
@@ -138,10 +173,11 @@ class Path:
if len(subpath) == 1:
subgroup = group
else:
- subgroup = etree.SubElement(group, 'g')
+ subgroup = inkex.etree.SubElement(group, 'g')
Path.draw_paths_recursively(subpath, subgroup, styles_dict)
else:
- if styles_dict[subpath.style]['draw']:
+ # ~ if subpath.style != 'n':
+ if subpath.style != 'n' and styles_dict[subpath.style]['draw']:
if subpath.type == 'linear':
points = subpath.points
@@ -151,13 +187,14 @@ class Path:
if subpath.closed:
path = path + 'L{},{} Z'.format(*points[0])
- attribs = {'style': str(inkex.Style(styles_dict[subpath.style])), 'd': path}
- etree.SubElement(group, inkex.addNS('path', 'svg'), attribs)
+
+ attribs = {'style': format_style(styles_dict[subpath.style]), 'd': path}
+ inkex.etree.SubElement(group, inkex.addNS('path', 'svg'), attribs)
else:
- attribs = {'style': str(inkex.Style(styles_dict[subpath.style])),
+ attribs = {'style': format_style(styles_dict[subpath.style]),
'cx': str(subpath.points[0][0]), 'cy': str(subpath.points[0][1]),
'r': str(subpath.radius)}
- etree.SubElement(group, inkex.addNS('circle', 'svg'), attribs)
+ inkex.etree.SubElement(group, inkex.addNS('circle', 'svg'), attribs)
@classmethod
def generate_hgrid(cls, xlims, ylims, nb_of_divisions, style, include_edge=False):
@@ -242,6 +279,7 @@ class Path:
paths.append(cls([points[i], points[j]],
styles[i]))
return paths
+
def __add__(self, offsets):
""" " + " operator overload.
@@ -463,4 +501,60 @@ class Path:
for path in paths:
paths_new.append(Path.reflect(path, p1, p2))
- return paths_new
\ No newline at end of file
+ return paths_new
+
+ @classmethod
+ def list_simplify(cls, paths):
+ """ Gets complicated path-tree list and converts it into
+ a simple list.
+
+ Returns
+ ---------
+ paths: list
+ list of Path instances
+ """
+ if type(paths) == Path:
+ return paths
+
+ simple_list = []
+ for i in range(len(paths)):
+ if type(paths[i]) == Path:
+ simple_list.append(paths[i])
+ elif type(paths[i]) == list:
+ simple_list = simple_list + Path.list_simplify(paths[i])
+ return simple_list
+
+ @classmethod
+ def list_invert(cls, paths):
+ """ Invert list of paths and points of each path.
+
+ Returns
+ ---------
+ paths: list
+ list of Path instances
+ """
+
+ if type(paths) == Path:
+ # return Path(paths.points[::-1], paths.style, paths.closed, paths.invert)
+ return Path(paths.points, paths.style, paths.closed, True)
+ elif type(paths) == list:
+ paths_inverted = []
+ # n = len(paths)
+ # for i in range(n):
+ # # paths_inverted.append(Path.list_invert(paths[n-1-i]))
+ # paths_inverted.append(Path.list_invert(paths[i]))
+ for path in paths:
+ # paths_inverted.append(Path.list_invert(paths[n-1-i]))
+ paths_inverted.append(Path.list_invert(path))
+ return paths_inverted[::-1]
+
+ @classmethod
+ def debug_points(cls, paths):
+ """ Plots points of path tree in drawing order.
+
+ """
+ if type(paths) == Path:
+ inkex.debug(paths.points)
+ elif type(paths) == list:
+ for sub_path in paths:
+ Path.debug_points(sub_path)
diff --git a/extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Pattern.py b/extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Pattern.py
index 3dc8c257..199a06ff 100644
--- a/extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Pattern.py
+++ b/extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Pattern.py
@@ -29,7 +29,8 @@ class Pattern(inkex.Effect):
self.add_argument('--mountain_dashes_duty', type=float, default=0.5, help='Mountain dash duty cycle.')
self.add_argument('--mountain_dashes_bool', type=inkex.Boolean, default=True, help='Dashed strokes?')
self.add_argument('--mountain_bool', type=inkex.Boolean, default=True, help='Draw mountains?')
-
+ self.add_argument('--mountain_bool_only', type=inkex.Boolean, default=False)
+
# --------------------------------------------------------------------------------------------------------------
# valley options
self.add_argument('-v', '--valley_stroke_color', default=65535, help='The valley creases color.')
@@ -38,6 +39,7 @@ class Pattern(inkex.Effect):
self.add_argument('--valley_dashes_duty', type=float, default=0.25, help='Valley dash duty cycle.')
self.add_argument('--valley_dashes_bool', type=inkex.Boolean, default=True, help='Dashed strokes?')
self.add_argument('--valley_bool', type=inkex.Boolean, default=True, help='Draw valleys?')
+ self.add_argument('--valley_bool_only', type=inkex.Boolean, default=False)
# --------------------------------------------------------------------------------------------------------------
# edge options
@@ -47,6 +49,7 @@ class Pattern(inkex.Effect):
self.add_argument('--edge_dashes_duty', type=float, default=0.25, help='Edge dash duty cycle.')
self.add_argument('--edge_dashes_bool', type=inkex.Boolean, default=False, help='Dashed strokes?')
self.add_argument('--edge_bool', type=inkex.Boolean, default=True, help='Draw edges?')
+ self.add_argument('--edge_bool_only', type=inkex.Boolean, default=False)
self.add_argument('--edge_single_path', type=inkex.Boolean, default=True, help='Edges as single path?')
# --------------------------------------------------------------------------------------------------------------
@@ -57,6 +60,7 @@ class Pattern(inkex.Effect):
self.add_argument('--universal_dashes_duty', type=float, default=0.25, help='Universal dash duty cycle.')
self.add_argument('--universal_dashes_bool', type=inkex.Boolean, default=False, help='Dashed strokes?')
self.add_argument('--universal_bool', type=inkex.Boolean, default=True, help='Draw universal creases?')
+ self.add_argument('--universal_bool_only', type=inkex.Boolean, default=False)
# --------------------------------------------------------------------------------------------------------------
# semicrease options
@@ -66,7 +70,8 @@ class Pattern(inkex.Effect):
self.add_argument('--semicrease_dashes_duty', type=float,default=0.25, help='Semicrease dash duty cycle.')
self.add_argument('--semicrease_dashes_bool', type=inkex.Boolean, default=False, help='Dashed strokes?')
self.add_argument('--semicrease_bool', type=inkex.Boolean, default=True, help='Draw semicreases?')
-
+ self.add_argument('--semicrease_bool_only', type=inkex.Boolean, default=False)
+
# --------------------------------------------------------------------------------------------------------------
# cut options
self.add_argument('--cut_stroke_color', default=16711935, help='The cut creases color.')
@@ -75,23 +80,42 @@ class Pattern(inkex.Effect):
self.add_argument('--cut_dashes_duty', type=float, default=0.25, help='Cut dash duty cycle.')
self.add_argument('--cut_dashes_bool', type=inkex.Boolean, default=False, help='Dashed strokes?')
self.add_argument('--cut_bool', type=inkex.Boolean, default=True, help='Draw cuts?')
+ self.add_argument('--cut_bool_only', type=inkex.Boolean, default=False)
# --------------------------------------------------------------------------------------------------------------
# vertex options
self.add_argument('--vertex_stroke_color', default=255, help='Vertices\' color.')
self.add_argument('--vertex_stroke_width', type=float, default=0.1, help='Width of vertex strokes.')
self.add_argument('--vertex_radius', type=float, default=0.1, help='Radius of vertices.')
- self.add_argument('--vertex_bool', type=inkex.Boolean, default=True, help='Draw vertices?')
+ self.add_argument('--vertex_bool', type=inkex.Boolean, default=True)
+ self.add_argument('--vertex_bool_only', type=inkex.Boolean, default=False)
+
# here so we can have tabs - but we do not use it directly - else error
self.add_argument('--active-tab', default='title', help="Active tab.")
self.path_tree = []
self.edge_points = []
+ self.vertex_points = []
self.translate = (0, 0)
def effect(self):
- """ Main function, called when the extension is run.
- """
+ # check if any selected to print only some of the crease types:
+ bool_only_list = [self.options.mountain_bool_only,
+ self.options.valley_bool_only,
+ self.options.edge_bool_only,
+ self.options.universal_bool_only,
+ self.options.semicrease_bool_only,
+ self.options.cut_bool_only,
+ self.options.vertex_bool_only]
+ if sum(bool_only_list) > 0:
+ self.options.mountain_bool = self.options.mountain_bool and self.options.mountain_bool_only
+ self.options.valley_bool = self.options.valley_bool and self.options.valley_bool_only
+ self.options.edge_bool = self.options.edge_bool and self.options.edge_bool_only
+ self.options.universal_bool = self.options.universal_bool and self.options.universal_bool_only
+ self.options.semicrease_bool = self.options.semicrease_bool and self.options.semicrease_bool_only
+ self.options.cut_bool = self.options.cut_bool and self.options.cut_bool_only
+ self.options.vertex_bool = self.options.vertex_bool and self.options.vertex_bool_only
+
# construct dictionary containing styles
self.create_styles_dict()
@@ -103,6 +127,14 @@ class Pattern(inkex.Effect):
# what page are we on
# page_id = self.options.active_tab # sometimes wrong the very first time
+ # get vertex points and add them to path tree
+ vertex_radius = self.options.vertex_radius * self.calc_unit_factor()
+ vertices = []
+ self.vertex_points = list(set([i for i in self.vertex_points])) # remove duplicates
+ for vertex_point in self.vertex_points:
+ vertices.append(Path(vertex_point, style='p', radius=vertex_radius))
+ self.path_tree.append(vertices)
+
# Translate according to translate attribute
g_attribs = {inkex.addNS('label', 'inkscape'): '{} Origami pattern'.format(self.options.pattern),
# inkex.addNS('transform-center-x','inkscape'): str(-bbox_center[0]),
diff --git a/extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/SupportRing.py b/extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/SupportRing.py
new file mode 100644
index 00000000..f933fe62
--- /dev/null
+++ b/extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/SupportRing.py
@@ -0,0 +1,86 @@
+#! /usr/bin/env python3
+
+import numpy as np
+from math import pi, sin, cos
+
+import inkex
+
+from Path import Path
+from Pattern import Pattern
+
+class SupportRing(Pattern):
+
+ def __init__(self):
+ Pattern.__init__(self) # Must be called in order to parse common options
+
+ # save all custom parameters defined on .inx file
+ self.add_argument('--sides', type=int, default=3)
+ self.add_argument('--radius_external', type=float, default=10.0)
+ self.add_argument('--radius_ratio', type=float, default=0.5)
+ self.add_argument('--radius_type', default='polygonal')
+ self.add_argument('--radius_draw', type=inkex.Boolean, default=True)
+ self.add_argument('--connector_length', type=float, default=3.0)
+ self.add_argument('--connector_thickness', type=float, default=3.0)
+ self.add_argument('--head_length', type=float, default=1.0)
+ self.add_argument('--head_thickness', type=float, default=1.0)
+ self.add_argument('--pattern', default='support ring')
+
+ def generate_path_tree(self):
+ """ Specialized path generation for your origami pattern
+ """
+ # retrieve conversion factor for selected unit
+ unit_factor = self.calc_unit_factor()
+
+ # retrieve saved parameters, and apply unit factor where needed
+ radius_external = self.options.radius_external * unit_factor
+ radius_type = self.options.radius_type
+ radius_ratio = self.options.radius_ratio
+ radius_internal = radius_external * radius_ratio
+ dradius = radius_external-radius_internal
+ sides = self.options.sides
+ connector_length = self.options.connector_length * unit_factor
+ connector_thickness = self.options.connector_thickness * unit_factor
+ head_length = self.options.head_length * unit_factor
+ head_thickness = self.options.head_thickness * unit_factor
+
+ angle = pi / sides
+ length_external = 2 * radius_external * sin(angle)
+ length_internal = length_external * radius_ratio
+
+ external_points = [(-length_external/2, 0),
+ (-connector_thickness / 2, 0),
+ (-connector_thickness / 2, -connector_length),
+ (-connector_thickness / 2 - head_thickness / 2, -connector_length),
+ (-connector_thickness / 2, -connector_length - head_length),
+ (0, -connector_length - head_length),
+ (+connector_thickness / 2, -connector_length - head_length),
+ (+connector_thickness / 2 + head_thickness / 2, -connector_length),
+ (+connector_thickness / 2, -connector_length),
+ (+connector_thickness / 2, 0),
+ (length_external/2, 0)]
+ internal_points = [(0, 0), (length_internal, 0)]
+
+ external_lines_0 = Path(external_points, 'm') + (length_external / 2, 0)
+ external_lines = [external_lines_0]
+
+ for i in range(sides-1):
+ x, y = external_lines[-1].points[-1]
+ external_lines.append(external_lines_0*(1, 2*(i+1)*angle) + (x, y))
+
+ self.path_tree = [external_lines]
+
+ if self.options.radius_draw == True:
+ if radius_type == 'polygonal':
+ internal_lines_0 = Path(internal_points, 'm')
+ internal_lines = [internal_lines_0]
+ for i in range(sides - 1):
+ x, y = internal_lines[-1].points[-1]
+ internal_lines.append(internal_lines_0*(1, 2*(i+1)*angle) + (x, y))
+ internal_lines = Path.list_add(internal_lines, ((length_external - length_internal) / 2, dradius * cos(angle)))
+ elif radius_type == 'circular':
+ internal_lines = Path((length_external / 2, radius_internal + dradius/2), radius=radius_internal, style = 'm')
+
+ self.path_tree.append(internal_lines)
+
+if __name__ == '__main__':
+ SupportRing().run()
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/origami_patterns/origami_patterns_bendy_straw.inx b/extensions/fablabchemnitz/origami_patterns/origami_patterns_bendy_straw.inx
new file mode 100644
index 00000000..97d80474
--- /dev/null
+++ b/extensions/fablabchemnitz/origami_patterns/origami_patterns_bendy_straw.inx
@@ -0,0 +1,105 @@
+
+
+ Origami Pattern - Bendy Straw
+ fablabchemnitz.de.origami_patterns.bendy_straw
+
+
+
+
+
+
+
+
+
+ 6
+ 3
+
+ 25.0
+ 0.75
+
+
+
+
+
+ 45
+ 35
+ 1
+ 2
+
+
+
+
+
+
+
+
+
+ false
+
+ 5.0
+ false
+ false
+ 3.0
+ 3.0
+
+ 3.0
+ false
+ 3.0
+ 3.0
+
+
+ true
+ true
+ 1
+ 0.5
+ 0.1
+ 4278190335
+
+
+ true
+ true
+ 1
+ 0.25
+ 0.1
+ 65535
+
+
+ true
+ false
+ 1
+ 0.25
+ 0.1
+ 16711935
+
+
+ true
+ true
+ false
+ 1
+ 0.25
+ 0.1
+ 255
+
+
+ true
+ true
+ true
+ true
+ true
+ 0.1
+ 0.1
+ 255
+
+
+
+ all
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/origami_patterns/origami_patterns_kresling.inx b/extensions/fablabchemnitz/origami_patterns/origami_patterns_kresling.inx
index e742e297..c2b253c7 100644
--- a/extensions/fablabchemnitz/origami_patterns/origami_patterns_kresling.inx
+++ b/extensions/fablabchemnitz/origami_patterns/origami_patterns_kresling.inx
@@ -1,6 +1,6 @@
- Origami Pattern - Kresling tower
+ Origami Pattern - Kresling Tower
fablabchemnitz.de.origami_patterns.kresling_full
@@ -21,9 +21,6 @@
-
@@ -48,6 +45,7 @@
true
+ false
true
1
0.5
@@ -56,6 +54,7 @@
true
+ false
true
1
0.25
@@ -64,6 +63,7 @@
true
+ false
true
false
1
@@ -72,7 +72,8 @@
255
- false
+ true
+ false
0.1
0.1
255
diff --git a/extensions/fablabchemnitz/origami_patterns/origami_patterns_misc_support_ring.inx b/extensions/fablabchemnitz/origami_patterns/origami_patterns_misc_support_ring.inx
new file mode 100644
index 00000000..ec1c8443
--- /dev/null
+++ b/extensions/fablabchemnitz/origami_patterns/origami_patterns_misc_support_ring.inx
@@ -0,0 +1,48 @@
+
+
+ Origami Pattern - Support Ring
+ fablabchemnitz.de.origami_patterns.support_ring
+
+
+ 6
+ 10.0
+
+ 3.0
+ 3.0
+ 1.0
+ 1.0
+
+ true
+ 0.5
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+ 1
+ 0.5
+ 0.1
+ 4278190335
+
+
+
+ all
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/origami_patterns/origami_patterns_pleat_circular.inx b/extensions/fablabchemnitz/origami_patterns/origami_patterns_pleat_circular.inx
index ffcbf00a..84c1ae9a 100644
--- a/extensions/fablabchemnitz/origami_patterns/origami_patterns_pleat_circular.inx
+++ b/extensions/fablabchemnitz/origami_patterns/origami_patterns_pleat_circular.inx
@@ -20,6 +20,7 @@
true
+ false
true
1
0.5
@@ -28,6 +29,7 @@
true
+ false
true
1
0.25
@@ -36,6 +38,7 @@
true
+ false
true
false
1
@@ -43,8 +46,16 @@
0.1
255
+
+ true
+ false
+ 0.1
+ 0.1
+ 255
+
true
+ false
false
1
0.25
diff --git a/extensions/fablabchemnitz/origami_patterns/origami_patterns_pleat_hypar.inx b/extensions/fablabchemnitz/origami_patterns/origami_patterns_pleat_hypar.inx
index ebfec933..f4d8139c 100644
--- a/extensions/fablabchemnitz/origami_patterns/origami_patterns_pleat_hypar.inx
+++ b/extensions/fablabchemnitz/origami_patterns/origami_patterns_pleat_hypar.inx
@@ -21,10 +21,10 @@
7
false
-
true
+ false
true
1
0.5
@@ -33,6 +33,7 @@
true
+ false
true
1
0.25
@@ -41,6 +42,7 @@
true
+ false
false
1
0.25
@@ -49,6 +51,7 @@
true
+ false
true
false
1
@@ -57,7 +60,8 @@
255
- false
+ true
+ false
0.1
0.1
255
diff --git a/extensions/fablabchemnitz/origami_patterns/origami_patterns_template.inx b/extensions/fablabchemnitz/origami_patterns/origami_patterns_template.inx
index fc3d7c57..eba5068f 100644
--- a/extensions/fablabchemnitz/origami_patterns/origami_patterns_template.inx
+++ b/extensions/fablabchemnitz/origami_patterns/origami_patterns_template.inx
@@ -1,6 +1,6 @@
- Origami Pattern - Template effect
+ Origami Pattern - Template Effect
fablabchemnitz.de.origami_patterns.template
@@ -21,14 +21,16 @@
true
+ false
true
- 1
- 0.5
+ 1
+ 0.5
0.1
4278190335
true
+ false
true
1
0.25
@@ -37,44 +39,21 @@
true
+ false
true
false
- 1
- 0.25
- 0.1
+ 1
+ 0.25
+ 0.1
255
true
- 0.1
- 0.1
+ false
+ 0.1
+ 0.1
255
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
all
diff --git a/extensions/fablabchemnitz/origami_patterns/origami_patterns_waterbomb.inx b/extensions/fablabchemnitz/origami_patterns/origami_patterns_waterbomb.inx
index b54314e0..d24e9971 100644
--- a/extensions/fablabchemnitz/origami_patterns/origami_patterns_waterbomb.inx
+++ b/extensions/fablabchemnitz/origami_patterns/origami_patterns_waterbomb.inx
@@ -28,6 +28,7 @@
true
+ false
true
1
0.5
@@ -36,6 +37,7 @@
true
+ false
true
1
0.25
@@ -44,6 +46,7 @@
true
+ false
true
false
1
@@ -52,7 +55,8 @@
255
- false
+ true
+ false
0.1
0.1
255