Added Plate class
This commit is contained in:
Родитель
8cac594725
Коммит
28dfbe6226
|
@ -481,7 +481,19 @@ namespace SpiroNet.Wpf
|
||||||
using (var f = System.IO.File.OpenText(path))
|
using (var f = System.IO.File.OpenText(path))
|
||||||
{
|
{
|
||||||
var plate = f.ReadToEnd();
|
var plate = f.ReadToEnd();
|
||||||
ExecuteScript(plate);
|
var shapes = Plate.ToShapes(plate);
|
||||||
|
if (shapes != null)
|
||||||
|
{
|
||||||
|
Shapes = shapes;
|
||||||
|
Data = new Dictionary<PathShape, string>();
|
||||||
|
|
||||||
|
foreach (var shape in Shapes)
|
||||||
|
{
|
||||||
|
UpdateData(shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,64 +501,11 @@ namespace SpiroNet.Wpf
|
||||||
{
|
{
|
||||||
using (var f = System.IO.File.CreateText(path))
|
using (var f = System.IO.File.CreateText(path))
|
||||||
{
|
{
|
||||||
var plate = ToPlate(Shapes);
|
var plate = Plate.FromShapes(Shapes);
|
||||||
f.Write(plate);
|
f.Write(plate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string Format(double value)
|
|
||||||
{
|
|
||||||
return value.ToString(CultureInfo.GetCultureInfo("en-GB"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string ToPlate(IList<PathShape> shapes)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
|
|
||||||
sb.AppendLine("(plate");
|
|
||||||
|
|
||||||
foreach (var shape in shapes)
|
|
||||||
{
|
|
||||||
foreach (var point in shape.Points)
|
|
||||||
{
|
|
||||||
switch (point.Type)
|
|
||||||
{
|
|
||||||
case SpiroPointType.Corner:
|
|
||||||
sb.AppendLine(string.Format(" (v {0} {1})", Format(point.X), Format(point.Y)));
|
|
||||||
break;
|
|
||||||
case SpiroPointType.G4:
|
|
||||||
sb.AppendLine(string.Format(" (o {0} {1})", Format(point.X), Format(point.Y)));
|
|
||||||
break;
|
|
||||||
case SpiroPointType.G2:
|
|
||||||
sb.AppendLine(string.Format(" (c {0} {1})", Format(point.X), Format(point.Y)));
|
|
||||||
break;
|
|
||||||
case SpiroPointType.Left:
|
|
||||||
sb.AppendLine(string.Format(" ([ {0} {1})", Format(point.X), Format(point.Y)));
|
|
||||||
break;
|
|
||||||
case SpiroPointType.Right:
|
|
||||||
sb.AppendLine(string.Format(" (] {0} {1})", Format(point.X), Format(point.Y)));
|
|
||||||
break;
|
|
||||||
case SpiroPointType.End:
|
|
||||||
sb.AppendLine(" (z)");
|
|
||||||
break;
|
|
||||||
case SpiroPointType.OpenContour:
|
|
||||||
sb.AppendLine(string.Format(" ({ {0} {1})", Format(point.X), Format(point.Y)));
|
|
||||||
break;
|
|
||||||
case SpiroPointType.EndOpenContour:
|
|
||||||
sb.AppendLine(string.Format(" (} {0} {1})", Format(point.X), Format(point.Y)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shape.IsClosed && !shape.IsTagged)
|
|
||||||
sb.AppendLine(" (z)");
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.AppendLine(")");
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ExportAsSvg(string path)
|
public void ExportAsSvg(string path)
|
||||||
{
|
{
|
||||||
using (var f = System.IO.File.CreateText(path))
|
using (var f = System.IO.File.CreateText(path))
|
||||||
|
@ -580,159 +539,19 @@ namespace SpiroNet.Wpf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private PathShape NewTaggedShape()
|
|
||||||
{
|
|
||||||
return new PathShape()
|
|
||||||
{
|
|
||||||
IsStroked = true,
|
|
||||||
IsFilled = false,
|
|
||||||
IsClosed = false,
|
|
||||||
IsTagged = true,
|
|
||||||
Points = new ObservableCollection<SpiroControlPoint>()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static SpiroControlPoint ToPoint(SpiroPointType type, string x, string y)
|
|
||||||
{
|
|
||||||
var point = new SpiroControlPoint();
|
|
||||||
point.X = double.Parse(x, CultureInfo.GetCultureInfo("en-GB").NumberFormat);
|
|
||||||
point.Y = double.Parse(y, CultureInfo.GetCultureInfo("en-GB").NumberFormat);
|
|
||||||
point.Type = type;
|
|
||||||
return point;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ExecuteScript(string script)
|
public void ExecuteScript(string script)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(script))
|
var shapes = Plate.ToShapes(script);
|
||||||
return;
|
if (shapes != null)
|
||||||
|
|
||||||
var newLine = Environment.NewLine.ToCharArray();
|
|
||||||
var separator = new char[] { ' ', '\t' };
|
|
||||||
var trim = new char[] { '(', ')' };
|
|
||||||
var options = StringSplitOptions.RemoveEmptyEntries;
|
|
||||||
var lines = script.Split(newLine, options).Select(x => x.Trim().Trim(trim).Split(separator, options));
|
|
||||||
|
|
||||||
PathShape shape = null;
|
|
||||||
|
|
||||||
foreach (var line in lines)
|
|
||||||
{
|
{
|
||||||
if (line.Length == 0 || line[0] == "plate")
|
foreach (var shape in shapes)
|
||||||
continue;
|
|
||||||
|
|
||||||
switch (line[0][0])
|
|
||||||
{
|
{
|
||||||
case 'v':
|
Shapes.Add(shape);
|
||||||
{
|
UpdateData(shape);
|
||||||
if (shape == null)
|
|
||||||
shape = NewTaggedShape();
|
|
||||||
|
|
||||||
if (line.Length == 3)
|
|
||||||
shape.Points.Add(ToPoint(SpiroPointType.Corner, line[1], line[2]));
|
|
||||||
else
|
|
||||||
throw new FormatException();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
{
|
|
||||||
if (shape == null)
|
|
||||||
shape = NewTaggedShape();
|
|
||||||
|
|
||||||
if (line.Length == 3)
|
|
||||||
shape.Points.Add(ToPoint(SpiroPointType.G4, line[1], line[2]));
|
|
||||||
else
|
|
||||||
throw new FormatException();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
{
|
|
||||||
if (shape == null)
|
|
||||||
shape = NewTaggedShape();
|
|
||||||
|
|
||||||
if (line.Length == 3)
|
|
||||||
shape.Points.Add(ToPoint(SpiroPointType.G2, line[1], line[2]));
|
|
||||||
else
|
|
||||||
throw new FormatException();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '[':
|
|
||||||
{
|
|
||||||
if (shape == null)
|
|
||||||
shape = NewTaggedShape();
|
|
||||||
|
|
||||||
if (line.Length == 3)
|
|
||||||
shape.Points.Add(ToPoint(SpiroPointType.Left, line[1], line[2]));
|
|
||||||
else
|
|
||||||
throw new FormatException();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ']':
|
|
||||||
{
|
|
||||||
if (shape == null)
|
|
||||||
shape = NewTaggedShape();
|
|
||||||
|
|
||||||
if (line.Length == 3)
|
|
||||||
shape.Points.Add(ToPoint(SpiroPointType.Right, line[1], line[2]));
|
|
||||||
else
|
|
||||||
throw new FormatException();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'z':
|
|
||||||
{
|
|
||||||
if (shape == null)
|
|
||||||
shape = NewTaggedShape();
|
|
||||||
|
|
||||||
if (line.Length == 1)
|
|
||||||
shape.Points.Add(ToPoint(SpiroPointType.End, "0", "0"));
|
|
||||||
else if (line.Length == 3)
|
|
||||||
shape.Points.Add(ToPoint(SpiroPointType.End, line[1], line[2]));
|
|
||||||
else
|
|
||||||
throw new FormatException();
|
|
||||||
|
|
||||||
Shapes.Add(shape);
|
|
||||||
UpdateData(shape);
|
|
||||||
shape = null;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '{':
|
|
||||||
{
|
|
||||||
if (shape == null)
|
|
||||||
shape = NewTaggedShape();
|
|
||||||
|
|
||||||
if (line.Length == 3)
|
|
||||||
shape.Points.Add(ToPoint(SpiroPointType.OpenContour, line[1], line[2]));
|
|
||||||
else
|
|
||||||
throw new FormatException();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '}':
|
|
||||||
{
|
|
||||||
if (shape == null)
|
|
||||||
shape = NewTaggedShape();
|
|
||||||
|
|
||||||
if (line.Length == 3)
|
|
||||||
shape.Points.Add(ToPoint(SpiroPointType.EndOpenContour, line[1], line[2]));
|
|
||||||
else
|
|
||||||
throw new FormatException();
|
|
||||||
|
|
||||||
Shapes.Add(shape);
|
|
||||||
UpdateData(shape);
|
|
||||||
shape = null;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new FormatException();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (shape != null)
|
Invalidate();
|
||||||
{
|
|
||||||
shape.IsTagged = false;
|
|
||||||
Shapes.Add(shape);
|
|
||||||
UpdateData(shape);
|
|
||||||
shape = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Invalidate();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,238 @@
|
||||||
|
/*
|
||||||
|
SpiroNet.Wpf
|
||||||
|
Copyright (C) 2015 Wiesław Šoltés
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 3
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace SpiroNet.Wpf
|
||||||
|
{
|
||||||
|
public static class Plate
|
||||||
|
{
|
||||||
|
private static string Format(double value)
|
||||||
|
{
|
||||||
|
return value.ToString(CultureInfo.GetCultureInfo("en-GB"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string FromShapes(IList<PathShape> shapes)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
|
sb.AppendLine("(plate");
|
||||||
|
|
||||||
|
foreach (var shape in shapes)
|
||||||
|
{
|
||||||
|
foreach (var point in shape.Points)
|
||||||
|
{
|
||||||
|
switch (point.Type)
|
||||||
|
{
|
||||||
|
case SpiroPointType.Corner:
|
||||||
|
sb.AppendLine(string.Format(" (v {0} {1})", Format(point.X), Format(point.Y)));
|
||||||
|
break;
|
||||||
|
case SpiroPointType.G4:
|
||||||
|
sb.AppendLine(string.Format(" (o {0} {1})", Format(point.X), Format(point.Y)));
|
||||||
|
break;
|
||||||
|
case SpiroPointType.G2:
|
||||||
|
sb.AppendLine(string.Format(" (c {0} {1})", Format(point.X), Format(point.Y)));
|
||||||
|
break;
|
||||||
|
case SpiroPointType.Left:
|
||||||
|
sb.AppendLine(string.Format(" ([ {0} {1})", Format(point.X), Format(point.Y)));
|
||||||
|
break;
|
||||||
|
case SpiroPointType.Right:
|
||||||
|
sb.AppendLine(string.Format(" (] {0} {1})", Format(point.X), Format(point.Y)));
|
||||||
|
break;
|
||||||
|
case SpiroPointType.End:
|
||||||
|
sb.AppendLine(" (z)");
|
||||||
|
break;
|
||||||
|
case SpiroPointType.OpenContour:
|
||||||
|
sb.AppendLine(string.Format(" ({ {0} {1})", Format(point.X), Format(point.Y)));
|
||||||
|
break;
|
||||||
|
case SpiroPointType.EndOpenContour:
|
||||||
|
sb.AppendLine(string.Format(" (} {0} {1})", Format(point.X), Format(point.Y)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shape.IsClosed && !shape.IsTagged)
|
||||||
|
sb.AppendLine(" (z)");
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.AppendLine(")");
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PathShape NewShape()
|
||||||
|
{
|
||||||
|
return new PathShape()
|
||||||
|
{
|
||||||
|
IsStroked = true,
|
||||||
|
IsFilled = false,
|
||||||
|
IsClosed = false,
|
||||||
|
IsTagged = true,
|
||||||
|
Points = new ObservableCollection<SpiroControlPoint>()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SpiroControlPoint NewPoint(SpiroPointType type, string x, string y)
|
||||||
|
{
|
||||||
|
var point = new SpiroControlPoint();
|
||||||
|
point.X = double.Parse(x, CultureInfo.GetCultureInfo("en-GB").NumberFormat);
|
||||||
|
point.Y = double.Parse(y, CultureInfo.GetCultureInfo("en-GB").NumberFormat);
|
||||||
|
point.Type = type;
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IList<PathShape> ToShapes(string plate)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(plate))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var shapes = new ObservableCollection<PathShape>();
|
||||||
|
var newLine = Environment.NewLine.ToCharArray();
|
||||||
|
var separator = new char[] { ' ', '\t' };
|
||||||
|
var trim = new char[] { '(', ')' };
|
||||||
|
var options = StringSplitOptions.RemoveEmptyEntries;
|
||||||
|
var lines = plate.Split(newLine, options).Select(x => x.Trim().Trim(trim).Split(separator, options));
|
||||||
|
|
||||||
|
PathShape shape = null;
|
||||||
|
|
||||||
|
foreach (var line in lines)
|
||||||
|
{
|
||||||
|
if (line.Length == 0 || line[0] == "plate")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (line[0][0])
|
||||||
|
{
|
||||||
|
case 'v':
|
||||||
|
{
|
||||||
|
if (shape == null)
|
||||||
|
shape = NewShape();
|
||||||
|
|
||||||
|
if (line.Length == 3)
|
||||||
|
shape.Points.Add(NewPoint(SpiroPointType.Corner, line[1], line[2]));
|
||||||
|
else
|
||||||
|
throw new FormatException();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
{
|
||||||
|
if (shape == null)
|
||||||
|
shape = NewShape();
|
||||||
|
|
||||||
|
if (line.Length == 3)
|
||||||
|
shape.Points.Add(NewPoint(SpiroPointType.G4, line[1], line[2]));
|
||||||
|
else
|
||||||
|
throw new FormatException();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
{
|
||||||
|
if (shape == null)
|
||||||
|
shape = NewShape();
|
||||||
|
|
||||||
|
if (line.Length == 3)
|
||||||
|
shape.Points.Add(NewPoint(SpiroPointType.G2, line[1], line[2]));
|
||||||
|
else
|
||||||
|
throw new FormatException();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
{
|
||||||
|
if (shape == null)
|
||||||
|
shape = NewShape();
|
||||||
|
|
||||||
|
if (line.Length == 3)
|
||||||
|
shape.Points.Add(NewPoint(SpiroPointType.Left, line[1], line[2]));
|
||||||
|
else
|
||||||
|
throw new FormatException();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ']':
|
||||||
|
{
|
||||||
|
if (shape == null)
|
||||||
|
shape = NewShape();
|
||||||
|
|
||||||
|
if (line.Length == 3)
|
||||||
|
shape.Points.Add(NewPoint(SpiroPointType.Right, line[1], line[2]));
|
||||||
|
else
|
||||||
|
throw new FormatException();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'z':
|
||||||
|
{
|
||||||
|
if (shape == null)
|
||||||
|
shape = NewShape();
|
||||||
|
|
||||||
|
if (line.Length == 1)
|
||||||
|
shape.Points.Add(NewPoint(SpiroPointType.End, "0", "0"));
|
||||||
|
else if (line.Length == 3)
|
||||||
|
shape.Points.Add(NewPoint(SpiroPointType.End, line[1], line[2]));
|
||||||
|
else
|
||||||
|
throw new FormatException();
|
||||||
|
|
||||||
|
shapes.Add(shape);
|
||||||
|
shape = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '{':
|
||||||
|
{
|
||||||
|
if (shape == null)
|
||||||
|
shape = NewShape();
|
||||||
|
|
||||||
|
if (line.Length == 3)
|
||||||
|
shape.Points.Add(NewPoint(SpiroPointType.OpenContour, line[1], line[2]));
|
||||||
|
else
|
||||||
|
throw new FormatException();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '}':
|
||||||
|
{
|
||||||
|
if (shape == null)
|
||||||
|
shape = NewShape();
|
||||||
|
|
||||||
|
if (line.Length == 3)
|
||||||
|
shape.Points.Add(NewPoint(SpiroPointType.EndOpenContour, line[1], line[2]));
|
||||||
|
else
|
||||||
|
throw new FormatException();
|
||||||
|
|
||||||
|
shapes.Add(shape);
|
||||||
|
shape = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new FormatException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shape != null)
|
||||||
|
{
|
||||||
|
shape.IsTagged = false;
|
||||||
|
shapes.Add(shape);
|
||||||
|
shape = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return shapes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -71,6 +71,7 @@
|
||||||
<Compile Include="Path\PathBezierContext.cs" />
|
<Compile Include="Path\PathBezierContext.cs" />
|
||||||
<Compile Include="Path\PathDrawing.cs" />
|
<Compile Include="Path\PathDrawing.cs" />
|
||||||
<Compile Include="Path\PathShape.cs" />
|
<Compile Include="Path\PathShape.cs" />
|
||||||
|
<Compile Include="Plate\Plate.cs" />
|
||||||
<Compile Include="Util\Command.cs" />
|
<Compile Include="Util\Command.cs" />
|
||||||
<Compile Include="Util\ObservableObject.cs" />
|
<Compile Include="Util\ObservableObject.cs" />
|
||||||
<Page Include="MainWindow.xaml">
|
<Page Include="MainWindow.xaml">
|
||||||
|
|
Загрузка…
Ссылка в новой задаче