// Begin License: // Copyright (C) 2006-2008 Tobias Sargeant (tobias.sargeant@gmail.com). // All rights reserved. // // This file is part of the Carve CSG Library (http://carve-csg.com/) // // This file may be used under the terms of the GNU General Public // License version 2.0 as published by the Free Software Foundation // and appearing in the file LICENSE.GPL2 included in the packaging of // this file. // // This file is provided "AS IS" with NO WARRANTY OF ANY KIND, // INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE. // End: #if defined(HAVE_CONFIG_H) # include #endif #include #include #include #include #include #include #include #include #ifndef WIN32 # include #endif namespace { struct line : public gloop::stream::null_reader { carve::input::PolylineSetData *data; line(carve::input::PolylineSetData *_data) : data(_data) { } virtual void length(int len) { } virtual void next() { data->beginPolyline(); } virtual void end() { } carve::input::PolylineSetData::polyline_data_t &curr() const { return data->polylines.back(); } }; struct line_closed : public gloop::stream::reader { line *l; line_closed(line *_l) : l(_l) { } virtual void value(bool val) { l->curr().first = val; } }; struct line_idx : public gloop::stream::reader { line *l; line_idx(line *_l) : l(_l) { } virtual void length(size_t len) { if (l) l->curr().second.reserve(len); } virtual void value(int val) { l->curr().second.push_back(val); } }; template struct vertex : public gloop::stream::null_reader { container_t &container; vertex(container_t &_container) : container(_container) { } virtual void next() { container.push_back(carve::geom3d::Vector()); } virtual void length(int l) { if (l > 0) container.reserve(container.size() + l); } virtual void end() { } carve::geom3d::Vector &curr() const { return container.back(); } }; template vertex *vertex_inserter(container_t &container) { return new vertex(container); } template struct vertex_component : public gloop::stream::reader { const curr_t *i; vertex_component(const curr_t *_i) : i(_i) { } virtual void value(double val) { i->curr().v[idx] = val; } }; template vertex_component *vertex_component_inserter(const curr_t *i) { return new vertex_component(i); } struct face : public gloop::stream::null_reader { carve::input::PolyhedronData *data; face(carve::input::PolyhedronData *_data) : data(_data) { } virtual void length(int l) { if (l > 0) data->reserveFaces(l, 3); } }; struct face_idx : public gloop::stream::reader { carve::input::PolyhedronData *data; mutable std::vector vidx; face_idx(carve::input::PolyhedronData *_data) : data(_data), vidx() { } virtual void length(int l) { vidx.clear(); vidx.reserve(l); } virtual void value(int val) { vidx.push_back(val); } virtual void end() { data->addFace(vidx.begin(), vidx.end()); } }; struct tristrip_idx : public gloop::stream::reader { carve::input::PolyhedronData *data; mutable int a, b, c; mutable bool clk; tristrip_idx(carve::input::PolyhedronData *_data) : data(_data), a(-1), b(-1), c(-1), clk(true) { } virtual void value(int val) { a = b; b = c; c = val; if (a == -1 || b == -1 || c == -1) { clk = true; } else { if (clk) { data->addFace(a, b, c); } else { data->addFace(c, b, a); } clk = !clk; } } virtual void length(int len) { data->reserveFaces(len - 2, 3); } }; struct begin_pointset : public gloop::stream::null_reader { gloop::stream::model_reader &sr; carve::input::Input &inputs; carve::input::PointSetData *data; begin_pointset(gloop::stream::model_reader &_sr, carve::input::Input &_inputs) : sr(_sr), inputs(_inputs) { } ~begin_pointset() { } virtual void begin() { data = new carve::input::PointSetData(); vertex > *vi = vertex_inserter(data->points); sr.addReader("pointset.vertex", vi); sr.addReader("pointset.vertex.x", vertex_component_inserter<0>(vi)); sr.addReader("pointset.vertex.y", vertex_component_inserter<1>(vi)); sr.addReader("pointset.vertex.z", vertex_component_inserter<2>(vi)); } virtual void end() { std::cerr << "pointset complete" << std::endl; inputs.addDataBlock(data); } virtual void fail() { delete data; } }; struct begin_polyline : public gloop::stream::null_reader { gloop::stream::model_reader &sr; carve::input::Input &inputs; carve::input::PolylineSetData *data; begin_polyline(gloop::stream::model_reader &_sr, carve::input::Input &_inputs) : sr(_sr), inputs(_inputs) { } ~begin_polyline() { } virtual void begin() { data = new carve::input::PolylineSetData(); vertex > *vi = vertex_inserter(data->points); sr.addReader("polyline.vertex", vi); sr.addReader("polyline.vertex.x", vertex_component_inserter<0>(vi)); sr.addReader("polyline.vertex.y", vertex_component_inserter<1>(vi)); sr.addReader("polyline.vertex.z", vertex_component_inserter<2>(vi)); line *li = new line(data); sr.addReader("polyline.polyline", li); sr.addReader("polyline.polyline.closed", new line_closed(li)); sr.addReader("polyline.polyline.vertex_indices", new line_idx(li)); } virtual void end() { inputs.addDataBlock(data); } virtual void fail() { delete data; } }; struct begin_polyhedron : public gloop::stream::null_reader { gloop::stream::model_reader &sr; carve::input::Input &inputs; carve::input::PolyhedronData *data; begin_polyhedron(gloop::stream::model_reader &_sr, carve::input::Input &_inputs) : sr(_sr), inputs(_inputs) { } ~begin_polyhedron() { } virtual void begin() { data = new carve::input::PolyhedronData(); vertex > *vi = vertex_inserter(data->points); sr.addReader("polyhedron.vertex", vi); sr.addReader("polyhedron.vertex.x", vertex_component_inserter<0>(vi)); sr.addReader("polyhedron.vertex.y", vertex_component_inserter<1>(vi)); sr.addReader("polyhedron.vertex.z", vertex_component_inserter<2>(vi)); sr.addReader("polyhedron.face", new face(data)); sr.addReader("polyhedron.face.vertex_indices", new face_idx(data)); sr.addReader("polyhedron.tristrips.vertex_indices", new tristrip_idx(data)); } virtual void end() { inputs.addDataBlock(data); } virtual void fail() { delete data; } }; void modelSetup(carve::input::Input &inputs, gloop::stream::model_reader &model) { model.addReader("polyhedron", new begin_polyhedron(model, inputs)); model.addReader("polyline", new begin_polyline(model, inputs)); model.addReader("pointset", new begin_pointset(model, inputs)); } } template bool readFile(std::istream &in, carve::input::Input &inputs, const carve::math::Matrix &transform) { filetype_t f; modelSetup(inputs, f); if (!f.read(in)) return false; inputs.transform(transform); return true; } template carve::poly::Polyhedron *readFile(std::istream &in, const carve::math::Matrix &transform) { carve::input::Input inputs; if (!readFile(in, inputs, transform)) { return false; } for (std::list::const_iterator i = inputs.input.begin(); i != inputs.input.end(); ++i) { carve::poly::Polyhedron *poly = inputs.create(*i); if (poly) return poly; } return NULL; } template bool readFile(const std::string &in_file, carve::input::Input &inputs, const carve::math::Matrix &transform = carve::math::Matrix::IDENT()) { std::ifstream in(in_file.c_str(),std::ios_base::binary | std::ios_base::in); if (!in.is_open()) { std::cerr << "File '" << in_file << "' could not be opened." << std::endl; return false; } std::cerr << "Loading " << in_file << "'" << std::endl; return readFile(in, inputs, transform); } template carve::poly::Polyhedron* readFile(const std::string &in_file, const carve::math::Matrix &transform = carve::math::Matrix::IDENT()) { std::ifstream in(in_file.c_str(),std::ios_base::binary | std::ios_base::in); if (!in.is_open()) { std::cerr << "File '" << in_file << "' could not be opened." << std::endl; return NULL; } std::cerr << "Loading '" << in_file << "'" << std::endl; return readFile(in, transform); } bool readPLY(std::istream &in, carve::input::Input &inputs, const carve::math::Matrix &transform) { return readFile(in, inputs, transform); } carve::poly::Polyhedron *readPLY(std::istream &in, const carve::math::Matrix &transform) { return readFile(in, transform); } bool readPLY(const std::string &in_file, carve::input::Input &inputs, const carve::math::Matrix &transform) { return readFile(in_file, inputs, transform); } carve::poly::Polyhedron *readPLY(const std::string &in_file, const carve::math::Matrix &transform) { return readFile(in_file, transform); } bool readOBJ(std::istream &in, carve::input::Input &inputs, const carve::math::Matrix &transform) { return readFile(in, inputs, transform); } carve::poly::Polyhedron *readOBJ(std::istream &in, const carve::math::Matrix &transform) { return readFile(in, transform); } bool readOBJ(const std::string &in_file, carve::input::Input &inputs, const carve::math::Matrix &transform) { return readFile(in_file, inputs, transform); } carve::poly::Polyhedron *readOBJ(const std::string &in_file, const carve::math::Matrix &transform) { return readFile(in_file, transform); } bool readVTK(std::istream &in, carve::input::Input &inputs, const carve::math::Matrix &transform) { return readFile(in, inputs, transform); } carve::poly::Polyhedron *readVTK(std::istream &in, const carve::math::Matrix &transform) { return readFile(in, transform); } bool readVTK(const std::string &in_file, carve::input::Input &inputs, const carve::math::Matrix &transform) { return readFile(in_file, inputs, transform); } carve::poly::Polyhedron *readVTK(const std::string &in_file, const carve::math::Matrix &transform) { return readFile(in_file, transform); }