Ejemplo n.º 1
0
void alignMesh( Polyhedron & poly )
{
    int num = poly.size_of_vertices();

    // initialization here is very important!!
    Point3 ave( 0.0, 0.0, 0.0 );
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	ave = ave + ( vi->point() - CGAL::ORIGIN );
    }
    ave = CGAL::ORIGIN + ( ave - CGAL::ORIGIN )/( double )num;

    unsigned int dim	= 3;
    double * data	= new double [ num*dim ];

    int nPoints = 0;
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	data[ nPoints * dim + 0 ] = vi->point().x() - ave.x();
	data[ nPoints * dim + 1 ] = vi->point().y() - ave.y();
	data[ nPoints * dim + 2 ] = vi->point().z() - ave.z();
	nPoints++;
    }

    assert( nPoints == ( int )num );

    /*****************************************
      analyze the engenstructure of X^T X
     *****************************************/
    /* define the matrix X */
    gsl_matrix_view X = gsl_matrix_view_array( data, num, dim );

    /* memory reallocation */
    // proj = ( double * )realloc( proj, sizeof( double ) * PDIM * num );

    /* calculate the covariance matrix B */
    gsl_matrix * B              = gsl_matrix_alloc( dim, dim );
    gsl_blas_dgemm( CblasTrans, CblasNoTrans, 1.0,
                    &(X.matrix),
                    &(X.matrix), 0.0,
                    B );
       
    /* divided by the number of samples */
    gsl_matrix_scale( B, 1.0/(double)num );

    gsl_vector * eVal       = gsl_vector_alloc( dim );
    gsl_matrix * eVec       = gsl_matrix_alloc( dim, dim );
    gsl_eigen_symmv_workspace * w
                                = gsl_eigen_symmv_alloc( dim );

    // eigenanalysis of the matrix B
    gsl_eigen_symmv( B, eVal, eVec, w );
    // release the memory of w
    gsl_eigen_symmv_free( w );
    // sort eigenvalues in a descending order
    gsl_eigen_symmv_sort( eVal, eVec, GSL_EIGEN_SORT_VAL_DESC );

    // #ifdef MYDEBUG
    for ( unsigned int i = 0; i < dim; ++i ) {
	cerr << "Eigenvalue No. " << i << " = " << gsl_vector_get( eVal, i ) << endl;
	cerr << "Eigenvector No. " << i << endl;
	double length = 0.0;
	for ( unsigned int j = 0; j < dim; ++j ) {
	    cerr << gsl_matrix_get( eVec, i, j ) << " ";
	    length += gsl_matrix_get( eVec, i, j )*gsl_matrix_get( eVec, i, j );
	}
	cerr << " length = " << length << endl;
    }
    // #endif	// MYDEBUG

    // 0 1 2, 0 2 1, 
    

    Transformation3 map;
    map = 
	Transformation3( gsl_matrix_get(eVec,1,0), gsl_matrix_get(eVec,0,0), gsl_matrix_get(eVec,2,0),
			 gsl_matrix_get(eVec,1,1), gsl_matrix_get(eVec,0,1), gsl_matrix_get(eVec,2,1),
			 gsl_matrix_get(eVec,1,2), gsl_matrix_get(eVec,0,2), gsl_matrix_get(eVec,2,2) );
    if ( map.is_odd() ) {
	cerr << " Transformation matrix reflected" << endl;
	map = 
	    Transformation3( gsl_matrix_get(eVec,1,0), gsl_matrix_get(eVec,0,0), -gsl_matrix_get(eVec,2,0),
			     gsl_matrix_get(eVec,1,1), gsl_matrix_get(eVec,0,1), -gsl_matrix_get(eVec,2,1),
			     gsl_matrix_get(eVec,1,2), gsl_matrix_get(eVec,0,2), -gsl_matrix_get(eVec,2,2) );
    }

    for ( unsigned int i = 0; i < dim; ++i ) {
	cerr << "| ";
	for ( unsigned int j = 0; j < dim; ++j ) {
	    cerr << map.cartesian( i, j ) << " ";
	}
	cerr << "|" << endl;
    }

    transformMesh( poly, map );

    return;
}
Ejemplo n.º 2
0
//------------------------------------------------------------------------------
//	Normalize the 3D triangulated mesh with the display window
//------------------------------------------------------------------------------
void normalizeMesh( Polyhedron & poly, vector< Segment3 > & bone )
{
    Vector3 sum, ave;

    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	sum = sum + ( vi->point() - CGAL::ORIGIN );
    }
    ave = sum / ( double )poly.size_of_vertices();

    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	vi->point() = vi->point() - ave;
    }
    
    cerr << " ave = " << ave << endl;
    Transformation3 translate( CGAL::TRANSLATION, -ave );

    // fabs:absolute values-no negative values
    double sideMax = 0.0;
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	if ( fabs( vi->point().x() ) > sideMax ) sideMax = fabs( vi->point().x() );
	if ( fabs( vi->point().y() ) > sideMax ) sideMax = fabs( vi->point().y() );
	if ( fabs( vi->point().z() ) > sideMax ) sideMax = fabs( vi->point().z() );
    }
    
	// sideMax: the largest number
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	vi->point() = CGAL::ORIGIN + ( vi->point() - CGAL::ORIGIN ) / sideMax;
    }

    Transformation3 scale( CGAL::SCALING, 1.0/sideMax );

    Transformation3 composite = scale * translate;
	    
    for ( unsigned int k = 0; k < bone.size(); ++k ) {
	bone[ k ] = bone[ k ].transform( composite );
    }
}
Ejemplo n.º 3
0
void gnuplot_print_vertices(std::ostream& out, const Vertices& vertices)
{
    for (Vertex_iterator it = vertices.begin(); it != vertices.end(); ++it)
        out << (*it) << " " << it->unique_id() << endl;
}
Ejemplo n.º 4
0
//------------------------------------------------------------------------------
//	Align the mesh
//------------------------------------------------------------------------------
Vector3 principalAxis( Polyhedron & poly )
{
    int num = poly.size_of_vertices();

    // initialization here is very important!!
    Point3 ave( 0.0, 0.0, 0.0 );
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	ave = ave + ( vi->point() - CGAL::ORIGIN );
    }
    ave = CGAL::ORIGIN + ( ave - CGAL::ORIGIN )/( double )num;

    unsigned int dim	= 3;
    double * data	= new double [ num*dim ];

    int nPoints = 0;
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	data[ nPoints * dim + 0 ] = vi->point().x() - ave.x();
	data[ nPoints * dim + 1 ] = vi->point().y() - ave.y();
	data[ nPoints * dim + 2 ] = vi->point().z() - ave.z();
	nPoints++;
    }

    assert( nPoints == ( int )num );

    /*****************************************
      analyze the engenstructure of X^T X
     *****************************************/
    /* define the matrix X */
    gsl_matrix_view X = gsl_matrix_view_array( data, num, dim );

    /* memory reallocation */
    // proj = ( double * )realloc( proj, sizeof( double ) * PDIM * num );

    /* calculate the covariance matrix B */
    gsl_matrix * B              = gsl_matrix_alloc( dim, dim );
    gsl_blas_dgemm( CblasTrans, CblasNoTrans, 1.0,
                    &(X.matrix),
                    &(X.matrix), 0.0,
                    B );
       
    /* divided by the number of samples */
    gsl_matrix_scale( B, 1.0/(double)num );

    gsl_vector * eVal       = gsl_vector_alloc( dim );
    gsl_matrix * eVec       = gsl_matrix_alloc( dim, dim );
    gsl_eigen_symmv_workspace * w
                                = gsl_eigen_symmv_alloc( dim );

    // eigenanalysis of the matrix B
    gsl_eigen_symmv( B, eVal, eVec, w );
    // release the memory of w
    gsl_eigen_symmv_free( w );
    // sort eigenvalues in a descending order
    gsl_eigen_symmv_sort( eVal, eVec, GSL_EIGEN_SORT_VAL_DESC );

#ifdef MYDEBUG
    for ( unsigned int i = 0; i < dim; ++i ) {
	cerr << "Eigenvalue No. " << i << " = " << gsl_vector_get( eVal, i ) << endl;
	cerr << "Eigenvector No. " << i << endl;
	for ( unsigned int j = 0; j < dim; ++j ) {
	    length += gsl_matrix_get( eVec, i, j )*gsl_matrix_get( eVec, i, j );
	}
	cerr << " length = " << length << endl;
    }
#endif	// MYDEBUG

    Vector3 ref( gsl_matrix_get( eVec, 0, 0 ),
		 gsl_matrix_get( eVec, 0, 1 ),
		 gsl_matrix_get( eVec, 0, 2 ) );
    return ref;

#ifdef DEBUG
    gsl_vector_view eachVec = gsl_matrix_column( eigenVec, 0 );
    double cosRot = gsl_matrix_get( eigenVec, 0, 1 );
    double sinRot = gsl_matrix_get( eigenVec, 1, 1 );
#ifdef DEBUG
    cerr << " 2nd axis : " << cosRot << " , " << sinRot << endl;
#endif	// DEBUG

    Transformation2 rotate( CGAL::ROTATION, -sinRot, cosRot );
    for ( unsigned int i = 0; i < subpatch.size(); ++i ) {
	subpatch[ i ]->triangle() = subpatch[ i ]->triangle().transform( rotate );
    }
#endif	// DEBUG
}
Ejemplo n.º 5
0
void MSDM2_Component::Matching_Multires_Update(PolyhedronPtr m_PolyDegrad, Facet * _TabMatchedFacet)
	{
		
		
		int ind=0;
		for(Vertex_iterator	pVertex	= m_PolyDegrad->vertices_begin();
					pVertex	!= m_PolyDegrad->vertices_end();
					pVertex++)
		{
                        //Point3d Nearest=pVertex->match; // MT
			Facet* f_Nearest=&_TabMatchedFacet[ind];

			pVertex->tag(ind);

			ind++;

			//for debug
			//pVertex->point()=Nearest;

			///calculation of the nearest point curvature value using vertices of the Nearest triangle	
			//we use linear interpolation using barycentric coordinates
			Point3d x1=f_Nearest->halfedge()->vertex()->point();
			Point3d x2=f_Nearest->halfedge()->next()->vertex()->point();
			Point3d x3=f_Nearest->halfedge()->next()->next()->vertex()->point();

			double l1=sqrt((x3-x2)*(x3-x2));
			double l2=sqrt((x1-x3)*(x1-x3));
			double l3=sqrt((x1-x2)*(x1-x2));

			Vector v1=f_Nearest->halfedge()->vertex()->point()-pVertex->point();
			Vector v2=f_Nearest->halfedge()->next()->vertex()->point()-pVertex->point();
			Vector v3=f_Nearest->halfedge()->next()->next()->vertex()->point()-pVertex->point();

			double t1=sqrt(v1*v1);
			double t2=sqrt(v2*v2);
			double t3=sqrt(v3*v3);
			
			double p1=(l1+t2+t3)/2;
			double p2=(t1+l2+t3)/2;
			double p3=(t1+t2+l3)/2;

			double A1=(p1*(p1-l1)*(p1-t3)*(p1-t2));
			double A2=(p2*(p2-l2)*(p2-t3)*(p2-t1));
			double A3=(p3*(p3-l3)*(p3-t1)*(p3-t2));

			if(A1>0) A1=sqrt(A1); else	A1=0;
			if(A2>0) A2=sqrt(A2); else	A2=0;
			if(A3>0) A3=sqrt(A3); else	A3=0;
			
			double c1=f_Nearest->halfedge()->vertex()->KmaxCurv;
			double c2=f_Nearest->halfedge()->next()->vertex()->KmaxCurv;
			double c3=f_Nearest->halfedge()->next()->next()->vertex()->KmaxCurv;

			if((A1+A2+A3)>0)
				pVertex->curvmatch=(A1*c1+A2*c2+A3*c3)/(A1+A2+A3);
			else
				pVertex->curvmatch=(c1+c2+c3)/3;		


			

			
		}
		
}
Ejemplo n.º 6
0
//! Initialize an arrangement
void init_arr(Arrangement& arr, int verbose_level)
{
  // Initialize the data of the halfedges of the arrangement.
  Halfedge_iterator heit;
  for (heit = arr.halfedges_begin(); heit != arr.halfedges_end(); ++heit)
    heit->set_data(heit->curve().data() *
                   ((heit->direction() == CGAL::ARR_LEFT_TO_RIGHT) ? 1 : 2));

  // Initialize the data of the faces of the arrangement.
  Face_iterator fit;
  for (fit = arr.faces_begin(); fit != arr.faces_end(); ++fit) {
    unsigned int count = 0;

    // Outer ccb
    Outer_ccb_iterator ocit;
    for (ocit = fit->outer_ccbs_begin(); ocit != fit->outer_ccbs_end(); ++ocit) {
      Ccb_halfedge_circulator curr = *ocit;
      do count += curr->data() * 2;
      while (++curr != *ocit);
    }

    // Inner ccbs
    Inner_ccb_iterator icit;
    for (icit = fit->inner_ccbs_begin(); icit != fit->inner_ccbs_end(); ++icit) {
      Ccb_halfedge_circulator curr = *icit;
      do count += curr->data();
      while (++curr != *icit);
    }

    fit->set_data(count);
  }

  // Initialize the data of the vertices of the arrangement.
  Vertex_iterator vit;
  for (vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit) {
    unsigned int count = 0;
    if (vit->is_isolated()) count = vit->face()->data();
    else {
      Halfedge_around_vertex_const_circulator curr = vit->incident_halfedges();
      do count += curr->data();
      while (++curr != vit->incident_halfedges());
    }
    vit->set_data(count);
  }

  if (verbose_level > 0) std::cout << "Arrangement Input: " << std::endl;

  if (verbose_level > 1) {
    std::cout << "Halfedge Data: " << std::endl;
    Halfedge_iterator heit;
    for (heit = arr.halfedges_begin(); heit != arr.halfedges_end(); ++heit)
      std::cout << heit->source()->point() << " "
                << heit->target()->point() << " " << heit->data()
                << std::endl;
  }

  if (verbose_level > 0) {
    std::cout << "Face Data: " << std::endl;
    Face_iterator fit;
    for (fit = arr.faces_begin(); fit != arr.faces_end(); ++fit)
      std::cout << fit->data() << std::endl;
  }
}
/**
 * Executes one custom timestep
 * @param averageEdgeLength The function to compute the average edge length for a given vertex
 * @param getOffsetPoint Computes the new location of the given point
 * @return The results of running the timestep
 */
stepResults StoneWeatherer::doOneCustomStep( double ( *averageEdgeLength )( const Vertex_handle & v ), Point( *getOffsetPoint )( const Point & p, const VertexData & d, const StoneWeatherer * caller ) ) {

	CGAL::Timer timestamp;
	stepResults result;
	result.secondsTotal = 0.0;
	timestamp.start();
	timestamp.reset();
	
	/**
	 * Maps circumcenters to where they really came from
	 */
	 map<Point,Point> pointMap;

	// Generate the correct-resolution offset points
	vector<Point> newPoints;
	int n;
	int i;
	int j;
	Vertex_handle vhi;
	Vertex_handle vhj;
	double dist2;
	Point a;
	Point b;
	Point c;
	VertexData d;

	// Put in midPoints of edges as needed, and flag redundant vertices
	for ( Cell_iterator it = newDT->finite_cells_begin(); it != newDT->finite_cells_end(); ++it ) {

		if ( it->info() != AIR ) {
			
			for ( n = 0; n < 4; ++n ) {

				if ( it->neighbor( n )->info() != it->info() || newDT->is_infinite( it->neighbor( n ) ) ) {

					for ( i = 1; i < 4; ++i ) {

						Vertex_handle vhi = it->vertex( n ^ i );

						for ( j = i + 1; j < 4; ++j ) {

							Vertex_handle vhj = it->vertex( n ^ j );

							// Only check each edge once...
							if ( vhi < vhj ) {

								dist2 = ( vhi->point() - vhj->point() ).squared_length();

								if ( dist2 > maxSquareDistance( averageEdgeLength, vhi, vhj ) ) {

									// Don't split non-live edges
									a = vhi->point();
									b = vhj->point();

									if ( !live( a.x(), a.y(), a.z() ) && !live( b.x(), b.y(), b.z() ) ) {

										continue;
									}

									// Split edge
									a = CGAL::ORIGIN + ( ( a - CGAL::ORIGIN ) + ( b - CGAL::ORIGIN ) ) * 0.5;
									d = VertexData::midPoint( vhi->info(), vhj->info() );
									
									//// If the vertex is shared by both objects, split it
									//if ( ( d.flag & ROCK ) && ( d.flag & MORE_ROCK ) ) {

									//	VertexData d1;
									//	VertexData d2;
									//	splitVertexData( d, d1, d2 );
									//	
									//	Point a1 = jitterPoint( a );
									//	Point a2 = jitterPoint( a );
									//	
									//	c = getOffsetPoint( a1, d1, this );
									//	newPoints.push_back( c );
									//	pointMap.insert( pair<Point,Point>( c, a1 ) );

									//	c = getOffsetPoint( a2, d2, this );
									//	newPoints.push_back( c );
									//	pointMap.insert( pair<Point,Point>( c, a2 ) );
									//}
									//else {

										c = getOffsetPoint( a, d, this );
										newPoints.push_back( c );
										pointMap.insert( pair<Point,Point>( c, a ) );
									//}
								}
								else if ( vhi->info().kill != TOO_CLOSE && dist2 < minSquareDistance( averageEdgeLength, vhi, vhj ) ) {

									// The higher-address endpoint
									vhj->info().kill = TOO_CLOSE;
								}
							}
						}
					}
				}
			}
		}
	}

	double bound[ 3 ][ 2 ] = {
		{ 1.0e30, -1.0e30 },
		{ 1.0e30, -1.0e30 },
		{ 1.0e30, -1.0e30 }
	};

	// Put in all the border vertices
	for ( Vertex_iterator it = newDT->finite_vertices_begin(); it != newDT->finite_vertices_end(); ++it ) {

		if ( it->point().x() < bound[ 0 ][ 0 ] ) {

			bound[ 0 ][ 0 ] = it->point().x();
		}
		else if ( it->point().x() > bound[ 0 ][ 1 ] ) {

			bound[ 0 ][ 1 ] = it->point().x();
		}

		if ( it->point().y() < bound[ 1 ][ 0 ] ) {

			bound[ 1 ][ 0 ] = it->point().y();
		}
		else if ( it->point().y() > bound[ 1 ][ 1 ] ) {

			bound[ 1 ][ 1 ] = it->point().y();
		}

		if ( it->point().z() < bound[ 2 ][ 0 ] ) {

			bound[ 2 ][ 0 ] = it->point().z();
		}
		else if ( it->point().z() > bound[ 2 ][ 1 ] ) {

			bound[ 2 ][ 1 ] = it->point().z();
		}

		if ( !live( it->point().x(), it->point().y(), it->point().z() ) ) {

			newPoints.push_back( it->point() );
			pointMap.insert( pair<Point,Point>( it->point(), it->point() ) );
		}
		else if ( it->info().kill == BORDER ) {

			VertexData d = it->info();
			Point a = it->point();
			Point c;

			//// If the vertex is shared by both objects, split it
			//if ( ( d.flag & ROCK ) && ( d.flag & MORE_ROCK ) ) {

			//	VertexData d1;
			//	VertexData d2;
			//	splitVertexData( d, d1, d2 );
			//	
			//	Point a1 = jitterPoint( a );
			//	Point a2 = jitterPoint( a );
			//	
			//	c = getOffsetPoint( a1, d1, this );
			//	newPoints.push_back( c );
			//	pointMap.insert( pair<Point,Point>( c, a1 ) );

			//	c = getOffsetPoint( a2, d2, this );
			//	newPoints.push_back( c );
			//	pointMap.insert( pair<Point,Point>( c, a2 ) );
			//}
			//else {

				c = getOffsetPoint( a, d, this );
				newPoints.push_back( c );
				pointMap.insert( pair<Point,Point>( c, a ) );
			//}
		}
	}

	result.secondsTotal += ( result.secondsMotion = timestamp.time() );
	timestamp.reset();

	// Create the new mesh
	swapDT();
	newDT->clear();
	newDT->insert( newPoints.begin(), newPoints.end() );

	result.secondsTotal += ( result.secondsCGAL = timestamp.time() );
	//secondsTotal += result.secondsCGAL;
	//secondsCGAL += result.secondsCGAL;
	timestamp.reset();

	// Update the inside-outside flags of new tetrahedrons
	setContentFlags( result.midPoint, pointMap );
	result.midPoint[ 0 ] = ( bound[ 0 ][ 0 ] + bound[ 0 ][ 1 ] ) * 0.5;
	result.midPoint[ 1 ] = ( bound[ 1 ][ 0 ] + bound[ 1 ][ 1 ] ) * 0.5;
	result.midPoint[ 2 ] = ( bound[ 2 ][ 0 ] + bound[ 2 ][ 1 ] ) * 0.5;

	result.secondsTotal += ( result.secondsLabeling = timestamp.time() );
	//secondsTotal += result.secondsLabeling;
	//secondsLabeling += result.secondsLabeling;
	timestamp.reset();

	// Update vertex information
	setVertexInfo();

	result.secondsTotal += ( result.secondsAnalysis = timestamp.time() );
	timestamp.reset();
	timestamp.stop();

	result.numVertices = newDT->number_of_vertices();
	result.numTetrahedrons = newDT->number_of_cells();

	cumulativeResults.secondsTotal += result.secondsTotal;
	cumulativeResults.secondsMotion += result.secondsMotion;
	cumulativeResults.secondsCGAL += result.secondsCGAL;
	cumulativeResults.secondsLabeling += result.secondsLabeling;
	cumulativeResults.secondsAnalysis += result.secondsAnalysis;

	return result;
}
Ejemplo n.º 8
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);
					}

					

					
					
				}
                
			}
			
		}
/**
 * Sets the new vertex info for the vertices in the new mesh
 */
void StoneWeatherer::setVertexInfo() {

	// Clear everything
	for ( Vertex_iterator it = newDT->finite_vertices_begin(); it != newDT->finite_vertices_end(); ++it ) {

		it->info().clear();
	}

	int i;

	// Label the vertices to keep (those defining boundaries between materials, where "infinite" means "air")
	for ( All_Cell_iterator it = newDT->all_cells_begin(); it != newDT->all_cells_end(); ++it ) {

		if ( newDT->is_infinite( it ) ) {

			for ( i = 0; i < 4; ++i ) {

				it->vertex( i )->info().flag |= AIR;
			}
		}
		else {

			for ( i = 0; i < 4; ++i ) {

				it->vertex( i )->info().flag |= it->info();
			}
		}
	}

	// Simplify the labels for mesh simplification later
	for ( Vertex_iterator it = newDT->finite_vertices_begin(); it != newDT->finite_vertices_end(); ++it ) {

		switch ( it->info().flag ) {

			case AIR | DIRT | ROCK | MORE_ROCK:

				// border
			case AIR | DIRT | ROCK:

				// border

			case AIR | DIRT | MORE_ROCK:

				// border

			case AIR | ROCK | MORE_ROCK:

				// border

			case DIRT | ROCK | MORE_ROCK:

				// border

			case AIR | ROCK:

				// border

			case AIR | DIRT:

				// border

			case AIR | MORE_ROCK:

				// border

			case ROCK | DIRT:

				// border

			case DIRT | MORE_ROCK:

				// border

			case ROCK | MORE_ROCK:

				// border

				it->info().kill = BORDER;
				break;

			default:

				it->info().kill = FLOATER;
		}
	}

	int n;

	// Accumulate face normals for border faces
	for ( Cell_iterator it = newDT->finite_cells_begin(); it != newDT->finite_cells_end(); ++it ) {

		if ( it->info() != AIR ) {

			for ( n = 0; n < 4; ++n ) {

				if ( it->neighbor( n )->info() < it->info() || newDT->is_infinite( it->neighbor( n ) ) ) {

					Point t0 = it->vertex( n ^ 1 )->point();
					Vector s1 = it->vertex( n ^ 2 )->point() - t0;
					Vector s2 = it->vertex( n ^ 3 )->point() - t0;
					Vector norm = CGAL::cross_product( s1, s2 );

					for ( i = 1; i < 4; ++i ) {

						it->vertex( n ^ i )->info().normal = it->vertex( n ^ i )->info().normal + norm;
					}
				}
			}
		}
	}

	// Normalize the normals
	for ( Vertex_iterator it = newDT->finite_vertices_begin(); it != newDT->finite_vertices_end(); ++it ) {

		if ( it->info().kill != FLOATER ) {

			it->info().normal = it->info().normal / sqrt( it->info().normal.squared_length() );
		}
	}

	// Accumulate the edge curvatures and find range of edge lengths for future stepsize and vertex importance
	minEdgeLength = -1.0e300;
	int j;
	Vector e;
	double elen2;
	double curveMult;
	double importanceMult;
	double n_dot_e;

	for ( Cell_iterator it = newDT->finite_cells_begin(); it != newDT->finite_cells_end(); ++it ) {

		if ( it->info() != AIR ) {

			for ( n = 0; n < 4; ++n ) {

				if ( it->neighbor( n )->info() < it->info() || newDT->is_infinite( it->neighbor( n ) ) ) {

					for ( i = 1; i < 4; ++i ) {

						for ( j = i + 1; j < 4; ++j ) {

							e = it->vertex( n ^ i )->point() - it->vertex( n ^ j )->point();
							elen2 = e.squared_length();
							SETMAX( minEdgeLength, -elen2 );
							curveMult = 1.0 / elen2;
							importanceMult = sqrt( curveMult ); // Geometric importance is edge-length independent
							n_dot_e = dot( it->vertex( n ^ i )->info().normal, e );
							it->vertex( n ^ i )->info().numEdges += 1;
							it->vertex( n ^ i )->info().curvature += 2.0 * n_dot_e * curveMult;
							SETMAX( it->vertex( n ^ i )->info().importance, fabs( n_dot_e * importanceMult ) );
						}
					}
				}
			}
		}
	}

	minEdgeLength = sqrt( -minEdgeLength );
	minCurvature = -1.0e300;
	maxCurvature = -1.0e300;

	for ( Vertex_iterator it = newDT->finite_vertices_begin(); it != newDT->finite_vertices_end(); ++it ) {

		if ( it->info().numEdges > 0 ) {

			it->info().curvature /= it->info().numEdges;
			SETMAX( minCurvature, -it->info().curvature );
			SETMAX( maxCurvature, +it->info().curvature );
		}
	}

	// Colorize the vertices
	//for ( Vertex_iterator it = newDT->finite_vertices_begin(); it != newDT->finite_vertices_end(); ++it ) {

	//	it->info().rgb[ 0 ] = 0.0;
	//	it->info().rgb[ 1 ] = 0.0;
	//	it->info().rgb[ 2 ] = 0.0;

	//	if ( it->info().flag & ROCK ) {

	//		it->info().rgb[ 2 ] = 1.0;
	//	}

	//	if ( it->info().flag & MORE_ROCK ) {

	//		it->info().rgb[ 0 ] = 1.0;
	//	}
	//}

	minCurvature *= -1.0;
}
Ejemplo n.º 10
0
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);	

}
Ejemplo n.º 11
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);	

}
Ejemplo n.º 12
0
// TODO: fixing after quantization the potentially introduced degeneracies, such as removing the null surface facet
void Various_Processing_Component::CoordinateQuantization (PolyhedronPtr pMesh, int bitDepth)
{
	Vertex_iterator	pVertex;
	double quantizationLevel = std::pow(2.0,bitDepth);
	pVertex = pMesh->vertices_begin();
	Point3d point = pVertex->point();
	double xmax = double(point.x());
	double xmin = xmax;
	double ymax = double(point.y());
	double ymin = ymax;
	double zmax = double(point.z());
	double zmin = zmax;
	pVertex++;

	for (; pVertex != pMesh->vertices_end(); pVertex++)
	{
		point = pVertex->point();
		double x = double(point.x());
		double y = double(point.y());
		double z = double(point.z());
		if (x>xmax)
			xmax = x;
		if (x<xmin)
			xmin = x;
		if (y>ymax)
			ymax = y;
		if (y<ymin)
			ymin = y;
		if (z>zmax)
			zmax = z;
		if (z<zmin)
			zmin = z;
	}

	double xstep = (xmax-xmin)/quantizationLevel;
	double ystep = (ymax-ymin)/quantizationLevel;
	double zstep = (zmax-zmin)/quantizationLevel;

	for (pVertex = pMesh->vertices_begin(); pVertex != pMesh->vertices_end();pVertex++)
	{
		point = pVertex->point();
		double x = double(point.x());
		double y = double(point.y());
		double z = double(point.z());

		double xquantified, yquantified, zquantified;

		double xint = 1.0*std::floor((x-xmin)/xstep)*xstep + xmin;
		double xfrac = x - xint;
		if (xfrac<=(0.5*xstep))
			xquantified = xint;
		else
			xquantified = xint + xstep;

		double yint = 1.0*std::floor((y-ymin)/ystep)*ystep + ymin;
		double yfrac = y - yint;
		if (yfrac<=(0.5*ystep))
			yquantified = yint;
		else
			yquantified = yint +ystep;

		double zint = 1.0*std::floor((z-zmin)/zstep)*zstep + zmin;
		double zfrac = z - zint;
		if (zfrac<=(0.5*zstep))
			zquantified = zint;
		else
			zquantified = zint + zstep;

		pVertex->point() = Point3d(xquantified,yquantified,zquantified);
	}

	pMesh->compute_normals();
}
Ejemplo n.º 13
0
// 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;
}