diff --git a/ACadSharp.Tests/IO/MultiLeaderTests.cs b/ACadSharp.Tests/IO/MultiLeaderTests.cs new file mode 100644 index 00000000..1ce32810 --- /dev/null +++ b/ACadSharp.Tests/IO/MultiLeaderTests.cs @@ -0,0 +1,142 @@ +using ACadSharp.Entities; +using ACadSharp.IO; +using System.Collections.Generic; +using System.IO; +using Xunit; +using Xunit.Abstractions; + +namespace ACadSharp.Tests.IO +{ + public class MultiLeaderTests : IOTestsBase + { + public MultiLeaderTests(ITestOutputHelper output) : base(output) + { + } + + [Fact] + public void MultiLeaderDwg() + { + string inPath = Path.Combine($"{_samplesFolder}", "multileader", "sample_MLeader_AC1032.dwg"); + CadDocument doc = DwgReader.Read(inPath); + + // There are 14 multileaders in DWG file + Assert.Equal(14, doc.Entities.Count); + + List entities = new List(doc.Entities); + + MultiLeader multiLeader; + + multiLeader = (MultiLeader)entities[0]; + Assert.Equal(@"MULTILEADER TEST", multiLeader.ContextData.TextLabel); + Assert.Equal(TextAttachmentPointType.Left, multiLeader.TextAttachmentPoint); + Assert.Equal(TextAttachmentType.MiddleOfTopLine, multiLeader.TextLeftAttachment); + Assert.False(multiLeader.TextFrame); + Assert.Equal(8, multiLeader.LandingDistance); + Assert.Equal(TextAttachmentDirectionType.Horizontal, multiLeader.TextAttachmentDirection); + + multiLeader = (MultiLeader)entities[1]; + Assert.Equal(@"MULTILEADER\PTEST\P123", multiLeader.ContextData.TextLabel); + Assert.Equal(TextAttachmentPointType.Left, multiLeader.TextAttachmentPoint); + Assert.Equal(TextAttachmentType.MiddleOfTopLine, multiLeader.TextLeftAttachment); + Assert.False(multiLeader.TextFrame); + Assert.Equal(8, multiLeader.LandingDistance); + Assert.Equal(TextAttachmentDirectionType.Horizontal, multiLeader.TextAttachmentDirection); + + multiLeader = (MultiLeader)entities[2]; + Assert.Equal(@"MULTILEADER\PTEST\P123", multiLeader.ContextData.TextLabel); + Assert.Equal(TextAttachmentPointType.Center, multiLeader.TextAttachmentPoint); + Assert.Equal(TextAttachmentType.MiddleOfTopLine, multiLeader.TextLeftAttachment); + Assert.False(multiLeader.TextFrame); + Assert.Equal(8, multiLeader.LandingDistance); + Assert.Equal(TextAttachmentDirectionType.Horizontal, multiLeader.TextAttachmentDirection); + + multiLeader = (MultiLeader)entities[3]; + Assert.Equal(@"MULTILEADER\PTEST\P123", multiLeader.ContextData.TextLabel); + Assert.Equal(TextAttachmentPointType.Right, multiLeader.TextAttachmentPoint); + Assert.Equal(TextAttachmentType.MiddleOfTopLine, multiLeader.TextLeftAttachment); + Assert.False(multiLeader.TextFrame); + Assert.Equal(8, multiLeader.LandingDistance); + Assert.Equal(TextAttachmentDirectionType.Horizontal, multiLeader.TextAttachmentDirection); + + multiLeader = (MultiLeader)entities[4]; + Assert.Equal(@"MULTILEADER\PTEST\P123", multiLeader.ContextData.TextLabel); + Assert.Equal(TextAttachmentPointType.Right, multiLeader.TextAttachmentPoint); + Assert.Equal(TextAttachmentType.MiddleOfTopLine, multiLeader.TextLeftAttachment); + Assert.True(multiLeader.TextFrame); + Assert.Equal(8, multiLeader.LandingDistance); + Assert.Equal(TextAttachmentDirectionType.Horizontal, multiLeader.TextAttachmentDirection); + + multiLeader = (MultiLeader)entities[5]; + Assert.Equal(@"MULTILEADER\PTEST\P123", multiLeader.ContextData.TextLabel); + Assert.Equal(TextAttachmentPointType.Right, multiLeader.TextAttachmentPoint); + Assert.Equal(TextAttachmentType.MiddleOfTopLine, multiLeader.TextLeftAttachment); + Assert.True(multiLeader.TextFrame); + Assert.Equal(8, multiLeader.LandingDistance); + Assert.Equal(TextAttachmentDirectionType.Horizontal, multiLeader.TextAttachmentDirection); + + multiLeader = (MultiLeader)entities[6]; + Assert.Equal(@"MULTILEADER\PTEST\P123", multiLeader.ContextData.TextLabel); + Assert.Equal(TextAttachmentPointType.Right, multiLeader.TextAttachmentPoint); + Assert.Equal(TextAttachmentType.MiddleOfTopLine, multiLeader.TextLeftAttachment); + Assert.True(multiLeader.TextFrame); + Assert.Equal(16, multiLeader.LandingDistance); + Assert.Equal(TextAttachmentDirectionType.Horizontal, multiLeader.TextAttachmentDirection); + + multiLeader = (MultiLeader)entities[7]; + Assert.Equal(@"MULTILEADER\PTEST\P123", multiLeader.ContextData.TextLabel); + Assert.Equal(TextAttachmentPointType.Right, multiLeader.TextAttachmentPoint); + Assert.Equal(TextAttachmentType.MiddleOfTopLine, multiLeader.TextLeftAttachment); + Assert.True(multiLeader.TextFrame); + Assert.Equal(16, multiLeader.LandingDistance); + Assert.Equal(TextAttachmentDirectionType.Horizontal, multiLeader.TextAttachmentDirection); + + multiLeader = (MultiLeader)entities[8]; + Assert.Equal(@"MULTILEADER\PTEST\P123", multiLeader.ContextData.TextLabel); + Assert.Equal(TextAttachmentPointType.Right, multiLeader.TextAttachmentPoint); + Assert.Equal(TextAttachmentType.MiddleOfTopLine, multiLeader.TextLeftAttachment); + Assert.True(multiLeader.TextFrame); + Assert.Equal(16, multiLeader.LandingDistance); + Assert.Equal(TextAttachmentDirectionType.Horizontal, multiLeader.TextAttachmentDirection); + + multiLeader = (MultiLeader)entities[9]; + Assert.Equal(@"MULTILEADER\PTEST\P123", multiLeader.ContextData.TextLabel); + Assert.Equal(TextAttachmentPointType.Right, multiLeader.TextAttachmentPoint); + Assert.Equal(TextAttachmentType.MiddleOfTopLine, multiLeader.TextLeftAttachment); + Assert.True(multiLeader.TextFrame); + Assert.Equal(16, multiLeader.LandingDistance); + Assert.Equal(TextAttachmentDirectionType.Horizontal, multiLeader.TextAttachmentDirection); + + multiLeader = (MultiLeader)entities[10]; + Assert.Equal(@"MULTILEADER\PTEST\P123", multiLeader.ContextData.TextLabel); + Assert.Equal(TextAttachmentPointType.Right, multiLeader.TextAttachmentPoint); + Assert.Equal(TextAttachmentType.MiddleOfTopLine, multiLeader.TextLeftAttachment); + Assert.True(multiLeader.TextFrame); + Assert.Equal(16, multiLeader.LandingDistance); + Assert.Equal(TextAttachmentDirectionType.Horizontal, multiLeader.TextAttachmentDirection); + + multiLeader = (MultiLeader)entities[11]; + Assert.Equal(@"MULTILEADER TEST", multiLeader.ContextData.TextLabel); + Assert.Equal(TextAttachmentPointType.Left, multiLeader.TextAttachmentPoint); + Assert.Equal(TextAttachmentType.BottomLine, multiLeader.TextLeftAttachment); + Assert.False(multiLeader.TextFrame); + Assert.Equal(8, multiLeader.LandingDistance); + Assert.Equal(TextAttachmentDirectionType.Horizontal, multiLeader.TextAttachmentDirection); + + multiLeader = (MultiLeader)entities[12]; + Assert.Equal(@"MULTILEADER TEST", multiLeader.ContextData.TextLabel); + Assert.Equal(TextAttachmentPointType.Left, multiLeader.TextAttachmentPoint); + Assert.Equal(TextAttachmentType.TopOfTopLine, multiLeader.TextLeftAttachment); + Assert.False(multiLeader.TextFrame); + Assert.Equal(8, multiLeader.LandingDistance); + Assert.Equal(TextAttachmentDirectionType.Horizontal, multiLeader.TextAttachmentDirection); + + multiLeader = (MultiLeader)entities[13]; + Assert.Equal(@"MULTILEADER TEST", multiLeader.ContextData.TextLabel); + Assert.Equal(TextAttachmentPointType.Left, multiLeader.TextAttachmentPoint); + Assert.Equal(TextAttachmentType.TopOfTopLine, multiLeader.TextLeftAttachment); + Assert.False(multiLeader.TextFrame); + Assert.Equal(8, multiLeader.LandingDistance); + Assert.Equal(TextAttachmentDirectionType.Vertical, multiLeader.TextAttachmentDirection); + } + } +} diff --git a/ACadSharp/AttachmentType.cs b/ACadSharp/AttachmentType.cs new file mode 100644 index 00000000..80b90498 --- /dev/null +++ b/ACadSharp/AttachmentType.cs @@ -0,0 +1,9 @@ +namespace ACadSharp { + + public enum AttachmentType : short { + + CenterExtents = 0, + + InsertionPoint = 1 + } +} \ No newline at end of file diff --git a/ACadSharp/DxfFileToken.cs b/ACadSharp/DxfFileToken.cs index 481ec322..5dc070e2 100644 --- a/ACadSharp/DxfFileToken.cs +++ b/ACadSharp/DxfFileToken.cs @@ -119,6 +119,7 @@ public static class DxfFileToken public const string ObjectScale = "SCALE"; public const string ObjectSortEntsTable = "SORTENTSTABLE"; public const string ObjectXRecord = "XRECORD"; + public const string ObjectMLeaderContextData = "CONTEXT_DATA"; #endregion } diff --git a/ACadSharp/DxfSubclassMarker.cs b/ACadSharp/DxfSubclassMarker.cs index 7cd9cf21..de1261ea 100644 --- a/ACadSharp/DxfSubclassMarker.cs +++ b/ACadSharp/DxfSubclassMarker.cs @@ -43,6 +43,9 @@ public static class DxfSubclassMarker public const string Vertex = "AcDbVertex"; public const string Polyline = "AcDb2dPolyline"; public const string Leader = "AcDbLeader"; + public const string MLeader = "AcDbMLeader"; + public const string MLeaderStyle = "AcDbMLeaderStyle"; + public const string MultiLeaderAnnotContext = "AcDbMultiLeaderAnnotContext"; public const string LwPolyline = "AcDbPolyline"; public const string PolylineVertex = "AcDb2dVertex"; public const string Polyline3d = "AcDb3dPolyline"; diff --git a/ACadSharp/Entities/MultiLeader.cs b/ACadSharp/Entities/MultiLeader.cs new file mode 100644 index 00000000..63b65433 --- /dev/null +++ b/ACadSharp/Entities/MultiLeader.cs @@ -0,0 +1,356 @@ +using System.Collections.Generic; + +using ACadSharp.Attributes; +using ACadSharp.Objects; +using ACadSharp.Tables; + +using CSMath; + + +namespace ACadSharp.Entities +{ + /// + /// Represents a entity. + /// + /// + /// Object name
+ /// Dxf class name + ///
+ [DxfName(DxfFileToken.EntityMLeader)] + [DxfSubClass(DxfSubclassMarker.MLeader)] + public class MultiLeader : Entity + { + /// + public override ObjectType ObjectType => ObjectType.UNLISTED; + + /// + public override string ObjectName => DxfFileToken.EntityMLeader; + + /// + public override string SubclassMarker => DxfSubclassMarker.MLeader; + + // TODO + // We ommit this class because we assumed that the multileader + // does not have a list of arrow heads associated (see below). + // According to the OpenDesign_Specification_for_.dwg_files + // each arrowhead shall be associated with an IsDefault flag + // having the group code 94. This means the type of the field + // is BL instead of B. + // According to the DXF refence the 94 group code refers to + // the index of the arrow head. + /* + /// + /// Represents an associated arrow head, with the arrowhead index. + /// + public class ArrowheadAssociation { + + /// + /// Arrowhead Index + /// + [DxfCodeValue(94)] + public int ArrowheadIndex { get; set; } + + // IsDefault property + + /// + /// Arrowhead ID + /// + [DxfCodeValue(345)] + public BlockRecord Arrowhead { get; set; } + } + */ + + + /// + /// + /// + public class BlockAttribute { + /// + /// Block Attribute Id + /// + [DxfCodeValue(330)] + public AttributeDefinition AttributeDefinition { get; set; } + + /// + /// Block Attribute Index + /// + [DxfCodeValue(177)] + public short Index { get; set; } + + /// + /// Block Attribute Width + /// + [DxfCodeValue(44)] + public double Width { get; set; } + + /// + /// Block Attribute Text String + /// + [DxfCodeValue(302)] + public string Text { get; set; } + } + + /// + /// Contains the multileader content (block/text) and the leaders. + /// + public MultiLeaderAnnotContext ContextData { get; set; } + + /// + /// Gets a providing reusable style information + /// for this . + /// + [DxfCodeValue(340)] + public MultiLeaderStyle Style { get; set; } + + /// + /// Property Override Flag + /// + [DxfCodeValue(90)] + public MultiLeaderPropertyOverrideFlags PropertyOverrideFlags { get; set; } + + /// + /// PathType (Leader Type) + /// + [DxfCodeValue(170)] + public MultiLeaderPathType PathType { get; set; } + + /// + /// LeaderLineColor + /// + [DxfCodeValue(91)] + public Color LineColor { get; set; } + + // TODO Additional Line Type? see Entity.LineType. + /// + /// Leader Line Type + /// + [DxfCodeValue(341)] + public LineType LeaderLineType { get; set; } + + // TODO Additional Line Weight? see Entity.LineWeight. + /// + /// Leader Line Weight + /// + [DxfCodeValue(171)] + public LineweightType LeaderLineWeight { get; set; } + + /// + /// Enable Landing + /// + [DxfCodeValue(290)] + public bool EnableLanding { get; set; } + + /// + /// Enable Dogleg + /// + [DxfCodeValue(291)] + public bool EnableDogleg { get; set; } + + /// + /// Landing Distance + /// + [DxfCodeValue(41)] + public double LandingDistance { get; set; } + + /// + /// Arrowhead ID + /// + [DxfCodeValue(342)] + public BlockRecord Arrowhead { get; set; } + + /// + /// Arrowhead Size + /// + [DxfCodeValue(42)] + public double ArrowheadSize { get; set; } + + /// + /// Content Type + /// + [DxfCodeValue(172)] + public LeaderContentType ContentType { get; set; } + + #region Text Menu Properties + + /// + /// Text Style + /// + [DxfCodeValue(343)] + public TextStyle TextStyle { get; set; } + + /// + /// Text Left Attachment Type + /// + [DxfCodeValue(173)] + public TextAttachmentType TextLeftAttachment { get; set; } + + /// + /// Text Right Attachement Type + /// + [DxfCodeValue(95)] + public TextAttachmentType TextRightAttachment { get; set; } + + /// + /// Text Angle Type + /// + [DxfCodeValue(174)] + public TextAngleType TextAngle { get; set; } + + /// + /// Text Alignment + /// + [DxfCodeValue(175)] + public TextAlignmentType TextAlignment { get; set; } + + /// + /// Text Color + /// + [DxfCodeValue(92)] + public Color TextColor { get; set; } + + /// + /// Enable Frame Text + /// + [DxfCodeValue(292)] + public bool TextFrame { get; set; } + + #endregion + #region Block Content Properties + + /// + /// Block Content + /// + [DxfCodeValue(344)] + public BlockRecord BlockContent { get; set; } + + /// + /// Block Content Color + /// + [DxfCodeValue(93)] + public Color BlockContentColor { get; set; } + + /// + /// Block Content Scale + /// + [DxfCodeValue(10, 20, 30)] + public XYZ BlockContentScale { get; set; } + + /// + /// Block Content Rotation + /// + [DxfCodeValue(43)] + public double BlockContentRotation { get; set; } + + /// + /// Block Content Connection Type + /// + [DxfCodeValue(176)] + public AttachmentType BlockContentConnection { get; set; } + + #endregion + + /// + /// Enable Annotation Scale + /// + [DxfCodeValue(293)] + public bool EnableAnnotationScale { get; set; } + + // TODO According to the OpenDesign_Specification_for_.dwg_files + // a list of arror head AND a list of block attributes can occur. + // If both list are empty it ist expected that two BL-field should + // occur yielding count=0 for both lists. But when we read two + // BL-fields we get out of sync. If we read one BL-field everything + // works fine. + // We do not understand what a list of arroheads can be used for, + // and we do not know how to create such a list. + // The documentation for arrowheads list in OpenDesign_Specification_for_.dwg_files + // and the DXF Reference are contracicting. + // Decision: + // Ommit the Arrowheads property, + // try to keep the block attributes. + + // public IList Arrowheads { get; } = new List(); + + + /// + /// Gets a list of objects representing + /// a reference to a "block attribute"? and some proprties to adjust + /// the attribute. + /// + public IList BlockAttributes { get; } = new List(); + + /// + /// Text Direction Negative + /// + [DxfCodeValue(294)] + public bool TextDirectionNegative { get; set; } + + /// + /// Text Align in IPE (meaning unknown) + /// + [DxfCodeValue(178)] + public short TextAligninIPE { get; set; } + + /// + /// Text Attachment Point + /// + [DxfCodeValue(179)] + public TextAttachmentPointType TextAttachmentPoint { get; set; } + + /// + /// Scale Factor + /// + [DxfCodeValue(45)] + public double ScaleFactor { get; set; } + + /// + /// Text attachment direction for MText contents. + /// + /// + /// A . + /// + [DxfCodeValue(271)] + public TextAttachmentDirectionType TextAttachmentDirection { get; set; } + + /// + /// Bottom text attachment direction. + /// + /// + /// A having the values + /// 9 = Center + /// 10 = Underline and Center + /// + [DxfCodeValue(272)] + public TextAttachmentType TextBottomAttachment { get; set; } + + /// + /// Top text attachment direction. + /// + /// + /// A having the values + /// 9 = Center + /// 10 = Underline and Center + /// + [DxfCodeValue(273)] + public TextAttachmentType TextTopAttachment { get; set; } + + /// + /// Leader extended to text + /// + public bool ExtendedToText { get; set; } + + public override CadObject Clone() + { + MultiLeader clone = (MultiLeader)base.Clone(); + + clone.ContextData = (MultiLeaderAnnotContext)this.ContextData?.Clone(); + + foreach (var att in BlockAttributes) + { + clone.BlockAttributes.Add(att); + } + + return clone; + } + } +} diff --git a/ACadSharp/FlowDirectionType.cs b/ACadSharp/FlowDirectionType.cs new file mode 100644 index 00000000..80c82b6d --- /dev/null +++ b/ACadSharp/FlowDirectionType.cs @@ -0,0 +1,7 @@ +namespace ACadSharp { + public enum FlowDirectionType : short { + Horizontal = 1, + Vertical = 3, + ByStyle = 6, + } +} \ No newline at end of file diff --git a/ACadSharp/IO/DWG/DwgStreamReaders/DwgMergedReader.cs b/ACadSharp/IO/DWG/DwgStreamReaders/DwgMergedReader.cs index 2abf1357..34fd525e 100644 --- a/ACadSharp/IO/DWG/DwgStreamReaders/DwgMergedReader.cs +++ b/ACadSharp/IO/DWG/DwgStreamReaders/DwgMergedReader.cs @@ -49,7 +49,7 @@ public DwgMergedReader(IDwgStreamReader manReader, IDwgStreamReader textReader, public void Advance(int offset) { - throw new InvalidOperationException(); + _mainReader.Advance(offset); } public void AdvanceByte() diff --git a/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs b/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs index 1c49bfcb..c96e56c8 100644 --- a/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs +++ b/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs @@ -7,10 +7,13 @@ using ACadSharp.Tables; using ACadSharp.Tables.Collections; using CSMath; +using CSUtilities.IO; using System.Collections.Generic; using System.Linq; using System.IO; using System; +using ACadSharp.Types; +using static ACadSharp.Objects.MultiLeaderAnnotContext; namespace ACadSharp.IO.DWG { @@ -996,8 +999,12 @@ private CadTemplate readUnlistedType(short classNumber) case "MESH": template = this.readMesh(); break; - case "MLEADER": + case "MULTILEADER": + template = this.readMultiLeader(); + break; case "MLEADERSTYLE": + template = this.readMultiLeaderStyle(); + break; case "OLE2FRAME": break; case "ACDBPLACEHOLDER": @@ -2798,6 +2805,493 @@ private CadTemplate readLeader() return template; } + private CadTemplate readMultiLeader() + { + if (!R2010Plus) + { + return null; + } + + MultiLeader mLeader = new MultiLeader(); + CadMLeaderTemplate template = new CadMLeaderTemplate(mLeader); + + this.readCommonEntityData(template); + + // 270 Version, expected to be 2 + var f270 = _objectReader.ReadBitShort(); + + mLeader.ContextData = readMultiLeaderAnnotContext(template); + + // Multileader Common data + // 340 Leader StyleId (handle) + template.LeaderStyleHandle = this.handleReference(); + // 90 Property Override Flags (int32) + mLeader.PropertyOverrideFlags = (MultiLeaderPropertyOverrideFlags)this._objectReader.ReadBitLong(); + // 170 LeaderLineType (short) + mLeader.PathType = (MultiLeaderPathType)_objectReader.ReadBitShort(); + // 91 Leade LineColor (Color) + mLeader.LineColor = _mergedReaders.ReadCmColor(); + // 341 LeaderLineTypeID (handle/LineType) + template.LeaderLineTypeHandle = this.handleReference(); + // 171 LeaderLine Weight + mLeader.LeaderLineWeight = (LineweightType)_objectReader.ReadBitShort(); + // 290 Enable Landing + mLeader.EnableLanding = _objectReader.ReadBit(); + // 291 Enable Dogleg + mLeader.EnableDogleg = _objectReader.ReadBit(); + + // TODO Why do we need this + _objectReader.Advance(2); + + // 41 Dogleg Length / Landing distance + mLeader.LandingDistance = _objectReader.ReadBitDouble(); + // 342 Arrowhead ID + template.ArrowheadHandle = this.handleReference(); + // 42 Arrowhead Size + mLeader.ArrowheadSize = _objectReader.ReadBitDouble(); + // 172 Content Type + mLeader.ContentType = (LeaderContentType)_objectReader.ReadBitShort(); + // 343 Text Style ID (handle/TextStyle) + template.MTextStyleHandle = this.handleReference(); + // 173 Text Left Attachment Type + mLeader.TextLeftAttachment = (TextAttachmentType)_objectReader.ReadBitShort(); + // 95 Text Right Attachement Type + mLeader.TextRightAttachment = (TextAttachmentType)_objectReader.ReadBitShort(); + // 174 Text Angle Type + mLeader.TextAngle = (TextAngleType)_objectReader.ReadBitShort(); + // 175 Text Alignment Type + mLeader.TextAlignment = (TextAlignmentType)_objectReader.ReadBitShort(); + // 92 Text Color + mLeader.TextColor = _mergedReaders.ReadCmColor(); + // 292 Enable Frame Text + mLeader.TextFrame = _objectReader.ReadBit(); + // 344 Block Content ID + template.BlockContentHandle = this.handleReference(); + // 93 Block Content Color + mLeader.BlockContentColor = _mergedReaders.ReadCmColor(); + // 10 Block Content Scale + mLeader.BlockContentScale = _objectReader.Read3BitDouble(); + // 43 Block Content Rotation + mLeader.BlockContentRotation = _objectReader.ReadBitDouble(); + // 176 Block Content Connection Type + mLeader.BlockContentConnection = (AttachmentType)_objectReader.ReadBitShort(); + // 293 Enable Annotation Scale/Is annotative + mLeader.EnableAnnotationScale = _objectReader.ReadBit(); + + //if (R2007pre) + //{ + // BL number of arrow heads Read2Bits returns 2 --> 0 + //int arrowHeadCount = _objectReader.ReadBitLong(); + //for (int ah = 0; ah < arrowHeadCount; ah++) { + // // DXF: 94 BL Arrowhead Index (DXF) + // // ODA: 94 B Is Default + // int arrowheadIndex = _objectReader.ReadBitLong(); + // //bool isDefault = _objectReader.ReadBit(); + // bool isDefault = true; + // // 345 Arrowhead ID + // template.ArrowheadHandles.Add(this.handleReference(), isDefault); + //} + //} + + // BL Number of Block Labels + int blockLabelCount = _objectReader.ReadBitShort(); + // 330 Block Attribute definition handle (hard pointer) + // 302 Block Attribute Text String + // 177 Block Attribute Index + // 44 Block Attribute Width + for (int bl = 0; bl < blockLabelCount; bl++) { + var attributeHandle = this.handleReference(); + var blockAttribute = new MultiLeader.BlockAttribute() { + Text = _textReader.ReadVariableText(), + Index = _objectReader.ReadBitShort(), + Width = _objectReader.ReadBitDouble() + }; + mLeader.BlockAttributes.Add(blockAttribute); + template.BlockAttributeHandles.Add(blockAttribute, attributeHandle); + } + + // 294 Text Direction Negative + mLeader.TextDirectionNegative = _objectReader.ReadBit(); + // 178 Text Align in IPE + mLeader.TextAligninIPE = _objectReader.ReadBitShort(); + // 179 Text Attachment Point + mLeader.TextAttachmentPoint = (TextAttachmentPointType)_objectReader.ReadBitShort(); + // 45 BD ScaleFactor + mLeader.ScaleFactor = _objectReader.ReadBitDouble(); + + // 271 Text attachment direction for MText contents + mLeader.TextAttachmentDirection = (TextAttachmentDirectionType)_objectReader.ReadBitShort(); + // 272 Bottom text attachment direction (sequence my be interchanged) + mLeader.TextBottomAttachment = (TextAttachmentType)_objectReader.ReadBitShort(); + // 273 Top text attachment direction + mLeader.TextTopAttachment = (TextAttachmentType)_objectReader.ReadBitShort(); + + if (R2013Plus) + { + // 295 Leader extended to text + mLeader.ExtendedToText = _objectReader.ReadBit(); + } + return template; + } + + + private MultiLeaderAnnotContext readMultiLeaderAnnotContext(CadMLeaderTemplate template) { + MultiLeaderAnnotContext annotContext = new MultiLeaderAnnotContext(); + + // BL - Number of leader roots + int leaderRootCount = _objectReader.ReadBitLong(); + for (int i = 0; i < leaderRootCount; i++) { + annotContext.LeaderRoots.Add(readLeaderRoot(template)); + } + + // Common + // BD 40 Overall scale + annotContext.OverallScale = _objectReader.ReadBitDouble(); + // 3BD 10 Content base point + annotContext.ContentBasePoint = _objectReader.Read3BitDouble(); + // BD 41 Text height + annotContext.TextHeight = _objectReader.ReadBitDouble(); + // BD 140 Arrow head size + annotContext.ArrowheadSize = _objectReader.ReadBitDouble(); + // BD 145 Landing gap + annotContext.LandingGap = _objectReader.ReadBitDouble(); + // BS 174 Style left text attachment type. See also MLEADER style left text attachment type for values. Relevant if mleader attachment direction is horizontal. + annotContext.TextLeftAttachment = (TextAttachmentType)_objectReader.ReadBitShort(); + // BS 175 Style right text attachment type. See also MLEADER style left text attachment type for values. Relevant if mleader attachment direction is horizontal. + annotContext.TextRightAttachment = (TextAttachmentType)_objectReader.ReadBitShort(); + // BS 176 Text align type (0 = left, 1 = center, 2 = right) + annotContext.TextAlignment = (TextAlignmentType)_objectReader.ReadBitShort(); + // BS 177 Attachment type (0 = content extents, 1 = insertion point). + annotContext.AttachmentType = (AttachmentType)_objectReader.ReadBitShort(); + // B 290 Has text contents + annotContext.HasTextContents = _objectReader.ReadBit(); + if (annotContext.HasTextContents) { + // TV 304 Text label + annotContext.TextLabel = _textReader.ReadVariableText(); + // 3BD 11 Normal vector + annotContext.Normal = _objectReader.Read3BitDouble(); + // H 340 Text style handle (hard pointer) + template.AnnotContextTextStyleHandle = this.handleReference(); + // 3BD 12 Location + annotContext.Location = _objectReader.Read3BitDouble(); + // 3BD 13 Direction + annotContext.Direction = _objectReader.Read3BitDouble(); + // BD 42 Rotation (radians) + annotContext.Rotation = _objectReader.ReadBitDouble(); + // BD 43 Boundary width + annotContext.BoundaryWidth = _objectReader.ReadBitDouble(); + // BD 44 Boundary height + annotContext.BoundaryHeight = _objectReader.ReadBitDouble(); + // BD 45 Line spacing factor + annotContext.LineSpacingFactor = _objectReader.ReadBitDouble(); + // BS 170 Line spacing style (1 = at least, 2 = exactly) + annotContext.LineSpacing = (LineSpacingStyle)_objectReader.ReadBitShort(); + // CMC 90 Text color + annotContext.TextColor = _objectReader.ReadCmColor(); + // BS 171 Alignment (1 = left, 2 = center, 3 = right) + annotContext.TextAlignment = (TextAlignmentType)_objectReader.ReadBitShort(); + // BS 172 Flow direction (1 = horizontal, 3 = vertical, 6 = by style) + annotContext.FlowDirection = (FlowDirectionType)_objectReader.ReadBitShort(); + // CMC 91 Background fill color + annotContext.BackgroundFillColor = _objectReader.ReadCmColor(); + // BD 141 Background scale factor + annotContext.BackgroundScaleFactor = _objectReader.ReadBitDouble(); + // BL 92 Background transparency + annotContext.BackgroundTransparency = _objectReader.ReadBitLong(); + // B 291 Is background fill enabled + annotContext.BackgroundFillEnabled = _objectReader.ReadBit(); + // B 292 Is background mask fill on + annotContext.BackgroundMaskFillOn = _objectReader.ReadBit(); + // BS 173 Column type (ODA writes 0), *TODO: what meaning for values? + annotContext.ColumnType = _objectReader.ReadBitShort(); + // B 293 Is text height automatic? + annotContext.TextHeightAutomatic = _objectReader.ReadBit(); + // BD 142 Column width + annotContext.ColumnWidth = _objectReader.ReadBitDouble(); + // BD 143 Column gutter + annotContext.ColumnGutter = _objectReader.ReadBitDouble(); + // B 294 Column flow reversed + annotContext.ColumnFlowReversed = _objectReader.ReadBit(); + + // Column sizes + // BD 144 Column size + int columnSizesCount = _objectReader.ReadBitLong(); + for (int i = 0; i < columnSizesCount; i++) { + annotContext.ColumnSizes.Add(_objectReader.ReadBitDouble()); + } + + // B 295 Word break + annotContext.WordBreak = _objectReader.ReadBit(); + // B Unknown + _objectReader.ReadBit(); + // ELSE(Has text contents) + } + else if (annotContext.HasContentsBlock = _objectReader.ReadBit()) { + //B 296 Has contents block + //IF Has contents block + // H 341 AcDbBlockTableRecord handle (soft pointer) + template.AnnotContextBlockRecordHandle = this.handleReference(); + // 3BD 14 Normal vector + annotContext.Normal = _objectReader.Read3BitDouble(); + // 3BD 15 Location + annotContext.Location = _objectReader.Read3BitDouble(); + // 3BD 16 Scale vector + annotContext.BlockContentScale = _objectReader.Read3BitDouble(); + // BD 46 Rotation (radians) + annotContext.Rotation = _objectReader.ReadBitDouble(); + // CMC 93 Block color + annotContext.BlockContentColor = _objectReader.ReadCmColor(); + // BD (16) 47 16 doubles containing the complete transformation + // matrix. Order of transformation is: + // - Rotation, + // - OCS to WCS (using normal vector), + // - Scaling (using scale vector) + // - Translation (using location) + // Simply read an array of 16 doubles: + double[] matrix = annotContext.TransformationMatrix; + matrix[0] = _objectReader.ReadBitDouble(); + matrix[1] = _objectReader.ReadBitDouble(); + matrix[2] = _objectReader.ReadBitDouble(); + matrix[3] = _objectReader.ReadBitDouble(); + matrix[4] = _objectReader.ReadBitDouble(); + matrix[5] = _objectReader.ReadBitDouble(); + matrix[6] = _objectReader.ReadBitDouble(); + matrix[7] = _objectReader.ReadBitDouble(); + matrix[8] = _objectReader.ReadBitDouble(); + matrix[9] = _objectReader.ReadBitDouble(); + matrix[10] = _objectReader.ReadBitDouble(); + matrix[11] = _objectReader.ReadBitDouble(); + matrix[12] = _objectReader.ReadBitDouble(); + matrix[13] = _objectReader.ReadBitDouble(); + matrix[14] = _objectReader.ReadBitDouble(); + matrix[16] = _objectReader.ReadBitDouble(); + } + //END IF Has contents block + //END IF Has text contents + + // 3BD 110 Base point + annotContext.BasePoint = _objectReader.Read3BitDouble(); + // 3BD 111 Base direction + annotContext.BaseDirection = _objectReader.Read3BitDouble(); + // 3BD 112 Base vertical + annotContext.BaseVertical = _objectReader.Read3BitDouble(); + // B 297 Is normal reversed? + annotContext.NormalReversed = _objectReader.ReadBit(); + + // BS 273 Style top attachment + annotContext.TextTopAttachment = (TextAttachmentType)_objectReader.ReadBitShort(); + // BS 272 Style bottom attachment + annotContext.TextBottomAttachment = (TextAttachmentType)_objectReader.ReadBitShort(); + + return annotContext; + } + + private LeaderRoot readLeaderRoot(CadMLeaderTemplate template) { + LeaderRoot leaderRoot = new LeaderRoot(); + + // B 290 Is content valid(ODA writes true)/DXF: Has Set Last Leader Line Point + leaderRoot.ContentValid = _objectReader.ReadBit(); + // B 291 Unknown(ODA writes true)/DXF: Has Set Dogleg Vector + leaderRoot.Unknown = _objectReader.ReadBit(); + // 3BD 10 Connection point/DXF: Last Leader Line Point + leaderRoot.ConnectionPoint = _objectReader.Read3BitDouble(); + // 3BD 11 Direction/DXF: Dogleg vector + leaderRoot.Direction = _objectReader.Read3BitDouble(); + + // Break start/end point pairs + // BL Number of break start / end point pairs + // 3BD 12 Break start point + // 3BD 13 Break end point + int breakStartEndPointCount = _objectReader.ReadBitLong(); + for (int bsep = 0; bsep < breakStartEndPointCount; bsep++) { + leaderRoot.BreakStartEndPointsPairs.Add(new StartEndPointPair( + _objectReader.Read3BitDouble(), + _objectReader.Read3BitDouble())); + } + + // BL 90 Leader index + leaderRoot.LeaderIndex = _objectReader.ReadBitLong(); + // BD 40 Landing distance + leaderRoot.LandingDistance = _objectReader.ReadBitDouble(); + + // Leader lines + // BL Number of leader lines + int leaderLineCount = _objectReader.ReadBitLong(); + for (int ll = 0; ll < leaderLineCount; ll++) { + leaderRoot.Lines.Add(readLeaderLine(template)); + } + + // BS 271 Attachment direction(0 = horizontal, 1 = vertical, default is 0) + leaderRoot.AttachmentDirection = (TextAttachmentDirectionType)_objectReader.ReadBitShort(); + + return leaderRoot; + } + + private LeaderLine readLeaderLine(CadMLeaderTemplate template) { + LeaderLine leaderLine = new LeaderLine(); + CadMLeaderTemplate.LeaderLineSubTemplate leaderLineSubTemplate = new CadMLeaderTemplate.LeaderLineSubTemplate(leaderLine); + template.LeaderLineSubTemplates.Add(leaderLineSubTemplate); + + // Points + // BL - Number of points + // 3BD 10 Point + int pointCount = _objectReader.ReadBitLong(); + for (int p = 0; p < pointCount; p++) { + leaderLine.Points.Add(_objectReader.Read3BitDouble()); + } + + // Add optional Break Info (one or more) + // BL Break info count + leaderLine.BreakInfoCount = _objectReader.ReadBitLong(); + if (leaderLine.BreakInfoCount > 0) { + // BL 90 Segment index + leaderLine.SegmentIndex = _objectReader.ReadBitLong(); + + // Start/end point pairs + // 3BD 11 Start Point + // 3BD 12 End point + int startEndPointCount = _objectReader.ReadBitLong(); + for (int sep = 0; sep < startEndPointCount; sep++) { + leaderLine.StartEndPoints.Add(new StartEndPointPair( + _objectReader.Read3BitDouble(), + _objectReader.Read3BitDouble())); + } + } + + // BL 91 Leader line index + leaderLine.Index = _objectReader.ReadBitLong(); + + // BS 170 Leader type(0 = invisible leader, 1 = straight leader, 2 = spline leader) + leaderLine.PathType = (MultiLeaderPathType)_objectReader.ReadBitShort(); + // CMC 92 Line color + leaderLine.LineColor = _objectReader.ReadCmColor(); + // H 340 Line type handle(hard pointer) + leaderLineSubTemplate.LineTypeHandle = this.handleReference(); + // BL 171 Line weight + leaderLine.LineWeight = (LineweightType)_objectReader.ReadBitLong(); + // BD 40 Arrow size + leaderLine.ArrowheadSize = _objectReader.ReadBitDouble(); + // H 341 Arrow symbol handle(hard pointer) + leaderLineSubTemplate.ArrowSymbolHandle = this.handleReference(); + + // BL 93 Override flags (1 = leader type, 2 = line color, 4 = line type, 8 = line weight, 16 = arrow size, 32 = arrow symbol(handle) + leaderLine.OverrideFlags = (LeaderLinePropertOverrideFlags)_objectReader.ReadBitLong(); + + return leaderLine; + } + + private CadTemplate readMultiLeaderStyle() + { + if (!R2010Plus) + { + return null; + } + + MultiLeaderStyle mLeaderStyle = new MultiLeaderStyle(); + CadMLeaderStyleTemplate template = new CadMLeaderStyleTemplate(mLeaderStyle); + + this.readCommonNonEntityData(template); + + // BS 179 Version expected: 2 + var version = _objectReader.ReadBitShort(); + + // BS 170 Content type (see paragraph on LEADER for more details). + mLeaderStyle.ContentType = (LeaderContentType)_objectReader.ReadBitShort(); + // BS 171 Draw multi-leader order (0 = draw content first, 1 = draw leader first) + mLeaderStyle.MultiLeaderDrawOrder = (MultiLeaderDrawOrderType)_objectReader.ReadBitShort(); + // BS 172 Draw leader order (0 = draw leader head first, 1 = draw leader tail first) + mLeaderStyle.LeaderDrawOrder = (LeaderDrawOrderType)_objectReader.ReadBitShort(); + // BL 90 Maximum number of points for leader + mLeaderStyle.MaxLeaderSegmentsPoints = _objectReader.ReadBitShort(); + // BD 40 First segment angle (radians) + mLeaderStyle.FirstSegmentAngleConstraint = _objectReader.ReadBitDouble(); + // BD 41 Second segment angle (radians) + mLeaderStyle.SecondSegmentAngleConstraint = _objectReader.ReadBitDouble(); + // BS 173 Leader type (see paragraph on LEADER for more details). + mLeaderStyle.PathType = (MultiLeaderPathType)_objectReader.ReadBitShort(); + // CMC 91 Leader line color + mLeaderStyle.LineColor = _mergedReaders.ReadCmColor(); + // H 340 Leader line type handle (hard pointer) + template.LeaderLineTypeHandle = this.handleReference(); + // BL 92 Leader line weight + mLeaderStyle.LeaderLineWeight = (LineweightType)_objectReader.ReadBitLong(); + // B 290 Is landing enabled? + mLeaderStyle.EnableLanding = _objectReader.ReadBit(); + // BD 42 Landing gap + mLeaderStyle.LandingGap = _objectReader.ReadBitDouble(); + // B 291 Auto include landing (is dog-leg enabled?) + mLeaderStyle.EnableDogleg = _objectReader.ReadBit(); + // BD 43 Landing distance + mLeaderStyle.LandingDistance = _objectReader.ReadBitDouble(); + // TV 3 Style description + mLeaderStyle.Description = _mergedReaders.ReadVariableText(); + // H 341 Arrow head block handle (hard pointer) + template.ArrowheadHandle = this.handleReference(); + // BD 44 Arrow head size + mLeaderStyle.ArrowheadSize = _objectReader.ReadBitDouble(); + // TV 300 Text default + mLeaderStyle.DefaultTextContents = _mergedReaders.ReadVariableText(); + // H 342 Text style handle (hard pointer) + template.MTextStyleHandle = this.handleReference(); + // BS 174 Left attachment (see paragraph on LEADER for more details). + mLeaderStyle.TextLeftAttachment = (TextAttachmentType)_objectReader.ReadBitShort(); + // BS 178 Right attachment (see paragraph on LEADER for more details). + mLeaderStyle.TextRightAttachment = (TextAttachmentType)_objectReader.ReadBitShort(); + if (R2010Plus) {// IF IsNewFormat OR DXF file + // BS 175 Text angle type (see paragraph on LEADER for more details). + mLeaderStyle.TextAngle = (TextAngleType)_objectReader.ReadBitShort(); + + } // END IF IsNewFormat OR DXF file + // BS 176 Text alignment type + mLeaderStyle.TextAlignment = (TextAlignmentType)_objectReader.ReadBitShort(); + // CMC 93 Text color + mLeaderStyle.TextColor = _mergedReaders.ReadCmColor(); + // BD 45 Text height + mLeaderStyle.TextHeight = _objectReader.ReadBitDouble(); + // B 292 Text frame enabled + mLeaderStyle.TextFrame = _objectReader.ReadBit(); + if (R2010Plus) {// IF IsNewFormat OR DXF file + // B 297 Always align text left + mLeaderStyle.TextAlignAlwaysLeft = _objectReader.ReadBit(); + }// END IF IsNewFormat OR DXF file + // BD 46 Align space + mLeaderStyle.AlignSpace = _objectReader.ReadBitDouble(); + // H 343 Block handle (hard pointer) + template.BlockContentHandle = this.handleReference(); + // CMC 94 Block color + mLeaderStyle.BlockContentColor = _mergedReaders.ReadCmColor(); + // 3BD 47,49,140 Block scale vector + mLeaderStyle.BlockContentScale = _objectReader.Read3BitDouble(); + // B 293 Is block scale enabled + mLeaderStyle.EnableBlockContentScale = _objectReader.ReadBit(); + // BD 141 Block rotation (radians) + mLeaderStyle.BlockContentRotation = _objectReader.ReadBitDouble(); + // B 294 Is block rotation enabled + mLeaderStyle.EnableBlockContentRotation = _objectReader.ReadBit(); + // BS 177 Block connection type (0 = MLeader connects to the block extents, 1 = MLeader connects to the block base point) + mLeaderStyle.BlockContentConnection = (BlockContentConnectionType)_objectReader.ReadBitShort(); + // BD 142 Scale factor + mLeaderStyle.ScaleFactor = _objectReader.ReadBitDouble(); + // B 295 Property changed, meaning not totally clear + // might be set to true if something changed after loading, + // or might be used to trigger updates in dependent MLeaders. + // sequence seems to be different in DXF + mLeaderStyle.OverwritePropertyValue = _objectReader.ReadBit(); + // B 296 Is annotative? + mLeaderStyle.IsAnnotative = _objectReader.ReadBit(); + // BD 143 Break size + mLeaderStyle.BreakGapSize = _objectReader.ReadBitDouble(); + + // BS 271 Attachment direction (see paragraph on LEADER for more details). + mLeaderStyle.TextAttachmentDirection = (TextAttachmentDirectionType)_objectReader.ReadBitShort(); + // BS 273 Top attachment (see paragraph on LEADER for more details). + mLeaderStyle.TextBottomAttachment = (TextAttachmentType)_objectReader.ReadBitShort(); + // BS 272 Bottom attachment (see paragraph on LEADER for more details). + mLeaderStyle.TextTopAttachment = (TextAttachmentType)_objectReader.ReadBitShort(); + + return template; + } + private CadTemplate readMLine() { MLine mline = new MLine(); diff --git a/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Entities.cs b/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Entities.cs index 7eb6776e..5e817e08 100644 --- a/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Entities.cs +++ b/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Entities.cs @@ -21,6 +21,7 @@ private void writeEntity(Entity entity) case MText: case Shape: case Solid3D: + case MultiLeader: //Unlisted case Wipeout: this.notify($"Entity type not implemented {entity.GetType().FullName}", NotificationType.NotImplemented); diff --git a/ACadSharp/IO/DXF/DxfStreamWriter/DxfObjectsSectionWriter.cs b/ACadSharp/IO/DXF/DxfStreamWriter/DxfObjectsSectionWriter.cs index 7f38971e..10330b22 100644 --- a/ACadSharp/IO/DXF/DxfStreamWriter/DxfObjectsSectionWriter.cs +++ b/ACadSharp/IO/DXF/DxfStreamWriter/DxfObjectsSectionWriter.cs @@ -1,5 +1,6 @@ using ACadSharp.Entities; using ACadSharp.Objects; +using ACadSharp.Tables; using System; using System.Linq; @@ -30,6 +31,7 @@ protected void writeObject(T co) { case AcdbPlaceHolder: case Material: + case MultiLeaderStyle: case SortEntitiesTable: case Scale: case VisualStyle: diff --git a/ACadSharp/IO/DXF/DxfStreamWriter/DxfSectionWriterBase.Entities.cs b/ACadSharp/IO/DXF/DxfStreamWriter/DxfSectionWriterBase.Entities.cs index acdcd7d9..5a765808 100644 --- a/ACadSharp/IO/DXF/DxfStreamWriter/DxfSectionWriterBase.Entities.cs +++ b/ACadSharp/IO/DXF/DxfStreamWriter/DxfSectionWriterBase.Entities.cs @@ -17,6 +17,7 @@ protected void writeEntity(T entity) case MLine: case MText: case Solid3D: + case MultiLeader: this.notify($"Entity type not implemented : {entity.GetType().FullName}", NotificationType.NotImplemented); return; } diff --git a/ACadSharp/IO/Templates/CadInsertTemplate.cs b/ACadSharp/IO/Templates/CadInsertTemplate.cs index d8329a83..c3cd635b 100644 --- a/ACadSharp/IO/Templates/CadInsertTemplate.cs +++ b/ACadSharp/IO/Templates/CadInsertTemplate.cs @@ -1,4 +1,4 @@ -using ACadSharp.Entities; +using ACadSharp.Entities; using ACadSharp.Tables; using System.Collections.Generic; using ACadSharp.IO.DXF; diff --git a/ACadSharp/IO/Templates/CadMLeaderStyleTemplate.cs b/ACadSharp/IO/Templates/CadMLeaderStyleTemplate.cs new file mode 100644 index 00000000..08052abd --- /dev/null +++ b/ACadSharp/IO/Templates/CadMLeaderStyleTemplate.cs @@ -0,0 +1,34 @@ +using ACadSharp.Tables; + +namespace ACadSharp.IO.Templates { + internal class CadMLeaderStyleTemplate : CadTableEntryTemplate + { + public CadMLeaderStyleTemplate(MultiLeaderStyle entry) : base(entry) { } + + public ulong LeaderLineTypeHandle { get; internal set; } + + public ulong ArrowheadHandle { get; internal set; } + + public ulong MTextStyleHandle { get; internal set; } + + public ulong BlockContentHandle { get; internal set; } + + public override void Build(CadDocumentBuilder builder) { + + base.Build(builder); + + if (builder.TryGetCadObject(this.LeaderLineTypeHandle, out LineType lineType)) { + this.CadObject.LeaderLineType = lineType; + } + //if (builder.TryGetCadObject(this.ArrowheadHandle, out Arr arrowhead)) { + // this.CadObject.Arrowhead = arrowhead; + //} + if (builder.TryGetCadObject(this.MTextStyleHandle, out TextStyle textStyle)) { + this.CadObject.TextStyle = textStyle; + } + if (builder.TryGetCadObject(this.BlockContentHandle, out BlockRecord blockContent)) { + this.CadObject.BlockContent = blockContent; + } + } + } +} diff --git a/ACadSharp/IO/Templates/CadMLeaderTemplate.cs b/ACadSharp/IO/Templates/CadMLeaderTemplate.cs new file mode 100644 index 00000000..dcf92761 --- /dev/null +++ b/ACadSharp/IO/Templates/CadMLeaderTemplate.cs @@ -0,0 +1,115 @@ +using System.Collections.Generic; + +using ACadSharp.Entities; +using ACadSharp.Objects; +using ACadSharp.Tables; + +namespace ACadSharp.IO.Templates +{ + internal class CadMLeaderTemplate : CadEntityTemplate + { + public CadMLeaderTemplate(MultiLeader entity) : base(entity) { } + + public ulong LeaderStyleHandle { get; internal set; } + + public ulong LeaderLineTypeHandle { get; internal set; } + + public ulong MTextStyleHandle { get; internal set; } + + public ulong BlockContentHandle { get; internal set; } + + public ulong ArrowheadHandle { get; internal set; } + + public IDictionary ArrowheadHandles { get; } = new Dictionary(); + + + public IDictionary BlockAttributeHandles { get; } = new Dictionary(); + + // Context-Data Handles + public ulong AnnotContextTextStyleHandle { get; internal set; } + + public ulong AnnotContextBlockRecordHandle { get; internal set; } + + public IList LeaderLineSubTemplates { get; } = new List(); + + + public class LeaderLineSubTemplate + { + public MultiLeaderAnnotContext.LeaderLine LeaderLine { get; } + + public LeaderLineSubTemplate(MultiLeaderAnnotContext.LeaderLine leaderLine) + { + this.LeaderLine = leaderLine; + } + + public ulong LineTypeHandle { get; internal set; } + + public ulong ArrowSymbolHandle { get; internal set; } + } + + + public override void Build(CadDocumentBuilder builder) + { + base.Build(builder); + + MultiLeader multiLeader = (MultiLeader)this.CadObject; + MultiLeaderAnnotContext annotContext = multiLeader.ContextData; + + if (builder.TryGetCadObject(this.AnnotContextTextStyleHandle, out TextStyle annotContextTextStyle)) + { + annotContext.TextStyle = annotContextTextStyle; + } + if (builder.TryGetCadObject(this.AnnotContextBlockRecordHandle, out BlockRecord annotContextBlockRecord)) + { + annotContext.BlockContent = annotContextBlockRecord; + } + + if (builder.TryGetCadObject(this.LeaderStyleHandle, out MultiLeaderStyle leaderStyle)) + { + multiLeader.Style = leaderStyle; + } + if (builder.TryGetCadObject(this.LeaderLineTypeHandle, out LineType lineType)) + { + multiLeader.LeaderLineType = lineType; + } + if (builder.TryGetCadObject(this.MTextStyleHandle, out TextStyle textStyle)) + { + multiLeader.TextStyle = textStyle; + } + if (builder.TryGetCadObject(this.BlockContentHandle, out BlockRecord blockContent)) + { + multiLeader.BlockContent = blockContent; + } + if (builder.TryGetCadObject(this.ArrowheadHandle, out BlockRecord arrowHead)) + { + multiLeader.Arrowhead = arrowHead; + } + + // TODO + foreach (KeyValuePair arrowHeadHandleEntries in ArrowheadHandles) { + } + + foreach (MultiLeader.BlockAttribute blockAttribute in multiLeader.BlockAttributes) + { + ulong attributeHandle = this.BlockAttributeHandles[blockAttribute]; + if (builder.TryGetCadObject(attributeHandle, out AttributeDefinition attributeDefinition)) + { + blockAttribute.AttributeDefinition = attributeDefinition; + } + } + + foreach (LeaderLineSubTemplate leaderLineSubTemplate in this.LeaderLineSubTemplates) + { + MultiLeaderAnnotContext.LeaderLine leaderLine = leaderLineSubTemplate.LeaderLine; + if (builder.TryGetCadObject(leaderLineSubTemplate.LineTypeHandle, out LineType leaderLinelineType)) + { + leaderLine.LineType = leaderLinelineType; + } + if (builder.TryGetCadObject(leaderLineSubTemplate.ArrowSymbolHandle, out BlockRecord arrowhead)) + { + leaderLine.Arrowhead = arrowhead; + } + } + } + } +} diff --git a/ACadSharp/LeaderContentType.cs b/ACadSharp/LeaderContentType.cs new file mode 100644 index 00000000..c6828592 --- /dev/null +++ b/ACadSharp/LeaderContentType.cs @@ -0,0 +1,25 @@ +namespace ACadSharp { + + public enum LeaderContentType : short { + + /// + /// None + /// + None = 0, + + /// + /// Leader content is provided by a block + /// + Block = 1, + + /// + /// Leader content is provided by a MTEXT entity + /// + MText = 2, + + /// + /// Leader content is provided by a TOLERANCE entity + /// + Tolerance = 3 + } +} \ No newline at end of file diff --git a/ACadSharp/LeaderLinePropertOverrideFlags.cs b/ACadSharp/LeaderLinePropertOverrideFlags.cs new file mode 100644 index 00000000..24d6c08b --- /dev/null +++ b/ACadSharp/LeaderLinePropertOverrideFlags.cs @@ -0,0 +1,52 @@ +using System; + +using ACadSharp.Entities; +using ACadSharp.Tables; + +namespace ACadSharp { + + [Flags] + public enum LeaderLinePropertOverrideFlags : Int32 { + + /// + /// No property to be overridden + /// + None = 0, + + /// + /// property + /// overrides settings from and . + /// + PathType = 1, + + /// + /// property + /// overrides settings from and . + /// + LineColor = 2, + + /// + /// property + /// overrides settings from and . + /// + LineType = 4, + + /// + /// property + /// overrides settings from and . + /// + LineWeight = 8, + + /// + /// property + /// overrides settings from and . + /// + ArrowheadSize = 16, + + /// + /// property + /// overrides settings from and . + /// + Arrowhead = 32, + } +} \ No newline at end of file diff --git a/ACadSharp/LineSpacingStyle.cs b/ACadSharp/LineSpacingStyle.cs new file mode 100644 index 00000000..d7c54c6c --- /dev/null +++ b/ACadSharp/LineSpacingStyle.cs @@ -0,0 +1,7 @@ +namespace ACadSharp { + + public enum LineSpacingStyle : short { + AtLeast = 1, + Exactly = 2, + } +} \ No newline at end of file diff --git a/ACadSharp/MultiLeaderPathType.cs b/ACadSharp/MultiLeaderPathType.cs new file mode 100644 index 00000000..30ad0842 --- /dev/null +++ b/ACadSharp/MultiLeaderPathType.cs @@ -0,0 +1,27 @@ +// TODO similar to LeaderPathType +// 0 = straight line leader, 1 = spline leader + + +namespace ACadSharp { + + /// + /// Controls the way the leader is drawn. + /// + public enum MultiLeaderPathType { + + /// + /// Invisible leader + /// + Invisible = 0, + + /// + /// Draws the leader line as a set of straight line segments + /// + StraightLineSegments = 1, + + /// + /// Draws the leader line as a spline + /// + Spline = 2 + } +} diff --git a/ACadSharp/MultiLeaderPropertyOverrideFlags.cs b/ACadSharp/MultiLeaderPropertyOverrideFlags.cs new file mode 100644 index 00000000..20f743ac --- /dev/null +++ b/ACadSharp/MultiLeaderPropertyOverrideFlags.cs @@ -0,0 +1,167 @@ +using System; + +using ACadSharp.Entities; +using ACadSharp.Tables; + +namespace ACadSharp { + + [Flags] + public enum MultiLeaderPropertyOverrideFlags : int { + + /// + /// No Flag: No property to be overridden + /// + None = 0, + + /// + /// Override property. + /// + PathType = 0x1, + + /// + /// Override property. + /// + LineColor = 0x2, + + /// + /// Override property. + /// + LeaderLineType = 0x4, + + /// + /// Override property. + /// + LeaderLineWeight = 0x8, + + /// + /// Override property. + /// + EnableLanding = 0x10, + + /// + /// Override property. + /// + LandingGap = 0x20, + + /// + /// Override property. + /// + EnableDogleg = 0x40, + + /// + /// Override property. + /// + LandingDistance = 0x80, + + /// + /// Override property. + /// + Arrowhead = 0x100, + + /// + /// Override property. + /// + ArrowheadSize = 0x200, + + /// + /// Override property. + /// + ContentType = 0x400, + + /// + /// Override property. + /// + TextStyle = 0x800, + + /// + /// Override property. + /// + TextLeftAttachment = 0x1000, + + /// + /// Override property. + /// + TextAngle = 0x2000, + + /// + /// Override property. + /// + TextAlignment = 0x4000, + + /// + /// Override property. + /// + TextColor = 0x8000, + + /// + /// Override property. + /// + TextHeight = 0x10000, + + /// + /// Override property. + /// + TextFrame = 0x20000, + + /// + /// Override property. + /// + EnableUseDefaultMText = 0x40000, + + /// + /// Override property. + /// + BlockContent = 0x80000, + + /// + /// Override property. + /// + BlockContentColor = 0x100000, + + /// + /// Override property. + /// + BlockContentScale = 0x200000, + + /// + /// Override property. + /// + BlockContentRotation = 0x400000, + + /// + /// Override property. + /// + BlockConnectionConnection = 0x800000, + + + /// + /// Override property. + /// + ScaleFactor = 0x1000000, + + /// + /// Override property. + /// + TextRightAttachment = 0x2000000, + + /// + /// Override property. + /// + TextSwitchAlignmentType = 0x4000000, + + /// + /// Override property. + /// + TextAttachmentDirection = 0x8000000, + + /// + /// Override property. + /// + TextTopAttachment = 0x10000000, + + /// + /// Override property. + /// + TextBottomAttachment = 0x20000000 + } +} diff --git a/ACadSharp/Objects/MultiLeaderAnnotContext.cs b/ACadSharp/Objects/MultiLeaderAnnotContext.cs new file mode 100644 index 00000000..d7951f8a --- /dev/null +++ b/ACadSharp/Objects/MultiLeaderAnnotContext.cs @@ -0,0 +1,364 @@ +using System.Collections.Generic; + +using ACadSharp.Attributes; +using ACadSharp.Tables; + +using CSMath; + + +namespace ACadSharp.Objects +{ + + /// + /// This class represents a subset ob the properties of the MLeaderAnnotContext + /// object, that are embedded into the MultiLeader entity. + /// + public partial class MultiLeaderAnnotContext : CadObject + { + public override ObjectType ObjectType => ObjectType.UNLISTED; + + /// + public override string SubclassMarker => DxfSubclassMarker.MultiLeaderAnnotContext; + + /// + public override string ObjectName => DxfFileToken.ObjectMLeaderContextData; + + + /// + /// Leader Roots + /// + public IList LeaderRoots { get; } = new List(); + + + /// + /// Overall scale + /// + [DxfCodeValue(40)] + public double OverallScale { get; set; } + + /// + /// Content base point + /// + [DxfCodeValue(10, 20, 30)] + public XYZ ContentBasePoint { get; set; } + + /// + /// Text height + /// + [DxfCodeValue(41)] + public double TextHeight { get; set; } + + /// + /// Arrow head size + /// + [DxfCodeValue(140)] + public double ArrowheadSize { get; set; } + + /// + /// Landing gap + /// + [DxfCodeValue(145)] + public double LandingGap { get; set; } + + /// + /// Style left text attachment type + /// + /// + /// See also MLEADER style left text attachment type for values. + /// Relevant if mleader attachment direction is horizontal. + /// + [DxfCodeValue(174)] + public TextAttachmentType TextLeftAttachment { get; set; } + + /// + /// Style right text attachment type + /// + /// + /// See also MLEADER style left text attachment type for values. + /// Relevant if mleader attachment direction is horizontal. + /// + [DxfCodeValue(175)] + public TextAttachmentType TextRightAttachment { get; set; } + + /// + /// Text align type + /// + [DxfCodeValue(176)] + public TextAlignmentType TextAlignment { get; set; } + + /// + /// Attachment type + /// --> MLeader.BlockContentConnectionType + /// + [DxfCodeValue(177)] + public AttachmentType AttachmentType { get; set; } + + /// + /// Has text contents + /// + [DxfCodeValue(290)] + public bool HasTextContents { get; set; } + + /// + /// Text label + /// + [DxfCodeValue(304)] + public string TextLabel { get; set; } + + /// + /// Normal vector + /// + [DxfCodeValue(11)] + public XYZ Normal { get; set; } + + /// + /// Text style handle (hard pointer) + /// + [DxfCodeValue(340)] + public TextStyle TextStyle { get; set; } + + /// + /// Location + /// + [DxfCodeValue(12, 22, 32)] + public XYZ Location { get; set; } + + /// + /// Direction + /// + [DxfCodeValue(13, 23, 33)] + public XYZ Direction { get; set; } + + /// + /// Rotation (radians) + /// + [DxfCodeValue(42)] + public double Rotation { get; set; } + + /// + /// Boundary width + /// + [DxfCodeValue(43)] + public double BoundaryWidth { get; set; } + + /// + /// Boundary height + /// + [DxfCodeValue(44)] + public double BoundaryHeight { get; set; } + + /// + /// Line spacing factor + /// + [DxfCodeValue(45)] + public double LineSpacingFactor { get; set; } + + /// + /// Line spacing style + /// + [DxfCodeValue(170)] + public LineSpacingStyle LineSpacing { get; set; } + + /// + /// Text color + /// + [DxfCodeValue(90)] + public Color TextColor { get; set; } + + // BS 171 Alignment (1 = left, 2 = center, 3 = right) + // see above: TextAlignment + + /// + /// Flow direction + /// + [DxfCodeValue(172)] + public FlowDirectionType FlowDirection { get; set; } + + /// + /// Background fill color + /// + [DxfCodeValue(91)] + public Color BackgroundFillColor { get; set; } + + /// + /// Background scale factor + /// + [DxfCodeValue(141)] + public double BackgroundScaleFactor { get; set; } + + /// + /// Background transparency + /// + [DxfCodeValue(92)] + public int BackgroundTransparency { get; set; } + + /// + /// Is background fill enabled + /// + [DxfCodeValue(291)] + public bool BackgroundFillEnabled { get; set; } + + /// + /// Is background mask fill on + /// + [DxfCodeValue(292)] + public bool BackgroundMaskFillOn { get; set; } + + /// + /// Column type (ODA writes 0) + /// + [DxfCodeValue(173)] + public short ColumnType { get; set; } + + /// + /// Is text height automatic? + /// + [DxfCodeValue(293)] + public bool TextHeightAutomatic { get; set; } + + /// + /// Column width + /// + [DxfCodeValue(142)] + public double ColumnWidth { get; set; } + + /// + /// Column gutter + /// + [DxfCodeValue(143)] + public double ColumnGutter { get; set; } + + /// + /// Column flow reversed + /// + [DxfCodeValue(294)] + public bool ColumnFlowReversed { get; set; } + + /// + /// Get a list of column sizes + /// + [DxfCodeValue(144)] + public IList ColumnSizes { get; } = new List(); + + /// + /// Word break + /// + [DxfCodeValue(295)] + public bool WordBreak { get; set; } + + /// + /// Has contents block + /// + [DxfCodeValue(296)] + public bool HasContentsBlock { get; set; } + + /// + /// Gets a containing elements + /// to be drawn as content for the MultiLeader. + /// + [DxfCodeValue(341)] + public BlockRecord BlockContent { get; set; } + + // These fields read from DWG are stored into the + // Normal and Location property (see above). + //3BD 14 Normal vector + //3BD 15 Location + + /// + /// Scale vector + /// + [DxfCodeValue(16)] + public XYZ BlockContentScale { get; set; } + + // This field read from DWG are stored into the + // Rotation property (see above). + //BD 46 Rotation (radians) + + /// + /// Block color + /// + [DxfCodeValue(93)] + public Color BlockContentColor { get; set; } + + // TODO ? should double[] be replaced by a TransformationMatrix type? + + /// + /// Gets a array of 16 doubles containg the complete transformation + /// matrix. + /// + /// + /// + /// Order of transformation is: + /// + /// + /// Rotation, + /// OCS to WCS (using normal vector), + /// Scaling (using scale vector), + /// Translation (using location) + /// + /// + [DxfCodeValue(93)] + public double[] TransformationMatrix { get; } = new double[16]; + + /// + /// Base point + /// + [DxfCodeValue(110, 120, 130)] + public XYZ BasePoint { get; set; } + + /// + /// Base direction + /// + [DxfCodeValue(111, 121, 131)] + public XYZ BaseDirection { get; set; } + + /// + /// Base vertical + /// + [DxfCodeValue(112, 122, 132)] + public XYZ BaseVertical { get; set; } + + /// + /// Is normal reversed? + /// + [DxfCodeValue(297)] + public bool NormalReversed { get; set; } + + /// + /// Style top attachment. + /// + /// + /// See also MLEADER style left text attachment type for values. + /// Relevant if mleader attachment direction is vertical. + /// + [DxfCodeValue(273)] + public TextAttachmentType TextTopAttachment { get; set; } + + /// + /// Style bottom attachment. + /// + /// + /// See also MLEADER style left text attachment type for values. + /// Relevant if mleader attachment direction is vertical. + /// + [DxfCodeValue(272)] + public TextAttachmentType TextBottomAttachment { get; set; } + + /// + /// Default constructor + /// + public MultiLeaderAnnotContext() : base() { } + + public override CadObject Clone() + { + MultiLeaderAnnotContext clone = (MultiLeaderAnnotContext)base.Clone(); + + foreach (var leaderRoot in LeaderRoots) + { + clone.LeaderRoots.Add((LeaderRoot)leaderRoot.Clone()); + } + + return clone; + } + } +} \ No newline at end of file diff --git a/ACadSharp/Objects/MultiLeaderAnnotContextClasses.cs b/ACadSharp/Objects/MultiLeaderAnnotContextClasses.cs new file mode 100644 index 00000000..c554dfbf --- /dev/null +++ b/ACadSharp/Objects/MultiLeaderAnnotContextClasses.cs @@ -0,0 +1,215 @@ +using System; +using System.Collections.Generic; + +using ACadSharp.Attributes; +using ACadSharp.Tables; + +using CSMath; + + +namespace ACadSharp.Objects +{ + + /// + /// Nested classes in MultiLeaderAnnotContext + /// + public partial class MultiLeaderAnnotContext : CadObject + { + /// + /// Represents a leader root + /// + /// + /// Appears in DXF as 302 DXF: “LEADER“ + /// + public class LeaderRoot : ICloneable + { + public LeaderRoot() { } + + /// + /// Is content valid (ODA writes true) + /// + public bool ContentValid { get; set; } + + /// + /// Unknown (ODA writes true) + /// + public bool Unknown { get; set; } + + /// + /// Connection point + /// + public XYZ ConnectionPoint { get; set; } + + /// + /// Direction + /// + public XYZ Direction { get; set; } + + /// + /// Gets a list of . + /// + public IList BreakStartEndPointsPairs { get; } = new List(); + + /// + /// Leader index + /// + public int LeaderIndex { get; set; } + + /// + /// Landing distance + /// + public double LandingDistance { get; set; } + + /// + /// Gets a list of objects representing + /// representing leader lines starting from the landing point + /// of the multi leader. + /// + public IList Lines { get; } = new List(); + + //R2010 + /// + /// Attachment direction + /// + public TextAttachmentDirectionType AttachmentDirection { get; internal set; } + + public object Clone() + { + LeaderRoot clone = (LeaderRoot)this.MemberwiseClone(); + + foreach (var breakStartEndPoint in BreakStartEndPointsPairs) + { + clone.BreakStartEndPointsPairs.Add((StartEndPointPair)breakStartEndPoint.Clone()); + } + + foreach (var line in Lines) + { + clone.Lines.Add((LeaderLine)line.Clone()); + } + + return clone; + } + } + + /// + /// Start/end point pairs + /// 3BD 11 Start Point + /// 3BD 12 End point + /// + public struct StartEndPointPair : ICloneable + { + public StartEndPointPair(XYZ startPoint, XYZ endPoint) { + StartPoint = startPoint; + EndPoint = endPoint; + } + + /// + /// Break start point + /// + [DxfCodeValue(12)] + public XYZ StartPoint { get; private set; } + + /// + /// Break end point + /// + [DxfCodeValue(13)] + public XYZ EndPoint { get; private set; } + + public object Clone() + { + return this.MemberwiseClone(); + } + } + + + /// + /// Represents a leader line + /// + /// + /// Appears as 304 DXF: “LEADER_LINE“ + /// + public class LeaderLine : ICloneable + { + public LeaderLine() { } + + /// + /// Points of leader line + /// + public IList Points { get; set; } = new List(); + + /// + /// Break info count + /// + public int BreakInfoCount { get; set; } + + /// + /// Segment index + /// + public int SegmentIndex { get; set; } + + /// + /// Start/end point pairs + /// + public IList StartEndPoints { get; set; } + + /// + /// Leader line index. + /// + public int Index { get; set; } + + //R2010 + /// + /// Leader type + /// + public MultiLeaderPathType PathType { get; set; } + + /// + /// Line color + /// + public Color LineColor { get; set; } + + /// + /// Line type + /// + public LineType LineType { get; set; } + + /// + /// Line weight + /// + public LineweightType LineWeight { get; set; } + + /// + /// Arrowhead size + /// + public double ArrowheadSize { get; set; } + + /// + /// Gets or sets a containig elements + /// to be dawn as arrow symbol. + /// + public BlockRecord Arrowhead { get; set; } + + /// + /// Override flags + /// + public LeaderLinePropertOverrideFlags OverrideFlags { get; set; } + + public object Clone() + { + LeaderLine clone = (LeaderLine)this.MemberwiseClone(); + + foreach (var point in Points) + { + clone.Points.Add(point); + } + + foreach (var startEndPoint in StartEndPoints) + { + clone.StartEndPoints.Add((StartEndPointPair)startEndPoint.Clone()); + } + + return clone; + } + } + } +} \ No newline at end of file diff --git a/ACadSharp/Tables/BlockContentConnectionType.cs b/ACadSharp/Tables/BlockContentConnectionType.cs new file mode 100644 index 00000000..e56420fb --- /dev/null +++ b/ACadSharp/Tables/BlockContentConnectionType.cs @@ -0,0 +1,15 @@ +namespace ACadSharp.Entities { + + public enum BlockContentConnectionType { + + /// + /// MLeader connects to the block extents + /// + BlockExtents = 0, + + /// + /// MLeader connects to the block base point + /// + BasePoint = 1, + } +} \ No newline at end of file diff --git a/ACadSharp/Tables/LeaderDrawOrderType.cs b/ACadSharp/Tables/LeaderDrawOrderType.cs new file mode 100644 index 00000000..e4bf517e --- /dev/null +++ b/ACadSharp/Tables/LeaderDrawOrderType.cs @@ -0,0 +1,19 @@ +namespace ACadSharp.Tables { + + /// + /// Specifies the draw order of a + /// in a entity. + /// + public enum LeaderDrawOrderType { + + /// + /// 0 = draw leader head first + /// + LeaderHeadFirst = 0, + + /// + /// 1 = draw leader tail first + /// + LeaderTailFirst = 1, + } +} \ No newline at end of file diff --git a/ACadSharp/Tables/MultiLeaderDrawOrderType.cs b/ACadSharp/Tables/MultiLeaderDrawOrderType.cs new file mode 100644 index 00000000..d40c02fc --- /dev/null +++ b/ACadSharp/Tables/MultiLeaderDrawOrderType.cs @@ -0,0 +1,18 @@ +namespace ACadSharp.Tables { + + /// + /// Specifies the draw order of a entity. + /// + public enum MultiLeaderDrawOrderType { + + /// + /// 0 = draw content first, + /// + ContentFirst = 0, + + /// + /// 1 = draw leader first + /// + LeaderFirst = 1, + } +} \ No newline at end of file diff --git a/ACadSharp/Tables/MultiLeaderStyle.cs b/ACadSharp/Tables/MultiLeaderStyle.cs new file mode 100644 index 00000000..6820eaac --- /dev/null +++ b/ACadSharp/Tables/MultiLeaderStyle.cs @@ -0,0 +1,314 @@ +using ACadSharp.Attributes; +using ACadSharp.Entities; + +using CSMath; + + +namespace ACadSharp.Tables +{ + /// + /// Represents a table entry. + /// + /// + /// Object name
+ /// Dxf class name + ///
+ [DxfName(DxfFileToken.EntityMLeaderStyle)] + [DxfSubClass(DxfSubclassMarker.MLeaderStyle)] + public class MultiLeaderStyle : TableEntry + { + /// + public override ObjectType ObjectType => ObjectType.UNLISTED; + + /// + public override string ObjectName => DxfFileToken.EntityMLeaderStyle; + + /// + public override string SubclassMarker => DxfSubclassMarker.MLeaderStyle; + + /// + /// Content Type + /// + [DxfCodeValue(170)] + public LeaderContentType ContentType { get; set; } + + /// + /// DrawMLeaderOrder Type + /// + [DxfCodeValue(171)] + public MultiLeaderDrawOrderType MultiLeaderDrawOrder { get; set; } + + /// + /// DrawLeaderOrder Type + /// + [DxfCodeValue(172)] + public LeaderDrawOrderType LeaderDrawOrder { get; set; } + + /// + /// MaxLeader Segments Points + /// + [DxfCodeValue(90)] + public int MaxLeaderSegmentsPoints { get; set; } + + /// + /// First Segment Angle Constraint + /// + [DxfCodeValue(40)] + public double FirstSegmentAngleConstraint { get; set; } + + /// + /// Second Segment Angle Constraint + /// + [DxfCodeValue(41)] + public double SecondSegmentAngleConstraint { get; set; } + + /// + /// LeaderType + /// + [DxfCodeValue(173)] + public MultiLeaderPathType PathType { get; set; } + + /// + /// LeaderLineColor + /// + [DxfCodeValue(91)] + public Color LineColor { get; set; } + + /// + /// LeaderLineType ID + /// + [DxfCodeValue(340)] + public LineType LeaderLineType { get; set; } + + /// + /// LeaderLineWeight + /// + [DxfCodeValue(92)] + public LineweightType LeaderLineWeight { get; set; } + + /// + /// Enable Landing + /// + [DxfCodeValue(290)] + public bool EnableLanding { get; set; } + + /// + /// Landing Gap + /// + [DxfCodeValue(42)] + public double LandingGap { get; set; } + + /// + /// Enable Dogleg + /// + [DxfCodeValue(291)] + public bool EnableDogleg { get; set; } + + /// + /// Landing Distance + /// + [DxfCodeValue(43)] + public double LandingDistance { get; set; } + + /// + /// Mleader Style Description + /// + [DxfCodeValue(3)] + public string Description { get; set; } + + /// + /// Arrowhead ID is Block? + /// + [DxfCodeValue(341)] + public BlockRecord Arrowhead { get; set; } + + /// + /// Arrowhead Size + /// + [DxfCodeValue(44)] + public double ArrowheadSize { get; set; } + + /// + /// Default MText Contents + /// + [DxfCodeValue(300)] + public string DefaultTextContents { get; set; } + + /// + /// mTextStyleId + /// + [DxfCodeValue(342)] + public TextStyle TextStyle { get; set; } + + /// + /// Text Left Attachment Type + /// + [DxfCodeValue(174)] + public TextAttachmentType TextLeftAttachment { get; set; } + + /// + /// Text Angle Type + /// + [DxfCodeValue(175)] + public TextAngleType TextAngle { get; set; } + + /// + /// Text Alignment Type + /// + [DxfCodeValue(176)] + public TextAlignmentType TextAlignment { get; set; } + + /// + /// Text Right Attachment Type + /// + [DxfCodeValue(178)] + public TextAttachmentType TextRightAttachment { get; set; } + + /// + /// Text Color + /// + [DxfCodeValue(93)] + public Color TextColor { get; set; } + + /// + /// Text Height + /// + [DxfCodeValue(45)] + public double TextHeight { get; set; } + + /// + /// Enable Frame Text + /// + [DxfCodeValue(292)] + public bool TextFrame { get; set; } + + /// + /// Text Align Always Left + /// + [DxfCodeValue(297)] + public bool TextAlignAlwaysLeft { get; set; } + + /// + /// Align Space + /// + [DxfCodeValue(46)] + public double AlignSpace { get; set; } + + /// + /// Block Content ID + /// + [DxfCodeValue(343)] + public BlockRecord BlockContent { get; set; } + + /// + /// Block Content Color + /// + [DxfCodeValue(94)] + public Color BlockContentColor { get; set; } + + /// + /// Block Content Scale + /// + [DxfCodeValue(47, 49, 140)] + public XYZ BlockContentScale { get; set; } + + /// + /// Enable Block Content Scale + /// + [DxfCodeValue(293)] + public bool EnableBlockContentScale { get; set; } + + /// + /// Block Content Rotation + /// + [DxfCodeValue(141)] + public double BlockContentRotation { get; set; } + + /// + /// Enable Block Content Rotation + /// + [DxfCodeValue(294)] + public bool EnableBlockContentRotation { get; set; } + + /// + /// Block Content Connection Type + /// + [DxfCodeValue(177)] + public BlockContentConnectionType BlockContentConnection { get; set; } + + /// + /// Scale + /// + [DxfCodeValue(142)] + public double ScaleFactor { get; set; } + + /// + /// Overwrite Property Value + /// + /// + /// Property changed, meaning not totally clear + /// might be set to true if something changed after loading, + /// or might be used to trigger updates in dependent MLeaders. + /// sequence seems to be different in DXF + /// + [DxfCodeValue(295)] + public bool OverwritePropertyValue { get; set; } + + /// + /// Is Annotative + /// + [DxfCodeValue(296)] + public bool IsAnnotative { get; set; } + + /// + /// Break Gap Size + /// + [DxfCodeValue(143)] + public double BreakGapSize { get; set; } + + /// + /// Text attachment direction for MText contents + /// + [DxfCodeValue(271)] + public TextAttachmentDirectionType TextAttachmentDirection { get; set; } + + /// + /// Bottom text attachment direction + /// + /// + /// A having the values + /// 9 = Center + /// 10 = Underline and Center + /// + [DxfCodeValue(272)] + public TextAttachmentType TextBottomAttachment { get; set; } + + /// + /// Top text attachment direction + /// + /// + /// A having the values + /// 9 = Center + /// 10 = Underline and Center + /// + [DxfCodeValue(273)] + public TextAttachmentType TextTopAttachment { get; set; } + + /// + /// Default constructor + /// + public MultiLeaderStyle() : base() { } + + public MultiLeaderStyle(string name) : this() + { + Name = name; + } + + public override CadObject Clone() + { + MultiLeaderStyle clone = (MultiLeaderStyle)base.Clone(); + + return clone; + } + } +} diff --git a/ACadSharp/TextAlignmentType.cs b/ACadSharp/TextAlignmentType.cs new file mode 100644 index 00000000..884e2b23 --- /dev/null +++ b/ACadSharp/TextAlignmentType.cs @@ -0,0 +1,9 @@ +namespace ACadSharp { + + public enum TextAlignmentType : short { + + Left = 0, + Center = 1, + Right = 2, + } +} \ No newline at end of file diff --git a/ACadSharp/TextAngleType.cs b/ACadSharp/TextAngleType.cs new file mode 100644 index 00000000..a49f37a2 --- /dev/null +++ b/ACadSharp/TextAngleType.cs @@ -0,0 +1,22 @@ +namespace ACadSharp { + + public enum TextAngleType : short { + + /// + /// Text angle is equal to last leader line segment angle + /// + ParllelToLastLeaderLine = 0, + + /// + /// Text is horizontal + /// + Horizontal = 1, + + /// + /// Text angle is equal to last leader line segment angle, + /// but potentially rotated by 180 degrees so the right side is up + /// for readability. + /// + Optimized = 2, + } +} diff --git a/ACadSharp/TextAttachmentDirectionType.cs b/ACadSharp/TextAttachmentDirectionType.cs new file mode 100644 index 00000000..f21bac4a --- /dev/null +++ b/ACadSharp/TextAttachmentDirectionType.cs @@ -0,0 +1,9 @@ +namespace ACadSharp { + + public enum TextAttachmentDirectionType { + + Horizontal = 0, + + Vertical = 1, + } +} diff --git a/ACadSharp/TextAttachmentPoint.cs b/ACadSharp/TextAttachmentPoint.cs new file mode 100644 index 00000000..4c968df1 --- /dev/null +++ b/ACadSharp/TextAttachmentPoint.cs @@ -0,0 +1,11 @@ +namespace ACadSharp { + + public enum TextAttachmentPointType : short { + + Left = 1, + + Center = 2, + + Right = 3, + } +} \ No newline at end of file diff --git a/ACadSharp/TextAttachmentType.cs b/ACadSharp/TextAttachmentType.cs new file mode 100644 index 00000000..c01d023f --- /dev/null +++ b/ACadSharp/TextAttachmentType.cs @@ -0,0 +1,62 @@ +namespace ACadSharp { + + /// + /// + /// + public enum TextAttachmentType : short { + /// + /// Top of top text line. + /// + TopOfTopLine = 0, + + /// + /// Middle of top text line. + /// + MiddleOfTopLine = 1, + + /// + /// Middle of text. + /// + MiddleOfText = 2, + + /// + /// Middle of bottom text line. + /// + MiddleOfBottomLine = 3, + + /// + /// Bottom of bottom text line. + /// + BottomOfBottomLine = 4, + + /// + /// Bottom text line. + /// + BottomLine = 5, + + /// + /// Bottom of top text line. Underline bottom line. + /// + BottomOfTopLineUnderlineBottomLine = 6, + + /// + /// Bottom of top text line. Underline top line. + /// + BottomOfTopLineUnderlineTopLine = 7, + + /// + /// Bottom of top text line. Underline all content. + /// + BottomofTopLineUnderlineAll = 8, + + /// + /// Center of text (y-coordinate only). + /// + CenterOfText = 9, + + /// + /// Center of text (y-coordinate only), and overline top/underline bottom content. + /// + CenterOfTextOverline = 10, + } +} diff --git a/samples/multileader/sample_MLeader_AC1032.dwg b/samples/multileader/sample_MLeader_AC1032.dwg new file mode 100644 index 00000000..84cce408 Binary files /dev/null and b/samples/multileader/sample_MLeader_AC1032.dwg differ