diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt
index 41bf9de26..046d54141 100644
--- a/xs/CMakeLists.txt
+++ b/xs/CMakeLists.txt
@@ -64,6 +64,8 @@ add_library(libslic3r STATIC
     ${LIBDIR}/libslic3r/Fill/FillConcentric.hpp
     ${LIBDIR}/libslic3r/Fill/FillHoneycomb.cpp
     ${LIBDIR}/libslic3r/Fill/FillHoneycomb.hpp
+    ${LIBDIR}/libslic3r/Fill/FillGyroid.cpp
+    ${LIBDIR}/libslic3r/Fill/FillGyroid.hpp
     ${LIBDIR}/libslic3r/Fill/FillPlanePath.cpp
     ${LIBDIR}/libslic3r/Fill/FillPlanePath.hpp
     ${LIBDIR}/libslic3r/Fill/FillRectilinear.cpp
diff --git a/xs/src/libslic3r/Fill/FillBase.cpp b/xs/src/libslic3r/Fill/FillBase.cpp
index 2fa237e5f..88645b3d9 100644
--- a/xs/src/libslic3r/Fill/FillBase.cpp
+++ b/xs/src/libslic3r/Fill/FillBase.cpp
@@ -8,6 +8,7 @@
 #include "FillConcentric.hpp"
 #include "FillHoneycomb.hpp"
 #include "Fill3DHoneycomb.hpp"
+#include "FillGyroid.hpp"
 #include "FillPlanePath.hpp"
 #include "FillRectilinear.hpp"
 #include "FillRectilinear2.hpp"
@@ -21,6 +22,7 @@ Fill* Fill::new_from_type(const InfillPattern type)
     case ipConcentric:          return new FillConcentric();
     case ipHoneycomb:           return new FillHoneycomb();
     case ip3DHoneycomb:         return new Fill3DHoneycomb();
+    case ipGyroid:              return new FillGyroid();
     case ipRectilinear:         return new FillRectilinear2();
 //  case ipRectilinear:         return new FillRectilinear();
     case ipLine:                return new FillLine();
diff --git a/xs/src/libslic3r/Fill/FillGyroid.cpp b/xs/src/libslic3r/Fill/FillGyroid.cpp
new file mode 100644
index 000000000..5fb16ba4d
--- /dev/null
+++ b/xs/src/libslic3r/Fill/FillGyroid.cpp
@@ -0,0 +1,236 @@
+#include "../ClipperUtils.hpp"
+#include "../PolylineCollection.hpp"
+#include "../Surface.hpp"
+#include <cmath>
+#include <algorithm>
+#include <iostream>
+
+#include "FillGyroid.hpp"
+
+namespace Slic3r {
+
+Polyline FillGyroid::makeLineVert(double xPos, double yPos, double width, double height, double currentXBegin, double segmentSize, coord_t scaleFactor, 
+        double zCs, double zSn, bool flip, double decal){
+    double maxSlope = abs(abs(zCs)-abs(zSn));
+    Polyline polyline;
+    polyline.points.push_back(Point(coord_t((std::max(std::min(currentXBegin, xPos+width),xPos) + decal) * scaleFactor), coord_t(yPos * scaleFactor)));
+    for(double y=yPos;y<yPos+height+segmentSize;y+=segmentSize){
+        if(y>yPos+height) y = yPos+height;
+        double ySn = sin(y +(zCs<0?3.14:0) + 3.14);
+        double yCs = cos(y +(zCs<0?3.14:0) + 3.14+(!flip?0:3.14));
+
+        double a = ySn;
+        double b = -zCs;
+        double res = zSn*yCs;
+        double r = sqrt(a*a + b*b);
+        double x = asin(a/r) + asin(res/r) +3.14;
+        x += currentXBegin;
+        
+        double ydeviation = 0.5*(flip?-1:1)*(zSn>0?-1:1)*decal*(1-maxSlope)*(res/r - a/r);
+        polyline.points.push_back(Point(coord_t((std::max(std::min(x, xPos+width),xPos)+decal-ydeviation/2) * scaleFactor), coord_t((y + ydeviation) * scaleFactor)));
+    }
+    
+    return polyline;
+}
+
+Polyline FillGyroid::makeLineHori(double xPos, double yPos, double width, double height, double currentYBegin, double segmentSize, coord_t scaleFactor, 
+        double zCs, double zSn, bool flip, double decal){
+    double maxSlope = abs(abs(zCs)-abs(zSn));
+    Polyline polyline;
+    polyline.points.push_back(Point(coord_t(xPos * scaleFactor), coord_t((std::max(std::min(currentYBegin, yPos+height),yPos)+decal) * scaleFactor)));
+    for(double x=xPos;x<xPos+width+segmentSize;x+=segmentSize){
+        if(x>xPos+width) x = xPos+width;
+        double xSn = sin(x +(zSn<0?3.14:0) +(flip?0:3.14));
+        double xCs = cos(x +(zSn<0?3.14:0) );
+        
+        double a = xCs;
+        double b = -zSn;
+        double res = zCs*xSn;
+        double r = sqrt(a*a + b*b);
+        double y = asin(a/r) + asin(res/r) +3.14/2;
+        y += currentYBegin;
+        
+        double xdeviation = 0.5*(flip?-1:1)*(zCs>0?-1:1)*decal*(1-maxSlope)*(res/r - a/r);
+        polyline.points.push_back(Point(coord_t((x + xdeviation) * scaleFactor), coord_t((std::max(std::min(y, yPos+height),yPos)+decal-xdeviation/2) * scaleFactor)));
+    }
+    
+    return polyline;
+}
+
+inline void FillGyroid::correctOrderAndAdd(const int num, Polyline poly, Polylines &array){
+    if(num%2==0){
+        Points temp(poly.points.rbegin(), poly.points.rend());
+        poly.points.assign(temp.begin(),temp.end());
+    }
+    array.push_back(poly);
+}
+
+// Generate a set of curves (array of array of 2d points) that describe a
+// horizontal slice of a truncated regular octahedron with a specified
+// grid square size.
+Polylines FillGyroid::makeGrid(coord_t gridZ, double density, double layer_width, size_t gridWidth, size_t gridHeight, size_t curveType)
+{
+    coord_t  scaleFactor = coord_t(scale_(layer_width) / density);
+    Polylines result;
+    Polyline *polyline2;
+    double segmentSize = density/2;
+    double decal = layer_width*density;
+    double xPos = 0, yPos=0, width=gridWidth, height=gridHeight;
+     //scale factor for 5% : 8 712 388
+     // 1z = 10^-6 mm ?
+    double z = gridZ/(1.0 * scaleFactor);
+    double zSn = sin(z);
+    double zCs = cos(z);
+    
+
+    int numLine = 0;
+    
+    if(abs(zSn)<=abs(zCs)){
+        //vertical
+        //begin to first one
+        int iter = 1;
+        double currentXBegin = xPos - PI/2;
+        currentXBegin = PI*(int)(currentXBegin/PI -1);
+        iter = (int)(currentXBegin/PI +1)%2;
+        bool flip = iter%2==1;
+        // bool needNewLine =false;
+        while(currentXBegin<xPos+width-PI/2){
+            
+            correctOrderAndAdd(numLine, makeLineVert(xPos, yPos, width, height, currentXBegin, segmentSize, scaleFactor, zCs, zSn, flip, 0), result);
+            numLine++;
+            
+            //then, return by the other side
+            iter++;
+            currentXBegin = currentXBegin + PI;
+            flip = iter%2==1;
+            
+            if(currentXBegin < xPos+width-PI/2){
+                
+                correctOrderAndAdd(numLine, makeLineVert(xPos, yPos, width, height, currentXBegin, segmentSize, scaleFactor, zCs, zSn, flip, 0), result);
+                numLine++;
+
+                // relance
+                iter++;
+                currentXBegin = currentXBegin + PI;
+                flip = iter%2==1;
+            }
+        }
+    }else{
+        //horizontal
+        
+
+        //begin to first one
+        int iter = 1;
+        //search first line output
+        double currentYBegin = yPos ;
+        currentYBegin = PI*(int)(currentYBegin/PI -0);
+        iter = (int)(currentYBegin/PI +1)%2;
+        
+        bool flip = iter%2==1;
+        
+        
+        while(currentYBegin < yPos+width){
+
+            correctOrderAndAdd(numLine, makeLineHori(xPos, yPos, width, height, currentYBegin, segmentSize, scaleFactor, zCs, zSn, flip, 0), result);
+            numLine++;
+        
+            //then, return by the other side
+            iter++;
+            currentYBegin = currentYBegin + PI;
+            flip = iter%2==1;
+            
+            if(currentYBegin<yPos+width){
+                
+                correctOrderAndAdd(numLine, makeLineHori(xPos, yPos, width, height, currentYBegin, segmentSize, scaleFactor, zCs, zSn, flip, 0), result);
+                numLine++;
+                
+                //relance
+                iter++;
+                currentYBegin = currentYBegin + PI;
+                flip = iter%2==1;
+            }
+        }
+    }
+    
+    return result;
+}
+
+void FillGyroid::_fill_surface_single(
+    const FillParams                &params, 
+    unsigned int                     thickness_layers,
+    const std::pair<float, Point>   &direction, 
+    ExPolygon                       &expolygon, 
+    Polylines                       &polylines_out)
+{
+    // no rotation is supported for this infill pattern
+    BoundingBox bb = expolygon.contour.bounding_box();
+    coord_t     distance = coord_t(scale_(this->spacing) / (params.density*this->scaling));
+
+    // align bounding box to a multiple of our grid module
+    bb.merge(_align_to_grid(bb.min, Point(2*M_PI*distance, 2*M_PI*distance)));
+    
+    // generate pattern
+    Polylines   polylines = makeGrid(
+        (coord_t)scale_(this->z),
+        params.density*this->scaling,
+        this->spacing,
+        (size_t)(ceil(bb.size().x / distance) + 1),
+        (size_t)(ceil(bb.size().y / distance) + 1),
+        (size_t)(((this->layer_id/thickness_layers) % 2) + 1) );
+    
+    // move pattern in place
+    for (Polylines::iterator it = polylines.begin(); it != polylines.end(); ++ it)
+        it->translate(bb.min.x, bb.min.y);
+    
+
+    // clip pattern to boundaries
+    polylines = intersection_pl(polylines, (Polygons)expolygon);
+
+    // connect lines
+    if (! params.dont_connect && ! polylines.empty()) { // prevent calling leftmost_point() on empty collections
+        ExPolygon expolygon_off;
+        {
+            ExPolygons expolygons_off = offset_ex(expolygon, (float)SCALED_EPSILON);
+            if (! expolygons_off.empty()) {
+                // When expanding a polygon, the number of islands could only shrink. Therefore the offset_ex shall generate exactly one expanded island for one input island.
+                assert(expolygons_off.size() == 1);
+                std::swap(expolygon_off, expolygons_off.front());
+            }
+        }
+        Polylines chained = PolylineCollection::chained_path_from(
+#if SLIC3R_CPPVER >= 11
+            std::move(polylines), 
+#else
+            polylines,
+#endif
+            PolylineCollection::leftmost_point(polylines), false); // reverse allowed
+        bool first = true;
+        for (Polylines::iterator it_polyline = chained.begin(); it_polyline != chained.end(); ++ it_polyline) {
+            if (! first) {
+                // Try to connect the lines.
+                Points &pts_end = polylines_out.back().points;
+                const Point &first_point = it_polyline->points.front();
+                const Point &last_point = pts_end.back();
+                // TODO: we should also check that both points are on a fill_boundary to avoid 
+                // connecting paths on the boundaries of internal regions
+                // TODO: avoid crossing current infill path
+                if (first_point.distance_to(last_point) <= 5 * distance && 
+                    expolygon_off.contains(Line(last_point, first_point))) {
+                    // Append the polyline.
+                    pts_end.insert(pts_end.end(), it_polyline->points.begin(), it_polyline->points.end());
+                    continue;
+                }
+            }
+            // The lines cannot be connected.
+#if SLIC3R_CPPVER >= 11
+            polylines_out.push_back(std::move(*it_polyline));
+#else
+            polylines_out.push_back(Polyline());
+            std::swap(polylines_out.back(), *it_polyline);
+#endif
+            first = false;
+        }
+    }
+}
+
+} // namespace Slic3r
diff --git a/xs/src/libslic3r/Fill/FillGyroid.hpp b/xs/src/libslic3r/Fill/FillGyroid.hpp
new file mode 100644
index 000000000..4467a88de
--- /dev/null
+++ b/xs/src/libslic3r/Fill/FillGyroid.hpp
@@ -0,0 +1,55 @@
+#ifndef slic3r_FillGyroid_hpp_
+#define slic3r_FillGyroid_hpp_
+
+#include <map>
+
+#include "../libslic3r.h"
+
+#include "FillBase.hpp"
+
+namespace Slic3r {
+
+class FillGyroid : public Fill
+{
+public:
+
+    FillGyroid(){ scaling = 1.75; }
+    virtual Fill* clone() const { return new FillGyroid(*this); };
+    virtual ~FillGyroid() {}
+
+    // require bridge flow since most of this pattern hangs in air
+    virtual bool use_bridge_flow() const { return true; }
+
+protected:
+    
+    // mult of density, to have a good %of weight for each density parameter
+    float scaling;
+
+
+    virtual void _fill_surface_single(
+        const FillParams                &params, 
+        unsigned int                     thickness_layers,
+        const std::pair<float, Point>   &direction, 
+        ExPolygon                       &expolygon, 
+        Polylines                       &polylines_out);
+    
+    // create the gyroid grid to clip.
+    Polylines makeGrid(coord_t gridZ, double density, double layer_width, size_t gridWidth, size_t gridHeight, size_t curveType);
+    //add line poly in reverse if needed into array
+    inline void correctOrderAndAdd(const int num, Polyline poly, Polylines &array);
+    //create a curved horinzontal line  (for each x, compute y)
+    Polyline makeLineHori(double xPos, double yPos, double width, double height, 
+        double currentYBegin, double segmentSize, coord_t scaleFactor, 
+        double zCs, double zSn, 
+        bool flip, double decal=0);
+    //create a curved vertival line (for each y, compute x)
+    Polyline makeLineVert(double xPos, double yPos, double width, double height, 
+        double currentXBegin, double segmentSize, coord_t scaleFactor, 
+        double zCs, double zSn, 
+        bool flip, double decal=0);
+
+};
+
+} // namespace Slic3r
+
+#endif // slic3r_FillGyroid_hpp_
diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp
index d88bb2162..f59c2f097 100644
--- a/xs/src/libslic3r/PrintConfig.cpp
+++ b/xs/src/libslic3r/PrintConfig.cpp
@@ -555,6 +555,7 @@ PrintConfigDef::PrintConfigDef()
     def->enum_values.push_back("concentric");
     def->enum_values.push_back("honeycomb");
     def->enum_values.push_back("3dhoneycomb");
+    def->enum_values.push_back("gyroid");
     def->enum_values.push_back("hilbertcurve");
     def->enum_values.push_back("archimedeanchords");
     def->enum_values.push_back("octagramspiral");
@@ -567,6 +568,7 @@ PrintConfigDef::PrintConfigDef()
     def->enum_labels.push_back("Concentric");
     def->enum_labels.push_back("Honeycomb");
     def->enum_labels.push_back("3D Honeycomb");
+    def->enum_labels.push_back("Gyroid");
     def->enum_labels.push_back("Hilbert Curve");
     def->enum_labels.push_back("Archimedean Chords");
     def->enum_labels.push_back("Octagram Spiral");
diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp
index 4394fcac1..7d2fb0145 100644
--- a/xs/src/libslic3r/PrintConfig.hpp
+++ b/xs/src/libslic3r/PrintConfig.hpp
@@ -29,7 +29,7 @@ enum GCodeFlavor {
 
 enum InfillPattern {
     ipRectilinear, ipGrid, ipTriangles, ipStars, ipCubic, ipLine, ipConcentric, ipHoneycomb, ip3DHoneycomb,
-    ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral,
+    ipGyroid, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral,
 };
 
 enum SupportMaterialPattern {
@@ -73,6 +73,7 @@ template<> inline t_config_enum_values& ConfigOptionEnum<InfillPattern>::get_enu
         keys_map["concentric"]          = ipConcentric;
         keys_map["honeycomb"]           = ipHoneycomb;
         keys_map["3dhoneycomb"]         = ip3DHoneycomb;
+        keys_map["gyroid"]              = ipGyroid;
         keys_map["hilbertcurve"]        = ipHilbertCurve;
         keys_map["archimedeanchords"]   = ipArchimedeanChords;
         keys_map["octagramspiral"]      = ipOctagramSpiral;