23 #ifndef __VCGLIB_APPEND
24 #define __VCGLIB_APPEND
26 #include <vcg/complex/allocate.h>
27 #include <vcg/complex/algorithms/update/selection.h>
38 template<
class MeshLeft,
class ConstMeshRight>
42 typedef typename MeshLeft::ScalarType ScalarLeft;
43 typedef typename MeshLeft::CoordType CoordLeft;
44 typedef typename MeshLeft::VertexType VertexLeft;
45 typedef typename MeshLeft::EdgeType EdgeLeft;
46 typedef typename MeshLeft::FaceType FaceLeft;
47 typedef typename MeshLeft::HEdgeType HEdgeLeft;
48 typedef typename MeshLeft::TetraType TetraLeft;
49 typedef typename MeshLeft::VertexPointer VertexPointerLeft;
50 typedef typename MeshLeft::VertexIterator VertexIteratorLeft;
51 typedef typename MeshLeft::EdgeIterator EdgeIteratorLeft;
52 typedef typename MeshLeft::HEdgeIterator HEdgeIteratorLeft;
53 typedef typename MeshLeft::FaceIterator FaceIteratorLeft;
54 typedef typename MeshLeft::TetraIterator TetraIteratorLeft;
57 typedef typename ConstMeshRight::ScalarType ScalarRight;
58 typedef typename ConstMeshRight::CoordType CoordRight;
59 typedef typename ConstMeshRight::VertexType VertexRight;
60 typedef typename ConstMeshRight::EdgeType EdgeRight;
61 typedef typename ConstMeshRight::HEdgeType HEdgeRight;
62 typedef typename ConstMeshRight::FaceType FaceRight;
63 typedef typename ConstMeshRight::TetraType TetraRight;
64 typedef typename ConstMeshRight::TetraPointer TetraPointerRight;
65 typedef typename ConstMeshRight::TetraIterator TetraIteratorRight;
66 typedef typename ConstMeshRight::VertexPointer VertexPointerRight;
67 typedef typename ConstMeshRight::VertexIterator VertexIteratorRight;
68 typedef typename ConstMeshRight::EdgeIterator EdgeIteratorRight;
69 typedef typename ConstMeshRight::HEdgeIterator HEdgeIteratorRight;
70 typedef typename ConstMeshRight::FaceIterator FaceIteratorRight;
71 typedef typename ConstMeshRight::FacePointer FacePointerRight;
74 static size_t InvalidIndex() {
return std::numeric_limits<size_t>::max(); }
75 std::vector<size_t> vert, face, edge, hedge, tetra;
78 static void ImportVertexAdj(MeshLeft &ml,
const ConstMeshRight &mr, VertexLeft &vl,
const VertexRight &vr,
Remap &remap ){
80 if(HasVEAdjacency(ml) && HasVEAdjacency(mr) && vr.cVEp() != 0){
81 size_t i = Index(mr,vr.cVEp());
82 vl.VEp() = (i>ml.edge.size())? 0 : &ml.edge[remap.edge[i]];
87 if(HasPerVertexVFAdjacency(ml) && HasPerVertexVFAdjacency(mr) && vr.cVFp() != 0 ){
88 size_t i = Index(mr,vr.cVFp());
89 vl.VFp() = (i>ml.face.size())? 0 :&ml.face[remap.face[i]];
94 if(HasVHAdjacency(ml) && HasVHAdjacency(mr) && vr.cVHp() != 0){
95 vl.VHp() = &ml.hedge[remap.hedge[Index(mr,vr.cVHp())]];
100 if(HasVTAdjacency(ml) && HasVTAdjacency(mr) && vr.cVTp() != 0){
101 size_t i = Index(mr, vr.cVTp());
102 vl.VTp() = (i > ml.edge.size()) ? 0 : &ml.tetra[remap.tetra[i]];
107 static void ImportEdgeAdj(MeshLeft &ml,
const ConstMeshRight &mr, EdgeLeft &el,
const EdgeRight &er, Remap &remap)
110 if(HasEEAdjacency(ml) && HasEEAdjacency(mr))
111 for(
unsigned int vi = 0; vi < 2; ++vi)
113 size_t idx = Index(mr,er.cEEp(vi));
114 el.EEp(vi) = (idx>ml.edge.size())? 0 : &ml.edge[remap.edge[idx]];
115 el.EEi(vi) = er.cEEi(vi);
119 if(HasEFAdjacency(ml) && HasEFAdjacency(mr)){
120 size_t idx = Index(mr,er.cEFp());
121 el.EFp() = (idx>ml.face.size())? 0 :&ml.face[remap.face[idx]];
122 el.EFi() = er.cEFi();
126 if(HasEHAdjacency(ml) && HasEHAdjacency(mr))
127 el.EHp() = &ml.hedge[remap.hedge[Index(mr,er.cEHp())]];
131 static void ImportFaceAdj(MeshLeft &ml,
const ConstMeshRight &mr, FaceLeft &fl,
const FaceRight &fr, Remap &remap )
134 if(HasFEAdjacency(ml) && HasFEAdjacency(mr)){
135 assert(fl.VN() == fr.VN());
136 for(
int vi = 0; vi < fl.VN(); ++vi ){
137 size_t idx = remap.edge[Index(mr,fr.cFEp(vi))];
138 if(idx!=Remap::InvalidIndex())
139 fl.FEp(vi) = &ml.edge[idx];
144 if(HasFFAdjacency(ml) && HasFFAdjacency(mr)){
145 assert(fl.VN() == fr.VN());
146 for(
int vi = 0; vi < fl.VN(); ++vi ){
147 size_t idx = remap.face[Index(mr,fr.cFFp(vi))];
148 if(idx!=Remap::InvalidIndex()){
149 assert(idx >= 0 && idx < ml.face.size());
150 fl.FFp(vi) = &ml.face[idx];
151 fl.FFi(vi) = fr.cFFi(vi);
157 if(HasPerFaceVFAdjacency(ml) && HasPerFaceVFAdjacency(mr))
159 assert(fl.VN() == fr.VN());
160 for (
int vi = 0; vi < fl.VN(); ++vi)
162 const auto * fp = fr.cVFp(vi);
163 const auto vfindex = fr.cVFi(vi);
164 size_t fidx = (fp ==
nullptr) ? Remap::InvalidIndex() : remap.face[Index(mr,fp)];
166 if (fidx == Remap::InvalidIndex())
169 assert(fl.cVFi(vi) == -1);
173 assert(fidx >= 0 && fidx < ml.face.size());
174 fl.VFp(vi) = &ml.face[fidx];
175 fl.VFi(vi) = vfindex;
181 if(HasFHAdjacency(ml) && HasFHAdjacency(mr))
182 fl.FHp() = &ml.hedge[remap.hedge[Index(mr,fr.cFHp())]];
185 static void ImportHEdgeAdj(MeshLeft &ml,
const ConstMeshRight &mr, HEdgeLeft &hl,
const HEdgeRight &hr, Remap &remap,
bool ){
187 if(HasHVAdjacency(ml) && HasHVAdjacency(mr))
188 hl.HVp() = &ml.vert[remap.vert[Index(mr,hr.cHVp())]];
191 if(HasHEAdjacency(ml) && HasHEAdjacency(mr)){
192 size_t idx = Index(mr,hr.cHEp()) ;
193 hl.HEp() = (idx>ml.edge.size())? 0 : &ml.edge[remap.edge[idx]];
197 if(HasHFAdjacency(ml) && HasHFAdjacency(mr)){
198 size_t idx = Index(mr,hr.cHFp());
199 hl.HFp() = (idx>ml.face.size())? 0 :&ml.face[remap.face[idx]];
204 if(HasHOppAdjacency(ml) && HasHOppAdjacency(mr))
205 hl.HOp() = &ml.hedge[remap.hedge[Index(mr,hr.cHOp())]];
208 if(HasHNextAdjacency(ml) && HasHNextAdjacency(mr))
209 hl.HNp() = &ml.hedge[remap.hedge[Index(mr,hr.cHNp())]];
212 if(HasHPrevAdjacency(ml) && HasHPrevAdjacency(mr))
213 hl.HPp() = &ml.hedge[remap.hedge[Index(mr,hr.cHPp())]];
216 static void ImportTetraAdj(MeshLeft &ml,
const ConstMeshRight &mr, TetraLeft &tl,
const TetraRight &tr, Remap &remap )
219 if(HasTTAdjacency(ml) && HasTTAdjacency(mr)){
220 for(
int vi = 0; vi < 4; ++vi ){
221 size_t idx = remap.tetra[Index(mr,tr.cTTp(vi))];
222 if(idx != Remap::InvalidIndex()){
223 tl.TTp(vi) = &ml.tetra[idx];
224 tl.TTi(vi) = tr.cTTi(vi);
253 static void Mesh(MeshLeft& ml, ConstMeshRight& mr,
const bool selected =
false,
const bool adjFlag =
false)
262 assert(adjFlag ==
false || ml.IsEmpty());
290 const ConstMeshRight& mr,
291 const bool selected =
false,
292 const bool adjFlag =
false)
300 remap.vert.resize(mr.vert.size(), Remap::InvalidIndex());
301 VertexIteratorLeft vp;
311 if(!selected || v.IsS())
313 size_t ind=Index(mr,v);
314 remap.vert[ind]=int(Index(ml,*vp));
319 remap.edge.resize(mr.edge.size(), Remap::InvalidIndex());
329 if(!selected || e.IsS()){
330 size_t ind=Index(mr,e);
331 remap.edge[ind]=int(Index(ml,*ep));
337 remap.face.resize(mr.face.size(), Remap::InvalidIndex());
347 if(!selected || f.IsS()){
348 size_t ind=Index(mr,f);
349 remap.face[ind]=int(Index(ml,*fp));
355 remap.hedge.resize(mr.hedge.size(),Remap::InvalidIndex());
359 if(!selected || he.IsS()){
360 size_t ind=Index(mr,he);
361 assert(remap.hedge[ind]==Remap::InvalidIndex());
362 HEdgeIteratorLeft hp = Allocator<MeshLeft>::AddHEdges(ml,1);
363 (*hp).ImportData(he);
364 remap.hedge[ind]=Index(ml,*hp);
368 remap.tetra.resize(mr.tetra.size(), Remap::InvalidIndex());
372 if (!selected || t.IsS()) {
373 size_t idx = Index(mr, t);
374 assert (remap.tetra[idx] == Remap::InvalidIndex());
375 TetraIteratorLeft tp = Allocator<MeshLeft>::AddTetras(ml, 1);
377 remap.tetra[idx] = Index(ml, *tp);
387 std::vector<unsigned int> mappingTextures(mr.textures.size());
389 unsigned int baseMlT = ml.textures.size();
390 for (
unsigned int i = 0; i < mr.textures.size(); ++i) {
391 auto it = std::find(ml.textures.begin(), ml.textures.end(), mr.textures[i]);
393 if (it == ml.textures.end()) {
395 mappingTextures[i] = baseMlT++;
396 ml.textures.push_back(mr.textures[i]);
400 mappingTextures[i] = it - ml.textures.begin();
409 bool vertTexFlag = HasPerVertexTexCoord(ml) && HasPerVertexTexCoord(mr);
414 if(!selected || v.IsS()){
415 VertexLeft &vl = ml.vert[remap.vert[Index(mr,v)]];
418 ImportVertexAdj(ml,mr,vl,v,remap);
420 if (size_t(v.T().n()) < mappingTextures.size()) {
422 vl.T().n() = mappingTextures[v.T().n()];
426 vl.T().n() = v.T().n();
435 if(!selected || e.IsS()){
436 ml.edge[remap.edge[Index(mr,e)]].ImportData(e);
438 EdgeLeft &el = ml.edge[remap.edge[Index(mr,e)]];
439 if(HasEVAdjacency(ml) && HasEVAdjacency(mr)){
440 el.V(0) = &ml.vert[remap.vert[Index(mr,e.cV(0))]];
441 el.V(1) = &ml.vert[remap.vert[Index(mr,e.cV(1))]];
443 if(adjFlag) ImportEdgeAdj(ml,mr,el,e,remap);
448 bool wedgeTexFlag = HasPerWedgeTexCoord(ml) && HasPerWedgeTexCoord(mr);
453 if(!selected || f.IsS())
455 FaceLeft &fl = ml.face[remap.face[Index(mr,f)]];
457 if(HasFVAdjacency(ml) && HasFVAdjacency(mr)){
458 for(int i = 0; i < fl.VN(); ++i)
459 fl.V(i) = &ml.vert[remap.vert[Index(mr,f.cV(i))]];
463 for(int i = 0; i < 3; ++i){
464 if (size_t(f.WT(i).n()) < mappingTextures.size()){
466 fl.WT(i).n() = mappingTextures[f.WT(i).n()];
470 fl.WT(i).n() = f.WT(i).n();
474 if(adjFlag) ImportFaceAdj(ml,mr,ml.face[remap.face[Index(mr,f)]],f,remap);
482 if(!selected || he.IsS()){
483 ml.hedge[remap.hedge[Index(mr,he)]].ImportData(he);
484 ImportHEdgeAdj(ml,mr,ml.hedge[remap.hedge[Index(mr,he)]],he,remap,selected);
491 if(!selected || t.IsS())
493 TetraLeft &tl = ml.tetra[remap.tetra[Index(mr,t)]];
495 if(HasFVAdjacency(ml) && HasFVAdjacency(mr)){
496 for(int i = 0; i < 4; ++i)
497 tl.V(i) = &ml.vert[remap.vert[Index(mr,t.cV(i))]];
500 if(adjFlag) ImportTetraAdj(ml, mr, ml.tetra[remap.tetra[Index(mr,t)]], t, remap);
516 typename std::set< PointerToAttribute >::iterator al, ar;
519 for (al = ml.vert_attr.begin(); al != ml.vert_attr.end(); ++al)
520 if(!(*al)._name.empty())
522 ar = mr.vert_attr.find(*al);
523 if (ar != mr.vert_attr.end())
526 for (
const auto & v : mr.vert)
528 if( !v.IsD() && (!selected || v.IsS()))
529 (*al)._handle->CopyValue(remap.vert[Index(mr,v)], id_r, (*ar)._handle);
536 for (al = ml.edge_attr.begin(); al != ml.edge_attr.end(); ++al)
537 if (!(*al)._name.empty())
539 ar = mr.edge_attr.find(*al);
540 if (ar!= mr.edge_attr.end())
543 for (
const auto & e : mr.edge)
545 if( !e.IsD() && (!selected || e.IsS()))
546 (*al)._handle->CopyValue(remap.edge[Index(mr,e)], id_r, (*ar)._handle);
553 for (al = ml.face_attr.begin(); al != ml.face_attr.end(); ++al)
554 if (!(*al)._name.empty())
556 ar = mr.face_attr.find(*al);
557 if (ar!= mr.face_attr.end())
560 for (
const auto & f : mr.face)
562 if( !f.IsD() && (!selected || f.IsS()))
563 (*al)._handle->CopyValue(remap.face[Index(mr,f)], id_r, (*ar)._handle);
570 for (al = ml.tetra_attr.begin(); al != ml.tetra_attr.end(); ++al)
571 if (!(*al)._name.empty())
573 ar = mr.tetra_attr.find(*al);
574 if (ar!= mr.tetra_attr.end())
577 for (
const auto & t: mr.tetra)
579 if( !t.IsD() && (!selected || t.IsS()))
580 (*al)._handle->CopyValue(remap.tetra[Index(mr, t)], id_r, (*ar)._handle);
601 static void MeshCopy(MeshLeft& ml, ConstMeshRight& mr,
bool selected=
false,
const bool adjFlag =
false)
604 Mesh(ml,mr,selected,adjFlag);
605 ml.bbox.Import(mr.bbox);
608 static void MeshCopyConst(MeshLeft& ml,
const ConstMeshRight& mr,
bool selected=
false,
const bool adjFlag =
false)
611 MeshAppendConst(ml,mr,selected,adjFlag);
612 ml.bbox.Import(mr.bbox);
619 static void Selected(MeshLeft& ml, ConstMeshRight& mr)
static EdgeIterator AddEdges(MeshType &m, size_t n, PointerUpdater< EdgePointer > &pu)
Add n edges to the mesh. Function to add n edges to the mesh. The elements are added always to the en...
Definition: allocate.h:333
static VertexIterator AddVertices(MeshType &m, size_t n, PointerUpdater< VertexPointer > &pu)
Add n vertices to the mesh. Function to add n vertices to the mesh. The elements are added always to ...
Definition: allocate.h:189
static FaceIterator AddFaces(MeshType &m, size_t n)
Function to add n faces to the mesh. First wrapper, with no parameters.
Definition: allocate.h:615
Class to safely duplicate and append (portion of) meshes.
Definition: append.h:40
static void MeshAppendConst(MeshLeft &ml, const ConstMeshRight &mr, const bool selected=false, const bool adjFlag=false)
MeshAppendConst.
Definition: append.h:288
static void MeshCopy(MeshLeft &ml, ConstMeshRight &mr, bool selected=false, const bool adjFlag=false)
Copy the second mesh over the first one. The first mesh is destroyed. If requested only the selected ...
Definition: append.h:601
static void Mesh(MeshLeft &ml, ConstMeshRight &mr, const bool selected=false, const bool adjFlag=false)
Append the second mesh to the first one.
Definition: append.h:253
static void Selected(MeshLeft &ml, ConstMeshRight &mr)
Append only the selected elements of second mesh to the first one.
Definition: append.h:619
static size_t VertexCount(const MeshType &m)
This function returns the number of selected vertices.
Definition: selection.h:300
static size_t EdgeCount(const MeshType &m)
This function returns the number of selected edges.
Definition: selection.h:290
static size_t FaceCount(const MeshType &m)
This function returns the number of selected faces.
Definition: selection.h:280
static size_t VertexFromEdgeLoose(MeshType &m, bool preserveSelection=false)
Select all the vertices that are touched by at least a single selected edge.
Definition: selection.h:399
static size_t VertexFromFaceLoose(MeshType &m, bool preserveSelection=false)
Select all the vertices that are touched by at least a single selected faces.
Definition: selection.h:386
void ForEachTetra(const MeshType &m, Callable action)
Definition: foreach.h:270
void ForEachEdge(const MeshType &m, Callable action)
Definition: foreach.h:222
void ForEachFace(const MeshType &m, Callable action)
Definition: foreach.h:78
void ForEachVertex(const MeshType &m, Callable action)
Definition: foreach.h:126
void ForEachHEdge(const MeshType &m, Callable action)
Definition: foreach.h:174
Definition: namespaces.dox:6