240 lines
5.5 KiB
C++
240 lines
5.5 KiB
C++
|
// 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:
|
||
|
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include <carve/carve.hpp>
|
||
|
#include <carve/poly.hpp>
|
||
|
#include <carve/polyline.hpp>
|
||
|
#include <carve/pointset.hpp>
|
||
|
|
||
|
|
||
|
|
||
|
namespace carve {
|
||
|
namespace input {
|
||
|
|
||
|
struct Data {
|
||
|
Data() {
|
||
|
}
|
||
|
|
||
|
virtual ~Data() {
|
||
|
}
|
||
|
|
||
|
virtual void transform(const carve::math::Matrix &transform) {
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
struct VertexData : public Data {
|
||
|
std::vector<carve::geom3d::Vector> points;
|
||
|
|
||
|
VertexData() : Data() {
|
||
|
}
|
||
|
|
||
|
virtual ~VertexData() {
|
||
|
}
|
||
|
|
||
|
virtual void transform(const carve::math::Matrix &transform) {
|
||
|
for (size_t i = 0; i < points.size(); ++i) {
|
||
|
points[i] *= transform;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
size_t addVertex(carve::geom3d::Vector point) {
|
||
|
size_t index = points.size();
|
||
|
points.push_back(point);
|
||
|
return index;
|
||
|
}
|
||
|
|
||
|
inline void reserveVertices(int count) {
|
||
|
points.reserve(count);
|
||
|
}
|
||
|
|
||
|
size_t getVertexCount() const {
|
||
|
return points.size();
|
||
|
}
|
||
|
|
||
|
const carve::geom3d::Vector &getVertex(int index) const {
|
||
|
return points[index];
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
struct PolyhedronData : public VertexData {
|
||
|
std::vector<int> faceIndices;
|
||
|
int faceCount;
|
||
|
|
||
|
PolyhedronData() : VertexData(), faceIndices(), faceCount(0) {
|
||
|
}
|
||
|
|
||
|
virtual ~PolyhedronData() {
|
||
|
}
|
||
|
|
||
|
void reserveFaces(int count, int avgFaceSize) {
|
||
|
faceIndices.reserve(faceIndices.size() + count * (1 + avgFaceSize));
|
||
|
}
|
||
|
|
||
|
int getFaceCount() const {
|
||
|
return faceCount;
|
||
|
}
|
||
|
|
||
|
template <typename Iter>
|
||
|
void addFace(Iter begin, Iter end) {
|
||
|
size_t n = std::distance(begin, end);
|
||
|
faceIndices.reserve(faceIndices.size() + n + 1);
|
||
|
faceIndices.push_back(n);
|
||
|
std::copy(begin, end, std::back_inserter(faceIndices));
|
||
|
++faceCount;
|
||
|
}
|
||
|
|
||
|
void addFace(int a, int b, int c) {
|
||
|
faceIndices.push_back(3);
|
||
|
faceIndices.push_back(a);
|
||
|
faceIndices.push_back(b);
|
||
|
faceIndices.push_back(c);
|
||
|
++faceCount;
|
||
|
}
|
||
|
|
||
|
void addFace(int a, int b, int c, int d) {
|
||
|
faceIndices.push_back(4);
|
||
|
faceIndices.push_back(a);
|
||
|
faceIndices.push_back(b);
|
||
|
faceIndices.push_back(c);
|
||
|
faceIndices.push_back(d);
|
||
|
++faceCount;
|
||
|
}
|
||
|
|
||
|
void clearFaces() {
|
||
|
faceIndices.clear();
|
||
|
faceCount = 0;
|
||
|
}
|
||
|
|
||
|
carve::poly::Polyhedron *create() const {
|
||
|
return new carve::poly::Polyhedron(points, faceCount, faceIndices);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
struct PolylineSetData : public VertexData {
|
||
|
typedef std::pair<bool, std::vector<int> > polyline_data_t;
|
||
|
std::list<polyline_data_t> polylines;
|
||
|
|
||
|
PolylineSetData() : VertexData(), polylines() {
|
||
|
}
|
||
|
|
||
|
virtual ~PolylineSetData() {
|
||
|
}
|
||
|
|
||
|
void beginPolyline(bool closed = false) {
|
||
|
polylines.push_back(std::make_pair(closed, std::vector<int>()));
|
||
|
}
|
||
|
|
||
|
void reservePolyline(size_t len) {
|
||
|
polylines.back().second.reserve(len);
|
||
|
}
|
||
|
|
||
|
void addPolylineIndex(int idx) {
|
||
|
polylines.back().second.push_back(idx);
|
||
|
}
|
||
|
|
||
|
carve::line::PolylineSet *create() const {
|
||
|
carve::line::PolylineSet *p = new carve::line::PolylineSet(points);
|
||
|
|
||
|
for (std::list<polyline_data_t>::const_iterator i = polylines.begin();
|
||
|
i != polylines.end();
|
||
|
++i) {
|
||
|
p->addPolyline((*i).first, (*i).second.begin(), (*i).second.end());
|
||
|
}
|
||
|
return p;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
struct PointSetData : public VertexData {
|
||
|
|
||
|
PointSetData() : VertexData() {
|
||
|
}
|
||
|
|
||
|
virtual ~PointSetData() {
|
||
|
}
|
||
|
|
||
|
carve::point::PointSet *create() const {
|
||
|
carve::point::PointSet *p = new carve::point::PointSet(points);
|
||
|
return p;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
class Input {
|
||
|
public:
|
||
|
std::list<Data *> input;
|
||
|
|
||
|
Input() {
|
||
|
}
|
||
|
|
||
|
~Input() {
|
||
|
for (std::list<Data *>::iterator i = input.begin(); i != input.end(); ++i) {
|
||
|
delete (*i);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void addDataBlock(Data *data) {
|
||
|
input.push_back(data);
|
||
|
}
|
||
|
|
||
|
void transform(const carve::math::Matrix &transform) {
|
||
|
if (transform == carve::math::Matrix::IDENT()) return;
|
||
|
for (std::list<Data *>::iterator i = input.begin(); i != input.end(); ++i) {
|
||
|
(*i)->transform(transform);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
template<typename T>
|
||
|
static inline T *create(Data *d) {
|
||
|
return NULL;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template<>
|
||
|
inline carve::poly::Polyhedron *Input::create(Data *d) {
|
||
|
PolyhedronData *p = dynamic_cast<PolyhedronData *>(d);
|
||
|
if (p == NULL) return NULL;
|
||
|
return p->create();
|
||
|
}
|
||
|
|
||
|
template<>
|
||
|
inline carve::line::PolylineSet *Input::create(Data *d) {
|
||
|
PolylineSetData *p = dynamic_cast<PolylineSetData *>(d);
|
||
|
if (p == NULL) return NULL;
|
||
|
return p->create();
|
||
|
}
|
||
|
|
||
|
template<>
|
||
|
inline carve::point::PointSet *Input::create(Data *d) {
|
||
|
PointSetData *p = dynamic_cast<PointSetData *>(d);
|
||
|
if (p == NULL) return NULL;
|
||
|
return p->create();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|