import bpy import bmesh import os import sys import numpy as np from mathutils import Vector import datetime import json from pathlib import Path import inspect current_file_path = Path(os.path.abspath(__file__)).parent workplace_dir_path = str(current_file_path /"exe" / "Workplace") executable_dir_path = str(current_file_path / "exe" / "Release") def read_parameter_file(parameter_file_path): isbridge_arg = False hole_height_arg = 0.0 hole_radius_arg = 0.0 use_honeycomb_type_arg = False hole_distance_arg = 0.0 texture_style_arg = "" use_sharp_edge_arg = False angle_of_se_arg = 0.0 area_threshold_arg = 0 boundary_margin_arg= 0.25 number_id_arg = False with open(parameter_file_path, 'r') as param_file: lines = param_file.readlines() for line in lines: parts = line.strip().split(':') if len(parts) == 2: param_name = parts[0].strip() param_value = parts[1].strip() # 根据参数名称设置相应的属性值 if param_name == "IsBridge": isbridge_arg = param_value.lower() == "true" if param_name == "Hole Height": hole_height_arg = float(param_value) elif param_name == "Hole Radius": hole_radius_arg = float(param_value) elif param_name == "Use Honeycomb Type": use_honeycomb_type_arg = param_value.lower() == "true" elif param_name == "Hole Distance": hole_distance_arg = float(param_value) elif param_name == "Texture Style": texture_style_arg = int(param_value) elif param_name == "Use_sharp_edge": use_sharp_edge_arg = param_value.lower() == "true" elif param_name == "Angle_of_se": angle_of_se_arg = float(param_value) elif param_name == "Area_threshold": area_threshold_arg = int(param_value) elif param_name == "Boundary_Margin": boundary_margin_arg = float(param_value) elif param_name == "Number ID": number_id_arg = param_value.lower() == "true" return (isbridge_arg,hole_height_arg, hole_radius_arg, \ use_honeycomb_type_arg, \ hole_distance_arg, texture_style_arg, use_sharp_edge_arg,\ angle_of_se_arg, area_threshold_arg, boundary_margin_arg, number_id_arg) parameter_file_path = os.path.join(workplace_dir_path, "parameters", "qianya1.txt") processed_files_path = os.path.join(workplace_dir_path, "parameters", "processed_files.txt") recent_parameter_file_path= os.path.join(workplace_dir_path, "parameters", "recent.txt") failed_models_files_path=os.path.join(workplace_dir_path, "parameters", "failed_models_files.txt") counter_path=os.path.join(workplace_dir_path, "parameters", "counter.txt") # style_items = [ # ('圆台1', '圆台1', ''), # ('圆台2', '圆台2', ''), # ('圆柱', '圆柱', ''), # ('方形', '方形', ''), # ('三角形', '三角形', ''), # ('六边形', '六边形', ''), # ('八边形', '八边形', '') # ] parameter_file_path = os.path.join(workplace_dir_path, "parameters", "input.txt") (isbridge_arg,hole_height, hole_radius, use_honeycomb_type, \ hole_distance, texture_style, use_sharp_edge,angle_of_se, area_threshold,\ boundary_margin, number_id) = read_parameter_file(parameter_file_path) counter = 0 folder_path=workplace_dir_path folder_path=folder_path+"/assets" file_list = os.listdir(folder_path) model_files = [filename for filename in file_list if filename.endswith(".stl")] with open(processed_files_path, 'r') as file: processed_files = file.read().splitlines() with open(failed_models_files_path, 'r') as file: failed_models_files = [line.strip().split(' % ')[1] for line in file.readlines()] for model_file in model_files: print(model_file) if model_file in processed_files: print(f'Skipping {model_file}, already processed.') continue if model_file in failed_models_files: print(f'Skipping {model_file}, it is failed model.') continue try: file_number = int(model_file[:3]) except ValueError: print(f"Error extracting the first three digits from {model_file}. Skipping.") continue counter = file_number current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') model_file_with_time = f'{current_time} % {model_file}' with open(failed_models_files_path, 'a') as failed_file: failed_file.write(model_file_with_time + '\n') file_path = os.path.join(folder_path, model_file) bpy.ops.import_mesh.stl(filepath=file_path) model_filename = os.path.splitext(os.path.basename(model_file))[0] imported_object = bpy.context.selected_objects[0] bpy.ops.object.select_all(action='DESELECT') imported_object.select_set(True) working_object = bpy.context.active_object bpyscene = bpy.context.scene tri_mesh_path = os.path.join(workplace_dir_path, "assets", "model.obj") bpy.ops.export_scene.obj(filepath=tri_mesh_path, use_selection=True, axis_forward='Y', axis_up='Z', use_edges=False, use_animation=False, use_materials=False, use_uvs=False, use_normals=False, use_mesh_modifiers=False, use_nurbs=False, use_smooth_groups=False, use_vertex_groups=False, use_blen_objects=False, use_smooth_groups_bitflags=False) import dapy_t3d_surface_hole sample_distance = 2.0*hole_radius+hole_distance hole_factor = 2.0*hole_radius / sample_distance try: os.chdir(executable_dir_path) if isbridge_arg == "桥一" or isbridge_arg == "桥二": if number_id == True: mesh_with_hole = dapy_t3d_surface_hole.GenerateSurfaceHoles(hole_height, hole_factor,use_honeycomb_type, sample_distance, texture_style,use_sharp_edge,angle_of_se,area_threshold,boundary_margin,counter,False,True) else: mesh_with_hole = dapy_t3d_surface_hole.GenerateSurfaceHoles(hole_height, hole_factor,use_honeycomb_type, sample_distance, texture_style,use_sharp_edge,angle_of_se,area_threshold,boundary_margin,0,False,True) else: if number_id == True: mesh_with_hole = dapy_t3d_surface_hole.GenerateSurfaceHoles(hole_height, hole_factor,use_honeycomb_type, sample_distance, texture_style,use_sharp_edge,angle_of_se,area_threshold,boundary_margin,counter,False,False) else: mesh_with_hole = dapy_t3d_surface_hole.GenerateSurfaceHoles(hole_height, hole_factor,use_honeycomb_type, sample_distance, texture_style,use_sharp_edge,angle_of_se,area_threshold,boundary_margin,0,False,False) except Exception as e: print({'ERROR'}, f"Failed to run GenerateSurfaceHoles: {str(e)}") continue working_object.hide_set(True) new_mesh = bpy.data.meshes.new("mesh-" + working_object.name + "-hole") new_mesh.from_pydata(mesh_with_hole.mat_coordinates.tolist(), [], mesh_with_hole.mat_faces.tolist()) new_mesh.update() new_object = bpy.data.objects.new(working_object.name + "-hole", new_mesh) export_filename = f"{counter}_{model_filename}.stl" bpy.context.collection.objects.link(new_object) bpy.context.view_layer.objects.active = new_object new_object.select_set(True) export_path=workplace_dir_path+"/results/"+export_filename bpy.ops.export_mesh.stl(filepath=export_path, use_selection=True, axis_forward='Y', axis_up='Z') bpy.data.objects.remove(imported_object) bpy.data.objects.remove(new_object, do_unlink=True) with open(failed_models_files_path, 'r') as file: lines = file.readlines() with open(failed_models_files_path, 'w') as file: for line in lines: saved_model_file = line.strip().split(' % ')[1] if saved_model_file != model_file: file.write(line) with open(processed_files_path, 'a') as file: file.write(model_file + '\n') with open(counter_path, 'w') as counter_file: counter_file.write(str(counter)) with open(processed_files_path, 'w') as file: file.write('') with open(counter_path, 'w') as file: file.write('') # if save == True: # with open(recent_parameter_file_path, 'w') as param_file: # param_file.write(f"Hole Height: {hole_height}\n") # param_file.write(f"Hole Radius: {hole_radius}\n") # param_file.write(f"Use Honeycomb Type: {use_honeycomb_type}\n") # param_file.write(f"Hole Distance: {hole_distance}\n") # param_file.write(f"Texture Style: {texture_style}\n") # param_file.write(f"Use_sharp_edge: {use_sharp_edge}\n") # param_file.write(f"Angle_of_se: {angle_of_se}\n") # param_file.write(f"Area_threshold: {area_threshold}\n") # param_file.write(f"Boundary_Margin: {boundary_margin}\n") # param_file.write(f"Number ID: {number_id}\n") # with open(parameter_file_path, 'w') as param_file: # param_file.write(f"Hole Height: {hole_height}\n") # param_file.write(f"Hole Radius: {hole_radius}\n") # param_file.write(f"Use Honeycomb Type: {use_honeycomb_type}\n") # param_file.write(f"Hole Distance: {hole_distance}\n") # param_file.write(f"Texture Style: {texture_style}\n") # param_file.write(f"Use_sharp_edge: {use_sharp_edge}\n") # param_file.write(f"Angle_of_se: {angle_of_se}\n") # param_file.write(f"Area_threshold: {area_threshold}\n") # param_file.write(f"Boundary_Margin: {boundary_margin}\n") # param_file.write(f"Number ID: {number_id}\n")