Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

请求在生成地形的时候,取消使用open3d的convert_heightfield_to_watertight_trimesh函数来进行简化。 #493

Open
Huisouan opened this issue Jan 7, 2025 · 0 comments

Comments

@Huisouan
Copy link

Huisouan commented Jan 7, 2025

在genesis生成复杂地形的时候,convert_heightfield_to_watertight_trimesh函数里面使用了open3d的simplify_quadric_decimation对mesh进行简化。然而这个函数在计算上可能有一定的问题,请看如下链接:simplify_quadric_decimation works horrible #2581

是否可以先暂时不要使用这个简化,直接使用sdf_mesh。
def convert_heightfield_to_watertight_trimesh(height_field_raw, horizontal_scale, vertical_scale, slope_threshold=None): """ Adapted from Issac Gym'sconvert_heightfield_to_trimesh` function.
Convert a heightfield array to a triangle mesh represented by vertices and triangles.
Optionally, corrects vertical surfaces above the provide slope threshold:

    If (y2-y1)/(x2-x1) > slope_threshold -> Move A to A' (set x1 = x2). Do this for all directions.
               B(x2,y2)
              /|
             / |
            /  |
    (x1,y1)A---A'(x2',y1)

Parameters:
    height_field_raw (np.array): input heightfield
    horizontal_scale (float): horizontal scale of the heightfield [meters]
    vertical_scale (float): vertical scale of the heightfield [meters]
    slope_threshold (float): the slope threshold above which surfaces are made vertical. If None no correction is applied (default: None)
Returns:
    vertices (np.array(float)): array of shape (num_vertices, 3). Each row represents the location of each vertex [meters]
    triangles (np.array(int)): array of shape (num_triangles, 3). Each row represents the indices of the 3 vertices connected by this triangle.
"""
hf = height_field_raw
num_rows = hf.shape[0]
num_cols = hf.shape[1]

y = np.linspace(0, (num_cols - 1) * horizontal_scale, num_cols)
x = np.linspace(0, (num_rows - 1) * horizontal_scale, num_rows)
yy, xx = np.meshgrid(y, x)

if slope_threshold is not None:
    assert False  # our sdf representation doesn't support steep slopes well

    slope_threshold *= horizontal_scale / vertical_scale
    move_x = np.zeros((num_rows, num_cols))
    move_y = np.zeros((num_rows, num_cols))
    move_corners = np.zeros((num_rows, num_cols))
    move_x[: num_rows - 1, :] += hf[1:num_rows, :] - hf[: num_rows - 1, :] > slope_threshold
    move_x[1:num_rows, :] -= hf[: num_rows - 1, :] - hf[1:num_rows, :] > slope_threshold
    move_y[:, : num_cols - 1] += hf[:, 1:num_cols] - hf[:, : num_cols - 1] > slope_threshold
    move_y[:, 1:num_cols] -= hf[:, : num_cols - 1] - hf[:, 1:num_cols] > slope_threshold
    move_corners[: num_rows - 1, : num_cols - 1] += (
        hf[1:num_rows, 1:num_cols] - hf[: num_rows - 1, : num_cols - 1] > slope_threshold
    )
    move_corners[1:num_rows, 1:num_cols] -= (
        hf[: num_rows - 1, : num_cols - 1] - hf[1:num_rows, 1:num_cols] > slope_threshold
    )
    xx += (move_x + move_corners * (move_x == 0)) * horizontal_scale
    yy += (move_y + move_corners * (move_y == 0)) * horizontal_scale

# create triangle mesh vertices and triangles from the heightfield grid
vertices_top = np.zeros((num_rows * num_cols, 3), dtype=np.float32)
vertices_top[:, 0] = xx.flatten()
vertices_top[:, 1] = yy.flatten()
vertices_top[:, 2] = hf.flatten() * vertical_scale
triangles_top = -np.ones((2 * (num_rows - 1) * (num_cols - 1), 3), dtype=np.uint32)
for i in range(num_rows - 1):
    ind0 = np.arange(0, num_cols - 1) + i * num_cols
    ind1 = ind0 + 1
    ind2 = ind0 + num_cols
    ind3 = ind2 + 1
    start = 2 * i * (num_cols - 1)
    stop = start + 2 * (num_cols - 1)
    triangles_top[start:stop:2, 0] = ind0
    triangles_top[start:stop:2, 1] = ind3
    triangles_top[start:stop:2, 2] = ind1
    triangles_top[start + 1 : stop : 2, 0] = ind0
    triangles_top[start + 1 : stop : 2, 1] = ind2
    triangles_top[start + 1 : stop : 2, 2] = ind3

# bottom plane
z_min = np.min(vertices_top[:, 2]) - 1.0

vertices_bottom = np.zeros((num_rows * num_cols, 3), dtype=np.float32)
vertices_bottom[:, 0] = xx.flatten()
vertices_bottom[:, 1] = yy.flatten()
vertices_bottom[:, 2] = z_min
triangles_bottom = -np.ones((2 * (num_rows - 1) * (num_cols - 1), 3), dtype=np.uint32)
for i in range(num_rows - 1):
    ind0 = np.arange(0, num_cols - 1) + i * num_cols
    ind1 = ind0 + 1
    ind2 = ind0 + num_cols
    ind3 = ind2 + 1
    start = 2 * i * (num_cols - 1)
    stop = start + 2 * (num_cols - 1)
    triangles_bottom[start:stop:2, 0] = ind0
    triangles_bottom[start:stop:2, 2] = ind3
    triangles_bottom[start:stop:2, 1] = ind1
    triangles_bottom[start + 1 : stop : 2, 0] = ind0
    triangles_bottom[start + 1 : stop : 2, 2] = ind2
    triangles_bottom[start + 1 : stop : 2, 1] = ind3
triangles_bottom += num_rows * num_cols

# side face
triangles_side_0 = np.zeros([2 * (num_rows - 1), 3], dtype=np.uint32)
for i in range(num_rows - 1):
    ind0 = i * num_cols
    ind1 = (i + 1) * num_cols
    ind2 = ind0 + num_rows * num_cols
    ind3 = ind1 + num_rows * num_cols
    triangles_side_0[2 * i] = [ind0, ind2, ind1]
    triangles_side_0[2 * i + 1] = [ind1, ind2, ind3]

triangles_side_1 = np.zeros([2 * (num_cols - 1), 3], dtype=np.uint32)
for i in range(num_cols - 1):
    ind0 = i
    ind1 = i + 1
    ind2 = ind0 + num_rows * num_cols
    ind3 = ind1 + num_rows * num_cols
    triangles_side_1[2 * i] = [ind0, ind1, ind2]
    triangles_side_1[2 * i + 1] = [ind1, ind3, ind2]

triangles_side_2 = np.zeros([2 * (num_rows - 1), 3], dtype=np.uint32)
for i in range(num_rows - 1):
    ind0 = i * num_cols + num_cols - 1
    ind1 = (i + 1) * num_cols + num_cols - 1
    ind2 = ind0 + num_rows * num_cols
    ind3 = ind1 + num_rows * num_cols
    triangles_side_2[2 * i] = [ind0, ind1, ind2]
    triangles_side_2[2 * i + 1] = [ind1, ind3, ind2]

triangles_side_3 = np.zeros([2 * (num_cols - 1), 3], dtype=np.uint32)
for i in range(num_cols - 1):
    ind0 = i + (num_rows - 1) * num_cols
    ind1 = i + 1 + (num_rows - 1) * num_cols
    ind2 = ind0 + num_rows * num_cols
    ind3 = ind1 + num_rows * num_cols
    triangles_side_3[2 * i] = [ind0, ind2, ind1]
    triangles_side_3[2 * i + 1] = [ind1, ind2, ind3]

vertices = np.concatenate([vertices_top, vertices_bottom], axis=0)
triangles = np.concatenate(
    [triangles_top, triangles_bottom, triangles_side_0, triangles_side_1, triangles_side_2, triangles_side_3],
    axis=0,
)

# This a uniformly-distributed full mesh, which gives faster sdf generation
sdf_mesh = trimesh.Trimesh(vertices, triangles, process=False)
# This is the mesh used for non-sdf purposes. It's losslessly simplified from the full mesh, to save memory cost for storing verts and faces
#mesh = sdf_mesh.simplify_quadric_decimation(face_count=0, maximum_error=0.0)

return sdf_mesh, sdf_mesh

`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant