mirror of https://github.com/vitalif/openscad
Multiple non-MDI assumptions were made, setting CWD and assuming it didn't change. Fix required to pass more context to nodes (functions). It's not totally clean, but it's a start. Fixes bugs: opening multiple files simultaneously only loaded the first file, refreshing an scad file referencing an external file failed if another scad file was opened in the meantime.
git-svn-id: http://svn.clifford.at/openscad/trunk@451 b57f626f-c46c-0410-a088-ec61d464b74cstl_dim
parent
64c3be3fd7
commit
f3d16e23b9
|
@ -51,7 +51,7 @@ public:
|
|||
static const int maxRecentFiles = 10;
|
||||
QAction *actionRecentFile[maxRecentFiles];
|
||||
|
||||
MainWindow(const char *filename = 0);
|
||||
MainWindow(const QString &filename);
|
||||
~MainWindow();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include "function.h"
|
||||
#include "module.h"
|
||||
#include "printutils.h"
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
|
||||
Context::Context(const Context *parent)
|
||||
{
|
||||
|
@ -35,6 +37,7 @@ Context::Context(const Context *parent)
|
|||
functions_p = NULL;
|
||||
modules_p = NULL;
|
||||
inst_p = NULL;
|
||||
if (parent) document_path = parent->document_path;
|
||||
ctx_stack.append(this);
|
||||
}
|
||||
|
||||
|
@ -109,3 +112,8 @@ AbstractNode *Context::evaluate_module(const ModuleInstantiation *inst) const
|
|||
return NULL;
|
||||
}
|
||||
|
||||
QString Context::get_absolute_path(const QString &filename) const
|
||||
{
|
||||
return QFileInfo(QDir(this->document_path), filename).absoluteFilePath();
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ public:
|
|||
const QHash<QString, class AbstractFunction*> *functions_p;
|
||||
const QHash<QString, class AbstractModule*> *modules_p;
|
||||
const class ModuleInstantiation *inst_p;
|
||||
QString document_path;
|
||||
|
||||
static QVector<const Context*> ctx_stack;
|
||||
|
||||
|
@ -25,6 +26,8 @@ public:
|
|||
void set_variable(QString name, Value value);
|
||||
Value lookup_variable(QString name, bool silent = false) const;
|
||||
|
||||
QString get_absolute_path(const QString &filename) const;
|
||||
|
||||
Value evaluate_function(QString name, const QVector<QString> &argnames, const QVector<Value> &argvalues) const;
|
||||
class AbstractNode *evaluate_module(const ModuleInstantiation *inst) const;
|
||||
};
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "dxfdata.h"
|
||||
#include "builtin.h"
|
||||
#include "printutils.h"
|
||||
#include "context.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -39,7 +40,7 @@
|
|||
QHash<QString,Value> dxf_dim_cache;
|
||||
QHash<QString,Value> dxf_cross_cache;
|
||||
|
||||
Value builtin_dxf_dim(const QVector<QString> &argnames, const QVector<Value> &args)
|
||||
Value builtin_dxf_dim(const Context *ctx, const QVector<QString> &argnames, const QVector<Value> &args)
|
||||
{
|
||||
QString filename;
|
||||
QString layername;
|
||||
|
@ -50,7 +51,7 @@ Value builtin_dxf_dim(const QVector<QString> &argnames, const QVector<Value> &ar
|
|||
|
||||
for (int i = 0; i < argnames.count() && i < args.count(); i++) {
|
||||
if (argnames[i] == "file")
|
||||
filename = args[i].text;
|
||||
filename = ctx->get_absolute_path(args[i].text);
|
||||
if (argnames[i] == "layer")
|
||||
layername = args[i].text;
|
||||
if (argnames[i] == "origin")
|
||||
|
@ -124,7 +125,7 @@ Value builtin_dxf_dim(const QVector<QString> &argnames, const QVector<Value> &ar
|
|||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_dxf_cross(const QVector<QString> &argnames, const QVector<Value> &args)
|
||||
Value builtin_dxf_cross(const Context *ctx, const QVector<QString> &argnames, const QVector<Value> &args)
|
||||
{
|
||||
QString filename;
|
||||
QString layername;
|
||||
|
@ -134,7 +135,7 @@ Value builtin_dxf_cross(const QVector<QString> &argnames, const QVector<Value> &
|
|||
|
||||
for (int i = 0; i < argnames.count() && i < args.count(); i++) {
|
||||
if (argnames[i] == "file")
|
||||
filename = args[i].text;
|
||||
filename = ctx->get_absolute_path(args[i].text);
|
||||
if (argnames[i] == "layer")
|
||||
layername = args[i].text;
|
||||
if (argnames[i] == "origin")
|
||||
|
|
|
@ -91,7 +91,7 @@ AbstractNode *DxfLinearExtrudeModule::evaluate(const Context *ctx, const ModuleI
|
|||
Value twist = c.lookup_variable("twist", true);
|
||||
Value slices = c.lookup_variable("slices", true);
|
||||
|
||||
node->filename = file.text;
|
||||
node->filename = c.get_absolute_path(file.text);
|
||||
node->layername = layer.text;
|
||||
node->height = height.num;
|
||||
node->convexity = (int)convexity.num;
|
||||
|
|
|
@ -84,7 +84,7 @@ AbstractNode *DxfRotateExtrudeModule::evaluate(const Context *ctx, const ModuleI
|
|||
Value origin = c.lookup_variable("origin", true);
|
||||
Value scale = c.lookup_variable("scale", true);
|
||||
|
||||
node->filename = file.text;
|
||||
node->filename = c.get_absolute_path(file.text);
|
||||
node->layername = layer.text;
|
||||
node->convexity = (int)convexity.num;
|
||||
origin.getv2(node->origin_x, node->origin_y);
|
||||
|
|
78
src/func.cc
78
src/func.cc
|
@ -80,9 +80,9 @@ BuiltinFunction::~BuiltinFunction()
|
|||
{
|
||||
}
|
||||
|
||||
Value BuiltinFunction::evaluate(const Context*, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues) const
|
||||
Value BuiltinFunction::evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues) const
|
||||
{
|
||||
return eval_func(call_argnames, call_argvalues);
|
||||
return eval_func(ctx, call_argnames, call_argvalues);
|
||||
}
|
||||
|
||||
QString BuiltinFunction::dump(QString indent, QString name) const
|
||||
|
@ -110,7 +110,7 @@ static double rad2deg(double x)
|
|||
return x;
|
||||
}
|
||||
|
||||
Value builtin_min(const QVector<QString>&, const QVector<Value> &args)
|
||||
Value builtin_min(const Context *, const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() >= 1 && args[0].type == Value::NUMBER) {
|
||||
double val = args[0].num;
|
||||
|
@ -122,7 +122,7 @@ Value builtin_min(const QVector<QString>&, const QVector<Value> &args)
|
|||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_max(const QVector<QString>&, const QVector<Value> &args)
|
||||
Value builtin_max(const Context *, const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() >= 1 && args[0].type == Value::NUMBER) {
|
||||
double val = args[0].num;
|
||||
|
@ -134,98 +134,98 @@ Value builtin_max(const QVector<QString>&, const QVector<Value> &args)
|
|||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_sin(const QVector<QString>&, const QVector<Value> &args)
|
||||
Value builtin_sin(const Context *, const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() == 1 && args[0].type == Value::NUMBER)
|
||||
return Value(sin(deg2rad(args[0].num)));
|
||||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_cos(const QVector<QString>&, const QVector<Value> &args)
|
||||
Value builtin_cos(const Context *, const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() == 1 && args[0].type == Value::NUMBER)
|
||||
return Value(cos(deg2rad(args[0].num)));
|
||||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_asin(const QVector<QString>&, const QVector<Value> &args)
|
||||
Value builtin_asin(const Context *, const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() == 1 && args[0].type == Value::NUMBER)
|
||||
return Value(rad2deg(asin(args[0].num)));
|
||||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_acos(const QVector<QString>&, const QVector<Value> &args)
|
||||
Value builtin_acos(const Context *, const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() == 1 && args[0].type == Value::NUMBER)
|
||||
return Value(rad2deg(acos(args[0].num)));
|
||||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_tan(const QVector<QString>&, const QVector<Value> &args)
|
||||
Value builtin_tan(const Context *, const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() == 1 && args[0].type == Value::NUMBER)
|
||||
return Value(tan(deg2rad(args[0].num)));
|
||||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_atan(const QVector<QString>&, const QVector<Value> &args)
|
||||
Value builtin_atan(const Context *, const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() == 1 && args[0].type == Value::NUMBER)
|
||||
return Value(rad2deg(atan(args[0].num)));
|
||||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_atan2(const QVector<QString>&, const QVector<Value> &args)
|
||||
Value builtin_atan2(const Context *, const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() == 2 && args[0].type == Value::NUMBER && args[1].type == Value::NUMBER)
|
||||
return Value(rad2deg(atan2(args[0].num, args[1].num)));
|
||||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_round(const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() == 1 && args[0].type == Value::NUMBER)
|
||||
return Value(round(args[0].num));
|
||||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_ceil(const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() == 1 && args[0].type == Value::NUMBER)
|
||||
return Value(ceil(args[0].num));
|
||||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_floor(const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() == 1 && args[0].type == Value::NUMBER)
|
||||
return Value(floor(args[0].num));
|
||||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_pow(const QVector<QString>&, const QVector<Value> &args)
|
||||
Value builtin_pow(const Context *, const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() == 2 && args[0].type == Value::NUMBER && args[1].type == Value::NUMBER)
|
||||
return Value(pow(args[0].num, args[1].num));
|
||||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_sqrt(const QVector<QString>&, const QVector<Value> &args)
|
||||
Value builtin_round(const Context *, const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() == 1 && args[0].type == Value::NUMBER)
|
||||
return Value(round(args[0].num));
|
||||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_ceil(const Context *, const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() == 1 && args[0].type == Value::NUMBER)
|
||||
return Value(ceil(args[0].num));
|
||||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_floor(const Context *, const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() == 1 && args[0].type == Value::NUMBER)
|
||||
return Value(floor(args[0].num));
|
||||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_sqrt(const Context *, const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() == 1 && args[0].type == Value::NUMBER)
|
||||
return Value(sqrt(args[0].num));
|
||||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_exp(const QVector<QString>&, const QVector<Value> &args)
|
||||
Value builtin_exp(const Context *, const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() == 1 && args[0].type == Value::NUMBER)
|
||||
return Value(exp(args[0].num));
|
||||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_log(const QVector<QString>&, const QVector<Value> &args)
|
||||
Value builtin_log(const Context *, const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() == 2 && args[0].type == Value::NUMBER && args[1].type == Value::NUMBER)
|
||||
return Value(log(args[1].num) / log(args[0].num));
|
||||
|
@ -234,14 +234,14 @@ Value builtin_log(const QVector<QString>&, const QVector<Value> &args)
|
|||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_ln(const QVector<QString>&, const QVector<Value> &args)
|
||||
Value builtin_ln(const Context *, const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
if (args.size() == 1 && args[0].type == Value::NUMBER)
|
||||
return Value(log(args[0].num));
|
||||
return Value();
|
||||
}
|
||||
|
||||
Value builtin_str(const QVector<QString>&, const QVector<Value> &args)
|
||||
Value builtin_str(const Context *, const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
QString str;
|
||||
for (int i = 0; i < args.size(); i++)
|
||||
|
@ -254,7 +254,7 @@ Value builtin_str(const QVector<QString>&, const QVector<Value> &args)
|
|||
return Value(str);
|
||||
}
|
||||
|
||||
Value builtin_lookup(const QVector<QString>&, const QVector<Value> &args)
|
||||
Value builtin_lookup(const Context *, const QVector<QString>&, const QVector<Value> &args)
|
||||
{
|
||||
double p, low_p, low_v, high_p, high_v;
|
||||
if (args.size() < 2 || !args[0].getnum(p) || args[1].vec.size() < 2 || args[1].vec[0]->vec.size() < 2)
|
||||
|
|
|
@ -15,7 +15,7 @@ public:
|
|||
class BuiltinFunction : public AbstractFunction
|
||||
{
|
||||
public:
|
||||
typedef Value (*eval_func_t)(const QVector<QString> &argnames, const QVector<Value> &args);
|
||||
typedef Value (*eval_func_t)(const Context *ctx, const QVector<QString> &argnames, const QVector<Value> &args);
|
||||
eval_func_t eval_func;
|
||||
|
||||
BuiltinFunction(eval_func_t f) : eval_func(f) { }
|
||||
|
|
|
@ -93,7 +93,7 @@ AbstractNode *ImportModule::evaluate(const Context *ctx, const ModuleInstantiati
|
|||
node->fs = c.lookup_variable("$fs").num;
|
||||
node->fa = c.lookup_variable("$fa").num;
|
||||
|
||||
node->filename = c.lookup_variable("file").text;
|
||||
node->filename = c.get_absolute_path(c.lookup_variable("file").text);
|
||||
node->layername = c.lookup_variable("layer", true).text;
|
||||
node->convexity = c.lookup_variable("convexity", true).num;
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ static char copyrighttext[] =
|
|||
|
||||
QPointer<MainWindow> MainWindow::current_win = NULL;
|
||||
|
||||
MainWindow::MainWindow(const char *filename)
|
||||
MainWindow::MainWindow(const QString &filename)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
|
@ -299,7 +299,7 @@ MainWindow::MainWindow(const char *filename)
|
|||
PRINT(copyrighttext);
|
||||
PRINT("");
|
||||
|
||||
if (filename) {
|
||||
if (!filename.isEmpty()) {
|
||||
openFile(filename);
|
||||
} else {
|
||||
setFileName("");
|
||||
|
@ -387,7 +387,7 @@ static void report_func(const class AbstractNode*, void *vp, int mark)
|
|||
#ifdef ENABLE_MDI
|
||||
void MainWindow::requestOpenFile(const QString &filename)
|
||||
{
|
||||
new MainWindow(filename.toUtf8());
|
||||
new MainWindow(filename);
|
||||
}
|
||||
#else
|
||||
void MainWindow::requestOpenFile(const QString &)
|
||||
|
@ -400,7 +400,7 @@ MainWindow::openFile(const QString &new_filename)
|
|||
{
|
||||
#ifdef ENABLE_MDI
|
||||
if (!editor->toPlainText().isEmpty()) {
|
||||
new MainWindow(new_filename.toUtf8());
|
||||
new MainWindow(new_filename);
|
||||
current_win = NULL;
|
||||
return;
|
||||
}
|
||||
|
@ -415,6 +415,7 @@ MainWindow::setFileName(const QString &filename)
|
|||
{
|
||||
if (filename.isEmpty()) {
|
||||
this->fileName.clear();
|
||||
this->root_ctx.document_path = currentdir;
|
||||
setWindowTitle("OpenSCAD - New Document[*]");
|
||||
}
|
||||
else {
|
||||
|
@ -437,6 +438,7 @@ MainWindow::setFileName(const QString &filename)
|
|||
this->fileName = fileinfo.fileName();
|
||||
}
|
||||
|
||||
this->root_ctx.document_path = fileinfo.dir().absolutePath();
|
||||
QDir::setCurrent(fileinfo.dir().absolutePath());
|
||||
}
|
||||
|
||||
|
@ -773,7 +775,7 @@ void MainWindow::compileCSG(bool procevents)
|
|||
void MainWindow::actionNew()
|
||||
{
|
||||
#ifdef ENABLE_MDI
|
||||
new MainWindow;
|
||||
new MainWindow(QString());
|
||||
#else
|
||||
setFileName("");
|
||||
editor->setPlainText("");
|
||||
|
|
|
@ -59,6 +59,7 @@ static void help(const char *progname)
|
|||
QString commandline_commands;
|
||||
const char *make_command = NULL;
|
||||
QSet<QString> dependencies;
|
||||
QString currentdir;
|
||||
QString examplesdir;
|
||||
QString librarydir;
|
||||
|
||||
|
@ -101,6 +102,7 @@ int main(int argc, char **argv)
|
|||
#ifdef Q_WS_MAC
|
||||
app.installEventFilter(new EventFilter(&app));
|
||||
#endif
|
||||
QDir original_path = QDir::current();
|
||||
|
||||
// set up groups for QSettings
|
||||
QCoreApplication::setOrganizationName("OpenSCAD");
|
||||
|
@ -161,6 +163,8 @@ int main(int argc, char **argv)
|
|||
help(argv[0]);
|
||||
#endif
|
||||
|
||||
currentdir = QDir::currentPath();
|
||||
|
||||
QDir exdir(QApplication::instance()->applicationDirPath());
|
||||
#ifdef Q_WS_MAC
|
||||
exdir.cd("../Resources"); // Examples can be bundled
|
||||
|
@ -232,7 +236,6 @@ int main(int argc, char **argv)
|
|||
root_module = parse((text+commandline_commands).toAscii().data(), fileInfo.absolutePath().toLocal8Bit(), false);
|
||||
}
|
||||
|
||||
QString original_path = QDir::currentPath();
|
||||
QDir::setCurrent(fileInfo.absolutePath());
|
||||
|
||||
AbstractNode::resetIndexCounter();
|
||||
|
@ -241,7 +244,7 @@ int main(int argc, char **argv)
|
|||
CGAL_Nef_polyhedron *root_N;
|
||||
root_N = new CGAL_Nef_polyhedron(root_node->render_cgal_nef_polyhedron());
|
||||
|
||||
QDir::setCurrent(original_path);
|
||||
QDir::setCurrent(original_path.absolutePath());
|
||||
|
||||
if (deps_output_file) {
|
||||
fp = fopen(deps_output_file, "wt");
|
||||
|
@ -279,6 +282,8 @@ int main(int argc, char **argv)
|
|||
installAppleEventHandlers();
|
||||
#endif
|
||||
|
||||
QString qfilename = QFileInfo(original_path, filename).absoluteFilePath();
|
||||
|
||||
#if 0 /*** disabled by clifford wolf: adds rendering artefacts with OpenCSG ***/
|
||||
// turn on anti-aliasing
|
||||
QGLFormat f;
|
||||
|
@ -287,12 +292,12 @@ int main(int argc, char **argv)
|
|||
QGLFormat::setDefaultFormat(f);
|
||||
#endif
|
||||
#ifdef ENABLE_MDI
|
||||
new MainWindow(filename);
|
||||
new MainWindow(qfilename);
|
||||
while (optind < argc)
|
||||
new MainWindow(argv[optind++]);
|
||||
new MainWindow(QFileInfo(original_path, argv[optind++]).absoluteFilePath());
|
||||
app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
|
||||
#else
|
||||
MainWindow *m = new MainWindow(filename);
|
||||
MainWindow *m = new MainWindow(qfilename);
|
||||
app.connect(m, SIGNAL(destroyed()), &app, SLOT(quit()));
|
||||
#endif
|
||||
rc = app.exec();
|
||||
|
|
|
@ -46,6 +46,10 @@ extern int parser_error_pos;
|
|||
|
||||
extern void handle_dep(QString filename);
|
||||
|
||||
// The CWD when application started. We shouldn't change CWD, but until we stop
|
||||
// doing this, use currentdir to get the original CWD.
|
||||
extern QString currentdir;
|
||||
|
||||
extern QString examplesdir;
|
||||
extern QString librarydir;
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ AbstractNode *SurfaceModule::evaluate(const Context *ctx, const ModuleInstantiat
|
|||
Context c(ctx);
|
||||
c.args(argnames, argexpr, inst->argnames, inst->argvalues);
|
||||
|
||||
node->filename = c.lookup_variable("file").text;
|
||||
node->filename = c.get_absolute_path(c.lookup_variable("file").text);
|
||||
|
||||
Value center = c.lookup_variable("center", true);
|
||||
if (center.type == Value::BOOL) {
|
||||
|
|
Loading…
Reference in New Issue