[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
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