summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CGALCache.cc2
-rw-r--r--src/CSGTermEvaluator.cc2
-rw-r--r--src/OpenCSGRenderer.cc4
-rw-r--r--src/OpenCSGWarningDialog.ui3
-rw-r--r--src/Preferences.cc14
-rw-r--r--src/ThrownTogetherRenderer.cc6
-rw-r--r--src/colornode.h3
-rw-r--r--src/csgterm.cc128
-rw-r--r--src/csgterm.h11
-rw-r--r--src/csgtermnormalizer.cc150
-rw-r--r--src/csgtermnormalizer.h22
-rw-r--r--src/export.cc39
-rw-r--r--src/glview.cc9
-rw-r--r--src/lexer.l21
-rw-r--r--src/linalg.h6
-rw-r--r--src/mainwin.cc28
-rw-r--r--src/openscad.cc4
-rw-r--r--src/parser.y15
-rw-r--r--src/renderer.cc2
-rw-r--r--src/renderer.h2
-rw-r--r--src/state.h16
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
contact: Jan Huwald // Impressum