Notifications
Clear all

[Closed] csv file rotation problem

Hopefully someone with better maxscript knowledge can help with this.
I have a csv file driving the position of some dummy helpers. The problem i am having is getting each dummy object to have a local rotation being driven from the csv file. This is a sample of my csv file:

0 975.4222 2181.8731 0 267 360 75
1 975.4222 2181.8731 4.203 105 166 85
2 975.4222 2181.8731 8.406 15 179 296
3 975.4222 2181.8731 12.609 97 142 147
4 975.4222 2181.8731 16.812 298 69 178
5 975.4222 2181.8731 21.015 299 162 272
6 975.4222 2181.8731 25.218 295 243 95
7 975.4222 2181.8731 29.421 24 241 48
8 975.4222 2181.8731 33.624 161 98 227
9 975.4222 2181.8731 37.827 184 64 156

columns 1 through four name the point and position it to an x y and z coordinate. Columns 5 6 and 7 represent a rotation value for each point around the x y z. This is where i am struggling. If i run my code with the random values then the script fails. If however all the values for column 5 are the same and the values for columns 6 and 7 are also the same then the script will run, but each dummy will have the same rotation (obviously). I know i must be doing something slightly wrong. Any help would be really appreciated. My current code is as follows:

-- open the file as text, read mode
f = openFile "c:\\Testtocsv003c.csv" mode:"rt"

prefabPoint = dummy name:"dummy"

-- if it opened successfully (exists, etc)...
if f != undefined do
(
while not eof f do
(
-- Read a line from the file
l = readline f
-- turn that line into an array of strings using commas as delimiters
lf = filterString l ","
if (lf[1]!=undefined ) do
(
newPoint = instance prefabPoint
newPoint.name = lf[1]
x = lf[2] as float -- bracketed number reads column position from text file
y = lf[3] as float -- bracketed number reads column position from text file
z = lf[4] as float -- bracketed number reads column position from text file
xRot = lf[5] as float
yRot = lf[6] as float
zRot = lf[7] as float	

newPoint.pos = [x,y,z] --creates point objects at xyz coordinates from text file. To offset by distance for example change to : [100*x,100*y,100*z]
	

rotate newPoint (eulerangles xRot yRot zRot) --rotates point 

)
)
close f
delete prefabPoint
)

Thanks all. Oh and sorry if the formatting is wrong. This is my first post.

Paul

4 Replies

One way could be using a Matrix:

(
 	data = #()
 	append data  #(0,	975.4222, 2181.8731,	  0,	267, 360,  75)
 	append data  #(1,	975.4222, 2181.8731,  4.203,	105, 166,  85)
 	append data  #(2,	975.4222, 2181.8731,  8.406,	 15, 179, 296)
 	append data  #(3,	975.4222, 2181.8731, 12.609,	 97, 142, 147)
 	append data  #(4,	975.4222, 2181.8731, 16.812,	298,  69, 178)
 	append data  #(5,	975.4222, 2181.8731, 21.015,	299, 162, 272)
 	append data  #(6,	975.4222, 2181.8731, 25.218,	295, 243,  95)
 	append data  #(7,	975.4222, 2181.8731, 29.421,	 24, 241,  48)
 	append data  #(8,	975.4222, 2181.8731, 33.624,	161,  98, 227)
 	append data  #(9,	975.4222, 2181.8731, 37.827,	184,  64, 156)
 	
 	for j in data  do
 	(
 		tm = matrix3 1
 		prerotate tm (eulerangles j[5] j[6] j[7])
 		tm.row4 = [j[2],j[3],j[4]]
 		
 		dummy transform:tm name:(j[1] as string)
 	)
 )

Hi Jorge,

Thanks for that it works. However, do you think i could use a matrix to look to the csv file rather than pasting in all the data to the code? I say this as in my csv file i have hundreds of points that need positioning and rotating.
Thanks again.

Paul

Hi Paul,

Sure, you can use a Matrix as many times as you need. Here is a function to parse the CSV file. I’ve also attached a sample file.

(
 	
 	fn BuildDummiesFromCSV fileName =
 	(
 		-- File don't exist. Return -1
 		if not doesFileExist fileName do return -1
 		
 		-- Open the file as text, read mode. "rt" default mode
 		stream = openFile fileName mode:"rt"
 		
 		-- Can't open the File. Return -2
 		if stream == undefined do return -2
 
 		-- Create a temporary Dummy
 		tmpHelper = dummy()
 
 		-- Keep track of the amount of lines
 		linesCount = 0
 		
 		-- Keep track of the created Helpers
 		succeed = 0
 		
 		-- If it opened successfully (exists, etc)...
 		-- While the end of the FileStream is not reached ...
 		while not eof stream do
 		(
 			-- Read a line from the file
 			l = readline stream
 			
 			linesCount += 1
 			
 			-- Turn that line into an array of strings using comma, semicolon, space or tab as delimiters,
 			-- to handle more than one CSV format.
 			lf = filterString l ",; 	" splitEmptyTokens:false
 			
 			-- If the array has 7 elements then proceed
 			if lf.count == 7 then
 			(
 				-- Get the new Point name
 				name = lf[1]
 				
 				-- Get the X, Y, Z positions
 				xPos = lf[2] as float
 				yPos = lf[3] as float
 				zPos = lf[4] as float
 
 				-- Get the X, Y, Z rotations
 				xRot = lf[5] as float
 				yRot = lf[6] as float
 				zRot = lf[7] as float	
 
 				-- Create an Identity Matrix
 				tm = matrix3 1
 				
 				-- Rotate the Matrix
 				prerotate tm (eulerangles xRot yRot zRot)
 				
 				-- Position the Matrix
 				tm.row4 = [xPos, yPos, zPos]
 				
 				-- Create an Instance of the Dummy Helper and assign the
 				-- transform matrix and name. Do they need to be Instances?
 				instance tmpHelper transform:tm name:name
 				
 				succeed += 1
 			)else(
 				format "Error >>
	Line:%
	%
	%

" linesCount l lf
 			)
 		)
 		
 		-- Close the FileStream
 		flush stream
 		close stream
 		
 		-- Delete the temporary Helper
 		delete tmpHelper
 		
 		format "Lines:% >> Succeed:%
" linesCount succeed
 		
 		return 1
 		
 	)
 	
 	BuildDummiesFromCSV @"C:\points_data.csv"
 	
 )

Perfect! Thank you Jorge.
Thats exactly what i am after. Also thank you for commenting it all up. Its helped me understand a bit more about how to use csv files, which is good, as i can seem to find very little information on them of any real use.

Thanks again

Paul