Commits

iorodeo committed 1e5aa9b

Project creation.

  • Participants

Comments (0)

Files changed (61)

+syntax: glob
+*.pyc
+*~
+*.o
+*.egg-info
+*.swp
+*.scad
+*.stl
+*.pkl
+*.komodo*
+*.egg-info
+.DS_Store
+build
+dist
+.komodo*
+deb_dist
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+
+"""
+Parameters for two chamber flybox. 
+
+Units: mm
+"""
+create_dxf = True 
+create_stl = False
+create_scad_proj = False
+#style = '3mm'
+style = '1.5mm'
+
+# Inner dimensions of the box
+x_inner = 100.0
+y_inner = 75.0
+z_inner = 10.0
+dim_inner = x_inner, y_inner, z_inner 
+
+# Standoffs
+diam_standoff = 6.0
+diam_standoff_hole = 3.4 
+space_standoff = 1.0
+
+# Material thickness 
+if style == '3mm':
+    thickness_side = 3.0
+    thickness_door = 3.0 
+    thickness_divider = 3.0
+    thickness_top_outer = 3.0 
+    thickness_bot_outer = 3.0 
+elif style == '1.5mm':
+    thickness_side = 1.5
+    thickness_door = 1.5 
+    thickness_divider = 1.5
+    thickness_top_outer = 1.5 
+    thickness_bot_outer = 1.5 
+else:
+    raise ValueError, 'unknown style {0}'.format(style)
+
+thickness_top_inner = 1.5
+thickness_bot_inner = 1.5 
+
+thickness_divider_transtabs = 1.5
+thickness_divider_transtabs_side = 0.5 
+
+# Radii 
+radius_top = 3.0
+radius_bot = 3.0 
+radius_door = 0.5*(z_inner + thickness_top_inner + thickness_bot_inner)
+
+# Door handle and tolerance 
+length_door_handle = 1.5*radius_door
+diam_door_handle_hole = radius_door
+z_tol_door = 0.0
+
+# Tabs
+width_tab_normal = 10.0 
+width_tab_div_to_side = z_inner/3.0
+tab_pos_div_to_side = (0.5,)
+tab_pos_div_to_topbot = (0.25,0.75)
+tab_pos_side_to_topbot = (0.1,0.5,0.9)
+
+# rendering fn parameters
+projection_fn = 50
+stl_fn = 50
+
+# stl veiwer color rgba
+vconfig_color_standoff = 0.4, 0.4, 0.4, 1.0
+vconfig_color_top_inner = 0.4, 0.4, 1.0, 1.0
+vconfig_color_top_outer = vconfig_color_top_inner 
+vconfig_color_bot_inner = vconfig_color_top_inner
+vconfig_color_bot_outer = vconfig_color_top_inner
+vconfig_color_side = 0.9, 0.9, 0.9, 1.0
+vconfig_color_divider = vconfig_color_side 
+vconfig_color_door = vconfig_color_side 
+
+vconfig_color_divider_transtabs = 0.6, 0.6, 1.0, 0.3
+vconfig_color_transtabs_side = 0.9, 0.9, 0.9, 1.0
+
+# stl vconfig backgound color rgb  and size
+vconfig_color_background = 0.5, 0.5, 0.6
+vconfig_size = 600,600
+
+
+
+

flybox_two_chamber.py

+from __future__ import print_function
+import os
+import pickle
+import subprocess
+from py2scad import *
+
+
+class FlyBoxTwoChamber(object):
+
+    def __init__(self, params):
+        self.params = params
+        self.make_top_and_bot()
+        self.make_doors()
+        self.make_sides()
+        self.make_divider()
+        self.make_divider_transtabs()
+        self.make_vconfig_color_dict()
+
+    def make_top_and_bot(self):
+        """
+        Create inner and outer layers of the top and bottom.
+        """
+        # Outer dimesions for box
+        x = self.params.x_inner  
+        x += 2*self.params.thickness_door  
+        x += 2*self.params.diam_standoff + 4*self.params.space_standoff
+        y = self.params.y_inner
+        y += 2*self.params.thickness_side 
+        y += 2*self.params.diam_standoff + 4*self.params.space_standoff
+        self.x_outer, self.y_outer = x, y
+
+        # Get list of slots for tabs
+        slot_list = []
+        slot_pos_list = self.get_slot_pos_list('side_to_topbot')
+        size_slot = self.params.width_tab_normal, self.params.thickness_side
+        for pos in slot_pos_list: 
+            slot_list.append((pos,size_slot))
+
+        slot_pos_list = self.get_slot_pos_list('div_to_topbot')
+        size_slot = self.params.thickness_divider, self.params.width_tab_normal
+        for pos in slot_pos_list:
+            slot_list.append((pos, size_slot))
+
+        # Create top and bottom parts - both inner and outer layers
+        for pos in ('top', 'bot'):
+            for layer in ('inner', 'outer'):
+                z = getattr(self.params,'thickness_{0}_{1}'.format(pos,layer))
+                r = getattr(self.params,'radius_{0}'.format(pos))
+                plate_params = { 'size': (x,y,z), 'radius': r, 'slots': slot_list}
+                part = Plate_W_Slots(plate_params).make()
+                setattr(self,'{0}_{1}'.format(pos,layer),part)
+
+        # Cut inner top and bottom to make slots for sliding doors
+        x_door_cut = self.params.thickness_door
+        y_door_cut = y
+        z_door_cut = 2.0*max([
+            self.params.thickness_top_inner, 
+            self.params.thickness_bot_inner,
+            ])
+        size_door_cut = x_door_cut, y_door_cut, z_door_cut
+        cube_door_cut = Cube(size=size_door_cut)
+
+        vx = 0.5*self.params.x_inner + 0.5*x_door_cut
+        vy = 2*self.params.space_standoff + self.params.diam_standoff
+        self.cube_door_cut_pos = Translate(cube_door_cut, v=( vx,vy,0))
+        self.cube_door_cut_neg = Translate(cube_door_cut, v=(-vx,vy,0))
+
+        self.top_inner = Difference([
+            self.top_inner,
+            self.cube_door_cut_pos,
+            self.cube_door_cut_neg,
+            ])
+
+        self.bot_inner = Difference([
+            self.bot_inner,
+            self.cube_door_cut_pos,
+            self.cube_door_cut_neg,
+            ])
+
+        # Create standoff holes and standoffs
+        self.hole_list_standoff = []
+        for i in (-1,0,1):
+            for j in (-1,1):
+                for pos in ('top', 'bot'):
+                    for layer in ('outer', 'inner'):
+
+                        x_hole = 0.5*x - self.params.space_standoff  
+                        x_hole -= 0.5*self.params.diam_standoff
+                        x_hole = i*x_hole
+
+                        y_hole = 0.5*y - self.params.space_standoff 
+                        y_hole -= 0.5*self.params.diam_standoff
+                        y_hole = j*y_hole
+
+                        hole = {
+                                'panel' : '{0}_{1}'.format(pos,layer),
+                                'type'  : 'round',
+                                'location' : (x_hole, y_hole),
+                                'size' : self.params.diam_standoff_hole,
+                                }
+                self.hole_list_standoff.append(hole)
+
+        self.add_holes(self.hole_list_standoff)
+
+        # Create standoff
+        self.standoff = Cylinder(
+                r1 = 0.5*self.params.diam_standoff,
+                r2 = 0.5*self.params.diam_standoff,
+                h = self.params.z_inner,
+                )
+
+
+    def make_doors(self):
+        """
+        Create the sliding doors.
+        """
+        x_door = self.params.z_inner 
+        x_door += self.params.thickness_top_inner 
+        x_door += self.params.thickness_bot_inner
+        x_door - self.params.z_tol_door
+
+        y_door = self.y_outer
+        y_door -= 2*self.params.space_standoff + self.params.diam_standoff
+        y_door += self.params.length_door_handle
+        self.x_door, self.y_door = x_door, y_door
+
+        part0 = rounded_box(
+                x_door, 
+                y_door, 
+                self.params.thickness_door,
+                self.params.radius_door,
+                round_z = False,
+                )
+
+        part1 = Cube(size=(
+            x_door, 
+            (y_door-self.params.length_door_handle), 
+            self.params.thickness_door
+            ))
+
+        part1 = Translate(part1,v=(0,-0.5*self.params.length_door_handle,0))
+        self.door = Union([part0,part1])
+
+        # Add handle hole to door
+        hole = {
+                'panel': 'door',
+                'type': 'round',
+                'location': (0,0.5*y_door - self.params.radius_door),
+                'size': self.params.diam_door_handle_hole,
+                }
+        self.add_holes([hole])
+
+
+    def make_sides(self):
+        """
+        Creates the side walls
+        """
+        x_side = self.params.x_inner
+        y_side = self.params.z_inner
+        z_side = self.params.thickness_side
+
+        tab_data_xz_pos = []
+        for pos in self.params.tab_pos_side_to_topbot:
+            tab_data_xz_pos.append((
+                pos, 
+                self.params.width_tab_normal,
+                self.params.thickness_top_inner + self.params.thickness_top_outer,
+                '+'
+                ))
+        tab_data_xz_neg = []
+        for pos in self.params.tab_pos_side_to_topbot:
+            tab_data_xz_neg.append((
+                pos,
+                self.params.width_tab_normal,
+                self.params.thickness_bot_inner + self.params.thickness_bot_outer,
+                '+'
+                ))
+
+        plate_params = {
+                'size': (x_side, y_side, z_side),
+                'xz+': tab_data_xz_pos,
+                'xz-': tab_data_xz_neg,
+                'yz+': [],
+                'yz-': [],
+                }
+        self.side = Plate_W_Tabs(plate_params).make()
+
+        # Add hole for divider tab
+        slot_list = []
+        slot_pos_list = self.get_slot_pos_list('div_to_side')
+        for pos in slot_pos_list:
+            slot_size = (
+                    self.params.thickness_divider,
+                    self.params.width_tab_div_to_side
+                    )
+            slot_hole = {
+                    'panel': 'side',
+                    'type': 'square',
+                    'location': pos,
+                    'size': slot_size,
+                    }
+            slot_list.append(slot_hole)
+        self.add_holes(slot_list)
+
+
+    def make_divider(self):
+        x_div = self.params.z_inner
+        y_div = self.params.y_inner
+        z_div = self.params.thickness_divider
+
+        tab_data_xz_pos = []
+        tab_data_xz_neg = []
+        width_tab = self.params.width_tab_div_to_side
+        depth_tab = self.params.thickness_side
+        for val in self.params.tab_pos_div_to_side:
+            tab_data = (val, width_tab, depth_tab, '+')
+            tab_data_xz_pos.append(tab_data)
+            tab_data_xz_neg.append(tab_data)
+
+        tab_data_yz_pos = []
+        tab_data_yz_neg = []
+        width_tab = self.params.width_tab_normal
+        depth_tab_pos = self.params.thickness_top_inner + self.params.thickness_top_outer
+        depth_tab_neg = self.params.thickness_bot_inner + self.params.thickness_bot_outer
+        for val in self.params.tab_pos_div_to_topbot:
+            tab_data_pos = (val, width_tab, depth_tab_pos, '+')
+            tab_data_neg = (val, width_tab, depth_tab_neg, '+')
+            tab_data_yz_pos.append(tab_data_pos)
+            tab_data_yz_neg.append(tab_data_neg)
+
+        params = {
+                'size': (x_div, y_div, z_div),
+                'xz+': tab_data_xz_pos,
+                'xz-': tab_data_xz_neg,
+                'yz+': tab_data_yz_pos,
+                'yz-': tab_data_yz_neg,
+                }
+        self.divider = Plate_W_Tabs(params).make()
+
+    def make_divider_transtabs(self):
+        x_div = self.params.z_inner
+        y_div = self.params.y_inner
+        z_div = self.params.thickness_divider_transtabs
+
+        tab_data_xz_pos = []
+        tab_data_xz_neg = []
+        width_tab = self.params.width_tab_div_to_side
+        depth_tab = self.params.thickness_side
+        for val in self.params.tab_pos_div_to_side:
+            tab_data = (val, width_tab, depth_tab, '+')
+            tab_data_xz_pos.append(tab_data)
+            tab_data_xz_neg.append(tab_data)
+
+        tab_data_yz_pos = []
+        tab_data_yz_neg = []
+        width_tab = self.params.width_tab_normal
+        depth_tab_pos = self.params.thickness_top_inner + self.params.thickness_top_outer
+        depth_tab_neg = self.params.thickness_bot_inner + self.params.thickness_bot_outer
+        for val in self.params.tab_pos_div_to_topbot:
+            tab_data_pos = (val, width_tab, depth_tab_pos, '+')
+            tab_data_neg = (val, width_tab, depth_tab_neg, '+')
+            tab_data_yz_pos.append(tab_data_pos)
+            tab_data_yz_neg.append(tab_data_neg)
+
+        params = {
+                'size': (x_div, y_div, z_div),
+                'xz+': tab_data_xz_pos,
+                'xz-': tab_data_xz_neg,
+                'yz+': tab_data_yz_pos,
+                'yz-': tab_data_yz_neg,
+                }
+        self.divider_transtabs = Plate_W_Tabs(params).make()
+        side_size = (x_div, y_div, self.params.thickness_divider_transtabs_side)
+        self.divider_transtabs_side = Cube(size=side_size)
+
+
+    def add_holes(self, hole_list, cut_depth = None):
+        """
+        Add holes to given panel of the enclosure.
+        """
+        if not cut_depth:
+            thickness_list = []
+            for name in dir(self.params):
+                if 'thickness' in name:
+                    value = getattr(self.params,name)
+                    thickness_list.append(value)
+            cut_depth = 2*max(thickness_list)
+
+        for hole in hole_list:
+            # Create differencing cylinder for hole based on hole type.
+            if hole['type'] == 'round':
+                radius = 0.5*hole['size']
+                hole_cyl = Cylinder(r1=radius, r2=radius, h=cut_depth)
+            elif hole['type'] == 'square':
+                sz_x, sz_y = hole['size']
+                sz_z = cut_depth 
+                hole_cyl = Cube(size = (sz_x,sz_y,sz_z))
+            elif hole['type'] == 'rounded_square':
+                sz_x, sz_y, radius = hole['size']
+                sz_z = cut_depth 
+                hole_cyl = rounded_box(sz_x, sz_y, sz_z, radius, round_z=False)
+            else:
+                raise ValueError, 'unkown hole type {0}'.format(hole['type'])
+
+            # Translate cylinder into position
+            x,y = hole['location']
+            hole_cyl = Translate(hole_cyl, v = (x,y,0.0))
+
+            # Get panel in which to make hole
+            panel = getattr(self, hole['panel'])
+
+            # Cut hole
+            panel = Difference([panel, hole_cyl])
+            setattr(self, hole['panel'], panel)
+
+
+    def get_slot_pos_list(self,name):
+        """
+        Get lists of x,y position for tabs given their names. Note, coordinates
+        are for the unrotated parts - not the assembled parts.
+        """
+        slot_pos_list = []
+        if name == 'side_to_topbot':
+            for val in self.params.tab_pos_side_to_topbot:
+                for j in (-1,1):
+                    x_slot = (0.5 - val)*self.params.x_inner
+                    y_slot = j*(0.5*self.params.y_inner + 0.5*self.params.thickness_side)
+                    slot_pos_list.append((x_slot,y_slot))
+        elif name == 'div_to_topbot':
+            for val in self.params.tab_pos_div_to_topbot:
+                x_slot = 0.0
+                y_slot = (0.5 - val)*self.params.y_inner
+                slot_pos_list.append((x_slot,y_slot))
+        elif name == 'div_to_side':
+            for val in self.params.tab_pos_div_to_side:
+                x_slot = 0.0
+                y_slot = (0.5 - val)*self.params.z_inner
+                slot_pos_list.append((x_slot,y_slot))
+        else:
+            raise ValueError, 'unknown tab type {0}'.format(name)
+        return slot_pos_list
+        
+
+    def get_assembly(self,**kwargs):
+        part_dict = {} 
+        options = {}
+        try:
+            explode = kwargs['explode']
+        except KeyError:
+            explode = 0,0,0
+        try:
+            output_type = kwargs['output_type']
+        except KeyError:
+            output_type = 'list'
+        assert output_type in ('list','dict')
+
+        x_explode, y_explode, z_explode = explode
+
+        # Add top and bottoms (inner and outer)
+        vz = 0.5*self.params.z_inner + 0.5*self.params.thickness_top_inner
+        vz += z_explode
+        top_inner = Translate(self.top_inner,v=(0,0,vz))
+        part_dict['top_inner'] = top_inner
+        options['show_top_inner'] = True
+
+        vz = 0.5*self.params.z_inner + self.params.thickness_top_inner
+        vz += 0.5*self.params.thickness_top_outer
+        vz += 2.0*z_explode
+        top_outer = Translate(self.top_outer,v=(0,0,vz))
+        part_dict['top_outer'] = top_outer
+        options['show_top_outer'] = True
+        
+        vz = -(0.5*self.params.z_inner + 0.5*self.params.thickness_bot_inner)
+        vz -= z_explode
+        bot_inner = Translate(self.bot_inner,v=(0,0,vz))
+        part_dict['bot_inner'] = bot_inner
+        options['show_bot_inner'] = True
+
+        vz = -(0.5*self.params.z_inner + self.params.thickness_bot_inner)
+        vz -= 0.5*self.params.thickness_bot_outer
+        vz -= 2.0*z_explode
+
+        bot_outer = Translate(self.bot_outer,v=(0,0,vz))
+        part_dict['bot_outer'] = bot_outer
+        options['show_bot_outer'] = True
+
+        # Add standoffs
+        standoff_list = []
+        for hole in self.hole_list_standoff:
+            x_standoff, y_standoff = hole['location']
+            x_standoff += 2*sign(x_standoff)*x_explode
+            y_standoff += 2*sign(y_standoff)*y_explode
+            standoff = Translate(self.standoff,v=(x_standoff, y_standoff, 0))
+            standoff_list.append(standoff)
+        part_dict['standoff'] = standoff_list
+        options['show_standoff'] = True
+
+        # Add doors
+        try:
+            door_open = kwargs['door_open']
+        except KeyError:
+            door_open = False 
+        door = Rotate(self.door,a=90, v=(0,1,0))
+        vx = 0.5*self.params.x_inner + 0.5*self.params.thickness_door
+        vx += x_explode
+        vy = 0.5*self.y_door - 0.5*self.y_outer
+        vy += 2*self.params.space_standoff + self.params.diam_standoff
+
+        if door_open:
+            vy += self.y_door
+
+        door_pos = Translate(door,v=(vx,vy,0))
+        door_neg = Translate(door,v=(-vx,vy,0))
+        part_dict['door_pos'] = door_pos
+        part_dict['door_neg'] = door_neg
+        options['show_door_pos'] = True
+        options['show_door_neg'] = True
+
+        # Add sides
+        side = Rotate(self.side,a=90,v=(1,0,0))
+        vy = 0.5*self.params.y_inner + 0.5*self.params.thickness_side
+        vy += y_explode
+        side_pos = Translate(side,v=(0,vy,0))
+        side_neg = Translate(side,v=(0,-vy,0))
+        part_dict['side_pos'] = side_pos
+        part_dict['side_neg'] = side_neg
+        options['show_side_pos'] = True
+        options['show_side_neg'] = True
+
+        # Add divider
+        divider = Rotate(self.divider,a=90,v=(0,1,0))
+        part_dict['divider'] = divider
+        options['show_divider'] = True
+
+        # Generate output list
+        output_list = []
+        output_dict = {}
+        options.update(kwargs)
+        for name, part in part_dict.iteritems():
+            if options['show_{0}'.format(name)]:
+                if type(part) is list:
+                    output_list.extend(part)
+                else:
+                    output_list.append(part)
+                output_dict[name] = part
+        if output_type == 'list':
+            return output_list 
+        else:
+            return output_dict
+
+    def get_transtabs_assembly(self, **kwargs):
+        part_dict = {} 
+        options = {}
+        try:
+            explode = kwargs['explode']
+        except KeyError:
+            explode = 0,0,0
+        try:
+            output_type = kwargs['output_type']
+        except KeyError:
+            output_type = 'list'
+        assert output_type in ('list','dict')
+
+        x_explode, y_explode, z_explode = explode
+        # Add divider
+        divider_transtabs = Rotate(self.divider_transtabs,a=90,v=(0,1,0))
+        part_dict['divider_transtabs'] = divider_transtabs
+        options['show_divider_transtabs'] = True
+
+        # Add divider sides
+        divider_transtabs_side = Rotate(self.divider_transtabs_side,a=90,v=(0,1,0))
+        vx = 0.5*self.params.thickness_divider_transtabs
+        vx += 0.5*self.params.thickness_divider_transtabs_side
+        vx += x_explode
+        divider_transtabs_side_pos = Translate(divider_transtabs_side,v=(vx,0,0))
+        divider_transtabs_side_neg = Translate(divider_transtabs_side,v=(-vx,0,0))
+        part_dict['transtabs_side_pos'] = divider_transtabs_side_pos
+        part_dict['transtabs_side_neg'] = divider_transtabs_side_neg
+        options['show_transtabs_side_pos'] = True
+        options['show_transtabs_side_neg'] = True
+
+        # Generate output list
+        output_list = []
+        output_dict = {}
+        options.update(kwargs)
+        for name, part in part_dict.iteritems():
+            if options['show_{0}'.format(name)]:
+                if type(part) is list:
+                    output_list.extend(part)
+                else:
+                    output_list.append(part)
+                output_dict[name] = part
+        if output_type == 'list':
+            return output_list 
+        else:
+            return output_dict
+
+    def write_proj_scad(self):
+        """
+        Write the project scad files
+        """
+        part_names = [
+                'top_outer',
+                'top_inner',
+                'bot_outer',
+                'bot_inner',
+                'door', 
+                'side',
+                'divider',
+                ]
+        scad_file_list = []
+        for name in part_names:
+            scad_name = '{0}.{1}'.format(name,'scad')
+            part = getattr(self,name)
+            part_proj = Projection(part)
+            prog = SCAD_Prog()
+            prog.fn = self.params.projection_fn
+            prog.add(part_proj)
+            prog.write(scad_name)
+            scad_file_list.append(scad_name)
+        return scad_file_list
+
+    def write_dxf(self,erase_scad=True):
+        scad_file_list = self.write_proj_scad()
+        for scad_name in scad_file_list:
+            base_name, ext = os.path.splitext(scad_name)
+            dxf_name = '{0}.{1}'.format(base_name,'dxf')
+            print('writing: {0}'.format(dxf_name))
+            subprocess.call(['openscad','-x',dxf_name,scad_name])
+            if erase_scad:
+                os.remove(scad_name)
+
+    def write_assembly_scad(self,filename,**kwargs):
+        try:
+            assembly_method = kwargs['assembly_method']
+        except KeyError:
+            assembly_method = self.get_assembly
+        box_assembly = assembly_method(**kwargs)
+        prog_assembly = SCAD_Prog()
+        prog_assembly.fn = 50
+        prog_assembly.add(box_assembly)
+        prog_assembly.write(filename)
+
+
+    def write_assembly_stl(self,**kwargs):
+        kwargs['output_type'] = 'dict'
+        try:
+            erase_scad = kwargs['erase_scad']
+        except KeyError:
+            erase_scad = True
+        try:
+            vconfig_only = kwargs['vconfig_only']
+        except KeyError:
+            vconfig_only = False
+        try:
+            assembly_method = kwargs['assembly_method']
+            vconfig_filename = kwargs['vconfig_filename']
+        except KeyError:
+            assembly_method = self.get_assembly
+            vconfig_filename = 'flybox_assembly_vconfig.pkl'
+        part_dict = assembly_method(**kwargs)
+        vconfig_dict = {}
+        vconfig_dict['background'] = self.params.vconfig_color_background
+        vconfig_dict['size'] = self.params.vconfig_size
+        vconfig_part_list = []
+        for name, part in part_dict.iteritems():
+            if type(part) is list:
+                for i, subpart in enumerate(part):
+                    subname = '{0}_{1}'.format(name,i)
+                    vconfig_part = self.write_stl(
+                            subname, 
+                            subpart, 
+                            erase_scad=erase_scad, 
+                            vconfig_only=vconfig_only,
+                            )
+                    vconfig_part_list.append(vconfig_part)
+            else:
+                vconfig_part = self.write_stl(
+                        name, 
+                        part, 
+                        erase_scad=erase_scad,
+                        vconfig_only=vconfig_only,
+                        )
+                vconfig_part_list.append(vconfig_part)
+        vconfig_dict['objects'] = vconfig_part_list
+        with open(vconfig_filename,'w') as f:
+            pickle.dump(vconfig_dict, f)
+
+
+    def write_stl(self, name, part, erase_scad=True, vconfig_only=False):
+        scad_filename = '{0}.scad'.format(name)
+        stl_filename = '{0}.stl'.format(name)
+        print('{0} --> {1}'.format(scad_filename, stl_filename))
+        prog = SCAD_Prog()
+        prog.fn = self.params.stl_fn
+        prog.add(part)
+        prog.write(scad_filename)
+        if not vconfig_only:
+            subprocess.call(['openscad', '-s', stl_filename, scad_filename])
+        if erase_scad==True:
+            os.remove(scad_filename)
+        rgba_color = self.get_vconfig_color(name)
+        vconfig = self.get_part_vconfig(stl_filename,rgba_color)
+        return vconfig
+
+ 
+    def get_part_vconfig(self, filename, rgba_color):
+        color = rgba_color[:3]
+        opacity = rgba_color[3]
+        parameters = {
+                'specular_power' : 0.8,
+                'specular'       : 0.7,
+                'diffuse'        : 0.7, 
+                'color'          : color,
+                'opacity'        : opacity, 
+                } 
+        vconfig = {'filename' : filename, 'parameters' : parameters}
+        return vconfig 
+
+    def get_vconfig_color(self,name):
+        for color_name in self.vconfig_color_dict:
+            if color_name in name:
+                print(color_name, name)
+                return self.vconfig_color_dict[color_name]
+
+    def make_vconfig_color_dict(self):
+        self.vconfig_color_dict = {}
+        for name in dir(self.params):
+            if 'vconfig_color' in name:
+                color_name = name[len('vconfig_color_'):]
+                self.vconfig_color_dict[color_name] = getattr(self.params,name) 
+
+
+
+def sign(x):
+    if x > 0:
+        return 1
+    elif x < 0:
+        return -1
+    else:
+        return 0
+
+# -----------------------------------------------------------------------------
+if __name__ == '__main__':
+
+    # Testing and development
+
+    import flybox_params as params
+    box = FlyBoxTwoChamber(params)
+
+    if 0:
+        assembly_options = {
+                'explode': (0,0,5),
+                'show_top_outer': False,
+                'show_top_inner': False, 
+                'show_bot_outer': True,
+                'show_bot_inner': True,
+                'show_door_pos': True,
+                'show_door_neg': True,
+                'show_side_pos': True,
+                'show_side_neg': True,
+                'show_divider': True,
+                'show_standoff': True,
+                'door_open': True,
+                'vconfig_only': True,
+                }
+        box.write_assembly_scad('flybox_assembly.scad', **assembly_options)
+        box.write_assembly_stl(**assembly_options)
+
+    # Show transparent tabs
+    if 0:
+        assembly_options = {
+                'assembly_method': box.get_transtabs_assembly,
+                'vconfig_filename': 'transtabs_vconfig.pkl',
+                'explode': (0,0,0),
+                'vconfig_only': False,
+                }
+        box.write_assembly_scad('transtabs_assembly.scad',**assembly_options)
+        box.write_assembly_stl(**assembly_options)
+
+    #box.write_proj_scad()
+    #box.write_dxf()
+
+

laser_cutting/orders/order_08_20_2012/clear_1p5mm.svg

+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="1057.5"
+   height="1057.5"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="New document 1">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective10" />
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       id="perspective4106" />
+    <marker
+       refY="0"
+       refX="0"
+       style="overflow:visible"
+       id="DistanceX-0"
+       orient="auto">
+      <path
+         style="stroke:#000000;stroke-width:0.5"
+         d="M 3,-3 -3,3 M 0,-5 0,5"
+         id="path3295" />
+    </marker>
+    <symbol
+       id="*Model_Space-6" />
+    <symbol
+       id="*Paper_Space-7" />
+    <symbol
+       id="*Paper_Space0-4" />
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       id="perspective3055" />
+    <marker
+       refY="0"
+       refX="0"
+       style="overflow:visible"
+       id="DistanceX"
+       orient="auto">
+      <path
+         style="stroke:#000000;stroke-width:0.5"
+         d="M 3,-3 -3,3 M 0,-5 0,5"
+         id="path2844" />
+    </marker>
+    <symbol
+       id="*Model_Space" />
+    <symbol
+       id="*Paper_Space" />
+    <symbol
+       id="*Paper_Space0" />
+    <inkscape:perspective
+       id="perspective10-0"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       id="perspective4651" />
+    <marker
+       refY="0"
+       refX="0"
+       style="overflow:visible"
+       id="DistanceX-8"
+       orient="auto">
+      <path
+         style="stroke:#000000;stroke-width:0.5"
+         d="M 3,-3 -3,3 M 0,-5 0,5"
+         id="path3840-8" />
+    </marker>
+    <symbol
+       id="*Model_Space-1" />
+    <symbol
+       id="*Paper_Space-8" />
+    <symbol
+       id="*Paper_Space0-6" />
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       id="perspective3711" />
+    <marker
+       refY="0"
+       refX="0"
+       style="overflow:visible"
+       id="DistanceX-0-7"
+       orient="auto">
+      <path
+         style="stroke:#000000;stroke-width:0.5"
+         d="M 3,-3 -3,3 M 0,-5 0,5"
+         id="path3516-2" />
+    </marker>
+    <symbol
+       id="*Model_Space-8" />
+    <symbol
+       id="*Paper_Space-9" />
+    <symbol
+       id="*Paper_Space0-7" />
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       id="perspective3379" />
+    <marker
+       refY="0"
+       refX="0"
+       style="overflow:visible"
+       id="DistanceX-2"
+       orient="auto">
+      <path
+         style="stroke:#000000;stroke-width:0.5"
+         d="M 3,-3 -3,3 M 0,-5 0,5"
+         id="path3168" />
+    </marker>
+    <symbol
+       id="*Model_Space-0" />
+    <symbol
+       id="*Paper_Space-2" />
+    <symbol
+       id="*Paper_Space0-9" />
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       id="perspective3039" />
+    <marker
+       refY="0"
+       refX="0"
+       style="overflow:visible"
+       id="DistanceX-6"
+       orient="auto">
+      <path
+         style="stroke:#000000;stroke-width:0.5"
+         d="M 3,-3 -3,3 M 0,-5 0,5"
+         id="path2844-8" />
+    </marker>
+    <symbol
+       id="*Model_Space-9" />
+    <symbol
+       id="*Paper_Space-5" />
+    <symbol
+       id="*Paper_Space0-8" />
+    <inkscape:perspective
+       id="perspective10-1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.49497475"
+     inkscape:cx="1161.9319"
+     inkscape:cy="425.32261"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     units="in"
+     borderlayer="true"
+     inkscape:window-width="1680"
+     inkscape:window-height="975"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,5.14025)">
+    <g
+       id="g3164"
+       transform="translate(-563.61523,123.27644)">
+      <g
+         transform="translate(794.28571,-308.57143)"
+         inkscape:label="0"
+         id="g2849">
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -216.14173,1213.5827 0,-322.44097"
+           id="path2851" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -216.14173,891.14173 0.085,-1.33228"
+           id="path2853" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -216.05669,889.80945 0.24803,-1.31103"
+           id="path2855" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -215.80866,888.49842 0.41457,-1.2685"
+           id="path2857" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -215.39409,887.22992 0.56693,-1.20827"
+           id="path2859" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -214.82716,886.02165 0.71574,-1.12677"
+           id="path2861" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -214.11142,884.89488 0.8504,-1.0311"
+           id="path2863" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -213.26102,883.86378 0.97441,-0.91417"
+           id="path2865" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -212.28661,882.94961 1.0807,-0.78308"
+           id="path2867" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -211.20591,882.16653 1.1693,-0.64133"
+           id="path2869" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -210.03661,881.5252 1.24015,-0.49252"
+           id="path2871" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -208.79646,881.03268 1.29331,-0.33307"
+           id="path2873" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -207.50315,880.69961 1.3252,-0.16654"
+           id="path2875" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -206.17795,880.53307 0.66614,0"
+           id="path2877" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -205.51181,880.53307 0,-0.0213"
+           id="path2879" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -205.51181,880.51181 17.71653,0"
+           id="path2881" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -187.79528,880.51181 0,315.35429"
+           id="path2883" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -187.79528,1195.8661 10.62993,0"
+           id="path2885" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -177.16535,1195.8661 0,-315.35429"
+           id="path2887" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -177.16535,880.51181 354.3307,0"
+           id="path2889" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 177.16535,880.51181 0,315.35429"
+           id="path2891" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 177.16535,1195.8661 10.62993,0"
+           id="path2893" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 187.79528,1195.8661 0,-315.35429"
+           id="path2895" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 187.79528,880.51181 17.71653,0"
+           id="path2897" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 205.51181,880.51181 0,0.0213"
+           id="path2899" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 205.51181,880.53307 0.66614,0"
+           id="path2901" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 206.17795,880.53307 1.3252,0.16654"
+           id="path2903" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 207.50315,880.69961 1.29331,0.33307"
+           id="path2905" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 208.79646,881.03268 1.24015,0.49252"
+           id="path2907" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 210.03661,881.5252 1.1693,0.64133"
+           id="path2909" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 211.20591,882.16653 1.0807,0.78308"
+           id="path2911" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 212.28661,882.94961 0.97441,0.91417"
+           id="path2913" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 213.26102,883.86378 0.8504,1.0311"
+           id="path2915" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 214.11142,884.89488 0.71574,1.12677"
+           id="path2917" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 214.82716,886.02165 0.56693,1.20827"
+           id="path2919" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 215.39409,887.22992 0.41457,1.2685"
+           id="path2921" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 215.80866,888.49842 0.24803,1.31103"
+           id="path2923" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 216.05669,889.80945 0.085,1.33228"
+           id="path2925" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 216.14173,891.14173 0,322.44097"
+           id="path2927" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 216.14173,1213.5827 -0.085,1.3323"
+           id="path2929" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 216.05669,1214.915 -0.24803,1.311"
+           id="path2931" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 215.80866,1216.226 -0.41457,1.2685"
+           id="path2933" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 215.39409,1217.4945 -0.56693,1.2083"
+           id="path2935" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 214.82716,1218.7028 -0.71574,1.1267"
+           id="path2937" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 214.11142,1219.8295 -0.8504,1.0311"
+           id="path2939" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 213.26102,1220.8606 -0.97441,0.9142"
+           id="path2941" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 212.28661,1221.7748 -1.0807,0.7831"
+           id="path2943" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 211.20591,1222.5579 -1.1693,0.6413"
+           id="path2945" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 210.03661,1223.1992 -1.24015,0.4925"
+           id="path2947" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 208.79646,1223.6917 -1.29331,0.3331"
+           id="path2949" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 207.50315,1224.0248 -1.3252,0.1665"
+           id="path2951" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 206.17795,1224.1913 -0.66614,0"
+           id="path2953" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 205.51181,1224.1913 0,0.021"
+           id="path2955" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 205.51181,1224.2126 -411.02362,0"
+           id="path2957" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -205.51181,1224.2126 0,-0.021"
+           id="path2959" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -205.51181,1224.1913 -0.66614,0"
+           id="path2961" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -206.17795,1224.1913 -1.3252,-0.1665"
+           id="path2963" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -207.50315,1224.0248 -1.29331,-0.3331"
+           id="path2965" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -208.79646,1223.6917 -1.24015,-0.4925"
+           id="path2967" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -210.03661,1223.1992 -1.1693,-0.6413"
+           id="path2969" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -211.20591,1222.5579 -1.0807,-0.7831"
+           id="path2971" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -212.28661,1221.7748 -0.97441,-0.9142"
+           id="path2973" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -213.26102,1220.8606 -0.8504,-1.0311"
+           id="path2975" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -214.11142,1219.8295 -0.71574,-1.1267"
+           id="path2977" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -214.82716,1218.7028 -0.56693,-1.2083"
+           id="path2979" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -215.39409,1217.4945 -0.41457,-1.2685"
+           id="path2981" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -215.80866,1216.226 -0.24803,-1.311"
+           id="path2983" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -216.05669,1214.915 -0.085,-1.3323"
+           id="path2985" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -159.44882,1195.8661 0,-10.6299"
+           id="path2987" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -159.44882,1185.2362 35.43307,0"
+           id="path2989" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -124.01575,1185.2362 0,10.6299"
+           id="path2991" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -124.01575,1195.8661 -35.43307,0"
+           id="path2993" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -159.44882,919.48819 0,-10.62992"
+           id="path2995" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -159.44882,908.85827 35.43307,0"
+           id="path2997" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -124.01575,908.85827 0,10.62992"
+           id="path2999" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -124.01575,919.48819 -35.43307,0"
+           id="path3001" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -17.716535,1195.8661 0,-10.6299"
+           id="path3003" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -17.716535,1185.2362 35.43307,0"
+           id="path3005" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 17.716535,1185.2362 0,10.6299"
+           id="path3007" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 17.716535,1195.8661 -35.43307,0"
+           id="path3009" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -17.716535,919.48819 0,-10.62992"
+           id="path3011" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -17.716535,908.85827 35.43307,0"
+           id="path3013" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 17.716535,908.85827 0,10.62992"
+           id="path3015" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 17.716535,919.48819 -35.43307,0"
+           id="path3017" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -5.314961,1136.5157 0,-35.433"
+           id="path3019" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -5.314961,1101.0827 10.629922,0"
+           id="path3021" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 5.314961,1101.0827 0,35.433"
+           id="path3023" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 5.314961,1136.5157 -10.629922,0"
+           id="path3025" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -5.314961,1003.6417 0,-35.43304"
+           id="path3027" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -5.314961,968.20866 10.629922,0"
+           id="path3029" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 5.314961,968.20866 0,35.43304"
+           id="path3031" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 5.314961,1003.6417 -10.629922,0"
+           id="path3033" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 124.01575,1195.8661 0,-10.6299"
+           id="path3035" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 124.01575,1185.2362 35.43307,0"
+           id="path3037" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 159.44882,1185.2362 0,10.6299"
+           id="path3039" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 159.44882,1195.8661 -35.43307,0"
+           id="path3041" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 124.01575,919.48819 0,-10.62992"
+           id="path3043" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 124.01575,908.85827 35.43307,0"
+           id="path3045" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 159.44882,908.85827 0,10.62992"
+           id="path3047" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 159.44882,919.48819 -35.43307,0"
+           id="path3049" />
+      </g>
+    </g>
+    <g
+       id="g4515"
+       transform="translate(604.74889,669.25748)">
+      <g
+         transform="translate(88.571429,-851.42857)"
+         inkscape:label="0"
+         id="g3300">
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -216.14173,1213.5827 0,-322.44097"
+           id="path3302" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -216.14173,891.14173 0.085,-1.33228"
+           id="path3304" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -216.05669,889.80945 0.24803,-1.31103"
+           id="path3306" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -215.80866,888.49842 0.41457,-1.2685"
+           id="path3308" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -215.39409,887.22992 0.56693,-1.20827"
+           id="path3310" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -214.82716,886.02165 0.71574,-1.12677"
+           id="path3312" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -214.11142,884.89488 0.8504,-1.0311"
+           id="path3314" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -213.26102,883.86378 0.97441,-0.91417"
+           id="path3316" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -212.28661,882.94961 1.0807,-0.78308"
+           id="path3318" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -211.20591,882.16653 1.1693,-0.64133"
+           id="path3320" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -210.03661,881.5252 1.24015,-0.49252"
+           id="path3322" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -208.79646,881.03268 1.29331,-0.33307"
+           id="path3324" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -207.50315,880.69961 1.3252,-0.16654"
+           id="path3326" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -206.17795,880.53307 0.66614,0"
+           id="path3328" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -205.51181,880.53307 0,-0.0213"
+           id="path3330" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -205.51181,880.51181 17.71653,0"
+           id="path3332" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -187.79528,880.51181 0,315.35429"
+           id="path3334" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -187.79528,1195.8661 10.62993,0"
+           id="path3336" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -177.16535,1195.8661 0,-315.35429"
+           id="path3338" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -177.16535,880.51181 354.3307,0"
+           id="path3340" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 177.16535,880.51181 0,315.35429"
+           id="path3342" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 177.16535,1195.8661 10.62993,0"
+           id="path3344" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 187.79528,1195.8661 0,-315.35429"
+           id="path3346" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 187.79528,880.51181 17.71653,0"
+           id="path3348" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 205.51181,880.51181 0,0.0213"
+           id="path3350" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 205.51181,880.53307 0.66614,0"
+           id="path3352" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 206.17795,880.53307 1.3252,0.16654"
+           id="path3354" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 207.50315,880.69961 1.29331,0.33307"
+           id="path3356" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 208.79646,881.03268 1.24015,0.49252"
+           id="path3358" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 210.03661,881.5252 1.1693,0.64133"
+           id="path3360" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 211.20591,882.16653 1.0807,0.78308"
+           id="path3362" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 212.28661,882.94961 0.97441,0.91417"
+           id="path3364" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 213.26102,883.86378 0.8504,1.0311"
+           id="path3366" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 214.11142,884.89488 0.71574,1.12677"
+           id="path3368" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 214.82716,886.02165 0.56693,1.20827"
+           id="path3370" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 215.39409,887.22992 0.41457,1.2685"
+           id="path3372" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 215.80866,888.49842 0.24803,1.31103"
+           id="path3374" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 216.05669,889.80945 0.085,1.33228"
+           id="path3376" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 216.14173,891.14173 0,322.44097"
+           id="path3378" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 216.14173,1213.5827 -0.085,1.3323"
+           id="path3380" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 216.05669,1214.915 -0.24803,1.311"
+           id="path3382" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 215.80866,1216.226 -0.41457,1.2685"
+           id="path3384" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 215.39409,1217.4945 -0.56693,1.2083"
+           id="path3386" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 214.82716,1218.7028 -0.71574,1.1267"
+           id="path3388" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 214.11142,1219.8295 -0.8504,1.0311"
+           id="path3390" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 213.26102,1220.8606 -0.97441,0.9142"
+           id="path3392" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 212.28661,1221.7748 -1.0807,0.7831"
+           id="path3394" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 211.20591,1222.5579 -1.1693,0.6413"
+           id="path3396" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 210.03661,1223.1992 -1.24015,0.4925"
+           id="path3398" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 208.79646,1223.6917 -1.29331,0.3331"
+           id="path3400" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 207.50315,1224.0248 -1.3252,0.1665"
+           id="path3402" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 206.17795,1224.1913 -0.66614,0"
+           id="path3404" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 205.51181,1224.1913 0,0.021"
+           id="path3406" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 205.51181,1224.2126 -411.02362,0"
+           id="path3408" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -205.51181,1224.2126 0,-0.021"
+           id="path3410" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -205.51181,1224.1913 -0.66614,0"
+           id="path3412" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -206.17795,1224.1913 -1.3252,-0.1665"
+           id="path3414" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -207.50315,1224.0248 -1.29331,-0.3331"
+           id="path3416" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -208.79646,1223.6917 -1.24015,-0.4925"
+           id="path3418" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -210.03661,1223.1992 -1.1693,-0.6413"
+           id="path3420" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -211.20591,1222.5579 -1.0807,-0.7831"
+           id="path3422" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -212.28661,1221.7748 -0.97441,-0.9142"
+           id="path3424" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -213.26102,1220.8606 -0.8504,-1.0311"
+           id="path3426" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -214.11142,1219.8295 -0.71574,-1.1267"
+           id="path3428" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -214.82716,1218.7028 -0.56693,-1.2083"
+           id="path3430" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -215.39409,1217.4945 -0.41457,-1.2685"
+           id="path3432" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -215.80866,1216.226 -0.24803,-1.311"
+           id="path3434" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -216.05669,1214.915 -0.085,-1.3323"
+           id="path3436" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -207.99213,1210.0394 0.0461,-0.7548"
+           id="path3438" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -207.94606,1209.2846 0.14173,-0.744"
+           id="path3440" />
+        <path
+           style="fill:none;stroke:#000000"
+           d="m -207.80433,1208.5406 0.23386,-0.7193"
+           id="path3442" />
+        <path
+           style="fill:none;stroke:#000000"