Readblend and ListBase

Physics APIs, Physics file formats, Maya, Max, XSI, Cinema 4D, Lightwave, Blender, thinkingParticles™ and other simulation tools, exporters and importers
Post Reply
Sorlaize
Posts: 18
Joined: Sun Mar 29, 2009 5:00 pm

Readblend and ListBase

Post by Sorlaize »

Hi, I can't seem to load a ListBase struct from a .blend, I am importing an armature which has worked, going by the makesDNA headers and this blender page, but I don't really know what I'm doing :P

Here is the problem code:

Code: Select all

void
blend_acquire_armature_from_obj(BlendFile *bf, BlendObject *meobj, bArmature *arm)
{
	{
		BlendObject obj, bListBaseObj, bFirstBoneObj;
		BlendBlockPointer vblock, fblock, cblock, ttblock,mtblock,dblock, matlink, bFirstBonePtr;
		int i;
		int32_t ldata = 123456;
		float fdata1, fdata2, fdata3;

		blend_init_armature(arm);

		if (!(blend_object_structure_getfield(bf, &obj, *meobj,
			"flag") &&
			blend_object_getdata(bf, &ldata, obj))) 
		{
			printf("invalid armature 0x1\n");
			meobj->type = BOBJ_TYPE_INVALID_ARMATURE;
			return;
		}
		arm->flag = ldata;

		if (!(blend_object_structure_getfield(bf, &obj, *meobj,
			"drawtype") &&
			blend_object_getdata(bf, &ldata, obj))) 
		{
				printf("invalid armature 0x2\n");
				meobj->type = BOBJ_TYPE_INVALID_ARMATURE;
				return;
		}
		arm->drawtype = ldata;

		if (!(blend_object_structure_getfield(bf, &obj, *meobj,
			"bonebase") &&
				blend_object_structure_getfield(bf, &bListBaseObj, obj,
				"first") &&
					//blend_object_structure_getfield(bf, &bFirstBoneObj, bListBaseObj,
					//"weight") &&
					blend_object_getdata(bf, &bFirstBonePtr, bListBaseObj))) {
					abort();
		}
This is the part where I'm trying to get some data from the bones. When I step through the second blend_object_structure_getfield() I can see "ListBase" as the type, so it looked as though I was close.

Code: Select all

		if (!(blend_object_structure_getfield(bf, &obj, *meobj,
			"bonebase") &&
				blend_object_structure_getfield(bf, &bListBaseObj, obj,
				"first") &&
					//blend_object_structure_getfield(bf, &bFirstBoneObj, bListBaseObj,
					//"weight") &&
					blend_object_getdata(bf, &bFirstBonePtr, bListBaseObj))) {
					abort();
		}
That code doesn't "abort" but bFirstBonePtr is set to 0 here:

Code: Select all

*(BlendBlockPointer*)dest =
			blend_block_from_blendpointer(blend_file,
			BGETLEUINT32(data));
So I can't get the data that way, it seems! Any thoughts?

Thanks.
Attachments
gk-src-changes.zip
changes to readblend
(24.18 KiB) Downloaded 557 times
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Readblend and ListBase

Post by Erwin Coumans »

ListBase pointers have to be extracted in a special way indeed.

Check out the latest revision of GameKit, I just added some example code how to iterate over a ListBase, object->ipo->curve:
http://code.google.com/p/gamekit/source ... &r=40#1802

The ListBase.first pointer can be extracted manually using

Code: Select all

void** ptrptr = &block->array_entries->field_bytes[block->array_entries->field_offsets[obj2.field_index]];
 BlendBlockPointer ptrlast;
BlendBlockPointer firstptr = *ptrptr;
ptrptr++;
ptrlast= *ptrptr;
if (firstptr)
{
BlendBlockPointer curveblockptr = blend_block_from_blendpointer(bf, firstptr);
BlendObject curve;
BlendBlock* block3;
BlendBlock* block2;
BlendObject newObj,nextOb;
BlendBlockPointer nextPtr;
curve = blend_block_get_object(bf, curveblockptr, 0);
do {
        extract_curve_bezier_triples(bf, &curve);

        //blend_acquire_obj_from_obj(bf,&obj,&tmpObj,0);
        if (!(blend_object_structure_getfield(bf, &nextOb, curve,"next") &&     blend_object_getdata(bf, &nextPtr, nextOb))) 
        {
                printf("error: no next?\n");
        } else
        {
                ///this 'next' object would let you iterate over the linked list until next == 0
                if (nextPtr)
                {
                        BlendBlock* block3;
                        nextOb = blend_block_get_object(bf, nextPtr, 0);
                        block3 = (BlendBlock*)nextOb.block;
                        curve = nextOb;
                }
        }
} while (nextPtr);
}
Then iterate as long as you get a valid next pointer, check the above code snippet for IpoCurve bez

Here is some more background on .blend files
http://atmind.nl/blender/mystery_ot_blend.html
http://www.atmind.nl/blender/blender-sdna-249.html

Extracting ListBase linked lists in Armature objects should be possible in a similar way.

If you manage to get it up and running, do you mind sharing your code?
Thanks,
Erwin

by the way, Blender 2.50 will change several data structures, so we will update readblend once Blender 2.50 is released. Also note that readblend only supports 32bit, little-endian .blend files.
ibkanat
Posts: 1
Joined: Sun Oct 18, 2009 1:38 am

Re: Readblend and ListBase

Post by ibkanat »

I was wondering if there is a plan or way to build this on Linux 64 bit.
Post Reply