updated dcm version
This commit is contained in:
parent
913ec86fdd
commit
6c494157f5
|
@ -1 +1,3 @@
|
|||
/usr/include/eigen3
|
||||
/home/stefan/Projects/openDCM/opendcm/
|
||||
/home/stefan/Projects/openDCM/
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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&) {
|
||||
|
|
|
@ -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) {
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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> {
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user