CNC - g-code generation

FUN with a CNC router

(Work in progress. Enquiries to:


I bough a small CNC machine from Sain Smart, the "Genmitsu CNC router 3018-PRO". It is a entry level device and is not to costly. It works correctly and is pretty sturdy.

It is driven by GRBL code that is in turn produced from GCODE. The passage from GCODE to GRBL is done by the controller on the CNC machine. Our fun lies with the generation of the GCODE.

The connection from the GCODE provider to this CNC device is through a simple USB port. In my case I am running a full PC running Debian. However I have verified the solution described here on Raspberry PI3.


There is a plethora of software to produce GCODE. Some are very simple and others are quite extensive and are part of a whole Computer Aided Design (CAD) system. Some are very complex and can be used for engineering and electronic board design. Some are free. On my Fedora (Linux) system I have had some successes with flatcam, pycam, openscad, librecad, kicad, dxf2gcode, blender  png23d, rastercarve etc.

I have also used a GCODE visualizer and CNC port driver called Candle. This program is our friend. It simply permits the preview of the CNC task contained in GCODE files, interact with the CNC device et set some parameters such as the all important zero point.

My first goal

My first goal was to start with an image, massage it with image editors, assign cut depth by colors and then send it to the CNC machine. This statement hides a lot of complexity.

I was looking to carve an end product with smooth well defined edges.

I went from one solution to an other and I despaired. I could not really find what I wanted. This is not to critique those programs that I tried but weel, I did not like what I was able to produce with them and I found many built in python code that where limited and unstable and in some cases very slow.

So I built my own G-CODE generator

Call me a compulsive programmer and I will not argue with you. I like programming.

I wanted:

  • A fully parametrized application.
  • Capable of handling large and or complex tasks.
  • Fast execution.
  • Raspberry  PI3 compatible. 

So it is written in "C". It has the following usage profile:

Usage:  sculpt

        -xflip          (0 or 1, default=0) Flip the image on the X-axis.
        -border         (0 or 1, default=0) Sculpt a clean continous border around the objects.
        -mborder                (0 or 1, default=0) Remove using border as guide.
        -proportional           (0,1 default=0) sub-level proportionality.
        -dist2depth             (0-255, default=0) Make depth function of distance from border.
        -lines          (0 or 1, default=0) Sculpt a clean continous lines.
        -invert         (0 or 1, default=0) Sculpt inverted image
        -raster         (0 or 1, default=0) Sculpt image line by line.
        -lru            (0 or 1, default=1) Remove material within the borders. Left-Right-Up.
        -udr            (0 or 1, default=1) Remove material within the borders. Up-Down-Right
        -inside         (0 or 1, default=0) Remove material within the borders.
        -insidealt      (0 or 1, default=0) Remove material within the borders (alternate method).
        -alphamask      (0 or 1, default=0) Remove material corresponding to the alpha layer of the image.
        -cutlevels      (>0, default=1) Number of cutting passes to perform.
        -cutdepth       (>0 default=0.5) Depth of each cut (cumulative).
        -cutterdiameter (>0, default 3) Width of the cutting head.
        -cutterdiameter2        (>0, default 0) Width of the 2nd cutting head.
        -middle         (0 or 1 , default=0) Define the xy offset to zero in the middle.
        -box            (>999, default=-999) Cut a box around the picture with border distance.
        -spiral         ('r' or 'l', turns, increment default=) Cut a spiral here X,Y,{r|l},TURNS,INCREMENT.
        -gear           ('m,t,h' where m is mode in mm and t is the # of teeth and hole diameter default=) Cut a spur gear.
        -hole           ('x,y,c' where x,y are the coordinates and t is the radius, default=) Cut a hole.
        -line           ('x,y,xx,yy' where x,y,xx,yy are the coordinates, default=) Cut a line.
        -dup            ('x,y' where x,y are the coordinates offsets, default=) Cut a duplicat object.
        -circle         (>-999 default=-999) Cut a circle around the picture with border distance.
        -safez          (>0, default=5) Safe height above material for fast travel without cutting.
        -spindlespeed   (>=0, <=200, default 200) Cutting head rotation speed index.
        -feedrate       (>=0, <=1000, default 150) Cutting head displacement speed index.
        -cutteroverlap  (>=0, <=100, default 50) amount of overlap between cuts;
        -output, -o     (stdout) File to receive the generated g-code.
        -input, -i      PNG file to analyse (REQUIRED).

The input file

Must be a PNG file of depth 8 and grayscale.


  1. Obtain a source image:
  2. Massage it to obtain:
  3. Build the G-CODE using sculpt thusly: "./sculpt -cutdepth 1 -cutterdiameter 1 -border 1  -inside 0 -insidealt 0  images/a1.png > t.ngc; Candle t.ngc".
  4. Use Candle to preview the CNC cutting task:
  5. Prepare the router, Don't forget to correctly set the zero xy and z point and then "press Send". It night be a good idea to do a dry run without a cutting tool inserted to make sure that the head stays in bounds and does not hit anything such as the claps used if any.

Cutting modes

The cutting modes are "-inside", "-insidealt", "-border" and "-raster".

"-inside" will remove material. It tries to minimize the head displacements but the strategies used to direct the cutting head fails often and this results in many head displacements.

"-insidealt" aims the do the same thing as "-inside" it strategy is different. It also fails. Try one and the other and choose the one that best suits.

"-udr" and "-lru" are variants of the two strategies above. "-udr" removes in a strait line going up and down before incrementing the "x" axis. "-lru" removes material going left and right before incrementing the "y" axis.

"-raster" removes material strictly up an down varying the "cutdepth" according to the relative grey intensity.

"-box" and "-circle" removes material to form a box or a circle around the images that was cut. The diameter to side lengths are taken from the image width and height.

(Creation and modification dates: