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
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user