Go to the documentation of this file.00001 #ifndef OPENTISSUE_DYNAMICS_PSYS_MASS_SPRING_SYSTEM_PSYS_SURFACE_MESH_H
00002 #define OPENTISSUE_DYNAMICS_PSYS_MASS_SPRING_SYSTEM_PSYS_SURFACE_MESH_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/dynamics/psys/constraints/psys_stick.h>
00013 #include <OpenTissue/dynamics/psys/forces/psys_spring.h>
00014 #include <OpenTissue/dynamics/psys/mass_spring_system/psys_mass_spring_system.h>
00015
00016 #include <list>
00017 #include <map>
00018
00019 namespace OpenTissue
00020 {
00021 namespace psys
00022 {
00023
00029 template<
00030 typename types
00031 , typename integrator_policy
00032 >
00033 class SurfaceMesh : public MassSpringSystem<types,integrator_policy>
00034 {
00035 public:
00036
00037 typedef MassSpringSystem<types,integrator_policy> base_class;
00038
00039 public:
00040
00041 typedef typename types::math_types math_types;
00042 typedef typename math_types::real_type real_type;
00043 typedef typename math_types::vector3_type vector3_type;
00044 typedef typename types::particle_type particle_type;
00045 typedef Stick<types> stick_type;
00046 typedef Spring<types> spring_type;
00047 typedef typename types::coupling_type coupling_type;
00048 typedef typename types::mesh_type mesh_type;
00049
00050 protected:
00051
00052 typedef typename mesh_type::vertex_type vertex_type;
00053 typedef typename mesh_type::vertex_iterator vertex_iterator;
00054 typedef typename mesh_type::vertex_halfedge_circulator vertex_halfedge_circulator;
00055
00056 typedef std::list<stick_type> stick_container;
00057 typedef std::list<stick_type*> stick_ptr_container;
00058 typedef std::map<particle_type*, stick_ptr_container > stick_lut_type;
00059
00060 typedef std::list<spring_type> spring_container;
00061 typedef std::list<spring_type*> spring_ptr_container;
00062 typedef std::map<particle_type*, spring_ptr_container > spring_lut_type;
00063
00064 public:
00065
00066 coupling_type m_coupling;
00067 int m_rigidty;
00068 stick_container m_sticks;
00069 stick_lut_type m_stick_lut;
00070 spring_container m_springs;
00071 spring_lut_type m_spring_lut;
00072
00073 public:
00074
00075 int & rigidty() { return m_rigidty; }
00076 int const & rigidty() const { return m_rigidty; }
00077 coupling_type & coupling() { return m_coupling; }
00078 coupling_type const & coupling() const { return m_coupling; }
00079
00080 protected:
00081
00082 bool exist_stick(particle_type * A,particle_type * B)
00083 {
00084 typedef typename boost::indirect_iterator< typename stick_ptr_container::iterator, stick_type> stick_iterator;
00085
00086 stick_ptr_container sticksA = m_stick_lut[A];
00087 stick_ptr_container sticksB = m_stick_lut[B];
00088 if(sticksA.empty())
00089 return false;
00090 if(sticksB.empty())
00091 return false;
00092 {
00093 stick_iterator s = stick_iterator( sticksA.begin() );
00094 stick_iterator end = stick_iterator( sticksA.end() );
00095 for(;s!=end;++s)
00096 {
00097 if( (s->A() == A && s->B()==B) || (s->B()==A && s->A()==B) )
00098 return true;
00099 }
00100 }
00101 {
00102 stick_iterator s = stick_iterator( sticksB.begin() );
00103 stick_iterator end = stick_iterator( sticksB.end() );
00104 for(;s!=end;++s)
00105 {
00106 if( (s->A()==A && s->B()==B) || (s->B()==A && s->A()==B) )
00107 return true;
00108 }
00109 }
00110 return false;
00111 }
00112
00113 bool exist_spring(particle_type * A,particle_type * B)
00114 {
00115 typedef boost::indirect_iterator< typename spring_ptr_container::iterator, spring_type> spring_iterator;
00116 spring_ptr_container springsA = m_spring_lut[A];
00117 spring_ptr_container springsB = m_spring_lut[B];
00118 if(springsA.empty())
00119 return false;
00120 if(springsB.empty())
00121 return false;
00122 {
00123 spring_iterator s = spring_iterator( springsA.begin() );
00124 spring_iterator end = spring_iterator( springsA.end() );
00125 for(;s!=end;++s)
00126 {
00127 if( (s->A() == A && s->B()==B) || (s->B()==A && s->A()==B) )
00128 return true;
00129 }
00130 }
00131 {
00132 spring_iterator s = spring_iterator( springsB.begin() );
00133 spring_iterator end = spring_iterator( springsB.end() );
00134 for(;s!=end;++s)
00135 {
00136 if( (s->A()==A && s->B()==B) || (s->B()==A && s->A()==B) )
00137 return true;
00138 }
00139 }
00140 return false;
00141 }
00142
00143
00144 void add_stick(particle_type * A,particle_type * B)
00145 {
00146 if(A==B)
00147 return;
00148
00149 m_sticks.push_back(stick_type());
00150 stick_type * s = &m_sticks.back();
00151 this->add_constraint( s );
00152 s->init(A,B);
00153 m_stick_lut[A].push_back(s);
00154 m_stick_lut[B].push_back(s);
00155
00156 }
00157
00158 void add_spring(particle_type * A,particle_type * B)
00159 {
00160 if(A==B)
00161 return;
00162
00163 m_springs.push_back(spring_type());
00164 spring_type * s = &m_springs.back();
00165 this->add_force( s );
00166 s->init(A,B);
00167 m_spring_lut[A].push_back(s);
00168 m_spring_lut[B].push_back(s);
00169
00170 }
00171
00172
00173 template<typename vertex_iterator_container>
00174 void traverse(
00175 vertex_iterator root
00176 , vertex_iterator from
00177 , bool create_sticks
00178 , bool create_springs
00179 , int dist
00180 , vertex_iterator_container & visited
00181 )
00182 {
00183 if( dist >= m_rigidty )
00184 return;
00185
00186 visited.push_back(from);
00187 from->m_tag = 1;
00188
00189 vertex_halfedge_circulator h(*from),hend;
00190 for(;h!=hend;++h)
00191 {
00192 vertex_iterator to = h->get_destination_iterator();
00193 if( to->m_tag == 0 )
00194 {
00195 particle_type * A = &( m_coupling.particle( (*root) ) );
00196 particle_type * B = &( m_coupling.particle( (*to) ) );
00197
00198 if(create_sticks && !exist_stick(A,B))
00199 add_stick(A,B);
00200
00201 if(create_springs && !exist_spring(A,B))
00202 add_spring(A,B);
00203
00204 traverse( root, to, create_sticks, create_springs, dist+1, visited);
00205 }
00206 }
00207 }
00208
00209 public:
00210
00211 SurfaceMesh()
00212 : m_rigidty(2)
00213 , m_sticks()
00214 , m_stick_lut()
00215 , m_springs()
00216 , m_spring_lut()
00217 {}
00218
00219 virtual ~SurfaceMesh() {}
00220
00221 public:
00222
00223 virtual void clear()
00224 {
00225 base_class::clear();
00226
00227 m_coupling.clear();
00228
00229 m_sticks.clear();
00230 m_springs.clear();
00231 m_stick_lut.clear();
00232 m_spring_lut.clear();
00233 }
00234
00235 virtual void init(mesh_type & mesh, bool create_sticks, bool create_springs)
00236 {
00237 clear();
00238
00239 m_coupling.init(*this,mesh);
00240
00241 mesh::clear_vertex_tags(m_coupling.mesh());
00242
00243 vertex_iterator end = m_coupling.mesh().vertex_end();
00244 vertex_iterator v = m_coupling.mesh().vertex_begin();
00245 for(;v!=end;++v)
00246 {
00247 std::list<vertex_iterator> visited;
00248
00249 traverse( v, v, create_sticks, create_springs, 0, visited);
00250
00251 for(typename std::list<vertex_iterator>::iterator w = visited.begin();w!=visited.end();++w)
00252 (*w)->m_tag = 0;
00253 }
00254
00255 m_stick_lut.clear();
00256 m_spring_lut.clear();
00257 }
00258
00259 };
00260 }
00261 }
00262
00263
00264 #endif