Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
28,854 changes: 28,854 additions & 0 deletions samples/annotative/annotative_dimensions_AC1032.dxf

Large diffs are not rendered by default.

161 changes: 161 additions & 0 deletions src/ACadSharp.Tests/IO/DimensionObjectContextDataTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
using ACadSharp.Entities;
using ACadSharp.IO;
using ACadSharp.Objects;
using ACadSharp.Tables;
using CSMath;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Xunit;
using Xunit.Abstractions;

namespace ACadSharp.Tests.IO;

public class DimensionObjectContextDataTests : IOTestsBase
{
private const string _fileName = "annotative/annotative_dimensions_AC1032";

public DimensionObjectContextDataTests(ITestOutputHelper output) : base(output)
{
}

[Fact]
public void DwgAndDxfMatch()
{
var dwg = contextData(DwgReader.Read(path("dwg"), this.onNotification));
var dxf = contextData(DxfReader.Read(path("dxf"), this.onNotification));

Assert.Equal(dxf.Count, dwg.Count);

foreach (DimensionObjectContextData d in dwg.Values)
{
DimensionObjectContextData x = dxf[d.Handle];

Assert.Equal(x.GetType(), d.GetType());
Assert.Equal(x.Scale.Name, d.Scale.Name);
Assert.Equal(x.Block.Name, d.Block.Name);
Assert.Equal(round(x.TextLocation), round(d.TextLocation));
Assert.Equal(x.IsDefaultTextLocation, d.IsDefaultTextLocation);
Assert.Equal(x.TextRotation, d.TextRotation);
Assert.Equal(x.OverrideFlags, d.OverrideFlags);
Assert.Equal(x.TextOutsideExtensions, d.TextOutsideExtensions);
Assert.Equal(x.SuppressOutsideExtensions, d.SuppressOutsideExtensions);
Assert.Equal(x.TextInsideExtensions, d.TextInsideExtensions);
Assert.Equal(x.FlipFirstArrow, d.FlipFirstArrow);
Assert.Equal(x.FlipSecondArrow, d.FlipSecondArrow);

switch (d)
{
case AlignedDimensionObjectContextData a:
Assert.Equal(round(((AlignedDimensionObjectContextData)x).DimensionLinePoint), round(a.DimensionLinePoint));
break;
case AngularDimensionObjectContextData a:
Assert.Equal(round(((AngularDimensionObjectContextData)x).ArcPoint), round(a.ArcPoint));
break;
case DiametricDimensionObjectContextData a:
Assert.Equal(round(((DiametricDimensionObjectContextData)x).FirstArcPoint), round(a.FirstArcPoint));
Assert.Equal(round(((DiametricDimensionObjectContextData)x).DefinitionPoint), round(a.DefinitionPoint));
break;
case OrdinateDimensionObjectContextData a:
Assert.Equal(round(((OrdinateDimensionObjectContextData)x).DefinitionPoint), round(a.DefinitionPoint));
Assert.Equal(round(((OrdinateDimensionObjectContextData)x).LeaderEndpoint), round(a.LeaderEndpoint));
break;
case RadialDimensionObjectContextData a:
Assert.Equal(round(((RadialDimensionObjectContextData)x).FirstArcPoint), round(a.FirstArcPoint));
break;
}
}
}

[Fact]
public void ReadDwg()
{
var all = contextData(DwgReader.Read(path("dwg"), this.onNotification)).Values.ToList();

//7 annotative dimensions, each with a 1:1 and a 1:20 representation
//the jogged radial dimension (LARGE_RADIAL_DIMENSION) is not read as an entity, so its 2 are not reached
Assert.Equal(14, all.Count);
Assert.Equal(4, all.OfType<AlignedDimensionObjectContextData>().Count());
Assert.Equal(4, all.OfType<AngularDimensionObjectContextData>().Count());
Assert.Equal(2, all.OfType<DiametricDimensionObjectContextData>().Count());
Assert.Equal(2, all.OfType<OrdinateDimensionObjectContextData>().Count());
Assert.Equal(2, all.OfType<RadialDimensionObjectContextData>().Count());
Assert.All(all, d => Assert.NotNull(d.Block));
Assert.Equal(14, all.Select(d => d.Block.Name).Distinct().Count());

var diametric = all.OfType<DiametricDimensionObjectContextData>().First();
Assert.Equal(new XY(240, 30), round(diametric.TextLocation));
Assert.False(diametric.IsDefaultTextLocation);
Assert.Equal(new XYZ(224, 18, 0), round(diametric.FirstArcPoint));
Assert.Equal(new XYZ(176, -18, 0), round(diametric.DefinitionPoint));

var ordinate = all.OfType<OrdinateDimensionObjectContextData>().First();
Assert.True(ordinate.IsDefaultTextLocation);
Assert.Equal(new XYZ(120, -40, 0), round(ordinate.LeaderEndpoint));
}

[Fact]
public void ReadOverrides()
{
//The 1:20 representation of some dimensions has overridden variables
foreach (CadDocument doc in new[] { DwgReader.Read(path("dwg"), this.onNotification), DxfReader.Read(path("dxf"), this.onNotification) })
{
var all = contextData(doc).Values.ToList();

var tix = Assert.Single(all, d => d.TextInsideExtensions);
Assert.IsType<AlignedDimensionObjectContextData>(tix);
Assert.Equal(8, tix.OverrideFlags);

var tofl = Assert.Single(all, d => d.TextOutsideExtensions);
Assert.IsType<AlignedDimensionObjectContextData>(tofl);
Assert.Equal(1, tofl.OverrideFlags);

Assert.IsType<AngularDimensionObjectContextData>(Assert.Single(all, d => d.OverrideFlags == 4));
Assert.IsType<DiametricDimensionObjectContextData>(Assert.Single(all, d => d.OverrideFlags == 16));
Assert.IsType<AngularDimensionObjectContextData>(Assert.Single(all, d => d.FlipSecondArrow));
}

var dxf = contextData(DxfReader.Read(path("dxf"), this.onNotification)).Values;
Assert.Equal(TextArrowFitType.BestFit, Assert.Single(dxf, d => d.OverrideFlags == 4).DimensionTextArrowFit);
Assert.Equal(TextMovement.FreeTextPosition, Assert.Single(dxf, d => d.OverrideFlags == 16).TextMovement);
}

private static Dictionary<ulong, DimensionObjectContextData> contextData(CadDocument doc)
{
var result = new Dictionary<ulong, DimensionObjectContextData>();
foreach (Entity e in doc.Entities)
{
collect(e.XDictionary, result);
}
return result;
}

private static void collect(CadDictionary dictionary, Dictionary<ulong, DimensionObjectContextData> result)
{
if (dictionary == null)
{
return;
}

foreach (NonGraphicalObject item in dictionary)
{
if (item is DimensionObjectContextData data)
{
result[data.Handle] = data;
}
else if (item is CadDictionary sub)
{
collect(sub, result);
}
}
}

private static string path(string ext)
{
return Path.Combine(TestVariables.SamplesFolder, $"{_fileName}.{ext}");
}

private static XY round(XY p) => new XY(System.Math.Round(p.X, 6), System.Math.Round(p.Y, 6));

private static XYZ round(XYZ p) => new XYZ(System.Math.Round(p.X, 6), System.Math.Round(p.Y, 6), System.Math.Round(p.Z, 6));
}
14 changes: 14 additions & 0 deletions src/ACadSharp/DxfFileToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,18 @@ public static class DxfFileToken

public const string AcmPartRef = "ACMPARTREF";

public const string AlignedDimensionObjectContextData = "ACDB_ALDIMOBJECTCONTEXTDATA_CLASS";

public const string AngularDimensionObjectContextData = "ACDB_ANGDIMOBJECTCONTEXTDATA_CLASS";

public const string BeginSection = "SECTION";

public const string BlkRefObjectContextData = "ACDB_BLKREFOBJECTCONTEXTDATA_CLASS";

public const string BlkRefToken = "{BLKREFS";

public const string DiametricDimensionObjectContextData = "ACDB_DMDIMOBJECTCONTEXTDATA_CLASS";

public const string Block = "BLOCK";

public const string BlocksSection = "BLOCKS";
Expand Down Expand Up @@ -120,6 +126,8 @@ public static class DxfFileToken

public const string EntityRevolvedSurface = "REVOLVEDSURFACE";

public const string EntityRText = "RTEXT";

public const string EntitySection = "SECTION";

public const string EntitySeqend = "SEQEND";
Expand Down Expand Up @@ -178,6 +186,12 @@ public static class DxfFileToken

public const string MTextAttributeObjectContextData = "ACDB_MTEXTATTRIBUTEOBJECTCONTEXTDATA_CLASS";

public const string OrdinateDimensionObjectContextData = "ACDB_ORDDIMOBJECTCONTEXTDATA_CLASS";

public const string RadialDimensionLargeObjectContextData = "ACDB_RADIMLRGOBJECTCONTEXTDATA_CLASS";

public const string RadialDimensionObjectContextData = "ACDB_RADIMOBJECTCONTEXTDATA_CLASS";

public const string ObjectAecCleanupGroupDef = "AEC_CLEANUP_GROUP_DEF";

public const string ObjectAecWallStyle = "AEC_WALL_STYLE";
Expand Down
14 changes: 14 additions & 0 deletions src/ACadSharp/DxfSubclassMarker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ public static class DxfSubclassMarker

public const string Angular3PointDimension = "AcDb3PointAngularDimension";

public const string AlignedDimensionObjectContextData = "AcDbAlignedDimensionObjectContextData";

public const string AngularDimensionObjectContextData = "AcDbAngularDimensionObjectContextData";

public const string AnnotScaleObjectContextData = "AcDbAnnotScaleObjectContextData";

public const string ApplicationId = "AcDbRegAppTableRecord";
Expand Down Expand Up @@ -202,6 +206,10 @@ public static class DxfSubclassMarker

public const string ModelerGeometry = "AcDbModelerGeometry";

public const string DiametricDimensionObjectContextData = "AcDbDiametricDimensionObjectContextData";

public const string DimensionObjectContextData = "AcDbDimensionObjectContextData";

public const string MText = "AcDbMText";

public const string MTextAttributeObjectContextData = "AcDbMTextAttributeObjectContextData";
Expand All @@ -216,6 +224,12 @@ public static class DxfSubclassMarker

public const string Ole2Frame = "AcDbOle2Frame";

public const string OrdinateDimensionObjectContextData = "AcDbOrdinateDimensionObjectContextData";

public const string RadialDimensionLargeObjectContextData = "AcDbRadialDimensionLargeObjectContextData";

public const string RadialDimensionObjectContextData = "AcDbRadialDimensionObjectContextData";

public const string OrdinateDimension = "AcDbOrdinateDimension";

public const string PartList = "AcmPartList";
Expand Down
11 changes: 11 additions & 0 deletions src/ACadSharp/Entities/Entity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,17 @@ public virtual LineType LineType
[DxfCodeValue(370)]
public LineWeightType LineWeight { get; set; } = LineWeightType.ByLayer;

/// <summary>
/// Plot style source of the entity (named plot style drawings), as stored in DWG: 0 = by layer,
/// 1 = by block, 3 = the style in <see cref="PlotStyleHandle"/>.
/// </summary>
public byte PlotStyleFlags { get; set; }

/// <summary>
/// Handle of the entity's plot style name (an entry of the ACAD_PLOTSTYLENAME dictionary) when <see cref="PlotStyleFlags"/> is 3.
/// </summary>
public ulong PlotStyleHandle { get; set; }

/// <inheritdoc/>
[DxfCodeValue(DxfReferenceType.Handle, 347)]
public Material Material
Expand Down
26 changes: 26 additions & 0 deletions src/ACadSharp/Entities/UnknownEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,32 @@ public override string SubclassMarker
}
}

/// <summary>
/// Remote text (Express Tools RTEXT) data, when this unknown entity is one and could be read.
/// </summary>
public RemoteText RText { get; set; }

/// <summary>
/// Data of an Express Tools RTEXT object: text from a file or from a DIESEL expression.
/// </summary>
public class RemoteText
{
/// <summary>Insertion point.</summary>
public XYZ InsertPoint { get; set; }
/// <summary>Extrusion direction.</summary>
public XYZ Normal { get; set; } = XYZ.AxisZ;
/// <summary>Rotation, radians.</summary>
public double Rotation { get; set; }
/// <summary>Text height.</summary>
public double Height { get; set; }
/// <summary>Flags: 1 = contents is a DIESEL expression, otherwise a file name.</summary>
public short Flags { get; set; }
/// <summary>DIESEL expression or file name.</summary>
public string Contents { get; set; }
/// <summary>Handle of the text style.</summary>
public ulong StyleHandle { get; set; }
}

/// <summary>
/// Dxf class linked to this entity.
/// </summary>
Expand Down
73 changes: 73 additions & 0 deletions src/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.Objects.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using ACadSharp.IO.Templates;
using ACadSharp.Objects;
using ACadSharp.Objects.Evaluations;
using ACadSharp.Tables;
using System;
using System.Collections.Generic;

Expand Down Expand Up @@ -29,6 +30,78 @@ private void readAnnotScaleObjectContextData(CadAnnotScaleObjectContextDataTempl
template.ScaleHandle = this.handleReference();
}

private CadTemplate readDimensionObjectContextData(DimensionObjectContextData contextData)
{
var template = new CadDimensionObjectContextDataTemplate(contextData);
this.readAnnotScaleObjectContextData(template);

//2RD 10 Text location
contextData.TextLocation = this._objectReader.Read2RawDouble();
//B 294 Default text location
contextData.IsDefaultTextLocation = this._objectReader.ReadBit();
//BD 140 Text rotation
contextData.TextRotation = this._objectReader.ReadBitDouble();
//H 2 Dimension block for this scale
template.BlockHandle = this.handleReference();
//B 293 Unknown
contextData.Unknown293 = this._objectReader.ReadBit();
//B 298 DIMTOFL
contextData.TextOutsideExtensions = this._objectReader.ReadBit();
//B 291 DIMSOXD
contextData.SuppressOutsideExtensions = this._objectReader.ReadBit();
//B 70 DIMATFIT is overridden, the DXF value is not stored
this._objectReader.ReadBit();
//B 292 DIMTIX
contextData.TextInsideExtensions = this._objectReader.ReadBit();
//B 71 DIMTMOVE is overridden, the DXF value is not stored
this._objectReader.ReadBit();
//RC 280 Override flags
contextData.OverrideFlags = this._objectReader.ReadByte();
//B 295 Unknown
contextData.Unknown295 = this._objectReader.ReadBit();
//B 296 Flip second arrow
contextData.FlipSecondArrow = this._objectReader.ReadBit();
//B 297 Flip first arrow
contextData.FlipFirstArrow = this._objectReader.ReadBit();

switch (contextData)
{
case AlignedDimensionObjectContextData aligned:
//3BD 11 Dimension line point
aligned.DimensionLinePoint = this._objectReader.Read3BitDouble();
break;
case AngularDimensionObjectContextData angular:
//3BD 11 Arc point
angular.ArcPoint = this._objectReader.Read3BitDouble();
break;
case DiametricDimensionObjectContextData diametric:
//3BD 11 First arc point
diametric.FirstArcPoint = this._objectReader.Read3BitDouble();
//3BD 12 Definition point
diametric.DefinitionPoint = this._objectReader.Read3BitDouble();
break;
case OrdinateDimensionObjectContextData ordinate:
//3BD 11 Definition point
ordinate.DefinitionPoint = this._objectReader.Read3BitDouble();
//3BD 12 Leader end point
ordinate.LeaderEndpoint = this._objectReader.Read3BitDouble();
break;
case RadialDimensionObjectContextData radial:
//3BD 11 First arc point
radial.FirstArcPoint = this._objectReader.Read3BitDouble();
if (radial is RadialDimensionLargeObjectContextData large)
{
//3BD 12 Override center
large.OverrideCenter = this._objectReader.Read3BitDouble();
//3BD 13 Jog point
large.JogPoint = this._objectReader.Read3BitDouble();
}
break;
}

return template;
}

private CadTemplate readBlkRefObjectContextData()
{
BlockReferenceObjectContextData contextData = new BlockReferenceObjectContextData();
Expand Down
Loading