FreeCAD Script: Extract Edge Curves from a Face

Extracting edge curves from a solid face in FreeCAD can be automated using Python through the built-in Part module. By navigating FreeCAD's Boundary Representation (B-Rep) hierarchy, you can target a specific face of an object, access its boundary edges, and extract either the raw mathematical curves or generate new geometric edge objects directly in your active document.

Understanding the Geometry Hierarchy

In FreeCAD's Part module, topological entities follow a strict hierarchy:

  1. Solid / CompSolid: The complete 3D body.
  2. Face: A bounded surface on the solid.
  3. Wire: A sequence of connected edges forming the face boundary (outer perimeter or inner holes).
  4. Edge: The topological segment bounding a surface.
  5. Curve: The underlying mathematical geometry of an edge (e.g., GeomLine, GeomCircle, GeomBSplineCurve).

To extract edge data, you retrieve the Face from the object's Shape, iterate through its Edges collection, and access either the topological Edge or its underlying Curve.

Step-by-Step Python Script

The following script accesses the first face of an active object, extracts its bounding edges, and creates separate parametric edge objects in the FreeCAD tree.

import FreeCAD as App
import Part

# Get active document and selected or targeted object
doc = App.ActiveDocument
obj = doc.ActiveObject

if not obj or not hasattr(obj, "Shape"):
    raise ValueError("Please select or specify an object with valid shape geometry.")

# Target a specific face (for example, the first face)
target_face = obj.Shape.Faces[0]

# Iterate through each edge of the face
for index, edge in enumerate(target_face.Edges):
    # 1. Access the underlying mathematical curve geometry
    curve_geometry = edge.Curve
    print(f"Edge {index} Curve Type: {type(curve_geometry)}")

    # 2. Create a new document object from the edge
    edge_feature = doc.addObject("Part::Feature", f"ExtractedEdge_{index}")
    edge_feature.Shape = edge

# Recompute the document to display new objects in the tree
doc.recompute()

Accessing Curve Parameters Directly

If you do not need to create document objects, but instead need coordinates, tangent vectors, or points along the boundary for calculations, query the Curve object directly:

for edge in target_face.Edges:
    curve = edge.Curve
    
    # Get start and end parameter range
    first_param = edge.FirstParameter
    last_param = edge.LastParameter
    
    # Calculate 3D points at specific parameters
    start_point = curve.value(first_param)
    end_point = curve.value(last_param)
    mid_point = curve.value((first_param + last_param) / 2.0)
    
    print(f"Start: {start_point}, Mid: {mid_point}, End: {end_point}")

Extracting Ordered Boundary Wires

A face often contains both outer boundaries and inner cutouts (holes). If you need the edges grouped by continuous loops, access target_face.Wires instead:

# Outer wire is usually the first wire
outer_wire = target_face.Wires[0]

# Extract edges specifically from the outer boundary loop
for edge in outer_wire.Edges:
    # Process outer boundary edge
    pass

This ensures that edges remain logically connected in sequential order around the perimeter of the face.