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