[Closed] pointCount from pointcache modlifier
Does anyone know a way to get the pointcount of the currently loaded pointcache file using maxscript? I want to do this cause I have written a script to merge/edit/blend pointcache files together. But at the moment I have to give the script a mesh to do the merging on. It’d be nice to just have the script know how many points in a mesh it needs to make and make them automatically.
Cheers,
Cg.
you could get it from the UI using UIAccessor, or you can try getting it from the file.
For the Autodesk Cache type, it looks like it might start at offset -2 (2 bytes) from the string ‘DVCA’. Not entirely sure about the 2 bytes – might be more… 2 gives you a 65,535 point maximum.’
Edit: Or positive offset from ‘SIZE’, I suppose >_<
fn pointCachePointCount f = (
-- check the filetype
fType = getFilenameType f
case ftype of (
".xml": ( f = (getFilenamePath f) + (getFilenameFile f) + ".mc"; fType = ".mc2" )
".mc2": ( )
".pc2": ( )
default: ( throw "Invalid file type" )
)
if (not (doesFileExist f)) then ( throw "File does not exist" )
local pointCount = undefined
local f = fopen f "rb"
if (fType == ".mc2") then (
-- get file size
fseek f 0 #seek_end
fSize= ftell f
-- back to the beginning
fseek f 0 #seek_set
-- Find the first SIZE value, and grab the size
while ((ftell f < 1024) AND (ftell f < fSize)) do (
if (readString f == "SIZE") do (
fseek f 3 #seek_cur
pointCount = ReadLong f
exit
)
)
if (pointCount != undefined) then (
-- flip Long value's endianness
pointCount = bit.swapbytes pointCount 1 4
pointCount = bit.swapbytes pointCount 2 3
)
)
else if (fType == ".pc2") then (
-- Much easier...
fseek f 16 #seek_set
pointCount = readLong f
)
fclose f
pointCount
)
pointCachePointCount $.modifiers[1].filename
Wow, thanks for that response. Very impressive. I very much appreciate it. However it’s way above my understanding. Also, I’m sorry I should have mentioned that I use pc2 files. The .xml/.mc files with the double filesize are often very impractical. So using the xml/mc option will more than negate the handy saving I was hoping to gain with the auto vert creation.
I will look into the UIAccessor thing though.
Thanks very much for you amazingly skilled reply,
Cg.
Amazing. Thanks. Does exactly what I need. Now I’m just trying to understand what it does. I’ve never delved into the world of binary files before.
I’ve figured that the bare bones of what I need is below. How did you know where to start seeking? Is 16 a line or a position? Can you explain this a little? Actually after more thought, is there somewhere I can learn about binary files and how to find out the information inside them? I’m assuming that if you can find information out about how many points are in a PC file, then you should be able to find out at least the first positions of those points yes? If you could possibly “teach a man to fish” on this topic, it would be immensely helpful.
fn pointCachePointCount f =
(
local f = fopen f "rb"
fseek f 16 #seek_set
pointCount = readLong f
fclose f
pointCount
)
Thanks again, very kind of you to share your expertise,
Cg.
The easiest way to figure these types of things out is by saving two files with as little changes between them and comparing the two (in a binary file comparer; I just use Total Commander’s file compare functionality).
So e.g. I made a 1×1 segment plane, saved the file, then changed it to a 2×1 segment plane, and saved another file. Comparing those two files showed a few differences, but the important difference was at byte offset 17, I think (the 17th character in the file, basically), which changed from 04 in the first file to 06 in the second; which, conveniently, is the number of points in each mesh (note that these values are typically displayed as hexadecimal, so after 09 comes 0a, etc.).
I then changed the plane to 100×100 segments, saved again, did another comparison to see where the bytes in the file were going from there to figure out which offset I should actually start reading, and how many bytes should be read.
After that it’s just a matter of poking at the maxscript help file for handling binary files (binstream).
I don’t know how easy it would be to get e.g. the first point (in the file)’s position – but I’d try to find out in much the same way as with the count. E.g. just move a single vertex from one known position to another known position, and check what bytes change in the file – and how they change.
Unfortunately the positions are much more complex than a simple integer count, so that might be a good bit less trivial