Skip to content

Commit 4ac8ff0

Browse files
authored
Merge initial a3d export support
Initial a3d export support
2 parents 03501ad + 7283d77 commit 4ac8ff0

6 files changed

Lines changed: 577 additions & 30 deletions

File tree

io_scene_a3d/A3D.py

Lines changed: 186 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
SOFTWARE.
2121
'''
2222

23-
from .IOTools import unpackStream, readNullTerminatedString, calculatePadding
23+
from io import BytesIO
24+
25+
from .IOTools import unpackStream, packStream, readNullTerminatedString, calculatePadding
2426
from . import A3DObjects
2527

2628
'''
@@ -65,13 +67,33 @@ def read(self, stream):
6567
self.readRootBlock2(stream)
6668
elif self.version == 3:
6769
self.readRootBlock3(stream)
70+
else:
71+
raise RuntimeError(f"Unknown A3D version: {self.version}")
72+
73+
def write(self, stream, version=2):
74+
# Write header data
75+
stream.write(A3D_SIGNATURE)
76+
packStream("<2H", stream, version, 0)
77+
78+
# Write root block
79+
if version == 1:
80+
self.writeRootBlock1(stream)
81+
elif version == 2:
82+
self.writeRootBlock2(stream)
83+
elif version == 3:
84+
self.writeRootBlock3(stream)
85+
else:
86+
raise RuntimeError(f"Unknown A3D version: {version} whilst writing A3D")
6887

6988
'''
7089
Root data blocks
7190
'''
7291
def readRootBlock1(self, stream):
7392
raise RuntimeError("Version 1 files are not supported yet")
7493

94+
def writeRootBlock1(self, stream):
95+
raise RuntimeError("Version 1 files are not supported yet")
96+
7597
def readRootBlock2(self, stream):
7698
# Verify signature
7799
signature, _ = unpackStream("<2I", stream)
@@ -85,6 +107,21 @@ def readRootBlock2(self, stream):
85107
self.readTransformBlock2(stream)
86108
self.readObjectBlock2(stream)
87109

110+
def writeRootBlock2(self, stream):
111+
buffer = BytesIO()
112+
113+
# Write data to the buffer
114+
print("Writing root block")
115+
self.writeMaterialBlock2(buffer)
116+
self.writeMeshBlock2(buffer)
117+
self.writeTransformBlock2(buffer)
118+
self.writeObjectBlock2(buffer)
119+
120+
# Write buffer to stream
121+
packStream("<2I", stream, A3D_ROOTBLOCK_SIGNATURE, buffer.tell())
122+
buffer.seek(0, 0)
123+
stream.write(buffer.read())
124+
88125
def readRootBlock3(self, stream):
89126
# Verify signature
90127
signature, length = unpackStream("<2I", stream)
@@ -101,6 +138,21 @@ def readRootBlock3(self, stream):
101138
padding = calculatePadding(length)
102139
stream.read(padding)
103140

141+
def writeRootBlock3(self, stream):
142+
buffer = BytesIO()
143+
144+
# Write data to the buffer
145+
print("Writing root block")
146+
self.writeMaterialBlock3(buffer)
147+
self.writeMeshBlock3(buffer)
148+
self.writeTransformBlock3(buffer)
149+
self.writeObjectBlock3(buffer)
150+
151+
# Write buffer to stream
152+
packStream("<2I", stream, A3D_ROOTBLOCK_SIGNATURE, buffer.tell())
153+
buffer.seek(0, 0)
154+
stream.write(buffer.read())
155+
104156
'''
105157
Material data blocks
106158
'''
@@ -117,6 +169,20 @@ def readMaterialBlock2(self, stream):
117169
material.read2(stream)
118170
self.materials.append(material)
119171

172+
def writeMaterialBlock2(self, stream):
173+
buffer = BytesIO()
174+
175+
# Write data to the buffer
176+
print("Writing material block")
177+
packStream("<I", buffer, len(self.materials))
178+
for material in self.materials:
179+
material.write2(buffer)
180+
181+
# Write buffer to stream
182+
packStream("<2I", stream, A3D_MATERIALBLOCK_SIGNATURE, buffer.tell())
183+
buffer.seek(0, 0)
184+
stream.write(buffer.read())
185+
120186
def readMaterialBlock3(self, stream):
121187
# Verify signature
122188
signature, length, materialCount = unpackStream("<3I", stream)
@@ -134,6 +200,24 @@ def readMaterialBlock3(self, stream):
134200
padding = calculatePadding(length)
135201
stream.read(padding)
136202

203+
def writeMaterialBlock3(self, stream):
204+
buffer = BytesIO()
205+
206+
# Write data to the buffer
207+
print("Writing material block")
208+
packStream("<I", buffer, len(self.materials))
209+
for material in self.materials:
210+
material.write3(buffer)
211+
212+
# Write buffer to stream
213+
packStream("<2I", stream, A3D_MATERIALBLOCK_SIGNATURE, buffer.tell())
214+
buffer.seek(0, 0)
215+
stream.write(buffer.read())
216+
217+
# Padding
218+
paddingSize = calculatePadding(buffer.tell())
219+
stream.write(b"\x00" * paddingSize)
220+
137221
'''
138222
Mesh data blocks
139223
'''
@@ -150,6 +234,20 @@ def readMeshBlock2(self, stream):
150234
mesh.read2(stream)
151235
self.meshes.append(mesh)
152236

237+
def writeMeshBlock2(self, stream):
238+
buffer = BytesIO()
239+
240+
# Write data to the buffer
241+
print("Writing mesh block")
242+
packStream("<I", buffer, len(self.meshes))
243+
for mesh in self.meshes:
244+
mesh.write2(buffer)
245+
246+
# Write buffer to stream
247+
packStream("<2I", stream, A3D_MESHBLOCK_SIGNATURE, buffer.tell())
248+
buffer.seek(0, 0)
249+
stream.write(buffer.read())
250+
153251
def readMeshBlock3(self, stream):
154252
# Verify signature
155253
signature, length, meshCount = unpackStream("<3I", stream)
@@ -167,6 +265,24 @@ def readMeshBlock3(self, stream):
167265
padding = calculatePadding(length)
168266
stream.read(padding)
169267

268+
def writeMeshBlock3(self, stream):
269+
buffer = BytesIO()
270+
271+
# Write data to the buffer
272+
print("Writing mesh block")
273+
packStream("<I", buffer, len(self.meshes))
274+
for mesh in self.meshes:
275+
mesh.write3(buffer)
276+
277+
# Write buffer to stream
278+
packStream("<2I", stream, A3D_MESHBLOCK_SIGNATURE, buffer.tell())
279+
buffer.seek(0, 0)
280+
stream.write(buffer.read())
281+
282+
# Padding
283+
paddingSize = calculatePadding(buffer.tell())
284+
stream.write(b"\x00" * paddingSize)
285+
170286
'''
171287
Transform data blocks
172288
'''
@@ -187,6 +303,22 @@ def readTransformBlock2(self, stream):
187303
parentID, = unpackStream("<i", stream)
188304
self.transformParentIDs.append(parentID)
189305

306+
def writeTransformBlock2(self, stream):
307+
buffer = BytesIO()
308+
309+
# Write data to the buffer
310+
print("Writing transform block")
311+
packStream("<I", buffer, len(self.transforms))
312+
for transform in self.transforms:
313+
transform.write2(buffer)
314+
for parentID in self.transformParentIDs:
315+
packStream("<i", buffer, parentID)
316+
317+
# Write buffer to stream
318+
packStream("<2I", stream, A3D_TRANSFORMBLOCK_SIGNATURE, buffer.tell())
319+
buffer.seek(0, 0)
320+
stream.write(buffer.read())
321+
190322
def readTransformBlock3(self, stream):
191323
# Verify signature
192324
signature, length, transformCount = unpackStream("<3I", stream)
@@ -195,7 +327,6 @@ def readTransformBlock3(self, stream):
195327

196328
# Read data
197329
print(f"Reading transform block with {transformCount} transforms and length {length}")
198-
transforms = []
199330
for _ in range(transformCount):
200331
transform = A3DObjects.A3DTransform()
201332
transform.read3(stream)
@@ -209,6 +340,26 @@ def readTransformBlock3(self, stream):
209340
padding = calculatePadding(length)
210341
stream.read(padding)
211342

343+
def writeTransformBlock3(self, stream):
344+
buffer = BytesIO()
345+
346+
# Write data to the buffer
347+
print("Writing transform block")
348+
packStream("<I", buffer, len(self.transforms))
349+
for transform in self.transforms:
350+
transform.write3(buffer)
351+
for parentID in self.transformParentIDs:
352+
packStream("<i", buffer, parentID)
353+
354+
# Write buffer to stream
355+
packStream("<2I", stream, A3D_TRANSFORMBLOCK_SIGNATURE, buffer.tell())
356+
buffer.seek(0, 0)
357+
stream.write(buffer.read())
358+
359+
# Padding
360+
paddingSize = calculatePadding(buffer.tell())
361+
stream.write(b"\x00" * paddingSize)
362+
212363
'''
213364
Object data blocks
214365
'''
@@ -225,6 +376,20 @@ def readObjectBlock2(self, stream):
225376
objec.read2(stream)
226377
self.objects.append(objec)
227378

379+
def writeObjectBlock2(self, stream):
380+
buffer = BytesIO()
381+
382+
# Write data to the buffer
383+
print("Writing object block")
384+
packStream("<I", buffer, len(self.objects))
385+
for objec in self.objects:
386+
objec.write2(buffer)
387+
388+
# Write buffer to stream
389+
packStream("<2I", stream, A3D_OBJECTBLOCK_SIGNATURE, buffer.tell())
390+
buffer.seek(0, 0)
391+
stream.write(buffer.read())
392+
228393
def readObjectBlock3(self, stream):
229394
# Verify signature
230395
signature, length, objectCount = unpackStream("<3I", stream)
@@ -240,4 +405,22 @@ def readObjectBlock3(self, stream):
240405

241406
# Padding
242407
padding = calculatePadding(length)
243-
stream.read(padding)
408+
stream.read(padding)
409+
410+
def writeObjectBlock3(self, stream):
411+
buffer = BytesIO()
412+
413+
# Write data to the buffer
414+
print("Writing object block")
415+
packStream("<I", buffer, len(self.objects))
416+
for objec in self.objects:
417+
objec.write3(buffer)
418+
419+
# Write buffer to stream
420+
packStream("<2I", stream, A3D_OBJECTBLOCK_SIGNATURE, buffer.tell())
421+
buffer.seek(0, 0)
422+
stream.write(buffer.read())
423+
424+
# Padding
425+
paddingSize = calculatePadding(buffer.tell())
426+
stream.write(b"\x00" * paddingSize)

0 commit comments

Comments
 (0)