diff --git a/ACadSharp/DxfFileToken.cs b/ACadSharp/DxfFileToken.cs index a3b8b209..6aa4ca12 100644 --- a/ACadSharp/DxfFileToken.cs +++ b/ACadSharp/DxfFileToken.cs @@ -74,8 +74,7 @@ public static class DxfFileToken public const string EntityLine = "LINE"; public const string EntityLwPolyline = "LWPOLYLINE"; public const string EntityMesh = "MESH"; - public const string EntityMLeader = "MLEADER"; - public const string EntityMLeaderStyle = "MLEADERSTYLE"; + public const string EntityMultiLeader = "MULTILEADER"; public const string EntityMLine = "MLINE"; public const string EntityMText = "MTEXT"; public const string EntityOleFrame = "OLEFRAME"; @@ -114,6 +113,7 @@ public static class DxfFileToken public const string ObjectPlotSettings = "PLOTSETTINGS"; public const string ObjectPlaceholder = "ACDBPLACEHOLDER"; public const string ObjectLayout = "LAYOUT"; + public const string ObjectMLeaderStyle = "MLEADERSTYLE"; public const string ObjectImageDefinition = "IMAGEDEF"; public const string ObjectImageDefinitionReactor = "IMAGEDEF_REACTOR"; public const string ObjectMLineStyle = "MLINESTYLE"; diff --git a/ACadSharp/DxfSubclassMarker.cs b/ACadSharp/DxfSubclassMarker.cs index de1261ea..f428d54e 100644 --- a/ACadSharp/DxfSubclassMarker.cs +++ b/ACadSharp/DxfSubclassMarker.cs @@ -43,7 +43,7 @@ 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 MultiLeader = "AcDbMLeader"; public const string MLeaderStyle = "AcDbMLeaderStyle"; public const string MultiLeaderAnnotContext = "AcDbMultiLeaderAnnotContext"; public const string LwPolyline = "AcDbPolyline"; diff --git a/ACadSharp/Entities/MultiLeader.cs b/ACadSharp/Entities/MultiLeader.cs index 4d181d70..a21e823d 100644 --- a/ACadSharp/Entities/MultiLeader.cs +++ b/ACadSharp/Entities/MultiLeader.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using ACadSharp.Attributes; using ACadSharp.Objects; using ACadSharp.Tables; @@ -12,21 +13,21 @@ namespace ACadSharp.Entities /// Represents a entity. /// /// - /// Object name
- /// Dxf class name + /// Object name
+ /// Dxf class name ///
- [DxfName(DxfFileToken.EntityMLeader)] - [DxfSubClass(DxfSubclassMarker.MLeader)] + [DxfName(DxfFileToken.EntityMultiLeader)] + [DxfSubClass(DxfSubclassMarker.MultiLeader)] public class MultiLeader : Entity { /// public override ObjectType ObjectType => ObjectType.UNLISTED; /// - public override string ObjectName => DxfFileToken.EntityMLeader; + public override string ObjectName => DxfFileToken.EntityMultiLeader; /// - public override string SubclassMarker => DxfSubclassMarker.MLeader; + public override string SubclassMarker => DxfSubclassMarker.MultiLeader; // TODO // We ommit this class because we assumed that the multileader @@ -63,7 +64,7 @@ public class ArrowheadAssociation { /// /// /// - public class BlockAttribute + public class BlockAttribute : ICloneable { /// /// Block Attribute Id @@ -88,6 +89,11 @@ public class BlockAttribute /// [DxfCodeValue(302)] public string Text { get; set; } + + public object Clone() + { + return this.MemberwiseClone(); + } } /// @@ -103,69 +109,149 @@ public class BlockAttribute public MultiLeaderStyle Style { get; set; } /// - /// Property Override Flag + /// Gets or sets a value containing a list of flags indicating which multileader + /// properties specified by the associated + /// are to be overridden by properties specified by this + /// or the attached . /// [DxfCodeValue(90)] public MultiLeaderPropertyOverrideFlags PropertyOverrideFlags { get; set; } /// - /// PathType (Leader Type) + /// Gets or sets a value indicating the path type of this + /// (see ). + /// This property overrides the value from + /// when the flag is set in the + /// property. /// [DxfCodeValue(170)] public MultiLeaderPathType PathType { get; set; } /// - /// LeaderLineColor + /// Gets or sets color of the leader lines of this + /// (see ). + /// This property overrides the value from + /// when the flag is set in the + /// property. /// + /// + /// The value for all leader lines can be overridden for each individual leader line by the + /// property when the + /// flag is set in the + /// property. + /// [DxfCodeValue(91)] public Color LineColor { get; set; } // TODO Additional Line Type? see Entity.LineType. /// - /// Leader Line Type - /// + /// Gets or sets of the leader lines of this + /// (see ). + /// This property overrides the value from + /// when the flag is set in the + /// property. + /// + /// + /// The setting for all leader lines can be overridden for each individual leader line by the + /// property when the + /// flag is set in the + /// property. + /// [DxfCodeValue(341)] public LineType LeaderLineType { get; set; } // TODO Additional Line Weight? see Entity.LineWeight. /// - /// Leader Line Weight - /// + /// Gets or sets a value specifying the lineweight to be applied to all leader lines of this + /// (see ). + /// This property overrides the value from + /// when the flag is set in the + /// property. + /// + /// + /// The value for all leader lines can be overridden for each individual leader line by the + /// property when the + /// flag is set in the + /// property. + /// [DxfCodeValue(171)] public LineweightType LeaderLineWeight { get; set; } /// - /// Enable Landing + /// Gets or sets a value indicating whether landing is enabled. + /// This property overrides the value from + /// when the flag is set in the + /// property. /// [DxfCodeValue(290)] public bool EnableLanding { get; set; } /// - /// Enable Dogleg + /// Gets or sets a value indicating that leader lines of this + /// are to be drawn with a dogleg (see ). + /// This property overrides the value from + /// when the flag is set in the + /// property. /// [DxfCodeValue(291)] public bool EnableDogleg { get; set; } /// - /// Landing Distance + /// Gets or sets the landing distance, i.e. the length of the dogleg, for this . + /// This property overrides the value from + /// when the flag is set in the + /// property. /// + /// + /// There is only one field for the landing distance in the multileader property grid. + /// The value entered arrives in this property and the + /// property. If two leader roots exist both receive the same value. I seems + /// flag is never set. + /// + /// [DxfCodeValue(41)] public double LandingDistance { get; set; } /// - /// Arrowhead ID + /// Gets or sets a representing the arrowhead + /// (see ) to be displayed with every leader line. + /// This property overrides the value from + /// when the flag is set in the + /// property. /// + /// + /// The value for all leader lines can be overridden for each individual leader line by the + /// property when the + /// flag is set in the + /// property. + /// [DxfCodeValue(342)] public BlockRecord Arrowhead { get; set; } /// - /// Arrowhead Size - /// + /// Gests or sets the arrowhead size (see ) + /// for every leader line + /// when the flag is set in the + /// property. + /// + /// + /// + /// The value for all leader lines can be overridden for each individual leader line by the + /// property when the + /// flag is set in the + /// property. + /// + /// This property is also exposed by the class. Values + /// should be equal, the value is + /// assumed to be used. + /// + /// [DxfCodeValue(42)] public double ArrowheadSize { get; set; } /// - /// Content Type + /// Gets or sets a value indicating whether the content of this + /// is a text label, a content block, or a tolerance. /// [DxfCodeValue(172)] public LeaderContentType ContentType { get; set; } @@ -173,43 +259,102 @@ public class BlockAttribute #region Text Menu Properties /// - /// Text Style + /// Gets or sets the to be used to display the text label of this + /// . + /// This property overrides the value from + /// when the flag is set in the + /// property. /// + /// + /// This property is also exposed by the class + /// (). + /// Values should be equal, the + /// is assumed to be used. + /// [DxfCodeValue(343)] public TextStyle TextStyle { get; set; } /// - /// Text Left Attachment Type + /// Gets or sets the text left attachment type (see ). + /// This property overrides the value from + /// when the flag is set (see + /// property). /// + /// + /// This property is also exposed by the class. Values + /// should be equal, the value is + /// assumed to be used. + /// + /// + /// A having the values 0-8 can be used + /// ("horizontal" attachment types). + /// [DxfCodeValue(173)] public TextAttachmentType TextLeftAttachment { get; set; } /// - /// Text Right Attachement Type + /// Gets or sets the text right attachment type (see ). + /// This property overrides the value from + /// when the flag is set (see + /// property). /// + /// + /// This property is also exposed by the class. Values + /// should be equal, the value is + /// assumed to be used. + /// + /// + /// A having the values 0-8 can be used + /// ("horizontal" attachment types). + /// [DxfCodeValue(95)] public TextAttachmentType TextRightAttachment { get; set; } + // TODO How to set this value? /// - /// Text Angle Type + /// Gets or sets a value indicating the text angle. + /// This property overrides the value from + /// when the flag is set (see + /// property). /// [DxfCodeValue(174)] public TextAngleType TextAngle { get; set; } /// - /// Text Alignment + /// Gets or sets the text alignement type. /// + /// + /// The Open Design Specification for DWG documents this property as Unknown, + /// DXF reference as Text Aligment Type. + /// Available DWG and DXF sample documents saved by AutoCAD return always 0=Left. + /// + /// This property is also exposed by the class. Values + /// should be equal, the value is + /// assumed to be used. + /// + /// [DxfCodeValue(175)] public TextAlignmentType TextAlignment { get; set; } /// - /// Text Color + /// Gets or sets the color for the display of the text label. + /// This property overrides the value from + /// when the flag is set (see + /// property). /// + /// + /// This property is also exposed by the class. Values + /// should be equal, the value is + /// assumed to be used. + /// [DxfCodeValue(92)] public Color TextColor { get; set; } /// - /// Enable Frame Text + /// Gets or sets a value indicating that the text label is to be drawn with a frame. + /// This property overrides the value from + /// when the flag is set (see + /// property). /// [DxfCodeValue(292)] public bool TextFrame { get; set; } @@ -218,32 +363,70 @@ public class BlockAttribute #region Block Content Properties /// - /// Block Content + /// Gets a containing elements + /// to be drawn as content for the multileader. + /// This property overrides the value from + /// when the flag is set (see + /// property). /// + /// + /// This property is also exposed by the class. Values + /// should be equal, the value is + /// assumed to be used. + /// [DxfCodeValue(344)] public BlockRecord BlockContent { get; set; } /// - /// Block Content Color + /// Gets or sets the block-content color. + /// This property overrides the value from + /// when the flag is set (see + /// property). /// + /// + /// This property is also exposed by the class. Values + /// should be equal, the value is + /// assumed to be used. + /// [DxfCodeValue(93)] public Color BlockContentColor { get; set; } /// - /// Block Content Scale + /// Gets or sets the scale factor for block content. + /// This property overrides the value from + /// when the flag is set (see + /// property). /// + /// + /// This property is also exposed by the class. Values + /// should be equal, the value is + /// assumed to be used. + /// [DxfCodeValue(10, 20, 30)] public XYZ BlockContentScale { get; set; } /// - /// Block Content Rotation + /// Gets or sets the rotation of the block content of the multileader. /// + /// + /// This property is also exposed by the class. Values + /// should be equal, the value is + /// assumed to be used. + /// [DxfCodeValue(DxfReferenceType.IsAngle, 43)] public double BlockContentRotation { get; set; } /// - /// Block Content Connection Type + /// Gets or sets a value indicating whether the multileader connects to the content-block extents + /// or to the content-block base point + /// when the flag is set in the + /// property. /// + /// + /// This property is also exposed by the class. Values + /// should be equal, the value is + /// assumed to be used. + /// [DxfCodeValue(176)] public BlockContentConnectionType BlockContentConnection { get; set; } @@ -257,7 +440,7 @@ public class BlockAttribute // 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 + // If both list are empty it ist expected that two BL-fields 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. @@ -292,20 +475,54 @@ public class BlockAttribute public short TextAligninIPE { get; set; } /// - /// Text Attachment Point + /// Gets or sets a value indicating the text attachment point. /// + /// + /// The Open Desisign Specification for DWG files documents this property as Justification, + /// the DXF referenece as Text Attachmenst point. + /// + /// This property is also exposed by the class + /// (). + /// The property always has the same value + /// and seems to have the respective value as . + /// The property is to be used. + /// + /// [DxfCodeValue(179)] public TextAttachmentPointType TextAttachmentPoint { get; set; } /// - /// Scale Factor + /// Gets or sets a scale factor (see ). + /// This property overrides the value from + /// when the flag is set (see + /// property). + /// The scale factor is applied by AutoCAD. /// + /// + /// This property is also exposed by the class. Values + /// should be equal, the value is + /// assumed to be relevant. + /// [DxfCodeValue(45)] public double ScaleFactor { get; set; } /// - /// Text attachment direction for MText contents. - /// + /// Gets or sets the Text attachment direction for text or block contents. + /// This property overrides the value from + /// when the flag is set in the + /// property. + /// + /// + /// + /// This property defines whether the leaders attach to the left/right of the content block/text, + /// or attach to the top/bottom. + /// + /// The value for all leader lines can be overridden for each individual leader line by the + /// property when the + /// flag is set in the + /// property. + /// + /// /// /// A . /// @@ -313,23 +530,41 @@ public class BlockAttribute public TextAttachmentDirectionType TextAttachmentDirection { get; set; } /// - /// Bottom text attachment direction. + /// Gets or sets the text bottom attachment type (see ). + /// This property override the value from + /// when the flag is set (see + /// property). /// + /// + /// This property is also exposed by the class. Values + /// should be equal, the value is + /// assumed to be used. + /// /// /// A having the values - /// 9 = Center + /// 9 = Center, /// 10 = Underline and Center + /// can be used ("vertical" attachment types). /// [DxfCodeValue(272)] public TextAttachmentType TextBottomAttachment { get; set; } /// - /// Top text attachment direction. + /// Gets or sets the text top attachment type (see ). + /// This property override the value from + /// when the flag is set (see + /// property). /// + /// + /// This property is also exposed by the class. Values + /// should be equal, the value is + /// assumed to be used. + /// /// /// A having the values - /// 9 = Center + /// 9 = Center, /// 10 = Underline and Center + /// can be used ("vertical" attachment types). /// [DxfCodeValue(273)] public TextAttachmentType TextTopAttachment { get; set; } @@ -345,9 +580,10 @@ public override CadObject Clone() clone.ContextData = (MultiLeaderAnnotContext)this.ContextData?.Clone(); - foreach (var att in BlockAttributes) + clone.BlockAttributes.Clear(); + foreach (var att in this.BlockAttributes) { - clone.BlockAttributes.Add(att); + clone.BlockAttributes.Add((BlockAttribute)att.Clone()); } return clone; diff --git a/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs b/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs index 6780a096..dcb97843 100644 --- a/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs +++ b/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs @@ -2913,7 +2913,7 @@ private CadTemplate readMultiLeader() // 43 Block Content Rotation mLeader.BlockContentRotation = this._objectReader.ReadBitDouble(); // 176 Block Content Connection Type - mLeader.BlockContentConnection = (BlockContentConnectionType)_objectReader.ReadBitShort(); + mLeader.BlockContentConnection = (BlockContentConnectionType)this._objectReader.ReadBitShort(); // 293 Enable Annotation Scale/Is annotative mLeader.EnableAnnotationScale = this._objectReader.ReadBit(); @@ -2935,7 +2935,7 @@ private CadTemplate readMultiLeader() } // BL Number of Block Labels - int blockLabelCount = this._objectReader.ReadBitShort(); + int blockLabelCount = this._objectReader.ReadBitLong(); for (int bl = 0; bl < blockLabelCount; bl++) { // 330 Block Attribute definition handle (hard pointer) @@ -2994,7 +2994,7 @@ private MultiLeaderAnnotContext readMultiLeaderAnnotContext(CadMLeaderTemplate t // Common // BD 40 Overall scale - annotContext.ScaleFactor = _objectReader.ReadBitDouble(); + annotContext.ScaleFactor = this._objectReader.ReadBitDouble(); // 3BD 10 Content base point annotContext.ContentBasePoint = this._objectReader.Read3BitDouble(); // BD 41 Text height @@ -3218,13 +3218,13 @@ private LeaderLine readLeaderLine(CadMLeaderTemplate template) leaderLine.SegmentIndex = this._objectReader.ReadBitLong(); // Start/end point pairs - // 3BD 11 Start Point - // 3BD 12 End point int startEndPointCount = this._objectReader.ReadBitLong(); for (int sep = 0; sep < startEndPointCount; sep++) { leaderLine.StartEndPoints.Add(new StartEndPointPair( + // 3BD 11 Start Point this._objectReader.Read3BitDouble(), + // 3BD 12 End point this._objectReader.Read3BitDouble())); } } @@ -3316,7 +3316,7 @@ private CadTemplate readMultiLeaderStyle() mLeaderStyle.TextAngle = (TextAngleType)this._objectReader.ReadBitShort(); } // END IF IsNewFormat OR DXF file - // BS 176 Text alignment type + // BS 176 Text alignment type mLeaderStyle.TextAlignment = (TextAlignmentType)this._objectReader.ReadBitShort(); // CMC 93 Text color mLeaderStyle.TextColor = this._mergedReaders.ReadCmColor(); @@ -3329,8 +3329,8 @@ private CadTemplate readMultiLeaderStyle() // B 297 Always align text left mLeaderStyle.TextAlignAlwaysLeft = this._objectReader.ReadBit(); }// END IF IsNewFormat OR DXF file - // BD 46 Align space - mLeaderStyle.AlignSpace = _objectReader.ReadBitDouble(); + // BD 46 Align space + mLeaderStyle.AlignSpace = this._objectReader.ReadBitDouble(); // H 343 Block handle (hard pointer) template.BlockContentHandle = this.handleReference(); // CMC 94 Block color diff --git a/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Common.cs b/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Common.cs index 531be021..80e2901d 100644 --- a/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Common.cs +++ b/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Common.cs @@ -2,7 +2,6 @@ using ACadSharp.Entities; using ACadSharp.Tables; using CSUtilities.Converters; -using System; using System.IO; namespace ACadSharp.IO.DWG diff --git a/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Entities.cs b/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Entities.cs index 532ffec8..e9fe7b3c 100644 --- a/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Entities.cs +++ b/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Entities.cs @@ -1,4 +1,5 @@ using ACadSharp.Entities; +using ACadSharp.Objects; using CSMath; using System; using System.Collections.Generic; @@ -19,7 +20,6 @@ private void writeEntity(Entity entity) case UnknownEntity: case AttributeEntity: case Solid3D: - case MultiLeader: case Mesh: this.notify($"Entity type not implemented {entity.GetType().FullName}", NotificationType.NotImplemented); return; @@ -95,6 +95,9 @@ private void writeEntity(Entity entity) case MText mtext: this.writeMText(mtext); break; + case MultiLeader multiLeader: + this.writeMultiLeader(multiLeader); + break; case Point p: this.writePoint(p); break; @@ -1115,6 +1118,363 @@ private void writeLeader(Leader leader) this._writer.HandleReference(DwgReferenceType.HardPointer, leader.Style); } + private void writeMultiLeader(MultiLeader multiLeader) + { + + if (this.R2010Plus) + { + // 270 Version, expected to be 2 + this._writer.WriteBitShort(2); + } + + writeMultiLeaderAnnotContext(multiLeader.ContextData); + + // Multileader Common data + // 340 Leader StyleId (handle) + this._writer.HandleReference(DwgReferenceType.HardPointer, multiLeader.Style); + // 90 Property Override Flags (int32) + this._writer.WriteBitLong((int)multiLeader.PropertyOverrideFlags); + // 170 LeaderLineType (short) + this._writer.WriteBitShort((short)multiLeader.PathType); + // 91 Leade LineColor (Color) + this._writer.WriteCmColor(multiLeader.LineColor); + // 341 LeaderLineTypeID (handle/LineType) + this._writer.HandleReference(DwgReferenceType.HardPointer, multiLeader.LeaderLineType); + // 171 LeaderLine Weight + this._writer.WriteBitLong((short)multiLeader.LeaderLineWeight); + + // 290 Enable Landing + this._writer.WriteBit(multiLeader.EnableLanding); + // 291 Enable Dogleg + this._writer.WriteBit(multiLeader.EnableDogleg); + + // 41 Dogleg Length / Landing distance + this._writer.WriteBitDouble(multiLeader.LandingDistance); + // 342 Arrowhead ID + this._writer.HandleReference(DwgReferenceType.HardPointer, multiLeader.Arrowhead); + //template.ArrowheadHandle = this.handleReference(); + // 42 Arrowhead Size + this._writer.WriteBitDouble(multiLeader.ArrowheadSize); + // 172 Content Type + 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 + this._writer.WriteBitShort((short)multiLeader.TextLeftAttachment); + // 95 Text Right Attachement Type + this._writer.WriteBitShort((short)multiLeader.TextRightAttachment); + // 174 Text Angle Type + this._writer.WriteBitShort((short)multiLeader.TextAngle); + // 175 Text Alignment Type + this._writer.WriteBitShort((short)multiLeader.TextAlignment); + // 92 Text Color + this._writer.WriteCmColor(multiLeader.TextColor); + // 292 Enable Frame Text + this._writer.WriteBit(multiLeader.TextFrame); + // 344 Block Content ID + this._writer.HandleReference(DwgReferenceType.HardPointer, multiLeader.BlockContent); // Hard/soft?? + // 93 Block Content Color + this._writer.WriteCmColor(multiLeader.BlockContentColor); + // 10 Block Content Scale + this._writer.Write3BitDouble(multiLeader.BlockContentScale); + // 43 Block Content Rotation + this._writer.WriteBitDouble(multiLeader.BlockContentRotation); + // 176 Block Content Connection Type + this._writer.WriteBitShort((short)multiLeader.BlockContentConnection); + // 293 Enable Annotation Scale/Is annotative + this._writer.WriteBit(multiLeader.EnableAnnotationScale); + + // R2007pre not supported + + // BL Number of Block Labels + int blockLabelCount = multiLeader.BlockAttributes.Count; + this._writer.WriteBitLong(blockLabelCount); + 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); + // 302 Block Attribute Text String + this._writer.WriteVariableText(blockAttribute.Text); + // 177 Block Attribute Index + this._writer.WriteBitShort(blockAttribute.Index); + // 44 Block Attribute Width + this._writer.WriteBitDouble(blockAttribute.Width); + } + + // 294 Text Direction Negative + this._writer.WriteBit(multiLeader.TextDirectionNegative); + // 178 Text Align in IPE + this._writer.WriteBitShort(multiLeader.TextAligninIPE); + // 179 Text Attachment Point + this._writer.WriteBitShort((short)multiLeader.TextAttachmentPoint); + // 45 BD ScaleFactor + this._writer.WriteBitDouble(multiLeader.ScaleFactor); + + if (this.R2010Plus) { + // 271 Text attachment direction for MText contents + 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) { + // 295 Leader extended to text + this._writer.WriteBit(multiLeader.ExtendedToText); + } + } + + 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++) { + writeLeaderRoot(annotContext.LeaderRoots[i]); + } + + // Common + // BD 40 Overall scale + this._writer.WriteBitDouble(annotContext.ScaleFactor); + // 3BD 10 Content base point + this._writer.Write3BitDouble(annotContext.ContentBasePoint); + // BD 41 Text height + this._writer.WriteBitDouble(annotContext.TextHeight); + // BD 140 Arrow head size + this._writer.WriteBitDouble(annotContext.ArrowheadSize); + // BD 145 Landing gap + this._writer.WriteBitDouble(annotContext.LandingGap); + // BS 174 Style left text attachment type. See also MLEADER style left text attachment type for values. Relevant if mleader attachment direction is horizontal. + this._writer.WriteBitShort((short)annotContext.TextLeftAttachment); + // BS 175 Style right text attachment type. See also MLEADER style left text attachment type for values. Relevant if mleader attachment direction is horizontal. + this._writer.WriteBitShort((short)annotContext.TextRightAttachment); + // BS 176 Text align type (0 = left, 1 = center, 2 = right) + this._writer.WriteBitShort((short)annotContext.TextAlignment); + // BS 177 Attachment type (0 = content extents, 1 = insertion point). + this._writer.WriteBitShort((short)annotContext.BlockContentConnection); + // B 290 Has text contents + this._writer.WriteBit(annotContext.HasTextContents); + if (annotContext.HasTextContents) { + // TV 304 Text label + this._writer.WriteVariableText(annotContext.TextLabel); + // 3BD 11 Normal vector + this._writer.Write3BitDouble(annotContext.TextNormal); + // H 340 Text style handle (hard pointer) + this._writer.HandleReference(DwgReferenceType.HardPointer, annotContext.TextStyle); + // 3BD 12 Location + this._writer.Write3BitDouble(annotContext.TextLocation); + // 3BD 13 Direction + this._writer.Write3BitDouble(annotContext.Direction); + // BD 42 Rotation (radians) + this._writer.WriteBitDouble(annotContext.TextRotation); + // BD 43 Boundary width + this._writer.WriteBitDouble(annotContext.BoundaryWidth); + // BD 44 Boundary height + this._writer.WriteBitDouble(annotContext.BoundaryHeight); + // BD 45 Line spacing factor + this._writer.WriteBitDouble(annotContext.LineSpacingFactor); + // BS 170 Line spacing style (1 = at least, 2 = exactly) + this._writer.WriteBitShort((short)annotContext.LineSpacing); + // CMC 90 Text color + this._writer.WriteCmColor(annotContext.TextColor); + // BS 171 Alignment (1 = left, 2 = center, 3 = right) + this._writer.WriteBitShort((short)annotContext.TextAttachmentPoint); + // BS 172 Flow direction (1 = horizontal, 3 = vertical, 6 = by style) + this._writer.WriteBitShort((short)annotContext.FlowDirection); + // CMC 91 Background fill color + this._writer.WriteCmColor(annotContext.BackgroundFillColor); + // BD 141 Background scale factor + this._writer.WriteBitDouble(annotContext.BackgroundScaleFactor); + // BL 92 Background transparency + this._writer.WriteBitLong(annotContext.BackgroundTransparency); + // B 291 Is background fill enabled + this._writer.WriteBit(annotContext.BackgroundFillEnabled); + // B 292 Is background mask fill on + this._writer.WriteBit(annotContext.BackgroundMaskFillOn); + // BS 173 Column type (ODA writes 0), *TODO: what meaning for values? + this._writer.WriteBitShort(annotContext.ColumnType); + // B 293 Is text height automatic? + this._writer.WriteBit(annotContext.TextHeightAutomatic); + // BD 142 Column width + this._writer.WriteBitDouble(annotContext.ColumnWidth); + // BD 143 Column gutter + this._writer.WriteBitDouble(annotContext.ColumnGutter); + // B 294 Column flow reversed + this._writer.WriteBit(annotContext.ColumnFlowReversed); + + // Column sizes + // BD 144 Column size + int columnSizesCount = annotContext.ColumnSizes.Count; + this._writer.WriteBitLong(columnSizesCount); + for (int i = 0; i < columnSizesCount; i++) { + this._writer.WriteBitDouble(annotContext.ColumnSizes[i]); + } + + // B 295 Word break + this._writer.WriteBit(annotContext.WordBreak); + // B Unknown + this._writer.WriteBit(false); + } + + else if (annotContext.HasContentsBlock) { + this._writer.WriteBit(annotContext.HasContentsBlock); + + //B 296 Has contents block + //IF Has contents block + // H 341 AcDbBlockTableRecord handle (soft pointer) + this._writer.HandleReference(DwgReferenceType.SoftPointer, annotContext.BlockContent); + // 3BD 14 Normal vector + this._writer.Write3BitDouble(annotContext.BlockContentNormal); + // 3BD 15 Location + this._writer.Write3BitDouble(annotContext.BlockContentLocation); + // 3BD 16 Scale vector + this._writer.Write3BitDouble(annotContext.BlockContentScale); + // BD 46 Rotation (radians) + this._writer.WriteBitDouble(annotContext.BlockContentRotation); + // CMC 93 Block color + this._writer.WriteCmColor(annotContext.BlockContentColor); + // 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) + var m4 = annotContext.TransformationMatrix; + this._writer.WriteBitDouble(m4.m00); + this._writer.WriteBitDouble(m4.m10); + this._writer.WriteBitDouble(m4.m20); + this._writer.WriteBitDouble(m4.m30); + + this._writer.WriteBitDouble(m4.m01); + this._writer.WriteBitDouble(m4.m11); + this._writer.WriteBitDouble(m4.m21); + this._writer.WriteBitDouble(m4.m31); + + this._writer.WriteBitDouble(m4.m02); + this._writer.WriteBitDouble(m4.m12); + this._writer.WriteBitDouble(m4.m22); + this._writer.WriteBitDouble(m4.m32); + + this._writer.WriteBitDouble(m4.m03); + this._writer.WriteBitDouble(m4.m13); + this._writer.WriteBitDouble(m4.m23); + this._writer.WriteBitDouble(m4.m33); + } + //END IF Has contents block + //END IF Has text contents + + // 3BD 110 Base point + this._writer.Write3BitDouble(annotContext.BasePoint); + // 3BD 111 Base direction + this._writer.Write3BitDouble(annotContext.BaseDirection); + // 3BD 112 Base vertical + this._writer.Write3BitDouble(annotContext.BaseVertical); + // B 297 Is normal reversed? + this._writer.WriteBit(annotContext.NormalReversed); + + if (this.R2010Plus) + { + // BS 273 Style top attachment + this._writer.WriteBitShort((short)annotContext.TextTopAttachment); + // BS 272 Style bottom attachment + this._writer.WriteBitShort((short)annotContext.TextBottomAttachment); + } + } + + private void writeLeaderRoot(MultiLeaderAnnotContext.LeaderRoot leaderRoot) + { + // B 290 Is content valid(ODA writes true)/DXF: Has Set Last Leader Line Point + this._writer.WriteBit(leaderRoot.ContentValid); + // B 291 Unknown(ODA writes true)/DXF: Has Set Dogleg Vector + this._writer.WriteBit(true); + // 3BD 10 Connection point/DXF: Last Leader Line Point + this._writer.Write3BitDouble(leaderRoot.ConnectionPoint); + // 3BD 11 Direction/DXF: Dogleg vector + this._writer.Write3BitDouble(leaderRoot.Direction); + + // Break start/end point pairs + // BL Number of break start / end point pairs + // 3BD 12 Break start point + // 3BD 13 Break end point + this._writer.WriteBitLong(leaderRoot.BreakStartEndPointsPairs.Count); + foreach (MultiLeaderAnnotContext.StartEndPointPair startEndPointPair in leaderRoot.BreakStartEndPointsPairs) + { + this._writer.Write3BitDouble(startEndPointPair.StartPoint); + this._writer.Write3BitDouble(startEndPointPair.EndPoint); + } + + // BL 90 Leader index + this._writer.WriteBitLong(leaderRoot.LeaderIndex); + // BD 40 Landing distance + this._writer.WriteBitDouble(leaderRoot.LandingDistance); + + // Leader lines + // BL Number of leader lines + this._writer.WriteBitLong(leaderRoot.Lines.Count); + foreach (MultiLeaderAnnotContext.LeaderLine leaderLine in leaderRoot.Lines) + { + writeLeaderLine(leaderLine); + } + + if (this.R2010Plus) + { + // BS 271 Attachment direction(0 = horizontal, 1 = vertical, default is 0) + this._writer.WriteBitShort((short)leaderRoot.TextAttachmentDirection); + } + } + + private void writeLeaderLine(MultiLeaderAnnotContext.LeaderLine leaderLine) + { + // Points + // BL - Number of points + // 3BD 10 Point + this._writer.WriteBitLong(leaderLine.Points.Count); + foreach (XYZ point in leaderLine.Points) { + // 3BD 10 Point + this._writer.Write3BitDouble(point); + } + + // Add optional Break Info (one or more) + // BL Break info count + this._writer.WriteBitLong(leaderLine.BreakInfoCount); + if (leaderLine.BreakInfoCount > 0) { + // BL 90 Segment index + this._writer.WriteBitLong(leaderLine.SegmentIndex); + + // Start/end point pairs + // 3BD 12 End point + this._writer.WriteBitLong(leaderLine.StartEndPoints.Count); + foreach (MultiLeaderAnnotContext.StartEndPointPair sep in leaderLine.StartEndPoints) + { + // 3BD 11 Start Point + this._writer.Write3BitDouble(sep.StartPoint); + this._writer.Write3BitDouble(sep.EndPoint); + } + } + + // BL 91 Leader line index + this._writer.WriteBitLong(leaderLine.Index); + + 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 + this._writer.WriteCmColor(leaderLine.LineColor); + // H 340 Line type handle(hard pointer) + this._writer.HandleReference(DwgReferenceType.HardPointer, leaderLine.LineType); + // BL 171 Line weight + this._writer.WriteBitLong((short)leaderLine.LineWeight); + // BD 40 Arrow size + this._writer.WriteBitDouble(leaderLine.ArrowheadSize); + // H 341 Arrow symbol handle(hard pointer) + this._writer.HandleReference(DwgReferenceType.HardPointer, leaderLine.Arrowhead); + + // BL 93 Override flags (1 = leader type, 2 = line color, 4 = line type, 8 = line weight, 16 = arrow size, 32 = arrow symbol(handle) + this._writer.WriteBitLong((short)leaderLine.OverrideFlags); + } + } + private void writeLine(Line line) { //R13-R14 Only: diff --git a/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Objects.cs b/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Objects.cs index 6f18514c..dcca76e4 100644 --- a/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Objects.cs +++ b/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Objects.cs @@ -25,7 +25,6 @@ private void writeObject(CadObject obj) switch (obj) { case Material: - case MultiLeaderStyle: case MultiLeaderAnnotContext: case SortEntitiesTable: case VisualStyle: @@ -65,6 +64,9 @@ private void writeObject(CadObject obj) case MLineStyle style: this.writeMLineStyle(style); break; + case MultiLeaderStyle multiLeaderStyle: + this.writeMultiLeaderStyle(multiLeaderStyle); + break; case PlotSettings plotsettings: this.writePlotSettings(plotsettings); break; @@ -333,6 +335,116 @@ private void writeMLineStyle(MLineStyle mlineStyle) } } + private void writeMultiLeaderStyle(MultiLeaderStyle mLeaderStyle) + { + if (!R2010Plus) + { + return; + } + + // BS 179 Version expected: 2 + this._writer.WriteBitShort(2); + + // BS 170 Content type (see paragraph on LEADER for more details). + this._writer.WriteBitShort((short)mLeaderStyle.ContentType); + // BS 171 Draw multi-leader order (0 = draw content first, 1 = draw leader first) + this._writer.WriteBitShort((short)mLeaderStyle.MultiLeaderDrawOrder); + // BS 172 Draw leader order (0 = draw leader head first, 1 = draw leader tail first) + this._writer.WriteBitShort((short)mLeaderStyle.LeaderDrawOrder); + // BL 90 Maximum number of points for leader + this._writer.WriteBitShort((short)mLeaderStyle.MaxLeaderSegmentsPoints); + // BD 40 First segment angle (radians) + this._writer.WriteBitDouble(mLeaderStyle.FirstSegmentAngleConstraint); + // BD 41 Second segment angle (radians) + this._writer.WriteBitDouble(mLeaderStyle.SecondSegmentAngleConstraint); + // BS 173 Leader type (see paragraph on LEADER for more details). + this._writer.WriteBitShort((short)mLeaderStyle.PathType); + // CMC 91 Leader line color + this._writer.WriteCmColor(mLeaderStyle.LineColor); + // H 340 Leader line type handle (hard pointer) + this._writer.HandleReference(DwgReferenceType.HardPointer, mLeaderStyle.LeaderLineType); + // BL 92 Leader line weight + this._writer.WriteBitLong((short)mLeaderStyle.LeaderLineWeight); + // B 290 Is landing enabled? + this._writer.WriteBit(mLeaderStyle.EnableLanding); + // BD 42 Landing gap + this._writer.WriteBitDouble(mLeaderStyle.LandingGap); + // B 291 Auto include landing (is dog-leg enabled?) + this._writer.WriteBit(mLeaderStyle.EnableDogleg); + // BD 43 Landing distance + this._writer.WriteBitDouble(mLeaderStyle.LandingDistance); + // TV 3 Style description + this._writer.WriteVariableText(mLeaderStyle.Description); + // H 341 Arrow head block handle (hard pointer) + this._writer.HandleReference(DwgReferenceType.HardPointer, mLeaderStyle.Arrowhead); + // BD 44 Arrow head size + this._writer.WriteBitDouble(mLeaderStyle.ArrowheadSize); + // TV 300 Text default + this._writer.WriteVariableText(mLeaderStyle.DefaultTextContents); + // H 342 Text style handle (hard pointer) + this._writer.HandleReference(DwgReferenceType.HardPointer, mLeaderStyle.TextStyle); + // BS 174 Left attachment (see paragraph on LEADER for more details). + this._writer.WriteBitShort((short)mLeaderStyle.TextLeftAttachment); + // BS 178 Right attachment (see paragraph on LEADER for more details). + this._writer.WriteBitShort((short)mLeaderStyle.TextRightAttachment); + if (R2010Plus) + { + // IF IsNewFormat OR DXF file + // BS 175 Text angle type (see paragraph on LEADER for more details). + this._writer.WriteBitShort((short)mLeaderStyle.TextAngle); + // END IF IsNewFormat OR DXF file + } + // BS 176 Text alignment type + this._writer.WriteBitShort((short)mLeaderStyle.TextAlignment); + // CMC 93 Text color + this._writer.WriteCmColor(mLeaderStyle.TextColor); + // BD 45 Text height + this._writer.WriteBitDouble(mLeaderStyle.TextHeight); + // B 292 Text frame enabled + this._writer.WriteBit(mLeaderStyle.TextFrame); + if (R2010Plus) + { + // IF IsNewFormat OR DXF file + // B 297 Always align text left + this._writer.WriteBit(mLeaderStyle.TextAlignAlwaysLeft); + // END IF IsNewFormat OR DXF file + } + // BD 46 Align space + this._writer.WriteBitDouble(mLeaderStyle.AlignSpace); + // H 343 Block handle (hard pointer) + this._writer.HandleReference(DwgReferenceType.HardPointer, mLeaderStyle.BlockContent); + // CMC 94 Block color + this._writer.WriteCmColor(mLeaderStyle.BlockContentColor); + // 3BD 47,49,140 Block scale vector + this._writer.Write3BitDouble(mLeaderStyle.BlockContentScale); + // B 293 Is block scale enabled + this._writer.WriteBit(mLeaderStyle.EnableBlockContentScale); + // BD 141 Block rotation (radians) + this._writer.WriteBitDouble(mLeaderStyle.BlockContentRotation); + // B 294 Is block rotation enabled + this._writer.WriteBit(mLeaderStyle.EnableBlockContentRotation); + // BS 177 Block connection type (0 = MLeader connects to the block extents, 1 = MLeader connects to the block base point) + this._writer.WriteBitShort((short)mLeaderStyle.BlockContentConnection); + // BD 142 Scale factor + this._writer.WriteBitDouble(mLeaderStyle.ScaleFactor); + // 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 + this._writer.WriteBit(mLeaderStyle.OverwritePropertyValue); + // B 296 Is annotative? + this._writer.WriteBit(mLeaderStyle.IsAnnotative); + // BD 143 Break size + this._writer.WriteBitDouble(mLeaderStyle.BreakGapSize); + + // BS 271 Attachment direction (see paragraph on LEADER for more details). + this._writer.WriteBitShort((short)mLeaderStyle.TextAttachmentDirection); + // BS 273 Top attachment (see paragraph on LEADER for more details). + this._writer.WriteBitShort((short)mLeaderStyle.TextBottomAttachment); + // BS 272 Bottom attachment (see paragraph on LEADER for more details). + this._writer.WriteBitShort((short)mLeaderStyle.TextTopAttachment); + } + private void writePlotSettings(PlotSettings plot) { //Common: diff --git a/ACadSharp/IO/DXF/DxfStreamWriter/DxfObjectsSectionWriter.cs b/ACadSharp/IO/DXF/DxfStreamWriter/DxfObjectsSectionWriter.cs index cadc65a7..ae73ccd6 100644 --- a/ACadSharp/IO/DXF/DxfStreamWriter/DxfObjectsSectionWriter.cs +++ b/ACadSharp/IO/DXF/DxfStreamWriter/DxfObjectsSectionWriter.cs @@ -30,7 +30,7 @@ protected void writeObject(T co) { case AcdbPlaceHolder: case Material: - case MultiLeaderStyle: + case MultiLeaderAnnotContext: case VisualStyle: case ImageDefinitionReactor: case XRecord: @@ -62,6 +62,9 @@ protected void writeObject(T co) case MLineStyle mlStyle: this.writeMLineStyle(mlStyle); break; + case MultiLeaderStyle multiLeaderlStyle: + this.writeMultiLeaderStyle(multiLeaderlStyle); + break; case PlotSettings plotSettings: this.writePlotSettings(plotSettings); break; @@ -252,6 +255,64 @@ protected void writeMLineStyle(MLineStyle style) } } + protected void writeMultiLeaderStyle(MultiLeaderStyle style) + { + DxfClassMap map = DxfClassMap.Create(); + + this._writer.Write(100, DxfSubclassMarker.MLeaderStyle); + + this._writer.Write(179, 2); + // this._writer.Write(2, style.Name, map); + this._writer.Write(170, (short)style.ContentType, map); + this._writer.Write(171, (short)style.MultiLeaderDrawOrder, map); + this._writer.Write(172, (short)style.LeaderDrawOrder, map); + this._writer.Write(90, style.MaxLeaderSegmentsPoints, map); + this._writer.Write(40, style.FirstSegmentAngleConstraint, map); + this._writer.Write(41, style.SecondSegmentAngleConstraint, map); + this._writer.Write(173, (short)style.PathType, map); + this._writer.WriteCmColor(91, style.LineColor, map); + this._writer.WriteHandle(340, style.LeaderLineType); + this._writer.Write(92, (short)style.LeaderLineWeight, map); + this._writer.Write(290, style.EnableLanding, map); + this._writer.Write(42, style.LandingGap, map); + this._writer.Write(291, style.EnableDogleg, map); + this._writer.Write(43, style.LandingDistance, map); + this._writer.Write(3, style.Description, map); + this._writer.WriteHandle(341, style.Arrowhead); + this._writer.Write(44, style.ArrowheadSize, map); + this._writer.Write(300, style.DefaultTextContents, map); + this._writer.WriteHandle(342, style.TextStyle); + this._writer.Write(174, (short)style.TextLeftAttachment, map); + this._writer.Write(178, (short)style.TextRightAttachment, map); + this._writer.Write(175, style.TextAngle, map); + this._writer.Write(176, (short)style.TextAlignment, map); + this._writer.WriteCmColor(93, style.TextColor, map); + this._writer.Write(45, style.TextHeight, map); + this._writer.Write(292, style.TextFrame, map); + this._writer.Write(297, style.TextAlignAlwaysLeft, map); + this._writer.Write(46, style.AlignSpace, map); + this._writer.WriteHandle(343, style.BlockContent); + this._writer.WriteCmColor(94, style.BlockContentColor, map); + + // Write 3 doubles since group codes do not conform vector group codes + this._writer.Write(47, style.BlockContentScale.X, map); + this._writer.Write(49, style.BlockContentScale.Y, map); + this._writer.Write(140, style.BlockContentScale.Z, map); + + this._writer.Write(293, style.EnableBlockContentScale, map); + this._writer.Write(141, style.BlockContentRotation, map); + this._writer.Write(294, style.EnableBlockContentRotation, map); + this._writer.Write(177, (short)style.BlockContentConnection, map); + this._writer.Write(142, style.ScaleFactor, map); + this._writer.Write(295, style.OverwritePropertyValue, map); + this._writer.Write(296, style.IsAnnotative, map); + this._writer.Write(143, style.BreakGapSize, map); + this._writer.Write(271, (short)style.TextAttachmentDirection, map); + this._writer.Write(272, (short)style.TextBottomAttachment, map); + this._writer.Write(273, (short)style.TextTopAttachment, map); + this._writer.Write(298, false); // undocumented + } + private void writeSortentsTable(SortEntitiesTable e) { this._writer.Write(DxfCode.Subclass, DxfSubclassMarker.SortentsTable); diff --git a/ACadSharp/IO/DXF/DxfStreamWriter/DxfSectionWriterBase.Entities.cs b/ACadSharp/IO/DXF/DxfStreamWriter/DxfSectionWriterBase.Entities.cs index 6f165582..34b3515f 100644 --- a/ACadSharp/IO/DXF/DxfStreamWriter/DxfSectionWriterBase.Entities.cs +++ b/ACadSharp/IO/DXF/DxfStreamWriter/DxfSectionWriterBase.Entities.cs @@ -1,7 +1,9 @@ using ACadSharp.Entities; +using ACadSharp.Objects; using CSMath; using System; using System.Linq; +using System.Text; namespace ACadSharp.IO.DXF { @@ -14,7 +16,6 @@ protected void writeEntity(T entity) switch (entity) { case Solid3D: - case MultiLeader: case UnknownEntity: this.notify($"Entity type not implemented : {entity.GetType().FullName}", NotificationType.NotImplemented); return; @@ -67,6 +68,9 @@ protected void writeEntity(T entity) case MText mtext: this.writeMText(mtext); break; + case MultiLeader multiLeader: + this.writeMultiLeader(multiLeader); + break; case Point point: this.writePoint(point); break; @@ -699,6 +703,158 @@ private void writeMTextValue(string text) this._writer.Write(1, text); } + private void writeMultiLeader(MultiLeader multiLeader) + { + MultiLeaderAnnotContext contextData = multiLeader.ContextData; + + this._writer.Write(100, "AcDbMLeader"); + + // version + // if (Version > ACadVersion. + this._writer.Write(270, 2); + + writeMultiLeaderAnnotContext(contextData); + + // MultiLeader properties + this._writer.WriteHandle(340, multiLeader.Style); + this._writer.Write(90, multiLeader.PropertyOverrideFlags); + this._writer.Write(170, (short)multiLeader.PathType); + + this._writer.WriteCmColor(91, multiLeader.LineColor); + + this._writer.WriteHandle(341, multiLeader.LineType); + this._writer.Write(171, (short)multiLeader.LeaderLineWeight); + this._writer.Write(290, multiLeader.EnableLanding); + this._writer.Write(291, multiLeader.EnableDogleg); + this._writer.Write(41, multiLeader.LandingDistance); + this._writer.Write(42, multiLeader.ArrowheadSize); + this._writer.Write(172, (short)multiLeader.ContentType); + this._writer.WriteHandle(343, multiLeader.TextStyle); + this._writer.Write(173, (short)multiLeader.TextLeftAttachment); + this._writer.Write(95, (short)multiLeader.TextRightAttachment); + this._writer.Write(174, (short)multiLeader.TextAngle); + this._writer.Write(175, (short)multiLeader.TextAlignment); + + this._writer.WriteCmColor(92, multiLeader.TextColor); + + this._writer.Write(292, multiLeader.TextFrame); + + this._writer.WriteCmColor(93, multiLeader.BlockContentColor); + + this._writer.Write(10, multiLeader.BlockContentScale); + + this._writer.Write(43, multiLeader.BlockContentRotation); + this._writer.Write(176, (short)multiLeader.BlockContentConnection); + this._writer.Write(293, multiLeader.EnableAnnotationScale); + this._writer.Write(294, multiLeader.TextDirectionNegative); + this._writer.Write(178, multiLeader.TextAligninIPE); + this._writer.Write(179, multiLeader.TextAttachmentPoint); + this._writer.Write(45, multiLeader.ScaleFactor); + this._writer.Write(271, multiLeader.TextAttachmentDirection); + this._writer.Write(272, multiLeader.TextBottomAttachment); + this._writer.Write(273, multiLeader.TextTopAttachment); + this._writer.Write(295, 0); + } + + private void writeMultiLeaderAnnotContext(MultiLeaderAnnotContext contextData) { + this._writer.Write(300, "CONTEXT_DATA{"); + this._writer.Write(40, contextData.ScaleFactor); + this._writer.Write(10, contextData.ContentBasePoint); + this._writer.Write(41, contextData.TextHeight); + this._writer.Write(140, contextData.ArrowheadSize); + this._writer.Write(145, contextData.LandingGap); + this._writer.Write(174, (short)contextData.TextLeftAttachment); + this._writer.Write(175, (short)contextData.TextRightAttachment); + this._writer.Write(176, (short)contextData.TextAlignment); + this._writer.Write(177, (short)contextData.BlockContentConnection); + this._writer.Write(290, contextData.HasTextContents); + this._writer.Write(304, contextData.TextLabel); + + this._writer.Write(11, contextData.TextNormal); + + this._writer.WriteHandle(340, contextData.TextStyle); + + this._writer.Write(12, contextData.TextLocation); + + this._writer.Write(13, contextData.Direction); + + this._writer.Write(42, contextData.TextRotation); + this._writer.Write(43, contextData.BoundaryWidth); + this._writer.Write(44, contextData.BoundaryHeight); + this._writer.Write(45, contextData.LineSpacingFactor); + this._writer.Write(170, (short)contextData.LineSpacing); + + this._writer.WriteCmColor(90, contextData.TextColor); + + this._writer.Write(171, (short)contextData.TextAttachmentPoint); + this._writer.Write(172, (short)contextData.FlowDirection); + + this._writer.WriteCmColor(91, contextData.BackgroundFillColor); + + this._writer.Write(141, contextData.BackgroundScaleFactor); + this._writer.Write(92, contextData.BackgroundTransparency); + this._writer.Write(291, contextData.BackgroundFillEnabled); + this._writer.Write(292, contextData.BackgroundMaskFillOn); + this._writer.Write(173, contextData.ColumnType); + this._writer.Write(293, contextData.TextHeightAutomatic); + this._writer.Write(142, contextData.ColumnWidth); + this._writer.Write(143, contextData.ColumnGutter); + this._writer.Write(294, contextData.ColumnFlowReversed); + this._writer.Write(295, contextData.WordBreak); + + this._writer.Write(296, contextData.HasContentsBlock); + + this._writer.Write(110, contextData.BasePoint); + + this._writer.Write(111, contextData.BaseDirection); + + this._writer.Write(112, contextData.BaseVertical); + + this._writer.Write(297, contextData.NormalReversed); + + foreach (MultiLeaderAnnotContext.LeaderRoot leaderRoot in contextData.LeaderRoots) { + writeLeaderRoot(leaderRoot); + } + + this._writer.Write(272, (short)contextData.TextBottomAttachment); + this._writer.Write(273, (short)contextData.TextTopAttachment); + this._writer.Write(301, "}"); // CONTEXT_DATA + } + + private void writeLeaderRoot(MultiLeaderAnnotContext.LeaderRoot leaderRoot) + { + this._writer.Write(302, "LEADER{"); + + // TODO: true is placeholder + this._writer.Write(290, true ? (short)1 : (short)0); // Has Set Last Leader Line Point + this._writer.Write(291, true ? (short)1 : (short)0); // Has Set Dogleg Vector + + this._writer.Write(10, leaderRoot.ConnectionPoint); + + this._writer.Write(11, leaderRoot.Direction); + + this._writer.Write(90, leaderRoot.LeaderIndex); + this._writer.Write(40, leaderRoot.LandingDistance); + + foreach (MultiLeaderAnnotContext.LeaderLine leaderLine in leaderRoot.Lines) { + writeLeaderLine(leaderLine); + } + + this._writer.Write(271, 0); + this._writer.Write(303, "}"); // LEADER + } + + private void writeLeaderLine(MultiLeaderAnnotContext.LeaderLine leaderLine) { + this._writer.Write(304, "LEADER_LINE{"); + + foreach (XYZ point in leaderLine.Points) { + this._writer.Write(10, point); + } + this._writer.Write(91, leaderLine.Index); + + this._writer.Write(305, "}"); // LEADER_Line + } + private void writePoint(Point line) { DxfClassMap map = DxfClassMap.Create(); diff --git a/ACadSharp/IO/DXF/DxfStreamWriter/DxfSectionWriterBase.cs b/ACadSharp/IO/DXF/DxfStreamWriter/DxfSectionWriterBase.cs index 7af63372..decefcc6 100644 --- a/ACadSharp/IO/DXF/DxfStreamWriter/DxfSectionWriterBase.cs +++ b/ACadSharp/IO/DXF/DxfStreamWriter/DxfSectionWriterBase.cs @@ -48,16 +48,6 @@ protected void writeCommonObjectData(CadObject cadObject) this._writer.Write(DxfCode.Handle, cadObject.Handle); } - this._writer.Write(DxfCode.SoftPointerId, cadObject.Owner.Handle); - - //TODO: Write exended data - if (cadObject.ExtendedData != null) - { - //this._writer.Write(DxfCode.ControlString,DxfFileToken.ReactorsToken); - //this._writer.Write(DxfCode.HardOwnershipId, cadObject.ExtendedData); - //this._writer.Write(DxfCode.ControlString, "}"); - } - if (cadObject.XDictionary != null) { this._writer.Write(DxfCode.ControlString, DxfFileToken.DictionaryToken); @@ -67,6 +57,24 @@ protected void writeCommonObjectData(CadObject cadObject) //Add the dictionary in the object holder this.Holder.Objects.Enqueue(cadObject.XDictionary); } + + if (cadObject.Reactors != null && cadObject.Reactors.Count > 0) { + this._writer.Write(DxfCode.ControlString,DxfFileToken.ReactorsToken); + foreach (ulong reactorHandle in cadObject.Reactors.Keys) { + this._writer.Write(DxfCode.SoftPointerId, reactorHandle); + } + this._writer.Write(DxfCode.ControlString, "}"); + } + + this._writer.Write(DxfCode.SoftPointerId, cadObject.Owner.Handle); + + //TODO: Write exended data + if (cadObject.ExtendedData != null) + { + //this._writer.Write(DxfCode.ControlString,DxfFileToken.ReactorsToken); + //this._writer.Write(DxfCode.HardOwnershipId, cadObject.ExtendedData); + //this._writer.Write(DxfCode.ControlString, "}"); + } } protected void writeExtendedData(CadObject cadObject) diff --git a/ACadSharp/IO/DXF/DxfStreamWriter/DxfStreamWriterBase.cs b/ACadSharp/IO/DXF/DxfStreamWriter/DxfStreamWriterBase.cs index 35d8d255..1eeb2171 100644 --- a/ACadSharp/IO/DXF/DxfStreamWriter/DxfStreamWriterBase.cs +++ b/ACadSharp/IO/DXF/DxfStreamWriter/DxfStreamWriterBase.cs @@ -1,6 +1,7 @@ using CSUtilities.Converters; using System; + namespace ACadSharp.IO.DXF { internal abstract class DxfStreamWriterBase : IDxfStreamWriter @@ -61,11 +62,7 @@ public void WriteCmColor(int code, Color color, DxfClassMap map = null) public void WriteHandle(int code, IHandledCadObject value, DxfClassMap map) { - if (value == null) - { - this.Write(code, (ulong)0, map); - } - else + if (value != null) { this.Write(code, value.Handle, map); } diff --git a/ACadSharp/MultiLeaderPathType.cs b/ACadSharp/MultiLeaderPathType.cs index 30ad0842..8a3804ce 100644 --- a/ACadSharp/MultiLeaderPathType.cs +++ b/ACadSharp/MultiLeaderPathType.cs @@ -1,14 +1,10 @@ -// TODO similar to LeaderPathType -// 0 = straight line leader, 1 = spline leader - - -namespace ACadSharp { +namespace ACadSharp { /// /// Controls the way the leader is drawn. /// - public enum MultiLeaderPathType { - + public enum MultiLeaderPathType : short + { /// /// Invisible leader /// diff --git a/ACadSharp/Objects/LeaderLinePropertOverrideFlags.cs b/ACadSharp/Objects/LeaderLinePropertOverrideFlags.cs index 6ec57839..baf66a2a 100644 --- a/ACadSharp/Objects/LeaderLinePropertOverrideFlags.cs +++ b/ACadSharp/Objects/LeaderLinePropertOverrideFlags.cs @@ -3,10 +3,14 @@ namespace ACadSharp.Objects { + /// + /// These flags specify whether properties of a leader line primarily defined by the + /// object or overidden by properties of the + /// object are overridden for an individual leader line. + /// [Flags] public enum LeaderLinePropertOverrideFlags : int { - /// /// No property to be overridden /// diff --git a/ACadSharp/Objects/MultiLeaderAnnotContext.cs b/ACadSharp/Objects/MultiLeaderAnnotContext.cs index 6ed68a33..15972f8f 100644 --- a/ACadSharp/Objects/MultiLeaderAnnotContext.cs +++ b/ACadSharp/Objects/MultiLeaderAnnotContext.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using ACadSharp.Attributes; using ACadSharp.Entities; using ACadSharp.Tables; @@ -13,7 +14,7 @@ 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 partial class MultiLeaderAnnotContext : NonGraphicalObject { public override ObjectType ObjectType => ObjectType.UNLISTED; @@ -25,101 +26,206 @@ public partial class MultiLeaderAnnotContext : CadObject /// - /// Leader Roots + /// Gets the list of objects of the multileader. /// + /// + /// A can have one or two leader roots having one ore more + /// leader lines each. + /// public IList LeaderRoots { get; } = new List(); - /// - /// Overall scale + /// Gets or sets a scale factor (see ). + /// This property overrides the value from + /// when the flag is set (see + /// property). + /// The scale factor is applied by AutoCAD. /// + /// + /// + /// The following properties entered in AutoCAD are multiplied with this scale factor: + /// + /// , , , + /// , and the elements of . + /// + /// The is adjusted. + /// + /// [DxfCodeValue(40)] public double ScaleFactor { get; set; } + // TODO /// - /// Content base point + /// Gets or sets the content base point. This point is identical with the landing end + /// point of the first leader. /// + /// + /// This point + /// [DxfCodeValue(10, 20, 30)] public XYZ ContentBasePoint { get; set; } /// - /// Text height + /// Get or sets the text height for the lext label of the multileader + /// (see ). + /// This property overrides the value from + /// when the flag is set in the + /// property. /// + /// + /// The value returned is the value entered in AutoCAD multiplied with the . + /// [DxfCodeValue(41)] public double TextHeight { get; set; } /// - /// Arrow head size + /// Gets or sets the arrowhead size (see ) + /// for every leader line. + /// This property overrides the value from + /// when the flag is set in the + /// property. /// + /// + /// + /// The value for all leader lines can be overridden for each individual leader line by the + /// property when the + /// flag is set in the + /// property. + /// + /// This property is also exposed by the class + /// (). + /// Values should be equal, the value of this property is assumed to be used. + /// + /// + /// + /// The value returned is the value entered in AutoCAD multiplied with the . + /// [DxfCodeValue(140)] public double ArrowheadSize { get; set; } /// - /// Landing gap + /// Gets or sets the landing gap (see ). + /// This property overrides the value from + /// when the flag is set (see + /// property). /// [DxfCodeValue(145)] public double LandingGap { get; set; } /// - /// Style left text attachment type + /// Gets or sets the text top attachment type (see ). + /// This property overrides the value from + /// when the flag is set (see + /// property). /// /// - /// See also MLEADER style left text attachment type for values. - /// Relevant if mleader attachment direction is horizontal. + /// This property is also exposed by the class + /// (). + /// Values should be equal, the value of this property is assumed to be used. /// + /// + /// A having the values 0-8 + /// can be used ("horizontal" attachment types). + /// [DxfCodeValue(174)] public TextAttachmentType TextLeftAttachment { get; set; } /// - /// Style right text attachment type + /// Gets or sets the text top attachment type (see ). + /// This property overrides the value from + /// when the flag is set (see + /// property). /// /// - /// See also MLEADER style left text attachment type for values. - /// Relevant if mleader attachment direction is horizontal. + /// This property is also exposed by the class + /// (). + /// Values should be equal, the value of this property is assumed to be used. /// + /// + /// A having the values 0-8 + /// can be used ("horizontal" attachment types). + /// [DxfCodeValue(175)] public TextAttachmentType TextRightAttachment { get; set; } /// - /// Text align type + /// Gets or sets the text alignment, i.e. the alignment of text lines if the a multiline + /// text label, relative to the . + /// This property overrides the value from + /// when the flag is set in the + /// property. /// + /// + /// This property contains the alignment value specified in AutoCAD rather than + /// and seems always to be consistent with + /// . + /// + /// Note that when changing this value the must be changed + /// accordingly. + /// + /// [DxfCodeValue(176)] public TextAlignmentType TextAlignment { get; set; } /// - /// Attachment type - /// --> MLeader.BlockContentConnectionType + /// Gets or sets a value indicating whether the multileader connects to the content-block extents + /// or to the content-block base point. + /// This property overrides the value from + /// when the flag is set in the + /// property. /// + /// + /// This property is also exposed by the class + /// (). + /// Values should be equal, the value of this property is assumed to be used. + /// [DxfCodeValue(177)] public BlockContentConnectionType BlockContentConnection { get; set; } + // TODO Check dependency of HasTextContent, HasContentBlock and MultiLeader.ContentType /// - /// Has text contents + /// Gets or sets a value indicating that the mutileader has a text label. /// [DxfCodeValue(290)] public bool HasTextContents { get; set; } /// - /// Text label + /// Gets or sets a string containg the text tat is to be dispayed a s text label of the + /// multileader. /// + /// + /// The string may contain MTEXT markups to specify new-lines, font, size, style, etc. + /// [DxfCodeValue(304)] public string TextLabel { get; set; } /// - /// Normal vector + /// Gets or sets the normal vector for the text label of the multileader. /// [DxfCodeValue(11, 21, 31)] public XYZ TextNormal { get; set; } /// - /// Text style handle (hard pointer) + /// Gets or sets the to be used to display the text label of the + /// multileader. + /// This property overrides the value from + /// when the flag is set in the + /// property. /// + /// + /// This property is also exposed by the class + /// (). + /// Values should be equal, the value of this property is assumed to be used. + /// [DxfCodeValue(340)] public TextStyle TextStyle { get; set; } /// - /// Location + /// Gets or sets the location of the text label of the multileader. /// + /// + /// This location is evaluated by AutoCAD from the + /// [DxfCodeValue(12, 22, 32)] public XYZ TextLocation { get; set; } @@ -130,162 +236,226 @@ public partial class MultiLeaderAnnotContext : CadObject public XYZ Direction { get; set; } /// - /// Rotation (radians) + /// Gets or sets the rotation of the text label of the multileader. /// + /// + /// The rotation angle in radians. + /// [DxfCodeValue(DxfReferenceType.IsAngle, 42)] public double TextRotation { get; set; } + // TODO /// - /// Boundary width + /// Boundary width (DXF Reference: TextWidth) + /// Value seems to be always zero. /// [DxfCodeValue(43)] public double BoundaryWidth { get; set; } + // TODO /// - /// Boundary height + /// Boundary height (DXF Reference: TextHeight) + /// Value seems to be always zero. /// [DxfCodeValue(44)] public double BoundaryHeight { get; set; } /// - /// Line spacing factor + /// Gets or sets the line-spacing factor for the display of the text label. /// [DxfCodeValue(45)] public double LineSpacingFactor { get; set; } /// - /// Line spacing style + /// Gets or sets the line spacing style for the display of the text label. /// [DxfCodeValue(170)] public LineSpacingStyle LineSpacing { get; set; } /// - /// Text color + /// Gets or sets the color for the display of the text label /// [DxfCodeValue(90)] public Color TextColor { get; set; } - // BS 171 Alignment (1 = left, 2 = center, 3 = right) - // see above: TextAlignment + /// + /// Gets or sets a value indicating the text attachment point. + /// + /// + /// In the Open Design Specification this property is documented as Alignment, in DXF + /// reference as Text Attachment. It is not clear what the meaning of this property + /// is in contrast to the property. The value seems to be always + /// consistent. + /// + /// This property is also exposed by the class + /// (). + /// Values should be equal, the value of this property is assumed to be used. + /// + /// [DxfCodeValue(171)] public TextAttachmentPointType TextAttachmentPoint { get; set; } + // TODO What is exactly ment by "flow direction"? + // When the value is not Horizontal line breaks in text label have to be ignored. + // The value returned by AutoCAD is normally 5. This not a valid enum value. /// - /// Flow direction + /// Gets or sets a value indicating the flow direction. /// [DxfCodeValue(172)] public FlowDirectionType FlowDirection { get; set; } + // TODO Create test cases /// /// Background fill color /// [DxfCodeValue(91)] public Color BackgroundFillColor { get; set; } + // TODO Create test cases /// /// Background scale factor /// [DxfCodeValue(141)] public double BackgroundScaleFactor { get; set; } + // TODO Create test cases /// /// Background transparency /// [DxfCodeValue(92)] public int BackgroundTransparency { get; set; } + // TODO Create test cases /// /// Is background fill enabled /// [DxfCodeValue(291)] public bool BackgroundFillEnabled { get; set; } + // TODO Create test cases /// /// Is background mask fill on /// [DxfCodeValue(292)] public bool BackgroundMaskFillOn { get; set; } + // TODO Create test cases /// /// Column type (ODA writes 0) /// [DxfCodeValue(173)] public short ColumnType { get; set; } + // TODO Create test cases /// /// Is text height automatic? /// [DxfCodeValue(293)] public bool TextHeightAutomatic { get; set; } + // TODO Create test cases /// /// Column width /// [DxfCodeValue(142)] public double ColumnWidth { get; set; } + // TODO Create test cases /// /// Column gutter /// [DxfCodeValue(143)] public double ColumnGutter { get; set; } + // TODO Create test cases /// /// Column flow reversed /// [DxfCodeValue(294)] public bool ColumnFlowReversed { get; set; } + // TODO Create test cases /// /// Get a list of column sizes /// [DxfCodeValue(144)] public IList ColumnSizes { get; } = new List(); - + + // TODO Create test cases /// /// Word break /// [DxfCodeValue(295)] public bool WordBreak { get; set; } + // TODO Check dependency of HasTextContent, HasContentBlock and MultiLeader.ContentType /// - /// Has contents block + /// Gets or sets a value indicating that the multileader has a content block. /// [DxfCodeValue(296)] public bool HasContentsBlock { get; set; } /// /// Gets a containing elements - /// to be drawn as content for the MultiLeader. + /// 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). + /// + /// Gets or sets the normal vector for the block content of the multileader. + /// [DxfCodeValue(14, 24, 34)] public XYZ BlockContentNormal { get; set; } /// - /// Location + /// Gets or sets the location of the böock content of the multileader. /// + /// + /// This location is evaluated by AutoCAD from the + /// [DxfCodeValue(15, 25, 35)] public XYZ BlockContentLocation { get; set; } + /// - /// Scale vector + /// Gets or sets the scale factor for block content. + /// This property overrides the value from + /// when the flag is set (see + /// property). /// + /// + /// This property is also exposed by the class + /// (). + /// Values should be equal, the value of this property is assumed to be used. + /// [DxfCodeValue(16, 26, 36)] public XYZ BlockContentScale { get; set; } /// - /// Rottaion (radians) + /// Gets or sets the rotation of the block content of the multileader. /// + /// + /// This property is also exposed by the class + /// (). + /// Values should be equal, the value of this property is assumed to be used. + /// + /// + /// The rotation angle in radians. + /// [DxfCodeValue(DxfReferenceType.IsAngle, 46)] public double BlockContentRotation { get; set; } /// - /// Block color + /// Gets or sets the block-content color. + /// This property overrides the value from + /// when the flag is set (see + /// property). /// + /// + /// This property is also exposed by the class + /// (). + /// Values should be equal, the value of this property is assumed to be used. + /// [DxfCodeValue(93)] public Color BlockContentColor { get; set; } @@ -332,27 +502,47 @@ public partial class MultiLeaderAnnotContext : CadObject public bool NormalReversed { get; set; } /// - /// Style top attachment. + /// Gets or sets the text top attachment type (see ). + /// This property override the value from + /// when the flag is set (see + /// property). /// /// - /// See also MLEADER style left text attachment type for values. - /// Relevant if mleader attachment direction is vertical. + /// This property is also exposed by the class + /// (). + /// Values should be equal, the value of this property is assumed to be used. /// + /// + /// A having the values + /// 9 = Center, + /// 10 = Underline and Center + /// can be used ("vertical" attachment types). + /// [DxfCodeValue(273)] public TextAttachmentType TextTopAttachment { get; set; } /// - /// Style bottom attachment. + /// Gets or sets the text bottom attachment type (see ). + /// This property override the value from + /// when the flag is set (see + /// property). /// /// - /// See also MLEADER style left text attachment type for values. - /// Relevant if mleader attachment direction is vertical. + /// This property is also exposed by the class + /// (). + /// Values should be equal, the value of this property is assumed to be used. /// + /// + /// A having the values + /// 9 = Center, + /// 10 = Underline and Center + /// can be used ("vertical" attachment types). + /// [DxfCodeValue(272)] public TextAttachmentType TextBottomAttachment { get; set; } /// - /// Default constructor + /// Initializes a new instance of a . /// public MultiLeaderAnnotContext() : base() { } @@ -360,7 +550,8 @@ public override CadObject Clone() { MultiLeaderAnnotContext clone = (MultiLeaderAnnotContext)base.Clone(); - foreach (var leaderRoot in LeaderRoots) + clone.LeaderRoots.Clear(); + foreach (var leaderRoot in this.LeaderRoots) { clone.LeaderRoots.Add((LeaderRoot)leaderRoot.Clone()); } diff --git a/ACadSharp/Objects/MultiLeaderAnnotContextClasses.cs b/ACadSharp/Objects/MultiLeaderAnnotContextClasses.cs index 56e1964f..edbbb3f8 100644 --- a/ACadSharp/Objects/MultiLeaderAnnotContextClasses.cs +++ b/ACadSharp/Objects/MultiLeaderAnnotContextClasses.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; - +using System.Linq; using ACadSharp.Attributes; using ACadSharp.Tables; @@ -13,7 +13,7 @@ namespace ACadSharp.Objects /// /// Nested classes in MultiLeaderAnnotContext /// - public partial class MultiLeaderAnnotContext : CadObject + public partial class MultiLeaderAnnotContext : NonGraphicalObject { /// /// Represents a leader root @@ -28,21 +28,25 @@ public LeaderRoot() { } /// /// Is content valid (ODA writes true) /// + [DxfCodeValue(290)] public bool ContentValid { get; set; } /// /// Unknown (ODA writes true) /// + [DxfCodeValue(291)] public bool Unknown { get; set; } /// /// Connection point /// + [DxfCodeValue(10, 20, 30)] public XYZ ConnectionPoint { get; set; } /// /// Direction /// + [DxfCodeValue(11, 21, 31)] public XYZ Direction { get; set; } /// @@ -53,16 +57,18 @@ public LeaderRoot() { } /// /// Leader index /// + [DxfCodeValue(90)] public int LeaderIndex { get; set; } /// /// Landing distance /// + [DxfCodeValue(40)] public double LandingDistance { get; set; } /// /// Gets a list of objects representing - /// representing leader lines starting from the landing point + /// leader lines starting from the landing point /// of the multi leader. /// public IList Lines { get; } = new List(); @@ -71,18 +77,19 @@ public LeaderRoot() { } /// /// Attachment direction /// + [DxfCodeValue(271)] public TextAttachmentDirectionType TextAttachmentDirection { get; set; } public object Clone() { LeaderRoot clone = (LeaderRoot)this.MemberwiseClone(); - foreach (var breakStartEndPoint in BreakStartEndPointsPairs) + foreach (var breakStartEndPoint in BreakStartEndPointsPairs.ToList()) { clone.BreakStartEndPointsPairs.Add((StartEndPointPair)breakStartEndPoint.Clone()); } - foreach (var line in Lines) + foreach (var line in Lines.ToList()) { clone.Lines.Add((LeaderLine)line.Clone()); } @@ -106,13 +113,13 @@ public StartEndPointPair(XYZ startPoint, XYZ endPoint) { /// /// Break start point /// - [DxfCodeValue(12)] + [DxfCodeValue(12, 22, 32)] public XYZ StartPoint { get; private set; } /// /// Break end point /// - [DxfCodeValue(13)] + [DxfCodeValue(13, 23, 33)] public XYZ EndPoint { get; private set; } public object Clone() @@ -133,7 +140,7 @@ public class LeaderLine : ICloneable public LeaderLine() { } /// - /// Points of leader line + /// Get the list of points of this . /// public IList Points { get; } = new List(); @@ -145,6 +152,7 @@ public LeaderLine() { } /// /// Segment index /// + [DxfCodeValue(90)] public int SegmentIndex { get; set; } /// @@ -155,55 +163,63 @@ public LeaderLine() { } /// /// Leader line index. /// + [DxfCodeValue(91)] public int Index { get; set; } //R2010 /// /// Leader type /// + [DxfCodeValue(170)] public MultiLeaderPathType PathType { get; set; } /// /// Line color /// + [DxfCodeValue(92)] public Color LineColor { get; set; } /// /// Line type /// + [DxfCodeValue(340)] public LineType LineType { get; set; } /// /// Line weight /// + [DxfCodeValue(171)] public LineweightType LineWeight { get; set; } /// /// Arrowhead size /// + [DxfCodeValue(40)] public double ArrowheadSize { get; set; } /// /// Gets or sets a containig elements /// to be dawn as arrow symbol. /// + [DxfCodeValue(341)] public BlockRecord Arrowhead { get; set; } /// /// Override flags /// + [DxfCodeValue(93)] public LeaderLinePropertOverrideFlags OverrideFlags { get; set; } public object Clone() { LeaderLine clone = (LeaderLine)this.MemberwiseClone(); - foreach (var point in Points) + foreach (var point in Points.ToList()) { clone.Points.Add(point); } - foreach (var startEndPoint in StartEndPoints) + foreach (var startEndPoint in StartEndPoints.ToList()) { clone.StartEndPoints.Add((StartEndPointPair)startEndPoint.Clone()); } diff --git a/ACadSharp/Objects/MultiLeaderStyle.cs b/ACadSharp/Objects/MultiLeaderStyle.cs index d143caf5..326ce52b 100644 --- a/ACadSharp/Objects/MultiLeaderStyle.cs +++ b/ACadSharp/Objects/MultiLeaderStyle.cs @@ -9,10 +9,10 @@ namespace ACadSharp.Objects /// Represents a object. /// /// - /// Object name
+ /// Object name
/// Dxf class name ///
- [DxfName(DxfFileToken.EntityMLeaderStyle)] + [DxfName(DxfFileToken.ObjectMLeaderStyle)] [DxfSubClass(DxfSubclassMarker.MLeaderStyle)] public class MultiLeaderStyle : NonGraphicalObject { @@ -30,7 +30,7 @@ public class MultiLeaderStyle : NonGraphicalObject public override ObjectType ObjectType => ObjectType.UNLISTED; /// - public override string ObjectName => DxfFileToken.EntityMLeaderStyle; + public override string ObjectName => DxfFileToken.ObjectMLeaderStyle; /// public override string SubclassMarker => DxfSubclassMarker.MLeaderStyle; diff --git a/ACadSharp/Tables/BlockContentConnectionType.cs b/ACadSharp/Tables/BlockContentConnectionType.cs index e56420fb..b50a233a 100644 --- a/ACadSharp/Tables/BlockContentConnectionType.cs +++ b/ACadSharp/Tables/BlockContentConnectionType.cs @@ -1,14 +1,17 @@ namespace ACadSharp.Entities { - public enum BlockContentConnectionType { - + /// + /// The values of this enum indicate how the multileader connects to the content block. + /// + public enum BlockContentConnectionType : short + { /// - /// MLeader connects to the block extents + /// MultiLeader connects to the block extents. /// BlockExtents = 0, /// - /// MLeader connects to the block base point + /// MultiLeader connects to the block base point. /// BasePoint = 1, } diff --git a/ACadSharp/TextAttachmentDirectionType.cs b/ACadSharp/TextAttachmentDirectionType.cs index f21bac4a..8c11f660 100644 --- a/ACadSharp/TextAttachmentDirectionType.cs +++ b/ACadSharp/TextAttachmentDirectionType.cs @@ -1,6 +1,7 @@ namespace ACadSharp { - public enum TextAttachmentDirectionType { + public enum TextAttachmentDirectionType : short + { Horizontal = 0, diff --git a/ACadSharp/TextAttachmentType.cs b/ACadSharp/TextAttachmentType.cs index 8bb50954..76ccfa0b 100644 --- a/ACadSharp/TextAttachmentType.cs +++ b/ACadSharp/TextAttachmentType.cs @@ -1,8 +1,18 @@ -namespace ACadSharp +using ACadSharp.Entities; + + +namespace ACadSharp { /// - /// + /// Text attachment type, controls how the text label of a is to placed + /// relative to the landing point. /// + /// + /// Values 0-8 are used for the left/right attachment points (attachment direction is horizontal), + /// + /// values 9-10 are used for the top/bottom attachment points (attachment direction is vertical). + /// + /// public enum TextAttachmentType : short { ///