Panda3D Eclipse / Pydev setup

Alrighty people, this at least to me seems almost perfect at the moment.

  1. Minor correction to get back Vec3 and friends:
try:
    f.write('%sclass %s:\n%s    def __init__(self):\n%s        pass\n' % (baseIndent, name, baseIndent, baseIndent))
except:
    f.write('%sclass %s:\n%s    def __init__(self):\n%s        pass\n' % (baseIndent, t.__name__, baseIndent, baseIndent))

Full code:

# -*- coding: UTF-8 -*-

import inspect
from panda3d.core import *
import libpanda, libpandaexpress

from panda3d.fx import *
import libpandafx

from panda3d.dtoolconfig import *
import libp3dtoolconfig

from panda3d.physics import *
import libpandaphysics

from panda3d.direct import *
import libp3direct

from panda3d.egg import *
import libpandaegg

from panda3d.ode import *
import libpandaode

from panda3d.bullet import *
import libpandabullet

from panda3d.vision import *
import libp3vision

#from panda3d.physx import *
#import libpandaphysx

from panda3d.ai import *
import libpandaai

#from panda3d.awesomium import *
#import libp3awesomium

#from panda3d.speedtree import *
#import libpandaspeedtree

from panda3d.rocket import *
import _rocketcore, _rocketcontrols, libp3rocket

BUILD = {
    'fx'           : [libpandafx]
    ,'core'        : [libpanda, libpandaexpress]
    ,"dtoolconfig" : [libp3dtoolconfig]
    ,"physics"     : [libpandaphysics]
    ,"fx"          : [libpandafx]
    ,"direct"      : [libp3direct]
    ,"egg"         : [libpandaegg]
    ,"ode"         : [libpandaode]
    ,"bullet"      : [libpandabullet]
    ,"vision"      : [libp3vision]
#    ,"physx"       : [libpandaphysx]
    ,"ai"          : [libpandaai]
#    ,"awesomium"   : [libp3awesomium]
#    ,"speedtree"   : [libpandaspeedtree]
    ,"rocket"      : [_rocketcore, _rocketcontrols, libp3rocket],
}

indent = '    '
importptrn = 'from panda3d.%s import %s'
skip = [
                'DtoolGetSupperBase',
                'DtoolClassDict'
             ]

def record(t, name, f, noclasses=False, baseIndent=''):
    if name.startswith('__'): return
    if isinstance(t, int):
        f.write('%s%s = int\n\n' % (baseIndent, name))
        return True
    elif isinstance(t, float):
        f.write('%s%s = float\n\n' % (baseIndent, name))
        return True
    elif isinstance(t, str):
        f.write('%s%s = str\n\n' % (baseIndent, name))
        return True
    elif inspect.isclass(t):
        if noclasses: return
        try:
            f.write('%sclass %s:\n%s    def __init__(self):\n%s        pass\n' % (baseIndent, name, baseIndent, baseIndent))
        except:
            f.write('%sclass %s:\n%s    def __init__(self):\n%s        pass\n' % (baseIndent, t.__name__, baseIndent, baseIndent))
        
        for _name in dir(t):
            if _name in skip:
                continue
            try:
                _t = eval('%s.%s' %(name, _name))
            except:
                return False
            record(_t, _name, f, noclasses=True, baseIndent=('%s    ' % baseIndent))
             
        return True
         
    elif callable(t):
        if hasattr(t, '__objclass__'):
            f.write('%sdef %s(self):\n%s    pass\n' % (baseIndent, t.__name__, baseIndent))
        else:
            f.write('%sdef %s():\n%s    pass\n' % (baseIndent, t.__name__, baseIndent))
            return True
    return False

def generateCore(base_name, modules):
 
    f = open('predef/panda3d.%s.pypredef' % base_name, 'w+')

    for module in modules:
        for name in dir(module):
            try:
                exec(importptrn % (base_name, name))
                t = eval(name)
             
                print "Building %s..." % name
                record(t, name, f)
             
            except Exception, e:
                print e
                continue
         
    f.close()
     
if __name__ == '__main__':
    for (name, module) in BUILD.items():
        generateCore(name, module) 
  1. I made panda3d importer module which aids pydev autocompletion. What it does is importing most common stuff, and asserts their types to help pydev figure them out.
  • p3d.py *
'''
* The Great panda3d/pydev autocompletion *
*        code is in public domain        *
Created on Nov 29, 2012
@author: rndbit

1. Use generated predefines
2. Insert 'direct' and 'panda3d' to forced builtins
3. Edit pycompletionserver.py (located somewhere like in C:\Program Files\Eclipse\plugins\org.python.pydev_2.7.1.2012100913\pysrc\ )
   Insert after 'currDirModule = None':
   try:
       from pandac.PandaModules import loadPrcFileData
       loadPrcFileData("", "window-type none")
       import direct
       import direct.directbase.DirectStart
   except:
       pass
'''

import direct, __builtin__, panda3d
from panda3d import core, dtoolconfig, physics, fx, egg, ode, bullet, vision, rocket, ai #, physx, awesomium, speedtree
import direct.directbase.DirectStart
from panda3d.core import Vec2, Vec2D, Vec2F, Vec3, Vec3F, Vec3D, Vec4, Vec4F, Vec4D,\
        Point2, Point2D, Point2F, Point3, Point3D, Point3F, Point4, Point4D, Point4F,\
        VBase2, VBase2D, VBase2F, VBase3, VBase3D, VBase3F, VBase4, VBase4D, VBase4F
from direct.stdpy.file import *
from direct.stdpy import threading2 as threading

if not hasattr(__builtin__, 'base'):
    base          = None
    aspect2d      = None
    aspect2dp     = None
    bboard        = None
    bpdb          = None
    camera        = None
    config        = None
    cpMgr         = None
    deltaProfiler = None
    directNotify  = None
    direct        = None
    eventMgr      = None
    globalClock   = None
    jobMgr        = None
    loader        = None
    messenger     = None
    onScreenDebug = None
    ostream       = None
    pixel2d       = None
    pixel2dp      = None
    render        = None
    render2d      = None
    render2dp     = None
    taskMgr       = None
    vfs           = None

assert isinstance(base, direct.showbase.ShowBase.ShowBase)
assert isinstance(aspect2d, core.NodePath)
assert isinstance(aspect2dp, core.NodePath)
assert isinstance(bboard, direct.showbase.BulletinBoard.BulletinBoard)
assert isinstance(bpdb, direct.showbase.BpDb.BpDb)
assert isinstance(camera, core.NodePath)
assert isinstance(config, core.DConfig)
assert isinstance(cpMgr, core.ConfigPageManager)
assert isinstance(deltaProfiler, direct.directutil.DeltaProfiler.DeltaProfiler)
assert isinstance(directNotify, direct.directnotify.DirectNotify.DirectNotify)
assert isinstance(eventMgr, direct.showbase.EventManager.EventManager)
assert isinstance(globalClock, core.ClockObject)
assert isinstance(jobMgr, direct.showbase.JobManager.JobManager)
assert isinstance(loader, direct.showbase.Loader.Loader)
assert isinstance(messenger, direct.showbase.Messenger.Messenger)
assert isinstance(onScreenDebug, direct.showbase.OnScreenDebug.OnScreenDebug)
assert isinstance(ostream, core.ostream)
assert isinstance(pixel2d, core.NodePath)
assert isinstance(pixel2dp, core.NodePath)
assert isinstance(render, core.NodePath)
assert isinstance(render2d, core.NodePath)
assert isinstance(render2dp, core.NodePath)
assert isinstance(taskMgr, direct.task.Task.TaskManager)
assert isinstance(vfs, core.VirtualFileSystem)

And usage is as simple as from p3d import *

  1. A tiny trick for pydev autocompletion server to get proper panda3d autocompletions. Following snippet in pyautocompletionserver.py makes all the difference:
try:
    import direct
    import direct.directbase.DirectStart
except:
    pass

See p3d.py comment above for more detailed instructions.

EDIT:
Actually its not perfect yet, we need function docs in docstrings \o/

EDIT2:
Forgot to mention that path Panda3D-1.8.0\direct has to be added to libraries.