1 from __future__ import absolute_import
3 import platform, os, subprocess, sys
5 if not hasattr(sys, 'frozen'):
6 cura_sf_path = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../cura_sf/"))
7 if cura_sf_path not in sys.path:
8 sys.path.append(cura_sf_path)
9 from skeinforge_application.skeinforge_utilities import skeinforge_craft
11 from util import profile
13 #How long does each step take compared to the others. This is used to make a better scaled progress bar, and guess time left.
14 sliceStepTimeFactor = {
15 'start': 3.3713991642,
16 'slice': 15.4984838963,
17 'preface': 5.17178297043,
18 'inset': 116.362634182,
19 'fill': 215.702672005,
20 'multiply': 21.9536788464,
21 'speed': 12.759510994,
22 'raft': 31.4580039978,
23 'skirt': 19.3436040878,
27 'comb': 23.7805759907,
30 'dimension': 90.4914340973
33 totalRunTimeFactor = 0
34 for v in sliceStepTimeFactor.values():
35 totalRunTimeFactor += v
38 "Return the path to the pypy executable if we can find it. Else return False"
39 if platform.system() == "Windows":
41 pypyExe = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../pypy/pypy.exe"))
44 pypyExe = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../pypy/bin/pypy"))
45 if os.path.exists(pypyExe):
48 path = os.environ['PATH']
49 paths = path.split(os.pathsep)
51 pypyExe = os.path.join(p, exeName)
52 if os.path.exists(pypyExe):
57 "Return the path to the pypy executable if we can find it. Else return False"
58 if platform.system() == "Windows":
59 exeName = "slic3r.exe"
60 slic3rExe = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../Slic3r/bin/slic3r.exe"));
63 slic3rExe = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../Slic3r/bin/slic3r"));
64 if os.path.exists(slic3rExe):
67 path = os.environ['PATH']
68 paths = path.split(os.pathsep)
70 slic3rExe = os.path.join(p, exeName)
71 if os.path.exists(slic3rExe):
75 def runSlice(fileNames):
76 "Run the slicer on the files. If we are running with PyPy then just do the slicing action. If we are running as Python, try to find pypy."
77 pypyExe = getPyPyExe()
78 for fileName in fileNames:
79 if fileName.startswith("#UTF8#"):
80 fileName = unicode(fileName[6:], "utf-8")
81 if platform.python_implementation() == "PyPy":
82 skeinforge_craft.writeOutput(fileName)
83 elif pypyExe == False:
84 if not hasattr(sys, 'frozen'):
85 print("************************************************")
86 print("* Failed to find pypy, so slicing with python! *")
87 print("************************************************")
88 skeinforge_craft.writeOutput(fileName)
89 print("************************************************")
90 print("* Failed to find pypy, so sliced with python! *")
91 print("************************************************")
93 print("******************************************************************")
94 print("* Failed to find pypy, we need pypy to slice with a frozen build *")
95 print("* Place pypy in the same directory as Cura so Cura can find it. *")
96 print("******************************************************************")
99 subprocess.call(getSliceCommand(fileName))
101 def getExportFilename(filename, ext = "gcode"):
102 return "%s.%s" % (filename[: filename.rfind('.')], ext)
104 #Get a short filename in 8.3 format for proper saving on SD.
105 def getShortFilename(filename):
106 ext = filename[filename.rfind('.'):]
107 filename = filename[: filename.rfind('.')]
108 return filename[:8] + ext[:2]
110 def getSliceCommand(filename):
111 if profile.getPreference('slicer').startswith('Slic3r') and getSlic3rExe() != False:
112 slic3rExe = getSlic3rExe()
113 if slic3rExe == False:
116 '--output-filename-format', '[input_filename_base].gcode',
117 '--nozzle-diameter', str(profile.calculateEdgeWidth()),
118 '--print-center', '%s,%s' % (profile.getPreferenceFloat('machine_width') / 2, profile.getPreferenceFloat('machine_depth') / 2),
120 '--gcode-flavor', 'reprap',
122 '--filament-diameter', profile.getProfileSetting('filament_diameter'),
123 '--extrusion-multiplier', str(1.0 / float(profile.getProfileSetting('filament_density'))),
124 '--temperature', profile.getProfileSetting('print_temperature'),
125 '--travel-speed', profile.getProfileSetting('travel_speed'),
126 '--perimeter-speed', profile.getProfileSetting('print_speed'),
127 '--small-perimeter-speed', profile.getProfileSetting('print_speed'),
128 '--infill-speed', profile.getProfileSetting('print_speed'),
129 '--solid-infill-speed', profile.getProfileSetting('print_speed'),
130 '--bridge-speed', profile.getProfileSetting('print_speed'),
131 '--bottom-layer-speed-ratio', str(float(profile.getProfileSetting('bottom_layer_speed')) / float(profile.getProfileSetting('print_speed'))),
132 '--layer-height', profile.getProfileSetting('layer_height'),
133 '--first-layer-height-ratio', '1.0',
134 '--infill-every-layers', '1',
135 '--perimeters', str(profile.calculateLineCount()),
136 '--solid-layers', str(profile.calculateSolidLayerCount()),
137 '--fill-density', str(float(profile.getProfileSetting('fill_density'))/100),
138 '--fill-angle', '45',
139 '--fill-pattern', 'rectilinear', #rectilinear line concentric hilbertcurve archimedeanchords octagramspiral
140 '--solid-fill-pattern', 'rectilinear',
141 '--start-gcode', profile.getAlterationFilePath('start.gcode'),
142 '--end-gcode', profile.getAlterationFilePath('end.gcode'),
143 '--retract-length', profile.getProfileSetting('retraction_amount'),
144 '--retract-speed', str(int(float(profile.getProfileSetting('retraction_speed')))),
145 '--retract-restart-extra', profile.getProfileSetting('retraction_extra'),
146 '--retract-before-travel', profile.getProfileSetting('retraction_min_travel'),
147 '--retract-lift', '0',
148 '--slowdown-below-layer-time', profile.getProfileSetting('cool_min_layer_time'),
149 '--min-print-speed', profile.getProfileSetting('cool_min_feedrate'),
150 '--skirts', profile.getProfileSetting('skirt_line_count'),
151 '--skirt-distance', str(int(float(profile.getProfileSetting('skirt_gap')))),
152 '--skirt-height', '1',
153 '--scale', profile.getProfileSetting('model_scale'),
154 '--rotate', profile.getProfileSetting('model_rotate_base'),
155 '--duplicate-x', profile.getProfileSetting('model_multiply_x'),
156 '--duplicate-y', profile.getProfileSetting('model_multiply_y'),
157 '--duplicate-distance', '10']
158 if profile.getProfileSetting('support') != 'None':
159 cmd.extend(['--support-material'])
160 cmd.extend([filename])
163 pypyExe = getPyPyExe()
165 pypyExe = sys.executable
167 #In case we have a frozen exe, then argv[0] points to the executable, but we want to give pypy a real script file.
168 if hasattr(sys, 'frozen'):
169 mainScriptFile = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../..", "cura_sf.zip"))
171 mainScriptFile = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", os.path.split(sys.argv[0])[1]))
172 cmd = [pypyExe, mainScriptFile, '-p', profile.getGlobalProfileString(), '-s']
173 if platform.system() == "Windows":
175 cmd.append(str(filename))
176 except UnicodeEncodeError:
177 cmd.append("#UTF8#" + filename.encode("utf-8"))
182 def startSliceCommandProcess(cmdList):
184 if subprocess.mswindows:
185 su = subprocess.STARTUPINFO()
186 su.dwFlags |= subprocess.STARTF_USESHOWWINDOW
187 su.wShowWindow = subprocess.SW_HIDE
188 kwargs['startupinfo'] = su
189 return subprocess.Popen(cmdList, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)