Many troubles exporting models to egg

Hello All,

I’m new to panda3d and I’m loving the engine, except the model pipeline.
This has been bothering me for a couple of days now.
Here are my failed attempts of getting a useful model into panda:

Couldn’t install any of the plugins both in 3DS max nor maya. Max’s plugin is apparently unmaintained and Maya is 64 bit.

Model in maya (simple cube) > export to binary (.mb) > use maya2egg2012:
Failed. My maya is 64 bit and the tool is 32 bit.
I could compile from source to try and fix this, but after spending 4 hours on my mac (I’m on windows now) compiling from source,
I am not willing to do that again (had to fix inumerous problems in the build script. It didnt find the headers paths nor the libs. there were so many -L/bla/bla -I/bla/bla -lpython I get nightmares with gcc now).

Model in Max (simple cube) > export Collada .DAE > use dae2eggg:
Actually worked! At this point I’m somewhat excited. The designer of the game (I’m the programmer)
does not use Max, so lets try Collada from maya.

Model in Maya (simple cube) > export Collada .DAE > use dae2eggg:
Worked too!
Finally! let’s try some more things.

I want to test if animations are well supported by the dae2egg converter.
Max (don’t really know how to use maya. Designer will replicate my experiment with maya. I’ll keep you posted.) > create cilinder > create some bones > create a HI solver for the bones > rig the cilinder to the bones > make a simple 3-keyframe animation (cilinder contracts and then expands back out).
Simplest animation one can make right?
Except now I cant convert it to egg, dae2egg simply goes OOM.
Seriously, OOM?? 3GB+ of memory is not enough to convert a simple cilinder with bones (no pun intended)??

Here’s the log:

C:\Users\Salvia\Desktop>dae2egg minhoca.DAE minhoca.egg

Reading minhoca.DAE
:daeegg(warning): Invalid integer in <frame_rate> tag: '30.000000'
Couldn't allocate memory page of size 131072: Error code 8

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

C:\Users\Salvia\Desktop>

The process crashes after +/- 2GB of mem utilization.

So, what I’m I doing wrong?
In before: Yes the cilinder is somewhat high poly, but not nearly enough to cause a OOM! If I’m getting OOM with a cilinder, god only knows what will happen when I try to convert a character, for example.
I’m thinking this is some sort of malloc loop or the program is leaking very badly. Where can I find the source code of this tool so I can try to debug it?
By the way I’m attaching the cilinder (minhoca.TXT, just rename it to whatever .DAE).

I really need some efficient pipeline which can give me easy export from maya to panda3d.
Where can I find a version of the maya plugin which works in maya 2014 64 bit?

In before again:
Panda3D 1.8.1 straight from download page (windows installer).
AMD Bulldozer x6, 4GB Ram, Radeon R9 270x.
Windows 7 x64
Maya 2012 and 2014
Max 2015

Really Guys, any directions on how to export from maya correctly
minhoca.txt (85.5 KB)

After much pain I was able to import it in blender, and then use YABEE to make the .egg.
With animation and whatnot.
Nevertheless it bothers me having to go thru so much trouble to just export a model.

b.t.w why 3DS and Maya used compiled plugins, which incompatible with different arh and versions? I’ve just googgled and seems that both editors supports various scripting systems. Perhaps it make sense to rewrite it with using scripts? Or remake dae2egg also with script. Sure, compiled plugins is faster, but exporting is not realtime task.

I think there are just to few 3ds/maya panda3d users. Maya scripting language is python but 3ds uses ‘maxscript’ so that’s an extra challenge. I know someone wanted to write a maxscript exporter a year or two ago, but it never got beyond exporting a static mesh.
There was also a lot of talk about better collada support some time ago - but I don’t think we have animation support for dae.

Hmm improving dae support or at least dae2egg seems the better solution for max/maya users

addition: seems max supports python docs.autodesk.com/3DSMAX/16/ENU/ … index.html

There are 64-bit builds of Panda, which should work with 64-bit versions of Autodesk Maya. The recent development builds are available for 64-bit Windows. I’ve made public builds for 64-bit OS X as well, though I’m not certain if those contain Maya exporters.

These should do the trick for Windows, even if they’re a little old:
panda3d.org/download.php?pl … =devel&sdk

For what it’s worth, animations aren’t supported by the dae2egg exporter. Sorry. :frowning: It’s not supposed to crash, though. I’ll look into that. But you can’t use this route for animated models anyway.

@ninth: it’s problematic to use Python in the Maya exporter. The main issue is that Maya itself comes with its own version of Python, which may be incompatible with Panda’s. We therefore have to isolate Panda’s Python from Maya’s Python, which is tricky enough in itself. The alternative is that the exporter runs independently of Panda, like YABEE, but then we lose the advantages of being able to use the EggData API.

I’m not sure that is such a bad thing. I can imagine that someone making a model for Panda3D may not have the SDK installed.

There’s also one ‘universal’ file format that has no p3d support - FBX.

It took me about an hour to hack up a pure Python fbx2egg converter for static models (in about 100 lines of code). Now I need to make a break, but when I’ll return I’ll try to add animations support for it (if I figure out how the animation is stored, bones/joints look simple). If it works I’ll publish it all, should be a good alternative.

Thanks for all the replies guys. I’ve convinced the designer to use blender + YABEE for now (not ideal, but should work).

Yes, FBX is ‘universal’ and panda does not support it. Every major 3d modelling software exports FBX nowadays, and is the de facto format for Unity3d. I think the community would benefit greatly if FBX SDK was integrated into panda.
I also agree that standalone (or script for the software, but independent of panda) is better. The designer is really a designer, he doesn’t have a clue of how to use window’s cmd, and it being standalone is much easier to write a GUI with tkinter without having to worry about finding dependencies.

This is the case. He installed the SDK as I told him, but he have no clue about using cmdline tools. Its painful trying to explain it over skype.
Wezu: I would like very much to see this code you made and contribute. What about you create a github (or whatever) repo?

Finally: Scripted > Compiled in that case. If it was a python script and not a binary I would be able to open it and fix it. Also I would have 50% less problems (because half my problems were about binary compatibility).

As maya supports python I’m thinking of forking YABEE and using maya API. Don’t know how much trouble that would be though.

It’s a bit of a shame that you couldn’t get maya2egg to work. It certainly does work, and has been used for many years by Disney and CMU.

I would applaud any effort to create an FBX importer for Panda.

rdb:
At some point yesterday I was able to make it work (don’t recall exactly what I did) but the exported .egg didn’t have any animations ( .getAnimNames() returned [] ) and the texture path was hardcoded (something like C:/Users/Felipe/Documents/models/tex/uv.png, Felipe is the designer who exported the .mb and I don’t have a user Felipe on my computer. Creating this directory structure made it work, but this is horribly bad.)
I’m not saying maya2egg is a bad tool, I’m just saying Its really hard to use.
I can certainly try it again tonight if you give me some insight.

By the way, where the egg nomenclature comes from?
If I recall .egg is an old way to pack python programs (it was just a .zip with some special header or something).

Well, as I said this is an hours work of hacking - not much yet, and a little ugly on the sides:

import os, sys

in_file=sys.argv[1]
out_file=sys.argv[2]

#data needed to construct an egg
#geometry
group=[]
vertex=[]
tangent=[]
binormal=[]
normal=[]
polygon=[]
uv=[]
texture=[]
weight=[]
joint=[]

isVertex=False
isTangent=False
isBinormal=False
isNormal=False
isPolygon=False
isUV=False

#read the fbx file
with open(in_file,'r') as fbx:
    for line in fbx:
        if isVertex:
            vertex.append(line.strip('a: ').strip('\n').split(','))
            isVertex=False
        elif isPolygon:
            polygon.append(line.strip('a: ').strip('\n').split(','))
            isPolygon=False   
        elif isNormal:
            normal.append(line.strip('a: ').strip('\n').split(','))
            isNormal=False  
        elif isBinormal:
            binormal.append(line.strip('a: ').strip('\n').split(','))
            isBinormal=False
        elif isTangent:
            tangent.append(line.strip('a: ').strip('\n').split(','))
            isTangent=False
        elif isUV:
            uv.append(line.strip('a: ').strip('\n').split(','))
            isUV=False
            
        if line.strip().startswith('Model:') and line.strip().endswith('"Mesh" {'):
            temp=line.strip().split(',')
            #should be ['Model/Geometry: {some_number}', '"Model::{some_name}"', '"Mesh" {']
            group.append((temp[0].strip('Model: '), temp[1].strip('"Model:: "')))
        elif line.strip().startswith('Vertices'):
            isVertex=True
        elif line.strip().startswith('PolygonVertexIndex'):
            isPolygon=True
        elif line.strip().startswith('Normals'):
            isNormal=True    
        elif line.strip().startswith('Binormals'):
            isBinormal=True 
        elif line.strip().startswith('Tangents'):
            isTangent=True  
        elif line.strip().startswith('UV:'):
            isUV=True    
         
#convert the fbx data to egg data  
egg_data={}
index=0
for gr in group:
    egg_vertex=[]
    egg_normal=[]
    egg_tangent=[]
    egg_binormal=[] 
    for i in range(0, len(vertex[index]), 3):           
        egg_vertex.append((vertex[index][i], vertex[index][i+1], vertex[index][i+2]))  
        egg_normal.append((normal[index][i], normal[index][i+1], normal[index][i+2]))
        if tangent:
            egg_tangent.append((tangent[index][i], tangent[index][i+1], tangent[index][i+2]))
            egg_binormal.append((binormal[index][i], binormal[index][i+1], binormal[index][i+2]))
        
    egg_uv=[]
    for i in range(0, len(uv[index]), 2):
        egg_uv.append((uv[index][i], uv[index][i+1]))
     
    egg_poly=[]
    poly=[]
    for v in polygon[index]:
        if int(v)>-1:
            poly.append(v)
        else:
            poly.append(int(v)*(-1)-1)
            egg_poly.append(poly)
            poly=[]
    egg_data[gr[1]]={'vertex':egg_vertex,
                    'normal':egg_normal,
                    'tangent':egg_tangent,
                    'binormal':egg_binormal, 
                    'uv':egg_uv,
                    'poly':egg_poly
                    } 
    index+=1                        
#write the egg file    
with open(out_file,'w') as egg:
    egg.write('<CoordinateSystem> { Z-Up }\n\n')
    for group in egg_data:
        egg.write('<Group> '+group+' {\n')
        egg.write('    <VertexPool> '+group+'.verts {\n')
        i=0
        for v in egg_data[group]['vertex']: 
            egg.write('        <Vertex> '+str(i)+' {\n')
            egg.write('        '+'{0} {1} {2}'.format(*v)+'\n')
            egg.write('            <Normal> {'+'{0} {1} {2}'.format(*egg_data[group]['normal'][i])+'}\n')
            egg.write('            <UV> {\n')
            egg.write('                {0} {1}\n'.format(*egg_data[group]['uv'][i]))
            if tangent:
                egg.write('                <Tangent> {'+'{0} {1} {2}'.format(*egg_data[group]['tangent'][i])+'}\n')
                egg.write('                <Binormal> {'+'{0} {1} {2}'.format(*egg_data[group]['binormal'][i])+'}\n')
            egg.write('            }\n')
            egg.write('        }\n')
            i+=1
        egg.write('    }\n')
        for v in egg_data[group]['poly']:
            egg.write('    <Polygon> {\n')
            egg.write('    <VertexRef> { ')
            for n in v:
                egg.write(str(n)+" ")
            egg.write(' <Ref> { '+group+'.verts } }\n')
            egg.write('    }\n')
        egg.write('}')         
 

At this point it can convert a mesh, but without textures, animations and the normals aren’t always correct if the fbx had smoothing groups and/or(?) hard edges (like a box). I didn’t yet have time to fix the problems and move to bones and animations.

I’m probably not the most competent person to make this kind of software, but I should be able to get something working.

wezu: thanks for the code! I will look at it carefully later tonight. But at first glance it looks like to much manual effort (codewise). Wouldn’t the FBX python SDK take care of this kind of bureaucracy?

It’s buggy and I had to rewrite a part of it to get the normals and uvs right (I needed to clone some verts, in fbx the normals and uv are 3 per triangle, so you can have 12 verts and 60 normals).
I’ll make a git tomorrow, got stuck on getting textures to work (can’t tell what object/mesh/geom is using what texture).

The fbx sdk could work, but I didn’t find any docs on the python api, so I’m doing it the hard way.

I’m not exactly sure. I haven’t really used maya2egg myself, to be honest. Are you using the GUI or the maya2egg tool? If the latter, the documentation states that you can control whether to export animations with the -a flag:

maya2egg -a model -o eggFileName.egg mayaFileName.mb 
maya2egg -a chan -o eggFileName.egg mayaFileName.mb 
maya2egg -a pose -o eggFileName.egg mayaFileName.mb 
maya2egg -a both -o eggFileName.egg mayaFileName.mb 

The meanings of these options are:
-a model	Save only the skinned and boned model, ready for animation but with no animation attached. This is ideal for models with several event- or interaction-based animations.
-a chan	Save only the animation data on the current model, but not the model itself. This is ideal applying animations to an already-existing model egg file that is ready to receive animation. A model may have several animation channels applied to it.
-a pose	Save the model in the current key position of the animation applied to it. This position must be selected before choosing to export the file. This format does not save the animation.
-a both	This will export the model and animation out as one file.

The texture problem sounds like it could be easily remedied by hand-editing the resulting .egg file (it’s a human-readable format) to change the texture paths to relative paths.

The Panda .egg format existed long before the Python .egg format was introduced.

this is old thread, but seen you talk about GUI and wanted to post a link here to my more current MayaPandaUI I redid a while back so it actually works, lol. [url]Updated MayaPandaUI Interface - Egg & Bam Exporter for Maya]
This one should work on numerous Maya builds as I’ve used it on 2012x32 up to current 2015x64. Might be a nice thing to have this working version included in the Panda3D releases for others to have easy access to?? :wink:

~Sean~