Files
create/src/Mod/Assembly/App/opendcm/module3d/module.hpp
2016-04-12 18:11:59 +02:00

336 lines
10 KiB
C++

/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
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_H
#define DCM_MODULE_3D_H
#include <boost/mpl/vector.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/if.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/variant.hpp>
#include <boost/function.hpp>
#include "opendcm/core.hpp"
#include "opendcm/core/object.hpp"
#include "opendcm/core/geometry.hpp"
#include "opendcm/core/clustergraph.hpp"
#include "opendcm/core/sheduler.hpp"
#include "opendcm/core/traits.hpp"
#include "geometry.hpp"
#include "distance.hpp"
#include "parallel.hpp"
#include "angle.hpp"
#include "solver.hpp"
#include "defines.hpp"
#include "clustermath.hpp"
namespace mpl = boost::mpl;
namespace dcm {
struct reset {}; //signal name
struct module3d_error : virtual boost::exception {}; //exception for all module3d special errors
template<typename Typelist, typename ID = No_Identifier>
struct Module3D {
template<typename Sys>
struct type : details::m3d {
struct Constraint3D;
struct Geometry3D;
struct vertex_prop;
struct inheriter_base;
typedef boost::shared_ptr<Geometry3D> Geom;
typedef boost::shared_ptr<Constraint3D> Cons;
typedef mpl::map3< mpl::pair<reset, boost::function<void (Geom) > >,
mpl::pair<remove, boost::function<void (Geom) > > ,
mpl::pair<recalculated, boost::function<void (Geom)> > > GeomSig;
typedef mpl::map1< mpl::pair<remove, boost::function<void (Cons) > > > ConsSignal;
typedef ID Identifier;
typedef Typelist geometry_types;
typedef details::MES<Sys> MES;
typedef details::SystemSolver<Sys> SystemSolver;
template<typename Derived>
class Geometry3D_base : public details::Geometry<typename Sys::Kernel, 3, typename Sys::geometries>,
public Object<Sys, Derived, GeomSig> {
typedef details::Geometry<typename Sys::Kernel, 3, typename Sys::geometries> Base;
typedef Object<Sys, Derived, GeomSig> ObjBase;
typedef typename Sys::Kernel Kernel;
typedef typename Kernel::number_type Scalar;
public:
Geometry3D_base(Sys& system);
template<typename T>
Geometry3D_base(const T& geometry, Sys& system);
template<typename T>
void set(const T& geometry);
bool holdsType() {
return m_geometry.which()!=0;
};
int whichType() {
return m_geometry.which()-1;
};
template<typename Visitor>
typename Visitor::result_type apply(Visitor& vis);
template<typename T>
T convertTo();
virtual boost::shared_ptr<Derived> clone(Sys& newSys);
protected:
typedef typename mpl::push_front<Typelist, boost::blank>::type ExtTypeList;
typedef typename boost::make_variant_over< ExtTypeList >::type Variant;
#ifdef USE_LOGGING
src::logger log;
#endif
Variant m_geometry; //Variant holding the real geometry type
//override protected event functions to emit signals
void reset();
void recalculated();
void removed();
friend struct Constraint3D;
};
template<typename Derived>
class Geometry3D_id : public Geometry3D_base<Derived> {
typedef Geometry3D_base<Derived> Base;
#ifdef USE_LOGGING
attrs::mutable_constant< std::string > log_id;
#endif
public:
Geometry3D_id(Sys& system);
template<typename T>
Geometry3D_id(const T& geometry, Sys& system);
template<typename T>
void set(const T& geometry, Identifier id);
//somehow the base class set funtion is not found
template<typename T>
void set(const T& geometry);
Identifier& getIdentifier();
void setIdentifier(Identifier id);
};
struct Geometry3D : public mpl::if_<boost::is_same<Identifier, No_Identifier>,
Geometry3D_base<Geometry3D>, Geometry3D_id<Geometry3D> >::type {
typedef vertex_prop vertex_propertie;
Geometry3D(Sys& system);
template<typename T>
Geometry3D(const T& geometry, Sys& system);
//allow accessing the internals by module3d classes but not by users
friend struct details::ClusterMath<Sys>;
friend struct details::ClusterMath<Sys>::map_downstream;
friend struct details::SystemSolver<Sys>;
friend struct details::SystemSolver<Sys>::Rescaler;
friend struct inheriter_base;
public:
//the geometry class itself does not hold an aligned eigen object, but maybe the variant
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
template<typename Derived>
class Constraint3D_base : public detail::Constraint<Sys, 3>, public Object<Sys, Derived, ConsSignal> {
typedef detail::Constraint<Sys, 3> CBase;
public:
Constraint3D_base(Sys& system, Geom f, Geom s) : detail::Constraint<Sys, 3>(f,s),
Object<Sys, Derived, ConsSignal>(system) {};
virtual boost::shared_ptr<Derived> clone(Sys& newSys);
};
template<typename Derived>
class Constraint3D_id : public Constraint3D_base<Derived> {
typedef Constraint3D_base<Derived> base;
public:
Constraint3D_id(Sys& system, Geom f, Geom s);
Identifier& getIdentifier();
void setIdentifier(Identifier id);
};
struct Constraint3D : public mpl::if_<boost::is_same<Identifier, No_Identifier>,
Constraint3D_base<Constraint3D>,
Constraint3D_id<Constraint3D> >::type {
Constraint3D(Sys& system, Geom first, Geom second);
friend struct details::SystemSolver<Sys>;
friend struct details::SystemSolver<Sys>::Rescaler;
friend struct details::MES<Sys>;
friend struct inheriter_base;
};
struct inheriter_base {
inheriter_base();
template<typename T>
Geom createGeometry3D(T geom);
Geom createGeometry3D();
void removeGeometry3D(Geom g);
template<typename T1>
Cons createConstraint3D(Geom first, Geom second, T1 constraint1);
void removeConstraint3D(Cons c);
void system_sub(boost::shared_ptr<Sys> subsys) {};
protected:
Sys* m_this;
void apply_edge_remove(GlobalEdge e);
};
struct inheriter_id : public inheriter_base {
protected:
using inheriter_base::m_this;
public:
using inheriter_base::createGeometry3D;
using inheriter_base::createConstraint3D;
template<typename T>
Geom createGeometry3D(T geom, Identifier id);
Geom createGeometry3D(Identifier id);
template<typename T>
Cons createConstraint3D(Identifier id, Geom first, Geom second, T constraint1);
void removeGeometry3D(Identifier id);
void removeConstraint3D(Identifier id);
using inheriter_base::removeGeometry3D;
using inheriter_base::removeConstraint3D;
bool hasGeometry3D(Identifier id);
Geom getGeometry3D(Identifier id);
bool hasConstraint3D(Identifier id);
Cons getConstraint3D(Identifier id);
};
struct inheriter : public mpl::if_<boost::is_same<Identifier, No_Identifier>, inheriter_base, inheriter_id>::type {};
struct math_prop {
typedef cluster_property kind;
typedef details::ClusterMath<Sys> type;
};
struct fix_prop {
typedef cluster_property kind;
typedef bool type;
};
struct vertex_prop {
typedef Geometry3D kind;
typedef GlobalVertex type;
};
struct edge_prop {
typedef Constraint3D kind;
typedef GlobalEdge type;
};
typedef mpl::vector6<vertex_prop, edge_prop, math_prop,
fix_prop, solverfailure, subsystemsolving> properties;
typedef mpl::vector2<Geometry3D, Constraint3D> objects;
typedef mpl::vector5<tag::point3D, tag::direction3D, tag::line3D, tag::plane3D, tag::cylinder3D> geometries;
typedef mpl::map0<> signals;
static void system_init(Sys& sys) {
sys.m_sheduler.addProcessJob(new SystemSolver());
};
static void system_copy(const Sys& from, Sys& into) {
//nothing to to as all objects and properties are copyed with the clustergraph
};
};
};
namespace details {
//allow direct access to the stored geometry in a Geometry3D, copyed from boost variant get
template <typename T>
struct get_visitor {
private:
typedef typename boost::add_pointer<T>::type pointer;
typedef typename boost::add_reference<T>::type reference;
public:
typedef pointer result_type;
public:
pointer operator()(reference operand) const {
return boost::addressof(operand);
}
template <typename U>
pointer operator()(const U&) const {
return static_cast<pointer>(0);
}
};
}
template<typename T, typename G>
typename boost::add_reference<T>::type get(G geom) {
typedef typename boost::add_pointer<T>::type T_ptr;
details::get_visitor<T> v;
T_ptr result = geom->apply(v);
//if (!result)
//TODO:throw bad_get();
return *result;
};
}//dcm
#include "imp/module_imp.hpp"
#endif //DCM_GEOMETRY3D_H