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.
221 lines
9.9 KiB
221 lines
9.9 KiB
|
2 weeks ago
|
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")
|