From 200e13a7ba2a204b9b72dc559fe6f14a2575d019 Mon Sep 17 00:00:00 2001 From: hesuicong Date: Wed, 11 Nov 2026 10:17:47 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=B9=E6=8E=A5=E6=80=80=E6=B1=9F=E7=9A=84?= =?UTF-8?q?=E8=B0=83=E7=94=A8=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fill2sc/generate_fill_mesh_hsc.py | 66 ++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/fill2sc/generate_fill_mesh_hsc.py b/fill2sc/generate_fill_mesh_hsc.py index 18f06c6..fa0c2d5 100644 --- a/fill2sc/generate_fill_mesh_hsc.py +++ b/fill2sc/generate_fill_mesh_hsc.py @@ -23,6 +23,8 @@ from PIL import Image, ImageDraw import subprocess import os +import sys +import argparse def auto_bevel_in_blender(input_obj_path, output_obj_path, bevel_width=0.5, angle_deg=15): blender_script = ( @@ -107,11 +109,19 @@ class FillMeshGenerator: BLAM = 0.6 # 边界平滑系数 TOL = 1e-4 # Jacobi 收敛阈值 - def __init__(self, in_obj=None, in_idx=None): + def __init__(self, in_obj=None, in_idx=None, out_fill=None): if in_obj: self.IN_OBJ = in_obj if in_idx: self.IN_IDX = in_idx + if out_fill: + self.OUT_FILL = out_fill + # 根据 OUT_FILL 自动推导 OUT_MERGED 和 OUT_PREVIEW + base, ext = os.path.splitext(self.OUT_FILL) + self.OUT_MERGED = base + "_filled" + ext + self.OUT_PREVIEW = base.replace("mesh", "preview") + ".png" + if self.OUT_PREVIEW == base + ".png": + self.OUT_PREVIEW = base + "_preview.png" self.report = [] self.lens_mask = None @@ -1392,19 +1402,39 @@ class FillMeshGenerator: faces.append((a, b, c)) faces.append((b, d, c)) - # ========== 8. 直墙(修正:法线朝外)========== + # ========== 8. 直墙(修正:连接圆角底层到对应的后表面位置)========== for i in range(Nr): j = (i + 1) % Nr a = fillet_idx(i, segments) b = fillet_idx(j, segments) - a_back = ring[i] + nV - b_back = ring[j] + nV - # 关键修正:原来是 (a,b,b_back) 和 (a,b_back,a_back) - # 现在改为: - faces.append((a, b_back, b)) - faces.append((a, a_back, b_back)) + # 后表面也做同样的向内偏移 + r_i = local_radius[i] + r_j = local_radius[j] + + # 后表面对应点的偏移量(和圆角底层相同) + offset_h_i = r_i * np.sin(1.0 * np.pi / 2) # segments/segments = 1.0 + offset_v_i = r_i * (1 - np.cos(1.0 * np.pi / 2)) + offset_h_j = r_j * np.sin(1.0 * np.pi / 2) + offset_v_j = r_j * (1 - np.cos(1.0 * np.pi / 2)) + + a_back_pt = Pb[ring[i]].copy() + a_back_pt[:2] -= outward_list[i][:2] * offset_h_i + a_back_pt[2] -= offset_v_i + + b_back_pt = Pb[ring[j]].copy() + b_back_pt[:2] -= outward_list[j][:2] * offset_h_j + b_back_pt[2] -= offset_v_j + + # 添加后表面偏移后的顶点 + a_back_idx = len(Pall) + b_back_idx = len(Pall) + 1 + Pall = np.vstack([Pall, a_back_pt, b_back_pt]) + + # 法线朝外 + faces.append((a, b_back_idx, b)) + faces.append((a, a_back_idx, b_back_idx)) Ff = np.asarray(faces, np.int64) @@ -1670,5 +1700,21 @@ class FillMeshGenerator: # 入口 # ====================================================================== if __name__ == "__main__": - gen = FillMeshGenerator() - gen.run() \ No newline at end of file + parser = argparse.ArgumentParser(description="眼镜-脸部填充网格生成器") + parser.add_argument("--in_obj", type=str, default="632723.obj", + help="输入 OBJ 模型文件路径 (默认: 632723.obj)") + parser.add_argument("--in_idx", type=str, default="index.txt", + help="眼镜顶点索引文件路径 (默认: index.txt)") + parser.add_argument("--out_fill", type=str, default="fill_mesh.obj", + help="输出填充网格文件路径 (默认: fill_mesh.obj)") + + args = parser.parse_args() + + gen = FillMeshGenerator( + in_obj=args.in_obj, + in_idx=args.in_idx, + out_fill=args.out_fill + ) + gen.run() + + # python generate_fill_mesh_hsc.py --in_obj 632723.obj --in_idx index.txt --out_fill fill_mesh.obj \ No newline at end of file