Added version of appending mesh that returns the remap
This commit is contained in:
parent
42abe0a955
commit
09f3407eb9
|
@ -295,9 +295,10 @@ static void AllocateEdge(MeshType &m)
|
|||
std::vector<FacePointer> fpVec;
|
||||
std::vector<int> eiVec;
|
||||
face::EFStarFF(Edges[i].f,Edges[i].z,fpVec,eiVec);
|
||||
for(size_t j=0;j<fpVec.size();++j)
|
||||
fpVec[j]->FEp(eiVec[j])=&(m.edge[i]);
|
||||
|
||||
for (size_t j = 0; j < fpVec.size(); ++j) {
|
||||
fpVec[j]->FEp(eiVec[j]) = &(m.edge[i]);
|
||||
assert(vcg::tri::IsValidPointer(m, fpVec[j]->cFEp(eiVec[j])));
|
||||
}
|
||||
// Edges[i].f->FE(Edges[i].z) = &(m.edge[i]);
|
||||
// Connect in loop the non manifold
|
||||
// FaceType* fpit=fp;
|
||||
|
|
|
@ -475,6 +475,234 @@ static void Mesh(MeshLeft& ml, ConstMeshRight& mr, const bool selected = false,
|
|||
// }
|
||||
}
|
||||
|
||||
static void Mesh(MeshLeft &ml,
|
||||
ConstMeshRight &mr,
|
||||
Remap &remap,
|
||||
const bool selected = false,
|
||||
const bool adjFlag = false)
|
||||
{
|
||||
// Note that if the the selection of the vertexes is not consistent with the face selection
|
||||
// the append could build faces referencing non existent vertices
|
||||
// so it is mandatory that the selection of the vertices reflects the loose selection
|
||||
// from edges and faces (e.g. if a face is selected all its vertices must be selected).
|
||||
// note the use of the parameter for preserving existing vertex selection.
|
||||
if (selected) {
|
||||
assert(adjFlag == false
|
||||
|| ml.IsEmpty()); // It is rather meaningless to partially copy adj relations.
|
||||
tri::UpdateSelection<ConstMeshRight>::VertexFromEdgeLoose(mr, true);
|
||||
tri::UpdateSelection<ConstMeshRight>::VertexFromFaceLoose(mr, true);
|
||||
}
|
||||
|
||||
// phase 1. allocate on ml vert,edge,face, hedge to accomodat those of mr
|
||||
// and build the remapping for all
|
||||
|
||||
// vertex
|
||||
remap.vert.resize(mr.vert.size(), Remap::InvalidIndex());
|
||||
VertexIteratorLeft vp;
|
||||
size_t svn = UpdateSelection<ConstMeshRight>::VertexCount(mr);
|
||||
if (selected)
|
||||
vp = Allocator<MeshLeft>::AddVertices(ml, int(svn));
|
||||
else
|
||||
vp = Allocator<MeshLeft>::AddVertices(ml, mr.vn);
|
||||
|
||||
for (VertexIteratorRight vi = mr.vert.begin(); vi != mr.vert.end(); ++vi) {
|
||||
if (!(*vi).IsD() && (!selected || (*vi).IsS())) {
|
||||
size_t ind = Index(mr, *vi);
|
||||
remap.vert[ind] = int(Index(ml, *vp));
|
||||
++vp;
|
||||
}
|
||||
}
|
||||
// edge
|
||||
remap.edge.resize(mr.edge.size(), Remap::InvalidIndex());
|
||||
EdgeIteratorLeft ep;
|
||||
size_t sen = UpdateSelection<ConstMeshRight>::EdgeCount(mr);
|
||||
if (selected)
|
||||
ep = Allocator<MeshLeft>::AddEdges(ml, sen);
|
||||
else
|
||||
ep = Allocator<MeshLeft>::AddEdges(ml, mr.en);
|
||||
|
||||
for (EdgeIteratorRight ei = mr.edge.begin(); ei != mr.edge.end(); ++ei)
|
||||
if (!(*ei).IsD() && (!selected || (*ei).IsS())) {
|
||||
size_t ind = Index(mr, *ei);
|
||||
remap.edge[ind] = int(Index(ml, *ep));
|
||||
++ep;
|
||||
}
|
||||
|
||||
// face
|
||||
remap.face.resize(mr.face.size(), Remap::InvalidIndex());
|
||||
FaceIteratorLeft fp;
|
||||
size_t sfn = UpdateSelection<ConstMeshRight>::FaceCount(mr);
|
||||
if (selected)
|
||||
fp = Allocator<MeshLeft>::AddFaces(ml, sfn);
|
||||
else
|
||||
fp = Allocator<MeshLeft>::AddFaces(ml, mr.fn);
|
||||
|
||||
for (FaceIteratorRight fi = mr.face.begin(); fi != mr.face.end(); ++fi)
|
||||
if (!(*fi).IsD() && (!selected || (*fi).IsS())) {
|
||||
size_t ind = Index(mr, *fi);
|
||||
remap.face[ind] = int(Index(ml, *fp));
|
||||
++fp;
|
||||
}
|
||||
|
||||
// hedge
|
||||
remap.hedge.resize(mr.hedge.size(), Remap::InvalidIndex());
|
||||
for (HEdgeIteratorRight hi = mr.hedge.begin(); hi != mr.hedge.end(); ++hi)
|
||||
if (!(*hi).IsD() && (!selected || (*hi).IsS())) {
|
||||
size_t ind = Index(mr, *hi);
|
||||
assert(remap.hedge[ind] == Remap::InvalidIndex());
|
||||
HEdgeIteratorLeft hp = Allocator<MeshLeft>::AddHEdges(ml, 1);
|
||||
(*hp).ImportData(*(hi));
|
||||
remap.hedge[ind] = Index(ml, *hp);
|
||||
}
|
||||
|
||||
remap.tetra.resize(mr.tetra.size(), Remap::InvalidIndex());
|
||||
for (TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti)
|
||||
if (!(*ti).IsD() && (!selected || (*ti).IsS())) {
|
||||
size_t idx = Index(mr, *ti);
|
||||
assert(remap.tetra[idx] == Remap::InvalidIndex());
|
||||
TetraIteratorLeft tp = Allocator<MeshLeft>::AddTetras(ml, 1);
|
||||
(*tp).ImportData(*ti);
|
||||
remap.tetra[idx] = Index(ml, *tp);
|
||||
}
|
||||
|
||||
// phase 2.
|
||||
// copy data from mr to its corresponding elements in ml and adjacencies
|
||||
|
||||
// vertex
|
||||
for (VertexIteratorRight vi = mr.vert.begin(); vi != mr.vert.end(); ++vi)
|
||||
if (!(*vi).IsD() && (!selected || (*vi).IsS())) {
|
||||
ml.vert[remap.vert[Index(mr, *vi)]].ImportData(*vi);
|
||||
if (adjFlag)
|
||||
ImportVertexAdj(ml, mr, ml.vert[remap.vert[Index(mr, *vi)]], *vi, remap);
|
||||
}
|
||||
|
||||
// edge
|
||||
for (EdgeIteratorRight ei = mr.edge.begin(); ei != mr.edge.end(); ++ei)
|
||||
if (!(*ei).IsD() && (!selected || (*ei).IsS())) {
|
||||
ml.edge[remap.edge[Index(mr, *ei)]].ImportData(*ei);
|
||||
// Edge to Vertex Adj
|
||||
EdgeLeft &el = ml.edge[remap.edge[Index(mr, *ei)]];
|
||||
if (HasEVAdjacency(ml) && HasEVAdjacency(mr)) {
|
||||
el.V(0) = &ml.vert[remap.vert[Index(mr, ei->cV(0))]];
|
||||
el.V(1) = &ml.vert[remap.vert[Index(mr, ei->cV(1))]];
|
||||
}
|
||||
if (adjFlag)
|
||||
ImportEdgeAdj(ml, mr, el, *ei, remap);
|
||||
}
|
||||
|
||||
// face
|
||||
const size_t textureOffset = ml.textures.size();
|
||||
bool WTFlag = HasPerWedgeTexCoord(mr) && (textureOffset > 0);
|
||||
for (FaceIteratorRight fi = mr.face.begin(); fi != mr.face.end(); ++fi)
|
||||
if (!(*fi).IsD() && (!selected || (*fi).IsS())) {
|
||||
FaceLeft &fl = ml.face[remap.face[Index(mr, *fi)]];
|
||||
fl.Alloc(fi->VN());
|
||||
if (HasFVAdjacency(ml) && HasFVAdjacency(mr)) {
|
||||
for (int i = 0; i < fl.VN(); ++i)
|
||||
fl.V(i) = &ml.vert[remap.vert[Index(mr, fi->cV(i))]];
|
||||
}
|
||||
fl.ImportData(*fi);
|
||||
if (WTFlag)
|
||||
for (int i = 0; i < fl.VN(); ++i)
|
||||
fl.WT(i).n() += short(textureOffset);
|
||||
if (adjFlag)
|
||||
ImportFaceAdj(ml, mr, ml.face[remap.face[Index(mr, *fi)]], *fi, remap);
|
||||
}
|
||||
|
||||
// hedge
|
||||
for (HEdgeIteratorRight hi = mr.hedge.begin(); hi != mr.hedge.end(); ++hi)
|
||||
if (!(*hi).IsD() && (!selected || (*hi).IsS())) {
|
||||
ml.hedge[remap.hedge[Index(mr, *hi)]].ImportData(*hi);
|
||||
ImportHEdgeAdj(ml, mr, ml.hedge[remap.hedge[Index(mr, *hi)]], *hi, remap, selected);
|
||||
}
|
||||
|
||||
//tetra
|
||||
for (TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti)
|
||||
if (!(*ti).IsD() && (!selected || (*ti).IsS())) {
|
||||
TetraLeft &tl = ml.tetra[remap.tetra[Index(mr, *ti)]];
|
||||
|
||||
if (HasFVAdjacency(ml) && HasFVAdjacency(mr)) {
|
||||
for (int i = 0; i < 4; ++i)
|
||||
tl.V(i) = &ml.vert[remap.vert[Index(mr, ti->cV(i))]];
|
||||
}
|
||||
tl.ImportData(*ti);
|
||||
if (adjFlag)
|
||||
ImportTetraAdj(ml, mr, ml.tetra[remap.tetra[Index(mr, *ti)]], *ti, remap);
|
||||
}
|
||||
|
||||
// phase 3.
|
||||
// take care of other per mesh data: textures, attributes
|
||||
|
||||
// At the end concatenate the vector with texture names.
|
||||
ml.textures.insert(ml.textures.end(), mr.textures.begin(), mr.textures.end());
|
||||
|
||||
// Attributes. Copy only those attributes that are present in both meshes
|
||||
// Two attributes in different meshes are considered the same if they have the same
|
||||
// name and the same type. This may be deceiving because they could in fact have
|
||||
// different semantic, but this is up to the developer.
|
||||
// If the left mesh has attributes that are not in the right mesh, their values for the elements
|
||||
// of the right mesh will be uninitialized
|
||||
|
||||
unsigned int id_r;
|
||||
typename std::set<PointerToAttribute>::iterator al, ar;
|
||||
|
||||
// per vertex attributes
|
||||
for (al = ml.vert_attr.begin(); al != ml.vert_attr.end(); ++al)
|
||||
if (!(*al)._name.empty()) {
|
||||
ar = mr.vert_attr.find(*al);
|
||||
if (ar != mr.vert_attr.end()) {
|
||||
id_r = 0;
|
||||
for (VertexIteratorRight vi = mr.vert.begin(); vi != mr.vert.end(); ++vi, ++id_r)
|
||||
if (!(*vi).IsD() && (!selected || (*vi).IsS()))
|
||||
(*al)._handle->CopyValue(remap.vert[Index(mr, *vi)], id_r, (*ar)._handle);
|
||||
}
|
||||
}
|
||||
|
||||
// per edge attributes
|
||||
for (al = ml.edge_attr.begin(); al != ml.edge_attr.end(); ++al)
|
||||
if (!(*al)._name.empty()) {
|
||||
ar = mr.edge_attr.find(*al);
|
||||
if (ar != mr.edge_attr.end()) {
|
||||
id_r = 0;
|
||||
for (EdgeIteratorRight ei = mr.edge.begin(); ei != mr.edge.end(); ++ei, ++id_r)
|
||||
if (!(*ei).IsD() && (!selected || (*ei).IsS()))
|
||||
(*al)._handle->CopyValue(remap.edge[Index(mr, *ei)], id_r, (*ar)._handle);
|
||||
}
|
||||
}
|
||||
|
||||
// per face attributes
|
||||
for (al = ml.face_attr.begin(); al != ml.face_attr.end(); ++al)
|
||||
if (!(*al)._name.empty()) {
|
||||
ar = mr.face_attr.find(*al);
|
||||
if (ar != mr.face_attr.end()) {
|
||||
id_r = 0;
|
||||
for (FaceIteratorRight fi = mr.face.begin(); fi != mr.face.end(); ++fi, ++id_r)
|
||||
if (!(*fi).IsD() && (!selected || (*fi).IsS()))
|
||||
(*al)._handle->CopyValue(remap.face[Index(mr, *fi)], id_r, (*ar)._handle);
|
||||
}
|
||||
}
|
||||
|
||||
// per tetra attributes
|
||||
for (al = ml.tetra_attr.begin(); al != ml.tetra_attr.end(); ++al)
|
||||
if (!(*al)._name.empty()) {
|
||||
ar = mr.tetra_attr.find(*al);
|
||||
if (ar != mr.tetra_attr.end()) {
|
||||
id_r = 0;
|
||||
for (TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti, ++id_r)
|
||||
if (!(*ti).IsD() && (!selected || (*ti).IsS()))
|
||||
(*al)._handle->CopyValue(remap.tetra[Index(mr, *ti)], id_r, (*ar)._handle);
|
||||
}
|
||||
}
|
||||
// per mesh attributes
|
||||
// if both ml and mr have an attribute with the same name, no action is done
|
||||
// if mr has an attribute that is NOT present in ml, the attribute is added to ml
|
||||
//for(ar = mr.mesh_attr.begin(); ar != mr.mesh_attr.end(); ++ar)
|
||||
// if(!(*ar)._name.empty()){
|
||||
// al = ml.mesh_attr.find(*ar);
|
||||
// if(al== ml.mesh_attr.end())
|
||||
// //...
|
||||
// }
|
||||
}
|
||||
/**
|
||||
* @brief MeshAppendConst
|
||||
* @param ml
|
||||
|
|
Loading…
Reference in New Issue