Browse Source

暂时可用的ISG

final
mckay 2 months ago
parent
commit
56efa123ec
  1. 39
      brep2sdf/IsoSurfacing.py

39
brep2sdf/IsoSurfacing.py

@ -20,6 +20,10 @@ def create_grid(depth, box_size):
z = np.linspace(start, end, grid_size) z = np.linspace(start, end, grid_size)
xx, yy, zz = np.meshgrid(x, y, z, indexing='ij') xx, yy, zz = np.meshgrid(x, y, z, indexing='ij')
points = np.stack([xx.ravel(), yy.ravel(), zz.ravel()], axis=1) 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 return points, xx, yy, zz
def predict_sdf(model, points, device): def predict_sdf(model, points, device):
@ -36,7 +40,7 @@ def predict_sdf(model, points, device):
sdf = model(points_t).cpu().numpy().flatten() sdf = model(points_t).cpu().numpy().flatten()
return sdf 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值三维数组 :param sdf: SDF值三维数组
@ -46,8 +50,21 @@ def extract_surface(sdf, xx, yy, zz, method='MC'):
""" """
if method == 'MC': if method == 'MC':
verts, faces, _, _ = measure.marching_cubes(sdf, level=0) 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: else:
raise NotImplementedError("仅支持Marching Cubes方法") raise ValueError(f"不支持的算法: {method}")
# 新增顶点后处理
verts = (verts - sdf.shape[0]//2) / (sdf.shape[0]//2) # 归一化到[-1,1]
return verts, faces return verts, faces
def save_ply(vertices, faces, filename): def save_ply(vertices, faces, filename):
@ -111,9 +128,16 @@ def main():
parser = argparse.ArgumentParser(description='IsoSurface Generator') parser = argparse.ArgumentParser(description='IsoSurface Generator')
parser.add_argument('-i', '--input', type=str, required=True, help='Input model file (.pt)') 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('-o', '--output', type=str, required=True, help='Output mesh file (.ply)')
parser.add_argument('--depth', type=int, default=3, help='网格深度(分辨率)') parser.add_argument('--depth', type=int, default=7, help='网格深度(分辨率)')
parser.add_argument('--box_size', type=float, default=1.0, help='边界框大小') parser.add_argument('--box_size', type=float, default=2.0, # 从1.0改为2.0
parser.add_argument('--method', type=str, default='MC', choices=['MC'], help='表面提取方法') 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('--use-gpu', action='store_true', help='使用GPU')
parser.add_argument('--compare', type=str, help='GT网格文件(.ply)') parser.add_argument('--compare', type=str, help='GT网格文件(.ply)')
parser.add_argument('--compres', type=int, default=32, help='误差计算分辨率') parser.add_argument('--compres', type=int, default=32, help='误差计算分辨率')
@ -139,6 +163,11 @@ def main():
print("Extracting surface...") print("Extracting surface...")
start_time = time.time() start_time = time.time()
verts, faces = extract_surface(sdf_grid, xx, yy, zz, args.method) 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") print(f"Surface extraction took {time.time() - start_time:.2f} seconds")
# 保存网格 # 保存网格

Loading…
Cancel
Save