Subtracting bodies with combineFeature (adsk api)

Subtracting bodies with combineFeature (adsk api)

bacjoel
Explorer Explorer
161 Views
3 Replies
Message 1 of 4

Subtracting bodies with combineFeature (adsk api)

bacjoel
Explorer
Explorer

Hello,

 

I'd like to ask for help with regards to the combineFeature.

 

In short: I have created multiple bodies independently via an extrusion process through the adsk api (I use python). The goal is to subtract these extruded bodies from an original body.

 

Problem: The code I have tried did not lead to the desired result. The bodies are not subtracted. I am not sure if the bodies are accessed correctly by the code, or if the combineFeature is not applied correctly.

 

I would be very grateful to receive some help.

 

Here my code:

 

        # Combine bodies into a single body

        bodies = rootComp.BRepBodies

        target_body = bodies.item[0]    # The original body to subtract from
        tools = bodies.item[1:]  # Collection of bodies to subtract from the original body
       
        combine_feature = rootComp.features.combineFeatures.create()
       
       
        # Create the combine input
        combine_input = combine_feature.createInput(target_body, tools)
        combine_input.operation = 1
        combine_input.isKeepToolBodies = False
        combine_input.isKeepTargetBody = False
        combine_input.isNewComponent = True  # keep only the resulting body

        combine_features.add(combine_input)
 
Many thanks in advance!
 
0 Likes
Accepted solutions (1)
162 Views
3 Replies
Replies (3)
Message 2 of 4

kandennti
Mentor
Mentor
Accepted solution

Hi @bacjoel -san.

 

I made several corrections.
I think the biggest problem is that tools need to be kept as ObjectCollection objects.

# Fusion360API Python script

import traceback
import adsk
import adsk.core as core
import adsk.fusion as fusion

def run(context):
    ui: core.UserInterface = None
    try:
        app: core.Application = core.Application.get()
        ui = app.userInterface
        des: fusion.Design = app.activeProduct
        rootComp: fusion.Component = des.rootComponent
        combine_features: fusion.CombineFeatures = rootComp.features.combineFeatures

        # Combine bodies into a single body

        # bodies = rootComp.BRepBodies
        bodies = rootComp.bRepBodies

        # target_body = bodies.item[0]    # The original body to subtract from
        target_body = bodies.item(0) # or bodies[0]
        # tools = bodies.item[1:]  # Collection of bodies to subtract from the original body
        tools: core.ObjectCollection = core.ObjectCollection.createWithArray(
            list(bodies)[1:] 
        )
       
        # combine_feature = rootComp.features.combineFeatures.create()
        combine_feature = rootComp.features.combineFeatures
       
        # Create the combine input
        combine_input: fusion.CombineFeatureInput = combine_feature.createInput(
            target_body, 
            tools
        )
        combine_input.operation = 1
        combine_input.isKeepToolBodies = False
        # combine_input.isKeepTargetBody = False
        combine_input.isNewComponent = True  # keep only the resulting body
 
        combine_features.add(combine_input)

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
0 Likes
Message 3 of 4

bacjoel
Explorer
Explorer
 
many thanks for the quick answer - I really appreciate it!
 
In the meantime, I spend some more time on this issue and implemented your advice.
 
I created this test code with joined circles, in case anyone else needs an example to test their basic code.
 
Have a good weekend and best regards!
 
 
Test Code:
"""This file acts as the main module for this script."""

import traceback
import adsk.core
import adsk.fusion
# import adsk.cam

# Initialize the global variables for the Application and UserInterface objects.
app = adsk.core.Application.get()
ui  = app.userInterface


def run(_context: str):
    """This function is called by Fusion when the script is run."""

    try:
        # Your code goes here.

        doc = app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
        design = app.activeProduct

        # Get the root component of the active design.
        rootComp = design.rootComponent

        # Create a new sketch on the xy plane.
        sketches = rootComp.sketches
        xyPlane = rootComp.xYConstructionPlane
        sketch1 = sketches.add(xyPlane)
        sketch2 = sketches.add(xyPlane)
        sketch3 = sketches.add(xyPlane)
        sketch4 = sketches.add(xyPlane)

        # Circels in sketch.
        circles_sketch1 = sketch1.sketchCurves.sketchCircles
        circles_sketch2 = sketch2.sketchCurves.sketchCircles
        circles_sketch3 = sketch3.sketchCurves.sketchCircles
        circles_sketch4 = sketch4.sketchCurves.sketchCircles


        circle1 = circles_sketch1.addByCenterRadius(adsk.core.Point3D.create(0, 0, 0), 10)
        circle2 = circles_sketch2.addByCenterRadius(adsk.core.Point3D.create(10, 0, 0), 10)
        circle3 = circles_sketch3.addByCenterRadius(adsk.core.Point3D.create(25, 0, 0), 10)
        circle4 = circles_sketch4.addByCenterRadius(adsk.core.Point3D.create(0, 15, 0), 15)



        t = 1
        t_wall = 0.5

        extrudeFeatures = rootComp.features.extrudeFeatures
        distance = adsk.core.ValueInput.createByReal(t)
        isFullLength = True

        operation = adsk.fusion.FeatureOperations.NewBodyFeatureOperation
        wallLocation = adsk.fusion.ThinExtrudeWallLocation.Center
        wallThickness = adsk.core.ValueInput.createByReal(t_wall)    

        profile_part1 = sketch1.profiles.item(0)
        profile_part2 = sketch2.profiles.item(0)  
        profile_part3 = sketch3.profiles.item(0)
        profile_part4 = sketch4.profiles.item(0)                  
       
        # Define the required input
        input = extrudeFeatures.createInput(profile_part1, operation)
        input.setThinExtrude(wallLocation, wallThickness)
        input.setSymmetricExtent(distance, isFullLength)

        extrudeFeatures.add(input)

        input2 = extrudeFeatures.createInput(profile_part2, operation)
        input2.setThinExtrude(wallLocation, wallThickness)
        input2.setSymmetricExtent(distance, isFullLength)
       
        extrudeFeatures.add(input2)

        input3 = extrudeFeatures.createInput(profile_part3, operation)
        input3.setThinExtrude(wallLocation, wallThickness)
        input3.setSymmetricExtent(distance, isFullLength)
       
        extrudeFeatures.add(input3)

        input4 = extrudeFeatures.createInput(profile_part4, operation)
        input4.setThinExtrude(wallLocation, wallThickness)
        input4.setSymmetricExtent(distance, isFullLength)
       
        extrudeFeatures.add(input4)


        # Have the two bodies selected.
        targetBody = rootComp.bRepBodies.item(0)  # The first body is the part boundary
        tools = adsk.core.ObjectCollection.create()
        j = 1  # Start from the second body
        while j <= rootComp.bRepBodies.count-2:
            tools.add(rootComp.bRepBodies.item(j))
            j += 1

        # toolBody = rootComp.bRepBodies.item(1)  # The body to subtract
        # toolBody2 = rootComp.bRepBodies.item(2)  # The body to subtract

        # Define the required inputs and create te combine feature.
        combineFeatures = rootComp.features.combineFeatures
        input: adsk.fusion.CombineFeatureInput = combineFeatures.createInput(targetBody, tools)
        input.isNewComponent = False
        input.isKeepToolBodies = False
        input.operation = 0
        combineFeature = combineFeatures.add(input)


        # Intersect the combined Voronoi body with the part boundary
        combineFeatures = rootComp.features.combineFeatures
        targetBody_boundary = rootComp.bRepBodies.item(0)  # The first body is the part boundary
        tools_boundary = adsk.core.ObjectCollection.create()
        tools_boundary.add(rootComp.bRepBodies.item(1))  # Add the combined Voronoi body

        input: adsk.fusion.CombineFeatureInput = combineFeatures.createInput(targetBody_boundary, tools_boundary)
        input.isNewComponent = False
        input.isKeepToolBodies = False
        input.operation = 0
        combineFeature = combineFeatures.add(input)


       
    except:  #pylint:disable=bare-except
        # Write the error message to the TEXT COMMANDS window.
        app.log(f'Failed:\n{traceback.format_exc()}')
Message 4 of 4

bacjoel
Explorer
Explorer

Hi kandennti

 

Many thanks for helping out! It was possible to make it work.

Meanwhile, I create a test script with intersecting circles in case anyone else needs it to their code:

"""This file acts as the main module for this script."""

import traceback
import adsk.core
import adsk.fusion
# import adsk.cam

# Initialize the global variables for the Application and UserInterface objects.
app = adsk.core.Application.get()
ui  = app.userInterface


def run(_context: str):
    """This function is called by Fusion when the script is run."""

    try:
        # Your code goes here.

        doc = app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
        design = app.activeProduct

        # Get the root component of the active design.
        rootComp = design.rootComponent

        # Create a new sketch on the xy plane.
        sketches = rootComp.sketches
        xyPlane = rootComp.xYConstructionPlane
        sketch1 = sketches.add(xyPlane)
        sketch2 = sketches.add(xyPlane)
        sketch3 = sketches.add(xyPlane)
        sketch4 = sketches.add(xyPlane)

        # Circels in sketch.
        circles_sketch1 = sketch1.sketchCurves.sketchCircles
        circles_sketch2 = sketch2.sketchCurves.sketchCircles
        circles_sketch3 = sketch3.sketchCurves.sketchCircles
        circles_sketch4 = sketch4.sketchCurves.sketchCircles


        circle1 = circles_sketch1.addByCenterRadius(adsk.core.Point3D.create(0, 0, 0), 10)
        circle2 = circles_sketch2.addByCenterRadius(adsk.core.Point3D.create(10, 0, 0), 10)
        circle3 = circles_sketch3.addByCenterRadius(adsk.core.Point3D.create(25, 0, 0), 10)
        circle4 = circles_sketch4.addByCenterRadius(adsk.core.Point3D.create(0, 15, 0), 15)



        t = 1
        t_wall = 0.5

        extrudeFeatures = rootComp.features.extrudeFeatures
        distance = adsk.core.ValueInput.createByReal(t)
        isFullLength = True

        operation = adsk.fusion.FeatureOperations.NewBodyFeatureOperation
        wallLocation = adsk.fusion.ThinExtrudeWallLocation.Center
        wallThickness = adsk.core.ValueInput.createByReal(t_wall)     

        profile_part1 = sketch1.profiles.item(0)
        profile_part2 = sketch2.profiles.item(0)  
        profile_part3 = sketch3.profiles.item(0)
        profile_part4 = sketch4.profiles.item(0)                  
        
        # Define the required input
        input = extrudeFeatures.createInput(profile_part1, operation)
        input.setThinExtrude(wallLocation, wallThickness)
        input.setSymmetricExtent(distance, isFullLength)

        extrudeFeatures.add(input)

        input2 = extrudeFeatures.createInput(profile_part2, operation)
        input2.setThinExtrude(wallLocation, wallThickness)
        input2.setSymmetricExtent(distance, isFullLength)
        
        extrudeFeatures.add(input2)

        input3 = extrudeFeatures.createInput(profile_part3, operation)
        input3.setThinExtrude(wallLocation, wallThickness)
        input3.setSymmetricExtent(distance, isFullLength)
        
        extrudeFeatures.add(input3)

        input4 = extrudeFeatures.createInput(profile_part4, operation)
        input4.setThinExtrude(wallLocation, wallThickness)
        input4.setSymmetricExtent(distance, isFullLength)
        
        extrudeFeatures.add(input4)


        # Have the two bodies selected.
        targetBody = rootComp.bRepBodies.item(0)  # The first body is the part boundary
        tools = adsk.core.ObjectCollection.create()
        j = 1  # Start from the second body
        while j <= rootComp.bRepBodies.count-2:
            tools.add(rootComp.bRepBodies.item(j))
            j += 1

        # toolBody = rootComp.bRepBodies.item(1)  # The body to subtract
        # toolBody2 = rootComp.bRepBodies.item(2)  # The body to subtract

        # Define the required inputs and create te combine feature.
        combineFeatures = rootComp.features.combineFeatures
        input: adsk.fusion.CombineFeatureInput = combineFeatures.createInput(targetBody, tools)
        input.isNewComponent = False
        input.isKeepToolBodies = False
        input.operation = 0
        combineFeature = combineFeatures.add(input)


        # Intersect the combined Voronoi body with the part boundary
        combineFeatures = rootComp.features.combineFeatures
        targetBody_boundary = rootComp.bRepBodies.item(0)  # The first body is the part boundary
        tools_boundary = adsk.core.ObjectCollection.create()
        tools_boundary.add(rootComp.bRepBodies.item(1))  # Add the combined Voronoi body

        input: adsk.fusion.CombineFeatureInput = combineFeatures.createInput(targetBody_boundary, tools_boundary)
        input.isNewComponent = False
        input.isKeepToolBodies = False
        input.operation = 0
        combineFeature = combineFeatures.add(input)


        
    except:  #pylint:disable=bare-except
        # Write the error message to the TEXT COMMANDS window.
        app.log(f'Failed:\n{traceback.format_exc()}')

 

I wish a good week and best regards!

0 Likes