2009-06-24 14:59:15 +04:00
|
|
|
/*
|
|
|
|
* OpenSCAD (www.openscad.at)
|
|
|
|
* Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define INCLUDE_ABSTRACT_NODE_DETAILS
|
|
|
|
|
|
|
|
#include "openscad.h"
|
2010-01-06 13:48:51 +03:00
|
|
|
#include "printutils.h"
|
2009-06-24 14:59:15 +04:00
|
|
|
|
2010-01-06 13:48:51 +03:00
|
|
|
QCache<QString,PolySet::ps_cache_entry> PolySet::ps_cache(100);
|
|
|
|
|
|
|
|
PolySet::ps_cache_entry::ps_cache_entry(PolySet *ps) :
|
|
|
|
ps(ps), msg(print_messages_stack.last()) { }
|
|
|
|
|
|
|
|
PolySet::ps_cache_entry::~ps_cache_entry() {
|
|
|
|
ps->unlink();
|
|
|
|
}
|
2009-07-28 22:17:29 +04:00
|
|
|
|
2009-06-24 14:59:15 +04:00
|
|
|
PolySet::PolySet()
|
|
|
|
{
|
2009-12-29 14:08:27 +03:00
|
|
|
is2d = false;
|
2009-07-15 01:47:32 +04:00
|
|
|
convexity = 1;
|
2009-07-28 16:53:52 +04:00
|
|
|
refcount = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
PolySet::~PolySet()
|
|
|
|
{
|
|
|
|
assert(refcount == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
PolySet* PolySet::link()
|
|
|
|
{
|
|
|
|
refcount++;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PolySet::unlink()
|
|
|
|
{
|
|
|
|
if (--refcount == 0)
|
|
|
|
delete this;
|
2009-06-24 14:59:15 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void PolySet::append_poly()
|
|
|
|
{
|
|
|
|
polygons.append(Polygon());
|
|
|
|
}
|
|
|
|
|
|
|
|
void PolySet::append_vertex(double x, double y, double z)
|
|
|
|
{
|
2009-07-21 23:33:39 +04:00
|
|
|
grid.align(x, y, z);
|
2009-06-24 14:59:15 +04:00
|
|
|
polygons.last().append(Point(x, y, z));
|
|
|
|
}
|
|
|
|
|
|
|
|
void PolySet::insert_vertex(double x, double y, double z)
|
|
|
|
{
|
2009-07-21 23:33:39 +04:00
|
|
|
grid.align(x, y, z);
|
2009-06-24 14:59:15 +04:00
|
|
|
polygons.last().insert(0, Point(x, y, z));
|
|
|
|
}
|
|
|
|
|
2010-01-09 20:15:56 +03:00
|
|
|
static void gl_draw_triangle(GLint *shaderinfo, const PolySet::Point *p0, const PolySet::Point *p1, const PolySet::Point *p2, bool e0, bool e1, bool e2, double z, bool mirrored)
|
2009-06-27 02:01:53 +04:00
|
|
|
{
|
2009-06-29 15:03:15 +04:00
|
|
|
double ax = p1->x - p0->x, bx = p1->x - p2->x;
|
|
|
|
double ay = p1->y - p0->y, by = p1->y - p2->y;
|
|
|
|
double az = p1->z - p0->z, bz = p1->z - p2->z;
|
|
|
|
double nx = ay*bz - az*by;
|
|
|
|
double ny = az*bx - ax*bz;
|
|
|
|
double nz = ax*by - ay*bx;
|
|
|
|
double nl = sqrt(nx*nx + ny*ny + nz*nz);
|
|
|
|
glNormal3d(nx / nl, ny / nl, nz / nl);
|
2009-06-27 02:01:53 +04:00
|
|
|
#ifdef ENABLE_OPENCSG
|
|
|
|
if (shaderinfo) {
|
|
|
|
double e0f = e0 ? 2.0 : -1.0;
|
|
|
|
double e1f = e1 ? 2.0 : -1.0;
|
|
|
|
double e2f = e2 ? 2.0 : -1.0;
|
|
|
|
glVertexAttrib3d(shaderinfo[3], e0f, e1f, e2f);
|
2009-12-30 15:39:12 +03:00
|
|
|
glVertexAttrib3d(shaderinfo[4], p1->x, p1->y, p1->z + z);
|
|
|
|
glVertexAttrib3d(shaderinfo[5], p2->x, p2->y, p2->z + z);
|
2009-06-27 02:01:53 +04:00
|
|
|
glVertexAttrib3d(shaderinfo[6], 0.0, 1.0, 0.0);
|
2009-12-30 15:39:12 +03:00
|
|
|
glVertex3d(p0->x, p0->y, p0->z + z);
|
2010-01-09 20:15:56 +03:00
|
|
|
if (!mirrored) {
|
|
|
|
glVertexAttrib3d(shaderinfo[3], e0f, e1f, e2f);
|
|
|
|
glVertexAttrib3d(shaderinfo[4], p0->x, p0->y, p0->z + z);
|
|
|
|
glVertexAttrib3d(shaderinfo[5], p2->x, p2->y, p2->z + z);
|
|
|
|
glVertexAttrib3d(shaderinfo[6], 0.0, 0.0, 1.0);
|
|
|
|
glVertex3d(p1->x, p1->y, p1->z + z);
|
|
|
|
}
|
2009-06-27 02:01:53 +04:00
|
|
|
glVertexAttrib3d(shaderinfo[3], e0f, e1f, e2f);
|
2009-12-30 15:39:12 +03:00
|
|
|
glVertexAttrib3d(shaderinfo[4], p0->x, p0->y, p0->z + z);
|
|
|
|
glVertexAttrib3d(shaderinfo[5], p1->x, p1->y, p1->z + z);
|
2009-06-27 02:01:53 +04:00
|
|
|
glVertexAttrib3d(shaderinfo[6], 1.0, 0.0, 0.0);
|
2009-12-30 15:39:12 +03:00
|
|
|
glVertex3d(p2->x, p2->y, p2->z + z);
|
2010-01-09 20:15:56 +03:00
|
|
|
if (mirrored) {
|
|
|
|
glVertexAttrib3d(shaderinfo[3], e0f, e1f, e2f);
|
|
|
|
glVertexAttrib3d(shaderinfo[4], p0->x, p0->y, p0->z + z);
|
|
|
|
glVertexAttrib3d(shaderinfo[5], p2->x, p2->y, p2->z + z);
|
|
|
|
glVertexAttrib3d(shaderinfo[6], 0.0, 0.0, 1.0);
|
|
|
|
glVertex3d(p1->x, p1->y, p1->z + z);
|
|
|
|
}
|
2009-06-27 02:01:53 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
2009-12-30 15:39:12 +03:00
|
|
|
glVertex3d(p0->x, p0->y, p0->z + z);
|
2010-01-09 20:15:56 +03:00
|
|
|
if (!mirrored)
|
|
|
|
glVertex3d(p1->x, p1->y, p1->z + z);
|
2009-12-30 15:39:12 +03:00
|
|
|
glVertex3d(p2->x, p2->y, p2->z + z);
|
2010-01-09 20:15:56 +03:00
|
|
|
if (mirrored)
|
|
|
|
glVertex3d(p1->x, p1->y, p1->z + z);
|
2009-06-27 02:01:53 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-09 20:15:56 +03:00
|
|
|
void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, double *m, GLint *shaderinfo) const
|
2009-06-26 17:29:48 +04:00
|
|
|
{
|
2010-01-09 20:15:56 +03:00
|
|
|
double m_scale_rotate_det =
|
|
|
|
m[0]*m[5]*m[10] + m[4]*m[9]*m[2] + m[8]*m[1]*m[6] -
|
|
|
|
(m[8]*m[5]*m[2] + m[4]*m[1]*m[10] + m[0]*m[9]*m[6]);
|
|
|
|
bool mirrored = m_scale_rotate_det < 0;
|
|
|
|
|
2009-08-04 22:55:25 +04:00
|
|
|
if (colormode == COLORMODE_MATERIAL) {
|
2009-06-25 12:12:41 +04:00
|
|
|
glColor3ub(249, 215, 44);
|
2009-06-27 02:01:53 +04:00
|
|
|
#ifdef ENABLE_OPENCSG
|
2009-06-26 21:07:40 +04:00
|
|
|
if (shaderinfo) {
|
|
|
|
glUniform4f(shaderinfo[1], 249 / 255.0, 215 / 255.0, 44 / 255.0, 1.0);
|
|
|
|
glUniform4f(shaderinfo[2], 255 / 255.0, 236 / 255.0, 94 / 255.0, 1.0);
|
|
|
|
}
|
2009-06-27 02:01:53 +04:00
|
|
|
#endif /* ENABLE_OPENCSG */
|
2009-06-26 21:07:40 +04:00
|
|
|
}
|
2009-08-04 22:55:25 +04:00
|
|
|
if (colormode == COLORMODE_CUTOUT) {
|
2009-06-25 12:12:41 +04:00
|
|
|
glColor3ub(157, 203, 81);
|
2009-06-27 02:01:53 +04:00
|
|
|
#ifdef ENABLE_OPENCSG
|
2009-06-26 21:07:40 +04:00
|
|
|
if (shaderinfo) {
|
|
|
|
glUniform4f(shaderinfo[1], 157 / 255.0, 203 / 255.0, 81 / 255.0, 1.0);
|
|
|
|
glUniform4f(shaderinfo[2], 171 / 255.0, 216 / 255.0, 86 / 255.0, 1.0);
|
|
|
|
}
|
2009-07-01 15:09:19 +04:00
|
|
|
#endif /* ENABLE_OPENCSG */
|
|
|
|
}
|
2009-08-04 22:55:25 +04:00
|
|
|
if (colormode == COLORMODE_HIGHLIGHT) {
|
2009-07-24 12:22:05 +04:00
|
|
|
glColor4ub(255, 157, 81, 128);
|
2009-07-01 15:09:19 +04:00
|
|
|
#ifdef ENABLE_OPENCSG
|
|
|
|
if (shaderinfo) {
|
|
|
|
glUniform4f(shaderinfo[1], 255 / 255.0, 157 / 255.0, 81 / 255.0, 0.5);
|
|
|
|
glUniform4f(shaderinfo[2], 255 / 255.0, 171 / 255.0, 86 / 255.0, 0.5);
|
|
|
|
}
|
2009-07-23 16:05:05 +04:00
|
|
|
#endif /* ENABLE_OPENCSG */
|
|
|
|
}
|
2009-08-04 22:55:25 +04:00
|
|
|
if (colormode == COLORMODE_BACKGROUND) {
|
2009-07-24 12:22:05 +04:00
|
|
|
glColor4ub(180, 180, 180, 128);
|
2009-07-23 16:05:05 +04:00
|
|
|
#ifdef ENABLE_OPENCSG
|
|
|
|
if (shaderinfo) {
|
|
|
|
glUniform4f(shaderinfo[1], 180 / 255.0, 180 / 255.0, 180 / 255.0, 0.5);
|
|
|
|
glUniform4f(shaderinfo[2], 150 / 255.0, 150 / 255.0, 150 / 255.0, 0.5);
|
|
|
|
}
|
2009-06-27 02:01:53 +04:00
|
|
|
#endif /* ENABLE_OPENCSG */
|
2009-06-26 21:07:40 +04:00
|
|
|
}
|
2009-06-27 02:01:53 +04:00
|
|
|
#ifdef ENABLE_OPENCSG
|
|
|
|
if (shaderinfo) {
|
|
|
|
glUniform1f(shaderinfo[7], shaderinfo[9]);
|
|
|
|
glUniform1f(shaderinfo[8], shaderinfo[10]);
|
|
|
|
}
|
|
|
|
#endif /* ENABLE_OPENCSG */
|
2009-12-30 15:39:12 +03:00
|
|
|
if (this->is2d) {
|
|
|
|
double zbase = csgmode;
|
2010-01-06 12:21:40 +03:00
|
|
|
glBegin(GL_TRIANGLES);
|
2009-12-30 15:39:12 +03:00
|
|
|
for (double z = -zbase/2; z < zbase; z += zbase)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < polygons.size(); i++) {
|
|
|
|
const Polygon *poly = &polygons[i];
|
|
|
|
if (poly->size() == 3) {
|
|
|
|
if (z < 0) {
|
2010-01-09 20:15:56 +03:00
|
|
|
gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(2), &poly->at(1), true, true, true, z, mirrored);
|
2009-12-30 15:39:12 +03:00
|
|
|
} else {
|
2010-01-09 20:15:56 +03:00
|
|
|
gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(1), &poly->at(2), true, true, true, z, mirrored);
|
2009-12-30 15:39:12 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (poly->size() == 4) {
|
|
|
|
if (z < 0) {
|
2010-01-09 20:15:56 +03:00
|
|
|
gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(3), &poly->at(1), true, false, true, z, mirrored);
|
|
|
|
gl_draw_triangle(shaderinfo, &poly->at(2), &poly->at(1), &poly->at(3), true, false, true, z, mirrored);
|
2009-12-30 15:39:12 +03:00
|
|
|
} else {
|
2010-01-09 20:15:56 +03:00
|
|
|
gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(1), &poly->at(3), true, false, true, z, mirrored);
|
|
|
|
gl_draw_triangle(shaderinfo, &poly->at(2), &poly->at(3), &poly->at(1), true, false, true, z, mirrored);
|
2009-12-30 15:39:12 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Point center;
|
|
|
|
for (int j = 0; j < poly->size(); j++) {
|
|
|
|
center.x += poly->at(j).x;
|
|
|
|
center.y += poly->at(j).y;
|
|
|
|
}
|
|
|
|
center.x /= poly->size();
|
|
|
|
center.y /= poly->size();
|
|
|
|
for (int j = 1; j <= poly->size(); j++) {
|
|
|
|
if (z < 0) {
|
|
|
|
gl_draw_triangle(shaderinfo, ¢er, &poly->at(j % poly->size()), &poly->at(j - 1),
|
2010-01-09 20:15:56 +03:00
|
|
|
false, true, false, z, mirrored);
|
2009-12-30 15:39:12 +03:00
|
|
|
} else {
|
|
|
|
gl_draw_triangle(shaderinfo, ¢er, &poly->at(j - 1), &poly->at(j % poly->size()),
|
2010-01-09 20:15:56 +03:00
|
|
|
false, true, false, z, mirrored);
|
2009-12-30 15:39:12 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-06-27 02:01:53 +04:00
|
|
|
}
|
2010-01-06 12:21:40 +03:00
|
|
|
const QVector<Polygon> *borders_p = &borders;
|
|
|
|
if (borders_p->size() == 0)
|
|
|
|
borders_p = &polygons;
|
|
|
|
for (int i = 0; i < borders_p->size(); i++) {
|
|
|
|
const Polygon *poly = &borders_p->at(i);
|
|
|
|
for (int j = 1; j <= poly->size(); j++) {
|
|
|
|
Point p1 = poly->at(j - 1), p2 = poly->at(j - 1);
|
|
|
|
Point p3 = poly->at(j % poly->size()), p4 = poly->at(j % poly->size());
|
|
|
|
p1.z -= zbase/2, p2.z += zbase/2;
|
|
|
|
p3.z -= zbase/2, p4.z += zbase/2;
|
2010-01-09 20:15:56 +03:00
|
|
|
gl_draw_triangle(shaderinfo, &p2, &p1, &p3, true, true, false, 0, mirrored);
|
|
|
|
gl_draw_triangle(shaderinfo, &p2, &p3, &p4, false, true, true, 0, mirrored);
|
2010-01-06 12:21:40 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
glEnd();
|
2009-12-30 15:39:12 +03:00
|
|
|
} else {
|
|
|
|
for (int i = 0; i < polygons.size(); i++) {
|
|
|
|
const Polygon *poly = &polygons[i];
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
|
|
if (poly->size() == 3) {
|
2010-01-09 20:15:56 +03:00
|
|
|
gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(1), &poly->at(2), true, true, true, 0, mirrored);
|
2009-06-27 02:01:53 +04:00
|
|
|
}
|
2009-12-30 15:39:12 +03:00
|
|
|
else if (poly->size() == 4) {
|
2010-01-09 20:15:56 +03:00
|
|
|
gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(1), &poly->at(3), true, false, true, 0, mirrored);
|
|
|
|
gl_draw_triangle(shaderinfo, &poly->at(2), &poly->at(3), &poly->at(1), true, false, true, 0, mirrored);
|
2009-12-30 15:39:12 +03:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
Point center;
|
|
|
|
for (int j = 0; j < poly->size(); j++) {
|
|
|
|
center.x += poly->at(j).x;
|
|
|
|
center.y += poly->at(j).y;
|
|
|
|
center.z += poly->at(j).z;
|
|
|
|
}
|
|
|
|
center.x /= poly->size();
|
|
|
|
center.y /= poly->size();
|
|
|
|
center.z /= poly->size();
|
|
|
|
for (int j = 1; j <= poly->size(); j++) {
|
2010-01-09 20:15:56 +03:00
|
|
|
gl_draw_triangle(shaderinfo, ¢er, &poly->at(j - 1), &poly->at(j % poly->size()), false, true, false, 0, mirrored);
|
2009-12-30 15:39:12 +03:00
|
|
|
}
|
2009-06-26 21:07:40 +04:00
|
|
|
}
|
2009-12-30 15:39:12 +03:00
|
|
|
glEnd();
|
2009-06-24 14:59:15 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-30 15:39:12 +03:00
|
|
|
void PolySet::render_edges(colormode_e colormode, csgmode_e csgmode) const
|
2009-06-25 12:12:41 +04:00
|
|
|
{
|
2009-08-04 22:55:25 +04:00
|
|
|
if (colormode == COLORMODE_MATERIAL)
|
2009-06-25 12:12:41 +04:00
|
|
|
glColor3ub(255, 236, 94);
|
2009-08-04 22:55:25 +04:00
|
|
|
if (colormode == COLORMODE_CUTOUT)
|
2009-06-25 12:12:41 +04:00
|
|
|
glColor3ub(171, 216, 86);
|
2009-08-04 22:55:25 +04:00
|
|
|
if (colormode == COLORMODE_HIGHLIGHT)
|
2009-07-24 12:22:05 +04:00
|
|
|
glColor4ub(255, 171, 86, 128);
|
2009-08-04 22:55:25 +04:00
|
|
|
if (colormode == COLORMODE_BACKGROUND)
|
2009-07-24 12:22:05 +04:00
|
|
|
glColor4ub(150, 150, 150, 128);
|
2009-12-30 15:39:12 +03:00
|
|
|
if (this->is2d) {
|
|
|
|
double zbase = csgmode;
|
|
|
|
for (double z = -zbase/2; z < zbase; z += zbase)
|
|
|
|
{
|
2010-01-06 12:21:40 +03:00
|
|
|
for (int i = 0; i < borders.size(); i++) {
|
|
|
|
const Polygon *poly = &borders[i];
|
2009-12-30 15:39:12 +03:00
|
|
|
glBegin(GL_LINE_LOOP);
|
|
|
|
for (int j = 0; j < poly->size(); j++) {
|
|
|
|
const Point *p = &poly->at(j);
|
|
|
|
glVertex3d(p->x, p->y, z);
|
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
}
|
2010-01-06 12:21:40 +03:00
|
|
|
for (int i = 0; i < borders.size(); i++) {
|
|
|
|
const Polygon *poly = &borders[i];
|
2009-12-30 15:39:12 +03:00
|
|
|
glBegin(GL_LINES);
|
|
|
|
for (int j = 0; j < poly->size(); j++) {
|
|
|
|
const Point *p = &poly->at(j);
|
|
|
|
glVertex3d(p->x, p->y, -zbase/2);
|
|
|
|
glVertex3d(p->x, p->y, +zbase/2);
|
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (int i = 0; i < polygons.size(); i++) {
|
|
|
|
const Polygon *poly = &polygons[i];
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
|
|
for (int j = 0; j < poly->size(); j++) {
|
|
|
|
const Point *p = &poly->at(j);
|
|
|
|
glVertex3d(p->x, p->y, p->z);
|
|
|
|
}
|
|
|
|
glEnd();
|
2009-06-25 12:12:41 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-06-24 14:59:15 +04:00
|
|
|
#ifdef ENABLE_CGAL
|
|
|
|
|
2009-07-17 03:11:08 +04:00
|
|
|
#undef GEN_SURFACE_DEBUG
|
|
|
|
|
2009-06-24 14:59:15 +04:00
|
|
|
class CGAL_Build_PolySet : public CGAL::Modifier_base<CGAL_HDS>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef CGAL_HDS::Vertex::Point Point;
|
|
|
|
|
|
|
|
const PolySet *ps;
|
|
|
|
CGAL_Build_PolySet(const PolySet *ps) : ps(ps) { }
|
|
|
|
|
|
|
|
void operator()(CGAL_HDS& hds)
|
|
|
|
{
|
|
|
|
CGAL_Polybuilder B(hds, true);
|
|
|
|
|
|
|
|
QVector<PolySet::Point> vertices;
|
2009-07-21 23:33:39 +04:00
|
|
|
Grid3d<int> vertices_idx;
|
2009-06-24 14:59:15 +04:00
|
|
|
|
|
|
|
for (int i = 0; i < ps->polygons.size(); i++) {
|
|
|
|
const PolySet::Polygon *poly = &ps->polygons[i];
|
|
|
|
for (int j = 0; j < poly->size(); j++) {
|
|
|
|
const PolySet::Point *p = &poly->at(j);
|
2009-07-21 23:33:39 +04:00
|
|
|
if (!vertices_idx.has(p->x, p->y, p->z)) {
|
|
|
|
vertices_idx.data(p->x, p->y, p->z) = vertices.size();
|
2009-06-24 14:59:15 +04:00
|
|
|
vertices.append(*p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
B.begin_surface(vertices.size(), ps->polygons.size());
|
2009-07-17 03:11:08 +04:00
|
|
|
#ifdef GEN_SURFACE_DEBUG
|
|
|
|
printf("=== CGAL Surface ===\n");
|
|
|
|
#endif
|
2009-06-24 14:59:15 +04:00
|
|
|
|
|
|
|
for (int i = 0; i < vertices.size(); i++) {
|
|
|
|
const PolySet::Point *p = &vertices[i];
|
|
|
|
B.add_vertex(Point(p->x, p->y, p->z));
|
2009-07-17 03:11:08 +04:00
|
|
|
#ifdef GEN_SURFACE_DEBUG
|
|
|
|
printf("%d: %f %f %f\n", i, p->x, p->y, p->z);
|
|
|
|
#endif
|
2009-06-24 14:59:15 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < ps->polygons.size(); i++) {
|
|
|
|
const PolySet::Polygon *poly = &ps->polygons[i];
|
2009-07-22 14:11:18 +04:00
|
|
|
QHash<int,int> fc;
|
|
|
|
bool facet_is_degenerated = false;
|
|
|
|
for (int j = 0; j < poly->size(); j++) {
|
|
|
|
const PolySet::Point *p = &poly->at(j);
|
|
|
|
int v = vertices_idx.data(p->x, p->y, p->z);
|
|
|
|
if (fc[v]++ > 0)
|
|
|
|
facet_is_degenerated = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!facet_is_degenerated)
|
|
|
|
B.begin_facet();
|
2009-07-17 03:11:08 +04:00
|
|
|
#ifdef GEN_SURFACE_DEBUG
|
|
|
|
printf("F:");
|
|
|
|
#endif
|
2009-06-24 14:59:15 +04:00
|
|
|
for (int j = 0; j < poly->size(); j++) {
|
|
|
|
const PolySet::Point *p = &poly->at(j);
|
2009-07-17 03:11:08 +04:00
|
|
|
#ifdef GEN_SURFACE_DEBUG
|
2009-07-21 23:33:39 +04:00
|
|
|
printf(" %d", vertices_idx.data(p->x, p->y, p->z));
|
2009-07-17 03:11:08 +04:00
|
|
|
#endif
|
2009-07-22 14:11:18 +04:00
|
|
|
if (!facet_is_degenerated)
|
|
|
|
B.add_vertex_to_facet(vertices_idx.data(p->x, p->y, p->z));
|
2009-06-24 14:59:15 +04:00
|
|
|
}
|
2009-07-17 03:11:08 +04:00
|
|
|
#ifdef GEN_SURFACE_DEBUG
|
2009-07-22 14:11:18 +04:00
|
|
|
if (facet_is_degenerated)
|
|
|
|
printf(" (degenerated)\n");
|
2009-07-17 03:11:08 +04:00
|
|
|
printf("\n");
|
|
|
|
#endif
|
2009-07-22 14:11:18 +04:00
|
|
|
if (!facet_is_degenerated)
|
|
|
|
B.end_facet();
|
2009-06-24 14:59:15 +04:00
|
|
|
}
|
|
|
|
|
2009-07-17 03:11:08 +04:00
|
|
|
#ifdef GEN_SURFACE_DEBUG
|
|
|
|
printf("====================\n");
|
|
|
|
#endif
|
2009-06-24 14:59:15 +04:00
|
|
|
B.end_surface();
|
|
|
|
|
|
|
|
#undef PointKey
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
CGAL_Nef_polyhedron PolySet::render_cgal_nef_polyhedron() const
|
|
|
|
{
|
2009-12-29 14:08:27 +03:00
|
|
|
if (this->is2d)
|
|
|
|
{
|
2010-01-13 12:10:15 +03:00
|
|
|
#if 0
|
|
|
|
// This version of the code causes problems in some cases.
|
|
|
|
// Example testcase: import_dxf("testdata/polygon8.dxf");
|
|
|
|
//
|
2010-01-05 22:09:01 +03:00
|
|
|
typedef std::list<CGAL_Nef_polyhedron2::Point> point_list_t;
|
|
|
|
typedef point_list_t::iterator point_list_it;
|
|
|
|
std::list< point_list_t > pdata_point_lists;
|
|
|
|
std::list < std::pair < point_list_it, point_list_it > > pdata;
|
2010-01-13 12:10:15 +03:00
|
|
|
Grid2d<CGAL_Nef_polyhedron2::Point> grid;
|
2010-01-05 22:09:01 +03:00
|
|
|
|
|
|
|
for (int i = 0; i < this->polygons.size(); i++) {
|
|
|
|
pdata_point_lists.push_back(point_list_t());
|
|
|
|
for (int j = 0; j < this->polygons[i].size(); j++) {
|
|
|
|
double x = this->polygons[i][j].x;
|
|
|
|
double y = this->polygons[i][j].y;
|
2010-01-13 12:10:15 +03:00
|
|
|
CGAL_Nef_polyhedron2::Point p;
|
|
|
|
if (grid.has(x, y)) {
|
|
|
|
p = grid.data(x, y);
|
|
|
|
} else {
|
|
|
|
p = CGAL_Nef_polyhedron2::Point(x, y);
|
|
|
|
grid.data(x, y) = p;
|
|
|
|
}
|
2010-01-05 22:09:01 +03:00
|
|
|
pdata_point_lists.back().push_back(p);
|
|
|
|
}
|
|
|
|
pdata.push_back(std::make_pair(pdata_point_lists.back().begin(),
|
|
|
|
pdata_point_lists.back().end()));
|
2009-12-29 14:08:27 +03:00
|
|
|
}
|
2010-01-05 22:09:01 +03:00
|
|
|
|
|
|
|
CGAL_Nef_polyhedron2 N(pdata.begin(), pdata.end(), CGAL_Nef_polyhedron2::POLYGONS);
|
|
|
|
return CGAL_Nef_polyhedron(N);
|
2010-01-13 12:10:15 +03:00
|
|
|
#else
|
|
|
|
CGAL_Nef_polyhedron2 N;
|
|
|
|
Grid2d<CGAL_Nef_polyhedron2::Point> grid;
|
|
|
|
|
|
|
|
for (int i = 0; i < this->polygons.size(); i++) {
|
|
|
|
std::list<CGAL_Nef_polyhedron2::Point> plist;
|
|
|
|
for (int j = 0; j < this->polygons[i].size(); j++) {
|
|
|
|
double x = this->polygons[i][j].x;
|
|
|
|
double y = this->polygons[i][j].y;
|
|
|
|
CGAL_Nef_polyhedron2::Point p;
|
|
|
|
if (grid.has(x, y)) {
|
|
|
|
p = grid.data(x, y);
|
|
|
|
} else {
|
|
|
|
p = CGAL_Nef_polyhedron2::Point(x, y);
|
|
|
|
grid.data(x, y) = p;
|
|
|
|
}
|
|
|
|
plist.push_back(p);
|
|
|
|
}
|
|
|
|
N += CGAL_Nef_polyhedron2(plist.begin(), plist.end(), CGAL_Nef_polyhedron2::INCLUDED);
|
|
|
|
}
|
|
|
|
|
|
|
|
return CGAL_Nef_polyhedron(N);
|
|
|
|
#endif
|
2009-12-29 14:08:27 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CGAL_Polyhedron P;
|
|
|
|
CGAL_Build_PolySet builder(this);
|
|
|
|
P.delegate(builder);
|
2009-06-24 14:59:15 +04:00
|
|
|
#if 0
|
2009-12-29 14:08:27 +03:00
|
|
|
std::cout << P;
|
2009-06-24 14:59:15 +04:00
|
|
|
#endif
|
2009-12-29 14:08:27 +03:00
|
|
|
CGAL_Nef_polyhedron3 N(P);
|
|
|
|
return CGAL_Nef_polyhedron(N);
|
|
|
|
}
|
|
|
|
return CGAL_Nef_polyhedron();
|
2009-06-24 14:59:15 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* ENABLE_CGAL */
|
|
|
|
|
|
|
|
PolySet *AbstractPolyNode::render_polyset(render_mode_e) const
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef ENABLE_CGAL
|
|
|
|
|
|
|
|
CGAL_Nef_polyhedron AbstractPolyNode::render_cgal_nef_polyhedron() const
|
|
|
|
{
|
2009-07-28 16:53:52 +04:00
|
|
|
QString cache_id = mk_cache_id();
|
2009-07-03 11:51:22 +04:00
|
|
|
if (cgal_nef_cache.contains(cache_id)) {
|
|
|
|
progress_report();
|
2010-01-06 13:48:51 +03:00
|
|
|
PRINT(cgal_nef_cache[cache_id]->msg);
|
|
|
|
return cgal_nef_cache[cache_id]->N;
|
2009-07-03 11:51:22 +04:00
|
|
|
}
|
|
|
|
|
2010-01-06 13:48:51 +03:00
|
|
|
print_messages_push();
|
|
|
|
|
2009-06-24 14:59:15 +04:00
|
|
|
PolySet *ps = render_polyset(RENDER_CGAL);
|
|
|
|
CGAL_Nef_polyhedron N = ps->render_cgal_nef_polyhedron();
|
2009-07-03 11:51:22 +04:00
|
|
|
|
2010-01-06 13:48:51 +03:00
|
|
|
cgal_nef_cache.insert(cache_id, new cgal_nef_cache_entry(N), N.weight());
|
|
|
|
print_messages_pop();
|
2009-06-24 14:59:15 +04:00
|
|
|
progress_report();
|
2010-01-06 13:48:51 +03:00
|
|
|
|
2009-07-28 16:53:52 +04:00
|
|
|
ps->unlink();
|
2009-06-24 14:59:15 +04:00
|
|
|
return N;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* ENABLE_CGAL */
|
|
|
|
|
2010-01-07 17:59:10 +03:00
|
|
|
CSGTerm *AbstractPolyNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
|
2009-06-24 14:59:15 +04:00
|
|
|
{
|
|
|
|
PolySet *ps = render_polyset(RENDER_OPENCSG);
|
2009-07-28 22:17:29 +04:00
|
|
|
return render_csg_term_from_ps(m, highlights, background, ps, modinst, idx);
|
|
|
|
}
|
|
|
|
|
2010-01-07 17:59:10 +03:00
|
|
|
CSGTerm *AbstractPolyNode::render_csg_term_from_ps(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background, PolySet *ps, const ModuleInstantiation *modinst, int idx)
|
2009-07-28 22:17:29 +04:00
|
|
|
{
|
2009-07-28 16:53:52 +04:00
|
|
|
CSGTerm *t = new CSGTerm(ps, m, QString("n%1").arg(idx));
|
2009-07-01 15:09:19 +04:00
|
|
|
if (modinst->tag_highlight && highlights)
|
|
|
|
highlights->append(t->link());
|
2009-07-23 16:05:05 +04:00
|
|
|
if (modinst->tag_background && background) {
|
|
|
|
background->append(t);
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-07-01 15:09:19 +04:00
|
|
|
return t;
|
2009-06-24 14:59:15 +04:00
|
|
|
}
|
|
|
|
|