From 56efa123ec7003411eacdc1a3e897460df485a26 Mon Sep 17 00:00:00 2001 From: mckay Date: Tue, 22 Apr 2025 15:23:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9A=82=E6=97=B6=E5=8F=AF=E7=94=A8=E7=9A=84IS?= =?UTF-8?q?G?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- brep2sdf/IsoSurfacing.py | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/brep2sdf/IsoSurfacing.py b/brep2sdf/IsoSurfacing.py index c1e6d9e..c9a7650 100644 --- a/brep2sdf/IsoSurfacing.py +++ b/brep2sdf/IsoSurfacing.py @@ -20,6 +20,10 @@ def create_grid(depth, box_size): z = np.linspace(start, end, grid_size) xx, yy, zz = np.meshgrid(x, y, z, indexing='ij') points = np.stack([xx.ravel(), yy.ravel(), zz.ravel()], axis=1) + + # 新增归一化处理 + max_coord = np.max(np.abs(points)) + points = points / max_coord # 归一化到[-1,1] return points, xx, yy, zz def predict_sdf(model, points, device): @@ -36,7 +40,7 @@ def predict_sdf(model, points, device): sdf = model(points_t).cpu().numpy().flatten() return sdf -def extract_surface(sdf, xx, yy, zz, method='MC'): +def extract_surface(sdf, xx, yy, zz, method='MC', feature_angle=30.0, voxel_size=0.01): """ 提取零表面 :param sdf: SDF值三维数组 @@ -46,8 +50,21 @@ def extract_surface(sdf, xx, yy, zz, method='MC'): """ if method == 'MC': verts, faces, _, _ = measure.marching_cubes(sdf, level=0) + elif method == 'EMC': + from iso_algorithms import enhanced_marching_cubes + verts, faces = enhanced_marching_cubes( + sdf, + feature_angle=feature_angle, + gradient_direction='descent' + ) + elif method == 'DC': + from iso_algorithms import dual_contouring + verts, faces = dual_contouring(sdf, voxel_size=voxel_size) else: - raise NotImplementedError("仅支持Marching Cubes方法") + raise ValueError(f"不支持的算法: {method}") + + # 新增顶点后处理 + verts = (verts - sdf.shape[0]//2) / (sdf.shape[0]//2) # 归一化到[-1,1] return verts, faces def save_ply(vertices, faces, filename): @@ -111,9 +128,16 @@ def main(): parser = argparse.ArgumentParser(description='IsoSurface Generator') parser.add_argument('-i', '--input', type=str, required=True, help='Input model file (.pt)') parser.add_argument('-o', '--output', type=str, required=True, help='Output mesh file (.ply)') - parser.add_argument('--depth', type=int, default=3, help='网格深度(分辨率)') - parser.add_argument('--box_size', type=float, default=1.0, help='边界框大小') - parser.add_argument('--method', type=str, default='MC', choices=['MC'], help='表面提取方法') + parser.add_argument('--depth', type=int, default=7, help='网格深度(分辨率)') + parser.add_argument('--box_size', type=float, default=2.0, # 从1.0改为2.0 + help='边界框大小(建议设为2.0以得到[-1,1]范围)') + parser.add_argument('--method', type=str, default='MC', + choices=['MC', 'EMC', 'DC'], # 新增算法选项 + help='表面提取方法: MC-MarchingCubes, EMC-EnhancedMC, DC-DualContouring') + parser.add_argument('--feature_angle', type=float, default=30.0, + help='特征角度阈值(EMC算法专用)') + parser.add_argument('--voxel_size', type=float, default=0.01, + help='体素尺寸(DC算法专用)') parser.add_argument('--use-gpu', action='store_true', help='使用GPU') parser.add_argument('--compare', type=str, help='GT网格文件(.ply)') parser.add_argument('--compres', type=int, default=32, help='误差计算分辨率') @@ -139,6 +163,11 @@ def main(): print("Extracting surface...") start_time = time.time() verts, faces = extract_surface(sdf_grid, xx, yy, zz, args.method) + + # 新增顶点归一化校验 + max_val = np.max(np.abs(verts)) + if max_val > 1.0 + 1e-6: # 允许微小误差 + verts = verts / max_val print(f"Surface extraction took {time.time() - start_time:.2f} seconds") # 保存网格