3 This page is in the table of contents.
4 Scale scales the carving to compensate for shrinkage after the extrusion has cooled.
6 The scale manual page is at:
8 http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Scale
10 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.
13 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.
19 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.
24 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.
27 Default is webbrowser.
29 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.
32 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.
35 This brings up the scale dialog.
37 > python scale.py Screw Holder Bottom.stl
38 The scale tool is parsing the file:
39 Screw Holder Bottom.stl
41 The scale tool has created the file:
42 .. Screw Holder Bottom_scale.gcode
46 from __future__ import absolute_import
47 #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.
50 from datetime import date
51 from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
52 from fabmetheus_utilities.svg_reader import SVGReader
53 from fabmetheus_utilities.vector3 import Vector3
54 from fabmetheus_utilities import archive
55 from fabmetheus_utilities import euclidean
56 from fabmetheus_utilities import gcodec
57 from fabmetheus_utilities import settings
58 from fabmetheus_utilities import svg_writer
59 from skeinforge_application.skeinforge_utilities import skeinforge_craft
60 from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
61 from skeinforge_application.skeinforge_utilities import skeinforge_profile
68 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
69 __date__ = '$Date: 2008/02/05 $'
70 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
73 def getCraftedText(fileName, svgText='', repository=None):
74 "Scale and convert an svg file or svgText."
75 return getCraftedTextFromText(fileName, archive.getTextIfEmpty(fileName, svgText), repository)
77 def getCraftedTextFromText(fileName, svgText, repository=None):
78 "Scale and convert an svgText."
79 if gcodec.isProcedureDoneOrFileIsEmpty(svgText, 'scale'):
81 if repository == None:
82 repository = settings.getReadRepository(ScaleRepository())
83 if repository.activateScale.value:
84 return ScaleSkein().getCraftedGcode(fileName, repository, svgText)
87 def getNewRepository():
89 return ScaleRepository()
91 def setLoopLayerScale(loopLayer, xyPlaneScale, zAxisScale):
92 "Set the slice element scale."
93 for loop in loopLayer.loops:
94 for pointIndex in xrange(len(loop)):
95 loop[pointIndex] *= xyPlaneScale
96 loopLayer.z *= zAxisScale
98 def writeOutput(fileName, shouldAnalyze=True):
100 skeinforge_craft.writeSVGTextWithNounMessage(fileName, ScaleRepository(), shouldAnalyze)
103 class ScaleRepository:
104 "A class to handle the scale settings."
106 "Set the default settings, execute title & settings fileName."
107 skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.scale.html', self )
108 self.fileNameInput = settings.FileNameInput().getFromFileName(fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Scale', self, '')
109 self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Scale')
110 self.activateScale = settings.BooleanSetting().getFromValue('Activate Scale', self, False)
111 self.xyPlaneScale = settings.FloatSpin().getFromValue(0.99, 'XY Plane Scale (ratio):', self, 1.03, 1.01)
112 self.zAxisScale = settings.FloatSpin().getFromValue(0.99, 'Z Axis Scale (ratio):', self, 1.02, 1.0)
113 self.svgViewer = settings.StringSetting().getFromValue('SVG Viewer:', self, 'webbrowser')
114 self.executeTitle = 'Scale'
117 "Scale button has been clicked."
118 fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
119 for fileName in fileNames:
120 writeOutput(fileName)
124 "A class to scale a skein of extrusions."
125 def getCraftedGcode(self, fileName, repository, svgText):
126 "Parse svgText and store the scale svgText."
127 svgReader = SVGReader()
128 svgReader.parseSVG('', svgText)
129 if svgReader.sliceDictionary == None:
130 print('Warning, nothing will be done because the sliceDictionary could not be found getCraftedGcode in preface.')
132 xyPlaneScale = repository.xyPlaneScale.value
133 zAxisScale = repository.zAxisScale.value
134 decimalPlacesCarried = int(svgReader.sliceDictionary['decimalPlacesCarried'])
135 layerHeight = zAxisScale * float(svgReader.sliceDictionary['layerHeight'])
136 edgeWidth = float(svgReader.sliceDictionary['edgeWidth'])
137 loopLayers = svgReader.loopLayers
138 for loopLayer in loopLayers:
139 setLoopLayerScale(loopLayer, xyPlaneScale, zAxisScale)
140 cornerMaximum = Vector3(-912345678.0, -912345678.0, -912345678.0)
141 cornerMinimum = Vector3(912345678.0, 912345678.0, 912345678.0)
142 svg_writer.setSVGCarvingCorners(cornerMaximum, cornerMinimum, layerHeight, loopLayers)
143 svgWriter = svg_writer.SVGWriter(
147 decimalPlacesCarried,
150 commentElement = svg_writer.getCommentElement(svgReader.documentElement)
151 procedureNameString = svgReader.sliceDictionary['procedureName'] + ',scale'
152 return svgWriter.getReplacedSVGTemplate(fileName, loopLayers, procedureNameString, commentElement)
156 "Display the scale dialog."
157 if len(sys.argv) > 1:
158 writeOutput(' '.join(sys.argv[1 :]))
160 settings.startMainLoopFromConstructor(getNewRepository())
162 if __name__ == "__main__":