Exemple #1
0
 def _start_saving(self, mdl0):
     AutoFix.info('Exporting {} to {}...'.format(
         os.path.basename(self.brres.name), self.mdl_file))
     self.start = time.time()
     self.image_library = set()
     if mdl0 is None:
         mdl0 = self.mdl0
         if mdl0 is None:
             self.mdl0 = mdl0 = self.brres.models[0]
     else:
         self.mdl0 = mdl0
     if type(mdl0) == str:
         self.mdl0 = mdl0 = self.brres.get_model(mdl0)
     if mdl0 is None:
         raise RuntimeError('No mdl0 file found to export!')
     self.polygons = [
         x for x in mdl0.objects if self._should_include_geometry(x)
     ]
     mats = []
     for x in self.polygons:
         if x.material not in mats:
             mats.append(x.material)
     self.materials = mats
     self.cwd = os.getcwd()
     work_dir, name = os.path.split(self.mdl_file)
     if work_dir:
         os.chdir(work_dir)
     base_name, ext = os.path.splitext(name)
     self.image_dir = base_name + '_maps'
     self.json_file = base_name + '.json'
     self.influences = mdl0.get_influences()
     self.bones = {}
     self.tex0_map = {}
     return base_name, mdl0
Exemple #2
0
 def add_texture_link(self, name):
     if name != 'Null' and not self.parent.get_texture(name):
         tex = fuzzy_match(name, self.parent.textures)
         notify = 'Adding reference to unknown texture "{}"'.format(name)
         if tex:
             notify += ', did you mean ' + tex.name + '?'
         AutoFix.info(notify, 4)
Exemple #3
0
 def info(self, key=None, indentation_level=0):
     trace = '  ' * indentation_level + '>' + self.name if indentation_level else self.parent.name + "->" + self.name
     AutoFix.info("{}:\t{} material(s)".format(trace, len(self.materials)),
                  1)
     indentation_level += 1
     # pass it along
     for x in self.materials:
         x.info(key, indentation_level)
Exemple #4
0
 def info(self, key=None, indentation=0):
     prefix = '>' + '  ' * indentation + self.name if indentation else '>(PAT0)' + self.name
     if key:
         AutoFix.info('{}: {}'.format(prefix, self.get_str(key)), 1)
     else:
         val = prefix + ': '
         for x in self.SETTINGS:
             val += ' ' + x + ':' + str(self.get_str(x))
         AutoFix.info(val, 1)
Exemple #5
0
    def encode(self,
               mdl,
               visible_bone=None,
               encoder=None,
               use_default_colors_if_none_found=True,
               priority=None,
               has_uv_mtx=None):
        if priority is not None:
            self.priority = priority
        if has_uv_mtx is not None:
            self.has_uv_mtx = has_uv_mtx
        if not visible_bone:
            if not mdl.bones:
                mdl.add_bone(mdl.name)
            visible_bone = mdl.bones[0]
            # if not linked_bone:
            #     self.linked_bone = visible_bone
        visible_bone.has_geometry = True
        self.encoded = p = Polygon(self.name, mdl)
        if encoder is not None:
            self.encoder = encoder
            encoder.before_encode(self)
        self.fmt_str = '>'
        if self.__encode_influences(p, self.influences, mdl, visible_bone):
            p.weight_index = self.ipp()
        self.__encode_tex_matrices(p, self.has_uv_mtx)
        if self.__encode_vertices(p, self.vertices, mdl):
            p.vertex_index = self.ipp()
        if self.__encode_normals(p, self.normals, mdl):
            p.normal_index = self.ipp()
        if self.__encode_colors(p, self.colors, mdl,
                                use_default_colors_if_none_found):
            p.color0_index = self.ipp()
        self.__encode_texcoords(p, self.texcoords, mdl)
        tris = self.__construct_tris(p, p.has_weights())
        data, p.face_count, p.facepoint_count = self.__encode_tris(
            tris, p.has_weights())
        past_align = len(data) % 0x20
        if past_align:
            data.extend(b'\0' * (0x20 - past_align))

        if p.face_count <= 0:
            # todo, cleanup?
            return None
        p.data = data
        p.encode_str = self.fmt_str
        mdl.objects.append(p)
        material = mdl.get_material_by_name(self.material_name)
        mdl.add_definition(material, p, visible_bone, self.priority)
        if self.colors and self.ENABLE_VERTEX_COLORS:
            AutoFix.info(
                '{} has colors, enabled vertex color in light channel.'.format(
                    self.name))
            material.enable_vertex_color()
        if encoder:
            encoder.after_encode(p)
        return p
Exemple #6
0
 def info(self, key=None, indentation_level=0):
     trace = '  ' * indentation_level + self.name if indentation_level else '>' + self.parent.name + "->" + self.name
     if key:
         val = self.get_str(key)
         AutoFix.info("{}\t{}:{}".format(trace, key, val), 1)
     else:
         AutoFix.info(
             "{}:\tScale:{} Rot:{} Trans:{}".format(trace, self.scale,
                                                    self.rotation,
                                                    self.translation), 1)
Exemple #7
0
 def _end_saving(self, writer):
     # dump json materials, create image library, write file
     MatsToJsonConverter(self.json_file).export(self.mdl0.materials)
     self.__add_pat0_images()
     self._create_image_library(self.tex0_map.values())
     os.chdir(self.cwd)
     writer.write(self.mdl_file)
     AutoFix.info('\t...finished in {} seconds.'.format(
         round(time.time() - self.start, 2)))
     return self.mdl_file
Exemple #8
0
 def rename_texture_link(self, layer, name):
     """Attempts to rename a layer, raises value error if the texture can't be found"""
     # No link found, try to find texture matching and create link
     if name != 'Null' and not self.parent.get_texture(name):
         tex = fuzzy_match(name, self.parent.textures)
         notify = 'Adding reference to unknown texture "{}"'.format(name)
         if tex:
             notify += ', did you mean ' + tex.name + '?'
         AutoFix.info(notify, 4)
     return name
Exemple #9
0
 def info(self, key='', indentation_level=0):
     if not key:
         m = max(3, len(self.SETTINGS))
         for i in range(m):
             setting = self.SETTINGS[i]
             key += setting + ':' + self.get_str(setting) + ' '
     else:
         key += ':' + self.get_str(key)
     start = '>' + indentation_level * '  '
     AutoFix.info('{}{}> {}'.format(start, self.name, key), 1)
Exemple #10
0
 def info(self, key=None, indentation_level=0):
     trace = '>' + '  ' * indentation_level if indentation_level else '>' + str(
         self.parent.get_material_name())
     if key:
         AutoFix.info(
             '{}->Stage:{}\t{}:{}'.format(trace, self.name, key, self[key]),
             1)
     else:
         AutoFix.info(
             '{}Stage:{}\tMapId:{} ColorScale:{}'.format(
                 trace, self.name, self['mapid'], self['colorscale']), 1)
Exemple #11
0
 def info(self, key=None, indentation_level=0):
     trace = '>' + '  ' * indentation_level if indentation_level else '>'
     if not key:
         AutoFix.info(
             '{}(Shader){}'.format(trace, self.get_material_name()), 1)
         indentation_level += 1
         for x in self.stages:
             x.info(key, indentation_level)
     else:
         AutoFix.info(
             '{}(Shader){}: {}:{} '.format(trace, self.get_material_name(),
                                           key, self[key]), 1)
Exemple #12
0
 def on_submit(self):
     path = self.path_edit.text()
     dir = os.path.dirname(path)
     if not os.path.exists(dir):
         AutoFix.error('Path {} does not exist!'.format(path))
     else:
         ImgConverter().decode(self.tex0,
                               path,
                               overwrite=True,
                               num_mips=self.mipmap_count.value())
         AutoFix.info('Exported {} to {}'.format(self.tex0.name, path))
         self.close()
Exemple #13
0
 def run(self):
     try:
         AutoFix.info('Started image manager...', 5)
         self.__clean()
         while self.enabled:
             if len(self.queue):
                 self.__decode_brres_images(self.queue.pop(0))
             else:
                 self.is_ready = True
             sleep(0.3)
     except:
         AutoFix.exception(shutdown=True)
Exemple #14
0
 def info(self, key=None, indentation_level=0):
     id = str(self.name)
     trace = '>' + '  ' * indentation_level + 'Tex:' + id if indentation_level else '>(SRT0)' \
                                                                              + self.parent.name + '->Tex:' + id
     if not key:
         for x in self.SETTINGS:
             anim = self.get_str(x)
             if len(anim) > 1:
                 trace += ' ' + x + ':' + str(anim)
         AutoFix.info(trace, 1)
     else:
         AutoFix.info('{}\t{}:{}'.format(trace, key, self.get_str(key)), 1)
Exemple #15
0
    def check(self, verts, norms, uvs, colors, materials
              ):  # as we go along, gather verts norms uvs colors materials
        modified = False
        vertices = self.get_vertex_group()
        if vertices:
            verts.add(vertices.name)
            if self.linked_bone:
                vertices.check_vertices(self.linked_bone)
        normals = self.get_normal_group()
        if normals:
            norms.add(normals.name)
        material = self.get_material()
        if material:
            materials.add(material.name)
        # Colors
        my_colors = self.get_color_group()
        uses_vertex_colors = material.is_vertex_color_enabled()
        if my_colors:
            colors.add(my_colors.name)
            if not uses_vertex_colors:
                AutoFix.info(f'{self.name} has unused vertex colors', 4)
        elif uses_vertex_colors:
            b = Bug(
                2, 2,
                f'{material.name} uses vertex colors but {self.name} has no colors!',
                'Disable vertex colors')
            material.enable_vertex_color(False)
            b.resolve()
            modified = True

        # UVs
        uvs_used = material.get_uv_channels()
        uv_count = 0
        for i in range(8):
            tex = self.get_uv_group(i)
            if tex:
                uv_count += 1
                uvs.add(tex.name)
                if i in uvs_used:
                    uvs_used.remove(i)
                else:
                    AutoFix.info(
                        f'{self.name} UV Channel {i} is not used by material.',
                        3)
            else:
                break
        if uvs_used:
            AutoFix.warn(
                f'{self.name} does not have UV channel(s) {uvs_used} but the material uses them!'
            )
        self.uv_count = uv_count
        return modified
Exemple #16
0
 def __init__(self, path):
     if self.LIBRARY is not None:
         raise RuntimeError('Already Initialized library!')
     if path is None:
         path = os.path.join(os.getcwd(), 'mat_lib.brres')
         self.LIBRARY_PATH = path
     try:
         self.brres = Brres(path)
     except FileNotFoundError as e:
         AutoFix.info(f'Material library "{path}" not found.')
         self.brres = Brres(path, read_file=False)
         self.brres.add_mdl0(Mdl0('lib', self.brres))
     self.on_brres_update()
Exemple #17
0
 def info(self, key=None, indentation_level=0):
     AutoFix.info(
         '{}{}:\t{} model(s)\t{} texture(s)'.format(
             '  ' * indentation_level + '>', self.name, len(self.models),
             len(self.textures)), 1)
     indentation_level += 2
     self.sub_info('MDL0', self.models, key, indentation_level)
     self.sub_info('TEX0', self.textures, key, indentation_level)
     # self.sub_info('PAT0', self.pat0, key, indentation_level)
     # self.sub_info('SRT0', self.srt0, key, indentation_level)
     self.sub_info('CHR0', self.chr0, key, indentation_level)
     self.sub_info('SCN0', self.scn0, key, indentation_level)
     self.sub_info('SHP0', self.shp0, key, indentation_level)
     self.sub_info('CLR0', self.clr0, key, indentation_level)
Exemple #18
0
 def add_tex0(self, tex0, replace=True, mark_modified=True):
     if tex0.name in self.texture_map:
         if not replace:
             return False
         self.remove_tex0(tex0.name)
         AutoFix.info('Replaced tex0 {}'.format(tex0.name))
     if tex0.parent is not None and tex0.parent is not self:
         t = Tex0(tex0.name, self)
         t.paste(tex0)
         tex0 = t
     self.textures.append(tex0)
     self.texture_map[tex0.name] = tex0
     tex0.parent = self  # this may be redundant
     if mark_modified:
         self.mark_modified()
     return True
Exemple #19
0
 def run(self):
     AutoFix.info('Started converter... ', 5)
     try:
         while True:
             if len(self.queue):
                 self.item = self.queue.pop(0)
                 self.item.convert()
                 self.signals.on_conversion_finish.emit(self.item)
                 self.item = None
                 # for x in self.observers:
                 #     x.on_conversion_finish(self.item)
             if not self.is_running:
                 break
             sleep(0.2)
     except:
         AutoFix.exception(shutdown=True)
Exemple #20
0
 def __init__(self, brres_files=[]):
     super().__init__()
     self.open_files = []
     self.brres = None
     self.image_updater = {}  # maps brres to list of subscribers
     self.cwd = os.getcwd()
     self.__init_threads()
     self.locked_files = set(
     )  # lock files that are pending conversion etc...
     # AutoFix.set_pipe(self)
     self.__init_UI()
     self.shell_is_shown = False
     self.shell = None
     for file in brres_files:
         self.open(file.name)
     AutoFix.info('Initialized main window', 5)
     self.show()
Exemple #21
0
 def save(self, filename=None, overwrite=None, check=True):
     if not filename:
         filename = self.name
     if overwrite is None:
         overwrite = self.OVERWRITE
     if not overwrite and os.path.exists(filename):
         AutoFix.error('File {} already exists!'.format(filename), 1)
     else:
         if check:
             self.check()
         f = BinFile(filename, mode="w")
         self.pack(f)
         if f.commitWrite():
             AutoFix.info("Wrote file '{}'".format(filename), 2)
             self.rename(filename)
             self.has_new_model = False
             self.mark_unmodified()
             return True
     return False
Exemple #22
0
 def info(self, key=None, indentation_level=0):
     trace = '>' + '  ' * indentation_level + self.name if indentation_level else '>' \
                                                                                  + self.parent.name + "->" + self.name
     if key in self.SETTINGS:
         val = self.getKey(key)
         if val is not None:
             AutoFix.info("{}\t{}:{}".format(trace, key, val), 1)
         return
     elif not key:
         AutoFix.info(
             "{}\txlu:{} cull:{}".format(trace, self.xlu,
                                         self.CULL_STRINGS[self.cullmode]),
             1)
     indentation_level += 1
     for x in self.layers:
         x.info(key, indentation_level)
     if self.srt0:
         self.srt0.info(key, indentation_level)
     elif self.pat0:
         self.pat0.info(key, indentation_level)
Exemple #23
0
 def __init_threads(self):
     AutoFix.info('Starting threads...', 5)
     self.threadpool = QThreadPool()  # for multi-threading
     self.threadpool.setMaxThreadCount(5)
     self.converter = converter = ConvertManager.get()
     converter.signals.on_conversion_finish.connect(
         self.on_conversion_finish)
     self.image_manager = image_manager = ImageManager.get()
     if image_manager.enabled:
         image_manager.signals.on_image_update.connect(self.on_image_update)
         self.threadpool.start(image_manager)
     else:
         AutoFix.warn(
             'Image Manager disabled, do you have Wiimms SZS Tools installed?'
         )
     self.threadpool.start(converter)
     log_pipe = LoggerPipe()
     log_pipe.info_sig.connect(self.info)
     log_pipe.warn_sig.connect(self.warn)
     log_pipe.error_sig.connect(self.error)
Exemple #24
0
 def check_group(self, group, used_set, extras=None):
     """
     helper function for check
     :param group, the group to check
     :param used_set, set of items with references
     """
     to_remove = []
     for x in group:
         if x.name not in used_set:
             AutoFix.info('Unused reference {}'.format(x.name), 3)
             if self.REMOVE_UNUSED_REFS:
                 to_remove.append(x)
         if extras and x.check(extras):
             self.mark_modified()
         elif x.check():
             self.mark_modified()
     if to_remove:
         AutoFix.info('(FIXED) Removed unused refs')
         for x in to_remove:
             group.remove(x)
Exemple #25
0
def perform_analysis(brres):
    s = ''
    has_count = 0
    if brres.chr0:
        s += ' has chr0'
    if brres.shp0:
        s += ' has shp0'
        has_count += 1
    if brres.clr0:
        s += ' has clr0'
        has_count += 1
    if brres.unused_pat0:
        s += ' has unused pat0'
    if brres.unused_srt0:
        s += ' has unused srt0'
    if brres.scn0:
        s += ' has scn0'
        has_count += 1
    if has_count:
        AutoFix.info(f'{brres.name} {s}')
    # AutoFix.info('Analyzing {}'.format(brres.name))
    export = False
Exemple #26
0
 def check(self):
     AutoFix.info('checking file {}'.format(self.name), 4)
     expected = self.get_expected_mdl_name()
     if self.MOONVIEW:
         self.check_moonview()
         Brres.MOONVIEW = False
     for mdl in self.models:
         mdl.check(expected)
         expected = None
     tex_names = set(self.get_texture_map().keys())
     tex_used = self.get_used_textures()
     unused = tex_names - tex_used
     if unused:
         b = Bug(4, 3, 'Unused textures: {}'.format(unused),
                 'Remove textures')
         if self.REMOVE_UNUSED_TEXTURES:
             self.remove_unused_textures(unused)
             b.resolve()
             self.mark_modified()
     all_tex = [x for x in self.textures]
     for tex in all_tex:
         tex.check()
Exemple #27
0
 def _start_loading(self, model_name):
     AutoFix.info('Converting {}... '.format(self.mdl_file))
     self.start = time.time()
     self.image_library = set()
     self.geometries = []
     self.cwd = os.getcwd()
     self.import_textures_map = {}
     self.mdl_file = os.path.abspath(self.mdl_file)
     library = MaterialLibrary.get()
     self.material_library = library.materials if library else None
     brres_dir, brres_name = os.path.split(self.brres.name)
     base_name = os.path.splitext(brres_name)[0]
     mdl_file_base_name = os.path.splitext(os.path.basename(
         self.mdl_file))[0]
     self.is_map = True if 'map' in base_name or mdl_file_base_name == 'map_model' else False
     work_dir, name = os.path.split(self.mdl_file)
     self.json_file = os.path.join(work_dir,
                                   os.path.splitext(name)[0]) + '.json'
     if work_dir:
         os.chdir(work_dir)  # change to the dir to help find relative paths
     return self._init_mdl0(brres_name,
                            os.path.splitext(name)[0], model_name)
Exemple #28
0
 def _end_loading(self):
     mdl0 = self.mdl0
     import_path_map = self.__normalize_image_path_map(
         self.import_textures_map)
     self._import_images(import_path_map)
     mdl0.rebuild_header()
     self.brres.add_mdl0(mdl0)
     if self.is_map:
         mdl0.add_map_bones()
     os.chdir(self.cwd)
     if self.ENCODE_PRESET:
         if not self.ENCODE_PRESET_ON_NEW or (
                 self.replacement_model is None
                 and self.json_polygon_encoding is None):
             Command('preset ' + self.ENCODE_PRESET + ' for * in ' +
                     self.brres.name + ' model ' +
                     self.mdl0.name).run_cmd()
     AutoFix.info('\t... finished in {} secs'.format(
         round(time.time() - self.start, 2)))
     if self.encoder:
         self.encoder.after_encode(mdl0)
     return mdl0
Exemple #29
0
 def info(self, key=None, indentation=0):
     AutoFix.info(
         '{} {}: {} {}x{} mips:{}'.format(self.MAGIC, self.name,
                                          self.FORMATS[self.format],
                                          self.width, self.height,
                                          self.num_mips), 1)