00001 #ifndef OPENTISSUE_DYNAMICS_MBD_MBD_EDGE_H 00002 #define OPENTISSUE_DYNAMICS_MBD_MBD_EDGE_H 00003 // 00004 // OpenTissue Template Library 00005 // - A generic toolbox for physics-based modeling and simulation. 00006 // Copyright (C) 2008 Department of Computer Science, University of Copenhagen. 00007 // 00008 // OTTL is licensed under zlib: http://opensource.org/licenses/zlib-license.php 00009 // 00010 #include <OpenTissue/configuration.h> 00011 00012 namespace OpenTissue 00013 { 00014 namespace mbd 00015 { 00016 template< typename mbd_types > 00017 class Edge 00018 : public mbd_types::edge_traits 00019 { 00020 public: 00021 00022 typedef typename mbd_types::math_policy::index_type size_type; 00023 typedef typename mbd_types::body_type body_type; 00024 typedef typename mbd_types::edge_type edge_type; 00025 typedef typename mbd_types::material_type material_type; 00026 typedef typename mbd_types::contact_iterator contact_iterator; 00027 typedef typename mbd_types::const_contact_iterator const_contact_iterator; 00028 00029 protected: 00030 00031 typedef typename mbd_types::contact_container contact_container; 00032 typedef typename mbd_types::collision_detection_policy collision_detection_policy; 00033 00034 protected: 00035 00036 body_type * m_A; 00037 body_type * m_B; 00038 contact_container m_contacts; 00039 00040 bool m_prunned; 00041 00042 public: 00043 00044 material_type * m_material; 00045 bool m_relative_resting; 00046 00047 00048 00049 00050 00051 00052 00053 size_type m_updated_time_stamp; 00054 00055 00056 00057 00058 collision_detection_policy * m_collision_detection; 00059 00060 public: 00061 00062 body_type const * get_body_A() const { return m_A; } 00063 body_type * get_body_A() { return m_A; } 00064 00065 body_type const * get_body_B() const { return m_B; } 00066 body_type * get_body_B() { return m_B; } 00067 00068 contact_iterator contact_begin() { return contact_iterator(m_contacts.begin()); } 00069 contact_iterator contact_end() { return contact_iterator(m_contacts.end()); } 00070 const_contact_iterator contact_begin() const { return const_contact_iterator(m_contacts.begin()); } 00071 const_contact_iterator contact_end() const { return const_contact_iterator(m_contacts.end()); } 00072 00073 size_type size_contacts() const { return m_contacts.size(); } 00074 00075 contact_container * get_contacts() { return &m_contacts; } 00076 material_type const * get_material() const { return m_material; } 00077 material_type * get_material() { return m_material; } 00078 00079 public: 00080 00081 Edge() 00082 : m_prunned(false) 00083 {} 00084 00085 virtual ~Edge(){} 00086 00087 public: 00088 00089 00095 bool & prunned() { return m_prunned; } 00096 bool const & prunned() const { return m_prunned; } 00097 00098 void init(body_type * const body_A, body_type * const body_B) 00099 { 00100 assert(body_A || !"Edge::init(): body A was null"); 00101 assert(body_B || !"Edge::init(): body A was null"); 00102 if(body_A->get_index() < body_B->get_index()) 00103 { 00104 m_A = const_cast<body_type*>(body_A); 00105 m_B = const_cast<body_type*>(body_B); 00106 } 00107 else 00108 { 00109 m_A = const_cast<body_type*>(body_B); 00110 m_B = const_cast<body_type*>(body_A); 00111 } 00112 00113 m_material = 0; 00114 m_contacts.clear(); 00115 m_relative_resting = false; 00116 m_updated_time_stamp = 0; 00117 m_collision_detection = 0; 00118 } 00119 00120 bool operator==(edge_type const & edge) const 00121 { 00122 assert(m_A || !"Edge::operator==(): body A was null"); 00123 assert(m_B || !"Edge::operator==(): body B was null"); 00124 assert(edge.m_A || !"Edge::operator==(): body A on edge was null"); 00125 assert(edge.m_B || !"Edge::operator==(): body B on edge was null"); 00126 return (m_A==edge.m_A && m_B==edge.m_B)? true : false; 00127 } 00128 bool operator!=(edge_type const & edge) const { return !(*this==edge); } 00129 00130 bool operator<(edge_type const & edge)const 00131 { 00132 assert(m_A || !"Edge::operator<(): body A was null"); 00133 assert(m_B || !"Edge::operator<(): body B was null"); 00134 assert(edge.m_A || !"Edge::operator<(): body A on edge was null"); 00135 assert(edge.m_B || !"Edge::operator<(): body B on edge was null"); 00136 00137 if(m_A<edge.m_A && m_B<edge.m_B) 00138 return true; 00139 if(m_A==edge.m_A && m_B<edge.m_B) 00140 return true; 00141 return false; 00142 } 00143 00144 size_type hash_key() const { return edge_type::hash_key(m_A,m_B); } 00145 00155 static size_type hash_key(body_type const * A,body_type const * B) 00156 { 00157 assert(A || !"Edge::hash_key(): body A was null"); 00158 assert(B || !"Edge::hash_key(): body B was null"); 00159 assert(A->get_index()!=B->get_index() || !"Edge::hash_key(): index of A and B were the same"); 00160 00161 if(A->get_index()<B->get_index()) 00162 return ((A->get_index()<<16)|(B->get_index()&0x0000FFFF)) ; 00163 return ((B->get_index()<<16)|(A->get_index()&0x0000FFFF)); 00164 } 00165 00172 bool is_up_to_date( ) const 00173 { 00174 assert(m_collision_detection || !"Edge::is_up_to_date(): collision detection pointer was null"); 00175 return (m_updated_time_stamp == m_collision_detection->get_time_stamp()); 00176 } 00177 00178 }; 00179 00180 } // namespace mbd 00181 } // namespace OpenTissue 00182 // OPENTISSUE_DYNAMICS_MBD_MBD_EDGE_H 00183 #endif