From 5cf994ec4b63abee7793e3e9cb8c5bd3bd753961 Mon Sep 17 00:00:00 2001 From: Antoine Date: Tue, 17 Feb 2026 18:34:36 +0000 Subject: [PATCH] fix: use mid-point to determine arc direction instead of clockwise flag The clockwise flag from NX extractor can be inverted depending on face normal orientation. The sampled mid-point is always reliable. Now _arc_angles checks which direction (CW vs CCW) passes through the mid-point and uses that. --- .../adaptive-isogrid/src/shared/arc_utils.py | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tools/adaptive-isogrid/src/shared/arc_utils.py b/tools/adaptive-isogrid/src/shared/arc_utils.py index c49f0495..bc120d71 100644 --- a/tools/adaptive-isogrid/src/shared/arc_utils.py +++ b/tools/adaptive-isogrid/src/shared/arc_utils.py @@ -16,6 +16,39 @@ def _arc_angles(seg: Dict[str, Any]): ex, ey = seg["end"] a0 = math.atan2(sy - cy, sx - cx) a1 = math.atan2(ey - cy, ex - cx) + + # If a midpoint is available, use it to determine the correct arc direction + # (more reliable than the clockwise flag, which can be inverted by face normal orientation) + mid = seg.get("mid") + if mid is not None: + mx, my = float(mid[0]), float(mid[1]) + a_mid = math.atan2(my - cy, mx - cx) + + # Try CCW direction (a1 > a0) + a1_ccw = a1 + if a1_ccw < a0: + a1_ccw += 2.0 * math.pi + # Check if mid angle falls within CCW sweep + a_mid_ccw = a_mid + if a_mid_ccw < a0: + a_mid_ccw += 2.0 * math.pi + ccw_ok = (a0 <= a_mid_ccw <= a1_ccw) + + # Try CW direction (a1 < a0) + a1_cw = a1 + if a1_cw > a0: + a1_cw -= 2.0 * math.pi + a_mid_cw = a_mid + if a_mid_cw > a0: + a_mid_cw -= 2.0 * math.pi + cw_ok = (a1_cw <= a_mid_cw <= a0) + + if ccw_ok and not cw_ok: + return a0, a1_ccw + elif cw_ok and not ccw_ok: + return a0, a1_cw + # If both or neither match, fall through to clockwise flag + cw = bool(seg.get("clockwise", False)) if cw: if a1 > a0: