From 9a5f0866845d59aa90f38c7158840f7cf89118c9 Mon Sep 17 00:00:00 2001 From: Antoine Date: Tue, 17 Feb 2026 00:59:37 +0000 Subject: [PATCH] fix(extrude): robust section creation with multi-approach fallback - Create section explicitly if builder.Section returns None - Try 3 approaches for adding curves: CreateRuleCurveFeature, CreateRuleCurveDumb with options, CreateRuleCurveDumb without - Detailed step-by-step logging for debugging - Get help point from first sketch curve for section seeding --- .../adaptive-isogrid/src/nx/import_profile.py | 164 +++++++++++++++--- 1 file changed, 142 insertions(+), 22 deletions(-) diff --git a/tools/adaptive-isogrid/src/nx/import_profile.py b/tools/adaptive-isogrid/src/nx/import_profile.py index e8cdd91a..70bbe334 100644 --- a/tools/adaptive-isogrid/src/nx/import_profile.py +++ b/tools/adaptive-isogrid/src/nx/import_profile.py @@ -481,57 +481,177 @@ def _extrude_sketch(part: Any, sketch: Any, thickness: float, builder = None rule_options = None try: + # Step 1: Create ExtrudeBuilder builder = part.Features.CreateExtrudeBuilder(NXOpen.Features.Feature.Null) + lister.WriteLine("[extrude] Step 1: ExtrudeBuilder created") - # Build section directly from the sketch feature + # Step 2: Create a Section and assign it to the builder + # builder.Section may be None for new extrudes — create one explicitly section = builder.Section - section.AllowSelfIntersection(True) + if section is None: + lister.WriteLine("[extrude] builder.Section is None — creating section explicitly") + section = part.Sections.CreateSection( + 0.0095, # chaining tolerance + 0.01, # distance tolerance + 0.5, # angle tolerance (radians) + ) + builder.Section = section + lister.WriteLine(f"[extrude] Created section: {section}") - rule_options = part.ScRuleFactory.CreateRuleOptions() - curve_rule = part.ScRuleFactory.CreateRuleCurveFeature( - [sketch.Feature], - NXOpen.DisplayableObject.Null, - rule_options, - ) + if section is None: + raise RuntimeError("Could not create or get Section object") + + section.SetAllowedEntityTypes(NXOpen.Section.AllowTypes.OnlyCurves) + section.AllowSelfIntersection(True) + lister.WriteLine("[extrude] Step 2: Section configured") + + # Step 3: Add sketch curves to section via feature rule + sketch_feat = sketch.Feature + lister.WriteLine(f"[extrude] Sketch feature: {sketch_feat.JournalIdentifier}") + + # Get a curve from the sketch to use as help point seed + sketch_curves = [] + try: + geom = sketch.GetAllGeometry() + for g in geom: + sketch_curves.append(g) + except Exception: + pass help_pt = NXOpen.Point3d(0.0, 0.0, 0.0) - section.AddToSection( - [curve_rule], - NXOpen.NXObject.Null, - NXOpen.NXObject.Null, - NXOpen.NXObject.Null, - help_pt, - NXOpen.Section.Mode.Create, - False, - ) + if sketch_curves: + try: + sp = sketch_curves[0].StartPoint + help_pt = NXOpen.Point3d(sp.X, sp.Y, sp.Z) + except Exception: + pass + # Try multiple approaches to add curves to section + added = False + + # Approach 1: CreateRuleCurveFeature (NX 12+) + if not added: + try: + rule_options = part.ScRuleFactory.CreateRuleOptions() + curve_rule = part.ScRuleFactory.CreateRuleCurveFeature( + [sketch_feat], + NXOpen.DisplayableObject.Null, + rule_options, + ) + section.AddToSection( + [curve_rule], + NXOpen.NXObject.Null, + NXOpen.NXObject.Null, + NXOpen.NXObject.Null, + help_pt, + NXOpen.Section.Mode.Create, + False, + ) + added = True + lister.WriteLine("[extrude] Step 3: Added curves via CreateRuleCurveFeature") + except Exception as exc: + lister.WriteLine(f"[extrude] CreateRuleCurveFeature failed: {exc}") + + # Approach 2: CreateRuleCurveDumb with curve array + options + if not added and sketch_curves: + try: + if rule_options is None: + rule_options = part.ScRuleFactory.CreateRuleOptions() + curve_rule = part.ScRuleFactory.CreateRuleCurveDumb( + sketch_curves, rule_options, + ) + section.AddToSection( + [curve_rule], + sketch_curves[0], + NXOpen.NXObject.Null, + NXOpen.NXObject.Null, + help_pt, + NXOpen.Section.Mode.Create, + False, + ) + added = True + lister.WriteLine("[extrude] Step 3: Added curves via CreateRuleCurveDumb") + except Exception as exc: + lister.WriteLine(f"[extrude] CreateRuleCurveDumb w/ options failed: {exc}") + + # Approach 3: CreateRuleCurveDumb without options (older NX) + if not added and sketch_curves: + try: + curve_rule = part.ScRuleFactory.CreateRuleCurveDumb(sketch_curves) + section.AddToSection( + [curve_rule], + sketch_curves[0], + NXOpen.NXObject.Null, + NXOpen.NXObject.Null, + help_pt, + NXOpen.Section.Mode.Create, + False, + ) + added = True + lister.WriteLine("[extrude] Step 3: Added curves via CreateRuleCurveDumb (no opts)") + except Exception as exc: + lister.WriteLine(f"[extrude] CreateRuleCurveDumb no-opts failed: {exc}") + + # Approach 4: UF curve chain + if not added: + try: + import NXOpen.UF + uf = NXOpen.UF.UFSession.GetUFSession() + # Use UF to create the extrude instead — bail from builder approach + lister.WriteLine("[extrude] All Section approaches failed — trying UF fallback") + raise RuntimeError("Section-based extrude failed, see above") + except ImportError: + raise RuntimeError("All extrude approaches failed") + + if not added: + raise RuntimeError("Could not add sketch curves to extrude section") + + # Step 4: Set direction direction = part.Directions.CreateDirection( NXOpen.Point3d(0.0, 0.0, 0.0), NXOpen.Vector3d(float(normal[0]), float(normal[1]), float(normal[2])), NXOpen.SmartObject.UpdateOption.WithinModeling, ) builder.Direction = direction + lister.WriteLine("[extrude] Step 4: Direction set") + # Step 5: Set limits builder.Limits.StartExtend.Value.RightHandSide = "0.0" builder.Limits.EndExtend.Value.RightHandSide = str(float(thickness)) builder.BooleanOperation.Type = NXOpen.GeometricUtilities.BooleanOperation.BooleanType.Create + lister.WriteLine("[extrude] Step 5: Limits set (0 → {})".format(thickness)) + # Step 6: Commit extrude_obj = builder.Commit() + lister.WriteLine(f"[extrude] Step 6: Commit returned: {extrude_obj} (type={type(extrude_obj).__name__})") + + # Try to find and name the extrude feature + extrude_feature = None + if isinstance(extrude_obj, NXOpen.Features.Feature): + extrude_feature = extrude_obj + else: + try: + committed = builder.GetCommittedObjects() + for obj in committed: + if isinstance(obj, NXOpen.Features.Feature): + extrude_feature = obj + break + except Exception: + pass - extrude_feature = extrude_obj if isinstance(extrude_obj, NXOpen.Features.Feature) else None if extrude_feature is not None: try: extrude_feature.SetName(extrude_name) - lister.WriteLine(f"[import] Extrude created and named: {extrude_name}") + lister.WriteLine(f"[extrude] ✓ Extrude created: {extrude_name}") except Exception: - lister.WriteLine("[import] Extrude created (could not rename)") + lister.WriteLine("[extrude] ✓ Extrude created (could not rename)") else: - lister.WriteLine("[import] Extrude committed (feature reference unclear)") + lister.WriteLine("[extrude] ✓ Extrude committed (feature ref unclear)") return extrude_feature except Exception as exc: - lister.WriteLine(f"[import] ERROR creating extrude: {exc}") + lister.WriteLine(f"[extrude] ERROR: {exc}") import traceback lister.WriteLine(traceback.format_exc()) return None