|
|
|
@ -9,12 +9,18 @@ import open3d as o3d |
|
|
|
import numpy as np |
|
|
|
import numpy as np |
|
|
|
from plyfile import PlyData, PlyElement |
|
|
|
from plyfile import PlyData, PlyElement |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
from config import print_factory_type_dir |
|
|
|
|
|
|
|
|
|
|
|
from general import mesh_tranform_to_pcd |
|
|
|
from general import mesh_tranform_to_pcd |
|
|
|
from general import need_upload_result |
|
|
|
from general import need_upload_result |
|
|
|
from general import read_mesh |
|
|
|
from general import read_mesh |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
from compute_print_net import get_models_bbox |
|
|
|
from compute_print_net import arrange_models_on_platform |
|
|
|
from compute_print_net import arrange_models_on_platform |
|
|
|
|
|
|
|
from compute_print_net import Platform |
|
|
|
|
|
|
|
from compute_print_net import down_sample |
|
|
|
from compute_print_net import compute_bbox_all |
|
|
|
from compute_print_net import compute_bbox_all |
|
|
|
|
|
|
|
from compute_print_net import compute_bbox_all_ext |
|
|
|
|
|
|
|
|
|
|
|
def make_bbox_for_print(base_original_obj_dir,dict_bad,dict_origin,is_downsample): |
|
|
|
def make_bbox_for_print(base_original_obj_dir,dict_bad,dict_origin,is_downsample): |
|
|
|
"""获取需要的盒子大小""" |
|
|
|
"""获取需要的盒子大小""" |
|
|
|
@ -81,6 +87,7 @@ def get_pcd_by_matrix(dict_mesh_obj,dict_total_matrix,dict_ply_name): |
|
|
|
|
|
|
|
|
|
|
|
return dict_pcd_fix |
|
|
|
return dict_pcd_fix |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def ply_print_layout_platform(dict_pcd_fix,dict_pcd_fix2,machine_size,dict_total_matrix,all_models): |
|
|
|
def ply_print_layout_platform(dict_pcd_fix,dict_pcd_fix2,machine_size,dict_total_matrix,all_models): |
|
|
|
"""根据排版结果移动点云到指定位置""" |
|
|
|
"""根据排版结果移动点云到指定位置""" |
|
|
|
# placed_models,unplaced_models = get_models_box_size(dict_fix,machine_size) |
|
|
|
# placed_models,unplaced_models = get_models_box_size(dict_fix,machine_size) |
|
|
|
@ -137,6 +144,32 @@ def ply_print_layout_platform(dict_pcd_fix,dict_pcd_fix2,machine_size,dict_total |
|
|
|
|
|
|
|
|
|
|
|
return placed_models |
|
|
|
return placed_models |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_models_bbox_net(dict_pcd_fix): |
|
|
|
|
|
|
|
return get_models_bbox(dict_pcd_fix) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
""" |
|
|
|
|
|
|
|
def get_models_box_size(dict_fix,machine_size): |
|
|
|
|
|
|
|
#获取排版的盒子大小 |
|
|
|
|
|
|
|
models = [] |
|
|
|
|
|
|
|
for ply_file in dict_fix: |
|
|
|
|
|
|
|
bbox_with_text = ply_file.split("=") |
|
|
|
|
|
|
|
bbox_with = bbox_with_text[-1] |
|
|
|
|
|
|
|
split_text = bbox_with.replace(".ply","").split("+") |
|
|
|
|
|
|
|
extend_dist = 2 |
|
|
|
|
|
|
|
x_length = int(float(split_text[2])*100) + extend_dist |
|
|
|
|
|
|
|
y_length = int(float(split_text[0])*100) + extend_dist |
|
|
|
|
|
|
|
z_length = int(float(split_text[1])*100) + extend_dist |
|
|
|
|
|
|
|
#print("get_models_box_size",x_length,y_length,z_length) |
|
|
|
|
|
|
|
models.append({'name':ply_file,'dimensions':(int(x_length/100),int(z_length/100),int(y_length/100))}) |
|
|
|
|
|
|
|
print(models) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
platform = Platform(int(machine_size[0]), int(machine_size[1]), int(machine_size[2])) |
|
|
|
|
|
|
|
print("开始计算排序...") |
|
|
|
|
|
|
|
platform.arrange_models(models) |
|
|
|
|
|
|
|
platform.print_results() |
|
|
|
|
|
|
|
return platform.get_result() |
|
|
|
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
def compute_distance(pcd1, pcd2): |
|
|
|
def compute_distance(pcd1, pcd2): |
|
|
|
""" |
|
|
|
""" |
|
|
|
正确计算两个点云之间距离的函数。 |
|
|
|
正确计算两个点云之间距离的函数。 |
|
|
|
@ -154,6 +187,44 @@ def compute_distance(pcd1, pcd2): |
|
|
|
# return min_dist, mean_dist, distances |
|
|
|
# return min_dist, mean_dist, distances |
|
|
|
return min_dist |
|
|
|
return min_dist |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def compute_distance_x(pcd1, pcd2): |
|
|
|
|
|
|
|
points1 = np.asarray(pcd1.points)[:, 0] # 提取所有X坐标[3](@ref) |
|
|
|
|
|
|
|
points2 = np.asarray(pcd2.points)[:, 0] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
x_diff = np.abs(points1[:, np.newaxis] - points2) |
|
|
|
|
|
|
|
return np.min(x_diff) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def compute_distance_y(pcd1, pcd2): |
|
|
|
|
|
|
|
points1 = np.asarray(pcd1.points)[:, 1] # 提取所有Y坐标[3](@ref) |
|
|
|
|
|
|
|
points2 = np.asarray(pcd2.points)[:, 1] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
y_diff = np.abs(points1.reshape(-1, 1) - points2) |
|
|
|
|
|
|
|
return np.min(y_diff) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def check_collision_x(pcd_moving, static_pcds,collision_threshold): |
|
|
|
|
|
|
|
moving_points = np.asarray(pcd_moving.points) |
|
|
|
|
|
|
|
min_distance_to_x_axis = np.min(np.abs(moving_points[:, 1])) # Y 坐标即为与 X 轴的距离 |
|
|
|
|
|
|
|
#print(f"与 X 轴的最小距离: {min_distance_to_x_axis}") |
|
|
|
|
|
|
|
#print(f"与 Y 轴的最小距离: {min_distance_to_y_axis}") |
|
|
|
|
|
|
|
#print(f"pcd_moving{len(static_pcds)}") |
|
|
|
|
|
|
|
if min_distance_to_x_axis < collision_threshold: |
|
|
|
|
|
|
|
print(f"与 X 轴发生碰撞! 最小距离: {min_distance_to_x_axis}") |
|
|
|
|
|
|
|
return True |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return check_collision_all(pcd_moving, static_pcds,collision_threshold) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def check_collision_y(pcd_moving, static_pcds,collision_threshold): |
|
|
|
|
|
|
|
moving_points = np.asarray(pcd_moving.points) |
|
|
|
|
|
|
|
#print(f"与 X 轴的最小距离: {min_distance_to_x_axis}") |
|
|
|
|
|
|
|
min_distance_to_y_axis = np.min(np.abs(moving_points[:, 0])) # X 坐标即为与 Y 轴的距离 |
|
|
|
|
|
|
|
#print(f"与 Y 轴的最小距离: {min_distance_to_y_axis}") |
|
|
|
|
|
|
|
#print(f"pcd_moving{len(static_pcds)}") |
|
|
|
|
|
|
|
if min_distance_to_y_axis < collision_threshold: |
|
|
|
|
|
|
|
print(f"与 Y 轴发生碰撞! 最小距离: {min_distance_to_y_axis}") |
|
|
|
|
|
|
|
return True |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return check_collision_all(pcd_moving, static_pcds,collision_threshold) |
|
|
|
|
|
|
|
|
|
|
|
import numpy as np |
|
|
|
import numpy as np |
|
|
|
|
|
|
|
|
|
|
|
def compute_aabb(pcd): |
|
|
|
def compute_aabb(pcd): |
|
|
|
@ -278,6 +349,9 @@ def compact_mode_for_min_dis_json(placed_models,dict_unplaced,dict_bounds_fix,ma |
|
|
|
else: |
|
|
|
else: |
|
|
|
pcd_second.append(pcd) |
|
|
|
pcd_second.append(pcd) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# pcd_all.append(pcd_downsampled) |
|
|
|
|
|
|
|
# name_list.append(model['name']) |
|
|
|
|
|
|
|
# model_list.append(model) |
|
|
|
dict_name[pcd] = model['name'] |
|
|
|
dict_name[pcd] = model['name'] |
|
|
|
dict_model[pcd] = model |
|
|
|
dict_model[pcd] = model |
|
|
|
dx = model['dimensions'][0] |
|
|
|
dx = model['dimensions'][0] |
|
|
|
@ -300,6 +374,7 @@ def compact_mode_for_min_dis_json(placed_models,dict_unplaced,dict_bounds_fix,ma |
|
|
|
if max_delta_x < 10: |
|
|
|
if max_delta_x < 10: |
|
|
|
draw_down = False |
|
|
|
draw_down = False |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# for idx, pcd in enumerate(pcd_all): |
|
|
|
for idx, pcd in enumerate(pcd_first): |
|
|
|
for idx, pcd in enumerate(pcd_first): |
|
|
|
|
|
|
|
|
|
|
|
if dict_model[pcd]['first_line']: |
|
|
|
if dict_model[pcd]['first_line']: |
|
|
|
@ -926,6 +1001,15 @@ def compact_mode_for_min_dis_json(placed_models,dict_unplaced,dict_bounds_fix,ma |
|
|
|
#""" |
|
|
|
#""" |
|
|
|
|
|
|
|
|
|
|
|
last_pcd_processed.append(pcd) |
|
|
|
last_pcd_processed.append(pcd) |
|
|
|
|
|
|
|
""" |
|
|
|
|
|
|
|
print("is_x_top",is_x_top) |
|
|
|
|
|
|
|
if not is_x_top: |
|
|
|
|
|
|
|
last_pcd_processed.append(pcd) |
|
|
|
|
|
|
|
print("last_pcd_processed.append",name) |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
print("fail last_pcd_processed.append",name, is_x_top) |
|
|
|
|
|
|
|
""" |
|
|
|
|
|
|
|
# o3d.io.write_point_cloud(os.path.join(output_dir, name), pcd) |
|
|
|
|
|
|
|
|
|
|
|
dict_total_matrix[obj_name]= T_trans1 @ dict_total_matrix[obj_name] |
|
|
|
dict_total_matrix[obj_name]= T_trans1 @ dict_total_matrix[obj_name] |
|
|
|
|
|
|
|
|
|
|
|
@ -945,6 +1029,19 @@ def move_to_top_left(pcd, edge_x_min, edge_y_max): |
|
|
|
|
|
|
|
|
|
|
|
return T_transTemp |
|
|
|
return T_transTemp |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def move_to_bottom_left(pcd, edge_x_min, edge_y_min): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
points = np.asarray(pcd.points) |
|
|
|
|
|
|
|
min_x = np.min(points[:, 0]) |
|
|
|
|
|
|
|
min_y = np.min(points[:, 1]) |
|
|
|
|
|
|
|
tx = edge_x_min - min_x |
|
|
|
|
|
|
|
ty = edge_y_min - min_y |
|
|
|
|
|
|
|
pcd.translate((tx, ty, 0), relative=True) |
|
|
|
|
|
|
|
T_transTemp = np.eye(4) |
|
|
|
|
|
|
|
T_transTemp[:3, 3] = [tx, ty, 0] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return T_transTemp |
|
|
|
|
|
|
|
|
|
|
|
def move_to_bottom_right(pcd, edge_x_max, edge_y_min): |
|
|
|
def move_to_bottom_right(pcd, edge_x_max, edge_y_min): |
|
|
|
|
|
|
|
|
|
|
|
points = np.asarray(pcd.points) |
|
|
|
points = np.asarray(pcd.points) |
|
|
|
@ -969,8 +1066,229 @@ def get_axis_aligned_bbox(pcd): |
|
|
|
'z_max': np.max(points[:,2]) |
|
|
|
'z_max': np.max(points[:,2]) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def down_obj_data_to_ply(weight_fix_out_obj_dir,weight_fix_out_ply_dir): |
|
|
|
|
|
|
|
"""""" |
|
|
|
|
|
|
|
obj_file_list = [aa for aa in os.listdir(weight_fix_out_obj_dir) if aa.endswith(".obj")] |
|
|
|
|
|
|
|
for obj_name in obj_file_list: |
|
|
|
|
|
|
|
obj_path = os.path.join(weight_fix_out_obj_dir,obj_name) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mesh_obj = read_mesh(obj_path) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vertices = np.asarray(mesh_obj.vertices) |
|
|
|
|
|
|
|
pcd = o3d.geometry.PointCloud() |
|
|
|
|
|
|
|
pcd.points = o3d.utility.Vector3dVector(vertices) |
|
|
|
|
|
|
|
voxel_size = 3 # 设置体素的大小,决定下采样的密度 |
|
|
|
|
|
|
|
pcd_downsampled = down_sample(pcd, voxel_size) |
|
|
|
|
|
|
|
ply_out_path = os.path.join(weight_fix_out_ply_dir,obj_name.replace(".obj",".ply")) |
|
|
|
|
|
|
|
o3d.io.write_point_cloud(ply_out_path, pcd_downsampled) |
|
|
|
|
|
|
|
print(ply_out_path,"下采样完成。") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def compute_centroid_compact(pcd): |
|
|
|
|
|
|
|
points = np.asarray(pcd.points) |
|
|
|
|
|
|
|
centroid = np.mean(points, axis=0) |
|
|
|
|
|
|
|
return centroid |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def compute_base_point(pcd): |
|
|
|
|
|
|
|
points = np.asarray(pcd.points) |
|
|
|
|
|
|
|
x_center = np.mean(points[:, 0]) |
|
|
|
|
|
|
|
y_center = np.mean(points[:, 1]) |
|
|
|
|
|
|
|
min_z = np.min(points[:, 2]) |
|
|
|
|
|
|
|
return np.array([x_center, y_center, min_z]) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import copy |
|
|
|
|
|
|
|
def move_obj_to_compact_bounds(bounds_fix_out_dir,bounds_compact_out_dir,weight_fix_out_obj_dir,base_original_obj_dir,compact_obj_out_dir,dict_mesh_obj,dict_unplaced,placed_remove_dir,dict_bad,bad_dir,full_dir,dict_bounds_fix,dict_compact,dict_origin): |
|
|
|
|
|
|
|
"""""" |
|
|
|
|
|
|
|
# obj_file_list = [aa for aa in os.listdir(weight_fix_out_obj_dir) if aa.endswith(".obj")] |
|
|
|
|
|
|
|
obj_file_list = list(dict_mesh_obj.keys()) |
|
|
|
|
|
|
|
ply_path_dict = {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# meshes = [] |
|
|
|
|
|
|
|
# for ply_file_name in os.listdir(bounds_fix_out_dir): |
|
|
|
|
|
|
|
for ply_file_name in dict_bounds_fix: |
|
|
|
|
|
|
|
ply_dict_key = ply_file_name.split("=")[0] |
|
|
|
|
|
|
|
ply_path_dict[ply_dict_key] = ply_file_name |
|
|
|
|
|
|
|
for obj_name in obj_file_list: |
|
|
|
|
|
|
|
obj_path = os.path.join(weight_fix_out_obj_dir, obj_name) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# mesh_obj = read_mesh(obj_path, False) |
|
|
|
|
|
|
|
mesh_obj = dict_mesh_obj[obj_name] |
|
|
|
|
|
|
|
# mesh_obj = dict_origin[obj_origin_path] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
original_obj_pid_dir = base_original_obj_dir |
|
|
|
|
|
|
|
obj_origin_path = os.path.join(original_obj_pid_dir, obj_name) |
|
|
|
|
|
|
|
obj_origin = dict_origin[obj_origin_path] |
|
|
|
|
|
|
|
# obj_origin = copy.deepcopy(dict_origin[obj_origin_path]) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ply_name_pid = obj_name.replace(".obj","") |
|
|
|
|
|
|
|
# ply_name = ply_path_dict[ply_name_pid] |
|
|
|
|
|
|
|
ply_name = ply_path_dict.get(ply_name_pid,None) |
|
|
|
|
|
|
|
print(ply_name_pid,ply_name) |
|
|
|
|
|
|
|
if ply_name is None: |
|
|
|
|
|
|
|
continue |
|
|
|
|
|
|
|
print("move_obj_to_compact_bounds",ply_name,len(dict_unplaced)) |
|
|
|
|
|
|
|
if not ply_name or ply_name in dict_unplaced: |
|
|
|
|
|
|
|
print("unplaced",ply_name) |
|
|
|
|
|
|
|
continue |
|
|
|
|
|
|
|
ply_fix_path = os.path.join(bounds_fix_out_dir,ply_name) |
|
|
|
|
|
|
|
ply_compact_path = os.path.join(bounds_compact_out_dir, ply_name) |
|
|
|
|
|
|
|
# pcd_fix = o3d.io.read_point_cloud(ply_fix_path) |
|
|
|
|
|
|
|
pcd_fix = dict_bounds_fix[ply_name] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vertices = np.asarray(obj_origin.vertices) |
|
|
|
|
|
|
|
pcd_origin = o3d.geometry.PointCloud() |
|
|
|
|
|
|
|
pcd_origin.points = o3d.utility.Vector3dVector(vertices) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# pcd_compact = o3d.io.read_point_cloud(ply_compact_path) |
|
|
|
|
|
|
|
pcd_compact = dict_compact[ply_name] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
centroid_fix = compute_centroid_compact(pcd_fix) |
|
|
|
|
|
|
|
centroid_compact = compute_centroid_compact(pcd_compact) |
|
|
|
|
|
|
|
centroid_origin = compute_centroid_compact(pcd_origin) |
|
|
|
|
|
|
|
displacement = centroid_compact - centroid_fix |
|
|
|
|
|
|
|
# displacement = centroid_compact - centroid_origin |
|
|
|
|
|
|
|
vertices = np.asarray(mesh_obj.vertices) |
|
|
|
|
|
|
|
vertices_translated = vertices + displacement # 将位移应用到每个顶点 |
|
|
|
|
|
|
|
mesh_obj.vertices = o3d.utility.Vector3dVector(vertices_translated) # 更新网格顶点 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
obj_pid = obj_name.split("_P")[0] |
|
|
|
|
|
|
|
#compact_obj_pid_out_dir = os.path.join(compact_obj_out_dir,obj_pid) |
|
|
|
|
|
|
|
compact_obj_pid_out_dir= compact_obj_out_dir |
|
|
|
|
|
|
|
if not os.path.exists(compact_obj_pid_out_dir): |
|
|
|
|
|
|
|
os.makedirs(compact_obj_pid_out_dir) |
|
|
|
|
|
|
|
obj_path_compact = os.path.join(compact_obj_pid_out_dir,obj_name) |
|
|
|
|
|
|
|
mesh_obj.compute_vertex_normals() |
|
|
|
|
|
|
|
o3d.io.write_triangle_mesh(obj_path_compact, mesh_obj,write_triangle_uvs=True) |
|
|
|
|
|
|
|
print(obj_path_compact, "移动后obj保存完成", displacement) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# meshes.append(mesh_obj) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#original_obj_pid_dir = os.path.join(base_original_obj_dir,obj_pid) |
|
|
|
|
|
|
|
original_obj_pid_dir = base_original_obj_dir |
|
|
|
|
|
|
|
for mtl in os.listdir(compact_obj_pid_out_dir): |
|
|
|
|
|
|
|
if mtl.endswith(".mtl"): |
|
|
|
|
|
|
|
if obj_pid in mtl: |
|
|
|
|
|
|
|
mtl_path = os.path.join(compact_obj_pid_out_dir,mtl) |
|
|
|
|
|
|
|
os.remove(mtl_path) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mtl_name = None |
|
|
|
|
|
|
|
tex_name = None |
|
|
|
|
|
|
|
for file_name in os.listdir(original_obj_pid_dir): |
|
|
|
|
|
|
|
if file_name.endswith(".mtl"): |
|
|
|
|
|
|
|
if obj_pid in file_name: |
|
|
|
|
|
|
|
mtl_name = file_name |
|
|
|
|
|
|
|
if file_name.endswith(".jpg"): |
|
|
|
|
|
|
|
if obj_pid in file_name: |
|
|
|
|
|
|
|
tex_name = file_name |
|
|
|
|
|
|
|
if file_name.endswith(".png"): |
|
|
|
|
|
|
|
if obj_pid in file_name: |
|
|
|
|
|
|
|
tex_name = file_name |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for file in os.listdir(original_obj_pid_dir): |
|
|
|
|
|
|
|
#print(f"file{file}") |
|
|
|
|
|
|
|
if file.endswith(".obj"): |
|
|
|
|
|
|
|
continue |
|
|
|
|
|
|
|
if obj_pid not in file: |
|
|
|
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
origin_path = os.path.join(original_obj_pid_dir,file) |
|
|
|
|
|
|
|
dis_path = os.path.join(compact_obj_pid_out_dir,file) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if os.path.isfile(origin_path): |
|
|
|
|
|
|
|
#print(f'origin_path{origin_path}') |
|
|
|
|
|
|
|
#print(f'dis_path{dis_path}') |
|
|
|
|
|
|
|
shutil.copy(origin_path,dis_path) |
|
|
|
|
|
|
|
time.sleep(1) |
|
|
|
|
|
|
|
#print("-"*50) |
|
|
|
|
|
|
|
base_origin_obj_path = os.path.join(original_obj_pid_dir,obj_name) |
|
|
|
|
|
|
|
#print(f"base_origin_obj_path{base_origin_obj_path}") |
|
|
|
|
|
|
|
#print(f"obj_path_compact{obj_path_compact}") |
|
|
|
|
|
|
|
update_obj_file(base_origin_obj_path, obj_path_compact) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
placed_remove_obj_path = os.path.join(placed_remove_dir, obj_name) |
|
|
|
|
|
|
|
shutil.copy(base_origin_obj_path,placed_remove_obj_path) |
|
|
|
|
|
|
|
os.remove(base_origin_obj_path) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
exist_obj_any = False |
|
|
|
|
|
|
|
exist_obj = False |
|
|
|
|
|
|
|
delete_mtl = False |
|
|
|
|
|
|
|
for file_name in os.listdir(original_obj_pid_dir): |
|
|
|
|
|
|
|
if file_name.endswith(".obj"): |
|
|
|
|
|
|
|
if obj_pid in file_name: |
|
|
|
|
|
|
|
exist_obj = True |
|
|
|
|
|
|
|
exist_obj_any = True |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not exist_obj_any: |
|
|
|
|
|
|
|
delete_mtl = True |
|
|
|
|
|
|
|
if not exist_obj: |
|
|
|
|
|
|
|
delete_mtl = True |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if delete_mtl: |
|
|
|
|
|
|
|
print("delete_mtl",mtl_name,tex_name) |
|
|
|
|
|
|
|
if mtl_name!=None: |
|
|
|
|
|
|
|
base_origin_mtl_path = os.path.join(original_obj_pid_dir,mtl_name) |
|
|
|
|
|
|
|
placed_remove_mtl_path = os.path.join(placed_remove_dir, mtl_name) |
|
|
|
|
|
|
|
shutil.copy(base_origin_mtl_path,placed_remove_mtl_path) |
|
|
|
|
|
|
|
os.remove(base_origin_mtl_path) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if tex_name!=None: |
|
|
|
|
|
|
|
base_origin_tex_path = os.path.join(original_obj_pid_dir,tex_name) |
|
|
|
|
|
|
|
placed_remove_tex_path = os.path.join(placed_remove_dir, tex_name) |
|
|
|
|
|
|
|
shutil.copy(base_origin_tex_path,placed_remove_tex_path) |
|
|
|
|
|
|
|
os.remove(base_origin_tex_path) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print(f"排版错误模型数量::{len(dict_bad)}") |
|
|
|
|
|
|
|
for obj_name in dict_bad: |
|
|
|
|
|
|
|
print("--错误模型名:", obj_name) |
|
|
|
|
|
|
|
process_obj_files(original_obj_pid_dir,bad_dir,obj_name) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print(f"排版剩余模型数量::{len(dict_unplaced)}") |
|
|
|
|
|
|
|
for ply_file_name in dict_unplaced: |
|
|
|
|
|
|
|
obj_name = ply_file_name.split("=")[0]+".obj" |
|
|
|
|
|
|
|
print("--剩余模型名:", obj_name) |
|
|
|
|
|
|
|
process_obj_files(original_obj_pid_dir,full_dir,obj_name) |
|
|
|
|
|
|
|
|
|
|
|
import json |
|
|
|
import json |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def extract_angles(R): |
|
|
|
|
|
|
|
# 提取绕X、Y、Z轴的旋转角度(弧度) |
|
|
|
|
|
|
|
rx_rad = np.arctan2(R[2, 1], R[2, 2]) # X轴旋转 |
|
|
|
|
|
|
|
ry_rad = np.arcsin(-R[2, 0]) # Y轴旋转 |
|
|
|
|
|
|
|
rz_rad = np.arctan2(R[1, 0], R[0, 0]) # Z轴旋转 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 将弧度转换为角度(度数) |
|
|
|
|
|
|
|
rx_deg = np.degrees(rx_rad) |
|
|
|
|
|
|
|
ry_deg = np.degrees(ry_rad) |
|
|
|
|
|
|
|
rz_deg = np.degrees(rz_rad) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return rx_deg, ry_deg, rz_deg |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def compute_mesh_center(vertices): |
|
|
|
|
|
|
|
""" |
|
|
|
|
|
|
|
计算网格质心 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
参数: |
|
|
|
|
|
|
|
vertices: 顶点坐标数组,形状为(N, 3)的NumPy数组或列表 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
返回: |
|
|
|
|
|
|
|
centroid: 质心坐标的NumPy数组 [x, y, z] |
|
|
|
|
|
|
|
""" |
|
|
|
|
|
|
|
if len(vertices) == 0: |
|
|
|
|
|
|
|
raise ValueError("顶点数组不能为空") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
n = len(vertices) # 顶点数量 |
|
|
|
|
|
|
|
# 初始化坐标累加器 |
|
|
|
|
|
|
|
sum_x, sum_y, sum_z = 0.0, 0.0, 0.0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 遍历所有顶点累加坐标值 |
|
|
|
|
|
|
|
for vertex in vertices: |
|
|
|
|
|
|
|
sum_x += vertex[0] |
|
|
|
|
|
|
|
sum_y += vertex[1] |
|
|
|
|
|
|
|
sum_z += vertex[2] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 计算各坐标轴的平均值 |
|
|
|
|
|
|
|
centroid = np.array([sum_x / n, sum_y / n, sum_z / n]) |
|
|
|
|
|
|
|
return centroid |
|
|
|
|
|
|
|
|
|
|
|
import re |
|
|
|
import re |
|
|
|
def extract_numbers_from_filename(filename): |
|
|
|
def extract_numbers_from_filename(filename): |
|
|
|
""" |
|
|
|
""" |
|
|
|
@ -995,7 +1313,7 @@ def extract_numbers_from_filename(filename): |
|
|
|
|
|
|
|
|
|
|
|
import requests |
|
|
|
import requests |
|
|
|
def move_obj_to_compact_bounds_json(base_original_obj_dir,dict_mesh_obj,dict_unplaced,dict_bad,bad_dir,full_dir,dict_bounds_fix, |
|
|
|
def move_obj_to_compact_bounds_json(base_original_obj_dir,dict_mesh_obj,dict_unplaced,dict_bad,bad_dir,full_dir,dict_bounds_fix, |
|
|
|
dict_total_matrix,batch_id, print_start_time,selected_machine,selected_mode,version): |
|
|
|
dict_total_matrix,save_mesh,batch_id, print_start_time,selected_machine,selected_mode,version): |
|
|
|
"""生成3D打印布局的JSON数据并保存为3DPrintLayout.json""" |
|
|
|
"""生成3D打印布局的JSON数据并保存为3DPrintLayout.json""" |
|
|
|
# 创建符合3DPrintLayout规范的JSON数据结构 |
|
|
|
# 创建符合3DPrintLayout规范的JSON数据结构 |
|
|
|
layout_data = { |
|
|
|
layout_data = { |
|
|
|
@ -1111,6 +1429,10 @@ def move_obj_to_compact_bounds_json(base_original_obj_dir,dict_mesh_obj,dict_unp |
|
|
|
print("--剩余模型名:", obj_name) |
|
|
|
print("--剩余模型名:", obj_name) |
|
|
|
process_obj_files(original_obj_pid_dir,full_dir,obj_name) |
|
|
|
process_obj_files(original_obj_pid_dir,full_dir,obj_name) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if save_mesh: |
|
|
|
|
|
|
|
cache_type_setting_dir=f"{base_original_obj_dir}/arrange" |
|
|
|
|
|
|
|
transform_save_o3d(layout_data, original_obj_pid_dir, cache_type_setting_dir) |
|
|
|
|
|
|
|
|
|
|
|
return send_layout_data |
|
|
|
return send_layout_data |
|
|
|
|
|
|
|
|
|
|
|
def process_obj_files(original_obj_pid_dir,placed_remove_dir,obj_name): |
|
|
|
def process_obj_files(original_obj_pid_dir,placed_remove_dir,obj_name): |
|
|
|
@ -1172,6 +1494,31 @@ def process_obj_files(original_obj_pid_dir,placed_remove_dir,obj_name): |
|
|
|
shutil.copy(base_origin_tex_path, placed_remove_tex_path) |
|
|
|
shutil.copy(base_origin_tex_path, placed_remove_tex_path) |
|
|
|
os.remove(base_origin_tex_path) |
|
|
|
os.remove(base_origin_tex_path) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def update_obj_file(original_obj_path,compact_obj_path): |
|
|
|
|
|
|
|
"""""" |
|
|
|
|
|
|
|
with open(original_obj_path, "r") as f: |
|
|
|
|
|
|
|
lines_original = f.readlines() |
|
|
|
|
|
|
|
mtllib_name = None |
|
|
|
|
|
|
|
mat_name = None |
|
|
|
|
|
|
|
for line in lines_original: |
|
|
|
|
|
|
|
if line.startswith("mtllib"): |
|
|
|
|
|
|
|
mtllib_name = line.split(" ")[1] |
|
|
|
|
|
|
|
elif line.startswith("usemtl"): |
|
|
|
|
|
|
|
mat_name = line.split(" ")[1] |
|
|
|
|
|
|
|
if mtllib_name and mat_name: |
|
|
|
|
|
|
|
break |
|
|
|
|
|
|
|
with open(compact_obj_path, "r") as f: |
|
|
|
|
|
|
|
lines = f.readlines() |
|
|
|
|
|
|
|
new_lines = [] |
|
|
|
|
|
|
|
for line2 in lines: |
|
|
|
|
|
|
|
if line2.startswith("mtllib"): |
|
|
|
|
|
|
|
line2 = f"mtllib {mtllib_name}\n" # 替换为原始 MTL 文件路径 |
|
|
|
|
|
|
|
elif line2.startswith("usemtl"): |
|
|
|
|
|
|
|
line2 = f"usemtl {mat_name}\n" # 替换为原始贴图路径 |
|
|
|
|
|
|
|
new_lines.append(line2) |
|
|
|
|
|
|
|
with open(compact_obj_path, "w") as f: |
|
|
|
|
|
|
|
f.writelines(new_lines) |
|
|
|
|
|
|
|
|
|
|
|
def pass_for_min_dis(placed_models, dict_unplaced, dict_bounds_fix): |
|
|
|
def pass_for_min_dis(placed_models, dict_unplaced, dict_bounds_fix): |
|
|
|
|
|
|
|
|
|
|
|
pcd_all = [] |
|
|
|
pcd_all = [] |
|
|
|
@ -1199,3 +1546,23 @@ def pass_for_min_dis(placed_models, dict_unplaced, dict_bounds_fix): |
|
|
|
name = name_list[idx] |
|
|
|
name = name_list[idx] |
|
|
|
print("fail to place (x=0)", name_list[idx], y, dy) |
|
|
|
print("fail to place (x=0)", name_list[idx], y, dy) |
|
|
|
dict_unplaced[name]=name |
|
|
|
dict_unplaced[name]=name |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
|
|
|
|
|
out_dir = "/data/datasets_20t/type_setting_test_data/" |
|
|
|
|
|
|
|
weight_fix_out_obj_dir = f"{out_dir}/print_weight_fix_data_obj" |
|
|
|
|
|
|
|
weight_fix_out_ply_dir = f"{out_dir}/data/datasets_20t/type_ssetting_test_data/print_weight_fix_data_ply" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
base_original_obj_dir=f"{print_factory_type_dir}/8/" |
|
|
|
|
|
|
|
if not os.path.exists(weight_fix_out_ply_dir): |
|
|
|
|
|
|
|
os.makedirs(weight_fix_out_ply_dir) |
|
|
|
|
|
|
|
bounds_fix_out_dir = f"{out_dir}/print_bounds_fix_data" |
|
|
|
|
|
|
|
bounds_compact_out_dir = f"{out_dir}/print_bounds_compact_data" |
|
|
|
|
|
|
|
compact_obj_out_dir = f"{out_dir}//print_compact_obj" |
|
|
|
|
|
|
|
if not os.path.exists(bounds_fix_out_dir): |
|
|
|
|
|
|
|
os.mkdir(bounds_fix_out_dir) |
|
|
|
|
|
|
|
if not os.path.exists(bounds_compact_out_dir): |
|
|
|
|
|
|
|
os.makedirs(bounds_compact_out_dir) |
|
|
|
|
|
|
|
if not os.path.exists(compact_obj_out_dir): |
|
|
|
|
|
|
|
os.makedirs(compact_obj_out_dir) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
move_obj_to_compact_bounds(bounds_fix_out_dir,bounds_compact_out_dir,weight_fix_out_obj_dir,base_original_obj_dir,compact_obj_out_dir) |