// add(category, (molids), (atomids)) static PyObject *label_add(PyObject *self, PyObject *args) { char *type; PyObject *molids, *atomids; int i; if (!PyArg_ParseTuple(args, (char *)"sO!O!:label.add", &type, &PyTuple_Type, &molids, &PyTuple_Type, &atomids)) return NULL; VMDApp *app = get_vmdapp(); MoleculeList *mlist = app->moleculeList; int cat = app->geometryList->geom_list_index(type); if (cat < 0) { PyErr_SetString(PyExc_ValueError, (char *)"Unknown label category"); return NULL; } int numitems; if (PyTuple_Size(molids) == 1 && PyTuple_Size(atomids) == 1) numitems = 1; else if (PyTuple_Size(molids) == 2 && PyTuple_Size(atomids) == 2) numitems = 2; else if (PyTuple_Size(molids) == 3 && PyTuple_Size(atomids) == 3) numitems = 3; else if (PyTuple_Size(molids) == 4 && PyTuple_Size(atomids) == 4) numitems = 4; else { PyErr_SetString(PyExc_TypeError, (char *)"label.add: 2nd and 3rd arguments" " must be tuples of size 1, 2, 3, or 4"); return NULL; } int m[4], a[4]; for (i=0; i<numitems; i++) { m[i] = PyInt_AsLong(PyTuple_GET_ITEM(molids, i)); a[i] = PyInt_AsLong(PyTuple_GET_ITEM(atomids, i)); if (PyErr_Occurred()) return NULL; Molecule *mol = mlist->mol_from_id(m[i]); if (!mol) { PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id"); return NULL; } if (a[i] < 0 || a[i] >= mol->nAtoms) { PyErr_SetString(PyExc_ValueError, (char *)"Invalid atom id"); return NULL; } } // Add the label, but don't toggle the on/off status. int ind = app->label_add(type, numitems, m, a, NULL, 0.0f, 0); if (ind < 0) { Py_INCREF(Py_None); return Py_None; } // Get the dict corresponding to this label. The dict we return // corresponds to either the label we just created, or to an existing // label whose state we have not changed. This makes it safe to use // label.add to get a proxy to a VMD label. GeomListPtr glist = app->geometryList->geom_list(cat); return geom2dict((*glist)[ind]); }
// helper function to get a molecule. Raises a ValueError exception on error static MoleculeGraphics *mol_from_id(int id) { VMDApp *app = get_vmdapp(); MoleculeList *mlist = app->moleculeList; Molecule *mol = mlist->mol_from_id(id); if (!mol) { PyErr_SetString(PyExc_ValueError, (char *)"Invalid graphics molecule"); return NULL; } return mol->moleculeGraphics(); }
MoleculeList molecules(const AtomContainer& fragment, bool selected_only) { // iterate over all molecules AtomContainerConstIterator it = fragment.beginAtomContainer(); MoleculeList result; for (; +it; ++it) { const Molecule* molecule = dynamic_cast<const Molecule*>(&*it); if ((molecule != 0) && (it->isSelected() || !selected_only)) { // store the molecule pointer in the list result.push_back(const_cast<Molecule*>(molecule)); } } return result; }
void MolBrowser::update() { MoleculeList *mlist = app->moleculeList; int nummols = mlist->num(); char buf[256], molnamebuf[81]; int need_full_regen = 0; #if 1 // If the browser is larger than needed, we have to // re-create it from scratch since some molecule was // potentially deleted from the middle. // If the size remains fixed, then we need to regenerate // because we are getting called to rename an existing molecule... if (size() > nummols || size() == nummols) { need_full_regen = 1; } #else need_full_regen = 1; #endif if (need_full_regen) { clear(); for (int i=0; i<nummols; i++) { Molecule *mol = mlist->molecule(i); // prevent string length overflows strncpy(molnamebuf, mol->molname(), sizeof(molnamebuf)-1); // display state of active/displayed/fixed by toggling the text color sprintf(buf, "%d\t%s\t%s\t%s\t%s\t%-13s\t%-9d\t%-7d\t%-3d", mol->id(), mlist->is_top(i) ? "T" : " ", mlist->active(i) ? VMDMENU_MOL_ACTIVE : VMDMENU_MOL_INACTIVE, mlist->displayed(i) ? VMDMENU_MOL_DISPLAYED : VMDMENU_MOL_NONDISPLAYED, mlist->fixed(i) ? VMDMENU_MOL_FIXED : VMDMENU_MOL_NONFIXED, molnamebuf, mol->nAtoms, mol->numframes(), mol->num_volume_data() ); if (i < size()) text(i+1, buf); else add(buf); } } else { // we just need to add one new molecule... int i = nummols - 1; Molecule *mol = mlist->molecule(i); // prevent string length overflows strncpy(molnamebuf, mol->molname(), sizeof(molnamebuf)-1); // display state of active/displayed/fixed by toggling the text color sprintf(buf, "%d\t%s\t%s\t%s\t%s\t%-13s\t%-9d\t%-7d\t%-3d", mol->id(), mlist->is_top(i) ? "T" : " ", mlist->active(i) ? VMDMENU_MOL_ACTIVE : VMDMENU_MOL_INACTIVE, mlist->displayed(i) ? VMDMENU_MOL_DISPLAYED : VMDMENU_MOL_NONDISPLAYED, mlist->fixed(i) ? VMDMENU_MOL_FIXED : VMDMENU_MOL_NONFIXED, molnamebuf, mol->nAtoms, mol->numframes(), mol->num_volume_data() ); if (i < size()) text(i+1, buf); // this shouldn't happen here... else add(buf); } if (mainmenu) mainmenu->update_gui_state(); }
void MolBrowser::update() { MoleculeList *mlist = app->moleculeList; int nummols = mlist->num(); #if 1 // // XXX this code updates the state of all of the molecules reliably, but // creates a huge performance cost when thousands of molecules are // loaded. We really need a scheme to create a changelist and apply // the changelist to only those molecule browser lines that need updates. // if (size() > nummols) clear(); for (int i=0; i<nummols; i++) { char buf[256], molnamebuf[81]; Molecule *mol = mlist->molecule(i); // prevent string length overflows strncpy(molnamebuf, mol->molname(), sizeof(molnamebuf)-1); // display state of active/displayed/fixed by toggling the text color sprintf(buf, "%d\t%s\t%s\t%s\t%s\t%-13s\t%-9d\t%-7d\t%-3d", mol->id(), mlist->is_top(i) ? "T" : " ", mlist->active(i) ? VMDMENU_MOL_ACTIVE : VMDMENU_MOL_INACTIVE, mlist->displayed(i) ? VMDMENU_MOL_DISPLAYED : VMDMENU_MOL_NONDISPLAYED, mlist->fixed(i) ? VMDMENU_MOL_FIXED : VMDMENU_MOL_NONFIXED, molnamebuf, mol->nAtoms, mol->numframes(), mol->num_volume_data() ); if (i < size()) text(i+1, buf); // update existing browser line else add(buf); // add a new browser line } #else // // XXX this code addresses the performance issues associated with the // full-update code above, but breaks molecule browser's handling // of operations multi-molecule selections. // char buf[256], molnamebuf[81]; int need_full_regen = 0; #if 1 // If the browser is larger than needed, we have to // re-create it from scratch since some molecule was // potentially deleted from the middle. // If the size remains fixed, then we need to regenerate // because we are getting called to rename an existing molecule... if (size() > nummols || size() == nummols) { need_full_regen = 1; } #else need_full_regen = 1; #endif if (need_full_regen) { clear(); for (int i=0; i<nummols; i++) { Molecule *mol = mlist->molecule(i); // prevent string length overflows strncpy(molnamebuf, mol->molname(), sizeof(molnamebuf)-1); // display state of active/displayed/fixed by toggling the text color sprintf(buf, "%d\t%s\t%s\t%s\t%s\t%-13s\t%-9d\t%-7d\t%-3d", mol->id(), mlist->is_top(i) ? "T" : " ", mlist->active(i) ? VMDMENU_MOL_ACTIVE : VMDMENU_MOL_INACTIVE, mlist->displayed(i) ? VMDMENU_MOL_DISPLAYED : VMDMENU_MOL_NONDISPLAYED, mlist->fixed(i) ? VMDMENU_MOL_FIXED : VMDMENU_MOL_NONFIXED, molnamebuf, mol->nAtoms, mol->numframes(), mol->num_volume_data() ); if (i < size()) text(i+1, buf); // update existing browser line else add(buf); // add a new browser line } } else { // we just need to add one new molecule... int i = nummols - 1; Molecule *mol = mlist->molecule(i); // prevent string length overflows strncpy(molnamebuf, mol->molname(), sizeof(molnamebuf)-1); // display state of active/displayed/fixed by toggling the text color sprintf(buf, "%d\t%s\t%s\t%s\t%s\t%-13s\t%-9d\t%-7d\t%-3d", mol->id(), mlist->is_top(i) ? "T" : " ", mlist->active(i) ? VMDMENU_MOL_ACTIVE : VMDMENU_MOL_INACTIVE, mlist->displayed(i) ? VMDMENU_MOL_DISPLAYED : VMDMENU_MOL_NONDISPLAYED, mlist->fixed(i) ? VMDMENU_MOL_FIXED : VMDMENU_MOL_NONFIXED, molnamebuf, mol->nAtoms, mol->numframes(), mol->num_volume_data() ); if (i < size()) text(i+1, buf); // update existing browser line else add(buf); // add a new browser line } #endif if (mainmenu) mainmenu->update_gui_state(); }