Community
Fusion API and Scripts
Got a new add-in to share? Need something specialized to be scripted? Ask questions or share what you’ve discovered with the community.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Combine/cut script problem

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
brad.bylls
419 Views, 4 Replies

Combine/cut script problem

See video attached that explains the problem.

Here is the script.

import adsk.core, adsk.fusion, traceback
import math

# Globals
_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)
strResult = ''

_handlers = []

def run(context):
    try:
        global _app, _ui
        _app = adsk.core.Application.get()
        _ui  = _app.userInterface

        cmdDef = _ui.commandDefinitions.itemById('adskSpurGearPythonScript')
        if not cmdDef:
            # Create a command definition.
            cmdDef = _ui.commandDefinitions.addButtonDefinition('adskSpurGearPythonScript', 'Spur Gear', 'Creates a spur gear component', '') 
        
        # Connect to the command created event.
        onCommandCreated = SketchCommandCreatedHandler()
        cmdDef.commandCreated.add(onCommandCreated)
        _handlers.append(onCommandCreated)
        
        # Execute the command.
        cmdDef.execute()

        # prevent this module from being terminate when the script returns, because we are waiting for event handlers to fire
        adsk.autoTerminate(False)
    except:
        if _ui:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

class SketchCommandDestroyHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.CommandEventArgs.cast(args)

            # when the command is done, terminate the script
            # this will release all globals which will remove all event handlers
            adsk.terminate()
        except:
            if _ui:
                _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

# Event handler for the commandCreated event.
class SketchCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.CommandCreatedEventArgs.cast(args)
            
            cmd = eventArgs.command
            cmd.isExecutedWhenPreEmpted = False
            inputs = cmd.commandInputs
            
            global root, features

            design = _app.activeProduct
            root = design.rootComponent
            features = root.features

            # Verify that a Fusion design is active.
            if not design:
                _ui.messageBox('A Fusion design must be active when invoking this command.')
                return()

            cmd.okButtonText = ("Make the Cuts") # text in "OK" button
            cmd.isExecutedWhenPreEmpted = False

            # Create the command dialog
            _inputSelectTargets = inputs.addSelectionInput('target', 'Target Bodies', 'Select the Bodies\nThat Will Be Cut')
            _inputSelectTargets.addSelectionFilter(adsk.core.SelectionCommandInput.Bodies)
            _inputSelectTargets.setSelectionLimits(0)

            _inputSelectTools = inputs.addSelectionInput('tool', 'Tool Bodies', 'Select the Bodies\nThat Will Do The Cutting')
            _inputSelectTools.addSelectionFilter(adsk.core.SelectionCommandInput.Bodies)
            _inputSelectTools.setSelectionLimits(0)

            _inputHideTools = inputs.addBoolValueInput('hideTools', 'Hide Tool Bodies?', True)

            _inputErrMessage = inputs.addTextBoxCommandInput('errMessage', '', '', 2, True)
            _inputErrMessage.isFullWidth = True
            
            # Connect to the command related events.
            onExecute = SketchCommandExecuteHandler()
            cmd.execute.add(onExecute)
            _handlers.append(onExecute)        
            
            onInputChanged = SketchCommandInputChangedHandler()
            cmd.inputChanged.add(onInputChanged)
            _handlers.append(onInputChanged)    
            
            onValidateInputs = SketchCommandValidateInputsHandler()
            cmd.validateInputs.add(onValidateInputs)
            _handlers.append(onValidateInputs)

            onDestroy = SketchCommandDestroyHandler()
            cmd.destroy.add(onDestroy)
            _handlers.append(onDestroy)

        except:
            if _ui:
                _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

# Event handler for the execute event.
class SketchCommandExecuteHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.CommandEventArgs.cast(args)
            inputs = eventArgs.command.commandInputs

            target_input = inputs.itemById('target').selectionCount
            tool_input = inputs.itemById('tool').selectionCount
            toolBodies = adsk.core.ObjectCollection.create()

            for x in range (0, target_input):
                targetBody = inputs.itemById('target').selection(x).entity

                toolBodies.clear()
                toolBody = None
                for y in range (0, tool_input):
                    toolBody = inputs.itemById('tool').selection(y).entity  # Problem line 130
                    toolBodies.add(toolBody)

                CombineCutInput = root.features.combineFeatures.createInput(targetBody, toolBodies)
                CombineCutFeats = features.combineFeatures
                CombineCutInput = CombineCutFeats.createInput(targetBody, toolBodies)
                CombineCutInput.operation = adsk.fusion.FeatureOperations.CutFeatureOperation
                CombineCutInput.isKeepToolBodies = True
                CombineCutFeats.add(CombineCutInput)

            if inputs['hideTools'] == True:
                for z in range (0, tool_input):
                    toolBodies.item(z).isVisible = False
        except:
            if _ui:
                _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))   
        
# Event handler for the inputChanged event.
class SketchCommandInputChangedHandler(adsk.core.InputChangedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.InputChangedEventArgs.cast(args)
            changedInput = eventArgs.input
            inputs :adsk.core.CommandInputs = eventArgs.inputs
            
            if changedInput.id == 'target':
                selection_input = inputs.itemById('target')
                # selection_input.hasFocus = True
            elif changedInput.id == 'tool':
                selection_input = inputs.itemById('tool')

        except:
            if _ui:
                _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))     
        
# Event handler for the validateInputs event.
class SketchCommandValidateInputsHandler(adsk.core.ValidateInputsEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.ValidateInputsEventArgs.cast(args)
            
            if strResult != ' ':
                return True
            else:
                return False

        except:
            if _ui:
                _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
  
Brad Bylls
4 REPLIES 4
Message 2 of 5
kandennti
in reply to: brad.bylls

Hi @brad.bylls .

 

It seems that the Tool's SelectionCommandInput is cleared when the first Cut is performed.

Therefore, if I create the ObjectCollection of Tools in advance and process it, no error occurs.

# Event handler for the execute event.
class SketchCommandExecuteHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.CommandEventArgs.cast(args)
            inputs = eventArgs.command.commandInputs

            # tools
            toolBodies = adsk.core.ObjectCollection.create()
            tool_input: adsk.core.SelectionCommandInput = inputs.itemById('tool')
            for idx in range(0, tool_input.selectionCount):
                toolBodies.add(tool_input.selection(idx).entity)

            # CombineCut
            target_input: adsk.core.SelectionCommandInput = inputs.itemById('target')
            for idx in range(0, target_input.selectionCount):
                targetBody = target_input.selection(idx).entity

                CombineCutInput = root.features.combineFeatures.createInput(targetBody, toolBodies)
                CombineCutFeats = features.combineFeatures
                CombineCutInput = CombineCutFeats.createInput(targetBody, toolBodies)
                CombineCutInput.operation = adsk.fusion.FeatureOperations.CutFeatureOperation
                CombineCutInput.isKeepToolBodies = True
                CombineCutFeats.add(CombineCutInput)

            # hide tools
            hideTools: adsk.core.BoolValueCommandInput = inputs.itemById('hideTools')
            if hideTools.value:
                for entity in toolBodies:
                    entity.isVisible = False

        except:
            if _ui:
                _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
Message 3 of 5
brad.bylls
in reply to: kandennti

Wow.

That works great.

I never would have thought of that.

You are a genius.

Thank you so much.

Now I can finish my add-in.

Brad Bylls
Message 4 of 5
MichaelT_123
in reply to: brad.bylls

Hi Mr BradBylls,

 

Could we dream that the problem you solved in your script would be found in a future version of the standard F360 combine tool?

 

Regards

MichaelT

MichaelT
Message 5 of 5
brad.bylls
in reply to: MichaelT_123

Thanks Mike. 

I would hope so.

Seems foolish that it wasn't that way to begin with. 

Brad Bylls

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report