Beispiel #1
0
 Point_3 operator()(const Vertex& v) const {
     CGAL_precondition((CGAL::circulator_size(v.vertex_begin()) & 1) == 0);
     std::size_t degree = CGAL::circulator_size(v.vertex_begin()) / 2;
     double alpha = (4.0 - 2.0 * std::cos(2.0 * CGAL_PI / degree)) / 9.0;
     Vector_3 vec = (v.point() - CGAL::ORIGIN) * (1.0 - alpha);
     HV_circulator h = v.vertex_begin();
     do {
         vec = vec + (h->opposite()->vertex()->point() - CGAL::ORIGIN)
                 * alpha / static_cast<double> (degree);
         ++h;
         CGAL_assertion(h != v.vertex_begin()); // even degree guaranteed
         ++h;
     } while (h != v.vertex_begin());
     return (CGAL::ORIGIN + vec);
 }
 Point operator()( const Vertex& v) const {
     std::size_t degree = CGAL::circulator_size( v.vertex_begin());
     if ( degree & 1) // odd degree only at border vertices
         return v.point();
     degree = degree / 2;
     double alpha = ( 4.0 - 2.0 * std::cos( 2.0 * CGAL_PI / degree)) / 9.0;
     Vector vec = (v.point() - CGAL::ORIGIN) * ( 1.0 - alpha);
     HV_circulator h = v.vertex_begin();
     do {
         // Even degree and border edges indicated non-manifold
         // vertex with two holes.
         if ( h->is_border_edge()) {
             std::cerr << "Error: non-manifold vertex. Erroneous smoothing."
                       << std::endl;
             return v.point();
         }
         vec = vec + ( h->opposite()->vertex()->point() - CGAL::ORIGIN)
           * alpha / static_cast<double>(degree);
         ++ h;
         CGAL_assertion( h != v.vertex_begin()); // even degree guaranteed
         ++ h;
     } while ( h != v.vertex_begin());
     return (CGAL::ORIGIN + vec);
 }
Beispiel #3
0
//////////////////////////////////////////////////////////////////////////////////////////////////////
// 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);	

}