Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <CGAL/IO/print_wavefront.h>
- #include <CGAL/Polygon_mesh_processing/clip.h>
- #include <CGAL/Polyhedron_3.h>
- #include <CGAL/Polyhedron_incremental_builder_3.h>
- #include <CGAL/Simple_cartesian.h>
- #include <CGAL/polyhedron_cut_plane_3.h>
- typedef CGAL::Simple_cartesian<double> Kernel;
- typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
- typedef Polyhedron::HalfedgeDS HalfedgeDS;
- template <class HDS> class build_mesh : public CGAL::Modifier_base<HDS> {
- public:
- explicit build_mesh(std::ifstream &ifs) : ifs(ifs) {}
- void operator()(HDS &hds) override {
- // Post-condition: `hds' is a valid polyhedral surface.
- CGAL::Polyhedron_incremental_builder_3<HDS> B(hds, true);
- std::vector<vec3d> V;
- std::vector<vec3i> F;
- std::tie(V, F) = parse_obj();
- B.begin_surface(V.size(), F.size());
- typedef typename HDS::Vertex Vertex;
- typedef typename Vertex::Point Point;
- std::for_each(V.begin(), V.end(), [&B](const vec3d &pos) {
- B.add_vertex(Point(pos[0], pos[1], pos[2]));
- });
- std::for_each(F.begin(), F.end(), [&B](const vec3i &face) {
- B.begin_facet();
- std::for_each(face.begin(), face.end(),
- [&B](unsigned int v) { B.add_vertex_to_facet(v); });
- B.end_facet();
- });
- B.end_surface();
- }
- private:
- typedef std::array<double, 3> vec3d;
- typedef std::array<unsigned int, 3> vec3i;
- std::ifstream &ifs;
- std::pair<std::vector<vec3d>, std::vector<vec3i>> parse_obj() {
- std::vector<vec3d> positions;
- std::vector<vec3i> indices;
- std::string lead;
- for (std::string line; std::getline(ifs, line);) {
- if (line[0] == '#')
- continue;
- lead = "";
- std::stringstream ss(line);
- ss >> lead;
- if (lead == "v") {
- double x, y, z;
- ss >> x >> y >> z;
- positions.push_back({x, y, z});
- } else if (lead == "f") {
- vec3i face;
- for (int i = 0; i < 3; ++i) {
- ss >> face[i];
- char ch;
- do {
- ch = ss.get();
- } while (!ss.eof() && ch != ' ');
- }
- for (int i = 0; i < 3; ++i)
- --face[i];
- indices.push_back(face);
- }
- }
- return {positions, indices};
- }
- };
- // Ref:
- // Polyhedron/examples/Polyhedron/polyhedron_prog_incr_builder.cpp
- Polyhedron load_obj(const std::string &filepath) {
- Polyhedron poly;
- std::ifstream ifs(filepath);
- build_mesh<HalfedgeDS> bm(ifs);
- poly.delegate(bm);
- ifs.close();
- return poly;
- }
- void export_obj(const std::string &filepath, const Polyhedron &poly) {
- std::ofstream ofs(filepath);
- CGAL::print_polyhedron_wavefront(ofs, poly);
- ofs.close();
- }
- // Ref:
- // Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h line 327
- void clip_to_bbox(Polyhedron &poly, const CGAL::Bbox_3 &bbox) {
- if (boost::begin(faces(poly)) == boost::end(faces(poly)))
- return;
- Polyhedron clipper;
- // everything is on positive side of this plane
- Kernel::Plane_3 plane(1, 0, 0, std::numeric_limits<double>::min());
- auto default_np = CGAL::Polygon_mesh_processing::parameters::all_default();
- CGAL::Oriented_side os =
- CGAL::Polygon_mesh_processing::internal::clip_to_bbox(
- plane, bbox, clipper, default_np);
- switch (os) {
- case CGAL::ON_NEGATIVE_SIDE:
- return; // nothing to clip, the full mesh is on the negative side
- case CGAL::ON_POSITIVE_SIDE:
- clear(poly); // clear the mesh that is fully on the positive side
- return;
- default:
- break;
- }
- // dispatch is needed because face index map for poly and clipper have to be
- // of the same time
- CGAL::Polygon_mesh_processing::internal::dispatch_clip_call(
- poly, clipper, default_np,
- CGAL::graph_has_property<Polyhedron, CGAL::face_index_t>());
- }
- int main(int argc, char *argv[]) {
- Polyhedron poly = load_obj(argv[1]);
- std::cout << "Loaded mesh (V=" << poly.size_of_vertices()
- << ", F=" << poly.size_of_facets() << ")" << std::endl;
- CGAL::Bbox_3 bbox(-100, -0.8, -0.4, 100, 0.8, 0.4);
- clip_to_bbox(poly, bbox);
- export_obj(argv[2], poly);
- std::cout << "Wrote to " << argv[2] << std::endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement