1

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?

H H
  • 263,252
  • 30
  • 330
  • 514
kettlepot
  • 10,574
  • 28
  • 71
  • 100
  • 2
    I concur with jldupont on that one. Besides, it looks like a duplicate (I suppose you don't mean to write the whole parser?): http://stackoverflow.com/questions/1035340/reading-binary-file-in-python – RedGlyph Nov 08 '09 at 12:18
  • Sorry, I didn't know I had to. – kettlepot Nov 08 '09 at 12:51
  • Thanks to RedGlyph I managed to read the file, but now I have a long string containing it all and it's formed from /xNN characters and sometimes there are some words. Here's a little piece '\xda\xba\xfa\x00Square01\x00lflow.bin\x00\x0001\x9bs\x84\x86\x9dsp\x86\x9dsh\xea\xef\x08\xc8\xad\xd4\t\x00\x01\x00\x00h\xea\xef\x08\xe0+\x9bsA1\x9bs\xc8\xad\xd4\t\xab' Now, in these characters i'm sure there are x y z coordinates of particles, but I don't have the minimum clue how to get them out of the "codes". – kettlepot Nov 08 '09 at 13:07
  • 2
    RealFlow .bin files don't seem to be widely documented. I found this somewhere: "The BIN file format specifications are provided by Next Limit in PDF format as part of the RealFlow application (included in the evaluation version). Please download the evaluation version of RealFlow or purchase the full product if you need the specs." If you have the spec someplace, we could help you with a Python interpretation of it. – Ned Batchelder Nov 08 '09 at 13:27

3 Answers3

5

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
  • 364,293
  • 75
  • 561
  • 662
  • 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.277950783606 4226e-41) or (201863462912.0, -9.4222019546613521e-38, 2.0722401690435395e-4 1) 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. – kettlepot Nov 08 '09 at 20:43
  • 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 Nov 08 '09 at 21:21
  • 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. – kettlepot Nov 08 '09 at 21:39
  • 1
    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 Nov 08 '09 at 21:43
  • Last thing: is there a way to speed up the loading of the file? – kettlepot Nov 08 '09 at 22:36
2

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
  • 41,928
  • 25
  • 127
  • 172
  • 1
    @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 Nov 08 '09 at 14:41
0

Thanks guys, I've found the file. Here I uploaded it, and included a particle file for you.

http://www.mediafire.com/download.php?xujqjghkcim

kettlepot
  • 10,574
  • 28
  • 71
  • 100