Skip to content

Commit

Permalink
Merge pull request #79 from Robert-N7/develop
Browse files Browse the repository at this point in the history
Advanced Conversion of Polygons
  • Loading branch information
Robert-N7 authored Jun 6, 2022
2 parents a07f262 + 62aeeef commit 457fbe1
Show file tree
Hide file tree
Showing 37 changed files with 1,491 additions and 281 deletions.
1 change: 1 addition & 0 deletions .idea/abmatt.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions .idea/runConfigurations/main_window.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions abmatt/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = 'v1.3.2'
9 changes: 5 additions & 4 deletions abmatt/brres/lib/matching.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,11 @@ def validInt(str, min=-0x7fffffff, max=0x7fffffff):

def it_eq(x, y):
"""determines if iterable is equal"""
x_type = type(x)
y_type = type(y)
if x_type != tuple and x_type != list or y_type != tuple and y_type != list:
return x == y # default comparison
try:
iter(x)
iter(y)
except TypeError:
return x == y
if len(x) != len(y):
return False
# recursively compare, in case of nested iterables
Expand Down
25 changes: 25 additions & 0 deletions abmatt/brres/mdl0/bone.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from copy import copy, deepcopy

import numpy as np

from abmatt.brres.lib.node import Node
Expand Down Expand Up @@ -39,6 +41,29 @@ def begin(self):
self.transform_matrix = [[y for y in x] for x in self.identity_matrix]
self.inverse_matrix = [[y for y in x] for x in self.identity_matrix]

def __deepcopy__(self, memodict={}):
b = Bone(self.name, None)
b.scale = copy(self.scale)
b.rotation = copy(self.rotation)
b.translation = copy(self.translation)
b.minimum = copy(self.minimum)
b.maximum = copy(self.maximum)
b.child = deepcopy(self.child)
b.part2 = self.part2
b.transform_matrix = deepcopy(self.transform_matrix)
b.inverse_matrix = deepcopy(self.inverse_matrix)
b.no_transform = self.no_transform
b.fixed_translation = self.fixed_translation
b.fixed_scale = self.fixed_scale
b.fixed_rotation = self.fixed_rotation
b.scale_equal = self.scale_equal
b.seg_scale_comp_apply = self.seg_scale_comp_apply
b.seg_scale_comp_parent = self.seg_scale_comp_parent
b.classic_scale_off = self.classic_scale_off
b.visible = self.visible
b.has_geometry = self.has_geometry
b.has_billboard_parent = self.has_billboard_parent

def __eq__(self, other):
result = super().__eq__(other) and np.allclose(self.scale, other.scale) and \
np.allclose(self.rotation, other.rotation) and np.allclose(self.translation, other.translation) and \
Expand Down
2 changes: 2 additions & 0 deletions abmatt/brres/mdl0/material/material.py
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,8 @@ def is_vertex_color_enabled(self):
def enable_vertex_color(self, enable=True):
if self.lightChannels[0].enable_vertex_color(enable):
self.mark_modified()
return True
return False

def get_material_color(self):
return self.lightChannels[0].materialColor
Expand Down
87 changes: 70 additions & 17 deletions abmatt/brres/mdl0/mdl0.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,35 +214,88 @@ def update_polygon_material(self, polygon, old_mat, new_mat):
m.paste(new_mat)
new_mat = m
new_mat.add_poly_ref(polygon)
old_mat.remove_poly_ref(polygon)
if old_mat:
old_mat.remove_poly_ref(polygon)
polygon.material = new_mat
if not len(old_mat.polygons):
if old_mat and not len(old_mat.polygons):
self.materials.remove(old_mat)
# self.mark_modified()
return new_mat

def __remove_group_item(self, item, group, if_not_in_group):
if item is not None and item not in if_not_in_group:
@staticmethod
def __remove_group_item(item, group, if_not_in_group):
if item is not None and item in group:
for x in if_not_in_group:
if x is item:
return False
group.remove(item)
return True

def remove_vertices(self, polygon):
result = self.__remove_group_item(
polygon.get_vertex_group(),
self.vertices,
[x.get_vertex_group() for x in self.objects if x is not polygon]
)
if result:
self.rebuild_head = True
self.mark_modified()
return result

def remove_normals(self, polygon):
result = self.__remove_group_item(
polygon.get_normal_group(),
self.normals,
[x.get_normal_group() for x in self.objects if x is not polygon]
)
if result:
self.rebuild_head = True
self.mark_modified()
return result

def remove_colors(self, polygon):
result = self.__remove_group_item(
polygon.get_color_group(),
self.colors,
[x.get_color_group() for x in self.objects if x is not polygon]
)
if result:
self.rebuild_head = True
self.mark_modified()
return result

def remove_uvs(self, polygon, uvs=None):
if not uvs:
uvs = [polygon.get_uv_group(i) for i in range(polygon.uv_count)]
all_used = []
for x in self.objects:
if x is not polygon:
all_used.extend([x.get_uv_group(i) for i in range(x.uv_count)])
result = True
removed = False
for x in uvs:
if not self.__remove_group_item(
x,
self.uvs,
all_used
):
result = False
else:
removed = True
if removed:
self.mark_modified()
self.rebuild_head = True
return result

def remove_polygon(self, polygon):
self.objects.remove(polygon)
self.rebuild_head = True
if len(polygon.material.polygons) == 1:
self.remove_material(polygon.material)
self.__remove_group_item(polygon.get_vertex_group(), self.vertices,
[x.get_vertex_group() for x in self.objects])
self.__remove_group_item(polygon.get_normal_group(), self.normals,
[x.get_normal_group() for x in self.objects])
self.__remove_group_item(polygon.get_color_group(), self.colors,
[x.get_color_group() for x in self.objects])
if polygon.uv_count:
uv_groups = set()
for x in self.objects:
for i in range(x.uv_count):
uv_groups.add(x.get_uv_group(i))
for i in range(polygon.uv_count):
self.__remove_group_item(polygon.get_uv_group(i), self.uvs, uv_groups)
self.remove_vertices(polygon)
self.remove_normals(polygon)
self.remove_colors(polygon)
self.remove_uvs(polygon)
self.mark_modified()

def add_material(self, material):
Expand Down
3 changes: 2 additions & 1 deletion abmatt/brres/mdl0/point.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from abmatt.autofix import AutoFix
from abmatt.brres.lib.decoder import decode_geometry_group
from abmatt.brres.lib.node import Node
from abmatt.brres.lib.matching import it_eq

FMT_UINT8 = 0
FMT_INT8 = 1
Expand Down Expand Up @@ -78,7 +79,7 @@ def __next__(self):
def __eq__(self, other):
return super().__eq__(other) and self.count == other.count and self.stride == other.stride \
and self.divisor == other.divisor and self.format == other.format and self.comp_count == other.comp_count \
and self.data == other.data
and it_eq(self.data, other.data)

def get_format(self):
return self.format
Expand Down
82 changes: 43 additions & 39 deletions abmatt/brres/mdl0/polygon.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,8 @@ def get_str(self, key):

def paste(self, other):
parent = self.parent
parent_diff = self.parent is not other.parent
self.tex_e = other.tex_e
i = parent.bones.index(other.visible_bone)
if i < 0:
b = deepcopy(other.visible_bone)
parent.add_bone(b)
else:
b = parent.bones[i]
self.visible_bone = b
i = parent.bones.index(other.linked_bone)
if i < 0:
b = deepcopy(other.linked_bone)
parent.add_bone(b)
else:
b = parent.bones[i]
self.linked_bone = b
parent.update_polygon_material(self, self.material, other.material)
self.decoded = None
self.priority = other.priority
self.vertex_index = other.vertex_index
Expand All @@ -49,42 +35,42 @@ def paste(self, other):
self.uv_indices = deepcopy(other.uv_indices)
self.weight_index = other.weight_index
self.uv_mtx_indices = deepcopy(other.uv_mtx_indices)
parent.vertices.remove(self.vertices)
self.vertices = deepcopy(other.vertices)
parent.vertices.append(self.vertices)
self.facepoint_count = other.facepoint_count
self.face_count = other.face_count
for c in self.colors:
if c:
found = False
for poly in parent.objects:
if c in poly.colors:
found = True
break
if not found:
parent.colors.remove(c)
self.colors = deepcopy(other.colors)
for c in self.colors:
parent.colors.append(c)
self.color_count = other.color_count
parent.normals.remove(self.normals)
self.normals = deepcopy(other.normals)
parent.normals.append(self.normals)
self.encode_str = other.encode_str
for uv in self.uvs:
parent.uvs.remove(uv)
self.uvs = deepcopy(other.uvs)
for uv in self.uvs:
parent.uvs.append(uv)
self.uv_count = other.uv_count
self.data = deepcopy(other.data)
self.flags = deepcopy(other.flags)
self.bone_table = deepcopy(other.bone_table)
self.fur_vector = other.fur_vector
self.fur_coord = other.fur_coord
self.vertex_e = other.vertex_e
self.normal_index3 = other.normal_index3
self.color0_e = other.color0_e
if parent:
parent.vertices.append(self.vertices)
parent.colors.extend([x for x in self.colors if x])
parent.uvs.extend([x for x in self.uvs if x])
parent.normals.append(self.normals)
if parent_diff:
self.visible_bone = deepcopy(other.visible_bone)
self.linked_bone = deepcopy(other.linked_bone)
if parent:
parent.add_bone(self.visible_bone)
if self.visible_bone is not self.linked_bone:
parent.add_bone(self.linked_bone)
parent.update_polygon_material(self, self.material, other.material)
else: # parent is same
self.visible_bone = other.visible_bone
self.linked_bone = other.linked_bone

def __deepcopy__(self, memodict={}):
p = Polygon(self.name, None)
p.paste(self)
return p

def __init__(self, name, parent, binfile=None):
self.tex_e = [1] * 8
Expand All @@ -110,7 +96,7 @@ def __eq__(self, other):
def __hash__(self):
return super().__hash__()

def begin(self):
def __reset(self):
# The face point indices, also indexes into the encode string
self.vertex_index = -1
self.normal_index = -1
Expand All @@ -120,6 +106,8 @@ def begin(self):
self.weight_index = -1
self.uv_mtx_indices = [-1] * 8
self.vertices = None
self.linked_bone = None
self.decoded = None
self.facepoint_count = 0
self.face_count = 0
self.colors = [None, None]
Expand All @@ -129,9 +117,11 @@ def begin(self):
self.uvs = [None] * 8
self.uv_count = 0
self.data = None

def begin(self):
self.__reset()
self.flags = 0
self.linked_bone = None
self.visible_bone = self.parent.bones[0]
self.visible_bone = self.parent.bones[0] if self.parent else None
self.bone_table = None
self.fur_vector = None
self.fur_coord = None
Expand Down Expand Up @@ -239,6 +229,8 @@ def check(self, verts, norms, uvs, colors, materials): # as we go along, gather
verts.add(vertices.name)
if self.linked_bone:
vertices.check_vertices(self.linked_bone)
else:
AutoFix.warn(f'{self.name} has no vertices!')
normals = self.get_normal_group()
if normals:
norms.add(normals.name)
Expand Down Expand Up @@ -301,3 +293,15 @@ def has_uv_matrix(self, i):

def has_normals(self):
return self.normals is not None

def before_recode(self):
"""Should only be called if recoding"""
self.parent.remove_vertices(self)
self.parent.remove_normals(self)
self.parent.remove_colors(self)
self.parent.remove_uvs(self)
self.__reset()

def after_recode(self):
"""Only call after recoding"""
self.mark_modified()
2 changes: 1 addition & 1 deletion abmatt/build/check_imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def check_file(self, file_path, package_modules):
new_data = []
for i in range(len(data)):
line = data[i]
match = re.search('(from (?P<from>\.?\w+)(\.\w+)* )?import (?P<imported>\w+).*', line)
match = re.search('^\s*(from (?P<from>\.?\w+)(\.\w+)* )?import (?P<imported>\w+).*', line)
new_line = None
if match:
d = match.groupdict()
Expand Down
1 change: 0 additions & 1 deletion abmatt/build/config.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
build_name = main # build output name
build_type = onedir # the type of build, (auto|onefile|onedir)
version = 1.3.1
run_integration_tests = False
run_unit_tests = False
2 changes: 2 additions & 0 deletions abmatt/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ def set_convert(self, params):
flags |= 8
elif lower == 'patch':
flags |= 0x10
elif lower == 'moonview':
flags |= 0x20
elif not self.name:
self.name = os.path.normpath(param)
else:
Expand Down
Loading

0 comments on commit 457fbe1

Please sign in to comment.