diff --git a/cpp_frep/frep.cpp b/cpp_frep/frep.cpp
index 9d539fee851b4f208a93eb816d253f1d55057a5f..0a84ea10cc24624a70ea9ba01c5668867fecdb1c 100755
--- a/cpp_frep/frep.cpp
+++ b/cpp_frep/frep.cpp
@@ -1,6 +1,9 @@
 #include <iostream>
 #include <math.h>
 #include <vector>
+#include <sstream>      // std::ostringstream
+
+
 
 namespace cpp_frep {
     using scalar=float;
@@ -347,6 +350,19 @@ namespace cpp_frep {
                 return (weight*shape1->eval()+(1-weight)*shape2->eval());
             }
 
+            std::string to_string_with_precision(const scalar a_value, const int n = 3)
+            {
+                std::ostringstream out;
+                out.precision(n);
+                out << std::fixed << a_value;
+                return out.str();
+            }
+
+            std::string getPrintedName(){
+                std::string frepName=name+"("+shape1->getPrintedName()+","+shape2->getPrintedName()+","+ to_string_with_precision(weight,2) +")" ;
+                return frepName;
+            }
+
     };
     //..................................................................//
 
diff --git a/cpp_frep/frep_tree.cpp b/cpp_frep/frep_tree.cpp
index cb5f50e8c5075423dde68b6f70f31aea9ee0d4a3..3f3d56fa6c6b6bb8adfcd5212d6c4a92dfc00f41 100644
--- a/cpp_frep/frep_tree.cpp
+++ b/cpp_frep/frep_tree.cpp
@@ -16,18 +16,23 @@ namespace cpp_frep {
                 Y=0.0f;
             };
 
-            Frep_tree(std::vector<std::vector<scalar>>  genome_) {
+            Frep_tree(std::vector<std::vector<scalar>>  genome_,bool smooth) {
                 // inputs=inputs_;
                 genome=genome_;
                 X=0.0f;
                 Y=0.0f;
                 nodeLength;
                 addPrimitives();
-                parseTree();
+                if(!smooth){
+                    parseTree();
+                }else{
+                    parseTreeSmooth();
+                }
+                
                 
             };
 
-            void updateGenome(std::vector<std::vector<scalar>>  genome_){
+            void updateGenome(std::vector<std::vector<scalar>>  genome_,bool smooth_){
                 genome=genome_;
 
                 counterAdd          =0;
@@ -44,8 +49,12 @@ namespace cpp_frep {
                 counterRectangle    =0;
 
                 addPrimitives();
-                parseTree();
-
+                smooth=smooth_;
+                if(!smooth){
+                    parseTree();
+                }else{
+                    parseTreeSmooth();
+                }
                 
             }
 
@@ -81,6 +90,15 @@ namespace cpp_frep {
                 std::cout<<"\n";
             }
 
+            void parseTreeSmooth(){
+                printGenome();
+                // parsedTree=getNode(0);
+                parsedTree=morphNodes(0);
+                std::cout<<"\n";
+                parsedTree->printName();
+                std::cout<<"\n";
+            }
+
             Frep* getNode(int index){
 
                 int nodeIndex=(int)(genome[index][0]*nodeLength);
@@ -222,150 +240,153 @@ namespace cpp_frep {
                 nodeIndex2=nodeIndex1==nodeLength-1?10.0:nodeIndex1+1;
                 float weight=genome[index][0]*nodeLength-(float)nodeIndex1;
                 
-                static Morph f1;
+
+                int n=counterMorph;
+                ArrayMorph[n].weight=1.0f-weight;
                 std::cout<<"Morph(";
-                f1.setShape1(getNodeSharp( index ,nodeIndex1));
+                counterMorph++;
+                ArrayMorph[n].setShape1(getNodeSmooth( index ,nodeIndex1));
                 std::cout<<",";
-                f1.setShape2(getNodeSharp(index ,nodeIndex2));
-                std::cout<<")";
-                f1.weight=1.0f-weight;
-                return &f1;
+                ArrayMorph[n].setShape2(getNodeSmooth( index ,nodeIndex2));
+                std::cout<<","<<1.0f-weight<<")";
+                
+                return &ArrayMorph[n];
 
+                
             }
 
-            Frep* getNodeSharp(int index, int nodeIndex){
+            Frep* getNodeSmooth(int index, int nodeIndex){
 
                 int shape1Index,shape2Index,shapeIndex;
+                shape1Index=index+(int)ceilf(genome[index][1]* (maxLength-1-index));
+                shape2Index=index+(int)ceilf(genome[index][2]* (maxLength-1-index));
+                shapeIndex =index+(int)ceilf(genome[index][1]* (maxLength-1-index));
 
                 //0 add, 1 subtract, 2 intersect, 3 morph, 4 translate, 5 scale, 6 rotate, 7 linearArrayX, 8 linearArrayX, 9 polar array
                 //TODO: Add parameters
                 switch (nodeIndex)
                 {
                     case 0: {
-                        static Add f;
+                        // Add f;
+                        int n=counterAdd;
                         std::cout<<"Add(";
-                        shape1Index=index+(int)ceilf(genome[index][1]* (maxLength-1-index));
-                        f.setShape1(morphNodes(genome[index][1]));
+                        counterAdd++;
+                        ArrayAdd[n].setShape1(morphNodes(shape1Index));
                         std::cout<<",";
-                        shape2Index=index+(int)ceilf(genome[index][2]* (maxLength-1-index));
-                        f.setShape2(morphNodes(shape2Index));
+                        ArrayAdd[n].setShape2(morphNodes(shape2Index));
                         std::cout<<")";
-                        return &f;
-                        break;
+                        return &ArrayAdd[n];
                     }
                     case 1: {
-                        static Subtract f;
+
+                        // Subtract f;
+                        int n=counterSubtract;
                         std::cout<<"Subtract(";
-                        shape1Index=index+(int)ceilf(genome[index][1]* (maxLength-1-index));
-                        f.setShape1(morphNodes(shape1Index));
+                        counterSubtract++;
+                        ArraySubtract[n].setShape1(morphNodes(shape1Index));
                         std::cout<<",";
-                        shape2Index=index+(int)ceilf(genome[index][2]* (maxLength-1-index));
-                        f.setShape2(morphNodes(shape2Index));
+                        ArraySubtract[n].setShape2(morphNodes(shape2Index));
                         std::cout<<")";
-                        return &f;
-                        break;
+                        return &ArraySubtract[n];
                     }
                     case 2: {
-                        static Intersect f;
+                        // Intersect f;
+                        int n=counterIntersect;
                         std::cout<<"Intersect(";
-                        shape1Index=index+(int)ceilf(genome[index][1]* (maxLength-1-index));
-                        f.setShape1(morphNodes(shape1Index));
+                        counterIntersect++;
+                        ArrayIntersect[n].setShape1(morphNodes(shape1Index));
                         std::cout<<",";
-                        shape2Index=index+(int)ceilf(genome[index][2]* (maxLength-1-index));
-                        f.setShape2(morphNodes(shape2Index));
+                        ArrayIntersect[n].setShape2(morphNodes(shape2Index));
                         std::cout<<")";
-                        return &f;
-                        break;
+                        return &ArrayIntersect[n];
                     }
                     case 3: {
-                        static Morph f;
+                        // Morph f;
+                        int n=counterMorph;
                         std::cout<<"Morph(";
-                        shape1Index=index+(int)ceilf(genome[index][1]* (maxLength-1-index));
-                        f.setShape1(morphNodes(shape1Index));
+                        counterMorph++;
+                        ArrayMorph[n].setShape1(morphNodes(shape1Index));
                         std::cout<<",";
-                        shape2Index=index+(int)ceilf(genome[index][2]* (maxLength-1-index));
-                        f.setShape2(morphNodes(shape2Index));
+                        ArrayMorph[n].setShape2(morphNodes(shape2Index));
                         std::cout<<")";
-                        return &f;
-                        break;
+                        ArrayMorph[n].weight=0.5;
+                        return &ArrayMorph[n];
                     }
                     case 4: {
-                        static Translate f;
+                        // Translate f;
+                        int n=counterTranslate;
                         std::cout<<"Translate(";
-                        shapeIndex=index+(int)ceilf(genome[index][1]* (maxLength-1-index));
-                        f.setShape(morphNodes(shapeIndex));
+                        counterTranslate++;
+                        ArrayTranslate[n].setShape(morphNodes(shapeIndex));
                         std::cout<<")";
-                        return &f;
-                        break;
+                        return &ArrayTranslate[n];
                     }
                     case 5: {
-                        static Scale f;
+                        // Scale f;
+                        int n=counterScale;
                         std::cout<<"Scale(";
-                        shapeIndex=index+(int)ceilf(genome[index][1]* (maxLength-1-index));
-                        f.setShape(morphNodes(shapeIndex));
+                        counterScale++;
+                        ArrayScale[n].setShape(morphNodes(shapeIndex));
                         std::cout<<")";
-                        return &f;
-                        break;
+                        return &ArrayScale[n];
                     }
                     case 6: {
-                        static Rotate f;
+                        //Rotate f;
+                        int n=counterRotate;
                         std::cout<<"Rotate(";
-                        shapeIndex=index+(int)ceilf(genome[index][1]* (maxLength-1-index));
-                        f.setShape(morphNodes(shapeIndex));
+                        counterRotate++;
+                        ArrayRotate[n].setShape(morphNodes(shapeIndex));
                         std::cout<<")";
-                        return &f;
-                        break;
+                        return &ArrayRotate[n];
                     }
                     case 7: {
-                        static LinearArrayX f;
+                        // LinearArrayX f;
+                        int n=counterLinearArrayX;
                         std::cout<<"LinearArrayX(";
-                        shapeIndex=index+(int)ceilf(genome[index][1]* (maxLength-1-index));
-                        f.setShape(morphNodes(shapeIndex));
+                        counterLinearArrayX++;
+                        ArrayLinearArrayX[n].setShape(morphNodes(shapeIndex));
                         std::cout<<")";
-                        return &f;
-                        break;
+                        return &ArrayLinearArrayX[n];
                     }
                     case 8: {
-                        static LinearArrayY f;
+                        // LinearArrayY f;
+                        int n=counterLinearArrayY;
                         std::cout<<"LinearArrayY(";
-                        shapeIndex=index+(int)ceilf(genome[index][1]* (maxLength-1-index));
-                        f.setShape(morphNodes(shapeIndex));
+                        counterLinearArrayY++;
+                        ArrayLinearArrayY[n].setShape(morphNodes(shapeIndex));
                         std::cout<<")";
-                        return &f;
-                        break;
+                        return &ArrayLinearArrayY[n];
                     }
                     case 9: {
-                        static PolarArray f;
+                        // PolarArray f;
+                        int n=counterPolarArray;
                         std::cout<<"PolarArray(";
-                        shapeIndex=index+(int)ceilf(genome[index][1]* (maxLength-1-index));
-                        f.setShape(morphNodes(shapeIndex));
+                        counterPolarArray++;
+                        ArrayPolarArray[n].setShape(morphNodes(shapeIndex));
                         std::cout<<")";
-                        return &f;
-                        break;
+                        return &ArrayPolarArray[n];
                     }
                     case 10: {
-                        static Circle f(1.0f,0.0f,0.0f);
+                        // Circle f(1.0f,0.0f,0.0f);
+                        int n=counterCircle;
+                        counterCircle++;
                         std::cout<<"Circle";
-                        return &f;
-                        break;
+                        return &ArrayCircle[n];
                     }
                     case 11: {
-                        static Rectangle f(-1.0f,1.0f,-1.0f,1.0f);
+                        // Rectangle f(-1.0f,1.0f,-1.0f,1.0f);
+                        int n=counterRectangle;
+                        counterRectangle++;
                         std::cout<<"Rectangle";
-                        return &f;
-                        break;
+                        return &ArrayRectangle[n];
                     }
                     default: {
-                        static Rectangle f(-1.0f,1.0f,-1.0f,1.0f);
-                        std::cout<<"rectangle1";
-                        std::cout<<nodeIndex;
-                        return &f;
-                        break;
+                        int n=counterRectangle;
+                        counterRectangle++;
+                        std::cout<<"REECCC";
+                        return &ArrayRectangle[n];
                     }
                 }
-                // static Rectangle f1(-1.0f,1.0f,-1.0f,1.0f);
-                // std::cout<<"rectangle2";
-                // return &f1;
             }
 
             void setXY(scalar X_,scalar Y_){
@@ -406,13 +427,13 @@ namespace cpp_frep {
             Frep* parsedTree;
             scalar nodeLength=12.0f;
 
-            static const int storageSpace=5;
+            static const int storageSpace=20;
 
             Add           ArrayAdd          [storageSpace];
             Subtract      ArraySubtract     [storageSpace];
             Intersect     ArrayIntersect    [storageSpace];
             Scale         ArrayScale        [storageSpace]; 
-            Morph         ArrayMorph        [storageSpace];
+            Morph         ArrayMorph        [storageSpace*20];
             Translate     ArrayTranslate    [storageSpace];
             Rotate        ArrayRotate       [storageSpace];
             LinearArrayX  ArrayLinearArrayX [storageSpace];
@@ -435,6 +456,8 @@ namespace cpp_frep {
             int  counterRectangle    =0;
 
             int numPrimitives=2;
+
+            bool smooth=false;
         
     };
 }
\ No newline at end of file
diff --git a/cpp_frep/main.cpp b/cpp_frep/main.cpp
index 288b8f863ebfa8ae595c61542ac030eb15c3169d..0a0c364c3762f4da207a63f9f0afe7cd8b6213e0 100755
--- a/cpp_frep/main.cpp
+++ b/cpp_frep/main.cpp
@@ -11,6 +11,22 @@ using namespace cpp_frep;
 
 using scalar=float;
 //--------------------------------------------------------------------------------------------------
+std::vector<std::string> insert_newlines(const std::string &in, const size_t every_n){
+    std::vector<std::string> outStrings;
+    // out.reserve(in.size() + in.size() / every_n);
+    int count=0;
+    outStrings.push_back("");
+    for(std::string::size_type i = 0; i < in.size(); i++) {
+        if (!(i % every_n) && i) {
+            // out.push_back('\n');
+            outStrings.push_back("");
+            count++;
+        }
+        outStrings[count].push_back(in[i]);
+    }
+    return outStrings;
+}
+
 void drawFrep(Frep* frep,scalar minX,scalar maxX,scalar minY,scalar maxY,scalar dx,scalar dy){
     for(scalar i=minX;i<maxX;i+=dx){
         for(scalar j=minY;j<maxY;j+=dy){
@@ -47,7 +63,7 @@ void drawFrep(Frep_tree frep,scalar minX,scalar maxX,scalar minY,scalar maxY,sca
 
 }
 
-void drawFrep(Frep_tree frep,scalar minX,scalar maxX,scalar minY,scalar maxY,scalar dx,scalar dy,std::string name){
+void drawFrep(Frep_tree frep,scalar minX,scalar maxX,scalar minY,scalar maxY,scalar dx,scalar dy,std::string name,bool preview){
 
     int height=(int)((maxX-minX)/dx);
     int width=(int)((maxY-minY)/dy);
@@ -83,9 +99,80 @@ void drawFrep(Frep_tree frep,scalar minX,scalar maxX,scalar minY,scalar maxY,sca
     }
     // std::cout  << '\n';
     
+    cv::Mat image = cv::Mat(width, height, CV_8UC4, pix);
+
+    auto strings=insert_newlines(frep.getPrintedGenome(),120);
+    float scale=0.3;
+    int y=20;
+    for (int i=0;i<strings.size();i++){
+        cv::putText(image, 
+            strings[i],
+            cv::Point(10,y), // Coordinates
+            cv::FONT_HERSHEY_SIMPLEX, // Font
+            scale, // Scale. 2.0 = 2x bigger
+            cv::Scalar(0,0,0), // BGR Color
+            1); // Line Thickness (Optional)
+        y+=15;
+
+    }
+
+    // cv::putText(image, 
+    //         frep.getPrintedGenome(),
+    //         cv::Point(10,10), // Coordinates
+    //         cv::FONT_HERSHEY_SIMPLEX, // Font
+    //         0.25, // Scale. 2.0 = 2x bigger
+    //         cv::Scalar(0,0,0), // BGR Color
+    //         1); // Line Thickness (Optional)
+
+    std::string fileName=name+".jpg";
+    cv::imwrite( fileName, image );
+    if(preview){
+        cv::namedWindow("Display Image", cv::WINDOW_AUTOSIZE );
+        cv::imshow("Display Image", image);
+        cv::waitKey(0);
+
+    }
+}
+
+void drawFrep(Frep* frep,scalar minX,scalar maxX,scalar minY,scalar maxY,scalar dx,scalar dy,std::string name,bool preview){
+
+    int height=(int)((maxX-minX)/dx);
+    int width=(int)((maxY-minY)/dy);
+    int size=height*width*4;
+    
+
+
+    int stride=0;
+    unsigned char pix[size];
+
+
+    for(scalar i=minX;i<maxX-dx;i+=dx){
+        for(scalar j=minY;j<maxY-dy;j+=dy){
+            frep->setXY(i,j);
+            scalar val=frep->eval();
+            if(val>0.0f){
+                // std::cout << "+" ;
+                pix[stride+0]=0;
+                pix[stride+1]=0;
+                pix[stride+2]=0;
+                pix[stride+3]=0;
+                
+            }else{
+                // std::cout << "o" ;
+                pix[stride+0]=255;
+                pix[stride+1]=255;
+                pix[stride+2]=255;
+                pix[stride+3]=255;
+            }
+            stride+=4;
+        }
+        // std::cout  << '\n';
+    }
+    // std::cout  << '\n';
+    
     cv::Mat image = cv::Mat(width, height, CV_8UC4, pix);
     cv::putText(image, 
-            frep.getPrintedGenome(),
+            frep->getPrintedName(),
             cv::Point(10,10), // Coordinates
             cv::FONT_HERSHEY_SIMPLEX, // Font
             0.25, // Scale. 2.0 = 2x bigger
@@ -94,11 +181,12 @@ void drawFrep(Frep_tree frep,scalar minX,scalar maxX,scalar minY,scalar maxY,sca
 
     std::string fileName=name+".jpg";
     cv::imwrite( fileName, image );
-    cv::namedWindow("Display Image", cv::WINDOW_AUTOSIZE );
-    cv::imshow("Display Image", image);
-    cv::waitKey(0);
-    
+    if(preview){
+        cv::namedWindow("Display Image", cv::WINDOW_AUTOSIZE );
+        cv::imshow("Display Image", image);
+        cv::waitKey(0);
 
+    }
 }
 
 float constraint(float num){
@@ -107,7 +195,7 @@ float constraint(float num){
     return num;
 }
 
-float compareL1(Vector v, Frep* frep,Frep_tree* frep_tree,scalar minX,scalar maxX,scalar minY,scalar maxY,scalar dx,scalar dy,std::string name){
+float compareL1(Vector v, Frep* frep,Frep_tree* frep_tree,scalar minX,scalar maxX,scalar minY,scalar maxY,scalar dx,scalar dy,std::string name,bool smooth){
 
     int height=(int)((maxX-minX)/dx);
     int width=(int)((maxY-minY)/dy);
@@ -136,10 +224,10 @@ float compareL1(Vector v, Frep* frep,Frep_tree* frep_tree,scalar minX,scalar max
     // frep_tree->genome[0][0]=constraint(v.at(0));
     // frep_tree->genome[0][1]=constraint(v.at(1));
     // frep_tree->genome[0][2]=constraint(v.at(2));
-    // frep_tree->updateGenome(frep_tree->genome);
+    // frep_tree->updateGenome(frep_tree->genome,false);
 
     
-    frep_tree->updateGenome(g);
+    frep_tree->updateGenome(g,smooth);
 
 
     for(scalar i=minX;i<maxX-dx;i+=dx){
@@ -178,13 +266,21 @@ float compareL1(Vector v, Frep* frep,Frep_tree* frep_tree,scalar minX,scalar max
     std::cout<<result <<"\n";   
     
     cv::Mat image = cv::Mat(width, height, CV_8UC4, pix);
-    cv::putText(image, 
-            frep_tree->getPrintedGenome(),
-            cv::Point(10,20), // Coordinates
+    auto strings=insert_newlines(frep_tree->getPrintedGenome(),120);
+    float scale=0.3;
+    int y=20;
+    for (int i=0;i<strings.size();i++){
+        cv::putText(image, 
+            strings[i],
+            cv::Point(10,y), // Coordinates
             cv::FONT_HERSHEY_SIMPLEX, // Font
-            0.5, // Scale. 2.0 = 2x bigger
+            scale, // Scale. 2.0 = 2x bigger
             cv::Scalar(0,0,0), // BGR Color
             1); // Line Thickness (Optional)
+        y+=15;
+
+    }
+    
 
     cv::imwrite( fileName, image );
     return result;
@@ -212,20 +308,21 @@ int main(int const, char const**) {
     scalar maxY=3.0f;
     scalar dx=0.01f;
     scalar dy=0.01f;
+    bool smooth=false;
     
     std::vector<std::vector<scalar>>  genome;
 
 
     std::vector<scalar> node1;
-    node1.push_back(0.848148);
-    node1.push_back(0.855556);
-    node1.push_back(0.244);
+    node1.push_back(0.34);
+    node1.push_back(0.1);
+    node1.push_back(0.95);
     genome.push_back(node1);
 
     std::vector<scalar> node2;
-    node2.push_back(0.205);
-    node2.push_back(0.4524);
-    node2.push_back(0.94);
+    node2.push_back(0.48);
+    node2.push_back(0.3);
+    node2.push_back(0.9);
     genome.push_back(node2);
 
     std::vector<scalar> node3;
@@ -234,14 +331,14 @@ int main(int const, char const**) {
     node3.push_back(0.727);
     genome.push_back(node3);
 
-    Frep_tree tree(genome); 
+    Frep_tree tree(genome,smooth); 
     // genome[0][0]=0.1;
-    // tree.updateGenome(genome);
-    // drawFrep(tree,minX, maxX, minY, maxY, dx, dy,"image");
+    // tree.updateGenome(genome,false);
+    // drawFrep(tree,minX, maxX, minY, maxY, dx, dy,"image22",true);
 
     
 
-    float precision = 0.01;
+    float precision = 0.001;
     int dimension = 3;
     NelderMeadOptimizer o(dimension, precision);
 
@@ -263,7 +360,7 @@ int main(int const, char const**) {
     Rectangle r(-1.0f,1.0f,-1.0f,1.0f);
     Subtract s(&r,&c);
     PolarArray pa(&r,0.0f, 0.0f, 45.0f,-1.0f);
-    // drawFrep(&s,minX, maxX, minY, maxY, dx, dy);
+    drawFrep(&s,minX, maxX, minY, maxY, dx, dy,"target",false);
 
     int count=0;
 
@@ -272,7 +369,7 @@ int main(int const, char const**) {
     
     float score=0.0f;
     while ( !o.done(score)) {
-        if(count>50){
+        if(count>50||o.done()){
             count=0;
             std::cout<<"Counld't find solution, reset with random values!\n";
             o.reset();
@@ -284,7 +381,7 @@ int main(int const, char const**) {
 
         std::string name1 = "i";
         std::string name=name1+std::to_string(count);   
-        score=compareL1( v, &s, &tree, minX, maxX, minY, maxY, dx, dy, name);
+        score=compareL1( v, &s, &tree, minX, maxX, minY, maxY, dx, dy, name,smooth);
         v = o.step(v,score );
         count++;
     }