diff --git a/extensions/fablabchemnitz_encoder_disk_generator.inx b/extensions/fablabchemnitz_encoder_disk_generator.inx deleted file mode 100644 index 4bd3e305..00000000 --- a/extensions/fablabchemnitz_encoder_disk_generator.inx +++ /dev/null @@ -1,50 +0,0 @@ - - - <_name>Encoder Disk Generator - fablabchemnitz.de.encoder_disk_generator - - - 0.0 - 0.0 - 1 - 0.0 - 0.0 - 0.0 - 0.0 - - - 0.0 - 0.0 - 1 - 0.0 - 0.0 - 0.0 - - - 0.0 - 0.0 - 1 - 1 - 0.0 - 0.0 - - - 30.0 - 5.0 - 010011110111000010001101 - 25.0 - 10.0 - - - - all - - - - - - - - \ No newline at end of file diff --git a/extensions/fablabchemnitz_encoder_disk_generator.py b/extensions/fablabchemnitz_encoder_disk_generator.py deleted file mode 100644 index 98249de8..00000000 --- a/extensions/fablabchemnitz_encoder_disk_generator.py +++ /dev/null @@ -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() \ No newline at end of file diff --git a/extensions/fablabchemnitz_fill_row.inx b/extensions/fablabchemnitz_fill_row.inx deleted file mode 100644 index d1cd0cc0..00000000 --- a/extensions/fablabchemnitz_fill_row.inx +++ /dev/null @@ -1,19 +0,0 @@ - - - <_name>Fill With Copies - fablabchemnitz.de.fill_row - Fills a row with selected paths (works for rectangle objects too). Original author: Pawel Mosakowski. Edited by Mario Voigt (2020). - 10 - 10 - - all - - - - - - - - diff --git a/extensions/fablabchemnitz_fill_row.py b/extensions/fablabchemnitz_fill_row.py deleted file mode 100644 index 7e8911ae..00000000 --- a/extensions/fablabchemnitz_fill_row.py +++ /dev/null @@ -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() \ No newline at end of file diff --git a/extensions/fablabchemnitz_shelves.inx b/extensions/fablabchemnitz_shelves.inx deleted file mode 100644 index 0d6568e6..00000000 --- a/extensions/fablabchemnitz_shelves.inx +++ /dev/null @@ -1,37 +0,0 @@ - - - <_name>Parametric Shelves - fablabchemnitz.de.shelves - - <_item value="mm">mm - <_item value="cm">cm - <_item value="m">m - <_item value="km">km - <_item value="in">in - <_item value="ft">ft - <_item value="yd">yd - <_item value="pt">pt - <_item value="px">px - <_item value="pc">pc - - 1.2 - 0.3 - 0.05 - 100 - 100 - 40 - 10; 20; 35 - 0.6 - 10 - - all - - - - - - - - \ No newline at end of file diff --git a/extensions/fablabchemnitz_shelves.py b/extensions/fablabchemnitz_shelves.py deleted file mode 100644 index a053707f..00000000 --- a/extensions/fablabchemnitz_shelves.py +++ /dev/null @@ -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() \ No newline at end of file