/
Export2Slicer.FCMacro
103 lines (88 loc) · 3.68 KB
/
Export2Slicer.FCMacro
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# -*- coding: utf-8 -*-
# Opens current visible objects in Slic3r. One can use different slicing software
__Title__ = 'Export to Slicer'
__Author__ = 'Damian Łoziński'
__Version__ = '0.3'
__Date__ = '2022-12-16'
__Comment__ = 'Export selected objects to amf/stl files and open it in Slicer'
__Web__ = 'https://github.com/dlozinski/FreeCAD-macros/blob/doc/ImportExport/ExportToSlicer.md'
__Wiki__ = ''
__Icon__ = 'Export2Slicer.png'
__Help__ = 'You may need to change slicer path. To do so open Tools > Edit parameters > BaseApp/Preferences/Macros/Export2Slicer'
__Status__ = 'Stable'
__Requires__ = 'freecad 0.17+'
__Communication__ = 'lozinski dot d at gmail dot com'
__Files__ = 'Export2Slicer.png'
import os
import re
import subprocess
import Mesh
import MeshPart
import FreeCAD as app
MACRO_PARAMS_PATH = 'User parameter:BaseApp/Preferences/Macros/Export2Slicer'
DEFAULT_SLICER_PATH = '/Applications/Original Prusa Drivers/PrusaSlicer.app/Contents/MacOS/PrusaSlicer'
DEFAUL_MESH_FORMAT = 'stl'
DEFAULT_ANGULAR_DEFLECTION = 0.07
macro_params = app.ParamGet(MACRO_PARAMS_PATH)
# Slicing program executable. One can use different slicing software here and provide proper slicer executable location and custom flags
slicer_path = macro_params.GetString('SlicerPath')
if not slicer_path:
macro_params.SetString('SlicerPath', DEFAULT_SLICER_PATH)
slicer_path = DEFAULT_SLICER_PATH
output_format = macro_params.GetString('OutputFormat');
if not output_format:
macro_params.SetString('OutputFormat', DEFAUL_MESH_FORMAT)
output_format = DEFAUL_MESH_FORMAT
# Angular deflection in radians. Lower value = better quality of curved shapes and bigger file size
angular_deflection = macro_params.GetFloat('AngularDeflection')
if not angular_deflection:
macro_params.SetFloat('AngularDeflection', DEFAULT_ANGULAR_DEFLECTION)
angular_deflection = DEFAULT_ANGULAR_DEFLECTION
def escape(text):
return re.sub(r'\W', '_', text)
def get_mesh_filename(doc_filename, mesh_names):
'''Returns valid filename for temporary mesh file'''
if doc_filename:
dirname = os.path.dirname(doc_filename)
filename = (
os.path.basename(doc_filename).partition('.')[0]
+ '-'
+ escape('_'.join(mesh_names))
+ '.'
+ output_format)
file_path = os.path.join(dirname, filename)
else:
file_path = 'meshes-export.' + output_format
return file_path
def main():
doc = app.activeDocument()
if not doc:
raise RuntimeError('No active document')
objects_to_export = Gui.Selection.getSelection()
try:
# Create temporary doc to store meshes so that we don't affect current doc history
tmp_doc = app.newDocument('meshes')
meshes = []
mesh_names = []
for o in objects_to_export:
if o.TypeId == 'Mesh::Feature':
meshes.append(o)
else:
mesh = tmp_doc.addObject('Mesh::Feature', '{}_{}'.format(doc.Label, o.Label))
mesh.Mesh = MeshPart.meshFromShape(o.Shape, LinearDeflection=0.1, AngularDeflection=angular_deflection, Relative=False)
meshes.append(mesh)
mesh_names.append(o.Label)
if meshes:
mesh_path = get_mesh_filename(doc.FileName, mesh_names)
Mesh.export(meshes, mesh_path)
else:
raise RuntimeError('No object selected')
finally:
app.closeDocument('meshes')
# Launch Slicer with meshes
subprocess.Popen((slicer_path, mesh_path))
app.Console.PrintMessage('Export2Slicer: Objects exported: {}\n'.format(mesh_path))
try:
main()
except Exception as e:
app.Console.PrintError('Export2Slicer error: {}\n'.format(e))