summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--context.cc34
-rw-r--r--example.scad5
-rw-r--r--lexer.l2
-rw-r--r--mainwin.cc4
-rw-r--r--module.cc2
-rw-r--r--openscad.h9
-rw-r--r--openscad.pro2
-rw-r--r--primitive.cc20
8 files changed, 63 insertions, 15 deletions
diff --git a/context.cc b/context.cc
index 1ae3c0d..127e367 100644
--- a/context.cc
+++ b/context.cc
@@ -20,25 +20,53 @@
#include "openscad.h"
+Context::Context(const Context *parent)
+{
+ this->parent = parent;
+ ctx_stack.append(this);
+}
+
+Context::~Context()
+{
+ ctx_stack.pop_back();
+}
+
void Context::args(const QVector<QString> &argnames, const QVector<Expression*> &argexpr,
const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues)
{
for (int i=0; i<argnames.size(); i++) {
- variables[argnames[i]] = i < argexpr.size() && argexpr[i] ? argexpr[i]->evaluate(this->parent) : Value();
+ set_variable(argnames[i], i < argexpr.size() && argexpr[i] ? argexpr[i]->evaluate(this->parent) : Value());
}
int posarg = 0;
for (int i=0; i<call_argnames.size(); i++) {
if (call_argnames[i].isEmpty()) {
- variables[argnames[posarg++]] = call_argvalues[i];
+ set_variable(argnames[posarg++], call_argvalues[i]);
} else {
- variables[call_argnames[i]] = call_argvalues[i];
+ set_variable(call_argnames[i], call_argvalues[i]);
}
}
}
+QVector<const Context*> Context::ctx_stack;
+
+void Context::set_variable(QString name, Value value)
+{
+ if (name.startsWith("$"))
+ config_variables[name] = value;
+ else
+ variables[name] = value;
+}
+
Value Context::lookup_variable(QString name) const
{
+ if (name.startsWith("$")) {
+ for (int i = ctx_stack.size()-1; i >= 0; i--) {
+ if (ctx_stack[i]->config_variables.contains(name))
+ return ctx_stack[i]->config_variables[name];
+ }
+ return Value();
+ }
if (variables.contains(name))
return variables[name];
if (parent)
diff --git a/example.scad b/example.scad
index c0ab7c2..0e844b2 100644
--- a/example.scad
+++ b/example.scad
@@ -76,6 +76,7 @@ module test005()
}
}
-test005();
-
+// test005();
+$fs_preview = 1;
+sphere(5);
diff --git a/lexer.l b/lexer.l
index 644512e..dd35aa1 100644
--- a/lexer.l
+++ b/lexer.l
@@ -52,7 +52,7 @@ extern const char *parser_input_buffer;
"undef" return TOK_UNDEF;
[+-]?[0-9][0-9.]* { parserlval.number = atof(yytext); return TOK_NUMBER; }
-[a-zA-Z0-9_]+ { parserlval.text = strdup(yytext); return TOK_ID; }
+"$"?[a-zA-Z0-9_]+ { parserlval.text = strdup(yytext); return TOK_ID; }
\"[^"]*\" { parserlval.text = strdup(yytext); return TOK_STRING; }
"." return '.';
diff --git a/mainwin.cc b/mainwin.cc
index 1331b4b..09affed 100644
--- a/mainwin.cc
+++ b/mainwin.cc
@@ -32,6 +32,10 @@ MainWindow::MainWindow(const char *filename)
{
root_ctx.functions_p = &builtin_functions;
root_ctx.modules_p = &builtin_modules;
+ root_ctx.set_variable("$fs_render", Value(1.0));
+ root_ctx.set_variable("$fa_render", Value(12.0));
+ root_ctx.set_variable("$fs_preview", Value(1.0));
+ root_ctx.set_variable("$fa_preview", Value(12.0));
root_module = NULL;
root_node = NULL;
diff --git a/module.cc b/module.cc
index c9142e2..6d7101c 100644
--- a/module.cc
+++ b/module.cc
@@ -112,7 +112,7 @@ AbstractNode *Module::evaluate(const Context *ctx, const QVector<QString> &call_
c.modules_p = &modules;
for (int i = 0; i < assignments_var.size(); i++) {
- c.variables[assignments_var[i]] = assignments_expr[i]->evaluate(&c);
+ c.set_variable(assignments_var[i], assignments_expr[i]->evaluate(&c));
}
AbstractNode *node = new AbstractNode();
diff --git a/openscad.h b/openscad.h
index a241a96..d37f6ac 100644
--- a/openscad.h
+++ b/openscad.h
@@ -245,13 +245,20 @@ class Context
public:
const Context *parent;
QHash<QString, Value> variables;
+ QHash<QString, Value> config_variables;
const QHash<QString, AbstractFunction*> *functions_p;
const QHash<QString, AbstractModule*> *modules_p;
- Context(const Context *parent = NULL) : parent(parent) { }
+ static QVector<const Context*> ctx_stack;
+
+ Context(const Context *parent = NULL);
+ ~Context();
+
void args(const QVector<QString> &argnames, const QVector<Expression*> &argexpr, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues);
+ void set_variable(QString name, Value value);
Value lookup_variable(QString name) const;
+
Value evaluate_function(QString name, const QVector<QString> &argnames, const QVector<Value> &argvalues) const;
AbstractNode *evaluate_module(QString name, const QVector<QString> &argnames, const QVector<Value> &argvalues, const QVector<AbstractNode*> child_nodes) const;
};
diff --git a/openscad.pro b/openscad.pro
index ed4618e..401647d 100644
--- a/openscad.pro
+++ b/openscad.pro
@@ -1,5 +1,5 @@
-CONFIG += qt
+CONFIG += qt debug
TEMPLATE = app
DEFINES += "ENABLE_CGAL=1"
diff --git a/primitive.cc b/primitive.cc
index beb73ba..a3e0fce 100644
--- a/primitive.cc
+++ b/primitive.cc
@@ -41,6 +41,8 @@ class PrimitiveNode : public AbstractPolyNode
public:
bool center;
double x, y, z, h, r1, r2;
+ double fs_render, fa_render;
+ double fs_preview, fa_preview;
primitive_type_e type;
PrimitiveNode(primitive_type_e type) : type(type) { }
virtual PolySet *render_polyset(render_mode_e mode) const;
@@ -70,6 +72,11 @@ AbstractNode *PrimitiveModule::evaluate(const Context *ctx, const QVector<QStrin
Context c(ctx);
c.args(argnames, argexpr, call_argnames, call_argvalues);
+ node->fs_render = c.lookup_variable("$fs_render").num;
+ node->fa_render = c.lookup_variable("$fa_render").num;
+ node->fs_preview = c.lookup_variable("$fs_preview").num;
+ node->fa_preview = c.lookup_variable("$fa_preview").num;
+
if (type == CUBE) {
Value size = c.lookup_variable("size");
Value center = c.lookup_variable("center");
@@ -132,15 +139,16 @@ void register_builtin_primitive()
builtin_modules["cylinder"] = new PrimitiveModule(CYLINDER);
}
-int get_fragments_from_r(double r)
+int get_fragments_from_r(double r, double fs, double fa)
{
- double fa = 72, fs = 0.5;
- return ceil(fmax(360.0 / fa, fmax(r*M_PI / fs, 5)));
+ return ceil(fmax(fmin(360.0 / fa, r*M_PI / fs), 5));
}
PolySet *PrimitiveNode::render_polyset(render_mode_e mode) const
{
PolySet *p = new PolySet();
+ double fs = mode == RENDER_CGAL ? fs_render : fs_preview;
+ double fa = mode == RENDER_CGAL ? fa_render : fa_preview;
if (type == CUBE && x > 0 && y > 0 && z > 0)
{
@@ -208,14 +216,14 @@ PolySet *PrimitiveNode::render_polyset(render_mode_e mode) const
double r, z;
};
- int rings = get_fragments_from_r(r1);
+ int rings = get_fragments_from_r(r1, fs, fa);
ring_s ring[rings];
for (int i = 0; i < rings; i++) {
double phi = (M_PI * (i + 0.5)) / rings;
ring[i].r = r1 * sin(phi);
ring[i].z = r1 * cos(phi);
- ring[i].fragments = get_fragments_from_r(ring[i].r);
+ ring[i].fragments = get_fragments_from_r(ring[i].r, fs, fa);
ring[i].points = new point2d[ring[i].fragments];
for (int j = 0; j < ring[i].fragments; j++) {
phi = (M_PI*2*j) / ring[i].fragments;
@@ -267,7 +275,7 @@ sphere_next_r2:
if (type == CYLINDER && h > 0 && r1 >=0 && r2 >= 0 && (r1 > 0 || r2 > 0))
{
- int fragments = get_fragments_from_r(fmax(r1, r2));
+ int fragments = get_fragments_from_r(fmax(r1, r2), fs, fa);
double z1, z2;
if (center) {
contact: Jan Huwald // Impressum