3 This page is in the table of contents.
4 Bottom sets the bottom of the carving to the defined altitude.
6 The bottom manual page is at:
7 http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Bottom
10 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.
13 ===Additional Height over Layer Thickness===
16 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.
21 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.
24 Default is webbrowser.
26 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.
29 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.
32 This brings up the bottom dialog.
34 > python bottom.py Screw Holder Bottom.stl
35 The bottom tool is parsing the file:
36 Screw Holder Bottom.stl
38 The bottom tool has created the file:
39 .. Screw Holder Bottom_bottom.gcode
43 from __future__ import absolute_import
44 #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module.
47 from datetime import date
48 from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
49 from fabmetheus_utilities.svg_reader import SVGReader
50 from fabmetheus_utilities.vector3 import Vector3
51 from fabmetheus_utilities import archive
52 from fabmetheus_utilities import euclidean
53 from fabmetheus_utilities import gcodec
54 from fabmetheus_utilities import settings
55 from fabmetheus_utilities import svg_writer
56 from skeinforge_application.skeinforge_utilities import skeinforge_craft
57 from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
58 from skeinforge_application.skeinforge_utilities import skeinforge_profile
65 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
66 __date__ = '$Date: 2008/02/05 $'
67 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
70 def getCraftedText(fileName, svgText='', repository=None):
71 "Bottom and convert an svg file or svgText."
72 return getCraftedTextFromText(fileName, archive.getTextIfEmpty(fileName, svgText), repository)
74 def getCraftedTextFromText(fileName, svgText, repository=None):
75 "Bottom and convert an svgText."
76 if gcodec.isProcedureDoneOrFileIsEmpty(svgText, 'bottom'):
78 if repository == None:
79 repository = settings.getReadRepository(BottomRepository())
80 if not repository.activateBottom.value:
82 return BottomSkein().getCraftedGcode(fileName, repository, svgText)
84 def getNewRepository():
86 return BottomRepository()
88 def writeOutput(fileName, shouldAnalyze=True):
90 skeinforge_craft.writeSVGTextWithNounMessage(fileName, BottomRepository(), shouldAnalyze)
93 class BottomRepository:
94 "A class to handle the bottom settings."
96 "Set the default settings, execute title & settings fileName."
97 skeinforge_profile.addListsToCraftTypeRepository(
98 'skeinforge_application.skeinforge_plugins.craft_plugins.bottom.html', self)
99 self.fileNameInput = settings.FileNameInput().getFromFileName(
100 fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Bottom', self, '')
101 self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Bottom')
102 self.activateBottom = settings.BooleanSetting().getFromValue('Activate Bottom', self, True)
103 self.additionalHeightOverLayerThickness = settings.FloatSpin().getFromValue(
104 0.0, 'Additional Height over Layer Thickness (ratio):', self, 1.0, 0.5)
105 self.altitude = settings.FloatSpin().getFromValue(-1.0, 'Altitude (mm):', self, 1.0, 0.0)
106 self.svgViewer = settings.StringSetting().getFromValue('SVG Viewer:', self, 'webbrowser')
107 self.executeTitle = 'Bottom'
110 "Bottom button has been clicked."
111 fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
112 for fileName in fileNames:
113 writeOutput(fileName)
117 "A class to bottom a skein of extrusions."
118 def getCraftedGcode(self, fileName, repository, svgText):
119 "Parse svgText and store the bottom svgText."
120 svgReader = SVGReader()
121 svgReader.parseSVG('', svgText)
122 if svgReader.sliceDictionary == None:
123 print('Warning, nothing will be done because the sliceDictionary could not be found getCraftedGcode in preface.')
125 decimalPlacesCarried = int(svgReader.sliceDictionary['decimalPlacesCarried'])
126 edgeWidth = float(svgReader.sliceDictionary['edgeWidth'])
127 layerHeight = float(svgReader.sliceDictionary['layerHeight'])
128 loopLayers = svgReader.loopLayers
129 zMinimum = 987654321.0
130 for loopLayer in loopLayers:
131 zMinimum = min(loopLayer.z, zMinimum)
132 deltaZ = repository.altitude.value + repository.additionalHeightOverLayerThickness.value * layerHeight - zMinimum
133 for loopLayer in loopLayers:
134 loopLayer.z += deltaZ
135 cornerMaximum = Vector3(-912345678.0, -912345678.0, -912345678.0)
136 cornerMinimum = Vector3(912345678.0, 912345678.0, 912345678.0)
137 svg_writer.setSVGCarvingCorners(cornerMaximum, cornerMinimum, layerHeight, loopLayers)
138 svgWriter = svg_writer.SVGWriter(
142 decimalPlacesCarried,
145 commentElement = svg_writer.getCommentElement(svgReader.documentElement)
146 procedureNameString = svgReader.sliceDictionary['procedureName'] + ',bottom'
147 return svgWriter.getReplacedSVGTemplate(fileName, loopLayers, procedureNameString, commentElement)
151 "Display the bottom dialog."
152 if len(sys.argv) > 1:
153 writeOutput(' '.join(sys.argv[1 :]))
155 settings.startMainLoopFromConstructor(getNewRepository())
157 if __name__ == "__main__":