Polished up the tesselator.
This commit is contained in:
parent
e3ed05491e
commit
f22926649c
@ -8,12 +8,22 @@ namespace Slic3r {
|
|||||||
|
|
||||||
class GluTessWrapper {
|
class GluTessWrapper {
|
||||||
public:
|
public:
|
||||||
|
GluTessWrapper() : m_tesselator(gluNewTess()) {
|
||||||
|
// register callback functions
|
||||||
|
gluTessCallback(m_tesselator, GLU_TESS_BEGIN_DATA, (_GLUfuncptr)tessBeginCB);
|
||||||
|
gluTessCallback(m_tesselator, GLU_TESS_END_DATA, (_GLUfuncptr)tessEndCB);
|
||||||
|
gluTessCallback(m_tesselator, GLU_TESS_ERROR_DATA, (_GLUfuncptr)tessErrorCB);
|
||||||
|
gluTessCallback(m_tesselator, GLU_TESS_VERTEX_DATA, (_GLUfuncptr)tessVertexCB);
|
||||||
|
gluTessCallback(m_tesselator, GLU_TESS_COMBINE_DATA, (_GLUfuncptr)tessCombineCB);
|
||||||
|
}
|
||||||
|
~GluTessWrapper() {
|
||||||
|
gluDeleteTess(m_tesselator);
|
||||||
|
}
|
||||||
|
|
||||||
Pointf3s tesselate(const ExPolygon &expoly, double z_, bool flipped_)
|
Pointf3s tesselate(const ExPolygon &expoly, double z_, bool flipped_)
|
||||||
{
|
{
|
||||||
z = z_;
|
m_z = z_;
|
||||||
flipped = flipped_;
|
m_flipped = flipped_;
|
||||||
triangles.clear();
|
|
||||||
intersection_points.clear();
|
|
||||||
std::vector<GLdouble> coords;
|
std::vector<GLdouble> coords;
|
||||||
{
|
{
|
||||||
size_t num_coords = expoly.contour.points.size();
|
size_t num_coords = expoly.contour.points.size();
|
||||||
@ -21,54 +31,35 @@ public:
|
|||||||
num_coords += poly.points.size();
|
num_coords += poly.points.size();
|
||||||
coords.reserve(num_coords * 3);
|
coords.reserve(num_coords * 3);
|
||||||
}
|
}
|
||||||
GLUtesselator *tess = gluNewTess(); // create a tessellator
|
gluTessBeginPolygon(m_tesselator, (void*)this);
|
||||||
// register callback functions
|
gluTessBeginContour(m_tesselator);
|
||||||
#ifndef _GLUfuncptr
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
typedef void (__stdcall *_GLUfuncptr)(void);
|
|
||||||
#else /* _MSC_VER */
|
|
||||||
#ifdef GLAPIENTRYP
|
|
||||||
typedef void (GLAPIENTRYP _GLUfuncptr)(void);
|
|
||||||
#else /* GLAPIENTRYP */
|
|
||||||
typedef void (*_GLUfuncptr)(void);
|
|
||||||
#endif
|
|
||||||
#endif /* _MSC_VER */
|
|
||||||
#endif /* _GLUfuncptr */
|
|
||||||
gluTessCallback(tess, GLU_TESS_BEGIN_DATA, (_GLUfuncptr)tessBeginCB);
|
|
||||||
gluTessCallback(tess, GLU_TESS_END_DATA, (_GLUfuncptr)tessEndCB);
|
|
||||||
gluTessCallback(tess, GLU_TESS_ERROR_DATA, (_GLUfuncptr)tessErrorCB);
|
|
||||||
gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (_GLUfuncptr)tessVertexCB);
|
|
||||||
gluTessCallback(tess, GLU_TESS_COMBINE_DATA, (_GLUfuncptr)tessCombineCB);
|
|
||||||
gluTessBeginPolygon(tess, (void*)this);
|
|
||||||
gluTessBeginContour(tess);
|
|
||||||
for (const Point &pt : expoly.contour.points) {
|
for (const Point &pt : expoly.contour.points) {
|
||||||
coords.emplace_back(unscale<double>(pt[0]));
|
coords.emplace_back(unscale<double>(pt[0]));
|
||||||
coords.emplace_back(unscale<double>(pt[1]));
|
coords.emplace_back(unscale<double>(pt[1]));
|
||||||
coords.emplace_back(0.);
|
coords.emplace_back(0.);
|
||||||
gluTessVertex(tess, &coords[coords.size() - 3], &coords[coords.size() - 3]);
|
gluTessVertex(m_tesselator, &coords[coords.size() - 3], &coords[coords.size() - 3]);
|
||||||
}
|
}
|
||||||
gluTessEndContour(tess);
|
gluTessEndContour(m_tesselator);
|
||||||
for (const Polygon &poly : expoly.holes) {
|
for (const Polygon &poly : expoly.holes) {
|
||||||
gluTessBeginContour(tess);
|
gluTessBeginContour(m_tesselator);
|
||||||
for (const Point &pt : poly.points) {
|
for (const Point &pt : poly.points) {
|
||||||
coords.emplace_back(unscale<double>(pt[0]));
|
coords.emplace_back(unscale<double>(pt[0]));
|
||||||
coords.emplace_back(unscale<double>(pt[1]));
|
coords.emplace_back(unscale<double>(pt[1]));
|
||||||
coords.emplace_back(0.);
|
coords.emplace_back(0.);
|
||||||
gluTessVertex(tess, &coords[coords.size() - 3], &coords[coords.size() - 3]);
|
gluTessVertex(m_tesselator, &coords[coords.size() - 3], &coords[coords.size() - 3]);
|
||||||
}
|
}
|
||||||
gluTessEndContour(tess);
|
gluTessEndContour(m_tesselator);
|
||||||
}
|
}
|
||||||
gluTessEndPolygon(tess);
|
gluTessEndPolygon(m_tesselator);
|
||||||
gluDeleteTess(tess);
|
m_output_triangles.clear();
|
||||||
return std::move(triangles);
|
m_intersection_points.clear();
|
||||||
|
return std::move(m_output_triangles);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pointf3s tesselate(const ExPolygons &expolygons, double z_, bool flipped_)
|
Pointf3s tesselate(const ExPolygons &expolygons, double z_, bool flipped_)
|
||||||
{
|
{
|
||||||
z = z_;
|
m_z = z_;
|
||||||
flipped = flipped_;
|
m_flipped = flipped_;
|
||||||
triangles.clear();
|
|
||||||
intersection_points.clear();
|
|
||||||
std::vector<GLdouble> coords;
|
std::vector<GLdouble> coords;
|
||||||
{
|
{
|
||||||
size_t num_coords = 0;
|
size_t num_coords = 0;
|
||||||
@ -80,49 +71,32 @@ public:
|
|||||||
}
|
}
|
||||||
coords.assign(num_coords * 3, 0);
|
coords.assign(num_coords * 3, 0);
|
||||||
}
|
}
|
||||||
GLUtesselator *tess = gluNewTess(); // create a tessellator
|
|
||||||
// register callback functions
|
|
||||||
#ifndef _GLUfuncptr
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
typedef void (__stdcall *_GLUfuncptr)(void);
|
|
||||||
#else /* _MSC_VER */
|
|
||||||
#ifdef GLAPIENTRYP
|
|
||||||
typedef void (GLAPIENTRYP _GLUfuncptr)(void);
|
|
||||||
#else /* GLAPIENTRYP */
|
|
||||||
typedef void (*_GLUfuncptr)(void);
|
|
||||||
#endif
|
|
||||||
#endif /* _MSC_VER */
|
|
||||||
#endif /* _GLUfuncptr */
|
|
||||||
gluTessCallback(tess, GLU_TESS_BEGIN_DATA, (_GLUfuncptr)tessBeginCB);
|
|
||||||
gluTessCallback(tess, GLU_TESS_END_DATA, (_GLUfuncptr)tessEndCB);
|
|
||||||
gluTessCallback(tess, GLU_TESS_ERROR_DATA, (_GLUfuncptr)tessErrorCB);
|
|
||||||
gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (_GLUfuncptr)tessVertexCB);
|
|
||||||
gluTessCallback(tess, GLU_TESS_COMBINE_DATA, (_GLUfuncptr)tessCombineCB);
|
|
||||||
for (const ExPolygon &expoly : expolygons) {
|
for (const ExPolygon &expoly : expolygons) {
|
||||||
gluTessBeginPolygon(tess, (void*)this);
|
gluTessBeginPolygon(m_tesselator, (void*)this);
|
||||||
gluTessBeginContour(tess);
|
gluTessBeginContour(m_tesselator);
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
for (const Point &pt : expoly.contour.points) {
|
for (const Point &pt : expoly.contour.points) {
|
||||||
coords[idx ++] = unscale<double>(pt[0]);
|
coords[idx ++] = unscale<double>(pt[0]);
|
||||||
coords[idx ++] = unscale<double>(pt[1]);
|
coords[idx ++] = unscale<double>(pt[1]);
|
||||||
coords[idx ++] = 0.;
|
coords[idx ++] = 0.;
|
||||||
gluTessVertex(tess, &coords[idx - 3], &coords[idx - 3]);
|
gluTessVertex(m_tesselator, &coords[idx - 3], &coords[idx - 3]);
|
||||||
}
|
}
|
||||||
gluTessEndContour(tess);
|
gluTessEndContour(m_tesselator);
|
||||||
for (const Polygon &poly : expoly.holes) {
|
for (const Polygon &poly : expoly.holes) {
|
||||||
gluTessBeginContour(tess);
|
gluTessBeginContour(m_tesselator);
|
||||||
for (const Point &pt : poly.points) {
|
for (const Point &pt : poly.points) {
|
||||||
coords[idx ++] = unscale<double>(pt[0]);
|
coords[idx ++] = unscale<double>(pt[0]);
|
||||||
coords[idx ++] = unscale<double>(pt[1]);
|
coords[idx ++] = unscale<double>(pt[1]);
|
||||||
coords[idx ++] = 0.;
|
coords[idx ++] = 0.;
|
||||||
gluTessVertex(tess, &coords[idx - 3], &coords[idx - 3]);
|
gluTessVertex(m_tesselator, &coords[idx - 3], &coords[idx - 3]);
|
||||||
}
|
}
|
||||||
gluTessEndContour(tess);
|
gluTessEndContour(m_tesselator);
|
||||||
}
|
}
|
||||||
gluTessEndPolygon(tess);
|
gluTessEndPolygon(m_tesselator);
|
||||||
}
|
}
|
||||||
gluDeleteTess(tess);
|
m_output_triangles.clear();
|
||||||
return std::move(triangles);
|
m_intersection_points.clear();
|
||||||
|
return std::move(m_output_triangles);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -136,15 +110,13 @@ private:
|
|||||||
void tessBegin(GLenum which)
|
void tessBegin(GLenum which)
|
||||||
{
|
{
|
||||||
assert(which == GL_TRIANGLES || which == GL_TRIANGLE_FAN || which == GL_TRIANGLE_STRIP);
|
assert(which == GL_TRIANGLES || which == GL_TRIANGLE_FAN || which == GL_TRIANGLE_STRIP);
|
||||||
if (!(which == GL_TRIANGLES || which == GL_TRIANGLE_FAN || which == GL_TRIANGLE_STRIP))
|
m_primitive_type = which;
|
||||||
printf("Co je to za haluz!?\n");
|
m_num_points = 0;
|
||||||
primitive_type = which;
|
|
||||||
num_points = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tessEnd()
|
void tessEnd()
|
||||||
{
|
{
|
||||||
num_points = 0;
|
m_num_points = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tessVertex(const GLvoid *data)
|
void tessVertex(const GLvoid *data)
|
||||||
@ -152,42 +124,42 @@ private:
|
|||||||
if (data == nullptr)
|
if (data == nullptr)
|
||||||
return;
|
return;
|
||||||
const GLdouble *ptr = (const GLdouble*)data;
|
const GLdouble *ptr = (const GLdouble*)data;
|
||||||
++ num_points;
|
++ m_num_points;
|
||||||
if (num_points == 1) {
|
if (m_num_points == 1) {
|
||||||
memcpy(pt0, ptr, sizeof(GLdouble) * 3);
|
memcpy(m_pt0, ptr, sizeof(GLdouble) * 3);
|
||||||
} else if (num_points == 2) {
|
} else if (m_num_points == 2) {
|
||||||
memcpy(pt1, ptr, sizeof(GLdouble) * 3);
|
memcpy(m_pt1, ptr, sizeof(GLdouble) * 3);
|
||||||
} else {
|
} else {
|
||||||
bool flip = flipped;
|
bool flip = m_flipped;
|
||||||
if (primitive_type == GL_TRIANGLE_STRIP && num_points == 4) {
|
if (m_primitive_type == GL_TRIANGLE_STRIP && m_num_points == 4) {
|
||||||
flip = !flip;
|
flip = !flip;
|
||||||
num_points = 2;
|
m_num_points = 2;
|
||||||
}
|
}
|
||||||
triangles.emplace_back(pt0[0], pt0[1], z);
|
m_output_triangles.emplace_back(m_pt0[0], m_pt0[1], m_z);
|
||||||
if (flip) {
|
if (flip) {
|
||||||
triangles.emplace_back(ptr[0], ptr[1], z);
|
m_output_triangles.emplace_back(ptr[0], ptr[1], m_z);
|
||||||
triangles.emplace_back(pt1[0], pt1[1], z);
|
m_output_triangles.emplace_back(m_pt1[0], m_pt1[1], m_z);
|
||||||
} else {
|
} else {
|
||||||
triangles.emplace_back(pt1[0], pt1[1], z);
|
m_output_triangles.emplace_back(m_pt1[0], m_pt1[1], m_z);
|
||||||
triangles.emplace_back(ptr[0], ptr[1], z);
|
m_output_triangles.emplace_back(ptr[0], ptr[1], m_z);
|
||||||
}
|
}
|
||||||
if (primitive_type == GL_TRIANGLE_STRIP) {
|
if (m_primitive_type == GL_TRIANGLE_STRIP) {
|
||||||
memcpy(pt0, pt1, sizeof(GLdouble) * 3);
|
memcpy(m_pt0, m_pt1, sizeof(GLdouble) * 3);
|
||||||
memcpy(pt1, ptr, sizeof(GLdouble) * 3);
|
memcpy(m_pt1, ptr, sizeof(GLdouble) * 3);
|
||||||
} else if (primitive_type == GL_TRIANGLE_FAN) {
|
} else if (m_primitive_type == GL_TRIANGLE_FAN) {
|
||||||
memcpy(pt1, ptr, sizeof(GLdouble) * 3);
|
memcpy(m_pt1, ptr, sizeof(GLdouble) * 3);
|
||||||
} else {
|
} else {
|
||||||
assert(primitive_type == GL_TRIANGLES);
|
assert(m_primitive_type == GL_TRIANGLES);
|
||||||
assert(num_points == 3);
|
assert(m_num_points == 3);
|
||||||
num_points = 0;
|
m_num_points = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tessCombine(const GLdouble newVertex[3], const GLdouble *neighborVertex[4], const GLfloat neighborWeight[4], GLdouble **outData)
|
void tessCombine(const GLdouble newVertex[3], const GLdouble *neighborVertex[4], const GLfloat neighborWeight[4], GLdouble **outData)
|
||||||
{
|
{
|
||||||
intersection_points.emplace_back(newVertex[0], newVertex[1], newVertex[2]);
|
m_intersection_points.emplace_back(newVertex[0], newVertex[1], m_z);
|
||||||
*outData = intersection_points.back().data();
|
*outData = m_intersection_points.back().data();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tessError(GLenum errorCode)
|
static void tessError(GLenum errorCode)
|
||||||
@ -197,14 +169,24 @@ private:
|
|||||||
// printf("Error: %s\n", (const char*)errorStr);
|
// printf("Error: %s\n", (const char*)errorStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLenum primitive_type;
|
// Instance owned over the life time of this wrapper.
|
||||||
GLdouble pt0[3];
|
GLUtesselator *m_tesselator;
|
||||||
GLdouble pt1[3];
|
|
||||||
int num_points;
|
// Currently processed primitive type.
|
||||||
Pointf3s triangles;
|
GLenum m_primitive_type;
|
||||||
std::deque<Vec3d> intersection_points;
|
// Two last vertices received for m_primitive_type. Used for processing triangle strips, fans etc.
|
||||||
double z;
|
GLdouble m_pt0[3];
|
||||||
bool flipped;
|
GLdouble m_pt1[3];
|
||||||
|
// Number of points processed over m_primitive_type.
|
||||||
|
int m_num_points;
|
||||||
|
// Triangles generated by the tesselator.
|
||||||
|
Pointf3s m_output_triangles;
|
||||||
|
// Intersection points generated by tessCombine callback. There should be none if the input contour is not self intersecting.
|
||||||
|
std::deque<Vec3d> m_intersection_points;
|
||||||
|
// Fixed third coordinate.
|
||||||
|
double m_z;
|
||||||
|
// Output triangles shall be flipped (normal points down).
|
||||||
|
bool m_flipped;
|
||||||
};
|
};
|
||||||
|
|
||||||
Pointf3s triangulate_expolygons_3df(const ExPolygon &poly, coordf_t z, bool flip)
|
Pointf3s triangulate_expolygons_3df(const ExPolygon &poly, coordf_t z, bool flip)
|
||||||
|
Loading…
Reference in New Issue
Block a user