void NumberValue::verifyUnits(const NumberValue& n) { if (type == Value::DIMENSION && n.type == Value::DIMENSION && getUnit().compare(n.getUnit()) != 0) { setValue(convert(n.getUnit())); setUnit(n.getUnit()); } }
Value* Color::substract(Value* v) { Color* c; NumberValue* n; if (v->type == COLOR) { c = static_cast<Color*>(v); color[RGB_RED] = color[RGB_RED] > c->getRed() ? color[RGB_RED] - c->getRed() : 0; color[RGB_GREEN] = color[RGB_GREEN] > c->getGreen() ? color[RGB_GREEN] - c->getGreen() : 0; color[RGB_BLUE] = color[RGB_BLUE] > c->getBlue() ? color[RGB_BLUE] - c->getBlue() : 0; } else if (v->type == Value::NUMBER || v->type == Value::PERCENTAGE || v->type == Value::DIMENSION) { n = static_cast<NumberValue*>(v); color[RGB_RED] -= n->getValue(); color[RGB_GREEN] -= n->getValue(); color[RGB_BLUE] -= n->getValue(); } else { throw new ValueException("You can only substract a color or \ a number from a color."); } valueChanged = true; return this; }
Value* NumberValue::tan(const vector<const Value*> &args) { if (args[0]->type != Value::NUMBER && args[0]->type != Value::DIMENSION) { throw new ValueException("tan() only works on numbers " "or dimensions", *args[0]->getTokens()); } NumberValue* n = new NumberValue(*(const NumberValue*)args[0]); double val = n->getValue(); std::string unit; if (n->type == Value::DIMENSION) { unit = n->getUnit(); if(unit.compare("rad") != 0 && unit.compare("deg") != 0 && unit.compare("grad") != 0 && unit.compare("turn") != 0) { throw new ValueException("ta() requires rad, deg, " "grad or turn units.", *args[0]->getTokens()); } val = UnitValue::angleToRad(val, unit); } n->setValue(std::tan(val)); n->type = Value::NUMBER; n->setUnit(""); return n; }
Node* CylinderSurfaceModule::evaluate(Context* ctx) { NumberValue* heightValue = dynamic_cast<NumberValue*>(getParameterArgument(ctx,0)); decimal h=1.0; if(heightValue) h=heightValue->getNumber(); NumberValue* rValue = dynamic_cast<NumberValue*>(getParameterArgument(ctx,1)); decimal r=1.0; if(rValue) r=rValue->getNumber(); Value* centerValue=getParameterArgument(ctx,2); bool center=false; if(centerValue) center=centerValue->isTrue(); decimal z1,z2; z1 = 0.0; z2 = h; Fragment* fg = Fragment::createFragment(ctx); int f = fg->getFragments(r); delete fg; QList<Point> c1=getCircle(r,f,z1); QList<Point> c2=getCircle(r,f,z2); PrimitiveNode* p=new PrimitiveNode(reporter); p->setChildren(ctx->getInputNodes()); foreach(Point pt,c1) { p->createVertex(pt); }
Value* Color::multiply(Value* v) { Color* c; NumberValue* n; int result; if (v->type == COLOR) { c = static_cast<Color*>(v); result = color[RGB_RED] * c->getRed(); color[RGB_RED] = max(min(result, 255), 0); result = color[RGB_GREEN] * c->getGreen(); color[RGB_GREEN] = max(min(result, 255), 0); result = color[RGB_BLUE] * c->getBlue(); color[RGB_BLUE] = max(min(result, 255), 0); } else if (v->type == Value::NUMBER || v->type == Value::PERCENTAGE || v->type == Value::DIMENSION) { n = static_cast<NumberValue*>(v); color[RGB_RED] *= n->getValue(); color[RGB_GREEN] *= n->getValue(); color[RGB_BLUE] *= n->getValue(); } else { throw new ValueException("You can only multiply a color by a \ color or a number."); } valueChanged = true; return this; }
Value* Color::add(Value* v) { Color* c; NumberValue* n; StringValue* s; string* str; if (v->type == COLOR) { c = static_cast<Color*>(v); color[RGB_RED] += c->getRed(); color[RGB_GREEN] += c->getGreen(); color[RGB_BLUE] += c->getBlue(); } else if (v->type == NUMBER || v->type == PERCENTAGE || v->type == DIMENSION) { n = static_cast<NumberValue*>(v); color[RGB_RED] += n->getValue(); color[RGB_GREEN] += n->getValue(); color[RGB_BLUE] += n->getValue(); } else if(v->type == STRING) { str = this->getTokens()->toString(); s = new StringValue(new Token(*str, Token::STRING), ((StringValue*)v)->getQuotes()); s->add(v); delete str; return s; } valueChanged = true; return this; }
Value* NumberValue::atan(const vector<const Value*> &args) { NumberValue* n = new NumberValue(*(const NumberValue*)args[0]); n->setValue(std::atan(n->getValue())); n->setUnit("rad"); n->type = Value::DIMENSION; return n; }
void NumberValue<T, TypeID>::setVal(AbstractValue* val) { if ( this->type() != val->type() ) throw "Variable must be the same type"; NumberValue<T, TypeID>* numVal = dynamic_cast<NumberValue<T, TypeID>*>(val); setValue(numVal->value()); }
Value* NumberValue::abs(const vector<const Value*> &args) { if (!NumberValue::isNumber(*args[0])) throw new ValueException("abs() only works on numeric " "values", *args[0]->getTokens()); NumberValue* n = new NumberValue(*(const NumberValue*)args[0]); n->setValue(fabs(n->getValue())); return n; }
boost::shared_ptr<AbstractValue> NumberValue<T, TypeID>::clone() { NumberValue<T, TypeID>* numVal = new NumberValue<T, TypeID>(); numVal->setValue(this->value()); boost::shared_ptr<AbstractValue> ptr(numVal); return ptr; }
Value* NumberValue::pow(const vector<const Value*> &args) { if (!NumberValue::isNumber(*args[0])) throw new ValueException("pow() only works on numeric values", *args[0]->getTokens()); NumberValue* n = new NumberValue(*(const NumberValue*)args[0]); double exp = ((const NumberValue*)args[1])->getValue(); n->setValue(std::pow(n->getValue(), exp)); return n; }
Value* NumberValue::mod(const vector<const Value*> &args) { if (!NumberValue::isNumber(*args[0]) || !NumberValue::isNumber(*args[1])) throw new ValueException("mod() only works on numeric values", *args[0]->getTokens()); NumberValue* n = new NumberValue(*(const NumberValue*)args[0]); double val2 = ((NumberValue*)args[1])->getValue(); n->setValue(std::fmod(n->getValue(), val2)); return n; }
Value* NumberValue::floor(const vector<const Value*> &args) { NumberValue *n; if (!NumberValue::isNumber(*args[0])) throw new ValueException("floor() only works on numeric " "values", *args[0]->getTokens()); n = new NumberValue(*static_cast<const NumberValue*>(args[0])); double val = n->getValue(); n->setValue(std::floor(val)); return n; }
// DIMENSION unit(DIMENSION, UNIT) Value* NumberValue::unit(const vector<const Value*> &arguments) { NumberValue* ret; if (arguments[0]->type == Value::NUMBER || arguments[0]->type == Value::DIMENSION) { ret = new NumberValue(((const NumberValue*)arguments[0])->getValue()); if (arguments.size() > 1) { ret->setUnit(((const UnitValue*)arguments[1])->getUnit()); } else ret->setUnit(""); return ret; } else throw new ValueException("argument 1 has to be a number " "or dimension", *arguments[0]->getTokens()); }
Value* NumberValue::round(const vector<const Value*> &args) { if (!NumberValue::isNumber(*args[0])) throw new ValueException("round() only works on numeric " "values", *args[0]->getTokens()); NumberValue* n = new NumberValue(*(const NumberValue*)args[0]); double val = n->getValue(); double decimalplaces = 0; if (args.size() > 1) decimalplaces = ((const NumberValue*)args[1])->getValue(); val = val * std::pow(10, decimalplaces); val = std::floor(val + 0.5); val = val / std::pow(10, decimalplaces); n->setValue(val); return n; }
void NumberValue::setType(const NumberValue &n) { type = n.type; if (n.type == DIMENSION) setUnit(n.getUnit()); else if (n.type == PERCENTAGE) tokens.front().type = Token::PERCENTAGE; else if (n.type == NUMBER) { setUnit(""); } }
Node* CylinderSurfaceModule::evaluate(Context* ctx) { NumberValue* heightValue = dynamic_cast<NumberValue*>(getParameterArgument(ctx,0)); double h=1.0; if(heightValue) h=heightValue->getNumber(); NumberValue* rValue = dynamic_cast<NumberValue*>(getParameterArgument(ctx,1)); double r=1.0; if(rValue) r=rValue->getNumber(); Value* centerValue=getParameterArgument(ctx,2); bool center=false; if(centerValue) center=centerValue->isTrue(); double z1,z2; if(center) { z1 = -h/2; z2 = +h/2; } else { z1 = 0.0; z2 = h; } int f = getFragments(r,ctx); Polygon c1 = getCircle(r,f,z1); Polygon c2 = getCircle(r,f,z2); PrimitiveNode* p = new PrimitiveNode(); for(int i=0; i<f; i++) { int j=(i+1)%f; p->createPolygon(); p->appendVertex(c1.at(i)); p->appendVertex(c2.at(i)); p->appendVertex(c2.at(j)); p->appendVertex(c1.at(j)); } return p; }
void Worker::generation() { Script* s=parse("reprap.rcam",NULL,true); TreeEvaluator* e = new TreeEvaluator(reporter); decimal height=getBoundsHeight(); QList<Argument*> args=getArgs(height); Callback* c = addCallback("layers",s,args); s->accept(*e); NumberValue* v = dynamic_cast<NumberValue*>(c->getResult()); if(v) { reporter->reportMessage(tr("Layers: %1").arg(v->getValueString())); int itterations=v->getNumber(); Instance* m=addProductInstance("manufacture",s); for(int i=0; i<=itterations; i++) { if(i>0) { e = new TreeEvaluator(reporter); } reporter->reportMessage(tr("Manufacturing layer: %1").arg(i)); QList<Argument*> args=getArgs(i); m->setArguments(args); s->accept(*e); Node* n=e->getRootNode(); NodeEvaluator* ne = new NodeEvaluator(reporter); n->accept(*ne); delete n; primitive=ne->getResult(); delete ne; update(); } } delete e; delete s; }
Value* NumberValue::add(const Value &v) const { const NumberValue* n; const StringValue* s; NumberValue* nret; StringValue* sret; if (isNumber(v)) { n = static_cast<const NumberValue*>(&v); nret = new NumberValue(getValue()); if (type == NUMBER) nret->setType(*n); else { nret->setType(*this); nret->verifyUnits(*n); } nret->setValue(nret->getValue() + n->getValue()); return nret; } else if (v.type == COLOR) { return static_cast<const Color*>(&v)->add(*this); } else if (v.type == STRING) { s = static_cast<const StringValue*>(&v); sret = new StringValue(*this, s->getQuotes()); sret->append(v); return sret; } else { throw new ValueException("Unsupported type.", *this->getTokens()); } }
Value* NumberValue::multiply(const Value &v) const { const NumberValue* n; NumberValue* ret; if (isNumber(v)) { n = static_cast<const NumberValue*>(&v); ret = new NumberValue(getValue()); if (type == NUMBER) ret->setType(*n); else { ret->setType(*this); ret->verifyUnits(*n); } ret->setValue(ret->getValue() * n->getValue()); return ret; } else if (v.type == COLOR) { return static_cast<const Color*>(&v)->multiply(*this); } else if(v.type == STRING) { return static_cast<const StringValue*>(&v)->multiply(*this); } else { throw new ValueException("Unsupported type.", *this->getTokens()); } }
Value* Color::divide(Value* v) { Color* c; NumberValue* n; if (v->type == COLOR) { c = static_cast<Color*>(v); color[RGB_RED] /= c->getRed(); color[RGB_GREEN] /= c->getGreen(); color[RGB_BLUE] /= c->getBlue(); } else if (v->type == Value::NUMBER || v->type == Value::PERCENTAGE || v->type == Value::DIMENSION){ n = static_cast<NumberValue*>(v); color[RGB_RED] /= n->getValue(); color[RGB_GREEN] /= n->getValue(); color[RGB_BLUE] /= n->getValue(); } else { throw new ValueException("You can only divide a color by a \ color or a number."); } valueChanged = true; return this; }
Value* NumberValue::convert(const vector<const Value*> &args) { if (!NumberValue::isNumber(*args[0])) throw new ValueException("convert() only works on numeric values", *args[0]->getTokens()); if (args[1]->type != Value::STRING && args[1]->type != Value::UNIT) { throw new ValueException("convert() requires a unit \ (or unit as a string)", *args[1]->getTokens()); } NumberValue* n = new NumberValue(*(const NumberValue*)args[0]); std::string unit; if (args[1]->type == Value::STRING) unit = ((const StringValue*)args[1])->getString(); else unit.append(((const UnitValue*)args[1])->getUnit()); n->setValue(n->convert(unit)); n->setUnit(unit); return n; }
Node* CylinderModule::evaluate(Context* ctx) { NumberValue* heightValue = dynamic_cast<NumberValue*>(getParameterArgument(ctx,0)); decimal h=1.0; if(heightValue) h=heightValue->getNumber(); NumberValue* r1Value = dynamic_cast<NumberValue*>(ctx->getArgument(1,"radius1")); NumberValue* r2Value = dynamic_cast<NumberValue*>(ctx->getArgument(2,"radius2")); BooleanValue* centerValue; decimal r1=1.0,r2=1.0; if(!r1Value) { NumberValue* rValue = dynamic_cast<NumberValue*>(getParameterArgument(ctx,1)); centerValue = dynamic_cast<BooleanValue*>(getParameterArgument(ctx,2)); if(rValue) { r1=r2=rValue->getNumber(); } else { NumberValue* dValue = dynamic_cast<NumberValue*>(ctx->getArgument(1,"diameter")); if(dValue) r1=r2=(dValue->getNumber()/2.0); } } else { if(r1Value) r1=r1Value->getNumber(); if(r2Value) r2=r2Value->getNumber(); else r2=r1; centerValue = dynamic_cast<BooleanValue*>(ctx->getArgument(3,"center")); } bool center = false; if(centerValue) center=centerValue->isTrue(); decimal z1,z2; z1 = 0.0; z2 = h; decimal r=fmax(r1,r2); Fragment fg=getSpecialVariables(ctx); int f = fg.getFragments(r); QList<Point> c1=getCircle(r1,f,z1); QList<Point> c2=getCircle(r2,f,z2); PrimitiveNode* p = new PrimitiveNode(); int n=0; Polygon* pg; if(r1>0) { pg=p->createPolygon(); foreach(Point pt,c1) { p->createVertex(pt); pg->append(n++); }
Value* NumberValue::divide(const Value &v) const { const NumberValue* n; NumberValue* ret; if (isNumber(v)) { n = static_cast<const NumberValue*>(&v); ret = new NumberValue(getValue()); if (type == NUMBER) ret->setType(*n); else { ret->setType(*this); ret->verifyUnits(*n); } ret->setValue(ret->getValue() / n->getValue()); return ret; } else throw new ValueException("You can only divide a number " "by a *number*.", *this->getTokens()); }
Value* NumberValue::substract(const Value &v) const { const NumberValue* n; NumberValue* ret; if (isNumber(v)) { n = static_cast<const NumberValue*>(&v); ret = new NumberValue(getValue()); if (type == NUMBER) ret->setType(*n); else { ret->setType(*this); ret->verifyUnits(*n); } ret->setValue(ret->getValue() - n->getValue()); return ret; } else throw new ValueException("You can only substract a " "*number* from a number.", *this->getTokens()); }
Node* SphereModule::evaluate(Context* ctx) { NumberValue* rValue=dynamic_cast<NumberValue*>(getParameterArgument(ctx,0)); Value* centerValue=getParameterArgument(ctx,1); bool center=true; if(centerValue) center=centerValue->isTrue(); double r=1.0; if(rValue) { r=rValue->getNumber(); } else { NumberValue* dValue = dynamic_cast<NumberValue*>(ctx->getArgument(0,"diameter")); if(dValue) r=(dValue->getNumber()/2.0); } int f = getFragments(r,ctx); int ringCount=f/2; QList<Polygon> rings; for(int i=0; i<ringCount; i++) { double phi = (M_PI*(i+0.5)) / ringCount; double r2 = r*sin(phi); double z = r*cos(phi)+!center*r; Polygon c = getCircle(r2,f,z); rings.append(c); } PrimitiveNode* p = new PrimitiveNode(); p->createPolygon(); for(int i=0; i<f; i++) p->appendVertex(rings.at(0).at(i)); for(int i = 0; i < ringCount-1; i++) { Polygon r1 = rings.at(i); Polygon r2 = rings.at(i+1); int r1i = 0, r2i = 0; while(r1i < f || r2i < f) { if(r1i >= f) goto next_r2; if(r2i >= f) goto next_r1; if((double)r1i / f < (double)r2i / f) { next_r1: p->createPolygon(); int r1j = (r1i+1) % f; p->prependVertex(r1.at(r1i)); p->prependVertex(r1.at(r1j)); p->prependVertex(r2.at(r2i % f)); r1i++; } else { next_r2: p->createPolygon(); int r2j = (r2i+1) % f; p->appendVertex(r2.at(r2i)); p->appendVertex(r2.at(r2j)); p->appendVertex(r1.at(r1i % f)); r2i++; } } } p->createPolygon(); for(int i=0; i<f; i++) p->prependVertex(rings.at(ringCount-1).at(i)); return p; }
Node* ConeModule::evaluate(Context* ctx) { NumberValue* heightValue = dynamic_cast<NumberValue*>(getParameterArgument(ctx,0)); NumberValue* r1Value = dynamic_cast<NumberValue*>(getParameterArgument(ctx,1)); NumberValue* r2Value = dynamic_cast<NumberValue*>(getParameterArgument(ctx,2)); Value* centerValue = getParameterArgument(ctx,3); decimal h=1.0; if(heightValue) h=heightValue->getNumber(); decimal r1=0,r2=0; if(r1Value) r1=r1Value->getNumber(); if(r2Value) r2=r2Value->getNumber(); bool center = false; if(centerValue) center=centerValue->isTrue(); decimal z1,z2; z1 = 0.0; z2 = h; Fragment fg=getSpecialVariables(ctx); decimal r=fmax(r1,r2); int f = fg.getFragments(r); Polygon* p1 = getCircle(r1,f,z1); Polygon* p2 = getCircle(r2,f,z2); QList<Point> c1=p1->getPoints(); QList<Point> c2=p2->getPoints(); PrimitiveNode* p = new PrimitiveNode(); if(r1 > 0) { p->createPolygon(); foreach(Point pt, c1) p->appendVertex(pt); } if(h==0.0) return p; for(int i=0; i<f; i++) { int j=(i+1)%f; if(r1 > 0) { p->createPolygon(); p->appendVertex(c1.at(i)); p->appendVertex(c2.at(i)); p->appendVertex(c1.at(j)); } if(r2 > 0) { p->createPolygon(); p->appendVertex(c2.at(i)); p->appendVertex(c2.at(j)); p->appendVertex(c1.at(j)); } } if(r2 > 0) { p->createPolygon(); foreach(Point pt,c2) p->prependVertex(pt); } if(center) { AlignNode* n=new AlignNode(); n->setCenter(true); n->addChild(p); return n; } return p; }
NumberValue::NumberValue(const NumberValue &n) { tokens.push_back(n.getTokens()->front()); this->type = n.type; }
Node* SphereModule::evaluate(Context* ctx) { NumberValue* rValue=dynamic_cast<NumberValue*>(getParameterArgument(ctx,0)); Value* centerValue=getParameterArgument(ctx,1); bool center=true; if(centerValue) center=centerValue->isTrue(); decimal r=0.0; if(rValue) { r=rValue->getNumber(); } else { NumberValue* dValue = dynamic_cast<NumberValue*>(ctx->getArgument(0,"diameter")); if(dValue) r=(dValue->getNumber()/2.0); } if(r==0.0) return new PointNode(); Fragment fg=getSpecialVariables(ctx); int f = fg.getFragments(r); int ringCount=f/2; decimal h=center?0.0:r; QList<Polygon> rings; for(int i=0; i<ringCount; i++) { decimal phi = (M_PI*(i+0.5)) / ringCount; decimal r2 = r*sin(phi); decimal z = r*cos(phi)+h; Polygon* c = getCircle(r2,f,z); rings.append(*c); } PrimitiveNode* p = new PrimitiveNode(); p->createPolygon(); Polygon top=rings.at(0); foreach(Point pt, top.getPoints()) p->appendVertex(pt); for(int i = 0; i < ringCount-1; i++) { QList<Point> r1 = rings.at(i).getPoints(); QList<Point> r2 = rings.at(i+1).getPoints(); int r1i = 0, r2i = 0; while(r1i < f || r2i < f) { if(r2i >= f||(decimal)r1i/f<(decimal)r2i/f) { p->createPolygon(); int r1j = (r1i+1) % f; p->prependVertex(r1.at(r1i)); p->prependVertex(r1.at(r1j)); p->prependVertex(r2.at(r2i % f)); r1i++; } else { p->createPolygon(); int r2j = (r2i+1) % f; p->appendVertex(r2.at(r2i)); p->appendVertex(r2.at(r2j)); p->appendVertex(r1.at(r1i % f)); r2i++; } } } p->createPolygon(); Polygon bottom=rings.at(ringCount-1); foreach(Point pt, bottom.getPoints()) p->prependVertex(pt); if(center) { AlignNode* n=new AlignNode(); n->setCenter(true); n->addChild(p); return n; } return p; }