diff --git a/src/Mod/Path/Tools/README.md b/src/Mod/Path/Tools/README.md index af51833aca..8f46b421bc 100644 --- a/src/Mod/Path/Tools/README.md +++ b/src/Mod/Path/Tools/README.md @@ -75,8 +75,8 @@ solid is updated to the correct representation. * this creates a PropertyBag object inside the Body (assuming it was selected) * add properties to which define the tool bit's shape and put those into the group 'Shape' * add any other properties to the bag which might be useful for the tool bit -1. Construct the body of the tool bit and assign experssions referencing properties from the PropertyBag (in the Shape - Group) for all constraints. +1. Construct the body of the tool bit and assign experssions referencing properties from the PropertyBag (in the + `Shape` Group) for all constraints. * Position the tip of the tool bit on the origin (0,0) 1. Save the document as a new file in the Shape directory * Before saving the document make sure you have _Save Thumbnail_ selected, and _Add program logo_ deselected in diff --git a/src/Mod/Path/Tools/Shape/ballend.fcstd b/src/Mod/Path/Tools/Shape/ballend.fcstd index 016a87cb83..42c1b2d6bb 100644 Binary files a/src/Mod/Path/Tools/Shape/ballend.fcstd and b/src/Mod/Path/Tools/Shape/ballend.fcstd differ diff --git a/src/Mod/Path/Tools/Shape/bullnose.fcstd b/src/Mod/Path/Tools/Shape/bullnose.fcstd index 740e99748c..1213e0173c 100644 Binary files a/src/Mod/Path/Tools/Shape/bullnose.fcstd and b/src/Mod/Path/Tools/Shape/bullnose.fcstd differ diff --git a/src/Mod/Path/Tools/Shape/chamfer.fcstd b/src/Mod/Path/Tools/Shape/chamfer.fcstd index f2d39cff84..b7c4b059e3 100644 Binary files a/src/Mod/Path/Tools/Shape/chamfer.fcstd and b/src/Mod/Path/Tools/Shape/chamfer.fcstd differ diff --git a/src/Mod/Path/Tools/Shape/drill.fcstd b/src/Mod/Path/Tools/Shape/drill.fcstd index 5358197072..6a92834072 100644 Binary files a/src/Mod/Path/Tools/Shape/drill.fcstd and b/src/Mod/Path/Tools/Shape/drill.fcstd differ diff --git a/src/Mod/Path/Tools/Shape/endmill.fcstd b/src/Mod/Path/Tools/Shape/endmill.fcstd index 5b5a76dc41..965d29a72a 100644 Binary files a/src/Mod/Path/Tools/Shape/endmill.fcstd and b/src/Mod/Path/Tools/Shape/endmill.fcstd differ diff --git a/src/Mod/Path/Tools/Shape/probe.fcstd b/src/Mod/Path/Tools/Shape/probe.fcstd index 41c74b9af0..602cf02bad 100644 Binary files a/src/Mod/Path/Tools/Shape/probe.fcstd and b/src/Mod/Path/Tools/Shape/probe.fcstd differ diff --git a/src/Mod/Path/Tools/Shape/slittingsaw.fcstd b/src/Mod/Path/Tools/Shape/slittingsaw.fcstd index 39062fa5b9..6944be88c4 100644 Binary files a/src/Mod/Path/Tools/Shape/slittingsaw.fcstd and b/src/Mod/Path/Tools/Shape/slittingsaw.fcstd differ diff --git a/src/Mod/Path/Tools/Shape/thread-mill.fcstd b/src/Mod/Path/Tools/Shape/thread-mill.fcstd index c5252940bd..d158c553ba 100644 Binary files a/src/Mod/Path/Tools/Shape/thread-mill.fcstd and b/src/Mod/Path/Tools/Shape/thread-mill.fcstd differ diff --git a/src/Mod/Path/Tools/Shape/v-bit.fcstd b/src/Mod/Path/Tools/Shape/v-bit.fcstd index df99cb26ee..e25840b9b8 100644 Binary files a/src/Mod/Path/Tools/Shape/v-bit.fcstd and b/src/Mod/Path/Tools/Shape/v-bit.fcstd differ diff --git a/src/Mod/Path/Tools/toolbit-attributes.py b/src/Mod/Path/Tools/toolbit-attributes.py new file mode 100644 index 0000000000..610edb89b2 --- /dev/null +++ b/src/Mod/Path/Tools/toolbit-attributes.py @@ -0,0 +1,147 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +# *************************************************************************** +# * Copyright (c) 2021 sliptonic * +# * * +# * 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 * +# * * +# *************************************************************************** +# +# Script for manipulating toolbit shapes in a batch. This is handy for making +# attributes consistent over multiple or all shape file. +# +# Most commands are straight forward, except for --set which can be used to +# set the actual value of a property, or, in the case of enumerations it can +# also be used to set the enum values. This might be particularly useful when +# adding more materials. +# +# The following example moves all properties from the "Extra" group into the +# "Attributes" group. Note that the Attributes group might or might not +# already exist. If it does exist the specified group gets merged in. +# +# ./toolbit-attributes.py --move 'Extra:Attributes' src/Mod/Path/Tools/Shape/*.fcstd +# +# This example sets the Flutes value of all Shapes to 0: +# +# ./toolbit-attributes.py --set Flutes=0 src/Mod/Path/Tools/Shape/*.fcstd +# +# Finally, this example sets the enumerations of the Material attribute: +# +# ./toolbit-attributes.py --set 'Material=[HSS,Carbide,Tool Steel,Titanium]' src/Mod/Path/Tools/Shape/*.fcstd +# +# After running this tool it might be necessary to open the shape files +# manually and make sure they are visible and the thumbprint image is +# saved. +# +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# !!! Final note: this is a dangerous tool and should not be shipped with FC. !!!! +# !!! It's sole purpose is to make life of the developers easier and ensure !!!! +# !!! consistent attributes across all toobit shapes. !!!! +# !!! A single typo can ruin a lot of toolbit shapes - make sure to only use !!!! +# !!! it if those shape files are under a version control system and you can !!!! +# !!! back out the changes easily. !!!! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +import argparse +import os +import sys + +parser = argparse.ArgumentParser() +parser.add_argument('path', nargs='+', help='Shape file to process') +parser.add_argument('--move', metavar=':', help='Move attributes from group 1 into group 2') +parser.add_argument('--delete', metavar='prop', help='Delete the given attribute') +parser.add_argument('--set', metavar='prop=value', help='Set property value') +parser.add_argument('--print', action='store_true', help='If set attributes are printed as discovered') +parser.add_argument('--print-all', action='store_true', help='If set Shape attributes are also printed') +parser.add_argument('--save-changes', action='store_true', help='Unless specified the file is not saved') +parser.add_argument('--freecad', help='Directory FreeCAD binaries (libFreeCAD.so) if not installed') +args = parser.parse_args() + +if args.freecad: + sys.path.append(args.freecad) + +import FreeCAD +import Path +import PathScripts.PathPropertyBag as PathPropertyBag +import PathScripts.PathUtil as PathUtil + +set_var=None +set_val=None + +GroupMap = {} +if args.move: + g = args.move.split(':') + if len(g) != 2: + print("ERROR: {} not a valid group mapping".format(args.move)) + sys.exit(1) + GroupMap[g[0]] = g[1] + +if args.set: + s = args.set.split('=') + if len(s) != 2: + print("ERROR: {} not a valid group mapping".format(args.move)) + sys.exit(1) + set_var = s[0] + set_val = s[1] + +for i, fname in enumerate(args.path): + #print(fname) + doc = FreeCAD.openDocument(fname, True) + print("{}:".format(doc.Name)) + for o in doc.Objects: + if PathPropertyBag.IsPropertyBag(o): + print(" {}:".format(o.Label)) + for p in o.Proxy.getCustomProperties(): + grp = o.getGroupOfProperty(p) + typ = o.getTypeIdOfProperty(p) + ttp = PathPropertyBag.getPropertyTypeName(typ) + val = PathUtil.getProperty(o, p) + dsc = o.getDocumentationOfProperty(p) + enm = '' + enum = [] + if ttp == 'Enumeration': + enum = o.getEnumerationsOfProperty(p) + enm = "{}".format(','.join(enum)) + if GroupMap.get(grp): + group = GroupMap.get(grp) + print("move: {}.{} -> {}".format(grp, p, group)) + o.removeProperty(p) + o.Proxy.addCustomProperty(typ, p, group, dsc) + if enum: + print("enum {}.{}: {}".format(group, p, enum)) + setattr(o, p, enum) + PathUtil.setProperty(o, p, val) + if p == set_var: + print("set {}.{} = {}".format(grp, p, set_val)) + if ttp == 'Enumeration' and set_val[0] == '[': + enum = set_val[1:-1].split(',') + setattr(o, p, enum) + else: + PathUtil.setProperty(o, p, set_val) + if p == args.delete: + print("delete {}.{}".format(grp, p)) + o.removeProperty(p) + if not args.print_all and grp == 'Shape': + continue + if args.print or args.print_all: + print(" {:10} {:20} {:20} {:10} {}".format(grp, p, ttp, str(val), enm)) + if args.save_changes: + doc.recompute() + doc.save() + FreeCAD.closeDocument(doc.Name) + +print('-done-')