|
|
|
|
@ -4,11 +4,14 @@ import json
@@ -4,11 +4,14 @@ import json
|
|
|
|
|
import os |
|
|
|
|
from PIL import Image |
|
|
|
|
import argparse |
|
|
|
|
import gc |
|
|
|
|
|
|
|
|
|
from config import print_factory_type_dir |
|
|
|
|
from general import mesh_transform_by_matrix |
|
|
|
|
from general import read_mesh |
|
|
|
|
from general import get_blank_path |
|
|
|
|
|
|
|
|
|
def load_and_transform_models(base_path, dict_origin, blank_path, json_name): |
|
|
|
|
def load_and_transform_models(base_path, dict_origin, json_name): |
|
|
|
|
|
|
|
|
|
meshes = [] # 存储所有变换后的网格 |
|
|
|
|
|
|
|
|
|
@ -30,8 +33,13 @@ def load_and_transform_models(base_path, dict_origin, blank_path, json_name):
@@ -30,8 +33,13 @@ def load_and_transform_models(base_path, dict_origin, blank_path, json_name):
|
|
|
|
|
print(f"读取JSON文件失败: {e}") |
|
|
|
|
return [] |
|
|
|
|
|
|
|
|
|
print(f"选择机型={data.get('summary')['selected_machine']}") |
|
|
|
|
selected_machine = data.get('summary')['selected_machine'] |
|
|
|
|
print(f"选择机型={selected_machine}") |
|
|
|
|
|
|
|
|
|
is_small_machine = True if selected_machine=="小机型" else False |
|
|
|
|
blank_path = get_blank_path(is_small_machine) |
|
|
|
|
|
|
|
|
|
index = 0 |
|
|
|
|
# 处理每个模型 |
|
|
|
|
for model in data.get('models', []): |
|
|
|
|
obj_name = model.get('file_name', '') |
|
|
|
|
@ -54,11 +62,11 @@ def load_and_transform_models(base_path, dict_origin, blank_path, json_name):
@@ -54,11 +62,11 @@ def load_and_transform_models(base_path, dict_origin, blank_path, json_name):
|
|
|
|
|
key = obj_path |
|
|
|
|
if key in dict_origin: |
|
|
|
|
# print("key in dict_origin") |
|
|
|
|
mesh = dict_origin[key] |
|
|
|
|
mesh_obj = dict_origin[key] |
|
|
|
|
else : |
|
|
|
|
# print("key not in dict_origin") |
|
|
|
|
mesh = o3d.io.read_triangle_mesh(obj_path, enable_post_processing=True) |
|
|
|
|
if not mesh.has_vertices(): |
|
|
|
|
mesh_obj = read_mesh(obj_path,True) |
|
|
|
|
if not mesh_obj.has_vertices(): |
|
|
|
|
print(f"警告: 网格无有效顶点 - {obj_path}") |
|
|
|
|
continue |
|
|
|
|
except Exception as e: |
|
|
|
|
@ -71,22 +79,31 @@ def load_and_transform_models(base_path, dict_origin, blank_path, json_name):
@@ -71,22 +79,31 @@ def load_and_transform_models(base_path, dict_origin, blank_path, json_name):
|
|
|
|
|
reconstructed_matrix = np.array(homo_matrix, dtype=np.float64) |
|
|
|
|
|
|
|
|
|
# 手动变换顶点 |
|
|
|
|
original_vertices = np.asarray(mesh.vertices) |
|
|
|
|
original_vertices = np.asarray(mesh_obj.vertices) |
|
|
|
|
transformed_vertices = mesh_transform_by_matrix(original_vertices, reconstructed_matrix) |
|
|
|
|
mesh.vertices = o3d.utility.Vector3dVector(transformed_vertices) |
|
|
|
|
mesh_obj.vertices = o3d.utility.Vector3dVector(transformed_vertices) |
|
|
|
|
|
|
|
|
|
del original_vertices, transformed_vertices, reconstructed_matrix |
|
|
|
|
|
|
|
|
|
# 添加到列表 |
|
|
|
|
meshes.append(mesh) |
|
|
|
|
print(f"已加载并变换: {os.path.basename(obj_path)}") |
|
|
|
|
meshes.append(mesh_obj) |
|
|
|
|
del mesh_obj |
|
|
|
|
|
|
|
|
|
gc.collect() |
|
|
|
|
|
|
|
|
|
print(f"已加载并变换: {index} {os.path.basename(obj_path)}") |
|
|
|
|
index = index + 1 |
|
|
|
|
|
|
|
|
|
#if (index > 100): |
|
|
|
|
# break |
|
|
|
|
|
|
|
|
|
add_plank = True |
|
|
|
|
if add_plank: |
|
|
|
|
# obj_path = os.path.join(blank_dir, "blank2.obj") |
|
|
|
|
obj_path = blank_path |
|
|
|
|
print("add_plank",obj_path) |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
mesh = o3d.io.read_triangle_mesh(obj_path, enable_post_processing=True) |
|
|
|
|
mesh = read_mesh(obj_path, True) |
|
|
|
|
if not mesh.has_vertices(): |
|
|
|
|
print(f"警告: 网格无有效顶点 - {obj_path}") |
|
|
|
|
except Exception as e: |
|
|
|
|
@ -130,9 +147,9 @@ def compute_mesh_center(vertices):
@@ -130,9 +147,9 @@ def compute_mesh_center(vertices):
|
|
|
|
|
centroid = np.array([sum_x / n, sum_y / n, sum_z / n]) |
|
|
|
|
return centroid |
|
|
|
|
|
|
|
|
|
def load_and_show(base_path, blank_dir, json_name="3DPrintLayout.json"): |
|
|
|
|
def load_and_show(base_path, json_name="3DPrintLayout.json"): |
|
|
|
|
# 加载并变换所有模型 |
|
|
|
|
transformed_meshes = load_and_transform_models(base_path, {}, blank_dir, json_name) |
|
|
|
|
transformed_meshes = load_and_transform_models(base_path, {}, json_name) |
|
|
|
|
|
|
|
|
|
if not transformed_meshes: |
|
|
|
|
print("没有加载到任何模型,请检查错误信息") |
|
|
|
|
@ -305,17 +322,13 @@ def set_orthographic_projection(view_control, ortho_scale=10.0):
@@ -305,17 +322,13 @@ def set_orthographic_projection(view_control, ortho_scale=10.0):
|
|
|
|
|
print(f"在配置 ViewControl 参数时出错: {e}") |
|
|
|
|
return False |
|
|
|
|
|
|
|
|
|
def set_orthographic(meshes, output_path, width=1920, height=1080, |
|
|
|
|
def set_orthographic(meshes, width=1920, height=1080, |
|
|
|
|
background_color=[1, 1, 1], camera_position=None, |
|
|
|
|
ortho_width=None, zoom=1.0): |
|
|
|
|
|
|
|
|
|
vis = o3d.visualization.Visualizer() |
|
|
|
|
vis.create_window(width=width, height=height, visible=False) |
|
|
|
|
|
|
|
|
|
# 添加几何体 |
|
|
|
|
for mesh in meshes: |
|
|
|
|
vis.add_geometry(mesh) |
|
|
|
|
|
|
|
|
|
# 设置渲染选项 |
|
|
|
|
render_opt = vis.get_render_option() |
|
|
|
|
render_opt.background_color = np.asarray(background_color) |
|
|
|
|
@ -323,12 +336,12 @@ def set_orthographic(meshes, output_path, width=1920, height=1080,
@@ -323,12 +336,12 @@ def set_orthographic(meshes, output_path, width=1920, height=1080,
|
|
|
|
|
render_opt.mesh_show_wireframe = False |
|
|
|
|
render_opt.point_size = 3.0 |
|
|
|
|
|
|
|
|
|
# 视角控制 |
|
|
|
|
view_control = vis.get_view_control() |
|
|
|
|
|
|
|
|
|
# 计算所有网格的合并边界框,用于自适应设置投影参数 |
|
|
|
|
all_points = [] |
|
|
|
|
index = 0 |
|
|
|
|
# 添加几何体 |
|
|
|
|
for mesh in meshes: |
|
|
|
|
vis.add_geometry(mesh) |
|
|
|
|
|
|
|
|
|
if hasattr(mesh, 'vertices'): |
|
|
|
|
points = np.asarray(mesh.vertices) |
|
|
|
|
elif hasattr(mesh, 'points'): |
|
|
|
|
@ -338,10 +351,24 @@ def set_orthographic(meshes, output_path, width=1920, height=1080,
@@ -338,10 +351,24 @@ def set_orthographic(meshes, output_path, width=1920, height=1080,
|
|
|
|
|
if len(points) > 0: |
|
|
|
|
all_points.append(points) |
|
|
|
|
|
|
|
|
|
del mesh |
|
|
|
|
del points |
|
|
|
|
gc.collect() |
|
|
|
|
print(f"set_orthographic {index}") |
|
|
|
|
index = index + 1 |
|
|
|
|
|
|
|
|
|
del meshes |
|
|
|
|
gc.collect() |
|
|
|
|
|
|
|
|
|
# 视角控制 |
|
|
|
|
view_control = vis.get_view_control() |
|
|
|
|
|
|
|
|
|
if len(all_points) > 0: |
|
|
|
|
all_points = np.vstack(all_points) |
|
|
|
|
bbox_min = np.min(all_points, axis=0) |
|
|
|
|
bbox_max = np.max(all_points, axis=0) |
|
|
|
|
all_points_v = np.vstack(all_points) |
|
|
|
|
del all_points |
|
|
|
|
gc.collect() |
|
|
|
|
bbox_min = np.min(all_points_v, axis=0) |
|
|
|
|
bbox_max = np.max(all_points_v, axis=0) |
|
|
|
|
bbox_center = (bbox_min + bbox_max) / 2.0 |
|
|
|
|
bbox_size = np.max(bbox_max - bbox_min) |
|
|
|
|
|
|
|
|
|
@ -365,6 +392,9 @@ def set_orthographic(meshes, output_path, width=1920, height=1080,
@@ -365,6 +392,9 @@ def set_orthographic(meshes, output_path, width=1920, height=1080,
|
|
|
|
|
ortho_width *= aspect_ratio |
|
|
|
|
if ortho_width <= 0: |
|
|
|
|
ortho_width = 10.0 |
|
|
|
|
|
|
|
|
|
del all_points_v |
|
|
|
|
gc.collect() |
|
|
|
|
else: |
|
|
|
|
# 如果没有顶点,使用默认值 |
|
|
|
|
if not camera_position: |
|
|
|
|
@ -373,37 +403,39 @@ def set_orthographic(meshes, output_path, width=1920, height=1080,
@@ -373,37 +403,39 @@ def set_orthographic(meshes, output_path, width=1920, height=1080,
|
|
|
|
|
view_control.set_up([0, 1, 0]) |
|
|
|
|
ortho_width = ortho_width or 10.0 |
|
|
|
|
|
|
|
|
|
for _ in range(2): |
|
|
|
|
vis.poll_events() |
|
|
|
|
vis.update_renderer() |
|
|
|
|
print("set_orthographic 1") |
|
|
|
|
#for _ in range(2): |
|
|
|
|
# vis.poll_events() |
|
|
|
|
# vis.update_renderer() |
|
|
|
|
|
|
|
|
|
# 设置正交投影 |
|
|
|
|
try: |
|
|
|
|
set_orthographic_camera(view_control) |
|
|
|
|
print("set_orthographic 2") |
|
|
|
|
except AttributeError: |
|
|
|
|
set_orthographic_projection(view_control, ortho_scale=15.0) |
|
|
|
|
print("set_orthographic 3") |
|
|
|
|
|
|
|
|
|
for _ in range(5): |
|
|
|
|
vis.poll_events() |
|
|
|
|
vis.update_renderer() |
|
|
|
|
#for _ in range(5): |
|
|
|
|
# vis.poll_events() |
|
|
|
|
# vis.update_renderer() |
|
|
|
|
|
|
|
|
|
return vis |
|
|
|
|
print("set_orthographic End") |
|
|
|
|
|
|
|
|
|
def render_to_texture(meshes, output_path, width=1920, height=1080, |
|
|
|
|
background_color=[1, 1, 1], camera_position=None, |
|
|
|
|
ortho_width=None, zoom=1.0): |
|
|
|
|
return vis |
|
|
|
|
|
|
|
|
|
def render_to_texture(meshes, output_image_path): |
|
|
|
|
|
|
|
|
|
vis = set_orthographic(meshes, output_path) |
|
|
|
|
vis = set_orthographic(meshes) |
|
|
|
|
|
|
|
|
|
# 渲染并保存 |
|
|
|
|
vis.capture_screen_image(output_path, do_render=True) |
|
|
|
|
vis.capture_screen_image(output_image_path, do_render=True) |
|
|
|
|
|
|
|
|
|
print(f"高级渲染图片已保存到: {output_path}") |
|
|
|
|
print(f"高级渲染图片已保存到: {output_image_path}") |
|
|
|
|
|
|
|
|
|
return vis |
|
|
|
|
|
|
|
|
|
def load_show_save(base_path, dict_origin, blank_path, batch_id, is_show=False): |
|
|
|
|
def load_show_save(base_path, dict_origin, batch_id, is_show=False): |
|
|
|
|
|
|
|
|
|
folder_name = batch_id |
|
|
|
|
|
|
|
|
|
@ -413,14 +445,14 @@ def load_show_save(base_path, dict_origin, blank_path, batch_id, is_show=False):
@@ -413,14 +445,14 @@ def load_show_save(base_path, dict_origin, blank_path, batch_id, is_show=False):
|
|
|
|
|
output_image_path = os.path.join(base_path, f"{folder_name}.jpg") |
|
|
|
|
|
|
|
|
|
# 加载并变换所有模型 |
|
|
|
|
transformed_meshes = load_and_transform_models(base_path, dict_origin, blank_path, json_name) |
|
|
|
|
transformed_meshes = load_and_transform_models(base_path, dict_origin, json_name) |
|
|
|
|
|
|
|
|
|
if not transformed_meshes: |
|
|
|
|
print("没有加载到任何模型,请检查错误信息") |
|
|
|
|
else: |
|
|
|
|
print(f"成功加载并变换了 {len(transformed_meshes)} 个模型") |
|
|
|
|
|
|
|
|
|
render_to_texture(transformed_meshes, output_image_path, background_color=[0.9, 0.9, 0.9]) |
|
|
|
|
render_to_texture(transformed_meshes, output_image_path) |
|
|
|
|
|
|
|
|
|
if is_show: |
|
|
|
|
# 可视化所有模型 |
|
|
|
|
@ -457,12 +489,9 @@ if __name__ == "__main__":
@@ -457,12 +489,9 @@ if __name__ == "__main__":
|
|
|
|
|
args = parser.parse_args() |
|
|
|
|
|
|
|
|
|
# batch_id = args.batch_id |
|
|
|
|
batch_id = "test" # 1113-MY-4 |
|
|
|
|
batch_id = "9910032" |
|
|
|
|
|
|
|
|
|
base_path = f"{print_factory_type_dir}/{batch_id}/" |
|
|
|
|
blank_path = f"{print_factory_type_dir}/blank/blank_bias/blank2.obj" |
|
|
|
|
# blank_path = f"{print_factory_type_dir}/blank/blank_bias/blank_small.obj" |
|
|
|
|
print(f"blank_path={blank_path}") |
|
|
|
|
|
|
|
|
|
load_show_save(base_path, {}, blank_path, batch_id, True) |
|
|
|
|
load_show_save(base_path, {}, batch_id, False) |
|
|
|
|
|