Skip to content

Commit f79a3fe

Browse files
committed
Basic importing using rewrite
1 parent c8d27c0 commit f79a3fe

4 files changed

Lines changed: 128 additions & 116 deletions

File tree

blender/io_scene_dava/FileIO/KA.py

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
99
'''
1010

11-
import StreamBuffer
11+
from .StreamBuffer import StreamBuffer
1212

1313
from io import BytesIO
1414

@@ -18,6 +18,38 @@
1818
class KAReadError(RuntimeError): pass
1919
class KAWriteError(RuntimeError): pass
2020

21+
'''
22+
Data types
23+
'''
24+
class Types:
25+
NONE = 0
26+
BOOLEAN = 1
27+
INT32 = 2
28+
FLOAT = 3
29+
STRING = 4
30+
WIDE_STRING = 5
31+
BYTE_ARRAY = 6
32+
UINT32 = 7
33+
KEYED_ARCHIVE = 8
34+
INT64 = 9
35+
UINT64 = 10
36+
VECTOR2 = 11
37+
VECTOR3 = 12
38+
VECTOR4 = 13
39+
MATRIX2 = 14
40+
MATRIX3 = 15
41+
MATRIX4 = 16
42+
COLOR = 17
43+
FASTNAME = 18
44+
AABBOX3 = 19
45+
FILEPATH = 20
46+
FLOAT64 = 21
47+
INT8 = 22
48+
UINT8 = 23
49+
INT16 = 24
50+
UINT16 = 25
51+
ARRAY = 27
52+
2153
'''
2254
Primitive data readers
2355
'''
@@ -172,9 +204,8 @@ def readKAHeader(stream):
172204
if stream.readBytes(2) != b"KA":
173205
raise KAReadError("Invalid magic string")
174206

175-
version = stream.readInt32(False)
207+
version = stream.readInt16(False)
176208
nodeCount = stream.readInt32(False)
177-
stream.readInt32(False) #TODO: duplicate of node count?
178209

179210
return (version, nodeCount)
180211

@@ -229,7 +260,7 @@ def readKA258(stream, stringTable):
229260
return {}
230261

231262
archive = {}
232-
for _ in range nodeCount:
263+
for _ in range(nodeCount):
233264
key, value = V2DataReader.readPair(stream, stringTable)
234265
archive[key] = value
235266

blender/io_scene_dava/FileIO/SCG.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
99
'''
1010

11-
from KA import readKA1
11+
from .KA import readKA1
1212

1313
'''
1414
Errors
@@ -33,7 +33,7 @@ def readSCG(stream):
3333
if node["##name"] != "PolygonGroup":
3434
print("Warning: SCG node wasn't a polygon group, skipping")
3535
continue
36-
polygonGroups[ node["#id"] ] = node
36+
polygonGroups[ int.from_bytes(node["#id"], "little") ] = node
3737

3838
return polygonGroups
3939

blender/io_scene_dava/Geometry/PolygonGroup.py

Lines changed: 45 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
99
'''
1010

11+
from io import BytesIO
12+
1113
from ..FileIO.StreamBuffer import StreamBuffer
1214

1315
class VertexTypes:
@@ -56,6 +58,7 @@ def __init__(self, fmt):
5658
self.JOINTWEIGHT = -1
5759

5860
# Parse format
61+
stride = 0
5962
if (fmt & VertexTypes.VERTEX):
6063
self.VERTEX = stride
6164
stride += 3 * 4
@@ -130,6 +133,7 @@ def __init__(self, polyGroup):
130133
self.id = polyGroup["#id"]
131134
self.cubeTextureCoordCount = polyGroup["cubeTextureCoordCount"]
132135
self.primitiveType = polyGroup["rhi_primitiveType"]
136+
self.primitiveCount = polyGroup["primitiveCount"]
133137

134138
# Vertices
135139
self.vertices = []
@@ -147,7 +151,7 @@ def __init__(self, polyGroup):
147151
self.cubetexcoords = []
148152

149153
# Parse vertex format
150-
vertexFormat = VertexFormat(polyGroup["self"])
154+
vertexFormat = VertexFormat(polyGroup["vertexFormat"])
151155

152156
# Parse vertices TODO
153157
stream = StreamBuffer( BytesIO(polyGroup["vertices"]) )
@@ -156,6 +160,7 @@ def __init__(self, polyGroup):
156160
self.vertices.append(
157161
(stream.readFloat(), stream.readFloat(), stream.readFloat())
158162
)
163+
stream.readBytes(vertexFormat.stride - 12) # Read off unhandled data
159164

160165
# Parse indices
161166
# 0 = uint16_t
@@ -167,57 +172,49 @@ def __init__(self, polyGroup):
167172
if polyGroup["indexFormat"] == 1:
168173
for _ in range(polyGroup["indexCount"]): self.indices.append( stream.readInt32(False) )
169174

170-
'''
171-
Primitive builders
172-
173-
line list, triangle list, triangle strip
174-
'''
175-
# Turn indices + vertices into a single vertex array
176-
def collectVertices(self, indices):
177-
vertexArray = []
178-
for index in indices:
179-
vertexArray.append( self.vertices[index] )
180-
return vertexArray
181-
182-
def generateTriangleList(self):
183-
faceIndices = []
184-
for i in range(0, count, 3):
185-
faceIndices.append([
186-
self.indices[i],
187-
self.indices[i+1],
188-
self.indices[i+2]
189-
])
190-
191-
return self.collectVertices(faceIndices)
192-
193-
#NOTE: We convert trianglestrip to trianglist to make the import easier
194-
def generateTriangleStrip(self):
195-
faceIndices = []
196-
197-
# First triangle
175+
'''
176+
Primitive builders
177+
178+
line list, triangle list, triangle strip
179+
'''
180+
def getTriangleList(self):
181+
faceIndices = []
182+
for i in range(0, len(self.indices), 3):
198183
faceIndices.append([
199-
self.indices[0],
200-
self.indices[1],
201-
self.indices[2]
184+
self.indices[i],
185+
self.indices[i+1],
186+
self.indices[i+2]
202187
])
203188

204-
# Digest triangestrip into trianglelist
205-
for i in range(3, count):
206-
faceIndices.append([
207-
self.indices[i-2],
208-
self.indices[i-1],
209-
self.indices[i]
210-
])
189+
return faceIndices
211190

212-
return self.collectVertices(indices)
191+
#NOTE: We convert trianglestrip to trianglist to make the import easier
192+
def getTriangleStrip(self):
193+
faceIndices = []
213194

214-
def generateLineList(self):
215-
edgeIndices = []
216-
for i in range(0, count, 2):
217-
edgeIndices.append([
218-
self.indices[i],
219-
self.indices[i+1]
220-
])
195+
# First triangle
196+
faceIndices.append([
197+
self.indices[0],
198+
self.indices[1],
199+
self.indices[2]
200+
])
221201

202+
# Digest triangestrip into trianglelist
203+
for i in range(3, len(self.indices)):
204+
faceIndices.append([
205+
self.indices[i-2],
206+
self.indices[i-1],
207+
self.indices[i]
208+
])
209+
210+
return faceIndices
211+
212+
def getLineList(self):
213+
edgeIndices = []
214+
for i in range(0, len(self.indices), 2):
215+
edgeIndices.append([
216+
self.indices[i],
217+
self.indices[i+1]
218+
])
222219

223-
return self.collectVertices(edgeIndices)
220+
return edgeIndices

blender/io_scene_dava/__init__.py

Lines changed: 46 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -25,119 +25,103 @@
2525
from bpy.props import StringProperty
2626
from bpy_extras.io_utils import ImportHelper, ExportHelper
2727

28-
from os.path import basename
29-
30-
from .FileIO import FileBuffer
31-
from .SCG.SCGReader import SCGReader
32-
from .SC2.SC2Reader import SC2Reader
28+
from .FileIO.StreamBuffer import StreamBuffer
29+
from .FileIO.SCG import readSCG
30+
from .Geometry.PolygonGroup import PrimitiveTypes, PolygonGroup
3331

3432
'''
3533
Operators
3634
'''
37-
class ImportSCG(Operator, ImportHelper):
35+
class ImportDAVA(Operator, ImportHelper):
3836
bl_idname = "import_scene.scg"
3937
bl_label = "Import DAVA geometry"
40-
bl_description = "Import a DAVA geometry file"
38+
bl_description = "Import a DAVA scene file"
4139

4240
filter_glob: StringProperty(default="*.scg", options={'HIDDEN'})
4341

4442
def invoke(self, context, event):
4543
return ImportHelper.invoke(self, context, event)
4644

45+
# Just import SCG whilst we get proper full imports working
4746
def execute(self, context):
4847
filepath = self.filepath
49-
filename = basename(filepath).split(".")[0]
50-
print(f"Importing DAVA geometry from {filepath}")
51-
52-
with open(filepath, "rb") as f:
53-
stream = FileBuffer(f)
54-
geometry = SCGReader.readFromBuffer(stream)
55-
56-
# Add geometry to scene
57-
collection = bpy.data.collections.new(filename)
58-
for groupId, polyGroup in geometry.polygonGroups.items():
48+
print(f"Importing DAVA scene from {filepath}")
49+
50+
with open(filepath, "rb") as scg:
51+
polyGroups = readSCG(
52+
StreamBuffer(scg)
53+
)
54+
55+
# Parse polygon groups
56+
for groupID in polyGroups.keys():
57+
polyGroups[groupID] = PolygonGroup( polyGroups[groupID] )
58+
59+
# Add polygon groups to scene
60+
collection = bpy.data.collections.new("DAVAMesh")
61+
for groupID in polyGroups.keys():
62+
group = polyGroups[groupID]
5963
mesh = bpy.data.meshes.new("mesh")
60-
mesh.from_pydata(polyGroup.vertices.VERTEX, polyGroup.edges, polyGroup.faces)
64+
65+
if group.primitiveType == PrimitiveTypes.TRIANGLELIST:
66+
mesh.from_pydata(group.vertices, [], group.getTriangleList())
67+
elif group.primitiveType == PrimitiveTypes.TRIANGLESTRIP:
68+
mesh.from_pydata(group.vertices, [], group.getTriangleStrip())
69+
elif group.primitiveType == PrimitiveTypes.LINELIST:
70+
mesh.from_pydata(group.vertices, group.getLineList(), [])
6171
mesh.update()
6272

63-
obj = bpy.data.objects.new(f"PolygonGroup{groupId}", mesh)
73+
obj = bpy.data.objects.new(f"PolygonGroup{groupID}", mesh)
6474
collection.objects.link(obj)
6575
bpy.context.scene.collection.children.link(collection)
66-
self.report({"INFO"}, f"Loaded {len(geometry.polygonGroups)} polygon groups")
76+
self.report({"INFO"}, f"Loaded {len(polyGroups)} polygon groups")
6777

6878
return {"FINISHED"}
6979

70-
class ExportSCG(Operator, ExportHelper):
71-
bl_idname = "export_scene.scg"
80+
class ExportDAVA(Operator, ExportHelper):
81+
bl_idname = "export_scene.sc2"
7282
bl_label = "Export DAVA geometry"
73-
bl_description = "Export a DAVA geometry file"
83+
bl_description = "Export a scene file"
7484

75-
filter_glob: StringProperty(default="*.scg", options={'HIDDEN'})
76-
filename_ext: StringProperty(default=".scg", options={'HIDDEN'})
85+
filter_glob: StringProperty(default="*.sc2", options={'HIDDEN'})
86+
filename_ext: StringProperty(default=".sc2", options={'HIDDEN'})
7787

7888
def invoke(self, context, event):
7989
return ExportHelper.invoke(self, context, event)
8090

8191
def execute(self, context):
8292
filepath = self.filepath
83-
print(f"Exporting DAVA geometry to {filepath}")
93+
print(f"Exporting DAVA scene to {filepath}")
8494
return {'FINISHED'}
8595

86-
class ImportSC2(Operator, ImportHelper):
87-
bl_idname = "import_scene.sc2"
88-
bl_label = "Import DAVA scene"
89-
bl_description = "Import a DAVA scene file"
90-
91-
filter_glob: StringProperty(default="*.sc2", options={'HIDDEN'})
92-
93-
def invoke(self, context, event):
94-
return ImportHelper.invoke(self, context, event)
95-
96-
def execute(self, context):
97-
filepath = self.filepath
98-
print(f"Importing DAVA scene file from {filepath}")
99-
100-
with open(filepath, "rb") as f:
101-
stream = FileBuffer(f)
102-
SC2Reader.readFromBuffer(stream)
103-
104-
return {"FINISHED"}
105-
10696
'''
10797
Menu
10898
'''
109-
def menu_func_import_scg(self, context):
110-
self.layout.operator(ImportSCG.bl_idname, text="DAVA scene geometry (.scg)")
111-
112-
def menu_func_export_scg(self, context):
113-
self.layout.operator(ExportSCG.bl_idname, text="DAVA scene geometry (.scg)")
99+
def menu_func_import_dava(self, context):
100+
self.layout.operator(ImportDAVA.bl_idname, text="DAVA scene (.sc2/.scg)")
114101

115-
def menu_func_import_sc2(self, context):
116-
self.layout.operator(ImportSC2.bl_idname, text="DAVA scene file (.sc2)")
102+
def menu_func_export_dava(self, context):
103+
self.layout.operator(ExportDAVA.bl_idname, text="DAVA scene (.sc2/.scg)")
117104

118105
'''
119106
Register
120107
'''
121108
classes = {
122-
ExportSCG,
123-
ImportSCG,
124-
ImportSC2
109+
ExportDAVA,
110+
ImportDAVA
125111
}
126112

127113
def register():
128114
# Register classes
129115
for c in classes:
130116
bpy.utils.register_class(c)
131117
# File > Import-Export
132-
bpy.types.TOPBAR_MT_file_import.append(menu_func_import_scg)
133-
bpy.types.TOPBAR_MT_file_export.append(menu_func_export_scg)
134-
bpy.types.TOPBAR_MT_file_import.append(menu_func_import_sc2)
118+
bpy.types.TOPBAR_MT_file_import.append(menu_func_import_dava)
119+
# bpy.types.TOPBAR_MT_file_export.append(menu_func_export_dava)
135120

136121
def unregister():
137122
# Unregister classes
138123
for c in classes:
139124
bpy.utils.unregister_class(c)
140125
# Remove `File > Import-Export`
141-
bpy.types.TOPBAR_MT_file_import.remove(menu_func_import_scg)
142-
bpy.types.TOPBAR_MT_file_export.remove(menu_func_export_scg)
143-
bpy.types.TOPBAR_MT_file_import.remove(menu_func_import_sc2)
126+
bpy.types.TOPBAR_MT_file_import.remove(menu_func_import_dava)
127+
# bpy.types.TOPBAR_MT_file_export.remove(menu_func_export_dava)

0 commit comments

Comments
 (0)