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 "Molecule.h"
00023 #include "MoleculeList.h"
00024 #include "MaterialList.h"
00025 #include "VMDApp.h"
00026 #include "Scene.h"
00027 #include "MoleculeGraphics.h"
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 static MoleculeGraphics *mol_from_id(int id) {
00039 VMDApp *app;
00040 if (!(app = get_vmdapp()))
00041 return NULL;
00042
00043 MoleculeList *mlist = app->moleculeList;
00044 Molecule *mol;
00045 if (!(mol = mlist->mol_from_id(id))) {
00046 PyErr_Format(PyExc_ValueError, "Invalid graphics molecule '%d'", id);
00047 return NULL;
00048 }
00049
00050 return mol->moleculeGraphics();
00051 }
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 static char triangle_doc[] =
00062 "Draws a triangle\n\n"
00063 "Args:\n"
00064 " molid (int): Molecule ID to draw on\n"
00065 " v1 (3-tuple of float): (x,y,z) coordinates of first vertex\n"
00066 " v2 (3-tuple of float): (x,y,z) coordinates of second vertex\n"
00067 " v3 (3-tuple of float): (x,y,z) coordinates of third vertex\n"
00068 "Returns:\n"
00069 " (int): ID of drawn triangle";
00070 static PyObject* py_triangle(PyObject *self, PyObject *args, PyObject *kwargs) {
00071 const char *kwlist[] = {"molid", "v1", "v2", "v3", NULL};
00072 float arr1[3], arr2[3], arr3[3];
00073 PyObject *v1, *v2, *v3;
00074 MoleculeGraphics *mol;
00075 int id;
00076
00077 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iOOO:graphics.triangle",
00078 (char**) kwlist, &id, &v1, &v2, &v3))
00079 return NULL;
00080
00081 if (!(mol = mol_from_id(id)))
00082 return NULL;
00083
00084 if (!py_array_from_obj(v1, arr1) ||
00085 !py_array_from_obj(v2, arr2) ||
00086 !py_array_from_obj(v3, arr3))
00087 return NULL;
00088
00089 return as_pyint(mol->add_triangle(arr1, arr2, arr3));
00090 }
00091
00092
00093 static char trinorm_doc[] =
00094 "Draws a triangle with given vertices and vertex normals\n\n"
00095 "Args:\n"
00096 " molid (int): Molecule ID to draw on\n"
00097 " v1 (3-tuple of float): (x,y,z) coordinates of first vertex\n"
00098 " v2 (3-tuple of float): (x,y,z) coordinates of second vertex\n"
00099 " v3 (3-tuple of float): (x,y,z) coordinates of third vertex\n"
00100 " n1 (3-tuple of float): (x,y,z) normal of first vertex\n"
00101 " n2 (3-tuple of float): (x,y,z) normal of second vertex\n"
00102 " n3 (3-tuple of float): (x,y,z) normal of third vertex\n"
00103 "Returns:\n"
00104 " (int): ID of drawn triangle";
00105 static PyObject* py_trinorm(PyObject *self, PyObject *args, PyObject *kwargs) {
00106 const char *kwlist[] = {"molid", "v1", "v2", "v3", "n1", "n2", "n3", NULL};
00107 float vert1[3], vert2[3], vert3[3], norm1[3], norm2[3], norm3[3];
00108 PyObject *v1, *v2, *v3, *n1, *n2, *n3;
00109 MoleculeGraphics *mol;
00110 int id;
00111
00112 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iOOOOOO:graphics.trinorm",
00113 (char**) kwlist, &id, &v1, &v2, &v3, &n1,
00114 &n2, &n3))
00115 return NULL;
00116
00117 if (!(mol = mol_from_id(id)))
00118 return NULL;
00119
00120 if (!py_array_from_obj(v1, vert1) ||
00121 !py_array_from_obj(v2, vert2) ||
00122 !py_array_from_obj(v3, vert3) ||
00123 !py_array_from_obj(n1, norm1) ||
00124 !py_array_from_obj(n2, norm2) ||
00125 !py_array_from_obj(n2, norm3))
00126 return NULL;
00127
00128 return as_pyint(mol->add_trinorm(vert1,vert2,vert3,norm1,norm2,norm3));
00129 }
00130
00131
00132 static char cylinder_doc[] =
00133 "Draws a cylinder\n\n"
00134 "Args:\n"
00135 " molid (int): Molecule ID to draw on \n"
00136 " v1 (3-tuple of float): (x,y,z) coordinates of first vertex\n"
00137 " v2 (3-tuple of float): (x,y,z) coordinates of second vertex\n"
00138 " radius (float): Cylinder radius, defaults to 1.0\n"
00139 " resolution (int): Number of sides of cylinder, defaults to 6\n"
00140 " filled (bool): If cylinder ends should be capped\n"
00141 "Returns:\n"
00142 " (int): ID of drawn cylinder";
00143 static PyObject* py_cylinder(PyObject *self, PyObject *args, PyObject *kwargs) {
00144 const char *kwlist[] = {"molid", "v1", "v2", "radius", "resolution", "filled",
00145 NULL};
00146 int resolution = 6, filled = 0;
00147 float vert1[3], vert2[3];
00148 MoleculeGraphics *mol;
00149 float radius = 1.0;
00150 PyObject *v1, *v2;
00151 int id;
00152
00153 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iOO|fiO&:graphics.cylinder",
00154 (char**) kwlist, &id, &v1, &v2, &radius,
00155 &resolution, convert_bool, &filled))
00156 return NULL;
00157
00158 if (!(mol = mol_from_id(id)))
00159 return NULL;
00160
00161 if (!py_array_from_obj(v1, vert1) ||
00162 !py_array_from_obj(v2, vert2))
00163 return NULL;
00164
00165 return as_pyint(mol->add_cylinder(vert1, vert2, radius, resolution, filled));
00166 }
00167
00168
00169 static char point_doc[] =
00170 "Draw a point at the given vertex\n\n"
00171 "Args:\n"
00172 " molid (int): Molecule ID to draw on\n"
00173 " v1 (3-tuple of float): (x,y,z) coordinates of point\n"
00174 "Returns:\n"
00175 " (int): ID of drawn point";
00176 static PyObject *py_point(PyObject *self, PyObject *args, PyObject *kwargs) {
00177 const char *kwlist[] = {"molid", "v1", NULL};
00178 MoleculeGraphics *mol;
00179 float vert[3];
00180 PyObject *v;
00181 int id;
00182
00183 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO:graphics.point",
00184 (char**) kwlist, &id, &v))
00185 return NULL;
00186
00187 if (!(mol = mol_from_id(id)))
00188 return NULL;
00189
00190 if (!py_array_from_obj(v, vert))
00191 return NULL;
00192
00193 return as_pyint(mol->add_point(vert));
00194 }
00195
00196
00197 static char line_doc[] =
00198 "Draw a line between the given vertices\n\n"
00199 "Args:\n"
00200 " molid (int): Molecule ID to draw on\n"
00201 " v1 (3-tuple of float): (x,y,z) coordinates of first vertex\n"
00202 " v2 (3-tuple of float): (x,y,z) coordinates of second vertex\n"
00203 " style (str): Either 'solid' or 'dashed'. Defaults to solid line\n"
00204 " width (int): Width of line. Defaults to 1\n"
00205 "Returns:\n"
00206 " (int): ID of drawn line";
00207 static PyObject* py_line(PyObject *self, PyObject *args, PyObject *kwargs) {
00208 const char *kwlist[] = {"molid", "v1", "v2", "style", "width", NULL};
00209 int line_style = ::SOLIDLINE;
00210 float vert1[3], vert2[3];
00211 MoleculeGraphics *mol;
00212 char *style = NULL;
00213 PyObject *v1, *v2;
00214 int width = 1;
00215 int id;
00216
00217 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iOO|zi:graphics.line",
00218 (char**) kwlist, &id, &v1, &v2, &style,
00219 &width))
00220 return NULL;
00221
00222 if (!(mol = mol_from_id(id)))
00223 return NULL;
00224
00225 if (!py_array_from_obj(v1, vert1) ||
00226 !py_array_from_obj(v2, vert2))
00227 return NULL;
00228
00229 if (style) {
00230 if (!strcmp(style, "solid"))
00231 line_style = ::SOLIDLINE;
00232 else if (!strcmp(style, "dashed"))
00233 line_style = ::DASHEDLINE;
00234 else {
00235 PyErr_Format(PyExc_ValueError, "invalid line style '%s'", style);
00236 return NULL;
00237 }
00238 }
00239
00240
00241
00242 return as_pyint(mol->add_line(vert1, vert2, line_style, width));
00243 }
00244
00245
00246
00247 static char mats_doc[] =
00248 "Turns materials on or off for subsequent graphics primitives. Already drawn\n"
00249 "graphics objects are not affected.\n\n"
00250 "Args:\n"
00251 " molid (int): Molecule ID to affect\n"
00252 " on (bool): If materials should be on";
00253 static PyObject* py_materials(PyObject *self, PyObject *args, PyObject *kwargs) {
00254 const char *kwlist[] = {"molid", "on", NULL};
00255 MoleculeGraphics *mol;
00256 int id, onoff;
00257
00258 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO&:graphics.materials",
00259 (char**) kwlist, &id, convert_bool, &onoff))
00260 return NULL;
00261
00262 if (!(mol = mol_from_id(id)))
00263 return NULL;
00264
00265 mol->use_materials(onoff);
00266 Py_INCREF(Py_None);
00267 return Py_None;
00268 }
00269
00270
00271
00272 static char mat_doc[] =
00273 "Set material for all graphics in this molecule\n\n"
00274 "Args:\n"
00275 " molid (int): Molecule ID to affect\n"
00276 " name (str): Material name. Must be one returned by `material.listall()`";
00277 static PyObject* py_material(PyObject *self, PyObject *args, PyObject *kwargs) {
00278 const char *kwlist[] = {"molid", "name", NULL};
00279 MoleculeGraphics *mol;
00280 int id, matindex;
00281 char *name;
00282
00283 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "is:graphics.material",
00284 (char**) kwlist, &id, &name))
00285 return NULL;
00286
00287 if (!(mol = mol_from_id(id)))
00288 return NULL;
00289
00290 MaterialList *mlist = get_vmdapp()->materialList;
00291 matindex = mlist->material_index(name);
00292 if (matindex < 0) {
00293 PyErr_Format(PyExc_ValueError, "Invalid material name '%s'", name);
00294 return NULL;
00295 }
00296
00297 mol->use_material(mlist->material(matindex));
00298 Py_INCREF(Py_None);
00299 return Py_None;
00300 }
00301
00302
00303 static char color_doc[] =
00304 "Set color for subsequent graphics primitives in this molecule.\n\n"
00305 "Args:\n"
00306 " molid (int): Molecule ID to affect\n"
00307 " color (int, 3-tuple of float, or str): Color, either as color ID,\n"
00308 " or name.";
00309 static PyObject* py_color(PyObject *self, PyObject *args, PyObject *kwargs) {
00310 const char *kwlist[] = {"molid", "color", NULL};
00311 int id, index;
00312 PyObject *obj;
00313
00314 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO:graphics.color",
00315 (char**) kwlist, &id, &obj))
00316 return NULL;
00317
00318 VMDApp *app;
00319 if (!(app = get_vmdapp()))
00320 return NULL;
00321
00322 MoleculeGraphics *mol;
00323 if (!(mol = mol_from_id(id)))
00324 return NULL;
00325
00326
00327 if (is_pyint(obj)) {
00328 index = as_int(obj);
00329
00330
00331 } else if (is_pystring(obj)) {
00332 index = app->color_index(as_constcharptr(obj));
00333
00334
00335 } else {
00336 PyErr_SetString(PyExc_TypeError, "Wrong type for color object");
00337 return NULL;
00338 }
00339
00340
00341 if (index < 0 || index >= MAXCOLORS) {
00342 PyErr_Format(PyExc_ValueError, "Color index '%d' out of bounds", index);
00343 return NULL;
00344 }
00345
00346
00347 if (mol->use_color(index) < 0) {
00348 PyErr_SetString(PyExc_ValueError, "Error using color");
00349 return NULL;
00350 }
00351
00352 Py_INCREF(Py_None);
00353 return Py_None;
00354 }
00355
00356
00357 static char cone_doc[] =
00358 "Draws a cone. Base of cone is always filled\n\n"
00359 "Args:\n"
00360 " molid (int): Molecule ID to draw on \n"
00361 " v1 (3-tuple of float): (x,y,z) coordinates of first vertex\n"
00362 " v2 (3-tuple of float): (x,y,z) coordinates of second vertex\n"
00363 " radius (float): Cone radius at base, defaults to 1.0\n"
00364 " radius2 (float): Cone radius at end. Defaults to 0.0 for pointy cone.\n"
00365 " If nonzero, end will not appear as filled."
00366 " resolution (int): Number of sides of cone , defaults to 6\n"
00367 "Returns:\n"
00368 " (int): ID of drawn cone";
00369 static PyObject *py_cone(PyObject *self, PyObject *args, PyObject *kwargs) {
00370 float vert1[3], vert2[3];
00371 MoleculeGraphics *mol;
00372 PyObject *v1, *v2;
00373 float radius = 1.0;
00374 float radius2 = 0.0;
00375 int resolution = 6;
00376 int id;
00377
00378 const char *kwlist[] = {"molid", "v1", "v2", "radius", "radius2",
00379 "resolution", NULL};
00380
00381 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iOO|ffi:graphics.cone",
00382 (char**) kwlist, &id, &v1, &v2, &radius,
00383 &radius2, &resolution))
00384 return NULL;
00385
00386 if (!(mol = mol_from_id(id)))
00387 return NULL;
00388
00389 if (!py_array_from_obj(v1, vert1) ||
00390 !py_array_from_obj(v2, vert2))
00391 return NULL;
00392
00393 return as_pyint(mol->add_cone(vert1, vert2, radius, radius2, resolution));
00394 }
00395
00396
00397 static char sphere_doc[] =
00398 "Draws a sphere\n\n"
00399 "Args:\n"
00400 " molid (int): Molecule ID to draw on \n"
00401 " center (3-tuple of float): (x,y,z) coordinates to center sphere.\n"
00402 " Defaults to the origin.\n"
00403 " radius (float): Sphere radius. Defaults to 1.0\n"
00404 " resolution (int): Sphere resolution. Defaults to 6\n"
00405 "Returns:\n"
00406 " (int): ID of drawn sphere";
00407 static PyObject *py_sphere(PyObject *self, PyObject *args, PyObject *kwargs) {
00408 const char *kwlist[] = {"molid","center", "radius", "resolution", NULL};
00409 PyObject *center = NULL;
00410 MoleculeGraphics *mol;
00411 int resolution = 6;
00412 float radius = 1;
00413 float arr[3];
00414 int id;
00415
00416 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|Ofi:graphics.sphere",
00417 (char**) kwlist, &id, ¢er, &radius,
00418 &resolution))
00419 return NULL;
00420
00421 if (!(mol = mol_from_id(id)))
00422 return NULL;
00423
00424
00425 if (center == NULL || center == Py_None) {
00426 arr[0] = arr[1] = arr[2] = 0.0f;
00427
00428
00429 } else if (!py_array_from_obj(center, arr)) {
00430 PyErr_SetString(PyExc_ValueError, "Sphere center must be a 3-tuple");
00431 return NULL;
00432 }
00433
00434 return as_pyint(mol->add_sphere(arr, radius, resolution));
00435 }
00436
00437
00438 static char text_doc[] =
00439 "Draw text\n\n"
00440 "Args:\n"
00441 " molid (int): Molecule ID to draw on\n"
00442 " position (3-tuple of float): (x,y,z) coordinates to center text on\n"
00443 " text (str): Text to display\n"
00444 " size (float): Text size. Defaults to 1.0\n"
00445 " width (float): Text width. Defaults to 1.0\n"
00446 "Returns:\n"
00447 " (int): ID of drawn text\n";
00448 static PyObject *py_text(PyObject *self, PyObject *args, PyObject *kwargs) {
00449 const char *kwlist[] = {"molid", "position", "text", "size", "width", NULL};
00450 MoleculeGraphics *mol;
00451 float size = 1.0f, width = 1.0f;
00452 float arr[3];
00453 PyObject *v;
00454 char *text;
00455 int id;
00456
00457 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iOs|ff:graphics.text",
00458 (char**) kwlist, &id, &v, &text, &size,
00459 &width))
00460 return NULL;
00461
00462 if (!(mol = mol_from_id(id)))
00463 return NULL;
00464
00465 if (!py_array_from_obj(v, arr)) {
00466 PyErr_SetString(PyExc_ValueError, "Text position must be a 3-tuple");
00467 return NULL;
00468 }
00469
00470 return as_pyint(mol->add_text(arr, text, size, width));
00471 }
00472
00473
00474
00475
00476
00477 static char delete_doc[] =
00478 "Deletes a specified graphics object, or all graphics at a given molid\n\n"
00479 "Args:\n"
00480 " molid (int): Molecule ID to delete graphics from\n"
00481 " which (int or str): Graphics ID to delete, or 'all' for all objects.\n";
00482 static PyObject *py_delete(PyObject *self, PyObject *args, PyObject *kwargs) {
00483 const char* kwlist[] = {"molid", "which", NULL};
00484 MoleculeGraphics *mol;
00485 PyObject *obj;
00486 int id;
00487
00488 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO:graphics.delete",
00489 (char**) kwlist, &id, &obj))
00490 return NULL;
00491
00492 if (!(mol = mol_from_id(id)))
00493 return NULL;
00494
00495
00496 if (is_pyint(obj)) {
00497 int index = as_int(obj);
00498 mol->delete_id(index);
00499
00500
00501 } else if (is_pystring(obj)) {
00502 const char *s = as_constcharptr(obj);
00503
00504 if (!strcmp(s, "all")) {
00505 mol->delete_all();
00506 } else {
00507 PyErr_Format(PyExc_ValueError, "Invalid delete string '%s'", s);
00508 return NULL;
00509 }
00510
00511
00512 } else {
00513 PyErr_SetString(PyExc_TypeError, "Invalid argument for 'which'. Must "
00514 "be int or str");
00515 return NULL;
00516 }
00517
00518 Py_INCREF(Py_None);
00519 return Py_None;
00520 }
00521
00522
00523 static char replace_doc[] =
00524 "Delete a graphics object and have the next element replace this one.\n\n"
00525 "Args:\n"
00526 " molid (int): Molecule ID containing graphics object\n"
00527 " graphic (int): Graphics object ID to delete\n";
00528 static PyObject *py_replace(PyObject *self, PyObject *args, PyObject *kwargs) {
00529 const char *kwlist[] = {"molid", "graphic", NULL};
00530 MoleculeGraphics *mol;
00531 int index;
00532 int id;
00533
00534 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:graphics.replace",
00535 (char**) kwlist, &id, &index))
00536 return NULL;
00537
00538 if (!(mol = mol_from_id(id)))
00539 return NULL;
00540
00541 mol->replace_id(index);
00542
00543 Py_INCREF(Py_None);
00544 return Py_None;
00545 }
00546
00547
00548 static char info_doc[] =
00549 "Describe a graphics object with given index\n\n"
00550 "Args:\n"
00551 " molid (int): Molecule ID containing graphics object\n"
00552 " graphic (int): Graphics object ID to describe\n"
00553 "Returns:\n"
00554 " (str): Description of graphics object\n"
00555 "Raises:\n"
00556 " IndexError: If object does not exist\n";
00557 static PyObject *py_info(PyObject *self, PyObject *args, PyObject *kwargs) {
00558 const char *kwlist[] = {"molid", "graphic", NULL};
00559 MoleculeGraphics *mol;
00560 int index;
00561 int id;
00562
00563 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:graphics.info",
00564 (char**) kwlist, &id, &index))
00565 return NULL;
00566
00567 if (!(mol = mol_from_id(id)))
00568 return NULL;
00569
00570 if (mol->index_id(index) == -1) {
00571 PyErr_SetString(PyExc_IndexError, "Invalid graphics object");
00572 return NULL;
00573 }
00574
00575 return as_pystring(mol->info_id(index));
00576 }
00577
00578
00579 static char list_doc[] =
00580 "List all drawn graphics objects on a given molecule\n\n"
00581 "Args:\n"
00582 " molid (int): Molecule ID to query\n"
00583 "Returns:\n"
00584 " (list of int): Graphics object IDs present in molecule";
00585 static PyObject *py_listall(PyObject *self, PyObject *args, PyObject *kwargs) {
00586 const char *kwlist[] = {"molid", NULL};
00587 MoleculeGraphics *mol;
00588 PyObject *newlist;
00589 int id;
00590
00591 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:graphics.listall",
00592 (char**) kwlist, &id))
00593 return NULL;
00594
00595 if (!(mol = mol_from_id(id)))
00596 return NULL;
00597
00598 newlist = PyList_New(0);
00599 for (int i=0; i< mol->num_elements(); i++) {
00600 int index = mol->element_id(i);
00601 if (index >= 0) {
00602
00603 PyObject *tmp = as_pyint(index);
00604 int rc = PyList_Append(newlist, tmp);
00605 Py_XDECREF(tmp);
00606
00607 if (rc || PyErr_Occurred())
00608 goto failure;
00609 }
00610 }
00611
00612 return newlist;
00613
00614 failure:
00615 PyErr_SetString(PyExc_ValueError, "Problem listing graphics objects");
00616 Py_DECREF(newlist);
00617 return NULL;
00618 }
00619
00620
00621 static PyMethodDef GraphicsMethods[] = {
00622 {"cone", (PyCFunction)py_cone,METH_VARARGS | METH_KEYWORDS, cone_doc},
00623 {"sphere", (PyCFunction)py_sphere, METH_VARARGS | METH_KEYWORDS, sphere_doc},
00624 {"triangle",(PyCFunction)py_triangle, METH_VARARGS | METH_KEYWORDS, triangle_doc},
00625 {"trinorm",(PyCFunction)py_trinorm, METH_VARARGS | METH_KEYWORDS, trinorm_doc},
00626 {"point",(PyCFunction)py_point, METH_VARARGS | METH_KEYWORDS, point_doc},
00627 {"line", (PyCFunction)py_line,METH_VARARGS | METH_KEYWORDS, line_doc},
00628 {"cylinder", (PyCFunction)py_cylinder, METH_VARARGS | METH_KEYWORDS, cylinder_doc},
00629 {"materials",(PyCFunction)py_materials, METH_VARARGS | METH_KEYWORDS, mats_doc},
00630 {"material",(PyCFunction)py_material, METH_VARARGS | METH_KEYWORDS, mat_doc},
00631 {"color",(PyCFunction)py_color, METH_VARARGS | METH_KEYWORDS, color_doc},
00632 {"text", (PyCFunction)py_text,METH_VARARGS | METH_KEYWORDS, text_doc},
00633 {"delete",(PyCFunction)py_delete, METH_VARARGS | METH_KEYWORDS, delete_doc},
00634 {"replace",(PyCFunction)py_replace, METH_VARARGS | METH_KEYWORDS, replace_doc},
00635 {"info",(PyCFunction)py_info, METH_VARARGS | METH_KEYWORDS, info_doc},
00636 {"listall",(PyCFunction)py_listall, METH_VARARGS | METH_KEYWORDS, list_doc},
00637 {NULL, NULL}
00638 };
00639
00640
00641 static const char graphics_moddoc[] =
00642 "Methods for drawing graphics primitives in the render window";
00643
00644
00645 #if PY_MAJOR_VERSION >= 3
00646 static struct PyModuleDef graphicsdef = {
00647 PyModuleDef_HEAD_INIT,
00648 "graphics",
00649 graphics_moddoc,
00650 -1,
00651 GraphicsMethods,
00652 };
00653 #endif
00654
00655
00656 PyObject* initgraphics(void) {
00657 #if PY_MAJOR_VERSION >= 3
00658 PyObject *m = PyModule_Create(&graphicsdef);
00659 #else
00660 PyObject *m = Py_InitModule3("graphics", GraphicsMethods, graphics_moddoc);
00661 #endif
00662
00663 return m;
00664 }
00665