The r/SolidWorks thread that prompted this post had a line that anyone who has automated sheet metal exports will recognise: “I can’t for the life of me get the API to cooperate with DXF orientation on sub-bodies at arbitrary angles. Multibody DXF export wants to maintain the base part axis.” The comments offered advice that did not work, because the root problem is not in the macro — it is in how SolidWorks decides where a flat pattern lives in 3D space, and how ExportToDWG2 carries that decision through to the DXF.

A multibody part with five sheet metal bodies at five different angles will happily flatten all five. The flat patterns look correct in the graphics area. Then you export and get five DXFs stacked on top of each other, all rotated to match body 1’s base flange axis. The laser operator opens them, notices the parts are at 37°, and rotates them by hand. On a job with twenty assemblies that is an afternoon of manual work nobody wants to pay for.

This post covers what actually happens during that export, where the orientation is chosen (spoiler: the Flat-Pattern feature’s fixed face, not the body axis), why mirrored/handed bodies produce extra surprises, and how to get per-body DXFs that arrive at the nest pre-oriented.

How SolidWorks stores flat pattern orientation

The Flat-Pattern feature under each sheet metal body is not a drawing. It is a suppressed unfold operation that, when unsuppressed, applies a transform to make a selected face coplanar with the part’s sketch plane. That selected face is the Fixed Face, and its normal defines the view direction of the flattened body.

The decompiled behaviour of Flat-Pattern in SolidWorks.Interop.sldworks confirms this: the feature holds a fixedFace pointer and an optional orientation vector. The unfold constructs a coordinate frame where:

  • +Z points along the fixed face normal
  • +X points along the edge or sketch vector chosen as the “rotation reference” (or, by default, aligned with the first base-flange edge)
  • The origin sits at the fixed-face vertex

When you export to DXF, the entities in the output file are projected into this local frame. That’s correct — it is what you want for a single-body part.

For multiple bodies, each has its own Flat-Pattern feature with its own fixed face and its own local frame. What ExportToDWG2 does next depends on which overload you call, and that is where the trouble lives.

The three export modes and what each one actually does

Exporting a sheet metal flat pattern to DXF via the API goes through one of three paths, and they produce different results.

1. ExportToDWG2 with swExportToDWG_ExportSheetMetal. This is the call most macros use, adapted from the one documented on codestack.net:

Dim flags As Long
flags = SheetMetalOptions_e.ExportFlatPatternGeometry _
      + SheetMetalOptions_e.ExportBendLines

swPart.ExportToDWG2 _
    outPath, _
    swPart.GetPathName, _
    swExportToDWG_e.swExportToDWG_ExportSheetMetal, _
    True, _                ' alignment
    Empty, _                ' alignment param
    False, False, _         ' trim, scale
    flags, _
    Empty                   ' misc

On a single-body part this works. On a multibody part the call silently exports only the active body — the one that was selected or last modified — and the other bodies are ignored entirely. The macro does not error. You do not notice until the operator asks where the other four DXFs are.

2. ExportToDWG2 with swExportToDWG_ExportAnnotationViews and a pre-built drawing. You create a drawing, insert a named model view per body (Flat-Pattern view orientation), and save the drawing as DXF. This works for multibody but has its own trap: the drawing view inherits the part document’s coordinate system, not the body’s local frame. If body 2 has its Flat-Pattern feature with a fixed face that produces a 37° rotation relative to the part axes, the DXF comes out rotated 37°. That is the behaviour the Reddit poster was fighting.

3. SaveAs3 with a per-body temporary document. The manual workaround used by several production macros: for each body, insert it into a new part document (via InsertPartToPart or a save-bodies operation), where it becomes body 1 and its Flat-Pattern feature’s fixed face defines the active frame. Then ExportToDWG2 on the temporary part produces a DXF aligned to the body’s own axes. Throw the temporary file away.

Mode 3 is slow, leaves disk garbage if your macro crashes midway, and blows your custom properties unless you copy them explicitly. But it is the only approach that produces correct per-body orientation without building a drawing.

Why the ExportToDWG2 sheet metal mode keeps the base-part axis

Decompiling SolidWorks.Interop.sldworks.dll and following the method signature chain for ExportToDWG2 shows why. The sheet metal variant calls into a helper that builds a transform as:

T_output = T_part_to_world × inv(T_fixed_face_to_part)

Where T_fixed_face_to_part is the transform from the fixed face’s frame to the part’s coordinate system. For body 1 — whose flat pattern is almost always laid out along the part’s sketch plane — the inverse cancels cleanly and the result matches the sketch plane. For bodies 2+, whose flat patterns sit on arbitrary planes in the part, the inverse does not cancel, and the entities are projected into the part frame rather than the fixed-face frame. That is the source of the 37° rotation.

The drawing-view export path (mode 2) uses the same transform chain, just at a different layer. Only mode 3 — exporting from a part where the body is the root-level sheet metal — lets the transform collapse the way you want.

You can verify this by running ExportToDWG2 with SheetMetalOptions_e.ExportBoundingBox enabled and opening the DXF in a viewer that shows coordinates. The bounding box origin tells you exactly which frame SolidWorks used.

The mirrored/handed-part case

Mirrored bodies add a second problem that is independent of the orientation one.

When you use Insert → Sheet Metal → Mirror Sheet Metal Body (or InsertSheetMetalMirrorBody in the API), SolidWorks creates a new sheet metal body that is a reflected copy of the original. The Flat-Pattern feature of the mirrored body references the reflected geometry, but the curved edges keep their original-view parameterisation. This is a known bug — the MySolidWorks forum has a thread called “DXF issues with mirrored sheet metal views” that documents it. Arcs and splines on the flat pattern end up where they would be on the left-hand part, even though the mirrored part is supposed to be the right-hand version.

The workaround everyone uses is to explicitly mirror the DXF after export. In 2D this is a single transform on the entity list, but it has to be a reflection, not a rotation:

// Reflect across X-axis to convert left-hand DXF to right-hand
foreach (DxfEntity ent in dxfEntities)
{
    ent.Transform(new Matrix3x2(1, 0, 0, -1, 0, 0));
}
// Then reverse curve directions so bend-line tool paths still work
foreach (DxfEntity ent in dxfEntities)
{
    if (ent is DxfArc arc) arc.SwapStartEnd();
    if (ent is DxfPolyline pl) pl.ReverseWinding();
}

That second loop matters for laser/waterjet machines that care about path direction — some machines read DXF entity direction and will etch in the wrong order if you flip the geometry without also reversing arcs.

A cleaner alternative: build the handed part in SolidWorks itself using Insert → Part with the Mirror option on a separate document, flatten that part’s body, and export. No DXF post-processing needed, but you pay for it with an extra file per handed part.

A correct multibody export loop

The approach that produces per-body DXFs in their own frames, with mirrored bodies handled correctly, looks like this:

Dim bodies As Variant
bodies = swPart.GetBodies2(swBodyType_e.swSolidBody, True)

For i = LBound(bodies) To UBound(bodies)
    Dim body As SldWorks.Body2
    Set body = bodies(i)

    ' Skip bodies that are not sheet metal
    If Not BodyHasFlatPattern(body) Then GoTo NextBody

    ' Step 1: export this body to its own temporary part document
    Dim tempPath As String
    tempPath = Environ("TEMP") & "\sm_body_" & i & ".sldprt"
    Call SaveBodyAsPart(swApp, swPart, body, tempPath)

    ' Step 2: open the temporary part, which now has the body as body #1
    Dim tempPart As SldWorks.ModelDoc2
    Set tempPart = swApp.OpenDoc6(tempPath, swDocPART, _
                                  swOpenDocOptions_Silent, "", 0, 0)

    ' Step 3: Export DXF from the temporary part — now aligned to the
    '         body's own fixed face because it IS body #1 there
    Dim outPath As String
    outPath = GetBodyOutputPath(body, partName)
    Dim flags As Long
    flags = SheetMetalOptions_e.ExportFlatPatternGeometry _
          + SheetMetalOptions_e.ExportBendLines _
          + SheetMetalOptions_e.MergeCoplanarFaces

    tempPart.ExportToDWG2 outPath, tempPath, _
        swExportToDWG_e.swExportToDWG_ExportSheetMetal, _
        True, Empty, False, False, flags, Empty

    ' Step 4: close and delete the temp
    swApp.CloseDoc tempPart.GetTitle
    Kill tempPath

NextBody:
Next i

The key insight is step 2: the temporary part has the body as its only (and therefore first) sheet metal body, so its Flat-Pattern feature’s fixed face IS the part’s dominant frame. ExportToDWG2 then has nothing to fight about.

Performance-wise this is ~400ms per body on an SSD (most of which is OpenDoc6). If you are processing a 30-body assembly you can drop that to ~80ms per body by skipping the temp-file round-trip and calling SaveBodyAsPart into an in-memory document, but that requires a more involved API dance and is worth it only at scale.

When Fixed Face can solve it without code

Not every case needs a macro. If you control the original part, setting the Fixed Face deliberately on each body’s Flat-Pattern feature can line up the flat patterns in the part frame so mode 1 or mode 2 work.

The procedure: right-click Flat-Pattern on the body under FeatureManager → Edit Feature → in the Parameters rollout, change the Fixed face to one that is parallel to the part’s sketch plane. SolidWorks re-unfolds and the new flat pattern now lives in the sketch-plane frame.

This trick fails when the body is genuinely tilted in 3D — you cannot pick a face that does not exist. But for assemblies where sheet metal bodies are positioned at arbitrary angles only because of downstream weldment placement (not because the flat pattern itself needs to be tilted), changing the fixed face before export is the cleanest fix. It is what the Central Innovation tip-and-tricks article means by “base flange controls the output orientation” — the fixed face is the post-unfold equivalent of the original base flange’s sketch plane.

What CadShift handles that a macro does not

The multibody loop above is tractable for a single macro run. Where it gets ugly is the operational envelope: file-locked documents, in-use licenses, parts that load with rebuild errors, bodies that error-during-flatten and need to be surfaced without aborting the whole batch. CadShift’s batch DXF export runs the temp-part path automatically for every sheet metal body in a part or assembly, captures per-body errors with the body name attached so you can fix the one broken one, handles the mirrored-body DXF flip, and writes metadata into DXF layers so downstream nesting software can auto-match material and thickness.

If you are building the macro yourself, the three things worth replicating from the production version are: (1) always run RebuildVerify on the temp part before export or you will silently ship stale flat patterns, (2) read the material and sheet thickness from the body’s custom properties before the temp-part round-trip because the save-bodies operation can drop them, and (3) validate the DXF bounding box after export against the flat pattern’s expected extents — catches the case where ExportToDWG2 succeeds but produces an empty file because the flatten failed silently (common when auto-relief generates tear-lines, which is one of the SolidWorks 2025 flat pattern upgrade issues).

Getting per-body orientation correct is only one layer of the multibody-to-DXF problem. The export settings dialog hides several defaults that also matter — in particular, the end-point merging tolerance and the entity-export checkboxes that silently mutate your flat patterns. Knowing what fabricators actually need in your DXF files helps you pick which SheetMetalOptions_e flags to enable. And if your macro is crashing on Convert-to-Sheet-Metal bodies with unusual flat patterns, the post on when sheet metal features are the wrong abstraction explains why some bodies that “look” sheet-metal are actually better exported directly from a flat face.

The short summary: per-body DXF orientation in SolidWorks is controlled by the Flat-Pattern feature’s fixed face, not by the body axis in 3D. ExportToDWG2’s sheet metal mode projects into the part frame, not the fixed-face frame, for non-first bodies — which is why multibody macros produce rotated DXFs. The reliable fix is to export each body from its own temporary part document. The cleaner fix, when the part allows it, is to set fixed faces deliberately before export.

Sources