mirror of https://github.com/vitalif/openscad
bugfix: Correctly handle else scopes, handle overrides inside assign scopes
parent
d195d05008
commit
23c9dee265
|
@ -62,7 +62,7 @@ AbstractNode *CgaladvModule::instantiate(const Context *ctx, const ModuleInstant
|
|||
|
||||
Context c(ctx);
|
||||
c.setVariables(args, evalctx);
|
||||
evalctx->applyScope();
|
||||
inst->scope.apply(*evalctx);
|
||||
|
||||
Value convexity, path, subdiv_type, level;
|
||||
|
||||
|
|
|
@ -218,7 +218,7 @@ AbstractNode *ColorModule::instantiate(const Context *ctx, const ModuleInstantia
|
|||
|
||||
Context c(ctx);
|
||||
c.setVariables(args, evalctx);
|
||||
evalctx->applyScope();
|
||||
inst->scope.apply(*evalctx);
|
||||
|
||||
Value v = c.lookup_variable("c");
|
||||
if (v.type() == Value::VECTOR) {
|
||||
|
|
|
@ -167,10 +167,6 @@ AbstractNode *ControlModule::instantiate(const Context* /*ctx*/, const ModuleIns
|
|||
{
|
||||
AbstractNode *node = NULL;
|
||||
|
||||
if (this->type != FOR && this->type != INT_FOR) {
|
||||
evalctx->applyScope();
|
||||
}
|
||||
|
||||
switch (this->type) {
|
||||
case CHILD: {
|
||||
printDeprecation("DEPRECATED: child() will be removed in future releases. Use children() instead.");
|
||||
|
@ -285,11 +281,15 @@ AbstractNode *ControlModule::instantiate(const Context* /*ctx*/, const ModuleIns
|
|||
|
||||
case ASSIGN: {
|
||||
node = new AbstractNode(inst);
|
||||
// We create a new context to avoid parameters from influencing each other
|
||||
// -> parallel evaluation. This is to be backwards compatible.
|
||||
Context c(evalctx);
|
||||
for (size_t i = 0; i < evalctx->numArgs(); i++) {
|
||||
if (!evalctx->getArgName(i).empty())
|
||||
c.set_variable(evalctx->getArgName(i), evalctx->getArgValue(i));
|
||||
}
|
||||
// Let any local variables override the parameters
|
||||
inst->scope.apply(c);
|
||||
std::vector<AbstractNode *> instantiatednodes = inst->instantiateChildren(&c);
|
||||
node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end());
|
||||
}
|
||||
|
@ -309,10 +309,12 @@ AbstractNode *ControlModule::instantiate(const Context* /*ctx*/, const ModuleIns
|
|||
node = new AbstractNode(inst);
|
||||
const IfElseModuleInstantiation *ifelse = dynamic_cast<const IfElseModuleInstantiation*>(inst);
|
||||
if (evalctx->numArgs() > 0 && evalctx->getArgValue(0).toBool()) {
|
||||
inst->scope.apply(*evalctx);
|
||||
std::vector<AbstractNode *> instantiatednodes = ifelse->instantiateChildren(evalctx);
|
||||
node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end());
|
||||
}
|
||||
else {
|
||||
ifelse->else_scope.apply(*evalctx);
|
||||
std::vector<AbstractNode *> instantiatednodes = ifelse->instantiateElseChildren(evalctx);
|
||||
node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end());
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
|
||||
AbstractNode *CsgModule::instantiate(const Context*, const ModuleInstantiation *inst, EvalContext *evalctx) const
|
||||
{
|
||||
evalctx->applyScope();
|
||||
inst->scope.apply(*evalctx);
|
||||
CsgNode *node = new CsgNode(inst, type);
|
||||
std::vector<AbstractNode *> instantiatednodes = inst->instantiateChildren(evalctx);
|
||||
node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end());
|
||||
|
|
|
@ -37,22 +37,6 @@ ModuleInstantiation *EvalContext::getChild(size_t i) const
|
|||
return this->scope ? this->scope->children[i] : NULL;
|
||||
}
|
||||
|
||||
/*!
|
||||
When instantiating a module which can take a scope as parameter (i.e. non-leaf nodes),
|
||||
use this method to apply the local scope definitions to the evaluation context.
|
||||
This will enable variables defined in local blocks.
|
||||
NB! for loops are special as the local block may depend on variables evaluated by the
|
||||
for loop parameters. The for loop code will handle this specially.
|
||||
*/
|
||||
void EvalContext::applyScope()
|
||||
{
|
||||
if (this->scope) {
|
||||
BOOST_FOREACH(const Assignment &ass, this->scope->assignments) {
|
||||
this->set_variable(ass.first, ass.second->evaluate(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
std::string EvalContext::dump(const AbstractModule *mod, const ModuleInstantiation *inst)
|
||||
{
|
||||
|
|
|
@ -22,8 +22,6 @@ public:
|
|||
size_t numChildren() const;
|
||||
ModuleInstantiation *getChild(size_t i) const;
|
||||
|
||||
void applyScope();
|
||||
|
||||
#ifdef DEBUG
|
||||
virtual std::string dump(const class AbstractModule *mod, const ModuleInstantiation *inst);
|
||||
#endif
|
||||
|
|
|
@ -58,7 +58,7 @@ AbstractNode *LinearExtrudeModule::instantiate(const Context *ctx, const ModuleI
|
|||
|
||||
Context c(ctx);
|
||||
c.setVariables(args, evalctx);
|
||||
evalctx->applyScope();
|
||||
inst->scope.apply(*evalctx);
|
||||
|
||||
node->fn = c.lookup_variable("$fn").toDouble();
|
||||
node->fs = c.lookup_variable("$fs").toDouble();
|
||||
|
|
|
@ -54,3 +54,16 @@ std::vector<AbstractNode*> LocalScope::instantiateChildren(const Context *evalct
|
|||
return childnodes;
|
||||
}
|
||||
|
||||
/*!
|
||||
When instantiating a module which can take a scope as parameter (i.e. non-leaf nodes),
|
||||
use this method to apply the local scope definitions to the evaluation context.
|
||||
This will enable variables defined in local blocks.
|
||||
NB! for loops are special as the local block may depend on variables evaluated by the
|
||||
for loop parameters. The for loop code will handle this specially.
|
||||
*/
|
||||
void LocalScope::apply(Context &ctx) const
|
||||
{
|
||||
BOOST_FOREACH(const Assignment &ass, this->assignments) {
|
||||
ctx.set_variable(ass.first, ass.second->evaluate(&ctx));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ public:
|
|||
std::string dump(const std::string &indent) const;
|
||||
std::vector<class AbstractNode*> instantiateChildren(const class Context *evalctx) const;
|
||||
void addChild(ModuleInstantiation *ch);
|
||||
void apply(Context &ctx) const;
|
||||
|
||||
AssignmentList assignments;
|
||||
ModuleInstantiationList children;
|
||||
|
|
|
@ -195,7 +195,7 @@ AbstractNode *Module::instantiate(const Context *ctx, const ModuleInstantiation
|
|||
|
||||
// At this point we know that nobody will modify the dependencies of the local scope
|
||||
// passed to this instance, so we can populate the context
|
||||
evalctx->applyScope();
|
||||
inst->scope.apply(*evalctx);
|
||||
|
||||
ModuleContext c(ctx, evalctx);
|
||||
// set $children first since we might have variables depending on it
|
||||
|
|
|
@ -58,7 +58,7 @@ AbstractNode *OffsetModule::instantiate(const Context *ctx, const ModuleInstanti
|
|||
|
||||
Context c(ctx);
|
||||
c.setVariables(args, evalctx);
|
||||
evalctx->applyScope();
|
||||
inst->scope.apply(*evalctx);
|
||||
|
||||
node->fn = c.lookup_variable("$fn").toDouble();
|
||||
node->fs = c.lookup_variable("$fs").toDouble();
|
||||
|
|
|
@ -53,7 +53,7 @@ AbstractNode *ProjectionModule::instantiate(const Context *ctx, const ModuleInst
|
|||
|
||||
Context c(ctx);
|
||||
c.setVariables(args, evalctx);
|
||||
evalctx->applyScope();
|
||||
inst->scope.apply(*evalctx);
|
||||
|
||||
Value convexity = c.lookup_variable("convexity", true);
|
||||
Value cut = c.lookup_variable("cut", true);
|
||||
|
|
|
@ -50,7 +50,7 @@ AbstractNode *RenderModule::instantiate(const Context *ctx, const ModuleInstanti
|
|||
|
||||
Context c(ctx);
|
||||
c.setVariables(args, evalctx);
|
||||
evalctx->applyScope();
|
||||
inst->scope.apply(*evalctx);
|
||||
|
||||
Value v = c.lookup_variable("convexity");
|
||||
if (v.type() == Value::NUMBER)
|
||||
|
|
|
@ -56,7 +56,7 @@ AbstractNode *RotateExtrudeModule::instantiate(const Context *ctx, const ModuleI
|
|||
|
||||
Context c(ctx);
|
||||
c.setVariables(args, evalctx);
|
||||
evalctx->applyScope();
|
||||
inst->scope.apply(*evalctx);
|
||||
|
||||
node->fn = c.lookup_variable("$fn").toDouble();
|
||||
node->fs = c.lookup_variable("$fs").toDouble();
|
||||
|
|
|
@ -83,7 +83,7 @@ AbstractNode *TransformModule::instantiate(const Context *ctx, const ModuleInsta
|
|||
|
||||
Context c(ctx);
|
||||
c.setVariables(args, evalctx);
|
||||
evalctx->applyScope();
|
||||
inst->scope.apply(*evalctx);
|
||||
|
||||
if (this->type == SCALE)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue