-
Notifications
You must be signed in to change notification settings - Fork 2
/
freecad_build.py
executable file
·160 lines (111 loc) · 4.44 KB
/
freecad_build.py
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import os.path
import sys
import FreeCAD
import Import
import Part
INCLUDE_SUBASSEMBLIES = False
PART_TYPEIDS = ('PartDesign::Body', 'App::Part', 'Part::Feature')
def auto_part_label(dest):
return '.'.join(os.path.basename(dest).split('.')[0:-1])
def has_part(o):
if o.TypeId == 'App::Link' and o.LinkedObject.TypeId in PART_TYPEIDS:
return True
if not o.Visibility:
return False
if o.TypeId in PART_TYPEIDS:
return True
return False
def find_labeled_part(doc, label):
print('### finding part with label', label)
found = doc.findObjects(Label=label)
if found:
print('### found labeled part')
return found[0]
return None
def find_parts(doc, label=None, max_parts=0):
parts = []
if label:
part = find_labeled_part(doc, label)
if part:
parts.append(part)
if not max_parts or len(parts) < max_parts:
print('### searching for usable parts...')
for o in doc.Objects:
#print('### checking', o.FullName, type(o), o.TypeId, o.Visibility)
#if hasattr(o, 'LinkedObject'):
if o.TypeId == 'App::Link':
print('### linked object', o.LinkedObject.FullName, type(o.LinkedObject),
o.LinkedObject.TypeId, o.LinkedObject.Visibility)
if o.LinkedObject.Name == 'Assembly':
print('### subassembly', o.LinkedObject.FullName)
if INCLUDE_SUBASSEMBLIES:
o.LinkedObject.Document.recompute()
parts.extend(find_parts(o.LinkedObject.Document))
if has_part(o):
parts.append(o)
if max_parts and len(parts) >= max_parts:
break
for part in parts:
print('### found usable part', part.FullName, part.TypeId)
if not parts:
print('### could not any usable parts in', path)
sys.exit(1)
return parts
def load_parts(path):
fmt = path.rpartition('.')[-1]
print('### loading document', path, fmt)
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Import/hSTEP").SetBool("ReadShapeCompoundMode", True)
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Import").SetInt("ImportMode", 0)
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Import").SetBool("ImportHiddenObject", False)
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Import").SetBool("ExpandCompound", False)
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Import").SetBool("UseBaseName", False)
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Import").SetBool("UseLinkGroup", False)
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Import").SetBool("ShowProgress", False)
if fmt == 'step':
Import.open(path)
else:
FreeCAD.openDocument(path)
doc = FreeCAD.ActiveDocument
print('### active document', doc.FileName)
doc.recompute()
label = auto_part_label(path)
max_parts = 1
if hasattr(doc, 'Assembly'):
max_parts = 0
parts = find_parts(doc, label, max_parts)
return doc, parts
def export_parts(parts, dest):
fmt = dest.rpartition('.')[-1]
print('### exporting', fmt, dest)
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Import").SetBool("ExportHiddenObject", False)
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Import").SetBool("ReduceObjects", False)
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Import").SetBool("UseLinkGroup", False)
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Import").SetBool("ShowProgress", False)
if fmt in ('3mf', 'stl', 'wrl', 'obj'):
import Mesh
Mesh.export(parts, dest)
elif fmt == 'dxf':
import Draft
views = []
for part in parts:
view = Draft.make_shape2dview(part, FreeCAD.Vector(-0.0, -0.0, 1.0))
views.append(view)
doc.recompute()
import importDXF
importDXF.export(views, dest)
else:
import Import
Import.export(parts, dest)
print('### export to', dest, 'successful')
def fuse_parts(doc, parts):
print('### fusing parts:', [o.FullName for o in parts])
doc.addObject("Part::MultiFuse","Fusion")
doc.Fusion.Shapes = parts
doc.recompute()
return doc.Fusion
def count_parts(objects):
count = 0
for o in objects:
if has_part(o):
count += 1
return count