Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

PickModeAddBond.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2019 The Board of Trustees of the           
00004  *cr                        University of Illinois                       
00005  *cr                         All Rights Reserved                        
00006  *cr                                                                   
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: PickModeAddBond.C,v $
00013  *      $Author: johns $        $Locker:  $                $State: Exp $
00014  *      $Revision: 1.19 $      $Date: 2019/01/17 21:21:01 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *
00019  * The PickMode object which allows a pointer to be used to create new 
00020  * geometrical monitoring labels.  This particular version is used only for
00021  * adding molecular labels, i.e. Atoms, Bonds, Angles, and Dihedrals.  As
00022  * more atoms are selected, they are remembered until enough have been picked
00023  * to create the relevant label (i.e. 3 atoms to create an Angle label).
00024  *
00025  ***************************************************************************/
00026 
00027 #include <math.h>
00028 #include "PickModeAddBond.h"
00029 #include "Pickable.h"
00030 #include "DisplayDevice.h"
00031 #include "Inform.h"
00032 #include "DrawMolecule.h"
00033 #include "CommandQueue.h"
00034 #include "TextEvent.h"
00035 #include "VMDApp.h"
00036 #include "utilities.h"
00037 
00038 PickModeAddBond::PickModeAddBond(VMDApp *vmdapp) 
00039 : app(vmdapp) {
00040 
00041   needName = FALSE;
00042 
00043   // indicate we're still at the starting trying to find something
00044   haveItems = 0;
00045 }
00046 
00047 void PickModeAddBond::pick_molecule_start(DrawMolecule *mol, DisplayDevice *d,
00048                         int, int tag, const int * /* cell */ , int dim, const float *pos) {
00049   // ignore the cell argument; we don't create bonds between images!
00050   atom = tag;
00051   memcpy(pPos, pos, dim*sizeof(float));
00052   needName = TRUE;
00053   
00054   int shift_pressed = d->shift_state() & DisplayDevice::SHIFT;
00055   app->commandQueue->runcommand(new PickAtomEvent(mol->id(), tag, 
00056     shift_pressed));
00057 }
00058 
00059 void PickModeAddBond::pick_molecule_end(DrawMolecule *m, DisplayDevice *) {
00060 
00061   if(needName) {
00062     // the selection was successful; first save the info for the object
00063 
00064     int id = m->id();
00065     molids[haveItems] = id; 
00066     atmids[haveItems] = atom;
00067 
00068     // every time an atom is selected, add an Atoms label
00069     app->label_add("Atoms", 1, &id, &atom, NULL, 0, 1);
00070 
00071     // indicate we have one more items in the ones we need
00072     haveItems++;
00073 
00074     // now check if we have enough items for the object we're out for
00075     if(haveItems >= 2) {
00076       if (molids[0] == molids[1]) {
00077         int id1 = atmids[0], id2 = atmids[1];
00078         MolAtom *atom1 = m->atom(id1), *atom2 = m->atom(id2);
00079         if (atom1->bonded(id2)) {
00080           int i;
00081 
00082           // Remove the bond
00083           for (i=0; i<atom1->bonds; i++) {
00084             if (atom1->bondTo[i] == id2) {
00085               for (int j=i; j<MAXATOMBONDS-1; j++)
00086                 atom1->bondTo[j] = atom1->bondTo[j+1];
00087               atom1->bonds--;
00088               break;
00089             }
00090           }
00091 
00092           for (i=0; i<atom2->bonds; i++) {
00093             if (atom2->bondTo[i] == id1) {
00094               for (int j=i; j<MAXATOMBONDS-1; j++)
00095                 atom2->bondTo[j] = atom2->bondTo[j+1];
00096               atom2->bonds--;
00097               break;
00098             }
00099           }
00100         } else {
00101           // Add the bond
00102           if (atom1->bonds >= MAXATOMBONDS ||
00103               atom2->bonds >= MAXATOMBONDS) {
00104             msgErr << "Unable to add bond: one or both atoms already has the maximum number." << sendmsg;
00105           } else {
00106             m->add_bond(id1, id2, 1, ATOMNORMAL);
00107           } 
00108         } 
00109         m->force_recalc(DrawMolItem::MOL_REGEN); // XXX many reps ignore bonds
00110       } else {
00111         msgErr << "Cannot add bond between two molecules." << sendmsg;
00112       } 
00113       // indicate we're done with this selection
00114       haveItems = 0;
00115 
00116       // when the user manipulates the bond info, we consider the bond
00117       // data to have become "valid", such that it will be saved out if
00118       // they write out files that can contain bond info.
00119       m->set_dataset_flag(BaseMolecule::BONDS);
00120     } 
00121   }
00122   needName = FALSE;
00123 }
00124 

Generated on Fri Apr 19 02:45:11 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002