float Remesh::RunStep() { cur_iter++; // COMPUTE THE MESH DISPLACEMENT for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) vi->delta = Kernel::Vector_3(0,0,0); // from current to the closest destination point for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { Kernel::Point_3 closest_point = dst_mesh.closestPoint(vi->point()); //cerr << "closest_point (" << closest_point << ") has ID " << dst_mesh.vertex_mapping[closest_point]->id << endl; Kernel::Vector_3 closest_normal = dst_mesh.vertex_mapping[closest_point]->normal(); //Kernel::Vector_3 closest_normal = dst_mesh.vertexMapping(closest_point)->normal(); /* vi->delta = closest_point - vi->point(); bool is_outside = v_norm((closest_point + closest_normal*v_norm(vi->delta)) - vi->point()) < v_norm(vi->delta); // bool is_outside = v_norm(v_normalized(closest_normal) + v_normalized(vi->delta)) < 1.4142; // bool is_outside = v_angle(closest_normal, vi->delta) > PI/2; double dist_sign = (is_outside?1:-1); vi->delta = vi->normal()*v_norm(vi->delta)*(-1)*dist_sign; */ vi->delta = vi->normal()* (closest_normal*(closest_point-vi->point())); // vi->delta == v_normalized(data->mesh.computeVectorComponent(vi->normal(),vi->delta,1))*v_norm(vi->delta); // vi->delta = v_normalized(vi->delta)*data->mesh.computeVertexStatistics(*vi,1)*0.05; // vi->delta = vi->normal(); //*alg_dt } // NORMALIZE the movements float total_movement = 0; int total_elements = 0; double max_delta = data->mesh.edge_avg*alg_dt; for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { //vi->delta = v_normalized(vi->delta)*data->mesh.computeVertexStatistics(*vi,1)*0.1; // double max_delta = data->mesh.computeVertexStatistics(*vi,1)*alg_dt; // double min_delta = data->mesh.edge_avg/5; // vi->delta = vi->delta; // vi->delta = vi->delta + v_normalized(vi->delta)*(RAND_MAX/2-std::rand())*1.0/RAND_MAX*data->mesh.edge_avg/2*alg_smoothing; // vi->delta = v_normalized(vi->delta)*max_delta; double the_norm = v_norm(vi->delta); if (the_norm > max_delta) { vi->delta = v_normalized(vi->delta)*max_delta; } // if (the_norm < min_delta) vi->delta = v_normalized(vi->delta)*min_delta; the_norm = v_norm(vi->delta); if (the_norm > max_delta*0.5) { total_elements++; total_movement += v_norm(vi->delta); } //vi->delta = vi->delta + Kernel::Vector_3((RAND_MAX/2-std::rand())*1.0/RAND_MAX, (RAND_MAX/2-std::rand())*1.0/RAND_MAX, (RAND_MAX/2-std::rand())*1.0/RAND_MAX)*data->mesh.computeVertexStatistics(*vi,1)*alg_smoothing; // vi->delta = vi->delta + data->mesh.computeVectorComponent(vi->normal(),vi->laplacian()*alg_dt,0); if (vi->border()==false) vi->delta = vi->delta + vi->laplacian()*alg_smoothing; } // MOVE THE MESH OpenGLContext::mutex.lock(); data->mesh.lock(); for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { if (alg_keepVerticesConstant) vi->delta = vi->normal()*(vi->delta*vi->normal()); vi->prev_delta = vi->delta; vi->border()=false; vi->move ( vi->delta ); } data->mesh.unlock(); data->mesh.updateMeshData(); OpenGLContext::mutex.unlock(); //saveOutput if (alg_saveOutput) { char filename[300]; sprintf(filename,"%s/output_%04d.off",alg_saveOutputPrefix,cur_iter); data->mesh.saveFormat(filename,"off"); sprintf(filename,"%s/output_%04d.diff",alg_saveOutputPrefix,cur_iter); data->mesh.saveVectorField(filename); sprintf(filename,"%s/output_%04d.idx",alg_saveOutputPrefix,cur_iter); data->mesh.saveVertexIndices(filename); } emit stepFinished(); return total_elements; // return (++cur_iter < iter); }
////////////////////////////////////////////////////////////////////////////////////////////////////// // run a step float Remesh::RunColorStep() { cur_iter++; cerr << "ITERATION ( " << cur_iter << ") " << endl; // COMPUTE THE MESH DISPLACEMENT for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { vi->delta = Kernel::Vector_3(0,0,0); vi->delta_tmp = Kernel::Vector_3(0,0,0); } // from current to the closest destination point for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { #if MOVE_THE_MESH Kernel::Point_3 closest_point = dst_mesh.closestColorPoint(vi->point(), (float *)(vi->color)); //Kernel::Point_3 closest_point = dst_mesh.closestPoint(vi->point()); #else Kernel::Point_3 tmp_point = vi->point() + vi->motion_vec; Kernel::Point_3 closest_point = dst_mesh.closestColorPoint(tmp_point, (float *)(vi->color)); #endif //cerr << "closest_point (" << closest_point << ") has ID " << dst_mesh.vertex_mapping[closest_point]->id << endl; //Kernel::Vector_3 closest_normal = dst_mesh.vertex_mapping[closest_point]->normal(); //Kernel::Vector_3 closest_normal = dst_mesh.vertexMapping(closest_point)->normal(); /* vi->delta = closest_point - vi->point(); bool is_outside = v_norm((closest_point + closest_normal*v_norm(vi->delta)) - vi->point()) < v_norm(vi->delta); // bool is_outside = v_norm(v_normalized(closest_normal) + v_normalized(vi->delta)) < 1.4142; // bool is_outside = v_angle(closest_normal, vi->delta) > PI/2; double dist_sign = (is_outside?1:-1); vi->delta = vi->normal()*v_norm(vi->delta)*(-1)*dist_sign; */ vi->delta = closest_point- (vi->point() + vi->motion_vec); //vi->delta = vi->normal()* (closest_normal*(closest_point-vi->point())); // vi->delta == v_normalized(data->mesh.computeVectorComponent(vi->normal(),vi->delta,1))*v_norm(vi->delta); // vi->delta = v_normalized(vi->delta)*data->mesh.computeVertexStatistics(*vi,1)*0.05; // vi->delta = vi->normal(); //*alg_dt } // NORMALIZE the movements float total_movement = 0; int total_elements = 0; double max_delta = data->mesh.edge_avg*alg_dt; for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { //vi->delta = v_normalized(vi->delta)*data->mesh.computeVertexStatistics(*vi,1)*0.1; // double max_delta = data->mesh.computeVertexStatistics(*vi,1)*alg_dt; // double min_delta = data->mesh.edge_avg/5; // vi->delta = vi->delta; // vi->delta = vi->delta + v_normalized(vi->delta)*(RAND_MAX/2-std::rand())*1.0/RAND_MAX*data->mesh.edge_avg/2*alg_smoothing; // vi->delta = v_normalized(vi->delta)*max_delta; double the_norm = v_norm(vi->delta); if (the_norm > max_delta) { vi->delta = v_normalized(vi->delta)*max_delta; } // if (the_norm < min_delta) vi->delta = v_normalized(vi->delta)*min_delta; the_norm = v_norm(vi->delta); if (! MOVE_THE_MESH || the_norm > max_delta*0.5) { total_elements++; total_movement += v_norm(vi->delta); } //vi->delta = vi->delta + Kernel::Vector_3((RAND_MAX/2-std::rand())*1.0/RAND_MAX, (RAND_MAX/2-std::rand())*1.0/RAND_MAX, (RAND_MAX/2-std::rand())*1.0/RAND_MAX)*data->mesh.computeVertexStatistics(*vi,1)*alg_smoothing; // vi->delta = vi->delta + data->mesh.computeVectorComponent(vi->normal(),vi->laplacian()*alg_dt,0); //vi->delta = vi->delta + vi->laplacian()*alg_smoothing; } data->mesh.diffuse(alg_smoothing, 0); #if ADD_LENGTH_CONSTRAINT for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { // Add a cost for preserving the smoothness and the geometry of the mesh HV_circulator h = vi->vertex_begin(); double geom_vx = 0 ; double geom_vy = 0 ; double geom_vz = 0 ; int order=0; do { const float xx = TO_FLOAT ( vi->point().x() ); const float yy = TO_FLOAT ( vi->point().y() ); const float zz = TO_FLOAT ( vi->point().z() ); const float xxx = TO_FLOAT ( h->opposite()->vertex()->point().x()) ; const float yyy = TO_FLOAT ( h->opposite()->vertex()->point().y()) ; const float zzz = TO_FLOAT ( h->opposite()->vertex()->point().z()) ; double d = (xx - xxx) * (xx - xxx) + (yy - yyy) * (yy - yyy) + (zz - zzz) * (zz - zzz) ; #if MOVE_THE_MESH double t_d2x = (xx + vi->delta[0]) - (xxx + h->opposite()->vertex()->delta[0]) ; double t_d2y = (yy + vi->delta[1]) - (yyy + h->opposite()->vertex()->delta[1]) ; double t_d2z = (zz + vi->delta[2]) - (zzz + h->opposite()->vertex()->delta[2]) ; #else double t_d2x = (xx + vi->motion_vec[0] + vi->delta[0]) - (xxx + h->opposite()->vertex()->motion_vec[0] + h->opposite()->vertex()->delta[0]) ; double t_d2y = (yy + vi->motion_vec[1] + vi->delta[1]) - (yyy + h->opposite()->vertex()->motion_vec[1] + h->opposite()->vertex()->delta[1]) ; double t_d2z = (zz + vi->motion_vec[2] + vi->delta[2]) - (zzz + h->opposite()->vertex()->motion_vec[2] + h->opposite()->vertex()->delta[2]) ; #endif double d2 = t_d2x * t_d2x + t_d2y * t_d2y + t_d2z * t_d2z; geom_vx += t_d2x * (sqrt(d2) - sqrt(d)) / sqrt(d2) ; geom_vy += t_d2y * (sqrt(d2) - sqrt(d)) / sqrt(d2) ; geom_vz += t_d2z * (sqrt(d2) - sqrt(d)) / sqrt(d2) ; order++; } while ( ++h != vi->vertex_begin() ); geom_vx /= order ; geom_vy /= order ; geom_vz /= order ; double alpha = 1 ; vi->delta_tmp = alpha * Vector(-geom_vx, -geom_vy, -geom_vz) ; #if 0 if(v_norm(vi->delta_tmp) > 0.001) std::cout << vi->delta << " + " << geom_vx << " " << geom_vy << " " << geom_vz <<std::endl ; #endif } for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { double alpha1 = 0.9, alpha2 = 0.1 ; if(v_norm(vi->delta)<0.01) { alpha2 = 0.9; alpha1 = 0.1; } vi->delta = alpha1 * vi->delta + alpha2 * vi->delta_tmp; } #endif // MOVE THE MESH OpenGLContext::mutex.lock(); data->mesh.lock(); for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { if (alg_keepVerticesConstant) vi->delta = vi->normal()*(vi->delta*vi->normal()); vi->prev_delta = vi->delta; #if MOVE_THE_MESH vi->move ( vi->delta ); #else vi->motion_vec = vi->motion_vec + vi->delta; #endif } data->mesh.unlock(); #if MOVE_THE_MESH data->mesh.updateMeshData(); #else //for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { // vi->motion_vec = vi->motion_vec + vi->laplacian() * alg_smoothing; // smooth the motion vectors //} #endif OpenGLContext::mutex.unlock(); //saveOutput if (alg_saveOutput) { char filename[300]; sprintf(filename,"%s/output_%04d.off",alg_saveOutputPrefix,cur_iter); data->mesh.saveFormat(filename,"off"); sprintf(filename,"%s/output_%04d.diff",alg_saveOutputPrefix,cur_iter); data->mesh.saveVectorField(filename); sprintf(filename,"%s/output_%04d.idx",alg_saveOutputPrefix,cur_iter); data->mesh.saveVertexIndices(filename); } emit stepFinished(); return total_movement; //return total_elements; // return (++cur_iter < iter); }