mirror of https://github.com/vitalif/openscad
Added a separate component for dealing with vertex reindexing
parent
6ae42bd0e7
commit
0c65fec41a
|
@ -375,6 +375,7 @@ cgal {
|
|||
HEADERS += src/cgal.h \
|
||||
src/cgalfwd.h \
|
||||
src/cgalutils.h \
|
||||
src/Reindexer.h \
|
||||
src/CGALCache.h \
|
||||
src/CGALRenderer.h \
|
||||
src/CGAL_Nef_polyhedron.h \
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
#ifndef REINDEXER_H_
|
||||
#define REINDEXER_H_
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/functional.hpp>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
/*!
|
||||
Reindexes a collection of elements of type T.
|
||||
Typically used to compress an element array by creating and reusing indexes to
|
||||
a new array or to merge two index tables to two arrays into a common index.
|
||||
The latter is necessary for VBO's or for unifying texture coordinate indices to
|
||||
multiple texture coordinate arrays.
|
||||
*/
|
||||
template<typename T>
|
||||
class Reindexer
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
Looks up a value. Will insert the value if it doesn't already exist.
|
||||
Returns the new index. */
|
||||
int lookup(const T &val) {
|
||||
typename boost::unordered_map<T, int>::const_iterator iter = this->map.find(val);
|
||||
if (iter != this->map.end()) return iter->second;
|
||||
else {
|
||||
this->map.insert(std::make_pair(val, this->map.size()));
|
||||
return this->map.size() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the current size of the new element array
|
||||
*/
|
||||
std::size_t size() const {
|
||||
return this->map.size();
|
||||
}
|
||||
|
||||
/*!
|
||||
Return the new element array.
|
||||
*/
|
||||
const T *getArray() {
|
||||
this->vec.resize(this->map.size());
|
||||
typename boost::unordered_map<T, int>::const_iterator iter = this->map.begin();
|
||||
while (iter != this->map.end()) {
|
||||
this->vec[iter->second] = iter->first;
|
||||
iter++;
|
||||
}
|
||||
return &this->vec[0];
|
||||
}
|
||||
|
||||
/*!
|
||||
Copies the internal vector to the given destination
|
||||
*/
|
||||
void copy(std::vector<T> &dest) {
|
||||
this->getArray();
|
||||
dest.resize(this->vec.size());
|
||||
std::copy(this->vec.begin(), this->vec.end(), dest.begin());
|
||||
}
|
||||
|
||||
private:
|
||||
boost::unordered_map<T, int> map;
|
||||
std::vector<T> vec;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -10,6 +10,7 @@
|
|||
#include "cgal.h"
|
||||
#include <CGAL/convex_hull_3.h>
|
||||
#include "svg.h"
|
||||
#include "Reindexer.h"
|
||||
|
||||
#include <map>
|
||||
#include <boost/foreach.hpp>
|
||||
|
@ -261,10 +262,18 @@ bool createPolySetFromPolyhedron(const CGAL_Polyhedron &p, PolySet &ps)
|
|||
|
||||
#undef GEN_SURFACE_DEBUG
|
||||
|
||||
namespace Eigen {
|
||||
size_t hash_value(Vector3d const &v) {
|
||||
size_t seed = 0;
|
||||
for (int i=0;i<3;i++) boost::hash_combine(seed, v[i]);
|
||||
return seed;
|
||||
}
|
||||
}
|
||||
|
||||
class CGAL_Build_PolySet : public CGAL::Modifier_base<CGAL_HDS>
|
||||
{
|
||||
public:
|
||||
typedef CGAL_HDS::Vertex::Point CGALPoint;
|
||||
typedef CGAL_Polybuilder::Point_3 CGALPoint;
|
||||
|
||||
const PolySet &ps;
|
||||
CGAL_Build_PolySet(const PolySet &ps) : ps(ps) { }
|
||||
|
@ -273,8 +282,7 @@ public:
|
|||
{
|
||||
CGAL_Polybuilder B(hds, true);
|
||||
typedef boost::tuple<double, double, double> BuilderVertex;
|
||||
typedef std::map<BuilderVertex, size_t> BuilderMap;
|
||||
BuilderMap vertices;
|
||||
Reindexer<Vector3d> vertices;
|
||||
std::vector<size_t> indices(3);
|
||||
|
||||
// Estimating same # of vertices as polygons (very rough)
|
||||
|
@ -285,14 +293,11 @@ public:
|
|||
if (pidx++ > 0) printf(",");
|
||||
indices.clear();
|
||||
BOOST_FOREACH(const Vector3d &v, p) {
|
||||
size_t idx;
|
||||
BuilderVertex bv = boost::make_tuple(v[0], v[1], v[2]);
|
||||
if (vertices.count(bv) > 0) indices.push_back(vertices[bv]);
|
||||
else {
|
||||
indices.push_back(vertices.size());
|
||||
vertices[bv] = vertices.size();
|
||||
B.add_vertex(CGALPoint(v[0], v[1], v[2]));
|
||||
}
|
||||
size_t s = vertices.size();
|
||||
size_t idx = vertices.lookup(v);
|
||||
// If we added a vertex, also add it to the CGAL builder
|
||||
if (idx == s) B.add_vertex(CGALPoint(v[0], v[1], v[2]));
|
||||
indices.push_back(idx);
|
||||
}
|
||||
std::map<size_t,int> fc;
|
||||
bool facet_is_degenerate = false;
|
||||
|
@ -317,13 +322,10 @@ public:
|
|||
printf("],\n");
|
||||
|
||||
printf("points=[");
|
||||
int vidx = 0;
|
||||
for (int vidx=0;vidx<vertices.size();vidx++) {
|
||||
if (vidx > 0) printf(",");
|
||||
const BuilderMap::const_iterator it =
|
||||
std::find_if(vertices.begin(), vertices.end(),
|
||||
boost::bind(&BuilderMap::value_type::second, _1) == vidx);
|
||||
printf("[%g,%g,%g]", it->first.get<0>(), it->first.get<1>(), it->first.get<2>());
|
||||
const Vector3d &v = vertices.getArray()[vidx];
|
||||
printf("[%g,%g,%g]", v[0], v[1], v[2]);
|
||||
}
|
||||
printf("]);\n");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue