00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <freecloth/geom/geMeshWingedEdge.imp.h>
00020 #include <freecloth/base/map>
00021
00022
00023
00024
00025 FREECLOTH_NAMESPACE_START
00026
00027
00028
00029
00030
00031
00032 GeMeshWingedEdge::GeMeshWingedEdge( const RCShdPtr<GeMesh>& mesh )
00033 : _mesh( mesh )
00034 {
00035 DGFX_ASSERT( !mesh.isNull() );
00036 build( *mesh );
00037 }
00038
00039
00040
00041 void GeMeshWingedEdge::build( const GeMesh& mesh )
00042 {
00043 typedef std::pair< VertexId, VertexId > VertexIdPair;
00044 typedef std::map< VertexIdPair, HalfEdgeId > EdgeMap;
00045 EdgeMap edgeMap;
00046
00047 GeMesh::FaceConstIterator fi;
00048 _halfEdges.resize( mesh.getNbFaces() * 3 );
00049
00050 _vertexHalfEdgeIds.resize( mesh.getNbVertices() );
00051 std::fill(
00052 _vertexHalfEdgeIds.begin(),
00053 _vertexHalfEdgeIds.end(),
00054 HalfEdge::ID_INVALID
00055 );
00056 _faceHalfEdgeIds.resize( mesh.getNbFaces() );
00057 std::fill(
00058 _faceHalfEdgeIds.begin(),
00059 _faceHalfEdgeIds.end(),
00060 HalfEdge::ID_INVALID
00061 );
00062
00063 HalfEdgeId hid;
00064 FaceId fid;
00065 for (
00066 fi = mesh.beginFace(), hid = 0, fid = 0;
00067 fi != mesh.endFace();
00068 hid += fi->getNbVertices(), ++fi, ++fid
00069 ) {
00070 DGFX_ASSERT( fi->getNbVertices() == 3 );
00071 for ( FaceVertexId fvid = 0; fvid < fi->getNbVertices(); ++fvid ) {
00072
00073 FaceVertexId fvid2 = (fvid + 1) % 3;
00074
00075 VertexId vid = fi->getVertexId( fvid );
00076 VertexId vid2 = fi->getVertexId( fvid2 );
00077
00078 HalfEdgeId heid = hid + fvid;
00079 HalfEdgeId heid2 = hid + fvid2;
00080
00081 #if 0
00082 if ( vid == 0 ) {
00083 std::cout << "Face " << fid
00084 << " vertex ids " << fi->getVertexId( 0 ) << "," << fi->getVertexId( 1 ) << "," << fi->getVertexId( 2 )
00085 << " vertices " << fi->getVertex( 0 ) << "," << fi->getVertex( 1 ) << "," << fi->getVertex( 2 )
00086 << std::endl;
00087 }
00088 #endif
00089 _halfEdges[ heid ] = HalfEdge(
00090 vid,
00091 HalfEdge::ID_INVALID,
00092 fid,
00093 heid2
00094 );
00095 _vertexHalfEdgeIds[ vid ] = heid;
00096 _faceHalfEdgeIds[ fid ] = heid;
00097 if ( vid < vid2 ) {
00098 edgeMap[ VertexIdPair( vid, vid2 ) ] = heid;
00099 }
00100 }
00101 }
00102
00103
00104 EdgeMap::const_iterator ei;
00105 for (
00106 fi = mesh.beginFace(), hid = 0, fid = 0;
00107 fi != mesh.endFace();
00108 hid += fi->getNbVertices(), ++fi, ++fid
00109 ) {
00110 for ( FaceVertexId fvid = 0; fvid < fi->getNbVertices(); ++fvid ) {
00111 FaceVertexId fvid2 = (fvid + 1) % 3;
00112 VertexId vid = fi->getVertexId( fvid );
00113 VertexId vid2 = fi->getVertexId( fvid2 );
00114 if ( vid > vid2 ) {
00115 ei = edgeMap.find( VertexIdPair( vid2, vid ) );
00116 if ( ei != edgeMap.end() ) {
00117 _halfEdges[ hid + fvid ]._twin = ei->second;
00118 _halfEdges[ ei->second ]._twin = hid + fvid;
00119 }
00120 }
00121 }
00122 }
00123
00124
00125 for (
00126 fi = mesh.beginFace(), hid = 0, fid = 0;
00127 fi != mesh.endFace();
00128 hid += fi->getNbVertices(), ++fi, ++fid
00129 ) {
00130 for ( FaceVertexId fvid = 0; fvid < fi->getNbVertices(); ++fvid ) {
00131
00132 VertexId vid = fi->getVertexId( fvid );
00133
00134 HalfEdgeId heid = hid + fvid;
00135
00136
00137
00138 if ( ! _halfEdges[ heid ].hasTwin() ) {
00139 _vertexHalfEdgeIds[ vid ] = heid;
00140 }
00141 }
00142 }
00143 }
00144
00145
00146
00147 inline const RCShdPtr<GeMesh>& GeMeshWingedEdge::getMeshPtr() const
00148 {
00149 return _mesh;
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159 GeMeshWingedEdge::VertexFaceIterator::VertexFaceIterator()
00160 {
00161 }
00162
00163
00164
00165 GeMeshWingedEdge::VertexFaceIterator::VertexFaceIterator(
00166 const GeMeshWingedEdge& meshwe,
00167 VertexId vertexId,
00168 HalfEdgeId halfEdgeId
00169 ) : _wrapper( meshwe, halfEdgeId ),
00170 _vertexId( vertexId )
00171 {
00172 DGFX_ASSERT(
00173 _wrapper.getOriginVertexId() == _vertexId
00174 );
00175 }
00176
00177
00178
00179 GeMeshWingedEdge::VertexFaceIterator::VertexFaceIterator(
00180 const HalfEdgeWrapper& wrapper,
00181 VertexId vertexId
00182 ) : _wrapper( wrapper ),
00183 _vertexId( vertexId )
00184 {
00185 }
00186
00187
00188
00189 GeMeshWingedEdge::VertexFaceIterator
00190 GeMeshWingedEdge::VertexFaceIterator::begin(
00191 const GeMeshWingedEdge& meshwe,
00192 VertexId vertexId
00193 ) {
00194 DGFX_ASSERT( vertexId < meshwe._vertexHalfEdgeIds.size() );
00195
00196 if ( meshwe._vertexHalfEdgeIds[ vertexId ] == ID_INVALID ) {
00197 return end( meshwe, vertexId );
00198 }
00199 return VertexFaceIterator(
00200 meshwe, vertexId, meshwe._vertexHalfEdgeIds[ vertexId ]
00201 );
00202 }
00203
00204
00205
00206 GeMeshWingedEdge::VertexFaceIterator&
00207 GeMeshWingedEdge::VertexFaceIterator::operator++()
00208 {
00209 DGFX_ASSERT( _vertexId != ID_INVALID );
00210
00211 bool atEnd = false;
00212 if ( _wrapper.getOriginVertexId() != _vertexId ) {
00213 atEnd = true;
00214 }
00215 else if ( _wrapper.getPrevHalfEdge().hasTwin() ) {
00216 _wrapper._halfEdgeId = _wrapper.getPrevHalfEdge().getTwinHalfEdgeId();
00217 DGFX_ASSERT( _wrapper.getOriginVertexId() == _vertexId );
00218 atEnd = (
00219 _wrapper._halfEdgeId ==
00220 _wrapper.getMeshWE()._vertexHalfEdgeIds[ _vertexId ]
00221 );
00222 }
00223 else {
00224 atEnd = true;
00225 }
00226 if ( atEnd ) {
00227 _vertexId = ID_INVALID;
00228 _wrapper._halfEdgeId = ID_INVALID;
00229 }
00230 else {
00231 _faceWrapper = _wrapper.getFace();
00232 }
00233 return *this;
00234 }
00235
00236
00237
00238 GeMeshWingedEdge::VertexFaceIterator
00239 GeMeshWingedEdge::VertexFaceIterator::operator++( int )
00240 {
00241 VertexFaceIterator copy( *this );
00242 operator++();
00243 return copy;
00244 }
00245
00246
00247
00248
00249
00250
00251
00252
00253 std::ostream& operator<< ( std::ostream& os, const GeMeshWingedEdge& m )
00254 {
00255 os << "GeMeshWingedEdge" << std::endl;
00256 GeMeshWingedEdge::HalfEdgeIterator hei;
00257 UInt32 i;
00258 for( hei = m.beginHalfEdge(), i = 0; hei != m.endHalfEdge(); ++hei, ++i ) {
00259 os << "[" << i << "] " << *hei << std::endl;
00260 }
00261 return os;
00262 }
00263
00264
00265
00266 std::ostream& operator<< (
00267 std::ostream& os,
00268 const GeMeshWingedEdge::HalfEdgeWrapper& he
00269 ) {
00270 os << "he( origin_vid=" << he.getOriginVertexId();
00271 os << " twin_heid=";
00272 if ( he.hasTwin() ) {
00273 os << he.getTwinHalfEdgeId();
00274 }
00275 else {
00276 os << "(nil)";
00277 }
00278 os << " face_id=" << he.getFaceId();
00279 os << " next_heid=" << he.getNextHalfEdgeId();
00280
00281 return os;
00282 }
00283
00284
00285
00286
00287
00288 template class GeMeshWingedEdge::EdgeIteratorBase<false>;
00289 template class GeMeshWingedEdge::EdgeIteratorBase<true>;
00290 template class GeMeshWingedEdge::VertexEdgeIteratorBase<false>;
00291 template class GeMeshWingedEdge::VertexEdgeIteratorBase<true>;
00292
00293 FREECLOTH_NAMESPACE_END