/*
* 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;
}