diff options
author | kintel <kintel@b57f626f-c46c-0410-a088-ec61d464b74c> | 2010-02-09 13:48:09 (GMT) |
---|---|---|
committer | kintel <kintel@b57f626f-c46c-0410-a088-ec61d464b74c> | 2010-02-09 13:48:09 (GMT) |
commit | c7b9a49c15f10ee76258f735ff66c1ed32e64c51 (patch) | |
tree | ebc9ef37dc44c0eed9c144441f5f763c381fdb08 /src/mainwin.cc | |
parent | 66ac9239767dd2151e61a11bc3fb9605c2a4d917 (diff) |
Cleaned up progress handling, implemented cancel function. Needs more testing
git-svn-id: http://svn.clifford.at/openscad/trunk@420 b57f626f-c46c-0410-a088-ec61d464b74c
Diffstat (limited to 'src/mainwin.cc')
-rw-r--r-- | src/mainwin.cc | 350 |
1 files changed, 205 insertions, 145 deletions
diff --git a/src/mainwin.cc b/src/mainwin.cc index e9bbdaa..02ea445 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -37,6 +37,7 @@ #include "export.h" #include "builtin.h" #include "dxftess.h" +#include "progress.h" #include <QMenu> #include <QTime> @@ -45,6 +46,7 @@ #include <QFileDialog> #include <QApplication> #include <QProgressDialog> +#include <QProgressBar> #include <QHBoxLayout> #include <QVBoxLayout> #include <QLabel> @@ -336,6 +338,20 @@ MainWindow::~MainWindow() #endif } +typedef QPair<QProgressBar*, QProgressDialog*> ProgressData; + +static void report_func(const class AbstractNode*, void *vp, int mark) +{ + ProgressData *progpair = static_cast<ProgressData*>(vp); + int v = (int)((mark*100.0) / progress_report_count); + progpair->first->setValue(v < 100 ? v : 99); + QString label; + label.sprintf("Rendering Polygon Mesh (%d/%d)", mark, progress_report_count); + progpair->second->setLabelText(label); + QApplication::processEvents(); + if (progpair->second->wasCanceled()) throw ProgressCancelException(); +} + /*! Requests to open a file from an external event, e.g. by double-clicking a filename. */ @@ -458,6 +474,9 @@ AbstractNode *MainWindow::find_root_tag(AbstractNode *n) return NULL; } +/*! + Parse and evaluate the design -> this->root_node +*/ void MainWindow::compile(bool procevents) { PRINT("Parsing design (AST generation)..."); @@ -554,7 +573,7 @@ void MainWindow::compile(bool procevents) if (procevents) QApplication::processEvents(); - AbstractNode::idx_counter = 1; + AbstractNode::resetIndexCounter(); root_inst = ModuleInstantiation(); absolute_root_node = root_module->evaluate(&root_ctx, &root_inst); @@ -567,6 +586,40 @@ void MainWindow::compile(bool procevents) } root_node->dump(""); + if (1) { + PRINT("Compilation finished."); + if (procevents) + QApplication::processEvents(); + } else { +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); + } + if (procevents) + QApplication::processEvents(); + } +} + +/*! + Generates CSG tree for OpenCSG evaluation. + Assumes that the design has been parsed and evaluated +*/ +void MainWindow::compileCSG(bool procevents) +{ + assert(this->root_node); PRINT("Compiling design (CSG Products generation)..."); if (procevents) QApplication::processEvents(); @@ -579,99 +632,102 @@ void MainWindow::compile(bool procevents) m[i] = -1; // Main CSG evaluation - root_raw_term = root_node->render_csg_term(m, &highlight_terms, &background_terms); - - if (!root_raw_term) - goto fail; - - PRINT("Compiling design (CSG Products normalization)..."); - if (procevents) - QApplication::processEvents(); + QTime t; + t.start(); - root_norm_term = root_raw_term->link(); + QProgressDialog *pd = new QProgressDialog("Rendering CSG products...", "Cancel", 0, 100); + QProgressBar *bar = new QProgressBar(pd); + bar->setRange(0, 100); + bar->setValue(0); + pd->setBar(bar); + pd->setAutoClose(false); + pd->show(); + ProgressData progpair(bar, pd); + QApplication::processEvents(); - // CSG normalization - while (1) { - CSGTerm *n = root_norm_term->normalize(); - root_norm_term->unlink(); - if (root_norm_term == n) - break; - root_norm_term = n; + progress_report_prep(root_node, report_func, &progpair); + try { + root_raw_term = root_node->render_csg_term(m, &highlight_terms, &background_terms); + if (!root_raw_term) { + PRINT("ERROR: CSG generation failed! (no top level object found)"); + if (procevents) + QApplication::processEvents(); + } } - - if (!root_norm_term) - goto fail; - - root_chain = new CSGChain(); - root_chain->import(root_norm_term); - - if (root_chain->polysets.size() > 1000) { - PRINTF("WARNING: Normalized tree has %d elements!", root_chain->polysets.size()); - PRINTF("WARNING: OpenCSG rendering has been disabled."); - } else { - enableOpenCSG = true; + catch (ProgressCancelException e) { } + progress_report_fin(); + delete pd; - if (highlight_terms.size() > 0) - { - PRINTF("Compiling highlights (%d CSG Trees)...", highlight_terms.size()); + if (root_raw_term) { + PRINT("Compiling design (CSG Products normalization)..."); if (procevents) QApplication::processEvents(); - - highlights_chain = new CSGChain(); - for (int i = 0; i < highlight_terms.size(); i++) { - while (1) { - CSGTerm *n = highlight_terms[i]->normalize(); - highlight_terms[i]->unlink(); - if (highlight_terms[i] == n) - break; - highlight_terms[i] = n; - } - highlights_chain->import(highlight_terms[i]); + + root_norm_term = root_raw_term->link(); + + // CSG normalization + while (1) { + CSGTerm *n = root_norm_term->normalize(); + root_norm_term->unlink(); + if (root_norm_term == n) + break; + root_norm_term = n; } - } - - if (background_terms.size() > 0) - { - PRINTF("Compiling background (%d CSG Trees)...", background_terms.size()); - if (procevents) - QApplication::processEvents(); + + assert(root_norm_term); - background_chain = new CSGChain(); - for (int i = 0; i < background_terms.size(); i++) { - while (1) { - CSGTerm *n = background_terms[i]->normalize(); - background_terms[i]->unlink(); - if (background_terms[i] == n) - break; - background_terms[i] = n; + root_chain = new CSGChain(); + root_chain->import(root_norm_term); + + if (root_chain->polysets.size() > 1000) { + PRINTF("WARNING: Normalized tree has %d elements!", root_chain->polysets.size()); + PRINTF("WARNING: OpenCSG rendering has been disabled."); + } else { + enableOpenCSG = true; + } + + if (highlight_terms.size() > 0) + { + PRINTF("Compiling highlights (%d CSG Trees)...", highlight_terms.size()); + if (procevents) + QApplication::processEvents(); + + highlights_chain = new CSGChain(); + for (int i = 0; i < highlight_terms.size(); i++) { + while (1) { + CSGTerm *n = highlight_terms[i]->normalize(); + highlight_terms[i]->unlink(); + if (highlight_terms[i] == n) + break; + highlight_terms[i] = n; + } + highlights_chain->import(highlight_terms[i]); } - background_chain->import(background_terms[i]); } - } - - if (1) { - PRINT("Compilation finished."); - if (procevents) - QApplication::processEvents(); - } else { -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; + + if (background_terms.size() > 0) + { + PRINTF("Compiling background (%d CSG Trees)...", background_terms.size()); + if (procevents) + QApplication::processEvents(); + + background_chain = new CSGChain(); + for (int i = 0; i < background_terms.size(); i++) { + while (1) { + CSGTerm *n = background_terms[i]->normalize(); + background_terms[i]->unlink(); + if (background_terms[i] == n) + break; + background_terms[i] = n; } + background_chain->import(background_terms[i]); } - PRINTF("ERROR: Compilation failed! (parser error in line %d)", line); } + + PRINT("CSG generation finished."); + int s = t.elapsed() / 1000; + PRINTF("Total rendering time: %d hours, %d minutes, %d seconds", s / (60*60), (s / 60) % 60, s % 60); if (procevents) QApplication::processEvents(); } @@ -909,6 +965,7 @@ void MainWindow::actionReloadCompile() current_win = this; compile(true); + if (this->root_node) compileCSG(true); #ifdef ENABLE_OPENCSG if (!(viewActionOpenCSG->isVisible() && viewActionOpenCSG->isChecked()) && @@ -929,6 +986,7 @@ void MainWindow::actionCompile() console->clear(); compile(!viewActionAnimate->isChecked()); + if (this->root_node) compileCSG(!viewActionAnimate->isChecked()); // Go to non-CGAL view mode if (!viewActionOpenCSG->isChecked() && !viewActionThrownTogether->isChecked()) { @@ -952,17 +1010,6 @@ void MainWindow::actionCompile() #ifdef ENABLE_CGAL -static void report_func(const class AbstractNode*, void *vp, int mark) -{ - QProgressDialog *pd = (QProgressDialog*)vp; - int v = (int)((mark*100.0) / progress_report_count); - pd->setValue(v < 100 ? v : 99); - QString label; - label.sprintf("Rendering Polygon Mesh using CGAL (%d/%d)", mark, progress_report_count); - pd->setLabelText(label); - QApplication::processEvents(); -} - void MainWindow::actionRenderCGAL() { current_win = this; @@ -985,71 +1032,84 @@ void MainWindow::actionRenderCGAL() QTime t; t.start(); - QProgressDialog *pd = new QProgressDialog("Rendering Polygon Mesh using CGAL...", QString(), 0, 100); - pd->setValue(0); + QProgressDialog *pd = new QProgressDialog("Rendering Polygon Mesh using CGAL...", "Cancel", 0, 100); + QProgressBar *bar = new QProgressBar(pd); + bar->setRange(0, 100); + bar->setValue(0); + pd->setBar(bar); pd->setAutoClose(false); pd->show(); +// this->statusBar()->addPermanentWidget(bar); + ProgressData progpair(bar, pd); QApplication::processEvents(); - progress_report_prep(root_node, report_func, pd); - this->root_N = new CGAL_Nef_polyhedron(root_node->render_cgal_nef_polyhedron()); + progress_report_prep(root_node, report_func, &progpair); + try { + this->root_N = new CGAL_Nef_polyhedron(root_node->render_cgal_nef_polyhedron()); + } + catch (ProgressCancelException e) { + } progress_report_fin(); +// this->statusBar()->removeWidget(bar); - 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"); - QApplication::processEvents(); - 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()); - QApplication::processEvents(); - 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()); - QApplication::processEvents(); - 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()); - QApplication::processEvents(); - PRINTF(" ConnComp: %6d", (int)this->root_N->p2.explorer().number_of_connected_components()); + 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()); 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"); - QApplication::processEvents(); - PRINTF(" Valid: %6s", this->root_N->p3.is_valid() ? "yes" : "no"); - QApplication::processEvents(); - PRINTF(" Vertices: %6d", (int)this->root_N->p3.number_of_vertices()); - QApplication::processEvents(); - PRINTF(" Halfedges: %6d", (int)this->root_N->p3.number_of_halfedges()); - QApplication::processEvents(); - PRINTF(" Edges: %6d", (int)this->root_N->p3.number_of_edges()); - QApplication::processEvents(); - PRINTF(" Halffacets: %6d", (int)this->root_N->p3.number_of_halffacets()); - QApplication::processEvents(); - PRINTF(" Facets: %6d", (int)this->root_N->p3.number_of_facets()); - QApplication::processEvents(); - PRINTF(" Volumes: %6d", (int)this->root_N->p3.number_of_volumes()); - 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"); + QApplication::processEvents(); + 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()); + QApplication::processEvents(); + 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()); + QApplication::processEvents(); + 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()); + QApplication::processEvents(); + 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"); + QApplication::processEvents(); + PRINTF(" Valid: %6s", this->root_N->p3.is_valid() ? "yes" : "no"); + QApplication::processEvents(); + PRINTF(" Vertices: %6d", (int)this->root_N->p3.number_of_vertices()); + QApplication::processEvents(); + PRINTF(" Halfedges: %6d", (int)this->root_N->p3.number_of_halfedges()); + QApplication::processEvents(); + PRINTF(" Edges: %6d", (int)this->root_N->p3.number_of_edges()); + QApplication::processEvents(); + PRINTF(" Halffacets: %6d", (int)this->root_N->p3.number_of_halffacets()); + QApplication::processEvents(); + PRINTF(" Facets: %6d", (int)this->root_N->p3.number_of_facets()); + QApplication::processEvents(); + 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); + int s = t.elapsed() / 1000; + PRINTF("Total rendering time: %d hours, %d minutes, %d seconds", s / (60*60), (s / 60) % 60, s % 60); - if (!viewActionCGALSurfaces->isChecked() && !viewActionCGALGrid->isChecked()) { - viewModeCGALSurface(); - } else { - screen->updateGL(); - } + if (!viewActionCGALSurfaces->isChecked() && !viewActionCGALGrid->isChecked()) { + viewModeCGALSurface(); + } else { + screen->updateGL(); + } - PRINT("Rendering finished."); + PRINT("Rendering finished."); + } delete pd; current_win = NULL; |