Advertisement
Guest User

Untitled

a guest
Sep 9th, 2019
863
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.23 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3.  
  4. #include <CGAL/IO/print_wavefront.h>
  5. #include <CGAL/Polygon_mesh_processing/clip.h>
  6. #include <CGAL/Polyhedron_3.h>
  7. #include <CGAL/Polyhedron_incremental_builder_3.h>
  8. #include <CGAL/Simple_cartesian.h>
  9. #include <CGAL/polyhedron_cut_plane_3.h>
  10.  
  11. typedef CGAL::Simple_cartesian<double> Kernel;
  12. typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
  13. typedef Polyhedron::HalfedgeDS HalfedgeDS;
  14.  
  15. template <class HDS> class build_mesh : public CGAL::Modifier_base<HDS> {
  16. public:
  17.   explicit build_mesh(std::ifstream &ifs) : ifs(ifs) {}
  18.   void operator()(HDS &hds) override {
  19.  
  20.     // Post-condition: `hds' is a valid polyhedral surface.
  21.     CGAL::Polyhedron_incremental_builder_3<HDS> B(hds, true);
  22.  
  23.     std::vector<vec3d> V;
  24.     std::vector<vec3i> F;
  25.     std::tie(V, F) = parse_obj();
  26.  
  27.     B.begin_surface(V.size(), F.size());
  28.  
  29.     typedef typename HDS::Vertex Vertex;
  30.     typedef typename Vertex::Point Point;
  31.  
  32.     std::for_each(V.begin(), V.end(), [&B](const vec3d &pos) {
  33.       B.add_vertex(Point(pos[0], pos[1], pos[2]));
  34.     });
  35.  
  36.     std::for_each(F.begin(), F.end(), [&B](const vec3i &face) {
  37.       B.begin_facet();
  38.  
  39.       std::for_each(face.begin(), face.end(),
  40.                     [&B](unsigned int v) { B.add_vertex_to_facet(v); });
  41.  
  42.       B.end_facet();
  43.     });
  44.  
  45.     B.end_surface();
  46.   }
  47.  
  48. private:
  49.   typedef std::array<double, 3> vec3d;
  50.   typedef std::array<unsigned int, 3> vec3i;
  51.  
  52.   std::ifstream &ifs;
  53.  
  54.   std::pair<std::vector<vec3d>, std::vector<vec3i>> parse_obj() {
  55.     std::vector<vec3d> positions;
  56.     std::vector<vec3i> indices;
  57.  
  58.     std::string lead;
  59.     for (std::string line; std::getline(ifs, line);) {
  60.       if (line[0] == '#')
  61.         continue;
  62.  
  63.       lead = "";
  64.       std::stringstream ss(line);
  65.       ss >> lead;
  66.  
  67.       if (lead == "v") {
  68.         double x, y, z;
  69.         ss >> x >> y >> z;
  70.         positions.push_back({x, y, z});
  71.       } else if (lead == "f") {
  72.         vec3i face;
  73.         for (int i = 0; i < 3; ++i) {
  74.           ss >> face[i];
  75.           char ch;
  76.           do {
  77.             ch = ss.get();
  78.           } while (!ss.eof() && ch != ' ');
  79.         }
  80.         for (int i = 0; i < 3; ++i)
  81.           --face[i];
  82.         indices.push_back(face);
  83.       }
  84.     }
  85.  
  86.     return {positions, indices};
  87.   }
  88. };
  89.  
  90. // Ref:
  91. //  Polyhedron/examples/Polyhedron/polyhedron_prog_incr_builder.cpp
  92. Polyhedron load_obj(const std::string &filepath) {
  93.   Polyhedron poly;
  94.  
  95.   std::ifstream ifs(filepath);
  96.   build_mesh<HalfedgeDS> bm(ifs);
  97.   poly.delegate(bm);
  98.  
  99.   ifs.close();
  100.   return poly;
  101. }
  102.  
  103. void export_obj(const std::string &filepath, const Polyhedron &poly) {
  104.   std::ofstream ofs(filepath);
  105.   CGAL::print_polyhedron_wavefront(ofs, poly);
  106.   ofs.close();
  107. }
  108.  
  109. // Ref:
  110. //  Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h line 327
  111. void clip_to_bbox(Polyhedron &poly, const CGAL::Bbox_3 &bbox) {
  112.   if (boost::begin(faces(poly)) == boost::end(faces(poly)))
  113.     return;
  114.  
  115.   Polyhedron clipper;
  116.  
  117.   // everything is on positive side of this plane
  118.   Kernel::Plane_3 plane(1, 0, 0, std::numeric_limits<double>::min());
  119.  
  120.   auto default_np = CGAL::Polygon_mesh_processing::parameters::all_default();
  121.   CGAL::Oriented_side os =
  122.       CGAL::Polygon_mesh_processing::internal::clip_to_bbox(
  123.           plane, bbox, clipper, default_np);
  124.  
  125.   switch (os) {
  126.   case CGAL::ON_NEGATIVE_SIDE:
  127.     return; // nothing to clip, the full mesh is on the negative side
  128.   case CGAL::ON_POSITIVE_SIDE:
  129.     clear(poly); // clear the mesh that is fully on the positive side
  130.     return;
  131.   default:
  132.     break;
  133.   }
  134.  
  135.   // dispatch is needed because face index map for poly and clipper have to be
  136.   // of the same time
  137.   CGAL::Polygon_mesh_processing::internal::dispatch_clip_call(
  138.       poly, clipper, default_np,
  139.       CGAL::graph_has_property<Polyhedron, CGAL::face_index_t>());
  140. }
  141.  
  142. int main(int argc, char *argv[]) {
  143.   Polyhedron poly = load_obj(argv[1]);
  144.   std::cout << "Loaded mesh (V=" << poly.size_of_vertices()
  145.             << ", F=" << poly.size_of_facets() << ")" << std::endl;
  146.  
  147.   CGAL::Bbox_3 bbox(-100, -0.8, -0.4, 100, 0.8, 0.4);
  148.   clip_to_bbox(poly, bbox);
  149.  
  150.   export_obj(argv[2], poly);
  151.   std::cout << "Wrote to " << argv[2] << std::endl;
  152.  
  153.   return 0;
  154. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement