def load(self, filepath): data = nif.NiStream() data.load(filepath) # attach kf file if self.attach_keyframe_data: self.import_keyframe_data(data, filepath) # apply settings data.apply_scale(self.scale_correction) # resolve heirarchy roots = self.resolve_nodes(data.roots) # resolve armatures if any(self.armatures): self.resolve_armatures() self.apply_axis_corrections() self.correct_rest_positions() # create bl objects for node, cls in self.nodes.items(): if node.output is None: cls(node).create() node.animation.create() # set active object bpy.context.view_layer.objects.active = self.get_root_output(roots)
def save(self, filepath): bl_objects = self.get_source_objects() # resolve heirarchy roots = self.resolve_nodes(bl_objects) # resolve armatures if any(self.armatures): self.resolve_armatures() self.apply_axis_corrections() # resolve depsgraph self.resolve_depsgraph() # uniform scale fix for root in roots: root.ensure_uniform_scale() # create ni objects for node, cls in self.nodes.items(): if node.output is None: cls(node).create() node.animation.create() data = nif.NiStream() data.root = self.get_root_output(roots) data.apply_scale(self.scale_correction) data.merge_properties(ignore={"name", "shine", "specular_color"}) data.sort() data.save(filepath) # extract x/kf file if self.extract_keyframe_data: self.export_keyframe_data(data, filepath)
def import_keyframe_data(data, filepath): kf_path = pathlib.Path(filepath).with_suffix(".kf") if not kf_path.exists(): print(f'import_keyframe_data: "{kf_path}" does not exist') else: kf_data = nif.NiStream() kf_data.load(kf_path) data.attach_keyframe_data(kf_data)
def extract_keyframe_data(self) -> NiStream: """Extract animation data. Useful for generating 'x.nif' and 'x.kf' files.""" # extract text data for obj in self.objects_of_type(nif.NiObjectNET): text_data = obj.extra_datas.discard_type(nif.NiTextKeyExtraData) if text_data: break else: raise ValueError( "extract_keyframe_data: no NiTextKeyExtraData object was found." ) # extract controllers kf_controllers = {} def extract_kf_controller(owner): if isinstance(owner, nif.NiObjectNET): kf_controller = owner.controllers.discard_type( nif.NiKeyframeController) if kf_controller: kf_controller.target = None kf_controllers[owner] = kf_controller for root in self.roots: extract_kf_controller(root) for node in root.descendants(): extract_kf_controller(node) if not kf_controllers: raise ValueError( "extract_keyframe_data: no NiKeyframeController objects were found." ) # create x.kf output output = nif.NiStream() # assign root object output.root = nif.NiSequenceStreamHelper(extra_data=text_data) # assign controllers extra_datas = [] controllers = [] for target, controller in kf_controllers.items(): extra_data = nif.NiStringExtraData(string_data=target.name) extra_datas.append(extra_data) controllers.append(controller) output.root.extra_datas.extend(extra_datas) output.root.controllers.extend(controllers) return output
def execute(self): data = nif.NiStream() data.load(self.filepath) data.merge_properties() # fix transforms if self.discard_root_transforms: data.root.matrix = ID44 # attach kf file if self.attach_keyframe_data: self.import_keyframe_data(data) # copy file name if data.root.name == "": data.root.name = self.filepath.name # scale correction data.apply_scale(self.scale_correction) # resolve heirarchy roots = self.resolve_nodes(data.roots) # resolve armatures if any(self.armatures): self.resolve_armatures() self.correct_rest_positions() self.apply_axis_corrections() self.correct_bone_parenting() # discard frame pos frame_current = bpy.context.scene.frame_current bpy.context.scene.frame_set(0) # create bl objects for node, cls in self.nodes.items(): if node.output is None: cls(node).create() # unmute animations for node in map(self.get, self.armatures): node.animation.set_mute(False) # restore frame pos bpy.context.scene.frame_current = frame_current # set active object bpy.context.view_layer.objects.active = self.get_root_output(roots)