removed some unwanted extensions

This commit is contained in:
Mario Voigt 2020-07-30 14:35:23 +02:00
parent eaa59837dd
commit 6241edb17a
6 changed files with 0 additions and 776 deletions

View File

@ -1,50 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension>
<_name>Encoder Disk Generator</_name>
<id>fablabchemnitz.de.encoder_disk_generator</id>
<param name="tab" type="notebook">
<page name="rotary_enc" _gui-text="Rotary encoder">
<param name="diameter" type="float" min="0.0" max="1000.0" _gui-text="Diameter of the encoder disk">0.0</param>
<param name="hole_diameter" type="float" min="0.0" max="1000.0" _gui-text="Diameter of the center hole">0.0</param>
<param name="segments" type="int" min="1" max="10000" _gui-text="Number of segments">1</param>
<param name="outer_encoder_diameter" type="float" min="0.0" max="1000.0" _gui-text="Diameter of the outer encoder disk">0.0</param>
<param name="outer_encoder_width" type="float" min="1.0" max="1000.0" _gui-text="Width of the outer encoder disk">0.0</param>
<param name="inner_encoder_diameter" type="float" min="0.0" max="1000.0" _gui-text="Diameter of the inner encoder disk">0.0</param>
<param name="inner_encoder_width" type="float" min="1.0" max="1000.0" _gui-text="Width of the inner encoder disk">0.0</param>
</page>
<page name="brgc" _gui-text="Binary reflected gray code (BRGC)">
<param name="brgc_diameter" type="float" min="0.0" max="1000.0" _gui-text="Diameter of the encoder disk">0.0</param>
<param name="brgc_hole_diameter" type="float" min="0.0" max="1000.0" _gui-text="Diameter of the center hole">0.0</param>
<param name="bits" type="int" min="1" max="32" _gui-text="Number of bits/tracks">1</param>
<param name="encoder_diameter" type="float" min="1.0" max="1000.0" _gui-text="Outer diameter of the last track">0.0</param>
<param name="track_width" type="float" min="1.0" max="1000.0" _gui-text="Width of one track">0.0</param>
<param name="track_distance" type="float" min="0.0" max="1000.0" _gui-text="Distance between tracks">0.0</param>
</page>
<page name="stgc" _gui-text="Single-track gray code (STGC)">
<param name="stgc_diameter" type="float" min="0.0" max="1000.0" _gui-text="Diameter of the encoder disk">0.0</param>
<param name="stgc_hole_diameter" type="float" min="0.0" max="1000.0" _gui-text="Diameter of the center hole">0.0</param>
<param name="cutouts" type="int" min="1" max="5" _gui-text="Number of cutouts">1</param>
<param name="sensors" type="int" min="1" max="36" _gui-text="Number of sensors">1</param>
<param name="stgc_encoder_diameter" type="float" min="1.0" max="1000.0" _gui-text="Outer diameter of track">0.0</param>
<param name="stgc_track_width" type="float" min="1.0" max="1000.0" _gui-text="Width of one track">0.0</param>
</page>
<page name="bitmap_enc" _gui-text="Bitmap encoder">
<param name="bm_diameter" type="float" min="0.0" max="1000.0" _gui-text="Diameter of the encoder disk">30.0</param>
<param name="bm_hole_diameter" type="float" min="0.0" max="1000.0" _gui-text="Diameter of the center hole">5.0</param>
<param name="bm_bits" type="string" _gui-text="Bits for segments">010011110111000010001101</param>
<param name="bm_outer_encoder_diameter" type="float" min="0.0" max="1000.0" _gui-text="Diameter of the outer encoder disk">25.0</param>
<param name="bm_outer_encoder_width" type="float" min="1.0" max="1000.0" _gui-text="Width of the outer encoder disk">10.0</param>
</page>
</param>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu _name="FabLab Chemnitz">
<submenu _name="Shape/Pattern from Generator" />
</submenu>
</effects-menu>
</effect>
<script>
<command reldir="extensions" interpreter="python">fablabchemnitz_encoder_disk_generator.py</command>
</script>
</inkscape-extension>

View File

@ -1,404 +0,0 @@
#!/usr/bin/env python3
import inkex
import math
import string
from lxml import etree
from inkex.transforms import Transform
# Function for calculating a point from the origin when you know the distance
# and the angle
def calculatePoint(angle, distance):
if (angle < 0 or angle > 360):
return None
else:
return [
distance * math.cos(math.radians(angle)),
distance * math.sin(math.radians(angle))]
class EncoderDiskGenerator(inkex.Effect):
def __init__(self):
inkex.Effect.__init__(self)
self.arg_parser.add_argument("--tab", default="rotary_enc", help="Selected tab")
self.arg_parser.add_argument("--diameter", type=float, default=0.0, help="Diameter of the encoder disk")
self.arg_parser.add_argument("--hole_diameter", type=float, default=0.0, help="Diameter of the center hole")
self.arg_parser.add_argument("--segments", type=int, default=0, help="Number of segments")
self.arg_parser.add_argument("--outer_encoder_diameter", type=float, default=0.0, help="Diameter of the outer encoder disk")
self.arg_parser.add_argument("--outer_encoder_width", type=float, default=0.0, help="Width of the outer encoder disk")
self.arg_parser.add_argument("--inner_encoder_diameter", type=float, default=0.0, help="Diameter of the inner encoder disk")
self.arg_parser.add_argument("--inner_encoder_width", type=float, default=0.0, help="Width of the inner encoder disk")
self.arg_parser.add_argument("--bits", type=int, default=1, help="Number of bits/tracks")
self.arg_parser.add_argument("--encoder_diameter", type=float, default=0.0, help="Outer diameter of the last track")
self.arg_parser.add_argument("--track_width", type=float, default=0.0, help="Width of one track")
self.arg_parser.add_argument("--track_distance", type=float, default=0.0, help="Distance between tracks")
self.arg_parser.add_argument("--bm_diameter", type=float, default=0.0, help="Diameter of the encoder disk")
self.arg_parser.add_argument("--bm_hole_diameter", type=float, default=0.0, help="Diameter of the center hole")
self.arg_parser.add_argument("--bm_bits", default="", help="Bits of segments")
self.arg_parser.add_argument("--bm_outer_encoder_diameter", type=float, default=0.0, help="Diameter of the outer encoder disk")
self.arg_parser.add_argument("--bm_outer_encoder_width", type=float, default=0.0, help="Width of the outer encoder disk")
self.arg_parser.add_argument("--brgc_diameter", type=float, default=0.0, help="Diameter of the encoder disk")
self.arg_parser.add_argument("--stgc_diameter", type=float, default=0.0, help="Diameter of the encoder disk")
self.arg_parser.add_argument("--brgc_hole_diameter", type=float, default=0.0, help="Diameter of the center hole")
self.arg_parser.add_argument("--cutouts", type=int, default=1, help="Number of cutouts")
self.arg_parser.add_argument("--sensors", type=int, default=1, help="Number of sensors")
self.arg_parser.add_argument("--stgc_hole_diameter", type=float, default=0.0, help="Diameter of the center hole")
self.arg_parser.add_argument("--stgc_encoder_diameter", type=float, default=0.0, help="Outer diameter of the last track")
self.arg_parser.add_argument("--stgc_track_width", type=float, default=0.0, help="Width of track")
# This function just concatenates the point and the command and returns
# the data string
def parsePathData(self, command, point):
path_data = command + ' %f ' % point[0] + ' %f ' % point[1]
return path_data
# Creates a gray code of size bits (n >= 1) in the format of a list
def createGrayCode(self, bits):
gray_code = [[False], [True]]
if bits == 1:
return gray_code
for i in range(bits - 1):
temp = []
# Reflect values
for j in range(len(gray_code[0]), 0, -1):
for k in range(0, len(gray_code)):
if j == len(gray_code[0]):
temp.append([gray_code[k][-j]])
else:
temp[k].append(gray_code[k][-j])
while temp:
gray_code.append(temp.pop())
# Add False to the "old" values and true to the new ones
for j in range(0, len(gray_code)):
if j < len(gray_code) / 2:
gray_code[j].insert(0, False)
else:
gray_code[j].insert(0, True)
temp = []
return gray_code
# This function returns the segments for a gray encoder
def drawGrayEncoder(self, line_style, bits, encoder_diameter, track_width,
track_distance):
gray_code = self.createGrayCode(bits)
segments = []
segment_size = 0
start_angle_position = 0
index = 0
current_encoder_diameter = encoder_diameter
previous_item = False
position_size = 360.0 / (2 ** bits)
for i in range(len(gray_code[0]) - 1, -1, -1):
for j in gray_code:
if j[i]:
segment_size += 1
if segment_size == 1:
start_angle_position = index
previous_item = True
elif not j[i] and previous_item:
segments.append(
self.drawSegment(line_style,
start_angle_position * position_size,
segment_size * position_size,
current_encoder_diameter,
track_width))
segment_size = 0
previous_item = False
start_angle_position = 0
index += 1
if previous_item:
segments.append(self.drawSegment(line_style,
start_angle_position * position_size,
segment_size * position_size,
current_encoder_diameter, track_width))
segment_size = 0
previous_item = False
start_angle_position = 0
current_encoder_diameter -= (2 * track_distance + 2 * track_width)
index = 0
return segments
# Check if there is too many cutouts compared to number of sensors
def validSTGrayEncoder(self, cutouts, sensors):
if sensors < 6 and cutouts > 1:
pass
elif sensors <= 10 and cutouts > 2:
pass
elif sensors <= 16 and cutouts > 3:
pass
elif sensors <= 23 and cutouts > 4:
pass
elif sensors <= 36 and cutouts > 5:
pass
else:
return True
return False
# This function returns the segments for a single-track gray encoder
def drawSTGrayEncoder(
self, line_style, cutouts, sensors, encoder_diameter, track_width):
segments = []
resolution = 360.0 / (cutouts * 2 * sensors)
current_angle = 0.0
added_angle = ((2 * cutouts + 1) * resolution)
for n in range(cutouts):
current_segment_size = ((n * 2 + 2) * cutouts + 1) * resolution
segments.append(
self.drawSegment(
line_style, current_angle,
current_segment_size,
encoder_diameter, track_width))
current_angle += added_angle + current_segment_size
return segments
def drawLabel(self, group, angle, segment_angle, outer_diameter, labelNum):
outer_radius = outer_diameter / 2
label_angle = angle + (segment_angle / 2)
point = calculatePoint(label_angle, outer_radius)
matrix = Transform('rotate(' + str(label_angle + 90) + ')').matrix
matrix_str = str(matrix[0][0]) + "," + str(matrix[0][1])
matrix_str += "," + str(matrix[1][0]) + "," + str(matrix[1][1]) + ",0,0"
text = {
'id': 'text' + str(labelNum),
#'sodipodi:linespacing': '0%',
'style': 'font-size: 6px;font-style: normal;font-family: Sans',
#'transform': 'matrix(' + matrix_str + ')',
'x': str(point[0]),
'y': str(point[1]),
#'xml:space': 'preserve'
}
textElement = etree.SubElement(group, inkex.addNS('text', 'svg'), text)
#tspanElement = etree.Element(
# textElement, '{%s}%s' % (svg_uri, 'tspan'), tspan)
textElement.text = string.printable[labelNum % len(string.printable)]
self.svg.get_current_layer().append(textElement)
# This function creates the path for one single segment
def drawSegment(self, line_style, angle, segment_angle, outer_diameter, width):
path = {'style': str(inkex.Style(line_style))}
path['d'] = ''
outer_radius = outer_diameter / 2
# Go to the first point in the segment
path['d'] += self.parsePathData(
'M', calculatePoint(angle, outer_radius - width))
# Go to the second point in the segment
path['d'] += self.parsePathData('L', calculatePoint(angle, outer_radius))
# Go to the third point in the segment, draw an arc
point = calculatePoint(angle + segment_angle, outer_radius)
path['d'] += self.parsePathData('A', [outer_radius, outer_radius]) + \
'0 0 1' + self.parsePathData(' ', point)
# Go to the fourth point in the segment
point = calculatePoint(angle + segment_angle, outer_radius - width)
path['d'] += self.parsePathData('L', point)
# Go to the beginning in the segment, draw an arc
point = calculatePoint(angle, outer_radius - width)
# 'Z' closes the path
path['d'] += (self.parsePathData(
'A',
[outer_radius - width, outer_radius - width]) +
'0 0 0' + self.parsePathData(' ', point) + ' Z')
# Return the path
return path
# This function adds an element to the document
def addElement(self, element_type, group, element_attributes):
etree.SubElement(
group, inkex.addNS(element_type, 'svg'),
element_attributes)
def drawCircles(self, hole_diameter, diameter):
# Attributes for the center hole, then create it, if diameter is 0, dont
# create it
circle_elements = []
attributes = {
'style': str(inkex.Style({'stroke': 'none', 'fill': 'black'})),
'r': str(hole_diameter / 2)
}
if self.options.hole_diameter > 0:
circle_elements.append(attributes)
# Attributes for the guide hole in the center hole, then create it
attributes = {
'style': str(inkex.Style(
{'stroke': 'white', 'fill': 'white', 'stroke-width': '0.1'})),
'r': '1'
}
circle_elements.append(attributes)
# Attributes for the outer rim, then create it
attributes = {
'style': str(inkex.Style(
{'stroke': 'black', 'stroke-width': '1', 'fill': 'none'})),
'r': str(diameter / 2)
}
if self.options.diameter > 0:
circle_elements.append(attributes)
return circle_elements
def drawCommonCircles(self, group, diameter, hole_diameter):
circle_elements = self.drawCircles(hole_diameter, diameter)
for circle in circle_elements:
self.addElement('circle', group, circle)
def effectBrgc(self, group, line_style, diameter, hole_diameter):
if (((self.options.encoder_diameter / 2) -
(self.options.bits * self.options.track_width +
(self.options.bits - 1) * self.options.track_distance)) <
self.options.brgc_hole_diameter / 2):
inkex.errormsg("Innermost encoder smaller than the center hole!")
else:
segments = self.drawGrayEncoder(
line_style, self.options.bits,
self.options.encoder_diameter,
self.options.track_width,
self.options.track_distance)
for item in segments:
self.addElement('path', group, item)
self.drawCommonCircles(group, diameter, hole_diameter)
def effectStgc(self, group, line_style, diameter, hole_diameter):
if ((self.options.stgc_encoder_diameter / 2) -
self.options.stgc_track_width < self.options.stgc_hole_diameter / 2):
inkex.errormsg("Encoder smaller than the center hole!")
elif not self.validSTGrayEncoder(self.options.cutouts, self.options.sensors):
inkex.errormsg("Too many cutouts compared to number of sensors!")
else:
segments = self.drawSTGrayEncoder(line_style, self.options.cutouts,
self.options.sensors, self.options.stgc_encoder_diameter,
self.options.stgc_track_width)
for item in segments:
self.addElement('path', group, item)
self.drawCommonCircles(group, diameter, hole_diameter)
def effectRotaryEnc(self, group, line_style, diameter, hole_diameter):
# Angle of one single segment
segment_angle = 360.0 / (self.options.segments * 2)
for segment_number in range(0, self.options.segments):
angle = segment_number * (segment_angle * 2)
if (self.options.outer_encoder_width > 0 and
self.options.outer_encoder_diameter > 0 and
self.options.outer_encoder_diameter / 2 >
self.options.outer_encoder_width):
segment = self.drawSegment(line_style, angle,
segment_angle,
self.options.outer_encoder_diameter,
self.options.outer_encoder_width)
self.addElement('path', group, segment)
# If the inner encoder diameter is something else than 0; create it
if (self.options.outer_encoder_width > 0 and
self.options.inner_encoder_diameter > 0 and
self.options.inner_encoder_diameter / 2 >
self.options.inner_encoder_width):
# The inner encoder must be half an encoder segment ahead of the outer one
segment = self.drawSegment(
line_style, angle + (segment_angle / 2), segment_angle,
self.options.inner_encoder_diameter,
self.options.inner_encoder_width)
self.addElement('path', group, segment)
self.drawCommonCircles(group, diameter, hole_diameter)
def effectBitmapEnc(self, group, line_style, diameter, hole_diameter):
bits = self.options.bm_bits
bm_segments = len(bits)
# Angle of one single segment
segment_angle = 360.0 / bm_segments
for segment_number in range(0, bm_segments):
angle = segment_number * segment_angle
if (self.options.bm_outer_encoder_width > 0 and
self.options.bm_outer_encoder_diameter > 0 and
self.options.bm_outer_encoder_diameter >
self.options.bm_outer_encoder_width):
self.drawLabel(group,
angle, segment_angle,
self.options.bm_diameter,
segment_number)
# Drawing only the black segments
if (bits[segment_number] == '1'):
segment = self.drawSegment(
line_style, angle,
segment_angle,
self.options.bm_outer_encoder_diameter,
self.options.bm_outer_encoder_width)
self.addElement('path', group, segment)
self.drawCommonCircles(group, diameter, hole_diameter)
def effect(self):
# Group to put all the elements in, center set in the middle of the view
group = etree.SubElement(self.svg.get_current_layer(), 'g', {
inkex.addNS('label', 'inkscape'): 'Encoder disk',
'transform': 'translate' + str(self.svg.namedview.center)
})
# Line style for the encoder segments
line_style = {
'stroke': 'white',
'stroke-width': '0',
'fill': 'black'
}
if self.options.tab == "brgc":
self.effectBrgc(group, line_style,
self.options.brgc_diameter,
self.options.brgc_hole_diameter)
if self.options.tab == "stgc":
self.effectStgc(group, line_style,
self.options.stgc_diameter,
self.options.stgc_hole_diameter)
if self.options.tab == "rotary_enc":
self.effectRotaryEnc(group, line_style,
self.options.diameter,
self.options.hole_diameter)
if self.options.tab == "bitmap_enc":
self.effectBitmapEnc(group, line_style,
self.options.bm_diameter,
self.options.bm_hole_diameter)
if __name__ == '__main__':
EncoderDiskGenerator().run()

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<_name>Fill With Copies</_name>
<id>fablabchemnitz.de.fill_row</id>
<param name="help_text" type="description">Fills a row with selected paths (works for rectangle objects too). Original author: Pawel Mosakowski. Edited by Mario Voigt (2020).</param>
<param name="gap_x" type="int" min="0" max="100000" _gui-text="Gap in X direction">10</param>
<param name="gap_y" type="int" min="0" max="100000" _gui-text="Gap in Y direction">10</param>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu _name="FabLab Chemnitz">
<submenu _name="Nesting/Cut Optimization"/>
</submenu>
</effects-menu>
</effect>
<script>
<command reldir="extensions" interpreter="python">fablabchemnitz_fill_row.py</command>
</script>
</inkscape-extension>

View File

@ -1,73 +0,0 @@
#!/usr/bin/env python3
import sys
from inkex import Effect as InkscapeEffect
from inkex import etree, addNS
from copy import deepcopy
from inkex.paths import Path
from inkex.transforms import Transform
from lxml import etree
class FillRow(InkscapeEffect):
def __init__(self):
InkscapeEffect.__init__(self)
self.arg_parser.add_argument("--gap_x", type=int, default="10")
self.arg_parser.add_argument("--gap_y",type=int, default="10")
def effect(self):
if len(self.svg.selected) > 0:
self.total_height = 0
for id, node in self.svg.selected.items():
self.fill_row(node)
def fill_row(self, node):
#max_line_width = self.svg.unittouu('450mm')
#x_start = self.svg.unittouu('3mm')
#y_start = self.svg.unittouu('1600mm') - self.svg.unittouu('3mm')
#gap_x = gap_y = self.svg.unittouu('10mm')
svg = self.document.getroot()
x_start = 0
y_start = self.svg.unittouu(svg.attrib['height'])
max_line_width = self.svg.unittouu(svg.get('width'))
total_width = 0
total_height = self.total_height
group = etree.SubElement(self.svg.get_current_layer(), addNS('g','svg'))
bbox = node.bounding_box()
x = bbox.left
y = bbox.top
node_width = self.options.gap_x + bbox.width
while total_width + node_width < max_line_width:
node_copy = deepcopy(node)
group.append(node_copy)
x_dest = x_start + total_width
y_dest = y_start - (total_height + bbox.height)
# translation logic
if node_copy.tag == addNS('path','svg'):
x_delta = x_dest - x
y_delta = y_dest - y
path = Path(node_copy.attrib['d'])
path.translate(x_delta, y_delta, True)
node_copy.attrib['d'] = str(Path(path))
elif node_copy.tag == addNS('g','svg'):
x_delta = x_dest - x
y_delta = y_dest - y
translation_matrix = [[1.0, 0.0, x_delta], [0.0, 1.0, y_delta]]
Transform(translation_matrix) * node_copy.transform
else:
node_copy.attrib['x'] = str(x_dest)
node_copy.attrib['y'] = str(y_dest)
total_width += node_width
self.total_height += group.bounding_box().height + self.options.gap_y
FillRow().run()

View File

@ -1,37 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<_name>Parametric Shelves</_name>
<id>fablabchemnitz.de.shelves</id>
<param name="unit" type="enum" _gui-text="Unit">
<_item value="mm">mm</_item>
<_item value="cm">cm</_item>
<_item value="m">m</_item>
<_item value="km">km</_item>
<_item value="in">in</_item>
<_item value="ft">ft</_item>
<_item value="yd">yd</_item>
<_item value="pt">pt</_item>
<_item value="px">px</_item>
<_item value="pc">pc</_item>
</param>
<param name="thickness" type="float" min="1.0" max="100.0" _gui-text="Material thickness">1.2</param>
<param name="tool_diameter" type="float" min="0.0" _gui-text="Tool diameter (mind the units!)">0.3</param>
<param name="tolerance" type="float" min="-10000.0" max="10000.0" _gui-text="Tolerance">0.05</param>
<param name="height" type="float" min="0.0" max="10000.0" _gui-text="Height">100</param>
<param name="width" type="float" min="0.0" max="10000.0" _gui-text="Width">100</param>
<param name="depth" type="float" min="0.0" max="10000.0" _gui-text="Depth">40</param>
<param name="shelve_list" type="string" min="0.0" max="10000.0" _gui-text="Shelve heigths (semicolon separated list)">10; 20; 35</param>
<param name="groove_depth" type="float" min="0.0" max="10000.0" _gui-text="Groove depth">0.6</param>
<param name="tab_size" type="float" min="0.0" max="10000.0" _gui-text="Tab size (approximate; will be resized to evenly fit the side)">10</param>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu _name="FabLab Chemnitz">
<submenu _name="Finger-jointed/Tabbed Boxes" />
</submenu>
</effects-menu>
</effect>
<script>
<command reldir="extensions" interpreter="python">fablabchemnitz_shelves.py</command>
</script>
</inkscape-extension>

View File

@ -1,193 +0,0 @@
#!/usr/bin/env python3
from inkscape_helper.Coordinate import Coordinate
import inkex
from lxml import etree
default_style = str(inkex.Style({'stroke': '#000000','stroke-width': '1','fill': 'none'}))
groove_style = str(inkex.Style({'stroke': '#0000FF','stroke-width': '1','fill': 'none'}))
mark_style = str(inkex.Style({'stroke': '#00FF00','stroke-width': '1','fill': 'none'}))
def draw_line(parent, start, end, style = default_style):
line_attribs = {'style': style,
'd': 'M '+str(start.x)+','+str(start.y)+' L '+str(end.x)+','+str(end.y)}
etree.SubElement(parent, inkex.addNS('path', 'svg'), line_attribs)
class Shelves(inkex.Effect):
def __init__(self):
inkex.Effect.__init__(self)
self.arg_parser.add_argument('--unit', default = 'cm', help = 'Unit, should be one of ')
self.arg_parser.add_argument('--tool_diameter', type = float, default = '0.3', help = 'Tool diameter')
self.arg_parser.add_argument('--tolerance', type = float, default = '0.05')
self.arg_parser.add_argument('--thickness', type = float, dest = 'thickness', default = '1.2', help = 'Material thickness')
self.arg_parser.add_argument('--width', type = float, default = '3.0', help = 'Box width')
self.arg_parser.add_argument('--height', type = float, default = '10.0', help = 'Box height')
self.arg_parser.add_argument('--depth', type = float, default = '3.0', help = 'Box depth')
self.arg_parser.add_argument('--shelve_list',default = '', help = 'semicolon separated list of shelve heigths')
self.arg_parser.add_argument('--groove_depth', type = float, default = '0.5', help = 'Groove depth')
self.arg_parser.add_argument('--tab_size', type = float, default = '10', help = 'Approximate tab width (tabs will be evenly spaced along the length of the edge)')
def effect(self):
# input sanity check and unit conversion
error = False
self.knownUnits = ['in', 'pt', 'px', 'mm', 'cm', 'm', 'km', 'pc', 'yd', 'ft']
if self.options.unit not in self.knownUnits:
inkex.errormsg('Error: unknown unit. '+ self.options.unit)
error = True
unit = self.options.unit
if min(self.options.height, self.options.width, self.options.depth) == 0:
inkex.errormsg('Error: Dimensions must be non zero')
error = True
shelves = []
for s in self.options.shelve_list.split(';'):
try:
shelves.append(self.svg.unittouu(str(s).strip() + unit))
except ValueError:
inkex.errormsg('Error: nonnumeric value in shelves (' + s + ')')
error = True
if error:
exit()
height = self.svg.unittouu(str(self.options.height) + unit)
width = self.svg.unittouu(str(self.options.width) + unit)
depth = self.svg.unittouu(str(self.options.depth) + unit)
thickness = self.svg.unittouu(str(self.options.thickness) + unit)
groove_depth = self.svg.unittouu(str(self.options.groove_depth) + unit)
tab_size = self.svg.unittouu(str(self.options.tab_size) + unit)
tolerance = self.svg.unittouu(str(self.options.tolerance) + unit)
tool_diameter = self.svg.unittouu(str(self.options.tool_diameter) + unit)
doc_root = self.document.getroot()
docWidth = self.svg.unittouu(doc_root.get('width'))
docHeigh = self.svg.unittouu(doc_root.attrib['height'])
layer = etree.SubElement(doc_root, 'g')
layer.set(inkex.addNS('label', 'inkscape'), 'Shelves')
layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
def H(x):
return Coordinate(x, 0)
def V(x):
return Coordinate(0, x)
def tab_count(dist, desired_tab_size):
F = int(dist // desired_tab_size)
if F / 2 % 2 == 0: # make sure we have an odd number of tabs
n = F // 2
else:
n = (F - 1) // 2
return 2 * n + 1
# create groups for the different parts
g_l_side = etree.SubElement(layer, 'g')
g_r_side = etree.SubElement(layer, 'g')
g_top = etree.SubElement(layer, 'g')
g_bottom = etree.SubElement(layer, 'g')
g_back = etree.SubElement(layer, 'g')
g_divider = etree.SubElement(layer, 'g')
h_spacing = H(10 + thickness)
v_spacing = V(10 + thickness)
v_tab_count = tab_count(height, tab_size)
v_tab = V(height / v_tab_count)
h_tab_count = tab_count(width, tab_size)
h_tab = H(width / h_tab_count)
d_tab_count = tab_count(depth, tab_size)
d_tab_size = depth / d_tab_count
h_tab_height = V(thickness)
top_origin = h_spacing * 2 + v_spacing + H(depth)
left_side_origin = h_spacing + v_spacing * 2 + V(depth)
back_origin = left_side_origin + h_spacing + H(depth)
right_side_origin = back_origin + h_spacing + H(width)
bottom_origin = back_origin + v_spacing + V(height)
def draw_tabbed_edge(parent, edge_start, tab, inset, count, invert = False):
start = edge_start + (inset if invert else Coordinate(0, 0))
for i in range(count):
if (i % 2 == 0) != invert:
t_offset = inset
else:
t_offset = Coordinate(0, 0)
end = start + tab
#inkex.utils.debug(str((i, start, end, t_offset)))
draw_line(parent, start, end)
if i < count - 1: # skip last one
start = edge_start + t_offset + tab * (i + 1)
draw_line(parent, end, start)
# top
draw_line(g_top, top_origin, top_origin + H(width))
draw_tabbed_edge(g_top, top_origin, V(d_tab_size), H(thickness), d_tab_count, False)
draw_tabbed_edge(g_top, top_origin + H(width) , V(d_tab_size), H(-thickness), d_tab_count, False)
draw_tabbed_edge(g_top, top_origin + V(depth), h_tab, V(-thickness), h_tab_count, True)
# groove
center_v_groove_l = (width - thickness) / 2 - tolerance
groove_l_side = top_origin + H(center_v_groove_l)
groove_r_side = groove_l_side + H(thickness + tolerance * 2)
draw_line(g_top, groove_l_side, groove_l_side + V(depth), groove_style)
draw_line(g_top, groove_r_side, groove_r_side + V(depth), groove_style)
# left
draw_line(g_l_side, left_side_origin, left_side_origin + V(height))
draw_tabbed_edge(g_l_side, left_side_origin + H(depth), v_tab, H(-thickness), v_tab_count, True)
draw_tabbed_edge(g_l_side, left_side_origin, H(d_tab_size), V(thickness), d_tab_count, True)
draw_tabbed_edge(g_l_side, left_side_origin + V(height), H(d_tab_size), V(-thickness), d_tab_count, True)
# back
draw_tabbed_edge(g_back, back_origin, v_tab, H(thickness), v_tab_count, False)
draw_tabbed_edge(g_back, back_origin + H(width), v_tab, H(-thickness), v_tab_count, False)
draw_tabbed_edge(g_back, back_origin, h_tab, V(thickness), h_tab_count, False)
draw_tabbed_edge(g_back, back_origin + V(height), h_tab, V(-thickness), h_tab_count, False)
# groove
groove_l_side = back_origin + H(center_v_groove_l)
groove_r_side = groove_l_side + H(thickness + tolerance * 2)
draw_line(g_back, groove_l_side, groove_l_side + V(height), groove_style)
draw_line(g_back, groove_r_side, groove_r_side + V(height), groove_style)
# right
draw_line(g_r_side, right_side_origin + H(depth), right_side_origin + H(depth) + V(height))
draw_tabbed_edge(g_r_side, right_side_origin, v_tab, H(thickness), v_tab_count, True)
draw_tabbed_edge(g_r_side, right_side_origin, H(d_tab_size), V(thickness), d_tab_count, True)
draw_tabbed_edge(g_r_side, right_side_origin + V(height), H(d_tab_size), V(-thickness), d_tab_count, True)
# bottom
draw_line(g_bottom, bottom_origin + V(depth), bottom_origin + V(depth) + H(width))
draw_tabbed_edge(g_bottom, bottom_origin, V(d_tab_size), H(thickness), d_tab_count, False)
draw_tabbed_edge(g_bottom, bottom_origin + H(width) , V(d_tab_size), H(-thickness), d_tab_count, False)
draw_tabbed_edge(g_bottom, bottom_origin, h_tab, V(thickness), h_tab_count, True)
# groove
groove_l_side = bottom_origin + H(center_v_groove_l)
groove_r_side = groove_l_side + H(thickness + tolerance * 2)
draw_line(g_bottom, groove_l_side, groove_l_side + V(depth), groove_style)
draw_line(g_bottom, groove_r_side, groove_r_side + V(depth), groove_style)
#shelves
prev_top = 0
gr_short = thickness - groove_depth + tool_diameter / 2 # avoid that the grooves are visible from the outside
for s in shelves:
s_top = prev_top + thickness + s - tolerance
s_bottom = s_top + thickness + tolerance * 2
draw_line(g_l_side, left_side_origin + V(s_top), left_side_origin + V(s_top) + H(depth - gr_short), groove_style)
draw_line(g_l_side, left_side_origin + V(s_bottom), left_side_origin + V(s_bottom) + H(depth - gr_short), groove_style)
draw_line(g_r_side, right_side_origin + V(s_top) + H(gr_short), right_side_origin + V(s_top) + H(depth), groove_style)
draw_line(g_r_side, right_side_origin + V(s_bottom) + H(gr_short), right_side_origin + V(s_bottom) + H(depth), groove_style)
draw_line(g_back, back_origin + V(s_top) + H(gr_short), back_origin + V(s_top) + H(width - gr_short), groove_style)
draw_line(g_back, back_origin + V(s_bottom) + H(gr_short), back_origin + V(s_bottom) + H(width - gr_short), groove_style)
prev_top = s_top
# Create effect instance and apply it.
Shelves().run()