Example #1
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.getModel(text):
                 AutoFix.get().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.get().error(
                     'Polygon with name {} already exists!'.format(text))
                 return
             node.rename(text)
Example #2
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.get().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'
Example #3
0
 def add_texture_link(self, name):
     if name != 'Null' and not self.parent.getTexture(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.get().info(notify, 4)
Example #4
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))
Example #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)
Example #6
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)
Example #7
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
Example #8
0
 def info(self, key=None, indentation_level=0):
     trace = '  ' * indentation_level + '>' + self.name if indentation_level else self.parent.name + "->" + self.name
     AutoFix.get().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)
Example #9
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]
Example #10
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()
Example #11
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
Example #12
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)
Example #13
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)
Example #14
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
Example #15
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
Example #16
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.getTexture(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.get().info(notify, 4)
     return name
Example #17
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.get().info('{}{}> {}'.format(start, self.name, key), 1)
Example #18
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.')
Example #19
0
 def unpack_frames(self, pat0, binfile):
     # frame header
     size, _, scale_factor = binfile.read('2Hf', 8)
     frames = pat0.frames
     for i in range(size):
         frame_id, tex_id, plt_id = binfile.read('f2H', 8)
         if frame_id > pat0.framecount:
             AutoFix.get().warn('Unpacked Pat0 {} frame index out of range'.format(pat0.name), 1)
             break
         frames.append(pat0.Frame(frame_id, tex_id, plt_id))
Example #20
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
Example #21
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
Example #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:
         val = self.get_str(key)
         AutoFix.get().info("{}\t{}:{}".format(trace, key, val), 1)
     else:
         AutoFix.get().info(
             "{}:\tScale:{} Rot:{} Trans:{}".format(trace, self.scale,
                                                    self.rotation,
                                                    self.translation), 1)
Example #23
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
Example #24
0
 def set_convert(self, params):
     flags = 0
     self.name = self.destination = self.model = None
     while len(params):
         param = params.pop(0)
         lower = param.lower()
         if lower == 'to':
             try:
                 self.destination = os.path.normpath(params.pop(0))
             except IndexError:
                 raise ParsingException('Expected destination after "to"')
         elif lower == 'in':
             self.model = self.name
             try:
                 self.name = os.path.normpath(params.pop(0))
             except IndexError:
                 raise ParsingException('Expected brres filename after keyword "in"')
         elif lower == 'no-normals':
             flags |= 1
         elif lower == 'no-colors':
             flags |= 2
         elif not self.name:
             self.name = os.path.normpath(param)
         else:
             raise ParsingException('Unknown parameter {}'.format(param))
     self.ext = None
     supported_formats = ('.dae', '.obj')
     self.is_import = False
     if self.name:
         dir, filename = os.path.split(self.name)
         base_name, ext = os.path.splitext(filename)
         ext = ext.lower()
         if ext in supported_formats:
             self.is_import = True
             self.ext = ext
     if self.destination and self.is_import:
         dir, filename = os.path.split(self.destination)
         split = os.path.splitext(filename)
         try:
             ext = split[1]
         except IndexError:
             ext = None
         if ext is None or ext.lower() != '.brres':
             if ext:
                 AutoFix.get().warn('Unsupported target extension {}, using .brres'.format(ext))
             self.destination += '.brres'
     if not self.is_import:
         if not self.destination:
             raise ParsingException('Convert requires target!')
         dir, filename = os.path.split(self.destination)
         base_name, ext = os.path.splitext(filename)
         self.ext = ext.lower()
         if self.ext not in supported_formats:
             raise ParsingException('Unsupported export format {}'.format(self.ext))
     self.flags = flags
Example #25
0
 def on_brres_update(self):
     self.materials = {}
     self.brres.register_observer(self)
     for model in self.brres.models:
         model.register_observer(self)
         for material in model.materials:
             material.register_observer(self)
             if material.name not in self.materials:
                 self.materials[material.name] = material
             else:
                 AutoFix.get().warn('Multiple materials named {} in material library'.format(material.name))
Example #26
0
 def get_index_type(self, index):
     """
     Returns the INDEX_FORMAT
     """
     if index < 0:
         return INDEX_FORMAT_NONE
     else:
         try:
             return INDEX_FORMAT_BYTE if self.encode_str[index + 1] == 'B' else INDEX_FORMAT_SHORT
         except IndexError:
             AutoFix.get().error(f'Polygon {self.name} in {self.parent.parent.name} tri index {index} out of range.')
Example #27
0
 def run_cmd(self):
     if self.hasSelection:
         if not self.updateSelection(self.file, self.model, self.name):
             AutoFix.get().warn('No selection found for "{}"'.format(self.txt))
             return False
         elif self.cmd == 'select':
             return True
     elif not self.MATERIALS and self.cmd == 'info':
         if self.key == 'keys':
             ctype = self.type if self.type else self.SELECT_TYPE
             self.info_keys(ctype)
             return True
         # self.file = self.model = self.name = None
         # self.updateSelection(None)         # reset selection
     if self.cmd == 'preset':
         return self.runPreset(self.key)
     elif self.cmd == 'convert':
         return self.run_convert()
     if not self.ACTIVE_FILES:
         raise RuntimeError('No file detected! ({})'.format(self.txt))
     if self.cmd == 'save':
         self.run_save()
         return True
     self.updateTypeSelection()
     if not self.SELECTED:
         if self.cmd == 'info':
             AutoFix.get().info('No items in selection.')
             return True
         raise RuntimeError('No items found in selection! ({})'.format(self.txt))
     if self.cmd == 'set':
         self.markModified()
         for x in self.SELECTED:
             x.set_str(self.key, self.value)
     elif self.cmd == 'info':
         if self.key == 'keys':
             self.info_keys(self.SELECT_TYPE)
         else:
             for x in self.SELECTED:
                 x.info(self.key)
         # for y in self.ACTIVE_FILES:
         #     print(y.name)
     elif self.cmd == 'add':
         self.markModified()
         self.add(self.SELECT_TYPE, self.SELECT_ID)
     elif self.cmd == 'remove':
         self.markModified()
         self.remove(self.SELECT_TYPE, self.SELECT_ID)
     elif self.cmd == 'copy':
         self.run_copy(self.SELECT_TYPE)
     elif self.cmd == 'paste':
         self.markModified()
         self.run_paste(self.SELECT_TYPE)
     return True
Example #28
0
 def run(self):
     try:
         AutoFix.get().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.get().exception(shutdown=True)
Example #29
0
 def info(self, key=None, indentation_level=0):
     AutoFix.get().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)
Example #30
0
 def info(self, key=None, indentation_level=0):
     trace = '>' + '  ' * indentation_level if indentation_level else '>'
     if not key:
         AutoFix.get().info(
             '{}(Shader){}'.format(trace, self.getMaterialName()), 1)
         indentation_level += 1
         for x in self.stages:
             x.info(key, indentation_level)
     else:
         AutoFix.get().info(
             '{}(Shader){}: {}:{} '.format(trace, self.getMaterialName(),
                                           key, self[key]), 1)