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: 

How do I cut an occurrence out of a component?

4 REPLIES 4
Reply
Message 1 of 5
the.mephit
505 Views, 4 Replies

How do I cut an occurrence out of a component?

I've got a component, which is basically the side of a box. I copy this component (now a second occurrence) and create a rigid joint with an offset so I now have the opposite side of the box.

 

I now want to cut both these sides out of the bottom:

input = self.parent.features.combineFeatures.createInput( targetBody, sourceBodies )
input.operation = adsk.fusion.FeatureOperations.CutFeatureOperation
input.isKeepToolBodies = True
		
#self.parent is the parent component self.parent.features.combineFeatures.add( input )

This works for the original component, but not the second occurrence, in the timeline, I see the following:

 

Capture.JPGIf I then manually select the combine feature in the timeline and edit it and immediately click ok, it works as intended.

 

I can't see any mention of transforms in the api documentation, so I'm not sure what I'm missing 😞

4 REPLIES 4
Message 2 of 5
goyals
in reply to: the.mephit

If you can share the complete script, It might be easy to understand what is the problem. 



Shyam Goyal
Sr. Software Dev. Manager
Message 3 of 5
the.mephit
in reply to: goyals

Well most of it is here: https://github.com/DanForever/BoxMaker

I don't really know how that helps though, what I need is an example of how to use multiple instances of a component as the cutting tool in a combineFeature (ideally moved and locked into place with a rigid joint), as the samples in the documentation only seem to deal with a single component

Message 4 of 5
BrianEkins
in reply to: the.mephit

Here's a simple program that draws a box as one component and a sphere as a second component.  It then creates multiple copies of the sphere component and then uses a combine feature to subtract all of the spheres from the box to the create Swiss cheese like shown below.

 

Swiss.png

 

 

 

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

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = _app.userInterface
        des = adsk.fusion.Design.cast(app.activeProduct)
        root = des.rootComponent

        # Draw a box.
        length = 20
        width = 10
        height = 15
        
        boxOcc = root.occurrences.addNewComponent(adsk.core.Matrix3D.create())
        boxComp = boxOcc.component
        boxSketch = boxComp.sketches.add(boxComp.xYConstructionPlane)
        lines = []
        linesCol = boxSketch.sketchCurves.sketchLines
        lines.append(linesCol.addByTwoPoints(adsk.core.Point3D.create(0,0,0),
                                             adsk.core.Point3D.create(length,0,0)))
        lines.append(linesCol.addByTwoPoints(lines[0].endSketchPoint,
                                             adsk.core.Point3D.create(length,width,0)))
        lines.append(linesCol.addByTwoPoints(lines[1].endSketchPoint,
                                             adsk.core.Point3D.create(0,width,0)))
        lines.append(linesCol.addByTwoPoints(lines[2].endSketchPoint,
                                             lines[0].startSketchPoint))

        boxComp.features.extrudeFeatures.addSimple(boxSketch.profiles.item(0),
                                                adsk.core.ValueInput.createByReal(height),
                                                adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
                                                
        # Draw a sphere.
        radius = 3

        spheres = []        
        spheres.append(root.occurrences.addNewComponent(adsk.core.Matrix3D.create()))
        sphereComp = spheres[0].component
        sphereSketch = sphereComp.sketches.add(sphereComp.xYConstructionPlane)
        arc = sphereSketch.sketchCurves.sketchArcs.addByCenterStartSweep(adsk.core.Point3D.create(0,0,0),
                                                                        adsk.core.Point3D.create(0,-radius,0),
                                                                        math.pi)
        line = sphereSketch.sketchCurves.sketchLines.addByTwoPoints(arc.startSketchPoint, arc.endSketchPoint)                                        
        
        sphereInput = sphereComp.features.revolveFeatures.createInput(sphereSketch.profiles.item(0),
                                                        line, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
        sphereInput.setAngleExtent(False, adsk.core.ValueInput.createByReal(math.pi * 2))
        sphereComp.features.revolveFeatures.add(sphereInput)
        
        # Create several instances of the sphere randomly placed within the box.
        for i in range(25):
            x = random.random()*length
            y = random.random()*width
            z = random.random()*height
            
            trans = adsk.core.Matrix3D.create()
            trans.translation = adsk.core.Vector3D.create(x,y,z)
            spheres.append(root.occurrences.addExistingComponent(sphereComp, trans))
        
        
        target = boxComp.bRepBodies.item(0).createForAssemblyContext(boxOcc)
        tools = adsk.core.ObjectCollection.create()
        for i in range(len(spheres)):
            tools.add(sphereComp.bRepBodies.item(0).createForAssemblyContext(spheres[i]))
        combInput = root.features.combineFeatures.createInput(target, tools)
        combInput.isKeepToolBodies = False
        combInput.operation = adsk.fusion.FeatureOperations.CutFeatureOperation
        root.features.combineFeatures.add(combInput)
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
Message 5 of 5
the.mephit
in reply to: BrianEkins

Thank you so much @BrianEkins for your sample. I've used your sample to create a simple rigid joint between two boxes, which I then use to cut two holes out of the larger main box, and it works fine.

 

Adapting my main project to work as the sample describes, and still no luck, I get the same error that I put in the original post, however, I've discovered it happens in my project because I create a parent component to group everything together.

 

I've reproduced this using your sample by simply creating a component and then creating the boxes from that rather than going straight off the documents root node.

 

My best guess right now is that I need to use a proxy of the parent component when creating the combineFeature, rather than the component itself directly. Except that Occurrences don't have a features, and when I call:

#See full script below for context
proxy = root.createForAssemblyContext( rootOcc )

I just hit an exception:

>>> Exception: Traceback (most recent call last):
  File "C:/Users/Daniel/AppData/Roaming/Autodesk/Autodesk Fusion 360/API/Scripts/Sphere Cut sample/Sphere Cut sample.py", line 231, in run
    sampleModified2()
  File "C:/Users/Daniel/AppData/Roaming/Autodesk/Autodesk Fusion 360/API/Scripts/Sphere Cut sample/Sphere Cut sample.py", line 214, in sampleModified2
    proxy = root.createForAssemblyContext( rootOcc )
  File "C:/Users/Daniel/AppData/Local/Autodesk/webdeploy/production/2b2ead9071920969d66eeab4f87d7b161696c63e/Api/Python/packages\adsk\fusion.py", line 33585, in <lambda>
    __getattr__ = lambda self, name: _swig_getattr(self, Component, name)
  File "C:/Users/Daniel/AppData/Local/Autodesk/webdeploy/production/2b2ead9071920969d66eeab4f87d7b161696c63e/Api/Python/packages\adsk\fusion.py", line 57, in _swig_getattr
    raise AttributeError(name)
AttributeError: createForAssemblyContext

 

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

def sampleModified2():
	app = adsk.core.Application.get()
	des = adsk.fusion.Design.cast(app.activeProduct)
	root = des.rootComponent

	rootOcc = root.occurrences.addNewComponent(adsk.core.Matrix3D.create())
	root = rootOcc.component
	
	# Draw a box.
	length = 20
	width = 10
	height = 15
	
	boxOcc = root.occurrences.addNewComponent(adsk.core.Matrix3D.create())
	boxComp = boxOcc.component
	boxComp.name = "box"
	boxSketch = boxComp.sketches.add(boxComp.xYConstructionPlane)
	lines = []
	linesCol = boxSketch.sketchCurves.sketchLines
	lines.append(linesCol.addByTwoPoints(adsk.core.Point3D.create(0,0,0),
										 adsk.core.Point3D.create(length,0,0)))
	lines.append(linesCol.addByTwoPoints(lines[0].endSketchPoint,
										 adsk.core.Point3D.create(length,width,0)))
	lines.append(linesCol.addByTwoPoints(lines[1].endSketchPoint,
										 adsk.core.Point3D.create(0,width,0)))
	lines.append(linesCol.addByTwoPoints(lines[2].endSketchPoint,
										 lines[0].startSketchPoint))

	boxComp.features.extrudeFeatures.addSimple(boxSketch.profiles.item(0),
											adsk.core.ValueInput.createByReal(height),
											adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
											
											
	points =[ ( -1.5, -1.5, 0 ), ( 1.5, -1.5, 0 ), ( 1.5, 1.5, 0 ), (-1.5, 1.5, 0 ) ]
											
	miniBox = root.occurrences.addNewComponent(adsk.core.Matrix3D.create())
	miniBox1sketch = miniBox.component.sketches.add(miniBox.component.xYConstructionPlane)

	for i in range( len( points ) ):
		pointA = points[ i ]
		pointB = points[ i + 1 ] if i + 1 < len( points ) else points[ 0 ]
		miniBox1sketch.sketchCurves.sketchLines.addByTwoPoints( adsk.core.Point3D.create( *pointA ), adsk.core.Point3D.create( *pointB ) )

	miniBox.component.features.extrudeFeatures.addSimple( miniBox1sketch.profiles.item(0), adsk.core.ValueInput.createByReal( 3.0 ), adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
	
	minibox2 = root.occurrences.addExistingComponent( miniBox.component, adsk.core.Matrix3D.create())
	
	edgeA = miniBox.bRepBodies.item( 0 ).edges.item( 0 )
	edgeB = minibox2.bRepBodies.item( 0 ).edges.item( 0 )
	
	joinA = adsk.fusion.JointGeometry.createByCurve( edgeA, adsk.fusion.JointKeyPointTypes.MiddleKeyPoint )
	joinB = adsk.fusion.JointGeometry.createByCurve( edgeB, adsk.fusion.JointKeyPointTypes.MiddleKeyPoint )
	
	jointInput = root.joints.createInput( joinA, joinB )
	jointInput.offset = adsk.core.ValueInput.createByReal( -4 )
	jointInput.setAsRigidJointMotion()
	joint = root.joints.add( jointInput )

	# cut
	
	target = boxComp.bRepBodies.item(0).createForAssemblyContext(boxOcc)
	tools = adsk.core.ObjectCollection.create()
	
	minibox1Tool = miniBox.component.bRepBodies.item(0).createForAssemblyContext( miniBox )
	minibox2Tool = minibox2.component.bRepBodies.item(0).createForAssemblyContext( minibox2 )
	tools.add( minibox1Tool )
	tools.add( minibox2Tool )

	combInput = root.features.combineFeatures.createInput( target, tools )
	combInput.isKeepToolBodies = False
	combInput.operation = adsk.fusion.FeatureOperations.CutFeatureOperation
	root.features.combineFeatures.add(combInput)

def run(context):
	try:
		sampleModified2()
	except:
		print( "Exception: {}".format( traceback.format_exc() ) )

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

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report