Files
virtual_interdimensional_sp…/scripts/generate_json.py
Victor Giers 0961bbccbf auto-git:
[add] scripts/.DS_Store
 [add] scripts/README.md
 [add] scripts/extract_texture_filename_from_3ds.py
 [add] scripts/generate_3d_glb.py
 [add] scripts/generate_json.py
 [add] scripts/image_from_json.py
 [add] scripts/naming.py
 [add] scripts/openai_image_gen.py
 [add] scripts/remesh_bake_batch.py
 [add] server/public/assets/images/.DS_Store
 [add] server/public/assets/models/spirits/.DS_Store
 [change] server/public/assets/.DS_Store
 [change] server/public/assets/models/.DS_Store
2025-12-04 08:39:04 +01:00

100 lines
4.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
import re
from difflib import get_close_matches
MODEL_FILES = [
"Ebisu.glb","Enenra.glb","Enenra2.glb","Oboroguruma.glb","Oiwa.glb","Okiku.glb","Okomeki.001.glb",
"Okuninushi.glb","Oni.glb","Onryo.glb","Oyamatsumi.001.glb","Raijin.glb","Rokurokubi.glb","Ryujin.glb",
"Sarutahiko_Okami.glb","Shinigami.001.glb","Shuten_Doji.glb","Sojobo.glb","Sojobo2.glb","Susanoo.glb",
"Takeminakata.glb","Takeminakata2.001.glb","Tanuki.glb","Tengu.glb","Tenjin.glb","Tsukumogami.glb",
"Tsukuyomi_No_Mikoto.glb","Tsurube_Otoshi.glb","Tsurube_Otoshi2.glb","Tsurube_Otoshi3.glb","Tsurube_Otoshi4.glb",
"Ubume.glb","Yama_Uba.glb","Yama_Uba2.glb","Yamata_No_Orichi.glb","Yamawaro.glb","Yatagarasu2.glb",
"Yuki_Onna.glb","Yurei.glb","Abe_No_Seimei.glb","Abura_Akago.glb","Abura_Sumashi.glb","Abura_Sumashi2.glb",
"Aka_Manto.glb","Akaname.glb","Akateko2.glb","Akkorokamui.glb","Akuchu.glb","Amabie2.glb","Amanojaku.glb",
"Amaterasu.glb","Ame_No_Uzume.001.glb","Amenominakanushi.glb","Aoandon.001.glb","Aoandon2.001.glb",
"Ashiari_Yashiki.glb","Ashinaga_Tenaga2.glb","Azukiarai.glb","Azukibabaa.glb","Azukihakari.glb",
"Bake_Kujira.glb","Bake_Kujira2.glb","Bake_Kujira3.glb","Bakezori.glb","Baku.glb","Basan.glb",
"Benzaiten.glb","Betobeto_San.glb","Bishamonten.glb","Biwa_Bokuboku.glb","Chochin_Obake.glb","Daidarabotchi.glb",
"Daikokuten+Text.glb","Daikokuten.glb","Fujin.glb","Funayurei.glb","Furaribi.glb","Futakuchi_Onna.glb",
"Gaki.glb","Gashadokuro.glb","Hachiman.glb","Hiderigami.001.glb","Hitotsume_Kozo.glb","Hoko.glb",
"Inari_Okami.glb","Ittan_Momen2.glb","Izanagi_No_Mikoto.glb","Izanami_No_Mikoto.glb","Jikininki.glb",
"Jorogumo3.glb","Kamaitachi.glb","Kamikiri.glb","Kappa.glb","Karakasa_Obake.glb","Karakasa_Obake2.glb",
"Kitsune.glb","Kodama.glb","Kudan.glb","Mizushi.glb","Mokumokuren.glb","Mujina.glb","Nekomata.glb",
"Noppera_Bo.glb","Nue.glb","Nuppeppo2.glb","Nurarihyon.glb","Nure_Onna.glb","Nurikabe.glb","Nurikabe2.glb"
]
def normalize(s):
s = s.lower()
s = re.sub(r"[^a-z0-9]", "", s)
s = s.replace("ou", "o") # für "YamatanoOrOchi" vs "Yamata_No_Orichi"
return s
def generate_candidates(spirit_name):
base = spirit_name.split()[0]
latin = re.split(r"\s|\(|", spirit_name)[0]
candidates = [latin]
candidates += [latin.replace("-", "_"), latin.replace("-", ""), latin.replace("_", ""), latin.title(), latin.upper()]
if not latin.endswith("NoMikoto"):
candidates.append(latin + "NoMikoto")
candidates.append(latin + "_No_Mikoto")
return list(set([normalize(c) for c in candidates]))
def find_best_model(spirit_name):
candidates = generate_candidates(spirit_name)
model_names = [f[:-4] for f in MODEL_FILES]
normalized_models = [normalize(n) for n in model_names]
results = []
for c in candidates:
for i, n in enumerate(normalized_models):
dist = levenshtein(c, n)
if dist <= 2 or c in n or n in c:
results.append(MODEL_FILES[i])
results = sorted(list(set(results)))
if not results:
matches = get_close_matches(candidates[0], normalized_models, n=3, cutoff=0.6)
models = [MODEL_FILES[normalized_models.index(m)] for m in matches]
return models
return results
def levenshtein(a, b):
if a == b: return 0
if not a: return len(b)
if not b: return len(a)
v0 = list(range(len(b) + 1))
v1 = [0] * (len(b) + 1)
for i in range(len(a)):
v1[0] = i + 1
for j in range(len(b)):
cost = 0 if a[i] == b[j] else 1
v1[j + 1] = min(v1[j] + 1, v0[j + 1] + 1, v0[j] + cost)
v0, v1 = v1, v0
return v0[len(b)]
def main():
with open("wesen.json", encoding="utf-8") as f:
spirits = json.load(f)
output = []
for spirit in spirits:
name = spirit.get("Name", "")
matches = find_best_model(name)
if not matches:
print(f"[!] Kein Modell gefunden für '{name}'!")
new_spirit = spirit.copy()
new_spirit["Model URL"] = ""
output.append(new_spirit)
elif len(matches) == 1:
new_spirit = spirit.copy()
new_spirit["Model URL"] = "/assets/models/spirits/" + matches[0]
output.append(new_spirit)
else:
print(f"\n[?] Mehrere mögliche Modelle für '{name}': {matches}")
for m in matches:
new_spirit = spirit.copy()
new_spirit["Model URL"] = "/assets/models/spirits/" + m
output.append(new_spirit)
with open("spirit_list_out.json", "w", encoding="utf-8") as f:
json.dump(output, f, ensure_ascii=False, indent=2)
print("\nFERTIG. Ergebnis: spirit_list_out.json")
if __name__ == "__main__":
main()