summaryrefslogtreecommitdiff
path: root/src/mainwin.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mainwin.cc')
-rw-r--r--src/mainwin.cc478
1 files changed, 271 insertions, 207 deletions
diff --git a/src/mainwin.cc b/src/mainwin.cc
index 44c5cff..56502f2 100644
--- a/src/mainwin.cc
+++ b/src/mainwin.cc
@@ -24,6 +24,7 @@
*
*/
+#include "PolySetCache.h"
#include "MainWindow.h"
#include "openscad.h" // examplesdir
#include "Preferences.h"
@@ -40,6 +41,7 @@
#include "dxftess.h"
#include "progress.h"
#ifdef ENABLE_OPENCSG
+#include "CSGTermEvaluator.h"
#include "OpenCSGRenderer.h"
#endif
#ifdef USE_PROGRESSWIDGET
@@ -74,19 +76,34 @@
#include "qlanguagefactory.h"
#endif
+#include <fstream>
+
+#include <algorithm>
+#include <boost/foreach.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
+using namespace boost::lambda;
+
#ifdef ENABLE_CGAL
-#include "cgalrenderer.h"
+#include "CGALCache.h"
+#include "CGALEvaluator.h"
+#include "PolySetCGALEvaluator.h"
+#include "CGALRenderer.h"
+#include "CGAL_Nef_polyhedron.h"
+#include "cgal.h"
#endif // ENABLE_CGAL
+// Global application state
+unsigned int GuiLocker::gui_locked = 0;
+
#define QUOTE(x__) # x__
#define QUOTED(x__) QUOTE(x__)
static char helptitle[] =
- "OpenSCAD "
- QUOTED(OPENSCAD_VERSION)
- " (www.openscad.org)\n";
+ "OpenSCAD " QUOTED(OPENSCAD_VERSION) " (www.openscad.org)\n"
+ "Visitor refactored version\n";
static char copyrighttext[] =
"Copyright (C) 2009-2011 Marius Kintel <marius@kintel.net> and Clifford Wolf <clifford@clifford.at>\n"
"\n"
@@ -137,11 +154,13 @@ MainWindow::MainWindow(const QString &filename)
root_ctx.set_variable("$fa", Value(12.0));
root_ctx.set_variable("$t", Value(0.0));
+ root_ctx.set_constant("PI",Value(M_PI));
+
Value zero3;
zero3.type = Value::VECTOR;
- zero3.vec.append(new Value(0.0));
- zero3.vec.append(new Value(0.0));
- zero3.vec.append(new Value(0.0));
+ zero3.append(new Value(0.0));
+ zero3.append(new Value(0.0));
+ zero3.append(new Value(0.0));
root_ctx.set_variable("$vpt", zero3);
root_ctx.set_variable("$vpr", zero3);
@@ -180,8 +199,8 @@ MainWindow::MainWindow(const QString &filename)
editor->setLineWrapping(true); // Not designable
setFont("", 0); // Init default font
- screen->statusLabel = new QLabel(this);
- statusBar()->addWidget(screen->statusLabel);
+ this->glview->statusLabel = new QLabel(this);
+ statusBar()->addWidget(this->glview->statusLabel);
animate_timer = new QTimer(this);
connect(animate_timer, SIGNAL(timeout()), this, SLOT(updateTVal()));
@@ -276,7 +295,7 @@ MainWindow::MainWindow(const QString &filename)
this->viewActionOpenCSG->setVisible(false);
#else
connect(this->viewActionOpenCSG, SIGNAL(triggered()), this, SLOT(viewModeOpenCSG()));
- if (!screen->hasOpenCSGSupport()) {
+ if (!this->glview->hasOpenCSGSupport()) {
this->viewActionOpenCSG->setEnabled(false);
}
#endif
@@ -323,6 +342,7 @@ MainWindow::MainWindow(const QString &filename)
} else {
setFileName("");
}
+ updateRecentFileActions();
connect(editor->document(), SIGNAL(contentsChanged()), this, SLOT(animateUpdateDocChanged()));
#ifdef _QCODE_EDIT_
@@ -332,9 +352,9 @@ MainWindow::MainWindow(const QString &filename)
connect(editor->document(), SIGNAL(modificationChanged(bool)), this, SLOT(setWindowModified(bool)));
connect(editor->document(), SIGNAL(modificationChanged(bool)), fileActionSave, SLOT(setEnabled(bool)));
#endif
- connect(screen, SIGNAL(doAnimateUpdate()), this, SLOT(animateUpdate()));
+ connect(this->glview, SIGNAL(doAnimateUpdate()), this, SLOT(animateUpdate()));
- connect(Preferences::inst(), SIGNAL(requestRedraw()), this->screen, SLOT(updateGL()));
+ connect(Preferences::inst(), SIGNAL(requestRedraw()), this->glview, SLOT(updateGL()));
connect(Preferences::inst(), SIGNAL(fontChanged(const QString&,uint)),
this, SLOT(setFont(const QString&,uint)));
Preferences::inst()->apply();
@@ -474,6 +494,7 @@ MainWindow::openFile(const QString &new_filename)
setFileName(new_filename);
load();
+ updateRecentFiles();
}
void
@@ -481,7 +502,7 @@ MainWindow::setFileName(const QString &filename)
{
if (filename.isEmpty()) {
this->fileName.clear();
- this->root_ctx.document_path = currentdir;
+ this->root_ctx.setDocumentPath(currentdir.toStdString());
setWindowTitle("OpenSCAD - New Document[*]");
}
else {
@@ -493,21 +514,29 @@ MainWindow::setFileName(const QString &filename)
QString infoFileName = fileinfo.absoluteFilePath();
if (!infoFileName.isEmpty()) {
this->fileName = infoFileName;
- QSettings settings; // already set up properly via main.cpp
- QStringList files = settings.value("recentFileList").toStringList();
- files.removeAll(this->fileName);
- files.prepend(this->fileName);
- while (files.size() > maxRecentFiles)
- files.removeLast();
- settings.setValue("recentFileList", files);
} else {
this->fileName = fileinfo.fileName();
}
- this->root_ctx.document_path = fileinfo.dir().absolutePath();
+ this->root_ctx.setDocumentPath(fileinfo.dir().absolutePath().toStdString());
QDir::setCurrent(fileinfo.dir().absolutePath());
}
+}
+
+void MainWindow::updateRecentFiles()
+{
+ // Check that the canonical file path exists - only update recent files
+ // if it does. Should prevent empty list items on initial open etc.
+ QFileInfo fileinfo(this->fileName);
+ QString infoFileName = fileinfo.absoluteFilePath();
+ QSettings settings; // already set up properly via main.cpp
+ QStringList files = settings.value("recentFileList").toStringList();
+ files.removeAll(infoFileName);
+ files.prepend(infoFileName);
+ while (files.size() > maxRecentFiles) files.removeLast();
+ settings.setValue("recentFileList", files);
+
foreach(QWidget *widget, QApplication::topLevelWidgets()) {
MainWindow *mainWin = qobject_cast<MainWindow *>(widget);
if (mainWin) {
@@ -516,6 +545,7 @@ MainWindow::setFileName(const QString &filename)
}
}
+
void MainWindow::updatedFps()
{
bool fps_ok;
@@ -564,7 +594,7 @@ void MainWindow::load()
AbstractNode *MainWindow::find_root_tag(AbstractNode *n)
{
- foreach(AbstractNode *v, n->children) {
+ BOOST_FOREACH (AbstractNode *v, n->children) {
if (v->modinst->tag_root) return v;
if (AbstractNode *vroot = find_root_tag(v)) return vroot;
}
@@ -572,7 +602,7 @@ AbstractNode *MainWindow::find_root_tag(AbstractNode *n)
}
/*!
- Parse and evaluate the design -> this->root_node
+ Parse and evaluate the design => this->root_node
*/
void MainWindow::compile(bool procevents)
{
@@ -581,7 +611,7 @@ void MainWindow::compile(bool procevents)
QApplication::processEvents();
// Invalidate renderers before we kill the CSG tree
- screen->setRenderer(NULL);
+ this->glview->setRenderer(NULL);
if (this->opencsgRenderer) {
delete this->opencsgRenderer;
this->opencsgRenderer = NULL;
@@ -592,80 +622,83 @@ void MainWindow::compile(bool procevents)
}
// Remove previous CSG tree
- if (root_module) {
- delete root_module;
- root_module = NULL;
+ if (this->root_module) {
+ delete this->root_module;
+ this->root_module = NULL;
}
- if (absolute_root_node) {
- delete absolute_root_node;
- absolute_root_node = NULL;
+ if (this->absolute_root_node) {
+ delete this->absolute_root_node;
+ this->absolute_root_node = NULL;
}
- if (root_raw_term) {
- root_raw_term->unlink();
- root_raw_term = NULL;
+ if (this->root_raw_term) {
+ this->root_raw_term->unlink();
+ this->root_raw_term = NULL;
}
- if (root_norm_term) {
- root_norm_term->unlink();
- root_norm_term = NULL;
+ if (this->root_norm_term) {
+ this->root_norm_term->unlink();
+ this->root_norm_term = NULL;
}
- if (root_chain) {
- delete root_chain;
- root_chain = NULL;
+ if (this->root_chain) {
+ delete this->root_chain;
+ this->root_chain = NULL;
}
- foreach(CSGTerm *v, highlight_terms) {
- v->unlink();
- }
- highlight_terms.clear();
- if (highlights_chain) {
- delete highlights_chain;
- highlights_chain = NULL;
- }
- foreach(CSGTerm *v, background_terms) {
- v->unlink();
- }
- background_terms.clear();
- if (background_chain) {
- delete background_chain;
- background_chain = NULL;
- }
- root_node = NULL;
+ std::for_each(this->highlight_terms.begin(), this->highlight_terms.end(),
+ bind(&CSGTerm::unlink, _1));
+
+ this->highlight_terms.clear();
+ delete this->highlights_chain;
+ this->highlights_chain = NULL;
+
+ std::for_each(this->background_terms.begin(), this->background_terms.end(),
+ bind(&CSGTerm::unlink, _1));
+ this->background_terms.clear();
+ delete this->background_chain;
+ this->background_chain = NULL;
+
+ this->root_node = NULL;
+ this->tree.setRoot(NULL);
// Initialize special variables
- root_ctx.set_variable("$t", Value(e_tval->text().toDouble()));
+ this->root_ctx.set_variable("$t", Value(e_tval->text().toDouble()));
Value vpt;
vpt.type = Value::VECTOR;
- vpt.vec.append(new Value(-screen->object_trans_x));
- vpt.vec.append(new Value(-screen->object_trans_y));
- vpt.vec.append(new Value(-screen->object_trans_z));
- root_ctx.set_variable("$vpt", vpt);
+ vpt.append(new Value(-this->glview->object_trans_x));
+ vpt.append(new Value(-this->glview->object_trans_y));
+ vpt.append(new Value(-this->glview->object_trans_z));
+ this->root_ctx.set_variable("$vpt", vpt);
Value vpr;
vpr.type = Value::VECTOR;
- vpr.vec.append(new Value(fmodf(360 - screen->object_rot_x + 90, 360)));
- vpr.vec.append(new Value(fmodf(360 - screen->object_rot_y, 360)));
- vpr.vec.append(new Value(fmodf(360 - screen->object_rot_z, 360)));
+ vpr.append(new Value(fmodf(360 - this->glview->object_rot_x + 90, 360)));
+ vpr.append(new Value(fmodf(360 - this->glview->object_rot_y, 360)));
+ vpr.append(new Value(fmodf(360 - this->glview->object_rot_z, 360)));
root_ctx.set_variable("$vpr", vpr);
// Parse
- last_compiled_doc = editor->toPlainText();
- root_module = parse((last_compiled_doc + "\n" + commandline_commands).toAscii().data(), this->fileName.isEmpty() ? "" : QFileInfo(this->fileName).absolutePath().toLocal8Bit(), false);
+ this->last_compiled_doc = editor->toPlainText();
+ this->root_module = parse((this->last_compiled_doc + "\n" +
+ QString::fromStdString(commandline_commands)).toAscii().data(),
+ this->fileName.isEmpty() ?
+ "" :
+ QFileInfo(this->fileName).absolutePath().toLocal8Bit(),
+ false);
// Error highlighting
- if (highlighter) {
- delete highlighter;
- highlighter = NULL;
+ if (this->highlighter) {
+ delete this->highlighter;
+ this->highlighter = NULL;
}
if (parser_error_pos >= 0) {
- highlighter = new Highlighter(editor->document());
+ this->highlighter = new Highlighter(editor->document());
}
- if (!root_module) {
+ if (!this->root_module) {
if (!animate_panel->isVisible()) {
#ifdef _QCODE_EDIT_
QDocumentCursor cursor = editor->cursor();
@@ -685,19 +718,23 @@ void MainWindow::compile(bool procevents)
QApplication::processEvents();
AbstractNode::resetIndexCounter();
- root_inst = ModuleInstantiation();
- absolute_root_node = root_module->evaluate(&root_ctx, &root_inst);
+ this->root_inst = ModuleInstantiation();
+ this->absolute_root_node = this->root_module->evaluate(&this->root_ctx, &this->root_inst);
- if (!absolute_root_node)
+ if (!this->absolute_root_node)
goto fail;
// Do we have an explicit root node (! modifier)?
- if (!(this->root_node = find_root_tag(absolute_root_node))) {
- this->root_node = absolute_root_node;
+ if (!(this->root_node = find_root_tag(this->absolute_root_node))) {
+ this->root_node = this->absolute_root_node;
}
- root_node->dump("");
+ // FIXME: Consider giving away ownership of root_node to the Tree, or use reference counted pointers
+ this->tree.setRoot(this->root_node);
+ // Dump the tree (to initialize caches).
+ // FIXME: We shouldn't really need to do this explicitly..
+ this->tree.getString(*this->root_node);
- if (1) {
+ if (1) {
PRINT("Compilation finished.");
if (procevents)
QApplication::processEvents();
@@ -706,18 +743,7 @@ fail:
if (parser_error_pos < 0) {
PRINT("ERROR: Compilation failed! (no top level object found)");
} else {
- int line = 1;
- QByteArray pb = last_compiled_doc.toAscii();
- char *p = pb.data();
- for (int i = 0; i < parser_error_pos; i++) {
- if (p[i] == '\n')
- line++;
- if (p[i] == 0) {
- line = -1;
- break;
- }
- }
- PRINTF("ERROR: Compilation failed! (parser error in line %d)", line);
+ PRINT("ERROR: Compilation failed!");
}
if (procevents)
QApplication::processEvents();
@@ -735,13 +761,6 @@ void MainWindow::compileCSG(bool procevents)
if (procevents)
QApplication::processEvents();
- double m[20];
-
- for (int i = 0; i < 16; i++)
- m[i] = i % 5 == 0 ? 1.0 : 0.0;
- for (int i = 16; i < 20; i++)
- m[i] = -1;
-
// Main CSG evaluation
QTime t;
t.start();
@@ -762,12 +781,17 @@ void MainWindow::compileCSG(bool procevents)
progress_report_prep(root_node, report_func, pd);
try {
- root_raw_term = root_node->render_csg_term(m, &highlight_terms, &background_terms);
+ CGALEvaluator cgalevaluator(this->tree);
+ PolySetCGALEvaluator psevaluator(cgalevaluator);
+ CSGTermEvaluator csgrenderer(this->tree, &psevaluator);
+ root_raw_term = csgrenderer.evaluateCSGTerm(*root_node, highlight_terms, background_terms);
if (!root_raw_term) {
PRINT("ERROR: CSG generation failed! (no top level object found)");
if (procevents)
QApplication::processEvents();
}
+ PolySetCache::instance()->print();
+ CGALCache::instance()->print();
}
catch (ProgressCancelException e) {
PRINT("CSG generation cancelled.");
@@ -801,12 +825,12 @@ void MainWindow::compileCSG(bool procevents)
if (highlight_terms.size() > 0)
{
- PRINTF("Compiling highlights (%d CSG Trees)...", highlight_terms.size());
+ PRINTF("Compiling highlights (%zu CSG Trees)...", highlight_terms.size());
if (procevents)
QApplication::processEvents();
highlights_chain = new CSGChain();
- for (int i = 0; i < highlight_terms.size(); i++) {
+ for (unsigned int i = 0; i < highlight_terms.size(); i++) {
while (1) {
CSGTerm *n = highlight_terms[i]->normalize();
highlight_terms[i]->unlink();
@@ -820,12 +844,12 @@ void MainWindow::compileCSG(bool procevents)
if (background_terms.size() > 0)
{
- PRINTF("Compiling background (%d CSG Trees)...", background_terms.size());
+ PRINTF("Compiling background (%zu CSG Trees)...", background_terms.size());
if (procevents)
QApplication::processEvents();
background_chain = new CSGChain();
- for (int i = 0; i < background_terms.size(); i++) {
+ for (unsigned int i = 0; i < background_terms.size(); i++) {
while (1) {
CSGTerm *n = background_terms[i]->normalize();
background_terms[i]->unlink();
@@ -842,10 +866,11 @@ void MainWindow::compileCSG(bool procevents)
PRINTF("WARNING: OpenCSG rendering has been disabled.");
}
else {
+ PRINTF("Normalized CSG tree has %d elements", root_chain->polysets.size());
this->opencsgRenderer = new OpenCSGRenderer(this->root_chain,
this->highlights_chain,
this->background_chain,
- this->screen->shaderinfo);
+ this->glview->shaderinfo);
}
this->thrownTogetherRenderer = new ThrownTogetherRenderer(this->root_chain,
this->highlights_chain,
@@ -876,7 +901,9 @@ void MainWindow::actionOpen()
{
QString new_filename = QFileDialog::getOpenFileName(this, "Open File", "", "OpenSCAD Designs (*.scad)");
#ifdef ENABLE_MDI
- new MainWindow(new_filename);
+ if (!new_filename.isEmpty()) {
+ new MainWindow(new_filename);
+ }
#else
if (!new_filename.isEmpty()) {
if (!maybeSave())
@@ -974,6 +1001,7 @@ void MainWindow::actionSave()
this->editor->setContentModified(false);
}
clearCurrentOutput();
+ updateRecentFiles();
}
}
@@ -1027,7 +1055,7 @@ void MainWindow::pasteViewportTranslation()
QTextCursor cursor = editor->textCursor();
#endif
QString txt;
- txt.sprintf("[ %.2f, %.2f, %.2f ]", -screen->object_trans_x, -screen->object_trans_y, -screen->object_trans_z);
+ txt.sprintf("[ %.2f, %.2f, %.2f ]", -this->glview->object_trans_x, -this->glview->object_trans_y, -this->glview->object_trans_z);
cursor.insertText(txt);
}
@@ -1040,7 +1068,7 @@ void MainWindow::pasteViewportRotation()
#endif
QString txt;
txt.sprintf("[ %.2f, %.2f, %.2f ]",
- fmodf(360 - screen->object_rot_x + 90, 360), fmodf(360 - screen->object_rot_y, 360), fmodf(360 - screen->object_rot_z, 360));
+ fmodf(360 - this->glview->object_rot_x + 90, 360), fmodf(360 - this->glview->object_rot_y, 360), fmodf(360 - this->glview->object_rot_z, 360));
cursor.insertText(txt);
}
@@ -1084,6 +1112,9 @@ bool MainWindow::checkModified()
void MainWindow::actionReloadCompile()
{
+ if (GuiLocker::isLocked()) return;
+ GuiLocker lock;
+
if (!checkModified()) return;
console->clear();
@@ -1111,6 +1142,9 @@ void MainWindow::actionReloadCompile()
void MainWindow::actionCompile()
{
+ if (GuiLocker::isLocked()) return;
+ GuiLocker lock;
+
setCurrentOutput();
console->clear();
@@ -1130,7 +1164,7 @@ void MainWindow::actionCompile()
}
if (viewActionAnimate->isChecked() && e_dump->isChecked()) {
- QImage img = screen->grabFrameBuffer();
+ QImage img = this->glview->grabFrameBuffer();
QString filename;
double s = e_fsteps->text().toDouble();
double t = e_tval->text().toDouble();
@@ -1145,15 +1179,19 @@ void MainWindow::actionCompile()
void MainWindow::actionRenderCGAL()
{
+ if (GuiLocker::isLocked()) return;
+ GuiLocker lock;
+
setCurrentOutput();
console->clear();
compile(true);
- if (!root_module || !root_node)
+ if (!this->root_module || !this->root_node) {
return;
+ }
- this->screen->setRenderer(NULL);
+ this->glview->setRenderer(NULL);
delete this->cgalRenderer;
this->cgalRenderer = NULL;
if (this->root_N) {
@@ -1183,9 +1221,12 @@ void MainWindow::actionRenderCGAL()
QApplication::processEvents();
- progress_report_prep(root_node, report_func, pd);
+ progress_report_prep(this->root_node, report_func, pd);
try {
- this->root_N = new CGAL_Nef_polyhedron(root_node->render_cgal_nef_polyhedron());
+ CGALEvaluator evaluator(this->tree);
+ this->root_N = new CGAL_Nef_polyhedron(evaluator.evaluateCGALMesh(*this->root_node));
+ PolySetCache::instance()->print();
+ CGALCache::instance()->print();
}
catch (ProgressCancelException e) {
PRINT("Rendering cancelled.");
@@ -1194,64 +1235,70 @@ void MainWindow::actionRenderCGAL()
if (this->root_N)
{
- PRINTF("Number of vertices currently in CGAL cache: %d", AbstractNode::cgal_nef_cache.totalCost());
- PRINTF("Number of objects currently in CGAL cache: %d", AbstractNode::cgal_nef_cache.size());
+ // FIXME: Reenable cache cost info
+// PRINTF("Number of vertices currently in CGAL cache: %d", AbstractNode::cgal_nef_cache.totalCost());
+// PRINTF("Number of objects currently in CGAL cache: %d", AbstractNode::cgal_nef_cache.size());
QApplication::processEvents();
if (this->root_N->dim == 2) {
PRINTF(" Top level object is a 2D object:");
QApplication::processEvents();
- PRINTF(" Empty: %6s", this->root_N->p2.is_empty() ? "yes" : "no");
+ PRINTF(" Empty: %6s", this->root_N->p2->is_empty() ? "yes" : "no");
QApplication::processEvents();
- PRINTF(" Plane: %6s", this->root_N->p2.is_plane() ? "yes" : "no");
+ PRINTF(" Plane: %6s", this->root_N->p2->is_plane() ? "yes" : "no");
QApplication::processEvents();
- PRINTF(" Vertices: %6d", (int)this->root_N->p2.explorer().number_of_vertices());
+ PRINTF(" Vertices: %6d", (int)this->root_N->p2->explorer().number_of_vertices());
QApplication::processEvents();
- PRINTF(" Halfedges: %6d", (int)this->root_N->p2.explorer().number_of_halfedges());
+ PRINTF(" Halfedges: %6d", (int)this->root_N->p2->explorer().number_of_halfedges());
QApplication::processEvents();
- PRINTF(" Edges: %6d", (int)this->root_N->p2.explorer().number_of_edges());
+ PRINTF(" Edges: %6d", (int)this->root_N->p2->explorer().number_of_edges());
QApplication::processEvents();
- PRINTF(" Faces: %6d", (int)this->root_N->p2.explorer().number_of_faces());
+ PRINTF(" Faces: %6d", (int)this->root_N->p2->explorer().number_of_faces());
QApplication::processEvents();
- PRINTF(" FaceCycles: %6d", (int)this->root_N->p2.explorer().number_of_face_cycles());
+ PRINTF(" FaceCycles: %6d", (int)this->root_N->p2->explorer().number_of_face_cycles());
QApplication::processEvents();
- PRINTF(" ConnComp: %6d", (int)this->root_N->p2.explorer().number_of_connected_components());
+ PRINTF(" ConnComp: %6d", (int)this->root_N->p2->explorer().number_of_connected_components());
QApplication::processEvents();
}
if (this->root_N->dim == 3) {
PRINTF(" Top level object is a 3D object:");
- PRINTF(" Simple: %6s", this->root_N->p3.is_simple() ? "yes" : "no");
+ PRINTF(" Simple: %6s", this->root_N->p3->is_simple() ? "yes" : "no");
QApplication::processEvents();
- PRINTF(" Valid: %6s", this->root_N->p3.is_valid() ? "yes" : "no");
+ PRINTF(" Valid: %6s", this->root_N->p3->is_valid() ? "yes" : "no");
QApplication::processEvents();
- PRINTF(" Vertices: %6d", (int)this->root_N->p3.number_of_vertices());
+ PRINTF(" Vertices: %6d", (int)this->root_N->p3->number_of_vertices());
QApplication::processEvents();
- PRINTF(" Halfedges: %6d", (int)this->root_N->p3.number_of_halfedges());
+ PRINTF(" Halfedges: %6d", (int)this->root_N->p3->number_of_halfedges());
QApplication::processEvents();
- PRINTF(" Edges: %6d", (int)this->root_N->p3.number_of_edges());
+ PRINTF(" Edges: %6d", (int)this->root_N->p3->number_of_edges());
QApplication::processEvents();
- PRINTF(" Halffacets: %6d", (int)this->root_N->p3.number_of_halffacets());
+ PRINTF(" Halffacets: %6d", (int)this->root_N->p3->number_of_halffacets());
QApplication::processEvents();
- PRINTF(" Facets: %6d", (int)this->root_N->p3.number_of_facets());
+ PRINTF(" Facets: %6d", (int)this->root_N->p3->number_of_facets());
QApplication::processEvents();
- PRINTF(" Volumes: %6d", (int)this->root_N->p3.number_of_volumes());
+ PRINTF(" Volumes: %6d", (int)this->root_N->p3->number_of_volumes());
QApplication::processEvents();
}
int s = t.elapsed() / 1000;
PRINTF("Total rendering time: %d hours, %d minutes, %d seconds", s / (60*60), (s / 60) % 60, s % 60);
- this->cgalRenderer = new CGALRenderer(*this->root_N);
- // Go to CGAL view mode
- if (viewActionCGALGrid->isChecked()) {
- viewModeCGALGrid();
+ if (!this->root_N->empty()) {
+ this->cgalRenderer = new CGALRenderer(*this->root_N);
+ // Go to CGAL view mode
+ if (viewActionCGALGrid->isChecked()) {
+ viewModeCGALGrid();
+ }
+ else {
+ viewModeCGALSurface();
+ }
+
+ PRINT("Rendering finished.");
}
else {
- viewModeCGALSurface();
+ PRINT("WARNING: No top level geometry to render");
}
-
- PRINT("Rendering finished.");
}
#ifdef USE_PROGRESSWIDGET
@@ -1272,7 +1319,7 @@ void MainWindow::actionDisplayAST()
e->setWindowTitle("AST Dump");
e->setReadOnly(true);
if (root_module) {
- e->setPlainText(root_module->dump("", ""));
+ e->setPlainText(QString::fromStdString(root_module->dump("", "")));
} else {
e->setPlainText("No AST to dump. Please try compiling first...");
}
@@ -1289,8 +1336,8 @@ void MainWindow::actionDisplayCSGTree()
e->setTabStopWidth(30);
e->setWindowTitle("CSG Tree Dump");
e->setReadOnly(true);
- if (root_node) {
- e->setPlainText(root_node->dump(""));
+ if (this->root_node) {
+ e->setPlainText(QString::fromStdString(this->tree.getString(*this->root_node)));
} else {
e->setPlainText("No CSG to dump. Please try compiling first...");
}
@@ -1307,7 +1354,7 @@ void MainWindow::actionDisplayCSGProducts()
e->setTabStopWidth(30);
e->setWindowTitle("CSG Products Dump");
e->setReadOnly(true);
- e->setPlainText(QString("\nCSG before normalization:\n%1\n\n\nCSG after normalization:\n%2\n\n\nCSG rendering chain:\n%3\n\n\nHighlights CSG rendering chain:\n%4\n\n\nBackground CSG rendering chain:\n%5\n").arg(root_raw_term ? root_raw_term->dump() : "N/A", root_norm_term ? root_norm_term->dump() : "N/A", root_chain ? root_chain->dump() : "N/A", highlights_chain ? highlights_chain->dump() : "N/A", background_chain ? background_chain->dump() : "N/A"));
+ e->setPlainText(QString("\nCSG before normalization:\n%1\n\n\nCSG after normalization:\n%2\n\n\nCSG rendering chain:\n%3\n\n\nHighlights CSG rendering chain:\n%4\n\n\nBackground CSG rendering chain:\n%5\n").arg(root_raw_term ? QString::fromStdString(root_raw_term->dump()) : "N/A", root_norm_term ? QString::fromStdString(root_norm_term->dump()) : "N/A", root_chain ? QString::fromStdString(root_chain->dump()) : "N/A", highlights_chain ? QString::fromStdString(highlights_chain->dump()) : "N/A", background_chain ? QString::fromStdString(background_chain->dump()) : "N/A"));
e->show();
e->resize(600, 400);
clearCurrentOutput();
@@ -1319,6 +1366,8 @@ void MainWindow::actionExportSTLorOFF(bool stl_mode)
void MainWindow::actionExportSTLorOFF(bool)
#endif
{
+ if (GuiLocker::isLocked()) return;
+ GuiLocker lock;
#ifdef ENABLE_CGAL
setCurrentOutput();
@@ -1334,14 +1383,16 @@ void MainWindow::actionExportSTLorOFF(bool)
return;
}
- if (!this->root_N->p3.is_simple()) {
+ if (!this->root_N->p3->is_simple()) {
PRINT("Object isn't a valid 2-manifold! Modify your design..");
clearCurrentOutput();
return;
}
+ QString suffix = stl_mode ? ".stl" : ".off";
QString stl_filename = QFileDialog::getSaveFileName(this,
- stl_mode ? "Export STL File" : "Export OFF File", "",
+ stl_mode ? "Export STL File" : "Export OFF File",
+ this->fileName.isEmpty() ? "Untitled"+suffix : QFileInfo(this->fileName).baseName()+suffix,
stl_mode ? "STL Files (*.stl)" : "OFF Files (*.off)");
if (stl_filename.isEmpty()) {
PRINTF("No filename specified. %s export aborted.", stl_mode ? "STL" : "OFF");
@@ -1351,19 +1402,23 @@ void MainWindow::actionExportSTLorOFF(bool)
QProgressDialog *pd = new QProgressDialog(
stl_mode ? "Exporting object to STL file..." : "Exporting object to OFF file...",
- QString(), 0, this->root_N->p3.number_of_facets() + 1);
+ QString(), 0, this->root_N->p3->number_of_facets() + 1);
pd->setValue(0);
pd->setAutoClose(false);
pd->show();
QApplication::processEvents();
- if (stl_mode)
- export_stl(this->root_N, stl_filename, pd);
- else
- export_off(this->root_N, stl_filename, pd);
-
- PRINTF("%s export finished.", stl_mode ? "STL" : "OFF");
+ std::ofstream fstream(stl_filename.toUtf8());
+ if (!fstream.is_open()) {
+ PRINTA("Can't open file \"%1\" for export", stl_filename);
+ }
+ else {
+ if (stl_mode) export_stl(this->root_N, fstream, pd);
+ else export_off(this->root_N, fstream, pd);
+ fstream.close();
+ PRINTF("%s export finished.", stl_mode ? "STL" : "OFF");
+ }
delete pd;
clearCurrentOutput();
@@ -1397,16 +1452,25 @@ void MainWindow::actionExportDXF()
return;
}
- QString stl_filename = QFileDialog::getSaveFileName(this,
- "Export DXF File", "", "DXF Files (*.dxf)");
- if (stl_filename.isEmpty()) {
+ QString dxf_filename = QFileDialog::getSaveFileName(this,
+ "Export DXF File",
+ this->fileName.isEmpty() ? "Untitled.dxf" : QFileInfo(this->fileName).baseName()+".dxf",
+ "DXF Files (*.dxf)");
+ if (dxf_filename.isEmpty()) {
PRINTF("No filename specified. DXF export aborted.");
clearCurrentOutput();
return;
}
- export_dxf(this->root_N, stl_filename, NULL);
- PRINTF("DXF export finished.");
+ std::ofstream fstream(dxf_filename.toUtf8());
+ if (!fstream.is_open()) {
+ PRINTA("Can't open file \"%s\" for export", dxf_filename);
+ }
+ else {
+ export_dxf(this->root_N, fstream, NULL);
+ fstream.close();
+ PRINTF("DXF export finished.");
+ }
clearCurrentOutput();
#endif /* ENABLE_CGAL */
@@ -1414,7 +1478,7 @@ void MainWindow::actionExportDXF()
void MainWindow::actionExportImage()
{
- QImage img = screen->grabFrameBuffer();
+ QImage img = this->glview->grabFrameBuffer();
setCurrentOutput();
QString img_filename = QFileDialog::getSaveFileName(this,
@@ -1432,9 +1496,9 @@ void MainWindow::actionExportImage()
void MainWindow::actionFlushCaches()
{
- PolySet::ps_cache.clear();
+ PolySetCache::instance()->clear();
#ifdef ENABLE_CGAL
- AbstractNode::cgal_nef_cache.clear();
+ CGALCache::instance()->clear();
#endif
dxf_dim_cache.clear();
dxf_cross_cache.clear();
@@ -1459,10 +1523,10 @@ void MainWindow::viewModeActionsUncheck()
*/
void MainWindow::viewModeOpenCSG()
{
- if (screen->hasOpenCSGSupport()) {
+ if (this->glview->hasOpenCSGSupport()) {
viewModeActionsUncheck();
viewActionOpenCSG->setChecked(true);
- screen->setRenderer(this->opencsgRenderer ? (Renderer *)this->opencsgRenderer : (Renderer *)this->thrownTogetherRenderer);
+ this->glview->setRenderer(this->opencsgRenderer ? (Renderer *)this->opencsgRenderer : (Renderer *)this->thrownTogetherRenderer);
} else {
viewModeThrownTogether();
}
@@ -1476,17 +1540,17 @@ void MainWindow::viewModeCGALSurface()
{
viewModeActionsUncheck();
viewActionCGALSurfaces->setChecked(true);
- screen->setShowFaces(true);
- screen->setRenderer(this->cgalRenderer);
- screen->updateGL();
+ this->glview->setShowFaces(true);
+ this->glview->setRenderer(this->cgalRenderer);
+ this->glview->updateGL();
}
void MainWindow::viewModeCGALGrid()
{
viewModeActionsUncheck();
viewActionCGALGrid->setChecked(true);
- screen->setShowFaces(false);
- screen->setRenderer(this->cgalRenderer);
+ this->glview->setShowFaces(false);
+ this->glview->setRenderer(this->cgalRenderer);
}
#endif /* ENABLE_CGAL */
@@ -1495,31 +1559,31 @@ void MainWindow::viewModeThrownTogether()
{
viewModeActionsUncheck();
viewActionThrownTogether->setChecked(true);
- screen->setRenderer(this->thrownTogetherRenderer);
+ this->glview->setRenderer(this->thrownTogetherRenderer);
}
void MainWindow::viewModeShowEdges()
{
QSettings settings;
settings.setValue("view/showEdges",viewActionShowEdges->isChecked());
- screen->setShowEdges(viewActionShowEdges->isChecked());
- screen->updateGL();
+ this->glview->setShowEdges(viewActionShowEdges->isChecked());
+ this->glview->updateGL();
}
void MainWindow::viewModeShowAxes()
{
QSettings settings;
settings.setValue("view/showAxes",viewActionShowAxes->isChecked());
- screen->setShowAxes(viewActionShowAxes->isChecked());
- screen->updateGL();
+ this->glview->setShowAxes(viewActionShowAxes->isChecked());
+ this->glview->updateGL();
}
void MainWindow::viewModeShowCrosshairs()
{
QSettings settings;
settings.setValue("view/showCrosshairs",viewActionShowCrosshairs->isChecked());
- screen->setShowCrosshairs(viewActionShowCrosshairs->isChecked());
- screen->updateGL();
+ this->glview->setShowCrosshairs(viewActionShowCrosshairs->isChecked());
+ this->glview->updateGL();
}
void MainWindow::viewModeAnimate()
@@ -1557,66 +1621,66 @@ void MainWindow::animateUpdate()
void MainWindow::viewAngleTop()
{
- screen->object_rot_x = 90;
- screen->object_rot_y = 0;
- screen->object_rot_z = 0;
- screen->updateGL();
+ this->glview->object_rot_x = 90;
+ this->glview->object_rot_y = 0;
+ this->glview->object_rot_z = 0;
+ this->glview->updateGL();
}
void MainWindow::viewAngleBottom()
{
- screen->object_rot_x = 270;
- screen->object_rot_y = 0;
- screen->object_rot_z = 0;
- screen->updateGL();
+ this->glview->object_rot_x = 270;
+ this->glview->object_rot_y = 0;
+ this->glview->object_rot_z = 0;
+ this->glview->updateGL();
}
void MainWindow::viewAngleLeft()
{
- screen->object_rot_x = 0;
- screen->object_rot_y = 0;
- screen->object_rot_z = 90;
- screen->updateGL();
+ this->glview->object_rot_x = 0;
+ this->glview->object_rot_y = 0;
+ this->glview->object_rot_z = 90;
+ this->glview->updateGL();
}
void MainWindow::viewAngleRight()
{
- screen->object_rot_x = 0;
- screen->object_rot_y = 0;
- screen->object_rot_z = 270;
- screen->updateGL();
+ this->glview->object_rot_x = 0;
+ this->glview->object_rot_y = 0;
+ this->glview->object_rot_z = 270;
+ this->glview->updateGL();
}
void MainWindow::viewAngleFront()
{
- screen->object_rot_x = 0;
- screen->object_rot_y = 0;
- screen->object_rot_z = 0;
- screen->updateGL();
+ this->glview->object_rot_x = 0;
+ this->glview->object_rot_y = 0;
+ this->glview->object_rot_z = 0;
+ this->glview->updateGL();
}
void MainWindow::viewAngleBack()
{
- screen->object_rot_x = 0;
- screen->object_rot_y = 0;
- screen->object_rot_z = 180;
- screen->updateGL();
+ this->glview->object_rot_x = 0;
+ this->glview->object_rot_y = 0;
+ this->glview->object_rot_z = 180;
+ this->glview->updateGL();
}
void MainWindow::viewAngleDiagonal()
{
- screen->object_rot_x = 35;
- screen->object_rot_y = 0;
- screen->object_rot_z = 25;
- screen->updateGL();
+ this->glview->object_rot_x = 35;
+ this->glview->object_rot_y = 0;
+ this->glview->object_rot_z = -25;
+ this->glview->updateGL();
}
void MainWindow::viewCenter()
{
- screen->object_trans_x = 0;
- screen->object_trans_y = 0;
- screen->object_trans_z = 0;
- screen->updateGL();
+ this->glview->object_trans_x = 0;
+ this->glview->object_trans_y = 0;
+ this->glview->object_trans_z = 0;
+ this->glview->updateGL();
}
void MainWindow::viewPerspective()
@@ -1625,8 +1689,8 @@ void MainWindow::viewPerspective()
settings.setValue("view/orthogonalProjection",false);
viewActionPerspective->setChecked(true);
viewActionOrthogonal->setChecked(false);
- screen->setOrthoMode(false);
- screen->updateGL();
+ this->glview->setOrthoMode(false);
+ this->glview->updateGL();
}
void MainWindow::viewOrthogonal()
@@ -1635,8 +1699,8 @@ void MainWindow::viewOrthogonal()
settings.setValue("view/orthogonalProjection",true);
viewActionPerspective->setChecked(false);
viewActionOrthogonal->setChecked(true);
- screen->setOrthoMode(true);
- screen->updateGL();
+ this->glview->setOrthoMode(true);
+ this->glview->updateGL();
}
void MainWindow::hideConsole()
contact: Jan Huwald // Impressum