chiark / gitweb /
Add instant slicing.
authordaid303 <daid303@gmail.com>
Thu, 28 Mar 2013 11:01:36 +0000 (12:01 +0100)
committerdaid303 <daid303@gmail.com>
Thu, 28 Mar 2013 11:01:36 +0000 (12:01 +0100)
216 files changed:
Cura/gui/flatSlicerWindow.py [deleted file]
Cura/gui/mainWindow.py
Cura/gui/sceneView.py
Cura/gui/util/openglGui.py
Cura/slice/__init__.py [deleted file]
Cura/slice/__main__.py [deleted file]
Cura/slice/cura_sf/SkeinforgeVersion [deleted file]
Cura/slice/cura_sf/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/archive.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/euclidean.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/fabmetheus_interpret.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/amf.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/csv.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/dae.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/gts.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/obj.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/slc.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/stl.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/svg.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/gcodec.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/_drill.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/_svg.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/circle.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/concatenate.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/extrude.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/gear.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/grid.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/heightmap.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/lathe.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/line.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/linear_bearing_cage.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/lineation.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/mechaslab.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/peg.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/polygon.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/shaft.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/solid.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/sponge_slice.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/square.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/teardrop.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/text.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/dictionary.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/face.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/path.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/path_elements/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/path_elements/arc.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/path_elements/cubic.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/path_elements/quadratic.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/vertex.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/boolean_geometry.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/boolean_solid.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/creation.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/document.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/setting.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables/dictionary_attribute.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables/list_attribute.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables/string_attribute.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/_math.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/euclid.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/measure.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/print.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/example.csv [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/matrix.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_matrix/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_matrix/_scale.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_matrix/rotate.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_matrix/transform.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_matrix/translate.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/_array.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/_carve.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/_copy.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/disjoin.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/import.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/write.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/bevel.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/convex.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/outline.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/overhang.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/round.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/segment.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/wedge.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/_bottom.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/_inset.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/_outset.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/equation.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/flip.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/mirror.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/cube.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/cylinder.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/difference.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/group.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/intersection.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/sphere.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/triangle_mesh.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/union.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/_print.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/class.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/elif.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/else.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/for.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/function.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/if.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/return.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/statement.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/while.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry_plugins/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry_plugins/creation/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry_plugins/manipulation_matrix/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry_plugins/manipulation_meta/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry_plugins/manipulation_paths/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/geometry_plugins/manipulation_shapes/__init__.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/intercircle.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/settings.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/svg_reader.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/svg_writer.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/templates/canvas_template.svg [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/templates/layer_template.svg [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/vector3.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/vector3index.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/version.txt [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/xml_simple_reader.py [deleted file]
Cura/slice/cura_sf/fabmetheus_utilities/xml_simple_writer.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/__init__.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/__init__.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/analyze.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/analyze_plugins/__init__.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/__init__.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/alteration.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/bottom.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/carve.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/chamber.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/chop.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/cleave.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/clip.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/coil.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/comb.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/cool.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/dimension.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/drill.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/dwindle.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/__init__.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/binary_16_byte.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/gcode_step.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/gcode_time_segment.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/static_plugins/__init__.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/static_plugins/gcode_small.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/feed.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/fill.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/fillet.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/flow.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/home.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/hop.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/inset.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/jitter.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/joris.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/lash.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/lift.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/limit.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/mill.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/multiply.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/oozebane.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/outset.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/preface.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/raft.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/scale.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/skin.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/skirt.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/smooth.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/speed.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/splodge.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/stretch.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/temperature.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/tower.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/unpause.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/whittle.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/widen.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/wipe.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/help.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/meta.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/meta_plugins/__init__.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/meta_plugins/description.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/meta_plugins/polyfile.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/profile.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/profile_plugins/__init__.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/profile_plugins/cutting.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/profile_plugins/extrusion.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/profile_plugins/milling.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/profile_plugins/winding.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/__init__.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/skeinforge_analyze.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/skeinforge_craft.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/skeinforge_help.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/skeinforge_meta.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/skeinforge_polyfile.py [deleted file]
Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/skeinforge_profile.py [deleted file]
Cura/util/objectScene.py
Cura/util/profile.py
Cura/util/sliceEngine.py [new file with mode: 0644]

diff --git a/Cura/gui/flatSlicerWindow.py b/Cura/gui/flatSlicerWindow.py
deleted file mode 100644 (file)
index b24f587..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-from __future__ import absolute_import
-
-import wx
-import os
-
-from wx import glcanvas
-
-import OpenGL
-OpenGL.ERROR_CHECKING = False
-from OpenGL.GLU import *
-from OpenGL.GL import *
-
-from Cura.gui.util import toolbarUtil
-from Cura.gui.util import opengl
-from Cura.util import util3d
-from Cura.util import svg
-from Cura.util import profile
-from Cura.util import version
-
-class flatSlicerWindow(wx.Frame):
-       "Cura 2D SVG slicer"
-       def __init__(self):
-               super(flatSlicerWindow, self).__init__(None, title='Cura - ' + version.getVersion())
-
-               self.machineSize = util3d.Vector3(profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height'))
-               self.filename = None
-               self.svg = None
-
-               wx.EVT_CLOSE(self, self.OnClose)
-               self.panel = wx.Panel(self, -1)
-               self.SetSizer(wx.BoxSizer(wx.VERTICAL))
-               self.GetSizer().Add(self.panel, 1, flag=wx.EXPAND)
-
-               self.toolbar = toolbarUtil.Toolbar(self.panel)
-
-               toolbarUtil.NormalButton(self.toolbar, self.OnOpenSVG, 'open.png', 'Open SVG')
-               self.toolbar.AddSeparator()
-               group = []
-               toolbarUtil.RadioButton(self.toolbar, group, 'object-3d-on.png', 'object-3d-off.png', '3D view', callback=self.On3DClick)
-               toolbarUtil.RadioButton(self.toolbar, group, 'object-top-on.png', 'object-top-off.png', 'Topdown view', callback=self.OnTopClick).SetValue(True)
-               self.toolbar.AddSeparator()
-               toolbarUtil.NormalButton(self.toolbar, self.OnQuit, 'exit.png', 'Close project planner')
-               
-               self.toolbar.Realize()
-               
-               sizer = wx.GridBagSizer(2,2)
-               self.panel.SetSizer(sizer)
-               self.preview = PreviewGLCanvas(self.panel, self)
-
-               sizer.Add(self.toolbar, (0,0), span=(1,1), flag=wx.EXPAND|wx.LEFT|wx.RIGHT)
-               sizer.Add(self.preview, (1,0), span=(5,1), flag=wx.EXPAND)
-
-               sizer.AddGrowableCol(0)
-               sizer.AddGrowableRow(1)
-
-               self.SetSize((600,400))
-
-       def OnClose(self, e):
-               self.Destroy()
-
-       def OnQuit(self, e):
-               self.Close()
-
-       def On3DClick(self):
-               self.preview.yaw = 30
-               self.preview.pitch = 60
-               self.preview.zoom = 300
-               self.preview.view3D = True
-               self.preview.Refresh()
-
-       def OnTopClick(self):
-               self.preview.view3D = False
-               self.preview.zoom = self.machineSize.x / 2 + 10
-               self.preview.offsetX = 0
-               self.preview.offsetY = 0
-               self.preview.Refresh()
-
-       def OnOpenSVG(self, e):
-               dlg=wx.FileDialog(self, "Open SVG file", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
-               dlg.SetWildcard("SVG files (*.svg)|*.svg;*.SVG")
-               if dlg.ShowModal() == wx.ID_OK:
-                       self.filename = dlg.GetPath()
-                       self.svg = svg.SVG(self.filename)
-                       self.svg.center(complex(profile.getPreferenceFloat('machine_width')/2, profile.getPreferenceFloat('machine_depth')/2))
-                       self.preview.Refresh()
-               dlg.Destroy()
-
-class PreviewGLCanvas(glcanvas.GLCanvas):
-       def __init__(self, parent, realParent):
-               attribList = (glcanvas.WX_GL_RGBA, glcanvas.WX_GL_DOUBLEBUFFER, glcanvas.WX_GL_DEPTH_SIZE, 24, glcanvas.WX_GL_STENCIL_SIZE, 8)
-               glcanvas.GLCanvas.__init__(self, parent, attribList = attribList)
-               self.parent = realParent
-               self.context = glcanvas.GLContext(self)
-               wx.EVT_PAINT(self, self.OnPaint)
-               wx.EVT_SIZE(self, self.OnSize)
-               wx.EVT_ERASE_BACKGROUND(self, self.OnEraseBackground)
-               wx.EVT_LEFT_DOWN(self, self.OnMouseLeftDown)
-               wx.EVT_MOTION(self, self.OnMouseMotion)
-               wx.EVT_MOUSEWHEEL(self, self.OnMouseWheel)
-               self.yaw = 30
-               self.pitch = 60
-               self.zoom = self.parent.machineSize.x / 2 + 10
-               self.offsetX = 0
-               self.offsetY = 0
-               self.view3D = False
-               self.allowDrag = False
-       
-       def OnMouseLeftDown(self,e):
-               self.allowDrag = True
-       
-       def OnMouseMotion(self,e):
-               if self.allowDrag and e.Dragging() and e.LeftIsDown():
-                       if self.view3D:
-                               self.yaw += e.GetX() - self.oldX
-                               self.pitch -= e.GetY() - self.oldY
-                               if self.pitch > 170:
-                                       self.pitch = 170
-                               if self.pitch < 10:
-                                       self.pitch = 10
-                       else:
-                               self.offsetX += float(e.GetX() - self.oldX) * self.zoom / self.GetSize().GetHeight() * 2
-                               self.offsetY -= float(e.GetY() - self.oldY) * self.zoom / self.GetSize().GetHeight() * 2
-                       self.Refresh()
-               else:
-                       self.allowDrag = False
-               if e.Dragging() and e.RightIsDown():
-                       if self.view3D:
-                               self.zoom += e.GetY() - self.oldY
-                               if self.zoom < 1:
-                                       self.zoom = 1
-                       self.Refresh()
-               self.oldX = e.GetX()
-               self.oldY = e.GetY()
-       
-       def OnMouseWheel(self,e):
-               if self.view3D:
-                       self.zoom *= 1.0 - float(e.GetWheelRotation() / e.GetWheelDelta()) / 10.0
-                       if self.zoom < 1.0:
-                               self.zoom = 1.0
-                       self.Refresh()
-       
-       def OnEraseBackground(self,event):
-               #Workaround for windows background redraw flicker.
-               pass
-       
-       def OnSize(self,event):
-               self.Refresh()
-
-       def OnPaint(self,event):
-               dc = wx.PaintDC(self)
-               self.SetCurrent(self.context)
-               opengl.InitGL(self, self.view3D, self.zoom)
-               if self.view3D:
-                       glTranslate(0,0,-self.zoom)
-                       glRotate(-self.pitch, 1,0,0)
-                       glRotate(self.yaw, 0,0,1)
-                       if False: #self.parent.triangleMesh != None:
-                               glTranslate(0,0,-self.parent.triangleMesh.getMaximum().z / 2)
-               else:
-                       glScale(1.0/self.zoom, 1.0/self.zoom, 1.0)
-                       glTranslate(self.offsetX, self.offsetY, 0.0)
-               glTranslate(-self.parent.machineSize.x/2, -self.parent.machineSize.y/2, 0)
-
-               self.OnDraw()
-               self.SwapBuffers()
-
-       def OnDraw(self):
-               machineSize = self.parent.machineSize
-               opengl.DrawMachine(machineSize)
-               
-               if self.parent.svg != None:
-                       for path in self.parent.svg.paths:
-                               glColor3f(1.0,0.8,0.6)
-                               glBegin(GL_LINE_STRIP)
-                               for p in path:
-                                       glVertex3f(p.real, p.imag, 1)
-                               glEnd()
-               
-               glFlush()
index c2f4056cc18080aa4f8f96cf6b8d53cc48f25f52..624417656cf636249658786a60415ace804595a7 100644 (file)
@@ -112,8 +112,6 @@ class mainWindow(wx.Frame):
                i = toolsMenu.Append(-1, 'Batch run...')
                self.Bind(wx.EVT_MENU, self.OnBatchRun, i)
                self.normalModeOnlyItems.append(i)
-               #               i = toolsMenu.Append(-1, 'Open SVG (2D) slicer...')
-               #               self.Bind(wx.EVT_MENU, self.OnSVGSlicerOpen, i)
                if minecraftImport.hasMinecraft():
                        i = toolsMenu.Append(-1, 'Minecraft import...')
                        self.Bind(wx.EVT_MENU, self.OnMinecraftImport, i)
@@ -259,6 +257,7 @@ class mainWindow(wx.Frame):
 
                        # Enabled sash
                        self.splitter.SetSashSize(4)
+               self.scene.updateProfileToControls()
                                                                
        def OnPreferences(self, e):
                prefDialog = preferencesDialog.preferencesDialog(self)
@@ -491,11 +490,6 @@ class mainWindow(wx.Frame):
                mi.Centre()
                mi.Show(True)
 
-       def OnSVGSlicerOpen(self, e):
-               svgSlicer = flatSlicerWindow.flatSlicerWindow()
-               svgSlicer.Centre()
-               svgSlicer.Show(True)
-
        def OnCheckForUpdate(self, e):
                newVersion = version.checkForNewerVersion()
                if newVersion is not None:
index 3bdf62a444f54438dbde1324183894a7d34bac8a..f90b766273e13ae792a137dd0595c720b865556f 100644 (file)
@@ -13,6 +13,7 @@ from Cura.util import profile
 from Cura.util import meshLoader
 from Cura.util import objectScene
 from Cura.util import resources
+from Cura.util import sliceEngine
 from Cura.gui.util import opengl
 from Cura.gui.util import openglGui
 
@@ -56,8 +57,16 @@ class SceneView(openglGui.glGuiPanel):
                self._animZoom = None
                self._platformMesh = meshLoader.loadMeshes(resources.getPathForMesh('ultimaker_platform.stl'))[0]
                self._platformMesh._drawOffset = numpy.array([0,0,0.5], numpy.float32)
+               self._isSimpleMode = True
+               self._slicer = sliceEngine.Slicer(self._updateSliceProgress)
                wx.EVT_IDLE(self, self.OnIdle)
                self.updateProfileToControls()
+               self._sceneUpdateTimer = wx.Timer(self)
+               self.Bind(wx.EVT_TIMER, lambda e : self._slicer.runSlicer(self._scene), self._sceneUpdateTimer)
+
+               self.openFileButton      = openglGui.glButton(self, 4, 'Load', (0,0), lambda : self.GetParent().GetParent().GetParent()._showModelLoadDialog(1))
+               self.printButton         = openglGui.glButton(self, 6, 'Print', (1,0), None)
+               self.printButton.setDisabled(True)
 
        def OnIdle(self, e):
                if self._animView is not None or self._animZoom is not None:
@@ -68,12 +77,23 @@ class SceneView(openglGui.glGuiPanel):
                                self.Refresh()
                                return
 
+       def sceneUpdated(self):
+               self._sceneUpdateTimer.Start(1, True)
+               self._slicer.abortSlicer()
+               self.Refresh()
+
+       def _updateSliceProgress(self, progressValue, ready):
+               self.printButton.setDisabled(not ready)
+               self.printButton.setProgressBar(progressValue)
+               self.Refresh()
+
        def loadScene(self, fileList):
                for filename in fileList:
                        for obj in meshLoader.loadMeshes(filename):
-                               obj._loadAnim = anim(1, 0, 2)
+                               obj._loadAnim = anim(1, 0, 1.5)
                                self._scene.add(obj)
                                self._selectObject(obj)
+               self.sceneUpdated()
 
        def _deleteObject(self, obj):
                if obj == self._selectedObj:
@@ -84,15 +104,27 @@ class SceneView(openglGui.glGuiPanel):
                for m in obj._meshList:
                        if m.vbo is not None:
                                self.glReleaseList.append(m.vbo)
-
-       def _selectObject(self, obj):
-               self._selectedObj = obj
-               newViewPos = numpy.array([self._selectedObj.getPosition()[0], self._selectedObj.getPosition()[1], self._selectedObj.getMaximum()[2] / 2])
-               self._animView = anim(self._viewTarget.copy(), newViewPos, 0.5)
-               newZoom = self._selectedObj.getBoundaryCircle() * 6
-               self._animZoom = anim(self._zoom, newZoom, 0.5)
+               if self._isSimpleMode:
+                       self._scene.arrangeAll()
+               self.sceneUpdated()
+
+       def _selectObject(self, obj, zoom = True):
+               if obj != self._selectedObj:
+                       self._selectedObj = obj
+               if zoom:
+                       newViewPos = numpy.array([obj.getPosition()[0], obj.getPosition()[1], obj.getMaximum()[2] / 2])
+                       self._animView = anim(self._viewTarget.copy(), newViewPos, 0.5)
+                       newZoom = obj.getBoundaryCircle() * 6
+                       if newZoom > numpy.max(self._machineSize) * 3:
+                               newZoom = numpy.max(self._machineSize) * 3
+                       self._animZoom = anim(self._zoom, newZoom, 0.5)
 
        def updateProfileToControls(self):
+               oldSimpleMode = self._isSimpleMode
+               self._isSimpleMode = profile.getPreference('startMode') == 'Simple'
+               if self._isSimpleMode and not oldSimpleMode:
+                       self._scene.arrangeAll()
+                       self.sceneUpdated()
                self._machineSize = numpy.array([profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height')])
                self._objColors[0] = profile.getPreferenceColour('model_colour')
                self._objColors[1] = profile.getPreferenceColour('model_colour2')
@@ -127,7 +159,7 @@ class SceneView(openglGui.glGuiPanel):
                if self._mouseState == 'dragOrClick':
                        if e.Button == 1:
                                if self._focusObj is not None:
-                                       self._selectedObj = self._focusObj
+                                       self._selectObject(self._focusObj, False)
                                        self.Refresh()
 
        def OnMouseUp(self, e):
@@ -138,9 +170,9 @@ class SceneView(openglGui.glGuiPanel):
                                else:
                                        self._selectedObj = None
                                        self.Refresh()
-               if self._mouseState == 'drag' and self._selectedObj is not None:
+               if self._mouseState == 'dragObject' and self._selectedObj is not None:
                        self._scene.pushFree()
-                       self.Refresh()
+                       self.sceneUpdated()
                self._mouseState = None
 
        def OnMouseMotion(self,e):
@@ -159,7 +191,8 @@ class SceneView(openglGui.glGuiPanel):
                                        self._zoom = 1
                                if self._zoom > numpy.max(self._machineSize) * 3:
                                        self._zoom = numpy.max(self._machineSize) * 3
-                       elif e.LeftIsDown() and self._selectedObj is not None:
+                       elif e.LeftIsDown() and self._selectedObj is not None and not self._isSimpleMode:
+                               self._mouseState = 'dragObject'
                                z = max(0, self._mouseClick3DPos[2])
                                p0 = opengl.unproject(self._mouseX, self.viewport[1] + self.viewport[3] - self._mouseY, 0, self.modelMatrix, self.projMatrix, self.viewport)
                                p1 = opengl.unproject(self._mouseX, self.viewport[1] + self.viewport[3] - self._mouseY, 1, self.modelMatrix, self.projMatrix, self.viewport)
@@ -200,7 +233,7 @@ class SceneView(openglGui.glGuiPanel):
                glMatrixMode(GL_PROJECTION)
                glLoadIdentity()
                aspect = float(size.GetWidth()) / float(size.GetHeight())
-               gluPerspective(45.0, aspect, 1.0, 1000.0)
+               gluPerspective(45.0, aspect, 1.0, numpy.max(self._machineSize) * 4)
 
                glMatrixMode(GL_MODELVIEW)
                glLoadIdentity()
index 3faffe3bcc002da824c728212943c0f79559e155..72da49d2433672d797b778feb8367aee62cf527f 100644 (file)
@@ -347,6 +347,7 @@ class glButton(glGuiControl):
                self._hidden = False
                self._disabled = False
                self._showExpandArrow = False
+               self._progressBar = 0.0
 
        def setSelected(self, value):
                self._selected = value
@@ -360,6 +361,9 @@ class glButton(glGuiControl):
        def setDisabled(self, value):
                self._disabled = value
 
+       def setProgressBar(self, value):
+               self._progressBar = value
+
        def getSelected(self):
                return self._selected
 
@@ -417,6 +421,12 @@ class glButton(glGuiControl):
                        glColor4ub(255,255,255,255)
                        opengl.glDrawStringCenter(self._tooltip)
                glPopMatrix()
+               if 0.0 < self._progressBar < 1.0:
+                       glColor4ub(255,255,255,192)
+                       glPushMatrix()
+                       opengl.glDrawTexturedQuad(pos[0]-bs/2, pos[1]+bs/2, bs, bs / 4, 0)
+                       opengl.glDrawTexturedQuad(pos[0]-bs/2, pos[1]+bs/2, bs * self._progressBar, bs / 4, 0)
+                       glPopMatrix()
 
        def _checkHit(self, x, y):
                if self._hidden or self._disabled:
diff --git a/Cura/slice/__init__.py b/Cura/slice/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/__main__.py b/Cura/slice/__main__.py
deleted file mode 100644 (file)
index a551e9e..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-from __future__ import absolute_import
-
-from optparse import OptionParser
-import sys
-import re
-import os
-import urllib
-import urllib2
-import platform
-import hashlib
-import subprocess
-
-if not hasattr(sys, 'frozen'):
-       cura_sf_path = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "./cura_sf/"))
-       if cura_sf_path not in sys.path:
-               sys.path.append(cura_sf_path)
-
-from Cura.util import profile
-from Cura.util import version
-from Cura.slice.cura_sf.skeinforge_application.skeinforge_plugins.craft_plugins import export
-
-def fixUTF8(input):
-       if input.startswith('#UTF8#'):
-               return input[6:].decode('utf-8')
-       return input
-
-def main():
-       parser = OptionParser(usage="usage: %prog [options] <X,Y> <filename>[, <X,Y> <filename>][, ...]")
-       parser.add_option("-p", "--profile", action="store", type="string", dest="profile",
-                                         help="Encoded profile to use for the print")
-       parser.add_option("-o", "--output", action="store", type="string", dest="output",
-                                         help="Output filename")
-       (options, args) = parser.parse_args()
-       if options.output is None:
-               print 'Missing output filename'
-               sys.exit(1)
-       if options.profile is not None:
-               profile.loadProfileFromString(options.profile)
-       options.output = fixUTF8(options.output)
-
-       steamEngineFilename = os.path.join(os.path.dirname(__file__), 'SteamEngine')
-       if platform.system() == "Windows":
-               steamEngineFilename += ".exe"
-               if os.path.isfile("C:\Software\Cura_SteamEngine\_bin\Release\Cura_SteamEngine.exe"):
-                       steamEngineFilename = "C:\Software\Cura_SteamEngine\_bin\Release\Cura_SteamEngine.exe"
-       if os.path.isfile(steamEngineFilename):
-               for idx in xrange(0, len(args), 2):
-                       position = map(float, args[idx].split(','))
-                       if len(position) < 9 + 2:
-                               position = position[0:2]
-                               position += [1,0,0]
-                               position += [0,1,0]
-                               position += [0,0,1]
-
-                       settings = {}
-                       settings['layerThickness'] = int(profile.getProfileSettingFloat('layer_height') * 1000)
-                       settings['initialLayerThickness'] = int(profile.getProfileSettingFloat('bottom_thickness') * 1000)
-                       settings['filamentDiameter'] = int(profile.getProfileSettingFloat('filament_diameter') * 1000)
-                       settings['extrusionWidth'] = int(profile.calculateEdgeWidth() * 1000)
-                       settings['insetCount'] = int(profile.calculateLineCount())
-                       settings['downSkinCount'] = int(profile.calculateSolidLayerCount())
-                       settings['upSkinCount'] = int(profile.calculateSolidLayerCount())
-                       if profile.getProfileSettingFloat('fill_density') > 0:
-                               settings['sparseInfillLineDistance'] = int(100 * 1000 * profile.calculateEdgeWidth() / profile.getProfileSettingFloat('fill_density'))
-                       else:
-                               settings['sparseInfillLineDistance'] = 9999999
-                       settings['skirtDistance'] = int(profile.getProfileSettingFloat('skirt_gap') * 1000)
-                       settings['skirtLineCount'] = int(profile.getProfileSettingFloat('skirt_line_count'))
-
-                       settings['initialSpeedupLayers'] = int(4)
-                       settings['initialLayerSpeed'] = int(profile.getProfileSettingFloat('bottom_layer_speed'))
-                       settings['printSpeed'] = int(profile.getProfileSettingFloat('print_speed'))
-                       settings['moveSpeed'] = int(profile.getProfileSettingFloat('travel_speed'))
-                       settings['fanOnLayerNr'] = int(profile.getProfileSettingFloat('fan_layer'))
-                       settings['supportAngle'] = int(60) if profile.getProfileSetting('support') != 'None' else int(-1)
-                       settings['supportEverywhere'] = int(1) if profile.getProfileSetting('support') == 'Everywhere' else int(0)
-                       settings['retractionAmount'] = int(0) if profile.getProfileSetting('retraction_enable') == 'False' else int(profile.getProfileSettingFloat('retraction_amount') * 1000)
-                       settings['retractionSpeed'] = int(profile.getProfileSettingFloat('retraction_speed'))
-                       settings['objectSink'] = int(profile.getProfileSettingFloat('object_sink') * 1000.0)
-
-                       cmdList = [steamEngineFilename, args[idx+1], '-o', options.output, '-m', ','.join(map(str, position[2:]))]
-                       for (key, value) in settings.items():
-                               cmdList += ['-s', str(key) + "=" + str(value)]
-                       kwargs = {}
-                       if subprocess.mswindows:
-                               su = subprocess.STARTUPINFO()
-                               su.dwFlags |= subprocess.STARTF_USESHOWWINDOW
-                               su.wShowWindow = subprocess.SW_HIDE
-                               kwargs['startupinfo'] = su
-                       p = subprocess.Popen(cmdList, **kwargs)
-                       p.communicate()
-               return
-
-       clearZ = 0
-       resultFile = open(options.output, "w")
-       for idx in xrange(0, len(args), 2):
-               position = map(float, args[idx].split(','))
-               if len(position) < 9 + 2:
-                       position = position[0:2]
-                       position += [1,0,0]
-                       position += [0,1,0]
-                       position += [0,0,1]
-               filenames = fixUTF8(args[idx + 1]).split('|')
-
-               profile.setTempOverride('object_center_x', position[0])
-               profile.setTempOverride('object_center_y', position[1])
-               if idx == 0:
-                       resultFile.write(';TYPE:CUSTOM\n')
-                       resultFile.write(profile.getAlterationFileContents('start.gcode', len(filenames)).replace('?filename?', ' '.join(filenames).encode('ascii', 'replace')))
-               else:
-                       resultFile.write(';TYPE:CUSTOM\n')
-                       n = output[-1].rfind('Z')+1
-                       zString = output[-1][n:n+20]
-                       zString = zString[0:zString.find(' ')]
-                       clearZ = max(clearZ, float(zString) + 10)
-                       profile.setTempOverride('clear_z', clearZ)
-                       print position
-                       print profile.getAlterationFileContents('nextobject.gcode')
-                       resultFile.write(profile.getAlterationFileContents('nextobject.gcode').replace('?filename?', ' '.join(filenames).encode('ascii', 'replace')))
-
-               output = []
-               for filename in filenames:
-                       extruderNr = filenames.index(filename)
-                       profile.resetTempOverride()
-                       if extruderNr > 0:
-                               profile.setTempOverride('object_center_x', position[0] - profile.getPreferenceFloat('extruder_offset_x%d' % (extruderNr)))
-                               profile.setTempOverride('object_center_y', position[1] - profile.getPreferenceFloat('extruder_offset_y%d' % (extruderNr)))
-                               profile.setTempOverride('fan_enabled', 'False')
-                               profile.setTempOverride('skirt_line_count', '0')
-                               profile.setTempOverride('alternative_center', filenames[0])
-                       else:
-                               profile.setTempOverride('object_center_x', position[0])
-                               profile.setTempOverride('object_center_y', position[1])
-                       profile.setTempOverride('object_matrix', ','.join(map(str, position[2:11])))
-                       if extruderNr > 0:
-                               if profile.getProfileSettingFloat('filament_diameter%d' % (extruderNr + 1)) > 0:
-                                       profile.setTempOverride('filament_diameter', profile.getProfileSetting('filament_diameter%d' % (extruderNr + 1)))
-                       output.append(export.getOutput(filename))
-                       profile.resetTempOverride()
-               if len(output) == 1:
-                       resultFile.write(output[0])
-               else:
-                       stitchMultiExtruder(output, resultFile)
-       resultFile.write(';TYPE:CUSTOM\n')
-       resultFile.write(profile.getAlterationFileContents('end.gcode'))
-       resultFile.close()
-
-       print "Running plugins"
-       ret = profile.runPostProcessingPlugins(options.output)
-       if ret is not None:
-               print ret
-       print "Finalizing %s" % (os.path.basename(options.output))
-       if profile.getPreference('submit_slice_information') == 'True':
-               filenames = fixUTF8(args[idx + 1]).split('|')
-               for filename in filenames:
-                       m = hashlib.sha512()
-                       f = open(filename, "rb")
-                       while True:
-                               chunk = f.read(1024)
-                               if not chunk:
-                                       break
-                               m.update(chunk)
-                       f.close()
-                       data = {
-                               'processor': platform.processor(),
-                               'machine': platform.machine(),
-                               'platform': platform.platform(),
-                               'profile': profile.getProfileString(),
-                               'preferences': profile.getGlobalPreferencesString(),
-                               'modelhash': m.hexdigest(),
-                               'version': version.getVersion(),
-                       }
-                       try:
-                               f = urllib2.urlopen("http://platform.ultimaker.com/curastats/", data = urllib.urlencode(data), timeout = 5);
-                               f.read()
-                               f.close()
-                       except:
-                               pass
-
-
-def isPrintingLine(line):
-       if line.startswith("G1") and ('X' in line or 'Y' in line) and 'E' in line:
-               return True
-       return False
-
-def getCodeFloat(line, code, default):
-       n = line.find(code) + 1
-       if n < 1:
-               return default
-       m = line.find(' ', n)
-       try:
-               if m < 0:
-                       return float(line[n:])
-               return float(line[n:m])
-       except:
-               return default
-
-def stitchMultiExtruder(outputList, resultFile):
-       print "Stitching %i files for multi-extrusion" % (len(outputList))
-       currentExtruder = 0
-       resultFile.write('T%d\n' % (currentExtruder))
-       layerNr = 0
-       hasLine = True
-       outputList = map(lambda o: o.split('\n'), outputList)
-       outputOrder = range(0, len(outputList))
-       outputSlice = []
-       for n in xrange(0, len(outputList)):
-               outputSlice.append([0, 0])
-       currentX = 0
-       currentY = 0
-       currentZ = 0
-       currentF = 60
-       while hasLine:
-               hasLine = layerNr < 1000
-               for n in xrange(0, len(outputList)):
-                       outputSlice[n][0] = outputSlice[n][1] + 1
-                       outputSlice[n][1] = outputSlice[n][0]
-                       while outputSlice[n][1] < len(outputList[n]) and not outputList[n][outputSlice[n][1]].startswith(';LAYER:'):
-                               outputSlice[n][1] += 1
-               outputOrder = range(currentExtruder, len(outputList)) + range(0, currentExtruder)
-               for n in outputOrder:
-                       if outputSlice[n][1] > outputSlice[n][0] + 1:
-                               nextExtruder = n
-                               resultFile.write(';LAYER:%d\n' % (layerNr))
-                               resultFile.write(';EXTRUDER:%d\n' % (nextExtruder))
-
-                               startSlice = outputSlice[n][0]
-                               endSlice = outputSlice[n][1]
-                               currentE = 0
-                               while not isPrintingLine(outputList[n][startSlice]):
-                                       currentE = getCodeFloat(outputList[n][startSlice], 'E', currentE)
-                                       currentX = getCodeFloat(outputList[n][startSlice], 'X', currentX)
-                                       currentY = getCodeFloat(outputList[n][startSlice], 'Y', currentY)
-                                       currentZ = getCodeFloat(outputList[n][startSlice], 'Z', currentZ)
-                                       currentF = getCodeFloat(outputList[n][startSlice], 'F', currentF)
-                                       startSlice += 1
-                               while not isPrintingLine(outputList[n][endSlice-1]):
-                                       endSlice -= 1
-
-                               if nextExtruder != currentExtruder:
-                                       profile.setTempOverride('extruder', nextExtruder)
-                                       profile.setTempOverride('new_x', currentX)
-                                       profile.setTempOverride('new_y', currentY)
-                                       profile.setTempOverride('new_z', currentZ)
-                                       resultFile.write(profile.getAlterationFileContents('switchExtruder.gcode') + '\n')
-                                       profile.resetTempOverride()
-                                       currentExtruder = nextExtruder
-
-                               for idx in xrange(outputSlice[n][0], startSlice):
-                                       if not 'G1' in outputList[n][idx]:
-                                               resultFile.write(outputList[n][idx])
-                                               resultFile.write('\n')
-
-                               resultFile.write('G1 X%f Y%f Z%f F%f\n' % (currentX, currentY, currentZ, profile.getProfileSettingFloat('travel_speed') * 60))
-                               resultFile.write('G1 F%f\n' % (currentF))
-                               resultFile.write('G92 E%f\n' % (currentE))
-                               for idx in xrange(startSlice, endSlice):
-                                       resultFile.write(outputList[n][idx])
-                                       resultFile.write('\n')
-                                       currentX = getCodeFloat(outputList[n][idx], 'X', currentX)
-                                       currentY = getCodeFloat(outputList[n][idx], 'Y', currentY)
-                                       currentZ = getCodeFloat(outputList[n][idx], 'Z', currentZ)
-                                       hasLine = True
-                               resultFile.write('G92 E0\n')
-               layerNr += 1
-
-if __name__ == '__main__':
-       main()
diff --git a/Cura/slice/cura_sf/SkeinforgeVersion b/Cura/slice/cura_sf/SkeinforgeVersion
deleted file mode 100644 (file)
index fb1ff68..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-This SkeinPyPy version is based in Skeinforge: 50
-
diff --git a/Cura/slice/cura_sf/__init__.py b/Cura/slice/cura_sf/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/archive.py b/Cura/slice/cura_sf/fabmetheus_utilities/archive.py
deleted file mode 100644 (file)
index 5a770fb..0000000
+++ /dev/null
@@ -1,402 +0,0 @@
-"""
-Boolean geometry utilities.
-
-"""
-
-from __future__ import absolute_import
-
-import os
-import sys
-import traceback
-import zipfile
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalTemporarySettingsPath = os.path.join(os.path.expanduser('~'), '.skeinforge_pypy')
-
-
-def addToNamePathDictionary(directoryPath, namePathDictionary):
-       'Add to the name path dictionary.'
-       pluginFileNames = getPluginFileNamesFromDirectoryPath(directoryPath)
-       for pluginFileName in pluginFileNames:
-               namePathDictionary[pluginFileName.replace('_', '')] = os.path.join(directoryPath, pluginFileName)
-
-def getAbsoluteFolderPath(filePath, folderName=''):
-       'Get the absolute folder path.'
-       absoluteFolderPath = os.path.dirname(os.path.abspath(filePath))
-       if folderName == '':
-               return absoluteFolderPath
-       return os.path.join(absoluteFolderPath, folderName)
-
-def getAbsoluteFrozenFolderPath(filePath, folderName=''):
-       'Get the absolute frozen folder path.'
-       if hasattr(sys, 'frozen'):
-               if '.py' in filePath:
-                       filePath = ''.join(filePath.rpartition('\\')[: 2])
-               filePath = os.path.join(filePath, 'skeinforge_application')
-       return getAbsoluteFolderPath(filePath, folderName)
-
-def getAnalyzePluginsDirectoryPath(subName=''):
-       'Get the analyze plugins directory path.'
-       return getJoinedPath(getSkeinforgePluginsPath('analyze_plugins'), subName)
-
-def getCraftPluginsDirectoryPath(subName=''):
-       'Get the craft plugins directory path.'
-       return getJoinedPath(getSkeinforgePluginsPath('craft_plugins'), subName)
-
-def getDocumentationPath(subName=''):
-       'Get the documentation file path.'
-       return getJoinedPath(getFabmetheusPath('documentation'), subName)
-
-def getElementsPath(subName=''):
-       'Get the evaluate_elements directory path.'
-       return getJoinedPath(getGeometryUtilitiesPath('evaluate_elements'), subName)
-
-def getEndsWithList(word, wordEndings):
-       'Determine if the word ends with a list.'
-       for wordEnding in wordEndings:
-               if word.endswith(wordEnding):
-                       return True
-       return False
-
-def getFabmetheusPath(subName=''):
-       'Get the fabmetheus directory path.'
-       fabmetheusFile = None
-       if hasattr(sys, 'frozen'):
-               fabmetheusFile = unicode(sys.executable, sys.getfilesystemencoding())
-       else:
-               fabmetheusFile = os.path.dirname(os.path.abspath(__file__))
-       return getJoinedPath(os.path.dirname(fabmetheusFile), subName)
-
-def getFabmetheusToolsPath(subName=''):
-       'Get the fabmetheus tools directory path.'
-       return getJoinedPath(getFabmetheusUtilitiesPath('fabmetheus_tools'), subName)
-
-def getFabmetheusUtilitiesPath(subName=''):
-       'Get the fabmetheus utilities directory path.'
-       return getJoinedPath(getFabmetheusPath('fabmetheus_utilities'), subName)
-
-def getFileNamesByFilePaths(pluginFilePaths):
-       'Get the file names of the plugins by the file paths.'
-       fileNames = []
-       for pluginFilePath in pluginFilePaths:
-               pluginBasename = os.path.basename(pluginFilePath)
-               pluginBasename = getUntilDot(pluginBasename)
-               fileNames.append(pluginBasename)
-       return fileNames
-
-def getFilePaths(fileInDirectory=''):
-       'Get the file paths in the directory of the file in directory.'
-       directoryName = os.getcwd()
-       if fileInDirectory != '':
-               directoryName = os.path.dirname(fileInDirectory)
-       return getFilePathsByDirectory(directoryName)
-
-def getFilePathsByDirectory(directoryName):
-       'Get the file paths in the directory of the file in directory.'
-       absoluteDirectoryPath = os.path.abspath(directoryName)
-       filePaths = []
-       if os.path.isdir(directoryName):
-               for fileName in os.listdir(directoryName):
-                       filePaths.append(os.path.join(absoluteDirectoryPath, fileName))
-       elif '.zip/' in directoryName:
-               zipfilename = directoryName[:directoryName.rfind('.zip/')+4]
-               subpath = directoryName[directoryName.rfind('.zip/')+5:]
-
-               z = zipfile.ZipFile(zipfilename, 'r')
-               for name in z.namelist():
-                       if os.path.dirname(name) == subpath:
-                               filePaths.append(os.path.join(zipfilename, name))
-               z.close()
-               print(directoryName, filePaths)
-       return filePaths
-
-def getFilePathsRecursively(fileInDirectory=''):
-       'Get the file paths in the directory of the file in directory.'
-       filePaths = getFilePaths(fileInDirectory)
-       filePathsRecursively = filePaths[:]
-       for filePath in filePaths:
-               if os.path.isdir(filePath):
-                       directory = os.listdir(filePath)
-                       if len(directory) > 0:
-                               filePathsRecursively += getFilePathsRecursively(os.path.join(filePath, directory[0]))
-       return filePathsRecursively
-
-def getFilePathWithUnderscoredBasename(fileName, suffix):
-       'Get the file path with all spaces in the basename replaced with underscores.'
-       suffixFileName = getUntilDot(fileName) + suffix
-       suffixDirectoryName = os.path.dirname(suffixFileName)
-       suffixReplacedBaseName = os.path.basename(suffixFileName).replace(' ', '_')
-       return os.path.join(suffixDirectoryName, suffixReplacedBaseName)
-
-def getFilesWithFileTypesWithoutWords(fileTypes, words = [], fileInDirectory=''):
-       'Get files which have a given file type, but with do not contain a word in a list.'
-       filesWithFileTypes = []
-       for filePath in getFilePaths(fileInDirectory):
-               for fileType in fileTypes:
-                       if isFileWithFileTypeWithoutWords(fileType, filePath, words):
-                               filesWithFileTypes.append(filePath)
-       filesWithFileTypes.sort()
-       return filesWithFileTypes
-
-def getFilesWithFileTypesWithoutWordsRecursively(fileTypes, words = [], fileInDirectory=''):
-       'Get files recursively which have a given file type, but with do not contain a word in a list.'
-       filesWithFileTypesRecursively = []
-       for filePath in getFilePathsRecursively(fileInDirectory):
-               for fileType in fileTypes:
-                       if isFileWithFileTypeWithoutWords(fileType, filePath, words):
-                               filesWithFileTypesRecursively.append(filePath)
-       filesWithFileTypesRecursively.sort()
-       return filesWithFileTypesRecursively
-
-def getFilesWithFileTypeWithoutWords(fileType, words = [], fileInDirectory=''):
-       'Get files which have a given file type, but with do not contain a word in a list.'
-       filesWithFileType = []
-       for filePath in getFilePaths(fileInDirectory):
-               if isFileWithFileTypeWithoutWords(fileType, filePath, words):
-                       filesWithFileType.append(filePath)
-       filesWithFileType.sort()
-       return filesWithFileType
-
-def getFileText(fileName, printWarning=True, readMode='r'):
-       'Get the entire text of a file.'
-       if '.zip/' in fileName:
-               zipfilename = fileName[:fileName.rfind('.zip/')+4]
-               subpath = fileName[fileName.rfind('.zip/')+5:]
-
-               try:
-                       z = zipfile.ZipFile(zipfilename, 'r')
-                       f = z.open(subpath, 'r')
-                       fileText = f.read()
-                       f.close()
-                       z.close()
-                       return fileText
-               except KeyError:
-                       if printWarning:
-                               print('The file ' + fileName + ' does not exist.')
-                       return ''
-       try:
-               f = open(fileName, readMode)
-               fileText = f.read()
-               f.close()
-               return fileText
-       except IOError:
-               if printWarning:
-                       print('The file ' + fileName + ' does not exist.')
-       
-       return ''
-
-def getFileTextInFileDirectory(fileInDirectory, fileName, readMode='r'):
-       'Get the entire text of a file in the directory of the file in directory.'
-       absoluteFilePathInFileDirectory = os.path.join(os.path.dirname(fileInDirectory), fileName)
-       return getFileText(absoluteFilePathInFileDirectory, True, readMode)
-
-def getFundamentalsPath(subName=''):
-       'Get the evaluate_fundamentals directory path.'
-       return getJoinedPath(getGeometryUtilitiesPath('evaluate_fundamentals'), subName)
-
-def getGeometryDictionary(folderName):
-       'Get to the geometry name path dictionary.'
-       geometryDictionary={}
-       geometryDirectory = getGeometryPath()
-       addToNamePathDictionary(os.path.join(geometryDirectory, folderName), geometryDictionary)
-       geometryPluginsDirectory = getFabmetheusUtilitiesPath('geometry_plugins')
-       addToNamePathDictionary(os.path.join(geometryPluginsDirectory, folderName), geometryDictionary)
-       return geometryDictionary
-
-def getGeometryPath(subName=''):
-       'Get the geometry directory path.'
-       return getJoinedPath(getFabmetheusUtilitiesPath('geometry'), subName)
-
-def getGeometryToolsPath(subName=''):
-       'Get the geometry tools directory path.'
-       return getJoinedPath(getGeometryPath('geometry_tools'), subName)
-
-def getGeometryUtilitiesPath(subName=''):
-       'Get the geometry_utilities directory path.'
-       return getJoinedPath(getGeometryPath('geometry_utilities'), subName)
-
-def getInterpretPluginsPath(subName=''):
-       'Get the interpret plugins directory path.'
-       return getJoinedPath(getFabmetheusToolsPath('interpret_plugins'), subName)
-
-def getJoinedPath(path, subName=''):
-       'Get the joined file path.'
-       if subName == '':
-               return path
-       return os.path.join(path, subName)
-
-def getModuleWithDirectoryPath(directoryPath, fileName):
-       'Get the module from the fileName and folder name.'
-       if fileName == '':
-               print('The file name in getModule in archive was empty.')
-               return None
-       originalSystemPath = sys.path[:]
-       try:
-               sys.path.insert(0, directoryPath)
-               folderPluginsModule = __import__(fileName)
-               sys.path = originalSystemPath
-               return folderPluginsModule
-       except:
-               sys.path = originalSystemPath
-               print('')
-               print('Exception traceback in getModuleWithDirectoryPath in archive:')
-               traceback.print_exc(file=sys.stdout)
-               print('')
-               print('That error means; could not import a module with the fileName ' + fileName)
-               print('and an absolute directory name of ' + directoryPath)
-               print('')
-       return None
-
-def getModuleWithPath(path):
-       'Get the module from the path.'
-       return getModuleWithDirectoryPath(os.path.dirname(path), os.path.basename(path))
-
-def getPluginFileNamesFromDirectoryPath(directoryPath):
-       'Get the file names of the python plugins in the directory path.'
-       fileInDirectory = os.path.join(directoryPath, '__init__.py')
-       return getFileNamesByFilePaths(getPythonFileNamesExceptInit(fileInDirectory))
-
-def getProfilesPath(subName=''):
-       'Get the profiles directory path, which is the settings directory joined with profiles.'
-       return getJoinedPath(getSettingsPath('profiles'), subName)
-
-def getPythonDirectoryNames(directoryName):
-       'Get the python directories.'
-       pythonDirectoryNames = []
-       directory = os.listdir(directoryName)
-       for fileName in directory:
-               subdirectoryName = os.path.join(directoryName, fileName)
-               if os.path.isdir(subdirectoryName):
-                       if os.path.isfile(os.path.join(subdirectoryName, '__init__.py')):
-                               pythonDirectoryNames.append(subdirectoryName)
-       return pythonDirectoryNames
-
-def getPythonDirectoryNamesRecursively(directoryName=''):
-       'Get the python directories recursively.'
-       recursivePythonDirectoryNames = []
-       if directoryName == '':
-               directoryName = os.getcwd()
-       if os.path.isfile(os.path.join(directoryName, '__init__.py')):
-               recursivePythonDirectoryNames.append(directoryName)
-               pythonDirectoryNames = getPythonDirectoryNames(directoryName)
-               for pythonDirectoryName in pythonDirectoryNames:
-                       recursivePythonDirectoryNames += getPythonDirectoryNamesRecursively(pythonDirectoryName)
-       else:
-               return []
-       return recursivePythonDirectoryNames
-
-def getPythonFileNamesExceptInit(fileInDirectory=''):
-       'Get the python fileNames of the directory which the fileInDirectory is in, except for the __init__.py file.'
-       pythonFileNamesExceptInit = getFilesWithFileTypeWithoutWords('py', ['__init__.py'], fileInDirectory)
-       pythonFileNamesExceptInit.sort()
-       return pythonFileNamesExceptInit
-
-def getPythonFileNamesExceptInitRecursively(directoryName=''):
-       'Get the python fileNames of the directory recursively, except for the __init__.py files.'
-       pythonDirectoryNames = getPythonDirectoryNamesRecursively(directoryName)
-       pythonFileNamesExceptInitRecursively = []
-       for pythonDirectoryName in pythonDirectoryNames:
-               pythonFileNamesExceptInitRecursively += getPythonFileNamesExceptInit(os.path.join(pythonDirectoryName, '__init__.py'))
-       pythonFileNamesExceptInitRecursively.sort()
-       return pythonFileNamesExceptInitRecursively
-
-def getSettingsPath(subName=''):
-       'Get the settings directory path, which is the home directory joined with .skeinforge.'
-       global globalTemporarySettingsPath
-       return getJoinedPath(globalTemporarySettingsPath, subName)
-
-def getSkeinforgePath(subName=''):
-       'Get the skeinforge directory path.'
-       return getJoinedPath(getFabmetheusPath('skeinforge_application'), subName)
-
-def getSkeinforgePluginsPath(subName=''):
-       'Get the skeinforge plugins directory path.'
-       return getJoinedPath(getSkeinforgePath('skeinforge_plugins'), subName)
-
-def getSummarizedFileName(fileName):
-       'Get the fileName basename if the file is in the current working directory, otherwise return the original full name.'
-       if os.getcwd() == os.path.dirname(fileName):
-               return os.path.basename(fileName)
-       return fileName
-
-def getTemplatesPath(subName=''):
-       'Get the templates directory path.'
-       return getJoinedPath(getFabmetheusUtilitiesPath('templates'), subName)
-
-def getTextIfEmpty(fileName, text):
-       'Get the text from a file if it the text is empty.'
-       if text != '':
-               return text
-       return getFileText(fileName)
-
-def getTextLines(text):
-       'Get the all the lines of text of a text.'
-       if '\r' in text:
-               text = text.replace('\r', '\n').replace('\n\n', '\n')
-       textLines = text.split('\n')
-       if len(textLines) == 1:
-               if textLines[0] == '':
-                       return []
-       return textLines
-
-def getUntilDot(text):
-       'Get the text until the last dot, if any.'
-       dotIndex = text.rfind('.')
-       if dotIndex < 0:
-               return text
-       return text[: dotIndex]
-
-def getVersionFileName():
-       'Get the file name of the version date.getFabmetheusUtilitiesPath(subName='')'
-       return getFabmetheusUtilitiesPath('version.txt')
-
-def isFileWithFileTypeWithoutWords(fileType, fileName, words):
-       'Determine if file has a given file type, but with does not contain a word in a list.'
-       fileName = os.path.basename(fileName)
-       fileTypeDot = '.' + fileType
-       if not fileName.endswith(fileTypeDot):
-               return False
-       for word in words:
-               if fileName.find(word) >= 0:
-                       return False
-       return True
-
-def makeDirectory(directoryPath):
-       'Make a directory if it does not already exist.'
-       if os.path.isdir(directoryPath):
-               return
-       try:
-               print('The following directory was made:')
-               print(os.path.abspath(directoryPath))
-               os.makedirs(directoryPath)
-       except OSError:
-               print('Skeinforge can not make the directory %s so give it read/write permission for that directory and the containing directory.' % directoryPath)
-
-def removeBackupFilesByType(fileType):
-       'Remove backup files by type.'
-       backupFilePaths = getFilesWithFileTypesWithoutWordsRecursively([fileType + '~'])
-       for backupFilePath in backupFilePaths:
-               os.remove(backupFilePath)
-
-def removeBackupFilesByTypes(fileTypes):
-       'Remove backup files by types.'
-       for fileType in fileTypes:
-               removeBackupFilesByType(fileType)
-
-def writeFileMessageEnd(end, fileName, fileText, message):
-       'Write to a fileName with a suffix and print a message.'
-       suffixFileName = getUntilDot(fileName) + end
-       writeFileText(suffixFileName, fileText)
-       print(message + getSummarizedFileName(suffixFileName))
-
-def writeFileText(fileName, fileText, writeMode='w+'):
-       'Write a text to a file.'
-       file = open(fileName, writeMode)
-       file.write(fileText)
-       file.close()
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/euclidean.py b/Cura/slice/cura_sf/fabmetheus_utilities/euclidean.py
deleted file mode 100644 (file)
index 09359fb..0000000
+++ /dev/null
@@ -1,2496 +0,0 @@
-"""
-Euclidean is a collection of python utilities for complex numbers, paths, polygons & Vector3s.
-
-To use euclidean, install python 2.x on your machine, which is avaliable from http://www.python.org/download/
-
-Then in the folder which euclidean is in, type 'python' in a shell to run the python interpreter.  Finally type 'import euclidean' to import these utilities and 'from vector3 import Vector3' to import the Vector3 class.
-
-
-Below are examples of euclidean use.
-
->>> from euclidean import *
->>> origin=complex()
->>> right=complex(1.0,0.0)
->>> back=complex(0.0,1.0)
->>> getMaximum(right,back)
-1.0, 1.0
->>> polygon=[origin, right, back]
->>> getLoopLength(polygon)
-3.4142135623730949
->>> getAreaLoop(polygon)
-0.5
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import xml_simple_writer
-
-import sys
-import math
-import random
-
-if sys.version_info[0] < 3:
-       import cStringIO
-else:
-       import io as cStringIO
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalGoldenAngle = 3.8832220774509332 # (math.sqrt(5.0) - 1.0) * math.pi
-globalGoldenRatio = 1.6180339887498948482045868 # math.sqrt(1.25) + 0.5
-globalTau = math.pi + math.pi # http://tauday.com/
-
-
-def addElementToListDictionary(element, key, listDictionary):
-       'Add an element to the list table.'
-       if key in listDictionary:
-               listDictionary[key].append(element)
-       else:
-               listDictionary[key] = [element]
-
-def addElementToListDictionaryIfNotThere(element, key, listDictionary):
-       'Add the value to the lists.'
-       if key in listDictionary:
-               elements = listDictionary[key]
-               if element not in elements:
-                       elements.append(element)
-       else:
-               listDictionary[key] = [element]
-
-def addElementToPixelList( element, pixelDictionary, x, y ):
-       'Add an element to the pixel list.'
-       addElementToListDictionary( element, (x, y), pixelDictionary )
-
-def addElementToPixelListFromPoint( element, pixelDictionary, point ):
-       'Add an element to the pixel list.'
-       addElementToPixelList( element, pixelDictionary, int( round( point.real ) ), int( round( point.imag ) ) )
-
-def addHorizontallyBoundedPoint(begin, center, end, horizontalBegin, horizontalEnd, path):
-       'Add point if it is within the horizontal bounds.'
-       if horizontalEnd <= center.real <= horizontalBegin:
-               path.append(center)
-               return
-       if end != None:
-               if center.real > horizontalBegin >= end.real:
-                       centerMinusEnd = center - end
-                       along = (center.real - horizontalBegin) / centerMinusEnd.real
-                       path.append(center - along * centerMinusEnd)
-                       return
-       if begin != None:
-               if center.real < horizontalEnd <= begin.real:
-                       centerMinusBegin = center - begin
-                       along = (center.real - horizontalEnd) / centerMinusBegin.real
-                       path.append(center - along * centerMinusBegin)
-
-def addListToListTable( elementList, key, listDictionary ):
-       'Add a list to the list table.'
-       if key in listDictionary:
-               listDictionary[key] += elementList
-       else:
-               listDictionary[key] = elementList
-
-def addLoopToPixelTable( loop, pixelDictionary, width ):
-       'Add loop to the pixel table.'
-       for pointIndex in xrange(len(loop)):
-               pointBegin = loop[pointIndex]
-               pointEnd = loop[(pointIndex + 1) % len(loop)]
-               addValueSegmentToPixelTable( pointBegin, pointEnd, pixelDictionary, None, width )
-
-def addNestedRingBeginning(distanceFeedRate, loop, z):
-       'Add nested ring beginning to gcode output.'
-       distanceFeedRate.addLine('(<nestedRing>)')
-       distanceFeedRate.addLine('(<boundaryPerimeter>)')
-       for point in loop:
-               pointVector3 = Vector3(point.real, point.imag, z)
-               distanceFeedRate.addLine(distanceFeedRate.getBoundaryLine(pointVector3))
-
-def addPathToPixelTable( path, pixelDictionary, value, width ):
-       'Add path to the pixel table.'
-       for pointIndex in xrange( len(path) - 1 ):
-               pointBegin = path[pointIndex]
-               pointEnd = path[pointIndex + 1]
-               addValueSegmentToPixelTable( pointBegin, pointEnd, pixelDictionary, value, width )
-
-def addPixelTableToPixelTable( fromPixelTable, intoPixelTable ):
-       'Add from pixel table to the into pixel table.'
-       for fromPixelTableKey in fromPixelTable.keys():
-               intoPixelTable[ fromPixelTableKey ] = fromPixelTable[ fromPixelTableKey ]
-
-def addPixelToPixelTableWithSteepness( isSteep, pixelDictionary, value, x, y ):
-       'Add pixels to the pixel table with steepness.'
-       if isSteep:
-               pixelDictionary[(y, x)] = value
-       else:
-               pixelDictionary[(x, y)] = value
-
-def addPointToPath( path, pixelDictionary, point, value, width ):
-       'Add a point to a path and the pixel table.'
-       path.append(point)
-       if len(path) < 2:
-               return
-       begin = path[-2]
-       addValueSegmentToPixelTable( begin, point, pixelDictionary, value, width )
-
-def addSegmentToPixelTable( beginComplex, endComplex, pixelDictionary, shortenDistanceBegin, shortenDistanceEnd, width ):
-       'Add line segment to the pixel table.'
-       if abs( beginComplex - endComplex ) <= 0.0:
-               return
-       beginComplex /= width
-       endComplex /= width
-       if shortenDistanceBegin > 0.0:
-               endMinusBeginComplex = endComplex - beginComplex
-               endMinusBeginComplexLength = abs( endMinusBeginComplex )
-               if endMinusBeginComplexLength < shortenDistanceBegin:
-                       return
-               beginComplex = beginComplex + endMinusBeginComplex * shortenDistanceBegin / endMinusBeginComplexLength
-       if shortenDistanceEnd > 0.0:
-               beginMinusEndComplex = beginComplex - endComplex
-               beginMinusEndComplexLength = abs( beginMinusEndComplex )
-               if beginMinusEndComplexLength < 0.0:
-                       return
-               endComplex = endComplex + beginMinusEndComplex * shortenDistanceEnd / beginMinusEndComplexLength
-       deltaX = endComplex.real - beginComplex.real
-       deltaY = endComplex.imag - beginComplex.imag
-       isSteep = abs( deltaY ) > abs( deltaX )
-       if isSteep:
-               beginComplex = complex( beginComplex.imag, beginComplex.real )
-               endComplex = complex( endComplex.imag, endComplex.real )
-       if beginComplex.real > endComplex.real:
-               endComplex, beginComplex = beginComplex, endComplex
-       deltaX = endComplex.real - beginComplex.real
-       deltaY = endComplex.imag - beginComplex.imag
-       if deltaX > 0.0:
-               gradient = deltaY / deltaX
-       else:
-               gradient = 0.0
-               print('Warning, deltaX in addSegmentToPixelTable in euclidean is 0.')
-               print(beginComplex)
-               print(endComplex)
-               print(shortenDistanceBegin)
-               print(shortenDistanceEnd)
-               print(width)
-       xBegin = int(round(beginComplex.real))
-       xEnd = int(round(endComplex.real))
-       yIntersection = beginComplex.imag - beginComplex.real * gradient
-       if isSteep:
-               pixelDictionary[( int( round( beginComplex.imag ) ), xBegin)] = None
-               pixelDictionary[( int( round( endComplex.imag ) ), xEnd )] = None
-               for x in xrange( xBegin + 1, xEnd ):
-                       y = int( math.floor( yIntersection + x * gradient ) )
-                       pixelDictionary[(y, x)] = None
-                       pixelDictionary[(y + 1, x)] = None
-       else:
-               pixelDictionary[(xBegin, int( round( beginComplex.imag ) ) )] = None
-               pixelDictionary[(xEnd, int( round( endComplex.imag ) ) )] = None
-               for x in xrange( xBegin + 1, xEnd ):
-                       y = int( math.floor( yIntersection + x * gradient ) )
-                       pixelDictionary[(x, y)] = None
-                       pixelDictionary[(x, y + 1)] = None
-
-def addSquareTwoToPixelDictionary(pixelDictionary, point, value, width):
-       'Add square with two pixels around the center to pixel dictionary.'
-       point /= width
-       x = int(round(point.real))
-       y = int(round(point.imag))
-       for xStep in xrange(x - 2, x + 3):
-               for yStep in xrange(y - 2, y + 3):
-                       pixelDictionary[(xStep, yStep)] = value
-
-def addToThreadsFromLoop(extrusionHalfWidth, gcodeType, loop, oldOrderedLocation, skein):
-       'Add to threads from the last location from loop.'
-       loop = getLoopStartingClosest(extrusionHalfWidth, oldOrderedLocation.dropAxis(), loop)
-       oldOrderedLocation.x = loop[0].real
-       oldOrderedLocation.y = loop[0].imag
-       gcodeTypeStart = gcodeType
-       if isWiddershins(loop):
-               skein.distanceFeedRate.addLine('(<%s> outer )' % gcodeType)
-       else:
-               skein.distanceFeedRate.addLine('(<%s> inner )' % gcodeType)
-       skein.addGcodeFromThreadZ(loop + [loop[0]], oldOrderedLocation.z)
-       skein.distanceFeedRate.addLine('(</%s>)' % gcodeType)
-
-def addToThreadsRemove(extrusionHalfWidth, nestedRings, oldOrderedLocation, skein, threadSequence):
-       'Add to threads from the last location from nested rings.'
-       while len(nestedRings) > 0:
-               getTransferClosestNestedRing(extrusionHalfWidth, nestedRings, oldOrderedLocation, skein, threadSequence)
-
-def addValueSegmentToPixelTable( beginComplex, endComplex, pixelDictionary, value, width ):
-       'Add line segment to the pixel table.'
-       if abs( beginComplex - endComplex ) <= 0.0:
-               return
-       beginComplex /= width
-       endComplex /= width
-       deltaX = endComplex.real - beginComplex.real
-       deltaY = endComplex.imag - beginComplex.imag
-       isSteep = abs( deltaY ) > abs( deltaX )
-       if isSteep:
-               beginComplex = complex( beginComplex.imag, beginComplex.real )
-               endComplex = complex( endComplex.imag, endComplex.real )
-       if beginComplex.real > endComplex.real:
-               endComplex, beginComplex = beginComplex, endComplex
-       deltaX = endComplex.real - beginComplex.real
-       deltaY = endComplex.imag - beginComplex.imag
-       if deltaX > 0.0:
-               gradient = deltaY / deltaX
-       else:
-               gradient = 0.0
-               print('Warning, deltaX in addValueSegmentToPixelTable in euclidean is 0.')
-               print(beginComplex)
-               print(value)
-               print(endComplex)
-               print(width)
-       xBegin = int(round(beginComplex.real))
-       xEnd = int(round(endComplex.real))
-       yIntersection = beginComplex.imag - beginComplex.real * gradient
-       if isSteep:
-               pixelDictionary[(int( round( beginComplex.imag ) ), xBegin)] = value
-               pixelDictionary[(int( round( endComplex.imag ) ), xEnd)] = value
-               for x in xrange( xBegin + 1, xEnd ):
-                       y = int( math.floor( yIntersection + x * gradient ) )
-                       pixelDictionary[(y, x)] = value
-                       pixelDictionary[(y + 1, x)] = value
-       else:
-               pixelDictionary[(xBegin, int( round( beginComplex.imag ) ))] = value
-               pixelDictionary[(xEnd, int( round( endComplex.imag ) ))] = value
-               for x in xrange( xBegin + 1, xEnd ):
-                       y = int( math.floor( yIntersection + x * gradient ) )
-                       pixelDictionary[(x, y)] = value
-                       pixelDictionary[(x, y + 1)] = value
-
-def addValueToOutput(depth, keyInput, output, value):
-       'Add value to the output.'
-       depthStart = '  ' * depth
-       output.write('%s%s:' % (depthStart, keyInput))
-       if value.__class__ == dict:
-               output.write('\n')
-               keys = value.keys()
-               keys.sort()
-               for key in keys:
-                       addValueToOutput(depth + 1, key, output, value[key])
-               return
-       if value.__class__ == list:
-               output.write('\n')
-               for elementIndex, element in enumerate(value):
-                       addValueToOutput(depth + 1, elementIndex, output, element)
-               return
-       output.write(' %s\n' % value)
-
-def addXIntersectionIndexesFromLoopListsY( loopLists, xIntersectionIndexList, y ):
-       'Add the x intersection indexes for the loop lists.'
-       for loopListIndex in xrange( len(loopLists) ):
-               loopList = loopLists[ loopListIndex ]
-               addXIntersectionIndexesFromLoopsY( loopList, loopListIndex, xIntersectionIndexList, y )
-
-def addXIntersectionIndexesFromLoopsY( loops, solidIndex, xIntersectionIndexList, y ):
-       'Add the x intersection indexes for the loops.'
-       for loop in loops:
-               addXIntersectionIndexesFromLoopY( loop, solidIndex, xIntersectionIndexList, y )
-
-def addXIntersectionIndexesFromLoopY( loop, solidIndex, xIntersectionIndexList, y ):
-       'Add the x intersection indexes for a loop.'
-       for pointIndex in xrange(len(loop)):
-               pointFirst = loop[pointIndex]
-               pointSecond = loop[(pointIndex + 1) % len(loop)]
-               xIntersection = getXIntersectionIfExists( pointFirst, pointSecond, y )
-               if xIntersection != None:
-                       xIntersectionIndexList.append( XIntersectionIndex( solidIndex, xIntersection ) )
-
-def addXIntersectionIndexesFromSegment( index, segment, xIntersectionIndexList ):
-       'Add the x intersection indexes from the segment.'
-       for endpoint in segment:
-               xIntersectionIndexList.append( XIntersectionIndex( index, endpoint.point.real ) )
-
-def addXIntersectionIndexesFromSegments( index, segments, xIntersectionIndexList ):
-       'Add the x intersection indexes from the segments.'
-       for segment in segments:
-               addXIntersectionIndexesFromSegment( index, segment, xIntersectionIndexList )
-
-def addXIntersectionIndexesFromXIntersections( index, xIntersectionIndexList, xIntersections ):
-       'Add the x intersection indexes from the XIntersections.'
-       for xIntersection in xIntersections:
-               xIntersectionIndexList.append( XIntersectionIndex( index, xIntersection ) )
-
-def addXIntersections( loop, xIntersections, y ):
-       'Add the x intersections for a loop.'
-       for pointIndex in xrange(len(loop)):
-               pointFirst = loop[pointIndex]
-               pointSecond = loop[(pointIndex + 1) % len(loop)]
-               xIntersection = getXIntersectionIfExists( pointFirst, pointSecond, y )
-               if xIntersection != None:
-                       xIntersections.append( xIntersection )
-
-def addXIntersectionsFromLoopForTable(loop, xIntersectionsTable, width):
-       'Add the x intersections for a loop into a table.'
-       for pointIndex in xrange(len(loop)):
-               pointBegin = loop[pointIndex]
-               pointEnd = loop[(pointIndex + 1) % len(loop)]
-               if pointBegin.imag > pointEnd.imag:
-                       pointOriginal = pointBegin
-                       pointBegin = pointEnd
-                       pointEnd = pointOriginal
-               fillBegin = int( math.ceil( pointBegin.imag / width ) )
-               fillEnd = int( math.ceil( pointEnd.imag / width ) )
-               if fillEnd > fillBegin:
-                       secondMinusFirstComplex = pointEnd - pointBegin
-                       secondMinusFirstImaginaryOverReal = secondMinusFirstComplex.real / secondMinusFirstComplex.imag
-                       beginRealMinusImaginary = pointBegin.real - pointBegin.imag * secondMinusFirstImaginaryOverReal
-                       for fillLine in xrange( fillBegin, fillEnd ):
-                               y = fillLine * width
-                               xIntersection = y * secondMinusFirstImaginaryOverReal + beginRealMinusImaginary
-                               addElementToListDictionary( xIntersection, fillLine, xIntersectionsTable )
-
-def addXIntersectionsFromLoops(loops, xIntersections, y):
-       'Add the x intersections for the loops.'
-       for loop in loops:
-               addXIntersections(loop, xIntersections, y)
-
-def addXIntersectionsFromLoopsForTable(loops, xIntersectionsTable, width):
-       'Add the x intersections for a loop into a table.'
-       for loop in loops:
-               addXIntersectionsFromLoopForTable(loop, xIntersectionsTable, width)
-
-def compareSegmentLength( endpoint, otherEndpoint ):
-       'Get comparison in order to sort endpoints in ascending order of segment length.'
-       if endpoint.segmentLength > otherEndpoint.segmentLength:
-               return 1
-       if endpoint.segmentLength < otherEndpoint.segmentLength:
-               return - 1
-       return 0
-
-def concatenateRemovePath(connectedPaths, pathIndex, paths, pixelDictionary, segments, sharpestProduct, width):
-       'Get connected paths from paths.'
-       bottomSegment = segments[pathIndex]
-       path = paths[pathIndex]
-       if bottomSegment == None:
-               connectedPaths.append(path)
-               return
-       endpoints = getEndpointsFromSegments(segments[pathIndex + 1 :])
-       bottomSegmentEndpoint = bottomSegment[0]
-       nextEndpoint = bottomSegmentEndpoint.getClosestMissCheckEndpointPath(endpoints, bottomSegmentEndpoint.path, pixelDictionary, sharpestProduct, width)
-       if nextEndpoint == None:
-               bottomSegmentEndpoint = bottomSegment[1]
-               nextEndpoint = bottomSegmentEndpoint.getClosestMissCheckEndpointPath(endpoints, bottomSegmentEndpoint.path, pixelDictionary, sharpestProduct, width)
-       if nextEndpoint == None:
-               connectedPaths.append(path)
-               return
-       if len(bottomSegmentEndpoint.path) > 0 and len(nextEndpoint.path) > 0:
-               bottomEnd = bottomSegmentEndpoint.path[-1]
-               nextBegin = nextEndpoint.path[-1]
-               nextMinusBottomNormalized = getNormalized(nextBegin - bottomEnd)
-               if len( bottomSegmentEndpoint.path ) > 1:
-                       bottomPenultimate = bottomSegmentEndpoint.path[-2]
-                       if getDotProduct(getNormalized(bottomPenultimate - bottomEnd), nextMinusBottomNormalized) > 0.99:
-                               connectedPaths.append(path)
-                               return
-               if len( nextEndpoint.path ) > 1:
-                       nextPenultimate = nextEndpoint.path[-2]
-                       if getDotProduct(getNormalized(nextPenultimate - nextBegin), - nextMinusBottomNormalized) > 0.99:
-                               connectedPaths.append(path)
-                               return
-       nextEndpoint.path.reverse()
-       concatenatedPath = bottomSegmentEndpoint.path + nextEndpoint.path
-       paths[nextEndpoint.pathIndex] = concatenatedPath
-       segments[nextEndpoint.pathIndex] = getSegmentFromPath(concatenatedPath, nextEndpoint.pathIndex)
-       addValueSegmentToPixelTable(bottomSegmentEndpoint.point, nextEndpoint.point, pixelDictionary, None, width)
-
-def getAngleAroundZAxisDifference( subtractFromVec3, subtractVec3 ):
-       'Get the angle around the Z axis difference between a pair of Vector3s.'
-       subtractVectorMirror = complex( subtractVec3.x , - subtractVec3.y )
-       differenceVector = getRoundZAxisByPlaneAngle( subtractVectorMirror, subtractFromVec3 )
-       return math.atan2( differenceVector.y, differenceVector.x )
-
-def getAngleDifferenceByComplex( subtractFromComplex, subtractComplex ):
-       'Get the angle between a pair of normalized complexes.'
-       subtractComplexMirror = complex( subtractComplex.real , - subtractComplex.imag )
-       differenceComplex = subtractComplexMirror * subtractFromComplex
-       return math.atan2( differenceComplex.imag, differenceComplex.real )
-
-def getAreaLoop(loop):
-       'Get the area of a complex polygon.'
-       areaLoopDouble = 0.0
-       for pointIndex, point in enumerate(loop):
-               pointEnd  = loop[(pointIndex + 1) % len(loop)]
-               areaLoopDouble += point.real * pointEnd.imag - pointEnd.real * point.imag
-       return 0.5 * areaLoopDouble
-
-def getAreaLoopAbsolute(loop):
-       'Get the absolute area of a complex polygon.'
-       return abs(getAreaLoop(loop))
-
-def getAreaLoops(loops):
-       'Get the area of a list of complex polygons.'
-       areaLoops = 0.0
-       for loop in loops:
-               areaLoops += getAreaLoop(loop)
-       return areaLoops
-
-def getAreaVector3LoopAbsolute(loop):
-       'Get the absolute area of a vector3 polygon.'
-       return getAreaLoopAbsolute(getComplexPath(loop))
-
-def getAroundLoop(begin, end, loop):
-       'Get an arc around a loop.'
-       aroundLoop = []
-       if end <= begin:
-               end += len(loop)
-       for pointIndex in xrange(begin, end):
-               aroundLoop.append(loop[pointIndex % len(loop)])
-       return aroundLoop
-
-def getAwayPath(path, radius):
-       'Get a path with only the points that are far enough away from each other, except for the last point.'
-       if len(path) < 2:
-               return path
-       lastPoint = path[-1]
-       awayPath = getAwayPoints(path, radius)
-       if len(awayPath) == 0:
-               return [lastPoint]
-       if abs(lastPoint - awayPath[-1]) > 0.001 * radius:
-               awayPath.append(lastPoint)
-       return awayPath
-
-def getAwayPoints(points, radius):
-       'Get a path with only the points that are far enough away from each other.'
-       awayPoints = []
-       oneOverOverlapDistance = 1000.0 / radius
-       pixelDictionary = {}
-       for point in points:
-               x = int(point.real * oneOverOverlapDistance)
-               y = int(point.imag * oneOverOverlapDistance)
-               if not getSquareIsOccupied(pixelDictionary, x, y):
-                       awayPoints.append(point)
-                       pixelDictionary[(x, y)] = None
-       return awayPoints
-
-def getBooleanFromDictionary(defaultBoolean, dictionary, key):
-       'Get boolean from the dictionary and key.'
-       if key not in dictionary:
-               return defaultBoolean
-       return getBooleanFromValue(dictionary[key])
-
-def getBooleanFromValue(value):
-       'Get boolean from the word.'
-       firstCharacter = str(value).lower().lstrip()[: 1]
-       return firstCharacter == 't' or firstCharacter == '1'
-
-def getBottomByPath(path):
-       'Get the bottom of the path.'
-       bottom = 987654321987654321.0
-       for point in path:
-               bottom = min(bottom, point.z)
-       return bottom
-
-def getBottomByPaths(paths):
-       'Get the bottom of the paths.'
-       bottom = 987654321987654321.0
-       for path in paths:
-               for point in path:
-                       bottom = min(bottom, point.z)
-       return bottom
-
-def getClippedAtEndLoopPath( clip, loopPath ):
-       'Get a clipped loop path.'
-       if clip <= 0.0:
-               return loopPath
-       loopPathLength = getPathLength(loopPath)
-       clip = min( clip, 0.3 * loopPathLength )
-       lastLength = 0.0
-       pointIndex = 0
-       totalLength = 0.0
-       clippedLength = loopPathLength - clip
-       while totalLength < clippedLength and pointIndex < len(loopPath) - 1:
-               firstPoint = loopPath[pointIndex]
-               secondPoint  = loopPath[pointIndex + 1]
-               pointIndex += 1
-               lastLength = totalLength
-               totalLength += abs(firstPoint - secondPoint)
-       remainingLength = clippedLength - lastLength
-       clippedLoopPath = loopPath[ : pointIndex ]
-       ultimateClippedPoint = loopPath[pointIndex]
-       penultimateClippedPoint = clippedLoopPath[-1]
-       segment = ultimateClippedPoint - penultimateClippedPoint
-       segmentLength = abs(segment)
-       if segmentLength <= 0.0:
-               return clippedLoopPath
-       newUltimatePoint = penultimateClippedPoint + segment * remainingLength / segmentLength
-       return clippedLoopPath + [newUltimatePoint]
-
-def getClippedLoopPath(clip, loopPath):
-       'Get a clipped loop path.'
-       if clip <= 0.0:
-               return loopPath
-       loopPathLength = getPathLength(loopPath)
-       clip = min(clip, 0.3 * loopPathLength)
-       lastLength = 0.0
-       pointIndex = 0
-       totalLength = 0.0
-       while totalLength < clip and pointIndex < len(loopPath) - 1:
-               firstPoint = loopPath[pointIndex]
-               secondPoint  = loopPath[pointIndex + 1]
-               pointIndex += 1
-               lastLength = totalLength
-               totalLength += abs(firstPoint - secondPoint)
-       remainingLength = clip - lastLength
-       clippedLoopPath = loopPath[pointIndex :]
-       ultimateClippedPoint = clippedLoopPath[0]
-       penultimateClippedPoint = loopPath[pointIndex - 1]
-       segment = ultimateClippedPoint - penultimateClippedPoint
-       segmentLength = abs(segment)
-       loopPath = clippedLoopPath
-       if segmentLength > 0.0:
-               newUltimatePoint = penultimateClippedPoint + segment * remainingLength / segmentLength
-               loopPath = [newUltimatePoint] + loopPath
-       return getClippedAtEndLoopPath(clip, loopPath)
-
-def getClippedSimplifiedLoopPath(clip, loopPath, radius):
-       'Get a clipped and simplified loop path.'
-       return getSimplifiedPath(getClippedLoopPath(clip, loopPath), radius)
-
-def getClosestDistanceIndexToLine(point, loop):
-       'Get the distance squared to the closest segment of the loop and index of that segment.'
-       smallestDistance = 987654321987654321.0
-       closestDistanceIndex = None
-       for pointIndex in xrange(len(loop)):
-               segmentBegin = loop[pointIndex]
-               segmentEnd = loop[(pointIndex + 1) % len(loop)]
-               distance = getDistanceToPlaneSegment(segmentBegin, segmentEnd, point)
-               if distance < smallestDistance:
-                       smallestDistance = distance
-                       closestDistanceIndex = DistanceIndex(distance, pointIndex)
-       return closestDistanceIndex
-
-def getClosestPointOnSegment(segmentBegin, segmentEnd, point):
-       'Get the closest point on the segment.'
-       segmentDifference = segmentEnd - segmentBegin
-       if abs(segmentDifference) <= 0.0:
-               return segmentBegin
-       pointMinusSegmentBegin = point - segmentBegin
-       beginPlaneDot = getDotProduct(pointMinusSegmentBegin, segmentDifference)
-       differencePlaneDot = getDotProduct(segmentDifference, segmentDifference)
-       intercept = beginPlaneDot / differencePlaneDot
-       intercept = max(intercept, 0.0)
-       intercept = min(intercept, 1.0)
-       return segmentBegin + segmentDifference * intercept
-
-def getComplexByCommaString( valueCommaString ):
-       'Get the commaString as a complex.'
-       try:
-               splitLine = valueCommaString.replace(',', ' ').split()
-               return complex( float( splitLine[0] ), float(splitLine[1]) )
-       except:
-               pass
-       return None
-
-def getComplexByWords(words, wordIndex=0):
-       'Get the complex by the first two words.'
-       try:
-               return complex(float(words[wordIndex]), float(words[wordIndex + 1]))
-       except:
-               pass
-       return None
-
-def getComplexDefaultByDictionary( defaultComplex, dictionary, key ):
-       'Get the value as a complex.'
-       if key in dictionary:
-               return complex( dictionary[key].strip().replace('(', '').replace(')', '') )
-       return defaultComplex
-
-def getComplexDefaultByDictionaryKeys( defaultComplex, dictionary, keyX, keyY ):
-       'Get the value as a complex.'
-       x = getFloatDefaultByDictionary( defaultComplex.real, dictionary, keyX )
-       y = getFloatDefaultByDictionary( defaultComplex.real, dictionary, keyY )
-       return complex(x, y)
-
-def getComplexPath(vector3Path):
-       'Get the complex path from the vector3 path.'
-       complexPath = []
-       for point in vector3Path:
-               complexPath.append(point.dropAxis())
-       return complexPath
-
-def getComplexPathByMultiplier(multiplier, path):
-       'Get the multiplied complex path.'
-       complexPath = []
-       for point in path:
-               complexPath.append(multiplier * point)
-       return complexPath
-
-def getComplexPaths(vector3Paths):
-       'Get the complex paths from the vector3 paths.'
-       complexPaths = []
-       for vector3Path in vector3Paths:
-               complexPaths.append(getComplexPath(vector3Path))
-       return complexPaths
-
-def getComplexPolygon(center, radius, sides, startAngle=0.0):
-       'Get the complex polygon.'
-       complexPolygon = []
-       sideAngle = 2.0 * math.pi / float(sides)
-       for side in xrange(abs(sides)):
-               unitPolar = getWiddershinsUnitPolar(startAngle)
-               complexPolygon.append(unitPolar * radius + center)
-               startAngle += sideAngle
-       return complexPolygon
-
-def getComplexPolygonByComplexRadius(radius, sides, startAngle=0.0):
-       'Get the complex polygon.'
-       complexPolygon = []
-       sideAngle = 2.0 * math.pi / float(sides)
-       for side in xrange(abs(sides)):
-               unitPolar = getWiddershinsUnitPolar(startAngle)
-               complexPolygon.append(complex(unitPolar.real * radius.real, unitPolar.imag * radius.imag))
-               startAngle += sideAngle
-       return complexPolygon
-
-def getComplexPolygonByStartEnd(endAngle, radius, sides, startAngle=0.0):
-       'Get the complex polygon by start and end angle.'
-       angleExtent = endAngle - startAngle
-       sideAngle = 2.0 * math.pi / float(sides)
-       sides = int(math.ceil(abs(angleExtent / sideAngle)))
-       sideAngle = angleExtent / float(sides)
-       complexPolygon = []
-       for side in xrange(abs(sides) + 1):
-               unitPolar = getWiddershinsUnitPolar(startAngle)
-               complexPolygon.append(unitPolar * radius)
-               startAngle += sideAngle
-       return getLoopWithoutCloseEnds(0.000001 * radius, complexPolygon)
-
-def getConcatenatedList(originalLists):
-       'Get the lists as one concatenated list.'
-       concatenatedList = []
-       for originalList in originalLists:
-               concatenatedList += originalList
-       return concatenatedList
-
-def getConnectedPaths(paths, pixelDictionary, sharpestProduct, width):
-       'Get connected paths from paths.'
-       if len(paths) < 2:
-               return paths
-       connectedPaths = []
-       segments = []
-       for pathIndex in xrange(len(paths)):
-               path = paths[pathIndex]
-               segments.append(getSegmentFromPath(path, pathIndex))
-       for pathIndex in xrange(0, len(paths) - 1):
-               concatenateRemovePath(connectedPaths, pathIndex, paths, pixelDictionary, segments, sharpestProduct, width)
-       connectedPaths.append(paths[-1])
-       return connectedPaths
-
-def getCrossProduct(firstComplex, secondComplex):
-       'Get z component cross product of a pair of complexes.'
-       return firstComplex.real * secondComplex.imag - firstComplex.imag * secondComplex.real
-
-def getDecimalPlacesCarried(extraDecimalPlaces, value):
-       'Get decimal places carried by the decimal places of the value plus the extraDecimalPlaces.'
-       return max(0, 1 + int(math.ceil(extraDecimalPlaces - math.log10(value))))
-
-def getDiagonalFlippedLoop(loop):
-       'Get loop flipped over the dialogonal, in other words with the x and y swapped.'
-       diagonalFlippedLoop = []
-       for point in loop:
-               diagonalFlippedLoop.append( complex( point.imag, point.real ) )
-       return diagonalFlippedLoop
-
-def getDiagonalFlippedLoops(loops):
-       'Get loops flipped over the dialogonal, in other words with the x and y swapped.'
-       diagonalFlippedLoops = []
-       for loop in loops:
-               diagonalFlippedLoops.append( getDiagonalFlippedLoop(loop) )
-       return diagonalFlippedLoops
-
-def getDictionaryString(dictionary):
-       'Get the dictionary string.'
-       output = cStringIO.StringIO()
-       keys = dictionary.keys()
-       keys.sort()
-       for key in keys:
-               addValueToOutput(0, key, output, dictionary[key])
-       return output.getvalue()
-
-def getDistanceToLine(begin, end, point):
-       'Get the distance from a vector3 point to an infinite line.'
-       pointMinusBegin = point - begin
-       if begin == end:
-               return abs(pointMinusBegin)
-       endMinusBegin = end - begin
-       return abs(endMinusBegin.cross(pointMinusBegin)) / abs(endMinusBegin)
-
-def getDistanceToLineByPath(begin, end, path):
-       'Get the maximum distance from a path to an infinite line.'
-       distanceToLine = -987654321.0
-       for point in path:
-               distanceToLine = max(getDistanceToLine(begin, end, point), distanceToLine)
-       return distanceToLine
-
-def getDistanceToLineByPaths(begin, end, paths):
-       'Get the maximum distance from paths to an infinite line.'
-       distanceToLine = -987654321.0
-       for path in paths:
-               distanceToLine = max(getDistanceToLineByPath(begin, end, path), distanceToLine)
-       return distanceToLine
-
-def getDistanceToPlaneSegment( segmentBegin, segmentEnd, point ):
-       'Get the distance squared from a point to the x & y components of a segment.'
-       segmentDifference = segmentEnd - segmentBegin
-       pointMinusSegmentBegin = point - segmentBegin
-       beginPlaneDot = getDotProduct( pointMinusSegmentBegin, segmentDifference )
-       if beginPlaneDot <= 0.0:
-               return abs( point - segmentBegin ) * abs( point - segmentBegin )
-       differencePlaneDot = getDotProduct( segmentDifference, segmentDifference )
-       if differencePlaneDot <= beginPlaneDot:
-               return abs( point - segmentEnd ) * abs( point - segmentEnd )
-       intercept = beginPlaneDot / differencePlaneDot
-       interceptPerpendicular = segmentBegin + segmentDifference * intercept
-       return abs( point - interceptPerpendicular ) * abs( point - interceptPerpendicular )
-
-def getDotProduct(firstComplex, secondComplex):
-       'Get the dot product of a pair of complexes.'
-       return firstComplex.real * secondComplex.real + firstComplex.imag * secondComplex.imag
-
-def getDotProductPlusOne( firstComplex, secondComplex ):
-       'Get the dot product plus one of the x and y components of a pair of Vector3s.'
-       return 1.0 + getDotProduct( firstComplex, secondComplex )
-
-def getDurationString( seconds ):
-       'Get the duration string.'
-       secondsRounded = int( round( seconds ) )
-       durationString = getPluralString( secondsRounded % 60, 'second')
-       if seconds < 60:
-               return durationString
-       durationString =  '%s %s' % ( getPluralString( ( secondsRounded / 60 ) % 60, 'minute'), durationString )
-       if seconds < 3600:
-               return durationString
-       return  '%s %s' % ( getPluralString( secondsRounded / 3600, 'hour'), durationString )
-
-def getEndpointFromPath( path, pathIndex ):
-       'Get endpoint segment from a path.'
-       begin = path[-1]
-       end = path[-2]
-       endpointBegin = Endpoint()
-       endpointEnd = Endpoint().getFromOtherPoint( endpointBegin, end )
-       endpointBegin.getFromOtherPoint( endpointEnd, begin )
-       endpointBegin.path = path
-       endpointBegin.pathIndex = pathIndex
-       return endpointBegin
-
-def getEndpointsFromSegments( segments ):
-       'Get endpoints from segments.'
-       endpoints = []
-       for segment in segments:
-               for endpoint in segment:
-                       endpoints.append( endpoint )
-       return endpoints
-
-def getEndpointsFromSegmentTable( segmentTable ):
-       'Get the endpoints from the segment table.'
-       endpoints = []
-       segmentTableKeys = segmentTable.keys()
-       segmentTableKeys.sort()
-       for segmentTableKey in segmentTableKeys:
-               for segment in segmentTable[ segmentTableKey ]:
-                       for endpoint in segment:
-                               endpoints.append( endpoint )
-       return endpoints
-
-def getEnumeratorKeys(enumerator, keys):
-       'Get enumerator keys.'
-       if len(keys) == 1:
-               return keys[0]
-       return getEnumeratorKeysExceptForOneArgument(enumerator, keys)
-
-def getEnumeratorKeysAlwaysList(enumerator, keys):
-       'Get enumerator keys.'
-       if keys.__class__ != list:
-               return [keys]
-       if len(keys) == 1:
-               return keys
-       return getEnumeratorKeysExceptForOneArgument(enumerator, keys)
-
-def getEnumeratorKeysExceptForOneArgument(enumerator, keys):
-       'Get enumerator keys, except when there is one argument.'
-       if len(keys) == 0:
-               return range(0, len(enumerator))
-       beginIndex = keys[0]
-       endIndex = keys[1]
-       if len(keys) == 2:
-               if beginIndex == None:
-                       beginIndex = 0
-               if endIndex == None:
-                       endIndex = len(enumerator)
-               return range(beginIndex, endIndex)
-       step = keys[2]
-       beginIndexDefault = 0
-       endIndexDefault = len(enumerator)
-       if step < 0:
-               beginIndexDefault = endIndexDefault - 1
-               endIndexDefault = -1
-       if beginIndex == None:
-               beginIndex = beginIndexDefault
-       if endIndex == None:
-               endIndex = endIndexDefault
-       return range(beginIndex, endIndex, step)
-
-def getFillOfSurroundings(nestedRings, penultimateFillLoops):
-       'Get extra fill loops of nested rings.'
-       fillOfSurroundings = []
-       for nestedRing in nestedRings:
-               fillOfSurroundings += nestedRing.getFillLoops(penultimateFillLoops)
-       return fillOfSurroundings
-
-def getFlattenedNestedRings(nestedRings):
-       'Get flattened nested rings.'
-       flattenedNestedRings = []
-       for nestedRing in nestedRings:
-               nestedRing.addFlattenedNestedRings(flattenedNestedRings)
-       return flattenedNestedRings
-
-def getFloatDefaultByDictionary( defaultFloat, dictionary, key ):
-       'Get the value as a float.'
-       evaluatedFloat = None
-       if key in dictionary:
-               evaluatedFloat = getFloatFromValue(dictionary[key])
-       if evaluatedFloat == None:
-               return defaultFloat
-       return evaluatedFloat
-
-def getFloatFromValue(value):
-       'Get the value as a float.'
-       try:
-               return float(value)
-       except:
-               pass
-       return None
-
-def getFourSignificantFigures(number):
-       'Get number rounded to four significant figures as a string.'
-       if number == None:
-               return None
-       absoluteNumber = abs(number)
-       if absoluteNumber >= 100.0:
-               return getRoundedToPlacesString( 2, number )
-       if absoluteNumber < 0.000000001:
-               return getRoundedToPlacesString( 13, number )
-       return getRoundedToPlacesString( 3 - math.floor( math.log10( absoluteNumber ) ), number )
-
-def getHalfSimplifiedLoop( loop, radius, remainder ):
-       'Get the loop with half of the points inside the channel removed.'
-       if len(loop) < 2:
-               return loop
-       channelRadius = abs(radius * .01)
-       simplified = []
-       addIndex = 0
-       if remainder == 1:
-               addIndex = len(loop) - 1
-       for pointIndex in xrange(len(loop)):
-               point = loop[pointIndex]
-               if pointIndex % 2 == remainder or pointIndex == addIndex:
-                       simplified.append(point)
-               elif not isWithinChannel( channelRadius, pointIndex, loop ):
-                       simplified.append(point)
-       return simplified
-
-def getHalfSimplifiedPath(path, radius, remainder):
-       'Get the path with half of the points inside the channel removed.'
-       if len(path) < 2:
-               return path
-       channelRadius = abs(radius * .01)
-       simplified = [path[0]]
-       for pointIndex in xrange(1, len(path) - 1):
-               point = path[pointIndex]
-               if pointIndex % 2 == remainder:
-                       simplified.append(point)
-               elif not isWithinChannel(channelRadius, pointIndex, path):
-                       simplified.append(point)
-       simplified.append(path[-1])
-       return simplified
-
-def getHorizontallyBoundedPath(horizontalBegin, horizontalEnd, path):
-       'Get horizontally bounded path.'
-       horizontallyBoundedPath = []
-       for pointIndex, point in enumerate(path):
-               begin = None
-               previousIndex = pointIndex - 1
-               if previousIndex >= 0:
-                       begin = path[previousIndex]
-               end = None
-               nextIndex = pointIndex + 1
-               if nextIndex < len(path):
-                       end = path[nextIndex]
-               addHorizontallyBoundedPoint(begin, point, end, horizontalBegin, horizontalEnd, horizontallyBoundedPath)
-       return horizontallyBoundedPath
-
-def getIncrementFromRank( rank ):
-       'Get the increment from the rank which is 0 at 1 and increases by three every power of ten.'
-       rankZone = int( math.floor( rank / 3 ) )
-       rankModulo = rank % 3
-       powerOfTen = pow( 10, rankZone )
-       moduloMultipliers = ( 1, 2, 5 )
-       return float( powerOfTen * moduloMultipliers[ rankModulo ] )
-
-def getInsidesAddToOutsides( loops, outsides ):
-       'Add loops to either the insides or outsides.'
-       insides = []
-       for loopIndex in xrange( len(loops) ):
-               loop = loops[loopIndex]
-               if isInsideOtherLoops( loopIndex, loops ):
-                       insides.append(loop)
-               else:
-                       outsides.append(loop)
-       return insides
-
-def getIntermediateLocation( alongWay, begin, end ):
-       'Get the intermediate location between begin and end.'
-       return begin * ( 1.0 - alongWay ) + end * alongWay
-
-def getIntersectionOfXIntersectionIndexes( totalSolidSurfaceThickness, xIntersectionIndexList ):
-       'Get x intersections from surrounding layers.'
-       xIntersectionList = []
-       solidTable = {}
-       solid = False
-       xIntersectionIndexList.sort()
-       for xIntersectionIndex in xIntersectionIndexList:
-               toggleHashtable(solidTable, xIntersectionIndex.index, '')
-               oldSolid = solid
-               solid = len(solidTable) >= totalSolidSurfaceThickness
-               if oldSolid != solid:
-                       xIntersectionList.append(xIntersectionIndex.x)
-       return xIntersectionList
-
-def getIntersectionOfXIntersectionsTables(xIntersectionsTables):
-       'Get the intersection of the XIntersections tables.'
-       if len(xIntersectionsTables) == 0:
-               return {}
-       intersectionOfXIntersectionsTables = {}
-       firstIntersectionTable = xIntersectionsTables[0]
-       for firstIntersectionTableKey in firstIntersectionTable.keys():
-               xIntersectionIndexList = []
-               for xIntersectionsTableIndex in xrange(len(xIntersectionsTables)):
-                       xIntersectionsTable = xIntersectionsTables[xIntersectionsTableIndex]
-                       if firstIntersectionTableKey in xIntersectionsTable:
-                               addXIntersectionIndexesFromXIntersections(xIntersectionsTableIndex, xIntersectionIndexList, xIntersectionsTable[firstIntersectionTableKey])
-               xIntersections = getIntersectionOfXIntersectionIndexes(len(xIntersectionsTables), xIntersectionIndexList)
-               if len(xIntersections) > 0:
-                       intersectionOfXIntersectionsTables[firstIntersectionTableKey] = xIntersections
-       return intersectionOfXIntersectionsTables
-
-def getIntFromValue(value):
-       'Get the value as an int.'
-       try:
-               return int(value)
-       except:
-               pass
-       return None
-
-def getIsInFilledRegion(loops, point):
-       'Determine if the point is in the filled region of the loops.'
-       return getNumberOfIntersectionsToLeftOfLoops(loops, point) % 2 == 1
-
-def getIsInFilledRegionByPaths(loops, paths):
-       'Determine if the point of any path is in the filled region of the loops.'
-       for path in paths:
-               if len(path) > 0:
-                       if getIsInFilledRegion(loops, path[0]):
-                               return True
-       return False
-
-def getIsRadianClose(firstRadian, secondRadian):
-       'Determine if the firstRadian is close to the secondRadian.'
-       return abs(math.pi - abs(math.pi - ((firstRadian - secondRadian) % (math.pi + math.pi) ))) < 0.000001
-
-def getIsWiddershinsByVector3( polygon ):
-       'Determine if the polygon goes round in the widdershins direction.'
-       return isWiddershins( getComplexPath( polygon ) )
-
-def getJoinOfXIntersectionIndexes( xIntersectionIndexList ):
-       'Get joined x intersections from surrounding layers.'
-       xIntersections = []
-       solidTable = {}
-       solid = False
-       xIntersectionIndexList.sort()
-       for xIntersectionIndex in xIntersectionIndexList:
-               toggleHashtable(solidTable, xIntersectionIndex.index, '')
-               oldSolid = solid
-               solid = len(solidTable) > 0
-               if oldSolid != solid:
-                       xIntersections.append(xIntersectionIndex.x)
-       return xIntersections
-
-def getLargestLoop(loops):
-       'Get largest loop from loops.'
-       largestArea = -987654321.0
-       largestLoop = []
-       for loop in loops:
-               loopArea = abs(getAreaLoopAbsolute(loop))
-               if loopArea > largestArea:
-                       largestArea = loopArea
-                       largestLoop = loop
-       return largestLoop
-
-def getLeftPoint(points):
-       'Get the leftmost complex point in the points.'
-       leftmost = 987654321.0
-       leftPointComplex = None
-       for pointComplex in points:
-               if pointComplex.real < leftmost:
-                       leftmost = pointComplex.real
-                       leftPointComplex = pointComplex
-       return leftPointComplex
-
-def getLeftPointIndex(points):
-       'Get the index of the leftmost complex point in the points.'
-       if len(points) < 1:
-               return None
-       leftPointIndex = 0
-       for pointIndex in xrange( len(points) ):
-               if points[pointIndex].real < points[ leftPointIndex ].real:
-                       leftPointIndex = pointIndex
-       return leftPointIndex
-
-def getListTableElements( listDictionary ):
-       'Get all the element in a list table.'
-       listDictionaryElements = []
-       for listDictionaryValue in listDictionary.values():
-               listDictionaryElements += listDictionaryValue
-       return listDictionaryElements
-
-def getLoopCentroid(polygonComplex):
-       'Get the area of a complex polygon using http://en.wikipedia.org/wiki/Centroid.'
-       polygonDoubleArea = 0.0
-       polygonTorque = 0.0
-       for pointIndex in xrange( len(polygonComplex) ):
-               pointBegin = polygonComplex[pointIndex]
-               pointEnd  = polygonComplex[ (pointIndex + 1) % len(polygonComplex) ]
-               doubleArea = pointBegin.real * pointEnd.imag - pointEnd.real * pointBegin.imag
-               doubleCenter = complex( pointBegin.real + pointEnd.real, pointBegin.imag + pointEnd.imag )
-               polygonDoubleArea += doubleArea
-               polygonTorque += doubleArea * doubleCenter
-       torqueMultiplier = 0.333333333333333333333333 / polygonDoubleArea
-       return polygonTorque * torqueMultiplier
-
-def getLoopConvex(points):
-       'Get convex hull of points using gift wrap algorithm.'
-       loopConvex = []
-       pointSet = set()
-       for point in points:
-               if point not in pointSet:
-                       pointSet.add(point)
-                       loopConvex.append(point)
-       if len(loopConvex) < 4:
-               return loopConvex
-       leftPoint = getLeftPoint(loopConvex)
-       lastPoint = leftPoint
-       pointSet.remove(leftPoint)
-       loopConvex = [leftPoint]
-       lastSegment = complex(0.0, 1.0)
-       while True:
-               greatestDotProduct = -9.9
-               greatestPoint = None
-               greatestSegment = None
-               if len(loopConvex) > 2:
-                       nextSegment = getNormalized(leftPoint - lastPoint)
-                       if abs(nextSegment) > 0.0:
-                               greatestDotProduct = getDotProduct(nextSegment, lastSegment)
-               for point in pointSet:
-                       nextSegment = getNormalized(point - lastPoint)
-                       if abs(nextSegment) > 0.0:
-                               dotProduct = getDotProduct(nextSegment, lastSegment)
-                               if dotProduct > greatestDotProduct:
-                                       greatestDotProduct = dotProduct
-                                       greatestPoint = point
-                                       greatestSegment = nextSegment
-               if greatestPoint == None:
-                       return loopConvex
-               lastPoint = greatestPoint
-               loopConvex.append(greatestPoint)
-               pointSet.remove(greatestPoint)
-               lastSegment = greatestSegment
-       return loopConvex
-
-def getLoopConvexCentroid(polygonComplex):
-       'Get centroid of the convex hull of a complex polygon.'
-       return getLoopCentroid( getLoopConvex(polygonComplex) )
-
-def getLoopInsideContainingLoop( containingLoop, loops ):
-       'Get a loop that is inside the containing loop.'
-       for loop in loops:
-               if loop != containingLoop:
-                       if isPathInsideLoop( containingLoop, loop ):
-                               return loop
-       return None
-
-def getLoopLength( polygon ):
-       'Get the length of a polygon perimeter.'
-       polygonLength = 0.0
-       for pointIndex in xrange( len( polygon ) ):
-               point = polygon[pointIndex]
-               secondPoint  = polygon[ (pointIndex + 1) % len( polygon ) ]
-               polygonLength += abs( point - secondPoint )
-       return polygonLength
-
-def getLoopStartingClosest(extrusionHalfWidth, location, loop):
-       'Add to threads from the last location from loop.'
-       closestIndex = getClosestDistanceIndexToLine(location, loop).index
-       loop = getAroundLoop(closestIndex, closestIndex, loop)
-       closestPoint = getClosestPointOnSegment(loop[0], loop[1], location)
-       if abs(closestPoint - loop[0]) > extrusionHalfWidth and abs(closestPoint - loop[1]) > extrusionHalfWidth:
-               loop = [closestPoint] + loop[1 :] + [loop[0]]
-       elif abs(closestPoint - loop[0]) > abs(closestPoint - loop[1]):
-               loop = loop[1 :] + [loop[0]]
-       return loop
-
-def getLoopWithoutCloseEnds(close, loop):
-       'Get loop without close ends.'
-       if len(loop) < 2:
-               return loop
-       if abs(loop[0] - loop[-1]) > close:
-               return loop
-       return loop[: -1]
-
-def getLoopWithoutCloseSequentialPoints(close, loop):
-       'Get loop without close sequential points.'
-       if len(loop) < 2:
-               return loop
-       lastPoint = loop[-1]
-       loopWithoutCloseSequentialPoints = []
-       for point in loop:
-               if abs(point - lastPoint) > close:
-                       loopWithoutCloseSequentialPoints.append(point)
-               lastPoint = point
-       return loopWithoutCloseSequentialPoints
-
-def getMaximum(firstComplex, secondComplex):
-       'Get a complex with each component the maximum of the respective components of a pair of complexes.'
-       return complex(max(firstComplex.real, secondComplex.real), max(firstComplex.imag, secondComplex.imag))
-
-def getMaximumByComplexPath(path):
-       'Get a complex with each component the maximum of the respective components of a complex path.'
-       maximum = complex(-987654321987654321.0, -987654321987654321.0)
-       for point in path:
-               maximum = getMaximum(maximum, point)
-       return maximum
-
-def getMaximumByComplexPaths(paths):
-       'Get a complex with each component the maximum of the respective components of complex paths.'
-       maximum = complex(-987654321987654321.0, -987654321987654321.0)
-       for path in paths:
-               for point in path:
-                       maximum = getMaximum(maximum, point)
-       return maximum
-
-def getMaximumByVector3Path(path):
-       'Get a vector3 with each component the maximum of the respective components of a vector3 path.'
-       maximum = Vector3(-987654321987654321.0, -987654321987654321.0, -987654321987654321.0)
-       for point in path:
-               maximum.maximize(point)
-       return maximum
-
-def getMaximumByVector3Paths(paths):
-       'Get a complex with each component the maximum of the respective components of a complex path.'
-       maximum = Vector3(-987654321987654321.0, -987654231987654321.0, -987654321987654321.0)
-       for path in paths:
-               for point in path:
-                       maximum.maximize(point)
-       return maximum
-
-def getMaximumSpan(loop):
-       'Get the maximum span of the loop.'
-       extent = getMaximumByComplexPath(loop) - getMinimumByComplexPath(loop)
-       return max(extent.real, extent.imag)
-
-def getMinimum(firstComplex, secondComplex):
-       'Get a complex with each component the minimum of the respective components of a pair of complexes.'
-       return complex(min(firstComplex.real, secondComplex.real), min(firstComplex.imag, secondComplex.imag))
-
-def getMinimumByComplexPath(path):
-       'Get a complex with each component the minimum of the respective components of a complex path.'
-       minimum = complex(987654321987654321.0, 987654321987654321.0)
-       for point in path:
-               minimum = getMinimum(minimum, point)
-       return minimum
-
-def getMinimumByComplexPaths(paths):
-       'Get a complex with each component the minimum of the respective components of complex paths.'
-       minimum = complex(987654321987654321.0, 987654321987654321.0)
-       for path in paths:
-               for point in path:
-                       minimum = getMinimum(minimum, point)
-       return minimum
-
-def getMinimumByVector3Path(path):
-       'Get a vector3 with each component the minimum of the respective components of a vector3 path.'
-       minimum = Vector3(987654321987654321.0, 987654321987654321.0, 987654321987654321.0)
-       for point in path:
-               minimum.minimize(point)
-       return minimum
-
-def getMinimumByVector3Paths(paths):
-       'Get a complex with each component the minimum of the respective components of a complex path.'
-       minimum = Vector3(987654321987654321.0, 987654321987654321.0, 987654321987654321.0)
-       for path in paths:
-               for point in path:
-                       minimum.minimize(point)
-       return minimum
-
-def getMirrorPath(path):
-       "Get mirror path."
-       close = 0.001 * getPathLength(path)
-       for pointIndex in xrange(len(path) - 1, -1, -1):
-               point = path[pointIndex]
-               flipPoint = complex(-point.real, point.imag)
-               if abs(flipPoint - path[-1]) > close:
-                       path.append(flipPoint)
-       return path
-
-def getNormal(begin, center, end):
-       'Get normal.'
-       centerMinusBegin = (center - begin).getNormalized()
-       endMinusCenter = (end - center).getNormalized()
-       return centerMinusBegin.cross(endMinusCenter)
-
-def getNormalByPath(path):
-       'Get normal by path.'
-       totalNormal = Vector3()
-       for pointIndex, point in enumerate(path):
-               center = path[(pointIndex + 1) % len(path)]
-               end = path[(pointIndex + 2) % len(path)]
-               totalNormal += getNormalWeighted(point, center, end)
-       return totalNormal.getNormalized()
-
-def getNormalized(complexNumber):
-       'Get the normalized complex.'
-       complexNumberLength = abs(complexNumber)
-       if complexNumberLength > 0.0:
-               return complexNumber / complexNumberLength
-       return complexNumber
-
-def getNormalWeighted(begin, center, end):
-       'Get weighted normal.'
-       return (center - begin).cross(end - center)
-
-def getNumberOfIntersectionsToLeft(loop, point):
-       'Get the number of intersections through the loop for the line going left.'
-       numberOfIntersectionsToLeft = 0
-       for pointIndex in xrange(len(loop)):
-               firstPointComplex = loop[pointIndex]
-               secondPointComplex = loop[(pointIndex + 1) % len(loop)]
-               xIntersection = getXIntersectionIfExists(firstPointComplex, secondPointComplex, point.imag)
-               if xIntersection != None:
-                       if xIntersection < point.real:
-                               numberOfIntersectionsToLeft += 1
-       return numberOfIntersectionsToLeft
-
-def getNumberOfIntersectionsToLeftOfLoops(loops, point):
-       'Get the number of intersections through the loop for the line starting from the left point and going left.'
-       totalNumberOfIntersectionsToLeft = 0
-       for loop in loops:
-               totalNumberOfIntersectionsToLeft += getNumberOfIntersectionsToLeft(loop, point)
-       return totalNumberOfIntersectionsToLeft
-
-def getOrderedNestedRings(nestedRings):
-       'Get ordered nestedRings from nestedRings.'
-       insides = []
-       orderedNestedRings = []
-       for loopIndex in xrange(len(nestedRings)):
-               nestedRing = nestedRings[loopIndex]
-               otherLoops = []
-               for beforeIndex in xrange(loopIndex):
-                       otherLoops.append(nestedRings[beforeIndex].boundary)
-               for afterIndex in xrange(loopIndex + 1, len(nestedRings)):
-                       otherLoops.append(nestedRings[afterIndex].boundary)
-               if isPathEntirelyInsideLoops(otherLoops, nestedRing.boundary):
-                       insides.append(nestedRing)
-               else:
-                       orderedNestedRings.append(nestedRing)
-       for outside in orderedNestedRings:
-               outside.getFromInsideSurroundings(insides)
-       return orderedNestedRings
-
-def getPathCopy(path):
-       'Get path copy.'
-       pathCopy = []
-       for point in path:
-               pathCopy.append(point.copy())
-       return pathCopy
-
-def getPathLength(path):
-       'Get the length of a path ( an open polyline ).'
-       pathLength = 0.0
-       for pointIndex in xrange( len(path) - 1 ):
-               firstPoint = path[pointIndex]
-               secondPoint  = path[pointIndex + 1]
-               pathLength += abs(firstPoint - secondPoint)
-       return pathLength
-
-def getPathsFromEndpoints(endpoints, maximumConnectionLength, pixelDictionary, sharpestProduct, width):
-       'Get paths from endpoints.'
-       if len(endpoints) < 2:
-               return []
-       endpoints = endpoints[:] # so that the first two endpoints aren't removed when used again
-       for beginningEndpoint in endpoints[: : 2]:
-               beginningPoint = beginningEndpoint.point
-               addSegmentToPixelTable(beginningPoint, beginningEndpoint.otherEndpoint.point, pixelDictionary, 0, 0, width)
-       endpointFirst = endpoints[0]
-       endpoints.remove(endpointFirst)
-       otherEndpoint = endpointFirst.otherEndpoint
-       endpoints.remove(otherEndpoint)
-       nextEndpoint = None
-       path = []
-       paths = [path]
-       if len(endpoints) > 1:
-               nextEndpoint = otherEndpoint.getClosestMiss(endpoints, path, pixelDictionary, sharpestProduct, width)
-               if nextEndpoint != None:
-                       if abs(nextEndpoint.point - endpointFirst.point) < abs(nextEndpoint.point - otherEndpoint.point):
-                               endpointFirst = endpointFirst.otherEndpoint
-                               otherEndpoint = endpointFirst.otherEndpoint
-       addPointToPath(path, pixelDictionary, endpointFirst.point, None, width)
-       addPointToPath(path, pixelDictionary, otherEndpoint.point, len(paths) - 1, width)
-       oneOverEndpointWidth = 1.0 / maximumConnectionLength
-       endpointTable = {}
-       for endpoint in endpoints:
-               addElementToPixelListFromPoint(endpoint, endpointTable, endpoint.point * oneOverEndpointWidth)
-       while len(endpointTable) > 0:
-               if len(endpointTable) == 1:
-                       if len(endpointTable.values()[0]) < 2:
-                               return []
-               endpoints = getSquareValuesFromPoint(endpointTable, otherEndpoint.point * oneOverEndpointWidth)
-               nextEndpoint = otherEndpoint.getClosestMiss(endpoints, path, pixelDictionary, sharpestProduct, width)
-               if nextEndpoint == None:
-                       path = []
-                       paths.append(path)
-                       endpoints = getListTableElements(endpointTable)
-                       nextEndpoint = otherEndpoint.getClosestEndpoint(endpoints)
-# this commented code should be faster than the getListTableElements code, but it isn't, someday a spiral algorithim could be tried
-#                      endpoints = getSquareValuesFromPoint( endpointTable, otherEndpoint.point * oneOverEndpointWidth )
-#                      nextEndpoint = otherEndpoint.getClosestEndpoint(endpoints)
-#                      if nextEndpoint == None:
-#                              endpoints = []
-#                              for endpointTableValue in endpointTable.values():
-#                                      endpoints.append( endpointTableValue[0] )
-#                              nextEndpoint = otherEndpoint.getClosestEndpoint(endpoints)
-#                              endpoints = getSquareValuesFromPoint( endpointTable, nextEndpoint.point * oneOverEndpointWidth )
-#                              nextEndpoint = otherEndpoint.getClosestEndpoint(endpoints)
-               addPointToPath(path, pixelDictionary, nextEndpoint.point, len(paths) - 1, width)
-               removeElementFromPixelListFromPoint(nextEndpoint, endpointTable, nextEndpoint.point * oneOverEndpointWidth)
-               otherEndpoint = nextEndpoint.otherEndpoint
-               addPointToPath(path, pixelDictionary, otherEndpoint.point, len(paths) - 1, width)
-               removeElementFromPixelListFromPoint(otherEndpoint, endpointTable, otherEndpoint.point * oneOverEndpointWidth)
-       return paths
-
-def getPlaneDot( vec3First, vec3Second ):
-       'Get the dot product of the x and y components of a pair of Vector3s.'
-       return vec3First.x * vec3Second.x + vec3First.y * vec3Second.y
-
-def getPluralString( number, suffix ):
-       'Get the plural string.'
-       if number == 1:
-               return '1 %s' % suffix
-       return '%s %ss' % ( number, suffix )
-
-def getPointPlusSegmentWithLength( length, point, segment ):
-       'Get point plus a segment scaled to a given length.'
-       return segment * length / abs(segment) + point
-
-def getPointsByHorizontalDictionary(width, xIntersectionsDictionary):
-       'Get points from the horizontalXIntersectionsDictionary.'
-       points = []
-       xIntersectionsDictionaryKeys = xIntersectionsDictionary.keys()
-       xIntersectionsDictionaryKeys.sort()
-       for xIntersectionsDictionaryKey in xIntersectionsDictionaryKeys:
-               for xIntersection in xIntersectionsDictionary[xIntersectionsDictionaryKey]:
-                       points.append(complex(xIntersection, xIntersectionsDictionaryKey * width))
-       return points
-
-def getPointsByVerticalDictionary(width, xIntersectionsDictionary):
-       'Get points from the verticalXIntersectionsDictionary.'
-       points = []
-       xIntersectionsDictionaryKeys = xIntersectionsDictionary.keys()
-       xIntersectionsDictionaryKeys.sort()
-       for xIntersectionsDictionaryKey in xIntersectionsDictionaryKeys:
-               for xIntersection in xIntersectionsDictionary[xIntersectionsDictionaryKey]:
-                       points.append(complex(xIntersectionsDictionaryKey * width, xIntersection))
-       return points
-
-def getRadiusArealizedMultiplier(sides):
-       'Get the radius multiplier for a polygon of equal area.'
-       return math.sqrt(globalTau / sides / math.sin(globalTau / sides))
-
-def getRandomComplex(begin, end):
-       'Get random complex.'
-       endMinusBegin = end - begin
-       return begin + complex(random.random() * endMinusBegin.real, random.random() * endMinusBegin.imag)
-
-def getRank(width):
-       'Get the rank which is 0 at 1 and increases by three every power of ten.'
-       return int(math.floor(3.0 * math.log10(width)))
-
-def getRotatedComplexes(planeAngle, points):
-       'Get points rotated by the plane angle'
-       rotatedComplexes = []
-       for point in points:
-               rotatedComplexes.append(planeAngle * point)
-       return rotatedComplexes
-
-def getRotatedComplexLists(planeAngle, pointLists):
-       'Get point lists rotated by the plane angle'
-       rotatedComplexLists = []
-       for pointList in pointLists:
-               rotatedComplexLists.append(getRotatedComplexes(planeAngle, pointList))
-       return rotatedComplexLists
-
-def getRotatedWiddershinsQuarterAroundZAxis(vector3):
-       'Get Vector3 rotated a quarter widdershins turn around Z axis.'
-       return Vector3(-vector3.y, vector3.x, vector3.z)
-
-def getRoundedPoint(point):
-       'Get point with each component rounded.'
-       return Vector3(round(point.x), round( point.y ), round(point.z))
-
-def getRoundedToPlaces(decimalPlaces, number):
-       'Get number rounded to a number of decimal places.'
-       decimalPlacesRounded = max(1, int(round(decimalPlaces)))
-       return round(number, decimalPlacesRounded)
-
-def getRoundedToPlacesString(decimalPlaces, number):
-       'Get number rounded to a number of decimal places as a string, without exponential formatting.'
-       roundedToPlaces = getRoundedToPlaces(decimalPlaces, number)
-       roundedToPlacesString = str(roundedToPlaces)
-       if 'e' in roundedToPlacesString:
-               return ('%.15f' % roundedToPlaces).rstrip('0')
-       return roundedToPlacesString
-
-def getRoundedToThreePlaces(number):
-       'Get number rounded to three places as a string.'
-       return str(round(number, 3))
-
-def getRoundZAxisByPlaneAngle( planeAngle, vector3 ):
-       'Get Vector3 rotated by a plane angle.'
-       return Vector3( vector3.x * planeAngle.real - vector3.y * planeAngle.imag, vector3.x * planeAngle.imag + vector3.y * planeAngle.real, vector3.z )
-
-def getSegmentFromPath( path, pathIndex ):
-       'Get endpoint segment from a path.'
-       if len(path) < 2:
-               return None
-       begin = path[-1]
-       end = path[-2]
-       forwardEndpoint = getEndpointFromPath( path, pathIndex )
-       reversePath = path[:]
-       reversePath.reverse()
-       reverseEndpoint = getEndpointFromPath( reversePath, pathIndex )
-       return ( forwardEndpoint, reverseEndpoint )
-
-def getSegmentFromPoints( begin, end ):
-       'Get endpoint segment from a pair of points.'
-       endpointFirst = Endpoint()
-       endpointSecond = Endpoint().getFromOtherPoint( endpointFirst, end )
-       endpointFirst.getFromOtherPoint( endpointSecond, begin )
-       return ( endpointFirst, endpointSecond )
-
-def getSegmentsFromXIntersectionIndexes( xIntersectionIndexList, y ):
-       'Get endpoint segments from the x intersection indexes.'
-       xIntersections = getXIntersectionsFromIntersections( xIntersectionIndexList )
-       return getSegmentsFromXIntersections( xIntersections, y )
-
-def getSegmentsFromXIntersections( xIntersections, y ):
-       'Get endpoint segments from the x intersections.'
-       segments = []
-       end = len( xIntersections )
-       if len( xIntersections ) % 2 == 1:
-               end -= 1
-       for xIntersectionIndex in xrange( 0, end, 2 ):
-               firstX = xIntersections[ xIntersectionIndex ]
-               secondX = xIntersections[ xIntersectionIndex + 1 ]
-               if firstX != secondX:
-                       segments.append( getSegmentFromPoints( complex( firstX, y ), complex( secondX, y ) ) )
-       return segments
-
-def getSimplifiedLoop( loop, radius ):
-       'Get loop with points inside the channel removed.'
-       if len(loop) < 2:
-               return loop
-       simplificationMultiplication = 256
-       simplificationRadius = radius / float( simplificationMultiplication )
-       maximumIndex = len(loop) * simplificationMultiplication
-       pointIndex = 1
-       while pointIndex < maximumIndex:
-               oldLoopLength = len(loop)
-               loop = getHalfSimplifiedLoop( loop, simplificationRadius, 0 )
-               loop = getHalfSimplifiedLoop( loop, simplificationRadius, 1 )
-               simplificationRadius += simplificationRadius
-               if oldLoopLength == len(loop):
-                       if simplificationRadius > radius:
-                               return getAwayPoints( loop, radius )
-                       else:
-                               simplificationRadius *= 1.5
-               simplificationRadius = min( simplificationRadius, radius )
-               pointIndex += pointIndex
-       return getAwayPoints( loop, radius )
-
-def getSimplifiedLoops( loops, radius ):
-       'Get the simplified loops.'
-       simplifiedLoops = []
-       for loop in loops:
-               simplifiedLoops.append( getSimplifiedLoop( loop, radius ) )
-       return simplifiedLoops
-
-def getSimplifiedPath(path, radius):
-       'Get path with points inside the channel removed.'
-       if len(path) < 2:
-               return path
-       simplificationMultiplication = 256
-       simplificationRadius = radius / float(simplificationMultiplication)
-       maximumIndex = len(path) * simplificationMultiplication
-       pointIndex = 1
-       while pointIndex < maximumIndex:
-               oldPathLength = len(path)
-               path = getHalfSimplifiedPath(path, simplificationRadius, 0)
-               path = getHalfSimplifiedPath(path, simplificationRadius, 1)
-               simplificationRadius += simplificationRadius
-               if oldPathLength == len(path):
-                       if simplificationRadius > radius:
-                               return getAwayPath(path, radius)
-                       else:
-                               simplificationRadius *= 1.5
-               simplificationRadius = min(simplificationRadius, radius)
-               pointIndex += pointIndex
-       return getAwayPath(path, radius)
-
-def getSquareIsOccupied( pixelDictionary, x, y ):
-       'Determine if a square around the x and y pixel coordinates is occupied.'
-       squareValues = []
-       for xStep in xrange(x - 1, x + 2):
-               for yStep in xrange(y - 1, y + 2):
-                       if (xStep, yStep) in pixelDictionary:
-                               return True
-       return False
-
-def getSquareLoopWiddershins(beginComplex, endComplex):
-       'Get a square loop from the beginning to the end and back.'
-       loop = [beginComplex, complex(endComplex.real, beginComplex.imag), endComplex]
-       loop.append(complex(beginComplex.real, endComplex.imag))
-       return loop
-
-def getSquareValues( pixelDictionary, x, y ):
-       'Get a list of the values in a square around the x and y pixel coordinates.'
-       squareValues = []
-       for xStep in xrange(x - 1, x + 2):
-               for yStep in xrange(y - 1, y + 2):
-                       stepKey = (xStep, yStep)
-                       if stepKey in pixelDictionary:
-                               squareValues += pixelDictionary[ stepKey ]
-       return squareValues
-
-def getSquareValuesFromPoint( pixelDictionary, point ):
-       'Get a list of the values in a square around the point.'
-       return getSquareValues(pixelDictionary, int(round(point.real)), int(round(point.imag)))
-
-def getStepKeyFromPoint(point):
-       'Get step key for the point.'
-       return (int(round(point.real)), int(round(point.imag)))
-
-def getThreeSignificantFigures(number):
-       'Get number rounded to three significant figures as a string.'
-       absoluteNumber = abs(number)
-       if absoluteNumber >= 10.0:
-               return getRoundedToPlacesString( 1, number )
-       if absoluteNumber < 0.000000001:
-               return getRoundedToPlacesString( 12, number )
-       return getRoundedToPlacesString( 1 - math.floor( math.log10( absoluteNumber ) ), number )
-
-def getTopPath(path):
-       'Get the top of the path.'
-       top = -987654321987654321.0
-       for point in path:
-               top = max(top, point.z)
-       return top
-
-def getTopPaths(paths):
-       'Get the top of the paths.'
-       top = -987654321987654321.0
-       for path in paths:
-               for point in path:
-                       top = max(top, point.z)
-       return top
-
-def getTransferClosestNestedRing(extrusionHalfWidth, nestedRings, oldOrderedLocation, skein, threadSequence):
-       'Get and transfer the closest remaining nested ring.'
-       if len(nestedRings) > 0:
-               oldOrderedLocation.z = nestedRings[0].z
-       closestDistance = 987654321987654321.0
-       closestNestedRing = None
-       for remainingNestedRing in nestedRings:
-               distance = getClosestDistanceIndexToLine(oldOrderedLocation.dropAxis(), remainingNestedRing.boundary).distance
-               if distance < closestDistance:
-                       closestDistance = distance
-                       closestNestedRing = remainingNestedRing
-       nestedRings.remove(closestNestedRing)
-       closestNestedRing.addToThreads(extrusionHalfWidth, oldOrderedLocation, skein, threadSequence)
-       return closestNestedRing
-
-def getTransferredNestedRings( insides, loop ):
-       'Get transferred paths from inside nested rings.'
-       transferredSurroundings = []
-       for insideIndex in xrange( len( insides ) - 1, - 1, - 1 ):
-               insideSurrounding = insides[ insideIndex ]
-               if isPathInsideLoop( loop, insideSurrounding.boundary ):
-                       transferredSurroundings.append( insideSurrounding )
-                       del insides[ insideIndex ]
-       return transferredSurroundings
-
-def getTransferredPaths( insides, loop ):
-       'Get transferred paths from inside paths.'
-       transferredPaths = []
-       for insideIndex in xrange( len( insides ) - 1, - 1, - 1 ):
-               inside = insides[ insideIndex ]
-               if isPathInsideLoop( loop, inside ):
-                       transferredPaths.append( inside )
-                       del insides[ insideIndex ]
-       return transferredPaths
-
-def getTranslatedComplexPath(path, translateComplex):
-       'Get the translated complex path.'
-       translatedComplexPath = []
-       for point in path:
-               translatedComplexPath.append(point + translateComplex)
-       return translatedComplexPath
-
-def getVector3Path(complexPath, z=0.0):
-       'Get the vector3 path from the complex path.'
-       vector3Path = []
-       for complexPoint in complexPath:
-               vector3Path.append(Vector3(complexPoint.real, complexPoint.imag, z))
-       return vector3Path
-
-def getVector3Paths(complexPaths, z=0.0):
-       'Get the vector3 paths from the complex paths.'
-       vector3Paths = []
-       for complexPath in complexPaths:
-               vector3Paths.append(getVector3Path(complexPath, z))
-       return vector3Paths
-
-def getWiddershinsUnitPolar(angle):
-       'Get polar complex from counterclockwise angle from 1, 0.'
-       return complex(math.cos(angle), math.sin(angle))
-
-def getXIntersectionIfExists( beginComplex, endComplex, y ):
-       'Get the x intersection if it exists.'
-       if ( y > beginComplex.imag ) == ( y > endComplex.imag ):
-               return None
-       endMinusBeginComplex = endComplex - beginComplex
-       return ( y - beginComplex.imag ) / endMinusBeginComplex.imag * endMinusBeginComplex.real + beginComplex.real
-
-def getXIntersectionsFromIntersections( xIntersectionIndexList ):
-       'Get x intersections from the x intersection index list, in other words subtract non negative intersections from negatives.'
-       xIntersections = []
-       fill = False
-       solid = False
-       solidTable = {}
-       xIntersectionIndexList.sort()
-       for solidX in xIntersectionIndexList:
-               if solidX.index >= 0:
-                       toggleHashtable( solidTable, solidX.index, '' )
-               else:
-                       fill = not fill
-               oldSolid = solid
-               solid = ( len( solidTable ) == 0 and fill )
-               if oldSolid != solid:
-                       xIntersections.append( solidX.x )
-       return xIntersections
-
-def getXYComplexFromVector3(vector3):
-       'Get an xy complex from a vector3 if it exists, otherwise return None.'
-       if vector3 == None:
-               return None
-       return vector3.dropAxis()
-
-def getYIntersectionIfExists( beginComplex, endComplex, x ):
-       'Get the y intersection if it exists.'
-       if ( x > beginComplex.real ) == ( x > endComplex.real ):
-               return None
-       endMinusBeginComplex = endComplex - beginComplex
-       return ( x - beginComplex.real ) / endMinusBeginComplex.real * endMinusBeginComplex.imag + beginComplex.imag
-
-def getZComponentCrossProduct( vec3First, vec3Second ):
-       'Get z component cross product of a pair of Vector3s.'
-       return vec3First.x * vec3Second.y - vec3First.y * vec3Second.x
-
-def isInsideOtherLoops( loopIndex, loops ):
-       'Determine if a loop in a list is inside another loop in that list.'
-       return isPathInsideLoops( loops[ : loopIndex ] + loops[loopIndex + 1 :], loops[loopIndex] )
-
-def isLineIntersectingInsideXSegment( beginComplex, endComplex, segmentFirstX, segmentSecondX, y ):
-       'Determine if the line is crossing inside the x segment.'
-       xIntersection = getXIntersectionIfExists( beginComplex, endComplex, y )
-       if xIntersection == None:
-               return False
-       if xIntersection < min( segmentFirstX, segmentSecondX ):
-               return False
-       return xIntersection <= max( segmentFirstX, segmentSecondX )
-
-def isLineIntersectingLoop( loop, pointBegin, pointEnd ):
-       'Determine if the line is intersecting loops.'
-       normalizedSegment = pointEnd - pointBegin
-       normalizedSegmentLength = abs( normalizedSegment )
-       if normalizedSegmentLength > 0.0:
-               normalizedSegment /= normalizedSegmentLength
-               segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag)
-               pointBeginRotated = segmentYMirror * pointBegin
-               pointEndRotated = segmentYMirror * pointEnd
-               if isLoopIntersectingInsideXSegment( loop, pointBeginRotated.real, pointEndRotated.real, segmentYMirror, pointBeginRotated.imag ):
-                       return True
-       return False
-
-def isLineIntersectingLoops( loops, pointBegin, pointEnd ):
-       'Determine if the line is intersecting loops.'
-       normalizedSegment = pointEnd - pointBegin
-       normalizedSegmentLength = abs( normalizedSegment )
-       if normalizedSegmentLength > 0.0:
-               normalizedSegment /= normalizedSegmentLength
-               segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag)
-               pointBeginRotated = segmentYMirror * pointBegin
-               pointEndRotated = segmentYMirror * pointEnd
-               if isLoopListIntersectingInsideXSegment( loops, pointBeginRotated.real, pointEndRotated.real, segmentYMirror, pointBeginRotated.imag ):
-                       return True
-       return False
-
-def isLoopIntersectingInsideXSegment( loop, segmentFirstX, segmentSecondX, segmentYMirror, y ):
-       'Determine if the loop is intersecting inside the x segment.'
-       rotatedLoop = getRotatedComplexes( segmentYMirror, loop )
-       for pointIndex in xrange( len( rotatedLoop ) ):
-               pointFirst = rotatedLoop[pointIndex]
-               pointSecond = rotatedLoop[ (pointIndex + 1) % len( rotatedLoop ) ]
-               if isLineIntersectingInsideXSegment( pointFirst, pointSecond, segmentFirstX, segmentSecondX, y ):
-                       return True
-       return False
-
-def isLoopIntersectingLoop( loop, otherLoop ):
-       'Determine if the loop is intersecting the other loop.'
-       for pointIndex in xrange(len(loop)):
-               pointBegin = loop[pointIndex]
-               pointEnd = loop[(pointIndex + 1) % len(loop)]
-               if isLineIntersectingLoop( otherLoop, pointBegin, pointEnd ):
-                       return True
-       return False
-
-def isLoopIntersectingLoops( loop, otherLoops ):
-       'Determine if the loop is intersecting other loops.'
-       for pointIndex in xrange(len(loop)):
-               pointBegin = loop[pointIndex]
-               pointEnd = loop[(pointIndex + 1) % len(loop)]
-               if isLineIntersectingLoops( otherLoops, pointBegin, pointEnd ):
-                       return True
-       return False
-
-def isLoopListIntersecting(loops):
-       'Determine if a loop in the list is intersecting the other loops.'
-       for loopIndex in xrange(len(loops) - 1):
-               loop = loops[loopIndex]
-               if isLoopIntersectingLoops(loop, loops[loopIndex + 1 :]):
-                       return True
-       return False
-
-def isLoopListIntersectingInsideXSegment( loopList, segmentFirstX, segmentSecondX, segmentYMirror, y ):
-       'Determine if the loop list is crossing inside the x segment.'
-       for alreadyFilledLoop in loopList:
-               if isLoopIntersectingInsideXSegment( alreadyFilledLoop, segmentFirstX, segmentSecondX, segmentYMirror, y ):
-                       return True
-       return False
-
-def isPathEntirelyInsideLoop(loop, path):
-       'Determine if a path is entirely inside another loop.'
-       for point in path:
-               if not isPointInsideLoop(loop, point):
-                       return False
-       return True
-
-def isPathEntirelyInsideLoops(loops, path):
-       'Determine if a path is entirely inside another loop in a list.'
-       for loop in loops:
-               if isPathEntirelyInsideLoop(loop, path):
-                       return True
-       return False
-
-def isPathInsideLoop(loop, path):
-       'Determine if a path is inside another loop.'
-       return isPointInsideLoop(loop, getLeftPoint(path))
-
-def isPathInsideLoops(loops, path):
-       'Determine if a path is inside another loop in a list.'
-       for loop in loops:
-               if isPathInsideLoop(loop, path):
-                       return True
-       return False
-
-def isPixelTableIntersecting( bigTable, littleTable, maskTable = {} ):
-       'Add path to the pixel table.'
-       littleTableKeys = littleTable.keys()
-       for littleTableKey in littleTableKeys:
-               if littleTableKey not in maskTable:
-                       if littleTableKey in bigTable:
-                               return True
-       return False
-
-def isPointInsideLoop(loop, point):
-       'Determine if a point is inside another loop.'
-       return getNumberOfIntersectionsToLeft(loop, point) % 2 == 1
-
-def isSegmentCompletelyInX( segment, xFirst, xSecond ):
-       'Determine if the segment overlaps within x.'
-       segmentFirstX = segment[0].point.real
-       segmentSecondX = segment[1].point.real
-       if max( segmentFirstX, segmentSecondX ) > max( xFirst, xSecond ):
-               return False
-       return min( segmentFirstX, segmentSecondX ) >= min( xFirst, xSecond )
-
-def isWiddershins(polygonComplex):
-       'Determine if the complex polygon goes round in the widdershins direction.'
-       return getAreaLoop(polygonComplex) > 0.0
-
-def isWithinChannel( channelRadius, pointIndex, loop ):
-       'Determine if the the point is within the channel between two adjacent points.'
-       point = loop[pointIndex]
-       behindSegmentComplex = loop[(pointIndex + len(loop) - 1) % len(loop)] - point
-       behindSegmentComplexLength = abs( behindSegmentComplex )
-       if behindSegmentComplexLength < channelRadius:
-               return True
-       aheadSegmentComplex = loop[(pointIndex + 1) % len(loop)] - point
-       aheadSegmentComplexLength = abs( aheadSegmentComplex )
-       if aheadSegmentComplexLength < channelRadius:
-               return True
-       behindSegmentComplex /= behindSegmentComplexLength
-       aheadSegmentComplex /= aheadSegmentComplexLength
-       absoluteZ = getDotProductPlusOne( aheadSegmentComplex, behindSegmentComplex )
-       if behindSegmentComplexLength * absoluteZ < channelRadius:
-               return True
-       return aheadSegmentComplexLength * absoluteZ < channelRadius
-
-def isXSegmentIntersectingPath( path, segmentFirstX, segmentSecondX, segmentYMirror, y ):
-       'Determine if a path is crossing inside the x segment.'
-       rotatedPath = getRotatedComplexes( segmentYMirror, path )
-       for pointIndex in xrange( len( rotatedPath ) - 1 ):
-               pointFirst = rotatedPath[pointIndex]
-               pointSecond = rotatedPath[pointIndex + 1]
-               if isLineIntersectingInsideXSegment( pointFirst, pointSecond, segmentFirstX, segmentSecondX, y ):
-                       return True
-       return False
-
-def isXSegmentIntersectingPaths( paths, segmentFirstX, segmentSecondX, segmentYMirror, y ):
-       'Determine if a path list is crossing inside the x segment.'
-       for path in paths:
-               if isXSegmentIntersectingPath( path, segmentFirstX, segmentSecondX, segmentYMirror, y ):
-                       return True
-       return False
-
-def joinSegmentTables( fromTable, intoTable ):
-       'Join both segment tables and put the join into the intoTable.'
-       intoTableKeys = intoTable.keys()
-       fromTableKeys = fromTable.keys()
-       joinedKeyTable = {}
-       concatenatedTableKeys = intoTableKeys + fromTableKeys
-       for concatenatedTableKey in concatenatedTableKeys:
-               joinedKeyTable[ concatenatedTableKey ] = None
-       joinedKeys = joinedKeyTable.keys()
-       joinedKeys.sort()
-       for joinedKey in joinedKeys:
-               xIntersectionIndexList = []
-               if joinedKey in intoTable:
-                       addXIntersectionIndexesFromSegments( 0, intoTable[ joinedKey ], xIntersectionIndexList )
-               if joinedKey in fromTable:
-                       addXIntersectionIndexesFromSegments( 1, fromTable[ joinedKey ], xIntersectionIndexList )
-               xIntersections = getJoinOfXIntersectionIndexes( xIntersectionIndexList )
-               lineSegments = getSegmentsFromXIntersections( xIntersections, joinedKey )
-               if len( lineSegments ) > 0:
-                       intoTable[ joinedKey ] = lineSegments
-               else:
-                       print('This should never happen, there are no line segments in joinSegments in euclidean')
-
-def joinXIntersectionsTables( fromTable, intoTable ):
-       'Join both XIntersections tables and put the join into the intoTable.'
-       joinedKeyTable = {}
-       concatenatedTableKeys = fromTable.keys() + intoTable.keys()
-       for concatenatedTableKey in concatenatedTableKeys:
-               joinedKeyTable[ concatenatedTableKey ] = None
-       for joinedKey in joinedKeyTable.keys():
-               xIntersectionIndexList = []
-               if joinedKey in intoTable:
-                       addXIntersectionIndexesFromXIntersections( 0, xIntersectionIndexList, intoTable[ joinedKey ] )
-               if joinedKey in fromTable:
-                       addXIntersectionIndexesFromXIntersections( 1, xIntersectionIndexList, fromTable[ joinedKey ] )
-               xIntersections = getJoinOfXIntersectionIndexes( xIntersectionIndexList )
-               if len( xIntersections ) > 0:
-                       intoTable[ joinedKey ] = xIntersections
-               else:
-                       print('This should never happen, there are no line segments in joinSegments in euclidean')
-
-def overwriteDictionary(fromDictionary, keys, toDictionary):
-       'Overwrite the dictionary.'
-       for key in keys:
-               if key in fromDictionary:
-                       toDictionary[key] = fromDictionary[key]
-
-def removeElementFromDictionary(dictionary, key):
-       'Remove element from the dictionary.'
-       if key in dictionary:
-               del dictionary[key]
-
-def removeElementFromListTable(element, key, listDictionary):
-       'Remove an element from the list table.'
-       if key not in listDictionary:
-               return
-       elementList = listDictionary[key]
-       if len( elementList ) < 2:
-               del listDictionary[key]
-               return
-       if element in elementList:
-               elementList.remove(element)
-
-def removeElementFromPixelListFromPoint( element, pixelDictionary, point ):
-       'Remove an element from the pixel list.'
-       stepKey = getStepKeyFromPoint(point)
-       removeElementFromListTable( element, stepKey, pixelDictionary )
-
-def removeElementsFromDictionary(dictionary, keys):
-       'Remove list from the dictionary.'
-       for key in keys:
-               removeElementFromDictionary(dictionary, key)
-
-def removePixelTableFromPixelTable( pixelDictionaryToBeRemoved, pixelDictionaryToBeRemovedFrom ):
-       'Remove pixel from the pixel table.'
-       removeElementsFromDictionary( pixelDictionaryToBeRemovedFrom, pixelDictionaryToBeRemoved.keys() )
-
-def removePrefixFromDictionary( dictionary, prefix ):
-       'Remove the attributes starting with the prefix from the dictionary.'
-       for key in dictionary.keys():
-               if key.startswith( prefix ):
-                       del dictionary[key]
-
-def removeTrueFromDictionary(dictionary, key):
-       'Remove key from the dictionary in the value is true.'
-       if key in dictionary:
-               if getBooleanFromValue(dictionary[key]):
-                       del dictionary[key]
-
-def removeTrueListFromDictionary( dictionary, keys ):
-       'Remove list from the dictionary in the value is true.'
-       for key in keys:
-               removeTrueFromDictionary( dictionary, key )
-
-def subtractXIntersectionsTable( subtractFromTable, subtractTable ):
-       'Subtract the subtractTable from the subtractFromTable.'
-       subtractFromTableKeys = subtractFromTable.keys()
-       subtractFromTableKeys.sort()
-       for subtractFromTableKey in subtractFromTableKeys:
-               xIntersectionIndexList = []
-               addXIntersectionIndexesFromXIntersections( - 1, xIntersectionIndexList, subtractFromTable[ subtractFromTableKey ] )
-               if subtractFromTableKey in subtractTable:
-                       addXIntersectionIndexesFromXIntersections( 0, xIntersectionIndexList, subtractTable[ subtractFromTableKey ] )
-               xIntersections = getXIntersectionsFromIntersections( xIntersectionIndexList )
-               if len( xIntersections ) > 0:
-                       subtractFromTable[ subtractFromTableKey ] = xIntersections
-               else:
-                       del subtractFromTable[ subtractFromTableKey ]
-
-def swapList( elements, indexBegin, indexEnd ):
-       'Swap the list elements.'
-       elements[ indexBegin ], elements[ indexEnd ] = elements[ indexEnd ], elements[ indexBegin ]
-
-def toggleHashtable( hashtable, key, value ):
-       'Toggle a hashtable between having and not having a key.'
-       if key in hashtable:
-               del hashtable[key]
-       else:
-               hashtable[key] = value
-
-def transferClosestFillLoop(extrusionHalfWidth, oldOrderedLocation, remainingFillLoops, skein):
-       'Transfer the closest remaining fill loop.'
-       closestDistance = 987654321987654321.0
-       closestFillLoop = None
-       for remainingFillLoop in remainingFillLoops:
-               distance = getClosestDistanceIndexToLine(oldOrderedLocation.dropAxis(), remainingFillLoop).distance
-               if distance < closestDistance:
-                       closestDistance = distance
-                       closestFillLoop = remainingFillLoop
-       newClosestFillLoop = getLoopInsideContainingLoop(closestFillLoop, remainingFillLoops)
-       while newClosestFillLoop != None:
-               closestFillLoop = newClosestFillLoop
-               newClosestFillLoop = getLoopInsideContainingLoop(closestFillLoop, remainingFillLoops)
-       remainingFillLoops.remove(closestFillLoop)
-       addToThreadsFromLoop(extrusionHalfWidth, 'loop', closestFillLoop[:], oldOrderedLocation, skein)
-
-def transferClosestPath( oldOrderedLocation, remainingPaths, skein ):
-       'Transfer the closest remaining path.'
-       closestDistance = 987654321987654321.0
-       closestPath = None
-       oldOrderedLocationComplex = oldOrderedLocation.dropAxis()
-       for remainingPath in remainingPaths:
-               distance = min( abs( oldOrderedLocationComplex - remainingPath[0] ), abs( oldOrderedLocationComplex - remainingPath[-1] ) )
-               if distance < closestDistance:
-                       closestDistance = distance
-                       closestPath = remainingPath
-       remainingPaths.remove( closestPath )
-       skein.addGcodeFromThreadZ( closestPath, oldOrderedLocation.z )
-       oldOrderedLocation.x = closestPath[-1].real
-       oldOrderedLocation.y = closestPath[-1].imag
-
-def transferClosestPaths(oldOrderedLocation, remainingPaths, skein):
-       'Transfer the closest remaining paths.'
-       while len(remainingPaths) > 0:
-               transferClosestPath(oldOrderedLocation, remainingPaths, skein)
-
-def transferPathsToNestedRings(nestedRings, paths):
-       'Transfer paths to nested rings.'
-       for nestedRing in nestedRings:
-               nestedRing.transferPaths(paths)
-
-def translateVector3Path(path, translateVector3):
-       'Translate the vector3 path.'
-       for point in path:
-               point.setToVector3(point + translateVector3)
-
-def translateVector3Paths(paths, translateVector3):
-       'Translate the vector3 paths.'
-       for path in paths:
-               translateVector3Path(path, translateVector3)
-
-def unbuckleBasis( basis, maximumUnbuckling, normal ):
-       'Unbuckle space.'
-       normalDot = basis.dot( normal )
-       dotComplement = math.sqrt( 1.0 - normalDot * normalDot )
-       unbuckling = maximumUnbuckling
-       if dotComplement > 0.0:
-               unbuckling = min( 1.0 / dotComplement, maximumUnbuckling )
-       basis.setToVector3( basis * unbuckling )
-
-
-class DistanceIndex(object):
-       'A class to hold the distance and the index of the loop.'
-       def __init__(self, distance, index):
-               'Initialize.'
-               self.distance = distance
-               self.index = index
-
-       def __repr__(self):
-               'Get the string representation of this distance index.'
-               return '%s, %s' % (self.distance, self.index)
-
-
-class Endpoint(object):
-       'The endpoint of a segment.'
-       def __repr__(self):
-               'Get the string representation of this Endpoint.'
-               return 'Endpoint %s, %s' % ( self.point, self.otherEndpoint.point )
-
-       def getClosestEndpoint( self, endpoints ):
-               'Get closest endpoint.'
-               smallestDistance = 987654321987654321.0
-               closestEndpoint = None
-               for endpoint in endpoints:
-                       distance = abs( self.point - endpoint.point )
-                       if distance < smallestDistance:
-                               smallestDistance = distance
-                               closestEndpoint = endpoint
-               return closestEndpoint
-
-       def getClosestMiss(self, endpoints, path, pixelDictionary, sharpestProduct, width):
-               'Get the closest endpoint which the segment to that endpoint misses the other extrusions.'
-               pathMaskTable = {}
-               smallestDistance = 987654321.0
-               penultimateMinusPoint = complex(0.0, 0.0)
-               if len(path) > 1:
-                       penultimatePoint = path[-2]
-                       addSegmentToPixelTable(penultimatePoint, self.point, pathMaskTable, 0, 0, width)
-                       penultimateMinusPoint = penultimatePoint - self.point
-                       if abs(penultimateMinusPoint) > 0.0:
-                               penultimateMinusPoint /= abs(penultimateMinusPoint)
-               for endpoint in endpoints:
-                       endpoint.segment = endpoint.point - self.point
-                       endpoint.segmentLength = abs(endpoint.segment)
-                       if endpoint.segmentLength <= 0.0:
-                               return endpoint
-               endpoints.sort(compareSegmentLength)
-               for endpoint in endpoints[: 15]: # increasing the number of searched endpoints increases the search time, with 20 fill took 600 seconds for cilinder.gts, with 10 fill took 533 seconds
-                       normalizedSegment = endpoint.segment / endpoint.segmentLength
-                       isOverlappingSelf = getDotProduct(penultimateMinusPoint, normalizedSegment) > sharpestProduct
-                       if not isOverlappingSelf:
-                               if len(path) > 2:
-                                       segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag)
-                                       pointRotated = segmentYMirror * self.point
-                                       endpointPointRotated = segmentYMirror * endpoint.point
-                                       if isXSegmentIntersectingPath(path[max(0, len(path) - 21) : -1], pointRotated.real, endpointPointRotated.real, segmentYMirror, pointRotated.imag):
-                                               isOverlappingSelf = True
-                       if not isOverlappingSelf:
-                               totalMaskTable = pathMaskTable.copy()
-                               addSegmentToPixelTable(endpoint.point, endpoint.otherEndpoint.point, totalMaskTable, 0, 0, width)
-                               segmentTable = {}
-                               addSegmentToPixelTable(self.point, endpoint.point, segmentTable, 0, 0, width)
-                               if not isPixelTableIntersecting(pixelDictionary, segmentTable, totalMaskTable):
-                                       return endpoint
-               return None
-
-       def getClosestMissCheckEndpointPath(self, endpoints, path, pixelDictionary, sharpestProduct, width):
-               'Get the closest endpoint which the segment to that endpoint misses the other extrusions, also checking the path of the endpoint.'
-               pathMaskTable = {}
-               smallestDistance = 987654321.0
-               penultimateMinusPoint = complex(0.0, 0.0)
-               if len(path) > 1:
-                       penultimatePoint = path[-2]
-                       addSegmentToPixelTable(penultimatePoint, self.point, pathMaskTable, 0, 0, width)
-                       penultimateMinusPoint = penultimatePoint - self.point
-                       if abs(penultimateMinusPoint) > 0.0:
-                               penultimateMinusPoint /= abs(penultimateMinusPoint)
-               for endpoint in endpoints:
-                       endpoint.segment = endpoint.point - self.point
-                       endpoint.segmentLength = abs(endpoint.segment)
-                       if endpoint.segmentLength <= 0.0:
-                               return endpoint
-               endpoints.sort( compareSegmentLength )
-               for endpoint in endpoints[ : 15 ]: # increasing the number of searched endpoints increases the search time, with 20 fill took 600 seconds for cilinder.gts, with 10 fill took 533 seconds
-                       normalizedSegment = endpoint.segment / endpoint.segmentLength
-                       isOverlappingSelf = getDotProduct(penultimateMinusPoint, normalizedSegment) > sharpestProduct
-                       if not isOverlappingSelf:
-                               if len(path) > 2:
-                                       segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag)
-                                       pointRotated = segmentYMirror * self.point
-                                       endpointPointRotated = segmentYMirror * endpoint.point
-                                       if isXSegmentIntersectingPath(path[ max(0, len(path) - 21) : -1], pointRotated.real, endpointPointRotated.real, segmentYMirror, pointRotated.imag):
-                                               isOverlappingSelf = True
-                               endpointPath = endpoint.path
-                               if len(endpointPath) > 2:
-                                       segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag)
-                                       pointRotated = segmentYMirror * self.point
-                                       endpointPointRotated = segmentYMirror * endpoint.point
-                                       if isXSegmentIntersectingPath(endpointPath, pointRotated.real, endpointPointRotated.real, segmentYMirror, pointRotated.imag):
-                                               isOverlappingSelf = True
-                       if not isOverlappingSelf:
-                               totalMaskTable = pathMaskTable.copy()
-                               addSegmentToPixelTable(endpoint.point, endpoint.otherEndpoint.point, totalMaskTable, 0, 0, width)
-                               segmentTable = {}
-                               addSegmentToPixelTable(self.point, endpoint.point, segmentTable, 0, 0, width)
-                               if not isPixelTableIntersecting(pixelDictionary, segmentTable, totalMaskTable):
-                                       return endpoint
-               return None
-
-       def getFromOtherPoint( self, otherEndpoint, point ):
-               'Initialize from other endpoint.'
-               self.otherEndpoint = otherEndpoint
-               self.point = point
-               return self
-
-
-class LoopLayer(object):
-       'Loops with a z.'
-       def __init__(self, z):
-               'Initialize.'
-               self.loops = []
-               self.z = z
-
-       def __repr__(self):
-               'Get the string representation of this loop layer.'
-               return '%s, %s' % (self.z, self.loops)
-
-
-class NestedRing(object):
-       'A nested ring.'
-       def __init__(self):
-               'Initialize.'
-               self.boundary = []
-               self.innerNestedRings = None
-
-       def __repr__(self):
-               'Get the string representation of this nested ring.'
-               return str(self.__dict__)
-
-       def addFlattenedNestedRings(self, flattenedNestedRings):
-               'Add flattened nested rings.'
-               flattenedNestedRings.append(self)
-               for innerNestedRing in self.innerNestedRings:
-                       flattenedNestedRings += getFlattenedNestedRings(innerNestedRing.innerNestedRings)
-
-       def getFromInsideSurroundings(self, inputSurroundingInsides):
-               'Initialize from inside nested rings.'
-               transferredSurroundings = getTransferredNestedRings(inputSurroundingInsides, self.boundary)
-               self.innerNestedRings = getOrderedNestedRings(transferredSurroundings)
-               return self
-
-
-class NestedBand(NestedRing):
-       'A loop that surrounds paths.'
-       def __init__(self):
-               'Initialize.'
-               NestedRing.__init__(self)
-               self.edgePaths = []
-               self.extraLoops = []
-               self.infillBoundaries = []
-               self.infillPaths = []
-#              self.lastExistingFillLoops = None
-               self.lastFillLoops = None
-               self.loop = None
-               self.penultimateFillLoops = []
-               self.z = None
-
-       def __repr__(self):
-               'Get the string representation of this nested ring.'
-               stringRepresentation = 'boundary\n%s\n' % self.boundary
-               stringRepresentation += 'loop\n%s\n' % self.loop
-               stringRepresentation += 'inner nested rings\n%s\n' % self.innerNestedRings
-               stringRepresentation += 'infillPaths\n'
-               for infillPath in self.infillPaths:
-                       stringRepresentation += 'infillPath\n%s\n' % infillPath
-               stringRepresentation += 'edgePaths\n'
-               for edgePath in self.edgePaths:
-                       stringRepresentation += 'edgePath\n%s\n' % edgePath
-               return stringRepresentation + '\n'
-
-       def addPerimeterInner(self, extrusionHalfWidth, oldOrderedLocation, skein, threadSequence):
-               'Add to the edge and the inner island.'
-               if self.loop == None:
-                       skein.distanceFeedRate.addLine('(<edgePath>)')
-                       transferClosestPaths(oldOrderedLocation, self.edgePaths[:], skein)
-                       skein.distanceFeedRate.addLine('(</edgePath>)')
-               else:
-                       addToThreadsFromLoop(extrusionHalfWidth, 'edge', self.loop[:], oldOrderedLocation, skein)
-               skein.distanceFeedRate.addLine('(</boundaryPerimeter>)')
-               addToThreadsRemove(extrusionHalfWidth, self.innerNestedRings[:], oldOrderedLocation, skein, threadSequence)
-
-       def addToBoundary(self, vector3):
-               'Add vector3 to boundary.'
-               self.boundary.append(vector3.dropAxis())
-               self.z = vector3.z
-
-       def addToLoop(self, vector3):
-               'Add vector3 to loop.'
-               if self.loop == None:
-                       self.loop = []
-               self.loop.append(vector3.dropAxis())
-               self.z = vector3.z
-
-       def addToThreads(self, extrusionHalfWidth, oldOrderedLocation, skein, threadSequence):
-               'Add to paths from the last location.'
-               addNestedRingBeginning(skein.distanceFeedRate, self.boundary, self.z)
-               threadFunctionDictionary = {
-                       'infill' : self.transferInfillPaths, 'loops' : self.transferClosestFillLoops, 'edge' : self.addPerimeterInner}
-               for threadType in threadSequence:
-                       threadFunctionDictionary[threadType](extrusionHalfWidth, oldOrderedLocation, skein, threadSequence)
-               skein.distanceFeedRate.addLine('(</nestedRing>)')
-
-       def getFillLoops(self, penultimateFillLoops):
-               'Get last fill loops from the outside loop and the loops inside the inside loops.'
-               fillLoops = self.getLoopsToBeFilled()[:]
-               surroundingBoundaries = self.getSurroundingBoundaries()
-               withinLoops = []
-               if penultimateFillLoops == None:
-                       penultimateFillLoops = self.penultimateFillLoops
-               if penultimateFillLoops == None:
-                       print('Warning, penultimateFillLoops == None in getFillLoops in NestedBand in euclidean.')
-                       return fillLoops
-               for penultimateFillLoop in penultimateFillLoops:
-                       if len(penultimateFillLoop) > 2:
-                               if getIsInFilledRegion(surroundingBoundaries, penultimateFillLoop[0]):
-                                       withinLoops.append(penultimateFillLoop)
-               if not getIsInFilledRegionByPaths(self.penultimateFillLoops, fillLoops):
-                       fillLoops += self.penultimateFillLoops
-               for nestedRing in self.innerNestedRings:
-                       fillLoops += getFillOfSurroundings(nestedRing.innerNestedRings, penultimateFillLoops)
-               return fillLoops
-#
-#      def getLastExistingFillLoops(self):
-#              'Get last existing fill loops.'
-#              lastExistingFillLoops = self.lastExistingFillLoops[:]
-#              for nestedRing in self.innerNestedRings:
-#                      lastExistingFillLoops += nestedRing.getLastExistingFillLoops()
-#              return lastExistingFillLoops
-
-       def getLoopsToBeFilled(self):
-               'Get last fill loops from the outside loop and the loops inside the inside loops.'
-               if self.lastFillLoops == None:
-                       return self.getSurroundingBoundaries()
-               return self.lastFillLoops
-
-       def getSurroundingBoundaries(self):
-               'Get the boundary of the surronding loop plus any boundaries of the innerNestedRings.'
-               surroundingBoundaries = [self.boundary]
-               for nestedRing in self.innerNestedRings:
-                       surroundingBoundaries.append(nestedRing.boundary)
-               return surroundingBoundaries
-
-       def transferClosestFillLoops(self, extrusionHalfWidth, oldOrderedLocation, skein, threadSequence):
-               'Transfer closest fill loops.'
-               if len( self.extraLoops ) < 1:
-                       return
-               remainingFillLoops = self.extraLoops[:]
-               while len( remainingFillLoops ) > 0:
-                       transferClosestFillLoop(extrusionHalfWidth, oldOrderedLocation, remainingFillLoops, skein)
-
-       def transferInfillPaths(self, extrusionHalfWidth, oldOrderedLocation, skein, threadSequence):
-               'Transfer the infill paths.'
-               if len(self.infillBoundaries) == 0 and len(self.infillPaths) == 0:
-                       return 
-               skein.distanceFeedRate.addLine('(<infill>)')
-               for infillBoundary in self.infillBoundaries:
-                       skein.distanceFeedRate.addLine('(<infillBoundary>)')
-                       for infillPoint in infillBoundary:
-                               infillPointVector3 = Vector3(infillPoint.real, infillPoint.imag, self.z)
-                               skein.distanceFeedRate.addLine(skein.distanceFeedRate.getInfillBoundaryLine(infillPointVector3))
-                       skein.distanceFeedRate.addLine('(</infillBoundary>)')
-               transferClosestPaths(oldOrderedLocation, self.infillPaths[:], skein)
-               skein.distanceFeedRate.addLine('(</infill>)')
-
-       def transferPaths(self, paths):
-               'Transfer paths.'
-               for nestedRing in self.innerNestedRings:
-                       transferPathsToNestedRings(nestedRing.innerNestedRings, paths)
-               self.infillPaths = getTransferredPaths(paths, self.boundary)
-
-
-class PathZ(object):
-       'Complex path with a z.'
-       def __init__( self, z ):
-               self.path = []
-               self.z = z
-
-       def __repr__(self):
-               'Get the string representation of this path z.'
-               return '%s, %s' % ( self.z, self.path )
-
-
-class ProjectiveSpace(object):
-       'Class to define a projective space.'
-       def __init__( self, basisX = Vector3(1.0, 0.0, 0.0), basisY = Vector3( 0.0, 1.0, 0.0 ), basisZ = Vector3(0.0, 0.0, 1.0) ):
-               'Initialize the basis vectors.'
-               self.basisX = basisX
-               self.basisY = basisY
-               self.basisZ = basisZ
-
-       def __repr__(self):
-               'Get the string representation of this ProjectivePlane.'
-               return '%s, %s, %s' % ( self.basisX, self.basisY, self.basisZ )
-
-       def getByBasisXZ( self, basisX, basisZ ):
-               'Get by x basis x and y basis.'
-               self.basisX = basisX
-               self.basisZ = basisZ
-               self.basisX.normalize()
-               self.basisY = basisZ.cross(self.basisX)
-               self.basisY.normalize()
-               return self
-
-       def getByBasisZFirst(self, basisZ, firstVector3):
-               'Get by basisZ and first.'
-               self.basisZ = basisZ
-               self.basisY = basisZ.cross(firstVector3)
-               self.basisY.normalize()
-               self.basisX = self.basisY.cross(self.basisZ)
-               self.basisX.normalize()
-               return self
-
-       def getByBasisZTop(self, basisZ, top):
-               'Get by basisZ and top.'
-               return self.getByBasisXZ(top.cross(basisZ), basisZ)
-
-       def getByLatitudeLongitude( self, viewpointLatitude, viewpointLongitude ):
-               'Get by latitude and longitude.'
-               longitudeComplex = getWiddershinsUnitPolar( math.radians( 90.0 - viewpointLongitude ) )
-               viewpointLatitudeRatio = getWiddershinsUnitPolar( math.radians( viewpointLatitude ) )
-               basisZ = Vector3( viewpointLatitudeRatio.imag * longitudeComplex.real, viewpointLatitudeRatio.imag * longitudeComplex.imag, viewpointLatitudeRatio.real )
-               return self.getByBasisXZ( Vector3( - longitudeComplex.imag, longitudeComplex.real, 0.0 ), basisZ )
-
-       def getByTilt( self, tilt ):
-               'Get by latitude and longitude.'
-               xPlaneAngle = getWiddershinsUnitPolar( tilt.real )
-               self.basisX = Vector3( xPlaneAngle.real, 0.0,  xPlaneAngle.imag )
-               yPlaneAngle = getWiddershinsUnitPolar( tilt.imag )
-               self.basisY = Vector3( 0.0,  yPlaneAngle.real, yPlaneAngle.imag )
-               self.basisZ = self.basisX.cross(self.basisY)
-               return self
-
-       def getComplexByComplex( self, pointComplex ):
-               'Get complex by complex point.'
-               return self.basisX.dropAxis() * pointComplex.real + self.basisY.dropAxis() * pointComplex.imag
-
-       def getCopy(self):
-               'Get copy.'
-               return ProjectiveSpace( self.basisX, self.basisY, self.basisZ )
-
-       def getDotComplex(self, point):
-               'Get the dot complex.'
-               return complex( point.dot(self.basisX), point.dot(self.basisY) )
-
-       def getDotVector3(self, point):
-               'Get the dot vector3.'
-               return Vector3(point.dot(self.basisX), point.dot(self.basisY), point.dot(self.basisZ))
-
-       def getNextSpace( self, nextNormal ):
-               'Get next space by next normal.'
-               nextSpace = self.getCopy()
-               nextSpace.normalize()
-               dotNext = nextSpace.basisZ.dot( nextNormal )
-               if dotNext > 0.999999:
-                       return nextSpace
-               if dotNext < - 0.999999:
-                       nextSpace.basisX = - nextSpace.basisX
-                       return nextSpace
-               crossNext = nextSpace.basisZ.cross( nextNormal )
-               oldBasis = ProjectiveSpace().getByBasisZTop( nextSpace.basisZ, crossNext )
-               newBasis = ProjectiveSpace().getByBasisZTop( nextNormal, crossNext )
-               nextSpace.basisX = newBasis.getVector3ByPoint( oldBasis.getDotVector3( nextSpace.basisX ) )
-               nextSpace.basisY = newBasis.getVector3ByPoint( oldBasis.getDotVector3( nextSpace.basisY ) )
-               nextSpace.basisZ = newBasis.getVector3ByPoint( oldBasis.getDotVector3( nextSpace.basisZ ) )
-               nextSpace.normalize()
-               return nextSpace
-
-       def getSpaceByXYScaleAngle( self, angle, scale ):
-               'Get space by angle and scale.'
-               spaceByXYScaleRotation = ProjectiveSpace()
-               planeAngle = getWiddershinsUnitPolar(angle)
-               spaceByXYScaleRotation.basisX = self.basisX * scale.real * planeAngle.real + self.basisY * scale.imag * planeAngle.imag
-               spaceByXYScaleRotation.basisY = - self.basisX * scale.real * planeAngle.imag + self.basisY * scale.imag * planeAngle.real
-               spaceByXYScaleRotation.basisZ = self.basisZ
-               return spaceByXYScaleRotation
-
-       def getVector3ByPoint(self, point):
-               'Get vector3 by point.'
-               return self.basisX * point.x + self.basisY * point.y + self.basisZ * point.z
-
-       def normalize(self):
-               'Normalize.'
-               self.basisX.normalize()
-               self.basisY.normalize()
-               self.basisZ.normalize()
-
-       def unbuckle( self, maximumUnbuckling, normal ):
-               'Unbuckle space.'
-               unbuckleBasis( self.basisX, maximumUnbuckling, normal )
-               unbuckleBasis( self.basisY, maximumUnbuckling, normal )
-
-
-class XIntersectionIndex(object):
-       'A class to hold the x intersection position and the index of the loop which intersected.'
-       def __init__( self, index, x ):
-               'Initialize.'
-               self.index = index
-               self.x = x
-
-       def __cmp__(self, other):
-               'Get comparison in order to sort x intersections in ascending order of x.'
-               if self.x < other.x:
-                       return - 1
-               return int( self.x > other.x )
-
-       def __eq__(self, other):
-               'Determine whether this XIntersectionIndex is identical to other one.'
-               if other == None:
-                       return False
-               if other.__class__ != self.__class__:
-                       return False
-               return self.index == other.index and self.x == other.x
-
-       def __ne__(self, other):
-               'Determine whether this XIntersectionIndex is not identical to other one.'
-               return not self.__eq__(other)
-
-       def __repr__(self):
-               'Get the string representation of this x intersection.'
-               return 'XIntersectionIndex index %s; x %s ' % ( self.index, self.x )
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/fabmetheus_interpret.py b/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/fabmetheus_interpret.py
deleted file mode 100644 (file)
index 3e2153e..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-"""
-Fabmetheus interpret is a fabmetheus utility to interpret a file, turning it into fabmetheus constructive solid geometry xml.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import os
-import time
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCarving(fileName):
-       "Get carving."
-       pluginModule = getInterpretPlugin(fileName)
-       if pluginModule == None:
-               return None
-       return pluginModule.getCarving(fileName)
-
-def getGNUTranslatorFilesUnmodified():
-       "Get the file types from the translators in the import plugins folder."
-       return archive.getFilesWithFileTypesWithoutWords(getImportPluginFileNames())
-
-def getGNUTranslatorGcodeFileTypeTuples():
-       "Get the file type tuples from the translators in the import plugins folder plus gcode."
-       fileTypeTuples = [] #getTranslatorFileTypeTuples()
-       fileTypeTuples.append( ('Gcode text files', '*.gcode') )
-       fileTypeTuples.sort()
-       return fileTypeTuples
-
-def getImportPluginFileNames():
-       "Get interpret plugin fileNames."
-       return archive.getPluginFileNamesFromDirectoryPath( getPluginsDirectoryPath() )
-
-def getInterpretPlugin(fileName):
-       "Get the interpret plugin for the file."
-       importPluginFileNames = getImportPluginFileNames()
-       for importPluginFileName in importPluginFileNames:
-               fileTypeDot = '.' + importPluginFileName
-               if fileName[ - len(fileTypeDot) : ].lower() == fileTypeDot:
-                       importPluginsDirectoryPath = getPluginsDirectoryPath()
-                       pluginModule = archive.getModuleWithDirectoryPath( importPluginsDirectoryPath, importPluginFileName )
-                       if pluginModule != None:
-                               return pluginModule
-       print('Could not find plugin to handle ' + fileName )
-       return None
-
-def getNewRepository():
-       'Get new repository.'
-       return InterpretRepository()
-
-def getPluginsDirectoryPath():
-       "Get the plugins directory path."
-       return archive.getInterpretPluginsPath()
-
-def getTranslatorFileTypeTuples():
-       "Get the file types from the translators in the import plugins folder."
-       importPluginFileNames = getImportPluginFileNames()
-       fileTypeTuples = []
-       for importPluginFileName in importPluginFileNames:
-               fileTypeTitle = importPluginFileName.upper() + ' files'
-               fileType = ( fileTypeTitle, '*.' + importPluginFileName )
-               fileTypeTuples.append( fileType )
-       fileTypeTuples.sort()
-       return fileTypeTuples
-
-def getWindowAnalyzeFile(fileName):
-       "Get file interpretion."
-       startTime = time.time()
-       carving = getCarving(fileName)
-       if carving == None:
-               return None
-       interpretGcode = str( carving )
-       if interpretGcode == '':
-               return None
-       repository = settings.getReadRepository( InterpretRepository() )
-       if repository.printInterpretion.value:
-               print(interpretGcode)
-       suffixFileName = fileName[ : fileName.rfind('.') ] + '_interpret.' + carving.getInterpretationSuffix()
-       suffixDirectoryName = os.path.dirname(suffixFileName)
-       suffixReplacedBaseName = os.path.basename(suffixFileName).replace(' ', '_')
-       suffixFileName = os.path.join( suffixDirectoryName, suffixReplacedBaseName )
-       archive.writeFileText( suffixFileName, interpretGcode )
-       print('The interpret file is saved as ' + archive.getSummarizedFileName(suffixFileName) )
-       print('It took %s to interpret the file.' % euclidean.getDurationString( time.time() - startTime ) )
-       textProgram = repository.textProgram.value
-       if textProgram == '':
-               return None
-       if textProgram == 'webbrowser':
-               settings.openWebPage(suffixFileName)
-               return None
-       textFilePath = '"' + os.path.normpath(suffixFileName) + '"' # " to send in file name with spaces
-       shellCommand = textProgram + ' ' + textFilePath
-       print('Sending the shell command:')
-       print(shellCommand)
-       commandResult = os.system(shellCommand)
-       if commandResult != 0:
-               print('It may be that the system could not find the %s program.' % textProgram )
-               print('If so, try installing the %s program or look for another one, like Open Office which can be found at:' % textProgram )
-               print('http://www.openoffice.org/')
-               print('Open office writer can then be started from the command line with the command "soffice -writer".')
-
-
-class InterpretRepository(object):
-       "A class to handle the interpret settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.analyze_plugins.interpret.html', self)
-               self.fileNameInput = settings.FileNameInput().getFromFileName( getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Interpret', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Interpret')
-               self.activateInterpret = settings.BooleanSetting().getFromValue('Activate Interpret', self, False )
-               self.printInterpretion = settings.BooleanSetting().getFromValue('Print Interpretion', self, False )
-               self.textProgram = settings.StringSetting().getFromValue('Text Program:', self, 'webbrowser')
-               self.executeTitle = 'Interpret'
-
-       def execute(self):
-               "Write button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrGcodeDirectory( self.fileNameInput.value, self.fileNameInput.wasCancelled )
-               for fileName in fileNames:
-                       getWindowAnalyzeFile(fileName)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/amf.py b/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/amf.py
deleted file mode 100644 (file)
index b5ddfc4..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-from __future__ import absolute_import
-
-import zipfile
-try:
-       from xml.etree import cElementTree as ElementTree
-except:
-       from xml.etree import ElementTree
-
-from fabmetheus_utilities.geometry.geometry_tools import face
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-
-def getCarving(fileName=''):
-       "Get the triangle mesh for the dae file."
-       return amfModel().load(fileName)
-
-class amfModel(triangle_mesh.TriangleMesh):
-       def __init__(self):
-               super(amfModel, self).__init__()
-
-       def load(self, filename):
-               try:
-                       zfile = zipfile.ZipFile(filename)
-                       xml = zfile.read(zfile.namelist()[0])
-                       zfile.close()
-               except zipfile.BadZipfile:
-                       f = open(filename, "r")
-                       xml = f.read()
-                       f.close()
-               amf = ElementTree.fromstring(xml)
-               if 'unit' in amf.attrib:
-                       unit = amf.attrib['unit'].lower()
-               else:
-                       unit = 'millimeter'
-               if unit == 'millimeter':
-                       scale = 1.0
-               elif unit == 'meter':
-                       scale = 1000.0
-               elif unit == 'inch':
-                       scale = 25.4
-               elif unit == 'feet':
-                       scale = 304.8
-               elif unit == 'micron':
-                       scale = 0.001
-               else:
-                       print "Unknown unit in amf: %s" % (unit)
-                       scale = 1.0
-
-               for obj in amf.iter('object'):
-                       for mesh in obj.iter('mesh'):
-                               startIndex = len(self.vertexes)
-                               for vertices in mesh.iter('vertices'):
-                                       for vertex in vertices.iter('vertex'):
-                                               for coordinates in vertex.iter('coordinates'):
-                                                       v = [0.0,0.0,0.0]
-                                                       for t in coordinates:
-                                                               if t.tag == 'x':
-                                                                       v[0] = float(t.text)
-                                                               elif t.tag == 'y':
-                                                                       v[1] = float(t.text)
-                                                               elif t.tag == 'z':
-                                                                       v[2] = float(t.text)
-                                                       self.vertexes.append(Vector3(v[0], v[1], v[2]))
-                               for volume in mesh.iter('volume'):
-                                       for triangle in volume.iter('triangle'):
-                                               f = face.Face()
-                                               f.index = len(self.faces)
-                                               for t in triangle:
-                                                       if t.tag == 'v1' or t.tag == 'v2' or t.tag == 'v3':
-                                                               f.vertexIndexes.append(startIndex + int(t.text))
-                                               self.faces.append(f)
-               return self
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/csv.py b/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/csv.py
deleted file mode 100644 (file)
index e05accf..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-"""
-This page is in the table of contents.
-The csv.py script is an import translator plugin to get a carving from an csv file.
-
-An import plugin is a script in the interpret_plugins folder which has the function getCarving.  It is meant to be run from the interpret tool.  To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.
-
-The getCarving function takes the file name of an csv file and returns the carving.
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import xml_simple_reader
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCarving(fileName=''):
-       "Get the carving for the csv file."
-       csvText = archive.getFileText(fileName)
-       if csvText == '':
-               return None
-       csvParser = CSVSimpleParser( fileName, None, csvText )
-       lowerLocalName = csvParser.getDocumentElement().getNodeName().lower()
-       pluginModule = archive.getModuleWithDirectoryPath( getPluginsDirectoryPath(), lowerLocalName )
-       if pluginModule == None:
-               return None
-       return pluginModule.getCarvingFromParser( csvParser )
-
-def getLineDictionary(line):
-       "Get the line dictionary."
-       lineDictionary = {}
-       splitLine = line.split('\t')
-       for splitLineIndex in xrange( len(splitLine) ):
-               word = splitLine[ splitLineIndex ]
-               if word != '':
-                       lineDictionary[ splitLineIndex ] = word
-       return lineDictionary
-
-def getPluginsDirectoryPath():
-       "Get the plugins directory path."
-       return archive.getInterpretPluginsPath('xml_plugins')
-
-
-class CSVElement( xml_simple_reader.XMLElement ):
-       "A csv element."
-       def continueParsingObject( self, line, lineStripped ):
-               "Parse replaced line."
-               splitLineStripped = lineStripped.split('\t')
-               key = splitLineStripped[0]
-               value = splitLineStripped[1]
-               self.attributes[key] = value
-               self.addToIdentifierDictionaries()
-
-       def continueParsingTable( self, line, lineStripped ):
-               "Parse replaced line."
-               if self.headingDictionary == None:
-                       self.headingDictionary = getLineDictionary(line)
-                       return
-               csvElement = self
-               oldAttributesLength = len( self.attributes )
-               if oldAttributesLength > 0:
-                       csvElement = CSVElement()
-               csvElement.parentNode = self.parentNode
-               csvElement.localName = self.localName
-               lineDictionary = getLineDictionary(line)
-               for columnIndex in lineDictionary.keys():
-                       if columnIndex in self.headingDictionary:
-                               key = self.headingDictionary[ columnIndex ]
-                               value = lineDictionary[ columnIndex ]
-                               csvElement.attributes[key] = value
-               csvElement.addToIdentifierDictionaries()
-               if len( csvElement.attributes ) == 0 or oldAttributesLength == 0 or self.parentNode == None:
-                       return
-               self.parentNode.childNodes.append( csvElement )
-
-       def getElementFromObject( self, leadingTabCount, lineStripped, oldElement ):
-               "Parse replaced line."
-               splitLine = lineStripped.split('\t')
-               self.localName = splitLine[1]
-               if leadingTabCount == 0:
-                       return self
-               self.parentNode = oldElement
-               while leadingTabCount <= self.parentNode.getNumberOfParents():
-                       self.parentNode = self.parentNode.parentNode
-               self.parentNode.childNodes.append(self)
-               return self
-
-       def getElementFromTable( self, leadingTabCount, lineStripped, oldElement ):
-               "Parse replaced line."
-               self.headingDictionary = None
-               return self.getElementFromObject( leadingTabCount, lineStripped, oldElement )
-
-       def getNumberOfParents(self):
-               "Get the number of parent nodes."
-               if self.parentNode == None:
-                       return 0
-               return self.parentNode.getNumberOfParents() + 1
-
-
-class CSVSimpleParser( xml_simple_reader.DocumentNode ):
-       "A simple csv parser."
-       def __init__( self, parentNode, csvText ):
-               "Add empty lists."
-               self.continueFunction = None
-               self.extraLeadingTabCount = None
-               self.lines = archive.getTextLines( csvText )
-               self.oldCSVElement = None
-               self.documentElement = None
-               for line in self.lines:
-                       self.parseLine(line)
-
-       def getNewCSVElement( self, leadingTabCount, lineStripped ):
-               "Get a new csv element."
-               if self.documentElement != None and self.extraLeadingTabCount == None:
-                       self.extraLeadingTabCount = 1 - leadingTabCount
-               if self.extraLeadingTabCount != None:
-                       leadingTabCount += self.extraLeadingTabCount
-               if lineStripped[ : len('_table') ] == '_table' or lineStripped[ : len('_t') ] == '_t':
-                       self.oldCSVElement = CSVElement().getElementFromTable( leadingTabCount, lineStripped, self.oldCSVElement )
-                       self.continueFunction = self.oldCSVElement.continueParsingTable
-                       return
-               self.oldCSVElement = CSVElement().getElementFromObject( leadingTabCount, lineStripped, self.oldCSVElement )
-               self.continueFunction = self.oldCSVElement.continueParsingObject
-
-       def parseLine(self, line):
-               "Parse a gcode line and add it to the inset skein."
-               lineStripped = line.lstrip()
-               if len( lineStripped ) < 1:
-                       return
-               leadingPart = line[ : line.find( lineStripped ) ]
-               leadingTabCount = leadingPart.count('\t')
-               if lineStripped[ : len('_') ] == '_':
-                       self.getNewCSVElement( leadingTabCount, lineStripped )
-                       if self.documentElement == None:
-                               self.documentElement = self.oldCSVElement
-                               self.documentElement.document = self
-                       return
-               if self.continueFunction != None:
-                       self.continueFunction( line, lineStripped )
-
-
-def main():
-       "Display the inset dialog."
-       if len(sys.argv) > 1:
-               getCarving(' '.join(sys.argv[1 :]))
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/dae.py b/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/dae.py
deleted file mode 100644 (file)
index 96e96f0..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_tools import face
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-
-from  xml.parsers.expat import ParserCreate
-
-def getCarving(fileName=''):
-       "Get the triangle mesh for the dae file."
-       return daeModel().load(fileName)
-
-class daeModel(triangle_mesh.TriangleMesh):
-       def __init__(self):
-               triangle_mesh.TriangleMesh.__init__(self)
-
-       def load(self, filename):
-               r = ParserCreate()
-               r.StartElementHandler = self._StartElementHandler
-               r.EndElementHandler = self._EndElementHandler
-               r.CharacterDataHandler = self._CharacterDataHandler
-
-               self._base = {}
-               self._cur = self._base
-               self._idMap = {}
-               self._geometryList = []
-               r.ParseFile(open(filename, "r"))
-
-               self._scale = float(self._base['collada'][0]['asset'][0]['unit'][0]['_meter']) * 1000
-               
-               for instance_visual_scene in self._base['collada'][0]['scene'][0]['instance_visual_scene']:
-                       for node in self._idMap[instance_visual_scene['_url']]['node']:
-                               self._ProcessNode2(node)
-               
-               self._base = None
-               self._cur = None
-               self._idMap = None
-               
-               return self
-       
-       def _ProcessNode2(self, node, matrix = None):
-               if 'matrix' in node:
-                       oldMatrix = matrix
-                       matrix = map(float, node['matrix'][0]['__data'].split())
-                       if oldMatrix != None:
-                               newMatrix = [0]*16
-                               newMatrix[0] = oldMatrix[0] * matrix[0] + oldMatrix[1] * matrix[4] + oldMatrix[2] * matrix[8] + oldMatrix[3] * matrix[12]
-                               newMatrix[1] = oldMatrix[0] * matrix[1] + oldMatrix[1] * matrix[5] + oldMatrix[2] * matrix[9] + oldMatrix[3] * matrix[13]
-                               newMatrix[2] = oldMatrix[0] * matrix[2] + oldMatrix[1] * matrix[6] + oldMatrix[2] * matrix[10] + oldMatrix[3] * matrix[14]
-                               newMatrix[3] = oldMatrix[0] * matrix[3] + oldMatrix[1] * matrix[7] + oldMatrix[2] * matrix[11] + oldMatrix[3] * matrix[15]
-                               newMatrix[4] = oldMatrix[4] * matrix[0] + oldMatrix[5] * matrix[4] + oldMatrix[6] * matrix[8] + oldMatrix[7] * matrix[12]
-                               newMatrix[5] = oldMatrix[4] * matrix[1] + oldMatrix[5] * matrix[5] + oldMatrix[6] * matrix[9] + oldMatrix[7] * matrix[13]
-                               newMatrix[6] = oldMatrix[4] * matrix[2] + oldMatrix[5] * matrix[6] + oldMatrix[6] * matrix[10] + oldMatrix[7] * matrix[14]
-                               newMatrix[7] = oldMatrix[4] * matrix[3] + oldMatrix[5] * matrix[7] + oldMatrix[6] * matrix[11] + oldMatrix[7] * matrix[15]
-                               newMatrix[8] = oldMatrix[8] * matrix[0] + oldMatrix[9] * matrix[4] + oldMatrix[10] * matrix[8] + oldMatrix[11] * matrix[12]
-                               newMatrix[9] = oldMatrix[8] * matrix[1] + oldMatrix[9] * matrix[5] + oldMatrix[10] * matrix[9] + oldMatrix[11] * matrix[13]
-                               newMatrix[10] = oldMatrix[8] * matrix[2] + oldMatrix[9] * matrix[6] + oldMatrix[10] * matrix[10] + oldMatrix[11] * matrix[14]
-                               newMatrix[11] = oldMatrix[8] * matrix[3] + oldMatrix[9] * matrix[7] + oldMatrix[10] * matrix[11] + oldMatrix[11] * matrix[15]
-                               newMatrix[12] = oldMatrix[12] * matrix[0] + oldMatrix[13] * matrix[4] + oldMatrix[14] * matrix[8] + oldMatrix[15] * matrix[12]
-                               newMatrix[13] = oldMatrix[12] * matrix[1] + oldMatrix[13] * matrix[5] + oldMatrix[14] * matrix[9] + oldMatrix[15] * matrix[13]
-                               newMatrix[14] = oldMatrix[12] * matrix[2] + oldMatrix[13] * matrix[6] + oldMatrix[14] * matrix[10] + oldMatrix[15] * matrix[14]
-                               newMatrix[15] = oldMatrix[12] * matrix[3] + oldMatrix[13] * matrix[7] + oldMatrix[14] * matrix[11] + oldMatrix[15] * matrix[15]
-                               matrix = newMatrix
-               if 'node' in node:
-                       for n in node['node']:
-                               self._ProcessNode2(n, matrix)
-               if 'instance_geometry' in node:
-                       for instance_geometry in node['instance_geometry']:
-                               mesh = self._idMap[instance_geometry['_url']]['mesh'][0]
-                               
-                               if 'triangles' in mesh:
-                                       for triangles in mesh['triangles']:
-                                               for input in triangles['input']:
-                                                       if input['_semantic'] == 'VERTEX':
-                                                               vertices = self._idMap[input['_source']]
-                                               for input in vertices['input']:
-                                                       if input['_semantic'] == 'POSITION':
-                                                               vertices = self._idMap[input['_source']]
-                                               indexList = map(int, triangles['p'][0]['__data'].split())
-                                               positionList = map(float, vertices['float_array'][0]['__data'].split())
-
-                                               startIndex = len(self.vertexes)
-                                               for idx in xrange(0, len(positionList)/3):
-                                                       x = positionList[idx*3] * self._scale
-                                                       y = positionList[idx*3+1] * self._scale
-                                                       z = positionList[idx*3+2] * self._scale
-                                                       if matrix != None:
-                                                               self.vertexes.append(Vector3(x * matrix[0] + y * matrix[1] + z * matrix[2] + matrix[3], x * matrix[4] + y * matrix[5] + z * matrix[6] + matrix[7], x * matrix[8] + y * matrix[9] + z * matrix[10] + matrix[11]))
-                                                       else:
-                                                               self.vertexes.append(Vector3(x, y, z))
-                                               stepSize = len(indexList) / (int(triangles['_count']) * 3)
-                                               for i in xrange(0, int(triangles['_count'])):
-                                                       idx = i * stepSize * 3
-                                                       f = face.Face()
-                                                       f.index = len(self.faces)
-                                                       f.vertexIndexes.append(startIndex + indexList[idx])
-                                                       f.vertexIndexes.append(startIndex + indexList[idx+stepSize])
-                                                       f.vertexIndexes.append(startIndex + indexList[idx+stepSize*2])
-                                                       self.faces.append(f)
-
-               if 'instance_node' in node:
-                       for instance_node in node['instance_node']:
-                               self._ProcessNode2(self._idMap[instance_node['_url']], matrix)
-       
-       def _StartElementHandler(self, name, attributes):
-               name = name.lower()
-               if not name in self._cur:
-                       self._cur[name] = []
-               new = {'__name': name, '__parent': self._cur}
-               self._cur[name].append(new)
-               self._cur = new
-               for k in attributes.keys():
-                       self._cur['_' + k] = attributes[k]
-               
-               if 'id' in attributes:
-                       self._idMap['#' + attributes['id']] = self._cur
-               
-       def _EndElementHandler(self, name):
-               self._cur = self._cur['__parent']
-
-       def _CharacterDataHandler(self, data):
-               if len(data.strip()) < 1:
-                       return
-               if '__data' in self._cur:
-                       self._cur['__data'] += data
-               else:
-                       self._cur['__data'] = data
-       
-       def _GetWithKey(self, item, basename, key, value):
-               input = basename
-               while input in item:
-                       if item[basename]['_'+key] == value:
-                               return self._idMap[item[input]['_source']]
-                       basename += "!"
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/gts.py b/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/gts.py
deleted file mode 100644 (file)
index c5dd895..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-"""
-This page is in the table of contents.
-The gts.py script is an import translator plugin to get a carving from an gts file.
-
-An import plugin is a script in the interpret_plugins folder which has the function getCarving.  It is meant to be run from the interpret tool.  To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.
-
-The getCarving function takes the file name of an gts file and returns the carving.
-
-The GNU Triangulated Surface (.gts) format is described at:
-http://gts.sourceforge.net/reference/gts-surfaces.html#GTS-SURFACE-WRITE
-
-Quoted from http://gts.sourceforge.net/reference/gts-surfaces.html#GTS-SURFACE-WRITE
-"All the lines beginning with GTS_COMMENTS (#!) are ignored. The first line contains three unsigned integers separated by spaces. The first integer is the number of vertexes, nv, the second is the number of edges, ne and the third is the number of faces, nf.
-
-Follows nv lines containing the x, y and z coordinates of the vertexes. Follows ne lines containing the two indices (starting from one) of the vertexes of each edge. Follows nf lines containing the three ordered indices (also starting from one) of the edges of each face.
-
-The format described above is the least common denominator to all GTS files. Consistent with an object-oriented approach, the GTS file format is extensible. Each of the lines of the file can be extended with user-specific attributes accessible through the read() and write() virtual methods of each of the objects written (surface, vertexes, edges or faces). When read with different object classes, these extra attributes are just ignored."
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_tools import face
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import archive
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCarving(fileName):
-       "Get the carving for the gts file."
-       return getFromGNUTriangulatedSurfaceText( archive.getFileText(fileName), triangle_mesh.TriangleMesh() )
-
-def getFromGNUTriangulatedSurfaceText( gnuTriangulatedSurfaceText, triangleMesh ):
-       "Initialize from a GNU Triangulated Surface Text."
-       if gnuTriangulatedSurfaceText == '':
-               return None
-       lines = archive.getTextLines( gnuTriangulatedSurfaceText )
-       linesWithoutComments = []
-       for line in lines:
-               if len(line) > 0:
-                       firstCharacter = line[0]
-                       if firstCharacter != '#' and firstCharacter != '!':
-                               linesWithoutComments.append(line)
-       splitLine = linesWithoutComments[0].split()
-       numberOfVertexes = int( splitLine[0] )
-       numberOfEdges = int(splitLine[1])
-       numberOfFaces = int( splitLine[2] )
-       faceTriples = []
-       for vertexIndex in xrange( numberOfVertexes ):
-               line = linesWithoutComments[ vertexIndex + 1 ]
-               splitLine = line.split()
-               vertex = Vector3( float( splitLine[0] ), float(splitLine[1]), float( splitLine[2] ) )
-               triangleMesh.vertexes.append(vertex)
-       edgeStart = numberOfVertexes + 1
-       for edgeIndex in xrange( numberOfEdges ):
-               line = linesWithoutComments[ edgeIndex + edgeStart ]
-               splitLine = line.split()
-               vertexIndexes = []
-               for word in splitLine[ : 2 ]:
-                       vertexIndexes.append( int(word) - 1 )
-               edge = face.Edge().getFromVertexIndexes( edgeIndex, vertexIndexes )
-               triangleMesh.edges.append( edge )
-       faceStart = edgeStart + numberOfEdges
-       for faceIndex in xrange( numberOfFaces ):
-               line = linesWithoutComments[ faceIndex + faceStart ]
-               splitLine = line.split()
-               edgeIndexes = []
-               for word in splitLine[ : 3 ]:
-                       edgeIndexes.append( int(word) - 1 )
-               triangleMesh.faces.append( face.Face().getFromEdgeIndexes( edgeIndexes, triangleMesh.edges, faceIndex ) )
-       return triangleMesh
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/obj.py b/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/obj.py
deleted file mode 100644 (file)
index 2a479b3..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-"""
-This page is in the table of contents.
-The obj.py script is an import translator plugin to get a carving from an obj file.
-
-An example obj file is box.obj in the models folder.
-
-An import plugin is a script in the interpret_plugins folder which has the function getCarving.  It is meant to be run from the interpret tool.  To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.
-
-The getCarving function takes the file name of an obj file and returns the carving.
-
-From wikipedia, OBJ (or .OBJ) is a geometry definition file format first developed by Wavefront Technologies for its Advanced Visualizer animation package:
-http://en.wikipedia.org/wiki/Obj
-
-The Object File specification is at:
-http://local.wasp.uwa.edu.au/~pbourke/dataformats/obj/
-
-An excellent link page about obj files is at:
-http://people.sc.fsu.edu/~burkardt/data/obj/obj.html
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_tools import face
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addFacesGivenText( objText, triangleMesh ):
-       "Add faces given obj text."
-       lines = archive.getTextLines( objText )
-       for line in lines:
-               splitLine = line.split()
-               firstWord = gcodec.getFirstWord(splitLine)
-               if firstWord == 'v':
-                       triangleMesh.vertexes.append( getVertexGivenLine(line) )
-               elif firstWord == 'f':
-                       addFacesGivenLine( triangleMesh.faces, line )
-
-def getCarving(fileName=''):
-       "Get the triangle mesh for the obj file."
-       if fileName == '':
-               return None
-       objText = archive.getFileText(fileName, True, 'rb')
-       if objText == '':
-               return None
-       triangleMesh = triangle_mesh.TriangleMesh()
-       addFacesGivenText(objText, triangleMesh)
-       return triangleMesh
-
-def addFacesGivenLine( faces, line ):
-       "Add face given line index and lines."
-       parts = map(lambda p: p.split('/')[0], line.split())
-       for idx in xrange(1, len(parts)-2):
-               addface = face.Face()
-               addface.index = len( faces )
-               addface.vertexIndexes.append(int(parts[1]) - 1)
-               addface.vertexIndexes.append(int(parts[idx+1]) - 1)
-               addface.vertexIndexes.append(int(parts[idx+2]) - 1)
-               faces.append(addface)
-
-def getVertexGivenLine(line):
-       "Get vertex given obj vertex line."
-       splitLine = line.split()
-       return Vector3( float(splitLine[1]), float( splitLine[2] ), float( splitLine[3] ) )
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/slc.py b/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/slc.py
deleted file mode 100644 (file)
index 32f4b75..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-"""
-This page is in the table of contents.
-The slc.py script is an import translator plugin to get a carving from an [http://rapid.lpt.fi/archives/rp-ml-1999/0713.html slc file].
-
-An import plugin is a script in the interpret_plugins folder which has the function getCarving.  It is meant to be run from the interpret tool.  To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.
-
-The getCarving function takes the file name of an slc file and returns the carving.
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import svg_writer
-from struct import unpack
-import math
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCarving(fileName=''):
-       "Get the triangle mesh for the slc file."
-       carving = SLCCarving()
-       carving.readFile(fileName)
-       return carving
-
-def getLittleEndianFloatGivenFile( file ):
-       "Get little endian float given a file."
-       return unpack('<f', file.read(4) )[0]
-
-def getLittleEndianUnsignedLongGivenFile( file ):
-       "Get little endian float given a file."
-       return unpack('<L', file.read(4) )[0]
-
-def getPointsFromFile( numPoints, file ):
-       "Process the vertice points for a given boundary."
-       points = []
-       for pointIndex in xrange( numPoints ):
-               x = getLittleEndianFloatGivenFile( file )
-               y = getLittleEndianFloatGivenFile( file )
-               points.append( complex(x, y) )
-       return points
-
-def readHeader( file ):
-       "Read the slc header."
-       while ord( file.read( 1 ) ) != 0x1A:
-               pass
-
-
-class SampleTableEntry(object):
-       "Sample table entry."
-       def __init__( self, file ):
-               "Read in the sampling table section. It contains a table length (byte) and the table entries."
-               self.min_z_level = getLittleEndianFloatGivenFile( file )
-               self.layer_thickness = getLittleEndianFloatGivenFile( file )
-               self.beam_comp = getLittleEndianFloatGivenFile( file )
-               getLittleEndianFloatGivenFile( file )
-
-       def __repr__(self):
-               "Get the string representation of this sample table entry."
-               return '%s, %s, %s' % ( self.min_z_level, self.layer_thickness, self.beam_comp )
-
-
-class SLCCarving(object):
-       "An slc carving."
-       def __init__(self):
-               "Add empty lists."
-               self.layerHeight = None
-               self.loopLayers = []
-               self.maximumZ = - 987654321.0
-               self.minimumZ = 987654321.0
-       
-       def __repr__(self):
-               "Get the string representation of this carving."
-               return self.getCarvedSVG()
-
-       def addXML(self, depth, output):
-               "Add xml for this object."
-               xml_simple_writer.addXMLFromObjects(depth, self.loopLayers, output)
-
-       def getCarveBoundaryLayers(self):
-               "Get the  boundary layers."
-               return self.loopLayers
-
-       def getCarveCornerMaximum(self):
-               "Get the corner maximum of the vertexes."
-               return self.cornerMaximum
-
-       def getCarveCornerMinimum(self):
-               "Get the corner minimum of the vertexes."
-               return self.cornerMinimum
-
-       def getCarvedSVG(self):
-               "Get the carved svg text."
-               if len(self.loopLayers) < 1:
-                       return ''
-               decimalPlaces = max(0, 2 - int(math.floor(math.log10(self.layerHeight))))
-               self.svgWriter = svg_writer.SVGWriter(True, self.cornerMaximum, self.cornerMinimum, decimalPlaces, self.layerHeight)
-               return self.svgWriter.getReplacedSVGTemplate(self.fileName, self.loopLayers, 'basic')
-
-       def getCarveLayerHeight(self):
-               "Get the layer height."
-               return self.layerHeight
-
-       def getFabmetheusXML(self):
-               "Return the fabmetheus XML."
-               return None
-
-       def getInterpretationSuffix(self):
-               "Return the suffix for a carving."
-               return 'svg'
-
-       def processContourLayers( self, file ):
-               "Process a contour layer at a time until the top of the part."
-               while True:
-                       minLayer = getLittleEndianFloatGivenFile( file )
-                       numContours = getLittleEndianUnsignedLongGivenFile( file )
-                       if numContours == 0xFFFFFFFF:
-                               return
-                       loopLayer = euclidean.LoopLayer( minLayer )
-                       self.loopLayers.append( loopLayer )
-                       for contourIndex in xrange( numContours ):
-                               numPoints = getLittleEndianUnsignedLongGivenFile( file )
-                               numGaps = getLittleEndianUnsignedLongGivenFile( file )
-                               if numPoints > 2:
-                                       loopLayer.loops.append( getPointsFromFile( numPoints, file ) )
-
-       def readFile( self, fileName ):
-               "Read SLC and store the layers."
-               self.fileName = fileName
-               pslcfile = open( fileName, 'rb')
-               readHeader( pslcfile )
-               pslcfile.read( 256 ) #Go past the 256 byte 3D Reserved Section.
-               self.readTableEntry( pslcfile )
-               self.processContourLayers( pslcfile )
-               pslcfile.close()
-               self.cornerMaximum = Vector3(-987654321.0, -987654321.0, self.maximumZ)
-               self.cornerMinimum = Vector3(987654321.0, 987654321.0, self.minimumZ)
-               for loopLayer in self.loopLayers:
-                       for loop in loopLayer.loops:
-                               for point in loop:
-                                       pointVector3 = Vector3(point.real, point.imag, loopLayer.z)
-                                       self.cornerMaximum.maximize(pointVector3)
-                                       self.cornerMinimum.minimize(pointVector3)
-               halfLayerThickness = 0.5 * self.layerHeight
-               self.cornerMaximum.z += halfLayerThickness
-               self.cornerMinimum.z -= halfLayerThickness
-
-       def readTableEntry( self, file ):
-               "Read in the sampling table section. It contains a table length (byte) and the table entries."
-               tableEntrySize = ord( file.read( 1 ) )
-               if tableEntrySize == 0:
-                       print("Sampling table size is zero!")
-                       exit()
-               for index in xrange( tableEntrySize ):
-                       sampleTableEntry = SampleTableEntry( file )
-                       self.layerHeight = sampleTableEntry.layerHeight
-
-       def setCarveImportRadius( self, importRadius ):
-               "Set the import radius."
-               pass
-
-       def setCarveIsCorrectMesh( self, isCorrectMesh ):
-               "Set the is correct mesh flag."
-               pass
-
-       def setCarveLayerHeight( self, layerHeight ):
-               "Set the layer height."
-               pass
-
-
-def main():
-       "Display the inset dialog."
-       if len(sys.argv) > 1:
-               getCarving(' '.join(sys.argv[1 :]))
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/stl.py b/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/stl.py
deleted file mode 100644 (file)
index cb54bf4..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-"""
-This page is in the table of contents.
-The stl.py script is an import translator plugin to get a carving from an stl file.
-
-An import plugin is a script in the interpret_plugins folder which has the function getCarving.  It is meant to be run from the interpret tool.  To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.
-
-The getCarving function takes the file name of an stl file and returns the carving.
-
-STL is an inferior triangle surface format, described at:
-http://en.wikipedia.org/wiki/STL_(file_format)
-
-A good triangle surface format is the GNU Triangulated Surface format which is described at:
-http://gts.sourceforge.net/reference/gts-surfaces.html#GTS-SURFACE-WRITE
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_tools import face
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import archive
-from struct import unpack
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addFacesGivenBinary( stlData, triangleMesh, vertexIndexTable ):
-       "Add faces given stl binary."
-       numberOfVertexes = ( len( stlData ) - 84 ) / 50
-       vertexes = []
-       for vertexIndex in xrange( numberOfVertexes ):
-               byteIndex = 84 + vertexIndex * 50
-               vertexes.append( getVertexGivenBinary( byteIndex + 12, stlData ) )
-               vertexes.append( getVertexGivenBinary( byteIndex + 24, stlData ) )
-               vertexes.append( getVertexGivenBinary( byteIndex + 36, stlData ) )
-       addFacesGivenVertexes( triangleMesh, vertexIndexTable, vertexes )
-
-def addFacesGivenText( stlText, triangleMesh, vertexIndexTable ):
-       "Add faces given stl text."
-       lines = archive.getTextLines( stlText )
-       vertexes = []
-       for line in lines:
-               if line.find('vertex') != - 1:
-                       vertexes.append( getVertexGivenLine(line) )
-       addFacesGivenVertexes( triangleMesh, vertexIndexTable, vertexes )
-
-def addFacesGivenVertexes( triangleMesh, vertexIndexTable, vertexes ):
-       "Add faces given stl text."
-       for vertexIndex in xrange( 0, len(vertexes), 3 ):
-               triangleMesh.faces.append( getFaceGivenLines( triangleMesh, vertexIndex, vertexIndexTable, vertexes ) )
-
-def getCarving(fileName=''):
-       "Get the triangle mesh for the stl file."
-       if fileName == '':
-               return None
-       stlData = archive.getFileText(fileName, True, 'rb')
-       if stlData == '':
-               return None
-       triangleMesh = triangle_mesh.TriangleMesh()
-       vertexIndexTable = {}
-       numberOfVertexStrings = stlData.count('vertex')
-       requiredVertexStringsForText = max( 2, len( stlData ) / 8000 )
-       if numberOfVertexStrings > requiredVertexStringsForText:
-               addFacesGivenText( stlData, triangleMesh, vertexIndexTable )
-       else:
-#      A binary stl should never start with the word "solid".  Because this error is common the file is been parsed as binary regardless.
-               addFacesGivenBinary( stlData, triangleMesh, vertexIndexTable )
-       return triangleMesh
-
-def getFaceGivenLines( triangleMesh, vertexStartIndex, vertexIndexTable, vertexes ):
-       "Add face given line index and lines."
-       faceGivenLines = face.Face()
-       faceGivenLines.index = len( triangleMesh.faces )
-       for vertexIndex in xrange( vertexStartIndex, vertexStartIndex + 3 ):
-               vertex = vertexes[vertexIndex]
-               vertexUniqueIndex = len( vertexIndexTable )
-               if str(vertex) in vertexIndexTable:
-                       vertexUniqueIndex = vertexIndexTable[ str(vertex) ]
-               else:
-                       vertexIndexTable[ str(vertex) ] = vertexUniqueIndex
-                       triangleMesh.vertexes.append(vertex)
-               faceGivenLines.vertexIndexes.append( vertexUniqueIndex )
-       return faceGivenLines
-
-def getFloat(floatString):
-       "Get the float, replacing commas if necessary because an inferior program is using a comma instead of a point for the decimal point."
-       try:
-               return float(floatString)
-       except:
-               return float( floatString.replace(',', '.') )
-
-def getFloatGivenBinary( byteIndex, stlData ):
-       "Get vertex given stl vertex line."
-       return unpack('f', stlData[ byteIndex : byteIndex + 4 ] )[0]
-
-def getVertexGivenBinary( byteIndex, stlData ):
-       "Get vertex given stl vertex line."
-       return Vector3( getFloatGivenBinary( byteIndex, stlData ), getFloatGivenBinary( byteIndex + 4, stlData ), getFloatGivenBinary( byteIndex + 8, stlData ) )
-
-def getVertexGivenLine(line):
-       "Get vertex given stl vertex line."
-       splitLine = line.split()
-       return Vector3( getFloat(splitLine[1]), getFloat( splitLine[2] ), getFloat( splitLine[3] ) )
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/svg.py b/Cura/slice/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/svg.py
deleted file mode 100644 (file)
index 13d0812..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-"""
-This page is in the table of contents.
-The svg.py script is an import translator plugin to get a carving from an svg file.  This script will read an svg file made by skeinforge or by inkscape.
-
-An example inkscape svg file is inkscape_star.svg in the models folder.
-
-An import plugin is a script in the interpret_plugins folder which has the function getCarving.  It is meant to be run from the interpret tool.  To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.
-
-The getCarving function takes the file name of an svg file and returns the carving.
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.svg_reader import SVGReader
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import svg_writer
-from fabmetheus_utilities import xml_simple_writer
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCarving(fileName=''):
-       'Get the triangle mesh for the gts file.'
-       carving = SVGCarving()
-       carving.parseSVG(fileName, archive.getFileText(fileName))
-       return carving
-
-
-class SVGCarving(object):
-       'An svg carving.'
-       def __init__(self):
-               'Add empty lists.'
-               self.layerHeight = 1.0
-               self.maximumZ = - 987654321.0
-               self.minimumZ = 987654321.0
-               self.svgReader = SVGReader()
-
-       def __repr__(self):
-               'Get the string representation of this carving.'
-               return self.getCarvedSVG()
-
-       def addXML(self, depth, output):
-               'Add xml for this object.'
-               xml_simple_writer.addXMLFromObjects(depth, self.svgReader.loopLayers, output)
-
-       def getCarveBoundaryLayers(self):
-               'Get the  boundary layers.'
-               return self.svgReader.loopLayers
-
-       def getCarveCornerMaximum(self):
-               'Get the corner maximum of the vertexes.'
-               return self.cornerMaximum
-
-       def getCarveCornerMinimum(self):
-               'Get the corner minimum of the vertexes.'
-               return self.cornerMinimum
-
-       def getCarvedSVG(self):
-               'Get the carved svg text.'
-               return svg_writer.getSVGByLoopLayers(True, self, self.svgReader.loopLayers)
-
-       def getCarveLayerHeight(self):
-               'Get the layer height.'
-               return self.layerHeight
-
-       def getFabmetheusXML(self):
-               'Return the fabmetheus XML.'
-               return None
-
-       def getInterpretationSuffix(self):
-               'Return the suffix for a carving.'
-               return 'svg'
-
-       def parseSVG(self, fileName, svgText):
-               'Parse SVG text and store the layers.'
-               if svgText == '':
-                       return
-               self.fileName = fileName
-               self.svgReader.parseSVG(fileName, svgText)
-               self.layerHeight = euclidean.getFloatDefaultByDictionary(
-                       self.layerHeight, self.svgReader.sliceDictionary, 'layerHeight')
-               self.cornerMaximum = Vector3(-987654321.0, -987654321.0, self.maximumZ)
-               self.cornerMinimum = Vector3(987654321.0, 987654321.0, self.minimumZ)
-               svg_writer.setSVGCarvingCorners(
-                       self.cornerMaximum, self.cornerMinimum, self.layerHeight, self.svgReader.loopLayers)
-
-       def setCarveImportRadius(self, importRadius):
-               'Set the import radius.'
-               pass
-
-       def setCarveIsCorrectMesh(self, isCorrectMesh):
-               'Set the is correct mesh flag.'
-               pass
-
-       def setCarveLayerHeight(self, layerHeight):
-               'Set the layer height.'
-               self.layerHeight = layerHeight
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/gcodec.py b/Cura/slice/cura_sf/fabmetheus_utilities/gcodec.py
deleted file mode 100644 (file)
index 3fd2043..0000000
+++ /dev/null
@@ -1,441 +0,0 @@
-"""
-Gcodec is a collection of utilities to decode and encode gcode.
-
-To run gcodec, install python 2.x on your machine, which is avaliable from http://www.python.org/download/
-
-Then in the folder which gcodec is in, type 'python' in a shell to run the python interpreter.  Finally type 'from gcodec import *' to import this program.
-
-Below is an example of gcodec use.  This example is run in a terminal in the folder which contains gcodec and Screw Holder Bottom_export.gcode.
-
->>> from gcodec import *
->>> getFileText('Screw Holder Bottom_export.gcode')
-'G90\nG21\nM103\nM105\nM106\nM110 S60.0\nM111 S30.0\nM108 S210.0\nM104 S235.0\nG1 X0.37 Y-4.07 Z1.9 F60.0\nM101\n
-..
-many lines of text
-..
-
-"""
-from __future__ import absolute_import
-
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-
-import math
-import sys
-
-if sys.version_info[0] < 3:
-       import cStringIO
-else:
-       import io as cStringIO
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addLineAndNewlineIfNecessary(line, output):
-       'Add the line and if the line does not end with a newline add a newline.'
-       output.write(line)
-       if len(line) < 1:
-               return
-       if not line.endswith('\n'):
-               output.write('\n')
-
-def addLinesToCString(cString, lines):
-       'Add lines which have something to cStringIO.'
-       for line in lines:
-               if line != '':
-                       cString.write(line + '\n')
-
-def getArcDistance(relativeLocation, splitLine):
-       'Get arc distance.'
-       halfPlaneLineDistance = 0.5 * abs(relativeLocation.dropAxis())
-       radius = getDoubleFromCharacterSplitLine('R', splitLine)
-       if radius == None:
-               iFloat = getDoubleFromCharacterSplitLine('I', splitLine)
-               jFloat = getDoubleFromCharacterSplitLine('J', splitLine)
-               radius = abs(complex(iFloat, jFloat))
-       angle = 0.0
-       if radius > 0.0:
-               halfPlaneLineDistanceOverRadius = halfPlaneLineDistance / radius
-               if halfPlaneLineDistance < radius:
-                       angle = 2.0 * math.asin(halfPlaneLineDistanceOverRadius)
-               else:
-                       angle = math.pi * halfPlaneLineDistanceOverRadius
-       return abs(complex(angle * radius, relativeLocation.z))
-
-def getDoubleAfterFirstLetter(word):
-       'Get the double value of the word after the first letter.'
-       return float(word[1 :])
-
-def getDoubleForLetter(letter, splitLine):
-       'Get the double value of the word after the first occurence of the letter in the split line.'
-       return getDoubleAfterFirstLetter(splitLine[getIndexOfStartingWithSecond(letter, splitLine)])
-
-def getDoubleFromCharacterSplitLine(character, splitLine):
-       'Get the double value of the string after the first occurence of the character in the split line.'
-       indexOfCharacter = getIndexOfStartingWithSecond(character, splitLine)
-       if indexOfCharacter < 0:
-               return None
-       floatString = splitLine[indexOfCharacter][1 :]
-       try:
-               return float(floatString)
-       except ValueError:
-               return None
-
-def getDoubleFromCharacterSplitLineValue(character, splitLine, value):
-       'Get the double value of the string after the first occurence of the character in the split line, if it does not exist return the value.'
-       splitLineFloat = getDoubleFromCharacterSplitLine(character, splitLine)
-       if splitLineFloat == None:
-               return value
-       return splitLineFloat
-
-def getFeedRateMinute(feedRateMinute, splitLine):
-       'Get the feed rate per minute if the split line has a feed rate.'
-       indexOfF = getIndexOfStartingWithSecond('F', splitLine)
-       if indexOfF > 0:
-               return getDoubleAfterFirstLetter( splitLine[indexOfF] )
-       return feedRateMinute
-
-def getFirstWord(splitLine):
-       'Get the first word of a split line.'
-       if len(splitLine) > 0:
-               return splitLine[0]
-       return ''
-
-def getFirstWordFromLine(line):
-       'Get the first word of a line.'
-       return getFirstWord(line.split())
-
-def getFirstWordIndexReverse(firstWord, lines, startIndex):
-       'Parse gcode in reverse order until the first word if there is one, otherwise return -1.'
-       for lineIndex in xrange(len(lines) - 1, startIndex - 1, -1):
-               if firstWord == getFirstWord(getSplitLineBeforeBracketSemicolon(lines[lineIndex])):
-                       return lineIndex
-       return -1
-
-def getGcodeFileText(fileName, gcodeText):
-       'Get the gcode text from a file if it the gcode text is empty and if the file is a gcode file.'
-       if gcodeText != '':
-               return gcodeText
-       if fileName.endswith('.gcode'):
-               return archive.getFileText(fileName)
-       return ''
-
-def getGcodeWithoutDuplication(duplicateWord, gcodeText):
-       'Get gcode text without duplicate first words.'
-       lines = archive.getTextLines(gcodeText)
-       oldWrittenLine = None
-       output = cStringIO.StringIO()
-       for line in lines:
-               firstWord = getFirstWordFromLine(line)
-               if firstWord == duplicateWord:
-                       if line != oldWrittenLine:
-                               output.write(line + '\n')
-                               oldWrittenLine = line
-               else:
-                       if len(line) > 0:
-                               output.write(line + '\n')
-       return output.getvalue()
-
-def getIndexOfStartingWithSecond(letter, splitLine):
-       'Get index of the first occurence of the given letter in the split line, starting with the second word.  Return - 1 if letter is not found'
-       for wordIndex in xrange( 1, len(splitLine) ):
-               word = splitLine[ wordIndex ]
-               firstLetter = word[0]
-               if firstLetter == letter:
-                       return wordIndex
-       return - 1
-
-def getLineWithValueString(character, line, splitLine, valueString):
-       'Get the line with a valueString.'
-       roundedValueString = character + valueString
-       indexOfValue = getIndexOfStartingWithSecond(character, splitLine)
-       if indexOfValue == -1:
-               return line + ' ' + roundedValueString
-       word = splitLine[indexOfValue]
-       return line.replace(word, roundedValueString)
-
-def getLocationFromSplitLine(oldLocation, splitLine):
-       'Get the location from the split line.'
-       if oldLocation == None:
-               oldLocation = Vector3()
-       return Vector3(
-               getDoubleFromCharacterSplitLineValue('X', splitLine, oldLocation.x),
-               getDoubleFromCharacterSplitLineValue('Y', splitLine, oldLocation.y),
-               getDoubleFromCharacterSplitLineValue('Z', splitLine, oldLocation.z))
-
-def getRotationBySplitLine(splitLine):
-       'Get the complex rotation from the split gcode line.'
-       return complex(splitLine[1].replace('(', '').replace(')', ''))
-
-def getSplitLineBeforeBracketSemicolon(line):
-       'Get the split line before a bracket or semicolon.'
-       if ';' in line:
-               line = line[: line.find(';')]
-       bracketIndex = line.find('(')
-       if bracketIndex > 0:
-               return line[: bracketIndex].split()
-       return line.split()
-
-def getStringFromCharacterSplitLine(character, splitLine):
-       'Get the string after the first occurence of the character in the split line.'
-       indexOfCharacter = getIndexOfStartingWithSecond(character, splitLine)
-       if indexOfCharacter < 0:
-               return None
-       return splitLine[indexOfCharacter][1 :]
-
-def getTagBracketedLine(tagName, value):
-       'Get line with a begin tag, value and end tag.'
-       return '(<%s> %s </%s>)' % (tagName, value, tagName)
-
-def getTagBracketedProcedure(procedure):
-       'Get line with a begin procedure tag, procedure and end procedure tag.'
-       return getTagBracketedLine('procedureName', procedure)
-
-def isProcedureDone(gcodeText, procedure):
-       'Determine if the procedure has been done on the gcode text.'
-       if gcodeText == '':
-               return False
-       extruderInitializationIndex = gcodeText.find('(</extruderInitialization>)')
-       if extruderInitializationIndex == -1:
-               metadataBeginIndex = gcodeText.find('<metadata>')
-               metadataEndIndex = gcodeText.find('</metadata>')
-               if metadataBeginIndex != -1 and metadataEndIndex != -1:
-                       attributeString = "procedureName='%s'" % procedure
-                       return gcodeText.find(attributeString, metadataBeginIndex, metadataEndIndex) != -1
-               return False
-       return gcodeText.find(getTagBracketedProcedure(procedure), 0, extruderInitializationIndex) != -1
-
-def isProcedureDoneOrFileIsEmpty(gcodeText, procedure):
-       'Determine if the procedure has been done on the gcode text or the file is empty.'
-       if gcodeText == '':
-               return True
-       return isProcedureDone(gcodeText, procedure)
-
-def isThereAFirstWord(firstWord, lines, startIndex):
-       'Parse gcode until the first word if there is one.'
-       for lineIndex in xrange(startIndex, len(lines)):
-               line = lines[lineIndex]
-               splitLine = getSplitLineBeforeBracketSemicolon(line)
-               if firstWord == getFirstWord(splitLine):
-                       return True
-       return False
-
-
-class BoundingRectangle(object):
-       'A class to get the corners of a gcode text.'
-       def getFromGcodeLines(self, lines, radius):
-               'Parse gcode text and get the minimum and maximum corners.'
-               self.cornerMaximum = complex(-987654321.0, -987654321.0)
-               self.cornerMinimum = complex(987654321.0, 987654321.0)
-               self.oldLocation = None
-               self.cornerRadius = complex(radius, radius)
-               for line in lines:
-                       self.parseCorner(line)
-               return self
-
-       def isPointInside(self, point):
-               'Determine if the point is inside the bounding rectangle.'
-               return self.cornerMinimum.imag <= point.imag <= self.cornerMaximum.imag and self.cornerMinimum.real <= point.real <= self.cornerMaximum.real
-
-       def parseCorner(self, line):
-               'Parse a gcode line and use the location to update the bounding corners.'
-               splitLine = getSplitLineBeforeBracketSemicolon(line)
-               firstWord = getFirstWord(splitLine)
-               if firstWord == '(<boundaryPoint>':
-                       locationComplex = getLocationFromSplitLine(None, splitLine).dropAxis()
-                       self.cornerMaximum = euclidean.getMaximum(self.cornerMaximum, locationComplex)
-                       self.cornerMinimum = euclidean.getMinimum(self.cornerMinimum, locationComplex)
-               elif firstWord == 'G1':
-                       location = getLocationFromSplitLine(self.oldLocation, splitLine)
-                       locationComplex = location.dropAxis()
-                       self.cornerMaximum = euclidean.getMaximum(self.cornerMaximum, locationComplex + self.cornerRadius)
-                       self.cornerMinimum = euclidean.getMinimum(self.cornerMinimum, locationComplex - self.cornerRadius)
-                       self.oldLocation = location
-
-
-class DistanceFeedRate(object):
-       'A class to limit the z feed rate and round values.'
-       def __init__(self):
-               'Initialize.'
-               self.isAlteration = False
-               self.decimalPlacesCarried = 3
-               self.output = cStringIO.StringIO()
-
-       def addFlowRateLine(self, flowRate):
-               'Add a flow rate line.'
-               self.output.write('M108 S%s\n' % euclidean.getFourSignificantFigures(flowRate))
-
-       def addGcodeFromFeedRateThreadZ(self, feedRateMinute, thread, travelFeedRateMinute, z):
-               'Add a thread to the output.'
-               if len(thread) > 0:
-                       self.addGcodeMovementZWithFeedRate(travelFeedRateMinute, thread[0], z)
-               else:
-                       print('zero length vertex positions array which was skipped over, this should never happen.')
-               if len(thread) < 2:
-                       print('thread of only one point in addGcodeFromFeedRateThreadZ in gcodec, this should never happen.')
-                       print(thread)
-                       return
-               self.output.write('M101\n') # Turn extruder on.
-               for point in thread[1 :]:
-                       self.addGcodeMovementZWithFeedRate(feedRateMinute, point, z)
-               self.output.write('M103\n') # Turn extruder off.
-
-       def addGcodeFromLoop(self, loop, z):
-               'Add the gcode loop.'
-               euclidean.addNestedRingBeginning(self, loop, z)
-               self.addPerimeterBlock(loop, z)
-               self.addLine('(</boundaryPerimeter>)')
-               self.addLine('(</nestedRing>)')
-
-       def addGcodeFromThreadZ(self, thread, z):
-               'Add a thread to the output.'
-               if len(thread) > 0:
-                       self.addGcodeMovementZ(thread[0], z)
-               else:
-                       print('zero length vertex positions array which was skipped over, this should never happen.')
-               if len(thread) < 2:
-                       print('thread of only one point in addGcodeFromThreadZ in gcodec, this should never happen.')
-                       print(thread)
-                       return
-               self.output.write('M101\n') # Turn extruder on.
-               for point in thread[1 :]:
-                       self.addGcodeMovementZ(point, z)
-               self.output.write('M103\n') # Turn extruder off.
-
-       def addGcodeMovementZ(self, point, z):
-               'Add a movement to the output.'
-               self.output.write(self.getLinearGcodeMovement(point, z) + '\n')
-
-       def addGcodeMovementZWithFeedRate(self, feedRateMinute, point, z):
-               'Add a movement to the output.'
-               self.output.write(self.getLinearGcodeMovementWithFeedRate(feedRateMinute, point, z) + '\n')
-
-       def addGcodeMovementZWithFeedRateVector3(self, feedRateMinute, vector3):
-               'Add a movement to the output by Vector3.'
-               xRounded = self.getRounded(vector3.x)
-               yRounded = self.getRounded(vector3.y)
-               self.output.write('G1 X%s Y%s Z%s F%s\n' % (xRounded, yRounded, self.getRounded(vector3.z), self.getRounded(feedRateMinute)))
-
-       def addLine(self, line):
-               'Add a line of text and a newline to the output.'
-               if len(line) > 0:
-                       self.output.write(line + '\n')
-
-       def addLineCheckAlteration(self, line):
-               'Add a line of text and a newline to the output and check to see if it is an alteration line.'
-               firstWord = getFirstWord(getSplitLineBeforeBracketSemicolon(line))
-               if firstWord == '(<alteration>)':
-                       self.isAlteration = True
-               elif firstWord == '(</alteration>)':
-                       self.isAlteration = False
-               if len(line) > 0:
-                       self.output.write(line + '\n')
-
-       def addLines(self, lines):
-               'Add lines of text to the output.'
-               addLinesToCString(self.output, lines)
-
-       def addLinesSetAbsoluteDistanceMode(self, lines):
-               'Add lines of text to the output and ensure the absolute mode is set.'
-               if len(lines) < 1:
-                       return
-               if len(lines[0]) < 1:
-                       return
-               absoluteDistanceMode = True
-               self.addLine('(<alteration>)')
-               for line in lines:
-                       splitLine = getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = getFirstWord(splitLine)
-                       if firstWord == 'G90':
-                               absoluteDistanceMode = True
-                       elif firstWord == 'G91':
-                               absoluteDistanceMode = False
-                       self.addLine('(<alterationDeleteThisPrefix/>)' + line)
-               if not absoluteDistanceMode:
-                       self.addLine('G90')
-               self.addLine('(</alteration>)')
-
-       def addParameter(self, firstWord, parameter):
-               'Add the parameter.'
-               self.addLine(firstWord + ' S' + euclidean.getRoundedToThreePlaces(parameter))
-
-       def addPerimeterBlock(self, loop, z):
-               'Add the edge gcode block for the loop.'
-               if len(loop) < 2:
-                       return
-               if euclidean.isWiddershins(loop): # Indicate that an edge is beginning.
-                       self.addLine('(<edge> outer )')
-               else:
-                       self.addLine('(<edge> inner )')
-               self.addGcodeFromThreadZ(loop + [loop[0]], z)
-               self.addLine('(</edge>)') # Indicate that an edge is beginning.
-
-       def addTagBracketedLine(self, tagName, value):
-               'Add a begin tag, value and end tag.'
-               self.addLine(getTagBracketedLine(tagName, value))
-
-       def addTagRoundedLine(self, tagName, value):
-               'Add a begin tag, rounded value and end tag.'
-               self.addLine('(<%s> %s </%s>)' % (tagName, self.getRounded(value), tagName))
-
-       def addTagBracketedProcedure(self, procedure):
-               'Add a begin procedure tag, procedure and end procedure tag.'
-               self.addLine(getTagBracketedProcedure(procedure))
-
-       def getBoundaryLine(self, location):
-               'Get boundary gcode line.'
-               return '(<boundaryPoint> X%s Y%s Z%s </boundaryPoint>)' % (self.getRounded(location.x), self.getRounded(location.y), self.getRounded(location.z))
-
-       def getFirstWordMovement(self, firstWord, location):
-               'Get the start of the arc line.'
-               return '%s X%s Y%s Z%s' % (firstWord, self.getRounded(location.x), self.getRounded(location.y), self.getRounded(location.z))
-
-       def getInfillBoundaryLine(self, location):
-               'Get infill boundary gcode line.'
-               return '(<infillPoint> X%s Y%s Z%s </infillPoint>)' % (self.getRounded(location.x), self.getRounded(location.y), self.getRounded(location.z))
-
-       def getIsAlteration(self, line):
-               'Determine if it is an alteration.'
-               if self.isAlteration:
-                       self.addLineCheckAlteration(line)
-                       return True
-               return False
-
-       def getLinearGcodeMovement(self, point, z):
-               'Get a linear gcode movement.'
-               return 'G1 X%s Y%s Z%s' % (self.getRounded(point.real), self.getRounded(point.imag), self.getRounded(z))
-
-       def getLinearGcodeMovementWithFeedRate(self, feedRateMinute, point, z):
-               'Get a z limited gcode movement.'
-               linearGcodeMovement = self.getLinearGcodeMovement(point, z)
-               if feedRateMinute == None:
-                       return linearGcodeMovement
-               return linearGcodeMovement + ' F' + self.getRounded(feedRateMinute)
-
-       def getLineWithFeedRate(self, feedRateMinute, line, splitLine):
-               'Get the line with a feed rate.'
-               return getLineWithValueString('F', line, splitLine, self.getRounded(feedRateMinute))
-
-       def getLineWithX(self, line, splitLine, x):
-               'Get the line with an x.'
-               return getLineWithValueString('X', line, splitLine, self.getRounded(x))
-
-       def getLineWithY(self, line, splitLine, y):
-               'Get the line with a y.'
-               return getLineWithValueString('Y', line, splitLine, self.getRounded(y))
-
-       def getLineWithZ(self, line, splitLine, z):
-               'Get the line with a z.'
-               return getLineWithValueString('Z', line, splitLine, self.getRounded(z))
-
-       def getRounded(self, number):
-               'Get number rounded to the number of carried decimal places as a string.'
-               return euclidean.getRoundedToPlacesString(self.decimalPlacesCarried, number)
-
-       def parseSplitLine(self, firstWord, splitLine):
-               'Parse gcode split line and store the parameters.'
-               if firstWord == '(<decimalPlacesCarried>':
-                       self.decimalPlacesCarried = int(splitLine[1])
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/_drill.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/_drill.py
deleted file mode 100644 (file)
index bb3b286..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-"""
-Drill negative solid.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.creation import teardrop
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.vector3 import Vector3
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getGeometryOutput(derivation, elementNode):
-       "Get vector3 vertexes from attribute dictionary."
-       if derivation == None:
-               derivation = DrillDerivation(elementNode)
-       negatives = []
-       teardrop.addNegativesByRadius(elementNode, derivation.end, negatives, derivation.radius, derivation.start)
-       return solid.getGeometryOutputByManipulation(elementNode, negatives[0])
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       "Get vector3 vertexes from attribute dictionary by arguments."
-       evaluate.setAttributesByArguments(['radius', 'start', 'end'], arguments, elementNode)
-       return getGeometryOutput(None, elementNode)
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return DrillDerivation(elementNode)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       solid.processElementNodeByGeometry(elementNode, getGeometryOutput(None, elementNode))
-
-
-class DrillDerivation(object):
-       "Class to hold drill variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.elementNode = elementNode
-               self.end = evaluate.getVector3ByPrefix(Vector3(0.0, 0.0, 1.0), elementNode, 'end')
-               self.start = evaluate.getVector3ByPrefix(Vector3(), elementNode, 'start')
-               self.radius = lineation.getFloatByPrefixBeginEnd(elementNode, 'radius', 'diameter', 1.0)
-               size = evaluate.getEvaluatedFloat(None, elementNode, 'size')
-               if size != None:
-                       self.radius = 0.5 * size
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/_svg.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/_svg.py
deleted file mode 100644 (file)
index 0e26dd5..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-"""
-Svg reader.
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_tools import path
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import svg_reader
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getGeometryOutput(derivation, elementNode):
-       "Get vector3 vertexes from attribute dictionary."
-       if derivation == None:
-               derivation = SVGDerivation(elementNode)
-       return getGeometryOutputBySVGReader(elementNode, derivation.svgReader)
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       "Get vector3 vertexes from attribute dictionary by arguments."
-       derivation = SVGDerivation()
-       derivation.svgReader.parseSVG('', arguments[0])
-       return getGeometryOutput(derivation, elementNode)
-
-def getGeometryOutputBySVGReader(elementNode, svgReader):
-       "Get vector3 vertexes from svgReader."
-       geometryOutput = []
-       for loopLayer in svgReader.loopLayers:
-               for loop in loopLayer.loops:
-                       vector3Path = euclidean.getVector3Path(loop, loopLayer.z)
-                       sideLoop = lineation.SideLoop(vector3Path)
-                       sideLoop.rotate(elementNode)
-                       geometryOutput += lineation.getGeometryOutputByManipulation(elementNode, sideLoop)
-       return geometryOutput
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return SVGDerivation(elementNode)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       path.convertElementNode(elementNode, getGeometryOutput(None, elementNode))
-
-
-class SVGDerivation(object):
-       "Class to hold svg variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.svgReader = svg_reader.SVGReader()
-               self.svgReader.parseSVGByElementNode(elementNode)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/circle.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/circle.py
deleted file mode 100644 (file)
index 7439d38..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-"""
-Polygon path.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_tools import path
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getGeometryOutput(derivation, elementNode):
-       "Get vector3 vertexes from attribute dictionary."
-       if derivation == None:
-               derivation = CircleDerivation(elementNode)
-       angleTotal = math.radians(derivation.start)
-       loop = []
-       sidesCeiling = int(math.ceil(abs(derivation.sides) * derivation.extent / 360.0))
-       sideAngle = math.radians(derivation.extent) / sidesCeiling
-       if derivation.sides < 0.0:
-               sideAngle = -sideAngle
-       spiral = lineation.Spiral(derivation.spiral, 0.5 * sideAngle / math.pi)
-       for side in xrange(sidesCeiling + 1):
-               unitPolar = euclidean.getWiddershinsUnitPolar(angleTotal)
-               x = unitPolar.real * derivation.radiusArealized.real
-               y = unitPolar.imag * derivation.radiusArealized.imag
-               vertex = spiral.getSpiralPoint(unitPolar, Vector3(x, y))
-               angleTotal += sideAngle
-               loop.append(vertex)
-       radiusMaximum = 0.000001 * max(derivation.radiusArealized.real, derivation.radiusArealized.imag)
-       loop = euclidean.getLoopWithoutCloseEnds(radiusMaximum, loop)
-       lineation.setClosedAttribute(elementNode, derivation.revolutions)
-       return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(loop, sideAngle))
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       "Get vector3 vertexes from attribute dictionary by arguments."
-       evaluate.setAttributesByArguments(['radius', 'start', 'end', 'revolutions'], arguments, elementNode)
-       return getGeometryOutput(None, elementNode)
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return CircleDerivation(elementNode)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       path.convertElementNode(elementNode, getGeometryOutput(None, elementNode))
-
-
-class CircleDerivation(object):
-       "Class to hold circle variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.radius = lineation.getRadiusComplex(elementNode, complex(1.0, 1.0))
-               self.sides = evaluate.getEvaluatedFloat(None, elementNode, 'sides')
-               if self.sides == None:
-                       radiusMaximum = max(self.radius.real, self.radius.imag)
-                       self.sides = evaluate.getSidesMinimumThreeBasedOnPrecisionSides(elementNode, radiusMaximum)
-               self.radiusArealized = evaluate.getRadiusArealizedBasedOnAreaRadius(elementNode, self.radius, self.sides)
-               self.start = evaluate.getEvaluatedFloat(0.0, elementNode, 'start')
-               end = evaluate.getEvaluatedFloat(360.0, elementNode, 'end')
-               self.revolutions = evaluate.getEvaluatedFloat(1.0, elementNode, 'revolutions')
-               self.extent = evaluate.getEvaluatedFloat(end - self.start, elementNode, 'extent')
-               self.extent += 360.0 * (self.revolutions - 1.0)
-               self.spiral = evaluate.getVector3ByPrefix(None, elementNode, 'spiral')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/concatenate.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/concatenate.py
deleted file mode 100644 (file)
index e082bba..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-"""
-Boolean geometry concatenation.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_tools import path
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities import euclidean
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getGeometryOutput(derivation, elementNode):
-       'Get triangle mesh from attribute dictionary.'
-       if derivation == None:
-               derivation = ConcatenateDerivation(elementNode)
-       concatenatedList = euclidean.getConcatenatedList(derivation.target)[:]
-       if len(concatenatedList) == 0:
-               print('Warning, in concatenate there are no paths.')
-               print(elementNode.attributes)
-               return None
-       if 'closed' not in elementNode.attributes:
-               elementNode.attributes['closed'] = 'true'
-       return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(concatenatedList))
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       'Get triangle mesh from attribute dictionary by arguments.'
-       return getGeometryOutput(None, elementNode)
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return ConcatenateDerivation(elementNode)
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       path.convertElementNode(elementNode, getGeometryOutput(None, elementNode))
-
-
-class ConcatenateDerivation(object):
-       'Class to hold concatenate variables.'
-       def __init__(self, elementNode):
-               'Initialize.'
-               self.target = evaluate.getTransformedPathsByKey([], elementNode, 'target')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/extrude.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/extrude.py
deleted file mode 100644 (file)
index b94b6d9..0000000
+++ /dev/null
@@ -1,438 +0,0 @@
-"""
-Boolean geometry extrusion.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities.vector3index import Vector3Index
-from fabmetheus_utilities import euclidean
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addLoop(derivation, endMultiplier, loopLists, path, portionDirectionIndex, portionDirections, vertexes):
-       'Add an indexed loop to the vertexes.'
-       portionDirection = portionDirections[ portionDirectionIndex ]
-       if portionDirection.directionReversed == True:
-               loopLists.append([])
-       loops = loopLists[-1]
-       interpolationOffset = derivation.interpolationDictionary['offset']
-       offset = interpolationOffset.getVector3ByPortion( portionDirection )
-       if endMultiplier != None:
-               if portionDirectionIndex == 0:
-                       setOffsetByMultiplier( interpolationOffset.path[1], interpolationOffset.path[0], endMultiplier, offset )
-               elif portionDirectionIndex == len( portionDirections ) - 1:
-                       setOffsetByMultiplier( interpolationOffset.path[-2], interpolationOffset.path[-1], endMultiplier, offset )
-       scale = derivation.interpolationDictionary['scale'].getComplexByPortion( portionDirection )
-       twist = derivation.interpolationDictionary['twist'].getYByPortion( portionDirection )
-       projectiveSpace = euclidean.ProjectiveSpace()
-       if derivation.tiltTop == None:
-               tilt = derivation.interpolationDictionary['tilt'].getComplexByPortion( portionDirection )
-               projectiveSpace = projectiveSpace.getByTilt( tilt )
-       else:
-               normals = getNormals( interpolationOffset, offset, portionDirection )
-               normalFirst = normals[0]
-               normalAverage = getNormalAverage(normals)
-               if derivation.tiltFollow and derivation.oldProjectiveSpace != None:
-                       projectiveSpace = derivation.oldProjectiveSpace.getNextSpace( normalAverage )
-               else:
-                       projectiveSpace = projectiveSpace.getByBasisZTop( normalAverage, derivation.tiltTop )
-               derivation.oldProjectiveSpace = projectiveSpace
-               projectiveSpace.unbuckle( derivation.maximumUnbuckling, normalFirst )
-       projectiveSpace = projectiveSpace.getSpaceByXYScaleAngle( twist, scale )
-       loop = []
-       if ( abs( projectiveSpace.basisX ) + abs( projectiveSpace.basisY ) ) < 0.0001:
-               vector3Index = Vector3Index(len(vertexes))
-               addOffsetAddToLists( loop, offset, vector3Index, vertexes )
-               loops.append(loop)
-               return
-       for point in path:
-               vector3Index = Vector3Index(len(vertexes))
-               projectedVertex = projectiveSpace.getVector3ByPoint(point)
-               vector3Index.setToVector3( projectedVertex )
-               addOffsetAddToLists( loop, offset, vector3Index, vertexes )
-       loops.append(loop)
-
-def addNegatives(derivation, negatives, paths):
-       'Add pillars output to negatives.'
-       portionDirections = getSpacedPortionDirections(derivation.interpolationDictionary)
-       for path in paths:
-               loopLists = getLoopListsByPath(derivation, 1.000001, path, portionDirections)
-               geometryOutput = triangle_mesh.getPillarsOutput(loopLists)
-               negatives.append(geometryOutput)
-
-def addNegativesPositives(derivation, negatives, paths, positives):
-       'Add pillars output to negatives and positives.'
-       portionDirections = getSpacedPortionDirections(derivation.interpolationDictionary)
-       for path in paths:
-               endMultiplier = None
-               if not euclidean.getIsWiddershinsByVector3(path):
-                       endMultiplier = 1.000001
-               loopLists = getLoopListsByPath(derivation, endMultiplier, path, portionDirections)
-               geometryOutput = triangle_mesh.getPillarsOutput(loopLists)
-               if endMultiplier == None:
-                       positives.append(geometryOutput)
-               else:
-                       negatives.append(geometryOutput)
-
-def addOffsetAddToLists(loop, offset, vector3Index, vertexes):
-       'Add an indexed loop to the vertexes.'
-       vector3Index += offset
-       loop.append(vector3Index)
-       vertexes.append(vector3Index)
-
-def addPositives(derivation, paths, positives):
-       'Add pillars output to positives.'
-       portionDirections = getSpacedPortionDirections(derivation.interpolationDictionary)
-       for path in paths:
-               loopLists = getLoopListsByPath(derivation, None, path, portionDirections)
-               geometryOutput = triangle_mesh.getPillarsOutput(loopLists)
-               positives.append(geometryOutput)
-
-def addSpacedPortionDirection( portionDirection, spacedPortionDirections ):
-       'Add spaced portion directions.'
-       lastSpacedPortionDirection = spacedPortionDirections[-1]
-       if portionDirection.portion - lastSpacedPortionDirection.portion > 0.003:
-               spacedPortionDirections.append( portionDirection )
-               return
-       if portionDirection.directionReversed > lastSpacedPortionDirection.directionReversed:
-               spacedPortionDirections.append( portionDirection )
-
-def addTwistPortions( interpolationTwist, remainderPortionDirection, twistPrecision ):
-       'Add twist portions.'
-       lastPortionDirection = interpolationTwist.portionDirections[-1]
-       if remainderPortionDirection.portion == lastPortionDirection.portion:
-               return
-       lastTwist = interpolationTwist.getYByPortion( lastPortionDirection )
-       remainderTwist = interpolationTwist.getYByPortion( remainderPortionDirection )
-       twistSegments = int( math.floor( abs( remainderTwist - lastTwist ) / twistPrecision ) )
-       if twistSegments < 1:
-               return
-       portionDifference = remainderPortionDirection.portion - lastPortionDirection.portion
-       twistSegmentsPlusOne = float( twistSegments + 1 )
-       for twistSegment in xrange( twistSegments ):
-               additionalPortion = portionDifference * float( twistSegment + 1 ) / twistSegmentsPlusOne
-               portionDirection = PortionDirection( lastPortionDirection.portion + additionalPortion )
-               interpolationTwist.portionDirections.append( portionDirection )
-
-def comparePortionDirection( portionDirection, otherPortionDirection ):
-       'Comparison in order to sort portion directions in ascending order of portion then direction.'
-       if portionDirection.portion > otherPortionDirection.portion:
-               return 1
-       if portionDirection.portion < otherPortionDirection.portion:
-               return - 1
-       if portionDirection.directionReversed < otherPortionDirection.directionReversed:
-               return - 1
-       return portionDirection.directionReversed > otherPortionDirection.directionReversed
-
-def getGeometryOutput(derivation, elementNode):
-       'Get triangle mesh from attribute dictionary.'
-       if derivation == None:
-               derivation = ExtrudeDerivation(elementNode)
-       if len(euclidean.getConcatenatedList(derivation.target)) == 0:
-               print('Warning, in extrude there are no paths.')
-               print(elementNode.attributes)
-               return None
-       return getGeometryOutputByLoops(derivation, derivation.target)
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       'Get triangle mesh from attribute dictionary by arguments.'
-       return getGeometryOutput(None, elementNode)
-
-def getGeometryOutputByLoops(derivation, loops):
-       'Get geometry output by sorted, nested loops.'
-       loops.sort(key=euclidean.getAreaVector3LoopAbsolute, reverse=True)
-       complexLoops = euclidean.getComplexPaths(loops)
-       nestedRings = []
-       for loopIndex, loop in enumerate(loops):
-               complexLoop = complexLoops[loopIndex]
-               leftPoint = euclidean.getLeftPoint(complexLoop)
-               isInFilledRegion = euclidean.getIsInFilledRegion(complexLoops[: loopIndex] + complexLoops[loopIndex + 1 :], leftPoint)
-               if isInFilledRegion == euclidean.isWiddershins(complexLoop):
-                       loop.reverse()
-               nestedRing = euclidean.NestedRing()
-               nestedRing.boundary = complexLoop
-               nestedRing.vector3Loop = loop
-               nestedRings.append(nestedRing)
-       nestedRings = euclidean.getOrderedNestedRings(nestedRings)
-       nestedRings = euclidean.getFlattenedNestedRings(nestedRings)
-       portionDirections = getSpacedPortionDirections(derivation.interpolationDictionary)
-       if len(nestedRings) < 1:
-               return {}
-       if len(nestedRings) == 1:
-               geometryOutput = getGeometryOutputByNestedRing(derivation, nestedRings[0], portionDirections)
-               return solid.getGeometryOutputByManipulation(derivation.elementNode, geometryOutput)
-       shapes = []
-       for nestedRing in nestedRings:
-               shapes.append(getGeometryOutputByNestedRing(derivation, nestedRing, portionDirections))
-       return solid.getGeometryOutputByManipulation(derivation.elementNode, {'union' : {'shapes' : shapes}})
-
-def getGeometryOutputByNegativesPositives(elementNode, negatives, positives):
-       'Get triangle mesh from elementNode, negatives and positives.'
-       positiveOutput = triangle_mesh.getUnifiedOutput(positives)
-       if len(negatives) < 1:
-               return solid.getGeometryOutputByManipulation(elementNode, positiveOutput)
-       if len(positives) < 1:
-               negativeOutput = triangle_mesh.getUnifiedOutput(negatives)
-               return solid.getGeometryOutputByManipulation(elementNode, negativeOutput)
-       return solid.getGeometryOutputByManipulation(elementNode, {'difference' : {'shapes' : [positiveOutput] + negatives}})
-
-def getGeometryOutputByNestedRing(derivation, nestedRing, portionDirections):
-       'Get geometry output by sorted, nested loops.'
-       loopLists = getLoopListsByPath(derivation, None, nestedRing.vector3Loop, portionDirections)
-       outsideOutput = triangle_mesh.getPillarsOutput(loopLists)
-       if len(nestedRing.innerNestedRings) < 1:
-               return outsideOutput
-       shapes = [outsideOutput]
-       for nestedRing.innerNestedRing in nestedRing.innerNestedRings:
-               loopLists = getLoopListsByPath(derivation, 1.000001, nestedRing.innerNestedRing.vector3Loop, portionDirections)
-               shapes.append(triangle_mesh.getPillarsOutput(loopLists))
-       return {'difference' : {'shapes' : shapes}}
-
-def getLoopListsByPath(derivation, endMultiplier, path, portionDirections):
-       'Get loop lists from path.'
-       vertexes = []
-       loopLists = [[]]
-       derivation.oldProjectiveSpace = None
-       for portionDirectionIndex in xrange(len(portionDirections)):
-               addLoop(derivation, endMultiplier, loopLists, path, portionDirectionIndex, portionDirections, vertexes)
-       return loopLists
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return ExtrudeDerivation(elementNode)
-
-def getNormalAverage(normals):
-       'Get normal.'
-       if len(normals) < 2:
-               return normals[0]
-       return (normals[0] + normals[1]).getNormalized()
-
-def getNormals( interpolationOffset, offset, portionDirection ):
-       'Get normals.'
-       normals = []
-       portionFrom = portionDirection.portion - 0.0001
-       portionTo = portionDirection.portion + 0.0001
-       if portionFrom >= 0.0:
-               normals.append( ( offset - interpolationOffset.getVector3ByPortion( PortionDirection( portionFrom ) ) ).getNormalized() )
-       if portionTo <= 1.0:
-               normals.append( ( interpolationOffset.getVector3ByPortion( PortionDirection( portionTo ) ) - offset ).getNormalized() )
-       return normals
-
-def getSpacedPortionDirections( interpolationDictionary ):
-       'Get sorted portion directions.'
-       portionDirections = []
-       for interpolationDictionaryValue in interpolationDictionary.values():
-               portionDirections += interpolationDictionaryValue.portionDirections
-       portionDirections.sort( comparePortionDirection )
-       if len( portionDirections ) < 1:
-               return []
-       spacedPortionDirections = [ portionDirections[0] ]
-       for portionDirection in portionDirections[1 :]:
-               addSpacedPortionDirection( portionDirection, spacedPortionDirections )
-       return spacedPortionDirections
-
-def insertTwistPortions(derivation, elementNode):
-       'Insert twist portions and radian the twist.'
-       interpolationDictionary = derivation.interpolationDictionary
-       interpolationTwist = Interpolation().getByPrefixX(elementNode, derivation.twistPathDefault, 'twist')
-       interpolationDictionary['twist'] = interpolationTwist
-       for point in interpolationTwist.path:
-               point.y = math.radians(point.y)
-       remainderPortionDirections = interpolationTwist.portionDirections[1 :]
-       interpolationTwist.portionDirections = [interpolationTwist.portionDirections[0]]
-       if elementNode != None:
-               twistPrecision = setting.getTwistPrecisionRadians(elementNode)
-       for remainderPortionDirection in remainderPortionDirections:
-               addTwistPortions(interpolationTwist, remainderPortionDirection, twistPrecision)
-               interpolationTwist.portionDirections.append(remainderPortionDirection)
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       solid.processElementNodeByGeometry(elementNode, getGeometryOutput(None, elementNode))
-
-def setElementNodeToEndStart(elementNode, end, start):
-       'Set elementNode attribute dictionary to a tilt following path from the start to end.'
-       elementNode.attributes['path'] = [start, end]
-       elementNode.attributes['tiltFollow'] = 'true'
-       elementNode.attributes['tiltTop'] = Vector3(0.0, 0.0, 1.0)
-
-def setOffsetByMultiplier(begin, end, multiplier, offset):
-       'Set the offset by the multiplier.'
-       segment = end - begin
-       delta = segment * multiplier - segment
-       offset.setToVector3(offset + delta)
-
-
-class ExtrudeDerivation(object):
-       'Class to hold extrude variables.'
-       def __init__(self, elementNode):
-               'Initialize.'
-               self.elementNode = elementNode
-               self.interpolationDictionary = {}
-               self.tiltFollow = evaluate.getEvaluatedBoolean(True, elementNode, 'tiltFollow')
-               self.tiltTop = evaluate.getVector3ByPrefix(None, elementNode, 'tiltTop')
-               self.maximumUnbuckling = evaluate.getEvaluatedFloat(5.0, elementNode, 'maximumUnbuckling')
-               scalePathDefault = [Vector3(1.0, 1.0, 0.0), Vector3(1.0, 1.0, 1.0)]
-               self.interpolationDictionary['scale'] = Interpolation().getByPrefixZ(elementNode, scalePathDefault, 'scale')
-               self.target = evaluate.getTransformedPathsByKey([], elementNode, 'target')
-               if self.tiltTop == None:
-                       offsetPathDefault = [Vector3(), Vector3(0.0, 0.0, 1.0)]
-                       self.interpolationDictionary['offset'] = Interpolation().getByPrefixZ(elementNode, offsetPathDefault, '')
-                       tiltPathDefault = [Vector3(), Vector3(0.0, 0.0, 1.0)]
-                       self.interpolationDictionary['tilt'] = Interpolation().getByPrefixZ(elementNode, tiltPathDefault, 'tilt')
-                       for point in self.interpolationDictionary['tilt'].path:
-                               point.x = math.radians(point.x)
-                               point.y = math.radians(point.y)
-               else:
-                       offsetAlongDefault = [Vector3(), Vector3(1.0, 0.0, 0.0)]
-                       self.interpolationDictionary['offset'] = Interpolation().getByPrefixAlong(elementNode, offsetAlongDefault, '')
-               self.twist = evaluate.getEvaluatedFloat(0.0, elementNode, 'twist')
-               self.twistPathDefault = [Vector3(), Vector3(1.0, self.twist) ]
-               insertTwistPortions(self, elementNode)
-
-
-class Interpolation(object):
-       'Class to interpolate a path.'
-       def __init__(self):
-               'Set index.'
-               self.interpolationIndex = 0
-
-       def __repr__(self):
-               'Get the string representation of this Interpolation.'
-               return str(self.__dict__)
-
-       def getByDistances(self):
-               'Get by distances.'
-               beginDistance = self.distances[0]
-               self.interpolationLength = self.distances[-1] - beginDistance
-               self.close = abs(0.000001 * self.interpolationLength)
-               self.portionDirections = []
-               oldDistance = -self.interpolationLength # so the difference should not be close
-               for distance in self.distances:
-                       deltaDistance = distance - beginDistance
-                       portionDirection = PortionDirection(deltaDistance / self.interpolationLength)
-                       if abs(deltaDistance - oldDistance) < self.close:
-                               portionDirection.directionReversed = True
-                       self.portionDirections.append(portionDirection)
-                       oldDistance = deltaDistance
-               return self
-
-       def getByPrefixAlong(self, elementNode, path, prefix):
-               'Get interpolation from prefix and xml element along the path.'
-               if len(path) < 2:
-                       print('Warning, path is too small in evaluate in Interpolation.')
-                       return
-               if elementNode == None:
-                       self.path = path
-               else:
-                       self.path = evaluate.getTransformedPathByPrefix(elementNode, path, prefix)
-               self.distances = [0.0]
-               previousPoint = self.path[0]
-               for point in self.path[1 :]:
-                       distanceDifference = abs(point - previousPoint)
-                       self.distances.append(self.distances[-1] + distanceDifference)
-                       previousPoint = point
-               return self.getByDistances()
-
-       def getByPrefixX(self, elementNode, path, prefix):
-               'Get interpolation from prefix and xml element in the z direction.'
-               if len(path) < 2:
-                       print('Warning, path is too small in evaluate in Interpolation.')
-                       return
-               if elementNode == None:
-                       self.path = path
-               else:
-                       self.path = evaluate.getTransformedPathByPrefix(elementNode, path, prefix)
-               self.distances = []
-               for point in self.path:
-                       self.distances.append(point.x)
-               return self.getByDistances()
-
-       def getByPrefixZ(self, elementNode, path, prefix):
-               'Get interpolation from prefix and xml element in the z direction.'
-               if len(path) < 2:
-                       print('Warning, path is too small in evaluate in Interpolation.')
-                       return
-               if elementNode == None:
-                       self.path = path
-               else:
-                       self.path = evaluate.getTransformedPathByPrefix(elementNode, path, prefix)
-               self.distances = []
-               for point in self.path:
-                       self.distances.append(point.z)
-               return self.getByDistances()
-
-       def getComparison( self, first, second ):
-               'Compare the first with the second.'
-               if abs( second - first ) < self.close:
-                       return 0
-               if second > first:
-                       return 1
-               return - 1
-
-       def getComplexByPortion( self, portionDirection ):
-               'Get complex from z portion.'
-               self.setInterpolationIndexFromTo( portionDirection )
-               return self.oneMinusInnerPortion * self.startVertex.dropAxis() + self.innerPortion * self.endVertex.dropAxis()
-
-       def getInnerPortion(self):
-               'Get inner x portion.'
-               fromDistance = self.distances[ self.interpolationIndex ]
-               innerLength = self.distances[ self.interpolationIndex + 1 ] - fromDistance
-               if abs( innerLength ) == 0.0:
-                       return 0.0
-               return ( self.absolutePortion - fromDistance ) / innerLength
-
-       def getVector3ByPortion( self, portionDirection ):
-               'Get vector3 from z portion.'
-               self.setInterpolationIndexFromTo( portionDirection )
-               return self.oneMinusInnerPortion * self.startVertex + self.innerPortion * self.endVertex
-
-       def getYByPortion( self, portionDirection ):
-               'Get y from x portion.'
-               self.setInterpolationIndexFromTo( portionDirection )
-               return self.oneMinusInnerPortion * self.startVertex.y + self.innerPortion * self.endVertex.y
-
-       def setInterpolationIndex( self, portionDirection ):
-               'Set the interpolation index.'
-               self.absolutePortion = self.distances[0] + self.interpolationLength * portionDirection.portion
-               interpolationIndexes = range( 0, len( self.distances ) - 1 )
-               if portionDirection.directionReversed:
-                       interpolationIndexes.reverse()
-               for self.interpolationIndex in interpolationIndexes:
-                       begin = self.distances[ self.interpolationIndex ]
-                       end = self.distances[ self.interpolationIndex + 1 ]
-                       if self.getComparison( begin, self.absolutePortion ) != self.getComparison( end, self.absolutePortion ):
-                               return
-
-       def setInterpolationIndexFromTo( self, portionDirection ):
-               'Set the interpolation index, the start vertex and the end vertex.'
-               self.setInterpolationIndex( portionDirection )
-               self.innerPortion = self.getInnerPortion()
-               self.oneMinusInnerPortion = 1.0 - self.innerPortion
-               self.startVertex = self.path[ self.interpolationIndex ]
-               self.endVertex = self.path[ self.interpolationIndex + 1 ]
-
-
-class PortionDirection(object):
-       'Class to hold a portion and direction.'
-       def __init__( self, portion ):
-               'Initialize.'
-               self.directionReversed = False
-               self.portion = portion
-
-       def __repr__(self):
-               'Get the string representation of this PortionDirection.'
-               return '%s: %s' % ( self.portion, self.directionReversed )
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/gear.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/gear.py
deleted file mode 100644 (file)
index 9023964..0000000
+++ /dev/null
@@ -1,1150 +0,0 @@
-"""
-This page is in the table of contents.
-The gear script can generate a spur gear couple, a bevel gear couple, a ring gear couple and a rack & pinion couple.
-
-A helix pattern can be added to each gear type.  All the gear types have a clearance and all the teeth can be beveled.  A keyway, shaft and lightening holes can be added to all the round gears, and rack holes can be added to the rack.  The script can output solid gears or only the gear profiles.  Both gears of the couple can be generated or just one.
-
-The couple has a pinion gear and a complement.
-
-==Examples==
-The link text includes the distinguishing parameters.  Each svg page was generated from an xml page of the same root name using carve.  For example, gear.svg was generated by clicking 'Carve' on the carve tool panel and choosing gear.xml in the file chooser.
-
-Each generated svg file has the xml fabmetheus element without comments towards the end of the file.  To see it, open the svg file in a text editor and search for 'fabmetheus'   If you copy that into a new text document, add the line '<?xml version='1.0' ?>' at the beginning and then give it a file name with the extension '.xml', you could then generate another svg file using carve.
-
-===Bevel===
-Bevel gear couple.
-
-<a href='../models/xml_models/creation/gear/bevel.svg'>gear operatingAngle=90</a>
-
-===Collar===
-Spur gear couple and each gear has a collar.
-
-<a href='../models/xml_models/creation/gear/collar.svg'>gear complementCollarLengthOverFaceWidth='1' pinionCollarLengthOverFaceWidth='1' shaftRadius='5'</a>
-
-===Gear===
-Default spur gear with no parameters.
-
-<a href='../models/xml_models/creation/gear/gear.svg'>gear</a>
-
-===Keyway===
-Spur gear couple and each gear has a collar and defined keyway.
-
-<a href='../models/xml_models/creation/gear/keyway.svg'>gear complementCollarLengthOverFaceWidth='1' keywayRadius='2' pinionCollarLengthOverFaceWidth='1' shaftRadius='5'</a>
-
-===Rack===
-Rack and pinion couple.
-
-<a href='../models/xml_models/creation/gear/rack.svg'>gear teethComplement='0'</a>
-
-===Rack Hole===
-Rack and pinion couple, with holes in the rack.
-
-<a href='../models/xml_models/creation/gear/rack_hole.svg'>gear rackHoleRadiusOverWidth='0.2' rackWidthOverFaceWidth='2' teethComplement='0'</a>
-
-===Ring===
-Pinion and ring gear.
-
-<a href='../models/xml_models/creation/gear/ring.svg'>gear teethComplement='-23'</a>
-
-===Shaft===
-Spur gear couple and each gear has a square shaft hole.
-
-<a href='../models/xml_models/creation/gear/shaft.svg'>gear shaftRadius='5'</a>
-
-===Shaft Top===
-Spur gear couple and each gear has a round shaft hole, truncated on top.
-
-<a href='../models/xml_models/creation/gear/shaft_top.svg'>gear shaftRadius='5' shaftSides='13' shaftDepthTop='2'</a>
-
-===Spur Helix===
-Spur gear couple with the gear teeth following a helix path.
-
-<a href='../models/xml_models/creation/gear/spur_helix.svg'>gear  helixAngle='45'</a>
-
-===Spur Herringbone===
-Spur gear couple with the gear teeth following a herringbone path.
-
-<a href='../models/xml_models/creation/gear/spur_herringbone.svg'>gear  helixAngle='45' helixType='herringbone'</a>
-
-===Spur Parabolic===
-Spur gear couple with the gear teeth following a parabolic path.
-
-<a href='../models/xml_models/creation/gear/spur_parabolic.svg'>gear  helixAngle='45' helixType='parabolic'</a>
-
-===Spur Profile===
-Spur gear couple profile.  Since this is just a horizontal path, it can not be sliced, so the path is then extruded to create a solid which can be sliced and viewed.
-
-<a href='../models/xml_models/creation/gear/spur_profile.svg'>gear id='spurProfile' faceWidth='0' | extrude target='=document.getElementByID(spurProfile)</a>
-
-==Parameters==
-===Center Distance===
-Default is such that the pitch radius works out to twenty.
-
-Defines the distance between the gear centers.
-
-===Clearance Couplet===
-====Clearance Over Wavelength====
-Default is 0.1.
-
-Defines the ratio of the clearance over the wavelength of the gear profile.  The wavelength is the arc distance between the gear teeth.
-
-====Clearance====
-Default is the 'Clearance Over Wavelength' times the wavelength.
-
-Defines the clearance between the gear tooth and the other gear of the couple.  If the clearance is zero, the outside of the gear tooth will touch the other gear.  If the clearance is too high, the gear teeth will be long and weak.
-
-===Collar Addendum Couplet===
-====Collar Addendum Over Radius====
-Default is one.
-
-Defines the ratio of the collar addendum over the shaft radius.
-
-====Collar Addendum====
-Default is the 'Collar Addendum Over Radius' times the shaft radius.
-
-Defines the collar addendum.
-
-===Complement Collar Length Couplet===
-====Complement Collar Length Over Face Width====
-Default is zero.
-
-Defines the ratio of the complement collar length over the face width.
-
-====Complement Collar Length====
-Default is the 'Complement Collar Length Over Face Width' times the face width.
-
-Defines the complement collar length.  If the complement collar length is zero, there will not be a collar on the complement gear.
-
-===Creation Type===
-Default is 'both'.
-
-====Both====
-When selected, the pinion and complement will be generated.
-
-====Complement====
-When selected, only the complement gear or rack will be generated.
-
-====Pinion====
-When selected, only the pinion will be generated.
-
-===Face Width===
-Default is ten.
-
-Defines the face width.
-
-===Gear Hole Paths===
-Default is empty.
-
-Defines the centers of the gear holes.  If the gear hole paths parameter is the default empty, then the centers of the gear holes will be generated from other parameters.
-
-===Helix Angle===
-Default is zero.
-
-===Helix Path===
-Default is empty.
-
-Defines the helix path of the gear teeth.  If the helix path is the default empty, then the helix will be generated from the helix angle and helix type.
-
-===Helix Type===
-Default is 'basic'.
-
-====Basic====
-When selected, the helix will be basic.
-
-====Herringbone====
-When selected, the helix will have a herringbone pattern.
-
-====Parabolic====
-When selected, the helix will have a parabolic pattern.
-
-===Keyway Radius Couplet===
-====Keyway Radius Over Radius====
-Default is half.
-
-Defines the ratio of the keyway radius over the shaft radius.
-
-====Keyway Radius====
-Default is the 'Keyway Radius Over Radius' times the shaft radius.
-
-Defines the keyway radius.  If the keyway radius is zero, there will not be a keyway on the collar.
-
-===Lightening Hole Margin Couplet===
-====Lightening Hole Margin Over Rim Dedendum====
-Default is one.
-
-Defines the ratio of the lightening hole margin over the rim dedendum.
-
-====Lightening Hole Margin====
-Default is the 'Lightening Hole Margin Over Rim Dedendum' times the rim dedendum.
-
-Defines the minimum margin between lightening holes.
-
-===Lightening Hole Minimum Radius===
-Default is one.
-
-Defines the minimum radius of the lightening holes.
-
-===Move Type===
-Default is 'separate'.
-
-====None====
-When selected, the gears will be not be moved and will therefore overlap.  Afterwards the write plugin could be used to write each gear to a different file, so they can be fabricated in separate operations.
-
-====Mesh====
-When selected, the gears will be separated horizontally so that they just mesh.  This is useful to test if the gears mesh properly.
-
-====Separate====
-When selected, the gears will be separated horizontally with a gap between them.
-
-====Vertical====
-When selected, the gears will be separated vertically.
-
-===Operating Angle===
-Default is 180 degrees.
-
-Defines the operating angle between the gear axes.  If the operating angle is not 180 degrees, a bevel gear couple will be generated.
-
-===Pinion Collar Length Couplet===
-====Pinion Collar Length Over Face Width====
-Default is zero.
-
-Defines the ratio of the pinion collar length over the face width.
-
-====Pinion Collar Length====
-Default is the 'Pinion Collar Length Over Face Width' times the face width.
-
-Defines the pinion collar length.  If the pinion collar length is zero, there will not be a collar on the pinion gear.
-
-===Pitch Radius===
-Default is twenty if the pitch radius has not been set.  If the center distance is set, the default pitch radius is the center distance times the number of pinion teeth divided by the total number of gear teeth.
-
-Defines the pinion pitch radius.
-
-===Plate Clearance Couplet===
-====Plate Clearance Over Length====
-Default is 0.2.
-
-Defines the ratio of the plate clearance over the plate length.
-
-====Plate Clearance====
-Default is the 'Plate Clearance Over Length' times the plate length.
-
-Defines the clearance between the pinion and the plate of the ring gear.  If the clearance is zero, they will touch.
-
-===Plate Length Couplet===
-====Plate Length Over Face Width====
-Default is half.
-
-Defines the ratio of the plate length over the face width.
-
-====Plate Length====
-Default is the 'Plate Length Over Face Width' times the face width.
-
-Defines the length of the plate of the ring gear.
-
-===Pressure Angle===
-Default is twenty degrees.
-
-Defines the pressure angle of the gear couple.
-
-===Profile Surfaces===
-Default is eleven.
-
-Defines the number of profile surfaces.
-
-===Rack Hole Below Over Width Couplet===
-====Rack Hole Below Over Width====
-Default is 0.6.
-
-Defines the ratio of the distance below the pitch of the rack holes over the rack width.
-
-====Rack Hole Below====
-Default is the 'Rack Hole Below Over Width' times the rack width.
-
-Defines the the distance below the pitch of the rack holes.
-
-===Rack Hole Radius Couplet===
-====Rack Hole Radius Over Width====
-Default is zero.
-
-Defines the ratio of the rack hole radius over the rack width.
-
-====Rack Hole Radius====
-Default is the 'Rack Hole Radius Over Width' times the rack width.
-
-Defines the radius of the rack holes.  If the rack hole radius is zero, there won't be any rack holes.
-
-===Rack Hole Step Over Width Couplet===
-====Rack Hole Step Over Width====
-Default is one.
-
-Defines the ratio of the rack hole step over the rack width.
-
-====Rack Hole Step====
-Default is the 'Rack Hole Step Over Width' times the rack width.
-
-Defines the horizontal step distance between the rack holes.
-
-===Rack Length Over Radius Couplet===
-====Rack Length Over Radius====
-Default is two times pi.
-
-Defines the ratio of the rack length over the pitch radius.
-
-====Rack Length====
-Default is the 'Rack Length Over Radius' times the pitch radius.
-
-Defines the rack length.
-
-===Rack Width Couplet===
-====Rack Width Over Face Width====
-Default is one.
-
-Defines the ratio of the rack width over the face width.
-
-====Rack Width====
-Default is the 'Rack Width Over Face Width' times the face width.
-
-Defines the rack width.
-
-===Rim Dedendum Couplet===
-====Rim Dedendum Over Radius====
-Default is 0.2.
-
-Defines the ratio of the rim dedendum over the pitch radius.
-
-====Rim Dedendum====
-Default is the 'Rim Dedendum Over Radius' times the pitch radius.
-
-Defines the rim dedendum of the gear.
-
-===Root Bevel Couplet===
-====Root Bevel Over Clearance====
-Default is half.
-
-Defines the ratio of the root bevel over the clearance.
-
-====Root Bevel====
-Default is the 'Root Bevel Over Clearance' times the clearance.
-
-Defines the bevel at the root of the gear tooth.
-
-===Shaft Depth Bottom Couplet===
-====Shaft Depth Bottom Over Radius====
-Default is zero.
-
-Defines the ratio of the bottom shaft depth over the shaft radius.
-
-====Shaft Depth Bottom====
-Default is the 'Shaft Depth Bottom Over Radius' times the shaft radius.
-
-Defines the bottom shaft depth.
-
-===Shaft Depth Top Couplet===
-====Shaft Depth Top Over Radius====
-Default is zero.
-
-Defines the ratio of the top shaft depth over the shaft radius.
-
-====Shaft Depth Top====
-Default is the 'Shaft Depth Top Over Radius' times the shaft radius.
-
-Defines the top shaft depth.
-
-===Shaft Path===
-Default is empty.
-
-Defines the path of the shaft hole.  If the shaft path is the default empty, then the shaft path will be generated from the shaft depth bottom, shaft depth top, shaft radius and shaft sides.
-
-===Shaft Radius Couplet===
-====Shaft Radius Over Pitch Radius====
-Default is zero.
-
-Defines the ratio of the shaft radius over the pitch radius.
-
-====Shaft Radius====
-Default is the 'Shaft Radius Over Pitch Radius' times the pitch radius.
-
-Defines the shaft radius.  If the shaft radius is zero there will not be a shaft hole.
-
-===Shaft Sides===
-Default is four.
-
-Defines the number of shaft sides.
-
-===Teeth Pinion===
-Default is seven.
-
-Defines the number of teeth in the pinion.
-
-===Teeth Complement===
-Default is seventeen.
-
-Defines the number of teeth in the complement of the gear couple.  If the number of teeth is positive, the gear couple will be a spur or bevel type.  If the number of teeth is zero, the gear couple will be a rack and pinion.  If the number of teeth is negative, the gear couple will be a spur and ring.
-
-===Tip Bevel Couplet===
-====Tip Bevel Over Clearance====
-Default is 0.1.
-
-Defines the ratio of the tip bevel over the clearance.
-
-====Tip Bevel====
-Default is the 'Tip Bevel Over Clearance' times the clearance.
-
-Defines the bevel at the tip of the gear tooth.
-
-===Tooth Thickness Multiplier===
-Default is 0.99999.
-
-Defines the amount the thickness of the tooth will multiplied.  If when the gears are produced, they mesh too tightly, you can reduce the tooth thickness multiplier so that they mesh with reasonable tightness.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import extrude
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.creation import shaft
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.creation import teardrop
-from fabmetheus_utilities.geometry.geometry_tools import path
-from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities.vector3index import Vector3Index
-from fabmetheus_utilities import euclidean
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addBevelGear(derivation, extrudeDerivation, pitchRadius, positives, teeth, vector3GearProfile):
-       "Get extrude output for a cylinder gear."
-       totalPitchRadius = derivation.pitchRadiusComplement + derivation.pitchRadius
-       totalTeeth = derivation.teethPinion + derivation.teethComplement
-       portionDirections = extrude.getSpacedPortionDirections(extrudeDerivation.interpolationDictionary)
-       loopLists = extrude.getLoopListsByPath(extrudeDerivation, None, vector3GearProfile[0], portionDirections)
-       firstLoopList = loopLists[0]
-       gearOverPinion = float(totalTeeth - teeth) / float(teeth)
-       thirdLayerHeight = 0.33333333333 * setting.getLayerHeight(derivation.elementNode)
-       pitchRadian = math.atan(math.sin(derivation.operatingRadian) / (gearOverPinion + math.cos(derivation.operatingRadian)))
-       coneDistance = pitchRadius / math.sin(pitchRadian)
-       apex = Vector3(0.0, 0.0, math.sqrt(coneDistance * coneDistance - pitchRadius * pitchRadius))
-       cosPitch = apex.z / coneDistance
-       sinPitch = math.sin(pitchRadian)
-       for loop in firstLoopList:
-               for point in loop:
-                       alongWay = point.z / coneDistance
-                       oneMinusAlongWay = 1.0 - alongWay
-                       pointComplex = point.dropAxis()
-                       pointComplexLength = abs(pointComplex)
-                       deltaRadius = pointComplexLength - pitchRadius
-                       cosDeltaRadius = cosPitch * deltaRadius
-                       sinDeltaRadius = sinPitch * deltaRadius
-                       pointComplex *= (cosDeltaRadius + pitchRadius) / pointComplexLength
-                       point.x = pointComplex.real
-                       point.y = pointComplex.imag
-                       point.z += sinDeltaRadius
-                       point.x *= oneMinusAlongWay
-                       point.y *= oneMinusAlongWay
-       addBottomLoop(-thirdLayerHeight, firstLoopList)
-       topLoop = firstLoopList[-1]
-       topAddition = []
-       topZ = euclidean.getTopPath(topLoop) + thirdLayerHeight
-       oldIndex = topLoop[-1].index
-       for point in topLoop:
-               oldIndex += 1
-               topAddition.append(Vector3Index(oldIndex, 0.8 * point.x, 0.8 * point.y, topZ))
-       firstLoopList.append(topAddition)
-       translation = Vector3(0.0, 0.0, -euclidean.getBottomByPaths(firstLoopList))
-       euclidean.translateVector3Paths(firstLoopList, translation)
-       geometryOutput = triangle_mesh.getPillarsOutput(loopLists)
-       positives.append(geometryOutput)
-
-def addBottomLoop(deltaZ, loops):
-       "Add bottom loop to loops."
-       bottomLoop = loops[0]
-       bottomAddition = []
-       bottomZ = euclidean.getBottomByPath(bottomLoop) + deltaZ
-       for point in bottomLoop:
-               bottomAddition.append(Vector3Index(len(bottomAddition), point.x, point.y, bottomZ))
-       loops.insert(0, bottomAddition)
-       numberOfVertexes = 0
-       for loop in loops:
-               for point in loop:
-                       point.index = numberOfVertexes
-                       numberOfVertexes += 1
-
-def addCollarShaft(collarLength, derivation, elementNode, negatives, positives):
-       'Add collar.'
-       if collarLength <= 0.0:
-               addShaft(derivation, negatives, positives)
-               return
-       connectionEnd = Vector3(0.0, 0.0, derivation.faceWidth + collarLength)
-       copyShallow = derivation.elementNode.getCopyShallow()
-       copyShallow.attributes['path'] = [Vector3(0.0, 0.0, derivation.faceWidth), connectionEnd]
-       collarDerivation = extrude.ExtrudeDerivation(copyShallow)
-       addCollarShaftSetDerivation(collarDerivation, collarLength, derivation, elementNode, negatives, positives)
-
-def addCollarShaftSetDerivation(collarDerivation, collarLength, derivation, elementNode, negatives, positives):
-       'Add collar and shaft.'
-       collarSides = evaluate.getSidesMinimumThreeBasedOnPrecision(elementNode, derivation.shaftRimRadius)
-       collarProfile = euclidean.getComplexPolygon(complex(), derivation.shaftRimRadius, collarSides)
-       vector3CollarProfile = euclidean.getVector3Path(collarProfile)
-       extrude.addPositives(collarDerivation, [vector3CollarProfile], positives)
-       addShaft(derivation, negatives, positives)
-       drillZ = derivation.faceWidth + 0.5 * collarLength
-       drillEnd = Vector3(0.0, derivation.shaftRimRadius, drillZ)
-       drillStart = Vector3(0.0, 0.0, drillZ)
-       teardrop.addNegativesByRadius(elementNode, drillEnd, negatives, derivation.keywayRadius, drillStart)
-
-def addLighteningHoles(derivation, gearHolePaths, negatives, pitchRadius, positives):
-       "Add lightening holes."
-       positiveVertexes = matrix.getVertexes(positives)
-       bottomPath = euclidean.getTopPath(positiveVertexes)
-       topPath = euclidean.getBottomByPath(positiveVertexes)
-       copyShallow = derivation.elementNode.getCopyShallow()
-       copyShallow.attributes['path'] = [Vector3(0.0, 0.0, bottomPath), Vector3(0.0, 0.0, topPath)]
-       extrudeDerivation = extrude.ExtrudeDerivation(copyShallow)
-       vector3LighteningHoles = getLighteningHoles(derivation, gearHolePaths, pitchRadius)
-       extrude.addNegativesPositives(extrudeDerivation, negatives, vector3LighteningHoles, positives)
-
-def addRackHole(derivation, elementNode, vector3RackProfiles, x):
-       "Add rack hole to vector3RackProfiles."
-       rackHole = euclidean.getComplexPolygon(complex(x, -derivation.rackHoleBelow), derivation.rackHoleRadius, -13)
-       vector3RackProfiles.append(euclidean.getVector3Path(rackHole))
-
-def addRackHoles(derivation, elementNode, vector3RackProfiles):
-       "Add rack holes to vector3RackProfiles."
-       if len(derivation.gearHolePaths) > 0:
-               vector3RackProfiles += derivation.gearHolePaths
-               return
-       if derivation.rackHoleRadius <= 0.0:
-               return
-       addRackHole(derivation, elementNode, vector3RackProfiles, 0.0)
-       rackHoleMargin = derivation.rackHoleRadius + derivation.rackHoleRadius
-       rackHoleSteps = int(math.ceil((derivation.rackDemilength - rackHoleMargin) / derivation.rackHoleStep))
-       for rackHoleIndex in xrange(1, rackHoleSteps):
-               x = float(rackHoleIndex) * derivation.rackHoleStep
-               addRackHole(derivation, elementNode, vector3RackProfiles, -x)
-               addRackHole(derivation, elementNode, vector3RackProfiles, x)
-
-def addShaft(derivation, negatives, positives):
-       "Add shaft."
-       if len(derivation.shaftPath) < 3:
-               return
-       positiveVertexes = matrix.getVertexes(positives)
-       bottomPath = euclidean.getTopPath(positiveVertexes)
-       topPath = euclidean.getBottomByPath(positiveVertexes)
-       copyShallow = derivation.elementNode.getCopyShallow()
-       copyShallow.attributes['path'] = [Vector3(0.0, 0.0, bottomPath), Vector3(0.0, 0.0, topPath)]
-       extrudeDerivation = extrude.ExtrudeDerivation(copyShallow)
-       extrude.addNegativesPositives(extrudeDerivation, negatives, [derivation.shaftPath], positives)
-
-def getAxialMargin(circleRadius, numberOfSides, polygonRadius):
-       'Get axial margin.'
-       return polygonRadius * math.sin(math.pi / float(numberOfSides)) - circleRadius
-
-def getBevelPath(begin, bevel, center, end):
-       'Get bevel path.'
-       centerMinusBegin = center - begin
-       centerMinusBeginLength = abs(centerMinusBegin)
-       endMinusCenter = end - center
-       endMinusCenterLength = abs(endMinusCenter)
-       endMinusCenter /= endMinusCenterLength
-       maximumExtensionLength = 0.333333333 * endMinusCenterLength
-       if centerMinusBeginLength <= bevel * 1.5:
-               extensionLength = min(maximumExtensionLength, centerMinusBeginLength)
-               return [complex(center.real, center.imag) + extensionLength * endMinusCenter]
-       centerMinusBegin *= (centerMinusBeginLength - bevel) / centerMinusBeginLength
-       extensionLength = min(maximumExtensionLength, bevel)
-       bevelPath = [complex(center.real, center.imag) + extensionLength * endMinusCenter]
-       bevelPath.append(begin + centerMinusBegin)
-       return bevelPath
-
-def getGearPaths(derivation, pitchRadius, teeth, toothProfile):
-       'Get gear paths.'
-       if teeth < 0:
-               return getGearProfileAnnulus(derivation, pitchRadius, teeth, toothProfile)
-       if teeth == 0:
-               return [getGearProfileRack(derivation, toothProfile)]
-       return [getGearProfileCylinder(teeth, toothProfile)]
-
-def getGearProfileAnnulus(derivation, pitchRadius, teeth, toothProfile):
-       'Get gear profile for an annulus gear.'
-       gearProfileCylinder = getGearProfileCylinder(teeth, toothProfile)
-       annulusRadius = derivation.dedendum + derivation.rimDedendum - pitchRadius
-       return [euclidean.getComplexPolygon(complex(), annulusRadius, -teeth, 0.5 * math.pi), gearProfileCylinder]
-
-def getGearProfileCylinder(teeth, toothProfile):
-       'Get gear profile for a cylinder gear.'
-       gearProfile = []
-       toothAngleRadian = 2.0 * math.pi / float(teeth)
-       totalToothAngle = 0.0
-       for toothIndex in xrange(abs(teeth)):
-               for toothPoint in toothProfile:
-                       gearProfile.append(toothPoint * euclidean.getWiddershinsUnitPolar(totalToothAngle))
-               totalToothAngle += toothAngleRadian
-       return gearProfile
-
-def getGearProfileRack(derivation, toothProfile):
-       'Get gear profile for rack.'
-       derivation.extraRackDemilength = 0.0
-       for complexPoint in derivation.helixPath:
-               derivation.extraRackDemilength = max(abs(derivation.helixHeight * complexPoint.imag), derivation.extraRackDemilength)
-       rackDemilengthPlus = derivation.rackDemilength
-       if derivation.faceWidth > 0.0:
-               derivation.extraRackDemilength *= 1.1
-               rackDemilengthPlus += derivation.extraRackDemilength
-       teethRack = int(math.ceil(rackDemilengthPlus / derivation.wavelength))
-       gearProfile = []
-       for toothIndex in xrange(-teethRack, teethRack + 1):
-               translateComplex = complex(-toothIndex * derivation.wavelength, 0.0)
-               translatedPath = euclidean.getTranslatedComplexPath(toothProfile, translateComplex)
-               gearProfile += translatedPath
-       gearProfile = euclidean.getHorizontallyBoundedPath(rackDemilengthPlus, -rackDemilengthPlus, gearProfile)
-       firstPoint = gearProfile[0]
-       lastPoint = gearProfile[-1]
-       rackWidth = derivation.rackWidth
-       minimumRackWidth = 1.1 * derivation.dedendum
-       if rackWidth < minimumRackWidth:
-               rackWidth = minimumRackWidth
-               print('Warning, rackWidth is too small in getGearProfileRack in gear.')
-               print('RackWidth will be set to a bit more than the dedendum.')
-       gearProfile += [complex(lastPoint.real, -rackWidth),complex(firstPoint.real, -rackWidth)]
-       return gearProfile
-
-def getGeometryOutput(derivation, elementNode):
-       "Get vector3 vertexes from attribute dictionary."
-       if derivation == None:
-               derivation = GearDerivation(elementNode)
-       creationFirst = derivation.creationType.lower()[: 1]
-       toothProfileComplement = getToothProfile(derivation, derivation.pitchRadiusComplement, derivation.teethComplement)
-       pinionProfile = getGearProfileCylinder(derivation.teethPinion, derivation.pinionToothProfile)
-       complementPaths = getGearPaths(
-               derivation, derivation.pitchRadiusComplement, derivation.teethComplement, toothProfileComplement)
-       vector3PinionProfile = euclidean.getVector3Path(pinionProfile)
-       vector3ComplementPaths = euclidean.getVector3Paths(complementPaths)
-       translation = Vector3()
-       moveFirst = derivation.moveType.lower()[: 1]
-       if moveFirst != 'n':
-               distance = derivation.pitchRadius
-               if moveFirst == 'm':
-                       distance += derivation.pitchRadiusComplement
-               else:
-                       distance += abs(derivation.pitchRadiusComplement)
-                       decimalPlaces = 1 - int(math.floor(math.log10(distance)))
-                       distance += derivation.halfWavelength + derivation.halfWavelength
-                       distance = round(1.15 * distance, decimalPlaces)
-               translation = Vector3(0.0, -distance)
-       if derivation.faceWidth <=0.0:
-               return getPathOutput(
-                       creationFirst, derivation, elementNode, translation, vector3ComplementPaths, vector3PinionProfile)
-       pitchRadius = derivation.pitchRadius
-       teeth = derivation.teethPinion
-       twist = derivation.helixHeight / derivation.pitchRadius
-       extrudeOutputPinion = getOutputCylinder(
-               derivation.pinionCollarLength, derivation, elementNode, None, pitchRadius, teeth, twist, [vector3PinionProfile])
-       if creationFirst == 'p':
-               return extrudeOutputPinion
-       teeth = derivation.teethComplement
-       extrudeOutputSecond = None
-       if teeth == 0:
-               extrudeOutputSecond = getOutputRack(derivation, elementNode, vector3ComplementPaths[0])
-       else:
-               twist = -derivation.helixHeight / derivation.pitchRadiusComplement
-               extrudeOutputSecond = getOutputCylinder(
-                       derivation.complementCollarLength,
-                       derivation,
-                       elementNode,
-                       derivation.gearHolePaths,
-                       derivation.pitchRadiusComplement,
-                       teeth,
-                       twist,
-                       vector3ComplementPaths)
-       if creationFirst == 'c':
-               return extrudeOutputSecond
-       gearVertexes = matrix.getVertexes(extrudeOutputSecond)
-       if moveFirst == 'v':
-               translation = Vector3(0.0, 0.0, euclidean.getTopPath(gearVertexes))
-               euclidean.translateVector3Path(matrix.getVertexes(extrudeOutputPinion), translation)
-       else:
-               euclidean.translateVector3Path(gearVertexes, translation)
-       return {'group' : {'shapes' : [extrudeOutputPinion, extrudeOutputSecond]}}
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       "Get vector3 vertexes from attribute dictionary by arguments."
-       return getGeometryOutput(None, elementNode)
-
-def getHalfwave(pitchRadius, teeth):
-       'Get tooth halfwave.'
-       return pitchRadius * math.pi / float(teeth)
-
-def getHelixComplexPath(derivation, elementNode):
-       'Set gear helix path.'
-       helixTypeFirstCharacter = derivation.helixType.lower()[: 1]
-       if helixTypeFirstCharacter == 'b':
-               return [complex(), complex(1.0, 1.0)]
-       if helixTypeFirstCharacter == 'h':
-               return [complex(), complex(0.5, 0.5), complex(1.0, 0.0)]
-       if helixTypeFirstCharacter == 'p':
-               helixComplexPath = []
-               x = 0.0
-               xStep = setting.getLayerHeight(elementNode) / derivation.faceWidth
-               justBelowOne = 1.0 - 0.5 * xStep
-               while x < justBelowOne:
-                       distanceFromCenter = 0.5 - x
-                       parabolicTwist = 0.25 - distanceFromCenter * distanceFromCenter
-                       helixComplexPath.append(complex(x, parabolicTwist))
-                       x += xStep
-               helixComplexPath.append(complex(1.0, 0.0))
-               return helixComplexPath
-       print('Warning, the helix type was not one of (basic, herringbone or parabolic) in getHelixComplexPath in gear for:')
-       print(derivation.helixType)
-       print(derivation.elementNode)
-
-def getLiftedOutput(derivation, geometryOutput):
-       "Get extrude output for a rack."
-       if derivation.moveType.lower()[: 1] == 'm':
-               return geometryOutput
-       geometryOutputVertexes = matrix.getVertexes(geometryOutput)
-       translation = Vector3(0.0, 0.0, -euclidean.getBottomByPath(geometryOutputVertexes))
-       euclidean.translateVector3Path(geometryOutputVertexes, translation)
-       return geometryOutput
-
-def getLighteningHoles(derivation, gearHolePaths, pitchRadius):
-       'Get cutout circles.'
-       if gearHolePaths != None:
-               if len(gearHolePaths) > 0:
-                       return gearHolePaths
-       innerRadius = abs(pitchRadius) - derivation.dedendum
-       lighteningHoleOuterRadius = innerRadius - derivation.rimDedendum
-       shaftRimRadius = max(derivation.shaftRimRadius, (lighteningHoleOuterRadius) * (0.5 - math.sqrt(0.1875)))
-       lighteningHoleRadius = 0.5 * (lighteningHoleOuterRadius - derivation.shaftRimRadius)
-       if lighteningHoleRadius < derivation.lighteningHoleMinimumRadius:
-               return []
-       lighteningHoles = []
-       numberOfLighteningHoles = 3
-       polygonRadius = lighteningHoleOuterRadius - lighteningHoleRadius
-       rimDemiwidth = 0.5 * derivation.lighteningHoleMargin
-       axialMargin = getAxialMargin(lighteningHoleRadius, numberOfLighteningHoles, polygonRadius)
-       if axialMargin < rimDemiwidth:
-               while axialMargin < rimDemiwidth:
-                       lighteningHoleRadius *= 0.999
-                       if lighteningHoleRadius < derivation.lighteningHoleMinimumRadius:
-                               return []
-                       axialMargin = getAxialMargin(lighteningHoleRadius, numberOfLighteningHoles, polygonRadius)
-       else:
-               newNumberOfLighteningHoles = numberOfLighteningHoles
-               while axialMargin > rimDemiwidth:
-                       numberOfLighteningHoles = newNumberOfLighteningHoles
-                       newNumberOfLighteningHoles += 2
-                       axialMargin = getAxialMargin(lighteningHoleRadius, newNumberOfLighteningHoles, polygonRadius)
-       sideAngle = 2.0 * math.pi / float(numberOfLighteningHoles)
-       startAngle = 0.0
-       for lighteningHoleIndex in xrange(numberOfLighteningHoles):
-               unitPolar = euclidean.getWiddershinsUnitPolar(startAngle)
-               lighteningHole = euclidean.getComplexPolygon(unitPolar * polygonRadius, lighteningHoleRadius, -13)
-               lighteningHoles.append(lighteningHole)
-               startAngle += sideAngle
-       return euclidean.getVector3Paths(lighteningHoles)
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return GearDerivation(elementNode)
-
-def getOutputCylinder(
-               collarLength, derivation, elementNode, gearHolePaths, pitchRadius, teeth, twist, vector3GearProfile):
-       "Get extrude output for a cylinder gear."
-       copyShallow = derivation.elementNode.getCopyShallow()
-       copyShallow.attributes['path'] = [Vector3(), Vector3(0.0, 0.0, derivation.faceWidth)]
-       extrudeDerivation = extrude.ExtrudeDerivation(copyShallow)
-       negatives = []
-       positives = []
-       if twist != 0.0:
-               twistDegrees = math.degrees(twist)
-               extrudeDerivation.twistPathDefault = []
-               for complexPoint in derivation.helixPath:
-                       extrudeDerivation.twistPathDefault.append(Vector3(complexPoint.real, twistDegrees * complexPoint.imag))
-               extrude.insertTwistPortions(extrudeDerivation, elementNode)
-       if derivation.operatingAngle != 180.0:
-               addBevelGear(derivation, extrudeDerivation, pitchRadius, positives, teeth, vector3GearProfile)
-               addCollarShaft(collarLength, derivation, elementNode, negatives, positives)
-               return extrude.getGeometryOutputByNegativesPositives(elementNode, negatives, positives)
-       if pitchRadius > 0:
-               extrude.addNegativesPositives(extrudeDerivation, negatives, vector3GearProfile, positives)
-               addLighteningHoles(derivation, gearHolePaths, negatives, pitchRadius, positives)
-               addCollarShaft(collarLength, derivation, elementNode, negatives, positives)
-               return extrude.getGeometryOutputByNegativesPositives(elementNode, negatives, positives)
-       if derivation.plateLength <= 0.0:
-               extrude.addNegativesPositives(extrudeDerivation, negatives, vector3GearProfile, positives)
-               return extrude.getGeometryOutputByNegativesPositives(elementNode, negatives, positives)
-       portionDirections = extrude.getSpacedPortionDirections(extrudeDerivation.interpolationDictionary)
-       outerGearProfile = vector3GearProfile[0]
-       outerLoopLists = extrude.getLoopListsByPath(extrudeDerivation, None, outerGearProfile, portionDirections)
-       addBottomLoop(-derivation.plateClearance, outerLoopLists[0])
-       geometryOutput = triangle_mesh.getPillarsOutput(outerLoopLists)
-       positives.append(geometryOutput)
-       innerLoopLists = extrude.getLoopListsByPath(extrudeDerivation, None, vector3GearProfile[1], portionDirections)
-       addBottomLoop(-derivation.plateClearance, innerLoopLists[0])
-       geometryOutput = triangle_mesh.getPillarsOutput(innerLoopLists)
-       negatives.append(geometryOutput)
-       connectionStart = Vector3(0.0, 0.0, -derivation.plateLength)
-       copyShallow = derivation.elementNode.getCopyShallow()
-       copyShallow.attributes['path'] = [connectionStart, Vector3(0.0, 0.0, -derivation.plateClearance)]
-       plateDerivation = extrude.ExtrudeDerivation(copyShallow)
-       extrude.addNegativesPositives(plateDerivation, negatives, [outerGearProfile], positives)
-       vector3LighteningHoles = getLighteningHoles(derivation, gearHolePaths, pitchRadius)
-       extrude.addNegativesPositives(plateDerivation, negatives, vector3LighteningHoles, positives)
-       addShaft(derivation, negatives, positives)
-       positiveOutput = triangle_mesh.getUnifiedOutput(positives)
-       annulusPlateOutput = {'difference' : {'shapes' : [positiveOutput] + negatives}}
-       if collarLength <= 0.0:
-               outputCylinder = solid.getGeometryOutputByManipulation(elementNode, annulusPlateOutput)
-               return getLiftedOutput(derivation, outputCylinder)
-       negatives = []
-       positives = []
-       connectionEnd = Vector3(0.0, 0.0, derivation.faceWidth + collarLength)
-       copyShallow = derivation.elementNode.getCopyShallow()
-       copyShallow.attributes['path'] = [Vector3(0.0, 0.0, -derivation.plateClearance), connectionEnd]
-       collarDerivation = extrude.ExtrudeDerivation(copyShallow)
-       addCollarShaftSetDerivation(collarDerivation, collarLength, derivation, elementNode, negatives, positives)
-       collarOutput = {'difference' : {'shapes' : positives + negatives}}
-       cylinderOutput = {'union' : {'shapes' : [annulusPlateOutput, collarOutput]}}
-       outputCylinder = solid.getGeometryOutputByManipulation(elementNode, cylinderOutput)
-       return getLiftedOutput(derivation, outputCylinder)
-
-def getOutputRack(derivation, elementNode, vector3GearProfile):
-       "Get extrude output for a rack."
-       path = []
-       for complexPoint in derivation.helixPath:
-               point = Vector3(derivation.helixHeight * complexPoint.imag, 0.0, derivation.faceWidth * complexPoint.real)
-               path.append(point)
-       copyShallow = derivation.elementNode.getCopyShallow()
-       copyShallow.attributes['path'] = path
-       extrudeDerivation = extrude.ExtrudeDerivation(copyShallow)
-       negatives = []
-       positives = []
-       vector3RackProfiles = [vector3GearProfile]
-       if derivation.extraRackDemilength > 0.0:
-               yMaximum = -912345678.0
-               yMinimum = 912345678.0
-               for point in vector3GearProfile:
-                       yMaximum = max(point.y, yMaximum)
-                       yMinimum = min(point.y, yMinimum)
-               muchLessThanWidth = 0.01 * derivation.rackWidth
-               yMaximum += muchLessThanWidth
-               yMinimum -= muchLessThanWidth
-               extraRackLength = derivation.extraRackDemilength + derivation.extraRackDemilength
-               rackDemilengthPlus = derivation.rackDemilength + extraRackLength
-               leftNegative = [
-                       Vector3(-derivation.rackDemilength, yMaximum),
-                       Vector3(-derivation.rackDemilength, yMinimum),
-                       Vector3(-rackDemilengthPlus, yMinimum),
-                       Vector3(-rackDemilengthPlus, yMaximum)]
-               vector3RackProfiles.append(leftNegative)
-               rightNegative = [
-                       Vector3(rackDemilengthPlus, yMaximum),
-                       Vector3(rackDemilengthPlus, yMinimum),
-                       Vector3(derivation.rackDemilength, yMinimum),
-                       Vector3(derivation.rackDemilength, yMaximum)]
-               vector3RackProfiles.append(rightNegative)
-       addRackHoles(derivation, elementNode, vector3RackProfiles)
-       extrude.addNegativesPositives(extrudeDerivation, negatives, vector3RackProfiles, positives)
-       return extrude.getGeometryOutputByNegativesPositives(elementNode, negatives, positives)
-
-def getPathOutput(creationFirst, derivation, elementNode, translation, vector3ComplementPaths, vector3PinionProfile):
-       "Get gear path output."
-       vector3PinionProfile = lineation.getPackedGeometryOutputByLoop(elementNode, lineation.SideLoop(vector3PinionProfile))
-       if creationFirst == 'p':
-               return vector3PinionProfile
-       packedGearGeometry = []
-       for vector3ComplementPath in vector3ComplementPaths:
-               sideLoop = lineation.SideLoop(vector3ComplementPath)
-               packedGearGeometry += lineation.getPackedGeometryOutputByLoop(elementNode, sideLoop)
-       if creationFirst == 'c':
-               return packedGearGeometry
-       euclidean.translateVector3Paths(packedGearGeometry, translation)
-       return vector3PinionProfile + packedGearGeometry
-
-def getThicknessMultipliedPath(path, thicknessMultiplier):
-       "Get thickness multiplied path."
-       for pointIndex, point in enumerate(path):
-               path[pointIndex] = complex(point.real * thicknessMultiplier, point.imag)
-       return path
-
-def getToothProfile(derivation, pitchRadius, teeth):
-       'Get profile for one tooth.'
-       if teeth < 0:
-               return getToothProfileAnnulus(derivation, pitchRadius, teeth)
-       if teeth == 0:
-               return getToothProfileRack(derivation)
-       return getToothProfileCylinder(derivation, pitchRadius, teeth)
-
-def getToothProfileAnnulus(derivation, pitchRadius, teeth):
-       'Get profile for one tooth of an annulus.'
-       toothProfileHalf = []
-       toothProfileHalfCylinder = getToothProfileHalfCylinder(derivation, pitchRadius)
-       pitchRadius = -pitchRadius
-       innerRadius = pitchRadius - derivation.addendum
-       # tooth is multiplied by 1.02 because at around 1.01 for a 7/-23/20.0 test case, there is intersection since the paths are bending together
-       for point in getThicknessMultipliedPath(toothProfileHalfCylinder, 1.02 / derivation.toothThicknessMultiplier):
-               if abs(point) >= innerRadius:
-                       toothProfileHalf.append(point)
-       profileFirst = toothProfileHalf[0]
-       profileSecond = toothProfileHalf[1]
-       firstMinusSecond = profileFirst - profileSecond
-       remainingAddendum = abs(profileFirst) - innerRadius
-       firstMinusSecond *= remainingAddendum / abs(firstMinusSecond)
-       extensionPoint = profileFirst + firstMinusSecond
-       if derivation.tipBevel > 0.0:
-               unitPolar = euclidean.getWiddershinsUnitPolar(2.0 / float(teeth) * math.pi)
-               mirrorPoint = complex(-extensionPoint.real, extensionPoint.imag) * unitPolar
-               bevelPath = getBevelPath(profileFirst, derivation.tipBevel, extensionPoint, mirrorPoint)
-               toothProfileHalf = bevelPath + toothProfileHalf
-       else:
-               toothProfileHalf.insert(0, extensionPoint)
-       profileLast = toothProfileHalf[-1]
-       profilePenultimate = toothProfileHalf[-2]
-       lastMinusPenultimate = profileLast - profilePenultimate
-       remainingDedendum = pitchRadius - abs(profileLast) + derivation.dedendum
-       lastMinusPenultimate *= remainingDedendum / abs(lastMinusPenultimate)
-       extensionPoint = profileLast + lastMinusPenultimate
-       if derivation.rootBevel > 0.0:
-               mirrorPoint = complex(-extensionPoint.real, extensionPoint.imag)
-               bevelPath = getBevelPath(profileLast, derivation.rootBevel, extensionPoint, mirrorPoint)
-               bevelPath.reverse()
-               toothProfileHalf += bevelPath
-       else:
-               toothProfileHalf.append(extensionPoint)
-       toothProfileAnnulus = euclidean.getMirrorPath(toothProfileHalf)
-       toothProfileAnnulus.reverse()
-       return toothProfileAnnulus
-
-def getToothProfileCylinder(derivation, pitchRadius, teeth):
-       'Get profile for one tooth of a cylindrical gear.'
-       toothProfileHalfCylinder = getToothProfileHalfCylinder(derivation, pitchRadius)
-       toothProfileHalfCylinder = getThicknessMultipliedPath(toothProfileHalfCylinder, derivation.toothThicknessMultiplier)
-       toothProfileHalf = []
-       innerRadius = pitchRadius - derivation.dedendum
-       for point in toothProfileHalfCylinder:
-               if abs(point) >= innerRadius:
-                       toothProfileHalf.append(point)
-       return getToothProfileCylinderByProfile(derivation, pitchRadius, teeth, toothProfileHalf)
-
-def getToothProfileCylinderByProfile(derivation, pitchRadius, teeth, toothProfileHalf):
-       'Get profile for one tooth of a cylindrical gear.'
-       profileFirst = toothProfileHalf[0]
-       profileSecond = toothProfileHalf[1]
-       firstMinusSecond = profileFirst - profileSecond
-       remainingDedendum = abs(profileFirst) - pitchRadius + derivation.dedendum
-       firstMinusSecond *= remainingDedendum / abs(firstMinusSecond)
-       extensionPoint = profileFirst + firstMinusSecond
-       if derivation.rootBevel > 0.0:
-               unitPolar = euclidean.getWiddershinsUnitPolar(-2.0 / float(teeth) * math.pi)
-               mirrorPoint = complex(-extensionPoint.real, extensionPoint.imag) * unitPolar
-               bevelPath = getBevelPath(profileFirst, derivation.rootBevel, extensionPoint, mirrorPoint)
-               toothProfileHalf = bevelPath + toothProfileHalf
-       else:
-               toothProfileHalf.insert(0, extensionPoint)
-       if derivation.tipBevel > 0.0:
-               profileLast = toothProfileHalf[-1]
-               profilePenultimate = toothProfileHalf[-2]
-               mirrorPoint = complex(-profileLast.real, profileLast.imag)
-               bevelPath = getBevelPath(profilePenultimate, derivation.tipBevel, profileLast, mirrorPoint)
-               bevelPath.reverse()
-               toothProfileHalf = toothProfileHalf[: -1] + bevelPath
-       return euclidean.getMirrorPath(toothProfileHalf)
-
-def getToothProfileHalfCylinder(derivation, pitchRadius):
-       'Get profile for half of a one tooth of a cylindrical gear.'
-       toothProfile=[]
-#      x = -y * tan(p) + 1
-#      x*x + y*y = (2-cos(p))^2
-#      y*y*t*t-2yt+1+y*y=4-4c-c*c
-#      y*y*(t*t+1)-2yt=3-4c-c*c
-#      y*y*(t*t+1)-2yt-3+4c-c*c=0
-#      a=tt+1
-#      b=-2t
-#      c=c(4-c)-3
-       a = derivation.tanPressure * derivation.tanPressure + 1.0
-       b = -derivation.tanPressure - derivation.tanPressure
-       cEnd = derivation.cosPressure * (4.0 - derivation.cosPressure) - 3.0
-       yEnd = (-b - math.sqrt(b*b - 4 * a * cEnd)) * 0.5 / a
-       yEnd *= derivation.pitchRadius / abs(pitchRadius)
-       yEnd -= derivation.clearance / abs(pitchRadius)
-       # to prevent intersections, yBegin is moved towards the base circle, giving a thinner tooth
-       yBegin = -yEnd
-       if pitchRadius > 0.0:
-               yBegin = 0.5 * derivation.sinPressure + 0.5 * yBegin
-       beginComplex = complex(1.0 - yBegin * derivation.tanPressure, yBegin)
-       endComplex = complex(1.0 - yEnd * derivation.tanPressure, yEnd)
-       endMinusBeginComplex = endComplex - beginComplex
-       wholeAngle = -abs(endMinusBeginComplex) / derivation.cosPressure
-       wholeAngleIncrement = wholeAngle / float(derivation.profileSurfaces)
-       stringStartAngle = abs(beginComplex - complex(1.0, 0.0)) / derivation.cosPressure
-       wholeDepthIncrementComplex = endMinusBeginComplex / float(derivation.profileSurfaces)
-       for profileIndex in xrange(derivation.profileSurfaces + 1):
-               contactPoint = beginComplex + wholeDepthIncrementComplex * float(profileIndex)
-               stringAngle = stringStartAngle + wholeAngleIncrement * float(profileIndex)
-               angle = math.atan2(contactPoint.imag, contactPoint.real) - stringAngle
-               angle += 0.5 * math.pi - derivation.quarterWavelength / abs(pitchRadius)
-               toothPoint = abs(contactPoint) * euclidean.getWiddershinsUnitPolar(angle) * abs(pitchRadius)
-               toothProfile.append(toothPoint)
-       return toothProfile
-
-def getToothProfileRack(derivation):
-       'Get profile for one rack tooth.'
-       addendumSide = derivation.quarterWavelength - derivation.addendum * derivation.tanPressure
-       addendumComplex = complex(addendumSide, derivation.addendum)
-       dedendumSide = derivation.quarterWavelength + derivation.dedendum * derivation.tanPressure
-       dedendumComplex = complex(dedendumSide, -derivation.dedendum)
-       toothProfile = [dedendumComplex]
-       if derivation.rootBevel > 0.0:
-               mirrorPoint = complex(derivation.wavelength - dedendumSide, -derivation.dedendum)
-               toothProfile = getBevelPath(addendumComplex, derivation.rootBevel, dedendumComplex, mirrorPoint)
-       if derivation.tipBevel > 0.0:
-               mirrorPoint = complex(-addendumComplex.real, addendumComplex.imag)
-               bevelPath = getBevelPath(dedendumComplex, derivation.tipBevel, addendumComplex, mirrorPoint)
-               bevelPath.reverse()
-               toothProfile += bevelPath
-       else:
-               toothProfile.append(addendumComplex)
-       return euclidean.getMirrorPath(getThicknessMultipliedPath(toothProfile, derivation.toothThicknessMultiplier))
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       geometryOutput = getGeometryOutput(None, elementNode)
-       if geometryOutput.__class__ == list:
-               path.convertElementNode(elementNode, geometryOutput)
-       else:
-               solid.processElementNodeByGeometry(elementNode, geometryOutput)
-
-
-class GearDerivation(object):
-       "Class to hold gear variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.clearanceOverWavelength = evaluate.getEvaluatedFloat(0.1, elementNode, 'clearanceOverWavelength')
-               self.collarAddendumOverRadius = evaluate.getEvaluatedFloat(1.0, elementNode, 'collarAddendumOverRadius')
-               self.complementCollarLengthOverFaceWidth = evaluate.getEvaluatedFloat(
-                       0.0, elementNode, 'complementCollarLengthOverFaceWidth')
-               self.copyShallow = elementNode.getCopyShallow()
-               self.creationType = evaluate.getEvaluatedString('both', elementNode, 'creationType')
-               self.creationTypeMenuRadioStrings = 'both complement pinion'.split()
-               self.elementNode = elementNode
-               self.faceWidth = evaluate.getEvaluatedFloat(10.0, elementNode, 'faceWidth')
-               self.helixAngle = evaluate.getEvaluatedFloat(0.0, elementNode, 'helixAngle')
-               self.helixType = evaluate.getEvaluatedString('basic', elementNode, 'helixType')
-               self.helixTypeMenuRadioStrings = 'basic herringbone parabolic'.split()
-               self.keywayRadiusOverRadius = evaluate.getEvaluatedFloat(0.5, elementNode, 'keywayRadiusOverRadius')
-               self.lighteningHoleMarginOverRimDedendum = evaluate.getEvaluatedFloat(
-                       1.0, elementNode, 'lighteningHoleMarginOverRimDedendum')
-               self.lighteningHoleMinimumRadius = evaluate.getEvaluatedFloat(
-                       1.0, elementNode, 'lighteningHoleMinimumRadius')
-               self.moveType = evaluate.getEvaluatedString('separate', elementNode, 'moveType')
-               self.moveTypeMenuRadioStrings = 'mesh none separate vertical'.split()
-               self.operatingAngle = evaluate.getEvaluatedFloat(180.0, elementNode, 'operatingAngle')
-               self.pinionCollarLengthOverFaceWidth = evaluate.getEvaluatedFloat(
-                       0.0, elementNode, 'pinionCollarLengthOverFaceWidth')
-               self.plateClearanceOverLength = evaluate.getEvaluatedFloat(0.2, elementNode, 'plateClearanceOverLength')
-               self.plateLengthOverFaceWidth = evaluate.getEvaluatedFloat(0.5, elementNode, 'plateLengthOverFaceWidth')
-               self.pressureAngle = evaluate.getEvaluatedFloat(20.0, elementNode, 'pressureAngle')
-               self.profileSurfaces = evaluate.getEvaluatedInt(11, elementNode, 'profileSurfaces')
-               self.rackHoleBelowOverWidth = evaluate.getEvaluatedFloat(0.6, elementNode, 'rackHoleBelowOverWidth')
-               self.rackHoleRadiusOverWidth = evaluate.getEvaluatedFloat(0.0, elementNode, 'rackHoleRadiusOverWidth')
-               self.rackHoleStepOverWidth = evaluate.getEvaluatedFloat(1.0, elementNode, 'rackHoleStepOverWidth')
-               self.rackLengthOverRadius = evaluate.getEvaluatedFloat(math.pi + math.pi, elementNode, 'rackLengthOverRadius')
-               self.rackWidthOverFaceWidth = evaluate.getEvaluatedFloat(1.0, elementNode, 'rackWidthOverFaceWidth')
-               self.rimDedendumOverRadius = evaluate.getEvaluatedFloat(0.2, elementNode, 'rimDedendumOverRadius')
-               self.rootBevelOverClearance = evaluate.getEvaluatedFloat(0.5, elementNode, 'rootBevelOverClearance')
-               self.shaftDepthBottomOverRadius = evaluate.getEvaluatedFloat(0.0, elementNode, 'shaftDepthBottomOverRadius')
-               self.shaftDepthTopOverRadius = evaluate.getEvaluatedFloat(0.0, elementNode, 'shaftDepthOverRadius')
-               self.shaftRadiusOverPitchRadius = evaluate.getEvaluatedFloat(0.0, elementNode, 'shaftRadiusOverPitchRadius')
-               self.shaftSides = evaluate.getEvaluatedInt(4, elementNode, 'shaftSides')
-               self.teethComplement = evaluate.getEvaluatedInt(17, elementNode, 'teethComplement')
-               self.teethPinion = evaluate.getEvaluatedInt(7, elementNode, 'teeth')
-               totalTeethOverPinionTeeth = float(self.teethComplement + self.teethPinion) / float(self.teethPinion)
-               self.centerDistance = evaluate.getEvaluatedFloat(20.0 * totalTeethOverPinionTeeth, elementNode, 'centerDistance')
-               derivedPitchRadius = self.centerDistance / totalTeethOverPinionTeeth
-               self.pitchRadius = evaluate.getEvaluatedFloat(derivedPitchRadius, elementNode, 'pitchRadius')
-               self.tipBevelOverClearance = evaluate.getEvaluatedFloat(0.1, elementNode, 'tipBevelOverClearance')
-               # tooth multiplied by 0.99999 to avoid an intersection
-               self.toothThicknessMultiplier = evaluate.getEvaluatedFloat(0.99999, elementNode, 'toothThicknessMultiplier')
-               # Set derived variables.
-               self.wavelength = self.pitchRadius * 2.0 * math.pi / float(self.teethPinion)
-               self.clearance = self.wavelength * self.clearanceOverWavelength
-               self.clearance = evaluate.getEvaluatedFloat(self.clearance, elementNode, 'clearance')
-               self.complementCollarLength = self.faceWidth * self.complementCollarLengthOverFaceWidth
-               self.complementCollarLength = evaluate.getEvaluatedFloat(self.complementCollarLength, elementNode, 'complementCollarLength')
-               self.gearHolePaths = evaluate.getTransformedPathsByKey([], elementNode, 'gearHolePaths')
-               self.pinionCollarLength = self.faceWidth * self.pinionCollarLengthOverFaceWidth
-               self.pinionCollarLength = evaluate.getEvaluatedFloat(self.pinionCollarLength, elementNode, 'pinionCollarLength')
-               self.plateLength = self.faceWidth * self.plateLengthOverFaceWidth
-               self.plateLength = evaluate.getEvaluatedFloat(self.plateLength, elementNode, 'plateLength')
-               self.plateClearance = self.plateLength * self.plateClearanceOverLength
-               self.plateClearance = evaluate.getEvaluatedFloat(self.plateClearance, elementNode, 'plateClearance')
-               self.rackLength = self.pitchRadius * self.rackLengthOverRadius
-               self.rackLength = evaluate.getEvaluatedFloat(self.rackLength, elementNode, 'rackLength')
-               self.rackDemilength = 0.5 * self.rackLength
-               self.rackWidth = self.faceWidth * self.rackWidthOverFaceWidth
-               self.rackWidth = evaluate.getEvaluatedFloat(self.rackWidth, elementNode, 'rackWidth')
-               self.rimDedendum = self.pitchRadius * self.rimDedendumOverRadius
-               self.rimDedendum = evaluate.getEvaluatedFloat(self.rimDedendum, elementNode, 'rimDedendum')
-               self.rootBevel = self.clearance * self.rootBevelOverClearance
-               self.rootBevel = evaluate.getEvaluatedFloat(self.rootBevel, elementNode, 'rootBevel')
-               self.shaftRadius = self.pitchRadius * self.shaftRadiusOverPitchRadius
-               self.shaftRadius = evaluate.getEvaluatedFloat(self.shaftRadius, elementNode, 'shaftRadius')
-               self.collarAddendum = self.shaftRadius * self.collarAddendumOverRadius
-               self.collarAddendum = evaluate.getEvaluatedFloat(self.collarAddendum, elementNode, 'collarWidth')
-               self.keywayRadius = self.shaftRadius * self.keywayRadiusOverRadius
-               self.keywayRadius = lineation.getFloatByPrefixBeginEnd(elementNode, 'keywayRadius', 'keywayDiameter', self.keywayRadius)
-               self.lighteningHoleMargin = self.rimDedendum * self.lighteningHoleMarginOverRimDedendum
-               self.lighteningHoleMargin = evaluate.getEvaluatedFloat(
-                       self.lighteningHoleMargin, elementNode, 'lighteningHoleMargin')
-               self.rackHoleBelow = self.rackWidth * self.rackHoleBelowOverWidth
-               self.rackHoleBelow = evaluate.getEvaluatedFloat(self.rackHoleBelow, elementNode, 'rackHoleBelow')
-               self.rackHoleRadius = self.rackWidth * self.rackHoleRadiusOverWidth
-               self.rackHoleRadius = lineation.getFloatByPrefixBeginEnd(elementNode, 'rackHoleRadius', 'rackHoleDiameter', self.rackHoleRadius)
-               self.rackHoleStep = self.rackWidth * self.rackHoleStepOverWidth
-               self.rackHoleStep = evaluate.getEvaluatedFloat(self.rackHoleStep, elementNode, 'rackHoleStep')
-               self.shaftDepthBottom = self.shaftRadius * self.shaftDepthBottomOverRadius
-               self.shaftDepthBottom = evaluate.getEvaluatedFloat(self.shaftDepthBottom, elementNode, 'shaftDepthBottom')
-               self.shaftDepthTop = self.shaftRadius * self.shaftDepthTopOverRadius
-               self.shaftDepthTop = evaluate.getEvaluatedFloat(self.shaftDepthTop, elementNode, 'shaftDepthTop')
-               self.shaftPath = evaluate.getTransformedPathByKey([], elementNode, 'shaftPath')
-               if len(self.shaftPath) < 3:
-                       self.shaftPath = shaft.getShaftPath(self.shaftDepthBottom, self.shaftDepthTop, self.shaftRadius, -self.shaftSides)
-               self.tipBevel = self.clearance * self.tipBevelOverClearance
-               self.tipBevel = evaluate.getEvaluatedFloat(self.tipBevel, elementNode, 'tipBevel')
-               # Set derived values.
-               self.helixRadian = math.radians(self.helixAngle)
-               if self.teethComplement <= 0.0 and self.operatingAngle != 180.0:
-                       print('Warning, an operatingAngle other than 180 degrees can only work with a positive number of gear teeth.')
-                       print('Therefore the operatingAngle will be reset to 180 degrees.')
-                       self.operatingAngle = 180.0
-               self.tanHelix = math.tan(self.helixRadian)
-               self.helixHeight = self.tanHelix * self.faceWidth
-               self.operatingRadian = math.radians(self.operatingAngle)
-               self.pitchRadiusComplement = self.pitchRadius * float(self.teethComplement) / float(self.teethPinion)
-               self.pressureRadian = math.radians(self.pressureAngle)
-               self.cosPressure = math.cos(self.pressureRadian)
-               self.sinPressure = math.sin(self.pressureRadian)
-               self.tanPressure = math.tan(self.pressureRadian)
-               self.halfWavelength = 0.5 * self.wavelength
-               self.helixPath = euclidean.getComplexPath(evaluate.getTransformedPathByKey([], elementNode, 'helixPath'))
-               if len(self.helixPath) < 1:
-                       self.helixPath = getHelixComplexPath(self, elementNode)
-               self.quarterWavelength = 0.25 * self.wavelength
-               self.shaftRimRadius = self.shaftRadius + self.collarAddendum
-               self.toothProfileHalf = getToothProfileHalfCylinder(self, self.pitchRadius)
-               self.toothProfileHalf = getThicknessMultipliedPath(self.toothProfileHalf, self.toothThicknessMultiplier)
-               self.addendum = self.toothProfileHalf[-1].imag - self.pitchRadius
-               self.dedendum = abs(self.toothProfileHalf[-1]) - self.pitchRadius + self.clearance
-               self.pinionToothProfile = getToothProfileCylinderByProfile(self, self.pitchRadius, self.teethPinion, self.toothProfileHalf)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/grid.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/grid.py
deleted file mode 100644 (file)
index a396b17..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-"""
-Grid path points.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_tools import path
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities import euclidean
-import math
-import random
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addGridRow(diameter, gridPath, loopsComplex, maximumComplex, rowIndex, x, y, zigzag):
-       'Add grid row.'
-       row = []
-       while x < maximumComplex.real:
-               point = complex(x, y)
-               if euclidean.getIsInFilledRegion(loopsComplex, point):
-                       row.append(point)
-               x += diameter.real
-       if zigzag and rowIndex % 2 == 1:
-               row.reverse()
-       gridPath += row
-
-def getGeometryOutput(elementNode):
-       'Get vector3 vertexes from attribute dictionary.'
-       derivation = GridDerivation(elementNode)
-       diameter = derivation.radius + derivation.radius
-       typeStringTwoCharacters = derivation.typeString.lower()[: 2]
-       typeStringFirstCharacter = typeStringTwoCharacters[: 1]
-       topRight = complex(derivation.demiwidth, derivation.demiheight)
-       loopsComplex = [euclidean.getSquareLoopWiddershins(-topRight, topRight)]
-       if len(derivation.target) > 0:
-               loopsComplex = euclidean.getComplexPaths(derivation.target)
-       maximumComplex = euclidean.getMaximumByComplexPaths(loopsComplex)
-       minimumComplex = euclidean.getMinimumByComplexPaths(loopsComplex)
-       gridPath = None
-       if typeStringTwoCharacters == 'he':
-               gridPath = getHexagonalGrid(diameter, loopsComplex, maximumComplex, minimumComplex, derivation.zigzag)
-       elif typeStringTwoCharacters == 'ra' or typeStringFirstCharacter == 'a':
-               gridPath = getRandomGrid(derivation, diameter, elementNode, loopsComplex, maximumComplex, minimumComplex)
-       elif typeStringTwoCharacters == 're' or typeStringFirstCharacter == 'e':
-               gridPath = getRectangularGrid(diameter, loopsComplex, maximumComplex, minimumComplex, derivation.zigzag)
-       if gridPath == None:
-               print('Warning, the step type was not one of (hexagonal, random or rectangular) in getGeometryOutput in grid for:')
-               print(derivation.typeString)
-               print(elementNode)
-               return []
-       loop = euclidean.getVector3Path(gridPath)
-       elementNode.attributes['closed'] = 'false'
-       return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(loop, 0.5 * math.pi))
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       'Get vector3 vertexes from attribute dictionary by arguments.'
-       if len(arguments) < 1:
-               return getGeometryOutput(elementNode)
-       inradius = 0.5 * euclidean.getFloatFromValue(arguments[0])
-       elementNode.attributes['inradius.x'] = str(inradius)
-       if len(arguments) > 1:
-               inradius = 0.5 * euclidean.getFloatFromValue(arguments[1])
-       elementNode.attributes['inradius.y'] = str(inradius)
-       return getGeometryOutput(elementNode)
-
-def getHexagonalGrid(diameter, loopsComplex, maximumComplex, minimumComplex, zigzag):
-       'Get hexagonal grid.'
-       diameter = complex(diameter.real, math.sqrt(0.75) * diameter.imag)
-       demiradius = 0.25 * diameter
-       xRadius = 0.5 * diameter.real
-       xStart = minimumComplex.real - demiradius.real
-       y = minimumComplex.imag - demiradius.imag
-       gridPath = []
-       rowIndex = 0
-       while y < maximumComplex.imag:
-               x = xStart
-               if rowIndex % 2 == 1:
-                       x -= xRadius
-               addGridRow(diameter, gridPath, loopsComplex, maximumComplex, rowIndex, x, y, zigzag)
-               y += diameter.imag
-               rowIndex += 1
-       return gridPath
-
-def getIsPointInsideZoneAwayOthers(diameterReciprocal, loopsComplex, point, pixelDictionary):
-       'Determine if the point is inside the loops zone and and away from the other points.'
-       if not euclidean.getIsInFilledRegion(loopsComplex, point):
-               return False
-       pointOverDiameter = complex(point.real * diameterReciprocal.real, point.imag * diameterReciprocal.imag)
-       squareValues = euclidean.getSquareValuesFromPoint(pixelDictionary, pointOverDiameter)
-       for squareValue in squareValues:
-               if abs(squareValue - pointOverDiameter) < 1.0:
-                       return False
-       euclidean.addElementToPixelListFromPoint(pointOverDiameter, pixelDictionary, pointOverDiameter)
-       return True
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return GridDerivation(elementNode)
-
-def getRandomGrid(derivation, diameter, elementNode, loopsComplex, maximumComplex, minimumComplex):
-       'Get rectangular grid.'
-       gridPath = []
-       diameterReciprocal = complex(1.0 / diameter.real, 1.0 / diameter.imag)
-       diameterSquared = diameter.real * diameter.real + diameter.imag * diameter.imag
-       elements = int(math.ceil(derivation.density * euclidean.getAreaLoops(loopsComplex) / diameterSquared / math.sqrt(0.75)))
-       elements = evaluate.getEvaluatedInt(elements, elementNode, 'elements')
-       failedPlacementAttempts = 0
-       pixelDictionary = {}
-       if derivation.seed != None:
-               random.seed(derivation.seed)
-       successfulPlacementAttempts = 0
-       while failedPlacementAttempts < 100:
-               point = euclidean.getRandomComplex(minimumComplex, maximumComplex)
-               if getIsPointInsideZoneAwayOthers(diameterReciprocal, loopsComplex, point, pixelDictionary):
-                       gridPath.append(point)
-                       euclidean.addElementToPixelListFromPoint(point, pixelDictionary, point)
-                       successfulPlacementAttempts += 1
-               else:
-                       failedPlacementAttempts += 1
-               if successfulPlacementAttempts >= elements:
-                       return gridPath
-       return gridPath
-
-def getRectangularGrid(diameter, loopsComplex, maximumComplex, minimumComplex, zigzag):
-       'Get rectangular grid.'
-       demiradius = 0.25 * diameter
-       xStart = minimumComplex.real - demiradius.real
-       y = minimumComplex.imag - demiradius.imag
-       gridPath = []
-       rowIndex = 0
-       while y < maximumComplex.imag:
-               addGridRow(diameter, gridPath, loopsComplex, maximumComplex, rowIndex, xStart, y, zigzag)
-               y += diameter.imag
-               rowIndex += 1
-       return gridPath
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       path.convertElementNode(elementNode, getGeometryOutput(elementNode))
-
-
-class GridDerivation(object):
-       'Class to hold grid variables.'
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.inradius = lineation.getInradius(complex(10.0, 10.0), elementNode)
-               self.demiwidth = lineation.getFloatByPrefixBeginEnd(elementNode, 'demiwidth', 'width', self.inradius.real)
-               self.demiheight = lineation.getFloatByPrefixBeginEnd(elementNode, 'demiheight', 'height', self.inradius.imag)
-               self.density = evaluate.getEvaluatedFloat(0.2, elementNode, 'density')
-               self.radius = lineation.getComplexByPrefixBeginEnd(elementNode, 'elementRadius', 'elementDiameter', complex(1.0, 1.0))
-               self.radius = lineation.getComplexByPrefixBeginEnd(elementNode, 'radius', 'diameter', self.radius)
-               self.seed = evaluate.getEvaluatedInt(None, elementNode, 'seed')
-               self.target = evaluate.getTransformedPathsByKey([], elementNode, 'target')
-               self.typeMenuRadioStrings = 'hexagonal random rectangular'.split()
-               self.typeString = evaluate.getEvaluatedString('rectangular', elementNode, 'type')
-               self.zigzag = evaluate.getEvaluatedBoolean(True, elementNode, 'zigzag')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/heightmap.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/heightmap.py
deleted file mode 100644 (file)
index a4a4ad0..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-"""
-Heightmap.
-http://www.cs.otago.ac.nz/graphics/Mirage/node59.html
-http://en.wikipedia.org/wiki/Heightmap
-http://en.wikipedia.org/wiki/Netpbm_format
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities.vector3index import Vector3Index
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addHeightsByBitmap(heights, textLines):
-       'Add heights by bitmap.'
-       for line in textLines[3:]:
-               for integerWord in line.split():
-                       heights.append(float(integerWord))
-
-def addHeightsByGraymap(heights, textLines):
-       'Add heights by graymap.'
-       divisor = float(textLines[3])
-       for line in textLines[4:]:
-               for integerWord in line.split():
-                       heights.append(float(integerWord) / divisor)
-
-def getAddIndexedHeightGrid(heightGrid, minimumXY, step, top, vertexes):
-       'Get and add an indexed heightGrid.'
-       indexedHeightGrid = []
-       for rowIndex, row in enumerate(heightGrid):
-               indexedRow = []
-               indexedHeightGrid.append(indexedRow)
-               rowOffset = step.imag * float(rowIndex) + minimumXY.imag
-               for columnIndex, element in enumerate(row):
-                       columnOffset = step.real * float(columnIndex) + minimumXY.real
-                       vector3index = Vector3Index(len(vertexes), columnOffset, rowOffset, top * element)
-                       indexedRow.append(vector3index)
-                       vertexes.append(vector3index)
-       return indexedHeightGrid
-
-def getAddIndexedSegmentedPerimeter(heightGrid, maximumXY, minimumXY, step, vertexes, z=0.0):
-       'Get and add an indexed segmented perimeter.'
-       indexedSegmentedPerimeter = []
-       firstRow = heightGrid[0]
-       columnOffset = minimumXY.real
-       numberOfRowsMinusTwo = len(heightGrid) - 2
-       for column in firstRow:
-               vector3index = Vector3Index(len(vertexes), columnOffset, minimumXY.imag, z)
-               vertexes.append(vector3index)
-               indexedSegmentedPerimeter.append(vector3index)
-               columnOffset += step.real
-       rowOffset = minimumXY.imag
-       for rowIndex in xrange(numberOfRowsMinusTwo):
-               rowOffset += step.imag
-               vector3index = Vector3Index(len(vertexes), maximumXY.real, rowOffset, z)
-               vertexes.append(vector3index)
-               indexedSegmentedPerimeter.append(vector3index)
-       columnOffset = maximumXY.real
-       for column in firstRow:
-               vector3index = Vector3Index(len(vertexes), columnOffset, maximumXY.imag, z)
-               vertexes.append(vector3index)
-               indexedSegmentedPerimeter.append(vector3index)
-               columnOffset -= step.real
-       rowOffset = maximumXY.imag
-       for rowIndex in xrange(numberOfRowsMinusTwo):
-               rowOffset -= step.imag
-               vector3index = Vector3Index(len(vertexes), minimumXY.real, rowOffset, z)
-               vertexes.append(vector3index)
-               indexedSegmentedPerimeter.append(vector3index)
-       return indexedSegmentedPerimeter
-
-def getGeometryOutput(elementNode):
-       'Get vector3 vertexes from attribute dictionary.'
-       derivation = HeightmapDerivation(elementNode)
-       heightGrid = derivation.heightGrid
-       if derivation.fileName != '':
-               heightGrid = getHeightGrid(archive.getAbsoluteFolderPath(elementNode.getOwnerDocument().fileName, derivation.fileName))
-       return getGeometryOutputByHeightGrid(derivation, elementNode, heightGrid)
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       'Get vector3 vertexes from attribute dictionary by arguments.'
-       evaluate.setAttributesByArguments(['file', 'start'], arguments, elementNode)
-       return getGeometryOutput(elementNode)
-
-def getGeometryOutputByHeightGrid(derivation, elementNode, heightGrid):
-       'Get vector3 vertexes from attribute dictionary.'
-       numberOfColumns = len(heightGrid)
-       if numberOfColumns < 2:
-               print('Warning, in getGeometryOutputByHeightGrid in heightmap there are fewer than two rows for:')
-               print(heightGrid)
-               print(elementNode)
-               return None
-       numberOfRows = len(heightGrid[0])
-       if numberOfRows < 2:
-               print('Warning, in getGeometryOutputByHeightGrid in heightmap there are fewer than two columns for:')
-               print(heightGrid)
-               print(elementNode)
-               return None
-       for row in heightGrid:
-               if len(row) != numberOfRows:
-                       print('Warning, in getGeometryOutputByHeightGrid in heightmap the heightgrid is not rectangular for:')
-                       print(heightGrid)
-                       print(elementNode)
-                       return None
-       inradiusComplex = derivation.inradius.dropAxis()
-       minimumXY = -inradiusComplex
-       step = complex(derivation.inradius.x / float(numberOfRows - 1), derivation.inradius.y / float(numberOfColumns - 1))
-       step += step
-       faces = []
-       heightGrid = getRaisedHeightGrid(heightGrid, derivation.start)
-       top = derivation.inradius.z + derivation.inradius.z
-       vertexes = []
-       indexedBottomLoop = getAddIndexedSegmentedPerimeter(heightGrid, inradiusComplex, minimumXY, step, vertexes)
-       indexedLoops = [indexedBottomLoop]
-       indexedGridTop = getAddIndexedHeightGrid(heightGrid, minimumXY, step, top, vertexes)
-       indexedLoops.append(triangle_mesh.getIndexedLoopFromIndexedGrid(indexedGridTop))
-       vertexes = triangle_mesh.getUniqueVertexes(indexedLoops + indexedGridTop)
-       triangle_mesh.addPillarFromConvexLoopsGridTop(faces, indexedGridTop, indexedLoops)
-       return triangle_mesh.getGeometryOutputByFacesVertexes(faces, vertexes)
-
-def getHeightGrid(fileName):
-       'Get heightGrid by fileName.'
-       if 'models/' not in fileName:
-               print('Warning, models/ was not in the absolute file path, so for security nothing will be done for:')
-               print(fileName)
-               print('The heightmap tool can only read a file which has models/ in the file path.')
-               print('To import the file, move the file into a folder called model/ or a subfolder which is inside the model folder tree.')
-               return
-       pgmText = archive.getFileText(fileName)
-       textLines = archive.getTextLines(pgmText)
-       format = textLines[0].lower()
-       sizeWords = textLines[2].split()
-       numberOfColumns = int(sizeWords[0])
-       numberOfRows = int(sizeWords[1])
-       heights = []
-       if format == 'p1':
-               addHeightsByBitmap(heights, textLines)
-       elif format == 'p2':
-               addHeightsByGraymap(heights, textLines)
-       else:
-               print('Warning, the file format was not recognized for:')
-               print(fileName)
-               print('Heightmap can only read the Netpbm Portable bitmap format and the Netpbm Portable graymap format.')
-               print('The Netpbm formats are described at:')
-               print('http://en.wikipedia.org/wiki/Netpbm_format')
-               return []
-       heightGrid = []
-       heightIndex = 0
-       for rowIndex in xrange(numberOfRows):
-               row = []
-               heightGrid.append(row)
-               for columnIndex in xrange(numberOfColumns):
-                       row.append(heights[heightIndex])
-                       heightIndex += 1
-       return heightGrid
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return HeightmapDerivation(elementNode)
-
-def getRaisedHeightGrid(heightGrid, start):
-       'Get heightGrid raised above start.'
-       raisedHeightGrid = []
-       remainingHeight = 1.0 - start
-       for row in heightGrid:
-               raisedRow = []
-               raisedHeightGrid.append(raisedRow)
-               for element in row:
-                       raisedElement = remainingHeight * element + start
-                       raisedRow.append(raisedElement)
-       return raisedHeightGrid
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       solid.processElementNodeByGeometry(elementNode, getGeometryOutput(elementNode))
-
-
-class HeightmapDerivation(object):
-       'Class to hold heightmap variables.'
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.fileName = evaluate.getEvaluatedString('', elementNode, 'file')
-               self.heightGrid = evaluate.getEvaluatedValue([], elementNode, 'heightGrid')
-               self.inradius = evaluate.getVector3ByPrefixes(elementNode, ['demisize', 'inradius'], Vector3(10.0, 10.0, 5.0))
-               self.inradius = evaluate.getVector3ByMultiplierPrefix(elementNode, 2.0, 'size', self.inradius)
-               self.start = evaluate.getEvaluatedFloat(0.0, elementNode, 'start')
-
-       def __repr__(self):
-               'Get the string representation of this HeightmapDerivation.'
-               return euclidean.getDictionaryString(self.__dict__)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/lathe.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/lathe.py
deleted file mode 100644 (file)
index 04c14c3..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-"""
-Boolean geometry extrusion.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-def addLoopByComplex(derivation, endMultiplier, loopLists, path, pointComplex, vertexes):
-       "Add an indexed loop to the vertexes."
-       loops = loopLists[-1]
-       loop = []
-       loops.append(loop)
-       for point in path:
-               pointMinusBegin = point - derivation.axisStart
-               dotVector3 = derivation.axisProjectiveSpace.getDotVector3(pointMinusBegin)
-               dotVector3Complex = dotVector3.dropAxis()
-               dotPointComplex = pointComplex * dotVector3Complex
-               dotPoint = Vector3(dotPointComplex.real, dotPointComplex.imag, dotVector3.z)
-               projectedVector3 = derivation.axisProjectiveSpace.getVector3ByPoint(dotPoint) + derivation.axisStart
-               loop.append(projectedVector3)
-
-def addNegatives(derivation, negatives, paths):
-       "Add pillars output to negatives."
-       for path in paths:
-               loopListsByPath = getLoopListsByPath(derivation, 1.000001, path)
-               geometryOutput = triangle_mesh.getPillarsOutput(loopListsByPath)
-               negatives.append(geometryOutput)
-
-def addNegativesPositives(derivation, negatives, paths, positives):
-       "Add pillars output to negatives and positives."
-       for path in paths:
-               endMultiplier = None
-               normal = euclidean.getNormalByPath(path)
-               if normal.dot(derivation.normal) < 0.0:
-                       endMultiplier = 1.000001
-               loopListsByPath = getLoopListsByPath(derivation, endMultiplier, path)
-               geometryOutput = triangle_mesh.getPillarsOutput(loopListsByPath)
-               if endMultiplier == None:
-                       positives.append(geometryOutput)
-               else:
-                       negatives.append(geometryOutput)
-
-def addOffsetAddToLists( loop, offset, vector3Index, vertexes ):
-       "Add an indexed loop to the vertexes."
-       vector3Index += offset
-       loop.append( vector3Index )
-       vertexes.append( vector3Index )
-
-def addPositives(derivation, paths, positives):
-       "Add pillars output to positives."
-       for path in paths:
-               loopListsByPath = getLoopListsByPath(derivation, None, path)
-               geometryOutput = triangle_mesh.getPillarsOutput(loopListsByPath)
-               positives.append(geometryOutput)
-
-def getGeometryOutput(derivation, elementNode):
-       "Get triangle mesh from attribute dictionary."
-       if derivation == None:
-               derivation = LatheDerivation(elementNode)
-       if len(euclidean.getConcatenatedList(derivation.target)) == 0:
-               print('Warning, in lathe there are no paths.')
-               print(elementNode.attributes)
-               return None
-       negatives = []
-       positives = []
-       addNegativesPositives(derivation, negatives, derivation.target, positives)
-       return getGeometryOutputByNegativesPositives(derivation, elementNode, negatives, positives)
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       "Get triangle mesh from attribute dictionary by arguments."
-       return getGeometryOutput(None, elementNode)
-
-def getGeometryOutputByNegativesPositives(derivation, elementNode, negatives, positives):
-       "Get triangle mesh from derivation, elementNode, negatives and positives."
-       positiveOutput = triangle_mesh.getUnifiedOutput(positives)
-       if len(negatives) < 1:
-               return solid.getGeometryOutputByManipulation(elementNode, positiveOutput)
-       return solid.getGeometryOutputByManipulation(elementNode, {'difference' : {'shapes' : [positiveOutput] + negatives}})
-
-def getLoopListsByPath(derivation, endMultiplier, path):
-       "Get loop lists from path."
-       vertexes = []
-       loopLists = [[]]
-       if len(derivation.loop) < 2:
-               return loopLists
-       for pointIndex, pointComplex in enumerate(derivation.loop):
-               if endMultiplier != None and not derivation.isEndCloseToStart:
-                       if pointIndex == 0:
-                               nextPoint = derivation.loop[1]
-                               pointComplex = endMultiplier * (pointComplex - nextPoint) + nextPoint
-                       elif pointIndex == len(derivation.loop) - 1:
-                               previousPoint = derivation.loop[pointIndex - 1]
-                               pointComplex = endMultiplier * (pointComplex - previousPoint) + previousPoint
-               addLoopByComplex(derivation, endMultiplier, loopLists, path, pointComplex, vertexes)
-       if derivation.isEndCloseToStart:
-               loopLists[-1].append([])
-       return loopLists
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return LatheDerivation(elementNode)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       solid.processElementNodeByGeometry(elementNode, getGeometryOutput(None, elementNode))
-
-
-class LatheDerivation(object):
-       "Class to hold lathe variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.axisEnd = evaluate.getVector3ByPrefix(None, elementNode, 'axisEnd')
-               self.axisStart = evaluate.getVector3ByPrefix(None, elementNode, 'axisStart')
-               self.end = evaluate.getEvaluatedFloat(360.0, elementNode, 'end')
-               self.loop = evaluate.getTransformedPathByKey([], elementNode, 'loop')
-               self.sides = evaluate.getEvaluatedInt(None, elementNode, 'sides')
-               self.start = evaluate.getEvaluatedFloat(0.0, elementNode, 'start')
-               self.target = evaluate.getTransformedPathsByKey([], elementNode, 'target')
-               if len(self.target) < 1:
-                       print('Warning, no target in derive in lathe for:')
-                       print(elementNode)
-                       return
-               firstPath = self.target[0]
-               if len(firstPath) < 3:
-                       print('Warning, firstPath length is less than three in derive in lathe for:')
-                       print(elementNode)
-                       self.target = []
-                       return
-               if self.axisStart == None:
-                       if self.axisEnd == None:
-                               self.axisStart = firstPath[0]
-                               self.axisEnd = firstPath[-1]
-                       else:
-                               self.axisStart = Vector3()
-               self.axis = self.axisEnd - self.axisStart
-               axisLength = abs(self.axis)
-               if axisLength <= 0.0:
-                       print('Warning, axisLength is zero in derive in lathe for:')
-                       print(elementNode)
-                       self.target = []
-                       return
-               self.axis /= axisLength
-               firstVector3 = firstPath[1] - self.axisStart
-               firstVector3Length = abs(firstVector3)
-               if firstVector3Length <= 0.0:
-                       print('Warning, firstVector3Length is zero in derive in lathe for:')
-                       print(elementNode)
-                       self.target = []
-                       return
-               firstVector3 /= firstVector3Length
-               self.axisProjectiveSpace = euclidean.ProjectiveSpace().getByBasisZFirst(self.axis, firstVector3)
-               if self.sides == None:
-                       distanceToLine = euclidean.getDistanceToLineByPaths(self.axisStart, self.axisEnd, self.target)
-                       self.sides = evaluate.getSidesMinimumThreeBasedOnPrecisionSides(elementNode, distanceToLine)
-               endRadian = math.radians(self.end)
-               startRadian = math.radians(self.start)
-               self.isEndCloseToStart = euclidean.getIsRadianClose(endRadian, startRadian)
-               if len(self.loop) < 1:
-                       self.loop = euclidean.getComplexPolygonByStartEnd(endRadian, 1.0, self.sides, startRadian)
-               self.normal = euclidean.getNormalByPath(firstPath)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/line.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/line.py
deleted file mode 100644 (file)
index e3753d8..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-"""
-Square path.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_tools import path
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.vector3 import Vector3
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getGeometryOutput(derivation, elementNode):
-       "Get vector3 vertexes from attribute dictionary."
-       if derivation == None:
-               derivation = LineDerivation(elementNode)
-       endMinusStart = derivation.end - derivation.start
-       endMinusStartLength = abs(endMinusStart)
-       if endMinusStartLength <= 0.0:
-               print('Warning, end is the same as start in getGeometryOutput in line for:')
-               print(derivation.start)
-               print(derivation.end)
-               print(elementNode)
-               return None
-       typeStringTwoCharacters = derivation.typeString.lower()[: 2]
-       elementNode.attributes['closed'] = str(derivation.closed)
-       if derivation.step == None and derivation.steps == None:
-               return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop([derivation.start, derivation.end]))
-       loop = [derivation.start]
-       if derivation.step != None and derivation.steps != None:
-               stepVector = derivation.step / endMinusStartLength * endMinusStart
-               derivation.end = derivation.start + stepVector * derivation.steps
-               return getGeometryOutputByStep(elementNode, derivation.end, loop, derivation.steps, stepVector)
-       if derivation.step == None:
-               stepVector = endMinusStart / derivation.steps
-               return getGeometryOutputByStep(elementNode, derivation.end, loop, derivation.steps, stepVector)
-       endMinusStartLengthOverStep = endMinusStartLength / derivation.step
-       if typeStringTwoCharacters == 'av':
-               derivation.steps = max(1.0, round(endMinusStartLengthOverStep))
-               stepVector = derivation.step / endMinusStartLength * endMinusStart
-               derivation.end = derivation.start + stepVector * derivation.steps
-               return getGeometryOutputByStep(elementNode, derivation.end, loop, derivation.steps, stepVector)
-       if typeStringTwoCharacters == 'ma':
-               derivation.steps = math.ceil(endMinusStartLengthOverStep)
-               if derivation.steps < 1.0:
-                       return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop([derivation.start, derivation.end]))
-               stepVector = endMinusStart / derivation.steps
-               return getGeometryOutputByStep(elementNode, derivation.end, loop, derivation.steps, stepVector)
-       if typeStringTwoCharacters == 'mi':
-               derivation.steps = math.floor(endMinusStartLengthOverStep)
-               if derivation.steps < 1.0:
-                       return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(loop))
-               stepVector = endMinusStart / derivation.steps
-               return getGeometryOutputByStep(elementNode, derivation.end, loop, derivation.steps, stepVector)
-       print('Warning, the step type was not one of (average, maximum or minimum) in getGeometryOutput in line for:')
-       print(derivation.typeString)
-       print(elementNode)
-       loop.append(derivation.end)
-       return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(loop))
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       "Get vector3 vertexes from attribute dictionary by arguments."
-       evaluate.setAttributesByArguments(['start', 'end', 'step'], arguments, elementNode)
-       return getGeometryOutput(None, elementNode)
-
-def getGeometryOutputByStep(elementNode, end, loop, steps, stepVector):
-       "Get line geometry output by the end, loop, steps and stepVector."
-       stepsFloor = int(math.floor(abs(steps)))
-       for stepIndex in xrange(1, stepsFloor):
-               loop.append(loop[stepIndex - 1] + stepVector)
-       loop.append(end)
-       return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(loop))
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return LineDerivation(elementNode)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       path.convertElementNode(elementNode, getGeometryOutput(None, elementNode))
-
-
-class LineDerivation(object):
-       "Class to hold line variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.closed = evaluate.getEvaluatedBoolean(False, elementNode, 'closed')
-               self.end = evaluate.getVector3ByPrefix(Vector3(), elementNode, 'end')
-               self.start = evaluate.getVector3ByPrefix(Vector3(), elementNode, 'start')
-               self.step = evaluate.getEvaluatedFloat(None, elementNode, 'step')
-               self.steps = evaluate.getEvaluatedFloat(None, elementNode, 'steps')
-               self.typeMenuRadioStrings = 'average maximum minimum'.split()
-               self.typeString = evaluate.getEvaluatedString('minimum', elementNode, 'type')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/linear_bearing_cage.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/linear_bearing_cage.py
deleted file mode 100644 (file)
index 07f5e68..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-"""
-Linear bearing cage.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import extrude
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.creation import peg
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities.geometry.manipulation_matrix import translate
-from fabmetheus_utilities.geometry.solids import cylinder
-from fabmetheus_utilities.geometry.solids import sphere
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addAssemblyCage(derivation, negatives, positives):
-       'Add assembly linear bearing cage.'
-       addCageGroove(derivation, negatives, positives)
-       for pegCenterX in derivation.pegCenterXs:
-               addPositivePeg(derivation, positives, pegCenterX, -derivation.pegY)
-               addPositivePeg(derivation, positives, pegCenterX, derivation.pegY)
-       translate.translateNegativesPositives(negatives, positives, Vector3(0.0, -derivation.halfSeparationWidth))
-       femaleNegatives = []
-       femalePositives = []
-       addCageGroove(derivation, femaleNegatives, femalePositives)
-       for pegCenterX in derivation.pegCenterXs:
-               addNegativePeg(derivation, femaleNegatives, pegCenterX, -derivation.pegY)
-               addNegativePeg(derivation, femaleNegatives, pegCenterX, derivation.pegY)
-       translate.translateNegativesPositives(femaleNegatives, femalePositives, Vector3(0.0, derivation.halfSeparationWidth))
-       negatives += femaleNegatives
-       positives += femalePositives
-
-def addCage(derivation, height, negatives, positives):
-       'Add linear bearing cage.'
-       copyShallow = derivation.elementNode.getCopyShallow()
-       copyShallow.attributes['path'] = [Vector3(), Vector3(0.0, 0.0, height)]
-       extrudeDerivation = extrude.ExtrudeDerivation(copyShallow)
-       roundedExtendedRectangle = getRoundedExtendedRectangle(derivation.demiwidth, derivation.rectangleCenterX, 14)
-       outsidePath = euclidean.getVector3Path(roundedExtendedRectangle)
-       extrude.addPositives(extrudeDerivation, [outsidePath], positives)
-       for bearingCenterX in derivation.bearingCenterXs:
-               addNegativeSphere(derivation, negatives, bearingCenterX)
-
-def addCageGroove(derivation, negatives, positives):
-       'Add cage and groove.'
-       addCage(derivation, derivation.demiheight, negatives, positives)
-       addGroove(derivation, negatives)
-
-def addGroove(derivation, negatives):
-       'Add groove on each side of cage.'
-       copyShallow = derivation.elementNode.getCopyShallow()
-       extrude.setElementNodeToEndStart(copyShallow, Vector3(-derivation.demilength), Vector3(derivation.demilength))
-       extrudeDerivation = extrude.ExtrudeDerivation(copyShallow)
-       bottom = derivation.demiheight - 0.5 * derivation.grooveWidth
-       outside = derivation.demiwidth
-       top = derivation.demiheight
-       leftGroove = [
-               complex(-outside, bottom),
-               complex(-derivation.innerDemiwidth, derivation.demiheight),
-               complex(-outside, top)]
-       rightGroove = [
-               complex(outside, top),
-               complex(derivation.innerDemiwidth, derivation.demiheight),
-               complex(outside, bottom)]
-       extrude.addNegatives(extrudeDerivation, negatives, euclidean.getVector3Paths([leftGroove, rightGroove]))
-
-def addNegativePeg(derivation, negatives, x, y):
-       'Add negative cylinder at x and y.'
-       negativePegRadius = derivation.pegRadiusArealized + derivation.halfPegClearance
-       inradius = complex(negativePegRadius, negativePegRadius)
-       copyShallow = derivation.elementNode.getCopyShallow()
-       start = Vector3(x, y, derivation.height)
-       sides = evaluate.getSidesMinimumThreeBasedOnPrecision(copyShallow, negativePegRadius)
-       cylinder.addCylinderOutputByEndStart(0.0, inradius, negatives, sides, start, derivation.topOverBottom)
-
-def addNegativeSphere(derivation, negatives, x):
-       'Add negative sphere at x.'
-       radius = Vector3(derivation.radiusPlusClearance, derivation.radiusPlusClearance, derivation.radiusPlusClearance)
-       sphereOutput = sphere.getGeometryOutput(derivation.elementNode.getCopyShallow(), radius)
-       euclidean.translateVector3Path(matrix.getVertexes(sphereOutput), Vector3(x, 0.0, derivation.demiheight))
-       negatives.append(sphereOutput)
-
-def addPositivePeg(derivation, positives, x, y):
-       'Add positive cylinder at x and y.'
-       positivePegRadius = derivation.pegRadiusArealized - derivation.halfPegClearance
-       radiusArealized = complex(positivePegRadius, positivePegRadius)
-       copyShallow = derivation.elementNode.getCopyShallow()
-       start = Vector3(x, y, derivation.demiheight)
-       endZ = derivation.height
-       peg.addPegOutput(derivation.pegBevel, endZ, positives, radiusArealized, derivation.sides, start, derivation.topOverBottom)
-
-def getBearingCenterXs(bearingCenterX, numberOfSteps, stepX):
-       'Get the bearing center x list.'
-       bearingCenterXs = []
-       for stepIndex in xrange(numberOfSteps + 1):
-               bearingCenterXs.append(bearingCenterX)
-               bearingCenterX += stepX
-       return bearingCenterXs
-
-def getGeometryOutput(elementNode):
-       'Get vector3 vertexes from attribute dictionary.'
-       derivation = LinearBearingCageDerivation(elementNode)
-       negatives = []
-       positives = []
-       if derivation.typeStringFirstCharacter == 'a':
-               addAssemblyCage(derivation, negatives, positives)
-       else:
-               addCage(derivation, derivation.height, negatives, positives)
-       return extrude.getGeometryOutputByNegativesPositives(elementNode, negatives, positives)
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       'Get vector3 vertexes from attribute dictionary by arguments.'
-       evaluate.setAttributesByArguments(['length', 'radius'], arguments, elementNode)
-       return getGeometryOutput(elementNode)
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return LinearBearingCageDerivation(elementNode)
-
-def getPegCenterXs(numberOfSteps, pegCenterX, stepX):
-       'Get the peg center x list.'
-       pegCenterXs = []
-       for stepIndex in xrange(numberOfSteps):
-               pegCenterXs.append(pegCenterX)
-               pegCenterX += stepX
-       return pegCenterXs
-
-def getRoundedExtendedRectangle(radius, rectangleCenterX, sides):
-       'Get the rounded extended rectangle.'
-       roundedExtendedRectangle = []
-       halfSides = int(sides / 2)
-       halfSidesPlusOne = abs(halfSides + 1)
-       sideAngle = math.pi / float(halfSides)
-       extensionMultiplier = 1.0 / math.cos(0.5 * sideAngle)
-       center = complex(rectangleCenterX, 0.0)
-       startAngle = 0.5 * math.pi
-       for halfSide in xrange(halfSidesPlusOne):
-               unitPolar = euclidean.getWiddershinsUnitPolar(startAngle)
-               unitPolarExtended = complex(unitPolar.real * extensionMultiplier, unitPolar.imag)
-               roundedExtendedRectangle.append(unitPolarExtended * radius + center)
-               startAngle += sideAngle
-       center = complex(-rectangleCenterX, 0.0)
-       startAngle = -0.5 * math.pi
-       for halfSide in xrange(halfSidesPlusOne):
-               unitPolar = euclidean.getWiddershinsUnitPolar(startAngle)
-               unitPolarExtended = complex(unitPolar.real * extensionMultiplier, unitPolar.imag)
-               roundedExtendedRectangle.append(unitPolarExtended * radius + center)
-               startAngle += sideAngle
-       return roundedExtendedRectangle
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       solid.processElementNodeByGeometry(elementNode, getGeometryOutput(elementNode))
-
-
-class LinearBearingCageDerivation(object):
-       'Class to hold linear bearing cage variables.'
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.length = evaluate.getEvaluatedFloat(50.0, elementNode, 'length')
-               self.demilength = 0.5 * self.length
-               self.elementNode = elementNode
-               self.radius = lineation.getFloatByPrefixBeginEnd(elementNode, 'radius', 'diameter', 5.0)
-               self.cageClearanceOverRadius = evaluate.getEvaluatedFloat(0.05, elementNode, 'cageClearanceOverRadius')
-               self.cageClearance = self.cageClearanceOverRadius * self.radius
-               self.cageClearance = evaluate.getEvaluatedFloat(self.cageClearance, elementNode, 'cageClearance')
-               self.racewayClearanceOverRadius = evaluate.getEvaluatedFloat(0.1, elementNode, 'racewayClearanceOverRadius')
-               self.racewayClearance = self.racewayClearanceOverRadius * self.radius
-               self.racewayClearance = evaluate.getEvaluatedFloat(self.racewayClearance, elementNode, 'racewayClearance')
-               self.typeMenuRadioStrings = 'assembly integral'.split()
-               self.typeString = evaluate.getEvaluatedString('assembly', elementNode, 'type')
-               self.typeStringFirstCharacter = self.typeString[: 1 ].lower()
-               self.wallThicknessOverRadius = evaluate.getEvaluatedFloat(0.5, elementNode, 'wallThicknessOverRadius')
-               self.wallThickness = self.wallThicknessOverRadius * self.radius
-               self.wallThickness = evaluate.getEvaluatedFloat(self.wallThickness, elementNode, 'wallThickness')
-               self.zenithAngle = evaluate.getEvaluatedFloat(45.0, elementNode, 'zenithAngle')
-               self.zenithRadian = math.radians(self.zenithAngle)
-               self.demiheight = self.radius * math.cos(self.zenithRadian) - self.racewayClearance
-               self.height = self.demiheight + self.demiheight
-               self.radiusPlusClearance = self.radius + self.cageClearance
-               self.cageRadius = self.radiusPlusClearance + self.wallThickness
-               self.demiwidth = self.cageRadius
-               self.bearingCenterX = self.cageRadius - self.demilength
-               separation = self.cageRadius + self.radiusPlusClearance
-               bearingLength = -self.bearingCenterX - self.bearingCenterX
-               self.numberOfSteps = int(math.floor(bearingLength / separation))
-               self.stepX = bearingLength / float(self.numberOfSteps)
-               self.bearingCenterXs = getBearingCenterXs(self.bearingCenterX, self.numberOfSteps, self.stepX)
-               if self.typeStringFirstCharacter == 'a':
-                       self.setAssemblyCage()
-               self.rectangleCenterX = self.demiwidth - self.demilength
-
-       def setAssemblyCage(self):
-               'Set two piece assembly parameters.'
-               self.grooveDepthOverRadius = evaluate.getEvaluatedFloat(0.15, self.elementNode, 'grooveDepthOverRadius')
-               self.grooveDepth = self.grooveDepthOverRadius * self.radius
-               self.grooveDepth = evaluate.getEvaluatedFloat(self.grooveDepth, self.elementNode, 'grooveDepth')
-               self.grooveWidthOverRadius = evaluate.getEvaluatedFloat(0.6, self.elementNode, 'grooveWidthOverRadius')
-               self.grooveWidth = self.grooveWidthOverRadius * self.radius
-               self.grooveWidth = evaluate.getEvaluatedFloat(self.grooveWidth, self.elementNode, 'grooveWidth')
-               self.pegClearanceOverRadius = evaluate.getEvaluatedFloat(0.0, self.elementNode, 'pegClearanceOverRadius')
-               self.pegClearance = self.pegClearanceOverRadius * self.radius
-               self.pegClearance = evaluate.getEvaluatedFloat(self.pegClearance, self.elementNode, 'pegClearance')
-               self.halfPegClearance = 0.5 * self.pegClearance
-               self.pegRadiusOverRadius = evaluate.getEvaluatedFloat(0.5, self.elementNode, 'pegRadiusOverRadius')
-               self.pegRadius = self.pegRadiusOverRadius * self.radius
-               self.pegRadius = evaluate.getEvaluatedFloat(self.pegRadius, self.elementNode, 'pegRadius')
-               self.sides = evaluate.getSidesMinimumThreeBasedOnPrecision(self.elementNode, self.pegRadius)
-               self.pegRadiusArealized = evaluate.getRadiusArealizedBasedOnAreaRadius(self.elementNode, self.pegRadius, self.sides)
-               self.pegBevelOverPegRadius = evaluate.getEvaluatedFloat(0.25, self.elementNode, 'pegBevelOverPegRadius')
-               self.pegBevel = self.pegBevelOverPegRadius * self.pegRadiusArealized
-               self.pegBevel = evaluate.getEvaluatedFloat(self.pegBevel, self.elementNode, 'pegBevel')
-               self.pegMaximumRadius = self.pegRadiusArealized + abs(self.halfPegClearance)
-               self.separationOverRadius = evaluate.getEvaluatedFloat(0.5, self.elementNode, 'separationOverRadius')
-               self.separation = self.separationOverRadius * self.radius
-               self.separation = evaluate.getEvaluatedFloat(self.separation, self.elementNode, 'separation')
-               self.topOverBottom = evaluate.getEvaluatedFloat(0.8, self.elementNode, 'topOverBottom')
-               peg.setTopOverBottomByRadius(self, 0.0, self.pegRadiusArealized, self.height)
-               self.quarterHeight = 0.5 * self.demiheight
-               self.pegY = 0.5 * self.wallThickness + self.pegMaximumRadius
-               cagePegRadius = self.cageRadius + self.pegMaximumRadius
-               halfStepX = 0.5 * self.stepX
-               pegHypotenuse = math.sqrt(self.pegY * self.pegY + halfStepX * halfStepX)
-               if cagePegRadius > pegHypotenuse:
-                       self.pegY = math.sqrt(cagePegRadius * cagePegRadius - halfStepX * halfStepX)
-               self.demiwidth = max(self.pegY + self.pegMaximumRadius + self.wallThickness, self.demiwidth)
-               self.innerDemiwidth = self.demiwidth
-               self.demiwidth += self.grooveDepth
-               self.halfSeparationWidth = self.demiwidth + 0.5 * self.separation
-               if self.pegRadiusArealized <= 0.0:
-                       self.pegCenterXs = []
-               else:
-                       self.pegCenterXs = getPegCenterXs(self.numberOfSteps, self.bearingCenterX + halfStepX, self.stepX)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/lineation.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/lineation.py
deleted file mode 100644 (file)
index 37780e0..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-"""
-Polygon path.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_tools import path
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getComplexByDictionary(dictionary, valueComplex):
-       'Get complex by dictionary.'
-       if 'x' in dictionary:
-               valueComplex = complex(euclidean.getFloatFromValue(dictionary['x']),valueComplex.imag)
-       if 'y' in dictionary:
-               valueComplex = complex(valueComplex.real, euclidean.getFloatFromValue(dictionary['y']))
-       return valueComplex
-
-def getComplexByDictionaryListValue(value, valueComplex):
-       'Get complex by dictionary, list or value.'
-       if value.__class__ == complex:
-               return value
-       if value.__class__ == dict:
-               return getComplexByDictionary(value, valueComplex)
-       if value.__class__ == list:
-               return getComplexByFloatList(value, valueComplex)
-       floatFromValue = euclidean.getFloatFromValue(value)
-       if floatFromValue ==  None:
-               return valueComplex
-       return complex( floatFromValue, floatFromValue )
-
-def getComplexByFloatList( floatList, valueComplex ):
-       'Get complex by float list.'
-       if len(floatList) > 0:
-               valueComplex = complex(euclidean.getFloatFromValue(floatList[0]), valueComplex.imag)
-       if len(floatList) > 1:
-               valueComplex = complex(valueComplex.real, euclidean.getFloatFromValue(floatList[1]))
-       return valueComplex
-
-def getComplexByMultiplierPrefix(elementNode, multiplier, prefix, valueComplex):
-       'Get complex from multiplier, prefix and xml element.'
-       if multiplier == 0.0:
-               return valueComplex
-       oldMultipliedValueComplex = valueComplex * multiplier
-       complexByPrefix = getComplexByPrefix(elementNode, prefix, oldMultipliedValueComplex)
-       if complexByPrefix == oldMultipliedValueComplex:
-               return valueComplex
-       return complexByPrefix / multiplier
-
-def getComplexByMultiplierPrefixes(elementNode, multiplier, prefixes, valueComplex):
-       'Get complex from multiplier, prefixes and xml element.'
-       for prefix in prefixes:
-               valueComplex = getComplexByMultiplierPrefix(elementNode, multiplier, prefix, valueComplex)
-       return valueComplex
-
-def getComplexByPrefix(elementNode, prefix, valueComplex):
-       'Get complex from prefix and xml element.'
-       value = evaluate.getEvaluatedValue(None, elementNode, prefix)
-       if value != None:
-               valueComplex = getComplexByDictionaryListValue(value, valueComplex)
-       x = evaluate.getEvaluatedFloat(None, elementNode, prefix + '.x')
-       if x != None:
-               valueComplex = complex( x, getComplexIfNone( valueComplex ).imag )
-       y = evaluate.getEvaluatedFloat(None, elementNode, prefix + '.y')
-       if y != None:
-               valueComplex = complex( getComplexIfNone( valueComplex ).real, y )
-       return valueComplex
-
-def getComplexByPrefixBeginEnd(elementNode, prefixBegin, prefixEnd, valueComplex):
-       'Get complex from element node, prefixBegin and prefixEnd.'
-       valueComplex = getComplexByPrefix(elementNode, prefixBegin, valueComplex)
-       if prefixEnd in elementNode.attributes:
-               return 0.5 * getComplexByPrefix(elementNode, valueComplex + valueComplex, prefixEnd)
-       else:
-               return valueComplex
-
-def getComplexByPrefixes(elementNode, prefixes, valueComplex):
-       'Get complex from prefixes and xml element.'
-       for prefix in prefixes:
-               valueComplex = getComplexByPrefix(elementNode, prefix, valueComplex)
-       return valueComplex
-
-def getComplexIfNone( valueComplex ):
-       'Get new complex if the original complex is none.'
-       if valueComplex == None:
-               return complex()
-       return valueComplex
-
-def getFloatByPrefixBeginEnd(elementNode, prefixBegin, prefixEnd, valueFloat):
-       'Get float from prefixBegin, prefixEnd and xml element.'
-       valueFloat = evaluate.getEvaluatedFloat(valueFloat, elementNode, prefixBegin)
-       if prefixEnd in elementNode.attributes:
-               return 0.5 * evaluate.getEvaluatedFloat(valueFloat + valueFloat, elementNode, prefixEnd)
-       return valueFloat
-
-def getFloatByPrefixSide(defaultValue, elementNode, prefix, side):
-       'Get float by prefix and side.'
-       if elementNode == None:
-               return defaultValue
-       if side != None:
-               key = prefix + 'OverSide'
-               if key in elementNode.attributes:
-                       defaultValue = euclidean.getFloatFromValue(evaluate.getEvaluatedValueObliviously(elementNode, key)) * side
-       return evaluate.getEvaluatedFloat(defaultValue, elementNode, prefix)
-
-def getGeometryOutput(derivation, elementNode):
-       'Get geometry output from paths.'
-       if derivation == None:
-               derivation = LineationDerivation(elementNode)
-       geometryOutput = []
-       for path in derivation.target:
-               sideLoop = SideLoop(path)
-               geometryOutput += getGeometryOutputByLoop(elementNode, sideLoop)
-       return geometryOutput
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       'Get vector3 vertexes from attribute dictionary by arguments.'
-       return getGeometryOutput(None, elementNode)
-
-def getGeometryOutputByLoop(elementNode, sideLoop):
-       'Get geometry output by side loop.'
-       sideLoop.rotate(elementNode)
-       return getGeometryOutputByManipulation(elementNode, sideLoop)
-
-def getGeometryOutputByManipulation(elementNode, sideLoop):
-       'Get geometry output by manipulation.'
-       sideLoop.loop = euclidean.getLoopWithoutCloseSequentialPoints( sideLoop.close, sideLoop.loop )
-       return sideLoop.getManipulationPluginLoops(elementNode)
-
-def getInradius(defaultInradius, elementNode):
-       'Get inradius.'
-       defaultInradius = getComplexByPrefixes(elementNode, ['demisize', 'inradius'], defaultInradius)
-       return getComplexByMultiplierPrefix(elementNode, 2.0, 'size', defaultInradius)
-
-def getMinimumRadius(beginComplexSegmentLength, endComplexSegmentLength, radius):
-       'Get minimum radius.'
-       return min(abs(radius), 0.5 * min(beginComplexSegmentLength, endComplexSegmentLength))
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return LineationDerivation(elementNode)
-
-def getNumberOfBezierPoints(begin, elementNode, end):
-       'Get the numberOfBezierPoints.'
-       numberOfBezierPoints = int(math.ceil(0.5 * evaluate.getSidesMinimumThreeBasedOnPrecision(elementNode, abs(end - begin))))
-       return evaluate.getEvaluatedInt(numberOfBezierPoints, elementNode, 'sides')
-
-def getPackedGeometryOutputByLoop(elementNode, sideLoop):
-       'Get packed geometry output by side loop.'
-       sideLoop.rotate(elementNode)
-       return getGeometryOutputByManipulation(elementNode, sideLoop)
-
-def getRadiusAverage(radiusComplex):
-       'Get average radius from radiusComplex.'
-       return math.sqrt(radiusComplex.real * radiusComplex.imag)
-
-def getRadiusComplex(elementNode, radius):
-       'Get radius complex for elementNode.'
-       radius = getComplexByPrefixes(elementNode, ['demisize', 'radius'], radius)
-       return getComplexByMultiplierPrefixes(elementNode, 2.0, ['diameter', 'size'], radius)
-
-def getStrokeRadiusByPrefix(elementNode, prefix):
-       'Get strokeRadius by prefix.'
-       strokeRadius = getFloatByPrefixBeginEnd(elementNode, prefix + 'strokeRadius', prefix + 'strokeWidth', 1.0)
-       return getFloatByPrefixBeginEnd(elementNode, prefix + 'radius', prefix + 'diameter', strokeRadius)
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       path.convertElementNode(elementNode, getGeometryOutput(None, elementNode))
-
-def processElementNodeByFunction(elementNode, manipulationFunction):
-       'Process the xml element by the manipulationFunction.'
-       elementAttributesCopy = elementNode.attributes.copy()
-       targets = evaluate.getElementNodesByKey(elementNode, 'target')
-       for target in targets:
-               targetAttributesCopy = target.attributes.copy()
-               target.attributes = elementAttributesCopy
-               processTargetByFunction(manipulationFunction, target)
-               target.attributes = targetAttributesCopy
-
-def processTargetByFunction(manipulationFunction, target):
-       'Process the target by the manipulationFunction.'
-       if target.xmlObject == None:
-               print('Warning, there is no object in processTargetByFunction in lineation for:')
-               print(target)
-               return
-       geometryOutput = []
-       transformedPaths = target.xmlObject.getTransformedPaths()
-       for transformedPath in transformedPaths:
-               sideLoop = SideLoop(transformedPath)
-               sideLoop.rotate(target)
-               sideLoop.loop = euclidean.getLoopWithoutCloseSequentialPoints( sideLoop.close, sideLoop.loop )
-               geometryOutput += manipulationFunction(sideLoop.close, target, sideLoop.loop, '', sideLoop.sideLength)
-       if len(geometryOutput) < 1:
-               print('Warning, there is no geometryOutput in processTargetByFunction in lineation for:')
-               print(target)
-               return
-       removeChildNodesFromElementObject(target)
-       path.convertElementNode(target, geometryOutput)
-
-def removeChildNodesFromElementObject(elementNode):
-       'Process the xml element by manipulationFunction.'
-       elementNode.removeChildNodesFromIDNameParent()
-       if elementNode.xmlObject != None:
-               if elementNode.parentNode.xmlObject != None:
-                       if elementNode.xmlObject in elementNode.parentNode.xmlObject.archivableObjects:
-                               elementNode.parentNode.xmlObject.archivableObjects.remove(elementNode.xmlObject)
-
-def setClosedAttribute(elementNode, revolutions):
-       'Set the closed attribute of the elementNode.'
-       closedBoolean = evaluate.getEvaluatedBoolean(revolutions <= 1, elementNode, 'closed')
-       elementNode.attributes['closed'] = str(closedBoolean).lower()
-
-
-class LineationDerivation(object):
-       'Class to hold lineation variables.'
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.target = evaluate.getTransformedPathsByKey([], elementNode, 'target')
-
-
-class SideLoop(object):
-       'Class to handle loop, side angle and side length.'
-       def __init__(self, loop, sideAngle=None, sideLength=None):
-               'Initialize.'
-               if sideAngle == None:
-                       if len(loop) > 0:
-                               sideAngle = 2.0 * math.pi / float(len(loop))
-                       else:
-                               sideAngle = 1.0
-                               print('Warning, loop has no sides in SideLoop in lineation.')
-               if sideLength == None:
-                       if len(loop) > 0:
-                               sideLength = euclidean.getLoopLength(loop) / float(len(loop))
-                       else:
-                               sideLength = 1.0
-                               print('Warning, loop has no length in SideLoop in lineation.')
-               self.loop = loop
-               self.sideAngle = abs(sideAngle)
-               self.sideLength = abs(sideLength)
-               self.close = 0.001 * sideLength
-
-       def getManipulationPluginLoops(self, elementNode):
-               'Get loop manipulated by the plugins in the manipulation paths folder.'
-               xmlProcessor = elementNode.getXMLProcessor()
-               matchingPlugins = evaluate.getMatchingPlugins(elementNode, xmlProcessor.manipulationMatrixDictionary)
-               matchingPlugins += evaluate.getMatchingPlugins(elementNode, xmlProcessor.manipulationPathDictionary)
-               matchingPlugins += evaluate.getMatchingPlugins(elementNode, xmlProcessor.manipulationShapeDictionary)
-               matchingPlugins.sort(evaluate.compareExecutionOrderAscending)
-               loops = [self.loop]
-               for matchingPlugin in matchingPlugins:
-                       matchingLoops = []
-                       prefix = matchingPlugin.__name__.replace('_', '') + '.'
-                       for loop in loops:
-                               matchingLoops += matchingPlugin.getManipulatedPaths(self.close, elementNode, loop, prefix, self.sideLength)
-                       loops = matchingLoops
-               return loops
-
-       def rotate(self, elementNode):
-               'Rotate.'
-               rotation = math.radians(evaluate.getEvaluatedFloat(0.0, elementNode, 'rotation'))
-               rotation += evaluate.getEvaluatedFloat(0.0, elementNode, 'rotationOverSide') * self.sideAngle
-               if rotation != 0.0:
-                       planeRotation = euclidean.getWiddershinsUnitPolar( rotation )
-                       for vertex in self.loop:
-                               rotatedComplex = vertex.dropAxis() * planeRotation
-                               vertex.x = rotatedComplex.real
-                               vertex.y = rotatedComplex.imag
-               if 'clockwise' in elementNode.attributes:
-                       isClockwise = euclidean.getBooleanFromValue(evaluate.getEvaluatedValueObliviously(elementNode, 'clockwise'))
-                       if isClockwise == euclidean.getIsWiddershinsByVector3( self.loop ):
-                               self.loop.reverse()
-
-
-class Spiral(object):
-       'Class to add a spiral.'
-       def __init__(self, spiral, stepRatio):
-               'Initialize.'
-               self.spiral = spiral
-               if self.spiral == None:
-                       return
-               self.spiralIncrement = self.spiral * stepRatio
-               self.spiralTotal = Vector3()
-
-       def __repr__(self):
-               'Get the string representation of this Spiral.'
-               return self.spiral
-
-       def getSpiralPoint(self, unitPolar, vector3):
-               'Add spiral to the vector.'
-               if self.spiral == None:
-                       return vector3
-               vector3 += Vector3(unitPolar.real * self.spiralTotal.x, unitPolar.imag * self.spiralTotal.y, self.spiralTotal.z)
-               self.spiralTotal += self.spiralIncrement
-               return vector3
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/mechaslab.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/mechaslab.py
deleted file mode 100644 (file)
index f9c3fdb..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-"""
-Mechaslab.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import extrude
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.creation import peg
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.solids import cylinder
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addAlongWay(begin, distance, end, loop):
-       'Get the beveled rectangle.'
-       endMinusBegin = end - begin
-       endMinusBeginLength = abs(endMinusBegin)
-       if endMinusBeginLength <= 0.0:
-               return
-       alongWayMultiplier = distance / endMinusBeginLength
-       loop.append(begin + alongWayMultiplier * endMinusBegin)
-
-def addGroove(derivation, negatives):
-       'Add groove on each side of cage.'
-       copyShallow = derivation.elementNode.getCopyShallow()
-       extrude.setElementNodeToEndStart(copyShallow, Vector3(-derivation.demilength), Vector3(derivation.demilength))
-       extrudeDerivation = extrude.ExtrudeDerivation(copyShallow)
-       bottom = derivation.demiheight - 0.5 * derivation.grooveWidth
-       outside = derivation.demiwidth
-       top = derivation.demiheight
-       leftGroove = [
-               complex(-outside, bottom),
-               complex(-derivation.innerDemiwidth, derivation.demiheight),
-               complex(-outside, top)]
-       rightGroove = [
-               complex(outside, top),
-               complex(derivation.innerDemiwidth, derivation.demiheight),
-               complex(outside, bottom)]
-       groovesComplex = [leftGroove, rightGroove]
-       groovesVector3 = euclidean.getVector3Paths(groovesComplex)
-       extrude.addPositives(extrudeDerivation, groovesVector3, negatives)
-
-def addHollowPegSocket(derivation, hollowPegSocket, negatives, positives):
-       'Add the socket and hollow peg.'
-       pegHeight = derivation.pegHeight
-       pegRadians = derivation.pegRadians
-       pegRadiusComplex = complex(derivation.pegRadiusArealized, derivation.pegRadiusArealized)
-       pegTip = 0.8 * derivation.pegRadiusArealized
-       sides = derivation.pegSides
-       start = Vector3(hollowPegSocket.center.real, hollowPegSocket.center.imag, derivation.height)
-       tinyHeight = 0.0001 * pegHeight
-       topRadians = 0.25 * math.pi
-       boltTop = derivation.height
-       if hollowPegSocket.shouldAddPeg:
-               boltTop = peg.getTopAddBiconicOutput(
-                       pegRadians, pegHeight, positives, pegRadiusComplex, sides, start, pegTip, topRadians)
-       sides = derivation.socketSides
-       socketHeight = 1.05 * derivation.pegHeight
-       socketRadiusComplex = complex(derivation.socketRadiusArealized, derivation.socketRadiusArealized)
-       socketTip = 0.5 * derivation.overhangSpan
-       start = Vector3(hollowPegSocket.center.real, hollowPegSocket.center.imag, -tinyHeight)
-       topRadians = derivation.interiorOverhangRadians
-       if hollowPegSocket.shouldAddSocket:
-               peg.getTopAddBiconicOutput(pegRadians, socketHeight, negatives, socketRadiusComplex, sides, start, socketTip, topRadians)
-       if derivation.boltRadius <= 0.0:
-               return
-       if (not hollowPegSocket.shouldAddPeg) and (not hollowPegSocket.shouldAddSocket):
-               return
-       boltRadiusComplex = complex(derivation.boltRadius, derivation.boltRadius)
-       cylinder.addCylinderOutputByEndStart(boltTop + tinyHeight, boltRadiusComplex, negatives, derivation.boltSides, start)
-
-def addSlab(derivation, positives):
-       'Add slab.'
-       copyShallow = derivation.elementNode.getCopyShallow()
-       copyShallow.attributes['path'] = [Vector3(), Vector3(0.0, 0.0, derivation.height)]
-       extrudeDerivation = extrude.ExtrudeDerivation(copyShallow)
-       beveledRectangle = getBeveledRectangle(derivation.bevel, -derivation.topRight)
-       outsidePath = euclidean.getVector3Path(beveledRectangle)
-       extrude.addPositives(extrudeDerivation, [outsidePath], positives)
-
-def addXGroove(derivation, negatives, y):
-       'Add x groove.'
-       if derivation.topBevel <= 0.0:
-               return
-       bottom = derivation.height - derivation.topBevel
-       top = derivation.height
-       groove = [complex(y, bottom), complex(y - derivation.topBevel, top), complex(y + derivation.topBevel, top)]
-       triangle_mesh.addSymmetricXPath(negatives, groove, 1.0001 * derivation.topRight.real)
-
-def addYGroove(derivation, negatives, x):
-       'Add y groove'
-       if derivation.topBevel <= 0.0:
-               return
-       bottom = derivation.height - derivation.topBevel
-       top = derivation.height
-       groove = [complex(x, bottom), complex(x - derivation.topBevel, top), complex(x + derivation.topBevel, top)]
-       triangle_mesh.addSymmetricYPath(negatives, groove, 1.0001 * derivation.topRight.imag)
-
-def getBeveledRectangle(bevel, bottomLeft):
-       'Get the beveled rectangle.'
-       bottomRight = complex(-bottomLeft.real, bottomLeft.imag)
-       rectangle = [bottomLeft, bottomRight, -bottomLeft, -bottomRight]
-       if bevel <= 0.0:
-               return rectangle
-       beveledRectangle = []
-       for pointIndex, point in enumerate(rectangle):
-               begin = rectangle[(pointIndex + len(rectangle) - 1) % len(rectangle)]
-               end = rectangle[(pointIndex + 1) % len(rectangle)]
-               addAlongWay(point, bevel, begin, beveledRectangle)
-               addAlongWay(point, bevel, end, beveledRectangle)
-       return beveledRectangle
-
-def getGeometryOutput(elementNode):
-       'Get vector3 vertexes from attribute dictionary.'
-       derivation = MechaslabDerivation(elementNode)
-       negatives = []
-       positives = []
-       addSlab(derivation, positives)
-       for hollowPegSocket in derivation.hollowPegSockets:
-               addHollowPegSocket(derivation, hollowPegSocket, negatives, positives)
-       if 's' in derivation.topBevelPositions:
-               addXGroove(derivation, negatives, -derivation.topRight.imag)
-       if 'n' in derivation.topBevelPositions:
-               addXGroove(derivation, negatives, derivation.topRight.imag)
-       if 'w' in derivation.topBevelPositions:
-               addYGroove(derivation, negatives, -derivation.topRight.real)
-       if 'e' in derivation.topBevelPositions:
-               addYGroove(derivation, negatives, derivation.topRight.real)
-       return extrude.getGeometryOutputByNegativesPositives(elementNode, negatives, positives)
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       'Get vector3 vertexes from attribute dictionary by arguments.'
-       evaluate.setAttributesByArguments(['length', 'radius'], arguments, elementNode)
-       return getGeometryOutput(elementNode)
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return MechaslabDerivation(elementNode)
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       solid.processElementNodeByGeometry(elementNode, getGeometryOutput(elementNode))
-
-
-class CellExistence(object):
-       'Class to determine if a cell exists.'
-       def __init__(self, columns, rows, value):
-               'Initialize.'
-               self.existenceSet = None
-               if value == None:
-                       return
-               self.existenceSet = set()
-               for element in value:
-                       if element.__class__ == int:
-                               columnIndex = (element + columns) % columns
-                               for rowIndex in xrange(rows):
-                                       keyTuple = (columnIndex, rowIndex)
-                                       self.existenceSet.add(keyTuple)
-                       else:
-                               keyTuple = (element[0], element[1])
-                               self.existenceSet.add(keyTuple)
-
-       def __repr__(self):
-               'Get the string representation of this CellExistence.'
-               return euclidean.getDictionaryString(self.__dict__)
-
-       def getIsInExistence(self, columnIndex, rowIndex):
-               'Detremine if the cell at the column and row exists.'
-               if self.existenceSet == None:
-                       return True
-               return (columnIndex, rowIndex) in self.existenceSet
-
-
-class HollowPegSocket(object):
-       'Class to hold hollow peg socket variables.'
-       def __init__(self, center):
-               'Initialize.'
-               self.center = center
-               self.shouldAddPeg = True
-               self.shouldAddSocket = True
-
-       def __repr__(self):
-               'Get the string representation of this HollowPegSocket.'
-               return euclidean.getDictionaryString(self.__dict__)
-
-
-class MechaslabDerivation(object):
-       'Class to hold mechaslab variables.'
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.bevelOverRadius = evaluate.getEvaluatedFloat(0.2, elementNode, 'bevelOverRadius')
-               self.boltRadiusOverRadius = evaluate.getEvaluatedFloat(0.0, elementNode, 'boltRadiusOverRadius')
-               self.columns = evaluate.getEvaluatedInt(2, elementNode, 'columns')
-               self.elementNode = elementNode
-               self.heightOverRadius = evaluate.getEvaluatedFloat(2.0, elementNode, 'heightOverRadius')
-               self.interiorOverhangRadians = setting.getInteriorOverhangRadians(elementNode)
-               self.overhangSpan = setting.getOverhangSpan(elementNode)
-               self.pegClearanceOverRadius = evaluate.getEvaluatedFloat(0.0, elementNode, 'pegClearanceOverRadius')
-               self.pegRadians = math.radians(evaluate.getEvaluatedFloat(2.0, elementNode, 'pegAngle'))
-               self.pegHeightOverHeight = evaluate.getEvaluatedFloat(0.4, elementNode, 'pegHeightOverHeight')
-               self.pegRadiusOverRadius = evaluate.getEvaluatedFloat(0.7, elementNode, 'pegRadiusOverRadius')
-               self.radius = lineation.getFloatByPrefixBeginEnd(elementNode, 'radius', 'width', 5.0)
-               self.rows = evaluate.getEvaluatedInt(1, elementNode, 'rows')
-               self.topBevelOverRadius = evaluate.getEvaluatedFloat(0.2, elementNode, 'topBevelOverRadius')
-               # Set derived values.
-               self.bevel = evaluate.getEvaluatedFloat(self.bevelOverRadius * self.radius, elementNode, 'bevel')
-               self.boltRadius = evaluate.getEvaluatedFloat(self.boltRadiusOverRadius * self.radius, elementNode, 'boltRadius')
-               self.boltSides = evaluate.getSidesMinimumThreeBasedOnPrecision(elementNode, self.boltRadius)
-               self.bottomLeftCenter = complex(-float(self.columns - 1), -float(self.rows - 1)) * self.radius
-               self.height = evaluate.getEvaluatedFloat(self.heightOverRadius * self.radius, elementNode, 'height')
-               self.hollowPegSockets = []
-               centerY = self.bottomLeftCenter.imag
-               diameter = self.radius + self.radius
-               self.pegExistence = CellExistence(self.columns, self.rows, evaluate.getEvaluatedValue(None, elementNode, 'pegs'))
-               self.socketExistence = CellExistence(self.columns, self.rows, evaluate.getEvaluatedValue(None, elementNode, 'sockets'))
-               for rowIndex in xrange(self.rows):
-                       centerX = self.bottomLeftCenter.real
-                       for columnIndex in xrange(self.columns):
-                               hollowPegSocket = HollowPegSocket(complex(centerX, centerY))
-                               hollowPegSocket.shouldAddPeg = self.pegExistence.getIsInExistence(columnIndex, rowIndex)
-                               hollowPegSocket.shouldAddSocket = self.socketExistence.getIsInExistence(columnIndex, rowIndex)
-                               self.hollowPegSockets.append(hollowPegSocket)
-                               centerX += diameter
-                       centerY += diameter
-               self.pegClearance = evaluate.getEvaluatedFloat(self.pegClearanceOverRadius * self.radius, elementNode, 'pegClearance')
-               halfPegClearance = 0.5 * self.pegClearance
-               self.pegHeight = evaluate.getEvaluatedFloat(self.pegHeightOverHeight * self.height, elementNode, 'pegHeight')
-               self.pegRadius = evaluate.getEvaluatedFloat(self.pegRadiusOverRadius * self.radius, elementNode, 'pegRadius')
-               sides = 24 * max(1, math.floor(evaluate.getSidesBasedOnPrecision(elementNode, self.pegRadius) / 24))
-               self.socketRadius = self.pegRadius + halfPegClearance
-               self.pegSides = evaluate.getEvaluatedInt(sides, elementNode, 'pegSides')
-               self.pegRadius -= halfPegClearance
-               self.pegRadiusArealized = evaluate.getRadiusArealizedBasedOnAreaRadius(elementNode, self.pegRadius, self.pegSides)
-               self.socketSides = evaluate.getEvaluatedInt(sides, elementNode, 'socketSides')
-               self.socketRadiusArealized = evaluate.getRadiusArealizedBasedOnAreaRadius(elementNode, self.socketRadius, self.socketSides)
-               self.topBevel = evaluate.getEvaluatedFloat(self.topBevelOverRadius * self.radius, elementNode, 'topBevel')
-               self.topBevelPositions = evaluate.getEvaluatedString('nwse', elementNode, 'topBevelPositions').lower()
-               self.topRight = complex(float(self.columns), float(self.rows)) * self.radius
-
-       def __repr__(self):
-               'Get the string representation of this MechaslabDerivation.'
-               return euclidean.getDictionaryString(self.__dict__)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/peg.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/peg.py
deleted file mode 100644 (file)
index 02fd1ba..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-"""
-Peg.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import extrude
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.solids import cylinder
-from fabmetheus_utilities.vector3 import Vector3
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-
-def addPegOutput(bevel, endZ, outputs, radiusArealized, sides, start, topOverBottom):
-       'Add beveled cylinder to outputs given bevel, endZ, radiusArealized and start.'
-       height = abs(start.z - endZ)
-       bevelStartRatio = max(1.0 - bevel / height, 0.5)
-       oneMinusBevelStartRatio = 1.0 - bevelStartRatio
-       trunkEndZ = bevelStartRatio * endZ + oneMinusBevelStartRatio * start.z
-       trunkTopOverBottom = bevelStartRatio * topOverBottom + oneMinusBevelStartRatio
-       cylinder.addCylinderOutputByEndStart(trunkEndZ, radiusArealized, outputs, sides, start, trunkTopOverBottom)
-       capRadius = radiusArealized * trunkTopOverBottom
-       capStart = bevelStartRatio * Vector3(start.x, start.y, endZ) + oneMinusBevelStartRatio * start
-       radiusMaximum = max(radiusArealized.real, radiusArealized.imag)
-       endRadiusMaximum = radiusMaximum * topOverBottom - bevel
-       trunkRadiusMaximum = radiusMaximum * trunkTopOverBottom
-       capTopOverBottom = endRadiusMaximum / trunkRadiusMaximum
-       cylinder.addCylinderOutputByEndStart(endZ, capRadius, outputs, sides, capStart, capTopOverBottom)
-
-def getGeometryOutput(derivation, elementNode):
-       'Get vector3 vertexes from attribute dictionary.'
-       if derivation == None:
-               derivation = PegDerivation(elementNode)
-       positives = []
-       radiusArealized = complex(derivation.radiusArealized, derivation.radiusArealized)
-       addPegOutput(derivation.bevel, derivation.endZ, positives, radiusArealized, derivation.sides, derivation.start, derivation.topOverBottom)
-       return extrude.getGeometryOutputByNegativesPositives(elementNode, [], positives)
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       'Get vector3 vertexes from attribute dictionary by arguments.'
-       evaluate.setAttributesByArguments(['radius', 'endZ', 'start'], arguments, elementNode)
-       return getGeometryOutput(None, elementNode)
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return PegDerivation(elementNode)
-
-def getTopAddBiconicOutput(bottomRadians, height, outputs, radius, sides, start, tipRadius, topRadians):
-       'Get top and add biconic cylinder to outputs.'
-       radiusMaximum = max(radius.real, radius.imag)
-       topRadiusMaximum = radiusMaximum - height * math.tan(bottomRadians)
-       trunkEndZ = start.z + height
-       trunkTopOverBottom = topRadiusMaximum / radiusMaximum
-       topRadiusComplex = trunkTopOverBottom * radius
-       cylinder.addCylinderOutputByEndStart(trunkEndZ, radius, outputs, sides, start, trunkTopOverBottom)
-       tipOverTop = tipRadius / topRadiusMaximum
-       if tipOverTop >= 1.0:
-               return trunkEndZ
-       capStart = Vector3(start.x, start.y, trunkEndZ)
-       capEndZ = trunkEndZ + (topRadiusMaximum - tipRadius) / math.tan(topRadians)
-       cylinder.addCylinderOutputByEndStart(capEndZ, topRadiusComplex, outputs, sides, capStart, tipOverTop)
-       return capEndZ
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       solid.processElementNodeByGeometry(elementNode, getGeometryOutput(None, elementNode))
-
-def setTopOverBottomByRadius(derivation, endZ, radius, startZ):
-       'Set the derivation topOverBottom by the angle of the elementNode, the endZ, float radius and startZ.'
-       angleDegrees = evaluate.getEvaluatedFloat(None, derivation.elementNode, 'angle')
-       if angleDegrees != None:
-               derivation.topOverBottom = cylinder.getTopOverBottom(math.radians(angleDegrees), endZ, complex(radius, radius), startZ)
-
-
-class PegDerivation(object):
-       'Class to hold peg variables.'
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.bevelOverRadius = evaluate.getEvaluatedFloat(0.25, elementNode, 'bevelOverRadius')
-               self.clearanceOverRadius = evaluate.getEvaluatedFloat(0.0, elementNode, 'clearanceOverRadius')
-               self.elementNode = elementNode
-               self.endZ = evaluate.getEvaluatedFloat(10.0, elementNode, 'endZ')
-               self.start = evaluate.getVector3ByPrefix(Vector3(), elementNode, 'start')
-               self.radius = lineation.getFloatByPrefixBeginEnd(elementNode, 'radius', 'diameter', 2.0)
-               self.sides = evaluate.getSidesMinimumThreeBasedOnPrecision(elementNode, max(self.radius.real, self.radius.imag))
-               self.radiusArealized = evaluate.getRadiusArealizedBasedOnAreaRadius(elementNode, self.radius, self.sides)
-               self.topOverBottom = evaluate.getEvaluatedFloat(0.8, elementNode, 'topOverBottom')
-               setTopOverBottomByRadius(self, self.endZ, self.radiusArealized, self.start.z)
-               # Set derived variables.
-               self.bevel = evaluate.getEvaluatedFloat(self.bevelOverRadius * self.radiusArealized, elementNode, 'bevel')
-               self.clearance = evaluate.getEvaluatedFloat(self.clearanceOverRadius * self.radiusArealized, elementNode, 'clearance')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/polygon.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/polygon.py
deleted file mode 100644 (file)
index 35945ac..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-"""
-Polygon path.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_tools import path
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getGeometryOutput(derivation, elementNode):
-       "Get vector3 vertexes from attribute dictionary."
-       if derivation == None:
-               derivation = PolygonDerivation(elementNode)
-       loop = []
-       spiral = lineation.Spiral(derivation.spiral, 0.5 * derivation.sideAngle / math.pi)
-       for side in xrange(derivation.start, derivation.start + derivation.extent + 1):
-               angle = float(side) * derivation.sideAngle
-               unitPolar = euclidean.getWiddershinsUnitPolar(angle)
-               vertex = spiral.getSpiralPoint(unitPolar, Vector3(unitPolar.real * derivation.radius.real, unitPolar.imag * derivation.radius.imag))
-               loop.append(vertex)
-       loop = euclidean.getLoopWithoutCloseEnds(0.000001 * max(derivation.radius.real, derivation.radius.imag), loop)
-       lineation.setClosedAttribute(elementNode, derivation.revolutions)
-       return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(loop, derivation.sideAngle))
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       "Get vector3 vertexes from attribute dictionary by arguments."
-       evaluate.setAttributesByArguments(['sides', 'radius'], arguments, elementNode)
-       return getGeometryOutput(None, elementNode)
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return PolygonDerivation(elementNode)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       path.convertElementNode(elementNode, getGeometryOutput(None, elementNode))
-
-
-class PolygonDerivation(object):
-       "Class to hold polygon variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.sides = evaluate.getEvaluatedFloat(4.0, elementNode, 'sides')
-               self.sideAngle = 2.0 * math.pi / self.sides
-               cosSide = math.cos(0.5 * self.sideAngle)
-               self.radius = lineation.getComplexByMultiplierPrefixes(elementNode, cosSide, ['apothem', 'inradius'], complex(1.0, 1.0))
-               self.radius = lineation.getComplexByPrefixes(elementNode, ['demisize', 'radius'], self.radius)
-               self.radius = lineation.getComplexByMultiplierPrefixes(elementNode, 2.0, ['diameter', 'size'], self.radius)
-               self.sidesCeiling = int(math.ceil(abs(self.sides)))
-               self.start = evaluate.getEvaluatedInt(0, elementNode, 'start')
-               end = evaluate.getEvaluatedInt(self.sidesCeiling, elementNode, 'end')
-               self.revolutions = evaluate.getEvaluatedInt(1, elementNode, 'revolutions')
-               self.extent = evaluate.getEvaluatedInt(end - self.start, elementNode, 'extent')
-               self.extent += self.sidesCeiling * (self.revolutions - 1)
-               self.spiral = evaluate.getVector3ByPrefix(None, elementNode, 'spiral')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/shaft.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/shaft.py
deleted file mode 100644 (file)
index 2752108..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-"""
-Shaft path.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_tools import path
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities import euclidean
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getGeometryOutput(derivation, elementNode):
-       "Get vector3 vertexes from attribute dictionary."
-       if derivation == None:
-               derivation = ShaftDerivation(elementNode)
-       shaftPath = getShaftPath(derivation.depthBottom, derivation.depthTop, derivation.radius, derivation.sides)
-       return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(shaftPath))
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       "Get vector3 vertexes from attribute dictionary by arguments."
-       evaluate.setAttributesByArguments(['radius', 'sides'], arguments, elementNode)
-       return getGeometryOutput(None, elementNode)
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return ShaftDerivation(elementNode)
-
-def getShaftPath(depthBottom, depthTop, radius, sides):
-       'Get shaft with the option of a flat on the top and/or bottom.'
-       if radius <= 0.0:
-               return []
-       sideAngle = 2.0 * math.pi / float(abs(sides))
-       startAngle = 0.5 * sideAngle
-       endAngle = math.pi - 0.1 * sideAngle
-       shaftProfile = []
-       while startAngle < endAngle:
-               unitPolar = euclidean.getWiddershinsUnitPolar(startAngle)
-               shaftProfile.append(unitPolar * radius)
-               startAngle += sideAngle
-       if abs(sides) % 2 == 1:
-               shaftProfile.append(complex(-radius, 0.0))
-       horizontalBegin = radius - depthTop
-       horizontalEnd = depthBottom - radius
-       shaftProfile = euclidean.getHorizontallyBoundedPath(horizontalBegin, horizontalEnd, shaftProfile)
-       for shaftPointIndex, shaftPoint in enumerate(shaftProfile):
-               shaftProfile[shaftPointIndex] = complex(shaftPoint.imag, shaftPoint.real)
-       shaftPath = euclidean.getVector3Path(euclidean.getMirrorPath(shaftProfile))
-       if sides > 0:
-               shaftPath.reverse()
-       return shaftPath
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       path.convertElementNode(elementNode, getGeometryOutput(None, elementNode))
-
-
-class ShaftDerivation(object):
-       "Class to hold shaft variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.depthBottomOverRadius = evaluate.getEvaluatedFloat(0.0, elementNode, 'depthBottomOverRadius')
-               self.depthTopOverRadius = evaluate.getEvaluatedFloat(0.0, elementNode, 'depthOverRadius')
-               self.depthTopOverRadius = evaluate.getEvaluatedFloat(
-                       self.depthTopOverRadius, elementNode, 'depthTopOverRadius')
-               self.radius = evaluate.getEvaluatedFloat(1.0, elementNode, 'radius')
-               self.sides = evaluate.getEvaluatedInt(4, elementNode, 'sides')
-               self.depthBottom = self.radius * self.depthBottomOverRadius
-               self.depthBottom = evaluate.getEvaluatedFloat(self.depthBottom, elementNode, 'depthBottom')
-               self.depthTop = self.radius * self.depthTopOverRadius
-               self.depthTop = evaluate.getEvaluatedFloat(self.depthTop, elementNode, 'depth')
-               self.depthTop = evaluate.getEvaluatedFloat(self.depthTop, elementNode, 'depthTop')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/solid.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/solid.py
deleted file mode 100644 (file)
index 91fea73..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-"""
-Solid has functions for 3D shapes.
-
-Solid has some of the same functions as lineation, however you can not define geometry by dictionary string in the target because there is no getGeometryOutputByArguments function.  You would have to define a shape by making the shape element.  Also, you can not define geometry by 'get<Creation Name>, because the target only gets element.  Instead you would have the shape element, and set the target in solid to that element.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_tools import path
-from fabmetheus_utilities.geometry.geometry_utilities import boolean_geometry
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities import euclidean
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getGeometryOutputByFunction(elementNode, geometryFunction):
-       'Get geometry output by manipulationFunction.'
-       if elementNode.xmlObject == None:
-               print('Warning, there is no object in getGeometryOutputByFunction in solid for:')
-               print(elementNode)
-               return None
-       geometryOutput = elementNode.xmlObject.getGeometryOutput()
-       if geometryOutput == None:
-               print('Warning, there is no geometryOutput in getGeometryOutputByFunction in solid for:')
-               print(elementNode)
-               return None
-       return geometryFunction(elementNode, geometryOutput, '')
-
-def getGeometryOutputByManipulation(elementNode, geometryOutput):
-       'Get geometryOutput manipulated by the plugins in the manipulation shapes & solids folders.'
-       xmlProcessor = elementNode.getXMLProcessor()
-       matchingPlugins = getSolidMatchingPlugins(elementNode)
-       matchingPlugins.sort(evaluate.compareExecutionOrderAscending)
-       for matchingPlugin in matchingPlugins:
-               prefix = matchingPlugin.__name__.replace('_', '') + '.'
-               geometryOutput = matchingPlugin.getManipulatedGeometryOutput(elementNode, geometryOutput, prefix)
-       return geometryOutput
-
-def getLoopLayersSetCopy(elementNode, geometryOutput, importRadius, radius):
-       'Get the loop layers and set the copyShallow.'
-       halfLayerHeight = 0.5 * radius
-       copyShallow = elementNode.getCopyShallow()
-       processElementNodeByGeometry(copyShallow, geometryOutput)
-       targetMatrix = matrix.getBranchMatrixSetElementNode(elementNode)
-       matrix.setElementNodeDictionaryMatrix(copyShallow, targetMatrix)
-       transformedVertexes = copyShallow.xmlObject.getTransformedVertexes()
-       minimumZ = boolean_geometry.getMinimumZ(copyShallow.xmlObject)
-       if minimumZ == None:
-               copyShallow.parentNode.xmlObject.archivableObjects.remove(copyShallow.xmlObject)
-               return []
-       maximumZ = euclidean.getTopPath(transformedVertexes)
-       copyShallow.attributes['visible'] = True
-       copyShallowObjects = [copyShallow.xmlObject]
-       bottomLoopLayer = euclidean.LoopLayer(minimumZ)
-       z = minimumZ + 0.1 * radius
-       zoneArrangement = triangle_mesh.ZoneArrangement(radius, transformedVertexes)
-       bottomLoopLayer.loops = boolean_geometry.getEmptyZLoops(copyShallowObjects, importRadius, False, z, zoneArrangement)
-       loopLayers = [bottomLoopLayer]
-       z = minimumZ + halfLayerHeight
-       loopLayers += boolean_geometry.getLoopLayers(copyShallowObjects, importRadius, halfLayerHeight, maximumZ, False, z, zoneArrangement)
-       copyShallow.parentNode.xmlObject.archivableObjects.remove(copyShallow.xmlObject)
-       return loopLayers
-
-def getLoopOrEmpty(loopIndex, loopLayers):
-       'Get the loop, or if the loopIndex is out of range, get an empty list.'
-       if loopIndex < 0 or loopIndex >= len(loopLayers):
-               return []
-       return loopLayers[loopIndex].loops[0]
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return SolidDerivation(elementNode)
-
-def getSolidMatchingPlugins(elementNode):
-       'Get solid plugins in the manipulation matrix, shapes & solids folders.'
-       xmlProcessor = elementNode.getXMLProcessor()
-       matchingPlugins = evaluate.getMatchingPlugins(elementNode, xmlProcessor.manipulationMatrixDictionary)
-       return matchingPlugins + evaluate.getMatchingPlugins(elementNode, xmlProcessor.manipulationShapeDictionary)
-
-def processArchiveRemoveSolid(elementNode, geometryOutput):
-       'Process the target by the manipulationFunction.'
-       solidMatchingPlugins = getSolidMatchingPlugins(elementNode)
-       if len(solidMatchingPlugins) == 0:
-               elementNode.parentNode.xmlObject.archivableObjects.append(elementNode.xmlObject)
-               matrix.getBranchMatrixSetElementNode(elementNode)
-               return
-       processElementNodeByGeometry(elementNode, getGeometryOutputByManipulation(elementNode, geometryOutput))
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       processElementNodeByDerivation(None, elementNode)
-
-def processElementNodeByDerivation(derivation, elementNode):
-       'Process the xml element by derivation.'
-       if derivation == None:
-               derivation = SolidDerivation(elementNode)
-       elementAttributesCopy = elementNode.attributes.copy()
-       for target in derivation.targets:
-               targetAttributesCopy = target.attributes.copy()
-               target.attributes = elementAttributesCopy
-               processTarget(target)
-               target.attributes = targetAttributesCopy
-
-def processElementNodeByFunction(elementNode, manipulationFunction):
-       'Process the xml element.'
-       if 'target' not in elementNode.attributes:
-               print('Warning, there was no target in processElementNodeByFunction in solid for:')
-               print(elementNode)
-               return
-       target = evaluate.getEvaluatedLinkValue(elementNode, str(elementNode.attributes['target']).strip())
-       if target.__class__.__name__ == 'ElementNode':
-               manipulationFunction(elementNode, target)
-               return
-       path.convertElementNode(elementNode, target)
-       manipulationFunction(elementNode, elementNode)
-
-def processElementNodeByFunctionPair(elementNode, geometryFunction, pathFunction):
-       'Process the xml element by the appropriate manipulationFunction.'
-       elementAttributesCopy = elementNode.attributes.copy()
-       targets = evaluate.getElementNodesByKey(elementNode, 'target')
-       for target in targets:
-               targetAttributesCopy = target.attributes.copy()
-               target.attributes = elementAttributesCopy
-               processTargetByFunctionPair(geometryFunction, pathFunction, target)
-               target.attributes = targetAttributesCopy
-
-def processElementNodeByGeometry(elementNode, geometryOutput):
-       'Process the xml element by geometryOutput.'
-       if geometryOutput != None:
-               elementNode.getXMLProcessor().convertElementNode(elementNode, geometryOutput)
-
-def processTarget(target):
-       'Process the target.'
-       if target.xmlObject == None:
-               print('Warning, there is no object in processElementNode in solid for:')
-               print(target)
-               return
-       geometryOutput = target.xmlObject.getGeometryOutput()
-       if geometryOutput == None:
-               print('Warning, there is no geometryOutput in processElementNode in solid for:')
-               print(target.xmlObject)
-               return
-       geometryOutput = getGeometryOutputByManipulation(target, geometryOutput)
-       lineation.removeChildNodesFromElementObject(target)
-       target.getXMLProcessor().convertElementNode(target, geometryOutput)
-
-def processTargetByFunctionPair(geometryFunction, pathFunction, target):
-       'Process the target by the manipulationFunction.'
-       if target.xmlObject == None:
-               print('Warning, there is no object in processTargetByFunctions in solid for:')
-               print(target)
-               return
-       if len(target.xmlObject.getPaths()) > 0:
-               lineation.processTargetByFunction(pathFunction, target)
-               return
-       geometryOutput = getGeometryOutputByFunction(target, geometryFunction)
-       lineation.removeChildNodesFromElementObject(target)
-       target.getXMLProcessor().convertElementNode(target, geometryOutput)
-
-
-class SolidDerivation(object):
-       'Class to hold solid variables.'
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.targets = evaluate.getElementNodesByKey(elementNode, 'target')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/sponge_slice.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/sponge_slice.py
deleted file mode 100644 (file)
index 7992a3a..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-"""
-Sponge slice.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_tools import path
-from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-import math
-import random
-import time
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getGeometryOutput(derivation, elementNode):
-       "Get vector3 vertexes from attribute dictionary."
-       if derivation == None:
-               derivation = SpongeSliceDerivation(elementNode)
-       awayPoints = []
-       vector3Path = euclidean.getVector3Path(euclidean.getSquareLoopWiddershins(-derivation.inradius, derivation.inradius))
-       geometryOutput = lineation.SideLoop(vector3Path).getManipulationPluginLoops(elementNode)
-       minimumDistanceFromOther = derivation.wallThickness + derivation.minimumRadius + derivation.minimumRadius
-       if derivation.inradiusMinusRadiusThickness.real <= 0.0 or derivation.inradiusMinusRadiusThickness.imag <= 0.0:
-               return geometryOutput
-       for point in derivation.path:
-               if abs(point.x) <= derivation.inradiusMinusRadiusThickness.real and abs(point.y) <= derivation.inradiusMinusRadiusThickness.imag:
-                       awayPoints.append(point)
-       awayCircles = []
-       for point in awayPoints:
-               if getIsPointAway(minimumDistanceFromOther, point, awayCircles):
-                       awayCircles.append(SpongeCircle(point, derivation.minimumRadius))
-       averagePotentialBubbleArea = derivation.potentialBubbleArea / float(len(awayCircles))
-       averageBubbleRadius = math.sqrt(averagePotentialBubbleArea / math.pi) - 0.5 * derivation.wallThickness
-       sides = -4 * (max(evaluate.getSidesBasedOnPrecision(elementNode, averageBubbleRadius), 4) / 4)
-       sideAngle = math.pi / sides
-       cosSide = math.cos(sideAngle)
-       overlapArealRatio = (1 - cosSide) / cosSide
-       for circleIndex, circle in enumerate(awayCircles):
-               otherCircles = awayCircles[: circleIndex] + awayCircles[circleIndex + 1 :]
-               circle.radius = circle.getRadius(circle.center, derivation, otherCircles, overlapArealRatio)
-       if derivation.searchAttempts > 0:
-               for circleIndex, circle in enumerate(awayCircles):
-                       otherCircles = awayCircles[: circleIndex] + awayCircles[circleIndex + 1 :]
-                       circle.moveCircle(derivation, otherCircles, overlapArealRatio)
-       for circle in awayCircles:
-               vector3Path = euclidean.getVector3Path(euclidean.getComplexPolygon(circle.center.dropAxis(), circle.radius, sides, sideAngle))
-               geometryOutput += lineation.SideLoop(vector3Path).getManipulationPluginLoops(elementNode)
-       return geometryOutput
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       "Get vector3 vertexes from attribute dictionary by arguments."
-       return getGeometryOutput(None, elementNode)
-
-def getIsPointAway(minimumDistance, point, spongeCircles):
-       'Determine if the point is at least the minimumDistance away from other points.'
-       for otherSpongeCircle in spongeCircles:
-               if abs(otherSpongeCircle.center - point) < minimumDistance:
-                       return False
-       return True
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return SpongeSliceDerivation(elementNode)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       path.convertElementNode(elementNode, getGeometryOutput(None, elementNode))
-
-
-class SpongeCircle(object):
-       "Class to hold sponge circle."
-       def __init__(self, center, radius=0.0):
-               'Initialize.'
-               self.center = center
-               self.radius = radius
-
-       def getRadius(self, center, derivation, otherCircles, overlapArealRatio):
-               'Get sponge bubble radius.'
-               radius = 987654321.0
-               for otherSpongeCircle in otherCircles:
-                       distance = abs(otherSpongeCircle.center.dropAxis() - center.dropAxis())
-                       radius = min(distance - derivation.wallThickness - otherSpongeCircle.radius, radius)
-               overlapAreal = overlapArealRatio * radius
-               radius = min(derivation.inradiusMinusThickness.real + overlapAreal - abs(center.x), radius)
-               return min(derivation.inradiusMinusThickness.imag + overlapAreal - abs(center.y), radius)
-
-       def moveCircle(self, derivation, otherCircles, overlapArealRatio):
-               'Move circle into an open spot.'
-               angle = (abs(self.center) + self.radius) % euclidean.globalTau
-               movedCenter = self.center
-               searchRadius = derivation.searchRadiusOverRadius * self.radius
-               distanceIncrement = searchRadius / float(derivation.searchAttempts)
-               distance = 0.0
-               greatestRadius = self.radius
-               searchCircles = []
-               searchCircleDistance = searchRadius + searchRadius + self.radius + derivation.wallThickness
-               for otherCircle in otherCircles:
-                       if abs(self.center - otherCircle.center) <= searchCircleDistance + otherCircle.radius:
-                               searchCircles.append(otherCircle)
-               for attemptIndex in xrange(derivation.searchAttempts):
-                       angle += euclidean.globalGoldenAngle
-                       distance += distanceIncrement
-                       offset = distance * euclidean.getWiddershinsUnitPolar(angle)
-                       attemptCenter = self.center + Vector3(offset.real, offset.imag)
-                       radius = self.getRadius(attemptCenter, derivation, searchCircles, overlapArealRatio)
-                       if radius > greatestRadius:
-                               greatestRadius = radius
-                               movedCenter = attemptCenter
-               self.center = movedCenter
-               self.radius = greatestRadius
-
-
-class SpongeSliceDerivation(object):
-       "Class to hold sponge slice variables."
-       def __init__(self, elementNode):
-               'Initialize.'
-               elementNode.attributes['closed'] = 'true'
-               self.density = evaluate.getEvaluatedFloat(1.0, elementNode, 'density')
-               self.minimumRadiusOverThickness = evaluate.getEvaluatedFloat(1.0, elementNode, 'minimumRadiusOverThickness')
-               self.mobile = evaluate.getEvaluatedBoolean(False, elementNode, 'mobile')
-               self.inradius = lineation.getInradius(complex(10.0, 10.0), elementNode)
-               self.path = None
-               if 'path' in elementNode.attributes:
-                       self.path = evaluate.getPathByKey([], elementNode, 'path')
-               self.searchAttempts = evaluate.getEvaluatedInt(0, elementNode, 'searchAttempts')
-               self.searchRadiusOverRadius = evaluate.getEvaluatedFloat(1.0, elementNode, 'searchRadiusOverRadius')
-               self.seed = evaluate.getEvaluatedInt(None, elementNode, 'seed')
-               self.wallThickness = evaluate.getEvaluatedFloat(2.0 * setting.getEdgeWidth(elementNode), elementNode, 'wallThickness')
-               # Set derived variables.
-               self.halfWallThickness = 0.5 * self.wallThickness
-               self.inradiusMinusThickness = self.inradius - complex(self.wallThickness, self.wallThickness)
-               self.minimumRadius = evaluate.getEvaluatedFloat(self.minimumRadiusOverThickness * self.wallThickness, elementNode, 'minimumRadius')
-               self.inradiusMinusRadiusThickness = self.inradiusMinusThickness - complex(self.minimumRadius, self.minimumRadius)
-               self.potentialBubbleArea = 4.0 * self.inradiusMinusThickness.real * self.inradiusMinusThickness.imag
-               if self.path == None:
-                       radiusPlusHalfThickness = self.minimumRadius + self.halfWallThickness
-                       numberOfPoints = int(math.ceil(self.density * self.potentialBubbleArea / math.pi / radiusPlusHalfThickness / radiusPlusHalfThickness))
-                       self.path = []
-                       if self.seed == None:
-                               self.seed = time.time()
-                               print('Sponge slice seed used was: %s' % self.seed)
-                       random.seed(self.seed)
-                       for pointIndex in xrange(numberOfPoints):
-                               point = euclidean.getRandomComplex(-self.inradiusMinusRadiusThickness, self.inradiusMinusRadiusThickness)
-                               self.path.append(Vector3(point.real, point.imag))
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/square.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/square.py
deleted file mode 100644 (file)
index dc89d30..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-"""
-Square path.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_tools import path
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getGeometryOutput(derivation, elementNode):
-       "Get vector3 vertexes from attribute dictionary."
-       if derivation == None:
-               derivation = SquareDerivation(elementNode)
-       topRight = complex(derivation.topDemiwidth, derivation.demiheight)
-       topLeft = complex(-derivation.topDemiwidth, derivation.demiheight)
-       bottomLeft = complex(-derivation.bottomDemiwidth, -derivation.demiheight)
-       bottomRight = complex(derivation.bottomDemiwidth, -derivation.demiheight)
-       if derivation.interiorAngle != 90.0:
-               interiorPlaneAngle = euclidean.getWiddershinsUnitPolar(math.radians(derivation.interiorAngle - 90.0))
-               topRight = (topRight - bottomRight) * interiorPlaneAngle + bottomRight
-               topLeft = (topLeft - bottomLeft) * interiorPlaneAngle + bottomLeft
-       lineation.setClosedAttribute(elementNode, derivation.revolutions)
-       complexLoop = [topRight, topLeft, bottomLeft, bottomRight]
-       originalLoop = complexLoop[:]
-       for revolution in xrange(1, derivation.revolutions):
-               complexLoop += originalLoop
-       spiral = lineation.Spiral(derivation.spiral, 0.25)
-       loop = []
-       loopCentroid = euclidean.getLoopCentroid(originalLoop)
-       for point in complexLoop:
-               unitPolar = euclidean.getNormalized(point - loopCentroid)
-               loop.append(spiral.getSpiralPoint(unitPolar, Vector3(point.real, point.imag)))
-       return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(loop, 0.5 * math.pi))
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       "Get vector3 vertexes from attribute dictionary by arguments."
-       if len(arguments) < 1:
-               return getGeometryOutput(None, elementNode)
-       inradius = 0.5 * euclidean.getFloatFromValue(arguments[0])
-       elementNode.attributes['inradius.x'] = str(inradius)
-       if len(arguments) > 1:
-               inradius = 0.5 * euclidean.getFloatFromValue(arguments[1])
-       elementNode.attributes['inradius.y'] = str(inradius)
-       return getGeometryOutput(None, elementNode)
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return SquareDerivation(elementNode)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       path.convertElementNode(elementNode, getGeometryOutput(None, elementNode))
-
-
-class SquareDerivation(object):
-       "Class to hold square variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.inradius = lineation.getInradius(complex(1.0, 1.0), elementNode)
-               self.demiwidth = lineation.getFloatByPrefixBeginEnd(elementNode, 'demiwidth', 'width', self.inradius.real)
-               self.demiheight = lineation.getFloatByPrefixBeginEnd(elementNode, 'demiheight', 'height', self.inradius.imag)
-               self.bottomDemiwidth = lineation.getFloatByPrefixBeginEnd(elementNode, 'bottomdemiwidth', 'bottomwidth', self.demiwidth)
-               self.topDemiwidth = lineation.getFloatByPrefixBeginEnd(elementNode, 'topdemiwidth', 'topwidth', self.demiwidth)
-               self.interiorAngle = evaluate.getEvaluatedFloat(90.0, elementNode, 'interiorangle')
-               self.revolutions = evaluate.getEvaluatedInt(1, elementNode, 'revolutions')
-               self.spiral = evaluate.getVector3ByPrefix(None, elementNode, 'spiral')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/teardrop.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/teardrop.py
deleted file mode 100644 (file)
index 6379e04..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-"""
-Teardrop path.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import extrude
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_tools import path
-from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addNegativesByRadius(elementNode, end, negatives, radius, start):
-       "Add teardrop drill hole to negatives."
-       if radius <= 0.0:
-               return
-       copyShallow = elementNode.getCopyShallow()
-       extrude.setElementNodeToEndStart(copyShallow, end, start)
-       extrudeDerivation = extrude.ExtrudeDerivation(copyShallow)
-       extrude.addNegatives(extrudeDerivation, negatives, [getTeardropPathByEndStart(elementNode, end, radius, start)])
-
-def getGeometryOutput(derivation, elementNode):
-       "Get vector3 vertexes from attribute dictionary."
-       if derivation == None:
-               derivation = TeardropDerivation(elementNode)
-       teardropPath = getTeardropPath(
-               derivation.inclination, derivation.overhangRadians, derivation.overhangSpan, derivation.radiusArealized, derivation.sides)
-       return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(teardropPath))
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       "Get vector3 vertexes from attribute dictionary by arguments."
-       evaluate.setAttributesByArguments(['radius', 'inclination'], arguments, elementNode)
-       return getGeometryOutput(None, elementNode)
-
-def getInclination(end, start):
-       "Get inclination."
-       if end == None or start == None:
-               return 0.0
-       endMinusStart = end - start
-       return math.atan2(endMinusStart.z, abs(endMinusStart.dropAxis()))
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return TeardropDerivation(elementNode)
-
-def getTeardropPath(inclination, overhangRadians, overhangSpan, radiusArealized, sides):
-       "Get vector3 teardrop path."
-       sideAngle = 2.0 * math.pi / float(sides)
-       overhangPlaneAngle = euclidean.getWiddershinsUnitPolar(overhangRadians)
-       overhangRadians = math.atan2(overhangPlaneAngle.imag, overhangPlaneAngle.real * math.cos(inclination))
-       tanOverhangAngle = math.tan(overhangRadians)
-       beginAngle = overhangRadians
-       beginMinusEndAngle = math.pi + overhangRadians + overhangRadians
-       withinSides = int(math.ceil(beginMinusEndAngle / sideAngle))
-       withinSideAngle = -beginMinusEndAngle / float(withinSides)
-       teardropPath = []
-       for side in xrange(withinSides + 1):
-               unitPolar = euclidean.getWiddershinsUnitPolar(beginAngle)
-               teardropPath.append(unitPolar * radiusArealized)
-               beginAngle += withinSideAngle
-       firstPoint = teardropPath[0]
-       if overhangSpan <= 0.0:
-               teardropPath.append(complex(0.0, firstPoint.imag + firstPoint.real / tanOverhangAngle))
-       else:
-               deltaX = (radiusArealized - firstPoint.imag) * tanOverhangAngle
-               overhangPoint = complex(firstPoint.real - deltaX, radiusArealized)
-               remainingDeltaX = max(0.0, overhangPoint.real - 0.5 * overhangSpan )
-               overhangPoint += complex(-remainingDeltaX, remainingDeltaX / tanOverhangAngle)
-               teardropPath.append(complex(-overhangPoint.real, overhangPoint.imag))
-               teardropPath.append(overhangPoint)
-       return euclidean.getVector3Path(teardropPath)
-
-def getTeardropPathByEndStart(elementNode, end, radius, start):
-       "Get vector3 teardrop path by end and start."
-       inclination = getInclination(end, start)
-       sides = evaluate.getSidesMinimumThreeBasedOnPrecisionSides(elementNode, radius)
-       radiusArealized = evaluate.getRadiusArealizedBasedOnAreaRadius(elementNoderadius, sides)
-       return getTeardropPath(inclination, setting.getOverhangRadians(elementNode), setting.getOverhangSpan(elementNode), radiusArealized, sides)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       path.convertElementNode(elementNode, getGeometryOutput(None, elementNode))
-
-
-class TeardropDerivation(object):
-       "Class to hold teardrop variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               end = evaluate.getVector3ByPrefix(None, elementNode, 'end')
-               start = evaluate.getVector3ByPrefix(Vector3(), elementNode, 'start')
-               inclinationDegree = math.degrees(getInclination(end, start))
-               self.elementNode = elementNode
-               self.inclination = math.radians(evaluate.getEvaluatedFloat(inclinationDegree, elementNode, 'inclination'))
-               self.overhangRadians = setting.getOverhangRadians(elementNode)
-               self.overhangSpan = setting.getOverhangSpan(elementNode)
-               self.radius = lineation.getFloatByPrefixBeginEnd(elementNode, 'radius', 'diameter', 1.0)
-               size = evaluate.getEvaluatedFloat(None, elementNode, 'size')
-               if size != None:
-                       self.radius = 0.5 * size
-               self.sides = evaluate.getEvaluatedFloat(None, elementNode, 'sides')
-               if self.sides == None:
-                       self.sides = evaluate.getSidesMinimumThreeBasedOnPrecisionSides(elementNode, self.radius)
-               self.radiusArealized = evaluate.getRadiusArealizedBasedOnAreaRadius(elementNode, self.radius, self.sides)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/text.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/creation/text.py
deleted file mode 100644 (file)
index f22e3e8..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-"""
-Text vertexes.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_tools import path
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import svg_reader
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getGeometryOutput(derivation, elementNode):
-       "Get vector3 vertexes from attributes."
-       if derivation == None:
-               derivation = TextDerivation(elementNode)
-       if derivation.textString == '':
-               print('Warning, textString is empty in getGeometryOutput in text for:')
-               print(elementNode)
-               return []
-       geometryOutput = []
-       for textComplexLoop in svg_reader.getTextComplexLoops(derivation.fontFamily, derivation.fontSize, derivation.textString):
-               textComplexLoop.reverse()
-               vector3Path = euclidean.getVector3Path(textComplexLoop)
-               sideLoop = lineation.SideLoop(vector3Path)
-               sideLoop.rotate(elementNode)
-               geometryOutput += lineation.getGeometryOutputByManipulation(elementNode, sideLoop)
-       return geometryOutput
-
-def getGeometryOutputByArguments(arguments, elementNode):
-       "Get vector3 vertexes from attribute dictionary by arguments."
-       evaluate.setAttributesByArguments(['text', 'fontSize', 'fontFamily'], arguments, elementNode)
-       return getGeometryOutput(None, elementNode)
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return TextDerivation(elementNode)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       path.convertElementNode(elementNode, getGeometryOutput(None, elementNode))
-
-
-class TextDerivation(object):
-       "Class to hold text variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.fontFamily = evaluate.getEvaluatedString('Gentium Basic Regular', elementNode, 'font-family')
-               self.fontFamily = evaluate.getEvaluatedString(self.fontFamily, elementNode, 'fontFamily')
-               self.fontSize = evaluate.getEvaluatedFloat(12.0, elementNode, 'font-size')
-               self.fontSize = evaluate.getEvaluatedFloat(self.fontSize, elementNode, 'fontSize')
-               self.textString = elementNode.getTextContent()
-               self.textString = evaluate.getEvaluatedString(self.textString, elementNode, 'text')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/dictionary.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/dictionary.py
deleted file mode 100644 (file)
index 5036ad5..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-"""
-Boolean geometry dictionary object.
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import xml_simple_writer
-import cStringIO
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getAllPaths(paths, xmlObject):
-       'Get all paths.'
-       for archivableObject in xmlObject.archivableObjects:
-               paths += archivableObject.getPaths()
-       return paths
-
-def getAllTransformedPaths(transformedPaths, xmlObject):
-       'Get all transformed paths.'
-       for archivableObject in xmlObject.archivableObjects:
-               transformedPaths += archivableObject.getTransformedPaths()
-       return transformedPaths
-
-def getAllTransformedVertexes(transformedVertexes, xmlObject):
-       'Get all transformed vertexes.'
-       for archivableObject in xmlObject.archivableObjects:
-               transformedVertexes += archivableObject.getTransformedVertexes()
-       return transformedVertexes
-
-def getAllVertexes(vertexes, xmlObject):
-       'Get all vertexes.'
-       for archivableObject in xmlObject.archivableObjects:
-               vertexes += archivableObject.getVertexes()
-       return vertexes
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       evaluate.processArchivable( Dictionary, elementNode)
-
-
-class Dictionary(object):
-       'A dictionary object.'
-       def __init__(self):
-               'Add empty lists.'
-               self.archivableObjects = []
-               self.elementNode = None
-
-       def __repr__(self):
-               'Get the string representation of this object info.'
-               output = xml_simple_writer.getBeginGeometryXMLOutput(self.elementNode)
-               self.addXML( 1, output )
-               return xml_simple_writer.getEndGeometryXMLString(output)
-
-       def addXML(self, depth, output):
-               'Add xml for this object.'
-               attributeCopy = {}
-               if self.elementNode != None:
-                       attributeCopy = evaluate.getEvaluatedDictionaryByCopyKeys(['paths', 'target', 'vertexes'], self.elementNode)
-               euclidean.removeElementsFromDictionary(attributeCopy, matrix.getKeysM())
-               euclidean.removeTrueFromDictionary(attributeCopy, 'visible')
-               innerOutput = cStringIO.StringIO()
-               self.addXMLInnerSection(depth + 1, innerOutput)
-               self.addXMLArchivableObjects(depth + 1, innerOutput)
-               xml_simple_writer.addBeginEndInnerXMLTag(attributeCopy, depth, innerOutput.getvalue(), self.getXMLLocalName(), output)
-
-       def addXMLArchivableObjects(self, depth, output):
-               'Add xml for this object.'
-               xml_simple_writer.addXMLFromObjects( depth, self.archivableObjects, output )
-
-       def addXMLInnerSection(self, depth, output):
-               'Add xml section for this object.'
-               pass
-
-       def createShape(self):
-               'Create the shape.'
-               pass
-
-       def getAttributes(self):
-               'Get attribute table.'
-               if self.elementNode == None:
-                       return {}
-               return self.elementNode.attributes
-
-       def getComplexTransformedPathLists(self):
-               'Get complex transformed path lists.'
-               complexTransformedPathLists = []
-               for archivableObject in self.archivableObjects:
-                       complexTransformedPathLists.append(euclidean.getComplexPaths(archivableObject.getTransformedPaths()))
-               return complexTransformedPathLists
-
-       def getFabricationExtension(self):
-               'Get fabrication extension.'
-               return 'xml'
-
-       def getFabricationText(self, addLayerTemplate):
-               'Get fabrication text.'
-               return self.__repr__()
-
-       def getGeometryOutput(self):
-               'Get geometry output dictionary.'
-               shapeOutput = []
-               for visibleObject in evaluate.getVisibleObjects(self.archivableObjects):
-                       geometryOutput = visibleObject.getGeometryOutput()
-                       if geometryOutput != None:
-                               visibleObject.transformGeometryOutput(geometryOutput)
-                               shapeOutput.append(geometryOutput)
-               if len(shapeOutput) < 1:
-                       return None
-               return {self.getXMLLocalName() : {'shapes' : shapeOutput}}
-
-       def getMatrix4X4(self):
-               "Get the matrix4X4."
-               return None
-
-       def getMatrixChainTetragrid(self):
-               'Get the matrix chain tetragrid.'
-               return self.elementNode.parentNode.xmlObject.getMatrixChainTetragrid()
-
-       def getMinimumZ(self):
-               'Get the minimum z.'
-               return None
-
-       def getPaths(self):
-               'Get all paths.'
-               return getAllPaths([], self)
-
-       def getTransformedPaths(self):
-               'Get all transformed paths.'
-               return getAllTransformedPaths([], self)
-
-       def getTransformedVertexes(self):
-               'Get all transformed vertexes.'
-               return getAllTransformedVertexes([], self)
-
-       def getTriangleMeshes(self):
-               'Get all triangleMeshes.'
-               triangleMeshes = []
-               for archivableObject in self.archivableObjects:
-                       triangleMeshes += archivableObject.getTriangleMeshes()
-               return triangleMeshes
-
-       def getType(self):
-               'Get type.'
-               return self.__class__.__name__
-
-       def getVertexes(self):
-               'Get all vertexes.'
-               return getAllVertexes([], self)
-
-       def getVisible(self):
-               'Get visible.'
-               return False
-
-       def getXMLLocalName(self):
-               'Get xml local name.'
-               return self.__class__.__name__.lower()
-
-       def setToElementNode(self, elementNode):
-               'Set the shape of this carvable object info.'
-               self.elementNode = elementNode
-               elementNode.parentNode.xmlObject.archivableObjects.append(self)
-
-       def transformGeometryOutput(self, geometryOutput):
-               'Transform the geometry output by the local matrix4x4.'
-               if self.getMatrix4X4() != None:
-                       matrix.transformVector3sByMatrix(self.getMatrix4X4().tetragrid, matrix.getVertexes(geometryOutput))
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/face.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/face.py
deleted file mode 100644 (file)
index 3e85fd3..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-"""
-Face of a triangle mesh.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities import xml_simple_reader
-from fabmetheus_utilities import xml_simple_writer
-import cStringIO
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addFaces(geometryOutput, faces):
-       'Add the faces.'
-       if geometryOutput.__class__ == list:
-               for element in geometryOutput:
-                       addFaces(element, faces)
-               return
-       if geometryOutput.__class__ != dict:
-               return
-       for geometryOutputKey in geometryOutput.keys():
-               geometryOutputValue = geometryOutput[geometryOutputKey]
-               if geometryOutputKey == 'face':
-                       for face in geometryOutputValue:
-                               faces.append(face)
-               else:
-                       addFaces(geometryOutputValue, faces)
-
-def addGeometryList(elementNode, faces):
-       "Add vertex elements to an xml element."
-       for face in faces:
-               faceElement = xml_simple_reader.ElementNode()
-               face.addToAttributes( faceElement.attributes )
-               faceElement.localName = 'face'
-               faceElement.parentNode = elementNode
-               elementNode.childNodes.append( faceElement )
-
-def getCommonVertexIndex( edgeFirst, edgeSecond ):
-       "Get the vertex index that both edges have in common."
-       for edgeFirstVertexIndex in edgeFirst.vertexIndexes:
-               if edgeFirstVertexIndex == edgeSecond.vertexIndexes[0] or edgeFirstVertexIndex == edgeSecond.vertexIndexes[1]:
-                       return edgeFirstVertexIndex
-       print("Inconsistent GNU Triangulated Surface")
-       print(edgeFirst)
-       print(edgeSecond)
-       return 0
-
-def getFaces(geometryOutput):
-       'Get the faces.'
-       faces = []
-       addFaces(geometryOutput, faces)
-       return faces
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       face = Face()
-       face.index = len(elementNode.parentNode.xmlObject.faces)
-       for vertexIndexIndex in xrange(3):
-               face.vertexIndexes.append(evaluate.getEvaluatedInt(None, elementNode, 'vertex' + str(vertexIndexIndex)))
-       elementNode.parentNode.xmlObject.faces.append(face)
-
-
-class Edge(object):
-       "An edge of a triangle mesh."
-       def __init__(self):
-               "Set the face indexes to None."
-               self.faceIndexes = []
-               self.vertexIndexes = []
-               self.zMaximum = None
-               self.zMinimum = None
-       
-       def __repr__(self):
-               "Get the string representation of this Edge."
-               return str( self.index ) + ' ' + str( self.faceIndexes ) + ' ' + str(self.vertexIndexes)
-
-       def addFaceIndex( self, faceIndex ):
-               "Add first None face index to input face index."
-               self.faceIndexes.append( faceIndex )
-
-       def getFromVertexIndexes( self, edgeIndex, vertexIndexes ):
-               "Initialize from two vertex indices."
-               self.index = edgeIndex
-               self.vertexIndexes = vertexIndexes[:]
-               self.vertexIndexes.sort()
-               return self
-
-
-class Face(object):
-       "A face of a triangle mesh."
-       def __init__(self):
-               "Initialize."
-               self.edgeIndexes = []
-               self.index = None
-               self.vertexIndexes = []
-
-       def __repr__(self):
-               "Get the string representation of this object info."
-               output = cStringIO.StringIO()
-               self.addXML( 2, output )
-               return output.getvalue()
-
-       def addToAttributes(self, attributes):
-               "Add to the attribute dictionary."
-               for vertexIndexIndex in xrange(len(self.vertexIndexes)):
-                       vertexIndex = self.vertexIndexes[vertexIndexIndex]
-                       attributes['vertex' + str(vertexIndexIndex)] = str(vertexIndex)
-
-       def addXML(self, depth, output):
-               "Add the xml for this object."
-               attributes = {}
-               self.addToAttributes(attributes)
-               xml_simple_writer.addClosedXMLTag( attributes, depth, 'face', output )
-
-       def copy(self):
-               'Get the copy of this face.'
-               faceCopy = Face()
-               faceCopy.edgeIndexes = self.edgeIndexes[:]
-               faceCopy.index = self.index
-               faceCopy.vertexIndexes = self.vertexIndexes[:]
-               return faceCopy
-
-       def getFromEdgeIndexes( self, edgeIndexes, edges, faceIndex ):
-               "Initialize from edge indices."
-               if len(self.vertexIndexes) > 0:
-                       return
-               self.index = faceIndex
-               self.edgeIndexes = edgeIndexes
-               for edgeIndex in edgeIndexes:
-                       edges[ edgeIndex ].addFaceIndex( faceIndex )
-               for triangleIndex in xrange(3):
-                       indexFirst = ( 3 - triangleIndex ) % 3
-                       indexSecond = ( 4 - triangleIndex ) % 3
-                       self.vertexIndexes.append( getCommonVertexIndex( edges[ edgeIndexes[ indexFirst ] ], edges[ edgeIndexes[ indexSecond ] ] ) )
-               return self
-
-       def setEdgeIndexesToVertexIndexes( self, edges, edgeTable ):
-               "Set the edge indexes to the vertex indexes."
-               if len(self.edgeIndexes) > 0:
-                       return
-               for triangleIndex in xrange(3):
-                       indexFirst = ( 3 - triangleIndex ) % 3
-                       indexSecond = ( 4 - triangleIndex ) % 3
-                       vertexIndexFirst = self.vertexIndexes[ indexFirst ]
-                       vertexIndexSecond = self.vertexIndexes[ indexSecond ]
-                       vertexIndexPair = [ vertexIndexFirst, vertexIndexSecond ]
-                       vertexIndexPair.sort()
-                       edgeIndex = len( edges )
-                       if str( vertexIndexPair ) in edgeTable:
-                               edgeIndex = edgeTable[ str( vertexIndexPair ) ]
-                       else:
-                               edgeTable[ str( vertexIndexPair ) ] = edgeIndex
-                               edge = Edge().getFromVertexIndexes( edgeIndex, vertexIndexPair )
-                               edges.append( edge )
-                       edges[ edgeIndex ].addFaceIndex( self.index )
-                       self.edgeIndexes.append( edgeIndex )
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/path.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/path.py
deleted file mode 100644 (file)
index ea7366c..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-"""
-Path.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_tools import dictionary
-from fabmetheus_utilities.geometry.geometry_tools import vertex
-from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import svg_writer
-from fabmetheus_utilities import xml_simple_reader
-from fabmetheus_utilities import xml_simple_writer
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def convertElementNode(elementNode, geometryOutput):
-       'Convert the xml element by geometryOutput.'
-       if geometryOutput == None:
-               return
-       if len(geometryOutput) < 1:
-               return
-       if len(geometryOutput) == 1:
-               firstLoop = geometryOutput[0]
-               if firstLoop.__class__ == list:
-                       geometryOutput = firstLoop
-       firstElement = geometryOutput[0]
-       if firstElement.__class__ == list:
-               if len(firstElement) > 1:
-                       convertElementNodeRenameByPaths(elementNode, geometryOutput)
-               else:
-                       convertElementNodeByPath(elementNode, firstElement)
-       else:
-               convertElementNodeByPath(elementNode, geometryOutput)
-
-def convertElementNodeByPath(elementNode, geometryOutput):
-       'Convert the xml element to a path xml element.'
-       createLinkPath(elementNode)
-       elementNode.xmlObject.vertexes = geometryOutput
-       vertex.addGeometryList(elementNode, geometryOutput)
-
-def convertElementNodeRenameByPaths(elementNode, geometryOutput):
-       'Convert the xml element to a path xml element and add paths.'
-       createLinkPath(elementNode)
-       for geometryOutputChild in geometryOutput:
-               pathElement = xml_simple_reader.ElementNode()
-               pathElement.setParentAddToChildNodes(elementNode)
-               convertElementNodeByPath(pathElement, geometryOutputChild)
-
-def createLinkPath(elementNode):
-       'Create and link a path object.'
-       elementNode.localName = 'path'
-       elementNode.linkObject(Path())
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       evaluate.processArchivable(Path, elementNode)
-
-
-class Path(dictionary.Dictionary):
-       'A path.'
-       def __init__(self):
-               'Add empty lists.'
-               dictionary.Dictionary.__init__(self)
-               self.matrix4X4 = matrix.Matrix()
-               self.oldChainTetragrid = None
-               self.transformedPath = None
-               self.vertexes = []
-
-       def addXMLInnerSection(self, depth, output):
-               'Add the xml section for this object.'
-               if self.matrix4X4 != None:
-                       self.matrix4X4.addXML(depth, output)
-               xml_simple_writer.addXMLFromVertexes(depth, output, self.vertexes)
-
-       def getFabricationExtension(self):
-               'Get fabrication extension.'
-               return 'svg'
-
-       def getFabricationText(self, addLayerTemplate):
-               'Get fabrication text.'
-               carving = SVGFabricationCarving(addLayerTemplate, self.elementNode)
-               carving.setCarveLayerHeight(setting.getSheetThickness(self.elementNode))
-               carving.processSVGElement(self.elementNode.getOwnerDocument().fileName)
-               return str(carving)
-
-       def getMatrix4X4(self):
-               "Get the matrix4X4."
-               return self.matrix4X4
-
-       def getMatrixChainTetragrid(self):
-               'Get the matrix chain tetragrid.'
-               return matrix.getTetragridTimesOther(self.elementNode.parentNode.xmlObject.getMatrixChainTetragrid(), self.matrix4X4.tetragrid)
-
-       def getPaths(self):
-               'Get all paths.'
-               self.transformedPath = None
-               if len(self.vertexes) > 0:
-                       return dictionary.getAllPaths([self.vertexes], self)
-               return dictionary.getAllPaths([], self)
-
-       def getTransformedPaths(self):
-               'Get all transformed paths.'
-               if self.elementNode == None:
-                       return dictionary.getAllPaths([self.vertexes], self)
-               chainTetragrid = self.getMatrixChainTetragrid()
-               if self.oldChainTetragrid != chainTetragrid:
-                       self.oldChainTetragrid = chainTetragrid
-                       self.transformedPath = None
-               if self.transformedPath == None:
-                       self.transformedPath = matrix.getTransformedVector3s(chainTetragrid, self.vertexes)
-               if len(self.transformedPath) > 0:
-                       return dictionary.getAllTransformedPaths([self.transformedPath], self)
-               return dictionary.getAllTransformedPaths([], self)
-
-
-class SVGFabricationCarving(object):
-       'An svg carving.'
-       def __init__(self, addLayerTemplate, elementNode):
-               'Add empty lists.'
-               self.addLayerTemplate = addLayerTemplate
-               self.elementNode = elementNode
-               self.layerHeight = 1.0
-               self.loopLayers = []
-
-       def __repr__(self):
-               'Get the string representation of this carving.'
-               return self.getCarvedSVG()
-
-       def addXML(self, depth, output):
-               'Add xml for this object.'
-               xml_simple_writer.addXMLFromObjects(depth, self.loopLayers, output)
-
-       def getCarveBoundaryLayers(self):
-               'Get the  boundary layers.'
-               return self.loopLayers
-
-       def getCarveCornerMaximum(self):
-               'Get the corner maximum of the vertexes.'
-               return self.cornerMaximum
-
-       def getCarveCornerMinimum(self):
-               'Get the corner minimum of the vertexes.'
-               return self.cornerMinimum
-
-       def getCarvedSVG(self):
-               'Get the carved svg text.'
-               return svg_writer.getSVGByLoopLayers(self.addLayerTemplate, self, self.loopLayers)
-
-       def getCarveLayerHeight(self):
-               'Get the layer height.'
-               return self.layerHeight
-
-       def getFabmetheusXML(self):
-               'Return the fabmetheus XML.'
-               return self.elementNode.getOwnerDocument().getOriginalRoot()
-
-       def getInterpretationSuffix(self):
-               'Return the suffix for a carving.'
-               return 'svg'
-
-       def processSVGElement(self, fileName):
-               'Parse SVG element and store the layers.'
-               self.fileName = fileName
-               paths = self.elementNode.xmlObject.getPaths()
-               oldZ = None
-               self.loopLayers = []
-               loopLayer = None
-               for path in paths:
-                       if len(path) > 0:
-                               z = path[0].z
-                               if z != oldZ:
-                                       loopLayer = euclidean.LoopLayer(z)
-                                       self.loopLayers.append(loopLayer)
-                                       oldZ = z
-                               loopLayer.loops.append(euclidean.getComplexPath(path))
-               if len(self.loopLayers) < 1:
-                       return
-               self.cornerMaximum = Vector3(-987654321.0, -987654321.0, -987654321.0)
-               self.cornerMinimum = Vector3(987654321.0, 987654321.0, 987654321.0)
-               svg_writer.setSVGCarvingCorners(self.cornerMaximum, self.cornerMinimum, self.layerHeight, self.loopLayers)
-
-       def setCarveImportRadius( self, importRadius ):
-               'Set the import radius.'
-               pass
-
-       def setCarveIsCorrectMesh( self, isCorrectMesh ):
-               'Set the is correct mesh flag.'
-               pass
-
-       def setCarveLayerHeight( self, layerHeight ):
-               'Set the layer height.'
-               self.layerHeight = layerHeight
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/path_elements/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/path_elements/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/path_elements/arc.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/path_elements/arc.py
deleted file mode 100644 (file)
index 290f63a..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-"""
-Arc vertexes.
-
-From:
-http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import svg_reader
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getArcPath(elementNode):
-       "Get the arc path.rx ry x-axis-rotation large-arc-flag sweep-flag"
-       begin = elementNode.getPreviousVertex(Vector3())
-       end = evaluate.getVector3FromElementNode(elementNode)
-       largeArcFlag = evaluate.getEvaluatedBoolean(True, elementNode, 'largeArcFlag')
-       radius = lineation.getComplexByPrefix(elementNode, 'radius', complex(1.0, 1.0))
-       sweepFlag = evaluate.getEvaluatedBoolean(True, elementNode, 'sweepFlag')
-       xAxisRotation = math.radians(evaluate.getEvaluatedFloat(0.0, elementNode, 'xAxisRotation'))
-       arcComplexes = svg_reader.getArcComplexes(begin.dropAxis(), end.dropAxis(), largeArcFlag, radius, sweepFlag, xAxisRotation)
-       path = []
-       if len(arcComplexes) < 1:
-               return []
-       incrementZ = (end.z - begin.z) / float(len(arcComplexes))
-       z = begin.z
-       for pointIndex in xrange(len(arcComplexes)):
-               pointComplex = arcComplexes[pointIndex]
-               z += incrementZ
-               path.append(Vector3(pointComplex.real, pointComplex.imag, z))
-       if len(path) > 0:
-               path[-1] = end
-       return path
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       elementNode.parentNode.xmlObject.vertexes += getArcPath(elementNode)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/path_elements/cubic.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/path_elements/cubic.py
deleted file mode 100644 (file)
index 6e3fef1..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-"""
-Cubic vertexes.
-
-From:
-http://www.w3.org/TR/SVG/paths.html#PathDataCubicBezierCommands
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import svg_reader
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCubicPath(elementNode):
-       "Get the cubic path."
-       end = evaluate.getVector3FromElementNode(elementNode)
-       previousElementNode = elementNode.getPreviousElementNode()
-       if previousElementNode == None:
-               print('Warning, can not get previousElementNode in getCubicPath in cubic for:')
-               print(elementNode)
-               return [end]
-       begin = elementNode.getPreviousVertex(Vector3())
-       evaluatedControlPoints = evaluate.getTransformedPathByKey([], elementNode, 'controlPoints')
-       if len(evaluatedControlPoints) > 1:
-               return getCubicPathByBeginEnd(begin, evaluatedControlPoints, elementNode, end)
-       controlPoint0 = evaluate.getVector3ByPrefix(None, elementNode, 'controlPoint0')
-       controlPoint1 = evaluate.getVector3ByPrefix(None, elementNode, 'controlPoint1')
-       if len(evaluatedControlPoints) == 1:
-               controlPoint1 = evaluatedControlPoints[0]
-       if controlPoint0 == None:
-               oldControlPoint = evaluate.getVector3ByPrefixes(previousElementNode, ['controlPoint','controlPoint1'], None)
-               if oldControlPoint == None:
-                       oldControlPoints = evaluate.getTransformedPathByKey([], previousElementNode, 'controlPoints')
-                       if len(oldControlPoints) > 0:
-                               oldControlPoint = oldControlPoints[-1]
-               if oldControlPoint == None:
-                       oldControlPoint = end
-               controlPoint0 = begin + begin - oldControlPoint
-       return getCubicPathByBeginEnd(begin, [controlPoint0, controlPoint1], elementNode, end)
-
-def getCubicPathByBeginEnd(begin, controlPoints, elementNode, end):
-       "Get the cubic path by begin and end."
-       return svg_reader.getCubicPoints(begin, controlPoints, end, lineation.getNumberOfBezierPoints(begin, elementNode, end))
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       elementNode.parentNode.xmlObject.vertexes += getCubicPath(elementNode)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/path_elements/quadratic.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/path_elements/quadratic.py
deleted file mode 100644 (file)
index de7e9c0..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-"""
-Quadratic vertexes.
-
-From:
-http://www.w3.org/TR/SVG/paths.html#PathDataQuadraticBezierCommands
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import svg_reader
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getQuadraticPath(elementNode):
-       "Get the quadratic path."
-       end = evaluate.getVector3FromElementNode(elementNode)
-       previousElementNode = elementNode.getPreviousElementNode()
-       if previousElementNode == None:
-               print('Warning, can not get previousElementNode in getQuadraticPath in quadratic for:')
-               print(elementNode)
-               return [end]
-       begin = elementNode.getPreviousVertex(Vector3())
-       controlPoint = evaluate.getVector3ByPrefix(None, elementNode, 'controlPoint')
-       if controlPoint == None:
-               oldControlPoint = evaluate.getVector3ByPrefixes(previousElementNode, ['controlPoint','controlPoint1'], None)
-               if oldControlPoint == None:
-                       oldControlPoint = end
-               controlPoint = begin + begin - oldControlPoint
-               evaluate.addVector3ToElementNode(elementNode, 'controlPoint', controlPoint)
-       return svg_reader.getQuadraticPoints(begin, controlPoint, end, lineation.getNumberOfBezierPoints(begin, elementNode, end))
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       elementNode.parentNode.xmlObject.vertexes += getQuadraticPath(elementNode)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/vertex.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_tools/vertex.py
deleted file mode 100644 (file)
index 8fd7efd..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-"""
-Vertex of a triangle mesh.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities import xml_simple_reader
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addGeometryList(elementNode, vertexes):
-       "Add vertex elements to an xml element."
-       for vertex in vertexes:
-               vertexElement = getUnboundVertexElement(vertex)
-               vertexElement.parentNode = elementNode
-               elementNode.childNodes.append( vertexElement )
-
-def addVertexToAttributes(attributes, vertex):
-       "Add to the attribute dictionary."
-       if vertex.x != 0.0:
-               attributes['x'] = str(vertex.x)
-       if vertex.y != 0.0:
-               attributes['y'] = str(vertex.y)
-       if vertex.z != 0.0:
-               attributes['z'] = str(vertex.z)
-
-def getUnboundVertexElement(vertex):
-       "Add vertex element to an xml element."
-       vertexElement = xml_simple_reader.ElementNode()
-       addVertexToAttributes(vertexElement.attributes, vertex)
-       vertexElement.localName = 'vertex'
-       return vertexElement
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       elementNode.parentNode.xmlObject.vertexes.append(evaluate.getVector3FromElementNode(elementNode))
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/boolean_geometry.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/boolean_geometry.py
deleted file mode 100644 (file)
index 0e64464..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-"""
-This page is in the table of contents.
-The xml.py script is an import translator plugin to get a carving from an Art of Illusion xml file.
-
-An import plugin is a script in the interpret_plugins folder which has the function getCarving.  It is meant to be run from the interpret tool.  To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.
-
-The getCarving function takes the file name of an xml file and returns the carving.
-
-An xml file can be exported from Art of Illusion by going to the "File" menu, then going into the "Export" menu item, then picking the XML choice.  This will bring up the XML file chooser window, choose a place to save the file then click "OK".  Leave the "compressFile" checkbox unchecked.  All the objects from the scene will be exported, this plugin will ignore the light and camera.  If you want to fabricate more than one object at a time, you can have multiple objects in the Art of Illusion scene and they will all be carved, then fabricated together.
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting
-from fabmetheus_utilities.geometry.geometry_utilities import boolean_solid
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import xml_simple_writer
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getEmptyZLoops(archivableObjects, importRadius, shouldPrintWarning, z, zoneArrangement):
-       'Get loops at empty z level.'
-       emptyZ = zoneArrangement.getEmptyZ(z)
-       visibleObjects = evaluate.getVisibleObjects(archivableObjects)
-       visibleObjectLoopsList = boolean_solid.getVisibleObjectLoopsList(importRadius, visibleObjects, emptyZ)
-       loops = euclidean.getConcatenatedList(visibleObjectLoopsList)
-       if euclidean.isLoopListIntersecting(loops):
-               loops = boolean_solid.getLoopsUnion(importRadius, visibleObjectLoopsList)
-               if shouldPrintWarning:
-                       print('Warning, the triangle mesh slice intersects itself in getExtruderPaths in boolean_geometry.')
-                       print('Something will still be printed, but there is no guarantee that it will be the correct shape.')
-                       print('Once the gcode is saved, you should check over the layer with a z of:')
-                       print(z)
-       return loops
-
-def getLoopLayers(archivableObjects, importRadius, layerHeight, maximumZ, shouldPrintWarning, z, zoneArrangement):
-       'Get loop layers.'
-       loopLayers = []
-       while z <= maximumZ:
-               triangle_mesh.getLoopLayerAppend(loopLayers, z).loops = getEmptyZLoops(archivableObjects, importRadius, True, z, zoneArrangement)
-               z += layerHeight
-       return loopLayers
-
-def getMinimumZ(geometryObject):
-       'Get the minimum of the minimum z of the archivableObjects and the object.'
-       booleanGeometry = BooleanGeometry()
-       booleanGeometry.archivableObjects = geometryObject.archivableObjects
-       booleanGeometry.importRadius = setting.getImportRadius(geometryObject.elementNode)
-       booleanGeometry.layerHeight = setting.getLayerHeight(geometryObject.elementNode)
-       archivableMinimumZ = booleanGeometry.getMinimumZ()
-       geometryMinimumZ = geometryObject.getMinimumZ()
-       if archivableMinimumZ == None:
-               return geometryMinimumZ
-       if geometryMinimumZ == None:
-               return archivableMinimumZ
-       return min(archivableMinimumZ, geometryMinimumZ)
-
-
-class BooleanGeometry(object):
-       'A boolean geometry scene.'
-       def __init__(self):
-               'Add empty lists.'
-               self.archivableObjects = []
-               self.belowLoops = []
-               self.importRadius = 0.6
-               self.layerHeight = 0.4
-               self.loopLayers = []
-
-       def __repr__(self):
-               'Get the string representation of this carving.'
-               elementNode = None
-               if len(self.archivableObjects) > 0:
-                       elementNode = self.archivableObjects[0].elementNode
-               output = xml_simple_writer.getBeginGeometryXMLOutput(elementNode)
-               self.addXML( 1, output )
-               return xml_simple_writer.getEndGeometryXMLString(output)
-
-       def addXML(self, depth, output):
-               'Add xml for this object.'
-               xml_simple_writer.addXMLFromObjects( depth, self.archivableObjects, output )
-
-       def getCarveBoundaryLayers(self):
-               'Get the boundary layers.'
-               if self.getMinimumZ() == None:
-                       return []
-               z = self.minimumZ + 0.5 * self.layerHeight
-               self.loopLayers = getLoopLayers(self.archivableObjects, self.importRadius, self.layerHeight, self.maximumZ, True, z, self.zoneArrangement)
-               self.cornerMaximum = Vector3(-912345678.0, -912345678.0, -912345678.0)
-               self.cornerMinimum = Vector3(912345678.0, 912345678.0, 912345678.0)
-               for loopLayer in self.loopLayers:
-                       for loop in loopLayer.loops:
-                               for point in loop:
-                                       pointVector3 = Vector3(point.real, point.imag, loopLayer.z)
-                                       self.cornerMaximum.maximize(pointVector3)
-                                       self.cornerMinimum.minimize(pointVector3)
-               self.cornerMaximum.z += self.halfHeight
-               self.cornerMinimum.z -= self.halfHeight
-               for loopLayerIndex in xrange(len(self.loopLayers) -1, -1, -1):
-                       loopLayer = self.loopLayers[loopLayerIndex]
-                       if len(loopLayer.loops) > 0:
-                               return self.loopLayers[: loopLayerIndex + 1]
-               return []
-
-       def getCarveCornerMaximum(self):
-               'Get the corner maximum of the vertexes.'
-               return self.cornerMaximum
-
-       def getCarveCornerMinimum(self):
-               'Get the corner minimum of the vertexes.'
-               return self.cornerMinimum
-
-       def getCarveLayerHeight(self):
-               'Get the layer height.'
-               return self.layerHeight
-
-       def getFabmetheusXML(self):
-               'Return the fabmetheus XML.'
-               if len(self.archivableObjects) > 0:
-                       return self.archivableObjects[0].elementNode.getOwnerDocument().getOriginalRoot()
-               return None
-
-       def getInterpretationSuffix(self):
-               'Return the suffix for a boolean carving.'
-               return 'xml'
-
-       def getMatrix4X4(self):
-               'Get the matrix4X4.'
-               return None
-
-       def getMatrixChainTetragrid(self):
-               'Get the matrix chain tetragrid.'
-               return None
-
-       def getMinimumZ(self):
-               'Get the minimum z.'
-               vertexes = []
-               for visibleObject in evaluate.getVisibleObjects(self.archivableObjects):
-                       vertexes += visibleObject.getTransformedVertexes()
-               if len(vertexes) < 1:
-                       return None
-               self.maximumZ = -912345678.0
-               self.minimumZ = 912345678.0
-               for vertex in vertexes:
-                       self.maximumZ = max(self.maximumZ, vertex.z)
-                       self.minimumZ = min(self.minimumZ, vertex.z)
-               self.zoneArrangement = triangle_mesh.ZoneArrangement(self.layerHeight, vertexes)
-               self.halfHeight = 0.5 * self.layerHeight
-               self.setActualMinimumZ()
-               return self.minimumZ
-
-       def getNumberOfEmptyZLoops(self, z):
-               'Get number of empty z loops.'
-               return len(getEmptyZLoops(self.archivableObjects, self.importRadius, False, z, self.zoneArrangement))
-
-       def setActualMinimumZ(self):
-               'Get the actual minimum z at the lowest rotated boundary layer.'
-               halfHeightOverMyriad = 0.0001 * self.halfHeight
-               while self.minimumZ < self.maximumZ:
-                       if self.getNumberOfEmptyZLoops(self.minimumZ + halfHeightOverMyriad) > 0:
-                               if self.getNumberOfEmptyZLoops(self.minimumZ - halfHeightOverMyriad) < 1:
-                                       return
-                               increment = -self.halfHeight
-                               while abs(increment) > halfHeightOverMyriad:
-                                       self.minimumZ += increment
-                                       increment = 0.5 * abs(increment)
-                                       if self.getNumberOfEmptyZLoops(self.minimumZ) > 0:
-                                               increment = -increment
-                               self.minimumZ = round(self.minimumZ, -int(round(math.log10(halfHeightOverMyriad) + 1.5)))
-                               return
-                       self.minimumZ += self.layerHeight
-
-       def setCarveImportRadius( self, importRadius ):
-               'Set the import radius.'
-               self.importRadius = importRadius
-
-       def setCarveIsCorrectMesh( self, isCorrectMesh ):
-               'Set the is correct mesh flag.'
-               self.isCorrectMesh = isCorrectMesh
-
-       def setCarveLayerHeight( self, layerHeight ):
-               'Set the layer height.'
-               self.layerHeight = layerHeight
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/boolean_solid.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/boolean_solid.py
deleted file mode 100644 (file)
index 2128258..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-"""
-This page is in the table of contents.
-The xml.py script is an import translator plugin to get a carving from an Art of Illusion xml file.
-
-An import plugin is a script in the interpret_plugins folder which has the function getCarving.  It is meant to be run from the interpret tool.  To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.
-
-The getCarving function takes the file name of an xml file and returns the carving.
-
-An xml file can be exported from Art of Illusion by going to the "File" menu, then going into the "Export" menu item, then picking the XML choice.  This will bring up the XML file chooser window, choose a place to save the file then click "OK".  Leave the "compressFile" checkbox unchecked.  All the objects from the scene will be exported, this plugin will ignore the light and camera.  If you want to fabricate more than one object at a time, you can have multiple objects in the Art of Illusion scene and they will all be carved, then fabricated together.
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.solids import group
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import intercircle
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addLineLoopsIntersections( loopLoopsIntersections, loops, pointBegin, pointEnd ):
-       'Add intersections of the line with the loops.'
-       normalizedSegment = pointEnd - pointBegin
-       normalizedSegmentLength = abs( normalizedSegment )
-       if normalizedSegmentLength <= 0.0:
-               return
-       lineLoopsIntersections = []
-       normalizedSegment /= normalizedSegmentLength
-       segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag)
-       pointBeginRotated = segmentYMirror * pointBegin
-       pointEndRotated = segmentYMirror * pointEnd
-       addLoopsXSegmentIntersections( lineLoopsIntersections, loops, pointBeginRotated.real, pointEndRotated.real, segmentYMirror, pointBeginRotated.imag )
-       for lineLoopsIntersection in lineLoopsIntersections:
-               point = complex( lineLoopsIntersection, pointBeginRotated.imag ) * normalizedSegment
-               loopLoopsIntersections.append(point)
-
-def addLineXSegmentIntersection( lineLoopsIntersections, segmentFirstX, segmentSecondX, vector3First, vector3Second, y ):
-       'Add intersections of the line with the x segment.'
-       xIntersection = euclidean.getXIntersectionIfExists( vector3First, vector3Second, y )
-       if xIntersection == None:
-               return
-       if xIntersection < min( segmentFirstX, segmentSecondX ):
-               return
-       if xIntersection <= max( segmentFirstX, segmentSecondX ):
-               lineLoopsIntersections.append( xIntersection )
-
-def addLoopLoopsIntersections( loop, loopsLoopsIntersections, otherLoops ):
-       'Add intersections of the loop with the other loops.'
-       for pointIndex in xrange(len(loop)):
-               pointBegin = loop[pointIndex]
-               pointEnd = loop[(pointIndex + 1) % len(loop)]
-               addLineLoopsIntersections( loopsLoopsIntersections, otherLoops, pointBegin, pointEnd )
-
-def addLoopsXSegmentIntersections( lineLoopsIntersections, loops, segmentFirstX, segmentSecondX, segmentYMirror, y ):
-       'Add intersections of the loops with the x segment.'
-       for loop in loops:
-               addLoopXSegmentIntersections( lineLoopsIntersections, loop, segmentFirstX, segmentSecondX, segmentYMirror, y )
-
-def addLoopXSegmentIntersections( lineLoopsIntersections, loop, segmentFirstX, segmentSecondX, segmentYMirror, y ):
-       'Add intersections of the loop with the x segment.'
-       rotatedLoop = euclidean.getRotatedComplexes( segmentYMirror, loop )
-       for pointIndex in xrange( len( rotatedLoop ) ):
-               pointFirst = rotatedLoop[pointIndex]
-               pointSecond = rotatedLoop[ (pointIndex + 1) % len( rotatedLoop ) ]
-               addLineXSegmentIntersection( lineLoopsIntersections, segmentFirstX, segmentSecondX, pointFirst, pointSecond, y )
-
-def getInBetweenLoopsFromLoops(loops, radius):
-       'Get the in between loops from loops.'
-       inBetweenLoops = []
-       for loop in loops:
-               inBetweenLoop = []
-               for pointIndex in xrange(len(loop)):
-                       pointBegin = loop[pointIndex]
-                       pointEnd = loop[(pointIndex + 1) % len(loop)]
-                       intercircle.addPointsFromSegment(pointBegin, pointEnd, inBetweenLoop, radius)
-               inBetweenLoops.append(inBetweenLoop)
-       return inBetweenLoops
-
-def getInsetPointsByInsetLoop( insetLoop, inside, loops, radius ):
-       'Get the inset points of the inset loop inside the loops.'
-       insetPointsByInsetLoop = []
-       for pointIndex in xrange( len( insetLoop ) ):
-               pointBegin = insetLoop[ ( pointIndex + len( insetLoop ) - 1 ) % len( insetLoop ) ]
-               pointCenter = insetLoop[pointIndex]
-               pointEnd = insetLoop[ (pointIndex + 1) % len( insetLoop ) ]
-               if getIsInsetPointInsideLoops( inside, loops, pointBegin, pointCenter, pointEnd, radius ):
-                       insetPointsByInsetLoop.append( pointCenter )
-       return insetPointsByInsetLoop
-
-def getInsetPointsByInsetLoops( insetLoops, inside, loops, radius ):
-       'Get the inset points of the inset loops inside the loops.'
-       insetPointsByInsetLoops = []
-       for insetLoop in insetLoops:
-               insetPointsByInsetLoops += getInsetPointsByInsetLoop( insetLoop, inside, loops, radius )
-       return insetPointsByInsetLoops
-
-def getIsInsetPointInsideLoops( inside, loops, pointBegin, pointCenter, pointEnd, radius ):
-       'Determine if the inset point is inside the loops.'
-       centerMinusBegin = euclidean.getNormalized( pointCenter - pointBegin )
-       centerMinusBeginWiddershins = complex( - centerMinusBegin.imag, centerMinusBegin.real )
-       endMinusCenter = euclidean.getNormalized( pointEnd - pointCenter )
-       endMinusCenterWiddershins = complex( - endMinusCenter.imag, endMinusCenter.real )
-       widdershinsNormalized = euclidean.getNormalized( centerMinusBeginWiddershins + endMinusCenterWiddershins ) * radius
-       return euclidean.getIsInFilledRegion( loops,  pointCenter + widdershinsNormalized ) == inside
-
-def getLoopsDifference(importRadius, loopLists):
-       'Get difference loops.'
-       halfImportRadius = 0.5 * importRadius # so that there are no misses on shallow angles
-       radiusSide = 0.01 * importRadius
-       negativeLoops = getLoopsUnion(importRadius, loopLists[1 :])
-       intercircle.directLoops(False, negativeLoops)
-       positiveLoops = loopLists[0]
-       intercircle.directLoops(True, positiveLoops)
-       corners = getInsetPointsByInsetLoops(negativeLoops, True, positiveLoops, radiusSide)
-       corners += getInsetPointsByInsetLoops(positiveLoops, False, negativeLoops, radiusSide)
-       allPoints = corners[:]
-       allPoints += getInsetPointsByInsetLoops(getInBetweenLoopsFromLoops(negativeLoops, halfImportRadius), True, positiveLoops, radiusSide)
-       allPoints += getInsetPointsByInsetLoops(getInBetweenLoopsFromLoops(positiveLoops, halfImportRadius), False, negativeLoops, radiusSide)
-       return triangle_mesh.getDescendingAreaOrientedLoops(allPoints, corners, importRadius)
-
-def getLoopsIntersection(importRadius, loopLists):
-       'Get intersection loops.'
-       intercircle.directLoopLists(True, loopLists)
-       if len(loopLists) < 1:
-               return []
-       if len(loopLists) < 2:
-               return loopLists[0]
-       intercircle.directLoopLists(True, loopLists)
-       loopsIntersection = loopLists[0]
-       for loopList in loopLists[1 :]:
-               loopsIntersection = getLoopsIntersectionByPair(importRadius, loopsIntersection, loopList)
-       return loopsIntersection
-
-def getLoopsIntersectionByPair(importRadius, loopsFirst, loopsLast):
-       'Get intersection loops for a pair of loop lists.'
-       halfImportRadius = 0.5 * importRadius # so that there are no misses on shallow angles
-       radiusSide = 0.01 * importRadius
-       corners = []
-       corners += getInsetPointsByInsetLoops(loopsFirst, True, loopsLast, radiusSide)
-       corners += getInsetPointsByInsetLoops(loopsLast, True, loopsFirst, radiusSide)
-       allPoints = corners[:]
-       allPoints += getInsetPointsByInsetLoops(getInBetweenLoopsFromLoops(loopsFirst, halfImportRadius), True, loopsLast, radiusSide)
-       allPoints += getInsetPointsByInsetLoops(getInBetweenLoopsFromLoops(loopsLast, halfImportRadius), True, loopsFirst, radiusSide)
-       return triangle_mesh.getDescendingAreaOrientedLoops(allPoints, corners, importRadius)
-
-def getLoopsListsIntersections( loopsList ):
-       'Get intersections betweens the loops lists.'
-       loopsListsIntersections = []
-       for loopsIndex in xrange( len( loopsList ) ):
-               loops = loopsList[ loopsIndex ]
-               for otherLoops in loopsList[ : loopsIndex ]:
-                       loopsListsIntersections += getLoopsLoopsIntersections( loops, otherLoops )
-       return loopsListsIntersections
-
-def getLoopsLoopsIntersections( loops, otherLoops ):
-       'Get all the intersections of the loops with the other loops.'
-       loopsLoopsIntersections = []
-       for loop in loops:
-               addLoopLoopsIntersections( loop, loopsLoopsIntersections, otherLoops )
-       return loopsLoopsIntersections
-
-def getLoopsUnion(importRadius, loopLists):
-       'Get joined loops sliced through shape.'
-       allPoints = []
-       corners = getLoopsListsIntersections(loopLists)
-       radiusSideNegative = -0.01 * importRadius
-       intercircle.directLoopLists(True, loopLists)
-       for loopListIndex in xrange(len(loopLists)):
-               insetLoops = loopLists[ loopListIndex ]
-               inBetweenInsetLoops = getInBetweenLoopsFromLoops(insetLoops, importRadius)
-               otherLoops = euclidean.getConcatenatedList(loopLists[: loopListIndex] + loopLists[loopListIndex + 1 :])
-               corners += getInsetPointsByInsetLoops(insetLoops, False, otherLoops, radiusSideNegative)
-               allPoints += getInsetPointsByInsetLoops(inBetweenInsetLoops, False, otherLoops, radiusSideNegative)
-       allPoints += corners[:]
-       return triangle_mesh.getDescendingAreaOrientedLoops(allPoints, corners, importRadius)
-
-def getVisibleObjectLoopsList( importRadius, visibleObjects, z ):
-       'Get visible object loops list.'
-       visibleObjectLoopsList = []
-       for visibleObject in visibleObjects:
-               visibleObjectLoops = visibleObject.getLoops(importRadius, z)
-               visibleObjectLoopsList.append( visibleObjectLoops )
-       return visibleObjectLoopsList
-
-
-class BooleanSolid( group.Group ):
-       'A boolean solid object.'
-       def getDifference(self, importRadius, visibleObjectLoopsList):
-               'Get subtracted loops sliced through shape.'
-               return getLoopsDifference(importRadius, visibleObjectLoopsList)
-
-       def getIntersection(self, importRadius, visibleObjectLoopsList):
-               'Get intersected loops sliced through shape.'
-               return getLoopsIntersection(importRadius, visibleObjectLoopsList)
-
-       def getLoops(self, importRadius, z):
-               'Get loops sliced through shape.'
-               visibleObjects = evaluate.getVisibleObjects(self.archivableObjects)
-               if len( visibleObjects ) < 1:
-                       return []
-               visibleObjectLoopsList = getVisibleObjectLoopsList( importRadius, visibleObjects, z )
-               loops = self.getLoopsFromObjectLoopsList(importRadius, visibleObjectLoopsList)
-               return euclidean.getSimplifiedLoops( loops, importRadius )
-
-       def getLoopsFromObjectLoopsList(self, importRadius, visibleObjectLoopsList):
-               'Get loops from visible object loops list.'
-               return self.operationFunction(importRadius, visibleObjectLoopsList)
-
-       def getTransformedPaths(self):
-               'Get all transformed paths.'
-               importRadius = setting.getImportRadius(self.elementNode)
-               loopsFromObjectLoopsList = self.getLoopsFromObjectLoopsList(importRadius, self.getComplexTransformedPathLists())
-               return euclidean.getVector3Paths(loopsFromObjectLoopsList)
-
-       def getUnion(self, importRadius, visibleObjectLoopsList):
-               'Get joined loops sliced through shape.'
-               return getLoopsUnion(importRadius, visibleObjectLoopsList)
-
-       def getXMLLocalName(self):
-               'Get xml class name.'
-               return self.operationFunction.__name__.lower()[ len('get') : ]
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate.py
deleted file mode 100644 (file)
index cb2d356..0000000
+++ /dev/null
@@ -1,1935 +0,0 @@
-"""
-Evaluate expressions.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-import math
-import sys
-import traceback
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalModuleFunctionsDictionary = {}
-
-
-def addPrefixDictionary(dictionary, keys, value):
-       'Add prefixed key values to dictionary.'
-       for key in keys:
-               dictionary[key.lstrip('_')] = value
-
-def addQuoteWord(evaluatorWords, word):
-       'Add quote word and remainder if the word starts with a quote character or dollar sign, otherwise add the word.'
-       if len(word) < 2:
-               evaluatorWords.append(word)
-               return
-       firstCharacter = word[0]
-       if firstCharacter == '$':
-               dotIndex = word.find('.', 1)
-               if dotIndex > -1:
-                       evaluatorWords.append(word[: dotIndex])
-                       evaluatorWords.append(word[dotIndex :])
-                       return
-       if firstCharacter != '"' and firstCharacter != "'":
-               evaluatorWords.append(word)
-               return
-       nextQuoteIndex = word.find(firstCharacter, 1)
-       if nextQuoteIndex < 0 or nextQuoteIndex == len(word) - 1:
-               evaluatorWords.append(word)
-               return
-       nextQuoteIndex += 1
-       evaluatorWords.append(word[: nextQuoteIndex])
-       evaluatorWords.append(word[nextQuoteIndex :])
-
-def addToPathsRecursively(paths, vector3Lists):
-       'Add to vector3 paths recursively.'
-       if vector3Lists.__class__ == Vector3 or vector3Lists.__class__ .__name__ == 'Vector3Index':
-               paths.append([ vector3Lists ])
-               return
-       path = []
-       for vector3List in vector3Lists:
-               if vector3List.__class__ == list:
-                       addToPathsRecursively(paths, vector3List)
-               elif vector3List.__class__ == Vector3:
-                       path.append(vector3List)
-       if len(path) > 0:
-               paths.append(path)
-
-def addValueToEvaluatedDictionary(elementNode, evaluatedDictionary, key):
-       'Get the evaluated dictionary.'
-       value = getEvaluatedValueObliviously(elementNode, key)
-       if value == None:
-               valueString = str(elementNode.attributes[key])
-               print('Warning, addValueToEvaluatedDictionary in evaluate can not get a value for:')
-               print(valueString)
-               evaluatedDictionary[key + '__Warning__'] = 'Can not evaluate: ' + valueString.replace('"', ' ').replace( "'", ' ')
-       else:
-               evaluatedDictionary[key] = value
-
-def addVector3ToElementNode(elementNode, key, vector3):
-       'Add vector3 to xml element.'
-       elementNode.attributes[key] = '[%s,%s,%s]' % (vector3.x, vector3.y, vector3.z)
-
-def compareExecutionOrderAscending(module, otherModule):
-       'Get comparison in order to sort modules in ascending execution order.'
-       if module.globalExecutionOrder < otherModule.globalExecutionOrder:
-               return -1
-       if module.globalExecutionOrder > otherModule.globalExecutionOrder:
-               return 1
-       if module.__name__ < otherModule.__name__:
-               return -1
-       return int(module.__name__ > otherModule.__name__)
-
-def convertToPaths(dictionary):
-       'Recursively convert any ElementNodes to paths.'
-       if dictionary.__class__ == Vector3 or dictionary.__class__.__name__ == 'Vector3Index':
-               return
-       keys = getKeys(dictionary)
-       if keys == None:
-               return
-       for key in keys:
-               value = dictionary[key]
-               if value.__class__.__name__ == 'ElementNode':
-                       if value.xmlObject != None:
-                               dictionary[key] = getFloatListListsByPaths(value.xmlObject.getPaths())
-               else:
-                       convertToPaths(dictionary[key])
-
-def convertToTransformedPaths(dictionary):
-       'Recursively convert any ElementNodes to paths.'
-       if dictionary.__class__ == Vector3 or dictionary.__class__.__name__ == 'Vector3Index':
-               return
-       keys = getKeys(dictionary)
-       if keys == None:
-               return
-       for key in keys:
-               value = dictionary[key]
-               if value.__class__.__name__ == 'ElementNode':
-                       if value.xmlObject != None:
-                               dictionary[key] = value.xmlObject.getTransformedPaths()
-               else:
-                       convertToTransformedPaths(dictionary[key])
-
-def executeLeftOperations( evaluators, operationLevel ):
-       'Evaluate the expression value from the numeric and operation evaluators.'
-       for negativeIndex in xrange( - len(evaluators), - 1 ):
-               evaluatorIndex = negativeIndex + len(evaluators)
-               evaluators[evaluatorIndex].executeLeftOperation( evaluators, evaluatorIndex, operationLevel )
-
-def executeNextEvaluatorArguments(evaluator, evaluators, evaluatorIndex, nextEvaluator):
-       'Execute the nextEvaluator arguments.'
-       if evaluator.value == None:
-               print('Warning, executeNextEvaluatorArguments in evaluate can not get a evaluator.value for:')
-               print(evaluatorIndex)
-               print(evaluators)
-               print(evaluator)
-               return
-       nextEvaluator.value = evaluator.value(*nextEvaluator.arguments)
-       del evaluators[evaluatorIndex]
-
-def executePairOperations(evaluators, operationLevel):
-       'Evaluate the expression value from the numeric and operation evaluators.'
-       for negativeIndex in xrange(1 - len(evaluators), - 1):
-               evaluatorIndex = negativeIndex + len(evaluators)
-               evaluators[evaluatorIndex].executePairOperation(evaluators, evaluatorIndex, operationLevel)
-
-def getBracketEvaluators(bracketBeginIndex, bracketEndIndex, evaluators):
-       'Get the bracket evaluators.'
-       return getEvaluatedExpressionValueEvaluators(evaluators[bracketBeginIndex + 1 : bracketEndIndex])
-
-def getBracketsExist(evaluators):
-       'Evaluate the expression value.'
-       bracketBeginIndex = None
-       for negativeIndex in xrange( - len(evaluators), 0 ):
-               bracketEndIndex = negativeIndex + len(evaluators)
-               evaluatorEnd = evaluators[ bracketEndIndex ]
-               evaluatorWord = evaluatorEnd.word
-               if evaluatorWord in ['(', '[', '{']:
-                       bracketBeginIndex = bracketEndIndex
-               elif evaluatorWord in [')', ']', '}']:
-                       if bracketBeginIndex == None:
-                               print('Warning, bracketBeginIndex in evaluateBrackets in evaluate is None.')
-                               print('This may be because the brackets are not balanced.')
-                               print(evaluators)
-                               del evaluators[ bracketEndIndex ]
-                               return
-                       evaluators[ bracketBeginIndex ].executeBracket(bracketBeginIndex, bracketEndIndex, evaluators)
-                       evaluators[ bracketBeginIndex ].word = None
-                       return True
-       return False
-
-def getBracketValuesDeleteEvaluator(bracketBeginIndex, bracketEndIndex, evaluators):
-       'Get the bracket values and delete the evaluator.'
-       evaluatedExpressionValueEvaluators = getBracketEvaluators(bracketBeginIndex, bracketEndIndex, evaluators)
-       bracketValues = []
-       for evaluatedExpressionValueEvaluator in evaluatedExpressionValueEvaluators:
-               bracketValues.append( evaluatedExpressionValueEvaluator.value )
-       del evaluators[ bracketBeginIndex + 1: bracketEndIndex + 1 ]
-       return bracketValues
-
-def getCapitalizedSuffixKey(prefix, suffix):
-       'Get key with capitalized suffix.'
-       if prefix == '' or prefix.endswith('.'):
-               return prefix + suffix
-       return prefix + suffix[:1].upper()+suffix[1:]
-
-def getDictionarySplitWords(dictionary, value):
-       'Get split line for evaluators.'
-       if getIsQuoted(value):
-               return [value]
-       for dictionaryKey in dictionary.keys():
-               value = value.replace(dictionaryKey, ' ' + dictionaryKey + ' ')
-       dictionarySplitWords = []
-       for word in value.split():
-               dictionarySplitWords.append(word)
-       return dictionarySplitWords
-
-def getElementNodeByKey(elementNode, key):
-       'Get the xml element by key.'
-       if key not in elementNode.attributes:
-               return None
-       word = str(elementNode.attributes[key]).strip()
-       evaluatedLinkValue = getEvaluatedLinkValue(elementNode, word)
-       if evaluatedLinkValue.__class__.__name__ == 'ElementNode':
-               return evaluatedLinkValue
-       print('Warning, could not get ElementNode in getElementNodeByKey in evaluate for:')
-       print(key)
-       print(evaluatedLinkValue)
-       print(elementNode)
-       return None
-
-def getElementNodeObject(evaluatedLinkValue):
-       'Get ElementNodeObject.'
-       if evaluatedLinkValue.__class__.__name__ != 'ElementNode':
-               print('Warning, could not get ElementNode in getElementNodeObject in evaluate for:')
-               print(evaluatedLinkValue.__class__.__name__)
-               print(evaluatedLinkValue)
-               return None
-       if evaluatedLinkValue.xmlObject == None:
-               print('Warning, evaluatedLinkValue.xmlObject is None in getElementNodeObject in evaluate for:')
-               print(evaluatedLinkValue)
-               return None
-       return evaluatedLinkValue.xmlObject
-
-def getElementNodesByKey(elementNode, key):
-       'Get the xml elements by key.'
-       if key not in elementNode.attributes:
-               return []
-       word = str(elementNode.attributes[key]).strip()
-       evaluatedLinkValue = getEvaluatedLinkValue(elementNode, word)
-       if evaluatedLinkValue.__class__.__name__ == 'ElementNode':
-               return [evaluatedLinkValue]
-       if evaluatedLinkValue.__class__ == list:
-               return evaluatedLinkValue
-       print('Warning, could not get ElementNodes in getElementNodesByKey in evaluate for:')
-       print(key)
-       print(evaluatedLinkValue)
-       print(elementNode)
-       return []
-
-def getEndIndexConvertEquationValue( bracketEndIndex, evaluatorIndex, evaluators ):
-       'Get the bracket end index and convert the equation value evaluators into a string.'
-       evaluator = evaluators[evaluatorIndex]
-       if evaluator.__class__ != EvaluatorValue:
-               return bracketEndIndex
-       if not evaluator.word.startswith('equation.'):
-               return bracketEndIndex
-       if evaluators[ evaluatorIndex + 1 ].word != ':':
-               return bracketEndIndex
-       valueBeginIndex = evaluatorIndex + 2
-       equationValueString = ''
-       for valueEvaluatorIndex in xrange( valueBeginIndex, len(evaluators) ):
-               valueEvaluator = evaluators[ valueEvaluatorIndex ]
-               if valueEvaluator.word == ',' or valueEvaluator.word == '}':
-                       if equationValueString == '':
-                               return bracketEndIndex
-                       else:
-                               evaluators[ valueBeginIndex ] = EvaluatorValue( equationValueString )
-                               valueDeleteIndex = valueBeginIndex + 1
-                               del evaluators[ valueDeleteIndex : valueEvaluatorIndex ]
-                       return bracketEndIndex - valueEvaluatorIndex + valueDeleteIndex
-               equationValueString += valueEvaluator.word
-       return bracketEndIndex
-
-def getEvaluatedBoolean(defaultValue, elementNode, key):
-       'Get the evaluated boolean.'
-       if elementNode == None:
-               return defaultValue
-       if key in elementNode.attributes:
-               return euclidean.getBooleanFromValue(getEvaluatedValueObliviously(elementNode, key))
-       return defaultValue
-
-def getEvaluatedDictionaryByCopyKeys(copyKeys, elementNode):
-       'Get the evaluated dictionary by copyKeys.'
-       evaluatedDictionary = {}
-       for key in elementNode.attributes.keys():
-               if key in copyKeys:
-                       evaluatedDictionary[key] = elementNode.attributes[key]
-               else:
-                       addValueToEvaluatedDictionary(elementNode, evaluatedDictionary, key)
-       return evaluatedDictionary
-
-def getEvaluatedDictionaryByEvaluationKeys(elementNode, evaluationKeys):
-       'Get the evaluated dictionary.'
-       evaluatedDictionary = {}
-       for key in elementNode.attributes.keys():
-               if key in evaluationKeys:
-                       addValueToEvaluatedDictionary(elementNode, evaluatedDictionary, key)
-       return evaluatedDictionary
-
-def getEvaluatedExpressionValue(elementNode, value):
-       'Evaluate the expression value.'
-       try:
-               return getEvaluatedExpressionValueBySplitLine(elementNode, getEvaluatorSplitWords(value))
-       except:
-               print('Warning, in getEvaluatedExpressionValue in evaluate could not get a value for:')
-               print(value)
-               traceback.print_exc(file=sys.stdout)
-               return None
-
-def getEvaluatedExpressionValueBySplitLine(elementNode, words):
-       'Evaluate the expression value.'
-       evaluators = []
-       for wordIndex, word in enumerate(words):
-               nextWord = ''
-               nextWordIndex = wordIndex + 1
-               if nextWordIndex < len(words):
-                       nextWord = words[nextWordIndex]
-               evaluator = getEvaluator(elementNode, evaluators, nextWord, word)
-               if evaluator != None:
-                       evaluators.append(evaluator)
-       while getBracketsExist(evaluators):
-               pass
-       evaluatedExpressionValueEvaluators = getEvaluatedExpressionValueEvaluators(evaluators)
-       if len( evaluatedExpressionValueEvaluators ) > 0:
-               return evaluatedExpressionValueEvaluators[0].value
-       return None
-
-def getEvaluatedExpressionValueEvaluators(evaluators):
-       'Evaluate the expression value from the numeric and operation evaluators.'
-       for evaluatorIndex, evaluator in enumerate(evaluators):
-               evaluator.executeCenterOperation(evaluators, evaluatorIndex)
-       for negativeIndex in xrange(1 - len(evaluators), 0):
-               evaluatorIndex = negativeIndex + len(evaluators)
-               evaluators[evaluatorIndex].executeRightOperation(evaluators, evaluatorIndex)
-       executeLeftOperations(evaluators, 200)
-       for operationLevel in [80, 60, 40, 20, 15]:
-               executePairOperations(evaluators, operationLevel)
-       executeLeftOperations(evaluators, 13)
-       executePairOperations(evaluators, 12)
-       for negativeIndex in xrange(-len(evaluators), 0):
-               evaluatorIndex = negativeIndex + len(evaluators)
-               evaluators[evaluatorIndex].executePairOperation(evaluators, evaluatorIndex, 10)
-       for evaluatorIndex in xrange(len(evaluators) - 1, -1, -1):
-               evaluators[evaluatorIndex].executePairOperation(evaluators, evaluatorIndex, 0)
-       return evaluators
-
-def getEvaluatedFloat(defaultValue, elementNode, key):
-       'Get the evaluated float.'
-       if elementNode == None:
-               return defaultValue
-       if key in elementNode.attributes:
-               return euclidean.getFloatFromValue(getEvaluatedValueObliviously(elementNode, key))
-       return defaultValue
-
-def getEvaluatedInt(defaultValue, elementNode, key):
-       'Get the evaluated int.'
-       if elementNode == None:
-               return None
-       if key in elementNode.attributes:
-               try:
-                       return getIntFromFloatString(getEvaluatedValueObliviously(elementNode, key))
-               except:
-                       print('Warning, could not evaluate the int.')
-                       print(key)
-                       print(elementNode.attributes[key])
-       return defaultValue
-
-def getEvaluatedIntByKeys(defaultValue, elementNode, keys):
-       'Get the evaluated int by keys.'
-       for key in keys:
-               defaultValue = getEvaluatedInt(defaultValue, elementNode, key)
-       return defaultValue
-
-def getEvaluatedLinkValue(elementNode, word):
-       'Get the evaluated link value.'
-       if word == '':
-               return ''
-       if getStartsWithCurlyEqualRoundSquare(word):
-               return getEvaluatedExpressionValue(elementNode, word)
-       return word
-
-def getEvaluatedString(defaultValue, elementNode, key):
-       'Get the evaluated string.'
-       if elementNode == None:
-               return defaultValue
-       if key in elementNode.attributes:
-               return str(getEvaluatedValueObliviously(elementNode, key))
-       return defaultValue
-
-def getEvaluatedValue(defaultValue, elementNode, key):
-       'Get the evaluated value.'
-       if elementNode == None:
-               return defaultValue
-       if key in elementNode.attributes:
-               return getEvaluatedValueObliviously(elementNode, key)
-       return defaultValue
-
-def getEvaluatedValueObliviously(elementNode, key):
-       'Get the evaluated value.'
-       value = str(elementNode.attributes[key]).strip()
-       if key == 'id' or key == 'name' or key == 'tags':
-               return value
-       return getEvaluatedLinkValue(elementNode, value)
-
-def getEvaluator(elementNode, evaluators, nextWord, word):
-       'Get the evaluator.'
-       if word in globalSplitDictionary:
-               return globalSplitDictionary[word](elementNode, word)
-       firstCharacter = word[: 1]
-       if firstCharacter == "'" or firstCharacter == '"':
-               if len(word) > 1:
-                       if firstCharacter == word[-1]:
-                               return EvaluatorValue(word[1 : -1])
-       if firstCharacter == '$':
-               return EvaluatorValue(word[1 :])
-       dotIndex = word.find('.')
-       functions = elementNode.getXMLProcessor().functions
-       if dotIndex > -1 and len(word) > 1:
-               if dotIndex == 0 and word[1].isalpha():
-                       return EvaluatorAttribute(elementNode, word)
-               if dotIndex > 0:
-                       untilDot = word[: dotIndex]
-                       if untilDot in globalModuleEvaluatorDictionary:
-                               return globalModuleEvaluatorDictionary[untilDot](elementNode, word)
-               if len(functions) > 0:
-                       if untilDot in functions[-1].localDictionary:
-                               return EvaluatorLocal(elementNode, word)
-       if firstCharacter.isalpha() or firstCharacter == '_':
-               if len(functions) > 0:
-                       if word in functions[-1].localDictionary:
-                               return EvaluatorLocal(elementNode, word)
-               wordElement = elementNode.getElementNodeByID(word)
-               if wordElement != None:
-                       if wordElement.getNodeName() == 'class':
-                               return EvaluatorClass(wordElement, word)
-                       if wordElement.getNodeName() == 'function':
-                               return EvaluatorFunction(wordElement, word)
-               return EvaluatorValue(word)
-       return EvaluatorNumeric(elementNode, word)
-
-def getEvaluatorSplitWords(value):
-       'Get split words for evaluators.'
-       if value.startswith('='):
-               value = value[len('=') :]
-       if len(value) < 1:
-               return []
-       global globalDictionaryOperatorBegin
-       uniqueQuoteIndex = 0
-       word = ''
-       quoteString = None
-       quoteDictionary = {}
-       for characterIndex in xrange(len(value)):
-               character = value[characterIndex]
-               if character == '"' or character == "'":
-                       if quoteString == None:
-                               quoteString = ''
-                       elif quoteString != None:
-                               if character == quoteString[: 1]:
-                                       uniqueQuoteIndex = getUniqueQuoteIndex(uniqueQuoteIndex, value)
-                                       uniqueToken = getTokenByNumber(uniqueQuoteIndex)
-                                       quoteDictionary[uniqueToken] = quoteString + character
-                                       character = uniqueToken
-                                       quoteString = None
-               if quoteString == None:
-                       word += character
-               else:
-                       quoteString += character
-       beginSplitWords = getDictionarySplitWords(globalDictionaryOperatorBegin, word)
-       global globalSplitDictionaryOperator
-       evaluatorSplitWords = []
-       for beginSplitWord in beginSplitWords:
-               if beginSplitWord in globalDictionaryOperatorBegin:
-                       evaluatorSplitWords.append(beginSplitWord)
-               else:
-                       evaluatorSplitWords += getDictionarySplitWords(globalSplitDictionaryOperator, beginSplitWord)
-       for evaluatorSplitWordIndex, evaluatorSplitWord in enumerate(evaluatorSplitWords):
-               for quoteDictionaryKey in quoteDictionary.keys():
-                       if quoteDictionaryKey in evaluatorSplitWord:
-                               evaluatorSplitWords[evaluatorSplitWordIndex] = evaluatorSplitWord.replace(quoteDictionaryKey, quoteDictionary[quoteDictionaryKey])
-       evaluatorTransitionWords = []
-       for evaluatorSplitWord in evaluatorSplitWords:
-               addQuoteWord(evaluatorTransitionWords, evaluatorSplitWord)
-       return evaluatorTransitionWords
-
-def getFloatListFromBracketedString( bracketedString ):
-       'Get list from a bracketed string.'
-       if not getIsBracketed( bracketedString ):
-               return None
-       bracketedString = bracketedString.strip().replace('[', '').replace(']', '').replace('(', '').replace(')', '')
-       if len( bracketedString ) < 1:
-               return []
-       splitLine = bracketedString.split(',')
-       floatList = []
-       for word in splitLine:
-               evaluatedFloat = euclidean.getFloatFromValue(word)
-               if evaluatedFloat != None:
-                       floatList.append( evaluatedFloat )
-       return floatList
-
-def getFloatListListsByPaths(paths):
-       'Get float lists by paths.'
-       floatListLists = []
-       for path in paths:
-               floatListList = []
-               for point in path:
-                       floatListList.append( point.getFloatList() )
-       return floatListLists
-
-def getIntFromFloatString(value):
-       'Get the int from the string.'
-       floatString = str(value).strip()
-       if floatString == '':
-               return None
-       dotIndex = floatString.find('.')
-       if dotIndex < 0:
-               return int(value)
-       return int( round( float(floatString) ) )
-
-def getIsBracketed(word):
-       'Determine if the word is bracketed.'
-       if len(word) < 2:
-               return False
-       firstCharacter = word[0]
-       lastCharacter = word[-1]
-       if firstCharacter == '(' and lastCharacter == ')':
-               return True
-       return firstCharacter == '[' and lastCharacter == ']'
-
-def getIsQuoted(word):
-       'Determine if the word is quoted.'
-       if len(word) < 2:
-               return False
-       firstCharacter = word[0]
-       lastCharacter = word[-1]
-       if firstCharacter == '"' and lastCharacter == '"':
-               return True
-       return firstCharacter == "'" and lastCharacter == "'"
-
-def getKeys(repository):
-       'Get keys for repository.'
-       repositoryClass = repository.__class__
-       if repositoryClass == list or repositoryClass == tuple:
-               return range(len(repository))
-       if repositoryClass == dict:
-               return repository.keys()
-       return None
-
-def getLocalAttributeValueString(key, valueString):
-       'Get the local attribute value string with augmented assignment.'
-       augmentedStatements = '+= -= *= /= %= **='.split()
-       for augmentedStatement in augmentedStatements:
-               if valueString.startswith(augmentedStatement):
-                       return key + augmentedStatement[: -1] + valueString[len(augmentedStatement) :]
-       return valueString
-
-def getMatchingPlugins(elementNode, namePathDictionary):
-       'Get the plugins whose names are in the attribute dictionary.'
-       matchingPlugins = []
-       namePathDictionaryCopy = namePathDictionary.copy()
-       for key in elementNode.attributes:
-               dotIndex = key.find('.')
-               if dotIndex > - 1:
-                       keyUntilDot = key[: dotIndex]
-                       if keyUntilDot in namePathDictionaryCopy:
-                               pluginModule = archive.getModuleWithPath( namePathDictionaryCopy[ keyUntilDot ] )
-                               del namePathDictionaryCopy[ keyUntilDot ]
-                               if pluginModule != None:
-                                       matchingPlugins.append( pluginModule )
-       return matchingPlugins
-
-def getNextChildIndex(elementNode):
-       'Get the next childNode index.'
-       for childNodeIndex, childNode in enumerate( elementNode.parentNode.childNodes ):
-               if childNode == elementNode:
-                       return childNodeIndex + 1
-       return len( elementNode.parentNode.childNodes )
-
-def getPathByKey(defaultPath, elementNode, key):
-       'Get path from prefix and xml element.'
-       if key not in elementNode.attributes:
-               return defaultPath
-       word = str(elementNode.attributes[key]).strip()
-       evaluatedLinkValue = getEvaluatedLinkValue(elementNode, word)
-       if evaluatedLinkValue.__class__ == list:
-               return getPathByList(evaluatedLinkValue)
-       elementNodeObject = getElementNodeObject(evaluatedLinkValue)
-       if elementNodeObject == None:
-               return defaultPath
-       return elementNodeObject.getPaths()[0]
-
-def getPathByList(vertexList):
-       'Get the paths by list.'
-       if len(vertexList) < 1:
-               return Vector3()
-       if vertexList[0].__class__ != list:
-               vertexList = [vertexList]
-       path = []
-       for floatList in vertexList:
-               vector3 = getVector3ByFloatList(floatList, Vector3())
-               path.append(vector3)
-       return path
-
-def getPathByPrefix(elementNode, path, prefix):
-       'Get path from prefix and xml element.'
-       if len(path) < 2:
-               print('Warning, bug, path is too small in evaluate in setPathByPrefix.')
-               return
-       pathByKey = getPathByKey([], elementNode, getCapitalizedSuffixKey(prefix, 'path'))
-       if len( pathByKey ) < len(path):
-               for pointIndex in xrange( len( pathByKey ) ):
-                       path[pointIndex] = pathByKey[pointIndex]
-       else:
-               path = pathByKey
-       path[0] = getVector3ByPrefix(path[0], elementNode, getCapitalizedSuffixKey(prefix, 'pathStart'))
-       path[-1] = getVector3ByPrefix(path[-1], elementNode, getCapitalizedSuffixKey(prefix, 'pathEnd'))
-       return path
-
-def getPathsByKey(defaultPaths, elementNode, key):
-       'Get paths by key.'
-       if key not in elementNode.attributes:
-               return defaultPaths
-       word = str(elementNode.attributes[key]).strip()
-       evaluatedLinkValue = getEvaluatedLinkValue(elementNode, word)
-       if evaluatedLinkValue.__class__ == dict or evaluatedLinkValue.__class__ == list:
-               convertToPaths(evaluatedLinkValue)
-               return getPathsByLists(evaluatedLinkValue)
-       elementNodeObject = getElementNodeObject(evaluatedLinkValue)
-       if elementNodeObject == None:
-               return defaultPaths
-       return elementNodeObject.getPaths()
-
-def getPathsByLists(vertexLists):
-       'Get paths by lists.'
-       vector3Lists = getVector3ListsRecursively(vertexLists)
-       paths = []
-       addToPathsRecursively(paths, vector3Lists)
-       return paths
-
-def getRadiusArealizedBasedOnAreaRadius(elementNode, radius, sides):
-       'Get the areal radius from the radius, number of sides and cascade radiusAreal.'
-       if elementNode.getCascadeBoolean(False, 'radiusAreal'):
-               return radius
-       return radius * euclidean.getRadiusArealizedMultiplier(sides)
-
-def getSidesBasedOnPrecision(elementNode, radius):
-       'Get the number of polygon sides.'
-       return int(math.ceil(math.sqrt(0.5 * radius / setting.getPrecision(elementNode)) * math.pi))
-
-def getSidesMinimumThreeBasedOnPrecision(elementNode, radius):
-       'Get the number of polygon sides, with a minimum of three.'
-       return max(getSidesBasedOnPrecision(elementNode, radius), 3)
-
-def getSidesMinimumThreeBasedOnPrecisionSides(elementNode, radius):
-       'Get the number of polygon sides, with a minimum of three.'
-       sides = getSidesMinimumThreeBasedOnPrecision(elementNode, radius)
-       return getEvaluatedFloat(sides, elementNode, 'sides')
-
-def getSplitDictionary():
-       'Get split dictionary.'
-       global globalSplitDictionaryOperator
-       splitDictionary = globalSplitDictionaryOperator.copy()
-       global globalDictionaryOperatorBegin
-       splitDictionary.update( globalDictionaryOperatorBegin )
-       splitDictionary['and'] = EvaluatorAnd
-       splitDictionary['false'] = EvaluatorFalse
-       splitDictionary['False'] = EvaluatorFalse
-       splitDictionary['or'] = EvaluatorOr
-       splitDictionary['not'] = EvaluatorNot
-       splitDictionary['true'] = EvaluatorTrue
-       splitDictionary['True'] = EvaluatorTrue
-       splitDictionary['none'] = EvaluatorNone
-       splitDictionary['None'] = EvaluatorNone
-       return splitDictionary
-
-def getStartsWithCurlyEqualRoundSquare(word):
-       'Determine if the word starts with round or square brackets.'
-       return word.startswith('{') or word.startswith('=') or word.startswith('(') or word.startswith('[')
-
-def getTokenByNumber(number):
-       'Get token by number.'
-       return '_%s_' % number
-
-def getTransformedPathByKey(defaultTransformedPath, elementNode, key):
-       'Get transformed path from prefix and xml element.'
-       if key not in elementNode.attributes:
-               return defaultTransformedPath
-       value = elementNode.attributes[key]
-       if value.__class__ == list:
-               return value
-       word = str(value).strip()
-       evaluatedLinkValue = getEvaluatedLinkValue(elementNode, word)
-       if evaluatedLinkValue.__class__ == list:
-               return getPathByList(evaluatedLinkValue)
-       elementNodeObject = getElementNodeObject(evaluatedLinkValueClass)
-       if elementNodeObject == None:
-               return defaultTransformedPath
-       return elementNodeObject.getTransformedPaths()[0]
-
-def getTransformedPathByPrefix(elementNode, path, prefix):
-       'Get path from prefix and xml element.'
-       if len(path) < 2:
-               print('Warning, bug, path is too small in evaluate in setPathByPrefix.')
-               return
-       pathByKey = getTransformedPathByKey([], elementNode, getCapitalizedSuffixKey(prefix, 'path'))
-       if len( pathByKey ) < len(path):
-               for pointIndex in xrange( len( pathByKey ) ):
-                       path[pointIndex] = pathByKey[pointIndex]
-       else:
-               path = pathByKey
-       path[0] = getVector3ByPrefix(path[0], elementNode, getCapitalizedSuffixKey(prefix, 'pathStart'))
-       path[-1] = getVector3ByPrefix(path[-1], elementNode, getCapitalizedSuffixKey(prefix, 'pathEnd'))
-       return path
-
-def getTransformedPathsByKey(defaultTransformedPaths, elementNode, key):
-       'Get transformed paths by key.'
-       if key not in elementNode.attributes:
-               return defaultTransformedPaths
-       value = elementNode.attributes[key]
-       if value.__class__ == list:
-               return getPathsByLists(value)
-       word = str(value).strip()
-       evaluatedLinkValue = getEvaluatedLinkValue(elementNode, word)
-       if evaluatedLinkValue.__class__ == dict or evaluatedLinkValue.__class__ == list:
-               convertToTransformedPaths(evaluatedLinkValue)
-               return getPathsByLists(evaluatedLinkValue)
-       elementNodeObject = getElementNodeObject(evaluatedLinkValue)
-       if elementNodeObject == None:
-               return defaultTransformedPaths
-       return elementNodeObject.getTransformedPaths()
-
-def getUniqueQuoteIndex( uniqueQuoteIndex, word ):
-       'Get uniqueQuoteIndex.'
-       uniqueQuoteIndex += 1
-       while getTokenByNumber(uniqueQuoteIndex) in word:
-               uniqueQuoteIndex += 1
-       return uniqueQuoteIndex
-
-def getUniqueToken(word):
-       'Get unique token.'
-       uniqueString = '@#!'
-       for character in uniqueString:
-               if character not in word:
-                       return character
-       uniqueNumber = 0
-       while True:
-               for character in uniqueString:
-                       uniqueToken = character + str(uniqueNumber)
-                       if uniqueToken not in word:
-                               return uniqueToken
-                       uniqueNumber += 1
-
-def getVector3ByDictionary( dictionary, vector3 ):
-       'Get vector3 by dictionary.'
-       if 'x' in dictionary:
-               vector3 = getVector3IfNone(vector3)
-               vector3.x = euclidean.getFloatFromValue(dictionary['x'])
-       if 'y' in dictionary:
-               vector3 = getVector3IfNone(vector3)
-               vector3.y = euclidean.getFloatFromValue(dictionary['y'])
-       if 'z' in dictionary:
-               vector3 = getVector3IfNone(vector3)
-               vector3.z = euclidean.getFloatFromValue( dictionary['z'] )
-       return vector3
-
-def getVector3ByDictionaryListValue(value, vector3):
-       'Get vector3 by dictionary, list or value.'
-       if value.__class__ == Vector3 or value.__class__.__name__ == 'Vector3Index':
-               return value
-       if value.__class__ == dict:
-               return getVector3ByDictionary(value, vector3)
-       if value.__class__ == list:
-               return getVector3ByFloatList(value, vector3)
-       floatFromValue = euclidean.getFloatFromValue(value)
-       if floatFromValue ==  None:
-               return vector3
-       vector3.setToXYZ(floatFromValue, floatFromValue, floatFromValue)
-       return vector3
-
-def getVector3ByFloatList(floatList, vector3):
-       'Get vector3 by float list.'
-       if len(floatList) > 0:
-               vector3 = getVector3IfNone(vector3)
-               vector3.x = euclidean.getFloatFromValue(floatList[0])
-       if len(floatList) > 1:
-               vector3 = getVector3IfNone(vector3)
-               vector3.y = euclidean.getFloatFromValue(floatList[1])
-       if len(floatList) > 2:
-               vector3 = getVector3IfNone(vector3)
-               vector3.z = euclidean.getFloatFromValue(floatList[2])
-       return vector3
-
-def getVector3ByMultiplierPrefix( elementNode, multiplier, prefix, vector3 ):
-       'Get vector3 from multiplier, prefix and xml element.'
-       if multiplier == 0.0:
-               return vector3
-       oldMultipliedValueVector3 = vector3 * multiplier
-       vector3ByPrefix = getVector3ByPrefix(oldMultipliedValueVector3.copy(), elementNode, prefix)
-       if vector3ByPrefix == oldMultipliedValueVector3:
-               return vector3
-       return vector3ByPrefix / multiplier
-
-def getVector3ByMultiplierPrefixes( elementNode, multiplier, prefixes, vector3 ):
-       'Get vector3 from multiplier, prefixes and xml element.'
-       for prefix in prefixes:
-               vector3 = getVector3ByMultiplierPrefix( elementNode, multiplier, prefix, vector3 )
-       return vector3
-
-def getVector3ByPrefix(defaultVector3, elementNode, prefix):
-       'Get vector3 from prefix and xml element.'
-       value = getEvaluatedValue(None, elementNode, prefix)
-       if value != None:
-               defaultVector3 = getVector3ByDictionaryListValue(value, defaultVector3)
-       prefix = archive.getUntilDot(prefix)
-       x = getEvaluatedFloat(None, elementNode, prefix + '.x')
-       if x != None:
-               defaultVector3 = getVector3IfNone(defaultVector3)
-               defaultVector3.x = x
-       y = getEvaluatedFloat(None, elementNode, prefix + '.y')
-       if y != None:
-               defaultVector3 = getVector3IfNone(defaultVector3)
-               defaultVector3.y = y
-       z = getEvaluatedFloat(None, elementNode, prefix + '.z')
-       if z != None:
-               defaultVector3 = getVector3IfNone(defaultVector3)
-               defaultVector3.z = z
-       return defaultVector3
-
-def getVector3ByPrefixes( elementNode, prefixes, vector3 ):
-       'Get vector3 from prefixes and xml element.'
-       for prefix in prefixes:
-               vector3 = getVector3ByPrefix(vector3, elementNode, prefix)
-       return vector3
-
-def getVector3FromElementNode(elementNode):
-       'Get vector3 from xml element.'
-       vector3 = Vector3(
-               getEvaluatedFloat(0.0, elementNode, 'x'),
-               getEvaluatedFloat(0.0, elementNode, 'y'),
-               getEvaluatedFloat(0.0, elementNode, 'z'))
-       return getVector3ByPrefix(vector3, elementNode, 'cartesian')
-
-def getVector3IfNone(vector3):
-       'Get new vector3 if the original vector3 is none.'
-       if vector3 == None:
-               return Vector3()
-       return vector3
-
-def getVector3ListsRecursively(floatLists):
-       'Get vector3 lists recursively.'
-       if len(floatLists) < 1:
-               return Vector3()
-       firstElement = floatLists[0]
-       if firstElement.__class__ == Vector3:
-               return floatLists
-       if firstElement.__class__ != list:
-               return getVector3ByFloatList(floatLists, Vector3())
-       vector3ListsRecursively = []
-       for floatList in floatLists:
-               vector3ListsRecursively.append(getVector3ListsRecursively(floatList))
-       return vector3ListsRecursively
-
-def getVisibleObjects(archivableObjects):
-       'Get the visible objects.'
-       visibleObjects = []
-       for archivableObject in archivableObjects:
-               if archivableObject.getVisible():
-                       visibleObjects.append(archivableObject)
-       return visibleObjects
-
-def processArchivable(archivableClass, elementNode):
-       'Get any new elements and process the archivable.'
-       if elementNode == None:
-               return
-       elementNode.xmlObject = archivableClass()
-       elementNode.xmlObject.setToElementNode(elementNode)
-       elementNode.getXMLProcessor().processChildNodes(elementNode)
-
-def processCondition(elementNode):
-       'Process the xml element condition.'
-       xmlProcessor = elementNode.getXMLProcessor()
-       if elementNode.xmlObject == None:
-               elementNode.xmlObject = ModuleElementNode(elementNode)
-       if elementNode.xmlObject.conditionSplitWords == None:
-               return
-       if len(xmlProcessor.functions ) < 1:
-               print('Warning, the (in) element is not in a function in processCondition in evaluate for:')
-               print(elementNode)
-               return
-       if int(getEvaluatedExpressionValueBySplitLine(elementNode, elementNode.xmlObject.conditionSplitWords)) > 0:
-               xmlProcessor.functions[-1].processChildNodes(elementNode)
-       else:
-               elementNode.xmlObject.processElse(elementNode)
-
-def removeIdentifiersFromDictionary(dictionary):
-       'Remove the identifier elements from a dictionary.'
-       euclidean.removeElementsFromDictionary(dictionary, ['id', 'name', 'tags'])
-       return dictionary
-
-def setAttributesByArguments(argumentNames, arguments, elementNode):
-       'Set the attribute dictionary to the arguments.'
-       for argumentIndex, argument in enumerate(arguments):
-               elementNode.attributes[argumentNames[argumentIndex]] = argument
-
-def setFunctionLocalDictionary(arguments, function):
-       'Evaluate the function statement and delete the evaluators.'
-       function.localDictionary = {'_arguments' : arguments}
-       if len(arguments) > 0:
-               firstArgument = arguments[0]
-               if firstArgument.__class__ == dict:
-                       function.localDictionary = firstArgument
-                       return
-       if 'parameters' not in function.elementNode.attributes:
-               return
-       parameters = function.elementNode.attributes['parameters'].strip()
-       if parameters == '':
-               return
-       parameterWords = parameters.split(',')
-       for parameterWordIndex, parameterWord in enumerate(parameterWords):
-               strippedWord = parameterWord.strip()
-               keyValue = KeyValue().getByEqual(strippedWord)
-               if parameterWordIndex < len(arguments):
-                       function.localDictionary[keyValue.key] = arguments[parameterWordIndex]
-               else:
-                       strippedValue = keyValue.value
-                       if strippedValue == None:
-                               print('Warning there is no default parameter in getParameterValue for:')
-                               print(strippedWord)
-                               print(parameterWords)
-                               print(arguments)
-                               print(function.elementNode.attributes)
-                       else:
-                               strippedValue = strippedValue.strip()
-                       function.localDictionary[keyValue.key.strip()] = strippedValue
-       if len(arguments) > len(parameterWords):
-               print('Warning there are too many initializeFunction parameters for:')
-               print(function.elementNode.attributes)
-               print(parameterWords)
-               print(arguments)
-
-def setLocalAttribute(elementNode):
-       'Set the local attribute if any.'
-       if elementNode.xmlObject != None:
-               return
-       for key in elementNode.attributes:
-               if key[: 1].isalpha():
-                       value = getEvaluatorSplitWords(getLocalAttributeValueString(key, elementNode.attributes[key].strip()))
-                       elementNode.xmlObject = KeyValue(key, value)
-                       return
-       elementNode.xmlObject = KeyValue()
-
-
-class BaseFunction(object):
-       'Class to get equation results.'
-       def __init__(self, elementNode):
-               'Initialize.'
-               self.elementNode = elementNode
-               self.localDictionary = {}
-               self.xmlProcessor = elementNode.getXMLProcessor()
-
-       def __repr__(self):
-               'Get the string representation of this Class.'
-               return str(self.__dict__)
-
-       def getReturnValue(self):
-               'Get return value.'
-               self.getReturnValueWithoutDeletion()
-               del self.xmlProcessor.functions[-1]
-               return self.returnValue
-
-       def processChildNodes(self, elementNode):
-               'Process childNodes if shouldReturn is false.'
-               for childNode in elementNode.childNodes:
-                       if self.shouldReturn:
-                               return
-                       self.xmlProcessor.processElementNode(childNode)
-
-
-class ClassFunction(BaseFunction):
-       'Class to get class results.'
-       def getReturnValueByArguments(self, *arguments):
-               'Get return value by arguments.'
-               setFunctionLocalDictionary(arguments, self)
-               return self.getReturnValue()
-
-       def getReturnValueWithoutDeletion(self):
-               'Get return value without deleting last function.'
-               self.returnValue = None
-               self.shouldReturn = False
-               self.xmlProcessor.functions.append(self)
-               self.processChildNodes(self.elementNode)
-               return self.returnValue
-
-
-class ClassObject(object):
-       'Class to hold class attributes and functions.'
-       def __init__(self, elementNode):
-               'Initialize.'
-               self.functionDictionary = elementNode.xmlObject.functionDictionary
-               self.selfDictionary = {}
-               for variable in elementNode.xmlObject.variables:
-                       self.selfDictionary[variable] = None
-
-       def __repr__(self):
-               'Get the string representation of this Class.'
-               return str(self.__dict__)
-
-       def _getAccessibleAttribute(self, attributeName):
-               'Get the accessible attribute.'
-               if attributeName in self.selfDictionary:
-                       return self.selfDictionary[attributeName]
-               if attributeName in self.functionDictionary:
-                       function = self.functionDictionary[attributeName]
-                       function.classObject = self
-                       return function.getReturnValueByArguments
-               return None
-
-       def _setAccessibleAttribute(self, attributeName, value):
-               'Set the accessible attribute.'
-               if attributeName in self.selfDictionary:
-                       self.selfDictionary[attributeName] = value
-
-
-class EmptyObject(object):
-       'An empty object.'
-       def __init__(self):
-               'Do nothing.'
-               pass
-
-
-class Evaluator(object):
-       'Base evaluator class.'
-       def __init__(self, elementNode, word):
-               'Set value to none.'
-               self.value = None
-               self.word = word
-
-       def __repr__(self):
-               'Get the string representation of this Class.'
-               return str(self.__dict__)
-
-       def executeBracket( self, bracketBeginIndex, bracketEndIndex, evaluators ):
-               'Execute the bracket.'
-               pass
-
-       def executeCenterOperation(self, evaluators, evaluatorIndex):
-               'Execute operator which acts on the center.'
-               pass
-
-       def executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator):
-               'Execute the dictionary.'
-               del evaluators[evaluatorIndex]
-               enumeratorKeys = euclidean.getEnumeratorKeys(dictionary, keys)
-               if enumeratorKeys.__class__ == list:
-                       nextEvaluator.value = []
-                       for enumeratorKey in enumeratorKeys:
-                               if enumeratorKey in dictionary:
-                                       nextEvaluator.value.append(dictionary[enumeratorKey])
-                               else:
-                                       print('Warning, key in executeKey in Evaluator in evaluate is not in for:')
-                                       print(enumeratorKey)
-                                       print(dictionary)
-                       return
-               if enumeratorKeys in dictionary:
-                       nextEvaluator.value = dictionary[enumeratorKeys]
-               else:
-                       print('Warning, key in executeKey in Evaluator in evaluate is not in for:')
-                       print(enumeratorKeys)
-                       print(dictionary)
-
-       def executeFunction(self, evaluators, evaluatorIndex, nextEvaluator):
-               'Execute the function.'
-               pass
-
-       def executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator):
-               'Execute the key index.'
-               if self.value.__class__ == str:
-                       self.executeString(evaluators, keys, evaluatorIndex, nextEvaluator)
-                       return
-               if self.value.__class__ == list:
-                       self.executeList(evaluators, keys, evaluatorIndex, nextEvaluator)
-                       return
-               if self.value.__class__ == dict:
-                       self.executeDictionary(self.value, evaluators, keys, evaluatorIndex, nextEvaluator)
-                       return
-               getAccessibleDictionaryFunction = getattr(self.value, '_getAccessibleDictionary', None)
-               if getAccessibleDictionaryFunction != None:
-                       self.executeDictionary(getAccessibleDictionaryFunction(), evaluators, keys, evaluatorIndex, nextEvaluator)
-                       return
-               if self.value.__class__.__name__ != 'ElementNode':
-                       return
-               del evaluators[evaluatorIndex]
-               enumeratorKeys = euclidean.getEnumeratorKeys(self.value.attributes, keys)
-               if enumeratorKeys.__class__ == list:
-                       nextEvaluator.value = []
-                       for enumeratorKey in enumeratorKeys:
-                               if enumeratorKey in self.value.attributes:
-                                       nextEvaluator.value.append(getEvaluatedExpressionValue(self.value, self.value.attributes[enumeratorKey]))
-                               else:
-                                       print('Warning, key in executeKey in Evaluator in evaluate is not in for:')
-                                       print(enumeratorKey)
-                                       print(self.value.attributes)
-                       return
-               if enumeratorKeys in self.value.attributes:
-                       nextEvaluator.value = getEvaluatedExpressionValue(self.value, self.value.attributes[enumeratorKeys])
-               else:
-                       print('Warning, key in executeKey in Evaluator in evaluate is not in for:')
-                       print(enumeratorKeys)
-                       print(self.value.attributes)
-
-       def executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel):
-               'Execute operator which acts from the left.'
-               pass
-
-       def executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator):
-               'Execute the key index.'
-               del evaluators[evaluatorIndex]
-               enumeratorKeys = euclidean.getEnumeratorKeys(self.value, keys)
-               if enumeratorKeys.__class__ == list:
-                       nextEvaluator.value = []
-                       for enumeratorKey in enumeratorKeys:
-                               intKey = euclidean.getIntFromValue(enumeratorKey)
-                               if self.getIsInRange(intKey):
-                                       nextEvaluator.value.append(self.value[intKey])
-                               else:
-                                       print('Warning, key in executeList in Evaluator in evaluate is not in for:')
-                                       print(enumeratorKey)
-                                       print(self.value)
-                       return
-               intKey = euclidean.getIntFromValue(enumeratorKeys)
-               if self.getIsInRange(intKey):
-                       nextEvaluator.value = self.value[intKey]
-               else:
-                       print('Warning, key in executeList in Evaluator in evaluate is not in for:')
-                       print(enumeratorKeys)
-                       print(self.value)
-
-       def executePairOperation(self, evaluators, evaluatorIndex, operationLevel):
-               'Operate on two evaluators.'
-               pass
-
-       def executeRightOperation( self, evaluators, evaluatorIndex ):
-               'Execute operator which acts from the right.'
-               pass
-
-       def executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator):
-               'Execute the string.'
-               del evaluators[evaluatorIndex]
-               enumeratorKeys = euclidean.getEnumeratorKeys(self.value, keys)
-               if enumeratorKeys.__class__ == list:
-                       nextEvaluator.value = ''
-                       for enumeratorKey in enumeratorKeys:
-                               intKey = euclidean.getIntFromValue(enumeratorKey)
-                               if self.getIsInRange(intKey):
-                                       nextEvaluator.value += self.value[intKey]
-                               else:
-                                       print('Warning, key in executeString in Evaluator in evaluate is not in for:')
-                                       print(enumeratorKey)
-                                       print(self.value)
-                       return
-               intKey = euclidean.getIntFromValue(enumeratorKeys)
-               if self.getIsInRange(intKey):
-                       nextEvaluator.value = self.value[intKey]
-               else:
-                       print('Warning, key in executeString in Evaluator in evaluate is not in for:')
-                       print(enumeratorKeys)
-                       print(self.value)
-
-       def getIsInRange(self, keyIndex):
-               'Determine if the keyIndex is in range.'
-               if keyIndex == None:
-                       return False
-               return -len(self.value) <= keyIndex < len(self.value)
-
-
-class EvaluatorAddition(Evaluator):
-       'Class to add two evaluators.'
-       def executePair( self, evaluators, evaluatorIndex ):
-               'Add two evaluators.'
-               leftIndex = evaluatorIndex - 1
-               rightIndex = evaluatorIndex + 1
-               if leftIndex < 0:
-                       print('Warning, no leftKey in executePair in EvaluatorAddition for:')
-                       print(evaluators)
-                       print(evaluatorIndex)
-                       print(self)
-                       del evaluators[evaluatorIndex]
-                       return
-               if rightIndex >= len(evaluators):
-                       print('Warning, no rightKey in executePair in EvaluatorAddition for:')
-                       print(evaluators)
-                       print(evaluatorIndex)
-                       print(self)
-                       del evaluators[evaluatorIndex]
-                       return
-               rightValue = evaluators[rightIndex].value
-               evaluators[leftIndex].value = self.getOperationValue(evaluators[leftIndex].value, evaluators[rightIndex].value)
-               del evaluators[ evaluatorIndex : evaluatorIndex + 2 ]
-
-       def executePairOperation(self, evaluators, evaluatorIndex, operationLevel):
-               'Operate on two evaluators.'
-               if operationLevel == 20:
-                       self.executePair(evaluators, evaluatorIndex)
-
-       def getEvaluatedValues(self, enumerable, keys, value):
-               'Get evaluatedValues.'
-               if enumerable.__class__ == dict:
-                       evaluatedValues = {}
-                       for key in keys:
-                               evaluatedValues[key] = self.getOperationValue(value, enumerable[key])
-                       return evaluatedValues
-               evaluatedValues = []
-               for key in keys:
-                       evaluatedValues.append(self.getOperationValue(value, enumerable[key]))
-               return evaluatedValues
-
-       def getOperationValue(self, leftValue, rightValue):
-               'Get operation value.'
-               leftKeys = getKeys(leftValue)
-               rightKeys = getKeys(rightValue)
-               if leftKeys == None and rightKeys == None:
-                       return self.getValueFromValuePair(leftValue, rightValue)
-               if leftKeys == None:
-                       return self.getEvaluatedValues(rightValue, rightKeys, leftValue)
-               if rightKeys == None:
-                       return self.getEvaluatedValues(leftValue, leftKeys, rightValue)
-               leftKeys.sort(reverse=True)
-               rightKeys.sort(reverse=True)
-               if leftKeys != rightKeys:
-                       print('Warning, the leftKeys are different from the rightKeys in getOperationValue in EvaluatorAddition for:')
-                       print('leftValue')
-                       print(leftValue)
-                       print(leftKeys)
-                       print('rightValue')
-                       print(rightValue)
-                       print(rightKeys)
-                       print(self)
-                       return None
-               if leftValue.__class__ == dict or rightValue.__class__ == dict:
-                       evaluatedValues = {}
-                       for leftKey in leftKeys:
-                               evaluatedValues[leftKey] = self.getOperationValue(leftValue[leftKey], rightValue[leftKey])
-                       return evaluatedValues
-               evaluatedValues = []
-               for leftKey in leftKeys:
-                       evaluatedValues.append(self.getOperationValue(leftValue[leftKey], rightValue[leftKey]))
-               return evaluatedValues
-
-       def getValueFromValuePair(self, leftValue, rightValue):
-               'Add two values.'
-               return leftValue + rightValue
-
-
-class EvaluatorEqual(EvaluatorAddition):
-       'Class to compare two evaluators.'
-       def executePairOperation(self, evaluators, evaluatorIndex, operationLevel):
-               'Operate on two evaluators.'
-               if operationLevel == 15:
-                       self.executePair(evaluators, evaluatorIndex)
-
-       def getBooleanFromValuePair(self, leftValue, rightValue):
-               'Compare two values.'
-               return leftValue == rightValue
-
-       def getValueFromValuePair(self, leftValue, rightValue):
-               'Get value from comparison.'
-               return self.getBooleanFromValuePair(leftValue, rightValue)
-
-
-class EvaluatorSubtraction(EvaluatorAddition):
-       'Class to subtract two evaluators.'
-       def executeLeft( self, evaluators, evaluatorIndex ):
-               'Minus the value to the right.'
-               leftIndex = evaluatorIndex - 1
-               rightIndex = evaluatorIndex + 1
-               leftValue = None
-               if leftIndex >= 0:
-                       leftValue = evaluators[leftIndex].value
-               if leftValue != None:
-                       return
-               rightValue = evaluators[rightIndex].value
-               if rightValue == None:
-                       print('Warning, can not minus.')
-                       print(evaluators[rightIndex].word)
-               else:
-                       evaluators[rightIndex].value = self.getNegativeValue(rightValue)
-               del evaluators[evaluatorIndex]
-
-       def executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel):
-               'Minus the value to the right.'
-               if operationLevel == 200:
-                       self.executeLeft(evaluators, evaluatorIndex)
-
-       def getNegativeValue( self, value ):
-               'Get the negative value.'
-               keys = getKeys(value)
-               if keys == None:
-                       return self.getValueFromSingleValue(value)
-               for key in keys:
-                       value[key] = self.getNegativeValue(value[key])
-               return value
-
-       def getValueFromSingleValue( self, value ):
-               'Minus value.'
-               return -value
-
-       def getValueFromValuePair(self, leftValue, rightValue):
-               'Subtract two values.'
-               return leftValue - rightValue
-
-
-class EvaluatorAnd(EvaluatorAddition):
-       'Class to compare two evaluators.'
-       def executePairOperation(self, evaluators, evaluatorIndex, operationLevel):
-               'Operate on two evaluators.'
-               if operationLevel == 12:
-                       self.executePair(evaluators, evaluatorIndex)
-
-       def getBooleanFromValuePair(self, leftValue, rightValue):
-               'And two values.'
-               return leftValue and rightValue
-
-       def getValueFromValuePair(self, leftValue, rightValue):
-               'Get value from comparison.'
-               return self.getBooleanFromValuePair(leftValue, rightValue)
-
-
-class EvaluatorAttribute(Evaluator):
-       'Class to handle an attribute.'
-       def executeFunction(self, evaluators, evaluatorIndex, nextEvaluator):
-               'Execute the function.'
-               executeNextEvaluatorArguments(self, evaluators, evaluatorIndex, nextEvaluator)
-
-       def executeRightOperation( self, evaluators, evaluatorIndex ):
-               'Execute operator which acts from the right.'
-               attributeName = self.word[1 :]
-               previousIndex = evaluatorIndex - 1
-               previousEvaluator = evaluators[previousIndex]
-               if previousEvaluator.value.__class__ == dict:
-                       from fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables import dictionary_attribute
-                       self.value = dictionary_attribute._getAccessibleAttribute(attributeName, previousEvaluator.value)
-               elif previousEvaluator.value.__class__ == list:
-                       from fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables import list_attribute
-                       self.value = list_attribute._getAccessibleAttribute(attributeName, previousEvaluator.value)
-               elif previousEvaluator.value.__class__ == str:
-                       from fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables import string_attribute
-                       self.value = string_attribute._getAccessibleAttribute(attributeName, previousEvaluator.value)
-               else:
-                       attributeKeywords = attributeName.split('.')
-                       self.value = previousEvaluator.value
-                       for attributeKeyword in attributeKeywords:
-                               self.value = getattr(self.value, '_getAccessibleAttribute', None)(attributeKeyword)
-               if self.value == None:
-                       print('Warning, EvaluatorAttribute in evaluate can not get a getAccessibleAttributeFunction for:')
-                       print(attributeName)
-                       print(previousEvaluator.value)
-                       print(self)
-                       return
-               del evaluators[previousIndex]
-
-
-class EvaluatorBracketCurly(Evaluator):
-       'Class to evaluate a string.'
-       def executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators):
-               'Execute the bracket.'
-               for evaluatorIndex in xrange(bracketEndIndex - 3, bracketBeginIndex, - 1):
-                       bracketEndIndex = getEndIndexConvertEquationValue(bracketEndIndex, evaluatorIndex, evaluators)
-               evaluatedExpressionValueEvaluators = getBracketEvaluators(bracketBeginIndex, bracketEndIndex, evaluators)
-               self.value = {}
-               for evaluatedExpressionValueEvaluator in evaluatedExpressionValueEvaluators:
-                       keyValue = evaluatedExpressionValueEvaluator.value
-                       self.value[keyValue.key] = keyValue.value
-               del evaluators[bracketBeginIndex + 1: bracketEndIndex + 1]
-
-
-class EvaluatorBracketRound(Evaluator):
-       'Class to evaluate a string.'
-       def __init__(self, elementNode, word):
-               'Set value to none.'
-               self.arguments = []
-               self.value = None
-               self.word = word
-
-       def executeBracket( self, bracketBeginIndex, bracketEndIndex, evaluators ):
-               'Execute the bracket.'
-               self.arguments = getBracketValuesDeleteEvaluator(bracketBeginIndex, bracketEndIndex, evaluators)
-               if len( self.arguments ) < 1:
-                       return
-               if len( self.arguments ) > 1:
-                       self.value = self.arguments
-               else:
-                       self.value = self.arguments[0]
-
-       def executeRightOperation( self, evaluators, evaluatorIndex ):
-               'Evaluate the statement and delete the evaluators.'
-               previousIndex = evaluatorIndex - 1
-               if previousIndex < 0:
-                       return
-               evaluators[ previousIndex ].executeFunction( evaluators, previousIndex, self )
-
-
-class EvaluatorBracketSquare(Evaluator):
-       'Class to evaluate a string.'
-       def executeBracket( self, bracketBeginIndex, bracketEndIndex, evaluators ):
-               'Execute the bracket.'
-               self.value = getBracketValuesDeleteEvaluator(bracketBeginIndex, bracketEndIndex, evaluators)
-
-       def executeRightOperation( self, evaluators, evaluatorIndex ):
-               'Evaluate the statement and delete the evaluators.'
-               previousIndex = evaluatorIndex - 1
-               if previousIndex < 0:
-                       return
-               if self.value.__class__ != list:
-                       return
-               evaluators[ previousIndex ].executeKey( evaluators, self.value, previousIndex, self )
-
-
-class EvaluatorClass(Evaluator):
-       'Class evaluator class.'
-       def __init__(self, elementNode, word):
-               'Set value to none.'
-               self.elementNode = elementNode
-               self.value = None
-               self.word = word
-
-       def executeFunction(self, evaluators, evaluatorIndex, nextEvaluator):
-               'Execute the function.'
-               if self.elementNode.xmlObject == None:
-                       self.elementNode.xmlObject = FunctionVariable(self.elementNode)
-               nextEvaluator.value = ClassObject(self.elementNode)
-               initializeFunction = None
-               if '_init' in self.elementNode.xmlObject.functionDictionary:
-                       function = self.elementNode.xmlObject.functionDictionary['_init']
-                       function.classObject = nextEvaluator.value
-                       setFunctionLocalDictionary(nextEvaluator.arguments, function)
-                       function.getReturnValue()
-               del evaluators[evaluatorIndex]
-
-
-class EvaluatorComma(Evaluator):
-       'Class to join two evaluators.'
-       def executePairOperation(self, evaluators, evaluatorIndex, operationLevel):
-               'Operate on two evaluators.'
-               if operationLevel != 0:
-                       return
-               previousIndex = evaluatorIndex - 1
-               if previousIndex < 0:
-                       evaluators[evaluatorIndex].value = None
-                       return
-               if evaluators[previousIndex].word == ',':
-                       evaluators[evaluatorIndex].value = None
-                       return
-               del evaluators[evaluatorIndex]
-
-
-class EvaluatorConcatenate(Evaluator):
-       'Class to join two evaluators.'
-       def executePairOperation(self, evaluators, evaluatorIndex, operationLevel):
-               'Operate on two evaluators.'
-               if operationLevel != 80:
-                       return
-               leftIndex = evaluatorIndex - 1
-               if leftIndex < 0:
-                       del evaluators[evaluatorIndex]
-                       return
-               rightIndex = evaluatorIndex + 1
-               if rightIndex >= len(evaluators):
-                       del evaluators[ leftIndex : rightIndex ]
-                       return
-               leftValue = evaluators[leftIndex].value
-               rightValue = evaluators[rightIndex].value
-               if leftValue.__class__ == rightValue.__class__ and (leftValue.__class__ == list or rightValue.__class__ == str):
-                       evaluators[leftIndex].value = leftValue + rightValue
-                       del evaluators[ evaluatorIndex : evaluatorIndex + 2 ]
-                       return
-               if leftValue.__class__ == list and rightValue.__class__ == int:
-                       if rightValue > 0:
-                               originalList = leftValue[:]
-                               for copyIndex in xrange( rightValue - 1 ):
-                                       leftValue += originalList
-                               evaluators[leftIndex].value = leftValue
-                               del evaluators[ evaluatorIndex : evaluatorIndex + 2 ]
-                       return
-               if leftValue.__class__ == dict and rightValue.__class__ == dict:
-                       leftValue.update(rightValue)
-                       evaluators[leftIndex].value = leftValue
-                       del evaluators[ evaluatorIndex : evaluatorIndex + 2 ]
-                       return
-               del evaluators[ leftIndex : evaluatorIndex + 2 ]
-
-
-class EvaluatorDictionary(Evaluator):
-       'Class to join two evaluators.'
-       def executePairOperation(self, evaluators, evaluatorIndex, operationLevel):
-               'Operate on two evaluators.'
-               if operationLevel != 10:
-                       return
-               leftEvaluatorIndex = evaluatorIndex - 1
-               if leftEvaluatorIndex < 0:
-                       print('Warning, leftEvaluatorIndex is less than zero in EvaluatorDictionary for:')
-                       print(self)
-                       print(evaluators)
-                       return
-               rightEvaluatorIndex = evaluatorIndex + 1
-               if rightEvaluatorIndex >= len(evaluators):
-                       print('Warning, rightEvaluatorIndex too high in EvaluatorDictionary for:')
-                       print(rightEvaluatorIndex)
-                       print(self)
-                       print(evaluators)
-                       return
-               evaluators[rightEvaluatorIndex].value = KeyValue(evaluators[leftEvaluatorIndex].value, evaluators[rightEvaluatorIndex].value)
-               del evaluators[ leftEvaluatorIndex : rightEvaluatorIndex ]
-
-
-class EvaluatorDivision(EvaluatorAddition):
-       'Class to divide two evaluators.'
-       def executePairOperation(self, evaluators, evaluatorIndex, operationLevel):
-               'Operate on two evaluators.'
-               if operationLevel == 40:
-                       self.executePair(evaluators, evaluatorIndex)
-
-       def getValueFromValuePair(self, leftValue, rightValue):
-               'Divide two values.'
-               return leftValue / rightValue
-
-
-class EvaluatorElement(Evaluator):
-       'Element evaluator class.'
-       def __init__(self, elementNode, word):
-               'Set value to none.'
-               self.elementNode = elementNode
-               self.value = None
-               self.word = word
-
-       def executeCenterOperation(self, evaluators, evaluatorIndex):
-               'Execute operator which acts on the center.'
-               dotIndex = self.word.find('.')
-               if dotIndex < 0:
-                       print('Warning, EvaluatorElement in evaluate can not find the dot for:')
-                       print(functionName)
-                       print(self)
-                       return
-               attributeName = self.word[dotIndex + 1 :]
-               moduleName = self.word[: dotIndex]
-               if moduleName in globalModuleFunctionsDictionary:
-                       self.value = globalModuleFunctionsDictionary[moduleName](attributeName, self.elementNode)
-                       return
-               pluginModule = None
-               if moduleName in globalElementNameSet:
-                       pluginModule = archive.getModuleWithPath(archive.getElementsPath(moduleName))
-               if pluginModule == None:
-                       print('Warning, EvaluatorElement in evaluate can not get a pluginModule for:')
-                       print(moduleName)
-                       print(self)
-                       return
-               getAccessibleAttributeFunction = pluginModule._getAccessibleAttribute
-               globalModuleFunctionsDictionary[moduleName] = getAccessibleAttributeFunction
-               self.value = getAccessibleAttributeFunction(attributeName, self.elementNode)
-
-       def executeFunction(self, evaluators, evaluatorIndex, nextEvaluator):
-               'Execute the function.'
-               executeNextEvaluatorArguments(self, evaluators, evaluatorIndex, nextEvaluator)
-
-
-class EvaluatorFalse(Evaluator):
-       'Class to evaluate a string.'
-       def __init__(self, elementNode, word):
-               'Set value to zero.'
-               self.value = False
-               self.word = word
-
-
-class EvaluatorFunction(Evaluator):
-       'Function evaluator class.'
-       def __init__(self, elementNode, word):
-               'Set value to none.'
-               self.elementNode = elementNode
-               self.value = None
-               self.word = word
-
-       def executeFunction(self, evaluators, evaluatorIndex, nextEvaluator):
-               'Execute the function.'
-               if self.elementNode.xmlObject == None:
-                       if 'return' in self.elementNode.attributes:
-                               value = self.elementNode.attributes['return']
-                               self.elementNode.xmlObject = getEvaluatorSplitWords(value)
-                       else:
-                               self.elementNode.xmlObject = []
-               self.function = Function(self.elementNode )
-               setFunctionLocalDictionary(nextEvaluator.arguments, self.function)
-               nextEvaluator.value = self.function.getReturnValue()
-               del evaluators[evaluatorIndex]
-
-
-class EvaluatorFundamental(Evaluator):
-       'Fundamental evaluator class.'
-       def executeCenterOperation(self, evaluators, evaluatorIndex):
-               'Execute operator which acts on the center.'
-               dotIndex = self.word.find('.')
-               if dotIndex < 0:
-                       print('Warning, EvaluatorFundamental in evaluate can not find the dot for:')
-                       print(functionName)
-                       print(self)
-                       return
-               attributeName = self.word[dotIndex + 1 :]
-               moduleName = self.word[: dotIndex]
-               if moduleName in globalModuleFunctionsDictionary:
-                       self.value = globalModuleFunctionsDictionary[moduleName](attributeName)
-                       return
-               pluginModule = None
-               if moduleName in globalFundamentalNameSet:
-                       pluginModule = archive.getModuleWithPath(archive.getFundamentalsPath(moduleName))
-               else:
-                       underscoredName = '_' + moduleName
-                       if underscoredName in globalFundamentalNameSet:
-                               pluginModule = archive.getModuleWithPath(archive.getFundamentalsPath(underscoredName))
-               if pluginModule == None:
-                       print('Warning, EvaluatorFundamental in evaluate can not get a pluginModule for:')
-                       print(moduleName)
-                       print(self)
-                       return
-               getAccessibleAttributeFunction = pluginModule._getAccessibleAttribute
-               globalModuleFunctionsDictionary[moduleName] = getAccessibleAttributeFunction
-               self.value = getAccessibleAttributeFunction(attributeName)
-
-       def executeFunction(self, evaluators, evaluatorIndex, nextEvaluator):
-               'Execute the function.'
-               executeNextEvaluatorArguments(self, evaluators, evaluatorIndex, nextEvaluator)
-
-
-class EvaluatorGreaterEqual( EvaluatorEqual ):
-       'Class to compare two evaluators.'
-       def getBooleanFromValuePair(self, leftValue, rightValue):
-               'Compare two values.'
-               return leftValue >= rightValue
-
-
-class EvaluatorGreater( EvaluatorEqual ):
-       'Class to compare two evaluators.'
-       def getBooleanFromValuePair(self, leftValue, rightValue):
-               'Compare two values.'
-               return leftValue > rightValue
-
-
-class EvaluatorLessEqual( EvaluatorEqual ):
-       'Class to compare two evaluators.'
-       def getBooleanFromValuePair(self, leftValue, rightValue):
-               'Compare two values.'
-               return leftValue <= rightValue
-
-
-class EvaluatorLess( EvaluatorEqual ):
-       'Class to compare two evaluators.'
-       def getBooleanFromValuePair(self, leftValue, rightValue):
-               'Compare two values.'
-               return leftValue < rightValue
-
-
-class EvaluatorLocal(EvaluatorElement):
-       'Class to get a local variable.'
-       def executeCenterOperation(self, evaluators, evaluatorIndex):
-               'Execute operator which acts on the center.'
-               functions = self.elementNode.getXMLProcessor().functions
-               if len(functions) < 1:
-                       print('Warning, there are no functions in EvaluatorLocal in evaluate for:')
-                       print(self.word)
-                       return
-               attributeKeywords = self.word.split('.')
-               self.value = functions[-1].localDictionary[attributeKeywords[0]]
-               for attributeKeyword in attributeKeywords[1 :]:
-                       self.value = self.value._getAccessibleAttribute(attributeKeyword)
-
-
-class EvaluatorModulo( EvaluatorDivision ):
-       'Class to modulo two evaluators.'
-       def getValueFromValuePair(self, leftValue, rightValue):
-               'Modulo two values.'
-               return leftValue % rightValue
-
-
-class EvaluatorMultiplication( EvaluatorDivision ):
-       'Class to multiply two evaluators.'
-       def getValueFromValuePair(self, leftValue, rightValue):
-               'Multiply two values.'
-               return leftValue * rightValue
-
-
-class EvaluatorNone(Evaluator):
-       'Class to evaluate None.'
-       def __init__(self, elementNode, word):
-               'Set value to none.'
-               self.value = None
-               self.word = str(word)
-
-
-class EvaluatorNot(EvaluatorSubtraction):
-       'Class to compare two evaluators.'
-       def executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel):
-               'Minus the value to the right.'
-               if operationLevel == 13:
-                       self.executeLeft(evaluators, evaluatorIndex)
-
-       def getValueFromSingleValue( self, value ):
-               'Minus value.'
-               return not value
-
-
-class EvaluatorNotEqual( EvaluatorEqual ):
-       'Class to compare two evaluators.'
-       def getBooleanFromValuePair(self, leftValue, rightValue):
-               'Compare two values.'
-               return leftValue != rightValue
-
-
-class EvaluatorNumeric(Evaluator):
-       'Class to evaluate a string.'
-       def __init__(self, elementNode, word):
-               'Set value.'
-               self.value = None
-               self.word = word
-               try:
-                       if '.' in word:
-                               self.value = float(word)
-                       else:
-                               self.value = int(word)
-               except:
-                       print('Warning, EvaluatorNumeric in evaluate could not get a numeric value for:')
-                       print(word)
-                       print(elementNode)
-
-
-class EvaluatorOr( EvaluatorAnd ):
-       'Class to compare two evaluators.'
-       def getBooleanFromValuePair(self, leftValue, rightValue):
-               'Or two values.'
-               return leftValue or rightValue
-
-
-class EvaluatorPower(EvaluatorAddition):
-       'Class to power two evaluators.'
-       def executePairOperation(self, evaluators, evaluatorIndex, operationLevel):
-               'Operate on two evaluators.'
-               if operationLevel == 60:
-                       self.executePair(evaluators, evaluatorIndex)
-
-       def getValueFromValuePair(self, leftValue, rightValue):
-               'Power of two values.'
-               return leftValue ** rightValue
-
-
-class EvaluatorSelf(EvaluatorElement):
-       'Class to handle self.'
-       def executeCenterOperation(self, evaluators, evaluatorIndex):
-               'Execute operator which acts on the center.'
-               functions = self.elementNode.getXMLProcessor().functions
-               if len(functions) < 1:
-                       print('Warning, there are no functions in executeCenterOperation in EvaluatorSelf in evaluate for:')
-                       print(self.elementNode)
-                       return
-               function = functions[-1]
-               attributeKeywords = self.word.split('.')
-               self.value = function.classObject
-               for attributeKeyword in attributeKeywords[1 :]:
-                       self.value = self.value._getAccessibleAttribute(attributeKeyword)
-
-
-class EvaluatorTrue(Evaluator):
-       'Class to evaluate a string.'
-       def __init__(self, elementNode, word):
-               'Set value to true.'
-               self.value = True
-               self.word = word
-
-
-class EvaluatorValue(Evaluator):
-       'Class to evaluate a string.'
-       def __init__(self, word):
-               'Set value to none.'
-               self.value = word
-               self.word = str(word)
-
-
-class Function(BaseFunction):
-       'Class to get equation results.'
-       def __init__(self, elementNode):
-               'Initialize.'
-               self.elementNode = elementNode
-               self.evaluatorSplitLine = elementNode.xmlObject
-               self.localDictionary = {}
-               self.xmlProcessor = elementNode.getXMLProcessor()
-
-       def getReturnValueWithoutDeletion(self):
-               'Get return value without deleting last function.'
-               self.returnValue = None
-               self.xmlProcessor.functions.append(self)
-               if len(self.evaluatorSplitLine) < 1:
-                       self.shouldReturn = False
-                       self.processChildNodes(self.elementNode)
-               else:
-                       self.returnValue = getEvaluatedExpressionValueBySplitLine(self.elementNode, self.evaluatorSplitLine)
-               return self.returnValue
-
-
-class FunctionVariable(object):
-       'Class to hold class functions and variable set.'
-       def __init__(self, elementNode):
-               'Initialize.'
-               self.functionDictionary = {}
-               self.variables = []
-               self.processClass(elementNode)
-
-       def addToVariableSet(self, elementNode):
-               'Add to variables.'
-               setLocalAttribute(elementNode)
-               keySplitLine = elementNode.xmlObject.key.split('.')
-               if len(keySplitLine) == 2:
-                       if keySplitLine[0] == 'self':
-                               variable = keySplitLine[1]
-                               if variable not in self.variables:
-                                       self.variables.append(variable)
-
-       def processClass(self, elementNode):
-               'Add class to FunctionVariable.'
-               for childNode in elementNode.childNodes:
-                       self.processFunction(childNode)
-               if 'parentNode' in elementNode.attributes:
-                       self.processClass(elementNode.getElementNodeByID(elementNode.attributes['parentNode']))
-
-       def processFunction(self, elementNode):
-               'Add function to function dictionary.'
-               if elementNode.getNodeName() != 'function':
-                       return
-               idKey = elementNode.attributes['id']
-               if idKey in self.functionDictionary:
-                       return
-               self.functionDictionary[idKey] = ClassFunction(elementNode)
-               for childNode in elementNode.childNodes:
-                       self.processStatement(childNode)
-
-       def processStatement(self, elementNode):
-               'Add self statement to variables.'
-               if elementNode.getNodeName() == 'statement':
-                       self.addToVariableSet(elementNode)
-               for childNode in elementNode.childNodes:
-                       self.processStatement(childNode)
-
-
-class KeyValue(object):
-       'Class to hold a key value.'
-       def __init__(self, key=None, value=None):
-               'Get key value.'
-               self.key = key
-               self.value = value
-
-       def __repr__(self):
-               'Get the string representation of this KeyValue.'
-               return str(self.__dict__)
-
-       def getByCharacter( self, character, line ):
-               'Get by character.'
-               dotIndex = line.find( character )
-               if dotIndex < 0:
-                       self.key = line
-                       self.value = None
-                       return self
-               self.key = line[: dotIndex]
-               self.value = line[dotIndex + 1 :]
-               return self
-
-       def getByDot(self, line):
-               'Get by dot.'
-               return self.getByCharacter('.', line )
-
-       def getByEqual(self, line):
-               'Get by dot.'
-               return self.getByCharacter('=', line )
-
-
-class ModuleElementNode(object):
-       'Class to get the in attribute, the index name and the value name.'
-       def __init__( self, elementNode):
-               'Initialize.'
-               self.conditionSplitWords = None
-               self.elseElement = None
-               if 'condition' in elementNode.attributes:
-                       self.conditionSplitWords = getEvaluatorSplitWords( elementNode.attributes['condition'] )
-               else:
-                       print('Warning, could not find the condition attribute in ModuleElementNode in evaluate for:')
-                       print(elementNode)
-                       return
-               if len( self.conditionSplitWords ) < 1:
-                       self.conditionSplitWords = None
-                       print('Warning, could not get split words for the condition attribute in ModuleElementNode in evaluate for:')
-                       print(elementNode)
-               nextIndex = getNextChildIndex(elementNode)
-               if nextIndex >= len( elementNode.parentNode.childNodes ):
-                       return
-               nextElementNode = elementNode.parentNode.childNodes[ nextIndex ]
-               lowerLocalName = nextElementNode.getNodeName().lower()
-               if lowerLocalName != 'else' and lowerLocalName != 'elif':
-                       return
-               xmlProcessor = elementNode.getXMLProcessor()
-               if lowerLocalName not in xmlProcessor.namePathDictionary:
-                       return
-               self.pluginModule = archive.getModuleWithPath( xmlProcessor.namePathDictionary[ lowerLocalName ] )
-               if self.pluginModule == None:
-                       return
-               self.elseElement = nextElementNode
-
-       def processElse(self, elementNode):
-               'Process the else statement.'
-               if self.elseElement != None:
-                       self.pluginModule.processElse( self.elseElement)
-
-
-globalCreationDictionary = archive.getGeometryDictionary('creation')
-globalDictionaryOperatorBegin = {
-       '||' : EvaluatorConcatenate,
-       '==' : EvaluatorEqual,
-       '>=' : EvaluatorGreaterEqual,
-       '<=' : EvaluatorLessEqual,
-       '!=' : EvaluatorNotEqual,
-       '**' : EvaluatorPower }
-globalModuleEvaluatorDictionary = {}
-globalFundamentalNameSet = set(archive.getPluginFileNamesFromDirectoryPath(archive.getFundamentalsPath()))
-addPrefixDictionary(globalModuleEvaluatorDictionary, globalFundamentalNameSet, EvaluatorFundamental)
-globalElementNameSet = set(archive.getPluginFileNamesFromDirectoryPath(archive.getElementsPath()))
-addPrefixDictionary(globalModuleEvaluatorDictionary, globalElementNameSet, EvaluatorElement)
-globalModuleEvaluatorDictionary['self'] = EvaluatorSelf
-globalSplitDictionaryOperator = {
-       '+' : EvaluatorAddition,
-       '{' : EvaluatorBracketCurly,
-       '}' : Evaluator,
-       '(' : EvaluatorBracketRound,
-       ')' : Evaluator,
-       '[' : EvaluatorBracketSquare,
-       ']' : Evaluator,
-       ',' : EvaluatorComma,
-       ':' : EvaluatorDictionary,
-       '/' : EvaluatorDivision,
-       '>' : EvaluatorGreater,
-       '<' : EvaluatorLess,
-       '%' : EvaluatorModulo,
-       '*' : EvaluatorMultiplication,
-       '-' : EvaluatorSubtraction }
-globalSplitDictionary = getSplitDictionary() # must be after globalSplitDictionaryOperator
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/creation.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/creation.py
deleted file mode 100644 (file)
index 4385ee6..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-"""
-Boolean geometry utilities.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities import archive
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def _getAccessibleAttribute(attributeName, elementNode):
-       'Get the accessible attribute.'
-       functionName = attributeName[len('get') :].lower()
-       if functionName not in evaluate.globalCreationDictionary:
-               print('Warning, functionName not in globalCreationDictionary in _getAccessibleAttribute in creation for:')
-               print(functionName)
-               print(elementNode)
-               return None
-       pluginModule = archive.getModuleWithPath(evaluate.globalCreationDictionary[functionName])
-       if pluginModule == None:
-               print('Warning, _getAccessibleAttribute in creation can not get a pluginModule for:')
-               print(functionName)
-               print(elementNode)
-               return None
-       return Creation(elementNode, pluginModule).getCreation
-
-
-class Creation(object):
-       'Class to handle a creation.'
-       def __init__(self, elementNode, pluginModule):
-               'Initialize.'
-               self.elementNode = elementNode
-               self.pluginModule = pluginModule
-
-       def __repr__(self):
-               "Get the string representation of this creation."
-               return self.elementNode
-
-       def getCreation(self, *arguments):
-               "Get creation."
-               dictionary = {'_fromCreationEvaluator': 'true'}
-               firstArgument = None
-               if len(arguments) > 0:
-                       firstArgument = arguments[0]
-               if firstArgument.__class__ == dict:
-                       dictionary.update(firstArgument)
-                       return self.pluginModule.getGeometryOutput(None, self.elementNode.getCopyShallow(dictionary))
-               copyShallow = self.elementNode.getCopyShallow(dictionary)
-               return self.pluginModule.getGeometryOutputByArguments(arguments, copyShallow)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/document.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/document.py
deleted file mode 100644 (file)
index 0bb91a2..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-"""
-Boolean geometry utilities.
-
-"""
-
-from __future__ import absolute_import
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def _getAccessibleAttribute(attributeName, elementNode):
-       'Get the accessible attribute.'
-       if attributeName in globalGetAccessibleAttributeSet:
-               return getattr(Document(elementNode), attributeName, None)
-       return None
-
-
-class Document(object):
-       'Class to handle elementNodes in a document.'
-       def __init__(self, elementNode):
-               'Initialize.'
-               self.elementNode = elementNode
-
-       def __repr__(self):
-               'Get the string representation of this Document.'
-               return self.elementNode
-
-       def getCascadeBoolean(self, defaultBoolean, key):
-               'Get cascade boolean.'
-               return self.elementNode.getCascadeBoolean(defaultBoolean, key)
-
-       def getCascadeFloat(self, defaultFloat, key):
-               'Get cascade float.'
-               return self.elementNode.getCascadeFloat(defaultFloat, key)
-
-       def getDocumentElement(self):
-               'Get document element element.'
-               return self.elementNode.getDocumentElement()
-
-       def getElementByID(self, idKey):
-               'Get element by id.'
-               elementByID = self.elementNode.getElementNodeByID(idKey)
-               if elementByID == None:
-                       print('Warning, could not get elementByID in getElementByID in document for:')
-                       print(idKey)
-                       print(self.elementNode)
-               return elementByID
-
-       def getElementsByName(self, nameKey):
-               'Get element by name.'
-               elementsByName = self.elementNode.getElementNodesByName(nameKey)
-               if elementsByName == None:
-                       print('Warning, could not get elementsByName in getElementsByName in document for:')
-                       print(nameKey)
-                       print(self.elementNode)
-               return elementsByName
-
-       def getElementsByTag(self, tagKey):
-               'Get element by tag.'
-               elementsByTag = self.elementNode.getElementNodesByTag(tagKey)
-               if elementsByTag == None:
-                       print('Warning, could not get elementsByTag in getElementsByTag in document for:')
-                       print(tagKey)
-                       print(self.elementNode)
-               return elementsByTag
-
-       def getParentNode(self):
-               'Get parentNode element.'
-               return self.elementNode.parentNode
-
-       def getPrevious(self):
-               'Get previous element.'
-               return self.getPreviousElement()
-
-       def getPreviousElement(self):
-               'Get previous element.'
-               return self.elementNode.getPreviousElementNode()
-
-       def getPreviousVertex(self):
-               'Get previous element.'
-               return self.elementNode.getPreviousVertex()
-
-       def getSelfElement(self):
-               'Get self element.'
-               return self.elementNode
-
-
-globalAccessibleAttributeDictionary = 'getCascadeBoolean getCascadeFloat getDocumentElement getElementByID getElementsByName'.split()
-globalAccessibleAttributeDictionary += 'getElementsByTag getParentNode getPrevious getPreviousElement getPreviousVertex'.split()
-globalAccessibleAttributeDictionary += 'getSelfElement'.split()
-globalGetAccessibleAttributeSet = set(globalAccessibleAttributeDictionary)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/setting.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/setting.py
deleted file mode 100644 (file)
index 29ec20a..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-"""
-Boolean geometry utilities.
-
-"""
-
-from __future__ import absolute_import
-
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def _getAccessibleAttribute(attributeName, elementNode):
-       'Get the accessible attribute.'
-       if attributeName in globalGetAccessibleAttributeSet:
-               return getattr(Setting(elementNode), attributeName, None)
-       return None
-
-def getCascadeFloatWithoutSelf(defaultFloat, elementNode, key):
-       'Get the cascade float.'
-       if key in elementNode.attributes:
-               value = elementNode.attributes[key]
-               functionName = 'get' + key[0].upper() + key[1 :]
-               if functionName in value:
-                       if elementNode.parentNode == None:
-                               return defaultFloat
-                       else:
-                               elementNode = elementNode.parentNode
-       return elementNode.getCascadeFloat(defaultFloat, key)
-
-def getEdgeWidth(elementNode):
-       'Get the edge width.'
-       if elementNode == None:
-               return 0.72
-       preferences = skeinforge_craft.getCraftPreferences('carve')
-       layerHeight = skeinforge_craft.getCraftValue('Layer Height', preferences)
-       layerHeight = getCascadeFloatWithoutSelf(layerHeight, elementNode, 'layerHeight')
-       edgeWidthOverHeight = skeinforge_craft.getCraftValue('Edge Width over Height', preferences)
-       edgeWidthOverHeight = getCascadeFloatWithoutSelf(edgeWidthOverHeight, elementNode, 'edgeWidthOverHeight')
-       return getCascadeFloatWithoutSelf(edgeWidthOverHeight * layerHeight, elementNode, 'edgeWidth')
-
-def getImportCoarseness(elementNode, preferences=None):
-       'Get the importCoarseness.'
-       if elementNode == None:
-               return 1.0
-       if preferences == None:
-               preferences = skeinforge_craft.getCraftPreferences('carve')
-       importCoarseness = skeinforge_craft.getCraftValue('Import Coarseness', preferences)
-       return getCascadeFloatWithoutSelf(importCoarseness, elementNode, 'importCoarseness')
-
-def getImportRadius(elementNode):
-       'Get the importRadius.'
-       if elementNode == None:
-               return 0.36
-       preferences = skeinforge_craft.getCraftPreferences('carve')
-       importCoarseness = getImportCoarseness(elementNode, preferences)
-       layerHeight = skeinforge_craft.getCraftValue('Layer Height', preferences)
-       layerHeight = getCascadeFloatWithoutSelf(layerHeight, elementNode, 'layerHeight')
-       edgeWidthOverHeight = skeinforge_craft.getCraftValue('Edge Width over Height', preferences)
-       edgeWidthOverHeight = getCascadeFloatWithoutSelf(edgeWidthOverHeight, elementNode, 'edgeWidthOverHeight')
-       return getCascadeFloatWithoutSelf(0.5 * importCoarseness * layerHeight * edgeWidthOverHeight, elementNode, 'importRadius')
-
-def getInteriorOverhangAngle(elementNode):
-       'Get the interior overhang support angle in degrees.'
-       return getCascadeFloatWithoutSelf(30.0, elementNode, 'interiorOverhangAngle')
-
-def getInteriorOverhangRadians(elementNode):
-       'Get the interior overhang support angle in radians.'
-       return math.radians(getInteriorOverhangAngle(elementNode))
-
-def getLayerHeight(elementNode):
-       'Get the layer height.'
-       if elementNode == None:
-               return 0.4
-       preferences = skeinforge_craft.getCraftPreferences('carve')
-       return getCascadeFloatWithoutSelf(skeinforge_craft.getCraftValue('Layer Height', preferences), elementNode, 'layerHeight')
-
-def getOverhangAngle(elementNode):
-       'Get the overhang support angle in degrees.'
-       return getCascadeFloatWithoutSelf(45.0, elementNode, 'overhangAngle')
-
-def getOverhangRadians(elementNode):
-       'Get the overhang support angle in radians.'
-       return math.radians(getOverhangAngle(elementNode))
-
-def getOverhangSpan(elementNode):
-       'Get the overhang span.'
-       return getCascadeFloatWithoutSelf(2.0 * getLayerHeight(elementNode), elementNode, 'overhangSpan')
-
-def getPrecision(elementNode):
-       'Get the cascade precision.'
-       return getCascadeFloatWithoutSelf(0.2 * getLayerHeight(elementNode), elementNode, 'precision')
-
-def getSheetThickness(elementNode):
-       'Get the sheet thickness.'
-       return getCascadeFloatWithoutSelf(3.0, elementNode, 'sheetThickness')
-
-def getTwistPrecision(elementNode):
-       'Get the twist precision in degrees.'
-       return getCascadeFloatWithoutSelf(5.0, elementNode, 'twistPrecision')
-
-def getTwistPrecisionRadians(elementNode):
-       'Get the twist precision in radians.'
-       return math.radians(getTwistPrecision(elementNode))
-
-
-class Setting(object):
-       'Class to get handle elementNodes in a setting.'
-       def __init__(self, elementNode):
-               'Initialize.'
-               self.elementNode = elementNode
-
-       def __repr__(self):
-               'Get the string representation of this Setting.'
-               return self.elementNode
-
-       def getEdgeWidth(self):
-               'Get the edge width.'
-               return getEdgeWidth(self.elementNode)
-
-       def getImportCoarseness(self):
-               'Get the importCoarseness.'
-               return getImportCoarseness(self.elementNode)
-
-       def getImportRadius(self):
-               'Get the importRadius.'
-               return getImportRadius(self.elementNode)
-
-       def getInteriorOverhangAngle(self):
-               'Get the interior overhang support angle in degrees.'
-               return getInteriorOverhangAngle(self.elementNode)
-
-       def getInteriorOverhangRadians(self):
-               'Get the interior overhang support angle in radians.'
-               return getInteriorOverhangRadians(self.elementNode)
-
-       def getLayerHeight(self):
-               'Get the layer height.'
-               return getLayerHeight(self.elementNode)
-
-       def getOverhangAngle(self):
-               'Get the overhang support angle in degrees.'
-               return getOverhangAngle(self.elementNode)
-
-       def getOverhangRadians(self):
-               'Get the overhang support angle in radians.'
-               return getOverhangRadians(self.elementNode)
-
-       def getOverhangSpan(self):
-               'Get the overhang span.'
-               return getOverhangSpan(self.elementNode)
-
-       def getPrecision(self):
-               'Get the cascade precision.'
-               return getPrecision(self.elementNode)
-
-       def getSheetThickness(self):
-               'Get the sheet thickness.'
-               return getSheetThickness(self.elementNode)
-
-       def getTwistPrecision(self):
-               'Get the twist precision in degrees.'
-               return getTwistPrecision(self.elementNode)
-
-       def getTwistPrecisionRadians(self):
-               'Get the twist precision in radians.'
-               return getTwistPrecisionRadians(self.elementNode)
-
-
-globalAccessibleAttributeDictionary = 'getEdgeWidth getImportCoarseness getImportRadius getInteriorOverhangAngle getInteriorOverhangRadians'.split()
-globalAccessibleAttributeDictionary += 'getLayerHeight getOverhangSpan getOverhangAngle getOverhangRadians'.split()
-globalAccessibleAttributeDictionary += 'getPrecision getSheetThickness getTwistPrecision getTwistPrecisionRadians'.split()
-globalGetAccessibleAttributeSet = set(globalAccessibleAttributeDictionary)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables/dictionary_attribute.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables/dictionary_attribute.py
deleted file mode 100644 (file)
index 4fc6dfc..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-"""
-Dictionary object attributes.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import euclidean
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def _getAccessibleAttribute(attributeName, dictionaryObject):
-       'Get the accessible attribute.'
-       if attributeName in globalNativeFunctionSet:
-               return getattr(dictionaryObject, attributeName, None)
-       if attributeName in globalGetAccessibleAttributeSet:
-               stringAttribute = DictionaryAttribute(dictionaryObject)
-               return getattr(stringAttribute, attributeName, None)
-       return None
-
-
-class DictionaryAttribute(object):
-       'Class to handle a dictionary.'
-       def __init__(self, dictionaryObject):
-               'Initialize.'
-               self.dictionaryObject = dictionaryObject
-
-       def __repr__(self):
-               "Get the dictionary representation of this DictionaryAttribute."
-               return str(self.dictionaryObject)
-
-       def count(self, value):
-               'Get the count.'
-               countTotal = 0
-               for key, iteratorValue in self.dictionaryObject.iteritems():
-                       if iteratorValue == value:
-                               countTotal += 1
-               return countTotal
-
-       def delete(self, arguments):
-               'Get the delete dictionary.'
-               if arguments.__class__ != list:
-                       del self.dictionaryObject[arguments]
-                       return self.dictionaryObject
-               if len(arguments) == 0:
-                       self.dictionaryObject.clear()
-                       return self.dictionaryObject
-               if len(arguments) == 1:
-                       del self.dictionaryObject[arguments[0]]
-                       return self.dictionaryObject
-               for enumeratorKey in euclidean.getEnumeratorKeysAlwaysList(self.dictionaryObject, arguments):
-                       del self.dictionaryObject[enumeratorKey]
-               return self.dictionaryObject
-
-       def getIsIn(self, value):
-               'Determine if the value is in.'
-               return value in self.dictionaryObject
-
-       def getIsNotIn(self, value):
-               'Determine if the value is in.'
-               return not(value in self.dictionaryObject)
-
-       def getLength(self):
-               'Get the length.'
-               return len(self.dictionaryObject)
-
-       def getMax(self):
-               'Get the max.'
-               return max(self.dictionaryObject)
-
-       def getMin(self):
-               'Get the min.'
-               return min(self.dictionaryObject)
-
-       def index(self, value):
-               'Get the index element.'
-               for key, iteratorValue in self.dictionaryObject.iteritems():
-                       if iteratorValue == value:
-                               return key
-               raise ValueError('Value (%s) not found in index in DictionaryAttribute for (%s).' % (value, self.dictionaryObject))
-
-       def length(self):
-               'Get the length.'
-               return len(self.dictionaryObject)
-
-       def set(self, itemIndex, value):
-               'Set value.'
-               self.dictionaryObject[itemIndex] = value
-               return self.dictionaryObject
-
-
-globalAccessibleAttributeDictionary = 'count delete getIsIn getIsNotIn getLength getMax getMin index length set'.split()
-globalGetAccessibleAttributeSet = set(globalAccessibleAttributeDictionary)
-globalNativeFunctions = 'clear copy fromkeys get items keys pop popitem remove setdefault update values'.split()
-globalNativeFunctionSet = set(globalNativeFunctions)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables/list_attribute.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables/list_attribute.py
deleted file mode 100644 (file)
index 6813a19..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-"""
-List object attributes.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import euclidean
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def _getAccessibleAttribute(attributeName, listObject):
-       'Get the accessible attribute.'
-       if attributeName in globalNativeFunctionSet:
-               return getattr(listObject, attributeName, None)
-       if attributeName in globalGetAccessibleAttributeSet:
-               stringAttribute = ListAttribute(listObject)
-               return getattr(stringAttribute, attributeName, None)
-       return None
-
-
-class ListAttribute(object):
-       'Class to handle a list.'
-       def __init__(self, listObject):
-               'Initialize.'
-               self.listObject = listObject
-
-       def __repr__(self):
-               "Get the list representation of this ListAttribute."
-               return str(self.listObject)
-
-       def add(self, value):
-               'Get the concatenation, same as append.'
-               return self.listObject + [value]
-
-       def copy(self):
-               'Get the copy.'
-               return self.listObject[:]
-
-       def delete(self, arguments):
-               'Get the delete list.'
-               deleteList = []
-               enumeratorSet = set(euclidean.getEnumeratorKeysAlwaysList(self.listObject, arguments))
-               for elementIndex, element in enumerate(self.listObject):
-                       if elementIndex not in enumeratorSet:
-                               deleteList.append(element)
-               return deleteList
-
-       def get(self, itemIndex):
-               'Get value by index'
-               return self.listObject[itemIndex]
-
-       def getExpansion(self, items):
-               'Get the concatenated copies.'
-               expansion = []
-               for itemIndex in xrange(items):
-                       expansion += self.listObject[:]
-               return expansion
-
-       def getIsIn(self, value):
-               'Determine if the value is in.'
-               return value in self.listObject
-
-       def getIsNotIn(self, value):
-               'Determine if the value is in.'
-               return not(value in self.listObject)
-
-       def getLength(self):
-               'Get the length.'
-               return len(self.listObject)
-
-       def getMax(self):
-               'Get the max.'
-               return max(self.listObject)
-
-       def getMin(self):
-               'Get the min.'
-               return min(self.listObject)
-
-       def insert(self, insertIndex, value):
-               'Get the insert list.'
-               if insertIndex < 0:
-                       insertIndex += len(self.listObject)
-               insertIndex = max(0, insertIndex)
-               return self.listObject[: insertIndex] + [value] + self.listObject[insertIndex :]
-
-       def keys(self):
-               'Get the keys.'
-               return range(len(self.listObject))
-
-       def length(self):
-               'Get the length.'
-               return len(self.listObject)
-
-       def rindex(self, value):
-               'Get the rindex element.'
-               for elementIndex, element in enumerate(self.listObject):
-                       if element == value:
-                               return elementIndex
-               raise ValueError('Value (%s) not found in rindex in ListAttribute for (%s).' % (value, self.listObject))
-
-       def set(self, itemIndex, value):
-               'Set value.'
-               self.listObject[itemIndex] = value
-               return self.listObject
-
-       def values(self, arguments=None):
-               'Get the values.'
-               return self.listObject
-
-
-globalAccessibleAttributeDictionary = 'add copy count delete get getExpansion getIsIn getIsNotIn getLength getMax getMin'.split()
-globalAccessibleAttributeDictionary += 'insert keys length rindex set values'.split()
-globalGetAccessibleAttributeSet = set(globalAccessibleAttributeDictionary)
-globalNativeFunctions = 'append extend index pop remove reverse sort'.split()
-globalNativeFunctionSet = set(globalNativeFunctions)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables/string_attribute.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables/string_attribute.py
deleted file mode 100644 (file)
index 54b9258..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-"""
-String object attributes.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import euclidean
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def _getAccessibleAttribute(attributeName, stringObject):
-       'Get the accessible attribute.'
-       if attributeName in globalNativeFunctionSet:
-               return getattr(stringObject, attributeName, None)
-       if attributeName in globalGetAccessibleAttributeSet:
-               stringAttribute = StringAttribute(stringObject)
-               return getattr(stringAttribute, attributeName, None)
-       return None
-
-
-class StringAttribute(object):
-       'Class to handle a string.'
-       def __init__(self, stringObject):
-               'Initialize.'
-               self.stringObject = stringObject
-
-       def __repr__(self):
-               "Get the string representation of this StringAttribute."
-               return self.stringObject
-
-       def add(self, nextString):
-               'Get the add string, same as append.'
-               return self.stringObject + nextString
-
-       def append(self, nextString):
-               'Get the append string.'
-               return self.stringObject + nextString
-
-       def copy(self):
-               'Get the copy.'
-               return self.stringObject[:]
-
-       def delete(self, arguments):
-               'Get the delete string.'
-               deleteString = ''
-               enumeratorSet = set(euclidean.getEnumeratorKeysAlwaysList(self.stringObject, arguments))
-               for characterIndex, character in enumerate(self.stringObject):
-                       if characterIndex not in enumeratorSet:
-                               deleteString += character
-               return deleteString
-
-       def get(self, itemIndex):
-               'Get value by characterIndex'
-               return self.stringObject[itemIndex]
-
-       def getExpansion(self, items):
-               'Get the concatenated copies.'
-               expansion = ''
-               for itemIndex in xrange(items):
-                       expansion += self.stringObject
-               return expansion
-
-       def getIsIn(self, value):
-               'Determine if the value is in.'
-               return value in self.stringObject
-
-       def getIsNotIn(self, value):
-               'Determine if the value is in.'
-               return not(value in self.stringObject)
-
-       def getLength(self):
-               'Get the length.'
-               return len(self.stringObject)
-
-       def getMax(self):
-               'Get the max.'
-               return max(self.stringObject)
-
-       def getMin(self):
-               'Get the min.'
-               return min(self.stringObject)
-
-       def insert(self, insertIndex, value):
-               'Get the insert string.'
-               if insertIndex < 0:
-                       insertIndex += len(self.stringObject)
-               insertIndex = max(0, insertIndex)
-               return self.stringObject[: insertIndex] + value + self.stringObject[insertIndex :]
-
-       def keys(self):
-               'Get the keys.'
-               return range(len(self.stringObject))
-
-       def length(self):
-               'Get the length.'
-               return len(self.stringObject)
-
-       def remove(self, value):
-               'Get the remove string.'
-               removeIndex = self.stringObject.find(value)
-               if removeIndex > -1:
-                       return self.stringObject[: removeIndex] + self.stringObject[removeIndex + len(value) :]
-               return self.stringObject
-
-       def reverse(self):
-               'Get the reverse string.'
-               return self.stringObject[: : -1]
-
-       def set(self, itemIndex, value):
-               'Set value.'
-               self.stringObject[itemIndex] = value
-               return self.stringObject
-
-       def values(self):
-               'Get the values.'
-               values = []
-               for character in self.stringObject:
-                       values.append(character)
-               return values
-
-
-globalAccessibleAttributeDictionary = 'add append copy delete get getExpansion getIsIn getIsNotIn getLength getMax getMin'.split()
-globalAccessibleAttributeDictionary += 'insert keys length remove reverse set values'.split()
-globalGetAccessibleAttributeSet = set(globalAccessibleAttributeDictionary)
-globalNativeFunctions = 'capitalize center count decode encode endswith expandtabs find format index isalnum join'.split()
-globalNativeFunctions += 'isalpha isdigit islower isspace istitle isupper ljust lower lstrip partition replace rfind rindex'.split()
-globalNativeFunctions += 'rjust rpartition rsplit rstrip split splitlines startswith strip swapcase title translate upper zfill'.split()
-globalNativeFunctionSet = set(globalNativeFunctions)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/_math.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/_math.py
deleted file mode 100644 (file)
index aecfb30..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-"""
-Boolean geometry utilities.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import euclidean
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalNativeFunctions = 'acos asin atan atan2 ceil cos cosh degrees e exp fabs floor fmod frexp hypot'.split()
-globalNativeFunctions += 'ldexp log log10 modf pi pow radians sin sinh sqrt tan tanh trunc'.split()
-globalNativeFunctionSet = set(globalNativeFunctions)
-#Constants from: http://www.physlink.com/reference/MathConstants.cfm
-#Tau is from: http://tauday.com/
-#If anyone wants to add stuff, more constants are at: http://en.wikipedia.org/wiki/Mathematical_constant
-globalMathConstantDictionary = {
-       'euler' : 0.5772156649015328606065120,
-       'golden' : euclidean.globalGoldenRatio,
-       'goldenAngle' : euclidean.globalGoldenAngle,
-       'goldenRatio' : euclidean.globalGoldenRatio,
-       'tau' : euclidean.globalTau}
-
-
-def _getAccessibleAttribute(attributeName):
-       'Get the accessible attribute.'
-       if attributeName in globalMathConstantDictionary:
-               return globalMathConstantDictionary[attributeName]
-       if attributeName in globalNativeFunctionSet:
-               return math.__dict__[attributeName]
-       if attributeName in globalAccessibleAttributeDictionary:
-               return globalAccessibleAttributeDictionary[attributeName]
-       return None
-
-
-def getAbs(value):
-       'Get the abs.'
-       return abs(value)
-
-def getBoolean(value):
-       'Get the boolean.'
-       return bool(value)
-
-def getDivmod(x, y):
-       'Get the divmod.'
-       return divmod(x, y)
-
-def getFloat(value):
-       'Get the float.'
-       return float(value)
-
-def getHex(value):
-       'Get the hex.'
-       return hex(value)
-
-def getInt(value):
-       'Get the int.'
-       return int(value)
-
-def getLong(value):
-       'Get the long.'
-       return long(value)
-
-def getMax(first, second):
-       'Get the max.'
-       return max(first, second)
-
-def getMin(first, second):
-       'Get the min.'
-       return min(first, second)
-
-def getRound(value):
-       'Get the round.'
-       return round(value)
-
-def getString(value):
-       'Get the string.'
-       return str(value)
-
-
-globalAccessibleAttributeDictionary = {
-       'abs' : getAbs,
-       'boolean' : getBoolean,
-       'divmod' : getDivmod,
-       'float' : getFloat,
-       'hex' : getHex,
-       'int' : getInt,
-       'long' : getLong,
-       'max' : getMax,
-       'min' : getMin,
-       'round' : getRound,
-       'string' : getString}
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/euclid.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/euclid.py
deleted file mode 100644 (file)
index f9db2ba..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-"""
-Boolean geometry utilities.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities.vector3index import Vector3Index
-from fabmetheus_utilities import euclidean
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def _getAccessibleAttribute(attributeName):
-       'Get the accessible attribute.'
-       if attributeName in globalAccessibleAttributeDictionary:
-               return globalAccessibleAttributeDictionary[attributeName]
-       return None
-
-def getComplex(x=0.0, y=0.0):
-       'Get the complex.'
-       return complex(x, y)
-
-def getCylindrical(azimuthDegrees, radius=1.0, z=0.0):
-       'Get the cylindrical vector3 by degrees.'
-       return getCylindricalByRadians(math.radians(azimuthDegrees), radius, z)
-
-def getCylindricalByRadians(azimuthRadians, radius=1.0, z=0.0):
-       'Get the cylindrical vector3 by radians.'
-       polar = radius * euclidean.getWiddershinsUnitPolar(azimuthRadians)
-       return Vector3(polar.real, polar.imag, z)
-
-def getNestedVectorTestExample(x=0.0, y=0.0, z=0.0):
-       'Get the NestedVectorTestExample.'
-       return NestedVectorTestExample(Vector3(x, y, z))
-
-def getPolar(angleDegrees, radius=1.0):
-       'Get the complex polar by degrees.'
-       return radius * euclidean.getWiddershinsUnitPolar(math.radians(angleDegrees))
-
-def getPolarByRadians(angleRadians, radius=1.0):
-       'Get the complex polar by radians.'
-       return radius * euclidean.getWiddershinsUnitPolar(angleRadians)
-
-def getSpherical(azimuthDegrees, elevationDegrees, radius=1.0):
-       'Get the spherical vector3 unit by degrees.'
-       return getSphericalByRadians(math.radians(azimuthDegrees), math.radians(elevationDegrees), radius)
-
-def getSphericalByRadians(azimuthRadians, elevationRadians, radius=1.0):
-       'Get the spherical vector3 unit by radians.'
-       elevationComplex = euclidean.getWiddershinsUnitPolar(elevationRadians)
-       azimuthComplex = euclidean.getWiddershinsUnitPolar(azimuthRadians) * elevationComplex.real
-       return Vector3(azimuthComplex.real, azimuthComplex.imag, elevationComplex.imag) * radius
-
-def getVector3(x=0.0, y=0.0, z=0.0):
-       'Get the vector3.'
-       return Vector3(x, y, z)
-
-def getVector3Index(index=0, x=0.0, y=0.0, z=0.0):
-       'Get the vector3.'
-       return Vector3Index(index, x, y, z)
-
-
-class NestedVectorTestExample(object):
-       'Class to test local attribute.'
-       def __init__(self, vector3):
-               'Get the accessible attribute.'
-               self.vector3 = vector3
-
-       def _getAccessibleAttribute(self, attributeName):
-               "Get the accessible attribute."
-               if attributeName == 'vector3':
-                       return getattr(self, attributeName, None)
-               return None
-
-
-globalAccessibleAttributeDictionary = {
-       'complex' : getComplex,
-       'getCylindrical' : getCylindrical,
-       'getCylindricalByRadians' : getCylindricalByRadians,
-       'getPolar' : getPolar,
-       'getPolarByRadians' : getPolarByRadians,
-       'getSpherical' : getSpherical,
-       'getSphericalByRadians' : getSphericalByRadians,
-       'NestedVectorTestExample' : getNestedVectorTestExample,
-       'Vector3' : getVector3,
-       'Vector3Index' : getVector3Index}
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/measure.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/measure.py
deleted file mode 100644 (file)
index fbd6828..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-"""
-Boolean geometry utilities.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import euclidean
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def _getAccessibleAttribute(attributeName):
-       'Get the accessible attribute.'
-       if attributeName in globalAccessibleAttributeDictionary:
-               return globalAccessibleAttributeDictionary[attributeName]
-       return None
-
-def getBoundingBoxByPaths(elementNode):
-       'Get bounding box of the transformed paths of the xmlObject of the elementNode.'
-       transformedPaths = elementNode.xmlObject.getTransformedPaths()
-       maximum = euclidean.getMaximumByVector3Paths(transformedPaths)
-       minimum = euclidean.getMinimumByVector3Paths(transformedPaths)
-       return [minimum, maximum]
-
-def getCenterByPaths(elementNode):
-       'Get center of the transformed paths of the xmlObject of the elementNode.'
-       transformedPaths = elementNode.xmlObject.getTransformedPaths()
-       return 0.5 * (euclidean.getMaximumByVector3Paths(transformedPaths) + euclidean.getMinimumByVector3Paths(transformedPaths))
-
-def getExtentByPaths(elementNode):
-       'Get extent of the transformed paths of the xmlObject of the elementNode.'
-       transformedPaths = elementNode.xmlObject.getTransformedPaths()
-       return euclidean.getMaximumByVector3Paths(transformedPaths) - euclidean.getMinimumByVector3Paths(transformedPaths)
-
-def getInradiusByPaths(elementNode):
-       'Get inradius of the transformed paths of the xmlObject of the elementNode.'
-       return 0.5 * getExtentByPaths(elementNode)
-
-def getMinimumByPaths(elementNode):
-       'Get minimum of the transformed paths of the xmlObject of the elementNode.'
-       return euclidean.getMinimumByVector3Paths(elementNode.xmlObject.getTransformedPaths())
-
-def getMaximumByPaths(elementNode):
-       'Get maximum of the transformed paths of the xmlObject of the elementNode.'
-       return euclidean.getMaximumByVector3Paths(elementNode.xmlObject.getTransformedPaths())
-
-globalAccessibleAttributeDictionary = {
-       'getBoundingBoxByPaths' : getBoundingBoxByPaths,
-       'getCenterByPaths' : getCenterByPaths,
-       'getExtentByPaths' : getExtentByPaths,
-       'getInradiusByPaths' : getInradiusByPaths,
-       'getMaximumByPaths' : getMaximumByPaths,
-       'getMinimumByPaths' : getMinimumByPaths}
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/print.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/print.py
deleted file mode 100644 (file)
index cdae956..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-"""
-Boolean geometry utilities.
-
-"""
-
-from __future__ import absolute_import
-
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def _getAccessibleAttribute(attributeName):
-       'Get the accessible attribute.'
-       if attributeName in globalAccessibleAttributeDictionary:
-               return globalAccessibleAttributeDictionary[attributeName]
-       return None
-
-def continuous(valueString):
-       'Print continuous.'
-       sys.stdout.write(str(valueString))
-       return valueString
-
-def line(valueString):
-       'Print line.'
-       print(valueString)
-       return valueString
-
-
-globalAccessibleAttributeDictionary = {'continuous' : continuous, 'line' : line}
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/example.csv b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/example.csv
deleted file mode 100644 (file)
index eeecad1..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-"A"    
-0      0
-2      8
-4      0
-       
-1      4
-3      4
-       
-"B"    
-0      4
-2      4
-4      5
-4      7
-3      8
-0      8
-0      0
-3      0
-4      1
-4      3
-2      4
-       
-"C"    
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/matrix.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/geometry_utilities/matrix.py
deleted file mode 100644 (file)
index c124cc6..0000000
+++ /dev/null
@@ -1,492 +0,0 @@
-"""
-Boolean geometry four by four matrix.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import xml_simple_writer
-import cStringIO
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalExecutionOrder = 300
-
-
-def addVertexes(geometryOutput, vertexes):
-       'Add the vertexes.'
-       if geometryOutput.__class__ == list:
-               for element in geometryOutput:
-                       addVertexes(element, vertexes)
-               return
-       if geometryOutput.__class__ == dict:
-               for geometryOutputKey in geometryOutput.keys():
-                       if geometryOutputKey == 'vertex':
-                               vertexes += geometryOutput[geometryOutputKey]
-                       else:
-                               addVertexes(geometryOutput[geometryOutputKey], vertexes)
-
-def getBranchMatrix(elementNode):
-       'Get matrix starting from the object if it exists, otherwise get a matrix starting from stratch.'
-       branchMatrix = Matrix()
-       matrixChildElement = elementNode.getFirstChildByLocalName('matrix')
-       if matrixChildElement != None:
-               branchMatrix = branchMatrix.getFromElementNode(matrixChildElement, '')
-       branchMatrix = branchMatrix.getFromElementNode(elementNode, 'matrix.')
-       if elementNode.xmlObject == None:
-               return branchMatrix
-       elementNodeMatrix = elementNode.xmlObject.getMatrix4X4()
-       if elementNodeMatrix == None:
-               return branchMatrix
-       return elementNodeMatrix.getOtherTimesSelf(branchMatrix.tetragrid)
-
-def getBranchMatrixSetElementNode(elementNode):
-       'Get matrix starting from the object if it exists, otherwise get a matrix starting from stratch.'
-       branchMatrix = getBranchMatrix(elementNode)
-       setElementNodeDictionaryMatrix(elementNode, branchMatrix)
-       return branchMatrix
-
-def getCumulativeVector3Remove(defaultVector3, elementNode, prefix):
-       'Get cumulative vector3 and delete the prefixed attributes.'
-       if prefix == '':
-               defaultVector3.x = evaluate.getEvaluatedFloat(defaultVector3.x, elementNode, 'x')
-               defaultVector3.y = evaluate.getEvaluatedFloat(defaultVector3.y, elementNode, 'y')
-               defaultVector3.z = evaluate.getEvaluatedFloat(defaultVector3.z, elementNode, 'z')
-               euclidean.removeElementsFromDictionary(elementNode.attributes, ['x', 'y', 'z'])
-               prefix = 'cartesian'
-       defaultVector3 = evaluate.getVector3ByPrefix(defaultVector3, elementNode, prefix)
-       euclidean.removePrefixFromDictionary(elementNode.attributes, prefix)
-       return defaultVector3
-
-def getDiagonalSwitchedTetragrid(angleDegrees, diagonals):
-       'Get the diagonals and switched matrix by degrees.'
-       return getDiagonalSwitchedTetragridByRadians(math.radians(angleDegrees), diagonals)
-
-def getDiagonalSwitchedTetragridByPolar(diagonals, unitPolar):
-       'Get the diagonals and switched matrix by unitPolar.'
-       diagonalSwitchedTetragrid = getIdentityTetragrid()
-       for diagonal in diagonals:
-               diagonalSwitchedTetragrid[diagonal][diagonal] = unitPolar.real
-       diagonalSwitchedTetragrid[diagonals[0]][diagonals[1]] = -unitPolar.imag
-       diagonalSwitchedTetragrid[diagonals[1]][diagonals[0]] = unitPolar.imag
-       return diagonalSwitchedTetragrid
-
-def getDiagonalSwitchedTetragridByRadians(angleRadians, diagonals):
-       'Get the diagonals and switched matrix by radians.'
-       return getDiagonalSwitchedTetragridByPolar(diagonals, euclidean.getWiddershinsUnitPolar(angleRadians))
-
-def getIdentityTetragrid(tetragrid=None):
-       'Get four by four matrix with diagonal elements set to one.'
-       if tetragrid == None:
-               return [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]]
-       return tetragrid
-
-def getIsIdentityTetragrid(tetragrid):
-       'Determine if the tetragrid is the identity tetragrid.'
-       for column in xrange(4):
-               for row in xrange(4):
-                       if column == row:
-                               if tetragrid[column][row] != 1.0:
-                                       return False
-                       elif tetragrid[column][row] != 0.0:
-                               return False
-       return True
-
-def getIsIdentityTetragridOrNone(tetragrid):
-       'Determine if the tetragrid is None or if it is the identity tetragrid.'
-       if tetragrid == None:
-               return True
-       return getIsIdentityTetragrid(tetragrid)
-
-def getKeyA(row, column, prefix=''):
-       'Get the a format key string from row & column, counting from zero.'
-       return '%sa%s%s' % (prefix, row, column)
-
-def getKeyM(row, column, prefix=''):
-       'Get the m format key string from row & column, counting from one.'
-       return '%sm%s%s' % (prefix, row + 1, column + 1)
-
-def getKeysA(prefix=''):
-       'Get the matrix keys, counting from zero.'
-       keysA = []
-       for row in xrange(4):
-               for column in xrange(4):
-                       key = getKeyA(row, column, prefix)
-                       keysA.append(key)
-       return keysA
-
-def getKeysM(prefix=''):
-       'Get the matrix keys, counting from one.'
-       keysM = []
-       for row in xrange(4):
-               for column in xrange(4):
-                       key = getKeyM(row, column, prefix)
-                       keysM.append(key)
-       return keysM
-
-def getRemovedFloat(defaultFloat, elementNode, key, prefix):
-       'Get the float by the key and the prefix.'
-       prefixKey = prefix + key
-       if prefixKey in elementNode.attributes:
-               floatValue = evaluate.getEvaluatedFloat(None, elementNode, prefixKey)
-               if floatValue == None:
-                       print('Warning, evaluated value in getRemovedFloatByKeys in matrix is None for key:')
-                       print(prefixKey)
-                       print('for elementNode dictionary value:')
-                       print(elementNode.attributes[prefixKey])
-                       print('for elementNode dictionary:')
-                       print(elementNode.attributes)
-               else:
-                       defaultFloat = floatValue
-               del elementNode.attributes[prefixKey]
-       return defaultFloat
-
-def getRemovedFloatByKeys(defaultFloat, elementNode, keys, prefix):
-       'Get the float by the keys and the prefix.'
-       for key in keys:
-               defaultFloat = getRemovedFloat(defaultFloat, elementNode, key, prefix)
-       return defaultFloat
-
-def getRotateAroundAxisTetragrid(elementNode, prefix):
-       'Get rotate around axis tetragrid and delete the axis and angle attributes.'
-       angle = getRemovedFloatByKeys(0.0, elementNode, ['angle', 'counterclockwise'], prefix)
-       angle -= getRemovedFloat(0.0, elementNode, 'clockwise', prefix)
-       if angle == 0.0:
-               return None
-       angleRadians = math.radians(angle)
-       axis = getCumulativeVector3Remove(Vector3(), elementNode, prefix + 'axis')
-       axisLength = abs(axis)
-       if axisLength <= 0.0:
-               print('Warning, axisLength was zero in getRotateAroundAxisTetragrid in matrix so nothing will be done for:')
-               print(elementNode)
-               return None
-       axis /= axisLength
-       tetragrid = getIdentityTetragrid()
-       cosAngle = math.cos(angleRadians)
-       sinAngle = math.sin(angleRadians)
-       oneMinusCos = 1.0 - math.cos(angleRadians)
-       xx = axis.x * axis.x
-       xy = axis.x * axis.y
-       xz = axis.x * axis.z
-       yy = axis.y * axis.y
-       yz = axis.y * axis.z
-       zz = axis.z * axis.z
-       tetragrid[0] = [cosAngle + xx * oneMinusCos, xy * oneMinusCos - axis.z * sinAngle, xz * oneMinusCos + axis.y * sinAngle, 0.0]
-       tetragrid[1] = [xy * oneMinusCos + axis.z * sinAngle, cosAngle + yy * oneMinusCos, yz * oneMinusCos - axis.x * sinAngle, 0.0]
-       tetragrid[2] = [xz * oneMinusCos - axis.y * sinAngle, yz * oneMinusCos + axis.x * sinAngle, cosAngle + zz * oneMinusCos, 0.0]
-       return tetragrid
-
-def getRotateTetragrid(elementNode, prefix):
-       'Get rotate tetragrid and delete the rotate attributes.'
-       # http://en.wikipedia.org/wiki/Rotation_matrix
-       rotateMatrix = Matrix()
-       rotateMatrix.tetragrid = getRotateAroundAxisTetragrid(elementNode, prefix)
-       zAngle = getRemovedFloatByKeys(0.0, elementNode, ['axisclockwisez', 'observerclockwisez', 'z'], prefix)
-       zAngle -= getRemovedFloatByKeys(0.0, elementNode, ['axiscounterclockwisez', 'observercounterclockwisez'], prefix)
-       if zAngle != 0.0:
-               rotateMatrix.tetragrid = getTetragridTimesOther(getDiagonalSwitchedTetragrid(-zAngle, [0, 1]), rotateMatrix.tetragrid)
-       xAngle = getRemovedFloatByKeys(0.0, elementNode, ['axisclockwisex', 'observerclockwisex', 'x'], prefix)
-       xAngle -= getRemovedFloatByKeys(0.0, elementNode, ['axiscounterclockwisex', 'observercounterclockwisex'], prefix)
-       if xAngle != 0.0:
-               rotateMatrix.tetragrid = getTetragridTimesOther(getDiagonalSwitchedTetragrid(-xAngle, [1, 2]), rotateMatrix.tetragrid)
-       yAngle = getRemovedFloatByKeys(0.0, elementNode, ['axiscounterclockwisey', 'observerclockwisey', 'y'], prefix)
-       yAngle -= getRemovedFloatByKeys(0.0, elementNode, ['axisclockwisey', 'observercounterclockwisey'], prefix)
-       if yAngle != 0.0:
-               rotateMatrix.tetragrid = getTetragridTimesOther(getDiagonalSwitchedTetragrid(yAngle, [0, 2]), rotateMatrix.tetragrid)
-       return rotateMatrix.tetragrid
-
-def getScaleTetragrid(elementNode, prefix):
-       'Get scale matrix and delete the scale attributes.'
-       scaleDefaultVector3 = Vector3(1.0, 1.0, 1.0)
-       scale = getCumulativeVector3Remove(scaleDefaultVector3.copy(), elementNode, prefix)
-       if scale == scaleDefaultVector3:
-               return None
-       return [[scale.x, 0.0, 0.0, 0.0], [0.0, scale.y, 0.0, 0.0], [0.0, 0.0, scale.z, 0.0], [0.0, 0.0, 0.0, 1.0]]
-
-def getTetragridA(elementNode, prefix, tetragrid):
-       'Get the tetragrid from the elementNode letter a values.'
-       keysA = getKeysA(prefix)
-       evaluatedDictionary = evaluate.getEvaluatedDictionaryByEvaluationKeys(elementNode, keysA)
-       if len(evaluatedDictionary.keys()) < 1:
-               return tetragrid
-       for row in xrange(4):
-               for column in xrange(4):
-                       key = getKeyA(row, column, prefix)
-                       if key in evaluatedDictionary:
-                               value = evaluatedDictionary[key]
-                               if value == None or value == 'None':
-                                       print('Warning, value in getTetragridA in matrix is None for key for dictionary:')
-                                       print(key)
-                                       print(evaluatedDictionary)
-                               else:
-                                       tetragrid = getIdentityTetragrid(tetragrid)
-                                       tetragrid[row][column] = float(value)
-       euclidean.removeElementsFromDictionary(elementNode.attributes, keysA)
-       return tetragrid
-
-def getTetragridC(elementNode, prefix, tetragrid):
-       'Get the matrix Tetragrid from the elementNode letter c values.'
-       columnKeys = 'Pc1 Pc2 Pc3 Pc4'.replace('P', prefix).split()
-       evaluatedDictionary = evaluate.getEvaluatedDictionaryByEvaluationKeys(elementNode, columnKeys)
-       if len(evaluatedDictionary.keys()) < 1:
-               return tetragrid
-       for columnKeyIndex, columnKey in enumerate(columnKeys):
-               if columnKey in evaluatedDictionary:
-                       value = evaluatedDictionary[columnKey]
-                       if value == None or value == 'None':
-                               print('Warning, value in getTetragridC in matrix is None for columnKey for dictionary:')
-                               print(columnKey)
-                               print(evaluatedDictionary)
-                       else:
-                               tetragrid = getIdentityTetragrid(tetragrid)
-                               for elementIndex, element in enumerate(value):
-                                       tetragrid[elementIndex][columnKeyIndex] = element
-       euclidean.removeElementsFromDictionary(elementNode.attributes, columnKeys)
-       return tetragrid
-
-def getTetragridCopy(tetragrid):
-       'Get tetragrid copy.'
-       if tetragrid == None:
-               return None
-       tetragridCopy = []
-       for tetragridRow in tetragrid:
-               tetragridCopy.append(tetragridRow[:])
-       return tetragridCopy
-
-def getTetragridM(elementNode, prefix, tetragrid):
-       'Get the tetragrid from the elementNode letter m values.'
-       keysM = getKeysM(prefix)
-       evaluatedDictionary = evaluate.getEvaluatedDictionaryByEvaluationKeys(elementNode, keysM)
-       if len(evaluatedDictionary.keys()) < 1:
-               return tetragrid
-       for row in xrange(4):
-               for column in xrange(4):
-                       key = getKeyM(row, column, prefix)
-                       if key in evaluatedDictionary:
-                               value = evaluatedDictionary[key]
-                               if value == None or value == 'None':
-                                       print('Warning, value in getTetragridM in matrix is None for key for dictionary:')
-                                       print(key)
-                                       print(evaluatedDictionary)
-                               else:
-                                       tetragrid = getIdentityTetragrid(tetragrid)
-                                       tetragrid[row][column] = float(value)
-       euclidean.removeElementsFromDictionary(elementNode.attributes, keysM)
-       return tetragrid
-
-def getTetragridMatrix(elementNode, prefix, tetragrid):
-       'Get the tetragrid from the elementNode matrix value.'
-       matrixKey = prefix + 'matrix'
-       evaluatedDictionary = evaluate.getEvaluatedDictionaryByEvaluationKeys(elementNode, [matrixKey])
-       if len(evaluatedDictionary.keys()) < 1:
-               return tetragrid
-       value = evaluatedDictionary[matrixKey]
-       if value == None or value == 'None':
-               print('Warning, value in getTetragridMatrix in matrix is None for matrixKey for dictionary:')
-               print(matrixKey)
-               print(evaluatedDictionary)
-       else:
-               tetragrid = getIdentityTetragrid(tetragrid)
-               for rowIndex, row in enumerate(value):
-                       for elementIndex, element in enumerate(row):
-                               tetragrid[rowIndex][elementIndex] = element
-       euclidean.removeElementsFromDictionary(elementNode.attributes, [matrixKey])
-       return tetragrid
-
-def getTetragridR(elementNode, prefix, tetragrid):
-       'Get the tetragrid from the elementNode letter r values.'
-       rowKeys = 'Pr1 Pr2 Pr3 Pr4'.replace('P', prefix).split()
-       evaluatedDictionary = evaluate.getEvaluatedDictionaryByEvaluationKeys(elementNode, rowKeys)
-       if len(evaluatedDictionary.keys()) < 1:
-               return tetragrid
-       for rowKeyIndex, rowKey in enumerate(rowKeys):
-               if rowKey in evaluatedDictionary:
-                       value = evaluatedDictionary[rowKey]
-                       if value == None or value == 'None':
-                               print('Warning, value in getTetragridR in matrix is None for rowKey for dictionary:')
-                               print(rowKey)
-                               print(evaluatedDictionary)
-                       else:
-                               tetragrid = getIdentityTetragrid(tetragrid)
-                               for elementIndex, element in enumerate(value):
-                                       tetragrid[rowKeyIndex][elementIndex] = element
-       euclidean.removeElementsFromDictionary(elementNode.attributes, rowKeys)
-       return tetragrid
-
-def getTetragridTimesOther(firstTetragrid, otherTetragrid ):
-       'Get this matrix multiplied by the other matrix.'
-       #A down, B right from http://en.wikipedia.org/wiki/Matrix_multiplication
-       if firstTetragrid == None:
-               return otherTetragrid
-       if otherTetragrid == None:
-               return firstTetragrid
-       tetragridTimesOther = []
-       for row in xrange(4):
-               matrixRow = firstTetragrid[row]
-               tetragridTimesOtherRow = []
-               tetragridTimesOther.append(tetragridTimesOtherRow)
-               for column in xrange(4):
-                       dotProduct = 0
-                       for elementIndex in xrange(4):
-                               dotProduct += matrixRow[elementIndex] * otherTetragrid[elementIndex][column]
-                       tetragridTimesOtherRow.append(dotProduct)
-       return tetragridTimesOther
-
-def getTransformedByList(floatList, point):
-       'Get the point transformed by the array.'
-       return floatList[0] * point.x + floatList[1] * point.y + floatList[2] * point.z + floatList[3]
-
-def getTransformedVector3(tetragrid, vector3):
-       'Get the vector3 multiplied by a matrix.'
-       if getIsIdentityTetragridOrNone(tetragrid):
-               return vector3.copy()
-       return getTransformedVector3Blindly(tetragrid, vector3)
-
-def getTransformedVector3Blindly(tetragrid, vector3):
-       'Get the vector3 multiplied by a tetragrid without checking if the tetragrid exists.'
-       return Vector3(
-               getTransformedByList(tetragrid[0], vector3),
-               getTransformedByList(tetragrid[1], vector3),
-               getTransformedByList(tetragrid[2], vector3))
-
-def getTransformedVector3s(tetragrid, vector3s):
-       'Get the vector3s multiplied by a matrix.'
-       if getIsIdentityTetragridOrNone(tetragrid):
-               return euclidean.getPathCopy(vector3s)
-       transformedVector3s = []
-       for vector3 in vector3s:
-               transformedVector3s.append(getTransformedVector3Blindly(tetragrid, vector3))
-       return transformedVector3s
-
-def getTransformTetragrid(elementNode, prefix):
-       'Get the tetragrid from the elementNode.'
-       tetragrid = getTetragridA(elementNode, prefix, None)
-       tetragrid = getTetragridC(elementNode, prefix, tetragrid)
-       tetragrid = getTetragridM(elementNode, prefix, tetragrid)
-       tetragrid = getTetragridMatrix(elementNode, prefix, tetragrid)
-       tetragrid = getTetragridR(elementNode, prefix, tetragrid)
-       return tetragrid
-
-def getTranslateTetragrid(elementNode, prefix):
-       'Get translate matrix and delete the translate attributes.'
-       translation = getCumulativeVector3Remove(Vector3(), elementNode, prefix)
-       if translation.getIsDefault():
-               return None
-       return getTranslateTetragridByTranslation(translation)
-
-def getTranslateTetragridByTranslation(translation):
-       'Get translate tetragrid by translation.'
-       return [[1.0, 0.0, 0.0, translation.x], [0.0, 1.0, 0.0, translation.y], [0.0, 0.0, 1.0, translation.z], [0.0, 0.0, 0.0, 1.0]]
-
-def getVertexes(geometryOutput):
-       'Get the vertexes.'
-       vertexes = []
-       addVertexes(geometryOutput, vertexes)
-       return vertexes
-
-def setAttributesToMultipliedTetragrid(elementNode, tetragrid):
-       'Set the element attribute dictionary and element matrix to the matrix times the tetragrid.'
-       setElementNodeDictionaryMatrix(elementNode, getBranchMatrix(elementNode).getOtherTimesSelf(tetragrid))
-
-def setElementNodeDictionaryMatrix(elementNode, matrix4X4):
-       'Set the element attribute dictionary or element matrix to the matrix.'
-       if elementNode.xmlObject == None:
-               elementNode.attributes.update(matrix4X4.getAttributes('matrix.'))
-       else:
-               elementNode.xmlObject.matrix4X4 = matrix4X4
-
-def transformVector3Blindly(tetragrid, vector3):
-       'Transform the vector3 by a tetragrid without checking to see if it exists.'
-       x = getTransformedByList(tetragrid[0], vector3)
-       y = getTransformedByList(tetragrid[1], vector3)
-       z = getTransformedByList(tetragrid[2], vector3)
-       vector3.x = x
-       vector3.y = y
-       vector3.z = z
-
-def transformVector3ByMatrix(tetragrid, vector3):
-       'Transform the vector3 by a matrix.'
-       if getIsIdentityTetragridOrNone(tetragrid):
-               return
-       transformVector3Blindly(tetragrid, vector3)
-
-def transformVector3sByMatrix(tetragrid, vector3s):
-       'Transform the vector3s by a matrix.'
-       if getIsIdentityTetragridOrNone(tetragrid):
-               return
-       for vector3 in vector3s:
-               transformVector3Blindly(tetragrid, vector3)
-
-
-class Matrix(object):
-       'A four by four matrix.'
-       def __init__(self, tetragrid=None):
-               'Add empty lists.'
-               self.tetragrid = getTetragridCopy(tetragrid)
-
-       def __eq__(self, other):
-               'Determine whether this matrix is identical to other one.'
-               if other == None:
-                       return False
-               if other.__class__ != self.__class__:
-                       return False
-               return other.tetragrid == self.tetragrid
-
-       def __ne__(self, other):
-               'Determine whether this vector is not identical to other one.'
-               return not self.__eq__(other)
-
-       def __repr__(self):
-               'Get the string representation of this four by four matrix.'
-               output = cStringIO.StringIO()
-               self.addXML(0, output)
-               return output.getvalue()
-
-       def addXML(self, depth, output):
-               'Add xml for this object.'
-               attributes = self.getAttributes()
-               if len(attributes) > 0:
-                       xml_simple_writer.addClosedXMLTag(attributes, depth, self.__class__.__name__.lower(), output)
-
-       def getAttributes(self, prefix=''):
-               'Get the attributes from row column attribute strings, counting from one.'
-               attributes = {}
-               if self.tetragrid == None:
-                       return attributes
-               for row in xrange(4):
-                       for column in xrange(4):
-                               default = float(column == row)
-                               value = self.tetragrid[row][column]
-                               if abs( value - default ) > 0.00000000000001:
-                                       if abs(value) < 0.00000000000001:
-                                               value = 0.0
-                                       attributes[prefix + getKeyM(row, column)] = value
-               return attributes
-
-       def getFromElementNode(self, elementNode, prefix):
-               'Get the values from row column attribute strings, counting from one.'
-               attributes = elementNode.attributes
-               if attributes == None:
-                       return self
-               self.tetragrid = getTetragridTimesOther(getTransformTetragrid(elementNode, prefix), self.tetragrid)
-               self.tetragrid = getTetragridTimesOther(getScaleTetragrid(elementNode, 'scale.'), self.tetragrid)
-               self.tetragrid = getTetragridTimesOther(getRotateTetragrid(elementNode, 'rotate.'), self.tetragrid)
-               self.tetragrid = getTetragridTimesOther(getTranslateTetragrid(elementNode, 'translate.'), self.tetragrid)
-               return self
-
-       def getOtherTimesSelf(self, otherTetragrid):
-               'Get this matrix reverse multiplied by the other matrix.'
-               return Matrix(getTetragridTimesOther(otherTetragrid, self.tetragrid))
-
-       def getSelfTimesOther(self, otherTetragrid):
-               'Get this matrix multiplied by the other matrix.'
-               return Matrix(getTetragridTimesOther(self.tetragrid, otherTetragrid))
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_matrix/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_matrix/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_matrix/_scale.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_matrix/_scale.py
deleted file mode 100644 (file)
index b57cc56..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-"""
-Boolean geometry scale.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities.vector3 import Vector3
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalExecutionOrder = 340
-
-
-def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix):
-       "Get equated geometryOutput."
-       scalePoints( elementNode, matrix.getVertexes(geometryOutput), prefix )
-       return geometryOutput
-
-def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
-       "Get equated paths."
-       scalePoints( elementNode, loop, prefix )
-       return [loop]
-
-def getNewDerivation(elementNode, prefix, sideLength):
-       'Get new derivation.'
-       return ScaleDerivation(elementNode)
-
-def manipulateElementNode(elementNode, target):
-       "Manipulate the xml element."
-       derivation = ScaleDerivation(elementNode)
-       if derivation.scaleTetragrid == None:
-               print('Warning, scaleTetragrid was None in scale so nothing will be done for:')
-               print(elementNode)
-               return
-       matrix.setAttributesToMultipliedTetragrid(target, derivation.scaleTetragrid)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       solid.processElementNodeByFunction(elementNode, manipulateElementNode)
-
-def scalePoints(elementNode, points, prefix):
-       "Scale the points."
-       scaleVector3Default = Vector3(1.0, 1.0, 1.0)
-       scaleVector3 = matrix.getCumulativeVector3Remove(scaleVector3Default.copy(), elementNode, prefix)
-       if scaleVector3 == scaleVector3Default:
-               return
-       for point in points:
-               point.x *= scaleVector3.x
-               point.y *= scaleVector3.y
-               point.z *= scaleVector3.z
-
-
-class ScaleDerivation(object):
-       "Class to hold scale variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.scaleTetragrid = matrix.getScaleTetragrid(elementNode, '')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_matrix/rotate.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_matrix/rotate.py
deleted file mode 100644 (file)
index 5776d35..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-"""
-Boolean geometry rotate.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalExecutionOrder = 360
-
-
-def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix):
-       'Get equated geometryOutput.'
-       rotatePoints(elementNode, matrix.getVertexes(geometryOutput), prefix)
-       return geometryOutput
-
-def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
-       'Get equated paths.'
-       rotatePoints(elementNode, loop, prefix)
-       return [loop]
-
-def getNewDerivation(elementNode, prefix, sideLength):
-       'Get new derivation.'
-       return RotateDerivation(elementNode, prefix)
-
-def manipulateElementNode(elementNode, target):
-       'Manipulate the xml element.'
-       derivation = RotateDerivation(elementNode, '')
-       if derivation.rotateTetragrid == None:
-               print('Warning, rotateTetragrid was None in rotate so nothing will be done for:')
-               print(elementNode)
-               return
-       matrix.setAttributesToMultipliedTetragrid(target, derivation.rotateTetragrid)
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       solid.processElementNodeByFunction(elementNode, manipulateElementNode)
-
-def rotatePoints(elementNode, points, prefix):
-       'Rotate the points.'
-       derivation = RotateDerivation(elementNode, prefix)
-       if derivation.rotateTetragrid == None:
-               print('Warning, rotateTetragrid was None in rotate so nothing will be done for:')
-               print(elementNode)
-               return
-       matrix.transformVector3sByMatrix(derivation.rotateTetragrid, points)
-
-
-class RotateDerivation(object):
-       "Class to hold rotate variables."
-       def __init__(self, elementNode, prefix):
-               'Set defaults.'
-               self.rotateTetragrid = matrix.getRotateTetragrid(elementNode, prefix)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_matrix/transform.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_matrix/transform.py
deleted file mode 100644 (file)
index 0c471f6..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-"""
-Boolean geometry transform.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalExecutionOrder = 320
-
-
-def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix):
-       'Get equated geometryOutput.'
-       transformPoints(elementNode, matrix.getVertexes(geometryOutput), prefix)
-       return geometryOutput
-
-def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
-       'Get equated paths.'
-       transformPoints(elementNode, loop, prefix)
-       return [loop]
-
-def getNewDerivation(elementNode, prefix, sideLength):
-       'Get new derivation.'
-       return TransformDerivation(elementNode, prefix)
-
-def manipulateElementNode(elementNode, target):
-       'Manipulate the xml element.'
-       derivation = TransformDerivation(elementNode, '')
-       if derivation.transformTetragrid == None:
-               print('Warning, transformTetragrid was None in transform so nothing will be done for:')
-               print(elementNode)
-               return
-       matrix.setAttributesToMultipliedTetragrid(target, derivation.transformTetragrid)
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       solid.processElementNodeByFunction(elementNode, manipulateElementNode)
-
-def transformPoints(elementNode, points, prefix):
-       'Transform the points.'
-       derivation = TransformDerivation(elementNode, prefix)
-       if derivation.transformTetragrid == None:
-               print('Warning, transformTetragrid was None in transform so nothing will be done for:')
-               print(elementNode)
-               return
-       matrix.transformVector3sByMatrix(derivation.transformTetragrid, points)
-
-
-class TransformDerivation(object):
-       "Class to hold transform variables."
-       def __init__(self, elementNode, prefix):
-               'Set defaults.'
-               self.transformTetragrid = matrix.getTransformTetragrid(elementNode, prefix)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_matrix/translate.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_matrix/translate.py
deleted file mode 100644 (file)
index 115ccea..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-"""
-Boolean geometry translation.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalExecutionOrder = 380
-
-
-def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix):
-       "Get equated geometryOutput."
-       translatePoints(elementNode, matrix.getVertexes(geometryOutput), prefix)
-       return geometryOutput
-
-def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
-       "Get equated paths."
-       translatePoints(elementNode, loop, prefix)
-       return [loop]
-
-def getNewDerivation(elementNode, prefix, sideLength):
-       'Get new derivation.'
-       return TranslateDerivation(elementNode)
-
-def manipulateElementNode(elementNode, target):
-       "Manipulate the xml element."
-       derivation = TranslateDerivation(elementNode)
-       if derivation.translateTetragrid == None:
-               print('Warning, translateTetragrid was None in translate so nothing will be done for:')
-               print(elementNode)
-               return
-       matrix.setAttributesToMultipliedTetragrid(target, derivation.translateTetragrid)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       solid.processElementNodeByFunction(elementNode, manipulateElementNode)
-
-def translateNegativesPositives(negatives, positives, translation):
-       'Translate the negatives and postives.'
-       euclidean.translateVector3Path(matrix.getVertexes(negatives), translation)
-       euclidean.translateVector3Path(matrix.getVertexes(positives), translation)
-
-def translatePoints(elementNode, points, prefix):
-       "Translate the points."
-       translateVector3 = matrix.getCumulativeVector3Remove(Vector3(), elementNode, prefix)
-       if abs(translateVector3) > 0.0:
-               euclidean.translateVector3Path(points, translateVector3)
-
-
-class TranslateDerivation(object):
-       "Class to hold translate variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.translateTetragrid = matrix.getTranslateTetragrid(elementNode, '')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/_array.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/_array.py
deleted file mode 100644 (file)
index 7bd4816..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-"""
-Boolean geometry array.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities import euclidean
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addPathToGroup(derivation, groupDictionaryCopy, path, targetMatrix, totalIndex):
-       'Add path to the array group.'
-       for pointIndex, point in enumerate(path):
-               arrayElement = derivation.target.getCopy(derivation.elementNode.getIDSuffix(totalIndex), derivation.elementNode)
-               arrayDictionary = arrayElement.attributes
-               arrayDictionary['visible'] = str(derivation.visible).lower()
-               arrayDictionary.update(groupDictionaryCopy)
-               euclidean.removeTrueFromDictionary(arrayDictionary, 'visible')
-               vertexMatrix = matrix.Matrix(matrix.getTranslateTetragridByTranslation(point))
-               zAngle = totalIndex * 50.0
-               rotationMatrix = getRotationMatrix(arrayDictionary, derivation, path, point, pointIndex)
-               arrayElementMatrix = vertexMatrix.getSelfTimesOther(rotationMatrix.getSelfTimesOther(targetMatrix.tetragrid).tetragrid)
-               arrayDictionary.update(arrayElementMatrix.getAttributes('matrix.'))
-               arrayDictionary['_arrayIndex'] = totalIndex
-               arrayDictionary['_arrayPoint'] = point
-               totalIndex += 1
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return ArrayDerivation(elementNode)
-
-def getRotationMatrix(arrayDictionary, derivation, path, point, pointIndex):
-       'Get rotationMatrix.'
-       if len(path) < 2 or not derivation.track:
-               return matrix.Matrix()
-       point = point.dropAxis()
-       begin = path[(pointIndex + len(path) - 1) % len(path)].dropAxis()
-       end = path[(pointIndex + 1) % len(path)].dropAxis()
-       pointMinusBegin = point - begin
-       pointMinusBeginLength = abs(pointMinusBegin)
-       endMinusPoint = end - point
-       endMinusPointLength = abs(endMinusPoint)
-       if not derivation.closed:
-               if pointIndex == 0 and endMinusPointLength > 0.0:
-                       return getRotationMatrixByPolar(arrayDictionary, endMinusPoint, endMinusPointLength)
-               elif pointIndex == len(path) - 1 and pointMinusBeginLength > 0.0:
-                       return getRotationMatrixByPolar(arrayDictionary, pointMinusBegin, pointMinusBeginLength)
-       if pointMinusBeginLength <= 0.0:
-               print('Warning, point equals previous point in getRotationMatrix in array for:')
-               print(path)
-               print(pointIndex)
-               print(derivation.elementNode)
-               return matrix.Matrix()
-       pointMinusBegin /= pointMinusBeginLength
-       if endMinusPointLength <= 0.0:
-               print('Warning, point equals next point in getRotationMatrix in array for:')
-               print(path)
-               print(pointIndex)
-               print(derivation.elementNode)
-               return matrix.Matrix()
-       endMinusPoint /= endMinusPointLength
-       averagePolar = pointMinusBegin + endMinusPoint
-       averagePolarLength = abs(averagePolar)
-       if averagePolarLength <= 0.0:
-               print('Warning, averagePolarLength is zero in getRotationMatrix in array for:')
-               print(path)
-               print(pointIndex)
-               print(derivation.elementNode)
-               return matrix.Matrix()
-       return getRotationMatrixByPolar(arrayDictionary, averagePolar, averagePolarLength)
-
-def getRotationMatrixByPolar(arrayDictionary, polar, polarLength):
-       'Get rotationMatrix by polar and polarLength.'
-       polar /= polarLength
-       arrayDictionary['_arrayRotation'] = math.degrees(math.atan2(polar.imag, polar.real))
-       return matrix.Matrix(matrix.getDiagonalSwitchedTetragridByPolar([0, 1], polar))
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       processElementNodeByDerivation(None, elementNode)
-
-def processElementNodeByDerivation(derivation, elementNode):
-       'Process the xml element by derivation.'
-       if derivation == None:
-               derivation = ArrayDerivation(elementNode)
-       if derivation.target == None:
-               print('Warning, array could not get target for:')
-               print(elementNode)
-               return
-       if len(derivation.paths) < 1:
-               print('Warning, array could not get paths for:')
-               print(elementNode)
-               return
-       groupDictionaryCopy = elementNode.attributes.copy()
-       euclidean.removeElementsFromDictionary(groupDictionaryCopy, ['closed', 'paths', 'target', 'track', 'vertexes'])
-       evaluate.removeIdentifiersFromDictionary(groupDictionaryCopy)
-       targetMatrix = matrix.getBranchMatrixSetElementNode(derivation.target)
-       elementNode.localName = 'group'
-       totalIndex = 0
-       for path in derivation.paths:
-               addPathToGroup(derivation, groupDictionaryCopy, path, targetMatrix, totalIndex)
-       elementNode.getXMLProcessor().processElementNode(elementNode)
-
-
-class ArrayDerivation(object):
-       "Class to hold array variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.closed = evaluate.getEvaluatedBoolean(True, elementNode, 'closed')
-               self.elementNode = elementNode
-               self.paths = evaluate.getTransformedPathsByKey([], elementNode, 'paths')
-               vertexTargets = evaluate.getElementNodesByKey(elementNode, 'vertexes')
-               for vertexTarget in vertexTargets:
-                       self.paths.append(vertexTarget.getVertexes())
-               self.target = evaluate.getElementNodeByKey(elementNode, 'target')
-               self.track = evaluate.getEvaluatedBoolean(True, elementNode, 'track')
-               self.visible = evaluate.getEvaluatedBoolean(True, elementNode, 'visible')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/_carve.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/_carve.py
deleted file mode 100644 (file)
index c6715cc..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-"""
-Boolean geometry carve.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_tools import path
-from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting
-from fabmetheus_utilities.geometry.geometry_utilities import boolean_geometry
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import xml_simple_reader
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getLinkedElementNode(idSuffix, parentNode, target):
-       'Get elementNode with identifiers and parentNode.'
-       linkedElementNode = xml_simple_reader.ElementNode()
-       euclidean.overwriteDictionary(target.attributes, ['id', 'name', 'quantity'], linkedElementNode.attributes)
-       linkedElementNode.addSuffixToID(idSuffix)
-       tagKeys = target.getTagKeys()
-       tagKeys.append('carve')
-       tagKeys.sort()
-       tags = ', '.join(tagKeys)
-       linkedElementNode.attributes['tags'] = tags
-       linkedElementNode.setParentAddToChildNodes(parentNode)
-       linkedElementNode.addToIdentifierDictionaries()
-       return linkedElementNode
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return CarveDerivation(elementNode)
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       processElementNodeByDerivation(None, elementNode)
-
-def processElementNodeByDerivation(derivation, elementNode):
-       'Process the xml element by derivation.'
-       if derivation == None:
-               derivation = CarveDerivation(elementNode)
-       targetElementNode = derivation.targetElementNode
-       if targetElementNode == None:
-               print('Warning, carve could not get target for:')
-               print(elementNode)
-               return
-       xmlObject = targetElementNode.xmlObject
-       if xmlObject == None:
-               print('Warning, processElementNodeByDerivation in carve could not get xmlObject for:')
-               print(targetElementNode)
-               print(derivation.elementNode)
-               return
-       matrix.getBranchMatrixSetElementNode(targetElementNode)
-       transformedVertexes = xmlObject.getTransformedVertexes()
-       if len(transformedVertexes) < 1:
-               print('Warning, transformedVertexes is zero in processElementNodeByDerivation in carve for:')
-               print(xmlObject)
-               print(targetElementNode)
-               print(derivation.elementNode)
-               return
-       elementNode.localName = 'group'
-       elementNode.getXMLProcessor().processElementNode(elementNode)
-       minimumZ = boolean_geometry.getMinimumZ(xmlObject)
-       maximumZ = euclidean.getTopPath(transformedVertexes)
-       zoneArrangement = triangle_mesh.ZoneArrangement(derivation.layerHeight, transformedVertexes)
-       oldVisibleString = targetElementNode.attributes['visible']
-       targetElementNode.attributes['visible'] = True
-       z = minimumZ + 0.5 * derivation.layerHeight
-       loopLayers = boolean_geometry.getLoopLayers([xmlObject], derivation.importRadius, derivation.layerHeight, maximumZ, False, z, zoneArrangement)
-       targetElementNode.attributes['visible'] = oldVisibleString
-       for loopLayerIndex, loopLayer in enumerate(loopLayers):
-               if len(loopLayer.loops) > 0:
-                       pathElement = getLinkedElementNode('_carve_%s' % loopLayerIndex, elementNode, targetElementNode)
-                       vector3Loops = euclidean.getVector3Paths(loopLayer.loops, loopLayer.z)
-                       path.convertElementNode(pathElement, vector3Loops)
-
-
-class CarveDerivation(object):
-       "Class to hold carve variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.elementNode = elementNode
-               self.importRadius = setting.getImportRadius(elementNode)
-               self.layerHeight = setting.getLayerHeight(elementNode)
-               self.targetElementNode = evaluate.getElementNodeByKey(elementNode, 'target')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/_copy.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/_copy.py
deleted file mode 100644 (file)
index 7c93bdf..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-"""
-Boolean geometry copy.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities import euclidean
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return CopyDerivation(elementNode)
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       processElementNodeByDerivation(None, elementNode)
-
-def processElementNodeByDerivation(derivation, elementNode):
-       'Process the xml element by derivation.'
-       if derivation == None:
-               derivation = CopyDerivation(elementNode)
-       if derivation.target == None:
-               print('Warning, copy could not get target for:')
-               print(elementNode)
-               return
-       del elementNode.attributes['target']
-       copyMatrix = matrix.getBranchMatrixSetElementNode(elementNode)
-       targetMatrix = matrix.getBranchMatrixSetElementNode(derivation.target)
-       targetDictionaryCopy = evaluate.removeIdentifiersFromDictionary(derivation.target.attributes.copy())
-       targetDictionaryCopy.update(elementNode.attributes)
-       elementNode.attributes = targetDictionaryCopy
-       euclidean.removeTrueFromDictionary(elementNode.attributes, 'visible')
-       elementNode.localName = derivation.target.localName
-       derivation.target.copyXMLChildNodes(elementNode.getIDSuffix(), elementNode)
-       elementNode.getXMLProcessor().processElementNode(elementNode)
-       if copyMatrix != None and targetMatrix != None:
-               elementNode.xmlObject.matrix4X4 = copyMatrix.getSelfTimesOther(targetMatrix.tetragrid)
-       if elementNode.xmlObject == None:
-               return
-       if len(elementNode.xmlObject.getPaths()) > 0:
-               lineation.processElementNode(elementNode)
-               return
-       geometryOutput = elementNode.xmlObject.getGeometryOutput()
-       if geometryOutput == None:
-               return
-       solidMatchingPlugins = solid.getSolidMatchingPlugins(elementNode)
-       if len(solidMatchingPlugins) == 0:
-               return
-       geometryOutput = solid.getGeometryOutputByManipulation(elementNode, geometryOutput)
-       elementNode.xmlObject.transformGeometryOutput(geometryOutput)
-       lineation.removeChildNodesFromElementObject(elementNode)
-       elementNode.getXMLProcessor().convertElementNode(elementNode, geometryOutput)
-
-
-class CopyDerivation(object):
-       "Class to hold copy variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.target = evaluate.getElementNodeByKey(elementNode, 'target')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/disjoin.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/disjoin.py
deleted file mode 100644 (file)
index 4c6fcc3..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-"""
-Boolean geometry disjoin.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_tools import path
-from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting
-from fabmetheus_utilities.geometry.geometry_utilities import boolean_geometry
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities.geometry.solids import difference
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import xml_simple_reader
-from fabmetheus_utilities.vector3 import Vector3
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getLinkedElementNode(idSuffix, parentNode, target):
-       'Get elementNode with identifiers and parentNode.'
-       linkedElementNode = xml_simple_reader.ElementNode()
-       euclidean.overwriteDictionary(target.attributes, ['id', 'name', 'quantity'], linkedElementNode.attributes)
-       linkedElementNode.addSuffixToID(idSuffix)
-       tagKeys = target.getTagKeys()
-       tagKeys.append('disjoin')
-       tagKeys.sort()
-       tags = ', '.join(tagKeys)
-       linkedElementNode.attributes['tags'] = tags
-       linkedElementNode.setParentAddToChildNodes(parentNode)
-       linkedElementNode.addToIdentifierDictionaries()
-       return linkedElementNode
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return DisjoinDerivation(elementNode)
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       processElementNodeByDerivation(None, elementNode)
-
-def processElementNodeByDerivation(derivation, elementNode):
-       'Process the xml element by derivation.'
-       if derivation == None:
-               derivation = DisjoinDerivation(elementNode)
-       targetElementNode = derivation.targetElementNode
-       if targetElementNode == None:
-               print('Warning, disjoin could not get target for:')
-               print(elementNode)
-               return
-       xmlObject = targetElementNode.xmlObject
-       if xmlObject == None:
-               print('Warning, processElementNodeByDerivation in disjoin could not get xmlObject for:')
-               print(targetElementNode)
-               print(derivation.elementNode)
-               return
-       matrix.getBranchMatrixSetElementNode(targetElementNode)
-       transformedVertexes = xmlObject.getTransformedVertexes()
-       if len(transformedVertexes) < 1:
-               print('Warning, transformedVertexes is zero in processElementNodeByDerivation in disjoin for:')
-               print(xmlObject)
-               print(targetElementNode)
-               print(derivation.elementNode)
-               return
-       elementNode.localName = 'group'
-       elementNode.getXMLProcessor().processElementNode(elementNode)
-       targetChainMatrix = matrix.Matrix(xmlObject.getMatrixChainTetragrid())
-       minimumZ = boolean_geometry.getMinimumZ(xmlObject)
-       z = minimumZ + 0.5 * derivation.sheetThickness
-       zoneArrangement = triangle_mesh.ZoneArrangement(derivation.layerHeight, transformedVertexes)
-       oldVisibleString = targetElementNode.attributes['visible']
-       targetElementNode.attributes['visible'] = True
-       loops = boolean_geometry.getEmptyZLoops([xmlObject], derivation.importRadius, False, z, zoneArrangement)
-       targetElementNode.attributes['visible'] = oldVisibleString
-       vector3Loops = euclidean.getVector3Paths(loops, z)
-       pathElement = getLinkedElementNode('_sheet', elementNode, targetElementNode)
-       path.convertElementNode(pathElement, vector3Loops)
-       targetOutput = xmlObject.getGeometryOutput()
-       differenceElement = getLinkedElementNode('_solid', elementNode, targetElementNode)
-       targetElementCopy = targetElementNode.getCopy('_positive', differenceElement)
-       targetElementCopy.attributes['visible'] = True
-       targetElementCopy.attributes.update(targetChainMatrix.getAttributes('matrix.'))
-       complexMaximum = euclidean.getMaximumByVector3Path(transformedVertexes).dropAxis()
-       complexMinimum = euclidean.getMinimumByVector3Path(transformedVertexes).dropAxis()
-       centerComplex = 0.5 * (complexMaximum + complexMinimum)
-       centerVector3 = Vector3(centerComplex.real, centerComplex.imag, minimumZ)
-       slightlyMoreThanHalfExtent = 0.501 * (complexMaximum - complexMinimum)
-       inradius = Vector3(slightlyMoreThanHalfExtent.real, slightlyMoreThanHalfExtent.imag, derivation.sheetThickness)
-       cubeElement = xml_simple_reader.ElementNode()
-       cubeElement.attributes['inradius'] = str(inradius)
-       if not centerVector3.getIsDefault():
-               cubeElement.attributes['translate.'] = str(centerVector3)
-       cubeElement.localName = 'cube'
-       cubeElement.setParentAddToChildNodes(differenceElement)
-       difference.processElementNode(differenceElement)
-
-
-class DisjoinDerivation(object):
-       "Class to hold disjoin variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.elementNode = elementNode
-               self.importRadius = setting.getImportRadius(elementNode)
-               self.layerHeight = setting.getLayerHeight(elementNode)
-               self.sheetThickness = setting.getSheetThickness(elementNode)
-               self.targetElementNode = evaluate.getElementNodeByKey(elementNode, 'target')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/import.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/import.py
deleted file mode 100644 (file)
index 3de73c4..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-"""
-Boolean geometry group of solids.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.solids import group
-from fabmetheus_utilities import xml_simple_reader
-from fabmetheus_utilities import xml_simple_writer
-from fabmetheus_utilities import archive
-import os
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def appendAttributes(fromElementNode, toElementNode):
-       'Append the attributes from the child nodes of fromElementNode to the attributes of toElementNode.'
-       for childNode in fromElementNode.childNodes:
-               toElementNode.attributes.update(evaluate.removeIdentifiersFromDictionary(childNode.attributes.copy()))
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return ImportDerivation(elementNode)
-
-def getXMLFromCarvingFileName(fileName):
-       'Get xml text from xml text.'
-       carving = fabmetheus_interpret.getCarving(fileName)
-       if carving == None:
-               return ''
-       output = xml_simple_writer.getBeginGeometryXMLOutput()
-       carving.addXML(0, output)
-       return xml_simple_writer.getEndGeometryXMLString(output)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       processElementNodeByDerivation(None, elementNode)
-
-def processElementNodeByDerivation(derivation, elementNode):
-       'Process the xml element by derivation.'
-       if derivation == None:
-               derivation = ImportDerivation(elementNode)
-       if derivation.fileName == None:
-               return
-       parserFileName = elementNode.getOwnerDocument().fileName
-       absoluteFileName = archive.getAbsoluteFolderPath(parserFileName, derivation.fileName)
-       if 'models/' not in absoluteFileName:
-               print('Warning, models/ was not in the absolute file path, so for security nothing will be done for:')
-               print(elementNode)
-               print('For which the absolute file path is:')
-               print(absoluteFileName)
-               print('The import tool can only read a file which has models/ in the file path.')
-               print('To import the file, move the file into a folder called model/ or a subfolder which is inside the model folder tree.')
-               return
-       xmlText = ''
-       if derivation.fileName.endswith('.xml'):
-               xmlText = archive.getFileText(absoluteFileName)
-       else:
-               xmlText = getXMLFromCarvingFileName(absoluteFileName)
-       print('The import tool is opening the file:')
-       print(absoluteFileName)
-       if xmlText == '':
-               print('The file %s could not be found by processElementNode in import.' % derivation.fileName)
-               return
-       if derivation.importName == None:
-               elementNode.attributes['_importName'] = archive.getUntilDot(derivation.fileName)
-               if derivation.basename:
-                       elementNode.attributes['_importName'] = os.path.basename(elementNode.attributes['_importName'])
-       xml_simple_reader.createAppendByText(elementNode, xmlText)
-       if derivation.appendDocumentElement:
-               appendAttributes(elementNode, elementNode.getDocumentElement())
-       if derivation.appendElement:
-               appendAttributes(elementNode, elementNode)
-       elementNode.localName = 'group'
-       evaluate.processArchivable(group.Group, elementNode)
-
-
-class ImportDerivation(object):
-       "Class to hold import variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.appendDocumentElement = evaluate.getEvaluatedBoolean(False, elementNode, 'appendDocumentElement')
-               self.appendElement = evaluate.getEvaluatedBoolean(False, elementNode, 'appendElement')
-               self.basename = evaluate.getEvaluatedBoolean(True, elementNode, 'basename')
-               self.elementNode = elementNode
-               self.fileName = evaluate.getEvaluatedString('', elementNode, 'file')
-               self.importName = evaluate.getEvaluatedString(None, elementNode, '_importName')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/write.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_meta/write.py
deleted file mode 100644 (file)
index 9d2d128..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-"""
-Boolean geometry write.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities import archive
-import os
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return WriteDerivation(elementNode)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       processElementNodeByDerivation(None, elementNode)
-
-def processElementNodeByDerivation(derivation, elementNode):
-       'Process the xml element by derivation.'
-       if derivation == None:
-               derivation = WriteDerivation(elementNode)
-       if len(derivation.targets) < 1:
-               print('Warning, processElementNode in write could not get targets for:')
-               print(elementNode)
-               return
-       fileNames = []
-       for target in derivation.targets:
-               writeElementNode(derivation, fileNames, target)
-
-def writeElementNode(derivation, fileNames, target):
-       "Write a quantity of the target."
-       xmlObject = target.xmlObject
-       if xmlObject == None:
-               print('Warning, writeTarget in write could not get xmlObject for:')
-               print(target)
-               print(derivation.elementNode)
-               return
-       parserDirectory = os.path.dirname(derivation.elementNode.getOwnerDocument().fileName)
-       absoluteFolderDirectory = os.path.abspath(os.path.join(parserDirectory, derivation.folderName))
-       if '/models' not in absoluteFolderDirectory:
-               print('Warning, models/ was not in the absolute file path, so for security nothing will be done for:')
-               print(derivation.elementNode)
-               print('For which the absolute folder path is:')
-               print(absoluteFolderDirectory)
-               print('The write tool can only write a file which has models/ in the file path.')
-               print('To write the file, move the file into a folder called model/ or a subfolder which is inside the model folder tree.')
-               return
-       quantity = evaluate.getEvaluatedInt(1, target, 'quantity')
-       for itemIndex in xrange(quantity):
-               writeXMLObject(absoluteFolderDirectory, derivation, fileNames, target, xmlObject)
-
-def writeXMLObject(absoluteFolderDirectory, derivation, fileNames, target, xmlObject):
-       "Write one instance of the xmlObject."
-       extension = evaluate.getEvaluatedString(xmlObject.getFabricationExtension(), derivation.elementNode, 'extension')
-       fileNameRoot = derivation.fileName
-       if fileNameRoot == '':
-               fileNameRoot = evaluate.getEvaluatedString('', target, 'name')
-               fileNameRoot = evaluate.getEvaluatedString(fileNameRoot, target, 'id')
-               fileNameRoot += derivation.suffix
-       fileName = '%s.%s' % (fileNameRoot, extension)
-       suffixIndex = 2
-       while fileName in fileNames:
-               fileName = '%s_%s.%s' % (fileNameRoot, suffixIndex, extension)
-               suffixIndex += 1
-       absoluteFileName = os.path.join(absoluteFolderDirectory, fileName)
-       fileNames.append(fileName)
-       archive.makeDirectory(absoluteFolderDirectory)
-       if not derivation.writeMatrix:
-               xmlObject.matrix4X4 = matrix.Matrix()
-       print('The write tool generated the file:')
-       print(absoluteFileName)
-       archive.writeFileText(absoluteFileName, xmlObject.getFabricationText(derivation.addLayerTemplate))
-
-
-class WriteDerivation(object):
-       "Class to hold write variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.addLayerTemplate = evaluate.getEvaluatedBoolean(False, elementNode, 'addLayerTemplate')
-               self.elementNode = elementNode
-               self.fileName = evaluate.getEvaluatedString('', elementNode, 'file')
-               self.folderName = evaluate.getEvaluatedString('', elementNode, 'folder')
-               self.suffix = evaluate.getEvaluatedString('', elementNode, 'suffix')
-               self.targets = evaluate.getElementNodesByKey(elementNode, 'target')
-               self.writeMatrix = evaluate.getEvaluatedBoolean(True, elementNode, 'writeMatrix')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/bevel.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/bevel.py
deleted file mode 100644 (file)
index a7ebba3..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-"""
-Add material to support overhang or remove material at the overhang angle.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalExecutionOrder = 20
-
-
-def getBevelPath( begin, center, close, end, radius ):
-       "Get bevel path."
-       beginComplex = begin.dropAxis()
-       centerComplex = center.dropAxis()
-       endComplex = end.dropAxis()
-       beginComplexSegmentLength = abs( centerComplex - beginComplex )
-       endComplexSegmentLength = abs( centerComplex - endComplex )
-       minimumRadius = lineation.getMinimumRadius( beginComplexSegmentLength, endComplexSegmentLength, radius )
-       if minimumRadius <= close:
-               return [ center ]
-       beginBevel = center + minimumRadius / beginComplexSegmentLength * ( begin - center )
-       endBevel = center + minimumRadius / endComplexSegmentLength * ( end - center )
-       if radius > 0.0:
-               return [ beginBevel, endBevel ]
-       midpointComplex = 0.5 * ( beginBevel.dropAxis() + endBevel.dropAxis() )
-       spikeComplex = centerComplex + centerComplex - midpointComplex
-       return [ beginBevel, Vector3( spikeComplex.real, spikeComplex.imag, center.z ), endBevel ]
-
-def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
-       "Get bevel loop."
-       if len(loop) < 3:
-               return [loop]
-       derivation = BevelDerivation(elementNode, prefix, sideLength)
-       if derivation.radius == 0.0:
-               return loop
-       bevelLoop = []
-       for pointIndex in xrange(len(loop)):
-               begin = loop[(pointIndex + len(loop) - 1) % len(loop)]
-               center = loop[pointIndex]
-               end = loop[(pointIndex + 1) % len(loop)]
-               bevelLoop += getBevelPath(begin, center, close, end, derivation.radius)
-       return [euclidean.getLoopWithoutCloseSequentialPoints(close, bevelLoop)]
-
-def getNewDerivation(elementNode, prefix, sideLength):
-       'Get new derivation.'
-       return BevelDerivation(elementNode, prefix, sideLength)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       lineation.processElementNodeByFunction(elementNode, getManipulatedPaths)
-
-
-class BevelDerivation(object):
-       "Class to hold bevel variables."
-       def __init__(self, elementNode, prefix, sideLength):
-               'Set defaults.'
-               self.radius = lineation.getFloatByPrefixSide(0.0, elementNode, prefix + 'radius', sideLength)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/convex.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/convex.py
deleted file mode 100644 (file)
index 841a798..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-"""
-Create outline.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities import euclidean
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalExecutionOrder = 80
-
-
-def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
-       "Get path with overhangs removed or filled in."
-       if len(loop) < 4:
-               return [loop]
-       loopComplex = euclidean.getComplexPath(loop)
-       return euclidean.getVector3Paths([euclidean.getLoopConvex(loopComplex)], loop[0].z)
-
-def getNewDerivation(elementNode, prefix, sideLength):
-       'Get new derivation.'
-       return evaluate.EmptyObject()
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       lineation.processElementNodeByFunction(elementNode, getManipulatedPaths)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/outline.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/outline.py
deleted file mode 100644 (file)
index 7ee4b3b..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-"""
-Create outline.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import intercircle
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalExecutionOrder = 80
-
-
-def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
-       "Get path with outline."
-       if len(loop) < 2:
-               return [loop]
-       derivation = OutlineDerivation(elementNode, prefix, sideLength)
-       loopComplex = euclidean.getComplexPath(loop)
-       if derivation.isClosed:
-               loopComplexes = intercircle.getAroundsFromLoop(loopComplex, derivation.radius)
-       else:
-               loopComplexes = intercircle.getAroundsFromPath(loopComplex, derivation.radius)
-       return euclidean.getVector3Paths(loopComplexes, loop[0].z)
-
-def getNewDerivation(elementNode, prefix, sideLength):
-       'Get new derivation.'
-       return OutlineDerivation(elementNode, prefix, sideLength)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       lineation.processElementNodeByFunction(elementNode, getManipulatedPaths)
-
-
-class OutlineDerivation(object):
-       "Class to hold outline variables."
-       def __init__(self, elementNode, prefix, sideLength):
-               'Set defaults.'
-               self.isClosed = evaluate.getEvaluatedBoolean(False, elementNode, prefix + 'closed')
-               self.radius = evaluate.getEvaluatedFloat(setting.getEdgeWidth(elementNode), elementNode, prefix + 'radius')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/overhang.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/overhang.py
deleted file mode 100644 (file)
index d8c357f..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-"""
-Add material to support overhang or remove material at the overhang angle.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalExecutionOrder = 100
-
-
-def addUnsupportedPointIndexes( alongAway ):
-       "Add the indexes of the unsupported points."
-       addedUnsupportedPointIndexes = []
-       for pointIndex in xrange( len( alongAway.loop ) ):
-               point = alongAway.loop[pointIndex]
-               if pointIndex not in alongAway.unsupportedPointIndexes:
-                       if not alongAway.getIsClockwisePointSupported(point):
-                               alongAway.unsupportedPointIndexes.append( pointIndex )
-                               addedUnsupportedPointIndexes.append( pointIndex )
-       for pointIndex in addedUnsupportedPointIndexes:
-               point = alongAway.loop[pointIndex]
-               point.y += alongAway.maximumYPlus
-
-def alterClockwiseSupportedPath( alongAway, elementNode ):
-       "Get clockwise path with overhangs carved out."
-       alongAway.bottomPoints = []
-       alongAway.overhangSpan = setting.getOverhangSpan(elementNode)
-       maximumY = - 987654321.0
-       minimumYPointIndex = 0
-       for pointIndex in xrange( len( alongAway.loop ) ):
-               point = alongAway.loop[pointIndex]
-               if point.y < alongAway.loop[ minimumYPointIndex ].y:
-                       minimumYPointIndex = pointIndex
-               maximumY = max( maximumY, point.y )
-       alongAway.maximumYPlus = 2.0 * ( maximumY - alongAway.loop[ minimumYPointIndex ].y )
-       alongAway.loop = euclidean.getAroundLoop( minimumYPointIndex, minimumYPointIndex, alongAway.loop )
-       overhangClockwise = OverhangClockwise( alongAway )
-       alongAway.unsupportedPointIndexes = []
-       oldUnsupportedPointIndexesLength = - 987654321.0
-       while len( alongAway.unsupportedPointIndexes ) > oldUnsupportedPointIndexesLength:
-               oldUnsupportedPointIndexesLength = len( alongAway.unsupportedPointIndexes )
-               addUnsupportedPointIndexes( alongAway )
-       for pointIndex in alongAway.unsupportedPointIndexes:
-               point = alongAway.loop[pointIndex]
-               point.y -= alongAway.maximumYPlus
-       alongAway.unsupportedPointIndexes.sort()
-       alongAway.unsupportedPointIndexLists = []
-       oldUnsupportedPointIndex = - 987654321.0
-       unsupportedPointIndexList = None
-       for unsupportedPointIndex in alongAway.unsupportedPointIndexes:
-               if unsupportedPointIndex > oldUnsupportedPointIndex + 1:
-                       unsupportedPointIndexList = []
-                       alongAway.unsupportedPointIndexLists.append( unsupportedPointIndexList )
-               oldUnsupportedPointIndex = unsupportedPointIndex
-               unsupportedPointIndexList.append( unsupportedPointIndex )
-       alongAway.unsupportedPointIndexLists.reverse()
-       for unsupportedPointIndexList in alongAway.unsupportedPointIndexLists:
-               overhangClockwise.alterLoop( unsupportedPointIndexList )
-
-def alterWiddershinsSupportedPath( alongAway, close ):
-       "Get widdershins path with overhangs filled in."
-       alongAway.bottomPoints = []
-       alongAway.minimumY = getMinimumYByPath( alongAway.loop )
-       for point in alongAway.loop:
-               if point.y - alongAway.minimumY < close:
-                       alongAway.addToBottomPoints(point)
-       ascendingYPoints = alongAway.loop[:]
-       ascendingYPoints.sort( compareYAscending )
-       overhangWiddershinsLeft = OverhangWiddershinsLeft( alongAway )
-       overhangWiddershinsRight = OverhangWiddershinsRight( alongAway )
-       for point in ascendingYPoints:
-               alterWiddershinsSupportedPathByPoint( alongAway, overhangWiddershinsLeft, overhangWiddershinsRight, point )
-
-def alterWiddershinsSupportedPathByPoint( alongAway, overhangWiddershinsLeft, overhangWiddershinsRight, point ):
-       "Get widdershins path with overhangs filled in for point."
-       if alongAway.getIsWiddershinsPointSupported(point):
-               return
-       overhangWiddershins = overhangWiddershinsLeft
-       if overhangWiddershinsRight.getDistance() < overhangWiddershinsLeft.getDistance():
-               overhangWiddershins = overhangWiddershinsRight
-       overhangWiddershins.alterLoop()
-
-def compareYAscending( point, pointOther ):
-       "Get comparison in order to sort points in ascending y."
-       if point.y < pointOther.y:
-               return - 1
-       return int( point.y > pointOther.y )
-
-def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
-       "Get path with overhangs removed or filled in."
-       if len(loop) < 3:
-               print('Warning, loop has less than three sides in getManipulatedPaths in overhang for:')
-               print(elementNode)
-               return [loop]
-       derivation = OverhangDerivation(elementNode, prefix)
-       overhangPlaneAngle = euclidean.getWiddershinsUnitPolar(0.5 * math.pi - derivation.overhangRadians)
-       if derivation.overhangInclinationRadians != 0.0:
-               overhangInclinationCosine = abs(math.cos(derivation.overhangInclinationRadians))
-               if overhangInclinationCosine == 0.0:
-                       return [loop]
-               imaginaryTimesCosine = overhangPlaneAngle.imag * overhangInclinationCosine
-               overhangPlaneAngle = euclidean.getNormalized(complex(overhangPlaneAngle.real, imaginaryTimesCosine))
-       alongAway = AlongAway(loop, overhangPlaneAngle)
-       if euclidean.getIsWiddershinsByVector3(loop):
-               alterWiddershinsSupportedPath(alongAway, close)
-       else:
-               alterClockwiseSupportedPath(alongAway, elementNode)
-       return [euclidean.getLoopWithoutCloseSequentialPoints(close,  alongAway.loop)]
-
-def getMinimumYByPath(path):
-       "Get path with overhangs removed or filled in."
-       minimumYByPath = path[0].y
-       for point in path:
-               minimumYByPath = min( minimumYByPath, point.y )
-       return minimumYByPath
-
-def getNewDerivation(elementNode, prefix, sideLength):
-       'Get new derivation.'
-       return OverhangDerivation(elementNode, prefix)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       lineation.processElementNodeByFunction(elementNode, getManipulatedPaths)
-
-
-class AlongAway(object):
-       "Class to derive the path along the point and away from the point."
-       def __init__( self, loop, overhangPlaneAngle ):
-               "Initialize."
-               self.loop = loop
-               self.overhangPlaneAngle = overhangPlaneAngle
-               self.ySupport = - self.overhangPlaneAngle.imag
-
-       def __repr__(self):
-               "Get the string representation of AlongAway."
-               return '%s' % ( self.overhangPlaneAngle )
-
-       def addToBottomPoints(self, point):
-               "Add point to bottom points and set y to minimumY."
-               self.bottomPoints.append(point)
-               point.y = self.minimumY
-
-       def getIsClockwisePointSupported(self, point):
-               "Determine if the point on the clockwise loop is supported."
-               self.point = point
-               self.pointIndex = None
-               self.awayIndexes = []
-               numberOfIntersectionsBelow = 0
-               for pointIndex in xrange( len( self.loop ) ):
-                       begin = self.loop[pointIndex]
-                       end = self.loop[ (pointIndex + 1) % len( self.loop ) ]
-                       if begin != point and end != point:
-                               self.awayIndexes.append( pointIndex )
-                               yIntersection = euclidean.getYIntersectionIfExists( begin.dropAxis(), end.dropAxis(), point.x )
-                               if yIntersection != None:
-                                       numberOfIntersectionsBelow += ( yIntersection < point.y )
-                       if begin == point:
-                               self.pointIndex = pointIndex
-               if numberOfIntersectionsBelow % 2 == 0:
-                       return True
-               if self.pointIndex == None:
-                       return True
-               if self.getIsPointSupportedBySegment( self.pointIndex - 1 + len( self.loop ) ):
-                       return True
-               return self.getIsPointSupportedBySegment( self.pointIndex + 1 )
-
-       def getIsPointSupportedBySegment( self, endIndex ):
-               "Determine if the point on the widdershins loop is supported."
-               endComplex = self.loop[ ( endIndex % len( self.loop ) ) ].dropAxis()
-               endMinusPointComplex = euclidean.getNormalized( endComplex - self.point.dropAxis() )
-               return endMinusPointComplex.imag < self.ySupport
-
-       def getIsWiddershinsPointSupported(self, point):
-               "Determine if the point on the widdershins loop is supported."
-               if point.y <= self.minimumY:
-                       return True
-               self.point = point
-               self.pointIndex = None
-               self.awayIndexes = []
-               numberOfIntersectionsBelow = 0
-               for pointIndex in xrange( len( self.loop ) ):
-                       begin = self.loop[pointIndex]
-                       end = self.loop[ (pointIndex + 1) % len( self.loop ) ]
-                       if begin != point and end != point:
-                               self.awayIndexes.append( pointIndex )
-                               yIntersection = euclidean.getYIntersectionIfExists( begin.dropAxis(), end.dropAxis(), point.x )
-                               if yIntersection != None:
-                                       numberOfIntersectionsBelow += ( yIntersection < point.y )
-                       if begin == point:
-                               self.pointIndex = pointIndex
-               if numberOfIntersectionsBelow % 2 == 1:
-                       return True
-               if self.pointIndex == None:
-                       return True
-               if self.getIsPointSupportedBySegment( self.pointIndex - 1 + len( self.loop ) ):
-                       return True
-               return self.getIsPointSupportedBySegment( self.pointIndex + 1 )
-
-
-class OverhangClockwise(object):
-       "Class to get the intersection up from the point."
-       def __init__( self, alongAway ):
-               "Initialize."
-               self.alongAway = alongAway
-               self.halfRiseOverWidth = 0.5 * alongAway.overhangPlaneAngle.imag / alongAway.overhangPlaneAngle.real
-               self.widthOverRise = alongAway.overhangPlaneAngle.real / alongAway.overhangPlaneAngle.imag
-
-       def __repr__(self):
-               "Get the string representation of OverhangClockwise."
-               return '%s' % ( self.intersectionPlaneAngle )
-
-       def alterLoop( self, unsupportedPointIndexes ):
-               "Alter alongAway loop."
-               unsupportedBeginIndex = unsupportedPointIndexes[0]
-               unsupportedEndIndex = unsupportedPointIndexes[-1]
-               beginIndex = unsupportedBeginIndex - 1
-               endIndex = unsupportedEndIndex + 1
-               begin = self.alongAway.loop[ beginIndex ]
-               end = self.alongAway.loop[ endIndex ]
-               truncatedOverhangSpan = self.alongAway.overhangSpan
-               width = end.x - begin.x
-               heightDifference = abs( end.y - begin.y )
-               remainingWidth = width - self.widthOverRise * heightDifference
-               if remainingWidth <= 0.0:
-                       del self.alongAway.loop[ unsupportedBeginIndex : endIndex ]
-                       return
-               highest = begin
-               supportX = begin.x + remainingWidth
-               if end.y > begin.y:
-                       highest = end
-                       supportX = end.x - remainingWidth
-               tipY = highest.y + self.halfRiseOverWidth * remainingWidth
-               highestBetween = - 987654321.0
-               for unsupportedPointIndex in unsupportedPointIndexes:
-                       highestBetween = max( highestBetween, self.alongAway.loop[ unsupportedPointIndex ].y )
-               if highestBetween > highest.y:
-                       truncatedOverhangSpan = 0.0
-                       if highestBetween < tipY:
-                               below = tipY - highestBetween
-                               truncatedOverhangSpan = min( self.alongAway.overhangSpan, below / self.halfRiseOverWidth )
-               truncatedOverhangSpanRadius = 0.5 * truncatedOverhangSpan
-               if remainingWidth <= truncatedOverhangSpan:
-                       supportPoint = Vector3( supportX, highest.y, highest.z )
-                       self.alongAway.loop[ unsupportedBeginIndex : endIndex ] = [ supportPoint ]
-                       return
-               midSupportX = 0.5 * ( supportX + highest.x )
-               if truncatedOverhangSpan <= 0.0:
-                       supportPoint = Vector3( midSupportX, tipY, highest.z )
-                       self.alongAway.loop[ unsupportedBeginIndex : endIndex ] = [ supportPoint ]
-                       return
-               supportXLeft = midSupportX - truncatedOverhangSpanRadius
-               supportXRight = midSupportX + truncatedOverhangSpanRadius
-               supportY = tipY - self.halfRiseOverWidth * truncatedOverhangSpan
-               supportPoints = [ Vector3( supportXLeft, supportY, highest.z ), Vector3( supportXRight, supportY, highest.z ) ]
-               self.alongAway.loop[ unsupportedBeginIndex : endIndex ] = supportPoints
-
-
-class OverhangDerivation(object):
-       "Class to hold overhang variables."
-       def __init__(self, elementNode, prefix):
-               'Set defaults.'
-               self.overhangRadians = setting.getOverhangRadians(elementNode)
-               self.overhangInclinationRadians = math.radians(evaluate.getEvaluatedFloat(0.0, elementNode,  prefix + 'inclination'))
-
-
-class OverhangWiddershinsLeft(object):
-       "Class to get the intersection from the point down to the left."
-       def __init__( self, alongAway ):
-               "Initialize."
-               self.alongAway = alongAway
-               self.intersectionPlaneAngle = - alongAway.overhangPlaneAngle
-               self.setRatios()
-
-       def __repr__(self):
-               "Get the string representation of OverhangWiddershins."
-               return '%s' % ( self.intersectionPlaneAngle )
-
-       def alterLoop(self):
-               "Alter alongAway loop."
-               insertedPoint = self.alongAway.point.copy()
-               if self.closestXIntersectionIndex != None:
-                       self.alongAway.loop = self.getIntersectLoop()
-                       intersectionRelativeComplex = self.closestXDistance * self.intersectionPlaneAngle
-                       intersectionPoint = insertedPoint + Vector3( intersectionRelativeComplex.real, intersectionRelativeComplex.imag )
-                       self.alongAway.loop.append( intersectionPoint )
-                       return
-               if self.closestBottomPoint == None:
-                       return
-               if self.closestBottomPoint not in self.alongAway.loop:
-                       return
-               insertedPoint.x = self.bottomX
-               closestBottomIndex = self.alongAway.loop.index( self.closestBottomPoint )
-               self.alongAway.addToBottomPoints( insertedPoint )
-               self.alongAway.loop = self.getBottomLoop( closestBottomIndex, insertedPoint )
-               self.alongAway.loop.append( insertedPoint )
-
-       def getBottomLoop( self, closestBottomIndex, insertedPoint ):
-               "Get loop around bottom."
-               endIndex = closestBottomIndex + len( self.alongAway.loop ) + 1
-               return euclidean.getAroundLoop( self.alongAway.pointIndex, endIndex, self.alongAway.loop )
-
-       def getDistance(self):
-               "Get distance between point and closest intersection or bottom point along line."
-               self.pointMinusBottomY = self.alongAway.point.y - self.alongAway.minimumY
-               self.diagonalDistance = self.pointMinusBottomY * self.diagonalRatio
-               if self.alongAway.pointIndex == None:
-                       return self.getDistanceToBottom()
-               rotatedLoop = euclidean.getRotatedComplexes( self.intersectionYMirror,  euclidean.getComplexPath( self.alongAway.loop ) )
-               rotatedPointComplex = rotatedLoop[ self.alongAway.pointIndex ]
-               beginX = rotatedPointComplex.real
-               endX = beginX + self.diagonalDistance + self.diagonalDistance
-               xIntersectionIndexList = []
-               for pointIndex in self.alongAway.awayIndexes:
-                       beginComplex = rotatedLoop[pointIndex]
-                       endComplex = rotatedLoop[ (pointIndex + 1) % len( rotatedLoop ) ]
-                       xIntersection = euclidean.getXIntersectionIfExists( beginComplex, endComplex, rotatedPointComplex.imag )
-                       if xIntersection is not None:
-                               if beginX <= xIntersection < endX:
-                                       xIntersectionIndexList.append( euclidean.XIntersectionIndex( pointIndex, xIntersection ) )
-               self.closestXDistance = 987654321.0
-               self.closestXIntersectionIndex = None
-               for xIntersectionIndex in xIntersectionIndexList:
-                       xDistance = abs( xIntersectionIndex.x - beginX )
-                       if xDistance < self.closestXDistance:
-                               self.closestXIntersectionIndex = xIntersectionIndex
-                               self.closestXDistance = xDistance
-               if self.closestXIntersectionIndex != None:
-                       return self.closestXDistance
-               return self.getDistanceToBottom()
-
-       def getDistanceToBottom(self):
-               "Get distance between point and closest bottom point along line."
-               self.bottomX = self.alongAway.point.x + self.pointMinusBottomY * self.xRatio
-               self.closestBottomPoint = None
-               closestDistanceX = 987654321.0
-               for point in self.alongAway.bottomPoints:
-                       distanceX = abs( point.x - self.bottomX )
-                       if self.getIsOnside(point.x):
-                               if distanceX < closestDistanceX:
-                                       closestDistanceX = distanceX
-                                       self.closestBottomPoint = point
-               return closestDistanceX + self.diagonalDistance
-
-       def getIntersectLoop(self):
-               "Get intersection loop."
-               endIndex = self.closestXIntersectionIndex.index + len( self.alongAway.loop ) + 1
-               return euclidean.getAroundLoop( self.alongAway.pointIndex, endIndex, self.alongAway.loop )
-
-       def getIsOnside( self, x ):
-               "Determine if x is on the side along the direction of the intersection line."
-               return x <= self.alongAway.point.x
-
-       def setRatios(self):
-               "Set ratios."
-               self.diagonalRatio = 1.0 / abs( self.intersectionPlaneAngle.imag )
-               self.intersectionYMirror = complex( self.intersectionPlaneAngle.real, - self.intersectionPlaneAngle.imag )
-               self.xRatio = self.intersectionPlaneAngle.real / abs( self.intersectionPlaneAngle.imag )
-
-
-class OverhangWiddershinsRight( OverhangWiddershinsLeft ):
-       "Class to get the intersection from the point down to the right."
-       def __init__( self, alongAway ):
-               "Initialize."
-               self.alongAway = alongAway
-               self.intersectionPlaneAngle = complex( alongAway.overhangPlaneAngle.real, - alongAway.overhangPlaneAngle.imag )
-               self.setRatios()
-
-       def getBottomLoop( self, closestBottomIndex, insertedPoint ):
-               "Get loop around bottom."
-               endIndex = self.alongAway.pointIndex + len( self.alongAway.loop ) + 1
-               return euclidean.getAroundLoop( closestBottomIndex, endIndex, self.alongAway.loop )
-
-       def getIntersectLoop(self):
-               "Get intersection loop."
-               beginIndex = self.closestXIntersectionIndex.index + len( self.alongAway.loop ) + 1
-               endIndex = self.alongAway.pointIndex + len( self.alongAway.loop ) + 1
-               return euclidean.getAroundLoop( beginIndex, endIndex, self.alongAway.loop )
-
-       def getIsOnside( self, x ):
-               "Determine if x is on the side along the direction of the intersection line."
-               return x >= self.alongAway.point.x
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/round.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/round.py
deleted file mode 100644 (file)
index c1ee8fc..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-"""
-Add material to support overhang or remove material at the overhang angle.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalExecutionOrder = 40
-
-
-def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
-       "Get round loop."
-       if len(loop) < 3:
-               return [loop]
-       derivation = RoundDerivation(elementNode, prefix, sideLength)
-       if derivation.radius == 0.0:
-               return loop
-       roundLoop = []
-       sidesPerRadian = 0.5 / math.pi * evaluate.getSidesMinimumThreeBasedOnPrecision(elementNode, sideLength)
-       for pointIndex in xrange(len(loop)):
-               begin = loop[(pointIndex + len(loop) - 1) % len(loop)]
-               center = loop[pointIndex]
-               end = loop[(pointIndex + 1) % len(loop)]
-               roundLoop += getRoundPath(begin, center, close, end, derivation.radius, sidesPerRadian)
-       return [euclidean.getLoopWithoutCloseSequentialPoints(close, roundLoop)]
-
-def getNewDerivation(elementNode, prefix, sideLength):
-       'Get new derivation.'
-       return RoundDerivation(elementNode, prefix, sideLength)
-
-def getRoundPath( begin, center, close, end, radius, sidesPerRadian ):
-       "Get round path."
-       beginComplex = begin.dropAxis()
-       centerComplex = center.dropAxis()
-       endComplex = end.dropAxis()
-       beginComplexSegmentLength = abs( centerComplex - beginComplex )
-       endComplexSegmentLength = abs( centerComplex - endComplex )
-       minimumRadius = lineation.getMinimumRadius( beginComplexSegmentLength, endComplexSegmentLength, radius )
-       if minimumRadius <= close:
-               return [ center ]
-       beginBevel = center + minimumRadius / beginComplexSegmentLength * ( begin - center )
-       endBevel = center + minimumRadius / endComplexSegmentLength * ( end - center )
-       beginBevelComplex = beginBevel.dropAxis()
-       endBevelComplex = endBevel.dropAxis()
-       midpointComplex = 0.5 * ( beginBevelComplex + endBevelComplex )
-       if radius < 0.0:
-               centerComplex = midpointComplex + midpointComplex - centerComplex
-       midpointMinusCenterComplex = midpointComplex - centerComplex
-       midpointCenterLength = abs( midpointMinusCenterComplex )
-       midpointEndLength = abs( midpointComplex - endBevelComplex )
-       midpointCircleCenterLength = midpointEndLength * midpointEndLength / midpointCenterLength
-       circleRadius = math.sqrt( midpointCircleCenterLength * midpointCircleCenterLength + midpointEndLength * midpointEndLength )
-       circleCenterComplex = midpointComplex + midpointMinusCenterComplex * midpointCircleCenterLength / midpointCenterLength
-       circleCenter = Vector3( circleCenterComplex.real, circleCenterComplex.imag, center.z )
-       endMinusCircleCenterComplex = endBevelComplex - circleCenterComplex
-       beginMinusCircleCenter = beginBevel - circleCenter
-       beginMinusCircleCenterComplex = beginMinusCircleCenter.dropAxis()
-       angleDifference = euclidean.getAngleDifferenceByComplex( endMinusCircleCenterComplex, beginMinusCircleCenterComplex )
-       steps = int( math.ceil( abs( angleDifference ) * sidesPerRadian ) )
-       stepPlaneAngle = euclidean.getWiddershinsUnitPolar( angleDifference / float( steps ) )
-       deltaZStep = ( end.z - begin.z ) / float( steps )
-       roundPath = [ beginBevel ]
-       for step in xrange( 1, steps ):
-               beginMinusCircleCenterComplex = beginMinusCircleCenterComplex * stepPlaneAngle
-               arcPointComplex = circleCenterComplex + beginMinusCircleCenterComplex
-               arcPoint = Vector3( arcPointComplex.real, arcPointComplex.imag, begin.z + deltaZStep * step )
-               roundPath.append( arcPoint )
-       return roundPath + [ endBevel ]
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       lineation.processElementNodeByFunction(elementNode, getManipulatedPaths)
-
-
-class RoundDerivation(object):
-       "Class to hold round variables."
-       def __init__(self, elementNode, prefix, sideLength):
-               'Set defaults.'
-               self.radius = lineation.getFloatByPrefixSide(0.0, elementNode, prefix + 'radius', sideLength)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/segment.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/segment.py
deleted file mode 100644 (file)
index 6a022b9..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-"""
-Add material to support overhang or remove material at the overhang angle.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalExecutionOrder = 60
-
-
-def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
-       "Get segment loop."
-       if len(loop) < 3:
-               return [loop]
-       derivation = SegmentDerivation(elementNode, prefix)
-       if derivation.path == getSegmentPathDefault():
-               return [loop]
-       path = getXNormalizedVector3Path(derivation.path)
-       if euclidean.getIsWiddershinsByVector3(loop):
-               path = path[: : -1]
-               for point in path:
-                       point.x = 1.0 - point.x
-                       if derivation.center == None:
-                               point.y = - point.y
-       segmentLoop = []
-       startEnd = StartEnd(elementNode, len(loop), prefix)
-       for pointIndex in xrange(len(loop)):
-               if startEnd.start <= pointIndex < startEnd.end:
-                       segmentLoop += getSegmentPath(derivation.center, loop, path, pointIndex)
-               else:
-                       segmentLoop.append(loop[pointIndex])
-       return [euclidean.getLoopWithoutCloseSequentialPoints( close, segmentLoop)]
-
-def getNewDerivation(elementNode, prefix, sideLength):
-       'Get new derivation.'
-       return SegmentDerivation(elementNode, prefix)
-
-def getRadialPath(begin, center, end, path):
-       "Get radial path."
-       beginComplex = begin.dropAxis()
-       endComplex = end.dropAxis()
-       centerComplex = center.dropAxis()
-       beginMinusCenterComplex = beginComplex - centerComplex
-       endMinusCenterComplex = endComplex - centerComplex
-       beginMinusCenterComplexRadius = abs( beginMinusCenterComplex )
-       endMinusCenterComplexRadius = abs( endMinusCenterComplex )
-       if beginMinusCenterComplexRadius == 0.0 or endMinusCenterComplexRadius == 0.0:
-               return [ begin ]
-       beginMinusCenterComplex /= beginMinusCenterComplexRadius
-       endMinusCenterComplex /= endMinusCenterComplexRadius
-       angleDifference = euclidean.getAngleDifferenceByComplex( endMinusCenterComplex, beginMinusCenterComplex )
-       radialPath = []
-       for point in path:
-               weightEnd = point.x
-               weightBegin = 1.0 - weightEnd
-               weightedRadius = beginMinusCenterComplexRadius * weightBegin + endMinusCenterComplexRadius * weightEnd * ( 1.0 + point.y )
-               radialComplex = weightedRadius * euclidean.getWiddershinsUnitPolar( angleDifference * point.x ) * beginMinusCenterComplex
-               polygonPoint = center + Vector3( radialComplex.real, radialComplex.imag, point.z )
-               radialPath.append( polygonPoint )
-       return radialPath
-
-def getSegmentPath(center, loop, path, pointIndex):
-       "Get segment path."
-       centerBegin = loop[pointIndex]
-       centerEnd = loop[(pointIndex + 1) % len(loop)]
-       centerEndMinusBegin = centerEnd - centerBegin
-       if abs( centerEndMinusBegin ) <= 0.0:
-               return [ centerBegin ]
-       if center != None:
-               return getRadialPath(centerBegin, center, centerEnd, path)
-       begin = loop[(pointIndex + len(loop) - 1) % len(loop)]
-       end = loop[(pointIndex + 2) % len(loop)]
-       return getWedgePath(begin, centerBegin, centerEnd, centerEndMinusBegin, end, path)
-
-def getSegmentPathDefault():
-       "Get segment path default."
-       return [Vector3(), Vector3(0.0, 1.0)]
-
-def getWedgePath( begin, centerBegin, centerEnd, centerEndMinusBegin, end, path ):
-       "Get segment path."
-       beginComplex = begin.dropAxis()
-       centerBeginComplex = centerBegin.dropAxis()
-       centerEndComplex = centerEnd.dropAxis()
-       endComplex = end.dropAxis()
-       wedgePath = []
-       centerBeginMinusBeginComplex = euclidean.getNormalized( centerBeginComplex - beginComplex )
-       centerEndMinusCenterBeginComplexOriginal = centerEndComplex - centerBeginComplex
-       centerEndMinusCenterBeginComplexLength = abs( centerEndMinusCenterBeginComplexOriginal )
-       if centerEndMinusCenterBeginComplexLength <= 0.0:
-               return [ centerBegin ]
-       centerEndMinusCenterBeginComplex = centerEndMinusCenterBeginComplexOriginal / centerEndMinusCenterBeginComplexLength
-       endMinusCenterEndComplex = euclidean.getNormalized( endComplex - centerEndComplex )
-       widdershinsBegin = getWiddershinsAverageByVector3( centerBeginMinusBeginComplex, centerEndMinusCenterBeginComplex )
-       widdershinsEnd = getWiddershinsAverageByVector3( centerEndMinusCenterBeginComplex, endMinusCenterEndComplex )
-       for point in path:
-               weightEnd = point.x
-               weightBegin = 1.0 - weightEnd
-               polygonPoint = centerBegin + centerEndMinusBegin * point.x
-               weightedWiddershins = widdershinsBegin * weightBegin + widdershinsEnd * weightEnd
-               polygonPoint += weightedWiddershins * point.y * centerEndMinusCenterBeginComplexLength
-               polygonPoint.z += point.z
-               wedgePath.append( polygonPoint )
-       return wedgePath
-
-def getWiddershinsAverageByVector3( centerMinusBeginComplex, endMinusCenterComplex ):
-       "Get the normalized average of the widdershins vectors."
-       centerMinusBeginWiddershins = Vector3( - centerMinusBeginComplex.imag, centerMinusBeginComplex.real )
-       endMinusCenterWiddershins = Vector3( - endMinusCenterComplex.imag, endMinusCenterComplex.real )
-       return ( centerMinusBeginWiddershins + endMinusCenterWiddershins ).getNormalized()
-
-def getXNormalizedVector3Path(path):
-       "Get path where the x ranges from 0 to 1."
-       if len(path) < 1:
-               return path
-       minimumX = path[0].x
-       for point in path[1 :]:
-               minimumX = min( minimumX, point.x )
-       for point in path:
-               point.x -= minimumX
-       maximumX = path[0].x
-       for point in path[1 :]:
-               maximumX = max( maximumX, point.x )
-       for point in path:
-               point.x /= maximumX
-       return path
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       lineation.processElementNodeByFunction(elementNode, getManipulatedPaths)
-
-
-class SegmentDerivation(object):
-       "Class to hold segment variables."
-       def __init__(self, elementNode, prefix):
-               'Set defaults.'
-               self.center = evaluate.getVector3ByPrefix(None, elementNode, prefix + 'center')
-               self.path = evaluate.getPathByPrefix(elementNode, getSegmentPathDefault(), prefix)
-
-
-class StartEnd(object):
-       'Class to get a start through end range.'
-       def __init__(self, elementNode, modulo, prefix):
-               "Initialize."
-               self.start = evaluate.getEvaluatedInt(0, elementNode, prefix + 'start')
-               self.extent = evaluate.getEvaluatedInt(modulo - self.start, elementNode, prefix + 'extent')
-               self.end = evaluate.getEvaluatedInt(self.start + self.extent, elementNode, prefix + 'end')
-               self.revolutions = evaluate.getEvaluatedInt(1, elementNode, prefix + 'revolutions')
-               if self.revolutions > 1:
-                       self.end += modulo * (self.revolutions - 1)
-
-       def __repr__(self):
-               "Get the string representation of this StartEnd."
-               return '%s, %s, %s' % (self.start, self.end, self.revolutions)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/wedge.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_paths/wedge.py
deleted file mode 100644 (file)
index 952303d..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-"""
-Add material to support overhang or remove material at the overhang angle.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.vector3 import Vector3
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalExecutionOrder = -200
-
-
-def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
-       "Get wedge loop."
-       derivation = WedgeDerivation(elementNode, prefix)
-       loop.append(derivation.center)
-       return [loop]
-
-def getNewDerivation(elementNode, prefix, sideLength):
-       'Get new derivation.'
-       return WedgeDerivation(elementNode, prefix)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       lineation.processElementNodeByFunction(elementNode, getManipulatedPaths)
-
-
-class WedgeDerivation(object):
-       "Class to hold wedge variables."
-       def __init__(self, elementNode, prefix):
-               'Set defaults.'
-               self.center = evaluate.getVector3ByPrefix(Vector3(), elementNode, prefix + 'center')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/_bottom.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/_bottom.py
deleted file mode 100644 (file)
index c63b039..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-"""
-Boolean geometry bottom.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting
-from fabmetheus_utilities.geometry.geometry_utilities import boolean_geometry
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities import euclidean
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalExecutionOrder = 400
-
-
-def bottomElementNode(derivation, target):
-       "Bottom target."
-       xmlObject = target.xmlObject
-       if xmlObject == None:
-               print('Warning, bottomTarget in bottom could not get xmlObject for:')
-               print(target)
-               print(derivation.elementNode)
-               return
-       targetMatrix = matrix.getBranchMatrixSetElementNode(target)
-       lift = derivation.altitude
-       transformedPaths = xmlObject.getTransformedPaths()
-       if len(transformedPaths) > 0:
-               lift += derivation.getAdditionalPathLift() - euclidean.getBottomByPaths(transformedPaths)
-       else:
-               lift -= boolean_geometry.getMinimumZ(xmlObject)
-       targetMatrix.tetragrid = matrix.getIdentityTetragrid(targetMatrix.tetragrid)
-       targetMatrix.tetragrid[2][3] += lift
-       matrix.setElementNodeDictionaryMatrix(target, targetMatrix)
-
-def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix):
-       'Get bottomed geometryOutput.'
-       derivation = BottomDerivation(elementNode, prefix)
-       copyShallow = elementNode.getCopyShallow()
-       solid.processElementNodeByGeometry(copyShallow, geometryOutput)
-       targetMatrix = matrix.getBranchMatrixSetElementNode(elementNode)
-       matrix.setElementNodeDictionaryMatrix(copyShallow, targetMatrix)
-       minimumZ = boolean_geometry.getMinimumZ(copyShallow.xmlObject)
-       copyShallow.parentNode.xmlObject.archivableObjects.remove(copyShallow.xmlObject)
-       lift = derivation.altitude - minimumZ
-       vertexes = matrix.getVertexes(geometryOutput)
-       for vertex in vertexes:
-               vertex.z += lift
-       return geometryOutput
-
-def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
-       'Get flipped paths.'
-       if len(loop) < 1:
-               return [[]]
-       derivation = BottomDerivation(elementNode, prefix)
-       targetMatrix = matrix.getBranchMatrixSetElementNode(elementNode)
-       transformedLoop = matrix.getTransformedVector3s(matrix.getIdentityTetragrid(targetMatrix.tetragrid), loop)
-       lift = derivation.altitude + derivation.getAdditionalPathLift() - euclidean.getBottomByPath(transformedLoop)
-       for point in loop:
-               point.z += lift
-       return [loop]
-
-def getNewDerivation(elementNode, prefix, sideLength):
-       'Get new derivation.'
-       return BottomDerivation(elementNode, '')
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       processElementNodeByDerivation(None, elementNode)
-
-def processElementNodeByDerivation(derivation, elementNode):
-       'Process the xml element by derivation.'
-       if derivation == None:
-               derivation = BottomDerivation(elementNode, '')
-       targets = evaluate.getElementNodesByKey(elementNode, 'target')
-       if len(targets) < 1:
-               print('Warning, processElementNode in bottom could not get targets for:')
-               print(elementNode)
-               return
-       for target in targets:
-               bottomElementNode(derivation, target)
-
-
-class BottomDerivation(object):
-       "Class to hold bottom variables."
-       def __init__(self, elementNode, prefix):
-               'Set defaults.'
-               self.altitude = evaluate.getEvaluatedFloat(0.0, elementNode, prefix + 'altitude')
-               self.elementNode = elementNode
-               self.liftPath = evaluate.getEvaluatedBoolean(True, elementNode, prefix + 'liftPath')
-
-       def getAdditionalPathLift(self):
-               "Get path lift."
-               return 0.5 * setting.getLayerHeight(self.elementNode) * float(self.liftPath)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/_inset.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/_inset.py
deleted file mode 100644 (file)
index fabda37..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-"""
-Create inset.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting
-from fabmetheus_utilities.geometry.geometry_utilities import boolean_solid
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3index import Vector3Index
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import intercircle
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalExecutionOrder = 80
-
-
-def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix):
-       'Get inset geometryOutput.'
-       derivation = InsetDerivation(elementNode, prefix)
-       if derivation.radius == 0.0:
-               return geometryOutput
-       halfLayerHeight = 0.5 * derivation.radius
-       importRadius = 0.5 * derivation.radius * setting.getImportCoarseness(elementNode)
-       loopLayers = solid.getLoopLayersSetCopy(elementNode, geometryOutput, importRadius, derivation.radius)
-       triangleAltitude = math.sqrt(0.75) * derivation.radius
-       loops = []
-       vertexes = []
-       for loopLayerIndex in xrange(1, len(loopLayers), 2):
-               loopLayer = loopLayers[loopLayerIndex]
-               loopLayer.loops[0] = intercircle.getLargestInsetLoopFromLoop(loopLayer.loops[0], triangleAltitude)
-       for loopLayerIndex in xrange(0, len(loopLayers), 2):
-               loopLayer = loopLayers[loopLayerIndex]
-               loopLists = [[solid.getLoopOrEmpty(loopLayerIndex - 2, loopLayers)]]
-               loopLists.append([solid.getLoopOrEmpty(loopLayerIndex - 1, loopLayers)])
-               loopLists.append([intercircle.getLargestInsetLoopFromLoop(loopLayer.loops[0], derivation.radius)])
-               if evaluate.getEvaluatedBoolean(True, elementNode, prefix + 'insetTop'):
-                       loopLists.append([solid.getLoopOrEmpty(loopLayerIndex + 1, loopLayers)])
-                       loopLists.append([solid.getLoopOrEmpty(loopLayerIndex + 2, loopLayers)])
-               largestLoop = euclidean.getLargestLoop(boolean_solid.getLoopsIntersection(importRadius, loopLists))
-               triangle_mesh.addVector3Loop(largestLoop, loops, vertexes, loopLayer.z)
-       if evaluate.getEvaluatedBoolean(False, elementNode, prefix + 'addExtraTopLayer') and len(loops) > 0:
-               topLoop = loops[-1]
-               vector3Loop = []
-               loops.append(vector3Loop)
-               z = topLoop[0].z + derivation.radius
-               for point in topLoop:
-                       vector3Index = Vector3Index(len(vertexes), point.x, point.y, z)
-                       vector3Loop.append(vector3Index)
-                       vertexes.append(vector3Index)
-       return triangle_mesh.getMeldedPillarOutput(loops)
-
-def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
-       "Get inset path."
-       derivation = InsetDerivation(elementNode, prefix)
-       return intercircle.getInsetLoopsFromVector3Loop(loop, derivation.radius)
-
-def getNewDerivation(elementNode, prefix, sideLength):
-       'Get new derivation.'
-       return OutsetDerivation(elementNode, prefix)
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       solid.processElementNodeByFunctionPair(elementNode, getManipulatedGeometryOutput, getManipulatedPaths)
-
-
-class InsetDerivation(object):
-       "Class to hold inset variables."
-       def __init__(self, elementNode, prefix):
-               'Set defaults.'
-               self.radius = evaluate.getEvaluatedFloat(2.0 * setting.getEdgeWidth(elementNode), elementNode, prefix + 'radius')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/_outset.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/_outset.py
deleted file mode 100644 (file)
index ac4d6f3..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-"""
-Create inset.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting
-from fabmetheus_utilities.geometry.geometry_utilities import boolean_solid
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import intercircle
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalExecutionOrder = 80
-
-
-def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix):
-       'Get outset geometryOutput.'
-       derivation = OutsetDerivation(elementNode, prefix)
-       if derivation.radius == 0.0:
-               return geometryOutput
-       halfLayerHeight = 0.5 * derivation.radius
-       importRadius = 0.5 * derivation.radius * setting.getImportCoarseness(elementNode)
-       loopLayers = solid.getLoopLayersSetCopy(elementNode, geometryOutput, importRadius, derivation.radius)
-       if len(loopLayers) == 0:
-               return triangle_mesh.getMeldedPillarOutput([])
-       triangleAltitude = math.sqrt(0.75) * derivation.radius
-       loops = []
-       vertexes = []
-       for loopLayerIndex in xrange(1, len(loopLayers), 2):
-               loopLayer = loopLayers[loopLayerIndex]
-               loopLayer.loops[0] = intercircle.getLargestInsetLoopFromLoop(loopLayer.loops[0], triangleAltitude)
-       z = loopLayers[0].z - derivation.radius
-       for loopIndex in xrange(-2, len(loopLayers) + 2, 2):
-               loopLists = [[solid.getLoopOrEmpty(loopIndex - 2, loopLayers)]]
-               loopLists.append([solid.getLoopOrEmpty(loopIndex - 1, loopLayers)])
-               loopLists.append([intercircle.getLargestInsetLoopFromLoop(solid.getLoopOrEmpty(loopIndex, loopLayers), -derivation.radius)])
-               loopLists.append([solid.getLoopOrEmpty(loopIndex + 1, loopLayers)])
-               loopLists.append([solid.getLoopOrEmpty(loopIndex + 2, loopLayers)])
-               largestLoop = euclidean.getLargestLoop(boolean_solid.getLoopsUnion(importRadius, loopLists))
-               triangle_mesh.addVector3Loop(largestLoop, loops, vertexes, z)
-               z += derivation.radius
-       return triangle_mesh.getMeldedPillarOutput(loops)
-
-def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
-       "Get outset path."
-       derivation = OutsetDerivation(elementNode, prefix)
-       return intercircle.getInsetLoopsFromVector3Loop(loop, -derivation.radius)
-
-def getNewDerivation(elementNode, prefix, sideLength):
-       'Get new derivation.'
-       return OutsetDerivation(elementNode, prefix)
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       solid.processElementNodeByFunctionPair(elementNode, getManipulatedGeometryOutput, getManipulatedPaths)
-
-
-class OutsetDerivation(object):
-       "Class to hold outset variables."
-       def __init__(self, elementNode, prefix):
-               'Set defaults.'
-               self.radius = evaluate.getEvaluatedFloat(2.0 * setting.getEdgeWidth(elementNode), elementNode, prefix + 'radius')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/equation.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/equation.py
deleted file mode 100644 (file)
index 075b58b..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-"""
-Equation for vertexes.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities import euclidean
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalExecutionOrder = -100
-
-
-def equate(point, returnValue):
-       "Get equation for rectangular."
-       point.setToVector3(evaluate.getVector3ByDictionaryListValue(returnValue, point))
-
-def equatePoints(elementNode, points, prefix, revolutions):
-       "Equate the points."
-       derivation = EquationDerivation(elementNode, prefix)
-       for equationResult in derivation.equationResults:
-               for point in points:
-                       returnValue = equationResult.getReturnValue(point, revolutions)
-                       if returnValue == None:
-                               print('Warning, returnValue in alterVertexesByEquation in equation is None for:')
-                               print(point)
-                               print(elementNode)
-                       else:
-                               equationResult.equationFunction(point, returnValue)
-
-def equateX(point, returnValue):
-       "Get equation for rectangular x."
-       point.x = returnValue
-
-def equateY(point, returnValue):
-       "Get equation for rectangular y."
-       point.y = returnValue
-
-def equateZ(point, returnValue):
-       "Get equation for rectangular z."
-       point.z = returnValue
-
-def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix):
-       "Get equated geometryOutput."
-       equatePoints(elementNode, matrix.getVertexes(geometryOutput), prefix, None)
-       return geometryOutput
-
-def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
-       "Get equated paths."
-       equatePoints(elementNode, loop, prefix, 0.0)
-       return [loop]
-
-def getNewDerivation(elementNode, prefix, sideLength):
-       'Get new derivation.'
-       return EquationDerivation(elementNode, prefix)
-
-
-class EquationDerivation(object):
-       "Class to hold equation variables."
-       def __init__(self, elementNode, prefix):
-               'Set defaults.'
-               self.equationResults = []
-               self.addEquationResult(elementNode, equate, prefix)
-               self.addEquationResult(elementNode, equateX, prefix)
-               self.addEquationResult(elementNode, equateY, prefix)
-               self.addEquationResult(elementNode, equateZ, prefix)
-
-       def addEquationResult(self, elementNode, equationFunction, prefix):
-               'Add equation result to equationResults.'
-               prefixedEquationName = prefix + equationFunction.__name__[ len('equate') : ].replace('Dot', '.').lower()
-               if prefixedEquationName in elementNode.attributes:
-                       self.equationResults.append(EquationResult(elementNode, equationFunction, prefixedEquationName))
-
-
-class EquationResult(object):
-       "Class to get equation results."
-       def __init__(self, elementNode, equationFunction, key):
-               "Initialize."
-               self.distance = 0.0
-               elementNode.xmlObject = evaluate.getEvaluatorSplitWords(elementNode.attributes[key])
-               self.equationFunction = equationFunction
-               self.function = evaluate.Function(elementNode)
-               self.points = []
-
-       def getReturnValue(self, point, revolutions):
-               "Get return value."
-               if self.function == None:
-                       return point
-               self.function.localDictionary['azimuth'] = math.degrees(math.atan2(point.y, point.x))
-               if len(self.points) > 0:
-                       self.distance += abs(point - self.points[-1])
-               self.function.localDictionary['distance'] = self.distance
-               self.function.localDictionary['radius'] = abs(point.dropAxis())
-               if revolutions != None:
-                       if len( self.points ) > 0:
-                               revolutions += 0.5 / math.pi * euclidean.getAngleAroundZAxisDifference(point, self.points[-1])
-                       self.function.localDictionary['revolutions'] = revolutions
-               self.function.localDictionary['vertex'] = point
-               self.function.localDictionary['vertexes'] = self.points
-               self.function.localDictionary['vertexindex'] = len(self.points)
-               self.function.localDictionary['x'] = point.x
-               self.function.localDictionary['y'] = point.y
-               self.function.localDictionary['z'] = point.z
-               self.points.append(point)
-               return self.function.getReturnValueWithoutDeletion()
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/flip.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/flip.py
deleted file mode 100644 (file)
index af666c3..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-"""
-Add material to support overhang or remove material at the overhang angle.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities.vector3 import Vector3
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalExecutionOrder = 200
-
-
-# http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=269576
-# http://www.opengl.org/resources/code/samples/sig99/advanced99/notes/node159.html
-#      m.a00 = -2 * norm.x * norm.x + 1;
-#      m.a10 = -2 * norm.y * norm.x;
-#      m.a20 = -2 * norm.z * norm.x;
-#      m.a30 = 0;
-
-#      m.a01 = -2 * norm.x * norm.y;
-#      m.a11 = -2 * norm.y * norm.y + 1;
-#      m.a21 = -2 * norm.z * norm.y;
-#      m.a31 = 0;
-
-#      m.a02 = -2 * norm.x * norm.z;
-#      m.a12 = -2 * norm.y * norm.z;
-#      m.a22 = -2 * norm.z * norm.z + 1;
-#      m.a32 = 0;
-
-#      m.a03 = -2 * norm.x * d;
-#      m.a13 = -2 * norm.y * d;
-#      m.a23 = -2 * norm.z * d;
-#      m.a33 = 1;
-
-# normal = unit_vector(normal[:3])
-# M = numpy.identity(4)
-# M[:3, :3] -= 2.0 * numpy.outer(normal, normal)
-# M[:3, 3] = (2.0 * numpy.dot(point[:3], normal)) * normal
-# return M
-def flipPoints(elementNode, points, prefix):
-       'Flip the points.'
-       derivation = FlipDerivation(elementNode, prefix)
-       for point in points:
-               point.setToVector3(point - 2.0 * derivation.axis.dot(point - derivation.origin) * derivation.axis)
-
-def getFlippedLoop(elementNode, loop, prefix):
-       'Get flipped loop.'
-       flipPoints(elementNode, loop, prefix)
-       if getShouldReverse(elementNode, prefix):
-               loop.reverse()
-       return loop
-
-def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix):
-       'Get equated geometryOutput.'
-       flipPoints(elementNode, matrix.getVertexes(geometryOutput), prefix)
-       return geometryOutput
-
-def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
-       'Get flipped paths.'
-       return [getFlippedLoop(elementNode, loop, prefix)]
-
-def getNewDerivation(elementNode, prefix, sideLength):
-       'Get new derivation.'
-       return FlipDerivation(elementNode, prefix)
-
-def getShouldReverse(elementNode, prefix):
-       'Determine if the loop should be reversed.'
-       return evaluate.getEvaluatedBoolean(True, elementNode, prefix + 'reverse')
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       solid.processElementNodeByFunctionPair(elementNode, getManipulatedGeometryOutput, getManipulatedPaths)
-
-
-class FlipDerivation(object):
-       "Class to hold flip variables."
-       def __init__(self, elementNode, prefix):
-               'Set defaults.'
-               self.origin = evaluate.getVector3ByPrefix(Vector3(), elementNode, prefix + 'origin')
-               self.axis = evaluate.getVector3ByPrefix(Vector3(1.0, 0.0, 0.0), elementNode, prefix + 'axis').getNormalized()
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/mirror.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/manipulation_shapes/mirror.py
deleted file mode 100644 (file)
index 3f06c78..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-"""
-Add material to support overhang or remove material at the overhang angle.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.geometry_tools import face
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities.geometry.manipulation_shapes import flip
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities import euclidean
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalExecutionOrder = 200
-
-
-def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix):
-       'Get equated geometryOutput.'
-       flippedGeometryOutput = triangle_mesh.getGeometryOutputCopy(geometryOutput)
-       flip.flipPoints(elementNode, matrix.getVertexes(flippedGeometryOutput), prefix)
-       if flip.getShouldReverse(elementNode, prefix):
-               flippedFaces = face.getFaces(flippedGeometryOutput)
-               for flippedFace in flippedFaces:
-                       flippedFace.vertexIndexes.reverse()
-       return {'union' : {'shapes' : [flippedGeometryOutput, geometryOutput]}}
-
-def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
-       'Get flipped paths.'
-       return [loop + flip.getFlippedLoop(elementNode, euclidean.getPathCopy(loop), prefix)]
-
-def getNewDerivation(elementNode, prefix, sideLength):
-       'Get new derivation.'
-       return evaluate.EmptyObject()
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       solid.processElementNodeByFunctionPair(elementNode, getManipulatedGeometryOutput, getManipulatedPaths)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/cube.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/cube.py
deleted file mode 100644 (file)
index 886f5eb..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-"""
-Boolean geometry cube.
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addCube(elementNode, faces, inradius, vertexes):
-       'Add cube by inradius.'
-       square = [
-               complex(-inradius.x, -inradius.y),
-               complex(inradius.x, -inradius.y),
-               complex(inradius.x, inradius.y),
-               complex(-inradius.x, inradius.y)]
-       bottomTopSquare = triangle_mesh.getAddIndexedLoops(square, vertexes, [-inradius.z, inradius.z])
-       triangle_mesh.addPillarByLoops(faces, bottomTopSquare)
-
-def getGeometryOutput(elementNode, inradius):
-       'Get cube triangle mesh by inradius.'
-       faces = []
-       vertexes = []
-       addCube(elementNode, faces, inradius, vertexes)
-       return {'trianglemesh' : {'vertex' : vertexes, 'face' : faces}}
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return CubeDerivation(elementNode)
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       evaluate.processArchivable(Cube, elementNode)
-
-
-class Cube(triangle_mesh.TriangleMesh):
-       'A cube object.'
-       def addXMLSection(self, depth, output):
-               'Add the xml section for this object.'
-               pass
-
-       def createShape(self):
-               'Create the shape.'
-               addCube(self.elementNode, self.faces, self.inradius, self.vertexes)
-
-       def setToElementNode(self, elementNode):
-               'Set to elementNode.'
-               attributes = elementNode.attributes
-               self.elementNode = elementNode
-               self.inradius = CubeDerivation(elementNode).inradius
-               attributes['inradius.x'] = self.inradius.x
-               attributes['inradius.y'] = self.inradius.y
-               attributes['inradius.z'] = self.inradius.z
-               if 'inradius' in attributes:
-                       del attributes['inradius']
-               self.createShape()
-               solid.processArchiveRemoveSolid(elementNode, self.getGeometryOutput())
-
-
-class CubeDerivation(object):
-       "Class to hold cube variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.inradius = evaluate.getVector3ByPrefixes(elementNode, ['demisize', 'inradius'], Vector3(1.0, 1.0, 1.0))
-               self.inradius = evaluate.getVector3ByMultiplierPrefix(elementNode, 2.0, 'size', self.inradius)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/cylinder.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/cylinder.py
deleted file mode 100644 (file)
index 40abe76..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-"""
-Boolean geometry cylinder.
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import lineation
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities.geometry.solids import cube
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-import math
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addCylinder(faces, inradius, sides, topOverBottom, vertexes):
-       'Add cylinder by inradius.'
-       polygonBottom = euclidean.getComplexPolygonByComplexRadius(complex(inradius.x, inradius.y), sides)
-       polygonTop = polygonBottom
-       if topOverBottom <= 0.0:
-               polygonTop = [complex()]
-       elif topOverBottom != 1.0:
-               polygonTop = euclidean.getComplexPathByMultiplier(topOverBottom, polygonTop)
-       bottomTopPolygon = [
-               triangle_mesh.getAddIndexedLoop(polygonBottom, vertexes, -inradius.z),
-               triangle_mesh.getAddIndexedLoop(polygonTop, vertexes, inradius.z)]
-       triangle_mesh.addPillarByLoops(faces, bottomTopPolygon)
-
-def addCylinderOutputByEndStart(endZ, inradiusComplex, outputs, sides, start, topOverBottom=1.0):
-       'Add cylinder triangle mesh by endZ, inradius and start.'
-       inradius = Vector3(inradiusComplex.real, inradiusComplex.imag, 0.5 * abs(endZ - start.z))
-       cylinderOutput = getGeometryOutput(inradius, sides, topOverBottom)
-       vertexes = matrix.getVertexes(cylinderOutput)
-       if endZ < start.z:
-               for vertex in vertexes:
-                       vertex.z = -vertex.z
-       translation = Vector3(start.x, start.y, inradius.z + min(start.z, endZ))
-       euclidean.translateVector3Path(vertexes, translation)
-       outputs.append(cylinderOutput)
-
-def getGeometryOutput(inradius, sides, topOverBottom):
-       'Get cylinder triangle mesh by inradius.'
-       faces = []
-       vertexes = []
-       addCylinder(faces, inradius, sides, topOverBottom, vertexes)
-       return {'trianglemesh' : {'vertex' : vertexes, 'face' : faces}}
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return CylinderDerivation(elementNode)
-
-def getTopOverBottom(angle, endZ, inradiusComplex, startZ):
-       'Get topOverBottom by angle in radians, endZ, inradius and start.'
-       return max(1.0 - abs(endZ - startZ) * math.tan(angle) / lineation.getRadiusAverage(inradiusComplex), 0.0)
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       evaluate.processArchivable(Cylinder, elementNode)
-
-
-class Cylinder( cube.Cube ):
-       'A cylinder object.'
-       def __init__(self):
-               'Add empty lists.'
-               cube.Cube.__init__(self)
-
-       def createShape(self):
-               'Create the shape.'
-               sides = evaluate.getSidesMinimumThreeBasedOnPrecision(self.elementNode, max(self.inradius.x, self.inradius.y))
-               if self.elementNode.getCascadeBoolean(False, 'radiusAreal'):
-                       radiusArealizedMultiplier = euclidean.getRadiusArealizedMultiplier(sides)
-                       self.inradius.x *= radiusArealizedMultiplier
-                       self.inradius.y *= radiusArealizedMultiplier
-               addCylinder(self.faces, self.inradius, sides, self.topOverBottom, self.vertexes)
-
-       def setToElementNode(self, elementNode):
-               'Set to elementNode.'
-               attributes = elementNode.attributes
-               self.elementNode = elementNode
-               derivation = CylinderDerivation(elementNode)
-               self.inradius = derivation.inradius
-               self.topOverBottom = derivation.topOverBottom
-               if 'inradius' in attributes:
-                       del attributes['inradius']
-               attributes['height'] = self.inradius.z + self.inradius.z
-               attributes['radius.x'] = self.inradius.x
-               attributes['radius.y'] = self.inradius.y
-               attributes['topOverBottom'] = self.topOverBottom
-               self.createShape()
-               solid.processArchiveRemoveSolid(elementNode, self.getGeometryOutput())
-
-
-class CylinderDerivation(object):
-       "Class to hold cylinder variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.inradius = evaluate.getVector3ByPrefixes(elementNode, ['demisize', 'inradius', 'radius'], Vector3(1.0, 1.0, 1.0))
-               self.inradius = evaluate.getVector3ByMultiplierPrefixes(elementNode, 2.0, ['diameter', 'size'], self.inradius)
-               self.inradius.z = 0.5 * evaluate.getEvaluatedFloat(self.inradius.z + self.inradius.z, elementNode, 'height')
-               self.topOverBottom = evaluate.getEvaluatedFloat(1.0, elementNode, 'topOverBottom')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/difference.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/difference.py
deleted file mode 100644 (file)
index 296b172..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-"""
-Boolean geometry difference of solids.
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities import boolean_solid
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.solids import group
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def convertElementNode(elementNode, geometryOutput):
-       "Convert the xml element to a difference xml element."
-       group.convertContainerElementNode(elementNode, geometryOutput, Difference())
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return evaluate.EmptyObject(elementNode)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       evaluate.processArchivable(Difference, elementNode)
-
-
-class Difference( boolean_solid.BooleanSolid ):
-       "A difference object."
-       def getLoopsFromObjectLoopsList(self, importRadius, visibleObjectLoopsList):
-               "Get loops from visible object loops list."
-               return self.getDifference(importRadius, visibleObjectLoopsList)
-
-       def getXMLLocalName(self):
-               "Get xml class name."
-               return self.__class__.__name__.lower()
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/group.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/group.py
deleted file mode 100644 (file)
index 5785e73..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-"""
-Boolean geometry group of solids.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_tools import dictionary
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities import euclidean
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def convertContainerElementNode(elementNode, geometryOutput, xmlObject):
-       "Convert the xml element to a group xml element."
-       elementNode.linkObject(xmlObject)
-       matrix.getBranchMatrixSetElementNode(elementNode)
-       elementNode.getXMLProcessor().createChildNodes(geometryOutput['shapes'], elementNode)
-
-def convertElementNode(elementNode, geometryOutput):
-       "Convert the xml element to a group xml element."
-       convertContainerElementNode(elementNode, geometryOutput, Group())
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return evaluate.EmptyObject(elementNode)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       evaluate.processArchivable(Group, elementNode)
-
-
-class Group(dictionary.Dictionary):
-       "A group."
-       def __init__(self):
-               "Add empty lists."
-               dictionary.Dictionary.__init__(self)
-               self.matrix4X4 = matrix.Matrix()
-
-       def addXMLInnerSection(self, depth, output):
-               "Add xml inner section for this object."
-               if self.matrix4X4 != None:
-                       self.matrix4X4.addXML(depth, output)
-               self.addXMLSection(depth, output)
-
-       def addXMLSection(self, depth, output):
-               "Add the xml section for this object."
-               pass
-
-       def getLoops(self, importRadius, z):
-               "Get loops sliced through shape."
-               visibleObjects = evaluate.getVisibleObjects(self.archivableObjects)
-               loops = []
-               for visibleObject in visibleObjects:
-                       loops += visibleObject.getLoops(importRadius, z)
-               return loops
-
-       def getMatrix4X4(self):
-               "Get the matrix4X4."
-               return self.matrix4X4
-
-       def getMatrixChainTetragrid(self):
-               "Get the matrix chain tetragrid."
-               return matrix.getTetragridTimesOther(self.elementNode.parentNode.xmlObject.getMatrixChainTetragrid(), self.matrix4X4.tetragrid)
-
-       def getVisible(self):
-               "Get visible."
-               return euclidean.getBooleanFromDictionary(True, self.getAttributes(), 'visible')
-
-       def setToElementNode(self, elementNode):
-               'Set to elementNode.'
-               self.elementNode = elementNode
-               elementNode.parentNode.xmlObject.archivableObjects.append(self)
-               matrix.getBranchMatrixSetElementNode(elementNode)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/intersection.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/intersection.py
deleted file mode 100644 (file)
index 2af192b..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-"""
-Boolean geometry intersection of solids.
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.solids import difference
-from fabmetheus_utilities.geometry.solids import group
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def convertElementNode(elementNode, geometryOutput):
-       "Convert the xml element to an intersection xml element."
-       group.convertContainerElementNode(elementNode, geometryOutput, Intersection())
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return evaluate.EmptyObject(elementNode)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       evaluate.processArchivable(Intersection, elementNode)
-
-
-class Intersection(difference.Difference):
-       "An intersection object."
-       def getLoopsFromObjectLoopsList(self, importRadius, visibleObjectLoopsList):
-               "Get loops from visible object loops list."
-               return self.getIntersection(importRadius, visibleObjectLoopsList)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/sphere.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/sphere.py
deleted file mode 100644 (file)
index efffcad..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-"""
-Boolean geometry sphere.
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.creation import solid
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.solids import cube
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-import math
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addSphere(elementNode, faces, radius, vertexes):
-       'Add sphere by radius.'
-       bottom = -radius.z
-       sides = evaluate.getSidesMinimumThreeBasedOnPrecision(elementNode, max(radius.x, radius.y, radius.z))
-       sphereSlices = max(sides / 2, 2)
-       equator = euclidean.getComplexPolygonByComplexRadius(complex(radius.x, radius.y), sides)
-       polygons = [triangle_mesh.getAddIndexedLoop([complex()], vertexes, bottom)]
-       zIncrement = (radius.z + radius.z) / float(sphereSlices)
-       z = bottom
-       for sphereSlice in xrange(1, sphereSlices):
-               z += zIncrement
-               zPortion = abs(z) / radius.z
-               multipliedPath = euclidean.getComplexPathByMultiplier(math.sqrt(1.0 - zPortion * zPortion), equator)
-               polygons.append(triangle_mesh.getAddIndexedLoop(multipliedPath, vertexes, z))
-       polygons.append(triangle_mesh.getAddIndexedLoop([complex()], vertexes, radius.z))
-       triangle_mesh.addPillarByLoops(faces, polygons)
-
-def getGeometryOutput(elementNode, radius):
-       'Get triangle mesh from attribute dictionary.'
-       faces = []
-       vertexes = []
-       addSphere(elementNode, faces, radius, vertexes)
-       return {'trianglemesh' : {'vertex' : vertexes, 'face' : faces}}
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return SphereDerivation(elementNode)
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       evaluate.processArchivable(Sphere, elementNode)
-
-
-class Sphere(cube.Cube):
-       'A sphere object.'
-       def createShape(self):
-               'Create the shape.'
-               addSphere(self.elementNode, self.faces, self.radius, self.vertexes)
-
-       def setToElementNode(self, elementNode):
-               'Set to elementNode.'
-               attributes = elementNode.attributes
-               self.elementNode = elementNode
-               self.radius = SphereDerivation(elementNode).radius
-               if 'radius' in attributes:
-                       del attributes['radius']
-               attributes['radius.x'] = self.radius.x
-               attributes['radius.y'] = self.radius.y
-               attributes['radius.z'] = self.radius.z
-               self.createShape()
-               solid.processArchiveRemoveSolid(elementNode, self.getGeometryOutput())
-
-
-class SphereDerivation(object):
-       "Class to hold sphere variables."
-       def __init__(self, elementNode):
-               'Set defaults.'
-               self.radius = evaluate.getVector3ByPrefixes(elementNode, ['demisize', 'radius'], Vector3(1.0, 1.0, 1.0))
-               self.radius = evaluate.getVector3ByMultiplierPrefixes(elementNode, 2.0, ['diameter', 'size'], self.radius)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/triangle_mesh.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/triangle_mesh.py
deleted file mode 100644 (file)
index 36d583f..0000000
+++ /dev/null
@@ -1,949 +0,0 @@
-"""
-Triangle Mesh holds the faces and edges of a triangular mesh.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_tools import face
-from fabmetheus_utilities.geometry.geometry_tools import vertex
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities.geometry.solids import group
-from fabmetheus_utilities import xml_simple_writer
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities.vector3index import Vector3Index
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import intercircle
-from fabmetheus_utilities import settings
-import math
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addEdgePair( edgePairTable, edges, faceEdgeIndex, remainingEdgeIndex, remainingEdgeTable ):
-       'Add edge pair to the edge pair table.'
-       if faceEdgeIndex == remainingEdgeIndex:
-               return
-       if not faceEdgeIndex in remainingEdgeTable:
-               return
-       edgePair = EdgePair().getFromIndexesEdges( [ remainingEdgeIndex, faceEdgeIndex ], edges )
-       edgePairTable[ str( edgePair ) ] = edgePair
-
-def addFacesByConcaveLoop(faces, indexedLoop):
-       'Add faces from a polygon which is concave.'
-       if len(indexedLoop) < 3:
-               return
-       remainingLoop = indexedLoop[:]
-       while len(remainingLoop) > 2:
-               remainingLoop = getRemainingLoopAddFace(faces, remainingLoop)
-
-def addFacesByConvex(faces, indexedLoop):
-       'Add faces from a convex polygon.'
-       if len(indexedLoop) < 3:
-               return
-       indexBegin = indexedLoop[0].index
-       for indexedPointIndex in xrange(1, len(indexedLoop) - 1):
-               indexCenter = indexedLoop[indexedPointIndex].index
-               indexEnd = indexedLoop[(indexedPointIndex + 1) % len(indexedLoop) ].index
-               if indexBegin != indexCenter and indexCenter != indexEnd and indexEnd != indexBegin:
-                       faceFromConvex = face.Face()
-                       faceFromConvex.index = len(faces)
-                       faceFromConvex.vertexIndexes.append(indexBegin)
-                       faceFromConvex.vertexIndexes.append(indexCenter)
-                       faceFromConvex.vertexIndexes.append(indexEnd)
-                       faces.append(faceFromConvex)
-
-def addFacesByConvexBottomTopLoop(faces, indexedLoopBottom, indexedLoopTop):
-       'Add faces from loops.'
-       if len(indexedLoopBottom) == 0 or len(indexedLoopTop) == 0:
-               return
-       for indexedPointIndex in xrange(max(len(indexedLoopBottom), len(indexedLoopTop))):
-               indexedConvex = []
-               if len(indexedLoopBottom) > 1:
-                       indexedConvex.append(indexedLoopBottom[indexedPointIndex])
-                       indexedConvex.append(indexedLoopBottom[(indexedPointIndex + 1) % len(indexedLoopBottom)])
-               else:
-                       indexedConvex.append(indexedLoopBottom[0])
-               if len(indexedLoopTop) > 1:
-                       indexedConvex.append(indexedLoopTop[(indexedPointIndex + 1) % len(indexedLoopTop)])
-                       indexedConvex.append(indexedLoopTop[indexedPointIndex])
-               else:
-                       indexedConvex.append(indexedLoopTop[0])
-               addFacesByConvex(faces, indexedConvex)
-
-def addFacesByConvexLoops(faces, indexedLoops):
-       'Add faces from loops.'
-       if len(indexedLoops) < 2:
-               return
-       for indexedLoopsIndex in xrange(len(indexedLoops) - 2):
-               addFacesByConvexBottomTopLoop(faces, indexedLoops[indexedLoopsIndex], indexedLoops[indexedLoopsIndex + 1])
-       indexedLoopBottom = indexedLoops[-2]
-       indexedLoopTop = indexedLoops[-1]
-       if len(indexedLoopTop) < 1:
-               indexedLoopTop = indexedLoops[0]
-       addFacesByConvexBottomTopLoop(faces, indexedLoopBottom, indexedLoopTop)
-
-def addFacesByConvexReversed(faces, indexedLoop):
-       'Add faces from a reversed convex polygon.'
-       addFacesByConvex(faces, indexedLoop[: : -1])
-
-def addFacesByGrid(faces, grid):
-       'Add faces from grid.'
-       cellTopLoops = getIndexedCellLoopsFromIndexedGrid(grid)
-       for cellTopLoop in cellTopLoops:
-               addFacesByConvex(faces, cellTopLoop)
-
-def addFacesByLoop(faces, indexedLoop):
-       'Add faces from a polygon which may be concave.'
-       if len(indexedLoop) < 3:
-               return
-       lastNormal = None
-       for pointIndex, point in enumerate(indexedLoop):
-               center = indexedLoop[(pointIndex + 1) % len(indexedLoop)]
-               end = indexedLoop[(pointIndex + 2) % len(indexedLoop)]
-               normal = euclidean.getNormalWeighted(point, center, end)
-               if abs(normal) > 0.0:
-                       if lastNormal != None:
-                               if lastNormal.dot(normal) < 0.0:
-                                       addFacesByConcaveLoop(faces, indexedLoop)
-                                       return
-                       lastNormal = normal
-#      totalNormal = Vector3()
-#      for pointIndex, point in enumerate(indexedLoop):
-#              center = indexedLoop[(pointIndex + 1) % len(indexedLoop)]
-#              end = indexedLoop[(pointIndex + 2) % len(indexedLoop)]
-#              totalNormal += euclidean.getNormalWeighted(point, center, end)
-#      totalNormal.normalize()
-       addFacesByConvex(faces, indexedLoop)
-
-def addFacesByLoopReversed(faces, indexedLoop):
-       'Add faces from a reversed convex polygon.'
-       addFacesByLoop(faces, indexedLoop[: : -1])
-
-def addFacesByMeldedConvexLoops(faces, indexedLoops):
-       'Add faces from melded loops.'
-       if len(indexedLoops) < 2:
-               return
-       for indexedLoopsIndex in xrange(len(indexedLoops) - 2):
-               FaceGenerator(faces, indexedLoops[indexedLoopsIndex], indexedLoops[indexedLoopsIndex + 1])
-       indexedLoopBottom = indexedLoops[-2]
-       indexedLoopTop = indexedLoops[-1]
-       if len(indexedLoopTop) < 1:
-               indexedLoopTop = indexedLoops[0]
-       FaceGenerator(faces, indexedLoopBottom, indexedLoopTop)
-
-def addLoopToPointTable(loop, pointTable):
-       'Add the points in the loop to the point table.'
-       for point in loop:
-               pointTable[point] = None
-
-def addMeldedPillarByLoops(faces, indexedLoops):
-       'Add melded pillar by loops which may be concave.'
-       if len(indexedLoops) < 1:
-               return
-       if len(indexedLoops[-1]) < 1:
-               addFacesByMeldedConvexLoops(faces, indexedLoops)
-               return
-       addFacesByLoopReversed(faces, indexedLoops[0])
-       addFacesByMeldedConvexLoops(faces, indexedLoops)
-       addFacesByLoop(faces, indexedLoops[-1])
-
-def addPillarByLoops(faces, indexedLoops):
-       'Add pillar by loops which may be concave.'
-       if len(indexedLoops) < 1:
-               return
-       if len(indexedLoops[-1]) < 1:
-               addFacesByConvexLoops(faces, indexedLoops)
-               return
-       addFacesByLoopReversed(faces, indexedLoops[0])
-       addFacesByConvexLoops(faces, indexedLoops)
-       addFacesByLoop(faces, indexedLoops[-1])
-
-def addPillarFromConvexLoopsGrids(faces, indexedGrids, indexedLoops):
-       'Add pillar from convex loops and grids.'
-       cellBottomLoops = getIndexedCellLoopsFromIndexedGrid(indexedGrids[0])
-       for cellBottomLoop in cellBottomLoops:
-               addFacesByConvexReversed(faces, cellBottomLoop)
-       addFacesByConvexLoops(faces, indexedLoops)
-       addFacesByGrid(faces, indexedGrids[-1])
-
-def addPillarFromConvexLoopsGridTop(faces, indexedGridTop, indexedLoops):
-       'Add pillar from convex loops and grid top.'
-       addFacesByLoopReversed(faces, indexedLoops[0])
-       addFacesByConvexLoops(faces, indexedLoops)
-       addFacesByGrid(faces, indexedGridTop)
-
-def addPointsAtZ(edgePair, points, radius, vertexes, z):
-       'Add point complexes on the segment between the edge intersections with z.'
-       carveIntersectionFirst = getCarveIntersectionFromEdge(edgePair.edges[0], vertexes, z)
-       carveIntersectionSecond = getCarveIntersectionFromEdge(edgePair.edges[1], vertexes, z)
-       # threshold radius above 0.8 can create extra holes on Screw Holder, 0.7 should be safe for everything
-       intercircle.addPointsFromSegment(carveIntersectionFirst, carveIntersectionSecond, points, radius, 0.7)
-
-def addSymmetricXPath(outputs, path, x):
-       'Add x path output to outputs.'
-       vertexes = []
-       loops = [getSymmetricXLoop(path, vertexes, -x), getSymmetricXLoop(path, vertexes, x)]
-       outputs.append(getPillarOutput(loops))
-
-def addSymmetricXPaths(outputs, paths, x):
-       'Add x paths outputs to outputs.'
-       for path in paths:
-               addSymmetricXPath(outputs, path, x)
-
-def addSymmetricYPath(outputs, path, y):
-       'Add y path output to outputs.'
-       vertexes = []
-       loops = [getSymmetricYLoop(path, vertexes, -y), getSymmetricYLoop(path, vertexes, y)]
-       outputs.append(getPillarOutput(loops))
-
-def addSymmetricYPaths(outputs, paths, y):
-       'Add y paths outputs to outputs.'
-       for path in paths:
-               addSymmetricYPath(outputs, path, y)
-
-def addVector3Loop(loop, loops, vertexes, z):
-       'Add vector3Loop to loops if there is something in it, for inset and outset.'
-       vector3Loop = []
-       for point in loop:
-               vector3Index = Vector3Index(len(vertexes), point.real, point.imag, z)
-               vector3Loop.append(vector3Index)
-               vertexes.append(vector3Index)
-       if len(vector3Loop) > 0:
-               loops.append(vector3Loop)
-
-def addWithLeastLength(importRadius, loops, point):
-       'Insert a point into a loop, at the index at which the loop would be shortest.'
-       close = 1.65 * importRadius # a bit over the experimental minimum additional loop length to restore a right angle
-       shortestAdditionalLength = close
-       shortestLoop = None
-       shortestPointIndex = None
-       for loop in loops:
-               if len(loop) > 3:
-                       for pointIndex in xrange(len(loop)):
-                               additionalLoopLength = getAdditionalLoopLength(loop, point, pointIndex)
-                               if additionalLoopLength < shortestAdditionalLength:
-                                       if getIsPointCloseInline(close, loop, point, pointIndex):
-                                               shortestAdditionalLength = additionalLoopLength
-                                               shortestLoop = loop
-                                               shortestPointIndex = pointIndex
-       if shortestPointIndex != None:
-               shortestLoop.insert( shortestPointIndex, point )
-
-def convertElementNode(elementNode, geometryOutput):
-       'Convert the xml element to a TriangleMesh xml element.'
-       elementNode.linkObject(TriangleMesh())
-       matrix.getBranchMatrixSetElementNode(elementNode)
-       vertex.addGeometryList(elementNode, geometryOutput['vertex'])
-       face.addGeometryList(elementNode, geometryOutput['face'])
-       elementNode.getXMLProcessor().processChildNodes(elementNode)
-
-def getAddIndexedGrid( grid, vertexes, z ):
-       'Get and add an indexed grid.'
-       indexedGrid = []
-       for row in grid:
-               indexedRow = []
-               indexedGrid.append( indexedRow )
-               for pointComplex in row:
-                       vector3index = Vector3Index( len(vertexes), pointComplex.real, pointComplex.imag, z )
-                       indexedRow.append(vector3index)
-                       vertexes.append(vector3index)
-       return indexedGrid
-
-def getAddIndexedLoop(loop, vertexes, z):
-       'Get and add an indexed loop.'
-       indexedLoop = []
-       for index in xrange(len(loop)):
-               pointComplex = loop[index]
-               vector3index = Vector3Index(len(vertexes), pointComplex.real, pointComplex.imag, z)
-               indexedLoop.append(vector3index)
-               vertexes.append(vector3index)
-       return indexedLoop
-
-def getAddIndexedLoops( loop, vertexes, zList ):
-       'Get and add indexed loops.'
-       indexedLoops = []
-       for z in zList:
-               indexedLoop = getAddIndexedLoop( loop, vertexes, z )
-               indexedLoops.append(indexedLoop)
-       return indexedLoops
-
-def getAdditionalLoopLength(loop, point, pointIndex):
-       'Get the additional length added by inserting a point into a loop.'
-       afterPoint = loop[pointIndex]
-       beforePoint = loop[(pointIndex + len(loop) - 1) % len(loop)]
-       return abs(point - beforePoint) + abs(point - afterPoint) - abs(afterPoint - beforePoint)
-
-def getCarveIntersectionFromEdge(edge, vertexes, z):
-       'Get the complex where the carve intersects the edge.'
-       firstVertex = vertexes[ edge.vertexIndexes[0] ]
-       firstVertexComplex = firstVertex.dropAxis()
-       secondVertex = vertexes[ edge.vertexIndexes[1] ]
-       secondVertexComplex = secondVertex.dropAxis()
-       zMinusFirst = z - firstVertex.z
-       up = secondVertex.z - firstVertex.z
-       return zMinusFirst * ( secondVertexComplex - firstVertexComplex ) / up + firstVertexComplex
-
-def getClosestDistanceIndexToPoint(point, loop):
-       'Get the distance squared to the closest point of the loop and index of that point.'
-       smallestDistance = 987654321987654321.0
-       closestDistanceIndex = None
-       pointComplex = point.dropAxis()
-       for otherPointIndex, otherPoint in enumerate(loop):
-               distance = abs(pointComplex - otherPoint.dropAxis())
-               if distance < smallestDistance:
-                       smallestDistance = distance
-                       closestDistanceIndex = euclidean.DistanceIndex(distance, otherPointIndex)
-       return closestDistanceIndex
-
-def getDescendingAreaLoops(allPoints, corners, importRadius):
-       'Get descending area loops which include most of the points.'
-       loops = intercircle.getCentersFromPoints(allPoints, importRadius)
-       descendingAreaLoops = []
-       sortLoopsInOrderOfArea(True, loops)
-       pointDictionary = {}
-       for loop in loops:
-               if len(loop) > 2 and getOverlapRatio(loop, pointDictionary) < 0.3 and intercircle.getIsLarge(loop, importRadius):
-                       intercircle.directLoop(not euclidean.getIsInFilledRegion(descendingAreaLoops, loop[0]), loop)
-                       descendingAreaLoops.append(loop)
-                       addLoopToPointTable(loop, pointDictionary)
-       descendingAreaLoops = euclidean.getSimplifiedLoops(descendingAreaLoops, importRadius)
-       return getLoopsWithCorners(corners, importRadius, descendingAreaLoops, pointDictionary)
-
-def getDescendingAreaOrientedLoops(allPoints, corners, importRadius):
-       'Get descending area oriented loops which include most of the points.'
-       return getOrientedLoops(getDescendingAreaLoops(allPoints, corners, importRadius))
-
-def getGeometryOutputByFacesVertexes(faces, vertexes):
-       'Get geometry output dictionary by faces and vertexes.'
-       return {'trianglemesh' : {'vertex' : vertexes, 'face' : faces}}
-
-def getGeometryOutputCopy(object):
-       'Get the geometry output copy.'
-       objectClass = object.__class__
-       if objectClass == dict:
-               objectCopy = {}
-               for key in object:
-                       objectCopy[key] = getGeometryOutputCopy(object[key])
-               return objectCopy
-       if objectClass == list:
-               objectCopy = []
-               for value in object:
-                       objectCopy.append(getGeometryOutputCopy(value))
-               return objectCopy
-       if objectClass == face.Face or objectClass == Vector3 or objectClass == Vector3Index:
-               return object.copy()
-       return object
-
-def getIndexedCellLoopsFromIndexedGrid( grid ):
-       'Get indexed cell loops from an indexed grid.'
-       indexedCellLoops = []
-       for rowIndex in xrange( len( grid ) - 1 ):
-               rowBottom = grid[ rowIndex ]
-               rowTop = grid[ rowIndex + 1 ]
-               for columnIndex in xrange( len( rowBottom ) - 1 ):
-                       columnIndexEnd = columnIndex + 1
-                       indexedConvex = []
-                       indexedConvex.append( rowBottom[ columnIndex ] )
-                       indexedConvex.append( rowBottom[ columnIndex + 1 ] )
-                       indexedConvex.append( rowTop[ columnIndex + 1 ] )
-                       indexedConvex.append( rowTop[ columnIndex ] )
-                       indexedCellLoops.append( indexedConvex )
-       return indexedCellLoops
-
-def getIndexedLoopFromIndexedGrid( indexedGrid ):
-       'Get indexed loop from around the indexed grid.'
-       indexedLoop = indexedGrid[0][:]
-       for row in indexedGrid[1 : -1]:
-               indexedLoop.append( row[-1] )
-       indexedLoop += indexedGrid[-1][: : -1]
-       for row in indexedGrid[ len( indexedGrid ) - 2 : 0 : - 1 ]:
-               indexedLoop.append( row[0] )
-       return indexedLoop
-
-def getInfillDictionary(arounds, aroundWidth, infillInset, infillWidth, pixelTable, rotatedLoops, testLoops=None):
-       'Get combined fill loops which include most of the points.'
-       slightlyGreaterThanInfillInset = intercircle.globalIntercircleMultiplier * infillInset
-       allPoints = intercircle.getPointsFromLoops(rotatedLoops, infillInset, 0.7)
-       centers = intercircle.getCentersFromPoints(allPoints, slightlyGreaterThanInfillInset)
-       infillDictionary = {}
-       for center in centers:
-               insetCenter = intercircle.getSimplifiedInsetFromClockwiseLoop(center, infillInset)
-               insetPoint = insetCenter[0]
-               if len(insetCenter) > 2 and intercircle.getIsLarge(insetCenter, infillInset) and euclidean.getIsInFilledRegion(rotatedLoops, insetPoint):
-                       around = euclidean.getSimplifiedLoop(center, infillInset)
-                       euclidean.addLoopToPixelTable(around, pixelTable, aroundWidth)
-                       arounds.append(around)
-                       insetLoop = intercircle.getSimplifiedInsetFromClockwiseLoop(center, infillInset)
-                       euclidean.addXIntersectionsFromLoopForTable(insetLoop, infillDictionary, infillWidth)
-                       if testLoops != None:
-                               testLoops.append(insetLoop)
-       return infillDictionary
-
-def getInsetPoint( loop, tinyRadius ):
-       'Get the inset vertex.'
-       pointIndex = getWideAnglePointIndex(loop)
-       point = loop[ pointIndex % len(loop) ]
-       afterPoint = loop[(pointIndex + 1) % len(loop)]
-       beforePoint = loop[ ( pointIndex - 1 ) % len(loop) ]
-       afterSegmentNormalized = euclidean.getNormalized( afterPoint - point )
-       beforeSegmentNormalized = euclidean.getNormalized( beforePoint - point )
-       afterClockwise = complex( afterSegmentNormalized.imag, - afterSegmentNormalized.real )
-       beforeWiddershins = complex( - beforeSegmentNormalized.imag, beforeSegmentNormalized.real )
-       midpoint = afterClockwise + beforeWiddershins
-       midpointNormalized = midpoint / abs( midpoint )
-       return point + midpointNormalized * tinyRadius
-
-def getIsPathEntirelyOutsideTriangle(begin, center, end, vector3Path):
-       'Determine if a path is entirely outside another loop.'
-       loop = [begin.dropAxis(), center.dropAxis(), end.dropAxis()]
-       for vector3 in vector3Path:
-               point = vector3.dropAxis()
-               if euclidean.isPointInsideLoop(loop, point):
-                       return False
-       return True
-
-def getIsPointCloseInline(close, loop, point, pointIndex):
-       'Insert a point into a loop, at the index at which the loop would be shortest.'
-       afterCenterComplex = loop[pointIndex]
-       if abs(afterCenterComplex - point) > close:
-               return False
-       afterEndComplex = loop[(pointIndex + 1) % len(loop)]
-       if not isInline( point, afterCenterComplex, afterEndComplex ):
-               return False
-       beforeCenterComplex = loop[(pointIndex + len(loop) - 1) % len(loop)]
-       if abs(beforeCenterComplex - point) > close:
-               return False
-       beforeEndComplex = loop[(pointIndex + len(loop) - 2) % len(loop)]
-       return isInline(point, beforeCenterComplex, beforeEndComplex)
-
-def getLoopsFromCorrectMesh( edges, faces, vertexes, z ):
-       'Get loops from a carve of a correct mesh.'
-       remainingEdgeTable = getRemainingEdgeTable(edges, vertexes, z)
-       remainingValues = remainingEdgeTable.values()
-       error = False
-       for edge in remainingValues:
-               if len( edge.faceIndexes ) < 2:
-                       if not hasattr(edge, 'errorReported'):
-                               print('Model error(hole): ' + str(vertexes[edge.vertexIndexes[0]]) + ' ' + str(vertexes[edge.vertexIndexes[1]]))
-                               edge.errorReported = True
-                       error = True
-       if error:
-               return []
-       loops = []
-       while isPathAdded( edges, faces, loops, remainingEdgeTable, vertexes, z ):
-               pass
-       
-       warning = False
-       for idx in xrange(0, len(loops)-1):
-               loop = loops[idx]
-               p0 = loop[-1]
-               for p1 in loop:
-                       if euclidean.isLineIntersectingLoops(loops[idx+1:], p0, p1):
-                               if not warning:
-                                       print('Warning, the triangle mesh slice intersects itself in getLoopsFromCorrectMesh in triangle_mesh.')
-                               print('Model error(intersect): (%f, %f, %f) (%f, %f, %f)' % (p0.real, p0.imag, z, p1.real, p1.imag, z))
-                               warning = True
-                       p0 = p1
-       if warning:
-               return []
-       return loops
-#      untouchables = []
-#      for boundingLoop in boundingLoops:
-#              if not boundingLoop.isIntersectingList( untouchables ):
-#                      untouchables.append( boundingLoop )
-#      if len( untouchables ) < len( boundingLoops ):
-#              print('This should never happen, the carve layer intersects itself. Something will still be printed, but there is no guarantee that it will be the correct shape.')
-#              print('Once the gcode is saved, you should check over the layer with a z of:')
-#              print(z)
-#      remainingLoops = []
-#      for untouchable in untouchables:
-#              remainingLoops.append( untouchable.loop )
-#      return remainingLoops
-
-def getLoopsFromUnprovenMesh(edges, faces, importRadius, vertexes, z):
-       'Get loops from a carve of an unproven mesh.'
-       edgePairTable = {}
-       corners = []
-       remainingEdgeTable = getRemainingEdgeTable(edges, vertexes, z)
-       remainingEdgeTableKeys = remainingEdgeTable.keys()
-       for remainingEdgeIndexKey in remainingEdgeTable:
-               edge = remainingEdgeTable[remainingEdgeIndexKey]
-               carveIntersection = getCarveIntersectionFromEdge(edge, vertexes, z)
-               corners.append(carveIntersection)
-               for edgeFaceIndex in edge.faceIndexes:
-                       face = faces[edgeFaceIndex]
-                       for edgeIndex in face.edgeIndexes:
-                               addEdgePair(edgePairTable, edges, edgeIndex, remainingEdgeIndexKey, remainingEdgeTable)
-       allPoints = corners[:]
-       for edgePairValue in edgePairTable.values():
-               addPointsAtZ(edgePairValue, allPoints, importRadius, vertexes, z)
-       pointTable = {}
-       return getDescendingAreaLoops(allPoints, corners, importRadius)
-
-def getLoopLayerAppend(loopLayers, layerCount, z):
-       'Get next z and add extruder loops.'
-       settings.printProgressByNumber(len(loopLayers), layerCount, 'slice')
-       loopLayer = euclidean.LoopLayer(z)
-       loopLayers.append(loopLayer)
-       return loopLayer
-
-def getLoopsWithCorners(corners, importRadius, loops, pointTable):
-       'Add corners to the loops.'
-       for corner in corners:
-               if corner not in pointTable:
-                       addWithLeastLength(importRadius, loops, corner)
-                       pointTable[corner] = None
-       return euclidean.getSimplifiedLoops(loops, importRadius)
-
-def getMeldedPillarOutput(loops):
-       'Get melded pillar output.'
-       faces = []
-       vertexes = getUniqueVertexes(loops)
-       addMeldedPillarByLoops(faces, loops)
-       return getGeometryOutputByFacesVertexes(faces, vertexes)
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return evaluate.EmptyObject(elementNode)
-
-def getNextEdgeIndexAroundZ(edge, faces, remainingEdgeTable):
-       'Get the next edge index in the mesh carve.'
-       for faceIndex in edge.faceIndexes:
-               face = faces[faceIndex]
-               for edgeIndex in face.edgeIndexes:
-                       if edgeIndex in remainingEdgeTable:
-                               return edgeIndex
-       return -1
-
-def getOrientedLoops(loops):
-       'Orient the loops which must be in descending order.'
-       for loopIndex, loop in enumerate(loops):
-               leftPoint = euclidean.getLeftPoint(loop)
-               isInFilledRegion = euclidean.getIsInFilledRegion(loops[: loopIndex] + loops[loopIndex + 1 :], leftPoint)
-               if isInFilledRegion == euclidean.isWiddershins(loop):
-                       loop.reverse()
-       return loops
-
-def getOverlapRatio( loop, pointTable ):
-       'Get the overlap ratio between the loop and the point table.'
-       numberOfOverlaps = 0
-       for point in loop:
-               if point in pointTable:
-                       numberOfOverlaps += 1
-       return float( numberOfOverlaps ) / float(len(loop))
-
-def getPath( edges, pathIndexes, loop, z ):
-       'Get the path from the edge intersections.'
-       path = []
-       for pathIndexIndex in xrange( len( pathIndexes ) ):
-               pathIndex = pathIndexes[ pathIndexIndex ]
-               edge = edges[ pathIndex ]
-               carveIntersection = getCarveIntersectionFromEdge( edge, loop, z )
-               path.append( carveIntersection )
-       return path
-
-def getPillarOutput(loops):
-       'Get pillar output.'
-       faces = []
-       vertexes = getUniqueVertexes(loops)
-       addPillarByLoops(faces, loops)
-       return getGeometryOutputByFacesVertexes(faces, vertexes)
-
-def getPillarsOutput(loopLists):
-       'Get pillars output.'
-       pillarsOutput = []
-       for loopList in loopLists:
-               pillarsOutput.append(getPillarOutput(loopList))
-       return getUnifiedOutput(pillarsOutput)
-
-def getRemainingEdgeTable(edges, vertexes, z):
-       'Get the remaining edge hashtable.'
-       remainingEdgeTable = {}
-       if len(edges) > 0:
-               if edges[0].zMinimum == None:
-                       for edge in edges:
-                               setEdgeMaximumMinimum(edge, vertexes)
-       for edgeIndex in xrange(len(edges)):
-               edge = edges[edgeIndex]
-               if (edge.zMinimum < z) and (edge.zMaximum > z):
-                       remainingEdgeTable[edgeIndex] = edge
-       return remainingEdgeTable
-
-def getRemainingLoopAddFace(faces, remainingLoop):
-       'Get the remaining loop and add face.'
-       for indexedVertexIndex, indexedVertex in enumerate(remainingLoop):
-               nextIndex = (indexedVertexIndex + 1) % len(remainingLoop)
-               previousIndex = (indexedVertexIndex + len(remainingLoop) - 1) % len(remainingLoop)
-               nextVertex = remainingLoop[nextIndex]
-               previousVertex = remainingLoop[previousIndex]
-               remainingPath = euclidean.getAroundLoop((indexedVertexIndex + 2) % len(remainingLoop), previousIndex, remainingLoop)
-               if len(remainingLoop) < 4 or getIsPathEntirelyOutsideTriangle(previousVertex, indexedVertex, nextVertex, remainingPath):
-                       faceConvex = face.Face()
-                       faceConvex.index = len(faces)
-                       faceConvex.vertexIndexes.append(indexedVertex.index)
-                       faceConvex.vertexIndexes.append(nextVertex.index)
-                       faceConvex.vertexIndexes.append(previousVertex.index)
-                       faces.append(faceConvex)
-                       return euclidean.getAroundLoop(nextIndex, indexedVertexIndex, remainingLoop)
-       print('Warning, could not decompose polygon in getRemainingLoopAddFace in trianglemesh for:')
-       print(remainingLoop)
-       return []
-
-def getSharedFace( firstEdge, faces, secondEdge ):
-       'Get the face which is shared by two edges.'
-       for firstEdgeFaceIndex in firstEdge.faceIndexes:
-               for secondEdgeFaceIndex in secondEdge.faceIndexes:
-                       if firstEdgeFaceIndex == secondEdgeFaceIndex:
-                               return faces[ firstEdgeFaceIndex ]
-       return None
-
-def getSymmetricXLoop(path, vertexes, x):
-       'Get symmetrix x loop.'
-       loop = []
-       for point in path:
-               vector3Index = Vector3Index(len(vertexes), x, point.real, point.imag)
-               loop.append(vector3Index)
-               vertexes.append(vector3Index)
-       return loop
-
-def getSymmetricYLoop(path, vertexes, y):
-       'Get symmetrix y loop.'
-       loop = []
-       for point in path:
-               vector3Index = Vector3Index(len(vertexes), point.real, y, point.imag)
-               loop.append(vector3Index)
-               vertexes.append(vector3Index)
-       return loop
-
-def getUnifiedOutput(outputs):
-       'Get unified output.'
-       if len(outputs) < 1:
-               return {}
-       if len(outputs) == 1:
-               return outputs[0]
-       return {'union' : {'shapes' : outputs}}
-
-def getUniqueVertexes(loops):
-       'Get unique vertexes.'
-       vertexDictionary = {}
-       uniqueVertexes = []
-       for loop in loops:
-               for vertexIndex, vertex in enumerate(loop):
-                       vertexTuple = (vertex.x, vertex.y, vertex.z)
-                       if vertexTuple in vertexDictionary:
-                               loop[vertexIndex] = vertexDictionary[vertexTuple]
-                       else:
-                               if vertex.__class__ == Vector3Index:
-                                       loop[vertexIndex].index = len(vertexDictionary)
-                               else:
-                                       loop[vertexIndex] = Vector3Index(len(vertexDictionary), vertex.x, vertex.y, vertex.z)
-                               vertexDictionary[vertexTuple] = loop[vertexIndex]
-                               uniqueVertexes.append(loop[vertexIndex])
-       return uniqueVertexes
-
-def getWideAnglePointIndex(loop):
-       'Get a point index which has a wide enough angle, most point indexes have a wide enough angle, this is just to make sure.'
-       dotProductMinimum = 9999999.9
-       widestPointIndex = 0
-       for pointIndex in xrange(len(loop)):
-               point = loop[ pointIndex % len(loop) ]
-               afterPoint = loop[(pointIndex + 1) % len(loop)]
-               beforePoint = loop[ ( pointIndex - 1 ) % len(loop) ]
-               afterSegmentNormalized = euclidean.getNormalized( afterPoint - point )
-               beforeSegmentNormalized = euclidean.getNormalized( beforePoint - point )
-               dotProduct = euclidean.getDotProduct( afterSegmentNormalized, beforeSegmentNormalized )
-               if dotProduct < .99:
-                       return pointIndex
-               if dotProduct < dotProductMinimum:
-                       dotProductMinimum = dotProduct
-                       widestPointIndex = pointIndex
-       return widestPointIndex
-
-def isInline( beginComplex, centerComplex, endComplex ):
-       'Determine if the three complex points form a line.'
-       centerBeginComplex = beginComplex - centerComplex
-       centerEndComplex = endComplex - centerComplex
-       centerBeginLength = abs( centerBeginComplex )
-       centerEndLength = abs( centerEndComplex )
-       if centerBeginLength <= 0.0 or centerEndLength <= 0.0:
-               return False
-       centerBeginComplex /= centerBeginLength
-       centerEndComplex /= centerEndLength
-       return euclidean.getDotProduct( centerBeginComplex, centerEndComplex ) < -0.999
-
-def isPathAdded( edges, faces, loops, remainingEdgeTable, vertexes, z ):
-       'Get the path indexes around a triangle mesh carve and add the path to the flat loops.'
-       if len( remainingEdgeTable ) < 1:
-               return False
-       pathIndexes = []
-       remainingEdgeIndexKey = remainingEdgeTable.keys()[0]
-       pathIndexes.append( remainingEdgeIndexKey )
-       del remainingEdgeTable[remainingEdgeIndexKey]
-       nextEdgeIndexAroundZ = getNextEdgeIndexAroundZ( edges[remainingEdgeIndexKey], faces, remainingEdgeTable )
-       while nextEdgeIndexAroundZ != - 1:
-               pathIndexes.append( nextEdgeIndexAroundZ )
-               del remainingEdgeTable[ nextEdgeIndexAroundZ ]
-               nextEdgeIndexAroundZ = getNextEdgeIndexAroundZ( edges[ nextEdgeIndexAroundZ ], faces, remainingEdgeTable )
-       if len( pathIndexes ) < 3:
-               print('Dangling edges, will use intersecting circles to get import layer at height %s' % z)
-               for idx in pathIndexes:
-                       if not hasattr(edges[idx], 'errorReported'):
-                               print('Model error(dangle): ' + str(vertexes[edges[idx].vertexIndexes[0]]) + ' ' + str(vertexes[edges[idx].vertexIndexes[1]]))
-                               edges[idx].errorReported = True
-               del loops[:]
-               return False
-       loops.append( getPath( edges, pathIndexes, vertexes, z ) )
-       return True
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       evaluate.processArchivable(TriangleMesh, elementNode)
-
-def setEdgeMaximumMinimum(edge, vertexes):
-       'Set the edge maximum and minimum.'
-       beginIndex = edge.vertexIndexes[0]
-       endIndex = edge.vertexIndexes[1]
-       if beginIndex >= len(vertexes) or endIndex >= len(vertexes):
-               print('Warning, there are duplicate vertexes in setEdgeMaximumMinimum in triangle_mesh.')
-               print('Something might still be printed, but there is no guarantee that it will be the correct shape.' )
-               edge.zMaximum = -987654321.0
-               edge.zMinimum = -987654321.0
-               return
-       beginZ = vertexes[beginIndex].z
-       endZ = vertexes[endIndex].z
-       edge.zMinimum = min(beginZ, endZ)
-       edge.zMaximum = max(beginZ, endZ)
-
-def sortLoopsInOrderOfArea(isDescending, loops):
-       'Sort the loops in the order of area according isDescending.'
-       loops.sort(key=euclidean.getAreaLoopAbsolute, reverse=isDescending)
-
-
-class EdgePair(object):
-       def __init__(self):
-               'Pair of edges on a face.'
-               self.edgeIndexes = []
-               self.edges = []
-
-       def __repr__(self):
-               'Get the string representation of this EdgePair.'
-               return str( self.edgeIndexes )
-
-       def getFromIndexesEdges( self, edgeIndexes, edges ):
-               'Initialize from edge indices.'
-               self.edgeIndexes = edgeIndexes[:]
-               self.edgeIndexes.sort()
-               for edgeIndex in self.edgeIndexes:
-                       self.edges.append( edges[ edgeIndex ] )
-               return self
-
-
-class FaceGenerator(object):
-       'A face generator.'
-       def __init__(self, faces, indexedLoopBottom, indexedLoopTop):
-               'Initialize.'
-               self.startTop = 0
-               if len(indexedLoopBottom) == 0 or len(indexedLoopTop) == 0:
-                       return
-               smallestDistance = 987654321987654321.0
-               for pointIndex, point in enumerate(indexedLoopBottom):
-                       distanceIndex = getClosestDistanceIndexToPoint(point, indexedLoopTop)
-                       if distanceIndex.distance < smallestDistance:
-                               smallestDistance = distanceIndex.distance
-                               offsetBottom = pointIndex
-                               offsetTop = distanceIndex.index
-               self.indexedLoopBottom = indexedLoopBottom[offsetBottom :] + indexedLoopBottom[: offsetBottom]
-               self.indexedLoopTop = indexedLoopTop[offsetTop :] + indexedLoopTop[: offsetTop]
-               for bottomIndex in xrange(len(self.indexedLoopBottom)):
-                       self.addFacesByBottomIndex(bottomIndex, faces)
-               subsetTop = self.indexedLoopTop[self.startTop :]
-               subsetTop.append(self.indexedLoopTop[0])
-               addFacesByConvexBottomTopLoop(faces, [self.indexedLoopBottom[0]], subsetTop[: : -1])
-
-       def addFacesByBottomIndex(self, bottomIndex, faces):
-               'Add faces from the  bottom index to the next index.'
-               bottomPoint = self.indexedLoopBottom[bottomIndex % len(self.indexedLoopBottom)]
-               bottomPointNext = self.indexedLoopBottom[(bottomIndex + 1) % len(self.indexedLoopBottom)]
-               topIndex = self.startTop + getClosestDistanceIndexToPoint(bottomPointNext, self.indexedLoopTop[self.startTop :]).index
-               topIndexPlusOne = topIndex + 1
-               betweenIndex = self.getBetweenIndex(bottomPoint, bottomPointNext, topIndexPlusOne)
-               betweenIndexPlusOne = betweenIndex + 1
-               subsetStart = self.indexedLoopTop[self.startTop : betweenIndexPlusOne]
-               subsetEnd = self.indexedLoopTop[betweenIndex : topIndexPlusOne]
-               addFacesByConvexBottomTopLoop(faces, [bottomPoint], subsetStart[: : -1])
-               addFacesByConvexBottomTopLoop(faces, [bottomPoint, bottomPointNext], [self.indexedLoopTop[betweenIndex]])
-               addFacesByConvexBottomTopLoop(faces, [bottomPointNext], subsetEnd[: : -1])
-               self.startTop = topIndex
-
-       def getBetweenIndex(self, bottomPoint, bottomPointNext, topIndexPlusOne):
-               'Get the index of the last point along the loop which is closer to the bottomPoint.'
-               betweenIndex = self.startTop
-               bottomPointComplex = bottomPoint.dropAxis()
-               bottomPointNextComplex = bottomPointNext.dropAxis()
-               for topPointIndex in xrange(self.startTop, topIndexPlusOne):
-                       topPointComplex = self.indexedLoopTop[topPointIndex].dropAxis()
-                       if abs(topPointComplex - bottomPointComplex) > abs(topPointComplex - bottomPointNextComplex):
-                               return betweenIndex
-                       betweenIndex = topPointIndex
-               return betweenIndex
-
-
-class TriangleMesh( group.Group ):
-       'A triangle mesh.'
-       def __init__(self):
-               'Add empty lists.'
-               group.Group.__init__(self)
-               self.belowLoops = []
-               self.edges = []
-               self.faces = []
-               self.importCoarseness = 1.0
-               self.isCorrectMesh = True
-               self.loopLayers = []
-               self.oldChainTetragrid = None
-               self.transformedVertexes = None
-               self.vertexes = []
-
-       def addXMLSection(self, depth, output):
-               'Add the xml section for this object.'
-               xml_simple_writer.addXMLFromVertexes( depth, output, self.vertexes )
-               xml_simple_writer.addXMLFromObjects( depth, self.faces, output )
-
-       def getCarveBoundaryLayers(self):
-               'Get the boundary layers.'
-               if self.getMinimumZ() == None:
-                       return []
-               halfHeight = 0.5 * self.layerHeight
-               self.zoneArrangement = ZoneArrangement(self.layerHeight, self.getTransformedVertexes())
-               layerTop = self.cornerMaximum.z - halfHeight * 0.5
-               z = halfHeight
-               layerCount = int((layerTop - z) / self.layerHeight) + 1
-               while z < layerTop:
-                       getLoopLayerAppend(self.loopLayers, layerCount, z).loops = self.getLoopsFromMesh(self.zoneArrangement.getEmptyZ(z))
-                       z += self.layerHeight
-               return self.loopLayers
-
-       def getCarveCornerMaximum(self):
-               'Get the corner maximum of the vertexes.'
-               return self.cornerMaximum
-
-       def getCarveCornerMinimum(self):
-               'Get the corner minimum of the vertexes.'
-               return self.cornerMinimum
-
-       def getCarveLayerHeight(self):
-               'Get the layer height.'
-               return self.layerHeight
-
-       def getFabmetheusXML(self):
-               'Return the fabmetheus XML.'
-               return None
-
-       def getGeometryOutput(self):
-               'Get geometry output dictionary.'
-               return getGeometryOutputByFacesVertexes(self.faces, self.vertexes)
-
-       def getInterpretationSuffix(self):
-               'Return the suffix for a triangle mesh.'
-               return 'xml'
-
-       def getLoops(self, importRadius, z):
-               'Get loops sliced through shape.'
-               self.importRadius = importRadius
-               return self.getLoopsFromMesh(z)
-
-       def getLoopsFromMesh( self, z ):
-               'Get loops from a carve of a mesh.'
-               originalLoops = []
-               self.setEdgesForAllFaces()
-               if self.isCorrectMesh:
-                       originalLoops = getLoopsFromCorrectMesh( self.edges, self.faces, self.getTransformedVertexes(), z )
-               if len( originalLoops ) < 1:
-                       originalLoops = getLoopsFromUnprovenMesh( self.edges, self.faces, self.importRadius, self.getTransformedVertexes(), z )
-               loops = euclidean.getSimplifiedLoops(originalLoops, self.importRadius)
-               sortLoopsInOrderOfArea(True, loops)
-               return getOrientedLoops(loops)
-
-       def getMinimumZ(self):
-               'Get the minimum z.'
-               self.cornerMaximum = Vector3(-987654321.0, -987654321.0, -987654321.0)
-               self.cornerMinimum = Vector3(987654321.0, 987654321.0, 987654321.0)
-               transformedVertexes = self.getTransformedVertexes()
-               if len(transformedVertexes) < 1:
-                       return None
-               for point in transformedVertexes:
-                       self.cornerMaximum.maximize(point)
-                       self.cornerMinimum.minimize(point)
-               return self.cornerMinimum.z
-
-       def getTransformedVertexes(self):
-               'Get all transformed vertexes.'
-               if self.elementNode == None:
-                       return self.vertexes
-               chainTetragrid = self.getMatrixChainTetragrid()
-               if self.oldChainTetragrid != chainTetragrid:
-                       self.oldChainTetragrid = matrix.getTetragridCopy(chainTetragrid)
-                       self.transformedVertexes = None
-               if self.transformedVertexes == None:
-                       if len(self.edges) > 0:
-                               self.edges[0].zMinimum = None
-                       self.transformedVertexes = matrix.getTransformedVector3s(chainTetragrid, self.vertexes)
-               return self.transformedVertexes
-
-       def getTriangleMeshes(self):
-               'Get all triangleMeshes.'
-               return [self]
-
-       def getVertexes(self):
-               'Get all vertexes.'
-               self.transformedVertexes = None
-               return self.vertexes
-
-       def setCarveImportRadius( self, importRadius ):
-               'Set the import radius.'
-               self.importRadius = importRadius
-
-       def setCarveIsCorrectMesh( self, isCorrectMesh ):
-               'Set the is correct mesh flag.'
-               self.isCorrectMesh = isCorrectMesh
-
-       def setCarveLayerHeight( self, layerHeight ):
-               'Set the layer height.'
-               self.layerHeight = layerHeight
-
-       def setEdgesForAllFaces(self):
-               'Set the face edges of all the faces.'
-               edgeTable = {}
-               for face in self.faces:
-                       face.setEdgeIndexesToVertexIndexes( self.edges, edgeTable )
-
-
-class ZoneArrangement(object):
-       'A zone arrangement.'
-       def __init__(self, layerHeight, vertexes):
-               'Initialize the zone interval and the zZone table.'
-               self.zoneInterval = layerHeight / math.sqrt(len(vertexes)) / 1000.0
-               self.zZoneSet = set()
-               for point in vertexes:
-                       zoneIndexFloat = point.z / self.zoneInterval
-                       self.zZoneSet.add(math.floor(zoneIndexFloat))
-                       self.zZoneSet.add(math.ceil(zoneIndexFloat ))
-
-       def getEmptyZ(self, z):
-               'Get the first z which is not in the zone table.'
-               zoneIndex = round(z / self.zoneInterval)
-               if zoneIndex not in self.zZoneSet:
-                       return z
-               zoneAround = 1
-               while 1:
-                       zoneDown = zoneIndex - zoneAround
-                       if zoneDown not in self.zZoneSet:
-                               return zoneDown * self.zoneInterval
-                       zoneUp = zoneIndex + zoneAround
-                       if zoneUp not in self.zZoneSet:
-                               return zoneUp * self.zoneInterval
-                       zoneAround += 1
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/union.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/solids/union.py
deleted file mode 100644 (file)
index 2c2a954..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-"""
-Boolean geometry union of solids.
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.solids import difference
-from fabmetheus_utilities.geometry.solids import group
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def convertElementNode(elementNode, geometryOutput):
-       'Convert the xml element to a union xml element.'
-       group.convertContainerElementNode(elementNode, geometryOutput, Union())
-
-def getNewDerivation(elementNode):
-       'Get new derivation.'
-       return evaluate.EmptyObject(elementNode)
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       evaluate.processArchivable(Union, elementNode)
-
-
-class Union(difference.Difference):
-       'A difference object.'
-       def getLoopsFromObjectLoopsList(self, importRadius, visibleObjectLoopsList):
-               'Get loops from visible object loops list.'
-               return self.getUnion(importRadius, visibleObjectLoopsList)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/_print.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/_print.py
deleted file mode 100644 (file)
index 6f7171a..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-"""
-Print statement.
-
-There is also the print attribute in geometry_utilities/evaluate_fundamentals/print.py
-
-The model is xml_models/geometry_utilities/evaluate_fundamentals/print.xml
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getLocalDictionary( attributesKey, elementNode):
-       "Get the local dictionary."
-       xmlProcessor = elementNode.getXMLProcessor()
-       if len( xmlProcessor.functions ) < 1:
-               return None
-       return xmlProcessor.functions[-1].localDictionary
-
-def printAttributesKey( attributesKey, elementNode):
-       "Print the attributesKey."
-       if attributesKey.lower() == '_localdictionary':
-               localDictionary = getLocalDictionary( attributesKey, elementNode)
-               if localDictionary != None:
-                       localDictionaryKeys = localDictionary.keys()
-                       attributeValue = elementNode.attributes[attributesKey]
-                       if attributeValue != '':
-                               attributeValue = ' - ' + attributeValue
-                       print('Local Dictionary Variables' + attributeValue )
-                       localDictionaryKeys.sort()
-                       for localDictionaryKey in localDictionaryKeys:
-                               print('%s: %s' % ( localDictionaryKey, localDictionary[ localDictionaryKey ] ) )
-                       return
-       value = elementNode.attributes[attributesKey]
-       evaluatedValue = None
-       if value == '':
-               evaluatedValue = evaluate.getEvaluatedExpressionValue(elementNode, attributesKey)
-       else:
-               evaluatedValue = evaluate.getEvaluatedExpressionValue(elementNode, value)
-       print('%s: %s' % ( attributesKey, evaluatedValue ) )
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       if len(elementNode.getTextContent()) > 1:
-               print(elementNode.getTextContent())
-               return
-       attributesKeys = elementNode.attributes.keys()
-       if len( attributesKeys ) < 1:
-               print('')
-               return
-       attributesKeys.sort()
-       for attributesKey in attributesKeys:
-               printAttributesKey( attributesKey, elementNode)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/class.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/class.py
deleted file mode 100644 (file)
index a696481..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-"""
-Class.
-
-"""
-
-from __future__ import absolute_import
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def processElementNode(elementNode):
-       'Process the xml element.'
-       pass
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/elif.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/elif.py
deleted file mode 100644 (file)
index f45e789..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-"""
-Polygon path.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       pass
-
-def processElse(elementNode):
-       "Process the else statement."
-       evaluate.processCondition(elementNode)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/else.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/else.py
deleted file mode 100644 (file)
index f8a7d24..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-"""
-Polygon path.
-
-"""
-
-from __future__ import absolute_import
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       pass
-
-def processElse(elementNode):
-       "Process the else statement."
-       functions = elementNode.getXMLProcessor().functions
-       if len(functions) < 1:
-               print('Warning, "else" element is not in a function in processElse in else.py for:')
-               print(elementNode)
-               return
-       functions[-1].processChildNodes(elementNode)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/for.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/for.py
deleted file mode 100644 (file)
index 88d345c..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-"""
-Polygon path.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def processChildNodesByIndexValue( elementNode, function, index, indexValue, value ):
-       "Process childNodes by index value."
-       if indexValue.indexName != '':
-               function.localDictionary[ indexValue.indexName ] = index
-       if indexValue.valueName != '':
-               function.localDictionary[ indexValue.valueName ] = value
-       function.processChildNodes(elementNode)
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       if elementNode.xmlObject == None:
-               elementNode.xmlObject = IndexValue(elementNode)
-       if elementNode.xmlObject.inSplitWords == None:
-               return
-       xmlProcessor = elementNode.getXMLProcessor()
-       if len( xmlProcessor.functions ) < 1:
-               print('Warning, "for" element is not in a function in processElementNode in for.py for:')
-               print(elementNode)
-               return
-       function = xmlProcessor.functions[-1]
-       inValue = evaluate.getEvaluatedExpressionValueBySplitLine(elementNode, elementNode.xmlObject.inSplitWords)
-       if inValue.__class__ == list or inValue.__class__ == str:
-               for index, value in enumerate( inValue ):
-                       processChildNodesByIndexValue( elementNode, function, index, elementNode.xmlObject, value )
-               return
-       if inValue.__class__ == dict:
-               inKeys = inValue.keys()
-               inKeys.sort()
-               for inKey in inKeys:
-                       processChildNodesByIndexValue( elementNode, function, inKey, elementNode.xmlObject, inValue[ inKey ] )
-
-
-class IndexValue(object):
-       "Class to get the in attribute, the index name and the value name."
-       def __init__(self, elementNode):
-               "Initialize."
-               self.inSplitWords = None
-               self.indexName = ''
-               if 'index' in elementNode.attributes:
-                       self.indexName = elementNode.attributes['index']
-               self.valueName = ''
-               if 'value' in elementNode.attributes:
-                       self.valueName = elementNode.attributes['value']
-               if 'in' in elementNode.attributes:
-                       self.inSplitWords = evaluate.getEvaluatorSplitWords( elementNode.attributes['in'] )
-               else:
-                       print('Warning, could not find the "in" attribute in IndexValue in for.py for:')
-                       print(elementNode)
-                       return
-               if len( self.inSplitWords ) < 1:
-                       self.inSplitWords = None
-                       print('Warning, could not get split words for the "in" attribute in IndexValue in for.py for:')
-                       print(elementNode)
-
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/function.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/function.py
deleted file mode 100644 (file)
index 9ed32e3..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-"""
-Polygon path.
-
-"""
-
-from __future__ import absolute_import
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       pass
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/if.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/if.py
deleted file mode 100644 (file)
index 883bc70..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-"""
-Polygon path.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       evaluate.processCondition(elementNode)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/return.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/return.py
deleted file mode 100644 (file)
index 50488e8..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-"""
-Polygon path.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       functions = elementNode.getXMLProcessor().functions
-       if len(functions) < 1:
-               return
-       function = functions[-1]
-       function.shouldReturn = True
-       if elementNode.xmlObject == None:
-               if 'return' in elementNode.attributes:
-                       value = elementNode.attributes['return']
-                       elementNode.xmlObject = evaluate.getEvaluatorSplitWords(value)
-               else:
-                       elementNode.xmlObject = []
-       if len( elementNode.xmlObject ) > 0:
-               function.returnValue = evaluate.getEvaluatedExpressionValueBySplitLine(elementNode, elementNode.xmlObject)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/statement.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/statement.py
deleted file mode 100644 (file)
index 8db9c87..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-"""
-Polygon path.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       functions = elementNode.getXMLProcessor().functions
-       if len(functions) < 1:
-               print('Warning, there are no functions in processElementNode in statement for:')
-               print(elementNode)
-               return
-       function = functions[-1]
-       evaluate.setLocalAttribute(elementNode)
-       if elementNode.xmlObject.value == None:
-               print('Warning, elementNode.xmlObject.value is None in processElementNode in statement for:')
-               print(elementNode)
-               return
-       localValue = evaluate.getEvaluatedExpressionValueBySplitLine(elementNode, elementNode.xmlObject.value)
-       keywords = elementNode.xmlObject.key.split('.')
-       if len(keywords) == 0:
-               print('Warning, there are no keywords in processElementNode in statement for:')
-               print(elementNode)
-               return
-       firstWord = keywords[0]
-       if len(keywords) == 1:
-               function.localDictionary[firstWord] = localValue
-               return
-       attributeName = keywords[-1]
-       object = None
-       if firstWord == 'self':
-               object = function.classObject
-       else:
-               object = function.localDictionary[firstWord]
-       for keywordIndex in xrange(1, len(keywords) - 1):
-               object = object._getAccessibleAttribute(keywords[keywordIndex])
-       object._setAccessibleAttribute(attributeName, localValue)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/while.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry/statements/while.py
deleted file mode 100644 (file)
index 871e58c..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-"""
-Polygon path.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def processElementNode(elementNode):
-       "Process the xml element."
-       if elementNode.xmlObject == None:
-               if 'condition' in elementNode.attributes:
-                       value = elementNode.attributes['condition']
-                       elementNode.xmlObject = evaluate.getEvaluatorSplitWords(value)
-               else:
-                       elementNode.xmlObject = []
-       if len( elementNode.xmlObject ) < 1:
-               return
-       xmlProcessor = elementNode.getXMLProcessor()
-       if len( xmlProcessor.functions ) < 1:
-               return
-       function = xmlProcessor.functions[-1]
-       while evaluate.getEvaluatedExpressionValueBySplitLine(elementNode, elementNode.xmlObject) > 0:
-               function.processChildNodes(elementNode)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry_plugins/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry_plugins/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry_plugins/creation/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry_plugins/creation/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry_plugins/manipulation_matrix/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry_plugins/manipulation_matrix/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry_plugins/manipulation_meta/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry_plugins/manipulation_meta/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry_plugins/manipulation_paths/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry_plugins/manipulation_paths/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/geometry_plugins/manipulation_shapes/__init__.py b/Cura/slice/cura_sf/fabmetheus_utilities/geometry_plugins/manipulation_shapes/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/intercircle.py b/Cura/slice/cura_sf/fabmetheus_utilities/intercircle.py
deleted file mode 100644 (file)
index 132acc2..0000000
+++ /dev/null
@@ -1,718 +0,0 @@
-"""
-Intercircle is a collection of utilities for intersecting circles, used to get smooth loops around a collection of points and inset & outset loops.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import euclidean
-import math
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalDecreasingRadiusMultipliers = [1.0, 0.55, 0.35, 0.2]
-globalIntercircleMultiplier = 1.04 # 1.02 is enough to stop known intersection
-
-
-def addCircleIntersectionLoop(circleIntersectionLoop, circleIntersections):
-       'Add a circle intersection loop.'
-       firstCircleIntersection = circleIntersectionLoop[0]
-       circleIntersectionAhead = firstCircleIntersection
-       for circleIntersectionIndex in xrange(len(circleIntersections) + 1):
-               circleIntersectionAhead = circleIntersectionAhead.getCircleIntersectionAhead()
-               if circleIntersectionAhead == firstCircleIntersection or circleIntersectionAhead == None:
-                       firstCircleIntersection.steppedOn = True
-                       return
-               circleIntersectionAhead.addToList(circleIntersectionLoop)
-       firstCircleIntersection.steppedOn = True
-       print('Warning, addCircleIntersectionLoop would have gone into an endless loop.')
-       print('circleIntersectionLoop')
-       for circleIntersection in circleIntersectionLoop:
-               print(circleIntersection)
-               print(circleIntersection.circleNodeAhead)
-               print(circleIntersection.circleNodeBehind)
-       print('firstCircleIntersection')
-       print(firstCircleIntersection)
-       print('circleIntersections')
-       for circleIntersection in circleIntersections:
-               print(circleIntersection)
-
-def addEndCap(begin, end, points, radius):
-       'Get circular end cap.'
-       beginMinusEnd = begin - end
-       beginMinusEndLength = abs(beginMinusEnd)
-       if beginMinusEndLength <= 0.0:
-               points.append(begin)
-               return
-       beginMinusEnd *= radius / beginMinusEndLength
-       perpendicular = complex(-beginMinusEnd.imag, beginMinusEnd.real)
-       numberOfSides = 20 # to end up with close to unit length corners, 5 * 4
-       numberOfPositiveSides = numberOfSides / 2
-       totalAngle = 0.0
-       angle = euclidean.globalTau / float(numberOfSides)
-       # dotProductMultiplier to compensate for the corner outset in addInsetPointFromClockwiseTriple
-       dotProductMultiplier = 2.0 - 1.0 / math.cos(0.5 * angle)
-       for sideIndex in xrange(numberOfPositiveSides + 1):
-               circumferentialPoint = math.sin(totalAngle) * beginMinusEnd + math.cos(totalAngle) * perpendicular
-               points.append(begin + circumferentialPoint * dotProductMultiplier)
-               totalAngle += angle
-
-def addHalfPath(path, points, radius, thresholdRatio=0.9):
-       'Add the points from every point on a half path and between points.'
-       lessThanRadius = 0.75 * radius
-       for pointIndex in xrange(len(path) - 1):
-               begin = path[pointIndex]
-               center = path[pointIndex + 1]
-               centerBegin = getWiddershinsByLength(begin, center, radius)
-               if centerBegin != None:
-                       addPointsFromSegment(begin + centerBegin, center + centerBegin, points, lessThanRadius, thresholdRatio)
-               endIndex = pointIndex + 2
-               if endIndex < len(path):
-                       end = path[endIndex]
-                       centerEnd = getWiddershinsByLength(center, end, radius)
-                       if centerBegin != None and centerEnd != None:
-                               centerPerpendicular = 0.5 * (centerBegin + centerEnd)
-                               points.append(center + centerPerpendicular)
-                               if euclidean.getCrossProduct(centerBegin, centerEnd) < 0.0:
-                                       points.append(center + centerBegin)
-                                       points.append(center + centerEnd)
-                       else:
-                               points.append(center)
-       addEndCap(path[0], path[1], points, radius)
-
-def addInsetPointFromClockwiseTriple(begin, center, end, loop, radius):
-       'Get inset point with possible intersection from clockwise triple, out from widdershins loop.'
-       centerMinusBegin = center - begin
-       centerMinusBeginLength = abs(centerMinusBegin)
-       centerMinusBeginClockwise = None
-       if centerMinusBeginLength > 0.0:
-               centerMinusBeginClockwise = complex(centerMinusBegin.imag, -centerMinusBegin.real) / centerMinusBeginLength
-       endMinusCenter = end - center
-       endMinusCenterLength = abs(endMinusCenter)
-       endMinusCenterClockwise = None
-       if endMinusCenterLength > 0.0:
-               endMinusCenterClockwise = complex(endMinusCenter.imag, -endMinusCenter.real) / endMinusCenterLength
-       if centerMinusBeginClockwise == None and endMinusCenterClockwise == None:
-               return
-       if centerMinusBeginClockwise == None:
-               loop.append(center + endMinusCenterClockwise * radius)
-               return
-       if endMinusCenterClockwise == None:
-               loop.append(center + centerMinusBeginClockwise * radius)
-               return
-       centerClockwise = 0.5 * (centerMinusBeginClockwise + endMinusCenterClockwise)
-       dotProduct = euclidean.getDotProduct(centerMinusBeginClockwise, centerClockwise)
-       loop.append(center + centerClockwise * radius / max(0.4, abs(dotProduct))) # 0.4 to avoid pointy corners
-
-def addOrbits( distanceFeedRate, loop, orbitalFeedRatePerSecond, temperatureChangeTime, z ):
-       'Add orbits with the extruder off.'
-       timeInOrbit = 0.0
-       while timeInOrbit < temperatureChangeTime:
-               for point in loop:
-                       distanceFeedRate.addGcodeMovementZWithFeedRate( 60.0 * orbitalFeedRatePerSecond, point, z )
-               timeInOrbit += euclidean.getLoopLength(loop) / orbitalFeedRatePerSecond
-
-def addOrbitsIfLarge( distanceFeedRate, loop, orbitalFeedRatePerSecond, temperatureChangeTime, z ):
-       'Add orbits with the extruder off if the orbits are large enough.'
-       if orbitsAreLarge( loop, temperatureChangeTime ):
-               addOrbits( distanceFeedRate, loop, orbitalFeedRatePerSecond, temperatureChangeTime, z )
-
-def addPointsFromSegment( pointBegin, pointEnd, points, radius, thresholdRatio=0.9 ):
-       'Add point complexes between the endpoints of a segment.'
-       if radius <= 0.0:
-               print('This should never happen, radius should never be zero or less in addPointsFromSegment in intercircle.')
-       thresholdRadius = radius * thresholdRatio # a higher number would be faster but would leave bigger dangling loops and extra dangling loops.
-       thresholdDiameter = thresholdRadius + thresholdRadius
-       segment = pointEnd - pointBegin
-       segmentLength = abs(segment)
-       extraCircles = int( math.floor( segmentLength / thresholdDiameter ) )
-       if extraCircles < 1:
-               return
-       if segmentLength == 0.0:
-               print('Warning, segmentLength = 0.0 in intercircle.')
-               print('pointBegin')
-               print(pointBegin)
-               print(pointEnd)
-               return
-       if extraCircles < 2:
-               lengthIncrement = segmentLength / ( float(extraCircles) + 1.0 )
-               segment *= lengthIncrement / segmentLength
-               pointBegin += segment
-       else:
-               pointBegin += segment * thresholdDiameter / segmentLength
-               remainingLength = segmentLength - thresholdDiameter - thresholdDiameter
-               lengthIncrement = remainingLength / ( float(extraCircles) - 1.0 )
-               segment *= lengthIncrement / segmentLength
-       for circleIndex in xrange(extraCircles):
-               points.append( pointBegin )
-               pointBegin += segment
-
-def directLoop(isWiddershins, loop):
-       'Direct the loop.'
-       if euclidean.isWiddershins(loop) != isWiddershins:
-               loop.reverse()
-
-def directLoopLists(isWiddershins, loopLists):
-       'Direct the loop lists.'
-       for loopList in loopLists:
-               directLoops(isWiddershins, loopList)
-
-def directLoops(isWiddershins, loops):
-       'Direct the loops.'
-       for loop in loops:
-               directLoop(isWiddershins, loop)
-
-def getAroundsFromLoop(loop, radius, thresholdRatio=0.9):
-       'Get the arounds from the loop.'
-       return getAroundsFromPoints(getPointsFromLoop(loop, radius, thresholdRatio), radius)
-
-def getAroundsFromLoops( loops, radius, thresholdRatio=0.9 ):
-       'Get the arounds from the loops.'
-       return getAroundsFromPoints(getPointsFromLoops(loops, radius, thresholdRatio), radius)
-
-def getAroundsFromPath(path, radius, thresholdRatio=0.9):
-       'Get the arounds from the path.'
-       radius = abs(radius)
-       points = getPointsFromPath(path, radius, thresholdRatio)
-       return getAroundsFromPathPoints(points, radius, thresholdRatio=0.9)
-
-def getAroundsFromPathPoints(points, radius, thresholdRatio=0.9):
-       'Get the arounds from the path.'
-       centers = getCentersFromPoints(points, 0.8 * radius)
-       arounds = []
-       for center in centers:
-               if euclidean.isWiddershins(center):
-                       arounds.append(euclidean.getSimplifiedPath(center, radius))
-       return arounds
-
-def getAroundsFromPaths(paths, radius, thresholdRatio=0.9):
-       'Get the arounds from the path.'
-       radius = abs(radius)
-       points = []
-       for path in paths:
-               points += getPointsFromPath(path, radius, thresholdRatio)
-       return getAroundsFromPathPoints(points, radius, thresholdRatio=0.9)
-
-def getAroundsFromPoints( points, radius ):
-       'Get the arounds from the points.'
-       arounds = []
-       radius = abs(radius)
-       centers = getCentersFromPoints(points, globalIntercircleMultiplier * radius)
-       for center in centers:
-               inset = getSimplifiedInsetFromClockwiseLoop(center, radius)
-               if isLargeSameDirection(inset, center, radius):
-                       arounds.append(inset)
-       return arounds
-
-def getCentersFromCircleNodes( circleNodes, radius ):
-       'Get the complex centers of the circle intersection loops from circle nodes.'
-       if len( circleNodes ) < 2:
-               return []
-       circleIntersections = getCircleIntersectionsFromCircleNodes( circleNodes )
-       circleIntersectionLoops = getCircleIntersectionLoops( circleIntersections )
-       return getCentersFromIntersectionLoops( circleIntersectionLoops, radius )
-
-def getCentersFromIntersectionLoop(circleIntersectionLoop, radius):
-       'Get the centers from the intersection loop.'
-       loop = []
-       for circleIntersection in circleIntersectionLoop:
-               loop.append(circleIntersection.circleNodeAhead.actualPoint)
-       return loop
-
-def getCentersFromIntersectionLoops( circleIntersectionLoops, radius ):
-       'Get the centers from the intersection loops.'
-       centers = []
-       for circleIntersectionLoop in circleIntersectionLoops:
-               centers.append( getCentersFromIntersectionLoop( circleIntersectionLoop, radius ) )
-       return centers
-
-def getCentersFromLoop( loop, radius ):
-       'Get the centers of the loop.'
-       circleNodes = getCircleNodesFromLoop( loop, radius )
-       return getCentersFromCircleNodes( circleNodes, radius )
-
-def getCentersFromLoopDirection( isWiddershins, loop, radius ):
-       'Get the centers of the loop which go around in the given direction.'
-       centers = getCentersFromLoop( loop, radius )
-       return getLoopsFromLoopsDirection( isWiddershins, centers )
-
-def getCentersFromPoints(points, radius):
-       'Get the centers from the points.'
-       circleNodes = getCircleNodesFromPoints(points, abs(radius))
-       return getCentersFromCircleNodes(circleNodes, abs(radius))
-
-def getCircleIntersectionLoops( circleIntersections ):
-       'Get all the loops going through the circle intersections.'
-       circleIntersectionLoops = []
-       for circleIntersection in circleIntersections:
-               if not circleIntersection.steppedOn:
-                       circleIntersectionLoop = [ circleIntersection ]
-                       circleIntersectionLoops.append( circleIntersectionLoop )
-                       addCircleIntersectionLoop( circleIntersectionLoop, circleIntersections )
-       return circleIntersectionLoops
-
-def getCircleIntersectionsFromCircleNodes(circleNodes):
-       'Get all the circle intersections which exist between all the circle nodes.'
-       if len( circleNodes ) < 1:
-               return []
-       circleIntersections = []
-       index = 0
-       pixelTable = {}
-       for circleNode in circleNodes:
-               euclidean.addElementToPixelListFromPoint(circleNode, pixelTable, circleNode.dividedPoint)
-       accumulatedCircleNodeTable = {}
-       for circleNodeIndex in xrange(len(circleNodes)):
-               circleNodeBehind = circleNodes[circleNodeIndex]
-               circleNodeIndexMinusOne = circleNodeIndex - 1
-               if circleNodeIndexMinusOne >= 0:
-                       circleNodeAdditional = circleNodes[circleNodeIndexMinusOne]
-                       euclidean.addElementToPixelListFromPoint(circleNodeAdditional, accumulatedCircleNodeTable, 0.5 * circleNodeAdditional.dividedPoint)
-               withinNodes = circleNodeBehind.getWithinNodes(accumulatedCircleNodeTable)
-               for circleNodeAhead in withinNodes:
-                       circleIntersectionForward = CircleIntersection(circleNodeAhead, index, circleNodeBehind)
-                       if not circleIntersectionForward.isWithinCircles(pixelTable):
-                               circleIntersections.append(circleIntersectionForward)
-                               circleNodeBehind.circleIntersections.append(circleIntersectionForward)
-                               index += 1
-                       circleIntersectionBackward = CircleIntersection(circleNodeBehind, index, circleNodeAhead)
-                       if not circleIntersectionBackward.isWithinCircles(pixelTable):
-                               circleIntersections.append(circleIntersectionBackward)
-                               circleNodeAhead.circleIntersections.append(circleIntersectionBackward)
-                               index += 1
-       return circleIntersections
-
-def getCircleNodesFromLoop(loop, radius, thresholdRatio=0.9):
-       'Get the circle nodes from every point on a loop and between points.'
-       radius = abs(radius)
-       points = getPointsFromLoop( loop, radius, thresholdRatio )
-       return getCircleNodesFromPoints( points, radius )
-
-def getCircleNodesFromPoints(points, radius):
-       'Get the circle nodes from a path.'
-       if radius == 0.0:
-               print('Warning, radius is 0 in getCircleNodesFromPoints in intercircle.')
-               print(points)
-               return []
-       circleNodes = []
-       oneOverRadius = 1.000001 / radius # to avoid problem of accidentally integral radius
-       points = euclidean.getAwayPoints(points, radius)
-       for point in points:
-               circleNodes.append(CircleNode(oneOverRadius, point))
-       return circleNodes
-
-def getInsetLoopsFromLoop(loop, radius, thresholdRatio=0.9):
-       'Get the inset loops, which might overlap.'
-       if radius == 0.0:
-               return [loop]
-       isInset = radius > 0
-       insetLoops = []
-       isLoopWiddershins = euclidean.isWiddershins(loop)
-       arounds = getAroundsFromLoop(loop, radius, thresholdRatio)
-       for around in arounds:
-               leftPoint = euclidean.getLeftPoint(around)
-               shouldBeWithin = (isInset == isLoopWiddershins)
-               if euclidean.isPointInsideLoop(loop, leftPoint) == shouldBeWithin:
-                       if isLoopWiddershins != euclidean.isWiddershins(around):
-                               around.reverse()
-                       insetLoops.append(around)
-       return insetLoops
-
-def getInsetLoopsFromLoops(loops, radius):
-       'Get the inset loops, which might overlap.'
-       insetLoops = []
-       for loop in loops:
-               insetLoops += getInsetLoopsFromLoop(loop, radius)
-       return insetLoops
-
-def getInsetLoopsFromVector3Loop(loop, radius, thresholdRatio=0.9):
-       'Get the inset loops from vector3 loop, which might overlap.'
-       if len(loop) < 2:
-               return [loop]
-       loopComplex = euclidean.getComplexPath(loop)
-       loopComplexes = getInsetLoopsFromLoop(loopComplex, radius)
-       return euclidean.getVector3Paths(loopComplexes, loop[0].z)
-
-def getInsetSeparateLoopsFromLoops(loops, radius, thresholdRatio=0.9):
-       'Get the separate inset loops.'
-       if radius == 0.0:
-               return loops
-       isInset = radius > 0
-       insetSeparateLoops = []
-       arounds = getAroundsFromLoops(loops, abs(radius), thresholdRatio)
-       for around in arounds:
-               if isInset == euclidean.getIsInFilledRegion(loops, around[0]):
-                       if isInset:
-                               around.reverse()
-                       insetSeparateLoops.append(around)
-       return insetSeparateLoops
-
-def getInsetSeparateLoopsFromAroundLoops(loops, radius, radiusAround, thresholdRatio=0.9):
-       'Get the separate inset loops.'
-       if radius == 0.0:
-               return loops
-       isInset = radius > 0
-       insetSeparateLoops = []
-       radius = abs(radius)
-       radiusAround = max(abs(radiusAround), radius)
-       points = getPointsFromLoops(loops, radiusAround, thresholdRatio)
-       centers = getCentersFromPoints(points, globalIntercircleMultiplier * radiusAround)
-       for center in centers:
-               inset = getSimplifiedInsetFromClockwiseLoop(center, radius)
-               if isLargeSameDirection(inset, center, radius):
-                       if isInset == euclidean.getIsInFilledRegion(loops, inset[0]):
-                               if isInset:
-                                       inset.reverse()
-                               insetSeparateLoops.append(inset)
-       return insetSeparateLoops
-
-def getIsLarge(loop, radius):
-       'Determine if the loop is large enough.'
-       return euclidean.getMaximumSpan(loop) > 2.01 * abs(radius)
-
-def getLargestCenterOutsetLoopFromLoop(loop, radius, thresholdRatio=0.9):
-       'Get the largest circle outset loop from the loop.'
-       if radius == 0.0:
-               return loop
-       radius = abs(radius)
-       points = getPointsFromLoop(loop, radius, thresholdRatio)
-       centers = getCentersFromPoints(points, globalIntercircleMultiplier * radius)
-       largestCenterOutset = None
-       largestOutsetArea = -987654321.0
-       for center in centers:
-               outset = getSimplifiedInsetFromClockwiseLoop(center, radius)
-               if isLargeSameDirection(outset, center, radius):
-                       if euclidean.isPathInsideLoop(loop, outset) != euclidean.isWiddershins(loop):
-                               centerOutset = CenterOutset(center, outset)
-                               outsetArea = abs(euclidean.getAreaLoop(outset))
-                               if outsetArea > largestOutsetArea:
-                                       largestOutsetArea = outsetArea
-                                       largestCenterOutset = centerOutset
-       if largestCenterOutset == None:
-               return None
-       largestCenterOutset.center = euclidean.getSimplifiedLoop(largestCenterOutset.center, radius)
-       return largestCenterOutset
-
-def getLargestCenterOutsetLoopFromLoopRegardless(loop, radius):
-       'Get the largest circle outset loop from the loop, even if the radius has to be shrunk and even if there is still no outset loop.'
-       global globalDecreasingRadiusMultipliers
-       for decreasingRadiusMultiplier in globalDecreasingRadiusMultipliers:
-               decreasingRadius = radius * decreasingRadiusMultiplier
-               largestCenterOutsetLoop = getLargestCenterOutsetLoopFromLoop(loop, decreasingRadius)
-               if largestCenterOutsetLoop != None:
-                       return largestCenterOutsetLoop
-       return CenterOutset(loop, loop)
-
-def getLargestInsetLoopFromLoop(loop, radius):
-       'Get the largest inset loop from the loop.'
-       loops = getInsetLoopsFromLoop(loop, radius)
-       return euclidean.getLargestLoop(loops)
-
-def getLargestInsetLoopFromLoopRegardless( loop, radius ):
-       'Get the largest inset loop from the loop, even if the radius has to be shrunk and even if there is still no inset loop.'
-       global globalDecreasingRadiusMultipliers
-       for decreasingRadiusMultiplier in globalDecreasingRadiusMultipliers:
-               decreasingRadius = radius * decreasingRadiusMultiplier
-               largestInsetLoop = getLargestInsetLoopFromLoop( loop, decreasingRadius )
-               if len( largestInsetLoop ) > 0:
-                       return largestInsetLoop
-       print('Warning, there should always be a largestInsetLoop in getLargestInsetLoopFromLoopRegardless in intercircle.')
-       print(loop)
-       return loop
-
-def getLoopsFromLoopsDirection( isWiddershins, loops ):
-       'Get the loops going round in a given direction.'
-       directionalLoops = []
-       for loop in loops:
-               if euclidean.isWiddershins(loop) == isWiddershins:
-                       directionalLoops.append(loop)
-       return directionalLoops
-
-def getPointsFromLoop(loop, radius, thresholdRatio=0.9):
-       'Get the points from every point on a loop and between points.'
-       if radius == 0.0:
-               print('Warning, radius is 0 in getPointsFromLoop in intercircle.')
-               print(loop)
-               return loop
-       radius = abs(radius)
-       points = []
-       for pointIndex in xrange(len(loop)):
-               pointBegin = loop[pointIndex]
-               pointEnd = loop[(pointIndex + 1) % len(loop)]
-               points.append( pointBegin )
-               addPointsFromSegment( pointBegin, pointEnd, points, radius, thresholdRatio )
-       return points
-
-def getPointsFromLoops(loops, radius, thresholdRatio=0.9):
-       'Get the points from every point on a loop and between points.'
-       points = []
-       for loop in loops:
-               points += getPointsFromLoop(loop, radius, thresholdRatio)
-       return points
-
-def getPointsFromPath(path, radius, thresholdRatio=0.9):
-       'Get the points from every point on a path and between points.'
-       if len(path) < 1:
-               return []
-       if len(path) < 2:
-               return path
-       radius = abs(radius)
-       points = []
-       addHalfPath(path, points, radius, thresholdRatio)
-       addHalfPath(path[: : -1], points, radius, thresholdRatio)
-       return points
-
-def getSimplifiedInsetFromClockwiseLoop(loop, radius):
-       'Get loop inset from clockwise loop, out from widdershins loop.'
-       inset = []
-       for pointIndex, begin in enumerate(loop):
-               center = loop[(pointIndex + 1) % len(loop)]
-               end = loop[(pointIndex + 2) % len(loop)]
-               addInsetPointFromClockwiseTriple(begin, center, end, inset, radius)
-       return getWithoutIntersections(euclidean.getSimplifiedLoop(inset, radius))
-
-def getWiddershinsByLength(begin, end, length):
-       'Get the widdershins by length.'
-       endMinusBegin = end - begin
-       endMinusBeginLength = abs(endMinusBegin)
-       if endMinusBeginLength <= 0.0:
-               return None
-       endMinusBegin *= length / endMinusBeginLength
-       return complex(-endMinusBegin.imag, endMinusBegin.real)
-
-def getWithoutIntersections( loop ):
-       'Get loop without intersections.'
-       lastLoopLength = len( loop )
-       while lastLoopLength > 3:
-               removeIntersection( loop )
-               if len( loop ) == lastLoopLength:
-                       return loop
-               lastLoopLength = len( loop )
-       return loop
-
-def isLargeSameDirection(inset, loop, radius):
-       'Determine if the inset is in the same direction as the loop and it is large enough.'
-       if euclidean.isWiddershins(inset) != euclidean.isWiddershins(loop):
-               return False
-       return getIsLarge(inset, radius) and len(inset) > 2
-
-def isLoopIntersectingLoop( anotherLoop, loop ):
-       'Determine if the a loop is intersecting another loop.'
-       for pointIndex in xrange(len(loop)):
-               pointFirst = loop[pointIndex]
-               pointSecond = loop[(pointIndex + 1) % len(loop)]
-               segment = pointFirst - pointSecond
-               normalizedSegment = euclidean.getNormalized(segment)
-               segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag)
-               segmentFirstPoint = segmentYMirror * pointFirst
-               segmentSecondPoint = segmentYMirror * pointSecond
-               if euclidean.isLoopIntersectingInsideXSegment( anotherLoop, segmentFirstPoint.real, segmentSecondPoint.real, segmentYMirror, segmentFirstPoint.imag ):
-                       return True
-       return False
-
-def orbitsAreLarge( loop, temperatureChangeTime ):
-       'Determine if the orbits are large enough.'
-       if len(loop) < 1:
-               print('Zero length loop which was skipped over, this should never happen.')
-               return False
-       return temperatureChangeTime > 1.5
-
-def removeIntersection( loop ):
-       'Get loop without the first intersection.'
-       for pointIndex, ahead in enumerate(loop):
-               behind = loop[ ( pointIndex + len( loop ) - 1 ) % len( loop ) ]
-               behindEnd = loop[ ( pointIndex + len( loop ) - 2 ) % len( loop ) ]
-               behindMidpoint = 0.5 * ( behind + behindEnd )
-               aheadEnd = loop[ (pointIndex + 1) % len( loop ) ]
-               aheadMidpoint = 0.5 * ( ahead + aheadEnd )
-               normalizedSegment = behind - behindMidpoint
-               normalizedSegmentLength = abs( normalizedSegment )
-               if normalizedSegmentLength > 0.0:
-                       normalizedSegment /= normalizedSegmentLength
-                       segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag)
-                       behindRotated = segmentYMirror * behind
-                       behindMidpointRotated = segmentYMirror * behindMidpoint
-                       aheadRotated = segmentYMirror * ahead
-                       aheadMidpointRotated = segmentYMirror * aheadMidpoint
-                       y = behindRotated.imag
-                       xIntersection = euclidean.getXIntersectionIfExists( aheadRotated, aheadMidpointRotated, y )
-                       if xIntersection != None:
-                               if min( behindMidpointRotated.real, behindRotated.real ) < xIntersection < max( behindMidpointRotated.real, behindRotated.real ):
-                                       intersectionPoint = normalizedSegment * complex( xIntersection, y )
-                                       loop[ ( pointIndex + len( loop ) - 1 ) % len( loop ) ] = intersectionPoint
-                                       del loop[pointIndex]
-                                       return
-
-
-class BoundingLoop(object):
-       'A class to hold a bounding loop composed of a minimum complex, a maximum complex and an outset loop.'
-       def __eq__(self, other):
-               'Determine whether this bounding loop is identical to other one.'
-               if other == None:
-                       return False
-               return self.minimum == other.minimum and self.maximum == other.maximum and self.loop == other.loop
-
-       def __repr__(self):
-               'Get the string representation of this bounding loop.'
-               return '%s, %s, %s' % ( self.minimum, self.maximum, self.loop )
-
-       def getFromLoop( self, loop ):
-               'Get the bounding loop from a path.'
-               self.loop = loop
-               self.maximum = euclidean.getMaximumByComplexPath(loop)
-               self.minimum = euclidean.getMinimumByComplexPath(loop)
-               return self
-
-       def getOutsetBoundingLoop( self, outsetDistance ):
-               'Outset the bounding rectangle and loop by a distance.'
-               outsetBoundingLoop = BoundingLoop()
-               outsetBoundingLoop.maximum = self.maximum + complex( outsetDistance, outsetDistance )
-               outsetBoundingLoop.minimum = self.minimum - complex( outsetDistance, outsetDistance )
-               greaterThanOutsetDistance = 1.1 * outsetDistance
-               centers = getCentersFromLoopDirection( True, self.loop, greaterThanOutsetDistance )
-               outsetBoundingLoop.loop = getSimplifiedInsetFromClockwiseLoop( centers[0], outsetDistance )
-               return outsetBoundingLoop
-
-       def isEntirelyInsideAnother( self, anotherBoundingLoop ):
-               'Determine if this bounding loop is entirely inside another bounding loop.'
-               if self.minimum.imag < anotherBoundingLoop.minimum.imag or self.minimum.real < anotherBoundingLoop.minimum.real:
-                       return False
-               if self.maximum.imag > anotherBoundingLoop.maximum.imag or self.maximum.real > anotherBoundingLoop.maximum.real:
-                       return False
-               for point in self.loop:
-                       if euclidean.getNumberOfIntersectionsToLeft( anotherBoundingLoop.loop, point ) % 2 == 0:
-                               return False
-               return not isLoopIntersectingLoop( anotherBoundingLoop.loop, self.loop ) #later check for intersection on only acute angles
-
-       def isOverlappingAnother( self, anotherBoundingLoop ):
-               'Determine if this bounding loop is intersecting another bounding loop.'
-               if self.isRectangleMissingAnother( anotherBoundingLoop ):
-                       return False
-               for point in self.loop:
-                       if euclidean.getNumberOfIntersectionsToLeft( anotherBoundingLoop.loop, point ) % 2 == 1:
-                               return True
-               for point in anotherBoundingLoop.loop:
-                       if euclidean.getNumberOfIntersectionsToLeft( self.loop, point ) % 2 == 1:
-                               return True
-               return isLoopIntersectingLoop( anotherBoundingLoop.loop, self.loop ) #later check for intersection on only acute angles
-
-       def isOverlappingAnotherInList( self, boundingLoops ):
-               'Determine if this bounding loop is intersecting another bounding loop in a list.'
-               for boundingLoop in boundingLoops:
-                       if self.isOverlappingAnother( boundingLoop ):
-                               return True
-               return False
-
-       def isRectangleMissingAnother( self, anotherBoundingLoop ):
-               'Determine if the rectangle of this bounding loop is missing the rectangle of another bounding loop.'
-               if self.maximum.imag < anotherBoundingLoop.minimum.imag or self.maximum.real < anotherBoundingLoop.minimum.real:
-                       return True
-               return self.minimum.imag > anotherBoundingLoop.maximum.imag or self.minimum.real > anotherBoundingLoop.maximum.real
-
-
-class CenterOutset(object):
-       'A class to hold a center and an outset.'
-       def __init__(self, center, outset):
-               'Set the center and outset.'
-               self.center = center
-               self.outset = outset
-
-       def __repr__(self):
-               'Get the string representation of this CenterOutset.'
-               return '%s\n%s' % (self.center, self.outset)
-
-
-class CircleIntersection(object):
-       'An intersection of two complex circles.'
-       def __init__( self, circleNodeAhead, index, circleNodeBehind ):
-               self.aheadMinusBehind = 0.5 * ( circleNodeAhead.dividedPoint - circleNodeBehind.dividedPoint )
-               self.circleNodeAhead = circleNodeAhead
-               self.circleNodeBehind = circleNodeBehind
-               self.index = index
-               self.steppedOn = False
-               demichordWidth = math.sqrt( 1.0 - self.aheadMinusBehind.real * self.aheadMinusBehind.real - self.aheadMinusBehind.imag * self.aheadMinusBehind.imag )
-               rotatedClockwiseQuarter = complex( self.aheadMinusBehind.imag, - self.aheadMinusBehind.real )
-               rotatedClockwiseQuarterLength = abs( rotatedClockwiseQuarter )
-               if rotatedClockwiseQuarterLength == 0:
-                       print('Warning, rotatedClockwiseQuarter in getDemichord in intercircle is 0')
-                       print(circleNodeAhead.dividedPoint)
-                       print(circleNodeBehind.dividedPoint)
-                       self.demichord = 0.0
-               else:
-                       self.demichord = rotatedClockwiseQuarter * demichordWidth / rotatedClockwiseQuarterLength
-               self.positionRelativeToBehind = self.aheadMinusBehind + self.demichord
-
-       def __repr__(self):
-               'Get the string representation of this CircleIntersection.'
-               return '%s, %s, %s, %s' % (self.index, self.getAbsolutePosition(), self.circleNodeBehind, self.circleNodeAhead)
-
-       def addToList( self, circleIntersectionPath ):
-               'Add this to the circle intersection path, setting stepped on to be true.'
-               self.steppedOn = True
-               circleIntersectionPath.append(self)
-
-       def getAbsolutePosition(self):
-               'Get the absolute position.'
-               return self.positionRelativeToBehind + self.circleNodeBehind.dividedPoint
-
-       def getCircleIntersectionAhead(self):
-               'Get the first circle intersection on the circle node ahead.'
-               circleIntersections = self.circleNodeAhead.circleIntersections
-               circleIntersectionAhead = None
-               largestDot = -912345678.0
-               for circleIntersection in circleIntersections:
-                       if not circleIntersection.steppedOn:
-                               circleIntersectionRelativeToMidpoint = euclidean.getNormalized(circleIntersection.positionRelativeToBehind + self.aheadMinusBehind)
-                               dot = euclidean.getDotProduct(self.demichord, circleIntersectionRelativeToMidpoint)
-                               if dot > largestDot:
-                                       largestDot = dot
-                                       circleIntersectionAhead = circleIntersection
-               if circleIntersectionAhead == None:
-                       print('Warning, circleIntersectionAhead in getCircleIntersectionAhead in intercircle is None for:')
-                       print(self.circleNodeAhead.dividedPoint)
-                       print('circleIntersectionsAhead')
-                       for circleIntersection in circleIntersections:
-                               print(circleIntersection.circleNodeAhead.dividedPoint)
-                       print('circleIntersectionsBehind')
-                       for circleIntersection in self.circleNodeBehind.circleIntersections:
-                               print(circleIntersection.circleNodeAhead.dividedPoint)
-                       print('This may lead to a loop not being sliced.')
-                       print('If this is a problem, you may as well send a bug report, even though I probably can not fix this particular problem.')
-               return circleIntersectionAhead
-
-       def isWithinCircles(self, pixelTable):
-               'Determine if this circle intersection is within the circle node circles.'
-               absolutePosition = self.getAbsolutePosition()
-               squareValues = euclidean.getSquareValuesFromPoint(pixelTable, absolutePosition)
-               for squareValue in squareValues:
-                       if abs(squareValue.dividedPoint - absolutePosition) < 1.0:
-                               if squareValue != self.circleNodeAhead and squareValue != self.circleNodeBehind:
-                                       return True
-               return False
-
-
-class CircleNode(object):
-       'A complex node of complex circle intersections.'
-       def __init__(self, oneOverRadius, point):
-               self.actualPoint = point
-               self.circleIntersections = []
-               self.dividedPoint = point * oneOverRadius
-#              self.index = index # when debugging bring back index
-
-       def __repr__(self):
-               'Get the string representation of this CircleNode.'
-#              return '%s, %s, %s' % (self.index, self.dividedPoint, len(self.circleIntersections)) # when debugging bring back index
-               return '%s, %s' % (self.dividedPoint, len(self.circleIntersections))
-
-       def getWithinNodes(self, pixelTable):
-               'Get the nodes this circle node is within.'
-               withinNodes = []
-               squareValues = euclidean.getSquareValuesFromPoint(pixelTable, 0.5 * self.dividedPoint)
-               for squareValue in squareValues:
-                       if abs(self.dividedPoint - squareValue.dividedPoint) < 2.0:
-                               withinNodes.append(squareValue)
-               return withinNodes
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/settings.py b/Cura/slice/cura_sf/fabmetheus_utilities/settings.py
deleted file mode 100644 (file)
index b7dfdd9..0000000
+++ /dev/null
@@ -1,608 +0,0 @@
-"""
-Settings is a collection of utilities to display, read & write the settings and position widgets.
-
-"""
-
-from __future__ import absolute_import
-from __future__ import division
-
-import sys
-import types
-import math
-
-from Cura.util import profile
-from Cura.slice.cura_sf.fabmetheus_utilities import archive
-
-def DEFSET(setting):
-       return setting.value
-
-def storedSetting(name):
-       return lambda setting: profile.getProfileSetting(name)
-def storedSettingFloat(name):
-       return lambda setting: profile.getProfileSettingFloat(name)
-def storedSettingInt(name):
-       return lambda setting: int(profile.getProfileSettingFloat(name))
-def storedPreference(name):
-       return lambda setting: profile.getPreference(name)
-def storedPreferenceFloat(name):
-       return lambda setting: profile.getPreferenceFloat(name)
-def storedSettingInvertBoolean(name):
-       return lambda setting: profile.getProfileSetting(name) == "False"
-
-def ifSettingAboveZero(name):
-       return lambda setting: profile.getProfileSettingFloat(name) > 0
-
-def ifSettingIs(name, value):
-       return lambda setting: profile.getProfileSetting(name) == value
-
-def raftLayerCount(setting):
-       if profile.getProfileSetting('enable_raft') == "True":
-               return '1'
-       return '0'
-
-def storedPercentSetting(name):
-       return lambda setting: profile.getProfileSettingFloat(name) / 100
-
-def calculateEdgeWidth(setting):
-       return profile.calculateEdgeWidth()
-
-def calculateShells(setting):
-       return profile.calculateLineCount() - 1
-
-def calculateShellsBase(setting):
-       edgeWidth = profile.calculateEdgeWidth()
-       extraWall = profile.getProfileSettingFloat('extra_base_wall_thickness')
-       
-       return profile.calculateLineCount() - 1 + int(extraWall / edgeWidth + 0.0001)
-
-def calculateSolidLayerCount(setting):
-       return profile.calculateSolidLayerCount()
-
-def firstLayerSpeedRatio(setting):
-       bottomSpeed = profile.getProfileSettingFloat('bottom_layer_speed')
-       speed = profile.getProfileSettingFloat('print_speed')
-       return bottomSpeed/speed
-
-def calcSupportDistanceRatio(setting):
-       edgeWidth = calculateEdgeWidth(setting)
-       distance = profile.getProfileSettingFloat('support_distance')
-       return distance / edgeWidth
-
-def calculateMultiplyDistance(setting):
-       edgeWidth = calculateEdgeWidth(setting)
-       return 10.0 / edgeWidth
-
-def calcBottomLayerFlowRateRatio(setting):
-       bottomThickness = profile.getProfileSettingFloat('bottom_thickness')
-       layerThickness = profile.getProfileSettingFloat('layer_height')
-       if bottomThickness < layerThickness:
-               return 1.0
-       return bottomThickness / layerThickness
-
-def calcExtraBottomThickness(setting):
-       bottomThickness = profile.getProfileSettingFloat('bottom_thickness')
-       layerThickness = profile.getProfileSettingFloat('layer_height')
-       if bottomThickness < layerThickness:
-               return 0.0
-       return bottomThickness - layerThickness
-
-def calcLayerSkip(setting):
-       bottomThickness = profile.getProfileSettingFloat('bottom_thickness')
-       layerThickness = profile.getProfileSettingFloat('layer_height')
-       if bottomThickness < layerThickness:
-               return 0
-       return int(math.ceil((bottomThickness - layerThickness) / layerThickness + 0.0001) - 1)
-
-def getProfileInformation():
-       return {
-               'carve': {
-                       'Add_Layer_Template_to_SVG': 'False',
-                       'Edge_Width_mm': calculateEdgeWidth,
-                       'Extra_Decimal_Places_float': DEFSET,
-                       'Import_Coarseness_ratio': DEFSET,
-                       'Layer_Height_mm': storedSettingFloat("layer_height"),
-                       'Layers_From_index': calcLayerSkip,
-                       'Layers_To_index': DEFSET,
-                       'Correct_Mesh': DEFSET,
-                       'Unproven_Mesh': DEFSET,
-                       'SVG_Viewer': DEFSET,
-                       'ObjectMatrix': storedSetting("object_matrix"),
-                       'CenterX': lambda setting: profile.getProfileSettingFloat('object_center_x'),
-                       'CenterY': lambda setting: profile.getProfileSettingFloat('object_center_y'),
-                       'ObjectSink': storedSetting("object_sink"),
-                       'AlternativeCenterFile': storedSetting("alternative_center"),
-               },'scale': {
-                       'Activate_Scale': "False",
-                       'XY_Plane_Scale_ratio': DEFSET,
-                       'Z_Axis_Scale_ratio': DEFSET,
-                       'SVG_Viewer': DEFSET,
-               },'bottom': {
-                       'Activate_Bottom': DEFSET,
-                       'Additional_Height_over_Layer_Thickness_ratio': DEFSET,
-                       'Altitude_mm': calcExtraBottomThickness,
-                       'SVG_Viewer': DEFSET,
-               },'preface': {
-                       'Meta': DEFSET,
-                       'Set_Positioning_to_Absolute': "False",
-                       'Set_Units_to_Millimeters': "False",
-                       'Start_at_Home': DEFSET,
-                       'Turn_Extruder_Off_at_Shut_Down': DEFSET,
-                       'Turn_Extruder_Off_at_Start_Up': DEFSET,
-               },'widen': {
-                       'Activate_Widen': DEFSET,
-                       'Widen_Width_over_Edge_Width_ratio': DEFSET,
-               },'inset': {
-                       'Add_Custom_Code_for_Temperature_Reading': "False",
-                       'Infill_in_Direction_of_Bridge': ifSettingAboveZero('fill_density'),
-                       'Infill_Width': storedSettingFloat("nozzle_size"),
-                       'Loop_Order_Choice': DEFSET,
-                       'Overlap_Removal_Width_over_Perimeter_Width_ratio': DEFSET,
-                       'Turn_Extruder_Heater_Off_at_Shut_Down': "False",
-                       'Volume_Fraction_ratio': DEFSET,
-               },'fill': {
-                       'Activate_Fill': "True",
-                       'Solid_Surface_Top': storedSetting("solid_top"),
-                       'Override_First_Layer_Sequence': storedSetting("force_first_layer_sequence"),
-                       'Diaphragm_Period_layers': DEFSET,
-                       'Diaphragm_Thickness_layers': DEFSET,
-                       'Extra_Shells_on_Alternating_Solid_Layer_layers': calculateShells,
-                       'Extra_Shells_on_Base_layers': calculateShellsBase,
-                       'Extra_Shells_on_Sparse_Layer_layers': calculateShells,
-                       'Grid_Circle_Separation_over_Perimeter_Width_ratio': DEFSET,
-                       'Grid_Extra_Overlap_ratio': DEFSET,
-                       'Grid_Junction_Separation_Band_Height_layers': DEFSET,
-                       'Grid_Junction_Separation_over_Octogon_Radius_At_End_ratio': DEFSET,
-                       'Grid_Junction_Separation_over_Octogon_Radius_At_Middle_ratio': DEFSET,
-                       'Infill_Begin_Rotation_degrees': DEFSET,
-                       'Infill_Begin_Rotation_Repeat_layers': DEFSET,
-                       'Infill_Odd_Layer_Extra_Rotation_degrees': DEFSET,
-                       'Grid_Circular': ifSettingIs('infill_type', 'Grid Circular'),
-                       'Grid_Hexagonal': ifSettingIs('infill_type', 'Grid Hexagonal'),
-                       'Grid_Rectangular': ifSettingIs('infill_type', 'Grid Rectangular'),
-                       'Line': ifSettingIs('infill_type', 'Line'),
-                       'Infill_Perimeter_Overlap_ratio': storedPercentSetting('fill_overlap'),
-                       'Infill_Solidity_ratio': storedPercentSetting('fill_density'),
-                       'Infill_Width': storedSettingFloat("nozzle_size"),
-                       'Sharpest_Angle_degrees': DEFSET,
-                       'Solid_Surface_Thickness_layers': calculateSolidLayerCount,
-                       'Start_From_Choice': DEFSET,
-                       'Surrounding_Angle_degrees': DEFSET,
-                       'Thread_Sequence_Choice': storedSetting('sequence'),
-               },'multiply': {
-                       'Activate_Multiply': "False",
-                       'Center_X_mm': DEFSET,
-                       'Center_Y_mm': DEFSET,
-                       'Number_of_Columns_integer': DEFSET,
-                       'Number_of_Rows_integer': DEFSET,
-                       'Reverse_Sequence_every_Odd_Layer': DEFSET,
-                       'Separation_over_Perimeter_Width_ratio': DEFSET,
-               },'speed': {
-                       'Activate_Speed': "True",
-                       'Add_Flow_Rate': "True",
-                       'Bridge_Feed_Rate_Multiplier_ratio': storedPercentSetting('bridge_speed'),
-                       'Bridge_Flow_Rate_Multiplier_ratio': storedPercentSetting('bridge_speed'),
-                       'Duty_Cyle_at_Beginning_portion': DEFSET,
-                       'Duty_Cyle_at_Ending_portion': DEFSET,
-                       'Feed_Rate_mm/s': storedSettingFloat("print_speed"),
-                       'Flow_Rate_Setting_float': storedSettingFloat("print_speed"),
-                       'Object_First_Layer_Feed_Rate_Infill_Multiplier_ratio': firstLayerSpeedRatio,
-                       'Object_First_Layer_Feed_Rate_Perimeter_Multiplier_ratio': firstLayerSpeedRatio,
-                       'Object_First_Layer_Feed_Rate_Travel_Multiplier_ratio': firstLayerSpeedRatio,
-                       'Object_First_Layer_Flow_Rate_Infill_Multiplier_ratio': firstLayerSpeedRatio,
-                       'Object_First_Layer_Flow_Rate_Perimeter_Multiplier_ratio': firstLayerSpeedRatio,
-                       'Object_First_Layers_Amount_Of_Layers_For_Speed_Change': DEFSET,
-                       'Orbital_Feed_Rate_over_Operating_Feed_Rate_ratio': DEFSET,
-                       'Maximum_Z_Feed_Rate_mm/s': DEFSET,
-                       'Perimeter_Feed_Rate_Multiplier_ratio': DEFSET,
-                       'Perimeter_Flow_Rate_Multiplier_ratio': DEFSET,
-                       'Travel_Feed_Rate_mm/s': storedSettingFloat("travel_speed"),
-                       'Bottom_layer_flow_rate_ratio': calcBottomLayerFlowRateRatio,
-               },'temperature': {
-                       'Activate_Temperature': DEFSET,#ifSettingAboveZero('print_temperature'),
-                       'Cooling_Rate_Celcius/second': DEFSET,
-                       'Heating_Rate_Celcius/second': DEFSET,
-                       'Base_Temperature_Celcius': DEFSET,#storedSettingFloat("print_temperature"),
-                       'Interface_Temperature_Celcius': DEFSET,#storedSettingFloat("print_temperature"),
-                       'Object_First_Layer_Infill_Temperature_Celcius': DEFSET,#storedSettingFloat("print_temperature"),
-                       'Object_First_Layer_Perimeter_Temperature_Celcius': DEFSET,#storedSettingFloat("print_temperature"),
-                       'Object_Next_Layers_Temperature_Celcius': DEFSET,#storedSettingFloat("print_temperature"),
-                       'Support_Layers_Temperature_Celcius': DEFSET,#storedSettingFloat("print_temperature"),
-                       'Supported_Layers_Temperature_Celcius': DEFSET,#storedSettingFloat("print_temperature"),
-               },'raft': {
-                       'Activate_Raft': "True",
-                       'Add_Raft,_Elevate_Nozzle,_Orbit': DEFSET,
-                       'Base_Feed_Rate_Multiplier_ratio': DEFSET,
-                       'Base_Flow_Rate_Multiplier_ratio': storedPercentSetting('raft_base_material_amount'),
-                       'Base_Infill_Density_ratio': DEFSET,
-                       'Base_Layer_Thickness_over_Layer_Thickness': DEFSET,
-                       'Base_Layers_integer': raftLayerCount,
-                       'Base_Nozzle_Lift_over_Base_Layer_Thickness_ratio': DEFSET,
-                       'Initial_Circling': DEFSET,
-                       'Infill_Overhang_over_Extrusion_Width_ratio': DEFSET,
-                       'Interface_Feed_Rate_Multiplier_ratio': DEFSET,
-                       'Interface_Flow_Rate_Multiplier_ratio': storedPercentSetting('raft_interface_material_amount'),
-                       'Interface_Infill_Density_ratio': DEFSET,
-                       'Interface_Layer_Thickness_over_Layer_Thickness': DEFSET,
-                       'Interface_Layers_integer': raftLayerCount,
-                       'Interface_Nozzle_Lift_over_Interface_Layer_Thickness_ratio': DEFSET,
-                       'Name_of_Support_End_File': DEFSET,
-                       'Name_of_Support_Start_File': DEFSET,
-                       'Operating_Nozzle_Lift_over_Layer_Thickness_ratio': DEFSET,
-                       'Raft_Additional_Margin_over_Length_%': DEFSET,
-                       'Raft_Margin_mm': storedSettingFloat('raft_margin'),
-                       'Support_Cross_Hatch': lambda setting: 'True' if profile.getProfileSetting('support_dual_extrusion') == 'True' and int(profile.getPreference('extruder_amount')) > 1 else 'False',
-                       'Support_Flow_Rate_over_Operating_Flow_Rate_ratio': storedPercentSetting('support_rate'),
-                       'Support_Gap_over_Perimeter_Extrusion_Width_ratio': calcSupportDistanceRatio,
-                       'Support_Material_Choice_': storedSetting('support'),
-                       'Support_Minimum_Angle_degrees': DEFSET,
-                       'Support_Margin_mm': '3.0',
-                       'Support_Offset_X_mm': lambda setting: -profile.getPreferenceFloat('extruder_offset_x1') if profile.getProfileSetting('support_dual_extrusion') == 'True' and int(profile.getPreference('extruder_amount')) > 1 else '0',
-                       'Support_Offset_Y_mm': lambda setting: -profile.getPreferenceFloat('extruder_offset_y1') if profile.getProfileSetting('support_dual_extrusion') == 'True' and int(profile.getPreference('extruder_amount')) > 1 else '0',
-               },'skirt': {
-                       'Skirt_line_count': storedSetting("skirt_line_count"),
-                       'Convex': lambda setting: "True" if profile.getProfileSettingFloat('skirt_gap') > 0.0 else "False",
-                       'Gap_Width_mm': storedSetting("skirt_gap"),
-                       'Layers_To_index': "1",
-               },'joris': {
-                       'Activate_Joris': storedSetting("joris"),
-                       'Layers_From_index': calculateSolidLayerCount,
-               },'chamber': {
-                       'Activate_Chamber': "False",
-                       'Bed_Temperature_Celcius': DEFSET,
-                       'Bed_Temperature_Begin_Change_Height_mm': DEFSET,
-                       'Bed_Temperature_End_Change_Height_mm': DEFSET,
-                       'Bed_Temperature_End_Celcius': DEFSET,
-                       'Chamber_Temperature_Celcius': DEFSET,
-                       'Holding_Force_bar': DEFSET,
-               },'tower': {
-                       'Activate_Tower': "False",
-                       'Extruder_Possible_Collision_Cone_Angle_degrees': DEFSET,
-                       'Maximum_Tower_Height_layers': DEFSET,
-                       'Tower_Start_Layer_integer': DEFSET,
-               },'jitter': {
-                       'Activate_Jitter': "False",
-                       'Jitter_Over_Perimeter_Width_ratio': DEFSET,
-               },'clip': {
-                       'Activate_Clip': "False",
-                       'Clip_Over_Perimeter_Width_ratio': DEFSET,
-                       'Maximum_Connection_Distance_Over_Perimeter_Width_ratio': DEFSET,
-               },'smooth': {
-                       'Activate_Smooth': "False",
-                       'Layers_From_index': DEFSET,
-                       'Maximum_Shortening_over_Width_float': DEFSET,
-               },'stretch': {
-                       'Activate_Stretch': "False",
-                       'Cross_Limit_Distance_Over_Perimeter_Width_ratio': DEFSET,
-                       'Loop_Stretch_Over_Perimeter_Width_ratio': DEFSET,
-                       'Path_Stretch_Over_Perimeter_Width_ratio': DEFSET,
-                       'Perimeter_Inside_Stretch_Over_Perimeter_Width_ratio': DEFSET,
-                       'Perimeter_Outside_Stretch_Over_Perimeter_Width_ratio': DEFSET,
-                       'Stretch_From_Distance_Over_Perimeter_Width_ratio': DEFSET,
-               },'skin': {
-                       'Activate_Skin': storedSetting("enable_skin"),
-                       'Horizontal_Infill_Divisions_integer': "1",
-                       'Horizontal_Perimeter_Divisions_integer': "1",
-                       'Vertical_Divisions_integer': "2",
-                       'Hop_When_Extruding_Infill': "False",
-                       'Layers_From_index': "1",
-               },'comb': {
-                       'Activate_Comb': "True",
-                       'Running_Jump_Space_mm': DEFSET,
-               },'cool': {
-                       'Activate_Cool': "True",
-                       'Bridge_Cool_Celcius': DEFSET,
-                       'Cool_Type': DEFSET,
-                       'Maximum_Cool_Celcius': DEFSET,
-                       'Minimum_Layer_Time_seconds': storedSettingFloat("cool_min_layer_time"),
-                       'Minimum_Orbital_Radius_millimeters': DEFSET,
-                       'Name_of_Cool_End_File': DEFSET,
-                       'Name_of_Cool_Start_File': DEFSET,
-                       'Orbital_Outset_millimeters': DEFSET,
-                       'Turn_Fan_On_at_Beginning': storedSetting("fan_enabled"),
-                       'Turn_Fan_Off_at_Ending': storedSetting("fan_enabled"),
-                       'Minimum_feed_rate_mm/s': storedSettingFloat("cool_min_feedrate"),
-                       'Fan_on_at_layer': storedSettingInt('fan_layer'),
-                       'Fan_speed_min_%': storedSettingInt('fan_speed'),
-                       'Fan_speed_max_%': storedSettingInt('fan_speed_max'),
-               },'hop': {
-                       'Activate_Hop': storedSetting('hop_on_move'),
-                       'Hop_Over_Layer_Thickness_ratio': lambda setting: 0.2 / profile.getProfileSettingFloat('layer_height'),
-                       'Minimum_Hop_Angle_degrees': DEFSET,
-               },'wipe': {
-                       'Activate_Wipe': "False",
-                       'Arrival_X_mm': DEFSET,
-                       'Arrival_Y_mm': DEFSET,
-                       'Arrival_Z_mm': DEFSET,
-                       'Departure_X_mm': DEFSET,
-                       'Departure_Y_mm': DEFSET,
-                       'Departure_Z_mm': DEFSET,
-                       'Wipe_X_mm': DEFSET,
-                       'Wipe_Y_mm': DEFSET,
-                       'Wipe_Z_mm': DEFSET,
-                       'Wipe_Period_layers': DEFSET,
-               },'oozebane': {
-                       'Activate_Oozebane': "False",
-                       'After_Startup_Distance_millimeters': DEFSET,
-                       'Early_Shutdown_Distance_millimeters': DEFSET,
-                       'Early_Startup_Distance_Constant_millimeters': DEFSET,
-                       'Early_Startup_Maximum_Distance_millimeters': DEFSET,
-                       'First_Early_Startup_Distance_millimeters': DEFSET,
-                       'Minimum_Distance_for_Early_Startup_millimeters': DEFSET,
-                       'Minimum_Distance_for_Early_Shutdown_millimeters': DEFSET,
-                       'Slowdown_Startup_Steps_positive_integer': DEFSET,
-               },'dwindle': {
-                       'Activate_Dwindle': "False",
-                       'End_Rate_Multiplier_ratio': '0.5',
-                       'Pent_Up_Volume_cubic_millimeters': "0.4",
-                       'Slowdown_Steps_positive_integer': '5',
-                       'Slowdown_Volume_cubic_millimeters': "5.0",
-               },'splodge': {
-                       'Activate_Splodge': "False",
-                       'Initial_Lift_over_Extra_Thickness_ratio': DEFSET,
-                       'Initial_Splodge_Feed_Rate_mm/s': DEFSET,
-                       'Operating_Splodge_Feed_Rate_mm/s': DEFSET,
-                       'Operating_Splodge_Quantity_Length_millimeters': DEFSET,
-                       'Initial_Splodge_Quantity_Length_millimeters': DEFSET,
-                       'Operating_Lift_over_Extra_Thickness_ratio': DEFSET,
-               },'home': {
-                       'Activate_Home': "False",
-                       'Name_of_Home_File': DEFSET,
-               },'lash': {
-                       'Activate_Lash': "False",
-                       'X_Backlash_mm': DEFSET,
-                       'Y_Backlash_mm': DEFSET,
-               },'fillet': {
-                       'Activate_Fillet': "False",
-                       'Arc_Point': DEFSET,
-                       'Arc_Radius': DEFSET,
-                       'Arc_Segment': DEFSET,
-                       'Bevel': DEFSET,
-                       'Corner_Feed_Rate_Multiplier_ratio': DEFSET,
-                       'Fillet_Radius_over_Perimeter_Width_ratio': DEFSET,
-                       'Reversal_Slowdown_Distance_over_Perimeter_Width_ratio': DEFSET,
-                       'Use_Intermediate_Feed_Rate_in_Corners': DEFSET,
-               },'limit': {
-                       'Activate_Limit': "False",
-                       'Maximum_Initial_Feed_Rate_mm/s': DEFSET,
-               },'unpause': {
-                       'Activate_Unpause': "False",
-                       'Delay_milliseconds': DEFSET,
-                       'Maximum_Speed_ratio': DEFSET,
-               },'dimension': {
-                       'Activate_Dimension': "True",
-                       'Absolute_Extrusion_Distance': "True",
-                       'Relative_Extrusion_Distance': "False",
-                       'Extruder_Retraction_Speed_mm/s': storedSettingFloat('retraction_speed'),
-                       'Filament_Diameter_mm': storedSettingFloat("filament_diameter"),
-                       'Filament_Packing_Density_ratio': storedSettingFloat("filament_density"),
-                       'Maximum_E_Value_before_Reset_float': DEFSET,
-                       'Minimum_Travel_for_Retraction_millimeters': storedSettingFloat("retraction_min_travel"),
-                       'Retract_Within_Island': storedSettingInvertBoolean("retract_on_jumps_only"),
-                       'Retraction_Distance_millimeters': lambda setting: profile.getProfileSettingFloat('retraction_amount') if profile.getProfileSetting('retraction_enable') == 'True' else 0,
-                       'Restart_Extra_Distance_millimeters': storedSettingFloat('retraction_extra'),
-               },'alteration': {
-                       'Activate_Alteration': "False",
-                       'Name_of_End_File': "end.gcode",
-                       'Name_of_Start_File': "start.gcode",
-                       'Remove_Redundant_Mcode': "True",
-                       'Replace_Variable_with_Setting': DEFSET,
-               },'export': {
-                       'Activate_Export': "True",
-                       'Add_Descriptive_Extension': DEFSET,
-                       'Add_Export_Suffix': "False",
-                       'Add_Profile_Extension': DEFSET,
-                       'Add_Timestamp_Extension': DEFSET,
-                       'Also_Send_Output_To': DEFSET,
-                       'Analyze_Gcode': DEFSET,
-                       'Comment_Choice': DEFSET,
-                       'Do_Not_Change_Output': DEFSET,
-                       'binary_16_byte': DEFSET,
-                       'gcode_step': DEFSET,
-                       'gcode_time_segment': DEFSET,
-                       'gcode_small': DEFSET,
-                       'File_Extension': storedSetting('gcode_extension'),
-                       'Name_of_Replace_File': DEFSET,
-                       'Save_Penultimate_Gcode': "False",
-               }
-       }
-
-def safeConfigName(name):
-       return name.replace("=", "").replace(":", "").replace(" ", "_").replace("(", "").replace(")", "")
-
-def getReadRepository(repository):
-       "Read the configuration for this 'repository'"
-       
-       info = getProfileInformation()
-       if not info.has_key(repository.name):
-               print("Warning: Plugin: " + repository.name + " missing from Cura info")
-               return repository
-       info = info[repository.name]
-       
-       #print('getReadRepository:', repository.name)
-       for p in repository.preferences:
-               name = safeConfigName(p.name)
-               if not info.has_key(name):
-                       print("Setting: " + repository.name + ":" + name + " missing from Cura info")
-                       continue
-               if isinstance(info[name], types.FunctionType):
-                       p.setValueToString(str(info[name](p)))
-               else:
-                       p.setValueToString(str(info[name]))
-
-       return repository
-
-def printProgress(layerIndex, procedureName):
-       print("Progress[" + procedureName + ":" + str(layerIndex+1) + "]")
-       sys.stdout.flush()
-
-def printProgressByNumber(layerIndex, numberOfLayers, procedureName):
-       print("Progress[" + procedureName + ":" + str(layerIndex+1) + ":" + str(numberOfLayers) + "]")
-       sys.stdout.flush()
-
-def getAlterationFileLines(fileName):
-       'Get the alteration file line and the text lines from the fileName in the alterations directories.'
-       return getAlterationLines(fileName)
-
-def getAlterationLines(fileName):
-       return archive.getTextLines(getAlterationFile(fileName))
-
-def getAlterationFile(fileName):
-       return profile.getAlterationFileContents(fileName)
-
-####################################
-## Configuration settings classes ##
-####################################
-
-class GeneralSetting(object):
-       "Just a basic setting subclass"
-       def getFromValue( self, name, repository, value ):
-               #print('GeneralSetting:', name, repository, value )
-               self.name = name
-               self.value = value
-               repository.preferences.append(self)
-               return self
-
-class StringSetting(GeneralSetting):
-       "A class to display, read & write a string."
-       def setValueToString(self, value):
-               self.value = value
-
-class BooleanSetting( GeneralSetting ):
-       "A class to display, read & write a boolean."
-       def setValueToString(self, value):
-               self.value = str(value) == "True"
-
-class LatentStringVar(object):
-       "This is actually used as 'group' object for Radio buttons. (Did I mention the code is a mess?)"
-       "This class doesn't have a name, and isn't really used for anything. It doesn't even know which repository it belongs to"
-
-class Radio( BooleanSetting ):
-       "A class to display, read & write a boolean with associated radio button."
-       def getFromRadio( self, latentStringVar, name, repository, value ):
-               "Initialize."
-               #print('Radio->getFromRadio:', latentStringVar, name, repository, value )
-               self.name = name
-               self.value = value
-               repository.preferences.append(self)
-               return self
-
-class RadioCapitalized( Radio ):
-       "A class to display, read & write a boolean with associated radio button."
-
-class RadioCapitalizedButton( Radio ):
-       "A class to display, read & write a boolean with associated radio button. With an added configuration dialog button"
-       "Only used for the extra export options, which we are not using, so ignore the path for now"
-       def getFromPath( self, latentStringVar, name, path, repository, value ):
-               "Initialize."
-               #print('RadioCapitalizedButton->getFromPath:', latentStringVar, name, path, repository, value )
-               self.name = name
-               self.value = value
-               repository.preferences.append(self)
-               return self
-               
-class FileNameInput(StringSetting):
-       "A class to display, read & write a fileName."
-       def getFromFileName( self, fileTypes, name, repository, value ):
-               #print('FileNameInput:getFromFileName:', self, fileTypes, name, repository, value )
-               self.name = name
-               self.value = value
-               return self
-
-class HelpPage(object):
-       "A class to open a help page."
-       def getOpenFromAbsolute( self, hypertextAddress ):
-               return self
-
-class MenuButtonDisplay(object):
-       "A class to add a combo box selection."
-       def getFromName( self, name, repository ):
-               #print('MenuButtonDisplay->getFromName:', name, repository )
-               self.name = name
-               self.value = "ERROR"
-               self.radioList = []
-               repository.preferences.append(self)
-               return self
-       
-       def addRadio(self, radio, default):
-               if default:
-                       self.value = radio.name
-               self.radioList.append(radio)
-       
-       def setValueToString(self, value):
-               valueFound = False
-               for radio in self.radioList:
-                       if radio.name == value:
-                               valueFound = True
-               if valueFound:
-                       self.value = value
-                       for radio in self.radioList:
-                               radio.value = (radio.name == value)
-
-class MenuRadio( BooleanSetting ):
-       "A class to display, read & write a boolean with associated combo box selection."
-       def getFromMenuButtonDisplay( self, menuButtonDisplay, name, repository, value ):
-               "Initialize."
-               #print('MenuRadio->getFromMenuButtonDisplay:', menuButtonDisplay, name, repository, value )
-               self.name = name
-               self.value = value
-               menuButtonDisplay.addRadio(self, value)
-               return self
-
-class LabelDisplay(object):
-       "A class to add a label."
-       def getFromName( self, name, repository ):
-               "Initialize."
-               return self
-
-class FloatSetting(GeneralSetting):
-       "A class to display, read & write a float."
-       def setValueToString(self, value):
-               self.value = float(value)
-
-class FloatSpin( FloatSetting ):
-       "A class to display, read & write an float in a spin box."
-       def getFromValue(self, from_, name, repository, to, value):
-               "Initialize."
-               self.name = name
-               self.value = value
-               if repository != None:
-                       repository.preferences.append(self)
-               return self
-
-class LabelSeparator(object):
-       "A class to add a label and menu separator."
-       def getFromRepository( self, repository ):
-               "Initialize."
-               return self
-
-class IntSpin(FloatSpin):
-       "A class to display, read & write an int in a spin box."
-       def getSingleIncrementFromValue( self, from_, name, repository, to, value ):
-               "Initialize."
-               self.name = name
-               self.value = value
-               repository.preferences.append(self)
-               return self
-
-       def setValueToString(self, value):
-               self.value = int(value)
-
-##########################
-# Helper classes
-##########################
-
-class LayerCount(object):
-       'A class to handle the layerIndex.'
-       def __init__(self):
-               'Initialize.'
-               self.layerIndex = -1
-
-       def __repr__(self):
-               'Get the string representation of this LayerCount.'
-               return str(self.layerIndex)
-
-       def printProgressIncrement(self, procedureName):
-               'Print progress then increment layerIndex.'
-               self.layerIndex += 1
-               printProgress(self.layerIndex, procedureName)
-
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/svg_reader.py b/Cura/slice/cura_sf/fabmetheus_utilities/svg_reader.py
deleted file mode 100644 (file)
index 03846c9..0000000
+++ /dev/null
@@ -1,952 +0,0 @@
-"""
-Svg reader.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.xml_simple_reader import DocumentNode
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import intercircle
-from fabmetheus_utilities import settings
-from fabmetheus_utilities import svg_writer
-import math
-import os
-import sys
-import traceback
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalNumberOfCornerPoints = 11
-globalNumberOfBezierPoints = globalNumberOfCornerPoints + globalNumberOfCornerPoints
-globalNumberOfCirclePoints = 4 * globalNumberOfCornerPoints
-
-
-def addFunctionsToDictionary( dictionary, functions, prefix ):
-       "Add functions to dictionary."
-       for function in functions:
-               dictionary[ function.__name__[ len( prefix ) : ] ] = function
-
-def getArcComplexes(begin, end, largeArcFlag, radius, sweepFlag, xAxisRotation):
-       'Get the arc complexes, procedure at http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes'
-       if begin == end:
-               print('Warning, begin equals end in getArcComplexes in svgReader')
-               print(begin)
-               print(end)
-               return []
-       if radius.imag < 0.0:
-               print('Warning, radius.imag is less than zero in getArcComplexes in svgReader')
-               print(radius)
-               radius = complex(radius.real, abs(radius.imag))
-       if radius.real < 0.0:
-               print('Warning, radius.real is less than zero in getArcComplexes in svgReader')
-               print(radius)
-               radius = complex(abs(radius.real), radius.imag)
-       if radius.imag <= 0.0:
-               print('Warning, radius.imag is too small for getArcComplexes in svgReader')
-               print(radius)
-               return [end]
-       if radius.real <= 0.0:
-               print('Warning, radius.real is too small for getArcComplexes in svgReader')
-               print(radius)
-               return [end]
-       xAxisRotationComplex = euclidean.getWiddershinsUnitPolar(xAxisRotation)
-       reverseXAxisRotationComplex = complex(xAxisRotationComplex.real, -xAxisRotationComplex.imag)
-       beginRotated = begin * reverseXAxisRotationComplex
-       endRotated = end * reverseXAxisRotationComplex
-       beginTransformed = complex(beginRotated.real / radius.real, beginRotated.imag / radius.imag)
-       endTransformed = complex(endRotated.real / radius.real, endRotated.imag / radius.imag)
-       midpointTransformed = 0.5 * (beginTransformed + endTransformed)
-       midMinusBeginTransformed = midpointTransformed - beginTransformed
-       midMinusBeginTransformedLength = abs(midMinusBeginTransformed)
-       if midMinusBeginTransformedLength > 1.0:
-               print('The ellipse radius is too small for getArcComplexes in svgReader.')
-               print('So the ellipse will be scaled to fit, according to the formulas in "Step 3: Ensure radii are large enough" of:')
-               print('http://www.w3.org/TR/SVG/implnote.html#ArcCorrectionOutOfRangeRadii')
-               print('')
-               radius *= midMinusBeginTransformedLength
-               beginTransformed /= midMinusBeginTransformedLength
-               endTransformed /= midMinusBeginTransformedLength
-               midpointTransformed /= midMinusBeginTransformedLength
-               midMinusBeginTransformed /= midMinusBeginTransformedLength
-               midMinusBeginTransformedLength = 1.0
-       midWiddershinsTransformed = complex(-midMinusBeginTransformed.imag, midMinusBeginTransformed.real)
-       midWiddershinsLengthSquared = 1.0 - midMinusBeginTransformedLength * midMinusBeginTransformedLength
-       if midWiddershinsLengthSquared < 0.0:
-               midWiddershinsLengthSquared = 0.0
-       midWiddershinsLength = math.sqrt(midWiddershinsLengthSquared)
-       midWiddershinsTransformed *= midWiddershinsLength / abs(midWiddershinsTransformed)
-       centerTransformed = midpointTransformed
-       if largeArcFlag == sweepFlag:
-               centerTransformed -= midWiddershinsTransformed
-       else:
-               centerTransformed += midWiddershinsTransformed
-       beginMinusCenterTransformed = beginTransformed - centerTransformed
-       beginMinusCenterTransformedLength = abs(beginMinusCenterTransformed)
-       if beginMinusCenterTransformedLength <= 0.0:
-               return end
-       beginAngle = math.atan2(beginMinusCenterTransformed.imag, beginMinusCenterTransformed.real)
-       endMinusCenterTransformed = endTransformed - centerTransformed
-       angleDifference = euclidean.getAngleDifferenceByComplex(endMinusCenterTransformed, beginMinusCenterTransformed)
-       if sweepFlag:
-               if angleDifference < 0.0:
-                       angleDifference += 2.0 * math.pi
-       else:
-               if angleDifference > 0.0:
-                       angleDifference -= 2.0 * math.pi
-       global globalSideAngle
-       sides = int(math.ceil(abs(angleDifference) / globalSideAngle))
-       sideAngle = angleDifference / float(sides)
-       arcComplexes = []
-       center = complex(centerTransformed.real * radius.real, centerTransformed.imag * radius.imag) * xAxisRotationComplex
-       for side in xrange(1, sides):
-               unitPolar = euclidean.getWiddershinsUnitPolar(beginAngle + float(side) * sideAngle)
-               circumferential = complex(unitPolar.real * radius.real, unitPolar.imag * radius.imag) * beginMinusCenterTransformedLength
-               point = center + circumferential * xAxisRotationComplex
-               arcComplexes.append(point)
-       arcComplexes.append(end)
-       return arcComplexes
-
-def getChainMatrixSVG(elementNode, matrixSVG):
-       "Get chain matrixSVG by svgElement."
-       matrixSVG = matrixSVG.getOtherTimesSelf(getMatrixSVG(elementNode).tricomplex)
-       if elementNode.parentNode != None:
-               matrixSVG = getChainMatrixSVG(elementNode.parentNode, matrixSVG)
-       return matrixSVG
-
-def getChainMatrixSVGIfNecessary(elementNode, yAxisPointingUpward):
-       "Get chain matrixSVG by svgElement and yAxisPointingUpward."
-       matrixSVG = MatrixSVG()
-       if yAxisPointingUpward:
-               return matrixSVG
-       return getChainMatrixSVG(elementNode, matrixSVG)
-
-def getCubicPoint( along, begin, controlPoints, end ):
-       'Get the cubic point.'
-       segmentBegin = getQuadraticPoint( along, begin, controlPoints[0], controlPoints[1] )
-       segmentEnd = getQuadraticPoint( along, controlPoints[0], controlPoints[1], end )
-       return ( 1.0 - along ) * segmentBegin + along * segmentEnd
-
-def getCubicPoints( begin, controlPoints, end, numberOfBezierPoints=globalNumberOfBezierPoints):
-       'Get the cubic points.'
-       bezierPortion = 1.0 / float(numberOfBezierPoints)
-       cubicPoints = []
-       for bezierIndex in xrange( 1, numberOfBezierPoints + 1 ):
-               cubicPoints.append(getCubicPoint(bezierPortion * bezierIndex, begin, controlPoints, end))
-       return cubicPoints
-
-def getFontReader(fontFamily):
-       'Get the font reader for the fontFamily.'
-       fontLower = fontFamily.lower().replace(' ', '_')
-       global globalFontReaderDictionary
-       if fontLower in globalFontReaderDictionary:
-               return globalFontReaderDictionary[fontLower]
-       global globalFontFileNames
-       if globalFontFileNames == None:
-               globalFontFileNames = archive.getFileNamesByFilePaths(archive.getFilePathsByDirectory(getFontsDirectoryPath()))
-       if fontLower not in globalFontFileNames:
-               print('Warning, the %s font was not found in the fabmetheus_utilities/fonts folder, so Gentium Basic Regular will be substituted.' % fontFamily)
-               print('The available fonts are:')
-               globalFontFileNames.sort()
-               print(globalFontFileNames)
-               print('')
-               fontLower = 'gentium_basic_regular'
-       fontReader = FontReader(fontLower)
-       globalFontReaderDictionary[fontLower] = fontReader
-       return fontReader
-
-def getFontsDirectoryPath():
-       "Get the fonts directory path."
-       return archive.getFabmetheusUtilitiesPath('fonts')
-
-def getLabelString(dictionary):
-       "Get the label string for the dictionary."
-       for key in dictionary:
-               labelIndex = key.find('label')
-               if labelIndex >= 0:
-                       return dictionary[key]
-       return ''
-
-def getMatrixSVG(elementNode):
-       "Get matrixSVG by svgElement."
-       matrixSVG = MatrixSVG()
-       if 'transform' not in elementNode.attributes:
-               return matrixSVG
-       transformWords = []
-       for transformWord in elementNode.attributes['transform'].replace(')', '(').split('('):
-               transformWordStrip = transformWord.strip()
-               if transformWordStrip != '': # workaround for split(character) bug which leaves an extra empty element
-                       transformWords.append(transformWordStrip)
-       global globalGetTricomplexDictionary
-       getTricomplexDictionaryKeys = globalGetTricomplexDictionary.keys()
-       for transformWordIndex, transformWord in enumerate(transformWords):
-               if transformWord in getTricomplexDictionaryKeys:
-                       transformString = transformWords[transformWordIndex + 1].replace(',', ' ')
-                       matrixSVG = matrixSVG.getSelfTimesOther(globalGetTricomplexDictionary[ transformWord ](transformString.split()))
-       return matrixSVG
-
-def getQuadraticPoint( along, begin, controlPoint, end ):
-       'Get the quadratic point.'
-       oneMinusAlong = 1.0 - along
-       segmentBegin = oneMinusAlong * begin + along * controlPoint
-       segmentEnd = oneMinusAlong * controlPoint + along * end
-       return oneMinusAlong * segmentBegin + along * segmentEnd
-
-def getQuadraticPoints(begin, controlPoint, end, numberOfBezierPoints=globalNumberOfBezierPoints):
-       'Get the quadratic points.'
-       bezierPortion = 1.0 / float(numberOfBezierPoints)
-       quadraticPoints = []
-       for bezierIndex in xrange(1, numberOfBezierPoints + 1):
-               quadraticPoints.append(getQuadraticPoint(bezierPortion * bezierIndex, begin, controlPoint, end))
-       return quadraticPoints
-
-def getRightStripAlphabetPercent(word):
-       "Get word with alphabet characters and the percent sign stripped from the right."
-       word = word.strip()
-       for characterIndex in xrange(len(word) - 1, -1, -1):
-               character = word[characterIndex]
-               if not character.isalpha() and not character == '%':
-                       return float(word[: characterIndex + 1])
-       return None
-
-def getRightStripMinusSplit(lineString):
-       "Get string with spaces after the minus sign stripped."
-       oldLineStringLength = -1
-       while oldLineStringLength < len(lineString):
-               oldLineStringLength = len(lineString)
-               lineString = lineString.replace('- ', '-')
-       return lineString.split()
-
-def getStrokeRadius(elementNode):
-       "Get the stroke radius."
-       return 0.5 * getRightStripAlphabetPercent(getStyleValue('1.0', elementNode, 'stroke-width'))
-
-def getStyleValue(defaultValue, elementNode, key):
-       "Get the stroke value string."
-       if 'style' in elementNode.attributes:
-               line = elementNode.attributes['style']
-               strokeIndex = line.find(key)
-               if strokeIndex > -1:
-                       words = line[strokeIndex :].replace(':', ' ').replace(';', ' ').split()
-                       if len(words) > 1:
-                               return words[1]
-       if key in elementNode.attributes:
-               return elementNode.attributes[key]
-       if elementNode.parentNode == None:
-               return defaultValue
-       return getStyleValue(defaultValue, elementNode.parentNode, key)
-
-def getTextComplexLoops(fontFamily, fontSize, text, yAxisPointingUpward=True):
-       "Get text as complex loops."
-       textComplexLoops = []
-       fontReader = getFontReader(fontFamily)
-       horizontalAdvanceX = 0.0
-       for character in text:
-               glyph = fontReader.getGlyph(character, yAxisPointingUpward)
-               textComplexLoops += glyph.getSizedAdvancedLoops(fontSize, horizontalAdvanceX, yAxisPointingUpward)
-               horizontalAdvanceX += glyph.horizontalAdvanceX
-       return textComplexLoops
-
-def getTransformedFillOutline(elementNode, loop, yAxisPointingUpward):
-       "Get the loops if fill is on, otherwise get the outlines."
-       fillOutlineLoops = None
-       if getStyleValue('none', elementNode, 'fill').lower() == 'none':
-               fillOutlineLoops = intercircle.getAroundsFromLoop(loop, getStrokeRadius(elementNode))
-       else:
-               fillOutlineLoops = [loop]
-       return getChainMatrixSVGIfNecessary(elementNode, yAxisPointingUpward).getTransformedPaths(fillOutlineLoops)
-
-def getTransformedOutlineByPath(elementNode, path, yAxisPointingUpward):
-       "Get the outline from the path."
-       aroundsFromPath = intercircle.getAroundsFromPath(path, getStrokeRadius(elementNode))
-       return getChainMatrixSVGIfNecessary(elementNode, yAxisPointingUpward).getTransformedPaths(aroundsFromPath)
-
-def getTransformedOutlineByPaths(elementNode, paths, yAxisPointingUpward):
-       "Get the outline from the paths."
-       aroundsFromPaths = intercircle.getAroundsFromPaths(paths, getStrokeRadius(elementNode))
-       return getChainMatrixSVGIfNecessary(elementNode, yAxisPointingUpward).getTransformedPaths(aroundsFromPaths)
-
-def getTricomplexmatrix(transformWords):
-       "Get matrixSVG by transformWords."
-       tricomplex = [euclidean.getComplexByWords(transformWords)]
-       tricomplex.append(euclidean.getComplexByWords(transformWords, 2))
-       tricomplex.append(euclidean.getComplexByWords(transformWords, 4))
-       return tricomplex
-
-def getTricomplexrotate(transformWords):
-       "Get matrixSVG by transformWords."
-       rotate = euclidean.getWiddershinsUnitPolar(math.radians(float(transformWords[0])))
-       return [rotate, complex(-rotate.imag,rotate.real), complex()]
-
-def getTricomplexscale(transformWords):
-       "Get matrixSVG by transformWords."
-       scale = euclidean.getComplexByWords(transformWords)
-       return [complex(scale.real,0.0), complex(0.0,scale.imag), complex()]
-
-def getTricomplexskewX(transformWords):
-       "Get matrixSVG by transformWords."
-       skewX = math.tan(math.radians(float(transformWords[0])))
-       return [complex(1.0, 0.0), complex(skewX, 1.0), complex()]
-
-def getTricomplexskewY(transformWords):
-       "Get matrixSVG by transformWords."
-       skewY = math.tan(math.radians(float(transformWords[0])))
-       return [complex(1.0, skewY), complex(0.0, 1.0), complex()]
-
-def getTricomplexTimesColumn(firstTricomplex, otherColumn):
-       "Get this matrix multiplied by the otherColumn."
-       dotProductX = firstTricomplex[0].real * otherColumn.real + firstTricomplex[1].real * otherColumn.imag
-       dotProductY = firstTricomplex[0].imag * otherColumn.real + firstTricomplex[1].imag * otherColumn.imag
-       return complex(dotProductX, dotProductY)
-
-def getTricomplexTimesOther(firstTricomplex, otherTricomplex):
-       "Get the first tricomplex multiplied by the other tricomplex."
-       #A down, B right from http://en.wikipedia.org/wiki/Matrix_multiplication
-       tricomplexTimesOther = [getTricomplexTimesColumn(firstTricomplex, otherTricomplex[0])]
-       tricomplexTimesOther.append(getTricomplexTimesColumn(firstTricomplex, otherTricomplex[1]))
-       tricomplexTimesOther.append(getTricomplexTimesColumn(firstTricomplex, otherTricomplex[2]) + firstTricomplex[2])
-       return tricomplexTimesOther
-
-def getTricomplextranslate(transformWords):
-       "Get matrixSVG by transformWords."
-       translate = euclidean.getComplexByWords(transformWords)
-       return [complex(1.0, 0.0), complex(0.0, 1.0), translate]
-
-def processSVGElementcircle( elementNode, svgReader ):
-       "Process elementNode by svgReader."
-       attributes = elementNode.attributes
-       center = euclidean.getComplexDefaultByDictionaryKeys( complex(), attributes, 'cx', 'cy')
-       radius = euclidean.getFloatDefaultByDictionary( 0.0, attributes, 'r')
-       if radius == 0.0:
-               print('Warning, in processSVGElementcircle in svgReader radius is zero in:')
-               print(attributes)
-               return
-       global globalNumberOfCirclePoints
-       global globalSideAngle
-       loop = []
-       loopLayer = svgReader.getLoopLayer()
-       for side in xrange( globalNumberOfCirclePoints ):
-               unitPolar = euclidean.getWiddershinsUnitPolar( float(side) * globalSideAngle )
-               loop.append( center + radius * unitPolar )
-       loopLayer.loops += getTransformedFillOutline(elementNode, loop, svgReader.yAxisPointingUpward)
-
-def processSVGElementellipse( elementNode, svgReader ):
-       "Process elementNode by svgReader."
-       attributes = elementNode.attributes
-       center = euclidean.getComplexDefaultByDictionaryKeys( complex(), attributes, 'cx', 'cy')
-       radius = euclidean.getComplexDefaultByDictionaryKeys( complex(), attributes, 'rx', 'ry')
-       if radius.real == 0.0 or radius.imag == 0.0:
-               print('Warning, in processSVGElementellipse in svgReader radius is zero in:')
-               print(attributes)
-               return
-       global globalNumberOfCirclePoints
-       global globalSideAngle
-       loop = []
-       loopLayer = svgReader.getLoopLayer()
-       for side in xrange( globalNumberOfCirclePoints ):
-               unitPolar = euclidean.getWiddershinsUnitPolar( float(side) * globalSideAngle )
-               loop.append( center + complex( unitPolar.real * radius.real, unitPolar.imag * radius.imag ) )
-       loopLayer.loops += getTransformedFillOutline(elementNode, loop, svgReader.yAxisPointingUpward)
-
-def processSVGElementg(elementNode, svgReader):
-       'Process elementNode by svgReader.'
-       if 'id' not in elementNode.attributes:
-               return
-       idString = elementNode.attributes['id']
-       if 'beginningOfControlSection' in elementNode.attributes:
-               if elementNode.attributes['beginningOfControlSection'].lower()[: 1] == 't':
-                       svgReader.stopProcessing = True
-               return
-       idStringLower = idString.lower()
-       zIndex = idStringLower.find('z:')
-       if zIndex < 0:
-               idStringLower = getLabelString(elementNode.attributes)
-               zIndex = idStringLower.find('z:')
-       if zIndex < 0:
-               return
-       floatFromValue = euclidean.getFloatFromValue(idStringLower[zIndex + len('z:') :].strip())
-       if floatFromValue != None:
-               svgReader.z = floatFromValue
-
-def processSVGElementline(elementNode, svgReader):
-       "Process elementNode by svgReader."
-       begin = euclidean.getComplexDefaultByDictionaryKeys(complex(), elementNode.attributes, 'x1', 'y1')
-       end = euclidean.getComplexDefaultByDictionaryKeys(complex(), elementNode.attributes, 'x2', 'y2')
-       loopLayer = svgReader.getLoopLayer()
-       loopLayer.loops += getTransformedOutlineByPath(elementNode, [begin, end], svgReader.yAxisPointingUpward)
-
-def processSVGElementpath( elementNode, svgReader ):
-       "Process elementNode by svgReader."
-       if 'd' not in elementNode.attributes:
-               print('Warning, in processSVGElementpath in svgReader can not get a value for d in:')
-               print(elementNode.attributes)
-               return
-       loopLayer = svgReader.getLoopLayer()
-       PathReader(elementNode, loopLayer.loops, svgReader.yAxisPointingUpward)
-
-def processSVGElementpolygon( elementNode, svgReader ):
-       "Process elementNode by svgReader."
-       if 'points' not in elementNode.attributes:
-               print('Warning, in processSVGElementpolygon in svgReader can not get a value for d in:')
-               print(elementNode.attributes)
-               return
-       loopLayer = svgReader.getLoopLayer()
-       words = getRightStripMinusSplit(elementNode.attributes['points'].replace(',', ' '))
-       loop = []
-       for wordIndex in xrange( 0, len(words), 2 ):
-               loop.append(euclidean.getComplexByWords(words[wordIndex :]))
-       loopLayer.loops += getTransformedFillOutline(elementNode, loop, svgReader.yAxisPointingUpward)
-
-def processSVGElementpolyline(elementNode, svgReader):
-       "Process elementNode by svgReader."
-       if 'points' not in elementNode.attributes:
-               print('Warning, in processSVGElementpolyline in svgReader can not get a value for d in:')
-               print(elementNode.attributes)
-               return
-       loopLayer = svgReader.getLoopLayer()
-       words = getRightStripMinusSplit(elementNode.attributes['points'].replace(',', ' '))
-       path = []
-       for wordIndex in xrange(0, len(words), 2):
-               path.append(euclidean.getComplexByWords(words[wordIndex :]))
-       loopLayer.loops += getTransformedOutlineByPath(elementNode, path, svgReader.yAxisPointingUpward)
-
-def processSVGElementrect( elementNode, svgReader ):
-       "Process elementNode by svgReader."
-       attributes = elementNode.attributes
-       height = euclidean.getFloatDefaultByDictionary( 0.0, attributes, 'height')
-       if height == 0.0:
-               print('Warning, in processSVGElementrect in svgReader height is zero in:')
-               print(attributes)
-               return
-       width = euclidean.getFloatDefaultByDictionary( 0.0, attributes, 'width')
-       if width == 0.0:
-               print('Warning, in processSVGElementrect in svgReader width is zero in:')
-               print(attributes)
-               return
-       center = euclidean.getComplexDefaultByDictionaryKeys(complex(), attributes, 'x', 'y')
-       inradius = 0.5 * complex( width, height )
-       cornerRadius = euclidean.getComplexDefaultByDictionaryKeys( complex(), attributes, 'rx', 'ry')
-       loopLayer = svgReader.getLoopLayer()
-       if cornerRadius.real == 0.0 and cornerRadius.imag == 0.0:
-               inradiusMinusX = complex( - inradius.real, inradius.imag )
-               loop = [center + inradius, center + inradiusMinusX, center - inradius, center - inradiusMinusX]
-               loopLayer.loops += getTransformedFillOutline(elementNode, loop, svgReader.yAxisPointingUpward)
-               return
-       if cornerRadius.real == 0.0:
-               cornerRadius = complex( cornerRadius.imag, cornerRadius.imag )
-       elif cornerRadius.imag == 0.0:
-               cornerRadius = complex( cornerRadius.real, cornerRadius.real )
-       cornerRadius = complex( min( cornerRadius.real, inradius.real ), min( cornerRadius.imag, inradius.imag ) )
-       ellipsePath = [ complex( cornerRadius.real, 0.0 ) ]
-       inradiusMinusCorner = inradius - cornerRadius
-       loop = []
-       global globalNumberOfCornerPoints
-       global globalSideAngle
-       for side in xrange( 1, globalNumberOfCornerPoints ):
-               unitPolar = euclidean.getWiddershinsUnitPolar( float(side) * globalSideAngle )
-               ellipsePath.append( complex( unitPolar.real * cornerRadius.real, unitPolar.imag * cornerRadius.imag ) )
-       ellipsePath.append( complex( 0.0, cornerRadius.imag ) )
-       cornerPoints = []
-       for point in ellipsePath:
-               cornerPoints.append( point + inradiusMinusCorner )
-       cornerPointsReversed = cornerPoints[: : -1]
-       for cornerPoint in cornerPoints:
-               loop.append( center + cornerPoint )
-       for cornerPoint in cornerPointsReversed:
-               loop.append( center + complex( - cornerPoint.real, cornerPoint.imag ) )
-       for cornerPoint in cornerPoints:
-               loop.append( center - cornerPoint )
-       for cornerPoint in cornerPointsReversed:
-               loop.append( center + complex( cornerPoint.real, - cornerPoint.imag ) )
-       loop = euclidean.getLoopWithoutCloseSequentialPoints( 0.0001 * abs(inradius), loop )
-       loopLayer.loops += getTransformedFillOutline(elementNode, loop, svgReader.yAxisPointingUpward)
-
-def processSVGElementtext(elementNode, svgReader):
-       "Process elementNode by svgReader."
-       if svgReader.yAxisPointingUpward:
-               return
-       fontFamily = getStyleValue('Gentium Basic Regular', elementNode, 'font-family')
-       fontSize = getRightStripAlphabetPercent(getStyleValue('12.0', elementNode, 'font-size'))
-       matrixSVG = getChainMatrixSVGIfNecessary(elementNode, svgReader.yAxisPointingUpward)
-       loopLayer = svgReader.getLoopLayer()
-       translate = euclidean.getComplexDefaultByDictionaryKeys(complex(), elementNode.attributes, 'x', 'y')
-       for textComplexLoop in getTextComplexLoops(fontFamily, fontSize, elementNode.getTextContent(), svgReader.yAxisPointingUpward):
-               translatedLoop = []
-               for textComplexPoint in textComplexLoop:
-                       translatedLoop.append(textComplexPoint + translate )
-               loopLayer.loops.append(matrixSVG.getTransformedPath(translatedLoop))
-
-
-class FontReader(object):
-       "Class to read a font in the fonts folder."
-       def __init__(self, fontFamily):
-               "Initialize."
-               self.fontFamily = fontFamily
-               self.glyphDictionary = {}
-               self.glyphElementNodeDictionary = {}
-               self.missingGlyph = None
-               fileName = os.path.join(getFontsDirectoryPath(), fontFamily + '.svg')
-               documentElement = DocumentNode(fileName, archive.getFileText(fileName)).getDocumentElement()
-               self.fontElementNode = documentElement.getFirstChildByLocalName('defs').getFirstChildByLocalName('font')
-               self.fontFaceElementNode = self.fontElementNode.getFirstChildByLocalName('font-face')
-               self.unitsPerEM = float(self.fontFaceElementNode.attributes['units-per-em'])
-               glyphElementNodes = self.fontElementNode.getChildElementsByLocalName('glyph')
-               for glyphElementNode in glyphElementNodes:
-                       self.glyphElementNodeDictionary[glyphElementNode.attributes['unicode']] = glyphElementNode
-
-       def getGlyph(self, character, yAxisPointingUpward):
-               "Get the glyph for the character."
-               if character not in self.glyphElementNodeDictionary:
-                       if self.missingGlyph == None:
-                               missingGlyphElementNode = self.fontElementNode.getFirstChildByLocalName('missing-glyph')
-                               self.missingGlyph = Glyph(missingGlyphElementNode, self.unitsPerEM, yAxisPointingUpward)
-                       return self.missingGlyph
-               if character not in self.glyphDictionary:
-                       self.glyphDictionary[character] = Glyph(self.glyphElementNodeDictionary[character], self.unitsPerEM, yAxisPointingUpward)
-               return self.glyphDictionary[character]
-
-
-class Glyph(object):
-       "Class to handle a glyph."
-       def __init__(self, elementNode, unitsPerEM, yAxisPointingUpward):
-               "Initialize."
-               self.horizontalAdvanceX = float(elementNode.attributes['horiz-adv-x'])
-               self.loops = []
-               self.unitsPerEM = unitsPerEM
-               elementNode.attributes['fill'] = ''
-               if 'd' not in elementNode.attributes:
-                       return
-               PathReader(elementNode, self.loops, yAxisPointingUpward)
-
-       def getSizedAdvancedLoops(self, fontSize, horizontalAdvanceX, yAxisPointingUpward=True):
-               "Get loops for font size, advanced horizontally."
-               multiplierX = fontSize / self.unitsPerEM
-               multiplierY = multiplierX
-               if not yAxisPointingUpward:
-                       multiplierY = -multiplierY
-               sizedLoops = []
-               for loop in self.loops:
-                       sizedLoop = []
-                       sizedLoops.append(sizedLoop)
-                       for point in loop:
-                               sizedLoop.append( complex(multiplierX * (point.real + horizontalAdvanceX), multiplierY * point.imag))
-               return sizedLoops
-
-
-class MatrixSVG(object):
-       "Two by three svg matrix."
-       def __init__(self, tricomplex=None):
-               "Initialize."
-               self.tricomplex = tricomplex
-
-       def __repr__(self):
-               "Get the string representation of this two by three svg matrix."
-               return str(self.tricomplex)
-
-       def getOtherTimesSelf(self, otherTricomplex):
-               "Get the other matrix multiplied by this matrix."
-               if otherTricomplex == None:
-                       return MatrixSVG(self.tricomplex)
-               if self.tricomplex == None:
-                       return MatrixSVG(otherTricomplex)
-               return MatrixSVG(getTricomplexTimesOther(otherTricomplex, self.tricomplex))
-
-       def getSelfTimesOther(self, otherTricomplex):
-               "Get this matrix multiplied by the other matrix."
-               if otherTricomplex == None:
-                       return MatrixSVG(self.tricomplex)
-               if self.tricomplex == None:
-                       return MatrixSVG(otherTricomplex)
-               return MatrixSVG(getTricomplexTimesOther(self.tricomplex, otherTricomplex))
-
-       def getTransformedPath(self, path):
-               "Get transformed path."
-               if self.tricomplex == None:
-                       return path
-               complexX = self.tricomplex[0]
-               complexY = self.tricomplex[1]
-               complexTranslation = self.tricomplex[2]
-               transformedPath = []
-               for point in path:
-                       x = complexX.real * point.real + complexY.real * point.imag
-                       y = complexX.imag * point.real + complexY.imag * point.imag
-                       transformedPath.append(complex(x, y) + complexTranslation)
-               return transformedPath
-
-       def getTransformedPaths(self, paths):
-               "Get transformed paths."
-               if self.tricomplex == None:
-                       return paths
-               transformedPaths = []
-               for path in paths:
-                       transformedPaths.append(self.getTransformedPath(path))
-               return transformedPaths
-
-
-class PathReader(object):
-       "Class to read svg path."
-       def __init__(self, elementNode, loops, yAxisPointingUpward):
-               "Add to path string to loops."
-               self.controlPoints = None
-               self.elementNode = elementNode
-               self.loops = loops
-               self.oldPoint = None
-               self.outlinePaths = []
-               self.path = []
-               self.yAxisPointingUpward = yAxisPointingUpward
-               pathString = elementNode.attributes['d'].replace(',', ' ')
-               global globalProcessPathWordDictionary
-               processPathWordDictionaryKeys = globalProcessPathWordDictionary.keys()
-               for processPathWordDictionaryKey in processPathWordDictionaryKeys:
-                       pathString = pathString.replace( processPathWordDictionaryKey, ' %s ' % processPathWordDictionaryKey )
-               self.words = getRightStripMinusSplit(pathString)
-               for self.wordIndex in xrange( len( self.words ) ):
-                       word = self.words[ self.wordIndex ]
-                       if word in processPathWordDictionaryKeys:
-                               globalProcessPathWordDictionary[word](self)
-               if len(self.path) > 0:
-                       self.outlinePaths.append(self.path)
-               self.loops += getTransformedOutlineByPaths(elementNode, self.outlinePaths, yAxisPointingUpward)
-
-       def addPathArc( self, end ):
-               "Add an arc to the path."
-               begin = self.getOldPoint()
-               self.controlPoints = None
-               radius = self.getComplexByExtraIndex(1)
-               xAxisRotation = math.radians(float(self.words[self.wordIndex + 3]))
-               largeArcFlag = euclidean.getBooleanFromValue(self.words[ self.wordIndex + 4 ])
-               sweepFlag = euclidean.getBooleanFromValue(self.words[ self.wordIndex + 5 ])
-               self.path += getArcComplexes(begin, end, largeArcFlag, radius, sweepFlag, xAxisRotation)
-               self.wordIndex += 8
-
-       def addPathCubic( self, controlPoints, end ):
-               "Add a cubic curve to the path."
-               begin = self.getOldPoint()
-               self.controlPoints = controlPoints
-               self.path += getCubicPoints( begin, controlPoints, end )
-               self.wordIndex += 7
-
-       def addPathCubicReflected( self, controlPoint, end ):
-               "Add a cubic curve to the path from a reflected control point."
-               begin = self.getOldPoint()
-               controlPointBegin = begin
-               if self.controlPoints != None:
-                       if len(self.controlPoints) == 2:
-                               controlPointBegin = begin + begin - self.controlPoints[-1]
-               self.controlPoints = [controlPointBegin, controlPoint]
-               self.path += getCubicPoints(begin, self.controlPoints, end)
-               self.wordIndex += 5
-
-       def addPathLine(self, lineFunction, point):
-               "Add a line to the path."
-               self.controlPoints = None
-               self.path.append(point)
-               self.wordIndex += 3
-               self.addPathLineByFunction(lineFunction)
-
-       def addPathLineAxis(self, point):
-               "Add an axis line to the path."
-               self.controlPoints = None
-               self.path.append(point)
-               self.wordIndex += 2
-
-       def addPathLineByFunction( self, lineFunction ):
-               "Add a line to the path by line function."
-               while 1:
-                       if self.getFloatByExtraIndex() == None:
-                               return
-                       self.path.append(lineFunction())
-                       self.wordIndex += 2
-
-       def addPathMove( self, lineFunction, point ):
-               "Add an axis line to the path."
-               self.controlPoints = None
-               if len(self.path) > 0:
-                       self.outlinePaths.append(self.path)
-                       self.oldPoint = self.path[-1]
-               self.path = [point]
-               self.wordIndex += 3
-               self.addPathLineByFunction(lineFunction)
-
-       def addPathQuadratic( self, controlPoint, end ):
-               "Add a quadratic curve to the path."
-               begin = self.getOldPoint()
-               self.controlPoints = [controlPoint]
-               self.path += getQuadraticPoints(begin, controlPoint, end)
-               self.wordIndex += 5
-
-       def addPathQuadraticReflected( self, end ):
-               "Add a quadratic curve to the path from a reflected control point."
-               begin = self.getOldPoint()
-               controlPoint = begin
-               if self.controlPoints != None:
-                       if len( self.controlPoints ) == 1:
-                               controlPoint = begin + begin - self.controlPoints[-1]
-               self.controlPoints = [ controlPoint ]
-               self.path += getQuadraticPoints(begin, controlPoint, end)
-               self.wordIndex += 3
-
-       def getComplexByExtraIndex( self, extraIndex=0 ):
-               'Get complex from the extraIndex.'
-               return euclidean.getComplexByWords(self.words, self.wordIndex + extraIndex)
-
-       def getComplexRelative(self):
-               "Get relative complex."
-               return self.getComplexByExtraIndex() + self.getOldPoint()
-
-       def getFloatByExtraIndex( self, extraIndex=0 ):
-               'Get float from the extraIndex.'
-               totalIndex = self.wordIndex + extraIndex
-               if totalIndex >= len(self.words):
-                       return None
-               word = self.words[totalIndex]
-               if word[: 1].isalpha():
-                       return None
-               return euclidean.getFloatFromValue(word)
-
-       def getOldPoint(self):
-               'Get the old point.'
-               if len(self.path) > 0:
-                       return self.path[-1]
-               return self.oldPoint
-
-       def processPathWordA(self):
-               'Process path word A.'
-               self.addPathArc( self.getComplexByExtraIndex( 6 ) )
-
-       def processPathWorda(self):
-               'Process path word a.'
-               self.addPathArc(self.getComplexByExtraIndex(6) + self.getOldPoint())
-
-       def processPathWordC(self):
-               'Process path word C.'
-               end = self.getComplexByExtraIndex( 5 )
-               self.addPathCubic( [ self.getComplexByExtraIndex( 1 ), self.getComplexByExtraIndex(3) ], end )
-
-       def processPathWordc(self):
-               'Process path word C.'
-               begin = self.getOldPoint()
-               end = self.getComplexByExtraIndex( 5 )
-               self.addPathCubic( [ self.getComplexByExtraIndex( 1 ) + begin, self.getComplexByExtraIndex(3) + begin ], end + begin )
-
-       def processPathWordH(self):
-               "Process path word H."
-               beginY = self.getOldPoint().imag
-               self.addPathLineAxis(complex(float(self.words[self.wordIndex + 1]), beginY))
-               while 1:
-                       floatByExtraIndex = self.getFloatByExtraIndex()
-                       if floatByExtraIndex == None:
-                               return
-                       self.path.append(complex(floatByExtraIndex, beginY))
-                       self.wordIndex += 1
-
-       def processPathWordh(self):
-               "Process path word h."
-               begin = self.getOldPoint()
-               self.addPathLineAxis(complex(float(self.words[self.wordIndex + 1]) + begin.real, begin.imag))
-               while 1:
-                       floatByExtraIndex = self.getFloatByExtraIndex()
-                       if floatByExtraIndex == None:
-                               return
-                       self.path.append(complex(floatByExtraIndex + self.getOldPoint().real, begin.imag))
-                       self.wordIndex += 1
-
-       def processPathWordL(self):
-               "Process path word L."
-               self.addPathLine(self.getComplexByExtraIndex, self.getComplexByExtraIndex( 1 ))
-
-       def processPathWordl(self):
-               "Process path word l."
-               self.addPathLine(self.getComplexRelative, self.getComplexByExtraIndex(1) + self.getOldPoint())
-
-       def processPathWordM(self):
-               "Process path word M."
-               self.addPathMove(self.getComplexByExtraIndex, self.getComplexByExtraIndex(1))
-
-       def processPathWordm(self):
-               "Process path word m."
-               self.addPathMove(self.getComplexRelative, self.getComplexByExtraIndex(1) + self.getOldPoint())
-
-       def processPathWordQ(self):
-               'Process path word Q.'
-               self.addPathQuadratic( self.getComplexByExtraIndex( 1 ), self.getComplexByExtraIndex(3) )
-
-       def processPathWordq(self):
-               'Process path word q.'
-               begin = self.getOldPoint()
-               self.addPathQuadratic(self.getComplexByExtraIndex(1) + begin, self.getComplexByExtraIndex(3) + begin)
-
-       def processPathWordS(self):
-               'Process path word S.'
-               self.addPathCubicReflected( self.getComplexByExtraIndex( 1 ), self.getComplexByExtraIndex(3) )
-
-       def processPathWords(self):
-               'Process path word s.'
-               begin = self.getOldPoint()
-               self.addPathCubicReflected(self.getComplexByExtraIndex(1) + begin, self.getComplexByExtraIndex(3) + begin)
-
-       def processPathWordT(self):
-               'Process path word T.'
-               self.addPathQuadraticReflected( self.getComplexByExtraIndex( 1 ) )
-
-       def processPathWordt(self):
-               'Process path word t.'
-               self.addPathQuadraticReflected(self.getComplexByExtraIndex(1) + self.getOldPoint())
-
-       def processPathWordV(self):
-               "Process path word V."
-               beginX = self.getOldPoint().real
-               self.addPathLineAxis(complex(beginX, float(self.words[self.wordIndex + 1])))
-               while 1:
-                       floatByExtraIndex = self.getFloatByExtraIndex()
-                       if floatByExtraIndex == None:
-                               return
-                       self.path.append(complex(beginX, floatByExtraIndex))
-                       self.wordIndex += 1
-
-       def processPathWordv(self):
-               "Process path word v."
-               begin = self.getOldPoint()
-               self.addPathLineAxis(complex(begin.real, float(self.words[self.wordIndex + 1]) + begin.imag))
-               while 1:
-                       floatByExtraIndex = self.getFloatByExtraIndex()
-                       if floatByExtraIndex == None:
-                               return
-                       self.path.append(complex(begin.real, floatByExtraIndex + self.getOldPoint().imag))
-                       self.wordIndex += 1
-
-       def processPathWordZ(self):
-               "Process path word Z."
-               self.controlPoints = None
-               if len(self.path) < 1:
-                       return
-               self.loops.append(getChainMatrixSVGIfNecessary(self.elementNode, self.yAxisPointingUpward).getTransformedPath(self.path))
-               self.oldPoint = self.path[0]
-               self.path = []
-
-       def processPathWordz(self):
-               "Process path word z."
-               self.processPathWordZ()
-
-
-class SVGReader(object):
-       "An svg carving."
-       def __init__(self):
-               "Add empty lists."
-               self.loopLayers = []
-               self.sliceDictionary = None
-               self.stopProcessing = False
-               self.z = 0.0
-
-       def flipDirectLayer(self, loopLayer):
-               "Flip the y coordinate of the layer and direct the loops."
-               for loop in loopLayer.loops:
-                       for pointIndex, point in enumerate(loop):
-                               loop[pointIndex] = complex(point.real, -point.imag)
-               triangle_mesh.sortLoopsInOrderOfArea(True, loopLayer.loops)
-               for loopIndex, loop in enumerate(loopLayer.loops):
-                       isInsideLoops = euclidean.getIsInFilledRegion(loopLayer.loops[: loopIndex], euclidean.getLeftPoint(loop))
-                       intercircle.directLoop((not isInsideLoops), loop)
-
-       def getLoopLayer(self):
-               "Return the rotated loop layer."
-               if self.z != None:
-                       loopLayer = euclidean.LoopLayer(self.z)
-                       self.loopLayers.append(loopLayer)
-                       self.z = None
-               return self.loopLayers[-1]
-
-       def parseSVG(self, fileName, svgText):
-               "Parse SVG text and store the layers."
-               self.fileName = fileName
-               xmlParser = DocumentNode(fileName, svgText)
-               self.documentElement = xmlParser.getDocumentElement()
-               if self.documentElement == None:
-                       print('Warning, documentElement was None in parseSVG in SVGReader, so nothing will be done for:')
-                       print(fileName)
-                       return
-               self.parseSVGByElementNode(self.documentElement)
-
-       def parseSVGByElementNode(self, elementNode):
-               "Parse SVG by elementNode."
-               self.sliceDictionary = svg_writer.getSliceDictionary(elementNode)
-               self.yAxisPointingUpward = euclidean.getBooleanFromDictionary(False, self.sliceDictionary, 'yAxisPointingUpward')
-               self.processElementNode(elementNode)
-               if not self.yAxisPointingUpward:
-                       for loopLayer in self.loopLayers:
-                               self.flipDirectLayer(loopLayer)
-
-       def processElementNode(self, elementNode):
-               'Process the xml element.'
-               if self.stopProcessing:
-                       return
-               lowerLocalName = elementNode.getNodeName().lower()
-               global globalProcessSVGElementDictionary
-               if lowerLocalName in globalProcessSVGElementDictionary:
-                       try:
-                               globalProcessSVGElementDictionary[lowerLocalName](elementNode, self)
-                       except:
-                               print('Warning, in processElementNode in svg_reader, could not process:')
-                               print(elementNode)
-                               traceback.print_exc(file=sys.stdout)
-               for childNode in elementNode.childNodes:
-                       self.processElementNode(childNode)
-
-
-globalFontFileNames = None
-globalFontReaderDictionary = {}
-globalGetTricomplexDictionary = {}
-globalGetTricomplexFunctions = [
-       getTricomplexmatrix,
-       getTricomplexrotate,
-       getTricomplexscale,
-       getTricomplexskewX,
-       getTricomplexskewY,
-       getTricomplextranslate ]
-globalProcessPathWordFunctions = [
-       PathReader.processPathWordA,
-       PathReader.processPathWorda,
-       PathReader.processPathWordC,
-       PathReader.processPathWordc,
-       PathReader.processPathWordH,
-       PathReader.processPathWordh,
-       PathReader.processPathWordL,
-       PathReader.processPathWordl,
-       PathReader.processPathWordM,
-       PathReader.processPathWordm,
-       PathReader.processPathWordQ,
-       PathReader.processPathWordq,
-       PathReader.processPathWordS,
-       PathReader.processPathWords,
-       PathReader.processPathWordT,
-       PathReader.processPathWordt,
-       PathReader.processPathWordV,
-       PathReader.processPathWordv,
-       PathReader.processPathWordZ,
-       PathReader.processPathWordz ]
-globalProcessPathWordDictionary = {}
-globalProcessSVGElementDictionary = {}
-globalProcessSVGElementFunctions = [
-       processSVGElementcircle,
-       processSVGElementellipse,
-       processSVGElementg,
-       processSVGElementline,
-       processSVGElementpath,
-       processSVGElementpolygon,
-       processSVGElementpolyline,
-       processSVGElementrect,
-       processSVGElementtext ]
-globalSideAngle = 0.5 * math.pi / float( globalNumberOfCornerPoints )
-
-
-addFunctionsToDictionary( globalGetTricomplexDictionary, globalGetTricomplexFunctions, 'getTricomplex')
-addFunctionsToDictionary( globalProcessPathWordDictionary, globalProcessPathWordFunctions, 'processPathWord')
-addFunctionsToDictionary( globalProcessSVGElementDictionary, globalProcessSVGElementFunctions, 'processSVGElement')
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/svg_writer.py b/Cura/slice/cura_sf/fabmetheus_utilities/svg_writer.py
deleted file mode 100644 (file)
index eda0469..0000000
+++ /dev/null
@@ -1,277 +0,0 @@
-"""
-Svg_writer is a class and collection of utilities to read from and write to an svg file.
-
-Svg_writer uses the layer_template.svg file in the templates folder in the same folder as svg_writer, to output an svg file.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities.xml_simple_reader import DocumentNode
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import xml_simple_reader
-from fabmetheus_utilities import xml_simple_writer
-import cStringIO
-import math
-import os
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalOriginalTextString = '<!-- Original XML Text:\n'
-
-
-def getCarving(fileName):
-       'Get a carving for the file using an import plugin.'
-       pluginModule = fabmetheus_interpret.getInterpretPlugin(fileName)
-       if pluginModule == None:
-               return None
-       return pluginModule.getCarving(fileName)
-
-def getCommentElement(elementNode):
-       'Get a carving for the file using an import plugin.'
-       for childNode in elementNode.childNodes:
-               if childNode.getNodeName() == '#comment':
-                       if childNode.getTextContent().startswith(globalOriginalTextString):
-                               return childNode
-       return None
-
-def getSliceDictionary(elementNode):
-       'Get the metadata slice attribute dictionary.'
-       for metadataElement in elementNode.getChildElementsByLocalName('metadata'):
-               for childNode in metadataElement.childNodes:
-                       if childNode.getNodeName().lower() == 'slice:layers':
-                               return childNode.attributes
-       return {}
-
-def getSliceElementNodes(elementNode):
-       'Get the slice elements.'
-       gElementNodes = elementNode.getElementsByLocalName('g')
-       sliceElementNodes = []
-       for gElementNode in gElementNodes:
-               if 'id' in gElementNode.attributes:
-                       idValue = gElementNode.attributes['id'].strip()
-                       if idValue.startswith('z:'):
-                               sliceElementNodes.append(gElementNode)
-       return sliceElementNodes
-
-def getSVGByLoopLayers(addLayerTemplateToSVG, carving, loopLayers):
-       'Get the svg text.'
-       if len(loopLayers) < 1:
-               return ''
-       decimalPlacesCarried = max(0, 2 - int(math.floor(math.log10(carving.layerHeight))))
-       svgWriter = SVGWriter(
-               addLayerTemplateToSVG,
-               carving.getCarveCornerMaximum(),
-               carving.getCarveCornerMinimum(),
-               decimalPlacesCarried,
-               carving.getCarveLayerHeight())
-       return svgWriter.getReplacedSVGTemplate(carving.fileName, loopLayers, 'basic', carving.getFabmetheusXML())
-
-def getTruncatedRotatedBoundaryLayers(loopLayers, repository):
-       'Get the truncated rotated boundary layers.'
-       return loopLayers[repository.layersFrom.value : repository.layersTo.value]
-
-def setSVGCarvingCorners(cornerMaximum, cornerMinimum, layerHeight, loopLayers):
-       'Parse SVG text and store the layers.'
-       for loopLayer in loopLayers:
-               for loop in loopLayer.loops:
-                       for point in loop:
-                               pointVector3 = Vector3(point.real, point.imag, loopLayer.z)
-                               cornerMaximum.maximize(pointVector3)
-                               cornerMinimum.minimize(pointVector3)
-       halfLayerThickness = 0.5 * layerHeight
-       cornerMaximum.z += halfLayerThickness
-       cornerMinimum.z -= halfLayerThickness
-
-
-class SVGWriter(object):
-       'A base class to get an svg skein from a carving.'
-       def __init__(self,
-                       addLayerTemplateToSVG,
-                       cornerMaximum,
-                       cornerMinimum,
-                       decimalPlacesCarried,
-                       layerHeight,
-                       edgeWidth=None):
-               'Initialize.'
-               self.addLayerTemplateToSVG = addLayerTemplateToSVG
-               self.cornerMaximum = cornerMaximum
-               self.cornerMinimum = cornerMinimum
-               self.decimalPlacesCarried = decimalPlacesCarried
-               self.edgeWidth = edgeWidth
-               self.layerHeight = layerHeight
-               self.textHeight = 22.5
-               self.unitScale = 3.7
-
-       def addLayerBegin(self, layerIndex, loopLayer):
-               'Add the start lines for the layer.'
-               zRounded = self.getRounded(loopLayer.z)
-               self.graphicsCopy = self.graphicsElementNode.getCopy(zRounded, self.graphicsElementNode.parentNode)
-               if self.addLayerTemplateToSVG:
-                       translateXRounded = self.getRounded(self.controlBoxWidth + self.margin + self.margin)
-                       layerTranslateY = self.marginTop
-                       layerTranslateY += layerIndex * self.textHeight + (layerIndex + 1) * (self.extent.y * self.unitScale + self.margin)
-                       translateYRounded = self.getRounded(layerTranslateY)
-                       self.graphicsCopy.attributes['transform'] = 'translate(%s, %s)' % (translateXRounded, translateYRounded)
-                       layerString = 'Layer %s, z:%s' % (layerIndex, zRounded)
-                       self.graphicsCopy.getFirstChildByLocalName('text').setTextContent(layerString)
-                       self.graphicsCopy.attributes['inkscape:groupmode'] = 'layer'
-                       self.graphicsCopy.attributes['inkscape:label'] = layerString
-               self.pathElementNode = self.graphicsCopy.getFirstChildByLocalName('path')
-               self.pathDictionary = self.pathElementNode.attributes
-
-       def addLoopLayersToOutput(self, loopLayers):
-               'Add rotated boundary layers to the output.'
-               for loopLayerIndex, loopLayer in enumerate(loopLayers):
-                       self.addLoopLayerToOutput(loopLayerIndex, loopLayer)
-
-       def addLoopLayerToOutput(self, layerIndex, loopLayer):
-               'Add rotated boundary layer to the output.'
-               self.addLayerBegin(layerIndex, loopLayer)
-               if self.addLayerTemplateToSVG:
-                       self.pathDictionary['transform'] = self.getTransformString()
-               else:
-                       del self.pathDictionary['transform']
-               self.pathDictionary['d'] = self.getSVGStringForLoops(loopLayer.loops)
-
-       def addOriginalAsComment(self, elementNode):
-               'Add original elementNode as a comment.'
-               if elementNode == None:
-                       return
-               if elementNode.getNodeName() == '#comment':
-                       elementNode.setParentAddToChildNodes(self.svgElement)
-                       return
-               elementNodeOutput = cStringIO.StringIO()
-               elementNode.addXML(0, elementNodeOutput)
-               textLines = archive.getTextLines(elementNodeOutput.getvalue())
-               commentNodeOutput = cStringIO.StringIO()
-               isComment = False
-               for textLine in textLines:
-                       lineStripped = textLine.strip()
-                       if lineStripped[: len('<!--')] == '<!--':
-                               isComment = True
-                       if not isComment:
-                               if len(textLine) > 0:
-                                       commentNodeOutput.write(textLine + '\n')
-                       if '-->' in lineStripped:
-                               isComment = False
-               xml_simple_reader.CommentNode(self.svgElement, '%s%s-->\n' % (globalOriginalTextString, commentNodeOutput.getvalue())).appendSelfToParent()
-
-       def getReplacedSVGTemplate(self, fileName, loopLayers, procedureName, elementNode=None):
-               'Get the lines of text from the layer_template.svg file.'
-               self.extent = self.cornerMaximum - self.cornerMinimum
-               svgTemplateText = archive.getFileText(archive.getTemplatesPath('layer_template.svg'))
-               documentNode = DocumentNode(fileName, svgTemplateText)
-               self.svgElement = documentNode.getDocumentElement()
-               svgElementDictionary = self.svgElement.attributes
-               self.sliceDictionary = getSliceDictionary(self.svgElement)
-               self.controlBoxHeight = float(self.sliceDictionary['controlBoxHeight'])
-               self.controlBoxWidth = float(self.sliceDictionary['controlBoxWidth'])
-               self.margin = float(self.sliceDictionary['margin'])
-               self.marginTop = float(self.sliceDictionary['marginTop'])
-               self.textHeight = float(self.sliceDictionary['textHeight'])
-               self.unitScale = float(self.sliceDictionary['unitScale'])
-               svgMinWidth = float(self.sliceDictionary['svgMinWidth'])
-               self.controlBoxHeightMargin = self.controlBoxHeight + self.marginTop
-               if not self.addLayerTemplateToSVG:
-                       self.svgElement.getElementNodeByID('layerTextTemplate').removeFromIDNameParent()
-                       del self.svgElement.getElementNodeByID('sliceElementTemplate').attributes['transform']
-               self.graphicsElementNode = self.svgElement.getElementNodeByID('sliceElementTemplate')
-               self.graphicsElementNode.attributes['id'] = 'z:'
-               self.addLoopLayersToOutput(loopLayers)
-               self.setMetadataNoscriptElement('layerHeight', 'Layer Height: ', self.layerHeight)
-               self.setMetadataNoscriptElement('maxX', 'X: ', self.cornerMaximum.x)
-               self.setMetadataNoscriptElement('minX', 'X: ', self.cornerMinimum.x)
-               self.setMetadataNoscriptElement('maxY', 'Y: ', self.cornerMaximum.y)
-               self.setMetadataNoscriptElement('minY', 'Y: ', self.cornerMinimum.y)
-               self.setMetadataNoscriptElement('maxZ', 'Z: ', self.cornerMaximum.z)
-               self.setMetadataNoscriptElement('minZ', 'Z: ', self.cornerMinimum.z)
-               self.textHeight = float( self.sliceDictionary['textHeight'] )
-               controlTop = len(loopLayers) * (self.margin + self.extent.y * self.unitScale + self.textHeight) + self.marginTop + self.textHeight
-               self.svgElement.getFirstChildByLocalName('title').setTextContent(os.path.basename(fileName).decode("utf-8").encode('ascii', 'replace') + ' - Slice Layers')
-               svgElementDictionary['height'] = '%spx' % self.getRounded(max(controlTop, self.controlBoxHeightMargin))
-               width = max(self.extent.x * self.unitScale, svgMinWidth)
-               svgElementDictionary['width'] = '%spx' % self.getRounded( width )
-               self.sliceDictionary['decimalPlacesCarried'] = str( self.decimalPlacesCarried )
-               if self.edgeWidth != None:
-                       self.sliceDictionary['edgeWidth'] = self.getRounded( self.edgeWidth )
-               self.sliceDictionary['yAxisPointingUpward'] = 'true'
-               self.sliceDictionary['procedureName'] = procedureName
-               self.setDimensionTexts('dimX', 'X: ' + self.getRounded(self.extent.x))
-               self.setDimensionTexts('dimY', 'Y: ' + self.getRounded(self.extent.y))
-               self.setDimensionTexts('dimZ', 'Z: ' + self.getRounded(self.extent.z))
-               self.setTexts('numberOfLayers', 'Number of Layers: %s' % len(loopLayers))
-               volume = 0.0
-               for loopLayer in loopLayers:
-                       volume += euclidean.getAreaLoops(loopLayer.loops)
-               volume *= 0.001 * self.layerHeight
-               self.setTexts('volume', 'Volume: %s cm3' % self.getRounded(volume))
-               if not self.addLayerTemplateToSVG:
-                       self.svgElement.getFirstChildByLocalName('script').removeFromIDNameParent()
-                       self.svgElement.getElementNodeByID('controls').removeFromIDNameParent()
-               self.graphicsElementNode.removeFromIDNameParent()
-               self.addOriginalAsComment(elementNode)
-               return documentNode.__repr__()
-
-       def getRounded(self, number):
-               'Get number rounded to the number of carried decimal places as a string.'
-               return euclidean.getRoundedToPlacesString(self.decimalPlacesCarried, number)
-
-       def getRoundedComplexString(self, point):
-               'Get the rounded complex string.'
-               return self.getRounded( point.real ) + ' ' + self.getRounded( point.imag )
-
-       def getSVGStringForLoop( self, loop ):
-               'Get the svg loop string.'
-               if len(loop) < 1:
-                       return ''
-               return self.getSVGStringForPath(loop) + ' z'
-
-       def getSVGStringForLoops( self, loops ):
-               'Get the svg loops string.'
-               loopString = ''
-               if len(loops) > 0:
-                       loopString += self.getSVGStringForLoop( loops[0] )
-               for loop in loops[1 :]:
-                       loopString += ' ' + self.getSVGStringForLoop(loop)
-               return loopString
-
-       def getSVGStringForPath( self, path ):
-               'Get the svg path string.'
-               svgLoopString = ''
-               for point in path:
-                       stringBeginning = 'M '
-                       if len( svgLoopString ) > 0:
-                               stringBeginning = ' L '
-                       svgLoopString += stringBeginning + self.getRoundedComplexString(point)
-               return svgLoopString
-
-       def getTransformString(self):
-               'Get the svg transform string.'
-               cornerMinimumXString = self.getRounded(-self.cornerMinimum.x)
-               cornerMinimumYString = self.getRounded(-self.cornerMinimum.y)
-               return 'scale(%s, %s) translate(%s, %s)' % (self.unitScale, - self.unitScale, cornerMinimumXString, cornerMinimumYString)
-
-       def setDimensionTexts(self, key, valueString):
-               'Set the texts to the valueString followed by mm.'
-               self.setTexts(key, valueString + ' mm')
-
-       def setMetadataNoscriptElement(self, key, prefix, value):
-               'Set the metadata value and the text.'
-               valueString = self.getRounded(value)
-               self.sliceDictionary[key] = valueString
-               self.setDimensionTexts(key, prefix + valueString)
-
-       def setTexts(self, key, valueString):
-               'Set the texts to the valueString.'
-               self.svgElement.getElementNodeByID(key + 'Iso').setTextContent(valueString)
-               self.svgElement.getElementNodeByID(key + 'Layer').setTextContent(valueString)
-               self.svgElement.getElementNodeByID(key + 'Scroll').setTextContent(valueString)
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/templates/canvas_template.svg b/Cura/slice/cura_sf/fabmetheus_utilities/templates/canvas_template.svg
deleted file mode 100644 (file)
index b146e60..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" standalone="no"?>\r
-<svg contentScriptType="text/ecmascript"\r
-       baseProfile="full" zoomAndPan="magnify" contentStyleType="text/css"\r
-width="999px"\r
-height="999px"\r
-       preserveAspectRatio="xMidYMid meet"\r
-       xmlns="http://www.w3.org/2000/svg" version="1.0"\r
-       xmlns:xlink="http://www.w3.org/1999/xlink"\r
-       xmlns:slice="http://www.reprap.org/slice">\r
-       <metadata template = "svg_canvas">\r
-       </metadata>\r
-       <title>\r
-replaceLineWithTitle\r
-       </title>\r
-<!--replaceLineWith_coloredLines--> <line x1="0"  y1="10" x2="30"   y2="100" stroke="#00F" stroke-width="1px"/>\r
-</svg>\r
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/templates/layer_template.svg b/Cura/slice/cura_sf/fabmetheus_utilities/templates/layer_template.svg
deleted file mode 100644 (file)
index e410f9a..0000000
+++ /dev/null
@@ -1,519 +0,0 @@
-<?xml version='1.0' standalone='no'?>
-<!--Written in KDevelop (http://www.kdevelop.org/)-->
-<svg contentScriptType='text/ecmascript'
-       baseProfile='full' zoomAndPan='magnify' contentStyleType='text/css'
-       height='999px'
-       preserveAspectRatio='xMidYMid meet'
-       onload='init()'
-       width='999px'
-       xmlns='http://www.w3.org/2000/svg' version='1.0'
-       xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape'
-       xmlns:slice='http://www.reprap.org/slice'
-       xmlns:xlink='http://www.w3.org/1999/xlink'>
-       <metadata>
-               <slice:layers id='sliceData' controlBoxWidth='240' layerHeight='0.2' minX='0' maxX='61' minY='-5' maxY='50' minZ='0' maxZ='1' margin='20' marginTop='60' controlBoxHeight='720' svgMinWidth='516' template='svg_layer' textHeight='22.5' unitScale='3.7' version='0.1'/>
-       </metadata>
-       <script type='text/ecmascript'><![CDATA[
-globalMetadata = document.getElementsByTagNameNS('http://www.reprap.org/slice', 'layers')[0];
-globalSliceMinX = globalMetadata.getAttribute('minX') * 1;
-globalSliceMaxX = globalMetadata.getAttribute('maxX') * 1;
-globalSliceMinY = globalMetadata.getAttribute('minY') * 1;
-globalSliceMaxY = globalMetadata.getAttribute('maxY') * 1;
-globalSliceMinZ = globalMetadata.getAttribute('minZ') * 1;
-globalSliceMaxZ = globalMetadata.getAttribute('maxZ') * 1;
-
-//Control var's
-globalLayerIndex = 0; //Number of currently viewed layer (zero index)
-globalLatitude = 60.0;
-globalLongitude = 45.0;
-globalControlBoxHeight = globalMetadata.getAttribute('controlBoxHeight') * 1;
-globalControlBoxWidth = globalMetadata.getAttribute('controlBoxWidth') * 1;
-globalSliding = false;
-globalObserving = false
-
-//Display var's
-globalMargin = globalMetadata.getAttribute('margin') * 1;
-globalMarginTop = globalMetadata.getAttribute('marginTop') * 1;
-globalDimensionX = globalSliceMaxX - globalSliceMinX;
-globalDimensionY = globalSliceMaxY - globalSliceMinY;
-globalDimensionZ = globalSliceMaxZ - globalSliceMinZ;
-magnitudeXYSquared = globalDimensionX * globalDimensionX + globalDimensionY * globalDimensionY;
-globalDimensionMagnitude = Math.sqrt(magnitudeXYSquared + globalDimensionZ * globalDimensionZ);
-globalGlobeTravelRadian = 0.0;
-globalGlobeInnerObserverRadius = 0.0;
-globalTextHeight = globalMetadata.getAttribute('textHeight') * 1.0;
-globalUnitScale = globalMetadata.getAttribute('unitScale') * 1.0;
-globalXOffset = globalControlBoxWidth + globalMargin + globalMargin;
-globalYOffset = globalMargin + globalMarginTop;
-globalZoomScale = 1.0; //Default 1:1 may need smaller scale for large objects
-globalScale = globalUnitScale * globalZoomScale;
-
-//Globals to be set in init
-globalLayers = [];
-globalSlider = 0;
-globalThumb = 0;
-globalThumbRadius = 0.0;
-globalSliderWidthMinusDiameter = 0.0;
-
-
-function changeScale(newScale) {
-       globalZoomScale = newScale;
-       globalScale = globalUnitScale * globalZoomScale;
-       if (globalZoomScale >=1) { //dont scale line thickness for large display scale
-               document.getElementById('layerData').setAttributeNS(null, 'stroke-width', 2.0 / (globalScale));
-       }
-}
-
-function changeScaleIso(newScale) {
-       changeScale(newScale);
-       viewIso();
-}
-
-function changeScaleLayer(newScale) {
-       changeScale(newScale);
-       viewLayer();
-}
-
-function changeScaleScroll(newScale) {
-       changeScale(newScale);
-       viewScroll();
-}
-
-function displayIso(latitude, longitude) {
-       latitude = Math.max(0.0, latitude);
-       latitude = Math.min(89.0, latitude);
-       globalLatitude = Math.round(latitude);
-       globalLongitude = Math.round((longitude + 540.0) % 360.0) - 180.0;
-       latitudeRadians = getRadians(globalLatitude);
-       longitudeWiddershinsRadians = getRadians(90.0 - globalLongitude);
-       unitX = Math.cos(longitudeWiddershinsRadians);
-       unitY = Math.sin(longitudeWiddershinsRadians);
-       latitudeOverLayers = globalDimensionZ / globalLayers.length;
-       globalOneOverUnitScaleString = (1.0 / globalUnitScale).toString();
-       yScale = -1.0 * globalScale * Math.cos(latitudeRadians);
-       scaleRotateCenterString = ' scale(' + globalScale + ', ' + yScale + ')';
-       scaleRotateCenterString += ' rotate(' + (-1.0 * globalLongitude).toString() + ')';
-       centerX = (-0.5 * globalDimensionX - globalSliceMinX).toString();
-       centerY = (-0.5 * globalDimensionY - globalSliceMinY).toString();
-       scaleRotateCenterString += ' translate(' + centerX + ', ' + centerY + ')';
-       x = 0.5 * globalDimensionMagnitude * globalScale + globalXOffset;
-       halfLengthMinusOne = 0.5 * (globalLayers.length - 1);
-       for (var i in globalLayers) {
-               latitudeZSin = Math.sin(latitudeRadians) * (i - halfLengthMinusOne) * latitudeOverLayers
-               y = globalScale * (0.5 * globalDimensionMagnitude - latitudeZSin) + globalYOffset;
-//             y = globalDimensionY * globalScale + globalYOffset - i * unitY * latitudeOverLayers;
-               transformString = ' translate(' + x + ', ' + y + ')';
-               globalLayers[i].setAttributeNS(null, 'transform', transformString + scaleRotateCenterString);
-       }
-       setText('latitudeIso', 'Latitude: ' + globalLatitude.toString() + '°');
-       setText('longitudeIso', 'Longitude: ' + globalLongitude.toString() + '°');
-       globeMoveableRadius = globalGlobeTravelRadian * latitudeRadians + globalGlobeInnerObserverRadius;
-       globalObserver.setAttribute('cx', globalGlobeCenterX + unitX * globeMoveableRadius);
-       globalObserver.setAttribute('cy', globalGlobeCenterY - unitY * globeMoveableRadius);
-}
-
-function displayIsoByLatitude(latitude) {
-       displayIso(latitude, globalLongitude);
-}
-
-function displayIsoByLongitude(longitude) {
-       displayIso(globalLatitude, longitude);
-}
-
-function displayLayer(layerNum) {
-       if (globalLayers.length <= 1) {
-               document.getElementById('maxIndexLayer').setAttributeNS(null, 'visibility', 'hidden');
-               document.getElementById('minIndexLayer').setAttributeNS(null, 'visibility', 'hidden');
-               globalSlider.setAttributeNS(null, 'visibility', 'hidden');
-               globalThumb.setAttributeNS(null, 'visibility', 'hidden');
-       }
-       if (layerNum <= 0) {
-               document.getElementById('decreaseLayerIndex').setAttributeNS(null, 'visibility', 'hidden');
-       }
-       else {
-               document.getElementById('decreaseLayerIndex').setAttributeNS(null, 'visibility', 'visible');
-       }
-       if (layerNum >= globalLayers.length - 1) {
-               document.getElementById('increaseLayerIndex').setAttributeNS(null, 'visibility', 'hidden');
-       }
-       else {
-               document.getElementById('increaseLayerIndex').setAttributeNS(null, 'visibility', 'visible');
-       }
-       if (layerNum < 0 || layerNum >= globalLayers.length) {
-               return
-       }
-       globalLayers[globalLayerIndex].setAttributeNS(null, 'visibility', 'hidden');
-       currentLayerElement = globalLayers[layerNum]
-       currentLayerElement.setAttributeNS(null, 'visibility', 'visible');
-       globalLayerIndex = layerNum;
-       setText('currentIndexLayer', 'Layer: ' + globalLayerIndex.toString() + ', ' + currentLayerElement.getAttribute('id'));
-       //Slider
-       if (!globalSliding) {
-               placeThumb(globalSliderWidthMinusDiameter / (globalLayers.length - 1) * globalLayerIndex + globalThumbRadius);
-       }
-}
-
-function getDegrees(radians) {
-       return radians / Math.PI * 180.0;
-}
-
-function getRadians(degrees) {
-       return degrees / 180.0 * Math.PI;
-}
-
-function getScaleTransformString(scale) {
-       scaleTransformString = 'scale(' + scale + ' ' + (scale * - 1)
-       return scaleTransformString + ') translate(' + (globalSliceMinX * - 1) + ' ' + (globalSliceMinY * - 1) + ')';
-}
-
-function getWidth() {
-       return (globalDimensionX * globalScale) + globalXOffset
-}
-
-function hideElements(elementNames) {
-       for (var elementNameIndex in elementNames) {
-               document.getElementById(elementNames[elementNameIndex]).setAttributeNS(null, 'visibility', 'hidden');
-       }
-}
-
-function init() {
-       //Find only layer groups
-       globe = document.getElementById('globe');
-       globalGlobeCenterX = globe.getAttribute('cx') * 1;
-       globalGlobeCenterXWindow = globalGlobeCenterX + globalMargin;
-       globalGlobeCenterY = globe.getAttribute('cy') * 1;
-       globalGlobeCenterYWindow = globalGlobeCenterX + globalMarginTop;
-       globalObserver = document.getElementById('observer');
-       globeRadius = globe.getAttribute('r') * 1.0;
-       observerRadius = globalObserver.getAttribute('r') * 1.0;
-       globalGlobeInnerObserverRadius = document.getElementById('cover').getAttribute('r') * 1.0 + observerRadius;
-       globalGlobeTravelRadian = getDegrees(globeRadius - globalGlobeInnerObserverRadius - observerRadius) / 89.0;
-       globalSlider = document.getElementById('slider');
-       globalSliderX = globalSlider.getAttribute('x') * 1;
-       globalSliderXWindow = globalSliderX + globalMargin
-       globalThumb = document.getElementById('thumb');
-       globalThumbRadius = globalThumb.getAttribute('r') * 1;
-       globalSliderWidthMinusRadius = globalSlider.getAttribute('width') * 1 - globalThumbRadius;
-       globalSliderWidthMinusDiameter = globalSliderWidthMinusRadius - globalThumbRadius;
-       var allGroups = document.getElementsByTagName('g');
-       for (var i = 0; i < allGroups.length; i++) {
-               if (allGroups[i].id.indexOf('z:') == 0) {
-                       globalLayers.push(allGroups[i]);
-               }
-       }
-
-       //Slider
-       layerControlBox = document.getElementById('layerControlBox');
-       layerControlBox.addEventListener('mouseup', sliderUp, false);
-       layerControlBox.addEventListener('mousemove', sliderMove, false);
-       globalSlider.addEventListener('mousedown', sliderDownMove, false);
-       globalThumb.addEventListener('mousedown', sliderDownMove, false);
-       //Observer
-       isoControlBox = document.getElementById('isoControlBox');
-       isoControlBox.addEventListener('mouseup', observerUp, false);
-       isoControlBox.addEventListener('mousemove', observerMove, false);
-       globe.addEventListener('mousedown', observerDownMove, false);
-       globalObserver.addEventListener('mousedown', observerDownMove, false);
-       
-       //Control box data
-       setText('maxIndexLayer', globalLayers.length - 1);
-       changeScaleLayer(globalZoomScale);
-}
-
-function observerDown(event) {
-       globalObserving = true;
-}
-
-function observerDownMove(event) {
-       globalObserving = true;
-       observerMove(event);
-}
-
-function observerMove(event) {
-       if (!globalObserving) {
-               return;
-       }
-       observerX = event.clientX - globalGlobeCenterXWindow + window.pageXOffset;
-       observerY = event.clientY - globalGlobeCenterYWindow + window.pageYOffset;
-       distanceFromCenter = Math.sqrt(observerX * observerX + observerY * observerY);
-       latitudeRadians = (distanceFromCenter - globalGlobeInnerObserverRadius) / globalGlobeTravelRadian;
-       longitudeRadians = Math.atan2(observerX, -observerY);
-       displayIso(getDegrees(latitudeRadians), getDegrees(longitudeRadians));
-}
-
-function observerUp(event) {
-       globalObserving = false;
-}
-
-function placeThumb(value) {
-       if (globalLayers.length > 1) {
-               globalThumb.setAttribute('cx', globalSliderX + value);
-       }
-}
-
-function setScaleText(scaleID) {
-       setText(scaleID, ': ' + globalZoomScale);
-}
-
-function setSVG(width, height) {
-       rootSVG = document.getElementsByTagName('svg')[0];
-       svgMinWidth = globalMetadata.getAttribute('svgMinWidth') * 1;
-       height = Math.max(globalControlBoxHeight + globalMargin + globalMarginTop, height);
-       width = Math.max(svgMinWidth, width);
-       rootSVG.setAttributeNS(null, 'width', width + 'px')
-       rootSVG.setAttributeNS(null, 'height', height + 'px')
-}
-
-function setText(id, str) {
-       e = document.getElementById(id)
-       if (e != null)
-               e.firstChild.nodeValue = str;
-}
-
-function showElements(elementNames) {
-       for (var elementNameIndex in elementNames) {
-               document.getElementById(elementNames[elementNameIndex]).setAttributeNS(null, 'visibility', 'visible');
-       }
-}
-
-function sliderDown(event) {
-       globalSliding = true;
-}
-
-function sliderDownMove(event) {
-       globalSliding = true;
-       sliderMove(event);
-}
-
-function sliderMove(event) {
-       if (!globalSliding) {
-               return;
-       }
-       value = event.clientX - globalSliderXWindow + window.pageXOffset;
-       if (value >= globalThumbRadius && value <= globalSliderWidthMinusRadius) {
-               placeThumb(value);
-               zoneWidth = globalSliderWidthMinusDiameter / (globalLayers.length);
-               newLayer = Math.round((value - globalThumbRadius - 0.5 * zoneWidth) / zoneWidth)
-               if (newLayer != globalLayerIndex) {
-                       displayLayer(newLayer)
-               }
-       }
-}
-
-function sliderUp(event) {
-       globalSliding = false;
-}
-
-function viewIso() {
-       height = (globalDimensionMagnitude * globalScale) + globalYOffset;
-       setSVG((globalDimensionMagnitude * globalScale) + globalXOffset, height);
-       for (var i in globalLayers) {
-//             globalLayers[i].setAttributeNS(null, 'transform', 'translate(' + globalMargin + ' ' + height + ')');
-               globalLayers[i].setAttributeNS(null, 'visibility', 'visible');
-               globalLayers[i].getElementsByTagName('text')[0].setAttributeNS(null, 'visibility', 'hidden');
-               pathElements = globalLayers[i].getElementsByTagName('path');
-               for (var pathElementIndex = 0; pathElementIndex < pathElements.length; pathElementIndex++) {
-                         pathElements[pathElementIndex].setAttributeNS(null, 'transform', '');
-                 }
-         }
-         //show control box
-       hideElements(['decreaseLayerIndex', 'increaseLayerIndex', 'isoViewButton', 'layerControlBox', 'layerViewLabel', 'scrollControlBox', 'scrollViewLabel']);
-       showElements(['isoControlBox', 'isoViewLabel', 'layerViewButton', 'scrollViewButton']);
-       displayIso(globalLatitude, globalLongitude);
-       setScaleText('scaleIso');
-}
-
-function viewLayer() {
-       //Set svg size and view port
-       height = (globalDimensionY * globalScale) + globalYOffset;
-       setSVG(getWidth(), height);
-       //move and hide all layers 
-       for (var i in globalLayers) {
-               globalLayers[i].setAttributeNS(null, 'transform', 'translate(' + globalXOffset + ' ' + height + ')');
-               globalLayers[i].setAttributeNS(null, 'visibility', 'hidden');
-               globalLayers[i].getElementsByTagName('text')[0].setAttributeNS(null, 'visibility', 'hidden');
-               transform = getScaleTransformString(globalScale);
-               pathElements = globalLayers[i].getElementsByTagName('path');
-               for (var pathElementIndex = 0; pathElementIndex < pathElements.length; pathElementIndex++) {
-                       pathElements[pathElementIndex].setAttributeNS(null, 'transform', transform);
-               }
-       }
-
-       //show control box
-       hideElements(['isoControlBox', 'isoViewLabel', 'layerViewButton', 'scrollControlBox', 'scrollViewLabel'])
-       showElements(['isoViewButton', 'layerControlBox', 'layerViewLabel', 'scrollViewButton'])
-       
-       //show current layer
-       displayLayer(globalLayerIndex);
-       setScaleText('scaleLayer');
-}
-
-function viewScroll() {
-       //Set svg size and view port
-       yDimensionScale = globalDimensionY * globalScale
-       singleHeight = (globalMargin + yDimensionScale + globalTextHeight)
-       height = globalLayers.length * singleHeight + globalMargin + globalMargin + globalYOffset;
-       setSVG(getWidth(), height);
-
-       //move and show all layers 
-       for (var i in globalLayers) {
-               x = globalXOffset;
-               y = i * singleHeight + yDimensionScale + globalYOffset;
-               transform = getScaleTransformString(globalScale);
-               globalLayers[i].setAttributeNS(null, 'transform', 'translate(' + x + ', ' + y + ')');
-               pathElements = globalLayers[i].getElementsByTagName('path');
-               for (var pathElementIndex = 0; pathElementIndex < pathElements.length; pathElementIndex++) {
-                       pathElements[pathElementIndex].setAttributeNS(null, 'transform', transform);
-               }
-               globalLayers[i].setAttributeNS(null, 'visibility', 'visible');
-               globalLayers[i].getElementsByTagName('text')[0].setAttributeNS(null, 'visibility', 'visible');
-       }
-
-       //show control box
-       hideElements(['isoControlBox', 'isoViewLabel', 'layerControlBox', 'layerViewLabel', 'scrollViewButton'])
-       showElements(['isoViewButton', 'layerViewButton', 'scrollControlBox', 'scrollViewLabel'])
-       setScaleText('scaleScroll');
-}
-       ]]></script>
-
-       <title>replaceWith_Title</title>
-
-       <!--Begin Layer Data   -->
-       <g id='layerData' fill='#556B2F' fill-rule='evenodd' font-weight='bold' font-family='Arial' font-size='15px' inkscape:groupmode='layer' inkscape:label='Slice Layers' stroke='#00F' stroke-width='0.54px'>
-               <!--id='sliceElementTemplate' must be there or else the slice template will not be found-->
-               <g id='sliceElementTemplate' transform='translate(20, 242)'>
-                       <!--id='layerTextTemplate' must be there so that the text could be removed if necessary-->
-                       <text id='layerTextTemplate' y='15' fill='#000' stroke='none'>Layer 1, z:0.1</text>
-                       <path transform='scale(3.7, -3.7) translate(0, 5)' d='M 0 -5 L 50 0 L60 50 L 5 50 z M 5 3 L5 15 L15 15 L15 5 z'/>
-               </g>
-       </g>
-       <!--End Layer Data-->
-       <!--beginningOfControlSection='true' must be there or else the control boxes will be carved-->
-       <g id='controls' beginningOfControlSection='true' inkscape:groupmode='layer' inkscape:label='Controls'>
-       <!--id='isoControlBox' must be there so that the controls could be removed if necessary-->
-               <g id='isoControlBox' fill='#000' font-family='Arial' font-size='15px' font-weight='bold' transform='translate(20, 60)' visibility='hidden'>
-                       <rect width='240' height='720' stroke='gray' stroke-width='4px' fill='silver'/>
-                       <circle id='globe' cx='120' cy='120' r='100' fill='gray'/>
-                       <circle id='cover' cx='120' cy='120' r='33' fill='silver'/>
-                       <circle id='observer' r='12' fill='darkslateblue'/>
-                       <text x='20' y='260' id='latitudeIso'>Latitude</text>
-                       <text x='198' y='260' onclick='displayIsoByLatitude(globalLatitude-1.0)' fill='darkslateblue'>&lt;</text>
-                       <text x='213' y='260' onclick='displayIsoByLatitude(globalLatitude+1.0)' fill='darkslateblue'>&gt;</text>
-                       <text x='20' y='280' id='longitudeIso'>Longitude</text>
-                       <text x='198' y='280' onclick='displayIsoByLongitude(globalLongitude-1.0)' fill='darkslateblue'>&lt;</text>
-                       <text x='213' y='280' onclick='displayIsoByLongitude(globalLongitude+1.0)' fill='darkslateblue'>&gt;</text>
-                       <text x='20' y='300'>Scale</text>
-                       <text x='65' y='300' id='scaleIso'>1</text>
-                       <text x='198' y='300' onclick='changeScaleIso(globalZoomScale/2)' fill='darkslateblue'>&lt;</text>
-                       <text x='213' y='300' onclick='changeScaleIso(globalZoomScale*2)' fill='darkslateblue'>&gt;</text>
-                       <g transform='translate(20, 340)'>
-                               <text>Min</text>
-                               <text id='minXIso' y='20'></text>
-                               <text id='minYIso' y='40'></text>
-                               <text id='minZIso' y='60'></text>
-                       </g>
-                       <g transform='translate(20, 440)'>
-                               <text>Max</text>
-                               <text id='maxXIso' y='20'></text>
-                               <text id='maxYIso' y='40'></text>
-                               <text id='maxZIso' y='60'></text>
-                       </g>
-                       <g transform='translate(20, 540)'>
-                               <text>Dimension</text>
-                               <text id='dimXIso' y='20'></text>
-                               <text id='dimYIso' y='40'></text>
-                               <text id='dimZIso' y='60'></text>
-                       </g>
-                       <g transform='translate(20, 640)'>
-                               <text>Statistics</text>
-                               <text y='20' id='layerHeightIso' ></text>
-                               <text y='40' id='numberOfLayersIso' ></text>
-                               <text y='60' id='volumeIso' ></text>
-                       </g>
-               </g>
-               <!--id='layerControlBox' must be there so that the controls could be removed if necessary-->
-               <g id='layerControlBox' fill='#000' font-family='Arial' font-size='15px' font-weight='bold' transform='translate(20, 60)' visibility='hidden'>
-                       <rect width='240' height='720' stroke='gray' stroke-width='4px' fill='silver'/> 
-                       <path stroke-width='0' d='M 66 164 h76 v6 l18 -9 l-18 -9 v6 h-70 v-70 h6 l-9 -18 l-9 18 h6 z'/>
-                       <!--<path stroke='#000' stroke-width='3' d='M 20 20 h5 l-5 -10 l-5 10 h5 v35 h35 v-5 l10 5 l-10 5 v-5 h-35 z'/>-->
-                       <text x='68' y='64' text-anchor='middle'>Y</text>
-                       <text x='165' y='166'>X</text>
-                       <text x='20' y='245' id='minIndexLayer'>0</text>
-                       <rect id='slider' x='32' y='230' width='170' height='24' fill='gray'/>
-                       <circle id='thumb' cx='42' cy='242' r='12' fill='darkslateblue'/>
-                       <text x='203' y='245' id='maxIndexLayer'>1</text>
-                       <text x='20' y='280' id='currentIndexLayer'>Layer</text>
-                       <text x='198' y='280' id='decreaseLayerIndex' onclick='displayLayer(globalLayerIndex-1)' fill='darkslateblue'>&lt;</text>
-                       <text x='213' y='280' id='increaseLayerIndex' onclick='displayLayer(globalLayerIndex+1)' fill='darkslateblue'>&gt;</text>
-                       <text x='20' y='300'>Scale</text>
-                       <text x='65' y='300' id='scaleLayer'>1</text>
-                       <text x='198' y='300' onclick='changeScaleLayer(globalZoomScale/2)' fill='darkslateblue'>&lt;</text>
-                       <text x='213' y='300' onclick='changeScaleLayer(globalZoomScale*2)' fill='darkslateblue'>&gt;</text>
-                       <g transform='translate(20, 340)'>
-                               <text>Min</text>
-                               <text id='minXLayer' y='20'></text>
-                               <text id='minYLayer' y='40'></text>
-                               <text id='minZLayer' y='60'></text>
-                       </g>
-                       <g transform='translate(20, 440)'>
-                               <text>Max</text>
-                               <text id='maxXLayer' y='20'></text>
-                               <text id='maxYLayer' y='40'></text>
-                               <text id='maxZLayer' y='60'></text>
-                       </g>
-                       <g transform='translate(20, 540)'>
-                               <text>Dimension</text>
-                               <text id='dimXLayer' y='20'></text>
-                               <text id='dimYLayer' y='40'></text>
-                               <text id='dimZLayer' y='60'></text>
-                       </g>
-                       <g transform='translate(20, 640)'>
-                               <text>Statistics</text>
-                               <text y='20' id='layerHeightLayer' ></text>
-                               <text y='40' id='numberOfLayersLayer' ></text>
-                               <text y='60' id='volumeLayer' ></text>
-                       </g>
-               </g>
-               <!--id='scrollControlBox' must be there so that the controls could be removed if necessary-->
-               <g id='scrollControlBox' fill='#000' font-family='Arial' font-size='15px' font-weight='bold' transform='translate(20, 60)' visibility='visible'>
-                       <rect width='240' height='720' stroke='gray' stroke-width='4px' fill='silver'/> 
-                       <path stroke-width='0' d='M 66 164 h76 v6 l18 -9 l-18 -9 v6 h-70 v-70 h6 l-9 -18 l-9 18 h6 z'/>
-                       <text x='68' y='64' text-anchor='middle'>Y</text>
-                       <text x='165' y='166'>X</text>
-                       <text x='20' y='300'>Scale</text>
-                       <text x='65' y='300' id='scaleScroll'>: 1</text>
-                       <text x='198' y='300' onclick='changeScaleScroll(globalZoomScale/2)' fill='darkslateblue'>&lt;</text>
-                       <text x='213' y='300' onclick='changeScaleScroll(globalZoomScale*2)' fill='darkslateblue'>&gt;</text>
-                       <g transform='translate(20, 340)'>
-                               <text>Min</text>
-                               <text id='minXScroll' y='20'></text>
-                               <text id='minYScroll' y='40'></text>
-                               <text id='minZScroll' y='60'></text>
-                       </g>
-                       <g transform='translate(20, 440)'>
-                               <text>Max</text>
-                               <text id='maxXScroll' y='20'></text>
-                               <text id='maxYScroll' y='40'></text>
-                               <text id='maxZScroll' y='60'></text>
-                       </g>
-                       <g transform='translate(20, 540)'>
-                               <text>Dimension</text>
-                               <text id='dimXScroll' y='20'></text>
-                               <text id='dimYScroll' y='40'></text>
-                               <text id='dimZScroll' y='60'></text>
-                       </g>
-                       <g transform='translate(20, 640)'>
-                               <text>Statistics</text>
-                               <text y='20' id='layerHeightScroll' ></text>
-                               <text y='40' id='numberOfLayersScroll' ></text>
-                               <text y='60' id='volumeScroll' ></text>
-                       </g>
-               </g>
-               <text id='isoViewButton' x='80' y='30' fill='darkslateblue' font-size='18px' font-weight='normal' onclick='viewIso()'   text-anchor='middle' visibility='visible'>[Iso View]</text>
-               <text id='isoViewLabel' x='76' y='30' fill='darkslateblue' font-size='24px' font-weight='bold' text-anchor='middle' visibility='hidden'>Iso View</text>
-               <text id='layerViewButton' x='240' y='30' fill='darkslateblue' font-size='18px' font-weight='normal' onclick='viewLayer()' text-anchor='middle' visibility='visible'>[Layer View]</text>
-               <text id='layerViewLabel' x='236' y='30' fill='darkslateblue' font-size='24px' font-weight='bold' text-anchor='middle' visibility='hidden'>Layer View</text>
-               <text id='scrollViewButton' x='400' y='30' fill='darkslateblue' font-size='18px' font-weight='normal' onclick='viewScroll()' text-anchor='middle' visibility='hidden'>[Scroll View]</text>
-               <text id='scrollViewLabel' x='396' y='30' fill='darkslateblue' font-size='24px' font-weight='bold' text-anchor='middle' visibility='visible'>Scroll View</text>
-       </g>
-</svg>
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/vector3.py b/Cura/slice/cura_sf/fabmetheus_utilities/vector3.py
deleted file mode 100644 (file)
index 217534f..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-"""
-Vector3 is a three dimensional vector class.
-
-Below are examples of Vector3 use.
-
->>> from vector3 import Vector3
->>> origin = Vector3()
->>> origin
-0.0, 0.0, 0.0
->>> pythagoras = Vector3( 3, 4, 0 )
->>> pythagoras
-3.0, 4.0, 0.0
->>> pythagoras.magnitude()
-5.0
->>> pythagoras.magnitudeSquared()
-25
->>> triplePythagoras = pythagoras * 3.0
->>> triplePythagoras
-9.0, 12.0, 0.0
->>> plane = pythagoras.dropAxis()
->>> plane
-(3+4j)
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import xml_simple_writer
-import math
-import operator
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://forums.reprap.org/profile.php?12,28>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-class Vector3(object):
-       'A three dimensional vector class.'
-       __slots__ = ['x', 'y', 'z']
-
-       def __init__(self, x=0.0, y=0.0, z=0.0):
-               self.x = x
-               self.y = y
-               self.z = z
-
-       def __abs__(self):
-               'Get the magnitude of the Vector3.'
-               return math.sqrt( self.x * self.x + self.y * self.y + self.z * self.z )
-
-       magnitude = __abs__
-
-       def __add__(self, other):
-               'Get the sum of this Vector3 and other one.'
-               return Vector3( self.x + other.x, self.y + other.y, self.z + other.z )
-
-       def __copy__(self):
-               'Get the copy of this Vector3.'
-               return Vector3( self.x, self.y, self.z )
-
-       __pos__ = __copy__
-
-       copy = __copy__
-
-       def __div__(self, other):
-               'Get a new Vector3 by dividing each component of this one.'
-               return Vector3( self.x / other, self.y / other, self.z / other )
-
-       def __eq__(self, other):
-               'Determine whether this vector is identical to other one.'
-               if other == None:
-                       return False
-               if other.__class__ != self.__class__:
-                       return False
-               return self.x == other.x and self.y == other.y and self.z == other.z
-
-       def __floordiv__(self, other):
-               'Get a new Vector3 by floor dividing each component of this one.'
-               return Vector3( self.x // other, self.y // other, self.z // other )
-
-       def __hash__(self):
-               'Determine whether this vector is identical to other one.'
-               return self.__repr__().__hash__()
-
-       def __iadd__(self, other):
-               'Add other Vector3 to this one.'
-               self.x += other.x
-               self.y += other.y
-               self.z += other.z
-               return self
-
-       def __idiv__(self, other):
-               'Divide each component of this Vector3.'
-               self.x /= other
-               self.y /= other
-               self.z /= other
-               return self
-
-       def __ifloordiv__(self, other):
-               'Floor divide each component of this Vector3.'
-               self.x //= other
-               self.y //= other
-               self.z //= other
-               return self
-
-       def __imul__(self, other):
-               'Multiply each component of this Vector3.'
-               self.x *= other
-               self.y *= other
-               self.z *= other
-               return self
-
-       def __isub__(self, other):
-               'Subtract other Vector3 from this one.'
-               self.x -= other.x
-               self.y -= other.y
-               self.z -= other.z
-               return self
-
-       def __itruediv__(self, other):
-               'True divide each component of this Vector3.'
-               self.x = operator.truediv( self.x, other )
-               self.y = operator.truediv( self.y, other )
-               self.z = operator.truediv( self.z, other )
-               return self
-
-       def __mul__(self, other):
-               'Get a new Vector3 by multiplying each component of this one.'
-               return Vector3( self.x * other, self.y * other, self.z * other )
-
-       def __ne__(self, other):
-               'Determine whether this vector is not identical to other one.'
-               return not self.__eq__(other)
-
-       def __neg__(self):
-               return Vector3( - self.x, - self.y, - self.z )
-
-       def __nonzero__(self):
-               return self.x != 0 or self.y != 0 or self.z != 0
-
-       def __rdiv__(self, other):
-               'Get a new Vector3 by dividing each component of this one.'
-               return Vector3( other / self.x, other / self.y, other / self.z )
-
-       def __repr__(self):
-               'Get the string representation of this Vector3.'
-               return '(%s, %s, %s)' % ( self.x, self.y, self.z )
-
-       def __rfloordiv__(self, other):
-               'Get a new Vector3 by floor dividing each component of this one.'
-               return Vector3( other // self.x, other // self.y, other // self.z )
-
-       def __rmul__(self, other):
-               'Get a new Vector3 by multiplying each component of this one.'
-               return Vector3( self.x * other, self.y * other, self.z * other )
-
-       def __rtruediv__(self, other):
-               'Get a new Vector3 by true dividing each component of this one.'
-               return Vector3( operator.truediv( other , self.x ), operator.truediv( other, self.y ), operator.truediv( other, self.z ) )
-
-       def __sub__(self, other):
-               'Get the difference between the Vector3 and other one.'
-               return Vector3( self.x - other.x, self.y - other.y, self.z - other.z )
-
-       def __truediv__(self, other):
-               'Get a new Vector3 by true dividing each component of this one.'
-               return Vector3( operator.truediv( self.x, other ), operator.truediv( self.y, other ), operator.truediv( self.z, other ) )
-
-       def _getAccessibleAttribute(self, attributeName):
-               'Get the accessible attribute.'
-               if attributeName in globalGetAccessibleAttributeSet:
-                       return getattr(self, attributeName, None)
-               return None
-
-       def _setAccessibleAttribute(self, attributeName, value):
-               'Set the accessible attribute.'
-               if attributeName in globalSetAccessibleAttributeSet:
-                       setattr(self, attributeName, value)
-
-       def cross(self, other):
-               'Calculate the cross product of this vector with other one.'
-               return Vector3(self.y * other.z - self.z * other.y, -self.x * other.z + self.z * other.x, self.x * other.y - self.y * other.x)
-
-       def distance(self, other):
-               'Get the Euclidean distance between this vector and other one.'
-               return math.sqrt( self.distanceSquared(other) )
-
-       def distanceSquared(self, other):
-               'Get the square of the Euclidean distance between this vector and other one.'
-               separationX = self.x - other.x
-               separationY = self.y - other.y
-               separationZ = self.z - other.z
-               return separationX * separationX + separationY * separationY + separationZ * separationZ
-
-       def dot(self, other):
-               'Calculate the dot product of this vector with other one.'
-               return self.x * other.x + self.y * other.y + self.z * other.z
-
-       def dropAxis( self, which = 2 ):
-               'Get a complex by removing one axis of the vector3.'
-               if which == 0:
-                       return complex( self.y, self.z )
-               if which == 1:
-                       return complex( self.x, self.z )
-               if which == 2:
-                       return complex( self.x, self.y )
-
-       def getFloatList(self):
-               'Get the vector as a list of floats.'
-               return [ float( self.x ), float( self.y ), float( self.z ) ]
-
-       def getIsDefault(self):
-               'Determine if this is the zero vector.'
-               if self.x != 0.0:
-                       return False
-               if self.y != 0.0:
-                       return False
-               return self.z == 0.0
-
-       def getNormalized(self):
-               'Get the normalized Vector3.'
-               magnitude = abs(self)
-               if magnitude == 0.0:
-                       return self.copy()
-               return self / magnitude
-
-       def magnitudeSquared(self):
-               'Get the square of the magnitude of the Vector3.'
-               return self.x * self.x + self.y * self.y + self.z * self.z
-
-       def maximize(self, other):
-               'Maximize the Vector3.'
-               self.x = max(other.x, self.x)
-               self.y = max(other.y, self.y)
-               self.z = max(other.z, self.z)
-
-       def minimize(self, other):
-               'Minimize the Vector3.'
-               self.x = min(other.x, self.x)
-               self.y = min(other.y, self.y)
-               self.z = min(other.z, self.z)
-
-       def normalize(self):
-               'Scale each component of this Vector3 so that it has a magnitude of 1. If this Vector3 has a magnitude of 0, this method has no effect.'
-               magnitude = abs(self)
-               if magnitude != 0.0:
-                       self /= magnitude
-
-       def reflect( self, normal ):
-               'Reflect the Vector3 across the normal, which is assumed to be normalized.'
-               distance = 2 * ( self.x * normal.x + self.y * normal.y + self.z * normal.z )
-               return Vector3( self.x - distance * normal.x, self.y - distance * normal.y, self.z - distance * normal.z )
-
-       def setToVector3(self, other):
-               'Set this Vector3 to be identical to other one.'
-               self.x = other.x
-               self.y = other.y
-               self.z = other.z
-
-       def setToXYZ( self, x, y, z ):
-               'Set the x, y, and z components of this Vector3.'
-               self.x = x
-               self.y = y
-               self.z = z
-
-
-globalGetAccessibleAttributeSet = 'x y z'.split()
-globalSetAccessibleAttributeSet = globalGetAccessibleAttributeSet
-
-"""
-class Vector3:
-       __slots__ = ['x', 'y', 'z']
-
-
-       copy = __copy__
-
-       def __eq__(self, other):
-               if isinstance(other, Vector3):
-                       return self.x == other.x and \
-                                  self.y == other.y and \
-                                  self.z == other.z
-               else:
-                       assert hasattr(other, '__len__') and len(other) == 3
-                       return self.x == other[0] and \
-                                  self.y == other[1] and \
-                                  self.z == other[2]
-
-       def __getattr__(self, name):
-               try:
-                       return tuple([(self.x, self.y, self.z)['xyz'.index(c)] \
-                                                 for c in name])
-               except ValueError:
-                       raise AttributeError, name
-
-       def __getitem__(self, key):
-               return (self.x, self.y, self.z)[key]
-
-       def __iter__(self):
-               return iter((self.x, self.y, self.z))
-
-       def __len__(self):
-               return 3
-
-       def __repr__(self):
-               return 'Vector3(%.2f, %.2f, %.2f)' % (self.x,
-                                                                                         self.y,
-                                                                                         self.z)
-
-       if _enable_swizzle_set:
-               # This has detrimental performance on ordinary setattr as well
-               # if enabled
-               def __setattr__(self, name, value):
-                       if len(name) == 1:
-                               object.__setattr__(self, name, value)
-                       else:
-                               try:
-                                       l = [self.x, self.y, self.z]
-                                       for c, v in map(None, name, value):
-                                               l['xyz'.index(c)] = v
-                                       self.x, self.y, self.z = l
-                               except ValueError:
-                                       raise AttributeError, name
-
-       def __setitem__(self, key, value):
-               l = [self.x, self.y, self.z]
-               l[key] = value
-               self.x, self.y, self.z = l
-
-"""
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/vector3index.py b/Cura/slice/cura_sf/fabmetheus_utilities/vector3index.py
deleted file mode 100644 (file)
index 57470bb..0000000
+++ /dev/null
@@ -1,270 +0,0 @@
-"""
-Vector3 is a three dimensional vector class.
-
-Below are examples of Vector3 use.
-
->>> from vector3 import Vector3
->>> origin = Vector3()
->>> origin
-0.0, 0.0, 0.0
->>> pythagoras = Vector3( 3, 4, 0 )
->>> pythagoras
-3.0, 4.0, 0.0
->>> pythagoras.magnitude()
-5.0
->>> pythagoras.magnitudeSquared()
-25
->>> triplePythagoras = pythagoras * 3.0
->>> triplePythagoras
-9.0, 12.0, 0.0
->>> plane = pythagoras.dropAxis()
->>> plane
-(3+4j)
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import xml_simple_writer
-import math
-import operator
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://forums.reprap.org/profile.php?12,28>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-class Vector3Index(object):
-       'A three dimensional vector index class.'
-       __slots__ = ['index', 'x', 'y', 'z']
-
-       def __init__( self, index, x = 0.0, y = 0.0, z = 0.0 ):
-               self.index = index
-               self.x = x
-               self.y = y
-               self.z = z
-
-       def __abs__(self):
-               'Get the magnitude of the Vector3.'
-               return math.sqrt( self.x * self.x + self.y * self.y + self.z * self.z )
-
-       magnitude = __abs__
-
-       def __add__(self, other):
-               'Get the sum of this Vector3 and other one.'
-               return Vector3Index( self.index, self.x + other.x, self.y + other.y, self.z + other.z )
-
-       def __copy__(self):
-               'Get the copy of this Vector3.'
-               return Vector3Index( self.index, self.x, self.y, self.z )
-
-       __pos__ = __copy__
-
-       copy = __copy__
-
-       def __div__(self, other):
-               'Get a new Vector3 by dividing each component of this one.'
-               return Vector3Index( self.index, self.x / other, self.y / other, self.z / other )
-
-       def __eq__(self, other):
-               'Determine whether this vector is identical to other one.'
-               if other == None:
-                       return False
-               if other.__class__ != self.__class__:
-                       return False
-               return self.x == other.x and self.y == other.y and self.z == other.z
-
-       def __floordiv__(self, other):
-               'Get a new Vector3 by floor dividing each component of this one.'
-               return Vector3Index( self.index, self.x // other, self.y // other, self.z // other )
-
-       def __hash__(self):
-               'Determine whether this vector is identical to other one.'
-               return self.__repr__().__hash__()
-
-       def __iadd__(self, other):
-               'Add other Vector3 to this one.'
-               self.x += other.x
-               self.y += other.y
-               self.z += other.z
-               return self
-
-       def __idiv__(self, other):
-               'Divide each component of this Vector3.'
-               self.x /= other
-               self.y /= other
-               self.z /= other
-               return self
-
-       def __ifloordiv__(self, other):
-               'Floor divide each component of this Vector3.'
-               self.x //= other
-               self.y //= other
-               self.z //= other
-               return self
-
-       def __imul__(self, other):
-               'Multiply each component of this Vector3.'
-               self.x *= other
-               self.y *= other
-               self.z *= other
-               return self
-
-       def __isub__(self, other):
-               'Subtract other Vector3 from this one.'
-               self.x -= other.x
-               self.y -= other.y
-               self.z -= other.z
-               return self
-
-       def __itruediv__(self, other):
-               'True divide each component of this Vector3.'
-               self.x = operator.truediv( self.x, other )
-               self.y = operator.truediv( self.y, other )
-               self.z = operator.truediv( self.z, other )
-               return self
-
-       def __mul__(self, other):
-               'Get a new Vector3 by multiplying each component of this one.'
-               return Vector3Index( self.index, self.x * other, self.y * other, self.z * other )
-
-       def __ne__(self, other):
-               'Determine whether this vector is not identical to other one.'
-               return not self.__eq__(other)
-
-       def __neg__(self):
-               return Vector3Index( self.index, - self.x, - self.y, - self.z )
-
-       def __nonzero__(self):
-               return self.x != 0 or self.y != 0 or self.z != 0
-
-       def __rdiv__(self, other):
-               'Get a new Vector3 by dividing each component of this one.'
-               return Vector3Index( self.index, other / self.x, other / self.y, other / self.z )
-
-       def __repr__(self):
-               'Get the string representation of this Vector3 index.'
-               return '(%s, %s, %s, %s)' % (self.index, self.x, self.y, self.z)
-
-       def __rfloordiv__(self, other):
-               'Get a new Vector3 by floor dividing each component of this one.'
-               return Vector3Index( self.index, other // self.x, other // self.y, other // self.z )
-
-       def __rmul__(self, other):
-               'Get a new Vector3 by multiplying each component of this one.'
-               return Vector3Index( self.index, self.x * other, self.y * other, self.z * other )
-
-       def __rtruediv__(self, other):
-               'Get a new Vector3 by true dividing each component of this one.'
-               return Vector3Index( self.index, operator.truediv( other , self.x ), operator.truediv( other, self.y ), operator.truediv( other, self.z ) )
-
-       def __sub__(self, other):
-               'Get the difference between the Vector3 and other one.'
-               return Vector3Index( self.index, self.x - other.x, self.y - other.y, self.z - other.z )
-
-       def __truediv__(self, other):
-               'Get a new Vector3 by true dividing each component of this one.'
-               return Vector3Index( self.index, operator.truediv( self.x, other ), operator.truediv( self.y, other ), operator.truediv( self.z, other ) )
-
-       def _getAccessibleAttribute(self, attributeName):
-               'Get the accessible attribute.'
-               global globalGetAccessibleAttributeSet
-               if attributeName in globalGetAccessibleAttributeSet:
-                       return getattr(self, attributeName, None)
-               return None
-
-       def _setAccessibleAttribute(self, attributeName, value):
-               'Set the accessible attribute.'
-               if attributeName in globalSetAccessibleAttributeSet:
-                       setattr(self, attributeName, value)
-
-       def cross(self, other):
-               'Calculate the cross product of this vector with other one.'
-               return Vector3Index( self.index, self.y * other.z - self.z * other.y, - self.x * other.z + self.z * other.x, self.x * other.y - self.y * other.x )
-
-       def distance(self, other):
-               'Get the Euclidean distance between this vector and other one.'
-               return math.sqrt( self.distanceSquared(other) )
-
-       def distanceSquared(self, other):
-               'Get the square of the Euclidean distance between this vector and other one.'
-               separationX = self.x - other.x
-               separationY = self.y - other.y
-               separationZ = self.z - other.z
-               return separationX * separationX + separationY * separationY + separationZ * separationZ
-
-       def dot(self, other):
-               'Calculate the dot product of this vector with other one.'
-               return self.x * other.x + self.y * other.y + self.z * other.z
-
-       def dropAxis( self, which = 2 ):
-               'Get a complex by removing one axis of the vector3.'
-               if which == 0:
-                       return complex( self.y, self.z )
-               if which == 1:
-                       return complex( self.x, self.z )
-               if which == 2:
-                       return complex( self.x, self.y )
-
-       def getFloatList(self):
-               'Get the vector as a list of floats.'
-               return [ float( self.x ), float( self.y ), float( self.z ) ]
-
-       def getIsDefault(self):
-               'Determine if this is the zero vector.'
-               if self.x != 0.0:
-                       return False
-               if self.y != 0.0:
-                       return False
-               return self.z == 0.0
-
-       def getNormalized(self):
-               'Get the normalized Vector3.'
-               magnitude = abs(self)
-               if magnitude == 0.0:
-                       return self.copy()
-               return self / magnitude
-
-       def magnitudeSquared(self):
-               'Get the square of the magnitude of the Vector3.'
-               return self.x * self.x + self.y * self.y + self.z * self.z
-
-       def maximize(self, other):
-               'Maximize the Vector3.'
-               self.x = max(other.x, self.x)
-               self.y = max(other.y, self.y)
-               self.z = max(other.z, self.z)
-
-       def minimize(self, other):
-               'Minimize the Vector3.'
-               self.x = min(other.x, self.x)
-               self.y = min(other.y, self.y)
-               self.z = min(other.z, self.z)
-
-       def normalize(self):
-               'Scale each component of this Vector3 so that it has a magnitude of 1. If this Vector3 has a magnitude of 0, this method has no effect.'
-               magnitude = abs(self)
-               if magnitude != 0.0:
-                       self /= magnitude
-
-       def reflect( self, normal ):
-               'Reflect the Vector3 across the normal, which is assumed to be normalized.'
-               distance = 2 * ( self.x * normal.x + self.y * normal.y + self.z * normal.z )
-               return Vector3Index( self.index, self.x - distance * normal.x, self.y - distance * normal.y, self.z - distance * normal.z )
-
-       def setToVector3(self, other):
-               'Set this Vector3 to be identical to other one.'
-               self.x = other.x
-               self.y = other.y
-               self.z = other.z
-
-       def setToXYZ( self, x, y, z ):
-               'Set the x, y, and z components of this Vector3.'
-               self.x = x
-               self.y = y
-               self.z = z
-
-
-globalGetAccessibleAttributeSet = 'x y z'.split()
-globalSetAccessibleAttributeSet = globalGetAccessibleAttributeSet
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/version.txt b/Cura/slice/cura_sf/fabmetheus_utilities/version.txt
deleted file mode 100644 (file)
index 2dc4ea1..0000000
+++ /dev/null
@@ -1 +0,0 @@
-12.03.14
\ No newline at end of file
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/xml_simple_reader.py b/Cura/slice/cura_sf/fabmetheus_utilities/xml_simple_reader.py
deleted file mode 100644 (file)
index 1bf2e53..0000000
+++ /dev/null
@@ -1,847 +0,0 @@
-"""
-The xml_simple_reader.py script is an xml parser that can parse a line separated xml text.
-
-This xml parser will read a line seperated xml text and produce a tree of the xml with a document element.  Each element can have an attribute table, childNodes, a class name, parentNode, text and a link to the document element.
-
-This example gets an xml tree for the xml file boolean.xml.  This example is run in a terminal in the folder which contains boolean.xml and xml_simple_reader.py.
-
-
-> python
-Python 2.5.1 (r251:54863, Sep 22 2007, 01:43:31)
-[GCC 4.2.1 (SUSE Linux)] on linux2
-Type "help", "copyright", "credits" or "license" for more information.
->>> fileName = 'boolean.xml'
->>> file = open(fileName, 'r')
->>> xmlText = file.read()
->>> file.close()
->>> from xml_simple_reader import DocumentNode
->>> xmlParser = DocumentNode(fileName, xmlText)
->>> print(xmlParser)
-  ?xml, {'version': '1.0'}
-  ArtOfIllusion, {'xmlns:bf': '//babelfiche/codec', 'version': '2.0', 'fileversion': '3'}
-  Scene, {'bf:id': 'theScene'}
-  materials, {'bf:elem-type': 'java.lang.Object', 'bf:list': 'collection', 'bf:id': '1', 'bf:type': 'java.util.Vector'}
-..
-many more lines of the xml tree
-..
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.geometry.geometry_utilities import evaluate
-from fabmetheus_utilities.geometry.geometry_utilities import matrix
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import xml_simple_writer
-import cStringIO
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-globalGetAccessibleAttributeSet = set('getPaths getPreviousVertex getPreviousElementNode getVertexes parentNode'.split())
-
-
-def createAppendByText(parentNode, xmlText):
-       'Create and append the child nodes from the xmlText.'
-       monad = OpenMonad(parentNode)
-       for character in xmlText:
-               monad = monad.getNextMonad(character)
-
-def createAppendByTextb(parentNode, xmlText):
-       'Create and append the child nodes from the xmlText.'
-       monad = OpenMonad(parentNode)
-       for character in xmlText:
-               monad = monad.getNextMonad(character)
-
-def getChildElementsByLocalName(childNodes, localName):
-       'Get the childNodes which have the given local name.'
-       childElementsByLocalName = []
-       for childNode in childNodes:
-               if localName.lower() == childNode.getNodeName():
-                       childElementsByLocalName.append(childNode)
-       return childElementsByLocalName
-
-def getDocumentNode(fileName):
-       'Get the document from the file name.'
-       xmlText = getFileText('test.xml')
-       return DocumentNode(fileName, xmlText)
-
-def getElementsByLocalName(childNodes, localName):
-       'Get the descendents which have the given local name.'
-       elementsByLocalName = getChildElementsByLocalName(childNodes, localName)
-       for childNode in childNodes:
-               if childNode.getNodeType() == 1:
-                       elementsByLocalName += childNode.getElementsByLocalName(localName)
-       return elementsByLocalName
-
-def getFileText(fileName, printWarning=True, readMode='r'):
-       'Get the entire text of a file.'
-       try:
-               file = open(fileName, readMode)
-               fileText = file.read()
-               file.close()
-               return fileText
-       except IOError:
-               if printWarning:
-                       print('The file ' + fileName + ' does not exist.')
-       return ''
-
-
-class CDATASectionMonad(object):
-       'A monad to handle a CDATASection node.'
-       def __init__(self, input, parentNode):
-               'Initialize.'
-               self.input = input
-               self.parentNode = parentNode
-
-       def getNextMonad(self, character):
-               'Get the next monad.'
-               self.input.write(character)
-               if character == '>':
-                       inputString = self.input.getvalue()
-                       if inputString.endswith(']]>'):
-                               textContent = '<%s\n' % inputString
-                               self.parentNode.childNodes.append(CDATASectionNode(self.parentNode, textContent))
-                               return OpenMonad(self.parentNode)
-               return self
-
-
-class CDATASectionNode(object):
-       'A CDATASection node.'
-       def __init__(self, parentNode, textContent=''):
-               'Initialize.'
-               self.parentNode = parentNode
-               self.textContent = textContent
-
-       def __repr__(self):
-               'Get the string representation of this CDATASection node.'
-               return self.textContent
-
-       def addToIdentifierDictionaries(self):
-               'Add the element to the owner document identifier dictionaries.'
-               pass
-
-       def addXML(self, depth, output):
-               'Add xml for this CDATASection node.'
-               output.write(self.textContent)
-
-       def appendSelfToParent(self):
-               'Append self to the parentNode.'
-               self.parentNode.appendChild(self)
-
-       def copyXMLChildNodes(self, idSuffix, parentNode):
-               'Copy the xml childNodes.'
-               pass
-
-       def getAttributes(self):
-               'Get the attributes.'
-               return {}
-
-       def getChildNodes(self):
-               'Get the empty set.'
-               return []
-
-       def getCopy(self, idSuffix, parentNode):
-               'Copy the xml element, set its dictionary and add it to the parentNode.'
-               copy = self.getCopyShallow()
-               copy.parentNode = parentNode
-               copy.appendSelfToParent()
-               return copy
-
-       def getCopyShallow(self, attributes=None):
-               'Copy the node and set its parentNode.'
-               return CDATASectionNode(self.parentNode, self.textContent)
-
-       def getNodeName(self):
-               'Get the node name.'
-               return '#cdata-section'
-
-       def getNodeType(self):
-               'Get the node type.'
-               return 4
-
-       def getOwnerDocument(self):
-               'Get the owner document.'
-               return self.parentNode.getOwnerDocument()
-
-       def getTextContent(self):
-               'Get the text content.'
-               return self.textContent
-
-       def removeChildNodesFromIDNameParent(self):
-               'Remove the childNodes from the id and name dictionaries and the childNodes.'
-               pass
-
-       def removeFromIDNameParent(self):
-               'Remove this from the id and name dictionaries and the childNodes of the parentNode.'
-               if self.parentNode != None:
-                       self.parentNode.childNodes.remove(self)
-
-       def setParentAddToChildNodes(self, parentNode):
-               'Set the parentNode and add this to its childNodes.'
-               self.parentNode = parentNode
-               if self.parentNode != None:
-                       self.parentNode.childNodes.append(self)
-
-       attributes = property(getAttributes)
-       childNodes = property(getChildNodes)
-       nodeName = property(getNodeName)
-       nodeType = property(getNodeType)
-       ownerDocument = property(getOwnerDocument)
-
-
-class CommentMonad(CDATASectionMonad):
-       'A monad to handle a comment node.'
-       def getNextMonad(self, character):
-               'Get the next monad.'
-               self.input.write(character)
-               if character == '>':
-                       inputString = self.input.getvalue()
-                       if inputString.endswith('-->'):
-                               textContent = '<%s\n' % inputString
-                               self.parentNode.childNodes.append(CommentNode(self.parentNode, textContent))
-                               return OpenMonad(self.parentNode)
-               return self
-
-
-class CommentNode(CDATASectionNode):
-       'A comment node.'
-       def getCopyShallow(self, attributes=None):
-               'Copy the node and set its parentNode.'
-               return CommentNode(self.parentNode, self.textContent)
-
-       def getNodeName(self):
-               'Get the node name.'
-               return '#comment'
-
-       def getNodeType(self):
-               'Get the node type.'
-               return 8
-
-       nodeName = property(getNodeName)
-       nodeType = property(getNodeType)
-
-
-class DocumentNode(object):
-       'A class to parse an xml text and store the elements.'
-       def __init__(self, fileName, xmlText):
-               'Initialize.'
-               self.childNodes = []
-               self.fileName = fileName
-               self.idDictionary = {}
-               self.nameDictionary = {}
-               self.parentNode = None
-               self.tagDictionary = {}
-               self.xmlText = xmlText
-               createAppendByText(self, xmlText)
-
-       def __repr__(self):
-               'Get the string representation of this xml document.'
-               output = cStringIO.StringIO()
-               for childNode in self.childNodes:
-                       childNode.addXML(0, output)
-               return output.getvalue()
-
-       def appendChild(self, elementNode):
-               'Append child elementNode to the child nodes.'
-               self.childNodes.append(elementNode)
-               elementNode.addToIdentifierDictionaries()
-               return elementNode
-
-       def getAttributes(self):
-               'Get the attributes.'
-               return {}
-
-       def getCascadeBoolean(self, defaultBoolean, key):
-               'Get the cascade boolean.'
-               return defaultBoolean
-
-       def getCascadeFloat(self, defaultFloat, key):
-               'Get the cascade float.'
-               return defaultFloat
-
-       def getDocumentElement(self):
-               'Get the document element.'
-               if len(self.childNodes) == 0:
-                       return None
-               return self.childNodes[-1]
-
-       def getElementsByLocalName(self, localName):
-               'Get the descendents which have the given local name.'
-               return getElementsByLocalName(self.childNodes, localName)
-
-       def getImportNameChain(self, suffix=''):
-               'Get the import name chain with the suffix at the end.'
-               return suffix
-
-       def getNodeName(self):
-               'Get the node name.'
-               return '#document'
-
-       def getNodeType(self):
-               'Get the node type.'
-               return 9
-
-       def getOriginalRoot(self):
-               'Get the original reparsed document element.'
-               if evaluate.getEvaluatedBoolean(True, self.documentElement, 'getOriginalRoot'):
-                       return DocumentNode(self.fileName, self.xmlText).documentElement
-               return None
-
-       def getOwnerDocument(self):
-               'Get the owner document.'
-               return self
-
-       attributes = property(getAttributes)
-       documentElement = property(getDocumentElement)
-       nodeName = property(getNodeName)
-       nodeType = property(getNodeType)
-       ownerDocument = property(getOwnerDocument)
-
-
-class DocumentTypeMonad(CDATASectionMonad):
-       'A monad to handle a document type node.'
-       def getNextMonad(self, character):
-               'Get the next monad.'
-               self.input.write(character)
-               if character == '>':
-                       inputString = self.input.getvalue()
-                       if inputString.endswith('?>'):
-                               textContent = '%s\n' % inputString
-                               self.parentNode.childNodes.append(DocumentTypeNode(self.parentNode, textContent))
-                               return OpenMonad(self.parentNode)
-               return self
-
-
-class DocumentTypeNode(CDATASectionNode):
-       'A document type node.'
-       def getCopyShallow(self, attributes=None):
-               'Copy the node and set its parentNode.'
-               return DocumentTypeNode(self.parentNode, self.textContent)
-
-       def getNodeName(self):
-               'Get the node name.'
-               return '#forNowDocumentType'
-
-       def getNodeType(self):
-               'Get the node type.'
-               return 10
-
-       nodeName = property(getNodeName)
-       nodeType = property(getNodeType)
-
-
-class ElementEndMonad(object):
-       'A monad to look for the end of an ElementNode tag.'
-       def __init__(self, parentNode):
-               'Initialize.'
-               self.parentNode = parentNode
-
-       def getNextMonad(self, character):
-               'Get the next monad.'
-               if character == '>':
-                       return TextMonad(self.parentNode)
-               return self
-
-
-class ElementLocalNameMonad(object):
-       'A monad to set the local name of an ElementNode.'
-       def __init__(self, character, parentNode):
-               'Initialize.'
-               self.input = cStringIO.StringIO()
-               self.input.write(character)
-               self.parentNode = parentNode
-
-       def getNextMonad(self, character):
-               'Get the next monad.'
-               if character == '[':
-                       if (self.input.getvalue() + character).startswith('![CDATA['):
-                               self.input.write(character)
-                               return CDATASectionMonad(self.input, self.parentNode)
-               if character == '-':
-                       if (self.input.getvalue() + character).startswith('!--'):
-                               self.input.write(character)
-                               return CommentMonad(self.input, self.parentNode)
-               if character.isspace():
-                       self.setLocalName()
-                       return ElementReadMonad(self.elementNode)
-               if character == '/':
-                       self.setLocalName()
-                       self.elementNode.appendSelfToParent()
-                       return ElementEndMonad(self.elementNode.parentNode)
-               if character == '>':
-                       self.setLocalName()
-                       self.elementNode.appendSelfToParent()
-                       return TextMonad(self.elementNode)
-               self.input.write(character)
-               return self
-
-       def setLocalName(self):
-               'Set the class name.'
-               self.elementNode = ElementNode(self.parentNode)
-               self.elementNode.localName = self.input.getvalue().lower().strip()
-
-
-class ElementNode(object):
-       'An xml element.'
-       def __init__(self, parentNode=None):
-               'Initialize.'
-               self.attributes = {}
-               self.childNodes = []
-               self.localName = ''
-               self.parentNode = parentNode
-               self.xmlObject = None
-
-       def __repr__(self):
-               'Get the string representation of this xml document.'
-               return '%s\n%s\n%s' % (self.localName, self.attributes, self.getTextContent())
-
-       def _getAccessibleAttribute(self, attributeName):
-               'Get the accessible attribute.'
-               global globalGetAccessibleAttributeSet
-               if attributeName in globalGetAccessibleAttributeSet:
-                       return getattr(self, attributeName, None)
-               return None
-
-       def addSuffixToID(self, idSuffix):
-               'Add the suffix to the id.'
-               if 'id' in self.attributes:
-                       self.attributes['id'] += idSuffix
-
-       def addToIdentifierDictionaries(self):
-               'Add the element to the owner document identifier dictionaries.'
-               ownerDocument = self.getOwnerDocument()
-               importNameChain = self.getImportNameChain()
-               idKey = self.getStrippedAttributesValue('id')
-               if idKey != None:
-                       ownerDocument.idDictionary[importNameChain + idKey] = self
-               nameKey = self.getStrippedAttributesValue('name')
-               if nameKey != None:
-                       euclidean.addElementToListDictionaryIfNotThere(self, importNameChain + nameKey, ownerDocument.nameDictionary)
-               for tagKey in self.getTagKeys():
-                       euclidean.addElementToListDictionaryIfNotThere(self, tagKey, ownerDocument.tagDictionary)
-
-       def addXML(self, depth, output):
-               'Add xml for this elementNode.'
-               innerOutput = cStringIO.StringIO()
-               xml_simple_writer.addXMLFromObjects(depth + 1, self.childNodes, innerOutput)
-               innerText = innerOutput.getvalue()
-               xml_simple_writer.addBeginEndInnerXMLTag(self.attributes, depth, innerText, self.localName, output, self.getTextContent())
-
-       def appendChild(self, elementNode):
-               'Append child elementNode to the child nodes.'
-               self.childNodes.append(elementNode)
-               elementNode.addToIdentifierDictionaries()
-               return elementNode
-
-       def appendSelfToParent(self):
-               'Append self to the parentNode.'
-               self.parentNode.appendChild(self)
-
-       def copyXMLChildNodes(self, idSuffix, parentNode):
-               'Copy the xml childNodes.'
-               for childNode in self.childNodes:
-                       childNode.getCopy(idSuffix, parentNode)
-
-       def getCascadeBoolean(self, defaultBoolean, key):
-               'Get the cascade boolean.'
-               if key in self.attributes:
-                       value = evaluate.getEvaluatedBoolean(None, self, key)
-                       if value != None:
-                               return value
-               return self.parentNode.getCascadeBoolean(defaultBoolean, key)
-
-       def getCascadeFloat(self, defaultFloat, key):
-               'Get the cascade float.'
-               if key in self.attributes:
-                       value = evaluate.getEvaluatedFloat(None, self, key)
-                       if value != None:
-                               return value
-               return self.parentNode.getCascadeFloat(defaultFloat, key)
-
-       def getChildElementsByLocalName(self, localName):
-               'Get the childNodes which have the given local name.'
-               return getChildElementsByLocalName(self.childNodes, localName)
-
-       def getCopy(self, idSuffix, parentNode):
-               'Copy the xml element, set its dictionary and add it to the parentNode.'
-               matrix4X4 = matrix.getBranchMatrixSetElementNode(self)
-               attributesCopy = self.attributes.copy()
-               attributesCopy.update(matrix4X4.getAttributes('matrix.'))
-               copy = self.getCopyShallow(attributesCopy)
-               copy.setParentAddToChildNodes(parentNode)
-               copy.addSuffixToID(idSuffix)
-               copy.addToIdentifierDictionaries()
-               self.copyXMLChildNodes(idSuffix, copy)
-               return copy
-
-       def getCopyShallow(self, attributes=None):
-               'Copy the xml element and set its dictionary and parentNode.'
-               if attributes == None: # to evade default initialization bug where a dictionary is initialized to the last dictionary
-                       attributes = {}
-               copyShallow = ElementNode(self.parentNode)
-               copyShallow.attributes = attributes
-               copyShallow.localName = self.localName
-               return copyShallow
-
-       def getDocumentElement(self):
-               'Get the document element.'
-               return self.getOwnerDocument().getDocumentElement()
-
-       def getElementNodeByID(self, idKey):
-               'Get the xml element by id.'
-               idDictionary = self.getOwnerDocument().idDictionary
-               idKey = self.getImportNameChain() + idKey
-               if idKey in idDictionary:
-                       return idDictionary[idKey]
-               return None
-
-       def getElementNodesByName(self, nameKey):
-               'Get the xml elements by name.'
-               nameDictionary = self.getOwnerDocument().nameDictionary
-               nameKey = self.getImportNameChain() + nameKey
-               if nameKey in nameDictionary:
-                       return nameDictionary[nameKey]
-               return None
-
-       def getElementNodesByTag(self, tagKey):
-               'Get the xml elements by tag.'
-               tagDictionary = self.getOwnerDocument().tagDictionary
-               if tagKey in tagDictionary:
-                       return tagDictionary[tagKey]
-               return None
-
-       def getElementsByLocalName(self, localName):
-               'Get the descendents which have the given local name.'
-               return getElementsByLocalName(self.childNodes, localName)
-
-       def getFirstChildByLocalName(self, localName):
-               'Get the first childNode which has the given class name.'
-               for childNode in self.childNodes:
-                       if localName.lower() == childNode.getNodeName():
-                               return childNode
-               return None
-
-       def getIDSuffix(self, elementIndex=None):
-               'Get the id suffix from the dictionary.'
-               suffix = self.localName
-               if 'id' in self.attributes:
-                       suffix = self.attributes['id']
-               if elementIndex == None:
-                       return '_%s' % suffix
-               return '_%s_%s' % (suffix, elementIndex)
-
-       def getImportNameChain(self, suffix=''):
-               'Get the import name chain with the suffix at the end.'
-               importName = self.getStrippedAttributesValue('_importName')
-               if importName != None:
-                       suffix = '%s.%s' % (importName, suffix)
-               return self.parentNode.getImportNameChain(suffix)
-
-       def getNodeName(self):
-               'Get the node name.'
-               return self.localName
-
-       def getNodeType(self):
-               'Get the node type.'
-               return 1
-
-       def getOwnerDocument(self):
-               'Get the owner document.'
-               return self.parentNode.getOwnerDocument()
-
-       def getParser(self):
-               'Get the parser.'
-               return self.getOwnerDocument()
-
-       def getPaths(self):
-               'Get all paths.'
-               if self.xmlObject == None:
-                       return []
-               return self.xmlObject.getPaths()
-
-       def getPreviousElementNode(self):
-               'Get previous ElementNode if it exists.'
-               if self.parentNode == None:
-                       return None
-               previousElementNodeIndex = self.parentNode.childNodes.index(self) - 1
-               if previousElementNodeIndex < 0:
-                       return None
-               return self.parentNode.childNodes[previousElementNodeIndex]
-
-       def getPreviousVertex(self, defaultVector3=None):
-               'Get previous vertex if it exists.'
-               if self.parentNode == None:
-                       return defaultVector3
-               if self.parentNode.xmlObject == None:
-                       return defaultVector3
-               if len(self.parentNode.xmlObject.vertexes) < 1:
-                       return defaultVector3
-               return self.parentNode.xmlObject.vertexes[-1]
-
-       def getStrippedAttributesValue(self, keyString):
-               'Get the stripped attribute value if the length is at least one, otherwise return None.'
-               if keyString in self.attributes:
-                       strippedAttributesValue = self.attributes[keyString].strip()
-                       if len(strippedAttributesValue) > 0:
-                               return strippedAttributesValue
-               return None
-
-       def getSubChildWithID( self, idReference ):
-               'Get the childNode which has the idReference.'
-               for childNode in self.childNodes:
-                       if 'bf:id' in childNode.attributes:
-                               if childNode.attributes['bf:id'] == idReference:
-                                       return childNode
-                       subChildWithID = childNode.getSubChildWithID( idReference )
-                       if subChildWithID != None:
-                               return subChildWithID
-               return None
-
-       def getTagKeys(self):
-               'Get stripped tag keys.'
-               if 'tags' not in self.attributes:
-                       return []
-               tagKeys = []
-               tagString = self.attributes['tags']
-               if tagString.startswith('='):
-                       tagString = tagString[1 :]
-               if tagString.startswith('['):
-                       tagString = tagString[1 :]
-               if tagString.endswith(']'):
-                       tagString = tagString[: -1]
-               for tagWord in tagString.split(','):
-                       tagKey = tagWord.strip()
-                       if tagKey != '':
-                               tagKeys.append(tagKey)
-               return tagKeys
-
-       def getTextContent(self):
-               'Get the text from the child nodes.'
-               if len(self.childNodes) == 0:
-                       return ''
-               firstNode = self.childNodes[0]
-               if firstNode.nodeType == 3:
-                       return firstNode.textContent
-               return ''
-
-       def getValueByKey( self, key ):
-               'Get value by the key.'
-               if key in evaluate.globalElementValueDictionary:
-                       return evaluate.globalElementValueDictionary[key](self)
-               if key in self.attributes:
-                       return evaluate.getEvaluatedLinkValue(self, self.attributes[key])
-               return None
-
-       def getVertexes(self):
-               'Get the vertexes.'
-               if self.xmlObject == None:
-                       return []
-               return self.xmlObject.getVertexes()
-
-       def getXMLProcessor(self):
-               'Get the xmlProcessor.'
-               return self.getDocumentElement().xmlProcessor
-
-       def linkObject(self, xmlObject):
-               'Link self to xmlObject and add xmlObject to archivableObjects.'
-               self.xmlObject = xmlObject
-               self.xmlObject.elementNode = self
-               self.parentNode.xmlObject.archivableObjects.append(self.xmlObject)
-
-       def printAllVariables(self):
-               'Print all variables.'
-               print('attributes')
-               print(self.attributes)
-               print('childNodes')
-               print(self.childNodes)
-               print('localName')
-               print(self.localName)
-               print('parentNode')
-               print(self.parentNode.getNodeName())
-               print('text')
-               print(self.getTextContent())
-               print('xmlObject')
-               print(self.xmlObject)
-               print('')
-
-       def printAllVariablesRoot(self):
-               'Print all variables and the document element variables.'
-               self.printAllVariables()
-               documentElement = self.getDocumentElement()
-               if documentElement != None:
-                       print('')
-                       print('Root variables:')
-                       documentElement.printAllVariables()
-
-       def removeChildNodesFromIDNameParent(self):
-               'Remove the childNodes from the id and name dictionaries and the childNodes.'
-               childNodesCopy = self.childNodes[:]
-               for childNode in childNodesCopy:
-                       childNode.removeFromIDNameParent()
-
-       def removeFromIDNameParent(self):
-               'Remove this from the id and name dictionaries and the childNodes of the parentNode.'
-               self.removeChildNodesFromIDNameParent()
-               idKey = self.getStrippedAttributesValue('id')
-               if idKey != None:
-                       idDictionary = self.getOwnerDocument().idDictionary
-                       idKey = self.getImportNameChain() + idKey
-                       if idKey in idDictionary:
-                               del idDictionary[idKey]
-               nameKey = self.getStrippedAttributesValue('name')
-               if nameKey != None:
-                       euclidean.removeElementFromListTable(self, self.getImportNameChain() + nameKey, self.getOwnerDocument().nameDictionary)
-               for tagKey in self.getTagKeys():
-                       euclidean.removeElementFromListTable(self, tagKey, self.getOwnerDocument().tagDictionary)
-               if self.parentNode != None:
-                       self.parentNode.childNodes.remove(self)
-
-       def setParentAddToChildNodes(self, parentNode):
-               'Set the parentNode and add this to its childNodes.'
-               self.parentNode = parentNode
-               if self.parentNode != None:
-                       self.parentNode.childNodes.append(self)
-
-       def setTextContent(self, textContent=''):
-               'Get the text from the child nodes.'
-               if len(self.childNodes) == 0:
-                       self.childNodes.append(TextNode(self, textContent))
-                       return
-               firstNode = self.childNodes[0]
-               if firstNode.nodeType == 3:
-                       firstNode.textContent = textContent
-               self.childNodes.append(TextNode(self, textContent))
-
-       nodeName = property(getNodeName)
-       nodeType = property(getNodeType)
-       ownerDocument = property(getOwnerDocument)
-       textContent = property(getTextContent)
-
-
-class ElementReadMonad(object):
-       'A monad to read the attributes of the ElementNode tag.'
-       def __init__(self, elementNode):
-               'Initialize.'
-               self.elementNode = elementNode
-
-       def getNextMonad(self, character):
-               'Get the next monad.'
-               if character.isspace():
-                       return self
-               if character == '/':
-                       self.elementNode.appendSelfToParent()
-                       return ElementEndMonad(self.elementNode.parentNode)
-               if character == '>':
-                       self.elementNode.appendSelfToParent()
-                       return TextMonad(self.elementNode)
-               return KeyMonad(character, self.elementNode)
-
-
-class KeyMonad(object):
-       'A monad to set the key of an attribute of an ElementNode.'
-       def __init__(self, character, elementNode):
-               'Initialize.'
-               self.input = cStringIO.StringIO()
-               self.input.write(character)
-               self.elementNode = elementNode
-
-       def getNextMonad(self, character):
-               'Get the next monad.'
-               if character == '=':
-                       return ValueMonad(self.elementNode, self.input.getvalue().strip())
-               self.input.write(character)
-               return self
-
-
-class OpenChooseMonad(ElementEndMonad):
-       'A monad to choose the next monad.'
-       def getNextMonad(self, character):
-               'Get the next monad.'
-               if character.isspace():
-                       return self
-               if character == '?':
-                       input = cStringIO.StringIO()
-                       input.write('<?')
-                       return DocumentTypeMonad(input, self.parentNode)
-               if character == '/':
-                       return ElementEndMonad(self.parentNode.parentNode)
-               return ElementLocalNameMonad(character, self.parentNode)
-
-
-class OpenMonad(ElementEndMonad):
-       'A monad to handle the open tag character.'
-       def getNextMonad(self, character):
-               'Get the next monad.'
-               if character == '<':
-                       return OpenChooseMonad(self.parentNode)
-               return self
-
-
-class TextMonad(object):
-       'A monad to handle the open tag character and set the text.'
-       def __init__(self, parentNode):
-               'Initialize.'
-               self.input = cStringIO.StringIO()
-               self.parentNode = parentNode
-
-       def getNextMonad(self, character):
-               'Get the next monad.'
-               if character == '<':
-                       inputString = self.input.getvalue().strip()
-                       if len(inputString) > 0:
-                               self.parentNode.childNodes.append(TextNode(self.parentNode, inputString))
-                       return OpenChooseMonad(self.parentNode)
-               self.input.write(character)
-               return self
-
-
-class TextNode(CDATASectionNode):
-       'A text node.'
-       def addXML(self, depth, output):
-               'Add xml for this text node.'
-               pass
-
-       def getCopyShallow(self, attributes=None):
-               'Copy the node and set its parentNode.'
-               return TextNode(self.parentNode, self.textContent)
-
-       def getNodeName(self):
-               'Get the node name.'
-               return '#text'
-
-       def getNodeType(self):
-               'Get the node type.'
-               return 3
-
-       nodeName = property(getNodeName)
-       nodeType = property(getNodeType)
-
-
-class ValueMonad(object):
-       'A monad to set the value of an attribute of an ElementNode.'
-       def __init__(self, elementNode, key):
-               'Initialize.'
-               self.elementNode = elementNode
-               self.input = cStringIO.StringIO()
-               self.key = key
-               self.quoteCharacter = None
-
-       def getNextMonad(self, character):
-               'Get the next monad.'
-               if self.quoteCharacter == None:
-                       if character == '"' or character == "'":
-                               self.quoteCharacter = character
-                       return self
-               if self.quoteCharacter == character:
-                       self.elementNode.attributes[self.key] = self.input.getvalue()
-                       return ElementReadMonad(self.elementNode)
-               self.input.write(character)
-               return self
-
diff --git a/Cura/slice/cura_sf/fabmetheus_utilities/xml_simple_writer.py b/Cura/slice/cura_sf/fabmetheus_utilities/xml_simple_writer.py
deleted file mode 100644 (file)
index edbaa10..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-"""
-XML tag writer utilities.
-
-"""
-
-
-from __future__ import absolute_import
-
-import sys
-
-if sys.version_info[0] < 3:
-       import cStringIO
-else:
-       import io as cStringIO
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addBeginEndInnerXMLTag(attributes, depth, innerText, localName, output, text=''):
-       'Add the begin and end xml tag and the inner text if any.'
-       if len( innerText ) > 0:
-               addBeginXMLTag(attributes, depth, localName, output, text)
-               output.write( innerText )
-               addEndXMLTag(depth, localName, output)
-       else:
-               addClosedXMLTag(attributes, depth, localName, output, text)
-
-def addBeginXMLTag(attributes, depth, localName, output, text=''):
-       'Add the begin xml tag.'
-       depthStart = '\t' * depth
-       output.write('%s<%s%s>%s\n' % (depthStart, localName, getAttributesString(attributes), text))
-
-def addClosedXMLTag(attributes, depth, localName, output, text=''):
-       'Add the closed xml tag.'
-       depthStart = '\t' * depth
-       attributesString = getAttributesString(attributes)
-       if len(text) > 0:
-               output.write('%s<%s%s >%s</%s>\n' % (depthStart, localName, attributesString, text, localName))
-       else:
-               output.write('%s<%s%s />\n' % (depthStart, localName, attributesString))
-
-def addEndXMLTag(depth, localName, output):
-       'Add the end xml tag.'
-       depthStart = '\t' * depth
-       output.write('%s</%s>\n' % (depthStart, localName))
-
-def addXMLFromLoopComplexZ(attributes, depth, loop, output, z):
-       'Add xml from loop.'
-       addBeginXMLTag(attributes, depth, 'path', output)
-       for pointComplexIndex in xrange(len(loop)):
-               pointComplex = loop[pointComplexIndex]
-               addXMLFromXYZ(depth + 1, pointComplexIndex, output, pointComplex.real, pointComplex.imag, z)
-       addEndXMLTag(depth, 'path', output)
-
-def addXMLFromObjects(depth, objects, output):
-       'Add xml from objects.'
-       for object in objects:
-               object.addXML(depth, output)
-
-def addXMLFromVertexes(depth, output, vertexes):
-       'Add xml from loop.'
-       for vertexIndex in xrange(len(vertexes)):
-               vertex = vertexes[vertexIndex]
-               addXMLFromXYZ(depth + 1, vertexIndex, output, vertex.x, vertex.y, vertex.z)
-
-def addXMLFromXYZ(depth, index, output, x, y, z):
-       'Add xml from x, y & z.'
-       attributes = {'index' : str(index)}
-       if x != 0.0:
-               attributes['x'] = str(x)
-       if y != 0.0:
-               attributes['y'] = str(y)
-       if z != 0.0:
-               attributes['z'] = str(z)
-       addClosedXMLTag(attributes, depth, 'vertex', output)
-
-def compareAttributeKeyAscending(key, otherKey):
-       'Get comparison in order to sort attribute keys in ascending order, with the id key first and name second.'
-       if key == 'id':
-               return - 1
-       if otherKey == 'id':
-               return 1
-       if key == 'name':
-               return - 1
-       if otherKey == 'name':
-               return 1
-       if key < otherKey:
-               return - 1
-       return int(key > otherKey)
-
-def getAttributesString(attributes):
-       'Add the closed xml tag.'
-       attributesString = ''
-       attributesKeys = attributes.keys()
-       attributesKeys.sort(compareAttributeKeyAscending)
-       for attributesKey in attributesKeys:
-               valueString = str(attributes[attributesKey])
-               if "'" in valueString:
-                       attributesString += ' %s="%s"' % (attributesKey, valueString)
-               else:
-                       attributesString += " %s='%s'" % (attributesKey, valueString)
-       return attributesString
-
-def getBeginGeometryXMLOutput(elementNode=None):
-       'Get the beginning of the string representation of this boolean geometry object info.'
-       output = getBeginXMLOutput()
-       attributes = {}
-       if elementNode != None:
-               documentElement = elementNode.getDocumentElement()
-               attributes = documentElement.attributes
-       addBeginXMLTag(attributes, 0, 'fabmetheus', output)
-       return output
-
-def getBeginXMLOutput():
-       'Get the beginning of the string representation of this object info.'
-       output = cStringIO.StringIO()
-       output.write("<?xml version='1.0' ?>\n")
-       return output
-
-def getDictionaryWithoutList(dictionary, withoutList):
-       'Get the dictionary without the keys in the list.'
-       dictionaryWithoutList = {}
-       for key in dictionary:
-               if key not in withoutList:
-                       dictionaryWithoutList[key] = dictionary[key]
-       return dictionaryWithoutList
-
-def getEndGeometryXMLString(output):
-       'Get the string representation of this object info.'
-       addEndXMLTag(0, 'fabmetheus', output)
-       return output.getvalue()
diff --git a/Cura/slice/cura_sf/skeinforge_application/__init__.py b/Cura/slice/cura_sf/skeinforge_application/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/__init__.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/analyze.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/analyze.py
deleted file mode 100644 (file)
index 415b7ee..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-"""
-This page is in the table of contents.
-Analyze is a script to access the plugins which analyze a gcode file.
-
-The plugin buttons which are commonly used are bolded and the ones which are rarely used have normal font weight.
-
-==Gcodes==
-An explanation of the gcodes is at:
-http://reprap.org/bin/view/Main/Arduino_GCode_Interpreter
-
-and at:
-http://reprap.org/bin/view/Main/MCodeReference
-
-A gode example is at:
-http://forums.reprap.org/file.php?12,file=565
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_analyze
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addToMenu(master, menu, repository, window):
-       "Add a tool plugin menu."
-       analyzeFilePath = archive.getSkeinforgePluginsPath('analyze.py')
-       pluginsDirectoryPath = skeinforge_analyze.getPluginsDirectoryPath()
-       settings.addPluginsParentToMenu(pluginsDirectoryPath, menu, analyzeFilePath, skeinforge_analyze.getPluginFileNames())
-
-def getNewRepository():
-       'Get new repository.'
-       return skeinforge_analyze.AnalyzeRepository()
-
-def writeOutput(fileName):
-       "Analyze a gcode file."
-       repository = getNewRepository()
-       repository.fileNameInput.value = fileName
-       repository.execute()
-       settings.startMainLoopFromConstructor(repository)
-
-
-def main():
-       "Display the analyze dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/analyze_plugins/__init__.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/analyze_plugins/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft.py
deleted file mode 100644 (file)
index 6b62583..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-"""
-This page is in the table of contents.
-Craft is a script to access the plugins which craft a gcode file.
-
-The plugin buttons which are commonly used are bolded and the ones which are rarely used have normal font weight.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import os
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addSubmenus( menu, pluginFileName, pluginFolderPath, pluginPath ):
-       "Add a tool plugin menu."
-       submenu = settings.Tkinter.Menu( menu, tearoff = 0 )
-       menu.add_cascade( label = pluginFileName.capitalize(), menu = submenu )
-       settings.ToolDialog().addPluginToMenu( submenu, pluginPath )
-       submenu.add_separator()
-       submenuFileNames = archive.getPluginFileNamesFromDirectoryPath( pluginFolderPath )
-       for submenuFileName in submenuFileNames:
-               settings.ToolDialog().addPluginToMenu( submenu, os.path.join( pluginFolderPath, submenuFileName ) )
-
-def addToCraftMenu( menu ):
-       "Add a craft plugin menu."
-       settings.ToolDialog().addPluginToMenu(menu, archive.getUntilDot(archive.getSkeinforgePluginsPath('craft.py')))
-       menu.add_separator()
-       directoryPath = skeinforge_craft.getPluginsDirectoryPath()
-       directoryFolders = settings.getFolders(directoryPath)
-       pluginFileNames = skeinforge_craft.getPluginFileNames()
-       for pluginFileName in pluginFileNames:
-               pluginFolderName = pluginFileName + '_plugins'
-               pluginPath = os.path.join( directoryPath, pluginFileName )
-               if pluginFolderName in directoryFolders:
-                       addSubmenus( menu, pluginFileName, os.path.join( directoryPath, pluginFolderName ), pluginPath )
-               else:
-                       settings.ToolDialog().addPluginToMenu( menu, pluginPath )
-
-def addToMenu( master, menu, repository, window ):
-       "Add a tool plugin menu."
-       CraftMenuSaveListener( menu, window )
-
-def getNewRepository():
-       'Get new repository.'
-       return skeinforge_craft.CraftRepository()
-
-def writeOutput(fileName):
-       "Craft a gcode file."
-       return skeinforge_craft.writeOutput(fileName)
-
-
-class CraftMenuSaveListener(object):
-       "A class to update a craft menu."
-       def __init__( self, menu, window ):
-               "Set the menu."
-               self.menu = menu
-               addToCraftMenu( menu )
-               euclidean.addElementToListDictionaryIfNotThere( self, window, settings.globalProfileSaveListenerListTable )
-
-       def save(self):
-               "Profile has been saved and profile menu should be updated."
-               settings.deleteMenuItems( self.menu )
-               addToCraftMenu( self.menu )
-
-
-class CraftRadioButtonsSaveListener(object):
-       "A class to update the craft radio buttons."
-       def addToDialog( self, gridPosition ):
-               "Add this to the dialog."
-               euclidean.addElementToListDictionaryIfNotThere( self, self.repository.repositoryDialog, settings.globalProfileSaveListenerListTable )
-               self.gridPosition = gridPosition.getCopy()
-               self.gridPosition.increment()
-               self.gridPosition.row = gridPosition.rowStart
-               self.setRadioButtons()
-
-       def getFromRadioPlugins( self, radioPlugins, repository ):
-               "Initialize."
-               self.name = 'CraftRadioButtonsSaveListener'
-               self.radioPlugins = radioPlugins
-               self.repository = repository
-               repository.displayEntities.append(self)
-               return self
-
-       def save(self):
-               "Profile has been saved and craft radio plugins should be updated."
-               self.setRadioButtons()
-
-       def setRadioButtons(self):
-               "Profile has been saved and craft radio plugins should be updated."
-               craftSequence = skeinforge_profile.getCraftTypePluginModule().getCraftSequence()
-               gridPosition = self.gridPosition.getCopy()
-               maximumValue = False
-               activeRadioPlugins = []
-               for radioPlugin in self.radioPlugins:
-                       if radioPlugin.name in craftSequence:
-                               activeRadioPlugins.append( radioPlugin )
-                               radioPlugin.incrementGridPosition(gridPosition)
-                               maximumValue = max( radioPlugin.value, maximumValue )
-                       else:
-                               radioPlugin.radiobutton.grid_remove()
-               if not maximumValue:
-                       selectedRadioPlugin = settings.getSelectedRadioPlugin( self.repository.importantFileNames + [ activeRadioPlugins[0].name ], activeRadioPlugins ).setSelect()
-               self.repository.pluginFrame.update()
-
-
-def main():
-       "Display the craft dialog."
-       if len(sys.argv) > 1:
-               settings.startMainLoopFromWindow(writeOutput(' '.join(sys.argv[1 :])))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/__init__.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/alteration.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/alteration.py
deleted file mode 100644 (file)
index cf3d2f9..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-#! /usr/bin/env python
-"""
-This page is in the table of contents.
-The alteration plugin adds the start and end files to the gcode.
-
-This plugin also removes the alteration prefix tokens from the alteration lines.  Alteration lines have a prefix token so they can go through the craft plugins without being modified.  However, the tokens are not recognized by the firmware so they have to be removed before export. The alteration token is:
-(<alterationDeleteThisPrefix/>)
-
-The alteration manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Alteration
-
-==Operation==
-The default 'Activate Alteration' checkbox is on.  When it is on, the functions described below will work, when it is off, nothing will be done.
-
-==Settings==
-Alteration looks for alteration files in the alterations folder in the .skeinforge folder in the home directory.  Alteration does not care if the text file names are capitalized, but some file systems do not handle file name cases properly, so to be on the safe side you should give them lower case names.  If it doesn't find the file it then looks in the alterations folder in the skeinforge_plugins folder.
-
-===Name of End File===
-Default is 'end.gcode'.
-
-If there is a file with the name of the "Name of End File" setting, it will be added to the very end of the gcode.
-
-===Name of Start File===
-Default is 'start.gcode'.
-
-If there is a file with the name of the "Name of Start File" setting, it will be added to the very beginning of the gcode.
-
-===Remove Redundant Mcode===
-Default: True
-
-If 'Remove Redundant Mcode' is selected then M104 and M108 lines which are followed by a different value before there is a movement will be removed.  For example, if there is something like:
-M113 S1.0
-M104 S60.0
-(<layer> 0.72 )
-M104 S200.0
-(<skirt>)
-
-with Remove Redundant Mcode selected, that snippet would become:
-M113 S1.0
-M104 S200.0
-(<layer> 0.72 )
-(<skirt>)
-
-This is a relatively safe procedure, the only reason it is optional is because someone might make an alteration file which, for some unknown reason, requires the redundant mcode.
-
-===Replace Variable with Setting===
-Default: True
-
-If 'Replace Variable with Setting' is selected and there is an alteration line with a setting token, the token will be replaced by the value.
-
-For example, if there is an alteration line like:
-
-M140 S<setting.chamber.BedTemperature>
-
-the token would be replaced with the value and assuming the bed chamber was 60.0, the output would be:
-
-M140 S60.0
-
-==Examples==
-The following examples add the alteration information to the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and alteration.py.
-
-> python alteration.py
-This brings up the alteration dialog.
-
-> python alteration.py Screw Holder Bottom.stl
-The alteration tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The alteration tool has created the file:
-.. Screw Holder Bottom_alteration.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import cStringIO
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText(fileName, text='', repository=None):
-       'Alteration a gcode linear move text.'
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository, fileName)
-
-def getCraftedTextFromText(gcodeText, repository=None, fileName=''):
-       'Alteration a gcode linear move text.'
-       if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'alteration'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository(AlterationRepository())
-       if not repository.activateAlteration.value:
-               return gcodeText
-       return AlterationSkein().getCraftedGcode(gcodeText, repository, fileName)
-
-def getGcodeTextWithoutRedundantMcode(gcodeText):
-       'Get gcode text without redundant M104 and M108.'
-       lines = archive.getTextLines(gcodeText)
-       lines = getLinesWithoutRedundancy('M104', lines)
-       lines = getLinesWithoutRedundancy('M108', lines)
-       output = cStringIO.StringIO()
-       gcodec.addLinesToCString(output, lines)
-       return output.getvalue()
-
-def getLinesWithoutRedundancy(duplicateWord, lines):
-       'Get gcode lines without redundant first words.'
-       oldDuplicationIndex = None
-       for lineIndex, line in enumerate(lines):
-               firstWord = gcodec.getFirstWordFromLine(line)
-               if firstWord == duplicateWord:
-                       if oldDuplicationIndex == None:
-                               oldDuplicationIndex = lineIndex
-                       else:
-                               lines[oldDuplicationIndex] = line
-                               lines[lineIndex] = ''
-               elif firstWord.startswith('G') or firstWord == 'M101' or firstWord == 'M103':
-                       oldDuplicationIndex = None
-       return lines
-
-def getNewRepository():
-       'Get new repository.'
-       return AlterationRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       'Alteration a gcode linear move file.  Chain alteration the gcode if the alteration procedure has not been done.'
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'alteration', shouldAnalyze)
-
-
-class AlterationRepository(object):
-       "A class to handle the alteration settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.alteration.html', self )
-               self.baseNameSynonym = 'bookend.csv'
-               self.fileNameInput = settings.FileNameInput().getFromFileName(fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Alteration', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Alteration')
-               self.activateAlteration = settings.BooleanSetting().getFromValue('Activate Alteration', self, True)
-               self.nameOfEndFile = settings.StringSetting().getFromValue('Name of End File:', self, 'end.gcode')
-               self.nameOfStartFile = settings.StringSetting().getFromValue('Name of Start File:', self, 'start.gcode')
-               self.removeRedundantMcode = settings.BooleanSetting().getFromValue('Remove Redundant Mcode', self, True)
-               self.replaceVariableWithSetting = settings.BooleanSetting().getFromValue('Replace Variable with Setting', self, True)
-               self.executeTitle = 'Alteration'
-
-       def execute(self):
-               'Alteration button has been clicked.'
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class AlterationSkein(object):
-       "A class to alteration a skein of extrusions."
-       def __init__(self):
-               'Initialize.'
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.lineIndex = 0
-               self.settingDictionary = None
-
-       def addFromUpperLowerFile(self, fileName):
-               "Add lines of text from the fileName or the lowercase fileName, if there is no file by the original fileName in the directory."
-               alterationFileLines = map(lambda l: l.replace('?filename?', self.fileName.encode('ascii', 'replace')), settings.getAlterationFileLines(fileName))
-               self.distanceFeedRate.addLinesSetAbsoluteDistanceMode(alterationFileLines)
-
-       def getCraftedGcode(self, gcodeText, repository, fileName):
-               "Parse gcode text and store the bevel gcode."
-               self.fileName = fileName
-               self.lines = archive.getTextLines(gcodeText)
-               if repository.replaceVariableWithSetting.value:
-                       self.setSettingDictionary()
-               self.addFromUpperLowerFile(repository.nameOfStartFile.value) # Add a start file if it exists.
-               self.parseInitialization()
-               for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       self.distanceFeedRate.addLine(line)
-               self.addFromUpperLowerFile(repository.nameOfEndFile.value) # Add an end file if it exists.
-               gcodeText = self.getReplacedAlterationText()
-               if repository.removeRedundantMcode.value:
-                       gcodeText = getGcodeTextWithoutRedundantMcode(gcodeText)
-               return gcodeText
-
-       def getReplacedAlterationLine(self, alterationFileLine, searchIndex=0):
-               'Get the alteration file line with variables replaced with the settings.'
-               settingIndex = alterationFileLine.find('setting.', searchIndex)
-               beginIndex = settingIndex - 1
-               if beginIndex < 0:
-                       return alterationFileLine
-               endBracketIndex = alterationFileLine.find('>', settingIndex)
-               if alterationFileLine[beginIndex] != '<' or endBracketIndex == -1:
-                       return alterationFileLine
-               endIndex = endBracketIndex + 1
-               innerToken = alterationFileLine[settingIndex + len('setting.'): endIndex].replace('>', '').replace(' ', '').replace('_', '').lower()
-               if innerToken in self.settingDictionary:
-                       replacedSetting = self.settingDictionary[innerToken]
-                       replacedAlterationLine = alterationFileLine[: beginIndex] + replacedSetting + alterationFileLine[endIndex :]
-                       return self.getReplacedAlterationLine(replacedAlterationLine, beginIndex + len(replacedSetting))
-               return alterationFileLine
-
-       def getReplacedAlterationText(self):
-               'Replace the alteration lines if there are settings.'
-               if self.settingDictionary == None:
-                       return self.distanceFeedRate.output.getvalue().replace('(<alterationDeleteThisPrefix/>)', '')
-               lines = archive.getTextLines(self.distanceFeedRate.output.getvalue())
-               distanceFeedRate = gcodec.DistanceFeedRate()
-               for line in lines:
-                       if line.startswith('(<alterationDeleteThisPrefix/>)'):
-                               line = self.getReplacedAlterationLine(line[len('(<alterationDeleteThisPrefix/>)') :])
-                       distanceFeedRate.addLine(line)
-               return distanceFeedRate.output.getvalue()
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('alteration')
-                               return
-                       self.distanceFeedRate.addLine(line)
-
-       def setSettingDictionary(self):
-               'Set the setting dictionary from the gcode text.'
-               for line in self.lines:
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == '(<setting>' and self.settingDictionary != None:
-                               if len(splitLine) > 4:
-                                       procedure = splitLine[1]
-                                       name = splitLine[2].replace('_', ' ').replace(' ', '')
-                                       if '(' in name:
-                                               name = name[: name.find('(')]
-                                       value = ' '.join(splitLine[3 : -1])
-                                       self.settingDictionary[(procedure + '.' + name).lower()] = value
-                       elif firstWord == '(<settings>)':
-                               self.settingDictionary = {}
-                       elif firstWord == '(</settings>)':
-                               return
-
-
-def main():
-       "Display the alteration dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/bottom.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/bottom.py
deleted file mode 100644 (file)
index acd32c7..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-#! /usr/bin/env python
-"""
-This page is in the table of contents.
-Bottom sets the bottom of the carving to the defined altitude.
-
-The bottom manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Bottom
-
-==Operation==
-The default 'Activate Bottom' checkbox is on.  When it is on, the functions described below will work, when it is off, the functions will not be called.
-
-==Settings==
-===Additional Height over Layer Thickness===
-Default is half.
-
-The layers will start at the altitude plus the 'Additional Height over Layer Thickness' times the layer height.  The default value of half means that the bottom layer is at the height of the bottom slice, because each slice is made through the middle of each layer.  Raft expects the layers to start at an additional half layer height.  You should only change 'Additional Height over Layer Thickness' if you are manipulating the skeinforge output with your own program which does not use the raft tool.
-
-===Altitude===
-Default is zero.
-
-Defines the altitude of the bottom of the model.  The bottom slice has a z of the altitude plus the 'Additional Height over Layer Thickness' times the layer height.
-
-===SVG Viewer===
-Default is webbrowser.
-
-If the 'SVG Viewer' is set to the default 'webbrowser', the scalable vector graphics file will be sent to the default browser to be opened.  If the 'SVG Viewer' is set to a program name, the scalable vector graphics file will be sent to that program to be opened.
-
-==Examples==
-The following examples bottom the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and bottom.py.
-
-> python bottom.py
-This brings up the bottom dialog.
-
-> python bottom.py Screw Holder Bottom.stl
-The bottom tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The bottom tool has created the file:
-.. Screw Holder Bottom_bottom.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.svg_reader import SVGReader
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from fabmetheus_utilities import svg_writer
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText(fileName, svgText='', repository=None):
-       "Bottom and convert an svg file or svgText."
-       return getCraftedTextFromText(fileName, archive.getTextIfEmpty(fileName, svgText), repository)
-
-def getCraftedTextFromText(fileName, svgText, repository=None):
-       "Bottom and convert an svgText."
-       if gcodec.isProcedureDoneOrFileIsEmpty(svgText, 'bottom'):
-               return svgText
-       if repository == None:
-               repository = settings.getReadRepository(BottomRepository())
-       if not repository.activateBottom.value:
-               return svgText
-       return BottomSkein().getCraftedGcode(fileName, repository, svgText)
-
-def getNewRepository():
-       'Get new repository.'
-       return BottomRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       'Bottom the carving.'
-       skeinforge_craft.writeSVGTextWithNounMessage(fileName, BottomRepository(), shouldAnalyze)
-
-
-class BottomRepository(object):
-       "A class to handle the bottom settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository(
-                       'skeinforge_application.skeinforge_plugins.craft_plugins.bottom.html', self)
-               self.fileNameInput = settings.FileNameInput().getFromFileName(
-                       fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Bottom', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Bottom')
-               self.activateBottom = settings.BooleanSetting().getFromValue('Activate Bottom', self, True)
-               self.additionalHeightOverLayerThickness = settings.FloatSpin().getFromValue(
-                       0.0, 'Additional Height over Layer Thickness (ratio):', self, 1.0, 0.5)
-               self.altitude = settings.FloatSpin().getFromValue(-1.0, 'Altitude (mm):', self, 1.0, 0.0)
-               self.svgViewer = settings.StringSetting().getFromValue('SVG Viewer:', self, 'webbrowser')
-               self.executeTitle = 'Bottom'
-
-       def execute(self):
-               "Bottom button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class BottomSkein(object):
-       "A class to bottom a skein of extrusions."
-       def getCraftedGcode(self, fileName, repository, svgText):
-               "Parse svgText and store the bottom svgText."
-               svgReader = SVGReader()
-               svgReader.parseSVG('', svgText)
-               if svgReader.sliceDictionary == None:
-                       print('Warning, nothing will be done because the sliceDictionary could not be found getCraftedGcode in preface.')
-                       return ''
-               decimalPlacesCarried = int(svgReader.sliceDictionary['decimalPlacesCarried'])
-               edgeWidth = float(svgReader.sliceDictionary['edgeWidth'])
-               layerHeight = float(svgReader.sliceDictionary['layerHeight'])
-               loopLayers = svgReader.loopLayers
-               zMinimum = 987654321.0
-               for loopLayer in loopLayers:
-                       zMinimum = min(loopLayer.z, zMinimum)
-               deltaZ = repository.altitude.value + repository.additionalHeightOverLayerThickness.value * layerHeight - zMinimum
-               for loopLayer in loopLayers:
-                       loopLayer.z += deltaZ
-               cornerMaximum = Vector3(-912345678.0, -912345678.0, -912345678.0)
-               cornerMinimum = Vector3(912345678.0, 912345678.0, 912345678.0)
-               svg_writer.setSVGCarvingCorners(cornerMaximum, cornerMinimum, layerHeight, loopLayers)
-               svgWriter = svg_writer.SVGWriter(
-                       True,
-                       cornerMaximum,
-                       cornerMinimum,
-                       decimalPlacesCarried,
-                       layerHeight,
-                       edgeWidth)
-               commentElement = svg_writer.getCommentElement(svgReader.documentElement)
-               procedureNameString = svgReader.sliceDictionary['procedureName'] + ',bottom'
-               return svgWriter.getReplacedSVGTemplate(fileName, loopLayers, procedureNameString, commentElement)
-
-
-def main():
-       "Display the bottom dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/carve.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/carve.py
deleted file mode 100644 (file)
index feeaee4..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-"""
-This page is in the table of contents.
-Carve is the most important plugin to define for your printer.
-
-It carves a shape into svg slice layers.  It also sets the layer height and edge width for the rest of the tool chain.
-
-The carve manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Carve
-
-On the Arcol Blog a method of deriving the layer height is posted.  That article "Machine Calibrating" is at:
-http://blog.arcol.hu/?p=157
-
-==Settings==
-===Add Layer Template to SVG===
-Default is on.
-
-When selected, the layer template will be added to the svg output, which adds javascript control boxes.  So 'Add Layer Template to SVG' should be selected when the svg will be viewed in a browser.
-
-When off, no controls will be added, the svg output will only include the fabrication paths.  So 'Add Layer Template to SVG' should be deselected when the svg will be used by other software, like Inkscape.
-
-===Edge Width over Height===
-Default is 1.8.
-
-Defines the ratio of the extrusion edge width to the layer height.  This parameter tells skeinforge how wide the edge wall is expected to be in relation to the layer height.  Default value of 1.8 for the default layer height of 0.4 states that a single filament edge wall should be 0.4 mm * 1.8 = 0.72 mm wide.  The higher the value the more the edge will be inset.  A ratio of one means the extrusion is a circle, the default ratio of 1.8 means the extrusion is a wide oval.
-
-This is an important value because if you are calibrating your machine you need to ensure that the speed of the head and the extrusion rate in combination produce a wall that is 'Layer Height' * 'Edge Width over Height' wide. To start with 'Edge Width over Height' is probably best left at the default of 1.8 and the extrusion rate adjusted to give the correct calculated wall thickness.
-
-Adjustment is in the 'Speed' section with 'Feed Rate' controlling speed of the head in X & Y and 'Flow Rate' controlling the extrusion rate.  Initially it is probably easier to start adjusting the flow rate only a little at a time until you get a single filament of the correct width. If you change too many parameters at once you can get in a right mess.
-
-===Extra Decimal Places===
-Default is two.
-
-Defines the number of extra decimal places export will output compared to the number of decimal places in the layer height.  The higher the 'Extra Decimal Places', the more significant figures the output numbers will have.
-
-===Import Coarseness===
-Default is one.
-
-When a triangle mesh has holes in it, the triangle mesh slicer switches over to a slow algorithm that spans gaps in the mesh.  The higher the 'Import Coarseness' setting, the wider the gaps in the mesh it will span.  An import coarseness of one means it will span gaps of the edge width.
-
-===Layer Height===
-Default is 0.4 mm.
-
-Defines the the height of the layers skeinforge will cut your object into, in the z direction.  This is the most important carve setting, many values in the toolchain are derived from the layer height.
-
-For a 0.5 mm nozzle usable values are 0.3 mm to 0.5 mm.  Note; if you are using thinner layers make sure to adjust the extrusion speed as well.
-
-===Layers===
-Carve slices from bottom to top.  To get a single layer, set the "Layers From" to zero and the "Layers To" to one.  The 'Layers From' until 'Layers To' range is a python slice.
-
-====Layers From====
-Default is zero.
-
-Defines the index of the bottom layer that will be carved.  If the 'Layers From' is the default zero, the carving will start from the lowest layer.  If the 'Layers From' index is negative, then the carving will start from the 'Layers From' index below the top layer.
-
-For example if your object is 5 mm tall and your layer thicknes is 1 mm if you set layers from to 3 you will ignore the first 3 mm and start from 3 mm.
-
-====Layers To====
-Default is a huge number, which will be limited to the highest index layer.
-
-Defines the index of the top layer that will be carved.  If the 'Layers To' index is a huge number like the default, the carving will go to the top of the model.  If the 'Layers To' index is negative, then the carving will go to the 'Layers To' index below the top layer.
-
-This is the same as layers from, only it defines when to end the generation of gcode.
-
-===Mesh Type===
-Default is 'Correct Mesh'.
-
-====Correct Mesh====
-When selected, the mesh will be accurately carved, and if a hole is found, carve will switch over to the algorithm that spans gaps.
-
-====Unproven Mesh====
-When selected, carve will use the gap spanning algorithm from the start.  The problem with the gap spanning algothm is that it will span gaps, even if there is not actually a gap in the model.
-
-===SVG Viewer===
-Default is webbrowser.
-
-If the 'SVG Viewer' is set to the default 'webbrowser', the scalable vector graphics file will be sent to the default browser to be opened.  If the 'SVG Viewer' is set to a program name, the scalable vector graphics file will be sent to that program to be opened.
-
-==Examples==
-The following examples carve the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and carve.py.
-
-> python carve.py
-This brings up the carve dialog.
-
-> python carve.py Screw Holder Bottom.stl
-The carve tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The carve tool has created the file:
-.. Screw Holder Bottom_carve.svg
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from fabmetheus_utilities import svg_writer
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-from fabmetheus_utilities.vector3 import Vector3
-import math
-import sys
-import time
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, gcodeText = '', repository=None):
-       "Get carved text."
-       if fileName.endswith('.svg'):
-               gcodeText = archive.getTextIfEmpty(fileName, gcodeText)
-               if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'carve'):
-                       return gcodeText
-       carving = svg_writer.getCarving(fileName)
-       if carving == None:
-               return ''
-       if repository == None:
-               repository = CarveRepository()
-               settings.getReadRepository(repository)
-       return CarveSkein().getCarvedSVG( carving, fileName, repository )
-
-def getNewRepository():
-       'Get new repository.'
-       return CarveRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Carve a GNU Triangulated Surface file."
-       startTime = time.time()
-       print('File ' + archive.getSummarizedFileName(fileName) + ' is being carved.')
-       repository = CarveRepository()
-       settings.getReadRepository(repository)
-       carveGcode = getCraftedText(fileName, '', repository)
-       if carveGcode == '':
-               return
-       suffixFileName = archive.getFilePathWithUnderscoredBasename(fileName, '_carve.svg')
-       archive.writeFileText(suffixFileName, carveGcode)
-       print('The carved file is saved as ' + archive.getSummarizedFileName(suffixFileName))
-       print('It took %s to carve the file.' % euclidean.getDurationString(time.time() - startTime))
-       if shouldAnalyze:
-               settings.openSVGPage(suffixFileName, repository.svgViewer.value)
-
-
-class CarveRepository(object):
-       "A class to handle the carve settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.carve.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getTranslatorFileTypeTuples(), 'Open File for Carve', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Carve')
-               self.addLayerTemplateToSVG = settings.BooleanSetting().getFromValue('Add Layer Template to SVG', self, True)
-               self.edgeWidth = settings.FloatSpin().getFromValue( 0.1, 'Edge Width (mm):', self, 2.2, 0.4 )
-               self.extraDecimalPlaces = settings.FloatSpin().getFromValue(0.0, 'Extra Decimal Places (float):', self, 3.0, 2.0)
-               self.importCoarseness = settings.FloatSpin().getFromValue( 0.5, 'Import Coarseness (ratio):', self, 2.0, 1.0 )
-               self.layerHeight = settings.FloatSpin().getFromValue( 0.1, 'Layer Height (mm):', self, 1.0, 0.2 )
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Layers -', self )
-               self.layersFrom = settings.IntSpin().getFromValue( 0, 'Layers From (index):', self, 20, 0 )
-               self.layersTo = settings.IntSpin().getSingleIncrementFromValue( 0, 'Layers To (index):', self, 912345678, 912345678 )
-               settings.LabelSeparator().getFromRepository(self)
-               self.meshTypeLabel = settings.LabelDisplay().getFromName('Mesh Type: ', self )
-               importLatentStringVar = settings.LatentStringVar()
-               self.correctMesh = settings.Radio().getFromRadio( importLatentStringVar, 'Correct Mesh', self, True )
-               self.unprovenMesh = settings.Radio().getFromRadio( importLatentStringVar, 'Unproven Mesh', self, False )
-               self.svgViewer = settings.StringSetting().getFromValue('SVG Viewer:', self, 'webbrowser')
-               settings.LabelSeparator().getFromRepository(self)
-               self.executeTitle = 'Carve'
-
-               self.centerX = settings.FloatSpin().getFromValue(0.0, 'CenterX', self, 1000.0, 0.0);
-               self.centerY = settings.FloatSpin().getFromValue(0.0, 'CenterY', self, 1000.0, 0.0);
-               self.objectSink = settings.FloatSpin().getFromValue(0.0, 'ObjectSink', self, 1000.0, 0.0)
-               self.matrix = settings.StringSetting().getFromValue('ObjectMatrix', self, '1,0,0,0,1,0,0,0,1')
-               self.alternativeCenter = settings.StringSetting().getFromValue('AlternativeCenterFile', self, '')
-
-
-       def execute(self):
-               "Carve button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypes(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class CarveSkein(object):
-       "A class to carve a carving."
-       def getCarvedSVG(self, carving, fileName, repository):
-               "Parse gnu triangulated surface text and store the carved gcode."
-
-               matrix = map(float, repository.matrix.value.split(','))
-
-               for i in xrange(0, len(carving.vertexes)):
-                       x = carving.vertexes[i].x
-                       y = carving.vertexes[i].y
-                       z = carving.vertexes[i].z
-                       carving.vertexes[i] = Vector3(
-                               x * matrix[0] + y * matrix[3] + z * matrix[6],
-                               x * matrix[1] + y * matrix[4] + z * matrix[7],
-                               x * matrix[2] + y * matrix[5] + z * matrix[8])
-
-               if repository.alternativeCenter.value != '':
-                       carving2 = svg_writer.getCarving(repository.alternativeCenter.value)
-                       for i in xrange(0, len(carving2.vertexes)):
-                               x = carving2.vertexes[i].x
-                               y = carving2.vertexes[i].y
-                               z = carving2.vertexes[i].z
-                               carving2.vertexes[i] = Vector3(
-                                       x * matrix[0] + y * matrix[3] + z * matrix[6],
-                                       x * matrix[1] + y * matrix[4] + z * matrix[7],
-                                       x * matrix[2] + y * matrix[5] + z * matrix[8])
-                       minZ = carving2.getMinimumZ()
-                       minSize = carving2.getCarveCornerMinimum()
-                       maxSize = carving2.getCarveCornerMaximum()
-               else:
-                       minZ = carving.getMinimumZ()
-                       minSize = carving.getCarveCornerMinimum()
-                       maxSize = carving.getCarveCornerMaximum()
-               for v in carving.vertexes:
-                       v.z -= minZ + repository.objectSink.value
-                       v.x -= minSize.x + (maxSize.x - minSize.x) / 2
-                       v.y -= minSize.y + (maxSize.y - minSize.y) / 2
-                       v.x += repository.centerX.value
-                       v.y += repository.centerY.value
-
-               layerHeight = repository.layerHeight.value
-               edgeWidth = repository.edgeWidth.value
-               carving.setCarveLayerHeight(layerHeight)
-               importRadius = 0.5 * repository.importCoarseness.value * abs(edgeWidth)
-               carving.setCarveImportRadius(max(importRadius, 0.001 * layerHeight))
-               carving.setCarveIsCorrectMesh(repository.correctMesh.value)
-               loopLayers = carving.getCarveBoundaryLayers()
-               if len(loopLayers) < 1:
-                       print('Warning, there are no slices for the model, this could be because the model is too small for the Layer Height.')
-                       return ''
-               layerHeight = carving.getCarveLayerHeight()
-               decimalPlacesCarried = euclidean.getDecimalPlacesCarried(repository.extraDecimalPlaces.value, layerHeight)
-               edgeWidth = repository.edgeWidth.value
-               svgWriter = svg_writer.SVGWriter(
-                       repository.addLayerTemplateToSVG.value,
-                       carving.getCarveCornerMaximum(),
-                       carving.getCarveCornerMinimum(),
-                       decimalPlacesCarried,
-                       carving.getCarveLayerHeight(),
-                       edgeWidth)
-               truncatedRotatedBoundaryLayers = svg_writer.getTruncatedRotatedBoundaryLayers(loopLayers, repository)
-               return svgWriter.getReplacedSVGTemplate(fileName, truncatedRotatedBoundaryLayers, 'carve', carving.getFabmetheusXML())
-
-
-def main():
-       "Display the carve dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/chamber.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/chamber.py
deleted file mode 100644 (file)
index 62d328d..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-"""
-This page is in the table of contents.
-Some filaments contract too much and warp the extruded object.  To prevent this you have to print the object in a temperature regulated chamber and/or on a temperature regulated bed. The chamber tool allows you to control the bed and chamber temperature and the holding pressure.
-
-The chamber gcodes are also described at:
-
-http://reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes
-
-The chamber manual page is at:
-
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Chamber
-
-==Operation==
-The default 'Activate Chamber' checkbox is on.  When it is on, the functions described below will work, when it is off, nothing will be done.
-
-==Settings==
-===Bed===
-The initial bed temperature is defined by 'Bed Temperature'.  If the 'Bed Temperature End Change Height' is greater or equal to the 'Bed Temperature Begin Change Height' and the 'Bed Temperature Begin Change Height' is greater or equal to zero, then the temperature will be ramped toward the 'Bed Temperature End'.  The ramp will start once the extruder reaches the 'Bed Temperature Begin Change Height', then the bed temperature will approach the 'Bed Temperature End' as the extruder reaches the 'Bed Temperature End Change Height', finally the bed temperature will stay at the 'Bed Temperature End' for the remainder of the build.
-
-The idea is described at:
-http://www.makerbot.com/blog/2011/03/17/if-you-cant-stand-the-heat/
-
-====Bed Temperature====
-Default: 60C
-
-Defines the initial print bed temperature in Celcius by adding an M140 command.
-
-====Bed Temperature Begin Change Height====
-Default: -1 mm
-
-Defines the height of the beginning of the temperature ramp.  If the 'Bed Temperature End Change Height' is less than zero, the bed temperature will remain at the initial 'Bed Temperature'.
-
-====Bed Temperature End Change Height====
-Default: -1 mm
-
-Defines the height of the end of the temperature ramp.  If the 'Bed Temperature End Change Height' is less than zero or less than the 'Bed Temperature Begin Change Height', the bed temperature will remain at the initial 'Bed Temperature'.
-
-====Bed Temperature End====
-Default: 20C
-
-Defines the end bed temperature if there is a temperature ramp.
-
-===Chamber Temperature===
-Default: 30C
-
-Defines the chamber temperature in Celcius by adding an M141 command.
-
-===Holding Force===
-Default: 0
-
-Defines the holding pressure of a mechanism, like a vacuum table or electromagnet, to hold the bed surface or object, by adding an M142 command.  The holding pressure is in bars. For hardware which only has on/off holding, when the holding pressure is zero, turn off holding, when the holding pressure is greater than zero, turn on holding. 
-
-==Heated Beds==
-===Bothacker===
-A resistor heated aluminum plate by Bothacker:
-
-http://bothacker.com
-
-with an article at:
-
-http://bothacker.com/2009/12/18/heated-build-platform/
-
-===Domingo===
-A heated copper build plate by Domingo:
-
-http://casainho-emcrepstrap.blogspot.com/
-
-with articles at:
-
-http://casainho-emcrepstrap.blogspot.com/2010/01/first-time-with-pla-testing-it-also-on.html
-
-http://casainho-emcrepstrap.blogspot.com/2010/01/call-for-helpideas-to-develop-heated.html
-
-http://casainho-emcrepstrap.blogspot.com/2010/01/new-heated-build-platform.html
-
-http://casainho-emcrepstrap.blogspot.com/2010/01/no-acrylic-and-instead-kapton-tape-on.html
-
-http://casainho-emcrepstrap.blogspot.com/2010/01/problems-with-heated-build-platform-and.html
-
-http://casainho-emcrepstrap.blogspot.com/2010/01/perfect-build-platform.html
-
-http://casainho-emcrepstrap.blogspot.com/2009/12/almost-no-warp.html
-
-http://casainho-emcrepstrap.blogspot.com/2009/12/heated-base-plate.html
-
-===Jmil===
-A heated build stage by jmil, over at:
-
-http://www.hive76.org
-
-with articles at:
-
-http://www.hive76.org/handling-hot-build-surfaces
-
-http://www.hive76.org/heated-build-stage-success
-
-===Metalab===
-A heated base by the Metalab folks:
-
-http://reprap.soup.io
-
-with information at:
-
-http://reprap.soup.io/?search=heated%20base
-
-===Nophead===
-A resistor heated aluminum bed by Nophead:
-
-http://hydraraptor.blogspot.com
-
-with articles at:
-
-http://hydraraptor.blogspot.com/2010/01/will-it-stick.html
-
-http://hydraraptor.blogspot.com/2010/01/hot-metal-and-serendipity.html
-
-http://hydraraptor.blogspot.com/2010/01/new-year-new-plastic.html
-
-http://hydraraptor.blogspot.com/2010/01/hot-bed.html
-
-===Prusajr===
-A resistive wire heated plexiglass plate by prusajr:
-
-http://prusadjs.cz/
-
-with articles at:
-
-http://prusadjs.cz/2010/01/heated-reprap-print-bed-mk2/
-
-http://prusadjs.cz/2009/11/look-ma-no-warping-heated-reprap-print-bed/
-
-===Zaggo===
-A resistor heated aluminum plate by Zaggo at Pleasant Software:
-
-http://pleasantsoftware.com/developer/3d/
-
-with articles at:
-
-http://pleasantsoftware.com/developer/3d/2009/12/05/raftless/
-
-http://pleasantsoftware.com/developer/3d/2009/11/15/living-in-times-of-warp-free-printing/
-
-http://pleasantsoftware.com/developer/3d/2009/11/12/canned-heat/
-
-==Examples==
-The following examples chamber the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and chamber.py.
-
-> python chamber.py
-This brings up the chamber dialog.
-
-> python chamber.py Screw Holder Bottom.stl
-The chamber tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The chamber tool has created the file:
-Screw Holder Bottom_chamber.gcode
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText(fileName, text='', repository=None):
-       "Chamber the file or text."
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository)
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       "Chamber a gcode linear move text."
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'chamber'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository(ChamberRepository())
-       if not repository.activateChamber.value:
-               return gcodeText
-       return ChamberSkein().getCraftedGcode(gcodeText, repository)
-
-def getNewRepository():
-       'Get new repository.'
-       return ChamberRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Chamber a gcode linear move file."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'chamber', shouldAnalyze)
-
-
-class ChamberRepository(object):
-       "A class to handle the chamber settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.chamber.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Chamber', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Chamber')
-               self.activateChamber = settings.BooleanSetting().getFromValue('Activate Chamber', self, False )
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Bed -', self )
-               self.bedTemperature = settings.FloatSpin().getFromValue(20.0, 'Bed Temperature (Celcius):', self, 90.0, 60.0)
-               self.bedTemperatureBeginChangeHeight = settings.FloatSpin().getFromValue(-1.0, 'Bed Temperature Begin Change Height (mm):', self, 20.0, -1.0)
-               self.bedTemperatureEndChangeHeight = settings.FloatSpin().getFromValue(-1.0, 'Bed Temperature End Change Height (mm):', self, 40.0, -1.0)
-               self.bedTemperatureEnd = settings.FloatSpin().getFromValue(20.0, 'Bed Temperature End (Celcius):', self, 90.0, 20.0)
-               settings.LabelSeparator().getFromRepository(self)
-               self.chamberTemperature = settings.FloatSpin().getFromValue( 20.0, 'Chamber Temperature (Celcius):', self, 90.0, 30.0 )
-               self.holdingForce = settings.FloatSpin().getFromValue( 0.0, 'Holding Force (bar):', self, 100.0, 0.0 )
-               self.executeTitle = 'Chamber'
-
-       def execute(self):
-               "Chamber button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-
-class ChamberSkein(object):
-       "A class to chamber a skein of extrusions."
-       def __init__(self):
-               'Initialize.'
-               self.changeWidth = None
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.lineIndex = 0
-               self.lines = None
-               self.oldBedTemperature = None
-
-       def addBedTemperature(self, bedTemperature):
-               'Add bed temperature if it is different from the old.'
-               if bedTemperature != self.oldBedTemperature:
-                       self.distanceFeedRate.addParameter('M140', bedTemperature)
-                       self.oldBedTemperature = bedTemperature
-
-       def getCraftedGcode(self, gcodeText, repository):
-               "Parse gcode text and store the chamber gcode."
-               endAtLeastBegin = repository.bedTemperatureEndChangeHeight.value >= repository.bedTemperatureBeginChangeHeight.value
-               if endAtLeastBegin and repository.bedTemperatureBeginChangeHeight.value >= 0.0:
-                       self.changeWidth = repository.bedTemperatureEndChangeHeight.value - repository.bedTemperatureBeginChangeHeight.value
-               self.repository = repository
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization()
-               for line in self.lines[self.lineIndex :]:
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('chamber')
-                               return
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               "Parse a gcode line and add it to the chamber skein."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == '(<crafting>)':
-                       self.distanceFeedRate.addLine(line)
-                       self.addBedTemperature(self.repository.bedTemperature.value)
-                       self.distanceFeedRate.addParameter('M141', self.repository.chamberTemperature.value) # Set chamber temperature.
-                       self.distanceFeedRate.addParameter('M142', self.repository.holdingForce.value) # Set holding pressure.
-                       return
-               self.distanceFeedRate.addLine(line)
-               if firstWord == '(<layer>' and self.changeWidth != None:
-                       z = float(splitLine[1])
-                       if z >= self.repository.bedTemperatureEndChangeHeight.value:
-                               self.addBedTemperature(self.repository.bedTemperatureEnd.value)
-                               return
-                       if z <= self.repository.bedTemperatureBeginChangeHeight.value:
-                               return
-                       along = (z - self.repository.bedTemperatureBeginChangeHeight.value) / self.changeWidth
-                       self.addBedTemperature(self.repository.bedTemperature.value * (1 - along) + self.repository.bedTemperatureEnd.value * along)
-
-
-def main():
-       "Display the chamber dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/chop.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/chop.py
deleted file mode 100644 (file)
index 1bbf941..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-"""
-This page is in the table of contents.
-Chop is a script to chop a shape into svg slice layers.
-
-==Settings==
-===Add Layer Template to SVG===
-Default is on.
-
-When selected, the layer template will be added to the svg output, which adds javascript control boxes.  So 'Add Layer Template to SVG' should be selected when the svg will be viewed in a browser.
-
-When off, no controls will be added, the svg output will only include the fabrication paths.  So 'Add Layer Template to SVG' should be deselected when the svg will be used by other software, like Inkscape.
-
-===Add Extra Top Layer if Necessary===
-Default is on.
-
-When selected, chop will add an extra layer at the very top of the object if the top of the object is more than half the layer height above the first slice.  This is so the cutting tool doesn't cut too deeply through the top of the object on its first pass.
-
-===Extra Decimal Places===
-Default is two.
-
-Defines the number of extra decimal places export will output compared to the number of decimal places in the layer height.  The higher the 'Extra Decimal Places', the more significant figures the output numbers will have.
-
-===Import Coarseness===
-Default is one.
-
-When a triangle mesh has holes in it, the triangle mesh slicer switches over to a slow algorithm that spans gaps in the mesh.  The higher the 'Import Coarseness' setting, the wider the gaps in the mesh it will span.  An import coarseness of one means it will span gaps of the edge width.
-
-===Layer Height===
-Default is 0.4 mm.
-
-Defines the height of the layer, this is the most important chop setting.
-
-===Layers===
-Chop slices from top to bottom.  To get only the bottom layer, set the "Layers From" to minus one.  The 'Layers From' until 'Layers To' range is a python slice.
-
-====Layers From====
-Default is zero.
-
-Defines the index of the top layer that will be chopped.  If the 'Layers From' is the default zero, the carving will start from the top layer.  If the 'Layers From' index is negative, then the carving will start from the 'Layers From' index above the bottom layer.
-
-====Layers To====
-Default is a huge number, which will be limited to the highest index number.
-
-Defines the index of the bottom layer that will be chopped.  If the 'Layers To' index is a huge number like the default, the carving will go to the bottom of the model.  If the 'Layers To' index is negative, then the carving will go to the 'Layers To' index above the bottom layer.
-
-===Mesh Type===
-Default is 'Correct Mesh'.
-
-====Correct Mesh====
-When selected, the mesh will be accurately chopped, and if a hole is found, chop will switch over to the algorithm that spans gaps.
-
-====Unproven Mesh====
-When selected, chop will use the gap spanning algorithm from the start.  The problem with the gap spanning algothm is that it will span gaps, even if there is not actually a gap in the model.
-
-===Perimeter Width===
-Default is 2 mm.
-
-Defines the width of the edge.
-
-===SVG Viewer===
-Default is webbrowser.
-
-If the 'SVG Viewer' is set to the default 'webbrowser', the scalable vector graphics file will be sent to the default browser to be opened.  If the 'SVG Viewer' is set to a program name, the scalable vector graphics file will be sent to that program to be opened.
-
-==Examples==
-The following examples chop the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and chop.py.
-
-> python chop.py
-This brings up the chop dialog.
-
-> python chop.py Screw Holder Bottom.stl
-The chop tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The chop tool has created the file:
-.. Screw Holder Bottom_chop.svg
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from fabmetheus_utilities import svg_writer
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import os
-import sys
-import time
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, gcodeText = '', repository=None):
-       "Get chopped text."
-       if fileName.endswith('.svg'):
-               gcodeText = archive.getTextIfEmpty(fileName, gcodeText)
-               if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'chop'):
-                       return gcodeText
-       carving = svg_writer.getCarving(fileName)
-       if carving == None:
-               return ''
-       if repository == None:
-               repository = ChopRepository()
-               settings.getReadRepository(repository)
-       return ChopSkein().getCarvedSVG( carving, fileName, repository )
-
-def getNewRepository():
-       'Get new repository.'
-       return ChopRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Chop a GNU Triangulated Surface file.  If no fileName is specified, chop the first GNU Triangulated Surface file in this folder."
-       startTime = time.time()
-       print('File ' + archive.getSummarizedFileName(fileName) + ' is being chopped.')
-       repository = ChopRepository()
-       settings.getReadRepository(repository)
-       chopGcode = getCraftedText( fileName, '', repository )
-       if chopGcode == '':
-               return
-       suffixFileName = fileName[ : fileName.rfind('.') ] + '_chop.svg'
-       suffixDirectoryName = os.path.dirname(suffixFileName)
-       suffixReplacedBaseName = os.path.basename(suffixFileName).replace(' ', '_')
-       suffixFileName = os.path.join( suffixDirectoryName, suffixReplacedBaseName )
-       archive.writeFileText( suffixFileName, chopGcode )
-       print('The chopped file is saved as ' + archive.getSummarizedFileName(suffixFileName) )
-       print('It took %s to chop the file.' % euclidean.getDurationString( time.time() - startTime ) )
-       if shouldAnalyze:
-               settings.openSVGPage( suffixFileName, repository.svgViewer.value )
-
-
-class ChopRepository(object):
-       "A class to handle the chop settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.chop.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getTranslatorFileTypeTuples(), 'Open File to be Chopped', self, '')
-               self.addExtraTopLayerIfNecessary = settings.BooleanSetting().getFromValue('Add Extra Top Layer if Necessary', self, True )
-               self.addLayerTemplateToSVG = settings.BooleanSetting().getFromValue('Add Layer Template to SVG', self, True)
-               self.edgeWidth = settings.FloatSpin().getFromValue( 0.4, 'Edge Width (mm):', self, 4.0, 2.0 )
-               self.extraDecimalPlaces = settings.FloatSpin().getFromValue(0.0, 'Extra Decimal Places (float):', self, 3.0, 2.0)
-               self.importCoarseness = settings.FloatSpin().getFromValue( 0.5, 'Import Coarseness (ratio):', self, 2.0, 1.0 )
-               self.layerHeight = settings.FloatSpin().getFromValue( 0.1, 'Layer Height (mm):', self, 1.0, 0.4 )
-               self.layersFrom = settings.IntSpin().getFromValue( 0, 'Layers From (index):', self, 20, 0 )
-               self.layersTo = settings.IntSpin().getSingleIncrementFromValue( 0, 'Layers To (index):', self, 912345678, 912345678 )
-               self.meshTypeLabel = settings.LabelDisplay().getFromName('Mesh Type: ', self, )
-               importLatentStringVar = settings.LatentStringVar()
-               self.correctMesh = settings.Radio().getFromRadio( importLatentStringVar, 'Correct Mesh', self, True )
-               self.unprovenMesh = settings.Radio().getFromRadio( importLatentStringVar, 'Unproven Mesh', self, False )
-               self.svgViewer = settings.StringSetting().getFromValue('SVG Viewer:', self, 'webbrowser')
-               settings.LabelSeparator().getFromRepository(self)
-               self.executeTitle = 'Chop'
-
-       def execute(self):
-               "Chop button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypes(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class ChopSkein(object):
-       "A class to chop a carving."
-       def addExtraTopLayerIfNecessary( self, carving, layerHeight, loopLayers ):
-               "Add extra top layer if necessary."
-               topRotatedBoundaryLayer = loopLayers[-1]
-               cuttingSafeHeight = topRotatedBoundaryLayer.z + 0.5001 * layerHeight
-               if cuttingSafeHeight > carving.getCarveCornerMaximum().z:
-                       return
-               extraTopRotatedBoundaryLayer = topRotatedBoundaryLayer.getCopyAtZ( topRotatedBoundaryLayer.z + layerHeight )
-               loopLayers.append( extraTopRotatedBoundaryLayer )
-
-       def getCarvedSVG( self, carving, fileName, repository ):
-               "Parse gnu triangulated surface text and store the chopped gcode."
-               layerHeight = repository.layerHeight.value
-               edgeWidth = repository.edgeWidth.value
-               carving.setCarveLayerHeight( layerHeight )
-               importRadius = 0.5 * repository.importCoarseness.value * abs(edgeWidth)
-               carving.setCarveImportRadius(max(importRadius, 0.001 * layerHeight))
-               carving.setCarveIsCorrectMesh( repository.correctMesh.value )
-               loopLayers = carving.getCarveBoundaryLayers()
-               if len( loopLayers ) < 1:
-                       print('Warning, there are no slices for the model, this could be because the model is too small for the Layer Height.')
-                       return ''
-               if repository.addExtraTopLayerIfNecessary.value:
-                       self.addExtraTopLayerIfNecessary( carving, layerHeight, loopLayers )
-               loopLayers.reverse()
-               layerHeight = carving.getCarveLayerHeight()
-               decimalPlacesCarried = euclidean.getDecimalPlacesCarried(repository.extraDecimalPlaces.value, layerHeight)
-               svgWriter = svg_writer.SVGWriter(
-                       repository.addLayerTemplateToSVG.value,
-                       carving.getCarveCornerMaximum(),
-                       carving.getCarveCornerMinimum(),
-                       decimalPlacesCarried,
-                       carving.getCarveLayerHeight(),
-                       edgeWidth)
-               truncatedRotatedBoundaryLayers = svg_writer.getTruncatedRotatedBoundaryLayers(loopLayers, repository)
-               return svgWriter.getReplacedSVGTemplate( fileName, truncatedRotatedBoundaryLayers, 'chop', carving.getFabmetheusXML())
-
-
-def main():
-       "Display the chop dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/cleave.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/cleave.py
deleted file mode 100644 (file)
index cd8332e..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-"""
-This page is in the table of contents.
-Cleave is a script to cleave a shape into svg slice layers.
-
-==Settings==
-===Add Layer Template to SVG===
-Default is on.
-
-When selected, the layer template will be added to the svg output, which adds javascript control boxes.  So 'Add Layer Template to SVG' should be selected when the svg will be viewed in a browser.
-
-When off, no controls will be added, the svg output will only include the fabrication paths.  So 'Add Layer Template to SVG' should be deselected when the svg will be used by other software, like Inkscape.
-
-===Extra Decimal Places===
-Default is two.
-
-Defines the number of extra decimal places export will output compared to the number of decimal places in the layer height.  The higher the 'Extra Decimal Places', the more significant figures the output numbers will have.
-
-===Import Coarseness===
-Default is one.
-
-When a triangle mesh has holes in it, the triangle mesh slicer switches over to a slow algorithm that spans gaps in the mesh.  The higher the 'Import Coarseness' setting, the wider the gaps in the mesh it will span.  An import coarseness of one means it will span gaps of the edge width.
-
-===Layer Height===
-Default is 0.4 mm.
-
-Defines the height of the layer, this is the most important cleave setting.
-
-===Layers===
-Cleave slices from bottom to top.  To get a single layer, set the "Layers From" to zero and the "Layers To" to one.  The layer from until layer to range is a python slice.
-
-====Layers From====
-Default is zero.
-
-Defines the index of the bottom layer that will be cleaved.  If the layer from is the default zero, the carving will start from the lowest layer.  If the 'Layers From' index is negative, then the carving will start from the 'Layers From' index below the top layer.
-
-====Layers To====
-Default is a huge number, which will be limited to the highest index layer.
-
-Defines the index of the top layer that will be cleaved.  If the 'Layers To' index is a huge number like the default, the carving will go to the top of the model.  If the 'Layers To' index is negative, then the carving will go to the 'Layers To' index below the top layer.
-
-===Mesh Type===
-Default is 'Correct Mesh'.
-
-====Correct Mesh====
-When selected, the mesh will be accurately cleaved, and if a hole is found, cleave will switch over to the algorithm that spans gaps.
-
-====Unproven Mesh====
-When selected, cleave will use the gap spanning algorithm from the start.  The problem with the gap spanning algothm is that it will span gaps, even if there is not actually a gap in the model.
-
-===Perimeter Width===
-Default is two millimeters.
-
-Defines the width of the edge.
-
-===SVG Viewer===
-Default is webbrowser.
-
-If the 'SVG Viewer' is set to the default 'webbrowser', the scalable vector graphics file will be sent to the default browser to be opened.  If the 'SVG Viewer' is set to a program name, the scalable vector graphics file will be sent to that program to be opened.
-
-==Examples==
-The following examples cleave the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and cleave.py.
-
-> python cleave.py
-This brings up the cleave dialog.
-
-> python cleave.py Screw Holder Bottom.stl
-The cleave tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The cleave tool has created the file:
-.. Screw Holder Bottom_cleave.svg
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from fabmetheus_utilities import svg_writer
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import os
-import sys
-import time
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, gcodeText = '', repository=None):
-       "Get cleaved text."
-       if fileName.endswith('.svg'):
-               gcodeText = archive.getTextIfEmpty(fileName, gcodeText)
-               if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'cleave'):
-                       return gcodeText
-       carving = svg_writer.getCarving(fileName)
-       if carving == None:
-               return ''
-       if repository == None:
-               repository = CleaveRepository()
-               settings.getReadRepository(repository)
-       return CleaveSkein().getCarvedSVG( carving, fileName, repository )
-
-def getNewRepository():
-       'Get new repository.'
-       return CleaveRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Cleave a GNU Triangulated Surface file."
-       startTime = time.time()
-       print('File ' + archive.getSummarizedFileName(fileName) + ' is being cleaved.')
-       repository = CleaveRepository()
-       settings.getReadRepository(repository)
-       cleaveGcode = getCraftedText( fileName, '', repository )
-       if cleaveGcode == '':
-               return
-       suffixFileName = fileName[ : fileName.rfind('.') ] + '_cleave.svg'
-       suffixDirectoryName = os.path.dirname(suffixFileName)
-       suffixReplacedBaseName = os.path.basename(suffixFileName).replace(' ', '_')
-       suffixFileName = os.path.join( suffixDirectoryName, suffixReplacedBaseName )
-       archive.writeFileText( suffixFileName, cleaveGcode )
-       print('The cleaved file is saved as ' + archive.getSummarizedFileName(suffixFileName) )
-       print('It took %s to cleave the file.' % euclidean.getDurationString( time.time() - startTime ) )
-       if shouldAnalyze:
-               settings.openSVGPage( suffixFileName, repository.svgViewer.value )
-
-
-class CleaveRepository(object):
-       "A class to handle the cleave settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.cleave.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getTranslatorFileTypeTuples(), 'Open File to be Cleaved', self, '')
-               self.addLayerTemplateToSVG = settings.BooleanSetting().getFromValue('Add Layer Template to SVG', self, True)
-               self.edgeWidth = settings.FloatSpin().getFromValue( 0.4, 'Edge Width (mm):', self, 4.0, 2.0 )
-               self.extraDecimalPlaces = settings.FloatSpin().getFromValue(0.0, 'Extra Decimal Places (float):', self, 3.0, 2.0)
-               self.importCoarseness = settings.FloatSpin().getFromValue( 0.5, 'Import Coarseness (ratio):', self, 2.0, 1.0 )
-               self.layerHeight = settings.FloatSpin().getFromValue( 0.1, 'Layer Height (mm):', self, 1.0, 0.4 )
-               self.layersFrom = settings.IntSpin().getFromValue( 0, 'Layers From (index):', self, 20, 0 )
-               self.layersTo = settings.IntSpin().getSingleIncrementFromValue( 0, 'Layers To (index):', self, 912345678, 912345678 )
-               self.meshTypeLabel = settings.LabelDisplay().getFromName('Mesh Type: ', self, )
-               importLatentStringVar = settings.LatentStringVar()
-               self.correctMesh = settings.Radio().getFromRadio( importLatentStringVar, 'Correct Mesh', self, True )
-               self.unprovenMesh = settings.Radio().getFromRadio( importLatentStringVar, 'Unproven Mesh', self, False )
-               self.svgViewer = settings.StringSetting().getFromValue('SVG Viewer:', self, 'webbrowser')
-               settings.LabelSeparator().getFromRepository(self)
-               self.executeTitle = 'Cleave'
-
-       def execute(self):
-               "Cleave button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypes(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class CleaveSkein(object):
-       "A class to cleave a carving."
-       def getCarvedSVG( self, carving, fileName, repository ):
-               "Parse gnu triangulated surface text and store the cleaved gcode."
-               edgeWidth = repository.edgeWidth.value
-               layerHeight = repository.layerHeight.value
-               carving.setCarveLayerHeight( layerHeight )
-               importRadius = 0.5 * repository.importCoarseness.value * abs(edgeWidth)
-               carving.setCarveImportRadius(max(importRadius, 0.001 * layerHeight))
-               carving.setCarveIsCorrectMesh( repository.correctMesh.value )
-               loopLayers = carving.getCarveBoundaryLayers()
-               if len( loopLayers ) < 1:
-                       print('Warning, there are no slices for the model, this could be because the model is too small for the Layer Height.')
-                       return ''
-               layerThickness = carving.getCarveLayerHeight()
-               decimalPlacesCarried = euclidean.getDecimalPlacesCarried(repository.extraDecimalPlaces.value, layerHeight)
-               svgWriter = svg_writer.SVGWriter(
-                       repository.addLayerTemplateToSVG.value,
-                       carving.getCarveCornerMaximum(),
-                       carving.getCarveCornerMinimum(),
-                       decimalPlacesCarried,
-                       carving.getCarveLayerHeight(),
-                       edgeWidth)
-               truncatedRotatedBoundaryLayers = svg_writer.getTruncatedRotatedBoundaryLayers(loopLayers, repository)
-               return svgWriter.getReplacedSVGTemplate( fileName, truncatedRotatedBoundaryLayers, 'cleave', carving.getFabmetheusXML())
-
-
-def main():
-       "Display the cleave dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/clip.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/clip.py
deleted file mode 100644 (file)
index 9fef02a..0000000
+++ /dev/null
@@ -1,340 +0,0 @@
-"""
-This page is in the table of contents.
-The clip plugin clips the loop ends to prevent bumps from forming, and connects loops.
-
-The clip manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Clip
-
-==Operation==
-The default 'Activate Clip' checkbox is on.  When it is on, the functions described below will work, when it is off, the functions will not be called.
-
-==Settings==
-===Clip Over Perimeter Width===
-Default is 0.2.
-
-Defines the ratio of the amount each end of the loop is clipped over the edge width.  The total gap will therefore be twice the clip.  If the ratio is too high loops will have a gap, if the ratio is too low there will be a bulge at the loop ends.
-
-This setting will affect the output of clip, and the output of the skin.  In skin the half width edges will be clipped by according to this setting.
-
-===Maximum Connection Distance Over Perimeter Width===
-Default is ten.
-
-Defines the ratio of the maximum connection distance between loops over the edge width.
-
-Clip will attempt to connect loops that end close to each other, combining them into a spiral, so that the extruder does not stop and restart.  This setting sets the maximum gap size to connect.  This feature can reduce the amount of extra material or gaps formed at the loop end.
-
-Setting this to zero disables this feature, preventing the loops from being connected.
-
-==Examples==
-The following examples clip the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and clip.py.
-
-> python clip.py
-This brings up the clip dialog.
-
-> python clip.py Screw Holder Bottom.stl
-The clip tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The clip tool has created the file:
-.. Screw Holder Bottom_clip.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import intercircle
-from fabmetheus_utilities import settings
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText(fileName, text, repository=None):
-       "Clip a gcode linear move file or text."
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository)
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       "Clip a gcode linear move text."
-       if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'clip'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository(ClipRepository())
-       if not repository.activateClip.value:
-               return gcodeText
-       return ClipSkein().getCraftedGcode(gcodeText, repository)
-
-def getNewRepository():
-       'Get new repository.'
-       return ClipRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Clip a gcode linear move file.  Chain clip the gcode if it is not already clipped."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'clip', shouldAnalyze)
-
-
-class ClipRepository(object):
-       "A class to handle the clip settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.clip.html', self)
-               self.fileNameInput = settings.FileNameInput().getFromFileName(fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Clip', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Clip')
-               self.activateClip = settings.BooleanSetting().getFromValue('Activate Clip', self, False)
-               self.clipOverEdgeWidth = settings.FloatSpin().getFromValue(0.1, 'Clip Over Perimeter Width (ratio):', self, 0.8, 0.5)
-               self.maximumConnectionDistanceOverEdgeWidth = settings.FloatSpin().getFromValue( 1.0, 'Maximum Connection Distance Over Perimeter Width (ratio):', self, 20.0, 10.0)
-               self.executeTitle = 'Clip'
-
-       def execute(self):
-               "Clip button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class ClipSkein(object):
-       "A class to clip a skein of extrusions."
-       def __init__(self):
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.extruderActive = False
-               self.feedRateMinute = None
-               self.isEdge = False
-               self.isLoop = False
-               self.layerCount = settings.LayerCount()
-               self.loopPath = None
-               self.lineIndex = 0
-               self.oldConnectionPoint = None
-               self.oldLocation = None
-               self.oldWiddershins = None
-               self.travelFeedRateMinute = None
-
-       def addGcodeFromThreadZ( self, thread, z ):
-               "Add a gcode thread to the output."
-               if len(thread) > 0:
-                       self.distanceFeedRate.addGcodeMovementZWithFeedRate( self.travelFeedRateMinute, thread[0], z )
-               else:
-                       print("zero length vertex positions array which was skipped over, this should never happen")
-               if len(thread) < 2:
-                       print("thread of only one point in clip, this should never happen")
-                       print(thread)
-                       return
-               self.distanceFeedRate.addLine('M101')
-               for point in thread[1 :]:
-                       self.distanceFeedRate.addGcodeMovementZWithFeedRate( self.feedRateMinute, point, z )
-
-       def addSegmentToPixelTables(self, location, oldLocation):
-               "Add the segment to the layer and mask table."
-               euclidean.addValueSegmentToPixelTable(oldLocation, location, self.layerPixelTable, None, self.layerPixelWidth)
-
-       def addTailoredLoopPath(self, line):
-               "Add a clipped loop path."
-               if self.clipLength > 0.0:
-                       removeTable = {}
-                       euclidean.addLoopToPixelTable(self.loopPath.path, removeTable, self.layerPixelWidth)
-                       euclidean.removePixelTableFromPixelTable( removeTable, self.layerPixelTable )
-                       self.loopPath.path = euclidean.getClippedSimplifiedLoopPath(self.clipLength, self.loopPath.path, self.edgeWidth)
-                       euclidean.addLoopToPixelTable( self.loopPath.path, self.layerPixelTable, self.layerPixelWidth )
-               if self.oldWiddershins == None:
-                       self.addGcodeFromThreadZ( self.loopPath.path, self.loopPath.z )
-               else:
-                       if self.oldWiddershins != euclidean.isWiddershins( self.loopPath.path ):
-                               self.loopPath.path.reverse()
-                       for point in self.loopPath.path:
-                               self.distanceFeedRate.addGcodeMovementZWithFeedRate( self.feedRateMinute, point, self.loopPath.z )
-               if self.getNextThreadIsACloseLoop(self.loopPath.path):
-                       self.oldConnectionPoint = self.loopPath.path[-1]
-                       self.oldWiddershins = euclidean.isWiddershins(self.loopPath.path)
-               else:
-                       self.oldConnectionPoint = None
-                       self.oldWiddershins = None
-                       self.distanceFeedRate.addLine(line)
-               self.loopPath = None
-
-       def getConnectionIsCloseWithoutOverlap( self, location, path ):
-               "Determine if the connection is close enough and does not overlap another thread."
-               if len(path) < 1:
-                       return False
-               locationComplex = location.dropAxis()
-               segment = locationComplex - path[-1]
-               segmentLength = abs(segment)
-               if segmentLength <= 0.0:
-                       return True
-               if segmentLength > self.maximumConnectionDistance:
-                       return False
-               segmentTable = {}
-               euclidean.addSegmentToPixelTable( path[-1], locationComplex, segmentTable, 2.0, 2.0, self.layerPixelWidth )
-               if euclidean.isPixelTableIntersecting( self.layerPixelTable, segmentTable, {} ):
-                       return False
-               euclidean.addValueSegmentToPixelTable( path[-1], locationComplex, self.layerPixelTable, None, self.layerPixelWidth )
-               return True
-
-       def getCraftedGcode(self, gcodeText, repository):
-               "Parse gcode text and store the clip gcode."
-               self.lines = archive.getTextLines(gcodeText)
-               self.repository = repository
-               self.parseInitialization()
-               for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def getNextThreadIsACloseLoop(self, path):
-               "Determine if the next thread is a loop."
-               if self.oldLocation == None or self.maximumConnectionDistance <= 0.0:
-                       return False
-               isEdge = False
-               isLoop = False
-               location = self.oldLocation
-               for afterIndex in xrange(self.lineIndex + 1, len(self.lines)):
-                       line = self.lines[afterIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1':
-                               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-                       elif firstWord == '(<loop>':
-                               isLoop = True
-                       elif firstWord == '(<edge>':
-                               isEdge = True
-                       elif firstWord == 'M101':
-                               if isLoop != self.isLoop or isEdge != self.isEdge:
-                                       return False
-                               return self.getConnectionIsCloseWithoutOverlap(location, path)
-                       elif firstWord == '(<layer>':
-                               return False
-               return False
-
-       def isNextExtruderOn(self):
-               "Determine if there is an extruder on command before a move command."
-               for afterIndex in xrange(self.lineIndex + 1, len(self.lines)):
-                       line = self.lines[afterIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1' or firstWord == 'M103':
-                               return False
-                       elif firstWord == 'M101':
-                               return True
-               return False
-
-       def linearMove(self, splitLine):
-               "Add to loop path if this is a loop or path."
-               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine)
-               if self.isLoop or self.isEdge:
-                       if self.isNextExtruderOn():
-                               self.loopPath = euclidean.PathZ(location.z)
-               if self.loopPath == None:
-                       if self.extruderActive:
-                               self.oldWiddershins = None
-               else:
-                       if self.oldConnectionPoint != None:
-                               self.addSegmentToPixelTables(self.oldConnectionPoint, location.dropAxis())
-                               self.oldConnectionPoint = None
-                       self.loopPath.path.append(location.dropAxis())
-               self.oldLocation = location
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('clip')
-                               return
-                       elif firstWord == '(<edgeWidth>':
-                               self.distanceFeedRate.addTagBracketedLine('clipOverEdgeWidth', self.repository.clipOverEdgeWidth.value)
-                               self.edgeWidth = float(splitLine[1])
-                               absoluteEdgeWidth = abs(self.edgeWidth)
-                               self.clipLength = self.repository.clipOverEdgeWidth.value * self.edgeWidth
-                               self.connectingStepLength = 0.5 * absoluteEdgeWidth
-                               self.layerPixelWidth = 0.34321 * absoluteEdgeWidth
-                               self.maximumConnectionDistance = self.repository.maximumConnectionDistanceOverEdgeWidth.value * absoluteEdgeWidth
-                       elif firstWord == '(<travelFeedRatePerSecond>':
-                               self.travelFeedRateMinute = 60.0 * float(splitLine[1])
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               "Parse a gcode line and add it to the clip skein."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       self.linearMove(splitLine)
-               elif firstWord == '(<layer>':
-                       self.setLayerPixelTable()
-               elif firstWord == '(<loop>':
-                       self.isLoop = True
-               elif firstWord == '(</loop>)':
-                       self.isLoop = False
-               elif firstWord == 'M101':
-                       self.extruderActive = True
-               elif firstWord == 'M103':
-                       self.extruderActive = False
-                       if self.loopPath != None:
-                               self.addTailoredLoopPath(line)
-                               return
-               elif firstWord == '(<edge>':
-                       self.isEdge = True
-               elif firstWord == '(</edge>)':
-                       self.isEdge = False
-               if self.loopPath == None:
-                       self.distanceFeedRate.addLine(line)
-
-       def setLayerPixelTable(self):
-               "Set the layer pixel table."
-               self.layerCount.printProgressIncrement('clip')
-               boundaryLoop = None
-               extruderActive = False
-               self.lastInactiveLocation = None
-               self.layerPixelTable = {}
-               oldLocation = self.oldLocation
-               for afterIndex in xrange(self.lineIndex + 1, len(self.lines)):
-                       line = self.lines[ afterIndex ]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1':
-                               location = gcodec.getLocationFromSplitLine(oldLocation, splitLine)
-                               if extruderActive and oldLocation != None:
-                                       self.addSegmentToPixelTables(location.dropAxis(), oldLocation.dropAxis())
-                               if extruderActive:
-                                       if self.lastInactiveLocation != None:
-                                               self.addSegmentToPixelTables(self.lastInactiveLocation.dropAxis(), location.dropAxis())
-                                               self.lastInactiveLocation = None
-                               else:
-                                       self.lastInactiveLocation = location
-                               oldLocation = location
-                       elif firstWord == 'M101':
-                               extruderActive = True
-                       elif firstWord == 'M103':
-                               extruderActive = False
-                       elif firstWord == '(</boundaryPerimeter>)':
-                               euclidean.addLoopToPixelTable(boundaryLoop, self.layerPixelTable, self.layerPixelWidth)
-                               boundaryLoop = None
-                       elif firstWord == '(<boundaryPoint>':
-                               if boundaryLoop == None:
-                                       boundaryLoop = []
-                               location = gcodec.getLocationFromSplitLine(None, splitLine)
-                               boundaryLoop.append(location.dropAxis())
-                       elif firstWord == '(</layer>)':
-                               return
-
-def main():
-       "Display the clip dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/coil.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/coil.py
deleted file mode 100644 (file)
index 728e645..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-"""
-This page is in the table of contents.
-Coil is a script to coil wire or filament around an object.
-
-==Operation==
-The default 'Activate Coil' checkbox is on.  When it is on, the functions described below will work, when it is off, the functions will not be called.
-
-==Settings==
-===Minimum Tool Distance===
-Default is twenty millimeters.
-
-Defines the minimum distance between the wire dispenser and the object.  The 'Minimum Tool Distance' should be set to the maximum radius of the wire dispenser, times at least 1.3 to get a reasonable safety margin.
-
-==Examples==
-The following examples coil the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and coil.py.
-
-> python coil.py
-This brings up the coil dialog.
-
-> python coil.py Screw Holder Bottom.stl
-The coil tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The coil tool has created the file:
-Screw Holder Bottom_coil.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import intercircle
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, gcodeText = '', repository=None):
-       "Coil the file or gcodeText."
-       return getCraftedTextFromText( archive.getTextIfEmpty(fileName, gcodeText), repository )
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       "Coil a gcode linear move gcodeText."
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'coil'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository( CoilRepository() )
-       if not repository.activateCoil.value:
-               return gcodeText
-       return CoilSkein().getCraftedGcode(gcodeText, repository)
-
-def getNewRepository():
-       'Get new repository.'
-       return CoilRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Coil a gcode linear move file."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'coil', shouldAnalyze)
-
-
-class CoilRepository(object):
-       "A class to handle the coil settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.coil.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Coil', self, '')
-               self.activateCoil = settings.BooleanSetting().getFromValue('Activate Coil', self, True )
-               self.minimumToolDistance = settings.FloatSpin().getFromValue( 10.0, 'Minimum Tool Distance (millimeters):', self, 50.0, 20.0 )
-               self.executeTitle = 'Coil'
-
-       def execute(self):
-               "Coil button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-
-class CoilSkein(object):
-       "A class to coil a skein of extrusions."
-       def __init__(self):
-               self.boundaryLayers = []
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.edgeWidth = 0.6
-               self.lineIndex = 0
-               self.lines = None
-               self.oldLocationComplex = complex()
-               self.shutdownLines = []
-
-       def addCoilLayer( self, boundaryLayers, radius, z ):
-               "Add a coil layer."
-               self.distanceFeedRate.addLine('(<layer> %s )' % z ) # Indicate that a new layer is starting.
-               self.distanceFeedRate.addLine('(<nestedRing>)')
-               thread = []
-               for boundaryLayerIndex in xrange(1, len(boundaryLayers) - 1):
-                       boundaryLayer = boundaryLayers[boundaryLayerIndex]
-                       boundaryLayerBegin = boundaryLayers[boundaryLayerIndex - 1]
-                       boundaryLayerEnd = boundaryLayers[boundaryLayerIndex + 1]
-                       beginLocation = Vector3(0.0, 0.0, 0.5 * (boundaryLayerBegin.z + boundaryLayer.z))
-                       outsetLoop = intercircle.getLargestInsetLoopFromLoop(boundaryLayer.loops[0], - radius)
-                       self.addCoilToThread(beginLocation, 0.5 * (boundaryLayer.z + boundaryLayerEnd.z), outsetLoop, thread)
-               self.addGcodeFromThread(thread)
-               self.distanceFeedRate.addLine('(</nestedRing>)')
-               self.distanceFeedRate.addLine('(</layer>)')
-
-       def addCoilLayers(self):
-               "Add the coil layers."
-               numberOfLayersFloat = round( self.edgeWidth / self.layerHeight )
-               numberOfLayers = int( numberOfLayersFloat )
-               halfLayerThickness = 0.5 * self.layerHeight
-               startOutset = self.repository.minimumToolDistance.value + halfLayerThickness
-               startZ = self.boundaryLayers[0].z + halfLayerThickness
-               zRange = self.boundaryLayers[-1].z - self.boundaryLayers[0].z
-               zIncrement = 0.0
-               if zRange >= 0.0:
-                       zIncrement = zRange / numberOfLayersFloat
-               for layerIndex in xrange( numberOfLayers ):
-                       settings.printProgressByNumber(layerIndex, numberOfLayers, 'coil')
-                       boundaryLayers = self.boundaryLayers
-                       if layerIndex % 2 == 1:
-                               boundaryLayers = self.boundaryReverseLayers
-                       radius = startOutset + layerIndex * self.layerHeight
-                       z = startZ + layerIndex * zIncrement
-                       self.addCoilLayer( boundaryLayers, radius, z )
-
-       def addCoilToThread(self, beginLocation, endZ, loop, thread):
-               "Add a coil to the thread."
-               if len(loop) < 1:
-                       return
-               loop = euclidean.getLoopStartingClosest(self.halfEdgeWidth, self.oldLocationComplex, loop)
-               length = euclidean.getLoopLength(loop)
-               if length <= 0.0:
-                       return
-               oldPoint = loop[0]
-               pathLength = 0.0
-               for point in loop[1 :]:
-                       pathLength += abs(point - oldPoint)
-                       along = pathLength / length
-                       z = (1.0 - along) * beginLocation.z + along * endZ
-                       location = Vector3(point.real, point.imag, z)
-                       thread.append(location)
-                       oldPoint = point
-               self.oldLocationComplex = loop[-1]
-
-       def addGcodeFromThread( self, thread ):
-               "Add a thread to the output."
-               if len(thread) > 0:
-                       firstLocation = thread[0]
-                       self.distanceFeedRate.addGcodeMovementZ( firstLocation.dropAxis(), firstLocation.z )
-               else:
-                       print("zero length vertex positions array which was skipped over, this should never happen")
-               if len(thread) < 2:
-                       print("thread of only one point in addGcodeFromThread in coil, this should never happen")
-                       print(thread)
-                       return
-               self.distanceFeedRate.addLine('M101') # Turn extruder on.
-               for location in thread[1 :]:
-                       self.distanceFeedRate.addGcodeMovementZ( location.dropAxis(), location.z )
-               self.distanceFeedRate.addLine('M103') # Turn extruder off.
-
-       def getCraftedGcode(self, gcodeText, repository):
-               "Parse gcode text and store the coil gcode."
-               self.repository = repository
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization()
-               self.parseBoundaries()
-               self.parseUntilLayer()
-               self.addCoilLayers()
-               self.distanceFeedRate.addLines( self.shutdownLines )
-               return self.distanceFeedRate.output.getvalue()
-
-       def parseBoundaries(self):
-               "Parse the boundaries and add them to the boundary layers."
-               boundaryLoop = None
-               boundaryLayer = None
-               for line in self.lines[self.lineIndex :]:
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if len( self.shutdownLines ) > 0:
-                               self.shutdownLines.append(line)
-                       if firstWord == '(</boundaryPerimeter>)':
-                               boundaryLoop = None
-                       elif firstWord == '(<boundaryPoint>':
-                               location = gcodec.getLocationFromSplitLine(None, splitLine)
-                               if boundaryLoop == None:
-                                       boundaryLoop = []
-                                       boundaryLayer.loops.append(boundaryLoop)
-                               boundaryLoop.append(location.dropAxis())
-                       elif firstWord == '(<layer>':
-                               boundaryLayer = euclidean.LoopLayer(float(splitLine[1]))
-                               self.boundaryLayers.append(boundaryLayer)
-                       elif firstWord == '(</crafting>)':
-                               self.shutdownLines = [ line ]
-               for boundaryLayer in self.boundaryLayers:
-                       if not euclidean.isWiddershins( boundaryLayer.loops[0] ):
-                               boundaryLayer.loops[0].reverse()
-               self.boundaryReverseLayers = self.boundaryLayers[:]
-               self.boundaryReverseLayers.reverse()
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('coil')
-                               return
-                       elif firstWord == '(<layerHeight>':
-                               self.layerHeight = float(splitLine[1])
-                       elif firstWord == '(<edgeWidth>':
-                               self.edgeWidth = float(splitLine[1])
-                               self.halfEdgeWidth = 0.5 * self.edgeWidth
-                       self.distanceFeedRate.addLine(line)
-
-       def parseUntilLayer(self):
-               "Parse until the layer line and add it to the coil skein."
-               for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(<layer>':
-                               return
-                       self.distanceFeedRate.addLine(line)
-
-
-def main():
-       "Display the coil dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/comb.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/comb.py
deleted file mode 100644 (file)
index a42a0dd..0000000
+++ /dev/null
@@ -1,480 +0,0 @@
-"""
-This page is in the table of contents.
-Comb is a craft plugin to bend the extruder travel paths around holes in the slices, to avoid stringers.
-
-The comb manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Comb
-
-==Operation==
-The default 'Activate Comb' checkbox is off.  When it is on, the functions described below will work, when it is off, nothing will be done.
-
-==Settings==
-===Running Jump Space===
-Default: 2 mm
-
-Defines the running jump space that is added before going from one island to another.  If the running jump space is greater than zero, the departure from the island will also be brought closer to the arrival point on the next island so that the stringer between islands will be shorter.  For an extruder with acceleration code, an extra space before leaving the island means that it will be going at high speed as it exits the island, which means the stringer between islands will be thinner.
-
-==Examples==
-The following examples comb the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and comb.py.
-
-> python comb.py
-This brings up the comb dialog.
-
-> python comb.py Screw Holder Bottom.stl
-The comb tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The comb tool has created the file:
-.. Screw Holder Bottom_comb.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import intercircle
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText(fileName, text, repository=None):
-       "Comb a gcode linear move text."
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository)
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       "Comb a gcode linear move text."
-       if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'comb'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository(CombRepository())
-       if not repository.activateComb.value:
-               return gcodeText
-       return CombSkein().getCraftedGcode(gcodeText, repository)
-
-def getJumpPoint(begin, end, loop, runningJumpSpace):
-       'Get running jump point inside loop.'
-       segment = begin - end
-       segmentLength = abs(segment)
-       if segmentLength == 0.0:
-               return begin
-       segment /= segmentLength
-       distancePoint = DistancePoint(begin, loop, runningJumpSpace, segment)
-       if distancePoint.distance == runningJumpSpace:
-               return distancePoint.point
-       effectiveDistance = distancePoint.distance
-       jumpPoint = distancePoint.point
-       segmentLeft = complex(0.70710678118654757, -0.70710678118654757)
-       distancePoint = DistancePoint(begin, loop, runningJumpSpace, segmentLeft)
-       distancePoint.distance *= 0.5
-       if distancePoint.distance > effectiveDistance:
-               effectiveDistance = distancePoint.distance
-               jumpPoint = distancePoint.point
-       segmentRight = complex(0.70710678118654757, 0.70710678118654757)
-       distancePoint = DistancePoint(begin, loop, runningJumpSpace, segmentRight)
-       distancePoint.distance *= 0.5
-       if distancePoint.distance > effectiveDistance:
-               effectiveDistance = distancePoint.distance
-               jumpPoint = distancePoint.point
-       return jumpPoint
-
-def getJumpPointIfInside(boundary, otherPoint, edgeWidth, runningJumpSpace):
-       'Get the jump point if it is inside the boundary, otherwise return None.'
-       insetBoundary = intercircle.getSimplifiedInsetFromClockwiseLoop(boundary, -edgeWidth)
-       closestJumpDistanceIndex = euclidean.getClosestDistanceIndexToLine(otherPoint, insetBoundary)
-       jumpIndex = (closestJumpDistanceIndex.index + 1) % len(insetBoundary)
-       jumpPoint = euclidean.getClosestPointOnSegment(insetBoundary[closestJumpDistanceIndex.index], insetBoundary[jumpIndex], otherPoint)
-       jumpPoint = getJumpPoint(jumpPoint, otherPoint, boundary, runningJumpSpace)
-       if euclidean.isPointInsideLoop(boundary, jumpPoint):
-               return jumpPoint
-       return None
-
-def getNewRepository():
-       'Get new repository.'
-       return CombRepository()
-
-def getPathsByIntersectedLoop(begin, end, loop):
-       'Get both paths along the loop from the point closest to the begin to the point closest to the end.'
-       closestBeginDistanceIndex = euclidean.getClosestDistanceIndexToLine(begin, loop)
-       closestEndDistanceIndex = euclidean.getClosestDistanceIndexToLine(end, loop)
-       beginIndex = (closestBeginDistanceIndex.index + 1) % len(loop)
-       endIndex = (closestEndDistanceIndex.index + 1) % len(loop)
-       closestBegin = euclidean.getClosestPointOnSegment(loop[closestBeginDistanceIndex.index], loop[beginIndex], begin)
-       closestEnd = euclidean.getClosestPointOnSegment(loop[closestEndDistanceIndex.index], loop[endIndex], end)
-       clockwisePath = [closestBegin]
-       widdershinsPath = [closestBegin]
-       if closestBeginDistanceIndex.index != closestEndDistanceIndex.index:
-               widdershinsPath += euclidean.getAroundLoop(beginIndex, endIndex, loop)
-               clockwisePath += euclidean.getAroundLoop(endIndex, beginIndex, loop)[: : -1]
-       clockwisePath.append(closestEnd)
-       widdershinsPath.append(closestEnd)
-       return [clockwisePath, widdershinsPath]
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Comb a gcode linear move file."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'comb', shouldAnalyze)
-
-
-class BoundarySegment(object):
-       'A boundary and segment.'
-       def __init__(self, begin):
-               'Initialize'
-               self.segment = [begin]
-
-       def getSegment(self, boundarySegmentIndex, boundarySegments, edgeWidth, runningJumpSpace):
-               'Get both paths along the loop from the point closest to the begin to the point closest to the end.'
-               nextBoundarySegment = boundarySegments[boundarySegmentIndex + 1]
-               nextBegin = nextBoundarySegment.segment[0]
-               end = getJumpPointIfInside(self.boundary, nextBegin, edgeWidth, runningJumpSpace)
-               if end == None:
-                       end = self.segment[1]
-               nextBegin = getJumpPointIfInside(nextBoundarySegment.boundary, end, edgeWidth, runningJumpSpace)
-               if nextBegin != None:
-                       nextBoundarySegment.segment[0] = nextBegin
-               return (self.segment[0], end)
-
-
-class CombRepository(object):
-       "A class to handle the comb settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.comb.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Comb', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Comb')
-               self.activateComb = settings.BooleanSetting().getFromValue('Activate Comb', self, True )
-               self.runningJumpSpace = settings.FloatSpin().getFromValue(0.0, 'Running Jump Space (mm):', self, 5.0, 2.0)
-               self.executeTitle = 'Comb'
-
-       def execute(self):
-               "Comb button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class CombSkein(object):
-       "A class to comb a skein of extrusions."
-       def __init__(self):
-               'Initialize'
-               self.boundaryLoop = None
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.extruderActive = False
-               self.layer = None
-               self.layerCount = settings.LayerCount()
-               self.layerTable = {}
-               self.layerZ = None
-               self.lineIndex = 0
-               self.lines = None
-               self.nextLayerZ = None
-               self.oldLocation = None
-               self.oldZ = None
-               self.operatingFeedRatePerMinute = None
-               self.travelFeedRateMinute = None
-               self.widdershinTable = {}
-
-       def addGcodePathZ( self, feedRateMinute, path, z ):
-               "Add a gcode path, without modifying the extruder, to the output."
-               for point in path:
-                       self.distanceFeedRate.addGcodeMovementZWithFeedRate(feedRateMinute, point, z)
-
-       def addIfTravel(self, splitLine):
-               "Add travel move around loops if the extruder is off."
-               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               if not self.extruderActive and self.oldLocation != None:
-                       if len(self.getBoundaries()) > 0:
-                               highestZ = max(location.z, self.oldLocation.z)
-                               self.addGcodePathZ(self.travelFeedRateMinute, self.getAroundBetweenPath(self.oldLocation.dropAxis(), location.dropAxis()), highestZ)
-               self.oldLocation = location
-
-       def addToLoop(self, location):
-               "Add a location to loop."
-               if self.layer == None:
-                       if not self.oldZ in self.layerTable:
-                               self.layerTable[self.oldZ] = []
-                       self.layer = self.layerTable[self.oldZ]
-               if self.boundaryLoop == None:
-                       self.boundaryLoop = []
-                       self.layer.append(self.boundaryLoop)
-               self.boundaryLoop.append(location.dropAxis())
-
-       def getAroundBetweenLineSegment(self, begin, boundaries, end):
-               'Get the path around the loops in the way of the original line segment.'
-               aroundBetweenLineSegment = []
-               boundaries = self.getBoundaries()
-               points = []
-               boundaryIndexes = self.getBoundaryIndexes(begin, boundaries, end, points)
-               boundaryIndexesIndex = 0
-               while boundaryIndexesIndex < len(boundaryIndexes) - 1:
-                       if boundaryIndexes[boundaryIndexesIndex + 1] == boundaryIndexes[boundaryIndexesIndex]:
-                               loopFirst = boundaries[boundaryIndexes[boundaryIndexesIndex]]
-                               pathBetween = self.getPathBetween(loopFirst, points[boundaryIndexesIndex : boundaryIndexesIndex + 4])
-                               begin = points[boundaryIndexesIndex]
-                               end = points[boundaryIndexesIndex + 3]
-                               pathBetween = self.getInsidePointsAlong(begin, pathBetween[0], points) + pathBetween
-                               pathBetween += self.getInsidePointsAlong(end, pathBetween[-1], points)
-                               aroundBetweenLineSegment += pathBetween
-                               boundaryIndexesIndex += 2
-                       else:
-                               boundaryIndexesIndex += 1
-               return aroundBetweenLineSegment
-
-       def getAroundBetweenPath(self, begin, end):
-               'Get the path around the loops in the way of the original line segment.'
-               aroundBetweenPath = []
-               boundaries = self.getBoundaries()
-               boundarySegments = self.getBoundarySegments(begin, boundaries, end)
-               for boundarySegmentIndex, boundarySegment in enumerate(boundarySegments):
-                       segment = boundarySegment.segment
-                       if boundarySegmentIndex < len(boundarySegments) - 1 and self.runningJumpSpace > 0.0:
-                               segment = boundarySegment.getSegment(boundarySegmentIndex, boundarySegments, self.edgeWidth, self.runningJumpSpace)
-                       aroundBetweenPath += self.getAroundBetweenLineSegment(segment[0], boundaries, segment[1])
-                       if boundarySegmentIndex < len(boundarySegments) - 1:
-                               aroundBetweenPath.append(segment[1])
-                               aroundBetweenPath.append(boundarySegments[boundarySegmentIndex + 1].segment[0])
-               for pointIndex in xrange(len(aroundBetweenPath) - 1, -1, -1):
-                       pointBefore = begin
-                       beforeIndex = pointIndex - 1
-                       if beforeIndex >= 0:
-                               pointBefore = aroundBetweenPath[beforeIndex]
-                       pointAfter = end
-                       afterIndex = pointIndex + 1
-                       if afterIndex < len(aroundBetweenPath):
-                               pointAfter = aroundBetweenPath[afterIndex]
-                       if not euclidean.isLineIntersectingLoops(boundaries, pointBefore, pointAfter):
-                               del aroundBetweenPath[pointIndex]
-               return aroundBetweenPath
-
-       def getBoundaries(self):
-               "Get boundaries for the layer."
-               if self.layerZ in self.layerTable:
-                       return self.layerTable[self.layerZ]
-               return []
-
-       def getBoundaryIndexes(self, begin, boundaries, end, points):
-               'Get boundary indexes and set the points in the way of the original line segment.'
-               boundaryIndexes = []
-               points.append(begin)
-               switchX = []
-               segment = euclidean.getNormalized(end - begin)
-               segmentYMirror = complex(segment.real, - segment.imag)
-               beginRotated = segmentYMirror * begin
-               endRotated = segmentYMirror * end
-               y = beginRotated.imag
-               for boundaryIndex in xrange(len(boundaries)):
-                       boundary = boundaries[boundaryIndex]
-                       boundaryRotated = euclidean.getRotatedComplexes(segmentYMirror, boundary)
-                       euclidean.addXIntersectionIndexesFromLoopY(boundaryRotated, boundaryIndex, switchX, y)
-               switchX.sort()
-               maximumX = max(beginRotated.real, endRotated.real)
-               minimumX = min(beginRotated.real, endRotated.real)
-               for xIntersection in switchX:
-                       if minimumX < xIntersection.x < maximumX:
-                               point = segment * complex(xIntersection.x, y)
-                               points.append(point)
-                               boundaryIndexes.append(xIntersection.index)
-               points.append(end)
-               return boundaryIndexes
-
-       def getBoundarySegments(self, begin, boundaries, end):
-               'Get the path broken into boundary segments whenever a different boundary is crossed.'
-               boundarySegments = []
-               boundarySegment = BoundarySegment(begin)
-               boundarySegments.append(boundarySegment)
-               points = []
-               boundaryIndexes = self.getBoundaryIndexes(begin, boundaries, end, points)
-               boundaryIndexesIndex = 0
-               while boundaryIndexesIndex < len(boundaryIndexes) - 1:
-                       if boundaryIndexes[boundaryIndexesIndex + 1] != boundaryIndexes[boundaryIndexesIndex]:
-                               boundarySegment.boundary = boundaries[boundaryIndexes[boundaryIndexesIndex]]
-                               nextBoundary = boundaries[boundaryIndexes[boundaryIndexesIndex + 1]]
-                               if euclidean.isWiddershins(boundarySegment.boundary) and euclidean.isWiddershins(nextBoundary):
-                                       boundarySegment.segment.append(points[boundaryIndexesIndex + 1])
-                                       boundarySegment = BoundarySegment(points[boundaryIndexesIndex + 2])
-                                       boundarySegment.boundary = nextBoundary
-                                       boundarySegments.append(boundarySegment)
-                                       boundaryIndexesIndex += 1
-                       boundaryIndexesIndex += 1
-               boundarySegment.segment.append(points[-1])
-               return boundarySegments
-
-       def getCraftedGcode(self, gcodeText, repository):
-               "Parse gcode text and store the comb gcode."
-               self.runningJumpSpace = repository.runningJumpSpace.value
-               self.repository = repository
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization()
-               for lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[lineIndex]
-                       self.parseBoundariesLayers(line)
-               for lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[lineIndex]
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def getInsidePointsAlong(self, begin, end, points):
-               'Get the points along the segment if it is required to keep the path inside the widdershin boundaries.'
-               segment = end - begin
-               segmentLength = abs(segment)
-               if segmentLength < self.quadrupleEdgeWidth:
-                       return []
-               segmentHalfPerimeter = self.halfEdgeWidth / segmentLength * segment
-               justAfterBegin = begin + segmentHalfPerimeter
-               justBeforeEnd = end - segmentHalfPerimeter
-               widdershins = self.getWiddershins()
-               if not euclidean.isLineIntersectingLoops(widdershins, justAfterBegin, justBeforeEnd):
-                       return []
-               numberOfSteps = 10
-               stepLength = (segmentLength - self.doubleEdgeWidth) / float(numberOfSteps)
-               for step in xrange(1, numberOfSteps + 1):
-                       along = begin + stepLength * step
-                       if not euclidean.isLineIntersectingLoops(widdershins, along, justBeforeEnd):
-                               return [along]
-               return []
-
-       def getPathBetween(self, loop, points):
-               "Add a path between the edge and the fill."
-               paths = getPathsByIntersectedLoop(points[1], points[2], loop)
-               shortestPath = paths[int(euclidean.getPathLength(paths[1]) < euclidean.getPathLength(paths[0]))]
-               if len(shortestPath) < 2:
-                       return shortestPath
-               if abs(points[1] - shortestPath[0]) > abs(points[1] - shortestPath[-1]):
-                       shortestPath.reverse()
-               loopWiddershins = euclidean.isWiddershins(loop)
-               pathBetween = []
-               for pointIndex in xrange(len(shortestPath)):
-                       center = shortestPath[pointIndex]
-                       centerPerpendicular = None
-                       beginIndex = pointIndex - 1
-                       if beginIndex >= 0:
-                               begin = shortestPath[beginIndex]
-                               centerPerpendicular = intercircle.getWiddershinsByLength(center, begin, self.edgeWidth*2.0)
-                       centerEnd = None
-                       endIndex = pointIndex + 1
-                       if endIndex < len(shortestPath):
-                               end = shortestPath[endIndex]
-                               centerEnd = intercircle.getWiddershinsByLength(end, center, self.edgeWidth*2.0)
-                       if centerPerpendicular == None:
-                               centerPerpendicular = centerEnd
-                       elif centerEnd != None:
-                               centerPerpendicular = 0.5 * (centerPerpendicular + centerEnd)
-                       between = None
-                       if centerPerpendicular == None:
-                               between = center
-                       if between == None:
-                               centerSideWiddershins = center + centerPerpendicular
-                               if euclidean.isPointInsideLoop(loop, centerSideWiddershins) == loopWiddershins:
-                                       between = centerSideWiddershins
-                       if between == None:
-                               centerSideClockwise = center - centerPerpendicular
-                               if euclidean.isPointInsideLoop(loop, centerSideClockwise) == loopWiddershins:
-                                       between = centerSideClockwise
-                       if between == None:
-                               between = center
-                       pathBetween.append(between)
-               return pathBetween
-
-       def getWiddershins(self):
-               'Get widdershins for the layer.'
-               if self.layerZ in self.widdershinTable:
-                       return self.widdershinTable[self.layerZ]
-               self.widdershinTable[self.layerZ] = []
-               for boundary in self.getBoundaries():
-                       if euclidean.isWiddershins(boundary):
-                               self.widdershinTable[self.layerZ].append(boundary)
-               return self.widdershinTable[self.layerZ]
-
-       def parseBoundariesLayers(self, line):
-               "Parse a gcode line."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'M103':
-                       self.boundaryLoop = None
-               elif firstWord == '(<boundaryPoint>':
-                       location = gcodec.getLocationFromSplitLine(None, splitLine)
-                       self.addToLoop(location)
-               elif firstWord == '(<layer>':
-                       self.boundaryLoop = None
-                       self.layer = None
-                       self.oldZ = float(splitLine[1])
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('comb')
-                               return
-                       elif firstWord == '(<edgeWidth>':
-                               self.edgeWidth = float(splitLine[1])
-                               self.doubleEdgeWidth = self.edgeWidth + self.edgeWidth
-                               self.halfEdgeWidth = 0.5 * self.edgeWidth
-                               self.quadrupleEdgeWidth = self.doubleEdgeWidth + self.doubleEdgeWidth
-                       elif firstWord == '(<travelFeedRatePerSecond>':
-                               self.travelFeedRateMinute = 60.0 * float(splitLine[1])
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               "Parse a gcode line and add it to the comb skein."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if self.distanceFeedRate.getIsAlteration(line):
-                       return
-               if firstWord == 'G1':
-                       self.addIfTravel(splitLine)
-                       self.layerZ = self.nextLayerZ
-               elif firstWord == 'M101':
-                       self.extruderActive = True
-               elif firstWord == 'M103':
-                       self.extruderActive = False
-               elif firstWord == '(<layer>':
-                       self.layerCount.printProgressIncrement('comb')
-                       self.nextLayerZ = float(splitLine[1])
-                       if self.layerZ == None:
-                               self.layerZ = self.nextLayerZ
-               self.distanceFeedRate.addLineCheckAlteration(line)
-
-
-class DistancePoint(object):
-       'A class to get the distance of the point along a segment inside a loop.'
-       def __init__(self, begin, loop, runningJumpSpace, segment):
-               'Initialize'
-               self.distance = 0.0
-               self.point = begin
-               steps = 10
-               spaceOverSteps = runningJumpSpace / float(steps)
-               for numerator in xrange(1, steps + 1):
-                       distance = float(numerator) * spaceOverSteps
-                       point = begin + segment * distance
-                       if euclidean.isPointInsideLoop(loop, point):
-                               self.distance = distance
-                               self.point = point
-                       else:
-                               return
-
-
-def main():
-       "Display the comb dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/cool.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/cool.py
deleted file mode 100644 (file)
index 66b3e58..0000000
+++ /dev/null
@@ -1,436 +0,0 @@
-"""
-This page is in the table of contents.
-Cool is a craft tool to cool the shape.
-
-Cool works well with a stepper extruder, it does not work well with a DC motor extruder.
-
-If enabled, before each layer that takes less then "Minimum Layer Time" to print the tool head will orbit around the printed area for 'Minimum Layer Time' minus 'the time it takes to print the layer' before it starts printing the layer. This is great way to let layers with smaller area cool before you start printing on top of them (so you do not overheat the area). 
-
-The cool manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Cool
-
-Allan Ecker aka The Masked Retriever's has written the "Skeinforge Quicktip: Cool" at:
-http://blog.thingiverse.com/2009/07/28/skeinforge-quicktip-cool/
-
-==Operation==
-The default 'Activate Cool' checkbox is on.  When it is on, the functions described below will work, when it is off, the functions will not be called.
-
-==Settings==
-===Bridge Cool===
-Default is one degree Celcius.
-
-If the layer is a bridge layer, then cool will lower the temperature by 'Bridge Cool' degrees Celcius.
-
-===Cool Type===
-Default is 'Slow Down'.
-
-====Orbit====
-When selected, cool will add orbits with the extruder off to give the layer time to cool, so that the next layer is not extruded on a molten base.  The orbits will be around the largest island on that layer.  Orbit should only be chosen if you can not upgrade to a stepper extruder.
-
-====Slow Down====
-When selected, cool will slow down the extruder so that it will take the minimum layer time to extrude the layer.  DC motors do not operate properly at slow flow rates, so if you have a DC motor extruder, you should upgrade to a stepper extruder, but if you can't do that, you can try using the 'Orbit' option.
-
-===Maximum Cool===
-Default is 2 degrees Celcius.
-
-If it takes less time to extrude the layer than the minimum layer time, then cool will lower the temperature by the 'Maximum Cool' setting times the layer time over the minimum layer time.
-
-===Minimum Layer Time===
-Default is 60 seconds.
-
-Defines the minimum amount of time the extruder will spend on a layer, this is an important setting.
-
-===Minimum Orbital Radius===
-Default is 10 millimeters.
-
-When the orbit cool type is selected, if the area of the largest island is as large as the square of the "Minimum Orbital Radius" then the orbits will be just within the island.  If the island is smaller, then the orbits will be in a square of the "Minimum Orbital Radius" around the center of the island.  This is so that the hot extruder does not stay too close to small islands.
-
-===Name of Alteration Files===
-Cool looks for alteration files in the alterations folder in the .skeinforge folder in the home directory.  Cool does not care if the text file names are capitalized, but some file systems do not handle file name cases properly, so to be on the safe side you should give them lower case names.  If it doesn't find the file it then looks in the alterations folder in the skeinforge_plugins folder.  The cool start and end text idea is from:
-http://makerhahn.blogspot.com/2008/10/yay-minimug.html
-
-====Name of Cool End File====
-Default is cool_end.gcode.
-
-If there is a file with the name of the "Name of Cool End File" setting, it will be added to the end of the orbits.
-
-====Name of Cool Start File====
-Default is cool_start.gcode.
-
-If there is a file with the name of the "Name of Cool Start File" setting, it will be added to the start of the orbits.
-
-===Orbital Outset===
-Default is 2 millimeters.
-
-When the orbit cool type is selected, the orbits will be outset around the largest island by 'Orbital Outset' millimeters.  If 'Orbital Outset' is negative, the orbits will be inset instead.
-
-===Turn Fan On at Beginning===
-Default is on.
-
-When selected, cool will turn the fan on at the beginning of the fabrication by adding the M106 command.
-
-===Turn Fan Off at Ending===
-Default is on.
-
-When selected, cool will turn the fan off at the ending of the fabrication by adding the M107 command.
-
-==Examples==
-The following examples cool the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and cool.py.
-
-> python cool.py
-This brings up the cool dialog.
-
-> python cool.py Screw Holder Bottom.stl
-The cool tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The cool tool has created the file:
-.. Screw Holder Bottom_cool.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import intercircle
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText(fileName, text, repository=None):
-       'Cool a gcode linear move text.'
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository)
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       'Cool a gcode linear move text.'
-       if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'cool'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository(CoolRepository())
-       if not repository.activateCool.value:
-               return gcodeText
-       return CoolSkein().getCraftedGcode(gcodeText, repository)
-
-def getNewRepository():
-       'Get new repository.'
-       return CoolRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       'Cool a gcode linear move file.  Chain cool the gcode if it is not already cooled.'
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'cool', shouldAnalyze)
-
-
-class CoolRepository(object):
-       'A class to handle the cool settings.'
-       def __init__(self):
-               'Set the default settings, execute title & settings fileName.'
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.cool.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName(
-                       fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Cool', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute(
-                       'http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Cool')
-               self.activateCool = settings.BooleanSetting().getFromValue('Activate Cool', self, True)
-               self.bridgeCool = settings.FloatSpin().getFromValue(0.0, 'Bridge Cool (Celcius):', self, 10.0, 1.0)
-               self.coolType = settings.MenuButtonDisplay().getFromName('Cool Type:', self)
-               self.orbit = settings.MenuRadio().getFromMenuButtonDisplay(self.coolType, 'Orbit', self, False)
-               self.slowDown = settings.MenuRadio().getFromMenuButtonDisplay(self.coolType, 'Slow Down', self, True)
-               self.maximumCool = settings.FloatSpin().getFromValue(0.0, 'Maximum Cool (Celcius):', self, 10.0, 2.0)
-               self.minimumLayerTime = settings.FloatSpin().getFromValue(0.0, 'Minimum Layer Time (seconds):', self, 120.0, 10.0)
-               self.minimumOrbitalRadius = settings.FloatSpin().getFromValue(
-                       0.0, 'Minimum Orbital Radius (millimeters):', self, 20.0, 10.0)
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Name of Alteration Files -', self )
-               self.nameOfCoolEndFile = settings.StringSetting().getFromValue('Name of Cool End File:', self, 'cool_end.gcode')
-               self.nameOfCoolStartFile = settings.StringSetting().getFromValue('Name of Cool Start File:', self, 'cool_start.gcode')
-               settings.LabelSeparator().getFromRepository(self)
-               self.orbitalOutset = settings.FloatSpin().getFromValue(1.0, 'Orbital Outset (millimeters):', self, 5.0, 2.0)
-               self.turnFanOnAtBeginning = settings.BooleanSetting().getFromValue('Turn Fan On at Beginning', self, True)
-               self.turnFanOffAtEnding = settings.BooleanSetting().getFromValue('Turn Fan Off at Ending', self, True)
-               self.executeTitle = 'Cool'
-               
-               self.minimumFeedRate = settings.FloatSpin().getFromValue(0.0, 'Minimum feed rate (mm/s):', self, 10.0, 5.0)
-               self.fanTurnOnLayerNr = settings.IntSpin().getFromValue(0, 'Fan on at layer:', self, 100, 0)
-               self.fanSpeedMin = settings.IntSpin().getFromValue(0, 'Fan speed min (%):', self, 100, 100)
-               self.fanSpeedMax = settings.IntSpin().getFromValue(0, 'Fan speed max (%):', self, 100, 100)
-
-       def execute(self):
-               'Cool button has been clicked.'
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(
-                       self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class CoolSkein(object):
-       'A class to cool a skein of extrusions.'
-       def __init__(self):
-               self.boundaryLayer = None
-               self.coolTemperature = None
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.feedRateMinute = 960.0
-               self.highestZ = 1.0
-               self.isBridgeLayer = False
-               self.isExtruderActive = False
-               self.layerCount = settings.LayerCount()
-               self.lineIndex = 0
-               self.lines = None
-               self.multiplier = 1.0
-               self.oldFlowRate = None
-               self.oldFlowRateString = None
-               self.oldLocation = None
-               self.oldTemperature = None
-               self.minFeedrate = 0
-               self.fanEnabled = False
-               self.lastFanSpeed = 0
-
-       def addCoolOrbits(self, remainingOrbitTime):
-               'Add the minimum radius cool orbits.'
-               if len(self.boundaryLayer.loops) < 1:
-                       return
-               insetBoundaryLoops = self.boundaryLayer.loops
-               if abs(self.repository.orbitalOutset.value) > 0.1 * abs(self.edgeWidth):
-                       insetBoundaryLoops = intercircle.getInsetLoopsFromLoops(self.boundaryLayer.loops, -self.repository.orbitalOutset.value)
-               if len(insetBoundaryLoops) < 1:
-                       insetBoundaryLoops = self.boundaryLayer.loops
-               largestLoop = euclidean.getLargestLoop(insetBoundaryLoops)
-               loopArea = euclidean.getAreaLoopAbsolute(largestLoop)
-               if loopArea < self.minimumArea:
-                       center = 0.5 * (euclidean.getMaximumByComplexPath(largestLoop) + euclidean.getMinimumByComplexPath(largestLoop))
-                       centerXBounded = max(center.real, self.boundingRectangle.cornerMinimum.real)
-                       centerXBounded = min(centerXBounded, self.boundingRectangle.cornerMaximum.real)
-                       centerYBounded = max(center.imag, self.boundingRectangle.cornerMinimum.imag)
-                       centerYBounded = min(centerYBounded, self.boundingRectangle.cornerMaximum.imag)
-                       center = complex(centerXBounded, centerYBounded)
-                       maximumCorner = center + self.halfCorner
-                       minimumCorner = center - self.halfCorner
-                       largestLoop = euclidean.getSquareLoopWiddershins(minimumCorner, maximumCorner)
-               pointComplex = euclidean.getXYComplexFromVector3(self.oldLocation)
-               if pointComplex != None:
-                       largestLoop = euclidean.getLoopStartingClosest(self.edgeWidth, pointComplex, largestLoop)
-               intercircle.addOrbitsIfLarge(
-                       self.distanceFeedRate, largestLoop, self.orbitalFeedRatePerSecond, remainingOrbitTime, self.highestZ)
-
-       def addCoolTemperature(self, remainingOrbitTime):
-               'Parse a gcode line and add it to the cool skein.'
-               if self.repository.minimumLayerTime.value < 0.0001:
-                       return
-               layerCool = self.repository.maximumCool.value * remainingOrbitTime / self.repository.minimumLayerTime.value
-               if self.isBridgeLayer:
-                       layerCool = max(self.repository.bridgeCool.value, layerCool)
-               if self.oldTemperature != None and layerCool != 0.0:
-                       self.coolTemperature = self.oldTemperature - layerCool
-                       self.addTemperature(self.coolTemperature)
-
-       def addFanSpeed(self, remainingOrbitTime):
-               if self.repository.minimumLayerTime.value < 0.0001:
-                       fanSpeed = self.repository.fanSpeedMin.value
-               else:
-                       f = min(1.0, 2.0 * remainingOrbitTime / self.repository.minimumLayerTime.value)
-                       fanSpeed = self.repository.fanSpeedMin.value + (self.repository.fanSpeedMax.value - self.repository.fanSpeedMin.value) * f
-               if self.lastFanSpeed != fanSpeed:
-                       self.distanceFeedRate.addLine('M106 S%d' % (fanSpeed * 255 / 100))
-                       self.lastFanSpeed = fanSpeed
-
-       def addFlowRate(self, flowRate):
-               'Add a multipled line of flow rate if different.'
-               if flowRate != None:
-                       self.distanceFeedRate.addLine('M108 S' + euclidean.getFourSignificantFigures(flowRate))
-
-       def addGcodeFromFeedRateMovementZ(self, feedRateMinute, point, z):
-               'Add a movement to the output.'
-               self.distanceFeedRate.addLine(self.distanceFeedRate.getLinearGcodeMovementWithFeedRate(feedRateMinute, point, z))
-
-       def addOrbitsIfNecessary(self, remainingOrbitTime):
-               'Parse a gcode line and add it to the cool skein.'
-               if remainingOrbitTime > 0.0 and self.boundaryLayer != None:
-                       self.addCoolOrbits(remainingOrbitTime)
-
-       def addTemperature(self, temperature):
-               'Add a line of temperature.'
-               self.distanceFeedRate.addLine('M104 S' + euclidean.getRoundedToThreePlaces(temperature))
-
-       def getCoolMove(self, line, location, splitLine):
-               'Get cool line according to time spent on layer.'
-               self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine)
-               return self.distanceFeedRate.getLineWithFeedRate(self.multiplier * self.feedRateMinute, line, splitLine)
-
-       def getCraftedGcode(self, gcodeText, repository):
-               'Parse gcode text and store the cool gcode.'
-               self.repository = repository
-               self.coolEndLines = settings.getAlterationFileLines(repository.nameOfCoolEndFile.value)
-               self.coolStartLines = settings.getAlterationFileLines(repository.nameOfCoolStartFile.value)
-               self.halfCorner = complex(repository.minimumOrbitalRadius.value, repository.minimumOrbitalRadius.value)
-               self.lines = archive.getTextLines(gcodeText)
-               self.minimumArea = 4.0 * repository.minimumOrbitalRadius.value * repository.minimumOrbitalRadius.value
-               self.minFeedrate = repository.minimumFeedRate.value * 60
-               self.parseInitialization()
-               self.boundingRectangle = gcodec.BoundingRectangle().getFromGcodeLines(self.lines[self.lineIndex :], 0.5 * self.edgeWidth)
-               margin = 0.2 * self.edgeWidth
-               halfCornerMargin = self.halfCorner + complex(margin, margin)
-               self.boundingRectangle.cornerMaximum -= halfCornerMargin
-               self.boundingRectangle.cornerMinimum += halfCornerMargin
-               for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       self.parseLine(line)
-               if repository.turnFanOffAtEnding.value:
-                       self.distanceFeedRate.addLine('M107')
-               return gcodec.getGcodeWithoutDuplication('M108', self.distanceFeedRate.output.getvalue())
-
-       def getLayerTime(self):
-               'Get the time the extruder spends on the layer.'
-               feedRateMinute = self.feedRateMinute
-               layerTime = 0.0
-               lastThreadLocation = self.oldLocation
-               for lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1':
-                               location = gcodec.getLocationFromSplitLine(lastThreadLocation, splitLine)
-                               feedRateMinute = gcodec.getFeedRateMinute(feedRateMinute, splitLine)
-                               if lastThreadLocation != None:
-                                       feedRateSecond = feedRateMinute / 60.0
-                                       layerTime += location.distance(lastThreadLocation) / feedRateSecond
-                               lastThreadLocation = location
-                       elif firstWord == '(<bridgeRotation>':
-                               self.isBridgeLayer = True
-                       elif firstWord == '(</layer>)':
-                               return layerTime
-               return layerTime
-
-       def getLayerTimeActive(self):
-               'Get the time the extruder spends on the layer while active.'
-               feedRateMinute = self.feedRateMinute
-               isExtruderActive = self.isExtruderActive
-               layerTime = 0.0
-               lastThreadLocation = self.oldLocation
-               for lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1':
-                               location = gcodec.getLocationFromSplitLine(lastThreadLocation, splitLine)
-                               feedRateMinute = gcodec.getFeedRateMinute(feedRateMinute, splitLine)
-                               if lastThreadLocation != None and isExtruderActive:
-                                       feedRateSecond = feedRateMinute / 60.0
-                                       layerTime += location.distance(lastThreadLocation) / feedRateSecond
-                               lastThreadLocation = location
-                       elif firstWord == 'M101':
-                               isExtruderActive = True
-                       elif firstWord == 'M103':
-                               isExtruderActive = False
-                       elif firstWord == '(<bridgeRotation>':
-                               self.isBridgeLayer = True
-                       elif firstWord == '(</layer>)':
-                               return layerTime
-               return layerTime
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == 'M108':
-                               self.oldFlowRate = float(splitLine[1][1 :])
-                       elif firstWord == '(<edgeWidth>':
-                               self.edgeWidth = float(splitLine[1])
-                       elif firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('cool')
-                               return
-                       elif firstWord == '(<operatingFlowRate>':
-                               self.oldFlowRate = float(splitLine[1])
-                       elif firstWord == '(<orbitalFeedRatePerSecond>':
-                               self.orbitalFeedRatePerSecond = float(splitLine[1])
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               'Parse a gcode line and add it to the cool skein.'
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-                       self.highestZ = max(location.z, self.highestZ)
-                       if self.isExtruderActive:
-                               line = self.getCoolMove(line, location, splitLine)
-                       self.oldLocation = location
-               elif firstWord == 'M101':
-                       self.isExtruderActive = True
-               elif firstWord == 'M103':
-                       self.isExtruderActive = False
-               elif firstWord == 'M104':
-                       self.oldTemperature = gcodec.getDoubleAfterFirstLetter(splitLine[1])
-               elif firstWord == 'M108':
-                       self.oldFlowRate = float(splitLine[1][1 :])
-                       self.addFlowRate(self.multiplier * self.oldFlowRate)
-                       return
-               elif firstWord == '(<boundaryPoint>':
-                       self.boundaryLoop.append(gcodec.getLocationFromSplitLine(None, splitLine).dropAxis())
-               elif firstWord == '(<layer>':
-                       self.layerCount.printProgressIncrement('cool')
-                       self.distanceFeedRate.addLine(line)
-                       if self.repository.turnFanOnAtBeginning.value and self.repository.fanTurnOnLayerNr.value == self.layerCount.layerIndex:
-                               self.fanEnabled = True
-                       self.distanceFeedRate.addLinesSetAbsoluteDistanceMode(self.coolStartLines)
-                       layerTime = self.getLayerTime()
-                       remainingOrbitTime = max(self.repository.minimumLayerTime.value - layerTime, 0.0)
-                       self.addCoolTemperature(remainingOrbitTime)
-                       if self.fanEnabled:
-                               self.addFanSpeed(remainingOrbitTime)
-                       if self.repository.orbit.value:
-                               self.addOrbitsIfNecessary(remainingOrbitTime)
-                       else:
-                               self.setMultiplier(remainingOrbitTime)
-                               if self.oldFlowRate != None:
-                                       self.addFlowRate(self.multiplier * self.oldFlowRate)
-                       z = float(splitLine[1])
-                       self.boundaryLayer = euclidean.LoopLayer(z)
-                       self.highestZ = max(z, self.highestZ)
-                       self.distanceFeedRate.addLinesSetAbsoluteDistanceMode(self.coolEndLines)
-                       return
-               elif firstWord == '(</layer>)':
-                       self.isBridgeLayer = False
-                       self.multiplier = 1.0
-                       if self.coolTemperature != None:
-                               self.addTemperature(self.oldTemperature)
-                               self.coolTemperature = None
-                       if self.oldFlowRate != None:
-                               self.addFlowRate(self.oldFlowRate)
-               elif firstWord == '(<nestedRing>)':
-                       self.boundaryLoop = []
-                       self.boundaryLayer.loops.append(self.boundaryLoop)
-               self.distanceFeedRate.addLine(line)
-
-       def setMultiplier(self, remainingOrbitTime):
-               'Set the feed and flow rate multiplier.'
-               layerTimeActive = self.getLayerTimeActive()
-               if remainingOrbitTime + layerTimeActive > 0.00001:
-                       self.multiplier = min(1.0, layerTimeActive / (remainingOrbitTime + layerTimeActive))
-                       if self.feedRateMinute * self.multiplier < self.minFeedrate:
-                               self.multiplier = self.minFeedrate / self.feedRateMinute
-               else:
-                       self.multiplier = 1.0
-
-def main():
-       'Display the cool dialog.'
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == '__main__':
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/dimension.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/dimension.py
deleted file mode 100644 (file)
index 52ad2f6..0000000
+++ /dev/null
@@ -1,420 +0,0 @@
-#! /usr/bin/env python
-"""
-This page is in the table of contents.
-Dimension adds Adrian's extruder distance E value so firmware does not have to calculate it on it's own and can set the extruder speed in relation to the distance that needs to be extruded.  Some printers don't support this.  Extruder distance is described at:
-
-http://blog.reprap.org/2009/05/4d-printing.html
-
-and in Erik de Bruijn's conversion script page at:
-
-http://objects.reprap.org/wiki/3D-to-5D-Gcode.php
-
-The dimension manual page is at:
-
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Dimension
-
-Nophead wrote an excellent article on how to set the filament parameters:
-
-http://hydraraptor.blogspot.com/2011/03/spot-on-flow-rate.html
-
-==Operation==
-The default 'Activate Dimension' checkbox is off.  When it is on, the functions described below will work, when it is off, the functions will not be called.
-
-==Settings==
-===Extrusion Distance Format Choice===
-Default is 'Absolute Extrusion Distance' because in Adrian's description the distance is absolute.  In future, because the relative distances are smaller than the cumulative absolute distances, hopefully the firmware will be able to use relative distance.
-
-====Absolute Extrusion Distance====
-When selected, the extrusion distance output will be the total extrusion distance to that gcode line.
-
-====Relative Extrusion Distance====
-When selected, the extrusion distance output will be the extrusion distance from the last gcode line.
-
-===Extruder Retraction Speed===
-Default is 13.3 mm/s.
-
-Defines the extruder retraction feed rate.  A high value will allow the retraction operation to complete before much material oozes out.  If your extruder can handle it, this value should be much larger than your feed rate.
-
-As an example, I have a feed rate of 48 mm/s and a 'Extruder Retraction Speed' of 150 mm/s.
-
-===Filament===
-====Filament Diameter====
-Default is 2.8 millimeters.
-
-Defines the filament diameter.
-
-====Filament Packing Density====
-Default is 0.85.  This is for ABS.
-
-Defines the effective filament packing density.
-
-The default value is so low for ABS because ABS is relatively soft and with a pinch wheel extruder the teeth of the pinch dig in farther, so it sees a smaller effective diameter.  With a hard plastic like PLA the teeth of the pinch wheel don't dig in as far, so it sees a larger effective diameter, so feeds faster, so for PLA the value should be around 0.97.  This is with Wade's hobbed bolt.  The effect is less significant with larger pinch wheels.
-
-Overall, you'll have to find the optimal filament packing density by experiment.
-
-===Maximum E Value before Reset===
-Default: 91234.0
-
-Defines the maximum E value before it is reset with the 'G92 E0' command line.  The reason it is reset only after the maximum E value is reached is because at least one firmware takes time to reset.  The problem with waiting until the E value is high before resetting is that more characters are sent.  So if your firmware takes a lot of time to reset, set this parameter to a high value, if it doesn't set this parameter to a low value or even zero.
-
-===Minimum Travel for Retraction===
-Default: 1.0 millimeter
-
-Defines the minimum distance that the extruder head has to travel from the end of one thread to the beginning of another, in order to trigger the extruder retraction.  Setting this to a high value means the extruder will retract only occasionally, setting it to a low value means the extruder will retract most of the time.
-
-===Retract Within Island===
-Default is off.
-
-When selected, retraction will work even when the next thread is within the same island.  If it is not selected, retraction will only work when crossing a boundary.
-
-===Retraction Distance===
-Default is zero.
-
-Defines the amount the extruder retracts (sucks back) the extruded filament whenever an extruder stop is commanded.  Using this seems to help prevent stringing.  e.g. If set to 10 the extruder reverses the distance required to pull back 10mm of filament.  In fact this does not actually happen but if you set this distance by trial and error you can get to a point where there is very little ooze from the extruder when it stops which is not normally the case. 
-
-===Restart Extra Distance===
-Default is zero.
-
-Defines the restart extra distance when the thread restarts.  The restart distance will be the retraction distance plus the restart extra distance.
-
-If this is greater than zero when the extruder starts this distance is added to the retract value giving extra filament.  It can be a negative value in which case it is subtracted from the retraction distance.  On some Repstrap machines a negative value can stop the build up of plastic that can occur at the start of edges.
-
-==Examples==
-The following examples dimension the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and dimension.py.
-
-> python dimension.py
-This brings up the dimension dialog.
-
-> python dimension.py Screw Holder Bottom.stl
-The dimension tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The dimension tool has created the file:
-.. Screw Holder Bottom_dimension.gcode
-
-"""
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import intercircle
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import math
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, gcodeText = '', repository=None):
-       'Dimension a gcode file or text.'
-       return getCraftedTextFromText( archive.getTextIfEmpty(fileName, gcodeText), repository )
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       'Dimension a gcode text.'
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'dimension'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository( DimensionRepository() )
-       if not repository.activateDimension.value:
-               return gcodeText
-       return DimensionSkein().getCraftedGcode(gcodeText, repository)
-
-def getNewRepository():
-       'Get new repository.'
-       return DimensionRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       'Dimension a gcode file.'
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'dimension', shouldAnalyze)
-
-
-class DimensionRepository(object):
-       'A class to handle the dimension settings.'
-       def __init__(self):
-               'Set the default settings, execute title & settings fileName.'
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.dimension.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Dimension', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Dimension')
-               self.activateDimension = settings.BooleanSetting().getFromValue('Activate Dimension', self, True )
-               extrusionDistanceFormatLatentStringVar = settings.LatentStringVar()
-               self.extrusionDistanceFormatChoiceLabel = settings.LabelDisplay().getFromName('Extrusion Distance Format Choice: ', self )
-               settings.Radio().getFromRadio( extrusionDistanceFormatLatentStringVar, 'Absolute Extrusion Distance', self, True )
-               self.relativeExtrusionDistance = settings.Radio().getFromRadio( extrusionDistanceFormatLatentStringVar, 'Relative Extrusion Distance', self, False )
-               self.extruderRetractionSpeed = settings.FloatSpin().getFromValue( 4.0, 'Extruder Retraction Speed (mm/s):', self, 34.0, 13.3 )
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Filament -', self )
-               self.filamentDiameter = settings.FloatSpin().getFromValue(1.0, 'Filament Diameter (mm):', self, 6.0, 2.89)
-               self.filamentPackingDensity = settings.FloatSpin().getFromValue(0.7, 'Filament Packing Density (ratio):', self, 1.0, 1.0)
-               settings.LabelSeparator().getFromRepository(self)
-               self.maximumEValueBeforeReset = settings.FloatSpin().getFromValue(0.0, 'Maximum E Value before Reset (float):', self, 999999.9, 91234.0)
-               self.minimumTravelForRetraction = settings.FloatSpin().getFromValue(0.0, 'Minimum Travel for Retraction (millimeters):', self, 2.0, 1.0)
-               self.retractWithinIsland = settings.BooleanSetting().getFromValue('Retract Within Island', self, False)
-               self.retractionDistance = settings.FloatSpin().getFromValue( 0.0, 'Retraction Distance (millimeters):', self, 100.0, 0.0 )
-               self.restartExtraDistance = settings.FloatSpin().getFromValue( 0.0, 'Restart Extra Distance (millimeters):', self, 100.0, 0.0 )
-               self.executeTitle = 'Dimension'
-
-       def execute(self):
-               'Dimension button has been clicked.'
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class DimensionSkein(object):
-       'A class to dimension a skein of extrusions.'
-       def __init__(self):
-               'Initialize.'
-               self.absoluteDistanceMode = True
-               self.boundaryLayers = []
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.feedRateMinute = None
-               self.isExtruderActive = False
-               self.layerIndex = -1
-               self.lineIndex = 0
-               self.maximumZFeedRatePerSecond = None
-               self.oldLocation = None
-               self.operatingFlowRate = None
-               self.retractionRatio = 1.0
-               self.totalExtrusionDistance = 0.0
-               self.travelFeedRatePerSecond = None
-               self.addRetraction = True
-               self.reverseRetraction = False
-               self.maxDistancePerMove = 30
-
-       def addLinearMoveExtrusionDistanceLine(self, extrusionDistance):
-               'Get the extrusion distance string from the extrusion distance.'
-               if self.repository.extruderRetractionSpeed.value != 0.0 and extrusionDistance != 0.0:
-                       self.distanceFeedRate.output.write('G1 F%s\n' % self.extruderRetractionSpeedMinuteString)
-                       self.distanceFeedRate.output.write('G1%s\n' % self.getExtrusionDistanceStringFromExtrusionDistance(extrusionDistance))
-                       self.distanceFeedRate.output.write('G1 F%s\n' % self.distanceFeedRate.getRounded(self.feedRateMinute))
-
-       def getCraftedGcode(self, gcodeText, repository):
-               'Parse gcode text and store the dimension gcode.'
-               self.repository = repository
-               filamentRadius = 0.5 * repository.filamentDiameter.value
-               filamentPackingArea = math.pi * filamentRadius * filamentRadius * repository.filamentPackingDensity.value
-               self.minimumTravelForRetraction = self.repository.minimumTravelForRetraction.value
-               self.doubleMinimumTravelForRetraction = self.minimumTravelForRetraction + self.minimumTravelForRetraction
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization()
-               if not self.repository.retractWithinIsland.value:
-                       self.parseBoundaries()
-               self.flowScaleSixty = 60.0 * self.layerHeight * self.edgeWidth / filamentPackingArea
-               self.restartDistance = self.repository.retractionDistance.value + self.repository.restartExtraDistance.value
-               self.extruderRetractionSpeedMinuteString = self.distanceFeedRate.getRounded(60.0 * self.repository.extruderRetractionSpeed.value)
-               for lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       self.parseLine( lineIndex )
-               return self.distanceFeedRate.output.getvalue()
-
-       def getDimensionedArcMovement(self, line, splitLine):
-               'Get a dimensioned arc movement.'
-               if self.oldLocation == None:
-                       return line
-               relativeLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               self.oldLocation += relativeLocation
-               distance = gcodec.getArcDistance(relativeLocation, splitLine)
-               return line + self.getExtrusionDistanceString(distance, splitLine)
-
-       def getDimensionedLinearMovement( self, line, splitLine ):
-               'Get a dimensioned linear movement.'
-               distance = 0.0
-               if self.absoluteDistanceMode:
-                       location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-                       if self.oldLocation != None:
-                               distance = abs( location - self.oldLocation )
-                               if distance > self.maxDistancePerMove * 1.1:
-                                       extra = ''
-                                       while distance > self.maxDistancePerMove * 1.1:
-                                               self.oldLocation.z = location.z
-                                               self.oldLocation += (location - self.oldLocation) / distance * self.maxDistancePerMove
-                                               distance -= self.maxDistancePerMove
-                                               e = self.getExtrusionDistanceString(self.maxDistancePerMove, splitLine)
-                                               extra += self.distanceFeedRate.getLinearGcodeMovementWithFeedRate(self.feedRateMinute, self.oldLocation.dropAxis(), self.oldLocation.z) + e + '\n'
-                                       line = extra + line
-                       self.oldLocation = location
-               else:
-                       if self.oldLocation is None:
-                               print('Warning: There was no absolute location when the G91 command was parsed, so the absolute location will be set to the origin.')
-                               self.oldLocation = Vector3()
-                       location = gcodec.getLocationFromSplitLine(None, splitLine)
-                       distance = abs( location )
-                       self.oldLocation += location
-               return line + self.getExtrusionDistanceString( distance, splitLine )
-
-       def getDistanceToNextThread(self, lineIndex):
-               'Get the travel distance to the next thread.'
-               if self.oldLocation == None:
-                       return None
-               isActive = False
-               location = self.oldLocation
-               for afterIndex in xrange(lineIndex + 1, len(self.lines)):
-                       line = self.lines[afterIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1':
-                               if isActive:
-                                       if not self.repository.retractWithinIsland.value:
-                                               locationEnclosureIndex = self.getSmallestEnclosureIndex(location.dropAxis())
-                                               if locationEnclosureIndex == self.getSmallestEnclosureIndex(self.oldLocation.dropAxis()):
-                                                       return None
-                                       locationMinusOld = location - self.oldLocation
-                                       return abs(locationMinusOld)
-                               location = gcodec.getLocationFromSplitLine(location, splitLine)
-                       elif firstWord == 'M101':
-                               isActive = True
-                       elif firstWord == 'M103':
-                               isActive = False
-               return None
-
-       def getExtrusionDistanceString( self, distance, splitLine ):
-               'Get the extrusion distance string.'
-               self.feedRateMinute = gcodec.getFeedRateMinute( self.feedRateMinute, splitLine )
-               if not self.isExtruderActive:
-                       return ''
-               if distance == 0.0:
-                       return ''
-               if distance < 0.0:
-                       print('Warning, the distance is less than zero in getExtrusionDistanceString in dimension; so there will not be an E value')
-                       print(distance)
-                       print(splitLine)
-                       return ''
-               if self.operatingFlowRate == None:
-                       return self.getExtrusionDistanceStringFromExtrusionDistance(self.flowScaleSixty / 60.0 * distance)
-               else:
-                       scaledFlowRate = self.flowRate * self.flowScaleSixty
-                       return self.getExtrusionDistanceStringFromExtrusionDistance(scaledFlowRate / self.feedRateMinute * distance)
-
-       def getExtrusionDistanceStringFromExtrusionDistance(self, extrusionDistance):
-               'Get the extrusion distance string from the extrusion distance.'
-               if self.repository.relativeExtrusionDistance.value:
-                       return ' E' + self.distanceFeedRate.getRounded(extrusionDistance)
-               self.totalExtrusionDistance += extrusionDistance
-               return ' E' + self.distanceFeedRate.getRounded(self.totalExtrusionDistance)
-
-       def getRetractionRatio(self, lineIndex):
-               'Get the retraction ratio.'
-               distanceToNextThread = self.getDistanceToNextThread(lineIndex)
-               if distanceToNextThread == None:
-                       return 0.0
-               if distanceToNextThread >= self.doubleMinimumTravelForRetraction:
-                       return 1.0
-               if distanceToNextThread <= self.minimumTravelForRetraction:
-                       return 0.0
-               return (distanceToNextThread - self.minimumTravelForRetraction) / self.minimumTravelForRetraction
-
-       def getSmallestEnclosureIndex(self, point):
-               'Get the index of the smallest boundary loop which encloses the point.'
-               boundaryLayer = self.boundaryLayers[self.layerIndex]
-               for loopIndex, loop in enumerate(boundaryLayer.loops):
-                       if euclidean.isPointInsideLoop(loop, point):
-                               return loopIndex
-               return None
-
-       def parseBoundaries(self):
-               'Parse the boundaries and add them to the boundary layers.'
-               boundaryLoop = None
-               boundaryLayer = None
-               for line in self.lines[self.lineIndex :]:
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == '(</boundaryPerimeter>)':
-                               boundaryLoop = None
-                       elif firstWord == '(<boundaryPoint>':
-                               location = gcodec.getLocationFromSplitLine(None, splitLine)
-                               if boundaryLoop == None:
-                                       boundaryLoop = []
-                                       boundaryLayer.loops.append(boundaryLoop)
-                               boundaryLoop.append(location.dropAxis())
-                       elif firstWord == '(<layer>':
-                               boundaryLayer = euclidean.LoopLayer(float(splitLine[1]))
-                               self.boundaryLayers.append(boundaryLayer)
-               for boundaryLayer in self.boundaryLayers:
-                       triangle_mesh.sortLoopsInOrderOfArea(False, boundaryLayer.loops)
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('dimension')
-                               return
-                       elif firstWord == '(<layerHeight>':
-                               self.layerHeight = float(splitLine[1])
-                       elif firstWord == '(<maximumZDrillFeedRatePerSecond>':
-                               self.maximumZFeedRatePerSecond = float(splitLine[1])
-                       elif firstWord == '(<maximumZFeedRatePerSecond>':
-                               self.maximumZFeedRatePerSecond = float(splitLine[1])
-                       elif firstWord == '(<operatingFeedRatePerSecond>':
-                               self.feedRateMinute = 60.0 * float(splitLine[1])
-                       elif firstWord == '(<operatingFlowRate>':
-                               self.operatingFlowRate = float(splitLine[1])
-                               self.flowRate = self.operatingFlowRate
-                       elif firstWord == '(<edgeWidth>':
-                               self.edgeWidth = float(splitLine[1])
-                       elif firstWord == '(<travelFeedRatePerSecond>':
-                               self.travelFeedRatePerSecond = float(splitLine[1])
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine( self, lineIndex ):
-               'Parse a gcode line and add it to the dimension skein.'
-               line = self.lines[lineIndex].lstrip()
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G2' or firstWord == 'G3':
-                       line = self.getDimensionedArcMovement( line, splitLine )
-               if firstWord == 'G1':
-                       line = self.getDimensionedLinearMovement( line, splitLine )
-               if firstWord == 'G90':
-                       self.absoluteDistanceMode = True
-               elif firstWord == 'G91':
-                       self.absoluteDistanceMode = False
-               elif firstWord == '(<layer>':
-                       self.layerIndex += 1
-                       if self.layerIndex == 0 and self.repository.relativeExtrusionDistance.value:
-                               self.distanceFeedRate.addLine('M83 ;Relative extrusion')
-                       settings.printProgress(self.layerIndex, 'dimension')
-               elif firstWord == '(</layer>)' or firstWord == '(<supportLayer>)' or firstWord == '(</supportLayer>)':
-                       if self.totalExtrusionDistance > 0.0 and not self.repository.relativeExtrusionDistance.value:
-                               self.distanceFeedRate.addLine('G92 E0')
-                               self.totalExtrusionDistance = 0.0
-               elif firstWord == 'M101':
-                       if self.retractionRatio > 0.0:
-                               self.addLinearMoveExtrusionDistanceLine(self.restartDistance * self.retractionRatio)
-                       if self.totalExtrusionDistance > self.repository.maximumEValueBeforeReset.value: 
-                               if not self.repository.relativeExtrusionDistance.value:
-                                       self.distanceFeedRate.addLine('G92 E0')
-                                       self.totalExtrusionDistance = 0.0
-                       self.isExtruderActive = True
-               elif firstWord == 'M103':
-                       self.retractionRatio = self.getRetractionRatio(lineIndex)
-                       if self.retractionRatio > 0.0:
-                               self.addLinearMoveExtrusionDistanceLine(-self.repository.retractionDistance.value * self.retractionRatio)
-                       self.isExtruderActive = False
-               elif firstWord == 'M108':
-                       self.flowRate = float( splitLine[1][1 :] )
-               self.distanceFeedRate.addLine(line)
-
-
-def main():
-       'Display the dimension dialog.'
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == '__main__':
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/drill.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/drill.py
deleted file mode 100644 (file)
index 685c0c0..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-"""
-This page is in the table of contents.
-Drill is a script to drill down small holes.
-
-==Operation==
-The default 'Activate Drill' checkbox is on.  When it is on, the functions described below will work, when it is off, the functions will not be called.
-
-==Settings==
-===Drilling Margin===
-The drill script will move the tool from the top of the hole plus the 'Drilling Margin on Top', to the bottom of the hole minus the 'Drilling Margin on Bottom'.
-
-===Drilling Margin on Top===
-Default is three millimeters.
-
-===Drilling Margin on Bottom===
-Default is one millimeter.
-
-==Examples==
-The following examples drill the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and drill.py.
-
-> python drill.py
-This brings up the drill dialog.
-
-> python drill.py Screw Holder Bottom.stl
-The drill tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The drill tool has created the file:
-.. Screw Holder Bottom_drill.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-def getCraftedText( fileName, text, repository=None):
-       "Drill a gcode linear move file or text."
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository)
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       "Drill a gcode linear move text."
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'drill'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository( DrillRepository() )
-       if not repository.activateDrill.value:
-               return gcodeText
-       return DrillSkein().getCraftedGcode(gcodeText, repository)
-
-def getNewRepository():
-       'Get new repository.'
-       return DrillRepository()
-
-def getPolygonCenter( polygon ):
-       "Get the centroid of a polygon."
-       pointSum = complex()
-       areaSum = 0.0
-       for pointIndex in xrange( len( polygon ) ):
-               pointBegin = polygon[pointIndex]
-               pointEnd  = polygon[ (pointIndex + 1) % len( polygon ) ]
-               area = pointBegin.real * pointEnd.imag - pointBegin.imag * pointEnd.real
-               areaSum += area
-               pointSum += complex( pointBegin.real + pointEnd.real, pointBegin.imag + pointEnd.imag ) * area
-       return pointSum / 3.0 / areaSum
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Drill a gcode linear move file."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'drill', shouldAnalyze)
-
-
-class ThreadLayer(object):
-       "A layer of loops and paths."
-       def __init__( self, z ):
-               "Thread layer constructor."
-               self.points = []
-               self.z = z
-
-       def __repr__(self):
-               "Get the string representation of this thread layer."
-               return '%s, %s' % ( self.z, self.points )
-
-
-class DrillRepository(object):
-       "A class to handle the drill settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.drill.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Drill', self, '')
-               self.activateDrill = settings.BooleanSetting().getFromValue('Activate Drill', self, True )
-               self.drillingMarginOnBottom = settings.FloatSpin().getFromValue( 0.0, 'Drilling Margin on Bottom (millimeters):', self, 5.0, 1.0 )
-               self.drillingMarginOnTop = settings.FloatSpin().getFromValue( 0.0, 'Drilling Margin on Top (millimeters):', self, 20.0, 3.0 )
-               self.executeTitle = 'Drill'
-
-       def execute(self):
-               "Drill button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class DrillSkein(object):
-       "A class to drill a skein of extrusions."
-       def __init__(self):
-               self.boundary = None
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.extruderActive = False
-               self.halfLayerThickness = 0.4
-               self.isDrilled = False
-               self.lineIndex = 0
-               self.lines = None
-               self.maximumDistance = 0.06
-               self.oldLocation = None
-               self.threadLayer = None
-               self.threadLayers = []
-
-       def addDrillHoles(self):
-               "Parse a gcode line."
-               self.isDrilled = True
-               if len( self.threadLayers ) < 1:
-                       return
-               topThreadLayer = self.threadLayers[0]
-               drillPoints = topThreadLayer.points
-               for drillPoint in drillPoints:
-                       zTop = topThreadLayer.z + self.halfLayerThickness + self.repository.drillingMarginOnTop.value
-                       drillingCenterDepth = self.getDrillingCenterDepth( topThreadLayer.z, drillPoint )
-                       zBottom = drillingCenterDepth - self.halfLayerThickness - self.repository.drillingMarginOnBottom.value
-                       self.addGcodeFromVerticalThread( drillPoint, zTop, zBottom )
-
-       def addGcodeFromVerticalThread( self, point, zBegin, zEnd ):
-               "Add a thread to the output."
-               self.distanceFeedRate.addGcodeMovementZ( point, zBegin )
-               self.distanceFeedRate.addLine('M101') # Turn extruder on.
-               self.distanceFeedRate.addGcodeMovementZ( point, zEnd )
-               self.distanceFeedRate.addLine('M103') # Turn extruder off.
-
-       def addThreadLayerIfNone(self):
-               "Add a thread layer if it is none."
-               if self.threadLayer != None:
-                       return
-               self.threadLayer = ThreadLayer( self.layerZ )
-               self.threadLayers.append( self.threadLayer )
-
-       def getCraftedGcode(self, gcodeText, repository):
-               "Parse gcode text and store the drill gcode."
-               self.lines = archive.getTextLines(gcodeText)
-               self.repository = repository
-               self.parseInitialization()
-               for line in self.lines[self.lineIndex :]:
-                       self.parseNestedRing(line)
-               for line in self.lines[self.lineIndex :]:
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def getDrillingCenterDepth( self, drillingCenterDepth, drillPoint ):
-               "Get the drilling center depth."
-               for threadLayer in self.threadLayers[1 :]:
-                       if self.isPointClose( drillPoint, threadLayer.points ):
-                               drillingCenterDepth = threadLayer.z
-                       else:
-                               return drillingCenterDepth
-               return drillingCenterDepth
-
-       def isPointClose( self, drillPoint, points ):
-               "Determine if a point on the thread layer is close."
-               for point in points:
-                       if abs( point - drillPoint ) < self.maximumDistance:
-                               return True
-               return False
-
-       def linearMove( self, splitLine ):
-               "Add a linear move to the loop."
-               self.addThreadLayerIfNone()
-               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               if self.extruderActive:
-                       self.boundary = None
-               self.oldLocation = location
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('drill')
-                               return
-                       elif firstWord == '(<layerHeight>':
-                               self.halfLayerThickness = 0.5 * float(splitLine[1])
-                       elif firstWord == '(<edgeWidth>':
-                               self.maximumDistance = 0.1 * float(splitLine[1])
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               "Parse a gcode line."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               self.distanceFeedRate.addLine(line)
-               if firstWord == '(<layer>':
-                       if not self.isDrilled:
-                               self.addDrillHoles()
-
-       def parseNestedRing(self, line):
-               "Parse a nested ring."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       self.linearMove(splitLine)
-               if firstWord == 'M101':
-                       self.extruderActive = True
-               elif firstWord == 'M103':
-                       self.extruderActive = False
-               elif firstWord == '(<boundaryPoint>':
-                       location = gcodec.getLocationFromSplitLine(None, splitLine)
-                       if self.boundary == None:
-                               self.boundary = []
-                       self.boundary.append(location.dropAxis())
-               elif firstWord == '(<layer>':
-                       self.layerZ = float(splitLine[1])
-                       self.threadLayer = None
-               elif firstWord == '(<boundaryPerimeter>)':
-                       self.addThreadLayerIfNone()
-               elif firstWord == '(</boundaryPerimeter>)':
-                       if self.boundary != None:
-                               self.threadLayer.points.append( getPolygonCenter( self.boundary ) )
-                               self.boundary = None
-
-
-def main():
-       "Display the drill dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/dwindle.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/dwindle.py
deleted file mode 100644 (file)
index 88eff86..0000000
+++ /dev/null
@@ -1,284 +0,0 @@
-"""
-This page is in the table of contents.
-Dwindle is a plugin to reduce the feed rate and flow rate at the end of the thread, in order to reduce the ooze when traveling. It reduces the flow rate by a bit more than the feed rate, in order to use up the pent up plastic in the thread so that there is less remaining in the ooze.
-
-The dwindle manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Dwindle
-
-==Operation==
-The default 'Activate Dwindle' checkbox is off.  When it is on, the functions described below will work, when it is off, nothing will be done.
-
-==Settings==
-===End Rate Multiplier===
-Default: 0.5
-
-Defines the ratio of the feed and flow rate at the end over the feed and flow rate of the rest of the thread. With reasonable values for the 'Pent Up Volume' and 'Slowdown Volume', the amount of ooze should be roughly proportional to the square of the 'End Rate Multiplier'. If the 'End Rate Multiplier' is too low, the printing will be very slow because the feed rate will be lower. If the 'End Rate Multiplier' is too high, there will still be a lot of ooze.
-
-===Pent Up Volume===
-Default: 0.4 mm3
-
-When the filament is stopped, there is a pent up volume of plastic that comes out afterwards. For best results, the 'Pent Up Volume' in dwindle should be set to that amount. If the 'Pent Up Volume' is too small, there will still be a lot of ooze. If the 'Pent Up Volume' is too large, the end of the thread will be thinner than the rest of the thread.
-
-===Slowdown Steps===
-Default: 3
-
-Dwindle reduces the feed rate and flow rate in steps so the thread will remain at roughly the same thickness until the end.  The "Slowdown Steps" setting is the number of steps, the more steps the smaller the variation in the thread thickness, but the larger the size of the resulting gcode file and the more time spent pausing between segments.
-
-===Slowdown Volume===
-Default: 5 mm3
-
-The 'Slowdown Volume' is the volume of the end of the thread where the feed and flow rates will be decreased. If the 'Slowdown Volume' is too small, there won't be enough time to get rid of the pent up plastic, so there will still be a lot of ooze. If the 'Slowdown Volume' is too large, a bit of time will be wasted because for a large portion of the thread, the feed rate will be slow. Overall, it is best to err on being too large, because too large would only waste machine time in production, rather than the more important string removal labor time.
-
-==Examples==
-The following examples dwindle the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and dwindle.py.
-
-> python dwindle.py
-This brings up the dwindle dialog.
-
-> python dwindle.py Screw Holder Bottom.stl
-The dwindle tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The dwindle tool has created the file:
-.. Screw Holder Bottom_dwindle.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import math
-import sys
-
-__author__ = 'Enrique Perez (perez_enrique aht yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText(fileName, gcodeText, repository=None):
-       'Dwindle a gcode linear move text.'
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, gcodeText), repository)
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       'Dwindle a gcode linear move text.'
-       if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'dwindle'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository(DwindleRepository())
-       if not repository.activateDwindle.value:
-               return gcodeText
-       return DwindleSkein().getCraftedGcode(gcodeText, repository)
-
-def getNewRepository():
-       'Get new repository.'
-       return DwindleRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       'Dwindle a gcode linear move file.  Chain dwindle the gcode if it is not already dwindle.'
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'dwindle', shouldAnalyze)
-
-
-class DwindleRepository(object):
-       'A class to handle the dwindle settings.'
-       def __init__(self):
-               'Set the default settings, execute title & settings fileName.'
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.dwindle.html', self)
-               self.fileNameInput = settings.FileNameInput().getFromFileName(fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Dwindle', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Dwindle')
-               self.activateDwindle = settings.BooleanSetting().getFromValue('Activate Dwindle', self, False)
-               settings.LabelSeparator().getFromRepository(self)
-               self.endRateMultiplier = settings.FloatSpin().getFromValue(0.4, 'End Rate Multiplier (ratio):', self, 0.8, 0.5)
-               self.pentUpVolume = settings.FloatSpin().getFromValue(0.1, 'Pent Up Volume (cubic millimeters):', self, 1.0, 0.4)
-               self.slowdownSteps = settings.IntSpin().getFromValue(2, 'Slowdown Steps (positive integer):', self, 10, 3)
-               self.slowdownVolume = settings.FloatSpin().getFromValue(1.0, 'Slowdown Volume (cubic millimeters):', self, 10.0, 5.0)
-               self.executeTitle = 'Dwindle'
-
-       def execute(self):
-               'Dwindle button has been clicked.'
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class DwindleSkein(object):
-       'A class to dwindle a skein of extrusions.'
-       def __init__(self):
-               'Initialize.'
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.feedRateMinute = 959.0
-               self.isActive = False
-               self.layerIndex = -1
-               self.lineIndex = 0
-               self.lines = None
-               self.oldFlowRate = None
-               self.oldLocation = None
-               self.operatingFlowRate = None
-               self.threadSections = []
-
-       def addThread(self):
-               'Add the thread sections to the gcode.'
-               if len(self.threadSections) == 0:
-                       return
-               area = self.area
-               dwindlePortion = 0.0
-               endRateMultiplier = self.repository.endRateMultiplier.value
-               halfOverSteps = self.halfOverSteps
-               oneOverSteps = self.oneOverSteps
-               currentPentUpVolume = self.repository.pentUpVolume.value * self.oldFlowRate / self.operatingFlowRate
-               slowdownFlowRateMultiplier = 1.0 - (currentPentUpVolume / self.repository.slowdownVolume.value)
-               operatingFeedRateMinute = self.operatingFeedRateMinute
-               slowdownVolume = self.repository.slowdownVolume.value
-               for threadSectionIndex in xrange(len(self.threadSections) - 1, -1, -1):
-                       threadSection = self.threadSections[threadSectionIndex]
-                       dwindlePortion = threadSection.getDwindlePortion(area, dwindlePortion, operatingFeedRateMinute, self.operatingFlowRate, slowdownVolume)
-               for threadSection in self.threadSections:
-                       threadSection.addGcodeThreadSection(self.distanceFeedRate, endRateMultiplier, halfOverSteps, oneOverSteps, slowdownFlowRateMultiplier)
-               self.distanceFeedRate.addFlowRateLine(self.oldFlowRate)
-               self.threadSections = []
-
-       def getCraftedGcode(self, gcodeText, repository):
-               'Parse gcode text and store the dwindle gcode.'
-               self.lines = archive.getTextLines(gcodeText)
-               self.repository = repository
-               self.parseInitialization()
-               if self.operatingFlowRate == None:
-                       print('Warning, there is no operatingFlowRate so dwindle will do nothing.')
-                       return gcodeText
-               self.area = self.infillWidth * self.layerHeight * self.volumeFraction
-               self.oneOverSteps = 1.0 / float(repository.slowdownSteps.value)
-               self.halfOverSteps = 0.5 * self.oneOverSteps
-               for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       self.parseLine(line)
-               return gcodec.getGcodeWithoutDuplication('M108', self.distanceFeedRate.output.getvalue())
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('dwindle')
-                               return
-                       elif firstWord == '(<infillWidth>':
-                               self.infillWidth = float(splitLine[1])
-                       elif firstWord == '(<layerHeight>':
-                               self.layerHeight = float(splitLine[1])
-                       elif firstWord == '(<operatingFeedRatePerSecond>':
-                               self.operatingFeedRateMinute = 60.0 * float(splitLine[1])
-                       elif firstWord == '(<operatingFlowRate>':
-                               self.operatingFlowRate = float(splitLine[1])
-                               self.oldFlowRate = self.operatingFlowRate
-                       elif firstWord == '(<volumeFraction>':
-                               self.volumeFraction = float(splitLine[1])
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               'Parse a gcode line and add it to the dwindle skein.'
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine)
-                       location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-                       if self.isActive:
-                               self.threadSections.append(ThreadSection(self.feedRateMinute, self.oldFlowRate, location, self.oldLocation))
-                       self.oldLocation = location
-               elif firstWord == '(<layer>':
-                       self.layerIndex += 1
-                       settings.printProgress(self.layerIndex, 'dwindle')
-               elif firstWord == 'M101':
-                       self.isActive = True
-               elif firstWord == 'M103':
-                       self.isActive = False
-                       self.addThread()
-               elif firstWord == 'M108':
-                       self.oldFlowRate = gcodec.getDoubleAfterFirstLetter(splitLine[1])
-               if len(self.threadSections) == 0:
-                       self.distanceFeedRate.addLine(line)
-
-
-class ThreadSection(object):
-       'A class to handle a volumetric section of a thread.'
-       def __init__(self, feedRateMinute, flowRate, location, oldLocation):
-               'Initialize.'
-               self.feedRateMinute = feedRateMinute
-               self.flowRate = flowRate
-               self.location = location
-               self.oldLocation = oldLocation
-
-       def addGcodeMovementByRate(self, distanceFeedRate, endRateMultiplier, location, rateMultiplier, slowdownFlowRateMultiplier):
-               'Add gcode movement by rate multiplier.'
-               flowRate = self.flowRate
-               rateMultiplier = rateMultiplier + endRateMultiplier * (1.0 - rateMultiplier)
-               if rateMultiplier < 1.0:
-                       flowRate *= slowdownFlowRateMultiplier
-               distanceFeedRate.addFlowRateLine(flowRate * rateMultiplier)
-               distanceFeedRate.addGcodeMovementZWithFeedRateVector3(self.feedRateMinute * rateMultiplier, location)
-
-       def addGcodeThreadSection(self, distanceFeedRate, endRateMultiplier, halfOverSteps, oneOverSteps, slowdownFlowRateMultiplier):
-               'Add gcode thread section.'
-               if self.dwindlePortionEnd > 1.0 - halfOverSteps:
-                       distanceFeedRate.addFlowRateLine(self.flowRate)
-                       distanceFeedRate.addGcodeMovementZWithFeedRateVector3(self.feedRateMinute, self.location)
-                       return
-               dwindleDifference = self.dwindlePortionBegin - self.dwindlePortionEnd
-               if self.dwindlePortionBegin < 1.0 and dwindleDifference > oneOverSteps:
-                       numberOfStepsFloat = math.ceil(dwindleDifference / oneOverSteps)
-                       numberOfSteps = int(numberOfStepsFloat)
-                       for stepIndex in xrange(numberOfSteps):
-                               alongBetween = (float(stepIndex) + 0.5) / numberOfStepsFloat
-                               location = self.getLocation(float(stepIndex + 1) / numberOfStepsFloat)
-                               rateMultiplier = self.dwindlePortionEnd * alongBetween + self.dwindlePortionBegin * (1.0 - alongBetween)
-                               self.addGcodeMovementByRate(distanceFeedRate, endRateMultiplier, location, rateMultiplier, slowdownFlowRateMultiplier)
-                       return
-               if self.dwindlePortionBegin > 1.0 > self.dwindlePortionEnd:
-                       alongDwindle = 0.0
-                       if self.dwindlePortionBegin > 1.0 + halfOverSteps:
-                               alongDwindle = (self.dwindlePortionBegin - 1.0) / dwindleDifference
-                               self.addGcodeMovementByRate(distanceFeedRate, endRateMultiplier, self.getLocation(alongDwindle), 1.0, slowdownFlowRateMultiplier)
-                       alongDwindlePortion = self.dwindlePortionEnd * alongDwindle + self.dwindlePortionBegin * (1.0 - alongDwindle)
-                       alongDwindleDifference = alongDwindlePortion - self.dwindlePortionEnd
-                       numberOfStepsFloat = math.ceil(alongDwindleDifference / oneOverSteps)
-                       numberOfSteps = int(numberOfStepsFloat)
-                       for stepIndex in xrange(numberOfSteps):
-                               alongBetween = (float(stepIndex) + 0.5) / numberOfStepsFloat
-                               alongDwindleLocation = float(stepIndex + 1) / numberOfStepsFloat
-                               location = self.getLocation(alongDwindleLocation + alongDwindle * (1.0 - alongDwindleLocation))
-                               rateMultiplier = self.dwindlePortionEnd * alongBetween + alongDwindlePortion * (1.0 - alongBetween)
-                               self.addGcodeMovementByRate(distanceFeedRate, endRateMultiplier, location, rateMultiplier, slowdownFlowRateMultiplier)
-                       return
-               rateMultiplier = min(0.5 * (self.dwindlePortionBegin + self.dwindlePortionEnd), 1.0)
-               self.addGcodeMovementByRate(distanceFeedRate, endRateMultiplier, self.location, rateMultiplier, slowdownFlowRateMultiplier)
-
-       def getDwindlePortion(self, area, dwindlePortion, operatingFeedRateMinute, operatingFlowRate, slowdownVolume):
-               'Get cumulative dwindle portion.'
-               self.dwindlePortionEnd = dwindlePortion
-               distance = abs(self.oldLocation - self.location)
-               volume = area * distance
-               self.dwindlePortionBegin = dwindlePortion + volume / slowdownVolume
-               return self.dwindlePortionBegin
-
-       def getLocation(self, along):
-               'Get location along way.'
-               return self.location * along + self.oldLocation * (1.0 - along)
-
-
-def main():
-       'Display the dwindle dialog.'
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == '__main__':
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export.py
deleted file mode 100644 (file)
index d640f20..0000000
+++ /dev/null
@@ -1,412 +0,0 @@
-"""
-This page is in the table of contents.
-Export is a craft tool to pick an export plugin, add information to the file name, and delete comments.
-
-The export manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Export
-
-==Operation==
-The default 'Activate Export' checkbox is on.  When it is on, the functions described below will work, when it is off, the functions will not be called.
-
-==Settings==
-===Add Descriptive Extension===
-Default is off.
-
-When selected, key profile values will be added as an extension to the gcode file.  For example:
-test.04hx06w_03fill_2cx2r_33EL.gcode
-
-would mean:
-
-* . (Carve section.)
-* 04h = 'Layer Height (mm):' 0.4
-* x
-* 06w = 0.6 width i.e. 0.4 times 'Edge Width over Height (ratio):' 1.5
-* _ (Fill section.)
-* 03fill = 'Infill Solidity (ratio):' 0.3
-* _ (Multiply section; if there is one column and one row then this section is not shown.)
-* 2c = 'Number of Columns (integer):' 2
-* x
-* 2r = 'Number of Rows (integer):' 2.
-* _ (Speed section.)
-* 33EL = 'Feed Rate (mm/s):' 33.0 and 'Flow Rate Setting (float):' 33.0.  If either value has a positive value after the decimal place then this is also shown, but if it is zero it is hidden.  Also, if the values differ (which they shouldn't with 5D volumetrics) then each should be displayed separately.  For example, 35.2E30L = 'Feed Rate (mm/s):' 35.2 and 'Flow Rate Setting (float):' 30.0.
-
-===Add Profile Extension===
-Default is off.
-
-When selected, the current profile will be added to the file extension.  For example:
-test.my_profile_name.gcode
-
-===Add Timestamp Extension===
-Default is off.
-
-When selected, the current date and time is added as an extension in format YYYYmmdd_HHMMSS (so it is sortable if one has many files).  For example:
-test.my_profile_name.20110613_220113.gcode
-
-===Also Send Output To===
-Default is empty.
-
-Defines the output name for sending to a file or pipe.  A common choice is stdout to print the output in the shell screen.  Another common choice is stderr.  With the empty default, nothing will be done.  If the value is anything else, the output will be written to that file name.
-
-===Analyze Gcode===
-Default is on.
-
-When selected, the penultimate gcode will be sent to the analyze plugins to be analyzed and viewed.
-
-===Comment Choice===
-Default is 'Delete All Comments'.
-
-====Do Not Delete Comments====
-When selected, export will not delete comments.  Crafting comments slow down the processing in many firmware types, which leads to pauses and therefore a lower quality print.
-====Delete Crafting Comments====
-When selected, export will delete the time consuming crafting comments, but leave the initialization comments.  Since the crafting comments are deleted, there are no pauses during extrusion.  The remaining initialization comments provide some useful information for the analyze tools.
-
-====Delete All Comments====
-When selected, export will delete all comments.  The comments are not necessary to run a fabricator.  Some printers do not support comments at all so the safest way is choose this option.
-
-===Export Operations===
-Export presents the user with a choice of the export plugins in the export_plugins folder.  The chosen plugin will then modify the gcode or translate it into another format.  There is also the "Do Not Change Output" choice, which will not change the output.  An export plugin is a script in the export_plugins folder which has the getOutput function, the globalIsReplaceable variable and if it's output is not replaceable, the writeOutput function.
-
-===File Extension===
-Default is gcode.
-
-Defines the file extension added to the name of the output file.  The output file will be named as originalname_export.extension so if you are processing XYZ.stl the output will by default be XYZ_export.gcode
-===Name of Replace File===
-Default is replace.csv.
-
-When export is exporting the code, if there is a tab separated file  with the name of the "Name of Replace File" setting, it will replace the string in the first column by its replacement in the second column.  If there is nothing in the second column, the first column string will be deleted, if this leads to an empty line, the line will be deleted.  If there are replacement columns after the second, they will be added as extra lines of text.  There is an example file replace_example.csv to demonstrate the tab separated format, which can be edited in a text editor or a spreadsheet.
-
-Export looks for the alteration file in the alterations folder in the .skeinforge folder in the home directory.  Export does not care if the text file names are capitalized, but some file systems do not handle file name cases properly, so to be on the safe side you should give them lower case names.  If it doesn't find the file it then looks in the alterations folder in the skeinforge_plugins folder.
-
-===Save Penultimate Gcode===
-Default is off.
-
-When selected, export will save the gcode file with the suffix '_penultimate.gcode' just before it is exported.  This is useful because the code after it is exported could be in a form which the viewers can not display well.
-
-==Examples==
-The following examples export the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and export.py.
-
-> python export.py
-This brings up the export dialog.
-
-> python export.py Screw Holder Bottom.stl
-The export tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The export tool has created the file:
-.. Screw Holder Bottom_export.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_analyze
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import cStringIO
-import os
-import sys
-import time
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__credits__ = 'Gary Hodgson <http://garyhodgson.com/reprap/2011/06/hacking-skeinforge-export-module/>'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       'Export a gcode linear move text.'
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'export'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository(ExportRepository())
-       if not repository.activateExport.value:
-               return gcodeText
-       return ExportSkein().getCraftedGcode(repository, gcodeText)
-
-def getDescriptionCarve(lines):
-       'Get the description for carve.'
-       descriptionCarve = ''
-       layerThicknessString = getSettingString(lines, 'carve', 'Layer Height')
-       if layerThicknessString != None:
-               descriptionCarve += layerThicknessString.replace('.', '') + 'h'
-       edgeWidthString = getSettingString(lines, 'carve', 'Edge Width over Height')
-       if edgeWidthString != None:
-               descriptionCarve += 'x%sw' % str(float(edgeWidthString) * float(layerThicknessString)).replace('.', '')
-       return descriptionCarve
-
-def getDescriptionFill(lines):
-       'Get the description for fill.'
-       activateFillString = getSettingString(lines, 'fill', 'Activate Fill')
-       if activateFillString == None or activateFillString == 'False':
-               return ''
-       infillSolidityString = getSettingString(lines, 'fill', 'Infill Solidity')
-       return '_' + infillSolidityString.replace('.', '') + 'fill'
-
-def getDescriptionMultiply(lines):
-       'Get the description for multiply.'
-       activateMultiplyString = getSettingString(lines, 'multiply', 'Activate Multiply')
-       if activateMultiplyString == None or activateMultiplyString == 'False':
-               return ''
-       columnsString = getSettingString(lines, 'multiply', 'Number of Columns')
-       rowsString = getSettingString(lines, 'multiply', 'Number of Rows')
-       if columnsString == '1' and rowsString == '1':
-               return ''
-       return '_%scx%sr' % (columnsString, rowsString)
-
-def getDescriptionSpeed(lines):
-       'Get the description for speed.'
-       activateSpeedString = getSettingString(lines, 'speed', 'Activate Speed')
-       if activateSpeedString == None or activateSpeedString == 'False':
-               return ''
-       feedRateString = getSettingString(lines, 'speed', 'Feed Rate')
-       flowRateString = getSettingString(lines, 'speed', 'Flow Rate')
-       if feedRateString == flowRateString:
-               return '_%sEL' % feedRateString.replace('.0', '')
-       return '_%sE%sL' % (feedRateString.replace('.0', ''), flowRateString.replace('.0', ''))
-
-def getDescriptiveExtension(gcodeText):
-       'Get the descriptive extension.'
-       lines = archive.getTextLines(gcodeText)
-       return '.' + getDescriptionCarve(lines) + getDescriptionFill(lines) + getDescriptionMultiply(lines) + getDescriptionSpeed(lines)
-
-def getDistanceGcode(exportText):
-       'Get gcode lines with distance variable added, this is for if ever there is distance code.'
-       lines = archive.getTextLines(exportText)
-       oldLocation = None
-       for line in lines:
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               firstWord = None
-               if len(splitLine) > 0:
-                       firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       location = gcodec.getLocationFromSplitLine(oldLocation, splitLine)
-                       if oldLocation != None:
-                               distance = location.distance(oldLocation)
-                       oldLocation = location
-       return exportText
-
-def getFirstValue(gcodeText, word):
-       'Get the value from the first line which starts with the given word.'
-       for line in archive.getTextLines(gcodeText):
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if gcodec.getFirstWord(splitLine) == word:
-                       return splitLine[1]
-       return ''
-
-def getNewRepository():
-       'Get new repository.'
-       return ExportRepository()
-
-def getReplaceableExportGcode(nameOfReplaceFile, replaceableExportGcode):
-       'Get text with strings replaced according to replace.csv file.'
-       replaceLines = settings.getAlterationLines(nameOfReplaceFile)
-       if len(replaceLines) < 1:
-               return replaceableExportGcode
-       for replaceLine in replaceLines:
-               splitLine = replaceLine.replace('\\n', '\t').split('\t')
-               if len(splitLine) > 0:
-                       replaceableExportGcode = replaceableExportGcode.replace(splitLine[0], '\n'.join(splitLine[1 :]))
-       output = cStringIO.StringIO()
-       gcodec.addLinesToCString(output, archive.getTextLines(replaceableExportGcode))
-       return output.getvalue()
-
-def getSelectedPluginModule( plugins ):
-       'Get the selected plugin module.'
-       for plugin in plugins:
-               if plugin.value:
-                       return archive.getModuleWithDirectoryPath( plugin.directoryPath, plugin.name )
-       return None
-
-def getSettingString(lines, procedureName, settingNameStart):
-       'Get the setting value from the lines, return None if there is no setting starting with that name.'
-       settingNameStart = settingNameStart.replace(' ', '_')
-       for line in lines:
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               firstWord = None
-               if len(splitLine) > 0:
-                       firstWord = splitLine[0]
-               if firstWord == '(<setting>':
-                       if len(splitLine) > 4:
-                               if splitLine[1] == procedureName and splitLine[2].startswith(settingNameStart):
-                                       return splitLine[3]
-               elif firstWord == '(</settings>)':
-                       return None
-       return None
-
-def sendOutputTo(outputTo, text):
-       'Send output to a file or a standard output.'
-       if outputTo.endswith('stderr'):
-               sys.stderr.write(text)
-               sys.stderr.write('\n')
-               sys.stderr.flush()
-               return
-       if outputTo.endswith('stdout'):
-               sys.stdout.write(text)
-               sys.stdout.write('\n')
-               sys.stdout.flush()
-               return
-       archive.writeFileText(outputTo, text)
-
-def getOutput(fileName):
-       'Export a gcode linear move file.'
-       if fileName == '':
-               return None
-       repository = ExportRepository()
-       settings.getReadRepository(repository)
-       startTime = time.time()
-       print('File ' + archive.getSummarizedFileName(fileName.encode('ascii', 'replace')) + ' is being chain exported.')
-       gcodeText = gcodec.getGcodeFileText(fileName, '')
-       procedures = skeinforge_craft.getProcedures('export', gcodeText)
-       gcodeText = skeinforge_craft.getChainTextFromProcedures(fileName, procedures[: -1], gcodeText)
-       if gcodeText == '':
-               return None
-       fileNamePenultimate = fileName[: fileName.rfind('.')] + '_penultimate.gcode'
-       if repository.savePenultimateGcode.value:
-               archive.writeFileText(fileNamePenultimate, gcodeText)
-               print('The penultimate file is saved as ' + archive.getSummarizedFileName(fileNamePenultimate))
-       exportGcode = getCraftedTextFromText(gcodeText, repository)
-       replaceableExportGcode = None
-       selectedPluginModule = getSelectedPluginModule(repository.exportPlugins)
-       if selectedPluginModule is None:
-               replaceableExportGcode = exportGcode
-       else:
-               if selectedPluginModule.globalIsReplaceable:
-                       replaceableExportGcode = selectedPluginModule.getOutput(exportGcode)
-               #else:
-               #       selectedPluginModule.writeOutput(outputFilename, exportGcode)
-       if replaceableExportGcode is not None:
-               replaceableExportGcode = getReplaceableExportGcode(repository.nameOfReplaceFile.value, replaceableExportGcode)
-       if repository.alsoSendOutputTo.value != '':
-               if replaceableExportGcode == None:
-                       replaceableExportGcode = selectedPluginModule.getOutput(exportGcode)
-               sendOutputTo(repository.alsoSendOutputTo.value, replaceableExportGcode)
-       print('It took %s to export the file.' % euclidean.getDurationString(time.time() - startTime))
-       return replaceableExportGcode
-
-class ExportRepository(object):
-       'A class to handle the export settings.'
-       def __init__(self):
-               'Set the default settings, execute title & settings fileName.'
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.export.html', self)
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Export', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Export')
-               self.activateExport = settings.BooleanSetting().getFromValue('Activate Export', self, True)
-               self.alsoSendOutputTo = settings.StringSetting().getFromValue('Also Send Output To:', self, '')
-               self.analyzeGcode = settings.BooleanSetting().getFromValue('Analyze Gcode', self, True)
-               self.commentChoice = settings.MenuButtonDisplay().getFromName('Comment Choice:', self)
-               self.doNotDeleteComments = settings.MenuRadio().getFromMenuButtonDisplay(self.commentChoice, 'Do Not Delete Comments', self, True)
-               self.deleteCraftingComments = settings.MenuRadio().getFromMenuButtonDisplay(self.commentChoice, 'Delete Crafting Comments', self, False)
-               self.deleteAllComments = settings.MenuRadio().getFromMenuButtonDisplay(self.commentChoice, 'Delete All Comments', self, False)
-               exportPluginsFolderPath = archive.getAbsoluteFrozenFolderPath(archive.getCraftPluginsDirectoryPath('export.py'), 'export_plugins')
-               exportStaticDirectoryPath = os.path.join(exportPluginsFolderPath, 'static_plugins')
-               exportPluginFileNames = archive.getPluginFileNamesFromDirectoryPath(exportPluginsFolderPath)
-               exportStaticPluginFileNames = archive.getPluginFileNamesFromDirectoryPath(exportStaticDirectoryPath)
-               self.exportLabel = settings.LabelDisplay().getFromName('Export Operations: ', self)
-               self.exportPlugins = []
-               exportLatentStringVar = settings.LatentStringVar()
-               self.doNotChangeOutput = settings.RadioCapitalized().getFromRadio(exportLatentStringVar, 'Do Not Change Output', self, False)
-               self.doNotChangeOutput.directoryPath = None
-               allExportPluginFileNames = exportPluginFileNames + exportStaticPluginFileNames
-               for exportPluginFileName in allExportPluginFileNames:
-                       exportPlugin = None
-                       default = False
-                       if exportPluginFileName == "gcode_small":
-                               default = True
-                       if exportPluginFileName in exportPluginFileNames:
-                               path = os.path.join(exportPluginsFolderPath, exportPluginFileName)
-                               exportPlugin = settings.RadioCapitalizedButton().getFromPath(exportLatentStringVar, exportPluginFileName, path, self, default)
-                               exportPlugin.directoryPath = exportPluginsFolderPath
-                       else:
-                               exportPlugin = settings.RadioCapitalized().getFromRadio(exportLatentStringVar, exportPluginFileName, self, default)
-                               exportPlugin.directoryPath = exportStaticDirectoryPath
-                       self.exportPlugins.append(exportPlugin)
-               self.fileExtension = settings.StringSetting().getFromValue('File Extension:', self, 'gcode')
-               self.nameOfReplaceFile = settings.StringSetting().getFromValue('Name of Replace File:', self, 'replace.csv')
-               self.savePenultimateGcode = settings.BooleanSetting().getFromValue('Save Penultimate Gcode', self, False)
-               self.executeTitle = 'Export'
-
-       def execute(self):
-               'Export button has been clicked.'
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class ExportSkein(object):
-       'A class to export a skein of extrusions.'
-       def __init__(self):
-               self.crafting = False
-               self.decimalPlacesExported = 2
-               self.output = cStringIO.StringIO()
-
-       def addLine(self, line):
-               'Add a line of text and a newline to the output.'
-               if line != '':
-                       self.output.write(line + '\n')
-
-       def getCraftedGcode( self, repository, gcodeText ):
-               'Parse gcode text and store the export gcode.'
-               self.repository = repository
-               lines = archive.getTextLines(gcodeText)
-               for line in lines:
-                       self.parseLine(line)
-               return self.output.getvalue()
-
-       def getLineWithTruncatedNumber(self, character, line, splitLine):
-               'Get a line with the number after the character truncated.'
-               numberString = gcodec.getStringFromCharacterSplitLine(character, splitLine)
-               if numberString == None:
-                       return line
-               roundedNumberString = euclidean.getRoundedToPlacesString(self.decimalPlacesExported, float(numberString))
-               return gcodec.getLineWithValueString(character, line, splitLine, roundedNumberString)
-
-       def parseLine(self, line):
-               'Parse a gcode line.'
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       self.addLine(line)
-                       return
-               firstWord = splitLine[0]
-               if firstWord == '(</crafting>)':
-                       self.crafting = False
-               elif firstWord == '(<decimalPlacesCarried>':
-                       self.decimalPlacesExported = int(splitLine[1]) - 1
-               if self.repository.deleteAllComments.value or (self.repository.deleteCraftingComments.value and self.crafting):
-                       if firstWord[0] == '(':
-                               return
-                       else:
-                               line = line.split(';')[0].split('(')[0].strip()
-               if firstWord == '(<crafting>)':
-                       self.crafting = True
-               if firstWord == '(</extruderInitialization>)':
-                       self.addLine(gcodec.getTagBracketedProcedure('export'))
-               if firstWord != 'G1' and firstWord != 'G2' and firstWord != 'G3' :
-                       self.addLine(line)
-                       return
-               line = self.getLineWithTruncatedNumber('X', line, splitLine)
-               line = self.getLineWithTruncatedNumber('Y', line, splitLine)
-               line = self.getLineWithTruncatedNumber('Z', line, splitLine)
-               line = self.getLineWithTruncatedNumber('I', line, splitLine)
-               line = self.getLineWithTruncatedNumber('J', line, splitLine)
-               line = self.getLineWithTruncatedNumber('R', line, splitLine)
-               self.addLine(line)
-
-
-def main():
-       'Display the export dialog.'
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == '__main__':
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/__init__.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/binary_16_byte.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/binary_16_byte.py
deleted file mode 100644 (file)
index a4d1aef..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-"""
-This page is in the table of contents.
-Binary 16 byte is an export plugin to convert gcode into 16 byte binary segments.
-
-An export plugin is a script in the export_plugins folder which has the getOutput function, the globalIsReplaceable variable and if it's output is not replaceable, the writeOutput function.  It is meant to be run from the export tool.  To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.
-
-The getOutput function of this script takes a gcode text and returns that text converted into 16 byte segments.  The writeOutput function of this script takes a gcode text and writes that in a binary format converted into 16 byte segments.
-
-This plugin is just a starter to make a real binary converter.
-
-==Settings==
-===Feed Rate Step Length===
-Default is 0.1 millimeters/second.
-
-Defines the feed rate step length.
-
-===File Extension===
-Default is bin.
-
-Defines the file extension suffix.
-
-===Offset===
-====X Offset====
-Default is zero.
-
-Defines the X Offset.
-
-====Y Offset====
-Default is zero.
-
-Defines the Y Offset.
-
-====Z Offset====
-Default is zero.
-
-Defines the Z Offset.
-
-===Step Length===
-====X Step Length====
-Default is 0.1 millimeters.
-
-Defines the X axis step length.
-
-====Y Step Length====
-Default is 0.1 millimeters.
-
-Defines the Y axis step length.
-
-====Z Step Length====
-Default is 0.01 millimeters.
-
-Defines the Z axis step length.
-
-==Record structure==
-BinArray(0) = AscW(Inst_Code_Letter)
-BinArray(1) = cInst_Code
-
-X Data
-sInt32_to_Hbytes(iXdim_1)
-BinArray(2) = lsb 'short lsb
-BinArray(3) = msb 'short msb
-
-Y Data
-sInt32_to_Hbytes(iYdim_2)
-BinArray(4) = lsb 'short lsb
-BinArray(5) = msb 'short msb
-
-Z Data
-sInt32_to_Hbytes(iZdim_3)
-BinArray(6) = lsb 'short lsb
-BinArray(7) = msb 'short msb
-
-I Data
-sInt32_to_Hbytes(iIdim_4)
-BinArray(8) = lsb 'short lsb
-BinArray(9) = msb 'short msb
-
-J Data
-sInt32_to_Hbytes(iJdim_5)
-BinArray(10) = lsb 'short lsb
-BinArray(11) = msb 'short msb
-
-BinArray(12) = FP_Char
-sInt32_to_Hbytes(iFP_Num)
-BinArray(13) = lsb 'short lsb
-
-BinArray(14) = bActiveFlags
-
-BinArray(15) = AscW("#")End of record filler
-
-Byte 14 is worth a few extra notes, this byte is used to define which of the axes are active, its used to get round the problem of say a line of code with no mention of z. This would be put into the file as z = 0 as the space for this data is reserved, if we did nothing, this would instruct the machine to go to z = 0. If we use the active flag to define the z axis as inactive the z = 0 is ignored and the value set to the last saved value of z, i.e it does not move.  If the z data is actually set to z = 0 then the axis would be set to active and the move takes place.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-from struct import Struct
-import cStringIO
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-# This is true if the output is text and false if it is binary."
-globalIsReplaceable = False
-
-
-def getIntegerFlagFromCharacterSplitLine(character, splitLine):
-       "Get the integer flag after the first occurence of the character in the split line."
-       lineFromCharacter = gcodec.getStringFromCharacterSplitLine(character, splitLine)
-       if lineFromCharacter == None:
-               return 0
-       return 1
-
-def getIntegerFromCharacterLengthLineOffset( character, offset, splitLine, stepLength ):
-       "Get the integer after the first occurence of the character in the split line."
-       lineFromCharacter = gcodec.getStringFromCharacterSplitLine(character, splitLine)
-       if lineFromCharacter == None:
-               return 0
-       floatValue = ( float( lineFromCharacter ) + offset ) / stepLength
-       return int( round( floatValue ) )
-
-def getNewRepository():
-       'Get new repository.'
-       return Binary16ByteRepository()
-
-def getOutput( gcodeText, binary16ByteRepository = None ):
-       'Get the exported version of a gcode file.'
-       if gcodeText == '':
-               return ''
-       if binary16ByteRepository == None:
-               binary16ByteRepository = Binary16ByteRepository()
-               settings.getReadRepository( binary16ByteRepository )
-       return Binary16ByteSkein().getCraftedGcode( gcodeText, binary16ByteRepository )
-
-def writeOutput( fileName, gcodeText = ''):
-       "Write the exported version of a gcode file."
-       binary16ByteRepository = Binary16ByteRepository()
-       settings.getReadRepository( binary16ByteRepository )
-       gcodeText = gcodec.getGcodeFileText(fileName, gcodeText)
-       skeinOutput = getOutput( gcodeText, binary16ByteRepository )
-       suffixFileName = fileName[ : fileName.rfind('.') ] + '.' + binary16ByteRepository.fileExtension.value
-       archive.writeFileText( suffixFileName, skeinOutput )
-       print('The converted file is saved as ' + archive.getSummarizedFileName(suffixFileName) )
-
-
-class Binary16ByteRepository:
-       "A class to handle the export settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               #Set the default settings.
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.binary_16_byte.html', self)
-               self.fileNameInput = settings.FileNameInput().getFromFileName( [ ('Gcode text files', '*.gcode') ], 'Open File to be Converted to Binary 16 Byte', self, '')
-               self.feedRateStepLength = settings.FloatSpin().getFromValue( 0.0, 'Feed Rate Step Length (millimeters/second)', self, 1.0, 0.1 )
-               self.fileExtension = settings.StringSetting().getFromValue('File Extension:', self, 'bin')
-               settings.LabelDisplay().getFromName('Offset:', self )
-               self.xOffset = settings.FloatSpin().getFromValue( - 100.0, 'X Offset (millimeters)', self, 100.0, 0.0 )
-               self.yOffset = settings.FloatSpin().getFromValue( -100.0, 'Y Offset (millimeters)', self, 100.0, 0.0 )
-               self.zOffset = settings.FloatSpin().getFromValue( - 10.0, 'Z Offset (millimeters)', self, 10.0, 0.0 )
-               settings.LabelDisplay().getFromName('Step Length:', self )
-               self.xStepLength = settings.FloatSpin().getFromValue( 0.0, 'X Step Length (millimeters)', self, 1.0, 0.1 )
-               self.yStepLength = settings.FloatSpin().getFromValue( 0.0, 'Y Step Length (millimeters)', self, 1.0, 0.1 )
-               self.zStepLength = settings.FloatSpin().getFromValue( 0.0, 'Z Step Length (millimeters)', self, 0.2, 0.01 )
-               self.executeTitle = 'Convert to Binary 16 Byte'
-
-       def execute(self):
-               "Convert to binary 16 byte button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode( self.fileNameInput.value, ['.gcode'], self.fileNameInput.wasCancelled )
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class Binary16ByteSkein:
-       "A class to convert gcode into 16 byte binary segments."
-       def __init__(self):
-               self.output = cStringIO.StringIO()
-
-       def getCraftedGcode( self, gcodeText, binary16ByteRepository ):
-               "Parse gcode text and store the gcode."
-               self.binary16ByteRepository = binary16ByteRepository
-               lines = archive.getTextLines(gcodeText)
-               for line in lines:
-                       self.parseLine(line)
-               return self.output.getvalue()
-
-       def parseLine(self, line):
-               "Parse a gcode line."
-               binary16ByteRepository = self.binary16ByteRepository
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               firstWord = gcodec.getFirstWord(splitLine)
-               if len(firstWord) < 1:
-                       return
-               firstLetter = firstWord[0]
-               if firstLetter == '(':
-                       return
-               feedRateInteger = getIntegerFromCharacterLengthLineOffset('F', 0.0, splitLine, binary16ByteRepository.feedRateStepLength.value )
-               iInteger = getIntegerFromCharacterLengthLineOffset('I', 0.0, splitLine, binary16ByteRepository.xStepLength.value )
-               jInteger = getIntegerFromCharacterLengthLineOffset('J', 0.0, splitLine, binary16ByteRepository.yStepLength.value )
-               xInteger = getIntegerFromCharacterLengthLineOffset('X', binary16ByteRepository.xOffset.value, splitLine, binary16ByteRepository.xStepLength.value )
-               yInteger = getIntegerFromCharacterLengthLineOffset('Y', binary16ByteRepository.yOffset.value, splitLine, binary16ByteRepository.yStepLength.value )
-               zInteger = getIntegerFromCharacterLengthLineOffset('Z', binary16ByteRepository.zOffset.value, splitLine, binary16ByteRepository.zStepLength.value )
-               sixteenByteStruct = Struct('cBhhhhhhBc')
-               flagInteger = getIntegerFlagFromCharacterSplitLine('X', splitLine )
-               flagInteger += 2 * getIntegerFlagFromCharacterSplitLine('Y', splitLine )
-               flagInteger += 4 * getIntegerFlagFromCharacterSplitLine('Z', splitLine )
-               flagInteger += 8 * getIntegerFlagFromCharacterSplitLine('I', splitLine )
-               flagInteger += 16 * getIntegerFlagFromCharacterSplitLine('J', splitLine )
-               flagInteger += 32 * getIntegerFlagFromCharacterSplitLine('F', splitLine )
-               packedString = sixteenByteStruct.pack( firstLetter, int( firstWord[1 :] ), xInteger, yInteger, zInteger, iInteger, jInteger, feedRateInteger, flagInteger, '#')
-               self.output.write( packedString )
-
-
-def main():
-       "Display the export dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/gcode_step.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/gcode_step.py
deleted file mode 100644 (file)
index a94bb57..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-"""
-This page is in the table of contents.
-Gcode step is an export plugin to convert gcode from float position to number of steps.
-
-An export plugin is a script in the export_plugins folder which has the getOutput function, the globalIsReplaceable variable and if it's output is not replaceable, the writeOutput function.  It is meant to be run from the export tool.  To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.
-
-The getOutput function of this script takes a gcode text and returns it with the positions converted into number of steps.  The writeOutput function of this script takes a gcode text and writes that with the positions converted into number of steps.
-
-==Settings==
-===Add Feed Rate Even When Unchanging===
-Default is on.
-
-When selected, the feed rate will be added even when it did not change from the previous line.
-
-===Add Space Between Words===
-Default is on.
-
-When selected, a space will be added between each gcode word.
-
-===Add Z Even When Unchanging===
-Default is on.
-
-When selected, the z word will be added even when it did not change.
-
-===Feed Rate Step Length===
-Default is 0.1 millimeters/second.
-
-Defines the feed rate step length.
-
-===Offset===
-====X Offset====
-Default is zero.
-
-Defines the X Offset.
-
-====Y Offset====
-Default is zero.
-
-Defines the Y Offset.
-
-====Z Offset====
-Default is zero.
-
-Defines the Z Offset.
-
-===Step Length===
-====E Step Length====
-Default is 0.1 millimeters.
-
-Defines the E extrusion distance step length.
-
-===Radius Rate Step Length===
-Default is 0.1 millimeters/second.
-
-Defines the radius step length.
-
-====X Step Length====
-Default is 0.1 millimeters.
-
-Defines the X axis step length.
-
-====Y Step Length====
-Default is 0.1 millimeters.
-
-Defines the Y axis step length.
-
-====Z Step Length====
-Default is 0.01 millimeters.
-
-Defines the Z axis step length.
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import cStringIO
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-# This is true if the output is text and false if it is binary.
-globalIsReplaceable = True
-
-
-def getCharacterIntegerString(character, offset, splitLine, stepLength):
-       'Get a character and integer string.'
-       floatValue = getFloatFromCharacterSplitLine(character, splitLine)
-       if floatValue == None:
-               return ''
-       floatValue += offset
-       integerValue = int(round(float(floatValue / stepLength)))
-       return character + str(integerValue)
-
-def getFloatFromCharacterSplitLine(character, splitLine):
-       'Get the float after the first occurence of the character in the split line.'
-       lineFromCharacter = gcodec.getStringFromCharacterSplitLine(character, splitLine)
-       if lineFromCharacter == None:
-               return None
-       return float(lineFromCharacter)
-
-def getNewRepository():
-       'Get new repository.'
-       return GcodeStepRepository()
-
-def getOutput(gcodeText, repository=None):
-       'Get the exported version of a gcode file.'
-       if gcodeText == '':
-               return ''
-       if repository == None:
-               repository = GcodeStepRepository()
-               settings.getReadRepository(repository)
-       return GcodeStepSkein().getCraftedGcode(repository, gcodeText)
-
-def writeOutput( fileName, gcodeText = ''):
-       'Write the exported version of a gcode file.'
-       gcodeText = gcodec.getGcodeFileText(fileName, gcodeText)
-       repository = GcodeStepRepository()
-       settings.getReadRepository(repository)
-       output = getOutput(gcodeText, repository)
-       suffixFileName = fileName[: fileName.rfind('.')] + '_gcode_step.gcode'
-       archive.writeFileText(suffixFileName, output)
-       print('The converted file is saved as ' + archive.getSummarizedFileName(suffixFileName))
-
-
-class GcodeStepRepository(object):
-       'A class to handle the export settings.'
-       def __init__(self):
-               'Set the default settings, execute title & settings fileName.'
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.gcode_step.html', self)
-               self.addFeedRateEvenWhenUnchanging = settings.BooleanSetting().getFromValue('Add Feed Rate Even When Unchanging', self, True)
-               self.addSpaceBetweenWords = settings.BooleanSetting().getFromValue('Add Space Between Words', self, True)
-               self.addZEvenWhenUnchanging = settings.BooleanSetting().getFromValue('Add Z Even When Unchanging', self, True)
-               self.fileNameInput = settings.FileNameInput().getFromFileName([('Gcode text files', '*.gcode')], 'Open File to be Converted to Gcode Step', self, '')
-               self.feedRateStepLength = settings.FloatSpin().getFromValue(0.0, 'Feed Rate Step Length (millimeters/second)', self, 1.0, 0.1)
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Offset -', self )
-               self.xOffset = settings.FloatSpin().getFromValue(-100.0, 'X Offset (millimeters)', self, 100.0, 0.0)
-               self.yOffset = settings.FloatSpin().getFromValue(-100.0, 'Y Offset (millimeters)', self, 100.0, 0.0)
-               self.zOffset = settings.FloatSpin().getFromValue(-10.0, 'Z Offset (millimeters)', self, 10.0, 0.0)
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Step Length -', self )
-               self.eStepLength = settings.FloatSpin().getFromValue(0.0, 'E Step Length (float)', self, 1.0, 0.1)
-               self.radiusStepLength = settings.FloatSpin().getFromValue(0.0, 'Radius Step Length (millimeters)', self, 1.0, 0.1)
-               self.xStepLength = settings.FloatSpin().getFromValue(0.0, 'X Step Length (millimeters)', self, 1.0, 0.1)
-               self.yStepLength = settings.FloatSpin().getFromValue(0.0, 'Y Step Length (millimeters)', self, 1.0, 0.1)
-               self.zStepLength = settings.FloatSpin().getFromValue(0.0, 'Z Step Length (millimeters)', self, 0.2, 0.01)
-               self.executeTitle = 'Convert to Gcode Step'
-
-       def execute(self):
-               'Convert to gcode step button has been clicked.'
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, ['.gcode'], self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class GcodeStepSkein(object):
-       'A class to convert gcode into 16 byte binary segments.'
-       def __init__(self):
-               self.oldFeedRateString = None
-               self.oldZString = None
-               self.output = cStringIO.StringIO()
-
-       def addCharacterInteger(self, character, lineStringIO, offset, splitLine, stepLength):
-               'Add a character and integer to line string.'
-               characterIntegerString = getCharacterIntegerString(character, offset, splitLine, stepLength)
-               self.addStringToLine(lineStringIO, characterIntegerString)
-
-       def addLine(self, line):
-               'Add a line of text and a newline to the output.'
-               self.output.write(line + '\n')
-
-       def addStringToLine(self, lineStringIO, wordString):
-               'Add a character and integer to line string.'
-               if wordString == '':
-                       return
-               if self.repository.addSpaceBetweenWords.value:
-                       lineStringIO.write(' ')
-               lineStringIO.write(wordString)
-
-       def getCraftedGcode(self, repository, gcodeText):
-               'Parse gcode text and store the gcode.'
-               self.repository = repository
-               lines = archive.getTextLines(gcodeText)
-               for line in lines:
-                       self.parseLine(line)
-               return self.output.getvalue()
-
-       def parseLine(self, line):
-               'Parse a gcode line.'
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               firstWord = gcodec.getFirstWord(splitLine)
-               if len(firstWord) < 1:
-                       return
-               firstLetter = firstWord[0]
-               if firstLetter == '(':
-                       return
-               if firstWord != 'G1' and firstWord != 'G2' and firstWord != 'G3':
-                       self.addLine(line)
-                       return
-               lineStringIO = cStringIO.StringIO()
-               lineStringIO.write(firstWord)
-               self.addCharacterInteger('I', lineStringIO, 0.0, splitLine, self.repository.xStepLength.value)
-               self.addCharacterInteger('J', lineStringIO, 0.0, splitLine, self.repository.yStepLength.value)
-               self.addCharacterInteger('R', lineStringIO, 0.0, splitLine, self.repository.radiusStepLength.value)
-               self.addCharacterInteger('X', lineStringIO, self.repository.xOffset.value, splitLine, self.repository.xStepLength.value)
-               self.addCharacterInteger('Y', lineStringIO, self.repository.yOffset.value, splitLine, self.repository.yStepLength.value)
-               zString = getCharacterIntegerString('Z', self.repository.zOffset.value, splitLine, self.repository.zStepLength.value)
-               feedRateString = getCharacterIntegerString('F', 0.0, splitLine, self.repository.feedRateStepLength.value)
-               if zString != '':
-                       if zString != self.oldZString or self.repository.addZEvenWhenUnchanging.value:
-                               self.addStringToLine(lineStringIO, zString)
-               if feedRateString != '':
-                       if feedRateString != self.oldFeedRateString or self.repository.addFeedRateEvenWhenUnchanging.value:
-                               self.addStringToLine(lineStringIO, feedRateString)
-               self.addCharacterInteger('E', lineStringIO, 0.0, splitLine, self.repository.eStepLength.value)
-               self.addLine(lineStringIO.getvalue())
-               self.oldFeedRateString = feedRateString
-               self.oldZString = zString
-
-
-def main():
-       'Display the export dialog.'
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == '__main__':
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/gcode_time_segment.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/gcode_time_segment.py
deleted file mode 100644 (file)
index 99c74f4..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-"""
-This page is in the table of contents.
-Gcode time segment is an export plugin to convert gcode from float position to number of steps.
-
-An export plugin is a script in the export_plugins folder which has the getOutput function, the globalIsReplaceable variable and if it's output is not replaceable, the writeOutput function.  It is meant to be run from the export tool.  To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.
-
-The getOutput function of this script takes a gcode text and returns it with the positions converted into number of steps and time.  The writeOutput function of this script takes a gcode text and writes that with the positions converted into number of steps and time.
-
-==Settings==
-===Add Space Between Words===
-Default is on.
-
-When selected, a space will be added between each gcode word.
-
-===Offset===
-====X Offset====
-Default is zero.
-
-Defines the X Offset.
-
-====Y Offset====
-Default is zero.
-
-Defines the Y Offset.
-
-====Z Offset====
-Default is zero.
-
-Defines the Z Offset.
-
-===Step===
-===Extrusion Step===
-Default is 0.01 mm.
-
-Defines the radius step length.
-
-===Time Step===
-Default is 1 microsecond(mcs).
-
-Defines the time step duration.
-
-====X Step====
-Default is 0.1 mm.
-
-Defines the X axis step length.
-
-====Y Step====
-Default is 0.1 mm.
-
-Defines the Y axis step length.
-
-====Z Step====
-Default is 0.01 mm.
-
-Defines the Z axis step length.
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import cStringIO
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-# This is true if the output is text and false if it is binary."
-globalIsReplaceable = True
-
-
-def getCharacterIntegerString( character, offset, splitLine, step ):
-       "Get a character and integer string."
-       floatValue = getFloatFromCharacterSplitLine(character, splitLine)
-       if floatValue == None:
-               return None
-       floatValue += offset
-       integerValue = int(round(float(floatValue / step)))
-       return character + str( integerValue )
-
-def getFloatFromCharacterSplitLine(character, splitLine):
-       "Get the float after the first occurence of the character in the split line."
-       lineFromCharacter = gcodec.getStringFromCharacterSplitLine(character, splitLine)
-       if lineFromCharacter == None:
-               return None
-       return float(lineFromCharacter)
-
-def getNewRepository():
-       'Get new repository.'
-       return GcodeTimeSegmentRepository()
-
-def getOutput(gcodeText, repository=None):
-       'Get the exported version of a gcode file.'
-       if gcodeText == '':
-               return ''
-       if repository == None:
-               repository = GcodeTimeSegmentRepository()
-               settings.getReadRepository(repository)
-       return GcodeTimeSegmentSkein().getCraftedGcode(gcodeText, repository)
-
-def writeOutput( fileName, gcodeText = ''):
-       "Write the exported version of a gcode file."
-       gcodeText = gcodec.getGcodeFileText(fileName, gcodeText)
-       repository = GcodeTimeSegmentRepository()
-       settings.getReadRepository(repository)
-       output = getOutput(gcodeText, repository)
-       suffixFileName = fileName[ : fileName.rfind('.') ] + '_gcode_time_segment.gcode'
-       archive.writeFileText( suffixFileName, output )
-       print('The converted file is saved as ' + archive.getSummarizedFileName(suffixFileName) )
-
-
-class GcodeTimeSegmentRepository(object):
-       "A class to handle the export settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.gcode_time.html', self)
-               self.addSpaceBetweenWords = settings.BooleanSetting().getFromValue('Add Space Between Words', self, True )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( [ ('Gcode text files', '*.gcode') ], 'Open File to be Converted to Gcode Time', self, '')
-               self.initialTime = settings.FloatSpin().getFromValue(0.0, 'Initial Time (s)', self, 20.0, 10.0)
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Offset -', self )
-               self.xOffset = settings.FloatSpin().getFromValue( - 100.0, 'X Offset (mm)', self, 100.0, 0.0 )
-               self.yOffset = settings.FloatSpin().getFromValue( -100.0, 'Y Offset (mm)', self, 100.0, 0.0 )
-               self.zOffset = settings.FloatSpin().getFromValue( - 10.0, 'Z Offset (mm)', self, 10.0, 0.0 )
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Step -', self )
-               self.extrusionStep = settings.FloatSpin().getFromValue(0.0, 'Extrusion Step (mm)', self, 0.2, 0.01)
-               self.timeStep = settings.FloatSpin().getFromValue(0.0, 'Time Step (mcs)', self, 2000.0, 1000.0)
-               self.xStep = settings.FloatSpin().getFromValue(0.0, 'X Step (mm)', self, 1.0, 0.1)
-               self.yStep = settings.FloatSpin().getFromValue(0.0, 'Y Step (mm)', self, 1.0, 0.1)
-               self.zStep = settings.FloatSpin().getFromValue(0.0, 'Z Step (mm)', self, 0.2, 0.01)
-               settings.LabelSeparator().getFromRepository(self)
-               self.executeTitle = 'Convert to Gcode Time'
-
-       def execute(self):
-               "Convert to gcode step button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode( self.fileNameInput.value, ['.gcode'], self.fileNameInput.wasCancelled )
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class GcodeTimeSegmentSkein(object):
-       "A class to convert gcode into time segments."
-       def __init__(self):
-               'Initialize.'
-               self.feedRateMinute = None
-               self.isExtruderActive = False
-               self.oldFeedRateString = None
-               self.oldLocation = None
-               self.oldZString = None
-               self.operatingFlowRate = None
-               self.output = cStringIO.StringIO()
-
-       def addCharacterInteger(self, character, lineStringIO, offset, splitLine, step):
-               "Add a character and integer to line string."
-               characterIntegerString = getCharacterIntegerString(character, offset, splitLine, step)
-               self.addStringToLine(lineStringIO, characterIntegerString)
-
-       def addLine(self, line):
-               "Add a line of text and a newline to the output."
-               self.output.write(line + '\n')
-
-       def addStringToLine( self, lineStringIO, wordString ):
-               "Add a character and integer to line string."
-               if wordString == None:
-                       return
-               if self.repository.addSpaceBetweenWords.value:
-                       lineStringIO.write(' ')
-               lineStringIO.write( wordString )
-
-       def getCraftedGcode(self, gcodeText, repository):
-               "Parse gcode text and store the gcode."
-               self.repository = repository
-               lines = archive.getTextLines(gcodeText)
-               for line in lines:
-                       self.parseLine(line)
-               return self.output.getvalue()
-
-       def parseLine(self, line):
-               "Parse a gcode line."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               firstWord = gcodec.getFirstWord(splitLine)
-               if len(firstWord) < 1:
-                       return
-               firstLetter = firstWord[0]
-               if firstWord == '(<operatingFeedRatePerSecond>':
-                       self.feedRateMinute = 60.0 * float(splitLine[1])
-               elif firstWord == '(<operatingFlowRate>':
-                       self.operatingFlowRate = float(splitLine[1])
-                       self.flowRate = self.operatingFlowRate
-               if firstLetter == '(':
-                       return
-               if firstWord == 'M101':
-                       self.isExtruderActive = True
-               elif firstWord == 'M103':
-                       self.isExtruderActive = False
-               elif firstWord == 'M108':
-                       self.flowRate = float(splitLine[1][1 :])
-               if firstWord != 'G1' and firstWord != 'G2' and firstWord != 'G3':
-                       self.addLine(line)
-                       return
-               self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine)
-               lineStringIO = cStringIO.StringIO()
-               lineStringIO.write(firstWord)
-               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               self.addCharacterInteger('X', lineStringIO, self.repository.xOffset.value, splitLine, self.repository.xStep.value )
-               self.addCharacterInteger('Y', lineStringIO, self.repository.yOffset.value, splitLine, self.repository.yStep.value )
-               zString = getCharacterIntegerString('Z', self.repository.zOffset.value, splitLine, self.repository.zStep.value )
-               if zString == None:
-                       zString = self.oldZString
-               self.addStringToLine(lineStringIO, zString)
-               duration = self.repository.initialTime.value
-               if self.oldLocation != None:
-                       distance = abs(location - self.oldLocation)
-                       duration = 60.0 / self.feedRateMinute * distance
-               extrusionDistance = 0.0
-               if self.isExtruderActive:
-                       extrusionDistance = self.flowRate * duration
-               self.addStringToLine(lineStringIO, 'E%s' % int(round(extrusionDistance / self.repository.extrusionStep.value)))
-               self.addStringToLine(lineStringIO, 'D%s' % int(round(duration * 1000000.0 / self.repository.timeStep.value)))
-               self.addLine(lineStringIO.getvalue())
-               self.oldLocation = location
-               self.oldZString = zString
-
-
-def main():
-       "Display the export dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/static_plugins/__init__.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/static_plugins/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/static_plugins/gcode_small.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/static_plugins/gcode_small.py
deleted file mode 100644 (file)
index b55e52d..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-"""
-This page is in the table of contents.
-Gcode_small is an export plugin to remove the comments and the redundant z and feed rate parameters from a gcode file.
-
-An export plugin is a script in the export_plugins folder which has the getOutput function, the globalIsReplaceable variable and if it's output is not replaceable, the writeOutput function.  It is meant to be run from the export tool.  To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.
-
-The getOutput function of this script takes a gcode text and returns that text without comments and redundant z and feed rate parameters.  The writeOutput function of this script takes a gcode text and writes that text without comments and redundant z and feed rate parameters to a file.
-
-Many of the functions in this script are copied from gcodec in skeinforge_utilities.  They are copied rather than imported so developers making new plugins do not have to learn about gcodec, the code here is all they need to learn.
-
-"""
-
-from __future__ import absolute_import
-import cStringIO
-import os
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-# This is true if the output is text and false if it is binary."
-globalIsReplaceable = True
-
-
-def getIndexOfStartingWithSecond(letter, splitLine):
-       "Get index of the first occurence of the given letter in the split line, starting with the second word.  Return - 1 if letter is not found"
-       for wordIndex in xrange( 1, len(splitLine) ):
-               word = splitLine[ wordIndex ]
-               firstLetter = word[0]
-               if firstLetter == letter:
-                       return wordIndex
-       return - 1
-
-def getOutput(gcodeText):
-       'Get the exported version of a gcode file.'
-       return GcodeSmallSkein().getCraftedGcode(gcodeText)
-
-def getSplitLineBeforeBracketSemicolon(line):
-       "Get the split line before a bracket or semicolon."
-       bracketSemicolonIndex = min( line.find(';'), line.find('(') )
-       if bracketSemicolonIndex < 0:
-               return line.split()
-       return line[ : bracketSemicolonIndex ].split()
-
-def getStringFromCharacterSplitLine(character, splitLine):
-       "Get the string after the first occurence of the character in the split line."
-       indexOfCharacter = getIndexOfStartingWithSecond(character, splitLine)
-       if indexOfCharacter < 0:
-               return None
-       return splitLine[indexOfCharacter][1 :]
-
-def getSummarizedFileName(fileName):
-       "Get the fileName basename if the file is in the current working directory, otherwise return the original full name."
-       if os.getcwd() == os.path.dirname(fileName):
-               return os.path.basename(fileName)
-       return fileName
-
-def getTextLines(text):
-       "Get the all the lines of text of a text."
-       return text.replace('\r', '\n').split('\n')
-
-
-class GcodeSmallSkein(object):
-       "A class to remove redundant z and feed rate parameters from a skein of extrusions."
-       def __init__(self):
-               self.lastFeedRateString = None
-               self.lastZString = None
-               self.output = cStringIO.StringIO()
-               self.layerNr = 0
-               self.parsingAlteration = False
-
-       def getCraftedGcode( self, gcodeText ):
-               "Parse gcode text and store the gcode."
-               lines = getTextLines(gcodeText)
-               for line in lines:
-                       self.parseLine(line)
-               return self.output.getvalue()
-
-       def parseLine(self, line):
-               "Parse a gcode line."
-               if len(line) < 1:
-                       return
-               if line[0] == '(':
-                       self.parseComment(line)
-                       return
-               splitLine = getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if len(firstWord) < 1:
-                       return
-               if firstWord[0] == '(':
-                       return
-               if firstWord == 'M108' or firstWord == 'M113':
-                       return
-               if firstWord != 'G1':
-                       self.output.write(line + '\n')
-                       return
-               eString = getStringFromCharacterSplitLine('E', splitLine )
-               xString = getStringFromCharacterSplitLine('X', splitLine )
-               yString = getStringFromCharacterSplitLine('Y', splitLine )
-               zString = getStringFromCharacterSplitLine('Z', splitLine )
-               feedRateString = getStringFromCharacterSplitLine('F', splitLine )
-               self.output.write('G1')
-               if xString != None:
-                       self.output.write(' X' + xString )
-               if yString != None:
-                       self.output.write(' Y' + yString )
-               if zString != None and zString != self.lastZString:
-                       self.output.write(' Z' + zString )
-               if feedRateString != None and feedRateString != self.lastFeedRateString:
-                       self.output.write(' F' + feedRateString )
-               if eString != None:
-                       self.output.write(' E' + eString )
-               self.lastFeedRateString = feedRateString
-               self.lastZString = zString
-               self.output.write('\n')
-       
-       def parseComment(self, line):
-               if line.startswith('(<skirt>'):
-                       self.output.write(';TYPE:SKIRT\n');
-               elif line.startswith('(<edge>'):
-                       self.output.write(';TYPE:WALL-OUTER\n');
-               elif line.startswith('(<loop>'):
-                       self.output.write(';TYPE:WALL-INNER\n');
-               elif line.startswith('(<infill>'):
-                       self.output.write(';TYPE:FILL\n');
-               elif line.startswith('(<alteration>'):
-                       self.output.write(';TYPE:CUSTOM\n');
-                       self.parsingAlteration = True
-               elif line.startswith('(</alteration>)'):
-                       self.parsingAlteration = False
-               elif line.startswith('(<supportLayer>'):
-                       self.output.write(';TYPE:SUPPORT\n');
-               elif line.startswith('(<layer>'):
-                       self.output.write(';LAYER:%d\n' % (self.layerNr));
-                       self.layerNr += 1
-
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/feed.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/feed.py
deleted file mode 100644 (file)
index fb1a1ab..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-"""
-This page is in the table of contents.
-The feed script sets the maximum feed rate, operating feed rate & travel feed rate.
-
-==Operation==
-The default 'Activate Feed' checkbox is on.  When it is on, the functions described below will work, when it is off, the functions will not be called.
-
-==Settings==
-===Feed Rate===
-Default is 16 millimeters/second.
-
-Defines the feed rate for the shape.
-
-===Maximum Z Drill Feed Rate===
-Default is 0.1 millimeters/second.
-
-If your firmware limits the z feed rate, you do not need to set this setting.
-
-Defines the maximum feed that the tool head will move in the z direction while the tool is on.
-
-===Maximum Z Feed Rate===
-Default is one millimeter per second.
-
-Defines the maximum speed that the tool head will move in the z direction.
-
-===Travel Feed Rate===
-Default is 16 millimeters/second.
-
-Defines the feed rate when the cutter is off.  The travel feed rate could be set as high as the cutter can be moved, it does not have to be limited by the maximum cutter rate.
-
-==Examples==
-The following examples feed the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and feed.py.
-
-> python feed.py
-This brings up the feed dialog.
-
-> python feed.py Screw Holder Bottom.stl
-The feed tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The feed tool has created the file:
-.. Screw Holder Bottom_feed.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText(fileName, gcodeText='', repository=None):
-       "Feed the file or text."
-       return getCraftedTextFromText( archive.getTextIfEmpty( fileName, gcodeText ), repository )
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       "Feed a gcode linear move text."
-       if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'feed'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository(FeedRepository())
-       if not repository.activateFeed.value:
-               return gcodeText
-       return FeedSkein().getCraftedGcode(gcodeText, repository)
-
-def getNewRepository():
-       'Get new repository.'
-       return FeedRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Feed a gcode linear move file."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'feed', shouldAnalyze)
-
-class FeedRepository(object):
-       "A class to handle the feed settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.feed.html', self)
-               self.fileNameInput = settings.FileNameInput().getFromFileName(fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Feed', self, '')
-               self.activateFeed = settings.BooleanSetting().getFromValue('Activate Feed', self, True)
-               self.feedRatePerSecond = settings.FloatSpin().getFromValue(2.0, 'Feed Rate (mm/s):', self, 50.0, 16.0)
-               self.maximumZDrillFeedRatePerSecond = settings.FloatSpin().getFromValue(0.02, 'Maximum Z Drill Feed Rate (mm/s):', self, 0.5, 0.1)
-               self.maximumZFeedRatePerSecond = settings.FloatSpin().getFromValue(0.5, 'Maximum Z Feed Rate (mm/s):', self, 10.0, 1.0)
-               self.travelFeedRatePerSecond = settings.FloatSpin().getFromValue(2.0, 'Travel Feed Rate (mm/s):', self, 50.0, 16.0)
-               self.executeTitle = 'Feed'
-
-       def execute(self):
-               "Feed button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class FeedSkein(object):
-       "A class to feed a skein of cuttings."
-       def __init__(self):
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.feedRatePerSecond = 16.0
-               self.isExtruderActive = False
-               self.lineIndex = 0
-               self.lines = None
-               self.oldFlowrateString = None
-               self.oldLocation = None
-
-       def getCraftedGcode(self, gcodeText, repository):
-               "Parse gcode text and store the feed gcode."
-               self.repository = repository
-               self.feedRatePerSecond = repository.feedRatePerSecond.value
-               self.travelFeedRateMinute = 60.0 * self.repository.travelFeedRatePerSecond.value
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization()
-               for line in self.lines[self.lineIndex :]:
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def getFeededLine(self, line, splitLine):
-               "Get gcode line with feed rate."
-               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               self.oldLocation = location
-               feedRateMinute = 60.0 * self.feedRatePerSecond
-               if not self.isExtruderActive:
-                       feedRateMinute = self.travelFeedRateMinute
-               return self.distanceFeedRate.getLineWithFeedRate(feedRateMinute, line, splitLine)
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('feed')
-                               return
-                       elif firstWord == '(<edgeWidth>':
-                               self.absoluteEdgeWidth = abs(float(splitLine[1]))
-                               self.distanceFeedRate.addTagBracketedLine('maximumZDrillFeedRatePerSecond', self.repository.maximumZDrillFeedRatePerSecond.value)
-                               self.distanceFeedRate.addTagBracketedLine('maximumZFeedRatePerSecond', self.repository.maximumZFeedRatePerSecond.value )
-                               self.distanceFeedRate.addTagBracketedLine('operatingFeedRatePerSecond', self.feedRatePerSecond)
-                               self.distanceFeedRate.addTagBracketedLine('travelFeedRatePerSecond', self.repository.travelFeedRatePerSecond.value)
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               "Parse a gcode line and add it to the feed skein."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       line = self.getFeededLine(line, splitLine)
-               elif firstWord == 'M101':
-                       self.isExtruderActive = True
-               elif firstWord == 'M103':
-                       self.isExtruderActive = False
-               self.distanceFeedRate.addLine(line)
-
-
-def main():
-       'Display the feed dialog.'
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/fill.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/fill.py
deleted file mode 100644 (file)
index 9d71753..0000000
+++ /dev/null
@@ -1,1380 +0,0 @@
-#! /usr/bin/env python
-"""
-This page is in the table of contents.
-Fill is a script to fill the edges of a gcode file.
-
-The fill manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Fill
-
-Allan Ecker aka The Masked Retriever has written the "Skeinforge Quicktip: Fill" at:
-http://blog.thingiverse.com/2009/07/21/mysteries-of-skeinforge-fill/
-
-==Operation==
-The default 'Activate Fill' checkbox is off.  When it is on, the functions described below will work, when it is off, the functions will not be called.
-
-==Settings==
-===Diaphragm===
-The diaphragm is a solid group of layers, at regular intervals.  It can be used with a sparse infill to give the object watertight, horizontal compartments and/or a higher shear strength.
-
-====Diaphragm Period====
-Default is one hundred.
-
-Defines the number of layers between diaphrams.
-
-====Diaphragm Thickness====
-Default is zero, because the diaphragm feature is rarely used.
-
-Defines the number of layers the diaphram is composed of.
-
-===Extra Shells===
-The shells interior edge loops.  Adding extra shells makes the object stronger & heavier.
-
-====Extra Shells on Alternating Solid Layers====
-Default is two.
-
-Defines the number of extra shells, on the alternating solid layers.
-
-====Extra Shells on Base====
-Default is one.
-
-Defines the number of extra shells on the bottom, base layer and every even solid layer after that.  Setting this to a different value than the "Extra Shells on Alternating Solid Layers" means the infill pattern will alternate, creating a strong interleaved bond even if the edge loop shrinks.
-
-====Extra Shells on Sparse Layer====
-Default is one.
-
-Defines the number of extra shells on the sparse layers.  The solid layers are those at the top & bottom, and wherever the object has a plateau or overhang, the sparse layers are the layers in between.
-
-===Grid===
-====Grid Circle Separation over Perimeter Width====
-Default is 0.2.
-
-Defines the ratio of the amount the grid circle is inset over the edge width, the default is zero.  With a value of zero the circles will touch, with a value of one two threads could be fitted between the circles.
-
-====Grid Extra Overlap====
-Default is 0.1.
-
-Defines the amount of extra overlap added when extruding the grid to compensate for the fact that when the first thread going through a grid point is extruded, since there is nothing there yet for it to connect to it will shrink extra.
-
-====Grid Junction Separation over Octogon Radius At End====
-Default is zero.
-
-Defines the ratio of the amount the grid square is increased in each direction over the extrusion width at the end.  With a value of one or so the grid pattern will have large squares to go with the octogons.
-
-====Grid Junction Separation over Octogon Radius At Middle====
-Default is zero.
-
-Defines the increase at the middle.  If this value is different than the value at the end, the grid would have an accordion pattern, which would give it a higher shear strength.
-
-====Grid Junction Separation Band Height====
-Default is ten.
-
-Defines the height of the bands of the accordion pattern.
-
-===Infill===
-====Infill Pattern====
-Default is 'Line', since it is quicker to generate and does not add extra movements for the extruder.  The grid pattern has extra diagonal lines, so when choosing a grid option, set the infill solidity to 0.2 or less so that there is not too much plastic and the grid generation time, which increases with the third power of solidity, will be reasonable.
-
-=====Grid Circular=====
-When selected, the infill will be a grid of separated circles.  Because the circles are separated, the pattern is weak, it only provides support for the top layer threads and some strength in the z direction.  The flip side is that this infill does not warp the object, the object will get warped only by the walls.
-
-Because this pattern turns the extruder on and off often, it is best to use a stepper motor extruder.
-
-=====Grid Hexagonal=====
-When selected, the infill will be a hexagonal grid.  Because the grid is made with threads rather than with molding or milling, only a partial hexagon is possible, so the rectangular grid pattern is stronger.
-
-=====Grid Rectangular=====
-When selected, the infill will be a funky octogon square honeycomb like pattern which gives the object extra strength.
-
-=====Line=====
-When selected, the infill will be made up of lines.
-
-====Infill Begin Rotation====
-Default is forty five degrees, giving a diagonal infill.
-
-Defines the amount the infill direction of the base and every second layer thereafter is rotated.
-
-====Infill Odd Layer Extra Rotation====
-Default is ninety degrees, making the odd layer infill perpendicular to the base layer.
-
-Defines the extra amount the infill direction of the odd layers is rotated compared to the base layer.
-
-====Infill Begin Rotation Repeat====
-Default is one, giving alternating cross hatching.
-
-Defines the number of layers that the infill begin rotation will repeat.  With a value higher than one, the infill will go in one direction more often, giving the object more strength in one direction and less in the other, this is useful for beams and cantilevers.
-
-====Infill Perimeter Overlap====
-Default is 0.15.
-
-Defines the amount the infill overlaps the edge over the average of the edge and infill width.  The higher the value the more the infill will overlap the edge, and the thicker join between the infill and the edge.  If the value is too high, the join will be so thick that the nozzle will run plow through the join below making a mess, also when it is above 0.45 fill may not be able to create infill correctly.  If you want to stretch the infill a lot, set 'Path Stretch over Perimeter Width' in stretch to a high value.
-
-====Infill Solidity====
-Default is 0.2.
-
-Defines the solidity of the infill, this is the most important setting in fill.  A value of one means the infill lines will be right beside each other, resulting in a solid, strong, heavy shape which takes a long time to extrude.  A low value means the infill will be sparse, the interior will be mosty empty space, the object will be weak, light and quick to build.
-
-====Infill Width over Thickness====
-Default is 1.5.
-
-Defines the ratio of the infill width over the layer height.  The higher the value the wider apart the infill will be and therefore the sparser the infill will be.
-
-===Sharpest Angle===
-Default: 60 degrees
-
-Defines the sharpest angle that a thread is allowed to make before it is separated into two threads. If 'Sharpest Angle' is too low, the extruder will stop and start often, slowing printing and putting more wear and tear on the extruder. If 'Sharpest Angle' is too high, then threads will almost double back on themselves, leading to bumps in the fill, and sometimes filament being dragged by the nozzle.
-
-This parameter is used in fill, raft and skin.
-
-===Solid Surface Thickness===
-Default is three.
-
-Defines the number of solid layers that are at the bottom, top, plateaus and overhang.  With a value of zero, the entire object will be composed of a sparse infill, and water could flow right through it.  With a value of one, water will leak slowly through the surface and with a value of three, the object could be watertight.  The higher the solid surface thickness, the stronger and heavier the object will be.
-
-===Start From Choice===
-Default is 'Lower Left'.
-
-Defines where each layer starts from.
-
-====Lower Left====
-When selected the layer will start from the lower left corner.  This is to extrude in round robin fashion so that the first extrusion will be deposited on the coolest part of the last layer.  The reason for this is described at:
-http://hydraraptor.blogspot.com/2010/12/round-robin.html
-
-====Nearest====
-When selected the layer will start from the closest point to the end of the last layer.  This leads to less stringing, but the first extrusion will be deposited on the hottest part of the last layer which leads to melting problems.  So this option is deprecated, eventually this option will be removed and the layers will always start from the lower left.
-
-===Surrounding Angle===
-Default: 60 degrees
-
-Defines the angle that the surrounding layers around the infill are expanded.
-
-To decide whether or not the infill should be sparse or solid, fill looks at the 'Solid Surface Thickness' surrounding layers above and below the infill.  If any of the expanded layers above or below the infill do not cover the infill, then the infill will be solid in that region.  The layers are expanded by the height difference times the tangent of the surrounding angle, which is from the vertical.  For example, if the model is a wedge with a wall angle less than the surrounding angle, the interior layers (those which are not on the bottom or top) will be sparse.  If the wall angle is greater than the surrounding angle, the interior layers will be solid.
-
-The time required to examine the surrounding layers increases with the surrounding angle, so the surrounding angle is limited to eighty degrees, regardless of the input value.
-
-If you have an organic shape with gently sloping surfaces; if the surrounding angle is set too high, then too many layers will be sparse.  If the surrounding angle is too low, then too many layers will be solid and the extruder may end up plowing through previous layers:
-http://hydraraptor.blogspot.com/2008/08/bearing-fruit.html
-
-===Thread Sequence Choice===
-The 'Thread Sequence Choice' is the sequence in which the threads will be extruded on the second and higher layers.  There are three kinds of thread, the edge threads on the outside of the object, the loop threads aka inner shell threads, and the interior infill threads.  The first layer thread sequence is 'Perimeter > Loops > Infill'.
-
-The default choice is 'Perimeter > Loops > Infill', which the default stretch parameters are based on.  If you change from the default sequence choice setting of edge, then loops, then infill, the optimal stretch thread parameters would also be different.  In general, if the infill is extruded first, the infill would have to be stretched more so that even after the filament shrinkage, it would still be long enough to connect to the loop or edge.  The six sequence combinations follow below.
-
-====Infill > Loops > Perimeter====
-====Infill > Perimeter > Loops====
-====Loops > Infill > Perimeter====
-====Loops > Perimeter > Infill====
-====Perimeter > Infill > Loops====
-====Perimeter > Loops > Infill====
-
-==Examples==
-The following examples fill the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and fill.py.
-
-> python fill.py
-This brings up the fill dialog.
-
-> python fill.py Screw Holder Bottom.stl
-The fill tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The fill tool has created the file:
-.. Screw Holder Bottom_fill.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import intercircle
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import math
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/28/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-
-def addAroundGridPoint( arounds, gridPoint, gridPointInsetX, gridPointInsetY, gridPoints, gridSearchRadius, isBothOrNone, isDoubleJunction, isJunctionWide, paths, pixelTable, width ):
-       'Add the path around the grid point.'
-       closestPathIndex = None
-       aroundIntersectionPaths = []
-       for aroundIndex in xrange( len(arounds) ):
-               loop = arounds[ aroundIndex ]
-               for pointIndex in xrange(len(loop)):
-                       pointFirst = loop[pointIndex]
-                       pointSecond = loop[(pointIndex + 1) % len(loop)]
-                       yIntersection = euclidean.getYIntersectionIfExists( pointFirst, pointSecond, gridPoint.real )
-                       addYIntersectionPathToList( aroundIndex, pointIndex, gridPoint.imag, yIntersection, aroundIntersectionPaths )
-       if len( aroundIntersectionPaths ) < 2:
-               print('Warning, aroundIntersectionPaths is less than 2 in fill.')
-               print(aroundIntersectionPaths)
-               print(gridPoint)
-               return
-       yCloseToCenterArounds = getClosestOppositeIntersectionPaths(aroundIntersectionPaths)
-       if len(yCloseToCenterArounds) < 2:
-               return
-       segmentFirstY = min( yCloseToCenterArounds[0].y, yCloseToCenterArounds[1].y )
-       segmentSecondY = max( yCloseToCenterArounds[0].y, yCloseToCenterArounds[1].y )
-       yIntersectionPaths = []
-       gridPixel = euclidean.getStepKeyFromPoint( gridPoint / width )
-       segmentFirstPixel = euclidean.getStepKeyFromPoint( complex( gridPoint.real, segmentFirstY ) / width )
-       segmentSecondPixel = euclidean.getStepKeyFromPoint( complex( gridPoint.real, segmentSecondY ) / width )
-       pathIndexTable = {}
-       addPathIndexFirstSegment( gridPixel, pathIndexTable, pixelTable, segmentFirstPixel )
-       addPathIndexSecondSegment( gridPixel, pathIndexTable, pixelTable, segmentSecondPixel )
-       for pathIndex in pathIndexTable.keys():
-               path = paths[ pathIndex ]
-               for pointIndex in xrange( len(path) - 1 ):
-                       pointFirst = path[pointIndex]
-                       pointSecond = path[pointIndex + 1]
-                       yIntersection = getYIntersectionInsideYSegment( segmentFirstY, segmentSecondY, pointFirst, pointSecond, gridPoint.real )
-                       addYIntersectionPathToList( pathIndex, pointIndex, gridPoint.imag, yIntersection, yIntersectionPaths )
-       if len( yIntersectionPaths ) < 1:
-               return
-       yCloseToCenterPaths = []
-       if isDoubleJunction:
-               yCloseToCenterPaths = getClosestOppositeIntersectionPaths( yIntersectionPaths )
-       else:
-               yIntersectionPaths.sort( compareDistanceFromCenter )
-               yCloseToCenterPaths = [ yIntersectionPaths[0] ]
-       for yCloseToCenterPath in yCloseToCenterPaths:
-               setIsOutside( yCloseToCenterPath, aroundIntersectionPaths )
-       if len( yCloseToCenterPaths ) < 2:
-               yCloseToCenterPaths[0].gridPoint = gridPoint
-               insertGridPointPair( gridPoint, gridPointInsetX, gridPoints, isJunctionWide, paths, pixelTable, yCloseToCenterPaths[0], width )
-               return
-       plusMinusSign = getPlusMinusSign( yCloseToCenterPaths[1].y - yCloseToCenterPaths[0].y )
-       yCloseToCenterPaths[0].gridPoint = complex( gridPoint.real, gridPoint.imag - plusMinusSign * gridPointInsetY )
-       yCloseToCenterPaths[1].gridPoint = complex( gridPoint.real, gridPoint.imag + plusMinusSign * gridPointInsetY )
-       yCloseToCenterPaths.sort( comparePointIndexDescending )
-       insertGridPointPairs( gridPoint, gridPointInsetX, gridPoints, yCloseToCenterPaths[0], yCloseToCenterPaths[1], isBothOrNone, isJunctionWide, paths, pixelTable, width )
-
-def addInfillBoundary(infillBoundary, nestedRings):
-       'Add infill boundary to the nested ring that contains it.'
-       infillPoint = infillBoundary[0]
-       for nestedRing in nestedRings:
-               if euclidean.isPointInsideLoop(nestedRing.boundary, infillPoint):
-                       nestedRing.infillBoundaries.append(infillBoundary)
-                       return
-
-def addLoop(infillWidth, infillPaths, loop, rotationPlaneAngle):
-       'Add simplified path to fill.'
-       simplifiedLoop = euclidean.getSimplifiedLoop(loop, infillWidth)
-       if len(simplifiedLoop) < 2:
-               return
-       simplifiedLoop.append(simplifiedLoop[0])
-       planeRotated = euclidean.getRotatedComplexes(rotationPlaneAngle, simplifiedLoop)
-       infillPaths.append(planeRotated)
-
-def addPath(infillWidth, infillPaths, path, rotationPlaneAngle):
-       'Add simplified path to fill.'
-       simplifiedPath = euclidean.getSimplifiedPath(path, infillWidth)
-       if len(simplifiedPath) < 2:
-               return
-       planeRotated = euclidean.getRotatedComplexes(rotationPlaneAngle, simplifiedPath)
-       infillPaths.append(planeRotated)
-
-def addPathIndexFirstSegment( gridPixel, pathIndexTable, pixelTable, segmentFirstPixel ):
-       'Add the path index of the closest segment found toward the second segment.'
-       for yStep in xrange( gridPixel[1], segmentFirstPixel[1] - 1, - 1 ):
-               if getKeyIsInPixelTableAddValue( ( gridPixel[0], yStep ), pathIndexTable, pixelTable ):
-                       return
-
-def addPathIndexSecondSegment( gridPixel, pathIndexTable, pixelTable, segmentSecondPixel ):
-       'Add the path index of the closest segment found toward the second segment.'
-       for yStep in xrange( gridPixel[1], segmentSecondPixel[1] + 1 ):
-               if getKeyIsInPixelTableAddValue( ( gridPixel[0], yStep ), pathIndexTable, pixelTable ):
-                       return
-
-def addPointOnPath( path, pathIndex, pixelTable, point, pointIndex, width ):
-       'Add a point to a path and the pixel table.'
-       pointIndexMinusOne = pointIndex - 1
-       if pointIndex < len(path) and pointIndexMinusOne >= 0:
-               segmentTable = {}
-               begin = path[ pointIndexMinusOne ]
-               end = path[pointIndex]
-               euclidean.addValueSegmentToPixelTable( begin, end, segmentTable, pathIndex, width )
-               euclidean.removePixelTableFromPixelTable( segmentTable, pixelTable )
-       if pointIndexMinusOne >= 0:
-               begin = path[ pointIndexMinusOne ]
-               euclidean.addValueSegmentToPixelTable( begin, point, pixelTable, pathIndex, width )
-       if pointIndex < len(path):
-               end = path[pointIndex]
-               euclidean.addValueSegmentToPixelTable( point, end, pixelTable, pathIndex, width )
-       path.insert( pointIndex, point )
-
-def addPointOnPathIfFree( path, pathIndex, pixelTable, point, pointIndex, width ):
-       'Add the closest point to a path, if the point added to a path is free.'
-       if isAddedPointOnPathFree( path, pixelTable, point, pointIndex, width ):
-               addPointOnPath( path, pathIndex, pixelTable, point, pointIndex, width )
-
-def addSparseEndpoints(doubleInfillWidth, endpoints, horizontalSegmentsDictionary, horizontalSegmentsDictionaryKey, infillSolidity, removedEndpoints, solidSurfaceThickness, surroundingXIntersections):
-       'Add sparse endpoints.'
-       segments = horizontalSegmentsDictionary[horizontalSegmentsDictionaryKey]
-       for segment in segments:
-               addSparseEndpointsFromSegment(doubleInfillWidth, endpoints, horizontalSegmentsDictionary, horizontalSegmentsDictionaryKey, infillSolidity, removedEndpoints, segment, solidSurfaceThickness, surroundingXIntersections)
-
-def addSparseEndpointsFromSegment(doubleInfillWidth, endpoints, horizontalSegmentsDictionary, horizontalSegmentsDictionaryKey, infillSolidity, removedEndpoints, segment, solidSurfaceThickness, surroundingXIntersections):
-       'Add sparse endpoints from a segment.'
-       if infillSolidity > 0.0:
-               if int(round(round(float(horizontalSegmentsDictionaryKey) * infillSolidity) / infillSolidity)) == horizontalSegmentsDictionaryKey:
-                       endpoints += segment
-                       return
-               if abs(segment[0].point - segment[1].point) < doubleInfillWidth:
-                       endpoints += segment
-                       return
-               if not isSegmentAround(horizontalSegmentsDictionary, horizontalSegmentsDictionaryKey - 1, segment):
-                       endpoints += segment
-                       return
-               if not isSegmentAround(horizontalSegmentsDictionary, horizontalSegmentsDictionaryKey + 1, segment):
-                       endpoints += segment
-                       return
-       if solidSurfaceThickness == 0:
-               removedEndpoints += segment
-               return
-       if isSegmentCompletelyInAnIntersection(segment, surroundingXIntersections):
-               removedEndpoints += segment
-               return
-       endpoints += segment
-
-def addYIntersectionPathToList( pathIndex, pointIndex, y, yIntersection, yIntersectionPaths ):
-       'Add the y intersection path to the y intersection paths.'
-       if yIntersection == None:
-               return
-       yIntersectionPath = YIntersectionPath( pathIndex, pointIndex, yIntersection )
-       yIntersectionPath.yMinusCenter = yIntersection - y
-       yIntersectionPaths.append( yIntersectionPath )
-
-def compareDistanceFromCenter(self, other):
-       'Get comparison in order to sort y intersections in ascending order of distance from the center.'
-       distanceFromCenter = abs( self.yMinusCenter )
-       distanceFromCenterOther = abs( other.yMinusCenter )
-       if distanceFromCenter > distanceFromCenterOther:
-               return 1
-       if distanceFromCenter < distanceFromCenterOther:
-               return - 1
-       return 0
-
-def comparePointIndexDescending(self, other):
-       'Get comparison in order to sort y intersections in descending order of point index.'
-       if self.pointIndex > other.pointIndex:
-               return - 1
-       if self.pointIndex < other.pointIndex:
-               return 1
-       return 0
-
-def createExtraFillLoops(nestedRing, radius, radiusAround, shouldExtraLoopsBeAdded):
-       'Create extra fill loops.'
-       for innerNestedRing in nestedRing.innerNestedRings:
-               createFillForSurroundings(innerNestedRing.innerNestedRings, radius, radiusAround, shouldExtraLoopsBeAdded)
-       allFillLoops = intercircle.getInsetSeparateLoopsFromAroundLoops(nestedRing.getLoopsToBeFilled(), radius, max(1.4 * radius, radiusAround))
-       if len(allFillLoops) < 1:
-               return
-       if shouldExtraLoopsBeAdded:
-               nestedRing.extraLoops += allFillLoops
-               nestedRing.penultimateFillLoops = nestedRing.lastFillLoops
-       nestedRing.lastFillLoops = allFillLoops
-
-def createFillForSurroundings(nestedRings, radius, radiusAround, shouldExtraLoopsBeAdded):
-       'Create extra fill loops for nested rings.'
-       for nestedRing in nestedRings:
-               createExtraFillLoops(nestedRing, radius, radiusAround, shouldExtraLoopsBeAdded)
-
-def getAdditionalLength( path, point, pointIndex ):
-       'Get the additional length added by inserting a point into a path.'
-       if pointIndex == 0:
-               return abs( point - path[0] )
-       if pointIndex == len(path):
-               return abs( point - path[-1] )
-       return abs( point - path[pointIndex - 1] ) + abs( point - path[pointIndex] ) - abs( path[pointIndex] - path[pointIndex - 1] )
-
-def getClosestOppositeIntersectionPaths( yIntersectionPaths ):
-       'Get the close to center paths, starting with the first and an additional opposite if it exists.'
-       yIntersectionPaths.sort( compareDistanceFromCenter )
-       beforeFirst = yIntersectionPaths[0].yMinusCenter < 0.0
-       yCloseToCenterPaths = [ yIntersectionPaths[0] ]
-       for yIntersectionPath in yIntersectionPaths[1 :]:
-               beforeSecond = yIntersectionPath.yMinusCenter < 0.0
-               if beforeFirst != beforeSecond:
-                       yCloseToCenterPaths.append( yIntersectionPath )
-                       return yCloseToCenterPaths
-       return yCloseToCenterPaths
-
-def getCraftedText( fileName, gcodeText = '', repository=None):
-       'Fill the inset file or gcode text.'
-       return getCraftedTextFromText( archive.getTextIfEmpty(fileName, gcodeText), repository )
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       'Fill the inset gcode text.'
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'fill'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository( FillRepository() )
-       if not repository.activateFill.value:
-               return gcodeText
-       return FillSkein().getCraftedGcode( repository, gcodeText )
-
-def getKeyIsInPixelTableAddValue( key, pathIndexTable, pixelTable ):
-       'Determine if the key is in the pixel table, and if it is and if the value is not None add it to the path index table.'
-       if key in pixelTable:
-               value = pixelTable[key]
-               if value != None:
-                       pathIndexTable[value] = None
-               return True
-       return False
-
-def getLowerLeftCorner(nestedRings):
-       'Get the lower left corner from the nestedRings.'
-       lowerLeftCorner = Vector3()
-       lowestRealPlusImaginary = 987654321.0
-       for nestedRing in nestedRings:
-               for point in nestedRing.boundary:
-                       realPlusImaginary = point.real + point.imag
-                       if realPlusImaginary < lowestRealPlusImaginary:
-                               lowestRealPlusImaginary = realPlusImaginary
-                               lowerLeftCorner.setToXYZ(point.real, point.imag, nestedRing.z)
-       return lowerLeftCorner
-
-def getNewRepository():
-       'Get new repository.'
-       return FillRepository()
-
-def getNonIntersectingGridPointLine( gridPointInsetX, isJunctionWide, paths, pixelTable, yIntersectionPath, width ):
-       'Get the points around the grid point that is junction wide that do not intersect.'
-       pointIndexPlusOne = yIntersectionPath.getPointIndexPlusOne()
-       path = yIntersectionPath.getPath(paths)
-       begin = path[ yIntersectionPath.pointIndex ]
-       end = path[ pointIndexPlusOne ]
-       plusMinusSign = getPlusMinusSign( end.real - begin.real )
-       if isJunctionWide:
-               gridPointXFirst = complex( yIntersectionPath.gridPoint.real - plusMinusSign * gridPointInsetX, yIntersectionPath.gridPoint.imag )
-               gridPointXSecond = complex( yIntersectionPath.gridPoint.real + plusMinusSign * gridPointInsetX, yIntersectionPath.gridPoint.imag )
-               if isAddedPointOnPathFree( path, pixelTable, gridPointXSecond, pointIndexPlusOne, width ):
-                       if isAddedPointOnPathFree( path, pixelTable, gridPointXFirst, pointIndexPlusOne, width ):
-                               return [ gridPointXSecond, gridPointXFirst ]
-                       if isAddedPointOnPathFree( path, pixelTable, yIntersectionPath.gridPoint, pointIndexPlusOne, width ):
-                               return [ gridPointXSecond, yIntersectionPath.gridPoint ]
-                       return [ gridPointXSecond ]
-       if isAddedPointOnPathFree( path, pixelTable, yIntersectionPath.gridPoint, pointIndexPlusOne, width ):
-               return [ yIntersectionPath.gridPoint ]
-       return []
-
-def getPlusMinusSign(number):
-       'Get one if the number is zero or positive else negative one.'
-       if number >= 0.0:
-               return 1.0
-       return - 1.0
-
-def getWithLeastLength( path, point ):
-       'Insert a point into a path, at the index at which the path would be shortest.'
-       if len(path) < 1:
-               return 0
-       shortestPointIndex = None
-       shortestAdditionalLength = 999999999987654321.0
-       for pointIndex in xrange( len(path) + 1 ):
-               additionalLength = getAdditionalLength( path, point, pointIndex )
-               if additionalLength < shortestAdditionalLength:
-                       shortestAdditionalLength = additionalLength
-                       shortestPointIndex = pointIndex
-       return shortestPointIndex
-
-def getYIntersectionInsideYSegment( segmentFirstY, segmentSecondY, beginComplex, endComplex, x ):
-       'Get the y intersection inside the y segment if it does, else none.'
-       yIntersection = euclidean.getYIntersectionIfExists( beginComplex, endComplex, x )
-       if yIntersection == None:
-               return None
-       if yIntersection < min( segmentFirstY, segmentSecondY ):
-               return None
-       if yIntersection <= max( segmentFirstY, segmentSecondY ):
-               return yIntersection
-       return None
-
-def insertGridPointPair( gridPoint, gridPointInsetX, gridPoints, isJunctionWide, paths, pixelTable, yIntersectionPath, width ):
-       'Insert a pair of points around the grid point is is junction wide, otherwise inset one point.'
-       linePath = getNonIntersectingGridPointLine( gridPointInsetX, isJunctionWide, paths, pixelTable, yIntersectionPath, width )
-       insertGridPointPairWithLinePath( gridPoint, gridPointInsetX, gridPoints, isJunctionWide, linePath, paths, pixelTable, yIntersectionPath, width )
-
-def insertGridPointPairs( gridPoint, gridPointInsetX, gridPoints, intersectionPathFirst, intersectionPathSecond, isBothOrNone, isJunctionWide, paths, pixelTable, width ):
-       'Insert a pair of points around a pair of grid points.'
-       gridPointLineFirst = getNonIntersectingGridPointLine( gridPointInsetX, isJunctionWide, paths, pixelTable, intersectionPathFirst, width )
-       if len( gridPointLineFirst ) < 1:
-               if isBothOrNone:
-                       return
-               intersectionPathSecond.gridPoint = gridPoint
-               insertGridPointPair( gridPoint, gridPointInsetX, gridPoints, isJunctionWide, paths, pixelTable, intersectionPathSecond, width )
-               return
-       gridPointLineSecond = getNonIntersectingGridPointLine( gridPointInsetX, isJunctionWide, paths, pixelTable, intersectionPathSecond, width )
-       if len( gridPointLineSecond ) > 0:
-               insertGridPointPairWithLinePath( gridPoint, gridPointInsetX, gridPoints, isJunctionWide, gridPointLineFirst, paths, pixelTable, intersectionPathFirst, width )
-               insertGridPointPairWithLinePath( gridPoint, gridPointInsetX, gridPoints, isJunctionWide, gridPointLineSecond, paths, pixelTable, intersectionPathSecond, width )
-               return
-       if isBothOrNone:
-               return
-       originalGridPointFirst = intersectionPathFirst.gridPoint
-       intersectionPathFirst.gridPoint = gridPoint
-       gridPointLineFirstCenter = getNonIntersectingGridPointLine( gridPointInsetX, isJunctionWide, paths, pixelTable, intersectionPathFirst, width )
-       if len( gridPointLineFirstCenter ) > 0:
-               insertGridPointPairWithLinePath( gridPoint, gridPointInsetX, gridPoints, isJunctionWide, gridPointLineFirstCenter, paths, pixelTable, intersectionPathFirst, width )
-               return
-       intersectionPathFirst.gridPoint = originalGridPointFirst
-       insertGridPointPairWithLinePath( gridPoint, gridPointInsetX, gridPoints, isJunctionWide, gridPointLineFirst, paths, pixelTable, intersectionPathFirst, width )
-
-def insertGridPointPairWithLinePath( gridPoint, gridPointInsetX, gridPoints, isJunctionWide, linePath, paths, pixelTable, yIntersectionPath, width ):
-       'Insert a pair of points around the grid point is is junction wide, otherwise inset one point.'
-       if len( linePath ) < 1:
-               return
-       if gridPoint in gridPoints:
-               gridPoints.remove( gridPoint )
-       intersectionBeginPoint = None
-       moreThanInset = 2.1 * gridPointInsetX
-       path = yIntersectionPath.getPath(paths)
-       begin = path[ yIntersectionPath.pointIndex ]
-       end = path[ yIntersectionPath.getPointIndexPlusOne() ]
-       if yIntersectionPath.isOutside:
-               distanceX = end.real - begin.real
-               if abs( distanceX ) > 2.1 * moreThanInset:
-                       intersectionBeginXDistance = yIntersectionPath.gridPoint.real - begin.real
-                       endIntersectionXDistance = end.real - yIntersectionPath.gridPoint.real
-                       intersectionPoint = begin * endIntersectionXDistance / distanceX + end * intersectionBeginXDistance / distanceX
-                       distanceYAbsoluteInset = max( abs( yIntersectionPath.gridPoint.imag - intersectionPoint.imag ), moreThanInset )
-                       intersectionEndSegment = end - intersectionPoint
-                       intersectionEndSegmentLength = abs( intersectionEndSegment )
-                       if intersectionEndSegmentLength > 1.1 * distanceYAbsoluteInset:
-                               intersectionEndPoint = intersectionPoint + intersectionEndSegment * distanceYAbsoluteInset / intersectionEndSegmentLength
-                               path.insert( yIntersectionPath.getPointIndexPlusOne(), intersectionEndPoint )
-                       intersectionBeginSegment = begin - intersectionPoint
-                       intersectionBeginSegmentLength = abs( intersectionBeginSegment )
-                       if intersectionBeginSegmentLength > 1.1 * distanceYAbsoluteInset:
-                               intersectionBeginPoint = intersectionPoint + intersectionBeginSegment * distanceYAbsoluteInset / intersectionBeginSegmentLength
-       for point in linePath:
-               addPointOnPath( path, yIntersectionPath.pathIndex, pixelTable, point, yIntersectionPath.getPointIndexPlusOne(), width )
-       if intersectionBeginPoint != None:
-               addPointOnPath( path, yIntersectionPath.pathIndex, pixelTable, intersectionBeginPoint, yIntersectionPath.getPointIndexPlusOne(), width )
-
-def isAddedPointOnPathFree( path, pixelTable, point, pointIndex, width ):
-       'Determine if the point added to a path is intersecting the pixel table or the path.'
-       if 0 < pointIndex < len(path):
-               if isSharpCorner( ( path[pointIndex - 1] ), point, ( path[pointIndex] ) ):
-                       return False
-       pointIndexMinusOne = pointIndex - 1
-       if pointIndexMinusOne >= 0:
-               maskTable = {}
-               begin = path[ pointIndexMinusOne ]
-               if pointIndex < len(path):
-                       end = path[pointIndex]
-                       euclidean.addValueSegmentToPixelTable( begin, end, maskTable, None, width )
-               segmentTable = {}
-               euclidean.addSegmentToPixelTable( point, begin, segmentTable, 0.0, 2.0, width )
-               if euclidean.isPixelTableIntersecting( pixelTable, segmentTable, maskTable ):
-                       return False
-               if isAddedPointOnPathIntersectingPath( begin, path, point, pointIndexMinusOne ):
-                       return False
-       if pointIndex < len(path):
-               maskTable = {}
-               begin = path[pointIndex]
-               if pointIndexMinusOne >= 0:
-                       end = path[ pointIndexMinusOne ]
-                       euclidean.addValueSegmentToPixelTable( begin, end, maskTable, None, width )
-               segmentTable = {}
-               euclidean.addSegmentToPixelTable( point, begin, segmentTable, 0.0, 2.0, width )
-               if euclidean.isPixelTableIntersecting( pixelTable, segmentTable, maskTable ):
-                       return False
-               if isAddedPointOnPathIntersectingPath( begin, path, point, pointIndex ):
-                       return False
-       return True
-
-def isAddedPointOnPathIntersectingPath( begin, path, point, pointIndex ):
-       'Determine if the point added to a path is intersecting the path by checking line intersection.'
-       segment = point - begin
-       segmentLength = abs(segment)
-       if segmentLength <= 0.0:
-               return False
-       normalizedSegment = segment / segmentLength
-       segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag)
-       pointRotated = segmentYMirror * point
-       beginRotated = segmentYMirror * begin
-       if euclidean.isXSegmentIntersectingPath( path[ max( 0, pointIndex - 20 ) : pointIndex ], pointRotated.real, beginRotated.real, segmentYMirror, pointRotated.imag ):
-               return True
-       return euclidean.isXSegmentIntersectingPath( path[ pointIndex + 1 : pointIndex + 21 ], pointRotated.real, beginRotated.real, segmentYMirror, pointRotated.imag )
-
-def isIntersectingLoopsPaths( loops, paths, pointBegin, pointEnd ):
-       'Determine if the segment between the first and second point is intersecting the loop list.'
-       normalizedSegment = pointEnd.dropAxis() - pointBegin.dropAxis()
-       normalizedSegmentLength = abs( normalizedSegment )
-       if normalizedSegmentLength == 0.0:
-               return False
-       normalizedSegment /= normalizedSegmentLength
-       segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag)
-       pointBeginRotated = euclidean.getRoundZAxisByPlaneAngle( segmentYMirror, pointBegin )
-       pointEndRotated = euclidean.getRoundZAxisByPlaneAngle( segmentYMirror, pointEnd )
-       if euclidean.isLoopListIntersectingInsideXSegment( loops, pointBeginRotated.real, pointEndRotated.real, segmentYMirror, pointBeginRotated.imag ):
-               return True
-       return euclidean.isXSegmentIntersectingPaths( paths, pointBeginRotated.real, pointEndRotated.real, segmentYMirror, pointBeginRotated.imag )
-
-def isPointAddedAroundClosest(layerInfillWidth, paths, pixelTable, removedEndpointPoint, width):
-       'Add the closest removed endpoint to the path, with minimal twisting.'
-       closestDistanceSquared = 999999999987654321.0
-       closestPathIndex = None
-       for pathIndex in xrange(len(paths)):
-               path = paths[ pathIndex ]
-               for pointIndex in xrange(len(path)):
-                       point = path[pointIndex]
-                       distanceSquared = abs(point - removedEndpointPoint)
-                       if distanceSquared < closestDistanceSquared:
-                               closestDistanceSquared = distanceSquared
-                               closestPathIndex = pathIndex
-       if closestPathIndex == None:
-               return
-       if closestDistanceSquared < 0.8 * layerInfillWidth * layerInfillWidth:
-               return
-       closestPath = paths[closestPathIndex]
-       closestPointIndex = getWithLeastLength(closestPath, removedEndpointPoint)
-       if isAddedPointOnPathFree(closestPath, pixelTable, removedEndpointPoint, closestPointIndex, width):
-               addPointOnPath(closestPath, closestPathIndex, pixelTable, removedEndpointPoint, closestPointIndex, width)
-               return True
-       return isSidePointAdded(pixelTable, closestPath, closestPathIndex, closestPointIndex, layerInfillWidth, removedEndpointPoint, width)
-
-def isSegmentAround(aroundSegmentsDictionary, aroundSegmentsDictionaryKey, segment):
-       'Determine if there is another segment around.'
-       if aroundSegmentsDictionaryKey not in aroundSegmentsDictionary:
-               return False
-       for aroundSegment in aroundSegmentsDictionary[aroundSegmentsDictionaryKey]:
-               endpoint = aroundSegment[0]
-               if isSegmentInX(segment, endpoint.point.real, endpoint.otherEndpoint.point.real):
-                       return True
-       return False
-
-def isSegmentCompletelyInAnIntersection( segment, xIntersections ):
-       'Add sparse endpoints from a segment.'
-       for xIntersectionIndex in xrange( 0, len( xIntersections ), 2 ):
-               surroundingXFirst = xIntersections[ xIntersectionIndex ]
-               surroundingXSecond = xIntersections[ xIntersectionIndex + 1 ]
-               if euclidean.isSegmentCompletelyInX( segment, surroundingXFirst, surroundingXSecond ):
-                       return True
-       return False
-
-def isSegmentInX( segment, xFirst, xSecond ):
-       'Determine if the segment overlaps within x.'
-       segmentFirstX = segment[0].point.real
-       segmentSecondX = segment[1].point.real
-       if min( segmentFirstX, segmentSecondX ) > max( xFirst, xSecond ):
-               return False
-       return max( segmentFirstX, segmentSecondX ) > min( xFirst, xSecond )
-
-def isSharpCorner( beginComplex, centerComplex, endComplex ):
-       'Determine if the three complex points form a sharp corner.'
-       centerBeginComplex = beginComplex - centerComplex
-       centerEndComplex = endComplex - centerComplex
-       centerBeginLength = abs( centerBeginComplex )
-       centerEndLength = abs( centerEndComplex )
-       if centerBeginLength <= 0.0 or centerEndLength <= 0.0:
-               return False
-       centerBeginComplex /= centerBeginLength
-       centerEndComplex /= centerEndLength
-       return euclidean.getDotProduct( centerBeginComplex, centerEndComplex ) > 0.9
-
-def isSidePointAdded( pixelTable, closestPath, closestPathIndex, closestPointIndex, layerInfillWidth, removedEndpointPoint, width ):
-       'Add side point along with the closest removed endpoint to the path, with minimal twisting.'
-       if closestPointIndex <= 0 or closestPointIndex >= len( closestPath ):
-               return False
-       pointBegin = closestPath[ closestPointIndex - 1 ]
-       pointEnd = closestPath[ closestPointIndex ]
-       removedEndpointPoint = removedEndpointPoint
-       closest = pointBegin
-       farthest = pointEnd
-       removedMinusClosest = removedEndpointPoint - pointBegin
-       removedMinusClosestLength = abs( removedMinusClosest )
-       if removedMinusClosestLength <= 0.0:
-               return False
-       removedMinusOther = removedEndpointPoint - pointEnd
-       removedMinusOtherLength = abs( removedMinusOther )
-       if removedMinusOtherLength <= 0.0:
-               return False
-       insertPointAfter = None
-       insertPointBefore = None
-       if removedMinusOtherLength < removedMinusClosestLength:
-               closest = pointEnd
-               farthest = pointBegin
-               removedMinusClosest = removedMinusOther
-               removedMinusClosestLength = removedMinusOtherLength
-               insertPointBefore = removedEndpointPoint
-       else:
-               insertPointAfter = removedEndpointPoint
-       removedMinusClosestNormalized = removedMinusClosest / removedMinusClosestLength
-       perpendicular = removedMinusClosestNormalized * complex( 0.0, layerInfillWidth )
-       sidePoint = removedEndpointPoint + perpendicular
-       #extra check in case the line to the side point somehow slips by the line to the perpendicular
-       sidePointOther = removedEndpointPoint - perpendicular
-       if abs( sidePoint -  farthest ) > abs( sidePointOther -  farthest ):
-               perpendicular = - perpendicular
-               sidePoint = sidePointOther
-       maskTable = {}
-       closestSegmentTable = {}
-       toPerpendicularTable = {}
-       euclidean.addValueSegmentToPixelTable( pointBegin, pointEnd, maskTable, None, width )
-       euclidean.addValueSegmentToPixelTable( closest, removedEndpointPoint, closestSegmentTable, None, width )
-       euclidean.addValueSegmentToPixelTable( sidePoint, farthest, toPerpendicularTable, None, width )
-       if euclidean.isPixelTableIntersecting( pixelTable, toPerpendicularTable, maskTable ) or euclidean.isPixelTableIntersecting( closestSegmentTable, toPerpendicularTable, maskTable ):
-               sidePoint = removedEndpointPoint - perpendicular
-               toPerpendicularTable = {}
-               euclidean.addValueSegmentToPixelTable( sidePoint, farthest, toPerpendicularTable, None, width )
-               if euclidean.isPixelTableIntersecting( pixelTable, toPerpendicularTable, maskTable ) or euclidean.isPixelTableIntersecting( closestSegmentTable, toPerpendicularTable, maskTable ):
-                       return False
-       if insertPointBefore != None:
-               addPointOnPathIfFree( closestPath, closestPathIndex, pixelTable, insertPointBefore, closestPointIndex, width )
-       addPointOnPathIfFree( closestPath, closestPathIndex, pixelTable, sidePoint, closestPointIndex, width )
-       if insertPointAfter != None:
-               addPointOnPathIfFree( closestPath, closestPathIndex, pixelTable, insertPointAfter, closestPointIndex, width )
-       return True
-
-def removeEndpoints(layerInfillWidth, paths, pixelTable, removedEndpoints, aroundWidth):
-       'Remove endpoints which are added to the path.'
-       for removedEndpointIndex in xrange(len(removedEndpoints) -1, -1, -1):
-               removedEndpoint = removedEndpoints[removedEndpointIndex]
-               removedEndpointPoint = removedEndpoint.point
-               if isPointAddedAroundClosest(layerInfillWidth, paths, pixelTable, removedEndpointPoint, aroundWidth):
-                       removedEndpoints.remove(removedEndpoint )
-
-def setIsOutside( yCloseToCenterPath, yIntersectionPaths ):
-       'Determine if the yCloseToCenterPath is outside.'
-       beforeClose = yCloseToCenterPath.yMinusCenter < 0.0
-       for yIntersectionPath in yIntersectionPaths:
-               if yIntersectionPath != yCloseToCenterPath:
-                       beforePath = yIntersectionPath.yMinusCenter < 0.0
-                       if beforeClose == beforePath:
-                               yCloseToCenterPath.isOutside = False
-                               return
-       yCloseToCenterPath.isOutside = True
-
-def writeOutput(fileName, shouldAnalyze=True):
-       'Fill an inset gcode file.'
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'fill', shouldAnalyze)
-
-
-class FillRepository(object):
-       'A class to handle the fill settings.'
-       def __init__(self):
-               'Set the default settings, execute title & settings fileName.'
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.fill.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Fill', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Fill')
-               self.activateFill = settings.BooleanSetting().getFromValue('Activate Fill', self, True)
-               self.solidSurfaceTop = settings.BooleanSetting().getFromValue('Solid Surface Top', self, True)
-               self.overrideFirstLayerSequence = settings.BooleanSetting().getFromValue('Override First Layer Sequence', self, True)
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Diaphragm -', self )
-               self.diaphragmPeriod = settings.IntSpin().getFromValue( 20, 'Diaphragm Period (layers):', self, 200, 100 )
-               self.diaphragmThickness = settings.IntSpin().getFromValue( 0, 'Diaphragm Thickness (layers):', self, 5, 0 )
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Extra Shells -', self )
-               self.extraShellsAlternatingSolidLayer = settings.IntSpin().getFromValue( 0, 'Extra Shells on Alternating Solid Layer (layers):', self, 3, 2 )
-               self.extraShellsBase = settings.IntSpin().getFromValue( 0, 'Extra Shells on Base (layers):', self, 3, 1 )
-               self.extraShellsSparseLayer = settings.IntSpin().getFromValue( 0, 'Extra Shells on Sparse Layer (layers):', self, 3, 1 )
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Grid -', self )
-               self.gridCircleSeparationOverEdgeWidth = settings.FloatSpin().getFromValue(0.0, 'Grid Circle Separation over Perimeter Width (ratio):', self, 1.0, 0.2)
-               self.gridExtraOverlap = settings.FloatSpin().getFromValue( 0.0, 'Grid Extra Overlap (ratio):', self, 0.5, 0.1 )
-               self.gridJunctionSeparationBandHeight = settings.IntSpin().getFromValue( 0, 'Grid Junction Separation Band Height (layers):', self, 20, 10 )
-               self.gridJunctionSeparationOverOctogonRadiusAtEnd = settings.FloatSpin().getFromValue( 0.0, 'Grid Junction Separation over Octogon Radius At End (ratio):', self, 0.8, 0.0 )
-               self.gridJunctionSeparationOverOctogonRadiusAtMiddle = settings.FloatSpin().getFromValue( 0.0, 'Grid Junction Separation over Octogon Radius At Middle (ratio):', self, 0.8, 0.0 )
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Infill -', self )
-               self.infillBeginRotation = settings.FloatSpin().getFromValue( 0.0, 'Infill Begin Rotation (degrees):', self, 90.0, 45.0 )
-               self.infillBeginRotationRepeat = settings.IntSpin().getFromValue( 0, 'Infill Begin Rotation Repeat (layers):', self, 3, 1 )
-               self.infillOddLayerExtraRotation = settings.FloatSpin().getFromValue(30.0, 'Infill Odd Layer Extra Rotation (degrees):', self, 90.0, 90.0)
-               self.infillPatternLabel = settings.LabelDisplay().getFromName('Infill Pattern:', self )
-               infillLatentStringVar = settings.LatentStringVar()
-               self.infillPatternGridCircular = settings.Radio().getFromRadio( infillLatentStringVar, 'Grid Circular', self, False )
-               self.infillPatternGridHexagonal = settings.Radio().getFromRadio( infillLatentStringVar, 'Grid Hexagonal', self, False )
-               self.infillPatternGridRectangular = settings.Radio().getFromRadio( infillLatentStringVar, 'Grid Rectangular', self, False )
-               self.infillPatternLine = settings.Radio().getFromRadio( infillLatentStringVar, 'Line', self, True )
-               self.infillPerimeterOverlap = settings.FloatSpin().getFromValue( 0.0, 'Infill Perimeter Overlap (ratio):', self, 0.4, 0.15 )
-               self.infillSolidity = settings.FloatSpin().getFromValue( 0.04, 'Infill Solidity (ratio):', self, 0.3, 0.2 )
-               settings.LabelSeparator().getFromRepository(self)
-               self.sharpestAngle = settings.FloatSpin().getFromValue(50.0, 'Sharpest Angle (degrees):', self, 70.0, 60.0)
-               self.solidSurfaceThickness = settings.IntSpin().getFromValue(0, 'Solid Surface Thickness (layers):', self, 5, 3)
-               self.startFromChoice = settings.MenuButtonDisplay().getFromName('Start From Choice:', self)
-               self.startFromLowerLeft = settings.MenuRadio().getFromMenuButtonDisplay(self.startFromChoice, 'Lower Left', self, True)
-               self.startFromNearest = settings.MenuRadio().getFromMenuButtonDisplay(self.startFromChoice, 'Nearest', self, False)
-               self.surroundingAngle = settings.FloatSpin().getFromValue(30.0, 'Surrounding Angle (degrees):', self, 80.0, 60.0)
-               self.threadSequenceChoice = settings.MenuButtonDisplay().getFromName('Thread Sequence Choice:', self)
-               self.threadSequenceInfillLoops = settings.MenuRadio().getFromMenuButtonDisplay(self.threadSequenceChoice, 'Infill > Loops > Perimeter', self, False)
-               self.threadSequenceInfillPerimeter = settings.MenuRadio().getFromMenuButtonDisplay(self.threadSequenceChoice, 'Infill > Perimeter > Loops', self, False)
-               self.threadSequenceLoopsInfill = settings.MenuRadio().getFromMenuButtonDisplay(self.threadSequenceChoice, 'Loops > Infill > Perimeter', self, False)
-               self.threadSequenceLoopsPerimeter = settings.MenuRadio().getFromMenuButtonDisplay(self.threadSequenceChoice, 'Loops > Perimeter > Infill', self, True)
-               self.threadSequencePerimeterInfill = settings.MenuRadio().getFromMenuButtonDisplay(self.threadSequenceChoice, 'Perimeter > Infill > Loops', self, False)
-               self.threadSequencePerimeterLoops = settings.MenuRadio().getFromMenuButtonDisplay(self.threadSequenceChoice, 'Perimeter > Loops > Infill', self, False)
-               self.executeTitle = 'Fill'
-
-       def execute(self):
-               'Fill button has been clicked.'
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class FillSkein(object):
-       'A class to fill a skein of extrusions.'
-       def __init__(self):
-               'Initialize.'
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.edgeWidth = None
-               self.extruderActive = False
-               self.fillInset = 0.18
-               self.isEdge = False
-               self.lastExtraShells = - 1
-               self.lineIndex = 0
-               self.oldLocation = None
-               self.oldOrderedLocation = None
-               self.rotatedLayer = None
-               self.rotatedLayers = []
-               self.shutdownLineIndex = sys.maxint
-               self.nestedRing = None
-               self.thread = None
-
-       def addFill(self, layerIndex):
-               'Add fill to the carve layer.'
-#              if layerIndex > 2:
-#                      return
-               settings.printProgressByNumber(layerIndex, len(self.rotatedLayers), 'fill')
-               arounds = []
-               endpoints = []
-               extraShells = self.repository.extraShellsSparseLayer.value
-               infillPaths = []
-               layerFillInset = self.fillInset
-               layerInfillSolidity = self.infillSolidity
-               layerRemainder = layerIndex % int(round(self.repository.diaphragmPeriod.value))
-               layerRotation = self.getLayerRotation(layerIndex)
-               pixelTable = {}
-               reverseRotation = complex(layerRotation.real, - layerRotation.imag)
-               rotatedLayer = self.rotatedLayers[layerIndex]
-               self.isDoubleJunction = True
-               self.isJunctionWide = True
-               surroundingCarves = []
-               self.distanceFeedRate.addLine('(<layer> %s )' % rotatedLayer.z)
-               if layerRemainder >= int(round(self.repository.diaphragmThickness.value)):
-                       for surroundingIndex in xrange(1, self.solidSurfaceThickness + 1):
-                               if self.repository.solidSurfaceTop.value:
-                                       self.addRotatedCarve(layerIndex, -surroundingIndex, reverseRotation, surroundingCarves)
-                                       self.addRotatedCarve(layerIndex, surroundingIndex, reverseRotation, surroundingCarves)
-                               else:
-                                       self.addRotatedCarve(layerIndex, -surroundingIndex, reverseRotation, surroundingCarves)
-                                       self.addRotatedCarve(layerIndex, -surroundingIndex, reverseRotation, surroundingCarves)
-               if len(surroundingCarves) < self.doubleSolidSurfaceThickness:
-                       extraShells = self.repository.extraShellsAlternatingSolidLayer.value
-                       if self.lastExtraShells != self.repository.extraShellsBase.value:
-                               extraShells = self.repository.extraShellsBase.value
-               if rotatedLayer.rotation != None:
-                       extraShells = 0
-                       self.distanceFeedRate.addLine('(<bridgeRotation> %s )' % layerRotation)
-               self.distanceFeedRate.addLine('(<rotation> %s )' % layerRotation)
-#              aroundWidth = 0.34321 * self.infillWidth
-               aroundWidth = 0.24321 * self.infillWidth
-               doubleInfillWidth = 2.0 * self.infillWidth
-               gridPointInsetX = 0.5 * self.fillInset
-               self.lastExtraShells = extraShells
-               if self.repository.infillPatternGridHexagonal.value:
-                       infillBeginRotationPolar = euclidean.getWiddershinsUnitPolar(self.infillBeginRotation)
-                       if abs(euclidean.getDotProduct(layerRotation, infillBeginRotationPolar)) < math.sqrt( 0.5):
-                               layerInfillSolidity *= 0.5
-                               self.isDoubleJunction = False
-                       else:
-                               self.isJunctionWide = False
-               nestedRings = euclidean.getOrderedNestedRings(rotatedLayer.nestedRings)
-               radiusAround = 0.5 * min(self.infillWidth, self.edgeWidth)
-               createFillForSurroundings(nestedRings, self.edgeMinusHalfInfillWidth, radiusAround, False)
-               for extraShellIndex in xrange(extraShells):
-                       createFillForSurroundings(nestedRings, self.infillWidth, radiusAround, True)
-               fillLoops = euclidean.getFillOfSurroundings(nestedRings, None)
-               rotatedLoops = euclidean.getRotatedComplexLists(reverseRotation, fillLoops)
-               infillDictionary = triangle_mesh.getInfillDictionary(arounds, aroundWidth, self.fillInset, self.infillWidth, pixelTable, rotatedLoops)
-               if len(arounds) < 1:
-                       self.addThreadsBridgeLayer(layerIndex, nestedRings, rotatedLayer)
-                       return
-               self.horizontalSegmentsDictionary = {}
-               for infillDictionaryKey in infillDictionary.keys():
-                       xIntersections = infillDictionary[infillDictionaryKey]
-                       xIntersections.sort()
-                       y = infillDictionaryKey * self.infillWidth
-                       self.horizontalSegmentsDictionary[infillDictionaryKey] = euclidean.getSegmentsFromXIntersections(xIntersections, y)
-               self.surroundingXIntersectionsDictionary = {}
-               gridCircular = False
-               removedEndpoints = []
-               if len(surroundingCarves) >= self.doubleSolidSurfaceThickness:
-                       if self.repository.infillPatternGridCircular.value and self.repository.infillSolidity.value > 0.0:
-                               gridCircular = True
-                               layerInfillSolidity = 0.0
-                       xSurroundingIntersectionsDictionaries = [infillDictionary]
-                       for surroundingCarve in surroundingCarves:
-                               xSurroundingIntersectionsDictionary = {}
-                               euclidean.addXIntersectionsFromLoopsForTable(surroundingCarve, xSurroundingIntersectionsDictionary, self.infillWidth)
-                               xSurroundingIntersectionsDictionaries.append(xSurroundingIntersectionsDictionary)
-                       self.surroundingXIntersectionsDictionary = euclidean.getIntersectionOfXIntersectionsTables(xSurroundingIntersectionsDictionaries)
-                       for horizontalSegmentsDictionaryKey in self.horizontalSegmentsDictionary.keys():
-                               if horizontalSegmentsDictionaryKey in self.surroundingXIntersectionsDictionary:
-                                       surroundingXIntersections = self.surroundingXIntersectionsDictionary[horizontalSegmentsDictionaryKey]
-                               else:
-                                       surroundingXIntersections = []
-                               addSparseEndpoints(doubleInfillWidth, endpoints, self.horizontalSegmentsDictionary, horizontalSegmentsDictionaryKey, layerInfillSolidity, removedEndpoints, self.solidSurfaceThickness, surroundingXIntersections)
-               else:
-                       for segments in self.horizontalSegmentsDictionary.values():
-                               for segment in segments:
-                                       endpoints += segment
-               paths = euclidean.getPathsFromEndpoints(endpoints, 5.0 * self.infillWidth, pixelTable, self.sharpestProduct, aroundWidth)
-               if gridCircular:
-                       startAngle = euclidean.globalGoldenAngle * float(layerIndex)
-                       for gridPoint in self.getGridPoints(fillLoops, reverseRotation):
-                               self.addGridCircle(gridPoint, infillPaths, layerRotation, pixelTable, rotatedLoops, layerRotation, aroundWidth)
-               else:
-                       if self.isGridToBeExtruded():
-                               self.addGrid(
-                                       arounds, fillLoops, gridPointInsetX, layerIndex, paths, pixelTable, reverseRotation, surroundingCarves, aroundWidth)
-                       oldRemovedEndpointLength = len(removedEndpoints) + 1
-                       while oldRemovedEndpointLength - len(removedEndpoints) > 0:
-                               oldRemovedEndpointLength = len(removedEndpoints)
-                               removeEndpoints(self.infillWidth, paths, pixelTable, removedEndpoints, aroundWidth)
-                       paths = euclidean.getConnectedPaths(paths, pixelTable, self.sharpestProduct, aroundWidth)
-               for path in paths:
-                       addPath(self.infillWidth, infillPaths, path, layerRotation)
-               euclidean.transferPathsToNestedRings(nestedRings, infillPaths)
-               for fillLoop in fillLoops:
-                       addInfillBoundary(fillLoop, nestedRings)
-               self.addThreadsBridgeLayer(layerIndex, nestedRings, rotatedLayer)
-
-       def addGcodeFromThreadZ( self, thread, z ):
-               'Add a gcode thread to the output.'
-               self.distanceFeedRate.addGcodeFromThreadZ( thread, z )
-
-       def addGrid(self, arounds, fillLoops, gridPointInsetX, layerIndex, paths, pixelTable, reverseRotation, surroundingCarves, width):
-               'Add the grid to the infill layer.'
-               if len(surroundingCarves) < self.doubleSolidSurfaceThickness:
-                       return
-               explodedPaths = []
-               pathGroups = []
-               for path in paths:
-                       pathIndexBegin = len( explodedPaths )
-                       for pointIndex in xrange( len(path) - 1 ):
-                               pathSegment = [ path[pointIndex], path[pointIndex + 1] ]
-                               explodedPaths.append( pathSegment )
-                       pathGroups.append( ( pathIndexBegin, len( explodedPaths ) ) )
-               for pathIndex in xrange( len( explodedPaths ) ):
-                       explodedPath = explodedPaths[ pathIndex ]
-                       euclidean.addPathToPixelTable( explodedPath, pixelTable, pathIndex, width )
-               gridPoints = self.getGridPoints(fillLoops, reverseRotation)
-               gridPointInsetY = gridPointInsetX * ( 1.0 - self.repository.gridExtraOverlap.value )
-               if self.repository.infillPatternGridRectangular.value:
-                       gridBandHeight = self.repository.gridJunctionSeparationBandHeight.value
-                       gridLayerRemainder = ( layerIndex - self.solidSurfaceThickness ) % gridBandHeight
-                       halfBandHeight = 0.5 * float( gridBandHeight )
-                       halfBandHeightFloor = math.floor( halfBandHeight )
-                       fromMiddle = math.floor( abs( gridLayerRemainder - halfBandHeight ) )
-                       fromEnd = halfBandHeightFloor - fromMiddle
-                       gridJunctionSeparation = self.gridJunctionEnd * fromMiddle + self.gridJunctionMiddle * fromEnd
-                       gridJunctionSeparation /= halfBandHeightFloor
-                       gridPointInsetX += gridJunctionSeparation
-                       gridPointInsetY += gridJunctionSeparation
-               oldGridPointLength = len( gridPoints ) + 1
-               while oldGridPointLength - len( gridPoints ) > 0:
-                       oldGridPointLength = len( gridPoints )
-                       self.addRemainingGridPoints( arounds, gridPointInsetX, gridPointInsetY, gridPoints, True, explodedPaths, pixelTable, width )
-               oldGridPointLength = len( gridPoints ) + 1
-               while oldGridPointLength - len( gridPoints ) > 0:
-                       oldGridPointLength = len( gridPoints )
-                       self.addRemainingGridPoints( arounds, gridPointInsetX, gridPointInsetY, gridPoints, False, explodedPaths, pixelTable, width )
-               for pathGroupIndex in xrange( len( pathGroups ) ):
-                       pathGroup = pathGroups[ pathGroupIndex ]
-                       paths[ pathGroupIndex ] = []
-                       for explodedPathIndex in xrange( pathGroup[0], pathGroup[1] ):
-                               explodedPath = explodedPaths[ explodedPathIndex ]
-                               if len( paths[ pathGroupIndex ] ) == 0:
-                                       paths[ pathGroupIndex ] = explodedPath
-                               else:
-                                       paths[ pathGroupIndex ] += explodedPath[1 :]
-
-       def addGridCircle(self, center, infillPaths, layerRotation, pixelTable, rotatedLoops, startRotation, width):
-               'Add circle to the grid.'
-               startAngle = -math.atan2(startRotation.imag, startRotation.real)
-               loop = euclidean.getComplexPolygon(center, self.gridCircleRadius, 17, startAngle)
-               loopPixelDictionary = {}
-               euclidean.addLoopToPixelTable(loop, loopPixelDictionary, width)
-               if not euclidean.isPixelTableIntersecting(pixelTable, loopPixelDictionary):
-                       if euclidean.getIsInFilledRegion(rotatedLoops, euclidean.getLeftPoint(loop)):
-                               addLoop(self.infillWidth, infillPaths, loop, layerRotation)
-                               return
-               insideIndexPaths = []
-               insideIndexPath = None
-               for pointIndex, point in enumerate(loop):
-                       nextPoint = loop[(pointIndex + 1) % len(loop)]
-                       segmentDictionary = {}
-                       euclidean.addValueSegmentToPixelTable(point, nextPoint, segmentDictionary, None, width)
-                       euclidean.addSquareTwoToPixelDictionary(segmentDictionary, point, None, width)
-                       euclidean.addSquareTwoToPixelDictionary(segmentDictionary, nextPoint, None, width)
-                       shouldAddLoop = not euclidean.isPixelTableIntersecting(pixelTable, segmentDictionary)
-                       if shouldAddLoop:
-                               shouldAddLoop = euclidean.getIsInFilledRegion(rotatedLoops, point)
-                       if shouldAddLoop:
-                               if insideIndexPath == None:
-                                       insideIndexPath = [pointIndex]
-                                       insideIndexPaths.append(insideIndexPath)
-                               else:
-                                       insideIndexPath.append(pointIndex)
-                       else:
-                               insideIndexPath = None
-               if len(insideIndexPaths) > 1:
-                       insideIndexPathFirst = insideIndexPaths[0]
-                       insideIndexPathLast = insideIndexPaths[-1]
-                       if insideIndexPathFirst[0] == 0 and insideIndexPathLast[-1] == len(loop) - 1:
-                               insideIndexPaths[0] = insideIndexPathLast + insideIndexPathFirst
-                               del insideIndexPaths[-1]
-               for insideIndexPath in insideIndexPaths:
-                       path = []
-                       for insideIndex in insideIndexPath:
-                               if len(path) == 0:
-                                       path.append(loop[insideIndex])
-                               path.append(loop[(insideIndex + 1) % len(loop)])
-                       addPath(self.infillWidth, infillPaths, path, layerRotation)
-
-       def addGridLinePoints( self, begin, end, gridPoints, gridRotationAngle, offset, y ):
-               'Add the segments of one line of a grid to the infill.'
-               if self.gridRadius == 0.0:
-                       return
-               gridXStep = int(math.floor((begin) / self.gridXStepSize)) - 3
-               gridXOffset = offset + self.gridXStepSize * float(gridXStep)
-               while gridXOffset < end:
-                       if gridXOffset >= begin:
-                               gridPointComplex = complex(gridXOffset, y) * gridRotationAngle
-                               if self.repository.infillPatternGridCircular.value or self.isPointInsideLineSegments(gridPointComplex):
-                                       gridPoints.append(gridPointComplex)
-                       gridXStep = self.getNextGripXStep(gridXStep)
-                       gridXOffset = offset + self.gridXStepSize * float(gridXStep)
-
-       def addRemainingGridPoints(
-               self, arounds, gridPointInsetX, gridPointInsetY, gridPoints, isBothOrNone, paths, pixelTable, width):
-               'Add the remaining grid points to the grid point list.'
-               for gridPointIndex in xrange( len( gridPoints ) - 1, - 1, - 1 ):
-                       gridPoint = gridPoints[ gridPointIndex ]
-                       addAroundGridPoint( arounds, gridPoint, gridPointInsetX, gridPointInsetY, gridPoints, self.gridRadius, isBothOrNone, self.isDoubleJunction, self.isJunctionWide, paths, pixelTable, width )
-
-       def addRotatedCarve(self, currentLayer, layerDelta, reverseRotation, surroundingCarves):
-               'Add a rotated carve to the surrounding carves.rotatedCarveDictionary'
-               layerIndex = currentLayer + layerDelta
-               if layerIndex < 0 or layerIndex >= len(self.rotatedLayers):
-                       return
-               layerDifference = abs(layerDelta)
-               rotatedLayer = self.rotatedLayers[layerIndex]
-               if layerDifference in rotatedLayer.rotatedCarveDictionary:
-                       surroundingCarves.append(rotatedLayer.rotatedCarveDictionary[layerDifference])
-                       return
-               nestedRings = rotatedLayer.nestedRings
-               rotatedCarve = []
-               for nestedRing in nestedRings:
-                       planeRotatedLoop = euclidean.getRotatedComplexes(reverseRotation, nestedRing.boundary)
-                       rotatedCarve.append(planeRotatedLoop)
-               outsetRadius = float(layerDifference) * self.layerHeight * self.surroundingSlope - self.edgeWidth
-               if outsetRadius > 0.0:
-                       rotatedCarve = intercircle.getInsetSeparateLoopsFromAroundLoops(rotatedCarve, -outsetRadius, self.layerHeight)
-               surroundingCarves.append(rotatedCarve)
-               rotatedLayer.rotatedCarveDictionary[layerDifference] = rotatedCarve
-
-       def addThreadsBridgeLayer(self, layerIndex, nestedRings, rotatedLayer, testLoops=None):
-               'Add the threads, add the bridge end & the layer end tag.'
-               if self.oldOrderedLocation == None or self.repository.startFromLowerLeft.value:
-                       self.oldOrderedLocation = getLowerLeftCorner(nestedRings)
-               extrusionHalfWidth = 0.5 * self.infillWidth
-               threadSequence = self.threadSequence
-               if layerIndex < 1 and self.repository.overrideFirstLayerSequence.value:
-                       threadSequence = ['edge', 'loops', 'infill']
-               euclidean.addToThreadsRemove(extrusionHalfWidth, nestedRings, self.oldOrderedLocation, self, threadSequence)
-               if testLoops != None:
-                       for testLoop in testLoops:
-                               self.addGcodeFromThreadZ(testLoop, self.oldOrderedLocation.z)
-               self.distanceFeedRate.addLine('(</rotation>)')
-               if rotatedLayer.rotation != None:
-                       self.distanceFeedRate.addLine('(</bridgeRotation>)')
-               self.distanceFeedRate.addLine('(</layer>)')
-
-       def addToThread(self, location):
-               'Add a location to thread.'
-               if self.oldLocation == None:
-                       return
-               if self.isEdge:
-                       self.nestedRing.addToLoop( location )
-                       return
-               if self.thread == None:
-                       self.thread = [ self.oldLocation.dropAxis() ]
-                       self.nestedRing.edgePaths.append(self.thread)
-               self.thread.append(location.dropAxis())
-
-       def getCraftedGcode( self, repository, gcodeText ):
-               'Parse gcode text and store the bevel gcode.'
-               self.repository = repository
-               self.lines = archive.getTextLines(gcodeText)
-               self.sharpestProduct = math.sin(math.radians(repository.sharpestAngle.value))
-               self.threadSequence = None
-               if repository.threadSequenceInfillLoops.value:
-                       self.threadSequence = ['infill', 'loops', 'edge']
-               if repository.threadSequenceInfillPerimeter.value:
-                       self.threadSequence = ['infill', 'edge', 'loops']
-               if repository.threadSequenceLoopsInfill.value:
-                       self.threadSequence = ['loops', 'infill', 'edge']
-               if repository.threadSequenceLoopsPerimeter.value:
-                       self.threadSequence = ['loops', 'edge', 'infill']
-               if repository.threadSequencePerimeterInfill.value:
-                       self.threadSequence = ['edge', 'infill', 'loops']
-               if repository.threadSequencePerimeterLoops.value:
-                       self.threadSequence = ['edge', 'loops', 'infill']
-               if self.repository.infillPerimeterOverlap.value > 0.45:
-                       print('')
-                       print('!!! WARNING !!!')
-                       print('"Infill Perimeter Overlap" is greater than 0.45, which may create problems with the infill, like threads going through empty space and/or the extruder switching on and off a lot.')
-                       print('If you want to stretch the infill a lot, set "Path Stretch over Perimeter Width" in stretch to a high value instead of setting "Infill Perimeter Overlap" to a high value.')
-                       print('')
-               self.parseInitialization()
-               if self.edgeWidth == None:
-                       print('Warning, nothing will be done because self.edgeWidth in getCraftedGcode in FillSkein was None.')
-                       return ''
-               self.fillInset = self.infillWidth - self.infillWidth * self.repository.infillPerimeterOverlap.value
-               self.infillSolidity = repository.infillSolidity.value
-               self.edgeMinusHalfInfillWidth = self.edgeWidth - 0.5 * self.infillWidth
-               if self.isGridToBeExtruded():
-                       self.setGridVariables(repository)
-               self.infillBeginRotation = math.radians( repository.infillBeginRotation.value )
-               self.infillOddLayerExtraRotation = math.radians( repository.infillOddLayerExtraRotation.value )
-               self.solidSurfaceThickness = int( round( self.repository.solidSurfaceThickness.value ) )
-               self.doubleSolidSurfaceThickness = self.solidSurfaceThickness + self.solidSurfaceThickness
-               for lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       self.parseLine( lineIndex )
-               for layerIndex in xrange(len(self.rotatedLayers)):
-                       self.addFill(layerIndex)
-               self.distanceFeedRate.addLines( self.lines[ self.shutdownLineIndex : ] )
-               return self.distanceFeedRate.output.getvalue()
-
-       def getGridPoints(self, fillLoops, reverseRotation):
-               'Get the grid points.'
-               if self.infillSolidity > 0.8:
-                       return []
-               rotationBaseAngle = euclidean.getWiddershinsUnitPolar(self.infillBeginRotation)
-               reverseRotationBaseAngle = complex(rotationBaseAngle.real, - rotationBaseAngle.imag)
-               gridRotationAngle = reverseRotation * rotationBaseAngle
-               slightlyGreaterThanFillInset = intercircle.globalIntercircleMultiplier * self.gridInset
-               triangle_mesh.sortLoopsInOrderOfArea(True, fillLoops)
-               rotatedLoops = euclidean.getRotatedComplexLists(reverseRotationBaseAngle, fillLoops)
-               if self.repository.infillPatternGridCircular.value:
-                       return self.getGridPointsByLoops(
-                               gridRotationAngle, intercircle.getInsetSeparateLoopsFromLoops(rotatedLoops, -self.gridCircleRadius))
-               return self.getGridPointsByLoops(gridRotationAngle, intercircle.getInsetSeparateLoopsFromLoops(rotatedLoops, self.gridInset))
-
-       def getGridPointsByLoops(self, gridRotationAngle, loops):
-               'Get the grid points by loops.'
-               gridIntersectionsDictionary = {}
-               gridPoints = []
-               euclidean.addXIntersectionsFromLoopsForTable(loops, gridIntersectionsDictionary, self.gridRadius)
-               for gridIntersectionsKey in gridIntersectionsDictionary:
-                       y = gridIntersectionsKey * self.gridRadius + self.gridRadius * 0.5
-                       gridIntersections = gridIntersectionsDictionary[gridIntersectionsKey]
-                       gridIntersections.sort()
-                       gridIntersectionsLength = len(gridIntersections)
-                       if gridIntersectionsLength % 2 == 1:
-                               gridIntersectionsLength -= 1
-                       for gridIntersectionIndex in xrange(0, gridIntersectionsLength, 2):
-                               begin = gridIntersections[gridIntersectionIndex]
-                               end = gridIntersections[gridIntersectionIndex + 1]
-                               offset = self.offsetMultiplier * (gridIntersectionsKey % 2) + self.offsetBaseX
-                               self.addGridLinePoints(begin, end, gridPoints, gridRotationAngle, offset, y)
-               return gridPoints
-
-       def getLayerRotation(self, layerIndex):
-               'Get the layer rotation.'
-               rotation = self.rotatedLayers[layerIndex].rotation
-               if rotation != None:
-                       return rotation
-               infillBeginRotationRepeat = self.repository.infillBeginRotationRepeat.value
-               infillOddLayerRotationMultiplier = float( layerIndex % ( infillBeginRotationRepeat + 1 ) == infillBeginRotationRepeat )
-               layerAngle = self.infillBeginRotation + infillOddLayerRotationMultiplier * self.infillOddLayerExtraRotation
-               return euclidean.getWiddershinsUnitPolar(layerAngle)
-
-       def getNextGripXStep( self, gridXStep ):
-               'Get the next grid x step, increment by an extra one every three if hexagonal grid is chosen.'
-               gridXStep += 1
-               if self.repository.infillPatternGridHexagonal.value:
-                       if gridXStep % 3 == 0:
-                               gridXStep += 1
-               return gridXStep
-
-       def isGridToBeExtruded(self):
-               'Determine if the grid is to be extruded.'
-               if self.repository.infillPatternLine.value:
-                       return False
-               return self.repository.infillSolidity.value > 0.0
-
-       def isPointInsideLineSegments( self, gridPoint ):
-               'Is the point inside the line segments of the loops.'
-               if self.solidSurfaceThickness <= 0:
-                       return True
-               fillLine = int(round(gridPoint.imag / self.infillWidth))
-               if fillLine not in self.horizontalSegmentsDictionary:
-                       return False
-               if fillLine not in self.surroundingXIntersectionsDictionary:
-                       return False
-               lineSegments = self.horizontalSegmentsDictionary[fillLine]
-               surroundingXIntersections = self.surroundingXIntersectionsDictionary[fillLine]
-               for lineSegment in lineSegments:
-                       if isSegmentCompletelyInAnIntersection(lineSegment, surroundingXIntersections ):
-                               xFirst = lineSegment[0].point.real
-                               xSecond = lineSegment[1].point.real
-                               if min(xFirst, xSecond) < gridPoint.real < max(xFirst, xSecond):
-                                       return True
-               return False
-
-       def linearMove( self, splitLine ):
-               'Add a linear move to the thread.'
-               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               if self.extruderActive:
-                       self.addToThread( location )
-               self.oldLocation = location
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(<crafting>)':
-                               self.distanceFeedRate.addLine(line)
-                               return
-                       elif firstWord == '(<infillWidth>':
-                               self.infillWidth = float(splitLine[1])
-                       elif firstWord == '(<layerHeight>':
-                               self.layerHeight = float(splitLine[1])
-                               self.surroundingSlope = math.tan(math.radians(min(self.repository.surroundingAngle.value, 80.0)))
-                               self.distanceFeedRate.addTagRoundedLine('infillPerimeterOverlap', self.repository.infillPerimeterOverlap.value)
-                               self.distanceFeedRate.addTagRoundedLine('sharpestProduct', self.sharpestProduct)
-                       elif firstWord == '(<edgeWidth>':
-                               self.edgeWidth = float(splitLine[1])
-                               threadSequenceString = ' '.join( self.threadSequence )
-                               self.distanceFeedRate.addTagBracketedLine('threadSequenceString', threadSequenceString )
-                       elif firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('fill')
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine( self, lineIndex ):
-               'Parse a gcode line and add it to the fill skein.'
-               line = self.lines[lineIndex]
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       self.linearMove(splitLine)
-               elif firstWord == 'M101':
-                       self.extruderActive = True
-               elif firstWord == 'M103':
-                       self.extruderActive = False
-                       self.isEdge = False
-                       self.thread = None
-               elif firstWord == '(<boundaryPerimeter>)':
-                       self.nestedRing = euclidean.NestedBand()
-                       self.rotatedLayer.nestedRings.append( self.nestedRing )
-               elif firstWord == '(</boundaryPerimeter>)':
-                       self.nestedRing = None
-               elif firstWord == '(<boundaryPoint>':
-                       location = gcodec.getLocationFromSplitLine(None, splitLine)
-                       self.nestedRing.addToBoundary( location )
-               elif firstWord == '(<bridgeRotation>':
-                       self.rotatedLayer.rotation = gcodec.getRotationBySplitLine(splitLine)
-               elif firstWord == '(</crafting>)':
-                       self.shutdownLineIndex = lineIndex
-               elif firstWord == '(<layer>':
-                       self.rotatedLayer = RotatedLayer(float(splitLine[1]))
-                       self.rotatedLayers.append( self.rotatedLayer )
-                       self.thread = None
-               elif firstWord == '(<edge>':
-                       self.isEdge = True
-
-       def setGridVariables( self, repository ):
-               'Set the grid variables.'
-               self.gridInset = 1.2 * self.infillWidth
-               self.gridRadius = self.infillWidth / self.infillSolidity
-               self.gridXStepSize = 2.0 * self.gridRadius
-               self.offsetMultiplier = self.gridRadius
-               if self.repository.infillPatternGridHexagonal.value:
-                       self.gridXStepSize = 4.0 / 3.0 * self.gridRadius
-                       self.offsetMultiplier = 1.5 * self.gridXStepSize
-               if self.repository.infillPatternGridCircular.value:
-                       self.gridRadius += self.gridRadius
-                       self.gridXStepSize = self.gridRadius / math.sqrt(.75)
-                       self.offsetMultiplier = 0.5 * self.gridXStepSize
-                       circleInsetOverEdgeWidth = repository.gridCircleSeparationOverEdgeWidth.value + 0.5
-                       self.gridMinimumCircleRadius = self.edgeWidth
-                       self.gridInset = self.gridMinimumCircleRadius
-                       self.gridCircleRadius = self.offsetMultiplier - circleInsetOverEdgeWidth * self.edgeWidth
-                       if self.gridCircleRadius < self.gridMinimumCircleRadius:
-                               print('')
-                               print('!!! WARNING !!!')
-                               print('Grid Circle Separation over Edge Width is too high, which makes the grid circles too small.')
-                               print('You should reduce Grid Circle Separation over Edge Width to a reasonable value, like the default of 0.5.')
-                               print('The grid circle radius will be set to the minimum grid circle radius.')
-                               print('')
-                               self.gridCircleRadius = self.gridMinimumCircleRadius
-               self.offsetBaseX = 0.25 * self.gridXStepSize
-               if self.repository.infillPatternGridRectangular.value:
-                       halfGridMinusWidth = 0.5 * ( self.gridRadius - self.infillWidth )
-                       self.gridJunctionEnd = halfGridMinusWidth * repository.gridJunctionSeparationOverOctogonRadiusAtEnd.value
-                       self.gridJunctionMiddle = halfGridMinusWidth * repository.gridJunctionSeparationOverOctogonRadiusAtMiddle.value
-
-
-class RotatedLayer(object):
-       'A rotated layer.'
-       def __init__( self, z ):
-               'Initialize.'
-               self.rotatedCarveDictionary = {}
-               self.rotation = None
-               self.nestedRings = []
-               self.z = z
-
-       def __repr__(self):
-               'Get the string representation of this RotatedLayer.'
-               return '%s, %s, %s' % ( self.z, self.rotation, self.nestedRings )
-
-
-class YIntersectionPath(object):
-       'A class to hold the y intersection position, the loop which it intersected and the point index of the loop which it intersected.'
-       def __init__( self, pathIndex, pointIndex, y ):
-               'Initialize from the path, point index, and y.'
-               self.pathIndex = pathIndex
-               self.pointIndex = pointIndex
-               self.y = y
-
-       def __repr__(self):
-               'Get the string representation of this y intersection.'
-               return '%s, %s, %s' % ( self.pathIndex, self.pointIndex, self.y )
-
-       def getPath( self, paths ):
-               'Get the path from the paths and path index.'
-               return paths[ self.pathIndex ]
-
-       def getPointIndexPlusOne(self):
-               'Get the point index plus one.'
-               return self.pointIndex + 1
-
-
-def main():
-       'Display the fill dialog.'
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == '__main__':
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/fillet.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/fillet.py
deleted file mode 100644 (file)
index 51e33bc..0000000
+++ /dev/null
@@ -1,390 +0,0 @@
-"""
-This page is in the table of contents.
-Fillet rounds the corners slightly in a variety of ways.  This is to reduce corner blobbing and sudden extruder acceleration.
-
-The fillet manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Fillet
-
-==Operation==
-The default 'Activate Fillet' checkbox is off.  When it is on, the functions described below will work, when it is off, nothing will be done.
-
-==Settings==
-===Fillet Procedure Choice===
-Default is 'Bevel''.
-
-====Arc Point====
-When selected, the corners will be filleted with an arc using the gcode point form.
-
-====Arc Radius====
-When selected, the corners will be filleted with an arc using the gcode radius form.
-
-====Arc Segment====
-When selected, the corners will be filleted with an arc composed of several segments.
-
-====Bevel====
-When selected, the corners will be beveled.
-
-===Corner Feed Rate Multiplier===
-Default: 1.0
-
-Defines the ratio of the feed rate in corners over the original feed rate.  With a high value the extruder will move quickly in corners, accelerating quickly and leaving a thin extrusion.  With a low value, the extruder will move slowly in corners, accelerating gently and leaving a thick extrusion.
-
-===Fillet Radius over Perimeter Width===
-Default is 0.35.
-
-Defines the width of the fillet.
-
-===Reversal Slowdown over Perimeter Width===
-Default is 0.5.
-
-Defines how far before a path reversal the extruder will slow down.  Some tools, like nozzle wipe, double back the path of the extruder and this option will add a slowdown point in that path so there won't be a sudden jerk at the end of the path.  If the value is less than 0.1 a slowdown will not be added.
-
-===Use Intermediate Feed Rate in Corners===
-Default is on.
-
-When selected, the feed rate entering the corner will be the average of the old feed rate and the new feed rate.
-
-==Examples==
-The following examples fillet the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and fillet.py.
-
-> python fillet.py
-This brings up the fillet dialog.
-
-> python fillet.py Screw Holder Bottom.stl
-The fillet tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The fillet tool has created the file:
-.. Screw Holder Bottom_fillet.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import math
-import sys
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, gcodeText, repository = None ):
-       "Fillet a gcode linear move file or text."
-       return getCraftedTextFromText( archive.getTextIfEmpty( fileName, gcodeText ), repository )
-
-def getCraftedTextFromText( gcodeText, repository = None ):
-       "Fillet a gcode linear move text."
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'fillet'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository( FilletRepository() )
-       if not repository.activateFillet.value:
-               return gcodeText
-       if repository.arcPoint.value:
-               return ArcPointSkein().getCraftedGcode( repository, gcodeText )
-       elif repository.arcRadius.value:
-               return ArcRadiusSkein().getCraftedGcode( repository, gcodeText )
-       elif repository.arcSegment.value:
-               return ArcSegmentSkein().getCraftedGcode( repository, gcodeText )
-       elif repository.bevel.value:
-               return BevelSkein().getCraftedGcode( repository, gcodeText )
-       return gcodeText
-
-def getNewRepository():
-       'Get new repository.'
-       return FilletRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Fillet a gcode linear move file. Depending on the settings, either arcPoint, arcRadius, arcSegment, bevel or do nothing."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'fillet', shouldAnalyze)
-
-
-class BevelSkein(object):
-       "A class to bevel a skein of extrusions."
-       def __init__(self):
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.extruderActive = False
-               self.feedRateMinute = 960.0
-               self.filletRadius = 0.2
-               self.lineIndex = 0
-               self.lines = None
-               self.oldFeedRateMinute = None
-               self.oldLocation = None
-               self.shouldAddLine = True
-
-       def addLinearMovePoint( self, feedRateMinute, point ):
-               "Add a gcode linear move, feedRate and newline to the output."
-               self.distanceFeedRate.addLine( self.distanceFeedRate.getLinearGcodeMovementWithFeedRate( feedRateMinute, point.dropAxis(), point.z ) )
-
-       def getCornerFeedRate(self):
-               "Get the corner feed rate, which may be based on the intermediate feed rate."
-               feedRateMinute = self.feedRateMinute
-               if self.repository.useIntermediateFeedRateInCorners.value:
-                       if self.oldFeedRateMinute != None:
-                               feedRateMinute = 0.5 * ( self.oldFeedRateMinute + self.feedRateMinute )
-               return feedRateMinute * self.cornerFeedRateMultiplier
-
-       def getCraftedGcode( self, repository, gcodeText ):
-               "Parse gcode text and store the bevel gcode."
-               self.cornerFeedRateMultiplier = repository.cornerFeedRateMultiplier.value
-               self.lines = archive.getTextLines(gcodeText)
-               self.repository = repository
-               self.parseInitialization( repository )
-               for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def getExtruderOffReversalPoint( self, afterSegment, afterSegmentComplex, beforeSegment, beforeSegmentComplex, location ):
-               "If the extruder is off and the path is reversing, add intermediate slow points."
-               if self.repository.reversalSlowdownDistanceOverEdgeWidth.value < 0.1:
-                       return None
-               if self.extruderActive:
-                       return None
-               reversalBufferSlowdownDistance = self.reversalSlowdownDistance * 2.0
-               afterSegmentComplexLength = abs( afterSegmentComplex )
-               if afterSegmentComplexLength < reversalBufferSlowdownDistance:
-                       return None
-               beforeSegmentComplexLength = abs( beforeSegmentComplex )
-               if beforeSegmentComplexLength < reversalBufferSlowdownDistance:
-                       return None
-               afterSegmentComplexNormalized = afterSegmentComplex / afterSegmentComplexLength
-               beforeSegmentComplexNormalized = beforeSegmentComplex / beforeSegmentComplexLength
-               if euclidean.getDotProduct( afterSegmentComplexNormalized, beforeSegmentComplexNormalized ) < 0.95:
-                       return None
-               slowdownFeedRate = self.feedRateMinute * 0.5
-               self.shouldAddLine = False
-               beforePoint = euclidean.getPointPlusSegmentWithLength( self.reversalSlowdownDistance * abs( beforeSegment ) / beforeSegmentComplexLength, location, beforeSegment )
-               self.addLinearMovePoint( self.feedRateMinute, beforePoint )
-               self.addLinearMovePoint( slowdownFeedRate, location )
-               afterPoint = euclidean.getPointPlusSegmentWithLength( self.reversalSlowdownDistance * abs( afterSegment ) / afterSegmentComplexLength, location, afterSegment )
-               self.addLinearMovePoint( slowdownFeedRate, afterPoint )
-               return afterPoint
-
-       def getNextLocation(self):
-               "Get the next linear move.  Return none is none is found."
-               for afterIndex in xrange( self.lineIndex + 1, len(self.lines) ):
-                       line = self.lines[ afterIndex ]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       if gcodec.getFirstWord(splitLine) == 'G1':
-                               nextLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-                               return nextLocation
-               return None
-
-       def linearMove( self, splitLine ):
-               "Bevel a linear move."
-               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               self.feedRateMinute = gcodec.getFeedRateMinute( self.feedRateMinute, splitLine )
-               if self.oldLocation != None:
-                       nextLocation = self.getNextLocation()
-                       if nextLocation != None:
-                               location = self.splitPointGetAfter( location, nextLocation )
-               self.oldLocation = location
-               self.oldFeedRateMinute = self.feedRateMinute
-
-       def parseInitialization( self, repository ):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('fillet')
-                               return
-                       elif firstWord == '(<edgeWidth>':
-                               edgeWidth = abs(float(splitLine[1]))
-                               self.curveSection = 0.7 * edgeWidth
-                               self.filletRadius = edgeWidth * repository.filletRadiusOverEdgeWidth.value
-                               self.minimumRadius = 0.1 * edgeWidth
-                               self.reversalSlowdownDistance = edgeWidth * repository.reversalSlowdownDistanceOverEdgeWidth.value
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               "Parse a gcode line and add it to the bevel gcode."
-               self.shouldAddLine = True
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       self.linearMove(splitLine)
-               elif firstWord == 'M101':
-                       self.extruderActive = True
-               elif firstWord == 'M103':
-                       self.extruderActive = False
-               if self.shouldAddLine:
-                       self.distanceFeedRate.addLine(line)
-
-       def splitPointGetAfter( self, location, nextLocation ):
-               "Bevel a point and return the end of the bevel.   should get complex for radius"
-               if self.filletRadius < 2.0 * self.minimumRadius:
-                       return location
-               afterSegment = nextLocation - location
-               afterSegmentComplex = afterSegment.dropAxis()
-               afterSegmentComplexLength = abs( afterSegmentComplex )
-               thirdAfterSegmentLength = 0.333 * afterSegmentComplexLength
-               if thirdAfterSegmentLength < self.minimumRadius:
-                       return location
-               beforeSegment = self.oldLocation - location
-               beforeSegmentComplex = beforeSegment.dropAxis()
-               beforeSegmentComplexLength = abs( beforeSegmentComplex )
-               thirdBeforeSegmentLength = 0.333 * beforeSegmentComplexLength
-               if thirdBeforeSegmentLength < self.minimumRadius:
-                       return location
-               extruderOffReversalPoint = self.getExtruderOffReversalPoint( afterSegment, afterSegmentComplex, beforeSegment, beforeSegmentComplex, location )
-               if extruderOffReversalPoint != None:
-                       return extruderOffReversalPoint
-               bevelRadius = min( thirdAfterSegmentLength, self.filletRadius )
-               bevelRadius = min( thirdBeforeSegmentLength, bevelRadius )
-               self.shouldAddLine = False
-               beforePoint = euclidean.getPointPlusSegmentWithLength( bevelRadius * abs( beforeSegment ) / beforeSegmentComplexLength, location, beforeSegment )
-               self.addLinearMovePoint( self.feedRateMinute, beforePoint )
-               afterPoint = euclidean.getPointPlusSegmentWithLength( bevelRadius * abs( afterSegment ) / afterSegmentComplexLength, location, afterSegment )
-               self.addLinearMovePoint( self.getCornerFeedRate(), afterPoint )
-               return afterPoint
-
-
-class ArcSegmentSkein( BevelSkein ):
-       "A class to arc segment a skein of extrusions."
-       def addArc( self, afterCenterDifferenceAngle, afterPoint, beforeCenterSegment, beforePoint, center ):
-               "Add arc segments to the filleted skein."
-               absoluteDifferenceAngle = abs( afterCenterDifferenceAngle )
-#              steps = int( math.ceil( absoluteDifferenceAngle * 1.5 ) )
-               steps = int( math.ceil( min( absoluteDifferenceAngle * 1.5, absoluteDifferenceAngle * abs( beforeCenterSegment ) / self.curveSection ) ) )
-               stepPlaneAngle = euclidean.getWiddershinsUnitPolar( afterCenterDifferenceAngle / steps )
-               for step in xrange( 1, steps ):
-                       beforeCenterSegment = euclidean.getRoundZAxisByPlaneAngle( stepPlaneAngle, beforeCenterSegment )
-                       arcPoint = center + beforeCenterSegment
-                       self.addLinearMovePoint( self.getCornerFeedRate(), arcPoint )
-               self.addLinearMovePoint( self.getCornerFeedRate(), afterPoint )
-
-       def splitPointGetAfter( self, location, nextLocation ):
-               "Fillet a point into arc segments and return the end of the last segment."
-               if self.filletRadius < 2.0 * self.minimumRadius:
-                       return location
-               afterSegment = nextLocation - location
-               afterSegmentComplex = afterSegment.dropAxis()
-               thirdAfterSegmentLength = 0.333 * abs( afterSegmentComplex )
-               if thirdAfterSegmentLength < self.minimumRadius:
-                       return location
-               beforeSegment = self.oldLocation - location
-               beforeSegmentComplex = beforeSegment.dropAxis()
-               thirdBeforeSegmentLength = 0.333 * abs( beforeSegmentComplex )
-               if thirdBeforeSegmentLength < self.minimumRadius:
-                       return location
-               extruderOffReversalPoint = self.getExtruderOffReversalPoint( afterSegment, afterSegmentComplex, beforeSegment, beforeSegmentComplex, location )
-               if extruderOffReversalPoint != None:
-                       return extruderOffReversalPoint
-               bevelRadius = min( thirdAfterSegmentLength, self.filletRadius )
-               bevelRadius = min( thirdBeforeSegmentLength, bevelRadius )
-               self.shouldAddLine = False
-               beforePoint = euclidean.getPointPlusSegmentWithLength( bevelRadius * abs( beforeSegment ) / abs( beforeSegmentComplex ), location, beforeSegment )
-               self.addLinearMovePoint( self.feedRateMinute, beforePoint )
-               afterPoint = euclidean.getPointPlusSegmentWithLength( bevelRadius * abs( afterSegment ) / abs( afterSegmentComplex ), location, afterSegment )
-               afterPointComplex = afterPoint.dropAxis()
-               beforePointComplex = beforePoint.dropAxis()
-               locationComplex = location.dropAxis()
-               midpoint = 0.5 * ( afterPoint + beforePoint )
-               midpointComplex = midpoint.dropAxis()
-               midpointMinusLocationComplex = midpointComplex - locationComplex
-               midpointLocationLength = abs( midpointMinusLocationComplex )
-               if midpointLocationLength < 0.01 * self.filletRadius:
-                       self.addLinearMovePoint( self.getCornerFeedRate(), afterPoint )
-                       return afterPoint
-               midpointAfterPointLength = abs( midpointComplex - afterPointComplex )
-               midpointCenterLength = midpointAfterPointLength * midpointAfterPointLength / midpointLocationLength
-               radius = math.sqrt( midpointCenterLength * midpointCenterLength + midpointAfterPointLength * midpointAfterPointLength )
-               centerComplex = midpointComplex + midpointMinusLocationComplex * midpointCenterLength / midpointLocationLength
-               center = Vector3( centerComplex.real, centerComplex.imag, midpoint.z )
-               afterCenterComplex = afterPointComplex - centerComplex
-               beforeCenter = beforePoint - center
-               angleDifference = euclidean.getAngleDifferenceByComplex( afterCenterComplex, beforeCenter.dropAxis() )
-               self.addArc( angleDifference, afterPoint, beforeCenter, beforePoint, center )
-               return afterPoint
-
-
-class ArcPointSkein( ArcSegmentSkein ):
-       "A class to arc point a skein of extrusions."
-       def addArc( self, afterCenterDifferenceAngle, afterPoint, beforeCenterSegment, beforePoint, center ):
-               "Add an arc point to the filleted skein."
-               if afterCenterDifferenceAngle == 0.0:
-                       return
-               afterPointMinusBefore = afterPoint - beforePoint
-               centerMinusBefore = center - beforePoint
-               firstWord = 'G3'
-               if afterCenterDifferenceAngle < 0.0:
-                       firstWord = 'G2'
-               centerMinusBeforeComplex = centerMinusBefore.dropAxis()
-               if abs( centerMinusBeforeComplex ) <= 0.0:
-                       return
-               radius = abs( centerMinusBefore )
-               arcDistanceZ = complex( abs( afterCenterDifferenceAngle ) * radius, afterPointMinusBefore.z )
-               distance = abs( arcDistanceZ )
-               if distance <= 0.0:
-                       return
-               line = self.distanceFeedRate.getFirstWordMovement( firstWord, afterPoint ) + self.getRelativeCenter( centerMinusBeforeComplex )
-               cornerFeedRate = self.getCornerFeedRate()
-               if cornerFeedRate != None:
-                       line += ' F' + self.distanceFeedRate.getRounded(cornerFeedRate)
-               self.distanceFeedRate.addLine(line)
-
-       def getRelativeCenter( self, centerMinusBeforeComplex ):
-               "Get the relative center."
-               return ' I%s J%s' % ( self.distanceFeedRate.getRounded( centerMinusBeforeComplex.real ), self.distanceFeedRate.getRounded( centerMinusBeforeComplex.imag ) )
-
-
-class ArcRadiusSkein( ArcPointSkein ):
-       "A class to arc radius a skein of extrusions."
-       def getRelativeCenter( self, centerMinusBeforeComplex ):
-               "Get the relative center."
-               radius = abs( centerMinusBeforeComplex )
-               return ' R' + ( self.distanceFeedRate.getRounded(radius) )
-
-
-class FilletRepository(object):
-       "A class to handle the fillet settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.fillet.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File to be Filleted', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Fillet')
-               self.activateFillet = settings.BooleanSetting().getFromValue('Activate Fillet', self, False )
-               self.filletProcedureChoiceLabel = settings.LabelDisplay().getFromName('Fillet Procedure Choice: ', self )
-               filletLatentStringVar = settings.LatentStringVar()
-               self.arcPoint = settings.Radio().getFromRadio( filletLatentStringVar, 'Arc Point', self, False )
-               self.arcRadius = settings.Radio().getFromRadio( filletLatentStringVar, 'Arc Radius', self, False )
-               self.arcSegment = settings.Radio().getFromRadio( filletLatentStringVar, 'Arc Segment', self, False )
-               self.bevel = settings.Radio().getFromRadio( filletLatentStringVar, 'Bevel', self, True )
-               self.cornerFeedRateMultiplier = settings.FloatSpin().getFromValue(0.8, 'Corner Feed Rate Multiplier (ratio):', self, 1.2, 1.0)
-               self.filletRadiusOverEdgeWidth = settings.FloatSpin().getFromValue( 0.25, 'Fillet Radius over Perimeter Width (ratio):', self, 0.65, 0.35 )
-               self.reversalSlowdownDistanceOverEdgeWidth = settings.FloatSpin().getFromValue( 0.3, 'Reversal Slowdown Distance over Perimeter Width (ratio):', self, 0.7, 0.5 )
-               self.useIntermediateFeedRateInCorners = settings.BooleanSetting().getFromValue('Use Intermediate Feed Rate in Corners', self, True )
-               self.executeTitle = 'Fillet'
-
-       def execute(self):
-               "Fillet button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-def main():
-       "Display the fillet dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/flow.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/flow.py
deleted file mode 100644 (file)
index 8eda2a7..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-"""
-This page is in the table of contents.
-The flow script sets the flow rate by writing the M108 gcode.
-
-==Operation==
-The default 'Activate Flow' checkbox is on.  When it is on, the functions described below will work, when it is off, the functions will not be called.
-
-==Settings==
-===Flow Rate===
-Default is 210.
-
-Defines the flow rate which will be written following the M108 command.  The flow rate is usually a PWM setting, but could be anything, like the rpm of the tool or the duty cycle of the tool.
-
-==Examples==
-The following examples flow the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and flow.py.
-
-> python flow.py
-This brings up the flow dialog.
-
-> python flow.py Screw Holder Bottom.stl
-The flow tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The flow tool has created the file:
-.. Screw Holder Bottom_flow.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, text='', flowRepository = None ):
-       "Flow the file or text."
-       return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), flowRepository )
-
-def getCraftedTextFromText( gcodeText, flowRepository = None ):
-       "Flow a gcode linear move text."
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'flow'):
-               return gcodeText
-       if flowRepository == None:
-               flowRepository = settings.getReadRepository( FlowRepository() )
-       if not flowRepository.activateFlow.value:
-               return gcodeText
-       return FlowSkein().getCraftedGcode( gcodeText, flowRepository )
-
-def getNewRepository():
-       'Get new repository.'
-       return FlowRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Flow a gcode linear move file."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'flow', shouldAnalyze)
-
-
-class FlowRepository(object):
-       "A class to handle the flow settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.flow.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Flow', self, '')
-               self.activateFlow = settings.BooleanSetting().getFromValue('Activate Flow', self, True )
-               self.flowRate = settings.FloatSpin().getFromValue( 50.0, 'Flow Rate (arbitrary units):', self, 250.0, 210.0 )
-               self.executeTitle = 'Flow'
-
-       def execute(self):
-               "Flow button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class FlowSkein(object):
-       "A class to flow a skein of extrusions."
-       def __init__(self):
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.lineIndex = 0
-               self.lines = None
-               self.oldFlowRate = None
-               self.oldLocation = None
-
-       def addFlowRateLine(self):
-               "Add flow rate line."
-               flowRate = self.flowRepository.flowRate.value
-               if flowRate != self.oldFlowRate:
-                       self.distanceFeedRate.addLine('M108 S' + euclidean.getFourSignificantFigures(flowRate))
-               self.oldFlowRate = flowRate
-
-       def getCraftedGcode( self, gcodeText, flowRepository ):
-               "Parse gcode text and store the flow gcode."
-               self.flowRepository = flowRepository
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization()
-               for line in self.lines[self.lineIndex :]:
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('flow')
-                               return
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               "Parse a gcode line and add it to the flow skein."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1' or firstWord == '(<layer>':
-                       self.addFlowRateLine()
-               self.distanceFeedRate.addLine(line)
-
-
-def main():
-       "Display the flow dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/home.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/home.py
deleted file mode 100644 (file)
index c9bb623..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-"""
-This page is in the table of contents.
-Plugin to home the tool at beginning of each layer.
-
-The home manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Home
-
-==Operation==
-The default 'Activate Home' checkbox is on.  When it is on, the functions described below will work, when it is off, nothing will be done.
-
-==Settings==
-===Name of Home File===
-Default: home.gcode
-
-At the beginning of a each layer, home will add the commands of a gcode script with the name of the "Name of Home File" setting, if one exists.  Home does not care if the text file names are capitalized, but some file systems do not handle file name cases properly, so to be on the safe side you should give them lower case names.  Home looks for those files in the alterations folder in the .skeinforge folder in the home directory. If it doesn't find the file it then looks in the alterations folder in the skeinforge_plugins folder.
-
-==Examples==
-The following examples home the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and home.py.
-
-> python home.py
-This brings up the home dialog.
-
-> python home.py Screw Holder Bottom.stl
-The home tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The home tool has created the file:
-.. Screw Holder Bottom_home.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, text, repository = None ):
-       "Home a gcode linear move file or text."
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository)
-
-def getCraftedTextFromText( gcodeText, repository = None ):
-       "Home a gcode linear move text."
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'home'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository( HomeRepository() )
-       if not repository.activateHome.value:
-               return gcodeText
-       return HomeSkein().getCraftedGcode(gcodeText, repository)
-
-def getNewRepository():
-       'Get new repository.'
-       return HomeRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Home a gcode linear move file.  Chain home the gcode if it is not already homed."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'home', shouldAnalyze)
-
-
-class HomeRepository(object):
-       "A class to handle the home settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.home.html', self)
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Home', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Home')
-               self.activateHome = settings.BooleanSetting().getFromValue('Activate Home', self, False )
-               self.nameOfHomeFile = settings.StringSetting().getFromValue('Name of Home File:', self, 'home.gcode')
-               self.executeTitle = 'Home'
-       def execute(self):
-               "Home button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class HomeSkein(object):
-       "A class to home a skein of extrusions."
-       def __init__(self):
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.extruderActive = False
-               self.highestZ = None
-               self.homeLines = []
-               self.layerCount = settings.LayerCount()
-               self.lineIndex = 0
-               self.lines = None
-               self.oldLocation = None
-               self.shouldHome = False
-               self.travelFeedRateMinute = 957.0
-
-       def addFloat( self, begin, end ):
-               "Add dive to the original height."
-               beginEndDistance = begin.distance(end)
-               alongWay = self.absoluteEdgeWidth / beginEndDistance
-               closeToEnd = euclidean.getIntermediateLocation( alongWay, end, begin )
-               closeToEnd.z = self.highestZ
-               self.distanceFeedRate.addLine( self.distanceFeedRate.getLinearGcodeMovementWithFeedRate( self.travelFeedRateMinute, closeToEnd.dropAxis(), closeToEnd.z ) )
-
-       def addHomeTravel( self, splitLine ):
-               "Add the home travel gcode."
-               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               self.highestZ = max( self.highestZ, location.z )
-               if not self.shouldHome:
-                       return
-               self.shouldHome = False
-               if self.oldLocation == None:
-                       return
-               if self.extruderActive:
-                       self.distanceFeedRate.addLine('M103')
-               self.addHopUp( self.oldLocation )
-               self.distanceFeedRate.addLinesSetAbsoluteDistanceMode(self.homeLines)
-               self.addHopUp( self.oldLocation )
-               self.addFloat( self.oldLocation, location )
-               if self.extruderActive:
-                       self.distanceFeedRate.addLine('M101')
-
-       def addHopUp(self, location):
-               "Add hop to highest point."
-               locationUp = Vector3( location.x, location.y, self.highestZ )
-               self.distanceFeedRate.addLine( self.distanceFeedRate.getLinearGcodeMovementWithFeedRate( self.travelFeedRateMinute, locationUp.dropAxis(), locationUp.z ) )
-
-       def getCraftedGcode( self, gcodeText, repository ):
-               "Parse gcode text and store the home gcode."
-               self.repository = repository
-               self.homeLines = settings.getAlterationFileLines(repository.nameOfHomeFile.value)
-               if len(self.homeLines) < 1:
-                       return gcodeText
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization( repository )
-               for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def parseInitialization( self, repository ):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('home')
-                               return
-                       elif firstWord == '(<edgeWidth>':
-                               self.absoluteEdgeWidth = abs(float(splitLine[1]))
-                       elif firstWord == '(<travelFeedRatePerSecond>':
-                               self.travelFeedRateMinute = 60.0 * float(splitLine[1])
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               "Parse a gcode line and add it to the bevel gcode."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       self.addHomeTravel(splitLine)
-                       self.oldLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               elif firstWord == '(<layer>':
-                       self.layerCount.printProgressIncrement('home')
-                       if len(self.homeLines) > 0:
-                               self.shouldHome = True
-               elif firstWord == 'M101':
-                       self.extruderActive = True
-               elif firstWord == 'M103':
-                       self.extruderActive = False
-               self.distanceFeedRate.addLine(line)
-
-
-def main():
-       "Display the home dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/hop.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/hop.py
deleted file mode 100644 (file)
index 53a77f0..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-"""
-This page is in the table of contents.
-Hop is a script to raise the extruder when it is not extruding.
-
-Note: 
-
-Note: In some cases where you have thin overhang this plugin can help solve the problem object being knocked off by the head
-
-The hop manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Hop
-
-==Operation==
-The default 'Activate Hop' checkbox is off.
-
-It is off because Vik and Nophead found better results without hopping.  Numerous users reported better output without this plugin hence it is off by default.  
-
-When activated the extruder will hop when traveling.  When it is off, nothing will be done.
-
-==Settings==
-===Hop Over Layer Thickness===
-Default is one.
-
-Defines the ratio of the hop height over the layer height, this is the most important hop setting.
-
-===Minimum Hop Angle===
-Default is 20 degrees.
-
-Defines the minimum angle that the path of the extruder will be raised.  An angle of ninety means that the extruder will go straight up as soon as it is not extruding and a low angle means the extruder path will gradually rise to the hop height.
-
-==Examples==
-The following examples hop the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and hop.py.
-
-> python hop.py
-This brings up the hop dialog.
-
-> python hop.py Screw Holder Bottom.stl
-The hop tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The hop tool has created the file:
-.. Screw Holder Bottom_hop.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import math
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, text, hopRepository = None ):
-       "Hop a gcode linear move text."
-       return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), hopRepository )
-
-def getCraftedTextFromText( gcodeText, hopRepository = None ):
-       "Hop a gcode linear move text."
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'hop'):
-               return gcodeText
-       if hopRepository == None:
-               hopRepository = settings.getReadRepository( HopRepository() )
-       if not hopRepository.activateHop.value:
-               return gcodeText
-       return HopSkein().getCraftedGcode( gcodeText, hopRepository )
-
-def getNewRepository():
-       'Get new repository.'
-       return HopRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Hop a gcode linear move file.  Chain hop the gcode if it is not already hopped."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'hop', shouldAnalyze)
-
-
-class HopRepository(object):
-       "A class to handle the hop settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.hop.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Hop', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Hop')
-               self.activateHop = settings.BooleanSetting().getFromValue('Activate Hop', self, False )
-               self.hopOverLayerThickness = settings.FloatSpin().getFromValue( 0.5, 'Hop Over Layer Thickness (ratio):', self, 1.5, 1.0 )
-               self.minimumHopAngle = settings.FloatSpin().getFromValue( 20.0, 'Minimum Hop Angle (degrees):', self, 60.0, 30.0 )
-               self.executeTitle = 'Hop'
-
-       def execute(self):
-               "Hop button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class HopSkein(object):
-       "A class to hop a skein of extrusions."
-       def __init__(self):
-               'Initialize'
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.extruderActive = False
-               self.feedRateMinute = 961.0
-               self.hopHeight = 0.4
-               self.hopDistance = self.hopHeight
-               self.justDeactivated = False
-               self.layerCount = settings.LayerCount()
-               self.lineIndex = 0
-               self.lines = None
-               self.oldLocation = None
-
-       def getCraftedGcode( self, gcodeText, hopRepository ):
-               "Parse gcode text and store the hop gcode."
-               self.lines = archive.getTextLines(gcodeText)
-               self.minimumSlope = math.tan( math.radians( hopRepository.minimumHopAngle.value ) )
-               self.parseInitialization( hopRepository )
-               for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def getHopLine(self, line):
-               "Get hopped gcode line."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               self.feedRateMinute = gcodec.getFeedRateMinute( self.feedRateMinute, splitLine )
-               if self.extruderActive:
-                       return line
-               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               highestZ = location.z
-               if self.oldLocation != None:
-                       highestZ = max( highestZ, self.oldLocation.z )
-               highestZHop = highestZ + self.hopHeight
-               locationComplex = location.dropAxis()
-               if self.justDeactivated:
-                       oldLocationComplex = self.oldLocation.dropAxis()
-                       distance = abs( locationComplex - oldLocationComplex )
-                       if distance < self.minimumDistance:
-                               if self.isNextTravel() or distance == 0.0:
-                                       return self.distanceFeedRate.getLineWithZ( line, splitLine, highestZHop )
-                       alongRatio = min( 0.41666666, self.hopDistance / distance )
-                       oneMinusAlong = 1.0 - alongRatio
-                       closeLocation = oldLocationComplex * oneMinusAlong + locationComplex * alongRatio
-                       self.distanceFeedRate.addLine( self.distanceFeedRate.getLineWithZ( line, splitLine, highestZHop ) )
-                       if self.isNextTravel():
-                               return self.distanceFeedRate.getLineWithZ( line, splitLine, highestZHop )
-                       farLocation = oldLocationComplex * alongRatio + locationComplex * oneMinusAlong
-                       self.distanceFeedRate.addGcodeMovementZWithFeedRate( self.feedRateMinute, farLocation, highestZHop )
-                       return line
-               if self.isNextTravel():
-                       return self.distanceFeedRate.getLineWithZ( line, splitLine, highestZHop )
-               return line
-
-       def isNextTravel(self):
-               "Determine if there is another linear travel before the thread ends."
-               for afterIndex in xrange( self.lineIndex + 1, len(self.lines) ):
-                       line = self.lines[ afterIndex ]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1':
-                               return True
-                       if firstWord == 'M101':
-                               return False
-               return False
-
-       def parseInitialization( self, hopRepository ):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(<layerHeight>':
-                               layerHeight = float(splitLine[1])
-                               self.hopHeight = hopRepository.hopOverLayerThickness.value * layerHeight
-                               self.hopDistance = self.hopHeight / self.minimumSlope
-                               self.minimumDistance = 0.5 * layerHeight
-                       elif firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('hop')
-                               return
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               "Parse a gcode line and add it to the bevel gcode."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if self.distanceFeedRate.getIsAlteration(line):
-                       return
-               if firstWord == 'G1':
-                       line = self.getHopLine(line)
-                       self.oldLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-                       self.justDeactivated = False
-               elif firstWord == '(<layer>':
-                       self.layerCount.printProgressIncrement('hop')
-               elif firstWord == 'M101':
-                       self.extruderActive = True
-               elif firstWord == 'M103':
-                       self.extruderActive = False
-                       self.justDeactivated = True
-               self.distanceFeedRate.addLineCheckAlteration(line)
-
-
-def main():
-       "Display the hop dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/inset.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/inset.py
deleted file mode 100644 (file)
index 8af333f..0000000
+++ /dev/null
@@ -1,469 +0,0 @@
-#! /usr/bin/env python
-"""
-This page is in the table of contents.
-Inset will inset the outside outlines by half the edge width, and outset the inside outlines by the same amount.
-
-The inset manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Inset
-
-==Settings==
-===Add Custom Code for Temperature Reading===
-Default is on.
-
-When selected, the M105 custom code for temperature reading will be added at the beginning of the file.
-
-===Infill in Direction of Bridge===
-Default is on.
-
-When selected, the infill will be in the direction of any bridge across a gap, so that the fill will be able to span a bridge easier.
-
-===Loop Order Choice===
-Default loop order choice is 'Ascending Area'.
-
-When overlap is to be removed, for each loop, the overlap is checked against the list of loops already extruded.  If the latest loop overlaps an already extruded loop, the overlap is removed from the latest loop.  The loops are ordered according to their areas.
-
-====Ascending Area====
-When selected, the loops will be ordered in ascending area.  With thin walled parts, if overlap is being removed the outside of the container will not be extruded.  Holes will be the correct size.
-
-====Descending Area====
-When selected, the loops will be ordered in descending area.  With thin walled parts, if overlap is being removed the inside of the container will not be extruded.  Holes will be missing the interior wall so they will be slightly wider than model size.
-
-===Overlap Removal Width over Perimeter Width===
-Default is 0.6.
-
-Defines the ratio of the overlap removal width over the edge width.  Any part of the extrusion that comes within the overlap removal width of another is removed.  This is to prevent the extruder from depositing two extrusions right beside each other.  If the 'Overlap Removal Width over Perimeter Width' is less than 0.2, the overlap will not be removed.
-
-===Turn Extruder Heater Off at Shut Down===
-Default is on.
-
-When selected, the M104 S0 gcode line will be added to the end of the file to turn the extruder heater off by setting the extruder heater temperature to 0.
-
-===Volume Fraction===
-Default: 0.82
-
-The 'Volume Fraction' is the estimated volume of the thread compared to the box defined by the layer height and infill width. This is used in dwindle, splodge, and statistic. It is in inset because inset is a required extrusion tool, earlier in the chain than dwindle and splodge. In dwindle and splodge it is used to determine the filament volume, in statistic it is used to determine the extrusion diameter.
-
-==Examples==
-The following examples inset the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and inset.py.
-
-> python inset.py
-This brings up the inset dialog.
-
-> python inset.py Screw Holder Bottom.stl
-The inset tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The inset tool has created the file:
-.. Screw Holder Bottom_inset.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import intercircle
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import cmath
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addAlreadyFilledArounds( alreadyFilledArounds, loop, radius ):
-       "Add already filled loops around loop to alreadyFilledArounds."
-       radius = abs(radius)
-       alreadyFilledLoop = []
-       slightlyGreaterThanRadius = intercircle.globalIntercircleMultiplier * radius
-       muchGreaterThanRadius = 2.5 * radius
-       centers = intercircle.getCentersFromLoop( loop, slightlyGreaterThanRadius )
-       for center in centers:
-               alreadyFilledInset = intercircle.getSimplifiedInsetFromClockwiseLoop( center, radius )
-               if intercircle.isLargeSameDirection( alreadyFilledInset, center, radius ):
-                       alreadyFilledLoop.append( alreadyFilledInset )
-       if len( alreadyFilledLoop ) > 0:
-               alreadyFilledArounds.append( alreadyFilledLoop )
-
-def addSegmentOutline( isThick, outlines, pointBegin, pointEnd, width ):
-       "Add a diamond or hexagonal outline for a line segment."
-       width = abs( width )
-       exclusionWidth = 0.6 * width
-       slope = 0.2
-       if isThick:
-               slope = 3.0
-               exclusionWidth = 0.8 * width
-       segment = pointEnd - pointBegin
-       segmentLength = abs(segment)
-       if segmentLength == 0.0:
-               return
-       normalizedSegment = segment / segmentLength
-       outline = []
-       segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag)
-       pointBeginRotated = segmentYMirror * pointBegin
-       pointEndRotated = segmentYMirror * pointEnd
-       along = 0.05
-       alongLength = along * segmentLength
-       if alongLength > 0.1 * exclusionWidth:
-               along *= 0.1 * exclusionWidth / alongLength
-       alongEnd = 1.0 - along
-       remainingToHalf = 0.5 - along
-       alongToWidth = exclusionWidth / slope / segmentLength
-       pointBeginIntermediate = euclidean.getIntermediateLocation( along, pointBeginRotated, pointEndRotated )
-       pointEndIntermediate = euclidean.getIntermediateLocation( alongEnd, pointBeginRotated, pointEndRotated )
-       outline.append( pointBeginIntermediate )
-       verticalWidth = complex( 0.0, exclusionWidth )
-       if alongToWidth > 0.9 * remainingToHalf:
-               verticalWidth = complex( 0.0, slope * remainingToHalf * segmentLength )
-               middle = ( pointBeginIntermediate + pointEndIntermediate ) * 0.5
-               middleDown = middle - verticalWidth
-               middleUp = middle + verticalWidth
-               outline.append( middleUp )
-               outline.append( pointEndIntermediate )
-               outline.append( middleDown )
-       else:
-               alongOutsideBegin = along + alongToWidth
-               alongOutsideEnd = alongEnd - alongToWidth
-               outsideBeginCenter = euclidean.getIntermediateLocation( alongOutsideBegin, pointBeginRotated, pointEndRotated )
-               outsideBeginCenterDown = outsideBeginCenter - verticalWidth
-               outsideBeginCenterUp = outsideBeginCenter + verticalWidth
-               outsideEndCenter = euclidean.getIntermediateLocation( alongOutsideEnd, pointBeginRotated, pointEndRotated )
-               outsideEndCenterDown = outsideEndCenter - verticalWidth
-               outsideEndCenterUp = outsideEndCenter + verticalWidth
-               outline.append( outsideBeginCenterUp )
-               outline.append( outsideEndCenterUp )
-               outline.append( pointEndIntermediate )
-               outline.append( outsideEndCenterDown )
-               outline.append( outsideBeginCenterDown )
-       outlines.append( euclidean.getRotatedComplexes( normalizedSegment, outline ) )
-
-def getBridgeDirection(belowLoops, layerLoops, radius):
-       'Get span direction for the majority of the overhanging extrusion edge, if any.'
-       if len(belowLoops) < 1:
-               return None
-       belowOutsetLoops = intercircle.getInsetLoopsFromLoops(belowLoops, -radius)
-       bridgeRotation = complex()
-       for loop in layerLoops:
-               for pointIndex, point in enumerate(loop):
-                       previousIndex = (pointIndex + len(loop) - 1) % len(loop)
-                       bridgeRotation += getOverhangDirection(belowOutsetLoops, loop[previousIndex], point)
-       if abs(bridgeRotation) < 0.75 * radius:
-               return None
-       else:
-               return cmath.sqrt(bridgeRotation / abs(bridgeRotation))
-
-def getCraftedText( fileName, text='', repository=None):
-       "Inset the preface file or text."
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository)
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       "Inset the preface gcode text."
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'inset'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository( InsetRepository() )
-       return InsetSkein().getCraftedGcode(gcodeText, repository)
-
-def getDoubledRoundZ( overhangingSegment, segmentRoundZ ):
-       'Get doubled plane angle around z of the overhanging segment.'
-       endpoint = overhangingSegment[0]
-       roundZ = endpoint.point - endpoint.otherEndpoint.point
-       roundZ *= segmentRoundZ
-       if abs( roundZ ) == 0.0:
-               return complex()
-       if roundZ.real < 0.0:
-               roundZ *= - 1.0
-       roundZLength = abs( roundZ )
-       return roundZ * roundZ / roundZLength
-
-def getInteriorSegments(loops, segments):
-       'Get segments inside the loops.'
-       interiorSegments = []
-       for segment in segments:
-               center = 0.5 * (segment[0].point + segment[1].point)
-               if euclidean.getIsInFilledRegion(loops, center):
-                       interiorSegments.append(segment)
-       return interiorSegments
-
-def getIsIntersectingWithinList(loop, loopList):
-       "Determine if the loop is intersecting or is within the loop list."
-       leftPoint = euclidean.getLeftPoint(loop)
-       for otherLoop in loopList:
-               if euclidean.getNumberOfIntersectionsToLeft(otherLoop, leftPoint) % 2 == 1:
-                       return True
-       return euclidean.isLoopIntersectingLoops(loop, loopList)
-
-def getNewRepository():
-       'Get new repository.'
-       return InsetRepository()
-
-def getOverhangDirection( belowOutsetLoops, segmentBegin, segmentEnd ):
-       'Add to span direction from the endpoint segments which overhang the layer below.'
-       segment = segmentEnd - segmentBegin
-       normalizedSegment = euclidean.getNormalized( complex( segment.real, segment.imag ) )
-       segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag)
-       segmentBegin = segmentYMirror * segmentBegin
-       segmentEnd = segmentYMirror * segmentEnd
-       solidXIntersectionList = []
-       y = segmentBegin.imag
-       solidXIntersectionList.append( euclidean.XIntersectionIndex( - 1.0, segmentBegin.real ) )
-       solidXIntersectionList.append( euclidean.XIntersectionIndex( - 1.0, segmentEnd.real ) )
-       for belowLoopIndex in xrange( len( belowOutsetLoops ) ):
-               belowLoop = belowOutsetLoops[ belowLoopIndex ]
-               rotatedOutset = euclidean.getRotatedComplexes( segmentYMirror, belowLoop )
-               euclidean.addXIntersectionIndexesFromLoopY( rotatedOutset, belowLoopIndex, solidXIntersectionList, y )
-       overhangingSegments = euclidean.getSegmentsFromXIntersectionIndexes( solidXIntersectionList, y )
-       overhangDirection = complex()
-       for overhangingSegment in overhangingSegments:
-               overhangDirection += getDoubledRoundZ( overhangingSegment, normalizedSegment )
-       return overhangDirection
-
-def getSegmentsFromLoopListsPoints( loopLists, pointBegin, pointEnd ):
-       "Get endpoint segments from the beginning and end of a line segment."
-       normalizedSegment = pointEnd - pointBegin
-       normalizedSegmentLength = abs( normalizedSegment )
-       if normalizedSegmentLength == 0.0:
-               return []
-       normalizedSegment /= normalizedSegmentLength
-       segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag)
-       pointBeginRotated = segmentYMirror * pointBegin
-       pointEndRotated = segmentYMirror * pointEnd
-       rotatedLoopLists = []
-       for loopList in loopLists:
-               rotatedLoopLists.append(euclidean.getRotatedComplexLists(segmentYMirror, loopList))
-       xIntersectionIndexList = []
-       xIntersectionIndexList.append( euclidean.XIntersectionIndex( - 1, pointBeginRotated.real ) )
-       xIntersectionIndexList.append( euclidean.XIntersectionIndex( - 1, pointEndRotated.real ) )
-       euclidean.addXIntersectionIndexesFromLoopListsY( rotatedLoopLists, xIntersectionIndexList, pointBeginRotated.imag )
-       segments = euclidean.getSegmentsFromXIntersectionIndexes( xIntersectionIndexList, pointBeginRotated.imag )
-       for segment in segments:
-               for endpoint in segment:
-                       endpoint.point *= normalizedSegment
-       return segments
-
-def isCloseToLast( paths, point, radius ):
-       "Determine if the point is close to the last point of the last path."
-       if len(paths) < 1:
-               return False
-       lastPath = paths[-1]
-       return abs( lastPath[-1] - point ) < radius
-
-def isIntersectingItself( loop, width ):
-       "Determine if the loop is intersecting itself."
-       outlines = []
-       for pointIndex in xrange(len(loop)):
-               pointBegin = loop[pointIndex]
-               pointEnd = loop[(pointIndex + 1) % len(loop)]
-               if euclidean.isLineIntersectingLoops( outlines, pointBegin, pointEnd ):
-                       return True
-               addSegmentOutline( False, outlines, pointBegin, pointEnd, width )
-       return False
-
-def isIntersectingWithinLists( loop, loopLists ):
-       "Determine if the loop is intersecting or is within the loop lists."
-       for loopList in loopLists:
-               if getIsIntersectingWithinList( loop, loopList ):
-                       return True
-       return False
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Inset the carving of a gcode file."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'inset', shouldAnalyze)
-
-
-class InsetRepository(object):
-       "A class to handle the inset settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.inset.html', self)
-               self.baseNameSynonymDictionary = {
-                       'Infill in Direction of Bridge' : 'carve.csv',
-                       'Infill Width over Thickness (ratio):' : 'fill.csv'}
-               self.fileNameInput = settings.FileNameInput().getFromFileName(fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Inset', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Inset')
-               self.addCustomCodeForTemperatureReading = settings.BooleanSetting().getFromValue('Add Custom Code for Temperature Reading', self, True)
-               self.infillInDirectionOfBridge = settings.BooleanSetting().getFromValue('Infill in Direction of Bridge', self, True)
-               self.infillWidth = settings.FloatSpin().getFromValue(0.1, 'Infill Width:', self, 1.7, 0.4)
-               self.loopOrderChoice = settings.MenuButtonDisplay().getFromName('Loop Order Choice:', self )
-               self.loopOrderAscendingArea = settings.MenuRadio().getFromMenuButtonDisplay(self.loopOrderChoice, 'Ascending Area', self, True)
-               self.loopOrderDescendingArea = settings.MenuRadio().getFromMenuButtonDisplay(self.loopOrderChoice, 'Descending Area', self, False)
-               self.overlapRemovalWidthOverEdgeWidth = settings.FloatSpin().getFromValue(0.3, 'Overlap Removal Width over Perimeter Width (ratio):', self, 0.9, 0.6)
-               self.turnExtruderHeaterOffAtShutDown = settings.BooleanSetting().getFromValue('Turn Extruder Heater Off at Shut Down', self, True)
-               self.volumeFraction = settings.FloatSpin().getFromValue(0.7, 'Volume Fraction (ratio):', self, 0.9, 0.82)
-               self.executeTitle = 'Inset'
-
-       def execute(self):
-               "Inset button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class InsetSkein(object):
-       "A class to inset a skein of extrusions."
-       def __init__(self):
-               'Initialize.'
-               self.belowLoops = []
-               self.boundary = None
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.layerCount = settings.LayerCount()
-               self.lineIndex = 0
-               self.loopLayer = None
-
-       def addGcodeFromPerimeterPaths(self, isIntersectingSelf, loop, loopLayer, loopLists, radius):
-               "Add the edge paths to the output."
-               segments = []
-               outlines = []
-               thickOutlines = []
-               allLoopLists = loopLists[:] + [thickOutlines]
-               aroundLists = loopLists
-               for pointIndex in xrange(len(loop)):
-                       pointBegin = loop[pointIndex]
-                       pointEnd = loop[(pointIndex + 1) % len(loop)]
-                       if isIntersectingSelf:
-                               if euclidean.isLineIntersectingLoops(outlines, pointBegin, pointEnd):
-                                       segments += getSegmentsFromLoopListsPoints(allLoopLists, pointBegin, pointEnd)
-                               else:
-                                       segments += getSegmentsFromLoopListsPoints(loopLists, pointBegin, pointEnd)
-                               addSegmentOutline(False, outlines, pointBegin, pointEnd, self.overlapRemovalWidth)
-                               addSegmentOutline(True, thickOutlines, pointBegin, pointEnd, self.overlapRemovalWidth)
-                       else:
-                               segments += getSegmentsFromLoopListsPoints(loopLists, pointBegin, pointEnd)
-               edgePaths = []
-               path = []
-               muchSmallerThanRadius = 0.1 * radius
-               segments = getInteriorSegments(loopLayer.loops, segments)
-               for segment in segments:
-                       pointBegin = segment[0].point
-                       if not isCloseToLast(edgePaths, pointBegin, muchSmallerThanRadius):
-                               path = [pointBegin]
-                               edgePaths.append(path)
-                       path.append(segment[1].point)
-               if len(edgePaths) > 1:
-                       firstPath = edgePaths[0]
-                       lastPath = edgePaths[-1]
-                       if abs(lastPath[-1] - firstPath[0]) < 0.1 * muchSmallerThanRadius:
-                               connectedBeginning = lastPath[: -1] + firstPath
-                               edgePaths[0] = connectedBeginning
-                               edgePaths.remove(lastPath)
-               muchGreaterThanRadius = 6.0 * radius
-               for edgePath in edgePaths:
-                       if euclidean.getPathLength(edgePath) > muchGreaterThanRadius:
-                               self.distanceFeedRate.addGcodeFromThreadZ(edgePath, loopLayer.z)
-
-       def addGcodeFromRemainingLoop(self, loop, loopLayer, loopLists, radius):
-               "Add the remainder of the loop which does not overlap the alreadyFilledArounds loops."
-               centerOutset = intercircle.getLargestCenterOutsetLoopFromLoopRegardless(loop, radius)
-               euclidean.addNestedRingBeginning(self.distanceFeedRate, centerOutset.outset, loopLayer.z)
-               self.addGcodePerimeterBlockFromRemainingLoop(centerOutset.center, loopLayer, loopLists, radius)
-               self.distanceFeedRate.addLine('(</boundaryPerimeter>)')
-               self.distanceFeedRate.addLine('(</nestedRing>)')
-
-       def addGcodePerimeterBlockFromRemainingLoop(self, loop, loopLayer, loopLists, radius):
-               "Add the perimter block remainder of the loop which does not overlap the alreadyFilledArounds loops."
-               if self.repository.overlapRemovalWidthOverEdgeWidth.value < 0.2:
-                       self.distanceFeedRate.addPerimeterBlock(loop, loopLayer.z)
-                       return
-               isIntersectingSelf = isIntersectingItself(loop, self.overlapRemovalWidth)
-               if isIntersectingWithinLists(loop, loopLists) or isIntersectingSelf:
-                       self.addGcodeFromPerimeterPaths(isIntersectingSelf, loop, loopLayer, loopLists, radius)
-               else:
-                       self.distanceFeedRate.addPerimeterBlock(loop, loopLayer.z)
-               addAlreadyFilledArounds(loopLists, loop, self.overlapRemovalWidth)
-
-       def addInitializationToOutput(self):
-               "Add initialization gcode to the output."
-               if self.repository.addCustomCodeForTemperatureReading.value:
-                       self.distanceFeedRate.addLine('M105') # Custom code for temperature reading.
-
-       def addInset(self, loopLayer):
-               "Add inset to the layer."
-               alreadyFilledArounds = []
-               extrudateLoops = intercircle.getInsetLoopsFromLoops(loopLayer.loops, self.halfEdgeWidth)
-               if self.repository.infillInDirectionOfBridge.value:
-                       bridgeRotation = getBridgeDirection(self.belowLoops, extrudateLoops, self.halfEdgeWidth)
-                       if bridgeRotation != None:
-                               self.distanceFeedRate.addTagBracketedLine('bridgeRotation', bridgeRotation)
-               self.belowLoops = loopLayer.loops
-               triangle_mesh.sortLoopsInOrderOfArea(not self.repository.loopOrderAscendingArea.value, extrudateLoops)
-               for extrudateLoop in extrudateLoops:
-                       self.addGcodeFromRemainingLoop(extrudateLoop, loopLayer, alreadyFilledArounds, self.halfEdgeWidth)
-
-       def getCraftedGcode(self, gcodeText, repository):
-               "Parse gcode text and store the bevel gcode."
-               self.repository = repository
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization()
-               for line in self.lines[self.lineIndex :]:
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(<decimalPlacesCarried>':
-                               self.addInitializationToOutput()
-                       elif firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('inset')
-                               return
-                       elif firstWord == '(<layerHeight>':
-                               layerHeight = float(splitLine[1])
-                               self.infillWidth = self.repository.infillWidth.value
-                               self.distanceFeedRate.addTagRoundedLine('infillWidth', self.infillWidth)
-                               self.distanceFeedRate.addTagRoundedLine('volumeFraction', self.repository.volumeFraction.value)
-                       elif firstWord == '(<edgeWidth>':
-                               self.edgeWidth = float(splitLine[1])
-                               self.halfEdgeWidth = 0.5 * self.edgeWidth
-                               self.overlapRemovalWidth = self.edgeWidth * self.repository.overlapRemovalWidthOverEdgeWidth.value
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               "Parse a gcode line and add it to the inset skein."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == '(<boundaryPoint>':
-                       location = gcodec.getLocationFromSplitLine(None, splitLine)
-                       self.boundary.append(location.dropAxis())
-               elif firstWord == '(</crafting>)':
-                               self.distanceFeedRate.addLine(line)
-                               if self.repository.turnExtruderHeaterOffAtShutDown.value:
-                                       self.distanceFeedRate.addLine('M104 S0') # Turn extruder heater off.
-                               return
-               elif firstWord == '(<layer>':
-                       self.layerCount.printProgressIncrement('inset')
-                       self.loopLayer = euclidean.LoopLayer(float(splitLine[1]))
-                       self.distanceFeedRate.addLine(line)
-               elif firstWord == '(</layer>)':
-                       self.addInset(self.loopLayer)
-                       self.loopLayer = None
-               elif firstWord == '(<nestedRing>)':
-                       self.boundary = []
-                       self.loopLayer.loops.append(self.boundary)
-               if self.loopLayer == None:
-                       self.distanceFeedRate.addLine(line)
-
-
-def main():
-       "Display the inset dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/jitter.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/jitter.py
deleted file mode 100644 (file)
index 8ffae95..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-"""
-This page is in the table of contents.
-This craft tool jitters the loop end position to a different place on each layer to prevent a ridge from being created on the side of the object.
-
-The jitter manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Jitter
-
-==Operation==
-The default 'Activate Jitter' checkbox is on.  When it is on, the functions described below will work, when it is off, nothing will be done.
-
-==Settings==
-===Jitter Over Perimeter Width===
-Default: 2
-
-Defines the amount the loop ends will be jittered over the edge width.  A high value means the loops will start all over the place and a low value means loops will start at roughly the same place on each layer.
-
-For example if you turn jitter off and print a cube every outside shell on the cube will start from exactly the same point so you will have a visible "mark/line/seam" on the side of the cube.  Using the jitter tool you move that start point around hence you avoid that visible seam. 
-
-
-==Examples==
-The following examples jitter the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and jitter.py.
-
-> python jitter.py
-This brings up the jitter dialog.
-
-> python jitter.py Screw Holder Bottom.stl
-The jitter tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The jitter tool has created the file:
-.. Screw Holder Bottom_jitter.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import math
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, text, jitterRepository = None ):
-       'Jitter a gcode linear move text.'
-       return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), jitterRepository )
-
-def getCraftedTextFromText( gcodeText, jitterRepository = None ):
-       'Jitter a gcode linear move text.'
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'jitter'):
-               return gcodeText
-       if jitterRepository == None:
-               jitterRepository = settings.getReadRepository( JitterRepository() )
-       if not jitterRepository.activateJitter.value:
-               return gcodeText
-       return JitterSkein().getCraftedGcode( jitterRepository, gcodeText )
-
-def getJitteredLoop( jitterDistance, jitterLoop ):
-       'Get a jittered loop path.'
-       loopLength = euclidean.getLoopLength( jitterLoop )
-       lastLength = 0.0
-       pointIndex = 0
-       totalLength = 0.0
-       jitterPosition = ( jitterDistance + 256.0 * loopLength ) % loopLength
-       while totalLength < jitterPosition and pointIndex < len( jitterLoop ):
-               firstPoint = jitterLoop[pointIndex]
-               secondPoint  = jitterLoop[ (pointIndex + 1) % len( jitterLoop ) ]
-               pointIndex += 1
-               lastLength = totalLength
-               totalLength += abs(firstPoint - secondPoint)
-       remainingLength = jitterPosition - lastLength
-       pointIndex = pointIndex % len( jitterLoop )
-       ultimateJitteredPoint = jitterLoop[pointIndex]
-       penultimateJitteredPointIndex = ( pointIndex + len( jitterLoop ) - 1 ) % len( jitterLoop )
-       penultimateJitteredPoint = jitterLoop[ penultimateJitteredPointIndex ]
-       segment = ultimateJitteredPoint - penultimateJitteredPoint
-       segmentLength = abs(segment)
-       originalOffsetLoop = euclidean.getAroundLoop( pointIndex, pointIndex, jitterLoop )
-       if segmentLength <= 0.0:
-               return originalOffsetLoop
-       newUltimatePoint = penultimateJitteredPoint + segment * remainingLength / segmentLength
-       return [newUltimatePoint] + originalOffsetLoop
-
-def getNewRepository():
-       'Get new repository.'
-       return JitterRepository()
-
-def isLoopNumberEqual( betweenX, betweenXIndex, loopNumber ):
-       'Determine if the loop number is equal.'
-       if betweenXIndex >= len( betweenX ):
-               return False
-       return betweenX[ betweenXIndex ].index == loopNumber
-
-def writeOutput(fileName, shouldAnalyze=True):
-       'Jitter a gcode linear move file.'
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'jitter', shouldAnalyze)
-
-
-class JitterRepository(object):
-       'A class to handle the jitter settings.'
-       def __init__(self):
-               'Set the default settings, execute title & settings fileName.'
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.jitter.html', self)
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Jitter', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Jitter')
-               self.activateJitter = settings.BooleanSetting().getFromValue('Activate Jitter', self, False)
-               self.jitterOverEdgeWidth = settings.FloatSpin().getFromValue(1.0, 'Jitter Over Perimeter Width (ratio):', self, 3.0, 2.0)
-               self.executeTitle = 'Jitter'
-
-       def execute(self):
-               'Jitter button has been clicked.'
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class JitterSkein(object):
-       'A class to jitter a skein of extrusions.'
-       def __init__(self):
-               'Initialize.'
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.feedRateMinute = None
-               self.isLoopPerimeter = False
-               self.layerCount = settings.LayerCount()
-               self.layerGolden = 0.0
-               self.lineIndex = 0
-               self.lines = None
-               self.loopPath = None
-               self.oldLocation = None
-               self.operatingFeedRatePerMinute = None
-               self.travelFeedRateMinute = None
-
-       def addGcodeFromThreadZ( self, thread, z ):
-               'Add a gcode thread to the output.'
-               if len(thread) > 0:
-                       self.addGcodeMovementZ( self.travelFeedRateMinute, thread[0], z )
-               else:
-                       print('zero length vertex positions array which was skipped over, this should never happen.')
-               if len(thread) < 2:
-                       return
-               self.distanceFeedRate.addLine('M101')
-               self.addGcodePathZ( self.feedRateMinute, thread[1 :], z )
-
-       def addGcodeMovementZ(self, feedRateMinute, point, z):
-               'Add a movement to the output.'
-               if feedRateMinute == None:
-                       feedRateMinute = self.operatingFeedRatePerMinute
-               self.distanceFeedRate.addGcodeMovementZWithFeedRate(feedRateMinute, point, z)
-
-       def addGcodePathZ( self, feedRateMinute, path, z ):
-               'Add a gcode path, without modifying the extruder, to the output.'
-               for point in path:
-                       self.addGcodeMovementZ(feedRateMinute, point, z)
-
-       def addTailoredLoopPath(self):
-               'Add a clipped and jittered loop path.'
-               loop = getJitteredLoop(self.layerJitter, self.loopPath.path[: -1])
-               loop = euclidean.getAwayPoints(loop, 0.2 * self.edgeWidth)
-               self.addGcodeFromThreadZ(loop + [loop[0]], self.loopPath.z)
-               self.loopPath = None
-
-       def getCraftedGcode(self, jitterRepository, gcodeText):
-               'Parse gcode text and store the jitter gcode.'
-               if jitterRepository.jitterOverEdgeWidth.value == 0.0:
-                       print('Warning, Jitter Over Perimeter Width is zero so thing will be done.')
-                       return gcodeText
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization(jitterRepository)
-               for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       self.parseLine(self.lines[self.lineIndex])
-               return self.distanceFeedRate.output.getvalue()
-
-       def parseInitialization( self, jitterRepository ):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('jitter')
-                               return
-                       elif firstWord == '(<operatingFeedRatePerSecond>':
-                               self.operatingFeedRatePerMinute = 60.0 * float(splitLine[1])
-                       elif firstWord == '(<edgeWidth>':
-                               self.edgeWidth = float(splitLine[1])
-                               self.jitter = jitterRepository.jitterOverEdgeWidth.value * self.edgeWidth
-                       elif firstWord == '(<travelFeedRatePerSecond>':
-                               self.travelFeedRateMinute = 60.0 * float(splitLine[1])
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               'Parse a gcode line, jitter it and add it to the jitter skein.'
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       self.setFeedRateLocationLoopPath(line, splitLine)
-                       if self.loopPath != None:
-                               self.loopPath.path.append(self.oldLocation.dropAxis())
-                               return
-               elif firstWord == 'M101':
-                       if self.loopPath != None:
-                               return
-               elif firstWord == 'M103':
-                       self.isLoopPerimeter = False
-                       if self.loopPath != None:
-                               self.addTailoredLoopPath()
-               elif firstWord == '(<layer>':
-                       self.layerCount.printProgressIncrement('jitter')
-                       self.layerGolden = math.fmod(self.layerGolden + 0.61803398874989479, 1.0)
-                       self.layerJitter = self.jitter * self.layerGolden - 0.5
-               elif firstWord == '(<loop>' or firstWord == '(<edge>':
-                       self.isLoopPerimeter = True
-               self.distanceFeedRate.addLine(line)
-
-       def setFeedRateLocationLoopPath(self, line, splitLine):
-               'Set the feedRateMinute, oldLocation and loopPath.'
-               self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine)
-               self.oldLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               if not self.isLoopPerimeter or self.loopPath != None:
-                       return
-               for afterIndex in xrange(self.lineIndex + 1, len(self.lines)):
-                       line = self.lines[afterIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1' or firstWord == 'M103':
-                               return
-                       elif firstWord == 'M101':
-                               self.loopPath = euclidean.PathZ(self.oldLocation.z)
-                               return
-
-
-def main():
-       'Display the jitter dialog.'
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == '__main__':
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/joris.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/joris.py
deleted file mode 100644 (file)
index 33e40ba..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-"""
-This page is in the table of contents.
-The Joris plugin makes the perimiter slowly increase in Z over the layer. This will make vases/cups without a z blob.
-
-==Operation==
-The default 'Activate Joris' checkbox is off.  When it is on, the Joris plugin will do it's work.
-
-==Settings==
-===Layers From===
-Default: 1
-
-Defines which layer of the print the joris process starts from.
-
-==Tips==
-
-==Examples==
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-
-__author__ = 'Daid (daid303@gmail.com'
-__date__ = '$Date: 2012/24/01 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText(fileName, gcodeText, repository=None):
-       'Joris a gcode linear move text.'
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, gcodeText), repository)
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       'Joris a gcode linear move text.'
-       if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'Joris'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository(JorisRepository())
-       if not repository.activateJoris.value:
-               return gcodeText
-       return JorisSkein().getCraftedGcode(gcodeText, repository)
-
-def getIsMinimumSides(loops, sides=3):
-       'Determine if all the loops have at least the given number of sides.'
-       for loop in loops:
-               if len(loop) < sides:
-                       return False
-       return True
-
-def getNewRepository():
-       'Get new repository.'
-       return JorisRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       'Joris a gcode linear move file.  Chain Joris the gcode if it is not already Jorised.'
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'joris', shouldAnalyze)
-
-
-class JorisRepository(object):
-       'A class to handle the Joris settings.'
-       def __init__(self):
-               'Set the default settings, execute title & settings fileName.'
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.joris.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Joris', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Joris')
-               self.activateJoris = settings.BooleanSetting().getFromValue('Activate Joris', self, False)
-               settings.LabelSeparator().getFromRepository(self)
-               self.layersFrom = settings.IntSpin().getSingleIncrementFromValue(0, 'Layers From (index):', self, 912345678, 1)
-               self.executeTitle = 'Joris'
-
-       def execute(self):
-               'Joris button has been clicked.'
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class JorisSkein(object):
-       'A class to Joris a skein of extrusions.'
-       def __init__(self):
-               'Initialize.'
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.lines = None
-               self.layerIndex = -1
-               self.feedRateMinute = 959.0
-               self.travelFeedRateMinute = 957.0
-               self.perimeter = None
-               self.oldLocation = None
-               self.doJoris = False
-               self.firstLayer = True
-       
-       def getCraftedGcode( self, gcodeText, repository ):
-               'Parse gcode text and store the joris gcode.'
-               self.lines = archive.getTextLines(gcodeText)
-               self.repository = repository
-               self.layersFromBottom = repository.layersFrom.value
-               self.parseInitialization()
-               for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       self.parseLine(line)
-               return gcodec.getGcodeWithoutDuplication('M108', self.distanceFeedRate.output.getvalue())
-               
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(<layerThickness>':
-                               self.layerThickness = float(splitLine[1])
-                       elif firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('joris')
-                               return
-                       elif firstWord == '(<travelFeedRatePerSecond>':
-                               self.travelFeedRateMinute = 60.0 * float(splitLine[1])
-                       self.distanceFeedRate.addLine(line)
-                       
-       def parseLine(self, line):
-               'Parse a gcode line and add it to the joris skein.'
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1' and self.doJoris:
-                       self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine)
-                       location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-                       self.oldLocation = location
-                       if self.perimeter != None:
-                               self.perimeter.append(location.dropAxis())
-                               return
-               elif firstWord == '(<layer>':
-                       self.layerIndex += 1
-                       settings.printProgress(self.layerIndex, 'joris')
-               elif firstWord == 'M108':
-                       self.oldFlowRate = gcodec.getDoubleAfterFirstLetter(splitLine[1])
-               elif firstWord == '(<edge>':
-                       if self.layerIndex >= self.layersFromBottom:
-                               self.doJoris = True
-               elif firstWord == 'M101' and self.doJoris:
-                       self.perimeter = []
-                       return
-               elif firstWord == 'M103' and self.doJoris:
-                       self.addJorisedPerimeter()
-                       return
-               elif firstWord == '(</edge>)':
-                       self.doJoris = False
-               self.distanceFeedRate.addLine(line)
-               
-       def addJorisedPerimeter(self):
-               'Add jorised perimeter.'
-               if self.perimeter is None:
-                       return
-               #Calculate the total length of the perimeter.
-               p = self.oldLocation.dropAxis()
-               perimeterLength = 0
-               for point in self.perimeter:
-                       perimeterLength += abs( point - p )
-                       p = point
-               
-               #Build the perimeter with an increasing Z over the length.
-               if self.firstLayer:
-                       #On the first layer, we need to create an extra jorised perimeter, else we create a gap at the end of the perimeter.
-                       p = self.oldLocation.dropAxis()
-                       length = 0;
-                       self.distanceFeedRate.addLine('M101') # Turn extruder on.
-                       for point in self.perimeter:
-                               length += abs( point - p );
-                               p = point
-                               self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.feedRateMinute, point, self.oldLocation.z - self.layerThickness + self.layerThickness * length / perimeterLength)
-                       self.distanceFeedRate.addLine('M103') # Turn extruder off.
-                       self.firstLayer = False
-
-               p = self.oldLocation.dropAxis()
-               length = 0;
-               self.distanceFeedRate.addLine('M101') # Turn extruder on.
-               for point in self.perimeter:
-                       length += abs( point - p );
-                       p = point
-                       self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.feedRateMinute, point, self.oldLocation.z + self.layerThickness * length / perimeterLength)
-               self.distanceFeedRate.addLine('M103') # Turn extruder off.
-               self.perimeter = None
-
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/lash.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/lash.py
deleted file mode 100644 (file)
index 0e731e9..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-"""
-This page is in the table of contents.
-Lash is a script to partially compensate for the backlash of the tool head.
-
-The lash manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Lash
-
-The lash tool is ported from Erik de Bruijn's 3D-to-5D-Gcode php GPL'd script at:
-http://objects.reprap.org/wiki/3D-to-5D-Gcode.php
-
-The default values are from the settings in Erik's 3D-to-5D-Gcode, I believe the settings are used on his Darwin reprap.
-
-==Operation==
-The default 'Activate Lash' checkbox is off.  When it is on, the functions described below will work, when it is off, nothing will be done.
-
-==Settings==
-===X Backlash===
-Default is 0.2 millimeters.
-
-Defines the distance the tool head will be lashed in the X direction.
-
-===Y Backlash===
-Default is 0.2 millimeters.
-
-Defines the distance the tool head will be lashed in the Y direction.
-
-==Examples==
-The following examples lash the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and lash.py.
-
-> python lash.py
-This brings up the lash dialog.
-
-> python lash.py Screw Holder Bottom.stl
-The lash tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The lash tool has created the file:
-.. Screw Holder Bottom_lash.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, text, lashRepository = None ):
-       "Get a lashed gcode linear move text."
-       return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), lashRepository )
-
-def getCraftedTextFromText( gcodeText, lashRepository = None ):
-       "Get a lashed gcode linear move text from text."
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'lash'):
-               return gcodeText
-       if lashRepository == None:
-               lashRepository = settings.getReadRepository( LashRepository() )
-       if not lashRepository.activateLash.value:
-               return gcodeText
-       return LashSkein().getCraftedGcode( gcodeText, lashRepository )
-
-def getNewRepository():
-       'Get new repository.'
-       return LashRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Lash a gcode linear move file."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'lash', shouldAnalyze)
-
-
-class LashRepository(object):
-       "A class to handle the lash settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.lash.html', self)
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Lash', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Lash')
-               self.activateLash = settings.BooleanSetting().getFromValue('Activate Lash', self, False )
-               self.xBacklash = settings.FloatSpin().getFromValue( 0.1, 'X Backlash (mm):', self, 0.5, 0.2 )
-               self.yBacklash = settings.FloatSpin().getFromValue( 0.1, 'Y Backlash (mm):', self, 0.5, 0.3 )
-               self.executeTitle = 'Lash'
-
-       def execute(self):
-               "Lash button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class LashSkein(object):
-       "A class to lash a skein of extrusions."
-       def __init__(self):
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.feedRateMinute = 958.0
-               self.lineIndex = 0
-               self.lines = None
-               self.oldLocation = None
-
-       def getCraftedGcode( self, gcodeText, lashRepository ):
-               "Parse gcode text and store the lash gcode."
-               self.lines = archive.getTextLines(gcodeText)
-               self.lashRepository = lashRepository
-               self.xBacklash = lashRepository.xBacklash.value
-               self.yBacklash = lashRepository.yBacklash.value
-               self.parseInitialization()
-               for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       self.parseLash(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def getLashedLine( self, line, location, splitLine ):
-               "Get lashed gcode line."
-               if self.oldLocation == None:
-                       return line
-               if location.x > self.oldLocation.x:
-                       line = self.distanceFeedRate.getLineWithX( line, splitLine, location.x + self.xBacklash )
-               else:
-                       line = self.distanceFeedRate.getLineWithX( line, splitLine, location.x - self.xBacklash )
-               if location.y > self.oldLocation.y:
-                       line = self.distanceFeedRate.getLineWithY( line, splitLine, location.y + self.yBacklash )
-               else:
-                       line = self.distanceFeedRate.getLineWithY( line, splitLine, location.y - self.yBacklash )
-               return line
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('lash')
-                               return
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLash(self, line):
-               "Parse a gcode line and add it to the lash skein."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-                       line = self.getLashedLine( line, location, splitLine )
-                       self.oldLocation = location
-               self.distanceFeedRate.addLine(line)
-
-
-def main():
-       "Display the lash dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/lift.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/lift.py
deleted file mode 100644 (file)
index 9fccf0d..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-"""
-This page is in the table of contents.
-Lift will change the altitude of the cutting tool when it is on so that it will cut through the slab at the correct altitude.  It will also lift the gcode when the tool is off so that the cutting tool will clear the top of the slab.
-
-==Operation==
-The default 'Activate Lift' checkbox is on.  When it is on, the functions described below will work, when it is off, the functions will not be called.
-
-==Settings==
-===Cutting Lift over Layer Step===
-Default is minus 0.5, because the end mill is the more common tool.
-
-Defines the ratio of the amount the cutting tool will be lifted over the layer step.  If whittle is off the layer step will be the layer height, if it is on, it will be the layer step from the whittle gcode.  If the cutting tool is like an end mill, where the cutting happens until the end of the tool, then the 'Cutting Lift over Layer Step' should be minus 0.5, so that the end mill cuts to the bottom of the slab.  If the cutting tool is like a laser, where the cutting happens around the focal point. the 'Cutting Lift over Layer Step' should be zero, so that the cutting action will be focused in the middle of the slab.
-
-===Clearance above Top===
-Default is 5 millimeters.
-
-Defines the distance above the top of the slab the cutting tool will be lifted when will tool is off so that the cutting tool will clear the top of the slab.
-
-==Examples==
-The following examples lift the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and lift.py.
-
-> python lift.py
-This brings up the lift dialog.
-
-> python lift.py Screw Holder Bottom.stl
-The lift tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The lift tool has created the file:
-.. Screw Holder Bottom_lift.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, text='', liftRepository = None ):
-       "Lift the preface file or text."
-       return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), liftRepository )
-
-def getCraftedTextFromText( gcodeText, liftRepository = None ):
-       "Lift the preface gcode text."
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'lift'):
-               return gcodeText
-       if liftRepository == None:
-               liftRepository = settings.getReadRepository( LiftRepository() )
-       if not liftRepository.activateLift.value:
-               return gcodeText
-       return LiftSkein().getCraftedGcode( liftRepository, gcodeText )
-
-def getNewRepository():
-       'Get new repository.'
-       return LiftRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Lift the carving of a gcode file."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'lift', shouldAnalyze)
-
-
-class LiftRepository(object):
-       "A class to handle the lift settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.lift.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File to be Lifted', self, '')
-               self.activateLift = settings.BooleanSetting().getFromValue('Activate Lift', self, True )
-               self.cuttingLiftOverLayerStep = settings.FloatSpin().getFromValue( - 1.0, 'Cutting Lift over Layer Step (ratio):', self, 1.0, - 0.5 )
-               self.clearanceAboveTop = settings.FloatSpin().getFromValue( 0.0, 'Clearance above Top (mm):', self, 10.0, 5.0 )
-               self.executeTitle = 'Lift'
-
-       def execute(self):
-               "Lift button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class LiftSkein(object):
-       "A class to lift a skein of extrusions."
-       def __init__(self):
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.extruderActive = False
-               self.layerStep = None
-               self.layerHeight = 0.3333333333
-               self.lineIndex = 0
-               self.maximumZ = - 912345678.0
-               self.oldLocation = None
-               self.previousActiveMovementLine = None
-               self.previousInactiveMovementLine = None
-
-       def addPreviousInactiveMovementLineIfNecessary(self):
-               "Add the previous inactive movement line if necessary."
-               if self.previousInactiveMovementLine != None:
-                       self.distanceFeedRate.addLine( self.previousInactiveMovementLine )
-                       self.previousInactiveMovementLine = None
-
-       def getCraftedGcode( self, liftRepository, gcodeText ):
-               "Parse gcode text and store the lift gcode."
-               self.liftRepository = liftRepository
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization()
-               self.oldLocation = None
-               if self.layerStep == None:
-                       self.layerStep = self.layerHeight
-               self.cuttingLift = self.layerStep * liftRepository.cuttingLiftOverLayerStep.value
-               self.setMaximumZ()
-               self.travelZ = self.maximumZ + 0.5 * self.layerStep + liftRepository.clearanceAboveTop.value
-               for line in self.lines[self.lineIndex :]:
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def getLinearMove( self, line, location, splitLine ):
-               "Get the linear move."
-               if self.extruderActive:
-                       z = location.z + self.cuttingLift
-                       return self.distanceFeedRate.getLineWithZ( line, splitLine, z )
-               if self.previousActiveMovementLine != None:
-                       previousActiveMovementLineSplit = self.previousActiveMovementLine.split()
-                       self.distanceFeedRate.addLine( self.distanceFeedRate.getLineWithZ( self.previousActiveMovementLine, previousActiveMovementLineSplit, self.travelZ ) )
-                       self.previousActiveMovementLine = None
-               self.distanceFeedRate.addLine( self.distanceFeedRate.getLineWithZ( line, splitLine, self.travelZ ) )
-               self.previousInactiveMovementLine = line
-               return ''
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex].lstrip()
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('lift')
-                               return
-                       elif firstWord == '(<layerHeight>':
-                               self.layerHeight = float(splitLine[1])
-                       elif firstWord == '(<layerStep>':
-                               self.layerStep = float(splitLine[1])
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               "Parse a gcode line and add it to the lift skein."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-                       line = self.getLinearMove( line, location, splitLine )
-                       self.previousActiveMovementLine = line
-                       self.oldLocation = location
-               elif firstWord == 'M101':
-                       self.addPreviousInactiveMovementLineIfNecessary()
-                       self.extruderActive = True
-               elif firstWord == 'M103':
-                       self.extruderActive = False
-               self.distanceFeedRate.addLine(line)
-
-       def setMaximumZ(self):
-               "Set maximum  z."
-               localOldLocation = None
-               for line in self.lines[self.lineIndex :]:
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1':
-                               location = gcodec.getLocationFromSplitLine( localOldLocation, splitLine )
-                               self.maximumZ = max( self.maximumZ, location.z )
-                               localOldLocation = location
-
-
-def main():
-       "Display the lift dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/limit.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/limit.py
deleted file mode 100644 (file)
index ac3e2c9..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-#! /usr/bin/env python
-"""
-This page is in the table of contents.
-This plugin limits the feed rate of the tool head, so that the stepper motors are not driven too fast and skip steps.
-
-The limit manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Limit
-
-The maximum z feed rate is defined in speed.
-
-==Operation==
-The default 'Activate Limit' checkbox is on.  When it is on, the functions described below will work, when it is off, nothing will be done.
-
-==Settings==
-===Maximum Initial Feed Rate===
-Default is one millimeter per second.
-
-Defines the maximum speed of the inital tool head move.
-
-==Examples==
-The following examples limit the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and limit.py.
-
-> python limit.py
-This brings up the limit dialog.
-
-> python limit.py Screw Holder Bottom.stl
-The limit tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The limit tool has created the file:
-.. Screw Holder Bottom_limit.gcode
-
-"""
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/28/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText(fileName, gcodeText='', repository=None):
-       'Limit a gcode file or text.'
-       return getCraftedTextFromText( archive.getTextIfEmpty(fileName, gcodeText), repository )
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       'Limit a gcode text.'
-       if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'limit'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository(LimitRepository())
-       if not repository.activateLimit.value:
-               return gcodeText
-       return LimitSkein().getCraftedGcode(gcodeText, repository)
-
-def getNewRepository():
-       'Get new repository.'
-       return LimitRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       'Limit a gcode file.'
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'limit', shouldAnalyze)
-
-
-class LimitRepository(object):
-       'A class to handle the limit settings.'
-       def __init__(self):
-               'Set the default settings, execute title & settings fileName.'
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.limit.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Limit', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Limit')
-               self.activateLimit = settings.BooleanSetting().getFromValue('Activate Limit', self, False)
-               self.maximumInitialFeedRate = settings.FloatSpin().getFromValue(0.5, 'Maximum Initial Feed Rate (mm/s):', self, 10.0, 1.0)
-               self.executeTitle = 'Limit'
-
-       def execute(self):
-               'Limit button has been clicked.'
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class LimitSkein(object):
-       'A class to limit a skein of extrusions.'
-       def __init__(self):
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.feedRateMinute = None
-               self.lineIndex = 0
-               self.maximumZDrillFeedRatePerSecond = 987654321.0
-               self.oldLocation = None
-
-       def getCraftedGcode(self, gcodeText, repository):
-               'Parse gcode text and store the limit gcode.'
-               self.repository = repository
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization()
-               self.maximumZDrillFeedRatePerSecond = min(self.maximumZDrillFeedRatePerSecond, self.maximumZFeedRatePerSecond)
-               self.maximumZCurrentFeedRatePerSecond = self.maximumZFeedRatePerSecond
-               for lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       self.parseLine( lineIndex )
-               return self.distanceFeedRate.output.getvalue()
-
-       def getLimitedInitialMovement(self, line, splitLine):
-               'Get a limited linear movement.'
-               if self.oldLocation == None:
-                       line = self.distanceFeedRate.getLineWithFeedRate(60.0 * self.repository.maximumInitialFeedRate.value, line, splitLine)
-               return line
-
-       def getZLimitedLine(self, deltaZ, distance, line, splitLine):
-               'Get a replaced z limited gcode movement line.'
-               zFeedRateSecond = self.feedRateMinute * deltaZ / distance / 60.0
-               if zFeedRateSecond <= self.maximumZCurrentFeedRatePerSecond:
-                       return line
-               limitedFeedRateMinute = self.feedRateMinute * self.maximumZCurrentFeedRatePerSecond / zFeedRateSecond
-               return self.distanceFeedRate.getLineWithFeedRate(limitedFeedRateMinute, line, splitLine)
-
-       def getZLimitedLineArc(self, line, splitLine):
-               'Get a replaced z limited gcode arc movement line.'
-               self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine)
-               if self.feedRateMinute == None or self.oldLocation == None:
-                       return line
-               relativeLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               self.oldLocation += relativeLocation
-               deltaZ = abs(relativeLocation.z)
-               distance = gcodec.getArcDistance(relativeLocation, splitLine)
-               return self.getZLimitedLine(deltaZ, distance, line, splitLine)
-
-       def getZLimitedLineLinear(self, line, location, splitLine):
-               'Get a replaced z limited gcode linear movement line.'
-               self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine)
-               if location == self.oldLocation:
-                       return ''
-               if self.feedRateMinute == None or self.oldLocation == None:
-                       return line
-               deltaZ = abs(location.z - self.oldLocation.z)
-               distance = abs(location - self.oldLocation)
-               return self.getZLimitedLine(deltaZ, distance, line, splitLine)
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('limit')
-                               return
-                       elif firstWord == '(<maximumZDrillFeedRatePerSecond>':
-                               self.maximumZDrillFeedRatePerSecond = float(splitLine[1])
-                       elif firstWord == '(<maximumZFeedRatePerSecond>':
-                               self.maximumZFeedRatePerSecond = float(splitLine[1])
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine( self, lineIndex ):
-               'Parse a gcode line and add it to the limit skein.'
-               line = self.lines[lineIndex].lstrip()
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = gcodec.getFirstWord(splitLine)
-               if firstWord == 'G1':
-                       location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-                       line = self.getLimitedInitialMovement(line, splitLine)
-                       line = self.getZLimitedLineLinear(line, location, splitLine)
-                       self.oldLocation = location
-               elif firstWord == 'G2' or firstWord == 'G3':
-                       line = self.getZLimitedLineArc(line, splitLine)
-               elif firstWord == 'M101':
-                       self.maximumZCurrentFeedRatePerSecond = self.maximumZDrillFeedRatePerSecond
-               elif firstWord == 'M103':
-                       self.maximumZCurrentFeedRatePerSecond = self.maximumZFeedRatePerSecond
-               self.distanceFeedRate.addLine(line)
-
-
-def main():
-       'Display the limit dialog.'
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == '__main__':
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/mill.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/mill.py
deleted file mode 100644 (file)
index 0bc135b..0000000
+++ /dev/null
@@ -1,375 +0,0 @@
-"""
-This page is in the table of contents.
-Mill is a script to mill the outlines.
-
-==Operation==
-The default 'Activate Mill' checkbox is on.  When it is on, the functions described below will work, when it is off, the functions will not be called.
-
-==Settings==
-===Add Loops===
-====Add Inner Loops====
-Default is on.
-
-When selected, the inner milling loops will be added.
-
-====Add Outer Loops====
-Default is on.
-
-When selected, the outer milling loops will be added.
-
-===Cross Hatch===
-Default is on.
-
-When selected, there will be alternating horizontal and vertical milling paths, if it is off there will only be horizontal milling paths.
-
-===Loop Outset===
-====Loop Inner Outset over Perimeter Width====
-Default is 0.5.
-
-Defines the ratio of the amount the inner milling loop will be outset over the edge width.
-
-====Loop Outer Outset over Perimeter Width====
-Default is one.
-
-Defines the ratio of the amount the outer milling loop will be outset over the edge width.  The 'Loop Outer Outset over Perimeter Width' ratio should be greater than the 'Loop Inner Outset over Perimeter Width' ratio.
-
-===Mill Width over Perimeter Width===
-Default is one.
-
-Defines the ratio of the mill line width over the edge width.  If the ratio is one, all the material will be milled.  The greater the 'Mill Width over Perimeter Width' the farther apart the mill lines will be and so less of the material will be directly milled, the remaining material might still be removed in chips if the ratio is not much greater than one.
-
-==Examples==
-The following examples mill the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and mill.py.
-
-> python mill.py
-This brings up the mill dialog.
-
-> python mill.py Screw Holder Bottom.stl
-The mill tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The mill tool has created the file:
-Screw Holder Bottom_mill.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import intercircle
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, gcodeText = '', repository=None):
-       'Mill the file or gcodeText.'
-       return getCraftedTextFromText( archive.getTextIfEmpty(fileName, gcodeText), repository )
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       'Mill a gcode linear move gcodeText.'
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'mill'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository( MillRepository() )
-       if not repository.activateMill.value:
-               return gcodeText
-       return MillSkein().getCraftedGcode(gcodeText, repository)
-
-def getNewRepository():
-       'Get new repository.'
-       return MillRepository()
-
-def getPointsFromSegmentTable(segmentTable):
-       'Get the points from the segment table.'
-       points = []
-       segmentTableKeys = segmentTable.keys()
-       segmentTableKeys.sort()
-       for segmentTableKey in segmentTableKeys:
-               for segment in segmentTable[segmentTableKey]:
-                       for endpoint in segment:
-                               points.append(endpoint.point)
-       return points
-
-def isPointOfTableInLoop( loop, pointTable ):
-       'Determine if a point in the point table is in the loop.'
-       for point in loop:
-               if point in pointTable:
-                       return True
-       return False
-
-def writeOutput(fileName, shouldAnalyze=True):
-       'Mill a gcode linear move file.'
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'mill', shouldAnalyze)
-
-
-class Average(object):
-       'A class to hold values and get the average.'
-       def __init__(self):
-               self.reset()
-
-       def addValue( self, value ):
-               'Add a value to the total and the number of values.'
-               self.numberOfValues += 1
-               self.total += value
-
-       def getAverage(self):
-               'Get the average.'
-               if self.numberOfValues == 0:
-                       print('should never happen, self.numberOfValues in Average is zero')
-                       return 0.0
-               return self.total / float( self.numberOfValues )
-
-       def reset(self):
-               'Set the number of values and the total to the default.'
-               self.numberOfValues = 0
-               self.total = 0.0
-
-
-class MillRepository(object):
-       'A class to handle the mill settings.'
-       def __init__(self):
-               'Set the default settings, execute title & settings fileName.'
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.mill.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Mill', self, '')
-               self.activateMill = settings.BooleanSetting().getFromValue('Activate Mill', self, True )
-               settings.LabelDisplay().getFromName('- Add Loops -', self )
-               self.addInnerLoops = settings.BooleanSetting().getFromValue('Add Inner Loops', self, True )
-               self.addOuterLoops = settings.BooleanSetting().getFromValue('Add Outer Loops', self, True )
-               self.crossHatch = settings.BooleanSetting().getFromValue('Cross Hatch', self, True )
-               settings.LabelDisplay().getFromName('- Loop Outset -', self )
-               self.loopInnerOutsetOverEdgeWidth = settings.FloatSpin().getFromValue( 0.3, 'Loop Inner Outset over Perimeter Width (ratio):', self, 0.7, 0.5 )
-               self.loopOuterOutsetOverEdgeWidth = settings.FloatSpin().getFromValue( 0.8, 'Loop Outer Outset over Perimeter Width (ratio):', self, 1.4, 1.0 )
-               self.millWidthOverEdgeWidth = settings.FloatSpin().getFromValue( 0.8, 'Mill Width over Edge Width (ratio):', self, 1.8, 1.0 )
-               self.executeTitle = 'Mill'
-
-       def execute(self):
-               'Mill button has been clicked.'
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-
-class MillSkein(object):
-       'A class to mill a skein of extrusions.'
-       def __init__(self):
-               self.aroundPixelTable = {}
-               self.average = Average()
-               self.boundaryLayers = []
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.edgeWidth = 0.6
-               self.isExtruderActive = False
-               self.layerIndex = 0
-               self.lineIndex = 0
-               self.lines = None
-               self.oldLocation = None
-
-       def addGcodeFromLoops(self, loops, z):
-               'Add gcode from loops.'
-               if self.oldLocation == None:
-                       self.oldLocation = Vector3()
-               self.oldLocation.z = z
-               for loop in loops:
-                       self.distanceFeedRate.addGcodeFromThreadZ(loop, z)
-                       euclidean.addToThreadsFromLoop(self.halfEdgeWidth, 'loop', loop, self.oldLocation, self)
-
-       def addGcodeFromThreadZ( self, thread, z ):
-               'Add a thread to the output.'
-               self.distanceFeedRate.addGcodeFromThreadZ( thread, z )
-
-       def addMillThreads(self):
-               'Add the mill threads to the skein.'
-               boundaryLayer = self.boundaryLayers[self.layerIndex]
-               endpoints = euclidean.getEndpointsFromSegmentTable( boundaryLayer.segmentTable )
-               if len(endpoints) < 1:
-                       return
-               paths = euclidean.getPathsFromEndpoints(endpoints, 5.0 * self.millWidth, self.aroundPixelTable, 1.0, self.aroundWidth)
-               averageZ = self.average.getAverage()
-               if self.repository.addInnerLoops.value:
-                       self.addGcodeFromLoops( boundaryLayer.innerLoops, averageZ )
-               if self.repository.addOuterLoops.value:
-                       self.addGcodeFromLoops( boundaryLayer.outerLoops, averageZ )
-               for path in paths:
-                       simplifiedPath = euclidean.getSimplifiedPath( path, self.millWidth )
-                       self.distanceFeedRate.addGcodeFromThreadZ( simplifiedPath, averageZ )
-
-       def addSegmentTableLoops( self, boundaryLayerIndex ):
-               'Add the segment tables and loops to the boundary.'
-               boundaryLayer = self.boundaryLayers[boundaryLayerIndex]
-               euclidean.subtractXIntersectionsTable(boundaryLayer.outerHorizontalTable, boundaryLayer.innerHorizontalTable)
-               euclidean.subtractXIntersectionsTable(boundaryLayer.outerVerticalTable, boundaryLayer.innerVerticalTable)
-               boundaryLayer.horizontalSegmentTable = self.getHorizontalSegmentTableForXIntersectionsTable(
-                       boundaryLayer.outerHorizontalTable)
-               boundaryLayer.verticalSegmentTable = self.getVerticalSegmentTableForXIntersectionsTable(
-                       boundaryLayer.outerVerticalTable)
-               betweenPoints = getPointsFromSegmentTable(boundaryLayer.horizontalSegmentTable)
-               betweenPoints += getPointsFromSegmentTable(boundaryLayer.verticalSegmentTable)
-               innerPoints = euclidean.getPointsByHorizontalDictionary(self.millWidth, boundaryLayer.innerHorizontalTable)
-               innerPoints += euclidean.getPointsByVerticalDictionary(self.millWidth, boundaryLayer.innerVerticalTable)
-               innerPointTable = {}
-               for innerPoint in innerPoints:
-                       innerPointTable[innerPoint] = None
-               boundaryLayer.innerLoops = []
-               boundaryLayer.outerLoops = []
-               millRadius = 0.75 * self.millWidth
-               loops = triangle_mesh.getDescendingAreaOrientedLoops(betweenPoints, betweenPoints, millRadius)
-               for loop in loops:
-                       if isPointOfTableInLoop(loop, innerPointTable):
-                               boundaryLayer.innerLoops.append(loop)
-                       else:
-                               boundaryLayer.outerLoops.append(loop)
-               if self.repository.crossHatch.value and boundaryLayerIndex % 2 == 1:
-                       boundaryLayer.segmentTable = boundaryLayer.verticalSegmentTable
-               else:
-                       boundaryLayer.segmentTable = boundaryLayer.horizontalSegmentTable
-
-       def getCraftedGcode(self, gcodeText, repository):
-               'Parse gcode text and store the mill gcode.'
-               self.repository = repository
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization()
-               self.parseBoundaries()
-               for line in self.lines[self.lineIndex :]:
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def getHorizontalSegmentTableForXIntersectionsTable( self, xIntersectionsTable ):
-               'Get the horizontal segment table from the xIntersectionsTable.'
-               horizontalSegmentTable = {}
-               xIntersectionsTableKeys = xIntersectionsTable.keys()
-               xIntersectionsTableKeys.sort()
-               for xIntersectionsTableKey in xIntersectionsTableKeys:
-                       xIntersections = xIntersectionsTable[ xIntersectionsTableKey ]
-                       segments = euclidean.getSegmentsFromXIntersections( xIntersections, xIntersectionsTableKey * self.millWidth )
-                       horizontalSegmentTable[ xIntersectionsTableKey ] = segments
-               return horizontalSegmentTable
-
-       def getHorizontalXIntersectionsTable(self, loops):
-               'Get the horizontal x intersections table from the loops.'
-               horizontalXIntersectionsTable = {}
-               euclidean.addXIntersectionsFromLoopsForTable(loops, horizontalXIntersectionsTable, self.millWidth)
-               return horizontalXIntersectionsTable
-
-       def getVerticalSegmentTableForXIntersectionsTable( self, xIntersectionsTable ):
-               'Get the vertical segment table from the xIntersectionsTable which has the x and y swapped.'
-               verticalSegmentTable = {}
-               xIntersectionsTableKeys = xIntersectionsTable.keys()
-               xIntersectionsTableKeys.sort()
-               for xIntersectionsTableKey in xIntersectionsTableKeys:
-                       xIntersections = xIntersectionsTable[ xIntersectionsTableKey ]
-                       segments = euclidean.getSegmentsFromXIntersections( xIntersections, xIntersectionsTableKey * self.millWidth )
-                       for segment in segments:
-                               for endpoint in segment:
-                                       endpoint.point = complex( endpoint.point.imag, endpoint.point.real )
-                       verticalSegmentTable[ xIntersectionsTableKey ] = segments
-               return verticalSegmentTable
-
-       def parseBoundaries(self):
-               'Parse the boundaries and add them to the boundary layers.'
-               boundaryLoop = None
-               boundaryLayer = None
-               for line in self.lines[self.lineIndex :]:
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == '(</boundaryPerimeter>)':
-                               boundaryLoop = None
-                       elif firstWord == '(<boundaryPoint>':
-                               location = gcodec.getLocationFromSplitLine(None, splitLine)
-                               if boundaryLoop == None:
-                                       boundaryLoop = []
-                                       boundaryLayer.loops.append(boundaryLoop)
-                               boundaryLoop.append(location.dropAxis())
-                       elif firstWord == '(<layer>':
-                               boundaryLayer = euclidean.LoopLayer(float(splitLine[1]))
-                               self.boundaryLayers.append(boundaryLayer)
-               if len(self.boundaryLayers) < 2:
-                       return
-               for boundaryLayer in self.boundaryLayers:
-                       boundaryLayer.innerOutsetLoops = intercircle.getInsetSeparateLoopsFromLoops(boundaryLayer.loops, -self.loopInnerOutset)
-                       boundaryLayer.outerOutsetLoops = intercircle.getInsetSeparateLoopsFromLoops(boundaryLayer.loops, -self.loopOuterOutset)
-                       boundaryLayer.innerHorizontalTable = self.getHorizontalXIntersectionsTable( boundaryLayer.innerOutsetLoops )
-                       boundaryLayer.outerHorizontalTable = self.getHorizontalXIntersectionsTable( boundaryLayer.outerOutsetLoops )
-                       boundaryLayer.innerVerticalTable = self.getHorizontalXIntersectionsTable( euclidean.getDiagonalFlippedLoops( boundaryLayer.innerOutsetLoops ) )
-                       boundaryLayer.outerVerticalTable = self.getHorizontalXIntersectionsTable( euclidean.getDiagonalFlippedLoops( boundaryLayer.outerOutsetLoops ) )
-               for boundaryLayerIndex in xrange( len(self.boundaryLayers) - 2, - 1, - 1 ):
-                       boundaryLayer = self.boundaryLayers[ boundaryLayerIndex ]
-                       boundaryLayerBelow = self.boundaryLayers[ boundaryLayerIndex + 1 ]
-                       euclidean.joinXIntersectionsTables( boundaryLayerBelow.outerHorizontalTable, boundaryLayer.outerHorizontalTable )
-                       euclidean.joinXIntersectionsTables( boundaryLayerBelow.outerVerticalTable, boundaryLayer.outerVerticalTable )
-               for boundaryLayerIndex in xrange( 1, len(self.boundaryLayers) ):
-                       boundaryLayer = self.boundaryLayers[ boundaryLayerIndex ]
-                       boundaryLayerAbove = self.boundaryLayers[ boundaryLayerIndex - 1 ]
-                       euclidean.joinXIntersectionsTables( boundaryLayerAbove.innerHorizontalTable, boundaryLayer.innerHorizontalTable )
-                       euclidean.joinXIntersectionsTables( boundaryLayerAbove.innerVerticalTable, boundaryLayer.innerVerticalTable )
-               for boundaryLayerIndex in xrange( len(self.boundaryLayers) ):
-                       self.addSegmentTableLoops(boundaryLayerIndex)
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('mill')
-                               return
-                       elif firstWord == '(<edgeWidth>':
-                               self.edgeWidth = float(splitLine[1])
-                               self.aroundWidth = 0.1 * self.edgeWidth
-                               self.halfEdgeWidth = 0.5 * self.edgeWidth
-                               self.millWidth = self.edgeWidth * self.repository.millWidthOverEdgeWidth.value
-                               self.loopInnerOutset = self.halfEdgeWidth + self.edgeWidth * self.repository.loopInnerOutsetOverEdgeWidth.value
-                               self.loopOuterOutset = self.halfEdgeWidth + self.edgeWidth * self.repository.loopOuterOutsetOverEdgeWidth.value
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               'Parse a gcode line and add it to the mill skein.'
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-                       if self.isExtruderActive:
-                               self.average.addValue(location.z)
-                               if self.oldLocation != None:
-                                       euclidean.addValueSegmentToPixelTable( self.oldLocation.dropAxis(), location.dropAxis(), self.aroundPixelTable, None, self.aroundWidth )
-                       self.oldLocation = location
-               elif firstWord == 'M101':
-                       self.isExtruderActive = True
-               elif firstWord == 'M103':
-                       self.isExtruderActive = False
-               elif firstWord == '(<layer>':
-                       settings.printProgress(self.layerIndex, 'mill')
-                       self.aroundPixelTable = {}
-                       self.average.reset()
-               elif firstWord == '(</layer>)':
-                       if len(self.boundaryLayers) > self.layerIndex:
-                               self.addMillThreads()
-                       self.layerIndex += 1
-               self.distanceFeedRate.addLine(line)
-
-
-def main():
-       'Display the mill dialog.'
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == '__main__':
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/multiply.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/multiply.py
deleted file mode 100644 (file)
index 8f4a433..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-"""
-This page is in the table of contents.
-The multiply plugin will take a single object and create an array of objects.  It is used when you want to print single object multiple times in a single pass.
-
-You can also position any object using this plugin by setting the center X and center Y to the desired coordinates (0,0 for the center of the print_bed) and setting the number of rows and columns to 1 (effectively setting a 1x1 matrix - printing only a single object).
-
-The multiply manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Multiply
-
-Besides using the multiply tool, another way of printing many copies of the model is to duplicate the model in Art of Illusion, however many times you want, with the appropriate offsets.  Then you can either use the Join Objects script in the scripts submenu to create a combined shape or you can export the whole scene as an xml file, which skeinforge can then slice.
-
-==Operation==
-The default 'Activate Multiply' checkbox is on.  When it is on, the functions described below will work, when it is off, nothing will be done.
-
-==Settings==
-===Center===
-Default is the origin.
-
-The center of the shape will be moved to the "Center X" and "Center Y" coordinates.
-
-====Center X====
-====Center Y====
-
-===Number of Cells===
-====Number of Columns====
-Default is one.
-
-Defines the number of columns in the array table.
-
-====Number of Rows====
-Default is one.
-
-Defines the number of rows in the table.
-
-===Reverse Sequence every Odd Layer===
-Default is off.
-
-When selected the build sequence will be reversed on every odd layer so that the tool will travel less.  The problem is that the builds would be made with different amount of time to cool, so some would be too hot and some too cold, which is why the default is off.
-
-===Separation over Perimeter Width===
-Default is fifteen.
-
-Defines the ratio of separation between the shape copies over the edge width.
-
-==Examples==
-The following examples multiply the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and multiply.py.
-
-> python multiply.py
-This brings up the multiply dialog.
-
-> python multiply.py Screw Holder Bottom.stl
-The multiply tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The multiply tool has created the file:
-.. Screw Holder Bottom_multiply.gcode
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText(fileName, text='', repository=None):
-       'Multiply the fill file or text.'
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository)
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       'Multiply the fill text.'
-       if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'multiply'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository(MultiplyRepository())
-       if not repository.activateMultiply.value:
-               return gcodeText
-       return MultiplySkein().getCraftedGcode(gcodeText, repository)
-
-def getNewRepository():
-       'Get new repository.'
-       return MultiplyRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       'Multiply a gcode linear move file.'
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'multiply', shouldAnalyze)
-
-
-class MultiplyRepository(object):
-       'A class to handle the multiply settings.'
-       def __init__(self):
-               'Set the default settings, execute title & settings fileName.'
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.multiply.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName(
-                       fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Multiply', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Multiply')
-               self.activateMultiply = settings.BooleanSetting().getFromValue('Activate Multiply', self, True)
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Center -', self )
-               self.centerX = settings.FloatSpin().getFromValue(-100.0, 'Center X (mm):', self, 100.0, 105.0)
-               self.centerY = settings.FloatSpin().getFromValue(-100.0, 'Center Y (mm):', self, 100.0, 105.0)
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Number of Cells -', self)
-               self.numberOfColumns = settings.IntSpin().getFromValue(1, 'Number of Columns (integer):', self, 10, 1)
-               self.numberOfRows = settings.IntSpin().getFromValue(1, 'Number of Rows (integer):', self, 10, 1)
-               settings.LabelSeparator().getFromRepository(self)
-               self.reverseSequenceEveryOddLayer = settings.BooleanSetting().getFromValue('Reverse Sequence every Odd Layer', self, False)
-               self.separationOverEdgeWidth = settings.FloatSpin().getFromValue(5.0, 'Separation over Perimeter Width (ratio):', self, 25.0, 15.0)
-               self.executeTitle = 'Multiply'
-
-       def execute(self):
-               'Multiply button has been clicked.'
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(
-                       self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class MultiplySkein(object):
-       'A class to multiply a skein of extrusions.'
-       def __init__(self):
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.isExtrusionActive = False
-               self.layerIndex = 0
-               self.layerLines = []
-               self.lineIndex = 0
-               self.lines = None
-               self.oldLocation = None
-               self.rowIndex = 0
-               self.shouldAccumulate = True
-
-       def addElement(self, offset):
-               'Add moved element to the output.'
-               for line in self.layerLines:
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == '(<boundaryPoint>':
-                               movedLocation = self.getMovedLocationSetOldLocation(offset, splitLine)
-                               line = self.distanceFeedRate.getBoundaryLine(movedLocation)
-                       elif firstWord == 'G1':
-                               movedLocation = self.getMovedLocationSetOldLocation(offset, splitLine)
-                               line = self.distanceFeedRate.getLinearGcodeMovement(movedLocation.dropAxis(), movedLocation.z)
-                       elif firstWord == '(<infillPoint>':
-                               movedLocation = self.getMovedLocationSetOldLocation(offset, splitLine)
-                               line = self.distanceFeedRate.getInfillBoundaryLine(movedLocation)
-                       self.distanceFeedRate.addLine(line)
-
-       def addLayer(self):
-               'Add multiplied layer to the output.'
-               self.addRemoveThroughLayer()
-               offset = self.centerOffset - self.arrayCenter - self.shapeCenter
-               for rowIndex in xrange(self.repository.numberOfRows.value):
-                       yRowOffset = float(rowIndex) * self.extentPlusSeparation.imag
-                       if self.layerIndex % 2 == 1 and self.repository.reverseSequenceEveryOddLayer.value:
-                               yRowOffset = self.arrayExtent.imag - yRowOffset
-                       for columnIndex in xrange(self.repository.numberOfColumns.value):
-                               xColumnOffset = float(columnIndex) * self.extentPlusSeparation.real
-                               if self.rowIndex % 2 == 1:
-                                       xColumnOffset = self.arrayExtent.real - xColumnOffset
-                               elementOffset = complex(offset.real + xColumnOffset, offset.imag + yRowOffset)
-                               self.addElement(elementOffset)
-                       self.rowIndex += 1
-               settings.printProgress(self.layerIndex, 'multiply')
-               if len(self.layerLines) > 1:
-                       self.layerIndex += 1
-               self.layerLines = []
-
-       def addRemoveThroughLayer(self):
-               'Parse gcode initialization and store the parameters.'
-               for layerLineIndex in xrange(len(self.layerLines)):
-                       line = self.layerLines[layerLineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.addLine(line)
-                       if firstWord == '(<layer>':
-                               self.layerLines = self.layerLines[layerLineIndex + 1 :]
-                               return
-
-       def getCraftedGcode(self, gcodeText, repository):
-               'Parse gcode text and store the multiply gcode.'
-               self.centerOffset = complex(repository.centerX.value, repository.centerY.value)
-               self.repository = repository
-               self.numberOfColumns = repository.numberOfColumns.value
-               self.numberOfRows = repository.numberOfRows.value
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization()
-               self.setCorners()
-               for line in self.lines[self.lineIndex :]:
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def getMovedLocationSetOldLocation(self, offset, splitLine):
-               'Get the moved location and set the old location.'
-               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               self.oldLocation = location
-               return Vector3(location.x + offset.real, location.y + offset.imag, location.z)
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('multiply')
-                               self.distanceFeedRate.addLine(line)
-                               self.lineIndex += 1
-                               return
-                       elif firstWord == '(<edgeWidth>':
-                               self.absoluteEdgeWidth = abs(float(splitLine[1]))
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               'Parse a gcode line and add it to the multiply skein.'
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == '(</layer>)':
-                       self.addLayer()
-                       self.distanceFeedRate.addLine(line)
-                       return
-               elif firstWord == '(</crafting>)':
-                       self.shouldAccumulate = False
-               if self.shouldAccumulate:
-                       self.layerLines.append(line)
-                       return
-               self.distanceFeedRate.addLine(line)
-
-       def setCorners(self):
-               'Set maximum and minimum corners and z.'
-               cornerMaximumComplex = complex(-987654321.0, -987654321.0)
-               cornerMinimumComplex = -cornerMaximumComplex
-               for line in self.lines[self.lineIndex :]:
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1':
-                               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-                               if self.isExtrusionActive:
-                                       locationComplex = location.dropAxis()
-                                       cornerMaximumComplex = euclidean.getMaximum(locationComplex,  cornerMaximumComplex)
-                                       cornerMinimumComplex = euclidean.getMinimum(locationComplex,  cornerMinimumComplex)
-                               self.oldLocation = location
-                       elif firstWord == 'M101':
-                               self.isExtrusionActive = True
-                       elif firstWord == 'M103':
-                               self.isExtrusionActive = False
-               self.extent = cornerMaximumComplex - cornerMinimumComplex
-               self.shapeCenter = 0.5 * (cornerMaximumComplex + cornerMinimumComplex)
-               self.separation = self.repository.separationOverEdgeWidth.value * self.absoluteEdgeWidth
-               self.extentPlusSeparation = self.extent + complex(self.separation, self.separation)
-               columnsMinusOne = self.numberOfColumns - 1
-               rowsMinusOne = self.numberOfRows - 1
-               self.arrayExtent = complex(self.extentPlusSeparation.real * columnsMinusOne, self.extentPlusSeparation.imag * rowsMinusOne)
-               self.arrayCenter = 0.5 * self.arrayExtent
-
-
-def main():
-       'Display the multiply dialog.'
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == '__main__':
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/oozebane.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/oozebane.py
deleted file mode 100644 (file)
index a16ab6d..0000000
+++ /dev/null
@@ -1,578 +0,0 @@
-"""
-This page is in the table of contents.
-Oozebane is a script to turn off the extruder before the end of a thread and turn it on before the beginning.
-
-The oozebane manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Oozebane
-
-After oozebane turns the extruder on, it slows the feed rate down where the thread starts.  Then it speeds it up in steps so in theory the thread will remain at roughly the same thickness from the beginning.
-
-==Operation==
-The default 'Activate Oozebane' checkbox is on.  When it is on, the functions described below will work, when it is off, the functions will not be called.
-
-==Settings==
-===After Startup Distance===
-Default is 1.2.
-
-When oozebane reaches the point where the extruder would of turned on, it slows down so that the thread will be thick at that point.  Afterwards it speeds the extruder back up to operating speed.  The speed up distance is the "After Startup Distance".
-
-===Early Shutdown Distance===
-Default is 1.2.
-
-Defines the distance before the end of the thread that the extruder will be turned off.  It is the most important oozebane setting.  A higher distance means the extruder will turn off sooner and the end of the line will be thinner.
-
-===Early Startup Maximum Distance===
-Default is 1.2.
-
-Defines the maximum distance before the thread starts that the extruder will be turned on
-
-===Early Startup Distance Constant===
-Default is twenty.
-
-The longer the extruder has been off, the earlier the extruder will turn back on, the ratio is one minus one over e to the power of the distance the extruder has been off over the "Early Startup Distance Constant".
-
-===First Early Startup Distance===
-Default is twenty five.
-
-Defines the distance before the first thread starts that the extruder will be turned off.  This value should be high because, according to Marius, the extruder takes a second or two to extrude when starting for the first time.
-
-===Minimum Distance for Early Shutdown===
-Default is zero.
-
-Defines the minimum distance that the extruder has to be off after the thread end for the early shutdown feature to activate.
-
-===Minimum Distance for Early Startup===
-Default is zero.
-
-Defines the minimum distance that the extruder has to be off before the thread begins for the early start up feature to activate.
-
-===Slowdown Startup Steps===
-Default is three.
-
-When oozebane turns the extruder off, it slows the feed rate down in steps so in theory the thread will remain at roughly the same thickness until the end.  The "Slowdown Startup Steps" setting is the number of steps, the more steps the smaller the size of the step that the feed rate will be decreased and the larger the size of the resulting gcode file.
-
-==Examples==
-The following examples oozebane the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and oozebane.py.
-
-> python oozebane.py
-This brings up the oozebane dialog.
-
-> python oozebane.py Screw Holder Bottom.stl
-The oozebane tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The oozebane tool has created the file:
-.. Screw Holder Bottom_oozebane.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import math
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, text, oozebaneRepository = None ):
-       "Oozebane a gcode linear move file or text."
-       return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), oozebaneRepository )
-
-def getCraftedTextFromText( gcodeText, oozebaneRepository = None ):
-       "Oozebane a gcode linear move text."
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'oozebane'):
-               return gcodeText
-       if oozebaneRepository == None:
-               oozebaneRepository = settings.getReadRepository( OozebaneRepository() )
-       if not oozebaneRepository.activateOozebane.value:
-               return gcodeText
-       return OozebaneSkein().getCraftedGcode( gcodeText, oozebaneRepository )
-
-def getNewRepository():
-       'Get new repository.'
-       return OozebaneRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Oozebane a gcode linear move file."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'oozebane', shouldAnalyze)
-
-
-class OozebaneRepository(object):
-       "A class to handle the oozebane settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.oozebane.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Oozebane', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Oozebane')
-               self.activateOozebane = settings.BooleanSetting().getFromValue('Activate Oozebane', self, False )
-               self.afterStartupDistance = settings.FloatSpin().getFromValue( 0.7, 'After Startup Distance (millimeters):', self, 1.7, 1.2 )
-               self.earlyShutdownDistance = settings.FloatSpin().getFromValue( 0.7, 'Early Shutdown Distance (millimeters):', self, 1.7, 1.2 )
-               self.earlyStartupDistanceConstant = settings.FloatSpin().getFromValue( 10.0, 'Early Startup Distance Constant (millimeters):', self, 30.0, 20.0 )
-               self.earlyStartupMaximumDistance = settings.FloatSpin().getFromValue( 0.7, 'Early Startup Maximum Distance (millimeters):', self, 1.7, 1.2 )
-               self.firstEarlyStartupDistance = settings.FloatSpin().getFromValue( 5.0, 'First Early Startup Distance (millimeters):', self, 45.0, 25.0 )
-               self.minimumDistanceForEarlyStartup = settings.FloatSpin().getFromValue( 0.0, 'Minimum Distance for Early Startup (millimeters):', self, 10.0, 0.0 )
-               self.minimumDistanceForEarlyShutdown = settings.FloatSpin().getFromValue( 0.0, 'Minimum Distance for Early Shutdown (millimeters):', self, 10.0, 0.0 )
-               self.slowdownStartupSteps = settings.IntSpin().getFromValue( 2, 'Slowdown Startup Steps (positive integer):', self, 5, 3 )
-               self.executeTitle = 'Oozebane'
-
-       def execute(self):
-               "Oozebane button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class OozebaneSkein(object):
-       "A class to oozebane a skein of extrusions."
-       def __init__(self):
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.distanceFromThreadEndToThreadBeginning = None
-               self.earlyStartupDistance = None
-               self.extruderInactiveLongEnough = True
-               self.feedRateMinute = 961.0
-               self.isExtruderActive = False
-               self.isFirstExtrusion = True
-               self.isShutdownEarly = False
-               self.isStartupEarly = False
-               self.lineIndex = 0
-               self.lines = None
-               self.oldLocation = None
-               self.operatingFeedRateMinute = 959.0
-               self.shutdownStepIndex = 999999999
-               self.startupStepIndex = 999999999
-
-       def addAfterStartupLine( self, splitLine ):
-               "Add the after startup lines."
-               distanceAfterThreadBeginning = self.getDistanceAfterThreadBeginning()
-               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               segment = self.oldLocation - location
-               segmentLength = segment.magnitude()
-               distanceBack = distanceAfterThreadBeginning - self.afterStartupDistances[ self.startupStepIndex ]
-               if segmentLength > 0.0:
-                       locationBack = location + segment * distanceBack / segmentLength
-                       feedRate = self.operatingFeedRateMinute * self.afterStartupFlowRates[ self.startupStepIndex ]
-                       if not self.isCloseToEither( locationBack, location, self.oldLocation ):
-                               self.distanceFeedRate.addLine( self.getLinearMoveWithFeedRate( feedRate, locationBack ) )
-               self.startupStepIndex += 1
-
-       def addLineSetShutdowns(self, line):
-               "Add a line and set the shutdown variables."
-               self.distanceFeedRate.addLine(line)
-               self.isShutdownEarly = True
-
-       def getActiveFeedRateRatio(self):
-               "Get the feed rate of the first active move over the operating feed rate."
-               isSearchExtruderActive = self.isExtruderActive
-               for afterIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[ afterIndex ]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1':
-                               if isSearchExtruderActive:
-                                       return gcodec.getFeedRateMinute( self.feedRateMinute, splitLine ) / self.operatingFeedRateMinute
-                       elif firstWord == 'M101':
-                               isSearchExtruderActive = True
-               print('active feed rate ratio was not found in oozebane.')
-               return 1.0
-
-       def getAddAfterStartupLines(self, line):
-               "Get and / or add after the startup lines."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               while self.isDistanceAfterThreadBeginningGreater():
-                       self.addAfterStartupLine(splitLine)
-               if self.startupStepIndex >= len( self.afterStartupDistances ):
-                       self.startupStepIndex = len( self.afterStartupDistances ) + 999999999999
-                       return self.getLinearMoveWithFeedRateSplitLine( self.operatingFeedRateMinute, splitLine )
-               feedRate = self.operatingFeedRateMinute * self.getStartupFlowRateMultiplier( self.getDistanceAfterThreadBeginning() / self.afterStartupDistance, len( self.afterStartupDistances ) )
-               return self.getLinearMoveWithFeedRateSplitLine( feedRate, splitLine )
-
-       def getAddBeforeStartupLines(self, line):
-               "Get and / or add before the startup lines."
-               distanceThreadBeginning = self.getDistanceToThreadBeginning()
-               if distanceThreadBeginning == None:
-                       return line
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               self.extruderInactiveLongEnough = False
-               self.isStartupEarly = True
-               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               segment = self.oldLocation - location
-               segmentLength = segment.magnitude()
-               distanceBack = self.earlyStartupDistance - distanceThreadBeginning
-               if segmentLength <= 0.0:
-                       print('This should never happen, segmentLength is zero in getAddBeforeStartupLines in oozebane.')
-                       print(line)
-                       self.extruderInactiveLongEnough = True
-                       self.isStartupEarly = False
-                       return line
-               locationBack = location + segment * distanceBack / segmentLength
-               self.distanceFeedRate.addLine( self.getLinearMoveWithFeedRate( gcodec.getFeedRateMinute( self.feedRateMinute, splitLine ) , locationBack ) )
-               self.distanceFeedRate.addLine('M101')
-               if self.isCloseToEither( locationBack, location, self.oldLocation ):
-                       return ''
-               return self.getLinearMoveWithFeedRate( self.operatingFeedRateMinute, location )
-
-       def getAddShutSlowDownLine(self, line):
-               "Add the shutdown and slowdown lines."
-               if self.shutdownStepIndex >= len( self.earlyShutdownDistances ):
-                       self.shutdownStepIndex = len( self.earlyShutdownDistances ) + 99999999
-                       return False
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               distanceThreadEnd = self.getDistanceToExtruderOffCommand( self.earlyShutdownDistances[ self.shutdownStepIndex ] )
-               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               if distanceThreadEnd == None:
-                       distanceThreadEnd = self.getDistanceToExtruderOffCommand( self.earlyShutdownDistances[0] )
-                       if distanceThreadEnd != None:
-                               shutdownFlowRateMultiplier = self.getShutdownFlowRateMultiplier( 1.0 - distanceThreadEnd / self.earlyShutdownDistance, len( self.earlyShutdownDistances ) )
-                               line = self.getLinearMoveWithFeedRate( self.feedRateMinute * shutdownFlowRateMultiplier, location )
-                       self.distanceFeedRate.addLine(line)
-                       return False
-               segment = self.oldLocation - location
-               segmentLength = segment.magnitude()
-               distanceBack = self.earlyShutdownDistances[ self.shutdownStepIndex ] - distanceThreadEnd
-               locationBack = location
-               if segmentLength > 0.0:
-                       locationBack = location + segment * distanceBack / segmentLength
-               if self.shutdownStepIndex == 0:
-                       if not self.isCloseToEither( locationBack, location, self.oldLocation ):
-                               line = self.getLinearMoveWithFeedRate( self.feedRateMinute, locationBack )
-                       self.distanceFeedRate.addLine(line)
-                       self.addLineSetShutdowns('M103')
-                       return True
-               if self.isClose( locationBack, self.oldLocation ):
-                       return True
-               feedRate = self.feedRateMinute * self.earlyShutdownFlowRates[ self.shutdownStepIndex ]
-               line = self.getLinearMoveWithFeedRate( feedRate, locationBack )
-               if self.isClose( locationBack, location ):
-                       line = self.getLinearMoveWithFeedRate( feedRate, location )
-               self.distanceFeedRate.addLine(line)
-               return True
-
-       def getAddShutSlowDownLines(self, line):
-               "Get and / or add the shutdown and slowdown lines."
-               while self.getAddShutSlowDownLine(line):
-                       self.shutdownStepIndex += 1
-               return ''
-
-       def getCraftedGcode( self, gcodeText, oozebaneRepository ):
-               "Parse gcode text and store the oozebane gcode."
-               self.lines = archive.getTextLines(gcodeText)
-               self.oozebaneRepository = oozebaneRepository
-               self.parseInitialization( oozebaneRepository )
-               for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def getDistanceAfterThreadBeginning(self):
-               "Get the distance after the beginning of the thread."
-               line = self.lines[self.lineIndex]
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               lastThreadLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               totalDistance = 0.0
-               extruderOnReached = False
-               for beforeIndex in xrange( self.lineIndex - 1, 3, - 1 ):
-                       line = self.lines[ beforeIndex ]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1':
-                               location = gcodec.getLocationFromSplitLine( lastThreadLocation, splitLine )
-                               totalDistance += location.distance( lastThreadLocation )
-                               lastThreadLocation = location
-                               if extruderOnReached:
-                                       return totalDistance
-                       elif firstWord == 'M101':
-                               extruderOnReached = True
-               return None
-
-       def getDistanceToExtruderOffCommand( self, remainingDistance ):
-               "Get the distance to the word."
-               line = self.lines[self.lineIndex]
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               lastThreadLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               totalDistance = 0.0
-               for afterIndex in xrange( self.lineIndex + 1, len(self.lines) ):
-                       line = self.lines[ afterIndex ]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1':
-                               location = gcodec.getLocationFromSplitLine( lastThreadLocation, splitLine )
-                               totalDistance += location.distance( lastThreadLocation )
-                               lastThreadLocation = location
-                               if totalDistance >= remainingDistance:
-                                       return None
-                       elif firstWord == 'M103':
-                               return totalDistance
-               return None
-
-       def getDistanceToThreadBeginning(self):
-               "Get the distance to the beginning of the thread."
-               if self.earlyStartupDistance == None:
-                       return None
-               line = self.lines[self.lineIndex]
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               lastThreadLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               totalDistance = 0.0
-               for afterIndex in xrange( self.lineIndex + 1, len(self.lines) ):
-                       line = self.lines[ afterIndex ]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1':
-                               location = gcodec.getLocationFromSplitLine( lastThreadLocation, splitLine )
-                               totalDistance += location.distance( lastThreadLocation )
-                               lastThreadLocation = location
-                               if totalDistance >= self.earlyStartupDistance:
-                                       return None
-                       elif firstWord == 'M101':
-                               return totalDistance
-               return None
-
-       def getDistanceToThreadBeginningAfterThreadEnd( self, remainingDistance ):
-               "Get the distance to the thread beginning after the end of this thread."
-               extruderOnReached = False
-               line = self.lines[self.lineIndex]
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               lastThreadLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               threadEndReached = False
-               totalDistance = 0.0
-               for afterIndex in xrange( self.lineIndex + 1, len(self.lines) ):
-                       line = self.lines[ afterIndex ]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1':
-                               location = gcodec.getLocationFromSplitLine( lastThreadLocation, splitLine )
-                               if threadEndReached:
-                                       totalDistance += location.distance( lastThreadLocation )
-                                       if totalDistance >= remainingDistance:
-                                               return None
-                                       if extruderOnReached:
-                                               return totalDistance
-                               lastThreadLocation = location
-                       elif firstWord == 'M101':
-                               extruderOnReached = True
-                       elif firstWord == 'M103':
-                               threadEndReached = True
-               return None
-
-       def getDistanceToThreadEnd(self):
-               "Get the distance to the end of the thread."
-               if self.shutdownStepIndex >= len( self.earlyShutdownDistances ):
-                       return None
-               return self.getDistanceToExtruderOffCommand( self.earlyShutdownDistances[ self.shutdownStepIndex ] )
-
-       def getLinearMoveWithFeedRate( self, feedRate, location ):
-               "Get a linear move line with the feed rate."
-               return self.distanceFeedRate.getLinearGcodeMovementWithFeedRate( feedRate, location.dropAxis(), location.z )
-
-       def getLinearMoveWithFeedRateSplitLine( self, feedRate, splitLine ):
-               "Get a linear move line with the feed rate and split line."
-               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               return self.getLinearMoveWithFeedRate( feedRate, location )
-
-       def getOozebaneLine(self, line):
-               "Get oozebaned gcode line."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               self.feedRateMinute = gcodec.getFeedRateMinute( self.feedRateMinute, splitLine )
-               if self.oldLocation == None:
-                       return line
-               if self.startupStepIndex < len( self.afterStartupDistances ):
-                       return self.getAddAfterStartupLines(line)
-               if self.extruderInactiveLongEnough:
-                       return self.getAddBeforeStartupLines(line)
-               if self.shutdownStepIndex < len( self.earlyShutdownDistances ):
-                       return self.getAddShutSlowDownLines(line)
-               if self.isStartupEarly:
-                       return self.getLinearMoveWithFeedRateSplitLine( self.operatingFeedRateMinute, splitLine )
-               return line
-
-       def getShutdownFlowRateMultiplier( self, along, numberOfDistances ):
-               "Get the shut down flow rate multipler."
-               if numberOfDistances <= 0:
-                       return 1.0
-               return 1.0 - 0.5 / float( numberOfDistances ) - along * float( numberOfDistances - 1 ) / float( numberOfDistances )
-
-       def getStartupFlowRateMultiplier( self, along, numberOfDistances ):
-               "Get the startup flow rate multipler."
-               if numberOfDistances <= 0:
-                       return 1.0
-               return min( 1.0, 0.5 / float( numberOfDistances ) + along )
-
-       def isClose( self, location, otherLocation ):
-               "Determine if the location is close to the other location."
-               return location.distanceSquared( otherLocation ) < self.closeSquared
-
-       def isCloseToEither( self, location, otherLocationFirst, otherLocationSecond ):
-               "Determine if the location is close to the other locations."
-               if self.isClose( location, otherLocationFirst ):
-                       return True
-               return self.isClose( location, otherLocationSecond )
-
-       def isDistanceAfterThreadBeginningGreater(self):
-               "Determine if the distance after the thread beginning is greater than the step index after startup distance."
-               if self.startupStepIndex >= len( self.afterStartupDistances ):
-                       return False
-               return self.getDistanceAfterThreadBeginning() > self.afterStartupDistances[ self.startupStepIndex ]
-
-       def parseInitialization( self, oozebaneRepository ):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('oozebane')
-                               return
-                       elif firstWord == '(<operatingFeedRatePerSecond>':
-                               self.operatingFeedRateMinute = 60.0 * float(splitLine[1])
-                               self.feedRateMinute = self.operatingFeedRateMinute
-                       elif firstWord == '(<edgeWidth>':
-                               self.edgeWidth = float(splitLine[1])
-                               self.setExtrusionWidth( oozebaneRepository )
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               "Parse a gcode line and add it to the bevel gcode."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       self.setEarlyStartupDistance(splitLine)
-                       line = self.getOozebaneLine(line)
-                       self.oldLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               elif firstWord == 'M101':
-                       self.isExtruderActive = True
-                       self.extruderInactiveLongEnough = False
-                       if self.getDistanceToExtruderOffCommand( self.earlyShutdownDistance ) == None:
-                               self.setEarlyShutdown()
-                       if self.getDistanceToExtruderOffCommand( 1.03 * ( self.earlyShutdownDistance + self.afterStartupDistance ) ) == None:
-                               afterStartupRatio = 1.0
-                               if self.minimumDistanceForEarlyStartup > 0.0:
-                                       if self.distanceFromThreadEndToThreadBeginning != None:
-                                               afterStartupRatio = self.distanceFromThreadEndToThreadBeginning / self.minimumDistanceForEarlyStartup
-                               self.setAfterStartupFlowRates( afterStartupRatio )
-                               self.startupStepIndex = 9999999999
-                               if len( self.afterStartupDistances ) > 0:
-                                       self.startupStepIndex = 0
-                       if self.isStartupEarly:
-                               self.isStartupEarly = False
-                               return
-               elif firstWord == 'M103':
-                       self.isExtruderActive = False
-                       self.shutdownStepIndex = 999999999
-                       if self.getDistanceToThreadBeginning() == None:
-                               self.extruderInactiveLongEnough = True
-                       self.distanceFromThreadEndToThreadBeginning = None
-                       self.earlyStartupDistance = None
-                       if self.isShutdownEarly:
-                               self.isShutdownEarly = False
-                               return
-               self.distanceFeedRate.addLine(line)
-
-       def setAfterStartupFlowRates( self, afterStartupRatio ):
-               "Set the after startup flow rates."
-               afterStartupRatio = min( 1.0, afterStartupRatio )
-               afterStartupRatio = max( 0.0, afterStartupRatio )
-               self.afterStartupDistance = afterStartupRatio * self.getActiveFeedRateRatio() * self.oozebaneRepository.afterStartupDistance.value
-               self.afterStartupDistances = []
-               self.afterStartupFlowRate = 1.0
-               self.afterStartupFlowRates = []
-               afterStartupSteps = int( math.floor( afterStartupRatio * float( self.oozebaneRepository.slowdownStartupSteps.value ) ) )
-               if afterStartupSteps < 1:
-                       return
-               if afterStartupSteps < 2:
-                       afterStartupSteps = 2
-               for stepIndex in xrange( afterStartupSteps ):
-                       afterWay = ( stepIndex + 1 ) / float( afterStartupSteps )
-                       afterMiddleWay = self.getStartupFlowRateMultiplier( stepIndex / float( afterStartupSteps ), afterStartupSteps )
-                       self.afterStartupDistances.append( afterWay * self.afterStartupDistance )
-                       if stepIndex == 0:
-                               self.afterStartupFlowRate = afterMiddleWay
-                       else:
-                               self.afterStartupFlowRates.append( afterMiddleWay )
-               if afterStartupSteps > 0:
-                       self.afterStartupFlowRates.append(1.0)
-
-       def setEarlyShutdown(self):
-               "Set the early shutdown variables."
-               distanceToThreadBeginning = self.getDistanceToThreadBeginningAfterThreadEnd( self.minimumDistanceForEarlyShutdown )
-               earlyShutdownRatio = 1.0
-               if distanceToThreadBeginning != None:
-                       if self.minimumDistanceForEarlyShutdown > 0.0:
-                               earlyShutdownRatio = distanceToThreadBeginning / self.minimumDistanceForEarlyShutdown
-               self.setEarlyShutdownFlowRates( earlyShutdownRatio )
-               if len( self.earlyShutdownDistances ) > 0:
-                       self.shutdownStepIndex = 0
-
-       def setEarlyShutdownFlowRates( self, earlyShutdownRatio ):
-               "Set the extrusion width."
-               earlyShutdownRatio = min( 1.0, earlyShutdownRatio )
-               earlyShutdownRatio = max( 0.0, earlyShutdownRatio )
-               self.earlyShutdownDistance = earlyShutdownRatio * self.getActiveFeedRateRatio() * self.oozebaneRepository.earlyShutdownDistance.value
-               self.earlyShutdownDistances = []
-               self.earlyShutdownFlowRates = []
-               earlyShutdownSteps = int( math.floor( earlyShutdownRatio * float( self.oozebaneRepository.slowdownStartupSteps.value ) ) )
-               if earlyShutdownSteps < 2:
-                       earlyShutdownSteps = 0
-               earlyShutdownStepsMinusOne = float( earlyShutdownSteps ) - 1.0
-               for stepIndex in xrange( earlyShutdownSteps ):
-                       downMiddleWay = self.getShutdownFlowRateMultiplier( stepIndex / earlyShutdownStepsMinusOne, earlyShutdownSteps )
-                       downWay = 1.0 - stepIndex / earlyShutdownStepsMinusOne
-                       self.earlyShutdownFlowRates.append( downMiddleWay )
-                       self.earlyShutdownDistances.append( downWay * self.earlyShutdownDistance )
-
-       def setEarlyStartupDistance( self, splitLine ):
-               "Set the early startup distance."
-               if self.earlyStartupDistance != None:
-                       return
-               self.distanceFromThreadEndToThreadBeginning = 0.0
-               lastThreadLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               if self.oldLocation != None:
-                       self.distanceFromThreadEndToThreadBeginning = lastThreadLocation.distance( self.oldLocation )
-               for afterIndex in xrange( self.lineIndex + 1, len(self.lines) ):
-                       line = self.lines[ afterIndex ]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1':
-                               location = gcodec.getLocationFromSplitLine( lastThreadLocation, splitLine )
-                               self.distanceFromThreadEndToThreadBeginning += location.distance( lastThreadLocation )
-                               lastThreadLocation = location
-                       elif firstWord == 'M101':
-                               distanceConstantRatio = self.distanceFromThreadEndToThreadBeginning / self.earlyStartupDistanceConstant
-                               earlyStartupOperatingDistance = self.earlyStartupMaximumDistance * ( 1.0 - math.exp( - distanceConstantRatio ) )
-                               if self.isFirstExtrusion:
-                                       earlyStartupOperatingDistance = self.oozebaneRepository.firstEarlyStartupDistance.value
-                                       self.isFirstExtrusion = False
-                               self.earlyStartupDistance = earlyStartupOperatingDistance * self.getActiveFeedRateRatio()
-                               return
-
-       def setExtrusionWidth( self, oozebaneRepository ):
-               "Set the extrusion width."
-               self.closeSquared = 0.01 * self.edgeWidth * self.edgeWidth
-               self.earlyStartupMaximumDistance = oozebaneRepository.earlyStartupMaximumDistance.value
-               self.earlyStartupDistanceConstant = oozebaneRepository.earlyStartupDistanceConstant.value
-               self.minimumDistanceForEarlyStartup = oozebaneRepository.minimumDistanceForEarlyStartup.value
-               self.minimumDistanceForEarlyShutdown = oozebaneRepository.minimumDistanceForEarlyShutdown.value
-               self.setEarlyShutdownFlowRates(1.0)
-               self.setAfterStartupFlowRates(1.0)
-
-
-def main():
-       "Display the oozebane dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/outset.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/outset.py
deleted file mode 100644 (file)
index be38937..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-"""
-This page is in the table of contents.
-Outset outsets the edges of the slices of a gcode file.  The outside edges will be outset by half the edge width, and the inside edges will be inset by half the edge width.  Outset is needed for subtractive machining, like cutting or milling.
-
-==Operation==
-The default 'Activate Outset' checkbox is on.  When it is on, the gcode will be outset, when it is off, the gcode will not be changed.
-
-==Examples==
-The following examples outset the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and outset.py.
-
-> python outset.py
-This brings up the outset dialog.
-
-> python outset.py Screw Holder Bottom.stl
-The outset tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The outset tool has created the file:
-.. Screw Holder Bottom_outset.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import intercircle
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, text='', repository=None):
-       'Outset the preface file or text.'
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository)
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       'Outset the preface gcode text.'
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'outset'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository( OutsetRepository() )
-       if not repository.activateOutset.value:
-               return gcodeText
-       return OutsetSkein().getCraftedGcode(gcodeText, repository)
-
-def getNewRepository():
-       'Get new repository.'
-       return OutsetRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       'Outset the carving of a gcode file.'
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'outset', shouldAnalyze)
-
-
-class OutsetRepository(object):
-       'A class to handle the outset settings.'
-       def __init__(self):
-               'Set the default settings, execute title & settings fileName.'
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.outset.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Outset', self, '')
-               self.activateOutset = settings.BooleanSetting().getFromValue('Activate Outset', self, True )
-               self.executeTitle = 'Outset'
-
-       def execute(self):
-               'Outset button has been clicked.'
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class OutsetSkein(object):
-       'A class to outset a skein of extrusions.'
-       def __init__(self):
-               self.boundary = None
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.layerCount = settings.LayerCount()
-               self.lineIndex = 0
-               self.loopLayer = None
-
-       def addGcodeFromRemainingLoop( self, loop, radius, z ):
-               'Add the remainder of the loop.'
-               boundary = intercircle.getLargestInsetLoopFromLoopRegardless( loop, radius )
-               euclidean.addNestedRingBeginning( self.distanceFeedRate, boundary, z )
-               self.distanceFeedRate.addPerimeterBlock(loop, z)
-               self.distanceFeedRate.addLine('(</boundaryPerimeter>)')
-               self.distanceFeedRate.addLine('(</nestedRing>)')
-
-       def addOutset(self, loopLayer):
-               'Add outset to the layer.'
-               extrudateLoops = intercircle.getInsetLoopsFromLoops(loopLayer.loops, -self.absoluteHalfEdgeWidth)
-               triangle_mesh.sortLoopsInOrderOfArea(False, extrudateLoops)
-               for extrudateLoop in extrudateLoops:
-                       self.addGcodeFromRemainingLoop(extrudateLoop, self.absoluteHalfEdgeWidth, loopLayer.z)
-
-       def getCraftedGcode(self, gcodeText, repository):
-               'Parse gcode text and store the bevel gcode.'
-               self.repository = repository
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization()
-               for lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       self.parseLine( lineIndex )
-               return self.distanceFeedRate.output.getvalue()
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex].lstrip()
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('outset')
-                               return
-                       elif firstWord == '(<edgeWidth>':
-                               self.absoluteHalfEdgeWidth = 0.5 * abs(float(splitLine[1]))
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine( self, lineIndex ):
-               'Parse a gcode line and add it to the outset skein.'
-               line = self.lines[lineIndex].lstrip()
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == '(<boundaryPoint>':
-                       location = gcodec.getLocationFromSplitLine(None, splitLine)
-                       self.boundary.append(location.dropAxis())
-               elif firstWord == '(<layer>':
-                       self.layerCount.printProgressIncrement('outset')
-                       self.loopLayer = euclidean.LoopLayer(float(splitLine[1]))
-                       self.distanceFeedRate.addLine(line)
-               elif firstWord == '(</layer>)':
-                       self.addOutset( self.loopLayer )
-                       self.loopLayer = None
-               elif firstWord == '(<nestedRing>)':
-                       self.boundary = []
-                       self.loopLayer.loops.append( self.boundary )
-               if self.loopLayer == None:
-                       self.distanceFeedRate.addLine(line)
-
-
-def main():
-       'Display the outset dialog.'
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == '__main__':
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/preface.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/preface.py
deleted file mode 100644 (file)
index 5b36203..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-#! /usr/bin/env python
-"""
-This page is in the table of contents.
-Preface converts the svg slices into gcode extrusion layers, optionally with home, positioning, turn off, and unit commands.
-
-The preface manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Preface
-
-==Settings==
-===Meta===
-Default is empty.
-
-The 'Meta' field is to add meta tags or a note to all your files.  Whatever is in that field will be added in a meta tagged line to the output.
-
-===Set Positioning to Absolute===
-Default is on.
-
-When selected, preface will add the G90 command to set positioning to absolute.
-
-===Set Units to Millimeters===
-Default is on.
-
-When selected, preface will add the G21 command to set the units to millimeters.
-
-===Start at Home===
-Default is off.
-
-When selected, the G28 go to home gcode will be added at the beginning of the file.
-
-===Turn Extruder Off===
-====Turn Extruder Off at Shut Down====
-Default is on.
-
-When selected, the M103 turn extruder off gcode will be added at the end of the file.
-
-====Turn Extruder Off at Start Up====
-Default is on.
-
-When selected, the M103 turn extruder off gcode will be added at the beginning of the file.
-
-==Examples==
-The following examples preface the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and preface.py.
-
-> python preface.py
-This brings up the preface dialog.
-
-> python preface.py Screw Holder Bottom.stl
-The preface tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The preface tool has created the file:
-.. Screw Holder Bottom_preface.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from datetime import date, datetime
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.svg_reader import SVGReader
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-from time import strftime
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, text='', repository = None ):
-       "Preface and convert an svg file or text."
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository)
-
-def getCraftedTextFromText( text, repository = None ):
-       "Preface and convert an svg text."
-       if gcodec.isProcedureDoneOrFileIsEmpty( text, 'preface'):
-               return text
-       if repository == None:
-               repository = settings.getReadRepository(PrefaceRepository())
-       return PrefaceSkein().getCraftedGcode(repository, text)
-
-def getNewRepository():
-       'Get new repository.'
-       return PrefaceRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Preface the carving of a gcode file."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'preface', shouldAnalyze)
-
-
-class PrefaceRepository(object):
-       "A class to handle the preface settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.preface.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Preface', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Preface')
-               self.meta = settings.StringSetting().getFromValue('Meta:', self, '')
-               self.setPositioningToAbsolute = settings.BooleanSetting().getFromValue('Set Positioning to Absolute', self, True )
-               self.setUnitsToMillimeters = settings.BooleanSetting().getFromValue('Set Units to Millimeters', self, True )
-               self.startAtHome = settings.BooleanSetting().getFromValue('Start at Home', self, False )
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Turn Extruder Off -', self )
-               self.turnExtruderOffAtShutDown = settings.BooleanSetting().getFromValue('Turn Extruder Off at Shut Down', self, True )
-               self.turnExtruderOffAtStartUp = settings.BooleanSetting().getFromValue('Turn Extruder Off at Start Up', self, True )
-               self.executeTitle = 'Preface'
-
-       def execute(self):
-               "Preface button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class PrefaceSkein(object):
-       "A class to preface a skein of extrusions."
-       def __init__(self):
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.extruderActive = False
-               self.lineIndex = 0
-               self.oldLocation = None
-               self.svgReader = SVGReader()
-
-       def addInitializationToOutput(self):
-               "Add initialization gcode to the output."
-               self.distanceFeedRate.addTagBracketedLine('format', 'skeinforge gcode')
-               absoluteFilePathUntilDot = archive.getUntilDot(archive.getCraftPluginsDirectoryPath('preface.py'))
-               dateTodayString = date.today().isoformat().replace('-', '.')[2 :]
-               if absoluteFilePathUntilDot == '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/preface': #is this script on Enrique's computer?
-                       archive.writeFileText(archive.getVersionFileName(), dateTodayString)
-               versionText = archive.getFileText(archive.getVersionFileName())
-               self.distanceFeedRate.addTagBracketedLine('version', versionText)
-               dateTimeTuple = datetime.now().timetuple()
-               created = dateTodayString + '|%s:%s' % (dateTimeTuple[3], dateTimeTuple[4])
-               self.distanceFeedRate.addTagBracketedLine('created', created)
-               self.distanceFeedRate.addLine('(<extruderInitialization>)')
-               if self.repository.setPositioningToAbsolute.value:
-                       self.distanceFeedRate.addLine('G90 ;set positioning to absolute') # Set positioning to absolute.
-               if self.repository.setUnitsToMillimeters.value:
-                       self.distanceFeedRate.addLine('G21 ;set units to millimeters') # Set units to millimeters.
-               if self.repository.startAtHome.value:
-                       self.distanceFeedRate.addLine('G28 ;start at home') # Start at home.
-               if self.repository.turnExtruderOffAtStartUp.value:
-                       self.distanceFeedRate.addLine('M103') # Turn extruder off.
-               craftTypeName = skeinforge_profile.getCraftTypeName()
-               self.distanceFeedRate.addTagBracketedLine('craftTypeName', craftTypeName)
-               self.distanceFeedRate.addTagBracketedLine('decimalPlacesCarried', self.distanceFeedRate.decimalPlacesCarried)
-               layerHeight = float(self.svgReader.sliceDictionary['layerHeight'])
-               self.distanceFeedRate.addTagRoundedLine('layerThickness', layerHeight)
-               self.distanceFeedRate.addTagRoundedLine('layerHeight', layerHeight)
-               if self.repository.meta.value:
-                       self.distanceFeedRate.addTagBracketedLine('meta', self.repository.meta.value)
-               edgeWidth = float(self.svgReader.sliceDictionary['edgeWidth'])
-               self.distanceFeedRate.addTagRoundedLine('edgeWidth', edgeWidth)
-               self.distanceFeedRate.addTagRoundedLine('perimeterWidth', edgeWidth)
-               self.distanceFeedRate.addTagBracketedLine('profileName', skeinforge_profile.getProfileName(craftTypeName))
-               self.distanceFeedRate.addLine('(<settings>)')
-               pluginFileNames = skeinforge_craft.getPluginFileNames()
-               for pluginFileName in pluginFileNames:
-                       self.addToolSettingLines(pluginFileName)
-               self.distanceFeedRate.addLine('(</settings>)')
-               self.distanceFeedRate.addTagBracketedLine('timeStampPreface', strftime('%Y%m%d_%H%M%S'))
-               procedureNames = self.svgReader.sliceDictionary['procedureName'].replace(',', ' ').split()
-               for procedureName in procedureNames:
-                       self.distanceFeedRate.addTagBracketedProcedure(procedureName)
-               self.distanceFeedRate.addTagBracketedProcedure('preface')
-               self.distanceFeedRate.addLine('(</extruderInitialization>)') # Initialization is finished, extrusion is starting.
-               self.distanceFeedRate.addLine('(<crafting>)') # Initialization is finished, crafting is starting.
-
-       def addPreface( self, loopLayer ):
-               "Add preface to the carve layer."
-               self.distanceFeedRate.addLine('(<layer> %s )' % loopLayer.z ) # Indicate that a new layer is starting.
-               for loop in loopLayer.loops:
-                       self.distanceFeedRate.addGcodeFromLoop(loop, loopLayer.z)
-               self.distanceFeedRate.addLine('(</layer>)')
-
-       def addShutdownToOutput(self):
-               "Add shutdown gcode to the output."
-               self.distanceFeedRate.addLine('(</crafting>)') # GCode formatted comment
-               if self.repository.turnExtruderOffAtShutDown.value:
-                       self.distanceFeedRate.addLine('M103') # Turn extruder motor off.
-
-       def addToolSettingLines(self, pluginName):
-               "Add tool setting lines."
-               preferences = skeinforge_craft.getCraftPreferences(pluginName)
-               if skeinforge_craft.getCraftValue('Activate %s' % pluginName.capitalize(), preferences) != True:
-                       return
-               for preference in preferences:
-                       valueWithoutReturn = str(preference.value).replace('\n', ' ').replace('\r', ' ')
-                       if preference.name != 'WindowPosition' and not preference.name.startswith('Open File'):
-                               line = '%s %s %s' % (pluginName, preference.name.replace(' ', '_'), valueWithoutReturn)
-                               self.distanceFeedRate.addTagBracketedLine('setting', line)
-
-       def getCraftedGcode( self, repository, gcodeText ):
-               "Parse gcode text and store the bevel gcode."
-               self.repository = repository
-               self.svgReader.parseSVG('', gcodeText)
-               if self.svgReader.sliceDictionary == None:
-                       print('Warning, nothing will be done because the sliceDictionary could not be found getCraftedGcode in preface.')
-                       return ''
-               self.distanceFeedRate.decimalPlacesCarried = int(self.svgReader.sliceDictionary['decimalPlacesCarried'])
-               self.addInitializationToOutput()
-               for loopLayerIndex, loopLayer in enumerate(self.svgReader.loopLayers):
-                       settings.printProgressByNumber(loopLayerIndex, len(self.svgReader.loopLayers), 'preface')
-                       self.addPreface( loopLayer )
-               self.addShutdownToOutput()
-               return self.distanceFeedRate.output.getvalue()
-
-
-def main():
-       "Display the preface dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/raft.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/raft.py
deleted file mode 100644 (file)
index 1de1508..0000000
+++ /dev/null
@@ -1,1117 +0,0 @@
-"""
-This page is in the table of contents.
-Raft is a plugin to create a raft, elevate the nozzle and set the temperature.  A raft is a flat base structure on top of which your object is being build and has a few different purposes. It fills irregularities like scratches and pits in your printbed and gives you a nice base parallel to the printheads movement. It also glues your object to the bed so to prevent warping in bigger object.  The rafts base layer performs these tricks while the sparser interface layer(s) help you removing the object from the raft after printing.  It is based on the Nophead's reusable raft, which has a base layer running one way, and a couple of perpendicular layers above.  Each set of layers can be set to a different temperature.  There is the option of having the extruder orbit the raft for a while, so the heater barrel has time to reach a different temperature, without ooze accumulating around the nozzle.
-
-The raft manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Raft
-
-The important values for the raft settings are the temperatures of the raft, the first layer and the next layers.  These will be different for each material.  The default settings for ABS, HDPE, PCL & PLA are extrapolated from Nophead's experiments.
-
-You don't necessarily need a raft and especially small object will print fine on a flat bed without one, sometimes its even better when you need a water tight base to print directly on the bed.  If you want to only set the temperature or only create support material or only elevate the nozzle without creating a raft, set the Base Layers and Interface Layers to zero.
-
-<gallery perRow="1">
-Image:Raft.jpg|Raft
-</gallery>
-
-Example of a raft on the left with the interface layers partially removed exposing the base layer. Notice that the first line of the base is rarely printed well because of the startup time of the extruder. On the right you see an object with its raft still attached.
-
-The Raft panel has some extra settings, it probably made sense to have them there but they have not that much to do with the actual Raft. First are the Support material settings. Since close to all RepRap style printers have no second extruder for support material Skeinforge offers the option to print support structures with the same material set at a different speed and temperature. The idea is that the support sticks less to the actual object when it is extruded around the minimum possible working temperature. This results in a temperature change EVERY layer so build time will increase seriously.
-
-Allan Ecker aka The Masked Retriever's has written two quicktips for raft which follow below.
-"Skeinforge Quicktip: The Raft, Part 1" at:
-http://blog.thingiverse.com/2009/07/14/skeinforge-quicktip-the-raft-part-1/
-"Skeinforge Quicktip: The Raft, Part II" at:
-http://blog.thingiverse.com/2009/08/04/skeinforge-quicktip-the-raft-part-ii/
-
-Nophead has written about rafts on his blog:
-http://hydraraptor.blogspot.com/2009/07/thoughts-on-rafts.html
-
-More pictures of rafting in action are available from the Metalab blog at:
-http://reprap.soup.io/?search=rafting
-
-==Operation==
-Default: On
-
-When it is on, the functions described below will work, when it is off, nothing will be done, so no temperatures will be set, nozzle will not be lifted..
-
-==Settings==
-===Add Raft, Elevate Nozzle, Orbit===
-Default: On
-
-When selected, the script will also create a raft, elevate the nozzle, orbit and set the altitude of the bottom of the raft.  It also turns on support generation.
-
-===Base===
-Base layer is the part of the raft that touches the bed.
-
-====Base Feed Rate Multiplier====
-Default is one.
-
-Defines the base feed rate multiplier.  The greater the 'Base Feed Rate Multiplier', the thinner the base, the lower the 'Base Feed Rate Multiplier', the thicker the base.
-
-====Base Flow Rate Multiplier====
-Default is one.
-
-Defines the base flow rate multiplier.  The greater the 'Base Flow Rate Multiplier', the thicker the base, the lower the 'Base Flow Rate Multiplier', the thinner the base.
-
-====Base Infill Density====
-Default is 0.5.
-
-Defines the infill density ratio of the base of the raft.
-
-====Base Layer Height over Layer Thickness====
-Default is two.
-
-Defines the ratio of the height & width of the base layer compared to the height and width of the object infill.  The feed rate will be slower for raft layers which have thicker extrusions than the object infill.
-
-====Base Layers====
-Default is one.
-
-Defines the number of base layers.
-
-====Base Nozzle Lift over Base Layer Thickness====
-Default is 0.4.
-
-Defines the amount the nozzle is above the center of the base extrusion divided by the base layer thickness.
-
-===Initial Circling===
-Default is off.
-
-When selected, the extruder will initially circle around until it reaches operating temperature.
-
-===Infill Overhang over Extrusion Width===
-Default is 0.05.
-
-Defines the ratio of the infill overhang over the the extrusion width of the raft.
-
-===Interface===
-====Interface Feed Rate Multiplier====
-Default is one.
-
-Defines the interface feed rate multiplier.  The greater the 'Interface Feed Rate Multiplier', the thinner the interface, the lower the 'Interface Feed Rate Multiplier', the thicker the interface.
-
-====Interface Flow Rate Multiplier====
-Default is one.
-
-Defines the interface flow rate multiplier.  The greater the 'Interface Flow Rate Multiplier', the thicker the interface, the lower the 'Interface Flow Rate Multiplier', the thinner the interface.
-
-====Interface Infill Density====
-Default is 0.5.
-
-Defines the infill density ratio of the interface of the raft.
-
-====Interface Layer Thickness over Extrusion Height====
-Default is one.
-
-Defines the ratio of the height & width of the interface layer compared to the height and width of the object infill.  The feed rate will be slower for raft layers which have thicker extrusions than the object infill.
-
-====Interface Layers====
-Default is two.
-
-Defines the number of interface layers to print.
-
-====Interface Nozzle Lift over Interface Layer Thickness====
-Default is 0.45.
-
-Defines the amount the nozzle is above the center of the interface extrusion divided by the interface layer thickness.
-
-===Name of Alteration Files===
-If support material is generated, raft looks for alteration files in the alterations folder in the .skeinforge folder in the home directory.  Raft does not care if the text file names are capitalized, but some file systems do not handle file name cases properly, so to be on the safe side you should give them lower case names.  If it doesn't find the file it then looks in the alterations folder in the skeinforge_plugins folder.
-
-====Name of Support End File====
-Default is support_end.gcode.
-
-If support material is generated and if there is a file with the name of the "Name of Support End File" setting, it will be added to the end of the support gcode.
-
-====Name of Support Start File====
-If support material is generated and if there is a file with the name of the "Name of Support Start File" setting, it will be added to the start of the support gcode.
-
-===Operating Nozzle Lift over Layer Thickness===
-Default is 0.5.
-
-Defines the amount the nozzle is above the center of the operating extrusion divided by the layer height.
-
-===Raft Size===
-The raft fills a rectangle whose base size is the rectangle around the bottom layer of the object expanded on each side by the 'Raft Margin' plus the 'Raft Additional Margin over Length (%)' percentage times the length of the side.
-
-====Raft Additional Margin over Length====
-Default is 1 percent.
-
-====Raft Margin====
-Default is three millimeters.
-
-===Support===
-Good articles on support material are at:
-http://davedurant.wordpress.com/2010/07/31/skeinforge-support-part-1/
-http://davedurant.wordpress.com/2010/07/31/skeinforge-support-part-2/
-
-====Support Cross Hatch====
-Default is off.
-
-When selected, the support material will cross hatched.  Cross hatching the support makes it stronger and harder to remove, which is why the default is off.
-
-====Support Flow Rate over Operating Flow Rate====
-Default: 0.9.
-
-Defines the ratio of the flow rate when the support is extruded over the operating flow rate.  With a number less than one, the support flow rate will be smaller so the support will be thinner and easier to remove.
-
-====Support Gap over Perimeter Extrusion Width====
-Default: 0.5.
-
-Defines the gap between the support material and the object over the edge extrusion width.
-
-====Support Material Choice====
-Default is 'None' because the raft takes time to generate.
-
-=====Empty Layers Only=====
-When selected, support material will be only on the empty layers.  This is useful when making identical objects in a stack.
-
-=====Everywhere=====
-When selected, support material will be added wherever there are overhangs, even inside the object.  Because support material inside objects is hard or impossible to remove, this option should only be chosen if the object has a cavity that needs support and there is some way to extract the support material.
-
-=====Exterior Only=====
-When selected, support material will be added only the exterior of the object.  This is the best option for most objects which require support material.
-
-=====None=====
-When selected, raft will not add support material.
-
-====Support Minimum Angle====
-Default is sixty degrees.
-
-Defines the minimum angle that a surface overhangs before support material is added.  If angle is lower then this value the support will be generated.  This angle is defined from the vertical, so zero is a vertical wall, ten is a wall with a bit of overhang, thirty is the typical safe angle for filament extrusion, sixty is a really high angle for extrusion and ninety is an unsupported horizontal ceiling.
-
-==Examples==
-The following examples raft the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and raft.py.
-
-> python raft.py
-This brings up the raft dialog.
-
-> python raft.py Screw Holder Bottom.stl
-The raft tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The raft tool has created the file:
-Screw Holder Bottom_raft.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import intercircle
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import math
-import os
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-#maybe later wide support
-#raft outline temperature http://hydraraptor.blogspot.com/2008/09/screw-top-pot.html
-def getCraftedText( fileName, text='', repository=None):
-       'Raft the file or text.'
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository)
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       'Raft a gcode linear move text.'
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'raft'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository( RaftRepository() )
-       if not repository.activateRaft.value:
-               return gcodeText
-       return RaftSkein().getCraftedGcode(gcodeText, repository)
-
-def getCrossHatchPointLine( crossHatchPointLineTable, y ):
-       'Get the cross hatch point line.'
-       if not crossHatchPointLineTable.has_key(y):
-               crossHatchPointLineTable[ y ] = {}
-       return crossHatchPointLineTable[ y ]
-
-def getEndpointsFromYIntersections( x, yIntersections ):
-       'Get endpoints from the y intersections.'
-       endpoints = []
-       for yIntersectionIndex in xrange( 0, len( yIntersections ), 2 ):
-               firstY = yIntersections[ yIntersectionIndex ]
-               secondY = yIntersections[ yIntersectionIndex + 1 ]
-               if firstY != secondY:
-                       firstComplex = complex( x, firstY )
-                       secondComplex = complex( x, secondY )
-                       endpointFirst = euclidean.Endpoint()
-                       endpointSecond = euclidean.Endpoint().getFromOtherPoint( endpointFirst, secondComplex )
-                       endpointFirst.getFromOtherPoint( endpointSecond, firstComplex )
-                       endpoints.append( endpointFirst )
-                       endpoints.append( endpointSecond )
-       return endpoints
-
-def getExtendedLineSegment(extensionDistance, lineSegment, loopXIntersections):
-       'Get extended line segment.'
-       pointBegin = lineSegment[0].point
-       pointEnd = lineSegment[1].point
-       segment = pointEnd - pointBegin
-       segmentLength = abs(segment)
-       if segmentLength <= 0.0:
-               print('This should never happen in getExtendedLineSegment in raft, the segment should have a length greater than zero.')
-               print(lineSegment)
-               return None
-       segmentExtend = segment * extensionDistance / segmentLength
-       lineSegment[0].point -= segmentExtend
-       lineSegment[1].point += segmentExtend
-       for loopXIntersection in loopXIntersections:
-               setExtendedPoint(lineSegment[0], pointBegin, loopXIntersection)
-               setExtendedPoint(lineSegment[1], pointEnd, loopXIntersection)
-       return lineSegment
-
-def getLoopsBySegmentsDictionary(segmentsDictionary, width):
-       'Get loops from a horizontal segments dictionary.'
-       points = []
-       for endpoint in getVerticalEndpoints(segmentsDictionary, width, 0.1 * width, width):
-               points.append(endpoint.point)
-       for endpoint in euclidean.getEndpointsFromSegmentTable(segmentsDictionary):
-               points.append(endpoint.point)
-       return triangle_mesh.getDescendingAreaOrientedLoops(points, points, width + width)
-
-def getNewRepository():
-       'Get new repository.'
-       return RaftRepository()
-
-def getVerticalEndpoints(horizontalSegmentsTable, horizontalStep, verticalOverhang, verticalStep):
-       'Get vertical endpoints.'
-       interfaceSegmentsTableKeys = horizontalSegmentsTable.keys()
-       interfaceSegmentsTableKeys.sort()
-       verticalTableTable = {}
-       for interfaceSegmentsTableKey in interfaceSegmentsTableKeys:
-               interfaceSegments = horizontalSegmentsTable[interfaceSegmentsTableKey]
-               for interfaceSegment in interfaceSegments:
-                       begin = int(round(interfaceSegment[0].point.real / verticalStep))
-                       end = int(round(interfaceSegment[1].point.real / verticalStep))
-                       for stepIndex in xrange(begin, end + 1):
-                               if stepIndex not in verticalTableTable:
-                                       verticalTableTable[stepIndex] = {}
-                               verticalTableTable[stepIndex][interfaceSegmentsTableKey] = None
-       verticalTableTableKeys = verticalTableTable.keys()
-       verticalTableTableKeys.sort()
-       verticalEndpoints = []
-       for verticalTableTableKey in verticalTableTableKeys:
-               verticalTable = verticalTableTable[verticalTableTableKey]
-               verticalTableKeys = verticalTable.keys()
-               verticalTableKeys.sort()
-               xIntersections = []
-               for verticalTableKey in verticalTableKeys:
-                       y = verticalTableKey * horizontalStep
-                       if verticalTableKey - 1 not in verticalTableKeys:
-                               xIntersections.append(y - verticalOverhang)
-                       if verticalTableKey + 1 not in verticalTableKeys:
-                               xIntersections.append(y + verticalOverhang)
-               for segment in euclidean.getSegmentsFromXIntersections(xIntersections, verticalTableTableKey * verticalStep):
-                       for endpoint in segment:
-                               endpoint.point = complex(endpoint.point.imag, endpoint.point.real)
-                               verticalEndpoints.append(endpoint)
-       return verticalEndpoints
-
-def setExtendedPoint( lineSegmentEnd, pointOriginal, x ):
-       'Set the point in the extended line segment.'
-       if min( lineSegmentEnd.point.real, pointOriginal.real ) < x < max( lineSegmentEnd.point.real, pointOriginal.real ):
-               lineSegmentEnd.point = complex( x, pointOriginal.imag )
-
-def writeOutput(fileName, shouldAnalyze=True):
-       'Raft a gcode linear move file.'
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'raft', shouldAnalyze)
-
-
-class RaftRepository(object):
-       'A class to handle the raft settings.'
-       def __init__(self):
-               'Set the default settings, execute title & settings fileName.'
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.raft.html', self)
-               self.fileNameInput = settings.FileNameInput().getFromFileName(
-                       fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Raft', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute(
-                       'http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Raft')
-               self.activateRaft = settings.BooleanSetting().getFromValue('Activate Raft', self, True)
-               self.addRaftElevateNozzleOrbitSetAltitude = settings.BooleanSetting().getFromValue(
-                       'Add Raft, Elevate Nozzle, Orbit:', self, True)
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Base -', self)
-               self.baseFeedRateMultiplier = settings.FloatSpin().getFromValue(0.7, 'Base Feed Rate Multiplier (ratio):', self, 1.1, 1.0)
-               self.baseFlowRateMultiplier = settings.FloatSpin().getFromValue(0.7, 'Base Flow Rate Multiplier (ratio):', self, 1.1, 1.0)
-               self.baseInfillDensity = settings.FloatSpin().getFromValue(0.3, 'Base Infill Density (ratio):', self, 0.9, 0.5)
-               self.baseLayerThicknessOverLayerThickness = settings.FloatSpin().getFromValue(
-                       1.0, 'Base Layer Thickness over Layer Thickness:', self, 3.0, 2.0)
-               self.baseLayers = settings.IntSpin().getFromValue(0, 'Base Layers (integer):', self, 3, 0)
-               self.baseNozzleLiftOverBaseLayerThickness = settings.FloatSpin().getFromValue(
-                       0.2, 'Base Nozzle Lift over Base Layer Thickness (ratio):', self, 0.8, 0.4)
-               settings.LabelSeparator().getFromRepository(self)
-               self.initialCircling = settings.BooleanSetting().getFromValue('Initial Circling:', self, False)
-               self.infillOverhangOverExtrusionWidth = settings.FloatSpin().getFromValue(
-                       0.0, 'Infill Overhang over Extrusion Width (ratio):', self, 0.5, 0.05)
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Interface -', self)
-               self.interfaceFeedRateMultiplier = settings.FloatSpin().getFromValue(
-                       0.7, 'Interface Feed Rate Multiplier (ratio):', self, 1.1, 1.0)
-               self.interfaceFlowRateMultiplier = settings.FloatSpin().getFromValue(
-                       0.7, 'Interface Flow Rate Multiplier (ratio):', self, 1.1, 1.0)
-               self.interfaceInfillDensity = settings.FloatSpin().getFromValue(
-                       0.3, 'Interface Infill Density (ratio):', self, 0.9, 0.5)
-               self.interfaceLayerThicknessOverLayerThickness = settings.FloatSpin().getFromValue(
-                       1.0, 'Interface Layer Thickness over Layer Thickness:', self, 3.0, 1.0)
-               self.interfaceLayers = settings.IntSpin().getFromValue(
-                       0, 'Interface Layers (integer):', self, 3, 0)
-               self.interfaceNozzleLiftOverInterfaceLayerThickness = settings.FloatSpin().getFromValue(
-                       0.25, 'Interface Nozzle Lift over Interface Layer Thickness (ratio):', self, 0.85, 0.45)
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Name of Alteration Files -', self)
-               self.nameOfSupportEndFile = settings.StringSetting().getFromValue('Name of Support End File:', self, 'support_end.gcode')
-               self.nameOfSupportStartFile = settings.StringSetting().getFromValue(
-                       'Name of Support Start File:', self, 'support_start.gcode')
-               settings.LabelSeparator().getFromRepository(self)
-               self.operatingNozzleLiftOverLayerThickness = settings.FloatSpin().getFromValue(
-                       0.3, 'Operating Nozzle Lift over Layer Thickness (ratio):', self, 0.7, 0.5)
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Raft Size -', self)
-               self.raftAdditionalMarginOverLengthPercent = settings.FloatSpin().getFromValue(
-                       0.5, 'Raft Additional Margin over Length (%):', self, 1.5, 1.0)
-               self.raftMargin = settings.FloatSpin().getFromValue(
-                       1.0, 'Raft Margin (mm):', self, 5.0, 3.0)
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Support -', self)
-               self.supportCrossHatch = settings.BooleanSetting().getFromValue('Support Cross Hatch', self, False)
-               self.supportFlowRateOverOperatingFlowRate = settings.FloatSpin().getFromValue(
-                       0.7, 'Support Flow Rate over Operating Flow Rate (ratio):', self, 1.1, 1.0)
-               self.supportGapOverPerimeterExtrusionWidth = settings.FloatSpin().getFromValue(
-                       0.5, 'Support Gap over Perimeter Extrusion Width (ratio):', self, 1.5, 1.0)
-               self.supportMaterialChoice = settings.MenuButtonDisplay().getFromName('Support Material Choice: ', self)
-               self.supportChoiceNone = settings.MenuRadio().getFromMenuButtonDisplay(self.supportMaterialChoice, 'None', self, True)
-               self.supportChoiceEmptyLayersOnly = settings.MenuRadio().getFromMenuButtonDisplay(self.supportMaterialChoice, 'Empty Layers Only', self, False)
-               self.supportChoiceEverywhere = settings.MenuRadio().getFromMenuButtonDisplay(self.supportMaterialChoice, 'Everywhere', self, False)
-               self.supportChoiceExteriorOnly = settings.MenuRadio().getFromMenuButtonDisplay(self.supportMaterialChoice, 'Exterior Only', self, False)
-               self.supportMinimumAngle = settings.FloatSpin().getFromValue(40.0, 'Support Minimum Angle (degrees):', self, 80.0, 60.0)
-               self.executeTitle = 'Raft'
-               self.supportMargin = settings.FloatSpin().getFromValue(
-                       1.0, 'Support Margin (mm):', self, 5.0, 3.0)
-               self.supportOffsetX = settings.FloatSpin().getFromValue(0.0, 'Support Offset X (mm):', self, 100.0, 0.0)
-               self.supportOffsetY = settings.FloatSpin().getFromValue(0.0, 'Support Offset Y (mm):', self, 100.0, 0.0)
-
-       def execute(self):
-               'Raft button has been clicked.'
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class RaftSkein(object):
-       'A class to raft a skein of extrusions.'
-       def __init__(self):
-               self.addLineLayerStart = True
-               self.baseTemperature = None
-               self.beginLoop = None
-               self.boundaryLayers = []
-               self.coolingRate = None
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.edgeWidth = 0.6
-               self.extrusionStart = True
-               self.extrusionTop = 0.0
-               self.feedRateMinute = 961.0
-               self.heatingRate = None
-               self.insetTable = {}
-               self.interfaceTemperature = None
-               self.isEdgePath = False
-               self.isNestedRing = True
-               self.isStartupEarly = False
-               self.layerIndex = - 1
-               self.layerStarted = False
-               self.layerHeight = 0.4
-               self.lineIndex = 0
-               self.lines = None
-               self.objectFirstLayerInfillTemperature = None
-               self.objectFirstLayerPerimeterTemperature = None
-               self.objectNextLayersTemperature = None
-               self.oldFlowRate = None
-               self.oldLocation = None
-               self.oldTemperatureOutputString = None
-               self.operatingFeedRateMinute = None
-               self.operatingFlowRate = None
-               self.operatingLayerEndLine = '(<operatingLayerEnd> </operatingLayerEnd>)'
-               self.operatingJump = None
-               self.orbitalFeedRatePerSecond = 2.01
-               self.sharpestProduct = 0.94
-               self.supportFlowRate = None
-               self.supportLayers = []
-               self.supportLayersTemperature = None
-               self.supportedLayersTemperature = None
-               self.travelFeedRateMinute = None
-
-       def addBaseLayer(self):
-               'Add a base layer.'
-               baseLayerThickness = self.layerHeight * self.baseLayerThicknessOverLayerThickness
-               zCenter = self.extrusionTop + 0.5 * baseLayerThickness
-               z = zCenter + baseLayerThickness * self.repository.baseNozzleLiftOverBaseLayerThickness.value
-               if len(self.baseEndpoints) < 1:
-                       print('This should never happen, the base layer has a size of zero.')
-                       return
-               self.addLayerFromEndpoints(
-                       self.baseEndpoints,
-                       self.repository.baseFeedRateMultiplier.value,
-                       self.repository.baseFlowRateMultiplier.value,
-                       baseLayerThickness,
-                       self.baseLayerThicknessOverLayerThickness,
-                       self.baseStep,
-                       z)
-
-       def addBaseSegments(self, baseExtrusionWidth):
-               'Add the base segments.'
-               baseOverhang = self.repository.infillOverhangOverExtrusionWidth.value * baseExtrusionWidth
-               self.baseEndpoints = getVerticalEndpoints(self.interfaceSegmentsTable, self.interfaceStep, baseOverhang, self.baseStep)
-
-       def addEmptyLayerSupport( self, boundaryLayerIndex ):
-               'Add support material to a layer if it is empty.'
-               supportLayer = SupportLayer([])
-               self.supportLayers.append(supportLayer)
-               if len( self.boundaryLayers[ boundaryLayerIndex ].loops ) > 0:
-                       return
-               aboveXIntersectionsTable = {}
-               euclidean.addXIntersectionsFromLoopsForTable( self.getInsetLoopsAbove(boundaryLayerIndex), aboveXIntersectionsTable, self.interfaceStep )
-               belowXIntersectionsTable = {}
-               euclidean.addXIntersectionsFromLoopsForTable( self.getInsetLoopsBelow(boundaryLayerIndex), belowXIntersectionsTable, self.interfaceStep )
-               supportLayer.xIntersectionsTable = euclidean.getIntersectionOfXIntersectionsTables( [ aboveXIntersectionsTable, belowXIntersectionsTable ] )
-
-       def addFlowRate(self, flowRate):
-               'Add a flow rate value if different.'
-               if flowRate != None:
-                       self.distanceFeedRate.addLine('M108 S' + euclidean.getFourSignificantFigures(flowRate))
-
-       def addInterfaceLayer(self):
-               'Add an interface layer.'
-               interfaceLayerThickness = self.layerHeight * self.interfaceLayerThicknessOverLayerThickness
-               zCenter = self.extrusionTop + 0.5 * interfaceLayerThickness
-               z = zCenter + interfaceLayerThickness * self.repository.interfaceNozzleLiftOverInterfaceLayerThickness.value
-               if len(self.interfaceEndpoints) < 1:
-                       print('This should never happen, the interface layer has a size of zero.')
-                       return
-               self.addLayerFromEndpoints(
-                       self.interfaceEndpoints,
-                       self.repository.interfaceFeedRateMultiplier.value,
-                       self.repository.interfaceFlowRateMultiplier.value,
-                       interfaceLayerThickness,
-                       self.interfaceLayerThicknessOverLayerThickness,
-                       self.interfaceStep,
-                       z)
-
-       def addInterfaceTables(self, interfaceExtrusionWidth):
-               'Add interface tables.'
-               overhang = self.repository.infillOverhangOverExtrusionWidth.value * interfaceExtrusionWidth
-               self.interfaceEndpoints = []
-               self.interfaceIntersectionsTableKeys = self.interfaceIntersectionsTable.keys()
-               self.interfaceSegmentsTable = {}
-               for yKey in self.interfaceIntersectionsTableKeys:
-                       self.interfaceIntersectionsTable[yKey].sort()
-                       y = yKey * self.interfaceStep
-                       lineSegments = euclidean.getSegmentsFromXIntersections(self.interfaceIntersectionsTable[yKey], y)
-                       xIntersectionIndexList = []
-                       for lineSegmentIndex in xrange(len(lineSegments)):
-                               lineSegment = lineSegments[lineSegmentIndex]
-                               endpointBegin = lineSegment[0]
-                               endpointEnd = lineSegment[1]
-                               endpointBegin.point = complex(self.baseStep * math.floor(endpointBegin.point.real / self.baseStep) - overhang, y)
-                               endpointEnd.point = complex(self.baseStep * math.ceil(endpointEnd.point.real / self.baseStep) + overhang, y)
-                               if endpointEnd.point.real > endpointBegin.point.real:
-                                       euclidean.addXIntersectionIndexesFromSegment(lineSegmentIndex, lineSegment, xIntersectionIndexList)
-                       xIntersections = euclidean.getJoinOfXIntersectionIndexes(xIntersectionIndexList)
-                       joinedSegments = euclidean.getSegmentsFromXIntersections(xIntersections, y)
-                       if len(joinedSegments) > 0:
-                               self.interfaceSegmentsTable[yKey] = joinedSegments
-                       for joinedSegment in joinedSegments:
-                               self.interfaceEndpoints += joinedSegment
-
-       def addLayerFromEndpoints(
-               self,
-               endpoints,
-               feedRateMultiplier,
-               flowRateMultiplier,
-               layerLayerThickness,
-               layerThicknessRatio,
-               step,
-               z):
-               'Add a layer from endpoints and raise the extrusion top.'
-               layerThicknessRatioSquared = layerThicknessRatio * layerThicknessRatio
-               feedRateMinute = self.feedRateMinute * feedRateMultiplier / layerThicknessRatioSquared
-               if len(endpoints) < 1:
-                       return
-               aroundPixelTable = {}
-               aroundWidth = 0.34321 * step
-               paths = euclidean.getPathsFromEndpoints(endpoints, 1.5 * step, aroundPixelTable, self.sharpestProduct, aroundWidth)
-               self.addLayerLine(z)
-               if self.operatingFlowRate != None:
-                       self.addFlowRate(flowRateMultiplier * self.operatingFlowRate)
-               for path in paths:
-                       simplifiedPath = euclidean.getSimplifiedPath(path, step)
-                       self.distanceFeedRate.addGcodeFromFeedRateThreadZ(feedRateMinute, simplifiedPath, self.travelFeedRateMinute, z)
-               self.extrusionTop += layerLayerThickness
-               self.addFlowRate(self.oldFlowRate)
-
-       def addLayerLine(self, z):
-               'Add the layer gcode line and close the last layer gcode block.'
-               if self.layerStarted:
-                       self.distanceFeedRate.addLine('(</layer>)')
-               self.distanceFeedRate.addLine('(<layer> %s )' % self.distanceFeedRate.getRounded(z)) # Indicate that a new layer is starting.
-               if self.beginLoop != None:
-                       zBegin = self.extrusionTop + self.layerHeight
-                       intercircle.addOrbitsIfLarge(self.distanceFeedRate, self.beginLoop, self.orbitalFeedRatePerSecond, self.temperatureChangeTimeBeforeRaft, zBegin)
-                       self.beginLoop = None
-               self.layerStarted = True
-
-       def addOperatingOrbits(self, boundaryLoops, pointComplex, temperatureChangeTime, z):
-               'Add the orbits before the operating layers.'
-               if len(boundaryLoops) < 1:
-                       return
-               insetBoundaryLoops = intercircle.getInsetLoopsFromLoops(boundaryLoops, self.edgeWidth)
-               if len(insetBoundaryLoops) < 1:
-                       insetBoundaryLoops = boundaryLoops
-               largestLoop = euclidean.getLargestLoop(insetBoundaryLoops)
-               if pointComplex != None:
-                       largestLoop = euclidean.getLoopStartingClosest(self.edgeWidth, pointComplex, largestLoop)
-               intercircle.addOrbitsIfLarge(self.distanceFeedRate, largestLoop, self.orbitalFeedRatePerSecond, temperatureChangeTime, z)
-
-       def addRaft(self):
-               'Add the raft.'
-               self.baseLayerThicknessOverLayerThickness = self.repository.baseLayerThicknessOverLayerThickness.value
-               baseExtrusionWidth = self.edgeWidth * self.baseLayerThicknessOverLayerThickness
-               self.baseStep = baseExtrusionWidth / self.repository.baseInfillDensity.value
-               self.interfaceLayerThicknessOverLayerThickness = self.repository.interfaceLayerThicknessOverLayerThickness.value
-               interfaceExtrusionWidth = self.edgeWidth * self.interfaceLayerThicknessOverLayerThickness
-               self.interfaceStep = interfaceExtrusionWidth / self.repository.interfaceInfillDensity.value
-               self.setCornersZ()
-               self.cornerMinimumComplex = self.cornerMinimum.dropAxis()
-               originalExtent = self.cornerMaximumComplex - self.cornerMinimumComplex
-               self.raftOutsetRadius = self.repository.raftMargin.value + self.repository.raftAdditionalMarginOverLengthPercent.value * 0.01 * max(originalExtent.real, originalExtent.imag)
-               self.supportOutsetRadius = self.repository.supportMargin.value
-               self.setBoundaryLayers()
-               if len(self.boundaryLayers) < 1:
-                       print('this should never happen, there are no boundary layers in addRaft')
-                       return
-               outsetSeparateLoops = intercircle.getInsetSeparateLoopsFromLoops(self.boundaryLayers[0].loops, -self.raftOutsetRadius, 0.8)
-               self.interfaceIntersectionsTable = {}
-               euclidean.addXIntersectionsFromLoopsForTable(outsetSeparateLoops, self.interfaceIntersectionsTable, self.interfaceStep)
-               if len(self.supportLayers) > 0:
-                       supportIntersectionsTable = self.supportLayers[0].xIntersectionsTable
-                       euclidean.joinXIntersectionsTables(supportIntersectionsTable, self.interfaceIntersectionsTable)
-               self.addInterfaceTables(interfaceExtrusionWidth)
-               self.addRaftPerimeters()
-               self.baseIntersectionsTable = {}
-               complexRadius = complex(self.raftOutsetRadius, self.raftOutsetRadius)
-               self.complexHigh = complexRadius + self.cornerMaximumComplex
-               self.complexLow = self.cornerMinimumComplex - complexRadius
-               self.beginLoop = euclidean.getSquareLoopWiddershins(self.cornerMinimumComplex, self.cornerMaximumComplex)
-               if not intercircle.orbitsAreLarge(self.beginLoop, self.temperatureChangeTimeBeforeRaft):
-                       self.beginLoop = None
-               if self.repository.baseLayers.value > 0:
-                       self.addTemperatureLineIfDifferent(self.baseTemperature)
-                       self.addBaseSegments(baseExtrusionWidth)
-               for baseLayerIndex in xrange(self.repository.baseLayers.value):
-                       self.addBaseLayer()
-               if self.repository.interfaceLayers.value > 0:
-                       self.addTemperatureLineIfDifferent(self.interfaceTemperature)
-               self.interfaceIntersectionsTableKeys.sort()
-               for interfaceLayerIndex in xrange(self.repository.interfaceLayers.value):
-                       self.addInterfaceLayer()
-               self.operatingJump = self.extrusionTop + self.layerHeight * self.repository.operatingNozzleLiftOverLayerThickness.value
-               for boundaryLayer in self.boundaryLayers:
-                       if self.operatingJump != None:
-                               boundaryLayer.z += self.operatingJump
-               if self.repository.baseLayers.value > 0 or self.repository.interfaceLayers.value > 0:
-                       boundaryZ = self.boundaryLayers[0].z
-                       if self.layerStarted:
-                               self.distanceFeedRate.addLine('(</layer>)')
-                               self.layerStarted = False
-                       self.distanceFeedRate.addLine('(<raftLayerEnd> </raftLayerEnd>)')
-                       self.addLayerLine(boundaryZ)
-                       temperatureChangeTimeBeforeFirstLayer = self.getTemperatureChangeTime(self.objectFirstLayerPerimeterTemperature)
-                       self.addTemperatureLineIfDifferent(self.objectFirstLayerPerimeterTemperature)
-                       largestOutsetLoop = intercircle.getLargestInsetLoopFromLoop(euclidean.getLargestLoop(outsetSeparateLoops), -self.raftOutsetRadius)
-                       intercircle.addOrbitsIfLarge(self.distanceFeedRate, largestOutsetLoop, self.orbitalFeedRatePerSecond, temperatureChangeTimeBeforeFirstLayer, boundaryZ)
-                       self.addLineLayerStart = False
-
-       def addRaftedLine( self, splitLine ):
-               'Add elevated gcode line with operating feed rate.'
-               self.oldLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine)
-               z = self.oldLocation.z
-               if self.operatingJump != None:
-                       z += self.operatingJump
-               temperature = self.objectNextLayersTemperature
-               if self.layerIndex == 0:
-                       if self.isEdgePath:
-                               temperature = self.objectFirstLayerPerimeterTemperature
-                       else:
-                               temperature = self.objectFirstLayerInfillTemperature
-               self.addTemperatureLineIfDifferent(temperature)
-               self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.feedRateMinute, self.oldLocation.dropAxis(), z)
-
-       def addRaftPerimeters(self):
-               'Add raft edges if there is a raft.'
-               interfaceOutset = self.halfEdgeWidth * self.interfaceLayerThicknessOverLayerThickness
-               for supportLayer in self.supportLayers:
-                       supportSegmentTable = supportLayer.supportSegmentTable
-                       if len(supportSegmentTable) > 0:
-                               outset = interfaceOutset
-                               self.addRaftPerimetersByLoops(getLoopsBySegmentsDictionary(supportSegmentTable, self.interfaceStep), outset)
-               if self.repository.baseLayers.value < 1 and self.repository.interfaceLayers.value < 1:
-                       return
-               overhangMultiplier = 1.0 + self.repository.infillOverhangOverExtrusionWidth.value + self.repository.infillOverhangOverExtrusionWidth.value
-               outset = self.halfEdgeWidth
-               if self.repository.interfaceLayers.value > 0:
-                       outset = max(interfaceOutset * overhangMultiplier, outset)
-               if self.repository.baseLayers.value > 0:
-                       outset = max(self.halfEdgeWidth * self.baseLayerThicknessOverLayerThickness * overhangMultiplier, outset)
-               self.addRaftPerimetersByLoops(getLoopsBySegmentsDictionary(self.interfaceSegmentsTable, self.interfaceStep), outset)
-
-       def addRaftPerimetersByLoops(self, loops, outset):
-               'Add raft edges to the gcode for loops.'
-               loops = intercircle.getInsetSeparateLoopsFromLoops(loops, -outset)
-               for loop in loops:
-                       self.distanceFeedRate.addLine('(<raftPerimeter>)')
-                       for point in loop:
-                               roundedX = self.distanceFeedRate.getRounded(point.real)
-                               roundedY = self.distanceFeedRate.getRounded(point.imag)
-                               self.distanceFeedRate.addTagBracketedLine('raftPoint', 'X%s Y%s' % (roundedX, roundedY))
-                       self.distanceFeedRate.addLine('(</raftPerimeter>)')
-
-       def addSegmentTablesToSupportLayers(self):
-               'Add segment tables to the support layers.'
-               for supportLayer in self.supportLayers:
-                       supportLayer.supportSegmentTable = {}
-                       xIntersectionsTable = supportLayer.xIntersectionsTable
-                       for xIntersectionsTableKey in xIntersectionsTable:
-                               y = xIntersectionsTableKey * self.interfaceStep
-                               supportLayer.supportSegmentTable[ xIntersectionsTableKey ] = euclidean.getSegmentsFromXIntersections( xIntersectionsTable[ xIntersectionsTableKey ], y )
-
-       def addSupportLayerTemperature(self, endpoints, z):
-               'Add support layer and temperature before the object layer.'
-               self.distanceFeedRate.addLinesSetAbsoluteDistanceMode(self.supportStartLines)
-               self.distanceFeedRate.addLine('(<supportLayer>)')
-               self.addTemperatureOrbits(endpoints, self.supportedLayersTemperature, z)
-               aroundPixelTable = {}
-               aroundWidth = 0.34321 * self.interfaceStep
-               boundaryLoops = self.boundaryLayers[self.layerIndex].loops
-               halfSupportOutset = 0.5 * self.supportOutset
-               aroundBoundaryLoops = intercircle.getAroundsFromLoops(boundaryLoops, halfSupportOutset)
-               for aroundBoundaryLoop in aroundBoundaryLoops:
-                       euclidean.addLoopToPixelTable(aroundBoundaryLoop, aroundPixelTable, aroundWidth)
-               paths = euclidean.getPathsFromEndpoints(endpoints, 1.5 * self.interfaceStep, aroundPixelTable, self.sharpestProduct, aroundWidth)
-               feedRateMinuteMultiplied = self.operatingFeedRateMinute
-               supportFlowRateMultiplied = self.supportFlowRate
-               if self.layerIndex == 0:
-                       feedRateMinuteMultiplied *= self.objectFirstLayerFeedRateInfillMultiplier
-                       if supportFlowRateMultiplied != None:
-                               supportFlowRateMultiplied = self.operatingFlowRate * self.objectFirstLayerFlowRateInfillMultiplier
-               self.addFlowRate(supportFlowRateMultiplied)
-               for path in paths:
-                       path = map(lambda p: p + complex(self.supportOffsetX, self.supportOffsetY), path)
-                       self.distanceFeedRate.addGcodeFromFeedRateThreadZ(feedRateMinuteMultiplied, path, self.travelFeedRateMinute, z)
-               self.addFlowRate(self.oldFlowRate)
-               self.addTemperatureOrbits(endpoints, self.supportLayersTemperature, z)
-               self.distanceFeedRate.addLinesSetAbsoluteDistanceMode(self.supportEndLines)
-               self.distanceFeedRate.addLine('(</supportLayer>)')
-
-       def addSupportSegmentTable( self, layerIndex ):
-               'Add support segments from the boundary layers.'
-               aboveLayer = self.boundaryLayers[ layerIndex + 1 ]
-               aboveLoops = aboveLayer.loops
-               supportLayer = self.supportLayers[layerIndex]
-               if len( aboveLoops ) < 1:
-                       return
-               boundaryLayer = self.boundaryLayers[layerIndex]
-               rise = aboveLayer.z - boundaryLayer.z
-               outsetSupportLoops = intercircle.getInsetSeparateLoopsFromLoops(boundaryLayer.loops, -self.minimumSupportRatio * rise)
-               numberOfSubSteps = 4
-               subStepSize = self.interfaceStep / float( numberOfSubSteps )
-               aboveIntersectionsTable = {}
-               euclidean.addXIntersectionsFromLoopsForTable( aboveLoops, aboveIntersectionsTable, subStepSize )
-               outsetIntersectionsTable = {}
-               euclidean.addXIntersectionsFromLoopsForTable( outsetSupportLoops, outsetIntersectionsTable, subStepSize )
-               euclidean.subtractXIntersectionsTable( aboveIntersectionsTable, outsetIntersectionsTable )
-               for aboveIntersectionsTableKey in aboveIntersectionsTable.keys():
-                       supportIntersectionsTableKey = int( round( float( aboveIntersectionsTableKey ) / numberOfSubSteps ) )
-                       xIntersectionIndexList = []
-                       if supportIntersectionsTableKey in supportLayer.xIntersectionsTable:
-                               euclidean.addXIntersectionIndexesFromXIntersections( 0, xIntersectionIndexList, supportLayer.xIntersectionsTable[ supportIntersectionsTableKey ] )
-                       euclidean.addXIntersectionIndexesFromXIntersections( 1, xIntersectionIndexList, aboveIntersectionsTable[ aboveIntersectionsTableKey ] )
-                       supportLayer.xIntersectionsTable[ supportIntersectionsTableKey ] = euclidean.getJoinOfXIntersectionIndexes( xIntersectionIndexList )
-
-       def addTemperatureLineIfDifferent(self, temperature):
-               'Add a line of temperature if different.'
-               if temperature == None:
-                       return
-               temperatureOutputString = euclidean.getRoundedToThreePlaces(temperature)
-               if temperatureOutputString == self.oldTemperatureOutputString:
-                       return
-               if temperatureOutputString != None:
-                       self.distanceFeedRate.addLine('M104 S' + temperatureOutputString) # Set temperature.
-               self.oldTemperatureOutputString = temperatureOutputString
-
-       def addTemperatureOrbits( self, endpoints, temperature, z ):
-               'Add the temperature and orbits around the support layer.'
-               if self.layerIndex < 0:
-                       return
-               boundaryLoops = self.boundaryLayers[self.layerIndex].loops
-               temperatureTimeChange = self.getTemperatureChangeTime( temperature )
-               self.addTemperatureLineIfDifferent( temperature )
-               if len( boundaryLoops ) < 1:
-                       layerCornerHigh = complex(-987654321.0, -987654321.0)
-                       layerCornerLow = complex(987654321.0, 987654321.0)
-                       for endpoint in endpoints:
-                               layerCornerHigh = euclidean.getMaximum( layerCornerHigh, endpoint.point )
-                               layerCornerLow = euclidean.getMinimum( layerCornerLow, endpoint.point )
-                       squareLoop = euclidean.getSquareLoopWiddershins( layerCornerLow, layerCornerHigh )
-                       intercircle.addOrbitsIfLarge( self.distanceFeedRate, squareLoop, self.orbitalFeedRatePerSecond, temperatureTimeChange, z )
-                       return
-               edgeInset = 0.4 * self.edgeWidth
-               insetBoundaryLoops = intercircle.getInsetLoopsFromLoops(boundaryLoops, edgeInset)
-               if len( insetBoundaryLoops ) < 1:
-                       insetBoundaryLoops = boundaryLoops
-               largestLoop = euclidean.getLargestLoop( insetBoundaryLoops )
-               intercircle.addOrbitsIfLarge( self.distanceFeedRate, largestLoop, self.orbitalFeedRatePerSecond, temperatureTimeChange, z )
-
-       def addToFillXIntersectionIndexTables( self, supportLayer ):
-               'Add fill segments from the boundary layers.'
-               supportLoops = supportLayer.supportLoops
-               supportLayer.fillXIntersectionsTable = {}
-               if len(supportLoops) < 1:
-                       return
-               euclidean.addXIntersectionsFromLoopsForTable( supportLoops, supportLayer.fillXIntersectionsTable, self.interfaceStep )
-
-       def extendXIntersections( self, loops, radius, xIntersectionsTable ):
-               'Extend the support segments.'
-               xIntersectionsTableKeys = xIntersectionsTable.keys()
-               for xIntersectionsTableKey in xIntersectionsTableKeys:
-                       lineSegments = euclidean.getSegmentsFromXIntersections( xIntersectionsTable[ xIntersectionsTableKey ], xIntersectionsTableKey )
-                       xIntersectionIndexList = []
-                       loopXIntersections = []
-                       euclidean.addXIntersectionsFromLoops( loops, loopXIntersections, xIntersectionsTableKey )
-                       for lineSegmentIndex in xrange( len( lineSegments ) ):
-                               lineSegment = lineSegments[ lineSegmentIndex ]
-                               extendedLineSegment = getExtendedLineSegment( radius, lineSegment, loopXIntersections )
-                               if extendedLineSegment != None:
-                                       euclidean.addXIntersectionIndexesFromSegment( lineSegmentIndex, extendedLineSegment, xIntersectionIndexList )
-                       xIntersections = euclidean.getJoinOfXIntersectionIndexes( xIntersectionIndexList )
-                       if len( xIntersections ) > 0:
-                               xIntersectionsTable[ xIntersectionsTableKey ] = xIntersections
-                       else:
-                               del xIntersectionsTable[ xIntersectionsTableKey ]
-
-       def getCraftedGcode(self, gcodeText, repository):
-               'Parse gcode text and store the raft gcode.'
-               self.repository = repository
-               self.minimumSupportRatio = math.tan( math.radians( repository.supportMinimumAngle.value ) )
-               self.supportEndLines = settings.getAlterationFileLines(repository.nameOfSupportEndFile.value)
-               self.supportStartLines = settings.getAlterationFileLines(repository.nameOfSupportStartFile.value)
-               self.supportOffsetX = repository.supportOffsetX.value
-               self.supportOffsetY = repository.supportOffsetY.value
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization()
-               self.temperatureChangeTimeBeforeRaft = 0.0
-               if self.repository.initialCircling.value:
-                       maxBaseInterfaceTemperature = max(self.baseTemperature, self.interfaceTemperature)
-                       firstMaxTemperature = max(maxBaseInterfaceTemperature, self.objectFirstLayerPerimeterTemperature)
-                       self.temperatureChangeTimeBeforeRaft = self.getTemperatureChangeTime(firstMaxTemperature)
-               if repository.addRaftElevateNozzleOrbitSetAltitude.value:
-                       self.addRaft()
-               self.addTemperatureLineIfDifferent( self.objectFirstLayerPerimeterTemperature )
-               for line in self.lines[self.lineIndex :]:
-                       self.parseLine(line)
-               return gcodec.getGcodeWithoutDuplication('M108', self.distanceFeedRate.output.getvalue())
-
-       def getElevatedBoundaryLine( self, splitLine ):
-               'Get elevated boundary gcode line.'
-               location = gcodec.getLocationFromSplitLine(None, splitLine)
-               if self.operatingJump != None:
-                       location.z += self.operatingJump
-               return self.distanceFeedRate.getBoundaryLine( location )
-
-       def getInsetLoops( self, boundaryLayerIndex ):
-               'Inset the support loops if they are not already inset.'
-               if boundaryLayerIndex not in self.insetTable:
-                       self.insetTable[ boundaryLayerIndex ] = intercircle.getInsetSeparateLoopsFromLoops(self.boundaryLayers[ boundaryLayerIndex ].loops, self.quarterEdgeWidth)
-               return self.insetTable[ boundaryLayerIndex ]
-
-       def getInsetLoopsAbove( self, boundaryLayerIndex ):
-               'Get the inset loops above the boundary layer index.'
-               for aboveLayerIndex in xrange( boundaryLayerIndex + 1, len(self.boundaryLayers) ):
-                       if len( self.boundaryLayers[ aboveLayerIndex ].loops ) > 0:
-                               return self.getInsetLoops( aboveLayerIndex )
-               return []
-
-       def getInsetLoopsBelow( self, boundaryLayerIndex ):
-               'Get the inset loops below the boundary layer index.'
-               for belowLayerIndex in xrange( boundaryLayerIndex - 1, - 1, - 1 ):
-                       if len( self.boundaryLayers[ belowLayerIndex ].loops ) > 0:
-                               return self.getInsetLoops( belowLayerIndex )
-               return []
-
-       def getStepsUntilEnd( self, begin, end, stepSize ):
-               'Get steps from the beginning until the end.'
-               step = begin
-               steps = []
-               while step < end:
-                       steps.append( step )
-                       step += stepSize
-               return steps
-
-       def getSupportEndpoints(self):
-               'Get the support layer segments.'
-               if len(self.supportLayers) <= self.layerIndex:
-                       return []
-               supportSegmentTable = self.supportLayers[self.layerIndex].supportSegmentTable
-               if self.layerIndex % 2 == 1 and self.repository.supportCrossHatch.value:
-                       return getVerticalEndpoints(supportSegmentTable, self.interfaceStep, 0.1 * self.edgeWidth, self.interfaceStep)
-               return euclidean.getEndpointsFromSegmentTable(supportSegmentTable)
-
-       def getTemperatureChangeTime( self, temperature ):
-               'Get the temperature change time.'
-               if temperature == None:
-                       return 0.0
-               oldTemperature = 25.0 # typical chamber temperature
-               if self.oldTemperatureOutputString != None:
-                       oldTemperature = float( self.oldTemperatureOutputString )
-               if temperature == oldTemperature:
-                       return 0.0
-               if temperature > oldTemperature:
-                       return ( temperature - oldTemperature ) / self.heatingRate
-               return ( oldTemperature - temperature ) / abs( self.coolingRate )
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(<baseTemperature>':
-                               self.baseTemperature = float(splitLine[1])
-                       elif firstWord == '(<coolingRate>':
-                               self.coolingRate = float(splitLine[1])
-                       elif firstWord == '(<edgeWidth>':
-                               self.edgeWidth = float(splitLine[1])
-                               self.halfEdgeWidth = 0.5 * self.edgeWidth
-                               self.quarterEdgeWidth = 0.25 * self.edgeWidth
-                               self.supportOutset = self.edgeWidth + self.edgeWidth * self.repository.supportGapOverPerimeterExtrusionWidth.value
-                       elif firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('raft')
-                       elif firstWord == '(<heatingRate>':
-                               self.heatingRate = float(splitLine[1])
-                       elif firstWord == '(<interfaceTemperature>':
-                               self.interfaceTemperature = float(splitLine[1])
-                       elif firstWord == '(<layer>':
-                               return
-                       elif firstWord == '(<layerHeight>':
-                               self.layerHeight = float(splitLine[1])
-                       elif firstWord == 'M108':
-                               self.oldFlowRate = float(splitLine[1][1 :])
-                       elif firstWord == '(<objectFirstLayerFeedRateInfillMultiplier>':
-                               self.objectFirstLayerFeedRateInfillMultiplier = float(splitLine[1])
-                       elif firstWord == '(<objectFirstLayerFlowRateInfillMultiplier>':
-                               self.objectFirstLayerFlowRateInfillMultiplier = float(splitLine[1])
-                       elif firstWord == '(<objectFirstLayerInfillTemperature>':
-                               self.objectFirstLayerInfillTemperature = float(splitLine[1])
-                       elif firstWord == '(<objectFirstLayerPerimeterTemperature>':
-                               self.objectFirstLayerPerimeterTemperature = float(splitLine[1])
-                       elif firstWord == '(<objectNextLayersTemperature>':
-                               self.objectNextLayersTemperature = float(splitLine[1])
-                       elif firstWord == '(<orbitalFeedRatePerSecond>':
-                               self.orbitalFeedRatePerSecond = float(splitLine[1])
-                       elif firstWord == '(<operatingFeedRatePerSecond>':
-                               self.operatingFeedRateMinute = 60.0 * float(splitLine[1])
-                               self.feedRateMinute = self.operatingFeedRateMinute
-                       elif firstWord == '(<operatingFlowRate>':
-                               self.operatingFlowRate = float(splitLine[1])
-                               self.oldFlowRate = self.operatingFlowRate
-                               self.supportFlowRate = self.operatingFlowRate * self.repository.supportFlowRateOverOperatingFlowRate.value
-                       elif firstWord == '(<sharpestProduct>':
-                               self.sharpestProduct = float(splitLine[1])
-                       elif firstWord == '(<supportLayersTemperature>':
-                               self.supportLayersTemperature = float(splitLine[1])
-                       elif firstWord == '(<supportedLayersTemperature>':
-                               self.supportedLayersTemperature = float(splitLine[1])
-                       elif firstWord == '(<travelFeedRatePerSecond>':
-                               self.travelFeedRateMinute = 60.0 * float(splitLine[1])
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               'Parse a gcode line and add it to the raft skein.'
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       if self.extrusionStart:
-                               self.addRaftedLine(splitLine)
-                               return
-               elif firstWord == 'M101':
-                       if self.isStartupEarly:
-                               self.isStartupEarly = False
-                               return
-               elif firstWord == 'M108':
-                       self.oldFlowRate = float(splitLine[1][1 :])
-               elif firstWord == '(<boundaryPoint>':
-                       line = self.getElevatedBoundaryLine(splitLine)
-               elif firstWord == '(</crafting>)':
-                       self.extrusionStart = False
-                       self.distanceFeedRate.addLine( self.operatingLayerEndLine )
-               elif firstWord == '(<layer>':
-                       self.layerIndex += 1
-                       settings.printProgress(self.layerIndex, 'raft')
-                       boundaryLayer = None
-                       layerZ = self.extrusionTop + float(splitLine[1])
-                       if len(self.boundaryLayers) > 0:
-                               boundaryLayer = self.boundaryLayers[self.layerIndex]
-                               layerZ = boundaryLayer.z
-                       if self.operatingJump != None:
-                               line = '(<layer> %s )' % self.distanceFeedRate.getRounded( layerZ )
-                       if self.layerStarted and self.addLineLayerStart:
-                               self.distanceFeedRate.addLine('(</layer>)')
-                       self.layerStarted = False
-                       if self.layerIndex > len(self.supportLayers) + 1:
-                               self.distanceFeedRate.addLine( self.operatingLayerEndLine )
-                               self.operatingLayerEndLine = ''
-                       if self.addLineLayerStart:
-                               self.distanceFeedRate.addLine(line)
-                       self.addLineLayerStart = True
-                       line = ''
-                       endpoints = self.getSupportEndpoints()
-                       if self.layerIndex == 1:
-                               if len(endpoints) < 1:
-                                       temperatureChangeTimeBeforeNextLayers = self.getTemperatureChangeTime( self.objectNextLayersTemperature )
-                                       self.addTemperatureLineIfDifferent( self.objectNextLayersTemperature )
-                                       if self.repository.addRaftElevateNozzleOrbitSetAltitude.value and boundaryLayer != None and len( boundaryLayer.loops ) > 0:
-                                               self.addOperatingOrbits( boundaryLayer.loops, euclidean.getXYComplexFromVector3( self.oldLocation ), temperatureChangeTimeBeforeNextLayers, layerZ )
-                       if len(endpoints) > 0:
-                               self.addSupportLayerTemperature( endpoints, layerZ )
-               elif firstWord == '(<edge>' or firstWord == '(<edgePath>)':
-                       self.isEdgePath = True
-               elif firstWord == '(</edge>)' or firstWord == '(</edgePath>)':
-                       self.isEdgePath = False
-               self.distanceFeedRate.addLine(line)
-
-       def setBoundaryLayers(self):
-               'Set the boundary layers.'
-               if self.repository.supportChoiceNone.value:
-                       return
-               if len(self.boundaryLayers) < 2:
-                       return
-               if self.repository.supportChoiceEmptyLayersOnly.value:
-                       supportLayer = SupportLayer([])
-                       self.supportLayers.append(supportLayer)
-                       for boundaryLayerIndex in xrange(1, len(self.boundaryLayers) -1):
-                               self.addEmptyLayerSupport(boundaryLayerIndex)
-                       self.truncateSupportSegmentTables()
-                       self.addSegmentTablesToSupportLayers()
-                       return
-               for boundaryLayer in self.boundaryLayers:
-                       # thresholdRadius of 0.8 is needed to avoid the ripple inset bug http://hydraraptor.blogspot.com/2010/12/crackers.html
-                       supportLoops = intercircle.getInsetSeparateLoopsFromLoops(boundaryLayer.loops, -self.supportOutset, 0.8)
-                       supportLayer = SupportLayer(supportLoops)
-                       self.supportLayers.append(supportLayer)
-               for supportLayerIndex in xrange(len(self.supportLayers) - 1):
-                       self.addSupportSegmentTable(supportLayerIndex)
-               self.truncateSupportSegmentTables()
-               for supportLayerIndex in xrange(len(self.supportLayers) - 1):
-                       boundaryLoops = self.boundaryLayers[supportLayerIndex].loops
-                       self.extendXIntersections( boundaryLoops, self.supportOutset, self.supportLayers[supportLayerIndex].xIntersectionsTable)
-               for supportLayer in self.supportLayers:
-                       self.addToFillXIntersectionIndexTables(supportLayer)
-               if self.repository.supportChoiceExteriorOnly.value:
-                       for supportLayerIndex in xrange(1, len(self.supportLayers)):
-                               self.subtractJoinedFill(supportLayerIndex)
-               for supportLayer in self.supportLayers:
-                       euclidean.subtractXIntersectionsTable(supportLayer.xIntersectionsTable, supportLayer.fillXIntersectionsTable)
-               for supportLayerIndex in xrange(len(self.supportLayers) - 2, -1, -1):
-                       xIntersectionsTable = self.supportLayers[supportLayerIndex].xIntersectionsTable
-                       aboveXIntersectionsTable = self.supportLayers[supportLayerIndex + 1].xIntersectionsTable
-                       euclidean.joinXIntersectionsTables(aboveXIntersectionsTable, xIntersectionsTable)
-               for supportLayerIndex in xrange(len(self.supportLayers)):
-                       supportLayer = self.supportLayers[supportLayerIndex]
-                       self.extendXIntersections(supportLayer.supportLoops, self.supportOutsetRadius, supportLayer.xIntersectionsTable)
-               for supportLayer in self.supportLayers:
-                       euclidean.subtractXIntersectionsTable(supportLayer.xIntersectionsTable, supportLayer.fillXIntersectionsTable)
-               self.addSegmentTablesToSupportLayers()
-
-       def setCornersZ(self):
-               'Set maximum and minimum corners and z.'
-               boundaryLoop = None
-               boundaryLayer = None
-               layerIndex = - 1
-               self.cornerMaximumComplex = complex(-912345678.0, -912345678.0)
-               self.cornerMinimum = Vector3(912345678.0, 912345678.0, 912345678.0)
-               self.firstLayerLoops = []
-               for line in self.lines[self.lineIndex :]:
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == '(</boundaryPerimeter>)':
-                               boundaryLoop = None
-                       elif firstWord == '(<boundaryPoint>':
-                               location = gcodec.getLocationFromSplitLine(None, splitLine)
-                               if boundaryLoop == None:
-                                       boundaryLoop = []
-                                       boundaryLayer.loops.append(boundaryLoop)
-                               boundaryLoop.append(location.dropAxis())
-                               self.cornerMaximumComplex = euclidean.getMaximum(self.cornerMaximumComplex, location.dropAxis())
-                               self.cornerMinimum.minimize(location)
-                       elif firstWord == '(<layer>':
-                               z = float(splitLine[1])
-                               boundaryLayer = euclidean.LoopLayer(z)
-                               self.boundaryLayers.append(boundaryLayer)
-                       elif firstWord == '(<layer>':
-                               layerIndex += 1
-                               if self.repository.supportChoiceNone.value:
-                                       if layerIndex > 1:
-                                               return
-
-       def subtractJoinedFill( self, supportLayerIndex ):
-               'Join the fill then subtract it from the support layer table.'
-               supportLayer = self.supportLayers[supportLayerIndex]
-               fillXIntersectionsTable = supportLayer.fillXIntersectionsTable
-               belowFillXIntersectionsTable = self.supportLayers[ supportLayerIndex - 1 ].fillXIntersectionsTable
-               euclidean.joinXIntersectionsTables( belowFillXIntersectionsTable, supportLayer.fillXIntersectionsTable )
-               euclidean.subtractXIntersectionsTable( supportLayer.xIntersectionsTable, supportLayer.fillXIntersectionsTable )
-
-       def truncateSupportSegmentTables(self):
-               'Truncate the support segments after the last support segment which contains elements.'
-               for supportLayerIndex in xrange( len(self.supportLayers) - 1, - 1, - 1 ):
-                       if len( self.supportLayers[supportLayerIndex].xIntersectionsTable ) > 0:
-                               self.supportLayers = self.supportLayers[ : supportLayerIndex + 1 ]
-                               return
-               self.supportLayers = []
-
-
-class SupportLayer(object):
-       'Support loops with segment tables.'
-       def __init__( self, supportLoops ):
-               self.supportLoops = supportLoops
-               self.supportSegmentTable = {}
-               self.xIntersectionsTable = {}
-
-       def __repr__(self):
-               'Get the string representation of this loop layer.'
-               return '%s' % ( self.supportLoops )
-
-
-def main():
-       'Display the raft dialog.'
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == '__main__':
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/scale.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/scale.py
deleted file mode 100644 (file)
index 60f99ad..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-#! /usr/bin/env python
-"""
-This page is in the table of contents.
-Scale scales the carving to compensate for shrinkage after the extrusion has cooled.
-
-The scale manual page is at:
-
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Scale
-
-It is best to only change the XY Plane Scale, because that does not affect other variables.  If you choose to change the Z Axis Scale, that increases the layer height so you must increase the feed rate in speed by the same amount and maybe some other variables which depend on layer height.
-
-==Operation==
-The default 'Activate Scale' checkbox is off.  When it is on, the functions described below will work, when it is off, nothing will be done.
-
-==Settings==
-===XY Plane Scale===
-Default is 1.01.
-
-Defines the amount the xy plane of the carving will be scaled.  The xy coordinates will be scaled, but the edge width is not changed, so this can be changed without affecting other variables.
-
-===Z Axis Scale===
-Default is one.
-
-Defines the amount the z axis of the carving will be scaled.  The default is one because changing this changes many variables related to the layer height.  For example, the feedRate should be multiplied by the Z Axis Scale because the layers would be farther apart.
-
-===SVG Viewer===
-Default is webbrowser.
-
-If the 'SVG Viewer' is set to the default 'webbrowser', the scalable vector graphics file will be sent to the default browser to be opened.  If the 'SVG Viewer' is set to a program name, the scalable vector graphics file will be sent to that program to be opened.
-
-==Examples==
-The following examples scale the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and scale.py.
-
-> python scale.py
-This brings up the scale dialog.
-
-> python scale.py Screw Holder Bottom.stl
-The scale tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The scale tool has created the file:
-.. Screw Holder Bottom_scale.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.svg_reader import SVGReader
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from fabmetheus_utilities import svg_writer
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText(fileName, svgText='', repository=None):
-       "Scale and convert an svg file or svgText."
-       return getCraftedTextFromText(fileName, archive.getTextIfEmpty(fileName, svgText), repository)
-
-def getCraftedTextFromText(fileName, svgText, repository=None):
-       "Scale and convert an svgText."
-       if gcodec.isProcedureDoneOrFileIsEmpty(svgText, 'scale'):
-               return svgText
-       if repository == None:
-               repository = settings.getReadRepository(ScaleRepository())
-       if repository.activateScale.value:
-               return ScaleSkein().getCraftedGcode(fileName, repository, svgText)
-       return svgText
-
-def getNewRepository():
-       'Get new repository.'
-       return ScaleRepository()
-
-def setLoopLayerScale(loopLayer, xyPlaneScale, zAxisScale):
-       "Set the slice element scale."
-       for loop in loopLayer.loops:
-               for pointIndex in xrange(len(loop)):
-                       loop[pointIndex] *= xyPlaneScale
-       loopLayer.z *= zAxisScale
-
-def writeOutput(fileName, shouldAnalyze=True):
-       'Scale the carving.'
-       skeinforge_craft.writeSVGTextWithNounMessage(fileName, ScaleRepository(), shouldAnalyze)
-
-
-class ScaleRepository(object):
-       "A class to handle the scale settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.scale.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName(fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Scale', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Scale')
-               self.activateScale = settings.BooleanSetting().getFromValue('Activate Scale', self, False)
-               self.xyPlaneScale = settings.FloatSpin().getFromValue(0.99, 'XY Plane Scale (ratio):', self, 1.03, 1.01)
-               self.zAxisScale = settings.FloatSpin().getFromValue(0.99, 'Z Axis Scale (ratio):', self, 1.02, 1.0)
-               self.svgViewer = settings.StringSetting().getFromValue('SVG Viewer:', self, 'webbrowser')
-               self.executeTitle = 'Scale'
-
-       def execute(self):
-               "Scale button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class ScaleSkein(object):
-       "A class to scale a skein of extrusions."
-       def getCraftedGcode(self, fileName, repository, svgText):
-               "Parse svgText and store the scale svgText."
-               svgReader = SVGReader()
-               svgReader.parseSVG('', svgText)
-               if svgReader.sliceDictionary == None:
-                       print('Warning, nothing will be done because the sliceDictionary could not be found getCraftedGcode in preface.')
-                       return ''
-               xyPlaneScale = repository.xyPlaneScale.value
-               zAxisScale = repository.zAxisScale.value
-               decimalPlacesCarried = int(svgReader.sliceDictionary['decimalPlacesCarried'])
-               layerHeight = zAxisScale * float(svgReader.sliceDictionary['layerHeight'])
-               edgeWidth = float(svgReader.sliceDictionary['edgeWidth'])
-               loopLayers = svgReader.loopLayers
-               for loopLayer in loopLayers:
-                       setLoopLayerScale(loopLayer, xyPlaneScale, zAxisScale)
-               cornerMaximum = Vector3(-912345678.0, -912345678.0, -912345678.0)
-               cornerMinimum = Vector3(912345678.0, 912345678.0, 912345678.0)
-               svg_writer.setSVGCarvingCorners(cornerMaximum, cornerMinimum, layerHeight, loopLayers)
-               svgWriter = svg_writer.SVGWriter(
-                       True,
-                       cornerMaximum,
-                       cornerMinimum,
-                       decimalPlacesCarried,
-                       layerHeight,
-                       edgeWidth)
-               commentElement = svg_writer.getCommentElement(svgReader.documentElement)
-               procedureNameString = svgReader.sliceDictionary['procedureName'] + ',scale'
-               return svgWriter.getReplacedSVGTemplate(fileName, loopLayers, procedureNameString, commentElement)
-
-
-def main():
-       "Display the scale dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/skin.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/skin.py
deleted file mode 100644 (file)
index c8a69f0..0000000
+++ /dev/null
@@ -1,398 +0,0 @@
-"""
-This page is in the table of contents.
-Skin is a plugin to smooth the surface skin of an object by replacing the edge surface with a surface printed at a fraction of the carve
-height.  This gives the impression that the object was carved at a much thinner height giving a high-quality finish, but still prints 
-in a relatively short time.  The latest process has some similarities with a description at:
-
-http://adventuresin3-dprinting.blogspot.com/2011/05/skinning.html
-
-The skin manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Skin
-
-==Operation==
-The default 'Activate Skin' checkbox is off.  When it is on, the functions described below will work, when it is off, nothing will be done.
-
-==Settings==
-===Division===
-====Horizontal Infill Divisions====
-Default: 2
-
-Defines the number of times the skinned infill is divided horizontally.
-
-====Horizontal Perimeter Divisions====
-Default: 1
-
-Defines the number of times the skinned edges are divided horizontally.
-
-====Vertical Divisions====
-Default: 2
-
-Defines the number of times the skinned infill and edges are divided vertically.
-
-===Hop When Extruding Infill===
-Default is off.
-
-When selected, the extruder will hop before and after extruding the lower infill in order to avoid the regular thickness threads.
-
-===Layers From===
-Default: 1
-
-Defines which layer of the print the skinning process starts from. It is not wise to set this to zero, skinning the bottom layer is likely to cause the bottom edge not to adhere well to the print surface.
-
-==Tips==
-Due to the very small Z-axis moves skinning can generate as it prints the edge, it can cause the Z-axis speed to be limited by the Limit plug-in, if you have it enabled. This can cause some printers to pause excessively during each layer change. To overcome this, ensure that the Z-axis max speed in the Limit tool is set to an appropriate value for your printer, e.g. 10mm/s
-
-Since Skin prints a number of fractional-height edge layers for each layer, printing the edge last causes the print head to travel down from the current print height. Depending on the shape of your extruder nozzle, you may get higher quality prints if you print the edges first, so the print head always travels up.  This is set via the Thread Sequence Choice setting in the Fill tool.
-
-==Examples==
-The following examples skin the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and skin.py.
-
-> python skin.py
-This brings up the skin dialog.
-
-> python skin.py Screw Holder Bottom.stl
-The skin tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The skin tool has created the file:
-.. Screw Holder Bottom_skin.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import intercircle
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique aht yahoo.com) & James Blackwell (jim_blag ahht hotmail.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText(fileName, gcodeText, repository=None):
-       'Skin a gcode linear move text.'
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, gcodeText), repository)
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       'Skin a gcode linear move text.'
-       if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'skin'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository(SkinRepository())
-       if not repository.activateSkin.value:
-               return gcodeText
-       return SkinSkein().getCraftedGcode(gcodeText, repository)
-
-def getIsMinimumSides(loops, sides=3):
-       'Determine if all the loops have at least the given number of sides.'
-       for loop in loops:
-               if len(loop) < sides:
-                       return False
-       return True
-
-def getNewRepository():
-       'Get new repository.'
-       return SkinRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       'Skin a gcode linear move file.  Chain skin the gcode if it is not already skinned.'
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'skin', shouldAnalyze)
-
-
-class SkinRepository(object):
-       'A class to handle the skin settings.'
-       def __init__(self):
-               'Set the default settings, execute title & settings fileName.'
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.skin.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Skin', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Skin')
-               self.activateSkin = settings.BooleanSetting().getFromValue('Activate Skin', self, False)
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Division -', self)
-               self.horizontalInfillDivisions = settings.IntSpin().getSingleIncrementFromValue(1, 'Horizontal Infill Divisions (integer):', self, 3, 2)
-               self.horizontalPerimeterDivisions = settings.IntSpin().getSingleIncrementFromValue(1, 'Horizontal Perimeter Divisions (integer):', self, 3, 1)
-               self.verticalDivisions = settings.IntSpin().getSingleIncrementFromValue(1, 'Vertical Divisions (integer):', self, 3, 2)
-               settings.LabelSeparator().getFromRepository(self)
-               self.hopWhenExtrudingInfill = settings.BooleanSetting().getFromValue('Hop When Extruding Infill', self, False)
-               self.layersFrom = settings.IntSpin().getSingleIncrementFromValue(0, 'Layers From (index):', self, 912345678, 1)
-               self.executeTitle = 'Skin'
-
-       def execute(self):
-               'Skin button has been clicked.'
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class SkinSkein(object):
-       'A class to skin a skein of extrusions.'
-       def __init__(self):
-               'Initialize.'
-               self.clipOverEdgeWidth = 0.0
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.edge = None
-               self.feedRateMinute = 959.0
-               self.infill = None
-               self.infillBoundaries = None
-               self.infillBoundary = None
-               self.layerIndex = -1
-               self.lineIndex = 0
-               self.lines = None
-               self.maximumZFeedRateMinute = 60.0
-               self.oldFlowRate = None
-               self.oldLocation = None
-               self.sharpestProduct = 0.94
-               self.travelFeedRateMinute = 957.0
-
-       def addFlowRateLine(self, flowRate):
-               'Add a flow rate line.'
-               if flowRate != None:
-                       self.distanceFeedRate.addLine('M108 S' + euclidean.getFourSignificantFigures(flowRate))
-
-       def addPerimeterLoop(self, thread, z):
-               'Add the edge loop to the gcode.'
-               self.distanceFeedRate.addGcodeFromFeedRateThreadZ(self.feedRateMinute, thread, self.travelFeedRateMinute, z)
-
-       def addSkinnedInfill(self):
-               'Add skinned infill.'
-               if self.infillBoundaries == None:
-                       return
-               bottomZ = self.oldLocation.z + self.layerHeight / self.verticalDivisionsFloat - self.layerHeight
-               offsetY = 0.5 * self.skinInfillWidth
-               if self.oldFlowRate != None:
-                       self.addFlowRateLine(self.oldFlowRate / self.verticalDivisionsFloat / self.horizontalInfillDivisionsFloat)
-               for verticalDivisionIndex in xrange(self.verticalDivisions):
-                       z = bottomZ + self.layerHeight / self.verticalDivisionsFloat * float(verticalDivisionIndex)
-                       self.addSkinnedInfillBoundary(self.infillBoundaries, offsetY * (verticalDivisionIndex % 2 == 0), self.oldLocation.z, z)
-               self.addFlowRateLine(self.oldFlowRate)
-               self.infillBoundaries = None
-
-       def addSkinnedInfillBoundary(self, infillBoundaries, offsetY, upperZ, z):
-               'Add skinned infill boundary.'
-               arounds = []
-               aroundWidth = 0.34321 * self.skinInfillInset
-               endpoints = []
-               pixelTable = {}
-               rotatedLoops = []
-               for infillBoundary in infillBoundaries:
-                       infillBoundaryRotated = euclidean.getRotatedComplexes(self.reverseRotation, infillBoundary)
-                       if offsetY != 0.0:
-                               for infillPointRotatedIndex, infillPointRotated in enumerate(infillBoundaryRotated):
-                                       infillBoundaryRotated[infillPointRotatedIndex] = complex(infillPointRotated.real, infillPointRotated.imag - offsetY)
-                       rotatedLoops.append(infillBoundaryRotated)
-               infillDictionary = triangle_mesh.getInfillDictionary(
-                       arounds, aroundWidth, self.skinInfillInset, self.skinInfillWidth, pixelTable, rotatedLoops)
-               for infillDictionaryKey in infillDictionary.keys():
-                       xIntersections = infillDictionary[infillDictionaryKey]
-                       xIntersections.sort()
-                       for segment in euclidean.getSegmentsFromXIntersections(xIntersections, infillDictionaryKey * self.skinInfillWidth):
-                               for endpoint in segment:
-                                       endpoint.point = complex(endpoint.point.real, endpoint.point.imag + offsetY)
-                                       endpoints.append(endpoint)
-               infillPaths = euclidean.getPathsFromEndpoints(endpoints, 5.0 * self.skinInfillWidth, pixelTable, self.sharpestProduct, aroundWidth)
-               for infillPath in infillPaths:
-                       addPointBeforeThread = True
-                       infillRotated = euclidean.getRotatedComplexes(self.rotation, infillPath)
-                       if upperZ > z and self.repository.hopWhenExtrudingInfill.value:
-                               feedRateMinute = self.travelFeedRateMinute
-                               infillRotatedFirst = infillRotated[0]
-                               location = Vector3(infillRotatedFirst.real, infillRotatedFirst.imag, upperZ)
-                               distance = abs(location - self.oldLocation)
-                               if distance > 0.0:
-                                       deltaZ = abs(upperZ - self.oldLocation.z)
-                                       zFeedRateComponent = feedRateMinute * deltaZ / distance
-                                       if zFeedRateComponent > self.maximumZFeedRateMinute:
-                                               feedRateMinute *= self.maximumZFeedRateMinute / zFeedRateComponent
-                               self.distanceFeedRate.addGcodeMovementZWithFeedRate(feedRateMinute, infillRotatedFirst, upperZ)
-                               self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.maximumZFeedRateMinute, infillRotatedFirst, z)
-                               addPointBeforeThread = False
-                       if addPointBeforeThread:
-                               self.distanceFeedRate.addGcodeMovementZ(infillRotated[0], z)
-                       self.distanceFeedRate.addLine('M101')
-                       for point in infillRotated[1 :]:
-                               self.distanceFeedRate.addGcodeMovementZ(point, z)
-                       self.distanceFeedRate.addLine('M103')
-                       lastPointRotated = infillRotated[-1]
-                       self.oldLocation = Vector3(lastPointRotated.real, lastPointRotated.imag, upperZ)
-                       if upperZ > z and self.repository.hopWhenExtrudingInfill.value:
-                               self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.maximumZFeedRateMinute, lastPointRotated, upperZ)
-
-       def addSkinnedPerimeter(self):
-               'Add skinned edge.'
-               if self.edge == None:
-                       return
-               bottomZ = self.oldLocation.z + self.layerHeight / self.verticalDivisionsFloat - self.layerHeight
-               edgeThread = self.edge[: -1]
-               edges = []
-               radiusAddition = self.edgeWidth / self.horizontalPerimeterDivisionsFloat
-               radius = 0.5 * radiusAddition - self.halfEdgeWidth
-               for division in xrange(self.repository.horizontalPerimeterDivisions.value):
-                       edges.append(self.getClippedSimplifiedLoopPathByLoop(intercircle.getLargestInsetLoopFromLoop(edgeThread, radius)))
-                       radius += radiusAddition
-               skinnedPerimeterFlowRate = None
-               if self.oldFlowRate != None:
-                       skinnedPerimeterFlowRate = self.oldFlowRate / self.verticalDivisionsFloat
-               if getIsMinimumSides(edges):
-                       if self.oldFlowRate != None:
-                               self.addFlowRateLine(skinnedPerimeterFlowRate / self.horizontalPerimeterDivisionsFloat)
-                       for verticalDivisionIndex in xrange(self.verticalDivisions):
-                               z = bottomZ + self.layerHeight / self.verticalDivisionsFloat * float(verticalDivisionIndex)
-                               for edge in edges:
-                                       self.addPerimeterLoop(edge, z)
-               else:
-                       self.addFlowRateLine(skinnedPerimeterFlowRate)
-                       for verticalDivisionIndex in xrange(self.verticalDivisions):
-                               z = bottomZ + self.layerHeight / self.verticalDivisionsFloat * float(verticalDivisionIndex)
-                               self.addPerimeterLoop(self.edge, z)
-               self.addFlowRateLine(self.oldFlowRate)
-               self.edge = None
-
-       def getClippedSimplifiedLoopPathByLoop(self, loop):
-               'Get clipped and simplified loop path from a loop.'
-               if len(loop) == 0:
-                       return []
-               loopPath = loop + [loop[0]]
-               return euclidean.getClippedSimplifiedLoopPath(self.clipLength, loopPath, self.halfEdgeWidth)
-
-       def getCraftedGcode( self, gcodeText, repository ):
-               'Parse gcode text and store the skin gcode.'
-               self.lines = archive.getTextLines(gcodeText)
-               self.repository = repository
-               self.layersFromBottom = repository.layersFrom.value
-               self.horizontalInfillDivisionsFloat = float(repository.horizontalInfillDivisions.value)
-               self.horizontalPerimeterDivisionsFloat = float(repository.horizontalPerimeterDivisions.value)
-               self.verticalDivisions = max(repository.verticalDivisions.value, 1)
-               self.verticalDivisionsFloat = float(self.verticalDivisions)
-               self.parseInitialization()
-               self.clipLength = 0.5 * self.clipOverEdgeWidth * self.edgeWidth
-               self.skinInfillInset = 0.5 * (self.infillWidth + self.skinInfillWidth) * (1.0 - self.infillPerimeterOverlap)
-               self.parseBoundaries()
-               for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       self.parseLine(line)
-               return gcodec.getGcodeWithoutDuplication('M108', self.distanceFeedRate.output.getvalue())
-
-       def parseBoundaries(self):
-               'Parse the boundaries and add them to the boundary layers.'
-               self.boundaryLayers = []
-               self.layerIndexTop = -1
-               boundaryLoop = None
-               boundaryLayer = None
-               for line in self.lines[self.lineIndex :]:
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == '(</boundaryPerimeter>)':
-                               boundaryLoop = None
-                       elif firstWord == '(<boundaryPoint>':
-                               location = gcodec.getLocationFromSplitLine(None, splitLine)
-                               if boundaryLoop == None:
-                                       boundaryLoop = []
-                                       boundaryLayer.loops.append(boundaryLoop)
-                               boundaryLoop.append(location.dropAxis())
-                       elif firstWord == '(<layer>':
-                               boundaryLayer = euclidean.LoopLayer(float(splitLine[1]))
-                               self.boundaryLayers.append(boundaryLayer)
-                               self.layerIndexTop += 1
-               for boundaryLayerIndex, boundaryLayer in enumerate(self.boundaryLayers):
-                       if len(boundaryLayer.loops) > 0:
-                               self.layersFromBottom += boundaryLayerIndex
-                               return
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(<clipOverEdgeWidth>':
-                               self.clipOverEdgeWidth = float(splitLine[1])
-                       elif firstWord == '(<edgeWidth>':
-                               self.edgeWidth = float(splitLine[1])
-                               self.halfEdgeWidth = 0.5 * self.edgeWidth
-                       elif firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('skin')
-                               return
-                       elif firstWord == '(<infillPerimeterOverlap>':
-                               self.infillPerimeterOverlap = float(splitLine[1])
-                       elif firstWord == '(<infillWidth>':
-                               self.infillWidth = float(splitLine[1])
-                               self.skinInfillWidth = self.infillWidth / self.horizontalInfillDivisionsFloat
-                       elif firstWord == '(<layerHeight>':
-                               self.layerHeight = float(splitLine[1])
-                       elif firstWord == '(<maximumZFeedRatePerSecond>':
-                               self.maximumZFeedRateMinute = 60.0 * float(splitLine[1])
-                       elif firstWord == '(<operatingFlowRate>':
-                               self.oldFlowRate = float(splitLine[1])
-                       elif firstWord == '(<sharpestProduct>':
-                               self.sharpestProduct = float(splitLine[1])
-                       elif firstWord == '(<travelFeedRatePerSecond>':
-                               self.travelFeedRateMinute = 60.0 * float(splitLine[1])
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               'Parse a gcode line and add it to the skin skein.'
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine)
-                       self.oldLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-                       if self.infillBoundaries != None:
-                               return
-                       if self.edge != None:
-                               self.edge.append(self.oldLocation.dropAxis())
-                               return
-               elif firstWord == '(<infill>)':
-                       if self.layerIndex >= self.layersFromBottom and self.layerIndex == self.layerIndexTop:
-                               self.infillBoundaries = []
-               elif firstWord == '(</infill>)':
-                       self.addSkinnedInfill()
-               elif firstWord == '(<infillBoundary>)':
-                       if self.infillBoundaries != None:
-                               self.infillBoundary = []
-                               self.infillBoundaries.append(self.infillBoundary)
-               elif firstWord == '(<infillPoint>':
-                       if self.infillBoundaries != None:
-                               location = gcodec.getLocationFromSplitLine(None, splitLine)
-                               self.infillBoundary.append(location.dropAxis())
-               elif firstWord == '(<layer>':
-                       self.layerIndex += 1
-                       settings.printProgress(self.layerIndex, 'skin')
-               elif firstWord == 'M101' or firstWord == 'M103':
-                       if self.infillBoundaries != None or self.edge != None:
-                               return
-               elif firstWord == 'M108':
-                       self.oldFlowRate = gcodec.getDoubleAfterFirstLetter(splitLine[1])
-               elif firstWord == '(<edge>':
-                       if self.layerIndex >= self.layersFromBottom:
-                               self.edge = []
-               elif firstWord == '(<rotation>':
-                       self.rotation = gcodec.getRotationBySplitLine(splitLine)
-                       self.reverseRotation = complex(self.rotation.real, -self.rotation.imag)
-               elif firstWord == '(</edge>)':
-                       self.addSkinnedPerimeter()
-               self.distanceFeedRate.addLine(line)
-
-
-def main():
-       'Display the skin dialog.'
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == '__main__':
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/skirt.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/skirt.py
deleted file mode 100644 (file)
index e5c8bdc..0000000
+++ /dev/null
@@ -1,350 +0,0 @@
-"""
-This page is in the table of contents.
-Skirt is a plugin to give the extruder some extra time to begin extruding properly before beginning the object, and to put a baffle around the model in order to keep the extrusion warm.
-
-The skirt manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Skirt
-
-It is loosely based on Lenbook's outline plugin:
-
-http://www.thingiverse.com/thing:4918
-
-it is also loosely based on the outline that Nophead sometimes uses:
-
-http://hydraraptor.blogspot.com/2010/01/hot-metal-and-serendipity.html
-
-and also loosely based on the baffles that Nophead made to keep corners warm:
-
-http://hydraraptor.blogspot.com/2010/09/some-corners-like-it-hot.html
-
-If you want only an outline, set 'Layers To' to one.  This gives the extruder some extra time to begin extruding properly before beginning your object, and gives you an early verification of where your object will be extruded.
-
-If you also want an insulating skirt around the entire object, set 'Layers To' to a huge number, like 912345678.  This will additionally make an insulating baffle around the object; to prevent moving air from cooling the object, which increases warping, especially in corners.
-
-==Operation==
-The default 'Activate Skirt' checkbox is off.  When it is on, the functions described below will work, when it is off, nothing will be done.
-
-==Settings==
-===Convex===
-Default is on.
-
-When selected, the skirt will be convex, going around the model with only convex angles.  If convex is not selected, the skirt will hug the model, going into every nook and cranny.
-
-===Gap over Perimeter Width===
-Default is three.
-
-Defines the ratio of the gap between the object and the skirt over the edge width.  If the ratio is too low, the skirt will connect to the object, if the ratio is too high, the skirt willl not provide much insulation for the object.
-
-===Layers To===
-Default is a one.
-
-Defines the number of layers of the skirt.  If you want only an outline, set 'Layers To' to one.  If you want an insulating skirt around the entire object, set 'Layers To' to a huge number, like 912345678.
-
-==Examples==
-The following examples skirt the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and skirt.py.
-
-> python skirt.py
-This brings up the skirt dialog.
-
-> python skirt.py Screw Holder Bottom.stl
-The skirt tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The skirt tool has created the file:
-.. Screw Holder Bottom_skirt.gcode
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import intercircle
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText(fileName, text='', repository=None):
-       'Skirt the fill file or text.'
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository)
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       'Skirt the fill text.'
-       if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'skirt'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository(SkirtRepository())
-       if repository.skirtLineCount.value < 1:
-               return gcodeText
-       return SkirtSkein().getCraftedGcode(gcodeText, repository)
-
-def getNewRepository():
-       'Get new repository.'
-       return SkirtRepository()
-
-def getOuterLoops(loops):
-       'Get widdershins outer loops.'
-       outerLoops = []
-       for loop in loops:
-               if not euclidean.isPathInsideLoops(outerLoops, loop):
-                       outerLoops.append(loop)
-       intercircle.directLoops(True, outerLoops)
-       return outerLoops
-
-def writeOutput(fileName, shouldAnalyze=True):
-       'Skirt a gcode linear move file.'
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'skirt', shouldAnalyze)
-
-
-class LoopCrossDictionary(object):
-       'Loop with a horizontal and vertical dictionary.'
-       def __init__(self):
-               'Initialize LoopCrossDictionary.'
-               self.loop = []
-
-       def __repr__(self):
-               'Get the string representation of this LoopCrossDictionary.'
-               return str(self.loop)
-
-
-class SkirtRepository(object):
-       'A class to handle the skirt settings.'
-       def __init__(self):
-               'Set the default settings, execute title & settings fileName.'
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.skirt.html', self)
-               self.fileNameInput = settings.FileNameInput().getFromFileName(
-                       fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Skirt', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Skirt')
-               self.skirtLineCount = settings.IntSpin().getSingleIncrementFromValue(0, 'Skirt line count', self, 20, 1)
-               self.convex = settings.BooleanSetting().getFromValue('Convex:', self, True)
-               self.gapWidth = settings.FloatSpin().getFromValue(1.0, 'Gap Width (mm):', self, 5.0, 3.0)
-               self.layersTo = settings.IntSpin().getSingleIncrementFromValue(0, 'Layers To (index):', self, 912345678, 1)
-               self.executeTitle = 'Skirt'
-
-       def execute(self):
-               'Skirt button has been clicked.'
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(
-                       self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class SkirtSkein(object):
-       'A class to skirt a skein of extrusions.'
-       def __init__(self):
-               'Initialize variables.'
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.feedRateMinute = 961.0
-               self.isExtruderActive = False
-               self.isSupportLayer = False
-               self.layerIndex = -1
-               self.lineIndex = 0
-               self.lines = None
-               self.oldFlowRate = None
-               self.oldLocation = None
-               self.oldTemperatureInput = None
-               self.skirtFlowRate = None
-               self.skirtTemperature = None
-               self.travelFeedRateMinute = 957.0
-               self.unifiedLoop = LoopCrossDictionary()
-
-       def addFlowRate(self, flowRate):
-               'Add a line of temperature if different.'
-               if flowRate != None:
-                       self.distanceFeedRate.addLine('M108 S' + euclidean.getFourSignificantFigures(flowRate))
-
-       def addSkirt(self, z):
-               'At skirt at z to gcode output.'
-               if len(self.outsetLoops) < 1 or len(self.outsetLoops[0]) < 1:
-                       return
-               self.setSkirtFeedFlowTemperature()
-               self.distanceFeedRate.addLine('(<skirt>)')
-               oldTemperature = self.oldTemperatureInput
-               self.addTemperatureLineIfDifferent(self.skirtTemperature)
-               self.addFlowRate(self.skirtFlowRate)
-               for outsetLoop in self.outsetLoops:
-                       closedLoop = outsetLoop + [outsetLoop[0]]
-                       self.distanceFeedRate.addGcodeFromFeedRateThreadZ(self.feedRateMinute, closedLoop, self.travelFeedRateMinute, z)
-               self.addFlowRate(self.oldFlowRate)
-               self.addTemperatureLineIfDifferent(oldTemperature)
-               self.distanceFeedRate.addLine('(</skirt>)')
-
-       def addTemperatureLineIfDifferent(self, temperature):
-               'Add a line of temperature if different.'
-               if temperature == None or temperature == self.oldTemperatureInput:
-                       return
-               self.distanceFeedRate.addLine('M104 S' + euclidean.getRoundedToThreePlaces(temperature))
-               self.oldTemperatureInput = temperature
-
-       def createSegmentDictionaries(self, loopCrossDictionary):
-               'Create horizontal and vertical segment dictionaries.'
-               loopCrossDictionary.horizontalDictionary = self.getHorizontalXIntersectionsTable(loopCrossDictionary.loop)
-               flippedLoop = euclidean.getDiagonalFlippedLoop(loopCrossDictionary.loop)
-               loopCrossDictionary.verticalDictionary = self.getHorizontalXIntersectionsTable(flippedLoop)
-
-       def createSkirtLoops(self):
-               'Create the skirt loops.'
-               points = euclidean.getPointsByHorizontalDictionary(self.edgeWidth, self.unifiedLoop.horizontalDictionary)
-               points += euclidean.getPointsByVerticalDictionary(self.edgeWidth, self.unifiedLoop.verticalDictionary)
-               loops = triangle_mesh.getDescendingAreaOrientedLoops(points, points, 2.5 * self.edgeWidth)
-               outerLoops = getOuterLoops(loops)
-               self.outsetLoops = []
-               for i in xrange(self.repository.skirtLineCount.value, 0, -1):
-                       outsetLoops = intercircle.getInsetSeparateLoopsFromLoops(outerLoops, -self.skirtOutset - (i-1) * self.edgeWidth)
-                       outsetLoops = getOuterLoops(outsetLoops)
-                       if self.repository.convex.value:
-                               outsetLoops = [euclidean.getLoopConvex(euclidean.getConcatenatedList(outsetLoops))]
-                       self.outsetLoops.extend(outsetLoops)
-
-       def getCraftedGcode(self, gcodeText, repository):
-               'Parse gcode text and store the skirt gcode.'
-               self.repository = repository
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization()
-               self.parseBoundaries()
-               self.createSkirtLoops()
-               for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       self.parseLine(line)
-               return gcodec.getGcodeWithoutDuplication('M108', self.distanceFeedRate.output.getvalue())
-
-       def getHorizontalXIntersectionsTable(self, loop):
-               'Get the horizontal x intersections table from the loop.'
-               horizontalXIntersectionsTable = {}
-               euclidean.addXIntersectionsFromLoopForTable(loop, horizontalXIntersectionsTable, self.edgeWidth)
-               return horizontalXIntersectionsTable
-
-       def parseBoundaries(self):
-               'Parse the boundaries and union them.'
-               self.createSegmentDictionaries(self.unifiedLoop)
-               if self.repository.layersTo.value < 1:
-                       return
-               loopCrossDictionary = None
-               layerIndex = -1
-               for line in self.lines[self.lineIndex :]:
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == '(</boundaryPerimeter>)' or firstWord == '(</raftPerimeter>)':
-                               self.createSegmentDictionaries(loopCrossDictionary)
-                               self.unifyLayer(loopCrossDictionary)
-                               loopCrossDictionary = None
-                       elif firstWord == '(<boundaryPoint>' or firstWord == '(<raftPoint>':
-                               location = gcodec.getLocationFromSplitLine(None, splitLine)
-                               if loopCrossDictionary == None:
-                                       loopCrossDictionary = LoopCrossDictionary()
-                               loopCrossDictionary.loop.append(location.dropAxis())
-                       elif firstWord == '(<layer>':
-                               layerIndex += 1
-                               if layerIndex > self.repository.layersTo.value:
-                                       return
-                               settings.printProgress(layerIndex, 'skirt')
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('skirt')
-                               return
-                       elif firstWord == '(<objectNextLayersTemperature>':
-                               self.oldTemperatureInput = float(splitLine[1])
-                               self.skirtTemperature = self.oldTemperatureInput
-                       elif firstWord == '(<operatingFeedRatePerSecond>':
-                               self.feedRateMinute = 60.0 * float(splitLine[1])
-                       elif firstWord == '(<operatingFlowRate>':
-                               self.oldFlowRate = float(splitLine[1])
-                               self.skirtFlowRate = self.oldFlowRate
-                       elif firstWord == '(<edgeWidth>':
-                               self.edgeWidth = float(splitLine[1])
-                               self.skirtOutset = self.repository.gapWidth.value + 0.5 * self.edgeWidth
-                               self.distanceFeedRate.addTagRoundedLine('skirtOutset', self.skirtOutset)
-                       elif firstWord == '(<travelFeedRatePerSecond>':
-                               self.travelFeedRateMinute = 60.0 * float(splitLine[1])
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               'Parse a gcode line and add it to the skirt skein.'
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == '(<raftPerimeter>)' or firstWord == '(</raftPerimeter>)' or firstWord == '(<raftPoint>':
-                       return
-               self.distanceFeedRate.addLine(line)
-               if firstWord == 'G1':
-                       self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine)
-               elif firstWord == '(<layer>':
-                       self.layerIndex += 1
-                       if self.layerIndex < self.repository.layersTo.value:
-                               self.addSkirt(float(splitLine[1]))
-               elif firstWord == 'M101':
-                       self.isExtruderActive = True
-               elif firstWord == 'M103':
-                       self.isExtruderActive = False
-               elif firstWord == 'M104':
-                       self.oldTemperatureInput = gcodec.getDoubleAfterFirstLetter(splitLine[1])
-                       self.skirtTemperature = self.oldTemperatureInput
-               elif firstWord == 'M108':
-                       self.oldFlowRate = gcodec.getDoubleAfterFirstLetter(splitLine[1])
-                       self.skirtFlowRate = self.oldFlowRate
-               elif firstWord == '(<supportLayer>)':
-                       self.isSupportLayer = True
-               elif firstWord == '(</supportLayer>)':
-                       self.isSupportLayer = False
-
-       def setSkirtFeedFlowTemperature(self):
-               'Set the skirt feed rate, flow rate and temperature to that of the next extrusion.'
-               isExtruderActive = self.isExtruderActive
-               isSupportLayer = self.isSupportLayer
-               for lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1':
-                               self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine)
-                               if isExtruderActive:
-                                       if not isSupportLayer:
-                                               return
-                       elif firstWord == 'M101':
-                               isExtruderActive = True
-                       elif firstWord == 'M103':
-                               isExtruderActive = False
-                       elif firstWord == 'M104':
-                               self.skirtTemperature = gcodec.getDoubleAfterFirstLetter(splitLine[1])
-                       elif firstWord == 'M108':
-                               self.skirtFlowRate = gcodec.getDoubleAfterFirstLetter(splitLine[1])
-                       elif firstWord == '(<supportLayer>)':
-                               isSupportLayer = True
-                       elif firstWord == '(</supportLayer>)':
-                               isSupportLayer = False
-
-       def unifyLayer(self, loopCrossDictionary):
-               'Union the loopCrossDictionary with the unifiedLoop.'
-               euclidean.joinXIntersectionsTables(loopCrossDictionary.horizontalDictionary, self.unifiedLoop.horizontalDictionary)
-               euclidean.joinXIntersectionsTables(loopCrossDictionary.verticalDictionary, self.unifiedLoop.verticalDictionary)
-
-
-def main():
-       'Display the skirt dialog.'
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == '__main__':
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/smooth.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/smooth.py
deleted file mode 100644 (file)
index da21d16..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-"""
-This page is in the table of contents.
-This plugin smooths jagged extruder paths.  It takes shortcuts through jagged paths and decreases the feed rate to compensate.
-
-Smooth is based on ideas in Nophead's frequency limit post: 
-
-http://hydraraptor.blogspot.com/2010/12/frequency-limit.html
-
-The smooth manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Smooth
-
-==Operation==
-The default 'Activate Smooth' checkbox is off.  When it is on, the functions described below will work, when it is off, nothing will be done.
-
-==Settings==
-===Layers From===
-Default: 1
-
-Defines which layer of the print the smoothing process starts from.  If this is set this to zero, that might cause the smoothed parts of the bottom edge not to adhere well to the print surface.  However, this is just a potential problem in theory, no bottom adhesion problem has been reported. 
-
-===Maximum Shortening over Width===
-Default: 1.2
-
-Defines the maximum shortening of the shortcut compared to the original path.  Smooth goes over the path and if the shortcut between the midpoint of one line and the midpoint of the second line after is not too short compared to the original and the shortcut is not too long, it replaces the jagged original with the shortcut.  If the maximum shortening is too much, smooth will shorten paths which should not of been shortened and will leave blobs and holes in the model.  If the maximum shortening is too little, even jagged paths that could be shortened safely won't be smoothed.
-
-==Examples==
-The following examples smooth the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and smooth.py.
-
-> python smooth.py
-This brings up the smooth dialog.
-
-> python smooth.py Screw Holder Bottom.stl
-The smooth tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The smooth tool has created the file:
-.. Screw Holder Bottom_smooth.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique aht yahoo.com) & James Blackwell (jim_blag ahht hotmail.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText(fileName, gcodeText, repository=None):
-       'Smooth a gcode linear move text.'
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, gcodeText), repository)
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       'Smooth a gcode linear move text.'
-       if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'smooth'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository(SmoothRepository())
-       if not repository.activateSmooth.value:
-               return gcodeText
-       return SmoothSkein().getCraftedGcode(gcodeText, repository)
-
-def getNewRepository():
-       'Get new repository.'
-       return SmoothRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       'Smooth a gcode linear move file.  Chain smooth the gcode if it is not already smoothed.'
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'smooth', shouldAnalyze)
-
-
-class SmoothRepository(object):
-       'A class to handle the smooth settings.'
-       def __init__(self):
-               'Set the default settings, execute title & settings fileName.'
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.smooth.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Smooth', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Smooth')
-               self.activateSmooth = settings.BooleanSetting().getFromValue('Activate Smooth', self, False)
-               self.layersFrom = settings.IntSpin().getSingleIncrementFromValue(0, 'Layers From (index):', self, 912345678, 1)
-               self.maximumShorteningOverWidth = settings.FloatSpin().getFromValue(0.2, 'Maximum Shortening over Width (float):', self, 2.0, 1.2)
-               self.executeTitle = 'Smooth'
-
-       def execute(self):
-               'Smooth button has been clicked.'
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class SmoothSkein(object):
-       'A class to smooth a skein of extrusions.'
-       def __init__(self):
-               'Initialize.'
-               self.boundaryLayerIndex = -1
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.feedRateMinute = 959.0
-               self.infill = None
-               self.layerCount = settings.LayerCount()
-               self.lineIndex = 0
-               self.lines = None
-               self.oldLocation = None
-               self.travelFeedRateMinute = 957.0
-
-       def addSmoothedInfill(self):
-               'Add smoothed infill.'
-               if len(self.infill) < 4:
-                       self.distanceFeedRate.addGcodeFromFeedRateThreadZ(self.feedRateMinute, self.infill, self.travelFeedRateMinute, self.oldLocation.z)
-                       return
-               self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.travelFeedRateMinute, self.infill[0], self.oldLocation.z)
-               self.distanceFeedRate.addLine('M101')
-               lengthMinusOne = len(self.infill) - 1
-               lengthMinusTwo = lengthMinusOne - 1
-               wasOriginalPoint = True
-               pointIndex = 0
-               while pointIndex < lengthMinusOne:
-                       nextPoint = self.infill[pointIndex + 1]
-                       afterNextIndex = pointIndex + 2
-                       if afterNextIndex < lengthMinusTwo:
-                               point = self.infill[pointIndex]
-                               midpoint = 0.5 * (point + nextPoint)
-                               afterNextPoint = self.infill[afterNextIndex]
-                               afterNextNextPoint = self.infill[afterNextIndex + 1]
-                               afterNextMidpoint = 0.5 * (afterNextPoint + afterNextNextPoint)
-                               shortcutDistance = abs(afterNextMidpoint - midpoint)
-                               originalDistance = abs(midpoint - point) + abs(afterNextPoint - nextPoint) + abs(afterNextMidpoint - afterNextPoint)
-                               segment = euclidean.getNormalized(nextPoint - point)
-                               afterNextSegment = euclidean.getNormalized(afterNextNextPoint - afterNextPoint)
-                               sameDirection = self.getIsParallelToRotation(segment) and self.getIsParallelToRotation(afterNextSegment)
-                               if originalDistance - shortcutDistance < self.maximumShortening and shortcutDistance < self.maximumDistance and sameDirection:
-                                       if wasOriginalPoint:
-                                               self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.feedRateMinute, midpoint, self.oldLocation.z)
-                                       feedrate = self.feedRateMinute
-                                       if originalDistance != 0.0:
-                                               feedrate *= shortcutDistance / originalDistance
-                                       self.distanceFeedRate.addGcodeMovementZWithFeedRate(feedrate, afterNextMidpoint, self.oldLocation.z)
-                                       wasOriginalPoint = False
-                                       pointIndex += 1
-                               else:
-                                       self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.feedRateMinute, nextPoint, self.oldLocation.z)
-                                       wasOriginalPoint = True
-                       else:
-                               self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.feedRateMinute, nextPoint, self.oldLocation.z)
-                               wasOriginalPoint = True
-                       pointIndex += 1
-               self.distanceFeedRate.addLine('M103')
-
-       def getCraftedGcode( self, gcodeText, repository ):
-               'Parse gcode text and store the smooth gcode.'
-               self.lines = archive.getTextLines(gcodeText)
-               self.repository = repository
-               self.layersFromBottom = repository.layersFrom.value
-               self.parseInitialization()
-               for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def getIsParallelToRotation(self, segment):
-               'Determine if the segment is parallel to the rotation.'
-               return abs(euclidean.getDotProduct(segment, self.rotation)) > 0.99999
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('smooth')
-                               return
-                       elif firstWord == '(<infillWidth>':
-                               self.infillWidth = float(splitLine[1])
-                               self.maximumShortening = self.repository.maximumShorteningOverWidth.value * self.infillWidth
-                               self.maximumDistance = 1.5 * self.maximumShortening
-                       elif firstWord == '(<travelFeedRatePerSecond>':
-                               self.travelFeedRateMinute = 60.0 * float(splitLine[1])
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               'Parse a gcode line and add it to the smooth skein.'
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == '(<boundaryPerimeter>)':
-                       if self.boundaryLayerIndex < 0:
-                               self.boundaryLayerIndex = 0
-               elif firstWord == 'G1':
-                       self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine)
-                       location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-                       self.oldLocation = location
-                       if self.infill != None:
-                               self.infill.append(location.dropAxis())
-                               return
-               elif firstWord == '(<infill>)':
-                       if self.boundaryLayerIndex >= self.layersFromBottom:
-                               self.infill = []
-               elif firstWord == '(</infill>)':
-                       self.infill = None
-               elif firstWord == '(<layer>':
-                       self.layerCount.printProgressIncrement('smooth')
-                       if self.boundaryLayerIndex >= 0:
-                               self.boundaryLayerIndex += 1
-               elif firstWord == 'M101':
-                       if self.infill != None:
-                               if len(self.infill) > 1:
-                                       self.infill = [self.infill[0]]
-                               return
-               elif firstWord == 'M103':
-                       if self.infill != None:
-                               self.addSmoothedInfill()
-                               self.infill = []
-                               return
-               elif firstWord == '(<rotation>':
-                       self.rotation = gcodec.getRotationBySplitLine(splitLine)
-               self.distanceFeedRate.addLine(line)
-
-
-def main():
-       'Display the smooth dialog.'
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == '__main__':
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/speed.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/speed.py
deleted file mode 100644 (file)
index 2aa7224..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-"""
-This page is in the table of contents.
-Speed is a plugin to set the feed rate and flow rate.
-
-The speed manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Speed
-
-==Operation==
-The default 'Activate Speed' checkbox is on.  When it is on, the functions described below will work, when it is off, nothing will be done.
-
-==Settings==
-===Add Flow Rate===
-Default is on.
-
-When selected, the flow rate will be added to the gcode.
-
-===Bridge===
-====Bridge Feed Rate Multiplier====
-Default is one.
-
-Defines the ratio of the feed rate (head speed) on the bridge layers over the feed rate of the typical non bridge layers.
-
-====Bridge Flow Rate Multiplier====
-Default is one.
-
-Defines the ratio of the flow rate (extruder speed) on the bridge layers over the flow rate of the typical non bridge layers.
-
-===Duty Cyle===
-====Duty Cyle at Beginning====
-Default is one, which will set the extruder motor to full current.
-
-Defines the duty cycle of the stepper motor pulse width modulation by adding an M113 command toward the beginning of the gcode text.  If the hardware has the option of using a potentiometer to set the duty cycle, to select the potentiometer option set 'Duty Cyle at Beginning' to an empty string.  To turn off the extruder, set the 'Duty Cyle at Beginning' to zero.
-
-====Duty Cyle at Ending====
-Default is zero, which will turn off the extruder motor.
-
-Defines the duty cycle of the stepper motor pulse width modulation by adding an M113 command toward the ending of the gcode text.  If the hardware has the option of using a potentiometer to set the duty cycle, to select the potentiometer option set 'Duty Cyle at Beginning' to an empty string.  To turn off the extruder, set the 'Duty Cyle at Ending' to zero.
-
-===Feed Rate===
-Default is sixteen millimeters per second.
-
-Defines the operating feed rate, the speed your printing head moves in XY plane, before any modifiers.
-
-===Flow Rate Setting===
-Default is 210.
-
-Defines the operating flow rate.
-
-RapMan uses this parameter to define the RPM of the extruder motor.  The extruder motor RPM is flow rate / 10 so if your flow rate is 150.0 that will set the extruder stepper to run at 15 RPM, different printers might read this value differently.
-
-===Maximum Z Feed Rate===
-Default is one millimeter per second.
-
-Defines the speed of a vertical hop, like the infill hop in skin.  Also, if the Limit plugin is activated, it will limit the maximum speed of the tool head in the z direction to this value.
-
-===Object First Layer===
-
-====Object First Layer Feed Rate Infill Multiplier====
-Default is 0.4.
-
-Defines the object first layer infill feed rate multiplier.  The greater the 'Object First Layer Feed Rate Infill Multiplier, the thinner the infill, the lower the 'Object First Layer Feed Rate Infill Multiplier', the thicker the infill.
-
-====Object First Layer Feed Rate Perimeter Multiplier====
-Default is 0.4.
-
-Defines the object first layer edge feed rate multiplier.  The greater the 'Object First Layer Feed Rate Perimeter Multiplier, the thinner the edge, the lower the 'Object First Layer Feed Rate Perimeter Multiplier', the thicker the edge.
-
-====Object First Layer Flow Rate Infill Multiplier====
-Default is 0.4.
-
-Defines the object first layer infill flow rate multiplier.  The greater the 'Object First Layer Flow Rate Infill Multiplier', the thicker the infill, the lower the 'Object First Layer Flow Rate Infill Multiplier, the thinner the infill.
-
-====Object First Layer Flow Rate Perimeter Multiplier====
-Default is 0.4.
-
-Defines the object first layer edge flow rate multiplier.  The greater the 'Object First Layer Flow Rate Perimeter Multiplier', the thicker the edge, the lower the 'Object First Layer Flow Rate Perimeter Multiplier, the thinner the edge.
-
-===Orbital Feed Rate over Operating Feed Rate===
-Default is 0.5.
-
-Defines the speed when the head is orbiting compared to the operating extruder speed.  If you want the orbit to be very short, set the "Orbital Feed Rate over Operating Feed Rate" setting to a low value like 0.1.
-
-===Perimeter===
-To have higher build quality on the outside at the expense of slower build speed, a typical setting for the 'Perimeter Feed Rate over Operating Feed Rate' would be 0.5.  To go along with that, if you are using a speed controlled extruder like a stepper extruder, the 'Perimeter Flow Rate over Operating Flow Rate' should also be 0.5.
-
-A stepper motor is the best way of driving the extruder; however, if you are stuck with a DC motor extruder using Pulse Width Modulation to control the speed, then you'll probably need a slightly higher ratio because there is a minimum voltage 'Flow Rate PWM Setting' required for the extruder motor to turn.  The flow rate PWM ratio would be determined by trial and error, with the first trial being:
-Perimeter Flow Rate over Operating Flow Rate ~ Perimeter Feed Rate over Operating Feed Rate * (Flow Rate PWM Setting - Minimum Flow Rate PWM Setting) + Minimum Flow Rate PWM Setting
-
-====Perimeter Feed Rate Multiplier====
-Default: 1.0
-
-Defines the ratio of the feed rate of the edge (outside shell) over the feed rate of the infill.  If you for example set this to 0.8 you will have a "stronger" outside edge than inside extrusion as the outside edge will be printed slower hence better lamination will occur and more filament will be placed there.
-
-====Perimeter Flow Rate Multiplier====
-Default: 1.0
-
-Defines the ratio of the flow rate of the edge (outside shell) over the flow rate of the infill.  If you want the same thickness of the edge but better lamination you need to compensate for the slower feed rate by slowing down the flow rate, but all combinations are possible for different results.
-
-===Travel Feed Rate===
-Default is sixteen millimeters per second.
-
-Defines the feed rate when the extruder is off (not printing).  The 'Travel Feed Rate' could be set as high as the extruder can be moved, it is not limited by the maximum extrusion rate.
-
-==Examples==
-The following examples speed the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and speed.py.
-
-> python speed.py
-This brings up the speed dialog.
-
-> python speed.py Screw Holder Bottom.stl
-The speed tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The speed tool has created the file:
-.. Screw Holder Bottom_speed.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, text='', repository=None):
-       "Speed the file or text."
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository)
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       "Speed a gcode linear move text."
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'speed'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository( SpeedRepository() )
-       if not repository.activateSpeed.value:
-               return gcodeText
-       return SpeedSkein().getCraftedGcode(gcodeText, repository)
-
-def getNewRepository():
-       'Get new repository.'
-       return SpeedRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Speed a gcode linear move file."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'speed', shouldAnalyze)
-
-
-class SpeedRepository(object):
-       "A class to handle the speed settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.speed.html', self )
-               self.baseNameSynonymDictionary = {
-                       'Object First Layer Feed Rate Infill Multiplier (ratio):' : 'raft.csv',
-                       'Object First Layer Feed Rate Perimeter Multiplier (ratio):' : 'raft.csv',
-                       'Object First Layer Flow Rate Infill Multiplier (ratio):' : 'raft.csv',
-                       'Object First Layer Flow Rate Perimeter Multiplier (ratio):' : 'raft.csv'}
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Speed', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Speed')
-               self.activateSpeed = settings.BooleanSetting().getFromValue('Activate Speed', self, True )
-               self.addFlowRate = settings.BooleanSetting().getFromValue('Add Flow Rate:', self, False )
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Bridge -', self )
-               self.bridgeFeedRateMultiplier = settings.FloatSpin().getFromValue( 0.8, 'Bridge Feed Rate Multiplier (ratio):', self, 1.2, 1.0 )
-               self.bridgeFlowRateMultiplier = settings.FloatSpin().getFromValue( 0.8, 'Bridge Flow Rate Multiplier (ratio):', self, 1.2, 1.0 )
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Duty Cyle -', self )
-               self.dutyCycleAtBeginning = settings.FloatSpin().getFromValue( 0.0, 'Duty Cyle at Beginning (portion):', self, 1.0, 1.0 )
-               self.dutyCycleAtEnding = settings.FloatSpin().getFromValue( 0.0, 'Duty Cyle at Ending (portion):', self, 1.0, 0.0 )
-               settings.LabelSeparator().getFromRepository(self)
-               self.feedRatePerSecond = settings.FloatSpin().getFromValue( 2.0, 'Feed Rate (mm/s):', self, 250.0, 50.0 )
-               self.flowRateSetting = settings.FloatSpin().getFromValue( 50.0, 'Flow Rate Setting (float):', self, 250.0, 50.0 )
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Object First Layers -', self)
-               self.objectFirstLayerFeedRateInfillMultiplier = settings.FloatSpin().getFromValue(
-                       0.2, 'Object First Layer Feed Rate Infill Multiplier (ratio):', self, 1.0, 0.4)
-               self.objectFirstLayerFeedRatePerimeterMultiplier = settings.FloatSpin().getFromValue(
-                       0.2, 'Object First Layer Feed Rate Perimeter Multiplier (ratio):', self, 1.0, 0.4)
-               self.objectFirstLayerFeedRateTravelMultiplier = settings.FloatSpin().getFromValue(
-                       0.2, 'Object First Layer Feed Rate Travel Multiplier (ratio):', self, 1.0, 0.4)
-               self.objectFirstLayerFlowRateInfillMultiplier = settings.FloatSpin().getFromValue(
-                       0.2, 'Object First Layer Flow Rate Infill Multiplier (ratio):', self, 1.0, 0.4)
-               self.objectFirstLayerFlowRatePerimeterMultiplier = settings.FloatSpin().getFromValue(
-                       0.2, 'Object First Layer Flow Rate Perimeter Multiplier (ratio):', self, 1.0, 0.4)
-               self.objectFirstLayersLayerAmount = settings.IntSpin().getFromValue(
-                       1, 'Object First Layers Amount Of Layers For Speed Change:', self, 10, 3)
-               settings.LabelSeparator().getFromRepository(self)
-               self.orbitalFeedRateOverOperatingFeedRate = settings.FloatSpin().getFromValue( 0.1, 'Orbital Feed Rate over Operating Feed Rate (ratio):', self, 0.9, 0.5 )
-               self.maximumZFeedRatePerSecond = settings.FloatSpin().getFromValue(0.5, 'Maximum Z Feed Rate (mm/s):', self, 10.0, 1.0)
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Perimeter -', self )
-               self.perimeterFeedRateMultiplier = settings.FloatSpin().getFromValue(0.5, 'Perimeter Feed Rate Multiplier (ratio):', self, 1.0, 1.0)
-               self.perimeterFlowRateMultiplier = settings.FloatSpin().getFromValue(0.5, 'Perimeter Flow Rate Multiplier (ratio):', self, 1.0, 1.0)
-               settings.LabelSeparator().getFromRepository(self)
-               self.travelFeedRatePerSecond = settings.FloatSpin().getFromValue( 2.0, 'Travel Feed Rate (mm/s):', self, 350.0, 250.0 )
-               self.executeTitle = 'Speed'
-               
-               self.bottomLayerFlowRateMultiplier = settings.FloatSpin().getFromValue(0.0, 'Bottom layer flow rate (ratio):', self, 10.0, 1.0)
-
-       def execute(self):
-               "Speed button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class SpeedSkein(object):
-       "A class to speed a skein of extrusions."
-       def __init__(self):
-               'Initialize.'
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.feedRatePerSecond = 16.0
-               self.isBridgeLayer = False
-               self.isEdgePath = False
-               self.isExtruderActive = False
-               self.layerIndex = -1
-               self.lineIndex = 0
-               self.lines = None
-               self.oldFlowRate = None
-
-       def addFlowRateLine(self):
-               "Add flow rate line."
-               if not self.repository.addFlowRate.value:
-                       return
-               flowRate = self.repository.flowRateSetting.value
-               if self.isBridgeLayer:
-                       flowRate *= self.repository.bridgeFlowRateMultiplier.value
-               if self.isEdgePath:
-                       flowRate *= self.repository.perimeterFlowRateMultiplier.value
-               if self.layerIndex < self.repository.objectFirstLayersLayerAmount.value:
-                       if self.isEdgePath:
-                               flowRate *= ((self.repository.objectFirstLayerFlowRatePerimeterMultiplier.value * (self.repository.objectFirstLayersLayerAmount.value - self.layerIndex)) + self.layerIndex) / self.repository.objectFirstLayersLayerAmount.value
-                       else:
-                               flowRate *= ((self.repository.objectFirstLayerFlowRateInfillMultiplier.value * (self.repository.objectFirstLayersLayerAmount.value - self.layerIndex)) + self.layerIndex) / self.repository.objectFirstLayersLayerAmount.value
-               if self.layerIndex == 0:
-                       flowRate *= self.repository.bottomLayerFlowRateMultiplier.value
-               if flowRate != self.oldFlowRate:
-                       self.distanceFeedRate.addLine('M108 S' + euclidean.getFourSignificantFigures(flowRate))
-               self.oldFlowRate = flowRate
-
-       def addParameterString( self, firstWord, parameterWord ):
-               "Add parameter string."
-               if parameterWord == '':
-                       self.distanceFeedRate.addLine(firstWord)
-                       return
-               self.distanceFeedRate.addParameter( firstWord, parameterWord )
-
-       def getCraftedGcode(self, gcodeText, repository):
-               "Parse gcode text and store the speed gcode."
-               self.repository = repository
-               self.feedRatePerSecond = repository.feedRatePerSecond.value
-               self.travelFeedRateMinute = 60.0 * self.repository.travelFeedRatePerSecond.value
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization()
-               for line in self.lines[self.lineIndex :]:
-                       self.parseLine(line)
-               self.addParameterString('M113', self.repository.dutyCycleAtEnding.value ) # Set duty cycle .
-               return self.distanceFeedRate.output.getvalue()
-
-       def getSpeededLine(self, line, splitLine):
-               'Get gcode line with feed rate.'
-               if gcodec.getIndexOfStartingWithSecond('F', splitLine) > 0:
-                       return line
-               feedRateMinute = 60.0 * self.feedRatePerSecond
-               if self.isBridgeLayer:
-                       feedRateMinute *= self.repository.bridgeFeedRateMultiplier.value
-               if self.isEdgePath:
-                       feedRateMinute *= self.repository.perimeterFeedRateMultiplier.value
-               if self.layerIndex < self.repository.objectFirstLayersLayerAmount.value:
-                       if self.isEdgePath:
-                               feedRateMinute *= ((self.repository.objectFirstLayerFeedRatePerimeterMultiplier.value * (self.repository.objectFirstLayersLayerAmount.value - self.layerIndex)) + self.layerIndex) / self.repository.objectFirstLayersLayerAmount.value
-                       else:
-                               feedRateMinute *= ((self.repository.objectFirstLayerFeedRateInfillMultiplier.value * (self.repository.objectFirstLayersLayerAmount.value - self.layerIndex)) + self.layerIndex) / self.repository.objectFirstLayersLayerAmount.value
-               self.addFlowRateLine()
-               if not self.isExtruderActive:
-                       feedRateMinute = self.travelFeedRateMinute
-                       if self.layerIndex < self.repository.objectFirstLayersLayerAmount.value:
-                               feedRateMinute *= ((self.repository.objectFirstLayerFeedRateTravelMultiplier.value * (self.repository.objectFirstLayersLayerAmount.value - self.layerIndex)) + self.layerIndex) / self.repository.objectFirstLayersLayerAmount.value
-               return self.distanceFeedRate.getLineWithFeedRate(feedRateMinute, line, splitLine)
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(<layerHeight>':
-                               self.layerHeight = float(splitLine[1])
-                       elif firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('speed')
-                               return
-                       elif firstWord == '(<edgeWidth>':
-                               self.absoluteEdgeWidth = abs(float(splitLine[1]))
-                               self.distanceFeedRate.addTagBracketedLine('maximumZFeedRatePerSecond', self.repository.maximumZFeedRatePerSecond.value )
-                               self.distanceFeedRate.addTagBracketedLine('objectFirstLayerFeedRateInfillMultiplier', self.repository.objectFirstLayerFeedRateInfillMultiplier.value)
-                               self.distanceFeedRate.addTagBracketedLine('operatingFeedRatePerSecond', self.feedRatePerSecond )
-                               if self.repository.addFlowRate.value:
-                                       self.distanceFeedRate.addTagBracketedLine('objectFirstLayerFlowRateInfillMultiplier', self.repository.objectFirstLayerFlowRateInfillMultiplier.value * self.repository.bottomLayerFlowRateMultiplier.value)
-                                       self.distanceFeedRate.addTagBracketedLine('operatingFlowRate', self.repository.flowRateSetting.value )
-                               orbitalFeedRatePerSecond = self.feedRatePerSecond * self.repository.orbitalFeedRateOverOperatingFeedRate.value
-                               self.distanceFeedRate.addTagBracketedLine('orbitalFeedRatePerSecond', orbitalFeedRatePerSecond )
-                               self.distanceFeedRate.addTagBracketedLine('travelFeedRatePerSecond', self.repository.travelFeedRatePerSecond.value )
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               "Parse a gcode line and add it to the speed skein."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == '(<crafting>)':
-                       self.distanceFeedRate.addLine(line)
-                       self.addParameterString('M113', self.repository.dutyCycleAtBeginning.value ) # Set duty cycle .
-                       return
-               elif firstWord == 'G1':
-                       line = self.getSpeededLine(line, splitLine)
-               elif firstWord == 'M101':
-                       self.isExtruderActive = True
-               elif firstWord == 'M103':
-                       self.isExtruderActive = False
-               elif firstWord == '(<bridgeRotation>':
-                       self.isBridgeLayer = True
-               elif firstWord == '(<layer>':
-                       self.layerIndex += 1
-                       settings.printProgress(self.layerIndex, 'speed')
-                       self.isBridgeLayer = False
-                       self.addFlowRateLine()
-               elif firstWord == '(<edge>' or firstWord == '(<edgePath>)':
-                       self.isEdgePath = True
-               elif firstWord == '(</edge>)' or firstWord == '(</edgePath>)':
-                       self.isEdgePath = False
-               self.distanceFeedRate.addLine(line)
-
-
-def main():
-       "Display the speed dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/splodge.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/splodge.py
deleted file mode 100644 (file)
index bef836f..0000000
+++ /dev/null
@@ -1,324 +0,0 @@
-"""
-This page is in the table of contents.
-Splodge turns the extruder on just before the start of a thread.  This is to give the extrusion a bit anchoring at the beginning.
-
-The splodge manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Splodge
-
-==Operation==
-The default 'Activate Splodge' checkbox is on.  When it is on, the functions described below will work, when it is off, the functions will not be called.
-
-==Settings==
-===Initial===
-====Initial Lift over Extra Thickness====
-Default is one.
-
-Defines the amount the extruder will be lifted over the extra thickness of the initial splodge thread.  The higher the ratio, the more the extruder will be lifted over the splodge, if the ratio is too low the extruder might plow through the splodge extrusion.
-
-====Initial Splodge Feed Rate====
-Default is one millimeter per second.
-
-Defines the feed rate at which the initial extra extrusion will be added.  With the default feed rate, the splodge will be added slower so it will be thicker than the regular extrusion.
-
-====Initial Splodge Quantity Length====
-Default is thirty millimeters.
-
-Defines the quantity length of extra extrusion at the operating feed rate that will be added to the initial thread.  If a splodge quantity length is smaller than 0.1 times the edge width, no splodge of that type will be added.
-
-===Operating===
-====Operating Lift over Extra Thickness====
-Default is one.
-
-Defines the amount the extruder will be lifted over the extra thickness of the operating splodge thread.
-
-====Operating Splodge Feed Rate====
-Default is one millimeter per second.
-
-Defines the feed rate at which the next extra extrusions will be added.
-
-====Operating Splodge Quantity Length====
-Default is thirty millimeters.
-
-Defines the quantity length of extra extrusion at the operating feed rate that will be added for the next threads.
-
-==Examples==
-The following examples splodge the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and splodge.py.
-
-> python splodge.py
-This brings up the splodge dialog.
-
-> python splodge.py Screw Holder Bottom.stl
-The splodge tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The splodge tool has created the file:
-.. Screw Holder Bottom_splodge.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import math
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, text, splodgeRepository = None ):
-       "Splodge a gcode linear move file or text."
-       return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), splodgeRepository )
-
-def getCraftedTextFromText( gcodeText, splodgeRepository = None ):
-       "Splodge a gcode linear move text."
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'splodge'):
-               return gcodeText
-       if splodgeRepository == None:
-               splodgeRepository = settings.getReadRepository( SplodgeRepository() )
-       if not splodgeRepository.activateSplodge.value:
-               return gcodeText
-       return SplodgeSkein().getCraftedGcode( gcodeText, splodgeRepository )
-
-def getNewRepository():
-       'Get new repository.'
-       return SplodgeRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Splodge a gcode linear move file."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'splodge', shouldAnalyze)
-
-
-class SplodgeRepository(object):
-       "A class to handle the splodge settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.splodge.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Splodge', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Splodge')
-               self.activateSplodge = settings.BooleanSetting().getFromValue('Activate Splodge', self, False )
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Initial -', self )
-               self.initialLiftOverExtraThickness = settings.FloatSpin().getFromValue( 0.5, 'Initial Lift over Extra Thickness (ratio):', self, 1.5, 1.0 )
-               self.initialSplodgeFeedRate = settings.FloatSpin().getFromValue( 0.4, 'Initial Splodge Feed Rate (mm/s):', self, 2.4, 1.0 )
-               self.initialSplodgeQuantityLength = settings.FloatSpin().getFromValue( 10.0, 'Initial Splodge Quantity Length (millimeters):', self, 90.0, 30.0 )
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Operating -', self )
-               self.operatingLiftOverExtraThickness = settings.FloatSpin().getFromValue( 0.5, 'Operating Lift over Extra Thickness (ratio):', self, 1.5, 1.0 )
-               self.operatingSplodgeFeedRate = settings.FloatSpin().getFromValue( 0.4, 'Operating Splodge Feed Rate (mm/s):', self, 2.4, 1.0 )
-               self.operatingSplodgeQuantityLength = settings.FloatSpin().getFromValue(0.4, 'Operating Splodge Quantity Length (millimeters):', self, 2.4, 1.0)
-               settings.LabelSeparator().getFromRepository(self)
-               self.executeTitle = 'Splodge'
-
-       def execute(self):
-               "Splodge button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class SplodgeSkein(object):
-       "A class to splodge a skein of extrusions."
-       def __init__(self):
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.feedRateMinute = 961.0
-               self.isExtruderActive = False
-               self.hasInitialSplodgeBeenAdded = False
-               self.isLastExtruderCommandActivate = False
-               self.lastLineOutput = None
-               self.lineIndex = 0
-               self.lines = None
-               self.oldLocation = None
-               self.operatingFeedRatePerSecond = 15.0
-
-       def addLineUnlessIdentical(self, line):
-               "Add a line, unless it is identical to the last line."
-               if line == self.lastLineOutput:
-                       return
-               self.lastLineOutput = line
-               self.distanceFeedRate.addLine(line)
-
-       def addLineUnlessIdenticalReactivate(self, line):
-               "Add a line, unless it is identical to the last line or another M101."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'M101':
-                       if not self.isLastExtruderCommandActivate:
-                               self.addLineUnlessIdentical(line)
-                               self.isLastExtruderCommandActivate = True
-                       return
-               if firstWord == 'M103':
-                       self.isLastExtruderCommandActivate = False
-               self.addLineUnlessIdentical(line)
-
-       def getCraftedGcode( self, gcodeText, splodgeRepository ):
-               "Parse gcode text and store the splodge gcode."
-               self.lines = archive.getTextLines(gcodeText)
-               self.setRotations()
-               self.splodgeRepository = splodgeRepository
-               self.parseInitialization( splodgeRepository )
-               self.boundingRectangle = gcodec.BoundingRectangle().getFromGcodeLines( self.lines[self.lineIndex :], 0.5 * self.edgeWidth )
-               self.initialSplodgeFeedRateMinute = 60.0 * splodgeRepository.initialSplodgeFeedRate.value
-               self.initialStartupDistance = splodgeRepository.initialSplodgeQuantityLength.value * splodgeRepository.initialSplodgeFeedRate.value / self.operatingFeedRatePerSecond
-               self.operatingSplodgeFeedRateMinute = 60.0 * splodgeRepository.operatingSplodgeFeedRate.value
-               self.operatingStartupDistance = splodgeRepository.operatingSplodgeQuantityLength.value * splodgeRepository.operatingSplodgeFeedRate.value / self.operatingFeedRatePerSecond
-               for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def getInitialSplodgeLine( self, line, location ):
-               "Add the initial splodge line."
-               if not self.isJustBeforeExtrusion():
-                       return line
-               self.hasInitialSplodgeBeenAdded = True
-               if self.splodgeRepository.initialSplodgeQuantityLength.value < self.minimumQuantityLength:
-                       return line
-               return self.getSplodgeLineGivenDistance( self.initialSplodgeFeedRateMinute, line, self.splodgeRepository.initialLiftOverExtraThickness.value, location, self.initialStartupDistance )
-
-       def getNextActiveLocationComplex(self):
-               "Get the next active line."
-               isActive = False
-               for lineIndex in xrange( self.lineIndex + 1, len(self.lines) ):
-                       line = self.lines[lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'M101':
-                               isActive = True
-                       if firstWord == 'G1' and isActive:
-                               return gcodec.getLocationFromSplitLine(self.oldLocation, splitLine).dropAxis()
-               return None
-
-       def getOperatingSplodgeLine( self, line, location ):
-               "Get the operating splodge line."
-               if not self.isJustBeforeExtrusion():
-                       return line
-               if self.splodgeRepository.operatingSplodgeQuantityLength.value < self.minimumQuantityLength:
-                       return line
-               return self.getSplodgeLineGivenDistance( self.operatingSplodgeFeedRateMinute, line, self.splodgeRepository.operatingLiftOverExtraThickness.value, location, self.operatingStartupDistance )
-
-       def getSplodgeLine(self, line, location, splitLine):
-               "Get splodged gcode line."
-               self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine)
-               if self.hasInitialSplodgeBeenAdded:
-                       return self.getOperatingSplodgeLine(line, location)
-               return self.getInitialSplodgeLine(line, location)
-
-       def getSplodgeLineGivenDistance( self, feedRateMinute, line, liftOverExtraThickness, location, startupDistance ):
-               "Add the splodge line."
-               locationComplex = location.dropAxis()
-               relativeStartComplex = None
-               nextLocationComplex = self.getNextActiveLocationComplex()
-               if nextLocationComplex != None:
-                       if nextLocationComplex != locationComplex:
-                               relativeStartComplex = locationComplex - nextLocationComplex
-               if relativeStartComplex == None:
-                       relativeStartComplex = complex( 19.9, 9.9 )
-                       if self.oldLocation != None:
-                               oldLocationComplex = self.oldLocation.dropAxis()
-                               if oldLocationComplex != locationComplex:
-                                       relativeStartComplex = oldLocationComplex - locationComplex
-               relativeStartComplex *= startupDistance / abs( relativeStartComplex )
-               startComplex = self.getStartInsideBoundingRectangle( locationComplex, relativeStartComplex )
-               feedRateMultiplier = feedRateMinute / self.operatingFeedRatePerSecond / 60.0
-               splodgeLayerThickness = self.layerHeight / math.sqrt( feedRateMultiplier )
-               extraLayerThickness = splodgeLayerThickness - self.layerHeight
-               lift = extraLayerThickness * liftOverExtraThickness
-               startLine = self.distanceFeedRate.getLinearGcodeMovementWithFeedRate( self.feedRateMinute, startComplex, location.z + lift )
-               self.addLineUnlessIdenticalReactivate( startLine )
-               self.addLineUnlessIdenticalReactivate('M101')
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               lineLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               self.distanceFeedRate.addGcodeMovementZWithFeedRate( feedRateMinute, locationComplex, lineLocation.z + lift )
-               return ''
-
-       def getStartInsideBoundingRectangle( self, locationComplex, relativeStartComplex ):
-               "Get a start inside the bounding rectangle."
-               startComplex = locationComplex + relativeStartComplex
-               if self.boundingRectangle.isPointInside( startComplex ):
-                       return startComplex
-               for rotation in self.rotations:
-                       rotatedRelativeStartComplex = relativeStartComplex * rotation
-                       startComplex = locationComplex + rotatedRelativeStartComplex
-                       if self.boundingRectangle.isPointInside( startComplex ):
-                               return startComplex
-               return startComplex
-
-       def isJustBeforeExtrusion(self):
-               "Determine if activate command is before linear move command."
-               for lineIndex in xrange(self.lineIndex + 1, len(self.lines)):
-                       line = self.lines[lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1' or firstWord == 'M103':
-                               return False
-                       if firstWord == 'M101':
-                               return True
-               return False
-
-       def parseInitialization( self, splodgeRepository ):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.addLineUnlessIdenticalReactivate(gcodec.getTagBracketedProcedure('splodge'))
-                               return
-                       elif firstWord == '(<layerHeight>':
-                               self.layerHeight = float(splitLine[1])
-                       elif firstWord == '(<operatingFeedRatePerSecond>':
-                               self.operatingFeedRatePerSecond = float(splitLine[1])
-                       elif firstWord == '(<edgeWidth>':
-                               self.edgeWidth = float(splitLine[1])
-                               self.minimumQuantityLength = 0.1 * self.edgeWidth
-                       self.addLineUnlessIdenticalReactivate(line)
-
-       def parseLine(self, line):
-               "Parse a gcode line and add it to the bevel gcode."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-                       line = self.getSplodgeLine(line, location, splitLine)
-                       self.oldLocation = location
-               elif firstWord == 'M101':
-                       self.isExtruderActive = True
-               elif firstWord == 'M103':
-                       self.isExtruderActive = False
-               self.addLineUnlessIdenticalReactivate(line)
-
-       def setRotations(self):
-               "Set the rotations."
-               self.rootHalf = math.sqrt( 0.5 )
-               self.rotations = []
-               self.rotations.append( complex( self.rootHalf, self.rootHalf ) )
-               self.rotations.append( complex( self.rootHalf, - self.rootHalf ) )
-               self.rotations.append( complex( 0.0, 1.0 ) )
-               self.rotations.append( complex(0.0, -1.0) )
-               self.rotations.append( complex( - self.rootHalf, self.rootHalf ) )
-               self.rotations.append( complex( - self.rootHalf, - self.rootHalf ) )
-
-
-def main():
-       "Display the splodge dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/stretch.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/stretch.py
deleted file mode 100644 (file)
index 0af481a..0000000
+++ /dev/null
@@ -1,423 +0,0 @@
-"""
-This page is in the table of contents.
-Stretch is very important Skeinforge plugin that allows you to partially compensate for the fact that extruded holes are smaller then they should be.  It stretches the threads to partially compensate for filament shrinkage when extruded.
-
-The stretch manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Stretch
-
-Extruded holes are smaller than the model because while printing an arc the head is depositing filament on both sides of the arc but in the inside of the arc you actually need less material then on the outside of the arc. You can read more about this on the RepRap ArcCompensation page:
-http://reprap.org/bin/view/Main/ArcCompensation
-
-In general, stretch will widen holes and push corners out.  In practice the filament contraction will not be identical to the algorithm, so even once the optimal parameters are determined, the stretch script will not be able to eliminate the inaccuracies caused by contraction, but it should reduce them.
-
-All the defaults assume that the thread sequence choice setting in fill is the edge being extruded first, then the loops, then the infill.  If the thread sequence choice is different, the optimal thread parameters will also be different.  In general, if the infill is extruded first, the infill would have to be stretched more so that even after the filament shrinkage, it would still be long enough to connect to the loop or edge.
-
-Holes should be made with the correct area for their radius.  In other words, for example if your modeling program approximates a hole of radius one (area = pi) by making a square with the points at [(1,0), (0,1), (-1,0), (0,-1)] (area = 2), the radius should be increased by sqrt(pi/2).  This can be done in fabmetheus xml by writing:
-radiusAreal='True'
-
-in the attributes of the object or any parent of that object.  In other modeling programs, you'll have to this manually or make a script.  If area compensation is not done, then changing the stretch parameters to over compensate for too small hole areas will lead to incorrect compensation in other shapes.
-
-==Operation==
-The default 'Activate Stretch' checkbox is off.  When it is on, the functions described below will work, when it is off, the functions will not be called.
-
-==Settings==
-===Loop Stretch Over Perimeter Width===
-Default is 0.1.
-
-Defines the ratio of the maximum amount the loop aka inner shell threads will be stretched compared to the edge width, in general this value should be the same as the 'Perimeter Outside Stretch Over Perimeter Width' setting.
-
-===Path Stretch Over Perimeter Width===
-Default is zero.
-
-Defines the ratio of the maximum amount the threads which are not loops, like the infill threads, will be stretched compared to the edge width.
-
-===Perimeter===
-====Perimeter Inside Stretch Over Perimeter Width====
-Default is 0.32.
-
-Defines the ratio of the maximum amount the inside edge thread will be stretched compared to the edge width, this is the most important setting in stretch.  The higher the value the more it will stretch the edge and the wider holes will be.  If the value is too small, the holes could be drilled out after fabrication, if the value is too high, the holes would be too wide and the part would have to junked.
-
-====Perimeter Outside Stretch Over Perimeter Width====
-Default is 0.1.
-
-Defines the ratio of the maximum amount the outside edge thread will be stretched compared to the edge width, in general this value should be around a third of the 'Perimeter Inside Stretch Over Perimeter Width' setting.
-
-===Stretch from Distance over Perimeter Width===
-Default is two.
-
-The stretch algorithm works by checking at each turning point on the extrusion path what the direction of the thread is at a distance of 'Stretch from Distance over Perimeter Width' times the edge width, on both sides, and moves the thread in the opposite direction.  So it takes the current turning-point, goes "Stretch from Distance over Perimeter Width" * "Perimeter Width" ahead, reads the direction at that point.  Then it goes the same distance in back in time, reads the direction at that other point.  It then moves the thread in the opposite direction, away from the center of the arc formed by these 2 points+directions.
-
-The magnitude of the stretch increases with:
-the amount that the direction of the two threads is similar and
-by the '..Stretch Over Perimeter Width' ratio.
-
-==Examples==
-The following examples stretch the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and stretch.py.
-
-> python stretch.py
-This brings up the stretch dialog.
-
-> python stretch.py Screw Holder Bottom.stl
-The stretch tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The stretch tool has created the file:
-.. Screw Holder Bottom_stretch.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-#maybe speed up feedRate option
-def getCraftedText( fileName, gcodeText, stretchRepository = None ):
-       "Stretch a gcode linear move text."
-       return getCraftedTextFromText( archive.getTextIfEmpty(fileName, gcodeText), stretchRepository )
-
-def getCraftedTextFromText( gcodeText, stretchRepository = None ):
-       "Stretch a gcode linear move text."
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'stretch'):
-               return gcodeText
-       if stretchRepository == None:
-               stretchRepository = settings.getReadRepository( StretchRepository() )
-       if not stretchRepository.activateStretch.value:
-               return gcodeText
-       return StretchSkein().getCraftedGcode( gcodeText, stretchRepository )
-
-def getNewRepository():
-       'Get new repository.'
-       return StretchRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Stretch a gcode linear move file.  Chain stretch the gcode if it is not already stretched."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'stretch', shouldAnalyze)
-
-
-class LineIteratorBackward(object):
-       "Backward line iterator class."
-       def __init__( self, isLoop, lineIndex, lines ):
-               self.firstLineIndex = None
-               self.isLoop = isLoop
-               self.lineIndex = lineIndex
-               self.lines = lines
-
-       def getIndexBeforeNextDeactivate(self):
-               "Get index two lines before the deactivate command."
-               for lineIndex in xrange( self.lineIndex + 1, len(self.lines) ):
-                       line = self.lines[lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'M103':
-                               return lineIndex - 2
-               print('This should never happen in stretch, no deactivate command was found for this thread.')
-               raise StopIteration, "You've reached the end of the line."
-
-       def getNext(self):
-               "Get next line going backward or raise exception."
-               while self.lineIndex > 3:
-                       if self.lineIndex == self.firstLineIndex:
-                               raise StopIteration, "You've reached the end of the line."
-                       if self.firstLineIndex == None:
-                               self.firstLineIndex = self.lineIndex
-                       nextLineIndex = self.lineIndex - 1
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'M103':
-                               if self.isLoop:
-                                       nextLineIndex = self.getIndexBeforeNextDeactivate()
-                               else:
-                                       raise StopIteration, "You've reached the end of the line."
-                       if firstWord == 'G1':
-                               if self.isBeforeExtrusion():
-                                       if self.isLoop:
-                                               nextLineIndex = self.getIndexBeforeNextDeactivate()
-                                       else:
-                                               raise StopIteration, "You've reached the end of the line."
-                               else:
-                                       self.lineIndex = nextLineIndex
-                                       return line
-                       self.lineIndex = nextLineIndex
-               raise StopIteration, "You've reached the end of the line."
-
-       def isBeforeExtrusion(self):
-               "Determine if index is two or more before activate command."
-               linearMoves = 0
-               for lineIndex in xrange( self.lineIndex + 1, len(self.lines) ):
-                       line = self.lines[lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1':
-                               linearMoves += 1
-                       if firstWord == 'M101':
-                               return linearMoves > 0
-                       if firstWord == 'M103':
-                               return False
-               print('This should never happen in isBeforeExtrusion in stretch, no activate command was found for this thread.')
-               return False
-
-
-class LineIteratorForward(object):
-       "Forward line iterator class."
-       def __init__( self, isLoop, lineIndex, lines ):
-               self.firstLineIndex = None
-               self.isLoop = isLoop
-               self.lineIndex = lineIndex
-               self.lines = lines
-
-       def getIndexJustAfterActivate(self):
-               "Get index just after the activate command."
-               for lineIndex in xrange( self.lineIndex - 1, 3, - 1 ):
-                       line = self.lines[lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'M101':
-                               return lineIndex + 1
-               print('This should never happen in stretch, no activate command was found for this thread.')
-               raise StopIteration, "You've reached the end of the line."
-
-       def getNext(self):
-               "Get next line or raise exception."
-               while self.lineIndex < len(self.lines):
-                       if self.lineIndex == self.firstLineIndex:
-                               raise StopIteration, "You've reached the end of the line."
-                       if self.firstLineIndex == None:
-                               self.firstLineIndex = self.lineIndex
-                       nextLineIndex = self.lineIndex + 1
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'M103':
-                               if self.isLoop:
-                                       nextLineIndex = self.getIndexJustAfterActivate()
-                               else:
-                                       raise StopIteration, "You've reached the end of the line."
-                       self.lineIndex = nextLineIndex
-                       if firstWord == 'G1':
-                               return line
-               raise StopIteration, "You've reached the end of the line."
-
-
-class StretchRepository(object):
-       "A class to handle the stretch settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.stretch.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Stretch', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Stretch')
-               self.activateStretch = settings.BooleanSetting().getFromValue('Activate Stretch', self, False )
-               self.crossLimitDistanceOverEdgeWidth = settings.FloatSpin().getFromValue( 3.0, 'Cross Limit Distance Over Perimeter Width (ratio):', self, 10.0, 5.0 )
-               self.loopStretchOverEdgeWidth = settings.FloatSpin().getFromValue( 0.05, 'Loop Stretch Over Perimeter Width (ratio):', self, 0.25, 0.11 )
-               self.pathStretchOverEdgeWidth = settings.FloatSpin().getFromValue( 0.0, 'Path Stretch Over Perimeter Width (ratio):', self, 0.2, 0.0 )
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Perimeter -', self )
-               self.edgeInsideStretchOverEdgeWidth = settings.FloatSpin().getFromValue( 0.12, 'Perimeter Inside Stretch Over Perimeter Width (ratio):', self, 0.52, 0.32 )
-               self.edgeOutsideStretchOverEdgeWidth = settings.FloatSpin().getFromValue( 0.05, 'Perimeter Outside Stretch Over Perimeter Width (ratio):', self, 0.25, 0.1 )
-               settings.LabelSeparator().getFromRepository(self)
-               self.stretchFromDistanceOverEdgeWidth = settings.FloatSpin().getFromValue( 1.0, 'Stretch From Distance Over Perimeter Width (ratio):', self, 3.0, 2.0 )
-               self.executeTitle = 'Stretch'
-
-       def execute(self):
-               "Stretch button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class StretchSkein(object):
-       "A class to stretch a skein of extrusions."
-       def __init__(self):
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.edgeWidth = 0.4
-               self.extruderActive = False
-               self.feedRateMinute = 959.0
-               self.isLoop = False
-               self.layerCount = settings.LayerCount()
-               self.lineIndex = 0
-               self.lines = None
-               self.oldLocation = None
-
-       def getCraftedGcode( self, gcodeText, stretchRepository ):
-               "Parse gcode text and store the stretch gcode."
-               self.lines = archive.getTextLines(gcodeText)
-               self.stretchRepository = stretchRepository
-               self.parseInitialization()
-               for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       self.parseStretch(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def getCrossLimitedStretch( self, crossLimitedStretch, crossLineIterator, locationComplex ):
-               "Get cross limited relative stretch for a location."
-               try:
-                       line = crossLineIterator.getNext()
-               except StopIteration:
-                       return crossLimitedStretch
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               pointComplex = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine).dropAxis()
-               pointMinusLocation = locationComplex - pointComplex
-               pointMinusLocationLength = abs( pointMinusLocation )
-               if pointMinusLocationLength <= self.crossLimitDistanceFraction:
-                       return crossLimitedStretch
-               parallelNormal = pointMinusLocation / pointMinusLocationLength
-               parallelStretch = euclidean.getDotProduct( parallelNormal, crossLimitedStretch ) * parallelNormal
-               if pointMinusLocationLength > self.crossLimitDistance:
-                       return parallelStretch
-               crossNormal = complex( parallelNormal.imag, - parallelNormal.real )
-               crossStretch = euclidean.getDotProduct( crossNormal, crossLimitedStretch ) * crossNormal
-               crossPortion = ( self.crossLimitDistance - pointMinusLocationLength ) / self.crossLimitDistanceRemainder
-               return parallelStretch + crossStretch * crossPortion
-
-       def getRelativeStretch( self, locationComplex, lineIterator ):
-               "Get relative stretch for a location."
-               lastLocationComplex = locationComplex
-               oldTotalLength = 0.0
-               pointComplex = locationComplex
-               totalLength = 0.0
-               while 1:
-                       try:
-                               line = lineIterator.getNext()
-                       except StopIteration:
-                               locationMinusPoint = locationComplex - pointComplex
-                               locationMinusPointLength = abs( locationMinusPoint )
-                               if locationMinusPointLength > 0.0:
-                                       return locationMinusPoint / locationMinusPointLength
-                               return complex()
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = splitLine[0]
-                       pointComplex = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine).dropAxis()
-                       locationMinusPoint = lastLocationComplex - pointComplex
-                       locationMinusPointLength = abs( locationMinusPoint )
-                       totalLength += locationMinusPointLength
-                       if totalLength >= self.stretchFromDistance:
-                               distanceFromRatio = ( self.stretchFromDistance - oldTotalLength ) / locationMinusPointLength
-                               totalPoint = distanceFromRatio * pointComplex + ( 1.0 - distanceFromRatio ) * lastLocationComplex
-                               locationMinusTotalPoint = locationComplex - totalPoint
-                               return locationMinusTotalPoint / self.stretchFromDistance
-                       lastLocationComplex = pointComplex
-                       oldTotalLength = totalLength
-
-       def getStretchedLine( self, splitLine ):
-               "Get stretched gcode line."
-               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               self.feedRateMinute = gcodec.getFeedRateMinute( self.feedRateMinute, splitLine )
-               self.oldLocation = location
-               if self.extruderActive and self.threadMaximumAbsoluteStretch > 0.0:
-                       return self.getStretchedLineFromIndexLocation( self.lineIndex - 1, self.lineIndex + 1, location )
-               if self.isJustBeforeExtrusion() and self.threadMaximumAbsoluteStretch > 0.0:
-                       return self.getStretchedLineFromIndexLocation( self.lineIndex - 1, self.lineIndex + 1, location )
-               return self.lines[self.lineIndex]
-
-       def getStretchedLineFromIndexLocation( self, indexPreviousStart, indexNextStart, location ):
-               "Get stretched gcode line from line index and location."
-               crossIteratorForward = LineIteratorForward( self.isLoop, indexNextStart, self.lines )
-               crossIteratorBackward = LineIteratorBackward( self.isLoop, indexPreviousStart, self.lines )
-               iteratorForward = LineIteratorForward( self.isLoop, indexNextStart, self.lines )
-               iteratorBackward = LineIteratorBackward( self.isLoop, indexPreviousStart, self.lines )
-               locationComplex = location.dropAxis()
-               relativeStretch = self.getRelativeStretch( locationComplex, iteratorForward ) + self.getRelativeStretch( locationComplex, iteratorBackward )
-               relativeStretch *= 0.8
-               relativeStretch = self.getCrossLimitedStretch( relativeStretch, crossIteratorForward, locationComplex )
-               relativeStretch = self.getCrossLimitedStretch( relativeStretch, crossIteratorBackward, locationComplex )
-               relativeStretchLength = abs( relativeStretch )
-               if relativeStretchLength > 1.0:
-                       relativeStretch /= relativeStretchLength
-               absoluteStretch = relativeStretch * self.threadMaximumAbsoluteStretch
-               stretchedPoint = location.dropAxis() + absoluteStretch
-               return self.distanceFeedRate.getLinearGcodeMovementWithFeedRate( self.feedRateMinute, stretchedPoint, location.z )
-
-       def isJustBeforeExtrusion(self):
-               "Determine if activate command is before linear move command."
-               for lineIndex in xrange( self.lineIndex + 1, len(self.lines) ):
-                       line = self.lines[lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1' or firstWord == 'M103':
-                               return False
-                       if firstWord == 'M101':
-                               return True
-#              print('This should never happen in isJustBeforeExtrusion in stretch, no activate or deactivate command was found for this thread.')
-               return False
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('stretch')
-                               return
-                       elif firstWord == '(<edgeWidth>':
-                               edgeWidth = float(splitLine[1])
-                               self.crossLimitDistance = self.edgeWidth * self.stretchRepository.crossLimitDistanceOverEdgeWidth.value
-                               self.loopMaximumAbsoluteStretch = self.edgeWidth * self.stretchRepository.loopStretchOverEdgeWidth.value
-                               self.pathAbsoluteStretch = self.edgeWidth * self.stretchRepository.pathStretchOverEdgeWidth.value
-                               self.edgeInsideAbsoluteStretch = self.edgeWidth * self.stretchRepository.edgeInsideStretchOverEdgeWidth.value
-                               self.edgeOutsideAbsoluteStretch = self.edgeWidth * self.stretchRepository.edgeOutsideStretchOverEdgeWidth.value
-                               self.stretchFromDistance = self.stretchRepository.stretchFromDistanceOverEdgeWidth.value * edgeWidth
-                               self.threadMaximumAbsoluteStretch = self.pathAbsoluteStretch
-                               self.crossLimitDistanceFraction = 0.333333333 * self.crossLimitDistance
-                               self.crossLimitDistanceRemainder = self.crossLimitDistance - self.crossLimitDistanceFraction
-                       self.distanceFeedRate.addLine(line)
-
-       def parseStretch(self, line):
-               "Parse a gcode line and add it to the stretch skein."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       line = self.getStretchedLine(splitLine)
-               elif firstWord == 'M101':
-                       self.extruderActive = True
-               elif firstWord == 'M103':
-                       self.extruderActive = False
-                       self.setStretchToPath()
-               elif firstWord == '(<layer>':
-                       self.layerCount.printProgressIncrement('stretch')
-               elif firstWord == '(<loop>':
-                       self.isLoop = True
-                       self.threadMaximumAbsoluteStretch = self.loopMaximumAbsoluteStretch
-               elif firstWord == '(</loop>)':
-                       self.setStretchToPath()
-               elif firstWord == '(<edge>':
-                       self.isLoop = True
-                       self.threadMaximumAbsoluteStretch = self.edgeInsideAbsoluteStretch
-                       if splitLine[1] == 'outer':
-                               self.threadMaximumAbsoluteStretch = self.edgeOutsideAbsoluteStretch
-               elif firstWord == '(</edge>)':
-                       self.setStretchToPath()
-               self.distanceFeedRate.addLine(line)
-
-       def setStretchToPath(self):
-               "Set the thread stretch to path stretch and is loop false."
-               self.isLoop = False
-               self.threadMaximumAbsoluteStretch = self.pathAbsoluteStretch
-
-
-def main():
-       "Display the stretch dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/temperature.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/temperature.py
deleted file mode 100644 (file)
index 4282c24..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-"""
-This page is in the table of contents.
-Temperature is a plugin to set the temperature for the entire extrusion.
-
-The temperature manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Temperature
-
-==Operation==
-The default 'Activate Temperature' checkbox is on.  When it is on, the functions described below will work, when it is off, nothing will be done.
-
-==Settings==
-===Rate===
-The default cooling rate and heating rate for the extruder were both been derived from bothacker's graph at:
-http://bothacker.com/wp-content/uploads/2009/09/18h5m53s9.29.2009.png
-
-====Cooling Rate====
-Default is three degrees Celcius per second.
-
-Defines the cooling rate of the extruder.
-
-====Heating Rate====
-Default is ten degrees Celcius per second.
-
-Defines the heating rate of the extruder.
-
-===Temperature===
-====Base Temperature====
-Default for ABS is two hundred degrees Celcius.
-
-Defines the raft base temperature.
-
-====Interface Temperature====
-Default for ABS is two hundred degrees Celcius.
-
-Defines the raft interface temperature.
-
-====Object First Layer Infill Temperature====
-Default for ABS is 195 degrees Celcius.
-
-Defines the infill temperature of the first layer of the object.
-
-====Object First Layer Perimeter Temperature====
-Default for ABS is two hundred and twenty degrees Celcius.
-
-Defines the edge temperature of the first layer of the object.
-
-====Object Next Layers Temperature====
-Default for ABS is two hundred and thirty degrees Celcius.
-
-Defines the temperature of the next layers of the object.
-
-====Support Layers Temperature====
-Default for ABS is two hundred degrees Celcius.
-
-Defines the support layers temperature.
-
-====Supported Layers Temperature====
-Default for ABS is two hundred and thirty degrees Celcius.
-
-Defines the temperature of the supported layers of the object, those layers which are right above a support layer.
-
-==Examples==
-The following examples add temperature information to the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and temperature.py.
-
-> python temperature.py
-This brings up the temperature dialog.
-
-> python temperature.py Screw Holder Bottom.stl
-The temperature tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The temperature tool has created the file:
-.. Screw Holder Bottom_temperature.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, text='', repository=None):
-       "Temperature the file or text."
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository)
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       "Temperature a gcode linear move text."
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'temperature'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository( TemperatureRepository() )
-       if not repository.activateTemperature.value:
-               return gcodeText
-       return TemperatureSkein().getCraftedGcode(gcodeText, repository)
-
-def getNewRepository():
-       'Get new repository.'
-       return TemperatureRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Temperature a gcode linear move file."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'temperature', shouldAnalyze)
-
-
-class TemperatureRepository(object):
-       "A class to handle the temperature settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.temperature.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Temperature', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Temperature')
-               self.activateTemperature = settings.BooleanSetting().getFromValue('Activate Temperature', self, False )
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Rate -', self )
-               self.coolingRate = settings.FloatSpin().getFromValue( 1.0, 'Cooling Rate (Celcius/second):', self, 20.0, 3.0 )
-               self.heatingRate = settings.FloatSpin().getFromValue( 1.0, 'Heating Rate (Celcius/second):', self, 20.0, 10.0 )
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Temperature -', self )
-               self.baseTemperature = settings.FloatSpin().getFromValue( 140.0, 'Base Temperature (Celcius):', self, 260.0, 200.0 )
-               self.interfaceTemperature = settings.FloatSpin().getFromValue( 140.0, 'Interface Temperature (Celcius):', self, 260.0, 200.0 )
-               self.objectFirstLayerInfillTemperature = settings.FloatSpin().getFromValue( 140.0, 'Object First Layer Infill Temperature (Celcius):', self, 260.0, 195.0 )
-               self.objectFirstLayerPerimeterTemperature = settings.FloatSpin().getFromValue( 140.0, 'Object First Layer Perimeter Temperature (Celcius):', self, 260.0, 220.0 )
-               self.objectNextLayersTemperature = settings.FloatSpin().getFromValue( 140.0, 'Object Next Layers Temperature (Celcius):', self, 260.0, 230.0 )
-               self.supportLayersTemperature = settings.FloatSpin().getFromValue( 140.0, 'Support Layers Temperature (Celcius):', self, 260.0, 200.0 )
-               self.supportedLayersTemperature = settings.FloatSpin().getFromValue( 140.0, 'Supported Layers Temperature (Celcius):', self, 260.0, 230.0 )
-               self.executeTitle = 'Temperature'
-
-       def execute(self):
-               "Temperature button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class TemperatureSkein(object):
-       "A class to temperature a skein of extrusions."
-       def __init__(self):
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.lineIndex = 0
-               self.lines = None
-
-       def getCraftedGcode(self, gcodeText, repository):
-               "Parse gcode text and store the temperature gcode."
-               self.repository = repository
-               self.lines = archive.getTextLines(gcodeText)
-               if self.repository.coolingRate.value < 0.1:
-                       print('The cooling rate should be more than 0.1, any cooling rate less than 0.1 will be treated as 0.1.')
-                       self.repository.coolingRate.value = 0.1
-               if self.repository.heatingRate.value < 0.1:
-                       print('The heating rate should be more than 0.1, any heating rate less than 0.1 will be treated as 0.1.')
-                       self.repository.heatingRate.value = 0.1
-               self.parseInitialization()
-               self.distanceFeedRate.addLines( self.lines[self.lineIndex :] )
-               return self.distanceFeedRate.output.getvalue()
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('temperature')
-                               return
-                       elif firstWord == '(<edgeWidth>':
-                               self.distanceFeedRate.addTagBracketedLine('coolingRate', self.repository.coolingRate.value )
-                               self.distanceFeedRate.addTagBracketedLine('heatingRate', self.repository.heatingRate.value )
-                               self.distanceFeedRate.addTagBracketedLine('baseTemperature', self.repository.baseTemperature.value )
-                               self.distanceFeedRate.addTagBracketedLine('interfaceTemperature', self.repository.interfaceTemperature.value )
-                               self.distanceFeedRate.addTagBracketedLine('objectFirstLayerInfillTemperature', self.repository.objectFirstLayerInfillTemperature.value )
-                               self.distanceFeedRate.addTagBracketedLine('objectFirstLayerPerimeterTemperature', self.repository.objectFirstLayerPerimeterTemperature.value )
-                               self.distanceFeedRate.addTagBracketedLine('objectNextLayersTemperature', self.repository.objectNextLayersTemperature.value )
-                               self.distanceFeedRate.addTagBracketedLine('supportLayersTemperature', self.repository.supportLayersTemperature.value )
-                               self.distanceFeedRate.addTagBracketedLine('supportedLayersTemperature', self.repository.supportedLayersTemperature.value )
-                       self.distanceFeedRate.addLine(line)
-
-
-def main():
-       "Display the temperature dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/tower.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/tower.py
deleted file mode 100644 (file)
index 7be6657..0000000
+++ /dev/null
@@ -1,378 +0,0 @@
-"""
-This page is in the table of contents.
-Tower commands the fabricator to extrude a disconnected region for a few layers, then go to another disconnected region and extrude there.  Its purpose is to reduce the number of stringers between a shape and reduce extruder travel.
-
-The tower manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Tower
-
-==Operation==
-The default 'Activate Tower' checkbox is off.  The default is off because tower could result in the extruder colliding with an already extruded part of the shape and because extruding in one region for more than one layer could result in the shape melting.  When it is on, the functions described below will work, when it is off, nothing will be done.
-
-==Settings==
-===Maximum Tower Height===
-Default: 5
-
-Defines the maximum number of layers that the extruder will extrude in one region before going to another.  This is the most important value for tower.
-
-===Extruder Possible Collision Cone Angle===
-Default: 60 degrees
-
-Tower works by looking for islands in each layer and if it finds another island in the layer above, it goes to the next layer above instead of going across to other regions on the original layer.  It checks for collision with shapes already extruded within a cone from the nozzle tip.  The 'Extruder Possible Collision Cone Angle' setting is the angle of that cone.  Realistic values for the cone angle range between zero and ninety.  The higher the angle, the less likely a collision with the rest of the shape is, generally the extruder will stay in the region for only a few layers before a collision is detected with the wide cone.
-
-===Tower Start Layer===
-Default: 1
-
-Defines the layer index which the script starts extruding towers, after the last raft layer which does not have support material.  It is best to not tower at least the first layer because the temperature of the first layer is sometimes different than that of the other layers.
-
-==Examples==
-The following examples tower the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and tower.py.
-
-> python tower.py
-This brings up the tower dialog.
-
-> python tower.py Screw Holder Bottom.stl
-The tower tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The tower tool has created the file:
-.. Screw Holder Bottom_tower.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import intercircle
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import math
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-def getCraftedText( fileName, text, towerRepository = None ):
-       "Tower a gcode linear move file or text."
-       return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), towerRepository )
-
-def getCraftedTextFromText( gcodeText, towerRepository = None ):
-       "Tower a gcode linear move text."
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'tower'):
-               return gcodeText
-       if towerRepository == None:
-               towerRepository = settings.getReadRepository( TowerRepository() )
-       if not towerRepository.activateTower.value:
-               return gcodeText
-       return TowerSkein().getCraftedGcode( gcodeText, towerRepository )
-
-def getNewRepository():
-       'Get new repository.'
-       return TowerRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Tower a gcode linear move file."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'tower', shouldAnalyze)
-
-
-class Island(object):
-       "A class to hold the boundary and lines."
-       def __init__(self):
-               self.boundary = []
-               self.boundingLoop = None
-               self.lines = []
-
-       def addToBoundary( self, splitLine ):
-               "Add to the boundary if it is not complete."
-               if self.boundingLoop == None:
-                       location = gcodec.getLocationFromSplitLine(None, splitLine)
-                       self.boundary.append(location.dropAxis())
-                       self.z = location.z
-
-       def createBoundingLoop(self):
-               "Create the bounding loop if it is not already created."
-               if self.boundingLoop == None:
-                       self.boundingLoop = intercircle.BoundingLoop().getFromLoop( self.boundary )
-
-
-class ThreadLayer(object):
-       "A layer of loops and paths."
-       def __init__(self):
-               "Thread layer constructor."
-               self.afterExtrusionLines = []
-               self.beforeExtrusionLines = []
-               self.islands = []
-
-       def __repr__(self):
-               "Get the string representation of this thread layer."
-               return '%s' % self.islands
-
-
-class TowerRepository(object):
-       "A class to handle the tower settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.tower.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Tower', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Tower')
-               self.activateTower = settings.BooleanSetting().getFromValue('Activate Tower', self, False )
-               self.extruderPossibleCollisionConeAngle = settings.FloatSpin().getFromValue( 40.0, 'Extruder Possible Collision Cone Angle (degrees):', self, 80.0, 60.0 )
-               self.maximumTowerHeight = settings.IntSpin().getFromValue( 2, 'Maximum Tower Height (layers):', self, 10, 5 )
-               self.towerStartLayer = settings.IntSpin().getFromValue( 1, 'Tower Start Layer (integer):', self, 5, 1 )
-               self.executeTitle = 'Tower'
-
-       def execute(self):
-               "Tower button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class TowerSkein(object):
-       "A class to tower a skein of extrusions."
-       def __init__(self):
-               self.afterExtrusionLines = []
-               self.beforeExtrusionLines = []
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.edgeWidth = 0.6
-               self.highestZ = - 987654321.0
-               self.island = None
-               self.layerIndex = 0
-               self.lineIndex = 0
-               self.lines = None
-               self.minimumBelow = 0.1
-               self.oldLayerIndex = None
-               self.oldLocation = None
-               self.oldOrderedLocation = Vector3()
-               self.shutdownLineIndex = sys.maxint
-               self.nestedRingCount = 0
-               self.threadLayer = None
-               self.threadLayers = []
-               self.travelFeedRateMinute = None
-
-       def addEntireLayer( self, threadLayer ):
-               "Add entire thread layer."
-               self.distanceFeedRate.addLines( threadLayer.beforeExtrusionLines )
-               for island in threadLayer.islands:
-                       self.distanceFeedRate.addLines( island.lines )
-               self.distanceFeedRate.addLines( threadLayer.afterExtrusionLines )
-
-       def addHighThread(self, location):
-               "Add thread with a high move if necessary to clear the previous extrusion."
-               if self.oldLocation != None:
-                       if self.oldLocation.z + self.minimumBelow < self.highestZ:
-                               self.distanceFeedRate.addGcodeMovementZWithFeedRate( self.travelFeedRateMinute, self.oldLocation.dropAxis(), self.highestZ )
-               if location.z + self.minimumBelow < self.highestZ:
-                       self.distanceFeedRate.addGcodeMovementZWithFeedRate( self.travelFeedRateMinute, location.dropAxis(), self.highestZ )
-
-       def addThreadLayerIfNone(self):
-               "Add a thread layer if it is none."
-               if self.threadLayer != None:
-                       return
-               self.threadLayer = ThreadLayer()
-               self.threadLayers.append( self.threadLayer )
-               self.threadLayer.beforeExtrusionLines = self.beforeExtrusionLines
-               self.beforeExtrusionLines = []
-
-       def addTowers(self):
-               "Add towers."
-               bottomLayerIndex = self.getBottomLayerIndex()
-               if bottomLayerIndex == None:
-                       return
-               removedIsland = self.getRemovedIslandAddLayerLinesIfDifferent( self.threadLayers[ bottomLayerIndex ].islands, bottomLayerIndex )
-               while 1:
-                       self.climbTower( removedIsland )
-                       bottomLayerIndex = self.getBottomLayerIndex()
-                       if bottomLayerIndex == None:
-                               return
-                       removedIsland = self.getRemovedIslandAddLayerLinesIfDifferent( self.threadLayers[ bottomLayerIndex ].islands, bottomLayerIndex )
-
-       def climbTower( self, removedIsland ):
-               "Climb up the island to any islands directly above."
-               outsetDistance = 1.5 * self.edgeWidth
-               for step in xrange( self.towerRepository.maximumTowerHeight.value ):
-                       aboveIndex = self.oldLayerIndex + 1
-                       if aboveIndex >= len( self.threadLayers ):
-                               return
-                       outsetRemovedLoop = removedIsland.boundingLoop.getOutsetBoundingLoop( outsetDistance )
-                       islandsWithin = []
-                       for island in self.threadLayers[ aboveIndex ].islands:
-                               if self.isInsideRemovedOutsideCone( island, outsetRemovedLoop, aboveIndex ):
-                                       islandsWithin.append( island )
-                       if len( islandsWithin ) < 1:
-                               return
-                       removedIsland = self.getRemovedIslandAddLayerLinesIfDifferent( islandsWithin, aboveIndex )
-                       self.threadLayers[ aboveIndex ].islands.remove( removedIsland )
-
-       def getBottomLayerIndex(self):
-               "Get the index of the first island layer which has islands."
-               for islandLayerIndex in xrange( len( self.threadLayers ) ):
-                       if len( self.threadLayers[ islandLayerIndex ].islands ) > 0:
-                               return islandLayerIndex
-               return None
-
-       def getCraftedGcode( self, gcodeText, towerRepository ):
-               "Parse gcode text and store the tower gcode."
-               self.lines = archive.getTextLines(gcodeText)
-               self.towerRepository = towerRepository
-               self.parseInitialization()
-               self.parseIfWordUntilWord('(<operatingLayerEnd>')
-               self.parseIfWordUntilWord('(</skirt>)')
-               for lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       self.parseLine( lineIndex )
-               concatenateEndIndex = min( len( self.threadLayers ), towerRepository.towerStartLayer.value )
-               for threadLayer in self.threadLayers[ : concatenateEndIndex ]:
-                       self.addEntireLayer( threadLayer )
-               self.threadLayers = self.threadLayers[ concatenateEndIndex : ]
-               self.addTowers()
-               self.distanceFeedRate.addLines( self.lines[ self.shutdownLineIndex : ] )
-               return self.distanceFeedRate.output.getvalue()
-
-       def getRemovedIslandAddLayerLinesIfDifferent( self, islands, layerIndex ):
-               "Add gcode lines for the layer if it is different than the old bottom layer index."
-               threadLayer = None
-               if layerIndex != self.oldLayerIndex:
-                       self.oldLayerIndex = layerIndex
-                       threadLayer = self.threadLayers[layerIndex]
-                       self.distanceFeedRate.addLines( threadLayer.beforeExtrusionLines )
-               removedIsland = self.getTransferClosestNestedRingLines( self.oldOrderedLocation, islands )
-               if threadLayer != None:
-                       self.distanceFeedRate.addLines( threadLayer.afterExtrusionLines )
-               return removedIsland
-
-       def getTransferClosestNestedRingLines( self, oldOrderedLocation, remainingNestedRings ):
-               "Get and transfer the closest remaining nested ring."
-               if len( remainingNestedRings ) > 0:
-                       oldOrderedLocation.z = remainingNestedRings[0].z
-               closestDistance = 999999999987654321.0
-               closestNestedRing = None
-               for remainingNestedRing in remainingNestedRings:
-                       distance = euclidean.getClosestDistanceIndexToLine(oldOrderedLocation.dropAxis(), remainingNestedRing.boundary).distance
-                       if distance < closestDistance:
-                               closestDistance = distance
-                               closestNestedRing = remainingNestedRing
-               remainingNestedRings.remove(closestNestedRing)
-               hasTravelledHighRoad = False
-               for line in closestNestedRing.lines:
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       if firstWord == 'G1':
-                               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-                               if not hasTravelledHighRoad:
-                                       hasTravelledHighRoad = True
-                                       self.addHighThread(location)
-                               if location.z > self.highestZ:
-                                       self.highestZ = location.z
-                               self.oldLocation = location
-                       self.distanceFeedRate.addLine(line)
-               return closestNestedRing
-
-       def isInsideRemovedOutsideCone( self, island, removedBoundingLoop, untilLayerIndex ):
-               "Determine if the island is entirely inside the removed bounding loop and outside the collision cone of the remaining islands."
-               if not island.boundingLoop.isEntirelyInsideAnother( removedBoundingLoop ):
-                       return False
-               bottomLayerIndex = self.getBottomLayerIndex()
-               coneAngleTangent = math.tan( math.radians( self.towerRepository.extruderPossibleCollisionConeAngle.value ) )
-               for layerIndex in xrange( bottomLayerIndex, untilLayerIndex ):
-                       islands = self.threadLayers[layerIndex].islands
-                       outsetDistance = self.edgeWidth * ( untilLayerIndex - layerIndex ) * coneAngleTangent + 0.5 * self.edgeWidth
-                       for belowIsland in self.threadLayers[layerIndex].islands:
-                               outsetIslandLoop = belowIsland.boundingLoop.getOutsetBoundingLoop( outsetDistance )
-                               if island.boundingLoop.isOverlappingAnother( outsetIslandLoop ):
-                                       return False
-               return True
-
-       def parseIfWordUntilWord(self, word):
-               "Parse gcode if there is a word until the word is reached."
-               for self.lineIndex in xrange(self.lineIndex, gcodec.getFirstWordIndexReverse(word, self.lines, self.lineIndex)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.addLine(line)
-                       if firstWord == 'G1':
-                               self.oldLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-                               if self.oldLocation.z > self.highestZ:
-                                       self.highestZ = self.oldLocation.z
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('tower')
-                       elif firstWord == '(<layer>':
-                               return
-                       elif firstWord == '(<layerHeight>':
-                               self.minimumBelow = 0.1 * float(splitLine[1])
-                       elif firstWord == '(<edgeWidth>':
-                               self.edgeWidth = float(splitLine[1])
-                       elif firstWord == '(<travelFeedRatePerSecond>':
-                               self.travelFeedRateMinute = 60.0 * float(splitLine[1])
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine( self, lineIndex ):
-               "Parse a gcode line."
-               line = self.lines[lineIndex]
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               self.afterExtrusionLines.append(line)
-               if firstWord == 'M103':
-                       self.afterExtrusionLines = []
-               elif firstWord == '(</boundaryPerimeter>)':
-                       self.island.createBoundingLoop()
-               elif firstWord == '(<boundaryPoint>':
-                       self.island.addToBoundary(splitLine)
-               elif firstWord == '(</crafting>)':
-                       self.shutdownLineIndex = lineIndex
-               elif firstWord == '(<layer>':
-                       self.beforeExtrusionLines = [ line ]
-                       self.island = None
-                       self.nestedRingCount = 0
-                       self.threadLayer = None
-                       return
-               elif firstWord == '(</layer>)':
-                       if self.threadLayer != None:
-                               self.threadLayer.afterExtrusionLines = self.afterExtrusionLines
-                       self.afterExtrusionLines = []
-               elif firstWord == '(</loop>)':
-                       self.afterExtrusionLines = []
-               elif firstWord == '(<nestedRing>)':
-                       self.nestedRingCount += 1
-                       if self.island == None:
-                               self.island = Island()
-                               self.addThreadLayerIfNone()
-                               self.threadLayer.islands.append( self.island )
-               elif firstWord == '(</edge>)':
-                       self.afterExtrusionLines = []
-               if self.island != None:
-                       self.island.lines.append(line)
-               if firstWord == '(</nestedRing>)':
-                       self.afterExtrusionLines = []
-                       self.nestedRingCount -= 1
-                       if self.nestedRingCount == 0:
-                               self.island = None
-               if len( self.beforeExtrusionLines ) > 0:
-                       self.beforeExtrusionLines.append(line)
-
-
-def main():
-       "Display the tower dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/unpause.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/unpause.py
deleted file mode 100644 (file)
index d7ae2d2..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-"""
-This page is in the table of contents.
-The unpause plugin is based on the Shane Hathaway's patch to speed up a line segment to compensate for the delay of the microprocessor.  The description is at:
-http://shane.willowrise.com/archives/delay-compensation-in-firmware/
-
-The unpause manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Unpause
-
-==Operation==
-The default 'Activate Unpause' checkbox is off.  When it is on, the functions described below will work, when it is off, nothing will be done.
-
-==Settings==
-===Delay===
-Default is 28 milliseconds, which Shane found for the Arduino.
-
-Defines the delay on the microprocessor that will be at least partially compensated for.
-
-===Maximum Speed===
-Default is 1.3.
-
-Defines the maximum amount that the feed rate will be sped up to, compared to the original feed rate.
-
-==Examples==
-The following examples unpause the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and unpause.py.
-
-> python unpause.py
-This brings up the unpause dialog.
-
-> python unpause.py Screw Holder Bottom.stl
-The unpause tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The unpause tool has created the file:
-.. Screw Holder Bottom_unpause.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, gcodeText, repository=None):
-       "Unpause a gcode linear move file or text."
-       return getCraftedTextFromText( archive.getTextIfEmpty( fileName, gcodeText ), repository )
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       "Unpause a gcode linear move text."
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'unpause'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository( UnpauseRepository() )
-       if not repository.activateUnpause.value:
-               return gcodeText
-       return UnpauseSkein().getCraftedGcode(gcodeText, repository)
-
-def getNewRepository():
-       'Get new repository.'
-       return UnpauseRepository()
-
-def getSelectedPlugin(repository):
-       "Get the selected plugin."
-       for plugin in repository.unpausePlugins:
-               if plugin.value:
-                       return plugin
-       return None
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Unpause a gcode linear move file."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'unpause', shouldAnalyze)
-
-
-class UnpauseRepository(object):
-       "A class to handle the unpause settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.unpause.html', self)
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Unpause', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Unpause')
-               self.activateUnpause = settings.BooleanSetting().getFromValue('Activate Unpause', self, False )
-               self.delay = settings.FloatSpin().getFromValue( 2.0, 'Delay (milliseconds):', self, 42.0, 28.0 )
-               self.maximumSpeed = settings.FloatSpin().getFromValue( 1.1, 'Maximum Speed (ratio):', self, 1.9, 1.3 )
-               self.executeTitle = 'Unpause'
-
-       def execute(self):
-               "Unpause button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class UnpauseSkein(object):
-       "A class to unpause a skein of extrusions."
-       def __init__(self):
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.feedRateMinute = 959.0
-               self.lineIndex = 0
-               self.lines = None
-               self.oldLocation = None
-
-       def getCraftedGcode(self, gcodeText, repository):
-               "Parse gcode text and store the unpause gcode."
-               self.delaySecond = repository.delay.value * 0.001
-               self.maximumSpeed = repository.maximumSpeed.value
-               self.minimumSpeedUpReciprocal = 1.0 / self.maximumSpeed
-               self.repository = repository
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization()
-               for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def getUnpausedArcMovement( self, line, splitLine ):
-               "Get an unpaused arc movement."
-               self.feedRateMinute = gcodec.getFeedRateMinute( self.feedRateMinute, splitLine )
-               if self.oldLocation == None:
-                       return line
-               relativeLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               self.oldLocation += relativeLocation
-               distance = gcodec.getArcDistance(relativeLocation, splitLine)
-               return self.getUnpausedMovement(distance, line, splitLine)
-
-       def getUnpausedLinearMovement( self, line, splitLine ):
-               "Get an unpaused linear movement."
-               self.feedRateMinute = gcodec.getFeedRateMinute( self.feedRateMinute, splitLine )
-               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               if self.oldLocation == None:
-                       self.oldLocation = location
-                       return line
-               distance = abs(self.oldLocation - location)
-               self.oldLocation = location
-               return self.getUnpausedMovement(distance, line, splitLine)
-
-       def getUnpausedMovement(self, distance, line, splitLine):
-               "Get an unpaused movement."
-               if distance <= 0.0:
-                       return line
-               resultantReciprocal = 1.0 - self.delaySecond / distance * self.feedRateMinute / 60.0
-               resultantReciprocal = max(self.minimumSpeedUpReciprocal, resultantReciprocal)
-               return self.distanceFeedRate.getLineWithFeedRate(self.feedRateMinute / resultantReciprocal, line, splitLine)
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('unpause')
-                               return
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               "Parse a gcode line."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       line = self.getUnpausedLinearMovement( line, splitLine )
-               if firstWord == 'G2' or firstWord == 'G3':
-                       line = self.getUnpausedArcMovement( line, splitLine )
-               self.distanceFeedRate.addLine(line)
-
-
-def main():
-       "Display the unpause dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/whittle.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/whittle.py
deleted file mode 100644 (file)
index 19eb5f7..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-"""
-This page is in the table of contents.
-Whittle will convert each polygon of a gcode file into a helix which has a vertical step down on each rotation.
-
-==Operation==
-The default 'Activate Whittle' checkbox is on.  When it is on, the functions described below will work, when it is off, the functions will not be called.  If the cutting tool can cut the slab in one cut, the 'Activate Whittle' checkbox should be off, the default is off.
-
-==Settings==
-===Maximum Vertical Step'===
-Default is 0.1 mm.
-
-Defines the maximum distance that the helix will step down on each rotation.  The number of steps in the helix will be the layer height divided by the 'Maximum Vertical Step', rounded up.  The amount the helix will step down is the layer height divided by the number of steps.  The thinner the 'Maximum Vertical Step', the more times the cutting tool will circle around on its way to the bottom of the slab.
-
-==Examples==
-The following examples whittle the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and whittle.py.
-
-> python whittle.py
-This brings up the whittle dialog.
-
-> python whittle.py Screw Holder Bottom.stl
-The whittle tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The whittle tool has created the file:
-.. Screw Holder Bottom_whittle.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import math
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/02/05 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, text='', whittleRepository = None ):
-       "Whittle the preface file or text."
-       return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), whittleRepository )
-
-def getCraftedTextFromText( gcodeText, whittleRepository = None ):
-       "Whittle the preface gcode text."
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'whittle'):
-               return gcodeText
-       if whittleRepository == None:
-               whittleRepository = settings.getReadRepository( WhittleRepository() )
-       if not whittleRepository.activateWhittle.value:
-               return gcodeText
-       return WhittleSkein().getCraftedGcode( whittleRepository, gcodeText )
-
-def getNewRepository():
-       'Get new repository.'
-       return WhittleRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Whittle the carving of a gcode file."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'whittle', shouldAnalyze)
-
-
-class WhittleRepository(object):
-       "A class to handle the whittle settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.whittle.html', self )
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File to be Whittled', self, '')
-               self.activateWhittle = settings.BooleanSetting().getFromValue('Activate Whittle', self, False )
-               self.maximumVerticalStep = settings.FloatSpin().getFromValue( 0.02, 'Maximum Vertical Step (mm):', self, 0.42, 0.1 )
-               self.executeTitle = 'Whittle'
-
-       def execute(self):
-               "Whittle button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class WhittleSkein(object):
-       "A class to whittle a skein of extrusions."
-       def __init__(self):
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.layerHeight = 0.3333333333
-               self.lineIndex = 0
-               self.movementLines = []
-               self.oldLocation = None
-
-       def getCraftedGcode( self, whittleRepository, gcodeText ):
-               "Parse gcode text and store the whittle gcode."
-               self.whittleRepository = whittleRepository
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization()
-               for line in self.lines[self.lineIndex :]:
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def getLinearMove( self, line, splitLine ):
-               "Get the linear move."
-               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               self.movementLines.append(line)
-               z = location.z + self.layerDeltas[0]
-               self.oldLocation = location
-               return self.distanceFeedRate.getLineWithZ( line, splitLine, z )
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex].lstrip()
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('whittle')
-                               return
-                       elif firstWord == '(<layerHeight>':
-                               self.setLayerThinknessVerticalDeltas(splitLine)
-                               self.distanceFeedRate.addTagBracketedLine('layerStep', self.layerStep )
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               "Parse a gcode line and add it to the whittle skein."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       line = self.getLinearMove( line, splitLine )
-               elif firstWord == 'M103':
-                       self.repeatLines()
-               self.distanceFeedRate.addLine(line)
-
-       def repeatLines(self):
-               "Repeat the lines at decreasing altitude."
-               for layerDelta in self.layerDeltas[1 :]:
-                       for movementLine in self.movementLines:
-                               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(movementLine)
-                               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-                               z = location.z + layerDelta
-                               self.distanceFeedRate.addLine( self.distanceFeedRate.getLineWithZ( movementLine, splitLine, z ) )
-               self.movementLines = []
-
-       def setLayerThinknessVerticalDeltas( self, splitLine ):
-               "Set the layer height and the vertical deltas."
-               self.layerHeight = float(splitLine[1])
-               numberOfSteps = int( math.ceil( self.layerHeight / self.whittleRepository.maximumVerticalStep.value ) )
-               self.layerStep = self.layerHeight / float( numberOfSteps )
-               self.layerDeltas = []
-               halfDeltaMinusHalfTop = 0.5 * self.layerStep * ( 1.0 - numberOfSteps )
-               for layerDeltaIndex in xrange( numberOfSteps - 1, - 1, - 1 ):
-                       layerDelta = layerDeltaIndex * self.layerStep + halfDeltaMinusHalfTop
-                       self.layerDeltas.append( layerDelta )
-
-
-def main():
-       "Display the whittle dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/widen.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/widen.py
deleted file mode 100644 (file)
index 9649f35..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-#! /usr/bin/env python
-"""
-This page is in the table of contents.
-Widen will widen the outside edges away from the inside edges, so that the outsides will be at least two edge widths away from the insides and therefore the outside filaments will not overlap the inside filaments.
-
-For example, if a mug has a very thin wall, widen would widen the outside of the mug so that the wall of the mug would be two edge widths wide, and the outside wall filament would not overlap the inside filament.
-
-For another example, if the outside of the object runs right next to a hole, widen would widen the wall around the hole so that the wall would bulge out around the hole, and the outside filament would not overlap the hole filament.
-
-The widen manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Widen
-
-==Operation==
-The default 'Activate Widen' checkbox is off.  When it is on, widen will work, when it is off, nothing will be done.
-
-==Examples==
-The following examples widen the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and widen.py.
-
-> python widen.py
-This brings up the widen dialog.
-
-> python widen.py Screw Holder Bottom.stl
-The widen tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The widen tool has created the file:
-.. Screw Holder Bottom_widen.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.geometry.geometry_utilities import boolean_solid
-from fabmetheus_utilities.geometry.solids import triangle_mesh
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import intercircle
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/28/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText(fileName, text='', repository=None):
-       'Widen the preface file or text.'
-       return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository)
-
-def getCraftedTextFromText(gcodeText, repository=None):
-       'Widen the preface gcode text.'
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'widen'):
-               return gcodeText
-       if repository == None:
-               repository = settings.getReadRepository( WidenRepository() )
-       if not repository.activateWiden.value:
-               return gcodeText
-       return WidenSkein().getCraftedGcode(gcodeText, repository)
-
-def getIntersectingWithinLoops(loop, loopList, outsetLoop):
-       'Get the loops which are intersecting or which it is within.'
-       intersectingWithinLoops = []
-       for otherLoop in loopList:
-               if getIsIntersectingWithinLoop(loop, otherLoop, outsetLoop):
-                       intersectingWithinLoops.append(otherLoop)
-       return intersectingWithinLoops
-
-def getIsIntersectingWithinLoop(loop, otherLoop, outsetLoop):
-       'Determine if the loop is intersecting or is within the other loop.'
-       if euclidean.isLoopIntersectingLoop(loop, otherLoop):
-               return True
-       return euclidean.isPathInsideLoop(otherLoop, loop) != euclidean.isPathInsideLoop(otherLoop, outsetLoop)
-
-def getIsPointInsideALoop(loops, point):
-       'Determine if a point is inside a loop of a loop list.'
-       for loop in loops:
-               if euclidean.isPointInsideLoop(loop, point):
-                       return True
-       return False
-
-def getNewRepository():
-       'Get new repository.'
-       return WidenRepository()
-
-def getWidenedLoops(loop, loopList, outsetLoop, radius):
-       'Get the widened loop.'
-       intersectingWithinLoops = getIntersectingWithinLoops(loop, loopList, outsetLoop)
-       if len(intersectingWithinLoops) < 1:
-               return [loop]
-       loopsUnified = boolean_solid.getLoopsUnion(radius, [[loop], intersectingWithinLoops])
-       if len(loopsUnified) < 1:
-               return [loop]
-       return loopsUnified
-
-def writeOutput(fileName, shouldAnalyze=True):
-       'Widen the carving of a gcode file.'
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'widen', shouldAnalyze)
-
-
-class WidenRepository(object):
-       'A class to handle the widen settings.'
-       def __init__(self):
-               'Set the default settings, execute title & settings fileName.'
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.widen.html', self)
-               self.fileNameInput = settings.FileNameInput().getFromFileName(
-                       fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Widen', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute(
-                       'http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Widen')
-               self.activateWiden = settings.BooleanSetting().getFromValue('Activate Widen', self, False)
-               self.widenWidthOverEdgeWidth = settings.IntSpin().getFromValue(2, 'Widen Width over Edge Width (ratio):', self, 4, 2)
-               self.executeTitle = 'Widen'
-
-       def execute(self):
-               'Widen button has been clicked.'
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(
-                       self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class WidenSkein(object):
-       'A class to widen a skein of extrusions.'
-       def __init__(self):
-               self.boundary = None
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.layerCount = settings.LayerCount()
-               self.lineIndex = 0
-               self.loopLayer = None
-
-       def addWiden(self, loopLayer):
-               'Add widen to the layer.'
-               triangle_mesh.sortLoopsInOrderOfArea(False, loopLayer.loops)
-               widdershinsLoops = []
-               clockwiseInsetLoops = []
-               for loopIndex in xrange(len(loopLayer.loops)):
-                       loop = loopLayer.loops[loopIndex]
-                       if euclidean.isWiddershins(loop):
-                               otherLoops = loopLayer.loops[: loopIndex] + loopLayer.loops[loopIndex + 1 :]
-                               leftPoint = euclidean.getLeftPoint(loop)
-                               if getIsPointInsideALoop(otherLoops, leftPoint):
-                                       self.distanceFeedRate.addGcodeFromLoop(loop, loopLayer.z)
-                               else:
-                                       widdershinsLoops.append(loop)
-                       else:
-#                              clockwiseInsetLoop = intercircle.getLargestInsetLoopFromLoop(loop, self.widenEdgeWidth)
-#                              clockwiseInsetLoop.reverse()
-#                              clockwiseInsetLoops.append(clockwiseInsetLoop)
-                               clockwiseInsetLoops += intercircle.getInsetLoopsFromLoop(loop, self.widenEdgeWidth)
-                               self.distanceFeedRate.addGcodeFromLoop(loop, loopLayer.z)
-               for widdershinsLoop in widdershinsLoops:
-                       outsetLoop = intercircle.getLargestInsetLoopFromLoop(widdershinsLoop, -self.widenEdgeWidth)
-                       for widenedLoop in getWidenedLoops(widdershinsLoop, clockwiseInsetLoops, outsetLoop, self.lessThanHalfEdgeWidth):
-                               self.distanceFeedRate.addGcodeFromLoop(widenedLoop, loopLayer.z)
-
-       def getCraftedGcode(self, gcodeText, repository):
-               'Parse gcode text and store the widen gcode.'
-               self.repository = repository
-               self.lines = archive.getTextLines(gcodeText)
-               self.parseInitialization()
-               for line in self.lines[self.lineIndex :]:
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def parseInitialization(self):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('widen')
-                       elif firstWord == '(<crafting>)':
-                               self.distanceFeedRate.addLine(line)
-                               return
-                       elif firstWord == '(<edgeWidth>':
-                               self.edgeWidth = float(splitLine[1])
-                               self.widenEdgeWidth = float(self.repository.widenWidthOverEdgeWidth.value) * self.edgeWidth
-                               self.lessThanHalfEdgeWidth = 0.49 * self.edgeWidth
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               'Parse a gcode line and add it to the widen skein.'
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == '(<boundaryPoint>':
-                       location = gcodec.getLocationFromSplitLine(None, splitLine)
-                       self.boundary.append(location.dropAxis())
-               elif firstWord == '(<layer>':
-                       self.layerCount.printProgressIncrement('widen')
-                       self.loopLayer = euclidean.LoopLayer(float(splitLine[1]))
-                       self.distanceFeedRate.addLine(line)
-               elif firstWord == '(</layer>)':
-                       self.addWiden( self.loopLayer )
-                       self.loopLayer = None
-               elif firstWord == '(<nestedRing>)':
-                       self.boundary = []
-                       self.loopLayer.loops.append( self.boundary )
-               if self.loopLayer == None:
-                       self.distanceFeedRate.addLine(line)
-
-
-def main():
-       'Display the widen dialog.'
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == '__main__':
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/wipe.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/wipe.py
deleted file mode 100644 (file)
index de65e59..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-"""
-This page is in the table of contents.
-At the beginning of a layer, depending on the settings, wipe will move the nozzle with the extruder off to the arrival point, then to the wipe point, then to the departure point, then back to the layer.
-
-The wipe path is machine specific, so you'll probably have to change all the default locations.
-
-The wipe manual page is at:
-http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Wipe
-
-==Operation==
-The default 'Activate Wipe' checkbox is off.  When it is on, the functions described below will work, when it is off, nothing will be done.
-
-==Settings==
-===Arrival Location===
-====Arrival X====
-Default is minus seventy millimeters.
-
-Defines the x coordinate of the arrival location.
-
-====Arrival Y====
-Default is minus fifty millimeters.
-
-Defines the y coordinate of the arrival location.
-
-====Arrival Z====
-Default is fifty millimeters.
-
-Defines the z coordinate of the arrival location.
-
-===Departure Location===
-====Departure X====
-Default is minus seventy millimeters.
-
-Defines the x coordinate of the departure location.
-
-====Departure Y====
-Default is minus forty millimeters.
-
-Defines the y coordinate of the departure location.
-
-====Departure Z====
-Default is fifty millimeters.
-
-Defines the z coordinate of the departure location.
-
-===Wipe Location===
-====Wipe X====
-Default is minus seventy millimeters.
-
-Defines the x coordinate of the wipe location.
-
-====Wipe Y====
-Default is minus seventy millimeters.
-
-Defines the y coordinate of the wipe location.
-
-====Wipe Z====
-Default is fifty millimeters.
-
-Defines the z coordinate of the wipe location.
-
-===Wipe Period===
-Default is three.
-
-Defines the number of layers between wipes.  Wipe will always wipe just before layer zero, afterwards it will wipe every "Wipe Period" layers.  With the default of three, wipe will wipe just before layer zero, layer three, layer six and so on.
-
-==Examples==
-The following examples wipe the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and wipe.py.
-
-> python wipe.py
-This brings up the wipe dialog.
-
-> python wipe.py Screw Holder Bottom.stl
-The wipe tool is parsing the file:
-Screw Holder Bottom.stl
-..
-The wipe tool has created the file:
-.. Screw Holder Bottom_wipe.gcode
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities.vector3 import Vector3
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_craft
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftedText( fileName, text, wipeRepository = None ):
-       "Wipe a gcode linear move text."
-       return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), wipeRepository )
-
-def getCraftedTextFromText( gcodeText, wipeRepository = None ):
-       "Wipe a gcode linear move text."
-       if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'wipe'):
-               return gcodeText
-       if wipeRepository == None:
-               wipeRepository = settings.getReadRepository( WipeRepository() )
-       if not wipeRepository.activateWipe.value:
-               return gcodeText
-       return WipeSkein().getCraftedGcode( gcodeText, wipeRepository )
-
-def getNewRepository():
-       'Get new repository.'
-       return WipeRepository()
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Wipe a gcode linear move file."
-       skeinforge_craft.writeChainTextWithNounMessage(fileName, 'wipe', shouldAnalyze)
-
-
-class WipeRepository(object):
-       "A class to handle the wipe settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.wipe.html', self)
-               self.fileNameInput = settings.FileNameInput().getFromFileName(fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Wipe', self, '')
-               self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Wipe')
-               self.activateWipe = settings.BooleanSetting().getFromValue('Activate Wipe', self, False)
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Arrival Location -', self)
-               self.locationArrivalX = settings.FloatSpin().getFromValue(-100.0, 'Arrival X (mm):', self, 100.0, -70.0)
-               self.locationArrivalY = settings.FloatSpin().getFromValue(-100.0, 'Arrival Y (mm):', self, 100.0, -50.0)
-               self.locationArrivalZ = settings.FloatSpin().getFromValue(-100.0, 'Arrival Z (mm):', self, 100.0, 50.0)
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Departure Location -', self)
-               self.locationDepartureX = settings.FloatSpin().getFromValue(-100.0, 'Departure X (mm):', self, 100.0, -70.0)
-               self.locationDepartureY = settings.FloatSpin().getFromValue(-100.0, 'Departure Y (mm):', self, 100.0, -40.0)
-               self.locationDepartureZ = settings.FloatSpin().getFromValue(-100.0, 'Departure Z (mm):', self, 100.0, 50.0)
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Wipe Location -', self)
-               self.locationWipeX = settings.FloatSpin().getFromValue(-100.0, 'Wipe X (mm):', self, 100.0, -70.0)
-               self.locationWipeY = settings.FloatSpin().getFromValue(-100.0, 'Wipe Y (mm):', self, 100.0, -70.0)
-               self.locationWipeZ = settings.FloatSpin().getFromValue(-100.0, 'Wipe Z (mm):', self, 100.0, 50.0)
-               settings.LabelSeparator().getFromRepository(self)
-               self.wipePeriod = settings.IntSpin().getFromValue(1, 'Wipe Period (layers):', self, 5, 3)
-               self.executeTitle = 'Wipe'
-
-       def execute(self):
-               "Wipe button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-class WipeSkein(object):
-       "A class to wipe a skein of extrusions."
-       def __init__(self):
-               self.distanceFeedRate = gcodec.DistanceFeedRate()
-               self.extruderActive = False
-               self.highestZ = None
-               self.layerIndex = -1
-               self.lineIndex = 0
-               self.lines = None
-               self.oldLocation = None
-               self.shouldWipe = False
-               self.travelFeedRateMinute = 957.0
-
-       def addHop( self, begin, end ):
-               "Add hop to highest point."
-               beginEndDistance = begin.distance(end)
-               if beginEndDistance < 3.0 * self.absoluteEdgeWidth:
-                       return
-               alongWay = self.absoluteEdgeWidth / beginEndDistance
-               closeToOldLocation = euclidean.getIntermediateLocation( alongWay, begin, end )
-               closeToOldLocation.z = self.highestZ
-               self.distanceFeedRate.addLine( self.getLinearMoveWithFeedRate( self.travelFeedRateMinute, closeToOldLocation ) )
-               closeToOldArrival = euclidean.getIntermediateLocation( alongWay, end, begin )
-               closeToOldArrival.z = self.highestZ
-               self.distanceFeedRate.addLine( self.getLinearMoveWithFeedRate( self.travelFeedRateMinute, closeToOldArrival ) )
-
-       def addWipeTravel( self, splitLine ):
-               "Add the wipe travel gcode."
-               location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               self.highestZ = max( self.highestZ, location.z )
-               if not self.shouldWipe:
-                       return
-               self.shouldWipe = False
-               if self.extruderActive:
-                       self.distanceFeedRate.addLine('M103')
-               if self.oldLocation != None:
-                       self.addHop( self.oldLocation, self.locationArrival )
-               self.distanceFeedRate.addLine( self.getLinearMoveWithFeedRate( self.travelFeedRateMinute, self.locationArrival ) )
-               self.distanceFeedRate.addLine( self.getLinearMoveWithFeedRate( self.travelFeedRateMinute, self.locationWipe ) )
-               self.distanceFeedRate.addLine( self.getLinearMoveWithFeedRate( self.travelFeedRateMinute, self.locationDeparture ) )
-               self.addHop( self.locationDeparture, location )
-               if self.extruderActive:
-                       self.distanceFeedRate.addLine('M101')
-
-       def getCraftedGcode( self, gcodeText, wipeRepository ):
-               "Parse gcode text and store the wipe gcode."
-               self.lines = archive.getTextLines(gcodeText)
-               self.wipePeriod = wipeRepository.wipePeriod.value
-               self.parseInitialization( wipeRepository )
-               self.locationArrival = Vector3( wipeRepository.locationArrivalX.value, wipeRepository.locationArrivalY.value, wipeRepository.locationArrivalZ.value )
-               self.locationDeparture = Vector3( wipeRepository.locationDepartureX.value, wipeRepository.locationDepartureY.value, wipeRepository.locationDepartureZ.value )
-               self.locationWipe = Vector3( wipeRepository.locationWipeX.value, wipeRepository.locationWipeY.value, wipeRepository.locationWipeZ.value )
-               for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       self.parseLine(line)
-               return self.distanceFeedRate.output.getvalue()
-
-       def getLinearMoveWithFeedRate( self, feedRate, location ):
-               "Get a linear move line with the feedRate."
-               return self.distanceFeedRate.getLinearGcodeMovementWithFeedRate( feedRate, location.dropAxis(), location.z )
-
-       def parseInitialization( self, wipeRepository ):
-               'Parse gcode initialization and store the parameters.'
-               for self.lineIndex in xrange(len(self.lines)):
-                       line = self.lines[self.lineIndex]
-                       splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-                       firstWord = gcodec.getFirstWord(splitLine)
-                       self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
-                       if firstWord == '(</extruderInitialization>)':
-                               self.distanceFeedRate.addTagBracketedProcedure('wipe')
-                               return
-                       elif firstWord == '(<edgeWidth>':
-                               self.absoluteEdgeWidth = abs(float(splitLine[1]))
-                       elif firstWord == '(<travelFeedRatePerSecond>':
-                               self.travelFeedRateMinute = 60.0 * float(splitLine[1])
-                       self.distanceFeedRate.addLine(line)
-
-       def parseLine(self, line):
-               "Parse a gcode line and add it to the bevel gcode."
-               splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
-               if len(splitLine) < 1:
-                       return
-               firstWord = splitLine[0]
-               if firstWord == 'G1':
-                       self.addWipeTravel(splitLine)
-                       self.oldLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
-               elif firstWord == '(<layer>':
-                       self.layerIndex += 1
-                       settings.printProgress(self.layerIndex, 'wipe')
-                       if self.layerIndex % self.wipePeriod == 0:
-                               self.shouldWipe = True
-               elif firstWord == 'M101':
-                       self.extruderActive = True
-               elif firstWord == 'M103':
-                       self.extruderActive = False
-               self.distanceFeedRate.addLine(line)
-
-
-def main():
-       "Display the wipe dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/help.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/help.py
deleted file mode 100644 (file)
index c4861e3..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-"""
-This page is in the table of contents.
-Help has buttons and menu items to open help, blog and forum pages in your primary browser.
-
-
-==Link Buttons==
-===Announcements===
-====Fabmetheus Blog====
-The skeinforge announcements blog and the place to post questions, bugs and skeinforge requests.
-
-===Documentation===
-====Index of Local Documentation====
-The list of the pages in the documentation folder.
-
-====Wiki Manual====
-The skeinforge wiki with pictures and charts.  It is the best and most readable source of skeinforge information and you are welcome to contribute.
-
-====Skeinforge Overview====
-A general description of skeinforge, has answers to frequently asked questions and has many links to skeinforge, fabrication and python pages.  It is also the help page of the skeinforge tool.
-
-===Forums===
-====Bits from Bytes Printing Board====
-Board about printing questions, problems and solutions.  Most of the people on that forum use the rapman, but many of the solutions apply to any reprap.
-
-====Bits from Bytes Software Board====
-Board about software, and has some skeinforge threads.
-
-====Skeinforge Contributions Thread====
-Forum thread about how to contribute to skeinforge development.
-
-====Skeinforge Settings Thread====
-Forum thread for people to post, download and discuss skeinforge settings.
-
-==Settings==
-===Wiki Manual Primary===
-Default is on.
-
-The help menu has an item for each button on the help page.  Also, at the very top, it has a link to the local documentation and if there is a separate page for that tool in the wiki manual, a link to that page on the manual.  If the 'Wiki Manual Primary' checkbutton is selected and there is a separate wiki manual page, the wiki page will be the primary document page, otherwise the local page will be primary.  The help button (? symbol button) on the tool page will open the primary page, as will pressing <F1>.  For example, if you click the the help button from the chamber tool, which has a separate page in the wiki, and 'Wiki Manual Primary' is selected, the wiki manual chamber page will be opened.  Clicking F1 will also open the wiki manual chamber page.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_help
-import os
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addToMenu( master, menu, repository, window ):
-       "Add a tool plugin menu."
-       path = settings.getPathInFabmetheusFromFileNameHelp( repository.fileNameHelp )
-       capitalizedBasename = os.path.basename(path).capitalize()
-       helpRepository = settings.getReadRepository( skeinforge_help.HelpRepository() )
-       if repository.openWikiManualHelpPage != None and helpRepository.wikiManualPrimary.value:
-               menu.add_command( label = 'Local ' + capitalizedBasename, command = repository.openLocalHelpPage )
-       else:
-               settings.addAcceleratorCommand('<F1>', repository.openLocalHelpPage, master, menu, 'Local ' + capitalizedBasename )
-       if repository.openWikiManualHelpPage != None:
-               if helpRepository.wikiManualPrimary.value:
-                       settings.addAcceleratorCommand('<F1>', repository.openWikiManualHelpPage, master, menu, 'Wiki Manual ' + capitalizedBasename )
-               else:
-                       menu.add_command( label = 'Wiki Manual ' + capitalizedBasename, command = repository.openWikiManualHelpPage )
-       menu.add_separator()
-       settings.addMenuEntitiesToMenu( menu, helpRepository.menuEntities )
-
-def getNewRepository():
-       'Get new repository.'
-       return skeinforge_help.HelpRepository()
-
-def main():
-       "Display the help dialog."
-       settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/meta.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/meta.py
deleted file mode 100644 (file)
index 1b256c7..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-"""
-This page is in the table of contents.
-Meta is a script to access the plugins which handle meta information.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_meta
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addToMenu( master, menu, repository, window ):
-       "Add a tool plugin menu."
-       metaFilePath = archive.getSkeinforgePluginsPath('meta.py')
-       settings.addPluginsParentToMenu(skeinforge_meta.getPluginsDirectoryPath(), menu, metaFilePath, skeinforge_meta.getPluginFileNames())
-
-def getNewRepository():
-       'Get new repository.'
-       return skeinforge_meta.MetaRepository()
-
-
-def main():
-       "Display the meta dialog."
-       settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/meta_plugins/__init__.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/meta_plugins/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/meta_plugins/description.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/meta_plugins/description.py
deleted file mode 100644 (file)
index 21c356e..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-"""
-This page is in the table of contents.
-Description is a script to store a description of the profile.
-
-==Settings==
-===Description Text===
-Default is 'Write your profile description here.'
-
-The suggested format is a description, followed by a link to a profile post or web page.
-
-==Example==
-Example of using description follows below.
-
-> python description.py
-This brings up the description dialog.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getNewRepository():
-       'Get new repository.'
-       return DescriptionRepository()
-
-
-class DescriptionRepository(object):
-       "A class to handle the description settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.meta_plugins.description.html', self)
-               description = 'Write your description of the profile here.\n\nSuggested format is a description, followed by a link to the profile post or web page.'
-               self.descriptionText = settings.TextSetting().getFromValue('Description Text:', self, description)
-
-
-def main():
-       "Display the file or directory dialog."
-       settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/meta_plugins/polyfile.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/meta_plugins/polyfile.py
deleted file mode 100644 (file)
index 1e0299c..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-"""
-This page is in the table of contents.
-Polyfile is a script to choose whether the skeinforge toolchain will operate on one file or all the files in a directory.
-
-==Settings==
-===Polyfile Choice===
-Default is 'Execute File',
-
-====Execute File====
-When selected, the toolchain will operate on only the chosen file.
-
-====Execute All Unmodified Files in a Directory'====
-When selected, the toolchain will operate on all the unmodifed files in the directory that the chosen file is in.
-
-==Example==
-Example of using polyfile follows below.
-
-> python polyfile.py
-This brings up the polyfile dialog.
-
-"""
-
-from __future__ import absolute_import
-
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getNewRepository():
-       'Get new repository.'
-       return skeinforge_polyfile.PolyfileRepository()
-
-
-def main():
-       "Display the file or directory dialog."
-       settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/profile.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/profile.py
deleted file mode 100644 (file)
index 6a49bdc..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-"""
-This page is in the table of contents.
-Profile is a script to set the craft types setting for the skeinforge chain.
-
-Profile presents the user with a choice of the craft types in the profile_plugins folder.  The chosen craft type is used to determine the craft type profile for the skeinforge chain.  The default craft type is extrusion.
-
-The setting is the selection.  If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved.
-
-To change the profile setting, in a shell in the profile folder type:
-> python profile.py
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import os
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def addSubmenus( craftTypeName, menu, pluginFileName, pluginPath, profileRadioVar ):
-       "Add a tool plugin menu."
-       submenu = settings.Tkinter.Menu( menu, tearoff = 0 )
-       menu.add_cascade( label = pluginFileName.capitalize(), menu = submenu )
-       settings.ToolDialog().addPluginToMenu( submenu, pluginPath )
-       submenu.add_separator()
-       pluginModule = skeinforge_profile.getCraftTypePluginModule( pluginFileName )
-       profilePluginSettings = settings.getReadRepository( pluginModule.getNewRepository() )
-       isSelected = ( craftTypeName == pluginFileName )
-       for profileName in profilePluginSettings.profileList.value:
-               value = isSelected and profileName == profilePluginSettings.profileListbox.value
-               ProfileMenuRadio( pluginFileName, submenu, profileName, profileRadioVar, value )
-
-def addToMenu( master, menu, repository, window ):
-       "Add a tool plugin menu."
-       ProfileMenuSaveListener( menu, window )
-
-def addToProfileMenu( menu ):
-       "Add a profile menu."
-       settings.ToolDialog().addPluginToMenu(menu, archive.getUntilDot(archive.getSkeinforgePluginsPath('profile.py')))
-       menu.add_separator()
-       directoryPath = skeinforge_profile.getPluginsDirectoryPath()
-       pluginFileNames = skeinforge_profile.getPluginFileNames()
-       craftTypeName = skeinforge_profile.getCraftTypeName()
-       profileRadioVar = settings.Tkinter.StringVar()
-       for pluginFileName in pluginFileNames:
-               addSubmenus( craftTypeName, menu, pluginFileName, os.path.join( directoryPath, pluginFileName ), profileRadioVar )
-
-def getNewRepository():
-       'Get new repository.'
-       return skeinforge_profile.ProfileRepository()
-
-
-class ProfileMenuRadio(object):
-       "A class to display a profile menu radio button."
-       def __init__( self, profilePluginFileName, menu, name, radioVar, value ):
-               "Create a profile menu radio."
-               self.activate = False
-               self.menu = menu
-               self.name = name
-               self.profileJoinName = profilePluginFileName + '.& /' + name
-               self.profilePluginFileName = profilePluginFileName
-               self.radioVar = radioVar
-               menu.add_radiobutton( label = name.replace('_', ' '), command = self.clickRadio, value = self.profileJoinName, variable = self.radioVar )
-               self.menuLength = menu.index( settings.Tkinter.END )
-               if value:
-                       self.radioVar.set( self.profileJoinName )
-                       self.menu.invoke( self.menuLength )
-               self.activate = True
-
-       def clickRadio(self):
-               "Workaround for Tkinter bug, invoke and set the value when clicked."
-               if not self.activate:
-                       return
-               self.radioVar.set( self.profileJoinName )
-               pluginModule = skeinforge_profile.getCraftTypePluginModule( self.profilePluginFileName )
-               profilePluginSettings = settings.getReadRepository( pluginModule.getNewRepository() )
-               profilePluginSettings.profileListbox.value = self.name
-               settings.writeSettings( profilePluginSettings )
-               profileSettings = skeinforge_profile.getReadProfileRepository()
-               plugins = profileSettings.craftRadios
-               for plugin in plugins:
-                       plugin.value = ( plugin.name == self.profilePluginFileName )
-               settings.writeSettings( profileSettings )
-               skeinforge_profile.updateProfileSaveListeners()
-
-
-class ProfileMenuSaveListener(object):
-       "A class to update a profile menu."
-       def __init__( self, menu, window ):
-               "Set the menu."
-               self.menu = menu
-               addToProfileMenu( menu )
-               euclidean.addElementToListDictionaryIfNotThere( self, window, settings.globalProfileSaveListenerListTable )
-
-       def save(self):
-               "Profile has been saved and profile menu should be updated."
-               settings.deleteMenuItems( self.menu )
-               addToProfileMenu( self.menu )
-
-
-def main():
-       "Display the profile dialog."
-       settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/profile_plugins/__init__.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/profile_plugins/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/profile_plugins/cutting.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/profile_plugins/cutting.py
deleted file mode 100644 (file)
index cbf5ac2..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-"""
-This page is in the table of contents.
-Cutting is a script to set the cutting profile for the skeinforge chain.
-
-The displayed craft sequence is the sequence in which the tools craft the model and export the output.
-
-On the cutting dialog, clicking the 'Add Profile' button will duplicate the selected profile and give it the name in the input field.  For example, if laser is selected and the name laser_10mm is in the input field, clicking the 'Add Profile' button will duplicate laser and save it as laser_10mm.  The 'Delete Profile' button deletes the selected profile.
-
-The profile selection is the setting.  If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved.  However; adding and deleting a profile is a permanent action, for example 'Cancel' will not bring back any deleted profiles.
-
-To change the cutting profile, in a shell in the profile_plugins folder type:
-> python cutting.py
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftSequence():
-       "Get the cutting craft sequence."
-       return 'chop preface outset multiply whittle drill lift flow feed home lash fillet limit unpause alteration export'.split()
-
-def getNewRepository():
-       'Get new repository.'
-       return CuttingRepository()
-
-
-class CuttingRepository(object):
-       "A class to handle the cutting settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsSetCraftProfile( getCraftSequence(), 'end_mill', self, 'skeinforge_application.skeinforge_plugins.profile_plugins.cutting.html')
-
-
-def main():
-       "Display the export dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/profile_plugins/extrusion.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/profile_plugins/extrusion.py
deleted file mode 100644 (file)
index 76a4f34..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-"""
-This page is in the table of contents.
-Extrusion is a script to set the extrusion profile for the skeinforge chain.
-
-The displayed craft sequence is the sequence in which the tools craft the model and export the output.
-
-On the extrusion dialog, clicking the 'Add Profile' button will duplicate the selected profile and give it the name in the input field.  For example, if ABS is selected and the name ABS_black is in the input field, clicking the 'Add Profile' button will duplicate ABS and save it as ABS_black.  The 'Delete Profile' button deletes the selected profile.
-
-The profile selection is the setting.  If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved.  However; adding and deleting a profile is a permanent action, for example 'Cancel' will not bring back any deleted profiles.
-
-To change the extrusion profile, in a shell in the profile_plugins folder type:
-> python extrusion.py
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftSequence():
-       'Get the extrusion craft sequence.'
-       return 'carve scale bottom preface widen inset fill multiply speed temperature raft skirt chamber tower jitter clip smooth stretch skin joris comb cool hop wipe oozebane dwindle splodge home lash fillet limit unpause dimension alteration export'.split()
-
-def getNewRepository():
-       'Get new repository.'
-       return ExtrusionRepository()
-
-
-class ExtrusionRepository(object):
-       'A class to handle the export settings.'
-       def __init__(self):
-               'Set the default settings, execute title & settings fileName.'
-               skeinforge_profile.addListsSetCraftProfile( getCraftSequence(), 'ABS', self, 'skeinforge_application.skeinforge_plugins.profile_plugins.extrusion.html')
-
-
-def main():
-       'Display the export dialog.'
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == '__main__':
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/profile_plugins/milling.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/profile_plugins/milling.py
deleted file mode 100644 (file)
index 5d39eed..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-"""
-This page is in the table of contents.
-Milling is a script to set the milling profile for the skeinforge chain.
-
-The displayed craft sequence is the sequence in which the tools craft the model and export the output.
-
-On the milling dialog, clicking the 'Add Profile' button will duplicate the selected profile and give it the name in the input field.  For example, if laser is selected and the name laser_10mm is in the input field, clicking the 'Add Profile' button will duplicate laser and save it as laser_10mm.  The 'Delete Profile' button deletes the selected profile.
-
-The profile selection is the setting.  If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved.  However; adding and deleting a profile is a permanent action, for example 'Cancel' will not bring back any deleted profiles.
-
-To change the milling profile, in a shell in the profile_plugins folder type:
-> python milling.py
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftSequence():
-       "Get the milling craft sequence."
-       return 'chop preface outset mill multiply drill lift flow feed home lash fillet limit unpause alteration export'.split()
-
-def getNewRepository():
-       'Get new repository.'
-       return MillingRepository()
-
-
-class MillingRepository(object):
-       "A class to handle the milling settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsSetCraftProfile( getCraftSequence(), 'end_mill', self, 'skeinforge_application.skeinforge_plugins.profile_plugins.milling.html')
-
-
-def main():
-       "Display the export dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/profile_plugins/winding.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_plugins/profile_plugins/winding.py
deleted file mode 100644 (file)
index 30949c7..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-"""
-This page is in the table of contents.
-Winding is a script to set the winding profile for the skeinforge chain.
-
-The displayed craft sequence is the sequence in which the tools craft the model and export the output.
-
-On the winding dialog, clicking the 'Add Profile' button will duplicate the selected profile and give it the name in the input field.  For example, if laser is selected and the name laser_10mm is in the input field, clicking the 'Add Profile' button will duplicate laser and save it as laser_10mm.  The 'Delete Profile' button deletes the selected profile.
-
-The profile selection is the setting.  If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved.  However; adding and deleting a profile is a permanent action, for example 'Cancel' will not bring back any deleted profiles.
-
-To change the winding profile, in a shell in the profile_plugins folder type:
-> python winding.py
-
-"""
-
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getCraftSequence():
-       "Get the winding craft sequence."
-       return 'cleave preface coil flow feed home lash fillet limit unpause alteration export'.split()
-
-def getNewRepository():
-       'Get new repository.'
-       return WindingRepository()
-
-
-class WindingRepository(object):
-       "A class to handle the winding settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsSetCraftProfile( getCraftSequence(), 'free_wire', self, 'skeinforge_application.skeinforge_plugins.profile_plugins.winding.html')
-
-
-def main():
-       "Display the export dialog."
-       if len(sys.argv) > 1:
-               writeOutput(' '.join(sys.argv[1 :]))
-       else:
-               settings.startMainLoopFromConstructor(getNewRepository())
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/__init__.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/skeinforge_analyze.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/skeinforge_analyze.py
deleted file mode 100644 (file)
index 1927eae..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-"""
-Analyze is a script to access the plugins which analyze a gcode file.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import sys
-import traceback
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getNewRepository():
-       'Get new repository.'
-       return AnalyzeRepository()
-
-def getPluginFileNames():
-       "Get analyze plugin fileNames."
-       return archive.getPluginFileNamesFromDirectoryPath( getPluginsDirectoryPath() )
-
-def getPluginsDirectoryPath():
-       "Get the plugins directory path."
-       return archive.getAnalyzePluginsDirectoryPath()
-
-def writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText=''):
-       "Analyze a gcode file."
-       gcodeText = archive.getTextIfEmpty(fileName, gcodeText)
-       pluginFileNames = getPluginFileNames()
-       window = None
-       for pluginFileName in pluginFileNames:
-               analyzePluginsDirectoryPath = getPluginsDirectoryPath()
-               pluginModule = archive.getModuleWithDirectoryPath( analyzePluginsDirectoryPath, pluginFileName )
-               if pluginModule != None:
-                       try:
-                               newWindow = pluginModule.writeOutput(fileName, fileNamePenultimate, fileNameSuffix,
-                                       filePenultimateWritten, gcodeText )
-                               if newWindow != None:
-                                       window = newWindow
-                       except:
-                               print('Warning, the tool %s could not analyze the output.' % pluginFileName )
-                               print('Exception traceback in writeOutput in skeinforge_analyze:')
-                               traceback.print_exc(file=sys.stdout)
-       return window
-
-
-class AnalyzeRepository(object):
-       "A class to handle the analyze settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_utilities.skeinforge_analyze.html', self)
-               self.fileNameInput = settings.FileNameInput().getFromFileName( [ ('Gcode text files', '*.gcode') ], 'Open File for Analyze', self, '')
-               importantFileNames = ['skeiniso', 'skeinlayer', 'statistic']
-               settings.getRadioPluginsAddPluginFrame( getPluginsDirectoryPath(), importantFileNames, getPluginFileNames(), self )
-               self.executeTitle = 'Analyze'
-
-       def execute(self):
-               "Analyze button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode( self.fileNameInput.value, [], self.fileNameInput.wasCancelled )
-               for fileName in fileNames:
-                       writeOutput( fileName, fileName )
-
-
-def main():
-       "Write analyze output."
-       fileName = ' '.join(sys.argv[1 :])
-       settings.startMainLoopFromWindow(writeOutput(fileName, fileName))
-
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/skeinforge_craft.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/skeinforge_craft.py
deleted file mode 100644 (file)
index 6135785..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-"""
-Craft is a script to access the plugins which craft a gcode file.
-
-The plugin buttons which are commonly used are bolded and the ones which are rarely used have normal font weight.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import euclidean
-from fabmetheus_utilities import gcodec
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_analyze
-from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-import os
-import sys
-import time
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getChainText( fileName, procedure ):
-       "Get a crafted shape file."
-       text=''
-       if fileName.endswith('.gcode') or fileName.endswith('.svg'):
-               text = archive.getFileText(fileName)
-       procedures = getProcedures( procedure, text )
-       return getChainTextFromProcedures( fileName, procedures, text )
-
-def getChainTextFromProcedures(fileName, procedures, text):
-       'Get a crafted shape file from a list of procedures.'
-       lastProcedureTime = time.time()
-       for procedure in procedures:
-               craftModule = getCraftModule(procedure)
-               if craftModule != None:
-                       text = craftModule.getCraftedText(fileName, text)
-                       if text == '':
-                               print('Warning, the text was not recognized in getChainTextFromProcedures in skeinforge_craft for')
-                               print(fileName)
-                               return ''
-                       if gcodec.isProcedureDone( text, procedure ):
-                               print('%s procedure took %s (%d).' % (procedure.capitalize(), euclidean.getDurationString(time.time() - lastProcedureTime), len(text)))
-                               lastProcedureTime = time.time()
-       return text
-
-def getCraftModule(pluginName):
-       'Get craft module.'
-       return archive.getModuleWithDirectoryPath(getPluginsDirectoryPath(), pluginName)
-
-def getCraftPreferences(pluginName):
-       'Get craft preferences.'
-       return settings.getReadRepository(getCraftModule(pluginName).getNewRepository()).preferences
-
-def getCraftValue(preferenceName, preferences):
-       "Get craft preferences value."
-       for preference in preferences:
-               if preference.name.startswith(preferenceName):
-                       return preference.value
-       return None
-
-def getLastModule():
-       "Get the last tool."
-       craftSequence = getReadCraftSequence()
-       if len( craftSequence ) < 1:
-               return None
-       return getCraftModule( craftSequence[-1] )
-
-def getNewRepository():
-       'Get new repository.'
-       return CraftRepository()
-
-def getPluginFileNames():
-       "Get craft plugin fileNames."
-       craftSequence = getReadCraftSequence()
-       craftSequence.sort()
-       return craftSequence
-
-def getPluginsDirectoryPath():
-       "Get the plugins directory path."
-       return archive.getCraftPluginsDirectoryPath()
-
-def getProcedures(procedure, text):
-       'Get the procedures up to and including the given procedure.'
-       craftSequence = getReadCraftSequence()
-       sequenceIndexFromProcedure = 0
-       if procedure in craftSequence:
-               sequenceIndexFromProcedure = craftSequence.index(procedure)
-       craftSequence = craftSequence[: sequenceIndexFromProcedure + 1]
-       for craftSequenceIndex in xrange(len(craftSequence) - 1, -1, -1):
-               procedure = craftSequence[craftSequenceIndex]
-               if gcodec.isProcedureDone(text, procedure):
-                       return craftSequence[craftSequenceIndex + 1 :]
-       return craftSequence
-
-def getReadCraftSequence():
-       "Get profile sequence."
-       return skeinforge_profile.getCraftTypePluginModule().getCraftSequence()
-
-def writeChainTextWithNounMessage(fileName, procedure, shouldAnalyze=True):
-       'Get and write a crafted shape file.'
-       print('')
-       print('The %s tool is parsing the file:' % procedure)
-       print(os.path.basename(fileName))
-       print('')
-       startTime = time.time()
-       fileNameSuffix = fileName[: fileName.rfind('.')] + '_' + procedure + '.gcode'
-       craftText = getChainText(fileName, procedure)
-       if craftText == '':
-               print('Warning, there was no text output in writeChainTextWithNounMessage in skeinforge_craft for:')
-               print(fileName)
-               return
-       archive.writeFileText(fileNameSuffix, craftText)
-       window = None
-       if shouldAnalyze:
-               window = skeinforge_analyze.writeOutput(fileName, fileNameSuffix, fileNameSuffix, True, craftText)
-       print('')
-       print('The %s tool has created the file:' % procedure)
-       print(fileNameSuffix)
-       print('')
-       print('It took %s to craft the file.' % euclidean.getDurationString(time.time() - startTime))
-       return window
-
-def writeOutput(fileName, shouldAnalyze=True):
-       "Craft a gcode file with the last module."
-       pluginModule = getLastModule()
-       if pluginModule != None:
-               return pluginModule.writeOutput(fileName, shouldAnalyze)
-
-def writeSVGTextWithNounMessage(fileName, repository, shouldAnalyze=True):
-       'Get and write an svg text and print messages.'
-       print('')
-       print('The %s tool is parsing the file:' % repository.lowerName)
-       print(os.path.basename(fileName))
-       print('')
-       startTime = time.time()
-       fileNameSuffix = fileName[: fileName.rfind('.')] + '_' + repository.lowerName + '.svg'
-       craftText = getChainText(fileName, repository.lowerName)
-       if craftText == '':
-               return
-       archive.writeFileText(fileNameSuffix, craftText)
-       print('')
-       print('The %s tool has created the file:' % repository.lowerName)
-       print(fileNameSuffix)
-       print('')
-       print('It took %s to craft the file.' % euclidean.getDurationString(time.time() - startTime))
-       if shouldAnalyze:
-               settings.getReadRepository(repository)
-               settings.openSVGPage(fileNameSuffix, repository.svgViewer.value)
-
-
-class CraftRadioButtonsSaveListener(object):
-       "A class to update the craft radio buttons."
-       def addToDialog( self, gridPosition ):
-               "Add this to the dialog."
-               euclidean.addElementToListDictionaryIfNotThere( self, self.repository.repositoryDialog, settings.globalProfileSaveListenerListTable )
-               self.gridPosition = gridPosition.getCopy()
-               self.gridPosition.row = gridPosition.rowStart
-               self.gridPosition.increment()
-               self.setRadioButtons()
-
-       def getFromRadioPlugins( self, radioPlugins, repository ):
-               "Initialize."
-               self.name = 'CraftRadioButtonsSaveListener'
-               self.radioPlugins = radioPlugins
-               self.repository = repository
-               repository.displayEntities.append(self)
-               return self
-
-       def save(self):
-               "Profile has been saved and craft radio plugins should be updated."
-               self.setRadioButtons()
-
-       def setRadioButtons(self):
-               "Profile has been saved and craft radio plugins should be updated."
-               activeRadioPlugins = []
-               craftSequence = skeinforge_profile.getCraftTypePluginModule().getCraftSequence()
-               gridPosition = self.gridPosition.getCopy()
-               isRadioPluginSelected = False
-               settings.getReadRepository(self.repository)
-               for radioPlugin in self.radioPlugins:
-                       if radioPlugin.name in craftSequence:
-                               activeRadioPlugins.append(radioPlugin)
-                               radioPlugin.incrementGridPosition(gridPosition)
-                               if radioPlugin.value:
-                                       radioPlugin.setSelect()
-                                       isRadioPluginSelected = True
-                       else:
-                               radioPlugin.radiobutton.grid_remove()
-               if not isRadioPluginSelected:
-                       radioPluginNames = self.repository.importantFileNames + [activeRadioPlugins[0].name]
-                       settings.getSelectedRadioPlugin(radioPluginNames , activeRadioPlugins).setSelect()
-               self.repository.pluginFrame.update()
-
-
-class CraftRepository(object):
-       "A class to handle the craft settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_utilities.skeinforge_craft.html', self)
-               self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Craft', self, '')
-               self.importantFileNames = ['carve', 'chop', 'feed', 'flow', 'lift', 'raft', 'speed']
-               allCraftNames = archive.getPluginFileNamesFromDirectoryPath(getPluginsDirectoryPath())
-               self.radioPlugins = settings.getRadioPluginsAddPluginFrame(getPluginsDirectoryPath(), self.importantFileNames, allCraftNames, self)
-               CraftRadioButtonsSaveListener().getFromRadioPlugins(self.radioPlugins, self)
-               self.executeTitle = 'Craft'
-
-       def execute(self):
-               "Craft button has been clicked."
-               fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode( self.fileNameInput.value, [], self.fileNameInput.wasCancelled )
-               for fileName in fileNames:
-                       writeOutput(fileName)
-
-
-def main():
-       "Write craft output."
-       writeOutput(' '.join(sys.argv[1 :]), False)
-
-if __name__ == "__main__":
-       main()
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/skeinforge_help.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/skeinforge_help.py
deleted file mode 100644 (file)
index a7f0791..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-"""
-Help has buttons and menu items to open help, blog and forum pages in your primary browser.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getNewRepository():
-       'Get new repository.'
-       return HelpRepository()
-
-
-class HelpRepository(object):
-       "A class to handle the help settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_utilities.skeinforge_help.html', self)
-               announcementsText = '- Announcements -                                                                                                                          '
-               announcementsLabel = settings.LabelDisplay().getFromName(announcementsText, self )
-               announcementsLabel.columnspan = 6
-               settings.LabelDisplay().getFromName('Fabmetheus Blog, Announcements & Questions:', self )
-               settings.HelpPage().getFromNameAfterHTTP('fabmetheus.blogspot.com/', 'Fabmetheus Blog', self )
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Documentation -', self )
-               settings.LabelDisplay().getFromName('Local Documentation Table of Contents: ', self )
-               settings.HelpPage().getFromNameSubName('Contents', self, 'contents.html')
-               settings.LabelDisplay().getFromName('Wiki Manual with Pictures & Charts: ', self )
-               settings.HelpPage().getFromNameAfterHTTP('fabmetheus.crsndoo.com/wiki/index.php/Skeinforge', 'Wiki Manual', self )
-               settings.LabelDisplay().getFromName('Skeinforge Overview: ', self )
-               settings.HelpPage().getFromNameSubName('Skeinforge Overview', self, 'skeinforge_application.skeinforge.html')
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Search -', self )
-               settings.LabelDisplay().getFromName('Reprap Search:', self )
-               settings.HelpPage().getFromNameAfterHTTP('members.axion.net/~enrique/search_reprap.html', 'Reprap Search', self )
-               settings.LabelDisplay().getFromName('Skeinforge Search:', self )
-               settings.HelpPage().getFromNameAfterHTTP('members.axion.net/~enrique/search_skeinforge.html', 'Skeinforge Search', self )
-               settings.LabelDisplay().getFromName('Web Search:', self )
-               settings.HelpPage().getFromNameAfterHTTP('members.axion.net/~enrique/search_web.html', 'Web Search', self )
-               settings.LabelSeparator().getFromRepository(self)
-               settings.LabelDisplay().getFromName('- Troubleshooting -', self )
-               settings.LabelDisplay().getFromName('Skeinforge Forum:', self)
-               settings.HelpPage().getFromNameAfterHTTP('forums.reprap.org/list.php?154', '    Skeinforge Forum    ', self )
-               settings.LabelSeparator().getFromRepository(self)
-               self.version = settings.LabelDisplay().getFromName('Version: ' + archive.getFileText(archive.getVersionFileName()), self)
-               self.wikiManualPrimary = settings.BooleanSetting().getFromValue('Wiki Manual Primary', self, True )
-               self.wikiManualPrimary.setUpdateFunction( self.save )
-
-       def save(self):
-               "Write the entities."
-               settings.writeSettingsPrintMessage(self)
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/skeinforge_meta.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/skeinforge_meta.py
deleted file mode 100644 (file)
index 4c9f59b..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-"""
-Meta is a script to access the plugins which handle meta information.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getNewRepository():
-       'Get new repository.'
-       return MetaRepository()
-
-def getPluginFileNames():
-       "Get meta plugin file names."
-       return archive.getPluginFileNamesFromDirectoryPath( getPluginsDirectoryPath() )
-
-def getPluginsDirectoryPath():
-       "Get the plugins directory path."
-       return archive.getSkeinforgePluginsPath('meta_plugins')
-
-
-class MetaRepository(object):
-       "A class to handle the meta settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_utilities.skeinforge_meta.html', self)
-               importantFileNames = ['polyfile']
-               settings.getRadioPluginsAddPluginFrame( getPluginsDirectoryPath(), importantFileNames, getPluginFileNames(), self )
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/skeinforge_polyfile.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/skeinforge_polyfile.py
deleted file mode 100644 (file)
index 19ac696..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-"""
-Polyfile is a script to choose whether the skeinforge toolchain will operate on one file or all the files in a directory.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import archive
-from fabmetheus_utilities import settings
-from skeinforge_application.skeinforge_utilities import skeinforge_profile
-
-
-__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
-__date__ = '$Date: 2008/21/04 $'
-__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
-
-
-def getFileOrDirectoryTypes( fileName, fileTypes, wasCancelled ):
-       "Get the gcode files in the directory the file is in if directory setting is true.  Otherwise, return the file in a list."
-       if isEmptyOrCancelled( fileName, wasCancelled ):
-               return []
-       if isDirectorySetting():
-               return archive.getFilesWithFileTypesWithoutWords( fileTypes, [], fileName )
-       return [ fileName ]
-
-def getFileOrDirectoryTypesUnmodifiedGcode(fileName, fileTypes, wasCancelled):
-       "Get the gcode files in the directory the file is in if directory setting is true.  Otherwise, return the file in a list."
-       if isEmptyOrCancelled(fileName, wasCancelled):
-               return []
-       if isDirectorySetting():
-               return archive.getFilesWithFileTypesWithoutWords(fileTypes, [], fileName)
-       return [fileName]
-
-def getFileOrGcodeDirectory( fileName, wasCancelled, words = [] ):
-       "Get the gcode files in the directory the file is in if directory setting is true.  Otherwise, return the file in a list."
-       if isEmptyOrCancelled( fileName, wasCancelled ):
-               return []
-       if isDirectorySetting():
-               dotIndex = fileName.rfind('.')
-               if dotIndex < 0:
-                       print('The file name should have a suffix, like myfile.xml.')
-                       print('Since the file name does not have a suffix, nothing will be done')
-               suffix = fileName[ dotIndex + 1 : ]
-               return archive.getFilesWithFileTypeWithoutWords( suffix, words, fileName )
-       return [ fileName ]
-
-def getNewRepository():
-       'Get new repository.'
-       return PolyfileRepository()
-
-def isDirectorySetting():
-       "Determine if the directory setting is true."
-       return settings.getReadRepository( PolyfileRepository() ).directorySetting.value
-
-def isEmptyOrCancelled( fileName, wasCancelled ):
-       "Determine if the fileName is empty or the dialog was cancelled."
-       return str(fileName) == '' or str(fileName) == '()' or wasCancelled
-
-
-class PolyfileRepository(object):
-       "A class to handle the polyfile settings."
-       def __init__(self):
-               "Set the default settings, execute title & settings fileName."
-               skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_utilities.skeinforge_polyfile.html', self)
-               self.directoryOrFileChoiceLabel = settings.LabelDisplay().getFromName('Directory or File Choice: ', self )
-               directoryLatentStringVar = settings.LatentStringVar()
-               self.directorySetting = settings.Radio().getFromRadio( directoryLatentStringVar, 'Execute All Unmodified Files in a Directory', self, False )
-               self.fileSetting = settings.Radio().getFromRadio( directoryLatentStringVar, 'Execute File', self, True )
diff --git a/Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/skeinforge_profile.py b/Cura/slice/cura_sf/skeinforge_application/skeinforge_utilities/skeinforge_profile.py
deleted file mode 100644 (file)
index 9d4a43a..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-"""
-Profile is a script to set the craft types setting for the skeinforge chain.
-
-Profile presents the user with a choice of the craft types in the profile_plugins folder.  The chosen craft type is used to determine the craft type profile for the skeinforge chain.  The default craft type is extrusion.
-
-"""
-
-from __future__ import absolute_import
-
-from fabmetheus_utilities import archive
-
-def getCraftTypeName():
-       return 'extrusion'
-
-def getProfileName(craftTypeName):
-       return 'Cura profile:' + craftTypeName
-
-def addListsToCraftTypeRepository(fileNameHelp, repository):
-       #print('addListsToCraftTypeRepository:', fileNameHelp, repository)
-       repository.name = fileNameHelp.split('.')[-2]
-       repository.preferences = []
-
-def getCraftTypePluginModule( craftTypeName = ''):
-       "Get the craft type plugin module"
-       if craftTypeName == '':
-               craftTypeName = getCraftTypeName()
-       profilePluginsDirectoryPath = getPluginsDirectoryPath()
-       return archive.getModuleWithDirectoryPath( profilePluginsDirectoryPath, craftTypeName )
-
-def getPluginsDirectoryPath():
-       "Get the plugins directory path."
-       return archive.getSkeinforgePluginsPath('profile_plugins')
-
index 9d4746119376527f87c642061264941c25a961ae..1070cb76ce8eb2b42c89a3151d3a25ceedf73e6e 100644 (file)
@@ -22,8 +22,18 @@ class Scene():
                self._objectList.remove(obj)
 
        def pushFree(self):
+               n = 1000
                while self._pushFree():
-                       pass
+                       n -= 1
+                       if n < 0:
+                               return
+
+       def arrangeAll(self):
+               oldList = self._objectList
+               self._objectList = []
+               for obj in oldList:
+                       obj.setPosition(numpy.array([0,0], numpy.float32))
+                       self.add(obj)
 
        def _pushFree(self):
                for a in self._objectList:
index 8fa7f19affcfd05fa750481083450e0fd20984d3..3810fe92e1f20671a84bcaa3b29254fa925fd251 100644 (file)
@@ -124,7 +124,7 @@ setting('print_temperature2',          0, int,   'basic',    'Speed & Temperatur
 setting('print_temperature3',          0, int,   'basic',    'Speed & Temperature').setRange(0,340).setLabel('3th nozzle temperature (C)', 'Temperature used for printing. Set at 0 to pre-heat yourself.\nFor PLA a value of 210C is usually used.\nFor ABS a value of 230C or higher is required.')
 setting('print_temperature4',          0, int,   'basic',    'Speed & Temperature').setRange(0,340).setLabel('4th nozzle temperature (C)', 'Temperature used for printing. Set at 0 to pre-heat yourself.\nFor PLA a value of 210C is usually used.\nFor ABS a value of 230C or higher is required.')
 setting('print_bed_temperature',      70, int,   'basic',    'Speed & Temperature').setRange(0,340).setLabel('Bed temperature (C)', 'Temperature used for the heated printer bed. Set at 0 to pre-heat yourself.')
-setting('support',                'None', ['None', 'Touching buildplate', 'Everywhere'], 'Basic', 'Support structure').setLabel('Support type', 'Type of support structure build.\n"Exterior only" is the most commonly used support setting.\n\nNone does not do any support.\nTouching buildplate only creates support where the support structure will touch the build platform.\nEverywhere creates support even on top of parts of the model.')
+setting('support',                'None', ['None', 'Touching buildplate', 'Everywhere'], 'basic', 'Support').setLabel('Support type', 'Type of support structure build.\n"Exterior only" is the most commonly used support setting.\n\nNone does not do any support.\nTouching buildplate only creates support where the support structure will touch the build platform.\nEverywhere creates support even on top of parts of the model.')
 setting('enable_raft',             False, bool,  'basic',   'Support').setLabel('Enable raft', 'A raft is a few layers of lines below the bottom of the object. It prevents warping. Full raft settings can be found in the expert settings.\nFor PLA this is usually not required. But if you print with ABS it is almost required.')
 setting('support_dual_extrusion',  False, bool, 'basic', 'Support').setLabel('Support dual extrusion', 'Print the support material with the 2nd extruder in a dual extrusion setup. The primary extruder will be used for normal material, while the second extruder is used to print support material.')
 setting('filament_diameter',        2.89, float, 'basic',    'Filament').setRange(1).setLabel('Diameter (mm)', 'Diameter of your filament, as accurately as possible.\nIf you cannot measure this value you will have to calibrate it, a higher number means less extrusion, a smaller number generates more extrusion.')
@@ -132,10 +132,10 @@ setting('filament_diameter2',          0, float, 'basic',    'Filament').setRang
 setting('filament_diameter3',          0, float, 'basic',    'Filament').setRange(0).setLabel('Diameter3 (mm)', 'Diameter of your filament for the 3th nozzle. Use 0 to use the same diameter as for nozzle 1.')
 setting('filament_diameter4',          0, float, 'basic',    'Filament').setRange(0).setLabel('Diameter4 (mm)', 'Diameter of your filament for the 4th nozzle. Use 0 to use the same diameter as for nozzle 1.')
 setting('filament_density',         1.00, float, 'basic',    'Filament').setRange(0.5,1.5).setLabel('Packing Density', 'Packing density of your filament. This should be 1.00 for PLA and 0.85 for ABS')
-setting('retraction_min_travel',     5.0, float, 'advanced', 'Retraction').setRange(0).setLabel('Minimum travel (mm)', 'Minimum amount of travel needed for a retraction to happen at all. To make sure you do not get a lot of retractions in a small area')
+#setting('retraction_min_travel',     5.0, float, 'advanced', 'Retraction').setRange(0).setLabel('Minimum travel (mm)', 'Minimum amount of travel needed for a retraction to happen at all. To make sure you do not get a lot of retractions in a small area')
 setting('retraction_speed',         40.0, float, 'advanced', 'Retraction').setRange(0.1).setLabel('Speed (mm/s)', 'Speed at which the filament is retracted, a higher retraction speed works better. But a very high retraction speed can lead to filament grinding.')
 setting('retraction_amount',         4.5, float, 'advanced', 'Retraction').setRange(0).setLabel('Distance (mm)', 'Amount of retraction, set at 0 for no retraction at all. A value of 2.0mm seems to generate good results.')
-setting('retraction_extra',          0.0, float, 'advanced', 'Retraction').setRange(0).setLabel('Extra length on start (mm)', 'Extra extrusion amount when restarting after a retraction, to better "Prime" your extruder after retraction.')
+#setting('retraction_extra',          0.0, float, 'advanced', 'Retraction').setRange(0).setLabel('Extra length on start (mm)', 'Extra extrusion amount when restarting after a retraction, to better "Prime" your extruder after retraction.')
 setting('bottom_thickness',          0.3, float, 'advanced', 'Quality').setRange(0).setLabel('Initial layer thickness (mm)', 'Layer thickness of the bottom layer. A thicker bottom layer makes sticking to the bed easier. Set to 0.0 to have the bottom layer thickness the same as the other layers.')
 setting('object_sink',               0.0, float, 'advanced', 'Quality').setLabel('Cut off object bottom (mm)', 'Sinks the object into the platform, this can be used for objects that do not have a flat bottom and thus create a too small first layer.')
 setting('enable_skin',             False, bool,  'advanced', 'Quality').setLabel('Duplicate outlines', 'Skin prints the outer lines of the prints twice, each time with half the thickness. This gives the illusion of a higher print quality.')
diff --git a/Cura/util/sliceEngine.py b/Cura/util/sliceEngine.py
new file mode 100644 (file)
index 0000000..0a3b5a9
--- /dev/null
@@ -0,0 +1,117 @@
+import subprocess
+import time
+import numpy
+import os
+import warnings
+import threading
+
+from Cura.util import profile
+
+def getEngineFilename():
+       return 'C:/Software/Cura_SteamEngine/_bin/Release/Cura_SteamEngine.exe'
+
+def getTempFilename():
+       warnings.simplefilter('ignore')
+       ret = os.tempnam(None, "Cura_Tmp")
+       warnings.simplefilter('default')
+       return ret
+
+class Slicer(object):
+       def __init__(self, progressCallback):
+               self._process = None
+               self._thread = None
+               self._callback = progressCallback
+               self._binaryStorageFilename = getTempFilename()
+               self._exportFilename = getTempFilename()
+               self._progressSteps = ['inset', 'skin', 'export']
+
+       def abortSlicer(self):
+               if self._process is not None:
+                       self._process.terminate()
+                       self._thread.join()
+
+       def runSlicer(self, scene):
+               self.abortSlicer()
+               self._callback(0.0, False)
+
+               commandList = [getEngineFilename(), '-vv']
+               for k, v in self._engineSettings().iteritems():
+                       commandList += ['-s', '%s=%s' % (k, str(v))]
+               commandList += ['-o', self._exportFilename]
+               commandList += ['-b', self._binaryStorageFilename]
+               self._objCount = 0
+               with open(self._binaryStorageFilename, "wb") as f:
+                       for obj in scene._objectList:
+                               if not scene.checkPlatform(obj):
+                                       continue
+                               for mesh in obj._meshList:
+                                       n = numpy.array(mesh.vertexCount, numpy.int32)
+                                       f.write(n.tostring())
+                                       f.write(mesh.vertexes.tostring())
+                               pos = obj.getPosition() * 1000
+                               pos += numpy.array([profile.getPreferenceFloat('machine_width') * 1000 / 2, profile.getPreferenceFloat('machine_depth') * 1000 / 2])
+                               commandList += ['-s', 'posx=%d' % int(pos[0]), '-s', 'posy=%d' % int(pos[1]), '#']
+                               self._objCount += 1
+               if self._objCount > 0:
+                       print ' '.join(commandList)
+                       self._process = self._runSliceProcess(commandList)
+                       self._thread = threading.Thread(target=self._watchProcess)
+                       self._thread.daemon = True
+                       self._thread.start()
+
+       def _watchProcess(self):
+               self._callback(0.0, False)
+               line = self._process.stdout.readline()
+               while len(line):
+                       line = line.strip()
+                       if line.startswith('Progress:'):
+                               line = line.split(':')
+                               progressValue = float(line[2]) / float(line[3])
+                               progressValue /= len(self._progressSteps)
+                               progressValue += 1.0 / len(self._progressSteps) * self._progressSteps.index(line[1])
+                               self._callback(progressValue, False)
+                       else:
+                               print '#', line.strip()
+                       line = self._process.stdout.readline()
+               for line in self._process.stderr:
+                       print line.strip()
+               returnCode = self._process.wait()
+               print returnCode
+               if returnCode == 0:
+                       self._callback(1.0, True)
+               else:
+                       self._callback(0.0, False)
+               self._process = None
+
+       def _engineSettings(self):
+               return {
+                       'layerThickness': int(profile.getProfileSettingFloat('layer_height') * 1000),
+                       'initialLayerThickness': int(profile.getProfileSettingFloat('bottom_thickness') * 1000),
+                       'filamentDiameter': int(profile.getProfileSettingFloat('filament_diameter') * 1000),
+                       'extrusionWidth': int(profile.calculateEdgeWidth() * 1000),
+                       'insetCount': int(profile.calculateLineCount()),
+                       'downSkinCount': int(profile.calculateSolidLayerCount()),
+                       'upSkinCount': int(profile.calculateSolidLayerCount()),
+                       'sparseInfillLineDistance': int(100 * profile.calculateEdgeWidth() * 1000 / profile.getProfileSettingFloat('fill_density')),
+                       'skirtDistance': int(profile.getProfileSettingFloat('skirt_gap') * 1000),
+                       'skirtLineCount': int(profile.getProfileSettingFloat('skirt_line_count')),
+                       'initialSpeedupLayers': int(4),
+                       'initialLayerSpeed': int(profile.getProfileSettingFloat('bottom_layer_speed')),
+                       'printSpeed': int(profile.getProfileSettingFloat('print_speed')),
+                       'moveSpeed': int(profile.getProfileSettingFloat('travel_speed')),
+                       'fanOnLayerNr': int(profile.getProfileSettingFloat('fan_layer')),
+                       'supportAngle': int(-1) if profile.getProfileSetting('support') == 'None' else int(60),
+                       'supportEverywhere': int(1) if profile.getProfileSetting('support') == 'Everywhere' else int(0),
+                       'retractionAmount': int(profile.getProfileSettingFloat('retraction_amount') * 1000),
+                       'retractionSpeed': int(profile.getProfileSettingFloat('retraction_speed')),
+                       'objectSink': int(profile.getProfileSettingFloat('object_sink') * 1000),
+               }
+
+       def _runSliceProcess(self, cmdList):
+               kwargs = {}
+               if subprocess.mswindows:
+                       su = subprocess.STARTUPINFO()
+                       su.dwFlags |= subprocess.STARTF_USESHOWWINDOW
+                       su.wShowWindow = subprocess.SW_HIDE
+                       kwargs['startupinfo'] = su
+               return subprocess.Popen(cmdList, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)