**Memory error** System exception (crazy RAM usage)

Hello all,

I am getting a memory error and have been unable to fix it thus far.

When I run my script on a batch of 360 files (asking it to load in 360 .max files, perform some operations on them, calculate a number of values for each file and write these values to a number of text files) the RAM usage quickly rises to 100% and after a certain amount of files have been processed windows gives me a message saying 'close down programs to prevent data loss'. At the same time maxscript crashes and throws the error 'unknown system exception *memory error*'

When I load less files, for example 100 the memory error does not occur, the process finishes and the files are produced. The extremely high memory usage still occurs though (12-13GB for 3ds max whilst running script), after the script has finished the memory usage remains the same. Also I've noticed the harddrive being filled with data whilst the script is running (13GB is added to the appdata folder for every file that is opened/processed, once the scene is reset these 13GB are removed from appdata and after loading the next file the process repeats)(I have no clue how that much data could be added since my .max file is 2 MB (I load the same .max file each iteration) and the text files I am producing with the script are 1.53MB for all of them).

My script does the following:
1) Rotates object to initial rotation (rotation of obj around world Z axis)
2) Rotate object about local Y axis in steps of 1 degree
3) Calculate a variable called rot_ratio (stands for rotation ratio) *The variable rot_ratio helps me determine how well the object 'fits' into the viewport (when viewed from a 'front view' camera)
4) Format calculated rotation ratio value to external file (local rotation angle corresponding to this rot_ratio is also added to external file)

I've tried increasing Heapsize, clearing max's memory in the first few lines of the script, adding garbage collection commands throughout the script (I know very little about garbage collection so the placement of these commands could definitely be better). I've freed up 50 gigs on my SSD to prevent issues with my drive filling up (need disk space for the 13GB being written to appdata). I've also tried increasing my virtual memory to 10 and 20GB (as suggested on another forum).

Info for testing with other .max files: input/output directory are defined in lines 17,18, please change username to your own for testing. Current script is simplified as much as possible for readability and as a result only works with scenes containing a single object which is an editable mesh. I've attached the scene I used for testing in .max format (for 2014, 2015, 2016, 2017 versions of max) and in .obj format.

Any help will be greatly appreciated, thank you! Laughing

calc_data_1_3_desktop_edit_4.ms2.35 KB
p90_single_obj2014.max1.51 MB
p90_single_obj2015.max1.51 MB
p90_single_obj2016.max1.51 MB
p90_single_obj.max1.35 MB
p90_single_obj.obj812.33 KB


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
fajar's picture

this is strange script.....

I dont know what your script does for, is it for pulling some data from current operation or else , but I notice your script need a lot improvement tho...I don't know why you link them and unlink them at almost the same time before calculate, so whats the point?, and theres resetmaxfile everywhere which you can simplify by using one reset for current file , in "fn fn_calc_rot_ratio x" , whats even x stand for ? theres no need to selectmore() , or clearselection() needed in your script, you just need collect them, one time only, like (for i in geometry where (matchpattern i.name pattern:"_copy") collect i) .

1. Dummy_and_obj = selection as array --- whats its for ? 
2.out_name = out_dir + i as string + ".txt"
		out_file = createfile out_name -- Create external file
		close out_file -- Close external file
---why not create and write it in and then close it ? 
3. theobj.parent = thedummy -- link dummy/obj
			thedummy.transform = (rotateYmatrix 1 ) * thedummy.transform -- Rotate dummy/obj local Y-axis
			theobj.parent = undefined
--its make no sense in this script tho ? whats for ? should you just , if my feeling is correct , you should link them , rotate them and then pull data from it , write it and then unlink , delete it, later just close the outfile ?


Maarten's picture

About the script..

Thank you for your reply!

(relatively) short answer: (tldr)

The x in "fn fn_calc_rot_ratio x" has no purpose, I just never looked up how to define a function without any arguments so I add x as one of the arguments to avoid errors.

Collect would indeed be better, and indeed does not need to occur more than once.. (thank you for pointing it out)

Please take a look at the attached image "rotate_for_best_fit.png" :)

1) The reason I need resetxform:

I am calculating the delta_x and delta_y for the object and for this I need the minimum/maximum x and y values of the object (I obtain these values by using the built in maxscript functons obj.max.x, obj.min.x etc.). I noticed that these min/max functions appear to return the minimum/maximum values of the bounding box's vertices. For this reason these functions return incorrect values when the bounding box has been rotated (which is the case when the object has been rotated). My solution for this problem was to reset the xform of the object which recalculated the bounding box.

2) The reason I need to link the object to dummy (dummy = obj.parent):
Since I am resetting the obj's xform before each calculation of the rot_ratio variable I am also resetting the pivot's rotation such that it is aligned with the world. This means that if I were to try and rotate the object around it's local Y axis again after resetting the x-form the rotation direction would be different from the initial rotation axis which is not what I want (I'd like the object to rotate as if the resetxform were not performed).
This is the reason I use the dummy, I create the dummy, align it with the object, make the dummy the parent of the object (if I move/rotate dummy then object will move/rotate with it), then I rotate the dummy about its local Y axis. Since the dummy's pivot is unaffected by the resetxform the rotation direction remains unchanged when resetxform is applied.
"dummy_and_obj" is a group containing the object and the afore mentioned dummy.

3) The reason I need to unlink the dummy before each calculation
if I recall correctly having the dummy linked to the object had in infleunce on the calculated min/max values, in other words: the reason for unlinking the dummy before each calulation is to get correct calculation results (more specifically to get correct obj min/max values).

4) The reason I am creating/closing output file more than once:
I want my output to be i text files where i is the index of my loop, currently: 359>i>0

5) The reason I am using resetmaxfile so often:
I used resetmaxfile before loading each max file because I thought it might have a positive effect on memory usage. I've tested this and indeed the memory usage is considerably lower after adding 'resetmaxfile' before each loadmaxfile command. Time to run script did go up though.
With resetmaxfile: Time = 104013[ms] ; Memory_usage = 138968 [L]
Without resetmaxfile: Time = 79126[ms] ; Memory_usage = 1103852 [L]

More eleborate answer:

I'll try and clarify what the script does/address your questions.

This script is part of a rendering script I am working on, the purpose of the rendering script is to rotate an object in such a way that the object 'fits' the best inside the view to be rendered. I wrote a script to do this because I want to make preview images for a lot of objects so doing it manually would take a lot of time.

Explanation regarding render script:
I have defined a variable 'rot_ratio' (stands for rotation ratio) which calculates the ratio between the object's (delta_x/delta_y) and the aspect ratio of the screen (renderwidth/renderheight). When this variable is equal to zero the aspect ratio of the object's bounding box matches the aspect ratio of the render frame and thus the object is rotated in such a way that it makes optimal use of screen real estate (which is what I want). The closer the variable rot_ratio's value is to 'zero', the better the use of screen real estate is.
Since I am rotating my object in steps of finite size (for example 1 degree steps) it will be very unlikely that my variable will ever reach the exact value 'zero', for this reason I've implemented a threshold value and whenever the rot_ratio variable is lower than this threshold (and when the function rot_ratio reaches a local minimum value) I can confidently say that the current rotation has a good use of screen real estate.

There is one problem with this method though, for each object there are several rotation angles for which the rot_ratio variable's value is under the treshold (since there are several local minima in the rot_ratio function which are under the treshold). Some of these local minima (rotations for the object which result in rot_ratio < treshold) result in the object being 'rotated too far' (image the object is rotated 179 degrees with respect to the local Y-axis, the object would then be upside down when rendered in this position and this would not look good on a render).
I'd like to spot some sort of pattern in the rot_ratio graph (all calculated values of rot_ratio on the y_axis and all corresponding rotation angles of the object on the x-axis) in order to determine which rotation direction will result in an object being rotated 'upside down'. I am not sure if this pattern exists but would like to try.

For recognizing this pattern I'd like to graph the data in a 3d surface plot (for this I used python), python needs x,y,z input in order to draw the graph, this is the purpose of the .txt files I am outputting via the maxscript.
I want to get the graph for the rot_ratio for each possible orientation of the object, this is the reason why i load the max file 359 times.

Please let me know if my explanation is not sufficient. Thank you! :)

rotate_for_best_fit.png 370.41 KB

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.