treat multiple assignment operator warning on msvc

This commit is contained in:
Stefan Tröger 2013-11-01 10:29:47 +01:00
parent 9b0d55bed8
commit dce4061ee6
10 changed files with 364 additions and 134 deletions

View File

@ -173,6 +173,11 @@ struct IDgen {
};
};
/**
* @brief Exception thrown from the graph at any occuring error
**/
struct cluster_error : virtual boost::exception {};
/**
* @brief Pointer type to share a common ID generator @ref IDgen
**/
@ -467,7 +472,8 @@ public:
* @param g the parent cluster graph
**/
ClusterGraph(boost::shared_ptr<ClusterGraph> g) : m_parent(g), m_id(new details::IDgen) {
if(g) m_id = g->m_id;
if(g)
m_id = g->m_id;
};
~ClusterGraph() {};
@ -741,7 +747,7 @@ public:
return (*it.first).first;
}
return LocalVertex();
throw details::cluster_error() << boost::errinfo_errno(12) << error_message("Cluster is not part of this graph");
};
/**
@ -785,7 +791,7 @@ public:
typename ClusterMap::iterator it = m_clusters.find(v);
if(it == m_clusters.end())
return; //TODO:throw
throw details::cluster_error() << boost::errinfo_errno(11) << error_message("Cluster is not part of this graph");
std::pair<LocalVertex, boost::shared_ptr<ClusterGraph> > res = *it;
@ -908,9 +914,11 @@ public:
boost::tie(e, done) = boost::edge(source, target, *this);
//if done=true the edge alredy existed
if(!done) boost::tie(e, done) = boost::add_edge(source, target, *this);
if(!done)
boost::tie(e, done) = boost::add_edge(source, target, *this);
if(!done) return fusion::make_vector(LocalEdge(), GlobalEdge(), false);
if(!done)
return fusion::make_vector(LocalEdge(), GlobalEdge(), false);
//init the bundle corecctly for new edge
GlobalEdge global = { fusion::at_c<0> ((*this) [source]), fusion::at_c<0> ((*this) [target]), m_id->generate() };
@ -948,7 +956,8 @@ public:
boost::tie(v2, d2) = getContainingVertex(target);
//if one vertex is not accessible from here this function fails
if(!(d1 && d2)) return fusion::make_vector(LocalEdge(), GlobalEdge(), false, false);
if(!(d1 && d2))
return fusion::make_vector(LocalEdge(), GlobalEdge(), false, false);
//if both vertices are in a subcluster this one must do the job as we cant access the local edge from here
if(v1 == v2 && isCluster(v1)) {
@ -960,9 +969,11 @@ public:
//check if we already have that Local edge
boost::tie(e, d3) = boost::edge(v1, v2, *this);
if(!d3) boost::tie(e, d3) = boost::add_edge(v1, v2, *this);
if(!d3)
boost::tie(e, d3) = boost::add_edge(v1, v2, *this);
if(!d3) return fusion::make_vector(LocalEdge(), GlobalEdge(), false, false);
if(!d3)
return fusion::make_vector(LocalEdge(), GlobalEdge(), false, false);
//init the bundle corectly for new edge
GlobalEdge global = { source, target, m_id->generate() };
@ -1111,11 +1122,14 @@ private:
bool operator()(edge_bundle_single& e) {
bool res;
//this predicate can be used to compare the edge itself or the vertives it connects. See
//if we are a relevant edge
if(isEdge)
res = (edge == fusion::at_c<1> (e));
else
res = (vert == fusion::at_c<1> (e).source) || (vert == fusion::at_c<1> (e).target);
//we are a hit, invoke the functor.
if(res || vert < 0)
func(fusion::at_c<1> (e));
@ -1133,8 +1147,11 @@ private:
std::pair<LocalVertex, bool> res = getContainingVertex(v);
//we don't throw, as this function gets invoked recursivly and it may happen that the
//vertex to remove is only in the top layers, not the button ones
if(!res.second)
return; //TODO:throw
return;
//iterate over every edge that connects to the global vertex or the cluster in which it is in
std::vector<LocalEdge> re; //remove edges
@ -1180,6 +1197,9 @@ public:
**/
template<typename Functor>
void removeVertex(LocalVertex id, Functor& f) {
//it is important to delete the global vertex, not the only local one as it's possible that
//we are in a subcluster and there are connections to the global vertex in the parent. They
//need to be deleted too.
removeVertex(getGlobalVertex(id), f);
};
//no default template arguments for template functions allowed before c++0x, so a little workaround
@ -1271,7 +1291,8 @@ protected:
typename boost::enable_if < boost::is_same<bundle, typename boost::vertex_bundle_type<Graph>::type>,
result_type >::type operator()(bundle& p) {
if(Type::value) fusion::for_each(fusion::at_c<2> (p), details::clear_ptr());
if(Type::value)
fusion::for_each(fusion::at_c<2> (p), details::clear_ptr());
return object_extractor<Obj>()(p);
}
@ -1287,7 +1308,8 @@ protected:
for(edge_single_iterator it = ebsv.begin(); it != ebsv.end(); it++) {
if(global_extractor()(*it) == m_key) {
if(Type::value) fusion::for_each(fusion::at_c<0> (*it), details::clear_ptr());
if(Type::value)
fusion::for_each(fusion::at_c<0> (*it), details::clear_ptr());
e = it;
break;
@ -1301,7 +1323,8 @@ protected:
template<typename bundle>
typename boost::enable_if < mpl::and_ < boost::is_same<bundle, typename boost::edge_bundle_type<Graph>::type>,
boost::is_same<key, LocalEdge> > , result_type >::type operator()(bundle& p) {
if(Type::value) fusion::for_each(fusion::at_c<0> (fusion::at_c<1> (p).front()), details::clear_ptr());
if(Type::value)
fusion::for_each(fusion::at_c<0> (fusion::at_c<1> (p).front()), details::clear_ptr());
return object_extractor<Obj>()(fusion::at_c<1> (p).front());
}
@ -1637,7 +1660,8 @@ public:
bool done;
boost::tie(e, done) = boost::edge(target, Cluster, *this);
if(!done) boost::tie(e, done) = boost::add_edge(target, Cluster, *this);
if(!done)
boost::tie(e, done) = boost::add_edge(target, Cluster, *this);
//if(!done) TODO: throw
@ -1680,7 +1704,8 @@ public:
bool done;
boost::tie(e, done) = boost::edge(nv, res.first, *cg);
if(!done) boost::tie(e, done) = boost::add_edge(nv, res.first, *cg);
if(!done)
boost::tie(e, done) = boost::add_edge(nv, res.first, *cg);
//if(!done) TODO: throw
@ -1747,8 +1772,10 @@ public:
GlobalVertex target;
//a bit cumbersome to allow cluster moving
if(parent()->getContainingVertex(global.source).first == nv) target = global.target;
else if(parent()->getContainingVertex(global.target).first == nv) target = global.source;
if(parent()->getContainingVertex(global.source).first == nv)
target = global.target;
else if(parent()->getContainingVertex(global.target).first == nv)
target = global.source;
else {
i++;
continue;
@ -1761,7 +1788,8 @@ public:
bool done;
boost::tie(e, done) = boost::edge(nv, res.first, *parent());
if(!done) boost::tie(e, done) = boost::add_edge(nv, res.first, *parent());
if(!done)
boost::tie(e, done) = boost::add_edge(nv, res.first, *parent());
//if(!done) TODO: throw
@ -1771,14 +1799,16 @@ public:
}
//see if we should destroy this edge (no global edges remain in local one)
if(vec.empty()) edge_vec.push_back(*it.first);
if(vec.empty())
edge_vec.push_back(*it.first);
}
//create a edge between new vertex and this cluster and add all global edges from within this cluster
it = boost::out_edges(v, *this);
LocalEdge e;
if(it.first != it.second) e = boost::add_edge(nv, this_v, *parent()).first;
if(it.first != it.second)
e = boost::add_edge(nv, this_v, *parent()).first;
for(; it.first != it.second; it.first++) {
std::vector<edge_bundle_single>& ep = fusion::at_c<1> ((*this) [*it.first]);
@ -1834,7 +1864,8 @@ protected:
for(cluster_iterator it = m_clusters.begin(); it != m_clusters.end(); it++) {
std::pair<LocalVertex, bool> res = ((*it).second)->getContainingVertex(id);
if(res.second) return std::make_pair((*it).first, true);
if(res.second)
return std::make_pair((*it).first, true);
}
}
@ -1850,11 +1881,13 @@ protected:
bool done;
boost::tie(v, done) = getContainingVertex(id);
if(!done) return fusion::make_vector(LocalVertex(), boost::shared_ptr<ClusterGraph>(), false);
if(!done)
return fusion::make_vector(LocalVertex(), boost::shared_ptr<ClusterGraph>(), false);
if(isCluster(v) && (getGlobalVertex(v) != id))
return m_clusters[v]->getContainingVertexGraph(id);
else return fusion::make_vector(v, sp_base::shared_from_this(), true);
else
return fusion::make_vector(v, sp_base::shared_from_this(), true);
};
/* Searches the global edge in all local edges of this graph, and returns the local
@ -1868,7 +1901,8 @@ protected:
boost::tie(v1, d1) = getContainingVertex(id.source, true);
boost::tie(v2, d2) = getContainingVertex(id.target, true);
if(!((d1 && d2) && (v1 != v2))) return std::make_pair(LocalEdge(), false);
if(!((d1 && d2) && (v1 != v2)))
return std::make_pair(LocalEdge(), false);
return boost::edge(v1, v2, *this);
};
@ -1883,9 +1917,11 @@ protected:
boost::tie(v1, d1) = getContainingVertex(id.source, true);
boost::tie(v2, d2) = getContainingVertex(id.target, true);
if(!(d1 && d2)) return fusion::make_vector(LocalEdge(), (ClusterGraph*) NULL, false);
if(!(d1 && d2))
return fusion::make_vector(LocalEdge(), (ClusterGraph*) NULL, false);
if(v1 == v2) return m_clusters[v1]->getContainingEdgeGraph(id);
if(v1 == v2)
return m_clusters[v1]->getContainingEdgeGraph(id);
return fusion::make_vector(boost::edge(v1, v2, *this).first, this, true);
};
@ -1935,7 +1971,8 @@ protected:
//TODO:Throw
}
if((v1 == v2) && isCluster(v1)) return m_clusters[v1]->apply_to_bundle(k, f);
if((v1 == v2) && isCluster(v1))
return m_clusters[v1]->apply_to_bundle(k, f);
else {
LocalEdge e;
bool done;

View File

@ -232,8 +232,10 @@ struct Equation : public EQ {
typename boost::enable_if<fusion::result_of::has_key<options, T>, Derived&>::type operator=(const T& val) {
return operator()(val);
};
//assign complete equation
Derived& operator=(const Derived& eq) {
//assign complete equation (we need to override the operator= in the derived class anyway as it
//is automaticly created by the compiler, so we use a different name here to avoid duplicate
//operator= warning on msvc)
Derived& assign(const Derived& eq) {
//we only copy the values which were set and are therefore valid
option_copy oc(values);
@ -303,7 +305,7 @@ struct print_pair {
template <typename charT, typename traits, typename Eq>
typename boost::enable_if<boost::is_base_of<EQ, Eq>, std::basic_ostream<charT,traits>&>::type
operator << (std::basic_ostream<charT,traits> & stream, const Eq& equation)
operator << (std::basic_ostream<charT,traits>& stream, const Eq& equation)
{
print_pair<charT, traits> pr;
pr.stream = &stream;
@ -323,7 +325,7 @@ struct Distance : public Equation<Distance, mpl::vector2<double, SolutionSpace>
//override needed ass assignmend operator is always created by the compiler
//and we need to ensure that our custom one is used
Distance& operator=(const Distance& d) {
return Equation::operator=(d);
return Equation::assign(d);
};
void setDefault() {
@ -397,7 +399,7 @@ struct Orientation : public Equation<Orientation, Direction, true> {
//override needed ass assignmend operator is always created by the compiler
//and we need to ensure that our custom one is used
Orientation& operator=(const Orientation& d) {
return Equation::operator=(d);
return Equation::assign(d);
};
void setDefault() {
@ -455,6 +457,7 @@ struct Orientation : public Equation<Orientation, Direction, true> {
struct Angle : public Equation<Angle, mpl::vector2<double, SolutionSpace>, true> {
using Equation::operator=;
Angle() : Equation() {
setDefault();
};
@ -462,7 +465,7 @@ struct Angle : public Equation<Angle, mpl::vector2<double, SolutionSpace>, true>
//override needed ass assignmend operator is always created by the compiler
//and we need to ensure that our custom one is used
Angle& operator=(const Angle& d) {
return Equation::operator=(d);
return Equation::assign(d);
};
void setDefault() {

View File

@ -21,7 +21,7 @@
#define GCM_OBJECT_H
#include <iostream>
#include <list>
#include <map>
#include <boost/mpl/at.hpp>
#include <boost/mpl/if.hpp>
@ -44,7 +44,6 @@
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/any.hpp>
#include "property.hpp"
@ -54,7 +53,7 @@ namespace fusion = boost::fusion;
/* Preprocessor implementation of emit signal. As we need many overloads with diffrent number of
* templated parameters we use boost preprocessor to do the hard repetive work. The definition and
* implementation are definded first as they need to be known before usage
* implementation are definded first as they need to be known before usage
* */
#define EMIT_ARGUMENTS(z, n, data) \
BOOST_PP_CAT(data, n)
@ -78,12 +77,14 @@ namespace fusion = boost::fusion;
BOOST_PP_ENUM_BINARY_PARAMS(n, Arg, const& arg) \
) \
{ \
typedef typename mpl::find<sig_name, S>::type iterator; \
typedef typename mpl::distance<typename mpl::begin<sig_name>::type, iterator>::type distance; \
typedef typename fusion::result_of::value_at<Signals, distance>::type list_type; \
list_type& list = fusion::at<distance>(m_signals); \
for (typename list_type::iterator it=list.begin(); it != list.end(); it++) \
(*it)(BOOST_PP_ENUM(n, EMIT_ARGUMENTS, arg)); \
if(m_emit_signals) {\
typedef typename mpl::find<sig_name, S>::type iterator; \
typedef typename mpl::distance<typename mpl::begin<sig_name>::type, iterator>::type distance; \
typedef typename fusion::result_of::value_at<Signals, distance>::type map_type; \
map_type& map = fusion::at<distance>(m_signals); \
for (typename map_type::iterator it=map.begin(); it != map.end(); it++) \
(it->second)(BOOST_PP_ENUM(n, EMIT_ARGUMENTS, arg)); \
}\
};
namespace dcm {
@ -98,10 +99,12 @@ namespace dcm {
//few standart signal names
struct remove {};
typedef boost::any Connection;
typedef int Connection;
template<typename SigMap>
struct SignalOwner {
SignalOwner();
/**
* @brief Connects a slot to a specified signal.
@ -130,9 +133,21 @@ struct SignalOwner {
template<typename S>
void disconnectSignal(Connection c);
/**
* @brief Enable or disable signal emittion
*
* If you want to supress all signals emitted by a object you can do this by calling this function.
* All calls to emitSignal() will be blocked until signals aer reenabled by using this function with
* onoff = true. Note that signals are not queued, if emitting is disabled all signals are lost.
*
* @param onoff bool value if signals shall be emitted or if they are disabled
*/
void enableSignals(bool onoff);
//with no vararg templates before c++11 we need preprocessor to create the overloads of emit signal we need
BOOST_PP_REPEAT(5, EMIT_CALL_DEF, ~)
protected:
/*signal handling
* extract all signal types to allow index search (inex search on signal functions would fail as same
@ -144,17 +159,19 @@ protected:
typedef typename mpl::fold < SigMap, mpl::vector<>,
mpl::push_back<mpl::_1, mpl::value_type<SigMap, mpl::_2> > >::type sig_functions;
typedef typename mpl::fold < sig_functions, mpl::vector<>,
mpl::push_back<mpl::_1, std::list<mpl::_2> > >::type sig_vectors;
mpl::push_back<mpl::_1, std::map<int, mpl::_2> > >::type sig_vectors;
typedef typename fusion::result_of::as_vector<sig_vectors>::type Signals;
Signals m_signals;
bool m_emit_signals;
int m_signal_count;
};
/**
* @brief Base class for all object types
*
* This class add's property and signal capabilitys to all deriving classes. For properties it is tigthly
* integrated with the system class: It searches systems property list for the derived class as specified by
* integrated with the system class: It searches systems property map for the derived class as specified by
* the second template parameter and makes it accessible via appopriate functions. Signals are speciefied by a
* mpl::map with signal name type as key and a boost::function as values.
*
@ -164,7 +181,7 @@ protected:
**/
template<typename Sys, typename Derived, typename Sig>
struct Object : public PropertyOwner<typename details::properties_by_object<typename Sys::properties, Derived>::type>,
public SignalOwner<Sig>,
public SignalOwner<Sig>,
boost::enable_shared_from_this<Derived> {
Object() {};
@ -204,15 +221,19 @@ boost::shared_ptr<Derived> Object<Sys, Derived, Sig>::clone(Sys& newSys)
return np;
};
template<typename SigMap>
SignalOwner<SigMap>::SignalOwner() : m_emit_signals(true), m_signal_count(0) {};
template<typename SigMap>
template<typename S>
Connection SignalOwner<SigMap>::connectSignal(typename mpl::at<SigMap, S>::type function)
{
typedef typename mpl::find<sig_name, S>::type iterator;
typedef typename mpl::distance<typename mpl::begin<sig_name>::type, iterator>::type distance;
typedef typename fusion::result_of::value_at<Signals, distance>::type list_type;
list_type& list = fusion::at<distance>(m_signals);
return list.insert(list.begin(), function);
typedef typename fusion::result_of::value_at<Signals, distance>::type map_type;
map_type& map = fusion::at<distance>(m_signals);
map[++m_signal_count] = function;
return m_signal_count;
};
template<typename SigMap>
@ -222,9 +243,15 @@ void SignalOwner<SigMap>::disconnectSignal(Connection c)
typedef typename mpl::find<sig_name, S>::type iterator;
typedef typename mpl::distance<typename mpl::begin<sig_name>::type, iterator>::type distance;
typedef typename fusion::result_of::value_at<Signals, distance>::type list_type;
list_type& list = fusion::at<distance>(m_signals);
list.erase(boost::any_cast<typename list_type::iterator>(c));
typedef typename fusion::result_of::value_at<Signals, distance>::type map_type;
map_type& map = fusion::at<distance>(m_signals);
map.erase(c);
};
template<typename SigMap>
void SignalOwner<SigMap>::enableSignals(bool onoff)
{
m_emit_signals = onoff;
};
BOOST_PP_REPEAT(5, EMIT_CALL_DEC, ~)

View File

@ -38,7 +38,7 @@ struct al_orientation : public Equation<al_orientation, Direction, true> {
};
al_orientation& operator=(const al_orientation& d) {
return Equation::operator=(d);
return Equation::assign(d);
};
void setDefault() {

View File

@ -37,7 +37,7 @@ struct ci_orientation : public Equation<ci_orientation, Direction, true> {
};
ci_orientation& operator=(const ci_orientation& d) {
return Equation::operator=(d);
return Equation::assign(d);
};
void setDefault() {
@ -193,7 +193,7 @@ struct ci_distance : public Equation<ci_distance, mpl::vector2<double, SolutionS
};
ci_distance& operator=(const ci_distance& d) {
return Equation::operator=(d);
return Equation::assign(d);
};
void setDefault() {

View File

@ -71,6 +71,7 @@ struct distance {
namespace dcm {
struct reset {}; //signal name
struct module3d_error : virtual boost::exception {}; //exception for all module3d special errors
template<typename Typelist, typename ID = No_Identifier>
struct Module3D {
@ -773,6 +774,9 @@ void Module3D<Typelist, ID>::type<Sys>::inheriter_id::removeGeometry3D(Identifie
if(hasGeometry3D(id))
inheriter_base::removeGeometry3D(getGeometry3D(id));
else
throw module3d_error() << boost::errinfo_errno(410) << error_message("no geometry with this ID in this system");
};
template<typename Typelist, typename ID>
@ -792,6 +796,8 @@ void Module3D<Typelist, ID>::type<Sys>::inheriter_id::removeConstraint3D(Identif
if(hasConstraint3D(id))
removeConstraint3D(getConstraint3D(id));
else
throw module3d_error() << boost::errinfo_errno(411) << error_message("no constraint with this ID in this system");
};

View File

@ -33,7 +33,6 @@ namespace details {
//this fixed equation
struct Fixed : public Equation<Orientation, Direction, true> {
using Equation::operator=;
using Equation::options;
Fixed() : Equation() {
setDefault();

View File

@ -43,6 +43,10 @@ struct ShapeGeneratorBase {
typedef typename module3d::Constraint3D Constraint3D;
typedef typename system_traits<Sys>::template getModule<details::mshape3d>::type moduleShape3d;
typedef typename moduleShape3d::Shape3D Shape3D;
typedef typename Shape3D::ShapeVector ShapeVector;
typedef typename Shape3D::GeometryVector GeometryVector;
typedef typename Shape3D::ConstraintVector ConstraintVector;
typedef typename moduleShape3d::shape_purpose_prop shape_purpose_prop;
typedef typename moduleShape3d::shape_geometry_prop shape_geometry_prop;
@ -50,17 +54,17 @@ struct ShapeGeneratorBase {
Sys* m_system;
boost::shared_ptr<Shape3D> m_shape;
std::vector<boost::shared_ptr<Geometry3D> >* m_geometries;
std::vector<boost::shared_ptr<Shape3D> >* m_shapes;
std::vector<boost::shared_ptr<Constraint3D> >* m_constraints;
GeometryVector* m_geometries;
ShapeVector* m_shapes;
ConstraintVector* m_constraints;
ShapeGeneratorBase(Sys* system) : m_system(system) {};
virtual ~ShapeGeneratorBase() {};
void set(boost::shared_ptr<Shape3D> shape,
std::vector<boost::shared_ptr<Geometry3D> >* geometries,
std::vector<boost::shared_ptr<Shape3D> >* shapes,
std::vector<boost::shared_ptr<Constraint3D> >* constraints) {
GeometryVector* geometries,
ShapeVector* shapes,
ConstraintVector* constraints) {
m_shape = shape;
m_geometries = geometries;
@ -76,6 +80,17 @@ struct ShapeGeneratorBase {
virtual boost::shared_ptr<Geometry3D> getOrCreateG3d(int type) = 0;
//get hlgeometry3d for optional types
virtual boost::shared_ptr<Shape3D> getOrCreateHLG3d(int type) = 0;
//append needs to be on this base class as the shape appends are protected
void append(boost::shared_ptr<Geometry3D> g) {
m_shape->append(g);
};
void append(boost::shared_ptr<Shape3D> g) {
m_shape->append(g);
};
void append(boost::shared_ptr<Constraint3D> g) {
m_shape->append(g);
};
};
} //details
@ -117,7 +132,7 @@ struct segment3D {
typedef typename Sys::Kernel Kernel;
using typename base::Geometry3D;
using typename base::Constraint3D;
using typename base::Shape3D;
using typename base::Shape3D;
type(Sys* system) : details::ShapeGeneratorBase<Sys>(system) {};
@ -141,17 +156,17 @@ struct segment3D {
//link the line geometrie to our shape
boost::shared_ptr<Geometry3D> g1 = base::m_system->createGeometry3D();
base::m_geometries->push_back(g1);
base::append(g1);
g1->template linkTo<tag::segment3D>(base::m_shape,0);
g1->template setProperty<typename base::shape_purpose_prop>(line);
g1->template connectSignal<recalculated>(boost::bind(&base::Shape3D::recalc, base::m_shape, _1));
g1->template connectSignal<recalculated>(boost::bind(&base::Shape3D::recalc, base::m_shape, _1));
//we have a segment, lets link the two points to it
boost::shared_ptr<Geometry3D> g2 = base::m_system->createGeometry3D();
base::m_geometries->push_back(g2);
base::append(g2);
g2->template setProperty<typename base::shape_purpose_prop>(startpoint);
boost::shared_ptr<Geometry3D> g3 = base::m_system->createGeometry3D();
base::m_geometries->push_back(g3);
base::append(g3);
g3->template setProperty<typename base::shape_purpose_prop>(endpoint);
//link the points to our new segment
@ -162,49 +177,52 @@ struct segment3D {
boost::shared_ptr<Constraint3D> c1 = base::m_system->createConstraint3D(g1,g2, details::fixed);
boost::shared_ptr<Constraint3D> c2 = base::m_system->createConstraint3D(g1,g3, details::fixed);
c1->disable(); //required by fixed constraint
base::append(c1);
c2->disable(); //requiered by fixed constraint
base::append(c2);
}
else
if(base::m_geometries->size() == 2) {
//we have two points, lets get them
boost::shared_ptr<Geometry3D> g1 = base::m_geometries->operator[](0);
boost::shared_ptr<Geometry3D> g2 = base::m_geometries->operator[](1);
else if(base::m_geometries->size() == 2) {
//we have two points, lets get them
boost::shared_ptr<Geometry3D> g1 = fusion::at_c<0>(base::m_geometries->operator[](0));
boost::shared_ptr<Geometry3D> g2 = fusion::at_c<0>(base::m_geometries->operator[](1));
//possibility 1: two points. we add a segment line an link the point in
if(g1->getGeometryType() == tag::weight::point::value || g2->getGeometryType() == tag::weight::point::value) {
//possibility 1: two points. we add a segment line an link the point in
if(g1->getGeometryType() == tag::weight::point::value || g2->getGeometryType() == tag::weight::point::value) {
g1->template setProperty<typename base::shape_purpose_prop>(startpoint);
g2->template setProperty<typename base::shape_purpose_prop>(endpoint);
g1->template setProperty<typename base::shape_purpose_prop>(startpoint);
g2->template setProperty<typename base::shape_purpose_prop>(endpoint);
//construct our segment value
typename Kernel::Vector val(6);
val.head(3) = g1->getValue();
val.tail(3) = g2->getValue();
//construct our segment value
typename Kernel::Vector val(6);
val.head(3) = g1->getValue();
val.tail(3) = g2->getValue();
//the shape is a segment
base::m_shape->template setValue<tag::segment3D>(val);
//the shape is a segment
base::m_shape->template setValue<tag::segment3D>(val);
//and create a segment geometry we use as line
boost::shared_ptr<Geometry3D> g3 = base::m_system->createGeometry3D();
base::m_geometries->push_back(g3);
g3->template linkTo<tag::segment3D>(base::m_shape,0);
g3->template setProperty<typename base::shape_purpose_prop>(line);
g3->template connectSignal<recalculated>(boost::bind(&base::Shape3D::recalc, base::m_shape, _1));
//and create a segment geometry we use as line
boost::shared_ptr<Geometry3D> g3 = base::m_system->createGeometry3D();
base::append(g3);
g3->template linkTo<tag::segment3D>(base::m_shape,0);
g3->template setProperty<typename base::shape_purpose_prop>(line);
g3->template connectSignal<recalculated>(boost::bind(&base::Shape3D::recalc, base::m_shape, _1));
//link the points to our new segment
g1->template linkTo<tag::point3D>(base::m_shape, 0);
g2->template linkTo<tag::point3D>(base::m_shape, 3);
//link the points to our new segment
g1->template linkTo<tag::point3D>(base::m_shape, 0);
g2->template linkTo<tag::point3D>(base::m_shape, 3);
//add the fix constraints to show our relation
boost::shared_ptr<Constraint3D> c1 = base::m_system->createConstraint3D(g1,g3, details::fixed);
boost::shared_ptr<Constraint3D> c2 = base::m_system->createConstraint3D(g1,g3, details::fixed);
c1->disable(); //required by fixed constraint
c2->disable(); //requiered by fixed constraint
//add the fix constraints to show our relation
boost::shared_ptr<Constraint3D> c1 = base::m_system->createConstraint3D(g1,g3, details::fixed);
boost::shared_ptr<Constraint3D> c2 = base::m_system->createConstraint3D(g1,g3, details::fixed);
c1->disable(); //required by fixed constraint
base::append(c1);
c2->disable(); //requiered by fixed constraint
base::append(c2);
}
else
throw creation_error() << boost::errinfo_errno(501) << error_message("Wrong geometries for segment construction");
};
}
else
throw creation_error() << boost::errinfo_errno(501) << error_message("Wrong geometries for segment construction");
};
};
//get geometry3d for optional types (e.g. midpoints)
virtual boost::shared_ptr<typename dcm::details::ShapeGeneratorBase<Sys>::Geometry3D> getOrCreateG3d(int type) {

View File

@ -191,7 +191,9 @@ struct ModuleShape3D {
struct inheriter_base;
struct Shape3D;
typedef mpl::map0<> ShapeSig;
typedef mpl::map2<
mpl::pair<remove, boost::function<void (boost::shared_ptr<Shape3D>) > >,
mpl::pair<remove, boost::function<void (boost::shared_ptr<Shape3D>) > > > ShapeSig;
template<typename Derived>
struct Shape3D_base : public details::Geometry<typename Sys::Kernel, 3, typename Sys::geometries>, public Object<Sys, Derived, ShapeSig > {
@ -235,34 +237,73 @@ struct ModuleShape3D {
virtual boost::shared_ptr<Derived> clone(Sys& newSys);
/*shape access functions*/
typedef typename std::vector<boost::shared_ptr<Geometry3D> >::const_iterator geometry3d_iterator;
typedef typename std::vector<boost::shared_ptr<Shape3D> >::const_iterator shape3d_iterator;
typedef typename std::vector<boost::shared_ptr<Constraint3D> >::const_iterator constraint3d_iterator;
/*shape access functions and extractors to mimic vector<> iterators*/
typedef std::vector<fusion::vector<boost::shared_ptr<Geometry3D>, Connection> > GeometryVector;
typedef std::vector<fusion::vector<boost::shared_ptr<Derived>, Connection> > ShapeVector;
typedef std::vector<fusion::vector<boost::shared_ptr<Constraint3D>, Connection> > ConstraintVector;
struct geom_extractor {
typedef boost::shared_ptr<Geometry3D> result_type;
template<typename T>
result_type operator()(T& pair) const {
return fusion::at_c<0>(pair);
};
};
struct shape_extractor {
typedef boost::shared_ptr<Shape3D> result_type;
template<typename T>
result_type operator()(T& pair) const {
return fusion::at_c<0>(pair);
};
};
struct cons_extractor {
typedef boost::shared_ptr<Constraint3D> result_type;
template<typename T>
result_type operator()(T& pair) const {
return fusion::at_c<0>(pair);
};
};
typedef boost::transform_iterator<geom_extractor, typename GeometryVector::const_iterator> geometry3d_iterator;
typedef boost::transform_iterator<shape_extractor, typename ShapeVector::iterator > shape3d_iterator;
typedef boost::transform_iterator<cons_extractor, typename ConstraintVector::iterator > constraint3d_iterator;
shape3d_iterator beginShape3D() {
return m_shapes.begin();
return boost::make_transform_iterator(m_shapes.begin(), shape_extractor());
};
shape3d_iterator endShape3D() {
return m_shapes.end();
return boost::make_transform_iterator(m_shapes.end(), shape_extractor());
};
geometry3d_iterator beginGeometry3D() {
return m_geometries.begin();
return boost::make_transform_iterator(m_geometries.begin(), geom_extractor());
};
geometry3d_iterator endGeometry3D() {
return m_geometries.end();
return boost::make_transform_iterator(m_geometries.end(), geom_extractor());
};
constraint3d_iterator beginConstraint3D() {
return m_constraints.begin();
return boost::make_transform_iterator(m_constraints.begin(), cons_extractor());
};
constraint3d_iterator endConstraint3D() {
return m_constraints.end();
constraint3d_iterator endConstraint3D() {
return boost::make_transform_iterator(m_constraints.end(), cons_extractor());
};
boost::shared_ptr<Geometry3D> geometry(purpose f);
template<typename T>
boost::shared_ptr<Shape3D> subshape();
//callbacks
void recalc(boost::shared_ptr<Geometry3D> g);
void remove(boost::shared_ptr<Geometry3D> g);
void remove(boost::shared_ptr<Derived> g);
void remove(boost::shared_ptr<Constraint3D> g);
private:
//we store all geometries, shapes and constraint which belong to this shape.
//Furthermore we store the remove connections, as we need to disconnect them later
GeometryVector m_geometries;
ShapeVector m_shapes;
ConstraintVector m_constraints;
protected:
#ifdef USE_LOGGING
@ -301,11 +342,7 @@ struct ModuleShape3D {
Variant m_geometry; //Variant holding the real geometry type
boost::shared_ptr< details::ShapeGeneratorBase<Sys> > m_generator;
using Object<Sys, Derived, mpl::map0<> >::m_system;
std::vector<boost::shared_ptr<Geometry3D> > m_geometries;
std::vector<boost::shared_ptr<Derived> > m_shapes;
std::vector<boost::shared_ptr<Constraint3D> > m_constraints;
using Object<Sys, Derived, ShapeSig>::m_system;
template<typename generator>
void initShape() {
@ -318,9 +355,14 @@ struct ModuleShape3D {
m_generator->init();
};
//disconnect all remove signals of stored geometry/shapes/constraints
void disconnectAll();
//the stroage is private, all things need to be added by this methods.
//this is used to ensure the proper event connections
boost::shared_ptr<Derived> append(boost::shared_ptr<Geometry3D> g);
boost::shared_ptr<Derived> append(boost::shared_ptr<Derived> g);
boost::shared_ptr<Derived> append(boost::shared_ptr<Constraint3D> g);
//override protected event functions to emit signals
void reset() {};
@ -370,6 +412,7 @@ struct ModuleShape3D {
friend struct details::SystemSolver<Sys>;
friend struct details::SystemSolver<Sys>::Rescaler;
friend struct inheriter_base;
friend struct details::ShapeGeneratorBase<Sys>;
public:
//the geometry class itself does not hold an aligned eigen object, but maybe the variant
@ -400,9 +443,11 @@ struct ModuleShape3D {
void removeShape3D(ID id);
bool hasShape3D(ID id);
boost::shared_ptr<Shape3D> getShape3D(ID id);
protected:
using inheriter_base::m_this;
using inheriter_base::removeShape3D;
protected:
using inheriter_base::m_this;
};
struct inheriter : public mpl::if_<boost::is_same<ID, No_Identifier>, inheriter_base, inheriter_id>::type {};
@ -507,7 +552,7 @@ template<typename Derived>
boost::shared_ptr<typename system_traits<Sys>::template getModule<details::m3d>::type::Geometry3D>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::geometry(purpose f) {
for(geometry3d_iterator it = m_geometries.begin(); it != m_geometries.end(); it++) {
for(geometry3d_iterator it = beginGeometry3D(); it != endGeometry3D(); it++) {
if((*it)->template getProperty<shape_purpose_prop>() == f)
return *it;
@ -520,8 +565,11 @@ template<typename Sys>
template<typename Derived>
boost::shared_ptr<Derived>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::append(boost::shared_ptr<Geometry3D> g) {
m_geometries.push_back(g);
g->template setProperty<shape_geometry_prop>(true);
Connection c = g->template connectSignal<dcm::remove>(boost::bind(static_cast<void (Shape3D_base::*)(boost::shared_ptr<Geometry3D>)>(&Shape3D_base::remove) , this, _1));
m_geometries.push_back(fusion::make_vector(g,c));
return ObjBase::shared_from_this();
};
@ -531,10 +579,42 @@ template<typename Sys>
template<typename Derived>
boost::shared_ptr<Derived>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::append(boost::shared_ptr<Derived> g) {
m_shapes.push_back(g);
Connection c = g->template connectSignal<dcm::remove>(boost::bind(static_cast<void (Shape3D_base::*)(boost::shared_ptr<Derived>)>(&Shape3D_base::remove) , this, _1));
m_shapes.push_back(fusion::make_vector(g,c));
return ObjBase::shared_from_this();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
boost::shared_ptr<Derived>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::append(boost::shared_ptr<Constraint3D> g) {
Connection c = g->template connectSignal<dcm::remove>(boost::bind(static_cast<void (Shape3D_base::*)(boost::shared_ptr<Constraint3D>)>(&Shape3D_base::remove) , this, _1));
m_constraints.push_back(fusion::make_vector(g,c));
return ObjBase::shared_from_this();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::disconnectAll() {
typename GeometryVector::iterator git;
for(git = m_geometries.begin(); git!=m_geometries.end(); git++)
fusion::at_c<0>(*git)->template disconnectSignal<dcm::remove>(fusion::at_c<1>(*git));
typename ShapeVector::iterator sit;
for(sit = m_shapes.begin(); sit!=m_shapes.end(); sit++)
fusion::at_c<0>(*sit)->template disconnectSignal<dcm::remove>(fusion::at_c<1>(*sit));
typename ConstraintVector::iterator cit;
for(cit = m_constraints.begin(); cit!=m_constraints.end(); cit++)
fusion::at_c<0>(*cit)->template disconnectSignal<dcm::remove>(fusion::at_c<1>(*cit));
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
@ -544,6 +624,63 @@ void ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::recalc(boost
Base::finishCalculation();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::remove(boost::shared_ptr<Geometry3D> g) {
//before we delete this shape by calling the system remove function, we need to remove
//this geometry as this would be deleted again by the system call and we would go into infinit recoursion
//get the vector object where the geometry is part of
typename GeometryVector::const_iterator it;
for(it=m_geometries.begin(); it!=m_geometries.end(); it++) {
if(fusion::at_c<0>(*it)==g)
break;
};
m_geometries.erase(std::remove(m_geometries.begin(), m_geometries.end(), *it), m_geometries.end());
ObjBase::m_system->removeShape3D(ObjBase::shared_from_this());
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::remove(boost::shared_ptr<Derived> g) {
//before we delete this shape by calling the system remove function, we need to remove
//this geometry as this would be deleted again by the system call and we would go into infinit recoursion
//get the vector object where the geometry is part of
typename ShapeVector::const_iterator it;
for(it=m_shapes.begin(); it!=m_shapes.end(); it++) {
if(fusion::at_c<0>(*it)==g)
break;
};
m_shapes.erase(std::remove(m_shapes.begin(), m_shapes.end(), *it), m_shapes.end());
ObjBase::m_system->removeShape3D(ObjBase::shared_from_this());
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::remove(boost::shared_ptr<Constraint3D> g) {
//before we delete this shape by calling the system remove function, we need to remove
//this geometry as this would be deleted again by the system call and we would go into infinit recoursion
//get the vector object where the geometry is part of
typename ConstraintVector::const_iterator it;
for(it=m_constraints.begin(); it!=m_constraints.end(); it++) {
if(fusion::at_c<0>(*it)==g)
break;
};
m_constraints.erase(std::remove(m_constraints.begin(), m_constraints.end(), *it), m_constraints.end());
ObjBase::m_system->removeShape3D(ObjBase::shared_from_this());
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
@ -636,20 +773,23 @@ template<typename Typelist, typename ID>
template<typename Sys>
void ModuleShape3D<Typelist, ID>::type<Sys>::inheriter_base::removeShape3D(boost::shared_ptr<Shape3D> g) {
//remove all constraints
typedef typename Shape3D::constraint3d_iterator cit;
for(cit it=g->constraint3dBegin(); it!=g->constraint3dEnd(); it++)
m_this->removeConstraint3D(*it);
//disconnect all shapes, geometries and constraints, as otherwise we would go into infinite
//recursion
g->disconnectAll();
//remove all constraints is unnessecary as they get removed together with the geometries
//remove all geometries
typedef typename Shape3D::geometry3d_iterator git;
for(git it=g->geometry3dBegin(); it!=g->geometry3dEnd(); it++)
for(git it=g->beginGeometry3D(); it!=g->endGeometry3D(); it++)
m_this->removeGeometry3D(*it);
//remove all subshapes
typedef typename Shape3D::shape3d_iterator sit;
for(sit it=g->shape3dBegin(); it!=g->shape3dEnd(); it++)
m_this->removeShape3D(*it);
/* TODO: find out why it iterates over a empty vector and crashs...
//remove all subshapes
typedef typename Shape3D::shape3d_iterator sit;
for(sit it=g->beginShape3D(); it!=g->endShape3D(); it++) {
m_this->removeShape3D(*it);
};*/
//emit remove shape signal bevore actually deleting it
g->template emitSignal<remove>(g);
@ -689,3 +829,4 @@ void ModuleShape3D<Typelist, ID>::type<Sys>::inheriter_id::removeShape3D(Identif
}//dcm
#endif //GCM_MODULE_SHAPE3D_H

View File

@ -92,4 +92,3 @@ struct ModuleState {