Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I cant import glb file into blender Error:Extension PIXIV_texture_basis is not available on this addon version #2346

Open
Be3up opened this issue Sep 9, 2024 · 6 comments
Labels
question Further information is requested

Comments

@Be3up
Copy link

Be3up commented Sep 9, 2024

изображение_2024-09-09_091303181
error: Extension PIXIV_texture_basis is not available on this addon version
how fix it?

@Be3up Be3up changed the title I cant import glb file into blender I cant import glb file into blender Error:Extension PIXIV_texture_basis is not available on this addon version Sep 9, 2024
@julienduroure
Copy link
Collaborator

Hello,
Blender glTF I/O manages only officialy ratified extensions.
PIXIV_texture_basis is not a ratified extension, and it seems this extensions is declared as required in this file.
So, as is, there is no way to read your file.

@Be3up
Copy link
Author

Be3up commented Sep 9, 2024

Hello, Blender glTF I/O manages only officialy ratified extensions. PIXIV_texture_basis is not a ratified extension, and it seems this extensions is declared as required in this file. So, as is, there is no way to read your file.

what do?

@julienduroure
Copy link
Collaborator

I never heard of PIXIV before your ticket, so I don't know where your file come from.
If you share your file, I maybe able to understand what this extension is about, and open it without any textures.
If this extension is similar to KHR_texture_basisu, you may be able to convert it to remove this extension with some tools like gltf-transform.

@Be3up
Copy link
Author

Be3up commented Sep 9, 2024

I never heard of PIXIV before your ticket, so I don't know where your file come from. If you share your file, I maybe able to understand what this extension is about, and open it without any textures. If this extension is similar to KHR_texture_basisu, you may be able to convert it to remove this extension with some tools like gltf-transform.

i wanna delete texture and make my texture for model
plz help

@Be3up Be3up closed this as completed Sep 9, 2024
@Be3up
Copy link
Author

Be3up commented Sep 9, 2024

До вашего билета я никогда не слышал о PIXIV, поэтому не знаю, откуда взялся ваш файл. Если вы поделитесь своим файлом, возможно, я смогу понять, что это за расширение, и открыть его без каких-либо текстур. Если это расширение похоже на KHR_texture_basisu , вы можете преобразовать его, чтобы удалить это расширение, с помощью некоторых инструментов, таких как gltf-transform.

I Download preview models (viewable in the browser) from VRoid Hub. Handles decryption and decompression (assist from bin). through script vroid-hub-downloader.py
link of script https://github.com/CetaceanNation/misc-scripts/blob/main/vroid-hub-downloader/vroid-hub-downloader.py

this is code of script:
#!/usr/bin/env python3
import argparse
from Crypto.Cipher import AES
import gzip
import io
import json
import os
import re
import requests
import sys
import zstandard

USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/114.0"
HOST = "https://hub.vroid.com"
API_VERSION = "11"
MODEL_FILE_EXT = "glb"
VROID_BASE = r"(?:https?://)?hub.vroid.com/(?P[a-z]{2}/)?"
VROID_USER = VROID_BASE + r"users/(?P<user_id>\d+)"
VROID_MODEL = VROID_BASE + r"characters/(?P<character_id>\d+)/models/(?P<model_id>\d+)"

def unpad(s):
return s[:-ord(s[len(s)-1:])]

def get_user_model_ids(user_id):
model_ids = []
api_url = f"{HOST}/api/users/{user_id}/character_models?antisocial_or_hate_usage=&characterization_allowed_user=&corporate_commercial_use=&credit=&modification=&personal_commercial_use=&political_or_religious_usage=&redistribution=&sexual_expression=&violent_expression="
page_num = 1
while api_url:
user_r = requests.get(api_url, headers={"User-Agent": USER_AGENT, "X-Api-Version": API_VERSION})
if not user_r.ok:
print(f"[user:{user_id}:page:{page_num}] got bad response from vroid hub, {user_r.status_code}")
break
user_j = user_r.json()
if "next" in user_j["_links"]:
api_url = HOST + user_j["_links"]["next"]["href"]
else:
api_url = None
for model in user_j["data"]:
model_ids.append(model["id"])
print(f"[user:{user_id}] found {len(model_ids)} models")
return model_ids

def download_preview_model(model_id):
model_preview_url = f"{HOST}/api/character_models/{model_id}/optimized_preview"
model_r = requests.get(model_preview_url, allow_redirects=True, headers={"User-Agent": USER_AGENT, "X-Api-Version": API_VERSION})
if not model_r.ok:
print(f"[model:{model_id}:preview] got bad response from vroid hub, {model_r.status_code}")
print(f"[model:{model_id}:preview] {model_r.content.decode()}")
return None
return io.BytesIO(model_r.content)

def decrypt_decompress_model(model_id, model_bytes, model_filename):
if not os.path.isfile(model_filename):
with open(model_filename, "wb") as dec_vrm:
iv_bytes = model_bytes.read(16)
key_bytes = model_bytes.read(32)
key_context = AES.new(key_bytes, AES.MODE_CBC, iv_bytes)
enc_data = model_bytes.read()
dec_data = unpad(key_context.decrypt(enc_data))[4:]
dctx = zstandard.ZstdDecompressor()
with dctx.stream_writer(dec_vrm) as decompressor:
decompressor.write(dec_data)
print(f"[model:{model_id}] wrote decrypted and decompressed model '{os.path.basename(model_filename)}'")
else:
print(f"[model:{model_id}] '{os.path.basename(model_filename)}' already exists")

def download_model_from_vroid(model_id, subdir=None):
model_path_base = os.path.join(subdir if subdir else args.directory, model_id)
model_api_url = f"{HOST}/api/character_models/{model_id}"
json_path = f"{model_path_base}.info.json"
model_api_r = requests.get(model_api_url, headers={"User-Agent": USER_AGENT, "X-Api-Version": API_VERSION})
if not model_api_r.ok:
print(f"[model:{model_id}:api] got bad response from vroid hub, {model_r.status_code}")
return
model_api_j = model_api_r.json()["data"]
if args.write_info_json and not os.path.isfile(json_path):
with open(json_path, "w") as json_file:
json_file.write(json.dumps(model_api_j))
print(f"[model:{model_id}:api] wrote '{os.path.basename(json_path)}'")
else:
print(f"[model:{model_id}:api] '{os.path.basename(json_path)}' already exists")
if not "conversion_state" in model_api_j["character_model"]["latest_character_model_version"]:
print(f"[model:{model_id}:api] warning: JSON response implies model preview does not exist, expecting 404")
elif model_api_j["character_model"]["latest_character_model_version"]["conversion_state"]["current_state"] != "completed":
print(f"[model:{model_id}:api] warning: JSON response implies model preview is not ready, expecting 404")
enc_vrm = download_preview_model(model_id)
if not enc_vrm:
return
decrypt_decompress_model(model_id, enc_vrm, f"{model_path_base}.{MODEL_FILE_EXT}")

def download_user_from_vroid(user_id):
user_api_url = f"{HOST}/api/users/{user_id}"
user_api_r = requests.get(user_api_url, headers={"User-Agent": USER_AGENT, "X-Api-Version": API_VERSION})
if not user_api_r.ok:
print(f"[user:{user_id}:api] got bad response from vroid hub, user might not exist, {user_api_r.status_code}")
return
user_api_j = user_api_r.json()
username = user_api_j["data"]["user"]["name"]
user_base_path = os.path.join(args.directory, f"{username} ({user_id})")
if not os.path.isdir(user_base_path):
os.makedirs(user_base_path)
json_path = f"{user_base_path}.info.json"
if args.write_info_json:
with open(json_path, "w") as json_file:
json_file.write(json.dumps(user_api_j["data"]))
print(f"[user:{user_id}:api] wrote '{os.path.basename(json_path)}'")
model_ids = get_user_model_ids(user_id)
for model_id in model_ids:
download_model_from_vroid(model_id, user_base_path)

parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument("-d", "--directory", type=str, help="save directory (defaults to current)", default=os.getcwd())
parser.add_argument("--write-info-json", action="store_true", help="write user/model json information for urls")
parser.add_argument("vrms", metavar="vroid links/vrm files", nargs="*", help="vroid hub links or encrypted vrm files i.e.\nhttps://hub.vroid.com/en/users/49620\nhttps://hub.vroid.com/en/characters/6819070713126783571/models/9038381612772945358\n2520951134072570694.vrm")
args = parser.parse_args()

if not os.path.isdir(args.directory):
os.makedirs(args.directory)

for vrm in args.vrms:
vroid_usr_m = re.search(VROID_USER, vrm)
model_m = re.search(VROID_MODEL, vrm)
if vroid_usr_m:
user_id = vroid_usr_m.group("user_id")
download_user_from_vroid(user_id)
elif model_m:
model_id = model_m.group("model_id")
download_model_from_vroid(model_id)
else:
if not os.path.isfile(vrm):
print(f"could not find file at path '{vrm}'")
continue
with open(vrm, "rb") as vrm_file:
enc_vrm = io.BytesIO(vrm_file.read())
model_filename = os.path.join(args.directory, f"{vrm}.decrypted.{MODEL_FILE_EXT}")
decrypt_decompress_model(enc_vrm, model_filename)

@julienduroure
Copy link
Collaborator

i wanna delete texture and make my texture for model
plz help

It will require to have the file, open it, and modify the provided file, by hand or programmatically.
This is out of the scope of this issue tracker, as there is no bug in the importer.

I do not plan to try to download a file from the website or using your script.
If you want help, you should provide the file

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants