Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
ca0c37d
Removed unecessary import from kf_import.py
Candoran2 Sep 17, 2022
7153b53
Updated kf_export.py to remove unused imports.
Candoran2 Sep 18, 2022
19e0294
Made changes necessary to export ZT2 kf.
Candoran2 Sep 18, 2022
11cb4db
Made changes for FO3 kf export.
Candoran2 Sep 18, 2022
e8b70e4
Added missed reset_field and added validation step before writing kf.
Candoran2 Sep 23, 2022
1ddbe4f
Transferred nif import to use the new library.
Candoran2 Sep 25, 2022
fa20764
Updated vertex group import for new library.
Candoran2 Sep 26, 2022
41308e5
Made changes to use new library for nif export.
Candoran2 Sep 26, 2022
9dce93a
Updated BS data flags export.
Sep 27, 2022
a7dbd75
Removed now-unnecessary .decode calls.
Sep 27, 2022
a4b804b
Made makezip.bat work with dir paths with spaces.
Sep 27, 2022
0977c88
Let n_node_type override detected one (needed for BSFadeNode as root …
Candoran2 Sep 27, 2022
6223cc6
Fix skin_partition_blocks > partitions because of xml change and shad…
Candoran2 Sep 27, 2022
57e8778
Added forgotten .classes.
Candoran2 Sep 29, 2022
0f9d234
Replaced NifFormat.classes with direct import of classes as NifClasses.
Candoran2 Sep 29, 2022
1305247
Changed game property to only allow games for supported versions.
Candoran2 Sep 30, 2022
0186864
Added initial support for static SSE nif import.
Candoran2 Oct 3, 2022
8637f4a
Couple small fixes, and #521 - partially.
Candoran2 Oct 3, 2022
1b5f91e
Finished adjustment to partition/body party import to directly use pa…
Candoran2 Oct 3, 2022
a897ebe
Added changes to import skinned BSTriShape, and corrected error in ma…
Candoran2 Oct 5, 2022
ed32f48
Normalization of ByteVector3 no longer necessary in addon code - is h…
Candoran2 Oct 6, 2022
d3dbf40
Replaced uses of Enum._name_ with Enum.name (_name_ is writeable, nam…
Candoran2 Oct 6, 2022
88c1c91
Replaced Enum._value_ with Enum.value, since the latter is read-only.
Candoran2 Oct 6, 2022
f3b7fa9
Followed f-string suggestions, as well as enum access and itertools.c…
Candoran2 Oct 7, 2022
e574d05
Removed modulo % 256 from texture clamp mode because it's no longer n…
Candoran2 Oct 7, 2022
9166bb0
Simplified havok material import due to xml changes and fixed BSEffec…
Candoran2 Oct 7, 2022
3934ff8
Removed KFFile class and used NifFile instead for KF import since cod…
Candoran2 Oct 7, 2022
56ab2c3
Removed uses of safe_decode and moved it to generated code.
Candoran2 Oct 9, 2022
70203cb
Did small fixes for codegen and migrated updated save_as_dds function…
Candoran2 Oct 11, 2022
0e280a4
Changed BSEffectShaderProperty import/export to reflect xml changes.
Candoran2 Oct 15, 2022
432f845
Updated (some) collision import and export for xml.
Candoran2 Oct 16, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions install/makezip.bat
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,14 @@ xcopy "%ROOT%"\LICENSE.rst io_scene_niftools
xcopy "%ROOT%"\README.rst io_scene_niftools
popd

powershell -executionpolicy bypass -Command "%DIR%\zip.ps1" -source "%DIR%\temp\io_scene_niftools" -destination "%DIR%\%ZIP_NAME%.zip"
rmdir /s /q %DIR%\temp
set "COMMAND_FILE=%DIR%\zip.ps1"
set "COMMAND_FILE=%COMMAND_FILE: =` %"

set "SOURCE_DIR=%DIR%\temp\io_scene_niftools"
set "SOURCE_DIR=%SOURCE_DIR: =` %"

set "DESTINATION_DIR=%DIR%\%ZIP_NAME%.zip"
set "DESTINATION_DIR=%DESTINATION_DIR: =` %"

powershell -executionpolicy bypass -Command "%COMMAND_FILE%" -source "%SOURCE_DIR%" -destination "%DESTINATION_DIR%"
rmdir /s /q "%DIR%\temp"
4 changes: 2 additions & 2 deletions io_scene_niftools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ def locate_dependencies():

with open(os.path.join(current_dir, "VERSION.txt")) as version:
NifLog.info(f"Loading: Blender Niftools Addon: {version.read()}")
import pyffi
NifLog.info(f"Loading: PyFFi: {pyffi.__version__}")
import generated.formats.nif as NifFormat
NifLog.info(f"Loading: NifFormat: {NifFormat.__xml_version__}") # todo [generated] update this and library to have actual versioning


locate_dependencies()
Expand Down
69 changes: 0 additions & 69 deletions io_scene_niftools/file_io/kf.py

This file was deleted.

17 changes: 9 additions & 8 deletions io_scene_niftools/file_io/nif.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@
#
# ***** END LICENSE BLOCK *****

import os.path as path

from pyffi.formats.nif import NifFormat
import generated.formats.nif as NifFormat

from io_scene_niftools.utils.logging import NifLog, NifError

Expand All @@ -51,18 +52,18 @@ def load_nif(file_path):
"""Loads a nif from the given file path"""
NifLog.info(f"Importing {file_path}")

data = NifFormat.Data()
file_ext = path.splitext(file_path)[1]

# open file for binary reading
with open(file_path, "rb") as nif_stream:
# check if nif file is valid
data.inspect_version_only(nif_stream)
if data.version >= 0:
modification, (version, user_version, bs_version) = NifFormat.NifFile.inspect_version_only(nif_stream)
if version >= 0:
# it is valid, so read the file
NifLog.info(f"NIF file version: {data.version:x}")
NifLog.info("Reading file")
data.read(nif_stream)
elif data.version == -1:
NifLog.info(f"NIF file version: {version:x}")
NifLog.info(f"Reading {file_ext} file")
data = NifFormat.NifFile.from_stream(nif_stream)
elif version == -1:
raise NifError("Unsupported NIF version.")
else:
raise NifError("Not a NIF file.")
Expand Down
6 changes: 2 additions & 4 deletions io_scene_niftools/kf_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@
import os
import bpy

import pyffi.spells.nif.fix

from io_scene_niftools.file_io.kf import KFFile
from io_scene_niftools.modules.nif_export import armature
from io_scene_niftools.modules.nif_export.animation.transform import TransformAnimation
from io_scene_niftools.nif_common import NifCommon
from io_scene_niftools.utils import math
Expand Down Expand Up @@ -95,6 +91,8 @@ def execute(self):
# scale correction for the skeleton
self.apply_scale(data, round(1 / NifOp.props.scale_correction))

data.validate()

kffile = os.path.join(directory, prefix + filebase + ext)
with open(kffile, "wb") as stream:
data.write(stream)
Expand Down
7 changes: 2 additions & 5 deletions io_scene_niftools/kf_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,7 @@

import os

import pyffi.spells.nif.fix

from io_scene_niftools.file_io.kf import KFFile
from io_scene_niftools.modules.nif_export import armature
from io_scene_niftools.file_io.nif import NifFile as KFFile
from io_scene_niftools.modules.nif_import.animation.transform import TransformAnimation
from io_scene_niftools.nif_common import NifCommon
from io_scene_niftools.utils import math
Expand Down Expand Up @@ -72,7 +69,7 @@ def execute(self):
# get nif space bind pose of armature here for all anims
self.transform_anim.get_bind_data(b_armature)
for kf_file in kf_files:
kfdata = KFFile.load_kf(kf_file)
kfdata = KFFile.load_nif(kf_file)

self.apply_scale(kfdata, NifOp.props.scale_correction)

Expand Down
22 changes: 11 additions & 11 deletions io_scene_niftools/modules/nif_export/animation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
from abc import ABC

import bpy
from pyffi.formats.nif import NifFormat
from generated.formats.nif import classes as NifClasses

from io_scene_niftools.modules.nif_export.block_registry import block_store
from io_scene_niftools.utils.singleton import NifOp, NifData
Expand Down Expand Up @@ -93,14 +93,14 @@ def get_controllers(nodes):
"""find all nodes and relevant controllers"""
node_kfctrls = {}
for node in nodes:
if not isinstance(node, NifFormat.NiAVObject):
if not isinstance(node, NifClasses.NiAVObject):
continue
# get list of all controllers for this node
ctrls = node.get_controllers()
for ctrl in ctrls:
if bpy.context.scene.niftools_scene.game == 'MORROWIND':
# morrowind: only keyframe controllers
if not isinstance(ctrl, NifFormat.NiKeyframeController):
if not isinstance(ctrl, NifClasses.NiKeyframeController):
continue
if node not in node_kfctrls:
node_kfctrls[node] = []
Expand Down Expand Up @@ -132,14 +132,14 @@ def create_controller(self, parent_block, target_name, priority=0):
# link interpolator from the controller
n_kfc.interpolator = n_kfi
# if parent is a node, attach controller to that node
if isinstance(parent_block, NifFormat.NiNode):
if isinstance(parent_block, NifClasses.NiNode):
parent_block.add_controller(n_kfc)
if n_kfi:
# set interpolator default data
n_kfi.scale, n_kfi.rotation, n_kfi.translation = parent_block.get_transform().get_scale_quat_translation()

# else ControllerSequence, so create a link
elif isinstance(parent_block, NifFormat.NiControllerSequence):
elif isinstance(parent_block, NifClasses.NiControllerSequence):
controlled_block = parent_block.add_controlled_block()
controlled_block.priority = priority
# todo - pyffi adds the names to the NiStringPalette, but it creates one per controller link...
Expand All @@ -159,15 +159,15 @@ def create_controller(self, parent_block, target_name, priority=0):
controlled_block.controller_type = "NiTransformController"
# get the parent's string palette
if not parent_block.string_palette:
parent_block.string_palette = NifFormat.NiStringPalette()
parent_block.string_palette = NifClasses.NiStringPalette(NifData.data)
# assign string palette to controller
controlled_block.string_palette = parent_block.string_palette
# add the strings and store their offsets
palette = controlled_block.string_palette.palette
controlled_block.node_name_offset = palette.add_string(controlled_block.node_name)
controlled_block.controller_type_offset = palette.add_string(controlled_block.controller_type)
# morrowind style
elif isinstance(parent_block, NifFormat.NiSequenceStreamHelper):
elif isinstance(parent_block, NifClasses.NiSequenceStreamHelper):
# create node reference by name
nodename_extra = block_store.create_block("NiStringExtraData")
nodename_extra.bytes_remaining = len(target_name) + 4
Expand All @@ -184,14 +184,14 @@ def create_controller(self, parent_block, target_name, priority=0):
@staticmethod
def get_n_interp_from_b_interp(b_ipol):
if b_ipol == "LINEAR":
return NifFormat.KeyType.LINEAR_KEY
return NifClasses.KeyType.LINEAR_KEY
elif b_ipol == "BEZIER":
return NifFormat.KeyType.QUADRATIC_KEY
return NifClasses.KeyType.QUADRATIC_KEY
elif b_ipol == "CONSTANT":
return NifFormat.KeyType.CONST_KEY
return NifClasses.KeyType.CONST_KEY

NifLog.warn(f"Unsupported interpolation mode ({b_ipol}) in blend, using quadratic/bezier.")
return NifFormat.KeyType.QUADRATIC_KEY
return NifClasses.KeyType.QUADRATIC_KEY

def add_dummy_markers(self, b_action):
# if we exported animations, but no animation groups are defined,
Expand Down
22 changes: 11 additions & 11 deletions io_scene_niftools/modules/nif_export/animation/material.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@
#
# ***** END LICENSE BLOCK *****

from pyffi.formats.nif import NifFormat
from generated.formats.nif import classes as NifClasses

from io_scene_niftools.modules.nif_export.animation import Animation
from io_scene_niftools.modules.nif_export.block_registry import block_store
from io_scene_niftools.utils.singleton import NifOp
from io_scene_niftools.utils.singleton import NifOp, NifData
from io_scene_niftools.utils.logging import NifLog


Expand Down Expand Up @@ -71,9 +71,9 @@ def export_material_controllers(self, b_material, n_mat_prop):
if not n_mat_prop:
raise ValueError("Bug!! must add material property before exporting alpha controller")
colors = (("alpha", None),
("niftools.ambient_color", NifFormat.TargetColor.TC_AMBIENT),
("diffuse_color", NifFormat.TargetColor.TC_DIFFUSE),
("specular_color", NifFormat.TargetColor.TC_SPECULAR))
("niftools.ambient_color", NifClasses.MaterialColor.TC_AMBIENT),
("diffuse_color", NifClasses.MaterialColor.TC_DIFFUSE),
("specular_color", NifClasses.MaterialColor.TC_SPECULAR))
# the actual export
for b_dtype, n_dtype in colors:
self.export_material_alpha_color_controller(b_material, n_mat_prop, b_dtype, n_dtype)
Expand All @@ -99,8 +99,8 @@ def export_material_alpha_color_controller(self, b_material, n_mat_prop, b_dtype
# create the key data
n_key_data = block_store.create_block(keydata, fcurves)
n_key_data.data.num_keys = len(fcurves[0].keyframe_points)
n_key_data.data.interpolation = NifFormat.KeyType.LINEAR_KEY
n_key_data.data.keys.update_size()
n_key_data.data.interpolation = NifClasses.KeyType.LINEAR_KEY
n_key_data.data.reset_field("keys")

# assumption: all curves have same amount of keys and are sampled at the same time
for i, n_key in enumerate(n_key_data.data.keys):
Expand Down Expand Up @@ -148,13 +148,13 @@ def export_uv_controller(self, b_material, n_geom):
return

# get the uv curves and translate them into nif data
n_uv_data = NifFormat.NiUVData()
n_uv_data = NifClasses.NiUVData(NifData.data)
for fcu, n_uv_group in zip(fcurves, n_uv_data.uv_groups):
if fcu:
NifLog.debug(f"Exporting {fcu} as NiUVData")
n_uv_group.num_keys = len(fcu.keyframe_points)
n_uv_group.interpolation = NifFormat.KeyType.LINEAR_KEY
n_uv_group.keys.update_size()
n_uv_group.interpolation = NifClasses.KeyType.LINEAR_KEY
n_uv_group.reset_field("keys")
for b_point, n_key in zip(fcu.keyframe_points, n_uv_group.keys):
# add each point of the curve
b_frame, b_value = b_point.co
Expand All @@ -167,7 +167,7 @@ def export_uv_controller(self, b_material, n_geom):

# if uv data is present then add the controller so it is exported
if fcurves[0].keyframe_points:
n_uv_ctrl = NifFormat.NiUVController()
n_uv_ctrl = NifClasses.NiUVController(NifData.data)
self.set_flags_and_timing(n_uv_ctrl, fcurves)
n_uv_ctrl.data = n_uv_data
# attach block to geometry
Expand Down
16 changes: 8 additions & 8 deletions io_scene_niftools/modules/nif_export/animation/morph.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#
# ***** END LICENSE BLOCK *****

from pyffi.formats.nif import NifFormat
from generated.formats.nif import classes as NifClasses
from pyffi.formats.egm import EgmFormat

from io_scene_niftools.modules.nif_export.animation import Animation
Expand Down Expand Up @@ -101,25 +101,25 @@ def export_morph_animation(self, b_mesh, b_key, n_trishape, vertmap):
morph_ctrl.data = morph_data
morph_data.num_morphs = len(b_key.key_blocks)
morph_data.num_vertices = n_trishape.data.num_vertices
morph_data.morphs.update_size()
morph_data.reset_field("morphs")

# create interpolators (for newer nif versions)
morph_ctrl.num_interpolators = len(b_key.key_blocks)
morph_ctrl.interpolators.update_size()
morph_ctrl.reset_field("interpolators")

# interpolator weights (for Fallout 3)
morph_ctrl.interpolator_weights.update_size()
morph_ctrl.reset_field("interpolator_weights")
# TODO [morph] some unknowns, bethesda only
# TODO [morph] just guessing here, data seems to be zero always
morph_ctrl.num_unknown_ints = len(b_key.key_blocks)
morph_ctrl.unknown_ints.update_size()
morph_ctrl.reset_field("unknown_ints")
for key_block_num, key_block in enumerate(b_key.key_blocks):
# export morphed vertices
n_morph = morph_data.morphs[key_block_num]
n_morph.frame_name = key_block.name
NifLog.info(f"Exporting n_morph {key_block.name}: vertices")
n_morph.arg = morph_data.num_vertices
n_morph.vectors.update_size()
n_morph.reset_field("vectors")
for b_v_index, (n_v_indices, b_vert) in enumerate(list(zip(vertmap, key_block.data))):
# see if this b_vert is used in the nif
if not n_v_indices:
Expand Down Expand Up @@ -161,9 +161,9 @@ def export_morph_animation(self, b_mesh, b_key, n_trishape, vertmap):
# note: we set data on n_morph for older nifs and on floatdata for newer nifs
# of course only one of these will be actually written to the file
for n_data in (n_morph, n_floatdata):
n_data.interpolation = NifFormat.KeyType.LINEAR_KEY
n_data.interpolation = NifClasses.KeyType.LINEAR_KEY
n_data.num_keys = len(fcurves[0].keyframe_points)
n_data.keys.update_size()
n_data.reset_field("keys")

for i, b_keyframe in enumerate(fcurves[0].keyframe_points):
frame, value = b_keyframe.co
Expand Down
8 changes: 4 additions & 4 deletions io_scene_niftools/modules/nif_export/animation/object.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
# ***** END LICENSE BLOCK *****

import bpy
from pyffi.formats.nif import NifFormat
from generated.formats.nif import classes as NifClasses

from io_scene_niftools.modules.nif_export.animation import Animation
from io_scene_niftools.modules.nif_export.block_registry import block_store
Expand Down Expand Up @@ -66,13 +66,13 @@ def export_visibility(self, n_node, b_action):
# NiVisData = old style, NiBoolData = new style
n_vis_data = block_store.create_block("NiVisData", fcurves)
n_vis_data.num_keys = len(fcurves[0].keyframe_points)
n_vis_data.keys.update_size()
n_vis_data.reset_field("keys")

# we just leave interpolation at constant
n_bool_data = block_store.create_block("NiBoolData", fcurves)
n_bool_data.data.interpolation = NifFormat.KeyType.CONST_KEY
n_bool_data.data.interpolation = NifClasses.KeyType.CONST_KEY
n_bool_data.data.num_keys = len(fcurves[0].keyframe_points)
n_bool_data.data.keys.update_size()
n_bool_data.data.reset_field("keys")
for b_point, n_vis_key, n_bool_key in zip(fcurves[0].keyframe_points, n_vis_data.keys, n_bool_data.data.keys):
# add each point of the curve
b_frame, b_value = b_point.co
Expand Down
Loading