Esempio n. 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
Esempio n. 2
0
 def unpack(self, pt, binfile):
     start = binfile.start()
     l = binfile.readLen()
     binfile.advance(4)
     binfile.store()
     binfile.advance(4)
     pt.index, pt.comp_count, pt.format, pt.divisor, pt.stride, pt.count = binfile.read(
         '3I2BH', 16)
     if not self.is_valid_comp_count(pt.comp_count):
         AutoFix.error(
             '{} has invalid component count {}, using default {}'.format(
                 pt.name, pt.comp_count, pt.default_comp_count))
         pt.comp_count = pt.default_comp_count
     if not is_valid_format(pt.format):
         # determine the format using the file length
         binfile.recall(pop=False)
         old_format = pt.format
         bytes_remaining = start + l - binfile.offset
         width = bytes_remaining // (pt.count * pt.comp_count)
         if width >= 4:
             pt.format = point.FMT_FLOAT
         elif width >= 2:  # assumes unsigned
             pt.format = point.FMT_INT16
         else:
             pt.format = point.FMT_INT8
         AutoFix.error('{} has invalid format {}, using format {}'.format(
             pt.name, old_format, point.FMT_STR[pt.format]))
Esempio n. 3
0
 def rename(self):
     node = self.get_indexed_item(self.clicked_index)
     if self.level == 0:
         self.handler.save_as_dialog()
     elif self.level == 1:
         brres = node.parent
         old_name = node.name
         text, ok = QInputDialog.getText(self,
                                         'Rename Node',
                                         'Rename to:',
                                         text=old_name)
         if ok and text != old_name:
             if brres.get_model(text):
                 AutoFix.error(
                     'Model with name {} already exists!'.format(text))
                 return
             node.rename(text)
             self.handler.on_rename_update(node, old_name)
     elif self.level == 2:
         mdl0 = node.parent
         text, ok = QInputDialog.getText(self,
                                         'Rename Node',
                                         'Rename to:',
                                         text=node.name)
         if ok:
             if text in [x.name for x in mdl0.objects]:
                 AutoFix.error(
                     'Polygon with name {} already exists!'.format(text))
                 return
             node.rename(text)
Esempio n. 4
0
 def pack(self, fog, binfile):
     AutoFix.warn('packing scn0 fog is not supported.')
     pack_header(binfile, fog.name, fog.node_id, fog.real_id)
     binfile.write('4BI2f', fog.flags, 0, 0, 0, fog.type, fog.start,
                   fog.end)
     binfile.write('4B', fog.color)
     binfile.end()
Esempio n. 5
0
 def info(self, key=None, indentation_level=0):
     trace = '>' + '  ' * indentation_level if indentation_level else '>' + str(self.parent.getMaterialName())
     if key:
         AutoFix.get().info('{}->Stage:{}\t{}:{}'.format(trace, self.name, key, self[key]), 1)
     else:
         AutoFix.get().info('{}Stage:{}\tMapId:{} ColorScale:{}'.format(
             trace, self.name, self['mapid'], self['colorscale']), 1)
Esempio n. 6
0
 def set_lightset_str(self, str):
     val = int(str)
     if val > 0:
         AutoFix.warn("Unusual lightset " + str + ", expected -1")
     if self.lightset != val:
         self.lightset = val
         self.mark_modified()
Esempio n. 7
0
 def decode(self, tex0, dest_file, overwrite=None, num_mips=0):
     if overwrite is None:
         overwrite = self.OVERWRITE_IMAGES
     if not dest_file:
         dest_file = tex0.name + '.png'
     elif os.path.isdir(dest_file):
         dest_file = os.path.join(dest_file, tex0.name + '.png')
     elif os.path.splitext(
             os.path.basename(dest_file))[1].lower() != '.png':
         dest_file += '.png'
     if not overwrite and os.path.exists(dest_file):
         AutoFix.warn('File {} already exists!'.format(dest_file))
         return None
     tmp = self.get_temp_dest()
     f = BinFile(tmp, 'w')
     tex0.pack(f)
     f.commitWrite()
     if num_mips == 0:
         mips = '--no-mipmaps'
     elif num_mips == -1:
         mips = '--n-mm=auto'
     else:
         mips = '--n-mm=' + str(num_mips)
     result = subprocess.call(
         [self.converter, 'decode', tmp, '-d', dest_file, mips, '-qo'],
         startupinfo=self.si)
     if tmp != dest_file:
         os.remove(tmp)
     if result:
         raise DecodeError('Failed to decode {}'.format(tex0.name))
     return dest_file
Esempio n. 8
0
 def __init__(self, filename, read_file=True):
     self.geometries = []
     self.vertices = []
     self.normals = []
     self.texcoords = []
     self.materials = {}
     self.images = set()
     self.filename = filename
     if read_file:
         self.mtllib = None
         self.parse_file(filename)
         to_remove = []
         for geo in self.geometries:
             try:
                 geo.normalize(self.vertices, self.normals, self.texcoords)
             except ValueError:
                 to_remove.append(geo)
                 AutoFix.warn('No geometry found for {}'.format(geo.name))
         if to_remove:
             self.geometries = [
                 x for x in self.geometries if x not in to_remove
             ]
     else:
         dir, name = os.path.split(filename)
         base_name = os.path.splitext(name)[0]
         self.mtllib = base_name + '.mtl'
Esempio n. 9
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)
Esempio n. 10
0
 def post_unpacking(self, brres):
     for x in brres.textures:
         brres.texture_map[x.name] = x
     brres.unused_pat0 = self.post_unpack_anim(self.pat0, 'materials', 'pat0')
     brres.unused_srt0 = self.post_unpack_anim(self.srt0, 'materials', 'srt0')
     if brres.unused_pat0 or brres.unused_srt0:
         AutoFix.warn('Unused animations detected')
Esempio n. 11
0
 def run(self, prefix, cmd):
     line = prefix + ' ' + cmd
     self.cmd_queue.append(line)
     try:
         Command.run_commands([Command(line)])
     except (ParsingException, NoSuchFile) as e:
         AutoFix.get().exception(e)
Esempio n. 12
0
 def __encode_vertices(self, polygon, vertices, mdl0):
     vert = Vertex(self.name, mdl0)
     mdl0.add_to_group(mdl0.vertices, vert)
     linked_bone = self.linked_bone
     points = vertices.points
     if polygon.has_weighted_matrix():
         AutoFix.get().warn(
             f'Polygon weighting is experimental, {polygon.name} will likely be incorrect.'
         )
         for i in range(len(vertices)):
             influence = self.influences[i]
             points[i] = influence.apply_to(points[i], decode=False)
         vertex_format, vertex_divisor, remapper = vertices.encode_data(
             vert, True)
         if remapper is not None:
             new_inf_map = {}
             old_inf_map = self.influences.influences
             for i in old_inf_map:
                 new_inf_map[remapper[i]] = old_inf_map[i]
             self.influences.influences = new_inf_map
     else:
         rotation_matrix = get_rotation_matrix(
             np.array(linked_bone.get_transform_matrix(), dtype=float))
         for i in range(len(points)):
             points[i] = np.dot(rotation_matrix, points[i])
         inv_matrix = np.array(linked_bone.get_inv_transform_matrix(),
                               dtype=float)
         vertices.points = apply_matrix(inv_matrix, vertices.points)
         vertices.encode_data(vert, False)
     polygon.vertices = vert
     self.fmt_str += get_index_format(vert)
     return True
Esempio n. 13
0
 def remove_tex0(self, name):
     try:
         tex = self.texture_map.pop(name)
         self.textures.remove(tex)
         self.mark_modified()
     except KeyError:
         AutoFix.get().warn('No texture {} in {}'.format(name, self.name))
Esempio n. 14
0
 def set_pat0(self, anim):
     if self.pat0:
         AutoFix.error(
             'Multiple Pat0 for {} in {}!'.format(self.name,
                                                  self.getBrres().name), 1)
         return False
     self.pat0 = anim
     return True
Esempio n. 15
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)
Esempio n. 16
0
 def unpack_unknown(self):
     if self.uk_offsets:
         AutoFix.warn('Unknown files {}, may be loosely supported'.format([x[0] for x in self.uk_offsets]))
     uk = []
     for name, offset in self.uk_offsets:
         self.binfile.offset = offset
         uk.append(UnknownUnpacker(self.binfile, self.section_offsets, name).node)
     return uk
Esempio n. 17
0
 def hook_textures(self, textures):
     m = len(textures)
     for x in self.node.frames:
         if x.tex >= m:
             x.tex = textures[0]
             AutoFix.get().warn('Unpacked Pat0 {} tex_id out of range'.format(self.node.name), 1)
         else:
             x.tex = textures[x.tex]
Esempio n. 18
0
 def set_srt0(self, anim):
     """This is called by model to set up the srt0 reference"""
     if self.srt0:
         AutoFix.error('Multiple Srt0 for {}'.format(self.name), 1)
         return False
     self.srt0 = anim
     anim.set_material(self)
     return True
Esempio n. 19
0
 def set_light_ref_str(self, value):
     i = int(value)
     if i > 0:
         AutoFix.warn('{} set unusual light ref {}, expected -1'.format(
             self.name, value))
     if self.scn0_light_ref != i:
         self.scn0_light_ref = i
         self.mark_modified()
Esempio n. 20
0
 def try_parse(self, text):
     try:
         self.cmds_run.append(text)
         if len(self.cmds_run) > 10:
             self.cmds_run.pop(0)
         return Command.run_commands([Command(text)])
     except ParsingException as e:
         AutoFix.get().error(str(e))
         return False
Esempio n. 21
0
 def info(self, key=None, indentation=0):
     prefix = '>' + '  ' * indentation + self.name if indentation else '>(PAT0)' + self.name
     if key:
         AutoFix.get().info('{}: {}'.format(prefix, self.get_str(key)), 1)
     else:
         val = prefix + ': '
         for x in self.SETTINGS:
             val += ' ' + x + ':' + str(self.get_str(x))
         AutoFix.get().info(val, 1)
Esempio n. 22
0
 def run_commands(commandlist):
     try:
         for cmd in commandlist:
             cmd.run_cmd()
     except (ValueError, SaveError, PasteError, MaxFileLimit, NoSuchFile, FileNotFoundError, ParsingException,
             OSError, UnpackingError, PackingError, NotImplementedError, NoImgConverterError, RuntimeError) as e:
         AutoFix.get().exception(e)
         return False
     return True
Esempio n. 23
0
 def _create_image_library(self, tex0s):
     if not tex0s:
         return True
     converter = ImgConverter()
     if not converter:
         AutoFix.get().error('No image converter found!')
         return False
     converter.batch_decode(tex0s, self.image_dir)
     return True
Esempio n. 24
0
 def on_submit(self):
     path = self.path_edit.text()
     dir = os.path.dirname(path)
     if not os.path.exists(dir):
         AutoFix.get().error('Path {} does not exist!'.format(path))
     else:
         ImgConverter().decode(self.tex0, path, overwrite=True, num_mips=self.mipmap_count.value())
         AutoFix.get().info('Exported {} to {}'.format(self.tex0.name, path))
         self.close()
Esempio n. 25
0
 def rename(self):
     if self.material is not None:
         current_name = self.material.name
         text, ok = QInputDialog.getText(self, 'Rename Node', 'Rename to:', text=current_name)
         if ok and text != current_name:
             if self.material.parent.get_material_by_name(text) is not None:
                 AutoFix.get().error('Material with name {} already exists!'.format(text))
                 return
             self.material.rename(text)
Esempio n. 26
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
Esempio n. 27
0
 def save_as_dialog(self):
     if self.brres:
         fname, filter = QFileDialog.getSaveFileName(
             self, 'Save as', self.cwd, 'Brres files (*.brres)')
         if fname:
             self.cwd = os.path.dirname(fname)
             self.brres.save(fname, overwrite=True)
             self.update_status('Wrote file {}'.format(fname))
     else:
         AutoFix.get().error('No Brres file selected.')
Esempio n. 28
0
 def _end_loading(self):
     mdl0 = self.mdl0
     mdl0.rebuild_header()
     self.brres.add_mdl0(mdl0)
     if self.is_map:
         mdl0.add_map_bones()
     os.chdir(self.cwd)
     AutoFix.get().info('\t... finished in {} secs'.format(
         round(time.time() - self.start, 2)))
     return mdl0
Esempio n. 29
0
 def _try_import_textures(brres, image_paths):
     if len(image_paths):
         try:
             converter = ImgConverter()
             converter.batch_encode(image_paths.values(),
                                    brres,
                                    overwrite=converter.OVERWRITE_IMAGES)
         except EncodeError:
             AutoFix.get().warn('Failed to encode images')
     return image_paths
Esempio n. 30
0
 def enqueue(self, converter):
     if converter == self.item:
         AutoFix.get().error('Conversion already in progress!')
         return False
     for x in self.queue:
         if x == converter:
             AutoFix.get().error('Conversion already in progress!')
             return False
     self.queue.append(converter)
     return True