Skip to content

Instantly share code, notes, and snippets.

@tw-Frey
Last active May 20, 2025 19:25
Show Gist options
  • Save tw-Frey/c4ddb0e70330d34eb44cce310d231a15 to your computer and use it in GitHub Desktop.
Save tw-Frey/c4ddb0e70330d34eb44cce310d231a15 to your computer and use it in GitHub Desktop.
USDZ convert Glb by Blender Command Line

使用 Blender 來轉換, 指令如下

Windows
blender -b -P usdz_to_glb.py -- %TIME%

Unix
blender -b -P usdz_to_glb.py -- "$(date)"


usdz_to_glb.py

# Blender 3.1.0 (hash c77597cd0e15 built 2022-03-09 00:44:13)
# (GUI流程) https://youtu.be/dGU7ot25P9M
import bpy
import os
import sys
import tempfile
import time
import zipfile

# 開始計時
print("FY-開始: %s %s" % (sys.argv[-2],sys.argv[-1]))

# 時間戳
def timeStamp():
    t=time.time()
    return "%s (%s)" % (time.asctime(time.localtime(t)),t)

# 找出解壓縮後 USDC 位置
def findUSDC(dirpath):
    files = os.listdir(dirpath)
    dirs = []
    for file in files:
        parts = file.split('.')
        filepath = os.path.join(dirpath, file)
        if os.path.isdir(filepath):
            dirs.append(filepath)
        elif len(parts) > 0 and parts[-1] == 'usdc':
            return filepath
    for dir in dirs:
        file = findUSDC(dir)
        if file != '':
            return file
    return ''

# 將 USDZ 解壓縮
def extractUSDC(filepath):
    try:
        if os.path.exists(filepath)==False:
            raise Exception(filepath + " 不存在")
        filePath, fileName = os.path.split(filepath)
        fileName, fileType = fileName.split('.')
    except Exception as e:
        print(e, "輸入不正確")
        return None
    if fileType == 'usdz':
        with zipfile.ZipFile(filepath, 'r') as zf:
            # Create a temp directory to extract to
            tempPath = tempfile.mkdtemp()
            try:
                zf.extractall(tempPath)
            except Exception as e:
                print(e)
            zf.close()
            # Find the usdc file
            usdcFile = findUSDC(tempPath)
            # 遞迴處理
            return extractUSDC(usdcFile)
    elif fileType == 'usdc':
        print(filepath)
        return filepath
    else:
        print("輸入不正確")
        return None
        
# 清除, 匯入USD, 匯出GLB
def main(usdzFileName = sys.argv[-1], usdzFileDir = os.getcwd()):
    # (清除) https://blender.stackexchange.com/questions/46990/how-to-completely-remove-all-loaded-data-from-blender#answer-46991
    bpy.ops.wm.read_factory_settings(use_empty=True)
    # (匯入USD) https://docs.blender.org/api/current/bpy.ops.wm.html?highlight=usd#bpy.ops.wm.usd_import
    iFile = os.path.join(usdzFileDir, usdzFileName)
    print("\t\tFY-輸入: ",iFile,os.path.getsize(iFile),"Bytes")
    iFile = extractUSDC(iFile)
    if iFile==None:
        print("\t\tFY-輸出: ",None)
        return None
    bpy.ops.wm.usd_import(filepath=iFile,import_usd_preview=True)
    # (匯出GLB) https://docs.blender.org/api/current/bpy.ops.export_scene.html?highlight=glb#bpy.ops.export_scene.gltf
    fileName, fileType = usdzFileName.split('.')
    oFile = "%s.glb" % os.path.join(usdzFileDir, fileName)
    bpy.ops.export_scene.gltf(filepath=oFile)
    print("\t\tFY-輸出: ",oFile,os.path.getsize(oFile),"Bytes")
    return oFile

# 主程序
nowDir = os.getcwd()
for file in os.listdir(nowDir):
    parts = file.split('.')
    if len(parts) > 0 and parts[-1] == 'usdz':
        print("\tFY-開始(%s): %s" % (file,timeStamp()))
        main(file, nowDir)
        print("\tFY-結束(%s): %s" % (file,timeStamp()))

# 結束計時
print("FY-結束: " + timeStamp())
@tw-Frey
Copy link
Author

tw-Frey commented Mar 22, 2022

待補充:
1. 解壓縮 [usdz] → [usdc and all others]
2. 建立輸出目錄
3. 指定輸入檔名

@tw-Frey
Copy link
Author

tw-Frey commented Mar 23, 2022

時間統計


範例1: 69MB檔案大小(Car)

  1. 環境建置開啟python: 2secs
  2. 輸入-輸出: 4secs

轉檔6秒內


範例2: 15MB檔案大小(AirForce)

  1. 環境建置開啟python: 2secs
  2. 輸入-輸出: 1secs

轉檔3秒內

@tw-Frey
Copy link
Author

tw-Frey commented Mar 29, 2022

電腦規格:

  • 處理器 Intel(R) Core(TM) i7-7600U CPU @ 2.80GHz 2.90 GHz
  • 已安裝記憶體(RAM) 16.0 GB (15.8 GB 可用)
  • 系統類型 64 位元作業系統,x64 型處理器
  • 版本 Windows 10 專業版
  • 版本 21H2
  • OS 組建 19044.1348

USDZ_to_GLB_流量

推論

保底 0.4 秒,流量 27 MB/秒,誤差 ±1 秒

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment