00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "py_commands.h"
00022 #include "CommandQueue.h"
00023 #include "VMDApp.h"
00024 #include "Molecule.h"
00025 #include "MoleculeList.h"
00026 #include "Animation.h"
00027
00028
00029 static const char once_doc[] = "Animate once through all frames.";
00030 static PyObject *py_once(PyObject *self, PyObject *args) {
00031 VMDApp *app;
00032 if (!(app = get_vmdapp()))
00033 return NULL;
00034
00035 app->animation_set_style(Animation::ANIM_ONCE);
00036
00037 Py_INCREF(Py_None);
00038 return Py_None;
00039 }
00040
00041
00042
00043 static const char rock_doc[] = "Animate back and forth between first and last frames.";
00044 static PyObject *py_rock(PyObject *self, PyObject *args) {
00045 VMDApp *app;
00046 if (!(app = get_vmdapp()))
00047 return NULL;
00048
00049 app->animation_set_style(Animation::ANIM_ROCK);
00050
00051 Py_INCREF(Py_None);
00052 return Py_None;
00053 }
00054
00055
00056
00057 static const char loop_doc[] = "Animate in a continuous loop.";
00058 static PyObject *py_loop(PyObject *self, PyObject *args) {
00059 VMDApp *app;
00060 if (!(app = get_vmdapp()))
00061 return NULL;
00062
00063 app->animation_set_style(Animation::ANIM_LOOP);
00064
00065 Py_INCREF(Py_None);
00066 return Py_None;
00067 }
00068
00069
00070
00071 static const char style_doc[] =
00072 "Returns current animation style\n\n"
00073 "Returns:\n"
00074 " (str) style, in ['Rock', 'Once', 'Loop']";
00075 static PyObject *py_style(PyObject *self, PyObject *args) {
00076 VMDApp *app;
00077 if (!(app = get_vmdapp()))
00078 return NULL;
00079
00080 int stylenum = app->anim->anim_style();
00081 return as_pystring((char*) animationStyleName[stylenum]);
00082 }
00083
00084
00085
00086 static const char goto_doc[] =
00087 "Display a givenframe on the next display update\n\n"
00088 "Args:\n"
00089 " frame (int): Frame index to display";
00090 static PyObject *py_anim_goto(PyObject *self, PyObject *args, PyObject *kwargs) {
00091 const char *kwnames[] = {"frame", NULL};
00092 int frame;
00093
00094 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:animate.goto",
00095 (char**) kwnames, &frame))
00096 return NULL;
00097
00098 VMDApp *app;
00099 if (!(app = get_vmdapp()))
00100 return NULL;
00101
00102 app->animation_set_frame(frame);
00103
00104 Py_INCREF(Py_None);
00105 return Py_None;
00106 }
00107
00108
00109
00110 static const char reverse_doc[] = "Start animating frames in reverse order.";
00111 static PyObject *py_reverse(PyObject *self, PyObject *args) {
00112 VMDApp *app;
00113 if (!(app = get_vmdapp()))
00114 return NULL;
00115
00116 app->animation_set_dir(Animation::ANIM_REVERSE);
00117
00118 Py_INCREF(Py_None);
00119 return Py_None;
00120 }
00121
00122
00123
00124 static const char forward_doc[] = "Start animating frames in forward order.";
00125 static PyObject *py_forward(PyObject *self, PyObject *args) {
00126 VMDApp *app;
00127 if (!(app = get_vmdapp()))
00128 return NULL;
00129 app->animation_set_dir(Animation::ANIM_FORWARD);
00130
00131 Py_INCREF(Py_None);
00132 return Py_None;
00133 }
00134
00135
00136
00137 static const char prev_doc[] = "Animate to the previous frame and stop.";
00138 static PyObject *py_prev(PyObject *self, PyObject *args) {
00139 VMDApp *app;
00140 if (!(app = get_vmdapp()))
00141 return NULL;
00142
00143 app->animation_set_dir(Animation::ANIM_REVERSE1);
00144
00145 Py_INCREF(Py_None);
00146 return Py_None;
00147 }
00148
00149
00150
00151 static const char next_doc[] = "Animate to the next frame and stop.";
00152 static PyObject *py_next(PyObject *self, PyObject *args) {
00153 VMDApp *app;
00154 if (!(app = get_vmdapp()))
00155 return NULL;
00156
00157 app->animation_set_dir(Animation::ANIM_FORWARD1);
00158
00159 Py_INCREF(Py_None);
00160 return Py_None;
00161 }
00162
00163
00164
00165 static const char pause_doc[] = "Pause the animation.";
00166 static PyObject *py_pause(PyObject *self, PyObject *args) {
00167 VMDApp *app;
00168 if (!(app = get_vmdapp()))
00169 return NULL;
00170
00171 app->animation_set_dir(Animation::ANIM_PAUSE);
00172
00173 Py_INCREF(Py_None);
00174 return Py_None;
00175 }
00176
00177
00178
00179 static const char speed_doc[] =
00180 "Set or get animation speed\n\n"
00181 "Args:\n"
00182 " value (float): New value for speed, between 0 and 1, or None to query\n"
00183 "Returns:\n"
00184 " (float) Current value for speed";
00185 static PyObject *py_speed(PyObject *self, PyObject *args, PyObject *kwargs) {
00186 const char *kwnames[] = {"value", NULL};
00187 float value = -1.0f;
00188
00189 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|f:animate.speed",
00190 (char**) kwnames, &value))
00191 return NULL;
00192
00193 VMDApp *app;
00194 if (!(app = get_vmdapp()))
00195 return NULL;
00196
00197 if (value != -1.0f) {
00198 if (value < 0.0f || value > 1.0f) {
00199 PyErr_SetString(PyExc_ValueError, "speed must be between 0 and 1");
00200 return NULL;
00201 }
00202 app->animation_set_speed(value);
00203 }
00204
00205
00206 return PyFloat_FromDouble(app->anim->speed());
00207 }
00208
00209
00210
00211 static const char skip_doc[] =
00212 "Set or get stride for animation frames. A skip value of 1 shows every frame,\n"
00213 "a value of 2 shows every other frame, etc.\n\n"
00214 "Args:\n"
00215 " value (int): New value for stride, or None to query\n\n"
00216 "Returns:\n"
00217 " (int) Current value for stride";
00218 static PyObject *py_skip(PyObject *self, PyObject *args, PyObject *kwargs) {
00219 const char *kwnames[] = {"value", NULL};
00220 int skip = 0;
00221
00222 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:animate.stride",
00223 (char**) kwnames, &skip))
00224 return NULL;
00225
00226 VMDApp *app;
00227 if (!(app = get_vmdapp()))
00228 return NULL;
00229
00230 if (skip) {
00231 if (skip < 1) {
00232 PyErr_SetString(PyExc_ValueError, "skip must be 1 or greater");
00233 return NULL;
00234 }
00235 app->animation_set_stride(skip);
00236 }
00237
00238 return as_pyint(app->anim->skip());
00239 }
00240
00241
00242
00243 static const char is_active_doc[] =
00244 "Returns whether a given molecule is active (updated during animation)\n\n"
00245 "Args:\n"
00246 " molid (int): Molecule ID to query\n\n"
00247 "Returns:\n"
00248 " (bool) If molecule is active";
00249 static PyObject *py_is_active(PyObject *self, PyObject *args, PyObject *kwargs) {
00250 const char *kwnames[] = {"molid", NULL};
00251 Molecule *mol;
00252 int molid;
00253
00254 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:animate.is_active",
00255 (char**) kwnames, &molid))
00256 return NULL;
00257
00258 VMDApp *app;
00259 if (!(app = get_vmdapp()))
00260 return NULL;
00261
00262 if (!(mol = app->moleculeList->mol_from_id(molid))) {
00263 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id");
00264 return NULL;
00265 }
00266
00267 return mol->active ? Py_True : Py_False;
00268 }
00269
00270
00271
00272 static const char activate_doc[] =
00273 "Set the active status of a molecule. Active molecules update their coordinate"
00274 " frames during animation, inactive ones do not.\n\n"
00275 "Args:\n"
00276 " molid (int): Molecule ID to change\n"
00277 " active (bool): New active status of molecule.";
00278 static PyObject *py_activate(PyObject *self, PyObject *args, PyObject *kwargs) {
00279 const char *kwnames[] = {"molid", "active", NULL};
00280 int status;
00281 int molid;
00282
00283 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO&:animate.activate",
00284 (char**) kwnames, &molid, convert_bool,
00285 &status))
00286 return NULL;
00287
00288 VMDApp *app;
00289 if (!(app = get_vmdapp()))
00290 return NULL;
00291
00292 Molecule *mol;
00293 if (!(mol = app->moleculeList->mol_from_id(molid))) {
00294 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id");
00295 return NULL;
00296 }
00297
00298 app->molecule_activate(molid, status);
00299
00300 Py_INCREF(Py_None);
00301 return Py_None;
00302 }
00303
00304
00305 static PyMethodDef methods[] = {
00306 {"once", (PyCFunction) py_once, METH_NOARGS, once_doc},
00307 {"rock", (PyCFunction) py_rock, METH_NOARGS, rock_doc },
00308 {"loop", (PyCFunction) py_loop, METH_NOARGS, loop_doc },
00309 {"style", (PyCFunction) py_style, METH_NOARGS, style_doc },
00310 {"goto", (PyCFunction) py_anim_goto, METH_VARARGS | METH_KEYWORDS, goto_doc },
00311 {"reverse", (PyCFunction) py_reverse, METH_NOARGS, reverse_doc },
00312 {"forward", (PyCFunction) py_forward, METH_NOARGS, forward_doc },
00313 {"prev", (PyCFunction) py_prev, METH_NOARGS, prev_doc },
00314 {"next", (PyCFunction) py_next, METH_NOARGS, next_doc },
00315 {"pause", (PyCFunction) py_pause, METH_NOARGS, pause_doc },
00316 {"speed", (PyCFunction) py_speed, METH_VARARGS | METH_KEYWORDS, speed_doc },
00317 {"skip", (PyCFunction) py_skip, METH_VARARGS | METH_KEYWORDS, skip_doc },
00318 {"is_active", (PyCFunction) py_is_active, METH_VARARGS | METH_KEYWORDS, is_active_doc },
00319 {"activate", (PyCFunction) py_activate, METH_VARARGS | METH_KEYWORDS, activate_doc },
00320 {NULL, NULL}
00321 };
00322
00323
00324 static const char animate_moddoc[] =
00325 "Methods for controlling molecules with multiple frames loaded";
00326
00327
00328 #if PY_MAJOR_VERSION >= 3
00329 struct PyModuleDef animatedef = {
00330 PyModuleDef_HEAD_INIT,
00331 "animate",
00332 animate_moddoc,
00333 -1,
00334 methods,
00335 };
00336 #endif
00337
00338
00339 PyObject* initanimate() {
00340 PyObject *m;
00341
00342 #if PY_MAJOR_VERSION >= 3
00343 m = PyModule_Create(&animatedef);
00344 #else
00345 m = Py_InitModule3("animate", methods, animate_moddoc);
00346 #endif
00347
00348 return m;
00349 }
00350