All skills
github avatar

/freecad-scripts

@c037695 official
by githubgithub/awesome-copilot40k stars
5,040

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.

Use this Skill: https://skilld.dev/gh/github/awesome-copilot/freecad-scripts

This session only. Nothing lands on disk.

referencesgeometry-and-shapes.md

≈2.2k tokens on demand. Your agent reads this file only when SKILL.md points to it.

FreeCAD Geometry and Shapes

Reference guide for creating and manipulating geometry in FreeCAD using the Part, Mesh, and Sketcher modules.

Official Wiki References

Part Module — Shape Hierarchy

OpenCASCADE topology levels (bottom to top):

Vertex → Edge → Wire → Face → Shell → Solid → CompSolid → Compound

Each level contains the levels below it.

Primitive Shapes

import Part
import FreeCAD as App

# Boxes
box = Part.makeBox(length, width, height)
box = Part.makeBox(10, 20, 30, App.Vector(0,0,0), App.Vector(0,0,1))

# Cylinders
cyl = Part.makeCylinder(radius, height)
cyl = Part.makeCylinder(5, 20, App.Vector(0,0,0), App.Vector(0,0,1), 360)

# Cones
cone = Part.makeCone(r1, r2, height)

# Spheres
sph = Part.makeSphere(radius)
sph = Part.makeSphere(10, App.Vector(0,0,0), App.Vector(0,0,1), -90, 90, 360)

# Torus
tor = Part.makeTorus(majorR, minorR)

# Planes (infinite → bounded face)
plane = Part.makePlane(length, width)
plane = Part.makePlane(10, 10, App.Vector(0,0,0), App.Vector(0,0,1))

# Helix
helix = Part.makeHelix(pitch, height, radius)

# Wedge
wedge = Part.makeWedge(xmin, ymin, zmin, z2min, x2min,
                        xmax, ymax, zmax, z2max, x2max)

Curves and Edges

# Line segment
line = Part.makeLine((0,0,0), (10,0,0))
line = Part.LineSegment(App.Vector(0,0,0), App.Vector(10,0,0)).toShape()

# Circle (full)
circle = Part.makeCircle(radius)
circle = Part.makeCircle(5, App.Vector(0,0,0), App.Vector(0,0,1))

# Arc (partial circle)
arc = Part.makeCircle(5, App.Vector(0,0,0), App.Vector(0,0,1), 0, 180)

# Arc through 3 points
arc3 = Part.Arc(App.Vector(0,0,0), App.Vector(5,5,0), App.Vector(10,0,0)).toShape()

# Ellipse
ellipse = Part.Ellipse(App.Vector(0,0,0), 10, 5).toShape()

# BSpline curve
points = [App.Vector(0,0,0), App.Vector(2,3,0), App.Vector(5,1,0), App.Vector(8,4,0)]
bspline = Part.BSplineCurve()
bspline.interpolate(points)
edge = bspline.toShape()

# BSpline with control points (approximate)
bspline2 = Part.BSplineCurve()
bspline2.buildFromPoles(points)
edge2 = bspline2.toShape()

# Bezier curve
bezier = Part.BezierCurve()
bezier.setPoles([App.Vector(0,0,0), App.Vector(3,5,0),
                  App.Vector(7,5,0), App.Vector(10,0,0)])
edge3 = bezier.toShape()

Wires, Faces, and Solids

# Wire from edges
wire = Part.Wire([edge1, edge2, edge3])   # edges must connect end-to-end

# Wire by sorting edges
wire = Part.Wire(Part.__sortEdges__([edges_list]))

# Face from wire (must be closed and planar, or a surface)
face = Part.Face(wire)

# Face from multiple wires (first = outer, rest = holes)
face = Part.Face([outer_wire, hole_wire1, hole_wire2])

# Shell from faces
shell = Part.Shell([face1, face2, face3])

# Solid from shell (must be closed)
solid = Part.Solid(shell)

# Compound (group shapes without merging)
compound = Part.Compound([shape1, shape2, shape3])

Shape Operations

# Boolean operations
union = shape1.fuse(shape2)
diff = shape1.cut(shape2)
inter = shape1.common(shape2)

# Multi-fuse / multi-cut
multi_fuse = shape1.multiFuse([shape2, shape3, shape4])

# Clean seam edges after boolean
clean = union.removeSplitter()

# Fillet (round edges)
filleted = solid.makeFillet(radius, solid.Edges)
filleted = solid.makeFillet(radius, [solid.Edges[0], solid.Edges[3]])

# Chamfer
chamfered = solid.makeChamfer(distance, solid.Edges)
chamfered = solid.makeChamfer(dist1, dist2, [solid.Edges[0]])  # asymmetric

# Offset (shell/thicken)
offset = solid.makeOffsetShape(offset_distance, tolerance)
thick = solid.makeThickness([face_to_remove], thickness, tolerance)

# Section (intersection curve of solid with plane)
section = solid.section(Part.makePlane(100, 100, App.Vector(0,0,5)))

Extrude, Revolve, Loft, Sweep

# Extrude face or wire
extruded = face.extrude(App.Vector(0, 0, 10))    # direction vector

# Revolve
revolved = face.revolve(
    App.Vector(0, 0, 0),     # center
    App.Vector(0, 1, 0),     # axis
    360                       # angle (degrees)
)

# Loft between wires/profiles
loft = Part.makeLoft([wire1, wire2, wire3], True)   # solid=True

# Sweep (pipe)
sweep = Part.Wire([path_edge]).makePipe(profile_wire)

# Sweep with Frenet frame
sweep = Part.Wire([path_edge]).makePipeShell(
    [profile_wire],
    True,    # make solid
    False    # use Frenet frame
)

Topological Exploration

shape = obj.Shape

# Sub-element access
shape.Vertexes          # [Vertex, ...]
shape.Edges             # [Edge, ...]
shape.Wires             # [Wire, ...]
shape.Faces             # [Face, ...]
shape.Shells            # [Shell, ...]
shape.Solids            # [Solid, ...]

# Vertex properties
v = shape.Vertexes[0]
v.Point                 # FreeCAD.Vector — the 3D coordinate

# Edge properties
e = shape.Edges[0]
e.Length
e.Curve                 # underlying geometric curve (Line, Circle, BSpline, ...)
e.Vertexes              # start and end vertices
e.firstVertex()         # first Vertex
e.lastVertex()          # last Vertex
e.tangentAt(0.5)        # tangent at parameter
e.valueAt(0.5)          # point at parameter
e.parameterAt(vertex)   # parameter at vertex

# Face properties
f = shape.Faces[0]
f.Area
f.Surface               # underlying geometric surface (Plane, Cylinder, ...)
f.CenterOfMass
f.normalAt(0.5, 0.5)    # normal at (u, v) parameter
f.Wires                 # bounding wires
f.OuterWire             # or Wires[0]

# Bounding box
bb = shape.BoundBox
bb.XMin, bb.XMax, bb.YMin, bb.YMax, bb.ZMin, bb.ZMax
bb.Center, bb.DiagonalLength
bb.XLength, bb.YLength, bb.ZLength

# Shape properties
shape.Volume
shape.Area
shape.CenterOfMass
shape.ShapeType         # "Solid", "Compound", "Face", etc.
shape.isValid()
shape.isClosed()

Sketcher Constraints Reference

Constraint Syntax Description
Coincident ("Coincident", geo1, pt1, geo2, pt2) Points coincide
Horizontal ("Horizontal", geo) Line is horizontal
Vertical ("Vertical", geo) Line is vertical
Parallel ("Parallel", geo1, geo2) Lines are parallel
Perpendicular ("Perpendicular", geo1, geo2) Lines are perpendicular
Tangent ("Tangent", geo1, geo2) Curves are tangent
Equal ("Equal", geo1, geo2) Equal length/radius
Symmetric ("Symmetric", geo1, pt1, geo2, pt2, geoLine) Symmetric about line
Distance ("Distance", geo1, pt1, geo2, pt2, value) Distance between points
DistanceX ("DistanceX", geo, pt1, pt2, value) Horizontal distance
DistanceY ("DistanceY", geo, pt1, pt2, value) Vertical distance
Radius ("Radius", geo, value) Circle/arc radius
Angle ("Angle", geo1, geo2, value) Angle between lines
Fixed ("Fixed", geo) Lock geometry

Point indices: 1 = start, 2 = end, 3 = center (circles/arcs). External geometry index: -1 = X axis, -2 = Y axis.

Mesh Operations

import Mesh

# Create from file
mesh = Mesh.Mesh("/path/to/model.stl")

# Create from topology (vertices + facets)
verts = [[0,0,0], [10,0,0], [10,10,0], [0,10,0], [5,5,10]]
facets = [[0,1,4], [1,2,4], [2,3,4], [3,0,4], [0,1,2], [0,2,3]]
mesh = Mesh.Mesh([verts[f[0]] + verts[f[1]] + verts[f[2]] for f in facets])

# Mesh properties
mesh.CountPoints
mesh.CountFacets
mesh.Volume
mesh.Area
mesh.isSolid()

# Mesh operations
mesh.unite(mesh2)       # Boolean union
mesh.intersect(mesh2)   # Boolean intersection
mesh.difference(mesh2)  # Boolean difference
mesh.offset(1.0)        # Offset surface
mesh.smooth()           # Laplacian smoothing

# Export
mesh.write("/path/to/output.stl")
mesh.write("/path/to/output.obj")

# Convert Part → Mesh
import MeshPart
mesh = MeshPart.meshFromShape(
    Shape=part_shape,
    LinearDeflection=0.1,
    AngularDeflection=0.523599,  # ~30 degrees
    Relative=False
)

# Convert Mesh → Part
import Part
tolerance = 0.05
shape = Part.Shape()
shape.makeShapeFromMesh(mesh.Topology, tolerance)
solid = Part.makeSolid(shape)

Source: SKILL.md on GitHub

No alerts16d4 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    This skill is a technical reference for FreeCAD Python scripting. It provides code templates and API documentation for 3D modeling, GUI creation, and automation. No malicious patterns or security risks were detected.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at c037695. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 20 hours ago.

Activeupdated 6 months ago
  • Python
  • freecad
  • cad
  • modeling
  • parametric
  • macros
  • geometry
  • part-design
  • sketcher
  • pyside

README badge

README badge for github/awesome-copilot/freecad-scripts

Writes Python scripts for FreeCAD's embedded interpreter, generating geometry creation, parametric FeaturePython objects, sketches, macros, and GUI tools using the FreeCAD Python API. Covers Part/Mesh/Sketcher workbenches, Coin3D scenegraph manipulation via Pivy, PySide dialogs, and custom workbench commands.

Generated from the current SKILL.md.

Does this skill work with all FreeCAD versions?
FreeCAD 0.19+ is recommended; version 0.21+/1.0+ is needed for the latest API features. The skill covers the core Python API stable across these versions.
Can I use this skill to create GUI dialogs?
Yes. The skill covers PySide2/Qt GUI tools within FreeCAD, which is bundled with FreeCAD installations.
Does this skill support mesh-to-solid conversion?
Yes. The skill includes examples of converting between mesh and Part shapes using MeshPart.meshFromShape() and Part.makeShapeFromMesh().
Can I create custom workbenches with this skill?
Yes. The skill covers creating custom workbenches, Gui Commands, and FeaturePython objects for parametric design.

Generated from the current SKILL.md. These answers refresh after source changes.