append.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 * VCGLib                                                            o o     *
00003 * Visual and Computer Graphics Library                            o     o   *
00004 *                                                                _   O  _   *
00005 * Copyright(C) 2004                                                \/)\/    *
00006 * Visual Computing Lab                                            /\/|      *
00007 * ISTI - Italian National Research Council                           |      *
00008 *                                                                    \      *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
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    // Vertex to Edge Adj
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    // Vertex to Face Adj
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    // Vertex to HEdge Adj
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      // Edge to Edge  Adj
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      // Edge to Face  Adj
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      // Edge to HEdge   Adj
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    // Face to Edge  Adj
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    // Face to Face  Adj
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    // Face to HEedge  Adj
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 /*sel*/ ){
00150    // HEdge to Vertex  Adj
00151    if(HasHVAdjacency(ml) && HasHVAdjacency(mr))
00152      hl.HVp() = &ml.vert[remap.vert[Index(mr,hr.cHVp())]];
00153 
00154    // HEdge to Edge  Adj
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    // HEdge to Face  Adj
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    // HEdge to Opposite HEdge  Adj
00168    if(HasHOppAdjacency(ml) && HasHOppAdjacency(mr))
00169      hl.HOp() = &ml.hedge[remap.hedge[Index(mr,hr.cHOp())]];
00170 
00171    // HEdge to Next  HEdge  Adj
00172    if(HasHNextAdjacency(ml) && HasHNextAdjacency(mr))
00173      hl.HNp() = &ml.hedge[remap.hedge[Index(mr,hr.cHNp())]];
00174 
00175    // HEdge to Next  HEdge  Adj
00176    if(HasHPrevAdjacency(ml) && HasHPrevAdjacency(mr))
00177      hl.HPp() = &ml.hedge[remap.hedge[Index(mr,hr.cHPp())]];
00178  }
00179 
00180 // Append Right Mesh to the Left Mesh
00181 // Append::Mesh(ml, mr) is equivalent to ml += mr.
00182 // Note MeshRigth could be costant...
00203 static void Mesh(MeshLeft& ml, ConstMeshRight& mr, const bool selected = false, const bool adjFlag = false)
00204 {
00205   // Note that if the the selection of the vertexes is not consistent with the face selection
00206   // the append could build faces referencing non existent vertices
00207   // so it is mandatory that the selection of the vertices reflects the loose selection
00208   // from edges and faces (e.g. if a face is selected all its vertices must be selected).
00209   // note the use of the parameter for preserving existing vertex selection.
00210   if(selected)
00211   {
00212     assert(adjFlag == false || ml.IsEmpty()); // It is rather meaningless to partially copy adj relations.
00213     tri::UpdateSelection<ConstMeshRight>::VertexFromEdgeLoose(mr,true);
00214     tri::UpdateSelection<ConstMeshRight>::VertexFromFaceLoose(mr,true);
00215   }
00216 
00217   // phase 1. allocate on ml vert,edge,face, hedge to accomodat those of mr
00218   // and build the remapping for all
00219 
00220   Remap remap;
00221 
00222   // vertex
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   // edge
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   // face
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   // hedge
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   // phase 2.
00280   // copy data from ml to its corresponding elements in ml and adjacencies
00281 
00282   // vertex
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   // edge
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       // Edge to Vertex  Adj
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   // face
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   // hedge
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         // phase 3.
00330         // take care of other per mesh data: textures,   attributes
00331 
00332         // At the end concatenate the vector with texture names.
00333         ml.textures.insert(ml.textures.end(),mr.textures.begin(),mr.textures.end());
00334 
00335         // Attributes. Copy only those attributes that are present in both meshes
00336         // Two attributes in different meshes are considered the same if they have the same
00337         // name and the same type. This may be deceiving because they could in fact have
00338         // different semantic, but this is up to the developer.
00339         // If the left mesh has attributes that are not in the right mesh, their values for the elements
00340         // of the right mesh will be uninitialized
00341 
00342         unsigned int id_r;
00343         typename std::set< PointerToAttribute  >::iterator al, ar;
00344 
00345         // per vertex attributes
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         // per edge attributes
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         // per face attributes
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                 // per mesh attributes
00385                 // if both ml and mr have an attribute with the same name, no action is done
00386                 // if mr has an attribute that is NOT present in ml, the attribute is added to ml
00387                 //for(ar = mr.mesh_attr.begin(); ar != mr.mesh_attr.end(); ++ar)
00388                 //        if(!(*ar)._name.empty()){
00389                 //                al =    ml.mesh_attr.find(*ar);
00390                 //                if(al== ml.mesh_attr.end())
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 }; // end of class Append
00414 
00415 
00416 
00417 
00418 
00419 } // End Namespace tri
00420 } // End Namespace vcg
00421 
00422 
00423 #endif
00424 
00425 


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:28:56