Пример #1
0
//**********************************************************************************
//test of polyhedron intersection callable from python shell
bool do_Polyhedras_Intersect(const shared_ptr<Shape>& cm1,const shared_ptr<Shape>& cm2,const State& state1,const State& state2){

	const Se3r& se31=state1.se3; 
	const Se3r& se32=state2.se3;
	Polyhedra* A = static_cast<Polyhedra*>(cm1.get());		
	Polyhedra* B = static_cast<Polyhedra*>(cm2.get());

	//move and rotate 1st the CGAL structure Polyhedron
	Matrix3r rot_mat = (se31.orientation).toRotationMatrix();
	Vector3r trans_vec = se31.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);

	//move and rotate 2st the CGAL structure Polyhedron
	rot_mat = (se32.orientation).toRotationMatrix();
	trans_vec = se32.position;
	t_rot_trans = Transformation(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 PB = B->GetPolyhedron();
	std::transform( PB.points_begin(), PB.points_end(), PB.points_begin(), t_rot_trans);

	//calculate plane equations
	std::transform( PA.facets_begin(), PA.facets_end(), PA.planes_begin(),Plane_equation());
	std::transform( PB.facets_begin(), PB.facets_end(), PB.planes_begin(),Plane_equation());


	//call test
	return do_intersect(PA,PB);
}
Пример #2
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";
}	}	
Пример #3
0
bool is_weakly_convex(Polyhedron const& p) {
  for (typename Polyhedron::Edge_const_iterator i = p.edges_begin(); i != p.edges_end(); ++i) {
    typename Polyhedron::Plane_3 p(i->opposite()->vertex()->point(), i->vertex()->point(), i->next()->vertex()->point());
    if (p.has_on_positive_side(i->opposite()->next()->vertex()->point()) &&
        CGAL::squared_distance(p, i->opposite()->next()->vertex()->point()) > 1e-8) {
      return false;
    }
  }
  // Also make sure that there is only one shell:
  boost::unordered_set<typename Polyhedron::Facet_const_handle, typename CGAL::Handle_hash_function> visited;
  // c++11
  // visited.reserve(p.size_of_facets());
  
  std::queue<typename Polyhedron::Facet_const_handle> to_explore;
  to_explore.push(p.facets_begin()); // One arbitrary facet
  visited.insert(to_explore.front());
  
  while (!to_explore.empty()) {
    typename Polyhedron::Facet_const_handle f = to_explore.front();
    to_explore.pop();
    typename Polyhedron::Facet::Halfedge_around_facet_const_circulator he, end;
    end = he = f->facet_begin();
    CGAL_For_all(he,end) {
      typename Polyhedron::Facet_const_handle o = he->opposite()->facet();
      
      if (!visited.count(o)) {
        visited.insert(o);
        to_explore.push(o);
      }
    }
  }
Пример #4
0
void geometryUtils::subdivide(Polyhedron& P) {
    if (P.size_of_facets() == 0)
        return;
    // We use that new vertices/halfedges/facets are appended at the end.
    std::size_t nv = P.size_of_vertices();
    Vertex_iterator last_v = P.vertices_end();
    --last_v; // the last of the old vertices
    Edge_iterator last_e = P.edges_end();
    --last_e; // the last of the old edges
    Facet_iterator last_f = P.facets_end();
    --last_f; // the last of the old facets
    Facet_iterator f = P.facets_begin(); // create new center vertices
    do {
        geometryUtils::subdivide_create_center_vertex(P, f);
    } while (f++ != last_f);
    std::vector<Point_3> pts; // smooth the old vertices
    pts.reserve(nv); // get intermediate space for the new points
    ++last_v; // make it the past-the-end position again
    std::transform(P.vertices_begin(), last_v, std::back_inserter(pts),
            Smooth_old_vertex());
    std::copy(pts.begin(), pts.end(), P.points_begin());
    Edge_iterator e = P.edges_begin(); // flip the old edges
    ++last_e; // make it the past-the-end position again
    while (e != last_e) {
        Halfedge_handle h = e;
        ++e; // careful, incr. before flip since flip destroys current edge
        geometryUtils::subdivide_flip_edge(P, h);
    };
    CGAL_postcondition(P.is_valid());
};
Пример #5
0
polyhedron cgal_to_polyhedron( const Nef_polyhedron &NP ){
    Polyhedron P;
    polyhedron ret;
    
    if( NP.is_simple() ){
        NP.convert_to_polyhedron(P);
        std::vector<double> coords;
        std::vector<int> tris;
        int next_id = 0;
        std::map< Polyhedron::Vertex*, int > vid;
        for( Polyhedron::Vertex_iterator iter=P.vertices_begin(); iter!=P.vertices_end(); iter++ ){
            coords.push_back( CGAL::to_double( (*iter).point().x() ) );
            coords.push_back( CGAL::to_double( (*iter).point().y() ) );
            coords.push_back( CGAL::to_double( (*iter).point().z() ) );
            vid[ &(*iter) ] = next_id++;
        }
        
        for( Polyhedron::Facet_iterator iter=P.facets_begin(); iter!=P.facets_end(); iter++ ){
            Polyhedron::Halfedge_around_facet_circulator j = iter->facet_begin();
            tris.push_back( CGAL::circulator_size(j) );
            do {
                tris.push_back( std::distance(P.vertices_begin(), j->vertex()) );
            } while ( ++j != iter->facet_begin());
        }
        
        ret.initialize_load_from_mesh( coords, tris );
    } else {
        std::cout << "resulting polyhedron is not simple!" << std::endl;
    }
    return ret;
}
Пример #6
0
void renewAttrs( Polyhedron & poly )
{
    // assign IDs to vertices
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	vi->nCuts()	= 0;
    }

    // assign IDs to faces: the dual vertex and the dual coordinates-the center coordinates
    for ( Facet_iterator fi = poly.facets_begin(); fi != poly.facets_end(); ++fi ) {
	fi->piece()	= NO_INDEX;
	Vector3 sum( 0.0, 0.0, 0.0 );
	Halfedge_facet_circulator hfc = fi->facet_begin();
	do {
	    sum = sum + ( hfc->vertex()->point() - CGAL::ORIGIN );
	} while ( ++hfc != fi->facet_begin() );
	sum = sum / ( double )CGAL::circulator_size( hfc );
	fi->center() = CGAL::ORIGIN + sum;
    }

    // assign the same IDs to the identical/ opposite halfedges
    for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) {
	hi->label()		= DEFAULT_LABEL;
	hi->match()		= DEFAULT_LABEL;
	hi->cycle()		= NO_INDEX;
	hi->connect()		= true;
	hi->visit()		= false;
	hi->path()		= NO_INDEX;
	hi->orient()		= true;
	// We individually handle hi->fixed
    }
}
Пример #7
0
int main()
{
    std::vector<Point_3> points;

    points.push_back(Point_3(2.0f, 3.535533905932738f, 3.535533905932737f));
    points.push_back(Point_3(4.0f, 2.0f, 0.0f));
    points.push_back(Point_3(0.0f, 2.0f, 0.0f));
    points.push_back(Point_3(1.0f, 0.0f, 0.0f));
    points.push_back(Point_3(4.0f, 1.414213562373095f, 1.414213562373095f));
    points.push_back(Point_3(0.0f, 1.414213562373095f, 1.414213562373095f));
    points.push_back(Point_3(3.0f, 0.0f, 0.0f));
    points.push_back(Point_3(2.0f, 5.0f, 0.0f));

    Polyhedron P;

    CGAL::convex_hull_3(points.begin(), points.end(), P);

    std::cout << "- Number of vertices  = " << P.size_of_vertices()    << std::endl;
    std::cout << "- Number of edges     = " << P.size_of_halfedges()/2 << std::endl;
    std::cout << "- Number of faces     = " << P.size_of_facets()      << std::endl;

    for ( Facet_iterator i = P.facets_begin(); i != P.facets_end(); ++i)
    {
        Halfedge_facet_circulator j = i->facet_begin();
        CGAL_assertion( CGAL::circulator_size(j) >= 3);
        std::cout << CGAL::circulator_size(j) << ' ';
        do{
            //std::cout << ' ' << std::distance(P.vertices_begin(), j->vertex());
            std::cout << " (" << j->vertex()->point().x() << ' ' << j->vertex()->point().y() << ' ' << j->vertex()->point().z() << ')' << ", ";
        } while ( ++j != i->facet_begin());

        std::cout << std::endl;
    }
    return 0;
}
void mergeCoplanar(Polyhedron& p,bool step2) {
	int facetsBefore =  p.size_of_facets();
	
	p.normalize_border();
	if(!p.size_of_border_halfedges()) {
		// Calculate normals only once in advace! so all tris should be coplanar with the original
		std::transform( p.facets_begin(), p.facets_end(),p.planes_begin(),Plane_equation());			// Calculate plane equations (only works on tri<- = bs)=true
		bool coplanarFound = true;
		std::vector<Polyhedron::Halfedge_handle> skipHEs;
		while (coplanarFound) {			
			coplanarFound = false;																		// Set coplanarFound false
			int percCount = 1;
			for (Polyhedron::Halfedge_iterator hit = p.halfedges_begin(); hit != p.halfedges_end(); ++hit,++percCount){ // Loop through all halfedges
				if (is_coplanar(hit,true)){																// If coplanar and equals semantics
					Polyhedron::Halfedge_handle removeMe = hit;
					while (CGAL::circulator_size(removeMe->vertex_begin()) < 3)							// Mover handle to beginning of linestring
						removeMe = removeMe->next();
					
					bool jcnh = false;
					if (!step2) jcnh = joinCreatesNoHole (hit);
					else		jcnh = joinCreatesNoHole2(hit);
					if (jcnh){														// If no holes will be created

						std::cout << "\rFacets   before/after: "<<facetsBefore<<" -> "<< p.size_of_facets()<<". ("<<100*percCount/p.size_of_halfedges()<<"%)";

						while (CGAL::circulator_size(removeMe->opposite()->vertex_begin()) < 3)			// Join vertexes until at the other end of linestring
							if (removeMe->facet_degree()>3 && removeMe->opposite()->facet_degree()>3)
								removeMe = (p.join_vertex(removeMe))->next()->opposite();
							else																		// One of the faces turned into a triangle ->remove center vertex
								break;																	
						if (CGAL::circulator_size(removeMe->opposite()->vertex_begin()) < 3)			// Remove remained of the border
							p.erase_center_vertex(removeMe->opposite());								// if two segments remain remove center point
						else
							p.join_facet(removeMe);														// if one segment remains join facets
						coplanarFound = true;
						break;
					} else { // simplify border, but how to do this safely? not optimal solution implemented. Should do: add inward offseted point of intersection etc.
						if (std::find(skipHEs.begin(), skipHEs.end(),hit)!=skipHEs.end()) {					// Skip if hit in skipList
							while (CGAL::circulator_size(removeMe->opposite()->vertex_begin()) < 3)	{		// Join vertexes until at the other end of linestring
								if (removeMe->facet_degree()>3 && removeMe->opposite()->facet_degree()>3)
									if (triDoesNotIntersectFacet(removeMe))									// if tri reMe,reME->prev does not intersect left or right facet
										removeMe = (p.join_vertex(removeMe))->next()->opposite();			// remove removeME
									else {
										skipHEs.push_back(removeMe);
										skipHEs.push_back(removeMe->opposite());
										removeMe = removeMe->prev();										// move removeME one halfedge back
									}
								else break;																	// stop if only a triangle remains or at other end																
							}	
							skipHEs.push_back(removeMe);
							skipHEs.push_back(removeMe->opposite());
	}	}	}	}	}	}
	//if (!step2) mergeCoplanar(p,true);
	//else 
		std::cout << "\rFacets   before/after: "<<facetsBefore<<" -> "<< p.size_of_facets()<<". (100%)"<<std::endl;
}
Пример #9
0
static int number_of_degenerate_facets(Polyhedron& p, const double threshold)
{
  int count = 0;
  for (typename Polyhedron::Facet_iterator facet = p.facets_begin();
       facet != p.facets_end(); facet++)
  {
    dolfin_assert(facet->is_triangle());
    if ( facet_is_degenerate<Polyhedron>(facet, threshold) )
      count++;
  }
  return count;
}
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;
}
Пример #11
0
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;
}
Пример #12
0
//------------------------------------------------------------------------------
//	Initialize the dual center 
//------------------------------------------------------------------------------
void initAttrs( Polyhedron & poly )
{
    // assign IDs to vertices
    int vID = 0;
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	vi->id()	= vID++;
	vi->label()	= DEFAULT_LABEL;
	vi->nCuts()	= 0;
    }
    cerr << "Total number of vertices = " << vID << endl;

    // assign IDs to faces: the dual vertex and the dual coordinates-the center coordinates
    int fID = 0;
    for ( Facet_iterator fi = poly.facets_begin(); fi != poly.facets_end(); ++fi ) {
	fi->id()	= fID++;
	// fi->label()	= DEFAULT_LABEL;
	fi->piece()	= NO_INDEX;
	Vector3 sum( 0.0, 0.0, 0.0 );
	Halfedge_facet_circulator hfc = fi->facet_begin();
	do {
	    sum = sum + ( hfc->vertex()->point() - CGAL::ORIGIN );
	} while ( ++hfc != fi->facet_begin() );
	sum = sum / ( double )CGAL::circulator_size( hfc );
	fi->center() = CGAL::ORIGIN + sum;
	// cerr << " Barycenter No. " << fid-1 << " : " << bary[ fid-1 ] << endl;
    }
    cerr << "Total number of facets = " << fID << endl;

    // initialize the halfedge IDs
    for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) {
	hi->id() = NO_INDEX;
    }

    // assign the same IDs to the identical/ opposite halfedges
    int eID = 0;
    for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) {
	if ( hi->id() == NO_INDEX ) {
	    assert( hi->opposite()->id() == NO_INDEX );
	    hi->id() = eID;
	    hi->opposite()->id() = eID;
	    eID++;
	    hi->label()		= hi->opposite()->label()	= DEFAULT_LABEL;
	    hi->match()		= hi->opposite()->match()	= DEFAULT_LABEL;
	    hi->cycle()		= hi->opposite()->cycle()	= NO_INDEX;
	    hi->weight()	= hi->opposite()->weight()	= 0.0;
	    hi->connect()	= hi->opposite()->connect()	= true;
	    hi->visit()		= hi->opposite()->visit()	= false;
	    // We individually handle hi->fixed
	}
    }
    cerr << "Total number of edges = " << eID << endl;
}
Пример #13
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?
	}
}
Пример #14
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;
 }
Пример #15
0
int main() {
    Point_3 p( 1, 0, 0);
    Point_3 q( 0, 1, 0);
    Point_3 r( 0, 0, 1);
    Point_3 s( 0, 0, 0);
    Polyhedron P;
    P.make_tetrahedron( p, q, r, s);
    std::transform( P.facets_begin(), P.facets_end(), P.planes_begin(),
                    Plane_equation());
    CGAL::set_pretty_mode( std::cout);
    std::copy( P.planes_begin(), P.planes_end(),
               std::ostream_iterator<Plane_3>( std::cout, "\n"));
    return 0;
}
Пример #16
0
//------------------------------------------------------------------------------
//	Compute and store the results of dual graphs into appropriate variables
//
//  computeDual( mesh, whole, bary, mid ); 
//------------------------------------------------------------------------------
void computeDual( Polyhedron & poly, Graph & dual,
		  vector< Point3 > & bary, vector< Point3 > & mid )
{
    // initialize the array of face barycenters: refer to the point at which the gravitational forces exerted by 2 objects are equal

    bary.clear();
    bary.resize( poly.size_of_facets() );

    // initialize the dual graph with dual vertices
    dual.clear();
    int fid = 0;
    for ( Facet_iterator fi = poly.facets_begin(); fi != poly.facets_end(); ++fi ) {
	// add a vertex: each face equals to each dual vertex
	add_vertex( dual );
	bary[ fid++ ] = fi->center(); 
	// cerr << " Barycenter No. " << fid-1 << " : " << bary[ fid-1 ] << endl;
    }

    int size_of_edges = poly.size_of_halfedges() / 2; //redundant

    // initialize the array of midpoints
    mid.clear();
    mid.resize( size_of_edges );

    // initialize the array of lengths
    // length.clear();
    // length.resize( size_of_edges );

    // construct the connecitivity of the dual graph
    for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) {
	int origID = hi->facet()->id(); // the face
	int destID = hi->opposite()->facet()->id(); // the neighbor face
	Point3 origCoord = hi->vertex()->point();
	Point3 destCoord = hi->opposite()->vertex()->point();
	Vector3 dispVec = origCoord - destCoord;
	Point3 midCoord = destCoord + 0.5 * dispVec;
	// double curLength = sqrt( dispVec.squared_length() ); // the length between two connected vertices
#ifdef DEBUG
	cerr << origID << " -- " << destID << endl;
#endif	// DEBUG	
	
	if ( origID < destID )
		add_edge( origID, destID, hi->id(), dual );  
		
	mid[ hi->id() ] = midCoord;
	hi->mid() = hi->opposite()->mid() = midCoord;
	hi->weight() = hi->opposite()->weight() = 1.0;
    }
}
IGL_INLINE void igl::copyleft::cgal::polyhedron_to_mesh(
  const Polyhedron & poly,
  Eigen::MatrixXd & V,
  Eigen::MatrixXi & F)
{
  using namespace std;
  V.resize(poly.size_of_vertices(),3);
  F.resize(poly.size_of_facets(),3);
  typedef typename Polyhedron::Vertex_const_iterator Vertex_iterator;
  std::map<Vertex_iterator,size_t> vertex_to_index;
  {
    size_t v = 0;
    for(
      typename Polyhedron::Vertex_const_iterator p = poly.vertices_begin();
      p != poly.vertices_end();
      p++)
    {
      V(v,0) = p->point().x();
      V(v,1) = p->point().y();
      V(v,2) = p->point().z();
      vertex_to_index[p] = v;
      v++;
    }
  }
  {
    size_t f = 0;
    for(
      typename Polyhedron::Facet_const_iterator facet = poly.facets_begin();
      facet != poly.facets_end();
      ++facet)
    {
      typename Polyhedron::Halfedge_around_facet_const_circulator he = 
        facet->facet_begin();
      // Facets in polyhedral surfaces are at least triangles.
      assert(CGAL::circulator_size(he) == 3 && "Facets should be triangles");
      size_t c = 0;
      do {
        //// This is stooopidly slow
        // F(f,c) = std::distance(poly.vertices_begin(), he->vertex());
        F(f,c) = vertex_to_index[he->vertex()];
        c++;
      } while ( ++he != facet->facet_begin());
      f++;
    }
  }
}
Пример #18
0
void intersection( const Polyhedron& P) {
    std::vector<Box> boxes;
    boxes.reserve( P.size_of_facets());
    for ( Facet_const_iterator i = P.facets_begin(); i != P.facets_end(); ++i){
        boxes.push_back(
            Box( i->halfedge()->vertex()->point().bbox()
               + i->halfedge()->next()->vertex()->point().bbox()
               + i->halfedge()->next()->next()->vertex()->point().bbox(),
                 i));
    }
    std::vector<const Box*> box_ptr;
    box_ptr.reserve( P.size_of_facets());
    for ( std::vector<Box>::iterator j = boxes.begin(); j != boxes.end(); ++j){
        box_ptr.push_back( &*j);
    }
    CGAL::box_self_intersection_d( box_ptr.begin(), box_ptr.end(),
                                   Intersect_facets(), std::ptrdiff_t(2000));
}
Пример #19
0
 int main(int argc, const char **argv )
 {
   std::vector<Point> points;
   CGAL::Random_points_on_sphere_3<Point> g;

   size_t N = 0;
   if (argc > 1)
     N = atof(argv[1]);
   N = std::max(size_t(100), N);

   for (size_t i = 0; i < N; ++i)
     points.push_back(rescale(*g++));

   for (size_t n = 0; n < 100; ++n)
     {
       std::cerr << "step " << n << ":\n\t";
       lloyd_step(points);
     }

   Polyhedron P;
   CGAL::convex_hull_3(points.begin(), points.end(), P);

   CGAL::set_ascii_mode( std::cout);
   std::cout << "OFF" << std::endl << P.size_of_vertices() << ' '
	     << P.size_of_facets() << " 0" << std::endl;
   std::copy( P.points_begin(), P.points_end(),
	      std::ostream_iterator<Point>( std::cout, "\n"));
   for (  Facet_iterator i = P.facets_begin(); i != P.facets_end(); ++i) {
     Halfedge_facet_circulator j = i->facet_begin();
     // Facets in polyhedral surfaces are at least triangles.
     CGAL_assertion( CGAL::circulator_size(j) >= 3);
     std::cout << CGAL::circulator_size(j) << ' ';
     do {
       std::cout << ' ' << std::distance(P.vertices_begin(), j->vertex());
     } while ( ++j != i->facet_begin());
     std::cout << std::endl;
   }

   std::ofstream os ("test.cloud");
   std::copy(points.begin(), points.end(),
	     std::ostream_iterator<Point>(os, "\n"));
}
Пример #20
0
Input_facets_AABB_tree* get_aabb_tree(Scene_polyhedron_item* item)
{
  QVariant aabb_tree_property = item->property(aabb_property_name);
  if(aabb_tree_property.isValid()) {
    void* ptr = aabb_tree_property.value<void*>();
    return static_cast<Input_facets_AABB_tree*>(ptr);
  }
  else {
    Polyhedron* poly = item->polyhedron();
    if(poly) {
      Input_facets_AABB_tree* tree = 
        new Input_facets_AABB_tree(poly->facets_begin(),
                                   poly->facets_end());
      item->setProperty(aabb_property_name, 
                        QVariant::fromValue<void*>(tree));
      return tree;
    }
    else return 0;
  }
}
Пример #21
0
static void remove_small_triangles(Polyhedron& p, const double threshold)
{
  int n = number_of_degenerate_facets(p, threshold);

  while (n > 0)
  {
    for (typename Polyhedron::Facet_iterator facet = p.facets_begin();
	 facet != p.facets_end(); facet++)
    {
      dolfin_assert(facet->is_triangle());

      if (get_triangle_area<Polyhedron>(facet) < threshold)
      {
	// cout << "Small triangle detected" << endl;
	// print_facet<Polyhedron>(facet);
	remove_triangle<Polyhedron>(p, facet);
	n = number_of_degenerate_facets<Polyhedron>(p, threshold);
	break;
      }
    }
  }
}
Пример #22
0
ofMesh & ofxCGALSkinSurface::makeSkinSurfaceMesh() {
    std::list<Weighted_point> l;
    FT shrinkfactor = shrinkFactor;
    
    for(int i=0; i<points.size(); i++) {
        float px = points[i].point.x;
        float py = points[i].point.y;
        float pz = points[i].point.z;
        float radius = points[i].radius;
        
        l.push_front(Weighted_point(Bare_point(px, py, pz), radius * radius));
    }
    
    Skin_surface_3 skin_surface(l.begin(), l.end(), shrinkfactor);
    
    Polyhedron p;
    CGAL::mesh_skin_surface_3(skin_surface, p);
    
    if(bSubdiv == true) {
        CGAL::subdivide_skin_surface_mesh_3(skin_surface, p);
    }
    
    mesh.clear();
    
    map<Point_3, int> point_indices;
    int count = 0;
    
    for (auto it=p.vertices_begin(); it!=p.vertices_end(); ++it) {
        auto& p = it->point();
        mesh.addVertex(ofVec3f(p.x(), p.y(), p.z()));
        point_indices[p] = count++;
    }
    for (auto it=p.facets_begin(); it!=p.facets_end(); ++it) {
        mesh.addIndex(point_indices[it->halfedge()->vertex()->point()]);
        mesh.addIndex(point_indices[it->halfedge()->next()->vertex()->point()]);
        mesh.addIndex(point_indices[it->halfedge()->prev()->vertex()->point()]);
    }
}
Пример #23
0
int main() {

	
	//std::cout<<CGBench::BendBench::Run(CGBench::VMag::M1)<<std::endl;
	//CGBench::BenchLanuch(CGBench::VMag::M3,CGBench::VMag::M3);

	/*std::ofstream of("C:\\123.off");

	std::vector <Point_3> arr;
	arr.push_back(Point_3 (2,0,2));
	arr.push_back(Point_3 (6,0,3));
	arr.push_back(Point_3 (8,0,4));
	arr.push_back(Point_3 (3,0,5));
	arr.push_back(Point_3 (5,0,6));
	arr.push_back(Point_3 (8,0,7));

	arr.push_back(Point_3 (0,1.75,8));
	arr.push_back(Point_3 (0,1.50,8));
	arr.push_back(Point_3 (0,1.25,8));

	arr.push_back(Point_3 (0,1,8));
	arr.push_back(Point_3 (0,1,7));
	arr.push_back(Point_3 (0,1,6));
	arr.push_back(Point_3 (0,1,5));
	arr.push_back(Point_3 (0,1,4));
	arr.push_back(Point_3 (0,1,3));

	arr.push_back(Point_3 (0,1.25,3));
	arr.push_back(Point_3 (0,1.50,3));
	arr.push_back(Point_3 (0,1.75,3));

	
	Point_3* Center = new Point_3(0,0,0);*/

	//Arc_2 s(30,270,30,true);
	//Circle_2 s(4,20);
	//Ellipse_2 s(6,4,30);
	//Plane_3 s(30,30,10,10);
	//Rectangle_2 s(20,10);

	//Box_3 s(20,20,20,15,15,15);
	//Capsule_3 s(30,200,10,10);
	//ChamferCyl_3 s(60,100,30,10,5,5,15);
	//Cone_3 s(2,5,10,3,3,3);
	//Cylinder_3 s(3,20,20,9,30);
	//Lathe_3 s(arr,Center,Z_ax,20,360);
	//Pyramid_3 s(100,200,200,4,4,4);
	//Sphere_3 s(20,50);
	//Spindle_3 s(10,30,20,10,5,15);
	//Spring_3 s(20,2.5,200,10,10,40);
	//Torus_3 s(20,5,0,0,30,40);
	//Tube_3 s(14,13,15,20,20,10);

	//Polyhedron P;
	//P = s.Draw();
	//Traingulate trg;
	//P=s.Draw();
	//std::transform(P.facets_begin(), P.facets_end(), P.planes_begin(), Normal_vector());
	/*Eigen::Transform3d T;
	Eigen::Vector3d Original(0,0,10);
	T.setIdentity();
	T.pretranslate (-Original);
	trg.ApplyTransformToPolyhedron(P,T);*/


	//Traingulate tr;
	//tr.Do(P);

	//Bevel Be(400,-4,1.25);
	//Be.Do(P);

	//Bridge Br(18,20);
	//Br.Do(P);

	//Extrude Ex(45,15);
	//Ex.Do(P);
	
	//Outline Ou(45,1.5);
	//Ou.Do(P);


	//Bend Ben(90,s.Center,Y_ax,false,20,-20);
	//Ben.Do(P);

	//Bulge Bu(40,s.Center,Z_ax,BRadial,false,45,-45);
	//Bu.Do(P);

	//Cylindrical_Wave CylWa(2,8,12,s.Center,Z_ax);
	//CylWa.Do(P);

	//Linear_Wave LiWaX(1,10,0,s.Center,Z_ax,X_ax);
	//LiWaX.Do(P);
	//Linear_Wave LiWaY(2,10,0,s.Center,Z_ax,Y_ax);
	//LiWaY.Do(P);

	/*ChamferCyl_3 n(1,50,5,10,10,10,40);
	Spindle_3 p(5,30,5,10,20,40);
	Polyhedron P;
	Polyhedron E;
	E = p.Draw();
	P = n.Draw();
	Morph Mor(E,50);
	Mor.Do(P);*/

	//Noise No(5,0.3,0,s.Center,Z_ax);
	//No.Do(P);

	//Skew Sk(30,s.Center,Z_ax,false,20,-20);
	//Sk.Do(P);

	//Smooth Sm(1);
	//Sm.Do(P);

	//Spherify Sph(50);
	//Sph.Do(P);

	//Squeeze Sq(-30,s.Center,Z_ax,false,10,0);
	//Sq.Do(P);

	//Stretch St(-20,s.Center,Z_ax,true,50,-50);
	//St.Do(P);
	
	//Taper Ta(3,s.Center,X_ax,false,20,-20);
	//Ta.Do(P);

	//Twist Tw(270,s.Center,Z_ax,true,-5,15);
	//Tw.Do(P);

	/*Box_3 B(20, 30, 60, 20, 30, 30); 
	Polyhedron P = B.Draw();
	Twist Tw1(270, B.Center, Z_ax, true, 30, 10);
	Twist Tw2(-270, B.Center, Z_ax, true, -10, -30);
	Stretch St(30, B.Center, Z_ax, true, 20,-20);
	Squeeze Sq(15, B.Center, Z_ax);
	Tw1.Do(P);
	Tw2.Do(P);
	Sq.Do(P);
	St.Do(P);*/

	std::ofstream of("C:\\123.off");

	Box_3 B(20, 30, 60, 20, 30, 30); 
Polyhedron P = B.Draw();
Twist Tw1(270, B.Center, Z_ax, true, 30, 10);
Twist Tw2(-270, B.Center, Z_ax, true, -10, -30);
Stretch St(30, B.Center, Z_ax, true, 20,-20);
Squeeze Sq(15, B.Center, Z_ax);
Tw1.Do(P);
Tw2.Do(P);
Sq.Do(P);
St.Do(P);



	//// Write polyhedron in Object File Format (OFF).
	CGAL::set_ascii_mode( of );
	of << "OFF" << std::endl << P.size_of_vertices() << ' ' << P.size_of_facets() << " 0" << std::endl;
	std::copy( P.points_begin(), P.points_end(), std::ostream_iterator<Point_3>( of, "\n"));

	for (  Facet_iterator i = P.facets_begin(); i != P.facets_end(); ++i) 
	{
		Halfedge_facet_circulator j = i->facet_begin();
		// Facets in polyhedral surfaces are at least triangles.
		CGAL_assertion( CGAL::circulator_size(j) >= 3);
		of << CGAL::circulator_size(j) << ' ';
		
		do 
		{
			of << ' ' << std::distance(P.vertices_begin(), j->vertex());
		} while ( ++j != i->facet_begin());
		
		of << std::endl;
	}

	/* Write polyhedron in (OBJ).
	CGAL::set_ascii_mode( oof );
	oof << "# " << P.size_of_vertices() << ' ' << std::endl <<"# "<< P.size_of_facets() << std::endl;
	oof<<"v ";
	std::copy( P.points_begin(), P.points_end(), std::ostream_iterator<Point_3>( oof, "\nv "));
	oof<<"_ _ _\n";
	for (  Facet_iterator i = P.facets_begin(); i != P.facets_end(); ++i)
	{
		Halfedge_facet_circulator j = i->facet_begin();
		// Facets in polyhedral surfaces are at least triangles.
		//CGAL_assertion( CGAL::circulator_size(j) >= 3);
       
		oof << 'f' << ' ';
       
		do
		{
			oof << ' ' << std::distance(P.vertices_begin(), j->vertex())+1;
		} while ( ++j != i->facet_begin());
       
		oof << std::endl;
	}
	*/

	return 0;
}
void PoissonSurfaceReconstruction::reconstruct(std::vector<Eigen::Vector3d> &points, std::vector<Eigen::Vector3d> &normals, TriangleMesh &mesh){

	assert(points.size() == normals.size());

  std::cout << "creating points with normal..." << std::endl;
  std::vector<Point_with_normal> points_with_normal;
  points_with_normal.resize((int)points.size());
  for(int i=0; i<(int)points.size(); i++){
    Vector vec(normals[i][0], normals[i][1], normals[i][2]);
    //Point_with_normal pwn(points[i][0], points[i][1], points[i][2], vec);
    //points_with_normal[i]  = pwn;
    points_with_normal[i] = Point_with_normal(points[i][0], points[i][1], points[i][2], vec);
  }

  std::cout << "constructing poisson reconstruction function..." << std::endl;
  Poisson_reconstruction_function function(points_with_normal.begin(), points_with_normal.end(),
                                           CGAL::make_normal_of_point_with_normal_pmap(PointList::value_type()));

  std::cout << "computing implicit function..." << std::endl;
  if( ! function.compute_implicit_function() ) {
  	std::cout << "compute implicit function is failure" << std::endl;
  	return;
  }
  	//return EXIT_FAILURE;

  // Computes average spacing
  std::cout << "compute average spacing..." << std::endl;
  FT average_spacing = CGAL::compute_average_spacing(points_with_normal.begin(), points_with_normal.end(),
                                                       6 /* knn = 1 ring */);
  // Gets one point inside the implicit surface
  // and computes implicit function bounding sphere radius.
  Point inner_point = function.get_inner_point();
  Sphere bsphere = function.bounding_sphere();
  FT radius = std::sqrt(bsphere.squared_radius());

  // Defines the implicit surface: requires defining a
  // conservative bounding sphere centered at inner point.
  FT sm_sphere_radius = 5.0 * radius;
  FT sm_dichotomy_error = distance_criteria*average_spacing/1000.0; // Dichotomy error must be << sm_distance
  //FT sm_dichotomy_error = distance_criteria*average_spacing/10.0; // Dichotomy error must be << sm_distance
  std::cout << "reconstructed surface" << std::endl;
  Surface_3 reconstructed_surface(function,
                    Sphere(inner_point,sm_sphere_radius*sm_sphere_radius),
                    sm_dichotomy_error/sm_sphere_radius);

  // Defines surface mesh generation criteria    
  CGAL::Surface_mesh_default_criteria_3<STr> criteria(angle_criteria,  // Min triangle angle (degrees)
                                                        radius_criteria*average_spacing,  // Max triangle size
                                                        distance_criteria*average_spacing); // Approximation error
  
  std::cout << "generating surface mesh..." << std::endl;
  // Generates surface mesh with manifold option
  STr tr; // 3D Delaunay triangulation for surface mesh generation
  C2t3 c2t3(tr); // 2D complex in 3D Delaunay triangulation
  CGAL::make_surface_mesh(c2t3,                                 // reconstructed mesh
                            reconstructed_surface,                              // implicit surface
                            criteria,                             // meshing criteria
                            CGAL::Manifold_tag());  // require manifold mesh

  if(tr.number_of_vertices() == 0){
  	std::cout << "surface mesh generation is failed" << std::endl;
  	return;
  }

  Polyhedron surface;
  CGAL::output_surface_facets_to_polyhedron(c2t3, surface);

  // convert CGAL::surface to TriangleMesh //
  std::cout << "converting CGA::surface to TriangleMesh..." << std::endl;
	std::vector<Eigen::Vector3d> pts;
	std::vector<std::vector<int> > faces;
	pts.resize(surface.size_of_vertices());
	faces.resize(surface.size_of_facets());

	Polyhedron::Point_iterator pit;
	int index = 0;
	for(pit=surface.points_begin(); pit!=surface.points_end(); ++pit){
		pts[index][0] = pit->x();
		pts[index][1] = pit->y();
		pts[index][2] = pit->z();				
		index ++;
	}
	index = 0;
	Polyhedron::Face_iterator fit;
	for(fit=surface.facets_begin(); fit!=surface.facets_end(); ++fit){
		std::vector<int > face(3);
		Halfedge_facet_circulator j = fit->facet_begin();
		int f_index = 0;
		do {
			face[f_index] = std::distance(surface.vertices_begin(), j->vertex());
			f_index++;
    } while ( ++j != fit->facet_begin());    

    faces[index] = face;
		index++;
	}

	mesh.createFromFaceVertex(pts, faces);  
}
Пример #25
0
/*
 * mexFunction(): entry point for the mex function
 */
void mexFunction(int nlhs, mxArray *plhs[], 
		 int nrhs, const mxArray *prhs[]) {

  // interface to deal with input arguments from Matlab
  enum InputIndexType {IN_TRI, IN_X, IN_METHOD, IN_ITER, InputIndexType_MAX};
  MatlabImportFilter::Pointer matlabImport = MatlabImportFilter::New();
  matlabImport->ConnectToMatlabFunctionInput(nrhs, prhs);

  // check that we have all input arguments
  matlabImport->CheckNumberOfArguments(2, InputIndexType_MAX);

  // register the inputs for this function at the import filter
  MatlabInputPointer inTRI =        matlabImport->RegisterInput(IN_TRI, "TRI");
  MatlabInputPointer inX =          matlabImport->RegisterInput(IN_X, "X");
  MatlabInputPointer inMETHOD =     matlabImport->RegisterInput(IN_METHOD, "METHOD");
  MatlabInputPointer inITER =       matlabImport->RegisterInput(IN_ITER, "ITER");

  // interface to deal with outputs to Matlab
  enum OutputIndexType {OUT_TRI, OUT_N, OutputIndexType_MAX};
  MatlabExportFilter::Pointer matlabExport = MatlabExportFilter::New();
  matlabExport->ConnectToMatlabFunctionOutput(nlhs, plhs);

  // check number of outputs the user is asking for
  matlabExport->CheckNumberOfArguments(0, OutputIndexType_MAX);

  // register the outputs for this function at the export filter
  typedef MatlabExportFilter::MatlabOutputPointer MatlabOutputPointer;
  MatlabOutputPointer outTRI = matlabExport->RegisterOutput(OUT_TRI, "TRI");
  MatlabOutputPointer outN = matlabExport->RegisterOutput(OUT_N, "N");

  // if any of the inputs is empty, the output is empty too
  if (mxIsEmpty(prhs[IN_TRI]) || mxIsEmpty(prhs[IN_X])) {
    matlabExport->CopyEmptyArrayToMatlab(outTRI);
    matlabExport->CopyEmptyArrayToMatlab(outN);
    return;
  }

  // polyhedron to contain the input mesh
  Polyhedron mesh;
  PolyhedronBuilder<Polyhedron> builder(matlabImport, inTRI, inX);
  mesh.delegate(builder);

  // get size of input matrix with the points
  mwSize nrowsTri = mxGetM(inTRI->pm);
  mwSize nrowsX = mxGetM(inX->pm);

#ifdef DEBUG  
  std::cout << "Number of facets read = " << mesh.size_of_facets() << std::endl;
  std::cout << "Number of vertices read = " << mesh.size_of_vertices() << std::endl;
#endif

  if (nrowsTri != mesh.size_of_facets()) {
    mexErrMsgTxt(("Input " + inTRI->name + ": Number of triangles read into mesh different from triangles provided at the input").c_str());
  }
  if (nrowsX != mesh.size_of_vertices()) {
    mexErrMsgTxt(("Input " + inX->name + ": Number of vertices read into mesh different from vertices provided at the input").c_str());
  }

  // sort halfedges such that the non-border edges precede the
  // border edges. We need to do this before any halfedge iterator
  // operations are valid
  mesh.normalize_border();
  
#ifdef DEBUG
  std::cout << "Number of border halfedges = " << mesh.size_of_border_halfedges() << std::endl;
#endif
  
  // number of holes we have filled
  mwIndex n = 0;

  // a closed mesh with no holes will have no border edges. What we do
  // is grab a border halfedge and close the associated hole. This
  // makes the rest of the iterators invalid, so we have to normalize
  // the mesh again. Then we iterate, looking for a new border
  // halfedge, filling the hole, etc.
  //
  // Note that confusingly, mesh.border_halfedges_begin() gives a
  // pointer to the halfedge that is NOT a border in a border
  // edge. The border halfedge is instead
  // mesh.border_halfedges_begin()->opposite()
  while (!mesh.is_closed()) {
    
    // exit if user pressed Ctrl+C
    ctrlcCheckPoint(__FILE__, __LINE__);

    // get the first hole we can find, and close it
    mesh.fill_hole(mesh.border_halfedges_begin()->opposite());

    // increase the counter of number of holes we have filled
    n++;

    // renormalize mesh so that halfedge iterators are again valid
    mesh.normalize_border();

  }

  // split all facets to triangles
  CGAL::triangulate_polyhedron<Polyhedron>(mesh);

  // copy output with number of holes filled
  std::vector<double> nout(1, n);
  matlabExport->CopyVectorOfScalarsToMatlab<double, std::vector<double> >(outN, nout, 1);

  // allocate memory for Matlab outputs
  double *tri = matlabExport->AllocateMatrixInMatlab<double>(outTRI, mesh.size_of_facets(), 3);

   // extract the triangles of the solution
  // snippet adapted from CgalMeshSegmentation.cpp

  // vertices coordinates. Assign indices to the vertices by defining
  // a map between their handles and the index
  std::map<Vertex_handle, int> V;
  int inum = 0;
  for(Vertex_iterator vit = mesh.vertices_begin(); vit != mesh.vertices_end(); ++vit) {

    // save to internal list of vertices
    V[vit] = inum++;

  }  

  // triangles given as (i,j,k), where each index corresponds to a vertex in x
  mwIndex row = 0;
  for (Facet_iterator fit = mesh.facets_begin(); fit != mesh.facets_end(); ++fit, ++row) {

    if (fit->facet_degree() != 3) {
      std::cerr << "Facet has " << fit->facet_degree() << " edges" << std::endl;
      mexErrMsgTxt("Facet does not have 3 edges");
    }

    // go around the half-edges of the facet, to extract the vertices
    Halfedge_around_facet_circulator heit = fit->facet_begin();
    int idx = 0;
    do {
      
      // extract triangle indices and save to Matlab output
      // note that Matlab indices go like 1, 2, 3..., while C++ indices go like 0, 1, 2...
      tri[row + idx * mesh.size_of_facets()] = 1 + V[heit->vertex()];
      idx++;

    } while (++heit != fit->facet_begin());
    
  }
}
Пример #26
0
void groupSemanticFacets(Polyhedron& polyhe,sfsVec& semFacetSetsVector,sfsVec& openSFSVector,std::map<int,std::vector<int>>& openingMap){
	bool skip;
	// Group non-openings
	for (Polyhedron::Facet_iterator fIt=polyhe.facets_begin();fIt!=polyhe.facets_end();++fIt) {
		if (fIt->semanticBLA == "Window" || fIt->semanticBLA == "Door") continue;				// Skip openings
		skip = false;																			// Check of facet has already been processed
		for (unsigned int i=0;i<semFacetSetsVector.size();++i) {
			if (semFacetSetsVector[i].first == fIt->semanticBLA									// Check sem of set
			&& (semFacetSetsVector[i].second.find(fIt)!=semFacetSetsVector[i].second.end())) {	// if in set -> skip
				skip = true;
				break;
			}
		}
		if (skip) continue;

		std::set<Polyhedron::Facet_handle> fhSet;
		connectedSemFacets(fIt,fIt->semanticBLA,false,fhSet,false);								// Get list of all (in)directly connected facets
		semFacetSetsVector.push_back(sfsPair(fIt->semanticBLA,fhSet));							// Store connected facet list
	}
	// Group and match openings
	for (Polyhedron::Facet_iterator fIt=polyhe.facets_begin();fIt!=polyhe.facets_end();++fIt) {
		if (!(fIt->semanticBLA == "Window" || fIt->semanticBLA == "Door")) continue;		// Skip non-openings
		skip = false;																		// Check of facet has already been processed
		for (unsigned int i=0;i<openSFSVector.size();++i) {
			if (openSFSVector[i].first == fIt->semanticBLA									// Check sem of set
			&& (openSFSVector[i].second.find(fIt)!=openSFSVector[i].second.end())) {		// if in set -> skip
				skip = true;
				break;
			}
		}
		if (skip) continue;

		// Store opening facets
		std::set<Polyhedron::Facet_handle> fhSet;
		connectedSemFacets(fIt,fIt->semanticBLA,false,fhSet,false);
		openSFSVector.push_back(sfsPair(fIt->semanticBLA,fhSet));

		// Match/Find Surface containing the opening
		bool found = false;	
		bool setRoof = false;
		Polyhedron::Facet_handle otherFace;
		otherFace->semanticBLA;
		Polyhedron::Facet::Halfedge_around_facet_circulator itHDS;
		for (std::set<Polyhedron::Facet_handle>::iterator setIt=fhSet.begin();setIt!=fhSet.end();++setIt) {
			itHDS = (*setIt)->facet_begin();				// Loop over the edges
			do {
				if (itHDS->opposite()->facet()->semanticBLA=="Wall" || itHDS->opposite()->facet()->semanticBLA=="WallSurface") {
					otherFace = itHDS->opposite()->facet();	// Prefer wall surfaces
					found = true;
					break;
				} else if (itHDS->opposite()->facet()->semanticBLA=="Roof" || itHDS->opposite()->facet()->semanticBLA=="RoofSurface") {
					otherFace = itHDS->opposite()->facet();	// Prefer wall surfaces
					setRoof = true;
				} else if (!setRoof // Roof is better than other (except wall)
						&& itHDS->opposite()->facet()->semanticBLA!="Window"
						&& itHDS->opposite()->facet()->semanticBLA!="Door"
						&& itHDS->opposite()->facet()->semanticBLA!="Install"
						&& itHDS->opposite()->facet()->semanticBLA!="BuildingInstallation")
					otherFace = itHDS->opposite()->facet();

			} while (++itHDS != (*setIt)->facet_begin());
			if (found) break;			// Break when wall or roof found
		}

		int openingContainer = 0;		// Index of container surface
		for (unsigned int i=0;i<semFacetSetsVector.size();++i) {
			if (semFacetSetsVector[i].first == otherFace->semanticBLA									// Check sem of set
			&& (semFacetSetsVector[i].second.find(otherFace)!=semFacetSetsVector[i].second.end())) {	// if in set -> skip
				openingContainer = i;
				break;
			}
		}	
		openingMap[openingContainer].push_back(openSFSVector.size()-1); // Add opening reference to container vector
	}
}
Пример #27
0
void apply_semanticRequirements(Polyhedron& exteriorPolyhe) {
	std::map<std::string,std::vector<bool>> semanticNormals;
	semanticNormals["Roof"] = std::vector<bool>(3,true);
	semanticNormals["Roof"][2] = false;		// down
	semanticNormals["Ground"] = std::vector<bool>(3,false);
	semanticNormals["Ground"][2] = true;
	semanticNormals["Ceiling"] = std::vector<bool>(3,false);
	semanticNormals["Ceiling"][2] = true;
	semanticNormals["Floor"] = std::vector<bool>(3,false);
	semanticNormals["Floor"][0] = true;
	semanticNormals["Wall"] = std::vector<bool>(3,true);
	semanticNormals["Window"] = std::vector<bool>(3,true);
	semanticNormals["Door"] = std::vector<bool>(3,true);
	semanticNormals["Closure"] = std::vector<bool>(3,true);
	semanticNormals[TO_DIST_SEMANTIC] = std::vector<bool>(3,true);
	//semanticNormals["Anything"] = std::vector<bool>(3,true);

	std::map<std::string,int> semanticEnum;
	semanticEnum["Roof"]		= 1;
	semanticEnum["Window"]		= 2;
	semanticEnum["Door"]		= 3;
	semanticEnum["Wall"]		= 4;
	semanticEnum["Ground"]		= 5;
	semanticEnum["Ceiling"]		= 6;
	semanticEnum["Floor"]		= 7;
	semanticEnum["Closure"]		= 8;

	semanticEnum["Anything"]	= 9;
	//semanticEnum["Install"]		= 10;
	
	Vector_3 ortVec;
	
	Polyhedron::Facet_iterator exfIt;						// Iterate over exterior faces
	for (exfIt = exteriorPolyhe.facets_begin(); exfIt != exteriorPolyhe.facets_end(); ++exfIt) {	
			
		int minSem = 99;
			
		for (std::vector<std::string>::iterator svIt=exfIt->equidistSems.begin();svIt!=exfIt->equidistSems.end();++svIt) {				// Add equidist semantics
			std::map<std::string,int>::iterator seIt = semanticEnum.find(*svIt);
			if (seIt!=semanticEnum.end()) {				// ......
				if (seIt->second<minSem) {
					minSem = seIt->second;
					exfIt->semanticBLA = *svIt;
				}
			}else {										// This seems wrong...
				exfIt->semanticBLA = *svIt;
				break;
			}
		}

		pointVector facetPoints = comp_facetPoints(exfIt);
		CGAL::normal_vector_newell_3(facetPoints.begin(),facetPoints.end(),ortVec); // Calculate normal vector, ortVec set to zero in newell
		if (!normalizeVector(ortVec)) continue;

		std::map<std::string,std::vector<bool>>::iterator  snIt = semanticNormals.find(exfIt->semanticBLA);
		if (snIt!=semanticNormals.end()) {
			if		(!snIt->second[0] && ortVec.z() > HORIZONTAL_ANGLE_RANGE)
				exfIt->semanticBLA = DEFAULT_UP_SEMANTIC;
			else if (!snIt->second[1] && ortVec.z() <= HORIZONTAL_ANGLE_RANGE && ortVec.z() >= -HORIZONTAL_ANGLE_RANGE)
				exfIt->semanticBLA = DEFAULT_HOR_SEMANTIC;
			else if (!snIt->second[2] && ortVec.z() <= -HORIZONTAL_ANGLE_RANGE)
				exfIt->semanticBLA = DEFAULT_DOWN_SEMANTIC;
		} else {
			if		(ortVec.z() > HORIZONTAL_ANGLE_RANGE)
				exfIt->semanticBLA = DEFAULT_UP_SEMANTIC;
			else if (ortVec.z() <= HORIZONTAL_ANGLE_RANGE && ortVec.z() >= -HORIZONTAL_ANGLE_RANGE)
				exfIt->semanticBLA = DEFAULT_HOR_SEMANTIC;
			else if (ortVec.z() <= -HORIZONTAL_ANGLE_RANGE)
				exfIt->semanticBLA = DEFAULT_DOWN_SEMANTIC;
		}
	}
	// Set semantics of facets created due to closing (too far from original geometry)
	for (exfIt = exteriorPolyhe.facets_begin(); exfIt != exteriorPolyhe.facets_end(); ++exfIt) {	
		if (exfIt->semanticBLA==TO_DIST_SEMANTIC) {
			std::set<Polyhedron::Facet_handle> fhSet;
			connectedSemFacets(exfIt,TO_DIST_SEMANTIC,false,fhSet);
			bool canBeUp	= indirectlyTouchingFindSem(DEFAULT_UP_SEMANTIC,fhSet);
			bool canBeDown	= indirectlyTouchingFindSem(DEFAULT_DOWN_SEMANTIC,fhSet);
			assignCeilVloor(fhSet,canBeUp,canBeDown);
		}
	}
}
// 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());
}
int main()
{
    Point p(1.0, 0.0, 0.0);
    Point q(0.0, 1.0, 0.0);
    Point r(0.0, 0.0, 1.0);
    Point s(0.0, 0.0, 0.0);
    Polyhedron polyhedron;
    polyhedron.make_tetrahedron(p, q, r, s);

    // constructs AABB tree
    Tree tree(polyhedron.facets_begin(),polyhedron.facets_end(),polyhedron);

    // constructs segment query
    Point a(-0.2, 0.2, -0.2);
    Point b(1.3, 0.2, 1.3);
    Segment segment_query(a,b);

    // tests intersections with segment query
    if(tree.do_intersect(segment_query))
        std::cout << "intersection(s)" << std::endl;
    else
        std::cout << "no intersection" << std::endl;

    // computes #intersections with segment query
    std::cout << tree.number_of_intersected_primitives(segment_query)
        << " intersection(s)" << std::endl;

    // computes first encountered intersection with segment query
    // (generally a point)
    Segment_intersection intersection =
        tree.any_intersection(segment_query);
    if(intersection)
    {
        // gets intersection object
      if(boost::get<Point>(&(intersection->first)))
        std::cout << "intersection object is a point" << std::endl;
    }

    // computes all intersections with segment query (as pairs object - primitive_id)
    std::list<Segment_intersection> intersections;
    tree.all_intersections(segment_query, std::back_inserter(intersections));

    // computes all intersected primitives with segment query as primitive ids
    std::list<Primitive_id> primitives;
    tree.all_intersected_primitives(segment_query, std::back_inserter(primitives));

    // constructs plane query
    Vector vec(0.0,0.0,1.0);
    Plane plane_query(a,vec);

    // computes first encountered intersection with plane query
    // (generally a segment)
    Plane_intersection plane_intersection = tree.any_intersection(plane_query);
    if(plane_intersection)
    {
      
      if(boost::get<Segment>(&(plane_intersection->first)))
            std::cout << "intersection object is a segment" << std::endl;
    }

    return EXIT_SUCCESS;
}
Пример #30
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;
}