Maxing out memory

Maxing out memory

Anonymous
Not applicable
1,732 Views
14 Replies
Message 1 of 15

Maxing out memory

Anonymous
Not applicable

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

0 Likes
Accepted solutions (1)
1,733 Views
14 Replies
Replies (14)
Message 2 of 15

zachesenbock
Contributor
Contributor
Accepted solution

Have you tried using

 

sketch.isComputeDeferred = True

 

before the circles are drawn, and then

 

sketch.isComputeDeferred = False

after?

0 Likes
Message 3 of 15

JesusFreke
Advocate
Advocate

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()

 

 

0 Likes
Message 4 of 15

Anonymous
Not applicable

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.

0 Likes
Message 5 of 15

Anonymous
Not applicable

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.

0 Likes
Message 6 of 15

Anonymous
Not applicable

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

0 Likes
Message 7 of 15

zachesenbock
Contributor
Contributor

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

0 Likes
Message 8 of 15

Anonymous
Not applicable

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 

0 Likes
Message 9 of 15

zachesenbock
Contributor
Contributor

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.

0 Likes
Message 10 of 15

Anonymous
Not applicable

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?

0 Likes
Message 11 of 15

zachesenbock
Contributor
Contributor

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.

0 Likes
Message 12 of 15

JesusFreke
Advocate
Advocate

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 

0 Likes
Message 13 of 15

JesusFreke
Advocate
Advocate

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)

0 Likes
Message 14 of 15

Anonymous
Not applicable

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

0 Likes
Message 15 of 15

MichaelT_123
Advisor
Advisor

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
0 Likes