enable scaling

This commit is contained in:
Stefan Tröger 2013-06-08 16:17:05 +02:00 committed by Stefan Tröger
parent 401c4d6dc0
commit 3058d86b23
30 changed files with 819 additions and 206 deletions

View File

@ -4,6 +4,8 @@ else(MSVC)
add_definitions(-DHAVE_LIMITS_H -DHAVE_CONFIG_H)
endif(MSVC)
add_definitions( -DUSE_LOGGING )
include_directories(
${CMAKE_SOURCE_DIR}/src
${CMAKE_BINARY_DIR}/src
@ -86,9 +88,15 @@ SET(Assembly_SRCS
${Module_SRCS}
)
set(log_LIB boost_log
rt
${Boost_SYSTEM_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
)
add_library(Assembly SHARED ${Assembly_SRCS})
target_link_libraries(Assembly ${Assembly_LIBS})
target_link_libraries(Assembly ${Assembly_LIBS} ${log_LIB})
fc_target_copy_resource(Assembly

View File

@ -57,7 +57,6 @@ public:
virtual TopoDS_Shape getShape(void) const;
//the toplevel assembly is the direct parent of the part
bool isParentAssembly(ItemPart* part);
ItemAssembly* getParentAssembly(ItemPart* part);

View File

@ -328,9 +328,14 @@ public:
bool operator!=(const T& other) const {
return !(this == &other);
};
void setCopyMode(bool on) {
copy_mode = on;
};
void setChanged() {
setClusterProperty<changed_prop>(true);
if(!copy_mode)
setClusterProperty<changed_prop>(true);
};
/* *******************************************************
@ -345,7 +350,7 @@ public:
};
template<typename P>
typename P::type& getSubclusterProperty(LocalVertex v) {
return getVertexCluster(v)->getClusterProperty<P>();
return getVertexCluster(v)->template getClusterProperty<P>();
};
template<typename P>
@ -804,6 +809,7 @@ private:
void simpleRemoveEdge(LocalEdge e) {
boost::remove_edge(e, *this);
};
public:
/**
@ -1041,7 +1047,7 @@ public:
cluster_iterator cit;
for(cit=m_clusters.begin(); cit != m_clusters.end(); cit++) {
f((*cit).second);
(*cit).second->for_each<Obj>(f, recursive);
(*cit).second->template for_each<Obj>(f, recursive);
}
}
};
@ -1383,6 +1389,7 @@ public:
protected:
boost::weak_ptr<ClusterGraph> m_parent;
details::IDpointer m_id;
bool copy_mode; //no changing itself when copying
/* Searches the global vertex in all local vertices of this graph, and returns the local
@ -1485,7 +1492,7 @@ protected:
//TODO: Throw (propeties return reference, but cant init a reference temporarily)
}
return fusion::at_c<1>(res)->apply_to_bundle<functor>(k, f);
return fusion::at_c<1>(res)->template apply_to_bundle<functor>(k, f);
};
template<typename functor>

View File

@ -33,7 +33,9 @@
#include <boost/mpl/less.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/any.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/fusion/include/mpl.hpp>
@ -69,12 +71,15 @@ public:
~Constraint();
virtual boost::shared_ptr<Derived> clone(Sys& newSys);
protected:
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 ConstraintVector>
void initialize(ConstraintVector& obj);
protected:
int equationCount();
template< typename creator_type>
@ -91,7 +96,7 @@ protected:
};
void collectPseudoPoints(Vec& vec1, Vec& vec2);
//Equation is the constraint with types, the EquationSet hold all needed Maps for calculation
template<typename Equation>
struct EquationSet {
@ -114,6 +119,12 @@ protected:
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 placeholder* clone() = 0;
//some runtime type infos are needed, as we cant access the contents with arbitrary functors
virtual std::vector<boost::any> getGenericEquations() = 0;
virtual std::vector<boost::any> getGenericConstraints() = 0;
virtual std::vector<const std::type_info*> getEquationTypes() = 0;
virtual std::vector<const std::type_info*> getConstraintTypes() = 0;
};
public:
@ -187,18 +198,49 @@ public:
void operator()(T& val) const;
};
holder(Objects& obj);
struct GenericEquations {
std::vector<boost::any>& vec;
GenericEquations(std::vector<boost::any>& v);
template<typename T>
void operator()(T& val) const;
};
struct GenericConstraints {
std::vector<boost::any>& vec;
GenericConstraints(std::vector<boost::any>& v);
template<typename T>
void operator()(T& val) const;
};
struct Types {
std::vector<const std::type_info*>& vec;
Types(std::vector<const std::type_info*>& v);
template<typename T>
void operator()(T& val) const;
};
holder(Objects& obj);
virtual void calculate(geom_ptr first, geom_ptr second, Scalar scale);
virtual placeholder* resetConstraint(geom_ptr first, geom_ptr second) const;
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() {
virtual int equationCount() {
return mpl::size<EquationVector>::value;
};
virtual std::vector<boost::any> getGenericEquations();
virtual std::vector<boost::any> getGenericConstraints();
virtual std::vector<const std::type_info*> getEquationTypes();
virtual std::vector<const std::type_info*> getConstraintTypes();
EquationSets m_sets;
Objects m_objects;
};
protected:
@ -217,14 +259,15 @@ protected:
template<typename T1, typename T2>
void operator()(const T1&, const T2&);
placeholder* p;
bool need_swap;
};
placeholder* content;
geom_ptr first, second;
Connection cf, cs;
public:
geom_ptr first, second;
};
@ -252,7 +295,7 @@ Constraint<Sys, Derived, Signals, MES, Geometry>::~Constraint() {
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
boost::shared_ptr<Derived> Constraint<Sys, Derived, Signals, MES, Geometry>::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;
@ -313,6 +356,26 @@ void Constraint<Sys, Derived, Signals, MES, Geometry>::collectPseudoPoints(Vec&
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() {
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() {
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() {
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() {
return content->getConstraintTypes();
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename ConstraintVector, typename EquationVector>
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::OptionSetter::OptionSetter(Objects& val) : objects(val) {};
@ -440,9 +503,52 @@ void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector,
}
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename ConstraintVector, typename EquationVector>
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::holder(Objects& obj) {
Constraint<Sys, Derived, Signals, MES, Geometry>::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 ConstraintVector, typename EquationVector>
template< typename T >
void Constraint<Sys, Derived, Signals, MES, Geometry>::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 ConstraintVector, typename EquationVector>
Constraint<Sys, Derived, Signals, MES, Geometry>::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 ConstraintVector, typename EquationVector>
template< typename T >
void Constraint<Sys, Derived, Signals, MES, Geometry>::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 ConstraintVector, typename EquationVector>
Constraint<Sys, Derived, Signals, MES, Geometry>::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 ConstraintVector, typename EquationVector>
template< typename T >
void Constraint<Sys, Derived, Signals, MES, Geometry>::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 ConstraintVector, typename EquationVector>
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::holder(Objects& obj) : m_objects(obj) {
//set the initial values in the equations
fusion::for_each(m_sets, OptionSetter(obj));
};
@ -455,7 +561,7 @@ void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector,
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename ConstraintVector, typename EquationVector>
typename Constraint<Sys, Derived, Signals, MES, Geometry>::placeholder*
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 {
//boost::apply_visitor(creator, first->m_geometry, second->m_geometry);
//if(creator.need_swap) first.swap(second);
@ -476,22 +582,58 @@ void Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector,
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename ConstraintVector, typename EquationVector>
typename Constraint<Sys, Derived, Signals, MES, Geometry>::placeholder*
typename Constraint<Sys, Derived, Signals, MES, Geometry>::placeholder*
Constraint<Sys, Derived, Signals, MES, Geometry>::holder<ConstraintVector, EquationVector>::clone() {
return new holder(*this);
};
template<typename Sys, typename Derived, typename Signals, typename MES, typename Geometry>
template<typename ConstraintVector, typename EquationVector>
std::vector<boost::any>
Constraint<Sys, Derived, Signals, MES, Geometry>::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 ConstraintVector, typename EquationVector>
std::vector<boost::any>
Constraint<Sys, Derived, Signals, MES, Geometry>::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 ConstraintVector, typename EquationVector>
std::vector<const std::type_info*>
Constraint<Sys, Derived, Signals, MES, Geometry>::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 ConstraintVector, typename EquationVector>
std::vector<const std::type_info*>
Constraint<Sys, Derived, Signals, MES, Geometry>::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) {
};
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&) {
typedef tag_order< typename geometry_traits<T1>::tag, typename geometry_traits<T2>::tag > order;
//transform the constraints into eqautions with the now known types

View File

@ -167,6 +167,8 @@ protected:
public:
typedef mpl::int_<Dim> Dimension;
Geometry(Sys& system);
template<typename T>
Geometry(const T& geometry, Sys& system);
@ -277,6 +279,17 @@ public:
/*****************************************************************************************************************/
/*****************************************************************************************************************/
template< typename Sys, typename Derived, typename GeometrieTypeList, int Dim>
Geometry<Sys, Derived, GeometrieTypeList, Dim>::Geometry(Sys& system)
: 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"));
#endif
this->m_system = &system;
};
template< typename Sys, typename Derived, typename GeometrieTypeList, int Dim>
template<typename T>

View File

@ -34,5 +34,9 @@
#include "module3d/coincident.hpp"
#include "module3d/module.hpp"
#ifdef DCM_USE_MODULESTATE
#include "module3d/state.hpp"
#endif
#endif //DCM_MODULE3D_H

View File

@ -273,7 +273,7 @@ struct Distance::type< Kernel, tag::line3D, tag::line3D > {
typedef typename Kernel::Vector3 Vector3;
typedef std::vector<typename Kernel::Vector3, Eigen::aligned_allocator<typename Kernel::Vector3> > Vec;
Scalar value, sc_value, cdn;
Scalar value, sc_value, cdn, nxn_n;
Vector3 c, n1, n2, nxn;
#ifdef USE_LOGGING
@ -314,6 +314,7 @@ struct Distance::type< Kernel, tag::line3D, tag::line3D > {
n1 = line1.template segment<3>(3);
n2 = line2.template segment<3>(3);
nxn = n1.cross(n2);
nxn_n = nxn.norm();
c = line2.template head<3>() - line1.template head<3>();
cdn = c.dot(nxn);
const Scalar res = std::abs(cdn) / nxn.norm();
@ -325,17 +326,17 @@ struct Distance::type< Kernel, tag::line3D, tag::line3D > {
};
Scalar calculateGradientFirst(Vector& line1, Vector& line2, Vector& dline1) {
if(nxn.norm() == 0)
if(nxn_n == 0)
return 1.;
const Vector3 nxn_diff = dline1.template segment<3>(3).cross(n2);
Scalar diff = (-dline1.template head<3>().dot(nxn)+c.dot(nxn_diff))*nxn.norm();
diff -= c.dot(nxn)*nxn.dot(nxn_diff)/nxn.norm();
Scalar diff = (-dline1.template head<3>().dot(nxn)+c.dot(nxn_diff))*nxn_n;
diff -= c.dot(nxn)*nxn.dot(nxn_diff)/nxn_n;
//absoulute value requires diffrent differentation for diffrent results
if(cdn <= 0) diff *= -1;
diff /= std::pow(nxn.norm(),2);
diff /= std::pow(nxn_n,2);
#ifdef USE_LOGGING
if(!boost::math::isfinite(diff))
@ -347,17 +348,17 @@ struct Distance::type< Kernel, tag::line3D, tag::line3D > {
};
Scalar calculateGradientSecond(Vector& line1, Vector& line2, Vector& dline2) {
if(nxn.norm() == 0)
if(nxn_n == 0)
return 1.;
const Vector3 nxn_diff = n1.cross(dline2.template segment<3>(3));
Scalar diff = (dline2.template head<3>().dot(nxn)+c.dot(nxn_diff))*nxn.norm();
diff -= c.dot(nxn)*nxn.dot(nxn_diff)/nxn.norm();
Scalar diff = (dline2.template head<3>().dot(nxn)+c.dot(nxn_diff))*nxn_n;
diff -= c.dot(nxn)*nxn.dot(nxn_diff)/nxn_n;
//absoulute value requires diffrent differentation for diffrent results
if(cdn <= 0) diff *= -1;
diff /= std::pow(nxn.norm(),2);
diff /= std::pow(nxn_n,2);
#ifdef USE_LOGGING
if(!boost::math::isfinite(diff))
@ -369,32 +370,32 @@ struct Distance::type< Kernel, tag::line3D, tag::line3D > {
};
void calculateGradientFirstComplete(Vector& line1, Vector& line2, Vector& gradient) {
if(nxn.norm() == 0) {
if(nxn_n == 0) {
gradient.head(3).setOnes();
return;
}
if(cdn >= 0) {
gradient.template head<3>() = -nxn/nxn.norm();
gradient.template segment<3>(3) = (c.cross(-n2)*nxn.norm()-c.dot(nxn)*n2.cross(nxn)/nxn.norm())/std::pow(nxn.norm(),2);
gradient.template head<3>() = -nxn/nxn_n;
gradient.template segment<3>(3) = (c.cross(-n2)*nxn_n-c.dot(nxn)*n2.cross(nxn)/nxn_n)/std::pow(nxn_n,2);
} else {
gradient.template head<3>() = nxn/nxn.norm();
gradient.template segment<3>(3) = (-c.cross(-n2)*nxn.norm()+c.dot(nxn)*n2.cross(nxn)/nxn.norm())/std::pow(nxn.norm(),2);
gradient.template head<3>() = nxn/nxn_n;
gradient.template segment<3>(3) = (-c.cross(-n2)*nxn_n+c.dot(nxn)*n2.cross(nxn)/nxn_n)/std::pow(nxn_n,2);
}
};
void calculateGradientSecondComplete(Vector& line1, Vector& line2, Vector& gradient) {
if(nxn.norm() == 0) {
if(nxn_n == 0) {
gradient.head(3).setOnes();
return;
}
if(cdn >= 0) {
gradient.template head<3>() = nxn/nxn.norm();
gradient.template segment<3>(3) = (c.cross(n1)*nxn.norm()-c.dot(nxn)*((-n1).cross(nxn))/nxn.norm())/std::pow(nxn.norm(),2);
gradient.template head<3>() = nxn/nxn_n;
gradient.template segment<3>(3) = (c.cross(n1)*nxn_n-c.dot(nxn)*((-n1).cross(nxn))/nxn_n)/std::pow(nxn_n,2);
} else {
gradient.template head<3>() = -nxn/nxn.norm();
gradient.template segment<3>(3) = (-c.cross(n1)*nxn.norm()+c.dot(nxn)*((-n1).cross(nxn))/nxn.norm())/std::pow(nxn.norm(),2);
gradient.template head<3>() = -nxn/nxn_n;
gradient.template segment<3>(3) = (-c.cross(n1)*nxn_n+c.dot(nxn)*((-n1).cross(nxn))/nxn_n)/std::pow(nxn_n,2);
}
};
};

View File

@ -85,6 +85,7 @@ struct Module3D {
typedef mpl::map1< mpl::pair<remove, boost::function<void (Cons) > > > ConsSignal;
typedef ID Identifier;
typedef Typelist geometry_types;
typedef details::MES<Sys> MES;
typedef details::SystemSolver<Sys> SystemSolver;
@ -98,6 +99,8 @@ struct Module3D {
attrs::mutable_constant< std::string > log_id;
#endif
public:
Geometry3D_id(Sys& system);
template<typename T>
Geometry3D_id(const T& geometry, Sys& system);
@ -116,6 +119,8 @@ struct Module3D {
typedef vertex_prop vertex_propertie;
Geometry3D(Sys& system);
template<typename T>
Geometry3D(const T& geometry, Sys& system);
@ -288,7 +293,20 @@ 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)
#ifdef USE_LOGGING
, log_id("No ID")
#endif
{
#ifdef USE_LOGGING
Base::log.add_attribute("ID", log_id);
#endif
};
template<typename Typelist, typename ID>
template<typename Sys>
@ -344,6 +362,15 @@ void Module3D<Typelist, ID>::type<Sys>::Geometry3D_id<Derived>::setIdentifier(Id
#endif
};
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_id<Geometry3D> >::type(system) {
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>

View File

@ -158,8 +158,8 @@ typename SystemSolver<Sys>::Scalar SystemSolver<Sys>::Rescaler::scaleClusters()
//get the biggest scale factor
details::ClusterMath<Sys>& math = (*cit.first).second->template getClusterProperty<math_prop>();
//math.m_pseudo.clear();
//collectPseudoPoints(cluster, (*cit.first).first, math.m_pseudo);
math.m_pseudo.clear();
collectPseudoPoints(cluster, (*cit.first).first, math.m_pseudo);
const Scalar s = math.calculateClusterScale();
sc = (s>sc) ? s : sc;
@ -272,9 +272,15 @@ void SystemSolver<Sys>::solveCluster(boost::shared_ptr<Cluster> cluster, Sys& sy
constraints += (*it.first)->equationCount();
};
if(params <= 0 || constraints <= 0) {
//TODO:throw
#ifdef USE_LOGGING
BOOST_LOG(log)<< "Error in system counting: params = " << params << " and constraints = "<<constraints;
#endif
return;
}
//initialise the system with now known size
//std::cout<<"constraints: "<<constraints<<", params: "<<params+rot_params+trans_params<<std::endl;
Mes mes(cluster, params, constraints);
//iterate all geometrys again and set the needed maps

View File

@ -21,74 +21,429 @@
#define DCM_MODULE3D_STATE_HPP
#include "module.hpp"
#include "opendcm/moduleState/traits.hpp"
#include <opendcm/moduleState/traits.hpp>
#include <opendcm/core/clustergraph.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/phoenix/function/adapt_function.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/greater.hpp>
#include <ios>
namespace karma = boost::spirit::karma;
namespace ascii = boost::spirit::karma::ascii;
namespace qi = boost::spirit::qi;
namespace karma_ascii = boost::spirit::karma::ascii;
namespace qi_ascii = boost::spirit::qi::ascii;
namespace phx = boost::phoenix;
namespace dcm {
namespace details {
struct geom_visitor : public boost::static_visitor<int> {
template<typename Sys>
struct getModule3D {
typedef typename system_traits<Sys>::template getModule<m3d>::type type;
};
struct geom_visitor : public boost::static_visitor<std::string> {
template<typename T>
int operator()(T& i) const {
return geometry_traits<T>::tag::weight::value;
std::string operator()(T& i) const {
//we use stings in case new geometry gets added and the weights shift, meaning: backwards
//compatible
std::string type;
switch( geometry_traits<T>::tag::weight::value ) {
case tag::weight::direction::value :
return "direction";
case tag::weight::point::value :
return "point";
case tag::weight::line::value :
return "line";
case tag::weight::plane::value :
return "plane";
case tag::weight::cylinder::value :
return "cylinder";
default:
return "unknown";
};
};
};
template<typename T>
int getWeight(boost::shared_ptr<T> ptr) {
return boost::apply_visitor(geom_visitor(), ptr->m_geometry);
std::string getWeight(boost::shared_ptr<T> ptr) {
geom_visitor v;
return ptr->apply(v);
};
template<typename Kernel>
void getStdVector(typename Kernel::Vector& eigen, std::vector<typename Kernel::number_type>& vec) {
vec.resize(eigen.size());
for(int i=0; i<eigen.size(); i++)
vec[i] = eigen(i);
template<typename T>
struct get_weight {
typedef typename geometry_traits<T>::tag::weight type;
};
}
template<typename System>
struct parser_generate< typename Module3D::type<System>::Geometry3D, System>
: public mpl::true_{};
template<typename System, typename iterator>
struct parser_generator< typename Module3D::type<System>::Geometry3D, System, iterator > {
typedef typename Sys::Kernel Kernel;
typedef typename typename Module3D::type<System>::Geometry3D Geometry;
typedef karma::rule<iterator, boost::shared_ptr<Geometry>() > generator;
static void init(generator& r) {
r = karma::lit("<type>Geometry3D</type>\n<class>")
<< ascii::string[karma::_1 = phx::bind(&details::getWeight<Geometry>, karma::_val)]
<< "</class>\n<value>"
<< (karma::double_ % " ")[phx::bind(&details::getStdVector<Kernel>, )]
};
//search the first type in the typevector with the given weight
template<typename Vector, typename Weight>
struct getWeightType {
typedef typename mpl::find_if<Vector, boost::is_same<get_weight<mpl::_1>, Weight > >::type iter;
typedef typename mpl::deref<iter>::type type;
};
template<typename System>
struct parser_parse< typename Module3D::type<System>::Geometry3D, System>
: public mpl::true_{};
typedef std::vector< fusion::vector2<std::string, std::string> > string_vec;
typedef std::vector< fusion::vector2<std::vector<char>, std::vector<char> > > char_vec;
template<typename System, typename iterator>
struct parser_parser< typename Module3D::type<System>::Geometry3D, System, iterator > {
typedef typename Module3D::type<System>::Geometry3D object_type;
template<typename C>
string_vec getConstraints(boost::shared_ptr<C> con) {
typedef qi::rule<iterator, boost::shared_ptr<object_type>(System*), qi::space_type> parser;
static void init(parser& r) {
r = qi::lexeme[qi::lit("<type>object 1 prop</type>")[ qi::_val =
phx::construct<boost::shared_ptr<object_type> >( phx::new_<object_type>(*qi::_r1))]] >> ("<value>HaHAHAHAHA</value>");
string_vec vec;
std::vector<boost::any> cvec = con->getGenericConstraints();
typename std::vector<boost::any>::iterator it;
for(it = cvec.begin(); it != cvec.end(); it++) {
if((*it).type() == typeid(dcm::Distance)) {
std::string value = boost::lexical_cast<std::string>(boost::any_cast<dcm::Distance>(*it).value);
vec.push_back(fusion::make_vector(std::string("Distance"), value));
}
else if((*it).type() == typeid(dcm::Angle)) {
std::string value = boost::lexical_cast<std::string>(boost::any_cast<dcm::Angle>(*it).value);
vec.push_back(fusion::make_vector(std::string("Angle"), value));
}
else if((*it).type() == typeid(dcm::Orientation)) {
std::string value = boost::lexical_cast<std::string>(boost::any_cast<dcm::Orientation>(*it).value);
vec.push_back(fusion::make_vector(std::string("Orientation"), value));
};
};
return vec;
};
template<typename Seq, typename T>
struct push_seq {
typedef typename fusion::result_of::as_vector<typename mpl::push_back< Seq, T >::type>::type type;
};
template<typename State, typename Add>
typename push_seq<State, Add>::type append(State& s, const typename Add::option_type& val) {
typedef typename push_seq<State, Add>::type Sequence;
typedef typename fusion::result_of::begin<Sequence>::type Begin;
typedef typename fusion::result_of::end<Sequence>::type End;
typedef typename fusion::result_of::prior<End>::type EndOld;
//create the new sequence
Sequence vec;
//copy the old values into the new sequence
Begin b(vec);
EndOld eo(vec);
fusion::iterator_range<Begin, EndOld> range(b, eo);
fusion::copy(s, range);
//insert this object at the end of the sequence
fusion::back(vec) = val;
//and return our new extendet sequence
return vec;
};
template<typename State, typename C, typename Count>
typename boost::enable_if<typename mpl::greater<Count, mpl::int_<3> >::type, void>::type
recursiveCreation(typename char_vec::iterator it,
typename char_vec::iterator end,
boost::shared_ptr<C> con,
State s ) {};
template<typename State, typename C, typename Count>
typename boost::enable_if<typename mpl::less_equal<Count, mpl::int_<3> >::type, void>::type
recursiveCreation(typename char_vec::iterator it,
typename char_vec::iterator end,
boost::shared_ptr<C> con,
State s ) {
if(it == end) {
con->template initialize<State>(s);
return;
};
std::string first( fusion::at_c<0>(*it).begin(), fusion::at_c<0>(*it).end() );
std::string second( fusion::at_c<1>(*it).begin(), fusion::at_c<1>(*it).end() );
if( first.compare("Distance") == 0 ) {
typedef typename push_seq<State, dcm::Distance>::type Vec;
Vec vec = append<State, dcm::Distance>(s, boost::lexical_cast<typename dcm::Distance::option_type>(second));
recursiveCreation<Vec, C, typename mpl::next<Count>::type >(++it, end, con, vec);
return;
};
};
template<typename C>
void setConstraints(char_vec& vec, boost::shared_ptr<C> con ) {
recursiveCreation<fusion::vector<>, C, mpl::int_<0> >(vec.begin(), vec.end(), con, fusion::vector<>());
};
template <typename Geom, typename Row, typename Value>
bool VectorOutput(Geom &v, Row& r, Value& val) {
if (r < v->m_global.rows()) {
val = v->m_global(r++);
return true; // output continues
}
return false; // fail the output
};
template <typename Geom, typename Row, typename Value>
bool VectorInput(Geom &v, Row& r, Value& val) {
v.conservativeResize(r+1);
v(r++) = val;
return true; // output continues
};
template<typename Geom>
struct inject_set {
template<typename Vec, typename Obj>
static void apply(Vec& v, Obj g) {
Geom gt;
(typename geometry_traits<Geom>::modell()).template inject<double,
typename geometry_traits<Geom>::accessor >(gt, v);
g->set(gt);
};
};
//spezialisation if no type in the typelist has the right weight
template<>
struct inject_set<mpl_::void_> {
template<typename Obj, typename Vec>
static void apply(Vec& v, Obj g) {
//TODO:throw
};
};
template<typename System>
bool Create(System* sys, std::string& type,
boost::shared_ptr<typename details::getModule3D<System>::type::Geometry3D> geom,
typename System::Kernel::Vector& v) {
typedef typename details::getModule3D<System>::type::geometry_types Typelist;
if(type.compare("direction") == 0 ) {
inject_set<typename getWeightType<Typelist, tag::weight::direction>::type>::apply(v, geom);
}
else if(type.compare("point") == 0) {
inject_set<typename getWeightType<Typelist, tag::weight::point>::type>::apply(v, geom);
}
else if(type.compare("line") == 0) {
inject_set<typename getWeightType<Typelist, tag::weight::line>::type>::apply(v, geom);
}
else if(type.compare("plane") == 0 ) {
inject_set<typename getWeightType<Typelist, tag::weight::plane>::type>::apply(v, geom);
}
else if(type.compare("cylinder") == 0 ) {
inject_set<typename getWeightType<Typelist, tag::weight::cylinder>::type>::apply(v, geom);
};
return true;
};
// define a new real number formatting policy
template <typename Num>
struct scientific_policy : karma::real_policies<Num>
{
// we want the numbers always to be in scientific format
static int floatfield(Num n) { return std::ios::scientific; }
static unsigned precision(Num n) {return 16;};
};
// define a new generator type based on the new policy
typedef karma::real_generator<double, scientific_policy<double> > science_type;
static science_type const scientific = science_type();
} //details
} //dcm
BOOST_PHOENIX_ADAPT_FUNCTION( bool, vector_out, dcm::details::VectorOutput, 3)
BOOST_PHOENIX_ADAPT_FUNCTION( bool, vector_in, dcm::details::VectorInput, 3)
BOOST_PHOENIX_ADAPT_FUNCTION( bool, create, dcm::details::Create, 4)
BOOST_FUSION_ADAPT_STRUCT(
dcm::GlobalEdge,
(int, ID)
(int, source)
(int, target)
)
namespace dcm {
template<typename System>
struct parser_generate< typename details::getModule3D<System>::type::Geometry3D , System>
: public mpl::true_{};
template<typename System, typename iterator>
struct parser_generator< typename details::getModule3D<System>::type::Geometry3D , System, iterator > {
typedef typename details::getModule3D<System>::type::Geometry3D Geometry;
typedef karma::rule<iterator, boost::shared_ptr<Geometry>(), karma::locals<int> > generator;
static void init(generator& r) {
r = karma::lit("<type>Geometry3D</type>\n<class>")
<< karma_ascii::string[karma::_1 = phx::bind(&details::getWeight<Geometry>, karma::_val)]
<< "</class>" << karma::eol << "<value>"
<< (details::scientific[ boost::spirit::_pass = vector_out(karma::_val, karma::_a, karma::_1) ] % ' ')
<< "</value>";
};
};
template<typename System>
struct parser_generate< typename details::getModule3D<System>::type::vertex_prop , System>
: public mpl::true_{};
template<typename System, typename iterator>
struct parser_generator< typename details::getModule3D<System>::type::vertex_prop , System, iterator > {
typedef karma::rule<iterator, GlobalVertex()> generator;
static void init(generator& r) {
r = karma::lit("<type>Vertex</type>")
<< karma::eol << "<value>" << karma::int_ << "</value>";
};
};
template<typename System>
struct parser_generate< typename details::getModule3D<System>::type::Constraint3D , System>
: public mpl::true_{};
template<typename System, typename iterator>
struct parser_generator< typename details::getModule3D<System>::type::Constraint3D , System, iterator > {
typedef typename details::getModule3D<System>::type::Geometry3D Geometry3D;
typedef typename details::getModule3D<System>::type::Constraint3D Constraint3D;
typedef typename details::getModule3D<System>::type::vertex_prop vertex_prop;
typedef karma::rule<iterator, boost::shared_ptr<Constraint3D>()> generator;
static void init(generator& r) {
r = karma::lit("<type>Constraint3D</type>") << karma::eol
<< "<connect first=" << karma::int_[karma::_1 = phx::bind(&Geometry3D::template getProperty<vertex_prop>, phx::bind(&Constraint3D::first, karma::_val))]
<< " second=" << karma::int_[karma::_1 = phx::bind(&Geometry3D::template getProperty<vertex_prop>, phx::bind(&Constraint3D::second, karma::_val))] << "></connect>"
<< (*(karma::eol<<"<constraint type="<<karma_ascii::string<<">"<<karma_ascii::string<<"</constraint>"))[karma::_1 = phx::bind(&details::getConstraints<Constraint3D>, karma::_val)];
};
};
template<typename System>
struct parser_generate< typename details::getModule3D<System>::type::edge_prop , System>
: public mpl::true_{};
template<typename System, typename iterator>
struct parser_generator< typename details::getModule3D<System>::type::edge_prop , System, iterator > {
typedef karma::rule<iterator, GlobalEdge&()> generator;
static void init(generator& r) {
r %= karma::lit("<type>Edge</type>")
<< karma::eol << "<value>" << karma::int_ << " "
<< karma::int_ << " " << karma::int_ << "</value>";
};
};
template<typename System>
struct parser_generate<typename details::getModule3D<System>::type::fix_prop, System> : public mpl::true_ {};
template<typename System, typename iterator>
struct parser_generator<typename details::getModule3D<System>::type::fix_prop, System, iterator> {
typedef karma::rule<iterator, bool&()> generator;
static void init(generator& r) {
r = karma::lit("<type>Fix</type>\n<value>") << karma::bool_ <<"</value>";
};
};
/****************************************************************************************************/
/****************************************************************************************************/
template<typename System>
struct parser_parse< typename details::getModule3D<System>::type::Geometry3D , System>
: public mpl::true_{};
template<typename System, typename iterator>
struct parser_parser< typename details::getModule3D<System>::type::Geometry3D, System, iterator > {
typedef typename details::getModule3D<System>::type::Geometry3D object_type;
typedef typename System::Kernel Kernel;
typedef qi::rule<iterator, boost::shared_ptr<object_type>(System*), qi::space_type, qi::locals<std::string, typename Kernel::Vector, int> > parser;
static void init(parser& r) {
r = qi::lit("<type>Geometry3D</type>")[ qi::_val = phx::construct<boost::shared_ptr<object_type> >( phx::new_<object_type>(*qi::_r1))]
>> "<class>" >> (+qi::char_("a-zA-Z"))[qi::_a = phx::construct<std::string>(phx::begin(qi::_1), phx::end(qi::_1))] >> "</class>"
>> "<value>" >> *qi::double_[ vector_in(qi::_b, qi::_c, qi::_1) ] >> "</value>"
>> qi::eps[ create(qi::_r1, qi::_a, qi::_val, qi::_b) ];
};
};
template<typename System>
struct parser_parse< typename details::getModule3D<System>::type::vertex_prop, System>
: public mpl::true_{};
template<typename System, typename iterator>
struct parser_parser< typename details::getModule3D<System>::type::vertex_prop, System, iterator > {
typedef qi::rule<iterator, GlobalVertex(), qi::space_type> parser;
static void init(parser& r) {
r %= qi::lit("<type>Vertex</type>") >> "<value>" >> qi::int_ >> "</value>";
};
};
template<typename System>
struct parser_parse< typename details::getModule3D<System>::type::Constraint3D , System>
: public mpl::true_{};
template<typename System, typename iterator>
struct parser_parser< typename details::getModule3D<System>::type::Constraint3D, System, iterator > {
typedef typename details::getModule3D<System>::type::Geometry3D Geometry3D;
typedef typename details::getModule3D<System>::type::Constraint3D Constraint3D;
typedef typename System::Kernel Kernel;
typedef qi::rule<iterator, boost::shared_ptr<Constraint3D>(System*), qi::space_type > parser;
static void init(parser& r) {
r = qi::lit("<type>Constraint3D</type>")
>> ("<connect first=" >> qi::int_ >> "second=" >> qi::int_ >> "></connect>")[
qi::_val = phx::construct<boost::shared_ptr<Constraint3D> >(
phx::new_<Constraint3D>(*qi::_r1,
phx::bind(&System::Cluster::template getObject<Geometry3D, GlobalVertex>, phx::bind(&System::m_cluster, qi::_r1), qi::_1),
phx::bind(&System::Cluster::template getObject<Geometry3D, GlobalVertex>, phx::bind(&System::m_cluster, qi::_r1), qi::_2) ) )
]
>> (*("<constraint type=" >> *qi_ascii::alpha >> ">" >> *qi_ascii::alnum >>"</constraint>"))[phx::bind(&details::setConstraints<Constraint3D>, qi::_1, qi::_val)];
};
};
template<typename System>
struct parser_parse< typename details::getModule3D<System>::type::edge_prop, System>
: public mpl::true_{};
template<typename System, typename iterator>
struct parser_parser< typename details::getModule3D<System>::type::edge_prop, System, iterator > {
typedef qi::rule<iterator, GlobalEdge(), qi::space_type> parser;
static void init(parser& r) {
r %= qi::lit("<type>Edge</type>")
>> "<value>" >> qi::int_ >> qi::int_ >> qi::int_ >> "</value>";
};
};
template<typename System>
struct parser_parse< typename details::getModule3D<System>::type::fix_prop, System>
: public mpl::true_{};
template<typename System, typename iterator>
struct parser_parser< typename details::getModule3D<System>::type::fix_prop, System, iterator > {
typedef qi::rule<iterator, bool(), qi::space_type> parser;
static void init(parser& r) {
r = qi::lit("<type>Fix</type>") >> "<value>" >> qi::bool_ >> "</value>";
};
};
}

View File

@ -20,6 +20,10 @@
#ifndef DCM_EDGE_GENERATOR_H
#define DCM_EDGE_GENERATOR_H
#ifndef BOOST_SPIRIT_USE_PHOENIX_V3
#define BOOST_SPIRIT_USE_PHOENIX_V3
#endif
#include "property_generator.hpp"
#include "object_generator.hpp"
#include "extractor.hpp"
@ -27,7 +31,6 @@
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/support/is_sequence.hpp>
#include <boost/fusion/include/is_sequence.hpp>
namespace karma = boost::spirit::karma;

View File

@ -21,6 +21,7 @@
#define DCM_EDGE_GENERATOR_IMP_H
#include "edge_vertex_generator.hpp"
#include "boost/phoenix/fusion/at.hpp"
namespace dcm {
namespace details {
@ -28,9 +29,9 @@ namespace details {
template<typename Sys>
edge_generator<Sys>::edge_generator() : edge_generator<Sys>::base_type(edge_range) {
globaledge = karma::int_[phx::bind(&Extractor<Sys>::getGlobalEdgeID, ex, karma::_val, karma::_1)]
<< " source=" << karma::int_[phx::bind(&Extractor<Sys>::getGlobalEdgeSource, ex, karma::_val, karma::_1)]
<< " target=" << karma::int_[phx::bind(&Extractor<Sys>::getGlobalEdgeTarget, ex, karma::_val, karma::_1)] << '>'
globaledge = karma::int_[phx::bind(&Extractor<Sys>::getGlobalEdgeID, &ex, karma::_val, karma::_1)]
<< " source=" << karma::int_[phx::bind(&Extractor<Sys>::getGlobalEdgeSource, &ex, karma::_val, karma::_1)]
<< " target=" << karma::int_[phx::bind(&Extractor<Sys>::getGlobalEdgeTarget, &ex, karma::_val, karma::_1)] << '>'
<< "+" << objects[karma::_1 = phx::at_c<0>(karma::_val)] << "-\n" ;

View File

@ -20,6 +20,10 @@
#ifndef DCM_EDGE_VERTEX_PARSER_H
#define DCM_EDGE_VERTEX_PARSER_H
#ifndef BOOST_SPIRIT_USE_PHOENIX_V3
#define BOOST_SPIRIT_USE_PHOENIX_V3
#endif
#include <boost/spirit/include/qi.hpp>
#include "opendcm/core/clustergraph.hpp"
#include "extractor.hpp"

View File

@ -21,6 +21,7 @@
#define DCM_EDGE_PARSER_IMP_H
#include "edge_vertex_parser.hpp"
#include "boost/phoenix/fusion/at.hpp"
namespace dcm {
namespace details {
@ -34,18 +35,18 @@ edge_parser<Sys>::edge_parser() : edge_parser<Sys>::base_type(edge) {
>> objects(qi::_r1)[phx::at_c<0>(qi::_val) = qi::_1] >> "</GlobalEdge>";
edge = (qi::lit("<Edge") >> "source=" >> qi::int_ >> "target=" >> qi::int_ >> '>')[qi::_val = phx::bind((&Sys::Cluster::addEdgeGlobal), qi::_r1, qi::_1, qi::_2)]
>> edge_prop[phx::bind(&Injector<Sys>::setEdgeProperties, in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)]
>> *global_edge(qi::_r2)
>> edge_prop[phx::bind(&Injector<Sys>::setEdgeProperties, &in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)]
>> (*global_edge(qi::_r2))[phx::bind(&Injector<Sys>::setEdgeBundles, &in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)]
>> ("</Edge>");
};
template<typename Sys>
vertex_parser<Sys>::vertex_parser() : vertex_parser<Sys>::base_type(vertex) {
vertex = qi::lit("<Vertex")[phx::bind(&Injector<Sys>::addVertex, in, qi::_r1, qi::_val)] >> qi::lit("id=")
vertex = qi::lit("<Vertex")[phx::bind(&Injector<Sys>::addVertex, &in, qi::_r1, qi::_val)] >> qi::lit("id=")
>> qi::int_[phx::at_c<1>(qi::_val) = phx::bind(&Sys::Cluster::setGlobalVertex, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)]
>> '>' >> prop[phx::bind(&Injector<Sys>::setVertexProperties, in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)]
>> objects(qi::_r2)[phx::bind(&Injector<Sys>::setVertexObjects, in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)]
>> '>' >> prop[phx::bind(&Injector<Sys>::setVertexProperties, &in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)]
>> objects(qi::_r2)[phx::bind(&Injector<Sys>::setVertexObjects, &in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)]
>> ("</Vertex>");
};

View File

@ -96,12 +96,20 @@ struct Injector {
typename details::pts<typename Sys::edge_properties>::type& prop) {
fusion::at_c<0>(cluster->operator[](e)) = prop;
};
void setEdgeBundles(typename Sys::Cluster* cluster, LocalEdge e,
std::vector<typename Sys::Cluster::edge_bundle_single>& bundles) {
fusion::at_c<1>(cluster->operator[](e)) = bundles;
};
void setVertexProperty(typename Sys::Cluster* cluster, int value) {
cluster->template setClusterProperty<details::cluster_vertex_prop>(value);
};
void addCluster(typename Sys::Cluster* cluster, typename Sys::Cluster* addcl) {
LocalVertex v = cluster->getLocalVertex(addcl->template getClusterProperty<details::cluster_vertex_prop>()).first;
cluster->m_clusters[v] = boost::shared_ptr<typename Sys::Cluster>(addcl);
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;
cluster->m_clusters[v] = boost::shared_ptr<typename Sys::Cluster>(*it);
};
};
void addVertex(typename Sys::Cluster* cluster, fusion::vector<LocalVertex, GlobalVertex>& vec) {
vec = cluster->addVertex();

View File

@ -20,6 +20,10 @@
#ifndef DCM_GENERATOR_H
#define DCM_GENERATOR_H
#ifndef BOOST_SPIRIT_USE_PHOENIX_V3
#define BOOST_SPIRIT_USE_PHOENIX_V3
#endif
#include "property_generator.hpp"
#include "edge_vertex_generator.hpp"
#include "extractor.hpp"

View File

@ -22,7 +22,6 @@
#include "generator.hpp"
#include "opendcm/core/clustergraph.hpp"
//#include "karma_trans.hpp"
#include <boost/fusion/include/std_pair.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
@ -53,10 +52,12 @@ namespace dcm {
template<typename Sys>
generator<Sys>::generator() : generator<Sys>::base_type(start) {
cluster %= karma::omit[karma::int_] << cluster_prop << -vertex_range[phx::bind(&Extractor<Sys>::getVertexRange, ex, karma::_val, karma::_1)]
<< -karma::buffer["\n" << edge_range[phx::bind(&Extractor<Sys>::getEdgeRange, ex, karma::_val, karma::_1)]]
<< -karma::buffer["\n" << (cluster_pair % karma::eol)[phx::bind(&Extractor<Sys>::getClusterRange, ex, karma::_val, karma::_1)]] << "-\n"
<< "</Cluster>";
cluster %= karma::omit[karma::int_] << cluster_prop
<< -karma::buffer[karma::eol << (cluster_pair % karma::eol)[phx::bind(&Extractor<Sys>::getClusterRange, &ex, karma::_val, karma::_1)]]
<< -vertex_range[phx::bind(&Extractor<Sys>::getVertexRange, &ex, karma::_val, karma::_1)]
<< -karma::buffer[karma::eol << edge_range[phx::bind(&Extractor<Sys>::getEdgeRange, &ex, karma::_val, karma::_1)]]
<< "-" << karma::eol
<< karma::lit("</Cluster>");
cluster_pair %= karma::lit("<Cluster id=") << karma::int_ << ">+"
<< karma::attr_cast<graph*,graph&>(cluster);

View File

@ -27,9 +27,6 @@
#include "parser.hpp"
#include "defines.hpp"
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
namespace qi = boost::spirit::qi;
namespace dcm {

View File

@ -1,6 +1,10 @@
#ifndef DCM_OBJECT_GENERATOR_H
#define DCM_OBJECT_GENERATOR_H
#ifndef BOOST_SPIRIT_USE_PHOENIX_V3
#define BOOST_SPIRIT_USE_PHOENIX_V3
#endif
#include "property_generator.hpp"
namespace fusion = boost::fusion;

View File

@ -6,6 +6,8 @@
#include "object_generator.hpp"
#include "property_generator_imp.hpp"
#include "boost/phoenix/fusion/at.hpp"
using namespace boost::spirit::karma;
namespace karma = boost::spirit::karma;
namespace phx = boost::phoenix;

View File

@ -20,24 +20,20 @@
#ifndef DCM_OBJECT_PARSER_H
#define DCM_OBJECT_PARSER_H
#ifndef BOOST_SPIRIT_USE_PHOENIX_V3
#define BOOST_SPIRIT_USE_PHOENIX_V3
#endif
#include "property_parser.hpp"
namespace dcm {
namespace details {
template<typename Obj, typename Sys>
struct empty_obj_parser : public qi::grammar<IIterator, boost::shared_ptr<Obj>(Sys*), qi::space_type> {
qi::rule<IIterator, boost::shared_ptr<Obj>(Sys*), qi::space_type> start;
empty_obj_parser(): empty_obj_parser::base_type(start) {
//start = qi::eps(false);
};
};
//grammar for a single object
template<typename Sys, typename Object, typename Par>
struct obj_parser : public qi::grammar<IIterator, boost::shared_ptr<Object>(Sys*), qi::space_type> {
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, boost::shared_ptr<Object>(Sys*), qi::space_type> start;
qi::rule<IIterator, qi::unused_type(typename details::sps<ObjList>::type*, Sys*), qi::space_type> start;
prop_par<Sys, typename Object::Sequence > prop;
obj_parser();
@ -52,8 +48,8 @@ template<typename Sys, typename seq, typename state>
struct obj_parser_fold : mpl::fold< seq, state,
mpl::if_< parser_parse<mpl::_2, Sys>,
mpl::push_back<mpl::_1,
obj_parser<Sys, mpl::_2, dcm::parser_parser<mpl::_2, Sys, IIterator> > >,
mpl::push_back<mpl::_1, empty_obj_parser<mpl::_2, Sys> > > > {};
obj_parser<Sys, seq, mpl::_2, dcm::parser_parser<mpl::_2, Sys, IIterator> > >,
mpl::_1 > > {};
//currently max. 10 objects are supported
template<typename Sys>
@ -61,28 +57,19 @@ struct obj_par : public qi::grammar<IIterator,
typename details::sps<typename Sys::objects>::type(Sys*),
qi::space_type> {
typedef typename Sys::objects ObjectList;
typedef typename Sys::objects ObjectList;
//create a vector with the appropriate rules for all objects. Do this with the rule init struct, as it gives
//automatic initialisation of the rules when the objects are created
typedef typename obj_parser_fold<Sys, ObjectList, mpl::vector<> >::type init_rules_vector;
//push back a empty rule so that we know where to go when nothing is to do
typedef typename mpl::push_back<init_rules_vector,
empty_obj_parser<typename mpl::back<ObjectList>::type, Sys> >::type rules_vector;
//create a vector with the appropriate rules for all needed objects.
typedef typename obj_parser_fold<Sys, ObjectList, mpl::vector<> >::type sub_rules_sequence;
//the type of the objectlist rule
typedef qi::rule<IIterator, qi::unused_type(typename details::sps<ObjectList>::type*, Sys*), qi::space_type> parent_rule;
//we need to store all recursive created rules
typedef typename mpl::fold< sub_rules_sequence, mpl::vector0<>,
mpl::push_back<mpl::_1, parent_rule> >::type parent_rules_sequence;
//create the fusion sequence of our rules
typedef typename fusion::result_of::as_vector<rules_vector>::type rules_sequnce;
//this struct returns the right accessvalue for the sequences. If we access a value bigger than the property vector size
//we use the last rule, as we made sure this is an empty one
template<int I>
struct index : public mpl::if_< mpl::less<mpl::int_<I>, mpl::size<ObjectList> >,
mpl::int_<I>, typename mpl::size<ObjectList>::prior >::type {};
//this struct tells us if we should execute the generator
template<int I>
struct valid : public mpl::less< mpl::int_<I>, mpl::size<ObjectList> > {};
rules_sequnce rules;
typename fusion::result_of::as_vector<sub_rules_sequence>::type sub_rules;
typename fusion::result_of::as_vector<parent_rules_sequence>::type parent_rules;
qi::rule<IIterator, typename details::sps<ObjectList>::type(Sys*), qi::space_type> obj;
obj_par();

View File

@ -22,38 +22,53 @@
#include "object_parser.hpp"
#include "property_parser_imp.hpp"
#include "boost/phoenix/fusion/at.hpp"
namespace dcm {
namespace details {
template<typename srs, typename prs, typename dist>
typename boost::enable_if<mpl::less< dist, mpl::size<srs> >, void >::type recursive_obj_init( srs& sseq, prs& pseq ) {
if(dist::value == 0) {
fusion::at<dist>(pseq) %= fusion::at<dist>(sseq)(qi::_r1, qi::_r2);
}
else {
fusion::at<dist>(pseq) %= fusion::at<typename mpl::prior< typename mpl::max<dist, mpl::int_<1> >::type >::type>(pseq)(qi::_r1, qi::_r2) | fusion::at<dist>(sseq)(qi::_r1, qi::_r2);
}
recursive_obj_init<srs, prs, typename mpl::next<dist>::type>(sseq, pseq);
};
template<typename Sys, typename Object, typename Par>
obj_parser<Sys, Object, Par>::obj_parser(): obj_parser::base_type(start) {
template<typename srs, typename prs, typename dist>
typename boost::disable_if<mpl::less< dist, mpl::size<srs> >, void >::type recursive_obj_init( srs& sseq, prs& pseq ){};
template<typename Sys, typename ObjList, typename Object, typename Par>
obj_parser<Sys, ObjList, Object, Par>::obj_parser(): obj_parser::base_type(start) {
typedef typename mpl::find<ObjList, Object>::type::pos pos;
Par::init(subrule);
start = qi::lit("<Object>") >> subrule(qi::_r1)[qi::_val = qi::_1]
>> qi::eps(qi::_val)[ phx::bind(&Sys::template push_back<Object>, qi::_r1, qi::_val)]
>> prop[phx::bind(&obj_parser::setProperties, qi::_val, qi::_1)]
start = qi::lit("<Object>") >> subrule(qi::_r2)[phx::at_c<pos::value>(*qi::_r1) = qi::_1]
>> qi::eps(phx::at_c<pos::value>(*qi::_r1))[ phx::bind(&Sys::template push_back<Object>, qi::_r2, phx::at_c<pos::value>(*qi::_r1))]
>> prop[phx::bind(&obj_parser::setProperties, phx::at_c<pos::value>(*qi::_r1), qi::_1)]
>> qi::lit("</Object>");
};
template<typename Sys, typename Object, typename Par>
void obj_parser<Sys, Object, Par>::setProperties(boost::shared_ptr<Object> ptr, typename details::pts<typename Object::Sequence>::type& seq) {
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) {
if(ptr) ptr->m_properties = seq;
};
template<typename Sys>
obj_par<Sys>::obj_par(): obj_par<Sys>::base_type(obj) {
obj = -(qi::eps(valid<0>::value) >> fusion::at<index<0> >(rules)(qi::_r1)[phx::at_c<index<0>::value>(qi::_val) = qi::_1])
>> -(qi::eps(valid<1>::value) >> fusion::at<index<1> >(rules)(qi::_r1)[phx::at_c<index<1>::value>(qi::_val) = qi::_1])
>> -(qi::eps(valid<2>::value) >> fusion::at<index<2> >(rules)(qi::_r1)[phx::at_c<index<2>::value>(qi::_val) = qi::_1])
>> -(qi::eps(valid<3>::value) >> fusion::at<index<3> >(rules)(qi::_r1)[phx::at_c<index<3>::value>(qi::_val) = qi::_1])
>> -(qi::eps(valid<4>::value) >> fusion::at<index<4> >(rules)(qi::_r1)[phx::at_c<index<4>::value>(qi::_val) = qi::_1])
>> -(qi::eps(valid<5>::value) >> fusion::at<index<5> >(rules)(qi::_r1)[phx::at_c<index<5>::value>(qi::_val) = qi::_1])
>> -(qi::eps(valid<6>::value) >> fusion::at<index<6> >(rules)(qi::_r1)[phx::at_c<index<6>::value>(qi::_val) = qi::_1])
>> -(qi::eps(valid<7>::value) >> fusion::at<index<7> >(rules)(qi::_r1)[phx::at_c<index<7>::value>(qi::_val) = qi::_1])
>> -(qi::eps(valid<8>::value) >> fusion::at<index<8> >(rules)(qi::_r1)[phx::at_c<index<8>::value>(qi::_val) = qi::_1])
>> -(qi::eps(valid<9>::value) >> fusion::at<index<9> >(rules)(qi::_r1)[phx::at_c<index<9>::value>(qi::_val) = qi::_1]);
recursive_obj_init<typename fusion::result_of::as_vector<sub_rules_sequence>::type,
typename fusion::result_of::as_vector<parent_rules_sequence>::type,
mpl::int_<0> >(sub_rules, parent_rules);
obj = *(fusion::back(parent_rules)(&qi::_val, qi::_r1));
};
}//details

View File

@ -20,6 +20,10 @@
#ifndef DCM_PARSER_H
#define DCM_PARSER_H
#ifndef BOOST_SPIRIT_USE_PHOENIX_V3
#define BOOST_SPIRIT_USE_PHOENIX_V3
#endif
#include <iosfwd>
#include <boost/spirit/include/qi.hpp>
@ -55,13 +59,13 @@ static void print(std::string s) {
};
template<typename Sys>
struct parser : qi::grammar<IIterator, typename Sys::Cluster*(Sys*), qi::locals<int>, qi::space_type> {
struct parser : qi::grammar<IIterator, typename Sys::Cluster*(Sys*), qi::locals<int, std::vector<typename Sys::Cluster*> >, qi::space_type> {
typedef typename Sys::Cluster graph;
parser();
qi::rule<IIterator, graph*(Sys*), qi::locals<int>, qi::space_type> cluster;
qi::rule<IIterator, graph*(Sys*), qi::locals<int, std::vector<graph*> >, qi::space_type> cluster;
details::cluster_prop_par<Sys> cluster_prop;
details::obj_par<Sys> objects;

View File

@ -59,11 +59,14 @@ parser<Sys>::parser() : parser<Sys>::base_type(cluster) {
cluster %= qi::lit("<Cluster id=") >> qi::omit[qi::int_[qi::_a = qi::_1]] >> ">"
>> -(qi::eps( qi::_a > 0 )[qi::_val = phx::new_<typename Sys::Cluster>()])
>> qi::eps[phx::bind(&Injector<Sys>::setVertexProperty, in, qi::_val, qi::_a)]
>> qi::eps[phx::bind(&Sys::Cluster::setCopyMode, qi::_val, true)]
>> qi::eps[phx::bind(&Injector<Sys>::setVertexProperty, &in, qi::_val, qi::_a)]
>> qi::attr_cast<graph*, graph>(cluster_prop >> qi::eps)
>> qi::omit[(*cluster(qi::_r1))[qi::_b = qi::_1]]
>> qi::omit[*vertex(qi::_val, qi::_r1)]
>> qi::omit[*edge(qi::_val, qi::_r1)]
>> qi::omit[*(cluster(qi::_r1)[phx::bind(&Injector<Sys>::addCluster, in, qi::_val, qi::_1)])]
>> qi::eps[phx::bind(&Injector<Sys>::addClusters, &in, qi::_b, qi::_val)]
>> qi::eps[phx::bind(&Sys::Cluster::setCopyMode, qi::_val, false)]
>> "</Cluster>";// >> str[&sp::print];
};

View File

@ -1,6 +1,10 @@
#ifndef DCM_PROPERTY_GENERATOR_H
#define DCM_PROPERTY_GENERATOR_H
#ifndef BOOST_SPIRIT_USE_PHOENIX_V3
#define BOOST_SPIRIT_USE_PHOENIX_V3
#endif
#include <boost/fusion/include/as_vector.hpp>
#include <boost/spirit/include/karma.hpp>
@ -21,7 +25,7 @@ typedef std::ostream_iterator<char> Iterator;
namespace details {
//a grammar that does nothing exept failing
//a grammar that does nothing returns true
struct empty_grammar : public karma::grammar<Iterator> {
karma::rule<Iterator> start;
empty_grammar(): empty_grammar::base_type(start) {

View File

@ -20,6 +20,10 @@
#ifndef DCM_PROPERTY_PARSER_H
#define DCM_PROPERTY_PARSER_H
#ifndef BOOST_SPIRIT_USE_PHOENIX_V3
#define BOOST_SPIRIT_USE_PHOENIX_V3
#endif
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <boost/spirit/include/qi_string.hpp>
@ -40,28 +44,11 @@ typedef boost::spirit::istream_iterator IIterator;
namespace details {
struct empty_parser : public qi::grammar<IIterator> {
qi::rule<IIterator> start;
empty_parser(): empty_parser::base_type(start) {
start = qi::eps(true);
};
empty_parser(const empty_parser& other) : empty_parser::base_type(start) {};
};
template<typename Prop>
struct skip_parser : public qi::grammar<IIterator, typename Prop::type()> {
qi::rule<IIterator, typename Prop::type()> start;
skip_parser() : skip_parser<Prop>::base_type(start) {
start = qi::eps(true);
};
skip_parser(const skip_parser& other) : skip_parser::base_type(start) {};
};
template<typename Prop, typename Par>
struct prop_parser : qi::grammar<IIterator, typename Prop::type(), qi::space_type> {
template<typename PropList, typename Prop, typename Par>
struct prop_parser : qi::grammar<IIterator, qi::unused_type(typename details::pts<PropList>::type*), qi::space_type> {
typename Par::parser subrule;
qi::rule<IIterator, typename Prop::type(), qi::space_type> start;
qi::rule<IIterator, qi::unused_type(typename details::pts<PropList>::type*), qi::space_type> start;
prop_parser();
prop_parser(const prop_parser& other) : prop_parser::base_type(start) {};
};
@ -69,26 +56,24 @@ struct prop_parser : qi::grammar<IIterator, typename Prop::type(), qi::space_typ
template<typename Sys, typename seq, typename state>
struct prop_parser_fold : mpl::fold< seq, state,
mpl::if_< dcm::parser_parse<mpl::_2, Sys>,
mpl::push_back<mpl::_1,
prop_parser<mpl::_2, dcm::parser_parser<mpl::_2, Sys, IIterator> > >,
mpl::push_back<mpl::_1, skip_parser<mpl::_2> > > > {};
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
template<typename Sys, typename PropertyList>
struct prop_par : qi::grammar<IIterator, typename details::pts<PropertyList>::type(), qi::space_type> {
//create a vector with the appropriate rules for all properties.
typedef typename prop_parser_fold<Sys, PropertyList, mpl::vector<> >::type init_rules_sequence;
//allow max 10 types as the following code expect this
BOOST_MPL_ASSERT((mpl::less_equal< mpl::size<init_rules_sequence>, mpl::int_<10> >));
//we want to process 10 elements, so create a vector with (10-prop.size()) empty rules
//and append it to our rules vector
typedef mpl::range_c<int,0, mpl::minus< mpl::int_<10>, mpl::size<init_rules_sequence> >::value > range;
typedef typename mpl::fold< range,
init_rules_sequence,
mpl::push_back<mpl::_1, empty_parser> >::type rules_sequence;
//create a vector with the appropriate rules for all needed properties.
typedef typename prop_parser_fold<Sys, PropertyList, mpl::vector<> >::type sub_rules_sequence;
//the type of the propertylist rule
typedef qi::rule<IIterator, qi::unused_type(typename details::pts<PropertyList>::type*), qi::space_type> parent_rule;
//we need to store all recursive created rules
typedef typename mpl::fold< sub_rules_sequence, mpl::vector0<>,
mpl::push_back<mpl::_1, parent_rule> >::type parent_rules_sequence;
typename fusion::result_of::as_vector<rules_sequence>::type rules;
typename fusion::result_of::as_vector<sub_rules_sequence>::type sub_rules;
typename fusion::result_of::as_vector<parent_rules_sequence>::type parent_rules;
qi::rule<IIterator, typename details::pts<PropertyList>::type(), qi::space_type> prop;
prop_par();

View File

@ -21,6 +21,8 @@
#define DCM_PROPERTY_PARSER_IMP_H
#include "property_parser.hpp"
#include <boost/fusion/include/back.hpp>
#include <boost/phoenix/fusion/at.hpp>
namespace dcm {
@ -28,21 +30,40 @@ namespace dcm {
typedef boost::spirit::istream_iterator IIterator;
namespace details {
template<typename Prop, typename Par>
prop_parser<Prop, Par>::prop_parser() : prop_parser<Prop, Par>::base_type(start) {
Par::init(subrule);
start %= qi::lit("<Property>") >> subrule >> qi::lit("</Property>");
template<typename srs, typename prs, typename dist>
typename boost::enable_if<mpl::less< dist, mpl::size<srs> >, void >::type recursive_init( srs& sseq, prs& pseq ) {
if(dist::value == 0) {
fusion::at<dist>(pseq) %= fusion::at<dist>(sseq)(qi::_r1);
}
else {
fusion::at<dist>(pseq) %= fusion::at<typename mpl::prior< typename mpl::max<dist, mpl::int_<1> >::type >::type>(pseq)(qi::_r1) | fusion::at<dist>(sseq)(qi::_r1);
}
recursive_init<srs, prs, typename mpl::next<dist>::type>(sseq, pseq);
};
template<typename srs, typename prs, typename dist>
typename boost::disable_if<mpl::less< dist, mpl::size<srs> >, void >::type recursive_init( srs& sseq, prs& pseq ){};
template<typename PropList, typename Prop, typename Par>
prop_parser<PropList, Prop, Par>::prop_parser() : prop_parser<PropList, Prop, Par>::base_type(start) {
typedef typename mpl::find<PropList, Prop>::type::pos pos;
Par::init(subrule);
start = qi::lit("<Property>") >> subrule[phx::at_c<pos::value>(*qi::_r1) = qi::_1] >> qi::lit("</Property>");
};
template<typename Sys, typename PropertyList>
prop_par<Sys, PropertyList>::prop_par() : prop_par<Sys, PropertyList>::base_type(prop) {
prop %= fusion::at_c<0>(rules) >> fusion::at_c<1>(rules) >> fusion::at_c<2>(rules)
>> fusion::at_c<3>(rules) >> fusion::at_c<4>(rules) >> fusion::at_c<5>(rules)
>> fusion::at_c<6>(rules) >> fusion::at_c<7>(rules) >> fusion::at_c<8>(rules)
>> fusion::at_c<9>(rules);
recursive_init<typename fusion::result_of::as_vector<sub_rules_sequence>::type,
typename fusion::result_of::as_vector<parent_rules_sequence>::type,
mpl::int_<0> >(sub_rules, parent_rules);
prop = *(fusion::back(parent_rules)(&qi::_val));
};
template<typename Sys>

View File

@ -20,6 +20,10 @@
#ifndef DCM_PARSER_TRAITS_H
#define DCM_PARSER_TRAITS_H
#ifndef BOOST_SPIRIT_USE_PHOENIX_V3
#define BOOST_SPIRIT_USE_PHOENIX_V3
#endif
#include <boost/mpl/bool.hpp>
#include <assert.h>

View File

@ -113,7 +113,7 @@ struct parser_parser<changed_prop, System, iterator> {
typedef qi::rule<iterator, bool(), qi::space_type> parser;
static void init(parser& r) {
r = qi::lit("<type>clusterchanged</type>") >> ("<value>") >> qi::bool_ >>"</value>";
r = qi::lit("<type>clusterchanged</type>") >> ("<value>") >> qi::bool_ >>"</value>" ;
};
};

View File

@ -27,6 +27,9 @@
#pragma warning( disable : 4503 )
#endif
//use phoenix v3 to allow normal boost phoenix use outside of spirit and not the spirit phoenix v2 version
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include "moduleState/module.hpp"
#include "moduleState/traits.hpp"