Batch maxscript to read .csv files run a script and save .max files

Batch maxscript to read .csv files run a script and save .max files

system-core
Enthusiast Enthusiast
2,154 Views
15 Replies
Message 1 of 16

Batch maxscript to read .csv files run a script and save .max files

system-core
Enthusiast
Enthusiast

create sphere from names in text file with this format

PlayerHouse_Shower01001|10|0|0|0|12

 

 

clearlistener()

adata = (dotnetClass "System.IO.File").ReadAllLines @"C:\test.txt"

for i = 1 to adata.count do
(
pInfo = (filterString adata[i] "|")
print pInfo
s = sphere segments:(pInfo[6] as integer)
s.radius = pInfo[2] as integer
s.pos = [pInfo[3] as integer,pInfo[4] as integer, pInfo[5] as integer]
s.name = pInfo[1]
)

 

 

move/rotate/scale objects from csv with this format

Name                                                                 Position                                   Rotation                    Scale
PlayerHouse_Shower01001,-80331.0938,90976.4297,7857.2979,0.0000,-0.0000,230.8562,1.0000
TreeMaplePreWar01Gr001,-99744.5547,77048.9453,10398.3457,0.6550,-0.6280,269.8729,0.9100

 

 

(
    file = memStreamMgr.openFile @"C:\test.csv"

    while NOT file.eos() do
    (
        local line = filterString (file.readLine()) ","
        if line.count == 8 AND isValidNode (local obj = getNodeByName line[1]) do
            obj.pos = [line[2] as float, line[3] as float, line[4] as float]
			
		if line.count == 8 AND isValidNode (local obj = getNodeByName line[1]) do
			obj.rotation = eulerAngles (line[5] as float) (line[6] as float) (line[7] as float)
			
        if line.count == 8 AND isValidNode (local obj = getNodeByName line[1]) do
            obj.scale = [line[8] as float, line[8] as float, line[8] as float]
	)
    memStreamMgr.close file
)

 

 

 

I wanted to modify the scripts above to save a max file, based on a csv file name that the script reads.

I've got hundreds of files with different names test.csv for example. the code should do the following

 


read file test.csv

 

create one object per name from the csv file, PlayerHouse_Shower01001 TreeMaplePreWar01Gr001...etc (can be a sphere/dummy/box)

 

run the script code position/rotation/scale

 

save test.max (Based on read csv filename)

 

reset

 

read next csv file

 

repeat until end of files

 

 

If anybody can help give me some examples or help me figure out how to do this I would appreciate it. Thankyou

0 Likes
Accepted solutions (1)
2,155 Views
15 Replies
Replies (15)
Message 2 of 16

denisT.MaxDoctor
Advisor
Advisor

lt is true that you always have a pair of .txt and .csv files with the same name in the same directory, and you need to create a max file with the same name in the same directory as the original pair?

0 Likes
Message 3 of 16

system-core
Enthusiast
Enthusiast

Yes same name same folder, the max file can be saved in the same folder or the 3dsmax/scenes is okay. Ideally I just want to process the csv data which also has the names to create objects. I created the csv.txt with names only in the first script to  generate spheres. I had to use notepad++ to manually add |10|0|0|0|12 it's tedious

0 Likes
Message 4 of 16

denisT.MaxDoctor
Advisor
Advisor

It sounds like you don't need TXT file at all. The CSV already tells you the name of object and its matrix3.

The type of the object could be any (dummy for example) with predefined size.

   

0 Likes
Message 5 of 16

system-core
Enthusiast
Enthusiast

Yes thats right, I have searched all over the internet for some code I could use, I don't have much knowledge to write code.

0 Likes
Message 6 of 16

denisT.MaxDoctor
Advisor
Advisor
Accepted solution

 

 

struct TheCSVBatchStruct 
(
private

	caption = "Choose a Folder for CSV Batch...",
	
	read_all_lines = (dotnetClass "System.IO.File").ReadAllLines,
	
public
	dummy_size = 100,
	last_dir, 
	
	fn make_matrix data =
	(
		if data.count == 8 then 
		(
			pos = [execute data[2], execute data[3], execute data[4]]
			rot = (eulerangles (execute data[5]) (execute data[6]) (execute data[7])) as quat
			scl = execute data[8] * [1,1,1]
			translate (rotate (scalematrix scl) (inverse rot)) pos
		)
		else (matrix3 1)
	),	

	fn process dir: saveCheck:on = 
	(
		if not saveCheck or checkforsave() do
		(
			if dir == unsupplied do dir = getSavePath caption:caption
			
			if iskindof dir String and doesfileexist dir do
			(
				pattern = pathConfig.appendPath dir @"*.csv"
				csvs = getfiles pattern
				
				format "directory: %\n" dir
				format "\tprocess CSV files:\n"
				
				for c in csvs do
				(
					resetmaxfile #noPrompt
					setSaveRequired off

					format "\t\tCSV: %\n" (filenamefrompath c)
					format "\t\t\tnodes:\n"
					
					ss = read_all_lines c
					for s in ss do
					(
						data = filterstring s ",;" 
						if data.count == 8 do
						(
							name = data[1]
							tm = make_matrix data

							node = dummy name:name boxsize:(dummy_size * [1,1,1]) transform:tm
							if isvalidnode node do
							(
								setSaveRequired on
								format "\t\t\t\t%\n" name
							)
						)
					)
					if getSaveRequired() do
					(
						m = replace c (c.count-2) 3 "max"
						format "\t\t\tMAX: %\n" (filenamefrompath m)
						
						res = savemaxfile m clearNeedSaveFlag:true useNewFile:false quiet:true
						format "\t\t\t\t%\n" ((if res then "SUCCEEDED" else "FAILED")	)							
					)
				)
			)
		)
	),
	
	on create do
	(
	)
)

csv_batch = TheCSVBatchStruct()

/*

-- default run:
csv_batch.process()

-- expert run if you exactly know what to do:
csv_batch.process savecheck:off dir:@"C:\temp\Tests"

*/

 

 

 

 

buy me a beer if it works  😉

 

PS. some bug was fixed 

0 Likes
Message 7 of 16

denisT.MaxDoctor
Advisor
Advisor

@system-core wrote:

... I have searched all over the internet for some code I could use, I don't have much knowledge to write code.


It's very hard to find something that works for a specific task... ChatGPT is not yet developed enough in this area to be trusted... so for now all that's left is to learn how to code on your own.

And yes... You could also ask someone who knows how to do it. 😎

0 Likes
Message 8 of 16

denisT.MaxDoctor
Advisor
Advisor

In reality, of course, batch tools are much more complex if you want to do it right. The main challenge is to make the batch robust and stable enough to complete the job, and informative enough to tell you about the process (track progress and statistics, log warnings and errors, etc.).

0 Likes
Message 9 of 16

system-core
Enthusiast
Enthusiast

I've tried the script and got the following in the listener

#Struct:TheCSVBatchStruct(
  last_dir:<data>; Public,
  make_matrix:<fn>; Public,
  read_all_lines:<data>; Private,
  dummy_size:<data>; Public,
  caption:<data>; Private,
  process:<fn>; Public)
(TheCSVBatchStruct dummy_size:100 last_dir:undefined)
OK

Am I supposed to add a folder path to "Choose a Folder for CSV Batch..." I did and I get the same text as above in the listener. I don't see anything happening and no files are created? Thanks for helping me

 

0 Likes
Message 10 of 16

denisT.MaxDoctor
Advisor
Advisor

do you run:

 

csv_batch.process()
0 Likes
Message 11 of 16

denisT.MaxDoctor
Advisor
Advisor

do you run:

 

csv_batch.process()

0 Likes
Message 12 of 16

system-core
Enthusiast
Enthusiast

No I just ran 3dsmaxbatch.exe C:\script.ms with cmd prompt. I'm a bit confused how to run it; and if I need to add a directory or does it let me select one What is the csv_batch.process() how would I run that. Thanks

csv_batch.process()

 

0 Likes
Message 13 of 16

denisT.MaxDoctor
Advisor
Advisor

1. open max

2. run the code I sent

3. run : 

csv_batch.process()

 


 

0 Likes
Message 14 of 16

system-core
Enthusiast
Enthusiast

I'm not sure what you mean here is a picture of what I have, I ran EvaluateAllimage.jpg

0 Likes
Message 15 of 16

denisT.MaxDoctor
Advisor
Advisor

Un-comment bottom of the script. And evaluate all again

0 Likes
Message 16 of 16

system-core
Enthusiast
Enthusiast

Yes it works, Thanks for that how could I donate some money for that beer

0 Likes