建模程序 多个定时程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

149 lines
7.0 KiB

import bpy
import bmesh
def active_object(obj):
bpy.context.view_layer.objects.active = obj
obj.select_set(True)
def get_obj_max_foot(workdir,filename,filename_tex):
# 1.模型导入和初始化
# 删除当前场景中的所有对象:
# use_global=False表示只删除当前场景中的对象,而不会影响到其他场景中的对象;confirm=False表示删除时不需要确认。
bpy.ops.object.delete(use_global=False, confirm=False)
bpy.ops.import_scene.obj(filepath=filename) # 导入指定路径的 OBJ 格式模型文件
bpy.context.scene.unit_settings.scale_length = 0.001 # 将场景的长度单位缩放为0.001,相当于将长度单位从默认的米缩小为毫米
bpy.context.scene.unit_settings.length_unit = 'CENTIMETERS' # 将场景的长度单位设置为厘米
bpy.context.scene.unit_settings.mass_unit = 'GRAMS' # 将场景的质量单位设置为克
obj = bpy.context.selected_objects[0] # 获取了当前选中的对象列表,然后通过 [0] 取得列表中的第一个对象
bpy.context.view_layer.objects.active = obj # 将变量 obj 设置为当前活动对象
obj.select_set(True) # 将变量 obj 的选择状态设置为 True,表示选中该对象
pid = obj.name # 获取该对象的名字
# 对选定的对象进行对齐操作
bpy.ops.object.align(align_mode='OPT_1', relative_to='OPT_1', align_axis={'Z'})
# 设置选中对象的原点,参数1:将原点设置为对象的质心,参数2:使用对象的几何中心作为参考
bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS', center='MEDIAN')
# 将选中对象的位置坐标分别设置为 (0, 0),即将对象移动到世界坐标系的原点位置
obj.location[0] = 0
obj.location[1] = 0
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True) # 将选中对象的位置、旋转和缩放应用到对象的数据中
# 2.选择要复制的对象
obj_duplicate = obj.copy()
obj_duplicate.data = obj.data.copy()
bpy.context.collection.objects.link(obj_duplicate)
# obj_duplicate.location.x += 5.0
bpy.ops.object.select_all(action='DESELECT') # 取消选中全部对象
# 3.处理复制的对象的脚底缝合边
# 选中复制对象
bpy.context.view_layer.objects.active = obj_duplicate
obj_duplicate.select_set(True)
selected_obj = bpy.context.active_object # 获取当前选中的对象
bpy.context.view_layer.objects.active = selected_obj # 将对象转换到编辑模式
# 切换到3D视图编辑模式
bpy.context.area.type = 'VIEW_3D'
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT') # 选择所有的边
# 切换到UV编辑器
bpy.context.area.type = 'IMAGE_EDITOR'
pid_img = f"{pid}Tex1.jpg"
bpy.ops.image.open(filepath=filename_tex, directory=workdir,
files=[{"name": pid_img, "name": pid_img}], relative_path=True,
show_multiview=False)
bpy.context.area.ui_type = 'UV'
bpy.ops.uv.select_all(action='SELECT') # 选择所有UV贴图顶点
# 标记所有沿孤岛的边为缝合边
bpy.ops.uv.seams_from_islands()
bpy.context.area.type = 'VIEW_3D'
bpy.ops.object.mode_set(mode='OBJECT')
# 获取世界坐标系下z轴接近0的顶点的索引
z_zero_vertex_indices = []
for i, vertex in enumerate(selected_obj.data.vertices):
world_vertex = selected_obj.matrix_world @ vertex.co
if abs(world_vertex.z) < 0.2:
z_zero_vertex_indices.append(i)
# 将对象转换回对象模式
bpy.ops.object.mode_set(mode='OBJECT')
# 创建一个新的顶点组,并将z_zero_vertices中的顶点添加到该顶点组中
vg = selected_obj.vertex_groups.new(name="z_zero_vertices")
for index in z_zero_vertex_indices:
vg.add([index], 1.0, 'REPLACE')
# 将选中的顶点设置为活动顶点
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.vertex_group_select() # 选中待处理的顶点
bpy.ops.mesh.mark_seam(clear=True) # 取消所选区域内的缝合边
bpy.ops.mesh.region_to_loop() # 选择选定面周围的边界边!!!
bpy.ops.mesh.select_mode(type="EDGE") # 转换为线模式
bpy.ops.mesh.mark_seam(clear=False) # 标记所选的线为缝合边
# 选中脚底顶点组
bpy.ops.uv.select_all(action='DESELECT')
bpy.ops.object.vertex_group_set_active(group='z_zero_vertices') # 设置活动顶点组
bpy.ops.object.vertex_group_select() # 选择分配给活动顶点组的所有顶点
bpy.ops.uv.unwrap()
# 处理贴图脚底部分孤岛,其他孤岛保持不变
# (1)反选模型顶点,方便贴图固定不需要处理的区域
bpy.ops.mesh.select_all(action='INVERT')
bpy.context.area.type = 'IMAGE_EDITOR' # 切换到贴图模式
bpy.context.area.ui_type = 'UV'
bpy.ops.uv.pin(clear=False)
bpy.ops.object.vertex_group_set_active(group='z_zero_vertices') # 设置活动顶点组
bpy.ops.object.vertex_group_select() # 选择分配给活动顶点组的所有顶点
# (2)脚底部位UV展开,平均孤岛比例,重新排列孤岛
bpy.ops.uv.select_all(action='SELECT')
bpy.ops.uv.average_islands_scale()
bpy.ops.uv.pack_islands(margin=0.001)
bpy.context.area.type = 'VIEW_3D'
bpy.ops.object.mode_set(mode='OBJECT')
# 4. 烘焙模式,参数设置
bpy.ops.object.select_all(action='DESELECT') # 取消选中全部对象
# # 选中原始对象
bpy.context.view_layer.objects.active = obj
obj.select_set(True)
# 选中复制对象
bpy.context.view_layer.objects.active = obj_duplicate
obj_duplicate.select_set(True)
bpy.context.scene.render.engine = 'CYCLES'
bpy.context.scene.cycles.device = 'GPU'
bpy.context.scene.cycles.preview_samples = 1
bpy.context.scene.cycles.samples = 1
bpy.context.scene.cycles.bake_type = 'DIFFUSE'
bpy.context.scene.render.bake.use_pass_direct = False
bpy.context.scene.render.bake.use_pass_indirect = False
bpy.context.scene.render.bake.use_selected_to_active = True
bpy.context.scene.render.bake.cage_extrusion = 0.01
bpy.ops.object.bake(type='DIFFUSE') # 开始 Bake
# 5. 导出模型和贴图
bpy.ops.object.select_all(action='DESELECT') # 取消选中全部对象
# 选中复制对象
bpy.context.view_layer.objects.active = obj_duplicate
obj_duplicate.select_set(True)
bpy.ops.wm.obj_export(filepath=filename, export_selected_objects=True)
bpy.context.area.type = 'IMAGE_EDITOR' # 切换到
bpy.ops.image.save_as(filepath=filename_tex)
bpy.context.area.type = 'TEXT_EDITOR' # 切换到文本编辑器
if __name__ == '__main__':
workdir = 'E:\\117080\\print_model'
# filename = f'{workdir}\\117080_12cm_x1.obj'
filename = f'{workdir}\\117080.obj'
filename_tex = f'{workdir}\\117080Tex1.jpg'
save_obj = f"{workdir}\\bake\\117080Tex1.obj"
save_tex = f"{workdir}\\bake\\117080Tex1.jpg"
get_obj_max_foot()