{"id":"f1546b93-7736-4a2a-9dfd-b49b0c1ec554","shortId":"zCmTeB","kind":"skill","title":"freecad-scripts","tagline":"Expert 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","description":"# FreeCAD Scripts\n\nExpert 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.\n\n## When to Use This Skill\n\n- Writing Python scripts for FreeCAD's built-in console or macro system\n- Creating or manipulating 3D geometry (Part, Mesh, Sketcher, Path, FEM)\n- Building parametric FeaturePython objects with custom properties\n- Developing GUI tools using PySide/Qt within FreeCAD\n- Manipulating the Coin3D scenegraph via Pivy\n- Creating custom workbenches or Gui Commands\n- Automating repetitive CAD operations with macros\n- Converting between mesh and solid representations\n- Scripting FEM analyses, raytracing, or drawing exports\n\n## Prerequisites\n\n- FreeCAD installed (0.19+ recommended; 0.21+/1.0+ for latest API)\n- Python 3.x (bundled with FreeCAD)\n- For GUI work: PySide2 (bundled with FreeCAD)\n- For scenegraph: Pivy (bundled with FreeCAD)\n\n## FreeCAD Python Environment\n\nFreeCAD embeds a Python interpreter. Scripts run in an environment where these key modules are available:\n\n```python\nimport FreeCAD          # Core module (also aliased as 'App')\nimport FreeCADGui       # GUI module (also aliased as 'Gui') — only in GUI mode\nimport Part             # Part workbench — BRep/OpenCASCADE shapes\nimport Mesh             # Mesh workbench — triangulated meshes\nimport Sketcher         # Sketcher workbench — 2D constrained sketches\nimport Draft            # Draft workbench — 2D drawing tools\nimport Arch             # Arch/BIM workbench\nimport Path             # Path/CAM workbench\nimport FEM              # FEM workbench\nimport TechDraw         # TechDraw workbench (replaces Drawing)\nimport BOPTools         # Boolean operations\nimport CompoundTools    # Compound shape utilities\n```\n\n### The FreeCAD Document Model\n\n```python\n# Create or access a document\ndoc = FreeCAD.newDocument(\"MyDoc\")\ndoc = FreeCAD.ActiveDocument\n\n# Add objects\nbox = doc.addObject(\"Part::Box\", \"MyBox\")\nbox.Length = 10.0\nbox.Width = 10.0\nbox.Height = 10.0\n\n# Recompute\ndoc.recompute()\n\n# Access objects\nobj = doc.getObject(\"MyBox\")\nobj = doc.MyBox  # Attribute access also works\n\n# Remove objects\ndoc.removeObject(\"MyBox\")\n```\n\n## Core Concepts\n\n### Vectors and Placements\n\n```python\nimport FreeCAD\n\n# Vectors\nv1 = FreeCAD.Vector(1, 0, 0)\nv2 = FreeCAD.Vector(0, 1, 0)\nv3 = v1.cross(v2)          # Cross product\nd = v1.dot(v2)              # Dot product\nv4 = v1 + v2                # Addition\nlength = v1.Length           # Magnitude\nv_norm = FreeCAD.Vector(v1)\nv_norm.normalize()           # In-place normalize\n\n# Rotations\nrot = FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1), 45)  # axis, angle(deg)\nrot = FreeCAD.Rotation(0, 0, 45)                       # Euler angles (yaw, pitch, roll)\n\n# Placements (position + orientation)\nplacement = FreeCAD.Placement(\n    FreeCAD.Vector(10, 20, 0),    # translation\n    FreeCAD.Rotation(0, 0, 45),   # rotation\n    FreeCAD.Vector(0, 0, 0)       # center of rotation\n)\nobj.Placement = placement\n\n# Matrix (4x4 transformation)\nimport math\nmat = FreeCAD.Matrix()\nmat.move(FreeCAD.Vector(10, 0, 0))\nmat.rotateZ(math.radians(45))\n```\n\n### Creating and Manipulating Geometry (Part Module)\n\nThe Part module wraps OpenCASCADE and provides BRep solid modeling:\n\n```python\nimport FreeCAD\nimport Part\n\n# --- Primitive Shapes ---\nbox = Part.makeBox(10, 10, 10)               # length, width, height\ncyl = Part.makeCylinder(5, 20)               # radius, height\nsphere = Part.makeSphere(10)                  # radius\ncone = Part.makeCone(5, 2, 10)               # r1, r2, height\ntorus = Part.makeTorus(10, 2)                 # major_r, minor_r\n\n# --- Wires and Edges ---\nedge1 = Part.makeLine((0, 0, 0), (10, 0, 0))\nedge2 = Part.makeLine((10, 0, 0), (10, 10, 0))\nedge3 = Part.makeLine((10, 10, 0), (0, 0, 0))\nwire = Part.Wire([edge1, edge2, edge3])\n\n# Circles and arcs\ncircle = Part.makeCircle(5)                   # radius\narc = Part.makeCircle(5, FreeCAD.Vector(0, 0, 0),\n                       FreeCAD.Vector(0, 0, 1), 0, 180)  # start/end angle\n\n# --- Faces ---\nface = Part.Face(wire)                        # From a closed wire\n\n# --- Solids from Faces/Wires ---\nextrusion = face.extrude(FreeCAD.Vector(0, 0, 10))       # Extrude\nrevolved = face.revolve(FreeCAD.Vector(0, 0, 0),\n                         FreeCAD.Vector(0, 0, 1), 360)    # Revolve\n\n# --- Boolean Operations ---\nfused = box.fuse(cyl)           # Union\ncut = box.cut(cyl)              # Subtraction\ncommon = box.common(cyl)        # Intersection\nfused_clean = fused.removeSplitter()  # Clean up seams\n\n# --- Fillets and Chamfers ---\nfilleted = box.makeFillet(1.0, box.Edges)          # radius, edges\nchamfered = box.makeChamfer(1.0, box.Edges)        # dist, edges\n\n# --- Loft and Sweep ---\nloft = Part.makeLoft([wire1, wire2], True)          # wires, solid\nswept = Part.Wire([path_edge]).makePipeShell([profile_wire],\n                                              True, False)  # solid, frenet\n\n# --- BSpline Curves ---\nfrom FreeCAD import Vector\npoints = [Vector(0,0,0), Vector(1,2,0), Vector(3,1,0), Vector(4,3,0)]\nbspline = Part.BSplineCurve()\nbspline.interpolate(points)\nedge = bspline.toShape()\n\n# --- Show in document ---\nPart.show(box, \"MyBox\")    # Quick display (adds to active doc)\n# Or explicitly:\ndoc = FreeCAD.ActiveDocument or FreeCAD.newDocument()\nobj = doc.addObject(\"Part::Feature\", \"MyShape\")\nobj.Shape = box\ndoc.recompute()\n```\n\n### Topological Exploration\n\n```python\nshape = obj.Shape\n\n# Access sub-elements\nshape.Vertexes    # List of Vertex objects\nshape.Edges       # List of Edge objects\nshape.Wires       # List of Wire objects\nshape.Faces       # List of Face objects\nshape.Shells      # List of Shell objects\nshape.Solids      # List of Solid objects\n\n# Bounding box\nbb = shape.BoundBox\nprint(bb.XMin, bb.XMax, bb.YMin, bb.YMax, bb.ZMin, bb.ZMax)\nprint(bb.Center)\n\n# Properties\nshape.Volume\nshape.Area\nshape.Length       # For edges/wires\nface.Surface       # Underlying geometric surface\nedge.Curve         # Underlying geometric curve\n\n# Shape type\nshape.ShapeType    # \"Solid\", \"Shell\", \"Face\", \"Wire\", \"Edge\", \"Vertex\", \"Compound\"\n```\n\n### Mesh Module\n\n```python\nimport Mesh\n\n# Create mesh from vertices and facets\nmesh = Mesh.Mesh()\nmesh.addFacet(\n    0.0, 0.0, 0.0,   # vertex 1\n    1.0, 0.0, 0.0,   # vertex 2\n    0.0, 1.0, 0.0    # vertex 3\n)\n\n# Import/Export\nmesh = Mesh.Mesh(\"/path/to/file.stl\")\nmesh.write(\"/path/to/output.stl\")\n\n# Convert Part shape to Mesh\nimport Part\nimport MeshPart\nshape = Part.makeBox(1, 1, 1)\nmesh = MeshPart.meshFromShape(Shape=shape, LinearDeflection=0.1,\n                                AngularDeflection=0.5)\n\n# Convert Mesh to Part shape\nshape = Part.Shape()\nshape.makeShapeFromMesh(mesh.Topology, 0.05)  # tolerance\nsolid = Part.makeSolid(shape)\n```\n\n### Sketcher Module\n\n# Create a sketch on XY plane\nsketch = doc.addObject(\"Sketcher::SketchObject\", \"MySketch\")\nsketch.Placement = FreeCAD.Placement(\n    FreeCAD.Vector(0, 0, 0),\n    FreeCAD.Rotation(0, 0, 0, 1)\n)\n\n# Add geometry (returns geometry index)\nidx_line = sketch.addGeometry(Part.LineSegment(\n    FreeCAD.Vector(0, 0, 0), FreeCAD.Vector(10, 0, 0)))\nidx_circle = sketch.addGeometry(Part.Circle(\n    FreeCAD.Vector(5, 5, 0), FreeCAD.Vector(0, 0, 1), 3))\n\n# Add constraints\nsketch.addConstraint(Sketcher.Constraint(\"Coincident\", 0, 2, 1, 1))\nsketch.addConstraint(Sketcher.Constraint(\"Horizontal\", 0))\nsketch.addConstraint(Sketcher.Constraint(\"DistanceX\", 0, 1, 0, 2, 10.0))\nsketch.addConstraint(Sketcher.Constraint(\"Radius\", 1, 3.0))\nsketch.addConstraint(Sketcher.Constraint(\"Fixed\", 0, 1))\n# Constraint types: Coincident, Horizontal, Vertical, Parallel, Perpendicular,\n#   Tangent, Equal, Symmetric, Distance, DistanceX, DistanceY, Radius, Angle,\n#   Fixed (Block), InternalAlignment\n\ndoc.recompute()\n```\n\n### Draft Module\n\n```python\nimport Draft\nimport FreeCAD\n\n# 2D shapes\nline = Draft.makeLine(FreeCAD.Vector(0,0,0), FreeCAD.Vector(10,0,0))\ncircle = Draft.makeCircle(5)\nrect = Draft.makeRectangle(10, 5)\npoly = Draft.makePolygon(6, radius=5)   # hexagon\n\n# Operations\nmoved = Draft.move(obj, FreeCAD.Vector(10, 0, 0), copy=True)\nrotated = Draft.rotate(obj, 45, FreeCAD.Vector(0,0,0),\n                        axis=FreeCAD.Vector(0,0,1), copy=True)\nscaled = Draft.scale(obj, FreeCAD.Vector(2,2,2), center=FreeCAD.Vector(0,0,0),\n                      copy=True)\noffset = Draft.offset(obj, FreeCAD.Vector(1,0,0))\narray = Draft.makeArray(obj, FreeCAD.Vector(15,0,0),\n                         FreeCAD.Vector(0,15,0), 3, 3)\n```\n\n## Creating Parametric Objects (FeaturePython)\n\nFeaturePython objects are custom parametric objects with properties that trigger recomputation:\n\n```python\nimport FreeCAD\nimport Part\n\nclass MyBox:\n    \"\"\"A custom parametric box.\"\"\"\n\n    def __init__(self, obj):\n        obj.Proxy = self\n        obj.addProperty(\"App::PropertyLength\", \"Length\", \"Dimensions\",\n                         \"Box length\").Length = 10.0\n        obj.addProperty(\"App::PropertyLength\", \"Width\", \"Dimensions\",\n                         \"Box width\").Width = 10.0\n        obj.addProperty(\"App::PropertyLength\", \"Height\", \"Dimensions\",\n                         \"Box height\").Height = 10.0\n\n    def execute(self, obj):\n        \"\"\"Called on document recompute.\"\"\"\n        obj.Shape = Part.makeBox(obj.Length, obj.Width, obj.Height)\n\n    def onChanged(self, obj, prop):\n        \"\"\"Called when a property changes.\"\"\"\n        pass\n\n    def __getstate__(self):\n        return None\n\n    def __setstate__(self, state):\n        return None\n\n\nclass ViewProviderMyBox:\n    \"\"\"View provider for custom icon and display settings.\"\"\"\n\n    def __init__(self, vobj):\n        vobj.Proxy = self\n\n    def getIcon(self):\n        return \":/icons/Part_Box.svg\"\n\n    def attach(self, vobj):\n        self.Object = vobj.Object\n\n    def updateData(self, obj, prop):\n        pass\n\n    def onChanged(self, vobj, prop):\n        pass\n\n    def __getstate__(self):\n        return None\n\n    def __setstate__(self, state):\n        return None\n\n\n# --- Usage ---\ndoc = FreeCAD.ActiveDocument or FreeCAD.newDocument(\"Test\")\nobj = doc.addObject(\"Part::FeaturePython\", \"CustomBox\")\nMyBox(obj)\nViewProviderMyBox(obj.ViewObject)\ndoc.recompute()\n```\n\n### Common Property Types\n\n| Property Type | Python Type | Description |\n|---|---|---|\n| `App::PropertyBool` | `bool` | Boolean |\n| `App::PropertyInteger` | `int` | Integer |\n| `App::PropertyFloat` | `float` | Float |\n| `App::PropertyString` | `str` | String |\n| `App::PropertyLength` | `float` (units) | Length with units |\n| `App::PropertyAngle` | `float` (deg) | Angle in degrees |\n| `App::PropertyVector` | `FreeCAD.Vector` | 3D vector |\n| `App::PropertyPlacement` | `FreeCAD.Placement` | Position + rotation |\n| `App::PropertyLink` | object ref | Link to another object |\n| `App::PropertyLinkList` | list of refs | Links to multiple objects |\n| `App::PropertyEnumeration` | `list`/`str` | Dropdown selection |\n| `App::PropertyFile` | `str` | File path |\n| `App::PropertyColor` | `tuple` | RGB color (0.0-1.0) |\n| `App::PropertyPythonObject` | any | Serializable Python object |\n\n## Creating GUI Tools\n\n### Gui Commands\n\n```python\nimport FreeCAD\nimport FreeCADGui\n\nclass MyCommand:\n    \"\"\"A custom toolbar/menu command.\"\"\"\n\n    def GetResources(self):\n        return {\n            \"Pixmap\": \":/icons/Part_Box.svg\",\n            \"MenuText\": \"My Custom Command\",\n            \"ToolTip\": \"Creates a custom box\",\n            \"Accel\": \"Ctrl+Shift+B\"\n        }\n\n    def IsActive(self):\n        return FreeCAD.ActiveDocument is not None\n\n    def Activated(self):\n        # Command logic here\n        FreeCAD.Console.PrintMessage(\"Command activated\\n\")\n\nFreeCADGui.addCommand(\"My_CustomCommand\", MyCommand())\n```\n\n### PySide Dialogs\n\n```python\nfrom PySide2 import QtWidgets, QtCore, QtGui\n\nclass MyDialog(QtWidgets.QDialog):\n    def __init__(self, parent=None):\n        super().__init__(parent or FreeCADGui.getMainWindow())\n        self.setWindowTitle(\"My Tool\")\n        self.setMinimumWidth(300)\n\n        layout = QtWidgets.QVBoxLayout(self)\n\n        # Input fields\n        self.label = QtWidgets.QLabel(\"Length:\")\n        self.spinbox = QtWidgets.QDoubleSpinBox()\n        self.spinbox.setRange(0.1, 1000.0)\n        self.spinbox.setValue(10.0)\n        self.spinbox.setSuffix(\" mm\")\n\n        form = QtWidgets.QFormLayout()\n        form.addRow(self.label, self.spinbox)\n        layout.addLayout(form)\n\n        # Buttons\n        btn_layout = QtWidgets.QHBoxLayout()\n        self.btn_ok = QtWidgets.QPushButton(\"OK\")\n        self.btn_cancel = QtWidgets.QPushButton(\"Cancel\")\n        btn_layout.addWidget(self.btn_ok)\n        btn_layout.addWidget(self.btn_cancel)\n        layout.addLayout(btn_layout)\n\n        self.btn_ok.clicked.connect(self.accept)\n        self.btn_cancel.clicked.connect(self.reject)\n\n# Usage\ndialog = MyDialog()\nif dialog.exec_() == QtWidgets.QDialog.Accepted:\n    length = dialog.spinbox.value()\n    FreeCAD.Console.PrintMessage(f\"Length: {length}\\n\")\n```\n\n### Task Panel (Recommended for FreeCAD integration)\n\n```python\nclass MyTaskPanel:\n    \"\"\"Task panel shown in the left sidebar.\"\"\"\n\n    def __init__(self):\n        self.form = QtWidgets.QWidget()\n        layout = QtWidgets.QVBoxLayout(self.form)\n        self.spinbox = QtWidgets.QDoubleSpinBox()\n        self.spinbox.setValue(10.0)\n        layout.addWidget(QtWidgets.QLabel(\"Length:\"))\n        layout.addWidget(self.spinbox)\n\n    def accept(self):\n        # Called when user clicks OK\n        length = self.spinbox.value()\n        FreeCAD.Console.PrintMessage(f\"Accepted: {length}\\n\")\n        FreeCADGui.Control.closeDialog()\n        return True\n\n    def reject(self):\n        FreeCADGui.Control.closeDialog()\n        return True\n\n    def getStandardButtons(self):\n        return int(QtWidgets.QDialogButtonBox.Ok |\n                   QtWidgets.QDialogButtonBox.Cancel)\n\n# Show the panel\npanel = MyTaskPanel()\nFreeCADGui.Control.showDialog(panel)\n```\n\n## Coin3D Scenegraph (Pivy)\n\n```python\nfrom pivy import coin\nimport FreeCADGui\n\n# Access the scenegraph root\nsg = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()\n\n# Add a custom separator with a sphere\nsep = coin.SoSeparator()\nmat = coin.SoMaterial()\nmat.diffuseColor.setValue(1.0, 0.0, 0.0)  # Red\ntrans = coin.SoTranslation()\ntrans.translation.setValue(10, 10, 10)\nsphere = coin.SoSphere()\nsphere.radius.setValue(2.0)\nsep.addChild(mat)\nsep.addChild(trans)\nsep.addChild(sphere)\nsg.addChild(sep)\n\n# Remove later\nsg.removeChild(sep)\n```\n\n## Custom Workbench Creation\n\n```python\nimport FreeCADGui\n\nclass MyWorkbench(FreeCADGui.Workbench):\n    MenuText = \"My Workbench\"\n    ToolTip = \"A custom workbench\"\n    Icon = \":/icons/freecad.svg\"\n\n    def Initialize(self):\n        \"\"\"Called at workbench activation.\"\"\"\n        import MyCommands  # Import your command module\n        self.appendToolbar(\"My Tools\", [\"My_CustomCommand\"])\n        self.appendMenu(\"My Menu\", [\"My_CustomCommand\"])\n\n    def Activated(self):\n        pass\n\n    def Deactivated(self):\n        pass\n\n    def GetClassName(self):\n        return \"Gui::PythonWorkbench\"\n\nFreeCADGui.addWorkbench(MyWorkbench)\n```\n\n## Macro Best Practices\n\n```python\n# Standard macro header\n# -*- coding: utf-8 -*-\n# FreeCAD Macro: MyMacro\n# Description: Brief description of what the macro does\n# Author: YourName\n# Version: 1.0\n# Date: 2026-04-07\n\nimport FreeCAD\nimport Part\nfrom FreeCAD import Base\n\n# Guard for GUI availability\nif FreeCAD.GuiUp:\n    import FreeCADGui\n    from PySide2 import QtWidgets, QtCore\n\ndef main():\n    doc = FreeCAD.ActiveDocument\n    if doc is None:\n        FreeCAD.Console.PrintError(\"No active document\\n\")\n        return\n\n    if FreeCAD.GuiUp:\n        sel = FreeCADGui.Selection.getSelection()\n        if not sel:\n            FreeCAD.Console.PrintWarning(\"No objects selected\\n\")\n\n    # ... macro logic ...\n\n    doc.recompute()\n    FreeCAD.Console.PrintMessage(\"Macro completed\\n\")\n\nif __name__ == \"__main__\":\n    main()\n```\n\n### Selection Handling\n\n```python\n# Get selected objects\nsel = FreeCADGui.Selection.getSelection()           # List of objects\nsel_ex = FreeCADGui.Selection.getSelectionEx()       # Extended (sub-elements)\n\nfor selobj in sel_ex:\n    obj = selobj.Object\n    for sub in selobj.SubElementNames:\n        print(f\"{obj.Name}.{sub}\")\n        shape = obj.getSubObject(sub)  # Get sub-shape\n\n# Select programmatically\nFreeCADGui.Selection.addSelection(doc.MyBox)\nFreeCADGui.Selection.addSelection(doc.MyBox, \"Face1\")\nFreeCADGui.Selection.clearSelection()\n```\n\n### Console Output\n\n```python\nFreeCAD.Console.PrintMessage(\"Info message\\n\")\nFreeCAD.Console.PrintWarning(\"Warning message\\n\")\nFreeCAD.Console.PrintError(\"Error message\\n\")\nFreeCAD.Console.PrintLog(\"Debug/log message\\n\")\n```\n\n## Common Patterns\n\n### Parametric Pad from Sketch\n\n```python\ndoc = FreeCAD.ActiveDocument\n\n# Create sketch\nsketch = doc.addObject(\"Sketcher::SketchObject\", \"Sketch\")\nsketch.addGeometry(Part.LineSegment(FreeCAD.Vector(0,0,0), FreeCAD.Vector(10,0,0)))\nsketch.addGeometry(Part.LineSegment(FreeCAD.Vector(10,0,0), FreeCAD.Vector(10,10,0)))\nsketch.addGeometry(Part.LineSegment(FreeCAD.Vector(10,10,0), FreeCAD.Vector(0,10,0)))\nsketch.addGeometry(Part.LineSegment(FreeCAD.Vector(0,10,0), FreeCAD.Vector(0,0,0)))\n# Close with coincident constraints\nfor i in range(3):\n    sketch.addConstraint(Sketcher.Constraint(\"Coincident\", i, 2, i+1, 1))\nsketch.addConstraint(Sketcher.Constraint(\"Coincident\", 3, 2, 0, 1))\n\n# Pad (PartDesign)\npad = doc.addObject(\"PartDesign::Pad\", \"Pad\")\npad.Profile = sketch\npad.Length = 5.0\nsketch.Visibility = False\ndoc.recompute()\n```\n\n### Export Shapes\n\n```python\n# STEP export\nPart.export([doc.MyBox], \"/path/to/output.step\")\n\n# STL export (mesh)\nimport Mesh\nMesh.export([doc.MyBox], \"/path/to/output.stl\")\n\n# IGES export\nPart.export([doc.MyBox], \"/path/to/output.iges\")\n\n# Multiple formats via importlib\nimport importlib\nimportlib.import_module(\"importOBJ\").export([doc.MyBox], \"/path/to/output.obj\")\n```\n\n### Units and Quantities\n\n```python\n# FreeCAD uses mm internally\nq = FreeCAD.Units.Quantity(\"10 mm\")\nq_inch = FreeCAD.Units.Quantity(\"1 in\")\nprint(q_inch.getValueAs(\"mm\"))  # 25.4\n\n# Parse user input with units\nq = FreeCAD.Units.parseQuantity(\"2.5 in\")\nvalue_mm = float(q)  # Value in mm (internal unit)\n```\n\n## Compensation Rules (Quasi-Coder Integration)\n\nWhen interpreting shorthand or quasi-code for FreeCAD scripts:\n\n1. **Terminology mapping**: \"box\" → `Part.makeBox()`, \"cylinder\" → `Part.makeCylinder()`, \"sphere\" → `Part.makeSphere()`, \"merge/combine/join\" → `.fuse()`, \"subtract/cut/remove\" → `.cut()`, \"intersect\" → `.common()`, \"round edges/fillet\" → `.makeFillet()`, \"bevel/chamfer\" → `.makeChamfer()`\n2. **Implicit document**: If no document handling is mentioned, wrap in standard `doc = FreeCAD.ActiveDocument or FreeCAD.newDocument()`\n3. **Units assumption**: Default to millimeters unless stated otherwise\n4. **Recompute**: Always call `doc.recompute()` after modifications\n5. **GUI guard**: Wrap GUI-dependent code in `if FreeCAD.GuiUp:` when the script may run headless\n6. **Part.show()**: Use `Part.show(shape, \"Name\")` for quick display, or `doc.addObject(\"Part::Feature\", \"Name\")` for named persistent objects\n\n## References\n\n### Primary Links\n\n- [Writing Python code](https://wiki.freecad.org/Manual:A_gentle_introduction#Writing_Python_code)\n- [Manipulating FreeCAD objects](https://wiki.freecad.org/Manual:A_gentle_introduction#Manipulating_FreeCAD_objects)\n- [Vectors and Placements](https://wiki.freecad.org/Manual:A_gentle_introduction#Vectors_and_Placements)\n- [Creating and manipulating geometry](https://wiki.freecad.org/Manual:Creating_and_manipulating_geometry)\n- [Creating parametric objects](https://wiki.freecad.org/Manual:Creating_parametric_objects)\n- [Creating interface tools](https://wiki.freecad.org/Manual:Creating_interface_tools)\n- [Python](https://en.wikipedia.org/wiki/Python_%28programming_language%29)\n- [Introduction to Python](https://wiki.freecad.org/Introduction_to_Python)\n- [Python scripting tutorial](https://wiki.freecad.org/Python_scripting_tutorial)\n- [FreeCAD scripting basics](https://wiki.freecad.org/FreeCAD_Scripting_Basics)\n- [Gui Command](https://wiki.freecad.org/Gui_Command)\n\n### Bundled Reference Documents\n\nSee the [references/](references/) directory for topic-organized guides:\n\n1. [scripting-fundamentals.md](references/scripting-fundamentals.md) — Core scripting, document model, console\n2. [geometry-and-shapes.md](references/geometry-and-shapes.md) — Part, Mesh, Sketcher, topology\n3. [parametric-objects.md](references/parametric-objects.md) — FeaturePython, properties, scripted objects\n4. [gui-and-interface.md](references/gui-and-interface.md) — PySide, dialogs, task panels, Coin3D\n5. [workbenches-and-advanced.md](references/workbenches-and-advanced.md) — Workbenches, macros, FEM, Path, recipes","tags":["freecad","scripts","awesome","copilot","github","agent-skills","agents","custom-agents","github-copilot","hacktoberfest","prompt-engineering"],"capabilities":["skill","source-github","skill-freecad-scripts","topic-agent-skills","topic-agents","topic-awesome","topic-custom-agents","topic-github-copilot","topic-hacktoberfest","topic-prompt-engineering"],"categories":["awesome-copilot"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/github/awesome-copilot/freecad-scripts","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add github/awesome-copilot","source_repo":"https://github.com/github/awesome-copilot","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 30743 github stars · SKILL.md body (20,890 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T00:52:09.524Z","embedding":null,"createdAt":"2026-04-18T21:49:28.116Z","updatedAt":"2026-04-22T00:52:09.524Z","lastSeenAt":"2026-04-22T00:52:09.524Z","tsv":"'+1':1821 '-04':1623 '-07':1624 '-1.0':1261 '-8':1605 '/1.0':159 '/freecad_scripting_basics)':2080 '/gui_command)':2085 '/icons/freecad.svg':1556 '/icons/part_box.svg':1133,1289 '/introduction_to_python)':2068 '/manual:a_gentle_introduction#manipulating_freecad_objects)':2033 '/manual:a_gentle_introduction#vectors_and_placements)':2039 '/manual:a_gentle_introduction#writing_python_code)':2027 '/manual:creating_and_manipulating_geometry)':2046 '/manual:creating_interface_tools)':2058 '/manual:creating_parametric_objects)':2052 '/path/to/file.stl':785 '/path/to/output.iges':1864 '/path/to/output.obj':1876 '/path/to/output.step':1851 '/path/to/output.stl':787,1859 '/python_scripting_tutorial)':2074 '/wiki/python_%28programming_language%29)':2062 '0':332,333,336,338,369,370,378,379,394,397,398,402,403,404,420,421,487,488,489,491,492,496,497,500,505,506,507,508,525,526,527,529,530,532,550,551,557,558,559,561,562,630,631,632,636,640,644,840,841,842,844,845,846,858,859,860,863,864,872,874,875,883,890,894,896,907,940,941,942,945,946,966,967,975,976,977,980,981,994,995,996,1004,1005,1011,1012,1014,1016,1769,1770,1771,1774,1775,1780,1781,1785,1791,1793,1795,1799,1801,1803,1804,1805,1828 '0.0':767,768,769,773,774,777,779,1260,1514,1515 '0.05':819 '0.1':807,1363 '0.19':156 '0.21':158 '0.5':809 '1':331,337,371,531,563,634,639,771,799,800,801,847,876,885,886,895,902,908,982,1003,1822,1829,1892,1932,2099 '1.0':591,597,772,778,1513,1620 '10':392,419,450,451,452,464,470,476,490,495,498,499,503,504,552,862,944,952,965,1520,1521,1522,1773,1779,1783,1784,1789,1790,1794,1800,1887 '10.0':298,300,302,898,1059,1068,1077,1366,1441 '1000.0':1364 '15':1010,1015 '180':533 '2':469,477,635,776,884,897,989,990,991,1819,1827,1952,2107 '2.0':1526 '2.5':1905 '20':393,459 '2026':1622 '25.4':1897 '2d':238,245,935 '3':164,638,643,781,877,1017,1018,1814,1826,1968,2114 '3.0':903 '300':1351 '360':564 '3d':68,101,1220 '4':642,1977,2121 '45':372,380,399,424,973 '4x4':411 '5':458,468,519,523,870,871,949,953,958,1984,2129 '5.0':1840 '6':956,2001 'accel':1299 'accept':1448,1459 'access':282,305,313,682,1495 'activ':661,1312,1319,1563,1581,1656 'add':290,659,848,878,1501 'addit':352 'alias':207,215 'also':206,214,314 'alway':1979 'analys':148 'angl':374,382,535,923,1214 'angulardeflect':808 'anoth':1233 'api':38,78,162 'app':209,1052,1061,1070,1187,1191,1195,1199,1203,1210,1217,1222,1227,1235,1244,1250,1255,1262 'applic':57 'arc':516,521 'arch':249 'arch/bim':250 'array':1006 'ask':16 'assumpt':1970 'attach':1135 'attribut':312 'author':1617 'autom':13,134 'avail':200,1636 'axi':373,978 'b':1302 'base':1632 'basic':2077 'bb':718 'bb.center':728 'bb.xmax':722 'bb.xmin':721 'bb.ymax':724 'bb.ymin':723 'bb.zmax':726 'bb.zmin':725 'best':1597 'bevel/chamfer':1950 'block':925 'bool':1189 'boolean':268,566,1190 'boptool':267 'bound':716 'box':292,295,448,655,675,717,1044,1056,1065,1074,1298,1935 'box.common':577 'box.cut':573 'box.edges':592,598 'box.fuse':569 'box.height':301 'box.length':297 'box.makechamfer':596 'box.makefillet':590 'box.width':299 'brep':438 'brep/opencascade':226 'brief':1610 'bspline':622,645 'bspline.interpolate':647 'bspline.toshape':650 'btn':1377,1395 'btn_layout.addwidget':1388,1391 'build':108 'built':92 'built-in':91 'bundl':166,173,179,2086 'button':1376 'cad':56,136 'call':79,1082,1096,1450,1560,1980 'cancel':1385,1387,1393 'center':405,992 'chamfer':588,595 'chang':1100 'circl':514,517,866,947 'class':1039,1113,1278,1334,1421,1545 'clean':581,583 'click':1453 'close':542,1806 'code':62,1603,1928,1991,2024 'coder':1920 'coin':1492 'coin.somaterial':1511 'coin.soseparator':1509 'coin.sosphere':1524 'coin.sotranslation':1518 'coin3d':31,124,1485,2128 'coincid':882,911,1808,1817,1825 'color':1259 'command':133,1272,1283,1293,1314,1318,1568,2082 'common':576,1179,1750,1946 'compens':1916 'complet':1677 'compound':272,752 'compoundtool':271 'concept':321 'cone':466 'consol':94,1731,2106 'constrain':239 'constraint':879,909,1809 'convert':140,788,810 'copi':968,983,997 'core':204,320,2102 'correct':75 'cover':40 'creat':18,98,128,280,425,758,826,1019,1268,1295,1759,2040,2047,2053 'creation':1541 'cross':342 'ctrl':1300 'curv':623,742 'custom':113,129,1026,1042,1118,1281,1292,1297,1503,1539,1553 'custombox':1173 'customcommand':1323,1574,1579 'cut':572,1944 'cyl':456,570,574,578 'cylind':1937 'd':344 'date':1621 'deactiv':1585 'debug/log':1747 'def':1045,1078,1091,1102,1107,1123,1129,1134,1140,1146,1152,1157,1284,1303,1311,1337,1430,1447,1465,1471,1557,1580,1584,1588,1646 'default':1971 'deg':375,1213 'degre':1216 'depend':1990 'descript':66,1186,1609,1611 'develop':115 'dialog':28,1326,1402,2125 'dialog.exec':1405 'dialog.spinbox.value':1408 'dimens':1055,1064,1073 'directori':2093 'display':658,1121,2009 'dist':599 'distanc':919 'distancex':893,920 'distancey':921 'doc':285,288,662,665,1164,1648,1651,1757,1964 'doc.addobject':293,670,833,1170,1762,1833,2011 'doc.getobject':308 'doc.mybox':311,1726,1728,1850,1858,1863,1875 'doc.recompute':304,676,927,1178,1674,1843,1981 'doc.removeobject':318 'document':277,284,653,1084,1657,1954,1957,2088,2104 'dot':347 'draft':242,243,928,932 'draft.makearray':1007 'draft.makecircle':948 'draft.makeline':938 'draft.makepolygon':955 'draft.makerectangle':951 'draft.move':962 'draft.offset':1000 'draft.rotate':971 'draft.scale':986 'draw':151,246,265 'dropdown':1248 'edg':484,594,600,614,649,694,750 'edge.curve':739 'edge1':485,511 'edge2':493,512 'edge3':501,513 'edges/fillet':1948 'edges/wires':734 'element':685,1700 'emb':186 'en.wikipedia.org':2061 'en.wikipedia.org/wiki/python_%28programming_language%29)':2060 'environ':184,194 'equal':917 'error':1743 'euler':381 'ex':1695,1705 'execut':1079 'expert':4,44 'explicit':664 'explor':678 'export':152,1844,1848,1853,1861,1874 'extend':1697 'extrud':553 'extrus':547 'f':1410,1458,1713 'face':536,537,704,748 'face.extrude':548 'face.revolve':555 'face.surface':735 'face1':1729 'faces/wires':546 'facet':763 'fals':619,1842 'featur':672,2013 'featurepython':110,1022,1023,1172,2117 'fem':107,147,257,258,2134 'field':1356 'file':1253 'fillet':586,589 'fix':906,924 'float':1197,1198,1205,1212,1909 'form':1369,1375 'form.addrow':1371 'format':1866 'freec':41 'freecad':2,8,19,36,42,55,76,89,121,154,168,175,181,182,185,203,276,327,443,625,934,1036,1275,1418,1606,1626,1630,1881,1930,2029,2075 'freecad-script':1 'freecad.activedocument':289,666,1165,1307,1649,1758,1965 'freecad.console.printerror':1654,1742 'freecad.console.printlog':1746 'freecad.console.printmessage':1317,1409,1457,1675,1734 'freecad.console.printwarning':1667,1738 'freecad.guiup':1638,1661,1994 'freecad.matrix':416 'freecad.newdocument':286,668,1167,1967 'freecad.placement':390,838,1224 'freecad.rotation':367,377,396,843 'freecad.units.parsequantity':1904 'freecad.units.quantity':1886,1891 'freecad.vector':330,335,358,368,391,401,418,524,528,549,556,560,839,857,861,869,873,939,943,964,974,979,988,993,1002,1009,1013,1219,1768,1772,1778,1782,1788,1792,1798,1802 'freecadgui':211,1277,1494,1544,1640 'freecadgui.activedocument.activeview.getscenegraph':1500 'freecadgui.addcommand':1321 'freecadgui.addworkbench':1594 'freecadgui.control.closedialog':1462,1468 'freecadgui.control.showdialog':1483 'freecadgui.getmainwindow':1346 'freecadgui.selection.addselection':1725,1727 'freecadgui.selection.clearselection':1730 'freecadgui.selection.getselection':1663,1690 'freecadgui.selection.getselectionex':1696 'freecadgui.workbench':1547 'frenet':621 'fuse':568,580,1942 'fused.removesplitter':582 'generat':47 'geometr':737,741 'geometri':102,428,849,851,2043 'geometry-and-shapes.md':2108 'get':1686,1719 'getclassnam':1589 'geticon':1130 'getresourc':1285 'getstandardbutton':1472 'getstat':1103,1153 'guard':1633,1986 'gui':27,116,132,170,212,217,220,1269,1271,1592,1635,1985,1989,2081 'gui-and-interface.md':2122 'gui-depend':1988 'guid':2098 'handl':1684,1958 'header':1602 'headless':2000 'height':455,461,473,1072,1075,1076 'hexagon':959 'horizont':889,912 'icon':1119,1555 'idx':853,865 'ige':1860 'implicit':1953 'import':202,210,222,228,234,241,248,252,256,260,266,270,326,413,442,444,626,756,793,795,931,933,1035,1037,1274,1276,1330,1491,1493,1543,1564,1566,1625,1627,1631,1639,1643,1855,1869 'import/export':782 'importlib':1868,1870 'importlib.import':1871 'importobj':1873 'in-plac':361 'inch':1890 'index':852 'info':1735 'init':1046,1124,1338,1343,1431 'initi':1558 'input':1355,1900 'instal':155 'int':1193,1475 'integ':1194 'integr':1419,1921 'interfac':2054 'intern':1884,1914 'internalalign':926 'interpret':58,189,1923 'intersect':579,1945 'introduct':2063 'isact':1304 'key':197 'languag':65 'later':1536 'latest':161 'layout':1352,1378,1396,1435 'layout.addlayout':1374,1394 'layout.addwidget':1442,1445 'left':1428 'length':353,453,1054,1057,1058,1207,1359,1407,1411,1412,1444,1455,1460 'line':854,937 'lineardeflect':806 'link':1231,1240,2021 'list':687,692,697,702,707,712,1237,1246,1691 'loft':601,604 'logic':1315,1673 'macro':11,96,139,1596,1601,1607,1615,1672,1676,2133 'magnitud':355 'main':1647,1681,1682 'major':478 'makechamf':1951 'makefillet':1949 'makepipeshel':615 'manipul':33,100,122,427,2028,2042 'map':1934 'mat':415,1510,1528 'mat.diffusecolor.setvalue':1512 'mat.move':417 'mat.rotatez':422 'math':414 'math.radians':423 'matrix':410 'may':1998 'mention':1960 'menu':1577 'menutext':1290,1548 'merge/combine/join':1941 'mesh':104,142,229,230,233,753,757,759,764,783,792,802,811,1854,1856,2111 'mesh.addfacet':766 'mesh.export':1857 'mesh.mesh':765,784 'mesh.topology':818 'mesh.write':786 'meshpart':796 'meshpart.meshfromshape':803 'messag':1736,1740,1744,1748 'millimet':1973 'minor':480 'mm':1368,1883,1888,1896,1908,1913 'mode':221 'model':20,69,278,440,2105 'modif':1983 'modul':198,205,213,430,433,754,825,929,1569,1872 'move':961 'multipl':1242,1865 'mybox':296,309,319,656,1040,1174 'mycommand':1279,1324,1565 'mydialog':1335,1403 'mydoc':287 'mymacro':1608 'myshap':673 'mysketch':836 'mytaskpanel':1422,1482 'myworkbench':1546,1595 'n':1320,1413,1461,1658,1671,1678,1737,1741,1745,1749 'name':1680,2006,2014,2016 'natur':64 'none':1106,1112,1156,1162,1310,1341,1653 'norm':357 'normal':364 'obj':307,310,669,963,972,987,1001,1008,1048,1081,1094,1143,1169,1175,1706 'obj.addproperty':1051,1060,1069 'obj.getsubobject':1717 'obj.height':1090 'obj.length':1088 'obj.name':1714 'obj.placement':408 'obj.proxy':1049 'obj.shape':674,681,1086 'obj.viewobject':1177 'obj.width':1089 'object':22,111,291,306,317,690,695,700,705,710,715,1021,1024,1028,1229,1234,1243,1267,1669,1688,1693,2018,2030,2049,2120 'offset':999 'ok':1381,1383,1390,1454 'onchang':1092,1147 'opencascad':435 'oper':137,269,567,960 'organ':2097 'orient':388 'otherwis':1976 'output':1732 'pad':1753,1830,1832,1835,1836 'pad.length':1839 'pad.profile':1837 'panel':1415,1424,1480,1481,1484,2127 'parallel':914 'parametr':21,109,1020,1027,1043,1752,2048 'parametric-objects.md':2115 'parent':1340,1344 'pars':1898 'part':103,223,224,294,429,432,445,671,789,794,813,1038,1171,1628,2012,2110 'part.bsplinecurve':646 'part.circle':868 'part.export':1849,1862 'part.face':538 'part.linesegment':856,1767,1777,1787,1797 'part.makebox':449,798,1087,1936 'part.makecircle':518,522 'part.makecone':467 'part.makecylinder':457,1938 'part.makeline':486,494,502 'part.makeloft':605 'part.makesolid':822 'part.makesphere':463,1940 'part.maketorus':475 'part.shape':816 'part.show':654,2002,2004 'part.wire':510,612 'part/mesh/sketcher':23 'partdesign':1831,1834 'pass':1101,1145,1151,1583,1587 'path':106,253,613,1254,2135 'path/cam':254 'pattern':1751 'perpendicular':915 'persist':2017 'pitch':384 'pivi':127,178,1487,1490 'pixmap':1288 'place':363 'placement':324,386,389,409,2036 'plane':831 'point':628,648 'poli':954 'posit':387,1225 'practic':1598 'prerequisit':153 'primari':2020 'primit':446 'print':720,727,1712,1894 'product':49,343,348 'production-qu':48 'profil':616 'programmat':1724 'prop':1095,1144,1150 'properti':114,729,1030,1099,1180,1182,2118 'propertyangl':1211 'propertybool':1188 'propertycolor':1256 'propertyenumer':1245 'propertyfil':1251 'propertyfloat':1196 'propertyinteg':1192 'propertylength':1053,1062,1071,1204 'propertylink':1228 'propertylinklist':1236 'propertyplac':1223 'propertypythonobject':1263 'propertystr':1200 'propertyvector':1218 'provid':437,1116 'pysid':30,1325,2124 'pyside/qt':119 'pyside2':172,1329,1642 'python':9,37,51,77,86,163,183,188,201,279,325,441,679,755,930,1034,1184,1266,1273,1327,1420,1488,1542,1599,1685,1733,1756,1846,1880,2023,2059,2065,2069 'pythonworkbench':1593 'q':1885,1889,1903,1910 'q_inch.getvalueas':1895 'qtcore':1332,1645 'qtgui':1333 'qtwidget':1331,1644 'qtwidgets.qdialog':1336 'qtwidgets.qdialog.accepted':1406 'qtwidgets.qdialogbuttonbox.cancel':1477 'qtwidgets.qdialogbuttonbox.ok':1476 'qtwidgets.qdoublespinbox':1361,1439 'qtwidgets.qformlayout':1370 'qtwidgets.qhboxlayout':1379 'qtwidgets.qlabel':1358,1443 'qtwidgets.qpushbutton':1382,1386 'qtwidgets.qvboxlayout':1353,1436 'qtwidgets.qwidget':1434 'qualiti':50 'quantiti':1879 'quasi':61,1919,1927 'quasi-cod':60,1918,1926 'quick':657,2008 'r':479,481 'r1':471 'r2':472 'radius':460,465,520,593,901,922,957 'rang':1813 'raytrac':149 'recip':2136 'recommend':157,1416 'recomput':303,1033,1085,1978 'rect':950 'red':1516 'ref':1230,1239 'refer':2019,2087,2091,2092 'references/geometry-and-shapes.md':2109 'references/gui-and-interface.md':2123 'references/parametric-objects.md':2116 'references/scripting-fundamentals.md':2101 'references/workbenches-and-advanced.md':2131 'reject':1466 'remov':316,1535 'repetit':135 'replac':264 'represent':145 'return':850,1105,1111,1132,1155,1161,1287,1306,1463,1469,1474,1591,1659 'revolv':554,565 'rgb':1258 'roll':385 'root':1498 'rot':366,376 'rotat':365,400,407,970,1226 'round':1947 'rule':1917 'run':191,1999 'scale':985 'scenegraph':32,125,177,1486,1497 'script':3,10,24,43,52,87,146,190,1931,1997,2070,2076,2103,2119 'scripting-fundamentals.md':2100 'seam':585 'see':2089 'sel':1662,1666,1689,1694,1704 'select':1249,1670,1683,1687,1723 'self':1047,1050,1080,1093,1104,1109,1125,1128,1131,1136,1142,1148,1154,1159,1286,1305,1313,1339,1354,1432,1449,1467,1473,1559,1582,1586,1590 'self.accept':1398 'self.appendmenu':1575 'self.appendtoolbar':1570 'self.btn':1380,1384,1389,1392 'self.btn_cancel.clicked.connect':1399 'self.btn_ok.clicked.connect':1397 'self.form':1433,1437 'self.label':1357,1372 'self.object':1138 'self.reject':1400 'self.setminimumwidth':1350 'self.setwindowtitle':1347 'self.spinbox':1360,1373,1438,1446 'self.spinbox.setrange':1362 'self.spinbox.setsuffix':1367 'self.spinbox.setvalue':1365,1440 'self.spinbox.value':1456 'selobj':1702 'selobj.object':1707 'selobj.subelementnames':1711 'sep':1508,1534,1538 'sep.addchild':1527,1529,1531 'separ':1504 'serializ':1265 'set':1122 'setstat':1108,1158 'sg':1499 'sg.addchild':1533 'sg.removechild':1537 'shape':227,273,447,680,743,790,797,804,805,814,815,823,936,1716,1722,1845,2005 'shape.area':731 'shape.boundbox':719 'shape.edges':691 'shape.faces':701 'shape.length':732 'shape.makeshapefrommesh':817 'shape.shapetype':745 'shape.shells':706 'shape.solids':711 'shape.vertexes':686 'shape.volume':730 'shape.wires':696 'shell':709,747 'shift':1301 'shorthand':59,1924 'show':651,1478 'shown':1425 'sidebar':1429 'sketch':240,828,832,1755,1760,1761,1765,1838 'sketch.addconstraint':880,887,891,899,904,1815,1823 'sketch.addgeometry':855,867,1766,1776,1786,1796 'sketch.placement':837 'sketch.visibility':1841 'sketcher':105,235,236,824,834,1763,2112 'sketcher.constraint':881,888,892,900,905,1816,1824 'sketchobject':835,1764 'skill':5,45,84 'skill-freecad-scripts' 'solid':144,439,544,610,620,714,746,821 'source-github' 'sphere':462,1507,1523,1532,1939 'sphere.radius.setvalue':1525 'standard':1600,1963 'start/end':534 'state':1110,1160,1975 'step':1847 'stl':1852 'str':1201,1247,1252 'string':1202 'sub':684,1699,1709,1715,1718,1721 'sub-el':683,1698 'sub-shap':1720 'subtract':575 'subtract/cut/remove':1943 'super':1342 'surfac':738 'sweep':603 'swept':611 'symmetr':918 'system':97 'tangent':916 'task':39,70,1414,1423,2126 'techdraw':261,262 'terminolog':1933 'test':1168 'toler':820 'tool':26,117,247,1270,1349,1572,2055 'toolbar/menu':1282 'tooltip':1294,1551 'topic':2096 'topic-agent-skills' 'topic-agents' 'topic-awesome' 'topic-custom-agents' 'topic-github-copilot' 'topic-hacktoberfest' 'topic-organ':2095 'topic-prompt-engineering' 'topolog':677,2113 'torus':474 'tran':1517,1530 'trans.translation.setvalue':1519 'transform':412 'translat':72,395 'triangul':232 'trigger':1032 'true':608,618,969,984,998,1464,1470 'tupl':1257 'tutori':2071 'type':744,910,1181,1183,1185 'under':736,740 'union':571 'unit':1206,1209,1877,1902,1915,1969 'unless':1974 'updatedata':1141 'usag':1163,1401 'use':14,82,118,1882,2003 'user':1452,1899 'utf':1604 'util':274 'v':356 'v1':329,350,359 'v1.cross':340 'v1.dot':345 'v1.length':354 'v2':334,341,346,351 'v3':339 'v4':349 'v_norm.normalize':360 'valu':1907,1911 'vector':322,328,627,629,633,637,641,1221,2034 'version':1619 'vertex':689,751,770,775,780 'vertic':761,913 'via':126,1867 'view':1115 'viewprovidermybox':1114,1176 'vobj':1126,1137,1149 'vobj.object':1139 'vobj.proxy':1127 'warn':1739 'width':454,1063,1066,1067 'wiki.freecad.org':2026,2032,2038,2045,2051,2057,2067,2073,2079,2084 'wiki.freecad.org/freecad_scripting_basics)':2078 'wiki.freecad.org/gui_command)':2083 'wiki.freecad.org/introduction_to_python)':2066 'wiki.freecad.org/manual:a_gentle_introduction#manipulating_freecad_objects)':2031 'wiki.freecad.org/manual:a_gentle_introduction#vectors_and_placements)':2037 'wiki.freecad.org/manual:a_gentle_introduction#writing_python_code)':2025 'wiki.freecad.org/manual:creating_and_manipulating_geometry)':2044 'wiki.freecad.org/manual:creating_interface_tools)':2056 'wiki.freecad.org/manual:creating_parametric_objects)':2050 'wiki.freecad.org/python_scripting_tutorial)':2072 'wire':482,509,539,543,609,617,699,749 'wire1':606 'wire2':607 'within':120 'work':171,315 'workbench':25,130,225,231,237,244,251,255,259,263,1540,1550,1554,1562,2132 'workbenches-and-advanced.md':2130 'wrap':434,1961,1987 'write':7,85,2022 'x':165 'xy':830 'yaw':383 'yournam':1618","prices":[{"id":"a8f6e5c1-138e-43a2-97d6-fe25f20836e5","listingId":"f1546b93-7736-4a2a-9dfd-b49b0c1ec554","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"github","category":"awesome-copilot","install_from":"skills.sh"},"createdAt":"2026-04-18T21:49:28.116Z"}],"sources":[{"listingId":"f1546b93-7736-4a2a-9dfd-b49b0c1ec554","source":"github","sourceId":"github/awesome-copilot/freecad-scripts","sourceUrl":"https://github.com/github/awesome-copilot/tree/main/skills/freecad-scripts","isPrimary":false,"firstSeenAt":"2026-04-18T21:49:28.116Z","lastSeenAt":"2026-04-22T00:52:09.524Z"}],"details":{"listingId":"f1546b93-7736-4a2a-9dfd-b49b0c1ec554","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"github","slug":"freecad-scripts","github":{"repo":"github/awesome-copilot","stars":30743,"topics":["agent-skills","agents","ai","awesome","custom-agents","github-copilot","hacktoberfest","prompt-engineering"],"license":"mit","html_url":"https://github.com/github/awesome-copilot","pushed_at":"2026-04-21T22:20:21Z","description":"Community-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.","skill_md_sha":"dda9f63fd5341cb8c601366383c9865dae365bc3","skill_md_path":"skills/freecad-scripts/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/github/awesome-copilot/tree/main/skills/freecad-scripts"},"layout":"multi","source":"github","category":"awesome-copilot","frontmatter":{"name":"freecad-scripts","description":"Expert 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 FreeCAD scripting basics, geometry creation, FeaturePython objects, interface tools, and macro development."},"skills_sh_url":"https://skills.sh/github/awesome-copilot/freecad-scripts"},"updatedAt":"2026-04-22T00:52:09.524Z"}}