//********************************************************************************** //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); }
// 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"; } }
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()); };
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; }
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 } }
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; }
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; }
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; }
//------------------------------------------------------------------------------ // 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; }
// 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? } }
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; }
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; }
//------------------------------------------------------------------------------ // 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++; } } }
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)); }
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")); }
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; } }
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; } } } }
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()]); } }
TrianglesList meshSimplification(TrianglesList &triangles, int stopPredicate) { #ifdef MESHSIMPLIFICATION_LOG CGAL::Timer timer; timer.start(); #endif TrianglesList result; try { Polyhedron P; #ifdef MESHSIMPLIFICATION_LOG std::cout << "Start Building Polyhedron surface... " << std::endl; #endif Build_triangle_mesh_coherent_surface<HalfedgeDS> triangle(triangles); P.delegate(triangle); P.normalize_border(); #ifdef MESHSIMPLIFICATION_LOG std::cout << "Completed Building Polyhedron surface:" << std::endl; std::cout << "Polyhedron is_pure_triangle: " << P.is_pure_triangle() << std::endl; std::cout << "Polyhedron is_closed: " << P.is_closed() << std::endl; std::cout << "Polyhedron is_pure_bivalent : " << P.is_pure_bivalent () << std::endl; std::cout << "Polyhedron is_pure_trivalent: " << P.is_pure_trivalent() << std::endl; std::cout << "Polyhedron is_valid 0: " << P.is_valid(false, 0) << std::endl; std::cout << "Polyhedron is_valid 1: " << P.is_valid(false, 1) << std::endl; std::cout << "Polyhedron is_valid 2: " << P.is_valid(false, 2) << std::endl; std::cout << "Polyhedron is_valid 3: " << P.is_valid(false, 3) << std::endl; std::cout << "Polyhedron is_valid 4: " << P.is_valid(false, 4) << std::endl; std::cout << "Polyhedron normalized_border_is_valid : " << P.normalized_border_is_valid(false) << std::endl; #endif #ifdef MESHSIMPLIFICATION_LOG std::cout << "Start edge_collapse... " << std::endl; #endif SMS::Count_stop_predicate<Polyhedron> stop(stopPredicate); int removedEdges = SMS::edge_collapse(P, stop, CGAL::vertex_index_map(boost::get(CGAL::vertex_external_index, P)).edge_index_map(boost::get(CGAL::edge_external_index ,P)) ); #ifdef MESHSIMPLIFICATION_LOG std::cout << "Completed edge_collapse:" << std::endl; std::cout << "Finished with: " << removedEdges << " edges removed and " << (P.size_of_halfedges()/2) << " final edges." << std::endl; #endif //Build output result for ( Polyhedron::Facet_iterator fit( P.facets_begin() ), fend( P.facets_end() ); fit != fend; ++fit ) { if ( fit->is_triangle() ) { PointCGAL verts[3]; int tick = 0; Polyhedron::Halfedge_around_facet_circulator hit( fit->facet_begin() ), hend( hit ); do { if ( tick < 3 ) { verts[tick++] = PointCGAL( hit->vertex()->point().x(), hit->vertex()->point().y(), hit->vertex()->point().z() ); } else { std::cout << "meshSimplification: We've got facets with more than 3 vertices even though the facet reported to be triangular..." << std::endl; } } while( ++hit != hend ); result.push_back( Triangle(verts[0], verts[1], verts[2]) ); } else { std::cout << "meshSimplification: Skipping non-triangular facet" << std::endl; } } } catch (CGAL::Assertion_exception e) { std::cout << "ERROR: meshSimplification CGAL::Assertion_exception" << e.message() << std::endl; } #ifdef MESHSIMPLIFICATION_LOG timer.stop(); std::cout << "meshSimplification result with: " << result.size() << " triangles." << std::endl; std::cout << "Total meshSimplification time: " << timer.time() << std::endl; #endif return result; }
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); }
/* * 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()); } }
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; }
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 } }
// 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; }
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 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); } } }