本文目录导读:

我来介绍几种批量转换3D模型格式的方法:
使用Blender + Python脚本
最通用的方案,支持几乎所有格式:
import bpy
import os
import glob
def batch_convert(input_folder, output_folder, target_format='.fbx'):
# 创建输出文件夹
os.makedirs(output_folder, exist_ok=True)
# 支持的输入格式
input_formats = ['.obj', '.stl', '.glb', '.gltf', '.dae', '.3ds', '.ply']
for ext in input_formats:
files = glob.glob(os.path.join(input_folder, f'*{ext}'))
for file_path in files:
# 清空场景
bpy.ops.wm.read_homefile(use_empty=True)
# 导入模型
file_name = os.path.basename(file_path)
if ext == '.obj':
bpy.ops.import_scene.obj(filepath=file_path)
elif ext == '.stl':
bpy.ops.import_mesh.stl(filepath=file_path)
elif ext in ['.glb', '.gltf']:
bpy.ops.import_scene.gltf(filepath=file_path)
elif ext == '.dae':
bpy.ops.wm.collada_import(filepath=file_path)
# 导出
output_name = file_name.replace(ext, target_format)
output_path = os.path.join(output_folder, output_name)
if target_format == '.fbx':
bpy.ops.export_scene.fbx(filepath=output_path)
elif target_format == '.obj':
bpy.ops.export_scene.obj(filepath=output_path)
elif target_format == '.glb':
bpy.ops.export_scene.gltf(filepath=output_path,
export_format='GLB')
print(f'转换完成: {file_name} -> {output_name}')
# 使用
batch_convert('/path/to/input', '/path/to/output', '.glb')
使用Assimp命令行工具
快速且支持格式多:
# 安装 assimp
# Ubuntu: sudo apt-get install assimp-utils
# Mac: brew install assimp
# 批量转换脚本
#!/bin/bash
INPUT_DIR="./models"
OUTPUT_DIR="./converted"
FORMAT="glb"
mkdir -p "$OUTPUT_DIR"
for file in "$INPUT_DIR"/*.obj "$INPUT_DIR"/*.stl "$INPUT_DIR"/*.dae; do
if [ -f "$file" ]; then
filename=$(basename "$file")
name="${filename%.*}"
output="$OUTPUT_DIR/$name.$FORMAT"
assimp export "$file" "$output"
echo "转换: $filename -> $output"
fi
done
使用Trimesh (Python)
适合处理大量网格模型:
import trimesh
import os
from pathlib import Path
def batch_convert_trimesh(input_dir, output_dir, target_format='glb'):
input_dir = Path(input_dir)
output_dir = Path(output_dir)
output_dir.mkdir(parents=True, exist_ok=True)
# 支持的格式
supported_formats = ['.obj', '.stl', '.ply', '.3mf', '.off', '.glb']
for ext in supported_formats:
for file_path in input_dir.glob(f'*{ext}'):
try:
# 加载模型
mesh = trimesh.load_mesh(file_path)
# 输出路径
output_path = output_dir / f'{file_path.stem}.{target_format}'
# 导出
mesh.export(output_path)
print(f'转换完成: {file_path.name}')
except Exception as e:
print(f'转换失败 {file_path.name}: {e}')
# 使用
batch_convert_trimesh('./input_models', './output_models', 'glb')
使用Unity Editor脚本
适合游戏开发工作流:
using UnityEngine;
using UnityEditor;
using System.IO;
public class BatchModelConverter : EditorWindow
{
[MenuItem("Tools/Batch Convert Models")]
static void ConvertModels()
{
string sourceFolder = "Assets/SourceModels";
string targetFolder = "Assets/ConvertedModels";
// 获取所有FBX文件
string[] guids = AssetDatabase.FindAssets("t:Model",
new[] { sourceFolder });
foreach (string guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
string fileName = Path.GetFileNameWithoutExtension(path);
// 设置导入设置
ModelImporter importer = AssetImporter.GetAtPath(path)
as ModelImporter;
if (importer != null)
{
// 修改设置
importer.materialLocation = ModelImporterMaterialLocation.External;
importer.importNormals = ModelImporterNormals.Import;
importer.importTangents = ModelImporterTangents.Import;
// 重新导入
importer.SaveAndReimport();
// 复制到目标文件夹
string targetPath = $"{targetFolder}/{fileName}.fbx";
AssetDatabase.CopyAsset(path, targetPath);
}
}
AssetDatabase.Refresh();
Debug.Log("批量转换完成!");
}
}
使用Node.js + three.js
适合Web应用场景:
const fs = require('fs-extra');
const path = require('path');
const { exec } = require('child_process');
// 安装: npm install -g three.js
async function batchConvert(inputDir, outputDir, targetFormat = 'glb') {
await fs.ensureDir(outputDir);
const files = await fs.readdir(inputDir);
for (const file of files) {
const ext = path.extname(file).toLowerCase();
const name = path.basename(file, ext);
const inputPath = path.join(inputDir, file);
const outputPath = path.join(outputDir, `${name}.${targetFormat}`);
// 使用 three.js 的 CLI 工具
const cmd = `npx three-convert ${inputPath} ${outputPath}`;
try {
await new Promise((resolve, reject) => {
exec(cmd, (error, stdout, stderr) => {
if (error) reject(error);
else resolve(stdout);
});
});
console.log(`转换完成: ${file}`);
} catch (error) {
console.error(`转换失败 ${file}:`, error.message);
}
}
}
// 使用
batchConvert('./input', './output', 'glb');
格式支持表
| 工具 | 输入格式 | 输出格式 | 特点 |
|---|---|---|---|
| Blender | 几乎所有格式 | 几乎所有格式 | 功能最强大 |
| Assimp | 40+种 | 多种 | 轻量快速 |
| Trimesh | 常见格式 | 常见格式 | 适合Python |
| Unity | FBX, OBJ等 | FBX | 游戏引擎集成 |
批量处理建议
- 预处理检查:先检查源文件完整性
- 错误处理:添加异常捕获,记录失败文件
- 并行处理:使用多线程提高速度
- 材质处理:注意纹理和材质的保留
选择哪种方法取决于你的具体需求和环境,Blender方案最通用,Assimp最快速,Trimesh最适合数据处理场景。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播