/*
* 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)