Hi, I exported a .bin file from RealFlow 4 and now need to be able to read it in Python, to make an importer. How do these files work?
+1
A:
You need to know how the data is coded in the file. If you have this information, you can use the struct package to convert the binary data to something that can be used in python.
I hope it helps
luc
2009-11-08 13:30:40
How can I search for information about it?
Gabriele Cirulli
2009-11-08 14:30:43
@terabytest: Check Ned's comment to see how to obtain them (you may have to unfold the comments with the `add / show .. more comments`).
RedGlyph
2009-11-08 14:41:32
A:
Thanks guys, I've found the file. Here I uploaded it, and included a particle file for you.
Gabriele Cirulli
2009-11-08 15:06:35
+3
A:
Here you go:
import struct
class Particle:
"""A single particle. Attributes added in BinFile."""
pass
class BinFile:
"""Parse and store the contents of a RealFlow .bin file."""
def __init__(self, fname):
self.bindata = open(fname, "rb").read()
self.off = 0
self.verify = self.peel("=i")[0]
assert self.verify == 0xfabada
self.name = self.string(250)
(self.version, self.scale, self.fluid_type, self.simtime, self.frame_number,
self.fps, self.num_particles, self.radius) = self.peel("=hfifiiif")
self.pressure = self.peel("=fff")
self.speed = self.peel("=fff")
self.temperature = self.peel("=fff")
if self.version >= 7:
self.emitter_position = self.peel("=fff")
self.emitter_rotation = self.peel("=fff")
self.emitter_scale = self.peel("=fff")
self.particles = [self.peel_particle() for i in range(self.num_particles)]
def peel_particle(self):
"""Read one particle from the file."""
p = Particle()
p.position = self.peel("=fff")
p.velocity = self.peel("=fff")
p.force = self.peel("=fff")
if self.version >= 9:
p.vorticity = self.peel("=fff")
if self.version >= 3:
p.normal = self.peel("=fff")
if self.version >= 4:
p.neighbors = self.peel("=i")[0]
if self.version >= 5:
p.texture = self.peel("=fff")
p.infobits = self.peel("=h")[0]
(p.age, p.isolation_time, p.viscosity, p.density, p.pressure, p.mass,
p.temperature, p.id) = self.peel("=fffffffi")
print p.id, p.neighbors, p.position
return p
def peel(self, fmt):
"""Read some struct data from `self.bindata`."""
data = struct.unpack_from(fmt, self.bindata, self.off)
self.off += struct.calcsize(fmt)
return data
def string(self, length):
s = self.bindata[self.off:self.off+length].split("\0")[0]
self.off += length
return s
b = BinFile("Circle0100001.bin")
print "Name:", b.name
print "Particles:", b.num_particles
print "Position of first particle", b.particles[0].position
When run on your sample data, it prints:
Name: Circle01
Particles: 1066
Position of first particle (-1.7062506675720215, 4.9283280372619629, -6.4365010261535645)
Ned Batchelder
2009-11-08 16:22:48
There's still a problem with this.When I add the particles in Blender as vertexes, the farthest we go in the list the strangest positions they take. At the end of the list I got particles with positions of(0.00084405858069658279, 7.0503529635574521e-41, 2.2779507836064226e-41)or(201863462912.0, -9.4222019546613521e-38, 2.0722401690435395e-41)And it gives a bad result.I'd need to know if the problem is with the script you wrote or in the bin file itself, and if there's a fix of some sort.
Gabriele Cirulli
2009-11-08 20:43:04
Add some debugging print statements to this script to see if the positions get strange toward the end of the list. If they don't, then the problem is in your Blender script.
Ned Batchelder
2009-11-08 21:21:26
I just checked and they have weird values distributed all over the list, not just in the end. I think the error isn't in my script because I print these values when I read them off the particle, with no elaboration.
Gabriele Cirulli
2009-11-08 21:39:09
You are right: I updated the program in the answer. I had one field of the wrong width, and had skipped a few fields.
Ned Batchelder
2009-11-08 21:43:14
Last thing: is there a way to speed up the loading of the file?
Gabriele Cirulli
2009-11-08 22:36:48