void GlobalFun::find_original_neighbors(CGrid::iterator starta, CGrid::iterator enda, 
	CGrid::iterator startb, CGrid::iterator endb, double radius)
{	

	double radius2 = radius*radius;
	double iradius16 = -4/radius2;
	const double PI = 3.1415926;

	for(CGrid::iterator dest = starta; dest != enda; dest++) 
	{
		CVertex &v = *(*dest);

		Point3f &p = v.P();
		for(CGrid::iterator origin = startb; origin != endb; origin++)
		{
			CVertex &t = *(*origin);

			Point3f &q = t.P();
			Point3f diff = p-q;

			double dist2 = diff.SquaredNorm();

			if(dist2 < radius2) 
			{                          
				v.original_neighbors.push_back((*origin)->m_index);
			}
		}
	}
}
void WLOP::computeRepulsionTerm(CMesh* samples)
{
	double repulsion_power = para->getDouble("Repulsion Power");
	bool need_density = para->getBool("Need Compute Density");
	double radius = para->getDouble("CGrid Radius"); 

	double radius2 = radius * radius;
	double iradius16 = -para->getDouble("H Gaussian Para")/radius2;

	cout << endl<< endl<< "Sample Neighbor Size:" << samples->vert[0].neighbors.size() << endl<< endl;
	for(int i = 0; i < samples->vert.size(); i++)
	{
		CVertex& v = samples->vert[i];
		for (int j = 0; j < v.neighbors.size(); j++)
		{
			CVertex& t = samples->vert[v.neighbors[j]];
			Point3f diff = v.P() - t.P();

			double dist2  = diff.SquaredNorm();
			double len = sqrt(dist2);
			if(len <= 0.001 * radius) len = radius*0.001;

			double w = exp(dist2*iradius16);
			double rep = w * pow(1.0 / len, repulsion_power);

			if (need_density)
			{
				rep *= samples_density[t.m_index];
			}

			repulsion[i] += diff * rep;  
			repulsion_weight_sum[i] += rep;
		}
	}
}
Example #3
0
Point3f RandomUnitVec(){
  Point3f k;
  do {
    k=Point3f(
     (random(200)-100)*0.01,
     (random(200)-100)*0.01,
     (random(200)-100)*0.01
    );
  } while (k.SquaredNorm()>1.0);

  return k.Normalize();
}
void WLOP::computeAverageTerm(CMesh* samples, CMesh* original)
{
	double average_power = para->getDouble("Average Power");
	bool need_density = para->getBool("Need Compute Density");
	double radius = para->getDouble("CGrid Radius"); 

	double radius2 = radius * radius;
	double iradius16 = -para->getDouble("H Gaussian Para")/radius2;

	cout << "Original Size:" << samples->vert[0].original_neighbors.size() << endl;
	for(int i = 0; i < samples->vert.size(); i++)
	{
		CVertex& v = samples->vert[i];

		for (int j = 0; j < v.original_neighbors.size(); j++)
		{
			CVertex& t = original->vert[v.original_neighbors[j]];
			
			Point3f diff = v.P() - t.P();
			double dist2  = diff.SquaredNorm();

			double w = 1;
			if (para->getBool("Run Anisotropic LOP"))
			{
				double len = sqrt(dist2);
				if(len <= 0.001 * radius) len = radius*0.001;
				double hn = diff * v.N();
				double phi = exp(hn * hn * iradius16);
				w = phi / pow(len, 2 - average_power);
			}
			else if (average_power < 2)
			{
				double len = sqrt(dist2);
				if(len <= 0.001 * radius) len = radius*0.001;
				w = exp(dist2 * iradius16) / pow(len, 2 - average_power);
			}
			else
			{
				w = exp(dist2 * iradius16);
			}

			if (need_density)
			{
				w *= original_density[t.m_index];
			}

			average[i] += t.P() * w;  
			average_weight_sum[i] += w;  

		}
	}
}
void GlobalFun::other_neighbors(CGrid::iterator starta, CGrid::iterator enda, 
	CGrid::iterator startb, CGrid::iterator endb, double radius)
{
	double radius2 = radius*radius;
	for(CGrid::iterator dest = starta; dest != enda; dest++)
	{
		CVertex &v = *(*dest);
		Point3f &p = v.P();

		for(CGrid::iterator origin = startb; origin != endb; origin++)
		{
			CVertex &t = *(*origin);
			Point3f &q = t.P();
			Point3f diff = p-q;
			double dist2 = diff.SquaredNorm();
			if(dist2 < radius2) 
			{   
				v.neighbors.push_back((*origin)->m_index);
				t.neighbors.push_back((*dest)->m_index);
			}
		}
	}
}
void GlobalFun::computeEigenWithTheta(CMesh* _samples, double radius)
{
	vector<vector<int> > neighborMap;

	typedef vector<CVertex>::iterator VertexIterator;

	VertexIterator begin = _samples->vert.begin();
	VertexIterator end = _samples->vert.end();

	neighborMap.assign(end - begin, vector<int>());

	int curr_index = 0;

	for (VertexIterator iter=begin; iter!=end; iter++, curr_index++)
	{
		if(iter->neighbors.size() <= 3)
		{
			iter->eigen_confidence = 0.5;
			continue;
		}

		for(int j = 0; j < iter->neighbors.size(); j++)
		{
			neighborMap[curr_index].push_back(iter->neighbors[j]);
		}
	}

	double radius2 = radius*radius;
	double iradius16 = -1/radius2; 

	int currIndex = 0;
	for (VertexIterator iter=begin; iter!=end; iter++, currIndex++)
	{
    if(iter->neighbors.size() <= 3)
    {
      iter->eigen_confidence = 0.5;
      continue;
    }

		Matrix33d covariance_matrix;
		Point3f diff;
		covariance_matrix.SetZero();
		int neighborIndex = -1;
		int neighbor_size = iter->neighbors.size();
		for (unsigned int n=0; n<neighbor_size; n++)
		{
			neighborIndex = neighborMap[currIndex][n];
			if(neighborIndex < 0)
				break;
			VertexIterator neighborIter = begin + neighborIndex;

			diff = iter->P() - neighborIter->P();

			Point3f vm = iter->N();
			Point3f tm = neighborIter->N();
			double dist2 = diff.SquaredNorm();
			double theta = exp(dist2*iradius16);

			for (int i=0; i<3; i++)
				for (int j=0; j<3; j++)
					covariance_matrix[i][j] += diff[i]*diff[j] * theta;
		}

		Point3f   eigenvalues;
		Matrix33d	eigenvectors;
		int required_rotations;
		vcg::Jacobi< Matrix33d, Point3f >(covariance_matrix, eigenvalues, eigenvectors, required_rotations);
		vcg::SortEigenvaluesAndEigenvectors< Matrix33d, Point3f >(eigenvalues, eigenvectors);


		double sum_eigen_value = (eigenvalues[0] + eigenvalues[1] + eigenvalues[2]);

		iter->eigen_confidence = eigenvalues[0] / sum_eigen_value;

		for (int d=0; d<3; d++)
			iter->eigen_vector0[d] = eigenvectors[d][0];
		for (int d=0; d<3; d++)
			iter->eigen_vector1[d] = eigenvectors[d][1];
		for (int d=0; d<3; d++)
			iter->N()[d] = eigenvectors[d][2];

		iter->eigen_vector0.Normalize();
		iter->eigen_vector1.Normalize();
		iter->N().Normalize();
	}
}
double WLOP::iterate()
{
	Timer time;

	initVertexes();

	time.start("Sample Original Neighbor Tree!!!");
	GlobalFun::computeBallNeighbors(samples, original, 
		para->getDouble("CGrid Radius"), box);
	time.end();

	time.start("Sample Sample Neighbor Tree");
	GlobalFun::computeBallNeighbors(samples, NULL, 
		para->getDouble("CGrid Radius"), samples->bbox);
	time.end();
	
	if (nTimeIterated == 0) 
	{
		if (para->getBool("Need Compute Density"))
		{
			double local_density_para = 0.95;
			time.start("Original Original Neighbor Tree");
			GlobalFun::computeBallNeighbors(original, NULL, 
				para->getDouble("CGrid Radius") * local_density_para, original->bbox);
			time.end();

			time.start("Compute Original Density");
			original_density.assign(original->vn, 0);

			computeDensity(true, para->getDouble("CGrid Radius") * local_density_para);
			time.end();
		}
		
	}

	if (para->getBool("Need Compute Density"))
	{
		time.start("Compute Density For Sample");
		computeDensity(false, para->getDouble("CGrid Radius"));
		time.end();
	}

	time.start("Sample Original Neighbor Tree!!!");
	GlobalFun::computeBallNeighbors(samples, original, 
		para->getDouble("CGrid Radius"), box);
	time.end();

	time.start("Compute Average Term");
	computeAverageTerm(samples, original);
	time.end();

	time.start("Compute Repulsion Term");
	computeRepulsionTerm(samples);
	time.end();

	double mu = para->getDouble("Repulsion Mu");
	Point3f c;

	for(int i = 0; i < samples->vert.size(); i++)
	{
		CVertex& v = samples->vert[i];
		c = v.P();

		if (average_weight_sum[i] > 1e-20)
		{
			v.P() = average[i] / average_weight_sum[i];
		}

		if (repulsion_weight_sum[i] > 1e-20 && mu >= 0)
		{
			v.P() +=  repulsion[i] * (mu / repulsion_weight_sum[i]);
		}

		if (average_weight_sum[i] > 1e-20 && repulsion_weight_sum[i] > 1e-20 )
		{
			Point3f diff = v.P() - c; 
			double move_error = sqrt(diff.SquaredNorm());

			error_x += move_error; 
		}
	}
	error_x = error_x / samples->vn;

	para->setValue("Current Movement Error", DoubleValue(error_x));
	cout << "****finished compute WLOP error:	" << error_x << endl;

	if (para->getBool("Need Compute PCA"))
	{
		time.start("Recompute PCA");
		recomputePCA_Normal();
		time.end();
	}
	return error_x;
}