diff options
author | clifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c> | 2009-06-26 04:32:52 (GMT) |
---|---|---|
committer | clifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c> | 2009-06-26 04:32:52 (GMT) |
commit | a05c91bcecb7bbf85c0e5d5a307708e69f8eb9c8 (patch) | |
tree | 2c53782f53fcc614725a815630ffa43f36ca91cb | |
parent | c318b749b12a2d51115c65a9ad8c9f45396a90d8 (diff) |
Clifford Wolf:
Added generic config variables
Added ${fs,fa}_{render,preview}
git-svn-id: http://svn.clifford.at/openscad/trunk@22 b57f626f-c46c-0410-a088-ec61d464b74c
-rw-r--r-- | context.cc | 34 | ||||
-rw-r--r-- | example.scad | 5 | ||||
-rw-r--r-- | lexer.l | 2 | ||||
-rw-r--r-- | mainwin.cc | 4 | ||||
-rw-r--r-- | module.cc | 2 | ||||
-rw-r--r-- | openscad.h | 9 | ||||
-rw-r--r-- | openscad.pro | 2 | ||||
-rw-r--r-- | primitive.cc | 20 |
8 files changed, 63 insertions, 15 deletions
@@ -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); @@ -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 '.'; @@ -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; @@ -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(); @@ -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) { |