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
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 gcodec
53 from fabmetheus_utilities import settings
54 from fabmetheus_utilities import svg_writer
55 from skeinforge_application.skeinforge_utilities import skeinforge_craft
56 from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
57 from skeinforge_application.skeinforge_utilities import skeinforge_profile
61 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
62 __date__ = '$Date: 2008/02/05 $'
63 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
66 def getCraftedText(fileName, svgText='', repository=None):
67 "Scale and convert an svg file or svgText."
68 return getCraftedTextFromText(fileName, archive.getTextIfEmpty(fileName, svgText), repository)
70 def getCraftedTextFromText(fileName, svgText, repository=None):
71 "Scale and convert an svgText."
72 if gcodec.isProcedureDoneOrFileIsEmpty(svgText, 'scale'):
74 if repository == None:
75 repository = settings.getReadRepository(ScaleRepository())
76 if repository.activateScale.value:
77 return ScaleSkein().getCraftedGcode(fileName, repository, svgText)
80 def getNewRepository():
82 return ScaleRepository()
84 def setLoopLayerScale(loopLayer, xyPlaneScale, zAxisScale):
85 "Set the slice element scale."
86 for loop in loopLayer.loops:
87 for pointIndex in xrange(len(loop)):
88 loop[pointIndex] *= xyPlaneScale
89 loopLayer.z *= zAxisScale
91 def writeOutput(fileName, shouldAnalyze=True):
93 skeinforge_craft.writeSVGTextWithNounMessage(fileName, ScaleRepository(), shouldAnalyze)
96 class ScaleRepository(object):
97 "A class to handle the scale settings."
99 "Set the default settings, execute title & settings fileName."
100 skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.scale.html', self )
101 self.fileNameInput = settings.FileNameInput().getFromFileName(fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Scale', self, '')
102 self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Scale')
103 self.activateScale = settings.BooleanSetting().getFromValue('Activate Scale', self, False)
104 self.xyPlaneScale = settings.FloatSpin().getFromValue(0.99, 'XY Plane Scale (ratio):', self, 1.03, 1.01)
105 self.zAxisScale = settings.FloatSpin().getFromValue(0.99, 'Z Axis Scale (ratio):', self, 1.02, 1.0)
106 self.svgViewer = settings.StringSetting().getFromValue('SVG Viewer:', self, 'webbrowser')
107 self.executeTitle = 'Scale'
110 "Scale 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)
116 class ScaleSkein(object):
117 "A class to scale a skein of extrusions."
118 def getCraftedGcode(self, fileName, repository, svgText):
119 "Parse svgText and store the scale 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 xyPlaneScale = repository.xyPlaneScale.value
126 zAxisScale = repository.zAxisScale.value
127 decimalPlacesCarried = int(svgReader.sliceDictionary['decimalPlacesCarried'])
128 layerHeight = zAxisScale * float(svgReader.sliceDictionary['layerHeight'])
129 edgeWidth = float(svgReader.sliceDictionary['edgeWidth'])
130 loopLayers = svgReader.loopLayers
131 for loopLayer in loopLayers:
132 setLoopLayerScale(loopLayer, xyPlaneScale, zAxisScale)
133 cornerMaximum = Vector3(-912345678.0, -912345678.0, -912345678.0)
134 cornerMinimum = Vector3(912345678.0, 912345678.0, 912345678.0)
135 svg_writer.setSVGCarvingCorners(cornerMaximum, cornerMinimum, layerHeight, loopLayers)
136 svgWriter = svg_writer.SVGWriter(
140 decimalPlacesCarried,
143 commentElement = svg_writer.getCommentElement(svgReader.documentElement)
144 procedureNameString = svgReader.sliceDictionary['procedureName'] + ',scale'
145 return svgWriter.getReplacedSVGTemplate(fileName, loopLayers, procedureNameString, commentElement)
149 "Display the scale dialog."
150 if len(sys.argv) > 1:
151 writeOutput(' '.join(sys.argv[1 :]))
153 settings.startMainLoopFromConstructor(getNewRepository())
155 if __name__ == "__main__":