00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef __VCGLIB_APPEND
00024 #define __VCGLIB_APPEND
00025
00026 #ifndef __VCG_MESH
00027 #error "This file should not be included alone. It is automatically included by complex.h"
00028 #endif
00029
00030 namespace vcg {
00031 namespace tri {
00039 template<class MeshLeft, class ConstMeshRight>
00040 class Append
00041 {
00042 public:
00043 typedef typename MeshLeft::ScalarType ScalarLeft;
00044 typedef typename MeshLeft::CoordType CoordLeft;
00045 typedef typename MeshLeft::VertexType VertexLeft;
00046 typedef typename MeshLeft::EdgeType EdgeLeft;
00047 typedef typename MeshLeft::FaceType FaceLeft;
00048 typedef typename MeshLeft::HEdgeType HEdgeLeft;
00049 typedef typename MeshLeft::VertexPointer VertexPointerLeft;
00050 typedef typename MeshLeft::VertexIterator VertexIteratorLeft;
00051 typedef typename MeshLeft::EdgeIterator EdgeIteratorLeft;
00052 typedef typename MeshLeft::HEdgeIterator HEdgeIteratorLeft;
00053 typedef typename MeshLeft::FaceIterator FaceIteratorLeft;
00054
00055
00056 typedef typename ConstMeshRight::ScalarType ScalarRight;
00057 typedef typename ConstMeshRight::CoordType CoordRight;
00058 typedef typename ConstMeshRight::VertexType VertexRight;
00059 typedef typename ConstMeshRight::EdgeType EdgeRight;
00060 typedef typename ConstMeshRight::HEdgeType HEdgeRight;
00061 typedef typename ConstMeshRight::FaceType FaceRight;
00062 typedef typename ConstMeshRight::VertexPointer VertexPointerRight;
00063 typedef typename ConstMeshRight::VertexIterator VertexIteratorRight;
00064 typedef typename ConstMeshRight::EdgeIterator EdgeIteratorRight;
00065 typedef typename ConstMeshRight::HEdgeIterator HEdgeIteratorRight;
00066 typedef typename ConstMeshRight::FaceIterator FaceIteratorRight;
00067 typedef typename ConstMeshRight::FacePointer FacePointerRight;
00068
00069 struct Remap{
00070 static size_t InvalidIndex() { return std::numeric_limits<size_t>::max(); }
00071 std::vector<size_t> vert,face,edge, hedge;
00072 };
00073
00074 static void ImportVertexAdj(MeshLeft &ml, ConstMeshRight &mr, VertexLeft &vl, VertexRight &vr, Remap &remap ){
00075
00076 if(HasVEAdjacency(ml) && HasVEAdjacency(mr) && vr.cVEp() != 0){
00077 size_t i = Index(mr,vr.cVEp());
00078 vl.VEp() = (i>ml.edge.size())? 0 : &ml.edge[remap.edge[i]];
00079 vl.VEi() = vr.VEi();
00080 }
00081
00082
00083 if(HasPerVertexVFAdjacency(ml) && HasPerVertexVFAdjacency(mr) && vr.cVFp() != 0 ){
00084 size_t i = Index(mr,vr.cVFp());
00085 vl.VFp() = (i>ml.face.size())? 0 :&ml.face[remap.face[i]];
00086 vl.VFi() = vr.VFi();
00087 }
00088
00089
00090 if(HasVHAdjacency(ml) && HasVHAdjacency(mr) && vr.cVHp() != 0){
00091 vl.VHp() = &ml.hedge[remap.hedge[Index(mr,vr.cVHp())]];
00092 vl.VHi() = vr.VHi();
00093 }
00094 }
00095
00096 static void ImportEdgeAdj(MeshLeft &ml, ConstMeshRight &mr, EdgeLeft &el, const EdgeRight &er, Remap &remap)
00097 {
00098
00099 if(HasEEAdjacency(ml) && HasEEAdjacency(mr))
00100 for(unsigned int vi = 0; vi < 2; ++vi)
00101 {
00102 size_t idx = Index(mr,er.cEEp(vi));
00103 el.EEp(vi) = (idx>ml.edge.size())? 0 : &ml.edge[remap.edge[idx]];
00104 el.EEi(vi) = er.cEEi(vi);
00105 }
00106
00107
00108 if(HasEFAdjacency(ml) && HasEFAdjacency(mr)){
00109 size_t idx = Index(mr,er.cEFp());
00110 el.EFp() = (idx>ml.face.size())? 0 :&ml.face[remap.face[idx]];
00111 el.EFi() = er.cEFi();
00112 }
00113
00114
00115 if(HasEHAdjacency(ml) && HasEHAdjacency(mr))
00116 el.EHp() = &ml.hedge[remap.hedge[Index(mr,er.cEHp())]];
00117 }
00118
00119
00120 static void ImportFaceAdj(MeshLeft &ml, ConstMeshRight &mr, FaceLeft &fl, const FaceRight &fr, Remap &remap )
00121 {
00122
00123 if(HasFEAdjacency(ml) && HasFEAdjacency(mr)){
00124 assert(fl.VN() == fr.VN());
00125 for( int vi = 0; vi < fl.VN(); ++vi ){
00126 size_t idx = remap.edge[Index(mr,fr.cFEp(vi))];
00127 if(idx!=Remap::InvalidIndex())
00128 fl.FEp(vi) = &ml.edge[idx];
00129 }
00130 }
00131
00132
00133 if(HasFFAdjacency(ml) && HasFFAdjacency(mr)){
00134 assert(fl.VN() == fr.VN());
00135 for( int vi = 0; vi < fl.VN(); ++vi ){
00136 size_t idx = remap.face[Index(mr,fr.cFFp(vi))];
00137 if(idx!=Remap::InvalidIndex()){
00138 fl.FFp(vi) = &ml.face[idx];
00139 fl.FFi(vi) = fr.cFFi(vi);
00140 }
00141 }
00142 }
00143
00144
00145 if(HasFHAdjacency(ml) && HasFHAdjacency(mr))
00146 fl.FHp() = &ml.hedge[remap.hedge[Index(mr,fr.cFHp())]];
00147 }
00148
00149 static void ImportHEdgeAdj(MeshLeft &ml, ConstMeshRight &mr, HEdgeLeft &hl, const HEdgeRight &hr, Remap &remap, bool ){
00150
00151 if(HasHVAdjacency(ml) && HasHVAdjacency(mr))
00152 hl.HVp() = &ml.vert[remap.vert[Index(mr,hr.cHVp())]];
00153
00154
00155 if(HasHEAdjacency(ml) && HasHEAdjacency(mr)){
00156 size_t idx = Index(mr,hr.cHEp()) ;
00157 hl.HEp() = (idx>ml.edge.size())? 0 : &ml.edge[remap.edge[idx]];
00158 }
00159
00160
00161 if(HasHFAdjacency(ml) && HasHFAdjacency(mr)){
00162 size_t idx = Index(mr,hr.cHFp());
00163 hl.HFp() = (idx>ml.face.size())? 0 :&ml.face[remap.face[idx]];
00164 }
00165
00166
00167
00168 if(HasHOppAdjacency(ml) && HasHOppAdjacency(mr))
00169 hl.HOp() = &ml.hedge[remap.hedge[Index(mr,hr.cHOp())]];
00170
00171
00172 if(HasHNextAdjacency(ml) && HasHNextAdjacency(mr))
00173 hl.HNp() = &ml.hedge[remap.hedge[Index(mr,hr.cHNp())]];
00174
00175
00176 if(HasHPrevAdjacency(ml) && HasHPrevAdjacency(mr))
00177 hl.HPp() = &ml.hedge[remap.hedge[Index(mr,hr.cHPp())]];
00178 }
00179
00180
00181
00182
00203 static void Mesh(MeshLeft& ml, ConstMeshRight& mr, const bool selected = false, const bool adjFlag = false)
00204 {
00205
00206
00207
00208
00209
00210 if(selected)
00211 {
00212 assert(adjFlag == false || ml.IsEmpty());
00213 tri::UpdateSelection<ConstMeshRight>::VertexFromEdgeLoose(mr,true);
00214 tri::UpdateSelection<ConstMeshRight>::VertexFromFaceLoose(mr,true);
00215 }
00216
00217
00218
00219
00220 Remap remap;
00221
00222
00223 remap.vert.resize(mr.vert.size(), Remap::InvalidIndex());
00224 VertexIteratorLeft vp;
00225 size_t svn = UpdateSelection<ConstMeshRight>::VertexCount(mr);
00226 if(selected)
00227 vp=Allocator<MeshLeft>::AddVertices(ml,int(svn));
00228 else
00229 vp=Allocator<MeshLeft>::AddVertices(ml,mr.vn);
00230
00231 for(VertexIteratorRight vi=mr.vert.begin(); vi!=mr.vert.end(); ++vi)
00232 {
00233 if(!(*vi).IsD() && (!selected || (*vi).IsS()))
00234 {
00235 size_t ind=Index(mr,*vi);
00236 remap.vert[ind]=int(Index(ml,*vp));
00237 ++vp;
00238 }
00239 }
00240
00241 remap.edge.resize(mr.edge.size(), Remap::InvalidIndex());
00242 EdgeIteratorLeft ep;
00243 size_t sen = UpdateSelection<ConstMeshRight>::EdgeCount(mr);
00244 if(selected) ep=Allocator<MeshLeft>::AddEdges(ml,sen);
00245 else ep=Allocator<MeshLeft>::AddEdges(ml,mr.en);
00246
00247 for(EdgeIteratorRight ei=mr.edge.begin(); ei!=mr.edge.end(); ++ei)
00248 if(!(*ei).IsD() && (!selected || (*ei).IsS())){
00249 size_t ind=Index(mr,*ei);
00250 remap.edge[ind]=int(Index(ml,*ep));
00251 ++ep;
00252 }
00253
00254
00255 remap.face.resize(mr.face.size(), Remap::InvalidIndex());
00256 FaceIteratorLeft fp;
00257 size_t sfn = UpdateSelection<ConstMeshRight>::FaceCount(mr);
00258 if(selected) fp=Allocator<MeshLeft>::AddFaces(ml,sfn);
00259 else fp=Allocator<MeshLeft>::AddFaces(ml,mr.fn);
00260
00261 for(FaceIteratorRight fi=mr.face.begin(); fi!=mr.face.end(); ++fi)
00262 if(!(*fi).IsD() && (!selected || (*fi).IsS())){
00263 size_t ind=Index(mr,*fi);
00264 remap.face[ind]=int(Index(ml,*fp));
00265 ++fp;
00266 }
00267
00268
00269 remap.hedge.resize(mr.hedge.size(),Remap::InvalidIndex());
00270 for(HEdgeIteratorRight hi=mr.hedge.begin(); hi!=mr.hedge.end(); ++hi)
00271 if(!(*hi).IsD() && (!selected || (*hi).IsS())){
00272 size_t ind=Index(mr,*hi);
00273 assert(remap.hedge[ind]==Remap::InvalidIndex());
00274 HEdgeIteratorLeft hp = Allocator<MeshLeft>::AddHEdges(ml,1);
00275 (*hp).ImportData(*(hi));
00276 remap.hedge[ind]=Index(ml,*hp);
00277 }
00278
00279
00280
00281
00282
00283 for(VertexIteratorRight vi=mr.vert.begin();vi!=mr.vert.end();++vi)
00284 if( !(*vi).IsD() && (!selected || (*vi).IsS())){
00285 ml.vert[remap.vert[Index(mr,*vi)]].ImportData(*vi);
00286 if(adjFlag) ImportVertexAdj(ml,mr,ml.vert[remap.vert[Index(mr,*vi)]],*vi,remap);
00287 }
00288
00289
00290 for(EdgeIteratorRight ei=mr.edge.begin();ei!=mr.edge.end();++ei)
00291 if(!(*ei).IsD() && (!selected || (*ei).IsS())){
00292 ml.edge[remap.edge[Index(mr,*ei)]].ImportData(*ei);
00293
00294 EdgeLeft &el = ml.edge[remap.edge[Index(mr,*ei)]];
00295 if(HasEVAdjacency(ml) && HasEVAdjacency(mr)){
00296 el.V(0) = &ml.vert[remap.vert[Index(mr,ei->cV(0))]];
00297 el.V(1) = &ml.vert[remap.vert[Index(mr,ei->cV(1))]];
00298 }
00299 if(adjFlag) ImportEdgeAdj(ml,mr,el,*ei,remap);
00300 }
00301
00302
00303 const size_t textureOffset = ml.textures.size();
00304 bool WTFlag = HasPerWedgeTexCoord(mr) && (textureOffset>0);
00305 for(FaceIteratorRight fi=mr.face.begin();fi!=mr.face.end();++fi)
00306 if(!(*fi).IsD() && (!selected || (*fi).IsS()))
00307 {
00308 FaceLeft &fl = ml.face[remap.face[Index(mr,*fi)]];
00309 fl.Alloc(fi->VN());
00310 if(HasFVAdjacency(ml) && HasFVAdjacency(mr)){
00311 for(int i = 0; i < fl.VN(); ++i)
00312 fl.V(i) = &ml.vert[remap.vert[Index(mr,fi->cV(i))]];
00313 }
00314 if(WTFlag)
00315 for(int i = 0; i < fl.VN(); ++i)
00316 fl.WT(i).n() += short(textureOffset);
00317 fl.ImportData(*fi);
00318 if(adjFlag) ImportFaceAdj(ml,mr,ml.face[remap.face[Index(mr,*fi)]],*fi,remap);
00319
00320 }
00321
00322
00323 for(HEdgeIteratorRight hi=mr.hedge.begin();hi!=mr.hedge.end();++hi)
00324 if(!(*hi).IsD() && (!selected || (*hi).IsS())){
00325 ml.hedge[remap.hedge[Index(mr,*hi)]].ImportData(*hi);
00326 ImportHEdgeAdj(ml,mr,ml.hedge[remap.hedge[Index(mr,*hi)]],*hi,remap,selected);
00327 }
00328
00329
00330
00331
00332
00333 ml.textures.insert(ml.textures.end(),mr.textures.begin(),mr.textures.end());
00334
00335
00336
00337
00338
00339
00340
00341
00342 unsigned int id_r;
00343 typename std::set< PointerToAttribute >::iterator al, ar;
00344
00345
00346 for(al = ml.vert_attr.begin(); al != ml.vert_attr.end(); ++al)
00347 if(!(*al)._name.empty()){
00348 ar = mr.vert_attr.find(*al);
00349 if(ar!= mr.vert_attr.end()){
00350 id_r = 0;
00351 for(VertexIteratorRight vi=mr.vert.begin();vi!=mr.vert.end();++vi,++id_r)
00352 if( !(*vi).IsD() && (!selected || (*vi).IsS()))
00353 memcpy((*al)._handle->At(remap.vert[Index(mr,*vi)]),(*ar)._handle->At(id_r),
00354 (*al)._handle->SizeOf());
00355 }
00356 }
00357
00358
00359 for(al = ml.edge_attr.begin(); al != ml.edge_attr.end(); ++al)
00360 if(!(*al)._name.empty()){
00361 ar = mr.edge_attr.find(*al);
00362 if(ar!= mr.edge_attr.end()){
00363 id_r = 0;
00364 for(EdgeIteratorRight ei=mr.edge.begin();ei!=mr.edge.end();++ei,++id_r)
00365 if( !(*ei).IsD() && (!selected || (*ei).IsS()))
00366 memcpy((*al)._handle->At(remap.edge[Index(mr,*ei)]),(*ar)._handle->At(id_r),
00367 (*al)._handle->SizeOf());
00368 }
00369 }
00370
00371
00372 for(al = ml.face_attr.begin(); al != ml.face_attr.end(); ++al)
00373 if(!(*al)._name.empty()){
00374 ar = mr.face_attr.find(*al);
00375 if(ar!= mr.face_attr.end()){
00376 id_r = 0;
00377 for(FaceIteratorRight fi=mr.face.begin();fi!=mr.face.end();++fi,++id_r)
00378 if( !(*fi).IsD() && (!selected || (*fi).IsS()))
00379 memcpy((*al)._handle->At(remap.face[Index(mr,*fi)]),(*ar)._handle->At(id_r),
00380 (*al)._handle->SizeOf());
00381 }
00382 }
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 }
00394
00398 static void MeshCopy(MeshLeft& ml, ConstMeshRight& mr, bool selected=false, const bool adjFlag = false)
00399 {
00400 ml.Clear();
00401 Mesh(ml,mr,selected,adjFlag);
00402 ml.bbox.Import(mr.bbox);
00403 }
00408 static void Selected(MeshLeft& ml, ConstMeshRight& mr)
00409 {
00410 Mesh(ml,mr,true);
00411 }
00412
00413 };
00414
00415
00416
00417
00418
00419 }
00420 }
00421
00422
00423 #endif
00424
00425