From: Jérôme Hénin (jhenin_at_ifr88.cnrs-mrs.fr)
Date: Thu May 27 2010 - 07:27:00 CDT

Hi all,

I have a VMD-hacking problem, which might be similar to what some of
you have tried. We'd like to have Tcl-wrapped C++ code do some calculations
efficiently, accessing VMD's atom coordinate data directly. Ideally,
that would be dynamically loaded, and not require recompiling VMD.

We have a python hack, where the python "timestep" routine (from
py_numeric.C) is called to get a python array, from which one can
extract the C pointer and work directly with it.

There is an interestingly ugly Tcl variant where a small Tcl routine
(added to TclCommands.C) gets the pointer (i.e.
myMolecule->get_frame(myFrame)->pos), casts it to a long int and
returns that. The integer is passed to my Tcl-C++ "plugin" (loaded
from a shared object), which casts it back to (float *), and goes on
to do the computation. This, on top of being ugly, requires inserting
this little Tcl hook and recompiling VMD. Amazingly though,
it works just fine.

In yet another variant, I have tried to eliminate the middle-man and
the need to modify and compile VMD by accessing VMD's internals
directly from my dynamically loaded C++ code. This felt a bit dangerous:
I was surprised that it worked up to a point, and then disappointed
that it didn't work all the way. Here are a few relevant lines from that
function:

VMDApp *app = (VMDApp *)Tcl_GetAssocData(interp, (char *)"VMDApp", NULL);
Molecule *mol = app->moleculeList->top();
Timestep *ts = mol->get_frame(0);

The result is the following: I do get a pointer to the top molecule,
but calling methods from that object essentially give me garbage (e.g.
the returned pointer from get_frame is off). I suppose that these are
not supposed to be called from external, dynamically loaded code, but
I don't understand all the details, for example, why the calls to
VMDApp methods do give me the right answers.

Could anyone point me to information that would help me understand
this? Does anyone have an opinion on a better way to obtain this kind
of "lightweight plugin" functionality?

Thanks,
Jerome