Fillet Feature Edit API Sample

Description

Demonstrates editing a fillet feature.
To successfully run this sample you can use this file or create a new model with the described fillet feature.

  1. Create a new model and add a block feature.
  2. Create a single fillet feature that defines three different fillets. The fillets need to be created in a way where they don't interact with one another. The easiest way is to create the fillets only on the vertical edges of the box.
    1. Create a constant radius fillet with a radius that is about 1/4 the size of the box.
    2. Create a chord length fillet whose radius is also about 1/4 the size of the box.
    3. Create a variable radius fillet with one intermediate radius and the radii are about 1/4 the size of the box and less.
Running the sample script will modify various settings of each fillet and change the edge each fillet is applied to.

Code Samples

import adsk.core, adsk.fusion, traceback

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface

        # Get active design, root component, and timeline.
        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        rootComp = design.rootComponent              
        timeline = design.timeline

        # Get the first fillet feature in the root component.
        fillet: adsk.fusion.FilletFeature = rootComp.features.filletFeatures[0]

        # Roll the timeline to just before the fillet.
        fillet.timelineObject.rollTo(True)

        # Iterate over the edge sets.
        edgeSet: adsk.fusion.FilletEdgeSet = None

        # Save the edges currently used by the edge sets into a list.
        edges = []
        for edgeSet in fillet.edgeSets:
            edges.append(edgeSet.edges[0])

        # Insert the last edge into the first index and remove the last edge.
        edges.insert(0, edges[len(edges)-1])
        edges.pop(len(edges)-1)

        # Process each edge set based on its type.
        for i in range(fillet.edgeSets.count):
            edgeSet = fillet.edgeSets[i]
            if edgeSet.objectType == adsk.fusion.ConstantRadiusFilletEdgeSet.classType():
                # Change the radious of the fillet.
                constantEdgeSet: adsk.fusion.ConstantRadiusFilletEdgeSet = edgeSet
                radiusParam = constantEdgeSet.radius
                radiusParam.value = radiusParam.value / 2.0

                # Toggle the continuity type between tangent and curvature.
                if constantEdgeSet.continuity == adsk.fusion.SurfaceContinuityTypes.TangentSurfaceContinuityType:
                    constantEdgeSet.continuity = adsk.fusion.SurfaceContinuityTypes.CurvatureSurfaceContinuityType
                elif constantEdgeSet.continuity == adsk.fusion.SurfaceContinuityTypes.CurvatureSurfaceContinuityType:
                    constantEdgeSet.continuity = adsk.fusion.SurfaceContinuityTypes.TangentSurfaceContinuityType

                # Change which edge is filleted.
                newEdge = adsk.core.ObjectCollection.create()
                newEdge.add(edges[i])
                constantEdgeSet.edges = newEdge
            elif edgeSet.objectType == adsk.fusion.VariableRadiusFilletEdgeSet.classType():
                variableEdgeSet: adsk.fusion.VariableRadiusFilletEdgeSet = edgeSet
                
                # Swap the values of the start and end radii.
                startRadiusParam = variableEdgeSet.startRadius
                endRadiusParam = variableEdgeSet.endRadius
                startVal = startRadiusParam.value
                startRadiusParam.expression = endRadiusParam.expression
                endRadiusParam.value = startVal

                # Edit the mid positions.
                midPositions = variableEdgeSet.midPositions  
                midRadii = variableEdgeSet.midRadii
                for j in range(0, midPositions.count):
                    # Change the position and radius of the mid positions.
                    pos = midPositions.item(j).value
                    pos = pos + ((1 - pos) * 0.25)
                    midPositions.item(j).value = pos

                    midRadii.item(j).value = midRadii.item(j).value * 1.5
                
                # Add a new position.                    
                newMidPosition = adsk.core.ValueInput.createByReal(0.25)
                newMidRadius = adsk.core.ValueInput.createByReal(startRadiusParam.value * 0.75)
                variableEdgeSet.addMidPosition(newMidPosition, newMidRadius)

                # Toggle the continuity type between tangent and curvature.
                if variableEdgeSet.continuity == adsk.fusion.SurfaceContinuityTypes.TangentSurfaceContinuityType:
                    variableEdgeSet.continuity = adsk.fusion.SurfaceContinuityTypes.CurvatureSurfaceContinuityType
                elif variableEdgeSet.continuity == adsk.fusion.SurfaceContinuityTypes.CurvatureSurfaceContinuityType:
                    variableEdgeSet.continuity = adsk.fusion.SurfaceContinuityTypes.TangentSurfaceContinuityType

                # Change which edge is filleted.
                newEdge = adsk.core.ObjectCollection.create()
                newEdge.add(edges[i])
                variableEdgeSet.edges = newEdge
            elif edgeSet.objectType == adsk.fusion.ChordLengthFilletEdgeSet.classType():
                chordLengthEdgeSet = adsk.fusion.ChordLengthFilletEdgeSet.cast(edgeSet)

                # Edit the chord length.
                chordLengthParam = chordLengthEdgeSet.chordLength
                chordLengthParam.value = chordLengthParam.value * .75

                # Edit the tangency weight.
                tangencyWeightParam = chordLengthEdgeSet.tangencyWeight
                tangencyWeightParam.value = tangencyWeightParam.value / 2                   

                # Toggle the continuity type between tangent and curvature.
                if chordLengthEdgeSet.continuity == adsk.fusion.SurfaceContinuityTypes.TangentSurfaceContinuityType:
                    chordLengthEdgeSet.continuity = adsk.fusion.SurfaceContinuityTypes.CurvatureSurfaceContinuityType
                elif chordLengthEdgeSet.continuity == adsk.fusion.SurfaceContinuityTypes.CurvatureSurfaceContinuityType:
                    chordLengthEdgeSet.continuity = adsk.fusion.SurfaceContinuityTypes.TangentSurfaceContinuityType

                # Change which edge is filleted.
                newEdge = adsk.core.ObjectCollection.create()
                newEdge.add(edges[i])
                chordLengthEdgeSet.edges = newEdge

        # Move the timeline back.
        timeline.moveToEnd()
        
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
#include <Core/Application/Application.h>
#include <Core/UserInterface/UserInterface.h>
#include <Core/Application/ObjectCollection.h>
#include <Core/Application/ValueInput.h>
#include <Core/Application/Document.h>

#include <Fusion/Fusion/Design.h>
#include <Fusion/Fusion/Timeline.h>
#include <Fusion/Fusion/TimelineObject.h>
#include <Fusion/Fusion/ModelParameter.h>
#include <Fusion/Fusion/ParameterList.h>
#include <Fusion/Components/Component.h>
#include <Fusion/Features/Features.h>
#include <Fusion/Features/FilletFeatures.h>
#include <Fusion/Features/FilletFeature.h>
#include <Fusion/Features/FilletFeatureInput.h>
#include <Fusion/Features/FilletEdgeSets.h>
#include <Fusion/Features/ConstantRadiusFilletEdgeSet.h>
#include <Fusion/Features/VariableRadiusFilletEdgeSet.h>
#include <Fusion/Features/ChordLengthFilletEdgeSet.h>
#include <Fusion/Features/AsymmetricFilletEdgeSet.h>
#include <Fusion/BRep/BRepEdge.h>


using namespace adsk::core;
using namespace adsk::fusion;

Ptr<UserInterface> ui;

extern "C" XI_EXPORT bool run(const char* context)
{
    Ptr<Application> app = Application::get();
    if (!app)
        return false;

    ui = app->userInterface();
    if (!ui)
        return false;


    // Get active design
    Ptr<Product> product = app->activeProduct();
    if (!product)
        return false;
    Ptr<Design> design = product;
    if (!design)
        return false;

    // Get root component in this design
    Ptr<Component> rootComp = design->rootComponent();
    if (!rootComp)
        return false;

    // Get the timeline associated with this design
    Ptr<Timeline> timeline = design->timeline();
    if (!timeline)
        return false;

    // Get the first fillet in the design.
    Ptr<Features> features = rootComp->features();
    if (!features)
        return false;
    Ptr<FilletFeatures> fillets = features->filletFeatures();
    if (!fillets)
        return false;
    Ptr<FilletFeature> fillet = fillets->item(0);
    if (!fillet)
        return false;

    // Roll the timeline to just before the fillet.
    Ptr<TimelineObject> timelineObj = fillet->timelineObject();
    if (!timelineObj)
        return false;
    timelineObj->rollTo(true);

    // Change the corner type.
    bool isRollingBallCorner = fillet->isRollingBallCorner();
    fillet->isRollingBallCorner(!isRollingBallCorner);

    // Save the edges currently used by the edge sets into a vector so that they are
    // rotated from the their indexed position. 0 = 1, 1 = 2, 2 = 0.
    Ptr<BRepEdge> edges[3];
    for (int i = 0; i < 3; ++i)
    {
        Ptr<FilletEdgeSet> edgeSet = fillet->edgeSets()->item(i);
        if (!edgeSet)
            return false;
        Ptr<BRepEdge> edge = nullptr;
        if (edgeSet->objectType() == adsk::fusion::ConstantRadiusFilletEdgeSet::classType())
        {
            Ptr<ConstantRadiusFilletEdgeSet> constRadEdgeSet = edgeSet;
            edge = constRadEdgeSet->edges()->item(0);
            if (!edge)
                return false;
        }
        else if (edgeSet->objectType() == adsk::fusion::ChordLengthFilletEdgeSet::classType())
        {
            Ptr<ChordLengthFilletEdgeSet> chordLengthEdgeSet = edgeSet;
            edge = chordLengthEdgeSet->edges()->item(0);
            if (!edge)
                return false;
        }
        else if (edgeSet->objectType() == adsk::fusion::VariableRadiusFilletEdgeSet::classType())
        {
            Ptr<VariableRadiusFilletEdgeSet> varRadEdgeSet = edgeSet;
            edge = varRadEdgeSet->edges()->item(0);
            if (!edge)
                return false;
        }
        else if (edgeSet->objectType() == adsk::fusion::AsymmetricFilletEdgeSet::classType())
        {
            Ptr<AsymmetricFilletEdgeSet> asyFilletEdgeSet = edgeSet;
            edge = asyFilletEdgeSet->edges()->item(0);
            if (!edge)
                return false;
        }

        // Reassign the edge into the new index.
        if (i == 2)
        {
            edges[0] = edge;
        }
        else
        {
            edges[i + 1] = edge;
        }
    }

    // Process each edge set based on its type.
    for (int i = 0; i < 3; ++i)
    {
        Ptr<FilletEdgeSet> edgeSet = fillet->edgeSets()->item(i);
        if (!edgeSet)
            return false;

        if (edgeSet->objectType() == adsk::fusion::ConstantRadiusFilletEdgeSet::classType())
        {
            Ptr<ConstantRadiusFilletEdgeSet> constRadEdgeSet = edgeSet;

            // Change the radius of the fillet.
            Ptr<ModelParameter> radiusParam = constRadEdgeSet->radius();
            if (!radiusParam)
                return false;
            radiusParam->value(radiusParam->value() / 2.0);

            // Toggle the continuity type between tangent and curvature.
            if (constRadEdgeSet->continuity() == adsk::fusion::SurfaceContinuityTypes::TangentSurfaceContinuityType)
            {
                constRadEdgeSet->continuity(adsk::fusion::SurfaceContinuityTypes::CurvatureSurfaceContinuityType);
            }
            else if (
                constRadEdgeSet->continuity() == adsk::fusion::SurfaceContinuityTypes::CurvatureSurfaceContinuityType)
            {
                constRadEdgeSet->continuity(adsk::fusion::SurfaceContinuityTypes::TangentSurfaceContinuityType);
            }

            // Change which edge is filleted.
            Ptr<ObjectCollection> newEdge = adsk::core::ObjectCollection::create();
            if (!newEdge)
                return false;
            newEdge->add(edges[i]);
            bool ret = constRadEdgeSet->edges(newEdge);
        }
        else if (edgeSet->objectType() == adsk::fusion::ChordLengthFilletEdgeSet::classType())
        {
            Ptr<ChordLengthFilletEdgeSet> chordLengthEdgeSet = edgeSet;

            // Edit the chord length.
            Ptr<ModelParameter> chordLengthParam = chordLengthEdgeSet->chordLength();
            if (!chordLengthParam)
                return false;
            chordLengthParam->value(chordLengthParam->value() * 0.75);

            // Edit the tangency weight.
            Ptr<ModelParameter> tangencyWeightParam = chordLengthEdgeSet->tangencyWeight();
            if (!tangencyWeightParam)
                return false;
            tangencyWeightParam->value(tangencyWeightParam->value() / 2.0);

            // Toggle the continuity type between tangent and curvature.
            if (chordLengthEdgeSet->continuity() == adsk::fusion::SurfaceContinuityTypes::TangentSurfaceContinuityType)
            {
                chordLengthEdgeSet->continuity(adsk::fusion::SurfaceContinuityTypes::CurvatureSurfaceContinuityType);
            }
            else if (
                chordLengthEdgeSet->continuity() ==
                adsk::fusion::SurfaceContinuityTypes::CurvatureSurfaceContinuityType)
            {
                chordLengthEdgeSet->continuity(adsk::fusion::SurfaceContinuityTypes::TangentSurfaceContinuityType);
            }

            // Change which edge is filleted.
            Ptr<ObjectCollection> newEdge = adsk::core::ObjectCollection::create();
            if (!newEdge)
                return false;
            newEdge->add(edges[i]);
            chordLengthEdgeSet->edges(newEdge);
        }
        else if (edgeSet->objectType() == adsk::fusion::VariableRadiusFilletEdgeSet::classType())
        {
            Ptr<VariableRadiusFilletEdgeSet> variableEdgeSet = edgeSet;

            // Swap the values of the start and end radii.
            Ptr<ModelParameter> startRadiusParam = variableEdgeSet->startRadius();
            if (!startRadiusParam)
                return false;
            Ptr<ModelParameter> endRadiusParam = variableEdgeSet->endRadius();
            if (!endRadiusParam)
                return false;
            double startVal = startRadiusParam->value();
            startRadiusParam->expression(endRadiusParam->expression());
            endRadiusParam->value(startVal);

            // Edit the mid positions.
            Ptr<ParameterList> midPositions = variableEdgeSet->midPositions();
            if (!midPositions)
                return false;
            Ptr<ParameterList> midRadii = variableEdgeSet->midRadii();
            if (!midRadii)
                return false;
            for (int j = 0; j < midPositions->count(); ++j)
            {
                // Change the position and radius of the mid positions.
                double pos = midPositions->item(j)->value();
                pos = pos + ((1 - pos) * 0.25);
                midPositions->item(j)->value(pos);

                midRadii->item(j)->value(midRadii->item(j)->value() * 1.5);
            }

            // Add a new position.
            Ptr<ValueInput> newMidPosition = adsk::core::ValueInput::createByReal(0.25);
            if (!newMidPosition)
                return false;
            Ptr<ValueInput> newMidRadius = adsk::core::ValueInput::createByReal(startRadiusParam->value() * 0.75);
            if (!newMidRadius)
                return false;
            variableEdgeSet->addMidPosition(newMidPosition, newMidRadius);

            // Toggle the continuity type between tangent and curvature.
            if (variableEdgeSet->continuity() == adsk::fusion::SurfaceContinuityTypes::TangentSurfaceContinuityType)
            {
                variableEdgeSet->continuity(adsk::fusion::SurfaceContinuityTypes::CurvatureSurfaceContinuityType);
            }
            else if (
                variableEdgeSet->continuity() == adsk::fusion::SurfaceContinuityTypes::CurvatureSurfaceContinuityType)
            {
                variableEdgeSet->continuity(adsk::fusion::SurfaceContinuityTypes::TangentSurfaceContinuityType);
            }

            // Change which edge is filleted.
            Ptr<ObjectCollection> newEdge = adsk::core::ObjectCollection::create();
            if (!newEdge)
                return false;
            newEdge->add(edges[i]);
            variableEdgeSet->edges(newEdge);
        }
    }

    // Move the timeline back.
    timeline->moveToEnd();


    return true;
}
/**
 * Fillet Feature Edit API Sample
 * Demonstrates editing a fillet feature. To successfully run this sample you can use this file or create a new model with the described fillet feature. Create a new model and add a block feature. Create a single fillet...
 */

import {adsk} from '@adsk/fusion'

function run() {

      // Get the Fusion API's application object
      const app = adsk.core.Application.get();
      if (!app) throw Error("No adsk.core.Application.");
  
      // Create a document.
      const design = app.activeProduct as adsk.fusion.Design
  
      // Get the root component of the active design.
      const rootComp = design.rootComponent

      //Get the timeline
      const timeline = design.timeline

      // Get the first fillet feature in the root component.
      const fillet: adsk.fusion.FilletFeature = rootComp.features.filletFeatures.item(0)
      // Roll the timeline to just before the fillet.
      fillet.timelineObject.rollTo(true)


      // Save the edges currently used by the edge sets into a list.
        const edges = []
        for (let i=0; i < fillet.edgeSets.count; i++) {
            const edgeSet = fillet.edgeSets.item(i)
            edges.push(edgeSet.edges.item(0))
        }

        // Insert the last edge into the first index and remove the last edge.
        edges.unshift(edges[edges.length - 1])
        edges.pop()

        // Process each edge set based on its type.
        for (let i=0; i < fillet.edgeSets.count; i++){
            const edgeSet = fillet.edgeSets.item(i)
            
            if (edgeSet instanceof adsk.fusion.ConstantRadiusFilletEdgeSet){
                // Change the radious of the fillet.
                const constantEdgeSet: adsk.fusion.ConstantRadiusFilletEdgeSet = edgeSet
                const radiusParam = constantEdgeSet.radius
                radiusParam.value = radiusParam.value / 2.0

                // Toggle the continuity type between tangent and curvature.
                if (constantEdgeSet.continuity == adsk.fusion.SurfaceContinuityTypes.TangentSurfaceContinuityType){
                    constantEdgeSet.continuity = adsk.fusion.SurfaceContinuityTypes.CurvatureSurfaceContinuityType}
                else if (constantEdgeSet.continuity == adsk.fusion.SurfaceContinuityTypes.CurvatureSurfaceContinuityType){
                    constantEdgeSet.continuity = adsk.fusion.SurfaceContinuityTypes.TangentSurfaceContinuityType}

                // Change which edge is filleted.
                const newEdge = adsk.core.ObjectCollection.create()
                newEdge.add(edges[i])
                constantEdgeSet.edges = newEdge}
            else if (edgeSet instanceof adsk.fusion.VariableRadiusFilletEdgeSet){
                const variableEdgeSet: adsk.fusion.VariableRadiusFilletEdgeSet = edgeSet
                
                // Swap the values of the start and end radii.
                const startRadiusParam = variableEdgeSet.startRadius
                const endRadiusParam = variableEdgeSet.endRadius
                const startVal = startRadiusParam.value
                startRadiusParam.expression = endRadiusParam.expression
                endRadiusParam.value = startVal

                // Edit the mid positions.
                const midPositions = variableEdgeSet.midPositions  
                const midRadii = variableEdgeSet.midRadii
                for (let i=0; i < midPositions.count; i++){
                  let pos = midPositions.item(i).value
                  pos = pos + ((1 - pos) * 0.25)
                  midPositions.item(i).value = pos
                  midRadii.item(i).value = midRadii.item(i).value * 1.5
                
                }
                
                // Add a new position.                    
                const newMidPosition = adsk.core.ValueInput.createByReal(0.25)
                const newMidRadius = adsk.core.ValueInput.createByReal(startRadiusParam.value * 0.75)
                variableEdgeSet.addMidPosition(newMidPosition, newMidRadius)

                // Toggle the continuity type between tangent and curvature.
                if (variableEdgeSet.continuity == adsk.fusion.SurfaceContinuityTypes.TangentSurfaceContinuityType){
                    variableEdgeSet.continuity = adsk.fusion.SurfaceContinuityTypes.CurvatureSurfaceContinuityType}
                else if  (variableEdgeSet.continuity == adsk.fusion.SurfaceContinuityTypes.CurvatureSurfaceContinuityType){
                    variableEdgeSet.continuity = adsk.fusion.SurfaceContinuityTypes.TangentSurfaceContinuityType}

                // Change which edge is filleted.
                const newEdge = adsk.core.ObjectCollection.create()
                newEdge.add(edges[i])
                variableEdgeSet.edges = newEdge}
            else if (edgeSet instanceof adsk.fusion.ChordLengthFilletEdgeSet){
                const chordLengthEdgeSet = edgeSet as adsk.fusion.ChordLengthFilletEdgeSet

                // Edit the chord length.
                const chordLengthParam = chordLengthEdgeSet.chordLength
                chordLengthParam.value = chordLengthParam.value * .75

                // Edit the tangency weight.
                const tangencyWeightParam = chordLengthEdgeSet.tangencyWeight
                tangencyWeightParam.value = tangencyWeightParam.value / 2                   

                // Toggle the continuity type between tangent and curvature.
                if (chordLengthEdgeSet.continuity == adsk.fusion.SurfaceContinuityTypes.TangentSurfaceContinuityType){
                    chordLengthEdgeSet.continuity = adsk.fusion.SurfaceContinuityTypes.CurvatureSurfaceContinuityType}
                else if (chordLengthEdgeSet.continuity == adsk.fusion.SurfaceContinuityTypes.CurvatureSurfaceContinuityType){
                    chordLengthEdgeSet.continuity = adsk.fusion.SurfaceContinuityTypes.TangentSurfaceContinuityType}

                // Change which edge is filleted.
                const newEdge = adsk.core.ObjectCollection.create()
                newEdge.add(edges[i])
                chordLengthEdgeSet.edges = newEdge}
        }

        // Move the timeline back.
        timeline.moveToEnd()
}

run();