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: 

Maxing out memory

14 REPLIES 14
SOLVED
Reply
Message 1 of 15
zcarter3333
608 Views, 14 Replies

Maxing out memory

I am maxing out my computer memory with Fusion 360 using up 12 GB of memory by itself with a script I'm running.

 

I need to draw 200 square sheets, each with a perforated pattern of circles (about 600 circles to each sheet).  I have verified that the script works for 2 sheets, but when I go more than about 5 sheets, the Fusion 360 crashes. I am just drawing 2D circles and squares on the XY construction plane so I don't understand why it is taking so much memory to make a 2D drawing. Is there not a 2-D only drawing mode you can access through scripting? I have to draw about 100,000 circular holes in total for the 200 square sheets and will be exporting it as a DXF.

 

Thanks

Tags (1)
14 REPLIES 14
Message 2 of 15
zachesenbock
in reply to: zcarter3333

Have you tried using

 

sketch.isComputeDeferred = True

 

before the circles are drawn, and then

 

sketch.isComputeDeferred = False

after?

Message 3 of 15
JesusFreke
in reply to: zcarter3333

Do you have to do all 200 sheets at once? You could do a few, export them and reset the document, do a few more, export them, etc.

 

You might also investigate using the TemporaryBRepManager to create 2d geometry, which is a much much lighter weight operation than drawing in a sketch.

 

e.g. to create a circle, you can use brep.createCylinderOrCone(), and then take the top or bottom face of the cylinder and convert just that face to a separate body. Similar for a square/rectangle - you can create a cube and take one of the faces. And you can use brep.booleanOperation with a boolean type of DifferenceBooleanType to cut out the holes from the sheet.

 

If you want to try a somewhat nicer wrapper around the TemporaryBRepManager, you can check out my fscad project. A rough example might be something like:

 

import adsk.core, adsk.fusion
from fscad import *

def run(_):
sheet = Rect(100, 100)

hole1 = Circle(2)
# place the hole 20cm inward from the bottom and left edges
hole1.place(
(~hole1 == -sheet) + 20, # align the middle of the hole (~hole) with the left edge of the sheet (-sheet), and then move it inward by 20
(~hole1 == -sheet) + 20, # align the middle of the hole (~hole) with the bottom edge of the sheet (-sheet), and then move it inward by 20
~hole1 == ~sheet)

assembly = Difference(sheet, hole1)

assembly.create_occurrence()

 

 

Message 4 of 15
zcarter3333
in reply to: zachesenbock

Wow, I didn't even know that existed! It does seem to have solved the memory issue. It is now hovering around ~2 GB while generating the circles.  I am testing it out with 24 sheets now.

Message 5 of 15
zcarter3333
in reply to: JesusFreke

Thanks JesusFreke,

 

This is a drawing which will be sent to a laser cutting bed of 5 foot by 10 foot, so I need all the squares to be aligned on the same drawing.  I could potentially draw each sheet on a separate DXF and then superimpose them all somehow outside of Fusion 360, but if this works I would rather do this.

 

I will have to look into the Temporary Brep manager if simply deferring the computing doesn't work for the full drawing. Thanks for the suggestion.

Message 6 of 15
zcarter3333
in reply to: JesusFreke

Ok, so while the deferred computing fixed part of the issue, it is obviously taking more time from one sheet to the next as the number of sheets increases. I set it to give a messageBox every time it makes a new sheet, and the time to create each sheet is increasing as the number of sheets increases. 

 

How do you simply take one of the cylinder faces from a brep.createCylinderOrCone() and convert it to a 2D body?

 

Thanks

Message 7 of 15
zachesenbock
in reply to: zcarter3333

Are all the sheets existing together in the same document, or are you clearing it and then starting the next one?

Message 8 of 15
zcarter3333
in reply to: zachesenbock

They are all on the same document. I need to draw them all on a singlegrid.png 5' x 10' canvas.

 

Attached is an example of one sheet 

Message 9 of 15
zachesenbock
in reply to: zcarter3333

If you export them all as one file then I'm not sure anything in the API can help with the accumulating calculation time. If you exported the sheets individually then I would've suggested having the script close and re-open the document. I'm currently running some experiments with this and it shows some promise at making the time increases at little less... exponential.

Message 10 of 15
zcarter3333
in reply to: zachesenbock

Can multiple DXFs be overlaid onto a single DXF? If I make 200 DXFs with the sheets in their proper position individually, is there a way to combine them all into one?

Message 11 of 15
zachesenbock
in reply to: zcarter3333

I don't think you can easily concatenate them, but you may be able to import them all at once. The code I'm testing currently, if you want to try it, is

 

app = adsk.core.Application.get()
ui  = app.userInterface
projects = app.data.dataProjects

allDocs = app.documents
currentDoc = app.activeDocument
currentDocName = currentDoc.name

timeList = []

for i in range(200):

	# Keep track of time taken. Used to reset document if too much memory has accumulated
	startTime = time.time()
		
	YOUR_SKETCH_FUNCTION(circleSketch)
	
	totalTime = time.time() - startTime
	
	timeList.append(totalTime)
	
	# If time has increase substantially, close and re-open the model.
	if totalTime > timeList[0] * 2.5:
	
		timeList = []
		currentDoc.close(False)
		
		startTime = time.time()
		
		for project in projects:
			if "YOUR PROJECT NAME" in project.name:
				folder = project.rootFolder
				for file in folder.dataFiles:
					if file.name in currentDocName:
						openFile = allDocs.open(file)
						activateFile = openFile.activate()
						
						currentDoc = app.activeDocument
						currentDocName = currentDoc.name
						
						product = app.activeProduct
						# Get the root component of the active design.
						rootComp = product.rootComponent           
						
						# Get sketches
						sketches = rootComp.sketches
						for sketch in sketches:
						
							# Find the Date Text sketch
							if sketch.name == "YOUR SKETCH NAME":
								circleSketch = sketch

I tried to format it so it would be easier for you to use in your case.

Message 12 of 15
JesusFreke
in reply to: zachesenbock

The following runs in just under 1 second on my machine 🙂

 

import adsk.core
import adsk.fusion
from adsk.core import Point3D, Vector3D, OrientedBoundingBox3D, Matrix3D
import time


def app():
return adsk.core.Application.get()


def design():
return adsk.fusion.Design.cast(app().activeProduct)


def root() -> adsk.fusion.Component:
return design().rootComponent


def brep():
return adsk.fusion.TemporaryBRepManager.get()


def rect(x, y, width, height):
# The top face of a box is always index 0
top_index = 0

top_face = brep().createBox(OrientedBoundingBox3D.create(
Point3D.create(
x + width/2,
y + width/2,
-.5),
Vector3D.create(1, 0, 0),
Vector3D.create(0, 1, 0),
width, height, 1)).faces[top_index]
return brep().copy(top_face)


def circle(x, y, radius):
# The top face of a cylinder is always index 2
top_index = 2

top_face = brep().createCylinderOrCone(
Point3D.create(x, y, -1), radius,
Point3D.create(x, y, 0), radius).faces[top_index]
return brep().copy(top_face)


def difference(target, *tools):
for tool in tools:
brep().booleanOperation(target, tool, adsk.fusion.BooleanTypes.DifferenceBooleanType)
return target


def union(*bodies):
target = None
for body in bodies:
if target is None:
target = body
else:
brep().booleanOperation(target, body, adsk.fusion.BooleanTypes.UnionBooleanType)
return target


def create_occurrence(body):
occurrence = root().occurrences.addNewComponent(Matrix3D.create())
occurrence.component.bRepBodies.add(body)
return occurrence


def run(_):
start = time.time()

design().designType = adsk.fusion.DesignTypes.DirectDesignType

sheets = []
for row in range(0, 10):
for col in range(0, 20):
sheet = rect(col * 102, row * 102, 100, 100)
hole = circle(col * 102 + 20, row * 102 + 20, 2)
sheets.append(difference(sheet, hole))

occurrence = create_occurrence(union(*sheets))

sketch = root().sketches.add(root().xYConstructionPlane)
sketch.include(occurrence.bRepBodies[0])

occurrence.deleteMe()

end = time.time()
print(end-start)

sheet_test.png 

Message 13 of 15
JesusFreke
in reply to: JesusFreke

I just tried it with a 15x15 grid of holes in each sheet, to simulate a more representative example, and it took a while to create the sketch. It was about 2 and a half minutes total, and it got up to about 8gb mem usage (private bytes, per SysInternal's ProcessExplorer)

Message 14 of 15
zcarter3333
in reply to: JesusFreke

Interesting. After leaving my code running apparently it is working, it is just slow. I think I will stick with the sketch method as long as I can export the single DXF at the end. I will probably have to leave it running overnight.

 

Do either of you know if it is possible to set the canvas / image size to exactly 10 foot by 5 foot (X by Y -> 302.4 by 152.4 cm)? The dimensions are important for laser cutting.

 

Thanks

Message 15 of 15
MichaelT_123
in reply to: zcarter3333

Hi Fellows,

 

What you are dealing with here is a quite simple structure

If you want to speed up the process of generation representative DXF .... just skip F360 in the process.

When you open DXF in ASCII editor you will find that the syntax required can be generated quickly and easily by direct assembling/programming the file content.

 

Regards

MichaelT

 

 

 

MichaelT

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