Use 3D Printer As a Plotter/cutter




I got an XYZ DaVinci 1.0a, hacked to have Repetier 0.92mod firmware, and wanted to use it as a plotter / cutter as well as a 3D printer. Some use cases:

  • plotting with fabric markers on T-shirts; the main point is to make coloring-sheet T-shirts our 4-year-old can color with fabric markers
  • drawing traces on circuit boards for etching
  • cutting gum paste for cake decorating
  • cutting paper or vinyl with a drag-knife.

It was important to me that the printer mod be easily and quickly installable and uninstallable, so one can quickly switch between plotting, cutting and 3D printing.

The software side of this is a Python script / Inkscape plugin that I wrote to convert SVG / HPGL path files into gcode that the printer can print.


  • M3 screws and nuts
  • ABS filament
  • pen or marker (for plotter)
  • pins, plywood, screws and bungee cord (for extended print platform)
  • cutter holder and blades (I used this one) (for cutter)
  • Cricut adhesive mat (for cutter)

My total cost was under $20, not counting the printer.

Step 1: Attachment Clip and Springy Tool Holder

For versatility and easy of printing, I went with a two-part approach:

  • attachment clip for the print head
  • springy tool holder for pen or cutter.

The attachment clip provides a mounting surface, with screw holes or gluable mounting holes, that clips onto the print head. The tool holder then screws or glues to it.

The attachment clip needs to be customized for your particular print head. Mine is for the XYZ DaVinci 1.0a. You may be able to use my OpenSCAD file to to customize for other printers. Experience shows that you'll have to measure, print, modify, print again.

I've used three tool holders. All of them need to be printed in ABS, and get their springiness from built-in ABS springs. The springiness is essential to compensate for imperfections in the surface (though you also may get some bonus springiness from your bed's leveling springs--but that may screw up your leveling).

  1. Two-piece very springy pen holder that I remixed from one that EGoe made for the ShapeOko.
  2. Low-profile pen holder that I designed from scratch.
  3. Roland-style blade mount holder that I also designed from scratch. The bird-shaped spring here is just designed to press on the blade mount's upper pin. You may need to change the dimensions slightly to fit your blade mount.

As long as the mounting screw/glue holes on your attachment clip has the same placement as on mine, you should be able to just print my tool holders without change. I used ABS juice (ABS dissolved in acetone) to attach the two piece holder to the attachment clip. The bond is surprisingly strong. The rest uses M3 screws and nuts.

The dimensions my pen holders are designed to hold up to a 15mm fabric marker, but you can use Thingiverse's Customizer to change the size. All of them are designed to use M3 screws and nuts to hold the tool in place. There are screw nut holes that are printed by the file. On my printer, these tend to come out very snug and I had to run a drill bit (sometimes just handheld) through the screw holes, and then use a screw to force a nut into the hole. The nice thing about that is that the nuts then tend to stay in the hole.

The two-piece pen holder is really cool looking, but takes up a lot of space, which limits your print area. Hence I designed my low-profile holder instead.

Step 2: Extended Print Platform

On my printer, because the tool is off to one side of the print bed, a large chunk of the print bed can't be used for drawing and cutting. However, there is also a chunk of space that could be used if the print bed were large. In my scrap collection, I had the remains of a plywood jigsaw puzzle, and I glued on some extra pieces of wood that made it into an extended print platform, which ties on with bungee cord. A bonus of this is that I can use thumbtacks to attach work to the wood. This is ugly and hackish, but worked.

I wouldn't use this for cutting, as it's going to be hard to make the plywood as level as a glass bed would be, and leveling is much more crucial for cutting.

Step 3: Calibrating

Level your printer bed. If you're going to be cutting, level it very carefully.

Attach your clip and tool holder, and insert the tool you will use. The calibration will be different for different combinations, and the Z-calibration will need to be done each time you level, as the heights will change slightly.

Make sure you can home your printer without the clip, holder or tool bumping into the bed. If not, you will need to do some careful hardware/software working around.

Now, use your printer panel or software (I used Repetier Host) in manual mode to move the printhead around.

First, move the printhead away from the bed for safety. Then locate the minimum and maximum XY coordinates of the available print area (make sure printer can move freely over it without bumping into any clips that you will use to hold the work in place). On my printer with the two-piece holder, the coordinates are minX=10, minY=8, maxX=192 and maxY=150, all in millimeters.

Now comes the crucial point. This is so crucial, I recommend doing it before every print. Find the Z coordinate that the tool will be in while drawing and cutting. To do this, attach whatever you want to draw on (paper, fabric, etc.) on the bed, or attach the cutting mat. Then very slowly lower the tool until it is at the desired height. To prevent marking the object when drawing, you can put a piece of aluminum foil between the pen/marker and the object.

For drawing, you want the pen to exert some pressure on the drawing surface. You'll need to experiment to get the right amount of pressure. For cutting, you want the very tip of the blade to slightly penetrate the cutting mat.

Make a note of the Z coordinate.

Then check how many millimeters you need to lift the tool for movement. Typically two or three millimeters of lift will do. The less you lift, the faster the print will be.

Finally, if you're cutting, measure the "tool offset". This is the distance from the swiveling knife pivot to the far edge of the knife. Typically, this will just be the width of the knife.

You will now have this data, all in millimeters:

  • minimum and maximum X and Y coordinates
  • work Z coordinate
  • distance to lift tool
  • tool offset (if cutting)

Step 4: Preparing Gcode With Inkscape

There is a pretty good chance you can use the bundled gcodetools extension to drive your printer as a plotter, but I ended up writing my own python script and extension.

1. Make sure you have Inkscape installed.

2. Download the latest release of my gcodeplot scripts. Drag the contents of the zip file into your Inkscape's extensions directory. E.g., C:\Program Files\Inkscape\share\extensions in a typical Windows installation (you will get a UAC prompt in Windows, and will need to use an account with admin privileges; if you don't have such an account, do a single-user install of Inkscape).

3. Restart or start Inkscape.

4. Load the SVG file you want to draw or cut into Inskcape. The lower-left corner of the page in Inkscape corresponds to the minimum X and Y coordinates you measured in the previous step. Make sure your images fit into the print area.

5. Convert the drawing to a path: ctrl-A to select everything, then Path | Object to Path.

6. Save to gcode:

  • File | Save As...
  • Select: "3-axis gcode plotter" in the "Save as type" dropdown (if it doesn't show up, gcodeplot hasn't been installed properly)
  • After pressing "Save", you will have a complicated window with many settings.
  • General tab:
    • Tool mode: choose "drawing" or "cutting" to start off
    • Left x-coordinate, lower y-coordinate: the minimum X and Y coordinates from previous step
    • Right x-coordinate, upper y-coordinate: the maximum X and Y coordinates from previous step
    • Work z-coordinate, from previous step
    • Lift z-height: distance to lift tool relative to work for movement, from previous step
    • Parking z-height: a good safe lift distance relative to work, to miss all clips, etc. (20mm default should be fine)
    • Serial port: leave blank
  • Fitting and Extracting tab:
    • I recommend the defaults
  • Drawing Settings tab (if drawing):
    • Shading threshold: 0 if you don't want to shade colored areas; 1 if you want to shade all colored areas
  • Cutting Settings tab (if cutting):
    • Tool Offset: set as measured in previous step
    • Overcut: probably set to the same value as the Tool Offset
  • Press OK.

Step 5: Drawing or Cutting

Make sure your work is attached well enough to the print bed. Here are some hints:

  • if you use any clips, make sure that the print head or pen won't crash into them
  • make sure bed is not being heated
  • for drawing on fabric with a fabric marker, make sure the fabric is very strongly attached along the edges and well stretched; otherwise, the marker will pull the fabric
  • for drawing on paper, you can just clip the paper to the bed or tape it with painter's tape; with a ball-point pen, I've had good luck just drawing on a sticky note that was stuck to the bed (it was a bit off on the side not glued down, but it still worked)
  • I'd attach CDs or PCBs (I haven't tried PCBs) with painter's tape
  • for cutting, use a Cricut adhesive mat, cut to the correct size, and clipped to your bed; you can customize the clips that I used

Load the gcode file into your printer control program and print. I used Repetier Host. Kill the print (know what your printer's reset button sequence is) if anything goes wrong to avoid damage.

Step 6: More Software Stuff

While saving the gcode with my gcodeplot Inkscape extension, you can fill out a serial port name (e.g., "COM4") and have it simultaneously send the code to your printer. I don't recommend this when starting out as you have no control during sending, and the reliability is likely lower than using something like Repetier Host. But eventually you can try it.

If you have python installed, can also be used directly from the commandline, and applied to a path-only SVG file (i.e., an SVG file where objects were converted to paths with Select-All and then Path | Object-to-Path in Inkscape) or an HPGL file. Run python (assuming you have python in your path, and you're in the root gcodeplot directory) to list the options. One particularly useful option is adjusting the x/y/z coordinates right inside To do that, include --pause-at-start --send=portname in the commandline, e.g.:

python --pause-at-start --send=COM4 mydrawing.svg

The printer will start up, but before any printing starts, you will get a gcodeplot commandline that lets you move the printhead around. Here are some pause-mode commands:

  • xn: here n is a number (e.g., x7, x0 or x-4.3) in millimeters; moves printhead to absolute x coordinate n. You can also replace n by left, center or right, as well as by more complicated formulas like (left+center)/2. In all commands, if you use formulas, there must be no spaces in them. Also, there must be no space between x and the number.
  • yn and zn: same but for y and z axes; the special coordinates bottom and top (for the y axis), and work and safe (for the z axis) will be recognized
  • x+n: increments the x position by n. E.g., x+0.7 moves the printhead by 0.7 mm in the positive direction, and x+-0.7 by 0.7 in the negative direction. (Don't confuse with x-0.7 which moves to absolute coordinate -0.7)
  • y+n and z+n: same but for y and z axes
  • left=x: set the left value (minimum x coordinate) for the drawing to the current x coordinate (you can also do more complicated formulas, like left=x-3 or left=left-0.1; again, no spaces)
  • bottom=y: set the bottom value (minimum x coordinate) for the drawing to the current y coordinate
  • work=z: set the work z-value
  • Gxxx: send any G-command to the printer
  • c: continue printing

After you set the left, bottom and work values, the drawing/cutting will be adjusted to use them.

Finally, you can do multicolor plotting by using a pen control file. Make a text file, e.g., named pens.txt, with contents like this:

1 (0,0) red Red marker
2 (0,0) #00FF00 Green marker
3 (0,0) black Black marker
4 (0,2) yellow Highlighter

The general format is penNumber (offsetX,offsetY) svgColor Description:

  • penNumber: an integer--drawing will be sorted in order of penNumber
  • (offsetX,offsetY): used in case the pen is a different thickness from the pen you used when calibrating; for instance, if your pen tip sticks out 2mm further in the y-direction than the one you used when calibrating, put (0,2). If all the pens are the same size, use (0,0) for them all. (There is no out-of-bounds checking when you use offsets. Be careful.)
  • svgColor: pen color, specified in SVG color format; there are many named colors; you can also use #RRGGBB hex color names, as well as rgb(r,g,b) color names where r,g,b are integers fromI y 0 to 255 or percentages (e.g., rgb(100%,100%,100%)).

If you then include --pens=pens.txt on your commandline, will match the colors in the drawing to the closest colors in your pens file, and insert a pause command in the gcode for pen changes. The challenge is either making sure that the pens all stick out the same distance (you'll have to do this if you are using a 3rd party program like Repetier Host to send the gcode to the printer) or else re-callibrating the z-coordinate using gcodeplot's pause-mode commands (i.e., move the printhead to the correct work position with zn or z+n commands--with aluminum foil to protect the work--and then do work=z).

I have yet to test the multiple color feature, as I haven't had a use for it.

Design Now: 3D Design Contest 2016

Participated in the
Design Now: 3D Design Contest 2016

CNC Contest 2016

Participated in the
CNC Contest 2016

Epilog Contest 8

Participated in the
Epilog Contest 8



  • Pets Challenge

    Pets Challenge
  • Beauty Tips Contest

    Beauty Tips Contest
  • Backyard Contest

    Backyard Contest

32 Discussions


Question 3 months ago

Hi good day!

Can I ask what's wrong with my software. It shows that there's an error and I cant run my UGS. Thanks for help.


8 months ago

I hate to say this, but I am stuck at the "save as" step. I have
unpacked your files and saved them to the extensions directory, but I do
not have a 3-axis option. What am I missing? Thanks for your time on

4 replies

Reply 8 months ago

I don't know. Maybe you have more than one Inkscape installation, and you put the files in the wrong one's extensions directory? That's happened to me.


Reply 8 months ago

Perhaps I am stuck on the whole install part.

Select: "3-axis gcode plotter" in the "Save as type" dropdown (if it doesn't show up, gcodeplot hasn't been installed properly)

I copied the contents of the zip file to the directory. Is that it? Also, the screen shot with the Gcode Plot window, where does that come from?


Reply 8 months ago

Yes, copy the zip contents, and then it should work. Did you restart Inkscape?
Note that the "Save as" type dropdown is not alphabetical, so it's easy to miss.
The screenshot is what happens when you choose "3-axis gcode plottery" in the dropdown.


Reply 8 months ago

I was copying the unzipped folder into the directory; not the just the contents. Thanks again!


Question 10 months ago

It constantly fails, telling me it has no points. I convert the bitmap to path (I try multiple options) but nevertheless it tells me no points. I would rather have you tell me how to get a path I can use instead of sending you every svg I need to draw. Please help. Apart from minor issues it is great software. THanks


10 months ago

I have a problem, when I generate de gcode and I use it on my printer a simple path just go like a lot of points not as an only path

1 reply

Reply 10 months ago

You can send me the svg file : arpruss at gmail dot com


1 year ago


Thanks for a most helpful Instructable and software.

I used Inkscape, drew a star within a star, Object to Path, File, Save as ...,

Select 3-axis gcode Plotter, Save, select x, y and z settings 20, 20, 150,150, 0,4, 15, 40, 30, 5 and OK, it returns the following error message:

Traceback (most recent call last):

File "", line 1093, in <module>

print('\n'.join(fixComments(plotter, g, comments=comments)))

TypeError: fixComments() got an unexpected keyword argument 'comments'

File D:\Gideon\CNC\Test.gcode could not be saved.

Is there something I overlooked?

Kind regards


8 replies

Reply 1 year ago

I updated in github. Better?


Reply 1 year ago

Hi, I installed the latest version but I'm still getting this error. I've checked if I could fix it, but I don't know what's wrong.

Traceback (most recent call last):
File "", line 1093, in <module>
print('\n'.join(fixComments(plotter, g, comments=comments)))
TypeError: fixComments() got an unexpected keyword argument 'comments'

It doesn't save the file because of this error sadly.


Reply 1 year ago

Thanks for your swift reply, I couldn't get it to work so I have decided to install InkScape 0.48.5 and use my own completely altered version of Unicorn. InkScape 0.48.5 is horrible to use, but at least it does work with the Unicorn plugin.

I am running a selfmade pen plotter from DVD drives. It has been a lot of work trying to get all of the parts working together (different brands of DVD-drives and four different pieces of software all altered by me so they work together for this plotter).

When this plotter is completely finished, I will try to upscale the project with normal Nema17 stepper motors and a custom Marlin firmware setup with LCD panel and some other fancy stuff. By the time that one is done, I might check out your gcode generator again as I expect less issues anyway since the stuff for that new project has a bigger userbase and less issues and bugs from the get-go.


Reply 1 year ago

What error message are you getting now?


Reply 1 year ago

Here a comparison what the Unicorn script makes vs what yours does. I don't know why this is happening.

Screen Shot 2018-06-25 at 12.40.28.pngScreen Shot 2018-06-25 at 12.37.33.png

Reply 1 year ago

It's the same error. I have gotten the file from

Using Inkscape 0.91

Traceback (most recent call last):
File "", line 1093, in
print('\n'.join(fixComments(plotter, g, comments=comments)))
TypeError: fixComments() got an unexpected keyword argument 'comments'

Where can I find the 0.10 release?

Wait, I just found your github, let me try! I was looking on your Inkscape extensions page!

Okay, it works now, but it doesn't generate a good representation of the item I'm trying to draw with a lot of double lines or 'shadowing', while with the Unicorn plugin I get what I want to draw. The drawback in the Unicorn extension is that the image has super-low resolution (choppy lines). Your script generates better lines, still a bit choppy, but it looks nicer 'rounder'.

ruben dariov

2 years ago

Hi, nice tutorial, i have a question, you know why inkscape show "no points" when try to save? thanks.

1 reply