mirror of https://github.com/vitalif/openscad
Cleaned up progress handling, implemented cancel function. Needs more testing
git-svn-id: http://svn.clifford.at/openscad/trunk@420 b57f626f-c46c-0410-a088-ec61d464b74cstl_dim
parent
66ac923976
commit
c7b9a49c15
|
@ -86,7 +86,8 @@ HEADERS += src/CGAL_renderer.h \
|
|||
src/openscad.h \
|
||||
src/polyset.h \
|
||||
src/printutils.h \
|
||||
src/value.h
|
||||
src/value.h \
|
||||
src/progress.h
|
||||
|
||||
SOURCES += src/openscad.cc \
|
||||
src/mainwin.cc \
|
||||
|
@ -118,7 +119,8 @@ SOURCES += src/openscad.cc \
|
|||
src/highlighter.cc \
|
||||
src/printutils.cc \
|
||||
src/nef2dxf.cc \
|
||||
src/Preferences.cc
|
||||
src/Preferences.cc \
|
||||
src/progress.cc
|
||||
|
||||
macx {
|
||||
HEADERS += src/AppleEvents.h \
|
||||
|
|
|
@ -68,6 +68,7 @@ private:
|
|||
void load();
|
||||
AbstractNode *find_root_tag(AbstractNode *n);
|
||||
void compile(bool procevents);
|
||||
void compileCSG(bool procevents);
|
||||
bool maybeSave();
|
||||
|
||||
private slots:
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "dxfdata.h"
|
||||
#include "dxftess.h"
|
||||
#include "polyset.h"
|
||||
#include "progress.h"
|
||||
#include "openscad.h" // get_fragments_from_r()
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -209,17 +210,6 @@ static void add_slice(PolySet *ps, DxfData::Path *pt, double rot1, double rot2,
|
|||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
PolySet *DxfLinearExtrudeNode::render_polyset(render_mode_e rm) const
|
||||
{
|
||||
QString key = mk_cache_id();
|
||||
|
@ -234,26 +224,9 @@ PolySet *DxfLinearExtrudeNode::render_polyset(render_mode_e rm) const
|
|||
if (filename.isEmpty())
|
||||
{
|
||||
#ifdef ENABLE_CGAL
|
||||
QTime t;
|
||||
QProgressDialog *pd = NULL;
|
||||
|
||||
if (rm == RENDER_OPENCSG)
|
||||
{
|
||||
PRINT_NOCACHE("Processing uncached linear_extrude outline...");
|
||||
QApplication::processEvents();
|
||||
|
||||
t.start();
|
||||
pd = new QProgressDialog("Rendering Polygon Mesh using CGAL...", QString(), 0, 100);
|
||||
pd->setValue(0);
|
||||
pd->setAutoClose(false);
|
||||
pd->show();
|
||||
QApplication::processEvents();
|
||||
|
||||
progress_report_prep((AbstractNode*)this, report_func, pd);
|
||||
}
|
||||
|
||||
// Before extruding, union all (2D) children nodes
|
||||
// to a single DxfData, then tessealte this into a PolySet
|
||||
// to a single DxfData, then tesselate this into a PolySet
|
||||
CGAL_Nef_polyhedron N;
|
||||
N.dim = 2;
|
||||
foreach(AbstractNode * v, children) {
|
||||
|
@ -263,12 +236,6 @@ PolySet *DxfLinearExtrudeNode::render_polyset(render_mode_e rm) const
|
|||
}
|
||||
dxf = new DxfData(N);
|
||||
|
||||
if (rm == RENDER_OPENCSG) {
|
||||
progress_report_fin();
|
||||
int s = t.elapsed() / 1000;
|
||||
PRINTF_NOCACHE("..rendering time: %d hours, %d minutes, %d seconds", s / (60*60), (s / 60) % 60, s % 60);
|
||||
delete pd;
|
||||
}
|
||||
#else // ENABLE_CGAL
|
||||
PRINT("WARNING: Found linear_extrude() statement without dxf file but compiled without CGAL support!");
|
||||
dxf = new DxfData();
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "builtin.h"
|
||||
#include "polyset.h"
|
||||
#include "dxfdata.h"
|
||||
#include "progress.h"
|
||||
#include "openscad.h" // get_fragments_from_r()
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -112,17 +113,6 @@ void register_builtin_dxf_rotate_extrude()
|
|||
builtin_modules["rotate_extrude"] = new DxfRotateExtrudeModule();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
PolySet *DxfRotateExtrudeNode::render_polyset(render_mode_e rm) const
|
||||
{
|
||||
QString key = mk_cache_id();
|
||||
|
@ -137,24 +127,6 @@ PolySet *DxfRotateExtrudeNode::render_polyset(render_mode_e rm) const
|
|||
if (filename.isEmpty())
|
||||
{
|
||||
#ifdef ENABLE_CGAL
|
||||
QTime t;
|
||||
QProgressDialog *pd;
|
||||
|
||||
if (rm == RENDER_OPENCSG)
|
||||
{
|
||||
PRINT_NOCACHE("Processing uncached rotate_extrude outline...");
|
||||
QApplication::processEvents();
|
||||
|
||||
t.start();
|
||||
pd = new QProgressDialog("Rendering Polygon Mesh using CGAL...", QString(), 0, 100);
|
||||
pd->setValue(0);
|
||||
pd->setAutoClose(false);
|
||||
pd->show();
|
||||
QApplication::processEvents();
|
||||
|
||||
progress_report_prep((AbstractNode*)this, report_func, pd);
|
||||
}
|
||||
|
||||
CGAL_Nef_polyhedron N;
|
||||
N.dim = 2;
|
||||
foreach(AbstractNode * v, children) {
|
||||
|
@ -164,12 +136,6 @@ PolySet *DxfRotateExtrudeNode::render_polyset(render_mode_e rm) const
|
|||
}
|
||||
dxf = new DxfData(N);
|
||||
|
||||
if (rm == RENDER_OPENCSG) {
|
||||
progress_report_fin();
|
||||
int s = t.elapsed() / 1000;
|
||||
PRINTF_NOCACHE("..rendering time: %d hours, %d minutes, %d seconds", s / (60*60), (s / 60) % 60, s % 60);
|
||||
delete pd;
|
||||
}
|
||||
#else // ENABLE_CGAL
|
||||
PRINT("WARNING: Found rotate_extrude() statement without dxf file but compiled without CGAL support!");
|
||||
dxf = new DxfData();
|
||||
|
|
364
src/mainwin.cc
364
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,89 +586,6 @@ void MainWindow::compile(bool procevents)
|
|||
}
|
||||
root_node->dump("");
|
||||
|
||||
PRINT("Compiling design (CSG Products generation)...");
|
||||
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
|
||||
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();
|
||||
|
||||
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 (!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;
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
if (1) {
|
||||
PRINT("Compilation finished.");
|
||||
if (procevents)
|
||||
|
@ -677,6 +613,126 @@ fail:
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
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();
|
||||
|
||||
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();
|
||||
|
||||
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();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
catch (ProgressCancelException e) {
|
||||
}
|
||||
progress_report_fin();
|
||||
delete pd;
|
||||
|
||||
if (root_raw_term) {
|
||||
PRINT("Compiling design (CSG Products normalization)...");
|
||||
if (procevents)
|
||||
QApplication::processEvents();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
assert(root_norm_term);
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::actionNew()
|
||||
{
|
||||
#ifdef ENABLE_MDI
|
||||
|
@ -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,72 +1032,85 @@ 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)
|
||||
{
|
||||
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());
|
||||
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);
|
||||
|
||||
if (!viewActionCGALSurfaces->isChecked() && !viewActionCGALGrid->isChecked()) {
|
||||
viewModeCGALSurface();
|
||||
} else {
|
||||
screen->updateGL();
|
||||
}
|
||||
|
||||
PRINT("Rendering finished.");
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (!viewActionCGALSurfaces->isChecked() && !viewActionCGALGrid->isChecked()) {
|
||||
viewModeCGALSurface();
|
||||
} else {
|
||||
screen->updateGL();
|
||||
}
|
||||
|
||||
PRINT("Rendering finished.");
|
||||
|
||||
delete pd;
|
||||
current_win = NULL;
|
||||
}
|
||||
|
|
65
src/node.cc
65
src/node.cc
|
@ -27,6 +27,8 @@
|
|||
#include "node.h"
|
||||
#include "module.h"
|
||||
#include "csgterm.h"
|
||||
#include "progress.h"
|
||||
#include "polyset.h"
|
||||
#include <QRegExp>
|
||||
|
||||
int AbstractNode::idx_counter;
|
||||
|
@ -55,7 +57,7 @@ QString AbstractNode::mk_cache_id() const
|
|||
|
||||
#ifdef ENABLE_CGAL
|
||||
|
||||
AbstractNode::cgal_nef_cache_entry::cgal_nef_cache_entry(CGAL_Nef_polyhedron N) :
|
||||
AbstractNode::cgal_nef_cache_entry::cgal_nef_cache_entry(const CGAL_Nef_polyhedron &N) :
|
||||
N(N), msg(print_messages_stack.last()) { };
|
||||
|
||||
QCache<QString, AbstractNode::cgal_nef_cache_entry> AbstractNode::cgal_nef_cache(100000);
|
||||
|
@ -167,35 +169,64 @@ QString AbstractIntersectionNode::dump(QString indent) const
|
|||
return dump_cache;
|
||||
}
|
||||
|
||||
int progress_report_count;
|
||||
void (*progress_report_f)(const class AbstractNode*, void*, int);
|
||||
void *progress_report_vp;
|
||||
|
||||
void AbstractNode::progress_prepare()
|
||||
{
|
||||
foreach (AbstractNode *v, children)
|
||||
v->progress_prepare();
|
||||
progress_mark = ++progress_report_count;
|
||||
this->progress_mark = ++progress_report_count;
|
||||
}
|
||||
|
||||
void AbstractNode::progress_report() const
|
||||
{
|
||||
if (progress_report_f)
|
||||
progress_report_f(this, progress_report_vp, progress_mark);
|
||||
progress_update(this, this->progress_mark);
|
||||
}
|
||||
|
||||
void progress_report_prep(AbstractNode *root, void (*f)(const class AbstractNode *node, void *vp, int mark), void *vp)
|
||||
#ifdef ENABLE_CGAL
|
||||
|
||||
CGAL_Nef_polyhedron AbstractPolyNode::render_cgal_nef_polyhedron() const
|
||||
{
|
||||
progress_report_count = 0;
|
||||
progress_report_f = f;
|
||||
progress_report_vp = vp;
|
||||
root->progress_prepare();
|
||||
QString cache_id = mk_cache_id();
|
||||
if (cgal_nef_cache.contains(cache_id)) {
|
||||
progress_report();
|
||||
PRINT(cgal_nef_cache[cache_id]->msg);
|
||||
return cgal_nef_cache[cache_id]->N;
|
||||
}
|
||||
|
||||
print_messages_push();
|
||||
|
||||
PolySet *ps = render_polyset(RENDER_CGAL);
|
||||
try {
|
||||
CGAL_Nef_polyhedron N = ps->render_cgal_nef_polyhedron();
|
||||
cgal_nef_cache.insert(cache_id, new cgal_nef_cache_entry(N), N.weight());
|
||||
print_messages_pop();
|
||||
progress_report();
|
||||
|
||||
ps->unlink();
|
||||
return N;
|
||||
}
|
||||
catch (...) { // Don't leak the PolySet on ProgressCancelException
|
||||
ps->unlink();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void progress_report_fin()
|
||||
#endif /* ENABLE_CGAL */
|
||||
|
||||
CSGTerm *AbstractPolyNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
|
||||
{
|
||||
progress_report_count = 0;
|
||||
progress_report_f = NULL;
|
||||
progress_report_vp = NULL;
|
||||
PolySet *ps = render_polyset(RENDER_OPENCSG);
|
||||
return render_csg_term_from_ps(m, highlights, background, ps, modinst, idx);
|
||||
}
|
||||
|
||||
CSGTerm *AbstractPolyNode::render_csg_term_from_ps(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background, PolySet *ps, const ModuleInstantiation *modinst, int idx)
|
||||
{
|
||||
CSGTerm *t = new CSGTerm(ps, m, QString("n%1").arg(idx));
|
||||
if (modinst->tag_highlight && highlights)
|
||||
highlights->append(t->link());
|
||||
if (modinst->tag_background && background) {
|
||||
background->append(t);
|
||||
return NULL;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,10 @@ void progress_report_fin();
|
|||
|
||||
class AbstractNode
|
||||
{
|
||||
static int idx_counter; // Node instantiation index
|
||||
public:
|
||||
static void resetIndexCounter() { idx_counter = 1; }
|
||||
|
||||
QVector<AbstractNode*> children;
|
||||
const class ModuleInstantiation *modinst;
|
||||
|
||||
|
@ -26,7 +29,6 @@ public:
|
|||
void progress_report() const;
|
||||
|
||||
int idx;
|
||||
static int idx_counter;
|
||||
QString dump_cache;
|
||||
|
||||
AbstractNode(const ModuleInstantiation *mi);
|
||||
|
@ -36,7 +38,7 @@ public:
|
|||
struct cgal_nef_cache_entry {
|
||||
CGAL_Nef_polyhedron N;
|
||||
QString msg;
|
||||
cgal_nef_cache_entry(CGAL_Nef_polyhedron N);
|
||||
cgal_nef_cache_entry(const CGAL_Nef_polyhedron &N);
|
||||
};
|
||||
static QCache<QString, cgal_nef_cache_entry> cgal_nef_cache;
|
||||
virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const;
|
||||
|
@ -64,7 +66,7 @@ public:
|
|||
RENDER_OPENCSG
|
||||
};
|
||||
AbstractPolyNode(const ModuleInstantiation *mi) : AbstractNode(mi) { };
|
||||
virtual class PolySet *render_polyset(render_mode_e mode) const;
|
||||
virtual class PolySet *render_polyset(render_mode_e mode) const = 0;
|
||||
#ifdef ENABLE_CGAL
|
||||
virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const;
|
||||
#endif
|
||||
|
|
|
@ -227,7 +227,7 @@ int main(int argc, char **argv)
|
|||
QString original_path = QDir::currentPath();
|
||||
QDir::setCurrent(fileInfo.absolutePath());
|
||||
|
||||
AbstractNode::idx_counter = 1;
|
||||
AbstractNode::resetIndexCounter();
|
||||
root_node = root_module->evaluate(&root_ctx, &root_inst);
|
||||
|
||||
CGAL_Nef_polyhedron *root_N;
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
*/
|
||||
|
||||
#include "polyset.h"
|
||||
#include "node.h"
|
||||
#include "module.h"
|
||||
#include "csgterm.h"
|
||||
#include "printutils.h"
|
||||
#include "Preferences.h"
|
||||
|
||||
|
@ -666,52 +663,3 @@ CGAL_Nef_polyhedron PolySet::render_cgal_nef_polyhedron() const
|
|||
|
||||
#endif /* ENABLE_CGAL */
|
||||
|
||||
PolySet *AbstractPolyNode::render_polyset(render_mode_e) const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_CGAL
|
||||
|
||||
CGAL_Nef_polyhedron AbstractPolyNode::render_cgal_nef_polyhedron() const
|
||||
{
|
||||
QString cache_id = mk_cache_id();
|
||||
if (cgal_nef_cache.contains(cache_id)) {
|
||||
progress_report();
|
||||
PRINT(cgal_nef_cache[cache_id]->msg);
|
||||
return cgal_nef_cache[cache_id]->N;
|
||||
}
|
||||
|
||||
print_messages_push();
|
||||
|
||||
PolySet *ps = render_polyset(RENDER_CGAL);
|
||||
CGAL_Nef_polyhedron N = ps->render_cgal_nef_polyhedron();
|
||||
|
||||
cgal_nef_cache.insert(cache_id, new cgal_nef_cache_entry(N), N.weight());
|
||||
print_messages_pop();
|
||||
progress_report();
|
||||
|
||||
ps->unlink();
|
||||
return N;
|
||||
}
|
||||
|
||||
#endif /* ENABLE_CGAL */
|
||||
|
||||
CSGTerm *AbstractPolyNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
|
||||
{
|
||||
PolySet *ps = render_polyset(RENDER_OPENCSG);
|
||||
return render_csg_term_from_ps(m, highlights, background, ps, modinst, idx);
|
||||
}
|
||||
|
||||
CSGTerm *AbstractPolyNode::render_csg_term_from_ps(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background, PolySet *ps, const ModuleInstantiation *modinst, int idx)
|
||||
{
|
||||
CSGTerm *t = new CSGTerm(ps, m, QString("n%1").arg(idx));
|
||||
if (modinst->tag_highlight && highlights)
|
||||
highlights->append(t->link());
|
||||
if (modinst->tag_background && background) {
|
||||
background->append(t);
|
||||
return NULL;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
#include "progress.h"
|
||||
#include "node.h"
|
||||
|
||||
int progress_report_count;
|
||||
void (*progress_report_f)(const class AbstractNode*, void*, int);
|
||||
void *progress_report_userdata;
|
||||
|
||||
void progress_report_prep(AbstractNode *root, void (*f)(const class AbstractNode *node, void *userdata, int mark), void *userdata)
|
||||
{
|
||||
progress_report_count = 0;
|
||||
progress_report_f = f;
|
||||
progress_report_userdata = userdata;
|
||||
root->progress_prepare();
|
||||
}
|
||||
|
||||
void progress_report_fin()
|
||||
{
|
||||
progress_report_count = 0;
|
||||
progress_report_f = NULL;
|
||||
progress_report_userdata = NULL;
|
||||
}
|
||||
|
||||
void progress_update(const AbstractNode *node, int mark)
|
||||
{
|
||||
if (progress_report_f)
|
||||
progress_report_f(node, progress_report_userdata, mark);
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef PROGRESS_H_
|
||||
#define PROGRESS_H_
|
||||
|
||||
// Reset to 0 in _prep() and increased for each Node instance in progress_prepare()
|
||||
extern int progress_report_count;
|
||||
|
||||
extern void (*progress_report_f)(const class AbstractNode*, void*, int);
|
||||
extern void *progress_report_userdata;
|
||||
|
||||
void progress_report_prep(AbstractNode *root, void (*f)(const class AbstractNode *node, void *userdata, int mark), void *userdata);
|
||||
void progress_report_fin();
|
||||
void progress_update(const AbstractNode *node, int mark);
|
||||
|
||||
class ProgressCancelException { };
|
||||
|
||||
#endif
|
|
@ -32,6 +32,7 @@
|
|||
#include "dxftess.h"
|
||||
#include "polyset.h"
|
||||
#include "export.h"
|
||||
#include "progress.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -95,17 +96,6 @@ void register_builtin_projection()
|
|||
|
||||
#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();
|
||||
}
|
||||
|
||||
PolySet *ProjectionNode::render_polyset(render_mode_e rm) const
|
||||
{
|
||||
QString key = mk_cache_id();
|
||||
|
@ -116,24 +106,6 @@ PolySet *ProjectionNode::render_polyset(render_mode_e rm) const
|
|||
|
||||
print_messages_push();
|
||||
|
||||
QTime t;
|
||||
QProgressDialog *pd = NULL;
|
||||
|
||||
if (rm == RENDER_OPENCSG)
|
||||
{
|
||||
PRINT_NOCACHE("Processing uncached projection body...");
|
||||
QApplication::processEvents();
|
||||
|
||||
t.start();
|
||||
pd = new QProgressDialog("Rendering Polygon Mesh using CGAL...", QString(), 0, 100);
|
||||
pd->setValue(0);
|
||||
pd->setAutoClose(false);
|
||||
pd->show();
|
||||
QApplication::processEvents();
|
||||
|
||||
progress_report_prep((AbstractNode*)this, report_func, pd);
|
||||
}
|
||||
|
||||
CGAL_Nef_polyhedron N;
|
||||
N.dim = 3;
|
||||
foreach(AbstractNode *v, this->children) {
|
||||
|
@ -142,13 +114,6 @@ PolySet *ProjectionNode::render_polyset(render_mode_e rm) const
|
|||
N.p3 += v->render_cgal_nef_polyhedron().p3;
|
||||
}
|
||||
|
||||
if (rm == RENDER_OPENCSG) {
|
||||
progress_report_fin();
|
||||
int s = t.elapsed() / 1000;
|
||||
PRINTF_NOCACHE("..rendering time: %d hours, %d minutes, %d seconds", s / (60*60), (s / 60) % 60, s % 60);
|
||||
delete pd;
|
||||
}
|
||||
|
||||
PolySet *ps = new PolySet();
|
||||
ps->convexity = this->convexity;
|
||||
ps->is2d = true;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "csgterm.h"
|
||||
#include "builtin.h"
|
||||
#include "printutils.h"
|
||||
#include "progress.h"
|
||||
#ifdef ENABLE_CGAL
|
||||
# include "cgal.h"
|
||||
#endif
|
||||
|
@ -124,17 +125,6 @@ CGAL_Nef_polyhedron RenderNode::render_cgal_nef_polyhedron() const
|
|||
return N;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
CSGTerm *RenderNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
|
||||
{
|
||||
QString key = mk_cache_id();
|
||||
|
@ -162,20 +152,10 @@ CSGTerm *RenderNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights
|
|||
QTime t;
|
||||
t.start();
|
||||
|
||||
QProgressDialog *pd = new QProgressDialog("Rendering Polygon Mesh using CGAL...", QString(), 0, 100);
|
||||
pd->setValue(0);
|
||||
pd->setAutoClose(false);
|
||||
pd->show();
|
||||
QApplication::processEvents();
|
||||
|
||||
progress_report_prep((AbstractNode*)this, report_func, pd);
|
||||
N = this->render_cgal_nef_polyhedron();
|
||||
progress_report_fin();
|
||||
|
||||
int s = t.elapsed() / 1000;
|
||||
PRINTF_NOCACHE("..rendering time: %d hours, %d minutes, %d seconds", s / (60*60), (s / 60) % 60, s % 60);
|
||||
|
||||
delete pd;
|
||||
}
|
||||
|
||||
PolySet *ps = NULL;
|
||||
|
|
Loading…
Reference in New Issue