Skip to content

Commit

Permalink
Merge pull request #427 from DomCR/issue-417_Hatch-polyline
Browse files Browse the repository at this point in the history
Issue 417 hatch polyline
  • Loading branch information
DomCR authored Aug 19, 2024
2 parents 5442cb8 + 9281c34 commit b9b5db1
Show file tree
Hide file tree
Showing 14 changed files with 278 additions and 21 deletions.
117 changes: 117 additions & 0 deletions src/ACadSharp.Tests/Entities/HatchTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using ACadSharp.Entities;
using CSMath;
using CSUtilities.Extensions;
using System;
using System.Collections.Generic;
using Xunit;

namespace ACadSharp.Tests.Entities
{
public class HatchTests
{
[Fact]
public void CreateHatch()
{
Hatch hatch = new Hatch();
hatch.IsSolid = true;

hatch.SeedPoints.Add(new XY());

List<Hatch.BoundaryPath.Line> edges = new List<Hatch.BoundaryPath.Line>();

//edges
Hatch.BoundaryPath.Line edge1 = new Hatch.BoundaryPath.Line
{
Start = new CSMath.XY(0, 0),
End = new CSMath.XY(1, 0)
};
edges.Add(edge1);

Hatch.BoundaryPath.Line edge2 = new Hatch.BoundaryPath.Line
{
Start = new CSMath.XY(1, 0),
End = new CSMath.XY(1, 1)
};
edges.Add(edge2);

Hatch.BoundaryPath.Line edge3 = new Hatch.BoundaryPath.Line
{
Start = new CSMath.XY(1, 1),
End = new CSMath.XY(0, 1)
};
edges.Add(edge3);

Hatch.BoundaryPath.Line edge4 = new Hatch.BoundaryPath.Line
{
Start = new CSMath.XY(0, 1),
End = new CSMath.XY(0, 0)
};
edges.Add(edge4);


Hatch.BoundaryPath path = new Hatch.BoundaryPath();
foreach (var item in edges)
{
path.Edges.Add(item);
}

hatch.Paths.Add(path);

Assert.NotEmpty(hatch.Paths);
Assert.NotEmpty(path.Edges);
Assert.False(path.IsPolyline);
}

[Fact]
public void CreatePolylineHatch()
{
Hatch hatch = new Hatch();
hatch.IsSolid = true;

Hatch.BoundaryPath path = new Hatch.BoundaryPath();

Hatch.BoundaryPath.Polyline pline = new Hatch.BoundaryPath.Polyline();
pline.Vertices.Add(new XYZ(0, 0, 0));
pline.Vertices.Add(new XYZ(1, 0, 0));
pline.Vertices.Add(new XYZ(1, 1, 0));
pline.Vertices.Add(new XYZ(0, 1, 0));
pline.Vertices.Add(new XYZ(0, 0, 0));

path.Edges.Add(pline);
path.Flags = path.Flags.AddFlag(BoundaryPathFlags.Polyline);
hatch.Paths.Add(path);

Assert.True(path.IsPolyline);
}

[Fact]
public void PolylineHatchNotAllowMoreEdges()
{
Hatch hatch = new Hatch();
hatch.IsSolid = true;

Hatch.BoundaryPath path = new Hatch.BoundaryPath();

Hatch.BoundaryPath.Polyline pline = new Hatch.BoundaryPath.Polyline();
pline.Vertices.Add(new XYZ(0, 0, 0));
pline.Vertices.Add(new XYZ(1, 0, 0));
pline.Vertices.Add(new XYZ(1, 1, 0));
pline.Vertices.Add(new XYZ(0, 1, 0));
pline.Vertices.Add(new XYZ(0, 0, 0));

path.Edges.Add(pline);

Assert.Throws<InvalidOperationException>(() =>
{
path.Edges.Add(new Hatch.BoundaryPath.Line());
}
);

Assert.Throws<InvalidOperationException>(() =>
{
path.Edges.Add(new Hatch.BoundaryPath.Polyline());
}
);
}
}
}
4 changes: 3 additions & 1 deletion src/ACadSharp.Tests/IO/CadReaderTestsBase.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using ACadSharp.Header;
using ACadSharp.Entities;
using ACadSharp.Header;
using ACadSharp.IO;
using ACadSharp.Tests.TestModels;
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit;
using Xunit.Abstractions;

Expand Down
2 changes: 1 addition & 1 deletion src/ACadSharp.Tests/IO/IOTestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ protected void onNotification(object sender, NotificationEventArgs e)

protected static void loadLocalSamples(string folder, string ext, TheoryData<FileModel> files)
{
string path = Path.Combine(TestVariables.SamplesFolder, "local", folder);
string path = Path.Combine("local", folder);
loadSamples(path, ext, files);
}

Expand Down
74 changes: 74 additions & 0 deletions src/ACadSharp.Tests/IO/WriterSingleObjectTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using ACadSharp.Objects;
using ACadSharp.Tables;
using CSMath;
using CSUtilities.Extensions;
using System.Collections.Generic;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -278,6 +279,77 @@ public void EntityTransparency()
this.Document.Entities.Add(line);
}

public void CreateHatchPolyline()
{
Hatch hatch = new Hatch();
hatch.IsSolid = true;

Hatch.BoundaryPath path = new Hatch.BoundaryPath();

Hatch.BoundaryPath.Polyline pline = new Hatch.BoundaryPath.Polyline();
pline.Vertices.Add(new XYZ(0, 0, 0));
pline.Vertices.Add(new XYZ(1, 0, 0));
pline.Vertices.Add(new XYZ(1, 1, 0));
pline.Vertices.Add(new XYZ(0, 1, 0));
pline.Vertices.Add(new XYZ(0, 0, 0));

path.Edges.Add(pline);
path.Flags = path.Flags.AddFlag(BoundaryPathFlags.Polyline);
hatch.Paths.Add(path);

this.Document.Entities.Add(hatch);
}

public void CreateHatch()
{
Hatch hatch = new Hatch();
hatch.IsSolid = true;

hatch.SeedPoints.Add(new XY());

List<Hatch.BoundaryPath.Line> edges = new List<Hatch.BoundaryPath.Line>();

//edges
Hatch.BoundaryPath.Line edge1 = new Hatch.BoundaryPath.Line
{
Start = new CSMath.XY(0, 0),
End = new CSMath.XY(1, 0)
};
edges.Add(edge1);

Hatch.BoundaryPath.Line edge2 = new Hatch.BoundaryPath.Line
{
Start = new CSMath.XY(1, 0),
End = new CSMath.XY(1, 1)
};
edges.Add(edge2);

Hatch.BoundaryPath.Line edge3 = new Hatch.BoundaryPath.Line
{
Start = new CSMath.XY(1, 1),
End = new CSMath.XY(0, 1)
};
edges.Add(edge3);

Hatch.BoundaryPath.Line edge4 = new Hatch.BoundaryPath.Line
{
Start = new CSMath.XY(0, 1),
End = new CSMath.XY(0, 0)
};
edges.Add(edge4);


Hatch.BoundaryPath path = new Hatch.BoundaryPath();
foreach (var item in edges)
{
path.Edges.Add(item);
}

hatch.Paths.Add(path);

this.Document.Entities.Add(hatch);
}

public void ChangedEncoding()
{
this.Document.Header.CodePage = "gb2312";
Expand Down Expand Up @@ -331,6 +403,8 @@ static WriterSingleObjectTests()
Data.Add(new(nameof(SingleCaseGenerator.CreateLayout)));
Data.Add(new(nameof(SingleCaseGenerator.EntityTransparency)));
Data.Add(new(nameof(SingleCaseGenerator.LineTypeWithSegments)));
Data.Add(new(nameof(SingleCaseGenerator.CreateHatchPolyline)));
Data.Add(new(nameof(SingleCaseGenerator.CreateHatch)));
Data.Add(new(nameof(SingleCaseGenerator.ChangedEncoding)));
}

Expand Down
4 changes: 2 additions & 2 deletions src/ACadSharp/CadDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ private void onRemove(object sender, CollectionChangedEventArgs e)
}
}

internal void RegisterCollection<T>(IObservableCollection<T> collection)
internal void RegisterCollection<T>(IObservableCadCollection<T> collection)
where T : CadObject
{
switch (collection)
Expand Down Expand Up @@ -498,7 +498,7 @@ internal void RegisterCollection<T>(IObservableCollection<T> collection)
}
}

internal void UnregisterCollection<T>(IObservableCollection<T> collection)
internal void UnregisterCollection<T>(IObservableCadCollection<T> collection)
where T : CadObject
{
switch (collection)
Expand Down
2 changes: 1 addition & 1 deletion src/ACadSharp/CadObjectCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace ACadSharp
{
public class CadObjectCollection<T> : IObservableCollection<T>
public class CadObjectCollection<T> : IObservableCadCollection<T>
where T : CadObject
{
public event EventHandler<CollectionChangedEventArgs> OnAdd;
Expand Down
3 changes: 3 additions & 0 deletions src/ACadSharp/Entities/Hatch.BoundaryPath.Edge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
{
public partial class Hatch
{
/// <summary>
/// Defines a hatch boundary.
/// </summary>
public partial class BoundaryPath
{
public enum EdgeType
Expand Down
9 changes: 6 additions & 3 deletions src/ACadSharp/Entities/Hatch.BoundaryPath.Polyline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ public class Polyline : Edge
public override EdgeType Type => EdgeType.Polyline;

/// <summary>
/// The polyline has bulges with value different than 0
/// The polyline has bulges with value different than 0.
/// </summary>
[DxfCodeValue(72)]
public bool HasBulge => this.Bulges.Any(b => b != 0);

/// <summary>
/// Is closed flag
/// Is closed flag.
/// </summary>
[DxfCodeValue(73)]
public bool IsClosed { get; set; }
Expand All @@ -35,8 +35,11 @@ public class Polyline : Edge
[DxfCodeValue(DxfReferenceType.Optional, 42)]
public IEnumerable<double> Bulges { get { return this.Vertices.Select(v => v.Z); } }

/// <summary>
/// Position values are only X and Y.
/// </summary>
/// <remarks>
/// Position values are only X and Y
/// The vertex bulge is stored in the Z component.
/// </remarks>
[DxfCodeValue(DxfReferenceType.Count, 93)]
public List<XYZ> Vertices { get; set; } = new();
Expand Down
65 changes: 63 additions & 2 deletions src/ACadSharp/Entities/Hatch.BoundaryPath.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,42 @@
using ACadSharp.Attributes;
using CSUtilities.Extensions;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;

namespace ACadSharp.Entities
{
public partial class Hatch
{
public partial class BoundaryPath
{
public bool IsPolyline { get { return this.Edges.OfType<Polyline>().Any(); } }

/// <summary>
/// Boundary path type flag
/// </summary>
[DxfCodeValue(92)]
public BoundaryPathFlags Flags { get; set; }
public BoundaryPathFlags Flags
{
get
{
if (this.IsPolyline)
{
this._flags = this._flags.AddFlag(BoundaryPathFlags.Polyline);
}
else
{
this._flags = this._flags.RemoveFlag(BoundaryPathFlags.Polyline);
}

return this._flags;
}
set
{
this._flags = value;
}
}

/// <summary>
/// Number of edges in this boundary path
Expand All @@ -20,18 +45,54 @@ public partial class BoundaryPath
/// only if boundary is not a polyline
/// </remarks>
[DxfCodeValue(DxfReferenceType.Count, 93)]
public List<Edge> Edges { get; set; } = new List<Edge>();
public ObservableCollection<Edge> Edges { get; } = new();

/// <summary>
/// Source boundary objects
/// </summary>
[DxfCodeValue(DxfReferenceType.Count, 97)]
public List<Entity> Entities { get; set; } = new List<Entity>();

private BoundaryPathFlags _flags;

public BoundaryPath()
{
Edges.CollectionChanged += this.onEdgesCollectionChanged;
}

public BoundaryPath Clone()
{
throw new System.NotImplementedException();
}

private void onEdgesCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
onAdd(e);
break;
case System.Collections.Specialized.NotifyCollectionChangedAction.Remove:
break;
case System.Collections.Specialized.NotifyCollectionChangedAction.Replace:
break;
case System.Collections.Specialized.NotifyCollectionChangedAction.Move:
break;
case System.Collections.Specialized.NotifyCollectionChangedAction.Reset:
break;
}
}

private void onAdd(NotifyCollectionChangedEventArgs e)
{
foreach (Edge edge in e.NewItems)
{
if (this.Edges.Count > 1 && this.IsPolyline)
{
throw new System.InvalidOperationException();
}
}
}
}
}
}
Loading

0 comments on commit b9b5db1

Please sign in to comment.