updated dcm version

This commit is contained in:
Stefan Tröger 2013-09-30 04:38:29 +00:00
parent 913ec86fdd
commit 6c494157f5
30 changed files with 2102 additions and 943 deletions

View File

@ -1 +1,3 @@
/usr/include/eigen3
/home/stefan/Projects/openDCM/opendcm/
/home/stefan/Projects/openDCM/

View File

@ -34,6 +34,7 @@
#endif
#include "core/defines.hpp"
#include "core/geometry.hpp"
#include "core/kernel.hpp"
#include "core/system.hpp"

File diff suppressed because it is too large Load Diff

View File

@ -44,10 +44,12 @@
#include <boost/fusion/sequence/intrinsic/size.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/preprocessor.hpp>
#include "traits.hpp"
#include "object.hpp"
#include "equations.hpp"
#include <Base/Console.h>
#include "geometry.hpp"
class T;
namespace mpl = boost::mpl;
@ -58,30 +60,59 @@ namespace dcm {
namespace detail {
//type erasure container for constraints
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
class Constraint : public Object<Sys, Derived, Signals > {
template<typename Sys, int Dim>
class Constraint {
typedef typename system_traits<Sys>::Kernel Kernel;
typedef typename Sys::Kernel Kernel;
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::DynStride DS;
typedef typename Kernel::MappedEquationSystem MES;
typedef boost::shared_ptr<Geometry> geom_ptr;
typedef boost::shared_ptr<details::Geometry<Kernel, Dim, typename Sys::geometries> > geom_ptr;
typedef std::vector<typename Kernel::Vector3, Eigen::aligned_allocator<typename Kernel::Vector3> > Vec;
//metafunction to create equation from consraint and tags
template<typename C, typename T1, typename T2>
struct equation {
typedef typename C::template type<Kernel, T1, T2> type;
};
public:
Constraint(Sys& system, geom_ptr f, geom_ptr s);
Constraint(geom_ptr f, geom_ptr s);
~Constraint();
virtual boost::shared_ptr<Derived> clone(Sys& newSys);
//workaround until better analysing class is created
// TODO: remove diasable once analyser is available
void disable() {
content->disable();
};
std::vector<boost::any> getGenericEquations();
std::vector<boost::any> getGenericConstraints();
std::vector<const std::type_info*> getEquationTypes();
std::vector<const std::type_info*> getConstraintTypes();
template<typename Tag1, typename Tag2, typename ConstraintVector>
void initializeFromTags(ConstraintVector& obj);
template<typename ConstraintVector>
void initialize(ConstraintVector& obj);
protected:
//initialising from geometry functions
template<typename WhichType, typename ConstraintVector>
void initializeFirstGeometry(ConstraintVector& cv, boost::mpl::false_);
template<typename WhichType, typename ConstraintVector>
void initializeFirstGeometry(ConstraintVector& cv, boost::mpl::true_);
template<typename WhichType, typename FirstType, typename ConstraintVector>
void initializeSecondGeometry(ConstraintVector& cv, boost::mpl::false_);
template<typename WhichType, typename FirstType, typename ConstraintVector>
void initializeSecondGeometry(ConstraintVector& cv, boost::mpl::true_);
template<typename FirstType, typename SecondType, typename ConstraintVector>
inline void intitalizeFinalize(ConstraintVector& cv, boost::mpl::false_);
template<typename FirstType, typename SecondType, typename ConstraintVector>
inline void intitalizeFinalize(ConstraintVector& cv, boost::mpl::true_);
int equationCount();
template< typename creator_type>
@ -105,14 +136,14 @@ protected:
struct EquationSet {
EquationSet() : m_diff_first(NULL,0,DS(0,0)), m_diff_first_rot(NULL,0,DS(0,0)),
m_diff_second(NULL,0,DS(0,0)), m_diff_second_rot(NULL,0,DS(0,0)),
m_residual(NULL,0,DS(0,0)) {};
m_residual(NULL,0,DS(0,0)), enabled(true) {};
Equation m_eq;
typename Kernel::VectorMap m_diff_first, m_diff_first_rot; //first geometry diff
typename Kernel::VectorMap m_diff_second, m_diff_second_rot; //second geometry diff
typename Kernel::VectorMap m_residual;
bool pure_rotation;
bool pure_rotation, enabled;
typedef Equation eq_type;
};
@ -125,6 +156,7 @@ protected:
virtual int equationCount() = 0;
virtual void setMaps(MES& mes, geom_ptr first, geom_ptr second) = 0;
virtual void collectPseudoPoints(geom_ptr first, geom_ptr second, Vec& vec1, Vec& vec2) = 0;
virtual void disable() = 0;
virtual placeholder* clone() = 0;
//some runtime type infos are needed, as we cant access the contents with arbitrary functors
@ -133,6 +165,7 @@ protected:
virtual std::vector<const std::type_info*> getEquationTypes() = 0;
virtual std::vector<const std::type_info*> getConstraintTypes() = 0;
};
int value;
public:
template< typename ConstraintVector, typename EquationVector>
@ -215,6 +248,27 @@ public:
void operator()(T& val) const;
};
struct EquationCounter {
int& count;
EquationCounter(int& c) : count(c) {};
template< typename T >
void operator()(T& val) const {
if(val.enabled)
count++;
};
};
//workaround until we have a better analyser class
struct disabler {
template<typename T>
void operator()(T& val) const {
val.enabled = false;
};
};
struct GenericEquations {
std::vector<boost::any>& vec;
GenericEquations(std::vector<boost::any>& v);
@ -248,8 +302,9 @@ public:
virtual void setMaps(MES& mes, geom_ptr first, geom_ptr second);
virtual void collectPseudoPoints(geom_ptr f, geom_ptr s, Vec& vec1, Vec& vec2);
virtual placeholder* clone();
virtual int equationCount() {
return mpl::size<EquationVector>::value;
virtual int equationCount();
virtual void disable() {
fusion::for_each(m_sets, disabler());
};
virtual std::vector<boost::any> getGenericEquations();
@ -259,27 +314,8 @@ public:
EquationSets m_sets;
Objects m_objects;
};
protected:
template< typename ConstraintVector >
struct creator : public boost::static_visitor<void> {
typedef ConstraintVector Objects;
Objects& objects;
creator(Objects& obj);
template<typename C, typename T1, typename T2>
struct equation {
typedef typename C::template type<Kernel, T1, T2> type;
};
template<typename T1, typename T2>
void operator()(const T1&, const T2&);
placeholder* p;
bool need_swap;
protected:
void for_each(EquationSets m_sets, Calculater Calculater);
};
placeholder* content;
@ -295,121 +331,111 @@ public:
/*****************************************************************************************************************/
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
Constraint<Sys, Derived, Signals, MES, Geometry>::Constraint(Sys& system, geom_ptr f, geom_ptr s)
template<typename Sys, int Dim>
Constraint<Sys, Dim>::Constraint(geom_ptr f, geom_ptr s)
: first(f), second(s), content(0) {
this->m_system = &system;
//cf = first->template connectSignal<reset> (boost::bind(&Constraint::geometryReset, this, _1));
//cs = second->template connectSignal<reset> (boost::bind(&Constraint::geometryReset, this, _1));
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
Constraint<Sys, Derived, Signals, MES, Geometry>::~Constraint() {
template<typename Sys, int Dim>
Constraint<Sys, Dim>::~Constraint() {
delete content;
//first->template disconnectSignal<reset>(cf);
//second->template disconnectSignal<reset>(cs);
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
boost::shared_ptr<Derived> Constraint<Sys, Derived, Signals, MES, Geometry>::clone(Sys& newSys) {
template<typename Sys, int Dim>
template<typename tag1, typename tag2, typename ConstraintVector>
void Constraint<Sys, Dim>::initializeFromTags(ConstraintVector& v) {
//copy the standart stuff
boost::shared_ptr<Derived> np = boost::shared_ptr<Derived>(new Derived(*static_cast<Derived*>(this)));
np->m_system = &newSys;
//copy the internals
np->content = content->clone();
//and get the geometry pointers right
if(first) {
GlobalVertex v = first->template getProperty<typename Geometry::vertex_propertie>();
np->first = newSys.m_cluster->template getObject<Geometry>(v);
}
if(second) {
GlobalVertex v = second->template getProperty<typename Geometry::vertex_propertie>();
np->second = newSys.m_cluster->template getObject<Geometry>(v);
}
return np;
};
typedef tag_order< tag1, tag2 > order;
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename ConstraintVector>
void Constraint<Sys, Derived, Signals, MES, Geometry>::initialize(ConstraintVector& obj) {
//transform the constraints into eqautions with the now known types
typedef typename mpl::fold< ConstraintVector, mpl::vector<>,
mpl::push_back<mpl::_1, equation<mpl::_2, typename order::first_tag,
typename order::second_tag> > >::type EquationVector;
//first create the new placeholder
creator<ConstraintVector> c(obj);
boost::apply_visitor(c, first->m_geometry, second->m_geometry);
//and build the placeholder
content = new holder<ConstraintVector, EquationVector>(v);
//and now store it
content = c.p;
//geometry order needs to be the one needed by equations
if(c.need_swap)
if(order::swapt::value)
first.swap(second);
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
int Constraint<Sys, Derived, Signals, MES, Geometry>::equationCount() {
template<typename Sys, int Dim>
template<typename ConstraintVector>
void Constraint<Sys, Dim>::initialize(ConstraintVector& cv) {
//use the compile time unrolling to retrieve the geometry tags
initializeFirstGeometry<mpl::int_<0>, ConstraintVector>(cv, mpl::true_());
};
template<typename Sys, int Dim>
int Constraint<Sys, Dim>::equationCount() {
return content->equationCount();
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template< typename creator_type>
void Constraint<Sys, Derived, Signals, MES, Geometry>::resetType(creator_type& c) {
void Constraint<Sys, Dim>::resetType(creator_type& c) {
boost::apply_visitor(c, first->m_geometry, second->m_geometry);
content = c.p;
if(c.need_swap)
first.swap(second);
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
void Constraint<Sys, Derived, Signals, MES, Geometry>::calculate(Scalar scale, bool rotation_only) {
template<typename Sys, int Dim>
void Constraint<Sys, Dim>::calculate(Scalar scale, bool rotation_only) {
content->calculate(first, second, scale, rotation_only);
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
void Constraint<Sys, Derived, Signals, MES, Geometry>::treatLGZ() {
template<typename Sys, int Dim>
void Constraint<Sys, Dim>::treatLGZ() {
content->treatLGZ(first, second);
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
void Constraint<Sys, Derived, Signals, MES, Geometry>::setMaps(MES& mes) {
template<typename Sys, int Dim>
void Constraint<Sys, Dim>::setMaps(MES& mes) {
content->setMaps(mes, first, second);
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
void Constraint<Sys, Derived, Signals, MES, Geometry>::collectPseudoPoints(Vec& vec1, Vec& vec2) {
template<typename Sys, int Dim>
void Constraint<Sys, Dim>::collectPseudoPoints(Vec& vec1, Vec& vec2) {
content->collectPseudoPoints(first, second, vec1, vec2);
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
std::vector<boost::any> Constraint<Sys, Derived, Signals, MES, Geometry>::getGenericEquations() {
template<typename Sys, int Dim>
std::vector<boost::any> Constraint<Sys, Dim>::getGenericEquations() {
return content->getGenericEquations();
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
std::vector<boost::any> Constraint<Sys, Derived, Signals, MES, Geometry>::getGenericConstraints() {
template<typename Sys, int Dim>
std::vector<boost::any> Constraint<Sys, Dim>::getGenericConstraints() {
return content->getGenericConstraints();
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
std::vector<const std::type_info*> Constraint<Sys, Derived, Signals, MES, Geometry>::getEquationTypes() {
template<typename Sys, int Dim>
std::vector<const std::type_info*> Constraint<Sys, Dim>::getEquationTypes() {
return content->getEquationTypes();
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
std::vector<const std::type_info*> Constraint<Sys, Derived, Signals, MES, Geometry>::getConstraintTypes() {
template<typename Sys, int Dim>
std::vector<const std::type_info*> Constraint<Sys, Dim>::getConstraintTypes() {
return content->getConstraintTypes();
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::OptionSetter::OptionSetter(Objects& val) : objects(val) {};
Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::OptionSetter::OptionSetter(Objects& val) : objects(val) {};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
template<typename T>
typename boost::enable_if<typename Constraint<Sys, Derived, Signals, MES, Geometry>::template holder<ConstraintVector, EquationVector>::template has_option<T>::type, void>::type
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::OptionSetter::operator()(EquationSet<T>& val) const {
typename boost::enable_if<typename Constraint<Sys, Dim>::template holder<ConstraintVector, EquationVector>::template has_option<T>::type, void>::type
Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::OptionSetter::operator()(EquationSet<T>& val) const {
//get the index of the corresbonding equation
typedef typename mpl::find<EquationVector, T>::type iterator;
@ -419,25 +445,29 @@ Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, Equat
val.pure_rotation = fusion::at<distance>(objects).pure_rotation;
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
template<typename T>
typename boost::enable_if<mpl::not_<typename Constraint<Sys, Derived, Signals, MES, Geometry>::template holder<ConstraintVector, EquationVector>::template has_option<T>::type>, void>::type
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::OptionSetter::operator()(EquationSet<T>& val) const {
typename boost::enable_if<mpl::not_<typename Constraint<Sys, Dim>::template holder<ConstraintVector, EquationVector>::template has_option<T>::type>, void>::type
Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::OptionSetter::operator()(EquationSet<T>& val) const {
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::Calculater::Calculater(geom_ptr f, geom_ptr s, Scalar sc, bool rotation_only)
Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::Calculater::Calculater(geom_ptr f, geom_ptr s, Scalar sc, bool rotation_only)
: first(f), second(s), scale(sc), rot_only(rotation_only) {
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
template< typename T >
void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::Calculater::operator()(T& val) const {
void Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::Calculater::operator()(T& val) const {
//if the equation is disabled we don't have anything mapped so avoid accessing it
if(!val.enabled)
return;
//if we only need pure rotational functions and we are not such a nice thing, everything becomes 0
if(rot_only && !val.pure_rotation) {
@ -520,17 +550,20 @@ void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector,
}
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::MapSetter::MapSetter(MES& m, geom_ptr f, geom_ptr s)
Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::MapSetter::MapSetter(MES& m, geom_ptr f, geom_ptr s)
: mes(m), first(f), second(s) {
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
template< typename T >
void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::MapSetter::operator()(T& val) const {
void Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::MapSetter::operator()(T& val) const {
if(!val.enabled)
return;
//when in cluster, there are 6 clusterparameter we differentiat for, if not we differentiat
//for every parameter in the geometry;
@ -555,17 +588,21 @@ void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector,
mes.setJacobiMap(equation, second->m_offset, second->m_parameterCount, val.m_diff_second);
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::PseudoCollector::PseudoCollector(geom_ptr f, geom_ptr s, Vec& vec1, Vec& vec2)
Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::PseudoCollector::PseudoCollector(geom_ptr f, geom_ptr s, Vec& vec1, Vec& vec2)
: first(f), second(s), points1(vec1), points2(vec2) {
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
template< typename T >
void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::PseudoCollector::operator()(T& val) const {
void Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::PseudoCollector::operator()(T& val) const {
if(!val.enabled)
return;
if(first->m_isInCluster && second->m_isInCluster) {
val.m_eq.calculatePseudo(first->m_rotated, points1, second->m_rotated, points2);
}
@ -581,21 +618,23 @@ void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector,
}
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::LGZ::LGZ(geom_ptr f, geom_ptr s)
Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::LGZ::LGZ(geom_ptr f, geom_ptr s)
: first(f), second(s) {
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
template< typename T >
void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::LGZ::operator()(T& val) const {
void Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::LGZ::operator()(T& val) const {
if(!val.enabled)
return;
//to treat local gradient zeros we calculate a approximate second derivative of the equations
//only do that if neseccary: residual is not zero
Base::Console().Message("res: %f\n", val.m_residual(0));
if(val.m_residual(0) > 1e-7) { //TODO: use exact precission and scale value
//rotations exist only in cluster
@ -604,19 +643,19 @@ void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector,
for(int i=0; i<3; i++) {
//only treat if the gradient realy is zero
Base::Console().Message("local grad: %f\n", val.m_diff_first_rot(i));
if(std::abs(val.m_diff_first_rot(i)) < 1e-7) {
//to get the approximated second derivative we need the slightly moved geometrie
typename Kernel::Vector incr = first->m_parameter + first->m_diffparam.col(i)*1e-3;
const typename Kernel::Vector p_old = first->m_parameter;
first->m_parameter += first->m_diffparam.col(i)*1e-3;
first->normalize();
//with this changed geometrie we test if a gradient exist now
typename Kernel::VectorMap block(&first->m_diffparam(0,i),first->m_parameterCount,1, DS(1,1));
typename Kernel::VectorMap block2(&incr(0),first->m_parameterCount,1, DS(1,1));
typename Kernel::number_type res = val.m_eq.calculateGradientFirst(block2,
typename Kernel::number_type res = val.m_eq.calculateGradientFirst(first->m_parameter,
second->m_parameter, block);
first->m_parameter = p_old;
//let's see if the initial LGZ was a real one
Base::Console().Message("approx second: %f\n", res);
if(std::abs(res) > 1e-7) {
//is a fake zero, let's correct it
@ -631,19 +670,19 @@ void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector,
for(int i=0; i<3; i++) {
//only treat if the gradient realy is zero
Base::Console().Message("local grad: %f\n", val.m_diff_second_rot(i));
if(std::abs(val.m_diff_second_rot(i)) < 1e-7) {
//to get the approximated second derivative we need the slightly moved geometrie
typename Kernel::Vector incr = second->m_parameter + second->m_diffparam.col(i)*1e-3;
const typename Kernel::Vector p_old = second->m_parameter;
second->m_parameter += second->m_diffparam.col(i)*1e-3;
second->normalize();
//with this changed geometrie we test if a gradient exist now
typename Kernel::VectorMap block(&second->m_diffparam(0,i),second->m_parameterCount,1, DS(1,1));
typename Kernel::VectorMap block2(&incr(0),second->m_parameterCount,1, DS(1,1));
typename Kernel::number_type res = val.m_eq.calculateGradientFirst(block2,
typename Kernel::number_type res = val.m_eq.calculateGradientFirst(first->m_parameter,
second->m_parameter, block);
second->m_parameter = p_old;
//let's see if the initial LGZ was a real one
Base::Console().Message("approx second: %f\n", res);
if(std::abs(res) > 1e-7) {
//is a fake zero, let's correct it
@ -655,155 +694,226 @@ void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector,
};
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::GenericEquations::GenericEquations(std::vector<boost::any>& v)
Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::GenericEquations::GenericEquations(std::vector<boost::any>& v)
: vec(v) {
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
template< typename T >
void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::GenericEquations::operator()(T& val) const {
void Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::GenericEquations::operator()(T& val) const {
vec.push_back(val.m_eq);
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::GenericConstraints::GenericConstraints(std::vector<boost::any>& v)
Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::GenericConstraints::GenericConstraints(std::vector<boost::any>& v)
: vec(v) {
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
template< typename T >
void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::GenericConstraints::operator()(T& val) const {
void Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::GenericConstraints::operator()(T& val) const {
vec.push_back(val);
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::Types::Types(std::vector<const std::type_info*>& v)
Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::Types::Types(std::vector<const std::type_info*>& v)
: vec(v) {
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
template< typename T >
void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::Types::operator()(T& val) const {
void Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::Types::operator()(T& val) const {
vec.push_back(&typeid(T));
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::holder(Objects& obj) : m_objects(obj) {
Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::holder(Objects& obj) : m_objects(obj) {
//set the initial values in the equations
fusion::for_each(m_sets, OptionSetter(obj));
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::calculate(geom_ptr first, geom_ptr second,
void Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::calculate(geom_ptr first, geom_ptr second,
Scalar scale, bool rotation_only) {
fusion::for_each(m_sets, Calculater(first, second, scale, rotation_only));
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::treatLGZ(geom_ptr first, geom_ptr second) {
void Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::treatLGZ(geom_ptr first, geom_ptr second) {
fusion::for_each(m_sets, LGZ(first, second));
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
typename Constraint<Sys, Derived, Signals, MES, Geometry>::placeholder*
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::resetConstraint(geom_ptr first, geom_ptr second) const {
typename Constraint<Sys, Dim>::placeholder*
Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::resetConstraint(geom_ptr first, geom_ptr second) const {
//boost::apply_visitor(creator, first->m_geometry, second->m_geometry);
//if(creator.need_swap) first.swap(second);
return NULL;
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::setMaps(MES& mes, geom_ptr first, geom_ptr second) {
void Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::setMaps(MES& mes, geom_ptr first, geom_ptr second) {
fusion::for_each(m_sets, MapSetter(mes, first, second));
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::collectPseudoPoints(geom_ptr f, geom_ptr s, Vec& vec1, Vec& vec2) {
void Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::collectPseudoPoints(geom_ptr f, geom_ptr s, Vec& vec1, Vec& vec2) {
fusion::for_each(m_sets, PseudoCollector(f, s, vec1, vec2));
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
typename Constraint<Sys, Derived, Signals, MES, Geometry>::placeholder*
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::clone() {
typename Constraint<Sys, Dim>::placeholder*
Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::clone() {
return new holder(*this);
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
int Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::equationCount() {
int count = 0;
EquationCounter counter(count);
fusion::for_each(m_sets, counter);
return count;
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
std::vector<boost::any>
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::getGenericEquations() {
Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::getGenericEquations() {
std::vector<boost::any> vec;
fusion::for_each(m_sets, GenericEquations(vec));
return vec;
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
std::vector<boost::any>
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::getGenericConstraints() {
Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::getGenericConstraints() {
std::vector<boost::any> vec;
fusion::for_each(m_objects, GenericConstraints(vec));
return vec;
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
std::vector<const std::type_info*>
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::getEquationTypes() {
Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::getEquationTypes() {
std::vector<const std::type_info*> vec;
mpl::for_each< EquationVector >(Types(vec));
return vec;
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename Sys, int Dim>
template<typename ConstraintVector, typename EquationVector>
std::vector<const std::type_info*>
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::getConstraintTypes() {
Constraint<Sys, Dim>::holder<ConstraintVector, EquationVector>::getConstraintTypes() {
std::vector<const std::type_info*> vec;
mpl::for_each< ConstraintVector >(Types(vec));
return vec;
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template< typename ConstraintVector >
Constraint<Sys, Derived, Signals, MES, Geometry>::creator<ConstraintVector>::creator(Objects& obj) : objects(obj) {
/****************************************************************/
/** compiletime unrolled geometry initialising */
/****************************************************************/
template<typename Sys, int Dim>
template<typename WhichType, typename ConstraintVector>
void Constraint<Sys, Dim>::initializeFirstGeometry(ConstraintVector& cv, boost::mpl::false_ /*unrolled*/) {
//this function is only for breaking the compilation loop, it should never be called
BOOST_ASSERT(false); //Should never assert here; only meant to stop recursion at the end of the typelist
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template< typename ConstraintVector >
template<typename T1, typename T2>
void Constraint<Sys, Derived, Signals, MES, Geometry>::creator<ConstraintVector>::operator()(const T1&, const T2&) {
template<typename Sys, int Dim>
template<typename WhichType, typename ConstraintVector>
void Constraint<Sys, Dim>::initializeFirstGeometry(ConstraintVector& cv, boost::mpl::true_ /*unrolled*/) {
typedef tag_order< typename geometry_traits<T1>::tag, typename geometry_traits<T2>::tag > order;
typedef typename Sys::geometries geometries;
switch(first->getExactType()) {
//transform the constraints into eqautions with the now known types
typedef typename mpl::fold< ConstraintVector, mpl::vector<>,
mpl::push_back<mpl::_1, equation<mpl::_2, typename order::first_tag,
typename order::second_tag> > >::type EquationVector;
//and build the placeholder
p = new holder<ConstraintVector, EquationVector>(objects);
need_swap = order::swapt::value;
#ifdef BOOST_PP_LOCAL_ITERATE
#define BOOST_PP_LOCAL_MACRO(n) \
case (WhichType::value + n): \
return initializeSecondGeometry<boost::mpl::int_<0>,\
typename mpl::at_c<geometries, WhichType::value + n >::type,\
ConstraintVector>(cv, typename boost::mpl::less<boost::mpl::int_<WhichType::value + n>, boost::mpl::size<geometries> >::type()); \
break;
#define BOOST_PP_LOCAL_LIMITS (0, 10)
#include BOOST_PP_LOCAL_ITERATE()
#endif //BOOST_PP_LOCAL_ITERATE
default:
typedef typename mpl::int_<WhichType::value + 10> next_which_t;
return initializeFirstGeometry<next_which_t, ConstraintVector> (cv,
typename mpl::less< next_which_t, typename mpl::size<geometries>::type >::type());
}
};
template<typename Sys, int Dim>
template<typename WhichType, typename FirstType, typename ConstraintVector>
void Constraint<Sys, Dim>::initializeSecondGeometry(ConstraintVector& cv, boost::mpl::false_ /*unrolled*/) {
//this function is only for breaking the compilation loop, it should never be called
BOOST_ASSERT(false); //Should never assert here; only meant to stop recursion at the end of the typelist
};
template<typename Sys, int Dim>
template<typename WhichType, typename FirstType, typename ConstraintVector>
void Constraint<Sys, Dim>::initializeSecondGeometry(ConstraintVector& cv, boost::mpl::true_ /*unrolled*/) {
typedef typename Sys::geometries geometries;
switch(second->getExactType()) {
#ifdef BOOST_PP_LOCAL_ITERATE
#define BOOST_PP_LOCAL_MACRO(n) \
case (WhichType::value + n): \
return intitalizeFinalize<FirstType, \
typename mpl::at_c<geometries, WhichType::value + n >::type,\
ConstraintVector>(cv, typename boost::mpl::less<boost::mpl::int_<WhichType::value + n>, boost::mpl::size<geometries> >::type()); \
break;
#define BOOST_PP_LOCAL_LIMITS (0, 10)
#include BOOST_PP_LOCAL_ITERATE()
#endif //BOOST_PP_LOCAL_ITERATE
default:
typedef typename mpl::int_<WhichType::value + 10> next_which_t;
return initializeSecondGeometry<next_which_t, FirstType, ConstraintVector>
(cv, typename mpl::less
< next_which_t
, typename mpl::size<geometries>::type>::type()
);
}
};
template<typename Sys, int Dim>
template<typename FirstType, typename SecondType, typename ConstraintVector>
inline void Constraint<Sys, Dim>::intitalizeFinalize(ConstraintVector& cv, boost::mpl::true_ /*is_unrolled_t*/) {
initializeFromTags<FirstType, SecondType>(cv);
};
template<typename Sys, int Dim>
template<typename FirstType, typename SecondType, typename ConstraintVector>
inline void Constraint<Sys, Dim>::intitalizeFinalize(ConstraintVector& cv, boost::mpl::false_ /*is_unrolled_t*/) {
//Should never be here at runtime; only required to block code generation that deref's the sequence out of bounds
BOOST_ASSERT(false);
}
};//detail
@ -811,3 +921,5 @@ void Constraint<Sys, Derived, Signals, MES, Geometry>::creator<ConstraintVector>
#endif //GCM_CONSTRAINT_H

View File

@ -44,11 +44,6 @@ namespace mpl = boost::mpl;
namespace dcm {
//a few exceptions to handle unsupported combinations
struct constraint_error : virtual boost::exception { };
typedef boost::error_info<struct first_geom, std::string> error_type_first_geometry;
typedef boost::error_info<struct second_geom, std::string> error_type_second_geometry;
struct no_option {};
template<typename Kernel>

View File

@ -33,7 +33,9 @@
#include <boost/mpl/or.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/find.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/fusion/include/mpl.hpp>
@ -43,7 +45,6 @@
#include <boost/variant.hpp>
#include "object.hpp"
#include "traits.hpp"
#include "logging.hpp"
#include "transformation.hpp"
@ -53,6 +54,9 @@ namespace fusion = boost::fusion;
namespace dcm {
//signal we use for recalculation
struct recalculated {};
namespace tag {
struct undefined {
@ -62,13 +66,73 @@ struct undefined {
//we need to order tags, this values make it easy for module tags
namespace weight {
struct direction : mpl::int_<0> {};
struct point : mpl::int_<1> {};
struct line : mpl::int_<2> {};
struct plane : mpl::int_<3> {};
struct cylinder : mpl::int_<4> {};
}
struct parameter : mpl::int_<0> {};
struct direction : mpl::int_<1> {};
struct point : mpl::int_<2> {};
struct line : mpl::int_<3> {};
struct segment : mpl::int_<4> {};
struct circle : mpl::int_<5> {};
struct arc : mpl::int_<6> {};
struct ellipse : mpl::int_<7> {};
struct elliptical_arc : mpl::int_<8> {};
struct plane : mpl::int_<9> {};
struct cylinder : mpl::int_<10> {};
}
} // tag
namespace details {
struct bg {}; //struct to allow test for basic geometry
template< typename weight_type, int params, bool rotatable, bool translatable>
struct basic_geometry : public bg {
typedef mpl::int_<params> parameters;
typedef typename mpl::if_c<translatable, mpl::int_<1>, mpl::int_<0> >::type translations;
typedef typename mpl::if_c<rotatable, mpl::int_<1>, mpl::int_<0> >::type rotations;
typedef weight_type weight;
typedef mpl::vector0<> sub_stack;
};
//build up stacked geometry. these are geometrys which can be splitted into multiple basic geometries. For
//example lines can be splittet into a point and a direction. Make sure you order the basic geometry in a
//sensible rotation/translation manner. Remember: geometrie is first rotated, than translated. Therefore
//everything that gets rotated and translated needs to be first, than the rotation only stuff, then the
//untransformed. For a line this would be <point, direction>
template<typename weight_type, typename T1, typename T2>
struct stacked2_geometry {
//be sure we only stack base geometrys
BOOST_MPL_ASSERT((boost::is_base_of< bg, T1 >));
BOOST_MPL_ASSERT((boost::is_base_of< bg, T2 >));
typedef typename mpl::plus<typename T1::parameters, typename T2::parameters>::type parameters;
typedef typename mpl::plus<typename T1::rotations, typename T2::rotations>::type rotations;
typedef typename mpl::plus<typename T1::translations, typename T2::translations>::type translations;
typedef weight_type weight;
typedef mpl::vector2<T1, T2> sub_stack;
};
template<typename weight_type, typename T1, typename T2, typename T3>
struct stacked3_geometry {
//be sure we only stack base geometrys
BOOST_MPL_ASSERT((boost::is_base_of< bg, T1 >));
BOOST_MPL_ASSERT((boost::is_base_of< bg, T2 >));
BOOST_MPL_ASSERT((boost::is_base_of< bg, T3 >));
typedef typename mpl::plus<typename T1::parameters, typename T2::parameters, typename T3::parameters>::type parameters;
typedef typename mpl::plus<typename T1::rotations, typename T2::rotations, typename T3::rotations>::type rotations;
typedef typename mpl::plus<typename T1::translations, typename T2::translations, typename T3::translations>::type translations;
typedef weight_type weight;
typedef mpl::vector3<T1, T2, T3> sub_stack;
};
} //details
namespace tag {
//a parameter is universal, so let's define it here
struct parameter : details::basic_geometry<weight::parameter, 1, false, false> {};
} //tag
struct orderd_bracket_accessor {
@ -124,41 +188,26 @@ struct geometry_clone_traits {
};
};
struct reset {}; //signal namespace
namespace details {
namespace detail {
// the parameter a geometr needs in a mapped equation system need to be managed seperate, as
// we may want to access the same parameter space from different geometries (if they are linked)
// this is done by the parameter space class
template<typename Kernel>
struct parameter_space {
template< typename Sys, typename Derived, typename GeometrieTypeList, int Dim>
class Geometry : public Object<Sys, Derived,
mpl::map3< mpl::pair<reset, boost::function<void (boost::shared_ptr<Derived>) > >,
mpl::pair<remove, boost::function<void (boost::shared_ptr<Derived>) > > ,
mpl::pair<recalculated, boost::function<void (boost::shared_ptr<Derived>)> > > > {
void init(typename Kernel::MappedEquationSystem* mes);
typedef mpl::map3< mpl::pair<reset, boost::function<void (boost::shared_ptr<Derived>) > >,
mpl::pair<remove, boost::function<void (boost::shared_ptr<Derived>) > >,
mpl::pair<recalculated, boost::function<void (boost::shared_ptr<Derived>)> > > Signals;
};
template<typename Kernel, int Dim, typename TagList = mpl::vector0<> >
class Geometry {
typedef typename boost::make_variant_over< GeometrieTypeList >::type Variant;
typedef Object<Sys, Derived, Signals> Base;
typedef typename system_traits<Sys>::Kernel Kernel;
typedef typename system_traits<Sys>::Cluster Cluster;
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::DynStride DS;
typedef typename Kernel::template transform_type<Dim>::type Transform;
typedef typename Kernel::template transform_type<Dim>::diff_type DiffTransform;
struct cloner : boost::static_visitor<void> {
typedef typename boost::make_variant_over< GeometrieTypeList >::type Variant;
Variant variant;
cloner(Variant& v) : variant(v) {};
template<typename T>
void operator()(T& t) {
variant = geometry_clone_traits<T>()(t);
};
};
#ifdef USE_LOGGING
protected:
src::logger log;
@ -167,23 +216,26 @@ protected:
public:
typedef mpl::int_<Dim> Dimension;
Geometry(Sys& system);
template<typename T>
Geometry(const T& geometry, Sys& system);
Geometry();
template<typename T>
void set(const T& geometry);
template<typename Visitor>
typename Visitor::result_type apply(Visitor& vis) {
return boost::apply_visitor(vis, m_geometry);
//basic ations
template<typename tag, typename Derived>
void setValue(const Eigen::MatrixBase<Derived>& t) {
init<tag>();
m_global = t;
};
typename Kernel::Vector& getValue() {
return m_global;
};
//basic ation
void transform(const Transform& t);
virtual boost::shared_ptr<Derived> clone(Sys& newSys);
int getGeneralType() {
return m_general_type;
};
int getExactType() {
return m_exact_type;
};
//allow accessing the internal values in unittests without making them public,
//so that access control of the internal classes is not changed and can be tested
@ -212,12 +264,19 @@ public:
int parameterCount() {
return m_parameterCount;
};
template<typename T>
void test_linkTo(boost::shared_ptr< Geometry< Kernel, Dim > > geom, int offset) {
linkTo<T>(geom, offset);
};
bool test_isLinked() {
return isLinked();
};
#endif
//protected would be the right way, however, visual studio 10 does not find a way to access them even when constraint::holder structs
//are declared friend
//protected:
Variant m_geometry; //Variant holding the real geometry type
int m_general_type, m_exact_type; //hold the type numbers for easy identification
int m_BaseParameterCount; //count of the parameters the variant geometry type needs
int m_parameterCount; //count of the used parameters (when in cluster:6, else m_BaseParameterCount)
int m_offset, m_offset_rot; //the starting point of our parameters in the math system parameter vector
@ -230,13 +289,16 @@ public:
typename Kernel::Matrix m_diffparam; //gradient vectors combined as matrix when in cluster
typename Kernel::VectorMap m_parameter; //map to the parameters in the solver
template<typename T>
void init(const T& t);
template<typename tag>
void init();
void normalize();
typename Sys::Kernel::VectorMap& getParameterMap();
void initMap();
typename Kernel::VectorMap& getParameterMap();
void initMap(typename Kernel::MappedEquationSystem* mes);
bool isInitialised() {
return m_init;
};
void setClusterMode(bool iscluster, bool isFixed);
bool getClusterMode() {
@ -246,30 +308,32 @@ public:
return m_clusterFixed;
};
int m_link_offset;
boost::shared_ptr<Geometry<Kernel, Dim, TagList> > m_link;
template<typename T>
void linkTo(boost::shared_ptr< Geometry< Kernel, Dim, TagList > > geom, int offset);
bool isLinked() {
return m_link!=0;
};
void recalculate(DiffTransform& trans);
typename Kernel::Vector3 getPoint() {
return m_toplocal.template segment<Dim>(0);
};
//visitor to write the calculated value into the variant
struct apply_visitor : public boost::static_visitor<void> {
apply_visitor(typename Kernel::Vector& v) : value(v) {};
template <typename T>
void operator()(T& t) const {
(typename geometry_traits<T>::modell()).template inject<typename Kernel::number_type,
typename geometry_traits<T>::accessor >(t, value);
}
typename Kernel::Vector& value;
};
//use m_value or parametermap as new value, dependend on the solving mode
void finishCalculation();
template<typename VectorType>
void transform(const Transform& t, VectorType& vec);
void scale(Scalar value);
//let the derived class decide what happens on significant events
virtual void reset() = 0;
virtual void recalculated() = 0;
virtual void removed() = 0;
};
@ -279,71 +343,37 @@ public:
/*****************************************************************************************************************/
/*****************************************************************************************************************/
template< typename Sys, typename Derived, typename GeometrieTypeList, int Dim>
Geometry<Sys, Derived, GeometrieTypeList, Dim>::Geometry(Sys& system)
template< typename Kernel, int Dim, typename TagList>
Geometry<Kernel, Dim, TagList>::Geometry()
: m_isInCluster(false), m_parameter(NULL,0,DS(0,0)),
m_clusterFixed(false), m_init(false) {
#ifdef USE_LOGGING
log.add_attribute("Tag", attrs::constant< std::string >("Geometry3D"));
log.add_attribute("Tag", attrs::constant< std::string >("Geometry"));
#endif
this->m_system = &system;
};
template< typename Sys, typename Derived, typename GeometrieTypeList, int Dim>
template<typename T>
Geometry<Sys, Derived, GeometrieTypeList, Dim>::Geometry(const T& geometry, Sys& system)
: m_isInCluster(false), m_geometry(geometry), m_parameter(NULL,0,DS(0,0)),
m_clusterFixed(false), m_init(false) {
#ifdef USE_LOGGING
log.add_attribute("Tag", attrs::constant< std::string >("Geometry3D"));
#endif
this->m_system = &system;
init<T>(geometry);
};
template< typename Sys, typename Derived, typename GeometrieTypeList, int Dim>
template<typename T>
void Geometry<Sys, Derived, GeometrieTypeList, Dim>::set(const T& geometry) {
m_geometry = geometry;
init<T>(geometry);
//Base::template emitSignal<reset>( ((Derived*)this)->shared_from_this() );
};
template< typename Sys, typename Derived, typename GeometrieTypeList, int Dim>
void Geometry<Sys, Derived, GeometrieTypeList, Dim>::transform(const Transform& t) {
template< typename Kernel, int Dim, typename TagList>
void Geometry<Kernel, Dim, TagList>::transform(const Transform& t) {
if(m_isInCluster)
transform(t, m_toplocal);
else if(m_init)
transform(t, m_rotated);
else
transform(t, m_global);
if(m_init)
transform(t, m_rotated);
else
transform(t, m_global);
};
template<typename Sys, typename Derived, typename GeometrieTypeList, int Dim>
boost::shared_ptr<Derived> Geometry<Sys, Derived, GeometrieTypeList, Dim>::clone(Sys& newSys) {
template< typename Kernel, int Dim, typename TagList>
template<typename tag>
void Geometry<Kernel, Dim, TagList>::init() {
//copy the standart stuff
boost::shared_ptr<Derived> np = boost::shared_ptr<Derived>(new Derived(*static_cast<Derived*>(this)));
np->m_system = &newSys;
//it's possible that the variant contains pointers, so we need to clone them
cloner clone_fnc(np->m_geometry);
boost::apply_visitor(clone_fnc, m_geometry);
return np;
};
template< typename Sys, typename Derived, typename GeometrieTypeList, int Dim>
template<typename T>
void Geometry<Sys, Derived, GeometrieTypeList, Dim>::init(const T& t) {
m_BaseParameterCount = geometry_traits<T>::tag::parameters::value;
m_BaseParameterCount = tag::parameters::value;
m_parameterCount = m_BaseParameterCount;
m_rotations = geometry_traits<T>::tag::rotations::value;
m_translations = geometry_traits<T>::tag::translations::value;
m_rotations = tag::rotations::value;
m_translations = tag::translations::value;
m_toplocal.setZero(m_parameterCount);
m_global.resize(m_parameterCount);
@ -353,8 +383,9 @@ void Geometry<Sys, Derived, GeometrieTypeList, Dim>::init(const T& t) {
m_diffparam.resize(m_parameterCount,6);
m_diffparam.setZero();
(typename geometry_traits<T>::modell()).template extract<Scalar,
typename geometry_traits<T>::accessor >(t, m_global);
m_general_type = tag::weight::value;
m_exact_type = mpl::find<TagList, tag>::type::pos::value;
normalize();
//new value which is not set into parameter, so init is false
@ -366,45 +397,73 @@ void Geometry<Sys, Derived, GeometrieTypeList, Dim>::init(const T& t) {
};
template< typename Sys, typename Derived, typename GeometrieTypeList, int Dim>
void Geometry<Sys, Derived, GeometrieTypeList, Dim>::normalize() {
template< typename Kernel, int Dim, typename TagList>
void Geometry<Kernel, Dim, TagList>::normalize() {
//directions are not nessessarily normalized, but we need to ensure this in cluster mode
for(int i=m_translations; i!=m_rotations; i++)
m_global.template segment<Dim>(i*Dim).normalize();
};
template< typename Sys, typename Derived, typename GeometrieTypeList, int Dim>
typename Sys::Kernel::VectorMap& Geometry<Sys, Derived, GeometrieTypeList, Dim>::getParameterMap() {
template< typename Kernel, int Dim, typename TagList>
typename Kernel::VectorMap& Geometry<Kernel, Dim, TagList>::getParameterMap() {
m_isInCluster = false;
m_parameterCount = m_BaseParameterCount;
return m_parameter;
};
template< typename Sys, typename Derived, typename GeometrieTypeList, int Dim>
void Geometry<Sys, Derived, GeometrieTypeList, Dim>::initMap() {
//when direct parameter solving the global value is wanted (as it's the initial rotation*toplocal)
m_parameter = m_global;
m_init = true;
template< typename Kernel, int Dim, typename TagList>
template<typename T>
void Geometry<Kernel, Dim, TagList>::linkTo(boost::shared_ptr<Geometry<Kernel, Dim, TagList> > geom, int offset) {
init<T>();
m_link = geom;
m_link_offset = offset;
m_global = geom->m_global.segment(offset, m_BaseParameterCount);
};
template< typename Sys, typename Derived, typename GeometrieTypeList, int Dim>
void Geometry<Sys, Derived, GeometrieTypeList, Dim>::setClusterMode(bool iscluster, bool isFixed) {
template< typename Kernel, int Dim, typename TagList>
void Geometry<Kernel, Dim, TagList>::initMap(typename Kernel::MappedEquationSystem* mes) {
//check should not be needed, but how knows...
if(!m_init) {
if(!isLinked()) {
m_offset = mes->setParameterMap(m_parameterCount, getParameterMap());
m_parameter = m_global;
m_init = true;
}
else {
//it's important that the linked geometry is initialised, as we going to access its parameter map
if(!m_link->isInitialised())
m_link->initMap(mes);
m_offset = m_link->m_offset + m_link_offset;
new(&getParameterMap()) typename Kernel::VectorMap(&m_link->getParameterMap()(m_link_offset), m_parameterCount, typename Kernel::DynStride(1,1));
}
}
};
template< typename Kernel, int Dim, typename TagList>
void Geometry<Kernel, Dim, TagList>::setClusterMode(bool iscluster, bool isFixed) {
m_isInCluster = iscluster;
m_clusterFixed = isFixed;
if(iscluster) {
//we are in cluster, therfore the parameter map should not point to a solver value but to
//the rotated original value;
new(&m_parameter) typename Sys::Kernel::VectorMap(&m_rotated(0), m_parameterCount, DS(1,1));
new(&m_parameter) typename Kernel::VectorMap(&m_rotated(0), m_parameterCount, DS(1,1));
//the local value is the global one as no transformation was applied yet
m_toplocal = m_global;
m_rotated = m_global;
} else new(&m_parameter) typename Sys::Kernel::VectorMap(&m_global(0), m_parameterCount, DS(1,1));
}
else
new(&m_parameter) typename Kernel::VectorMap(&m_global(0), m_parameterCount, DS(1,1));
};
template< typename Sys, typename Derived, typename GeometrieTypeList, int Dim>
void Geometry<Sys, Derived, GeometrieTypeList, Dim>::recalculate(DiffTransform& trans) {
if(!m_isInCluster) return;
template< typename Kernel, int Dim, typename TagList>
void Geometry<Kernel, Dim, TagList>::recalculate(DiffTransform& trans) {
if(!m_isInCluster)
return;
for(int i=0; i!=m_rotations; i++) {
//first rotate the original to the transformed value
@ -432,8 +491,8 @@ void Geometry<Sys, Derived, GeometrieTypeList, Dim>::recalculate(DiffTransform&
};
template< typename Sys, typename Derived, typename GeometrieTypeList, int Dim>
void Geometry<Sys, Derived, GeometrieTypeList, Dim>::finishCalculation() {
template< typename Kernel, int Dim, typename TagList>
void Geometry<Kernel, Dim, TagList>::finishCalculation() {
//if fixed nothing needs to be changed
if(m_isInCluster) {
//recalculate(1.); //remove scaling to get right global value
@ -450,18 +509,16 @@ void Geometry<Sys, Derived, GeometrieTypeList, Dim>::finishCalculation() {
BOOST_LOG(log) << "Finish calculation";
#endif
};
apply_visitor v(m_global);
apply(v);
m_init = false;
m_isInCluster = false;
//emit the signal for recalculation
Base::template emitSignal<recalculated>( ((Derived*)this)->shared_from_this() );
recalculated();
};
template< typename Sys, typename Derived, typename GeometrieTypeList, int Dim>
template< typename Kernel, int Dim, typename TagList>
template<typename VectorType>
void Geometry<Sys, Derived, GeometrieTypeList, Dim>::transform(const Transform& t, VectorType& vec) {
void Geometry<Kernel, Dim, TagList>::transform(const Transform& t, VectorType& vec) {
//everything that needs to be translated needs to be fully transformed
for(int i=0; i!=m_translations; i++) {
@ -480,8 +537,8 @@ void Geometry<Sys, Derived, GeometrieTypeList, Dim>::transform(const Transform&
#endif
}
template< typename Sys, typename Derived, typename GeometrieTypeList, int Dim>
void Geometry<Sys, Derived, GeometrieTypeList, Dim>::scale(Scalar value) {
template< typename Kernel, int Dim, typename TagList>
void Geometry<Kernel, Dim, TagList>::scale(Scalar value) {
for(int i=0; i!=m_translations; i++)
m_parameter.template segment<Dim>(i*Dim) *= 1./value;

View File

@ -35,6 +35,8 @@
#include "transformation.hpp"
#include "logging.hpp"
#include "defines.hpp"
#include "multimap.hpp"
namespace dcm {
@ -47,15 +49,11 @@ struct nothing {
//the parameter types
enum ParameterType {
general,
rotation,
complete
general, //every non-rotation parameter, therefore every translation and non transformed parameter
rotation, //all rotation parameters
complete //all parameter
};
//all solving related errors
typedef boost::error_info<struct user_message,std::string> error_message;
struct solving_error : virtual boost::exception { };
template<typename Kernel>
struct Dogleg {
@ -219,7 +217,6 @@ struct Dogleg {
number_type dF=0, dL=0;
number_type rho;
//handle possible lgz's
if(iter==0)
sys.removeLocalGradientZeros();
@ -492,7 +489,7 @@ struct Kernel {
};
virtual void recalculate() = 0;
virtual void removeLocalGradientZeros() = 0;
virtual void removeLocalGradientZeros() = 0;
};
@ -530,3 +527,4 @@ struct Kernel {

View File

@ -52,6 +52,10 @@
namespace mpl = boost::mpl;
namespace fusion = boost::fusion;
/* Preprocessor implementation of emit signal. As we need many overloads with diffrent number of
* templated parameters we use boost preprocessor to do the hard repetive work. The definition and
* implementation are definded first as they need to be known before usage
* */
#define EMIT_ARGUMENTS(z, n, data) \
BOOST_PP_CAT(data, n)
@ -63,16 +67,16 @@ namespace fusion = boost::fusion;
void emitSignal( \
BOOST_PP_ENUM_BINARY_PARAMS(n, Arg, const& arg) \
);
#define EMIT_CALL_DEC(z, n, data) \
template<typename Sys, typename Derived, typename Sig> \
template<typename SigMap> \
template < \
typename S \
BOOST_PP_ENUM_TRAILING_PARAMS(n, typename Arg) \
> \
void Object<Sys, Derived, Sig>::emitSignal( \
BOOST_PP_ENUM_BINARY_PARAMS(n, Arg, const& arg) \
) \
void SignalOwner<SigMap>::emitSignal( \
BOOST_PP_ENUM_BINARY_PARAMS(n, Arg, const& arg) \
) \
{ \
typedef typename mpl::find<sig_name, S>::type iterator; \
typedef typename mpl::distance<typename mpl::begin<sig_name>::type, iterator>::type distance; \
@ -84,12 +88,68 @@ namespace fusion = boost::fusion;
namespace dcm {
/** @defgroup Objects Objects
*
* @brief Concept and functionality of the dcm objects
*
*
**/
//few standart signal names
struct remove {};
struct recalculated {};
typedef boost::any Connection;
template<typename SigMap>
struct SignalOwner {
/**
* @brief Connects a slot to a specified signal.
*
* Slots are boost::functions which get called when the signal is emitted. Any valid boost::function
* which ressembles the signal tyes signature can be registert. It is important that the signal type
* was registerd to this object on creation by the appropriate template parameter.
*
* @tparam S the signal which should be intercepted
* @param function boost::function which resembles the signal type's signature
* @return void
**/
template<typename S>
Connection connectSignal(typename mpl::at<SigMap, S>::type function);
/**
* @brief Disconnects a slot for a specific signal.
*
* Disconnects a slot so that it dosn't get called at signal emittion. It's important to
* disconnect the slot by the same boost:function it was connected with.
*
* @tparam S the signal type of interest
* @param c connection with which the slot was initialy connected
* @return void
**/
template<typename S>
void disconnectSignal(Connection c);
//with no vararg templates before c++11 we need preprocessor to create the overloads of emit signal we need
BOOST_PP_REPEAT(5, EMIT_CALL_DEF, ~)
protected:
/*signal handling
* extract all signal types to allow index search (inex search on signal functions would fail as same
* signatures are supported for multiple signals). Create std::vectors to allow multiple slots per signal
* and store these vectors in a fusion::vector for easy access.
* */
typedef typename mpl::fold < SigMap, mpl::vector<>,
mpl::push_back<mpl::_1, mpl::key_type<SigMap, mpl::_2> > >::type sig_name;
typedef typename mpl::fold < SigMap, mpl::vector<>,
mpl::push_back<mpl::_1, mpl::value_type<SigMap, mpl::_2> > >::type sig_functions;
typedef typename mpl::fold < sig_functions, mpl::vector<>,
mpl::push_back<mpl::_1, std::list<mpl::_2> > >::type sig_vectors;
typedef typename fusion::result_of::as_vector<sig_vectors>::type Signals;
Signals m_signals;
};
/**
* @brief Base class for all object types
*
@ -103,7 +163,9 @@ typedef boost::any Connection;
* \tparam Sig a mpl::map specifing the object's signals by (type - boost::function) pairs
**/
template<typename Sys, typename Derived, typename Sig>
struct Object : public boost::enable_shared_from_this<Derived> {
struct Object : public PropertyOwner<typename details::properties_by_object<typename Sys::properties, Derived>::type>,
public SignalOwner<Sig>,
boost::enable_shared_from_this<Derived> {
Object() {};
Object(Sys& system);
@ -120,87 +182,7 @@ struct Object : public boost::enable_shared_from_this<Derived> {
**/
virtual boost::shared_ptr<Derived> clone(Sys& newSys);
/**
* @brief Access properties
*
* Returns a reference to the propertys actual value. The property type has to be registerd to the
* System type which was given as template parameter to this object.
* @tparam Prop property type which should be accessed
* @return Prop::type& a reference to the properties actual value.
**/
template<typename Prop>
typename Prop::type& getProperty();
/**
* @brief Set properties
*
* Set'S the value of a specified property. The property type has to be registerd to the
* System type which was given as template parameter to this object. Note that setProperty(value)
* is equivalent to getProperty() = value.
* @tparam Prop property type which should be setProperty
* @param value value of type Prop::type which should be set in this object
**/
template<typename Prop>
void setProperty(typename Prop::type value);
/**
* @brief Connects a slot to a specified signal.
*
* Slots are boost::functions which get called when the signal is emitted. Any valid boost::function
* which ressembles the signal tyes signature can be registert. It is important that the signal type
* was registerd to this object on creation by the appropriate template parameter.
*
* @tparam S the signal which should be intercepted
* @param function boost::function which resembles the signal type's signature
* @return void
**/
template<typename S>
Connection connectSignal(typename mpl::at<Sig, S>::type function);
/**
* @brief Disconnects a slot for a specific signal.
*
* Disconnects a slot so that it dosn't get called at signal emittion. It's important to
* disconnect the slot by the same boost:function it was connected with.
*
* @tparam S the signal type of interest
* @param function boost::function with which the slot was connected
* @return void
**/
template<typename S>
void disconnectSignal(Connection c);
/*properties
* search the property map of the system class and get the mpl::vector of properties for the
* derived type. It's imortant to not store the properties but their types. These types are
* stored and accessed as fusion vector.
* */
typedef typename mpl::at<typename Sys::object_properties, Derived>::type Mapped;
typedef typename mpl::if_< boost::is_same<Mapped, mpl::void_ >, mpl::vector0<>, Mapped>::type Sequence;
typedef typename details::pts<Sequence>::type Properties;
Properties m_properties;
Sys* m_system;
protected:
/*signal handling
* extract all signal types to allow index search (inex search on signal functions would fail as same
* signatures are supported for multiple signals). Create std::vectors to allow multiple slots per signal
* and store these vectors in a fusion::vector for easy access.
* */
typedef typename mpl::fold< Sig, mpl::vector<>,
mpl::push_back<mpl::_1, mpl::key_type<Sig, mpl::_2> > >::type sig_name;
typedef typename mpl::fold< Sig, mpl::vector<>,
mpl::push_back<mpl::_1, mpl::value_type<Sig, mpl::_2> > >::type sig_functions;
typedef typename mpl::fold< sig_functions, mpl::vector<>,
mpl::push_back<mpl::_1, std::list<mpl::_2> > >::type sig_vectors;
typedef typename fusion::result_of::as_vector<sig_vectors>::type Signals;
Signals m_signals;
public:
//with no vararg templates before c++11 we need preprocessor to create the overloads of emit signal we need
BOOST_PP_REPEAT(5, EMIT_CALL_DEF, ~)
};
@ -214,44 +196,29 @@ template<typename Sys, typename Derived, typename Sig>
Object<Sys, Derived, Sig>::Object(Sys& system) : m_system(&system) {};
template<typename Sys, typename Derived, typename Sig>
boost::shared_ptr<Derived> Object<Sys, Derived, Sig>::clone(Sys& newSys) {
boost::shared_ptr<Derived> Object<Sys, Derived, Sig>::clone(Sys& newSys)
{
boost::shared_ptr<Derived> np = boost::shared_ptr<Derived>(new Derived(*static_cast<Derived*>(this)));
np->m_system = &newSys;
return np;
};
template<typename Sys, typename Derived, typename Sig>
template<typename Prop>
typename Prop::type& Object<Sys, Derived, Sig>::getProperty() {
typedef typename mpl::find<Sequence, Prop>::type iterator;
typedef typename mpl::distance<typename mpl::begin<Sequence>::type, iterator>::type distance;
BOOST_MPL_ASSERT((mpl::not_<boost::is_same<iterator, typename mpl::end<Sequence>::type > >));
return fusion::at<distance>(m_properties);
};
template<typename Sys, typename Derived, typename Sig>
template<typename Prop>
void Object<Sys, Derived, Sig>::setProperty(typename Prop::type value) {
typedef typename mpl::find<Sequence, Prop>::type iterator;
typedef typename mpl::distance<typename mpl::begin<Sequence>::type, iterator>::type distance;
BOOST_MPL_ASSERT((mpl::not_<boost::is_same<iterator, typename mpl::end<Sequence>::type > >));
fusion::at<distance>(m_properties) = value;
};
template<typename Sys, typename Derived, typename Sig>
template<typename SigMap>
template<typename S>
Connection Object<Sys, Derived, Sig>::connectSignal(typename mpl::at<Sig, S>::type function) {
Connection SignalOwner<SigMap>::connectSignal(typename mpl::at<SigMap, S>::type function)
{
typedef typename mpl::find<sig_name, S>::type iterator;
typedef typename mpl::distance<typename mpl::begin<sig_name>::type, iterator>::type distance;
typedef typename fusion::result_of::value_at<Signals, distance>::type list_type;
list_type& list = fusion::at<distance>(m_signals);
return list.insert(list.begin(),function);
return list.insert(list.begin(), function);
};
template<typename Sys, typename Derived, typename Sig>
template<typename SigMap>
template<typename S>
void Object<Sys, Derived, Sig>::disconnectSignal(Connection c) {
void SignalOwner<SigMap>::disconnectSignal(Connection c)
{
typedef typename mpl::find<sig_name, S>::type iterator;
typedef typename mpl::distance<typename mpl::begin<sig_name>::type, iterator>::type distance;

View File

@ -27,21 +27,150 @@
#include <boost/fusion/container/vector.hpp>
#include <boost/mpl/find.hpp>
#include <boost/mpl/void.hpp>
#include <boost/mpl/filter_view.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/property_map/property_map.hpp>
#include "kernel.hpp"
namespace mpl = boost::mpl;
namespace fusion = boost::fusion;
namespace dcm {
/** @addtogroup Core
* @{ */
/** @defgroup Property Properties
*
* @brief Concept and handling of properties for generic data storage and type extension.
*
* Properties are a basic building block of the dcm and fullfill two essential tasks: First, build a
* infrastructure for storing data in any kind of object and second, make this data universally accessible.
* Universally accessible means in this context, that it shall be possible to retrieve data only by
* knowing some kind of identifier. No data type specific get/set functions or access to class members
* should be needed to access the stored values. The usage of identifiers allows to design interfaces
* for properties in a type interchangable way. Therefore no restrictions are imposed on the interface,
* no matter what or how much data is stored.
*
* The connection of data type and identifier is achieved through the property structs, which all follow
* the same concept: Identifier is the struct type, the stored data is exposed as 'type' typedef. The data
* type can be every c++ type (including classes and structs) which is default constructable. They don't need
* to be assignable or copyable by default, thats only nesseccary if you want to change the hole stored
* object by assigning. If not, the data object can be uncopyable and it should be used by
* retrieving it's reference with get-methods.
*
* Propertys are further designed to fit in the concept of compile-time modularisation. To allow the extension
* of all data-holding entitys with new data types, propertys store their own purpose. Thats
* done by extending the property struct with a second typedef which is named kind and which specifies of which
* kind the property is. That means, that this typedef defines when the property shall be used and for which
* context it is designed for. Dependend on the propertys kind, it will be added to diffrent places inside the dcm.
* A property of kind @ref vertex_property will added to vertices, a property of kind @ref object_property to all
* objects and so on.
*
* If the property type is a standart c++ type like int or bool, the defualt value can't be set by using its
* constructor. Therefore a interface for setting default values is added to the property. If you want
* to assign a default value you just need to add a struct default_value which returns the wanted default
* value with the operator(). If you don't want a default value, just don't add the struct. The implementation
* assignes the default value to the property, therefore it should only be used with assignalble types.
*
*
* A property implementation for storing integers at a graph edge with the identifier
* 'test'property' may look like that:
* @code
* struct test_property {
* typedef int type;
* typedef edge_property kind;
* }
* @endcode
*
* The same property with a default value would be implemented like this:
* @code
* struct test_property {
* typedef int type;
* typedef edge_property kind;
* struct default_value {
* int operator()() {
* return 3;
* };
* };
* }
* @endcode
*
*
* If you want to use properties in your class you should derive from PropertyOwner class, as it doas all the
* hanling needed and gives you get and set functions which work with the designed identifiers.
*
* @{ */
/**
* @brief Exeption for property errors
*
* This exception is thrown when a property related error is detected, for example if a objects is ask for a
* property which it does not own. This exceptions own the error-code range from 300-399.
**/
struct property_error : virtual boost::exception { };
/**
* @brief Identifier for vertex properties
*
* This is a identifier structure for vertex properties. Every property with this struct as 'kind' type
* will be added to all vertices of a cluster. It is accessible through global and local vertex
* descriptors. These properties are intended for use in boost algorithms in combination with
* \ref property_map .
*/
struct vertex_property {};
/**
* @brief Identifier for edge properties
*
* This is a identifier structure for edge properties. Every property with this struct as 'kind' type
* will be added to all local edges of a cluster. It is accessible through local edge
* descriptors, or global one by getting it's holding local edge first. Note that global edges don't
* have properties, as the properties are intended for use inside boost graph algorithms and therefore
* only needed in local edges. @see property_map
*/
struct edge_property {};
/**
* @brief Identifier for cluster properties
*
* A ClusterGraph has it's own properties, and ever property with this identifier as 'kind' type will be
* added to it. This is intended for internal dcm usage, its possible to give the abstract cluster a meaning
* by adding special properties to it. It can be accessed by special ClusterGraph functions designed for this
* purpose.
**/
struct cluster_property {};
/**
*@brief Identifier for general object properties
*
* Aproperty with this struct as 'kind' type will be added to all existing objects, no matter of individual
* type. Use this only for general, sharable properties. To add a property to a single object, use it's
* type as 'kind'.
**/
struct object_property {};
/**
*@brief Identifier for system setting properties
*
* Aproperty with this struct as 'kind' type will be added to the system class. Use this for user settings,
* which are just properties which are accessed horugh "setting" functions.
**/
struct setting_property {};
namespace details {
/** @addtogroup Metafunctions
* @{
* @brief Get vertex property information
*
* This traits struct is used to get property information regarding ClusterGraph vertices. It
* allows access to the local descriptor, the mpl property sequence and the position, at which the
* fusion property sequence is stored inside the bundle. It's used to allow generic property
* selection in combination with @ref property_selector
**/
template<typename Graph>
struct vertex_selector {
typedef typename boost::graph_traits<Graph>::vertex_descriptor key_type;
@ -49,6 +178,13 @@ struct vertex_selector {
typedef mpl::int_<1> property_distance;
};
/** @brief Get edge property information
*
* This traits struct is used to get property information regarding ClusterGraph edges. It
* allows access to the local descriptor, the mpl property sequence and the position, at which the
* fusion property sequence is stored inside the bundle. It's used to allow generic property
* selection in combination with @ref property_selector
**/
template<typename Graph>
struct edge_selector {
typedef typename boost::graph_traits<Graph>::edge_descriptor key_type;
@ -56,145 +192,421 @@ struct edge_selector {
typedef mpl::int_<0> property_distance;
};
/**
* @brief Select property information trait depending on property type
*
* Allows generic access to property information like descriptor or property sequence by exposing
* a specific selector type ( @ref vertex_selector or @ref edge_selector ) dependend on the supplied
* property.
**/
template< typename Kind, typename Graph>
struct property_selector : public mpl::if_<boost::is_same<Kind, vertex_property>,
struct property_selector : public mpl::if_ < boost::is_same<Kind, vertex_property>,
vertex_selector<Graph>, edge_selector<Graph> >::type {};
/**
* @brief Metafunction to expose the property storage type
**/
template<typename T>
struct property_type {
typedef typename T::type type;
};
/**
* @brief Metafunction to expose which kid of property this is
**/
template<typename T>
struct property_kind {
typedef typename T::kind type;
};
//property vector to a fusion sequence of the propety types
/**
* @brief Metafunction to get all properties for a given kind from a property sequence
**/
template<typename Sequence, typename Kind>
struct properties_by_kind {
typedef typename mpl::fold<Sequence, mpl::vector<>,
mpl::if_<
boost::is_same<Kind, property_kind<mpl::_2> >,
mpl::push_back<mpl::_1, mpl::_2>,
mpl::_1
>
>::type type;
};
/**
* @brief Metafunction to get all properties for a given object from a property sequence. This includes
* the properties with the object types and all general object properties
**/
template<typename Sequence, typename object>
struct properties_by_object {
typedef typename properties_by_kind<Sequence, object>::type object_props;
typedef typename properties_by_kind<Sequence, object_property>::type general_props;
typedef typename mpl::fold< object_props, general_props, mpl::push_back<mpl::_1,mpl::_2> >::type type;
};
/**
* @brief Metafunction to ensures that a property is in a lists
*
* Checks for the existence of a given Property in the mpl::vector supplied and adds the property if it is not found.
* @tparam List mpl::vector with property types
* @tparam Prop the property which should be in the supplied list
**/
template<typename List, typename Prop>
struct ensure_property {
typedef typename mpl::if_ <
boost::is_same <
typename mpl::find<List, Prop>::type,
typename mpl::end<List>::type > ,
typename mpl::push_back<List, Prop>::type,
List >::type type;
};
/**
* @brief Metafunction to ensures that multiple properties are in the lists
*
* Checks for the existence of all Property's given in the mpl::vector supplied and adds the properties if it is not found.
* @tparam List mpl::vector with property types
* @tparam PropList mpl::vector with properties which should be in the supplied list
**/
template<typename List, typename PropList>
struct ensure_properties {
typedef typename mpl::fold < PropList, List,
mpl::if_ <
boost::is_same< mpl::find<mpl::_1, mpl::_2>, mpl::end<mpl::_1> >,
mpl::push_back<mpl::_1, mpl::_2>,
mpl::_1
> >::type type;
};
/**
* @brief Property vector to a fusion sequence of the propety storage types
*
* Properties are passed around as mpl sequences, mostly vectors. To store actual values, they need to
* be transformed into fusion sequences. However, only the storage type needs to be in the vector, not
* the 'kind' information (as this is only used as meta information for type creation). This struct
* exposes a fusion vector which can hold all property storage types.
**/
template<typename T>
struct pts { //property type sequence
typedef typename mpl::transform<T, details::property_type<mpl::_1> >::type ptv;
typedef typename fusion::result_of::as_vector< ptv >::type type;
};
/**
* @brief Type traits to detect if the property has a default value
*
* If the user want to provide a default value for a property than he adds a default_value static function.
* To check if the this function is available we add a type traits which searches for this special function.
*/
BOOST_MPL_HAS_XXX_TRAIT_DEF(default_value)
/**@}*/
/**
* @brief Functor to assign default values to property
*
* This functor holds a pointer to the PropertyOwner in question. The operator() get the properties which
* hold a default value and assigns this value to the property the owner holds.
*/
template<typename PropertyOwner>
struct apply_default {
PropertyOwner* owner;
apply_default(PropertyOwner* o) : owner(o) {};
template<typename T>
void operator()(const T& t) {
owner->template getProperty<T>() = typename T::default_value()();
};
};
}
/** @addtogroup Metafunctions
* @{*/
/**
* @brief Expose if this is a edge property
**/
template<typename T>
struct is_edge_property : boost::is_same<typename T::kind,edge_property> {};
struct is_edge_property : boost::is_same<typename T::kind, edge_property> {};
/**
* @brief Expose if this is a vertex property
**/
template<typename T>
struct is_vertex_property : boost::is_same<typename T::kind,vertex_property> {};
struct is_vertex_property : boost::is_same<typename T::kind, vertex_property> {};
/**
* @brief Expose if this is a cluster property
**/
template<typename T>
struct is_cluster_property : boost::is_same<typename T::kind,cluster_property> {};
struct is_cluster_property : boost::is_same<typename T::kind, cluster_property> {};
/**
* @brief Expose if this is a general object property
**/
template<typename T>
struct is_object_property : boost::is_same<typename T::kind,object_property> {};
struct is_object_property : boost::is_same<typename T::kind, object_property> {};
/**@}*/
/**
* @brief Adapter to use dcm vertex and edge properties as boost property_maps in bgl algorithms
*
* Boost graph algorithms use property maps as generic storage for process data. In most cases the user
* needs to provide these maps. The simplest way is to create them on the stack right before their
* usage. If, however, the stored information is of use and one wants to store it permanently, this way
* is not practical. Therefor vertex and edge properties were introduced, they allow to store arbitrary
* information at their entity. To use this in combination with boost graph algorithms, this class can
* be used to expose vertex and edge properties as propertie maps to the boost algorithms. All process
* information is then stored permanently at the relevant position.
**/
template <typename Property, typename Graph>
class property_map {
public:
//expose boost property map interface types
typedef typename dcm::details::property_selector<typename Property::kind, Graph>::key_type key_type;
typedef typename Property::type value_type;
typedef typename Property::type& reference;
typedef boost::lvalue_property_map_tag category;
//expose cutom types for easy access
typedef Property property;
typedef typename dcm::details::property_selector<typename Property::kind, Graph>::sequence_type sequence;
typedef typename dcm::details::property_selector<typename Property::kind, Graph>::property_distance distance;
/**
* @brief Links property map with the ClusterGraph which shall be accessed
*
* As boost graph algorithms work with local descriptors, the property map needs to know in which
* graph they are valid. this graph has to be passed to the map. Of course this has to be the one
* on which the algorithm is used on
*
* @param g shared ptr of the cluster graph on which the algorithm is used
**/
property_map(boost::shared_ptr<Graph> g)
: m_graph(g) { }
boost::shared_ptr<Graph> m_graph;
};
/**
* @brief Parent class for all property holding classes in the dcm
*
* To ease the work with properties this class is provided. It receives all the properties, which shall be
* handled, in a mpl::vector typelist as its template argument. Than easy access to all properties by get
* and set functions is achieved.
*
**/
template<typename PropertyList>
struct PropertyOwner {
/**
* @brief Constructor assigning default values
*
* It's important to initialise the property fusion sequences with this constructor
* as much handling has to be done to ensure the users default values are added correctly
**/
PropertyOwner();
/**
* @brief Access properties
*
* Returns a reference to the propertys actual value. The property type has to be owned by this class,
* which means it needs to be in the typelist that was given as template parameter to this class.
* @tparam Prop property type which should be accessed
* @return Prop::type& a reference to the properties actual value.
**/
template<typename Prop>
typename Prop::type& getProperty();
/**
* @brief Set properties
*
* Sets the value of a specified property. The property type has to be owned by this class,
* which means it needs to be in the typelist that was given as template parameter to this class.
* Note that setProperty(value) is equivalent to getProperty() = value.
* @tparam Prop property type which should be setProperty
* @param value value of type Prop::type which should be set in this object
**/
template<typename Prop>
void setProperty(typename Prop::type value);
/* It's imortant to not store the properties but their types. These types are
* stored and accessed as fusion vector.
* */
typedef PropertyList PropertySequence;
typedef typename details::pts<PropertyList>::type Properties;
Properties m_properties;
};
template<typename T>
void pretty(T t) {
std::cout<<__PRETTY_FUNCTION__<<std::endl;
};
template<typename PropertyList>
PropertyOwner<PropertyList>::PropertyOwner() {
//get a vies of all types which have a default value
typedef typename mpl::filter_view<PropertyList, details::has_default_value<mpl::_> >::type view;
//set the default value
details::apply_default<PropertyOwner> func(this);
mpl::for_each<view>(func);
#if defined(BOOST_MPL_CFG_NO_HAS_XXX)
throw property_error() << boost::errinfo_errno(301) << error_message("no default values supported");
#endif
};
/**
* @brief Convienience spezialisation to ease interaction with system class
*
* Normaly property lists are retrieved from the system class, however, there are no empty lists. If no
* property is supplied for a PropertyOwner derived class, a mpl::void_ type will be retrieved. To
* remove the burdon of checking for that type in the class definition this spezialisation is supplied.
**/
template<>
struct PropertyOwner<mpl::void_> {
template<typename Prop>
typename Prop::type& getProperty() {
throw property_error() << boost::errinfo_errno(300) << error_message("unknown property type");
};
template<typename Prop>
void setProperty(typename Prop::type value) {
throw property_error() << boost::errinfo_errno(300) << error_message("unknown property type");
};
};
template<typename PropertyList>
template<typename Prop>
typename Prop::type& PropertyOwner<PropertyList>::getProperty() {
typedef typename mpl::find<PropertyList, Prop>::type iterator;
typedef typename mpl::distance<typename mpl::begin<PropertyList>::type, iterator>::type distance;
BOOST_MPL_ASSERT((mpl::not_<boost::is_same<iterator, typename mpl::end<PropertyList>::type > >));
return fusion::at<distance> (m_properties);
};
template<typename PropertyList>
template<typename Prop>
void PropertyOwner<PropertyList>::setProperty(typename Prop::type value) {
typedef typename mpl::find<PropertyList, Prop>::type iterator;
typedef typename mpl::distance<typename mpl::begin<PropertyList>::type, iterator>::type distance;
BOOST_MPL_ASSERT((mpl::not_<boost::is_same<iterator, typename mpl::end<PropertyList>::type > >));
fusion::at<distance> (m_properties) = value;
};
//now create some standart properties
//***********************************
/**
* @brief Dummy property
**/
struct empty_prop {
typedef int kind;
typedef int type;
typedef int kind;
typedef int type;
};
//type of a graph cluster
/**
* @brief Add a type to clusters
*
* Allows to specify special types to ClusterGraphs and make a it possibe to distuingish between
* diffrent purposes. The cluster types need to be int.
**/
struct type_prop {
//states the type of a cluster
typedef cluster_property kind;
typedef int type;
};
//cluster in graph changed?
/**
* @brief Was the cluster changed?
*
* Adds a boolean to the cluster which indicates if the cluster was changedsince the last
* processing. It should be set to true if vertices and edges were added or removed, Subclusters
* created or deleted and so on.
**/
struct changed_prop {
typedef cluster_property kind;
typedef bool type;
};
//vertex index for bgl algorithms
/**
* @brief Add an index to vertices
*
* Most boost graph algorithms need a index for vertices, ranging from 0 to vertex count. As this can
* be useful for many other things it is added as vertex property.
**/
struct vertex_index_prop {
typedef vertex_property kind;
typedef int type;
};
//edge index for bgl algorithms
/**
* @brief Add an index to edges
*
* Most boost graph algorithms need a index for edges, ranging from 0 to edge count. As this can
* be useful for many other things it is added as edge property.
**/
struct edge_index_prop {
typedef edge_property kind;
typedef int type;
};
//vertex color for bgl algorithms
struct vertex_color_prop {
typedef vertex_property kind;
typedef boost::default_color_type type;
};
//edge color for bgl algorithms
struct edge_color_prop {
typedef edge_property kind;
typedef boost::default_color_type type;
};
//object id's
/**
* @brief Add an ID to objects
*
* It may be wanted to add identification markers to objects, this property can be used for that. It
* is special, as it takes its storage type as template parameter. This property can therefore not be
* directly accessed with this struct, the template parameter has to be known.
* @tparam T the identifier type
**/
template<typename T>
struct id_prop {
typedef object_property kind;
typedef T type;
};
/**@}*/ //Property
/**@}*/ //Core
}
template<typename T>
void pretty(T t) {
std::cout<<__PRETTY_FUNCTION__<<std::endl;
};
namespace boost {
//access the propertymap needs to be boost visable
template<typename P, typename G>
typename dcm::property_map<P,G>::value_type get(const dcm::property_map<P,G>& map,
typename dcm::property_map<P,G>::key_type key) {
typename dcm::property_map<P, G>::value_type get(const dcm::property_map<P, G>& map,
typename dcm::property_map<P, G>::key_type key)
{
typedef dcm::property_map<P,G> map_t;
typedef dcm::property_map<P, G> map_t;
typedef typename mpl::find<typename map_t::sequence, typename map_t::property>::type iterator;
typedef typename mpl::distance<typename mpl::begin<typename map_t::sequence>::type, iterator>::type distance;
return fusion::at<distance>(fusion::at<typename dcm::property_map<P,G>::distance>(map.m_graph->operator[](key)));
return fusion::at<distance> (fusion::at<typename dcm::property_map<P, G>::distance> (map.m_graph->operator[](key)));
};
template <typename P, typename G>
void put(const dcm::property_map<P,G>& map,
typename dcm::property_map<P,G>::key_type key,
const typename dcm::property_map<P,G>::value_type& value) {
void put(const dcm::property_map<P, G>& map,
typename dcm::property_map<P, G>::key_type key,
const typename dcm::property_map<P, G>::value_type& value)
{
typedef dcm::property_map<P,G> map_t;
typedef dcm::property_map<P, G> map_t;
typedef typename mpl::find<typename map_t::sequence, typename map_t::property>::type iterator;
typedef typename mpl::distance<typename mpl::begin<typename map_t::sequence>::type, iterator>::type distance;
fusion::at<distance>(fusion::at<typename dcm::property_map<P,G>::distance>(map.m_graph->operator[](key))) = value;
fusion::at<distance> (fusion::at<typename dcm::property_map<P, G>::distance> (map.m_graph->operator[](key))) = value;
};
template <typename P, typename G>
typename dcm::property_map<P,G>::reference at(const dcm::property_map<P,G>& map,
typename dcm::property_map<P,G>::key_type key) {
typedef dcm::property_map<P,G> map_t;
typename dcm::property_map<P, G>::reference at(const dcm::property_map<P, G>& map,
typename dcm::property_map<P, G>::key_type key)
{
typedef dcm::property_map<P, G> map_t;
typedef typename mpl::find<typename map_t::sequence, typename map_t::property>::type iterator;
typedef typename mpl::distance<typename mpl::begin<typename map_t::sequence>::type, iterator>::type distance;
return fusion::at<distance>(fusion::at<typename dcm::property_map<P,G>::distance>(map.m_graph->operator[](key)));
return fusion::at<distance> (fusion::at<typename dcm::property_map<P, G>::distance> (map.m_graph->operator[](key)));
}
}

View File

@ -76,12 +76,6 @@ struct obj_fold : mpl::fold< seq, state,
boost::is_same< details::property_kind<mpl::_2>, obj>, is_object_property<mpl::_2> >,
mpl::push_back<mpl::_1,mpl::_2>, mpl::_1 > > {};
template<typename objects, typename properties>
struct property_map_fold {
typedef typename mpl::fold<
objects, mpl::map<>, mpl::insert< mpl::_1, mpl::pair<
mpl::_2, details::obj_fold<properties, mpl::vector<>, mpl::_2 > > > >::type type;
};
template<typename T>
struct get_identifier {
typedef typename T::Identifier type;
@ -100,6 +94,7 @@ struct EmptyModule {
struct inheriter {};
typedef mpl::vector<> properties;
typedef mpl::vector<> objects;
typedef mpl::vector<> geometries;
typedef Unspecified_Identifier Identifier;
static void system_init(T& sys) {};
@ -153,14 +148,20 @@ public:
typename details::vector_fold<typename Type2::properties,
typename details::vector_fold<typename Type1::properties,
mpl::vector<id_prop<Identifier> > >::type >::type>::type properties;
//get all geometries we support
typedef typename details::vector_fold<typename Type3::geometries,
typename details::vector_fold<typename Type2::geometries,
typename details::vector_fold<typename Type1::geometries,
mpl::vector<> >::type >::type>::type geometries;
//make the subcomponent lists of objects and properties
typedef typename details::edge_fold< properties, mpl::vector<> >::type edge_properties;
typedef typename details::vertex_fold< properties, mpl::vector<> >::type vertex_properties;
typedef typename details::edge_fold< properties,
mpl::vector1<edge_index_prop> >::type edge_properties;
typedef typename details::vertex_fold< properties,
mpl::vector1<vertex_index_prop> >::type vertex_properties;
typedef typename details::cluster_fold< properties,
mpl::vector<changed_prop, type_prop> >::type cluster_properties;
typedef typename details::property_map_fold<objects, properties>::type object_properties;
mpl::vector2<changed_prop, type_prop> >::type cluster_properties;
protected:
//object storage
@ -178,6 +179,11 @@ protected:
vector.clear();
};
};
//we hold our own PropertyOwner which we use for system settings. Don't inherit it as the user
//should not access the settings via the proeprty getter and setter functions.
typedef PropertyOwner<typename details::properties_by_kind<properties, setting_property>::type> SettingOwner;
SettingOwner m_settings;
#ifdef USE_LOGGING
boost::shared_ptr< sink_t > sink;
@ -267,9 +273,19 @@ public:
System* s = new System();
s->m_cluster = m_cluster->createCluster().first;
s->m_storage = m_storage;
s->m_cluster->template setClusterProperty<dcm::type_prop>(details::subcluster);
s->m_cluster->template setProperty<dcm::type_prop>(details::subcluster);
return s;
};
template<typename Setting>
typename Setting::type& getSetting() {
return m_settings.template getProperty<Setting>();
};
template<typename Setting>
void setSetting(typename Setting::type value){
m_settings.template setProperty<Setting>(value);
};
private:
struct cloner {
@ -321,3 +337,10 @@ public:

View File

@ -23,6 +23,7 @@
#include <boost/type_traits.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/void.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/preprocessor/repetition/enum_shifted.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
@ -36,8 +37,8 @@ namespace dcm {
template< typename T >
struct system_traits {
typedef typename T::Kernel Kernel;
typedef typename T::Cluster Cluster;
//typedef typename T::Kernel Kernel;
//typedef typename T::Cluster Cluster;
template<typename M>
struct getModule {
@ -46,7 +47,7 @@ struct system_traits {
typedef typename mpl::if_< boost::is_base_of<M, test1>, test1, typename T::Type3 >::type test2;
typedef typename mpl::if_< boost::is_base_of<M, test2>, test2, mpl::void_ >::type type;
typedef boost::is_same<type, mpl::void_> has_module;
typedef mpl::not_<boost::is_same<type, mpl::void_> > has_module;
};
};

View File

@ -33,6 +33,7 @@
#include "module3d/parallel.hpp"
#include "module3d/angle.hpp"
#include "module3d/coincident.hpp"
#include "module3d/alignment.hpp"
#include "module3d/module.hpp"
#ifdef DCM_USE_MODULESTATE

View File

@ -61,7 +61,7 @@ inline void calcGradFirstComp(const T& d1,
const T& grad) {
typename Kernel::number_type norm = d1.norm()*d2.norm();
const_cast< T& >(grad) = d2/norm - (d1.dot(d2)/std::pow(norm,2))*d1/d1.norm();
const_cast< T& >(grad) = d2/norm - d1.dot(d2)*d1/(std::pow(d1.norm(),3)*d2.norm());
};
template<typename Kernel, typename T>
@ -70,7 +70,7 @@ inline void calcGradSecondComp(const T& d1,
const T& grad) {
typename Kernel::number_type norm = d1.norm()*d2.norm();
const_cast< T& >(grad) = d1/norm - (d1.dot(d2)/std::pow(norm,2))*d2/d2.norm();
const_cast< T& >(grad) = d1/norm - d1.dot(d2)*d2/(std::pow(d2.norm(),3)*d1.norm());
};
}

View File

@ -29,8 +29,6 @@
#include <opendcm/core/kernel.hpp>
#include "defines.hpp"
#include "Base/Console.h"
#define MAXFAKTOR 1.2 //the maximal distance allowd by a point normed to the cluster size
#define MINFAKTOR 0.8 //the minimal distance allowd by a point normed to the cluster size
#define SKALEFAKTOR 1. //the faktor by which the biggest size is multiplied to get the scale value
@ -52,8 +50,8 @@ template<typename Sys>
struct ClusterMath {
public:
typedef typename system_traits<Sys>::Kernel Kernel;
typedef typename system_traits<Sys>::Cluster Cluster;
typedef typename Sys::Kernel Kernel;
typedef typename Sys::Cluster Cluster;
typedef typename system_traits<Sys>::template getModule<m3d>::type module3d;
typedef typename module3d::Geometry3D Geometry3D;
typedef boost::shared_ptr<Geometry3D> Geom;
@ -154,7 +152,7 @@ public:
template<typename Sys>
ClusterMath<Sys>::ClusterMath() : m_normQ(NULL), m_translation(NULL), init(false) {
m_resetTransform = typename Kernel::Quaternion(1,1,1,1);
m_resetTransform = Eigen::AngleAxisd(M_PI*2./3., Eigen::Vector3d(1,1,1).normalized());
m_shift.setZero();
#ifdef USE_LOGGING
@ -453,8 +451,8 @@ void ClusterMath<Sys>::mapClusterDownstreamGeometry(boost::shared_ptr<Cluster> c
BOOST_LOG(log) << "Map downstream geometry";
#endif
map_downstream down(cluster->template getClusterProperty<math_prop>(),
cluster->template getClusterProperty<fix_prop>());
map_downstream down(cluster->template getProperty<math_prop>(),
cluster->template getProperty<fix_prop>());
cluster->template for_each<Geometry3D>(down, true);
//TODO: if one subcluster is fixed the hole cluster should be too, as there are no
// dof's remaining between parts and so nothing can be moved when one part is fixed.

View File

@ -38,7 +38,7 @@ struct ci_orientation : public Equation<ci_orientation, Direction, true> {
struct type : public PseudoScale<Kernel> {
type() {
throw constraint_error() << boost::errinfo_errno(103) << error_message("unsupported geometry in coincidence/alignment orientation constraint")
throw constraint_error() << boost::errinfo_errno(103) << error_message("unsupported geometry in coincidence orientation constraint")
<< error_type_first_geometry(typeid(Tag1).name()) << error_type_second_geometry(typeid(Tag2).name());
};
@ -113,9 +113,6 @@ struct ci_orientation::type< Kernel, tag::line3D, tag::cylinder3D > : public dcm
template< typename Kernel >
struct ci_orientation::type< Kernel, tag::plane3D, tag::plane3D > : public dcm::Orientation::type< Kernel, tag::plane3D, tag::plane3D > {};
template< typename Kernel >
struct ci_orientation::type< Kernel, tag::plane3D, tag::cylinder3D > : public dcm::Orientation::type< Kernel, tag::plane3D, tag::cylinder3D > {};
template< typename Kernel >
struct ci_orientation::type< Kernel, tag::cylinder3D, tag::cylinder3D > : public dcm::Orientation::type< Kernel, tag::cylinder3D, tag::cylinder3D > {};
@ -132,7 +129,7 @@ struct ci_distance : public Equation<ci_distance, double> {
struct type : public PseudoScale<Kernel> {
type() {
throw constraint_error() << boost::errinfo_errno(104) << error_message("unsupported geometry in coincidence/alignment distance constraint")
throw constraint_error() << boost::errinfo_errno(104) << error_message("unsupported geometry in coincidence distance constraint")
<< error_type_first_geometry(typeid(Tag1).name()) << error_type_second_geometry(typeid(Tag2).name());
};
@ -172,22 +169,19 @@ template< typename Kernel >
struct ci_distance::type< Kernel, tag::point3D, tag::plane3D > : public dcm::Distance::type< Kernel, tag::point3D, tag::plane3D > {};
template< typename Kernel >
struct ci_distance::type< Kernel, tag::point3D, tag::cylinder3D > : public dcm::Distance::type< Kernel, tag::point3D, tag::cylinder3D > {};
struct ci_distance::type< Kernel, tag::point3D, tag::cylinder3D > : public dcm::Distance::type< Kernel, tag::point3D, tag::line3D > {};
template< typename Kernel >
struct ci_distance::type< Kernel, tag::line3D, tag::line3D > : public dcm::Distance::type< Kernel, tag::point3D, tag::line3D > {};
template< typename Kernel >
struct ci_distance::type< Kernel, tag::line3D, tag::plane3D > : public dcm::Distance::type< Kernel, tag::point3D, tag::plane3D > {};
struct ci_distance::type< Kernel, tag::line3D, tag::plane3D > : public dcm::Distance::type< Kernel, tag::line3D, tag::plane3D > {};
template< typename Kernel >
struct ci_distance::type< Kernel, tag::line3D, tag::cylinder3D > : public dcm::Distance::type< Kernel, tag::point3D, tag::cylinder3D > {};
struct ci_distance::type< Kernel, tag::line3D, tag::cylinder3D > : public dcm::Distance::type< Kernel, tag::point3D, tag::line3D > {};
template< typename Kernel >
struct ci_distance::type< Kernel, tag::plane3D, tag::plane3D > : public dcm::Distance::type< Kernel, tag::point3D, tag::plane3D > {};
template< typename Kernel >
struct ci_distance::type< Kernel, tag::plane3D, tag::cylinder3D > : public dcm::Distance::type< Kernel, tag::point3D, tag::cylinder3D > {};
struct ci_distance::type< Kernel, tag::plane3D, tag::plane3D > : public dcm::Distance::type< Kernel, tag::plane3D, tag::plane3D > {};
template< typename Kernel >
struct ci_distance::type< Kernel, tag::cylinder3D, tag::cylinder3D > : public dcm::Distance::type< Kernel, tag::point3D, tag::line3D > {};
@ -207,39 +201,8 @@ struct Coincidence : public dcm::constraint_sequence< fusion::vector2< details::
};
};
struct Alignment : public dcm::constraint_sequence< fusion::vector2< details::ci_distance, details::ci_orientation > > {
//allow to set the distance
Alignment& operator()(Direction val) {
fusion::at_c<1>(*this) = val;
return *this;
};
Alignment& operator()(double val) {
fusion::at_c<0>(*this) = val;
return *this;
};
Alignment& operator()(double val1, Direction val2) {
fusion::at_c<0>(*this) = val1;
fusion::at_c<1>(*this) = val2;
return *this;
};
Alignment& operator()(Direction val1, double val2) {
fusion::at_c<0>(*this) = val2;
fusion::at_c<1>(*this) = val1;
return *this;
};
Alignment& operator=(Direction val) {
fusion::at_c<1>(*this) = val;
return *this;
};
Alignment& operator=(double val) {
fusion::at_c<0>(*this) = val;
return *this;
};
};
//no standart equation, create our own object
static Coincidence coincidence;
static Alignment alignment;
}//dcm

View File

@ -20,8 +20,6 @@
#ifndef GCM_DEFINES_3D_H
#define GCM_DEFINES_3D_H
#include <boost/exception/exception.hpp>
namespace dcm {
namespace details {
@ -30,11 +28,6 @@ enum { cluster3D = 100};
struct m3d {}; //base of module3d::type to allow other modules check for it
}
//exception codes are needed by the user
//typedef boost::error_info<struct tag_solver_failure_type,int> solver_failure_type;
struct creation_error : virtual boost::exception {};
}
#endif

View File

@ -411,8 +411,9 @@ struct Distance::type< Kernel, tag::line3D, tag::plane3D > : public Distance::ty
#endif
typedef typename Kernel::VectorMap Vector;
void calculateGradientFirstComplete(Vector& p1, Vector& p2, Vector& g) {
Distance::type< Kernel, tag::point3D, tag::plane3D >::calculateGradientFirstComplete(p1,p2,g);
g.segment(3,3).setZero();
typename Kernel::VectorMap grad(&g(0), 3, typename Kernel::DynStride(1,1));
Distance::type< Kernel, tag::point3D, tag::plane3D >::calculateGradientFirstComplete(p1,p2,grad);
g.segment(3,3).setZero();
};
};
@ -451,7 +452,8 @@ struct Distance::type< Kernel, tag::plane3D, tag::plane3D > : public Distance::t
#endif
typedef typename Kernel::VectorMap Vector;
void calculateGradientFirstComplete(Vector& p1, Vector& p2, Vector& g) {
Distance::type< Kernel, tag::point3D, tag::plane3D >::calculateGradientFirstComplete(p1,p2,g);
typename Kernel::VectorMap grad(&g(0), 3, typename Kernel::DynStride(1,1));
Distance::type< Kernel, tag::point3D, tag::plane3D >::calculateGradientFirstComplete(p1,p2,grad);
g.segment(3,3).setZero();
};
};
@ -488,7 +490,8 @@ struct Distance::type< Kernel, tag::plane3D, tag::cylinder3D > : public Distance
};
void calculateGradientSecondComplete(Vector& p1, Vector& p2, Vector& g) {
Distance::type< Kernel, tag::point3D, tag::plane3D >::calculateGradientFirstComplete(p2,p1,g);
typename Kernel::VectorMap grad(&g(0), 3, typename Kernel::DynStride(1,1));
Distance::type< Kernel, tag::point3D, tag::plane3D >::calculateGradientFirstComplete(p2,p1,grad);
g.segment(3,3).setZero();
g(6) = -1;
};

View File

@ -25,41 +25,13 @@
namespace dcm {
namespace tag {
struct point3D {
typedef mpl::int_<3> parameters;
typedef mpl::int_<1> rotations;
typedef mpl::int_<1> translations;
typedef weight::point weight;
};
struct point3D : details::basic_geometry<weight::point, 3, true, true> {};
struct direction3D : details::basic_geometry<weight::direction, 3, true, false> {};
struct line3D : details::stacked2_geometry<weight::line, point3D, direction3D> {};
struct plane3D : details::stacked2_geometry<weight::plane, point3D, direction3D> {};
struct cylinder3D : details::stacked3_geometry<weight::cylinder, point3D, direction3D, parameter> {};
struct direction3D {
typedef mpl::int_<3> parameters;
typedef mpl::int_<1> rotations;
typedef mpl::int_<0> translations;
typedef weight::direction weight;
};
struct line3D {
typedef mpl::int_<6> parameters;
typedef mpl::int_<2> rotations;
typedef mpl::int_<1> translations;
typedef weight::line weight;
};
struct plane3D {
typedef mpl::int_<6> parameters;
typedef mpl::int_<2> rotations;
typedef mpl::int_<1> translations;
typedef weight::plane weight;
};
struct cylinder3D {
typedef mpl::int_<7> parameters;
typedef mpl::int_<2> rotations;
typedef mpl::int_<1> translations;
typedef weight::cylinder weight;
};
}
} //tag
namespace modell {
@ -155,6 +127,27 @@ namespace modell {
}
//dummy accessor
struct dummy_accessor {
template<typename Scalar, int ID, typename T>
Scalar get(T& t) {
return 1;
};
template<typename Scalar, int ID, typename T>
void set(Scalar value, T& t) {
//TODO: throw
};
};
//dummy geometry traits for boost blank, wil bever be used
template<>
struct geometry_traits<boost::blank> {
typedef tag::direction3D tag;
typedef modell::XYZ modell;
typedef dummy_accessor accessor;
};
}
#endif //GCM_GEOMETRY_3D_H

View File

@ -40,10 +40,10 @@
#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 "opendcm/core/geometry.hpp"
#include "geometry.hpp"
#include "distance.hpp"
#include "parallel.hpp"
@ -52,6 +52,7 @@
#include "defines.hpp"
#include "clustermath.hpp"
namespace mpl = boost::mpl;
namespace dcm {
@ -69,6 +70,8 @@ struct distance {
namespace dcm {
struct reset {}; //signal name
template<typename Typelist, typename ID = No_Identifier>
struct Module3D {
@ -82,25 +85,106 @@ struct Module3D {
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 Typelist geometry_types;
typedef details::MES<Sys> MES;
typedef details::SystemSolver<Sys> SystemSolver;
template<typename Derived>
class Geometry3D_id : public detail::Geometry<Sys, Derived, Typelist, 3> {
class Geometry3D_base : public details::Geometry<typename Sys::Kernel, 3, typename Sys::geometries>,
public Object<Sys, Derived, GeomSig> {
typedef detail::Geometry<Sys, Derived, Typelist, 3> Base;
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) {
return boost::apply_visitor(vis, m_geometry);
};
template<typename T>
T convertTo() {
T t;
(typename geometry_traits<T>::modell()).template inject<typename Kernel::number_type,
typename geometry_traits<T>::accessor >(t, Base::m_global);
return t;
};
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;
struct cloner : boost::static_visitor<void> {
typedef typename boost::make_variant_over< ExtTypeList >::type Variant;
Variant variant;
cloner(Variant& v) : variant(v) {};
template<typename T>
void operator()(T& t) {
variant = geometry_clone_traits<T>()(t);
};
};
//visitor to write the calculated value into the variant
struct apply_visitor : public boost::static_visitor<void> {
apply_visitor(typename Kernel::Vector& v) : value(v) {};
template <typename T>
void operator()(T& t) const {
(typename geometry_traits<T>::modell()).template inject<typename Kernel::number_type,
typename geometry_traits<T>::accessor >(t, value);
}
typename Kernel::Vector& value;
};
Variant m_geometry; //Variant holding the real geometry type
//override protected event functions to emit signals
void reset();
void recalculated();
void removed();
friend class 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);
Geometry3D_id(Sys& system);
template<typename T>
Geometry3D_id(const T& geometry, Sys& system);
@ -115,12 +199,12 @@ struct Module3D {
};
struct Geometry3D : public mpl::if_<boost::is_same<Identifier, No_Identifier>,
detail::Geometry<Sys, Geometry3D, Typelist, 3>, Geometry3D_id<Geometry3D> >::type {
Geometry3D_base<Geometry3D>, Geometry3D_id<Geometry3D> >::type {
typedef vertex_prop vertex_propertie;
Geometry3D(Sys& system);
template<typename T>
Geometry3D(const T& geometry, Sys& system);
@ -129,17 +213,28 @@ struct Module3D {
friend struct details::ClusterMath<Sys>::map_downstream;
friend struct details::SystemSolver<Sys>;
friend struct details::SystemSolver<Sys>::Rescaler;
friend class detail::Constraint<Sys, Constraint3D, ConsSignal, MES, Geometry3D>;
friend class inheriter_base;
public:
//the geometry class itself does not hold an aligned eigen object, but maybe the variant
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
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_id : public detail::Constraint<Sys, Derived, ConsSignal, MES, Geometry3D> {
class Constraint3D_base : public detail::Constraint<Sys, 3>, public Object<Sys, Derived, ConsSignal> {
typedef detail::Constraint<Sys, Derived, ConsSignal, MES, Geometry3D> base;
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);
@ -148,7 +243,7 @@ struct Module3D {
};
struct Constraint3D : public mpl::if_<boost::is_same<Identifier, No_Identifier>,
detail::Constraint<Sys, Constraint3D, ConsSignal, MES, Geometry3D>,
Constraint3D_base<Constraint3D>,
Constraint3D_id<Constraint3D> >::type {
Constraint3D(Sys& system, Geom first, Geom second);
@ -168,15 +263,28 @@ struct Module3D {
T, fusion::vector<T> >::type type;
};
template<typename covec>
struct initalizer : public boost::static_visitor<void> {
Cons constraint;
covec& cov;
initalizer(Cons c, covec& co) : constraint(c), cov(co) {};
template<typename T1, typename T2>
void operator()(const T1& t1, const T2& t2) {
constraint->template initialize< typename geometry_traits<T1>::tag,
typename geometry_traits<T2>::tag, covec>(cov);
};
};
struct set_constraint_option {
template<typename T>
typename boost::enable_if<mpl::is_sequence<T>, typename fusion_vec<T>::type >::type
typename boost::enable_if<mpl::is_sequence<T>, typename fusion_vec<T>::type >::type
operator()(T& val) {
return val;
};
template<typename T>
typename boost::disable_if<mpl::is_sequence<T>, typename fusion_vec<T>::type >::type
typename boost::disable_if<mpl::is_sequence<T>, typename fusion_vec<T>::type >::type
operator()(T& val) {
typename fusion_vec<T>::type vec;
fusion::at_c<0>(vec) = val;
@ -188,6 +296,7 @@ struct Module3D {
template<typename T>
Geom createGeometry3D(T geom);
Geom createGeometry3D();
void removeGeometry3D(Geom g);
template<typename T1>
@ -207,13 +316,14 @@ struct Module3D {
public:
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;
using inheriter_base::removeGeometry3D;
using inheriter_base::removeConstraint3D;
bool hasGeometry3D(Identifier id);
Geom getGeometry3D(Identifier id);
@ -241,7 +351,8 @@ struct Module3D {
};
typedef mpl::vector4<vertex_prop, edge_prop, math_prop, fix_prop> properties;
typedef mpl::vector<Geometry3D, Constraint3D> objects;
typedef mpl::vector2<Geometry3D, Constraint3D> objects;
typedef mpl::vector5<tag::point3D, tag::direction3D, tag::line3D, tag::plane3D, tag::cylinder3D> geometries;
static void system_init(Sys& sys) {
sys.m_sheduler.addProcessJob(new SystemSolver());
@ -298,10 +409,97 @@ typename boost::add_reference<T>::type get(G geom) {
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
Module3D<Typelist, ID>::type<Sys>::Geometry3D_id<Derived>::Geometry3D_id(Sys& system)
: detail::Geometry<Sys, Derived, Typelist, 3>(system)
Module3D<Typelist, ID>::type<Sys>::Geometry3D_base<Derived>::Geometry3D_base(Sys& system)
: Object<Sys, Derived, GeomSig>(system) {
#ifdef USE_LOGGING
, log_id("No ID")
log.add_attribute("Tag", attrs::constant< std::string >("Geometry3D"));
#endif
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
template<typename T>
Module3D<Typelist, ID>::type<Sys>::Geometry3D_base<Derived>::Geometry3D_base(const T& geometry, Sys& system)
: Object<Sys, Derived, GeomSig>(system) {
#ifdef USE_LOGGING
log.add_attribute("Tag", attrs::constant< std::string >("Geometry3D"));
#endif
m_geometry = geometry;
//first init, so that the geometry internal vector has the right size
Base::template init< typename geometry_traits<T>::tag >();
//now write the value;
(typename geometry_traits<T>::modell()).template extract<Scalar,
typename geometry_traits<T>::accessor >(geometry, Base::getValue());
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
template<typename T>
void Module3D<Typelist, ID>::type<Sys>::Geometry3D_base<Derived>::set(const T& geometry) {
m_geometry = geometry;
//first init, so that the geometry internal vector has the right size
Base::template init< typename geometry_traits<T>::tag >();
//now write the value;
(typename geometry_traits<T>::modell()).template extract<Scalar,
typename geometry_traits<T>::accessor >(geometry, Base::getValue());
reset();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
boost::shared_ptr<Derived> Module3D<Typelist, ID>::type<Sys>::Geometry3D_base<Derived>::clone(Sys& newSys) {
//copy the standart stuff
boost::shared_ptr<Derived> np = boost::shared_ptr<Derived>(new Derived(*static_cast<Derived*>(this)));
np->m_system = &newSys;
//it's possible that the variant contains pointers, so we need to clone them
cloner clone_fnc(np->m_geometry);
boost::apply_visitor(clone_fnc, m_geometry);
return np;
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void Module3D<Typelist, ID>::type<Sys>::Geometry3D_base<Derived>::recalculated() {
apply_visitor v(Base::getValue());
apply(v);
ObjBase::template emitSignal<dcm::recalculated>(((Derived*)this)->shared_from_this());
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void Module3D<Typelist, ID>::type<Sys>::Geometry3D_base<Derived>::removed() {
ObjBase::template emitSignal<dcm::remove>(((Derived*)this)->shared_from_this());
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void Module3D<Typelist, ID>::type<Sys>::Geometry3D_base<Derived>::reset() {
ObjBase::template emitSignal<dcm::reset>(((Derived*)this)->shared_from_this());
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
Module3D<Typelist, ID>::type<Sys>::Geometry3D_id<Derived>::Geometry3D_id(Sys& system)
: Module3D<Typelist, ID>::template type<Sys>::template Geometry3D_base<Derived>(system)
#ifdef USE_LOGGING
, log_id("No ID")
#endif
{
@ -315,9 +513,9 @@ template<typename Sys>
template<typename Derived>
template<typename T>
Module3D<Typelist, ID>::type<Sys>::Geometry3D_id<Derived>::Geometry3D_id(const T& geometry, Sys& system)
: detail::Geometry<Sys, Derived, Typelist, 3>(geometry, system)
: Module3D<Typelist, ID>::template type<Sys>::template Geometry3D_base<Derived>(geometry, system)
#ifdef USE_LOGGING
, log_id("No ID")
, log_id("No ID")
#endif
{
@ -368,7 +566,7 @@ template<typename Typelist, typename ID>
template<typename Sys>
Module3D<Typelist, ID>::type<Sys>::Geometry3D::Geometry3D(Sys& system)
: mpl::if_<boost::is_same<Identifier, No_Identifier>,
detail::Geometry<Sys, Geometry3D, Typelist, 3>,
Geometry3D_base<Geometry3D>,
Geometry3D_id<Geometry3D> >::type(system) {
};
@ -378,16 +576,38 @@ template<typename Sys>
template<typename T>
Module3D<Typelist, ID>::type<Sys>::Geometry3D::Geometry3D(const T& geometry, Sys& system)
: mpl::if_<boost::is_same<Identifier, No_Identifier>,
detail::Geometry<Sys, Geometry3D, Typelist, 3>,
Geometry3D_base<Geometry3D>,
Geometry3D_id<Geometry3D> >::type(geometry, system) {
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
boost::shared_ptr<Derived> Module3D<Typelist, ID>::type<Sys>::Constraint3D_base<Derived>::clone(Sys& newSys) {
//copy the standart stuff
boost::shared_ptr<Derived> np = boost::shared_ptr<Derived>(new Derived(*static_cast<Derived*>(this)));
np->m_system = &newSys;
//copy the internals
np->content = CBase::content->clone();
//and get the geometry pointers right
if(CBase::first) {
GlobalVertex v = boost::static_pointer_cast<Geometry3D>(CBase::first)->template getProperty<vertex_prop>();
np->first = newSys.m_cluster->template getObject<Geometry3D>(v);
}
if(CBase::second) {
GlobalVertex v = boost::static_pointer_cast<Geometry3D>(CBase::second)->template getProperty<vertex_prop>();
np->second = newSys.m_cluster->template getObject<Geometry3D>(v);
}
return np;
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
Module3D<Typelist, ID>::type<Sys>::Constraint3D_id<Derived>::Constraint3D_id(Sys& system, Geom f, Geom s)
: detail::Constraint<Sys, Derived, ConsSignal, MES, Geometry3D>(system, f, s) {
: Constraint3D_base<Derived>(system, f, s) {
};
@ -410,7 +630,7 @@ template<typename Typelist, typename ID>
template<typename Sys>
Module3D<Typelist, ID>::type<Sys>::Constraint3D::Constraint3D(Sys& system, Geom first, Geom second)
: mpl::if_<boost::is_same<Identifier, No_Identifier>,
detail::Constraint<Sys, Constraint3D, ConsSignal, MES, Geometry3D>,
Constraint3D_base<Constraint3D>,
Constraint3D_id<Constraint3D> >::type(system, first, second) {
};
@ -421,6 +641,19 @@ Module3D<Typelist, ID>::type<Sys>::inheriter_base::inheriter_base() {
m_this = ((Sys*) this);
};
template<typename Typelist, typename ID>
template<typename Sys>
typename Module3D<Typelist, ID>::template type<Sys>::Geom
Module3D<Typelist, ID>::type<Sys>::inheriter_base::createGeometry3D() {
Geom g(new Geometry3D(* ((Sys*) this)));
fusion::vector<LocalVertex, GlobalVertex> res = m_this->m_cluster->addVertex();
m_this->m_cluster->template setObject<Geometry3D> (fusion::at_c<0> (res), g);
g->template setProperty<vertex_prop>(fusion::at_c<1>(res));
m_this->push_back(g);
return g;
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
@ -466,12 +699,12 @@ Module3D<Typelist, ID>::type<Sys>::inheriter_base::createConstraint3D(Geom first
typedef typename fusion_vec<T1>::type covec;
//set the objects
covec cv = set_constraint_option()( constraint1 );
covec cv = set_constraint_option()(constraint1);
//now create the constraint
Cons c(new Constraint3D(*m_this, first, second));
//set the type and values
c->template initialize<covec>(cv);
//initialize constraint
c->initialize(cv);
//add it to the clustergraph
fusion::vector<LocalEdge, GlobalEdge, bool, bool> res;
@ -518,6 +751,15 @@ Module3D<Typelist, ID>::type<Sys>::inheriter_id::createGeometry3D(T geom, Identi
return g;
};
template<typename Typelist, typename ID>
template<typename Sys>
typename Module3D<Typelist, ID>::template type<Sys>::Geom
Module3D<Typelist, ID>::type<Sys>::inheriter_id::createGeometry3D(Identifier id) {
Geom g = inheriter_base::createGeometry3D();
g->setIdentifier(id);
return g;
};
template<typename Typelist, typename ID>
template<typename Sys>
void Module3D<Typelist, ID>::type<Sys>::inheriter_id::removeGeometry3D(Identifier id) {
@ -549,7 +791,8 @@ void Module3D<Typelist, ID>::type<Sys>::inheriter_id::removeConstraint3D(Identif
template<typename Typelist, typename ID>
template<typename Sys>
bool Module3D<Typelist, ID>::type<Sys>::inheriter_id::hasGeometry3D(Identifier id) {
if(getGeometry3D(id)) return true;
if(getGeometry3D(id))
return true;
return false;
};
@ -560,7 +803,8 @@ Module3D<Typelist, ID>::type<Sys>::inheriter_id::getGeometry3D(Identifier id) {
std::vector< Geom >& vec = inheriter_base::m_this->template objectVector<Geometry3D>();
typedef typename std::vector<Geom>::iterator iter;
for(iter it=vec.begin(); it!=vec.end(); it++) {
if(compare_traits<Identifier>::compare((*it)->getIdentifier(), id)) return *it;
if(compare_traits<Identifier>::compare((*it)->getIdentifier(), id))
return *it;
};
return Geom();
};
@ -568,7 +812,8 @@ Module3D<Typelist, ID>::type<Sys>::inheriter_id::getGeometry3D(Identifier id) {
template<typename Typelist, typename ID>
template<typename Sys>
bool Module3D<Typelist, ID>::type<Sys>::inheriter_id::hasConstraint3D(Identifier id) {
if(getConstraint3D(id)) return true;
if(getConstraint3D(id))
return true;
return false;
};
@ -579,7 +824,8 @@ Module3D<Typelist, ID>::type<Sys>::inheriter_id::getConstraint3D(Identifier id)
std::vector< Cons >& vec = inheriter_base::m_this->template objectVector<Constraint3D>();
typedef typename std::vector<Cons>::iterator iter;
for(iter it=vec.begin(); it!=vec.end(); it++) {
if(compare_traits<Identifier>::compare((*it)->getIdentifier(), id)) return *it;
if(compare_traits<Identifier>::compare((*it)->getIdentifier(), id))
return *it;
};
return Cons();
};

View File

@ -22,6 +22,7 @@
#include "defines.hpp"
#include "clustermath.hpp"
#include "opendcm/core/clustergraph.hpp"
#include "opendcm/core/sheduler.hpp"
#include "opendcm/core/traits.hpp"
#include <opendcm/core/kernel.hpp>
@ -32,17 +33,14 @@
#include <boost/graph/undirected_dfs.hpp>
#include <boost/exception/errinfo_errno.hpp>
#include "Base/Console.h"
#include <boost/graph/graphviz.hpp>
namespace dcm {
namespace details {
template<typename Sys>
struct MES : public system_traits<Sys>::Kernel::MappedEquationSystem {
struct MES : public Sys::Kernel::MappedEquationSystem {
typedef typename system_traits<Sys>::Kernel Kernel;
typedef typename system_traits<Sys>::Cluster Cluster;
typedef typename Sys::Kernel Kernel;
typedef typename Sys::Cluster Cluster;
typedef typename system_traits<Sys>::template getModule<m3d>::type module3d;
typedef typename module3d::Geometry3D Geometry3D;
typedef boost::shared_ptr<Geometry3D> Geom;
@ -51,7 +49,7 @@ struct MES : public system_traits<Sys>::Kernel::MappedEquationSystem {
typedef typename module3d::math_prop math_prop;
typedef typename module3d::fix_prop fix_prop;
typedef typename Kernel::number_type Scalar;
typedef typename system_traits<Sys>::Kernel::MappedEquationSystem base;
typedef typename Sys::Kernel::MappedEquationSystem Base;
boost::shared_ptr<Cluster> m_cluster;
@ -63,8 +61,8 @@ struct MES : public system_traits<Sys>::Kernel::MappedEquationSystem {
template<typename Sys>
struct SystemSolver : public Job<Sys> {
typedef typename system_traits<Sys>::Cluster Cluster;
typedef typename system_traits<Sys>::Kernel Kernel;
typedef typename Sys::Cluster Cluster;
typedef typename Sys::Kernel Kernel;
typedef typename Kernel::number_type Scalar;
typedef typename system_traits<Sys>::template getModule<m3d>::type module3d;
typedef typename module3d::Geometry3D Geometry3D;
@ -127,7 +125,7 @@ struct SystemSolver : public Job<Sys> {
template<typename Sys>
MES<Sys>::MES(boost::shared_ptr<Cluster> cl, int par, int eqn) : base(par, eqn), m_cluster(cl) {
MES<Sys>::MES(boost::shared_ptr<Cluster> cl, int par, int eqn) : Base(par, eqn), m_cluster(cl) {
};
@ -139,8 +137,8 @@ void MES<Sys>::recalculate() {
std::pair<citer, citer> cit = m_cluster->clusters();
for(; cit.first != cit.second; cit.first++) {
if(!(*cit.first).second->template getClusterProperty<fix_prop>())
(*cit.first).second->template getClusterProperty<math_prop>().recalculate();
if(!(*cit.first).second->template getProperty<fix_prop>())
(*cit.first).second->template getProperty<math_prop>().recalculate();
};
@ -154,7 +152,7 @@ void MES<Sys>::recalculate() {
std::pair< oiter, oiter > oit = m_cluster->template getObjects<Constraint3D>(*eit.first);
for(; oit.first != oit.second; oit.first++) {
if(*oit.first)
(*oit.first)->calculate(base::Scaling, base::rot_only);
(*oit.first)->calculate(Base::Scaling, Base::rot_only);
}
}
};
@ -162,7 +160,6 @@ void MES<Sys>::recalculate() {
template<typename Sys>
void MES<Sys>::removeLocalGradientZeros() {
Base::Console().Message("remove local gradient zero\n");
//let the constraints treat the local zeros
typedef typename Cluster::template object_iterator<Constraint3D> oiter;
typedef typename boost::graph_traits<Cluster>::edge_iterator eiter;
@ -178,6 +175,7 @@ void MES<Sys>::removeLocalGradientZeros() {
}
};
template<typename Sys>
SystemSolver<Sys>::Rescaler::Rescaler(boost::shared_ptr<Cluster> c, Mes& m) : cluster(c), mes(m), rescales(0) {
@ -198,11 +196,11 @@ typename SystemSolver<Sys>::Scalar SystemSolver<Sys>::Rescaler::scaleClusters()
Scalar sc = 0;
for(cit = cluster->clusters(); cit.first != cit.second; cit.first++) {
//fixed cluster are irrelevant for scaling
if((*cit.first).second->template getClusterProperty<fix_prop>())
if((*cit.first).second->template getProperty<fix_prop>())
continue;
//get the biggest scale factor
details::ClusterMath<Sys>& math = (*cit.first).second->template getClusterProperty<math_prop>();
details::ClusterMath<Sys>& math = (*cit.first).second->template getProperty<math_prop>();
math.m_pseudo.clear();
collectPseudoPoints(cluster, (*cit.first).first, math.m_pseudo);
@ -219,8 +217,8 @@ typename SystemSolver<Sys>::Scalar SystemSolver<Sys>::Rescaler::scaleClusters()
if(cluster->isCluster(*it.first)) {
boost::shared_ptr<Cluster> c = cluster->getVertexCluster(*it.first);
c->template getClusterProperty<math_prop>().applyClusterScale(sc,
c->template getClusterProperty<fix_prop>());
c->template getProperty<math_prop>().applyClusterScale(sc,
c->template getProperty<fix_prop>());
}
else {
Geom g = cluster->template getObject<Geometry3D>(*it.first);
@ -238,20 +236,20 @@ void SystemSolver<Sys>::Rescaler::collectPseudoPoints(
Eigen::aligned_allocator<typename SystemSolver<Sys>::Kernel::Vector3> >& vec) {
std::vector<typename Kernel::Vector3, Eigen::aligned_allocator<typename Kernel::Vector3> > vec2;
typedef typename Cluster::template object_iterator<Constraint3D> c_iter;
typedef typename Cluster::global_edge_iterator c_iter;
typedef typename boost::graph_traits<Cluster>::out_edge_iterator e_iter;
std::pair<e_iter, e_iter> it = boost::out_edges(cluster, *parent);
for(; it.first != it.second; it.first++) {
std::pair< c_iter, c_iter > cit = parent->template getObjects<Constraint3D>(*it.first);
std::pair< c_iter, c_iter > cit = parent->template getGlobalEdges(*it.first);
for(; cit.first != cit.second; cit.first++) {
Cons c = *(cit.first);
Cons c = parent->template getObject<Constraint3D>(*cit.first);
if(!c)
continue;
//get the first global vertex and see if we have it in the wanted cluster or not
GlobalVertex v = c->first->template getProperty<vertex_prop>();
GlobalVertex v = cit.first->source;
std::pair<LocalVertex,bool> res = parent->getLocalVertex(v);
if(!res.second)
return; //means the geometry is in non of the clusters which is not allowed
@ -287,8 +285,8 @@ void SystemSolver<Sys>::solveCluster(boost::shared_ptr<Cluster> cluster, Sys& sy
for(; cit.first != cit.second; cit.first++) {
boost::shared_ptr<Cluster> c = (*cit.first).second;
if(c->template getClusterProperty<changed_prop>() &&
c->template getClusterProperty<type_prop>() == details::cluster3D)
if(c->template getProperty<changed_prop>() &&
c->template getProperty<type_prop>() == details::cluster3D)
solveCluster(c, sys);
}
@ -338,9 +336,9 @@ void SystemSolver<Sys>::solveCluster(boost::shared_ptr<Cluster> cluster, Sys& sy
if(cluster->isCluster(*it.first)) {
boost::shared_ptr<Cluster> c = cluster->getVertexCluster(*it.first);
details::ClusterMath<Sys>& cm = c->template getClusterProperty<math_prop>();
details::ClusterMath<Sys>& cm = c->template getProperty<math_prop>();
//only get maps and propagate downstream if not fixed
if(!c->template getClusterProperty<fix_prop>()) {
if(!c->template getProperty<fix_prop>()) {
//set norm Quaternion as map to the parameter vector
int offset_rot = mes.setParameterMap(cm.getNormQuaternionMap(), rotation);
//set translation as map to the parameter vector
@ -363,10 +361,7 @@ void SystemSolver<Sys>::solveCluster(boost::shared_ptr<Cluster> cluster, Sys& sy
}
else {
Geom g = cluster->template getObject<Geometry3D>(*it.first);
int offset = mes.setParameterMap(g->m_parameterCount, g->getParameterMap());
g->m_offset = offset;
//init the parametermap with initial values
g->initMap();
g->initMap(&mes);
}
}
@ -404,12 +399,17 @@ void SystemSolver<Sys>::solveCluster(boost::shared_ptr<Cluster> cluster, Sys& sy
// always need the full solver power
bool has_cycle;
cycle_dedector cd(has_cycle);
//create te needed property map, fill it and run the test
//create te needed property maps and fill it
property_map<vertex_index_prop, Cluster> vi_map(cluster);
property_map<vertex_color_prop, Cluster> vc_map(cluster);
property_map<edge_color_prop, Cluster> ec_map(cluster);
cluster->initIndexMaps();
boost::undirected_dfs(*cluster.get(), boost::visitor(cd).vertex_index_map(vi_map).vertex_color_map(vc_map).edge_color_map(ec_map));
typedef std::map< LocalVertex, boost::default_color_type> vcmap;
typedef std::map< LocalEdge, boost::default_color_type> ecmap;
vcmap v_cm;
ecmap e_cm;
boost::associative_property_map< vcmap > v_cpm(v_cm);
boost::associative_property_map< ecmap > e_cpm(e_cm);
boost::undirected_dfs(*cluster.get(), boost::visitor(cd).vertex_index_map(vi_map).vertex_color_map(v_cpm).edge_color_map(e_cpm));
bool done = false;
if(!has_cycle) {
@ -419,7 +419,7 @@ void SystemSolver<Sys>::solveCluster(boost::shared_ptr<Cluster> cluster, Sys& sy
//cool, lets do uncylic. first all rotational constraints with rotational parameters
mes.setAccess(rotation);
mes.setGeneralEquationAccess(false);
//solve can be done without catching exceptions, because this only fails if the system is
//solve can be done without catching exceptions, because this only fails if the system in
//unsolvable
DummyScaler re;
Kernel::solve(mes, re);
@ -465,11 +465,11 @@ void SystemSolver<Sys>::solveCluster(boost::shared_ptr<Cluster> cluster, Sys& sy
if(cluster->isCluster(*it.first)) {
boost::shared_ptr<Cluster> c = cluster->getVertexCluster(*it.first);
if(!cluster->template getSubclusterProperty<fix_prop>(*it.first))
c->template getClusterProperty<math_prop>().finishCalculation();
c->template getProperty<math_prop>().finishCalculation();
else
c->template getClusterProperty<math_prop>().finishFixCalculation();
c->template getProperty<math_prop>().finishFixCalculation();
std::vector<Geom>& vec = c->template getClusterProperty<math_prop>().getGeometry();
std::vector<Geom>& vec = c->template getProperty<math_prop>().getGeometry();
for(typename std::vector<Geom>::iterator vit = vec.begin(); vit != vec.end(); vit++)
(*vit)->finishCalculation();
@ -481,7 +481,7 @@ void SystemSolver<Sys>::solveCluster(boost::shared_ptr<Cluster> cluster, Sys& sy
}
}
//we have solved this cluster
cluster->template setClusterProperty<changed_prop>(false);
cluster->template setProperty<changed_prop>(false);
}
catch(boost::exception&) {

View File

@ -70,8 +70,8 @@ struct ModulePart {
typedef typename boost::make_variant_over< Typelist >::type Variant;
typedef Object<Sys, Part, PartSignal> base;
typedef typename system_traits<Sys>::Kernel Kernel;
typedef typename system_traits<Sys>::Cluster Cluster;
typedef typename Sys::Kernel Kernel;
typedef typename Sys::Cluster Cluster;
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::Transform3D Transform;
@ -117,12 +117,9 @@ struct ModulePart {
template<typename T>
void set(const T& geometry);
//access the parts transformation
template<typename T>
T& get();
//get the transformation from part local to overall global. In multi layer systems
//this means the successive transformation from this part to the toplevel cluster
template<typename T>
T getGlobal();
@ -187,7 +184,7 @@ struct ModulePart {
void setTransformation(const T& geom) {
typedef typename system_traits<Sys>::template getModule<details::m3d>::type module3d;
details::ClusterMath<Sys>& cm = ((Sys*)this)->m_cluster->template getClusterProperty<typename module3d::math_prop>();
details::ClusterMath<Sys>& cm = ((Sys*)this)->m_cluster->template getProperty<typename module3d::math_prop>();
(typename geometry_traits<T>::modell()).template extract<typename Sys::Kernel,
typename geometry_traits<T>::accessor >(geom, cm.getTransform());
@ -204,7 +201,7 @@ struct ModulePart {
void getTransformation(T& geom) {
typedef typename system_traits<Sys>::template getModule<details::m3d>::type module3d;
details::ClusterMath<Sys>& cm = ((Sys*)this)->m_cluster->template getClusterProperty<typename module3d::math_prop>();
details::ClusterMath<Sys>& cm = ((Sys*)this)->m_cluster->template getProperty<typename module3d::math_prop>();
(typename geometry_traits<T>::modell()).template inject<typename Sys::Kernel,
typename geometry_traits<T>::accessor >(geom, cm.getTransform());
@ -215,7 +212,7 @@ struct ModulePart {
//function object to emit remove signal too al geometry which is deleted by part deletion
struct remover {
typedef typename system_traits<Sys>::Cluster Cluster;
typedef typename Sys::Cluster Cluster;
typedef typename system_traits<Sys>::template getModule<details::m3d>::type module3d;
typedef typename module3d::Geometry3D Geometry3D;
typedef boost::shared_ptr<Geometry3D> Geom;
@ -244,11 +241,12 @@ struct ModulePart {
typedef mpl::vector0<> properties;
typedef mpl::vector1<Part> objects;
typedef mpl::vector0<> geometries;
struct PrepareCluster : public Job<Sys> {
typedef typename system_traits<Sys>::Cluster Cluster;
typedef typename system_traits<Sys>::Kernel Kernel;
typedef typename Sys::Cluster Cluster;
typedef typename Sys::Kernel Kernel;
typedef typename system_traits<Sys>::template getModule<details::m3d>::type module3d;
PrepareCluster();
@ -257,8 +255,8 @@ struct ModulePart {
struct EvaljuateCluster : public Job<Sys> {
typedef typename system_traits<Sys>::Cluster Cluster;
typedef typename system_traits<Sys>::Kernel Kernel;
typedef typename Sys::Cluster Cluster;
typedef typename Sys::Kernel Kernel;
typedef typename system_traits<Sys>::template getModule<details::m3d>::type module3d;
EvaljuateCluster();
@ -286,10 +284,10 @@ ModulePart<Typelist, ID>::type<Sys>::Part_base::Part_base(const T& geometry, Sys
(typename geometry_traits<T>::modell()).template extract<Kernel,
typename geometry_traits<T>::accessor >(geometry, m_transform);
cluster->template setClusterProperty<typename module3d::fix_prop>(false);
cluster->template setProperty<typename module3d::fix_prop>(false);
//the the clustermath transform
m_cluster->template getClusterProperty<typename module3d::math_prop>().getTransform() = m_transform;
m_cluster->template getProperty<typename module3d::math_prop>().getTransform() = m_transform;
#ifdef USE_LOGGING
BOOST_LOG(log) << "Init: "<<m_transform;
@ -309,10 +307,9 @@ template<typename T>
typename ModulePart<Typelist, ID>::template type<Sys>::Part_base::Geom
ModulePart<Typelist, ID>::type<Sys>::Part_base::addGeometry3D(const T& geom, CoordinateFrame frame) {
Geom g(new Geometry3D(geom, *m_system));
if(frame == Local) {
//we need to collect all transforms up to this part!
Transform t;
Transform t;//(m_transform);
transform_traverse(t, m_cluster);
g->transform(t);
@ -328,10 +325,10 @@ ModulePart<Typelist, ID>::type<Sys>::Part_base::addGeometry3D(const T& geom, Coo
template<typename Typelist, typename ID>
template<typename Sys>
void ModulePart<Typelist, ID>::type<Sys>::Part_base::transform_traverse(typename ModulePart<Typelist, ID>::template type<Sys>::Part_base::Transform& t,
boost::shared_ptr<typename ModulePart<Typelist, ID>::template type<Sys>::Part_base::Cluster> c) {
void ModulePart<Typelist, ID>::type<Sys>::Part_base::transform_traverse(ModulePart<Typelist, ID>::type<Sys>::Part_base::Transform& t,
boost::shared_ptr<ModulePart<Typelist, ID>::type<Sys>::Part_base::Cluster> c) {
t *= c->template getClusterProperty<typename Part_base::module3d::math_prop>().m_transform;
t *= c->template getProperty<typename Part_base::module3d::math_prop>().m_transform;
if(c->isRoot())
return;
@ -349,6 +346,7 @@ void ModulePart<Typelist, ID>::type<Sys>::Part_base::set(const T& geometry) {
//set the clustermath transform
m_cluster->template getClusterProperty<typename module3d::math_prop>().getTransform() = m_transform;
};
template<typename Typelist, typename ID>
@ -419,7 +417,7 @@ void ModulePart<Typelist, ID>::type<Sys>::Part_base::finishCalculation() {
template<typename Typelist, typename ID>
template<typename Sys>
void ModulePart<Typelist, ID>::type<Sys>::Part_base::fix(bool fix_value) {
m_cluster->template setClusterProperty<typename module3d::fix_prop>(fix_value);
m_cluster->template setProperty<typename module3d::fix_prop>(fix_value);
};
template<typename Typelist, typename ID>
@ -502,14 +500,14 @@ template<typename T>
typename ModulePart<Typelist, ID>::template type<Sys>::Partptr
ModulePart<Typelist, ID>::type<Sys>::inheriter_base::createPart(const T& geometry) {
typedef typename system_traits<Sys>::Cluster Cluster;
typedef typename Sys::Cluster Cluster;
std::pair<boost::shared_ptr<Cluster>, LocalVertex> res = m_this->m_cluster->createCluster();
Partptr p(new Part(geometry, * ((Sys*) this), res.first));
m_this->m_cluster->template setObject<Part> (res.second, p);
m_this->push_back(p);
res.first->template setClusterProperty<type_prop>(clusterPart);
res.first->template setProperty<type_prop>(clusterPart);
return p;
};
@ -598,7 +596,7 @@ void ModulePart<Typelist, ID>::type<Sys>::PrepareCluster::execute(Sys& sys) {
typedef typename std::vector<Partptr>::iterator iter;
for(iter it = sys.template begin<Part>(); it != sys.template end<Part>(); it++) {
details::ClusterMath<Sys>& cm = (*it)->m_cluster->template getClusterProperty<typename module3d::math_prop>();
details::ClusterMath<Sys>& cm = (*it)->m_cluster->template getProperty<typename module3d::math_prop>();
cm.getTransform() = (*it)->m_transform;
};
};
@ -616,7 +614,7 @@ void ModulePart<Typelist, ID>::type<Sys>::EvaljuateCluster::execute(Sys& sys) {
typedef typename std::vector<Partptr>::iterator iter;
for(iter it = sys.template begin<Part>(); it != sys.template end<Part>(); it++) {
details::ClusterMath<Sys>& cm = (*it)->m_cluster->template getClusterProperty<typename module3d::math_prop>();
details::ClusterMath<Sys>& cm = (*it)->m_cluster->template getProperty<typename module3d::math_prop>();
(*it)->m_transform = cm.getTransform();
(*it)->finishCalculation();
};
@ -629,5 +627,3 @@ void ModulePart<Typelist, ID>::type<Sys>::EvaljuateCluster::execute(Sys& sys) {

View File

@ -81,7 +81,7 @@ struct Injector {
void setClusterProperties(typename Sys::Cluster* cluster,
typename details::pts<typename Sys::Cluster::cluster_properties>::type& prop) {
cluster->m_cluster_bundle = prop;
cluster->m_properties = prop;
};
void setVertexProperties(typename Sys::Cluster* cluster, LocalVertex v,
typename details::pts<typename Sys::vertex_properties>::type& prop) {
@ -101,13 +101,13 @@ struct Injector {
fusion::at_c<1>(cluster->operator[](e)) = bundles;
};
void setVertexProperty(typename Sys::Cluster* cluster, int value) {
cluster->template setClusterProperty<details::cluster_vertex_prop>(value);
cluster->template setProperty<details::cluster_vertex_prop>(value);
};
void addClusters(std::vector<typename Sys::Cluster*>& clusters, typename Sys::Cluster* cluster) {
typename std::vector<typename Sys::Cluster*>::iterator it;
for(it = clusters.begin(); it != clusters.end(); it++) {
LocalVertex v = cluster->getLocalVertex((*it)->template getClusterProperty<details::cluster_vertex_prop>()).first;
LocalVertex v = cluster->getLocalVertex((*it)->template getProperty<details::cluster_vertex_prop>()).first;
cluster->m_clusters[v] = boost::shared_ptr<typename Sys::Cluster>(*it);
};
};

View File

@ -56,7 +56,7 @@ template<typename Sys>
struct generator : karma::grammar<Iterator, typename Sys::Cluster& ()> {
typedef typename Sys::Cluster graph;
typedef typename graph::cluster_bundle graph_bundle;
typedef typename graph::Properties graph_bundle;
typedef typename boost::graph_traits<graph>::vertex_iterator viter;
typedef typename boost::graph_traits<graph>::edge_iterator eiter;

View File

@ -32,7 +32,7 @@ BOOST_FUSION_ADAPT_TPL_STRUCT(
(T1)(T2)(T3)(T4),
(dcm::ClusterGraph) (T1)(T2)(T3)(T4),
(int, test)
(typename dcm::details::pts<T3>::type, m_cluster_bundle))
(typename dcm::details::pts<T3>::type, m_properties))
namespace boost { namespace spirit { namespace traits

View File

@ -21,10 +21,10 @@ namespace details {
struct obj_grammar : public karma::grammar<Iterator, boost::shared_ptr<Object>()> {
typename Gen::generator subrule;
karma::rule<Iterator, boost::shared_ptr<Object>()> start;
details::prop_gen<Sys, typename Object::Sequence > prop;
details::prop_gen<Sys, typename Object::PropertySequence > prop;
obj_grammar();
static void getProperties(boost::shared_ptr<Object> ptr, typename details::pts<typename Object::Sequence>::type& seq);
static void getProperties(boost::shared_ptr<Object> ptr, typename details::pts<typename Object::PropertySequence>::type& seq);
};
//when objects should not be generated we need to get a empy rule, as obj_rule_init

View File

@ -29,7 +29,7 @@ obj_grammar<Sys, Object,Gen>::obj_grammar() : obj_grammar<Sys, Object,Gen>::base
};
template<typename Sys, typename Object, typename Gen>
void obj_grammar<Sys, Object,Gen>::getProperties(boost::shared_ptr<Object> ptr, typename details::pts<typename Object::Sequence>::type& seq) {
void obj_grammar<Sys, Object,Gen>::getProperties(boost::shared_ptr<Object> ptr, typename details::pts<typename Object::PropertySequence>::type& seq) {
if(ptr) seq = ptr->m_properties;
else {

View File

@ -34,11 +34,11 @@ template<typename Sys, typename ObjList, typename Object, typename Par>
struct obj_parser : public qi::grammar<IIterator, qi::unused_type(typename details::sps<ObjList>::type*, Sys*), qi::space_type> {
typename Par::parser subrule;
qi::rule<IIterator, qi::unused_type(typename details::sps<ObjList>::type*, Sys*), qi::space_type> start;
prop_par<Sys, typename Object::Sequence > prop;
prop_par<Sys, typename Object::PropertySequence > prop;
obj_parser();
static void setProperties(boost::shared_ptr<Object> ptr, typename details::pts<typename Object::Sequence>::type& seq);
static void setProperties(boost::shared_ptr<Object> ptr, typename details::pts<typename Object::PropertySequence>::type& seq);
};
//when objects should not be generated we need to get a empy rule, as obj_rule_init

View File

@ -57,7 +57,7 @@ obj_parser<Sys, ObjList, Object, Par>::obj_parser(): obj_parser::base_type(start
};
template<typename Sys, typename ObjList, typename Object, typename Par>
void obj_parser<Sys, ObjList, Object, Par>::setProperties(boost::shared_ptr<Object> ptr, typename details::pts<typename Object::Sequence>::type& seq) {
void obj_parser<Sys, ObjList, Object, Par>::setProperties(boost::shared_ptr<Object> ptr, typename details::pts<typename Object::PropertySequence>::type& seq) {
if(ptr) ptr->m_properties = seq;
};

View File

@ -31,7 +31,7 @@
BOOST_FUSION_ADAPT_TPL_STRUCT(
(T1)(T2)(T3)(T4),
(dcm::ClusterGraph) (T1)(T2)(T3)(T4),
(typename dcm::details::pts<T3>::type, m_cluster_bundle))
(typename dcm::details::pts<T3>::type, m_properties))
#include "parser.hpp"

View File

@ -59,7 +59,7 @@ struct prop_parser_fold : mpl::fold< seq, state,
mpl::push_back<mpl::_1, prop_parser<seq, mpl::_2, dcm::parser_parser<mpl::_2, Sys, IIterator> > >,
mpl::_1 > > {};
//grammar for a fusion sequence of properties. currently max. 10 properties are supported
//grammar for a fusion sequence of properties.
template<typename Sys, typename PropertyList>
struct prop_par : qi::grammar<IIterator, typename details::pts<PropertyList>::type(), qi::space_type> {