/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010-2012 University of Bonn. 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 . */ /* * ShapeFactory.cpp * * Created on: Sep 5, 2012 * Author: ankele */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include "ShapeFactory.hpp" #include "CodePatterns/Log.hpp" #include "BaseShapes.hpp" #include "ShapeOps.hpp" #include "CodePatterns/Singleton_impl.hpp" #include "LinearAlgebra/Vector.hpp" #include "LinearAlgebra/RealSpaceMatrix.hpp" #include "molecule.hpp" #include "World.hpp" ShapeFactory::ShapeFactory() { // Create map (type -> name). shapeNameMap[NowhereType] = "nowhere"; shapeNameMap[EverywhereType] = "everywhere"; shapeNameMap[SphereType] = "sphere"; shapeNameMap[CuboidType] = "cube"; shapeNameMap[PolygonType] = "polygon"; shapeNameMap[CombinedType] = "combined"; shapeNameMap[CylinderType] = "cylinder"; shapeNameMap[MoleculeSurfaceType] = "molecule-surface"; // Create inverse map. for (ShapeNameMap::iterator iter = shapeNameMap.begin(); iter != shapeNameMap.end(); ++ iter) nameShapeMap[iter->second] = iter->first; // Create baseShapeName list. for (ShapeNameMap::iterator iter = shapeNameMap.begin(); iter != shapeNameMap.end(); ++ iter) if (iter->first != CombinedType) baseShapeNames.push_back(iter->second); } ShapeType ShapeFactory::getShapeByName(const std::string& name) const { NameShapeMap::const_iterator iter = nameShapeMap.find(name); ASSERT(iter != nameShapeMap.end(), "ShapeFactory::getShapeByName() - unknown name: "+name+"."); return iter->second; } std::string ShapeFactory::getShapeName(ShapeType type) const { ShapeNameMap::const_iterator iter = shapeNameMap.find(type); ASSERT(iter != shapeNameMap.end(), "ShapeFactory::getShapeName() - unknown type: "+toString(type)+"."); return iter->second; } bool ShapeFactory::isValidShapeName(const std::string& name) const { NameShapeMap::const_iterator iter = nameShapeMap.find(name); return (iter != nameShapeMap.end()); } bool ShapeFactory::isSimpleShape(const ShapeType type) const { return ((type != CombinedType) && (type != MoleculeSurfaceType) ); } bool ShapeFactory::isSimpleShape(const std::string &name) const { return isSimpleShape(getShapeByName(name)); } const std::vector &ShapeFactory::getBaseShapeNames() const { return baseShapeNames; } ShapeFactory::~ShapeFactory() { } Shape ShapeFactory::produce(ShapeType type, const Vector &translation, const Vector &stretch, double angleX, double angleY, double angleZ) const { for (int i=0; i 0, "ShapeFactory::setStretch() - non positive component."); } // Create the basic shape. Shape s = Nowhere(); switch(type){ case NowhereType: s = Nowhere(); break; case EverywhereType: s = Everywhere(); break; case CuboidType: s = Cuboid(); break; case SphereType: s = Sphere(); break; case CylinderType: s = Cylinder(); break; case MoleculeSurfaceType: { const std::vector molecules = const_cast(World::getInstance()).getSelectedMolecules(); if (molecules.empty()) { ELOG(2, "No molecule is selected, cannot factorize its bounding shape."); s = Nowhere(); } else { const molecule * const mol = (*molecules.begin()); LOG(2, "DEBUG: Factoring shape from bounding box of molecule " << mol->getName() << "."); s = mol->getBoundingShape(stretch[0]); } break; } default: ASSERT(false, "ShapeFactory::produce - unhandled shape type: "+toString(type)+"."); } if (type != MoleculeSurfaceType) { // Transform (if necessary). if (stretch != Vector(1., 1., 1.)) s = ::stretch(s, stretch); if ((angleX != 0) || (angleY != 0) || (angleZ != 0)){ RealSpaceMatrix rotation; rotation.setRotation(angleX, angleY, angleZ); s = transform(s, rotation); } if (!translation.IsZero()) s = translate(s, translation); } return s; } CONSTRUCT_SINGLETON(ShapeFactory)