Go to the documentation of this file.00001 #ifndef OPENTISSUE_DYNAMICS_MBD_MBD_CONFIGURATION_H
00002 #define OPENTISSUE_DYNAMICS_MBD_MBD_CONFIGURATION_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/containers/containers_hash_map.h>
00013 #include <OpenTissue/utility/utility_map_data_iterator.h>
00014
00015 #include <boost/iterator/indirect_iterator.hpp>
00016
00017 namespace OpenTissue
00018 {
00019 namespace mbd
00020 {
00021
00022 template< typename mbd_types >
00023 class Configuration
00024 {
00025 public:
00026
00027 typedef typename mbd_types::body_type body_type;
00028 typedef typename mbd_types::edge_type edge_type;
00029 typedef typename mbd_types::material_library_type material_library_type;
00030 typedef typename mbd_types::math_policy::index_type size_type;
00031
00032 protected:
00033
00034 typedef typename mbd_types::math_policy::real_type real_type;
00035 typedef typename mbd_types::joint_type joint_type;
00036 typedef typename mbd_types::group_type group_type;
00037 typedef typename mbd_types::collision_detection_policy collision_detection_policy;
00038
00039
00040 typedef typename stdext::hash_map<size_type, body_type*> body_ptr_lut_type;
00041 typedef typename stdext::hash_map<size_type, joint_type*> joint_ptr_lut_type;
00042 typedef typename stdext::hash_map<size_type, edge_type> edge_lut_type;
00043
00044 protected:
00045
00046 collision_detection_policy * m_collision_detection;
00047 material_library_type * m_material_library;
00048 group_type m_all;
00049 body_ptr_lut_type m_bodies;
00050 joint_ptr_lut_type m_joints;
00051 edge_lut_type m_edges;
00052 real_type m_collision_envelope;
00053
00054 protected:
00055
00056 typedef OpenTissue::utility::map_data_iterator<typename body_ptr_lut_type::iterator> body_ptr_lut_iterator;
00057 typedef OpenTissue::utility::map_data_iterator<typename joint_ptr_lut_type::iterator> joint_ptr_lut_iterator;
00058
00059 public:
00060
00061 typedef boost::indirect_iterator<body_ptr_lut_iterator> body_iterator;
00062 typedef boost::indirect_iterator<joint_ptr_lut_iterator> joint_iterator;
00063 typedef OpenTissue::utility::map_data_iterator<typename edge_lut_type::iterator> edge_iterator;
00064
00065 body_iterator body_begin() { return body_iterator( body_ptr_lut_iterator(m_bodies.begin()) );}
00066 body_iterator body_end() { return body_iterator( body_ptr_lut_iterator(m_bodies.end() ) );}
00067
00068 edge_iterator edge_begin() { return edge_iterator( m_edges.begin() );}
00069 edge_iterator edge_end() { return edge_iterator( m_edges.end() );}
00070
00071 joint_iterator joint_begin() { return joint_iterator( joint_ptr_lut_iterator(m_joints.begin()) );}
00072 joint_iterator joint_end() { return joint_iterator( joint_ptr_lut_iterator(m_joints.end() ) );}
00073
00074 size_type size_bodies() const {return m_bodies.size(); }
00075
00076 public:
00077
00078 Configuration()
00079 : m_collision_detection(0)
00080 , m_material_library(0)
00081 , m_collision_envelope(0.01)
00082 {}
00083
00084 ~Configuration()
00085 {
00086 clear();
00087 }
00088
00089 public:
00090
00091 void set_material_library(material_library_type & library) { this->m_material_library = &library; }
00092
00093 material_library_type * get_material_library() const { return this->m_material_library; }
00094
00095 void set_collision_envelope(real_type const & value)
00096 {
00097 assert(value>0 || !"Configuration::set_collision_envelope(): envelope must be positive");
00098 m_collision_envelope = value;
00099 }
00100
00101 real_type const & get_collision_envelope() const { return m_collision_envelope; }
00102
00110 void connect(collision_detection_policy & collision_detection)
00111 {
00112 if(m_collision_detection)
00113 m_collision_detection->clear();
00114
00115 m_collision_detection = &collision_detection;
00116
00117 for(body_iterator body = body_begin();body!=body_end();++body)
00118 {
00119 m_collision_detection->add(&(*body));
00120 }
00121 }
00122
00123 public:
00124
00132 group_type * get_all_body_group()
00133 {
00134 m_all.clear();
00135 for(body_iterator body = body_begin();body!=body_end();++body)
00136 {
00137 if(body->is_active())
00138 m_all.m_bodies.push_back(&(*body));
00139 }
00140 return &m_all;
00141 }
00142
00143 bool add(body_type * body)
00144 {
00145 assert(body || !"Configuration::add(): body was null");
00146 assert(m_bodies.find(body->get_index())==m_bodies.end() || !"Configuration::add(): body was already in configuration");
00147
00148 m_bodies.insert( std::pair< size_type, body_type* >( body->get_index(), body ) );
00149
00150 if(m_collision_detection)
00151 m_collision_detection->add(body);
00152
00153 return true;
00154 }
00155
00156 bool remove(body_type * body)
00157 {
00158 assert(body || !"Configuration::remove(): body was null");
00159 assert(m_bodies.find(body->get_index())!=m_bodies.end() || !"Configuration::remove(): body was not in configuration");
00160
00161 if(body->has_joints())
00162 {
00163 std::cout << "Configuration::remove(): Remove all joints on body first" << std::endl;
00164 return false;
00165 }
00166
00167 while(!body->m_edges.empty())
00168 {
00169 edge_type * edge = body->m_edges.front();
00170 edge->get_body_A()->m_edges.remove(edge);
00171 edge->get_body_B()->m_edges.remove(edge);
00172 m_edges.erase(edge->hash_key());
00173 }
00174
00175 m_bodies.erase(body->get_index());
00176
00177 if(m_collision_detection)
00178 m_collision_detection->remove(body);
00179 return true;
00180 }
00181
00182 bool add(joint_type * joint)
00183 {
00184 assert(joint || !"Configuration::add(): Joint was null");
00185 assert(m_joints.find(joint->get_index())==m_joints.end() || !"Configuration::add(): Joint was already in configuration");
00186 if(joint->get_socket_A()==0)
00187 {
00188 std::cout << "Configuration::add(): Joint were missing socket A" << std::endl;
00189 return false;
00190 }
00191 if(joint->get_socket_A()->get_body()==0)
00192 {
00193 std::cout << "Configuration::add(): Joint socket A were missing a body" << std::endl;
00194 return false;
00195 }
00196 if(joint->get_socket_B()==0)
00197 {
00198 std::cout << "Configuration::add(): Joint were missing socket B" << std::endl;
00199 return false;
00200 }
00201 if(joint->get_socket_B()->get_body()==0)
00202 {
00203 std::cout << "Configuration::add(): Joint socket B were missing a body" << std::endl;
00204 return false;
00205 }
00206 typename body_ptr_lut_type::iterator itA = m_bodies.find(joint->get_socket_A()->get_body()->get_index());
00207 if(itA==m_bodies.end())
00208 {
00209 std::cout << "Configuration::add(): First add body on socket A" << std::endl;
00210 return false;
00211 }
00212 typename body_ptr_lut_type::iterator itB = m_bodies.find(joint->get_socket_B()->get_body()->get_index());
00213 if(itB==m_bodies.end())
00214 {
00215 std::cout << "Configuration::add(): First add body on socket B" << std::endl;
00216 return false;
00217 }
00218 m_joints.insert( std::pair< size_type, joint_type* >( joint->get_index(), joint ) );
00219 return true;
00220 }
00221
00222 bool remove(joint_type * joint)
00223 {
00224 assert(joint || !"Configuration::remove(): Joint was null");
00225 assert(m_joints.find(joint->get_index())!=m_joints.end() || !"Configuration::remove(): Joint was not in configuration");
00226 assert( !(joint->get_body_A()) || !"Configuration::remove(): Body A on joint was non-null");
00227 assert( !(joint->get_body_B()) || !"Configuration::remove(): Body B on joint was non-null");
00228
00229 m_joints.erase(joint->get_index());
00230
00231 return true;
00232 }
00233
00234 edge_type * get_edge(body_type * A,body_type * B)
00235 {
00236 assert(A || !"Configuration::get_edge(): body A was null");
00237 assert(B || !"Configuration::get_edge(): body B was null");
00238 assert(A!=B || !"Configuration::get_edge(): body A and B were the same");
00239
00240 typename edge_lut_type::iterator edge = m_edges.find(edge_type::hash_key(A,B));
00241 if(edge==m_edges.end())
00242 return 0;
00243 return &(edge->second);
00244 }
00245
00254 edge_type * add(body_type * A,body_type * B)
00255 {
00256 assert(A || !"Configuration::add(): body A was null");
00257 assert(B || !"Configuration::add(): body B was null");
00258 assert(A!=B || !"Configuration::add(): body A and B were the same");
00259 assert(m_material_library || !"Configuration::add(): Material library was null");
00260 assert(m_edges.find(edge_type::hash_key(A,B))==m_edges.end() || !"Configuration::add(): Edge allready existed in configuration");
00261 assert(m_collision_detection || !"Configuration::add(): Collision Detection was null");
00262
00263 std::pair<typename edge_lut_type::iterator,bool> result = m_edges.insert( std::make_pair(edge_type::hash_key(A,B),edge_type()) );
00264
00265 edge_type * edge = &(result.first->second);
00266 edge->init(A,B);
00267 edge->get_body_A()->m_edges.push_back(edge);
00268 edge->get_body_B()->m_edges.push_back(edge);
00269
00270 edge->m_material = m_material_library->get(A->get_material_idx(),B->get_material_idx());
00271
00272 if(!edge->m_material)
00273 {
00274 std::cout << "Configuration::add(): Could not find a material between ("<< A->get_material_idx() <<","<< B->get_material_idx() <<") using default material" << std::endl;
00275 edge->m_material = m_material_library->default_material();
00276 }
00277
00278 edge->m_collision_detection = m_collision_detection;
00279
00280 return edge;
00281 }
00282
00283 void remove(edge_type * edge)
00284 {
00285 assert(edge || !"Configuration::remove(): edge was null");
00286 assert(m_edges.find( edge->hash_key() )!=m_edges.end() || !"Configuration::remove(): edge was not in configuration");
00287
00288 edge->get_body_A()->m_edges.remove(edge);
00289 edge->get_body_B()->m_edges.remove(edge);
00290 m_edges.erase(edge->hash_key());
00291 }
00292
00293 void clear()
00294 {
00295 m_collision_detection = 0;
00296 m_material_library = 0;
00297
00298 while(!m_joints.empty())
00299 {
00300 typename joint_ptr_lut_type::iterator it = m_joints.begin();
00301 joint_type * joint = it->second;
00302 joint->clear();
00303 remove(joint);
00304 }
00305
00306 while(!m_bodies.empty())
00307 {
00308 typename body_ptr_lut_type::iterator it = m_bodies.begin();
00309 body_type * body = it->second;
00310 remove(body);
00311 body->clear();
00312 }
00313
00314 assert(m_bodies.empty() || !"Configuration::clear(): Internal error, not all bodies where removed?");
00315 assert(m_joints.empty() || !"Configuration::clear(): Internal error, not all joints where removed?");
00316
00317
00318
00319 assert(m_edges.empty() || !"Configuration::clear(): Internal error, not all edges where removed?");
00320 }
00321
00322 };
00323
00324 }
00325 }
00326
00327 #endif