MeshKit
1.0
|
00001 #include "SurfProHarmonicMap.hpp" 00002 #include <iostream> 00003 #include <math.h> 00004 #include <map> 00005 00006 namespace MeshKit { 00007 00008 SurfProHarmonicMap::SurfProHarmonicMap(MKCore* core, iBase_EntityHandle s, iBase_EntityHandle t, iBase_EntityHandle v) 00009 { 00010 mk_core = core; 00011 source.gFaceHandle = s; 00012 target.gFaceHandle = t; 00013 volume = v; 00014 00015 irel_pair = mk_core->irel_pair(); 00016 irel_instance = mk_core->irel_instance(); 00017 igeom_instance = mk_core->igeom_instance(); 00018 imesh_instance = mk_core->imesh_instance(); 00019 00020 g_err = igeom_instance->getTagHandle("GLOBAL_ID", global_geom_tag); 00021 IBERRCHK(g_err, "Trouble get the geom_id_tag for 'GLOBAL_ID'."); 00022 m_err = imesh_instance->getTagHandle("GLOBAL_ID", global_mesh_tag); 00023 IBERRCHK(m_err, "Trouble get the mesh_id_tag for 'GLOBAL_ID'."); 00024 g_err = igeom_instance->createTag("HARMONIC_SURF_PROJECTION", 1, iBase_INTEGER, harmonic_surf_pro); 00025 IBERRCHK(g_err, "Trouble create the tag handle."); 00026 m_err = imesh_instance->createTag("HARMONIC_FACET_MESH", 1, iBase_INTEGER, facet_mesh_tag); 00027 IBERRCHK(m_err, "Trouble create the tag handle."); 00028 preprocessing(); 00029 getFacets(); 00030 } 00031 00032 void SurfProHarmonicMap::projection() 00033 { 00034 //compute the normal vector 00035 vector<Vector3D> normal_src, normal_tgt; 00036 normal_src.resize(src_facet_tri.size()); 00037 normal_tgt.resize(tgt_facet_tri.size()); 00038 for (unsigned int i = 0; i < src_facet_tri.size(); i++){ 00039 computeNormalTri(src_facet_tri[i], normal_src[i], source); 00040 //std::cout << "source index = " << i << "\tnrml = {" << normal_src[i][0] << "," << normal_src[i][1] << "," << normal_src[i][2] << "}\n"; 00041 } 00042 for (unsigned int i = 0; i < tgt_facet_tri.size(); i++){ 00043 computeNormalTri(tgt_facet_tri[i], normal_tgt[i], target); 00044 //std::cout << "target index = " << i << "\tnrml = {" << normal_tgt[i][0] << "," << normal_tgt[i][1] << "," << normal_tgt[i][2] << "}\n"; 00045 } 00046 00047 //loop over the interior nodes of quad mesh on the source surface and compute barycentric coordinates in the physical source surface 00048 for (vector<Vertex>::iterator it = quad_mesh_src.begin(); it != quad_mesh_src.end(); it++){ 00049 if (it->onBoundary) 00050 continue; 00051 //std::cout << "index=" << it->index << "\tsrc quad node xyz = {" << it->xyz[0] << "," << it->xyz[1] << "," << it->xyz[2] << "}\t"; 00052 Vector3D bary_coord_src, bary_coord_tgt; 00053 int tri_index = findFacetTri(src_facet_tri, normal_src, it->xyz, bary_coord_src); 00054 //compute the positions of all the quad mesh nodes on the unit disk 00055 it->uv[0] = 0.0; 00056 it->uv[1] = 0.0; 00057 for (int i = 0; i < 3; i++){ 00058 it->uv[0] += bary_coord_src[i]*src_facet_tri[tri_index].connect[i]->uv[0]; 00059 it->uv[1] += bary_coord_src[i]*src_facet_tri[tri_index].connect[i]->uv[1]; 00060 } 00061 //std::cout << "\t\tsrc uv={" << it->uv[0] << "," << it->uv[1] << "} facet index=" << tri_index << "\tv1={" << src_facet_tri[tri_index].connect[0]->xyz[0] << "," << src_facet_tri[tri_index].connect[0]->xyz[1] << "," << src_facet_tri[tri_index].connect[0]->xyz[2] << "} v2={" << src_facet_tri[tri_index].connect[1]->xyz[0] << "," << src_facet_tri[tri_index].connect[1]->xyz[1] << "," << src_facet_tri[tri_index].connect[1]->xyz[2] << "} v3={" << src_facet_tri[tri_index].connect[2]->xyz[0] << "," << src_facet_tri[tri_index].connect[2]->xyz[1] << "," << src_facet_tri[tri_index].connect[2]->xyz[2] << "}\n"; 00062 //compute the barycentric coordinates of those quad mesh nodes on the unit disk of target surface 00063 tri_index = findFacetTri(tgt_facet_tri, it->uv, bary_coord_tgt); 00064 Vector3D xyz(0.0); 00065 for (int i = 0; i < 3; i++) 00066 for (int j = 0; j < 3; j++) 00067 xyz[j] += bary_coord_tgt[i]*tgt_facet_tri[tri_index].connect[i]->xyz[j]; 00068 00069 00070 g_err = igeom_instance->getEntClosestPtTrimmed(target.gFaceHandle, xyz[0], xyz[1], xyz[2], quad_mesh_tgt[it->index].xyz[0], quad_mesh_tgt[it->index].xyz[1], quad_mesh_tgt[it->index].xyz[2]); 00071 IBERRCHK(g_err, "Trouble get the trimmed closed point positions on the target surface!"); 00072 00073 //std::cout << "\t\ttgt uvw={" << bary_coord_tgt[0] << "," << bary_coord_tgt[1] << "," << bary_coord_tgt[2] << "} facet index=" << tri_index << "\tv1={" << tgt_facet_tri[tri_index].connect[0]->xyz[0] << "," << tgt_facet_tri[tri_index].connect[0]->xyz[1] << "," << tgt_facet_tri[tri_index].connect[0]->xyz[2] << "} v2={" << tgt_facet_tri[tri_index].connect[1]->xyz[0] << "," << tgt_facet_tri[tri_index].connect[1]->xyz[1] << "," << tgt_facet_tri[tri_index].connect[1]->xyz[2] << "} v3={" << tgt_facet_tri[tri_index].connect[2]->xyz[0] << "," << tgt_facet_tri[tri_index].connect[2]->xyz[1] << "," << tgt_facet_tri[tri_index].connect[2]->xyz[2] << "}\n"; 00074 //std::cout << "\t\tprojected pts xyz = {" << quad_mesh_tgt[it->index].xyz[0] << "," << quad_mesh_tgt[it->index].xyz[1] << "," << quad_mesh_tgt[it->index].xyz[2] << "}\ttmp = {" << xyz[0] << "," << xyz[1] << "," << xyz[2] << "}\n"; 00075 } 00076 /* 00077 vector<iBase_EntityHandle> nodes(quad_mesh_tgt.size()); 00078 for (unsigned int i = 0; i < quad_mesh_src.size(); i++){ 00079 if (quad_mesh_src[i].onBoundary) 00080 continue; 00081 //create vtx 00082 m_err = imesh_instance->createVtx(quad_mesh_tgt[i].xyz[0], quad_mesh_tgt[i].xyz[1], quad_mesh_tgt[i].xyz[2], nodes[i]); 00083 IBERRCHK(m_err, "Trouble create vtx ent!"); 00084 } 00085 00086 00087 for (unsigned int i = 0; i < facelist.size(); i++){ 00088 bool is_boundary = true; 00089 for (int j = 0; j < 4; j++) 00090 is_boundary = is_boundary && !facelist[i].connect[j]->onBoundary; 00091 if (is_boundary){ 00092 iBase_EntityHandle quads; 00093 vector<iBase_EntityHandle> tmp; 00094 tmp.push_back(nodes[facelist[i].connect[0]->index]); 00095 tmp.push_back(nodes[facelist[i].connect[1]->index]); 00096 tmp.push_back(nodes[facelist[i].connect[2]->index]); 00097 tmp.push_back(nodes[facelist[i].connect[3]->index]); 00098 m_err = imesh_instance->createEnt(iMesh_QUADRILATERAL, &tmp[0], 4, quads); 00099 IBERRCHK(m_err, "Trouble create an face entity!"); 00100 } 00101 } 00102 */ 00103 cleanup(); 00104 } 00105 00106 bool SurfProHarmonicMap::ComputeBarycentric(Vector3D a, Vector3D b, Vector3D c, Vector3D xyz, Vector3D &uvw) 00107 { 00108 //Compute vectors; 00109 Vector3D v0 = b - a; 00110 Vector3D v1 = c - a; 00111 Vector3D v2 = xyz - a; 00112 //compute dot products 00113 double dot00 = v0[0]*v0[0] + v0[1]*v0[1] + v0[2]*v0[2]; 00114 double dot01 = v0[0]*v1[0] + v0[1]*v1[1] + v0[2]*v1[2]; 00115 double dot02 = v0[0]*v2[0] + v0[1]*v2[1] + v0[2]*v2[2]; 00116 double dot11 = v1[0]*v1[0] + v1[1]*v1[1] + v1[2]*v1[2]; 00117 double dot12 = v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; 00118 //compute barycentric coordinates 00119 double invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01); 00120 uvw[1] = (dot11 * dot02 - dot01 * dot12) * invDenom; 00121 uvw[2] = (dot00 * dot12 - dot01 * dot02) * invDenom; 00122 uvw[0] = 1.0 - uvw[1] - uvw[2]; 00123 00124 //check if the point is in the triangle 00125 return (uvw[0]>=0)&&(uvw[1]>=0)&&(uvw[0]+uvw[1]<=1); 00126 } 00127 00128 void SurfProHarmonicMap::test() 00129 { 00130 vector<iBase_EntityHandle> test_nodes(src_facet_v.size()), test_edges(src_facet_e.size()), test_tri(src_facet_tri.size()); 00131 for (vector<Vertex>::iterator it = src_facet_v.begin(); it != src_facet_v.end(); it++){ 00132 m_err = imesh_instance->createVtx(it->uv[0], it->uv[1], 200.0, test_nodes[it->index]); 00133 IBERRCHK(m_err, "Trouble create a test vertex!"); 00134 } 00135 for (vector<Face>::iterator it = src_facet_tri.begin(); it != src_facet_tri.end(); it++){ 00136 vector<iBase_EntityHandle> tmp; 00137 tmp.push_back(test_nodes[it->connect[0]->index]); 00138 tmp.push_back(test_nodes[it->connect[1]->index]); 00139 tmp.push_back(test_nodes[it->connect[2]->index]); 00140 m_err = imesh_instance->createEnt(iMesh_TRIANGLE, &tmp[0], tmp.size(), test_tri[it->index]); 00141 IBERRCHK(m_err, "Trouble create a triangle mesh entity!"); 00142 } 00143 test_nodes.clear(); 00144 test_edges.clear(); 00145 test_tri.clear(); 00146 test_nodes.resize(tgt_facet_v.size()); 00147 test_tri.resize(tgt_facet_tri.size()); 00148 00149 for (vector<Vertex>::iterator it = tgt_facet_v.begin(); it != tgt_facet_v.end(); it++){ 00150 m_err = imesh_instance->createVtx(it->uv[0], it->uv[1], -200.0, test_nodes[it->index]); 00151 IBERRCHK(m_err, "Trouble create a test vertex!"); 00152 //std::cout << "unit disk vertex index = " << it->index << "\tuv = {" << it->uv[0] << ", " << it->uv[1] << "}\tis_boundary = " << it->onBoundary << std::endl; 00153 } 00154 for (vector<Face>::iterator it = tgt_facet_tri.begin(); it != tgt_facet_tri.end(); it++){ 00155 vector<iBase_EntityHandle> tmp; 00156 tmp.push_back(test_nodes[it->connect[0]->index]); 00157 tmp.push_back(test_nodes[it->connect[1]->index]); 00158 tmp.push_back(test_nodes[it->connect[2]->index]); 00159 m_err = imesh_instance->createEnt(iMesh_TRIANGLE, &tmp[0], tmp.size(), test_tri[it->index]); 00160 IBERRCHK(m_err, "Trouble create a triangle mesh entity!"); 00161 } 00162 } 00163 00164 void SurfProHarmonicMap::cleanup(){ 00165 vector<iBase_EntityHandle> ents_to_del; 00166 for (vector<Edge>::iterator it = src_facet_e.begin(); it != src_facet_e.end(); it++) 00167 ents_to_del.push_back(it->gEdgeHandle); 00168 for (vector<Edge>::iterator it = tgt_facet_e.begin(); it != tgt_facet_e.end(); it++) 00169 ents_to_del.push_back(it->gEdgeHandle); 00170 for (vector<Face>::iterator it = src_facet_tri.begin(); it != src_facet_tri.end(); it++) 00171 ents_to_del.push_back(it->gFaceHandle); 00172 for (vector<Face>::iterator it = tgt_facet_tri.begin(); it != tgt_facet_tri.end(); it++) 00173 ents_to_del.push_back(it->gFaceHandle); 00174 for (vector<Vertex>::iterator it = src_facet_v.begin(); it != src_facet_v.end(); it++) 00175 ents_to_del.push_back(it->gVertexHandle); 00176 for (vector<Vertex>::iterator it = tgt_facet_v.begin(); it != tgt_facet_v.end(); it++) 00177 ents_to_del.push_back(it->gVertexHandle); 00178 m_err = imesh_instance->rmvArrTag(&ents_to_del[0], ents_to_del.size(), facet_mesh_tag); 00179 IBERRCHK(m_err, "Trouble remove the tag data!"); 00180 m_err = imesh_instance->deleteEntArr(&ents_to_del[0], ents_to_del.size()); 00181 IBERRCHK(m_err, "Trouble delete entities!"); 00182 g_err = igeom_instance->destroyTag(harmonic_surf_pro, true); 00183 IBERRCHK(g_err, "Trouble delete a tag!"); 00184 m_err = imesh_instance->destroyTag(facet_mesh_tag, true); 00185 IBERRCHK(g_err, "Trouble delete a tag!"); 00186 00187 } 00188 00189 int SurfProHarmonicMap::findFacetTri(vector<Face> &facet_tri, Vector2D uv, Vector3D &uvw){ 00190 for (unsigned int i = 0; i < facet_tri.size(); i++){ 00191 if (ComputeBarycentric(facet_tri[i].connect[0]->uv, facet_tri[i].connect[1]->uv, facet_tri[i].connect[2]->uv, uv, uvw)) 00192 return i; 00193 } 00194 00195 return -1; 00196 } 00197 00198 bool SurfProHarmonicMap::ComputeBarycentric(Vector2D a, Vector2D b, Vector2D c, Vector2D xy, Vector3D &uvw) 00199 { 00200 //Compute vectors; 00201 Vector2D v0 = b - a; 00202 Vector2D v1 = c - a; 00203 Vector2D v2 = xy - a; 00204 //compute dot products 00205 double dot00 = v0[0]*v0[0] + v0[1]*v0[1]; 00206 double dot01 = v0[0]*v1[0] + v0[1]*v1[1]; 00207 double dot02 = v0[0]*v2[0] + v0[1]*v2[1]; 00208 double dot11 = v1[0]*v1[0] + v1[1]*v1[1]; 00209 double dot12 = v1[0]*v2[0] + v1[1]*v2[1]; 00210 //compute barycentric coordinates 00211 double invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01); 00212 uvw[1] = (dot11 * dot02 - dot01 * dot12) * invDenom; 00213 uvw[2] = (dot00 * dot12 - dot01 * dot02) * invDenom; 00214 uvw[0] = 1.0 - uvw[1] - uvw[2]; 00215 00216 //check if the point is in the triangle 00217 return (uvw[0]>=0)&&(uvw[1]>=0)&&(uvw[0]+uvw[1]<=1); 00218 } 00219 //compute the normal of a triangle 00220 void SurfProHarmonicMap::computeNormalTri(Face &tri, Vector3D& nrml, Face surf) 00221 { 00222 Vector3D a = tri.connect[0]->xyz, b = tri.connect[1]->xyz, c = tri.connect[2]->xyz; 00223 Vector3D va = b - a, vb = c - b; 00224 nrml[0] = va[1]*vb[2] - va[2]*vb[1]; 00225 nrml[1] = va[2]*vb[0] - va[0]*vb[2]; 00226 nrml[2] = va[0]*vb[1] - va[1]*vb[0]; 00227 double len = sqrt(nrml[0]*nrml[0] + nrml[1]*nrml[1] + nrml[2]*nrml[2]); 00228 for (int i = 0; i < 3; i++) 00229 nrml[i] /= len; 00230 00231 Vector3D surf_nrml(0.0); 00232 g_err = igeom_instance->getEntNrmlXYZ(surf.gFaceHandle, tri.connect[0]->xyz[0], tri.connect[0]->xyz[1], tri.connect[0]->xyz[2], surf_nrml[0], surf_nrml[1], surf_nrml[2]); 00233 IBERRCHK(g_err, "Trouble get the surface normal at a given position!"); 00234 double dotproduct = surf_nrml[0]*nrml[0] + surf_nrml[1]*nrml[1] + surf_nrml[2]*nrml[2]; 00235 if (dotproduct < 0){ 00236 for (int j = 0; j < 3; j++) 00237 nrml[j] = -1.0*nrml[j]; 00238 Vertex *tmp_vtx = tri.connect[1]; 00239 tri.connect[1] = tri.connect[2]; 00240 tri.connect[2] = tmp_vtx; 00241 } 00242 } 00243 //find a specific triangle where the point is located 00244 int SurfProHarmonicMap::findFacetTri(vector<Face> &facet_tri, vector<Vector3D> nrml, Vector3D xyz, Vector3D &uvw) 00245 { 00246 for (unsigned int i = 0; i < facet_tri.size(); i++){ 00247 Vector3D prj_pts; 00248 prjPtsToTri(facet_tri[i], xyz, nrml[i], prj_pts); 00249 00250 //bool test_bool = ComputeBarycentric(facet_tri[i].connect[0]->xyz, facet_tri[i].connect[1]->xyz, facet_tri[i].connect[2]->xyz, prj_pts, uvw); 00251 //std::cout << "\t\t\tindex = " << i << "\tbool = "<< test_bool << "\tbary uvw = {" << uvw[0] << "," << uvw[1] << "," << uvw[2] << "}\n"; 00252 00253 if (ComputeBarycentric(facet_tri[i].connect[0]->xyz, facet_tri[i].connect[1]->xyz, facet_tri[i].connect[2]->xyz, prj_pts, uvw)){ 00254 //std::cout << "projected pts = {" << prj_pts[0] << "," << prj_pts[1] << "," << prj_pts[2] << "}\n"; 00255 //double x = uvw[0]*facet_tri[i].connect[0]->xyz[0]+uvw[1]*facet_tri[i].connect[1]->xyz[0]+uvw[2]*facet_tri[i].connect[2]->xyz[0]; 00256 //double y = uvw[0]*facet_tri[i].connect[0]->xyz[1]+uvw[1]*facet_tri[i].connect[1]->xyz[1]+uvw[2]*facet_tri[i].connect[2]->xyz[1]; 00257 //double z = uvw[0]*facet_tri[i].connect[0]->xyz[2]+uvw[1]*facet_tri[i].connect[1]->xyz[2]+uvw[2]*facet_tri[i].connect[2]->xyz[2]; 00258 //std::cout << "\t\t\tx = " << x << " y = " << y << " z = " << z << std::endl; 00259 return i; 00260 00261 } 00262 } 00263 00264 return -1; 00265 } 00266 //project the point onto a plane determined by triangle 00267 void SurfProHarmonicMap::prjPtsToTri(Face tri, Vector3D pts, Vector3D nrml, Vector3D &xyz) 00268 { 00269 Vector3D origin = tri.connect[0]->xyz; 00270 Vector3D v = pts - origin; 00271 double dist = v[0]*nrml[0] + v[1]*nrml[1] + v[2]*nrml[2]; 00272 xyz = origin + v - dist*nrml; 00273 } 00274 00275 void SurfProHarmonicMap::setMeshData(vector<Vertex> &s, vector<Vertex> &t, vector<Face> &f){ 00276 quad_mesh_src.insert(quad_mesh_src.begin(), s.begin(), s.end()); 00277 quad_mesh_tgt.insert(quad_mesh_tgt.begin(), t.begin(), t.end()); 00278 facelist.insert(facelist.begin(), f.begin(), f.end()); 00279 } 00280 00281 void SurfProHarmonicMap::getMeshData(vector<Vertex> &v){ 00282 int index = -1; 00283 for (vector<Vertex>::iterator it = quad_mesh_tgt.begin(); it != quad_mesh_tgt.end(); it++){ 00284 index++; 00285 if (it->onBoundary) 00286 continue; 00287 v[index].xyz[0] = it->xyz[0]; 00288 v[index].xyz[1] = it->xyz[1]; 00289 v[index].xyz[2] = it->xyz[2]; 00290 } 00291 00292 } 00293 00294 void SurfProHarmonicMap::match() 00295 { 00296 //outmost boundary will be distributed on the unit disk 00297 boundaryDistribution(); 00298 ComputeWeight(); 00299 //extra processing of interior loops 00300 00301 HarmonicMapper hm_src(mk_core, src_facet_v, src_facet_tri, src_facet_e, adj_src); 00302 hm_src.execute(); 00303 hm_src.getUV(src_facet_v); 00304 00305 LocateBoundaryNodesTarget(); 00306 00307 HarmonicMapper hm_tgt(mk_core, tgt_facet_v, tgt_facet_tri, tgt_facet_e, adj_tgt); 00308 hm_tgt.execute(); 00309 hm_tgt.getUV(tgt_facet_v); 00310 00311 //test(); 00312 } 00313 00314 void SurfProHarmonicMap::LocateBoundaryNodesTarget() 00315 { 00316 std::set<int> set_edges, set_vertices; 00317 for (unsigned int i = 0; i < target.connEdges.size(); i++) 00318 set_edges.insert(target.connEdges[i]->index); 00319 for (unsigned int i = 0; i < source.connect.size(); i++) 00320 set_vertices.insert(source.connect[i]->index); 00321 00322 //match the vertices between the source and target surface. 00323 std::map<int,int> tgt_src_v, tgt_src_e; 00324 int count = -1; 00325 for (unsigned int mm = 0; mm < target.vertexloops.size(); mm++){ 00326 for (unsigned int i = 0; i < target.vertexloops[mm].size(); i++){ 00327 count++; 00328 tgt_src_v[count] = -1; 00329 bool is_found = false; 00330 int edge_index = -1; 00331 int pre_vertex = target.vertexloops[mm][i]; 00332 int next_vertex = -1; 00333 while(!is_found){ 00334 vector<iBase_EntityHandle> adj; 00335 //get the adjacent edges of a vertex 00336 g_err = igeom_instance->getEntAdj(vertices[pre_vertex].gVertexHandle, iBase_EDGE, adj); 00337 IBERRCHK(g_err, "Trouble get the adjacent edges around a vertex"); 00338 //find the edge on the linking surface 00339 if (edge_index != -1){ 00340 //get edges on the linking surfaces 00341 set_edges.clear(); 00342 std::vector<iBase_EntityHandle> adj_faces; 00343 g_err = igeom_instance->getEntAdj(edges[edge_index].gEdgeHandle, iBase_FACE, adj_faces); 00344 IBERRCHK(g_err, "Trouble get the adjacent faces around an edge"); 00345 for (std::vector<iBase_EntityHandle>::iterator it = adj_faces.begin(); it != adj_faces.end(); it++){ 00346 vector<iBase_EntityHandle> adj_edges; 00347 g_err = igeom_instance->getEntAdj(*it, iBase_EDGE, adj_edges); 00348 IBERRCHK(g_err, "Trouble get the adjacent edges around a face!"); 00349 for (vector<iBase_EntityHandle>::iterator it_e = adj_edges.begin(); it_e != adj_edges.end(); it_e++){ 00350 int intdata = -1; 00351 g_err = igeom_instance->getIntData(*it_e, harmonic_surf_pro, intdata); 00352 IBERRCHK(g_err, "Trouble get the int data for an edge"); 00353 set_edges.insert(intdata); 00354 } 00355 } 00356 } 00357 //proceed to the next linking edge 00358 is_found = true; 00359 for (vector<iBase_EntityHandle>::iterator it = adj.begin(); it != adj.end(); it++){ 00360 g_err = igeom_instance->getIntData(*it, harmonic_surf_pro, edge_index); 00361 IBERRCHK(g_err, "Trouble get the adjacent edges of a vertex!"); 00362 if (std::find(set_edges.begin(), set_edges.end(), edge_index)==set_edges.end()){//this is an edge on the linking surface. 00363 is_found = is_found && false; 00364 break; 00365 } 00366 else{ 00367 is_found = is_found && true; 00368 continue; 00369 } 00370 } 00371 //find the next vertex connected by the linking edge 00372 if (edges[edge_index].connect[0]->index == pre_vertex) 00373 next_vertex = edges[edge_index].connect[1]->index; 00374 else 00375 next_vertex = edges[edge_index].connect[0]->index; 00376 //check whether next vertex is on the source surface or not 00377 if (is_found) 00378 break; 00379 } 00380 tgt_src_v[target.vertexloops[mm][i]] = next_vertex; 00381 } 00382 } 00383 //done with the mapping of vertices between the source and target surfaces; 00384 //test the vertex mapping between source and target 00385 count = -1; 00386 for (unsigned int mm = 0; mm < target.vertexloops.size(); mm++){ 00387 for (unsigned int i = 0; i < target.vertexloops[mm].size(); i++){ 00388 int tgt_edge_index = target.edgeloops[mm][i]; 00389 int vtx_a = tgt_src_v[edges[tgt_edge_index].connect[0]->index], vtx_b = tgt_src_v[edges[tgt_edge_index].connect[1]->index]; 00390 for (unsigned int j = 0; j < source.connEdges.size(); j++){ 00391 int vtx_c = (source.connEdges[j]->connect[0])->index, vtx_d = (source.connEdges[j]->connect[1])->index; 00392 if (((vtx_c == vtx_a)&&(vtx_d == vtx_b))||((vtx_c == vtx_b)&&(vtx_d == vtx_a))){ 00393 tgt_src_e[tgt_edge_index] = source.connEdges[j]->index; 00394 break; 00395 } 00396 } 00397 } 00398 } 00399 00400 count = -1; 00401 map<int, int> src_vtx_facet; 00402 vector<vector<int> > src_nodes_list; 00403 vector<vector<double> > src_nodes_u; 00404 src_nodes_list.resize(edges.size()); 00405 src_nodes_u.resize(edges.size()); 00406 for (unsigned int i = 0; i < source.edgeloops.size(); i++){ 00407 00408 for (unsigned int j = 0; j < source.edgeloops[i].size(); j++){ 00409 count++; 00410 double u; 00411 for (list<int>::iterator it = src_geom_facet[count+source.connect.size()].begin(); it != src_geom_facet[count+source.connect.size()].end(); it++){ 00412 src_nodes_list[source.edgeloops[i][j]].push_back(*it); 00413 g_err = igeom_instance->getEntXYZtoU(edges[source.edgeloops[i][j]].gEdgeHandle, src_facet_v[*it].xyz[0], src_facet_v[*it].xyz[1], src_facet_v[*it].xyz[2], u); 00414 IBERRCHK(g_err, "Trouble get the u coordinates!"); 00415 src_nodes_u[source.edgeloops[i][j]].push_back(u); 00416 } 00417 } 00418 } 00419 count = -1; 00420 for (unsigned int i = 0; i < source.vertexloops.size(); i++){ 00421 for (unsigned int j = 0; j < source.vertexloops[i].size(); j++){ 00422 count++; 00423 src_vtx_facet[source.vertexloops[i][j]] = *(src_geom_facet[count].begin()); 00424 00425 } 00426 } 00427 //match the boundary facet nodes between source and target 00428 count = -1; 00429 for (unsigned int i = 0; i < target.vertexloops.size(); i++){ 00430 //loop i 00431 vector<iBase_EntityHandle> tmp_src, tmp_tgt; 00432 vector<double> dist_source, dist_target; 00433 for (unsigned int j = 0; j < target.edgeloops[i].size(); j++){ 00434 tmp_src.push_back(edges[target.edgeloops[i][j]].gEdgeHandle); 00435 tmp_tgt.push_back(edges[tgt_src_e[target.edgeloops[i][j]]].gEdgeHandle); 00436 } 00437 dist_source.resize(tmp_src.size()); 00438 g_err = igeom_instance->measure(&tmp_src[0], tmp_src.size(), &dist_source[0]); 00439 IBERRCHK(g_err, "Trouble get the measure of geometric edges!"); 00440 00441 dist_target.resize(tmp_tgt.size()); 00442 g_err = igeom_instance->measure(&tmp_tgt[0], tmp_tgt.size(), &dist_target[0]); 00443 IBERRCHK(g_err, "Trouble get the measure of geometric edges!"); 00444 for (unsigned int j = 0; j < target.vertexloops[i].size(); j++){ 00445 count++; 00446 int current_tgt_vtx = target.vertexloops[i][j], current_src_vtx = tgt_src_v[current_tgt_vtx]; 00447 int next_tgt_vtx = target.vertexloops[i][(j+1+target.vertexloops[i].size())%target.vertexloops[i].size()], next_src_vtx = tgt_src_v[next_tgt_vtx]; 00448 int tgt_edge_index = target.edgeloops[i][j]; 00449 int src_edge_index = tgt_src_e[tgt_edge_index]; 00450 double u1, u2, u3, u4, u; 00451 g_err = igeom_instance->getEntXYZtoU(edges[tgt_edge_index].gEdgeHandle, vertices[current_tgt_vtx].xyz[0], vertices[current_tgt_vtx].xyz[1], vertices[current_tgt_vtx].xyz[2], u1); 00452 IBERRCHK(g_err, "Trouble get the parametric coordinate of a vertex on an edge!"); 00453 g_err = igeom_instance->getEntXYZtoU(edges[tgt_edge_index].gEdgeHandle, vertices[next_tgt_vtx].xyz[0], vertices[next_tgt_vtx].xyz[1], vertices[next_tgt_vtx].xyz[2], u2); 00454 IBERRCHK(g_err, "Trouble get the parametric coordinate of a vertex on an edge!"); 00455 g_err = igeom_instance->getEntXYZtoU(edges[src_edge_index].gEdgeHandle, vertices[current_src_vtx].xyz[0], vertices[current_src_vtx].xyz[1], vertices[current_src_vtx].xyz[2], u3); 00456 IBERRCHK(g_err, "Trouble get the parametric coordinate of a vertex on an edge!"); 00457 g_err = igeom_instance->getEntXYZtoU(edges[src_edge_index].gEdgeHandle, vertices[next_src_vtx].xyz[0], vertices[next_src_vtx].xyz[1], vertices[next_src_vtx].xyz[2], u4); 00458 IBERRCHK(g_err, "Trouble get the parametric coordinate of a vertex on an edge!"); 00459 int count_pts = 0; 00460 int tgt_vtx_index = *(tgt_geom_facet[count].begin()); 00461 tgt_facet_v[tgt_vtx_index].onBoundary = true; 00462 tgt_facet_v[tgt_vtx_index].uv[0] = src_facet_v[src_vtx_facet[current_src_vtx]].uv[0]; 00463 tgt_facet_v[tgt_vtx_index].uv[1] = src_facet_v[src_vtx_facet[current_src_vtx]].uv[1]; 00464 00465 std::cout << "--------\nu = {" << u3 << " "; 00466 for (int m = src_nodes_u[src_edge_index].size()-1; m >= 0; m--) 00467 std::cout << "[" << m << "]" << src_nodes_u[src_edge_index][m] << " "; 00468 std::cout << u4 << "}\n--------\n"; 00469 for (list<int>::iterator it = tgt_geom_facet[count+target.connect.size()].begin(); it != tgt_geom_facet[count+target.connect.size()].end(); it++){ 00470 count_pts++; 00471 g_err = igeom_instance->getEntXYZtoU(edges[tgt_edge_index].gEdgeHandle, tgt_facet_v[*it].xyz[0], tgt_facet_v[*it].xyz[1], tgt_facet_v[*it].xyz[2], u); 00472 IBERRCHK(g_err, "Trouble get the parametric coordinate of a vertex on an edge!"); 00473 double u_src = (u4 - u3)*(u - u1)/(u2 - u1) + u3; 00474 00475 tgt_facet_v[*it].onBoundary = true; 00476 //how to compute the corresponding uv coordinates of each nodes on the source H_1 00477 //loop over facet nodes 00478 //cases to be discussed: (1) no facet nodes (2) last facet nodes (3) first facet nodes 00479 int pre_facet_v = -1, next_facet_v = -1; 00480 double pre_facet_u = 0.0, next_facet_u = 0.0; 00481 if (src_nodes_u[src_edge_index].size() == 0){//no facet nodes 00482 //it will be a straight line between current_src_vtx and next_src_vtx 00483 pre_facet_v = src_vtx_facet[current_src_vtx]; 00484 next_facet_v = src_vtx_facet[next_src_vtx]; 00485 pre_facet_u = u3; 00486 next_facet_u = u4; 00487 } 00488 else{ 00489 for (int m = src_nodes_u[src_edge_index].size()-1; m >= 0; m--){ 00490 if (u4 > u3){ 00491 if (m == 0)//it is located before the first item 00492 if (u_src >= src_nodes_u[src_edge_index][0]){ 00493 next_facet_v = src_vtx_facet[next_src_vtx]; 00494 next_facet_u = u4; 00495 pre_facet_v = src_nodes_list[src_edge_index][0]; 00496 pre_facet_u = src_nodes_u[src_edge_index][0]; 00497 break; 00498 } 00499 if (m == (src_nodes_u[src_edge_index].size()-1)){//it is located after the last item 00500 int tmp_index = src_nodes_list[src_edge_index].size() -1; 00501 if (u_src <= src_nodes_u[src_edge_index][tmp_index]){ 00502 next_facet_v = src_nodes_list[src_edge_index][tmp_index]; 00503 next_facet_u = src_nodes_u[src_edge_index][tmp_index]; 00504 pre_facet_v = src_vtx_facet[current_src_vtx]; 00505 pre_facet_u = u3; 00506 break; 00507 } 00508 } 00509 if (src_nodes_u[src_edge_index][m] >= u_src){//it is located between items 00510 if ((m+1)==src_nodes_list[src_edge_index].size()){ 00511 pre_facet_v = src_vtx_facet[current_src_vtx]; 00512 pre_facet_u = u3; 00513 } 00514 else{ 00515 pre_facet_v = src_nodes_list[src_edge_index][m+1]; 00516 pre_facet_u = src_nodes_u[src_edge_index][m+1]; 00517 } 00518 00519 next_facet_v = src_nodes_list[src_edge_index][m]; 00520 next_facet_u = src_nodes_u[src_edge_index][m]; 00521 break; 00522 } 00523 00524 } 00525 else{ 00526 if (m == 0)//it is located before the first item 00527 if (u_src <= src_nodes_u[src_edge_index][0]){ 00528 next_facet_v = src_vtx_facet[next_src_vtx]; 00529 next_facet_u = u4; 00530 pre_facet_v = src_nodes_list[src_edge_index][0]; 00531 pre_facet_u = src_nodes_u[src_edge_index][0]; 00532 break; 00533 } 00534 if (m == (src_nodes_u[src_edge_index].size()-1)){//it is located after the last item 00535 int tmp_index = src_nodes_list[src_edge_index].size() -1; 00536 if (u_src >= src_nodes_u[src_edge_index][tmp_index]){ 00537 next_facet_v = src_nodes_list[src_edge_index][tmp_index]; 00538 next_facet_u = src_nodes_u[src_edge_index][tmp_index]; 00539 pre_facet_v = src_vtx_facet[current_src_vtx]; 00540 pre_facet_u = u3; 00541 break; 00542 } 00543 } 00544 if (src_nodes_u[src_edge_index][m] <= u_src){ 00545 next_facet_v = src_nodes_list[src_edge_index][m]; 00546 next_facet_u = src_nodes_u[src_edge_index][m]; 00547 if ((m+1)==src_nodes_list[src_edge_index].size()){ 00548 pre_facet_v = src_vtx_facet[current_src_vtx]; 00549 pre_facet_u = u3; 00550 } 00551 else{ 00552 pre_facet_v = src_nodes_list[src_edge_index][m+1]; 00553 pre_facet_u = src_nodes_u[src_edge_index][m+1]; 00554 } 00555 break; 00556 } 00557 } 00558 } 00559 } 00560 double alpha = (u_src - pre_facet_u)/(next_facet_u - pre_facet_u); 00561 tgt_facet_v[*it].uv[0] = (1.0 - alpha)*src_facet_v[pre_facet_v].uv[0]+alpha*src_facet_v[next_facet_v].uv[0]; 00562 tgt_facet_v[*it].uv[1] = (1.0 - alpha)*src_facet_v[pre_facet_v].uv[1]+alpha*src_facet_v[next_facet_v].uv[1]; 00563 } 00564 } 00565 } 00566 } 00567 00568 void SurfProHarmonicMap::ComputeWeight() 00569 { 00570 //create the facet mesh on the source surface 00571 int count = -1; 00572 for (vector<Vertex>::iterator it = src_facet_v.begin(); it != src_facet_v.end(); it++){ 00573 m_err = imesh_instance->createVtx(it->xyz[0], it->xyz[1], it->xyz[2], it->gVertexHandle); 00574 IBERRCHK(m_err, "Trouble create a mesh vertex!"); 00575 count++; 00576 m_err = imesh_instance->setIntData(it->gVertexHandle, facet_mesh_tag, count); 00577 IBERRCHK(m_err, "Trouble set the int data for a facet vertex"); 00578 } 00579 //create the facet edge entities on the source surface 00580 vector<set<int> > edge_connect; 00581 edge_connect.resize(src_facet_v.size()); 00582 count = -1; 00583 for (vector<Face>::iterator it = src_facet_tri.begin(); it != src_facet_tri.end(); it++){ 00584 int a = it->connect[0]->index, b = it->connect[1]->index, c = it->connect[2]->index; 00585 if (edge_connect[a].find(b)==edge_connect[a].end()) 00586 addEdgeToList(a, b, count, edge_connect, src_facet_e, src_facet_v); 00587 if (edge_connect[a].find(c)==edge_connect[a].end()) 00588 addEdgeToList(a, c, count, edge_connect, src_facet_e, src_facet_v); 00589 if (edge_connect[b].find(c)==edge_connect[b].end()) 00590 addEdgeToList(b, c, count, edge_connect, src_facet_e, src_facet_v); 00591 } 00592 size_src_e = src_facet_e.size(); 00593 //create the facet face entities on the source surface 00594 count = -1; 00595 for (vector<Face>::iterator it = src_facet_tri.begin(); it != src_facet_tri.end(); it++){ 00596 vector<iBase_EntityHandle> nodes; 00597 for (unsigned int i = 0; i < it->connect.size(); i++) 00598 nodes.push_back((it->connect[i])->gVertexHandle); 00599 m_err = imesh_instance->createEnt(iMesh_TRIANGLE, &nodes[0], nodes.size(), it->gFaceHandle); 00600 IBERRCHK(m_err, "Trouble create a triangle mesh entity on the source surface!"); 00601 count++; 00602 m_err = imesh_instance->setIntData(it->gFaceHandle, facet_mesh_tag, count); 00603 IBERRCHK(m_err, "Trouble set the int data for a facet vertex"); 00604 } 00605 //add extra stuff in order to seal the interior loops 00606 addExtra(source, src_facet_v, src_facet_e, src_facet_tri, src_geom_facet, size_src_v); 00607 00608 //get the adjacent edges of every vertex on the source surface 00609 adj_src.resize(src_facet_v.size()); 00610 for (vector<Vertex>::iterator it = src_facet_v.begin(); it != src_facet_v.end(); it++){ 00611 vector<iBase_EntityHandle> adj_edges; 00612 m_err = imesh_instance->getEntAdj(it->gVertexHandle, iBase_EDGE, adj_edges); 00613 IBERRCHK(m_err, "Trouble get the adjacent edges around a vertex!"); 00614 int intdata = -1; 00615 for (vector<iBase_EntityHandle>::iterator it_e = adj_edges.begin(); it_e != adj_edges.end(); it_e++){ 00616 m_err = imesh_instance->getIntData(*it_e, facet_mesh_tag, intdata); 00617 IBERRCHK(m_err, "Trouble get the int data for the adjacent edges!"); 00618 adj_src[it->index].insert(intdata); 00619 } 00620 } 00621 //compute the weight for edges on the source surface 00622 computeEdgeWeight(src_facet_e, src_facet_tri, src_facet_v); 00623 00624 //create the facet mesh on the target surface 00625 count = -1; 00626 for (vector<Vertex>::iterator it = tgt_facet_v.begin(); it != tgt_facet_v.end(); it++){ 00627 m_err = imesh_instance->createVtx(it->xyz[0], it->xyz[1], it->xyz[2], it->gVertexHandle); 00628 IBERRCHK(m_err, "Trouble create a mesh vertex"); 00629 count++; 00630 m_err = imesh_instance->setIntData(it->gVertexHandle, facet_mesh_tag, count); 00631 IBERRCHK(m_err, "Trouble set the int data for a facet vertex"); 00632 } 00633 //get the facet edges on the target surface 00634 edge_connect.clear(); 00635 edge_connect.resize(tgt_facet_v.size()); 00636 count = -1; 00637 for (vector<Face>::iterator it = tgt_facet_tri.begin(); it != tgt_facet_tri.end(); it++){ 00638 int a = it->connect[0]->index, b = it->connect[1]->index, c = it->connect[2]->index; 00639 if (edge_connect[a].find(b)==edge_connect[a].end()) 00640 addEdgeToList(a, b, count, edge_connect, tgt_facet_e, tgt_facet_v); 00641 if (edge_connect[a].find(c)==edge_connect[a].end()) 00642 addEdgeToList(a, c, count, edge_connect, tgt_facet_e, tgt_facet_v); 00643 if (edge_connect[b].find(c)==edge_connect[b].end()) 00644 addEdgeToList(b, c, count, edge_connect, tgt_facet_e, tgt_facet_v); 00645 } 00646 size_tgt_e = tgt_facet_e.size(); 00647 //get the facet faces on the target surface 00648 count = -1; 00649 for (vector<Face>::iterator it = tgt_facet_tri.begin(); it != tgt_facet_tri.end(); it++){ 00650 vector<iBase_EntityHandle> nodes; 00651 for (unsigned int i = 0; i < it->connect.size(); i++) 00652 nodes.push_back((it->connect[i])->gVertexHandle); 00653 m_err = imesh_instance->createEnt(iMesh_TRIANGLE, &nodes[0], nodes.size(), it->gFaceHandle); 00654 IBERRCHK(m_err, "Trouble create a triangle mesh entity on the target surface!"); 00655 count++; 00656 m_err = imesh_instance->setIntData(it->gFaceHandle, facet_mesh_tag, count); 00657 IBERRCHK(m_err, "Trouble set the int data for a facet vertex!"); 00658 } 00659 //add extra stuff in order to seal the interior loops 00660 //addExtra(target, tgt_facet_v, tgt_facet_e, tgt_facet_tri, tgt_geom_facet, size_tgt_v); 00661 //get the adjacent edges of every vertex on the target surface 00662 adj_tgt.resize(tgt_facet_v.size()); 00663 for (vector<Vertex>::iterator it = tgt_facet_v.begin(); it != tgt_facet_v.end(); it++){ 00664 vector<iBase_EntityHandle> adj_edges; 00665 m_err = imesh_instance->getEntAdj(it->gVertexHandle, iBase_EDGE, adj_edges); 00666 IBERRCHK(m_err, "Trouble get the adjacent edges around a vertex!"); 00667 int intdata = -1; 00668 for (vector<iBase_EntityHandle>::iterator it_e = adj_edges.begin(); it_e != adj_edges.end(); it_e++){ 00669 m_err = imesh_instance->getIntData(*it_e, facet_mesh_tag, intdata); 00670 IBERRCHK(m_err, "Trouble get the int data for the adjacent edges!"); 00671 adj_tgt[it->index].insert(intdata); 00672 } 00673 } 00674 //compute the edge weight on the target surface 00675 computeEdgeWeight(tgt_facet_e, tgt_facet_tri, tgt_facet_v); 00676 00677 } 00678 00679 void SurfProHarmonicMap::addExtra(Face f, vector<Vertex> &facet_v, vector<Edge> &facet_e, vector<Face> &facet_tri, vector<list<int> > geom_facet, int size_facet_v) 00680 { 00681 //add extra nodes to the list 00682 if (f.vertexloops.size() > 1){ 00683 int count = 0; 00684 for (unsigned int i = 1; i < f.vertexloops.size(); i++){ 00685 double xyz[3] = {0.0, 0.0, 0.0}; 00686 count += f.vertexloops[i-1].size(); 00687 int vtx_center = size_facet_v+i-1; 00688 vector<int> pointlist; 00689 for (unsigned int j = 0; j < f.vertexloops[i].size(); j++){ 00690 pointlist.push_back(*(geom_facet[count+j].begin())); 00691 for (int m = 0; m < 3; m++) 00692 xyz[m] += facet_v[*(geom_facet[count+j].begin())].xyz[m]; 00693 for (list<int>::iterator it = geom_facet[count+j+f.connect.size()].begin(); it != geom_facet[count+j+f.connect.size()].end(); it++){ 00694 pointlist.push_back(*it); 00695 for (int m = 0; m < 3; m++) 00696 xyz[m] += facet_v[*it].xyz[m]; 00697 } 00698 } 00699 //done 00700 //add extra vertex 00701 for (int m = 0; m < 3; m++) 00702 facet_v[vtx_center].xyz[m] = xyz[m]/double(pointlist.size()); 00703 m_err = imesh_instance->createVtx(facet_v[vtx_center].xyz[0], facet_v[vtx_center].xyz[1], facet_v[vtx_center].xyz[2], facet_v[vtx_center].gVertexHandle); 00704 IBERRCHK(m_err, "Trouble create a facet vertex on the interior loops of source surface!"); 00705 m_err = imesh_instance->setIntData(facet_v[vtx_center].gVertexHandle, facet_mesh_tag, facet_v[vtx_center].index); 00706 IBERRCHK(m_err, "Trouble set the int data for a facet vertex"); 00707 facet_v[vtx_center].index = vtx_center; 00708 facet_v[vtx_center].onBoundary = false; 00709 //add extra facet edges and adjacent edges 00710 int ent_index = src_facet_e.size(); 00711 vector<iBase_EntityHandle> tmp; 00712 for (vector<int>::iterator it = pointlist.begin(); it != pointlist.end(); it++, ent_index++){ 00713 //std::cout << "test ent_index = " << ent_index << std::endl; 00714 Edge tmp_edge; 00715 tmp_edge.index = ent_index; 00716 tmp_edge.connect.resize(2); 00717 tmp_edge.connect[0] = &facet_v[*it]; 00718 tmp_edge.connect[1] = &facet_v[vtx_center]; 00719 tmp.clear(); 00720 tmp.push_back(facet_v[*it].gVertexHandle); 00721 tmp.push_back(facet_v[vtx_center].gVertexHandle); 00722 m_err = imesh_instance->createEnt(iMesh_LINE_SEGMENT, &tmp[0], 2, tmp_edge.gEdgeHandle); 00723 IBERRCHK(m_err, "Trouble create a extra facet edge on the interior loops of source surface!"); 00724 m_err = imesh_instance->setIntData(tmp_edge.gEdgeHandle, facet_mesh_tag, tmp_edge.index); 00725 IBERRCHK(m_err, "Trouble set the int data for a facet vertex"); 00726 00727 facet_e.push_back(tmp_edge); 00728 } 00729 //add extra facet faces 00730 ent_index = facet_tri.size(); 00731 //src_facet_tri.resize(ent_index+pointlist.size()); 00732 for (unsigned int j = 0; j < pointlist.size(); j++, ent_index++){ 00733 Face tmp_f; 00734 int vtx_index[3]; 00735 if (j == (pointlist.size()-1)){ 00736 vtx_index[0] = pointlist[j]; 00737 vtx_index[1] = pointlist[0]; 00738 } 00739 else{ 00740 vtx_index[0] = pointlist[j]; 00741 vtx_index[1] = pointlist[j+1]; 00742 } 00743 vtx_index[2] = vtx_center; 00744 tmp_f.connect.resize(3); 00745 tmp.clear(); 00746 for (int m = 0; m < 3; m++){ 00747 tmp_f.connect[m] = &facet_v[vtx_index[m]]; 00748 tmp.push_back(facet_v[vtx_index[m]].gVertexHandle); 00749 } 00750 tmp_f.index = ent_index; 00751 m_err = imesh_instance->createEnt(iMesh_TRIANGLE, &tmp[0], tmp.size(), tmp_f.gFaceHandle); 00752 IBERRCHK(m_err, "Trouble create a extra triangle facet face entity!"); 00753 m_err = imesh_instance->setIntData(tmp_f.gFaceHandle, facet_mesh_tag, tmp_f.index); 00754 IBERRCHK(m_err, "Trouble set the int data for a facet vertex"); 00755 facet_tri.push_back(tmp_f); 00756 } 00757 } 00758 } 00759 00760 00761 00762 } 00763 00764 void SurfProHarmonicMap::computeEdgeWeight(vector<Edge> &f_edges, vector<Face> &f, vector<Vertex> f_v) 00765 { 00766 //compute the weight 00767 for (vector<Edge>::iterator it = f_edges.begin(); it != f_edges.end(); it++){ 00768 vector<iBase_EntityHandle> adj_faces; 00769 m_err = imesh_instance->getEntAdj(it->gEdgeHandle, iBase_FACE, adj_faces); 00770 IBERRCHK(m_err, "Trouble get the adjacent faces for an facet edge!"); 00771 assert(adj_faces.size()<=2); 00772 double weight = 0.0; 00773 int a = (it->connect[0])->index, b = (it->connect[1])->index; 00774 for (vector<iBase_EntityHandle>::iterator it_ent = adj_faces.begin(); it_ent != adj_faces.end(); it_ent++){ 00775 int intdata = -1, c = -1; 00776 m_err = imesh_instance->getIntData(*it_ent, facet_mesh_tag, intdata); 00777 IBERRCHK(m_err, "Trouble get the int data for the adjacent face!"); 00778 if (((f[intdata].connect[0]->index == a)&&(f[intdata].connect[1]->index==b))||((f[intdata].connect[1]->index == a)&&(f[intdata].connect[0]->index==b))) 00779 c = f[intdata].connect[2]->index; 00780 else if (((f[intdata].connect[0]->index == a)&&(f[intdata].connect[2]->index==b))||((f[intdata].connect[2]->index == a)&&(f[intdata].connect[0]->index==b))) 00781 c = f[intdata].connect[1]->index; 00782 else if (((f[intdata].connect[1]->index == a)&&(f[intdata].connect[2]->index==b))||((f[intdata].connect[2]->index == a)&&(f[intdata].connect[1]->index==b))) 00783 c = f[intdata].connect[0]->index; 00784 else 00785 continue; 00786 double vec1[3], vec2[3]; 00787 for (int k = 0; k < 3; k++){ 00788 vec1[k] = f_v[a].xyz[k] - f_v[c].xyz[k]; 00789 vec2[k] = f_v[b].xyz[k] - f_v[c].xyz[k]; 00790 } 00791 double cos_value = (vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2])/sqrt((vec1[0]*vec1[0]+vec1[1]*vec1[1]+vec1[2]*vec1[2])*(vec2[0]*vec2[0]+vec2[1]*vec2[1]+vec2[2]*vec2[2])); 00792 //std::cout << "ctan(angle) = " << cos_value/sqrt(1-pow(cos_value,2)) << std::endl; 00793 weight += cos_value/sqrt(1-pow(cos_value,2)); 00794 } 00795 it->e = 0.5*weight; 00796 } 00797 00798 } 00799 00800 void SurfProHarmonicMap::addEdgeToList(int a, int b, int &count, vector<set<int> > &edge_connect, vector<Edge> &f_edges, vector<Vertex> &facet_v) 00801 { 00802 count++; 00803 f_edges.resize(count+1); 00804 edge_connect[a].insert(b); 00805 edge_connect[b].insert(a); 00806 f_edges[count].connect.resize(2); 00807 f_edges[count].connect[0] = &facet_v[a]; 00808 f_edges[count].connect[1] = &facet_v[b]; 00809 f_edges[count].index = count; 00810 vector<iBase_EntityHandle> nodes; 00811 nodes.push_back(facet_v[a].gVertexHandle); 00812 nodes.push_back(facet_v[b].gVertexHandle); 00813 m_err = imesh_instance->createEnt(iMesh_LINE_SEGMENT, &nodes[0], nodes.size(), f_edges[count].gEdgeHandle); 00814 IBERRCHK(m_err, "Trouble create a facet line segment!"); 00815 m_err = imesh_instance->setIntData(f_edges[count].gEdgeHandle, facet_mesh_tag, count); 00816 IBERRCHK(m_err, "Trouble set the int data for a facet edge!"); 00817 00818 } 00819 00820 void SurfProHarmonicMap::boundaryDistribution() 00821 { 00822 //loop over the geometry entities on the outmost boundary 00823 //1. get the total distance of the outmost boundary loop 00824 vector<iBase_EntityHandle> tmp; 00825 vector<double> dist_source, dist_target; 00826 double total_dist_source = 0.0, total_dist_target = 0.0; 00827 for (unsigned int i = 0; i < source.edgeloops[0].size(); i++) 00828 tmp.push_back(edges[source.edgeloops[0][i]].gEdgeHandle); 00829 dist_source.resize(tmp.size()); 00830 g_err = igeom_instance->measure(&tmp[0], tmp.size(), &dist_source[0]); 00831 IBERRCHK(g_err, "Trouble get the measure of geometric edges!"); 00832 tmp.clear(); 00833 for (unsigned int i = 0; i < target.edgeloops[0].size(); i++) 00834 tmp.push_back(edges[target.edgeloops[0][i]].gEdgeHandle); 00835 dist_target.resize(tmp.size()); 00836 g_err = igeom_instance->measure(&tmp[0], tmp.size(), &dist_target[0]); 00837 IBERRCHK(g_err, "Trouble get the measure of geometric edges!"); 00838 00839 //Initialization of u,v coordinates 00840 for (unsigned int i = 0; i < src_facet_v.size(); i++){ 00841 src_facet_v[i].uv[0] = 0.0; 00842 src_facet_v[i].uv[1] = 0.0; 00843 } 00844 for (unsigned int i = 0; i < tgt_facet_v.size(); i++){ 00845 tgt_facet_v[i].uv[0] = 0.0; 00846 tgt_facet_v[i].uv[1] = 0.0; 00847 } 00848 00849 //assign u,v coordinates for facet vertices on the outmost boundary onto the unit disk, both source and target surface 00850 for (vector<Vertex>::iterator it = src_facet_v.begin(); it != src_facet_v.end(); it++) 00851 it->onBoundary = false; 00852 for (vector<Vertex>::iterator it = tgt_facet_v.begin(); it != tgt_facet_v.end(); it++) 00853 it->onBoundary = false; 00854 boundaryUnitDisk(source, dist_source, src_facet_v, src_geom_facet); 00855 } 00856 00857 00858 void SurfProHarmonicMap::boundaryUnitDisk(Face f, vector<double> dist, vector<Vertex> &facet_v, std::vector<std::list<int> > geom_facet) 00859 { 00860 double local_dist = 0.0, dist_sum = 0.0, len_curve = 0.0; 00861 int start_vertex = f.vertexloops[0][0]; 00862 for (std::vector<double>::iterator it = dist.begin(); it != dist.end(); it++) 00863 dist_sum += *it; 00864 for (unsigned int i = 0; i < f.vertexloops[0].size(); i++){ 00865 if (i > 0){ 00866 len_curve += dist[i-1]; 00867 local_dist = len_curve; 00868 } 00869 //get the facet on a geometry vertex of a loop 00870 facet_v[*(geom_facet[i].begin())].uv[0] = 100.0*cos(2*PI*local_dist/dist_sum); 00871 facet_v[*(geom_facet[i].begin())].uv[1] = 100.0*sin(2*PI*local_dist/dist_sum); 00872 facet_v[*(geom_facet[i].begin())].onBoundary = true; 00873 int pre_v = *(geom_facet[i].begin()); 00874 //get the facet on a geometry edge of a loop 00875 for (std::list<int>::iterator it = geom_facet[i+f.connect.size()].begin(); it != geom_facet[i+f.connect.size()].end(); it++){ 00876 local_dist += sqrt(pow(facet_v[*it].xyz[0]-facet_v[pre_v].xyz[0],2)+pow(facet_v[*it].xyz[1]-facet_v[pre_v].xyz[1],2)+pow(facet_v[*it].xyz[2]-facet_v[pre_v].xyz[2],2)); 00877 pre_v = *it; 00878 facet_v[*it].uv[0] = 100.0*cos(2*PI*local_dist/dist_sum); 00879 facet_v[*it].uv[1] = 100.0*sin(2*PI*local_dist/dist_sum); 00880 facet_v[*it].onBoundary = true; 00881 } 00882 } 00883 } 00884 00885 void SurfProHarmonicMap::getFacets() 00886 { 00887 SimpleArray<double> src_coords, tgt_coords; 00888 SimpleArray<int> src_facets, tgt_facets; 00889 double dist_tolerance = 1.0e-1; 00890 int err; 00891 //facets on the source surface 00892 iGeom_getFacets(igeom_instance->instance(), source.gFaceHandle, dist_tolerance, ARRAY_INOUT(src_coords), ARRAY_INOUT(src_facets), &err); 00893 assert(!err); 00894 src_facet_v.resize(src_coords.size()/3+source.vertexloops.size()-1); 00895 src_facet_tri.resize(src_facets.size()/3); 00896 size_src_v = src_coords.size()/3; 00897 size_src_f = src_facets.size()/3; 00898 00899 for (unsigned int i = 0; i < src_coords.size(); i += 3){ 00900 src_facet_v[i/3].index = i/3; 00901 for (int k = 0; k < 3; k++) 00902 src_facet_v[i/3].xyz[k] = src_coords[i+k]; 00903 } 00904 for (unsigned int i = 0; i < src_facets.size(); i += 3){ 00905 src_facet_tri[i/3].index = i/3; 00906 src_facet_tri[i/3].connect.resize(3); 00907 for (int k = 0; k < 3; k++) 00908 src_facet_tri[i/3].connect[k] = &src_facet_v[src_facets[i+k]]; 00909 } 00910 //facets on the target surface 00911 iGeom_getFacets(igeom_instance->instance(), target.gFaceHandle, dist_tolerance, ARRAY_INOUT(tgt_coords), ARRAY_INOUT(tgt_facets), &err); 00912 assert(!err); 00913 //tgt_facet_v.resize(tgt_coords.size()/3+target.vertexloops.size()-1); 00914 tgt_facet_v.resize(tgt_coords.size()/3); 00915 tgt_facet_tri.resize(tgt_facets.size()/3); 00916 size_tgt_v = tgt_coords.size()/3; 00917 size_tgt_f = tgt_facet_tri.size(); 00918 for (unsigned int i = 0; i < tgt_coords.size(); i+=3){ 00919 tgt_facet_v[i/3].index = i/3; 00920 for (int k = 0; k < 3; k++) 00921 tgt_facet_v[i/3].xyz[k] = tgt_coords[i+k]; 00922 tgt_facet_v[i/3].uv[0] = 0.0; 00923 tgt_facet_v[i/3].uv[1] = 0.0; 00924 } 00925 for (unsigned int i = 0; i < tgt_facets.size(); i += 3){ 00926 tgt_facet_tri[i/3].index = i/3; 00927 tgt_facet_tri[i/3].connect.resize(3); 00928 for (int k = 0; k < 3; k++) 00929 tgt_facet_tri[i/3].connect[k] = &tgt_facet_v[tgt_facets[i+k]]; 00930 00931 } 00932 00933 //match the facet mesh with geometry(source surface and target surface) 00934 //map-->vertices, edges, faces on the source surface 00935 00936 std::cout << "starting the source surface mapping\n"; 00937 MapFacetGeom(source, src_facet_v, src_facet_geom, src_geom_facet, size_src_v); 00938 std::cout << "starting the target surface mapping\n"; 00939 MapFacetGeom(target, tgt_facet_v, tgt_facet_geom, tgt_geom_facet, size_tgt_v); 00940 } 00941 00942 void SurfProHarmonicMap::MapFacetGeom(Face f_surf, vector<Vertex> facet_node, std::map<int, int> &map_data, vector<list<int> > &geom_facet, int size_facet_v) 00943 { 00944 geom_facet.resize(f_surf.connect.size()+f_surf.connEdges.size()+1); 00945 //0===f_surf.connect.size()-1 store vertex info 00946 //f_surf.connect.size()===f_surf.connect.size()+f_surf.connEdges.size()-1 store edge info 00947 //f_surf.connect.size()+f_surf.connEdges.size() store face info 00948 for (unsigned int i = 0; i < size_facet_v; i++){ 00949 facet_node[i].index = i; 00950 int is_on = false; 00951 00952 map_data[i] = -1; 00953 00954 double proj_xyz[3]; 00955 g_err = igeom_instance->getEntClosestPtTrimmed(f_surf.gFaceHandle, facet_node[i].xyz[0], facet_node[i].xyz[1], facet_node[i].xyz[2], proj_xyz[0], proj_xyz[1], proj_xyz[2]); 00956 IBERRCHK(g_err, "Trouble get the closest point on a geometry entity!"); 00957 facet_node[i].xyz[0] = proj_xyz[0]; 00958 facet_node[i].xyz[1] = proj_xyz[1]; 00959 facet_node[i].xyz[2] = proj_xyz[2]; 00960 00961 00962 00963 //check whether the facet mesh is on vertices or not. 00964 for (unsigned int j = 0; j < f_surf.connect.size(); j++){ 00965 iGeom_isPositionOn(igeom_instance->instance(), f_surf.connect[j]->gVertexHandle, facet_node[i].xyz[0], facet_node[i].xyz[1], facet_node[i].xyz[2], &is_on); 00966 if (is_on){ 00967 map_data[i] = j; 00968 geom_facet[j].push_back(i); 00969 break; 00970 } 00971 } 00972 if (is_on) 00973 continue; 00974 //check whether the facet mesh is on edges or not 00975 for (unsigned int j = 0; j < f_surf.connEdges.size(); j++){ 00976 iGeom_isPositionOn(igeom_instance->instance(), f_surf.connEdges[j]->gEdgeHandle, facet_node[i].xyz[0], facet_node[i].xyz[1], facet_node[i].xyz[2], &is_on); 00977 if (is_on){ 00978 map_data[i] = f_surf.connect.size()+j; 00979 geom_facet[f_surf.connect.size()+j].push_back(i); 00980 break; 00981 } 00982 } 00983 if (is_on) 00984 continue; 00985 //check whether the facet mesh is on the surface or not 00986 iGeom_isPositionOn(igeom_instance->instance(), f_surf.gFaceHandle, facet_node[i].xyz[0], facet_node[i].xyz[1], facet_node[i].xyz[2], &is_on); 00987 if (is_on){ 00988 map_data[i] = f_surf.connect.size()+f_surf.connEdges.size(); 00989 geom_facet[f_surf.connect.size()+f_surf.connEdges.size()].push_back(i); 00990 } 00991 else{ 00992 std::cout << "Something is wrong for the facet mesh!\txyz = {" << facet_node[i].xyz[0] << "," << facet_node[i].xyz[1] << "," << facet_node[i].xyz[2] << "}\n"; 00993 00994 } 00995 } 00996 } 00997 00998 void SurfProHarmonicMap::preprocessing() 00999 { 01000 vector<iBase_EntityHandle> v; 01001 vector<iBase_EntityHandle> e; 01002 vector<iBase_EntityHandle> f; 01003 g_err = igeom_instance->getEntAdj(volume, iBase_VERTEX, v); 01004 IBERRCHK(g_err, "Trouble get the adjacent vertices on a volume!"); 01005 g_err = igeom_instance->getEntAdj(volume, iBase_EDGE, e); 01006 IBERRCHK(g_err, "Trouble get the adjacent edges on a volume!"); 01007 g_err = igeom_instance->getEntAdj(volume, iBase_FACE, f); 01008 IBERRCHK(g_err, "Trouble get the adjacent faces on a volume!"); 01009 vertices.resize(v.size()); 01010 for (unsigned int i = 0; i < v.size(); i++){ 01011 vertices[i].gVertexHandle = v[i]; 01012 g_err = igeom_instance->getVtxCoord(v[i], vertices[i].xyz[0], vertices[i].xyz[1], vertices[i].xyz[2]); 01013 IBERRCHK(g_err, "Trouble get the xyz coordinates!"); 01014 vertices[i].index = i; 01015 g_err = igeom_instance->getIntData(vertices[i].gVertexHandle, global_geom_tag, vertices[i].id); 01016 IBERRCHK(g_err, "Trouble get the int data for vertex entity"); 01017 g_err = igeom_instance->setIntData(vertices[i].gVertexHandle, harmonic_surf_pro, i); 01018 IBERRCHK(g_err, "Trouble set the int data for vertex entity"); 01019 } 01020 edges.resize(e.size()); 01021 for (unsigned int i = 0; i < e.size(); i++){ 01022 edges[i].index = i; 01023 edges[i].gEdgeHandle = e[i]; 01024 g_err = igeom_instance->getIntData(edges[i].gEdgeHandle, global_geom_tag, edges[i].id); 01025 IBERRCHK(g_err, "Trouble get the int data for geometrical edge entity!"); 01026 vector<iBase_EntityHandle> adjs; 01027 g_err = igeom_instance->getEntAdj(e[i], iBase_VERTEX, adjs); 01028 IBERRCHK(g_err, "Trouble get the adjacent vertices of a geometrical edge!"); 01029 for (unsigned int j = 0; j < adjs.size(); j++){ 01030 int tmp; 01031 g_err = igeom_instance->getIntData(adjs[j], harmonic_surf_pro, tmp); 01032 IBERRCHK(g_err, "Trouble get the int data for a geometrical vertex!"); 01033 edges[i].connect.push_back(&vertices[tmp]); 01034 } 01035 g_err = igeom_instance->setIntData(edges[i].gEdgeHandle, harmonic_surf_pro, i); 01036 IBERRCHK(g_err, "Trouble set the int data for a geometrical edge!"); 01037 } 01038 link.resize(f.size()); 01039 for (unsigned int i = 0; i < f.size(); i++){ 01040 if (f[i] == source.gFaceHandle){ 01041 addFaceToList(f[i], source, i, false); 01042 GetGeomLoops(source, source.vertexloops, source.edgeloops); 01043 postProcessGeomLoops(source); 01044 source.src_tgt_link = 0; 01045 link[i].index = -1; 01046 continue; 01047 } 01048 if (f[i] == target.gFaceHandle){ 01049 addFaceToList(f[i], target, i, false); 01050 GetGeomLoops(target, target.vertexloops, target.edgeloops); 01051 postProcessGeomLoops(target); 01052 target.src_tgt_link = 1; 01053 link[i].index = -2; 01054 continue; 01055 } 01056 link[i].src_tgt_link = 2; 01057 addFaceToList(f[i], link[i], i, true); 01058 01059 } 01060 01061 01062 } 01063 01064 void SurfProHarmonicMap::addFaceToList(iBase_EntityHandle entity, Face& f, int index, bool is_set_int) 01065 { 01066 f.gFaceHandle = entity; 01067 if (is_set_int){ 01068 g_err = igeom_instance->setIntData(f.gFaceHandle, harmonic_surf_pro, index); 01069 IBERRCHK(g_err, "Trouble set the int data for geometrical face entity!"); 01070 f.index = index; 01071 } 01072 01073 //get the adjacent vertices on a face 01074 vector<iBase_EntityHandle> tmp; 01075 g_err = igeom_instance->getEntAdj(f.gFaceHandle, iBase_VERTEX, tmp); 01076 IBERRCHK(g_err, "Trouble get the adjacent vertices on a geometrical face!"); 01077 for (unsigned int i = 0; i < tmp.size(); i++){ 01078 int tmpint = -1; 01079 g_err = igeom_instance->getIntData(tmp[i], harmonic_surf_pro, tmpint); 01080 IBERRCHK(g_err, "Trouble get the int data for a vertex!"); 01081 f.connect.push_back(&vertices[tmpint]); 01082 } 01083 //get the adjacent edges on a face 01084 tmp.clear(); 01085 g_err = igeom_instance->getEntAdj(f.gFaceHandle, iBase_EDGE, tmp); 01086 IBERRCHK(g_err, "Trouble get the adjacent edges on a geometrical face!"); 01087 for (unsigned int i = 0; i < tmp.size(); i++){ 01088 int tmpint = -1; 01089 g_err = igeom_instance->getIntData(tmp[i], harmonic_surf_pro, tmpint); 01090 IBERRCHK(g_err, "Trouble get the int data for a vertex!"); 01091 f.connEdges.push_back(&edges[tmpint]); 01092 } 01093 01094 } 01095 01096 //post process the geometric loops on the source/target surface 01097 //problem not to be solved: matching the loops between source and target surfaces should be done!!!!! 01098 void SurfProHarmonicMap::postProcessGeomLoops(Face& surf) 01099 { 01100 //make sure the outmost boundary loop is at [0]; 01101 int outmost_index = -1; 01102 double volume = -1.0; 01103 if (surf.edgeloops.size()<=1) 01104 return; 01105 for (unsigned int j = 0; j < surf.edgeloops.size(); j++){ 01106 std::vector<iBase_EntityHandle> entities; 01107 double mincorner[3] = {1.0e10,1.0e10,1.0e10}, maxcorner[3] = {-1.0e10,-1.0e10,-1.0e10}; 01108 for (unsigned int i = 0; i < surf.edgeloops[j].size(); i++){ 01109 double t_min[3], t_max[3]; 01110 entities.clear(); 01111 entities.push_back(edges[surf.edgeloops[j][i]].gEdgeHandle); 01112 g_err = igeom_instance->getArrBoundBox(&entities[0], entities.size(), iBase_StorageOrder_MIN, &t_min[0], &t_max[0]); 01113 IBERRCHK(g_err, "Trouble get the bound box for an array of entities"); 01114 if (fabs(mincorner[0])==fabs(mincorner[1])&&fabs(mincorner[1])==fabs(mincorner[2])&&fabs(maxcorner[0])==fabs(maxcorner[1])&&fabs(maxcorner[1])==fabs(mincorner[2])){ 01115 for (int m = 0; m < 3; m++){ 01116 mincorner[m] = t_min[m]; 01117 maxcorner[m] = t_max[m]; 01118 } 01119 } 01120 else{ 01121 if (t_min[0] < mincorner[0]) 01122 mincorner[0] = t_min[0]; 01123 if (t_min[1] < mincorner[1]) 01124 mincorner[1] = t_min[1]; 01125 if (t_min[2] < mincorner[2]) 01126 mincorner[2] = t_min[2]; 01127 if (t_max[0] > maxcorner[0]) 01128 maxcorner[0] = t_max[0]; 01129 if (t_max[1] > maxcorner[1]) 01130 maxcorner[1] = t_max[1]; 01131 if (t_max[2] > maxcorner[2]) 01132 maxcorner[2] = t_max[2]; 01133 } 01134 } 01135 //g_err = igeom_instance->getArrBoundBox(&entities[0], entities.size(), iBase_StorageOrder_MIN, &mincorner[0], &maxcorner[0]); 01136 //IBERRCHK(g_err, "Trouble get the bound box for an array of entities"); 01137 double len_x = fabs(maxcorner[0]-mincorner[0]), len_y = fabs(maxcorner[1]-mincorner[1]), len_z = fabs(maxcorner[2]-mincorner[2]); 01138 if (fabs(maxcorner[0]-mincorner[0]) < 1.0e-5) 01139 len_x = 1.0; 01140 if (fabs(maxcorner[1]-mincorner[1]) < 1.0e-5) 01141 len_y = 1.0; 01142 if (fabs(maxcorner[2]-mincorner[2]) < 1.0e-5) 01143 len_z = 1.0; 01144 double tmp_volume = len_x*len_y*len_z; 01145 if ( tmp_volume > volume){ 01146 volume = tmp_volume; 01147 outmost_index = j; 01148 } 01149 } 01150 //exchange loop[0] and loop[outmost_index] 01151 std::vector<int> tmp_loop1, tmp_loop2; 01152 for (unsigned int j = 0; j < surf.vertexloops[0].size(); j++){ 01153 tmp_loop1.push_back(surf.vertexloops[0][j]); 01154 tmp_loop2.push_back(surf.edgeloops[0][j]); 01155 } 01156 surf.vertexloops[0].clear(); 01157 surf.edgeloops[0].clear(); 01158 for (unsigned int j = 0; j < surf.vertexloops[outmost_index].size(); j++){ 01159 surf.vertexloops[0].push_back(surf.vertexloops[outmost_index][j]); 01160 surf.edgeloops[0].push_back(surf.edgeloops[outmost_index][j]); 01161 } 01162 surf.vertexloops[outmost_index].clear(); 01163 surf.edgeloops[outmost_index].clear(); 01164 for (unsigned int j = 0; j < tmp_loop1.size(); j++){ 01165 surf.vertexloops[outmost_index].push_back(tmp_loop1[j]); 01166 surf.edgeloops[outmost_index].push_back(tmp_loop2[j]); 01167 } 01168 //adjust surf.connect and surf.connEdges based on the boundary loops 01169 int count = 0; 01170 std::vector<int> v, e; 01171 for (unsigned int i = 0; i < surf.vertexloops.size(); i++) 01172 for (unsigned int j = 0; j < surf.vertexloops[i].size(); j++) 01173 v.push_back(surf.vertexloops[i][j]); 01174 for (unsigned int i = 0; i < surf.edgeloops.size(); i++) 01175 for (unsigned int j = 0; j < surf.edgeloops[i].size(); j++) 01176 e.push_back(surf.edgeloops[i][j]); 01177 01178 for (unsigned int i = 0; i < v.size(); i++) 01179 surf.connect[i] = &vertices[v[i]]; 01180 for (unsigned int i = 0; i < e.size(); i++) 01181 surf.connEdges[i] = &edges[e[i]]; 01182 01183 } 01184 01185 //get the geometric loops on target surfaces 01186 void SurfProHarmonicMap::GetGeomLoops(Face surf, vector<vector<int> > &loops_vertex, vector<vector<int> > &loops_edge) 01187 { 01188 //collect edges' information 01189 set<int> edge_index; 01190 for (unsigned int i = 0; i < surf.connEdges.size(); i++) 01191 edge_index.insert(surf.connEdges[i]->index); 01192 01193 int CurrentNum = 0; 01194 int TotalNum = surf.connect.size(); 01195 01196 while(CurrentNum < TotalNum){ 01197 int start_vertex = 0, next_vertex = -1, begin_vertex = 0; 01198 int start_edge = 0, next_edge = -1; 01199 01200 //get the starting edge 01201 start_vertex = edges[*(edge_index.begin())].connect[0]->index; 01202 start_edge = *(edge_index.begin()); 01203 01204 //get the edge sense and make sure that the nodes are oriented correctly 01205 int edge_sense = 0; 01206 int first_vertex = start_vertex, second_vertex = edges[*(edge_index.begin())].connect[1]->index; 01207 g_err = igeom_instance->getEgVtxSense(edges[start_edge].gEdgeHandle, vertices[first_vertex].gVertexHandle, vertices[second_vertex].gVertexHandle, edge_sense); 01208 IBERRCHK(g_err, "Trouble get the edge sense."); 01209 int face_sense = 0; 01210 g_err = igeom_instance->getEgFcSense(edges[start_edge].gEdgeHandle, surf.gFaceHandle, face_sense); 01211 IBERRCHK(g_err, "Trouble get the face sense."); 01212 if (face_sense*edge_sense < 0){ 01213 start_vertex = edges[*(edge_index.begin())].connect[1]->index; 01214 } 01215 01216 //initialization 01217 loops_vertex.resize(loops_vertex.size()+1); 01218 loops_edge.resize(loops_edge.size()+1); 01219 begin_vertex = start_vertex; 01220 //find the geometric loop 01221 while(next_vertex != begin_vertex){ 01222 loops_vertex[loops_vertex.size()-1].push_back(start_vertex); 01223 loops_edge[loops_edge.size()-1].push_back(start_edge); 01224 edge_index.erase(start_edge); 01225 if (start_vertex == edges[start_edge].connect[0]->index) 01226 next_vertex = edges[start_edge].connect[1]->index; 01227 else 01228 next_vertex = edges[start_edge].connect[0]->index; 01229 //find the adjacent geometric edge 01230 vector<iBase_EntityHandle> adj_edges; 01231 g_err = igeom_instance->getEntAdj(vertices[next_vertex].gVertexHandle, iBase_EDGE, adj_edges); 01232 IBERRCHK(g_err, "Trouble get the adjacent edges around a geometric vertex."); 01233 //remove unnecessary geometric edges 01234 assert(adj_edges.size()>=1); 01235 int intdata = -1; 01236 int next_edge_index = -1; 01237 for (int i = adj_edges.size()-1; i >= 0; i--){ 01238 g_err = igeom_instance->getIntData(adj_edges[i], harmonic_surf_pro, intdata); 01239 if (edge_index.find(intdata)==edge_index.end())//remove that geometric edge 01240 continue; 01241 else{ 01242 next_edge_index = intdata; 01243 break; 01244 } 01245 } 01246 if (next_edge_index == -1) 01247 break; 01248 next_edge = intdata; 01249 start_vertex = next_vertex; 01250 start_edge = next_edge; 01251 } 01252 CurrentNum += loops_vertex[loops_vertex.size()-1].size(); 01253 } 01254 } 01255 01256 01257 SurfProHarmonicMap::~SurfProHarmonicMap() 01258 { 01259 } 01260 01261 }