/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2013 University of Bonn. All rights reserved. * Copyright (C) 2013 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 . */ /* * DestroyAdjacencyAction.cpp * * Created on: May 1, 2013 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include "CodePatterns/Assert.hpp" #include "CodePatterns/Log.hpp" #include "Atom/atom.hpp" #include "Descriptors/AtomIdDescriptor.hpp" #include "Descriptors/AtomSelectionDescriptor.hpp" #include "Graph/BondGraph.hpp" #include "World.hpp" #include "WorldTime.hpp" #include #include #include #include "Actions/GraphAction/DestroyAdjacencyAction.hpp" using namespace MoleCuilder; // Storing undo state struct BondInfo_t { atomId_t leftatom; atomId_t rightatom; size_t degree; }; // and construct the stuff #include "DestroyAdjacencyAction.def" #include "Action_impl_pre.hpp" /** =========== define the function ====================== */ ActionState::ptr GraphDestroyAdjacencyAction::performCall() { BondGraph *BG = World::getInstance().getBondGraph(); ASSERT(BG != NULL, "GraphDestroyAdjacencyAction: BondGraph is NULL."); // check precondition World::ConstAtomComposite Set = const_cast(World::getInstance()). getAllAtoms(AtomsBySelection()); if (Set.empty()) { STATUS("No atoms selected."); return Action::failure; } // count all present bonds std::vector bonds; { size_t count_bonds = 0; for (World::ConstAtomComposite::const_iterator iter = Set.begin(); iter != Set.end(); ++iter) { const atom * const Walker = *iter; count_bonds += Walker->getListOfBonds().size(); } bonds.reserve(count_bonds/2); } // Storing undo info for (World::ConstAtomComposite::const_iterator iter = Set.begin(); iter != Set.end(); ++iter) { const atom * const Walker = *iter; const BondList& ListOfBonds = Walker->getListOfBonds(); for (BondList::const_iterator bonditer = ListOfBonds.begin(); bonditer != ListOfBonds.end(); ++bonditer) { const bond::ptr &CurrentBond = *bonditer; // if both atoms are in selected set, we check ids otherwise not if (((!World::getInstance().isSelected(CurrentBond->leftatom)) || (!World::getInstance().isSelected(CurrentBond->rightatom))) || (CurrentBond->leftatom->getId() < CurrentBond->rightatom->getId())) { BondInfo_t BondInfo; BondInfo.leftatom = CurrentBond->leftatom->getId(); BondInfo.rightatom = CurrentBond->rightatom->getId(); BondInfo.degree = CurrentBond->getDegree(); bonds.push_back(BondInfo); } } } GraphDestroyAdjacencyState *UndoState = new GraphDestroyAdjacencyState(bonds, params); LOG(0, "STATUS: Clearing the Adjacency."); { World::AtomComposite Set = World::getInstance().getAllAtoms(AtomsBySelection()); BG->cleanAdjacencyList(Set); } return ActionState::ptr(UndoState); } ActionState::ptr GraphDestroyAdjacencyAction::performUndo(ActionState::ptr _state) { GraphDestroyAdjacencyState *state = assert_cast(_state.get()); const size_t CurrentTime = WorldTime::getTime(); std::vector &bonds = state->bonds; for(std::vector::const_iterator iter = bonds.begin(); iter != bonds.end(); ++iter) { atom * const Walker = World::getInstance().getAtom(AtomById(iter->leftatom)); ASSERT( Walker != NULL, "GraphDestroyAdjacencyAction::performUndo() - "+toString(iter->leftatom)+" missing."); atom * const OtherWalker = World::getInstance().getAtom(AtomById(iter->rightatom)); ASSERT( OtherWalker != NULL, "GraphDestroyAdjacencyAction::performUndo() - "+toString(iter->rightatom)+" missing."); bond::ptr CurrentBond = Walker->addBond(CurrentTime, OtherWalker); CurrentBond->setDegree(iter->degree); } return ActionState::ptr(_state); } ActionState::ptr GraphDestroyAdjacencyAction::performRedo(ActionState::ptr _state){ BondGraph *BG = World::getInstance().getBondGraph(); ASSERT(BG != NULL, "GraphDestroyAdjacencyAction: BondGraph is NULL."); World::AtomComposite Set = World::getInstance().getAllAtoms(AtomsBySelection()); BG->cleanAdjacencyList(Set); return ActionState::ptr(_state); } bool GraphDestroyAdjacencyAction::canUndo() { return true; } bool GraphDestroyAdjacencyAction::shouldUndo() { return true; } /** =========== end of function ====================== */