rotation from csv file in maxscript - csv

Hopefully someone with better maxscript knowledge can help with this.
I have a csv file driving the position of some dummy helpers in 3dsmax. 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 from my csv file (actual file has hundreds of points):
0, 975.4222, 2181.8731, 0, 267, 360, 75,
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

This really should be in a comment, but I don't have enough reputation.
Anyway, I just ran your code successfully with 500 dummy objects with randomly generated transforms and it ran fine. So it sounds like it might be an issue with memory, possibly related to an open file--I once wrote a script that opened a file to read/write values and I had some strange results when I was doing operations while the file was open. So here's what I would suggest:
Read all values from the file into an array and then close the file before instancing your dummy nodes.
Wrap your operations and turn off the undo stack. This can sometimes help with memory issues when performing a large number of operations:
with undo off (
if (lf[1]!=undefined ) do
(
-- create instances of dummy nodes here ...
)
)
Good luck!

Related

how can I implement a function to load data into a design matrix and an output vector in octave

I have a .txt file with dimensions 100x4 but i want to generalise and make an initial matrix with m x n+1 dimension as the code should work fine with any data file. m is the number of training examples and n is the number of training features and the last column is the output vector.
function [X,y]= loadData(filename)
data=load(filename);
X=load(filename);
y=load(filename);
m=rows(filename);
n=size(filename);
end
expected value of elements in the matrix do not match the found value.
what is the mistake?
First of all you are loading 3 times the same things, so at the end data, X, and y contain exactly the same things.
Then you are passing filename -that is a string- to rows() and size(), so do not expect getting the sizes of some arrays: these functions won't open any file, they just operate on the string in this case. In octave a string is considered as a 1xl matric, l being the length of the string.

GnuPlot :: Plotting 3D recorded in an unconventional format

I would like to prepare a script file to draw a 3D plot of some kinetic spectroscopy results. In the experiment the absorption spectrum of a solution is measured sequentially at increasing times from t0 to tf with a constant increase in time Δt.
The plot will show the variation of absorbamce (Z) with wavelength and time.
The data are recorded using a UV-VIS spectrometer and saved as a CSV text file.
The file contains a table in which the first column are the wavelengths of the spectra. Afterwards, a column is added for each the measured spectra, and a number of columns depends on the total time and the time interval between measuerments. The time for each spectra appears in the headers line.
I wonder if the data can be plotted directly witha minimum of preformatting and without the need to rewrite the data in a more estandar XYZ format.
The structure of the data file is something like this
Title; espectroscopia UV-Vis
Comment;
Date; 23/10/2018 16:41:12
Operator; laboratorios
System Name; Undefined
Wavelength (nm); 0 Min; 0,1 Min; 0,2 Min; 0,3 Min; ... 28,5 Min
400,5551; 1,491613E-03; 1,810312E-03; 2,01891E-03; ... 4,755786E-03
... ... ... ... ... ...
799,2119; -5,509266E-04; 3,26314E-04; -4,319865E-04; ... -5,087912E-04
(EOF)
A copy of a sample data is included in this file kinetic_spectroscopy.csv.
Thanks.
Your data is in an acceptable form for gnuplot, but persuading the program to plot this as one line per wavelength rather than a gridded surface is more difficult. First let's establish that the file can be read and plotted. The following commands should read in the x/y coordinates (x = first row, y = first column) and the z values to construct a surface.
DATA = 'espectros cinetica.csv'
set datafile separator ';' # csv file with semicolon
# Your data uses , as a decimal point.
set decimal locale # The program can handle this if your locale is correct.
show decimal # confirm this by inspecting the output from "show".
set title DATA
set ylabel "Wavelength"
set xlabel "Time (min)"
set xyplane 0
set style data lines
splot DATA matrix nonuniform using 1:2:3 lc palette
This actually looks OK with your data. For a smaller number of scans it is probably not what you would want. In order to plot separate lines, one per scan, we could break this up into a sequence of line plots rather than a single surface plot:
DATA = 'espectros cinetica.csv'
set datafile separator ";"
set decimal locale
unset key
set title DATA
set style data lines
set ylabel "Wavelength"
set xlabel "Time (min)"
set xtics offset 0,-1 # move labels away from axis
splot for [row=0:*] DATA matrix nonuniform every :::row::row using 1:2:3
This is what I get for the first 100 rows of your data file. The row data is colored sequentially by gnuplot linetypes. Other coloring schemes are possible.

reverse tail for gnuplot

I would like to display data in a repeated online diagram with:
plot "tail -140 logging.dat | tac -r" with lines
I get an error message file cannot be opened, however in CLI it gives the reverse list of data as expected. Could anyone help me with the correct syntax, please?
Just for the records, here is a gnuplot-only, hence platform-independent solution. Check via stats the total number of lines. If there are less than N lines (here: 140), all lines will be plotted, otherwise only the 140 last ones.
Remark: if you do plot ... with lines, gnuplot will plot column 1 as x and column 2 as y per default. However, the output graph will look the same whether you reverse the data or not. So, I don't see why reversing the data would be necessary, unless you want to plot something what you haven't shown here or e.g. list a reversed table as text.
Script:
### plot N last lines of a file
reset session
FILE = "SO55221113.dat"
# create some random test data
set table FILE
set samples 1000
y0 = rand(0)
plot '+' u 1:(y0=y0+rand(0)-0.5)
unset table
N = 140
stats FILE u 0 nooutput # get total number of lines into STATS_records
M = STATS_records<=N ? STATS_records : STATS_records-N
plot FILE u 1:2 w l lc rgb "green" ti "all values", \
'' u 1:2 every ::M w l lc rgb "red" ti sprintf("last %d values",N)
### end of script
Result:

Using generator to save memory

Suppose I have one million files in my directory, It'd be a huge consumption in memory if I just did:
x = os.listdir('.')
Suppose for some reason, I chose to use os.walk method and did this to use generator:
def give_object(somepath)
for x in os.walk(somepath):
for j in x[2]:
yield j
os.walk is itself a generator, and I get a value of (cur_directory, sub_directories, list_of_all_files_in_cur_directory) via x. x[2] would contain the 1 million file names. In the second for statement, I'm also yielding a value, making a generator, but, at that point, I've already created a list out from x, So, Would this code really save memory space that would be used for the 1 million items? Or is this not a correct way of using generator for the use case? If so, how should I go about doing it?

Problem with MATLAB functions

I got this MATLAB function. When I ran it, the following error messege showed up. Can anybody give me some hint? Thank you. The code is also shown below.
[h,im_matched,theta,I,J]=im_reg_MI('keyframe1.jpg','keyframe2.jpg', 0, 1)
??? Undefined function or variable "h".
Error in ==> im_reg_MI at 74
[a, b] = max(h(:));% finding the max of MI and indecises
Below is the code.
[h,im_matched, theta,I,J]=im_reg_MI(image1, image2, angle, step)
[m,n]=size(image1);
[p,q]=size(image2);
[a,b]=size(angle);
im1=round(image1);
for k=1:b
J = rotate_image(angle(k),image2); %rotated cropped IMAGE2
image21=round(J);
[m1,n1]=size(image21);
for i=1:step:(m1-m)
for j=1:step:(n1-n)
im2=image21(i:(i+m-1),j:(j+n-1)); % selecting part of IMAGE2 matching the size of IMAHE1
im2=round(im2);
h(k,i,j)=MI2(im1,im2); % calculating MI
end
end
end
[a, b] = max(h(:));% finding the max of MI and indecises
The problem is that you aren't actually passing in image data for the image1 and image2 arguments. You're just passing character strings containing the image file names 'keyframe1.jpg' and 'keyframe2.jpg'.
You need to load the image data from the files first using IMREAD, then pass the image data to im_reg_MI. Assuming the images are in the current working directory, you would do something like this:
image1 = imread('keyframe1.jpg');
image2 = imread('keyframe2.jpg');
[h,im_matched,theta,I,J] = im_reg_MI(image1,image2,0,1);
EDIT:
There seems to be an additional error within im_reg_MI that occurs if image21 (the rotated version of image2) is the same size or smaller than image1 for one or more of its dimensions. If m1 were less than or equal to m and/or n1 were less than or equal to n, then one or both of the loops for i or j would never be entered since 1:step:(m1-m) and/or 1:step:(n1-n) would create an empty vector. Thus, the inner loop code would never be run and h would never be created.
And one extra note...
I noticed that the function im_reg_MI appears to treat the two images as 2-D, which means they must be intensity images (i.e. grayscale or binary image data). If you're dealing with indexed or RGB image data, I don't think im_reg_MI is going to handle them properly.