Skip to content

Write TableEntity to DXF - #1330

Open
2805028 wants to merge 5 commits into
DomCR:masterfrom
2805028:feat/dxf-tableentity-write
Open

2805028 wants to merge 5 commits into
DomCR:masterfrom
2805028:feat/dxf-tableentity-write

Conversation

@2805028

@2805028 2805028 commented Oct 23, 2026

Copy link
Copy Markdown

Resolves #1001

Related: #1085, #1217, #1324 (round-trip and table writing context)

Write TableEntity (ACAD_TABLE) to DXF

Description

The DXF writer currently drops TableEntity on purpose:
DxfSectionWriterBase.isEntitySupported lists it under "Entity type not implemented", so
every DXF export silently loses tables (a notification is raised, the entity is skipped).
The DXF reader already implements the full AcDbTable grammar
(readTableEntity in DxfSectionReaderBase), and the DWG writer already writes tables, so
the DXF writer is the missing half.

What this PR does

  1. Removes TableEntity from the "not implemented" exclusion list in isEntitySupported.

  2. Adds a case TableEntity branch to writeEntity (placed before case Insert,
    since a TableEntity is-an Insert and would otherwise be caught by the insert branch).

  3. Implements writeTableEntity/writeTableCell, emitting the layout real AutoCAD files
    use (verified against samples/sample_AC1032_ascii.dxf) and that readTableEntity
    consumes:

    100 AcDbBlockReference
      2 <table block name>, 10/20/30 insertion point, 41/42/43 scales, 50 rotation, 210 normal
    100 AcDbTable
      280 version
      342 table style handle (when set)
      11/21/31 horizontal direction
      90 value flag
      91 rows count / 92 columns count
      93..96 override flags (only when non-default)
      141* row heights, 142* column widths
      per cell (row-major):
        171 type, 172 edge flags, 173 merged value, 174 autofit,
        175/176 border width/height, 178 virtual edge flag, 145 rotation
        per content: 301 "CELL_VALUE" + the existing writeCadValue block (… 304 ACVALUE_END)
    

    The ACAD_TABLE class entry lands in the CLASSES section automatically:
    TableEntity already implements IDxfClassDefined and CadWriterBase.UpdateDxfClasses
    picks it up.

Scope notes (what is intentionally not in this PR)

  • Per-cell style overrides (background/content colors, border colors/lineweights,
    63/64/275..279/65..68) are not written yet: the entity reader's border-code mapping
    differs from the DXF reference (279→Top, 275→Right, 276→Bottom, 278→Left), so writing
    them today would round-trip into scrambled borders. Aligning the reader with the
    reference should come first; the writer can then emit the block.
  • The table cache block content (the anonymous block with the rendered grid) and the
    TABLECONTENT object (343) are not written; CadTableEntityTemplate collects the
    343 handle but never uses it, so nothing is lost for the ACadSharp object model.
  • Merged-cell ranges beyond Cell.MergedValue and break data are not written.
  • The DWG writer is not touched. When the WriterSingleObjectTests.SingleTableEntity case
    is round-tripped through DWG, the cell contents do not survive (pre-existing behavior,
    the case asserted nothing before this PR); the DXF half of that case is now asserted on
    every version.

Tests

  • src/ACadSharp.Tests/IO/TableEntityDxfWriteTests.cs (new file, 2 theories x
    AC1027/AC1032): WriteReadTableEntityAscii / WriteReadTableEntityBinary. Each builds a
    synthetic document with an anonymous block *T1, a table style reference, a 2x3 grid and
    per-cell string values (R0C0..R1C2), writes the DXF (ASCII or binary) and asserts the
    round trip: exactly one TableEntity in model space, Block resolved, 2 rows / 3
    columns, and the corner cell texts R0C0 / R1C2 intact. All 4 cases are red on
    master ("The collection was empty" — the entity is skipped by the writer) and green
    with the change.
  • WriterSingleObjectTests.SingleTableEntity (the roundtrip case suggested by the
    contributing guide): filled in with a valid 2x3 table and real assertions for the DXF
    format on every version (1e12f19); previously it built an invalid table and its
    assertions were disabled by a TODO. The DXF assertions pass on all six versions
    (AC1015..AC1032).

Full suite (ACadSharp.Tests, net9.0, Release): 2496 tests — 2493 passed, 1–2 pre-existing
(flaky) failures, 2 skipped. They fail identically on unmodified master
(Tables.DimensionStyleTests.GetLinearMeasurementText — decimal-comparator culture issue;
CadDocumentTests.AddCadObjectStressTest — intermittent, passed in this run). No new
failures. During bring-up
the writer also gained a guard for cell contents with no value (CadValue.Value == null,
common in empty cells of real files), without which re-writing the bundled samples
crashed.

AutoCAD compatibility

This PR is verified with an ACadSharp writer/reader round trip. Opening the produced file
in AutoCAD (and AUDIT) still needs a real AutoCAD run — the known table-style AUDIT issue
of freshly created documents (see the accompanying TABLESTYLE structure issue) applies to
any file written from a new CadDocument() and is independent of this change.

AI development

This change was developed with AI assistance under human supervision; the submitter
self-reviewed the diff, verified group codes against the repository samples and the
readTableEntity grammar, and ran the full test suite.

Unkar added 5 commits October 23, 2026 01:03
Remove the TableEntity exclusion from the DXF writer and implement
writeTableEntity/writeTableCell, following the layout AutoCAD writes (and the
DXF reader consumes): AcDbBlockReference data, then the AcDbTable section with
version, style handle, horizontal direction, value flag, grid counts, row
heights/column widths and the per-cell data with its contents (301 CELL_VALUE
+ value block). The ACAD_TABLE class entry is added automatically through
IDxfClassDefined.

Cell contents with no value are skipped; per-cell style overrides, the table
cache block content and the TABLECONTENT object are not written yet.
Fill in the SingleTableEntity case with a valid 2x3 table (anonymous cache
block, per-cell string values) and enable the round trip assertions for the
DXF format on every version. The DWG half stays unasserted for now: the DWG
writer does not restore the cell contents of this synthetic table yet, and
DXF writing is the scope of the accompanying change.
…ity-write

# Conflicts:
#	src/ACadSharp/IO/DXF/DxfStreamWriter/DxfSectionWriterBase.Entities.cs

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TableEntity - dxf writer

2 participants