mirror of
https://github.com/github/awesome-copilot.git
synced 2026-04-11 02:35:55 +00:00
* new skill freecad-scripts * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestions from code review * resolve: codepsellrc, readme * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * add suggestions from review --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
6.0 KiB
6.0 KiB
FreeCAD Scripting Fundamentals
Reference guide for FreeCAD Python scripting basics: the document model, the console, objects, selection, and the Python environment.
Official Wiki References
- A gentle introduction
- Introduction to Python
- Python scripting tutorial
- FreeCAD Scripting Basics
- Scripting and macros
- Working with macros
- Code snippets
- Debugging
- Profiling
- Python development environment
- Extra python modules
- FreeCAD vector math library
- Embedding FreeCAD
- Embedding FreeCADGui
- Macro at startup
- How to install macros
- IPython notebook integration
- Quantity
The FreeCAD Module Hierarchy
FreeCAD (App) — Core application, documents, objects, properties
├── FreeCAD.Vector — 3D vector
├── FreeCAD.Rotation — Quaternion rotation
├── FreeCAD.Placement — Position + rotation
├── FreeCAD.Matrix — 4x4 transformation matrix
├── FreeCAD.Units — Unit conversion and quantities
├── FreeCAD.Console — Message output
└── FreeCAD.Base — Base types
FreeCADGui (Gui) — GUI module (only when GUI is active)
├── Selection — Selection management
├── Control — Task panel management
├── ActiveDocument — GUI document wrapper
└── getMainWindow() — Qt main window
Document Operations
import FreeCAD
# Document lifecycle
doc = FreeCAD.newDocument("DocName")
doc = FreeCAD.openDocument("/path/to/file.FCStd")
doc = FreeCAD.ActiveDocument
FreeCAD.setActiveDocument("DocName")
doc.save()
doc.saveAs("/path/to/newfile.FCStd")
FreeCAD.closeDocument("DocName")
# Object management
obj = doc.addObject("Part::Feature", "ObjectName")
obj = doc.addObject("Part::FeaturePython", "CustomObj")
obj = doc.addObject("App::DocumentObjectGroup", "Group")
doc.removeObject("ObjectName")
# Object access
obj = doc.getObject("ObjectName")
obj = doc.ObjectName # attribute syntax
all_objs = doc.Objects # all objects in document
names = doc.findObjects("Part::Feature") # by type
# Recompute
doc.recompute() # recompute all
doc.recompute([obj1, obj2]) # recompute specific objects
obj.touch() # mark as needing recompute
Selection API
import FreeCADGui
# Get selection
sel = FreeCADGui.Selection.getSelection() # [obj, ...]
sel = FreeCADGui.Selection.getSelection("DocName") # from specific doc
sel_ex = FreeCADGui.Selection.getSelectionEx() # extended info
# Extended selection details
for s in sel_ex:
print(s.Object.Name) # parent object
print(s.SubElementNames) # ("Face1", "Edge3", ...)
print(s.SubObjects) # actual sub-shapes
for pt in s.PickedPoints:
print(pt) # 3D pick point
# Set selection
FreeCADGui.Selection.addSelection(obj)
FreeCADGui.Selection.addSelection(obj, "Face1")
FreeCADGui.Selection.removeSelection(obj)
FreeCADGui.Selection.clearSelection()
# Selection observer
class MySelectionObserver:
def addSelection(self, doc, obj, sub, pos):
print(f"Selected: {obj}.{sub} at {pos}")
def removeSelection(self, doc, obj, sub):
print(f"Deselected: {obj}.{sub}")
def setSelection(self, doc):
print(f"Selection set changed in {doc}")
def clearSelection(self, doc):
print(f"Selection cleared in {doc}")
obs = MySelectionObserver()
FreeCADGui.Selection.addObserver(obs)
# Later: FreeCADGui.Selection.removeObserver(obs)
Console and Logging
FreeCAD.Console.PrintMessage("Normal message\n") # blue/default
FreeCAD.Console.PrintWarning("Warning\n") # orange
FreeCAD.Console.PrintError("Error\n") # red
FreeCAD.Console.PrintLog("Debug info\n") # log only
# Console message observer
class MyLogger:
def __init__(self):
FreeCAD.Console.PrintMessage("Logger started\n")
def receive(self, msg):
# process msg
pass
Units and Quantities
from FreeCAD import Units
# Create quantities
q = Units.Quantity("10 mm")
q = Units.Quantity("1 in")
q = Units.Quantity(25.4, Units.Unit("mm"))
q = Units.parseQuantity("3.14 rad")
# Convert
value_mm = float(q) # internal unit (mm for length)
value_in = q.getValueAs("in") # convert to other unit
value_m = q.getValueAs("m")
# Available unit schemes: mm/kg/s (FreeCAD default), SI, Imperial, etc.
# Common units: mm, m, in, ft, deg, rad, kg, g, lb, s, min, hr
Property System
# Add properties to any DocumentObject
obj.addProperty("App::PropertyFloat", "MyProp", "GroupName", "Tooltip")
obj.MyProp = 42.0
# Check property existence
if hasattr(obj, "MyProp"):
print(obj.MyProp)
# Property metadata
obj.getPropertyByName("MyProp")
obj.getTypeOfProperty("MyProp") # returns list: ["App::PropertyFloat"]
obj.getDocumentationOfProperty("MyProp")
obj.getGroupOfProperty("MyProp")
# Set property as read-only, hidden, etc.
obj.setPropertyStatus("MyProp", "ReadOnly")
obj.setPropertyStatus("MyProp", "Hidden")
obj.setPropertyStatus("MyProp", "-ReadOnly") # remove status
# Statuses: ReadOnly, Hidden, Transient, Output, NoRecompute