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.
1204 lines
46 KiB
1204 lines
46 KiB
import os |
|
import json |
|
import requests |
|
import shutil |
|
import time |
|
import random |
|
import matplotlib.pyplot as plt |
|
import open3d as o3d |
|
import numpy as np |
|
from plyfile import PlyData, PlyElement |
|
|
|
from general import mesh_tranform_to_pcd |
|
from general import need_upload_result |
|
from general import extend_dist_min_collision |
|
|
|
from compute_print_net import arrange_models_on_platform |
|
from compute_print_net import compute_bbox_all |
|
|
|
from compute_print_net_out import read_mesh |
|
|
|
def make_bbox_for_print(base_original_obj_dir,dict_bad,dict_origin,is_downsample): |
|
"""获取需要的盒子大小""" |
|
start_time = time.time() |
|
|
|
obj_id_list = [aa.split(".o")[0] for aa in os.listdir(base_original_obj_dir) if aa.endswith(".obj")] |
|
obj_id_list = obj_id_list |
|
|
|
dict_mesh_obj = {} |
|
index = 0 |
|
for pid_t_y in obj_id_list: |
|
|
|
start_time1 = time.time() |
|
obj_name = pid_t_y+".obj" |
|
obj_path = os.path.join(base_original_obj_dir,obj_name) |
|
mesh_obj = read_mesh(obj_path) |
|
|
|
if mesh_obj is None: |
|
dict_bad[obj_name]=obj_name |
|
# 记录错误文件 |
|
error_log = os.path.join(base_original_obj_dir, "error_files.txt") |
|
with open(error_log, 'a') as f: |
|
f.write(f"{obj_path}\n") |
|
print(f"Skipping invalid file: {obj_path}") |
|
continue |
|
|
|
dict_origin[obj_name] = mesh_obj |
|
dict_mesh_obj[obj_name] = mesh_obj |
|
|
|
print(f"make_bbox_for_print {index} {obj_name} time={time.time()-start_time1}") |
|
|
|
index = index + 1 |
|
|
|
print(f"make_bbox_for_print total_time={time.time()-start_time}") |
|
|
|
# dict_total_matrix,all_models = compute_bbox_all_ext(base_original_obj_dir, is_downsample) |
|
dict_total_matrix,all_models = compute_bbox_all(dict_mesh_obj, is_downsample) |
|
return get_dict_pcd(dict_mesh_obj,dict_total_matrix,all_models) |
|
|
|
def get_dict_pcd(dict_mesh_obj,dict_total_matrix,all_models): |
|
dict_pcd_fix = {} |
|
|
|
dict_ply_name = {} |
|
for model in all_models: |
|
ply_name = model['name'] |
|
# print(f"get_dict_pcd {ply_name.split("=")[0]}.obj, {ply_name}") |
|
dict_ply_name[f"{ply_name.split("=")[0]}.obj"] = ply_name |
|
|
|
dict_pcd_fix = get_pcd_by_matrix(dict_mesh_obj,dict_total_matrix,dict_ply_name) |
|
|
|
return dict_total_matrix,all_models,dict_pcd_fix |
|
|
|
def get_pcd_by_matrix(dict_mesh_obj,dict_total_matrix,dict_ply_name): |
|
|
|
dict_pcd_fix= {} |
|
|
|
for key, value in dict_mesh_obj.items(): |
|
obj_name = key |
|
mesh_obj = value |
|
pcd_fix = mesh_tranform_to_pcd(mesh_obj, dict_total_matrix[obj_name]) |
|
dict_pcd_fix[dict_ply_name[obj_name]] = pcd_fix |
|
|
|
dict_mesh_obj.clear() |
|
del dict_mesh_obj |
|
|
|
return dict_pcd_fix |
|
|
|
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) |
|
|
|
# 1. 获取模型bbox尺寸 |
|
# all_models = get_models_bbox_net(dict_pcd_fix) |
|
print("all_models", all_models) |
|
|
|
# 2. 模型排版布局 |
|
print("开始计算排序...") |
|
placed_models, unplaced_models = arrange_models_on_platform(all_models, machine_size) |
|
|
|
if len(placed_models) ==0: |
|
print("放进打印盒的数量为0") |
|
return |
|
|
|
# 3. 根据排版结果移动点云和模型(原有逻辑不变) |
|
for model in placed_models: |
|
print(f" - {model['name']} at {model['position']} with dimensions {model['dimensions']}") |
|
ply_file_name = model['name'] |
|
move_position = model['position'] |
|
# print("要读取的点云数据路径",ply_origin_path) |
|
pcd = dict_pcd_fix[ply_file_name] |
|
# print("dict_fix read",ply_file_name,move_position) |
|
|
|
points = np.asarray(pcd.points) |
|
min_bound = np.min(points, axis=0) # 获取点云的最小边界 |
|
max_bound = np.max(points, axis=0) |
|
min_bound[1] = max(min_bound[1], 0) |
|
bbox_center = (min_bound + max_bound) / 2 # 计算包围盒的中心点 |
|
bbox_extent = (max_bound - min_bound) |
|
new_bbox = o3d.geometry.OrientedBoundingBox(center=bbox_center, |
|
R=np.eye(3), # 旋转矩阵,默认没有旋转 |
|
extent=bbox_extent) |
|
x = move_position[0] |
|
y = move_position[1] |
|
z = move_position[2] |
|
# move_position = np.array([x,y,z])/100 |
|
move_position = np.array([x, y, z]) |
|
# translation_vector = -move_position |
|
translation_vector = move_position |
|
pcd.translate(translation_vector) |
|
new_bbox.translate(translation_vector) |
|
obj_name = ply_file_name.split("=")[0]+".obj" |
|
|
|
T_trans1 = np.eye(4) |
|
T_trans1[:3, 3] = translation_vector |
|
dict_total_matrix[obj_name]= T_trans1 @ dict_total_matrix[obj_name] |
|
|
|
new_bbox_lines = o3d.geometry.LineSet.create_from_oriented_bounding_box(new_bbox) |
|
new_bbox_lines.paint_uniform_color([1, 0, 0]) # 红色 |
|
|
|
dict_pcd_fix2[ply_file_name] = pcd |
|
|
|
return placed_models |
|
|
|
def compute_distance(pcd1, pcd2): |
|
""" |
|
正确计算两个点云之间距离的函数。 |
|
返回两个点云之间最近距离的平均值、最小值以及全部距离数组。 |
|
""" |
|
# 使用Open3D内置的高效方法计算距离 |
|
# 计算pcd1中每个点到pcd2中最近点的距离 |
|
distances = pcd1.compute_point_cloud_distance(pcd2) |
|
distances = np.asarray(distances) |
|
|
|
# 计算有意义的统计量 |
|
min_dist = np.min(distances) # 所有点中的最小距离 |
|
mean_dist = np.mean(distances) # 距离的平均值 |
|
|
|
# return min_dist, mean_dist, distances |
|
return min_dist |
|
|
|
import numpy as np |
|
|
|
def compute_aabb(pcd): |
|
"""计算点云的AABB包围盒""" |
|
points = np.asarray(pcd.points) |
|
return { |
|
'min': np.min(points, axis=0), |
|
'max': np.max(points, axis=0) |
|
} |
|
|
|
def aabb_intersect(a, b, collision_threshold): |
|
"""判断两个AABB包围盒是否相交[2,8](@ref)""" |
|
return (a['max'][0] > b['min'][0] - collision_threshold and a['min'][0] < b['max'][0] + collision_threshold) and \ |
|
(a['max'][1] > b['min'][1] - collision_threshold and a['min'][1] < b['max'][1] + collision_threshold) and \ |
|
(a['max'][2] > b['min'][2] - collision_threshold and a['min'][2] < b['max'][2] + collision_threshold) |
|
|
|
def check_collision_all(pcd_moving, static_pcds, collision_threshold): |
|
# 预计算移动点云AABB |
|
moving_aabb = compute_aabb(pcd_moving) |
|
|
|
for static_pcd in static_pcds: |
|
if static_pcd == pcd_moving: |
|
continue |
|
# 第一阶段:AABB快速排除[1,6](@ref) |
|
static_aabb = compute_aabb(static_pcd) |
|
# print("len(static_pcd.points)=",len(static_pcd.points),"len(moving_aabb.points)=",len(pcd_moving.points)) |
|
if not aabb_intersect(moving_aabb, static_aabb, collision_threshold): |
|
continue # 包围盒无交集,直接跳过 |
|
|
|
if not aabb_intersect(moving_aabb, static_aabb, collision_threshold): |
|
return False |
|
|
|
# 第二阶段:精确点距离计算 |
|
min_distance = compute_distance(pcd_moving, static_pcd) |
|
# print("check_collision_all",min_distance) |
|
if min_distance < collision_threshold: |
|
return True |
|
|
|
return False |
|
|
|
def compute_centroid(pcd): |
|
# 获取点云的所有点 |
|
points = np.asarray(pcd.points) |
|
# 计算质心(只考虑 X 和 Y 坐标) |
|
centroid = np.mean(points[:, :2], axis=0) # 只考虑前两个维度(X 和 Y) |
|
return centroid |
|
|
|
def compute_distance_to_origin(centroid): |
|
# 计算质心距离原点的距离(只考虑 X 和 Y 坐标) |
|
return np.linalg.norm(centroid) # 计算 X 和 Y 的欧几里得距离 |
|
|
|
def compute_closest_distance_to_origin(pcd): |
|
# 获取点云的所有点坐标 |
|
points = np.asarray(pcd.points) |
|
# 计算每个点到原点的距离 |
|
distances = np.linalg.norm(points, axis=1) |
|
# 返回最小距离 |
|
return np.min(distances) |
|
|
|
def sort_ply_files_by_closest_distance(folder_path): |
|
ply_files = [f for f in os.listdir(folder_path) if f.endswith('.ply')] |
|
distances = [] |
|
|
|
for ply_file in ply_files: |
|
# 读取点云数据 |
|
pcd = o3d.io.read_point_cloud(os.path.join(folder_path, ply_file)) |
|
# 计算离原点最近的点的距离 |
|
closest_distance = compute_closest_distance_to_origin(pcd) |
|
distances.append((ply_file, closest_distance)) |
|
|
|
# 按照最近点的距离排序(由近到远) |
|
distances.sort(key=lambda x: x[1]) |
|
|
|
# 返回排序后的文件列表 |
|
sorted_files = [item[0] for item in distances] |
|
print("Sorted files:", sorted_files) |
|
return sorted_files |
|
|
|
def compact_mode_for_min_dis_json(placed_models,dict_unplaced,dict_bounds_fix,machine_size,dict_total_matrix): |
|
|
|
y_step=1 |
|
x_step=1 |
|
delta = 10 |
|
|
|
edge_x_min=0 + 4 |
|
edge_y_min=0 + 4 |
|
edge_x_max=machine_size[0] |
|
edge_y_max=machine_size[1] |
|
|
|
collision_threshold=2 |
|
move_last = True |
|
|
|
pcd_all = [] |
|
pcd_processed = [] |
|
pcd_processed_x_top = [] |
|
pcd_processed_no_x_top = [] |
|
# name_list = [] |
|
dict_name = {} |
|
# model_list = [] |
|
dict_model = {} |
|
last_pcd_list = [] |
|
# last_name_list = [] |
|
dic_last_name = {} |
|
last_pcd_processed = [] |
|
max_x = machine_size[0] |
|
min_x = 0 |
|
max_delta_x = 0 |
|
x_top_delta = 1 |
|
border_delta = 4 |
|
|
|
pcd_first= [] |
|
pcd_second= [] |
|
|
|
index = 0 |
|
for model in placed_models: |
|
pcd = dict_bounds_fix[model['name']] |
|
|
|
pcd_all.append(pcd) |
|
|
|
if (get_axis_aligned_bbox(pcd)['y_min']>edge_y_max*0.3 or True): |
|
pcd_first.append(pcd) |
|
else: |
|
pcd_second.append(pcd) |
|
|
|
dict_name[pcd] = model['name'] |
|
dict_model[pcd] = model |
|
dx = model['dimensions'][0] |
|
x = model['position'][0] |
|
|
|
if (x>=edge_x_max-x_top_delta) : |
|
pcd_processed_x_top.append(pcd) |
|
print("pcd_processed_x_top", model['name']) |
|
if dx > max_x: |
|
max_x = dx |
|
if dx < min_x: |
|
min_x = dx |
|
max_delta_x = max_x - min_x |
|
|
|
index += 1 |
|
|
|
# print("compact_mode_for_min_dis1_json", model, max_delta_x) |
|
|
|
draw_down = False |
|
if max_delta_x < 10: |
|
draw_down = False |
|
|
|
for idx, pcd in enumerate(pcd_first): |
|
|
|
if dict_model[pcd]['first_line']: |
|
pcd_processed.append(pcd) |
|
last_pcd_processed.append(pcd) |
|
continue |
|
|
|
x = dict_model[pcd]['position'][0] |
|
y = dict_model[pcd]['position'][1] |
|
dx = dict_model[pcd]['dimensions'][0] |
|
print("compact_mode", dict_name[pcd], dx, x) |
|
|
|
ply_file_name = dict_name[pcd] |
|
obj_name = ply_file_name.split("=")[0]+".obj" |
|
|
|
T_trans1 = np.eye(4) |
|
|
|
dist_x = 50 |
|
dist_y = 20 |
|
is_x_top = False |
|
if x - 10 < edge_x_min: |
|
dist_x = x - edge_x_min |
|
if y - 10 < edge_y_min: |
|
dist_y = y - edge_y_min |
|
if (x<edge_x_max-x_top_delta) : |
|
if draw_down: |
|
pcd.translate([-dist_x, -dist_y, 0]) |
|
|
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [-dist_x, -dist_y, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
# print("draw_down",obj_name) |
|
|
|
# pcd_processed_curr = pcd_processed_x_top |
|
pcd_processed_curr = pcd_processed |
|
else: |
|
is_x_top = True |
|
if check_collision_all(pcd, pcd_processed_no_x_top, extend_dist_min_collision): |
|
name = ply_file_name |
|
print("fail to place (x=0)", ply_file_name, dx) |
|
dict_unplaced[name]=name |
|
pcd_processed_curr = pcd_processed |
|
x_step_big = x_step * 2 |
|
y_step_big = y_step * 2 |
|
collision_threshold_big = collision_threshold + 10 |
|
y_init_big = 5 |
|
if dx > 80: |
|
y_init_big = 10 |
|
x_init_big = y_init_big - 1 |
|
|
|
if check_collision_all(pcd, pcd_processed_curr, extend_dist_min_collision): |
|
while True: |
|
step = 25 |
|
pcd.translate([0, -step, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, -step, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
# pcd.translate([-step, 0, 0]) |
|
# T_transTemp[:3, 3] = [-step, 0, 0] |
|
# T_trans1 = T_transTemp @ T_trans1 |
|
|
|
if not check_collision_all(pcd, pcd_processed_curr, collision_threshold_big): |
|
break |
|
|
|
""" |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
if bbox['y_max'] >= edge_y_max - collision_threshold: |
|
pcd.translate([-x_step_big, -y_step_big, 0]) |
|
print("compact_mode y_max", idx, bbox['y_max'], edge_y_max - collision_threshold_big) |
|
break |
|
if bbox['x_max'] >= edge_x_max - collision_threshold: |
|
pcd.translate([-x_step_big, -y_step_big, 0]) |
|
print("compact_mode x_max", idx, bbox['x_max'], edge_x_max - collision_threshold_big) |
|
break |
|
if check_collision_all(pcd, pcd_processed_curr,collision_threshold_big): |
|
pcd.translate([-x_step_big, -y_step_big, 0]) |
|
break |
|
pcd.translate([x_step_big, y_step_big, 0]) |
|
#""" |
|
#""" |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
# print("x_max",bbox['x_max'],bbox['x_min'],bbox['y_max'],bbox['y_min']) |
|
if bbox['y_min'] <= edge_y_min + collision_threshold_big and False: |
|
pcd.translate([0, y_step_big, 0]) |
|
break |
|
if bbox['y_max'] >= edge_y_max - collision_threshold_big: |
|
pcd.translate([0, -y_step_big, 0]) |
|
|
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, -y_step_big, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
|
|
break |
|
if check_collision_all(pcd, pcd_processed_curr,collision_threshold_big+y_init_big): #5 |
|
pcd.translate([0, -y_step_big, 0]) |
|
|
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, -y_step_big, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
|
|
break |
|
pcd.translate([0, y_step_big, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, y_step_big, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
if bbox['x_min'] <= edge_x_min + collision_threshold_big and False: |
|
pcd.translate([x_step_big, 0, 0]) |
|
break |
|
if bbox['x_max'] >= edge_x_max - collision_threshold_big: |
|
pcd.translate([-x_step_big, 0, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [-x_step_big, 0, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
break |
|
if check_collision_all(pcd, pcd_processed_curr,collision_threshold_big+x_init_big): |
|
pcd.translate([-x_step_big, 0, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [-x_step_big, 0, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
break |
|
pcd.translate([x_step_big, 0, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [x_step_big, 0, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
#""" |
|
#""" |
|
collision_threshold_init = collision_threshold+6 |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
if bbox['y_min'] <= edge_y_min + collision_threshold_init and False: |
|
pcd.translate([0, y_step, 0]) |
|
break |
|
# if bbox['y_max'] >= edge_y_max - collision_threshold_init: |
|
if bbox['y_max'] >= edge_y_max - border_delta: |
|
pcd.translate([0, -y_step, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, -y_step, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
break |
|
if check_collision_all(pcd, pcd_processed_curr,collision_threshold_init+1): #5 |
|
pcd.translate([0, -y_step, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, -y_step, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
break |
|
pcd.translate([0, y_step, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, y_step, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
#""" |
|
#""" |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
if bbox['x_min'] <= edge_x_min + collision_threshold_init and False: |
|
pcd.translate([x_step, 0, 0]) |
|
break |
|
# if bbox['x_max'] >= edge_x_max - collision_threshold_init: |
|
if bbox['x_max'] >= edge_x_max - border_delta: |
|
# print("1pcd.translate([-x_step, 0, 0])",name_list[idx]) |
|
pcd.translate([-x_step, 0, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [-x_step, 0, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
break |
|
if check_collision_all(pcd, pcd_processed_curr,collision_threshold_init): |
|
# print("2pcd.translate([-x_step, 0, 0])",name_list[idx]) |
|
pcd.translate([-x_step, 0, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [-x_step, 0, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
break |
|
pcd.translate([x_step, 0, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [x_step, 0, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
#""" |
|
#""" |
|
collision_threshold_init = collision_threshold+2 |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
if bbox['y_min'] <= edge_y_min + collision_threshold_init and False: |
|
pcd.translate([0, y_step, 0]) |
|
break |
|
if bbox['y_max'] >= edge_y_max - collision_threshold_init: |
|
pcd.translate([0, -y_step, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, -y_step, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
break |
|
if check_collision_all(pcd, pcd_processed_curr,collision_threshold_init+1): #5 |
|
pcd.translate([0, -y_step, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, -y_step, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
break |
|
pcd.translate([0, y_step, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, y_step, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
if bbox['x_min'] <= edge_x_min + collision_threshold_init and False: |
|
pcd.translate([x_step, 0, 0]) |
|
break |
|
if bbox['x_max'] >= edge_x_max - collision_threshold_init: |
|
pcd.translate([-x_step, 0, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [-x_step, 0, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
break |
|
if check_collision_all(pcd, pcd_processed_curr,collision_threshold_init): |
|
pcd.translate([-x_step, 0, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [-x_step, 0, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
break |
|
pcd.translate([x_step, 0, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [x_step, 0, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
# place again |
|
collision_threshold_init = collision_threshold+1 |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
if bbox['y_min'] <= edge_y_min + collision_threshold_init and False: |
|
pcd.translate([0, y_step, 0]) |
|
break |
|
if bbox['y_max'] >= edge_y_max - collision_threshold_init: |
|
pcd.translate([0, -y_step, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, -y_step, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
break |
|
if check_collision_all(pcd, pcd_processed_curr,collision_threshold_init): #5 |
|
pcd.translate([0, -y_step, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, -y_step, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
break |
|
pcd.translate([0, y_step, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, y_step, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
#""" |
|
pcd_processed.append(pcd) |
|
pcd_processed_x_top.append(pcd) |
|
if not is_x_top: |
|
pcd_processed_no_x_top.append(pcd) |
|
|
|
cross_border = False |
|
bbox = get_axis_aligned_bbox(pcd) |
|
if bbox['x_min'] <= edge_x_min + 1 or bbox['y_min'] <= edge_y_min + 1: |
|
cross_border = True |
|
print("coross_border",ply_file_name) |
|
|
|
if cross_border: |
|
pcd_second.append(pcd) |
|
dic_last_name[pcd] = ply_file_name |
|
else: |
|
last_pcd_processed.append(pcd) |
|
|
|
dict_total_matrix[obj_name]= T_trans1 @ dict_total_matrix[obj_name] |
|
|
|
volumes = [] |
|
# for idx, pcd in enumerate(last_pcd_list): |
|
for idx, pcd in enumerate(pcd_second): |
|
bbox = get_axis_aligned_bbox(pcd) |
|
|
|
x_length = bbox['x_max'] - bbox['x_min'] |
|
y_length = bbox['y_max'] - bbox['y_min'] |
|
z_length = bbox['z_max'] - bbox['z_min'] |
|
volume = x_length * y_length * z_length |
|
volumes.append(volume) |
|
|
|
# print("last_pcd_list", len(last_pcd_list), len(last_pcd_list), len(last_pcd_processed), len(pcd_all)) |
|
# sorted_indices = np.argsort(volumes)[::-1] |
|
# last_pcd_list2 = [last_pcd_list[i] for i in sorted_indices] |
|
# print("last_pcd_list2", len(last_pcd_list2)) |
|
|
|
print(f"pcd_second : len(pcd_first)={len(pcd_first)}, len(pcd_second)={len(pcd_second)}, len(last_pcd_processed)={len(last_pcd_processed)}, len(pcd_all)={len(pcd_all)}") |
|
sorted_indices = np.argsort(volumes)[::-1] |
|
pcd_second2 = [pcd_second[i] for i in sorted_indices] |
|
# print("pcd_second2 len", len(pcd_second2)) |
|
|
|
for idx, pcd in enumerate(pcd_second2): |
|
|
|
ply_file_name = dict_name[pcd] |
|
obj_name = ply_file_name.split("=")[0]+".obj" |
|
|
|
# print("pcd_second2", obj_name) |
|
|
|
T_trans1 = np.eye(4) |
|
|
|
points = np.asarray(pcd.points) |
|
min_x = np.min(points[:, 0]) |
|
max_y = np.max(points[:, 1]) # 当前最大y值 |
|
|
|
tx = edge_x_min - min_x |
|
ty = -max_y - 0.001 |
|
|
|
T_transTemp = move_to_top_left(pcd, edge_x_min+2, edge_y_max-2) |
|
|
|
T_trans1 = T_transTemp @ T_trans1 |
|
|
|
name = dict_name[pcd] |
|
# print("pcd_second2",name,"tx",tx,"ty",ty) |
|
succ_move = True |
|
y_accum = 0 |
|
finish_move2 = False |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
collision_threshold_init = collision_threshold+1 |
|
if bbox['y_min'] <= edge_y_min + collision_threshold_init: |
|
print("succ_move False",name,bbox['y_min'],edge_y_min + collision_threshold_init) |
|
succ_move = False |
|
finish_move2 = True |
|
|
|
if (finish_move2): |
|
break |
|
else: |
|
if not check_collision_all(pcd, last_pcd_processed,collision_threshold_init): |
|
print("succ_move1",name,bbox['x_max'],bbox['y_max'],len(last_pcd_processed)) |
|
break |
|
|
|
pcd.translate([0, -y_step, 0]) |
|
|
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, -y_step, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
|
|
y_accum += y_step |
|
|
|
if succ_move: |
|
#print("succ_move2", name) |
|
""" |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
if bbox['x_max'] >= edge_x_max - collision_threshold_big: |
|
pcd.translate([-x_step_big, 0, 0]) |
|
break |
|
if check_collision_all(pcd, last_pcd_processed,collision_threshold_big): |
|
pcd.translate([-x_step_big, 0, 0]) |
|
break |
|
pcd.translate([x_step_big, 0, 0]) |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
if bbox['y_max'] >= edge_y_max - collision_threshold: |
|
pcd.translate([0, -y_step, 0]) |
|
break |
|
if check_collision_all(pcd, last_pcd_processed,collision_threshold+1): #5 |
|
pcd.translate([0, -y_step, 0]) |
|
break |
|
pcd.translate([0, y_step, 0]) |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
if bbox['x_max'] >= edge_x_max - collision_threshold: |
|
pcd.translate([-x_step, 0, 0]) |
|
break |
|
if check_collision_all(pcd, last_pcd_processed,collision_threshold): |
|
pcd.translate([-x_step, 0, 0]) |
|
break |
|
pcd.translate([x_step, 0, 0]) |
|
#""" |
|
|
|
#""" |
|
x_accu = 0 |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
collision_threshold_init = collision_threshold+2 |
|
#print("Move x_step_big", name, bbox['y_max'], bbox['x_max']) |
|
if bbox['x_max'] >= edge_x_max - collision_threshold_init: |
|
pcd.translate([-x_accu, 0, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [-x_accu, 0, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
break |
|
if not check_collision_all(pcd, last_pcd_processed,collision_threshold_init): |
|
x_accu = 0 |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
collision_threshold_init = collision_threshold+1 |
|
if bbox['y_max'] >= edge_y_max - collision_threshold_init: |
|
pcd.translate([0, -y_step_big, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, -y_step_big, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
#print("Move y_max", name, bbox['y_max'], bbox['x_max']) |
|
break |
|
if check_collision_all(pcd, last_pcd_processed,collision_threshold_init): |
|
pcd.translate([0, -y_step_big, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, -y_step_big, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
#print("Move y_max2", name, bbox['y_max'], bbox['x_max']) |
|
break |
|
pcd.translate([0, y_step_big, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, y_step_big, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
#print("Move y_step_big", name, bbox['y_max'], bbox['x_max']) |
|
else: |
|
n = 1 |
|
|
|
x_accu += x_step_big |
|
pcd.translate([x_step_big, 0, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [x_step_big, 0, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
#""" |
|
else: |
|
# T_transTemp = move_to_bottom_left(pcd, edge_x_min, edge_y_min) |
|
T_transTemp = move_to_bottom_right(pcd, edge_x_max, edge_y_min) |
|
T_trans1 = T_transTemp @ T_trans1 |
|
|
|
print("last place", name) |
|
|
|
""" |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
collision_threshold_init = collision_threshold+10 |
|
if bbox['x_max'] >= edge_x_max - collision_threshold_init: |
|
print("fail to place",name) |
|
break |
|
if not check_collision_all(pcd, last_pcd_processed,collision_threshold_init): |
|
print("last place2",name) |
|
break |
|
pcd.translate([x_step_big, 0, 0]) |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
collision_threshold_init = collision_threshold+3 |
|
if bbox['y_max'] >= edge_y_max - collision_threshold_init: |
|
pcd.translate([0, -y_step_big, 0]) |
|
print("last place3",name) |
|
break |
|
if check_collision_all(pcd, last_pcd_processed,collision_threshold_init): #5 |
|
pcd.translate([0, -y_step_big, 0]) |
|
print("last place4",name,collision_threshold_init,len(last_pcd_processed)) |
|
break |
|
pcd.translate([0, y_step_big, 0]) |
|
print("last place41",y_step_big) |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
if bbox['y_max'] >= edge_y_max - collision_threshold: |
|
pcd.translate([0, -y_step, 0]) |
|
print("last place5",name) |
|
break |
|
if check_collision_all(pcd, last_pcd_processed,collision_threshold+1): #5 |
|
pcd.translate([0, -y_step, 0]) |
|
print("last place6",name) |
|
break |
|
pcd.translate([0, y_step, 0]) |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
if bbox['x_max'] >= edge_x_max - collision_threshold: |
|
pcd.translate([-x_step, 0, 0]) |
|
print("last place7",name) |
|
break |
|
if check_collision_all(pcd, last_pcd_processed,collision_threshold): |
|
pcd.translate([-x_step, 0, 0]) |
|
print("last place8",name) |
|
break |
|
pcd.translate([x_step, 0, 0]) |
|
#""" |
|
|
|
""" |
|
can_place_last = False |
|
x_accu = 0 |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
collision_threshold_init = collision_threshold+2 |
|
if bbox['x_max'] >= edge_x_max - collision_threshold_init: |
|
if not can_place_last: |
|
print("fail to place",name) |
|
dict_unplaced[name]=name |
|
else: |
|
pcd.translate([-x_accu, 0, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [-x_accu, 0, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
break |
|
if not check_collision_all(pcd, last_pcd_processed,collision_threshold_init): |
|
can_place_last = True |
|
x_accu = 0 |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
collision_threshold_init = collision_threshold+1 |
|
if bbox['y_max'] >= edge_y_max - collision_threshold_init: |
|
pcd.translate([0, -y_step_big, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, -y_step_big, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
break |
|
if check_collision_all(pcd, last_pcd_processed,collision_threshold_init): |
|
pcd.translate([0, -y_step_big, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, -y_step_big, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
break |
|
pcd.translate([0, y_step_big, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, y_step_big, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
#print("Move2 y_step_big", name) |
|
else: |
|
n = 1 |
|
|
|
x_accu += x_step_big |
|
pcd.translate([x_step_big, 0, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [x_step_big, 0, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
#""" |
|
|
|
#""" |
|
can_place_last = False |
|
x_accu = 0 |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
collision_threshold_init = collision_threshold+2 |
|
if bbox['x_max'] >= edge_x_max - collision_threshold_init: |
|
if not can_place_last: |
|
print("fail to place",name) |
|
dict_unplaced[name]=name |
|
else: |
|
pcd.translate([-x_accu, 0, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [-x_accu, 0, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
break |
|
if not check_collision_all(pcd, last_pcd_processed,collision_threshold_init): |
|
can_place_last = True |
|
x_accu = 0 |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
collision_threshold_init = collision_threshold+1 |
|
if bbox['y_max'] >= edge_y_max - collision_threshold_init: |
|
pcd.translate([0, -y_step_big, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, -y_step_big, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
break |
|
if check_collision_all(pcd, last_pcd_processed,collision_threshold_init): |
|
pcd.translate([0, -y_step_big, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, -y_step_big, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
break |
|
pcd.translate([0, y_step_big, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, y_step_big, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
#print("Move2 y_step_big", name) |
|
else: |
|
n = 1 |
|
|
|
x_accu += x_step_big |
|
pcd.translate([x_step_big, 0, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [x_step_big, 0, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
#""" |
|
|
|
""" |
|
can_place_last = False |
|
x_accu = 0 |
|
place_first = True |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
collision_threshold_init = collision_threshold+2 |
|
if bbox['x_min'] <= edge_x_min + collision_threshold_init: |
|
if not can_place_last: |
|
print("fail to place",name) |
|
dict_unplaced[name]=name |
|
else: |
|
pcd.translate([+x_accu, 0, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [+x_accu, 0, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
place_first = True |
|
print("place_first True") |
|
break |
|
can_break = False |
|
if not check_collision_all(pcd, last_pcd_processed,collision_threshold_init): |
|
can_place_last = True |
|
x_accu = 0 |
|
while True: |
|
bbox = get_axis_aligned_bbox(pcd) |
|
collision_threshold_init = collision_threshold+1 |
|
if bbox['y_max'] >= edge_y_max - collision_threshold_init: |
|
pcd.translate([0, -y_step_big, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, -y_step_big, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
can_break = True |
|
break |
|
if check_collision_all(pcd, last_pcd_processed,collision_threshold_init): |
|
pcd.translate([0, -y_step_big, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, -y_step_big, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
if place_first: |
|
can_break = True |
|
break |
|
pcd.translate([0, y_step_big, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [0, y_step_big, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
#print("Move2 y_step_big", name) |
|
else: |
|
n = 1 |
|
|
|
if can_break: |
|
break |
|
|
|
x_accu += x_step_big |
|
pcd.translate([-x_step_big, 0, 0]) |
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [-x_step_big, 0, 0] |
|
T_trans1 = T_transTemp @ T_trans1 |
|
#""" |
|
|
|
last_pcd_processed.append(pcd) |
|
|
|
dict_total_matrix[obj_name]= T_trans1 @ dict_total_matrix[obj_name] |
|
|
|
def move_to_top_left(pcd, edge_x_min, edge_y_max): |
|
points = np.asarray(pcd.points) |
|
min_x = np.min(points[:, 0]) |
|
max_y = np.max(points[:, 1]) # 当前最大y值 |
|
|
|
tx = edge_x_min - min_x |
|
# ty = -max_y - 0.001 |
|
ty = edge_y_max - max_y |
|
|
|
T_transTemp = np.eye(4) |
|
T_transTemp[:3, 3] = [tx, ty, 0] |
|
|
|
pcd.translate((tx, ty, 0), relative=True) |
|
|
|
return T_transTemp |
|
|
|
def move_to_bottom_right(pcd, edge_x_max, edge_y_min): |
|
|
|
points = np.asarray(pcd.points) |
|
max_x = np.min(points[:, 0]) |
|
min_y = np.min(points[:, 1]) |
|
tx = edge_x_max - max_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 get_axis_aligned_bbox(pcd): |
|
points = np.asarray(pcd.points) |
|
return { |
|
'x_min': np.min(points[:,0]), |
|
'x_max': np.max(points[:,0]), |
|
'y_min': np.min(points[:,1]), |
|
'y_max': np.max(points[:,1]), |
|
'z_min': np.min(points[:,2]), |
|
'z_max': np.max(points[:,2]) |
|
} |
|
|
|
import json |
|
|
|
import re |
|
def extract_numbers_from_filename(filename): |
|
""" |
|
从文件名中提取893333, 338908, 105043和x后面的数字 |
|
""" |
|
# 提取前两个下划线前的数字 |
|
first_part = re.findall(r'^(\d+)_(\d+)', filename) |
|
if first_part: |
|
num1, num2 = first_part[0] |
|
else: |
|
num1, num2 = None, None |
|
|
|
# 提取P后面的数字 |
|
p_number = re.findall(r'P(\d+)', filename) |
|
num3 = p_number[0] if p_number else None |
|
|
|
# 提取x后面的数字 |
|
x_number = re.findall(r'x(\d+)', filename) |
|
num4 = x_number[0] if x_number else None |
|
|
|
return [num for num in [num1, num2, num3, num4] if num is not None] |
|
|
|
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, |
|
dict_total_matrix,batch_id, print_start_time,selected_machine,selected_mode,version): |
|
"""生成3D打印布局的JSON数据并保存为3DPrintLayout.json""" |
|
# 创建符合3DPrintLayout规范的JSON数据结构 |
|
layout_data = { |
|
"summary": { |
|
"version": version, |
|
"homo_matrix": "Homogeneous Matrix", |
|
"precision": 6, |
|
"selected_machine": selected_machine, |
|
"selected_mode": selected_mode |
|
}, |
|
"models": [] |
|
} |
|
|
|
send_layout_data={ |
|
"data": [], |
|
"pre_complate_time": 0.0, |
|
"pre_batch_id": batch_id, |
|
"type_setting_start_time": print_start_time |
|
} |
|
|
|
print(f"need_upload_result={need_upload_result()}") |
|
is_need_upload_result = need_upload_result() |
|
|
|
obj_file_list = list(dict_mesh_obj.keys()) |
|
ply_path_dict = {} |
|
|
|
original_obj_pid_dir = base_original_obj_dir |
|
|
|
# 构建PLY文件路径映射 |
|
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: |
|
ply_name_pid = obj_name.replace(".obj", "") |
|
ply_name = ply_path_dict.get(ply_name_pid, None) |
|
|
|
if is_need_upload_result: |
|
result = extract_numbers_from_filename(ply_name) |
|
|
|
if not ply_name or ply_name in dict_unplaced: |
|
|
|
if is_need_upload_result: |
|
print_id = result[2] |
|
order_id = result[0] |
|
status = 0 |
|
pid = result[1] |
|
counts = result[3] |
|
send_layout_data["data"].append({ |
|
"print_id": print_id, |
|
"order_id": order_id, |
|
"status": status, |
|
"pid":pid, |
|
"counts":counts}) |
|
|
|
continue # 跳过未放置的模型 |
|
|
|
total_matrix = dict_total_matrix[obj_name] |
|
|
|
flattened = total_matrix.flatten()[:16] |
|
|
|
matrix_4x4 = [ |
|
[round(flattened[i], 6) for i in range(0, 4)], # 第1行 |
|
[round(flattened[i], 6) for i in range(4, 8)], # 第2行 |
|
[round(flattened[i], 6) for i in range(8, 12)], # 第3行 |
|
[round(flattened[i], 6) for i in range(12, 16)] # 第4行 |
|
] |
|
|
|
layout_data["models"].append({ |
|
"file_name": obj_name, |
|
"transform": { |
|
"homo_matrix": matrix_4x4 |
|
} |
|
}) |
|
|
|
if is_need_upload_result: |
|
print_id = result[2] |
|
order_id = result[0] |
|
status = 1 |
|
pid = result[1] |
|
counts = result[3] |
|
send_layout_data["data"].append({ |
|
"print_id": print_id, |
|
"order_id": order_id, |
|
"status": status, |
|
"pid":pid, |
|
"counts":counts}) |
|
|
|
# 保存JSON文件 |
|
# json_path = os.path.join(base_original_obj_dir, "3DPrintLayout.json") |
|
json_path = os.path.join(base_original_obj_dir, f"{batch_id}.json") |
|
|
|
import re |
|
json_str = json.dumps(layout_data, ensure_ascii=False, indent=2) |
|
json_str = re.sub( |
|
r'\[\s*(-?[\d.]+),\s+(-?[\d.]+),\s+(-?[\d.]+),\s+(-?[\d.]+)\s*\]', |
|
r'[\1,\2,\3,\4]', |
|
json_str |
|
) |
|
with open(json_path, "w", encoding='utf-8') as f: |
|
f.write(json_str) |
|
|
|
print(f"3D打印布局已保存至: {json_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) |
|
|
|
return send_layout_data |
|
|
|
def process_obj_files(original_obj_pid_dir,placed_remove_dir,obj_name): |
|
""" |
|
处理OBJ文件及其相关资源文件的复制、更新和清理 |
|
|
|
参数: |
|
original_obj_pid_dir: 包含原始OBJ文件的目录 |
|
placed_remove_dir: 用于存放移除文件的目录 |
|
obj_name: 要处理的OBJ文件名 |
|
""" |
|
|
|
base_origin_obj_path = os.path.join(original_obj_pid_dir,obj_name) |
|
|
|
# 从obj_name中提取PID(产品ID) |
|
obj_pid = obj_name.split("_P")[0] |
|
|
|
# 查找相关的MTL和纹理文件 |
|
mtl_name = None |
|
tex_name = None |
|
|
|
for file_name in os.listdir(original_obj_pid_dir): |
|
|
|
if file_name.endswith(".mtl") and obj_pid in file_name: |
|
mtl_name = file_name |
|
|
|
if (file_name.endswith(".jpg") or file_name.endswith(".png")) and obj_pid in file_name: |
|
tex_name = file_name |
|
|
|
# 将原始OBJ文件移动到移除目录 |
|
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) |
|
|
|
# 检查目录中是否还有其他OBJ文件 |
|
exist_obj_any = False |
|
exist_obj = False |
|
|
|
for file_name in os.listdir(original_obj_pid_dir): |
|
if file_name.endswith(".obj"): |
|
exist_obj_any = True |
|
if obj_pid in file_name: |
|
exist_obj = True |
|
|
|
# 确定是否需要删除MTL和纹理文件 |
|
delete_mtl = not exist_obj_any or not exist_obj |
|
|
|
# 如果确定要删除,移动MTL和纹理文件 |
|
if delete_mtl: |
|
if mtl_name: |
|
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: |
|
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) |
|
|
|
def pass_for_min_dis(placed_models, dict_unplaced, dict_bounds_fix): |
|
|
|
pcd_all = [] |
|
name_list = [] |
|
model_list = [] |
|
|
|
for model in placed_models: |
|
# pcd = o3d.io.read_point_cloud(ply_origin_path) |
|
pcd = dict_bounds_fix[model['name']] |
|
pcd_all.append(pcd) |
|
name_list.append(model['name']) |
|
model_list.append(model) |
|
|
|
for idx, pcd in enumerate(pcd_all): |
|
y = model_list[idx]['position'][1] |
|
dx = model_list[idx]['dimensions'][0] |
|
dy = model_list[idx]['dimensions'][1] |
|
# print("pass_for_min_dis", name_list[idx], y, dy) |
|
|
|
delta_y = 20 |
|
# safe_y = y - delta_y |
|
safe_y = y - dy - delta_y |
|
min_y = 0 |
|
if safe_y < min_y: |
|
name = name_list[idx] |
|
print("fail to place (x=0)", name_list[idx], y, dy) |
|
dict_unplaced[name]=name
|
|
|