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); }
Node* ScaleModule::evaluate(Context* ctx) { Point size; VectorValue* sizeVal=dynamic_cast<VectorValue*>(getParameterArgument(ctx,0)); if(sizeVal) size=sizeVal->getPoint(); Point ref; VectorValue* refVal=dynamic_cast<VectorValue*>(getParameterArgument(ctx,1)); if(refVal) ref=refVal->getPoint(); double x=0,y=0,z=0; size.getXYZ(x,y,z); double a=0,b=0,c=0; ref.getXYZ(a,b,c); //Derived reference translation using //http://tinyurl.com/3zhnpkw double m[16] = { x,0,0,0, 0,y,0,0, 0,0,z,0, a-(a*x),b-(b*x),c-(c*x),1 }; TransformationNode* n=new TransformationNode(); for(int i=0; i<16; i++) n->matrix[i]=m[i]; n->setChildren(ctx->getInputNodes()); return n; }
Node* TextModule::evaluate(const Context& ctx) const { auto* textVal=dynamic_cast<TextValue*>(getParameterArgument(ctx,0)); if(!textVal) return nullptr; QString family; auto* fontVal=dynamic_cast<TextValue*>(getParameterArgument(ctx,1)); if(fontVal) family=fontVal->getValueString(); int size=12; auto* sizeVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,2)); if(sizeVal) size=sizeVal->toInteger(); QPathTextBuilder tb(reporter); tb.setText(textVal->getValueString()); tb.setFamily(family); tb.setSize(size); auto* pn=new PrimitiveNode(reporter); Primitive* p=tb.buildPrimitive(); p->setType(Primitive::Surface); p->setSanitized(false); pn->setPrimitive(p); pn->setChildren(ctx.getInputNodes()); return pn; }
Value* AngFunction::evaluate(Context* ctx) { VectorValue* vecVal1=dynamic_cast<VectorValue*>(ctx->getArgument(0,"v1")); VectorValue* vecVal2=dynamic_cast<VectorValue*>(ctx->getArgument(1,"v2")); if(vecVal1&&vecVal2) { // a = |v1|*|v2| + v1 . v2 Value* norm=Value::operation(vecVal1,Expression::Length,vecVal2); Value* dot=Value::operation(vecVal1,Expression::DotProduct,vecVal2); Value* angle=Value::operation(norm,Expression::Add,dot); // [x,y,z] = v1 x v2 Value* cross=Value::operation(vecVal1,Expression::CrossProduct,vecVal2); VectorValue* axis=dynamic_cast<VectorValue*>(cross); //Renormalise the quaternion Value* q=new ComplexValue(angle,axis->getChildren()); Value* l=Value::operation(q,Expression::Length); return Value::operation(q,Expression::Divide,l); } decimal a=0.0; decimal x=0.0,y=0.0,z=0.0; NumberValue* numVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,0)); if(numVal) { a=numVal->getNumber(); VectorValue* vecVal=dynamic_cast<VectorValue*>(getParameterArgument(ctx,1)); if(vecVal) { Value* n=Value::operation(vecVal,Expression::Length); Value* u=Value::operation(vecVal,Expression::Divide,n); VectorValue* unitVec=dynamic_cast<VectorValue*>(u); if(unitVec) { Point p=unitVec->getPoint(); p.getXYZ(x,y,z); } } else { // Assume rotation around z axis when no axis given return getResult(a,0.0,0.0,1.0); } } else { NumberValue* xVal=dynamic_cast<NumberValue*>(ctx->getArgument(0,"x")); if(xVal) { a=xVal->getNumber(); return getResult(a,1.0,0.0,0.0); } NumberValue* yVal=dynamic_cast<NumberValue*>(ctx->getArgument(0,"y")); if(yVal) { a=yVal->getNumber(); return getResult(a,0.0,1.0,0.0); } NumberValue* zVal=dynamic_cast<NumberValue*>(ctx->getArgument(0,"z")); if(zVal) { a=zVal->getNumber(); return getResult(a,0.0,0.0,1.0); } } return getResult(a,x,y,z); }
Value* RandFunction::evaluate(const Context& ctx) const { decimal min=0; auto* minVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,0)); if(minVal) min=minVal->getNumber(); decimal max=0; auto* maxVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,1)); if(maxVal) max=maxVal->getNumber(); int count=1; auto* countVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,2)); if(countVal) count=countVal->toInteger(); auto* seedVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,3)); int seed=time(nullptr); if(seedVal) seed=seedVal->toInteger(); r_rand_seed(seed); QList<Value*> results; for(auto i=0; i<count; ++i) results.append(new NumberValue(r_rand(min,max))); return new VectorValue(results); }
Value* RandFunction::evaluate(Context* ctx) { decimal min=0; NumberValue* minVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,0)); if(minVal) min=minVal->getNumber(); decimal max=0; NumberValue* maxVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,1)); if(maxVal) max=maxVal->getNumber(); decimal count=1; NumberValue* countVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,2)); if(countVal) count=countVal->getNumber(); NumberValue* seedVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,3)); if(seedVal) srand((unsigned int)seedVal->getNumber()); else srand((unsigned int)time(0)); QList<Value*> results; for(int i=0; i<count; ++i) results.append(new NumberValue(frand(min,max))); return new VectorValue(results); }
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* Atan2Function::evaluate(Context* ctx) { NumberValue* yVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,0)); NumberValue* xVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,1)); if(yVal&&xVal) { double y=yVal->getNumber(); double x=xVal->getNumber(); return new NumberValue(atan2(y,x)); } return new Value(); }
Value* LengthFunction::evaluate(Context* ctx) { VectorValue* vecVal=dynamic_cast<VectorValue*>(getParameterArgument(ctx,0)); if(vecVal) { return new NumberValue(vecVal->getChildren().count()); } TextValue* txtVal=dynamic_cast<TextValue*>(getParameterArgument(ctx,0)); if(txtVal) { return new NumberValue(txtVal->getValueString().length()); } return new Value(); }
Node* MirrorModule::evaluate(Context* ctx) { Point vec; VectorValue* vecVal=dynamic_cast<VectorValue*>(getParameterArgument(ctx,0)); if(vecVal) vec=vecVal->getPoint(); decimal x=0,y=0,z=0; vec.getXYZ(x,y,z); decimal mag = sqrt(x*x + y*y + z*z); decimal u = x/mag; decimal v = y/mag; decimal w = z/mag; decimal m[16] = { 1-2*u*u,-2*v*u,-2*w*u,0, -2*u*v,1-2*v*v,-2*w*v,0, -2*u*w,-2*v*w,1-2*w*w,0, 0, 0, 0,1 }; TransformationNode* n=new TransformationNode(); for(int i=0; i<16; i++) n->matrix[i]=m[i]; n->setChildren(ctx->getInputNodes()); return n; }
Node* RotateExtrudeModule::evaluate(const Context& ctx) const { decimal angle=360.0; auto* angleVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,0)); if(angleVal) angle=angleVal->getNumber(); bool compatible=true; Point axis(0,0,1); auto* vecVal=dynamic_cast<VectorValue*>(getParameterArgument(ctx,1)); if(vecVal) { axis=vecVal->getPoint(); compatible=false; } decimal radius=0.0; auto* radiusVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,2)); if(radiusVal) radius=radiusVal->getNumber(); decimal height=0.0; auto* heightVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,3)); if(heightVal) height=heightVal->getNumber(); auto* n=new RotateExtrudeNode(); n->setSweep(angle); n->setAxis(axis); n->setRadius(radius); n->setHeight(height); Fragment* fg = Fragment::createFragment(ctx); n->setFragments(fg); if(compatible) { //if no axis is given we fall into legacy compatibility mode auto* Rx90=new TransformMatrix(1,0,0,0,0,0,-1,0,0,1,0,0,0,0,0,1); auto* t=new TransformationNode(); t->setMatrix(Rx90); t->setChildren(ctx.getInputNodes()); n->addChild(t); } else { n->setChildren(ctx.getInputNodes()); } return n; }
Node* ImportModule::evaluate(const Context& ctx) const { auto* fileVal = dynamic_cast<TextValue*>(getParameterArgument(ctx,0)); if(fileVal) return new ImportNode(fileVal->getValueString()); return new ImportNode(import); }
Node* VolumesModule::evaluate(Context* ctx) { bool mass=false; BooleanValue* massVal=dynamic_cast<BooleanValue*>(getParameterArgument(ctx,0)); if(massVal) mass=massVal->isTrue(); NumberValue* precVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,1)); VolumesNode* n=new VolumesNode(); if(precVal) n->setPrecision(precVal->getNumber()); n->setCalcMass(mass); n->setChildren(ctx->getInputNodes()); return n; }
Value* AbsFunction::evaluate(const Context& ctx) const { auto* numVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,0)); if(numVal) { return Value::operation(numVal,Expression::Length); } return Value::undefined(); }
Value* IsListFunction::evaluate(Context* ctx) { VectorValue* vec=dynamic_cast<VectorValue*>(getParameterArgument(ctx,0)); if(vec) return new BooleanValue(true); return new BooleanValue(false); }
Node* SliceModule::evaluate(Context* ctx) { decimal h=0.0; NumberValue* height=dynamic_cast<NumberValue*>(getParameterArgument(ctx,0)); if(height) h=height->getNumber(); decimal t=0.0; NumberValue* thick=dynamic_cast<NumberValue*>(getParameterArgument(ctx,1)); if(thick) t=thick->getNumber(); SliceNode* d = new SliceNode(); d->setHeight(h); d->setThickness(t); d->setChildren(ctx->getInputNodes()); return d; }
Node* ResizeModule::evaluate(const Context& ctx) const { Point size(0,0,0); auto* sizeVal=dynamic_cast<VectorValue*>(getParameterArgument(ctx,0)); if(sizeVal) size=sizeVal->getPoint(); bool autoSize=false; auto* autoSizeVal=dynamic_cast<BooleanValue*>(getParameterArgument(ctx,1)); if(autoSizeVal) autoSize=autoSizeVal->isTrue(); auto* n=new ResizeNode(); n->setSize(size); n->setChildren(ctx.getInputNodes()); n->setAutoSize(autoSize); return n; }
Node* ResizeModule::evaluate(Context* ctx) { Point size; VectorValue* sizeVal=dynamic_cast<VectorValue*>(getParameterArgument(ctx,0)); if(sizeVal) size=sizeVal->getPoint(); bool autoSize=true; BooleanValue* autoSizeVal=dynamic_cast<BooleanValue*>(getParameterArgument(ctx,1)); if(autoSizeVal) autoSize=autoSizeVal->isTrue(); ResizeNode* n=new ResizeNode(); n->setSize(size); n->setChildren(ctx->getInputNodes()); n->setAutoSize(autoSize); return n; }
Value* CeilFunction::evaluate(Context* ctx) { NumberValue* numVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,0)); if(numVal) { decimal num=numVal->getNumber(); return new NumberValue(r_ceil(num)); } return Value::undefined(); }
Value* CeilFunction::evaluate(Context* ctx) { NumberValue* numVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,0)); if(numVal) { double num=numVal->getNumber(); return new NumberValue(ceil(num)); } return new Value(); }
Value* SignFunction::evaluate(Context* ctx) { NumberValue* numVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,0)); if(numVal) { decimal num=numVal->getNumber(); return new NumberValue(sign(num)); } return new Value(); }
Value* AsinFunction::evaluate(const Context& ctx) const { auto* numVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,0)); if(numVal) { decimal num=numVal->getNumber(); return new NumberValue(r_asin_deg(num)); } return Value::undefined(); }
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; }
Node* RadialsModule::evaluate(Context* ctx) { NumberValue* precVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,0)); RadialsNode* n=new RadialsNode(); if(precVal) n->setPrecision(precVal->getNumber()); n->setChildren(ctx->getInputNodes()); return n; }
Node* PointModule::evaluate(Context* ctx) { VectorValue* location=dynamic_cast<VectorValue*>(getParameterArgument(ctx,0)); PointNode* p=new PointNode(); Point pt; if(location) pt = location->getPoint(); p->setPoint(pt); return p; }
Node* SubDivisionModule::evaluate(Context* ctx) { int level=0; NumberValue* levelVal=dynamic_cast<NumberValue*>(getParameterArgument(ctx,0)); if(levelVal) level=int(levelVal->getNumber()); SubDivisionNode* d = new SubDivisionNode(); d->setChildren(ctx->getInputNodes()); d->setLevel(level); return d; }
Node* PolylineModule::evaluate(Context* ctx) { VectorValue* points=dynamic_cast<VectorValue*>(getParameterArgument(ctx,0)); PolylineNode* p=new PolylineNode(); Polygon polyline; QList<Value*> children = points->getChildren(); foreach(Value* point, children) { VectorValue* pointVec=dynamic_cast<VectorValue*>(point); Point pt = pointVec->getPoint(); polyline.append(pt); }
Node* SquareModule::evaluate(const Context& ctx) const { Value* sizeVal=getParameterArgument(ctx,0); Value* centerVal=getParameterArgument(ctx,1); bool center=false; if(centerVal) center = centerVal->isTrue(); decimal x=1.0,y=1.0; if(sizeVal) { VectorValue* size=sizeVal->toVector(2); Point pt = size->getPoint(); x=pt.x(); y=pt.y(); } auto* pn=new PrimitiveNode(reporter); Primitive* p=pn->createPrimitive(); pn->setChildren(ctx.getInputNodes()); Polygon* pg=p->createPolygon(); p->createVertex(Point(0, 0, 0)); p->createVertex(Point(x, 0, 0)); p->createVertex(Point(x, y, 0)); p->createVertex(Point(0, y, 0)); pg->append(0); pg->append(1); pg->append(2); pg->append(3); if(center) { auto* an=new AlignNode(); an->setCenter(true); an->addChild(pn); return an; } return pn; }
Node* SquareModule::evaluate(Context* ctx) { Value* sizeVal=getParameterArgument(ctx,0); Value* centerVal=getParameterArgument(ctx,1); decimal center=false; if(centerVal) center = centerVal->isTrue(); decimal x=1.0,y=1.0; if(sizeVal) { VectorValue* size=sizeVal->toVector(2); Point p = size->getPoint(); p.getXY(x,y); } PrimitiveNode* p=new PrimitiveNode(); decimal x1, x2, y1, y2; x1 = y1 = 0; x2 = x; y2 = y; p->createPolygon(); p->appendVertex(x1, y1, 0); p->appendVertex(x2, y1, 0); p->appendVertex(x2, y2, 0); p->appendVertex(x1, y2, 0); if(center) { AlignNode* n=new AlignNode(); n->setCenter(true); n->addChild(p); return n; } return p; }
Node* PolygonModule::evaluate(Context* ctx) { VectorValue* pointsVec=dynamic_cast<VectorValue*>(getParameterArgument(ctx,0)); VectorValue* linesVec=dynamic_cast<VectorValue*>(ctx->getArgumentDeprecated(1,"lines","paths")); PrimitiveNode* p=new PrimitiveNode(); if(!pointsVec) return p; QList<Value*> points=pointsVec->getChildren(); foreach(Value* point, points) { VectorValue* pointVec=dynamic_cast<VectorValue*>(point); if(pointVec) { Point pt = pointVec->getPoint(); p->createVertex(pt); } }