"""Fold Feature API sample — exercises every public interface on FoldFeatures, FoldFeatureInput, FoldBendLineDefinitions, FoldBendLineDefinition (temporary and persistent), and FoldFeature. The document must contain: - A sheet metal body at bRepBodies.item(0) - A flat face suitable as the stationary face (faces.item(0) by default) - A sketch at sketches.item(0) with at least two sketch lines Adjust STATIONARY_FACE_IDX, LINE0_IDX, and LINE1_IDX to match your document. """ import traceback import math import adsk.core import adsk.fusion app = adsk.core.Application.get() ui = app.userInterface TOLERANCE = 1.0e-6 BEND_ANGLE_DEG = 90.0 BEND_ANGLE_RAD = math.radians(BEND_ANGLE_DEG) STATIONARY_FACE_IDX = 9 LINE0_IDX = 0 LINE1_IDX = 1 # --------------------------------------------------------------------------- # Helpers # --------------------------------------------------------------------------- def backToNow(design): design.timeline.moveToEnd() def clearFoldFeatures(features): """Delete all fold features so edge/face indices are stable.""" ff = features.foldFeatures while ff.count > 0: ff.item(0).deleteMe() ff = features.foldFeatures assert ff.count == 0 return ff # --------------------------------------------------------------------------- # FoldFeatureInput properties (temporary state) # --------------------------------------------------------------------------- def testFoldFeatureInputProperties(foldFeatures, face, line0): """Tests all FoldFeatureInput and temporary FoldBendLineDefinition APIs.""" inp = foldFeatures.createInput(face) assert inp is not None, "createInput returned None" # stationaryFace getter assert inp.stationaryFace is not None, "stationaryFace getter returned None" # isUseCornerRelief get/set inp.isUseCornerRelief = True assert inp.isUseCornerRelief is True inp.isUseCornerRelief = False assert inp.isUseCornerRelief is False # bendLines collection bendLines = inp.bendLines assert bendLines is not None # Add a bend line definition. angleVal = adsk.core.ValueInput.createByReal(BEND_ANGLE_RAD) def0 = bendLines.add( line0, angleVal, adsk.fusion.FoldBendLinePositionTypes.StartFoldBendLinePositionType, True) assert def0 is not None, "bendLines.add returned None" # isTemporary must be True for temporary definitions. assert def0.isTemporary is True # bendLine getter assert def0.bendLine is not None # bendAngle must be None for temporary definitions. assert def0.bendAngle is None, "bendAngle should be None on temporary definition" # bendAngleValue get/set — available on temporary definitions. bav = def0.bendAngleValue assert bav is not None, "bendAngleValue should not be None on temporary definition" newAngle = adsk.core.ValueInput.createByReal(math.radians(45.0)) def0.bendAngleValue = newAngle assert def0.bendAngleValue is not None # Restore to 90 degrees. def0.bendAngleValue = adsk.core.ValueInput.createByReal(BEND_ANGLE_RAD) # linePosition get/set — exercise all three enum values. for pos in [ adsk.fusion.FoldBendLinePositionTypes.StartFoldBendLinePositionType, adsk.fusion.FoldBendLinePositionTypes.CenterFoldBendLinePositionType, adsk.fusion.FoldBendLinePositionTypes.EndFoldBendLinePositionType, ]: def0.linePosition = pos assert def0.linePosition == pos, f"linePosition mismatch for {pos}" # Reset to Start. def0.linePosition = adsk.fusion.FoldBendLinePositionTypes.StartFoldBendLinePositionType # isBendReliefAllowed get/set. def0.isBendReliefAllowed = False assert def0.isBendReliefAllowed is False def0.isBendReliefAllowed = True assert def0.isBendReliefAllowed is True # count/item on the temporary collection. assert bendLines.count == 1 assert bendLines.item(0) is not None # Identity before parameter change: repeated item() calls return the same object. assert bendLines.item(0) == bendLines.item(0), "Temporary definition identity failed" item_before_change = bendLines.item(0) assert item_before_change == def0 # Change bend angle value and verify identity is preserved. def0.bendAngleValue = adsk.core.ValueInput.createByReal(1.047) # ~60 deg assert bendLines.item(0) == bendLines.item(0), "Temporary identity broken after angle change" assert bendLines.item(0) == item_before_change, "Temporary identity changed after angle setter" # Change line position and verify identity is preserved. def0.linePosition = adsk.fusion.FoldBendLinePositionTypes.CenterFoldBendLinePositionType assert bendLines.item(0) == bendLines.item(0), "Temporary identity broken after linePosition change" assert bendLines.item(0) == item_before_change, "Temporary identity changed after linePosition setter" # Change isBendReliefAllowed and verify identity is preserved. def0.isBendReliefAllowed = False assert bendLines.item(0) == bendLines.item(0), "Temporary identity broken after isBendReliefAllowed change" assert bendLines.item(0) == item_before_change, "Temporary identity changed after isBendReliefAllowed setter" # Restore to original values. def0.bendAngleValue = adsk.core.ValueInput.createByReal(1.5708) # 90 deg def0.linePosition = adsk.fusion.FoldBendLinePositionTypes.StartFoldBendLinePositionType def0.isBendReliefAllowed = True # deleteMe on a temporary bend line definition. assert def0.deleteMe(), "deleteMe on temporary definition failed" assert bendLines.count == 0 # --------------------------------------------------------------------------- # Create a FoldFeature (two bend lines) # --------------------------------------------------------------------------- def testCreateFoldFeature(foldFeatures, face, line0, line1): """Creates a persistent FoldFeature and checks collection APIs.""" inp = foldFeatures.createInput(face) assert inp is not None bendLines = inp.bendLines assert bendLines is not None angleVal = adsk.core.ValueInput.createByReal(BEND_ANGLE_RAD) bl0 = bendLines.add( line0, angleVal, adsk.fusion.FoldBendLinePositionTypes.StartFoldBendLinePositionType, True) assert bl0 is not None bl1 = bendLines.add( line1, adsk.core.ValueInput.createByReal(BEND_ANGLE_RAD), adsk.fusion.FoldBendLinePositionTypes.StartFoldBendLinePositionType, True) assert bl1 is not None feature = foldFeatures.add(inp) assert feature is not None, "foldFeatures.add returned None" featureName = feature.name assert featureName is not None and len(featureName) > 0 # nativeObject is None in the root component context. assert feature.nativeObject is None # FoldFeatures collection. assert foldFeatures.count >= 1 assert foldFeatures.item(0) is not None found = foldFeatures.itemByName(featureName) assert found is not None, f"itemByName('{featureName}') returned None" return feature # --------------------------------------------------------------------------- # Persistent FoldFeature and FoldBendLineDefinition properties # --------------------------------------------------------------------------- def testPersistentFeatureProperties(feature, foldFeatures, design): """Exercises persistent FoldFeature and FoldBendLineDefinition APIs.""" # stationaryFace getter. assert feature.stationaryFace is not None # bendLines on the persistent feature. persistentBendLines = feature.bendLines assert persistentBendLines is not None assert persistentBendLines.count == 2 # Identity: repeated item() calls on the same index must return the same object. assert persistentBendLines.item(0) == persistentBendLines.item(0), "Persistent definition identity failed (index 0)" assert persistentBendLines.item(1) == persistentBendLines.item(1), "Persistent definition identity failed (index 1)" assert persistentBendLines.item(0) != persistentBendLines.item(1), "Distinct indices must not be equal" # Roll timeline to just before the feature for editing. tl = feature.timelineObject assert tl is not None tl.rollTo(True) # isUseCornerRelief setter. feature.isUseCornerRelief = True assert feature.isUseCornerRelief is True feature.isUseCornerRelief = False assert feature.isUseCornerRelief is False # stationaryFace setter (set to the same face to confirm the path works). origFace = feature.stationaryFace feature.stationaryFace = origFace assert feature.stationaryFace is not None # Persistent FoldBendLineDefinition. pDef = persistentBendLines.item(0) assert pDef is not None # isTemporary must be False for persistent definitions. assert pDef.isTemporary is False # bendAngle (ModelParameter) — available on persistent definitions. bendAngleParam = pDef.bendAngle assert bendAngleParam is not None, "bendAngle should not be None on persistent definition" assert not math.isnan(bendAngleParam.value) # bendAngleValue must be None for persistent definitions. assert pDef.bendAngleValue is None, "bendAngleValue should be None on persistent definition" # bendLine getter. assert pDef.bendLine is not None # Capture once; identity must hold before and after every parameter change. def_item = persistentBendLines.item(0) assert def_item == persistentBendLines.item(0), "Persistent identity failed before change" assert persistentBendLines.item(0) == persistentBendLines.item(0), "Persistent identity failed before change" # Change bend angle via the ModelParameter and verify identity is preserved. bend_angle_param = pDef.bendAngle assert bend_angle_param is not None bend_angle_param.value = 1.047 # ~60 deg assert def_item == persistentBendLines.item(0), "Persistent identity failed after angle change (60 deg)" bend_angle_param.value = 1.5708 # restore to 90 deg assert def_item == persistentBendLines.item(0), "Persistent identity failed after angle restore (90 deg)" # linePosition get/set — verify identity after each change. for pos in [ adsk.fusion.FoldBendLinePositionTypes.CenterFoldBendLinePositionType, adsk.fusion.FoldBendLinePositionTypes.StartFoldBendLinePositionType, adsk.fusion.FoldBendLinePositionTypes.EndFoldBendLinePositionType, ]: pDef.linePosition = pos assert pDef.linePosition == pos, f"persistent linePosition mismatch for {pos}" assert def_item == persistentBendLines.item(0), f"Persistent identity failed after linePosition change to {pos}" # Reset to Start. pDef.linePosition = adsk.fusion.FoldBendLinePositionTypes.StartFoldBendLinePositionType # isBendReliefAllowed get/set — verify identity after each toggle. pDef.isBendReliefAllowed = False assert pDef.isBendReliefAllowed is False assert def_item == persistentBendLines.item(0), "Persistent identity failed after isBendReliefAllowed=False" pDef.isBendReliefAllowed = True assert pDef.isBendReliefAllowed is True assert def_item == persistentBendLines.item(0), "Persistent identity failed after isBendReliefAllowed=True" backToNow(design) # Verify changes persisted after rolling forward. assert pDef.isTemporary is False assert pDef.linePosition == adsk.fusion.FoldBendLinePositionTypes.StartFoldBendLinePositionType assert pDef.isBendReliefAllowed is True # --------------------------------------------------------------------------- # Add and delete a bend line on a persistent feature # --------------------------------------------------------------------------- def testBendLineAddAndDelete(feature, line1, design): """Adds a bend line to a persistent feature via bendLines.add, then deletes it.""" tl = feature.timelineObject assert tl is not None tl.rollTo(True) persistentBendLines = feature.bendLines countBefore = persistentBendLines.count newDef = persistentBendLines.add( line1, adsk.core.ValueInput.createByReal(BEND_ANGLE_RAD), adsk.fusion.FoldBendLinePositionTypes.StartFoldBendLinePositionType, True) assert newDef is not None, "bendLines.add on persistent feature returned None" persistentBendLines = feature.bendLines assert persistentBendLines.count == countBefore + 1 # Delete the newly added bend line. lastDef = persistentBendLines.item(persistentBendLines.count - 1) assert lastDef is not None assert lastDef.deleteMe(), "deleteMe on persistent bend line definition failed" persistentBendLines = feature.bendLines assert persistentBendLines.count == countBefore backToNow(design) # --------------------------------------------------------------------------- # Collection methods and feature deletion # --------------------------------------------------------------------------- def testCollectionAndDeletion(features, featureName): """Verifies FoldFeatures collection APIs and feature deletion.""" foldFeatures = features.foldFeatures initialCount = foldFeatures.count assert initialCount >= 1 # Iterate the collection. for i in range(initialCount): feat = foldFeatures.item(i) assert feat is not None # itemByName for a name that doesn't exist. assert foldFeatures.itemByName("NonExistentFoldFeature_XYZ") is None # Delete the feature identified by name. feat = foldFeatures.itemByName(featureName) assert feat is not None assert feat.deleteMe(), "feature.deleteMe() failed" foldFeatures = features.foldFeatures assert foldFeatures.count == initialCount - 1 # --------------------------------------------------------------------------- # Entry point # --------------------------------------------------------------------------- def run(_context): """Entry point called by Fusion when the script is run.""" try: design = adsk.fusion.Design.cast(app.activeProduct) rootComp = design.rootComponent # The body and sketch live in component1, the only child of the root component. occurrence = rootComp.occurrences.item(0) assert occurrence is not None, "No child occurrence found under root component" comp1 = occurrence.component assert comp1 is not None, "Could not get component from occurrence" features = comp1.features # Start clean. foldFeatures = clearFoldFeatures(features) body = comp1.bRepBodies.item(0) assert body is not None, "No body found; open a document with a sheet metal body" face = body.faces.item(STATIONARY_FACE_IDX) assert face is not None, f"No face at index {STATIONARY_FACE_IDX}" sketch = rootComp.sketches.item(0) assert sketch is not None, "No sketch found; open a document with a sketch" sketchLines = sketch.sketchCurves.sketchLines line0 = sketchLines.item(LINE0_IDX) line1 = sketchLines.item(LINE1_IDX) assert line0 is not None, f"No sketch line at index {LINE0_IDX}" assert line1 is not None, f"No sketch line at index {LINE1_IDX}" testFoldFeatureInputProperties(foldFeatures, face, line0) feature = testCreateFoldFeature(foldFeatures, face, line0, line1) featureName = feature.name testPersistentFeatureProperties(feature, foldFeatures, design) testBendLineAddAndDelete(feature, line1, design) testCollectionAndDeletion(features, featureName) app.log('FoldSample completed successfully.') except Exception: app.log(f'Failed:\n{traceback.format_exc()}')
// Fold Feature API sample — exercises every public interface on // FoldFeatures, FoldFeatureInput, FoldBendLineDefinitions, // FoldBendLineDefinition (temporary and persistent), and FoldFeature. // // The document must contain: // component1 (first child occurrence of the root component): // - a sheet metal body at bRepBodies.item(0) // - faces.item(STATIONARY_FACE_IDX) suitable as the stationary face // root component: // - a sketch at sketches.item(0) with at least two sketch lines // // Adjust STATIONARY_FACE_IDX, LINE0_IDX, and LINE1_IDX to match your document. #include <Core/CoreAll.h> #include <Fusion/FusionAll.h> using namespace adsk::core; using namespace adsk::fusion; static const size_t STATIONARY_FACE_IDX = 9; static const size_t LINE0_IDX = 0; static const size_t LINE1_IDX = 1; static const double BEND_ANGLE_RAD = 1.5707963267948966; // 90 degrees Ptr<Application> app; #define CHECK(expr) \ if (!(expr)) \ { \ app->log("FAIL: " #expr); \ return false; \ } #define CHECK_PTR(ptr) CHECK((ptr) != nullptr) // --------------------------------------------------------------------------- // Helpers // --------------------------------------------------------------------------- static bool backToNow(const Ptr<Design>& design) { auto tl = design->timeline(); CHECK_PTR(tl); CHECK(tl->moveToEnd()); return true; } static bool clearFoldFeatures(const Ptr<Features>& features) { auto foldFeatures = features->foldFeatures(); CHECK_PTR(foldFeatures); while (foldFeatures->count() > 0) { auto feat = foldFeatures->item(0); CHECK_PTR(feat); CHECK(feat->deleteMe()); foldFeatures = features->foldFeatures(); CHECK_PTR(foldFeatures); } CHECK(foldFeatures->count() == 0); return true; } // --------------------------------------------------------------------------- // FoldFeatureInput properties (temporary state) // --------------------------------------------------------------------------- static bool testFoldFeatureInputProperties( const Ptr<FoldFeatures>& foldFeatures, const Ptr<BRepFace>& face, const Ptr<SketchLine>& line0) { auto inp = foldFeatures->createInput(face); CHECK_PTR(inp); // stationaryFace getter CHECK_PTR(inp->stationaryFace()); // isUseCornerRelief get/set CHECK(inp->isUseCornerRelief(true)); CHECK(inp->isUseCornerRelief()); CHECK(inp->isUseCornerRelief(false)); CHECK(!inp->isUseCornerRelief()); // bendLines collection auto bendLines = inp->bendLines(); CHECK_PTR(bendLines); // Add a bend line definition auto def0 = bendLines->add( line0, ValueInput::createByReal(BEND_ANGLE_RAD), FoldBendLinePositionTypes::StartFoldBendLinePositionType, true); CHECK_PTR(def0); // isTemporary must be true for temporary definitions CHECK(def0->isTemporary()); // bendLine getter CHECK_PTR(def0->bendLine()); // bendAngle must be null for temporary definitions CHECK(!def0->bendAngle()); // bendAngleValue — available on temporary definitions CHECK_PTR(def0->bendAngleValue()); // bendAngleValue setter — change to 45 deg, then restore to 90 deg CHECK(def0->bendAngleValue(ValueInput::createByReal(0.7853981633974483))); CHECK_PTR(def0->bendAngleValue()); CHECK(def0->bendAngleValue(ValueInput::createByReal(BEND_ANGLE_RAD))); // linePosition get/set — exercise all three enum values CHECK(def0->linePosition(FoldBendLinePositionTypes::StartFoldBendLinePositionType)); CHECK(def0->linePosition() == FoldBendLinePositionTypes::StartFoldBendLinePositionType); CHECK(def0->linePosition(FoldBendLinePositionTypes::CenterFoldBendLinePositionType)); CHECK(def0->linePosition() == FoldBendLinePositionTypes::CenterFoldBendLinePositionType); CHECK(def0->linePosition(FoldBendLinePositionTypes::EndFoldBendLinePositionType)); CHECK(def0->linePosition() == FoldBendLinePositionTypes::EndFoldBendLinePositionType); // Reset to Start CHECK(def0->linePosition(FoldBendLinePositionTypes::StartFoldBendLinePositionType)); // isBendReliefAllowed get/set CHECK(def0->isBendReliefAllowed(false)); CHECK(!def0->isBendReliefAllowed()); CHECK(def0->isBendReliefAllowed(true)); CHECK(def0->isBendReliefAllowed()); // count/item on the temporary collection CHECK(bendLines->count() == 1); CHECK_PTR(bendLines->item(0)); // Identity before parameter change: repeated item() calls return the same object CHECK(bendLines->item(0) == bendLines->item(0)); auto itemBeforeChange = bendLines->item(0); CHECK(itemBeforeChange == def0); // Change bend angle value and verify identity is preserved CHECK(def0->bendAngleValue(ValueInput::createByReal(1.047))); // ~60 deg CHECK(bendLines->item(0) == bendLines->item(0)); CHECK(bendLines->item(0) == itemBeforeChange); // Change line position and verify identity is preserved CHECK(def0->linePosition(FoldBendLinePositionTypes::CenterFoldBendLinePositionType)); CHECK(bendLines->item(0) == bendLines->item(0)); CHECK(bendLines->item(0) == itemBeforeChange); // Change isBendReliefAllowed and verify identity is preserved CHECK(def0->isBendReliefAllowed(false)); CHECK(bendLines->item(0) == bendLines->item(0)); CHECK(bendLines->item(0) == itemBeforeChange); // Restore to original values CHECK(def0->bendAngleValue(ValueInput::createByReal(1.5708))); // 90 deg CHECK(def0->linePosition(FoldBendLinePositionTypes::StartFoldBendLinePositionType)); CHECK(def0->isBendReliefAllowed(true)); // deleteMe on a temporary bend line definition CHECK(def0->deleteMe()); CHECK(bendLines->count() == 0); return true; } // --------------------------------------------------------------------------- // Create a FoldFeature (two bend lines) // --------------------------------------------------------------------------- static bool testCreateFoldFeature( const Ptr<FoldFeatures>& foldFeatures, const Ptr<BRepFace>& face, const Ptr<SketchLine>& line0, const Ptr<SketchLine>& line1, Ptr<FoldFeature>& outFeature) { auto inp = foldFeatures->createInput(face); CHECK_PTR(inp); auto bendLines = inp->bendLines(); CHECK_PTR(bendLines); auto bl0 = bendLines->add( line0, ValueInput::createByReal(BEND_ANGLE_RAD), FoldBendLinePositionTypes::StartFoldBendLinePositionType, true); CHECK_PTR(bl0); auto bl1 = bendLines->add( line1, ValueInput::createByReal(BEND_ANGLE_RAD), FoldBendLinePositionTypes::StartFoldBendLinePositionType, true); CHECK_PTR(bl1); auto feature = foldFeatures->add(inp); CHECK_PTR(feature); auto featureName = feature->name(); CHECK(!featureName.empty()); // nativeObject is null in the root component context CHECK(!feature->nativeObject()); // FoldFeatures collection CHECK(foldFeatures->count() >= 1); CHECK_PTR(foldFeatures->item(0)); CHECK_PTR(foldFeatures->itemByName(featureName)); outFeature = feature; return true; } // --------------------------------------------------------------------------- // Persistent FoldFeature and FoldBendLineDefinition properties // --------------------------------------------------------------------------- static bool testPersistentFeatureProperties( const Ptr<FoldFeature>& feature, const Ptr<BRepFace>& stationaryFace, const Ptr<Design>& design) { // stationaryFace getter CHECK_PTR(feature->stationaryFace()); // bendLines on the persistent feature auto persistentBendLines = feature->bendLines(); CHECK_PTR(persistentBendLines); CHECK(persistentBendLines->count() == 2); // Identity: repeated item() calls on the same index must return the same object CHECK(persistentBendLines->item(0) == persistentBendLines->item(0)); CHECK(persistentBendLines->item(1) == persistentBendLines->item(1)); CHECK(persistentBendLines->item(0) != persistentBendLines->item(1)); // Roll timeline to just before the feature for editing auto tl = feature->timelineObject(); CHECK_PTR(tl); CHECK(tl->rollTo(true)); // isUseCornerRelief setter CHECK(feature->isUseCornerRelief(true)); CHECK(feature->isUseCornerRelief()); CHECK(feature->isUseCornerRelief(false)); CHECK(!feature->isUseCornerRelief()); // stationaryFace setter (set to the same face to confirm the path works) CHECK(feature->stationaryFace(stationaryFace)); CHECK_PTR(feature->stationaryFace()); // Persistent FoldBendLineDefinition auto apiDef = persistentBendLines->item(0); CHECK_PTR(apiDef); auto persistentDef = apiDef->cast<FoldBendLineDefinition>(); CHECK_PTR(persistentDef); // isTemporary must be false for persistent definitions CHECK(!persistentDef->isTemporary()); // bendAngle (ModelParameter) — available on persistent definitions CHECK_PTR(persistentDef->bendAngle()); // bendAngleValue must be null for persistent definitions CHECK(!persistentDef->bendAngleValue()); // bendLine getter CHECK_PTR(persistentDef->bendLine()); // Capture once; identity must hold before and after every parameter change auto defItem = persistentBendLines->item(0); CHECK(defItem == persistentBendLines->item(0)); CHECK(persistentBendLines->item(0) == persistentBendLines->item(0)); // Change bend angle via the ModelParameter and verify identity is preserved auto bendAngleParam = persistentDef->bendAngle(); CHECK_PTR(bendAngleParam); CHECK(bendAngleParam->value(1.047)); // ~60 deg CHECK(defItem == persistentBendLines->item(0)); CHECK(bendAngleParam->value(1.5708)); // restore to 90 deg CHECK(defItem == persistentBendLines->item(0)); // linePosition get/set — exercise all three enum values CHECK(persistentDef->linePosition(FoldBendLinePositionTypes::CenterFoldBendLinePositionType)); CHECK(persistentDef->linePosition() == FoldBendLinePositionTypes::CenterFoldBendLinePositionType); CHECK(defItem == persistentBendLines->item(0)); CHECK(persistentDef->linePosition(FoldBendLinePositionTypes::StartFoldBendLinePositionType)); CHECK(persistentDef->linePosition() == FoldBendLinePositionTypes::StartFoldBendLinePositionType); CHECK(defItem == persistentBendLines->item(0)); CHECK(persistentDef->linePosition(FoldBendLinePositionTypes::EndFoldBendLinePositionType)); CHECK(persistentDef->linePosition() == FoldBendLinePositionTypes::EndFoldBendLinePositionType); CHECK(defItem == persistentBendLines->item(0)); // Reset to Start CHECK(persistentDef->linePosition(FoldBendLinePositionTypes::StartFoldBendLinePositionType)); // isBendReliefAllowed get/set — verify identity after each toggle CHECK(persistentDef->isBendReliefAllowed(false)); CHECK(!persistentDef->isBendReliefAllowed()); CHECK(defItem == persistentBendLines->item(0)); CHECK(persistentDef->isBendReliefAllowed(true)); CHECK(persistentDef->isBendReliefAllowed()); CHECK(defItem == persistentBendLines->item(0)); // Roll forward to the end, then verify changes persisted CHECK(backToNow(design)); CHECK(!persistentDef->isTemporary()); CHECK(persistentDef->linePosition() == FoldBendLinePositionTypes::StartFoldBendLinePositionType); CHECK(persistentDef->isBendReliefAllowed()); return true; } // --------------------------------------------------------------------------- // Add and delete a bend line on a persistent feature // --------------------------------------------------------------------------- static bool testBendLineAddAndDelete( const Ptr<FoldFeature>& feature, const Ptr<SketchLine>& line1, const Ptr<Design>& design) { auto tl = feature->timelineObject(); CHECK_PTR(tl); CHECK(tl->rollTo(true)); auto persistentBendLines = feature->bendLines(); CHECK_PTR(persistentBendLines); auto countBefore = persistentBendLines->count(); auto newDef = persistentBendLines->add( line1, ValueInput::createByReal(BEND_ANGLE_RAD), FoldBendLinePositionTypes::StartFoldBendLinePositionType, true); CHECK_PTR(newDef); persistentBendLines = feature->bendLines(); CHECK_PTR(persistentBendLines); CHECK(persistentBendLines->count() == countBefore + 1); // Delete the newly added bend line auto lastDef = persistentBendLines->item(persistentBendLines->count() - 1); CHECK_PTR(lastDef); CHECK(lastDef->deleteMe()); persistentBendLines = feature->bendLines(); CHECK_PTR(persistentBendLines); CHECK(persistentBendLines->count() == countBefore); CHECK(backToNow(design)); return true; } // --------------------------------------------------------------------------- // Collection methods and feature deletion // --------------------------------------------------------------------------- static bool testCollectionAndDeletion(const Ptr<Features>& features, const std::string& featureName) { auto foldFeatures = features->foldFeatures(); CHECK_PTR(foldFeatures); auto initialCount = foldFeatures->count(); CHECK(initialCount >= 1); // Iterate the collection for (size_t i = 0; i < initialCount; ++i) CHECK_PTR(foldFeatures->item(i)); // itemByName for a name that does not exist CHECK(!foldFeatures->itemByName("NonExistentFoldFeature_XYZ")); // Delete the feature identified by name auto feat = foldFeatures->itemByName(featureName); CHECK_PTR(feat); CHECK(feat->deleteMe()); foldFeatures = features->foldFeatures(); CHECK_PTR(foldFeatures); CHECK(foldFeatures->count() == initialCount - 1); return true; } // --------------------------------------------------------------------------- // Entry point // --------------------------------------------------------------------------- extern "C" XI_EXPORT bool run(const char* context) { app = Application::get(); if (!app) return false; auto product = app->activeProduct(); CHECK_PTR(product); auto design = product->cast<Design>(); CHECK_PTR(design); auto rootComp = design->rootComponent(); CHECK_PTR(rootComp); // The body and sketch live in component1, the first child occurrence of root. auto occurrences = rootComp->occurrences(); CHECK_PTR(occurrences); auto occurrence = occurrences->item(0); CHECK_PTR(occurrence); auto comp1 = occurrence->component(); CHECK_PTR(comp1); // Sheet metal body is in comp1. auto bodies = comp1->bRepBodies(); CHECK_PTR(bodies); auto body = bodies->item(0); CHECK_PTR(body); auto faces = body->faces(); CHECK_PTR(faces); auto stationaryFace = faces->item(STATIONARY_FACE_IDX); CHECK_PTR(stationaryFace); // Sketch is in the root component. auto sketches = rootComp->sketches(); CHECK_PTR(sketches); auto sketch = sketches->item(0); CHECK_PTR(sketch); auto sketchLines = sketch->sketchCurves()->sketchLines(); CHECK_PTR(sketchLines); auto line0 = sketchLines->item(LINE0_IDX); auto line1 = sketchLines->item(LINE1_IDX); CHECK_PTR(line0); CHECK_PTR(line1); auto features = comp1->features(); CHECK_PTR(features); // Start clean — delete any existing fold features. CHECK(clearFoldFeatures(features)); auto foldFeatures = features->foldFeatures(); CHECK_PTR(foldFeatures); CHECK(testFoldFeatureInputProperties(foldFeatures, stationaryFace, line0)); Ptr<FoldFeature> feature; CHECK(testCreateFoldFeature(foldFeatures, stationaryFace, line0, line1, feature)); auto featureName = feature->name(); CHECK(testPersistentFeatureProperties(feature, stationaryFace, design)); CHECK(testBendLineAddAndDelete(feature, line1, design)); CHECK(testCollectionAndDeletion(features, featureName)); app->log("FoldSample completed successfully."); return true; }