From 0b2606adaebba0c88980ab364983e7f95b345306 Mon Sep 17 00:00:00 2001 From: DomCR Date: Sat, 24 Aug 2024 10:49:32 +0200 Subject: [PATCH 1/4] dwg reader --- src/ACadSharp/Entities/AttributeBase.cs | 2 + .../DWG/DwgStreamReaders/DwgObjectReader.cs | 42 ++++++++++++++++--- .../IO/Templates/CadAttributeTemplate.cs | 21 ++++++++++ 3 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 src/ACadSharp/IO/Templates/CadAttributeTemplate.cs diff --git a/src/ACadSharp/Entities/AttributeBase.cs b/src/ACadSharp/Entities/AttributeBase.cs index 3074a9a2..32dc2598 100644 --- a/src/ACadSharp/Entities/AttributeBase.cs +++ b/src/ACadSharp/Entities/AttributeBase.cs @@ -63,6 +63,8 @@ public string Tag public bool IsReallyLocked { get; set; } + public MText MText { get; set; } + private string _tag = string.Empty; public AttributeBase() : base() { } diff --git a/src/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs b/src/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs index 508f2a54..58d1e2a0 100644 --- a/src/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs +++ b/src/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs @@ -312,7 +312,17 @@ private void readCommonEntityData(CadEntityTemplate template) //R13 - R14 Only: if (this._version >= ACadVersion.AC1012 && this._version <= ACadVersion.AC1014) + { this.updateHandleReader(); + } + + this.readEntityMode(template); + } + + private void readEntityMode(CadEntityTemplate template) + { + //Get the cad object as an entity + Entity entity = template.CadObject; //Common: //6B : Flags @@ -1073,11 +1083,11 @@ private CadTemplate readText() private CadTemplate readAttribute() { AttributeEntity att = new AttributeEntity(); - CadTextEntityTemplate template = new CadTextEntityTemplate(att); + CadAttributeTemplate template = new CadAttributeTemplate(att); this.readCommonTextData(template); - this.readCommonAttData(att); + this.readCommonAttData(template); return template; } @@ -1085,11 +1095,11 @@ private CadTemplate readAttribute() private CadTemplate readAttributeDefinition() { AttributeDefinition attdef = new AttributeDefinition(); - CadTextEntityTemplate template = new CadTextEntityTemplate(attdef); + CadAttributeTemplate template = new CadAttributeTemplate(attdef); this.readCommonTextData(template); - this.readCommonAttData(attdef); + this.readCommonAttData(template); //R2010+: if (this.R2010Plus) @@ -1206,8 +1216,10 @@ private void readCommonTextData(CadTextEntityTemplate template) template.StyleHandle = this.handleReference(); } - private void readCommonAttData(AttributeBase att) + private void readCommonAttData(CadAttributeTemplate template) { + AttributeBase att = template.CadObject as AttributeBase; + //R2010+: if (this.R2010Plus) { @@ -1229,6 +1241,14 @@ private void readCommonAttData(AttributeBase att) //MTEXT fields … Here all fields of an embedded MTEXT object //are written, starting from the Entmode //(entity mode). The owner handle can be 0. + att.MText = new MText(); + CadTextEntityTemplate mtextTemplate = new CadTextEntityTemplate(att.MText); + template.MTextTemplate = mtextTemplate; + + this.readEntityMode(mtextTemplate); + + this.readMText(mtextTemplate, false); + short dataSize = this._objectReader.ReadBitShort(); if (dataSize > 0) { @@ -2585,7 +2605,17 @@ private CadTemplate readMText() MText mtext = new MText(); CadTextEntityTemplate template = new CadTextEntityTemplate(mtext); - this.readCommonEntityData(template); + return this.readMText(template, true); + } + + private CadTemplate readMText(CadTextEntityTemplate template, bool readCommonData) + { + MText mtext = template.CadObject as MText; + + if (readCommonData) + { + this.readCommonEntityData(template); + } //Insertion pt3 BD 10 First picked point. (Location relative to text depends on attachment point (71).) mtext.InsertPoint = this._objectReader.Read3BitDouble(); diff --git a/src/ACadSharp/IO/Templates/CadAttributeTemplate.cs b/src/ACadSharp/IO/Templates/CadAttributeTemplate.cs new file mode 100644 index 00000000..0a959abb --- /dev/null +++ b/src/ACadSharp/IO/Templates/CadAttributeTemplate.cs @@ -0,0 +1,21 @@ +using ACadSharp.Entities; + +namespace ACadSharp.IO.Templates +{ + internal class CadAttributeTemplate : CadTextEntityTemplate + { + public CadTextEntityTemplate MTextTemplate { get; set; } + + public CadAttributeTemplate(AttributeBase entity) : base(entity) { } + + public override void Build(CadDocumentBuilder builder) + { + base.Build(builder); + + if (this.MTextTemplate != null) + { + this.MTextTemplate.Build(builder); + } + } + } +} From c9a39d89f79eb2603987ae90f9a976a010c8b52c Mon Sep 17 00:00:00 2001 From: DomCR Date: Sat, 24 Aug 2024 11:08:55 +0200 Subject: [PATCH 2/4] dwgWriter --- .../DwgObjectWriter.Common.cs | 12 ++++- .../DwgObjectWriter.Entities.cs | 52 ++++++++++++------- 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Common.cs b/src/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Common.cs index 80e2901d..2b25d477 100644 --- a/src/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Common.cs +++ b/src/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Common.cs @@ -174,6 +174,11 @@ private void writeCommonEntityData(Entity entity) this._writer.SavePositonForSize(); } + this.writeEntityMode(entity); + } + + private void writeEntityMode(Entity entity) + { //FE: Entity mode(entmode). Generally, this indicates whether or not the owner //relative handle reference is present.The values go as follows: @@ -190,7 +195,7 @@ private void writeCommonEntityData(Entity entity) this._writer.Write2Bits(entmode); if (entmode == 0) { - this._writer.HandleReference(DwgReferenceType.SoftPointer, entity.Owner.Handle); + this._writer.HandleReference(DwgReferenceType.SoftPointer, entity.Owner); } this.writeReactorsAndDictionaryHandle(entity); @@ -371,6 +376,11 @@ private void writeReactorsAndDictionaryHandle(CadObject cadObject) private byte getEntMode(Entity entity) { + if (entity.Owner == null) + { + return 0; + } + if (entity.Owner.Handle == this._document.PaperSpace.Handle) { return 0b01; diff --git a/src/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Entities.cs b/src/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Entities.cs index 6fa314b9..f92c4c62 100644 --- a/src/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Entities.cs +++ b/src/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Entities.cs @@ -232,9 +232,15 @@ private void writeCommonAttData(AttributeBase att) { this._writer.WriteByte((byte)att.AttributeType); - if (att.AttributeType == AttributeType.MultiLine || att.AttributeType == AttributeType.ConstantMultiLine) + if (att.AttributeType == AttributeType.MultiLine || + att.AttributeType == AttributeType.ConstantMultiLine) { - throw new NotImplementedException("Multiple line Attribute not implemented"); + this.writeEntityMode(att.MText); + + this.writeMText(att.MText); + + //TODO: Write attribute MText data + this._writer.WriteBitShort(0); } } @@ -1158,7 +1164,7 @@ private void writeMultiLeader(MultiLeader multiLeader) this._writer.WriteBitShort((short)multiLeader.ContentType); // 343 Text Style ID (handle/TextStyle) this._writer.HandleReference(DwgReferenceType.HardPointer, multiLeader.TextStyle); // Hard/soft?? - // 173 Text Left Attachment Type + // 173 Text Left Attachment Type this._writer.WriteBitShort((short)multiLeader.TextLeftAttachment); // 95 Text Right Attachement Type this._writer.WriteBitShort((short)multiLeader.TextRightAttachment); @@ -1172,7 +1178,7 @@ private void writeMultiLeader(MultiLeader multiLeader) this._writer.WriteBit(multiLeader.TextFrame); // 344 Block Content ID this._writer.HandleReference(DwgReferenceType.HardPointer, multiLeader.BlockContent); // Hard/soft?? - // 93 Block Content Color + // 93 Block Content Color this._writer.WriteCmColor(multiLeader.BlockContentColor); // 10 Block Content Scale this._writer.Write3BitDouble(multiLeader.BlockContentScale); @@ -1188,7 +1194,8 @@ private void writeMultiLeader(MultiLeader multiLeader) // BL Number of Block Labels int blockLabelCount = multiLeader.BlockAttributes.Count; this._writer.WriteBitLong(blockLabelCount); - for (int bl = 0; bl < blockLabelCount; bl++) { + for (int bl = 0; bl < blockLabelCount; bl++) + { // 330 Block Attribute definition handle (hard pointer) MultiLeader.BlockAttribute blockAttribute = multiLeader.BlockAttributes[bl]; this._writer.HandleReference(DwgReferenceType.HardPointer, blockAttribute.AttributeDefinition); @@ -1209,27 +1216,31 @@ private void writeMultiLeader(MultiLeader multiLeader) // 45 BD ScaleFactor this._writer.WriteBitDouble(multiLeader.ScaleFactor); - if (this.R2010Plus) { + if (this.R2010Plus) + { // 271 Text attachment direction for MText contents - this._writer.WriteBitShort((short)multiLeader.TextAttachmentDirection); + this._writer.WriteBitShort((short)multiLeader.TextAttachmentDirection); // 272 Bottom text attachment direction (sequence my be interchanged) this._writer.WriteBitShort((short)multiLeader.TextBottomAttachment); // 273 Top text attachment direction this._writer.WriteBitShort((short)multiLeader.TextTopAttachment); } - if (R2013Plus) { + if (R2013Plus) + { // 295 Leader extended to text this._writer.WriteBit(multiLeader.ExtendedToText); } } - private void writeMultiLeaderAnnotContext(MultiLeaderAnnotContext annotContext) { + private void writeMultiLeaderAnnotContext(MultiLeaderAnnotContext annotContext) + { // BL - Number of leader roots int leaderRootCount = annotContext.LeaderRoots.Count; this._writer.WriteBitLong(leaderRootCount); - for (int i = 0; i < leaderRootCount; i++) { + for (int i = 0; i < leaderRootCount; i++) + { writeLeaderRoot(annotContext.LeaderRoots[i]); } @@ -1254,7 +1265,8 @@ private void writeMultiLeaderAnnotContext(MultiLeaderAnnotContext annotContext) this._writer.WriteBitShort((short)annotContext.BlockContentConnection); // B 290 Has text contents this._writer.WriteBit(annotContext.HasTextContents); - if (annotContext.HasTextContents) { + if (annotContext.HasTextContents) + { // TV 304 Text label this._writer.WriteVariableText(annotContext.TextLabel); // 3BD 11 Normal vector @@ -1306,7 +1318,8 @@ private void writeMultiLeaderAnnotContext(MultiLeaderAnnotContext annotContext) // BD 144 Column size int columnSizesCount = annotContext.ColumnSizes.Count; this._writer.WriteBitLong(columnSizesCount); - for (int i = 0; i < columnSizesCount; i++) { + for (int i = 0; i < columnSizesCount; i++) + { this._writer.WriteBitDouble(annotContext.ColumnSizes[i]); } @@ -1315,8 +1328,9 @@ private void writeMultiLeaderAnnotContext(MultiLeaderAnnotContext annotContext) // B Unknown this._writer.WriteBit(false); } - - else if (annotContext.HasContentsBlock) { + + else if (annotContext.HasContentsBlock) + { this._writer.WriteBit(annotContext.HasContentsBlock); //B 296 Has contents block @@ -1429,7 +1443,8 @@ private void writeLeaderLine(MultiLeaderAnnotContext.LeaderLine leaderLine) // BL - Number of points // 3BD 10 Point this._writer.WriteBitLong(leaderLine.Points.Count); - foreach (XYZ point in leaderLine.Points) { + foreach (XYZ point in leaderLine.Points) + { // 3BD 10 Point this._writer.Write3BitDouble(point); } @@ -1437,7 +1452,8 @@ private void writeLeaderLine(MultiLeaderAnnotContext.LeaderLine leaderLine) // Add optional Break Info (one or more) // BL Break info count this._writer.WriteBitLong(leaderLine.BreakInfoCount); - if (leaderLine.BreakInfoCount > 0) { + if (leaderLine.BreakInfoCount > 0) + { // BL 90 Segment index this._writer.WriteBitLong(leaderLine.SegmentIndex); @@ -1455,7 +1471,8 @@ private void writeLeaderLine(MultiLeaderAnnotContext.LeaderLine leaderLine) // BL 91 Leader line index this._writer.WriteBitLong(leaderLine.Index); - if (this.R2010Plus) { + if (this.R2010Plus) + { // BS 170 Leader type(0 = invisible leader, 1 = straight leader, 2 = spline leader) this._writer.WriteBitShort((short)leaderLine.PathType); // CMC 92 Line color @@ -2019,7 +2036,6 @@ private void writeTextEntity(TextEntity text) private void writeMText(MText mtext) { - //Insertion pt3 BD 10 First picked point. (Location relative to text depends on attachment point (71).) this._writer.Write3BitDouble(mtext.InsertPoint); //Extrusion 3BD 210 Undocumented; appears in DXF and entget, but ACAD doesn't even bother to adjust it to unit length. From 7fc75e0aac5b41f96f7d4d9c5dd412d646acf545 Mon Sep 17 00:00:00 2001 From: DomCR Date: Sat, 24 Aug 2024 19:44:17 +0200 Subject: [PATCH 3/4] dxfreader --- .../IO/DXF/DxfStreamReader/DxfSectionReaderBase.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/ACadSharp/IO/DXF/DxfStreamReader/DxfSectionReaderBase.cs b/src/ACadSharp/IO/DXF/DxfStreamReader/DxfSectionReaderBase.cs index 0529c7b9..b6748803 100644 --- a/src/ACadSharp/IO/DXF/DxfStreamReader/DxfSectionReaderBase.cs +++ b/src/ACadSharp/IO/DXF/DxfStreamReader/DxfSectionReaderBase.cs @@ -141,9 +141,9 @@ protected CadEntityTemplate readEntity() switch (this._reader.ValueAsString) { case DxfFileToken.EntityAttribute: - return this.readEntityCodes(new CadTextEntityTemplate(new AttributeEntity()), this.readAttributeDefinition); + return this.readEntityCodes(new CadAttributeTemplate(new AttributeEntity()), this.readAttributeDefinition); case DxfFileToken.EntityAttributeDefinition: - return this.readEntityCodes(new CadTextEntityTemplate(new AttributeDefinition()), this.readAttributeDefinition); + return this.readEntityCodes(new CadAttributeTemplate(new AttributeDefinition()), this.readAttributeDefinition); case DxfFileToken.EntityArc: return this.readEntityCodes(new CadEntityTemplate(), this.readArc); case DxfFileToken.EntityCircle: @@ -306,14 +306,19 @@ private bool readArc(CadEntityTemplate template, DxfMap map, string subclass = n private bool readAttributeDefinition(CadEntityTemplate template, DxfMap map, string subclass = null) { DxfClassMap emap = map.SubClasses[template.CadObject.SubclassMarker]; - CadTextEntityTemplate tmp = template as CadTextEntityTemplate; + CadAttributeTemplate tmp = template as CadAttributeTemplate; switch (this._reader.Code) { - //TODO: Implement multiline attribute def codes case 44: case 46: + return true; case 101: + var att = tmp.CadObject as AttributeBase; + att.MText = new MText(); + CadTextEntityTemplate mtextTemplate = new CadTextEntityTemplate(att.MText); + tmp.MTextTemplate = mtextTemplate; + this.readEntityCodes(mtextTemplate, this.readTextEntity); return true; default: if (!this.tryAssignCurrentValue(template.CadObject, emap)) From 5ad337f93763d868de2d6ac0a7809fead9237a24 Mon Sep 17 00:00:00 2001 From: DomCR Date: Sat, 24 Aug 2024 20:57:06 +0200 Subject: [PATCH 4/4] dxfwriter --- src/ACadSharp/Entities/AttributeBase.cs | 7 ++--- .../DxfSectionWriterBase.Entities.cs | 31 ++++++++++++++----- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/ACadSharp/Entities/AttributeBase.cs b/src/ACadSharp/Entities/AttributeBase.cs index 32dc2598..b3a6fef1 100644 --- a/src/ACadSharp/Entities/AttributeBase.cs +++ b/src/ACadSharp/Entities/AttributeBase.cs @@ -49,16 +49,15 @@ public string Tag } /// - /// Attribute flags + /// Attribute flags. /// [DxfCodeValue(70)] public AttributeFlags Flags { get; set; } /// - /// MText flag + /// Attribute type. /// - //[DxfCodeValue(280)] - //TODO: Check the dxf code of Attribute type. + [DxfCodeValue(71)] public AttributeType AttributeType { get; set; } = AttributeType.SingleLine; public bool IsReallyLocked { get; set; } diff --git a/src/ACadSharp/IO/DXF/DxfStreamWriter/DxfSectionWriterBase.Entities.cs b/src/ACadSharp/IO/DXF/DxfStreamWriter/DxfSectionWriterBase.Entities.cs index 91bbb806..c3c679d2 100644 --- a/src/ACadSharp/IO/DXF/DxfStreamWriter/DxfSectionWriterBase.Entities.cs +++ b/src/ACadSharp/IO/DXF/DxfStreamWriter/DxfSectionWriterBase.Entities.cs @@ -662,11 +662,14 @@ private void writeMLine(MLine mLine) } } - private void writeMText(MText mtext) + private void writeMText(MText mtext, bool writeSubclass = true) { DxfClassMap map = DxfClassMap.Create(); - this._writer.Write(DxfCode.Subclass, DxfSubclassMarker.MText); + if (writeSubclass) + { + this._writer.Write(DxfCode.Subclass, DxfSubclassMarker.MText); + } this._writer.Write(10, mtext.InsertPoint, map); @@ -756,7 +759,8 @@ private void writeMultiLeader(MultiLeader multiLeader) this._writer.Write(295, 0); } - private void writeMultiLeaderAnnotContext(MultiLeaderAnnotContext contextData) { + private void writeMultiLeaderAnnotContext(MultiLeaderAnnotContext contextData) + { this._writer.Write(300, "CONTEXT_DATA{"); this._writer.Write(40, contextData.ScaleFactor); this._writer.Write(10, contextData.ContentBasePoint); @@ -812,7 +816,8 @@ private void writeMultiLeaderAnnotContext(MultiLeaderAnnotContext contextData) { this._writer.Write(297, contextData.NormalReversed); - foreach (MultiLeaderAnnotContext.LeaderRoot leaderRoot in contextData.LeaderRoots) { + foreach (MultiLeaderAnnotContext.LeaderRoot leaderRoot in contextData.LeaderRoots) + { writeLeaderRoot(leaderRoot); } @@ -836,7 +841,8 @@ private void writeLeaderRoot(MultiLeaderAnnotContext.LeaderRoot leaderRoot) this._writer.Write(90, leaderRoot.LeaderIndex); this._writer.Write(40, leaderRoot.LandingDistance); - foreach (MultiLeaderAnnotContext.LeaderLine leaderLine in leaderRoot.Lines) { + foreach (MultiLeaderAnnotContext.LeaderLine leaderLine in leaderRoot.Lines) + { writeLeaderLine(leaderLine); } @@ -844,10 +850,12 @@ private void writeLeaderRoot(MultiLeaderAnnotContext.LeaderRoot leaderRoot) this._writer.Write(303, "}"); // LEADER } - private void writeLeaderLine(MultiLeaderAnnotContext.LeaderLine leaderLine) { + private void writeLeaderLine(MultiLeaderAnnotContext.LeaderLine leaderLine) + { this._writer.Write(304, "LEADER_LINE{"); - foreach (XYZ point in leaderLine.Points) { + foreach (XYZ point in leaderLine.Points) + { this._writer.Write(10, point); } this._writer.Write(91, leaderLine.Index); @@ -1115,6 +1123,15 @@ private void writeAttributeBase(AttributeBase att) { this._writer.Write(74, (short)att.VerticalAlignment); } + + if (this.Version > ACadVersion.AC1027 && att.MText != null) + { + this._writer.Write(71, (short)att.AttributeType); + this._writer.Write(72, (short)0); + this._writer.Write(11, att.AlignmentPoint); + + this.writeMText(att.MText, false); + } } private void writeVertex(Vertex v)