예제 #1
0
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();
}
예제 #2
0
void Remesh::selectClosest_tmp() { 
	int i=0;
	FILE *select = fopen("select.dat", "w");
	Vertex_handle vdst;	
	for (Vertex_iterator vi = dst_mesh.p.vertices_begin(); vi != dst_mesh.p.vertices_end(); vi++) {
	vi->id = -1;
	}

	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 << i << ": " << vi->point() << " closest to " << closest_point << endl; 
		if(v_norm(closest_point - vi->point()) < dst_mesh.edge_avg*alg_smoothing) {
			vdst = dst_mesh.vertex_mapping[closest_point]; 
			cerr << "whose id is " << vdst->id; 
			vdst->weight = 2;
			vdst->id = i; 
			cerr << " changed to " << vdst->id << endl;
		} i++;
	}
	i=0;
	for (Vertex_iterator vi = dst_mesh.p.vertices_begin(); vi != dst_mesh.p.vertices_end(); vi++) {
		if(vi->weight == 2) {
			fprintf(select, "%d\t%d\n", i,vi->id);
		}
		i++;
	}
	fclose(select);
	cerr << "Done with printing out stuff ! Exiting " << endl;
	exit(0);
}
예제 #3
0
  void CGALPolyhedronToVTKPolydata_converter(Polyhedron *polyhedron, vtkSmartPointer<vtkPolyData> polydata)
  {
	  //convert from cgal polyhedron to vtk poly data
	  //first the points
	  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
	  vtkSmartPointer<vtkCellArray> faces = vtkSmartPointer<vtkCellArray>::New();

	  //iterator over all vertices in  polyhedron, add them as points
	  std::map<Vertex_handle, vtkIdType> V;
	  vtkIdType inum = 0;
	  for ( Vertex_iterator v = polyhedron->vertices_begin(); v != polyhedron->vertices_end(); ++v)
	  {
		   points->InsertNextPoint(v->point()[0],v->point()[1],v->point()[2]);
		   V[v] = inum++;
	  }
	  //now iterate over all faces in polyhedron
	  for ( Facet_iterator i = polyhedron->facets_begin(); i != polyhedron->facets_end(); ++i)
	  {
		  Halfedge_around_facet_circulator j = i->facet_begin();
		  faces->InsertNextCell(CGAL::circulator_size(j));
		  do
		  {
			  //get indice of vertex, insert new cell point into faces
			  faces->InsertCellPoint(V[j->vertex()]);

		  } while(++j != i->facet_begin());
	  }

	  // Set the points and faces of the polydata
	  polydata->SetPoints(points);
	  polydata->SetPolys(faces);
  }
예제 #4
0
void transformMesh( Polyhedron & poly, Transformation3 & map )
{
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	Point3 store = vi->point().transform( map );
	vi->point() = store;
    }
}
예제 #5
0
파일: Mesh.cpp 프로젝트: shooshx/kawaiigl
void Mesh::compute_bounding_box()
{
	if (size_of_vertices()	== 0)
		return;

	float xmin, xmax, ymin, ymax, zmin, zmax;

	Vertex_iterator	pVertex	=	vertices_begin();
	xmin = xmax = pVertex->point().x;
	ymin = ymax = pVertex->point().y;
	zmin = zmax = pVertex->point().z;
	for(;pVertex !=	vertices_end();pVertex++)
	{
		const Vec3& p = pVertex->point();
		xmin	=	qMin(xmin,p.x);
		ymin	=	qMin(ymin,p.y);
		zmin	=	qMin(zmin,p.z);
		xmax	=	qMax(xmax,p.x);
		ymax	=	qMax(ymax,p.y);
		zmax	=	qMax(zmax,p.z);
	}

	m_min = Vec3(xmin, ymin, zmin);
	m_max = Vec3(xmax, ymax, zmax);
	m_diagLength = Vec3::distance(m_min, m_max);
	m_axisLength = Vec3(m_min, m_max);
	m_minMaxCenter = (m_min + m_max) / 2.0f;
}
예제 #6
0
void smoothMesh( Polyhedron & poly, unsigned int nTimes )
{
    int nV = poly.size_of_vertices();
    const double lambda = SMOOTHING_LAMBDA;
    const double mu	= SMOOTHING_MU;

    vector< Point3 > shrink  ( nV );
    vector< Point3 > expand  ( nV );

    for ( unsigned int k = 0; k < nTimes; ++k ) {
	// copy the vertex coordinates
	for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	    shrink  [ vi->id() ] = vi->point();
	}
	// shrinking stage
	for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	    moveVertex( vi, shrink[ vi->id() ], lambda );
	}
	// copy back the vertex coordinates
	for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	    vi->point()		= shrink[ vi->id() ];
	    expand[ vi->id() ]	= shrink[ vi->id() ];
	}
	// expanding stage
	for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	    moveVertex( vi, expand[ vi->id() ], mu );
	}
	// copy back the vertex coordinates
	for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	    vi->point()		= expand[ vi->id() ];
	}
    }
}
예제 #7
0
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();
}
예제 #8
0
	void MSDM2_Component::ConstructColorMap(PolyhedronPtr P, int MetricOrHausdorff)
	{
		if(MetricOrHausdorff==1)
		{
			if(P->IsDistanceComputed==true)
			{

				double R;
				int indiceLut;
				Vertex_iterator pVertex = NULL;

				if(MaxMSDM2>MinMSDM2)
				{
				  for (pVertex = P->vertices_begin();
					  pVertex != P->vertices_end();
					  pVertex++)
				  {

					
						R=(pVertex->MSDM2_Local-MinMSDM2)/(MaxMSDM2-MinMSDM2)*255;
					
						indiceLut=floor(R);
						pVertex->color(LUT_CourbureClust[3*indiceLut],LUT_CourbureClust[3*indiceLut+1],LUT_CourbureClust[3*indiceLut+2]);

				  }
				}
			}
		}
		else
		{
			if(P->IsDistanceComputed==true)
			{

				double R;
				int indiceLut;
				Vertex_iterator pVertex = NULL;

				if(MaxMSDM2>MinMSDM2)
				{
				  for (pVertex = P->vertices_begin();
					  pVertex != P->vertices_end();
					  pVertex++)
				  {

						float d=sqrt((pVertex->point()-pVertex->match)*(pVertex->point()-pVertex->match));
						R=(d-MinMSDM2)/(MaxMSDM2-MinMSDM2)*255;
					
						indiceLut=floor(R);
						pVertex->color(LUT_CourbureClust[3*indiceLut],LUT_CourbureClust[3*indiceLut+1],LUT_CourbureClust[3*indiceLut+2]);

				  }
				}
			}

		}
	}
예제 #9
0
void DegradeAnObject::changeAllPoints() {
	for(std::vector<Polyhedron>::iterator P = polys.begin() ; P != polys.end() ; ++P) {
		for ( Vertex_iterator v = P->vertices_begin(); v != P->vertices_end(); ++v) {
			Point_3 p(v->point().x()+((double) rand() / (RAND_MAX)),v->point().y()+((double) rand() / (RAND_MAX)),v->point().z()+((double) rand() / (RAND_MAX)));
			v->point() = p;
			std::cout << v->point() << std::endl;
		}
		std::cout << "--" << std::endl;
	}
}
예제 #10
0
void MSDM2_Component::Matching_Multires_Init(PolyhedronPtr m_PolyDegrad, PolyhedronPtr m_PolyOriginal , Facet * _TabMatchedFacet)
	{
		
		 // constructs AABB tree
		 AABB_Tree tree(m_PolyOriginal->facets_begin(),m_PolyOriginal->facets_end());
		 tree.accelerate_distance_queries();

		//Searching for the closest point and facet for each vertex

		int ind=0;
		for(Vertex_iterator	pVertex	= m_PolyDegrad->vertices_begin();
					pVertex	!= m_PolyDegrad->vertices_end();
					pVertex++)
		{
			pVertex->MSDM2_Local=0;
			 // computes closest point and primitive id
			Point_and_primitive_id pp = tree.closest_point_and_primitive(pVertex->point());
			Point3d Nearest=pp.first;
			Facet_iterator f_Nearest = pp.second; // closest primitive id

			pVertex->match=Nearest;
			_TabMatchedFacet[ind]=*f_Nearest;

			ind++;

			
			
		}
		
}
/**
 * Gets the list of points from the mesh
 * @param points Stores the list of points
 */
void StoneWeatherer::getPoints( vector<Point> & points ) const {

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

		points.push_back( it->point() );
	}
}
예제 #12
0
파일: main.cpp 프로젝트: vivzqs/jjcao-code
void modify_vertex_position()
{
	Polyhedron P;
    Halfedge_handle h = P.make_tetrahedron();
    if ( P.is_tetrahedron(h))
	{
		int i(0);
		for(Vertex_iterator vi = P.vertices_begin(); vi != P.vertices_end(); ++vi,++i)
		{
		  std::cout << "before changing vertex " << i << ": " << vi->point().x() << vi->point().y() << vi->point().z() << endl;
		  Point_3 pt(1, 0, 0);
		  vi->point() = pt;
		  std::cout << "after changing vertex " << i << ": " << vi->point().x() << vi->point().y() << vi->point().z() << endl;
		}
	}
}
string Various_Tools_Component::printClickedVertices(PolyhedronPtr pMesh,double x,double y,int tolerance)
{
	GLdouble *model;GLdouble *proj;GLint *view;

	view = new GLint[4];
	proj = new GLdouble[16];
	model = new GLdouble[16];

	glGetIntegerv(GL_VIEWPORT,view);
	glGetDoublev(GL_MODELVIEW_MATRIX,model);
	glGetDoublev(GL_PROJECTION_MATRIX,proj);

	y = view[3] - y;

	GLdouble wx,wy,wz;
	char szInfoVertex[256];

	string sInfoVertex = "";
	int vertexID = 0;

	//VertexID + 4就是该顶点在.obj文件中的行数
	for(Vertex_iterator pVertex = pMesh->vertices_begin();pVertex != pMesh->vertices_end();pVertex++)
	{
		gluProject(pVertex->point().x(),pVertex->point().y
			(),pVertex->point().z(),model,proj,view,&wx,&wy,&wz);
		if (wz > 0.0 && wz < 1.0)
		{
			if (x > floor(wx)-tolerance && x < floor(wx)+tolerance)
			{
				if (y > floor(wy) - tolerance && y < floor(wy)+tolerance)
				{
					sprintf(szInfoVertex, "Vertex: %u  -  (%lf, %lf, %lf)", vertexID, pVertex->point().x(), pVertex->point().y(), pVertex->point().z());
					sInfoVertex.assign(szInfoVertex);
				}
			}
		}
		vertexID++;
	}

	delete [] view;
	delete [] model;
	delete [] proj;

	return sInfoVertex;
}
void mepp_component_Boolean_Operations_plugin::New_Position()
{
    QApplication::setOverrideCursor(Qt::WaitCursor);

    // active viewer
    if (mw->activeMdiChild() != 0)
    {
        float x, y, z;
        double a, b, c, w;
        Viewer* viewer = (Viewer *)mw->activeMdiChild();

        ScenePtr S = viewer->getScenePtr();

        for(int i = 0; i<viewer->getScenePtr()->get_nb_polyhedrons(); i++)
        {
            Vertex_iterator pVertex = NULL;

            PolyhedronPtr P = S->get_polyhedron(i);

            viewer->frame(i)->getPosition(x,y,z);
            viewer->frame(i)->getOrientation(a,b,c,w);

            Vec T(x, y, z);
            Quaternion Q(a, b, c, w);

            for (pVertex = P->vertices_begin(); pVertex != P->vertices_end(); pVertex++)
            {
                Vec V = Q * Vec(pVertex->point().x(), pVertex->point().y(), pVertex->point().z()) + T;
                pVertex->point() = CGAL::ORIGIN + Vector(V[0], V[1], V[2]);
            }

            viewer->frame(i)->setPosition(0,0,0);
            viewer->frame(i)->setOrientation(0,0,0,1);
        }
        viewer->show();
        viewer->recreateListsAndUpdateGL();
    }
    QApplication::restoreOverrideCursor();
}
예제 #15
0
	void MSDM2_Component::ComputeMaxMin(PolyhedronPtr P, int MetricOrHausdorff)
	{
		if(MetricOrHausdorff==1)
		{
			if(P->IsDistanceComputed==true)
			{
				MinMSDM2=1000;
				MaxMSDM2=0;
				for(Vertex_iterator	pVertex	=	P->vertices_begin();pVertex!= P->vertices_end();pVertex++)
				{
					if(pVertex->MSDM2_Local>MaxMSDM2)
						MaxMSDM2=pVertex->MSDM2_Local;
					if(pVertex->MSDM2_Local<MinMSDM2)
						MinMSDM2=pVertex->MSDM2_Local;

				}
			}
		}
		else
		{
			if(P->IsDistanceComputed==true)
			{
				MinMSDM2=1000;
				MaxMSDM2=0;
				for(Vertex_iterator	pVertex	=	P->vertices_begin();pVertex!= P->vertices_end();pVertex++)
				{
					float d=sqrt((pVertex->point()-pVertex->match)*(pVertex->point()-pVertex->match));
					if(d>MaxMSDM2)
						MaxMSDM2=d;
					if(d<MinMSDM2)
						MinMSDM2=d;

				}
			}

		}
	

	}
예제 #16
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 );
    }
}
예제 #17
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]));
    }
  }
예제 #18
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;
}
예제 #19
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
}
예제 #20
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;		


			

			
		}
		
}
예제 #21
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);	

}
예제 #22
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;
}
예제 #23
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);	

}
예제 #24
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();
}
/**
 * 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;
}
예제 #26
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);
					}

					

					
					
				}
                
			}
			
		}