A small script to convert a LinuxCNC Tooltable to Path workbench tooltable format.

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
gnome71
Posts: 3
Joined: Mon Oct 12, 2020 1:26 pm

A small script to convert a LinuxCNC Tooltable to Path workbench tooltable format.

Post by gnome71 »

Hello everyone!

I wrote a small python script to convert a LinuxCNC tooltable "tool.tbl" into JSON format which can be imported by the Path workbench ToolTable Editor.
If a Toolcontroller is then created the tool numbers are the same as on my CNC mill.

Maybe somebody finds this useful too.

Code: Select all

# -*- coding: utf-8 -*-

# ***************************************************************************
# *                                                                         *
# *   Author: Alexander K, <>                  *
# *                                                                         *
# *   This program is free software; you can redistribute it and/or modify  *
# *   it under the terms of the GNU Lesser General Public License (LGPL)    *
# *   as published by the Free Software Foundation; either version 2 of     *
# *   the License, or (at your option) any later version.                   *
# *   for detail see the LICENCE text file.                                 *
# *                                                                         *
# *   This program is distributed in the hope that it will be useful,       *
# *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
# *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
# *   GNU Library General Public License for more details.                  *
# *                                                                         *
# *   You should have received a copy of the GNU Library General Public     *
# *   License along with this program; if not, write to the Free Software   *
# *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
# *   USA                                                                   *
# *                                                                         *
# ***************************************************************************
"""
FreeCAD LinuxCNC tooltable to Path Tooltable converter macro

INSTALLATION
Place this script in your macros folder. (default is $HOME/.FreeCAD/Macro on mac/linux,
C:/Users/youruser/Application Data/FreeCAD/Macro on windows).

USAGE:
In the FileOpenDialog select a LinuxCNC tooltable file (usually tool.tbl). It will then
be converted into JSON-format which the Tooltable Editor of the Path workbench can read.
The output file is located in the same directory as the input file and named "EMC Imported.json"
"""
__Name__   = "PathToolTableConvert"
__Comment__ = "Converts a LinuxCNC Tooltable into Path ToolTable json-format"
__Author__  = "alexK"
__Version__ = "0.1"
__Date__    = "2020-10-12"
__License__ = "LGPL-2.0-or-later"
__Web__ = ''
__Wiki__ = ''
__Icon__ = 'PathToolTableConvert.svg'
__Help__ = ''
__Status__ = ''
__Requires__ = ''
__Communication__ = ''
__Files__ = "PathToolTableConvert.FCMacro,PathToolTableConvert.svg"

import re
from pathlib import PurePath
from PySide import QtGui, QtCore
import FreeCAD as app
import FreeCADGui as Gui
import Path

# To debug start debug vscode, then run the script in FC.
#import ptvsd
#print("Waiting for debugger attach")
#ptvsd.enable_attach(address=('0.0.0.0', 5678))
#ptvsd.break_into_debugger()
# End debug

class ToolTable:
    """Class to process EMC tooltables."""

    def __init__(self, fin):
        self._tablename = 'EMC Imported'
        self._infile = fin
        self._p = PurePath(fin)
        self._outfile = str(self._p.parent) + '/' + self._tablename + '.json'
        self._tooltable_string = ''
        self._tools = []
        self._tooltypes = ['Undefined',
                'EndMill',
                'Drill',
                'CenterDrill',
                'CounterSink',
                'CounterBore',
                'FlyCutter',
                'Reamer',
                'Tap',
                'SlotCutter',
                'BallEndMill',
                'ChamferMill',
                'CornerRound',
                'Engraver'
        ]
        self._rx_dict = {
            'number': re.compile(r'(?P<number>T[0-9]*)'),
            'lengthoffset': re.compile(r'(?P<lengthoffset>Z-?[0-9]*\.[0-9]*|Z[0-9]*)'),
            'diameter': re.compile(r'(?P<diameter>D[0-9]*\.[0-9]*|D[0-9]*)'),
            'name': re.compile(r'(?P<name>;.*)\n')
        }

    def convert_tool_data(self):
        ''' Reads the LinuxCNC saved tooltable and parses it '''
        print('Infile:  ' + self._infile)
        print('Outfile: ' + self._outfile)
        with open(self._infile, 'r') as infile:
            for line in infile:
                tool = {'number': 0,
                        'cornerRadius': 0.0,
                        'cuttingEdgeAngle': 0.0,
                        'cuttingEdgeHeight': 0.0,
                        'diameter': 0.0,
                        'flatRadius': 0.0,
                        'lengthOffset': 0.0,
                        'material': 'undefined',
                        'name': 'undefined',
                        'tooltype': 'undefined',
                        'version': 1
                }
                for key, rx in self._rx_dict.items():
                    match = rx.search(line)
                    if match:
                        if key == 'number':
                            tool['number'] = match.group('number')[1:]
                        if key == 'lengthoffset':
                            tool['lengthOffset'] = match.group('lengthoffset')[1:]
                        if key == 'diameter':
                            tool['diameter'] = match.group('diameter')[1:]
                        if key == 'name':
                            tool['name'] = match.group('name')[1:]
                            for tooltype in self._tooltypes:
                                if self.contains_tooltype(tool['name'], tooltype):
                                    tool['tooltype'] = tooltype

                self._tools.append(tool)

        self._tooltable_string = '[{"TableName":"' + self._tablename + '","Tools":{'
        for tool in self._tools:
            self._tooltable_string += '"' + tool['number'] + '":{' + \
                '"cornerRadius":' + str(tool['cornerRadius']) + ',' + \
                '"cuttingEdgeAngle":' + str(tool['cuttingEdgeAngle']) + ',' + \
                '"cuttingEdgeHeight":' + str(tool['cuttingEdgeHeight']) + ',' + \
                '"diameter":' + str(tool['diameter']) + ',' + \
                '"flatRadius":' + str(tool['flatRadius']) + ',' + \
                '"lengthOffset":' + str(tool['lengthOffset']) + ',' + \
                '"material":"' + str(tool['material']).strip() + '",' + \
                '"name":"' + str(tool['name']).strip() + '",' + \
                '"tooltype":"' + str(tool['tooltype']).strip() + '",' + \
                '"version": 1},'

        self._tooltable_string = self._tooltable_string[:-1]
        self._tooltable_string += '},"Version": 1}]'
        #print(self._tooltable_string)

        outfile = open(self._outfile, 'w')
        outfile.write(self._tooltable_string)

        infile.close()
        outfile.close()
        print('Finished writing tooltable: ' + self._outfile)

        reply = QtGui.QMessageBox.question(None, "", "Finished converting.\nYou can now import:\n" + self._outfile \
                                            + "\nDo you want to open the toolmanager now?",
             QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No)
        if reply == QtGui.QMessageBox.Yes:
            Gui.runCommand('Path_ToolLibraryEdit',0)
        if reply == QtGui.QMessageBox.No:
            pass

    def contains_tooltype(self, s, w):
        return (' ' + w.lower() + ' ') in (' ' + s.lower() + ' ')


def main():
    ''' Main function '''
    infilename, _ = QtGui.QFileDialog.getOpenFileName(caption='Open Tooltable File',
                                                    filter='Tooltable (*.tbl)')

    if len(infilename) > 0:
        fctt = ToolTable(infilename)
        fctt.convert_tool_data()

if __name__ == '__main__':
    main()
Greetings from Austria,
Alex
sibelius
Posts: 109
Joined: Sat Jan 04, 2020 7:29 am
Location: Leura - NSW _Australia
Contact:

Re: A small script to convert a LinuxCNC Tooltable to Path workbench tooltable format.

Post by sibelius »

Hi
Thanks for your help.
I cannot make your macro to work.
This is the error I got

Code: Select all

Traceback (most recent call last):
  File "C:/Users/Valerio/AppData/Roaming/FreeCAD/Macro/PathToolTableConvert.FCMacro", line 179, in <module>
    main()
  File "C:/Users/Valerio/AppData/Roaming/FreeCAD/Macro/PathToolTableConvert.FCMacro", line 176, in main
    fctt.convert_tool_data()
  File "C:/Users/Valerio/AppData/Roaming/FreeCAD/Macro/PathToolTableConvert.FCMacro", line 143, in convert_tool_data
    '"tooltype":"' + str(tool['tooltype']).strip() + '",' + \
<class 'TypeError'>: must be str, not int
i also post my linuxCNC tool table
Any help would be appreciate

Regards,
V.
Attachments
tool .txt
my tool table
(2.22 KiB) Downloaded 97 times
sibelius
Posts: 109
Joined: Sat Jan 04, 2020 7:29 am
Location: Leura - NSW _Australia
Contact:

Re: A small script to convert a LinuxCNC Tooltable to Path workbench tooltable format.

Post by sibelius »

Hi everyone

I am the usual dumbass, the macro is working; the mistake I was making is leaving a empty line among the other line in the tooltable.tbl file.

Sweet as.
thanks for the macro, tested and working great.
User avatar
sliptonic
Veteran
Posts: 3457
Joined: Tue Oct 25, 2011 10:46 pm
Location: Columbia, Missouri
Contact:

Re: A small script to convert a LinuxCNC Tooltable to Path workbench tooltable format.

Post by sliptonic »

FYI, This tool appears to work only for the legacy tools. Strongly recommend everyone switch to using the new toolbit system.
An importer like this that takes linuxcnc tool tables and builds corresponding Toolbit libraries would be a welcome contribution.
ubiquity
Posts: 63
Joined: Fri Nov 03, 2017 7:40 pm

Re: A small script to convert a LinuxCNC Tooltable to Path workbench tooltable format.

Post by ubiquity »

Are the toolbit libraries in json format too?
OS - Linux Mint 19 & Win10 (both 64bit)
IT Training & Support (retired)
Cheers Paul
Post Reply