fix(extract): discover UF curve eval methods dynamically
NXOpen Python wraps UF methods with version-specific names. Now dumps available methods on UF.Modl, UF.Eval, UF.Curve and tries them in order. Detailed logging shows which method was found and used, plus raw result format on parse failures.
This commit is contained in:
@@ -169,41 +169,118 @@ def _sample_edge_polyline(edge: Any, chord_tol_mm: float, lister: Any = None) ->
|
|||||||
f"len={length:.3f} tol={tol:.3f} n_pts={n_pts}"
|
f"len={length:.3f} tol={tol:.3f} n_pts={n_pts}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# 1) Primary: UF_MODL_ask_curve_props — normalized parameter 0..1
|
# 1) Primary: UF curve evaluation — try multiple API patterns
|
||||||
try:
|
try:
|
||||||
import NXOpen
|
import NXOpen
|
||||||
import NXOpen.UF
|
import NXOpen.UF
|
||||||
|
|
||||||
uf = NXOpen.UF.UFSession.GetUFSession()
|
uf = NXOpen.UF.UFSession.GetUFSession()
|
||||||
|
|
||||||
pts: List[Point3D] = []
|
# Discover the correct method name (varies by NX version)
|
||||||
parse_failures = 0
|
# UF_MODL_ask_curve_props → uf.Modl.AskCurveProps or similar
|
||||||
|
modl = uf.Modl
|
||||||
|
modl_methods = [m for m in dir(modl) if 'curve' in m.lower() or 'Curve' in m]
|
||||||
|
_log(f"[edge] UF.Modl curve methods: {modl_methods}")
|
||||||
|
|
||||||
|
eval_obj = uf.Eval
|
||||||
|
eval_methods = [m for m in dir(eval_obj) if not m.startswith('_')]
|
||||||
|
_log(f"[edge] UF.Eval methods: {eval_methods}")
|
||||||
|
|
||||||
|
# Also check uf.Curve
|
||||||
try:
|
try:
|
||||||
for i in range(n_pts + 1):
|
curve_obj = uf.Curve
|
||||||
param = float(i) / float(n_pts) # 0.0 to 1.0
|
curve_methods = [m for m in dir(curve_obj) if 'eval' in m.lower() or 'Eval' in m or 'prop' in m.lower()]
|
||||||
# AskCurveProps returns: (point[3], tangent[3], normal[3], binormal[3], torsion, radius_of_curvature)
|
_log(f"[edge] UF.Curve eval methods: {curve_methods}")
|
||||||
result = uf.Modl.AskCurveProps(edge.Tag, param)
|
except Exception:
|
||||||
# result[0] is the point array [x, y, z]
|
|
||||||
if isinstance(result, (list, tuple)) and len(result) >= 1:
|
|
||||||
pt_data = result[0]
|
|
||||||
if isinstance(pt_data, (list, tuple)) and len(pt_data) >= 3:
|
|
||||||
pts.append((float(pt_data[0]), float(pt_data[1]), float(pt_data[2])))
|
|
||||||
elif hasattr(pt_data, '__len__') and len(pt_data) >= 3:
|
|
||||||
pts.append((float(pt_data[0]), float(pt_data[1]), float(pt_data[2])))
|
|
||||||
else:
|
|
||||||
parse_failures += 1
|
|
||||||
else:
|
|
||||||
parse_failures += 1
|
|
||||||
finally:
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
pts: List[Point3D] = []
|
||||||
|
parse_failures = 0
|
||||||
|
|
||||||
|
# Try each possible API in order
|
||||||
|
eval_func = None
|
||||||
|
eval_style = None
|
||||||
|
|
||||||
|
# Pattern A: uf.Modl.AskCurveProps(tag, param) — normalized 0..1
|
||||||
|
for method_name in ('AskCurveProps', 'ask_curve_props'):
|
||||||
|
fn = getattr(modl, method_name, None)
|
||||||
|
if callable(fn):
|
||||||
|
eval_func = fn
|
||||||
|
eval_style = 'modl_props'
|
||||||
|
_log(f"[edge] Using uf.Modl.{method_name}")
|
||||||
|
break
|
||||||
|
|
||||||
|
# Pattern B: uf.Eval.EvaluateUnitVectors or similar
|
||||||
|
if eval_func is None:
|
||||||
|
for method_name in eval_methods:
|
||||||
|
if 'valuat' in method_name.lower():
|
||||||
|
eval_func = getattr(eval_obj, method_name)
|
||||||
|
eval_style = 'eval_' + method_name
|
||||||
|
_log(f"[edge] Using uf.Eval.{method_name}")
|
||||||
|
break
|
||||||
|
|
||||||
|
# Pattern C: uf.Curve.EvaluateCurve(tag, param, deriv_flag)
|
||||||
|
if eval_func is None:
|
||||||
|
try:
|
||||||
|
curve_obj = uf.Curve
|
||||||
|
for method_name in ('EvaluateCurve', 'evaluate_curve'):
|
||||||
|
fn = getattr(curve_obj, method_name, None)
|
||||||
|
if callable(fn):
|
||||||
|
eval_func = fn
|
||||||
|
eval_style = 'curve_eval'
|
||||||
|
_log(f"[edge] Using uf.Curve.{method_name}")
|
||||||
|
break
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if eval_func is None:
|
||||||
|
raise RuntimeError(f"No UF curve evaluation method found. Modl methods: {modl_methods}, Eval methods: {eval_methods}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
evaluator = None
|
||||||
|
if 'eval_' in (eval_style or ''):
|
||||||
|
evaluator = eval_obj.Initialize2(edge.Tag)
|
||||||
|
limits = eval_obj.AskLimits(evaluator)
|
||||||
|
t0, t1 = float(limits[0]), float(limits[1])
|
||||||
|
|
||||||
|
for i in range(n_pts + 1):
|
||||||
|
param = float(i) / float(n_pts)
|
||||||
|
|
||||||
|
if eval_style == 'modl_props':
|
||||||
|
result = eval_func(edge.Tag, param)
|
||||||
|
elif eval_style == 'curve_eval':
|
||||||
|
# UF_CURVE_evaluate_curve(tag, natural_param, deriv_flag) → output array
|
||||||
|
# For arcs, natural param is in radians; for lines, arc length
|
||||||
|
# Use 0 = just point
|
||||||
|
t = t0 + (t1 - t0) * param if evaluator else param
|
||||||
|
result = eval_func(edge.Tag, t, 0)
|
||||||
|
else:
|
||||||
|
# eval_* method on evaluator
|
||||||
|
t = t0 + (t1 - t0) * param
|
||||||
|
result = eval_func(evaluator, 0, t)
|
||||||
|
|
||||||
|
# Parse result — try multiple formats
|
||||||
|
pt = _parse_eval_point(result)
|
||||||
|
if pt is not None:
|
||||||
|
pts.append(pt)
|
||||||
|
else:
|
||||||
|
parse_failures += 1
|
||||||
|
if parse_failures <= 2:
|
||||||
|
_log(f"[edge] Parse failed at param={param:.3f}, raw type={type(result).__name__}, repr={repr(result)[:200]}")
|
||||||
|
finally:
|
||||||
|
if evaluator is not None:
|
||||||
|
try:
|
||||||
|
eval_obj.Free(evaluator)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
if len(pts) >= 2:
|
if len(pts) >= 2:
|
||||||
_log(f"[edge] sampled via UF_MODL ({len(pts)} pts, {parse_failures} failures)")
|
_log(f"[edge] sampled via {eval_style} ({len(pts)} pts, {parse_failures} failures)")
|
||||||
return pts
|
return pts
|
||||||
|
|
||||||
_log(f"[edge] UF_MODL insufficient points ({len(pts)}), falling back")
|
_log(f"[edge] {eval_style} insufficient points ({len(pts)}), falling back")
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
_log(f"[edge] UF_MODL failed: {exc}")
|
_log(f"[edge] UF curve eval failed: {exc}")
|
||||||
|
|
||||||
# 2) Fallback: IBaseCurve.Evaluate (signature differs by NX versions)
|
# 2) Fallback: IBaseCurve.Evaluate (signature differs by NX versions)
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user