FARGO 3D
Fargo 3D is Printing 0%
All Articles / AI CAD Skill & Agent Pack
7 min read View Source
Package File#articles#ai-cad#skills#agents#solidcraft#figcraft

FreeCAD OpenCASCADE B-Rep, Printable STL & 3D Viewer Skill (`freecad-step-builder`)

Parametric 3D CAD solid modeling skill using headless FreeCAD OpenCASCADE (FreeCADCmd) to generate watertight STEP, FCStd, printable STL files, and standalone 3D WebGL assembly viewers for any CAD project (<ProjectName>).

This skill governs parametric 3D OpenCASCADE B-Rep solid modeling, boolean interference verification, .step/.stl export, and standalone interactive 3D WebGL viewer generation (<ProjectName>_3D_Assembly_Viewer.html) for any CAD project (<ProjectName>) using headless FreeCAD (FreeCADCmd).


0. Step 0: Resolve FreeCADCmd via .cad-tools.json or User Prompt

Do NOT search the filesystem to guess how FreeCAD is installed.

  1. Check .cad-tools.json in the workspace root for "freecad_cmd" (or check if the user already provided the FreeCAD command/path in the conversation or project AGENTS.md).
  2. If not yet configured, ask the user (or have the Designer / QA Inspector agent ask via ask_question) how FreeCAD is installed:
    • Flatpak: flatpak run --command=FreeCADCmd org.freecad.FreeCAD <script.py>
    • Native package: freecadcmd <script.py> or FreeCADCmd <script.py>
    • AppImage / Custom path: /path/to/FreeCAD.AppImage -c <script.py>
    • Or Not installed (use SolidCraft only).
  3. Save the command in .cad-tools.json and guard script entrypoints with:
    if __name__ in ("__main__", "<script_stem>"):
        build_and_export()
    
    because FreeCADCmd sets __name__ to the script filename stem rather than "__main__".

1. Standard Project Output Structure (<ProjectName>)

Blueprint-First Gate: Do NOT build 3D FreeCAD solids until the 1:1 mm orthographic 2D SVG blueprints (<ProjectName>_Side_View.svg, <ProjectName>_Front_View.svg, <ProjectName>_Top_View.svg) have been generated and reviewed by the user.

All 3D deliverables are modeled in millimeters (\(1\text{ unit} = 1.0\text{ mm}\)) in assembled world coordinates inside <ProjectName>/CAD/:

Deliverable Type Path Pattern Purpose
Parametric FreeCAD Project CAD/<ProjectName>_Full_Assembly.FCStd & CAD/FCStd/<PartName>.FCStd Native FreeCAD document with a Params Spreadsheet::Sheet and separate PartDesign::Body containers holding sequential Sketcher::SketchObject + PartDesign::Pad / PartDesign::Pocket features for human editing.
Individual Component STEP CAD/STEP/<PartName>.step Exact OpenCASCADE B-Rep solid for CAD interchange.
Individual Component STL CAD/STL/<PartName>.stl High-resolution watertight mesh (LinearDeflection=0.15, AngularDeflection=0.35) for 3D printing.
Sub-Assembly STEP CAD/STEP/<ProjectName>_Parts_Assembly.step Multi-body STEP assembly of all printable components.
Full Hardware Assembly CAD/STEP/<ProjectName>_Full_Assembly.step Complete assembly including host hardware and payload reference solids.
Interactive 3D WebGL Viewer <ProjectName>_3D_Assembly_Viewer.html Zero-dependency standalone HTML/WebGL viewer with Orbit/Pan/Zoom, Explode slider (0%..100%), camera presets, and per-part visibility toggles.

2. Mandatory Step-by-Step Parametric PartDesign::Body Build History Standard

CRITICAL RULE: Never Export a Collapsed Static Part::Feature Solid as the Primary .FCStd Model: Instead of fusing/cutting raw Part.Shape objects in Python memory and assigning the final shape to a single non-editable Part::Feature (obj.Shape = final_shape), always construct each part as a native PartDesign::Body with a step-by-step feature history driven by a Spreadsheet::Sheet (Params):

  1. Create a Parametric Spreadsheet::Sheet (Params):
    • Add a Spreadsheet::Sheet named "Params" to the FreeCAD document and register every key dimension (board/payload lengths, fan hole spacing, PSU cradle width/height, wall thicknesses, clip overhangs, dovetail clearances) with human-readable labels in Column A, numeric values in Column B, and aliases via sheet.setAlias("B2", "fan_hole_spacing").
  2. Build Each Component as a Separate PartDesign::Body:
    • Create one PartDesign::Body per printable part (doc.addObject("PartDesign::Body", part_name)).
    • Add sequential features inside each PartDesign::Body so a human opening the .FCStd file in FreeCAD GUI sees every step in the Model Tree and can double-click any sketch or pad/pocket to edit it:
      • Step A (Sketcher::SketchObject): sk = body.newObject("Sketcher::SketchObject", "Sketch_<FeatureName>"), attach to the appropriate plane (XY_Plane, XZ_Plane, YZ_Plane or a datum plane offset), add closed wire geometry (Part.LineSegment, Part.Circle, Part.ArcOfCircle), and apply Sketcher.Constraint('Coincident', ...) constraints.
      • Step B (PartDesign::Pad Additive Extrusion): pad = body.newObject("PartDesign::Pad", "Pad_<FeatureName>"), set pad.Profile = sk, pad.Length = ... (or bind to spreadsheet via pad.setExpression("Length", "<<Params>>.wall_thickness")).
      • Step C (PartDesign::Pocket Subtractive Cutout / Bore / Duct / Mortise): pocket = body.newObject("PartDesign::Pocket", "Pocket_<FeatureName>"), set pocket.Profile = sk_cut, pocket.Type = 0 (Dimension) or 1 (ThroughAll), and pocket.Reversed = True/False.
  3. Group Reference Hardware Separately:
    • Place non-printed reference hardware solids (e.g., SBC board + heatsink, PSU brick, 120 mm fans, host printer) inside a App::DocumentObjectGroup named "Reference_Hardware" so they are cleanly separated from the editable PartDesign::Body components.

3. Technical CAD & DFM Design Patterns (User Intent to Engineering Implementation)

  1. Step-by-Step PartDesign::Body Sketch-to-Pad/Pocket Modeling:
    • Construct cantilever webs, fan shrouds/plenums, PSU cradles, snap-fit clips, clevis hooks, and dovetail tenons/mortises as individual named Sketcher::SketchObject + PartDesign::Pad / PartDesign::Pocket steps inside each part's PartDesign::Body.
  2. Cantilever Snap-Fit Retention Clips & Overhang Ledges (Snap-Fit Retention Tabs):
    • User intent: "Hold the power supply or board in place with overhangs or clips."
    • CAD implementation: Model vertical Cradle Side-Walls that constrain lateral \((X, Y)\) translation, topped by Cantilever Snap-Fit Retention Ledges (Overhang Hooks) with a \(1.5\text{ to }2.5\text{ mm}\) inward catch lip, a \(30^\circ\text{--}45^\circ\) top Lead-In Insertion Chamfer (so the component snaps down past the flex tab during installation), and a \(0.30\text{ mm}\) vertical/lateral clearance allowance around the payload envelope.
  3. Coplanar Build-Plate Datum Face (Zero-Stickout Flush Bosses):
    • User intent: "Make the round hole part flush with the arm so it's flat on the bed to print."
    • CAD implementation: Make the axial length of cylindrical mounting bosses equal to the structural web thickness and align their outer faces to be strictly coplanar (\(\Delta X = 0\)). Eliminating out-of-plane boss stickout ensures the entire outer side face serves as a flat \(Z_{\text{print}} = 0\) build-plate datum requiring zero supports.
  4. Orthogonal Anti-Rotation Return Flange (Corner-Wrapping Reaction Pad):
    • User intent: "Wrap the front corner so the sleeve on the round peg can't rotate."
    • CAD implementation: Extending a \(90^\circ\) Orthogonal Return Flange around the chassis corner onto a flat orthogonal datum face constrains rotation (\(\theta = 0\)) and resolves cantilevered bending moment (\(M = F \cdot d\)) into a tension-at-pin / compression-at-pad force couple.
  5. Interlocking Cleat & Shrouded Clevis Gravity Joint:
    • User intent: "Have the top piece hook straight down over the front leg."
    • CAD implementation: Terminate the lower return flange in an upward Male Cleat Tang with a rear Receiver Channel and a lower Horizontal Bearing Shoulder (Step Ledge). Form a mating Female Clevis Saddle on the upper cantilever rail flanked by Axial Retention End-Cheeks (Shrouded Side Flanges) that capture the cleat laterally and prevent the lower brace from sliding off its mounting boss.
  6. Shouldered Half-Lap Dovetail Ledger Joint (Blind Mortises + Integral Drop-In Tenons):
    • User intent: "Have a lip that the center piece rests on with dovetails on top instead of separate bowties."
    • CAD implementation: Step the inner mating edge into a Lower Half-Lap Bearing Ledger (carrying vertical shear in direct compression) and cut Blind (Stopped) Female Dovetail Mortises into the upper half. Extrude Integral Male Dovetail Tenons (\(0.20\text{ mm}\) XY clearance allowance) on the ends of the spanning cross-member so it drops straight in from the top and locks lateral tension (\(F_X\)) and in-plane racking without separate butterfly/dutchman keys.
  7. Stepped Edge Rabbet Relief (Rabbet / Rebate Cut) for Overhanging Lids:
    • User intent: "Reverse L notch at the top back to clear a cover that overhangs the front by 5 mm."
    • CAD implementation: Cut a two-sided rectangular Edge Rabbet Relief (e.g., \(6\text{ mm}\) deep x \(5\text{ mm}\) high) along the upper-rear edge to clear the overhanging cover lip while preserving a lower Undercut Datum Contact Toe that reaches back to bear against the primary machine datum plane.
  8. FDM Bore Shrinkage Allowance & Coaxial Flange Counterbore:
    • User intent: "Open up a tight spool holder hole by 0.5 mm radius."
    • CAD implementation: Apply an ISO Free-Running Slip-Fit Clearance Allowance (\(\Delta R = +0.50\text{ to }+0.80\text{ mm}\), or \(+1.0\text{ to }+1.6\text{ mm}\) diametral clearance) on large FDM-printed bores (\(\varnothing 30\text{--}75\text{ mm}\)) to compensate for inner-perimeter shrinkage and seam bulge, paired with a coaxial Counterbore clearing the mounting base flange.

4. Dual Automated Verification Gates

  • Gate 1 (Manifold & Zero-Clash Gate):
    • Assert solid.isValid() == True and solid.Volume > 0 for every component.
    • Assert part_solid.common(host_reference_solid).Volume < 0.001 (\(0.0000\text{ mm}^3\) interference with the host machine, overhanging covers, doors, and keep-out envelopes).
    • Assert part_i.common(part_j).Volume < 0.001 (\(0.0000\text{ mm}^3\) boolean overlap across all mating components).
  • Gate 2 (Conditional Print Bed Bounding-Box Gate ONLY when "is_3d_printed": true):
    • When "is_3d_printed": true in .cad-tools.json, assert bbox.XLength <= SAFE_LIMIT and bbox.YLength <= SAFE_LIMIT and bbox.ZLength <= SAFE_LIMIT.
    • When "is_3d_printed": false (e.g., Game Design, Digital Twin, CNC, or Unconstrained CAD), skip print-bed bounding-box limits.
Back to Articles Hub Back to Top