Repository navigation
DWG reader: keep plot style, xref block and dimension context data; read RTEXT - #1272
jarrett-meyer wants to merge 7 commits into
Conversation
The DWG reader read these handles and discarded them: - entity plot style flags and plot style handle (named plot styles), now Entity.PlotStyleFlags and Entity.PlotStyleHandle; - layer plot style handle, now set to Layer.PlotStyleName as the DXF reader already does; - layer external reference block handle, which was stored in an unused LayerControlHandle template property, now Layer.XrefBlockHandle; - plot settings plot view handle, now PlotSettings.PlotViewHandle. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Annotative dimensions have one ACDB_*DIMOBJECTCONTEXTDATA_CLASS object per annotation scale, each pointing to the anonymous block with the dimension graphics for that scale. These objects were read as unknown non-graphical objects, so the per-scale blocks could not be found. Add DimensionObjectContextData with the scale and the block, and read it for every DIMOBJECTCONTEXTDATA class. Only the handles are read, not the data fields, so both writers skip it like other partially supported objects. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RTEXT (Express Tools remote text) has no class in the library and is read as an UnknownEntity, losing its data. After the common entity data, read its insertion point, normal, rotation, height, flags, contents (a DIESEL expression or a file name) and text style handle into UnknownEntity.RText. A read failure only reports a warning. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
||
| this.readCommonEntityData(template); | ||
|
|
||
| if (dxfClass?.DxfName == "RTEXT") |
There was a problem hiding this comment.
This should be in the switch in readUnlistedType following the same pattern.
There was a problem hiding this comment.
Done: moved to case DxfFileToken.EntityRText in the readUnlistedType switch, which calls a new readRText(c). RTEXT has no class of its own in the library, so it still produces an UnknownEntity with RText filled in.
| break; | ||
| } | ||
|
|
||
| if (template == null && c.DxfName.EndsWith("DIMOBJECTCONTEXTDATA_CLASS")) |
There was a problem hiding this comment.
This should be in the switch in readUnlistedType following the same pattern.
You can use "ACDB_DIMOBJECTCONTEXTDATA_CLASS".
There was a problem hiding this comment.
Moved into the readUnlistedType switch. A single ACDB_DIMOBJECTCONTEXTDATA_CLASS case would never match, though: DWG/DXF files store one class per dimension type, and no file declares the base name (that is why I had used EndsWith). I checked this against a drawing made in AutoCAD.
So there is now one class and one DxfFileToken constant per type, all derived from an abstract DimensionObjectContextData (AcDbDimensionObjectContextData):
ACDB_ALDIMOBJECTCONTEXTDATA_CLASS→AlignedDimensionObjectContextData(aligned and linear)ACDB_ANGDIMOBJECTCONTEXTDATA_CLASS→AngularDimensionObjectContextData(angular and arc length)ACDB_DMDIMOBJECTCONTEXTDATA_CLASS→DiametricDimensionObjectContextDataACDB_ORDDIMOBJECTCONTEXTDATA_CLASS→OrdinateDimensionObjectContextDataACDB_RADIMOBJECTCONTEXTDATA_CLASS→RadialDimensionObjectContextDataACDB_RADIMLRGOBJECTCONTEXTDATA_CLASS→RadialDimensionLargeObjectContextData(extends the radial one)
The data fields are now read as well, from both DWG and DXF: text location and rotation, the per-scale overrides (DIMTOFL, DIMSOXD, DIMTIX and the override flags), arrow flips, and each type's points. I decoded the DWG bit layout from that AutoCAD drawing and checked it against its DXF export. One finding: DWG stores DIMATFIT and DIMTMOVE only as "overridden" bits, so their values are read from DXF only.
The drawing is in samples/annotative/, and DimensionObjectContextDataTests compares the DWG and DXF reads. Known gaps: LARGE_RADIAL_DIMENSION entities are not read yet, so the large radial context data is not covered by the tests (its layout was only checked by hand against the DXF), and the writers still skip these objects.
…e switch Address review: dispatch both through the switch with DxfFileToken constants instead of separate checks. DWG files store the concrete ACDB_*DIMOBJECTCONTEXTDATA_CLASS subclass names, so each is listed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DWG files store the concrete ACDB_*DIMOBJECTCONTEXTDATA_CLASS names; there is no ACDB_DIMOBJECTCONTEXTDATA_CLASS class. Make DimensionObjectContextData an abstract base (AcDbDimensionObjectContextData) and add one class per type with its real DXF name and subclass marker: aligned, angular, diametric, ordinate, radial and radial large. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Read the per-scale text location, text rotation, default text location flag, overridden dimension variables (DIMTOFL, DIMSOXD, DIMTIX and the override flags), arrow flips and the type-specific points of each ACDB_*DIMOBJECTCONTEXTDATA_CLASS object, and read these objects from DXF. The DWG bit layout was decoded from a drawing made in AutoCAD and checked against its DXF export: text location is first, and DIMATFIT and DIMTMOVE are stored as single override bits, so their values are only read from DXF. The jogged radial class name is ACDB_RADIMLRGOBJECTCONTEXTDATA_CLASS and its data extends the radial one. Add samples/annotative with the drawing (7 annotative dimensions at 1:1 and 1:20, some with per-scale overrides) and tests comparing DWG and DXF. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
17a3d30 to
17034a5
Compare
The DWG reader already reads several handles and some object data and then throws them away. This PR keeps that data on the model so callers can use it, for example to plot drawings with named plot styles or to find the graphics of annotative dimensions. Each part is in its own commit.
Plot style, plot view and xref block handles
readCommonEntityDataread the plot style flags (BB) and the plot style handle and discarded both. They are now inEntity.PlotStyleFlags(0 = by layer, 1 = by block, 3 = handle present) andEntity.PlotStyleHandle. The handle points to an entry of theACAD_PLOTSTYLENAMEdictionary.CadLayerTemplatehad the build ofPlotStyleHandlecommented out, soLayer.PlotStyleNamewas always 0 for DWG files. It is now set from the handle, as the DXF reader already does with code 390.CadLayerTemplate.LayerControlHandleis the external reference block handle (the existing TODO pointed this out), and nothing used that property. It is now exposed asLayer.XrefBlockHandle, and the unused template property is removed. This gives a reliable link from an xref-dependent layer to its xref block, even when theXREF|prefix of the layer name is stale.PlotSettings.PlotViewHandle.These are exposed as raw handles, like the existing
Layer.PlotStyleName, because the plot style name entries have no model class yet. I can change them to resolved objects if you prefer.Dimension object context data
Annotative dimensions have one
ACDB_*DIMOBJECTCONTEXTDATA_CLASSobject per annotation scale (aligned, rotated, radial, diametric, and so on). Each one points to the anonymous block with the dimension graphics for that scale. These objects were read asUnknownNonGraphicalObject, so the per-scale blocks could not be found.This adds
DimensionObjectContextData : AnnotScaleObjectContextDatawithScaleandBlock. It is read for every class whose DXF name ends inDIMOBJECTCONTEXTDATA_CLASS. Only the handles are read, not the data fields. The DWG and DXF writers therefore skip it, the same way they handle other partially supported objects, and writing keeps its current behavior.RTEXT
RTEXT (Express Tools remote text) has no class in the library and is read as
UnknownEntity, so its data was lost. After the common entity data, the reader now reads the insertion point, normal, rotation, height, flags, contents (a DIESEL expression or a file name) and the text style handle intoUnknownEntity.RText. A read failure only reports a warning and leavesRTextnull. If you prefer a dedicatedRTextentity instead, I can rework this part, or you can leave this commit out.Tests
The full
ACadSharp.Testssuite passes on net9.0 (2400 passed, 2 skipped). I did not add new tests. The writer does not produce named plot styles, xref-dependent layers, annotative dimensions or RTEXT, so a meaningful synthetic DWG cannot be created for these paths. They were checked against real drawings that I cannot share.Related: the CSUtilities fix for
Matrix4.GetArbitraryAxis(DomCR/CSUtilities#28) is separate. This PR does not change the submodule pointer.A separate PR, #1271, contains DWG reader bug fixes. The two PRs are independent and merge cleanly together.
🤖 Generated with Claude Code