This commit is contained in:
kijai 2026-07-01 21:39:19 +03:00
parent 2bbf53e8fc
commit 6ecbaac853
3 changed files with 44 additions and 22 deletions

View File

@ -15,14 +15,18 @@ from torch import Tensor
def face_normals(vertices: Tensor, faces: Tensor) -> Tensor:
"""[F,3] unit face normals (degenerate faces -> zero)."""
v0 = vertices[faces[:, 0]]; v1 = vertices[faces[:, 1]]; v2 = vertices[faces[:, 2]]
v0 = vertices[faces[:, 0]]
v1 = vertices[faces[:, 1]]
v2 = vertices[faces[:, 2]]
n = torch.linalg.cross(v1 - v0, v2 - v0)
return n / n.norm(dim=1, keepdim=True).clamp_min(1e-20)
def face_areas(vertices: Tensor, faces: Tensor) -> Tensor:
"""[F] triangle areas."""
v0 = vertices[faces[:, 0]]; v1 = vertices[faces[:, 1]]; v2 = vertices[faces[:, 2]]
v0 = vertices[faces[:, 0]]
v1 = vertices[faces[:, 1]]
v2 = vertices[faces[:, 2]]
return 0.5 * torch.linalg.cross(v1 - v0, v2 - v0).norm(dim=1)

View File

@ -50,10 +50,14 @@ def _best_rotation_jit(uvs_np: np.ndarray, n_angles: int) -> float:
uy = uvs_np[i, 1]
xr = ux * c - uy * s
yr = ux * s + uy * c
if xr < xmin: xmin = xr
if xr > xmax: xmax = xr
if yr < ymin: ymin = yr
if yr > ymax: ymax = yr
if xr < xmin:
xmin = xr
if xr > xmax:
xmax = xr
if yr < ymin:
ymin = yr
if yr > ymax:
ymax = yr
area = (xmax - xmin) * (ymax - ymin)
if area < best_area:
best_area = area
@ -92,25 +96,37 @@ def _rasterize_chart_jit(
x2 = uvs_tex[i2, 0]
y2 = uvs_tex[i2, 1]
xmin_f = x0
if x1 < xmin_f: xmin_f = x1
if x2 < xmin_f: xmin_f = x2
if x1 < xmin_f:
xmin_f = x1
if x2 < xmin_f:
xmin_f = x2
xmax_f = x0
if x1 > xmax_f: xmax_f = x1
if x2 > xmax_f: xmax_f = x2
if x1 > xmax_f:
xmax_f = x1
if x2 > xmax_f:
xmax_f = x2
ymin_f = y0
if y1 < ymin_f: ymin_f = y1
if y2 < ymin_f: ymin_f = y2
if y1 < ymin_f:
ymin_f = y1
if y2 < ymin_f:
ymin_f = y2
ymax_f = y0
if y1 > ymax_f: ymax_f = y1
if y2 > ymax_f: ymax_f = y2
if y1 > ymax_f:
ymax_f = y1
if y2 > ymax_f:
ymax_f = y2
xmin = int(math.floor(xmin_f))
if xmin < 0: xmin = 0
if xmin < 0:
xmin = 0
xmax = int(math.ceil(xmax_f))
if xmax > w - 1: xmax = w - 1
if xmax > w - 1:
xmax = w - 1
ymin = int(math.floor(ymin_f))
if ymin < 0: ymin = 0
if ymin < 0:
ymin = 0
ymax = int(math.ceil(ymax_f))
if ymax > h - 1: ymax = h - 1
if ymax > h - 1:
ymax = h - 1
if xmax < xmin or ymax < ymin:
continue
denom = (y1 - y2) * (x0 - x2) + (x2 - x1) * (y0 - y2)

View File

@ -116,9 +116,12 @@ def _stretch_metrics(verts_3d: np.ndarray, uvs: np.ndarray, faces: np.ndarray) -
keep = (geom_area > 1e-12) & (np.abs(parametric_area) > 1e-12)
if not keep.any():
return float("inf"), float("inf"), n_flipped, n_zero
t1 = t[:, 0, 0]; s1 = t[:, 0, 1]
t2 = t[:, 1, 0]; s2 = t[:, 1, 1]
t3 = t[:, 2, 0]; s3 = t[:, 2, 1]
t1 = t[:, 0, 0]
s1 = t[:, 0, 1]
t2 = t[:, 1, 0]
s2 = t[:, 1, 1]
t3 = t[:, 2, 0]
s3 = t[:, 2, 1]
inv_2pa = 1.0 / (2.0 * pa)
Ss = (
p[:, 0] * (t2 - t3)[:, None]
@ -212,7 +215,6 @@ def _abf_face_coefficients(
verts_3d: np.ndarray, faces: np.ndarray
) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
"""Per-face ABF constraint (largest-sine vertex at local index 2); returns (faces_reordered, cosine, sine, valid_mask) with valid_mask False for degenerate tris."""
Fc = faces.shape[0]
p0 = verts_3d[faces[:, 0]]
p1 = verts_3d[faces[:, 1]]
p2 = verts_3d[faces[:, 2]]