目录glb缩放trimesh转换glb缩放缩放并把中心点移动到原点import os import trimesh import glob def move_to_zero(mesh): mesh.apply_translation(-mesh.centroid) print(f模型中心点: {mesh.centroid}) def scale_to_target_mm(input_path, output_path, target_mm): mesh trimesh.load(input_path) # 获取当前最大边长米 bounds mesh.bounds current_size bounds[1] - bounds[0] current_max_m max(current_size) # 目标尺寸米 target_m target_mm #/ 1000 # 计算缩放因子 scale_factor target_m / current_max_m print(f当前最大边长: {current_max_m:.3f} 米 ({current_max_m:.1f} mm)) print(f目标边长: {target_mm} mm) print(f缩放因子: {scale_factor}) # 应用缩放 mesh.apply_scale(scale_factor) move_to_zero(mesh) mesh.export(output_path, file_typeglb) # 验证 new_bounds mesh.bounds new_size new_bounds[1] - new_bounds[0] print(f缩放后最大边长: {max(new_size) :.1f} mm) return scale_factor if __name__ __main__: input_dirrE:\project\3d_label\three-bvh-csg-main\examples\kakou_m output_dirrE:\project\3d_label\three-bvh-csg-main\examples\kakou_s os.makedirs(output_dir, exist_okTrue) glb_files glob.glob(os.path.join(input_dir, *.glb)) glb_files.extend(glob.glob(os.path.join(input_dir, *.GLB))) print(f找到 {len(glb_files)} 个 GLB 文件) for i, input_path in enumerate(glb_files, 1): filename os.path.basename(input_path) output_path os.path.join(output_dir, filename) scale_to_target_mm(input_pathinput_path, output_pathoutput_path, target_mm8)trimesh转换import trimesh import numpy as np import os def analyze_and_convert_stl_to_glb(input_path, output_pathNone, scale_factor1.0, apply_scaleTrue): if not os.path.exists(input_path): print(f错误文件不存在 - {input_path}) return None print(f读取 STL 文件: {os.path.basename(input_path)}) print( * 60) try: mesh trimesh.load_mesh(input_path, processFalse) # processFalse 保留原始数据 print(✓ 文件加载成功) except Exception as e: print(f✗ 加载失败: {e}) return None # 打印模型参数 print(\n【模型基本参数】) print(- * 40) # 顶点和面信息 vertices_count len(mesh.vertices) faces_count len(mesh.faces) print(f顶点数: {vertices_count:,}) print(f三角形面数: {faces_count:,}) # 包围盒尺寸 bounds mesh.bounds min_bound bounds[0] max_bound bounds[1] size max_bound - min_bound print(f\n【包围盒尺寸】) print(f 宽度 (X轴): {size[0]:.4f} 米 ({size[0] * 1000:.2f} mm)) print(f 高度 (Y轴): {size[1]:.4f} 米 ({size[1] * 1000:.2f} mm)) print(f 深度 (Z轴): {size[2]:.4f} 米 ({size[2] * 1000:.2f} mm)) print(f 最长边: {max(size):.4f} 米 ({max(size) * 1000:.2f} mm)) # 包围盒范围 print(f\n【包围盒范围】) print(f X: [{min_bound[0]:.4f}, {max_bound[0]:.4f}] 米) print(f Y: [{min_bound[1]:.4f}, {max_bound[1]:.4f}] 米) print(f Z: [{min_bound[2]:.4f}, {max_bound[2]:.4f}] 米) # 中心点 center mesh.centroid print(f\n【质心/中心点】) print(f ({center[0]:.4f}, {center[1]:.4f}, {center[2]:.4f}) 米) # 体积和表面积 try: volume mesh.volume area mesh.area print(f\n【几何属性】) print(f 体积: {volume:.6f} 立方米 ({volume * 1e6:.2f} 立方厘米)) print(f 表面积: {area:.6f} 平方米 ({area * 1e4:.2f} 平方厘米)) except: print(f\n【几何属性】) print(f 体积: 无法计算网格可能不封闭) print(f 表面积: 无法计算) # 判断是否为流形 is_watertight mesh.is_watertight print(f\n【网格质量】) print(f 是否为水密/流形: {是 ✓ if is_watertight else 否 ✗}) if not is_watertight: # 检查边界边数 try: edges mesh.edges_unique boundary_edges sum(1 for e in edges if len(mesh.edge_adjacencies[e[0], e[1]] if hasattr(mesh, edge_adjacencies) else 0) 2) print(f 边界边数: {boundary_edges}) except: pass # 缩放处理 if apply_scale and scale_factor ! 1.0: print(f\n【缩放处理】) print(f 缩放因子: {scale_factor}) mesh.apply_scale(scale_factor) # 打印缩放后的尺寸 new_bounds mesh.bounds new_size new_bounds[1] - new_bounds[0] print(f 缩放后尺寸: {new_size[0]:.4f} × {new_size[1]:.4f} × {new_size[2]:.4f} 米) print(f 缩放后最大边长: {max(new_size) * 1000:.2f} mm) # 导出 GLB if output_path is None: base_name os.path.splitext(input_path)[0] output_path base_name .glb try: mesh.export(output_path, file_typeglb) print(f\n【导出完成】) print(f 输出文件: {output_path}) print(f 文件大小: {os.path.getsize(output_path) / 1024:.2f} KB) print( * 60) return mesh except Exception as e: print(f\n✗ 导出失败: {e}) return None def batch_convert_stl_to_glb(input_dir, output_dirNone, scale_factor1.0): import glob # 查找所有 STL 文件 stl_files glob.glob(os.path.join(input_dir, *.stl)) stl_files.extend(glob.glob(os.path.join(input_dir, *.STL))) if not stl_files: print(f错误在目录 {input_dir} 中没有找到 STL 文件) return print(f\n找到 {len(stl_files)} 个 STL 文件) print( * 60) # 创建输出目录 if output_dir and not os.path.exists(output_dir): os.makedirs(output_dir) success_count 0 fail_count 0 for i, input_file in enumerate(stl_files, 1): print(f\n[{i}/{len(stl_files)}] 处理: {os.path.basename(input_file)}) if output_dir: output_file os.path.join(output_dir, os.path.splitext(os.path.basename(input_file))[0] .glb) else: output_file os.path.splitext(input_file)[0] .glb try: mesh trimesh.load_mesh(input_file, processFalse) if scale_factor ! 1.0: mesh.apply_scale(scale_factor) mesh.export(output_file, file_typeglb) # 打印尺寸 size mesh.bounds[1] - mesh.bounds[0] print(f ✓ 成功 | 尺寸: {max(size) * 1000:.1f}mm | 输出: {os.path.basename(output_file)}) success_count 1 except Exception as e: print(f ✗ 失败: {e}) fail_count 1 print(\n * 60) print(f批量转换完成) print(f成功: {success_count} 个) print(f失败: {fail_count} 个) print( * 60) # 使用示例 if __name__ __main__: # 单个文件转换 INPUT_STL rE:\soft\qiuxing2.stl # 修改为你的 STL 文件路径 # 方式2缩放后转换例如米转毫米缩放 0.001 analyze_and_convert_stl_to_glb(INPUT_STL, scale_factor0.001) # 方式3指定输出路径并缩放 # OUTPUT_GLB rC:\path\to\output\model.glb # analyze_and_convert_stl_to_glb(INPUT_STL, OUTPUT_GLB, scale_factor0.001) # 批量转换目录中的所有 STL # batch_convert_stl_to_glb( # input_dirrC:\path\to\stl_files, # output_dirrC:\path\to\glb_output, # scale_factor0.001 # 米转毫米 # ) # 如果只是查看模型参数不导出 if os.path.exists(INPUT_STL): analyze_and_convert_stl_to_glb(INPUT_STL, scale_factor1.0) else: print(f请修改 INPUT_STL 变量为你的 STL 文件路径) print(\n使用方法:) print( 1. 修改 INPUT_STL 你的模型.stl) print( 2. 运行脚本) print(\n可选参数:) print( - scale_factor0.001 : 米转毫米) print( - scale_factor25.4 : 英寸转毫米)
stl转glb glb缩放
发布时间:2026/6/9 19:55:13
目录glb缩放trimesh转换glb缩放缩放并把中心点移动到原点import os import trimesh import glob def move_to_zero(mesh): mesh.apply_translation(-mesh.centroid) print(f模型中心点: {mesh.centroid}) def scale_to_target_mm(input_path, output_path, target_mm): mesh trimesh.load(input_path) # 获取当前最大边长米 bounds mesh.bounds current_size bounds[1] - bounds[0] current_max_m max(current_size) # 目标尺寸米 target_m target_mm #/ 1000 # 计算缩放因子 scale_factor target_m / current_max_m print(f当前最大边长: {current_max_m:.3f} 米 ({current_max_m:.1f} mm)) print(f目标边长: {target_mm} mm) print(f缩放因子: {scale_factor}) # 应用缩放 mesh.apply_scale(scale_factor) move_to_zero(mesh) mesh.export(output_path, file_typeglb) # 验证 new_bounds mesh.bounds new_size new_bounds[1] - new_bounds[0] print(f缩放后最大边长: {max(new_size) :.1f} mm) return scale_factor if __name__ __main__: input_dirrE:\project\3d_label\three-bvh-csg-main\examples\kakou_m output_dirrE:\project\3d_label\three-bvh-csg-main\examples\kakou_s os.makedirs(output_dir, exist_okTrue) glb_files glob.glob(os.path.join(input_dir, *.glb)) glb_files.extend(glob.glob(os.path.join(input_dir, *.GLB))) print(f找到 {len(glb_files)} 个 GLB 文件) for i, input_path in enumerate(glb_files, 1): filename os.path.basename(input_path) output_path os.path.join(output_dir, filename) scale_to_target_mm(input_pathinput_path, output_pathoutput_path, target_mm8)trimesh转换import trimesh import numpy as np import os def analyze_and_convert_stl_to_glb(input_path, output_pathNone, scale_factor1.0, apply_scaleTrue): if not os.path.exists(input_path): print(f错误文件不存在 - {input_path}) return None print(f读取 STL 文件: {os.path.basename(input_path)}) print( * 60) try: mesh trimesh.load_mesh(input_path, processFalse) # processFalse 保留原始数据 print(✓ 文件加载成功) except Exception as e: print(f✗ 加载失败: {e}) return None # 打印模型参数 print(\n【模型基本参数】) print(- * 40) # 顶点和面信息 vertices_count len(mesh.vertices) faces_count len(mesh.faces) print(f顶点数: {vertices_count:,}) print(f三角形面数: {faces_count:,}) # 包围盒尺寸 bounds mesh.bounds min_bound bounds[0] max_bound bounds[1] size max_bound - min_bound print(f\n【包围盒尺寸】) print(f 宽度 (X轴): {size[0]:.4f} 米 ({size[0] * 1000:.2f} mm)) print(f 高度 (Y轴): {size[1]:.4f} 米 ({size[1] * 1000:.2f} mm)) print(f 深度 (Z轴): {size[2]:.4f} 米 ({size[2] * 1000:.2f} mm)) print(f 最长边: {max(size):.4f} 米 ({max(size) * 1000:.2f} mm)) # 包围盒范围 print(f\n【包围盒范围】) print(f X: [{min_bound[0]:.4f}, {max_bound[0]:.4f}] 米) print(f Y: [{min_bound[1]:.4f}, {max_bound[1]:.4f}] 米) print(f Z: [{min_bound[2]:.4f}, {max_bound[2]:.4f}] 米) # 中心点 center mesh.centroid print(f\n【质心/中心点】) print(f ({center[0]:.4f}, {center[1]:.4f}, {center[2]:.4f}) 米) # 体积和表面积 try: volume mesh.volume area mesh.area print(f\n【几何属性】) print(f 体积: {volume:.6f} 立方米 ({volume * 1e6:.2f} 立方厘米)) print(f 表面积: {area:.6f} 平方米 ({area * 1e4:.2f} 平方厘米)) except: print(f\n【几何属性】) print(f 体积: 无法计算网格可能不封闭) print(f 表面积: 无法计算) # 判断是否为流形 is_watertight mesh.is_watertight print(f\n【网格质量】) print(f 是否为水密/流形: {是 ✓ if is_watertight else 否 ✗}) if not is_watertight: # 检查边界边数 try: edges mesh.edges_unique boundary_edges sum(1 for e in edges if len(mesh.edge_adjacencies[e[0], e[1]] if hasattr(mesh, edge_adjacencies) else 0) 2) print(f 边界边数: {boundary_edges}) except: pass # 缩放处理 if apply_scale and scale_factor ! 1.0: print(f\n【缩放处理】) print(f 缩放因子: {scale_factor}) mesh.apply_scale(scale_factor) # 打印缩放后的尺寸 new_bounds mesh.bounds new_size new_bounds[1] - new_bounds[0] print(f 缩放后尺寸: {new_size[0]:.4f} × {new_size[1]:.4f} × {new_size[2]:.4f} 米) print(f 缩放后最大边长: {max(new_size) * 1000:.2f} mm) # 导出 GLB if output_path is None: base_name os.path.splitext(input_path)[0] output_path base_name .glb try: mesh.export(output_path, file_typeglb) print(f\n【导出完成】) print(f 输出文件: {output_path}) print(f 文件大小: {os.path.getsize(output_path) / 1024:.2f} KB) print( * 60) return mesh except Exception as e: print(f\n✗ 导出失败: {e}) return None def batch_convert_stl_to_glb(input_dir, output_dirNone, scale_factor1.0): import glob # 查找所有 STL 文件 stl_files glob.glob(os.path.join(input_dir, *.stl)) stl_files.extend(glob.glob(os.path.join(input_dir, *.STL))) if not stl_files: print(f错误在目录 {input_dir} 中没有找到 STL 文件) return print(f\n找到 {len(stl_files)} 个 STL 文件) print( * 60) # 创建输出目录 if output_dir and not os.path.exists(output_dir): os.makedirs(output_dir) success_count 0 fail_count 0 for i, input_file in enumerate(stl_files, 1): print(f\n[{i}/{len(stl_files)}] 处理: {os.path.basename(input_file)}) if output_dir: output_file os.path.join(output_dir, os.path.splitext(os.path.basename(input_file))[0] .glb) else: output_file os.path.splitext(input_file)[0] .glb try: mesh trimesh.load_mesh(input_file, processFalse) if scale_factor ! 1.0: mesh.apply_scale(scale_factor) mesh.export(output_file, file_typeglb) # 打印尺寸 size mesh.bounds[1] - mesh.bounds[0] print(f ✓ 成功 | 尺寸: {max(size) * 1000:.1f}mm | 输出: {os.path.basename(output_file)}) success_count 1 except Exception as e: print(f ✗ 失败: {e}) fail_count 1 print(\n * 60) print(f批量转换完成) print(f成功: {success_count} 个) print(f失败: {fail_count} 个) print( * 60) # 使用示例 if __name__ __main__: # 单个文件转换 INPUT_STL rE:\soft\qiuxing2.stl # 修改为你的 STL 文件路径 # 方式2缩放后转换例如米转毫米缩放 0.001 analyze_and_convert_stl_to_glb(INPUT_STL, scale_factor0.001) # 方式3指定输出路径并缩放 # OUTPUT_GLB rC:\path\to\output\model.glb # analyze_and_convert_stl_to_glb(INPUT_STL, OUTPUT_GLB, scale_factor0.001) # 批量转换目录中的所有 STL # batch_convert_stl_to_glb( # input_dirrC:\path\to\stl_files, # output_dirrC:\path\to\glb_output, # scale_factor0.001 # 米转毫米 # ) # 如果只是查看模型参数不导出 if os.path.exists(INPUT_STL): analyze_and_convert_stl_to_glb(INPUT_STL, scale_factor1.0) else: print(f请修改 INPUT_STL 变量为你的 STL 文件路径) print(\n使用方法:) print( 1. 修改 INPUT_STL 你的模型.stl) print( 2. 运行脚本) print(\n可选参数:) print( - scale_factor0.001 : 米转毫米) print( - scale_factor25.4 : 英寸转毫米)