예제 #1
0
// Add semantics to Interior room polyhedra
void set_semantic_InteriorLoD4(Polyhedron& polyhe) {
	std::transform( polyhe.facets_begin(), polyhe.facets_end(),polyhe.planes_begin(),Plane_Newel_equation());		
	for (Polyhedron::Facet_iterator fIt = polyhe.facets_begin(); fIt != polyhe.facets_end(); ++fIt) {	// Iterate over faces
		Kernel::FT z = fIt->plane().orthogonal_vector().z();
		if		(z <= -HORIZONTAL_ANGLE_RANGE)	fIt->semanticBLA = "FloorSurface";
		else if (z >=  HORIZONTAL_ANGLE_RANGE)	fIt->semanticBLA = "CeilingSurface";
		else									fIt->semanticBLA = "InteriorWallSurface";
}	}	
int main()
{
  std::list<Weighted_point> l;
  FT shrinkfactor = 0.5;

  l.push_front(Weighted_point(Bare_point(0, 0, 0), 1));
  l.push_front(Weighted_point(Bare_point(0, 1, 0), 2));
  l.push_front(Weighted_point(Bare_point(0, 0, 2), 1));

  Skin_surface_3 skin_surface(l.begin(), l.end(), shrinkfactor);

  Polyhedron p;
  CGAL::mesh_skin_surface_3(skin_surface, p);

  for (Polyhedron::Facet_iterator fit = p.facets_begin(); fit != p.facets_end(); ++fit) {

    // Retrieve the generating simplex from the regular triangulation
    const Skin_surface_3::Simplex &s = fit->containing_simplex();

    // Get the weighted points from the simplex
    Skin_surface_3::Weighted_point wp[4];
    switch (s.dimension()) {
    case 0: {
      Skin_surface_3::Vertex_handle vh = s;
      wp[0] = vh->point();
      break;
    }
    case 1: {
      Skin_surface_3::Edge e = s;
      wp[0] = e.first->vertex(e.second)->point();
      wp[1] = e.first->vertex(e.third)->point();
      break;
    }
    case 2: {
      Skin_surface_3::Facet f = s;
      wp[0] = f.first->vertex((f.second + 1) & 3)->point();
      wp[1] = f.first->vertex((f.second + 2) & 3)->point();
      wp[2] = f.first->vertex((f.second + 3) & 3)->point();
      break;
    }
    case 3: {
      Skin_surface_3::Cell_handle ch = s;
      wp[0] = ch->vertex(0)->point();
      wp[1] = ch->vertex(1)->point();
      wp[2] = ch->vertex(2)->point();
      wp[3] = ch->vertex(3)->point();
      break;
    }
    }
  }

  return 0;
}
예제 #3
0
// Remove small triangles with different semantics
void remove_singularSemantics(Polyhedron& exteriorPolyhe) {
	double SMALL_TRIANGLE_LIMIT = 0.1;
	Polyhedron::Facet_iterator exfIt;						// Iterate over exterior faces

	while (true) {
		bool newSemFound = false;
		for (exfIt = exteriorPolyhe.facets_begin(); exfIt != exteriorPolyhe.facets_end(); ++exfIt) {
			if (exfIt->area < SMALL_TRIANGLE_LIMIT) {
				std::map<std::string,double> semCountList;
				std::map<std::string,double>::iterator semCount;
				Polyhedron::Facet::Halfedge_around_facet_circulator itHDS = exfIt->facet_begin();

				double maxArea = 0;
				std::string newSem;
						
					do {
						if (is_coplanar(itHDS,false)) {
							std::string otherSem = itHDS->opposite()->facet()->semanticBLA;

							// Compute sum of area

							if (is_coplanar(itHDS->opposite()->next(),true) ||
								is_coplanar(itHDS->opposite()->prev(),true)) {
								semCount = semCountList.find(otherSem);
								if (semCount == semCountList.end())
									semCountList[otherSem] = 1; // Might not be needed
								else
									++(semCountList[otherSem]);
							}
						}
					} while (++itHDS != exfIt->facet_begin());
				
					for (semCount = semCountList.begin();semCount!=semCountList.end();++semCount) {
						if (semCount->second > maxArea) {
							maxArea = semCount->second;
							newSem = semCount->first;
						} else if (semCount->second == maxArea &&
							((exfIt->semanticBLA=="Anything"&&semCount->first!="Anything")||semCount->first==exfIt->semanticBLA))
							newSem = semCount->first;
					}
					
				if (maxArea > 0 && newSem!=exfIt->semanticBLA) {
					exfIt->semanticBLA = newSem;
					newSemFound = true;
					break;										// Dafuq? is this correct?
				}
			}
		}
		if (!newSemFound) break;								// Really?
	}
}
예제 #4
0
 double lloyd_step (std::vector<Point> &points)
 {
   std::vector<Plane> planes;
   for (size_t i = 0; i < points.size(); ++i)
     planes.push_back(tangent_plane(points[i]));

   Polyhedron P;

   CGAL::internal::halfspaces_intersection(planes.begin(),
					   planes.end(), P, K());

   size_t N = points.size();
   points.clear();
   double totarea = 0.0;
   double vararea = 0.0;

   for (Polyhedron::Facet_iterator it = P.facets_begin();
	it != P.facets_end(); ++it)
     {
       Polyhedron::Halfedge_around_facet_circulator
	 h0 = it->facet_begin(), hf = h0--, hs = hf;
       hs ++;

       double farea = 0.0;
       Vector fcentroid (CGAL::NULL_VECTOR);
       while(1)
	 {
	   const Point &a  = h0->vertex()->point(),
	     &b = hf->vertex()->point(),
	     &c = hs->vertex()->point();
	   Vector v = 
	     CGAL::cross_product(b -a, c - a);
	   double tarea = .5 * sqrt(v.squared_length());
	   farea += tarea;
	   fcentroid = fcentroid +  (tarea/3.0) * ((a - CGAL::ORIGIN) + 
						   (b - CGAL::ORIGIN) + 
						   (c - CGAL::ORIGIN));
	   if (hs == h0)
	     break;
	   ++hs; ++hf;
	 }
       totarea += farea;
       vararea += pow(4.0 * M_PI / N - farea, 2.0);
       fcentroid = fcentroid/farea;
       points.push_back(project_back(CGAL::ORIGIN + fcentroid));
     }
   std::cerr << "area = " << totarea << ", "
	     << "vararea = " << vararea << "\n";
   return vararea/totarea;
 }
예제 #5
0
파일: normals.cpp 프로젝트: lrineau/cgal
int main(int argc, char** argv)
{
  typedef boost::property_map< 
    Polyhedron,
    CGAL::face_index_t 
    >::const_type Face_index_map;

  std::ifstream in((argc>1)?argv[1]:"cube.off");
  Polyhedron P;
  in >> P ;
  
  // initialize facet indices
  std::size_t i = 0;
  for(Polyhedron::Facet_iterator it = P.facets_begin(); it != P.facets_end(); ++it, ++i) 
  {
    it->id() = i;
  }

  // Ad hoc property_map to store normals. Face_index_map is used to
  // map face_descriptors to a contiguous range of indices. See
  // http://www.boost.org/libs/property_map/doc/vector_property_map.html
  // for details.
  boost::vector_property_map<Vector, Face_index_map> 
    normals(get(CGAL::face_index, P));

  calculate_face_normals(
    P // Graph
    , get(CGAL::vertex_point, P) // map from vertex_descriptor to point
    , normals // map from face_descriptor to Vector_3
    );

  std::cout << "Normals" << std::endl;
  for(Polyhedron::Facet_iterator it = P.facets_begin(); it != P.facets_end(); ++it) { 
    // Facet_iterator is a face_descriptor, so we can use it as the
    // key here
    std::cout << normals[it] << std::endl;
  }

  return 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());
}
예제 #7
0
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;
}
예제 #8
0
void set_semantic_AABB_C2V(Polyhedron& exteriorPolyhe,PolVector& polyVec) {

	if (exteriorPolyhe.is_pure_triangle()) {
		std::transform( exteriorPolyhe.facets_begin(), exteriorPolyhe.facets_end(),exteriorPolyhe.planes_begin(),Plane_equation());
		std::vector<std::string>	semList;
		std::vector<std::shared_ptr<AAbbTree>>		treeList;

		// Build Trees. One for each semantic
		for(PolVector::iterator pvIt = polyVec.begin();pvIt!=polyVec.end();++pvIt) {// Get AABB trees of all semantics
			if (pvIt->is_pure_triangle()) {
				std::string semP = pvIt->facets_begin()->semanticBLA;
				std::vector<std::string>::iterator  strIt = std::find(semList.begin(), semList.end(),semP);
				if (strIt==semList.end()) {											// If new sematic
					semList.push_back(semP);										// Add sem
					std::shared_ptr<AAbbTree> tree = std::make_shared<AAbbTree>(pvIt->facets_begin(),pvIt->facets_end());		// Create tree
					tree->accelerate_distance_queries();							// accelerate
					treeList.push_back(tree);										// Add tree
				} else																					// If not new
					treeList[strIt-semList.begin()]->insert(pvIt->facets_begin(),pvIt->facets_end());	// Append to tree
			} else std::cerr << "ERROR: Not pure triangle (set_semantic_AABB2C2V)" << std::endl;
		}
		

		// For each facet calculate the least distance to each tree
		std::string semListStr = boost::algorithm::join((semList), " ");
		int percCount = 1;
		Polyhedron::Facet_iterator exfIt;						// Iterate over exterior faces
		for (exfIt = exteriorPolyhe.facets_begin(); exfIt != exteriorPolyhe.facets_end(); ++exfIt,++percCount) {	
			
			std::cout << "\r"<<semListStr<<". ("<<100*percCount/exteriorPolyhe.size_of_facets()<<"%)";

			Vector_3 orthVec = exfIt->plane().orthogonal_vector();
			normalizeVector(orthVec);	//if (!normalizeVector(ortVec)) continue;

			std::vector<distSemFace> dsfList(semList.size());										
			Point_3 centerPoint = comp_facetCentroid(exfIt);						// Compute centroid
			std::vector<Kernel::FT> leastSemDistances;
			for (int intIt=0;intIt<(int)treeList.size();++intIt) {					// Loop over all trees
				AAbbTree::Point_and_primitive_id pp = treeList[intIt]->closest_point_and_primitive(centerPoint);
				dsfList[intIt].dist	= CGAL::squared_distance(centerPoint,pp.first);	// Store distance semantic and facet for each tree
				dsfList[intIt].sem	= semList[intIt];
				dsfList[intIt].fh	= pp.second;
			}

			std::sort(dsfList.begin(),dsfList.end(),by_dist());

			exfIt->leastSqDistance = dsfList[0].dist;					// least sqrt distance
			if (exfIt->isMinkFacet = dsfList[0].dist > SEMANTIC_DISTANCE_THRESHOLD) {
				exfIt->semanticBLA = TO_DIST_SEMANTIC;						// Default semantic if too distant
				continue;
			} else
				exfIt->semanticBLA = dsfList[0].sem;					// Semantics of closest

			Vector_3 faceNormal;
			Kernel::FT faceSqArea;
			double minAngle = 10;
			Kernel::FT maxArea= 0;

			for (std::vector<distSemFace>::iterator slIt = dsfList.begin();slIt != dsfList.end();++slIt)// HANDLE ANYTHING AS LESS IMPORTANT
				if (slIt->dist < dsfList[0].dist+OVERLAP_DIST_THRESHOLD) {	// Check if Equidistant
					pointVector facetPoints = comp_facetPoints(exfIt);
					CGAL::normal_vector_newell_3(facetPoints.begin(),facetPoints.end(),faceNormal); // Calculate normal vector, ortVec set to zero in newell
					double angle = comp_angle(orthVec,faceNormal);
					if (angle!=-1 && angle < minAngle+OVERLAP_ANGLE_THRESHOLD) {
						if (minAngle >= angle+OVERLAP_ANGLE_THRESHOLD)		exfIt->equidistSems.clear();
						if (angle < minAngle)								minAngle = angle;
						faceSqArea = comp_facetSquaredArea(facetPoints);
						if (faceSqArea>maxArea-OVERLAP_AREA_THRESHOLD) {
							if (maxArea<=faceSqArea-OVERLAP_AREA_THRESHOLD)	exfIt->equidistSems.clear();
							if (faceSqArea>maxArea)							maxArea = faceSqArea;
							exfIt->equidistSems.push_back(slIt->sem);				// Add equidist semantics
						}
					}
				}
		}
		std::cout << "\r"<<semListStr<<". (100%)" << std::endl;
	}else std::cerr << "ERROR: Not pure triangle (set_semantic_AABB2C2V)" << std::endl;
}