KiCad to WebGL: The Road So Far

Getting a reasonable looking 3D model for online viewing out of KiCad isn’t straightforward yet, but this article provides some automation scripts while going over the process.

The pipeline

We’ll be using:

Preparation

Fire up FreeCAD and install kicadStepUpMod from the new add-on manager.

To help automation we’ll add a small fix to kicadStepUpMod to enable calling the copper import function with a known filename, preventing a second ‘open file’ dialog to have to open the same file again. If the file already looks like this it means the project accepted my patch and you can skip this.

~/.FreeCAD/Mod/tracks.py, starting at line 170:

def addtracks(fname = None):
    global start_time, last_pcb_path, min_drill_size
    global use_LinkGroups, use_AppPart, tracks_version
    import sys 
     
    # cfg_read_all() it doesn't work through different files
    # print (min_drill_size)
     
    FreeCAD.Console.PrintMessage('tracks version: '+tracks_version+'\n')
    Filter=""  
    pg = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/kicadStepUp")
    if fname is None:
        last_pcb_path = pg.GetString("last_pcb_path")
        if len (last_pcb_path) == 0:
                last_pcb_path = ""
        fname, Filter = PySide.QtGui.QFileDialog.getOpenFileName(None, "Open File...",
                make_unicode(last_pcb_path), "*.kicad_pcb")

First Pass

The following script opens a file dialog to select a KiCad PCB file. Once selected it will load the board using kicadStepUpMod, import the outer copper layers, export the whole as temporary STEP file, re-import that to finally export the model to out.gltf, the 3D scene we’ll be using online, after some optimisation.

#!/usr/bin/freecad

import FreeCAD as App
import FreeCADGui as Gui
import ImportGui as Import

import kicadStepUptools as ksu
import tracks as ksu_tracks

import tkinter
from tkinter.filedialog import askopenfilename
tkinter.Tk().withdraw()
filename = askopenfilename()


print("\nOpening file: " + filename)

ksu.open(filename)
# # The default 'addtracks' function _always_ opens a file open dialog. With a patched version you can skip that:
# ksu_tracks.addtracks()
ksu_tracks.addtracks(filename)

# This extra export-import step fixes most color issues compared to doing a direct export to glTF:

Import.export(App.ActiveDocument.Objects, "/tmp/ksu.step")

App.newDocument("Unnamed")

# feat = Import.insert(u"/home/stefan/www/sites/new/rbts.co/test.step","Unnamed")
feat = Import.insert(u"/tmp/ksu.step","Unnamed")
Import.export(App.ActiveDocument.Objects, "out.gltf")

App.closeDocument(App.ActiveDocument.Name)
Gui.getMainWindow().close()

Optimising the 3D Model

We’ll be using some fairly new algorithms which compress a mesh much better than your regular ‘bunch of triangles’ meshes to have a good online viewing experience:

$ gltfpack -cc -tc -mi -si 0.5 -i test.gltf -o static/3d/test.glb

The number ‘0.5’ in above command is a quality control, 1 meaning no model changes and 0 maximum reduction (whatever that may be).

Online Viewer

The viewer is based on three.js. I’d have liked to use Google’s ‘ModelView’, but it had several issues making it rather unattractive (literally).