/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2012 University of Bonn. All rights reserved. * Copyright (C) 2013-2014 Frederik Heber. All rights reserved. * * * This file is part of MoleCuilder. * * MoleCuilder is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * MoleCuilder is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MoleCuilder. If not, see . */ /* * UndoRedoHelpers.cpp * * Created on: Apr 5, 2012 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif //#include "CodePatterns/MemDebug.hpp" #include "UndoRedoHelpers.hpp" #include #include #include #include "Atom/atom.hpp" #include "molecule.hpp" #include "Descriptors/AtomIdDescriptor.hpp" #include "Descriptors/MoleculeIdDescriptor.hpp" #include "CodePatterns/Assert.hpp" #include "CodePatterns/Log.hpp" #include "World.hpp" #include "WorldTime.hpp" bool MoleCuilder::AddAtomsFromAtomicInfo(const std::vector &atoms) { size_t i=0; for (; i > &mol_atoms) { bool status = true; for (std::map< moleculeId_t, std::vector >::const_iterator iter = mol_atoms.begin(); iter != mol_atoms.end(); ++iter) { // re-create the atom LOG(3, "DEBUG: Re-adding molecule " << iter->first << "."); molecule *mol_Walker = World::getInstance().recreateMolecule(iter->first); status &= (mol_Walker != NULL); // add all its atoms status &= AddAtomsFromAtomicInfo(iter->second); } if (!status) { // remove all molecules again for (std::map< moleculeId_t, std::vector >::const_iterator iter = mol_atoms.begin(); iter != mol_atoms.end(); ++iter) { molecule * mol = World::getInstance().getMolecule(MoleculeById(iter->first)); if (mol != NULL) removeAtomsinMolecule(mol); } // and announce the failure return false; } return true; } void MoleCuilder::RemoveAtomsFromAtomicInfo(std::vector &atoms) { BOOST_FOREACH(const AtomicInfo &_atom, atoms) { World::getInstance().destroyAtom(_atom.getId()); } } void MoleCuilder::StoreBondInformationFromAtoms( const std::vector &atoms, std::vector< BondInfo > &bonds) { ASSERT( bonds.empty(), "StoreBondInformationFromAtoms() - give bonds vector is not empty."); bonds.reserve(atoms.size()*4); for (std::vector::const_iterator atomiter = atoms.begin(); atomiter != atoms.end(); ++atomiter) { const BondList & _atom_bonds = (*atomiter)->getListOfBonds(); for(BondList::const_iterator iter = _atom_bonds.begin(); iter != _atom_bonds.end(); ++iter) bonds.push_back( BondInfo(*iter) ); } } bool MoleCuilder::AddBondsFromBondInfo(const std::vector< BondInfo > &bonds) { bool status = true; std::vector< BondInfo >::const_iterator iter = bonds.begin(); for(;iter != bonds.end(); ++iter) { if (!(*iter).RecreateBond()) { status = false; break; } } if (!status) { // remove all added bonds again for(std::vector< BondInfo >::const_iterator removeiter = bonds.begin(); removeiter != iter; ++removeiter) { removeiter->RemoveBond(); } } return status; } void MoleCuilder::SetAtomsFromAtomicInfo( const std::vector &_movedatoms, const unsigned int _step) { BOOST_FOREACH( const AtomicInfo &_atominfo, _movedatoms) { const atomId_t id = _atominfo.getId(); atom * const _atom = World::getInstance().getAtom(AtomById(id)); ASSERT( _atom != NULL, "MoleCuilder::SetAtomsFromAtomicInfo() - cannot find atom with id " +toString(id)+" in the world."); _atominfo.setAtom( *_atom, _step ); } } void MoleCuilder::SelectAtomsFromAtomicInfo(const std::vector &_movedatoms) { BOOST_FOREACH( const AtomicInfo &_atominfo, _movedatoms) { const atomId_t id = _atominfo.getId(); World::getInstance().selectAtom(id); } } void MoleCuilder::ResetAtomPosition(const std::vector &movedatoms, const std::vector &MovedToVector) { boost::function setter = boost::bind(&atom::setPosition, _1, _2); ResetByFunction(movedatoms, MovedToVector, setter); } void MoleCuilder::ResetAtomVelocity(const std::vector &movedatoms, const std::vector &VelocityVector) { boost::function setter = boost::bind(&atom::setAtomicVelocity, _1, _2); ResetByFunction(movedatoms, VelocityVector, setter); } void MoleCuilder::ResetAtomForce(const std::vector &movedatoms, const std::vector &ForceVector) { boost::function setter = boost::bind(&atom::setAtomicForce, _1, _2); ResetByFunction(movedatoms, ForceVector, setter); } void MoleCuilder::ResetByFunction( const std::vector &movedatoms, const std::vector &MovedToVector, boost::function &setter) { std::vector::const_iterator positer = MovedToVector.begin(); ASSERT(movedatoms.size() == MovedToVector.size(), "MoleCuilder::ResetAtomPosition() - the number of atoms " +toString(movedatoms.size())+" and the number of positions " +toString(MovedToVector.size())+" is not the same."); BOOST_FOREACH( const AtomicInfo &_atominfo, movedatoms) { const atomId_t id = _atominfo.getId(); atom * const _atom = World::getInstance().getAtom(AtomById(id)); ASSERT( _atom != NULL, "FillSphericalSurfaceAction::performRedo() - cannot find atom with id " +toString(id)+" in the world."); setter(_atom, *positer ); ++positer; } } void MoleCuilder::RemoveMoleculesWithAtomsByIds(const std::vector &ids) { for (std::vector::const_iterator iter = ids.begin(); iter != ids.end(); ++iter) { molecule * mol = World::getInstance().getMolecule(MoleculeById(*iter)); if (mol != NULL) { removeAtomsinMolecule(mol); // molecules are automatically removed when empty } } } void MoleCuilder::removeSteps( const std::vector &movedatoms, const unsigned int _firststep, const unsigned int _laststep) { for (std::vector::const_iterator iter = movedatoms.begin(); iter != movedatoms.end(); ++iter) { atom * const _atom = World::getInstance().getAtom(AtomById(*iter)); _atom->removeSteps(_firststep, _laststep); } } void MoleCuilder::addNewStep(const std::vector &_movedatoms, const unsigned int _step) { for(size_t i=0; i< _movedatoms.size(); ++i) { atom * const _atom = World::getInstance().getAtom(AtomById(_movedatoms[i].getId())); _atom->UpdateStep(_step); } } void MoleCuilder::addNewStep(const std::vector &_ids, const unsigned int _step) { for(size_t i=0; i< _ids.size(); ++i) { atom * const _atom = World::getInstance().getAtom(AtomById(_ids[i])); _atom->UpdateStep(_step); } } std::vector MoleCuilder::getIdsFromAtomicInfo(const std::vector &movedatoms) { std::vector ids(movedatoms.size(), (size_t)-1); std::transform( movedatoms.begin(), movedatoms.end(), ids.begin(), boost::bind(&AtomicInfo::getId, _1)); return ids; }