Você está no 3DFinder
Buscamos em Thingiverse, MakerWorld e Printables ao mesmo tempo para te dar o melhor de cada uma.
Descrição
blender 4.4,在脚本区域,将脚本复制到Text Editor中,然后点击Run Script即可
Stage 1 -> Stage 2:
blender
将所有图标的旋转调整正确
```python
import bpy
import os
import re
input_dir = r"E:\3DPrint\FF14ZhiYeTuBiao\stage1"
output_dir = r"E:\3DPrint\FF14ZhiYeTuBiao\stage2"
# 自动创建输出文件夹
os.makedirs(output_dir, exist_ok=True)
def strip_leading_digit(filename):
# 去掉前导的1/2/3,只保留一次.stl后缀
name = re.sub(r"^[123]", "", filename, count=1)
return name
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
stl_files = [f for f in os.listdir(input_dir) if f.lower().endswith('.stl') and not f.lower() == "hole.stl"]
for model_name in stl_files:
# 判断旋转角度
prefix_digit = model_name[0]
rotation_z = 0
if prefix_digit == "1":
rotation_z = 90
elif prefix_digit == "2":
rotation_z = 180
elif prefix_digit == "3":
rotation_z = 270
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
model_path = os.path.join(input_dir, model_name)
bpy.ops.wm.stl_import(filepath=model_path)
model_obj = bpy.context.selected_objects[0]
model_obj.name = "TargetObj"
# 旋转
if rotation_z != 0:
bpy.context.view_layer.objects.active = model_obj
model_obj.select_set(True)
bpy.ops.transform.rotate(value=-rotation_z * 3.14159265 / 180, orient_axis='Z')
# 导出文件名去掉前导数字
export_name = strip_leading_digit(model_name)
if not export_name.lower().endswith('.stl'):
export_name += '.stl'
output_path = os.path.join(output_dir, export_name)
bpy.ops.object.select_all(action='DESELECT')
model_obj.select_set(True)
bpy.context.view_layer.objects.active = model_obj
bpy.ops.wm.stl_export(filepath=output_path)
print("批量旋转并导出完成!")
```
Stage 2 -> Stage 3:
blender
将所有图标的左上角打孔,这一步处理前一定要先修复模型!
```python
import bpy
import os
import bpy
import os
input_dir = r"E:\\3DPrint\\FF14ZhiYeTuBiao\\stage2"
output_dir = r"E:\\3DPrint\\FF14ZhiYeTuBiao\\stage3"
hole_path = r"E:\\3DPrint\\FF14ZhiYeTuBiao\\hole.stl"
# 偏移量(如需打孔稍微往右下移,可调整,单位同模型)
offset_x = 2
offset_y = -2
offset_z = 0.0
def get_bbox_min(obj):
return [min([v[i] for v in obj.bound_box]) for i in range(3)]
def get_bbox_max(obj):
return [max([v[i] for v in obj.bound_box]) for i in range(3)]
# 自动创建输出目录
os.makedirs(output_dir, exist_ok=True)
# 清空场景
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
# 加载hole.stl
bpy.ops.wm.stl_import(filepath=hole_path)
hole_obj = bpy.context.selected_objects[0]
hole_mesh = hole_obj.data.copy()
hole_min = get_bbox_min(hole_obj)
hole_max = get_bbox_max(hole_obj)
bpy.data.objects.remove(hole_obj, do_unlink=True)
# 遍历stage2下所有stl
for model_name in os.listdir(input_dir):
if not model_name.lower().endswith('.stl'):
continue
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
model_path = os.path.join(input_dir, model_name)
bpy.ops.wm.stl_import(filepath=model_path)
model_obj = bpy.context.selected_objects[0]
model_obj.name = "TargetObj"
model_min = get_bbox_min(model_obj)
model_max = get_bbox_max(model_obj)
# 计算hole应放置位置(左上角:x最小,y最大,z最小),要对齐hole的最小x、最大y、最小z
hole_location = [
model_min[0] - hole_min[0] + offset_x,
model_max[1] - hole_max[1] + offset_y,
model_min[2] - hole_min[2] + offset_z
]
hole_copy = bpy.data.objects.new("HoleCopy", hole_mesh.copy())
bpy.context.collection.objects.link(hole_copy)
hole_copy.location = hole_location
# 布尔差集
bpy.context.view_layer.objects.active = model_obj
bool_mod = model_obj.modifiers.new(name="Boolean", type='BOOLEAN')
bool_mod.operation = 'DIFFERENCE'
bool_mod.object = hole_copy
bpy.ops.object.modifier_apply(modifier=bool_mod.name)
bpy.data.objects.remove(hole_copy, do_unlink=True)
# 导出
bpy.ops.object.select_all(action='DESELECT')
model_obj.select_set(True)
bpy.context.view_layer.objects.active = model_obj
output_path = os.path.join(output_dir, model_name)
bpy.ops.wm.stl_export(filepath=output_path)
print("批量左上角打孔并输出stage3完成!")
```
Gostou deste modelo? Crie uma conta grátis para salvar seus favoritos e voltar a eles depois.
Criar conta