Added version of appending mesh that returns the remap

This commit is contained in:
iasonmanolas 2021-05-01 21:22:47 +03:00
parent 42abe0a955
commit 09f3407eb9
2 changed files with 232 additions and 3 deletions

View File

@ -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;

View File

@ -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