|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import numpy as np |
|
|
|
|
|
def meshVerticeInpaint_smooth(texture, mask, vtx_pos, vtx_uv, pos_idx, uv_idx): |
|
texture_height, texture_width, texture_channel = texture.shape |
|
vtx_num = vtx_pos.shape[0] |
|
|
|
vtx_mask = np.zeros(vtx_num, dtype=np.float32) |
|
vtx_color = [np.zeros(texture_channel, dtype=np.float32) for _ in range(vtx_num)] |
|
uncolored_vtxs = [] |
|
G = [[] for _ in range(vtx_num)] |
|
|
|
for i in range(uv_idx.shape[0]): |
|
for k in range(3): |
|
vtx_uv_idx = uv_idx[i, k] |
|
vtx_idx = pos_idx[i, k] |
|
uv_v = int(round(vtx_uv[vtx_uv_idx, 0] * (texture_width - 1))) |
|
uv_u = int(round((1.0 - vtx_uv[vtx_uv_idx, 1]) * (texture_height - 1))) |
|
if mask[uv_u, uv_v] > 0: |
|
vtx_mask[vtx_idx] = 1.0 |
|
vtx_color[vtx_idx] = texture[uv_u, uv_v] |
|
else: |
|
uncolored_vtxs.append(vtx_idx) |
|
G[pos_idx[i, k]].append(pos_idx[i, (k + 1) % 3]) |
|
|
|
smooth_count = 2 |
|
last_uncolored_vtx_count = 0 |
|
while smooth_count > 0: |
|
uncolored_vtx_count = 0 |
|
for vtx_idx in uncolored_vtxs: |
|
sum_color = np.zeros(texture_channel, dtype=np.float32) |
|
total_weight = 0.0 |
|
vtx_0 = vtx_pos[vtx_idx] |
|
for connected_idx in G[vtx_idx]: |
|
if vtx_mask[connected_idx] > 0: |
|
vtx1 = vtx_pos[connected_idx] |
|
dist = np.sqrt(np.sum((vtx_0 - vtx1) ** 2)) |
|
dist_weight = 1.0 / max(dist, 1e-4) |
|
dist_weight *= dist_weight |
|
sum_color += vtx_color[connected_idx] * dist_weight |
|
total_weight += dist_weight |
|
if total_weight > 0: |
|
vtx_color[vtx_idx] = sum_color / total_weight |
|
vtx_mask[vtx_idx] = 1.0 |
|
else: |
|
uncolored_vtx_count += 1 |
|
|
|
if last_uncolored_vtx_count == uncolored_vtx_count: |
|
smooth_count -= 1 |
|
else: |
|
smooth_count += 1 |
|
last_uncolored_vtx_count = uncolored_vtx_count |
|
|
|
new_texture = texture.copy() |
|
new_mask = mask.copy() |
|
for face_idx in range(uv_idx.shape[0]): |
|
for k in range(3): |
|
vtx_uv_idx = uv_idx[face_idx, k] |
|
vtx_idx = pos_idx[face_idx, k] |
|
if vtx_mask[vtx_idx] == 1.0: |
|
uv_v = int(round(vtx_uv[vtx_uv_idx, 0] * (texture_width - 1))) |
|
uv_u = int(round((1.0 - vtx_uv[vtx_uv_idx, 1]) * (texture_height - 1))) |
|
new_texture[uv_u, uv_v] = vtx_color[vtx_idx] |
|
new_mask[uv_u, uv_v] = 255 |
|
return new_texture, new_mask |
|
|
|
|
|
def meshVerticeInpaint( |
|
texture, mask, vtx_pos, vtx_uv, pos_idx, uv_idx, method="smooth" |
|
): |
|
if method == "smooth": |
|
return meshVerticeInpaint_smooth( |
|
texture, mask, vtx_pos, vtx_uv, pos_idx, uv_idx |
|
) |
|
else: |
|
raise ValueError("Invalid method. Use 'smooth' or 'forward'.") |
|
|