diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CGALCache.cc | 2 | ||||
-rw-r--r-- | src/CSGTermEvaluator.cc | 2 | ||||
-rw-r--r-- | src/OpenCSGRenderer.cc | 4 | ||||
-rw-r--r-- | src/OpenCSGWarningDialog.ui | 3 | ||||
-rw-r--r-- | src/Preferences.cc | 14 | ||||
-rw-r--r-- | src/ThrownTogetherRenderer.cc | 6 | ||||
-rw-r--r-- | src/colornode.h | 3 | ||||
-rw-r--r-- | src/csgterm.cc | 128 | ||||
-rw-r--r-- | src/csgterm.h | 11 | ||||
-rw-r--r-- | src/csgtermnormalizer.cc | 150 | ||||
-rw-r--r-- | src/csgtermnormalizer.h | 22 | ||||
-rw-r--r-- | src/export.cc | 39 | ||||
-rw-r--r-- | src/glview.cc | 9 | ||||
-rw-r--r-- | src/lexer.l | 21 | ||||
-rw-r--r-- | src/linalg.h | 6 | ||||
-rw-r--r-- | src/mainwin.cc | 28 | ||||
-rw-r--r-- | src/openscad.cc | 4 | ||||
-rw-r--r-- | src/parser.y | 15 | ||||
-rw-r--r-- | src/renderer.cc | 2 | ||||
-rw-r--r-- | src/renderer.h | 2 | ||||
-rw-r--r-- | src/state.h | 16 |
21 files changed, 258 insertions, 229 deletions
diff --git a/src/CGALCache.cc b/src/CGALCache.cc index 6bdad41..84de722 100644 --- a/src/CGALCache.cc +++ b/src/CGALCache.cc @@ -7,7 +7,9 @@ CGALCache *CGALCache::inst = NULL; void CGALCache::insert(const std::string &id, const CGAL_Nef_polyhedron &N) { this->cache.insert(id, new CGAL_Nef_polyhedron(N), N.weight()); +#ifdef DEBUG PRINTF("CGAL Cache insert: %s (%d verts)", id.substr(0, 40).c_str(), N.weight()); +#endif } void CGALCache::print() diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index 65209dd..4624d4c 100644 --- a/src/CSGTermEvaluator.cc +++ b/src/CSGTermEvaluator.cc @@ -159,7 +159,7 @@ Response CSGTermEvaluator::visit(State &state, const TransformNode &node) Response CSGTermEvaluator::visit(State &state, const ColorNode &node) { if (state.isPrefix()) { - state.setColor(node.color); + if (!state.color().isValid()) state.setColor(node.color); } if (state.isPostfix()) { applyToChildren(node, CSGT_UNION); diff --git a/src/OpenCSGRenderer.cc b/src/OpenCSGRenderer.cc index 233124b..eb66687 100644 --- a/src/OpenCSGRenderer.cc +++ b/src/OpenCSGRenderer.cc @@ -86,7 +86,7 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo, if (shaderinfo) glUseProgram(shaderinfo[0]); for (; j < i; j++) { const Transform3d &m = chain->matrices[j]; - double *c = chain->colors[j]; + const Color4f &c = chain->colors[j]; glPushMatrix(); glMultMatrixd(m.data()); PolySet::csgmode_e csgmode = chain->types[j] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; @@ -99,7 +99,7 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo, csgmode = PolySet::csgmode_e(csgmode + 10); } else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0 || c[3] >= 0) { // User-defined color or alpha from source - setColor(c, shaderinfo); + setColor(c.data(), shaderinfo); } else if (chain->types[j] == CSGTerm::TYPE_DIFFERENCE) { setColor(COLORMODE_CUTOUT, shaderinfo); } else { diff --git a/src/OpenCSGWarningDialog.ui b/src/OpenCSGWarningDialog.ui index f902521..fe3f192 100644 --- a/src/OpenCSGWarningDialog.ui +++ b/src/OpenCSGWarningDialog.ui @@ -33,6 +33,9 @@ p, li { white-space: pre-wrap; } <property name="text"> <string>Enable OpenCSG</string> </property> + <property name="checked"> + <bool>true</bool> + </property> </widget> </item> <item> diff --git a/src/Preferences.cc b/src/Preferences.cc index 59f8d23..4c43f2d 100644 --- a/src/Preferences.cc +++ b/src/Preferences.cc @@ -47,10 +47,16 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent) // Setup default settings this->defaultmap["3dview/colorscheme"] = this->colorSchemeChooser->currentItem()->text(); - this->defaultmap["editor/fontfamily"] = this->fontChooser->currentText(); - this->defaultmap["editor/fontsize"] = this->fontSize->currentText().toUInt(); +#ifdef Q_WS_X11 + this->defaultmap["editor/fontfamily"] = "Mono"; +#elif defined (Q_WS_WIN) + this->defaultmap["editor/fontfamily"] = "Console"; +#elif defined (Q_WS_MAC) + this->defaultmap["editor/fontfamily"] = "Monaco"; +#endif + this->defaultmap["editor/fontsize"] = 12; this->defaultmap["advanced/opencsg_show_warning"] = true; - this->defaultmap["advanced/enable_opencsg_opengl1x"] = false; + this->defaultmap["advanced/enable_opencsg_opengl1x"] = true; // Toolbar QActionGroup *group = new QActionGroup(this); @@ -212,7 +218,7 @@ void Preferences::updateGUI() if (!found.isEmpty()) this->colorSchemeChooser->setCurrentItem(found.first()); QString fontfamily = getValue("editor/fontfamily").toString(); - int fidx = this->fontChooser->findText(fontfamily); + int fidx = this->fontChooser->findText(fontfamily,Qt::MatchContains); if (fidx >= 0) { this->fontChooser->setCurrentIndex(fidx); } diff --git a/src/ThrownTogetherRenderer.cc b/src/ThrownTogetherRenderer.cc index 36f7b95..146d2e1 100644 --- a/src/ThrownTogetherRenderer.cc +++ b/src/ThrownTogetherRenderer.cc @@ -67,7 +67,7 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight, if (polySetVisitMark[std::make_pair(chain->polysets[i].get(), &chain->matrices[i])]++ > 0) continue; const Transform3d &m = chain->matrices[i]; - double *c = chain->colors[i]; + const Color4f &c = chain->colors[i]; glPushMatrix(); glMultMatrixd(m.data()); PolySet::csgmode_e csgmode = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; @@ -93,10 +93,10 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight, else csgmode = PolySet::csgmode_e(csgmode); chain->polysets[i]->render_surface(csgmode, m); } else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0 || c[3] >= 0) { - setColor(c); + setColor(c.data()); chain->polysets[i]->render_surface(csgmode, m); if (showedges) { - glColor4d((c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0); + glColor4f((c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0); chain->polysets[i]->render_edges(csgmode); } } else if (chain->types[i] == CSGTerm::TYPE_DIFFERENCE) { diff --git a/src/colornode.h b/src/colornode.h index b41e2a9..9323638 100644 --- a/src/colornode.h +++ b/src/colornode.h @@ -3,6 +3,7 @@ #include "node.h" #include "visitor.h" +#include "linalg.h" class ColorNode : public AbstractNode { @@ -14,7 +15,7 @@ public: virtual std::string toString() const; virtual std::string name() const; - double color[4]; + Color4f color; }; #endif diff --git a/src/csgterm.cc b/src/csgterm.cc index 56fcbb5..4e6912b 100644 --- a/src/csgterm.cc +++ b/src/csgterm.cc @@ -89,10 +89,9 @@ shared_ptr<CSGTerm> CSGTerm::createCSGTerm(type_e type, CSGTerm *left, CSGTerm * return createCSGTerm(type, shared_ptr<CSGTerm>(left), shared_ptr<CSGTerm>(right)); } -CSGTerm::CSGTerm(const shared_ptr<PolySet> &polyset, const Transform3d &matrix, const double color[4], const std::string &label) - : type(TYPE_PRIMITIVE), polyset(polyset), label(label), m(matrix) +CSGTerm::CSGTerm(const shared_ptr<PolySet> &polyset, const Transform3d &matrix, const Color4f &color, const std::string &label) + : type(TYPE_PRIMITIVE), polyset(polyset), label(label), m(matrix), color(color) { - for (int i = 0; i < 4; i++) this->color[i] = color[i]; initBoundingBox(); } @@ -140,127 +139,6 @@ void CSGTerm::initBoundingBox() } } -shared_ptr<CSGTerm> CSGTerm::normalize(shared_ptr<CSGTerm> term) -{ - // This function implements the CSG normalization - // Reference: - // Goldfeather, J., Molnar, S., Turk, G., and Fuchs, H. Near - // Realtime CSG Rendering Using Tree Normalization and Geometric - // Pruning. IEEE Computer Graphics and Applications, 9(3):20-28, - // 1989. - // http://www.cc.gatech.edu/~turk/my_papers/pxpl_csg.pdf - - if (term->type == TYPE_PRIMITIVE) { - return term; - } - - do { - while (term && normalize_tail(term)) { } - if (!term || term->type == TYPE_PRIMITIVE) return term; - term->left = normalize(term->left); - } while (term->type != TYPE_UNION && - (term->right->type != TYPE_PRIMITIVE || term->left->type == TYPE_UNION)); - term->right = normalize(term->right); - - // FIXME: Do we need to take into account any transformation of item here? - if (!term->right) { - if (term->type == TYPE_UNION || term->type == TYPE_DIFFERENCE) return term->left; - else return term->right; - } - if (!term->left) { - if (term->type == TYPE_UNION) return term->right; - else return term->left; - } - - return term; -} - -bool CSGTerm::normalize_tail(shared_ptr<CSGTerm> &term) -{ - if (term->type == TYPE_UNION || term->type == TYPE_PRIMITIVE) return false; - - // Part A: The 'x . (y . z)' expressions - - shared_ptr<CSGTerm> x = term->left; - shared_ptr<CSGTerm> y = term->right->left; - shared_ptr<CSGTerm> z = term->right->right; - - shared_ptr<CSGTerm> result = term; - - // 1. x - (y + z) -> (x - y) - z - if (term->type == TYPE_DIFFERENCE && term->right->type == TYPE_UNION) { - term = createCSGTerm(TYPE_DIFFERENCE, - createCSGTerm(TYPE_DIFFERENCE, x, y), - z); - return true; - } - // 2. x * (y + z) -> (x * y) + (x * z) - else if (term->type == TYPE_INTERSECTION && term->right->type == TYPE_UNION) { - term = createCSGTerm(TYPE_UNION, - createCSGTerm(TYPE_INTERSECTION, x, y), - createCSGTerm(TYPE_INTERSECTION, x, z)); - return true; - } - // 3. x - (y * z) -> (x - y) + (x - z) - else if (term->type == TYPE_DIFFERENCE && term->right->type == TYPE_INTERSECTION) { - term = createCSGTerm(TYPE_UNION, - createCSGTerm(TYPE_DIFFERENCE, x, y), - createCSGTerm(TYPE_DIFFERENCE, x, z)); - return true; - } - // 4. x * (y * z) -> (x * y) * z - else if (term->type == TYPE_INTERSECTION && term->right->type == TYPE_INTERSECTION) { - term = createCSGTerm(TYPE_INTERSECTION, - createCSGTerm(TYPE_INTERSECTION, x, y), - z); - return true; - } - // 5. x - (y - z) -> (x - y) + (x * z) - else if (term->type == TYPE_DIFFERENCE && term->right->type == TYPE_DIFFERENCE) { - term = createCSGTerm(TYPE_UNION, - createCSGTerm(TYPE_DIFFERENCE, x, y), - createCSGTerm(TYPE_INTERSECTION, x, z)); - return true; - } - // 6. x * (y - z) -> (x * y) - z - else if (term->type == TYPE_INTERSECTION && term->right->type == TYPE_DIFFERENCE) { - term = createCSGTerm(TYPE_DIFFERENCE, - createCSGTerm(TYPE_INTERSECTION, x, y), - z); - return true; - } - - // Part B: The '(x . y) . z' expressions - - x = term->left->left; - y = term->left->right; - z = term->right; - - // 7. (x - y) * z -> (x * z) - y - if (term->left->type == TYPE_DIFFERENCE && term->type == TYPE_INTERSECTION) { - term = createCSGTerm(TYPE_DIFFERENCE, - createCSGTerm(TYPE_INTERSECTION, x, z), - y); - return true; - } - // 8. (x + y) - z -> (x - z) + (y - z) - else if (term->left->type == TYPE_UNION && term->type == TYPE_DIFFERENCE) { - term = createCSGTerm(TYPE_UNION, - createCSGTerm(TYPE_DIFFERENCE, x, z), - createCSGTerm(TYPE_DIFFERENCE, y, z)); - return true; - } - // 9. (x + y) * z -> (x * z) + (y * z) - else if (term->left->type == TYPE_UNION && term->type == TYPE_INTERSECTION) { - term = createCSGTerm(TYPE_UNION, - createCSGTerm(TYPE_INTERSECTION, x, z), - createCSGTerm(TYPE_INTERSECTION, y, z)); - return true; - } - - return false; -} - std::string CSGTerm::dump() { std::stringstream dump; @@ -281,7 +159,7 @@ CSGChain::CSGChain() { } -void CSGChain::add(const shared_ptr<PolySet> &polyset, const Transform3d &m, double *color, CSGTerm::type_e type, std::string label) +void CSGChain::add(const shared_ptr<PolySet> &polyset, const Transform3d &m, const Color4f &color, CSGTerm::type_e type, std::string label) { polysets.push_back(polyset); matrices.push_back(m); diff --git a/src/csgterm.h b/src/csgterm.h index 4930349..4278d85 100644 --- a/src/csgterm.h +++ b/src/csgterm.h @@ -28,14 +28,11 @@ public: shared_ptr<CSGTerm> right; BoundingBox bbox; - CSGTerm(const shared_ptr<PolySet> &polyset, const Transform3d &matrix, const double color[4], const std::string &label); + CSGTerm(const shared_ptr<PolySet> &polyset, const Transform3d &matrix, const Color4f &color, const std::string &label); ~CSGTerm(); const BoundingBox &getBoundingBox() const { return this->bbox; } - static shared_ptr<CSGTerm> normalize(shared_ptr<CSGTerm> term); - static bool normalize_tail(shared_ptr<CSGTerm> &term); - std::string dump(); private: CSGTerm(type_e type, shared_ptr<CSGTerm> left, shared_ptr<CSGTerm> right); @@ -44,7 +41,7 @@ private: void initBoundingBox(); Transform3d m; - double color[4]; + Color4f color; friend class CSGChain; }; @@ -54,13 +51,13 @@ class CSGChain public: std::vector<shared_ptr<PolySet> > polysets; std::vector<Transform3d> matrices; - std::vector<double*> colors; + std::vector<Color4f> colors; std::vector<CSGTerm::type_e> types; std::vector<std::string> labels; CSGChain(); - void add(const shared_ptr<PolySet> &polyset, const Transform3d &m, double *color, CSGTerm::type_e type, std::string label); + void add(const shared_ptr<PolySet> &polyset, const Transform3d &m, const Color4f &color, CSGTerm::type_e type, std::string label); void import(shared_ptr<CSGTerm> term, CSGTerm::type_e type = CSGTerm::TYPE_UNION); std::string dump(); diff --git a/src/csgtermnormalizer.cc b/src/csgtermnormalizer.cc new file mode 100644 index 0000000..a830422 --- /dev/null +++ b/src/csgtermnormalizer.cc @@ -0,0 +1,150 @@ +#include "csgtermnormalizer.h" +#include "csgterm.h" +#include "printutils.h" + +shared_ptr<CSGTerm> CSGTermNormalizer::normalize(const shared_ptr<CSGTerm> &root) +{ + shared_ptr<CSGTerm> temp = root; + while (1) { + shared_ptr<CSGTerm> n = normalizePass(temp); + if (temp == n) break; + temp = n; + + int num = count(temp); +#ifdef DEBUG + PRINTF("Normalize count: %d\n", num); +#endif + if (num > 5000) { + PRINTF("WARNING: Normalized tree is growing past 5000 elements. Aborting normalization.\n"); + return root; + } + } + return temp; +} + +shared_ptr<CSGTerm> CSGTermNormalizer::normalizePass(shared_ptr<CSGTerm> term) +{ + // This function implements the CSG normalization + // Reference: + // Goldfeather, J., Molnar, S., Turk, G., and Fuchs, H. Near + // Realtime CSG Rendering Using Tree Normalization and Geometric + // Pruning. IEEE Computer Graphics and Applications, 9(3):20-28, + // 1989. + // http://www.cc.gatech.edu/~turk/my_papers/pxpl_csg.pdf + + if (term->type == CSGTerm::TYPE_PRIMITIVE) { + return term; + } + + do { + while (term && normalize_tail(term)) { } + if (!term || term->type == CSGTerm::TYPE_PRIMITIVE) return term; + term->left = normalizePass(term->left); + } while (term->type != CSGTerm::TYPE_UNION && + (term->right->type != CSGTerm::TYPE_PRIMITIVE || term->left->type == CSGTerm::TYPE_UNION)); + term->right = normalizePass(term->right); + + // FIXME: Do we need to take into account any transformation of item here? + if (!term->right) { + if (term->type == CSGTerm::TYPE_UNION || term->type == CSGTerm::TYPE_DIFFERENCE) return term->left; + else return term->right; + } + if (!term->left) { + if (term->type == CSGTerm::TYPE_UNION) return term->right; + else return term->left; + } + + return term; +} + +bool CSGTermNormalizer::normalize_tail(shared_ptr<CSGTerm> &term) +{ + if (term->type == CSGTerm::TYPE_UNION || term->type == CSGTerm::TYPE_PRIMITIVE) return false; + + // Part A: The 'x . (y . z)' expressions + + shared_ptr<CSGTerm> x = term->left; + shared_ptr<CSGTerm> y = term->right->left; + shared_ptr<CSGTerm> z = term->right->right; + + shared_ptr<CSGTerm> result = term; + + // 1. x - (y + z) -> (x - y) - z + if (term->type == CSGTerm::TYPE_DIFFERENCE && term->right->type == CSGTerm::TYPE_UNION) { + term = CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, + CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, x, y), + z); + return true; + } + // 2. x * (y + z) -> (x * y) + (x * z) + else if (term->type == CSGTerm::TYPE_INTERSECTION && term->right->type == CSGTerm::TYPE_UNION) { + term = CSGTerm::createCSGTerm(CSGTerm::TYPE_UNION, + CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, y), + CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, z)); + return true; + } + // 3. x - (y * z) -> (x - y) + (x - z) + else if (term->type == CSGTerm::TYPE_DIFFERENCE && term->right->type == CSGTerm::TYPE_INTERSECTION) { + term = CSGTerm::createCSGTerm(CSGTerm::TYPE_UNION, + CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, x, y), + CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, x, z)); + return true; + } + // 4. x * (y * z) -> (x * y) * z + else if (term->type == CSGTerm::TYPE_INTERSECTION && term->right->type == CSGTerm::TYPE_INTERSECTION) { + term = CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, + CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, y), + z); + return true; + } + // 5. x - (y - z) -> (x - y) + (x * z) + else if (term->type == CSGTerm::TYPE_DIFFERENCE && term->right->type == CSGTerm::TYPE_DIFFERENCE) { + term = CSGTerm::createCSGTerm(CSGTerm::TYPE_UNION, + CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, x, y), + CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, z)); + return true; + } + // 6. x * (y - z) -> (x * y) - z + else if (term->type == CSGTerm::TYPE_INTERSECTION && term->right->type == CSGTerm::TYPE_DIFFERENCE) { + term = CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, + CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, y), + z); + return true; + } + + // Part B: The '(x . y) . z' expressions + + x = term->left->left; + y = term->left->right; + z = term->right; + + // 7. (x - y) * z -> (x * z) - y + if (term->left->type == CSGTerm::TYPE_DIFFERENCE && term->type == CSGTerm::TYPE_INTERSECTION) { + term = CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, + CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, z), + y); + return true; + } + // 8. (x + y) - z -> (x - z) + (y - z) + else if (term->left->type == CSGTerm::TYPE_UNION && term->type == CSGTerm::TYPE_DIFFERENCE) { + term = CSGTerm::createCSGTerm(CSGTerm::TYPE_UNION, + CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, x, z), + CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, y, z)); + return true; + } + // 9. (x + y) * z -> (x * z) + (y * z) + else if (term->left->type == CSGTerm::TYPE_UNION && term->type == CSGTerm::TYPE_INTERSECTION) { + term = CSGTerm::createCSGTerm(CSGTerm::TYPE_UNION, + CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, z), + CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, y, z)); + return true; + } + + return false; +} + +int CSGTermNormalizer::count(const shared_ptr<CSGTerm> &term) const +{ + if (!term) return 0; + return term->type == CSGTerm::TYPE_PRIMITIVE ? 1 : 0 + count(term->left) + count(term->right); +} diff --git a/src/csgtermnormalizer.h b/src/csgtermnormalizer.h new file mode 100644 index 0000000..df37441 --- /dev/null +++ b/src/csgtermnormalizer.h @@ -0,0 +1,22 @@ +#ifndef CSGTERMNORMALIZER_H_ +#define CSGTERMNORMALIZER_H_ + +#include "memory.h" + +class CSGTermNormalizer +{ +public: + CSGTermNormalizer() : counter(0) {} + ~CSGTermNormalizer() {} + + shared_ptr<class CSGTerm> normalize(const shared_ptr<CSGTerm> &term); + +private: + shared_ptr<CSGTerm> normalizePass(shared_ptr<CSGTerm> term) ; + bool normalize_tail(shared_ptr<CSGTerm> &term); + int count(const shared_ptr<CSGTerm> &term) const; + + int counter; +}; + +#endif diff --git a/src/export.cc b/src/export.cc index 5ce2d15..8abd5fa 100644 --- a/src/export.cc +++ b/src/export.cc @@ -84,31 +84,22 @@ void export_stl(CGAL_Nef_polyhedron *root_N, std::ostream &output, QProgressDial stream << x3 << " " << y3 << " " << z3; std::string vs3 = stream.str(); if (vs1 != vs2 && vs1 != vs3 && vs2 != vs3) { - // The above condition ensures that vs1-vs2, vs1-vs3, and their cross - // product are non-zero. Floating point arithmetic may however truncate - // small values to 0. This can be avoided by first scaling the components - // of vs1-vs2 and vs1-vs3. This has no effect on the resulting unit - // normal vector. - double dn[6] = { x1-x2, y1-y2, z1-z2, x1-x3, y1-y3, z1-z3 }; - double maxdn = 0; - int i; - for (i = 0; i < 6; ++i) { - double dx = dn[i]; - if (dx < 0) dx = -dx; - if (dx > maxdn) maxdn = dx; + // The above condition ensures that there are 3 distinct vertices, but + // they may be collinear. If they are, the unit normal is meaningless + // so the default value of "1 0 0" can be used. If the vertices are not + // collinear then the unit normal must be calculated from the + // components. + if (!CGAL::collinear(v1.point(),v2.point(),v3.point())) { + CGAL_Polyhedron::Traits::Vector_3 normal = CGAL::normal(v1.point(),v2.point(),v3.point()); + output << " facet normal " + << CGAL::sign(normal.x()) * sqrt(CGAL::to_double(normal.x()*normal.x()/normal.squared_length())) + << " " + << CGAL::sign(normal.y()) * sqrt(CGAL::to_double(normal.y()*normal.y()/normal.squared_length())) + << " " + << CGAL::sign(normal.z()) * sqrt(CGAL::to_double(normal.z()*normal.z()/normal.squared_length())) + << "\n"; } - for (i = 0; i < 6; ++i) dn[i] /= maxdn; - double nx = dn[1]*dn[5] - dn[2]*dn[4]; - double ny = dn[2]*dn[3] - dn[0]*dn[5]; - double nz = dn[0]*dn[4] - dn[1]*dn[3]; - double nlength = sqrt(nx*nx + ny*ny + nz*nz); - // Avoid generating normals for polygons with zero area - double eps = 0.000001; - if (nlength < eps) nlength = 1.0; - output << " facet normal " - << nx / nlength << " " - << ny / nlength << " " - << nz / nlength << "\n"; + else output << " facet normal 1 0 0\n"; output << " outer loop\n"; output << " vertex " << vs1 << "\n"; output << " vertex " << vs2 << "\n"; diff --git a/src/glview.cc b/src/glview.cc index f25cac6..63573e3 100644 --- a/src/glview.cc +++ b/src/glview.cc @@ -154,9 +154,9 @@ void GLView::initializeGL() "Extensions:\n" "%s\n", glewGetString(GLEW_VERSION), + glGetString(GL_VERSION), glGetString(GL_RENDERER), glGetString(GL_VENDOR), - glGetString(GL_VERSION), rbits, gbits, bbits, abits, dbits, sbits, glGetString(GL_EXTENSIONS)); // FIXME: glGetString(GL_EXTENSIONS) is deprecated in OpenGL 3.0. @@ -500,10 +500,11 @@ void GLView::paintGL() // FIXME: This was an attempt to keep contrast with background, but is suboptimal // (e.g. nearly invisible against a gray background). - int r,g,b; - r=g=b=0; +// int r,g,b; +// r=g=b=0; // bgcol.getRgb(&r, &g, &b); - glColor3d((255.0-r)/255.0, (255.0-g)/255.0, (255.0-b)/255.0); +// glColor3f((255.0f-r)/255.0f, (255.0f-g)/255.0f, (255.0f-b)/255.0f); + glColor3f(0.0f, 0.0f, 0.0f); glBegin(GL_LINES); // X Label glVertex3d(xlabel_x-3, xlabel_y-3, 0); glVertex3d(xlabel_x+3, xlabel_y+3, 0); diff --git a/src/lexer.l b/src/lexer.l index fd9ca3e..1b776d3 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -118,27 +118,6 @@ use[ \t\r\n>]*"<" { BEGIN(use); } } } -"<"[^ \t\r\n>]+">" { - char *filename = strdup(yytext+1); - filename[strlen(filename)-1] = 0; - path incpath = path(parser_source_path) / filename; - if (!exists(incpath)) { - incpath = librarydir / filename; - } - - PRINTF("DEPRECATED: Support for implicit include will be removed in future releases. Use `include <filename>' instead."); - handle_dep(absolute(incpath).generic_string()); - yyin = fopen(absolute(incpath).c_str(), "r"); - if (!yyin) { - PRINTF("WARNING: Can't open input file `%s'.", filename); - } else { - openfiles.push_back(yyin); - yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE )); - BEGIN(INITIAL); - } - free(filename); -} - <<EOF>> { if(!path_stack.empty()) path_stack.pop_back(); if (yyin && yyin != stdin) { diff --git a/src/linalg.h b/src/linalg.h index c1a14d1..15ef870 100644 --- a/src/linalg.h +++ b/src/linalg.h @@ -15,4 +15,10 @@ using Eigen::Transform3d; BoundingBox operator*(const Transform3d &m, const BoundingBox &box); +class Color4f : public Eigen::Vector4f +{ +public: + bool isValid() const { return this->minCoeff() >= 0.0f; } +}; + #endif diff --git a/src/mainwin.cc b/src/mainwin.cc index f9ce5c1..7b3a4b8 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -46,6 +46,7 @@ #include "ProgressWidget.h" #endif #include "ThrownTogetherRenderer.h" +#include "csgtermnormalizer.h" #include <QMenu> #include <QTime> @@ -178,7 +179,6 @@ MainWindow::MainWindow(const QString &filename) editor->setTabStopWidth(30); #endif editor->setLineWrapping(true); // Not designable - setFont("", 12); // Init default font this->glview->statusLabel = new QLabel(this); statusBar()->addWidget(this->glview->statusLabel); @@ -783,15 +783,8 @@ void MainWindow::compileCSG(bool procevents) if (procevents) QApplication::processEvents(); - this->root_norm_term = this->root_raw_term; - - // CSG normalization - while (1) { - shared_ptr<CSGTerm> n = CSGTerm::normalize(this->root_norm_term); - if (this->root_norm_term == n) break; - this->root_norm_term = n; - } - + CSGTermNormalizer normalizer; + this->root_norm_term = normalizer.normalize(this->root_raw_term); assert(this->root_norm_term); root_chain = new CSGChain(); @@ -805,11 +798,7 @@ void MainWindow::compileCSG(bool procevents) highlights_chain = new CSGChain(); for (unsigned int i = 0; i < highlight_terms.size(); i++) { - while (1) { - shared_ptr<CSGTerm> n = CSGTerm::normalize(highlight_terms[i]); - if (highlight_terms[i] == n) break; - highlight_terms[i] = n; - } + highlight_terms[i] = normalizer.normalize(highlight_terms[i]); highlights_chain->import(highlight_terms[i]); } } @@ -822,11 +811,7 @@ void MainWindow::compileCSG(bool procevents) background_chain = new CSGChain(); for (unsigned int i = 0; i < background_terms.size(); i++) { - while (1) { - shared_ptr<CSGTerm> n = CSGTerm::normalize(background_terms[i]); - if (background_terms[i] == n) break; - background_terms[i] = n; - } + background_terms[i] = normalizer.normalize(background_terms[i]); background_chain->import(background_terms[i]); } } @@ -1814,8 +1799,9 @@ MainWindow::preferences() void MainWindow::setFont(const QString &family, uint size) { - QFont font(editor->font()); + QFont font; if (!family.isEmpty()) font.setFamily(family); + else font.setFixedPitch(true); if (size > 0) font.setPointSize(size); font.setStyleHint(QFont::TypeWriter); editor->setFont(font); diff --git a/src/openscad.cc b/src/openscad.cc index 6f4d7c7..04c25bb 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -344,6 +344,10 @@ int main(int argc, char **argv) } if (dxf_output_file) { + if (root_N.dim != 2) { + fprintf(stderr, "Current top level object is not a 2D object.\n"); + exit(1); + } std::ofstream fstream(dxf_output_file); if (!fstream.is_open()) { PRINTF("Can't open file \"%s\" for export", dxf_output_file); diff --git a/src/parser.y b/src/parser.y index df652f5..1c4a784 100644 --- a/src/parser.y +++ b/src/parser.y @@ -586,12 +586,15 @@ AbstractModule *parse(const char *text, const char *path, int debug) if (!module) return NULL; - BOOST_FOREACH(Module::ModuleContainer::value_type &m, module->usedlibs) { - module->usedlibs[m.first] = Module::compile_library(m.first); - if (!module->usedlibs[m.first]) { - PRINTF("WARNING: Failed to compile library `%s'.", m.first.c_str()); - module->usedlibs.erase(m.first); - } + // Iterating manually since we want to modify the container while iterating + Module::ModuleContainer::iterator iter = module->usedlibs.begin(); + while (iter != module->usedlibs.end()) { + Module::ModuleContainer::iterator curr = iter++; + curr->second = Module::compile_library(curr->first); + if (!curr->second) { + PRINTF("WARNING: Failed to compile library `%s'.", curr->first.c_str()); + module->usedlibs.erase(curr); + } } parser_error_pos = -1; diff --git a/src/renderer.cc b/src/renderer.cc index b791673..5a767b8 100644 --- a/src/renderer.cc +++ b/src/renderer.cc @@ -2,7 +2,7 @@ #include "rendersettings.h" #include <QColor> -void Renderer::setColor(const double color[4], GLint *shaderinfo) const +void Renderer::setColor(const float color[4], GLint *shaderinfo) const { QColor col = RenderSettings::inst()->color(RenderSettings::OPENCSG_FACE_FRONT_COLOR); double c[4] = {color[0], color[1], color[2], color[3]}; diff --git a/src/renderer.h b/src/renderer.h index 8deabe8..2bc482d 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -25,7 +25,7 @@ public: COLORMODE_BACKGROUND_EDGES }; - virtual void setColor(const double color[4], GLint *shaderinfo = NULL) const; + virtual void setColor(const float color[4], GLint *shaderinfo = NULL) const; virtual void setColor(ColorMode colormode, GLint *shaderinfo = NULL) const; }; diff --git a/src/state.h b/src/state.h index 5dc74df..df202aa 100644 --- a/src/state.h +++ b/src/state.h @@ -9,8 +9,8 @@ class State public: State(const class AbstractNode *parent) : parentnode(parent), isprefix(false), ispostfix(false), numchildren(0) { - m = Transform3d::Identity(); - for (int i=0;i<4;i++) this->c[i] = -1.0; + this->matrix_ = Transform3d::Identity(); + this->color_.fill(-1.0f); } virtual ~State() {} @@ -18,15 +18,15 @@ public: void setPostfix(bool on) { this->ispostfix = on; } void setNumChildren(unsigned int numc) { this->numchildren = numc; } void setParent(const AbstractNode *parent) { this->parentnode = parent; } - void setMatrix(const Transform3d &m) { this->m = m; } - void setColor(const double c[4]) { memcpy(this->c, c, 4*sizeof(double)); } + void setMatrix(const Transform3d &m) { this->matrix_ = m; } + void setColor(const Color4f &c) { this->color_ = c; } bool isPrefix() const { return this->isprefix; } bool isPostfix() const { return this->ispostfix; } unsigned int numChildren() const { return this->numchildren; } const AbstractNode *parent() const { return this->parentnode; } - const Transform3d &matrix() const { return this->m; } - const double *color() const { return this->c; } + const Transform3d &matrix() const { return this->matrix_; } + const Color4f &color() const { return this->color_; } private: const AbstractNode * parentnode; @@ -35,8 +35,8 @@ private: unsigned int numchildren; // Transformation matrix and color. FIXME: Generalize such state variables? - Transform3d m; - double c[4]; + Transform3d matrix_; + Color4f color_; }; #endif |