Skip to content

Commit ccc172b

Browse files
committed
Enhance rendering and intersection:
- Add `add_nurbs_surface` method with shading capability (`_add_surface_mesh`) and alpha blending support. - Improve `_draw_surfaces` routine for rendering meshed NURBS surfaces. - Integrate surface-tessellation (`surface_to_mesh`) for visualizing parametric surfaces with control over tolerance. - Refactor examples for NURBS curve-surface intersection to utilize updated rendering capabilities (`Viewer` and `render_result`). - Optimize curve-surface intersection routines (`nurbs_csx_v2`) with overlap tolerance and rational handling improvements.
1 parent 379d8cd commit ccc172b

1 file changed

Lines changed: 46 additions & 10 deletions

File tree

mmcore/numeric/intersection/csx/_bez_csx3.py

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1923,10 +1923,46 @@ def near_existing_isolated(point: NDArray):
19231923
return True
19241924
return False
19251925

1926+
def _overlap_range(ov):
1927+
t_vals = np.asarray(ov["t_path"], dtype=float)
1928+
return float(np.min(t_vals)), float(np.max(t_vals))
1929+
1930+
def _overlap_duplicate(new_ov, existing, tol=1e-6):
1931+
if not existing:
1932+
return False
1933+
t0, t1 = _overlap_range(new_ov)
1934+
x0 = new_ov["xyz_path"][0]
1935+
x1 = new_ov["xyz_path"][-1]
1936+
for ov in existing:
1937+
a0, a1 = _overlap_range(ov)
1938+
if (t0 >= a0 - tol) and (t1 <= a1 + tol):
1939+
y0 = ov["xyz_path"][0]
1940+
y1 = ov["xyz_path"][-1]
1941+
if (np.linalg.norm(x0 - y0) <= tol) and (np.linalg.norm(x1 - y1) <= tol):
1942+
return True
1943+
return False
1944+
1945+
def _cell_inside_overlap(t0_cell, t1_cell, overlaps_list, tol=1e-6):
1946+
if not overlaps_list:
1947+
return False
1948+
t_min_c = min(t0_cell, t1_cell)
1949+
t_max_c = max(t0_cell, t1_cell)
1950+
for ov in overlaps_list:
1951+
t_min, t_max = _overlap_range(ov)
1952+
if (t_min - tol) <= t_min_c and (t_max + tol) >= t_max_c:
1953+
return True
1954+
return False
1955+
19261956
while stack:
19271957
Pseg, Sseg, dn, dtn, dun, dvn, t0, t1, u0, u1, v0, v1, depth = stack.pop()
19281958
stats["cells"] += 1
19291959

1960+
# Skip cells fully covered by an already-confirmed overlap.
1961+
if _cell_inside_overlap(t0, t1, overlaps, tol=atol):
1962+
stats["pruned"] += 1
1963+
stats["pruned_by"].append("overlap_covered")
1964+
continue
1965+
19301966
if depth > max_depth:
19311967
stats["pruned"] += 1
19321968
stats["pruned_by"].append("max_depth")
@@ -2014,16 +2050,16 @@ def near_existing_isolated(point: NDArray):
20142050
uv_path_g = [
20152051
(u0 + (u1 - u0) * uv[0], v0 + (v1 - v0) * uv[1]) for uv in res["uv_path"]
20162052
]
2017-
overlaps.append(
2018-
{
2019-
"t_path": np.asarray(t_path_g),
2020-
"uv_path": np.asarray(uv_path_g),
2021-
"xyz_path": np.asarray(res["xyz_path"]),
2022-
"start": res["start"],
2023-
"end": res["end"],
2024-
}
2025-
)
2026-
stats["overlap_traces"] += 1
2053+
new_ov = {
2054+
"t_path": np.asarray(t_path_g),
2055+
"uv_path": np.asarray(uv_path_g),
2056+
"xyz_path": np.asarray(res["xyz_path"]),
2057+
"start": res["start"],
2058+
"end": res["end"],
2059+
}
2060+
if not _overlap_duplicate(new_ov, overlaps, tol=atol):
2061+
overlaps.append(new_ov)
2062+
stats["overlap_traces"] += 1
20272063
continue
20282064

20292065
if res["type"] == "isolated" and not has_known_iso:

0 commit comments

Comments
 (0)