From 3058d86b23e61cef867da94c1c808824b2e43a33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Tr=C3=B6ger?= Date: Sat, 8 Jun 2013 16:17:05 +0200 Subject: [PATCH] enable scaling --- src/Mod/Assembly/App/CMakeLists.txt | 10 +- src/Mod/Assembly/App/ItemAssembly.h | 1 - .../App/opendcm/core/clustergraph.hpp | 15 +- .../Assembly/App/opendcm/core/constraint.hpp | 172 ++++++- .../Assembly/App/opendcm/core/geometry.hpp | 13 + src/Mod/Assembly/App/opendcm/module3d.hpp | 4 + .../App/opendcm/module3d/distance.hpp | 39 +- .../Assembly/App/opendcm/module3d/module.hpp | 27 ++ .../Assembly/App/opendcm/module3d/solver.hpp | 12 +- .../Assembly/App/opendcm/module3d/state.hpp | 439 ++++++++++++++++-- .../moduleState/edge_vertex_generator.hpp | 5 +- .../moduleState/edge_vertex_generator_imp.hpp | 7 +- .../moduleState/edge_vertex_parser.hpp | 4 + .../moduleState/edge_vertex_parser_imp.hpp | 11 +- .../App/opendcm/moduleState/extractor.hpp | 14 +- .../App/opendcm/moduleState/generator.hpp | 4 + .../App/opendcm/moduleState/generator_imp.hpp | 11 +- .../App/opendcm/moduleState/module.hpp | 3 - .../opendcm/moduleState/object_generator.hpp | 4 + .../moduleState/object_generator_imp.hpp | 2 + .../App/opendcm/moduleState/object_parser.hpp | 53 +-- .../opendcm/moduleState/object_parser_imp.hpp | 53 ++- .../App/opendcm/moduleState/parser.hpp | 8 +- .../App/opendcm/moduleState/parser_imp.hpp | 7 +- .../moduleState/property_generator.hpp | 6 +- .../opendcm/moduleState/property_parser.hpp | 53 +-- .../moduleState/property_parser_imp.hpp | 39 +- .../App/opendcm/moduleState/traits.hpp | 4 + .../App/opendcm/moduleState/traits_impl.hpp | 2 +- src/Mod/Assembly/App/opendcm/modulestate.hpp | 3 + 30 files changed, 819 insertions(+), 206 deletions(-) diff --git a/src/Mod/Assembly/App/CMakeLists.txt b/src/Mod/Assembly/App/CMakeLists.txt index c8cfb1013..7ca682440 100644 --- a/src/Mod/Assembly/App/CMakeLists.txt +++ b/src/Mod/Assembly/App/CMakeLists.txt @@ -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 diff --git a/src/Mod/Assembly/App/ItemAssembly.h b/src/Mod/Assembly/App/ItemAssembly.h index 4014a5ea7..f9050c55d 100644 --- a/src/Mod/Assembly/App/ItemAssembly.h +++ b/src/Mod/Assembly/App/ItemAssembly.h @@ -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); diff --git a/src/Mod/Assembly/App/opendcm/core/clustergraph.hpp b/src/Mod/Assembly/App/opendcm/core/clustergraph.hpp index 4fed639dd..7e2e69837 100644 --- a/src/Mod/Assembly/App/opendcm/core/clustergraph.hpp +++ b/src/Mod/Assembly/App/opendcm/core/clustergraph.hpp @@ -328,9 +328,14 @@ public: bool operator!=(const T& other) const { return !(this == &other); }; + + void setCopyMode(bool on) { + copy_mode = on; + }; void setChanged() { - setClusterProperty(true); + if(!copy_mode) + setClusterProperty(true); }; /* ******************************************************* @@ -345,7 +350,7 @@ public: }; template typename P::type& getSubclusterProperty(LocalVertex v) { - return getVertexCluster(v)->getClusterProperty

(); + return getVertexCluster(v)->template getClusterProperty

(); }; template @@ -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(f, recursive); + (*cit).second->template for_each(f, recursive); } } }; @@ -1383,6 +1389,7 @@ public: protected: boost::weak_ptr 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(k, f); + return fusion::at_c<1>(res)->template apply_to_bundle(k, f); }; template diff --git a/src/Mod/Assembly/App/opendcm/core/constraint.hpp b/src/Mod/Assembly/App/opendcm/core/constraint.hpp index 6cb91602d..db1fc39d1 100644 --- a/src/Mod/Assembly/App/opendcm/core/constraint.hpp +++ b/src/Mod/Assembly/App/opendcm/core/constraint.hpp @@ -33,7 +33,9 @@ #include #include #include +#include +#include #include #include @@ -69,12 +71,15 @@ public: ~Constraint(); virtual boost::shared_ptr clone(Sys& newSys); - -protected: - + std::vector getGenericEquations(); + std::vector getGenericConstraints(); + std::vector getEquationTypes(); + std::vector getConstraintTypes(); + template 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 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 getGenericEquations() = 0; + virtual std::vector getGenericConstraints() = 0; + virtual std::vector getEquationTypes() = 0; + virtual std::vector getConstraintTypes() = 0; }; public: @@ -187,18 +198,49 @@ public: void operator()(T& val) const; }; - holder(Objects& obj); + struct GenericEquations { + std::vector& vec; + GenericEquations(std::vector& v); + + template + void operator()(T& val) const; + }; + struct GenericConstraints { + std::vector& vec; + GenericConstraints(std::vector& v); + + template + void operator()(T& val) const; + }; + + struct Types { + std::vector& vec; + Types(std::vector& v); + + template + 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::value; }; + + virtual std::vector getGenericEquations(); + virtual std::vector getGenericConstraints(); + virtual std::vector getEquationTypes(); + virtual std::vector getConstraintTypes(); EquationSets m_sets; + Objects m_objects; }; protected: @@ -217,14 +259,15 @@ protected: template 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::~Constraint() { template boost::shared_ptr Constraint::clone(Sys& newSys) { - + //copy the standart stuff boost::shared_ptr np = boost::shared_ptr(new Derived(*static_cast(this))); np->m_system = &newSys; @@ -313,6 +356,26 @@ void Constraint::collectPseudoPoints(Vec& content->collectPseudoPoints(first, second, vec1, vec2); }; +template +std::vector Constraint::getGenericEquations() { + return content->getGenericEquations(); +}; + +template +std::vector Constraint::getGenericConstraints() { + return content->getGenericConstraints(); +}; + +template +std::vector Constraint::getEquationTypes() { + return content->getEquationTypes(); +}; + +template +std::vector Constraint::getConstraintTypes() { + return content->getConstraintTypes(); +}; + template template Constraint::holder::OptionSetter::OptionSetter(Objects& val) : objects(val) {}; @@ -440,9 +503,52 @@ void Constraint::holder template -Constraint::holder::holder(Objects& obj) { +Constraint::holder::GenericEquations::GenericEquations(std::vector& v) + : vec(v) { + +}; + +template +template +template< typename T > +void Constraint::holder::GenericEquations::operator()(T& val) const { + vec.push_back(val.m_eq); +}; + +template +template +Constraint::holder::GenericConstraints::GenericConstraints(std::vector& v) + : vec(v) { + +}; + +template +template +template< typename T > +void Constraint::holder::GenericConstraints::operator()(T& val) const { + vec.push_back(val); +}; + +template +template +Constraint::holder::Types::Types(std::vector& v) + : vec(v) { + +}; + +template +template +template< typename T > +void Constraint::holder::Types::operator()(T& val) const { + vec.push_back(&typeid(T)); +}; + +template +template +Constraint::holder::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::holder template -typename Constraint::placeholder* +typename Constraint::placeholder* Constraint::holder::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::holder template -typename Constraint::placeholder* +typename Constraint::placeholder* Constraint::holder::clone() { return new holder(*this); }; +template +template +std::vector +Constraint::holder::getGenericEquations() { + std::vector vec; + fusion::for_each( m_sets, GenericEquations(vec) ); + return vec; +}; + +template +template +std::vector +Constraint::holder::getGenericConstraints() { + std::vector vec; + fusion::for_each( m_objects, GenericConstraints(vec) ); + return vec; +}; + +template +template +std::vector +Constraint::holder::getEquationTypes() { + std::vector vec; + mpl::for_each< EquationVector >( Types(vec) ); + return vec; +}; + +template +template +std::vector +Constraint::holder::getConstraintTypes() { + std::vector vec; + mpl::for_each< ConstraintVector >( Types(vec) ); + return vec; +}; + template template< typename ConstraintVector > Constraint::creator::creator(Objects& obj) : objects(obj) { - + }; template template< typename ConstraintVector > template void Constraint::creator::operator()(const T1&, const T2&) { - + typedef tag_order< typename geometry_traits::tag, typename geometry_traits::tag > order; //transform the constraints into eqautions with the now known types diff --git a/src/Mod/Assembly/App/opendcm/core/geometry.hpp b/src/Mod/Assembly/App/opendcm/core/geometry.hpp index cca085233..131a2d24e 100644 --- a/src/Mod/Assembly/App/opendcm/core/geometry.hpp +++ b/src/Mod/Assembly/App/opendcm/core/geometry.hpp @@ -167,6 +167,8 @@ protected: public: typedef mpl::int_ Dimension; + Geometry(Sys& system); + template Geometry(const T& geometry, Sys& system); @@ -277,6 +279,17 @@ public: /*****************************************************************************************************************/ /*****************************************************************************************************************/ +template< typename Sys, typename Derived, typename GeometrieTypeList, int Dim> +Geometry::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 diff --git a/src/Mod/Assembly/App/opendcm/module3d.hpp b/src/Mod/Assembly/App/opendcm/module3d.hpp index db10e08cd..a0c4392fc 100644 --- a/src/Mod/Assembly/App/opendcm/module3d.hpp +++ b/src/Mod/Assembly/App/opendcm/module3d.hpp @@ -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 diff --git a/src/Mod/Assembly/App/opendcm/module3d/distance.hpp b/src/Mod/Assembly/App/opendcm/module3d/distance.hpp index 88fe8ab3e..273efc7aa 100644 --- a/src/Mod/Assembly/App/opendcm/module3d/distance.hpp +++ b/src/Mod/Assembly/App/opendcm/module3d/distance.hpp @@ -273,7 +273,7 @@ struct Distance::type< Kernel, tag::line3D, tag::line3D > { typedef typename Kernel::Vector3 Vector3; typedef std::vector > 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); } }; }; diff --git a/src/Mod/Assembly/App/opendcm/module3d/module.hpp b/src/Mod/Assembly/App/opendcm/module3d/module.hpp index ea6a9c9a1..b21c84ff8 100644 --- a/src/Mod/Assembly/App/opendcm/module3d/module.hpp +++ b/src/Mod/Assembly/App/opendcm/module3d/module.hpp @@ -85,6 +85,7 @@ struct Module3D { typedef mpl::map1< mpl::pair > > ConsSignal; typedef ID Identifier; + typedef Typelist geometry_types; typedef details::MES MES; typedef details::SystemSolver SystemSolver; @@ -98,6 +99,8 @@ struct Module3D { attrs::mutable_constant< std::string > log_id; #endif public: + Geometry3D_id(Sys& system); + template Geometry3D_id(const T& geometry, Sys& system); @@ -116,6 +119,8 @@ struct Module3D { typedef vertex_prop vertex_propertie; + Geometry3D(Sys& system); + template Geometry3D(const T& geometry, Sys& system); @@ -288,7 +293,20 @@ typename boost::add_reference::type get(G geom) { /*****************************************************************************************************************/ /*****************************************************************************************************************/ +template +template +template +Module3D::type::Geometry3D_id::Geometry3D_id(Sys& system) + : detail::Geometry(system) +#ifdef USE_LOGGING + , log_id("No ID") +#endif +{ +#ifdef USE_LOGGING + Base::log.add_attribute("ID", log_id); +#endif +}; template template @@ -344,6 +362,15 @@ void Module3D::type::Geometry3D_id::setIdentifier(Id #endif }; +template +template +Module3D::type::Geometry3D::Geometry3D(Sys& system) + : mpl::if_, + detail::Geometry, + Geometry3D_id >::type(system) { + +}; + template template template diff --git a/src/Mod/Assembly/App/opendcm/module3d/solver.hpp b/src/Mod/Assembly/App/opendcm/module3d/solver.hpp index 9502154b3..ac9910c45 100644 --- a/src/Mod/Assembly/App/opendcm/module3d/solver.hpp +++ b/src/Mod/Assembly/App/opendcm/module3d/solver.hpp @@ -158,8 +158,8 @@ typename SystemSolver::Scalar SystemSolver::Rescaler::scaleClusters() //get the biggest scale factor details::ClusterMath& math = (*cit.first).second->template getClusterProperty(); - //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::solveCluster(boost::shared_ptr 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 = "< +#include + +#include #include #include +#include +#include +#include + +#include 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 { + +template +struct getModule3D { + typedef typename system_traits::template getModule::type type; +}; + +struct geom_visitor : public boost::static_visitor { + template - int operator()(T& i) const { - return geometry_traits::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::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 -int getWeight(boost::shared_ptr ptr) { - return boost::apply_visitor(geom_visitor(), ptr->m_geometry); +std::string getWeight(boost::shared_ptr ptr) { + geom_visitor v; + return ptr->apply(v); }; -template -void getStdVector(typename Kernel::Vector& eigen, std::vector& vec) { - vec.resize(eigen.size()); - for(int i=0; i +struct get_weight { + typedef typename geometry_traits::tag::weight type; }; -} - -template -struct parser_generate< typename Module3D::type::Geometry3D, System> - : public mpl::true_{}; - -template -struct parser_generator< typename Module3D::type::Geometry3D, System, iterator > { - - typedef typename Sys::Kernel Kernel; - typedef typename typename Module3D::type::Geometry3D Geometry; - typedef karma::rule() > generator; - static void init(generator& r) { - r = karma::lit("Geometry3D\n") - << ascii::string[karma::_1 = phx::bind(&details::getWeight, karma::_val)] - << "\n" - << (karma::double_ % " ")[phx::bind(&details::getStdVector, )] - }; +//search the first type in the typevector with the given weight +template +struct getWeightType { + typedef typename mpl::find_if, Weight > >::type iter; + typedef typename mpl::deref::type type; }; -template -struct parser_parse< typename Module3D::type::Geometry3D, System> - : public mpl::true_{}; +typedef std::vector< fusion::vector2 > string_vec; +typedef std::vector< fusion::vector2, std::vector > > char_vec; -template -struct parser_parser< typename Module3D::type::Geometry3D, System, iterator > { - - typedef typename Module3D::type::Geometry3D object_type; +template +string_vec getConstraints(boost::shared_ptr con) { - typedef qi::rule(System*), qi::space_type> parser; - static void init(parser& r) { - r = qi::lexeme[qi::lit("object 1 prop")[ qi::_val = - phx::construct >( phx::new_(*qi::_r1))]] >> ("HaHAHAHAHA"); + string_vec vec; + std::vector cvec = con->getGenericConstraints(); + + typename std::vector::iterator it; + for(it = cvec.begin(); it != cvec.end(); it++) { + + if((*it).type() == typeid(dcm::Distance)) { + std::string value = boost::lexical_cast(boost::any_cast(*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(boost::any_cast(*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(boost::any_cast(*it).value); + vec.push_back(fusion::make_vector(std::string("Orientation"), value)); + }; + }; + return vec; +}; + +template +struct push_seq { + typedef typename fusion::result_of::as_vector::type>::type type; +}; + +template +typename push_seq::type append(State& s, const typename Add::option_type& val) { + + typedef typename push_seq::type Sequence; + typedef typename fusion::result_of::begin::type Begin; + typedef typename fusion::result_of::end::type End; + typedef typename fusion::result_of::prior::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 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 boost::enable_if >::type, void>::type +recursiveCreation(typename char_vec::iterator it, + typename char_vec::iterator end, + boost::shared_ptr con, + State s ) {}; + +template +typename boost::enable_if >::type, void>::type +recursiveCreation(typename char_vec::iterator it, + typename char_vec::iterator end, + boost::shared_ptr con, + State s ) { + + if(it == end) { + con->template initialize(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::type Vec; + Vec vec = append(s, boost::lexical_cast(second)); + recursiveCreation::type >(++it, end, con, vec); + return; + }; +}; + +template +void setConstraints(char_vec& vec, boost::shared_ptr con ) { + recursiveCreation, C, mpl::int_<0> >(vec.begin(), vec.end(), con, fusion::vector<>()); +}; + +template +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 +bool VectorInput(Geom &v, Row& r, Value& val) { + + v.conservativeResize(r+1); + v(r++) = val; + return true; // output continues +}; + +template +struct inject_set { + + template + static void apply(Vec& v, Obj g) { + Geom gt; + (typename geometry_traits::modell()).template inject::accessor >(gt, v); + g->set(gt); }; }; +//spezialisation if no type in the typelist has the right weight +template<> +struct inject_set { + + template + static void apply(Vec& v, Obj g) { + //TODO:throw + }; +}; + +template +bool Create(System* sys, std::string& type, + boost::shared_ptr::type::Geometry3D> geom, + typename System::Kernel::Vector& v) { + typedef typename details::getModule3D::type::geometry_types Typelist; + + if(type.compare("direction") == 0 ) { + inject_set::type>::apply(v, geom); + } + else if(type.compare("point") == 0) { + inject_set::type>::apply(v, geom); + } + else if(type.compare("line") == 0) { + inject_set::type>::apply(v, geom); + } + else if(type.compare("plane") == 0 ) { + inject_set::type>::apply(v, geom); + } + else if(type.compare("cylinder") == 0 ) { + inject_set::type>::apply(v, geom); + }; + return true; +}; + +// define a new real number formatting policy +template +struct scientific_policy : karma::real_policies +{ + // 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 > 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 +struct parser_generate< typename details::getModule3D::type::Geometry3D , System> + : public mpl::true_{}; + +template +struct parser_generator< typename details::getModule3D::type::Geometry3D , System, iterator > { + + typedef typename details::getModule3D::type::Geometry3D Geometry; + typedef karma::rule(), karma::locals > generator; + static void init(generator& r) { + r = karma::lit("Geometry3D\n") + << karma_ascii::string[karma::_1 = phx::bind(&details::getWeight, karma::_val)] + << "" << karma::eol << "" + << (details::scientific[ boost::spirit::_pass = vector_out(karma::_val, karma::_a, karma::_1) ] % ' ') + << ""; + }; +}; + + +template +struct parser_generate< typename details::getModule3D::type::vertex_prop , System> + : public mpl::true_{}; + +template +struct parser_generator< typename details::getModule3D::type::vertex_prop , System, iterator > { + + typedef karma::rule generator; + static void init(generator& r) { + r = karma::lit("Vertex") + << karma::eol << "" << karma::int_ << ""; + }; +}; + +template +struct parser_generate< typename details::getModule3D::type::Constraint3D , System> + : public mpl::true_{}; + +template +struct parser_generator< typename details::getModule3D::type::Constraint3D , System, iterator > { + + typedef typename details::getModule3D::type::Geometry3D Geometry3D; + typedef typename details::getModule3D::type::Constraint3D Constraint3D; + typedef typename details::getModule3D::type::vertex_prop vertex_prop; + typedef karma::rule()> generator; + static void init(generator& r) { + r = karma::lit("Constraint3D") << karma::eol + << "" + << (*(karma::eol<<""<"))[karma::_1 = phx::bind(&details::getConstraints, karma::_val)]; + }; +}; + +template +struct parser_generate< typename details::getModule3D::type::edge_prop , System> + : public mpl::true_{}; + +template +struct parser_generator< typename details::getModule3D::type::edge_prop , System, iterator > { + + typedef karma::rule generator; + static void init(generator& r) { + r %= karma::lit("Edge") + << karma::eol << "" << karma::int_ << " " + << karma::int_ << " " << karma::int_ << ""; + }; +}; + +template +struct parser_generate::type::fix_prop, System> : public mpl::true_ {}; + +template +struct parser_generator::type::fix_prop, System, iterator> { + typedef karma::rule generator; + + static void init(generator& r) { + r = karma::lit("Fix\n") << karma::bool_ <<""; + }; +}; + +/****************************************************************************************************/ +/****************************************************************************************************/ + +template +struct parser_parse< typename details::getModule3D::type::Geometry3D , System> + : public mpl::true_{}; + +template +struct parser_parser< typename details::getModule3D::type::Geometry3D, System, iterator > { + + typedef typename details::getModule3D::type::Geometry3D object_type; + typedef typename System::Kernel Kernel; + + typedef qi::rule(System*), qi::space_type, qi::locals > parser; + static void init(parser& r) { + r = qi::lit("Geometry3D")[ qi::_val = phx::construct >( phx::new_(*qi::_r1))] + >> "" >> (+qi::char_("a-zA-Z"))[qi::_a = phx::construct(phx::begin(qi::_1), phx::end(qi::_1))] >> "" + >> "" >> *qi::double_[ vector_in(qi::_b, qi::_c, qi::_1) ] >> "" + >> qi::eps[ create(qi::_r1, qi::_a, qi::_val, qi::_b) ]; + }; +}; + +template +struct parser_parse< typename details::getModule3D::type::vertex_prop, System> + : public mpl::true_{}; + +template +struct parser_parser< typename details::getModule3D::type::vertex_prop, System, iterator > { + + typedef qi::rule parser; + static void init(parser& r) { + r %= qi::lit("Vertex") >> "" >> qi::int_ >> ""; + }; +}; + + +template +struct parser_parse< typename details::getModule3D::type::Constraint3D , System> + : public mpl::true_{}; + +template +struct parser_parser< typename details::getModule3D::type::Constraint3D, System, iterator > { + + typedef typename details::getModule3D::type::Geometry3D Geometry3D; + typedef typename details::getModule3D::type::Constraint3D Constraint3D; + typedef typename System::Kernel Kernel; + + typedef qi::rule(System*), qi::space_type > parser; + static void init(parser& r) { + r = qi::lit("Constraint3D") + >> ("")[ + qi::_val = phx::construct >( + phx::new_(*qi::_r1, + phx::bind(&System::Cluster::template getObject, phx::bind(&System::m_cluster, qi::_r1), qi::_1), + phx::bind(&System::Cluster::template getObject, phx::bind(&System::m_cluster, qi::_r1), qi::_2) ) ) + ] + >> (*("" >> *qi_ascii::alnum >>""))[phx::bind(&details::setConstraints, qi::_1, qi::_val)]; + }; +}; + +template +struct parser_parse< typename details::getModule3D::type::edge_prop, System> + : public mpl::true_{}; + +template +struct parser_parser< typename details::getModule3D::type::edge_prop, System, iterator > { + + typedef qi::rule parser; + static void init(parser& r) { + r %= qi::lit("Edge") + >> "" >> qi::int_ >> qi::int_ >> qi::int_ >> ""; + }; +}; + +template +struct parser_parse< typename details::getModule3D::type::fix_prop, System> + : public mpl::true_{}; + +template +struct parser_parser< typename details::getModule3D::type::fix_prop, System, iterator > { + + typedef qi::rule parser; + static void init(parser& r) { + r = qi::lit("Fix") >> "" >> qi::bool_ >> ""; + }; +}; + } diff --git a/src/Mod/Assembly/App/opendcm/moduleState/edge_vertex_generator.hpp b/src/Mod/Assembly/App/opendcm/moduleState/edge_vertex_generator.hpp index 7182c5c4c..af446fa91 100644 --- a/src/Mod/Assembly/App/opendcm/moduleState/edge_vertex_generator.hpp +++ b/src/Mod/Assembly/App/opendcm/moduleState/edge_vertex_generator.hpp @@ -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 #include #include - #include namespace karma = boost::spirit::karma; diff --git a/src/Mod/Assembly/App/opendcm/moduleState/edge_vertex_generator_imp.hpp b/src/Mod/Assembly/App/opendcm/moduleState/edge_vertex_generator_imp.hpp index 40d6fa78e..9c99a32c7 100644 --- a/src/Mod/Assembly/App/opendcm/moduleState/edge_vertex_generator_imp.hpp +++ b/src/Mod/Assembly/App/opendcm/moduleState/edge_vertex_generator_imp.hpp @@ -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 edge_generator::edge_generator() : edge_generator::base_type(edge_range) { - globaledge = karma::int_[phx::bind(&Extractor::getGlobalEdgeID, ex, karma::_val, karma::_1)] - << " source=" << karma::int_[phx::bind(&Extractor::getGlobalEdgeSource, ex, karma::_val, karma::_1)] - << " target=" << karma::int_[phx::bind(&Extractor::getGlobalEdgeTarget, ex, karma::_val, karma::_1)] << '>' + globaledge = karma::int_[phx::bind(&Extractor::getGlobalEdgeID, &ex, karma::_val, karma::_1)] + << " source=" << karma::int_[phx::bind(&Extractor::getGlobalEdgeSource, &ex, karma::_val, karma::_1)] + << " target=" << karma::int_[phx::bind(&Extractor::getGlobalEdgeTarget, &ex, karma::_val, karma::_1)] << '>' << "+" << objects[karma::_1 = phx::at_c<0>(karma::_val)] << "-\n" ; diff --git a/src/Mod/Assembly/App/opendcm/moduleState/edge_vertex_parser.hpp b/src/Mod/Assembly/App/opendcm/moduleState/edge_vertex_parser.hpp index d4172fb3a..fe60473f2 100644 --- a/src/Mod/Assembly/App/opendcm/moduleState/edge_vertex_parser.hpp +++ b/src/Mod/Assembly/App/opendcm/moduleState/edge_vertex_parser.hpp @@ -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 #include "opendcm/core/clustergraph.hpp" #include "extractor.hpp" diff --git a/src/Mod/Assembly/App/opendcm/moduleState/edge_vertex_parser_imp.hpp b/src/Mod/Assembly/App/opendcm/moduleState/edge_vertex_parser_imp.hpp index 8b43333a0..c295b162f 100644 --- a/src/Mod/Assembly/App/opendcm/moduleState/edge_vertex_parser_imp.hpp +++ b/src/Mod/Assembly/App/opendcm/moduleState/edge_vertex_parser_imp.hpp @@ -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::edge_parser() : edge_parser::base_type(edge) { >> objects(qi::_r1)[phx::at_c<0>(qi::_val) = qi::_1] >> ""; edge = (qi::lit("> "source=" >> qi::int_ >> "target=" >> qi::int_ >> '>')[qi::_val = phx::bind((&Sys::Cluster::addEdgeGlobal), qi::_r1, qi::_1, qi::_2)] - >> edge_prop[phx::bind(&Injector::setEdgeProperties, in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)] - >> *global_edge(qi::_r2) + >> edge_prop[phx::bind(&Injector::setEdgeProperties, &in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)] + >> (*global_edge(qi::_r2))[phx::bind(&Injector::setEdgeBundles, &in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)] >> (""); }; template vertex_parser::vertex_parser() : vertex_parser::base_type(vertex) { - vertex = qi::lit("::addVertex, in, qi::_r1, qi::_val)] >> qi::lit("id=") + vertex = qi::lit("::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::setVertexProperties, in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)] - >> objects(qi::_r2)[phx::bind(&Injector::setVertexObjects, in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)] + >> '>' >> prop[phx::bind(&Injector::setVertexProperties, &in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)] + >> objects(qi::_r2)[phx::bind(&Injector::setVertexObjects, &in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)] >> (""); }; diff --git a/src/Mod/Assembly/App/opendcm/moduleState/extractor.hpp b/src/Mod/Assembly/App/opendcm/moduleState/extractor.hpp index 7d2e4ed7c..ad740c7b7 100644 --- a/src/Mod/Assembly/App/opendcm/moduleState/extractor.hpp +++ b/src/Mod/Assembly/App/opendcm/moduleState/extractor.hpp @@ -96,12 +96,20 @@ struct Injector { typename details::pts::type& prop) { fusion::at_c<0>(cluster->operator[](e)) = prop; }; + void setEdgeBundles(typename Sys::Cluster* cluster, LocalEdge e, + std::vector& bundles) { + fusion::at_c<1>(cluster->operator[](e)) = bundles; + }; void setVertexProperty(typename Sys::Cluster* cluster, int value) { cluster->template setClusterProperty(value); }; - void addCluster(typename Sys::Cluster* cluster, typename Sys::Cluster* addcl) { - LocalVertex v = cluster->getLocalVertex(addcl->template getClusterProperty()).first; - cluster->m_clusters[v] = boost::shared_ptr(addcl); + void addClusters(std::vector& clusters, typename Sys::Cluster* cluster) { + + typename std::vector::iterator it; + for(it = clusters.begin(); it != clusters.end(); it++) { + LocalVertex v = cluster->getLocalVertex((*it)->template getClusterProperty()).first; + cluster->m_clusters[v] = boost::shared_ptr(*it); + }; }; void addVertex(typename Sys::Cluster* cluster, fusion::vector& vec) { vec = cluster->addVertex(); diff --git a/src/Mod/Assembly/App/opendcm/moduleState/generator.hpp b/src/Mod/Assembly/App/opendcm/moduleState/generator.hpp index ab77c556c..d55d2c83d 100644 --- a/src/Mod/Assembly/App/opendcm/moduleState/generator.hpp +++ b/src/Mod/Assembly/App/opendcm/moduleState/generator.hpp @@ -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" diff --git a/src/Mod/Assembly/App/opendcm/moduleState/generator_imp.hpp b/src/Mod/Assembly/App/opendcm/moduleState/generator_imp.hpp index f258c065b..f7bb6bc6b 100644 --- a/src/Mod/Assembly/App/opendcm/moduleState/generator_imp.hpp +++ b/src/Mod/Assembly/App/opendcm/moduleState/generator_imp.hpp @@ -22,7 +22,6 @@ #include "generator.hpp" #include "opendcm/core/clustergraph.hpp" -//#include "karma_trans.hpp" #include #include @@ -53,10 +52,12 @@ namespace dcm { template generator::generator() : generator::base_type(start) { - cluster %= karma::omit[karma::int_] << cluster_prop << -vertex_range[phx::bind(&Extractor::getVertexRange, ex, karma::_val, karma::_1)] - << -karma::buffer["\n" << edge_range[phx::bind(&Extractor::getEdgeRange, ex, karma::_val, karma::_1)]] - << -karma::buffer["\n" << (cluster_pair % karma::eol)[phx::bind(&Extractor::getClusterRange, ex, karma::_val, karma::_1)]] << "-\n" - << ""; + cluster %= karma::omit[karma::int_] << cluster_prop + << -karma::buffer[karma::eol << (cluster_pair % karma::eol)[phx::bind(&Extractor::getClusterRange, &ex, karma::_val, karma::_1)]] + << -vertex_range[phx::bind(&Extractor::getVertexRange, &ex, karma::_val, karma::_1)] + << -karma::buffer[karma::eol << edge_range[phx::bind(&Extractor::getEdgeRange, &ex, karma::_val, karma::_1)]] + << "-" << karma::eol + << karma::lit(""); cluster_pair %= karma::lit("+" << karma::attr_cast(cluster); diff --git a/src/Mod/Assembly/App/opendcm/moduleState/module.hpp b/src/Mod/Assembly/App/opendcm/moduleState/module.hpp index c3a3a4d13..c6760c371 100644 --- a/src/Mod/Assembly/App/opendcm/moduleState/module.hpp +++ b/src/Mod/Assembly/App/opendcm/moduleState/module.hpp @@ -27,9 +27,6 @@ #include "parser.hpp" #include "defines.hpp" -#include -#include - namespace qi = boost::spirit::qi; namespace dcm { diff --git a/src/Mod/Assembly/App/opendcm/moduleState/object_generator.hpp b/src/Mod/Assembly/App/opendcm/moduleState/object_generator.hpp index 85a50bb99..9c42fd515 100644 --- a/src/Mod/Assembly/App/opendcm/moduleState/object_generator.hpp +++ b/src/Mod/Assembly/App/opendcm/moduleState/object_generator.hpp @@ -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; diff --git a/src/Mod/Assembly/App/opendcm/moduleState/object_generator_imp.hpp b/src/Mod/Assembly/App/opendcm/moduleState/object_generator_imp.hpp index 1114f19e8..df6491e46 100644 --- a/src/Mod/Assembly/App/opendcm/moduleState/object_generator_imp.hpp +++ b/src/Mod/Assembly/App/opendcm/moduleState/object_generator_imp.hpp @@ -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; diff --git a/src/Mod/Assembly/App/opendcm/moduleState/object_parser.hpp b/src/Mod/Assembly/App/opendcm/moduleState/object_parser.hpp index ab4525865..a2d669c34 100644 --- a/src/Mod/Assembly/App/opendcm/moduleState/object_parser.hpp +++ b/src/Mod/Assembly/App/opendcm/moduleState/object_parser.hpp @@ -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 -struct empty_obj_parser : public qi::grammar(Sys*), qi::space_type> { - qi::rule(Sys*), qi::space_type> start; - empty_obj_parser(): empty_obj_parser::base_type(start) { - //start = qi::eps(false); -}; -}; - //grammar for a single object -template -struct obj_parser : public qi::grammar(Sys*), qi::space_type> { +template +struct obj_parser : public qi::grammar::type*, Sys*), qi::space_type> { typename Par::parser subrule; - qi::rule(Sys*), qi::space_type> start; + qi::rule::type*, Sys*), qi::space_type> start; prop_par prop; obj_parser(); @@ -52,8 +48,8 @@ template struct obj_parser_fold : mpl::fold< seq, state, mpl::if_< parser_parse, mpl::push_back > >, - mpl::push_back > > > {}; + obj_parser > >, + mpl::_1 > > {}; //currently max. 10 objects are supported template @@ -61,28 +57,19 @@ struct obj_par : public qi::grammar::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 >::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::type, Sys> >::type rules_vector; + //create a vector with the appropriate rules for all needed objects. + typedef typename obj_parser_fold >::type sub_rules_sequence; + //the type of the objectlist rule + typedef qi::rule::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 >::type parent_rules_sequence; - //create the fusion sequence of our rules - typedef typename fusion::result_of::as_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 - struct index : public mpl::if_< mpl::less, mpl::size >, - mpl::int_, typename mpl::size::prior >::type {}; - //this struct tells us if we should execute the generator - template - struct valid : public mpl::less< mpl::int_, mpl::size > {}; - - rules_sequnce rules; + typename fusion::result_of::as_vector::type sub_rules; + typename fusion::result_of::as_vector::type parent_rules; + qi::rule::type(Sys*), qi::space_type> obj; obj_par(); diff --git a/src/Mod/Assembly/App/opendcm/moduleState/object_parser_imp.hpp b/src/Mod/Assembly/App/opendcm/moduleState/object_parser_imp.hpp index 4ee602761..268979c5f 100644 --- a/src/Mod/Assembly/App/opendcm/moduleState/object_parser_imp.hpp +++ b/src/Mod/Assembly/App/opendcm/moduleState/object_parser_imp.hpp @@ -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 boost::enable_if >, void >::type recursive_obj_init( srs& sseq, prs& pseq ) { + + if(dist::value == 0) { + fusion::at(pseq) %= fusion::at(sseq)(qi::_r1, qi::_r2); + } + else { + fusion::at(pseq) %= fusion::at >::type >::type>(pseq)(qi::_r1, qi::_r2) | fusion::at(sseq)(qi::_r1, qi::_r2); + } + + recursive_obj_init::type>(sseq, pseq); +}; -template -obj_parser::obj_parser(): obj_parser::base_type(start) { +template +typename boost::disable_if >, void >::type recursive_obj_init( srs& sseq, prs& pseq ){}; + + +template +obj_parser::obj_parser(): obj_parser::base_type(start) { + + typedef typename mpl::find::type::pos pos; + Par::init(subrule); - start = qi::lit("") >> subrule(qi::_r1)[qi::_val = qi::_1] - >> qi::eps(qi::_val)[ phx::bind(&Sys::template push_back, qi::_r1, qi::_val)] - >> prop[phx::bind(&obj_parser::setProperties, qi::_val, qi::_1)] + start = qi::lit("") >> subrule(qi::_r2)[phx::at_c(*qi::_r1) = qi::_1] + >> qi::eps(phx::at_c(*qi::_r1))[ phx::bind(&Sys::template push_back, qi::_r2, phx::at_c(*qi::_r1))] + >> prop[phx::bind(&obj_parser::setProperties, phx::at_c(*qi::_r1), qi::_1)] >> qi::lit(""); }; -template -void obj_parser::setProperties(boost::shared_ptr ptr, typename details::pts::type& seq) { +template +void obj_parser::setProperties(boost::shared_ptr ptr, typename details::pts::type& seq) { if(ptr) ptr->m_properties = seq; }; template obj_par::obj_par(): obj_par::base_type(obj) { - - obj = -(qi::eps(valid<0>::value) >> fusion::at >(rules)(qi::_r1)[phx::at_c::value>(qi::_val) = qi::_1]) - >> -(qi::eps(valid<1>::value) >> fusion::at >(rules)(qi::_r1)[phx::at_c::value>(qi::_val) = qi::_1]) - >> -(qi::eps(valid<2>::value) >> fusion::at >(rules)(qi::_r1)[phx::at_c::value>(qi::_val) = qi::_1]) - >> -(qi::eps(valid<3>::value) >> fusion::at >(rules)(qi::_r1)[phx::at_c::value>(qi::_val) = qi::_1]) - >> -(qi::eps(valid<4>::value) >> fusion::at >(rules)(qi::_r1)[phx::at_c::value>(qi::_val) = qi::_1]) - >> -(qi::eps(valid<5>::value) >> fusion::at >(rules)(qi::_r1)[phx::at_c::value>(qi::_val) = qi::_1]) - >> -(qi::eps(valid<6>::value) >> fusion::at >(rules)(qi::_r1)[phx::at_c::value>(qi::_val) = qi::_1]) - >> -(qi::eps(valid<7>::value) >> fusion::at >(rules)(qi::_r1)[phx::at_c::value>(qi::_val) = qi::_1]) - >> -(qi::eps(valid<8>::value) >> fusion::at >(rules)(qi::_r1)[phx::at_c::value>(qi::_val) = qi::_1]) - >> -(qi::eps(valid<9>::value) >> fusion::at >(rules)(qi::_r1)[phx::at_c::value>(qi::_val) = qi::_1]); - + + recursive_obj_init::type, + typename fusion::result_of::as_vector::type, + mpl::int_<0> >(sub_rules, parent_rules); + + obj = *(fusion::back(parent_rules)(&qi::_val, qi::_r1)); }; }//details diff --git a/src/Mod/Assembly/App/opendcm/moduleState/parser.hpp b/src/Mod/Assembly/App/opendcm/moduleState/parser.hpp index 1ff58c444..291e8c582 100644 --- a/src/Mod/Assembly/App/opendcm/moduleState/parser.hpp +++ b/src/Mod/Assembly/App/opendcm/moduleState/parser.hpp @@ -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 #include @@ -55,13 +59,13 @@ static void print(std::string s) { }; template -struct parser : qi::grammar, qi::space_type> { +struct parser : qi::grammar >, qi::space_type> { typedef typename Sys::Cluster graph; parser(); - qi::rule, qi::space_type> cluster; + qi::rule >, qi::space_type> cluster; details::cluster_prop_par cluster_prop; details::obj_par objects; diff --git a/src/Mod/Assembly/App/opendcm/moduleState/parser_imp.hpp b/src/Mod/Assembly/App/opendcm/moduleState/parser_imp.hpp index 6b9f42b81..605c50664 100644 --- a/src/Mod/Assembly/App/opendcm/moduleState/parser_imp.hpp +++ b/src/Mod/Assembly/App/opendcm/moduleState/parser_imp.hpp @@ -59,11 +59,14 @@ parser::parser() : parser::base_type(cluster) { cluster %= qi::lit("" >> -(qi::eps( qi::_a > 0 )[qi::_val = phx::new_()]) - >> qi::eps[phx::bind(&Injector::setVertexProperty, in, qi::_val, qi::_a)] + >> qi::eps[phx::bind(&Sys::Cluster::setCopyMode, qi::_val, true)] + >> qi::eps[phx::bind(&Injector::setVertexProperty, &in, qi::_val, qi::_a)] >> qi::attr_cast(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::addCluster, in, qi::_val, qi::_1)])] + >> qi::eps[phx::bind(&Injector::addClusters, &in, qi::_b, qi::_val)] + >> qi::eps[phx::bind(&Sys::Cluster::setCopyMode, qi::_val, false)] >> "";// >> str[&sp::print]; }; diff --git a/src/Mod/Assembly/App/opendcm/moduleState/property_generator.hpp b/src/Mod/Assembly/App/opendcm/moduleState/property_generator.hpp index 5637679a6..005aefc3f 100644 --- a/src/Mod/Assembly/App/opendcm/moduleState/property_generator.hpp +++ b/src/Mod/Assembly/App/opendcm/moduleState/property_generator.hpp @@ -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 #include @@ -21,7 +25,7 @@ typedef std::ostream_iterator Iterator; namespace details { -//a grammar that does nothing exept failing +//a grammar that does nothing returns true struct empty_grammar : public karma::grammar { karma::rule start; empty_grammar(): empty_grammar::base_type(start) { diff --git a/src/Mod/Assembly/App/opendcm/moduleState/property_parser.hpp b/src/Mod/Assembly/App/opendcm/moduleState/property_parser.hpp index 6e404bfa8..be8956505 100644 --- a/src/Mod/Assembly/App/opendcm/moduleState/property_parser.hpp +++ b/src/Mod/Assembly/App/opendcm/moduleState/property_parser.hpp @@ -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 #include #include @@ -40,28 +44,11 @@ typedef boost::spirit::istream_iterator IIterator; namespace details { -struct empty_parser : public qi::grammar { - qi::rule start; - empty_parser(): empty_parser::base_type(start) { - start = qi::eps(true); - }; - empty_parser(const empty_parser& other) : empty_parser::base_type(start) {}; -}; - -template -struct skip_parser : public qi::grammar { - qi::rule start; - skip_parser() : skip_parser::base_type(start) { - start = qi::eps(true); - }; - skip_parser(const skip_parser& other) : skip_parser::base_type(start) {}; -}; - -template -struct prop_parser : qi::grammar { +template +struct prop_parser : qi::grammar::type*), qi::space_type> { typename Par::parser subrule; - qi::rule start; + qi::rule::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 struct prop_parser_fold : mpl::fold< seq, state, mpl::if_< dcm::parser_parse, - mpl::push_back > >, - mpl::push_back > > > {}; + mpl::push_back > >, + mpl::_1 > > {}; //grammar for a fusion sequence of properties. currently max. 10 properties are supported template struct prop_par : qi::grammar::type(), qi::space_type> { - //create a vector with the appropriate rules for all properties. - typedef typename prop_parser_fold >::type init_rules_sequence; - //allow max 10 types as the following code expect this - BOOST_MPL_ASSERT((mpl::less_equal< mpl::size, 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, mpl::size >::value > range; - typedef typename mpl::fold< range, - init_rules_sequence, - mpl::push_back >::type rules_sequence; + //create a vector with the appropriate rules for all needed properties. + typedef typename prop_parser_fold >::type sub_rules_sequence; + //the type of the propertylist rule + typedef qi::rule::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 >::type parent_rules_sequence; - typename fusion::result_of::as_vector::type rules; + typename fusion::result_of::as_vector::type sub_rules; + typename fusion::result_of::as_vector::type parent_rules; + qi::rule::type(), qi::space_type> prop; prop_par(); diff --git a/src/Mod/Assembly/App/opendcm/moduleState/property_parser_imp.hpp b/src/Mod/Assembly/App/opendcm/moduleState/property_parser_imp.hpp index 4fa920c8d..d1ecc14f6 100644 --- a/src/Mod/Assembly/App/opendcm/moduleState/property_parser_imp.hpp +++ b/src/Mod/Assembly/App/opendcm/moduleState/property_parser_imp.hpp @@ -21,6 +21,8 @@ #define DCM_PROPERTY_PARSER_IMP_H #include "property_parser.hpp" +#include +#include namespace dcm { @@ -28,21 +30,40 @@ namespace dcm { typedef boost::spirit::istream_iterator IIterator; namespace details { - -template -prop_parser::prop_parser() : prop_parser::base_type(start) { - Par::init(subrule); - start %= qi::lit("") >> subrule >> qi::lit(""); + +template +typename boost::enable_if >, void >::type recursive_init( srs& sseq, prs& pseq ) { + + if(dist::value == 0) { + fusion::at(pseq) %= fusion::at(sseq)(qi::_r1); + } + else { + fusion::at(pseq) %= fusion::at >::type >::type>(pseq)(qi::_r1) | fusion::at(sseq)(qi::_r1); + } + + recursive_init::type>(sseq, pseq); }; +template +typename boost::disable_if >, void >::type recursive_init( srs& sseq, prs& pseq ){}; + +template +prop_parser::prop_parser() : prop_parser::base_type(start) { + + typedef typename mpl::find::type::pos pos; + + Par::init(subrule); + start = qi::lit("") >> subrule[phx::at_c(*qi::_r1) = qi::_1] >> qi::lit(""); +}; template prop_par::prop_par() : prop_par::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::type, + typename fusion::result_of::as_vector::type, + mpl::int_<0> >(sub_rules, parent_rules); + + prop = *(fusion::back(parent_rules)(&qi::_val)); }; template diff --git a/src/Mod/Assembly/App/opendcm/moduleState/traits.hpp b/src/Mod/Assembly/App/opendcm/moduleState/traits.hpp index 94c4a9b4a..c14efd4a6 100644 --- a/src/Mod/Assembly/App/opendcm/moduleState/traits.hpp +++ b/src/Mod/Assembly/App/opendcm/moduleState/traits.hpp @@ -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 #include diff --git a/src/Mod/Assembly/App/opendcm/moduleState/traits_impl.hpp b/src/Mod/Assembly/App/opendcm/moduleState/traits_impl.hpp index bb49a7eb9..03c8ff8e7 100644 --- a/src/Mod/Assembly/App/opendcm/moduleState/traits_impl.hpp +++ b/src/Mod/Assembly/App/opendcm/moduleState/traits_impl.hpp @@ -113,7 +113,7 @@ struct parser_parser { typedef qi::rule parser; static void init(parser& r) { - r = qi::lit("clusterchanged") >> ("") >> qi::bool_ >>""; + r = qi::lit("clusterchanged") >> ("") >> qi::bool_ >>"" ; }; }; diff --git a/src/Mod/Assembly/App/opendcm/modulestate.hpp b/src/Mod/Assembly/App/opendcm/modulestate.hpp index ace674aca..295eb2968 100644 --- a/src/Mod/Assembly/App/opendcm/modulestate.hpp +++ b/src/Mod/Assembly/App/opendcm/modulestate.hpp @@ -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"