$npx -y skills add github/awesome-copilot --skill freecad-scriptsExpert skill for writing FreeCAD Python scripts, macros, and automation. Use when asked to create FreeCAD models, parametric objects, Part/Mesh/Sketcher scripts, workbench tools, GUI dialogs with PySide, Coin3D scenegraph manipulation, or any FreeCAD Python API task. Covers FreeC
| 1 | # FreeCAD Scripts |
| 2 | |
| 3 | Expert skill for generating production-quality Python scripts for the FreeCAD CAD application. Interprets shorthand, quasi-code, and natural language descriptions of 3D modeling tasks and translates them into correct FreeCAD Python API calls. |
| 4 | |
| 5 | ## When to Use This Skill |
| 6 | |
| 7 | - Writing Python scripts for FreeCAD's built-in console or macro system |
| 8 | - Creating or manipulating 3D geometry (Part, Mesh, Sketcher, Path, FEM) |
| 9 | - Building parametric FeaturePython objects with custom properties |
| 10 | - Developing GUI tools using PySide/Qt within FreeCAD |
| 11 | - Manipulating the Coin3D scenegraph via Pivy |
| 12 | - Creating custom workbenches or Gui Commands |
| 13 | - Automating repetitive CAD operations with macros |
| 14 | - Converting between mesh and solid representations |
| 15 | - Scripting FEM analyses, raytracing, or drawing exports |
| 16 | |
| 17 | ## Prerequisites |
| 18 | |
| 19 | - FreeCAD installed (0.19+ recommended; 0.21+/1.0+ for latest API) |
| 20 | - Python 3.x (bundled with FreeCAD) |
| 21 | - For GUI work: PySide2 (bundled with FreeCAD) |
| 22 | - For scenegraph: Pivy (bundled with FreeCAD) |
| 23 | |
| 24 | ## FreeCAD Python Environment |
| 25 | |
| 26 | FreeCAD embeds a Python interpreter. Scripts run in an environment where these key modules are available: |
| 27 | |
| 28 | ```python |
| 29 | import FreeCAD # Core module (also aliased as 'App') |
| 30 | import FreeCADGui # GUI module (also aliased as 'Gui') — only in GUI mode |
| 31 | import Part # Part workbench — BRep/OpenCASCADE shapes |
| 32 | import Mesh # Mesh workbench — triangulated meshes |
| 33 | import Sketcher # Sketcher workbench — 2D constrained sketches |
| 34 | import Draft # Draft workbench — 2D drawing tools |
| 35 | import Arch # Arch/BIM workbench |
| 36 | import Path # Path/CAM workbench |
| 37 | import FEM # FEM workbench |
| 38 | import TechDraw # TechDraw workbench (replaces Drawing) |
| 39 | import BOPTools # Boolean operations |
| 40 | import CompoundTools # Compound shape utilities |
| 41 | ``` |
| 42 | |
| 43 | ### The FreeCAD Document Model |
| 44 | |
| 45 | ```python |
| 46 | # Create or access a document |
| 47 | doc = FreeCAD.newDocument("MyDoc") |
| 48 | doc = FreeCAD.ActiveDocument |
| 49 | |
| 50 | # Add objects |
| 51 | box = doc.addObject("Part::Box", "MyBox") |
| 52 | box.Length = 10.0 |
| 53 | box.Width = 10.0 |
| 54 | box.Height = 10.0 |
| 55 | |
| 56 | # Recompute |
| 57 | doc.recompute() |
| 58 | |
| 59 | # Access objects |
| 60 | obj = doc.getObject("MyBox") |
| 61 | obj = doc.MyBox # Attribute access also works |
| 62 | |
| 63 | # Remove objects |
| 64 | doc.removeObject("MyBox") |
| 65 | ``` |
| 66 | |
| 67 | ## Core Concepts |
| 68 | |
| 69 | ### Vectors and Placements |
| 70 | |
| 71 | ```python |
| 72 | import FreeCAD |
| 73 | |
| 74 | # Vectors |
| 75 | v1 = FreeCAD.Vector(1, 0, 0) |
| 76 | v2 = FreeCAD.Vector(0, 1, 0) |
| 77 | v3 = v1.cross(v2) # Cross product |
| 78 | d = v1.dot(v2) # Dot product |
| 79 | v4 = v1 + v2 # Addition |
| 80 | length = v1.Length # Magnitude |
| 81 | v_norm = FreeCAD.Vector(v1) |
| 82 | v_norm.normalize() # In-place normalize |
| 83 | |
| 84 | # Rotations |
| 85 | rot = FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1), 45) # axis, angle(deg) |
| 86 | rot = FreeCAD.Rotation(0, 0, 45) # Euler angles (yaw, pitch, roll) |
| 87 | |
| 88 | # Placements (position + orientation) |
| 89 | placement = FreeCAD.Placement( |
| 90 | FreeCAD.Vector(10, 20, 0), # translation |
| 91 | FreeCAD.Rotation(0, 0, 45), # rotation |
| 92 | FreeCAD.Vector(0, 0, 0) # center of rotation |
| 93 | ) |
| 94 | obj.Placement = placement |
| 95 | |
| 96 | # Matrix (4x4 transformation) |
| 97 | import math |
| 98 | mat = FreeCAD.Matrix() |
| 99 | mat.move(FreeCAD.Vector(10, 0, 0)) |
| 100 | mat.rotateZ(math.radians(45)) |
| 101 | ``` |
| 102 | |
| 103 | ### Creating and Manipulating Geometry (Part Module) |
| 104 | |
| 105 | The Part module wraps OpenCASCADE and provides BRep solid modeling: |
| 106 | |
| 107 | ```python |
| 108 | import FreeCAD |
| 109 | import Part |
| 110 | |
| 111 | # --- Primitive Shapes --- |
| 112 | box = Part.makeBox(10, 10, 10) # length, width, height |
| 113 | cyl = Part.makeCylinder(5, 20) # radius, height |
| 114 | sphere = Part.makeSphere(10) # radius |
| 115 | cone = Part.makeCone(5, 2, 10) # r1, r2, height |
| 116 | torus = Part.makeTorus(10, 2) # major_r, minor_r |
| 117 | |
| 118 | # --- Wires and Edges --- |
| 119 | edge1 = Part.makeLine((0, 0, 0), (10, 0, 0)) |
| 120 | edge2 = Part.makeLine((10, 0, 0), (10, 10, 0)) |
| 121 | edge3 = Part.makeLine((10, 10, 0), (0, 0, 0)) |
| 122 | wire = Part.Wire([edge1, edge2, edge3]) |
| 123 | |
| 124 | # Circles and arcs |
| 125 | circle = Part.makeCircle(5) # radius |
| 126 | arc = Part.makeCircle(5, FreeCAD.Vector(0, 0, 0), |
| 127 | FreeCAD.Vector(0, 0, 1), 0, 180) # start/end angle |
| 128 | |
| 129 | # --- Faces --- |
| 130 | face = Part.Face(wire) # From a closed wire |
| 131 | |
| 132 | # --- Solids from Faces/Wires --- |
| 133 | extrusion = face.extrude(FreeCAD.Vector(0, 0, 10)) # Extrude |
| 134 | revolved = face.revolve(FreeCAD.Vector(0, 0, 0), |
| 135 | FreeCAD.Vector(0, 0, 1), 360) # Revolve |
| 136 | |
| 137 | # --- Boolean Operations --- |
| 138 | fused = box.fuse(cyl) # Union |
| 139 | cut = box.cut(cyl) # Subtraction |
| 140 | common = box.commo |