Skip to content

Commit

Permalink
Improve raw file loading performance
Browse files Browse the repository at this point in the history
  • Loading branch information
AstrorEnales committed May 6, 2022
1 parent a2e48e8 commit 47e7b42
Showing 1 changed file with 22 additions and 26 deletions.
48 changes: 22 additions & 26 deletions blender_magicavoxel.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ def abgr_int_to_rgba_tuple(color: int) -> Tuple[int, int, int, int]:
]

DEBUG_OUTPUT = False
READ_INT_UNPACK = struct.Struct('<i').unpack
READ_FLOAT_UNPACK = struct.Struct('<f').unpack


class SparseArray:
Expand Down Expand Up @@ -219,22 +221,22 @@ def reduce_voxel_grid_to_hull(self, voxels: SparseArray, outside: SparseArray or
index = self.get_index(x, y, z)
if voxels[index] is not None:
# Left
if x == 0 or (outside is not None and outside[index - 1]):
if x == 0 or outside[index - 1]:
continue
# Right
if x == self.last_index_x or (outside is not None and outside[index + 1]):
if x == self.last_index_x or outside[index + 1]:
continue
# Down
if first_y or (outside is not None and outside[index - self.y_multiplier]):
if first_y or outside[index - self.y_multiplier]:
continue
# Up
if last_y or (outside is not None and outside[index + self.y_multiplier]):
if last_y or outside[index + self.y_multiplier]:
continue
# Back
if first_z or (outside is not None and outside[index - self.z_multiplier]):
if first_z or outside[index - self.z_multiplier]:
continue
# Front
if last_z or (outside is not None and outside[index + self.z_multiplier]):
if last_z or outside[index + self.z_multiplier]:
continue
# If not connected to the outside space, delete the voxel(inside hull)
del voxels[index]
Expand Down Expand Up @@ -1384,15 +1386,11 @@ def read_riff_id(f: IO) -> str:

@staticmethod
def read_int32(f: IO) -> int:
return struct.unpack('<i', f.read(4))[0]
return READ_INT_UNPACK(f.read(4))[0]

@staticmethod
def read_float32(f: IO) -> int:
return struct.unpack('<f', f.read(4))[0]

@staticmethod
def read_uint8(f: IO) -> int:
return struct.unpack('B', f.read(1))[0]
return READ_FLOAT_UNPACK(f.read(4))[0]

@staticmethod
def read_string(f: IO) -> str:
Expand Down Expand Up @@ -1426,14 +1424,13 @@ def read_size_chunk(f: IO, model: VoxModel):
@staticmethod
def read_xyzi_chunk(f: IO, model: VoxModel):
num_voxels = ImportVOX.read_int32(f)
model.meshes[-1].num_voxels = num_voxels
for i in range(0, num_voxels):
model.meshes[-1].set_voxel_color_index(
ImportVOX.read_uint8(f),
ImportVOX.read_uint8(f),
ImportVOX.read_uint8(f),
ImportVOX.read_uint8(f)
)
mesh = model.meshes[-1]
mesh.num_voxels = num_voxels
voxel_data = struct.unpack('%sB' % (num_voxels * 4), f.read(num_voxels * 4))
mesh.voxels = SparseArray(None, {
mesh.grid.get_index(voxel_data[i], voxel_data[i + 1], voxel_data[i + 2]): voxel_data[i + 3]
for i in range(0, num_voxels * 4, 4)
})

@staticmethod
def read_rcam_chunk(f: IO, model: VoxModel):
Expand Down Expand Up @@ -1530,12 +1527,10 @@ def read_layr_chunk(f: IO, model: VoxModel):
@staticmethod
def read_rgba_chunk(f: IO, model: VoxModel):
custom_palette: List[Tuple[int, int, int, int]] = [(0, 0, 0, 255)]
color_data = struct.unpack('%sB' % 256 * 4, f.read(256 * 4))
for i in range(256):
r = ImportVOX.read_uint8(f)
g = ImportVOX.read_uint8(f)
b = ImportVOX.read_uint8(f)
a = ImportVOX.read_uint8(f)
color = (r, g, b, a)
offset = i * 4
color = (color_data[offset], color_data[offset + 1], color_data[offset + 2], color_data[offset + 3])
if i == 255:
custom_palette[0] = color
else:
Expand All @@ -1544,7 +1539,8 @@ def read_rgba_chunk(f: IO, model: VoxModel):

@staticmethod
def read_imap_chunk(f: IO, _: VoxModel):
_ = {ImportVOX.read_uint8(f): (i + 1) % 256 for i in range(256)}
_ = struct.unpack('%sB' % 256, f.read(256)) # imap_data
# _ = {imap_data[i]: (i + 1) % 256 for i in range(256)}
# IMAP in combination with custom palette is only relevant for showing the palette in MV. Ignored.

@staticmethod
Expand Down

0 comments on commit 47e7b42

Please sign in to comment.