some fixes
This commit is contained in:
parent
b255672418
commit
2c84a21c64
@ -7,13 +7,13 @@
|
||||
<option value="path_slantselection">Slant selection</option>
|
||||
</param>
|
||||
<label>Unit for lengths is px</label>
|
||||
<param name="len1" type="float" gui-text="Len1: red <" min="1" max="100">12</param>
|
||||
<param name="len2" type="float" gui-text="Len2: green < =" min="1" max="100">25</param>
|
||||
<param name="len3" type="float" gui-text="Len3: greenyellow < =" min="1" max="100">40</param>
|
||||
<param name="len4" type="float" gui-text="Len4: skyblue < =" min="1" max="100">60</param>
|
||||
<param name="len5" type="float" gui-text="Len5: blue >" min="1" max="100">60</param>
|
||||
<param name="hor" type="float" gui-text="hor: red < (H/W)" min="0.01" max="100">0.1</param>
|
||||
<param name="ver" type="float" gui-text="ver: blue >" min="1" max="100">10</param>
|
||||
<param name="len1" type="float" gui-text="Len1: red <" min="1" max="99999">12</param>
|
||||
<param name="len2" type="float" gui-text="Len2: green < =" min="1" max="99999">25</param>
|
||||
<param name="len3" type="float" gui-text="Len3: greenyellow < =" min="1" max="99999">40</param>
|
||||
<param name="len4" type="float" gui-text="Len4: skyblue < =" min="1" max="99999">60</param>
|
||||
<param name="len5" type="float" gui-text="Len5: blue >" min="1" max="99999">60</param>
|
||||
<param name="hor" type="float" gui-text="hor: red < (H/W)" min="0.01" max="99999">0.1</param>
|
||||
<param name="ver" type="float" gui-text="ver: blue >" min="1" max="99999">10</param>
|
||||
<effect>
|
||||
<object-type>path</object-type>
|
||||
<effects-menu>
|
||||
|
@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>J Tech Photonics Laser Tool</name>
|
||||
<id>fablabchemnitz.de.j_tech_photonics_laser_tool</id>
|
||||
<param name="tabs" type="notebook">
|
||||
<page name="important_settings" gui-text="Important Settings">
|
||||
<param name="unit" type="optiongroup" appearance="combo" gui-text="Unit of Measurement">
|
||||
<option value="mm">millimeters</option>
|
||||
<option value="in">inches</option>
|
||||
</param>
|
||||
<param name="travel_speed" type="float" min="0" max="999999" gui-text="Travel Speed (unit/min)">3000</param>
|
||||
<param name="cutting_speed" type="float" min="0" max="999999" gui-text="Cutting Speed (unit/min)">750</param>
|
||||
<spacer/>
|
||||
<param name="passes" type="int" min="1" max="999999" gui-text="Passes">1</param>
|
||||
<param name="pass_depth" type="float" min="0" max="999999" gui-text="Pass Depth (unit)">1</param>
|
||||
<spacer/>
|
||||
<param name="directory" type="path" gui-text="Output Directory" mode="folder">-- Choose Output Directory --</param>
|
||||
<param name="filename" type="string" gui-text="Filename">output.gcode</param>
|
||||
<param name="filename_dynamic" type="bool" gui-text="Reuse SVG filename for output">false</param>
|
||||
<param name="filename_suffix" type="bool" gui-text="Add Numeric Suffix to Filename">true</param>
|
||||
</page>
|
||||
<page name="advanced_settings" gui-text="Advanced Settings">
|
||||
<param name="tool_power_command" type="string" gui-text="Tool Power Command">M3 S255;</param>
|
||||
<param name="tool_off_command" type="string" gui-text="Tool Off Command">M5;</param>
|
||||
<param name="dwell_time" type="float" gui-text="Dwell Time Before Moving (ms)">0</param>
|
||||
<spacer/>
|
||||
<param name="draw_debug" type="bool" gui-text="Draw Debug">true</param>
|
||||
<param name="debug_line_width" type="float" gui-text="Debug Line Width (px)">0.5</param>
|
||||
<param name="debug_arrow_scale" type="float" min="0" gui-text="Debug Arrow Scale">1.0</param>
|
||||
<spacer/>
|
||||
<param name="approximation_tolerance" type="string" gui-text="Approximation Tolerance (+-unit) [tip, stay between 10^-4 and 1]">0.01</param>
|
||||
</page>
|
||||
<page name="header_footer_settings" gui-text="Custom Header and Footer">
|
||||
<spacer/>
|
||||
<param name="header_path" type="path" mode="file" gui-text="Custom G-code Header Filepath" />
|
||||
<param name="footer_path" type="path" mode="file" gui-text="Custom G-code Footer Filepath" />
|
||||
<spacer/>
|
||||
<param name="do_z_axis_start" type="bool" gui-text="Set Z-Axis Start Position">false</param>
|
||||
<param name="z_axis_start" type="float" min="0" max="999999" gui-text="Absolute Z-Axis Start Position (unit)">0</param>
|
||||
<spacer/>
|
||||
<param name="move_to_origin_end" type="bool" gui-text="Move To Origin When Done">false</param>
|
||||
<spacer/>
|
||||
<param name="do_laser_off_start" type="bool" gui-text="Turn Laser Off Before a Job">true</param>
|
||||
<param name="do_laser_off_end" type="bool" gui-text="Turn Laser Off After a Job">true</param>
|
||||
</page>
|
||||
<page name="scaling" gui-text="Coordinate System and Transformations">
|
||||
<param name="machine_origin" type="optiongroup" appearance="combo" gui-text="Machine Origin">
|
||||
<option value="bottom-left">bottom-left</option>
|
||||
<option value="center">center</option>
|
||||
<option value="top-left">top-left</option>
|
||||
</param>
|
||||
<param name="invert_y_axis" type="bool" gui-text="Invert Y-Axis">false</param>
|
||||
<param name="bed_width" type="float" min="0" max="999999" gui-text="Bed X Width (unit)">200</param>
|
||||
<param name="bed_height" type="float" min="0" max="999999" gui-text="Bed Y Length (unit)">200</param>
|
||||
<spacer/>
|
||||
<param name="horizontal_offset" type="float" min="-999999" max="999999" gui-text="Gcode X Offset (unit)">0</param>
|
||||
<param name="vertical_offset" type="float" min="-999999" max="999999" gui-text="Gcode Y Offset (unit)">0</param>
|
||||
<param name="scaling_factor" type="float" min="-999999" max="999999" gui-text="Gcode Scaling Factor">1</param>
|
||||
</page>
|
||||
</param>
|
||||
<effect>
|
||||
<object-type>path</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="FabLab Chemnitz">
|
||||
<submenu name="Import/Export/Transfer"/>
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command location="inx" interpreter="python">j_tech_photonics_laser_tool.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
@ -0,0 +1,312 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
from lxml import etree
|
||||
from xml.etree import ElementTree as xml_tree
|
||||
from inkex import EffectExtension, Boolean
|
||||
|
||||
from svg_to_gcode.svg_parser import parse_root, Transformation, debug_methods
|
||||
from svg_to_gcode.geometry import LineSegmentChain
|
||||
from svg_to_gcode.compiler import Compiler, interfaces
|
||||
from svg_to_gcode import TOLERANCES
|
||||
|
||||
svg_name_space = "http://www.w3.org/2000/svg"
|
||||
inkscape_name_space = "http://www.inkscape.org/namespaces/inkscape"
|
||||
sodipodi_name_space = "http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
|
||||
inx_filename = "j_tech_photonics_laser_tool.inx"
|
||||
|
||||
|
||||
def generate_custom_interface(laser_off_command, laser_power_command):
|
||||
"""Wrapper function for generating a Gcode interface with a custom laser power command"""
|
||||
|
||||
class CustomInterface(interfaces.Gcode):
|
||||
"""A Gcode interface with a custom laser power command"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def laser_off(self):
|
||||
return f"{laser_off_command}"
|
||||
|
||||
def set_laser_power(self, _):
|
||||
return f"{laser_power_command}"
|
||||
|
||||
return CustomInterface
|
||||
|
||||
|
||||
class JTechPhotonicsLaserTool(EffectExtension):
|
||||
"""Inkscape Effect Extension."""
|
||||
|
||||
def __init__(self):
|
||||
EffectExtension.__init__(self)
|
||||
|
||||
def effect(self):
|
||||
"""Takes the SVG from Inkscape, generates gcode, returns the SVG after adding debug lines."""
|
||||
|
||||
root = self.document.getroot()
|
||||
|
||||
# Change svg_to_gcode's approximation tolerance
|
||||
TOLERANCES["approximation"] = float(self.options.approximation_tolerance.replace(',', '.'))
|
||||
|
||||
try:
|
||||
assert os.path.isdir(self.options.directory)
|
||||
except:
|
||||
self.debug(f"{self.options.directory} is not a directory")
|
||||
exit(2)
|
||||
|
||||
# Construct output path
|
||||
if self.options.filename:
|
||||
filename = self.options.filename
|
||||
if '.' not in filename:
|
||||
filename += ".gcode"
|
||||
elif self.document_path():
|
||||
filename, extension = self.document_path().split('.')
|
||||
filename = filename.split('/')[-1] + '.gcode'
|
||||
else:
|
||||
filename = "untitled.gcode"
|
||||
|
||||
output_path = os.path.join(self.options.directory, filename)
|
||||
|
||||
if self.options.filename_suffix:
|
||||
filename, extension = output_path.split('.')
|
||||
|
||||
n = 1
|
||||
while os.path.isfile(output_path):
|
||||
output_path = filename + str(n) + '.' + extension
|
||||
n += 1
|
||||
|
||||
# Load header and footer files
|
||||
header = []
|
||||
if self.options.header_path is not None:
|
||||
if os.path.isfile(self.options.header_path):
|
||||
with open(self.options.header_path, 'r') as header_file:
|
||||
header = header_file.read().splitlines()
|
||||
elif self.options.header_path != os.getcwd(): # The Inkscape file selector defaults to the working directory
|
||||
self.debug(f"Header file does not exist at {self.options.header_path}")
|
||||
exit(2)
|
||||
|
||||
footer = []
|
||||
if self.options.footer_path is not None:
|
||||
if os.path.isfile(self.options.footer_path):
|
||||
with open(self.options.footer_path, 'r') as footer_file:
|
||||
footer = footer_file.read().splitlines()
|
||||
elif self.options.footer_path != os.getcwd():
|
||||
self.debug(f"Footer file does not exist at {self.options.footer_path}")
|
||||
exit(2)
|
||||
|
||||
# Customize header/footer
|
||||
custom_interface = generate_custom_interface(self.options.tool_off_command, self.options.tool_power_command)
|
||||
interface_instance = custom_interface()
|
||||
|
||||
if self.options.do_laser_off_start:
|
||||
header.append(interface_instance.laser_off())
|
||||
if self.options.do_laser_off_end:
|
||||
footer.append(interface_instance.laser_off())
|
||||
|
||||
header.append(interface_instance.set_movement_speed(self.options.travel_speed))
|
||||
if self.options.do_z_axis_start:
|
||||
header.append(interface_instance.linear_move(z=self.options.z_axis_start))
|
||||
if self.options.move_to_origin_end:
|
||||
footer.append(interface_instance.linear_move(x=0, y=0))
|
||||
|
||||
# Generate gcode
|
||||
gcode_compiler = Compiler(custom_interface, self.options.travel_speed, self.options.cutting_speed,
|
||||
self.options.pass_depth, dwell_time=self.options.dwell_time, custom_header=header,
|
||||
custom_footer=footer, unit=self.options.unit)
|
||||
|
||||
transformation = Transformation()
|
||||
|
||||
transformation.add_translation(self.options.horizontal_offset, self.options.vertical_offset)
|
||||
transformation.add_scale(self.options.scaling_factor)
|
||||
|
||||
if self.options.machine_origin == "center":
|
||||
transformation.add_translation(-self.options.bed_width / 2, self.options.bed_height / 2)
|
||||
elif self.options.machine_origin == "top-left":
|
||||
transformation.add_translation(0, self.options.bed_height)
|
||||
|
||||
self.clear_debug()
|
||||
curves = parse_root(root, transform_origin=not self.options.invert_y_axis, root_transformation=transformation,
|
||||
canvas_height=self.options.bed_height)
|
||||
|
||||
gcode_compiler.append_curves(curves)
|
||||
gcode_compiler.compile_to_file(output_path, passes=self.options.passes)
|
||||
|
||||
# Draw debug lines
|
||||
if self.options.draw_debug:
|
||||
self.draw_debug_traces(curves)
|
||||
self.draw_unit_reference()
|
||||
self.select_non_debug_layer()
|
||||
|
||||
return self.document
|
||||
|
||||
def draw_debug_traces(self, curves):
|
||||
"""Traces arrows over all parsed paths"""
|
||||
|
||||
root = self.document.getroot()
|
||||
origin = self.options.machine_origin
|
||||
bed_width = self.options.bed_width
|
||||
bed_height = self.options.bed_height
|
||||
|
||||
group = etree.Element("{%s}g" % svg_name_space)
|
||||
group.set("id", "debug_traces")
|
||||
group.set("{%s}groupmode" % inkscape_name_space, "layer")
|
||||
group.set("{%s}label" % inkscape_name_space, "debug traces")
|
||||
|
||||
group.append(
|
||||
etree.fromstring(xml_tree.tostring(debug_methods.arrow_defs(arrow_scale=self.options.debug_arrow_scale))))
|
||||
|
||||
for curve in curves:
|
||||
approximation = LineSegmentChain.line_segment_approximation(curve)
|
||||
|
||||
change_origin = Transformation()
|
||||
|
||||
if not self.options.invert_y_axis:
|
||||
change_origin.add_scale(1, -1)
|
||||
change_origin.add_translation(0, -bed_height)
|
||||
|
||||
if origin == "center":
|
||||
change_origin.add_translation(bed_width / 2, bed_height / 2)
|
||||
|
||||
path_string = xml_tree.tostring(
|
||||
debug_methods.to_svg_path(approximation, color="red", opacity="0.5",
|
||||
stroke_width=f"{self.options.debug_line_width}px",
|
||||
transformation=change_origin, draw_arrows=True)
|
||||
)
|
||||
|
||||
group.append(etree.fromstring(path_string))
|
||||
|
||||
root.append(group)
|
||||
|
||||
def draw_unit_reference(self):
|
||||
"""Draws reference points to mark the bed's four corners"""
|
||||
root = self.document.getroot()
|
||||
unit = self.options.unit
|
||||
origin = self.options.machine_origin
|
||||
bed_width = self.options.bed_width
|
||||
bed_height = self.options.bed_height
|
||||
|
||||
group = etree.Element("{%s}g" % svg_name_space)
|
||||
group.set("id", "debug_references")
|
||||
group.set("{%s}groupmode" % inkscape_name_space, "layer")
|
||||
group.set("{%s}label" % inkscape_name_space, "debug reference points")
|
||||
|
||||
reference_points_svg = [(0, 0), (0, bed_height), (bed_width, 0), (bed_width, bed_height)]
|
||||
reference_points_gcode = {
|
||||
"bottom-left": [(0, bed_height), (0, 0), (bed_width, bed_height), (bed_width, 0)],
|
||||
"top-left": [(0, 0), (0, bed_height), (bed_width, 0), (bed_width, bed_height)],
|
||||
"center": [(-bed_width / 2, bed_height / 2), (-bed_width / 2, -bed_height / 2),
|
||||
(bed_width / 2, bed_height / 2),
|
||||
(bed_width / 2, -bed_height / 2)]
|
||||
}[origin]
|
||||
for i, (x, y) in enumerate(reference_points_svg):
|
||||
reference_point = etree.Element("{%s}g" % svg_name_space)
|
||||
|
||||
stroke_width = 2
|
||||
size = 7
|
||||
|
||||
x_direction = -1 if x > 0 else 1
|
||||
plus_sign = etree.Element("{%s}g" % svg_name_space)
|
||||
horizontal = etree.Element("{%s}line" % svg_name_space)
|
||||
horizontal.set("x1", str(x - x_direction * stroke_width / 2))
|
||||
horizontal.set("y1", str(y))
|
||||
horizontal.set("x2", str(x + x_direction * size))
|
||||
horizontal.set("y2", str(y))
|
||||
horizontal.set("style", f"stroke:black;stroke-width:{stroke_width}")
|
||||
plus_sign.append(horizontal)
|
||||
|
||||
y_direction = -1 if y > 0 else 1
|
||||
vertical = etree.Element("{%s}line" % svg_name_space)
|
||||
vertical.set("x1", str(x))
|
||||
vertical.set("y1", str(y + stroke_width / 2))
|
||||
vertical.set("x2", str(x))
|
||||
vertical.set("y2", str(y + y_direction * size))
|
||||
vertical.set("style", f"stroke:black;stroke-width:{stroke_width}")
|
||||
plus_sign.append(vertical)
|
||||
|
||||
reference_point.append(plus_sign)
|
||||
|
||||
text_box = etree.Element("{%s}text" % svg_name_space)
|
||||
text_box.set("x", str(x - 28))
|
||||
text_box.set("y", str(y - (y <= 0) * 6 + (y > 0) * 9))
|
||||
text_box.set("font-size", "6")
|
||||
text_box.text = f"{reference_points_gcode[i][0]}{unit}, {reference_points_gcode[i][1]}{unit}"
|
||||
reference_point.append(text_box)
|
||||
|
||||
group.append(reference_point)
|
||||
|
||||
root.append(group)
|
||||
|
||||
def select_non_debug_layer(self):
|
||||
"""
|
||||
Select content_layer and create one if it doesn't exist. This helps stop the user from accidentally placing new
|
||||
objects in debug layers.
|
||||
"""
|
||||
|
||||
root = self.document.getroot()
|
||||
|
||||
unique_id = "layer89324"
|
||||
content_layer = root.find("{%s}g[@id='%s']" % (svg_name_space, unique_id))
|
||||
|
||||
if content_layer is None:
|
||||
content_layer = etree.Element("{%s}g" % svg_name_space)
|
||||
content_layer.set("id", unique_id)
|
||||
content_layer.set("{%s}groupmode" % inkscape_name_space, "layer")
|
||||
content_layer.set("{%s}label" % inkscape_name_space, "content layer")
|
||||
|
||||
sodipodi = root.find("{%s}namedview" % sodipodi_name_space)
|
||||
if sodipodi is not None:
|
||||
sodipodi.set("{%s}current-layer" % inkscape_name_space, unique_id)
|
||||
|
||||
root.append(content_layer)
|
||||
|
||||
def clear_debug(self):
|
||||
"""Removes debug groups. Used before parsing paths for gcode."""
|
||||
root = self.document.getroot()
|
||||
|
||||
debug_traces = root.find("{%s}g[@id='debug_traces']" % svg_name_space)
|
||||
debug_references = root.find("{%s}g[@id='debug_references']" % svg_name_space)
|
||||
|
||||
if debug_traces is not None:
|
||||
root.remove(debug_traces)
|
||||
|
||||
if debug_references is not None:
|
||||
root.remove(debug_references)
|
||||
|
||||
def add_arguments(self, arg_parser):
|
||||
"""Tell inkscape what arguments to stick in self.options (behind the hood it's more complicated, see docs)"""
|
||||
arguments = self.read_arguments()
|
||||
|
||||
for arg in arguments:
|
||||
arg_parser.add_argument("--" + arg["name"], type=arg["type"], dest=arg["name"])
|
||||
|
||||
@staticmethod
|
||||
def read_arguments():
|
||||
"""
|
||||
This method reads arguments off of the inx file so you don't have to explicitly declare them in self.add_arguments()
|
||||
"""
|
||||
root = etree.parse(inx_filename).getroot()
|
||||
|
||||
arguments = [] # [{name, type, ...}]
|
||||
namespace = "http://www.inkscape.org/namespace/inkscape/extension"
|
||||
for arg in root.iter("{%s}param" % namespace):
|
||||
|
||||
name = arg.attrib["name"]
|
||||
|
||||
arg_type = arg.attrib["type"]
|
||||
|
||||
if arg_type in ["description", "notebook"]:
|
||||
continue
|
||||
|
||||
types = {"int": int, "float": float, "bool": Boolean, "string": str, "optiongroup": str, "path": str}
|
||||
|
||||
arguments.append({"name": name, "type": types[arg_type]})
|
||||
|
||||
if next(root.iter("{%s}page" % namespace)) is not None:
|
||||
arguments.append({"name": "tabs", "type": str})
|
||||
|
||||
return arguments
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
JTechPhotonicsLaserTool().run()
|
@ -0,0 +1,30 @@
|
||||
[
|
||||
{
|
||||
"name": "J Tech Photonics Laser Tool",
|
||||
"id": "fablabchemnitz.de.j_tech_photonics_laser_tool",
|
||||
"path": "j_tech_photonics_laser_tool",
|
||||
"dependent_extensions": null,
|
||||
"original_name": "J Tech Community Laser Tool",
|
||||
"original_id": "community.jtechphotonics.com",
|
||||
"license": "GNU GPL v2",
|
||||
"license_url": "https://jtechphotonics.com/Downloads/Inkscape/JTP-Laser-Tool_v1.1-beta_ink1.0.zip",
|
||||
"comment": "",
|
||||
"source_url": "https://gitea.fablabchemnitz.de/FabLab_Chemnitz/mightyscape-1.X/src/branch/master/extensions/fablabchemnitz/j_tech_photonics_laser_tool",
|
||||
"fork_url": "https://github.com/JTechPhotonics/J-Tech-Photonics-Laser-Tool",
|
||||
"documentation_url": "https://stadtfabrikanten.org/display/IFM/J+Tech+Photonics+Laser+Tool",
|
||||
"inkscape_gallery_url": null,
|
||||
"main_authors": [
|
||||
"github.com/JTechPhotonics",
|
||||
"github.com/PadLex",
|
||||
"github.com/odaki",
|
||||
"github.com/themanyone",
|
||||
"github.com/drewler",
|
||||
"github.com/nineff",
|
||||
"github.com/4cello",
|
||||
"github.com/dapperfu",
|
||||
"github.com/nmeurer",
|
||||
"github.com/aspeteRakete",
|
||||
"github.com/vmario89"
|
||||
]
|
||||
}
|
||||
]
|
378
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Bendy.py
Executable file
378
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Bendy.py
Executable file
@ -0,0 +1,378 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
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):
|
||||
""" Constructor
|
||||
"""
|
||||
Pattern.__init__(self) # Must be called in order to parse common options
|
||||
|
||||
# save all custom parameters defined on .inx file
|
||||
self.add_argument('--pattern', type=self.str, default='bendy_straw')
|
||||
self.add_argument('--pattern_type', type=self.str, default='origami')
|
||||
self.add_argument('--parameter_type', type=self.str, default='angles')
|
||||
self.add_argument('--n', type=self.int, default=6)
|
||||
self.add_argument('--lines', type=self.int, default=3)
|
||||
self.add_argument('--radius', type=self.float, default=25.0)
|
||||
# self.add_argument('--attachment_length', type=self.float, default=3.0)
|
||||
# self.add_argument('--attachment_length', type=self.int, default=20)
|
||||
self.add_argument('--radial_ratio', type=self.float, default=0.75)
|
||||
# self.add_argument('--alpha1', type=self.float, default=45.0)
|
||||
# self.add_argument('--alpha2', type=self.float, default=45.0)
|
||||
self.add_argument('--alpha1', type=self.int, default=45)
|
||||
self.add_argument('--alpha2', type=self.int, default=35)
|
||||
self.add_argument('--h1', type=self.float, default=1)
|
||||
self.add_argument('--h2', type=self.float, default=2)
|
||||
|
||||
self.add_argument('--vertex_base_outer_bool', type=self.bool, default=False)
|
||||
self.add_argument('--vertex_base_inner_bool', type=self.bool, default=False)
|
||||
self.add_argument('--vertex_radius_outer_bool', type=self.bool, default=False)
|
||||
self.add_argument('--vertex_radius_inner_bool', type=self.bool, default=False)
|
||||
|
||||
self.add_argument('--add_attachment', type=self.bool, default=False)
|
||||
|
||||
# slot options for support ring
|
||||
self.add_argument('--base_height', type=self.float, default=5.0)
|
||||
self.add_argument('--add_base_slot', type=self.bool, default=False)
|
||||
self.add_argument('--center_base_slot', type=self.bool, default=False)
|
||||
self.add_argument('--base_slot_height', type=self.float, default=3.0)
|
||||
self.add_argument('--base_slot_width', type=self.float, default=3.0)
|
||||
self.add_argument('--distance', type=self.float, default=3.0)
|
||||
self.add_argument('--add_distance_slot', type=self.bool, default=False)
|
||||
self.add_argument('--distance_slot_height', type=self.float, default=3.0)
|
||||
self.add_argument('--distance_slot_width', type=self.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
|
||||
|
||||
|
||||
|
||||
#
|
||||
|
||||
# Main function, creates an instance of the Class and calls self.draw() to draw the origami on inkscape
|
||||
# self.draw() is either a call to inkex.affect() or to svg.run(), depending on python version
|
||||
if __name__ == '__main__':
|
||||
e = Bendy_Straw() # remember to put the name of your Class here!
|
||||
e.draw()
|
@ -0,0 +1,98 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
import math
|
||||
import numpy as np
|
||||
from math import pi
|
||||
|
||||
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
|
||||
|
||||
def reflections_diag(path):
|
||||
new_paths = [path]
|
||||
new_paths = new_paths + Path.list_reflect(new_paths, (0, 0), (1, 1))
|
||||
return new_paths + Path.list_reflect(new_paths, (0, 0), (1, -1))
|
||||
|
||||
def reflections_rect(path):
|
||||
new_paths = [path]
|
||||
new_paths = new_paths + Path.list_reflect(new_paths, (0, 0), (0, 1))
|
||||
return new_paths + Path.list_reflect(new_paths, (0, 0), (1, 0))
|
||||
|
||||
def recenter(paths, dist):
|
||||
# paths_new = Path.list_simplify(paths)
|
||||
paths_new = Path.list_rotate(paths, pi/4)
|
||||
return Path.list_add(paths_new, (dist, dist))
|
||||
|
||||
class MasuBox(Pattern):
|
||||
|
||||
def __init__(self):
|
||||
""" Constructor
|
||||
"""
|
||||
Pattern.__init__(self) # Must be called in order to parse common options
|
||||
|
||||
# save all custom parameters defined on .inx file
|
||||
self.add_argument('--pattern', type=self.str, default='boxes_masu')
|
||||
self.add_argument('--width', type=self.float, default=10.0)
|
||||
self.add_argument('--height', type=self.float, default=10.0)
|
||||
self.add_argument('--width_delta', type=self.float, default=0.0)
|
||||
self.add_argument('--width_delta_bool', type=self.bool, default=False)
|
||||
|
||||
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
|
||||
width = self.options.width * unit_factor
|
||||
height = self.options.height * unit_factor
|
||||
if self.options.width_delta_bool:
|
||||
width_delta = self.options.width_delta * unit_factor
|
||||
width += width_delta
|
||||
height -= width_delta/2
|
||||
length = math.sqrt(2)*(width + 2*height)
|
||||
half_fold = 90 if self.options.simulation_mode else 180
|
||||
|
||||
# bottom of box
|
||||
ring_inner = Path.generate_square(width, width, center = [0,0], style = 'm', fold_angle=half_fold)
|
||||
|
||||
# ring making the corners
|
||||
lengths = [height, width, height]
|
||||
points = Path.get_square_points(sum(lengths), sum(lengths), [0,0])
|
||||
styles = ['vmv','mmm']
|
||||
ring_middle = [Path([points[i], points[(i + 1)%4]], 'm').
|
||||
break_path(lengths, styles[i % 2]) for i in range(4)]
|
||||
|
||||
# arms along width and length
|
||||
points = [(-width / 2, -(width / 2 + 0 * height)),
|
||||
(-width / 2, -(width / 2 + 1 * height)),
|
||||
(-width / 2, -(width / 2 + 2 * height)),
|
||||
(+width / 2, -(width / 2 + 2 * height)),
|
||||
(+width / 2, -(width / 2 + 1 * height)),
|
||||
(+width / 2, -(width / 2 + 0 * height))]
|
||||
|
||||
arms_ = [Path.list_create_from_points(points, 'mmvmm', fold_angles = [180, 180, half_fold, 180, 180]),
|
||||
Path.list_create_from_points(points, 'mvvvm', half_fold)]
|
||||
arms = [Path.list_rotate(arms_[i % 2], i * pi / 2) for i in range(4)]
|
||||
|
||||
# tiny corner diagonals
|
||||
diag = Path([(width/2, width/2), (width/2 + height, width/2 + height)], 'v')
|
||||
corner_diagonals = [diag * (1, i*pi/2) for i in range(4)]
|
||||
|
||||
self.edge_points = Path.get_square_points(length, length)
|
||||
|
||||
self.path_tree = [ring_inner, ring_middle, arms, corner_diagonals]
|
||||
self.path_tree = recenter(self.path_tree, length/2)
|
||||
|
||||
# Main function, creates an instance of the Class and calls self.draw() to draw the origami on inkscape
|
||||
# self.draw() is either a call to inkex.affect() or to svg.run(), depending on python version
|
||||
if __name__ == '__main__':
|
||||
e = MasuBox() # remember to put the name of your Class here!
|
||||
e.draw()
|
@ -0,0 +1,54 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
import numpy as np
|
||||
from math import pi
|
||||
|
||||
import inkex
|
||||
import math
|
||||
from Path import Path
|
||||
from Boxes_Masu import MasuBox
|
||||
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
|
||||
|
||||
def reflections_diag(path):
|
||||
new_paths = [path]
|
||||
new_paths = new_paths + Path.list_reflect(new_paths, (0, 0), (1, 1))
|
||||
return new_paths + Path.list_reflect(new_paths, (0, 0), (1, -1))
|
||||
|
||||
def reflections_rect(path):
|
||||
new_paths = [path]
|
||||
new_paths = new_paths + Path.list_reflect(new_paths, (0, 0), (0, 1))
|
||||
return new_paths + Path.list_reflect(new_paths, (0, 0), (1, 0))
|
||||
|
||||
|
||||
class MasuBoxSquare(MasuBox):
|
||||
|
||||
def __init__(self):
|
||||
""" Constructor
|
||||
"""
|
||||
MasuBox.__init__(self) # Must be called in order to parse common options
|
||||
|
||||
# save all custom parameters defined on .inx file
|
||||
self.add_argument('--length', type=self.float, default=10.0)
|
||||
|
||||
def generate_path_tree(self):
|
||||
""" Specialized path generation for your origami pattern
|
||||
"""
|
||||
# retrieve saved parameters, and apply unit factor where needed
|
||||
self.options.width = self.options.length / (2 * math.sqrt(2))
|
||||
self.options.height = self.options.width/2
|
||||
self.options.width_delta = 0.0
|
||||
self.options.width_delta_bool = False
|
||||
MasuBox.generate_path_tree(self)
|
||||
|
||||
|
||||
# Main function, creates an instance of the Class and calls self.draw() to draw the origami on inkscape
|
||||
# self.draw() is either a call to inkex.affect() or to svg.run(), depending on python version
|
||||
if __name__ == '__main__':
|
||||
e = MasuBoxSquare() # remember to put the name of your Class here!
|
||||
e.draw()
|
321
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Cylindrical.py
Executable file
321
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Cylindrical.py
Executable file
@ -0,0 +1,321 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
import numpy as np
|
||||
from abc import abstractmethod
|
||||
from math import pi, sin, cos, tan, asin, acos, atan, sqrt
|
||||
from itertools import accumulate
|
||||
|
||||
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
|
||||
|
||||
def generate_slot_line(n, slot_position,
|
||||
slot_height, slot_width,
|
||||
base_height, base_width):
|
||||
|
||||
if slot_height == 0 and slot_width == 0:
|
||||
return []
|
||||
|
||||
slot_height = min(slot_height, base_height)
|
||||
slot_width = min(slot_width, base_width)
|
||||
|
||||
rect = [ (0, 0),
|
||||
(0, slot_height),
|
||||
(slot_width, slot_height),
|
||||
(slot_width, 0)]
|
||||
|
||||
dx = (base_width - slot_width) / 2
|
||||
if slot_position == -1:
|
||||
dy = 0
|
||||
elif slot_position == 0:
|
||||
dy = (base_height - slot_height) / 2
|
||||
elif slot_position == +1:
|
||||
dy = base_height - slot_height
|
||||
|
||||
slot = Path(rect, 'c', closed=True) + (dx, dy)
|
||||
slots = [slot + (base_width * i, 0) for i in range(n)]
|
||||
|
||||
divider = Path([(base_width, 0), (base_width, base_height)], style='m')
|
||||
dividers = [divider + (base_width*i, 0) for i in range(n-1)]
|
||||
return slots + dividers
|
||||
|
||||
class Cylindrical(Pattern):
|
||||
|
||||
def __init__(self):
|
||||
""" Constructor
|
||||
"""
|
||||
Pattern.__init__(self) # Must be called in order to parse common options
|
||||
|
||||
# save all custom parameters defined on .inx file
|
||||
self.add_argument('--radius', type=self.float, default=10.0)
|
||||
self.add_argument('--sides', type=self.int, default=6)
|
||||
self.add_argument('--rows', type=self.int, default=3)
|
||||
self.add_argument('--extra_column', type=self.bool, default=False)
|
||||
|
||||
# slot options for support ring
|
||||
self.add_argument('--add_base_slot', type=self.bool, default=False)
|
||||
self.add_argument('--base_slot_position', type=self.str, default="1")
|
||||
self.add_argument('--base_height', type=self.float, default=5.0)
|
||||
self.add_argument('--base_slot_height', type=self.float, default=3.0)
|
||||
self.add_argument('--base_slot_width', type=self.float, default=3.0)
|
||||
|
||||
self.add_argument('--add_middle_slot', type=self.bool, default=False)
|
||||
self.add_argument('--middle_slot_position', type=self.str, default="0")
|
||||
self.add_argument('--distance', type=self.float, default=3.0)
|
||||
self.add_argument('--middle_slot_height', type=self.float, default=3.0)
|
||||
self.add_argument('--middle_slot_width', type=self.float, default=3.0)
|
||||
|
||||
@abstractmethod
|
||||
def parse_parameters(self):
|
||||
"""
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def generate_cell(self):
|
||||
""" Generate the the origami cell
|
||||
"""
|
||||
pass
|
||||
|
||||
def generate_path_tree(self):
|
||||
""" Specialized path generation for your origami pattern
|
||||
"""
|
||||
# zero distances when slot option not selected
|
||||
if not self.options.add_base_slot:
|
||||
self.options.base_height = 0
|
||||
self.options.base_slot_height = 0
|
||||
if not self.options.add_middle_slot:
|
||||
self.options.distance = 0
|
||||
self.options.middle_slot_height = 0
|
||||
if self.options.base_height == 0:
|
||||
self.options.add_base_slot = False
|
||||
if self.options.distance == 0:
|
||||
self.options.add_middle_slot = False
|
||||
|
||||
self.parse_parameters()
|
||||
|
||||
# pre-calculate width before adding one to sides, for easier attachment
|
||||
self.options.width = 2 * self.options.radius * sin(pi / self.options.sides)
|
||||
|
||||
self.options.cols = self.options.sides + self.options.extra_column
|
||||
|
||||
# get cell definitions
|
||||
cell_data = self.generate_cell()
|
||||
|
||||
# calculate divider if it doesn't exist
|
||||
if 'divider' not in cell_data:
|
||||
points = Path.get_points(cell_data['interior'])
|
||||
x = [p[0] for p in points if p[1] == 0]
|
||||
cell_data['divider'] = Path([(min(x), 0),
|
||||
(max(x), 0)], style='m')
|
||||
|
||||
points = Path.get_points(cell_data['divider'])
|
||||
x = [p[0] for p in points]
|
||||
DX = max(x) - min(x)
|
||||
# DX = 0
|
||||
|
||||
# if 'edge_right' not in cell_data and 'edge_left' not in cell_data:
|
||||
# cell_data['edge_left'] = []
|
||||
# for interior in cell_data['interior']:
|
||||
# points = Path.get_points(interior)
|
||||
# x = [p[0] for p in points]
|
||||
# y = [p[1] for p in points]
|
||||
# top = [p for p in points if p[1] == min(y)]
|
||||
# top_x = [p[0] for p in top]
|
||||
# # top_y = [p[1] for p in top]
|
||||
# bot = [p for p in points if p[1] == max(y)]
|
||||
# bot_x = [p[0] for p in bot]
|
||||
# # bot_y = [p[1] for p in bot]
|
||||
# top_left = [p for p in top if p[0] == min(top_x)][0]
|
||||
# bot_left = [p for p in bot if p[0] == min(bot_x)][0]
|
||||
# cell_data['edge_left'].append(Path([top_left, bot_left], 'e'))
|
||||
|
||||
|
||||
if 'edge_right' not in cell_data and 'edge_left' in cell_data:
|
||||
cell_data['edge_right'] = []
|
||||
for edge_left in cell_data['edge_left']:
|
||||
edge_right = edge_left + (DX, 0)
|
||||
edge_right.invert()
|
||||
cell_data['edge_right'].append(edge_right)
|
||||
|
||||
if 'edge_right' in cell_data and 'edge_left' not in cell_data:
|
||||
cell_data['edge_left'] = []
|
||||
for edge_right in cell_data['edge_right']:
|
||||
edge_left = edge_right + (-DX, 0)
|
||||
edge_left.invert()
|
||||
cell_data['edge_left'].append(edge_left)
|
||||
|
||||
cell_data['dx'], cell_data['dy'] = self.get_dxdy(cell_data)
|
||||
|
||||
# get all slots and vertical dividers between slots
|
||||
base, middle = self.generate_all_slots(cell_data)
|
||||
slots = [[base['slots'], middle['slots']]]
|
||||
|
||||
# get horizontal dividers between cells
|
||||
dividers = self.generate_horizontal_dividers(cell_data)
|
||||
|
||||
# finish by replicating the actual interior
|
||||
interior = self.generate_interior(cell_data)
|
||||
|
||||
# use slots and cell data to create the full edge paths
|
||||
self.edge_points = self.generate_fused_edge_points(base, middle, cell_data)
|
||||
|
||||
self.path_tree = [dividers, interior]
|
||||
if len(self.vertex_points) == 0:
|
||||
self.vertex_points = Path.get_points(self.path_tree)
|
||||
self.path_tree.append(slots)
|
||||
|
||||
def get_dxdy(self, cell_data):
|
||||
dx = [0]
|
||||
dy = [0]
|
||||
for edge in cell_data['edge_left']:
|
||||
dx.append(edge.points[1][0] - edge.points[0][0])
|
||||
dy.append(edge.points[1][1] - edge.points[0][1])
|
||||
return list(accumulate(dx)), list(accumulate(dy))
|
||||
|
||||
|
||||
def generate_interior(self, cell_data):
|
||||
# retrieve conversion factor for selected unit
|
||||
unit_factor = self.calc_unit_factor()
|
||||
rows = self.options.rows
|
||||
base_height = self.options.base_height * unit_factor
|
||||
distance = self.options.distance * unit_factor
|
||||
|
||||
interiors = []
|
||||
|
||||
for i in range(rows):
|
||||
dx = cell_data['dx'][i]
|
||||
dy = cell_data['dy'][i] + base_height + i * distance
|
||||
pattern = cell_data['interior'][i]
|
||||
interiors.append(Path.list_add(pattern, (dx, dy)))
|
||||
|
||||
return interiors
|
||||
|
||||
|
||||
def generate_horizontal_dividers(self, cell_data):
|
||||
# retrieve conversion factor for selected unit
|
||||
unit_factor = self.calc_unit_factor()
|
||||
rows = self.options.rows
|
||||
base_height = self.options.base_height * unit_factor
|
||||
distance = self.options.distance * unit_factor
|
||||
|
||||
divider = cell_data['divider']
|
||||
dividers = []
|
||||
|
||||
if self.options.add_base_slot:
|
||||
dividers.append(divider + (0, base_height))
|
||||
|
||||
for i in range(1, rows):
|
||||
dx = cell_data['dx'][i]
|
||||
dy = cell_data['dy'][i] + base_height + (i - 1) * distance
|
||||
dividers.append(divider + (dx, dy))
|
||||
if self.options.add_middle_slot:
|
||||
dividers.append(divider + (dx, dy + distance))
|
||||
|
||||
if self.options.add_base_slot:
|
||||
dx = cell_data['dx'][-1]
|
||||
dy = cell_data['dy'][-1] + base_height + (rows - 1) * distance
|
||||
dividers.append(divider + (dx, dy))
|
||||
|
||||
return dividers
|
||||
# pass
|
||||
|
||||
|
||||
def generate_all_slots(self, cell_data):
|
||||
dx_ = cell_data['dx']
|
||||
dy_ = cell_data['dy']
|
||||
|
||||
# retrieve conversion factor for selected unit
|
||||
unit_factor = self.calc_unit_factor()
|
||||
|
||||
# retrieve saved parameters, and apply unit factor where needed
|
||||
cols = self.options.cols
|
||||
rows = self.options.rows
|
||||
width = self.options.width * unit_factor
|
||||
|
||||
dist = self.options.distance * unit_factor
|
||||
base_height = self.options.base_height * unit_factor
|
||||
height = [dy_[i] + base_height + (i - 1) * dist for i in range(rows+1)]
|
||||
|
||||
base = {'left': [],
|
||||
'right': [],
|
||||
'slots': []}
|
||||
|
||||
if self.options.add_base_slot:
|
||||
base_slot_height = self.options.base_slot_height * unit_factor
|
||||
base_slot_width = self.options.base_slot_width * unit_factor
|
||||
base_slot_sizes = [base_slot_height, base_slot_width, base_height, width]
|
||||
|
||||
base_slot_top = generate_slot_line(cols, +int(self.options.base_slot_position), *base_slot_sizes)
|
||||
base_slot_bot = generate_slot_line(cols, -int(self.options.base_slot_position), *base_slot_sizes)
|
||||
|
||||
base['slots'] = [base_slot_top, Path.list_add(base_slot_bot, (dx_[-1], height[-1]))]
|
||||
|
||||
base['left'] = [Path([(0, 0), (0, base_height)], style = 'e'),
|
||||
Path([(dx_[-1], height[-1]),
|
||||
(dx_[-1], height[-1] + base_height)], style = 'e')]
|
||||
|
||||
base['right'] = [Path([(dx_[-1] + cols*width, height[-1] + base_height),
|
||||
(dx_[-1] + cols*width, height[-1] + base_height)], style = 'e'),
|
||||
Path([(cols*width, base_height),
|
||||
(cols*width, 0)], style = 'e')]
|
||||
|
||||
middle = {'left': [],
|
||||
'right': [],
|
||||
'slots': []}
|
||||
|
||||
if self.options.add_middle_slot:
|
||||
middle_slot_height = self.options.middle_slot_height * unit_factor
|
||||
middle_slot_width = self.options.middle_slot_width * unit_factor
|
||||
middle_slot_sizes = [middle_slot_height, middle_slot_width, dist, width]
|
||||
|
||||
middle_slot = generate_slot_line(cols, +int(self.options.middle_slot_position), *middle_slot_sizes)
|
||||
|
||||
middle['slots'] = [Path.list_add(middle_slot,
|
||||
(dx_[i], height[i]))
|
||||
for i in range(1, rows)]
|
||||
|
||||
middle['left'] = [Path([(0, 0),
|
||||
(0, dist)], style='e') +
|
||||
(dx_[i+1], dy_[1] + dist + height[i]) for i in range(rows-1)]
|
||||
middle['right'] = [
|
||||
Path([(0, height[rows-2] + base_height + (rows - 1) * dist),
|
||||
(0, dy_[-2] + base_height + (rows - 2) * dist)], style='e') +
|
||||
(dx_[-(i+2)] + cols*width, -dy_[i] - i*dist) for i in range(rows - 1)]
|
||||
|
||||
return base, middle
|
||||
|
||||
def generate_fused_edge_points(self, base, middle, cell_data):
|
||||
unit_factor = self.calc_unit_factor()
|
||||
base_height = self.options.base_height * unit_factor
|
||||
distance = self.options.distance * unit_factor
|
||||
rows = self.options.rows
|
||||
|
||||
edges = []
|
||||
if self.options.add_base_slot: edges.append(base['left'][0])
|
||||
for i in range(rows):
|
||||
cell_left = cell_data['edge_left'][i]
|
||||
dx = cell_data['dx'][i]
|
||||
edges.append(cell_left + (dx, cell_data['dy'][i] + base_height + i * distance))
|
||||
if self.options.add_middle_slot and i < rows - 1:
|
||||
edges.append(middle['left'][i] + (0, 0))
|
||||
if self.options.add_base_slot: edges.append(base['left'][1])
|
||||
|
||||
if self.options.add_base_slot: edges.append(base['right'][0])
|
||||
for i in range(rows):
|
||||
cell_right = cell_data['edge_right'][-(i + 1)]
|
||||
dx = cell_data['dx'][-(i + 2)]
|
||||
edges.append(cell_right + (dx, cell_data['dy'][rows - i - 1] + base_height + (rows - i - 1) * distance))
|
||||
if self.options.add_middle_slot and i < rows - 1:
|
||||
edges.append(middle['right'][i] + (0, 0))
|
||||
if self.options.add_base_slot: edges.append(base['right'][1])
|
||||
|
||||
return Path.get_points(edges)
|
||||
|
377
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Cylindrical_Bendy.py
Executable file
377
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Cylindrical_Bendy.py
Executable file
@ -0,0 +1,377 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
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):
|
||||
""" Constructor
|
||||
"""
|
||||
Pattern.__init__(self) # Must be called in order to parse common options
|
||||
|
||||
# save all custom parameters defined on .inx file
|
||||
self.add_argument('--pattern', type=self.str, default='bendy_straw')
|
||||
self.add_argument('--pattern_type', type=self.str, default='origami')
|
||||
self.add_argument('--parameter_type', type=self.str, default='angles')
|
||||
self.add_argument('--n', type=self.int, default=6)
|
||||
self.add_argument('--lines', type=self.int, default=3)
|
||||
self.add_argument('--radius', type=self.float, default=25.0)
|
||||
# self.add_argument('--attachment_length', type=self.float, default=3.0)
|
||||
# self.add_argument('--attachment_length', type=self.int, default=20)
|
||||
self.add_argument('--radial_ratio', type=self.float, default=0.75)
|
||||
# self.add_argument('--alpha1', type=self.float, default=45.0)
|
||||
# self.add_argument('--alpha2', type=self.float, default=45.0)
|
||||
self.add_argument('--alpha1', type=self.int, default=45)
|
||||
self.add_argument('--alpha2', type=self.int, default=35)
|
||||
self.add_argument('--h1', type=self.float, default=1)
|
||||
self.add_argument('--h2', type=self.float, default=2)
|
||||
|
||||
self.add_argument('--vertex_base_outer_bool', type=self.bool, default=False)
|
||||
self.add_argument('--vertex_base_inner_bool', type=self.bool, default=False)
|
||||
self.add_argument('--vertex_radius_outer_bool', type=self.bool, default=False)
|
||||
self.add_argument('--vertex_radius_inner_bool', type=self.bool, default=False)
|
||||
|
||||
self.add_argument('--add_attachment', type=self.bool, default=False)
|
||||
|
||||
# slot options for support ring
|
||||
self.add_argument('--base_height', type=self.float, default=5.0)
|
||||
self.add_argument('--add_base_slot', type=self.bool, default=False)
|
||||
self.add_argument('--center_base_slot', type=self.bool, default=False)
|
||||
self.add_argument('--base_slot_height', type=self.float, default=3.0)
|
||||
self.add_argument('--base_slot_width', type=self.float, default=3.0)
|
||||
self.add_argument('--distance', type=self.float, default=3.0)
|
||||
self.add_argument('--add_distance_slot', type=self.bool, default=False)
|
||||
self.add_argument('--distance_slot_height', type=self.float, default=3.0)
|
||||
self.add_argument('--distance_slot_width', type=self.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
|
||||
|
||||
|
||||
|
||||
#
|
||||
|
||||
# Main function, creates an instance of the Class and calls self.draw() to draw the origami on inkscape
|
||||
# self.draw() is either a call to inkex.affect() or to svg.run(), depending on python version
|
||||
if __name__ == '__main__':
|
||||
e = Bendy_Straw() # remember to put the name of your Class here!
|
||||
e.draw()
|
@ -0,0 +1,163 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
from math import pi, sin, asin, cos, tan, acos, sqrt
|
||||
import inkex
|
||||
import os
|
||||
|
||||
from Path import Path
|
||||
from Pattern import Pattern
|
||||
from Cylindrical import Cylindrical
|
||||
|
||||
|
||||
class Kresling(Cylindrical):
|
||||
|
||||
def __init__(self):
|
||||
""" Constructor
|
||||
"""
|
||||
Cylindrical.__init__(self) # Must be called in order to parse common options
|
||||
|
||||
self.add_argument('--pattern', type=self.str, default="kresling")
|
||||
|
||||
self.add_argument('--measure_value', type=self.float, default=10.0)
|
||||
self.add_argument('--measure_type', type=self.str, default=60)
|
||||
self.add_argument('--parameter_type', type=self.str, default=60)
|
||||
self.add_argument('--radial_ratio', type=self.float, default=0.5)
|
||||
self.add_argument('--angle_ratio', type=self.float, default=0.5)
|
||||
self.add_argument('--lambdatheta', type=self.float, default=45)
|
||||
|
||||
def parse_parameters(self):
|
||||
n = self.options.sides
|
||||
theta = pi * (n - 2) / (2 * n)
|
||||
# define ratio parameter
|
||||
parameter = self.options.parameter_type
|
||||
if parameter == 'radial_ratio':
|
||||
radial_ratio = self.options.radial_ratio
|
||||
max_radial_ratio = sin((pi / 4) * (1. - 2. / n))
|
||||
if radial_ratio > max_radial_ratio:
|
||||
inkex.errormsg(
|
||||
_("For polygon of {} sides, the maximal radial ratio is = {}".format(n, max_radial_ratio)))
|
||||
radial_ratio = max_radial_ratio
|
||||
self.options.angle_ratio = 1 - 2 * n * asin(radial_ratio) / ((n - 2) * pi)
|
||||
|
||||
elif parameter == 'lambdatheta':
|
||||
lambdatheta = self.options.lambdatheta
|
||||
angle_min = 45. * (1 - 2. / n)
|
||||
angle_max = 2 * angle_min
|
||||
if lambdatheta < angle_min:
|
||||
inkex.errormsg(_(
|
||||
"For polygon of {} sides, phi must be between {} and {} degrees, \nsetting lambda*theta = {}\n".format(
|
||||
n, angle_min, angle_max, angle_min)))
|
||||
lambdatheta = angle_min
|
||||
elif lambdatheta > angle_max:
|
||||
inkex.errormsg(_(
|
||||
"For polygon of {} sides, phi must be between {} and {} degrees, \nsetting lambda*theta = {}\n".format(
|
||||
n, angle_min, angle_max, angle_max)))
|
||||
lambdatheta = angle_max
|
||||
self.options.angle_ratio = lambdatheta * n / (90. * (n - 2.))
|
||||
|
||||
# define some length
|
||||
mtype = self.options.measure_type
|
||||
mvalue = self.options.measure_value
|
||||
angle_ratio = self.options.angle_ratio
|
||||
if mtype == 'a':
|
||||
radius = 0.5 * mvalue / (sin(pi / n))
|
||||
if mtype == 'b':
|
||||
A = cos(theta * (1 - angle_ratio))
|
||||
B = sin(pi / n)
|
||||
C = cos(theta * angle_ratio)
|
||||
radius = 0.5 * mvalue / sqrt(A ** 2 + B ** 2 - 2 * A * B * C)
|
||||
elif mtype == 'l':
|
||||
radius = 0.5 * mvalue / cos(theta * (1 - angle_ratio))
|
||||
elif mtype == 'radius_external':
|
||||
radius = mvalue
|
||||
elif mtype == 'radius_internal':
|
||||
radius = mvalue / (sin(theta * (1 - angle_ratio)))
|
||||
elif mtype == 'diameter_external':
|
||||
radius = 0.5 * mvalue
|
||||
elif mtype == 'diameter_internal':
|
||||
radius = 0.5 * mvalue / sin(theta * (1 - angle_ratio))
|
||||
|
||||
if self.options.pattern == 'mirrowed':
|
||||
self.options.mirror_cells = True
|
||||
else:
|
||||
self.options.mirror_cells = False
|
||||
self.options.radius = radius
|
||||
|
||||
def generate_cell(self):
|
||||
""" Generate the the origami cell
|
||||
"""
|
||||
# retrieve conversion factor for selected unit
|
||||
unit_factor = self.calc_unit_factor()
|
||||
rows = self.options.rows
|
||||
sides = self.options.sides
|
||||
cols = self.options.cols
|
||||
radius = self.options.radius * unit_factor
|
||||
width = self.options.width * unit_factor
|
||||
# vertex_radius = self.options.vertex_radius * unit_factor
|
||||
|
||||
angle_ratio = self.options.angle_ratio
|
||||
mirror_cells = self.options.mirror_cells
|
||||
|
||||
theta = (pi/2.)*(1 - 2./sides)
|
||||
l = 2.*radius*cos(theta*(1.-angle_ratio))
|
||||
dy = l * sin(theta * angle_ratio)
|
||||
dx = l * cos(theta * angle_ratio) - width
|
||||
|
||||
# init dict that holds everything
|
||||
cell_data = {}
|
||||
|
||||
# divider (supposed to be the same)
|
||||
cell_data['divider'] = Path([(0, 0), (width * cols, 0)], style='m')
|
||||
|
||||
# IMPORTANT: left edges from TOP to BOTTOM
|
||||
edge_left = [Path([(0, 0), (dx, dy)], style='e')]
|
||||
if mirror_cells:
|
||||
edge_left.append(Path([(0, 0), (-dx, dy)], style='e'))
|
||||
cell_data['edge_left'] = [edge_left[i % (1 + mirror_cells)] for i in range(rows)]
|
||||
|
||||
# IMPORTANT: right edges from BOTTOM to TOP
|
||||
edge_right = [Path([(cols * width + dx, dy), (cols * width, 0)], style='e')]
|
||||
if mirror_cells:
|
||||
edge_right.append(Path([(cols * width - dx, dy), (cols * width, 0)], style='e'))
|
||||
cell_data['edge_right'] = [edge_right[i % (1 + mirror_cells)] for i in range(rows)]
|
||||
|
||||
# rest of cell
|
||||
zigzags = [Kresling.generate_kresling_zigzag(sides, cols, radius, angle_ratio)]
|
||||
if mirror_cells:
|
||||
zigzags.append(Path.list_reflect(zigzags[0], (0, dy / 2), (dx, dy / 2)))
|
||||
zigzags[1] = Path.list_add(zigzags[1], (-dx, 0))
|
||||
|
||||
cell_data['interior'] = [zigzags[i % (1 + mirror_cells)] for i in range(rows)]
|
||||
|
||||
return cell_data
|
||||
|
||||
@staticmethod
|
||||
def generate_kresling_zigzag(sides, cols, radius, angle_ratio):
|
||||
# def generate_kresling_zigzag(sides, radius, angle_ratio, add_attachment):
|
||||
|
||||
theta = (pi / 2.) * (1 - 2. / sides)
|
||||
l = 2. * radius * cos(theta * (1. - angle_ratio))
|
||||
a = 2. * radius * sin(pi / sides)
|
||||
dy = l * sin(theta * angle_ratio)
|
||||
dx = l * cos(theta * angle_ratio) - a
|
||||
|
||||
points = []
|
||||
styles = []
|
||||
|
||||
for i in range(cols):
|
||||
points.append((i * a, 0))
|
||||
points.append(((i + 1) * a + dx, dy))
|
||||
styles.append('v')
|
||||
if i != cols - 1:
|
||||
styles.append('m')
|
||||
# elif add_attachment:
|
||||
# points.append((sides * a, 0))
|
||||
# styles.append('m')
|
||||
|
||||
path = Path.generate_separated_paths(points, styles)
|
||||
return path
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
e = Kresling()
|
||||
e.draw()
|
@ -0,0 +1,73 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
import numpy as np
|
||||
from abc import abstractmethod
|
||||
from math import pi, sin, cos, tan, asin, acos, atan, sqrt
|
||||
|
||||
import inkex
|
||||
|
||||
from Path import Path
|
||||
from Pattern import Pattern
|
||||
from Cylindrical import Cylindrical
|
||||
|
||||
|
||||
# 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
|
||||
|
||||
class Template(Cylindrical):
|
||||
|
||||
def __init__(self):
|
||||
""" Constructor
|
||||
"""
|
||||
Cylindrical.__init__(self) # Must be called in order to parse common options
|
||||
|
||||
# save all custom parameters defined on .inx file
|
||||
self.add_argument('--pattern', type=self.str, default='cylindrical_template')
|
||||
self.add_argument('--length', type=self.float, default=10.)
|
||||
self.add_argument('--angle', type=self.int, default=0)
|
||||
|
||||
def generate_cell(self):
|
||||
""" Generate the the origami cell
|
||||
"""
|
||||
# retrieve conversion factor for selected unit
|
||||
unit_factor = self.calc_unit_factor()
|
||||
sides = self.options.sides
|
||||
cols = self.options.cols
|
||||
rows = self.options.rows
|
||||
|
||||
length = self.options.length * unit_factor
|
||||
angle = self.options.angle * unit_factor
|
||||
width = self.options.width * unit_factor # use pre-calculated width
|
||||
|
||||
dx = length * sin(pi * angle / 180)
|
||||
dy = length * cos(pi * angle / 180)
|
||||
|
||||
# init dict that holds everything
|
||||
cell_data = {}
|
||||
|
||||
# divider can be set for performance, or it can be calculated automatically, supposing a mountain fold
|
||||
# cell_data['divider'] = Path([(0,0), (width*cols, 0)], style='m')
|
||||
|
||||
# Only left or right edges can be implemented, or both for performance
|
||||
# IMPORTANT: left edges from TOP to BOTTOM
|
||||
cell_data['edge_left'] = [Path([(0,0), (dx, dy)], style='e')]*rows
|
||||
|
||||
# # IMPORTANT: right edges from BOTTOM to TOP
|
||||
# cell_data['edge_right'] = [Path([(cols*width + dx, dy), (cols*width, 0)], style='e')]*rows
|
||||
|
||||
# rest of cell
|
||||
single = [Path([(0, 0), (width + dx, dy)], 'v'), Path([(width + dx, dy), (width, 0)], 'm')]
|
||||
pattern = [Path.list_add(single, (width*i, 0)) for i in range(cols)]
|
||||
pattern = Path.list_simplify(pattern)
|
||||
cell_data['interior'] = [pattern]*rows
|
||||
|
||||
return cell_data
|
||||
|
||||
|
||||
# Main function, creates an instance of the Class and calls self.draw() to draw the origami on inkscape
|
||||
# self.draw() is either a call to inkex.affect() or to svg.run(), depending on python version
|
||||
if __name__ == '__main__':
|
||||
e = Template() # remember to put the name of your Class here!
|
||||
e.draw()
|
122
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Hypar.py
Executable file
122
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Hypar.py
Executable file
@ -0,0 +1,122 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
import numpy as np
|
||||
|
||||
from math import pi, tan, sqrt, sin, cos
|
||||
|
||||
import inkex
|
||||
|
||||
from Path import Path
|
||||
from Pattern import Pattern
|
||||
|
||||
|
||||
class Hypar(Pattern):
|
||||
|
||||
def __init__(self):
|
||||
""" Constructor
|
||||
"""
|
||||
Pattern.__init__(self) # Must be called in order to parse common options
|
||||
|
||||
# save all custom parameters defined on .inx file
|
||||
self.add_argument('--pattern', type=self.str, default='template1')
|
||||
self.add_argument('--radius', type=self.float, default=10.0)
|
||||
self.add_argument('--sides', type=self.int, default=4)
|
||||
self.add_argument('--rings', type=self.int, default=7)
|
||||
self.add_argument('--simplify_center', type=self.bool, default=0)
|
||||
|
||||
def generate_path_tree(self):
|
||||
""" Specialized path generation for your origami pattern
|
||||
"""
|
||||
# retrieve saved parameters
|
||||
unit_factor = self.calc_unit_factor()
|
||||
vertex_radius = self.options.vertex_radius * unit_factor
|
||||
pattern = self.options.pattern
|
||||
radius = self.options.radius * unit_factor
|
||||
sides = self.options.sides
|
||||
rings = self.options.rings
|
||||
simplify_center = self.options.simplify_center
|
||||
sin_ = sin(pi / float(sides))
|
||||
a = radius*sin_ # half of length of polygon side
|
||||
H = radius*sqrt(1 - sin_**2)
|
||||
|
||||
polygon = Path.generate_polygon(sides, radius, 'e')
|
||||
|
||||
# # OLD diagonals generation with universal creases
|
||||
# diagonals = []
|
||||
# for i in range(sides):
|
||||
# diagonals.append(Path([(0, 0), polygon.points[i]], 'u'))
|
||||
# points = [(x, y) for x, y in polygon.points]
|
||||
# diagonals = diagonals + [Path.generate_separated_paths(points, 'm')]
|
||||
|
||||
# # modify center if needed
|
||||
# if simplify_center:
|
||||
# for i in range(sides):
|
||||
# if i % 2 == 0:
|
||||
# p2 = diagonals[i].points[1]
|
||||
# diagonals[i].points[0] = (1. / (rings + 1) * p2[0], 1. / (rings + 1) * p2[1])
|
||||
|
||||
# separate generic closed ring to create edges
|
||||
self.edge_points = polygon.points
|
||||
|
||||
# vertex and diagonal lines creation
|
||||
vertex_line = []
|
||||
diagonal_line = []
|
||||
for i in range(1, rings + 2):
|
||||
y1 = a * (float(i - 1) / (rings + 1.))
|
||||
x1 = H * float(i - 1) / (rings + 1.)
|
||||
y2 = a * (float(i) / (rings + 1.))
|
||||
x2 = H * float(i) / (rings + 1.)
|
||||
vertex_line.append((Path((x2, y2), style='p', radius=vertex_radius)))
|
||||
diagonal_line.append((Path([(x1, y1), (x2, y2)], style='m' if i % 2 else 'v')))
|
||||
|
||||
# rotation of vertices and diagonals for completing the drawing
|
||||
diagonals = []
|
||||
vertices = [Path((0, 0), style='p', radius=vertex_radius)]
|
||||
for i in range(sides):
|
||||
vertices = vertices+Path.list_rotate(vertex_line, i * 2 * pi / float(sides))
|
||||
diagonals = diagonals+[Path.list_rotate(diagonal_line, i * 2 * pi / float(sides))]
|
||||
|
||||
# modify center if needed
|
||||
if simplify_center:
|
||||
for i in range(sides):
|
||||
if i % 2 == 0:
|
||||
del diagonals[i][0]
|
||||
|
||||
# inkex.debug(len(diagonals))
|
||||
# inkex.debug(len(diagonals[0]))
|
||||
# diagonals = diagonals + diagonal
|
||||
|
||||
# scale generic closed ring to create inner rings
|
||||
inner_rings = []
|
||||
for i in range(rings + 1):
|
||||
inner_rings.append(polygon * (float(i)/(rings+1)))
|
||||
inner_rings[i].style = 'v' if i % 2 else 'm'
|
||||
|
||||
# create points for zig zag pattern
|
||||
zig_zags = []
|
||||
if pattern != "classic":
|
||||
zig_zag = []
|
||||
for i in range(1, rings + 1):
|
||||
y_out = a * ((i + 1.) / (rings + 1.))
|
||||
y_in = a * (float(i) / (rings + 1.))
|
||||
x_out = H * (i + 1.) / (rings + 1.)
|
||||
x_in = H * float(i) / (rings + 1.)
|
||||
|
||||
if pattern == "alternate_asymmetric" and i % 2:
|
||||
zig_zag.append(Path([(x_in, -y_in), (x_out, +y_out)], style='u'))
|
||||
else:
|
||||
zig_zag.append(Path([(x_in, +y_in), (x_out, -y_out)], style='u'))
|
||||
|
||||
# reflect zig zag pattern to create all sides
|
||||
zig_zags.append(zig_zag)
|
||||
for i in range(sides - 1):
|
||||
points = diagonals[i][0].points
|
||||
zig_zags.append(Path.list_reflect(zig_zags[i], points[0], points[1]))
|
||||
|
||||
self.translate = (radius, radius)
|
||||
self.path_tree = [diagonals, zig_zags, inner_rings, vertices]
|
||||
|
||||
# Main function, creates an instance of the Class and calls inkex.affect() to draw the origami on inkscape
|
||||
if __name__ == '__main__':
|
||||
e = Hypar() # remember to put the name of your Class here!
|
||||
e.draw()
|
162
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Kresling.py
Executable file
162
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Kresling.py
Executable file
@ -0,0 +1,162 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
from math import pi, sin, cos, tan, acos, sqrt
|
||||
import inkex
|
||||
import os
|
||||
|
||||
from Path import Path
|
||||
from Pattern import Pattern
|
||||
|
||||
|
||||
class Kresling(Pattern):
|
||||
|
||||
def __init__(self):
|
||||
""" Constructor
|
||||
"""
|
||||
Pattern.__init__(self) # Must be called in order to parse common options
|
||||
|
||||
self.add_argument('--pattern', type=self.str, default="kresling")
|
||||
self.add_argument('--lines', type=self.int, default=1)
|
||||
self.add_argument('--sides', type=self.int, default=3)
|
||||
self.add_argument('--add_attachment', type=self.bool, default=False)
|
||||
self.add_argument('--attachment_percentage', type=self.float, default=100.)
|
||||
self.add_argument('--mirror_cells', type=self.bool, default=False)
|
||||
|
||||
@staticmethod
|
||||
def generate_kresling_zigzag(sides, radius, angle_ratio, add_attachment):
|
||||
|
||||
theta = (pi / 2.) * (1 - 2. / sides)
|
||||
l = 2. * radius * cos(theta * (1. - angle_ratio))
|
||||
a = 2. * radius * sin(pi / sides)
|
||||
# b = sqrt(a * a + l * l - 2 * a * l * cos(angle_ratio * theta))
|
||||
# phi = abs(acos((l * l + b * b - a * a) / (2 * l * b)))
|
||||
# gamma = pi / 2 - angle_ratio * theta - phi
|
||||
dy = l * sin(theta * angle_ratio)
|
||||
dx = l * cos(theta * angle_ratio) - a
|
||||
|
||||
points = []
|
||||
styles = []
|
||||
|
||||
for i in range(sides):
|
||||
points.append((i * a, 0))
|
||||
points.append(((i + 1) * a + dx, -dy))
|
||||
styles.append('v')
|
||||
if i != sides - 1:
|
||||
styles.append('m')
|
||||
elif add_attachment:
|
||||
points.append((sides * a, 0))
|
||||
styles.append('m')
|
||||
|
||||
path = Path.generate_separated_paths(points, styles)
|
||||
return path
|
||||
|
||||
def generate_path_tree(self):
|
||||
""" Specialized path generation for Waterbomb tesselation pattern
|
||||
"""
|
||||
unit_factor = self.calc_unit_factor()
|
||||
vertex_radius = self.options.vertex_radius * unit_factor
|
||||
lines = self.options.lines
|
||||
sides = self.options.sides
|
||||
radius = self.options.radius * unit_factor
|
||||
angle_ratio = self.options.angle_ratio
|
||||
mirror_cells = self.options.mirror_cells
|
||||
|
||||
theta = (pi/2.)*(1 - 2./sides)
|
||||
l = 2.*radius*cos(theta*(1.-angle_ratio))
|
||||
a = 2.*radius*sin(pi/sides)
|
||||
# b = sqrt(a*a + l*l - 2*a*l*cos(angle_ratio*theta))
|
||||
# phi = abs(acos((l*l + b*b - a*a)/(2*l*b)))
|
||||
# gamma = pi/2 - angle_ratio*theta - phi
|
||||
# dy = b*cos(gamma)
|
||||
# dx = b*sin(gamma)
|
||||
dy = l * sin(theta * angle_ratio)
|
||||
dx = l * cos(theta * angle_ratio) - a
|
||||
|
||||
add_attachment = self.options.add_attachment
|
||||
attachment_percentage = self.options.attachment_percentage/100.
|
||||
attachment_height = a*(attachment_percentage-1)*tan(angle_ratio*theta)
|
||||
|
||||
vertices = []
|
||||
for i in range(sides + 1):
|
||||
for j in range(lines + 1):
|
||||
if mirror_cells:
|
||||
vertices.append(Path((dx*((lines - j)%2) + a*i, dy*j), style='p', radius=vertex_radius))
|
||||
else:
|
||||
vertices.append(Path((dx*(lines - j) + a*i, dy*j), style='p', radius=vertex_radius))
|
||||
|
||||
# create a horizontal grid, then offset each line according to angle
|
||||
grid_h = Path.generate_hgrid([0, a * sides], [0, dy * lines], lines, 'm')
|
||||
|
||||
if not mirror_cells:
|
||||
# shift every mountain line of the grid to the right by increasing amounts
|
||||
grid_h = Path.list_add(grid_h, [(i * dx, 0) for i in range(lines - 1, 0, -1)])
|
||||
else:
|
||||
# shift every OTHER mountain line of the grid a bit to the right
|
||||
grid_h = Path.list_add(grid_h, [((i%2)*dx, 0) for i in range(lines-1, 0, -1)])
|
||||
if add_attachment:
|
||||
for i in range(lines%2, lines-1, 2):
|
||||
# hacky solution, changes length of every other mountain line
|
||||
grid_h[i].points[1-i%2] = (grid_h[i].points[1-i%2][0] + a*attachment_percentage, grid_h[i].points[1-i%2][1])
|
||||
|
||||
# create MV zigzag for Kresling pattern
|
||||
zigzag = Kresling.generate_kresling_zigzag(sides, radius, angle_ratio, add_attachment)
|
||||
zigzags = []
|
||||
|
||||
# duplicate zigzag pattern for desired number of cells
|
||||
if not mirror_cells:
|
||||
for i in range(lines):
|
||||
zigzags.append(Path.list_add(zigzag, (i * dx, (lines - i) * dy)))
|
||||
else:
|
||||
zigzag_mirror = Path.list_reflect(zigzag, (0, lines * dy / 2), (dx, lines * dy / 2))
|
||||
for i in range(lines):
|
||||
if i % 2 == 1:
|
||||
zigzags.append(Path.list_add(zigzag_mirror, (0, -(lines - i + (lines-1)%2) * dy)))
|
||||
else:
|
||||
zigzags.append(Path.list_add(zigzag, (0, (lines - i) * dy)))
|
||||
|
||||
# create edge strokes
|
||||
if not mirror_cells:
|
||||
self.edge_points = [
|
||||
(a * sides , dy * lines), # bottom right
|
||||
(0 , dy * lines), # bottom left
|
||||
(dx * lines , 0), # top left
|
||||
(dx * lines + a * sides, 0)] # top right
|
||||
|
||||
if add_attachment:
|
||||
for i in range(lines):
|
||||
x = dx * (lines - i) + a * (sides + attachment_percentage)
|
||||
self.edge_points.append((x, dy * i))
|
||||
self.edge_points.append((x, dy * i - attachment_height))
|
||||
if i != lines - 1:
|
||||
self.edge_points.append((x-dx-a*attachment_percentage, dy * (i + 1)))
|
||||
pass
|
||||
|
||||
else:
|
||||
self.edge_points = [(a * sides + (lines % 2)*dx, 0)]
|
||||
|
||||
for i in range(lines+1):
|
||||
self.edge_points.append([((lines+i) % 2)*dx, dy*i])
|
||||
|
||||
self.edge_points.append([a * sides + ((lines+i) %2)*dx, lines*dy])
|
||||
|
||||
if add_attachment:
|
||||
for i in range(lines + 1):
|
||||
|
||||
if not i%2 == 0:
|
||||
self.edge_points.append([a*sides + (i%2)*(dx+a*attachment_percentage), dy*(lines - i) - (i%2)*attachment_height])
|
||||
self.edge_points.append([a*sides + (i%2)*(dx+a*attachment_percentage), dy*(lines - i)])
|
||||
if (i != lines):
|
||||
self.edge_points.append([a * sides + (i % 2) * (dx + a * attachment_percentage), dy * (lines - i) + (i % 2) * attachment_height])
|
||||
else:
|
||||
self.edge_points.append([a * sides + (i % 2) * (dx + a * attachment_percentage), dy * (lines - i)])
|
||||
else:
|
||||
for i in range(lines + 1):
|
||||
self.edge_points.append([a*sides + (i%2)*dx, dy*(lines - i)])
|
||||
|
||||
self.path_tree = [grid_h, zigzags, vertices]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
e = Kresling()
|
||||
e.draw()
|
92
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Kresling_full.py
Executable file
92
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Kresling_full.py
Executable file
@ -0,0 +1,92 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
from math import sin, cos, sqrt, asin, pi, ceil
|
||||
import inkex
|
||||
|
||||
from Path import Path
|
||||
from Pattern import Pattern
|
||||
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=self.float, default=10.0)
|
||||
self.add_argument('--measure_type', type=self.str, default=60)
|
||||
self.add_argument('--parameter_type', type=self.str, default=60)
|
||||
self.add_argument('--radial_ratio', type=self.float, default=0.5)
|
||||
self.add_argument('--angle_ratio', type=self.float, default=0.5)
|
||||
self.add_argument('--lambdatheta', type=self.float, default=45)
|
||||
|
||||
def generate_path_tree(self):
|
||||
""" Convert radial to angular ratio, then call regular Kresling constructor
|
||||
"""
|
||||
n = self.options.sides
|
||||
theta = pi*(n-2)/(2*n)
|
||||
# define ratio parameter
|
||||
parameter = self.options.parameter_type
|
||||
if parameter == 'radial_ratio':
|
||||
radial_ratio = self.options.radial_ratio
|
||||
max_radial_ratio = sin((pi/4)*(1. - 2./n))
|
||||
if radial_ratio > max_radial_ratio:
|
||||
inkex.errormsg(_("For polygon of {} sides, the maximal radial ratio is = {}".format(n, max_radial_ratio)))
|
||||
radial_ratio = max_radial_ratio
|
||||
self.options.angle_ratio = 1 - 2*n*asin(radial_ratio)/((n-2)*pi)
|
||||
|
||||
elif parameter == 'lambdatheta':
|
||||
lambdatheta = self.options.lambdatheta
|
||||
angle_min = 45. * (1 - 2. / n)
|
||||
angle_max = 2 * angle_min
|
||||
if lambdatheta < angle_min:
|
||||
inkex.errormsg(_(
|
||||
"For polygon of {} sides, phi must be between {} and {} degrees, \nsetting lambda*theta = {}\n".format(
|
||||
n, angle_min, angle_max, angle_min)))
|
||||
lambdatheta = angle_min
|
||||
elif lambdatheta > angle_max:
|
||||
inkex.errormsg(_(
|
||||
"For polygon of {} sides, phi must be between {} and {} degrees, \nsetting lambda*theta = {}\n".format(
|
||||
n, angle_min, angle_max, angle_max)))
|
||||
lambdatheta = angle_max
|
||||
self.options.angle_ratio = lambdatheta * n / (90. * (n - 2.))
|
||||
|
||||
|
||||
# define some length
|
||||
mtype = self.options.measure_type
|
||||
mvalue = self.options.measure_value
|
||||
angle_ratio = self.options.angle_ratio
|
||||
if mtype == 'a':
|
||||
radius = 0.5*mvalue / (sin(pi/n))
|
||||
if mtype == 'b':
|
||||
A = cos(theta*(1-angle_ratio))
|
||||
B = sin(pi/n)
|
||||
C = cos(theta*angle_ratio)
|
||||
radius = 0.5*mvalue / sqrt(A**2 + B**2 - 2*A*B*C)
|
||||
elif mtype == 'l':
|
||||
radius = 0.5*mvalue/cos(theta*(1-angle_ratio))
|
||||
elif mtype == 'radius_external':
|
||||
radius = mvalue
|
||||
elif mtype == 'radius_internal':
|
||||
radius = mvalue/(sin(theta*(1-angle_ratio)))
|
||||
elif mtype == 'diameter_external':
|
||||
radius = 0.5*mvalue
|
||||
elif mtype == 'diameter_internal':
|
||||
radius = 0.5*mvalue/sin(theta*(1-angle_ratio))
|
||||
|
||||
# inkex.errormsg(_("Value = {}, Mode = {}, Radius = {}".format(mvalue, mtype, radius)))
|
||||
|
||||
if self.options.pattern == 'mirrowed':
|
||||
self.options.mirror_cells = True
|
||||
else:
|
||||
self.options.mirror_cells = False
|
||||
self.options.radius = radius
|
||||
|
||||
Kresling.generate_path_tree(self)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
e = Kresling_Full()
|
||||
e.draw()
|
787
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Path.py
Executable file
787
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Path.py
Executable file
@ -0,0 +1,787 @@
|
||||
"""
|
||||
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, sqrt
|
||||
|
||||
# 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
|
||||
|
||||
Attributes
|
||||
---------
|
||||
points: tuple or list of tuples
|
||||
Points defining stroke lines.
|
||||
style: str
|
||||
Single character defining style of stroke. Default values are:
|
||||
'm' for mountain creases
|
||||
'v' for valley creases
|
||||
'e' for edge borders
|
||||
Extra possible values:
|
||||
'u' for universal creases
|
||||
's' for semicreases
|
||||
'c' for kirigami cuts
|
||||
angle: float
|
||||
From 0 to 180 degrees, converted to an opacity level from 0 to 1. This is how OrigamiSimulator encodes maximum
|
||||
fold angles
|
||||
closed: bool
|
||||
Tells if desired path should contain a last stroke from the last point to the first point, closing the path
|
||||
radius: float
|
||||
If only one point is given, it's assumed to be a circle and radius sets the radius
|
||||
|
||||
|
||||
Methods
|
||||
---------
|
||||
invert(self)
|
||||
Inverts path
|
||||
|
||||
Overloaded Operators
|
||||
---------
|
||||
__add__(self, offsets)
|
||||
Adding a tuple to a Path returns a new path with all points having an offset defined by the tuple
|
||||
|
||||
__mul__(self, transform)
|
||||
Define multiplication of a Path to a vector in complex exponential representation
|
||||
|
||||
|
||||
Static Methods
|
||||
---------
|
||||
draw_paths_recursively(path_tree, group, styles_dict)
|
||||
Draws strokes defined on "path_tree" to "group". Styles dict maps style of path_tree element to the definition
|
||||
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.
|
||||
|
||||
generate_vgrid(cls, xlims, ylims, nb_of_divisions, style, include_edge=False)
|
||||
Generate list of Path instances, in which each Path is a stroke defining a vertical grid dividing the space
|
||||
xlims * ylims nb_of_divisions times.
|
||||
|
||||
generate_separated_paths(cls, points, styles, closed=False)
|
||||
Generate list of Path instances, in which each Path is the stroke between each two point tuples, in case each
|
||||
stroke must be handled separately
|
||||
|
||||
reflect(cls, path, p1, p2)
|
||||
Reflects each point of path on line defined by two points and return new Path instance with new reflected points
|
||||
|
||||
list_reflect(cls, paths, p1, p2)
|
||||
Generate list of new Path instances, rotation each path by transform
|
||||
|
||||
list_rotate(cls, paths, theta, translation=(0, 0))
|
||||
Generate list of new Path instances, rotation each path by transform
|
||||
|
||||
list_add(cls, paths, offsets)
|
||||
Generate list of new Path instances, adding a different tuple for each list
|
||||
|
||||
list_mul(cls, paths, transf)
|
||||
Generate list of new Path instances, multiplying 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, fold_angle = 180.0):
|
||||
""" Constructor
|
||||
|
||||
Parameters
|
||||
---------
|
||||
points: list of 2D tuples
|
||||
stroke will connect all points
|
||||
style: str
|
||||
Single character defining style of stroke. For use with the OrigamiPatterns class (probably the only
|
||||
project that will ever use this file) the default values are:
|
||||
'm' for mountain creases
|
||||
'v' for valley creases
|
||||
'e' for edge borders
|
||||
closed: bool
|
||||
if true, last point will be connected to first point at the end
|
||||
invert: bool
|
||||
if true, stroke will start at the last point and go all the way to the first one
|
||||
"""
|
||||
if type(points) == list and len(points) != 1:
|
||||
self.type = 'linear'
|
||||
if invert:
|
||||
self.points = points[::-1]
|
||||
else:
|
||||
self.points = points
|
||||
|
||||
elif (type(points) == list and len(points) == 1):
|
||||
self.type = 'circular'
|
||||
self.points = points
|
||||
self.radius = radius
|
||||
|
||||
elif (type(points) == tuple and len(points) == 2):
|
||||
self.type = 'circular'
|
||||
self.points = [points]
|
||||
self.radius = radius
|
||||
|
||||
else:
|
||||
raise TypeError("Points must be tuple of length 2 (for a circle) or a list of tuples of length 2 each")
|
||||
|
||||
self.fold_angle = max(min(fold_angle, 180.), 0.)
|
||||
self.style = style
|
||||
self.closed = closed
|
||||
|
||||
def invert(self):
|
||||
""" Inverts path
|
||||
"""
|
||||
self.points = self.points[::-1]
|
||||
|
||||
"""
|
||||
Draw path recursively
|
||||
- Static method
|
||||
- Draws strokes defined on "path_tree" to "group"
|
||||
- Inputs:
|
||||
-- path_tree [nested list] of Path instances
|
||||
-- group [inkex.etree.SubElement]
|
||||
-- styles_dict [dict] containing all styles for path_tree
|
||||
"""
|
||||
@staticmethod
|
||||
def draw_paths_recursively(path_tree, group, styles_dict):
|
||||
""" Static method, draw list of Path instances recursively
|
||||
"""
|
||||
for subpath in path_tree:
|
||||
if type(subpath) == list:
|
||||
if len(subpath) == 1:
|
||||
subgroup = group
|
||||
else:
|
||||
subgroup = inkex.etree.SubElement(group, 'g')
|
||||
Path.draw_paths_recursively(subpath, subgroup, styles_dict)
|
||||
else:
|
||||
# ~ if subpath.style != 'n':
|
||||
if subpath.style != 'n' and styles_dict[subpath.style]['draw']:
|
||||
if subpath.type == 'linear':
|
||||
|
||||
points = subpath.points
|
||||
path = 'M{},{} '.format(*points[0])
|
||||
for i in range(1, len(points)):
|
||||
path = path + 'L{},{} '.format(*points[i])
|
||||
if subpath.closed:
|
||||
path = path + 'L{},{} Z'.format(*points[0])
|
||||
|
||||
attribs = {'style': format_style(styles_dict[subpath.style]),
|
||||
'd': path,
|
||||
'opacity': str(subpath.fold_angle/180)}
|
||||
inkex.etree.SubElement(group, inkex.addNS('path', 'svg'), attribs)
|
||||
else:
|
||||
attribs = {'style': format_style(styles_dict[subpath.style]),
|
||||
'cx': str(subpath.points[0][0]), 'cy': str(subpath.points[0][1]),
|
||||
'r': str(subpath.radius),
|
||||
'opacity': str(subpath.fold_angle/180)}
|
||||
inkex.etree.SubElement(group, inkex.addNS('circle', 'svg'), attribs)
|
||||
|
||||
@classmethod
|
||||
def get_average_point(cls, paths):
|
||||
points = cls.get_points(paths)
|
||||
n = len(points)
|
||||
x, y = 0, 0
|
||||
for p in points:
|
||||
x += p[0]
|
||||
y += p[1]
|
||||
return (x/n, y/n)
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_square_points(cls, width, height, center = None, rotation = 1):
|
||||
""" Get points of a square at given center or origin
|
||||
|
||||
Parameters
|
||||
---------
|
||||
width: float
|
||||
height: float
|
||||
center: list of floats
|
||||
rotation: float
|
||||
rotation in degrees
|
||||
|
||||
Returns
|
||||
---------
|
||||
points: list of tuples
|
||||
"""
|
||||
if center is None:
|
||||
center = [width/2, height/2]
|
||||
|
||||
#TODO: Implement rotation
|
||||
# c = cos(rotation * pi / 180)
|
||||
# s = sin(rotation * pi / 180)
|
||||
|
||||
points = [
|
||||
(center[0] - 0.5*width, center[1] + 0.5*height), # top left
|
||||
(center[0] + 0.5*width, center[1] + 0.5*height), # top right
|
||||
(center[0] + 0.5*width, center[1] - 0.5*height), # bottom right
|
||||
(center[0] - 0.5*width, center[1] - 0.5*height)] # bottom left
|
||||
# points = [
|
||||
# (center[0] + (-0.5*width*c - 0.5*height*s), center[1] + (-0.5*width*s + 0.5*height*c)), # top left
|
||||
# (center[0] + (+0.5*width*c - 0.5*height*s), center[1] + (+0.5*width*s + 0.5*height*c)), # top right
|
||||
# (center[0] + (+0.5*width*c + 0.5*height*s), center[1] - (+0.5*width*s - 0.5*height*c)), # bottom right
|
||||
# (center[0] + (-0.5*width*c + 0.5*height*s), center[1] - (-0.5*width*s - 0.5*height*c))] # bottom left
|
||||
return points
|
||||
|
||||
@classmethod
|
||||
def generate_square(cls, width, height, style ='e', fold_angle=180, center = None, rotation = 0):
|
||||
""" Generate a closed square at given center or origin
|
||||
|
||||
Parameters
|
||||
---------
|
||||
width: float
|
||||
height: float
|
||||
style: str
|
||||
fold_angle: float
|
||||
center: list of floats
|
||||
rotation: float
|
||||
rotation in degrees
|
||||
|
||||
Returns
|
||||
---------
|
||||
path: path instance
|
||||
"""
|
||||
points = cls.get_square_points(width, height, center, rotation)
|
||||
return Path(points, style, fold_angle=fold_angle, closed=True)
|
||||
|
||||
@classmethod
|
||||
def generate_hgrid(cls, xlims, ylims, nb_of_divisions, style, include_edge=False, fold_angle = 180):
|
||||
""" 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.
|
||||
|
||||
All lines are alternated, to minimize Laser Cutter unnecessary movements
|
||||
|
||||
Parameters
|
||||
---------
|
||||
xlims: tuple
|
||||
Defines x_min and x_max for space that must be divided.
|
||||
ylims: tuple
|
||||
Defines y_min and y_max for space that must be divided.
|
||||
nb_of_divisions: int
|
||||
Defines how many times it should be divided.
|
||||
style: str
|
||||
Single character defining style of stroke.
|
||||
include_edge: bool
|
||||
Defines if edge should be drawn or not.
|
||||
fold_angle: float
|
||||
|
||||
Returns
|
||||
---------
|
||||
paths: list of Path instances
|
||||
"""
|
||||
rect_len = (ylims[1] - ylims[0])/nb_of_divisions
|
||||
hgrid = []
|
||||
for i in range(1 - include_edge, nb_of_divisions + include_edge):
|
||||
hgrid.append(cls([(xlims[0], ylims[0]+i*rect_len),
|
||||
(xlims[1], ylims[0]+i*rect_len)],
|
||||
style=style, invert=i % 2 == 0, fold_angle = fold_angle))
|
||||
return hgrid
|
||||
|
||||
@classmethod
|
||||
def generate_vgrid(cls, xlims, ylims, nb_of_divisions, style, include_edge=False, fold_angle = 180):
|
||||
""" Generate list of Path instances, in which each Path is a stroke defining
|
||||
a vertical grid dividing the space xlims * ylims nb_of_divisions times.
|
||||
|
||||
All lines are alternated, to minimize Laser Cutter unnecessary movements
|
||||
|
||||
Parameters
|
||||
---------
|
||||
-> refer to generate_hgrid
|
||||
|
||||
Returns
|
||||
---------
|
||||
paths: list of Path instances
|
||||
"""
|
||||
rect_len = (xlims[1] - xlims[0])/nb_of_divisions
|
||||
vgrid = []
|
||||
for i in range(1 - include_edge, nb_of_divisions + include_edge):
|
||||
vgrid.append(cls([(xlims[0]+i*rect_len, ylims[0]),
|
||||
(xlims[0]+i*rect_len, ylims[1])],
|
||||
style=style, invert=i % 2 == 0, fold_angle = fold_angle))
|
||||
return vgrid
|
||||
|
||||
@classmethod
|
||||
def generate_polygon(cls, sides, radius, style, center=(0, 0), fold_angle = 180):
|
||||
points = []
|
||||
for i in range(sides):
|
||||
points.append((radius * cos((1 + i * 2) * pi / sides),
|
||||
radius * sin((1 + i * 2) * pi / sides)))
|
||||
return Path(points, style, closed=True, fold_angle = fold_angle)
|
||||
|
||||
@classmethod
|
||||
def generate_separated_paths(cls, points, styles, closed=False, fold_angle = 180):
|
||||
""" Generate list of Path instances, in which each Path is the stroke
|
||||
between each two point tuples, in case each stroke must be handled separately.
|
||||
|
||||
Returns
|
||||
---------
|
||||
paths: list
|
||||
list of Path instances
|
||||
"""
|
||||
paths = []
|
||||
if type(styles) == str:
|
||||
styles = [styles] * (len(points) - 1 + int(closed))
|
||||
elif len(styles) != len(points) - 1 + int(closed):
|
||||
raise TypeError("Number of paths and styles don't match")
|
||||
for i in range(len(points) - 1 + int(closed)):
|
||||
j = (i+1)%len(points)
|
||||
paths.append(cls([points[i], points[j]],
|
||||
styles[i], fold_angle = fold_angle))
|
||||
return paths
|
||||
|
||||
|
||||
def __add__(self, offsets):
|
||||
""" " + " operator overload.
|
||||
Adding a tuple to a Path returns a new path with all points having an offset
|
||||
defined by the tuple
|
||||
"""
|
||||
if type(offsets) == list:
|
||||
if len(offsets) != 1 or len(offsets) != len(self.points):
|
||||
raise TypeError("Paths can only be added by a tuple of a list of N tuples, "
|
||||
"where N is the same number of points")
|
||||
|
||||
elif type(offsets) != tuple:
|
||||
raise TypeError("Paths can only be added by tuples")
|
||||
else:
|
||||
offsets = [offsets] * len(self.points)
|
||||
|
||||
# if type(self.points) == list:
|
||||
points_new = []
|
||||
for point, offset in zip(self.points, offsets):
|
||||
points_new.append((point[0]+offset[0],
|
||||
point[1]+offset[1]))
|
||||
|
||||
if self.type == 'circular':
|
||||
radius = self.radius
|
||||
else:
|
||||
radius = 0.2
|
||||
|
||||
# if self.type == 'circular' else 0.1
|
||||
|
||||
return Path(points_new, self.style, self.closed, radius=radius, fold_angle=self.fold_angle)
|
||||
|
||||
@classmethod
|
||||
def list_add(cls, paths, offsets):
|
||||
""" Generate list of new Path instances, adding a different tuple for each list
|
||||
|
||||
Parameters
|
||||
---------
|
||||
paths: Path or list
|
||||
list of N Path instances
|
||||
offsets: tuple or list
|
||||
list of N tuples
|
||||
|
||||
Returns
|
||||
---------
|
||||
paths_new: list
|
||||
list of N Path instances
|
||||
"""
|
||||
if type(paths) == Path and type(offsets) == tuple:
|
||||
paths = [paths]
|
||||
offsets = [offsets]
|
||||
elif type(paths) == list and type(offsets) == tuple:
|
||||
offsets = [offsets] * len(paths)
|
||||
elif type(paths) == Path and type(offsets) == list:
|
||||
paths = [paths] * len(offsets)
|
||||
elif type(paths) == list and type(offsets) == list:
|
||||
if len(paths) == 1:
|
||||
paths = [paths[0]] * len(offsets)
|
||||
elif len(offsets) == 1:
|
||||
offsets = [offsets[0]] * len(paths)
|
||||
elif len(offsets) != len(paths):
|
||||
raise TypeError("List of paths and list of tuples must have same length. {} paths and {} offsets "
|
||||
" where given".format(len(paths), len(offsets)))
|
||||
else:
|
||||
pass
|
||||
|
||||
paths_new = []
|
||||
for path, offset in zip(paths, offsets):
|
||||
if type(path) == Path:
|
||||
paths_new.append(path+offset)
|
||||
elif type(path) == list:
|
||||
paths_new.append(
|
||||
cls.list_add(path, offset)
|
||||
)
|
||||
|
||||
return paths_new
|
||||
|
||||
@classmethod
|
||||
def list_mul(cls, paths, offsets):
|
||||
""" Generate list of new Path instances, multiplying a different tuple for each list
|
||||
|
||||
Parameters
|
||||
---------
|
||||
paths: Path or list
|
||||
list of N Path instances
|
||||
offsets: tuple or list
|
||||
list of N tuples
|
||||
|
||||
Returns
|
||||
---------
|
||||
paths_new: list
|
||||
list of N Path instances
|
||||
"""
|
||||
if type(paths) == Path and type(offsets) == tuple:
|
||||
paths = [paths]
|
||||
offsets = [offsets]
|
||||
elif type(paths) == list and type(offsets) == tuple:
|
||||
offsets = [offsets] * len(paths)
|
||||
elif type(paths) == Path and type(offsets) == list:
|
||||
paths = [paths] * len(offsets)
|
||||
elif type(paths) == list and type(offsets) == list:
|
||||
if len(paths) == 1:
|
||||
paths = [paths[0]] * len(offsets)
|
||||
elif len(offsets) == 1:
|
||||
offsets = [offsets[0]] * len(paths)
|
||||
elif len(offsets) != len(paths):
|
||||
raise TypeError("List of paths and list of tuples must have same length. {} paths and {} offsets "
|
||||
" where given".format(len(paths), len(offsets)))
|
||||
else:
|
||||
pass
|
||||
|
||||
paths_new = []
|
||||
for path, offset in zip(paths, offsets):
|
||||
paths_new.append(path*offset)
|
||||
|
||||
return paths_new
|
||||
|
||||
def break_path(self, lengths, styles = None):
|
||||
if len(self.points) != 2:
|
||||
raise ValueError('Path breaking only implemented for straight lines with 2 points')
|
||||
|
||||
if styles is None:
|
||||
styles = [self.style]*len(lengths)
|
||||
elif len(styles) != len(lengths):
|
||||
raise ValueError('Different number of lenghts and styles')
|
||||
|
||||
p0 = self.points[0]
|
||||
p1 = self.points[1]
|
||||
d = (p1[0]-p0[0], p1[1]-p0[1])
|
||||
L = sqrt(d[0]**2 + d[1]**2)
|
||||
dx = d[0] / L
|
||||
dy = d[1] / L
|
||||
paths = []
|
||||
start = 0
|
||||
p0_ = p0
|
||||
for l, s in zip(lengths, styles):
|
||||
p1_ = (p0_[0] + dx*l, p0_[1] + dy*l)
|
||||
paths.append(Path([p0_, p1_], style = s))
|
||||
p0_ = p1_
|
||||
return paths
|
||||
|
||||
|
||||
|
||||
def __mul__(self, transform):
|
||||
""" " * " operator overload.
|
||||
Define multiplication of a Path to a vector in complex exponential representation
|
||||
|
||||
Parameters
|
||||
---------
|
||||
transform: float of tuple of length 2 or 4
|
||||
if float, transform represents magnitude
|
||||
Example: path * 3
|
||||
if tuple length 2, transform[0] represents magnitude and transform[1] represents angle of rotation
|
||||
Example: path * (3, pi)
|
||||
if tuple length 4, transform[2],transform[3] define a different axis of rotation
|
||||
Example: path * (3, pi, 1, 1)
|
||||
"""
|
||||
points_new = []
|
||||
|
||||
# "temporary" (probably permanent) compatibility hack
|
||||
try:
|
||||
long_ = long
|
||||
except:
|
||||
long_ = int
|
||||
|
||||
if isinstance(transform, (int, long_, float)):
|
||||
for p in self.points:
|
||||
points_new.append((transform * p[0],
|
||||
transform * p[1]))
|
||||
|
||||
elif isinstance(transform, (list, tuple)):
|
||||
if len(transform) == 2:
|
||||
u = transform[0]*cos(transform[1])
|
||||
v = transform[0]*sin(transform[1])
|
||||
x_, y_ = 0, 0
|
||||
elif len(transform) == 4:
|
||||
u = transform[0]*cos(transform[1])
|
||||
v = transform[0]*sin(transform[1])
|
||||
x_, y_ = transform[2:]
|
||||
else:
|
||||
raise IndexError('Paths can only be multiplied by a number or a tuple/list of length 2 or 4')
|
||||
|
||||
for p in self.points:
|
||||
x, y = p[0]-x_, p[1]-y_
|
||||
points_new.append((x_ + x * u - y * v,
|
||||
y_ + x * v + y * u))
|
||||
else:
|
||||
raise TypeError('Paths can only be multiplied by a number or a tuple/list of length 2 or 4')
|
||||
|
||||
if self.type == 'circular':
|
||||
radius = self.radius
|
||||
else:
|
||||
radius = 0.2
|
||||
|
||||
return Path(points_new, self.style, self.closed, radius=radius, fold_angle=self.fold_angle)
|
||||
|
||||
def shape(self):
|
||||
points = self.points
|
||||
x = [p[0] for p in points]
|
||||
y = [p[1] for p in points]
|
||||
return [min(x), max(x), min(y), max(y)]
|
||||
|
||||
@classmethod
|
||||
def list_create_from_points(cls, points, styles, fold_angles = None):
|
||||
""" Generate list of new Path instances, between each two points
|
||||
|
||||
Parameters
|
||||
---------
|
||||
points: list of tuples
|
||||
list of points
|
||||
styles: str or list of str
|
||||
styles
|
||||
fold_angles: list of floats
|
||||
list of maximum fold angle values
|
||||
|
||||
Returns
|
||||
---------
|
||||
paths_new: list
|
||||
list of N Path instances
|
||||
"""
|
||||
if fold_angles is None:
|
||||
fold_angles = [180]
|
||||
elif type(fold_angles) != list:
|
||||
fold_angles = [fold_angles]
|
||||
|
||||
return [Path([points[i], points[i+1]],
|
||||
styles[i % len(styles)],
|
||||
fold_angle=fold_angles[i % len(fold_angles)]) for i in range(len(points)-1)]
|
||||
|
||||
@classmethod
|
||||
def list_rotate_symmetry(cls, paths, n, translation=(0,0)):
|
||||
""" Generate list of new Path instances, rotation each path by transform
|
||||
|
||||
Parameters
|
||||
---------
|
||||
paths: Path or list
|
||||
list of N Path instances
|
||||
n: int
|
||||
number of rotations
|
||||
translation: tuple or list 2
|
||||
axis of rotation
|
||||
|
||||
Returns
|
||||
---------
|
||||
paths_new: list
|
||||
list of N Path instances
|
||||
"""
|
||||
|
||||
theta = 2*pi/n
|
||||
paths_new = []
|
||||
for i in range(n):
|
||||
ith_rotation = cls.list_rotate(paths, theta, translation=translation)
|
||||
if type(paths) == list:
|
||||
paths_new += ith_rotation
|
||||
else:
|
||||
paths_new.append(ith_rotation)
|
||||
return paths_new
|
||||
|
||||
|
||||
@classmethod
|
||||
def list_rotate(cls, paths, theta, translation=(0, 0)):
|
||||
""" Generate list of new Path instances, rotation each path by transform
|
||||
|
||||
Parameters
|
||||
---------
|
||||
paths: Path or list
|
||||
list of N Path instances
|
||||
theta: float (radians)
|
||||
angle of rotation
|
||||
translation: tuple or list 2
|
||||
axis of rotation
|
||||
|
||||
Returns
|
||||
---------
|
||||
paths_new: list
|
||||
list of N Path instances
|
||||
"""
|
||||
if len(translation) != 2:
|
||||
TypeError("Translation must have length 2")
|
||||
|
||||
if type(paths) != list:
|
||||
paths = [paths]
|
||||
|
||||
paths_new = []
|
||||
for path in paths:
|
||||
if type(path) == Path:
|
||||
paths_new.append(path*(1, theta, translation[0], translation[1]))
|
||||
elif type(path) == list:
|
||||
paths_new.append(cls.list_rotate(path, theta, translation))
|
||||
|
||||
if len(paths_new) == 1:
|
||||
paths_new = paths_new[0]
|
||||
return paths_new
|
||||
|
||||
# TODO:
|
||||
# Apparently it's not working properly, must be debugged and tested
|
||||
@classmethod
|
||||
def reflect(cls, path, p1, p2):
|
||||
""" Reflects each point of path on line defined by two points and return new Path instance with new reflected points
|
||||
|
||||
Parameters
|
||||
---------
|
||||
path: Path
|
||||
p1: tuple or list of size 2
|
||||
p2: tuple or list of size 2
|
||||
|
||||
Returns
|
||||
---------
|
||||
path_reflected: Path
|
||||
"""
|
||||
|
||||
(x1, y1) = p1
|
||||
(x2, y2) = p2
|
||||
|
||||
if x1 == x2 and y1 == y2:
|
||||
ValueError("Duplicate points don't define a line")
|
||||
elif x1 == x2:
|
||||
t_x = [-1, 0, 2*x1, 1]
|
||||
t_y = [0, 1, 0, 1]
|
||||
else:
|
||||
m = (y2 - y1)/(x2 - x1)
|
||||
t = y1 - m*x1
|
||||
t_x = [1 - m**2, 2*m, -2*m*t, m**2 + 1]
|
||||
t_y = [2*m, m**2 - 1, +2*t, m**2 + 1]
|
||||
|
||||
points_new = []
|
||||
for p in path.points:
|
||||
x_ = (t_x[0]*p[0] + t_x[1]*p[1] + t_x[2]) / t_x[3]
|
||||
y_ = (t_y[0]*p[0] + t_y[1]*p[1] + t_y[2]) / t_y[3]
|
||||
points_new.append((x_, y_))
|
||||
|
||||
return Path(points_new, path.style, path.closed, fold_angle=path.fold_angle)
|
||||
|
||||
# TODO:
|
||||
# Apparently it's not working properly, must be debugged and tested
|
||||
@classmethod
|
||||
def list_reflect(cls, paths, p1, p2):
|
||||
""" Generate list of new Path instances, rotation each path by transform
|
||||
|
||||
Parameters
|
||||
---------
|
||||
paths: Path or list
|
||||
list of N Path instances
|
||||
p1: tuple or list of size 2
|
||||
p2: tuple or list of size 2
|
||||
|
||||
Returns
|
||||
---------
|
||||
paths_new: list
|
||||
list of N Path instances
|
||||
"""
|
||||
|
||||
if type(paths) == Path:
|
||||
paths = [paths]
|
||||
|
||||
paths_new = []
|
||||
for path in paths:
|
||||
paths_new.append(Path.reflect(path, p1, p2))
|
||||
|
||||
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)
|
||||
|
||||
@classmethod
|
||||
def get_points(cls, paths):
|
||||
""" Get points of path tree in drawing order.
|
||||
|
||||
"""
|
||||
points = []
|
||||
if type(paths) == Path:
|
||||
points = points + paths.points
|
||||
elif type(paths) == list:
|
||||
for sub_path in paths:
|
||||
points = points + Path.get_points(sub_path)
|
||||
return points
|
||||
|
||||
|
378
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Pattern.py
Executable file
378
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Pattern.py
Executable file
@ -0,0 +1,378 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Helper functions
|
||||
|
||||
"""
|
||||
import os
|
||||
from abc import abstractmethod
|
||||
|
||||
from Path import Path, inkex, simplestyle
|
||||
|
||||
class Pattern(inkex.Effect):
|
||||
""" Class that inherits inkex.Effect and further specializes it for different
|
||||
Patterns generation
|
||||
|
||||
Attributes
|
||||
---------
|
||||
styles_dict: dict
|
||||
defines styles for every possible stroke. Default values are:
|
||||
styles_dict = {'m' : mountain_style,
|
||||
'v' : valley_style,
|
||||
'e' : edge_style}
|
||||
|
||||
topgroup: inkex.etree.SubElement
|
||||
Top Inkscape group element
|
||||
|
||||
path_tree: nested list
|
||||
Contains "tree" of Path instances, defining new groups for each
|
||||
sublist
|
||||
|
||||
translate: 2 sized tuple
|
||||
Defines translation to be added when drawing to Inkscape (default: 0,0)
|
||||
|
||||
Methods
|
||||
---------
|
||||
effect(self)
|
||||
Main function, called when the extension is run.
|
||||
|
||||
create_styles_dict(self)
|
||||
Get stroke style parameters and use them to create the styles dictionary.
|
||||
|
||||
calc_unit_factor(self)
|
||||
Return the scale factor for all dimension conversions
|
||||
|
||||
add_text(self, node, text, position, text_height=12)
|
||||
Create and insert a single line of text into the svg under node.
|
||||
|
||||
get_color_string(self, longColor, verbose=False)
|
||||
Convert the long into a #RRGGBB color value
|
||||
|
||||
Abstract Methods
|
||||
---------
|
||||
__init__(self)
|
||||
Parse all options
|
||||
|
||||
generate_path_tree(self)
|
||||
Generate nested list of Path
|
||||
|
||||
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def generate_path_tree(self):
|
||||
""" Generate nested list of Path instances
|
||||
Abstract method, must be defined in all child classes
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def __init__(self):
|
||||
""" Parse all common options
|
||||
|
||||
Must be reimplemented in child classes to parse specialized options
|
||||
"""
|
||||
|
||||
inkex.Effect.__init__(self) # initialize the super class
|
||||
|
||||
# backwards compatibility
|
||||
try:
|
||||
self.add_argument = self.arg_parser.add_argument
|
||||
self.str = str
|
||||
self.int = int
|
||||
self.float = float
|
||||
self.bool = inkex.Boolean
|
||||
except:
|
||||
self.add_argument = self.OptionParser.add_option
|
||||
self.str = "string"
|
||||
self.int = "int"
|
||||
self.float = "float"
|
||||
self.bool = "inkbool"
|
||||
|
||||
# Two ways to get debug info:
|
||||
# OR just use inkex.debug(string) instead...
|
||||
try:
|
||||
self.tty = open("/dev/tty", 'w')
|
||||
except:
|
||||
self.tty = open(os.devnull, 'w') # '/dev/null' for POSIX, 'nul' for Windows.
|
||||
|
||||
self.add_argument('-u', '--units', type=self.str, default='mm')
|
||||
|
||||
# bypass most style options for OrigamiSimulator
|
||||
self.add_argument('--simulation_mode', type=self.bool, default=False)
|
||||
|
||||
# mountain options
|
||||
self.add_argument('--mountain_stroke_color', type=self.str, default=4278190335) # Red
|
||||
self.add_argument('--mountain_stroke_width', type=self.float, default=0.1)
|
||||
self.add_argument('--mountain_dashes_len', type=self.float, default=1.0)
|
||||
self.add_argument('--mountain_dashes_duty', type=self.float, default=0.5)
|
||||
self.add_argument('--mountain_dashes_bool', type=self.bool, default=True)
|
||||
self.add_argument('--mountain_bool', type=self.bool, default=True)
|
||||
self.add_argument('--mountain_bool_only', type=self.bool, default=False)
|
||||
|
||||
# valley options
|
||||
self.add_argument('--valley_stroke_color', type=self.str, default=65535) # Blue
|
||||
self.add_argument('--valley_stroke_width', type=self.float, default=0.1)
|
||||
self.add_argument('--valley_dashes_len', type=self.float, default=1.0)
|
||||
self.add_argument('--valley_dashes_duty', type=self.float, default=0.25)
|
||||
self.add_argument('--valley_dashes_bool', type=self.bool, default=True)
|
||||
self.add_argument('--valley_bool', type=self.bool, default=True)
|
||||
self.add_argument('--valley_bool_only', type=self.bool, default=False)
|
||||
|
||||
# edge options
|
||||
self.add_argument('--edge_stroke_color', type=self.str, default=255) # Black
|
||||
self.add_argument('--edge_stroke_width', type=self.float, default=0.1)
|
||||
self.add_argument('--edge_dashes_len', type=self.float, default=1.0)
|
||||
self.add_argument('--edge_dashes_duty', type=self.float, default=0.25)
|
||||
self.add_argument('--edge_dashes_bool', type=self.bool, default=False)
|
||||
self.add_argument('--edge_bool', type=self.bool, default=True)
|
||||
self.add_argument('--edge_bool_only', type=self.bool, default=False)
|
||||
self.add_argument('--edge_single_path', type=self.bool, default=True)
|
||||
|
||||
# universal crease options
|
||||
self.add_argument('--universal_stroke_color', type=self.str, default=4278255615) # Magenta
|
||||
self.add_argument('--universal_stroke_width', type=self.float, default=0.1)
|
||||
self.add_argument('--universal_dashes_len', type=self.float, default=1.0)
|
||||
self.add_argument('--universal_dashes_duty', type=self.float, default=0.25)
|
||||
self.add_argument('--universal_dashes_bool', type=self.bool, default=False)
|
||||
self.add_argument('--universal_bool', type=self.bool, default=True)
|
||||
self.add_argument('--universal_bool_only', type=self.bool, default=False)
|
||||
|
||||
# semicrease options
|
||||
self.add_argument('--semicrease_stroke_color', type=self.str, default=4294902015) # Yellow
|
||||
self.add_argument('--semicrease_stroke_width', type=self.float, default=0.1)
|
||||
self.add_argument('--semicrease_dashes_len', type=self.float, default=1.0)
|
||||
self.add_argument('--semicrease_dashes_duty', type=self.float, default=0.25)
|
||||
self.add_argument('--semicrease_dashes_bool', type=self.bool, default=False)
|
||||
self.add_argument('--semicrease_bool', type=self.bool, default=True)
|
||||
self.add_argument('--semicrease_bool_only', type=self.bool, default=False)
|
||||
|
||||
# cut options
|
||||
self.add_argument('--cut_stroke_color', type=self.str, default=16711935) # Green
|
||||
self.add_argument('--cut_stroke_width', type=self.float, default=0.1)
|
||||
self.add_argument('--cut_dashes_len', type=self.float, default=1.0)
|
||||
self.add_argument('--cut_dashes_duty', type=self.float, default=0.25)
|
||||
self.add_argument('--cut_dashes_bool', type=self.bool, default=False)
|
||||
self.add_argument('--cut_bool', type=self.bool, default=True)
|
||||
self.add_argument('--cut_bool_only', type=self.bool, default=False)
|
||||
|
||||
# vertex options
|
||||
self.add_argument('--vertex_stroke_color', type=self.str, default=255) # Black
|
||||
self.add_argument('--vertex_stroke_width', type=self.float, default=0.1)
|
||||
self.add_argument('--vertex_radius', type=self.float, default=0.1)
|
||||
self.add_argument('--vertex_dashes_bool', type=self.bool, default=False)
|
||||
self.add_argument('--vertex_bool', type=self.bool, default=True)
|
||||
self.add_argument('--vertex_bool_only', type=self.bool, default=False)
|
||||
|
||||
# here so we can have tabs - but we do not use it directly - else error
|
||||
self.add_argument('--active-tab', type=self.str, default='title') # use a legitimate default
|
||||
|
||||
self.path_tree = []
|
||||
self.edge_points = []
|
||||
self.vertex_points = []
|
||||
self.translate = (0, 0)
|
||||
|
||||
def effect(self):
|
||||
""" Main function, called when the extension is run.
|
||||
"""
|
||||
# bypass most style options if simulation mode is choosen
|
||||
self.check_simulation_mode()
|
||||
|
||||
# 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()
|
||||
|
||||
# get paths for selected origami pattern
|
||||
self.generate_path_tree()
|
||||
|
||||
# ~ accuracy = self.options.accuracy
|
||||
# ~ unit_factor = self.calc_unit_factor()
|
||||
# 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]),
|
||||
# inkex.addNS('transform-center-y','inkscape'): str(-bbox_center[1]),
|
||||
inkex.addNS('transform-center-x', 'inkscape'): str(0),
|
||||
inkex.addNS('transform-center-y', 'inkscape'): str(0),
|
||||
'transform': 'translate(%s,%s)' % self.translate}
|
||||
|
||||
# add the group to the document's current layer
|
||||
if type(self.path_tree) == list and len(self.path_tree) != 1:
|
||||
self.topgroup = inkex.etree.SubElement(self.get_layer(), 'g', g_attribs)
|
||||
else:
|
||||
self.topgroup = self.get_layer()
|
||||
|
||||
if len(self.edge_points) == 0:
|
||||
Path.draw_paths_recursively(self.path_tree, self.topgroup, self.styles_dict)
|
||||
elif self.options.edge_single_path:
|
||||
edges = Path(self.edge_points, 'e', closed=True)
|
||||
Path.draw_paths_recursively(self.path_tree + [edges], self.topgroup, self.styles_dict)
|
||||
else:
|
||||
edges = Path.generate_separated_paths(self.edge_points, 'e', closed=True)
|
||||
Path.draw_paths_recursively(self.path_tree + edges, self.topgroup, self.styles_dict)
|
||||
|
||||
# self.draw_paths_recursively(self.path_tree, self.topgroup, self.styles_dict)
|
||||
|
||||
# compatibility hack, "affect()" is replaced by "run()"
|
||||
def draw(self):
|
||||
try:
|
||||
self.run() # new
|
||||
except:
|
||||
self.affect() # old
|
||||
# close(self.tty)
|
||||
self.tty.close()
|
||||
|
||||
# compatibility hack
|
||||
def get_layer(self):
|
||||
try:
|
||||
return self.svg.get_current_layer() # new
|
||||
except:
|
||||
return self.current_layer # old
|
||||
|
||||
def check_simulation_mode(self):
|
||||
if not self.options.simulation_mode:
|
||||
pass
|
||||
else:
|
||||
self.options.mountain_stroke_color = 4278190335
|
||||
self.options.mountain_dashes_len = 0
|
||||
self.options.mountain_dashes_bool = False
|
||||
self.options.mountain_bool_only = False
|
||||
self.options.mountain_bool = True
|
||||
|
||||
self.options.valley_stroke_color = 65535
|
||||
self.options.valley_dashes_len = 0
|
||||
self.options.valley_dashes_bool = False
|
||||
self.options.valley_bool_only = False
|
||||
self.options.valley_bool = True
|
||||
|
||||
self.options.edge_stroke_color = 255
|
||||
self.options.edge_dashes_len = 0
|
||||
self.options.edge_dashes_bool = False
|
||||
self.options.edge_bool_only = False
|
||||
self.options.edge_bool = True
|
||||
|
||||
self.options.universal_stroke_color = 4278255615
|
||||
self.options.universal_dashes_len = 0
|
||||
self.options.universal_dashes_bool = False
|
||||
self.options.universal_bool_only = False
|
||||
self.options.universal_bool = True
|
||||
|
||||
self.options.cut_stroke_color = 16711935
|
||||
self.options.cut_dashes_len = 0
|
||||
self.options.cut_dashes_bool = False
|
||||
self.options.cut_bool_only = False
|
||||
self.options.cut_bool = True
|
||||
|
||||
self.options.vertex_bool = False
|
||||
|
||||
|
||||
def create_styles_dict(self):
|
||||
""" Get stroke style parameters and use them to create the styles dictionary, used for the Path generation
|
||||
"""
|
||||
unit_factor = self.calc_unit_factor()
|
||||
|
||||
def create_style(type):
|
||||
style = {'draw': getattr(self.options,type+"_bool"),
|
||||
'stroke': self.get_color_string(getattr(self.options,type+"_stroke_color")),
|
||||
'fill': 'none',
|
||||
'stroke-width': getattr(self.options,type+"_stroke_width") * unit_factor}
|
||||
if getattr(self.options,type+"_dashes_bool"):
|
||||
dash_gap_len = getattr(self.options,type+"_dashes_len")
|
||||
duty = getattr(self.options,type+"_dashes_duty")
|
||||
dash = (dash_gap_len * unit_factor) * duty
|
||||
gap = (dash_gap_len * unit_factor) * (1 - duty)
|
||||
style['stroke-dasharray'] = "{} {}".format(dash, gap)
|
||||
return style
|
||||
|
||||
self.styles_dict = {'m': create_style("mountain"),
|
||||
'v': create_style("valley"),
|
||||
'u': create_style("universal"),
|
||||
's': create_style("semicrease"),
|
||||
'c': create_style("cut"),
|
||||
'e': create_style("edge"),
|
||||
'p': create_style("vertex")}
|
||||
|
||||
def get_color_string(self, longColor, verbose=False):
|
||||
""" Convert the long into a #RRGGBB color value
|
||||
- verbose=true pops up value for us in defaults
|
||||
conversion back is A + B*256^1 + G*256^2 + R*256^3
|
||||
"""
|
||||
# compatibility hack, no "long" in Python 3
|
||||
try:
|
||||
longColor = long(longColor)
|
||||
if longColor < 0: longColor = long(longColor) & 0xFFFFFFFF
|
||||
hexColor = hex(longColor)[2:-3]
|
||||
except:
|
||||
longColor = int(longColor)
|
||||
hexColor = hex(longColor)[2:-2]
|
||||
inkex.debug = inkex.utils.debug
|
||||
|
||||
hexColor = '#' + hexColor.rjust(6, '0').upper()
|
||||
if verbose: inkex.debug("longColor = {}, hex = {}".format(longColor,hexColor))
|
||||
|
||||
return hexColor
|
||||
|
||||
def add_text(self, node, text, position, text_height=12):
|
||||
""" Create and insert a single line of text into the svg under node.
|
||||
"""
|
||||
line_style = {'font-size': '%dpx' % text_height, 'font-style':'normal', 'font-weight': 'normal',
|
||||
'fill': '#F6921E', 'font-family': 'Bitstream Vera Sans,sans-serif',
|
||||
'text-anchor': 'middle', 'text-align': 'center'}
|
||||
line_attribs = {inkex.addNS('label','inkscape'): 'Annotation',
|
||||
'style': simplestyle.formatStyle(line_style),
|
||||
'x': str(position[0]),
|
||||
'y': str((position[1] + text_height) * 1.2)
|
||||
}
|
||||
line = inkex.etree.SubElement(node, inkex.addNS('text','svg'), line_attribs)
|
||||
line.text = text
|
||||
|
||||
|
||||
def calc_unit_factor(self):
|
||||
""" Return the scale factor for all dimension conversions.
|
||||
|
||||
- The document units are always irrelevant as
|
||||
everything in inkscape is expected to be in 90dpi pixel units
|
||||
"""
|
||||
# namedView = self.document.getroot().find(inkex.addNS('namedview', 'sodipodi'))
|
||||
# doc_units = self.getUnittouu(str(1.0) + namedView.get(inkex.addNS('document-units', 'inkscape')))
|
||||
# backwards compatibility
|
||||
try:
|
||||
return self.svg.unittouu(str(1.0) + self.options.units)
|
||||
except:
|
||||
try:
|
||||
return inkex.unittouu(str(1.0) + self.options.units)
|
||||
except AttributeError:
|
||||
return self.unittouu(str(1.0) + self.options.units)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
101
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Pleat_Circular.py
Executable file
101
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Pleat_Circular.py
Executable file
@ -0,0 +1,101 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
import numpy as np
|
||||
|
||||
from math import pi, sin, cos
|
||||
|
||||
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
|
||||
|
||||
|
||||
class PleatCircular(Pattern):
|
||||
|
||||
def __init__(self):
|
||||
""" Constructor
|
||||
"""
|
||||
Pattern.__init__(self) # Must be called in order to parse common options
|
||||
|
||||
# save all custom parameters defined on .inx file
|
||||
self.add_argument('--pattern', type=self.str, default='pleat_circular')
|
||||
self.add_argument('--radius', type=self.float, default=55.0)
|
||||
self.add_argument('--ratio', type=self.float, default=0.4)
|
||||
self.add_argument('--rings', type=self.int, default=15)
|
||||
self.add_argument('--sides', type=self.int, default=20)
|
||||
|
||||
def generate_path_tree(self):
|
||||
""" Specialized path generation for your origami pattern
|
||||
"""
|
||||
# retrieve saved parameters
|
||||
unit_factor = self.calc_unit_factor()
|
||||
R = self.options.radius * unit_factor
|
||||
ratio = self.options.ratio
|
||||
r = R * ratio
|
||||
rings = self.options.rings
|
||||
dr = (1.-ratio)*R/rings
|
||||
self.translate = (R, R)
|
||||
|
||||
if not self.options.simulation_mode:
|
||||
inner_circles = []
|
||||
for i in range(1, rings):
|
||||
inner_circles.append(Path((0, 0), radius=r + i*dr, style='m' if i % 2 else 'v'))
|
||||
|
||||
edges = [Path((0, 0), radius=R, style='e'),
|
||||
Path((0, 0), radius=r, style='e')]
|
||||
|
||||
self.path_tree = [inner_circles, edges]
|
||||
|
||||
# append semicreases for simulation
|
||||
else:
|
||||
sides = self.options.sides
|
||||
dtheta = pi / sides
|
||||
# create diagonals
|
||||
diagonals = []
|
||||
for i in range(sides):
|
||||
p1 = (0, 0)
|
||||
p2 = (R * cos((1 + i * 2) * dtheta), R * sin((1 + i * 2) * dtheta))
|
||||
diagonals.append(Path([p1, p2], 'u'))
|
||||
|
||||
s = sin(dtheta)
|
||||
c = cos(dtheta)
|
||||
|
||||
# Edge
|
||||
paths = [Path([(c * R, -s * R), (R, 0), (c * R, s * R)], style='e'),
|
||||
Path([(c * r, -s * r), (r, 0), (c * r, s * r)], style='e')]
|
||||
|
||||
# MV circles
|
||||
for i in range(1, rings):
|
||||
r_i = r + i * dr
|
||||
paths.append(Path([(c * r_i, -s * r_i), (r_i, 0), (c * r_i, s * r_i)],
|
||||
style='m' if i % 2 else 'v'))
|
||||
|
||||
# Semicreases
|
||||
top = []
|
||||
bottom = []
|
||||
for i in range(rings + 1):
|
||||
r_i = r + i*dr
|
||||
top.append((r_i*(1 + (i % 2)*(c-1)), -(i % 2)*s*r_i))
|
||||
bottom.append((r_i*(1 + (i % 2)*(c-1)), (i % 2)*s*r_i))
|
||||
paths = paths + [Path([(r, 0), (R, 0)], 's'), # straight line 1
|
||||
Path([(r*c, r*s), (R*c, R*s)], 's', invert=True), # straight line 2
|
||||
Path(top, 's'), # top half of semicrease pattern
|
||||
Path(bottom, 's')] # bottom half of semicrease pattern
|
||||
|
||||
all_paths = [paths]
|
||||
for i in range(1, sides):
|
||||
all_paths.append(Path.list_rotate(all_paths[0], i*2*dtheta))
|
||||
|
||||
self.path_tree = all_paths
|
||||
|
||||
|
||||
|
||||
|
||||
# Main function, creates an instance of the Class and calls inkex.affect() to draw the origami on inkscape
|
||||
if __name__ == '__main__':
|
||||
e = PleatCircular() # remember to put the name of your Class here!
|
||||
e.draw()
|
129
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/SupportRing.py
Executable file
129
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/SupportRing.py
Executable file
@ -0,0 +1,129 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
import numpy as np
|
||||
from math import pi, sin, cos
|
||||
|
||||
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
|
||||
|
||||
|
||||
class SupportRing(Pattern):
|
||||
|
||||
def __init__(self):
|
||||
""" Constructor
|
||||
"""
|
||||
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=self.int, default=3)
|
||||
self.add_argument('--radius_external', type=self.float, default=10.0)
|
||||
self.add_argument('--inverted', type=self.bool, default=False)
|
||||
self.add_argument('--single_stroke', type=self.bool, default=True)
|
||||
self.add_argument('--radius_ratio', type=self.float, default=0.5)
|
||||
self.add_argument('--radius_type', type=self.str, default='polygonal')
|
||||
self.add_argument('--radius_draw', type=self.bool, default=True)
|
||||
self.add_argument('--connector_length', type=self.float, default=3.0)
|
||||
self.add_argument('--connector_thickness', type=self.float, default=3.0)
|
||||
self.add_argument('--head_length', type=self.float, default=1.0)
|
||||
self.add_argument('--head_thickness', type=self.float, default=1.0)
|
||||
self.add_argument('--pattern', type=self.str, 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
|
||||
|
||||
inverted = self.options.inverted
|
||||
sign = -1 if inverted else 1
|
||||
single_stroke = self.options.single_stroke
|
||||
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 if inverted else radius_external * radius_ratio
|
||||
# dradius = abs(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 if inverted else length_external * radius_ratio
|
||||
|
||||
external_points = [(-length_external/2, 0),
|
||||
(-connector_thickness / 2, 0),
|
||||
(-connector_thickness / 2, -connector_length*sign),
|
||||
(-connector_thickness / 2 - head_thickness / 2, -connector_length*sign),
|
||||
(-connector_thickness / 2, -(connector_length + head_length)*sign),
|
||||
(0, -(connector_length + head_length)*sign),
|
||||
(+connector_thickness / 2, -(connector_length + head_length)*sign),
|
||||
(+connector_thickness / 2 + head_thickness / 2, -connector_length*sign),
|
||||
(+connector_thickness / 2, -connector_length*sign),
|
||||
(+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))
|
||||
|
||||
if single_stroke:
|
||||
external_lines = Path(Path.get_points(external_lines), 'm')
|
||||
|
||||
self.path_tree = [external_lines]
|
||||
|
||||
if self.options.radius_draw == True:
|
||||
|
||||
# center point of main strokes
|
||||
outer_average = Path.get_average_point(external_lines)
|
||||
|
||||
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))
|
||||
|
||||
# move to center
|
||||
inner_average = Path.get_average_point(internal_lines)
|
||||
delta = ((outer_average[0] - inner_average[0]),
|
||||
(outer_average[1] - inner_average[1]))
|
||||
|
||||
if single_stroke:
|
||||
internal_lines = Path(Path.get_points(internal_lines), 'm')
|
||||
|
||||
internal_lines = Path.list_add(internal_lines, delta)
|
||||
elif radius_type == 'circular':
|
||||
|
||||
internal_lines = Path(outer_average, radius=radius_internal, style='m')
|
||||
|
||||
self.path_tree.append(internal_lines)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Main function, creates an instance of the Class and calls self.draw() to draw the origami on inkscape
|
||||
# self.draw() is either a call to inkex.affect() or to svg.run(), depending on python version
|
||||
if __name__ == '__main__':
|
||||
e = SupportRing() # remember to put the name of your Class here!
|
||||
e.draw()
|
113
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Template.py
Executable file
113
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Template.py
Executable file
@ -0,0 +1,113 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
import numpy as np
|
||||
from math import pi
|
||||
|
||||
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
|
||||
|
||||
|
||||
class Template(Pattern):
|
||||
|
||||
def __init__(self):
|
||||
""" Constructor
|
||||
"""
|
||||
Pattern.__init__(self) # Must be called in order to parse common options
|
||||
|
||||
# save all custom parameters defined on .inx file
|
||||
self.add_argument('--pattern', type=self.str, default='template1')
|
||||
self.add_argument('--length', type=self.float, default=10.0)
|
||||
self.add_argument('--angle', type=self.int, default=0)
|
||||
self.add_argument('--fold_angle_valley', type=self.int, default=180)
|
||||
|
||||
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
|
||||
length = self.options.length * unit_factor
|
||||
vertex_radius = self.options.vertex_radius * unit_factor
|
||||
pattern = self.options.pattern
|
||||
angle = self.options.angle * pi / 180
|
||||
fold_angle_valley = self.options.fold_angle_valley
|
||||
|
||||
# create all Path instances defining strokes
|
||||
# first define its points as a list of tuples...
|
||||
left_right_stroke_points = [(length / 2, 0),
|
||||
(length / 2, length)]
|
||||
up_down_stroke_points = [(0, length / 2),
|
||||
(length, length / 2)]
|
||||
|
||||
# doing the same for diagonals
|
||||
diagonal_1_stroke_points = [(0, 0),
|
||||
(length, length)]
|
||||
diagonal_2_stroke_points = [(0, length),
|
||||
(length, 0)]
|
||||
|
||||
# ... and then create the Path instances, defining its type ('m' for mountain, etc...)
|
||||
if pattern == 'template1':
|
||||
up_down = [Path(left_right_stroke_points, 'm', fold_angle = 180.),
|
||||
Path(up_down_stroke_points, 'm', fold_angle = 180.)]
|
||||
|
||||
diagonals = [Path(diagonal_1_stroke_points, 'v', fold_angle = fold_angle_valley),
|
||||
Path(diagonal_2_stroke_points, 'v', fold_angle = fold_angle_valley)]
|
||||
|
||||
else:
|
||||
up_down = [Path(left_right_stroke_points, 'v', fold_angle = fold_angle_valley),
|
||||
Path(up_down_stroke_points, 'v', fold_angle = fold_angle_valley)]
|
||||
|
||||
diagonals = [Path(diagonal_1_stroke_points, 'm', fold_angle = 180.),
|
||||
Path(diagonal_2_stroke_points, 'm', fold_angle = 180. )]
|
||||
|
||||
vertices = []
|
||||
for i in range(3):
|
||||
for j in range(3):
|
||||
vertices.append(Path(((i/2.) * length, (j/2.) * length), style='p', radius=vertex_radius))
|
||||
|
||||
# multiplication is implemented as a rotation, and list_rotate implements rotation for list of Path instances
|
||||
vertices = Path.list_rotate(vertices, angle, (1 * length, 1 * length))
|
||||
up_down = Path.list_rotate(up_down, angle, (1 * length, 1 * length))
|
||||
diagonals = Path.list_rotate(diagonals, angle, (1 * length, 1 * length))
|
||||
|
||||
# if Path constructor is called with more than two points, a single stroke connecting all of then will be
|
||||
# created. Using method generate_separated_paths, you can instead return a list of separated strokes
|
||||
# linking each two points
|
||||
|
||||
# create a list for edge strokes
|
||||
# create path from points to be able to use the already built rotate method
|
||||
edges = Path.generate_square(length, length, 'e', rotation = angle)
|
||||
edges = Path.list_rotate(edges, angle, (1 * length, 1 * length))
|
||||
|
||||
# IMPORTANT: the attribute "path_tree" must be created at the end, saving all strokes
|
||||
self.path_tree = [up_down, diagonals, vertices]
|
||||
|
||||
# IMPORTANT: at the end, save edge points as "self.edge_points", to simplify selection of single or multiple
|
||||
# strokes for the edge
|
||||
self.edge_points = edges.points
|
||||
|
||||
# if you decide not to declare "self.edge_points", then the edge must be explicitly created in the path_tree:
|
||||
# self.path_tree = [mountains, valleys, vertices, edges]
|
||||
|
||||
# FINAL REMARKS:
|
||||
# division is implemented as a reflection, and list_reflect implements it for a list of Path instances
|
||||
# here's a commented example:
|
||||
# line_reflect = (0 * length, 2 * length, 1 * length, 1 * length)
|
||||
# mountains = Path.list_reflect(mountains, line_reflect)
|
||||
# valleys = Path.list_reflect(valleys, line_reflect)
|
||||
# edges = Path.list_reflect(edges, line_reflect)
|
||||
|
||||
# Main function, creates an instance of the Class and calls self.draw() to draw the origami on inkscape
|
||||
# self.draw() is either a call to inkex.affect() or to svg.run(), depending on python version
|
||||
if __name__ == '__main__':
|
||||
e = Template() # remember to put the name of your Class here!
|
||||
e.draw()
|
112
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Waterbomb.py
Executable file
112
extensions/fablabchemnitz/origami_patterns/OrigamiPatterns/Waterbomb.py
Executable file
@ -0,0 +1,112 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
import math
|
||||
import numpy as np
|
||||
|
||||
import inkex
|
||||
|
||||
from Path import Path
|
||||
from Pattern import Pattern
|
||||
|
||||
# TODO:
|
||||
# Add fractional column number option
|
||||
|
||||
|
||||
class Waterbomb(Pattern):
|
||||
|
||||
def __init__(self):
|
||||
""" Constructor
|
||||
"""
|
||||
Pattern.__init__(self) # Must be called in order to parse common options
|
||||
|
||||
self.add_argument('--pattern', type=self.str, default='waterbomb')
|
||||
self.add_argument('--pattern_first_line', type=self.str, default='waterbomb')
|
||||
self.add_argument('--pattern_last_line', type=self.str, default='waterbomb')
|
||||
self.add_argument('--lines', type=self.int, default=8)
|
||||
self.add_argument('--columns', type=self.int, default=16)
|
||||
self.add_argument('--length', type=self.float, default=10.0)
|
||||
self.add_argument('--phase_shift', type=self.bool, default=True)
|
||||
|
||||
def generate_path_tree(self):
|
||||
""" Specialized path generation for Waterbomb tesselation pattern
|
||||
"""
|
||||
unit_factor = self.calc_unit_factor()
|
||||
length = self.options.length * unit_factor
|
||||
vertex_radius = self.options.vertex_radius * unit_factor
|
||||
cols = self.options.columns
|
||||
lines = self.options.lines
|
||||
phase_shift = self.options.phase_shift
|
||||
pattern_first_line = self.options.pattern_first_line
|
||||
pattern_last_line = self.options.pattern_last_line
|
||||
|
||||
# create vertices
|
||||
vertex_line_types = [[Path(((i / 2.) * length, 0), style='p', radius=vertex_radius) for i in range(2*cols + 1)],
|
||||
[Path((i * length, 0), style='p', radius=vertex_radius) for i in range(cols + 1)],
|
||||
[Path(((i + 0.5) * length, 0), style='p', radius=vertex_radius) for i in range(cols)]]
|
||||
|
||||
vertices = []
|
||||
for i in range(2*lines + 1):
|
||||
if i % 2 == 0 or (pattern_first_line == 'magic_ball' and i == 1) or (pattern_last_line == 'magic_ball' and i == 2*lines - 1):
|
||||
type = 0
|
||||
elif(int(i/2 + phase_shift)) % 2 == 0:
|
||||
type = 1
|
||||
else:
|
||||
type = 2
|
||||
vertices = vertices + Path.list_add(vertex_line_types[type], (0, 0.5*i*length))
|
||||
|
||||
# create a list for the horizontal creases and another for the vertical creases
|
||||
# alternate strokes to minimize laser cutter path
|
||||
corr_fist_line = length/2 if pattern_first_line == 'magic_ball' else 0
|
||||
corr_last_line = length/2 if pattern_last_line == 'magic_ball' else 0
|
||||
grid = [Path.generate_hgrid([0, length*cols], [0, length*lines], lines, 'm'),
|
||||
Path.generate_vgrid([0, length*cols], [corr_fist_line, length*lines-corr_last_line], 2*cols, 'm')]
|
||||
|
||||
vgrid_a = Path.generate_vgrid([0, length * cols], [0, length / 2], 2 * cols, 'v')
|
||||
vgrid_b = Path.list_add(vgrid_a, (0, (lines - 0.5) * length))
|
||||
if pattern_first_line == 'magic_ball' and pattern_last_line == 'magic_ball':
|
||||
grid[1] = [[vgrid_a[i], grid[1][i], vgrid_b[i]] if i % 2 == 0 else
|
||||
[vgrid_b[i], grid[1][i], vgrid_a[i]] for i in range(len(grid[1]))]
|
||||
elif pattern_first_line == 'magic_ball':
|
||||
grid[1] = [[vgrid_a[i], grid[1][i]] if i % 2 == 0 else
|
||||
[grid[1][i], vgrid_a[i]] for i in range(len(grid[1]))]
|
||||
elif pattern_last_line == 'magic_ball':
|
||||
grid[1] = [[grid[1][i], vgrid_b[i]] if i % 2 == 0 else
|
||||
[vgrid_b[i], grid[1][i]] for i in range(len(grid[1]))]
|
||||
|
||||
# create generic valley Path lines, one pointing up and other pointing down
|
||||
valley_types = [Path([(i * length / 2, (1 - i % 2) * length / 2) for i in range(2 * cols + 1)], 'v'),
|
||||
Path([( i*length/2, (i % 2)*length/2) for i in range(2 * cols + 1)], 'v')]
|
||||
|
||||
# define which lines must be of which type, according to parity and options
|
||||
senses = np.array([bool((i % 2+i)/2 % 2) for i in range(2*lines)])
|
||||
senses = 1*senses # converts bool array to 0's and 1's
|
||||
if phase_shift:
|
||||
senses = np.invert(senses)
|
||||
if pattern_first_line == "magic_ball":
|
||||
senses[0] = ~senses[0]
|
||||
if pattern_last_line == "magic_ball":
|
||||
senses[-1] = ~senses[-1]
|
||||
valleys = [valley_types[senses[i]] + (0, i * length / 2) for i in range(2*lines)]
|
||||
|
||||
# convert first and last lines to mountains if magic_ball
|
||||
if pattern_first_line == "magic_ball":
|
||||
valleys[0].style = 'm'
|
||||
if pattern_last_line == "magic_ball":
|
||||
valleys[-1].style = 'm'
|
||||
|
||||
# invert every two lines to minimize laser cutter movements
|
||||
for i in range(1, 2*lines, 2):
|
||||
valleys[i].invert()
|
||||
|
||||
self.edge_points = [(0*length*cols, 0*length*lines), # top left
|
||||
(1*length*cols, 0*length*lines), # top right
|
||||
(1*length*cols, 1*length*lines), # bottom right
|
||||
(0*length*cols, 1*length*lines)] # bottom left
|
||||
|
||||
self.path_tree = [grid, valleys, vertices]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
e = Waterbomb()
|
||||
e.draw()
|
31
extensions/fablabchemnitz/origami_patterns/Support_Ring_Belt/Belt.scad
Executable file
31
extensions/fablabchemnitz/origami_patterns/Support_Ring_Belt/Belt.scad
Executable file
@ -0,0 +1,31 @@
|
||||
module draw_cone(R,n,h,thickness){
|
||||
difference(){
|
||||
cylinder(h=h, r1=R+thickness, r2=R+thickness, center=true, $fn=n);
|
||||
cylinder(h=h, r1=R, r2=R, center=true, $fn=n);
|
||||
cylinder(h=h, r1=R, r2=R, center=true, $fn=n);
|
||||
}
|
||||
}
|
||||
|
||||
module draw_cut_boxes(R, n, thickness, slot_height, slot_width){
|
||||
union(){
|
||||
for (i=[0: n/2]){
|
||||
rotate(a=i*360/n, v=[0,0,1])
|
||||
cube([2*(R+thickness),slot_height,slot_width], center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module draw_belt(R, n, h, thickness, slot_height, slot_width){
|
||||
difference(){
|
||||
rotate(a=180/n, v=[0,0,1]) draw_cone(R, n, h, thickness);
|
||||
draw_cut_boxes(R, n, thickness, slot_height, slot_width);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
13
extensions/fablabchemnitz/origami_patterns/Support_Ring_Belt/Belt_main.scad
Executable file
13
extensions/fablabchemnitz/origami_patterns/Support_Ring_Belt/Belt_main.scad
Executable file
@ -0,0 +1,13 @@
|
||||
include <Belt.scad>
|
||||
|
||||
// Input parameters
|
||||
R = 35;
|
||||
n = 8;
|
||||
height = 7; // height of support
|
||||
thickness = 1; // thickness of belt
|
||||
|
||||
// square cuts to be pierced by support ring
|
||||
slot_height=3; // must be smaller than height
|
||||
slot_width=3;
|
||||
|
||||
draw_belt(R, n, height, thickness, slot_height, slot_width);
|
5
extensions/fablabchemnitz/origami_patterns/Support_Ring_Belt/README.md
Executable file
5
extensions/fablabchemnitz/origami_patterns/Support_Ring_Belt/README.md
Executable file
@ -0,0 +1,5 @@
|
||||
# Origami_Patterns_Support_Belt
|
||||
|
||||
Designed to be used with the [Origami Patterns Inkscape extension](https://github.com/evbernardes/Origami_Patterns).
|
||||
|
||||
3D Print this with TPU (or any other flexible material) and use together with the support rings.
|
384
extensions/fablabchemnitz/origami_patterns/logo.svg
Executable file
384
extensions/fablabchemnitz/origami_patterns/logo.svg
Executable file
@ -0,0 +1,384 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 128 128"
|
||||
inkscape:export-ydpi="45"
|
||||
inkscape:export-xdpi="45"
|
||||
inkscape:export-filename="/home/valessio/Desenvolvimento/inkscape/inkscape/inkscape.png"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
sodipodi:docname="logo.svg"
|
||||
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, custom)"
|
||||
sodipodi:version="0.32"
|
||||
id="svg2"
|
||||
height="128"
|
||||
width="128"
|
||||
version="1.0"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<title
|
||||
id="title7387">Inkscape Logo</title>
|
||||
<sodipodi:namedview
|
||||
bordercohor="#666666"
|
||||
inkscape:window-height="716"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
guidetolerance="10.0"
|
||||
gridtolerance="10.0"
|
||||
objecttolerance="10.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base"
|
||||
inkscape:zoom="2.5937425"
|
||||
inkscape:cx="60.144752"
|
||||
inkscape:cy="65.349587"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:document-units="px"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:snap-intersection-paths="true" />
|
||||
<defs
|
||||
id="defs4" />
|
||||
<style
|
||||
type="text/css"
|
||||
id="style26">
|
||||
.specularity {opacity:0.5;}
|
||||
.low-specularity {opacity:0.25;}
|
||||
.full-specularity {opacity:1;}
|
||||
.black {fill:#000000;}
|
||||
.white {fill:#ffffff;}
|
||||
.outline-big {stroke-width:16;stroke:none;opacity:0.1;fill:none;}
|
||||
.outline-small {stroke-width:8;stroke:none;opacity:0.2;fill:none;}
|
||||
.stroke-highlight {fill:none;stroke:none;opacity:0.2;}
|
||||
.base-shadow {fill:black;opacity:75;}
|
||||
</style>
|
||||
<!-- Copyright License -->
|
||||
<metadata
|
||||
id="metadata49">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="etiquette-icon">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Andy Fitzsimon</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title>Andrew Michael Fitzsimon</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<dc:publisher>
|
||||
<cc:Agent>
|
||||
<dc:title>Fitzsimon IT Consulting Pty Ltd</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:identifier>http://andy.fitzsimon.com.au</dc:identifier>
|
||||
<dc:date>2006</dc:date>
|
||||
<cc:license
|
||||
rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
|
||||
<dc:title>Inkscape Logo</dc:title>
|
||||
</cc:Work>
|
||||
<cc:License
|
||||
rdf:about="http://creativecommons.org/licenses/by-sa/3.0/">
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Notice" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Attribution" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
inkscape:label="Inkscape Flat Logo 2 Color Variant">
|
||||
<g
|
||||
id="g11223-6"
|
||||
transform="translate(-363.14098,-180.14807)">
|
||||
<path
|
||||
id="path6262-1"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="m 433.13709,195.71708 -1.30659,1.30659 -7.75944,-7.75944" />
|
||||
<path
|
||||
id="path6256-5"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="m 410.05994,203.59956 2.87293,2.87293 9.44881,-9.44882 9.44882,9.44882 4.28302,-4.28302" />
|
||||
<path
|
||||
id="path6250-9"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="m 442.06249,215.13814 -0.78317,0.78317 -9.44882,-9.44882 -9.44882,9.44882 -9.44881,-9.44882 -9.44882,9.44882 -2.76356,-2.76356" />
|
||||
<path
|
||||
id="path6244-4"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="m 396.05076,217.93684 7.43329,7.43328 9.44882,-9.44881 9.44881,9.44881 9.44882,-9.44881 9.44882,9.44881 3.75961,-3.7596" />
|
||||
<path
|
||||
id="path6238-9"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="m 450.98792,234.55916 -0.25978,0.25978 -9.44882,-9.44882 -9.44882,9.44882 -9.44882,-9.44882 -9.44881,9.44882 -9.44882,-9.44882 -9.44882,9.44882 -7.32467,-7.32467" />
|
||||
<path
|
||||
id="path6232-0"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="m 377.2918,242.11356 7.29461,-7.29462 9.44882,9.44882 9.44882,-9.44882 9.44882,9.44882 9.44881,-9.44882 9.44882,9.44882 9.44882,-9.44882 9.44882,9.44882 3.23425,-3.23423" />
|
||||
<path
|
||||
id="path6226-9"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="m 459.4641,253.00372 -8.73596,-8.73596 -9.44882,9.44882 -9.44882,-9.44882 -9.44882,9.44882 -9.44881,-9.44882 -9.44882,9.44882 -9.44882,-9.44882 -6.0349,6.0349" />
|
||||
<path
|
||||
id="path6220-1"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="m 399.93928,259.62063 3.54477,3.54477 9.44882,-9.44882 9.44881,9.44882 9.44882,-9.44882 9.44882,9.44882 9.44882,-9.44882 9.44882,9.44882 2.71109,-2.71111" />
|
||||
<path
|
||||
id="path6214-7"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="m 471.31338,270.92662 -1.6876,1.6876 -9.44882,-9.44882 -9.44882,9.44882 -9.44882,-9.44882 -9.44882,9.44882 -9.44882,-9.44882 -9.44881,9.44882 -9.44882,-9.44882 -5.78649,5.78649" />
|
||||
<path
|
||||
id="path6208-7"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="m 469.69219,281.99664 5.21462,-5.21463" />
|
||||
<path
|
||||
id="path6206-1"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="m 469.59648,282.03374 0.0293,0.0293 0.0664,-0.0664" />
|
||||
<path
|
||||
id="path6204-1"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="m 418.49961,276.49629 3.88207,-3.88207 9.44882,9.44882 9.44882,-9.44882 9.44882,9.44882 9.44882,-9.44882 9.41952,9.41952" />
|
||||
<path
|
||||
id="path6198-5"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="m 455.79433,287.12923 -5.06619,-5.06619 -9.44882,9.44882 -9.44882,-9.44882 -9.44882,9.44882 -5.2552,-5.2552" />
|
||||
<path
|
||||
id="path6192-9"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="m 428.44588,294.89648 3.38462,-3.38462 9.44882,9.44882 9.44882,-9.44882 5.80835,5.80835" />
|
||||
<path
|
||||
id="path6186-7"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="m 443.64641,303.32776 -2.36709,-2.36708 -3.08189,3.08191" />
|
||||
<path
|
||||
id="path6391-7"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="m 416.48883,197.02367 h 17.24985" />
|
||||
<path
|
||||
id="path6385-6"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="m 442.42419,215.92132 -44.40396,-1e-5" />
|
||||
<path
|
||||
id="path6379-7"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="m 380.18051,234.81893 70.92719,1e-5" />
|
||||
<path
|
||||
id="path6373-3"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="M 459.79318,253.71658 H 401.26239" />
|
||||
<path
|
||||
id="path6367-6"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="m 408.27014,272.61422 h 65.51707" />
|
||||
<path
|
||||
id="path6361-5"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="m 451.65652,291.51186 -33.95677,-1e-5" />
|
||||
<path
|
||||
id="path6349-6"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="m 394.03522,251.74531 1e-5,-31.74616" />
|
||||
<path
|
||||
id="path6335-3"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.378;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 403.48406,210.32922 -2e-5,44.28524" />
|
||||
<path
|
||||
id="path6329-9"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="M 412.93287,274.2102 V 200.65927" />
|
||||
<path
|
||||
id="path6323-4"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="M 422.38168,190.99324 V 293.01688" />
|
||||
<path
|
||||
id="path6317-8"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="m 431.83051,300.63994 -1e-5,-107.76974" />
|
||||
<path
|
||||
id="path6311-1"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="m 441.27932,213.43274 v 90.35173" />
|
||||
<path
|
||||
id="path6305-2"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="m 450.72813,300.88603 10e-6,-66.89272" />
|
||||
<path
|
||||
id="path6299-9"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="m 460.17696,254.55391 v 30.1817" />
|
||||
<path
|
||||
id="path6293-3"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="M 469.62578,282.02076 V 269.98558" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 65.083241,4.8918538 18.973468,52.075943 c -15.579296,19.293065 10.602433,17.048329 21.826117,22.605253 4.02611,4.11535 -15.431707,7.152953 -11.405596,11.271736 4.02611,4.11535 24.345438,7.928656 28.378413,12.044007 4.02611,4.115351 -8.240998,8.481261 -4.214888,12.596611 4.02611,4.11535 13.337992,0.21624 15.08161,9.71689 1.242499,6.78913 16.780608,2.91748 24.379766,-2.64288 4.02611,-4.11878 -7.702128,-3.73093 -3.676018,-7.84628 10.012078,-10.23861 19.334258,-3.72064 22.759708,-13.979837 1.69213,-5.069536 -14.73838,-7.815391 -10.7054,-11.930741"
|
||||
id="path2313" />
|
||||
<path
|
||||
d="m 54.048336,77.234841 c 1.232202,0.765407 19.869695,4.551255 24.424382,5.306366 1.578867,0.332934 0.459931,1.959854 -1.71616,3.058196 -4.908216,1.304281 -28.71478,-8.364562 -22.708222,-8.364562 z"
|
||||
id="path2315"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 65.083242,4.8918543 C 53.499169,11.656955 13.461169,16.06062 32.459049,35.058506 l 47.795048,48.852196 c 5.84524,5.611842 15.599893,5.673624 21.143083,0"
|
||||
id="path2322" />
|
||||
<path
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.378;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 65.083242,4.8918543 101.39718,83.910702"
|
||||
id="path3130" />
|
||||
<g
|
||||
id="g11223">
|
||||
<path
|
||||
id="path6262"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="M 433.13709 195.71708 L 431.8305 197.02367 L 424.07106 189.26423 " />
|
||||
<path
|
||||
id="path6256"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="M 410.05994 203.59956 L 412.93287 206.47249 L 422.38168 197.02367 L 431.8305 206.47249 L 436.11352 202.18947 " />
|
||||
<path
|
||||
id="path6250"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="M 442.06249 215.13814 L 441.27932 215.92131 L 431.8305 206.47249 L 422.38168 215.92131 L 412.93287 206.47249 L 403.48405 215.92131 L 400.72049 213.15775 " />
|
||||
<path
|
||||
id="path6244"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="M 396.05076 217.93684 L 403.48405 225.37012 L 412.93287 215.92131 L 422.38168 225.37012 L 431.8305 215.92131 L 441.27932 225.37012 L 445.03893 221.61052 " />
|
||||
<path
|
||||
id="path6238"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="M 450.98792 234.55916 L 450.72814 234.81894 L 441.27932 225.37012 L 431.8305 234.81894 L 422.38168 225.37012 L 412.93287 234.81894 L 403.48405 225.37012 L 394.03523 234.81894 L 386.71056 227.49427 " />
|
||||
<path
|
||||
id="path6232"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="M 377.2918 242.11356 L 384.58641 234.81894 L 394.03523 244.26776 L 403.48405 234.81894 L 412.93287 244.26776 L 422.38168 234.81894 L 431.8305 244.26776 L 441.27932 234.81894 L 450.72814 244.26776 L 453.96239 241.03353 " />
|
||||
<path
|
||||
id="path6226"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="M 459.4641 253.00372 L 450.72814 244.26776 L 441.27932 253.71658 L 431.8305 244.26776 L 422.38168 253.71658 L 412.93287 244.26776 L 403.48405 253.71658 L 394.03523 244.26776 L 388.00033 250.30266 " />
|
||||
<path
|
||||
id="path6220"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="M 399.93928 259.62063 L 403.48405 263.1654 L 412.93287 253.71658 L 422.38168 263.1654 L 431.8305 253.71658 L 441.27932 263.1654 L 450.72814 253.71658 L 460.17696 263.1654 L 462.88805 260.45429 " />
|
||||
<path
|
||||
id="path6214"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="M 471.31338 270.92662 L 469.62578 272.61422 L 460.17696 263.1654 L 450.72814 272.61422 L 441.27932 263.1654 L 431.8305 272.61422 L 422.38168 263.1654 L 412.93287 272.61422 L 403.48405 263.1654 L 397.69756 268.95189 " />
|
||||
<path
|
||||
id="path6208"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="M 469.69219 281.99664 L 474.90681 276.78201 " />
|
||||
<path
|
||||
id="path6206"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="M 469.59648 282.03374 L 469.62578 282.06304 L 469.69219 281.99664 " />
|
||||
<path
|
||||
id="path6204"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="M 418.49961 276.49629 L 422.38168 272.61422 L 431.8305 282.06304 L 441.27932 272.61422 L 450.72814 282.06304 L 460.17696 272.61422 L 469.59648 282.03374 " />
|
||||
<path
|
||||
id="path6198"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="M 455.79433 287.12923 L 450.72814 282.06304 L 441.27932 291.51186 L 431.8305 282.06304 L 422.38168 291.51186 L 417.12648 286.25666 " />
|
||||
<path
|
||||
id="path6192"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="M 428.44588 294.89648 L 431.8305 291.51186 L 441.27932 300.96068 L 450.72814 291.51186 L 456.53649 297.32021 " />
|
||||
<path
|
||||
id="path6186"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:0.377953"
|
||||
d="M 443.64641 303.32776 L 441.27932 300.96068 L 438.19743 304.04259 " />
|
||||
<path
|
||||
id="path6391"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="M 416.48883 197.02367 L 433.73868 197.02367 " />
|
||||
<path
|
||||
id="path6385"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="M 442.42419 215.92132 L 398.02023 215.92131 " />
|
||||
<path
|
||||
id="path6379"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="M 380.18051 234.81893 L 451.1077 234.81894 " />
|
||||
<path
|
||||
id="path6373"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="M 459.79318 253.71658 L 401.26239 253.71658 " />
|
||||
<path
|
||||
id="path6367"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="M 408.27014 272.61422 L 473.78721 272.61422 " />
|
||||
<path
|
||||
id="path6361"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="M 451.65652 291.51186 L 417.69975 291.51185 " />
|
||||
<path
|
||||
id="path6349"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="M 394.03522 251.74531 L 394.03523 219.99915 " />
|
||||
<path
|
||||
id="path6335"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="M 403.48406 210.32922 L 403.48404 254.61446 " />
|
||||
<path
|
||||
id="path6329"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="M 412.93287 274.2102 L 412.93287 200.65927 " />
|
||||
<path
|
||||
id="path6323"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="M 422.38168 190.99324 L 422.38168 293.01688 " />
|
||||
<path
|
||||
id="path6317"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="M 431.83051 300.63994 L 431.8305 192.8702 " />
|
||||
<path
|
||||
id="path6311"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="M 441.27932 213.43274 L 441.27932 303.78447 " />
|
||||
<path
|
||||
id="path6305"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="M 450.72813 300.88603 L 450.72814 233.99331 " />
|
||||
<path
|
||||
id="path6299"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="M 460.17696 254.55391 L 460.17696 284.73561 " />
|
||||
<path
|
||||
id="path6293"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.377953"
|
||||
d="M 469.62578 282.02076 L 469.62578 269.98558 " />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 464.53477,264.03673 c -4.03298,4.11535 12.39753,6.86121 10.7054,11.93074 -3.42546,10.2592 -12.74763,3.74123 -22.75971,13.97984 -4.02611,4.11535 7.70213,3.7275 3.67602,7.84628 -7.59916,5.56036 -23.13727,9.43201 -24.37977,2.64288 -1.74361,-9.50065 -11.0555,-5.60154 -15.08161,-9.71689 -4.02611,-4.11535 8.241,-8.48126 4.21489,-12.59661 -4.03297,-4.11535 -24.3523,-7.92866 -28.37841,-12.04401 -4.02611,-4.11878 15.4317,-7.15638 11.40559,-11.27173 -11.22368,-5.55693 -37.40541,-3.31219 -21.82611,-22.60526 l 46.10977,-47.18409 0,0 z"
|
||||
id="path5392-9"
|
||||
sodipodi:nodetypes="cccccscccccccc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 18 KiB |
21
extensions/fablabchemnitz/origami_patterns/meta.json
Normal file
21
extensions/fablabchemnitz/origami_patterns/meta.json
Normal file
@ -0,0 +1,21 @@
|
||||
[
|
||||
{
|
||||
"name": "Origami Pattern - <various>",
|
||||
"id": "fablabchemnitz.de.origami_patterns.<various>",
|
||||
"path": "origami_patterns",
|
||||
"dependent_extensions": null,
|
||||
"original_name": "<various>",
|
||||
"original_id": "org.inkscape.Origami_patterns.<various>",
|
||||
"license": "MIT License",
|
||||
"license_url": "https://github.com/evbernardes/Origami_Patterns/blob/master/LICENSE",
|
||||
"comment": "",
|
||||
"source_url": "https://gitea.fablabchemnitz.de/FabLab_Chemnitz/mightyscape-1.X/src/branch/master/extensions/fablabchemnitz/origami_patterns",
|
||||
"fork_url": "https://github.com/evbernardes/Origami_Patterns",
|
||||
"documentation_url": "https://stadtfabrikanten.org/display/IFM/Origami+Patterns",
|
||||
"inkscape_gallery_url": null,
|
||||
"main_authors": [
|
||||
"github.com/evbernardes",
|
||||
"github.com/vmario89"
|
||||
]
|
||||
}
|
||||
]
|
@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>Masu box (width and height)</name>
|
||||
<id>org.inkscape.Origami_patterns.boxes_masu</id>
|
||||
<param name="active-tab" type="notebook">
|
||||
<page name="title" gui-text="Options">
|
||||
<param name="width" type="float" max="10000" precision="3" gui-text="Width of box">10.0</param>
|
||||
<param name="height" type="float" max="10000" precision="3" gui-text="Height of box">10.0</param>
|
||||
<label>Needs a square paper of size: sqrt(2) * (width + 2*height).</label>
|
||||
<param name="width_delta" type="float" max="10000" precision="3" gui-text="Width increase*:">0.0</param>
|
||||
<param name="width_delta_bool" type="bool" gui-text="Add width increase*">false</param>
|
||||
<label>* this "width increase" slightly modifies the pattern for having a slightly bigger width and slightly smaller height, while keeping the same paper size. This is useful for creating companion box lids.</label>
|
||||
<param name="units" type="optiongroup" appearance="combo" gui-text="Units">
|
||||
<option value="mm">mm</option>
|
||||
<option value="cm">cm</option>
|
||||
<option value="in">in</option>
|
||||
<option value="pt">pt</option>
|
||||
<option value="px">px</option>
|
||||
</param>
|
||||
<param name="simulation_mode" type="bool" gui-text="Simulation mode">true</param>
|
||||
</page>
|
||||
<page name="mountains" gui-text="Mountain creases">
|
||||
<param name="mountain_bool" type="bool" gui-text="Draw mountains?">true</param>
|
||||
<param name="mountain_bool_only" type="bool" gui-text="Draw ONLY mountains?">false</param>
|
||||
<param name="mountain_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="mountain_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Mountain dash + gap length">1</param>
|
||||
<param name="mountain_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Mountain dash duty cycle">0.5</param>
|
||||
<param name="mountain_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of mountain strokes">0.1</param>
|
||||
<param name="mountain_stroke_color" type="color" gui-text="Mountain creases color: ">4278190335</param>
|
||||
</page>
|
||||
<page name="valleys" gui-text="Valley creases">
|
||||
<param name="valley_bool" type="bool" gui-text="Draw valley?">true</param>
|
||||
<param name="valley_bool_only" type="bool" gui-text="Draw ONLY valleys?">false</param>
|
||||
<param name="valley_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="valley_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Valley dash + gap length">1</param>
|
||||
<param name="valley_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Valley dash duty cycle">0.25</param>
|
||||
<param name="valley_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of valley strokes">0.1</param>
|
||||
<param name="valley_stroke_color" type="color" gui-text="Valley creases color: ">65535</param>
|
||||
</page>
|
||||
<page name="edge" gui-text="Edge">
|
||||
<param name="edge_bool" type="bool" gui-text="Draw edges?">true</param>
|
||||
<param name="edge_bool_only" type="bool" gui-text="Draw ONLY edges?">false</param>
|
||||
<param name="edge_single_path" type="bool" gui-text="Edges as single path?">true</param>
|
||||
<param name="edge_dashes_bool" type="bool" gui-text="Dashed strokes?">false</param>
|
||||
<param name="edge_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Edge dash + gap length">1</param>
|
||||
<param name="edge_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Edge dash duty cycle">0.25</param>
|
||||
<param name="edge_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of edge strokes">0.1</param>
|
||||
<param name="edge_stroke_color" type="color" gui-text="Edge color: ">255</param>
|
||||
</page>
|
||||
<page name="vertices" gui-text="Vertices">
|
||||
<param name="vertex_bool" type="bool" gui-text="Draw vertices?">true</param>
|
||||
<param name="vertex_bool_only" type="bool" gui-text="Draw ONLY vertices?">false</param>
|
||||
<param name="vertex_radius" type="float" min="0.01" max="50" appearance="full" gui-text="Radius of vertices">0.1</param>
|
||||
<param name="vertex_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of vertex strokes">0.1</param>
|
||||
<param name="vertex_stroke_color" type="color" gui-text="Vertices\' color: ">255</param>
|
||||
</page>
|
||||
</param>
|
||||
<effect>
|
||||
<object-type>all</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="Origami Patterns">
|
||||
<submenu name="Boxes" />
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command location="inx" interpreter="python">OrigamiPatterns/Boxes_Masu.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>Masu box (traditional)</name>
|
||||
<id>org.inkscape.Origami_patterns.boxes_masu_traditional</id>
|
||||
<param name="active-tab" type="notebook">
|
||||
<page name="options" gui-text="Options">
|
||||
<param name="length" type="float" max="10000" precision="3" gui-text="Length of square paper">10.0</param>
|
||||
<label>Creates a box of width = length / (2 * ( sqrt(2)) and height = width / 2.</label>
|
||||
<param name="units" type="optiongroup" appearance="combo" gui-text="Units">
|
||||
<option value="mm">mm</option>
|
||||
<option value="cm">cm</option>
|
||||
<option value="in">in</option>
|
||||
<option value="pt">pt</option>
|
||||
<option value="px">px</option>
|
||||
</param>
|
||||
<param name="simulation_mode" type="bool" gui-text="Simulation mode">true</param>
|
||||
</page>
|
||||
<page name="mountains" gui-text="Mountain creases">
|
||||
<param name="mountain_bool" type="bool" gui-text="Draw mountains?">true</param>
|
||||
<param name="mountain_bool_only" type="bool" gui-text="Draw ONLY mountains?">false</param>
|
||||
<param name="mountain_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="mountain_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Mountain dash + gap length">1</param>
|
||||
<param name="mountain_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Mountain dash duty cycle">0.5</param>
|
||||
<param name="mountain_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of mountain strokes">0.1</param>
|
||||
<param name="mountain_stroke_color" type="color" gui-text="Mountain creases color: ">4278190335</param>
|
||||
</page>
|
||||
<page name="valleys" gui-text="Valley creases">
|
||||
<param name="valley_bool" type="bool" gui-text="Draw valley?">true</param>
|
||||
<param name="valley_bool_only" type="bool" gui-text="Draw ONLY valleys?">false</param>
|
||||
<param name="valley_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="valley_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Valley dash + gap length">1</param>
|
||||
<param name="valley_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Valley dash duty cycle">0.25</param>
|
||||
<param name="valley_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of valley strokes">0.1</param>
|
||||
<param name="valley_stroke_color" type="color" gui-text="Valley creases color: ">65535</param>
|
||||
</page>
|
||||
<page name="edge" gui-text="Edge">
|
||||
<param name="edge_bool" type="bool" gui-text="Draw edges?">true</param>
|
||||
<param name="edge_bool_only" type="bool" gui-text="Draw ONLY edges?">false</param>
|
||||
<param name="edge_single_path" type="bool" gui-text="Edges as single path?">true</param>
|
||||
<param name="edge_dashes_bool" type="bool" gui-text="Dashed strokes?">false</param>
|
||||
<param name="edge_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Edge dash + gap length">1</param>
|
||||
<param name="edge_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Edge dash duty cycle">0.25</param>
|
||||
<param name="edge_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of edge strokes">0.1</param>
|
||||
<param name="edge_stroke_color" type="color" gui-text="Edge color: ">255</param>
|
||||
</page>
|
||||
<page name="vertices" gui-text="Vertices">
|
||||
<param name="vertex_bool" type="bool" gui-text="Draw vertices?">true</param>
|
||||
<param name="vertex_bool_only" type="bool" gui-text="Draw ONLY vertices?">false</param>
|
||||
<param name="vertex_radius" type="float" min="0.01" max="50" appearance="full" gui-text="Radius of vertices">0.1</param>
|
||||
<param name="vertex_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of vertex strokes">0.1</param>
|
||||
<param name="vertex_stroke_color" type="color" gui-text="Vertices\' color: ">255</param>
|
||||
</page>
|
||||
</param>
|
||||
<effect>
|
||||
<object-type>all</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="Origami Patterns">
|
||||
<submenu name="Boxes" />
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command location="inx" interpreter="python">OrigamiPatterns/Boxes_Masu_Traditional.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
@ -0,0 +1,111 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>Bendy Straw</name>
|
||||
<id>org.inkscape.Origami_patterns.cylindrical_bendy</id>
|
||||
<param name="active-tab" type="notebook">
|
||||
<page name="title" gui-text="Options">
|
||||
<param name="pattern_type" type="optiongroup" appearance="combo" gui-text="Type of pattern:">
|
||||
<option value="origami">Origami regular</option>
|
||||
<option value="origami_bent">Origami bent</option>
|
||||
<option value="kirigami1">Kirigami mode 1</option>
|
||||
<option value="kirigami2">Kirigami mode 2</option>
|
||||
</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="n" type="int" min="3" max="25" gui-text="Number of sides of polygon">6</param>
|
||||
<param name="lines" type="int" min="1" max="100" gui-text="Number of cells">3</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="radius" type="float" max="10000" precision="3" gui-text="Radius of bigger polygon">25.0</param>
|
||||
<param name="radial_ratio" type="float" max="1.0" min="0.0001" precision="3" gui-text="Ratio small radius/big radius">0.75</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="parameter_type" type="optiongroup" appearance="combo" gui-text="Parameter:">
|
||||
<option value="angles">Angles (alpha1, alpha2)</option>
|
||||
<option value="heights">Heights (h1, h2)</option>
|
||||
</param>
|
||||
<param name="alpha1" type="int" min="5" max="90" gui-text="Angle of superior cone (alpha1)">45</param>
|
||||
<param name="alpha2" type="int" min="5" max="90" gui-text="Angle of inferior cone (alpha2)">35</param>
|
||||
<param name="h1" type="float" min="0" max="200.0" precision="3" gui-text="Height of superior cone (h1)">1</param>
|
||||
<param name="h2" type="float" min="0" max="200.0" precision="3" gui-text="Height of inferior cone (h2)">2</param>
|
||||
<param name="units" type="optiongroup" appearance="combo" gui-text="Units">
|
||||
<option value="mm">mm</option>
|
||||
<option value="cm">cm</option>
|
||||
<option value="in">in</option>
|
||||
<option value="pt">pt</option>
|
||||
<option value="px">px</option>
|
||||
</param>
|
||||
<label>As published in: https://doi.org/10.1115/1.4052222</label>
|
||||
<param name="simulation_mode" type="bool" gui-text="Simulation mode">true</param>
|
||||
</page>
|
||||
<page name="extra" gui-text="Extra">
|
||||
<param name="add_attachment" type="bool" gui-text="Add attachments?">false</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="base_height" type="float" max="10000" precision="3" gui-text="Height of base">5.0</param>
|
||||
<param name="add_base_slot" type="bool" gui-text="Add base slots?">false</param>
|
||||
<param name="center_base_slot" type="bool" gui-text="Center base slots?">false</param>
|
||||
<param name="base_slot_height" type="float" max="10000" precision="3" gui-text="Height of base slot">3.0</param>
|
||||
<param name="base_slot_width" type="float" max="10000" precision="3" gui-text="Width of base slow">3.0</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="distance" type="float" max="10000" precision="3" gui-text="Distance between cells">3.0</param>
|
||||
<param name="add_distance_slot" type="bool" gui-text="Add slots between cells?">false</param>
|
||||
<param name="distance_slot_height" type="float" max="10000" precision="3" gui-text="Height of slots between cells">3.0</param>
|
||||
<param name="distance_slot_width" type="float" max="10000" precision="3" gui-text="Width of slots between cells">3.0</param>
|
||||
</page>
|
||||
<page name="mountains" gui-text="Mountains">
|
||||
<param name="mountain_bool" type="bool" gui-text="Draw mountains?">true</param>
|
||||
<param name="mountain_bool_only" type="bool" gui-text="Draw ONLY mountains?">false</param>
|
||||
<param name="mountain_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="mountain_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Mountain dash + gap length">1</param>
|
||||
<param name="mountain_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Mountain dash duty cycle">0.5</param>
|
||||
<param name="mountain_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of mountain strokes">0.1</param>
|
||||
<param name="mountain_stroke_color" type="color" gui-text="Mountain creases color: ">4278190335</param>
|
||||
</page>
|
||||
<page name="valleys" gui-text="Valleys">
|
||||
<param name="valley_bool" type="bool" gui-text="Draw valley?">true</param>
|
||||
<param name="valley_bool_only" type="bool" gui-text="Draw ONLY valleys?">false</param>
|
||||
<param name="valley_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="valley_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Valley dash + gap length">1</param>
|
||||
<param name="valley_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Valley dash duty cycle">0.25</param>
|
||||
<param name="valley_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of valley strokes">0.1</param>
|
||||
<param name="valley_stroke_color" type="color" gui-text="Valley creases color: ">65535</param>
|
||||
</page>
|
||||
<page name="cuts" gui-text="Cuts">
|
||||
<param name="cut_bool" type="bool" gui-text="Draw cuts?">true</param>
|
||||
<param name="cut_dashes_bool" type="bool" gui-text="Dashed strokes?">false</param>
|
||||
<param name="cut_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Cut dash + gap length">1</param>
|
||||
<param name="cut_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Cut dash duty cycle">0.25</param>
|
||||
<param name="cut_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of cut strokes">0.1</param>
|
||||
<param name="cut_stroke_color" type="color" gui-text="Cut creases color: ">16711935</param>
|
||||
</page>
|
||||
<page name="edge" gui-text="Edge">
|
||||
<param name="edge_bool" type="bool" gui-text="Draw edges?">true</param>
|
||||
<param name="edge_bool_only" type="bool" gui-text="Draw ONLY edges?">false</param>
|
||||
<param name="edge_single_path" type="bool" gui-text="Edges as single path?">true</param>
|
||||
<param name="edge_dashes_bool" type="bool" gui-text="Dashed strokes?">false</param>
|
||||
<param name="edge_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Edge dash + gap length">1</param>
|
||||
<param name="edge_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Edge dash duty cycle">0.25</param>
|
||||
<param name="edge_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of edge strokes">0.1</param>
|
||||
<param name="edge_stroke_color" type="color" gui-text="Edge color: ">255</param>
|
||||
</page>
|
||||
<page name="vertices" gui-text="Vertices">
|
||||
<param name="vertex_bool" type="bool" gui-text="Draw vertices?">true</param>
|
||||
<param name="vertex_bool_only" type="bool" gui-text="Draw ONLY vertices?">false</param>
|
||||
<param name="vertex_base_outer_bool" type="bool" gui-text="Outer base vertices?">true</param>
|
||||
<param name="vertex_base_inner_bool" type="bool" gui-text="Other base vertices?">true</param>
|
||||
<param name="vertex_radius_outer_bool" type="bool" gui-text="Outer radius vertices?">true</param>
|
||||
<param name="vertex_radius_inner_bool" type="bool" gui-text="Inner radius vertices?">true</param>
|
||||
<param name="vertex_radius" type="float" min="0.01" max="50" appearance="full" gui-text="Radius of vertices">0.1</param>
|
||||
<param name="vertex_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of vertex strokes">0.1</param>
|
||||
<param name="vertex_stroke_color" type="color" gui-text="Vertices\' color: ">255</param>
|
||||
</page>
|
||||
</param>
|
||||
<effect>
|
||||
<object-type>all</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="Origami Patterns">
|
||||
<submenu name="Cylindrical" />
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command location="inx" interpreter="python">OrigamiPatterns/Cylindrical_Bendy.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
@ -0,0 +1,122 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>Kresling tower</name>
|
||||
<id>org.inkscape.Origami_patterns.cylindrical_kresling</id>
|
||||
<param name="active-tab" type="notebook">
|
||||
<page name="options" gui-text="Options">
|
||||
<param name="pattern" type="optiongroup" appearance="combo" gui-text="Type of Kresling tower">
|
||||
<option value="regular">Regular</option>
|
||||
<option value="mirrowed">Mirror odd cells</option>
|
||||
</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="rows" type="int" min="1" max="100" gui-text="Number of cells">3</param>
|
||||
<param name="sides" type="int" min="3" max="100" gui-text="Number of polygon sides">6</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="measure_value" type="float" max="10000" precision="3" gui-text="Measure value:">10.0</param>
|
||||
<param name="measure_type" type="optiongroup" appearance="combo" gui-text="Measure type:">
|
||||
<option value="a">Polygon side (a)</option>
|
||||
<option value="b">Vertical mountain crease (b)</option>
|
||||
<option value="l">Diagonal valley crease (l)</option>
|
||||
<option value="radius_external">External radius</option>
|
||||
<option value="radius_internal">Internal radius (totally closed)</option>
|
||||
<option value="diameter_external">External diameter</option>
|
||||
<option value="diameter_internal">Internal diameter (totally closed)</option>
|
||||
</param>
|
||||
<param name="units" type="optiongroup" appearance="combo" gui-text="Units">
|
||||
<option value="mm">mm</option>
|
||||
<option value="cm">cm</option>
|
||||
<option value="in">in</option>
|
||||
<option value="pt">pt</option>
|
||||
<option value="px">px</option>
|
||||
</param>
|
||||
<param name="simulation_mode" type="bool" gui-text="Simulation mode">true</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="parameter_type" type="optiongroup" appearance="combo" gui-text="Parameter type:">
|
||||
<option value="angle_ratio">Angle ratio (lambda)</option>
|
||||
<option value="radial_ratio">Radial ratio</option>
|
||||
<option value="lambdatheta">Angle between a and l (lambda * theta)</option>
|
||||
</param>
|
||||
<param name="radial_ratio" type="float" min="0" max="0.7" precision="3" gui-text="Radial ratio:">0.5</param>
|
||||
<param name="angle_ratio" type="float" min="0.5" max="1" precision="3" gui-text="Angle ratio:">0.5</param>
|
||||
<param name="lambdatheta" type="float" min="15" max="90" precision="2" gui-text="Angle between a and l">60.0</param>
|
||||
</page>
|
||||
<page name="slots" gui-text="Slots">
|
||||
<param name="extra_column" type="bool" gui-text="Extra column?">false</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="add_base_slot" type="bool" gui-text="Add base slots?">false</param>
|
||||
<param name="base_slot_position" type="optiongroup" appearance="combo" gui-text="Base slot position:">
|
||||
<option value="-1">Top</option>
|
||||
<option value="0">Center</option>
|
||||
<option value="1">Bottom</option>
|
||||
</param>
|
||||
<param name="base_height" type="float" max="10000" precision="3" gui-text="Height of base">5.0</param>
|
||||
<param name="base_slot_height" type="float" max="10000" precision="3" gui-text="Height of base slot">3.0</param>
|
||||
<param name="base_slot_width" type="float" max="10000" precision="3" gui-text="Width of base slow">3.0</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="add_middle_slot" type="bool" gui-text="Add slots between cells?">false</param>
|
||||
<param name="middle_slot_position" type="optiongroup" appearance="combo" gui-text="Middle slot position:">
|
||||
<option value="-1">Top</option>
|
||||
<option value="0">Center</option>
|
||||
<option value="1">Bottom</option>
|
||||
</param>
|
||||
<param name="distance" type="float" max="10000" precision="3" gui-text="Distance between cells">3.0</param>
|
||||
<param name="middle_slot_height" type="float" max="10000" precision="3" gui-text="Height of slots between cells">3.0</param>
|
||||
<param name="middle_slot_width" type="float" max="10000" precision="3" gui-text="Width of slots between cells">3.0</param>
|
||||
</page>
|
||||
<page name="cuts" gui-text="Cuts">
|
||||
<param name="cut_bool" type="bool" gui-text="Draw cuts?">true</param>
|
||||
<param name="cut_bool_only" type="bool" gui-text="Draw ONLY cuts?">true</param>
|
||||
<param name="cut_dashes_bool" type="bool" gui-text="Dashed strokes?">false</param>
|
||||
<param name="cut_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Cut dash + gap length">1</param>
|
||||
<param name="cut_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Cut dash duty cycle">0.25</param>
|
||||
<param name="cut_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of cut strokes">0.1</param>
|
||||
<param name="cut_stroke_color" type="color" gui-text="Cut creases color: ">16711935</param>
|
||||
</page>
|
||||
<page name="mountains" gui-text="Mountain creases">
|
||||
<param name="mountain_bool" type="bool" gui-text="Draw mountains?">true</param>
|
||||
<param name="mountain_bool_only" type="bool" gui-text="Draw ONLY mountains?">false</param>
|
||||
<param name="mountain_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="mountain_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Mountain dash + gap length">1</param>
|
||||
<param name="mountain_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Mountain dash duty cycle">0.5</param>
|
||||
<param name="mountain_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of mountain strokes">0.1</param>
|
||||
<param name="mountain_stroke_color" type="color" gui-text="Mountain creases color: ">4278190335</param>
|
||||
</page>
|
||||
<page name="valleys" gui-text="Valley creases">
|
||||
<param name="valley_bool" type="bool" gui-text="Draw valley?">true</param>
|
||||
<param name="valley_bool_only" type="bool" gui-text="Draw ONLY valleys?">false</param>
|
||||
<param name="valley_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="valley_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Valley dash + gap length">1</param>
|
||||
<param name="valley_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Valley dash duty cycle">0.25</param>
|
||||
<param name="valley_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of valley strokes">0.1</param>
|
||||
<param name="valley_stroke_color" type="color" gui-text="Valley creases color: ">65535</param>
|
||||
</page>
|
||||
<page name="edge" gui-text="Edge">
|
||||
<param name="edge_bool" type="bool" gui-text="Draw edges?">true</param>
|
||||
<param name="edge_bool_only" type="bool" gui-text="Draw ONLY edges?">false</param>
|
||||
<param name="edge_single_path" type="bool" gui-text="Edges as single path?">true</param>
|
||||
<param name="edge_dashes_bool" type="bool" gui-text="Dashed strokes?">false</param>
|
||||
<param name="edge_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Edge dash + gap length">1</param>
|
||||
<param name="edge_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Edge dash duty cycle">0.25</param>
|
||||
<param name="edge_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of edge strokes">0.1</param>
|
||||
<param name="edge_stroke_color" type="color" gui-text="Edge color: ">255</param>
|
||||
</page>
|
||||
<page name="vertices" gui-text="Vertices">
|
||||
<param name="vertex_bool" type="bool" gui-text="Draw vertices?">true</param>
|
||||
<param name="vertex_bool_only" type="bool" gui-text="Draw ONLY vertices?">false</param>
|
||||
<param name="vertex_radius" type="float" min="0.01" max="50" appearance="full" gui-text="Radius of vertices">0.1</param>
|
||||
<param name="vertex_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of vertex strokes">0.1</param>
|
||||
<param name="vertex_stroke_color" type="color" gui-text="Vertices\' color: ">255</param>
|
||||
</page>
|
||||
</param>
|
||||
<effect>
|
||||
<object-type>all</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="Origami Patterns">
|
||||
<submenu name="Cylindrical" />
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command location="inx" interpreter="python">OrigamiPatterns/Cylindrical_Kresling.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
@ -0,0 +1,95 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>* Cylindrical template effect</name>
|
||||
<id>org.inkscape.Origami_patterns.cylindrical_template</id>
|
||||
<param name="active-tab" type="notebook">
|
||||
<page name="options" gui-text="Options">
|
||||
<label>------------------------------------</label>
|
||||
<label>Minimum necessary parameters for Cylindrical origami types :</label>
|
||||
<param name="radius" type="float" max="10000" precision="3" gui-text="Radius of cylinder">10.0</param>
|
||||
<param name="sides" type="int" min="3" max="25" gui-text="Number of sides of polygon">6</param>
|
||||
<param name="rows" type="int" min="1" max="100" gui-text="Number of cells">3</param>
|
||||
<label>-------------------------------------</label>
|
||||
<param name="length" type="float" max="10000" precision="3" gui-text="Length">10.0</param>
|
||||
<param name="angle" type="int" min="0" max="45" gui-text="Rotation angle (degree)">0</param>
|
||||
<param name="units" type="optiongroup" appearance="combo" gui-text="Units">
|
||||
<option value="mm">mm</option>
|
||||
<option value="cm">cm</option>
|
||||
<option value="in">in</option>
|
||||
<option value="pt">pt</option>
|
||||
<option value="px">px</option>
|
||||
</param>
|
||||
<label>The .inx file defines the bridge between Inkscape's interface and the python script.</label>
|
||||
<param name="simulation_mode" type="bool" gui-text="Simulation mode">true</param>
|
||||
</page>
|
||||
<page name="slots" gui-text="Slots">
|
||||
<param name="extra_column" type="bool" gui-text="Extra column?">false</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="add_base_slot" type="bool" gui-text="Add base slots?">false</param>
|
||||
<param name="base_slot_position" type="optiongroup" appearance="combo" gui-text="Base slot position:">
|
||||
<option value="-1">Top</option>
|
||||
<option value="0">Center</option>
|
||||
<option value="1">Bottom</option>
|
||||
</param>
|
||||
<param name="base_height" type="float" max="10000" precision="3" gui-text="Height of base">5.0</param>
|
||||
<param name="base_slot_height" type="float" max="10000" precision="3" gui-text="Height of base slot">3.0</param>
|
||||
<param name="base_slot_width" type="float" max="10000" precision="3" gui-text="Width of base slow">3.0</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="add_middle_slot" type="bool" gui-text="Add slots between cells?">false</param>
|
||||
<param name="middle_slot_position" type="optiongroup" appearance="combo" gui-text="Middle slot position:">
|
||||
<option value="-1">Top</option>
|
||||
<option value="0">Center</option>
|
||||
<option value="1">Bottom</option>
|
||||
</param>
|
||||
<param name="distance" type="float" max="10000" precision="3" gui-text="Distance between cells">3.0</param>
|
||||
<param name="middle_slot_height" type="float" max="10000" precision="3" gui-text="Height of slots between cells">3.0</param>
|
||||
<param name="middle_slot_width" type="float" max="10000" precision="3" gui-text="Width of slots between cells">3.0</param>
|
||||
</page>
|
||||
<page name="mountains" gui-text="Mountain creases">
|
||||
<param name="mountain_bool" type="bool" gui-text="Draw mountains?">true</param>
|
||||
<param name="mountain_bool_only" type="bool" gui-text="Draw ONLY mountains?">false</param>
|
||||
<param name="mountain_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="mountain_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Mountain dash + gap length">1</param>
|
||||
<param name="mountain_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Mountain dash duty cycle">0.5</param>
|
||||
<param name="mountain_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of mountain strokes">0.1</param>
|
||||
<param name="mountain_stroke_color" type="color" gui-text="Mountain creases color: ">4278190335</param>
|
||||
</page>
|
||||
<page name="valleys" gui-text="Valley creases">
|
||||
<param name="valley_bool" type="bool" gui-text="Draw valley?">true</param>
|
||||
<param name="valley_bool_only" type="bool" gui-text="Draw ONLY valleys?">false</param>
|
||||
<param name="valley_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="valley_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Valley dash + gap length">1</param>
|
||||
<param name="valley_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Valley dash duty cycle">0.25</param>
|
||||
<param name="valley_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of valley strokes">0.1</param>
|
||||
<param name="valley_stroke_color" type="color" gui-text="Valley creases color: ">65535</param>
|
||||
</page>
|
||||
<page name="edge" gui-text="Edge">
|
||||
<param name="edge_bool" type="bool" gui-text="Draw edges?">true</param>
|
||||
<param name="edge_bool_only" type="bool" gui-text="Draw ONLY edges?">false</param>
|
||||
<param name="edge_single_path" type="bool" gui-text="Edges as single path?">true</param>
|
||||
<param name="edge_dashes_bool" type="bool" gui-text="Dashed strokes?">false</param>
|
||||
<param name="edge_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Edge dash + gap length">1</param>
|
||||
<param name="edge_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Edge dash duty cycle">0.25</param>
|
||||
<param name="edge_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of edge strokes">0.1</param>
|
||||
<param name="edge_stroke_color" type="color" gui-text="Edge color: ">255</param>
|
||||
</page>
|
||||
<page name="vertices" gui-text="Vertices">
|
||||
<param name="vertex_bool" type="bool" gui-text="Draw vertices?">true</param>
|
||||
<param name="vertex_bool_only" type="bool" gui-text="Draw ONLY vertices?">false</param>
|
||||
<param name="vertex_radius" type="float" min="0.01" max="50" appearance="full" gui-text="Radius of vertices">0.1</param>
|
||||
<param name="vertex_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of vertex strokes">0.1</param>
|
||||
<param name="vertex_stroke_color" type="color" gui-text="Vertices\' color: ">255</param>
|
||||
</page>
|
||||
</param>
|
||||
<effect>
|
||||
<object-type>all</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="Origami Patterns">
|
||||
<submenu name="Cylindrical" />
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command location="inx" interpreter="python">OrigamiPatterns/Cylindrical_Template.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>* Support ring</name>
|
||||
<id>org.inkscape.Origami_patterns.support_ring</id>
|
||||
<param name="active-tab" type="notebook">
|
||||
<page name="options" gui-text="Options">
|
||||
<param name="sides" type="int" min="3" max="100" gui-text="Number of polygon sides">6</param>
|
||||
<param name="radius_external" type="float" max="10000" precision="3" gui-text="Pattern radius:">10.0</param>
|
||||
<param name="inverted" type="bool" gui-text="Invert hook direction?">false</param>
|
||||
<param name="single_stroke" type="bool" gui-text="Single stroke?">true</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="connector_length" type="float" max="10000" precision="3" gui-text="Connector length:">3.0</param>
|
||||
<param name="connector_thickness" type="float" max="10000" precision="3" gui-text="Connector thickness:">3.0</param>
|
||||
<param name="head_length" type="float" max="10000" precision="3" gui-text="Head extra length:">1.0</param>
|
||||
<param name="head_thickness" type="float" max="10000" precision="3" gui-text="Head extra thickness:">1.0</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="radius_draw" type="bool" gui-text="Draw internal radius? (or external, if inverted)">true</param>
|
||||
<param name="radius_ratio" type="float" min="0" max="0.9" precision="3" gui-text="Radial ratio:">0.5</param>
|
||||
<param name="radius_type" type="optiongroup" appearance="combo" gui-text="Internal radius type:">
|
||||
<option value="polygonal">Polygonal</option>
|
||||
<option value="circular">Circular</option>
|
||||
</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<label>Length must be at least the thickness of the origami material + the thickness of the belt.</label>
|
||||
<label>For an OpenSCAD simple implementation of the belt, see Origami_Patterns/Support_Ring_Belt.</label>
|
||||
<param name="units" type="optiongroup" appearance="combo" gui-text="Units">
|
||||
<option value="mm">mm</option>
|
||||
<option value="cm">cm</option>
|
||||
<option value="in">in</option>
|
||||
<option value="pt">pt</option>
|
||||
<option value="px">px</option>
|
||||
</param>
|
||||
</page>
|
||||
<page name="mountains" gui-text="Strokes">
|
||||
<param name="mountain_dashes_bool" type="bool" gui-text="Dashed strokes?">false</param>
|
||||
<param name="mountain_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Dash + gap length">1</param>
|
||||
<param name="mountain_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Dash duty cycle">0.5</param>
|
||||
<param name="mountain_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of strokes">0.1</param>
|
||||
<param name="mountain_stroke_color" type="color" gui-text="Strokes color: ">4278190335</param>
|
||||
</page>
|
||||
</param>
|
||||
<effect>
|
||||
<object-type>all</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="Origami Patterns">
|
||||
<submenu name="Cylindrical" />
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command location="inx" interpreter="python">OrigamiPatterns/SupportRing.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
107
extensions/fablabchemnitz/origami_patterns/origami_patterns_old_bendy.inx
Executable file
107
extensions/fablabchemnitz/origami_patterns/origami_patterns_old_bendy.inx
Executable file
@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>Bendy Straw (old, faster cutting)</name>
|
||||
<id>org.inkscape.Origami_patterns.old_bendy</id>
|
||||
<param name="active-tab" type="notebook">
|
||||
<page name="options" gui-text="Options">
|
||||
<param name="pattern_type" type="optiongroup" appearance="combo" gui-text="Type of pattern:">
|
||||
<option value="origami">Origami regular</option>
|
||||
<option value="origami_bent">Origami bent</option>
|
||||
<option value="kirigami1">Kirigami mode 1</option>
|
||||
<option value="kirigami2">Kirigami mode 2</option>
|
||||
</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="n" type="int" min="3" max="25" gui-text="Number of sides of polygon">6</param>
|
||||
<param name="lines" type="int" min="1" max="100" gui-text="Number of cells">3</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="radius" type="float" max="10000" precision="3" gui-text="Radius of bigger polygon">25.0</param>
|
||||
<param name="radial_ratio" type="float" max="1.0" min="0.0001" precision="3" gui-text="Ratio small radius/big radius">0.75</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="parameter_type" type="optiongroup" appearance="combo" gui-text="Parameter:">
|
||||
<option value="angles">Angles (alpha1, alpha2)</option>
|
||||
<option value="heights">Heights (h1, h2)</option>
|
||||
</param>
|
||||
<param name="alpha1" type="int" min="5" max="90" gui-text="Angle of superior cone (alpha1)">45</param>
|
||||
<param name="alpha2" type="int" min="5" max="90" gui-text="Angle of inferior cone (alpha2)">35</param>
|
||||
<param name="h1" type="float" min="0" max="200.0" precision="3" gui-text="Height of superior cone (h1)">1</param>
|
||||
<param name="h2" type="float" min="0" max="200.0" precision="3" gui-text="Height of inferior cone (h2)">2</param>
|
||||
<param name="units" type="optiongroup" appearance="combo" gui-text="Units">
|
||||
<option value="mm">mm</option>
|
||||
<option value="cm">cm</option>
|
||||
<option value="in">in</option>
|
||||
<option value="pt">pt</option>
|
||||
<option value="px">px</option>
|
||||
</param>
|
||||
<label>As published in: https://doi.org/10.1115/1.4052222</label>
|
||||
<param name="simulation_mode" type="bool" gui-text="Simulation mode">true</param>
|
||||
</page>
|
||||
<page name="extra" gui-text="Extra">
|
||||
<param name="add_attachment" type="bool" gui-text="Add attachments?">false</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="base_height" type="float" max="10000" precision="3" gui-text="Height of base">5.0</param>
|
||||
<param name="add_base_slot" type="bool" gui-text="Add base slots?">false</param>
|
||||
<param name="center_base_slot" type="bool" gui-text="Center base slots?">false</param>
|
||||
<param name="base_slot_height" type="float" max="10000" precision="3" gui-text="Height of base slot">3.0</param>
|
||||
<param name="base_slot_width" type="float" max="10000" precision="3" gui-text="Width of base slow">3.0</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="distance" type="float" max="10000" precision="3" gui-text="Distance between cells">3.0</param>
|
||||
<param name="add_distance_slot" type="bool" gui-text="Add slots between cells?">false</param>
|
||||
<param name="distance_slot_height" type="float" max="10000" precision="3" gui-text="Height of slots between cells">3.0</param>
|
||||
<param name="distance_slot_width" type="float" max="10000" precision="3" gui-text="Width of slots between cells">3.0</param>
|
||||
</page>
|
||||
<page name="mountains" gui-text="Mountains">
|
||||
<param name="mountain_bool" type="bool" gui-text="Draw mountains?">true</param>
|
||||
<param name="mountain_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="mountain_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Mountain dash + gap length">1</param>
|
||||
<param name="mountain_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Mountain dash duty cycle">0.5</param>
|
||||
<param name="mountain_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of mountain strokes">0.1</param>
|
||||
<param name="mountain_stroke_color" type="color" gui-text="Mountain creases color: ">4278190335</param>
|
||||
</page>
|
||||
<page name="valleys" gui-text="Valleys">
|
||||
<param name="valley_bool" type="bool" gui-text="Draw valley?">true</param>
|
||||
<param name="valley_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="valley_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Valley dash + gap length">1</param>
|
||||
<param name="valley_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Valley dash duty cycle">0.25</param>
|
||||
<param name="valley_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of valley strokes">0.1</param>
|
||||
<param name="valley_stroke_color" type="color" gui-text="Valley creases color: ">65535</param>
|
||||
</page>
|
||||
<page name="cuts" gui-text="Cuts">
|
||||
<param name="cut_bool" type="bool" gui-text="Draw cuts?">true</param>
|
||||
<param name="cut_dashes_bool" type="bool" gui-text="Dashed strokes?">false</param>
|
||||
<param name="cut_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Cut dash + gap length">1</param>
|
||||
<param name="cut_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Cut dash duty cycle">0.25</param>
|
||||
<param name="cut_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of cut strokes">0.1</param>
|
||||
<param name="cut_stroke_color" type="color" gui-text="Cut creases color: ">16711935</param>
|
||||
</page>
|
||||
<page name="edge" gui-text="Edge">
|
||||
<param name="edge_bool" type="bool" gui-text="Draw edges?">true</param>
|
||||
<param name="edge_single_path" type="bool" gui-text="Edges as single path?">true</param>
|
||||
<param name="edge_dashes_bool" type="bool" gui-text="Dashed strokes?">false</param>
|
||||
<param name="edge_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Edge dash + gap length">1</param>
|
||||
<param name="edge_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Edge dash duty cycle">0.25</param>
|
||||
<param name="edge_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of edge strokes">0.1</param>
|
||||
<param name="edge_stroke_color" type="color" gui-text="Edge color: ">255</param>
|
||||
</page>
|
||||
<page name="vertices" gui-text="Vertices">
|
||||
<param name="vertex_bool" type="bool" gui-text="Draw vertices?">true</param>
|
||||
<param name="vertex_base_outer_bool" type="bool" gui-text="Outer base vertices?">true</param>
|
||||
<param name="vertex_base_inner_bool" type="bool" gui-text="Other base vertices?">true</param>
|
||||
<param name="vertex_radius_outer_bool" type="bool" gui-text="Outer radius vertices?">true</param>
|
||||
<param name="vertex_radius_inner_bool" type="bool" gui-text="Inner radius vertices?">true</param>
|
||||
<param name="vertex_radius" type="float" min="0.01" max="50" appearance="full" gui-text="Radius of vertices">0.1</param>
|
||||
<param name="vertex_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of vertex strokes">0.1</param>
|
||||
<param name="vertex_stroke_color" type="color" gui-text="Vertices\' color: ">255</param>
|
||||
</page>
|
||||
</param>
|
||||
<effect>
|
||||
<object-type>all</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="Origami Patterns">
|
||||
<submenu name="Deprecated" />
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command location="inx" interpreter="python">OrigamiPatterns/Bendy.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
95
extensions/fablabchemnitz/origami_patterns/origami_patterns_old_kresling.inx
Executable file
95
extensions/fablabchemnitz/origami_patterns/origami_patterns_old_kresling.inx
Executable file
@ -0,0 +1,95 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>Kresling tower (old)</name>
|
||||
<id>org.inkscape.Origami_patterns.old_kresling</id>
|
||||
<param name="active-tab" type="notebook">
|
||||
<page name="options" gui-text="Options">
|
||||
<param name="pattern" type="optiongroup" appearance="combo" gui-text="Type of Kresling tower">
|
||||
<option value="regular">Regular</option>
|
||||
<option value="mirrowed">Mirror odd cells</option>
|
||||
</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="lines" type="int" min="1" max="100" gui-text="Number of cells">3</param>
|
||||
<param name="sides" type="int" min="3" max="100" gui-text="Number of polygon sides">6</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="measure_value" type="float" max="10000" precision="3" gui-text="Measure value:">10.0</param>
|
||||
<param name="measure_type" type="optiongroup" appearance="combo" gui-text="Measure type:">
|
||||
<option value="a">Polygon side (a)</option>
|
||||
<option value="b">Vertical mountain crease (b)</option>
|
||||
<option value="l">Diagonal valley crease (l)</option>
|
||||
<option value="radius_external">External radius</option>
|
||||
<option value="radius_internal">Internal radius (totally closed)</option>
|
||||
<option value="diameter_external">External diameter</option>
|
||||
<option value="diameter_internal">Internal diameter (totally closed)</option>
|
||||
</param>
|
||||
<param name="units" type="optiongroup" appearance="combo" gui-text="Units">
|
||||
<option value="mm">mm</option>
|
||||
<option value="cm">cm</option>
|
||||
<option value="in">in</option>
|
||||
<option value="pt">pt</option>
|
||||
<option value="px">px</option>
|
||||
</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
<param name="parameter_type" type="optiongroup" appearance="combo" gui-text="Parameter type:">
|
||||
<option value="angle_ratio">Angle ratio (lambda)</option>
|
||||
<option value="radial_ratio">Radial ratio</option>
|
||||
<option value="lambdatheta">Angle between a and l (lambda * theta)</option>
|
||||
</param>
|
||||
<param name="radial_ratio" type="float" min="0" max="0.7" precision="3" gui-text="Radial ratio:">0.5</param>
|
||||
<param name="angle_ratio" type="float" min="0.5" max="1" precision="3" gui-text="Angle ratio:">0.5</param>
|
||||
<param name="lambdatheta" type="float" min="15" max="90" precision="2" gui-text="Angle between a and l">60.0</param>
|
||||
<param name="simulation_mode" type="bool" gui-text="Simulation mode">true</param>
|
||||
</page>
|
||||
<page name="extraoptions" gui-text="Extra Options">
|
||||
<param name="add_attachment" type="bool" gui-text="Add one more facet to close tower?">false</param>
|
||||
<param name="attachment_percentage" type="float" min="0" max="100" precision="1" appearance="full" gui-text="Length percentage of extra facet">100</param>
|
||||
<label>------------------------------------------------------------</label>
|
||||
</page>
|
||||
<page name="mountains" gui-text="Mountain creases">
|
||||
<param name="mountain_bool" type="bool" gui-text="Draw mountains?">true</param>
|
||||
<param name="mountain_bool_only" type="bool" gui-text="Draw ONLY mountains?">false</param>
|
||||
<param name="mountain_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="mountain_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Mountain dash + gap length">1</param>
|
||||
<param name="mountain_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Mountain dash duty cycle">0.5</param>
|
||||
<param name="mountain_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of mountain strokes">0.1</param>
|
||||
<param name="mountain_stroke_color" type="color" gui-text="Mountain creases color: ">4278190335</param>
|
||||
</page>
|
||||
<page name="valleys" gui-text="Valley creases">
|
||||
<param name="valley_bool" type="bool" gui-text="Draw valley?">true</param>
|
||||
<param name="valley_bool_only" type="bool" gui-text="Draw ONLY valleys?">false</param>
|
||||
<param name="valley_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="valley_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Valley dash + gap length">1</param>
|
||||
<param name="valley_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Valley dash duty cycle">0.25</param>
|
||||
<param name="valley_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of valley strokes">0.1</param>
|
||||
<param name="valley_stroke_color" type="color" gui-text="Valley creases color: ">65535</param>
|
||||
</page>
|
||||
<page name="edge" gui-text="Edge">
|
||||
<param name="edge_bool" type="bool" gui-text="Draw edges?">true</param>
|
||||
<param name="edge_bool_only" type="bool" gui-text="Draw ONLY edges?">false</param>
|
||||
<param name="edge_single_path" type="bool" gui-text="Edges as single path?">true</param>
|
||||
<param name="edge_dashes_bool" type="bool" gui-text="Dashed strokes?">false</param>
|
||||
<param name="edge_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Edge dash + gap length">1</param>
|
||||
<param name="edge_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Edge dash duty cycle">0.25</param>
|
||||
<param name="edge_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of edge strokes">0.1</param>
|
||||
<param name="edge_stroke_color" type="color" gui-text="Edge color: ">255</param>
|
||||
</page>
|
||||
<page name="vertices" gui-text="Vertices">
|
||||
<param name="vertex_bool" type="bool" gui-text="Draw vertices?">true</param>
|
||||
<param name="vertex_bool_only" type="bool" gui-text="Draw ONLY vertices?">false</param>
|
||||
<param name="vertex_radius" type="float" min="0.01" max="50" appearance="full" gui-text="Radius of vertices">0.1</param>
|
||||
<param name="vertex_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of vertex strokes">0.1</param>
|
||||
<param name="vertex_stroke_color" type="color" gui-text="Vertices\' color: ">255</param>
|
||||
</page>
|
||||
</param>
|
||||
<effect>
|
||||
<object-type>all</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="Origami Patterns">
|
||||
<submenu name="Deprecated" />
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command location="inx" interpreter="python">OrigamiPatterns/Kresling_full.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>Circular</name>
|
||||
<id>org.inkscape.Origami_patterns.pleat_circular</id>
|
||||
<param name="active-tab" type="notebook">
|
||||
<page name="options" gui-text="Options">
|
||||
<param name="radius" type="float" max="10000" precision="3" gui-text="Radius of circle">55.0</param>
|
||||
<param name="units" type="optiongroup" appearance="combo" gui-text="Units">
|
||||
<option value="mm">mm</option>
|
||||
<option value="cm">cm</option>
|
||||
<option value="in">in</option>
|
||||
<option value="pt">pt</option>
|
||||
<option value="px">px</option>
|
||||
</param>
|
||||
<param name="ratio" type="float" min="0" max="1" precision="3" gui-text="Opening ratio">0.4</param>
|
||||
<param name="rings" type="int" min="3" max="100" gui-text="Number of rings">15</param>
|
||||
<label>------------------------------</label>
|
||||
<param name="simulation_mode" type="bool" gui-text="Simulation mode">true</param>
|
||||
<label>To simulate with OrigamiSimulator, semicreases (or facet creases) must be added to properly simulate paper, and the circles must be approximated as polygons.</label>
|
||||
<param name="sides" type="int" min="10" max="100" gui-text="Number of sides for polygon approximating half circle">20</param>
|
||||
</page>
|
||||
<page name="mountains" gui-text="Mountain creases">
|
||||
<param name="mountain_bool" type="bool" gui-text="Draw mountains?">true</param>
|
||||
<param name="mountain_bool_only" type="bool" gui-text="Draw ONLY mountains?">false</param>
|
||||
<param name="mountain_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="mountain_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Mountain dash + gap length">1</param>
|
||||
<param name="mountain_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Mountain dash duty cycle">0.5</param>
|
||||
<param name="mountain_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of mountain strokes">0.1</param>
|
||||
<param name="mountain_stroke_color" type="color" gui-text="Mountain creases color: ">4278190335</param>
|
||||
</page>
|
||||
<page name="valleys" gui-text="Valley creases">
|
||||
<param name="valley_bool" type="bool" gui-text="Draw valley?">true</param>
|
||||
<param name="valley_bool_only" type="bool" gui-text="Draw ONLY valleys?">false</param>
|
||||
<param name="valley_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="valley_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Valley dash + gap length">1</param>
|
||||
<param name="valley_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Valley dash duty cycle">0.25</param>
|
||||
<param name="valley_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of valley strokes">0.1</param>
|
||||
<param name="valley_stroke_color" type="color" gui-text="Valley creases color: ">65535</param>
|
||||
</page>
|
||||
<page name="edge" gui-text="Edge">
|
||||
<param name="edge_bool" type="bool" gui-text="Draw edges?">true</param>
|
||||
<param name="edge_bool_only" type="bool" gui-text="Draw ONLY edges?">false</param>
|
||||
<param name="edge_single_path" type="bool" gui-text="Edges as single path?">true</param>
|
||||
<param name="edge_dashes_bool" type="bool" gui-text="Dashed strokes?">false</param>
|
||||
<param name="edge_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Edge dash + gap length">1</param>
|
||||
<param name="edge_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Edge dash duty cycle">0.25</param>
|
||||
<param name="edge_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of edge strokes">0.1</param>
|
||||
<param name="edge_stroke_color" type="color" gui-text="Edge color: ">255</param>
|
||||
</page>
|
||||
<page name="vertices" gui-text="Vertices">
|
||||
<param name="vertex_bool" type="bool" gui-text="Draw vertices?">true</param>
|
||||
<param name="vertex_bool_only" type="bool" gui-text="Draw ONLY vertices?">false</param>
|
||||
<param name="vertex_radius" type="float" min="0.01" max="50" appearance="full" gui-text="Radius of vertices">0.1</param>
|
||||
<param name="vertex_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of vertex strokes">0.1</param>
|
||||
<param name="vertex_stroke_color" type="color" gui-text="Vertices\' color: ">255</param>
|
||||
</page>
|
||||
<page name="semicrease" gui-text="Semicreases">
|
||||
<param name="semicrease_bool" type="bool" gui-text="Draw semicreases?">true</param>
|
||||
<param name="semicrease_bool_only" type="bool" gui-text="Draw ONLY semicreases?">false</param>
|
||||
<param name="semicrease_dashes_bool" type="bool" gui-text="Dashed strokes?">false</param>
|
||||
<param name="semicrease_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Semicrease dash + gap length">1</param>
|
||||
<param name="semicrease_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Semicrease dash duty cycle">0.25</param>
|
||||
<param name="semicrease_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of semicrease strokes">0.1</param>
|
||||
<param name="semicrease_stroke_color" type="color" gui-text="Semicreases color: ">4294902015</param>
|
||||
</page>
|
||||
</param>
|
||||
<effect>
|
||||
<object-type>all</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="Origami Patterns">
|
||||
<submenu name="Pleat folds" />
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command location="inx" interpreter="python">OrigamiPatterns/Pleat_Circular.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
82
extensions/fablabchemnitz/origami_patterns/origami_patterns_pleat_hypar.inx
Executable file
82
extensions/fablabchemnitz/origami_patterns/origami_patterns_pleat_hypar.inx
Executable file
@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>N-sided Hypar</name>
|
||||
<id>org.inkscape.Origami_patterns.pleat_hypar</id>
|
||||
<param name="active-tab" type="notebook">
|
||||
<page name="options" gui-text="Options">
|
||||
<param name="pattern" type="optiongroup" appearance="combo" gui-text="Type of Hypar">
|
||||
<option value="classic">Classic Hypar</option>
|
||||
<option value="asymmetric">Asymmetric triangulation</option>
|
||||
<option value="alternate_asymmetric">Alternating asymmetric triangulation</option>
|
||||
</param>
|
||||
<param name="radius" type="float" max="10000" precision="3" gui-text="Radius of polygon">100.0</param>
|
||||
<param name="units" type="optiongroup" appearance="combo" gui-text="Units">
|
||||
<option value="mm">mm</option>
|
||||
<option value="cm">cm</option>
|
||||
<option value="in">in</option>
|
||||
<option value="pt">pt</option>
|
||||
<option value="px">px</option>
|
||||
</param>
|
||||
<param name="sides" type="int" min="3" max="100" gui-text="Number of polygon sides">4</param>
|
||||
<param name="rings" type="int" min="1" max="100" gui-text="Number of rings">7</param>
|
||||
<param name="simplify_center" type="bool" gui-text="Simplify center (probably not suited for odd number of sides)">false</param>
|
||||
<label>Implements Hypar (classical hyperbolic paraboloid approximate). Classic Hypar is the easiest one to fold. However, it's not rigid foldable. More information in: Demaine, E. D., Demaine, M. L., Hart, V., Price, G. N., and Tachi, T. (2011). (Non)Existence of Pleated Folds: How Paper Folds Between Creases. Graphs and Combinatorics, 27(3), 377–397. https://doi.org/10.1007/s00373-011-1025-2</label>
|
||||
<param name="simulation_mode" type="bool" gui-text="Simulation mode">true</param>
|
||||
</page>
|
||||
<page name="mountains" gui-text="Mountain creases">
|
||||
<param name="mountain_bool" type="bool" gui-text="Draw mountains?">true</param>
|
||||
<param name="mountain_bool_only" type="bool" gui-text="Draw ONLY mountains?">false</param>
|
||||
<param name="mountain_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="mountain_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Mountain dash + gap length">1</param>
|
||||
<param name="mountain_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Mountain dash duty cycle">0.5</param>
|
||||
<param name="mountain_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of mountain strokes">0.1</param>
|
||||
<param name="mountain_stroke_color" type="color" gui-text="Mountain creases color: ">4278190335</param>
|
||||
</page>
|
||||
<page name="valleys" gui-text="Valley creases">
|
||||
<param name="valley_bool" type="bool" gui-text="Draw valley?">true</param>
|
||||
<param name="valley_bool_only" type="bool" gui-text="Draw ONLY valleys?">false</param>
|
||||
<param name="valley_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="valley_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Valley dash + gap length">1</param>
|
||||
<param name="valley_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Valley dash duty cycle">0.25</param>
|
||||
<param name="valley_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of valley strokes">0.1</param>
|
||||
<param name="valley_stroke_color" type="color" gui-text="Valley creases color: ">65535</param>
|
||||
</page>
|
||||
<page name="universal" gui-text="Universal creases">
|
||||
<param name="universal_bool" type="bool" gui-text="Draw universal creases?">true</param>
|
||||
<param name="universal_bool_only" type="bool" gui-text="Draw ONLY universal creases?">false</param>
|
||||
<param name="universal_dashes_bool" type="bool" gui-text="Dashed strokes?">false</param>
|
||||
<param name="universal_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Universal dash + gap length">1</param>
|
||||
<param name="universal_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Universal dash duty cycle">0.25</param>
|
||||
<param name="universal_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of universal strokes">0.1</param>
|
||||
<param name="universal_stroke_color" type="color" gui-text="Universal creases color: ">4278255615</param>
|
||||
</page>
|
||||
<page name="edge" gui-text="Edge">
|
||||
<param name="edge_bool" type="bool" gui-text="Draw edges?">true</param>
|
||||
<param name="edge_bool_only" type="bool" gui-text="Draw ONLY edges?">false</param>
|
||||
<param name="edge_single_path" type="bool" gui-text="Edges as single path?">true</param>
|
||||
<param name="edge_dashes_bool" type="bool" gui-text="Dashed strokes?">false</param>
|
||||
<param name="edge_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Edge dash + gap length">1</param>
|
||||
<param name="edge_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Edge dash duty cycle">0.25</param>
|
||||
<param name="edge_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of edge strokes">0.1</param>
|
||||
<param name="edge_stroke_color" type="color" gui-text="Edge color: ">255</param>
|
||||
</page>
|
||||
<page name="vertices" gui-text="Vertices">
|
||||
<param name="vertex_bool" type="bool" gui-text="Draw vertices?">true</param>
|
||||
<param name="vertex_bool_only" type="bool" gui-text="Draw ONLY vertices?">false</param>
|
||||
<param name="vertex_radius" type="float" min="0.01" max="50" appearance="full" gui-text="Radius of vertices">0.1</param>
|
||||
<param name="vertex_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of vertex strokes">0.1</param>
|
||||
<param name="vertex_stroke_color" type="color" gui-text="Vertices\' color: ">255</param>
|
||||
</page>
|
||||
</param>
|
||||
<effect>
|
||||
<object-type>all</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="Origami Patterns">
|
||||
<submenu name="Pleat folds" />
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command location="inx" interpreter="python">OrigamiPatterns/Hypar.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
72
extensions/fablabchemnitz/origami_patterns/origami_patterns_template.inx
Executable file
72
extensions/fablabchemnitz/origami_patterns/origami_patterns_template.inx
Executable file
@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>Template effect</name>
|
||||
<id>org.inkscape.Origami_patterns.template</id>
|
||||
<param name="active-tab" type="notebook">
|
||||
<page name="options" gui-text="Options">
|
||||
<param name="pattern" type="optiongroup" appearance="combo" gui-text="Type of template">
|
||||
<option value="template1">Template pattern 1</option>
|
||||
<option value="template2">Template pattern 2</option>
|
||||
</param>
|
||||
<param name="length" type="float" max="10000" precision="3" gui-text="Length of grid square">10.0</param>
|
||||
<param name="units" type="optiongroup" appearance="combo" gui-text="Units">
|
||||
<option value="mm">mm</option>
|
||||
<option value="cm">cm</option>
|
||||
<option value="in">in</option>
|
||||
<option value="pt">pt</option>
|
||||
<option value="px">px</option>
|
||||
</param>
|
||||
<param name="angle" type="int" min="0" max="360" gui-text="Rotation angle (degree)">0</param>
|
||||
<param name="fold_angle_valley" type="int" min="0" max="180" gui-text="Max fold angle of valleys (degree)">180</param>
|
||||
<label>The .inx file defines the bridge between Inkscape's interface and the python script.</label>
|
||||
<param name="simulation_mode" type="bool" gui-text="Simulation* mode">true</param>
|
||||
<label>* Simulation mode bypasses most style preferences to quickly switch between OrigamiSimulator standard and your own chosen style (for laser cutting, for example).</label>
|
||||
</page>
|
||||
<page name="mountains" gui-text="Mountain creases">
|
||||
<param name="mountain_bool" type="bool" gui-text="Draw mountains?">true</param>
|
||||
<param name="mountain_bool_only" type="bool" gui-text="Draw ONLY mountains?">false</param>
|
||||
<param name="mountain_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="mountain_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Mountain dash + gap length">1</param>
|
||||
<param name="mountain_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Mountain dash duty cycle">0.5</param>
|
||||
<param name="mountain_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of mountain strokes">0.1</param>
|
||||
<param name="mountain_stroke_color" type="color" gui-text="Mountain creases color: ">4278190335</param>
|
||||
</page>
|
||||
<page name="valleys" gui-text="Valley creases">
|
||||
<param name="valley_bool" type="bool" gui-text="Draw valley?">true</param>
|
||||
<param name="valley_bool_only" type="bool" gui-text="Draw ONLY valleys?">false</param>
|
||||
<param name="valley_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="valley_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Valley dash + gap length">1</param>
|
||||
<param name="valley_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Valley dash duty cycle">0.25</param>
|
||||
<param name="valley_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of valley strokes">0.1</param>
|
||||
<param name="valley_stroke_color" type="color" gui-text="Valley creases color: ">65535</param>
|
||||
</page>
|
||||
<page name="edge" gui-text="Edge">
|
||||
<param name="edge_bool" type="bool" gui-text="Draw edges?">true</param>
|
||||
<param name="edge_bool_only" type="bool" gui-text="Draw ONLY edges?">false</param>
|
||||
<param name="edge_single_path" type="bool" gui-text="Edges as single path?">true</param>
|
||||
<param name="edge_dashes_bool" type="bool" gui-text="Dashed strokes?">false</param>
|
||||
<param name="edge_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Edge dash + gap length">1</param>
|
||||
<param name="edge_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Edge dash duty cycle">0.25</param>
|
||||
<param name="edge_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of edge strokes">0.1</param>
|
||||
<param name="edge_stroke_color" type="color" gui-text="Edge color: ">255</param>
|
||||
</page>
|
||||
<page name="vertices" gui-text="Vertices">
|
||||
<param name="vertex_bool" type="bool" gui-text="Draw vertices?">true</param>
|
||||
<param name="vertex_bool_only" type="bool" gui-text="Draw ONLY vertices?">false</param>
|
||||
<param name="vertex_radius" type="float" min="0.01" max="50" appearance="full" gui-text="Radius of vertices">0.1</param>
|
||||
<param name="vertex_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of vertex strokes">0.1</param>
|
||||
<param name="vertex_stroke_color" type="color" gui-text="Vertices\' color: ">255</param>
|
||||
</page>
|
||||
</param>
|
||||
<effect>
|
||||
<object-type>all</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="Origami Patterns">
|
||||
<submenu name="* Template submenu" />
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command location="inx" interpreter="python">OrigamiPatterns/Template.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
77
extensions/fablabchemnitz/origami_patterns/origami_patterns_waterbomb.inx
Executable file
77
extensions/fablabchemnitz/origami_patterns/origami_patterns_waterbomb.inx
Executable file
@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>Waterbomb</name>
|
||||
<id>org.inkscape.Origami_patterns.magic_ball</id>
|
||||
<param name="active-tab" type="notebook">
|
||||
<page name="options" gui-text="Options">
|
||||
<param name="pattern_first_line" type="optiongroup" appearance="combo" gui-text="First line:">
|
||||
<option value="waterbomb">Regular waterbomb</option>
|
||||
<option value="magic_ball">Magic ball</option>
|
||||
</param>
|
||||
<param name="pattern_last_line" type="optiongroup" appearance="combo" gui-text="Last line:">
|
||||
<option value="waterbomb">Regular waterbomb</option>
|
||||
<option value="magic_ball">Magic ball</option>
|
||||
</param>
|
||||
<param name="phase_shift" type="bool" gui-text="Shift phase?">false</param>
|
||||
<label>------------------------------</label>
|
||||
<param name="lines" type="int" min="1" max="100" gui-text="Number of lines">8</param>
|
||||
<param name="columns" type="int" min="1" max="100" gui-text="Number of columns">16</param>
|
||||
<label>------------------------------</label>
|
||||
<param name="length" type="float" max="10000" precision="3" gui-text="Length of grid square">10.0</param>
|
||||
<param name="units" type="optiongroup" appearance="combo" gui-text="Units">
|
||||
<option value="mm">mm</option>
|
||||
<option value="cm">cm</option>
|
||||
<option value="in">in</option>
|
||||
<option value="pt">pt</option>
|
||||
<option value="px">px</option>
|
||||
</param>
|
||||
<label>"Waterbomb tessellation" creates a simple tessellation pattern repeating the Waterbomb base, with a half-step phase shift between each line.
|
||||
The Magic ball is a different design that inverts both the upper half of the first line and the bottom half of the last line.</label>
|
||||
<param name="simulation_mode" type="bool" gui-text="Simulation mode">true</param>
|
||||
</page>
|
||||
<page name="mountains" gui-text="Mountain creases">
|
||||
<param name="mountain_bool" type="bool" gui-text="Draw mountains?">true</param>
|
||||
<param name="mountain_bool_only" type="bool" gui-text="Draw ONLY mountains?">false</param>
|
||||
<param name="mountain_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="mountain_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Mountain dash + gap length">1</param>
|
||||
<param name="mountain_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Mountain dash duty cycle">0.5</param>
|
||||
<param name="mountain_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of mountain strokes">0.1</param>
|
||||
<param name="mountain_stroke_color" type="color" gui-text="Mountain creases color: ">4278190335</param>
|
||||
</page>
|
||||
<page name="valleys" gui-text="Valley creases">
|
||||
<param name="valley_bool" type="bool" gui-text="Draw valley?">true</param>
|
||||
<param name="valley_bool_only" type="bool" gui-text="Draw ONLY valleys?">false</param>
|
||||
<param name="valley_dashes_bool" type="bool" gui-text="Dashed strokes?">true</param>
|
||||
<param name="valley_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Valley dash + gap length">1</param>
|
||||
<param name="valley_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Valley dash duty cycle">0.25</param>
|
||||
<param name="valley_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of valley strokes">0.1</param>
|
||||
<param name="valley_stroke_color" type="color" gui-text="Valley creases color: ">65535</param>
|
||||
</page>
|
||||
<page name="edge" gui-text="Edge">
|
||||
<param name="edge_bool" type="bool" gui-text="Draw edges?">true</param>
|
||||
<param name="edge_bool_only" type="bool" gui-text="Draw ONLY edges?">false</param>
|
||||
<param name="edge_single_path" type="bool" gui-text="Edges as single path?">true</param>
|
||||
<param name="edge_dashes_bool" type="bool" gui-text="Dashed strokes?">false</param>
|
||||
<param name="edge_dashes_len" type="float" min="0.1" max="10" appearance="full" precision="2" gui-text="Edge dash + gap length">1</param>
|
||||
<param name="edge_dashes_duty" type="float" min="0.1" max="1" appearance="full" precision="2" gui-text="Edge dash duty cycle">0.25</param>
|
||||
<param name="edge_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of edge strokes">0.1</param>
|
||||
<param name="edge_stroke_color" type="color" gui-text="Edge color: ">255</param>
|
||||
</page>
|
||||
<page name="vertices" gui-text="Vertices">
|
||||
<param name="vertex_bool" type="bool" gui-text="Draw vertices?">true</param>
|
||||
<param name="vertex_bool_only" type="bool" gui-text="Draw ONLY vertices?">false</param>
|
||||
<param name="vertex_radius" type="float" min="0.01" max="50" appearance="full" gui-text="Radius of vertices">0.1</param>
|
||||
<param name="vertex_stroke_width" type="float" min="0.01" max="3" appearance="full" gui-text="Width of vertex strokes">0.1</param>
|
||||
<param name="vertex_stroke_color" type="color" gui-text="Vertices\' color: ">255</param>
|
||||
</page>
|
||||
</param>
|
||||
<effect>
|
||||
<object-type>all</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="Origami Patterns" />
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command location="inx" interpreter="python">OrigamiPatterns/Waterbomb.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
Loading…
Reference in New Issue
Block a user