-
-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathThreeMF.py
129 lines (106 loc) · 4.75 KB
/
ThreeMF.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
# Python 2.7 and 3.5
# Author: Christoph Schranz, Salzburg Research
import os
import zipfile
import xml.etree.ElementTree as ET
namespace = {
"3mf": "http://schemas.microsoft.com/3dmanufacturing/core/2015/02",
"m" : "http://schemas.microsoft.com/3dmanufacturing/material/2015/02"
}
def Read3mf(f):
'''load parts of the 3mf with their properties'''
# The base object of 3mf is a zipped archive.
archive = zipfile.ZipFile(f, "r")
try:
root = ET.parse(archive.open("3D/3dmodel.model"))
# There can be multiple objects, try to load all of them.
objects = root.findall("./3mf:resources/3mf:object", namespace)
if len(objects) == 0:
print("No objects found in 3MF file %s, either the file is damaged or you are using an outdated format", f)
return None
obj_meshs = list()
c = 0
for obj in objects:
if obj.findall(".//3mf:mesh", namespace) == []:
continue
obj_meshs.append(dict())
objectid = obj.get("id")
obj_meshs[c]["objectid"] = objectid
vertex_list = []
obj_meshs[c]["mesh"] = list()
# for vertex in object.mesh.vertices.vertex:
for vertex in obj.findall(".//3mf:vertex", namespace):
vertex_list.append([vertex.get("x"), vertex.get("y"), vertex.get("z")])
triangles = obj.findall(".//3mf:triangle", namespace)
# for triangle in object.mesh.triangles.triangle:
for triangle in triangles:
v1 = int(triangle.get("v1"))
v2 = int(triangle.get("v2"))
v3 = int(triangle.get("v3"))
obj_meshs[c]["mesh"].append([float(vertex_list[v1][0]), float(vertex_list[v1][1]), float(vertex_list[v1][2])])
obj_meshs[c]["mesh"].append([float(vertex_list[v2][0]), float(vertex_list[v2][1]), float(vertex_list[v2][2])])
obj_meshs[c]["mesh"].append([float(vertex_list[v3][0]), float(vertex_list[v3][1]), float(vertex_list[v3][2])])
try:
obj_meshs[c]["Transform"] = getTransformation(root, objectid)
except:
pass
## try:
## color_list = list()
## colors = root.findall('.//m:color', namespace)
## if colors:
## for color in colors:
## color_list.append(color.get("color",0))
## obj_meshs[c]["color"] = color_list
## except AttributeError:
## pass # Empty list was found. Getting transformation is not possible
c = c + 1
except Exception as e:
print("exception occured in 3mf reader: %s" % e)
return None
return obj_meshs
def getTransformation(root, objectid):
builds = root.findall(".//3mf:item", namespace)
transforms = list()
for item in builds:
if item.get("transform"):
transforms.append((item.get("objectid"), item.get("transform")))
components = root.findall(".//3mf:components", namespace)
objects = root.findall("./3mf:resources/3mf:object", namespace)
for (transid, transform) in transforms:
for obj in objects:
if transid == obj.get("id"):
obj_ids = obj.findall(".//3mf:component", namespace)
for obj_id in obj_ids:
if obj_id.get("objectid") == objectid:
# print(transform)
break
return transform
def rotate3MF(f, outfile, objs):
# TODO doesn't work at the moment
archive = zipfile.ZipFile(f, "r")
root = ET.parse(archive.open("3D/3dmodel.model"))
for obj in objs:
itemid = None
# get build id for transform value
objects3MF = root.findall("./3mf:resources/3mf:object", namespace)
for elem in objects3MF:
for component in elem.findall(".//3mf:component", namespace):
if component.get("objectid") == obj["objectid"]:
# print("objid", elem.get("id"))
itemid = elem.get("id")
if itemid:
for item in root.findall(".//3mf:build/3mf:item", namespace):
if item.get("objectid") == itemid:
item.set("transform", obj["transform"])
else:
pass
# Writing the changed model in the output file
indir = os.path.splitext(f)[0]
zipf = zipfile.ZipFile(outfile, 'w', zipfile.ZIP_DEFLATED)
zipdir(indir, zipf)
zipf.close()
def zipdir(path, ziph):
# ziph is zipfile handle
for root, dirs, files in os.walk(path):
for file in files:
ziph.write(os.path.join(root, file))