From 515eef145f04730d20546d2f76b85c2e8714e412 Mon Sep 17 00:00:00 2001 From: Antoine Date: Mon, 16 Feb 2026 23:36:14 +0000 Subject: [PATCH] feat(import_profile): use ReplaceFeatureBuilder for sketch replacement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces naive ReplaceEntity approach with NX's proper ReplaceFeatureBuilder API. This mirrors the interactive right-click → Replace Feature workflow: - SelectFeature: old sketch to replace - ReplacementFeature: new sketch taking over - DoAutomaticGeomMatch: auto-maps curves - DeleteOriginalFeature: removes old after remap - Fallback: manual delete if builder fails All downstream features (extrude, trim) automatically re-reference the new sketch. --- .../adaptive-isogrid/src/nx/import_profile.py | 87 ++++++++++++++----- 1 file changed, 64 insertions(+), 23 deletions(-) diff --git a/tools/adaptive-isogrid/src/nx/import_profile.py b/tools/adaptive-isogrid/src/nx/import_profile.py index cbf4a244..2dce7f41 100644 --- a/tools/adaptive-isogrid/src/nx/import_profile.py +++ b/tools/adaptive-isogrid/src/nx/import_profile.py @@ -95,37 +95,78 @@ def _find_old_sketch_feature(part: Any, sketch_name: str, lister: Any): def _replace_and_delete_old_sketch(part: Any, old_feature: Any, new_feature: Any, lister: Any): """ - Replace all references from old sketch feature to new one, then delete old. - Uses NX Edit > Feature > Replace Feature approach. + Replace old sketch with new one using NX's ReplaceFeatureBuilder. + + This mirrors the interactive: right-click sketch → Replace Feature. + All downstream features (extrude, trim, etc.) automatically re-reference + the new sketch. The old sketch is deleted after replacement. + + API: NXOpen.Features.ReplaceFeatureBuilder + - SelectFeature → original feature to replace + - ReplacementFeature → new feature that takes over + - DeleteOriginalFeature → True (remove old after remap) + - DoAutomaticGeomMatch → True (auto-match edges/curves) + - AutomatchMap() → run the auto-matching + - Commit() → execute the replacement """ import NXOpen session = NXOpen.Session.GetSession() + mark = session.SetUndoMark(NXOpen.Session.MarkVisibility.Visible, + "Replace isogrid sketch") - # Try to replace references from old → new try: - # Get all parent features that reference the old sketch (e.g. Extrude) - parents = old_feature.GetParents() - if parents: - lister.WriteLine(f"[import] Old sketch has {len(parents)} parent feature(s) — replacing references") - for parent in parents: - try: - parent.ReplaceEntity(old_feature, new_feature) - lister.WriteLine(f"[import] Replaced reference in {parent.JournalIdentifier}") - except Exception as exc: - lister.WriteLine(f"[import] Could not replace in {parent.JournalIdentifier}: {exc}") - except Exception as exc: - lister.WriteLine(f"[import] Warning getting parents: {exc}") + # Create the ReplaceFeatureBuilder + builder = part.Features.CreateReplaceFeatureBuilder( + NXOpen.Features.Feature.Null + ) + + # Set the original feature (old sketch) to be replaced + added_old = builder.SelectFeature.Add(old_feature) + lister.WriteLine(f"[import] Set original feature: {old_feature.JournalIdentifier}") + + # Set the replacement feature (new sketch) + added_new = builder.ReplacementFeature.Add(new_feature) + lister.WriteLine(f"[import] Set replacement feature: {new_feature.JournalIdentifier}") + + # Configuration + builder.DeleteOriginalFeature = True + builder.DoAutomaticGeomMatch = True + + # Run automatic geometry matching (maps old curves → new curves) + try: + builder.AutomatchMap() + lister.WriteLine("[import] Auto-match mapping completed") + except Exception as exc: + lister.WriteLine(f"[import] Auto-match warning (may still work): {exc}") + + # Update the mapping + try: + builder.UpdateMap() + except Exception as exc: + lister.WriteLine(f"[import] UpdateMap note: {exc}") + + # Commit the replacement + builder.Commit() + lister.WriteLine("[import] ReplaceFeature committed — all references updated") + + builder.Destroy() - # Delete the old sketch feature - try: - mark = session.SetUndoMark(NXOpen.Session.MarkVisibility.Visible, "Delete old isogrid sketch") - nErrs = session.UpdateManager.AddToDeleteList(old_feature) - nErrs2 = session.UpdateManager.DoUpdate(mark) - lister.WriteLine(f"[import] Deleted old sketch feature ({nErrs + nErrs2} warnings)") except Exception as exc: - lister.WriteLine(f"[import] Warning deleting old sketch: {exc}") - lister.WriteLine(f"[import] You may need to manually delete the old sketch") + lister.WriteLine(f"[import] ReplaceFeatureBuilder failed: {exc}") + lister.WriteLine("[import] Falling back to manual delete + re-reference...") + + # Fallback: just delete the old sketch + # Downstream features (extrude) will go into "out of date" state + # and need manual re-selection of the new sketch section + try: + nErrs = session.UpdateManager.AddToDeleteList(old_feature) + nErrs2 = session.UpdateManager.DoUpdate(mark) + lister.WriteLine(f"[import] Deleted old sketch ({nErrs + nErrs2} warnings)") + lister.WriteLine("[import] ⚠ Extrude may need manual sketch re-selection") + except Exception as exc2: + lister.WriteLine(f"[import] Delete also failed: {exc2}") + lister.WriteLine("[import] ⚠ Manually delete old sketch and fix extrude") def _find_or_create_sketch(