コード例 #1
0
void ComputeGaussCurvature(Polyhedron::Vertex_iterator v1)
{
  double theta(0.0);
  Point3d p1 = v1->point();
  Point3d p2,p3;
  Vector3d v12, v13;
  Polyhedron::Halfedge_around_vertex_circulator first, curr, next;
  first = curr = v1->vertex_begin();
  do
  {
    next = curr;
    next++;

    p2 = curr->opposite()->vertex()->point();
    p3 = next->opposite()->vertex()->point();

    v12 = p2-p1;
    v13 = p3-p1;

    theta += std::acos( dot(v12,v13) / (norm(v12)*norm(v13)) );
  }
  while(++curr!=first);

  v1->set_gauss_curvature(2.0*M_PI - theta);
}
コード例 #2
0
ファイル: _polyhedra_utils.cpp プロジェクト: Mikelian/trunk
//**********************************************************************************
//returns min coordinates
Vector3r MinCoord(const shared_ptr<Shape>& cm1,const State& state1){
	const Se3r& se3=state1.se3; 
	Polyhedra* A = static_cast<Polyhedra*>(cm1.get());

	//move and rotate CGAL structure Polyhedron
	Matrix3r rot_mat = (se3.orientation).toRotationMatrix();
	Vector3r trans_vec = se3.position;
	Transformation t_rot_trans(rot_mat(0,0),rot_mat(0,1),rot_mat(0,2), trans_vec[0],rot_mat(1,0),rot_mat(1,1),rot_mat(1,2),trans_vec[1],rot_mat(2,0),rot_mat(2,1),rot_mat(2,2),trans_vec[2],1.);
	Polyhedron PA = A->GetPolyhedron();
	std::transform( PA.points_begin(), PA.points_end(), PA.points_begin(), t_rot_trans);
	
	Vector3r minccord = trans_vec;
	for(Polyhedron::Vertex_iterator vi = PA.vertices_begin(); vi != PA.vertices_end(); ++vi){	
		if (vi->point()[0]<minccord[0]) minccord[0]=vi->point()[0];
		if (vi->point()[1]<minccord[1]) minccord[1]=vi->point()[1];
		if (vi->point()[2]<minccord[2]) minccord[2]=vi->point()[2];
	}
	
	return minccord;
}
コード例 #3
0
Polyhedron::Halfedge_iterator GetHalfedge(Polyhedron::Vertex_iterator a, Polyhedron::Vertex_iterator b)
{
  Polyhedron::Halfedge_around_vertex_circulator first, curr;
  first = curr = b->vertex_begin();
  do
  {
    if(a == curr->opposite()->vertex())
      return curr;
  }
  while(++curr!=first);

  throw std::runtime_error("[Polyhedron::GetHalfedge] Error, a is not connected to b.");
}
コード例 #4
0
void Polyhedron_demo_jet_fitting_plugin::on_actionEstimateCurvature_triggered()
{
  // get active polyhedron
  const Scene_interface::Item_id index = scene->mainSelectionIndex();
  Scene_polyhedron_item* poly_item = 
    qobject_cast<Scene_polyhedron_item*>(scene->item(index));
  if(!poly_item)
    return;

  // wait cursor
  QApplication::setOverrideCursor(Qt::WaitCursor);

  Polyhedron* pMesh = poly_item->polyhedron();

  // types
  typedef CGAL::Monge_via_jet_fitting<Kernel> Fitting;
  typedef Fitting::Monge_form Monge_form;

  typedef Kernel::Point_3 Point;

  Scene_polylines_item* max_curv = new Scene_polylines_item;
  max_curv->setColor(Qt::red);
  max_curv->setName(tr("%1 (max curvatures)").arg(poly_item->name()));
  Scene_polylines_item* min_curv = new Scene_polylines_item;
  min_curv->setColor(Qt::green);
  min_curv->setName(tr("%1 (min curvatures)").arg(poly_item->name()));

  Polyhedron::Vertex_iterator v;
  for(v = pMesh->vertices_begin();
      v != pMesh->vertices_end();
      v++)
  {
    std::vector<Point> points;

    // pick central point
    const Point& central_point = v->point();
    points.push_back(central_point);

    // compute min edge len around central vertex
    // to scale the ribbons used to display the directions

    typedef Kernel::FT FT;

    FT min_edge_len = std::numeric_limits<FT>::infinity();
    Polyhedron::Halfedge_around_vertex_circulator he = v->vertex_begin();
    Polyhedron::Halfedge_around_vertex_circulator end = he;
    CGAL_For_all(he,end)
    {
      const Point& p = he->opposite()->vertex()->point();
      points.push_back(p);
      FT edge_len = std::sqrt(CGAL::squared_distance(central_point,p));
      min_edge_len = edge_len < min_edge_len ? edge_len : min_edge_len; // avoids #undef min
    }

    if(points.size() > 5)
    {
      // estimate curvature by fitting
      Fitting monge_fit;
      const int dim_monge = 2;
      const int dim_fitting = 2;
      Monge_form monge_form = monge_fit(points.begin(),points.end(),dim_fitting,dim_monge);

      // make monge form comply with vertex normal (to get correct
      // orientation)
      typedef Kernel::Vector_3 Vector;
      Vector n = CGAL::Polygon_mesh_processing::compute_vertex_normal(v, *pMesh);
      monge_form.comply_wrt_given_normal(n);

      Vector umin = min_edge_len * monge_form.minimal_principal_direction();
      Vector umax = min_edge_len * monge_form.maximal_principal_direction();

      Scene_polylines_item::Polyline max_segment(2), min_segment(2);

      const double du = 0.2;

      max_segment[0] = central_point + du * umax;
      max_segment[1] = central_point - du * umax;
      min_segment[0] = central_point + du * umin;
      min_segment[1] = central_point - du * umin;

      max_curv->polylines.push_back(max_segment);
      min_curv->polylines.push_back(min_segment);
    }
  }

  scene->addItem(max_curv);
  scene->addItem(min_curv);
  max_curv->changed();
  min_curv->changed();
  
  // default cursor
  QApplication::restoreOverrideCursor();
}
コード例 #5
0
// a helper method for running different iterators
void running_iterators( Polyhedron& P) {
    if ( P.size_of_facets() == 0)
        return;

    std::size_t nv = P.size_of_vertices();

    std::cout << "The number of vertices in the Polyhedron: " << nv << std::endl;
    std::cout << "The number of facets in the Polyhedron: " << P.size_of_facets() << std::endl;
    std::cout << "The number of half edges in the Polyhedron: " << P.size_of_halfedges() << std::endl;

    std::cout << std:: endl;

    Polyhedron::Vertex_iterator last_v = P.vertices_end();
    -- last_v;  // the last of the old vertices

    Polyhedron::Edge_iterator last_e = P.edges_end();
    -- last_e;  // the last of the old edges

    Polyhedron::Facet_iterator last_f = P.facets_end();
    -- last_f;  // the last of the old facets

    int k = 0;
    Polyhedron::Facet_iterator f = P.facets_begin();

    do {
    	std::cout << "Printing a facet index: " << k++ <<  std::endl;

    	f->halfedge();

    } while ( f++ != last_f);

    std::cout  << std::endl;

    // -------------------------------------------------
    // traverse the vertices
    // -------------------------------------------------

    std::cout << "Printing the vertex indices: " << std::endl;

     int n=0;
     for (Polyhedron::Vertex_iterator vi = P.vertices_begin(); vi != P.vertices_end(); ++vi)
     {
    	 Kernel::Point_3 p;
    	 p = vi->point();
    	 std::cout << "Vertex index: "  << n++ << std::endl;
    	 std::cout << "p.x() = "  << p.x() << std::endl;
    	 std::cout << "p.y() = "  << p.y() << std::endl;
    	 std::cout << "p.z() = "  << p.z() << std::endl;

     }

     std::cout  << std::endl;

     // -------------------------------------------------
     // traverse the edges
     // -------------------------------------------------

     std::cout << "Iterating over the edges.... " << std::endl;

     n=0;
     for (Polyhedron::Edge_iterator ei = P.edges_begin(); ei != P.edges_end(); ++ei)
     {
    	 ei->next();
    	 Kernel::Point_3 p;
    	 p =  ei->vertex()->point();
    	 std::cout << "For edge index: " << n++ << std::endl;
    	 std::cout << "p.x() = "  << p.x() << std::endl;
		 std::cout << "p.y() = "  << p.y() << std::endl;
		 std::cout << "p.z() = "  << p.z() << std::endl;

     }
     std::cout  << std::endl;

	 // -----------------------------------------------
	 // Do something else with the edge iterators
	 // -----------------------------------------------

    Polyhedron::Edge_iterator e = P.edges_begin();
    ++ last_e; // make it the past-the-end position again

    while ( e != last_e) {
    	Polyhedron::Halfedge_handle h = e;
        ++e;
    };

    CGAL_postcondition( P.is_valid());
}
コード例 #6
0
ファイル: Polyhedra.cpp プロジェクト: Mikelian/trunk
void Polyhedra::Initialize(){

	if (init) return;

	bool isRandom = false;
	
	//get vertices
	int N = (int) v.size();	
	if (N==0) {
		//generate randomly
		while ((int) v.size()<4) GenerateRandomGeometry();
		N = (int) v.size();
		isRandom = true;
	}

	//compute convex hull of vertices	
	std::vector<CGALpoint> points;
	points.resize(v.size());
	for(int i=0;i<N;i++) {
		points[i] = CGALpoint(v[i][0],v[i][1],v[i][2]);
	}

	CGAL::convex_hull_3(points.begin(), points.end(), P);
	
	//connect triagular facets if possible
	std::transform(P.facets_begin(), P.facets_end(), P.planes_begin(),Plane_equation());
	P = Simplify(P, 1E-9);

	//modify order of v according to CGAl polyhedron 
	int i = 0;
	v.clear();
	for (Polyhedron::Vertex_iterator vIter = P.vertices_begin(); vIter != P.vertices_end(); ++vIter, i++){
		v.push_back(Vector3r(vIter->point().x(),vIter->point().y(),vIter->point().z()));
	}	

	//list surface triangles for plotting
	faceTri.clear();
	std::transform(P.facets_begin(), P.facets_end(), P.planes_begin(),Plane_equation());
	for (Polyhedron::Facet_iterator fIter = P.facets_begin(); fIter != P.facets_end(); fIter++){
		Polyhedron::Halfedge_around_facet_circulator hfc0;
		int n = fIter->facet_degree();
		hfc0 = fIter->facet_begin();		
		int a = std::distance(P.vertices_begin(), hfc0->vertex());
		for (int i=2; i<n; i++){
			++hfc0;
			faceTri.push_back(a);
			faceTri.push_back(std::distance(P.vertices_begin(), hfc0->vertex()));
			faceTri.push_back(std::distance(P.vertices_begin(), hfc0->next()->vertex()));
		}
	}

	//compute centroid and volume
	P_volume_centroid(P, &volume, &centroid);
	//check vierd behavior of CGAL in tessalation
	if(isRandom && volume*1.75<4./3.*3.14*size[0]/2.*size[1]/2.*size[2]/2.) {
		v.clear();
		seed = rand();
		Initialize();
	}
        Vector3r translation((-1)*centroid);
	
	//set centroid to be [0,0,0]
	for(int i=0;i<N;i++) {
		v[i] = v[i]-centroid;
	}
	if(isRandom) centroid = Vector3r::Zero();

	Vector3r origin(0,0,0);

	//move and rotate also the CGAL structure Polyhedron
	Transformation t_trans(1.,0.,0.,translation[0],0.,1.,0.,translation[1],0.,0.,1.,translation[2],1.);		
	std::transform( P.points_begin(), P.points_end(), P.points_begin(), t_trans);	

	//compute inertia	
	Real vtet;
	Vector3r ctet;
	Matrix3r Itet1, Itet2;
	Matrix3r inertia_tensor(Matrix3r::Zero());
	for(int i=0; i<(int) faceTri.size(); i+=3){
		vtet = std::abs((origin-v[faceTri[i+2]]).dot((v[faceTri[i]]-v[faceTri[i+2]]).cross(v[faceTri[i+1]]-v[faceTri[i+2]]))/6.);		
		ctet = (origin+v[faceTri[i]]+v[faceTri[i+1]]+v[faceTri[i+2]]) / 4.;
		Itet1 = TetraInertiaTensor(origin-ctet, v[faceTri[i]]-ctet, v[faceTri[i+1]]-ctet, v[faceTri[i+2]]-ctet);
		ctet = ctet-origin;
		Itet2<<
			ctet[1]*ctet[1]+ctet[2]*ctet[2], -ctet[0]*ctet[1], -ctet[0]*ctet[2],
			-ctet[0]*ctet[1], ctet[0]*ctet[0]+ctet[2]*ctet[2], -ctet[2]*ctet[1],
			-ctet[0]*ctet[2], -ctet[2]*ctet[1], ctet[1]*ctet[1]+ctet[0]*ctet[0];
		inertia_tensor = inertia_tensor + Itet1 + Itet2*vtet; 
	}	

	if(std::abs(inertia_tensor(0,1))+std::abs(inertia_tensor(0,2))+std::abs(inertia_tensor(1,2)) < 1E-13){
		// no need to rotate, inertia already diagonal
		orientation = Quaternionr::Identity();
		inertia = Vector3r(inertia_tensor(0,0),inertia_tensor(1,1),inertia_tensor(2,2));
	}else{
		// calculate eigenvectors of I
		Vector3r rot;
		Matrix3r I_rot(Matrix3r::Zero()), I_new(Matrix3r::Zero()); 
		matrixEigenDecomposition(inertia_tensor,I_rot,I_new);
		// I_rot = eigenvectors of inertia_tensors in columns
		// I_new = eigenvalues on diagonal
		// set positove direction of vectors - otherwise reloading does not work
		Matrix3r sign(Matrix3r::Zero()); 
		Real max_v_signed = I_rot(0,0);
		Real max_v = std::abs(I_rot(0,0));
		if (max_v < std::abs(I_rot(1,0))) {max_v_signed = I_rot(1,0); max_v = std::abs(I_rot(1,0));} 
		if (max_v < std::abs(I_rot(2,0))) {max_v_signed = I_rot(2,0); max_v = std::abs(I_rot(2,0));} 
		sign(0,0) = max_v_signed/max_v;
		max_v_signed = I_rot(0,1);
		max_v = std::abs(I_rot(0,1));
		if (max_v < std::abs(I_rot(1,1))) {max_v_signed = I_rot(1,1); max_v = std::abs(I_rot(1,1));} 
		if (max_v < std::abs(I_rot(2,1))) {max_v_signed = I_rot(2,1); max_v = std::abs(I_rot(2,1));} 
		sign(1,1) = max_v_signed/max_v;
		sign(2,2) = 1.;
		I_rot = I_rot*sign;
		// force the eigenvectors to be right-hand oriented
		Vector3r third = (I_rot.col(0)).cross(I_rot.col(1));
		I_rot(0,2) = third[0];
		I_rot(1,2) = third[1];
		I_rot(2,2) = third[2];	
		
					
		inertia = Vector3r(I_new(0,0),I_new(1,1),I_new(2,2));
		orientation = Quaternionr(I_rot); 
		//rotate the voronoi cell so that x - is maximal inertia axis and z - is minimal inertia axis
		//orientation.normalize();  //not needed
		for(int i=0; i< (int) v.size();i++) {
			v[i] =  orientation.conjugate()*v[i];
		}
			
		//rotate also the CGAL structure Polyhedron
		Matrix3r rot_mat = (orientation.conjugate()).toRotationMatrix();
		Transformation t_rot(rot_mat(0,0),rot_mat(0,1),rot_mat(0,2),rot_mat(1,0),rot_mat(1,1),rot_mat(1,2),rot_mat(2,0),rot_mat(2,1),rot_mat(2,2),1.);	
		std::transform( P.points_begin(), P.points_end(), P.points_begin(), t_rot);

	}
	//initialization done
	init = 1;
}
コード例 #7
0
ファイル: _polyhedra_utils.cpp プロジェクト: Mikelian/trunk
//**********************************************************************************
//generate "packing" of non-overlapping balls
vector<Vector3r> fillBoxByBalls_cpp(Vector3r minCoord, Vector3r maxCoord, Vector3r sizemin, Vector3r sizemax, Vector3r ratio, int seed, shared_ptr<Material> mat, int NumPoints){	
	vector<Vector3r> v;
	Polyhedra trialP;
	Polyhedron trial, trial_moved;
	srand(seed);
	int it = 0;
	vector<Polyhedron> polyhedrons;
	vector<vector<Vector3r> > vv;
	Vector3r position;
	bool intersection;
	int count = 0;
	Vector3r radii;

	
	bool fixed_ratio = 0;
	if (ratio[0] > 0 && ratio[1] > 0 && ratio[2]>0){
		fixed_ratio = 1;
		sizemax[0] = min(min(sizemax[0]/ratio[0],  sizemax[1]/ratio[1]),  sizemax[2]/ratio[2]);
		sizemin[0] = max(max(sizemin[0]/ratio[0],  sizemin[1]/ratio[1]),  sizemin[2]/ratio[2]);
	}

	fixed_ratio = 1; //force spherical

	//it - number of trials to make packing possibly more/less dense
	Vector3r random_size;
	while (it<1000){
		it = it+1;
		if (it == 1){	
			if (fixed_ratio) {
				double rrr = (rand()*(sizemax[0]-sizemin[0])/RAND_MAX + sizemin[0])/2.;
				radii = Vector3r(rrr,rrr,rrr);
			}else  {
				radii = Vector3r(rand()*(sizemax[0]-sizemin[0])/2.,rand()*(sizemax[1]-sizemin[1])/2.,rand()*(sizemax[2]-sizemin[2])/2.)/RAND_MAX + sizemin/2.;
			}				
			trialP.v = BallPoints(radii,NumPoints,rand());
			trialP.Initialize();
			trial = trialP.GetPolyhedron();	
			Matrix3r rot_mat = (trialP.GetOri()).toRotationMatrix();
			Transformation t_rot(rot_mat(0,0),rot_mat(0,1),rot_mat(0,2),rot_mat(1,0),rot_mat(1,1),rot_mat(1,2),rot_mat(2,0),rot_mat(2,1),rot_mat(2,2),1.);	
			std::transform( trial.points_begin(), trial.points_end(), trial.points_begin(), t_rot);			
		}		
		position = Vector3r(rand()*(maxCoord[0]-minCoord[0]),rand()*(maxCoord[1]-minCoord[1]),rand()*(maxCoord[2]-minCoord[2]))/RAND_MAX + minCoord;

		//move CGAL structure Polyhedron
		Transformation transl(CGAL::TRANSLATION, ToCGALVector(position));
		trial_moved = trial;		
		std::transform( trial_moved.points_begin(), trial_moved.points_end(), trial_moved.points_begin(), transl);
		//calculate plane equations
		std::transform( trial_moved.facets_begin(), trial_moved.facets_end(), trial_moved.planes_begin(),Plane_equation());	

		intersection = false;	
		//call test with boundary
		for(Polyhedron::Vertex_iterator vi = trial_moved.vertices_begin(); (vi !=  trial_moved.vertices_end()) && (!intersection); vi++){
			intersection = (vi->point().x()<minCoord[0]) || (vi->point().x()>maxCoord[0]) || (vi->point().y()<minCoord[1]) || (vi->point().y()>maxCoord[1]) || (vi->point().z()<minCoord[2]) || (vi->point().z()>maxCoord[2]);
		}
		//call test with other polyhedrons	
		for(vector<Polyhedron>::iterator a = polyhedrons.begin(); (a != polyhedrons.end()) && (!intersection); a++){	
			intersection = do_intersect(*a,trial_moved);
		        if (intersection) break;
		}
		if (!intersection){
			polyhedrons.push_back(trial_moved);
			v.clear();
			for(Polyhedron::Vertex_iterator vi = trial_moved.vertices_begin(); vi !=  trial_moved.vertices_end(); vi++){
				v.push_back(FromCGALPoint(vi->point()));
			}
			vv.push_back(v);
			it = 0;
			count ++;

		}
	}
	cout << "generated " << count << " polyhedrons"<< endl;

	//can't be used - no information about material
	Scene* scene=Omega::instance().getScene().get();
	for(vector<vector<Vector3r> >::iterator p=vv.begin(); p!=vv.end(); ++p){
		shared_ptr<Body> BP = NewPolyhedra(*p, mat);
		BP->shape->color = Vector3r(double(rand())/RAND_MAX,double(rand())/RAND_MAX,double(rand())/RAND_MAX);
		scene->bodies->insert(BP);
	}
	return v;
}