-
-
Save mdeweerd/d14274ac53b64f23d983b5fdabed8f9e to your computer and use it in GitHub Desktop.
| #!/usr/bin/env /cygdrive/c/Program Files/FreeCAD 0.21/bin/python | |
| #!/usr/bin/env /cygdrive/c/Program Files/FreeCAD 0.20/bin/python | |
| #!/usr/bin/env python3 | |
| #!/usr/bin/env /cygdrive/c/Program Files/FreeCAD 0.20/bin/FreeCAD | |
| #!/usr/bin/env /cygdrive/c/Program Files/FreeCAD 0.20/bin/FreeCADCmd | |
| #!/usr/bin/freecad | |
| #!/usr/bin/python | |
| # (Options above for reminder, easy exchange of lines to adapt to local platform). | |
| # /!\ Launch this script using the python provided/used by FreeCAD | |
| # (Select/add the appropriate line above) | |
| # | |
| # | |
| # "Quick" and dirty script to convert from one format to the other, | |
| # including OpenSCAD to STEP conversion | |
| # For STEP output with color, this script must be run using FreeCAD, not FreeCADCmd, not python . | |
| # Also works with the latter two, but without color in STEP output. | |
| # | |
| # Original https://gist.github.com/slazav/4853bd36669bb9313ddb83f51ee1cb82 - slazav/convert_shape.py | |
| # Fork (this version): https://gist.github.com/d14274ac53b64f23d983b5fdabed8f9e | |
| # | |
| # | |
| import atexit | |
| import os | |
| import re | |
| import sys | |
| # Exit this program when we can catch an error | |
| def at_exit(): | |
| sys.exit(3) | |
| # Register the exit script (does not catch everything though). | |
| atexit.register(at_exit) | |
| # Says if this was run with the FreeCAD Gui available. | |
| hasGui = False | |
| guiIsPossible = False | |
| # Check if running from the Gui, cleanup sys.argv . | |
| freecadPattern = re.compile(r"FreeCAD(Cmd)?(\.exe)?$", re.IGNORECASE) | |
| freecadCmdPattern = re.compile(r"freecadcmd(\.exe)?$", re.IGNORECASE) | |
| if freecadPattern.search(sys.argv[0]): | |
| if not freecadCmdPattern.search(sys.argv[0]): | |
| hasGui = True | |
| # Remove freecad's path | |
| sys.argv.pop(0) | |
| # TODO: remove other arguments (-c, --console, etc) - workaround: do not use them | |
| else: | |
| paths = [ | |
| "/usr/lib64/freecad/lib", | |
| "C:/Program Files/FreeCAD 0.21/bin", | |
| "C:/Program Files/FreeCAD 0.20/bin", | |
| "C:/Program Files/FreeCAD 0.19/bin", | |
| "C:/Program Files/FreeCAD 0.18/bin", | |
| ] | |
| for p in paths: | |
| if os.path.exists(p): | |
| FREECADPATH = p | |
| break | |
| if FREECADPATH is not None: | |
| print("Using FreeCAD.so from " + FREECADPATH) | |
| sys.path.insert(0, FREECADPATH) | |
| os.environ["PYTHON_PATH"] = FREECADPATH | |
| guiIsPossible = True | |
| author = "MDW" | |
| company = "https://gist.github.com/d14274ac53b64f23d983b5fdabed8f9e" | |
| if os.getenv("AUTHOR") is not None: | |
| author = os.getenv("AUTHOR") | |
| if os.getenv("COMPANY") is not None: | |
| company = os.getenv("COMPANY") | |
| # Check if started with appropriate parameters | |
| if len(sys.argv) < 3: | |
| print("Usage: %s <in_file> <out_file>" % (sys.argv[0]),) | |
| sys.exit(1) | |
| iname = sys.argv[1] | |
| oname = sys.argv[2] | |
| import FreeCAD | |
| # Further checking of the parameters, especially the output | |
| isMesh = False | |
| # determine format from extension | |
| if oname[-5:] == ".iges": | |
| file_type = "iges" | |
| elif oname[-5:] == ".step": | |
| file_type = "step" | |
| if guiIsPossible: | |
| import FreeCADGui | |
| FreeCADGui.showMainWindow() | |
| hasGui = True | |
| elif oname[-4:] == ".dae": | |
| file_type = "dae" | |
| elif oname[-4:] == ".wrl": | |
| file_type = "wrl" | |
| isMesh = True | |
| else: | |
| print("Output file should have .step, .dae, .wrl or .iges extension") | |
| sys.exit(1) | |
| # Export the parameters to a file (debug): | |
| # p=FreeCAD.ParamGet("User parameter:BaseApp") | |
| # p.Export("e.tmp") | |
| if iname[-5:] == ".scad": | |
| # OpenSCAD import settings according to | |
| # https://forum.lulzbot.com/viewtopic.php?t=243 | |
| p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/OpenSCAD") | |
| p.SetBool("useViewProviderTree", True) | |
| p.SetBool("useMultmatrixFeature", True) | |
| # For some reason conversion does not work with cylinders created from | |
| # extruded 2d circles. | |
| # So I set MaxFN large enough and use smaller $fn in my step files to | |
| # export such cylinders as polygons. | |
| # If you use only normal cylinders, no need to use so large number here. | |
| p.SetInt("useMaxFN", 50) | |
| p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Part/STEP") | |
| p.SetString("Author", author) | |
| p.SetString("Company", company) | |
| p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Import/hSTEP") | |
| p.SetBool("ReadShapeCompoundMode", False) | |
| p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Import") | |
| p.SetBool("ExportLegacy", False) | |
| p.SetBool("ExpandCompound", False) | |
| p.SetInt("ImportMode", 0) | |
| # Set a scheme for the STEP output: | |
| # p.SetString("Scheme","AP203") | |
| # p.SetString("Scheme", "AP214CD") | |
| # p.SetString("Scheme","AP214DIS") | |
| # p.SetString("Scheme","AP214IS") | |
| p.SetString("Scheme", "AP242DIS") | |
| # Export modified parameters to a file: | |
| # p=FreeCAD.ParamGet("User parameter:BaseApp") | |
| # p.Export("final.tmp") | |
| # This should read any type of file | |
| FreeCAD.loadFile(iname) | |
| data = None | |
| if False: | |
| for p in App.ActiveDocument.RootObjects: | |
| # find root object and export the shape | |
| if len(p.InList) == 0: | |
| print(p.__class__.__name__) | |
| # iterate through all objects | |
| allObjects = [] | |
| for o in App.ActiveDocument.RootObjects: | |
| # find root object and export the shape | |
| if len(o.InList) == 0 and hasattr(o, "Shape") and o.Visibility: | |
| # print(o.__class__.__name__) | |
| # print (o.Visibility) | |
| if data is None: | |
| data = o | |
| allObjects.append(o) | |
| # print(allObjects) | |
| # Transform meshes (not perfect, WIP) | |
| mesh = None | |
| if data is not None and isMesh: | |
| import Import | |
| import MeshPart | |
| # shape = data[0][0].Shape | |
| shape = data.Shape | |
| mesh = MeshPart.meshFromShape(Shape=shape, LinearDeflection=0.1, Segments=True) | |
| if 0: | |
| shape_colors = data[0][1] | |
| face_colors = [(0, 0, 0)] * mesh.CountFacets | |
| for i in range(mesh.countSegments()): | |
| color = shape_colors[i] | |
| segm = mesh.getSegment(i) | |
| for j in segm: | |
| face_colors[j] = color | |
| # mesh.write(Filename="new_example.obj", Material=face_colors, Format="obj") | |
| # | |
| # Generate the output | |
| if data is None: | |
| print("Error: can't find any object") | |
| sys.exit(1) | |
| else: | |
| # print("Trying to write '{}'".format(oname)) | |
| if file_type == "step": | |
| done = False | |
| if hasGui: | |
| # Try our best option first! | |
| try: | |
| import ImportGui | |
| ImportGui.export( | |
| allObjects, name=oname, keepPlacement=True | |
| ) # , legacy=True, keepPlacement=True, exportHidden=True) | |
| done = True | |
| except Exception as e: | |
| print("export using ImportGui did not work", e) | |
| if not done: | |
| try: | |
| data.Shape.exportStep(oname) | |
| done = True | |
| except Exception as e: | |
| print("exportStep on shape did not work", e) | |
| if not done: | |
| try: | |
| import Import | |
| Import.export( | |
| obj=[data], | |
| name=oname, | |
| legacy=True, | |
| keepPlacement=True, | |
| exportHidden=True, | |
| ) | |
| done = True | |
| except Exception as e: | |
| print("export using Import did not work", e) | |
| elif file_type == "iges": | |
| data.Shape.exportIges(oname) | |
| elif file_type == "dae": | |
| import importDAE | |
| # mesh.write(Filename=oname) | |
| importDAE.export(data, oname) # .write(Filename=oname) | |
| elif file_type == "wrl": | |
| mesh.write(Filename=oname) | |
| sys.exit(0) | |
| sys.exit(2) |
I checked - it's been a while since I used this.
Do note that there are 2 "issues:
- Generating a STEP with colors;
- Viewing a STEP with colors.
While I managed to generate STEP with colors with older versions of FreeCAD, they were not (always) viewed in color in FreeCAD.
However, I could view them in color in KiCAD and they also in other tools.
I just tested FreeCAD 0.21.1: It generates more efficient STEP files and the STEP files with color are shown with color.
Not that the script tries several methods, the first one is ImportGui.export - in my case (on windows), FreeCAD opens a window which is closed almost immediately - so I think it works with the ImportGui.export method.
I am not 100% sure, but I think the ImportGui.Export provided better results - I would have prioritized the non-gui method if it didn't.
EDIT: I updated the script to call 0.21 (first line), add the 0.21 library as a library search path (windows), fix a spelling error, and also apply python formatting (black, flake, etc).
@mdeweerd Thanks for your reply, I just confused about the same function but not have same output(ImportGui.export and Import.export), and I will try to use the ImportGui.export to do it until I found anymore solution. ❤️
I try the
Import.exportand It still can not export step with color, is right?I found it from https://forum.freecad.org/viewtopic.php?f=22&t=58071
Does this problem have solved?