MeshKit  1.0
SurfProHarmonicMap.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines