Add Material write support and Mesh texture coordinates round-trip#1084
Open
ilCosmico wants to merge 7 commits into
Open
Add Material write support and Mesh texture coordinates round-trip#1084ilCosmico wants to merge 7 commits into
ilCosmico wants to merge 7 commits into
Conversation
Materials are currently dropped on the floor by DwgWriter: skipEntry returns true for Material so the entries created via MaterialCollection never reach the file. Round-tripping a CadDocument through DwgWriter and DwgReader reports zero materials regardless of what was in memory. This adds a writeMaterial method mirroring DwgObjectReader.readMaterial: name and description, then Ambient/Diffuse/Specular color blocks, then Reflection/Opacity/Bump/Refraction maps with their transform matrices, gloss and refraction scalars in the same positions the reader expects. The R2007a tail block (translucence, self_illumination, reflectivity, illumination_model, channel_flags, mode) is also emitted with defaults sampled from an AutoCAD-produced AC1027 reference. The reader does not consume those bytes but they are part of the body length AutoCAD writes, so omitting them produces a recover-mode prompt in DWG TrueView. Material is removed from skipEntry and dispatched alongside the other NonGraphicalObject writers. Verified end to end via RepoMaterialMissing: ACadSharp roundtrip now reports 6 materials matching the reference file, and DWG TrueView opens the output and switches to Conceptual without crashing.
The Material flag pair in writeCommonEntityData was hard-coded to 00 (ByLayer), so the per-entity Material handle was never written out. On read, MaterialHandle was captured in CadEntityTemplate but never applied to the entity's Material property during the build pass; only Layer, LineType and BookColor were resolved. writeCommonEntityData now checks entity.Material: when set, it writes the 11 flag pair and the hard-pointer handle to the material, matching what the reader expects. CadEntityTemplate.build resolves the captured MaterialHandle against the document builder and assigns the Material back to the entity. Verified end to end with RepoMaterialMissing: three Mesh cubes carrying distinct materials round-trip cleanly (meshesWithMaterial=3) and the resulting DWG still opens in DWG TrueView and switches to Conceptual without crashing.
The reader (readMaterial) constructs the color from the low three bytes of the BitLong and discards the high byte. The encoder was leaving the high byte at 0, which round-tripped through ACadSharp itself but caused AutoCAD and DWG TrueView to render any material whose method was set to Override as solid black: the high-byte tag tells the reader to treat the remaining three bytes as a 24-bit RGB true color rather than fall back to an indexed color lookup, and the indexed-color path was resolving to black with the diffuse RGB stored inline. Setting the high byte to 0xc2, the same true-color marker the BookColor writer already uses, fixes the rendered output. Verified end to end in DWG TrueView via RepoMaterialMissing: three meshes carrying Red, Green and Blue override-color materials now render in their assigned colors under the Realistic and Conceptual visual styles instead of all three appearing black.
Surface the three render-mode hints AutoCAD writes in the SINCE R_2007a Material tail block as proper enums on the Material API instead of raw ints. The three new types mirror the ODA-side OdGiMaterialTraits enums (ChannelFlags, IlluminationModel and Mode); their numeric values match the constants in GiMaterial.h so the bit patterns stay identical on the wire. Material.ChannelFlags goes from int to MaterialChannelFlags ([Flags]), defaulting to UseAll (0x7F = every channel enabled), which matches the value AutoCAD reference DWGs emit unconditionally and removes the "== 0 ? 127" fallback the writer used to need. Material.IlluminationModel goes from int to MaterialIlluminationModel, defaulting to BlinnShader (0) just like OdGiMaterialTraitsData. Material.Mode is new; it was previously hard-coded to 0 in the writer and never read. It now defaults to Realistic and is consumed by both sides. readMaterial now consumes the full tail block (translucence, self_illumination, reflectivity, illumination model, channel flags and mode) instead of stopping after the refraction map. AutoCAD always writes these bytes, so consuming them keeps the in-memory model in sync with the file and lets non-default values (e.g. kMetalShader, a custom channel mask) survive a DwgWriter / DwgReader round trip.
Add Mesh.TextureCoordinates and persist them as the
ADSK_XREC_SUBDVERTEXTEXCOORDS XRecord that AutoCAD/AcDbSubDMesh stores
on a mesh extension dictionary. DwgWriter materializes the XRecord
before writeHeader so the file's HandleSeed stays accurate; the reader
template populates the property when the XRecord is present.
Also fix CadDictionary.Add(string key, NonGraphicalObject value) so it
syncs value.Name with the supplied key when the value has no name yet.
Without this, calling Add("MY_KEY", new XRecord()) would persist with
an empty dictionary entry name. And lower Material.ChannelFlags default
from UseAll to UseDiffuse: UseAll caused TrueView to sample channels
the material had no data for and dropped texture rendering.
- MeshTests covers bounding-box, default TextureCoordinates state, clone independence, and DWG round-trip with the ADSK_XREC_SUBDVERTEXTEXCOORDS XRecord. - MaterialTests covers default property values and DWG round-trip for color methods, the strongly-typed enums, and diffuse-map metadata. - WriterSingleObjectTests registers SingleMeshWithTextureCoordinates and SingleMaterial so the writer cases run across the supported ACadVersion matrix.
The render-mode hints (Translucence, self_illumination, Reflectivity, IlluminationModel, ChannelFlags, Mode) are only present in MATERIAL objects from R2007a onward. Reading or writing them unconditionally runs past the end of older MATERIAL objects, corrupting the stream position for every subsequent object and tripping ReadBitLong in unrelated tables. Gate both sides on R2007Plus.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds Material write support and Mesh texture coordinate round-trip in DWG.
Test plan