mirror of
https://github.com/n64decomp/mk64
synced 2026-09-07 10:41:44 -04:00
start making models extraction with blender
This commit is contained in:
@@ -87,3 +87,5 @@ expected/*
|
||||
|
||||
# Doxygen
|
||||
docs/html/*
|
||||
objects
|
||||
tools/mingw64
|
||||
|
||||
@@ -10,3 +10,6 @@
|
||||
[submodule "doxygen-awesome-css"]
|
||||
path = doxygen-awesome-css
|
||||
url = https://github.com/jothepro/doxygen-awesome-css.git
|
||||
[submodule "tools/fast64"]
|
||||
path = tools/fast64
|
||||
url = https://github.com/Fast-64/fast64.git
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
"c:\Program Files\Blender Foundation\Blender 4.0\blender.exe" --python tools/blender_extension/fast64_run.py
|
||||
@@ -0,0 +1 @@
|
||||
"c:\Program Files\Blender Foundation\Blender 4.0\blender.exe" -b --python tools/blender_extension/blender_export.py -- courses/dks_jungle_parkway/course_data.inc.c d_course_dks_jungle_parkway_dl_E058
|
||||
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"courses/dks_jungle_parkway/course_data.inc.c": [
|
||||
"d_course_dks_jungle_parkway_dl_E730",
|
||||
"d_course_dks_jungle_parkway_dl_E058",
|
||||
"d_course_dks_jungle_parkway_dl_FC28",
|
||||
"d_course_dks_jungle_parkway_dl_kiwano_fruit",
|
||||
"d_course_dks_jungle_parkway_dl_palm_tree",
|
||||
"d_course_dks_jungle_parkway_dl_13878",
|
||||
"d_course_dks_jungle_parkway_dl_tree3",
|
||||
"d_course_dks_jungle_parkway_dl_tree2",
|
||||
"d_course_dks_jungle_parkway_dl_tree1"
|
||||
],
|
||||
"courses/banshee_boardwalk/course_data.inc.c": [
|
||||
"d_course_banshee_boardwalk_dl_B278",
|
||||
"d_course_banshee_boardwalk_dl_trash_bin",
|
||||
"d_course_banshee_boardwalk_dl_cheep_cheep"
|
||||
],
|
||||
"courses/bowsers_castle/course_data.inc.c": [
|
||||
"d_course_bowsers_castle_dl_thwomp",
|
||||
"d_course_bowsers_castle_dl_bush"
|
||||
],
|
||||
"courses/choco_mountain/course_data.inc.c":[
|
||||
"d_course_choco_mountain_dl_falling_rock"
|
||||
],
|
||||
"courses/frappe_snowland/course_data.inc.c":[
|
||||
"d_course_frappe_snowland_dl_tree"
|
||||
],
|
||||
"courses/kalimari_desert/course_data.inc.c":[
|
||||
"d_course_kalimari_desert_dl_cactus1",
|
||||
"d_course_kalimari_desert_dl_cactus2",
|
||||
"d_course_kalimari_desert_dl_cactus3",
|
||||
"d_course_kalimari_desert_dl_crossing_right_active",
|
||||
"d_course_kalimari_desert_dl_crossing_left_active",
|
||||
"d_course_kalimari_desert_dl_crossing_both_inactive",
|
||||
"d_course_kalimari_desert_dl_1B978",
|
||||
"d_course_kalimari_desert_dl_1C0F0",
|
||||
"d_course_kalimari_desert_dl_1D160",
|
||||
"d_course_kalimari_desert_dl_1D670",
|
||||
"d_course_kalimari_desert_dl_1E480",
|
||||
"d_course_kalimari_desert_dl_1E910",
|
||||
"d_course_kalimari_desert_dl_1F228",
|
||||
"d_course_kalimari_desert_dl_1F708",
|
||||
"d_course_kalimari_desert_dl_1FAF8",
|
||||
"d_course_kalimari_desert_dl_20A20",
|
||||
"d_course_kalimari_desert_dl_21220",
|
||||
"d_course_kalimari_desert_dl_21550",
|
||||
"d_course_kalimari_desert_dl_21A80",
|
||||
"d_course_kalimari_desert_dl_21C90",
|
||||
"d_course_kalimari_desert_dl_22D28",
|
||||
"d_course_kalimari_desert_dl_22D70",
|
||||
"d_course_kalimari_desert_dl_22DB8"
|
||||
],
|
||||
"courses/koopa_troopa_beach/course_data.inc.c":[
|
||||
"d_course_koopa_troopa_beach_dl_16630",
|
||||
"d_course_koopa_troopa_beach_dl_tree_top1",
|
||||
"d_course_koopa_troopa_beach_dl_tree_trunk1",
|
||||
"d_course_koopa_troopa_beach_dl_tree_top2",
|
||||
"d_course_koopa_troopa_beach_dl_tree_trunk2",
|
||||
"d_course_koopa_troopa_beach_dl_tree_top3",
|
||||
"d_course_koopa_troopa_beach_dl_tree_trunk3"
|
||||
],
|
||||
"courses/luigi_raceway/course_data.inc.c": [
|
||||
"d_course_luigi_raceway_dl_F650",
|
||||
"d_course_luigi_raceway_dl_F960",
|
||||
"d_course_luigi_raceway_dl_FA20",
|
||||
"d_course_luigi_raceway_dl_FBE0",
|
||||
"d_course_luigi_raceway_dl_FC70"
|
||||
]
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
import os
|
||||
import re
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='Actualise type in C code')
|
||||
parser.add_argument('-k', '--know_the_unknow', action='store_true', help='replace ? by type if is found somewhere')
|
||||
parser.add_argument('-cv', "--change_var_name", action='store_true', help='change var name')
|
||||
parser.add_argument("-cf", "--change_type_var", action='store_true', help="change type of var")
|
||||
|
||||
arg = parser.parse_args()
|
||||
|
||||
root = "."
|
||||
|
||||
var:dict[str,str] = {}
|
||||
number_type_var = {}
|
||||
ban_type = [
|
||||
"extern",
|
||||
"struct",
|
||||
"static",
|
||||
"UNUSED",
|
||||
"?",
|
||||
"include",
|
||||
"const",
|
||||
"case",
|
||||
"ALIGNED8",
|
||||
"typedef"
|
||||
]
|
||||
static = {}
|
||||
|
||||
def check_file_and_folder(path:str, name:str) -> bool:
|
||||
if not (name.endswith(".c") or name.endswith(".h")):
|
||||
return True
|
||||
|
||||
if "tools" in path:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def replace_type(var_name: str, var_type: str, chn: str) -> str:
|
||||
if var_name in chn:
|
||||
result = re.sub(rf"(?! )\w+ {var_name}", f"{var_type} {var_name}", chn)
|
||||
result = re.sub(rf"(?! )\? {var_name}", f"{var_type} {var_name}", chn)
|
||||
else:
|
||||
result = chn
|
||||
return result
|
||||
|
||||
def find_type(prefix = ""):
|
||||
for path, subdirs, files in os.walk(root):
|
||||
for name in files:
|
||||
if check_file_and_folder(path, name):
|
||||
continue
|
||||
|
||||
print(os.path.join(path, name))
|
||||
|
||||
with open(os.path.join(path, name)) as f:
|
||||
data = f.read()
|
||||
|
||||
if prefix=="":
|
||||
result = re.findall(r'\n(\w+) (\w+)', data)
|
||||
else:
|
||||
result = re.findall(r'\n'+prefix+r' (\w+) (\w+)', data)
|
||||
|
||||
for i in result:
|
||||
|
||||
if i[1] == "//" or (i[0] in ban_type) or len(i[1])<1:
|
||||
continue
|
||||
|
||||
var[i[1]] = i[0]
|
||||
|
||||
if i[0] in number_type_var:
|
||||
number_type_var[i[0]] += 1
|
||||
else:
|
||||
number_type_var[i[0]] = 1
|
||||
|
||||
def know_the_unknow():
|
||||
find_type()
|
||||
|
||||
find_type("static")
|
||||
|
||||
find_type("const")
|
||||
|
||||
find_type("struct")
|
||||
|
||||
find_type("extern")
|
||||
|
||||
print(var)
|
||||
|
||||
for path, subdirs, files in os.walk(root):
|
||||
for name in files:
|
||||
if check_file_and_folder(path, name):
|
||||
continue
|
||||
|
||||
print(os.path.join(path, name))
|
||||
with open(os.path.join(path, name), "r+") as f:
|
||||
data = f.read()
|
||||
for i in var:
|
||||
data = replace_type(i, var[i], data)
|
||||
|
||||
f.seek(0)
|
||||
f.write(data)
|
||||
|
||||
def change_var_name():
|
||||
|
||||
old_name = input("Old name: ")
|
||||
new_name = input("New name: ")
|
||||
|
||||
for path, subdirs, files in os.walk(root):
|
||||
for name in files:
|
||||
if check_file_and_folder(path, name):
|
||||
continue
|
||||
|
||||
print(os.path.join(path, name))
|
||||
with open(os.path.join(path, name), "r+") as f:
|
||||
data = f.read()
|
||||
data = data.replace(old_name, new_name)
|
||||
|
||||
f.seek(0)
|
||||
f.write(data)
|
||||
|
||||
def change_type_var():
|
||||
name_var = input("Name var: ")
|
||||
new_type = input("New type: ")
|
||||
|
||||
for path, subdirs, files in os.walk(root):
|
||||
for name in files:
|
||||
if check_file_and_folder(path, name):
|
||||
continue
|
||||
|
||||
print(os.path.join(path, name))
|
||||
with open(os.path.join(path, name), "r+") as f:
|
||||
data = f.read()
|
||||
data = replace_type(name_var, new_type, data)
|
||||
|
||||
f.seek(0)
|
||||
f.write(data)
|
||||
|
||||
def main():
|
||||
if arg.know_the_unknow:
|
||||
print("actualise type")
|
||||
know_the_unknow()
|
||||
elif arg.change_var_name:
|
||||
change_var_name()
|
||||
elif arg.change_type_var:
|
||||
change_type_var()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,51 @@
|
||||
import bpy
|
||||
import os
|
||||
import sys
|
||||
sys.path.append('tools')
|
||||
import fast64
|
||||
from fast64.fast64_internal.f3d.f3d_gbi import get_F3D_GBI
|
||||
from fast64.fast64_internal.f3d.f3d_material import createF3DMat
|
||||
from fast64.fast64_internal.f3d.f3d_parser import F3DContext, getImportData, importMeshC
|
||||
|
||||
from blender_extension.clean_scene import clean_scene
|
||||
|
||||
dir_path = os.path.dirname(os.path.realpath(__file__))
|
||||
dir_path = dir_path.replace("\\", "/")
|
||||
dir_path = os.path.dirname(dir_path)
|
||||
dir_path = os.path.dirname(dir_path)
|
||||
|
||||
print(dir_path)
|
||||
|
||||
fast64.register()
|
||||
|
||||
argv = sys.argv
|
||||
argv = argv[argv.index("--") + 1:] # get all args after "--"
|
||||
|
||||
bpy.context.scene.f3d_type = "F3DEX/LX"
|
||||
basePath = bpy.path.abspath(dir_path)
|
||||
scaleValue = bpy.context.scene.blenderF3DScale
|
||||
removeDoubles = bpy.context.scene.DLRemoveDoubles
|
||||
importNormals = bpy.context.scene.DLImportNormals
|
||||
drawLayer = bpy.context.scene.DLImportDrawLayer
|
||||
|
||||
file = argv[0]
|
||||
obj = argv[1]
|
||||
|
||||
clean_scene()
|
||||
if bpy.context.mode != "OBJECT":
|
||||
bpy.ops.object.mode_set(mode="OBJECT")
|
||||
|
||||
importPath = bpy.path.abspath(dir_path+"/"+file)
|
||||
|
||||
data = getImportData([importPath])
|
||||
|
||||
importMeshC(
|
||||
data,
|
||||
obj,
|
||||
scaleValue,
|
||||
removeDoubles,
|
||||
importNormals,
|
||||
drawLayer,
|
||||
F3DContext(get_F3D_GBI(), basePath, createF3DMat(None)),
|
||||
)
|
||||
bpy.ops.wm.save_as_mainfile(filepath="objects/"+obj+".blend")
|
||||
@@ -0,0 +1,43 @@
|
||||
import bpy
|
||||
|
||||
def purge_orphans():
|
||||
if bpy.app.version >= (3, 0, 0):
|
||||
bpy.ops.outliner.orphans_purge(
|
||||
do_local_ids=True, do_linked_ids=True, do_recursive=True
|
||||
)
|
||||
else:
|
||||
# call purge_orphans() recursively until there are no more orphan data blocks to purge
|
||||
result = bpy.ops.outliner.orphans_purge()
|
||||
if result.pop() != "CANCELLED":
|
||||
purge_orphans()
|
||||
|
||||
|
||||
def clean_scene():
|
||||
"""
|
||||
Removing all of the objects, collection, materials, particles,
|
||||
textures, images, curves, meshes, actions, nodes, and worlds from the scene
|
||||
"""
|
||||
if bpy.context.active_object and bpy.context.active_object.mode == "EDIT":
|
||||
bpy.ops.object.editmode_toggle()
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
obj.hide_set(False)
|
||||
obj.hide_select = False
|
||||
obj.hide_viewport = False
|
||||
|
||||
bpy.ops.object.select_all(action="SELECT")
|
||||
bpy.ops.object.delete()
|
||||
|
||||
collection_names = [col.name for col in bpy.data.collections]
|
||||
for name in collection_names:
|
||||
bpy.data.collections.remove(bpy.data.collections[name])
|
||||
|
||||
# in the case when you modify the world shader
|
||||
world_names = [world.name for world in bpy.data.worlds]
|
||||
for name in world_names:
|
||||
bpy.data.worlds.remove(bpy.data.worlds[name])
|
||||
# create a new world data block
|
||||
bpy.ops.world.new()
|
||||
bpy.context.scene.world = bpy.data.worlds["World"]
|
||||
|
||||
purge_orphans()
|
||||
@@ -0,0 +1,4 @@
|
||||
import sys
|
||||
sys.path.append('tools')
|
||||
import fast64
|
||||
fast64.register()
|
||||
@@ -0,0 +1,30 @@
|
||||
import json
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
if not os.path.exists("objects"):
|
||||
os.makedirs("objects")
|
||||
|
||||
models = json.load(open("tools/3d_models.json"))
|
||||
|
||||
blender = "c:/Program Files/Blender Foundation/Blender 4.0/blender.exe"
|
||||
|
||||
args = [
|
||||
"--background",
|
||||
"--python",
|
||||
"tools/blender_extension/blender_export.py",
|
||||
"--",
|
||||
]
|
||||
|
||||
for file in models:
|
||||
for obj in models[file]:
|
||||
if os.path.exists("objects/"+obj+".blend"):
|
||||
continue
|
||||
print(f"Exporting {obj} from {file}")
|
||||
args.append(file)
|
||||
args.append(obj)
|
||||
if subprocess.run([blender, *args]).returncode != 0 or not os.path.exists("objects/"+obj+".blend"):
|
||||
print(f"Failed to export {obj} from {file}")
|
||||
exit(1)
|
||||
args.pop()
|
||||
args.pop()
|
||||
Submodule
+1
Submodule tools/fast64 added at 3d6f730974
Reference in New Issue
Block a user