P.cpp (pymol-v2.1.0.tar.bz2) | : | P.cpp (pymol-open-source-2.2.0) | ||
---|---|---|---|---|
skipping to change at line 586 | skipping to change at line 586 | |||
PyMOLGlobals * G = wobj->G; | PyMOLGlobals * G = wobj->G; | |||
const char *aprop; | const char *aprop; | |||
AtomPropertyInfo *ap; | AtomPropertyInfo *ap; | |||
PyObject *ret = NULL; | PyObject *ret = NULL; | |||
bool borrowed = false; | bool borrowed = false; | |||
PyObject *keyobj = PyObject_Str(key); | PyObject *keyobj = PyObject_Str(key); | |||
aprop = PyString_AS_STRING(keyobj); | aprop = PyString_AS_STRING(keyobj); | |||
ap = PyMOL_GetAtomPropertyInfo(wobj->G->PyMOL, aprop); | ap = PyMOL_GetAtomPropertyInfo(wobj->G->PyMOL, aprop); | |||
Py_DECREF(keyobj); | Py_DECREF(keyobj); | |||
if (ap){ | if (ap){ | |||
#ifdef _PYMOL_IP_EXTRAS | ||||
#ifdef NO_MMLIBS | ||||
// static -> only show these warnings once | ||||
static bool warning_shown_text_type = false; | ||||
#endif | ||||
switch (ap->id) { | ||||
case ATOM_PROP_STEREO: | ||||
if (ObjectMoleculeUpdateMMStereoInfoForState(G, wobj->obj, wobj->state - 1 | ||||
) < 0) { | ||||
PyErr_SetString(PyExc_RuntimeError, | ||||
"please install rdkit or set SCHRODINGER variable"); | ||||
return NULL; | ||||
} | ||||
break; | ||||
case ATOM_PROP_TEXT_TYPE: | ||||
#ifndef NO_MMLIBS | ||||
ObjectMoleculeUpdateAtomTypeInfoForState(G, wobj->obj, wobj->state - 1, 1, | ||||
0); | ||||
#else | ||||
if (!warning_shown_text_type && !(wobj->cs && wobj->cs->validTextType)) { | ||||
warning_shown_text_type = true; | ||||
PRINTFB(G, FB_ObjectMolecule, FB_Warnings) | ||||
" Notice: Automatic 'text_type' assignment feature removed in PyMOL 2. | ||||
0.\n" ENDFB(G); | ||||
} | ||||
#endif | ||||
break; | ||||
} | ||||
#endif | ||||
switch (ap->Ptype){ | switch (ap->Ptype){ | |||
case cPType_string: | case cPType_string: | |||
{ | { | |||
char *val = (char*)(((char*)wobj->atomInfo) + ap->offset); | char *val = (char*)(((char*)wobj->atomInfo) + ap->offset); | |||
ret = PyString_FromString(val); | ret = PyString_FromString(val); | |||
} | } | |||
break; | break; | |||
case cPType_schar: | case cPType_schar: | |||
{ | { | |||
signed char val = *(signed char*)(((char*)wobj->atomInfo) + ap->offset); | signed char val = *(signed char*)(((char*)wobj->atomInfo) + ap->offset); | |||
skipping to change at line 655 | skipping to change at line 683 | |||
{ | { | |||
if (wobj->idx >= 0){ | if (wobj->idx >= 0){ | |||
ret = PyFloat_FromDouble(wobj->cs->coordPtr(wobj->idx)[ap->offset]); | ret = PyFloat_FromDouble(wobj->cs->coordPtr(wobj->idx)[ap->offset]); | |||
} else { | } else { | |||
PyErr_SetString(PyExc_NameError, | PyErr_SetString(PyExc_NameError, | |||
"x/y/z only available in iterate_state and alter_state"); | "x/y/z only available in iterate_state and alter_state"); | |||
} | } | |||
} | } | |||
break; | break; | |||
case cPType_settings: | case cPType_settings: | |||
ret = (PyObject*)wobj->G->P_inst->settingWrapperObject; | if (!wobj->settingWrapperObject) { | |||
wobj->settingWrapperObject = PyType_GenericNew(&settingWrapper_Type, Py_ | ||||
None, Py_None); | ||||
reinterpret_cast<SettingPropertyWrapperObject *>(wobj->settingWrapperObj | ||||
ect)->wobj = wobj; | ||||
} | ||||
ret = wobj->settingWrapperObject; | ||||
borrowed = true; | borrowed = true; | |||
break; | break; | |||
case cPType_properties: | case cPType_properties: | |||
PyErr_SetString(PyExc_NotImplementedError, | PyErr_SetString(PyExc_NotImplementedError, | |||
"'properties/p' not supported in Open-Source PyMOL"); | "'properties/p' not supported in Open-Source PyMOL"); | |||
break; | break; | |||
case cPType_state: | case cPType_state: | |||
ret = PyInt_FromLong((long)wobj->state); | ret = PyInt_FromLong((long)wobj->state); | |||
break; | break; | |||
default: | default: | |||
skipping to change at line 693 | skipping to change at line 725 | |||
char abbr[2] = {SeekerGetAbbr(G, st, 'O', 'X'), 0}; | char abbr[2] = {SeekerGetAbbr(G, st, 'O', 'X'), 0}; | |||
ret = PyString_FromString(abbr); | ret = PyString_FromString(abbr); | |||
} | } | |||
break; | break; | |||
default: | default: | |||
PyErr_SetString(PyExc_SystemError, "unhandled atom property type"); | PyErr_SetString(PyExc_SystemError, "unhandled atom property type"); | |||
} | } | |||
} | } | |||
} else { | } else { | |||
/* if not an atom property, check if local variable in dict */ | /* if not an atom property, check if local variable in dict */ | |||
ret = PyDict_GetItem(wobj->dict, key); | if (wobj->dict) { | |||
ret = PyDict_GetItem(wobj->dict, key); | ||||
} | ||||
if (ret) { | if (ret) { | |||
borrowed = true; | borrowed = true; | |||
} else { | } else { | |||
PyErr_SetNone(PyExc_KeyError); | PyErr_SetNone(PyExc_KeyError); | |||
} | } | |||
} | } | |||
if (borrowed) | if (borrowed) | |||
PXIncRef(ret); | PXIncRef(ret); | |||
return ret; | return ret; | |||
skipping to change at line 727 | skipping to change at line 761 | |||
} | } | |||
{ | { | |||
char aprop[16]; | char aprop[16]; | |||
PyObject *keyobj = PyObject_Str(key); | PyObject *keyobj = PyObject_Str(key); | |||
UtilNCopy(aprop, PyString_AS_STRING(keyobj), sizeof(aprop)); | UtilNCopy(aprop, PyString_AS_STRING(keyobj), sizeof(aprop)); | |||
Py_DECREF(keyobj); | Py_DECREF(keyobj); | |||
AtomPropertyInfo *ap = PyMOL_GetAtomPropertyInfo(wobj->G->PyMOL, aprop); | AtomPropertyInfo *ap = PyMOL_GetAtomPropertyInfo(wobj->G->PyMOL, aprop); | |||
if (ap){ | if (ap){ | |||
#ifdef _PYMOL_IP_EXTRAS | ||||
if (wobj->cs) { | ||||
switch (ap->id) { | ||||
case ATOM_PROP_STEREO: | ||||
wobj->cs->validMMStereo = MMPYMOLX_PROP_STATE_USER; | ||||
break; | ||||
case ATOM_PROP_TEXT_TYPE: | ||||
wobj->cs->validTextType = MMPYMOLX_PROP_STATE_USER; | ||||
break; | ||||
} | ||||
} | ||||
#endif | ||||
short changed = false; | short changed = false; | |||
if (wobj->read_only){ | if (wobj->read_only){ | |||
PyErr_SetString(PyExc_TypeError, | PyErr_SetString(PyExc_TypeError, | |||
"Use alter/alter_state to modify values"); | "Use alter/alter_state to modify values"); | |||
return -1; | return -1; | |||
} | } | |||
// alter_state: must be setting x/y/z or flags | // alter_state: must be setting x/y/z or flags | |||
if (wobj->idx >= 0) { | if (wobj->idx >= 0) { | |||
if (ap->Ptype == cPType_xyz_float) { | if (ap->Ptype == cPType_xyz_float) { | |||
skipping to change at line 870 | skipping to change at line 917 | |||
case ATOM_PROP_SS: | case ATOM_PROP_SS: | |||
wobj->atomInfo->ssType[0] = toupper(wobj->atomInfo->ssType[0]); | wobj->atomInfo->ssType[0] = toupper(wobj->atomInfo->ssType[0]); | |||
break; | break; | |||
case ATOM_PROP_FORMAL_CHARGE: | case ATOM_PROP_FORMAL_CHARGE: | |||
wobj->atomInfo->chemFlag = false; | wobj->atomInfo->chemFlag = false; | |||
break; | break; | |||
} | } | |||
} | } | |||
} else { | } else { | |||
/* if not an atom property, then its a local variable, store it */ | /* if not an atom property, then its a local variable, store it */ | |||
if (!wobj->dict) { | ||||
wobj->dict = PyDict_New(); | ||||
} | ||||
PyDict_SetItem(wobj->dict, key, val); | PyDict_SetItem(wobj->dict, key, val); | |||
} | } | |||
} | } | |||
return 0; /* 0 success, -1 failure */ | return 0; /* 0 success, -1 failure */ | |||
} | } | |||
/* BEGIN PROPRIETARY CODE SEGMENT (see disclaimer in "os_proprietary.h") */ | /* BEGIN PROPRIETARY CODE SEGMENT (see disclaimer in "os_proprietary.h") */ | |||
#ifdef WIN32 | #ifdef WIN32 | |||
static PyObject *P_time = NULL; | static PyObject *P_time = NULL; | |||
static PyObject *P_sleep = NULL; | static PyObject *P_sleep = NULL; | |||
skipping to change at line 1245 | skipping to change at line 1295 | |||
void PDumpTraceback(PyObject * err) | void PDumpTraceback(PyObject * err) | |||
{ | { | |||
PYOBJECT_CALLMETHOD(P_traceback, "print_tb", "O", err); | PYOBJECT_CALLMETHOD(P_traceback, "print_tb", "O", err); | |||
} | } | |||
void PDumpException() | void PDumpException() | |||
{ | { | |||
PYOBJECT_CALLMETHOD(P_traceback, "print_exc", ""); | PYOBJECT_CALLMETHOD(P_traceback, "print_exc", ""); | |||
} | } | |||
static | ||||
WrapperObject * WrapperObjectNew() { | ||||
auto wobj = (WrapperObject *)PyType_GenericNew(&Wrapper_Type, Py_None, Py_None | ||||
); | ||||
wobj->dict = NULL; | ||||
wobj->settingWrapperObject = NULL; | ||||
#ifdef _PYMOL_IP_EXTRAS | ||||
wobj->propertyWrapperObject = NULL; | ||||
#endif | ||||
return wobj; | ||||
} | ||||
int PAlterAtomState(PyMOLGlobals * G, PyCodeObject *expr_co, int read_only, | int PAlterAtomState(PyMOLGlobals * G, PyCodeObject *expr_co, int read_only, | |||
ObjectMolecule *obj, CoordSet *cs, int atm, int idx, | ObjectMolecule *obj, CoordSet *cs, int atm, int idx, | |||
int state, PyObject * space) | int state, PyObject * space) | |||
/* assumes Blocked python interpreter */ | /* assumes Blocked python interpreter */ | |||
{ | { | |||
int result = true; | int result = true; | |||
G->P_inst->wrapperObject->obj = obj; | auto wobj = WrapperObjectNew(); | |||
G->P_inst->wrapperObject->cs = cs; | wobj->G = G; | |||
G->P_inst->wrapperObject->atomInfo = obj->AtomInfo + atm; | wobj->obj = obj; | |||
G->P_inst->wrapperObject->atm = atm; | wobj->cs = cs; | |||
G->P_inst->wrapperObject->idx = idx; | wobj->atomInfo = obj->AtomInfo + atm; | |||
G->P_inst->wrapperObject->read_only = read_only; | wobj->atm = atm; | |||
G->P_inst->wrapperObject->state = state + 1; | wobj->idx = idx; | |||
wobj->read_only = read_only; | ||||
wobj->state = state + 1; | ||||
PXDecRef(PyEval_EvalCode(expr_co, space, (PyObject*)G->P_inst->wrapperObject)) | PXDecRef(PyEval_EvalCode(expr_co, space, (PyObject*)wobj)); | |||
; | WrapperObjectReset(wobj); | |||
WrapperObjectReset(G->P_inst->wrapperObject); | ||||
if(PyErr_Occurred()) { | if(PyErr_Occurred()) { | |||
PyErr_Print(); | PyErr_Print(); | |||
result = false; | result = false; | |||
} | } | |||
return result; | return result; | |||
} | } | |||
int PAlterAtom(PyMOLGlobals * G, | int PAlterAtom(PyMOLGlobals * G, | |||
ObjectMolecule *obj, CoordSet *cs, PyCodeObject *expr_co, int rea d_only, | ObjectMolecule *obj, CoordSet *cs, PyCodeObject *expr_co, int rea d_only, | |||
skipping to change at line 1302 | skipping to change at line 1365 | |||
} | } | |||
int PLabelAtom(PyMOLGlobals * G, ObjectMolecule *obj, CoordSet *cs, PyCodeObject *expr_co, int atm) | int PLabelAtom(PyMOLGlobals * G, ObjectMolecule *obj, CoordSet *cs, PyCodeObject *expr_co, int atm) | |||
{ | { | |||
int result = true; | int result = true; | |||
PyObject *P_inst_dict = G->P_inst->dict; | PyObject *P_inst_dict = G->P_inst->dict; | |||
PyObject *resultPyObject; | PyObject *resultPyObject; | |||
OrthoLineType label; | OrthoLineType label; | |||
AtomInfoType * ai = obj->AtomInfo + atm; | AtomInfoType * ai = obj->AtomInfo + atm; | |||
G->P_inst->wrapperObject->obj = obj; | ||||
G->P_inst->wrapperObject->cs = cs; | ||||
G->P_inst->wrapperObject->atomInfo = ai; | ||||
G->P_inst->wrapperObject->atm = atm; | ||||
G->P_inst->wrapperObject->idx = -1; | ||||
G->P_inst->wrapperObject->read_only = true; | ||||
if (obj->DiscreteFlag) { | ||||
G->P_inst->wrapperObject->state = obj->AtomInfo[atm].discrete_state; | ||||
} else { | ||||
G->P_inst->wrapperObject->state = 0; | ||||
} | ||||
if (!expr_co){ | if (!expr_co){ | |||
// unsetting label | // unsetting label | |||
LexAssign(G, ai->label, 0); | LexAssign(G, ai->label, 0); | |||
return true; | return true; | |||
} | } | |||
resultPyObject = PyEval_EvalCode(expr_co, P_inst_dict, (PyObject*)G->P_inst->w | ||||
rapperObject); | auto wobj = WrapperObjectNew(); | |||
WrapperObjectReset(G->P_inst->wrapperObject); | wobj->G = G; | |||
wobj->obj = obj; | ||||
wobj->cs = cs; | ||||
wobj->atomInfo = ai; | ||||
wobj->atm = atm; | ||||
wobj->idx = -1; | ||||
wobj->read_only = true; | ||||
if (obj->DiscreteFlag) { | ||||
wobj->state = obj->AtomInfo[atm].discrete_state; | ||||
} else { | ||||
wobj->state = 0; | ||||
} | ||||
resultPyObject = PyEval_EvalCode(expr_co, P_inst_dict, (PyObject*)wobj); | ||||
WrapperObjectReset(wobj); | ||||
if(PyErr_Occurred()) { | if(PyErr_Occurred()) { | |||
PyErr_Print(); | PyErr_Print(); | |||
result = false; | result = false; | |||
} else { | } else { | |||
result = true; | result = true; | |||
if(!PLabelPyObjectToStrMaxLen(G, resultPyObject, | if(!PLabelPyObjectToStrMaxLen(G, resultPyObject, | |||
label, sizeof(OrthoLineType) - 1)) | label, sizeof(OrthoLineType) - 1)) | |||
result = false; | result = false; | |||
if(PyErr_Occurred()) { | if(PyErr_Occurred()) { | |||
skipping to change at line 1858 | skipping to change at line 1924 | |||
strcat(line2, getenv("PYMOL_PATH")); | strcat(line2, getenv("PYMOL_PATH")); | |||
strcat(line2, "/ext"); | strcat(line2, "/ext"); | |||
putenv(line2); | putenv(line2); | |||
} | } | |||
} | } | |||
#endif | #endif | |||
#ifndef _PYMOL_EMBEDDED | #ifndef _PYMOL_EMBEDDED | |||
Py_Initialize(); | Py_Initialize(); | |||
PyEval_InitThreads(); | PyEval_InitThreads(); | |||
#if PY_MAJOR_VERSION < 3 | ||||
PyUnicode_SetDefaultEncoding("utf-8"); /* is this safe & legal? */ | ||||
#endif | ||||
#endif | #endif | |||
init_cmd(); | init_cmd(); | |||
#ifdef _PYMOL_MONOLITHIC | #ifdef _PYMOL_MONOLITHIC | |||
#ifndef _PYMOL_EMBEDDED | #ifndef _PYMOL_EMBEDDED | |||
/* | /* | |||
* initExtensionClass(); | * initExtensionClass(); | |||
* initsglite(); | * initsglite(); | |||
*/ | */ | |||
skipping to change at line 1988 | skipping to change at line 2051 | |||
rec->presentation = PyInt_AsLong(PyObject_GetAttrString(options, "presentation ")); | rec->presentation = PyInt_AsLong(PyObject_GetAttrString(options, "presentation ")); | |||
rec->defer_builds_mode = | rec->defer_builds_mode = | |||
PyInt_AsLong(PyObject_GetAttrString(options, "defer_builds_mode")); | PyInt_AsLong(PyObject_GetAttrString(options, "defer_builds_mode")); | |||
rec->full_screen = PyInt_AsLong(PyObject_GetAttrString(options, "full_screen") ); | rec->full_screen = PyInt_AsLong(PyObject_GetAttrString(options, "full_screen") ); | |||
load_str = PyString_AsString(PyObject_GetAttrString(options, "after_load_scrip t")); | load_str = PyString_AsString(PyObject_GetAttrString(options, "after_load_scrip t")); | |||
rec->sphere_mode = PyInt_AsLong(PyObject_GetAttrString(options, "sphere_mode") ); | rec->sphere_mode = PyInt_AsLong(PyObject_GetAttrString(options, "sphere_mode") ); | |||
rec->stereo_capable = PyInt_AsLong(PyObject_GetAttrString(options, "stereo_cap able")); | rec->stereo_capable = PyInt_AsLong(PyObject_GetAttrString(options, "stereo_cap able")); | |||
rec->stereo_mode = PyInt_AsLong(PyObject_GetAttrString(options, "stereo_mode") ); | rec->stereo_mode = PyInt_AsLong(PyObject_GetAttrString(options, "stereo_mode") ); | |||
rec->zoom_mode = PyInt_AsLong(PyObject_GetAttrString(options, "zoom_mode")); | rec->zoom_mode = PyInt_AsLong(PyObject_GetAttrString(options, "zoom_mode")); | |||
rec->no_quit = PyInt_AsLong(PyObject_GetAttrString(options, "no_quit")); | rec->no_quit = PyInt_AsLong(PyObject_GetAttrString(options, "no_quit")); | |||
rec->retina = PyInt_AsLong(PyObject_GetAttrString(options, "retina")); | ||||
rec->launch_status = PyInt_AsLong(PyObject_GetAttrString(options, "launch_stat | ||||
us")); | ||||
rec->gldebug = PyInt_AsLong(PyObject_GetAttrString(options, "gldebug")); | ||||
if(load_str) { | if(load_str) { | |||
if(load_str[0]) { | if(load_str[0]) { | |||
UtilNCopy(rec->after_load_script, load_str, PYMOL_MAX_OPT_STR); | UtilNCopy(rec->after_load_script, load_str, PYMOL_MAX_OPT_STR); | |||
} | } | |||
} | } | |||
if(PyErr_Occurred()) { | if(PyErr_Occurred()) { | |||
PyErr_Print(); | PyErr_Print(); | |||
} | } | |||
} | } | |||
skipping to change at line 2024 | skipping to change at line 2090 | |||
{ /* runs a string in the namespace of the pymol g lobal module */ | { /* runs a string in the namespace of the pymol g lobal module */ | |||
PXDecRef(PYOBJECT_CALLFUNCTION(G->P_inst->exec, "Os", P_pymol, str)); | PXDecRef(PYOBJECT_CALLFUNCTION(G->P_inst->exec, "Os", P_pymol, str)); | |||
} | } | |||
void PRunStringInstance(PyMOLGlobals * G, const char *str) | void PRunStringInstance(PyMOLGlobals * G, const char *str) | |||
{ /* runs a string in the namespace of the pymol i nstance */ | { /* runs a string in the namespace of the pymol i nstance */ | |||
PXDecRef(PYOBJECT_CALLFUNCTION(G->P_inst->exec, "Os", G->P_inst->obj, str)); | PXDecRef(PYOBJECT_CALLFUNCTION(G->P_inst->exec, "Os", G->P_inst->obj, str)); | |||
} | } | |||
void WrapperObjectReset(WrapperObject *wo){ | void WrapperObjectReset(WrapperObject *wo){ | |||
wo->obj = NULL; | if (wo->settingWrapperObject) { | |||
wo->cs = NULL; | reinterpret_cast<SettingPropertyWrapperObject *>(wo->settingWrapperObject)-> | |||
wo->atomInfo = NULL; | wobj = NULL; | |||
PyDict_Clear(wo->dict); | Py_DECREF(wo->settingWrapperObject); | |||
} | ||||
#ifdef _PYMOL_IP_EXTRAS | ||||
if (wo->propertyWrapperObject) { | ||||
reinterpret_cast<SettingPropertyWrapperObject *>(wo->propertyWrapperObject)- | ||||
>wobj = NULL; | ||||
Py_DECREF(wo->propertyWrapperObject); | ||||
} | ||||
#endif | ||||
Py_XDECREF(wo->dict); | ||||
Py_DECREF(wo); | ||||
} | } | |||
void PInit(PyMOLGlobals * G, int global_instance) | void PInit(PyMOLGlobals * G, int global_instance) | |||
{ | { | |||
#ifdef PYMOL_NEW_THREADS | #ifdef PYMOL_NEW_THREADS | |||
PyEval_InitThreads(); | PyEval_InitThreads(); | |||
#endif | #endif | |||
/* BEGIN PROPRIETARY CODE SEGMENT (see disclaimer in "os_proprietary.h") */ | /* BEGIN PROPRIETARY CODE SEGMENT (see disclaimer in "os_proprietary.h") */ | |||
#ifdef WIN32 | #ifdef WIN32 | |||
skipping to change at line 2225 | skipping to change at line 2299 | |||
if (PyType_Ready(&Wrapper_Type) < 0 | if (PyType_Ready(&Wrapper_Type) < 0 | |||
|| PyType_Ready(&settingWrapper_Type) < 0 | || PyType_Ready(&settingWrapper_Type) < 0 | |||
){ | ){ | |||
PRINTFB(G, FB_Python, FB_Errors) | PRINTFB(G, FB_Python, FB_Errors) | |||
" PInit: Wrapper_Type, settingWrapper_Type, propertyWrapper_Type not read y\n" ENDFB(G); | " PInit: Wrapper_Type, settingWrapper_Type, propertyWrapper_Type not read y\n" ENDFB(G); | |||
return; | return; | |||
} | } | |||
Py_INCREF(&Wrapper_Type); | Py_INCREF(&Wrapper_Type); | |||
Py_INCREF(&settingWrapper_Type); | Py_INCREF(&settingWrapper_Type); | |||
} | } | |||
G->P_inst->wrapperObject = (WrapperObject *)PyType_GenericNew(&Wrapper_Type, | ||||
Py_None, Py_None); | ||||
G->P_inst->wrapperObject->G = G; | ||||
G->P_inst->wrapperObject->dict = PyDict_New(); | ||||
G->P_inst->settingWrapperObject = (SettingPropertyWrapperObject *)PyType_Gen | ||||
ericNew(&settingWrapper_Type, Py_None, Py_None); | ||||
G->P_inst->settingWrapperObject->wobj = G->P_inst->wrapperObject; | ||||
Py_INCREF(G->P_inst->wrapperObject); | ||||
Py_INCREF(G->P_inst->settingWrapperObject); | ||||
} | } | |||
#ifdef _PYMOL_NO_MSGPACKC | #ifdef _PYMOL_NO_MSGPACKC | |||
// fallback MMTF support | // fallback MMTF support | |||
PyRun_SimpleString( | PyRun_SimpleString( | |||
"import pymol.importing;" | "import pymol.importing;" | |||
"pymol.importing.loadfunctions.setdefault('mmtf'," | "pymol.importing.loadfunctions.setdefault('mmtf'," | |||
"pymol.importing.load_mmtf)"); | "pymol.importing.load_mmtf)"); | |||
#endif | #endif | |||
} | } | |||
End of changes. 14 change blocks. | ||||
45 lines changed or deleted | 116 lines changed or added |