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 "VMDApp.h"
00023 #include "DisplayDevice.h"
00024
00025 static const char update_doc[] =
00026 "Force a render window update, without updating FLTK menus";
00027 static PyObject* py_update(PyObject *self, PyObject *args) {
00028 VMDApp *app;
00029 if (!(app = get_vmdapp()))
00030 return NULL;
00031
00032 app->display_update();
00033
00034 Py_INCREF(Py_None);
00035 return Py_None;
00036 }
00037
00038
00039 static const char update_ui_doc[] =
00040 "Update the render window and all user interfaces";
00041 static PyObject* py_update_ui(PyObject *self, PyObject *args) {
00042 VMDApp *app;
00043 if (!(app = get_vmdapp()))
00044 return NULL;
00045
00046 app->display_update_ui();
00047
00048 Py_INCREF(Py_None);
00049 return Py_None;
00050 }
00051
00052
00053 static const char update_on_doc[] =
00054 "Tell VMD to regularly update display and GUI menus";
00055 static PyObject* py_update_on(PyObject *self, PyObject *args) {
00056 VMDApp *app;
00057 if (!(app = get_vmdapp()))
00058 return NULL;
00059
00060 app->display_update_on(1);
00061
00062 Py_INCREF(Py_None);
00063 return Py_None;
00064 }
00065
00066
00067 static const char update_off_doc[] =
00068 "Stop updating the display. Updates will only occur when `update()` is called";
00069 static PyObject* py_update_off(PyObject *self, PyObject *args) {
00070 VMDApp *app;
00071 if (!(app = get_vmdapp()))
00072 return NULL;
00073
00074 app->display_update_on(0);
00075
00076 Py_INCREF(Py_None);
00077 return Py_None;
00078 }
00079
00080
00081 static const char set_doc[] =
00082 "Sets display properties. One or more properties may be set at a time.\n\n"
00083 "Args:\n"
00084 " eyesep (float): Eye separation\n"
00085 " focallength (float): Focal length\n"
00086 " height (float): Screen height relative to the camera\n"
00087 " distance (float): Screen distance relative to the camera\n"
00088 " nearclip (float): Near clipping plane distance\n"
00089 " farclip (float): Far clipping plane distance\n"
00090 " antialias (bool): If antialiasing is on\n"
00091 " depthcueue (bool): If depth cueuing is used\n"
00092 " culling (bool): If backface culling is used. Can reduce performance\n"
00093 " stereo (bool): If stereo mode is on\n"
00094 " projection (str): Projection mode, in [Perspective, Orthographic]\n"
00095 " size (list of 2 ints): Display window size, in px\n"
00096 " ambientocclusion (bool): If ambient occlusion is used\n"
00097 " aoambient (float): Amount of ambient light\n"
00098 " aodirect (float): Amount of direct light\n"
00099 " shadows (bool): If shadows should be rendered\n"
00100 " dof (bool): If depth of field effects should be rendered\n"
00101 " dof_fnumber (float): F-number for depth of field effects\n"
00102 " dof_focaldist (float): Focal distance for depth of field effects";
00103 static PyObject* py_set(PyObject *self, PyObject *args, PyObject *kwargs) {
00104 const char *kwlist[] = {"eyesep", "focallength", "height", "distance",
00105 "nearclip", "farclip", "antialias", "depthcue",
00106 "culling", "stereo", "projection", "size",
00107 "ambientocclusion", "aoambient", "aodirect",
00108 "shadows", "dof", "dof_fnumber", "dof_focaldist",
00109 NULL};
00110 float eyesep, focallength, height, distance, nearclip, farclip;
00111 float aoambient, aodirect, dof_fnumber, dof_focaldist;
00112 int antialias, depthcue, culling, ao, shadows, dof;
00113 char *stereo, *projection;
00114 int num_keys = 19;
00115 PyObject *size;
00116 int i, w, h;
00117
00118 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
00119 "|ffffffO&O&O&ssOO&ffO&O&ff:display.set",
00120 (char**) kwlist, &eyesep, &focallength,
00121 &height, &distance, &nearclip, &farclip,
00122 convert_bool, &antialias, convert_bool,
00123 &depthcue, convert_bool, &culling, &stereo,
00124 &projection, &size, convert_bool, &ao,
00125 &aoambient, &aodirect, convert_bool,
00126 &shadows, convert_bool, &dof, &dof_fnumber,
00127 &dof_focaldist))
00128 return NULL;
00129
00130 VMDApp *app;
00131 if (!(app = get_vmdapp()))
00132 return NULL;
00133
00134
00135
00136
00137
00138
00139
00140
00141 if (PyDict_GetItemString(kwargs, "nearclip") &&
00142 PyDict_GetItemString(kwargs, "farclip")) {
00143 if (nearclip >= farclip)
00144 goto cliperror;
00145
00146 if (nearclip >= app->display->far_clip())
00147 app->display_set_farclip(nearclip + 1.0, 0);
00148
00149 if (farclip <= app->display->near_clip())
00150 app->display_set_nearclip(farclip - 1.0, 0);
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 for (i = 0; i < num_keys; i++) {
00162 if (!PyDict_GetItemString(kwargs, kwlist[i]))
00163 continue;
00164
00165 switch (i) {
00166 case 0: app->display_set_eyesep(eyesep); break;
00167 case 1: app->display_set_focallen(focallength); break;
00168 case 2: app->display_set_screen_height(height); break;
00169 case 3: app->display_set_screen_distance(distance); break;
00170 case 4:
00171 if (nearclip >= app->display->far_clip())
00172 goto cliperror;
00173 app->display_set_nearclip(nearclip, 0);
00174 break;
00175 case 5:
00176 if (farclip <= app->display->near_clip())
00177 goto cliperror;
00178 app->display_set_farclip(farclip, 0);
00179 break;
00180 case 6: app->display_set_aa(antialias); break;
00181 case 7: app->display_set_depthcue(depthcue); break;
00182 case 8: app->display_set_culling(culling); break;
00183 case 9: app->display_set_stereo(stereo); break;
00184 case 10:
00185 if (!app->display_set_projection(projection)) {
00186 PyErr_SetString(PyExc_ValueError, "Invalid projection");
00187 goto failure;
00188 }
00189 break;
00190 case 11:
00191 if (!PySequence_Check(size) || PySequence_Size(size) != 2
00192 || is_pystring(size)) {
00193 PyErr_SetString(PyExc_ValueError,
00194 "size argument must be a two-element list or tuple");
00195 goto failure;
00196 }
00197 w = as_int(PySequence_GetItem(size, 0));
00198 h = as_int(PySequence_GetItem(size, 1));
00199 if (PyErr_Occurred())
00200 goto failure;
00201
00202 app->display_set_size(w, h);
00203
00204 break;
00205 case 12: app->display_set_ao(ao); break;
00206 case 13: app->display_set_ao_ambient(aoambient); break;
00207 case 14: app->display_set_ao_direct(aodirect); break;
00208 case 15: app->display_set_shadows(shadows); break;
00209 case 16: app->display_set_dof(dof); break;
00210 case 17: app->display_set_dof_fnumber(dof_fnumber); break;
00211 case 18: app->display_set_dof_focal_dist(dof_focaldist); break;
00212 default: ;
00213 }
00214 }
00215
00216 Py_INCREF(Py_None);
00217 return Py_None;
00218
00219 cliperror:
00220 PyErr_SetString(PyExc_ValueError, "Invalid clip plane settings. Near clip "
00221 "plane cannot be larger than far clip plane");
00222 failure:
00223 return NULL;
00224 }
00225
00226
00227 static char get_doc[] =
00228 "Query display properties\n\n"
00229 "Args:\n"
00230 " query (str): Property to query. See keywords for `display.set()` for a\n"
00231 " comprehensive list of properties.\n"
00232 "Returns:\n"
00233 " (either float, bool, list of 2 ints, or str): Value of queried parameter\n"
00234 " with datatype depending on the parameter type. See `display.set()`\n"
00235 " for a list of all parameters and types.";
00236 static PyObject* py_get(PyObject *self, PyObject *args, PyObject *kwargs) {
00237 const char *kwlist[] = {"query", NULL};
00238 PyObject *result = NULL;
00239 char *key;
00240
00241 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:display.get",
00242 (char**) kwlist, &key))
00243 return NULL;
00244
00245 VMDApp *app;
00246 if (!(app = get_vmdapp()))
00247 return NULL;
00248
00249 DisplayDevice *disp = app->display;
00250
00251
00252
00253
00254
00255
00256
00257
00258 if (!strcmp(key, "eyesep")) {
00259 result = PyFloat_FromDouble(disp->eyesep());
00260
00261 } else if (!strcmp(key, "focallength")) {
00262 result = PyFloat_FromDouble(disp->eye_dist());
00263
00264 } else if (!strcmp(key, "height")) {
00265 result = PyFloat_FromDouble(disp->screen_height());
00266
00267 } else if (!strcmp(key, "distance")) {
00268 result = PyFloat_FromDouble(disp->distance_to_screen());
00269
00270 } else if (!strcmp(key, "nearclip")) {
00271 result = PyFloat_FromDouble(disp->near_clip());
00272
00273 } else if (!strcmp(key, "farclip")) {
00274 result = PyFloat_FromDouble(disp->far_clip());
00275
00276 } else if (!strcmp(key, "antialias")) {
00277 result = disp->aa_enabled() ? Py_True : Py_False;
00278 Py_INCREF(result);
00279
00280 } else if (!strcmp(key, "depthcue")) {
00281 result = disp->cueing_enabled() ? Py_True : Py_False;
00282 Py_INCREF(result);
00283
00284 } else if (!strcmp(key, "culling")) {
00285 result = disp->culling_enabled() ? Py_True : Py_False;
00286 Py_INCREF(result);
00287
00288 } else if (!strcmp(key, "stereo")) {
00289 result = as_pystring(disp->stereo_name(disp->stereo_mode()));
00290
00291 } else if (!strcmp(key, "projection")) {
00292 result = as_pystring(disp->get_projection());
00293
00294 } else if (!strcmp(key, "size")) {
00295 int w, h;
00296 app->display_get_size(&w, &h);
00297 result = Py_BuildValue("[i,i]", w, h);
00298
00299 } else if (!strcmp(key, "ambientocclusion")) {
00300 result = disp->ao_enabled() ? Py_True : Py_False;
00301 Py_INCREF(result);
00302
00303 } else if (!strcmp(key, "aoambient")) {
00304 result = PyFloat_FromDouble(disp->get_ao_ambient());
00305
00306 } else if (!strcmp(key, "aodirect")) {
00307 result = PyFloat_FromDouble(disp->get_ao_direct());
00308
00309 } else if (!strcmp(key, "shadows")) {
00310 result = disp->shadows_enabled() ? Py_True : Py_False;
00311 Py_INCREF(result);
00312
00313 } else if (!strcmp(key, "dof")) {
00314 result = disp->dof_enabled() ? Py_True : Py_False;
00315 Py_INCREF(result);
00316
00317 } else if (!strcmp(key, "dof_fnumber")) {
00318 result = PyFloat_FromDouble(disp->get_dof_fnumber());
00319
00320 } else if (!strcmp(key, "dof_focaldist")) {
00321 result = PyFloat_FromDouble(disp->get_dof_focal_dist());
00322
00323 } else {
00324 PyErr_Format(PyExc_ValueError, "Invalid query '%s'", key);
00325 goto failure;
00326 }
00327
00328 if (PyErr_Occurred()) {
00329 PyErr_SetString(PyExc_RuntimeError, "Problem getting display attribute");
00330 goto failure;
00331 }
00332
00333 return result;
00334
00335 failure:
00336 Py_XDECREF(result);
00337 return NULL;
00338 }
00339
00340
00341 static const char stereomodes_doc[] =
00342 "Get available stereo modes\n\n"
00343 "Returns:\n"
00344 " (list of str): Available modes";
00345 static PyObject* py_stereomodes(PyObject *self, PyObject *args) {
00346 int j;
00347
00348 VMDApp *app;
00349 if (!(app = get_vmdapp()))
00350 return NULL;
00351
00352 DisplayDevice *disp = app->display;
00353 int num = disp->num_stereo_modes();
00354
00355 PyObject *newlist = PyList_New(num);
00356 if (!newlist || PyErr_Occurred())
00357 goto failure;
00358
00359 for (j = 0; j < num; j++) {
00360 PyList_SET_ITEM(newlist, j, as_pystring(disp->stereo_name(j)));
00361 if (PyErr_Occurred())
00362 goto failure;
00363 }
00364
00365 return newlist;
00366
00367 failure:
00368 PyErr_SetString(PyExc_RuntimeError, "Problem listing stero modes");
00369 Py_XDECREF(newlist);
00370 return NULL;
00371 }
00372
00373
00374 static PyMethodDef DisplayMethods[] = {
00375 {"update", (PyCFunction)py_update, METH_NOARGS, update_doc},
00376 {"update_ui", (PyCFunction)py_update_ui, METH_NOARGS, update_ui_doc},
00377 {"update_on", (PyCFunction)py_update_on, METH_NOARGS, update_on_doc},
00378 {"update_off", (PyCFunction)py_update_off, METH_NOARGS, update_off_doc},
00379 {"set", (PyCFunction)py_set, METH_VARARGS | METH_KEYWORDS, set_doc},
00380 {"get", (PyCFunction)py_get, METH_VARARGS | METH_KEYWORDS, get_doc},
00381 {"stereomodes", (PyCFunction)py_stereomodes, METH_NOARGS, stereomodes_doc},
00382 {NULL, NULL}
00383 };
00384
00385
00386 static const char disp_moddoc[] =
00387 "Contains methods to set various parameters in the graphical display, as "
00388 "well as controlling how the UI and render window are updated";
00389
00390
00391 #if PY_MAJOR_VERSION >= 3
00392 static struct PyModuleDef displaydef = {
00393 PyModuleDef_HEAD_INIT,
00394 "display",
00395 disp_moddoc,
00396 -1,
00397 DisplayMethods,
00398 };
00399 #endif
00400
00401
00402 PyObject* initdisplay() {
00403 #if PY_MAJOR_VERSION >= 3
00404 PyObject *m = PyModule_Create(&displaydef);
00405 #else
00406 PyObject *m = Py_InitModule3("display", DisplayMethods, disp_moddoc);
00407 #endif
00408
00409
00410
00411 PyModule_AddStringConstant(m, "PROJ_PERSP", "Perspective");
00412 PyModule_AddStringConstant(m, "PROJ_ORTHO", "Orthographic");
00413
00414 return m;
00415 }
00416