/* openDCM, dimensional constraint manager Copyright (C) 2012 Stefan Troeger This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef DCM_MODULE_3D_IMP_H #define DCM_MODULE_3D_IMP_H #include "../module.hpp" #include #include "constraint3d_imp.hpp" #include "geometry3d_imp.hpp" namespace bp = boost::placeholders; namespace dcm { namespace details { // template // struct distance { // typedef typename mpl::find::type iterator; // typedef typename mpl::distance::type, iterator>::type type; // BOOST_MPL_ASSERT((mpl::not_< boost::is_same::type > >)); // }; //build a constraint vector template struct fusion_vec { typedef typename mpl::if_< mpl::is_sequence, T, fusion::vector1 >::type type; }; struct set_constraint_option { template typename boost::enable_if, typename fusion_vec::type >::type operator()(T& val) { return val; }; template typename boost::disable_if, typename fusion_vec::type >::type operator()(T& val) { typename fusion_vec::type vec; fusion::at_c<0>(vec) = val; return vec; }; }; } template template Module3D::type::inheriter_base::inheriter_base() { m_this = ((Sys*) this); }; template template typename Module3D::template type::Geom Module3D::type::inheriter_base::createGeometry3D() { Geom g(new Geometry3D(* ((Sys*) this))); fusion::vector res = m_this->m_cluster->addVertex(); m_this->m_cluster->template setObject (fusion::at_c<0> (res), g); g->template setProperty(fusion::at_c<1>(res)); m_this->push_back(g); return g; }; template template template typename Module3D::template type::Geom Module3D::type::inheriter_base::createGeometry3D(T geom) { Geom g(new Geometry3D(geom, * ((Sys*) this))); fusion::vector res = m_this->m_cluster->addVertex(); m_this->m_cluster->template setObject (fusion::at_c<0> (res), g); g->template setProperty(fusion::at_c<1>(res)); m_this->push_back(g); return g; }; template template void Module3D::type::inheriter_base::removeGeometry3D(Geom g) { GlobalVertex v = g->template getProperty(); //check if this vertex holds a constraint Cons c = m_this->m_cluster->template getObject(v); if(c) c->template emitSignal(c); //emit remove geometry signal before actually deleting it, in case anyone wants to access the //graph before g->template emitSignal(g); //remove the vertex from graph and emit all edges that get removed with the functor boost::function functor = boost::bind(&inheriter_base::apply_edge_remove, this, bp::_1); m_this->m_cluster->removeVertex(v, functor); m_this->erase(g); }; template template template typename Module3D::template type::Cons Module3D::type::inheriter_base::createConstraint3D(Geom first, Geom second, T1 constraint1) { //get the fusion vector type typedef typename details::fusion_vec::type covec; //set the objects covec cv = details::set_constraint_option()(constraint1); //now create the constraint Cons c(new Constraint3D(*m_this, first, second)); //initialize constraint c->initialize(cv); //add it to the clustergraph fusion::vector res; res = m_this->m_cluster->addEdge(first->template getProperty(), second->template getProperty()); if(!fusion::at_c<2>(res)) { Cons rc; return rc; //TODO: throw }; m_this->m_cluster->template setObject (fusion::at_c<1> (res), c); //add the coresbondig edge to the constraint c->template setProperty(fusion::at_c<1>(res)); //store the constraint in general object vector of main system m_this->push_back(c); return c; }; template template void Module3D::type::inheriter_base::removeConstraint3D(Cons c) { GlobalEdge e = c->template getProperty(); c->template emitSignal(c); m_this->m_cluster->removeEdge(e); m_this->erase(c); }; template template void Module3D::type::inheriter_base::apply_edge_remove(GlobalEdge e) { Cons c = m_this->m_cluster->template getObject(e); c->template emitSignal(c); m_this->erase(c); }; template template template typename Module3D::template type::Geom Module3D::type::inheriter_id::createGeometry3D(T geom, Identifier id) { Geom g = inheriter_base::createGeometry3D(geom); g->setIdentifier(id); return g; }; template template typename Module3D::template type::Geom Module3D::type::inheriter_id::createGeometry3D(Identifier id) { Geom g = inheriter_base::createGeometry3D(); g->setIdentifier(id); return g; }; template template void Module3D::type::inheriter_id::removeGeometry3D(Identifier id) { if(hasGeometry3D(id)) inheriter_base::removeGeometry3D(getGeometry3D(id)); else throw module3d_error() << boost::errinfo_errno(410) << error_message("no geometry with this ID in this system"); }; template template template typename Module3D::template type::Cons Module3D::type::inheriter_id::createConstraint3D(Identifier id, Geom first, Geom second, T constraint1) { Cons c = inheriter_base::createConstraint3D(first, second, constraint1); c->setIdentifier(id); return c; }; template template void Module3D::type::inheriter_id::removeConstraint3D(Identifier id) { if(hasConstraint3D(id)) removeConstraint3D(getConstraint3D(id)); else throw module3d_error() << boost::errinfo_errno(411) << error_message("no constraint with this ID in this system"); }; template template bool Module3D::type::inheriter_id::hasGeometry3D(Identifier id) { if(getGeometry3D(id)) return true; return false; }; template template typename Module3D::template type::Geom Module3D::type::inheriter_id::getGeometry3D(Identifier id) { std::vector< Geom >& vec = inheriter_base::m_this->template objectVector(); typedef typename std::vector::iterator iter; for(iter it=vec.begin(); it!=vec.end(); it++) { if(compare_traits::compare((*it)->getIdentifier(), id)) return *it; }; return Geom(); }; template template bool Module3D::type::inheriter_id::hasConstraint3D(Identifier id) { if(getConstraint3D(id)) return true; return false; }; template template typename Module3D::template type::Cons Module3D::type::inheriter_id::getConstraint3D(Identifier id) { std::vector< Cons >& vec = inheriter_base::m_this->template objectVector(); typedef typename std::vector::iterator iter; for(iter it=vec.begin(); it!=vec.end(); it++) { if(compare_traits::compare((*it)->getIdentifier(), id)) return *it; }; return Cons(); }; } //dcm #endif //DCM_MODULE_3D_IMP_H