/* * RepeatBoxAction.cpp * * Created on: May 12, 2010 * Author: heber */ #include "Actions/WorldAction/RepeatBoxAction.hpp" #include "CommandLineParser.hpp" #include "atom.hpp" #include "log.hpp" #include "molecule.hpp" #include "vector.hpp" #include "verbose.hpp" #include "World.hpp" #include #include using namespace std; #include "UIElements/UIFactory.hpp" #include "UIElements/Dialog.hpp" #include "Actions/MapOfActions.hpp" const char WorldRepeatBoxAction::NAME[] = "repeat-box"; WorldRepeatBoxAction::WorldRepeatBoxAction() : Action(NAME) {} WorldRepeatBoxAction::~WorldRepeatBoxAction() {} Action::state_ptr WorldRepeatBoxAction::performCall() { Dialog *dialog = UIFactory::getInstance().makeDialog(); Vector Repeater; int count; const element ** Elements; molecule *mol = NULL; int j = 0; dialog->queryVector(NAME, &Repeater, World::getInstance().getDomain(), false, MapOfActions::getInstance().getDescription(NAME)); dialog->queryMolecule("molecule-by-id", &mol,MapOfActions::getInstance().getDescription("molecule-by-id")); if(dialog->display()) { double * const cell_size = World::getInstance().getDomain(); Vector x,y; for (int axis = 1; axis <= NDIM; axis++) { Vector ** vectors; Repeater[axis] = floor(Repeater[axis]); if (Repeater[axis] < 1) { DoeLog(1) && (eLog()<< Verbose(1) << "Repetition factor must be greater than 1!" << endl); Repeater[axis] = 1; } mol->CountAtoms(); // recount atoms if (mol->AtomCount != 0) { // if there is more than none count = mol->AtomCount; // is changed becausing of adding, thus has to be stored away beforehand Elements = new const element *[count]; vectors = new Vector *[count]; j = 0; atom *first = mol->start; while (first->next != mol->end) { // make a list of all atoms with coordinates and element first = first->next; Elements[j] = first->type; vectors[j] = &first->x; j++; } if (count != j) DoeLog(1) && (eLog()<< Verbose(1) << "AtomCount " << count << " is not equal to number of atoms in molecule " << j << "!" << endl); x.Zero(); y.Zero(); y[abs(axis)-1] = cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] * abs(axis)/axis; // last term is for sign, first is for magnitude for (int i=1;ix = (*vectors[k]) + x; first->type = Elements[k]; // insert original element mol->AddAtom(first); // and add to the molecule (which increments ElementsInMolecule, AtomCount, ...) } } // free memory delete[](Elements); delete[](vectors); // correct cell size if (axis < 0) { // if sign was negative, we have to translate everything x =(-(Repeater[axis]-1)) * y; mol->Translate(&x); } cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= Repeater[axis]; } } delete dialog; return Action::success; } else { delete dialog; return Action::failure; } } Action::state_ptr WorldRepeatBoxAction::performUndo(Action::state_ptr _state) { // ParserLoadXyzState *state = assert_cast(_state.get()); return Action::failure; // string newName = state->mol->getName(); // state->mol->setName(state->lastName); // // return Action::state_ptr(new ParserLoadXyzState(state->mol,newName)); } Action::state_ptr WorldRepeatBoxAction::performRedo(Action::state_ptr _state){ return Action::failure; } bool WorldRepeatBoxAction::canUndo() { return false; } bool WorldRepeatBoxAction::shouldUndo() { return false; } const string WorldRepeatBoxAction::getName() { return NAME; }