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:
- FreeCAD: Open Source 3D CAD modeller
- kicadStepUpMod: KiCad STEP import tools for FreeCAD
- meshoptimizer: Mesh tools for the glTF file format
- Three.js: 3D viewer toolkit for the web
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).