void Various_Processing_Component::LaplacianSmoothing (PolyhedronPtr pMesh, double deformFactor, int iteraNum, bool preserveBoundaries)
{
	Vertex_iterator	pVertex;
	int numVertex = pMesh->size_of_vertices();
	Vector * newPositions = new Vector[numVertex];

	for (int i=0; i<iteraNum; i++)
	{
		int n = 0;
		for (pVertex = pMesh->vertices_begin(); pVertex != pMesh->vertices_end(); pVertex++)
		{
			Vector currentVector = pVertex->point() - CGAL::ORIGIN;

			// do not smooth the boundary vertices if demanded by user
			bool is_border_vertex = false;
			bool stopFlag = false;
			Halfedge_around_vertex_circulator hav = (*pVertex).vertex_begin();
			do
			{
				if (hav->is_border()==true)
				{
					is_border_vertex = true;
					stopFlag = true;
				}
				hav++;
			} while ((hav!=(*pVertex).vertex_begin())&&(stopFlag==false));

			if ((preserveBoundaries==true)&&(is_border_vertex==true))
			{
				newPositions[n] = currentVector;
				n++;
				continue;
			}

			std::size_t degree = (*pVertex).vertex_degree();
			double alpha = 1.0/degree;
			Vector vectemp = Point3d(0,0,0) - CGAL::ORIGIN;
			Halfedge_around_vertex_circulator h = (*pVertex).vertex_begin();
			do
			{
				vectemp = vectemp+(h->opposite()->vertex()->point()-CGAL::ORIGIN-currentVector)*alpha;
				++h;
			} while (h != (*pVertex).vertex_begin());
			newPositions[n] = currentVector + deformFactor*vectemp;
			n++;
		}

		n = 0;
		for (pVertex = pMesh->vertices_begin(); pVertex != pMesh->vertices_end(); pVertex++)
		{
			pVertex->point() = Point3d(0,0,0) + newPositions[n];
			n++;
		}
	}

	delete [] newPositions;
	newPositions = 0;

	pMesh->compute_normals();
}
void Various_Processing_Component::NoiseAdditionUniform (PolyhedronPtr pMesh, double noiseIntensity, bool preserveBoundaries)
{
	// mesh centre calculation based on discrete "moment".
	//TODO: maybe in the future it will be based on volume moment.
	int numVertex = pMesh->size_of_vertices();;
	Vector centroid = Point3d(0,0,0) - CGAL::ORIGIN;
	double distancetoCentroid = 0.0;
	Vertex_iterator	pVertex;
	for (pVertex = pMesh->vertices_begin(); pVertex != pMesh->vertices_end(); pVertex++)
	{
		Vector vectemp = pVertex->point() - CGAL::ORIGIN;
		centroid = centroid + vectemp;
	}
	centroid = centroid/numVertex;

	// calculate the average distance from vertices to mesh centre
	for (pVertex = pMesh->vertices_begin(); pVertex!= pMesh->vertices_end(); pVertex++)
	{
		Vector vectemp = pVertex->point() - CGAL::ORIGIN;
		distancetoCentroid = distancetoCentroid + (double)std::sqrt((vectemp - centroid) * (vectemp - centroid));
	}
	distancetoCentroid = distancetoCentroid/numVertex;

	// add random uniform-distributed (between [-noiseLevel, +noiseLevel])
	srand((unsigned)time(NULL));
	double noisex, noisey, noisez;
	double noiseLevel = distancetoCentroid * noiseIntensity;
	for (pVertex = pMesh->vertices_begin(); pVertex!= pMesh->vertices_end(); pVertex++)
	{
		// keep boundaries untouched if demanded by user
		bool is_border_vertex = false;
		bool stopFlag = false;
		Halfedge_around_vertex_circulator hav = (*pVertex).vertex_begin();
		do
		{
			if (hav->is_border()==true)
			{
				is_border_vertex = true;
				stopFlag = true;
			}
			hav++;
		} while ((hav!=(*pVertex).vertex_begin())&&(stopFlag==false));

		if ((preserveBoundaries==true)&&(is_border_vertex==true))
			continue;

		noisex = noiseLevel * (1.0*rand()/RAND_MAX-0.5)*2;
		noisey = noiseLevel * (1.0*rand()/RAND_MAX-0.5)*2;
		noisez = noiseLevel * (1.0*rand()/RAND_MAX-0.5)*2;
		Vector temp = Point3d(noisex, noisey, noisez) - CGAL::ORIGIN;
		pVertex->point() = pVertex->point() + temp;
	}

	// for correct rendering, we need to update the mesh normals
	pMesh->compute_normals();
}
Example #3
0
//Description :: Check if removal of this vertex would violate the manifold_property or not.
bool Check_Manifold_Property(Halfedge_handle h, const int &type,const int &valence)
{
	bool check = false;
	Halfedge_handle g = h;
	int* Points_index = new int[valence];

	// if valence is 3, no new edge is inserted, so always safe to remove.
	if(valence == 3)
	{
		return false;
	}

	else
	{
		// Points_index[] contains all boundary vertices' indices (ordered in counterclockwise)

		Points_index[0] = g->vertex()->Vertex_Number_S;
		g = g->next(); // g points center vertex;

		for(int i=1; i<valence; i++)
		{
			g = g->prev_on_vertex();// around the vertex in the counterclockwise way.
			Points_index[i] = g->opposite()->vertex()->Vertex_Number_S;
		}

		// quadrangle
		if (valence == 4)
		{
			if ((type == 5) || (type == 8))
			{
				g = h->opposite();
				Halfedge_around_vertex_circulator Hvc = g->vertex_begin();
				Halfedge_around_vertex_circulator Hvc_end = Hvc;

				CGAL_For_all(Hvc,Hvc_end)
				{
					if (Hvc->opposite()->vertex()->Vertex_Number_S == Points_index[1])
						check = true;
				}
			}

			else if (( type == 6) || (type == 7))
			{
				g = h;
				Halfedge_around_vertex_circulator Hvc = g->vertex_begin();
				Halfedge_around_vertex_circulator Hvc_end = Hvc;

				CGAL_For_all(Hvc,Hvc_end)
				{
					if (Hvc->opposite()->vertex()->Vertex_Number_S == Points_index[2])
						check = true;;
				}

			}
Example #4
0
  void border_node(Halfedge_iterator eitr, Point& ept, Point& vpt) {
    Point& ep1 = eitr->vertex()->point();
    Point& ep2 = eitr->opposite()->vertex()->point();
    ept = Point((ep1[0]+ep2[0])/2, (ep1[1]+ep2[1])/2, (ep1[2]+ep2[2])/2);

    Halfedge_around_vertex_circulator vcir = eitr->vertex_begin();
    Point& vp1  = vcir->opposite()->vertex()->point();
    Point& vp0  = vcir->vertex()->point();
    Point& vp_1 = (--vcir)->opposite()->vertex()->point();
    vpt = Point((vp_1[0] + 6*vp0[0] + vp1[0])/8,
                (vp_1[1] + 6*vp0[1] + vp1[1])/8,
                (vp_1[2] + 6*vp0[2] + vp1[2])/8 );
  }
Example #5
0
  void vertex_node(Vertex_iterator vitr, Point& pt) {
    double R[] = {0.0, 0.0, 0.0};
    Point& S = vitr->point();

    Halfedge_around_vertex_circulator vcir = vitr->vertex_begin();
    std::size_t n = circulator_size(vcir);
    for (std::size_t i = 0; i < n; i++, ++vcir) {
      Point& p = vcir->opposite()->vertex()->point();
      R[0] += p[0]; 	R[1] += p[1]; 	R[2] += p[2];
    }
    if (n == 6) {
      pt = Point((10*S[0]+R[0])/16, (10*S[1]+R[1])/16, (10*S[2]+R[2])/16);
    } else if (n == 3) {
      double B = (5.0/8.0 - std::sqrt(3+2*std::cos(6.283/n))/64.0)/n;
      double A = 1-n*B;
      pt = Point((A*S[0]+B*R[0]), (A*S[1]+B*R[1]), (A*S[2]+B*R[2]));
    } else {
      double B = 3.0/8.0/n;
      double A = 1-n*B;
      pt = Point((A*S[0]+B*R[0]), (A*S[1]+B*R[1]), (A*S[2]+B*R[2]));
    }
  }
Example #6
0
	void MSDM2_Component::ProcessMSDM2_per_vertex( Vertex_iterator pVertex,double radius,std::vector<double> & TabDistance1,std::vector<double>& TabDistance2,std::vector<Point3d> &TabPoint1,std::vector<Point3d> &TabPoint2)
	{

		std::set<int> vertices ;

        std::stack<Vertex_iterator> S ;

		Point3d O = pVertex->point() ;

        S.push(pVertex) ;	
        vertices.insert(pVertex->tag()) ;
		
	
		TabDistance1.push_back(pVertex->KmaxCurv);
		TabPoint1.push_back(pVertex->point());

		TabDistance2.push_back(pVertex->curvmatch);
		TabPoint2.push_back(pVertex->match);

		int NbSommetInSphere=0;
                //double SommeDistance=0; // MT
	

        while(!S.empty())
		{
			Vertex_iterator v = S.top() ;
            S.pop() ;
            Point3d P = v->point() ;
            Halfedge_around_vertex_circulator h = v->vertex_begin();
			Halfedge_around_vertex_circulator pHalfedgeStart = h;
			CGAL_For_all(h,pHalfedgeStart)
			{
                Point3d p1 = h->vertex()->point();
				Point3d p2 = h->opposite()->vertex()->point();

				Point3d p1m = h->vertex()->match;
				Point3d p2m = h->opposite()->vertex()->match;

				Vector V = (p2-p1);
				Vector Vm = (p2m-p1m);

                if(v==pVertex || V * (P - O) > 0.0) 
				{
					double len_old = std::sqrt(V*V);
					bool isect = sphere_clip_vector_MSDM2(O, radius, P, V) ;
					double len_edge = std::sqrt(V*V);

					NbSommetInSphere++;
					
					
					double WeightedCurv1,WeightedCurv2;
					Point3d WeightedP1,WeightedP2;

					bool IsAlreadyIntegrated=false;
					if(!isect) 
					{
						
						Vertex_iterator w=h->opposite()->vertex();
                       if(vertices.find(w->tag()) == vertices.end())
						{
                            vertices.insert(w->tag()) ;
                            S.push(w) ;
                        }
					   else
						   IsAlreadyIntegrated=true;
                    }

					if (IsAlreadyIntegrated==false)
					{
						if(len_old!=0)
						{
							if(isect)
							{
								WeightedCurv1=(1-len_edge/len_old)*h->vertex()->KmaxCurv+len_edge/len_old*h->opposite()->vertex()->KmaxCurv;
								WeightedP1=p1+V;

								WeightedCurv2=(1-len_edge/len_old)*h->vertex()->curvmatch+len_edge/len_old*h->opposite()->vertex()->curvmatch;
								WeightedP2=p1m+(len_edge/len_old)*Vm;
							}
							else
							{
								WeightedCurv1=h->opposite()->vertex()->KmaxCurv;
								WeightedCurv2=h->opposite()->vertex()->curvmatch;
								WeightedP1=p2;
								WeightedP2=p2m;
							}
						}
						else
						{
							WeightedCurv1=h->opposite()->vertex()->KmaxCurv;
							WeightedCurv2=h->opposite()->vertex()->curvmatch;
							WeightedP1=p2;
							WeightedP2=p2m;
						}

						TabDistance1.push_back(WeightedCurv1);
						TabPoint1.push_back(WeightedP1);

						TabDistance2.push_back(WeightedCurv2);
						TabPoint2.push_back(WeightedP2);
					}

					

					
					
				}
                
			}
			
		}
// this time, we add Gaussian-distributed additive noise to the mesh vertex coordinates
// the standard deviation of the Gaussian distribution is "noiseLevel = distancetoCentroid * noiseIntensity"
void Various_Processing_Component::NoiseAdditionGaussian (PolyhedronPtr pMesh, double noiseIntensity, bool preserveBoundaries)
{
	int numVertex = pMesh->size_of_vertices();;
	Vector centroid = Point3d(0,0,0) - CGAL::ORIGIN;
	double distancetoCentroid = 0.0;
	Vertex_iterator	pVertex;
	for (pVertex = pMesh->vertices_begin(); pVertex != pMesh->vertices_end(); pVertex++)
	{
		Vector vectemp = pVertex->point() - CGAL::ORIGIN;
		centroid = centroid + vectemp;
	}
	centroid = centroid/numVertex;

	for (pVertex = pMesh->vertices_begin(); pVertex!= pMesh->vertices_end(); pVertex++)
	{
		Vector vectemp = pVertex->point() - CGAL::ORIGIN;
		distancetoCentroid = distancetoCentroid + (double)std::sqrt((vectemp - centroid) * (vectemp - centroid));
	}
	distancetoCentroid = distancetoCentroid/numVertex;

	srand((unsigned)time(NULL));
	double noisex, noisey, noisez;
	double * gaussNumbers = new double[3];
	double noiseLevel = distancetoCentroid * noiseIntensity;
	for (pVertex = pMesh->vertices_begin(); pVertex!= pMesh->vertices_end(); pVertex++)
	{
		bool is_border_vertex = false;
		bool stopFlag = false;
		Halfedge_around_vertex_circulator hav = (*pVertex).vertex_begin();
		do
		{
			if (hav->is_border()==true)
			{
				is_border_vertex = true;
				stopFlag = true;
			}
			hav++;
		} while ((hav!=(*pVertex).vertex_begin())&&(stopFlag==false));

		if ((preserveBoundaries==true)&&(is_border_vertex==true))
			continue;

		// pseudo-random Gaussian-distributed numbers generation from uniformly-distributed pseudo-random numbers
		double x, y, r2;
		for (int i=0; i<3; i++)
		{
			do
			{
				x = -1.0 + 2.0 * 1.0*rand()/RAND_MAX;
				y = -1.0 + 2.0 * 1.0*rand()/RAND_MAX;
				r2 = x * x + y * y;
			} while ((r2>1.0)||(r2==0.0));
			gaussNumbers[i] = y * sqrt(-2.0 * log(r2) / r2);
		}

		noisex = noiseLevel * gaussNumbers[0];
		noisey = noiseLevel * gaussNumbers[1];
		noisez = noiseLevel * gaussNumbers[2];
		Vector temp = Point3d(noisex, noisey, noisez) - CGAL::ORIGIN;
		pVertex->point() = pVertex->point() + temp;
	}

	pMesh->compute_normals();

	delete [] gaussNumbers;
	gaussNumbers = 0;
}