Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cad to svg #211

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
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
67 changes: 67 additions & 0 deletions src/ACadSharp.Tests/IO/SvgWriterTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using ACadSharp.Entities;
using ACadSharp.IO;
using ACadSharp.Tests.Common;
using CSMath;
using System;
using System.IO;
using Xunit;

namespace ACadSharp.Tests.IO
{
public class SvgWriterTests
{
public static readonly TheoryData<Type> EntityTypes = new TheoryData<Type>();

static SvgWriterTests()
{
foreach (var item in DataFactory.GetTypes<Entity>())
{
if (item == typeof(UnknownEntity))
{
continue;
}

EntityTypes.Add(item);
}

if (!Directory.Exists(TestVariables.OutputSvgFolder))
{
Directory.CreateDirectory(TestVariables.OutputSvgFolder);
}
}

[Theory]
[MemberData(nameof(EntityTypes))]
public void WriteEntitiesNoDocument(Type t)
{
Entity e = (Entity)Factory.CreateObject(t);
string filename = Path.Combine(TestVariables.OutputSvgFolder, $"{e.SubclassMarker}.svg");

using (SvgWriter writer = new SvgWriter(filename))
{
writer.WriteEntity(e);
}
}

[Fact]
public void WriteLineNoDocument()
{
Entity e = new Line(new XYZ(0, 0, 0), new XYZ(10, 10, 0));

string filename = Path.Combine(TestVariables.OutputSvgFolder, $"{e.ObjectType}.svg");

using (SvgWriter writer = new SvgWriter(filename))
{
writer.WriteEntity(e);
}
}

private void writeSvg(string filename, string svg)
{
using (StreamWriter sw = new StreamWriter(filename))
{
sw.Write(svg);
}
}
}
}
10 changes: 10 additions & 0 deletions src/ACadSharp.Tests/IO/WriterSingleObjectTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,15 @@ public void SingleMText()
this.Document.Entities.Add(mtext);
}

public void MTextChineseCharacters()
{
MText mtext = new MText();

mtext.Value = "这是一个多行文本";

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

public void SingleMTextSpecialCharacter()
{
MText mtext = new MText();
Expand Down Expand Up @@ -483,6 +492,7 @@ static WriterSingleObjectTests()
Data.Add(new(nameof(SingleCaseGenerator.SingleMText)));
Data.Add(new(nameof(SingleCaseGenerator.SingleMTextSpecialCharacter)));
Data.Add(new(nameof(SingleCaseGenerator.SingleMTextMultiline)));
Data.Add(new(nameof(SingleCaseGenerator.MTextChineseCharacters)));
Data.Add(new(nameof(SingleCaseGenerator.SinglePoint)));
Data.Add(new(nameof(SingleCaseGenerator.ClosedLwPolyline)));
Data.Add(new(nameof(SingleCaseGenerator.ClosedPolyline2DTest)));
Expand Down
19 changes: 12 additions & 7 deletions src/ACadSharp.Tests/TestVariables.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ public static class TestVariables
public static string DesktopFolder { get { return Environment.GetFolderPath(Environment.SpecialFolder.Desktop); } }

public static string SamplesFolder { get { return EnvironmentVars.Get<string>("SAMPLES_FOLDER"); } }

public static string OutputSamplesFolder { get { return EnvironmentVars.Get<string>("OUTPUT_SAMPLES_FOLDER"); } }

public static string OutputSingleCasesFolder { get { return EnvironmentVars.Get<string>("OUTPUT_SINGLE_CASES_FOLDER"); } }

public static string OutputSvgFolder { get { return EnvironmentVars.Get<string>("OUTPUT_SVG"); } }

public static bool LocalEnv { get { return EnvironmentVars.Get<bool>("LOCAL_ENV"); } }

public static double Delta { get { return EnvironmentVars.Get<double>("DELTA"); } }
Expand All @@ -27,6 +29,7 @@ static TestVariables()
EnvironmentVars.SetIfNull("SAMPLES_FOLDER", "../../../../../samples/");
EnvironmentVars.SetIfNull("OUTPUT_SAMPLES_FOLDER", "../../../../../samples/out");
EnvironmentVars.SetIfNull("OUTPUT_SINGLE_CASES_FOLDER", "../../../../../samples/out/single_cases");
EnvironmentVars.SetIfNull("OUTPUT_SVG", "../../../../../samples/out/svg");
EnvironmentVars.SetIfNull("LOCAL_ENV", "true");
EnvironmentVars.SetIfNull("DELTA", "0.00001");
EnvironmentVars.SetIfNull("DECIMAL_PRECISION", "5");
Expand All @@ -35,14 +38,16 @@ static TestVariables()

public static void CreateOutputFolders()
{
if (!Directory.Exists(OutputSamplesFolder))
{
Directory.CreateDirectory(OutputSamplesFolder);
}
craateFolderIfDoesNotExist(OutputSamplesFolder);
craateFolderIfDoesNotExist(OutputSingleCasesFolder);
craateFolderIfDoesNotExist(OutputSvgFolder);
}

if (!Directory.Exists(OutputSingleCasesFolder))
private static void craateFolderIfDoesNotExist(string path)
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(OutputSingleCasesFolder);
Directory.CreateDirectory(path);
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/ACadSharp/Entities/Line.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ public class Line : Entity
public XYZ EndPoint { get; set; } = XYZ.Zero;

/// <summary>
/// Default constructor
/// Default constructor.
/// </summary>
public Line() : base() { }

/// <summary>
/// Constructor with the start and end
/// Constructor with the start and end.
/// </summary>
/// <param name="start"></param>
/// <param name="end"></param>
Expand All @@ -72,4 +72,4 @@ public override BoundingBox GetBoundingBox()
return new BoundingBox(min, max);
}
}
}
}
13 changes: 1 addition & 12 deletions src/ACadSharp/IO/CadWriterBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,6 @@
using System;
using System.IO;
using ACadSharp.Classes;
using ACadSharp.IO;
using ACadSharp.Exceptions;
using ACadSharp.IO.DWG;
using ACadSharp.IO.DWG.DwgStreamWriters;
using CSUtilities.IO;
using System.Collections.Generic;

namespace ACadSharp.IO
{
Expand All @@ -18,12 +12,7 @@ namespace ACadSharp.IO
public abstract class CadWriterBase<T> : ICadWriter
where T : CadWriterConfiguration, new()
{
/// <summary>
/// Notification event to get information about the writing process.
/// </summary>
/// <remarks>
/// The notification system informs about any issue or non critical errors during the writing.
/// </remarks>
/// <inheritdoc/>
public event NotificationEventHandler OnNotification;

/// <summary>
Expand Down
10 changes: 9 additions & 1 deletion src/ACadSharp/IO/ICadWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@ namespace ACadSharp.IO
public interface ICadWriter : IDisposable
{
/// <summary>
/// Write the <see cref="CadDocument"/>
/// Notification event to get information about the writing process.
/// </summary>
/// <remarks>
/// The notification system informs about any issue or non critical errors during the writing.
/// </remarks>
event NotificationEventHandler OnNotification;

/// <summary>
/// Write the <see cref="CadDocument"/> into the stream.
/// </summary>
void Write();
}
Expand Down
183 changes: 183 additions & 0 deletions src/ACadSharp/IO/SvgWriter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
using ACadSharp.Entities;
using CSMath;
using System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Xml;

namespace ACadSharp.IO
{
public class SvgWriter : CadWriterBase<CadWriterConfiguration>
{
private SvgXmlWriter _writer;

public SvgWriter(Stream stream) : base(stream, null)
{
StreamWriter textWriter = new StreamWriter(stream);
this._writer = new SvgXmlWriter(textWriter);
}

public SvgWriter(string filename)
: this(File.Create(filename), null)
{
}

public SvgWriter(string filename, CadDocument document)
: this(File.Create(filename), document)
{
}

public SvgWriter(Stream stream, CadDocument document) : base(stream, document)
{
StreamWriter textWriter = new StreamWriter(this._stream);
this._writer = new SvgXmlWriter(this._stream, Encoding.Default);

this._writer.Formatting = Formatting.Indented;
}

/// <inheritdoc/>
/// <remarks>
/// <see cref="SvgWriter"/> will draw all the content in the model space.<br/>
/// The writer must be initialized with a none null <see cref="CadDocument"/>.
/// </remarks>
public override void Write()
{
this.Write(this._document);

throw new NotImplementedException();
}

public void Write(CadDocument document)
{
if (this._document is null)
{
throw new ArgumentNullException("CadDocument cannot be null in the SvgWriter.", "CadDocument");
}

this._encoding = this.getListedEncoding(document.Header.CodePage);

throw new NotImplementedException();
}

public void WriteEntity(Entity entity)
{
this._writer.WriteStartDocument();

this._writer.WriteStartElement("svg");

BoundingBox box = entity.GetBoundingBox();
this._writer.WriteAttributeString("width", box.Max.X);
this._writer.WriteAttributeString("height", box.Max.Y);

switch (entity)
{
case Line line:
this.writeLine(line);
break;
default:
throw new NotImplementedException($"Entity {entity.SubclassMarker} is not implemented.");
}

this._writer.WriteEndElement();

this._writer.WriteEndDocument();

this._writer.Close();
}

private void writeEntityStyle(Entity entity)
{
this._writer.WriteAttributeString("style", $"stroke:rgb({entity.Color.R},{entity.Color.G},{entity.Color.B})");
}

private void writeLine(Line line)
{
this._writer.WriteStartElement("line");

this.writeEntityStyle(line);

this._writer.WriteAttributeString("x1", line.StartPoint.X);
this._writer.WriteAttributeString("y1", line.StartPoint.Y);
this._writer.WriteAttributeString("x2", line.EndPoint.X);
this._writer.WriteAttributeString("y2", line.EndPoint.Y);
}

public string Convert(Entity entity)
{
StringBuilder sb = new StringBuilder();

BoundingBox box = entity.GetBoundingBox();



sb.AppendLine($"<svg width=\"{box.Max.X}\" height=\"{box.Max.Y}\">");

switch (entity)
{
case Line line:
sb.AppendLine(convertLine(line));
break;
default:
throw new NotImplementedException($"Svg convertion not implemented for {entity.SubclassMarker}");
}

sb.AppendLine($"</svg>");

return sb.ToString();
}

/// <inheritdoc/>
public override void Dispose()
{
this._stream.Dispose();
}

private string convertLine(Line line)
{
StringBuilder sb = new StringBuilder();

sb.Append($"\t");
sb.Append($"<line ");
sb.Append($"x1=\"{line.StartPoint.X}\" ");
sb.Append($"y1=\"{line.StartPoint.Y}\" ");
sb.Append($"x2=\"{line.EndPoint.X}\" ");
sb.Append($"y2=\"{line.EndPoint.Y}\" ");
sb.Append(this.entityStyle(line));
sb.Append($"/>");

return sb.ToString();
}

private string entityStyle(Entity entity)
{
StringBuilder style = new StringBuilder();

style.Append($"style=");

style.Append($"\"stroke:rgb({entity.Color.R},{entity.Color.G},{entity.Color.B})\"");

return style.ToString();
}
}

public class SvgXmlWriter : XmlTextWriter
{
public SvgXmlWriter(TextWriter w) : base(w)
{
}

public SvgXmlWriter(Stream w, Encoding encoding) : base(w, encoding)
{
}

public SvgXmlWriter(string filename, Encoding encoding) : base(filename, encoding)
{
}

public void WriteAttributeString(string localName, double value)
{
this.WriteAttributeString(localName, value.ToString(CultureInfo.InvariantCulture));
}
}
}
2 changes: 1 addition & 1 deletion src/CSUtilities
Loading