diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CGALEvaluator.cc | 22 | ||||
-rw-r--r-- | src/CGALRenderer.cc | 5 | ||||
-rw-r--r-- | src/CGAL_Nef_polyhedron.cc | 15 | ||||
-rw-r--r-- | src/GLView.h | 5 | ||||
-rw-r--r-- | src/MainWindow.h | 3 | ||||
-rw-r--r-- | src/MainWindow.ui | 6 | ||||
-rw-r--r-- | src/OpenCSGRenderer.cc | 35 | ||||
-rw-r--r-- | src/OpenCSGWarningDialog.cc | 23 | ||||
-rw-r--r-- | src/OpenCSGWarningDialog.h | 16 | ||||
-rw-r--r-- | src/OpenCSGWarningDialog.ui | 93 | ||||
-rw-r--r-- | src/PolySetCGALEvaluator.cc | 9 | ||||
-rw-r--r-- | src/Preferences.cc | 108 | ||||
-rw-r--r-- | src/Preferences.h | 17 | ||||
-rw-r--r-- | src/Preferences.ui | 18 | ||||
-rw-r--r-- | src/ThrownTogetherRenderer.cc | 57 | ||||
-rw-r--r-- | src/cgaladv_convexhull2.cc | 54 | ||||
-rw-r--r-- | src/glview.cc | 147 | ||||
-rw-r--r-- | src/lexer.l | 58 | ||||
-rw-r--r-- | src/mainwin.cc | 17 | ||||
-rw-r--r-- | src/polyset.cc | 57 | ||||
-rw-r--r-- | src/polyset.h | 12 | ||||
-rw-r--r-- | src/primitives.cc | 2 | ||||
-rw-r--r-- | src/renderer.cc | 66 | ||||
-rw-r--r-- | src/renderer.h | 21 | ||||
-rw-r--r-- | src/rendersettings.cc | 35 | ||||
-rw-r--r-- | src/rendersettings.h | 35 |
26 files changed, 608 insertions, 328 deletions
diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index 1772354..684ab42 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -116,13 +116,12 @@ CGAL_Nef_polyhedron CGALEvaluator::applyToChildren(const AbstractNode &node, CGA return N; } -extern CGAL_Nef_polyhedron2 *convexhull2(std::list<CGAL_Nef_polyhedron2*> a); - CGAL_Nef_polyhedron CGALEvaluator::applyHull(const CgaladvNode &node) { CGAL_Nef_polyhedron N; std::list<CGAL_Nef_polyhedron2*> polys; - std::list<CGAL_Polyhedron::Vertex::Point_3> points; + std::list<CGAL_Nef_polyhedron2::Point> points2d; + std::list<CGAL_Polyhedron::Vertex::Point_3> points3d; int dim = 0; BOOST_FOREACH(const ChildItem &item, this->visitedchildren[node.index()]) { const AbstractNode *chnode = item.first; @@ -137,23 +136,32 @@ CGAL_Nef_polyhedron CGALEvaluator::applyHull(const CgaladvNode &node) continue; } if (dim == 2) { - polys.push_back(chN.p2.get()); + CGAL_Nef_polyhedron2::Explorer explorer = chN.p2->explorer(); + BOOST_FOREACH(const CGAL_Nef_polyhedron2::Explorer::Vertex &vh, + std::make_pair(explorer.vertices_begin(), explorer.vertices_end())) { + if (explorer.is_standard(&vh)) { + points2d.push_back(explorer.point(&vh)); + } + } } else if (dim == 3) { CGAL_Polyhedron P; chN.p3->convert_to_Polyhedron(P); - std::transform(P.vertices_begin(), P.vertices_end(), std::back_inserter(points), + std::transform(P.vertices_begin(), P.vertices_end(), std::back_inserter(points3d), boost::bind(static_cast<const CGAL_Polyhedron::Vertex::Point_3&(CGAL_Polyhedron::Vertex::*)() const>(&CGAL_Polyhedron::Vertex::point), _1)); } chnode->progress_report(); } if (dim == 2) { - N = CGAL_Nef_polyhedron(convexhull2(polys)); + std::list<CGAL_Nef_polyhedron2::Point> result; + CGAL::convex_hull_2(points2d.begin(), points2d.end(),std:: back_inserter(result)); + N = CGAL_Nef_polyhedron(new CGAL_Nef_polyhedron2(result.begin(), result.end(), + CGAL_Nef_polyhedron2::INCLUDED)); } else if (dim == 3) { CGAL_Polyhedron P; - CGAL::convex_hull_3(points.begin(), points.end(), P); + CGAL::convex_hull_3(points3d.begin(), points3d.end(), P); N = CGAL_Nef_polyhedron(new CGAL_Nef_polyhedron3(P)); } return N; diff --git a/src/CGALRenderer.cc b/src/CGALRenderer.cc index 95bcba1..bac25a6 100644 --- a/src/CGALRenderer.cc +++ b/src/CGALRenderer.cc @@ -24,6 +24,11 @@ * */ +#ifdef _MSC_VER +// Boost conflicts with MPFR under MSVC (google it) +#include <mpfr.h> +#endif + // dxfdata.h must come first for Eigen SIMD alignment issues #include "dxfdata.h" #include "polyset.h" diff --git a/src/CGAL_Nef_polyhedron.cc b/src/CGAL_Nef_polyhedron.cc index 8c65777..6ed2d90 100644 --- a/src/CGAL_Nef_polyhedron.cc +++ b/src/CGAL_Nef_polyhedron.cc @@ -71,6 +71,8 @@ int CGAL_Nef_polyhedron::weight() const This method is not const since convert_to_Polyhedron() wasn't const in earlier versions of CGAL. + + Note: Can return NULL if an error occurred */ PolySet *CGAL_Nef_polyhedron::convertToPolyset() { @@ -85,9 +87,16 @@ PolySet *CGAL_Nef_polyhedron::convertToPolyset() delete dd; } else if (this->dim == 3) { - CGAL_Polyhedron P; - this->p3->convert_to_Polyhedron(P); - ps = createPolySetFromPolyhedron(P); + CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); + try { + CGAL_Polyhedron P; + this->p3->convert_to_Polyhedron(P); + ps = createPolySetFromPolyhedron(P); + } + catch (CGAL::Precondition_exception e) { + PRINTF("CGAL error in CGAL_Nef_polyhedron::convertToPolyset(): %s", e.what()); + } + CGAL::set_error_behaviour(old_behaviour); } return ps; } diff --git a/src/GLView.h b/src/GLView.h index c31e7af..5552e4b 100644 --- a/src/GLView.h +++ b/src/GLView.h @@ -32,7 +32,8 @@ public: void setShowCrosshairs(bool enabled) { this->showcrosshairs = enabled; } bool orthoMode() const { return this->orthomode; } void setOrthoMode(bool enabled) { this->orthomode = enabled; } - + const QString &getRendererInfo() const { return this->rendererInfo; } + public: QLabel *statusLabel; double object_rot_x; @@ -52,6 +53,8 @@ private: void init(); Renderer *renderer; + QString rendererInfo; + bool showfaces; bool showedges; bool showaxes; diff --git a/src/MainWindow.h b/src/MainWindow.h index b2d0f60..0f2a922 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -86,6 +86,8 @@ private: void loadViewSettings(); void loadDesignSettings(); + class QMessageBox *openglbox; + private slots: void actionNew(); void actionOpen(); @@ -156,6 +158,7 @@ public slots: void helpAbout(); void helpHomepage(); void helpManual(); + void helpOpenGL(); void quit(); void actionReloadCompile(); void checkAutoReload(); diff --git a/src/MainWindow.ui b/src/MainWindow.ui index dc73c05..d1bdb00 100644 --- a/src/MainWindow.ui +++ b/src/MainWindow.ui @@ -218,6 +218,7 @@ <addaction name="helpActionAbout"/> <addaction name="helpActionHomepage"/> <addaction name="helpActionManual"/> + <addaction name="helpActionOpenGLInfo"/> </widget> <addaction name="menu_File"/> <addaction name="menu_Edit"/> @@ -666,6 +667,11 @@ <string>Export as CSG...</string> </property> </action> + <action name="helpActionOpenGLInfo"> + <property name="text"> + <string>OpenGL info</string> + </property> + </action> </widget> <customwidgets> <customwidget> diff --git a/src/OpenCSGRenderer.cc b/src/OpenCSGRenderer.cc index a1aafc5..233124b 100644 --- a/src/OpenCSGRenderer.cc +++ b/src/OpenCSGRenderer.cc @@ -40,11 +40,11 @@ public: OpenCSG::Primitive(operation, convexity) { } shared_ptr<PolySet> ps; Transform3d m; - int csgmode; + PolySet::csgmode_e csgmode; virtual void render() { glPushMatrix(); glMultMatrixd(m.data()); - ps->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m); + ps->render_surface(csgmode, m); glPopMatrix(); } }; @@ -89,24 +89,23 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo, double *c = chain->colors[j]; glPushMatrix(); glMultMatrixd(m.data()); - int csgmode = chain->types[j] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; + PolySet::csgmode_e csgmode = chain->types[j] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; if (highlight) { - chain->polysets[j]->render_surface(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20), m, shaderinfo); - } else if (background) { - chain->polysets[j]->render_surface(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10), m, shaderinfo); - } else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0) { - // User-defined color from source - glColor4dv(c); - if (shaderinfo) { - glUniform4f(shaderinfo[1], c[0], c[1], c[2], c[3]); - glUniform4f(shaderinfo[2], (c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0); - } - chain->polysets[j]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m, shaderinfo); + setColor(COLORMODE_HIGHLIGHT, shaderinfo); + csgmode = PolySet::csgmode_e(csgmode + 20); + } + else if (background) { + setColor(COLORMODE_BACKGROUND, 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); } else if (chain->types[j] == CSGTerm::TYPE_DIFFERENCE) { - chain->polysets[j]->render_surface(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode), m, shaderinfo); + setColor(COLORMODE_CUTOUT, shaderinfo); } else { - chain->polysets[j]->render_surface(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode), m, shaderinfo); + setColor(COLORMODE_MATERIAL, shaderinfo); } + chain->polysets[j]->render_surface(csgmode, m, shaderinfo); glPopMatrix(); } if (shaderinfo) glUseProgram(0); @@ -124,8 +123,8 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo, prim->ps = chain->polysets[i]; prim->m = chain->matrices[i]; prim->csgmode = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; - if (highlight) prim->csgmode += 20; - else if (background) prim->csgmode += 10; + if (highlight) prim->csgmode = PolySet::csgmode_e(prim->csgmode + 20); + else if (background) prim->csgmode = PolySet::csgmode_e(prim->csgmode + 10); primitives.push_back(prim); } std::for_each(primitives.begin(), primitives.end(), del_fun<OpenCSG::Primitive>()); diff --git a/src/OpenCSGWarningDialog.cc b/src/OpenCSGWarningDialog.cc new file mode 100644 index 0000000..fdaaa50 --- /dev/null +++ b/src/OpenCSGWarningDialog.cc @@ -0,0 +1,23 @@ +#include "OpenCSGWarningDialog.h" +#include "Preferences.h" + +OpenCSGWarningDialog::OpenCSGWarningDialog(QWidget *parent) +{ + setupUi(this); + + connect(this->showBox, SIGNAL(toggled(bool)), + Preferences::inst()->openCSGWarningBox, SLOT(setChecked(bool))); + connect(this->showBox, SIGNAL(toggled(bool)), + Preferences::inst(), SLOT(openCSGWarningChanged(bool))); + + connect(this->enableOpenCSGBox, SIGNAL(toggled(bool)), + Preferences::inst()->enableOpenCSGBox, SLOT(setChecked(bool))); + connect(this->enableOpenCSGBox, SIGNAL(toggled(bool)), + Preferences::inst(), SLOT(enableOpenCSGChanged(bool))); +} + +void OpenCSGWarningDialog::setText(const QString &text) +{ + this->warningText->setPlainText(text); +} + diff --git a/src/OpenCSGWarningDialog.h b/src/OpenCSGWarningDialog.h new file mode 100644 index 0000000..5d9c8fa --- /dev/null +++ b/src/OpenCSGWarningDialog.h @@ -0,0 +1,16 @@ +#ifndef OPENCSGWARNINGDIALOG_H_ +#define OPENCSGWARNINGDIALOG_H_ + +#include "ui_OpenCSGWarningDialog.h" + +class OpenCSGWarningDialog : public QDialog, public Ui::OpenCSGWarningDialog +{ + Q_OBJECT; +public: + OpenCSGWarningDialog(QWidget *parent); + +public slots: + void setText(const QString &text); +}; + +#endif diff --git a/src/OpenCSGWarningDialog.ui b/src/OpenCSGWarningDialog.ui new file mode 100644 index 0000000..f902521 --- /dev/null +++ b/src/OpenCSGWarningDialog.ui @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>OpenCSGWarningDialog</class> + <widget class="QDialog" name="OpenCSGWarningDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>412</width> + <height>275</height> + </rect> + </property> + <property name="windowTitle"> + <string>OpenGL Warning</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTextEdit" name="warningText"> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="html"> + <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html></string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="enableOpenCSGBox"> + <property name="text"> + <string>Enable OpenCSG</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QCheckBox" name="showBox"> + <property name="text"> + <string>Show this message again</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="closeButton"> + <property name="text"> + <string>Close</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>closeButton</sender> + <signal>clicked()</signal> + <receiver>OpenCSGWarningDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>361</x> + <y>246</y> + </hint> + <hint type="destinationlabel"> + <x>205</x> + <y>137</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index 78d5704..7a9566b 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -396,8 +396,13 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const RenderNode &node) CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(node); PolySet *ps = NULL; if (!N.empty()) { - ps = N.convertToPolyset(); - ps->convexity = node.convexity; + if (!N.p3->is_simple()) { + PRINTF("WARNING: Body of render() isn't valid 2-manifold!"); + } + else { + ps = N.convertToPolyset(); + ps->convexity = node.convexity; + } } return ps; } diff --git a/src/Preferences.cc b/src/Preferences.cc index d240a9f..59f8d23 100644 --- a/src/Preferences.cc +++ b/src/Preferences.cc @@ -36,11 +36,21 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent) { setupUi(this); + // Editor pane + QFontDatabase db; + foreach(int size, db.standardSizes()) { + this->fontSize->addItem(QString::number(size)); + if (size == 12) { + this->fontSize->setCurrentIndex(this->fontSize->count()-1); + } + } + // 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(); - this->defaultmap["editor/opengl20_warning_show"] = true; + this->defaultmap["advanced/opencsg_show_warning"] = true; + this->defaultmap["advanced/enable_opencsg_opengl1x"] = false; // Toolbar QActionGroup *group = new QActionGroup(this); @@ -53,44 +63,38 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent) this->actionTriggered(this->prefsAction3DView); // 3D View pane - this->colorschemes["Cornfield"][BACKGROUND_COLOR] = QColor(0xff, 0xff, 0xe5); - this->colorschemes["Cornfield"][OPENCSG_FACE_FRONT_COLOR] = QColor(0xf9, 0xd7, 0x2c); - this->colorschemes["Cornfield"][OPENCSG_FACE_BACK_COLOR] = QColor(0x9d, 0xcb, 0x51); - this->colorschemes["Cornfield"][CGAL_FACE_FRONT_COLOR] = QColor(0xf9, 0xd7, 0x2c); - this->colorschemes["Cornfield"][CGAL_FACE_BACK_COLOR] = QColor(0x9d, 0xcb, 0x51); - this->colorschemes["Cornfield"][CGAL_FACE_2D_COLOR] = QColor(0x00, 0xbf, 0x99); - this->colorschemes["Cornfield"][CGAL_EDGE_FRONT_COLOR] = QColor(0xff, 0x00, 0x00); - this->colorschemes["Cornfield"][CGAL_EDGE_BACK_COLOR] = QColor(0xff, 0x00, 0x00); - this->colorschemes["Cornfield"][CGAL_EDGE_2D_COLOR] = QColor(0xff, 0x00, 0x00); - this->colorschemes["Cornfield"][CROSSHAIR_COLOR] = QColor(0x80, 0x00, 0x00); - - this->colorschemes["Metallic"][BACKGROUND_COLOR] = QColor(0xaa, 0xaa, 0xff); - this->colorschemes["Metallic"][OPENCSG_FACE_FRONT_COLOR] = QColor(0xdd, 0xdd, 0xff); - this->colorschemes["Metallic"][OPENCSG_FACE_BACK_COLOR] = QColor(0xdd, 0x22, 0xdd); - this->colorschemes["Metallic"][CGAL_FACE_FRONT_COLOR] = QColor(0xdd, 0xdd, 0xff); - this->colorschemes["Metallic"][CGAL_FACE_BACK_COLOR] = QColor(0xdd, 0x22, 0xdd); - this->colorschemes["Metallic"][CGAL_FACE_2D_COLOR] = QColor(0x00, 0xbf, 0x99); - this->colorschemes["Metallic"][CGAL_EDGE_FRONT_COLOR] = QColor(0xff, 0x00, 0x00); - this->colorschemes["Metallic"][CGAL_EDGE_BACK_COLOR] = QColor(0xff, 0x00, 0x00); - this->colorschemes["Metallic"][CGAL_EDGE_2D_COLOR] = QColor(0xff, 0x00, 0x00); - this->colorschemes["Metallic"][CROSSHAIR_COLOR] = QColor(0x80, 0x00, 0x00); - - this->colorschemes["Sunset"][BACKGROUND_COLOR] = QColor(0xaa, 0x44, 0x44); - this->colorschemes["Sunset"][OPENCSG_FACE_FRONT_COLOR] = QColor(0xff, 0xaa, 0xaa); - this->colorschemes["Sunset"][OPENCSG_FACE_BACK_COLOR] = QColor(0x88, 0x22, 0x33); - this->colorschemes["Sunset"][CGAL_FACE_FRONT_COLOR] = QColor(0xff, 0xaa, 0xaa); - this->colorschemes["Sunset"][CGAL_FACE_BACK_COLOR] = QColor(0x88, 0x22, 0x33); - this->colorschemes["Sunset"][CGAL_FACE_2D_COLOR] = QColor(0x00, 0xbf, 0x99); - this->colorschemes["Sunset"][CGAL_EDGE_FRONT_COLOR] = QColor(0xff, 0x00, 0x00); - this->colorschemes["Sunset"][CGAL_EDGE_BACK_COLOR] = QColor(0xff, 0x00, 0x00); - this->colorschemes["Sunset"][CGAL_EDGE_2D_COLOR] = QColor(0xff, 0x00, 0x00); - this->colorschemes["Sunset"][CROSSHAIR_COLOR] = QColor(0x80, 0x00, 0x00); - - // Editor pane - QFontDatabase db; - foreach(int size, db.standardSizes()) { - this->fontSize->addItem(QString::number(size)); - } + this->colorschemes["Cornfield"][RenderSettings::BACKGROUND_COLOR] = QColor(0xff, 0xff, 0xe5); + this->colorschemes["Cornfield"][RenderSettings::OPENCSG_FACE_FRONT_COLOR] = QColor(0xf9, 0xd7, 0x2c); + this->colorschemes["Cornfield"][RenderSettings::OPENCSG_FACE_BACK_COLOR] = QColor(0x9d, 0xcb, 0x51); + this->colorschemes["Cornfield"][RenderSettings::CGAL_FACE_FRONT_COLOR] = QColor(0xf9, 0xd7, 0x2c); + this->colorschemes["Cornfield"][RenderSettings::CGAL_FACE_BACK_COLOR] = QColor(0x9d, 0xcb, 0x51); + this->colorschemes["Cornfield"][RenderSettings::CGAL_FACE_2D_COLOR] = QColor(0x00, 0xbf, 0x99); + this->colorschemes["Cornfield"][RenderSettings::CGAL_EDGE_FRONT_COLOR] = QColor(0xff, 0x00, 0x00); + this->colorschemes["Cornfield"][RenderSettings::CGAL_EDGE_BACK_COLOR] = QColor(0xff, 0x00, 0x00); + this->colorschemes["Cornfield"][RenderSettings::CGAL_EDGE_2D_COLOR] = QColor(0xff, 0x00, 0x00); + this->colorschemes["Cornfield"][RenderSettings::CROSSHAIR_COLOR] = QColor(0x80, 0x00, 0x00); + + this->colorschemes["Metallic"][RenderSettings::BACKGROUND_COLOR] = QColor(0xaa, 0xaa, 0xff); + this->colorschemes["Metallic"][RenderSettings::OPENCSG_FACE_FRONT_COLOR] = QColor(0xdd, 0xdd, 0xff); + this->colorschemes["Metallic"][RenderSettings::OPENCSG_FACE_BACK_COLOR] = QColor(0xdd, 0x22, 0xdd); + this->colorschemes["Metallic"][RenderSettings::CGAL_FACE_FRONT_COLOR] = QColor(0xdd, 0xdd, 0xff); + this->colorschemes["Metallic"][RenderSettings::CGAL_FACE_BACK_COLOR] = QColor(0xdd, 0x22, 0xdd); + this->colorschemes["Metallic"][RenderSettings::CGAL_FACE_2D_COLOR] = QColor(0x00, 0xbf, 0x99); + this->colorschemes["Metallic"][RenderSettings::CGAL_EDGE_FRONT_COLOR] = QColor(0xff, 0x00, 0x00); + this->colorschemes["Metallic"][RenderSettings::CGAL_EDGE_BACK_COLOR] = QColor(0xff, 0x00, 0x00); + this->colorschemes["Metallic"][RenderSettings::CGAL_EDGE_2D_COLOR] = QColor(0xff, 0x00, 0x00); + this->colorschemes["Metallic"][RenderSettings::CROSSHAIR_COLOR] = QColor(0x80, 0x00, 0x00); + + this->colorschemes["Sunset"][RenderSettings::BACKGROUND_COLOR] = QColor(0xaa, 0x44, 0x44); + this->colorschemes["Sunset"][RenderSettings::OPENCSG_FACE_FRONT_COLOR] = QColor(0xff, 0xaa, 0xaa); + this->colorschemes["Sunset"][RenderSettings::OPENCSG_FACE_BACK_COLOR] = QColor(0x88, 0x22, 0x33); + this->colorschemes["Sunset"][RenderSettings::CGAL_FACE_FRONT_COLOR] = QColor(0xff, 0xaa, 0xaa); + this->colorschemes["Sunset"][RenderSettings::CGAL_FACE_BACK_COLOR] = QColor(0x88, 0x22, 0x33); + this->colorschemes["Sunset"][RenderSettings::CGAL_FACE_2D_COLOR] = QColor(0x00, 0xbf, 0x99); + this->colorschemes["Sunset"][RenderSettings::CGAL_EDGE_FRONT_COLOR] = QColor(0xff, 0x00, 0x00); + this->colorschemes["Sunset"][RenderSettings::CGAL_EDGE_BACK_COLOR] = QColor(0xff, 0x00, 0x00); + this->colorschemes["Sunset"][RenderSettings::CGAL_EDGE_2D_COLOR] = QColor(0xff, 0x00, 0x00); + this->colorschemes["Sunset"][RenderSettings::CROSSHAIR_COLOR] = QColor(0x80, 0x00, 0x00); connect(this->colorSchemeChooser, SIGNAL(itemSelectionChanged()), this, SLOT(colorSchemeChanged())); @@ -98,9 +102,11 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent) this, SLOT(fontFamilyChanged(const QString &))); connect(this->fontSize, SIGNAL(editTextChanged(const QString &)), this, SLOT(fontSizeChanged(const QString &))); - connect(this->openCSGWarningBox, SIGNAL(clicked(bool)), + connect(this->openCSGWarningBox, SIGNAL(toggled(bool)), this, SLOT(openCSGWarningChanged(bool))); updateGUI(); + + RenderSettings::inst()->setColors(this->colorschemes[getValue("3dview/colorscheme").toString()]); } Preferences::~Preferences() @@ -124,15 +130,13 @@ Preferences::actionTriggered(QAction *action) void Preferences::colorSchemeChanged() { + QString scheme = this->colorSchemeChooser->currentItem()->text(); QSettings settings; - settings.setValue("3dview/colorscheme", this->colorSchemeChooser->currentItem()->text()); + settings.setValue("3dview/colorscheme", scheme); - emit requestRedraw(); -} + RenderSettings::inst()->setColors(this->colorschemes[scheme]); -const QColor &Preferences::color(RenderColor idx) -{ - return this->colorschemes[getValue("3dview/colorscheme").toString()][idx]; + emit requestRedraw(); } void Preferences::fontFamilyChanged(const QString &family) @@ -154,7 +158,14 @@ void Preferences::openCSGWarningChanged(bool state) { QSettings settings; - settings.setValue("editor/opengl20_warning_show",state); + settings.setValue("advanced/opencsg_show_warning",state); +} + +void +Preferences::enableOpenCSGChanged(bool state) +{ + QSettings settings; + settings.setValue("advanced/enable_opencsg_opengl1x", state); } void Preferences::keyPressEvent(QKeyEvent *e) @@ -215,7 +226,8 @@ void Preferences::updateGUI() this->fontSize->setEditText(fontsize); } - this->openCSGWarningBox->setChecked(getValue("editor/opengl20_warning_show").toBool()); + this->openCSGWarningBox->setChecked(getValue("advanced/opencsg_show_warning").toBool()); + this->enableOpenCSGBox->setChecked(getValue("advanced/enable_opencsg_opengl1x").toBool()); } void Preferences::apply() const diff --git a/src/Preferences.h b/src/Preferences.h index bdc707d..7e22e63 100644 --- a/src/Preferences.h +++ b/src/Preferences.h @@ -4,6 +4,7 @@ #include <QMainWindow> #include <QSettings> #include "ui_Preferences.h" +#include "rendersettings.h" class Preferences : public QMainWindow, public Ui::Preferences { @@ -13,19 +14,6 @@ public: ~Preferences(); static Preferences *inst() { if (!instance) instance = new Preferences(); return instance; } - enum RenderColor { - BACKGROUND_COLOR, - OPENCSG_FACE_FRONT_COLOR, - OPENCSG_FACE_BACK_COLOR, - CGAL_FACE_FRONT_COLOR, - CGAL_FACE_2D_COLOR, - CGAL_FACE_BACK_COLOR, - CGAL_EDGE_FRONT_COLOR, - CGAL_EDGE_BACK_COLOR, - CGAL_EDGE_2D_COLOR, - CROSSHAIR_COLOR - }; - const QColor &color(RenderColor idx); QVariant getValue(const QString &key) const; void apply() const; @@ -35,6 +23,7 @@ public slots: void fontFamilyChanged(const QString &); void fontSizeChanged(const QString &); void openCSGWarningChanged(bool); + void enableOpenCSGChanged(bool); signals: void requestRedraw() const; @@ -47,7 +36,7 @@ private: void removeDefaultSettings(); QSettings::SettingsMap defaultmap; - QHash<QString, QMap<RenderColor, QColor> > colorschemes; + QHash<QString, QMap<RenderSettings::RenderColor, QColor> > colorschemes; static Preferences *instance; }; diff --git a/src/Preferences.ui b/src/Preferences.ui index 556172c..6b80674 100644 --- a/src/Preferences.ui +++ b/src/Preferences.ui @@ -185,6 +185,16 @@ <property name="text"> <string>Show OpenCSG capability warning</string> </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="enableOpenCSGBox"> + <property name="text"> + <string>Enable OpenCSG for OpenGL 1.x</string> + </property> </widget> </item> <item> @@ -239,7 +249,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset> + <iconset resource="../openscad.qrc"> <normaloff>:/icons/prefs3DView.png</normaloff>:/icons/prefs3DView.png</iconset> </property> <property name="text"> @@ -251,7 +261,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset> + <iconset resource="../openscad.qrc"> <normaloff>:/icons/prefsAdvanced.png</normaloff>:/icons/prefsAdvanced.png</iconset> </property> <property name="text"> @@ -263,7 +273,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset> + <iconset resource="../openscad.qrc"> <normaloff>:/icons/prefsEditor.png</normaloff>:/icons/prefsEditor.png</iconset> </property> <property name="text"> @@ -272,7 +282,7 @@ </action> </widget> <resources> - <include location="openscad.qrc"/> + <include location="../openscad.qrc"/> </resources> <connections/> </ui> diff --git a/src/ThrownTogetherRenderer.cc b/src/ThrownTogetherRenderer.cc index 3ab13ea..36f7b95 100644 --- a/src/ThrownTogetherRenderer.cc +++ b/src/ThrownTogetherRenderer.cc @@ -70,51 +70,48 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight, double *c = chain->colors[i]; glPushMatrix(); glMultMatrixd(m.data()); - int csgmode = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; + PolySet::csgmode_e csgmode = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; if (highlight) { - chain->polysets[i]->render_surface(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20), m); + csgmode = PolySet::csgmode_e(csgmode + 20); + setColor(COLORMODE_HIGHLIGHT); + chain->polysets[i]->render_surface(csgmode, m); if (showedges) { - glDisable(GL_LIGHTING); - chain->polysets[i]->render_edges(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20)); - glEnable(GL_LIGHTING); + setColor(COLORMODE_HIGHLIGHT_EDGES); + chain->polysets[i]->render_edges(csgmode); } } else if (background) { - chain->polysets[i]->render_surface(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10), m); + csgmode = PolySet::csgmode_e(csgmode + 10); + setColor(COLORMODE_BACKGROUND); + chain->polysets[i]->render_surface(csgmode, m); if (showedges) { - glDisable(GL_LIGHTING); - chain->polysets[i]->render_edges(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10)); - glEnable(GL_LIGHTING); + setColor(COLORMODE_BACKGROUND_EDGES); + chain->polysets[i]->render_edges(csgmode); } } else if (fberror) { - if (highlight) { - chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode + 20), m); - } else if (background) { - chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode + 10), m); - } else { - chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m); - } - } else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0) { - glColor4dv(c); - chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m); + if (highlight) csgmode = PolySet::csgmode_e(csgmode + 20); + else if (background) csgmode = PolySet::csgmode_e(csgmode + 10); + 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); + chain->polysets[i]->render_surface(csgmode, m); if (showedges) { - glDisable(GL_LIGHTING); glColor4d((c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0); - chain->polysets[i]->render_edges(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode)); - glEnable(GL_LIGHTING); + chain->polysets[i]->render_edges(csgmode); } } else if (chain->types[i] == CSGTerm::TYPE_DIFFERENCE) { - chain->polysets[i]->render_surface(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode), m); + setColor(COLORMODE_CUTOUT); + chain->polysets[i]->render_surface(csgmode, m); if (showedges) { - glDisable(GL_LIGHTING); - chain->polysets[i]->render_edges(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode)); - glEnable(GL_LIGHTING); + setColor(COLORMODE_CUTOUT_EDGES); + chain->polysets[i]->render_edges(csgmode); } } else { - chain->polysets[i]->render_surface(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode), m); + setColor(COLORMODE_MATERIAL); + chain->polysets[i]->render_surface(csgmode, m); if (showedges) { - glDisable(GL_LIGHTING); - chain->polysets[i]->render_edges(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode)); - glEnable(GL_LIGHTING); + setColor(COLORMODE_MATERIAL_EDGES); + chain->polysets[i]->render_edges(csgmode); } } glPopMatrix(); diff --git a/src/cgaladv_convexhull2.cc b/src/cgaladv_convexhull2.cc deleted file mode 100644 index 492df3c..0000000 --- a/src/cgaladv_convexhull2.cc +++ /dev/null @@ -1,54 +0,0 @@ -/* - * OpenSCAD (www.openscad.org) - * Copyright (C) 2009-2011 Clifford Wolf <clifford@clifford.at> and - * Marius Kintel <marius@kintel.net> - * - * 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. - * - * As a special exception, you have permission to link this program - * with the CGAL library and distribute executables, as long as you - * follow the requirements of the GNU GPL in regard to all of the - * software in the executable aside from CGAL. - * - * 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 - * - */ - -#ifdef ENABLE_CGAL - -#include "cgal.h" -#include <CGAL/convex_hull_2.h> - -extern CGAL_Poly2 nef2p2(CGAL_Nef_polyhedron2 p); - -CGAL_Nef_polyhedron2 *convexhull2(std::list<CGAL_Nef_polyhedron2*> a) -{ - std::list<CGAL_Nef_polyhedron2::Point> points; - - std::list<CGAL_Nef_polyhedron2*>::iterator i; - for (i=a.begin(); i!=a.end(); i++) { - CGAL_Poly2 ap=nef2p2(**i); - for (size_t j=0;j<ap.size();j++) { - double x=to_double(ap[j].x()),y=to_double(ap[j].y()); - CGAL_Nef_polyhedron2::Point p=CGAL_Nef_polyhedron2::Point(x,y); - points.push_back(p); - } - } - - std::list<CGAL_Nef_polyhedron2::Point> result; - CGAL::convex_hull_2(points.begin(),points.end(),std::back_inserter(result)); - - return new CGAL_Nef_polyhedron2(result.begin(),result.end(),CGAL_Nef_polyhedron2::INCLUDED); -} - -#endif diff --git a/src/glview.cc b/src/glview.cc index bc287b5..c96fe01 100644 --- a/src/glview.cc +++ b/src/glview.cc @@ -27,6 +27,7 @@ #include "GLView.h" #include "Preferences.h" #include "renderer.h" +#include "rendersettings.h" #include <QApplication> #include <QWheelEvent> @@ -39,6 +40,9 @@ #include <QTimer> #include <QTextEdit> #include <QVBoxLayout> +#include <QErrorMessage> +#include "OpenCSGWarningDialog.h" + #include "mathc99.h" #include <stdio.h> @@ -133,35 +137,84 @@ void GLView::initializeGL() fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err)); } + GLint rbits, gbits, bbits, abits, dbits, sbits; + glGetIntegerv(GL_RED_BITS, &rbits); + glGetIntegerv(GL_GREEN_BITS, &gbits); + glGetIntegerv(GL_BLUE_BITS, &bbits); + glGetIntegerv(GL_ALPHA_BITS, &abits); + glGetIntegerv(GL_DEPTH_BITS, &dbits); + glGetIntegerv(GL_STENCIL_BITS, &sbits); + + + this->rendererInfo.sprintf("GLEW version %s\n" + "OpenGL version %s\n" + "%s (%s)\n\n" + "RGBA(%d%d%d%d), depth(%d), stencil(%d)\n" + "Extensions:\n" + "%s\n", + glewGetString(GLEW_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. +// Use: glGetIntegerv(GL_NUM_EXTENSIONS, &NumberOfExtensions) and +// glGetStringi(GL_EXTENSIONS, i) + const char *openscad_disable_gl20_env = getenv("OPENSCAD_DISABLE_GL20"); if (openscad_disable_gl20_env && !strcmp(openscad_disable_gl20_env, "0")) { openscad_disable_gl20_env = NULL; } // All OpenGL 2 contexts are OpenCSG capable - if (GLEW_VERSION_2_0 && !openscad_disable_gl20_env) this->is_opencsg_capable = true; - // If OpenGL < 2, check for extensions - else if (GLEW_ARB_framebuffer_object) this->is_opencsg_capable = true; - else if (GLEW_EXT_framebuffer_object && GLEW_EXT_packed_depth_stencil) { - this->is_opencsg_capable = true; + if (GLEW_VERSION_2_0) { + if (!openscad_disable_gl20_env) { + this->is_opencsg_capable = true; + this->has_shaders = true; + } } + // If OpenGL < 2, check for extensions + else { + if (GLEW_ARB_framebuffer_object) this->is_opencsg_capable = true; + else if (GLEW_EXT_framebuffer_object && GLEW_EXT_packed_depth_stencil) { + this->is_opencsg_capable = true; + } #ifdef WIN32 - else if (WGLEW_ARB_pbuffer && WGLEW_ARB_pixel_format) this->is_opencsg_capable = true; + else if (WGLEW_ARB_pbuffer && WGLEW_ARB_pixel_format) this->is_opencsg_capable = true; #elif !defined(__APPLE__) - else if (GLXEW_SGIX_pbuffer && GLXEW_SGIX_fbconfig) this->is_opencsg_capable = true; + else if (GLXEW_SGIX_pbuffer && GLXEW_SGIX_fbconfig) this->is_opencsg_capable = true; #endif + } - if (GLEW_VERSION_2_0 && !openscad_disable_gl20_env) this->has_shaders = true; - - if (!this->is_opencsg_capable) { - opencsg_support = false; - QSettings settings; - // FIXME: This should be an OpenCSG capability warning, not an OpenGL 2 warning - if (settings.value("editor/opengl20_warning_show",true).toBool()) { + if (!GLEW_VERSION_2_0 || !this->is_opencsg_capable) { + if (Preferences::inst()->getValue("advanced/opencsg_show_warning").toBool()) { QTimer::singleShot(0, this, SLOT(display_opencsg_warning())); } } if (opencsg_support && this->has_shaders) { + /* + Uniforms: + 1 color1 - face color + 2 color2 - edge color + 7 xscale + 8 yscale + + Attributes: + 3 trig + 4 pos_b + 5 pos_c + 6 mask + + Other: + 9 width + 10 height + + Outputs: + tp + tr + shading + */ const char *vs_source = "uniform float xscale, yscale;\n" "attribute vec3 pos_b, pos_c;\n" @@ -187,6 +240,11 @@ void GLView::initializeGL() " shading = abs(dot(normal, lightDir));\n" "}\n"; + /* + Inputs: + tp && tr - if any components of tp < tr, use color2 (edge color) + shading - multiplied by color1. color2 is is without lighting + */ const char *fs_source = "uniform vec4 color1, color2;\n" "varying vec3 tp, tr, tmp;\n" @@ -252,9 +310,19 @@ void GLView::initializeGL() #ifdef ENABLE_OPENCSG void GLView::display_opencsg_warning() { - // data - QString title = QString("OpenGL context is not OpenCSG capable"); + OpenCSGWarningDialog *dialog = new OpenCSGWarningDialog(this); + QString message; + if (this->is_opencsg_capable) { + message += "Warning: You may experience OpenCSG rendering errors.\n\n"; + } + else { + message += "Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been disabled.\n\n"; + dialog->enableOpenCSGBox->hide(); + } + message += "It is highly recommended to use OpenSCAD on a system with " + "OpenGL 2.0 or later.\n" + "Your renderer information is as follows:\n"; QString rendererinfo; rendererinfo.sprintf("GLEW version %s\n" "%s (%s)\n" @@ -262,44 +330,13 @@ void GLView::display_opencsg_warning() glewGetString(GLEW_VERSION), glGetString(GL_RENDERER), glGetString(GL_VENDOR), glGetString(GL_VERSION)); + message += rendererinfo; - QString message = QString("Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been disabled.\n\n" - "It is highly recommended to use OpenSCAD on a system with OpenGL 2.0, " - "or support for the framebuffer_object or pbuffer extensions. " - "Your renderer information is as follows:\n\n%1").arg(rendererinfo); - - QString note = QString("Uncheck to hide this message in the future"); - - // presentation - QDialog *dialog = new QDialog(this); - dialog->setSizeGripEnabled(true); - dialog->setWindowTitle(title); - dialog->resize(500,300); - - QVBoxLayout *layout = new QVBoxLayout(dialog); - dialog->setLayout(layout); - - QTextEdit *textEdit = new QTextEdit(dialog); - textEdit->setPlainText(message); - layout->addWidget(textEdit); - - QCheckBox *checkbox = new QCheckBox(note,dialog); - checkbox->setCheckState(Qt::Checked); - layout->addWidget(checkbox); - - QDialogButtonBox *buttonbox = - new QDialogButtonBox( QDialogButtonBox::Ok, Qt::Horizontal,dialog); - layout->addWidget(buttonbox); - buttonbox->button(QDialogButtonBox::Ok)->setFocus(); - buttonbox->button(QDialogButtonBox::Ok)->setDefault(true); - - // action - connect(buttonbox, SIGNAL(accepted()), dialog, SLOT(accept())); - connect(checkbox, SIGNAL(clicked(bool)), - Preferences::inst()->openCSGWarningBox, SLOT(setChecked(bool))); - connect(checkbox, SIGNAL(clicked(bool)), - Preferences::inst(), SLOT(openCSGWarningChanged(bool))); + dialog->setText(message); + dialog->enableOpenCSGBox->setChecked(Preferences::inst()->getValue("advanced/enable_opencsg_opengl1x").toBool()); dialog->exec(); + + opencsg_support = this->is_opencsg_capable && Preferences::inst()->getValue("advanced/enable_opencsg_opengl1x").toBool(); } #endif @@ -344,7 +381,7 @@ void GLView::paintGL() glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - const QColor &bgcol = Preferences::inst()->color(Preferences::BACKGROUND_COLOR); + const QColor &bgcol = RenderSettings::inst()->color(RenderSettings::BACKGROUND_COLOR); glClearColor(bgcol.redF(), bgcol.greenF(), bgcol.blueF(), 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); @@ -362,7 +399,7 @@ void GLView::paintGL() if (showcrosshairs) { glLineWidth(3); - const QColor &col = Preferences::inst()->color(Preferences::CROSSHAIR_COLOR); + const QColor &col = RenderSettings::inst()->color(RenderSettings::CROSSHAIR_COLOR); glColor3f(col.redF(), col.greenF(), col.blueF()); glBegin(GL_LINES); for (double xf = -1; xf <= +1; xf += 2) @@ -463,7 +500,7 @@ 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; - bgcol.getRgb(&r, &g, &b); +// bgcol.getRgb(&r, &g, &b); glColor3d((255.0-r)/255.0, (255.0-g)/255.0, (255.0-b)/255.0); glBegin(GL_LINES); // X Label diff --git a/src/lexer.l b/src/lexer.l index 2760b07..c799028 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -200,35 +200,39 @@ QDir sourcepath() return QDir(parser_source_path); } +/* + Rules for include <path/file> + 1) include <sourcepath/path/file> + 2) include <librarydir/path/file> + */ void includefile() { - if(filename.isEmpty()) - return; - - if(filepath.isEmpty()) { - path_stack.push(sourcepath()); - } else { - QFileInfo dirinfo(sourcepath(),filepath); - path_stack.push(dirinfo.dir()); - filepath.clear(); - } - - QFileInfo finfo(sourcepath(), filename); - if (!finfo.exists()) { - finfo = QFileInfo(QDir(librarydir), filename); - } - - handle_dep(finfo.absoluteFilePath().toStdString()); - yyin = fopen(finfo.absoluteFilePath().toLocal8Bit(), "r"); - if (!yyin) { - PRINTA("WARNING: Can't open input file `%1'.", filename); - path_stack.pop(); - return; - } - openfiles.append(yyin); - filename.clear(); - - yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE )); + if (filename.isEmpty()) return; + + QDir dirinfo(sourcepath()); + if (!filepath.isEmpty()) { + dirinfo.cd(filepath); + } + + QFileInfo finfo(dirinfo, filename); + if (!finfo.exists()) { + finfo = QFileInfo(QFileInfo(QDir(librarydir), filepath).dir(), filename); + } + + filepath.clear(); + path_stack.push(dirinfo); + + handle_dep(finfo.absoluteFilePath().toStdString()); + yyin = fopen(finfo.absoluteFilePath().toLocal8Bit(), "r"); + if (!yyin) { + PRINTA("WARNING: Can't open input file `%1'.", filename); + path_stack.pop(); + return; + } + openfiles.append(yyin); + filename.clear(); + + yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE)); } /*! diff --git a/src/mainwin.cc b/src/mainwin.cc index c81f2f2..3243847 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -145,6 +145,7 @@ MainWindow::MainWindow(const QString &filename) register_builtin(root_ctx); + this->openglbox = NULL; root_module = NULL; absolute_root_node = NULL; root_chain = NULL; @@ -176,7 +177,7 @@ MainWindow::MainWindow(const QString &filename) editor->setTabStopWidth(30); #endif editor->setLineWrapping(true); // Not designable - setFont("", 0); // Init default font + setFont("", 12); // Init default font this->glview->statusLabel = new QLabel(this); statusBar()->addWidget(this->glview->statusLabel); @@ -312,6 +313,7 @@ MainWindow::MainWindow(const QString &filename) connect(this->helpActionAbout, SIGNAL(triggered()), this, SLOT(helpAbout())); connect(this->helpActionHomepage, SIGNAL(triggered()), this, SLOT(helpHomepage())); connect(this->helpActionManual, SIGNAL(triggered()), this, SLOT(helpManual())); + connect(this->helpActionOpenGLInfo, SIGNAL(triggered()), this, SLOT(helpOpenGL())); console->setReadOnly(true); @@ -1752,6 +1754,18 @@ MainWindow::helpManual() QDesktopServices::openUrl(QUrl("http://en.wikibooks.org/wiki/OpenSCAD_User_Manual")); } +void MainWindow::helpOpenGL() +{ + if (!this->openglbox) { + this->openglbox = new QMessageBox(QMessageBox::Information, + "OpenGL Info", "Detailed OpenGL Info", + QMessageBox::Ok, this); + + } + this->openglbox->setDetailedText(this->glview->getRendererInfo()); + this->openglbox->show(); +} + /*! FIXME: In MDI mode, should this be called on both reload functions? */ @@ -1822,3 +1836,4 @@ void MainWindow::clearCurrentOutput() { set_output_handler(NULL, NULL); } + diff --git a/src/polyset.cc b/src/polyset.cc index 742e425..481cbec 100644 --- a/src/polyset.cc +++ b/src/polyset.cc @@ -108,52 +108,9 @@ static void gl_draw_triangle(GLint *shaderinfo, const Vector3d &p0, const Vector } } -void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, const Transform3d &m, GLint *shaderinfo) const +void PolySet::render_surface(csgmode_e csgmode, const Transform3d &m, GLint *shaderinfo) const { bool mirrored = m.matrix().determinant() < 0; - - if (colormode == COLORMODE_MATERIAL) { -// FIXME: Reenable/rewrite - don't be dependant on GUI -// const QColor &col = Preferences::inst()->color(Preferences::OPENCSG_FACE_FRONT_COLOR); - const QColor &col = QColor(0xf9, 0xd7, 0x2c); - glColor3f(col.redF(), col.greenF(), col.blueF()); -#ifdef ENABLE_OPENCSG - if (shaderinfo) { - glUniform4f(shaderinfo[1], col.redF(), col.greenF(), col.blueF(), 1.0f); - glUniform4f(shaderinfo[2], 255 / 255.0f, 236 / 255.0f, 94 / 255.0f, 1.0f); - } -#endif /* ENABLE_OPENCSG */ - } - if (colormode == COLORMODE_CUTOUT) { -// FIXME: Reenable/rewrite - don't be dependant on GUI -// const QColor &col = Preferences::inst()->color(Preferences::OPENCSG_FACE_BACK_COLOR); - const QColor &col = QColor(0x9d, 0xcb, 0x51); - glColor3f(col.redF(), col.greenF(), col.blueF()); -#ifdef ENABLE_OPENCSG - if (shaderinfo) { - glUniform4f(shaderinfo[1], 157 / 255.0f, 203 / 255.0f, 81 / 255.0f, 1.0f); - glUniform4f(shaderinfo[2], 171 / 255.0f, 216 / 255.0f, 86 / 255.0f, 1.0f); - } -#endif /* ENABLE_OPENCSG */ - } - if (colormode == COLORMODE_HIGHLIGHT) { - glColor4ub(255, 157, 81, 128); -#ifdef ENABLE_OPENCSG - if (shaderinfo) { - glUniform4f(shaderinfo[1], 255 / 255.0f, 157 / 255.0f, 81 / 255.0f, 0.5f); - glUniform4f(shaderinfo[2], 255 / 255.0f, 171 / 255.0f, 86 / 255.0f, 0.5f); - } -#endif /* ENABLE_OPENCSG */ - } - if (colormode == COLORMODE_BACKGROUND) { - glColor4ub(180, 180, 180, 128); -#ifdef ENABLE_OPENCSG - if (shaderinfo) { - glUniform4f(shaderinfo[1], 180 / 255.0f, 180 / 255.0f, 180 / 255.0f, 0.5f); - glUniform4f(shaderinfo[2], 150 / 255.0f, 150 / 255.0f, 150 / 255.0f, 0.5f); - } -#endif /* ENABLE_OPENCSG */ - } #ifdef ENABLE_OPENCSG if (shaderinfo) { glUniform1f(shaderinfo[7], shaderinfo[9]); @@ -248,16 +205,9 @@ void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, const Tra } } -void PolySet::render_edges(colormode_e colormode, csgmode_e csgmode) const +void PolySet::render_edges(csgmode_e csgmode) const { - if (colormode == COLORMODE_MATERIAL) - glColor3ub(255, 236, 94); - if (colormode == COLORMODE_CUTOUT) - glColor3ub(171, 216, 86); - if (colormode == COLORMODE_HIGHLIGHT) - glColor4ub(255, 171, 86, 128); - if (colormode == COLORMODE_BACKGROUND) - glColor4ub(150, 150, 150, 128); + glDisable(GL_LIGHTING); if (this->is2d) { double zbase = csgmode; for (double z = -zbase/2; z < zbase; z += zbase) @@ -293,6 +243,7 @@ void PolySet::render_edges(colormode_e colormode, csgmode_e csgmode) const glEnd(); } } + glEnable(GL_LIGHTING); } BoundingBox PolySet::getBoundingBox() const diff --git a/src/polyset.h b/src/polyset.h index 57f5057..5698621 100644 --- a/src/polyset.h +++ b/src/polyset.h @@ -27,14 +27,6 @@ public: BoundingBox getBoundingBox() const; - enum colormode_e { - COLORMODE_NONE, - COLORMODE_MATERIAL, - COLORMODE_CUTOUT, - COLORMODE_HIGHLIGHT, - COLORMODE_BACKGROUND - }; - enum csgmode_e { CSGMODE_NONE, CSGMODE_NORMAL = 1, @@ -45,8 +37,8 @@ public: CSGMODE_HIGHLIGHT_DIFFERENCE = 22 }; - void render_surface(colormode_e colormode, csgmode_e csgmode, const Transform3d &m, GLint *shaderinfo = NULL) const; - void render_edges(colormode_e colormode, csgmode_e csgmode) const; + void render_surface(csgmode_e csgmode, const Transform3d &m, GLint *shaderinfo = NULL) const; + void render_edges(csgmode_e csgmode) const; }; #endif diff --git a/src/primitives.cc b/src/primitives.cc index 67e19c3..b3fa45f 100644 --- a/src/primitives.cc +++ b/src/primitives.cc @@ -327,7 +327,7 @@ PolySet *PrimitiveNode::evaluate_polyset(class PolySetEvaluator *) const }; int fragments = get_fragments_from_r(r1, fn, fs, fa); - int rings = fragments/2; + int rings = (fragments+1)/2; // Uncomment the following three lines to enable experimental sphere tesselation // if (rings % 2 == 0) rings++; // To ensure that the middle ring is at phi == 0 degrees diff --git a/src/renderer.cc b/src/renderer.cc new file mode 100644 index 0000000..b791673 --- /dev/null +++ b/src/renderer.cc @@ -0,0 +1,66 @@ +#include "renderer.h" +#include "rendersettings.h" +#include <QColor> + +void Renderer::setColor(const double 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]}; + if (c[0] < 0) c[0] = col.redF(); + if (c[1] < 0) c[1] = col.greenF(); + if (c[2] < 0) c[2] = col.blueF(); + if (c[3] < 0) c[3] = col.alphaF(); + glColor4dv(c); + if (shaderinfo) { + glUniform4f(shaderinfo[1], c[0], c[1], c[2], c[3]); + glUniform4f(shaderinfo[2], (c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0); + } +} + +void Renderer::setColor(ColorMode colormode, GLint *shaderinfo) const +{ + QColor col; + switch (colormode) { + case COLORMODE_NONE: + return; + break; + case COLORMODE_MATERIAL: + col = RenderSettings::inst()->color(RenderSettings::OPENCSG_FACE_FRONT_COLOR); + break; + case COLORMODE_CUTOUT: + col = RenderSettings::inst()->color(RenderSettings::OPENCSG_FACE_BACK_COLOR); + break; + case COLORMODE_HIGHLIGHT: + col.setRgb(255, 157, 81, 128); + break; + case COLORMODE_BACKGROUND: + col.setRgb(180, 180, 180, 128); + break; + case COLORMODE_MATERIAL_EDGES: + col.setRgb(255, 236, 94); + break; + case COLORMODE_CUTOUT_EDGES: + col.setRgb(171, 216, 86); + break; + case COLORMODE_HIGHLIGHT_EDGES: + col.setRgb(255, 171, 86, 128); + break; + case COLORMODE_BACKGROUND_EDGES: + col.setRgb(150, 150, 150, 128); + break; + default: + break; + } + float rgba[4]; + rgba[0] = col.redF(); + rgba[1] = col.greenF(); + rgba[2] = col.blueF(); + rgba[3] = col.alphaF(); + glColor4fv(rgba); +#ifdef ENABLE_OPENCSG + if (shaderinfo) { + glUniform4f(shaderinfo[1], col.redF(), col.greenF(), col.blueF(), 1.0f); + glUniform4f(shaderinfo[2], (col.redF()+1)/2, (col.greenF()+1)/2, (col.blueF()+1)/2, 1.0f); + } +#endif +} diff --git a/src/renderer.h b/src/renderer.h index 3c25e98..8deabe8 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -1,11 +1,32 @@ #ifndef RENDERER_H_ #define RENDERER_H_ +#include "system-gl.h" + +#ifdef _MSC_VER // NULL +#include <cstdlib> +#endif + class Renderer { public: virtual ~Renderer() {} virtual void draw(bool showfaces, bool showedges) const = 0; + + enum ColorMode { + COLORMODE_NONE, + COLORMODE_MATERIAL, + COLORMODE_CUTOUT, + COLORMODE_HIGHLIGHT, + COLORMODE_BACKGROUND, + COLORMODE_MATERIAL_EDGES, + COLORMODE_CUTOUT_EDGES, + COLORMODE_HIGHLIGHT_EDGES, + COLORMODE_BACKGROUND_EDGES + }; + + virtual void setColor(const double color[4], GLint *shaderinfo = NULL) const; + virtual void setColor(ColorMode colormode, GLint *shaderinfo = NULL) const; }; #endif // RENDERER_H diff --git a/src/rendersettings.cc b/src/rendersettings.cc new file mode 100644 index 0000000..ee57c34 --- /dev/null +++ b/src/rendersettings.cc @@ -0,0 +1,35 @@ +#include "rendersettings.h" + +RenderSettings *RenderSettings::inst(bool erase) +{ + static RenderSettings *instance = new RenderSettings; + if (erase) { + delete instance; + instance = NULL; + } + return instance; +} + +RenderSettings::RenderSettings() +{ + this->colors[BACKGROUND_COLOR] = QColor(0xff, 0xff, 0xe5); + this->colors[OPENCSG_FACE_FRONT_COLOR] = QColor(0xf9, 0xd7, 0x2c); + this->colors[OPENCSG_FACE_BACK_COLOR] = QColor(0x9d, 0xcb, 0x51); + this->colors[CGAL_FACE_FRONT_COLOR] = QColor(0xf9, 0xd7, 0x2c); + this->colors[CGAL_FACE_BACK_COLOR] = QColor(0x9d, 0xcb, 0x51); + this->colors[CGAL_FACE_2D_COLOR] = QColor(0x00, 0xbf, 0x99); + this->colors[CGAL_EDGE_FRONT_COLOR] = QColor(0xff, 0x00, 0x00); + this->colors[CGAL_EDGE_BACK_COLOR] = QColor(0xff, 0x00, 0x00); + this->colors[CGAL_EDGE_2D_COLOR] = QColor(0xff, 0x00, 0x00); + this->colors[CROSSHAIR_COLOR] = QColor(0x80, 0x00, 0x00); +} + +QColor RenderSettings::color(RenderColor idx) const +{ + return this->colors[idx]; +} + +void RenderSettings::setColors(const QMap<RenderColor, QColor> &colors) +{ + this->colors = colors; +} diff --git a/src/rendersettings.h b/src/rendersettings.h new file mode 100644 index 0000000..32e56f1 --- /dev/null +++ b/src/rendersettings.h @@ -0,0 +1,35 @@ +#ifndef RENDERSETTINGS_H_ +#define RENDERSETTINGS_H_ + +#include <QColor> +#include <QMap> + +class RenderSettings +{ +public: + static RenderSettings *inst(bool erase = false); + + enum RenderColor { + BACKGROUND_COLOR, + OPENCSG_FACE_FRONT_COLOR, + OPENCSG_FACE_BACK_COLOR, + CGAL_FACE_FRONT_COLOR, + CGAL_FACE_2D_COLOR, + CGAL_FACE_BACK_COLOR, + CGAL_EDGE_FRONT_COLOR, + CGAL_EDGE_BACK_COLOR, + CGAL_EDGE_2D_COLOR, + CROSSHAIR_COLOR + }; + + void setColors(const QMap<RenderColor, QColor> &colors); + QColor color(RenderColor idx) const; + +private: + RenderSettings(); + ~RenderSettings() {} + + QMap<RenderColor, QColor> colors; +}; + +#endif |