mirror of
https://github.com/YorhaX2P/NieR2Blender2NieR-PS4.git
synced 2026-08-26 19:43:33 +00:00
basename is now stored in dat_info.json; fixed too many files being added to DatContents, if there were already files in the folder; small UI related things (column fix, files order); fixed WMB import with "only extract" option
This commit is contained in:
+3
-14
@@ -234,20 +234,9 @@ def migrateDatDirs():
|
||||
if dirType["key"] not in bpy.context.scene or len(dirType["newList"]) > 0:
|
||||
continue
|
||||
datDir = bpy.context.scene[dirType["key"]]
|
||||
datInfoJson = ""
|
||||
fileOrderMetadata = ""
|
||||
for file in os.listdir(datDir):
|
||||
if file == "dat_info.json":
|
||||
datInfoJson = os.path.join(datDir, file)
|
||||
break
|
||||
elif file == "file_order.metadata":
|
||||
fileOrderMetadata = os.path.join(datDir, file)
|
||||
if datInfoJson:
|
||||
readJsonDatInfo(datInfoJson, dirType["newList"])
|
||||
elif fileOrderMetadata:
|
||||
readFileOrderMetadata(fileOrderMetadata, dirType["newList"])
|
||||
else:
|
||||
print("No dat_info.json or file_order.metadata found in " + datDir)
|
||||
if os.path.isdir(datDir):
|
||||
if not importContentsFileFromFolder(datDir, dirType["newList"]):
|
||||
print("No dat_info.json or file_order.metadata found in " + datDir)
|
||||
|
||||
## Collision Extras
|
||||
def setColourByCollisionType(obj):
|
||||
|
||||
@@ -17,7 +17,7 @@ class ImportNierCol(bpy.types.Operator, ImportHelper):
|
||||
def execute(self, context):
|
||||
from . import col_importer
|
||||
|
||||
setExportFieldsFromImportFile(self.filepath)
|
||||
setExportFieldsFromImportFile(self.filepath, False)
|
||||
enableCollisionTools()
|
||||
|
||||
return col_importer.main(self.filepath)
|
||||
|
||||
@@ -8,7 +8,7 @@ from bpy_extras.io_utils import ExportHelper, ImportHelper
|
||||
from ...consts import DAT_EXTENSIONS
|
||||
from ...utils.ioUtils import read_uint32
|
||||
|
||||
from ...utils.util import readFileOrderMetadata, readJsonDatInfo, saveDatInfo, triangulate_meshes, centre_origins, ShowMessageBox
|
||||
from ...utils.util import importContentsFileFromFolder, readFileOrderMetadata, readJsonDatInfo, saveDatInfo, triangulate_meshes, centre_origins, ShowMessageBox
|
||||
|
||||
|
||||
class ExportAllSteps(bpy.types.PropertyGroup):
|
||||
@@ -110,7 +110,8 @@ class DAT_DTT_PT_Export(bpy.types.Panel):
|
||||
if datType["showVar"]:
|
||||
box = box.box()
|
||||
if len(datType["contentsVar"]) > 0:
|
||||
columns = int(context.region.width / bpy.context.preferences.system.ui_scale // 150)
|
||||
columns = int(context.region.width / bpy.context.preferences.system.ui_scale // 170)
|
||||
columns = max(columns, 1)
|
||||
column = 0
|
||||
for file in datType["contentsVar"]:
|
||||
if column % columns == 0:
|
||||
@@ -259,8 +260,10 @@ class ExportAll(bpy.types.Operator):
|
||||
elif item.filepath.endswith('.wtp'):
|
||||
wtpFilePath = item.filepath
|
||||
|
||||
datFilePath = os.path.join(datDttExportDir, baseFilename + "." + datExt)
|
||||
dttFilePath = os.path.join(datDttExportDir, baseFilename + ".dtt")
|
||||
datFileName = baseFilename + "." + datExt
|
||||
dttFileName = baseFilename + ".dtt"
|
||||
datFilePath = os.path.join(datDttExportDir, datFileName)
|
||||
dttFilePath = os.path.join(datDttExportDir, dttFileName)
|
||||
|
||||
from ...wmb.exporter import wmb_exporter
|
||||
if exportSteps.useWmbStep:
|
||||
@@ -321,7 +324,7 @@ class ExportAll(bpy.types.Operator):
|
||||
# save info file
|
||||
datInfoFilePath = os.path.join(os.path.dirname(file_list[0]), "dat_info.json")
|
||||
fileNames = [os.path.basename(file_path) for file_path in file_list]
|
||||
saveDatInfo(datInfoFilePath, fileNames, context.scene.DatExtension)
|
||||
saveDatInfo(datInfoFilePath, fileNames, datFileName)
|
||||
# export dtt
|
||||
export_dat.main(datFilePath, file_list)
|
||||
exportedFilesCount += 1
|
||||
@@ -337,7 +340,7 @@ class ExportAll(bpy.types.Operator):
|
||||
# save info file
|
||||
datInfoFilePath = os.path.join(os.path.dirname(file_list[0]), "dat_info.json")
|
||||
fileNames = [os.path.basename(file_path) for file_path in file_list]
|
||||
saveDatInfo(datInfoFilePath, fileNames, "dtt")
|
||||
saveDatInfo(datInfoFilePath, fileNames, dttFileName)
|
||||
# export dtt
|
||||
export_dat.main(dttFilePath, file_list)
|
||||
exportedFilesCount += 1
|
||||
@@ -509,22 +512,9 @@ class ImportDatDttContentsFile(bpy.types.Operator, ImportHelper):
|
||||
# Parse the appropriate file and add files to contents
|
||||
root, ext = os.path.splitext(filepath)
|
||||
if isDir:
|
||||
# search for metadata or json file
|
||||
datInfoJson = ""
|
||||
fileOrderMetadata = ""
|
||||
for file in os.listdir(filepath):
|
||||
if file == "dat_info.json":
|
||||
datInfoJson = os.path.join(filepath, file)
|
||||
break
|
||||
elif file == "file_order.metadata":
|
||||
fileOrderMetadata = os.path.join(filepath, file)
|
||||
if datInfoJson:
|
||||
readJsonDatInfo(datInfoJson, contentsList)
|
||||
elif fileOrderMetadata:
|
||||
readFileOrderMetadata(fileOrderMetadata, contentsList)
|
||||
else:
|
||||
if not importContentsFileFromFolder(filepath, contentsList):
|
||||
self.report({"ERROR"}, "No 'file_order.metadata' or 'dat_info.json' file found in directory!")
|
||||
return {"FINISHED"}
|
||||
return {"CANCELLED"}
|
||||
elif ext == ".json":
|
||||
readJsonDatInfo(filepath, contentsList)
|
||||
elif ext == ".metadata":
|
||||
|
||||
@@ -27,16 +27,16 @@ def importDtt(only_extract, filepath):
|
||||
if not os.path.exists(wmb_filepath):
|
||||
wmb_filepath = os.path.join(extract_dir, tailless_tail + '.dat', last_filename[:-4] + '.wmb') # if not in dtt, then must be in dat
|
||||
|
||||
# WMB
|
||||
from ...wmb.importer import wmb_importer
|
||||
wmb_importer.main(only_extract, wmb_filepath)
|
||||
|
||||
if only_extract:
|
||||
return {'FINISHED'}
|
||||
|
||||
setExportFieldsFromImportFile(filepath)
|
||||
setExportFieldsFromImportFile(filepath, True)
|
||||
enableVisibilitySelector()
|
||||
|
||||
# WMB
|
||||
from ...wmb.importer import wmb_importer
|
||||
wmb_importer.main(only_extract, wmb_filepath)
|
||||
|
||||
# COL
|
||||
col_filepath = os.path.join(extract_dir, tailless_tail + '.dat', tailless_tail + '.col')
|
||||
if os.path.isfile(col_filepath):
|
||||
@@ -108,7 +108,7 @@ class ImportNierDat(bpy.types.Operator, ImportHelper):
|
||||
if onlyExtract:
|
||||
return {'FINISHED'}
|
||||
|
||||
setExportFieldsFromImportFile(filepath)
|
||||
setExportFieldsFromImportFile(filepath, True)
|
||||
|
||||
# COL
|
||||
col_filepath = os.path.join(extract_dir, tailless_tail + '.dat', tailless_tail + '.col')
|
||||
|
||||
@@ -84,7 +84,7 @@ def extract_file(fp, filename, FileOffset, Size, extract_dir):
|
||||
def get_all_files(path):
|
||||
pass
|
||||
|
||||
def extract_hashes(fp, extract_dir, FileCount, hashMapOffset, fileNamesOffset, extension):
|
||||
def extract_hashes(fp, extract_dir, FileCount, hashMapOffset, fileNamesOffset, filename):
|
||||
create_dir(extract_dir)
|
||||
|
||||
# file_order.metadata
|
||||
@@ -101,7 +101,7 @@ def extract_hashes(fp, extract_dir, FileCount, hashMapOffset, fileNamesOffset, e
|
||||
saveDatInfo(
|
||||
extract_dir + '/dat_info.json',
|
||||
[file.decode('utf-8').rstrip('\x00') for file in fileNames],
|
||||
extension
|
||||
filename
|
||||
)
|
||||
|
||||
# hash_data.metadata
|
||||
@@ -145,7 +145,7 @@ def main(filename, extract_dir, ROOT_DIR):
|
||||
extract_file(fp, Filename, FileOffset, Size, extract_dir_sub)
|
||||
extractedFiles += 1
|
||||
|
||||
extract_hashes(fp, extract_dir, FileCount, hashMapOffset, NameTableOffset, os.path.splitext(filename)[1][1:])
|
||||
extract_hashes(fp, extract_dir, FileCount, hashMapOffset, NameTableOffset, os.path.basename(filename))
|
||||
print(f"[+] {extractedFiles} files extracted from {filename}")
|
||||
if (FileCount):
|
||||
return Filename
|
||||
|
||||
@@ -16,6 +16,6 @@ class ImportNierLay(bpy.types.Operator, ImportHelper):
|
||||
def execute(self, context):
|
||||
from . import lay_importer
|
||||
|
||||
setExportFieldsFromImportFile(self.filepath)
|
||||
setExportFieldsFromImportFile(self.filepath, False)
|
||||
|
||||
return lay_importer.main(self.filepath)
|
||||
|
||||
+76
-37
@@ -176,39 +176,30 @@ def centre_origins(collection: str):
|
||||
bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
|
||||
obj.select_set(False)
|
||||
|
||||
def setExportFieldsFromImportFile(filepath: str) -> None:
|
||||
head = os.path.split(filepath)[0]
|
||||
tail = os.path.split(filepath)[1]
|
||||
datExt = ".dat" if tail.endswith("dtt") else os.path.splitext(tail)[1]
|
||||
tailless_tail = tail[:-4]
|
||||
extract_dir = os.path.join(head, 'nier2blender_extracted')
|
||||
|
||||
datDir = os.path.join(extract_dir, tailless_tail + datExt)
|
||||
if os.path.isdir(datDir) and datExt in DAT_EXTENSIONS:
|
||||
bpy.context.scene.DatExtension = datExt[1:]
|
||||
bpy.context.scene.DatContents.clear()
|
||||
for filename in os.listdir(datDir):
|
||||
full_path = os.path.join(datDir, filename)
|
||||
if os.path.isfile(full_path):
|
||||
name, ext = os.path.splitext(full_path)
|
||||
if len(ext) > 4:
|
||||
continue
|
||||
added_file = bpy.context.scene.DatContents.add()
|
||||
added_file.filepath = full_path
|
||||
|
||||
dttDir = os.path.join(extract_dir, tailless_tail + '.dtt')
|
||||
if os.path.isdir(dttDir):
|
||||
bpy.context.scene.DttContents.clear()
|
||||
for filename in os.listdir(dttDir):
|
||||
full_path = os.path.join(dttDir, filename)
|
||||
if os.path.isfile(full_path):
|
||||
name, ext = os.path.splitext(full_path)
|
||||
if len(ext) > 4:
|
||||
continue
|
||||
added_file = bpy.context.scene.DttContents.add()
|
||||
added_file.filepath = full_path
|
||||
|
||||
bpy.context.scene.ExportFileName = tailless_tail
|
||||
def setExportFieldsFromImportFile(filepath: str, isDatImport: bool) -> None:
|
||||
dir = os.path.dirname(filepath)
|
||||
if isDatImport:
|
||||
filename = os.path.basename(filepath)
|
||||
basename, ext = os.path.splitext(filename)
|
||||
datExt = ext if ext in DAT_EXTENSIONS else ".dat"
|
||||
datExtractedDir = os.path.join(dir, "nier2blender_extracted", basename + datExt)
|
||||
dttExtraDir = os.path.join(dir, "nier2blender_extracted", basename + ".dtt")
|
||||
else:
|
||||
filename = os.path.basename(dir)
|
||||
basename, ext = os.path.splitext(filename)
|
||||
datExt = ext if ext in DAT_EXTENSIONS else ".dat"
|
||||
parentDir = os.path.dirname(dir)
|
||||
if ext == ".dtt" or ext in DAT_EXTENSIONS:
|
||||
datExtractedDir = os.path.join(parentDir, basename + ".dat")
|
||||
dttExtraDir = os.path.join(parentDir, basename + ".dtt")
|
||||
else:
|
||||
print("Unknown DAT folder type")
|
||||
return
|
||||
|
||||
if os.path.exists(datExtractedDir):
|
||||
importContentsFileFromFolder(datExtractedDir, bpy.context.scene.DatContents)
|
||||
if os.path.exists(dttExtraDir):
|
||||
importContentsFileFromFolder(dttExtraDir, bpy.context.scene.DttContents)
|
||||
|
||||
def getPreferences():
|
||||
return bpy.context.preferences.addons[ADDON_NAME].preferences
|
||||
@@ -271,18 +262,53 @@ def setViewportColorTypeToObject():
|
||||
space.shading.type = "SOLID"
|
||||
space.shading.color_type = "OBJECT"
|
||||
|
||||
def importContentsFileFromFolder(folderPath: str, contentsList: bpy.types.CollectionProperty) -> bool:
|
||||
# search for metadata or json file
|
||||
datInfoJson = ""
|
||||
fileOrderMetadata = ""
|
||||
for file in os.listdir(folderPath):
|
||||
if file == "dat_info.json":
|
||||
datInfoJson = os.path.join(folderPath, file)
|
||||
break
|
||||
elif file == "file_order.metadata":
|
||||
fileOrderMetadata = os.path.join(folderPath, file)
|
||||
if datInfoJson:
|
||||
readJsonDatInfo(datInfoJson, contentsList)
|
||||
elif fileOrderMetadata:
|
||||
readFileOrderMetadata(fileOrderMetadata, contentsList)
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
||||
def getFileSortingKey(file: str):
|
||||
base, ext = os.path.splitext(file)
|
||||
return (base.lower(), ext.lower())
|
||||
|
||||
def readJsonDatInfo(filepath: str, contentsList: bpy.types.CollectionProperty):
|
||||
with open(filepath, "r") as f:
|
||||
filesData = json.load(f)
|
||||
files = []
|
||||
dir = os.path.dirname(filepath)
|
||||
for file in filesData["files"]:
|
||||
files.append(os.path.join(dir, file))
|
||||
# remove duplicates and sort
|
||||
files = list(set(files))
|
||||
files.sort(key=getFileSortingKey)
|
||||
|
||||
for file in files:
|
||||
added_file = contentsList.add()
|
||||
added_file.filepath = os.path.join(os.path.dirname(filepath), file)
|
||||
added_file.filepath = file
|
||||
|
||||
# some old dev versions don't have these properties, for backwards compatibility
|
||||
if "basename" in filesData:
|
||||
bpy.context.scene.ExportFileName = filesData["basename"]
|
||||
else:
|
||||
bpy.context.scene.ExportFileName = os.path.splitext(os.path.basename(dir))[0]
|
||||
if "ext" in filesData:
|
||||
if filesData["ext"] != "dtt":
|
||||
bpy.context.scene.DatExtension = filesData["ext"].lower()
|
||||
elif not os.path.dirname(filepath).endswith(".dtt"):
|
||||
bpy.context.scene.DatExtension = "dat"
|
||||
|
||||
|
||||
def readFileOrderMetadata(filepath: str, contentsList: bpy.types.CollectionProperty):
|
||||
if filepath.endswith("hash_order.metadata"):
|
||||
@@ -294,15 +320,28 @@ def readFileOrderMetadata(filepath: str, contentsList: bpy.types.CollectionPrope
|
||||
files = []
|
||||
for i in range(num_files):
|
||||
files.append(f.read(name_length).decode("utf-8").strip("\x00"))
|
||||
# remove duplicates and sort
|
||||
files = list(set(files))
|
||||
files.sort(key=getFileSortingKey)
|
||||
|
||||
for file in files:
|
||||
added_file = contentsList.add()
|
||||
added_file.filepath = os.path.join(os.path.dirname(filepath), file)
|
||||
|
||||
ext = os.path.splitext(filepath)[1]
|
||||
if ext == ".dtt" or ext in DAT_EXTENSIONS:
|
||||
bpy.context.scene.DatExtension = ext[1:]
|
||||
bpy.context.scene.ExportFileName = os.path.basename(filepath)[:-4]
|
||||
|
||||
def saveDatInfo(filepath: str, files: List[str], ext: str):
|
||||
def saveDatInfo(filepath: str, files: List[str], filename: str):
|
||||
files = list(set(files))
|
||||
files.sort(key=getFileSortingKey)
|
||||
base, ext = os.path.splitext(filename)
|
||||
with open(filepath, 'w') as f:
|
||||
jsonFiles = {
|
||||
"version": 1,
|
||||
"files": files,
|
||||
"ext": ext.lower()
|
||||
"basename": base,
|
||||
"ext": ext[1:]
|
||||
}
|
||||
json.dump(jsonFiles, f, indent=4)
|
||||
|
||||
@@ -21,7 +21,7 @@ class ImportNierWmb(bpy.types.Operator, ImportHelper):
|
||||
if self.reset_blend:
|
||||
wmb_importer.reset_blend()
|
||||
|
||||
setExportFieldsFromImportFile(self.filepath)
|
||||
setExportFieldsFromImportFile(self.filepath, False)
|
||||
enableVisibilitySelector()
|
||||
|
||||
return wmb_importer.main(False, self.filepath)
|
||||
|
||||
@@ -91,7 +91,7 @@ def importEntities(action: ET.Element, color: List[float], prefix: str) -> None:
|
||||
|
||||
for i, entity in enumerate(action.find("layouts").find("normal").find("layouts").findall("value")):
|
||||
entityId = entity.find("id").text
|
||||
loc = xmlVecToVec3(entity.find("location").find("position").text)
|
||||
loc = xmlVecToVec3(entity.find("location").find("position").text) if entity.find("location").find("position") is not None else (0, 0, 0)
|
||||
rot = xmlVecToVec3(entity.find("location").find("rotation").text) if entity.find("location").find("rotation") is not None else (0, 0, 0)
|
||||
scale = xmlVecToVec3(entity.find("scale").text) if entity.find("scale") is not None else (1, 1, 1)
|
||||
entityObjId = entity.find("objId").text if entity.find("objId") is not None else entity.find("objID").text
|
||||
|
||||
Reference in New Issue
Block a user