From 60cfbcda4edcfe2814f7404e6b778ac0042b41a2 Mon Sep 17 00:00:00 2001 From: "SND\\wo80_cp" Date: Wed, 30 May 2012 18:42:37 +0000 Subject: [PATCH] Preparing for beta 2. NO NEED TO DOWNLOAD! git-svn-id: https://triangle.svn.codeplex.com/svn@67702 0e2699bc-83d4-4a8f-98e7-55e24ab8c7a5 --- .../{Histogram.cs => AngleHistogram.cs} | 4 +- .../Controls/{ButtonDark.cs => DarkButton.cs} | 4 +- .../{CheckBoxDark.cs => DarkCheckBox.cs} | 4 +- .../{TextBoxDark.cs => DarkTextBox.cs} | 4 +- Triangle.NET/TestApp/Controls/MeshRenderer.cs | 4 +- ...Form1.Designer.cs => FormMain.Designer.cs} | 30 +- .../TestApp/{Form1.cs => FormMain.cs} | 8 +- .../TestApp/{Form1.resx => FormMain.resx} | 0 ...m2.Designer.cs => FormQuality.Designer.cs} | 6 +- .../TestApp/{Form2.cs => FormQuality.cs} | 4 +- .../TestApp/{Form2.resx => FormQuality.resx} | 0 Triangle.NET/TestApp/IO/FileProcessor.cs | 97 +++++ Triangle.NET/TestApp/IO/Formats/DatFile.cs | 69 +++ Triangle.NET/TestApp/IO/IMeshFormat.cs | 26 ++ Triangle.NET/TestApp/IO/JsonParser.cs | 408 ++++++++++++++++++ .../{TestApp.csproj => Mesh Explorer.csproj} | 59 +-- .../TestApp/Mesh Explorer.csproj.vspscc | 10 + Triangle.NET/TestApp/Program.cs | 2 +- .../TestApp/Properties/Resources.Designer.cs | 63 --- .../TestApp/Properties/Resources.resx | 117 ----- .../TestApp/Properties/Settings.Designer.cs | 26 -- .../TestApp/Properties/Settings.settings | 7 - .../{MeshDataInternal.cs => RenderData.cs} | 2 +- Triangle.NET/TestApp/Util.cs | 79 ++++ Triangle.NET/Triangle.sln | 14 +- Triangle.NET/Triangle.vssscc | 10 + Triangle.NET/Triangle/Geometry/BoundingBox.cs | 116 +++++ Triangle.NET/Triangle/Geometry/Edge.cs | 61 +++ Triangle.NET/Triangle/Geometry/ITriangle.cs | 69 +++ .../Triangle/Geometry/InputGeometry.cs | 187 ++++++++ Triangle.NET/Triangle/Geometry/Point.cs | 152 +++++++ .../Triangle/Geometry/RegionPointer.cs | 61 +++ Triangle.NET/Triangle/Triangle.csproj | 6 + Triangle.NET/Triangle/Triangle.csproj.vspscc | 10 + 34 files changed, 1427 insertions(+), 292 deletions(-) rename Triangle.NET/TestApp/Controls/{Histogram.cs => AngleHistogram.cs} (95%) rename Triangle.NET/TestApp/Controls/{ButtonDark.cs => DarkButton.cs} (96%) rename Triangle.NET/TestApp/Controls/{CheckBoxDark.cs => DarkCheckBox.cs} (96%) rename Triangle.NET/TestApp/Controls/{TextBoxDark.cs => DarkTextBox.cs} (95%) rename Triangle.NET/TestApp/{Form1.Designer.cs => FormMain.Designer.cs} (87%) rename Triangle.NET/TestApp/{Form1.cs => FormMain.cs} (94%) rename Triangle.NET/TestApp/{Form1.resx => FormMain.resx} (100%) rename Triangle.NET/TestApp/{Form2.Designer.cs => FormQuality.Designer.cs} (97%) rename Triangle.NET/TestApp/{Form2.cs => FormQuality.cs} (93%) rename Triangle.NET/TestApp/{Form2.resx => FormQuality.resx} (100%) create mode 100644 Triangle.NET/TestApp/IO/FileProcessor.cs create mode 100644 Triangle.NET/TestApp/IO/Formats/DatFile.cs create mode 100644 Triangle.NET/TestApp/IO/IMeshFormat.cs create mode 100644 Triangle.NET/TestApp/IO/JsonParser.cs rename Triangle.NET/TestApp/{TestApp.csproj => Mesh Explorer.csproj} (65%) create mode 100644 Triangle.NET/TestApp/Mesh Explorer.csproj.vspscc delete mode 100644 Triangle.NET/TestApp/Properties/Resources.Designer.cs delete mode 100644 Triangle.NET/TestApp/Properties/Resources.resx delete mode 100644 Triangle.NET/TestApp/Properties/Settings.Designer.cs delete mode 100644 Triangle.NET/TestApp/Properties/Settings.settings rename Triangle.NET/TestApp/Rendering/{MeshDataInternal.cs => RenderData.cs} (95%) create mode 100644 Triangle.NET/TestApp/Util.cs create mode 100644 Triangle.NET/Triangle.vssscc create mode 100644 Triangle.NET/Triangle/Geometry/BoundingBox.cs create mode 100644 Triangle.NET/Triangle/Geometry/Edge.cs create mode 100644 Triangle.NET/Triangle/Geometry/ITriangle.cs create mode 100644 Triangle.NET/Triangle/Geometry/InputGeometry.cs create mode 100644 Triangle.NET/Triangle/Geometry/Point.cs create mode 100644 Triangle.NET/Triangle/Geometry/RegionPointer.cs create mode 100644 Triangle.NET/Triangle/Triangle.csproj.vspscc diff --git a/Triangle.NET/TestApp/Controls/Histogram.cs b/Triangle.NET/TestApp/Controls/AngleHistogram.cs similarity index 95% rename from Triangle.NET/TestApp/Controls/Histogram.cs rename to Triangle.NET/TestApp/Controls/AngleHistogram.cs index eb65b9a..465be1e 100644 --- a/Triangle.NET/TestApp/Controls/Histogram.cs +++ b/Triangle.NET/TestApp/Controls/AngleHistogram.cs @@ -16,7 +16,7 @@ namespace TestApp.Controls /// /// TODO: Update summary. /// - public class Histogram : Control + public class AngleHistogram : Control { #region Designer @@ -56,7 +56,7 @@ namespace TestApp.Controls int[] data; int max = 0; - public Histogram() + public AngleHistogram() { this.BackColor = Color.FromArgb(76, 76, 76); InitializeComponent(); diff --git a/Triangle.NET/TestApp/Controls/ButtonDark.cs b/Triangle.NET/TestApp/Controls/DarkButton.cs similarity index 96% rename from Triangle.NET/TestApp/Controls/ButtonDark.cs rename to Triangle.NET/TestApp/Controls/DarkButton.cs index 83daa9a..153fb79 100644 --- a/Triangle.NET/TestApp/Controls/ButtonDark.cs +++ b/Triangle.NET/TestApp/Controls/DarkButton.cs @@ -10,7 +10,7 @@ namespace TestApp.Controls using System.Text; using System.Windows.Forms; - public class ButtonDark : Button + public class DarkButton : Button { #region Designer @@ -58,7 +58,7 @@ namespace TestApp.Controls } //-------------------------------------------------------------------------------- - public ButtonDark() + public DarkButton() { InitializeComponent(); } diff --git a/Triangle.NET/TestApp/Controls/CheckBoxDark.cs b/Triangle.NET/TestApp/Controls/DarkCheckBox.cs similarity index 96% rename from Triangle.NET/TestApp/Controls/CheckBoxDark.cs rename to Triangle.NET/TestApp/Controls/DarkCheckBox.cs index a7b0cfd..f177297 100644 --- a/Triangle.NET/TestApp/Controls/CheckBoxDark.cs +++ b/Triangle.NET/TestApp/Controls/DarkCheckBox.cs @@ -16,7 +16,7 @@ namespace TestApp.Controls /// /// TODO: Update summary. /// - public class CheckBoxDark : ButtonBase + public class DarkCheckBox : ButtonBase { #region Designer @@ -73,7 +73,7 @@ namespace TestApp.Controls } //-------------------------------------------------------------------------------- - public CheckBoxDark() + public DarkCheckBox() { this.BackColor = Color.FromArgb(76, 76, 76); InitializeComponent(); diff --git a/Triangle.NET/TestApp/Controls/TextBoxDark.cs b/Triangle.NET/TestApp/Controls/DarkTextBox.cs similarity index 95% rename from Triangle.NET/TestApp/Controls/TextBoxDark.cs rename to Triangle.NET/TestApp/Controls/DarkTextBox.cs index cdc53d7..b0f7ff5 100644 --- a/Triangle.NET/TestApp/Controls/TextBoxDark.cs +++ b/Triangle.NET/TestApp/Controls/DarkTextBox.cs @@ -13,7 +13,7 @@ namespace TestApp.Controls using System.Drawing.Drawing2D; using System.Windows.Forms; - public class TextBoxDark : Control + public class DarkTextBox : Control { #region Designer @@ -73,7 +73,7 @@ namespace TestApp.Controls TextBox textBox; - public TextBoxDark() + public DarkTextBox() { InitializeComponent(); diff --git a/Triangle.NET/TestApp/Controls/MeshRenderer.cs b/Triangle.NET/TestApp/Controls/MeshRenderer.cs index a6b23c7..632f318 100644 --- a/Triangle.NET/TestApp/Controls/MeshRenderer.cs +++ b/Triangle.NET/TestApp/Controls/MeshRenderer.cs @@ -30,7 +30,7 @@ namespace TestApp Pen lines = new Pen(Color.FromArgb(30, 30, 30)); Zoom zoom; - MeshDataInternal data; + RenderData data; bool initialized = false; public long RenderTime { get; private set; } @@ -43,7 +43,7 @@ namespace TestApp zoom = new Zoom(); context = new BufferedGraphicsContext(); - data = new MeshDataInternal(); + data = new RenderData(); } public void SetData(MeshData meshdata, bool input) diff --git a/Triangle.NET/TestApp/Form1.Designer.cs b/Triangle.NET/TestApp/FormMain.Designer.cs similarity index 87% rename from Triangle.NET/TestApp/Form1.Designer.cs rename to Triangle.NET/TestApp/FormMain.Designer.cs index a9b1e83..189484a 100644 --- a/Triangle.NET/TestApp/Form1.Designer.cs +++ b/Triangle.NET/TestApp/FormMain.Designer.cs @@ -1,6 +1,6 @@ namespace TestApp { - partial class Form1 + partial class FormMain { /// /// Required designer variable. @@ -28,13 +28,13 @@ /// private void InitializeComponent() { - this.btnStatistic = new TestApp.Controls.ButtonDark(); - this.tbNumPoints = new TestApp.Controls.TextBoxDark(); - this.cbConvex = new TestApp.Controls.CheckBoxDark(); - this.cbQuality = new TestApp.Controls.CheckBoxDark(); - this.btnRun = new TestApp.Controls.ButtonDark(); - this.btnOpen = new TestApp.Controls.ButtonDark(); - this.btnRandPts = new TestApp.Controls.ButtonDark(); + this.btnStatistic = new TestApp.Controls.DarkButton(); + this.tbNumPoints = new TestApp.Controls.DarkTextBox(); + this.cbConvex = new TestApp.Controls.DarkCheckBox(); + this.cbQuality = new TestApp.Controls.DarkCheckBox(); + this.btnRun = new TestApp.Controls.DarkButton(); + this.btnOpen = new TestApp.Controls.DarkButton(); + this.btnRandPts = new TestApp.Controls.DarkButton(); this.meshRenderer1 = new TestApp.MeshRenderer(); this.lbTime = new System.Windows.Forms.Label(); this.SuspendLayout(); @@ -162,13 +162,13 @@ #endregion private MeshRenderer meshRenderer1; - private Controls.ButtonDark btnRandPts; - private Controls.ButtonDark btnOpen; - private Controls.ButtonDark btnRun; - private Controls.CheckBoxDark cbQuality; - private Controls.TextBoxDark tbNumPoints; - private Controls.ButtonDark btnStatistic; - private Controls.CheckBoxDark cbConvex; + private Controls.DarkButton btnRandPts; + private Controls.DarkButton btnOpen; + private Controls.DarkButton btnRun; + private Controls.DarkCheckBox cbQuality; + private Controls.DarkTextBox tbNumPoints; + private Controls.DarkButton btnStatistic; + private Controls.DarkCheckBox cbConvex; private System.Windows.Forms.Label lbTime; } diff --git a/Triangle.NET/TestApp/Form1.cs b/Triangle.NET/TestApp/FormMain.cs similarity index 94% rename from Triangle.NET/TestApp/Form1.cs rename to Triangle.NET/TestApp/FormMain.cs index f61139c..0911c7f 100644 --- a/Triangle.NET/TestApp/Form1.cs +++ b/Triangle.NET/TestApp/FormMain.cs @@ -11,7 +11,7 @@ using TestApp.Rendering; namespace TestApp { - public partial class Form1 : Form + public partial class FormMain : Form { Random rand = new Random(DateTime.Now.Millisecond); @@ -26,9 +26,9 @@ namespace TestApp string dlgDirectory = Application.StartupPath; Statistic statistic = new Statistic(); - Form2 formStats; + FormQuality formStats; - public Form1() + public FormMain() { InitializeComponent(); } @@ -246,7 +246,7 @@ namespace TestApp { if (formStats == null) { - formStats = new Form2(); + formStats = new FormQuality(); } if (!formStats.Visible) diff --git a/Triangle.NET/TestApp/Form1.resx b/Triangle.NET/TestApp/FormMain.resx similarity index 100% rename from Triangle.NET/TestApp/Form1.resx rename to Triangle.NET/TestApp/FormMain.resx diff --git a/Triangle.NET/TestApp/Form2.Designer.cs b/Triangle.NET/TestApp/FormQuality.Designer.cs similarity index 97% rename from Triangle.NET/TestApp/Form2.Designer.cs rename to Triangle.NET/TestApp/FormQuality.Designer.cs index ea4c44e..38c7a6b 100644 --- a/Triangle.NET/TestApp/Form2.Designer.cs +++ b/Triangle.NET/TestApp/FormQuality.Designer.cs @@ -1,6 +1,6 @@ namespace TestApp { - partial class Form2 + partial class FormQuality { /// /// Required designer variable. @@ -60,7 +60,7 @@ this.lbRatioMax = new System.Windows.Forms.Label(); this.lbAngleMin = new System.Windows.Forms.Label(); this.lbAngleMax = new System.Windows.Forms.Label(); - this.histogram1 = new TestApp.Controls.Histogram(); + this.histogram1 = new TestApp.Controls.AngleHistogram(); this.SuspendLayout(); // // label1 @@ -484,6 +484,6 @@ private System.Windows.Forms.Label lbRatioMax; private System.Windows.Forms.Label lbAngleMin; private System.Windows.Forms.Label lbAngleMax; - private Controls.Histogram histogram1; + private Controls.AngleHistogram histogram1; } } \ No newline at end of file diff --git a/Triangle.NET/TestApp/Form2.cs b/Triangle.NET/TestApp/FormQuality.cs similarity index 93% rename from Triangle.NET/TestApp/Form2.cs rename to Triangle.NET/TestApp/FormQuality.cs index 2c3c230..c5eaa1a 100644 --- a/Triangle.NET/TestApp/Form2.cs +++ b/Triangle.NET/TestApp/FormQuality.cs @@ -11,11 +11,11 @@ using System.Globalization; namespace TestApp { - public partial class Form2 : Form + public partial class FormQuality : Form { static NumberFormatInfo nfi = CultureInfo.InvariantCulture.NumberFormat; - public Form2() + public FormQuality() { InitializeComponent(); diff --git a/Triangle.NET/TestApp/Form2.resx b/Triangle.NET/TestApp/FormQuality.resx similarity index 100% rename from Triangle.NET/TestApp/Form2.resx rename to Triangle.NET/TestApp/FormQuality.resx diff --git a/Triangle.NET/TestApp/IO/FileProcessor.cs b/Triangle.NET/TestApp/IO/FileProcessor.cs new file mode 100644 index 0000000..1671bbe --- /dev/null +++ b/Triangle.NET/TestApp/IO/FileProcessor.cs @@ -0,0 +1,97 @@ +// ----------------------------------------------------------------------- +// +// TODO: Update copyright text. +// +// ----------------------------------------------------------------------- + +namespace MeshExplorer.IO +{ + using System; + using System.Collections.Generic; + using System.IO; + using MeshExplorer.IO.Formats; + using TriangleNet.IO; + using TriangleNet.Geometry; + using TriangleNet; + + /// + /// Provides static methods to read and write mesh files. + /// + public static class FileProcessor + { + static Dictionary container = new Dictionary(); + + public static InputGeometry Open(string path) + { + string ext = Path.GetExtension(path); + + IMeshFormat provider; + + if (container.ContainsKey(ext)) + { + provider = container[ext]; + } + else + { + provider = CreateInstance(ext); + } + + return provider.Read(path); + } + + public static void Save(string path, Mesh data) + { + string ext = Path.GetExtension(path); + + IMeshFormat provider; + + if (container.ContainsKey(ext)) + { + provider = container[ext]; + } + else + { + provider = CreateInstance(ext); + } + + provider.Write(path, data); + } + + private static IMeshFormat CreateInstance(string ext) + { + // TODO: automate by using IMeshFormat's Extensions property. + + IMeshFormat provider = null; + + if (ext == ".node" || ext == ".poly") + { + //provider = new TriangleFile(); + } + else if (ext == ".json") + { + //provider = new JsonFile(); + } + else if (ext == ".dat") + { + provider = new DatFile(); + } + else if (ext == ".mphtxt") + { + //provider = new COMSOL(); + } + else if (ext == ".vtk") + { + //provider = new VtkFile(); + } + + if (provider == null) + { + throw new NotImplementedException("File format not implemented."); + } + + container.Add(ext, provider); + + return provider; + } + } +} diff --git a/Triangle.NET/TestApp/IO/Formats/DatFile.cs b/Triangle.NET/TestApp/IO/Formats/DatFile.cs new file mode 100644 index 0000000..813686e --- /dev/null +++ b/Triangle.NET/TestApp/IO/Formats/DatFile.cs @@ -0,0 +1,69 @@ +// ----------------------------------------------------------------------- +// +// TODO: Update copyright text. +// +// ----------------------------------------------------------------------- + +namespace MeshExplorer.IO.Formats +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.IO; + using System.Text; + using TriangleNet; + using TriangleNet.Geometry; + using TriangleNet.IO; + + /// + /// TODO: Update summary. + /// + public class DatFile : MeshExplorer.IO.IMeshFormat + { + /// + /// Gets the supported file extensions. + /// + public string[] Extensions + { + get { return new string[] { ".dat" }; } + } + + public InputGeometry Read(string filename) + { + InputGeometry data = new InputGeometry(); + + string line; + string[] split; + + using (TextReader reader = new StreamReader(filename)) + { + while ((line = reader.ReadLine()) != null) + { + split = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); + + if (split.Length == 2) + { + data.AddPoint( + double.Parse(split[0], Util.Nfi), + double.Parse(split[1], Util.Nfi)); + } + } + } + + int n = data.Count; + + for (int i = 0; i < n; i++) + { + data.AddSegment(i, (i + 1) % n); + + } + + return data; + } + + public void Write(string filename, Mesh data) + { + throw new NotImplementedException(); + } + } +} diff --git a/Triangle.NET/TestApp/IO/IMeshFormat.cs b/Triangle.NET/TestApp/IO/IMeshFormat.cs new file mode 100644 index 0000000..e598b96 --- /dev/null +++ b/Triangle.NET/TestApp/IO/IMeshFormat.cs @@ -0,0 +1,26 @@ +// ----------------------------------------------------------------------- +// +// TODO: Update copyright text. +// +// ----------------------------------------------------------------------- + +namespace MeshExplorer.IO +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using TriangleNet; + using TriangleNet.Geometry; + + /// + /// Defines an interface for mesh file formats. + /// + public interface IMeshFormat + { + string[] Extensions { get; } + + InputGeometry Read(string file); + void Write(string file, Mesh data); + } +} diff --git a/Triangle.NET/TestApp/IO/JsonParser.cs b/Triangle.NET/TestApp/IO/JsonParser.cs new file mode 100644 index 0000000..ced3436 --- /dev/null +++ b/Triangle.NET/TestApp/IO/JsonParser.cs @@ -0,0 +1,408 @@ +// ----------------------------------------------------------------------- +// +// fastJSON - http://fastjson.codeplex.com/ +// +// ----------------------------------------------------------------------- + +namespace MeshExplorer.IO +{ + using System; + using System.Collections; + using System.Collections.Generic; + using System.Globalization; + using System.Text; + + /// + /// This class encodes and decodes JSON strings. + /// Spec. details, see http://www.json.org/ + /// + /// JSON uses Arrays and Objects. These correspond here to the datatypes ArrayList and Hashtable. + /// All numbers are parsed to doubles. + /// + internal class JsonParser + { + enum Token + { + None = -1, // Used to denote no Lookahead available + Curly_Open, + Curly_Close, + Squared_Open, + Squared_Close, + Colon, + Comma, + String, + Number, + True, + False, + Null + } + + readonly char[] json; + readonly StringBuilder s = new StringBuilder(); + Token lookAheadToken = Token.None; + int index; + + public JsonParser(string json) + { + this.json = json.ToCharArray(); + } + + public object Decode() + { + return ParseValue(); + } + + private Dictionary ParseObject() + { + Dictionary table = new Dictionary(); + + ConsumeToken(); // { + + while (true) + { + switch (LookAhead()) + { + + case Token.Comma: + ConsumeToken(); + break; + + case Token.Curly_Close: + ConsumeToken(); + return table; + + default: + { + + // name + string name = ParseString(); + + // : + if (NextToken() != Token.Colon) + { + throw new Exception("Expected colon at index " + index); + } + + // value + object value = ParseValue(); + + table[name] = value; + } + break; + } + } + } + + private ArrayList ParseArray() + { + ArrayList array = new ArrayList(); + + ConsumeToken(); // [ + + while (true) + { + switch (LookAhead()) + { + + case Token.Comma: + ConsumeToken(); + break; + + case Token.Squared_Close: + ConsumeToken(); + return array; + + default: + { + array.Add(ParseValue()); + } + break; + } + } + } + + private object ParseValue() + { + switch (LookAhead()) + { + case Token.Number: + return ParseNumber(); + + case Token.String: + return ParseString(); + + case Token.Curly_Open: + return ParseObject(); + + case Token.Squared_Open: + return ParseArray(); + + case Token.True: + ConsumeToken(); + return true; + + case Token.False: + ConsumeToken(); + return false; + + case Token.Null: + ConsumeToken(); + return null; + } + + throw new Exception("Unrecognized token at index" + index); + } + + private string ParseString() + { + ConsumeToken(); // " + + s.Length = 0; + + int runIndex = -1; + + while (index < json.Length) + { + var c = json[index++]; + + if (c == '"') + { + if (runIndex != -1) + { + if (s.Length == 0) + return new string(json, runIndex, index - runIndex - 1); + + s.Append(json, runIndex, index - runIndex - 1); + } + return s.ToString(); + } + + if (c != '\\') + { + if (runIndex == -1) + runIndex = index - 1; + + continue; + } + + if (index == json.Length) break; + + if (runIndex != -1) + { + s.Append(json, runIndex, index - runIndex - 1); + runIndex = -1; + } + + switch (json[index++]) + { + case '"': + s.Append('"'); + break; + + case '\\': + s.Append('\\'); + break; + + case '/': + s.Append('/'); + break; + + case 'b': + s.Append('\b'); + break; + + case 'f': + s.Append('\f'); + break; + + case 'n': + s.Append('\n'); + break; + + case 'r': + s.Append('\r'); + break; + + case 't': + s.Append('\t'); + break; + + case 'u': + { + int remainingLength = json.Length - index; + if (remainingLength < 4) break; + + // parse the 32 bit hex into an integer codepoint + uint codePoint = ParseUnicode(json[index], json[index + 1], json[index + 2], json[index + 3]); + s.Append((char)codePoint); + + // skip 4 chars + index += 4; + } + break; + } + } + + throw new Exception("Unexpectedly reached end of string"); + } + + private uint ParseSingleChar(char c1, uint multipliyer) + { + uint p1 = 0; + if (c1 >= '0' && c1 <= '9') + p1 = (uint)(c1 - '0') * multipliyer; + else if (c1 >= 'A' && c1 <= 'F') + p1 = (uint)((c1 - 'A') + 10) * multipliyer; + else if (c1 >= 'a' && c1 <= 'f') + p1 = (uint)((c1 - 'a') + 10) * multipliyer; + return p1; + } + + private uint ParseUnicode(char c1, char c2, char c3, char c4) + { + uint p1 = ParseSingleChar(c1, 0x1000); + uint p2 = ParseSingleChar(c2, 0x100); + uint p3 = ParseSingleChar(c3, 0x10); + uint p4 = ParseSingleChar(c4, 1); + + return p1 + p2 + p3 + p4; + } + + private string ParseNumber() + { + ConsumeToken(); + + // Need to start back one place because the first digit is also a token and would have been consumed + var startIndex = index - 1; + + do + { + var c = json[index]; + + if ((c >= '0' && c <= '9') || c == '.' || c == '-' || c == '+' || c == 'e' || c == 'E') + { + if (++index == json.Length) throw new Exception("Unexpected end of string whilst parsing number"); + continue; + } + + break; + } while (true); + + return new string(json, startIndex, index - startIndex); + } + + private Token LookAhead() + { + if (lookAheadToken != Token.None) return lookAheadToken; + + return lookAheadToken = NextTokenCore(); + } + + private void ConsumeToken() + { + lookAheadToken = Token.None; + } + + private Token NextToken() + { + var result = lookAheadToken != Token.None ? lookAheadToken : NextTokenCore(); + + lookAheadToken = Token.None; + + return result; + } + + private Token NextTokenCore() + { + char c; + + // Skip past whitespace + do + { + c = json[index]; + + if (c > ' ') break; + if (c != ' ' && c != '\t' && c != '\n' && c != '\r') break; + + } while (++index < json.Length); + + if (index == json.Length) + { + throw new Exception("Reached end of string unexpectedly"); + } + + c = json[index]; + + index++; + + //if (c >= '0' && c <= '9') + // return Token.Number; + + switch (c) + { + case '{': + return Token.Curly_Open; + + case '}': + return Token.Curly_Close; + + case '[': + return Token.Squared_Open; + + case ']': + return Token.Squared_Close; + + case ',': + return Token.Comma; + + case '"': + return Token.String; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case '-': case '+': case '.': + return Token.Number; + + case ':': + return Token.Colon; + + case 'f': + if (json.Length - index >= 4 && + json[index + 0] == 'a' && + json[index + 1] == 'l' && + json[index + 2] == 's' && + json[index + 3] == 'e') + { + index += 4; + return Token.False; + } + break; + + case 't': + if (json.Length - index >= 3 && + json[index + 0] == 'r' && + json[index + 1] == 'u' && + json[index + 2] == 'e') + { + index += 3; + return Token.True; + } + break; + + case 'n': + if (json.Length - index >= 3 && + json[index + 0] == 'u' && + json[index + 1] == 'l' && + json[index + 2] == 'l') + { + index += 3; + return Token.Null; + } + break; + + } + + throw new Exception("Could not find token at index " + --index); + } + } +} diff --git a/Triangle.NET/TestApp/TestApp.csproj b/Triangle.NET/TestApp/Mesh Explorer.csproj similarity index 65% rename from Triangle.NET/TestApp/TestApp.csproj rename to Triangle.NET/TestApp/Mesh Explorer.csproj index 624c995..4b52f34 100644 --- a/Triangle.NET/TestApp/TestApp.csproj +++ b/Triangle.NET/TestApp/Mesh Explorer.csproj @@ -8,8 +8,8 @@ {336AAF8A-5316-4303-9E73-5E38BD0B28AF} WinExe Properties - TestApp - TestApp + MeshExplorer + Mesh Explorer v4.0 Client 512 @@ -46,64 +46,50 @@ - + Component - + Component - + Component - + Component - + Form - - Form1.cs + + FormMain.cs Component - + Form - - Form2.cs + + FormQuality.cs + + + + - + - - Form1.cs + + + FormMain.cs - - Form2.cs + + FormQuality.cs - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - True - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - @@ -111,6 +97,7 @@ Triangle + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/Triangle.NET/TestApp/Properties/Settings.Designer.cs b/Triangle.NET/TestApp/Properties/Settings.Designer.cs deleted file mode 100644 index aff0249..0000000 --- a/Triangle.NET/TestApp/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.261 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace TestApp.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - } -} diff --git a/Triangle.NET/TestApp/Properties/Settings.settings b/Triangle.NET/TestApp/Properties/Settings.settings deleted file mode 100644 index abf36c5..0000000 --- a/Triangle.NET/TestApp/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/Triangle.NET/TestApp/Rendering/MeshDataInternal.cs b/Triangle.NET/TestApp/Rendering/RenderData.cs similarity index 95% rename from Triangle.NET/TestApp/Rendering/MeshDataInternal.cs rename to Triangle.NET/TestApp/Rendering/RenderData.cs index b4a53e1..c9ed18c 100644 --- a/Triangle.NET/TestApp/Rendering/MeshDataInternal.cs +++ b/Triangle.NET/TestApp/Rendering/RenderData.cs @@ -14,7 +14,7 @@ namespace TestApp.Rendering using System.Drawing; using TriangleNet; - public class MeshDataInternal + public class RenderData { public PointF[] Points; public int[][] Triangles; diff --git a/Triangle.NET/TestApp/Util.cs b/Triangle.NET/TestApp/Util.cs new file mode 100644 index 0000000..d54f069 --- /dev/null +++ b/Triangle.NET/TestApp/Util.cs @@ -0,0 +1,79 @@ +// ----------------------------------------------------------------------- +// +// TODO: Update copyright text. +// +// ----------------------------------------------------------------------- + +namespace MeshExplorer +{ + using System; + using System.Drawing; + using System.Globalization; + using System.IO; + + /// + /// Utility class. + /// + public static class Util + { + internal static NumberFormatInfo Nfi = CultureInfo.InvariantCulture.NumberFormat; + + internal static Random Random = new Random(DateTime.Now.Millisecond); + + internal static bool TryReadLine(StreamReader reader, out string[] token) + { + token = null; + + if (reader.EndOfStream) + { + return false; + } + + string line = reader.ReadLine().Trim(); + + while (String.IsNullOrWhiteSpace(line) || line.StartsWith("#")) + { + if (reader.EndOfStream) + { + return false; + } + + line = reader.ReadLine().Trim(); + } + + token = line.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); + + return true; + } + + internal static string DoubleToString(double d) + { + double max = 999999; + double min = 0.00001; + + string spec = "0.00000"; + + if (d < min || d > max) + { + spec = "0.###e-000"; + } + + return d.ToString(spec, Util.Nfi); + } + + internal static string AngleToString(double d) + { + double max = 180 - 10E-14; + double min = 10E-14; + + string spec = "0.00000"; + + if (d < min || d > max) + { + spec = "0.#"; + } + + return d.ToString(spec, Util.Nfi); + } + } +} diff --git a/Triangle.NET/Triangle.sln b/Triangle.NET/Triangle.sln index 804e1ab..5267097 100644 --- a/Triangle.NET/Triangle.sln +++ b/Triangle.NET/Triangle.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Triangle", "Triangle\Triangle.csproj", "{F7907A0A-B75F-400B-9E78-BFAD00DB4D6B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApp", "TestApp\TestApp.csproj", "{336AAF8A-5316-4303-9E73-5E38BD0B28AF}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mesh Explorer", "TestApp\Mesh Explorer.csproj", "{336AAF8A-5316-4303-9E73-5E38BD0B28AF}" EndProject Global GlobalSection(TeamFoundationVersionControl) = preSolution @@ -11,12 +11,12 @@ Global SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C} SccTeamFoundationServer = https://tfs.codeplex.com/tfs/tfs06 SccLocalPath0 = . - SccProjectUniqueName1 = TestApp\\TestApp.csproj - SccProjectName1 = TestApp - SccLocalPath1 = TestApp - SccProjectUniqueName2 = Triangle\\Triangle.csproj - SccProjectName2 = Triangle - SccLocalPath2 = Triangle + SccProjectUniqueName1 = Triangle\\Triangle.csproj + SccProjectName1 = Triangle + SccLocalPath1 = Triangle + SccProjectUniqueName2 = TestApp\\Mesh\u0020Explorer.csproj + SccProjectName2 = TestApp + SccLocalPath2 = TestApp EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/Triangle.NET/Triangle.vssscc b/Triangle.NET/Triangle.vssscc new file mode 100644 index 0000000..794f014 --- /dev/null +++ b/Triangle.NET/Triangle.vssscc @@ -0,0 +1,10 @@ +"" +{ +"FILE_VERSION" = "9237" +"ENLISTMENT_CHOICE" = "NEVER" +"PROJECT_FILE_RELATIVE_PATH" = "" +"NUMBER_OF_EXCLUDED_FILES" = "0" +"ORIGINAL_PROJECT_FILE_PATH" = "" +"NUMBER_OF_NESTED_PROJECTS" = "0" +"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT" +} diff --git a/Triangle.NET/Triangle/Geometry/BoundingBox.cs b/Triangle.NET/Triangle/Geometry/BoundingBox.cs new file mode 100644 index 0000000..4d8cb0a --- /dev/null +++ b/Triangle.NET/Triangle/Geometry/BoundingBox.cs @@ -0,0 +1,116 @@ +// ----------------------------------------------------------------------- +// +// TODO: Update copyright text. +// +// ----------------------------------------------------------------------- + +namespace TriangleNet.Geometry +{ + using System; + + /// + /// A simple bounding box class. + /// + public class BoundingBox + { + double xmin, ymin, xmax, ymax; + + /// + /// Initializes a new instance of the class. + /// + public BoundingBox() + { + xmin = double.MaxValue; + ymin = double.MaxValue; + xmax = -double.MaxValue; + ymax = -double.MaxValue; + } + + /// + /// Initializes a new instance of the class + /// with predefined bounds. + /// + /// Minimum x value. + /// Minimum y value. + /// Maximum x value. + /// Maximum y value. + public BoundingBox(double xmin, double ymin, double xmax, double ymax) + { + this.xmin = xmin; + this.ymin = ymin; + this.xmax = xmax; + this.ymax = ymax; + } + + /// + /// Gets the minimum x value (left boundary). + /// + public double Xmin + { + get { return xmin; } + } + + /// + /// Gets the minimum y value (bottom boundary). + /// + public double Ymin + { + get { return ymin; } + } + + /// + /// Gets the maximum x value (right boundary). + /// + public double Xmax + { + get { return xmax; } + } + + /// + /// Gets the maximum y value (top boundary). + /// + public double Ymax + { + get { return ymax; } + } + + /// + /// Gets the width of the bounding box. + /// + public double Width + { + get { return xmax - xmin; } + } + + /// + /// Gets the height of the bounding box. + /// + public double Height + { + get { return ymax - ymin; } + } + + /// + /// Update bounds. + /// + /// X coordinate. + /// Y coordinate. + public void Update(double x, double y) + { + xmin = Math.Min(xmin, x); + ymin = Math.Min(ymin, y); + xmax = Math.Max(xmax, x); + ymax = Math.Max(ymax, y); + } + + /// + /// Check if given point is inside bounding box. + /// + /// Point to check. + /// Return true, if bounding box contains given point. + public bool Contains(Point pt) + { + return ((pt.x >= xmin) && (pt.x <= xmax) && (pt.y >= ymin) && (pt.y <= ymax)); + } + } +} diff --git a/Triangle.NET/Triangle/Geometry/Edge.cs b/Triangle.NET/Triangle/Geometry/Edge.cs new file mode 100644 index 0000000..c48ffee --- /dev/null +++ b/Triangle.NET/Triangle/Geometry/Edge.cs @@ -0,0 +1,61 @@ +// ----------------------------------------------------------------------- +// +// TODO: Update copyright text. +// +// ----------------------------------------------------------------------- + +namespace TriangleNet.Geometry +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using TriangleNet.Data; + + /// + /// Represents a straight line segment in 2D space. + /// + public class Edge + { + /// + /// Gets the first endpoints index. + /// + public int P0 + { + get; private set; + } + + /// + /// Gets the second endpoints index. + /// + public int P1 + { + get; private set; + } + + /// + /// Gets the segments boundary mark. + /// + public int Boundary + { + get; private set; + } + + /// + /// Initializes a new instance of the class. + /// + public Edge(int p0, int p1) + : this(p0, p1, 0) + { } + + /// + /// Initializes a new instance of the class. + /// + public Edge(int p0, int p1, int boundary) + { + this.P0 = p0; + this.P1 = p1; + this.Boundary = boundary; + } + } +} diff --git a/Triangle.NET/Triangle/Geometry/ITriangle.cs b/Triangle.NET/Triangle/Geometry/ITriangle.cs new file mode 100644 index 0000000..2b70fdb --- /dev/null +++ b/Triangle.NET/Triangle/Geometry/ITriangle.cs @@ -0,0 +1,69 @@ +// ----------------------------------------------------------------------- +// +// TODO: Update copyright text. +// +// ----------------------------------------------------------------------- + +namespace TriangleNet.Geometry +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + + /// + /// Triangle interface. + /// + public interface ITriangle + { + /// + /// The triangle id. + /// + int ID { get; } + + /// + /// First vertex id of the triangle. + /// + int P0 { get; } + /// + /// Second vertex id of the triangle. + /// + int P1 { get; } + /// + /// Third vertex id of the triangle. + /// + int P2 { get; } + /// + /// Gets the specified vertex id. + /// + int this[int index] { get; } + + /// + /// True if the triangle implementation contains neighbor information. + /// + bool SupportsNeighbors { get; } + + /// + /// First neighbor. + /// + int N0 { get; } + /// + /// Second neighbor. + /// + int N1 { get; } + /// + /// Third neighbor. + /// + int N2 { get; } + + /// + /// Triangle area constraint. + /// + double Area { get; } + + /// + /// Triangle atributes. + /// + double[] Attributes { get; } + } +} diff --git a/Triangle.NET/Triangle/Geometry/InputGeometry.cs b/Triangle.NET/Triangle/Geometry/InputGeometry.cs new file mode 100644 index 0000000..a503376 --- /dev/null +++ b/Triangle.NET/Triangle/Geometry/InputGeometry.cs @@ -0,0 +1,187 @@ +// ----------------------------------------------------------------------- +// +// TODO: Update copyright text. +// +// ----------------------------------------------------------------------- + +namespace TriangleNet.Geometry +{ + using System; + using System.Collections.Generic; + using TriangleNet.Data; + + /// + /// The input geometry which will be triangulated. May represent a + /// pointset or a planar straight line graph. + /// + public class InputGeometry + { + internal List points; + internal List segments; + internal List holes; + internal List regions; + + BoundingBox bounds; + + /// + /// Initializes a new instance of the class. + /// + public InputGeometry() + : this(3) + { + } + + /// + /// Initializes a new instance of the class. + /// The point list will be initialized with a given capacity. + /// + /// Point list capacity. + public InputGeometry(int capacity) + { + points = new List(capacity); + segments = new List(); + holes = new List(); + regions = new List(); + + bounds = new BoundingBox(); + } + + /// + /// Gets the bounding box of the input geometry. + /// + public BoundingBox Bounds + { + get { return bounds; } + } + + /// + /// Gets a value indicating whether the geometry should be treated as a PLSG. + /// + public bool HasSegments + { + get { return segments.Count > 0; } + } + + /// + /// Gets the number of points. + /// + public int Count + { + get { return points.Count; } + } + + /// + /// Gets the list of input points. + /// + public IEnumerable Points + { + get { return null; } + } + + /// + /// Gets the list of input segments. + /// + public IEnumerable Segments + { + get { return segments; } + } + + /// + /// Gets the list of input holes. + /// + public IEnumerable Holes + { + get { return holes; } + } + + /// + /// Gets the list of input holes. + /// + public IEnumerable Regions + { + get { return regions; } + } + + /// + /// Clear input geometry. + /// + public void Clear() + { + points.Clear(); + segments.Clear(); + holes.Clear(); + regions.Clear(); + } + + /// + /// Adds a point to the geometry. + /// + /// X coordinate. + /// Y coordinate. + public void AddPoint(double x, double y) + { + AddPoint(x, y, 0); + } + + /// + /// Adds a point to the geometry. + /// + /// X coordinate. + /// Y coordinate. + /// Boundary marker. + public void AddPoint(double x, double y, int boundary) + { + //points.Add(new Vertex(x, y, boundary)); + + bounds.Update(x, y); + } + + /// + /// Adds a hole location to the geometry. + /// + /// X coordinate of the hole. + /// Y coordinate of the hole. + public void AddHole(double x, double y) + { + holes.Add(new Point(x, y)); + } + + /// + /// Adds a hole location to the geometry. + /// + /// X coordinate of the hole. + /// Y coordinate of the hole. + /// The regions area constraint. + /// Region attribute. + public void AddRegion(double x, double y, double area, double attribute) + { + regions.Add(new RegionPointer(x, y, area, attribute)); + } + + /// + /// Adds a segment to the geometry. + /// + /// First endpoint. + /// Second endpoint. + public void AddSegment(int p0, int p1) + { + AddSegment(p0, p1, 0); + } + + /// + /// Adds a segment to the geometry. + /// + /// First endpoint. + /// Second endpoint. + /// Segment marker. + public void AddSegment(int p0, int p1, int boundary) + { + if (p0 == p1) + { + throw new NotSupportedException("Invalid endpoints."); + } + + segments.Add(new Edge(p0, p1, boundary)); + } + } +} diff --git a/Triangle.NET/Triangle/Geometry/Point.cs b/Triangle.NET/Triangle/Geometry/Point.cs new file mode 100644 index 0000000..9ff76f0 --- /dev/null +++ b/Triangle.NET/Triangle/Geometry/Point.cs @@ -0,0 +1,152 @@ +// ----------------------------------------------------------------------- +// +// Original Triangle code by Jonathan Richard Shewchuk, http://www.cs.cmu.edu/~quake/triangle.html +// Triangle.NET code by Christian Woltering, http://home.edo.tu-dortmund.de/~woltering/triangle/ +// +// ----------------------------------------------------------------------- + +namespace TriangleNet.Geometry +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + + /// + /// Represents a 2D point. + /// + public class Point : IComparable, IEquatable + { + internal double x; + internal double y; + internal int mark; + internal double[] attributes; + + public Point() + : this(0, 0, 0) + { + } + + public Point(double x, double y) + : this(x, y, 0) + { + } + + public Point(double x, double y, int mark) + { + this.x = x; + this.y = y; + this.mark = mark; + } + + #region Public properties + + /// + /// Gets the vertex x coordinate. + /// + public double X + { + get { return this.x; } + } + + /// + /// Gets the vertex y coordinate. + /// + public double Y + { + get { return this.y; } + } + + /// + /// Gets the vertex boundary mark. + /// + public int Boundary + { + get { return this.mark; } + } + + /// + /// Gets the vertex attributes (may be null). + /// + public double[] Attributes + { + get { return this.attributes; } + } + + #endregion + + #region Operator overloading / overriding Equals + + // Compare "Guidelines for Overriding Equals() and Operator ==" + // http://msdn.microsoft.com/en-us/library/ms173147.aspx + + public static bool operator ==(Point a, Point b) + { + // If both are null, or both are same instance, return true. + if (Object.ReferenceEquals(a, b)) + { + return true; + } + + // If one is null, but not both, return false. + if (((object)a == null) || ((object)b == null)) + { + return false; + } + + return a.Equals(b); + } + + public static bool operator !=(Point a, Point b) + { + return !(a == b); + } + + public override bool Equals(object obj) + { + // If parameter is null return false. + if (obj == null) + { + return false; + } + + Point p = obj as Point; + + if ((object)p == null) + { + return false; + } + + return (x == p.x) && (y == p.y); + } + + public bool Equals(Point p) + { + // If vertex is null return false. + if ((object)p == null) + { + return false; + } + + // Return true if the fields match: + return (x == p.x) && (y == p.y); + } + + #endregion + + public int CompareTo(Point other) + { + if (x == other.x && y == other.y) + { + return 0; + } + + return (x < other.x || (x == other.x && y < other.y)) ? -1 : 1; + } + + public override string ToString() + { + return String.Format("[{0},{1}]", x, y); + } + } +} diff --git a/Triangle.NET/Triangle/Geometry/RegionPointer.cs b/Triangle.NET/Triangle/Geometry/RegionPointer.cs new file mode 100644 index 0000000..aae795b --- /dev/null +++ b/Triangle.NET/Triangle/Geometry/RegionPointer.cs @@ -0,0 +1,61 @@ +// ----------------------------------------------------------------------- +// +// Original Triangle code by Jonathan Richard Shewchuk, http://www.cs.cmu.edu/~quake/triangle.html +// Triangle.NET code by Christian Woltering, http://home.edo.tu-dortmund.de/~woltering/triangle/ +// +// ----------------------------------------------------------------------- + +namespace TriangleNet.Geometry +{ + using System; + using System.Collections.Generic; + + /// + /// Pointer to a region in the mesh geometry. A region is a well-defined + /// subset of the geomerty (enclosed by subsegments). + /// + public class RegionPointer + { + internal Point point; + internal double area; + internal double attribute; + + /// + /// Initializes a new instance of the class. + /// + /// X coordinate of the region. + /// Y coordinate of the region. + /// Area constraint. + /// Region attribute. + public RegionPointer(double x, double y, double area, double attribute) + { + this.point = new Point(x, y); + this.area = area; + this.attribute = attribute; + } + + /// + /// Gets the location of the region. + /// + internal Point Point + { + get { return point; } + } + + /// + /// Gets the area constraint. + /// + internal double Area + { + get { return area; } + } + + /// + /// Gets the region attribute. + /// + internal double Attribute + { + get { return attribute; } + } + } +} diff --git a/Triangle.NET/Triangle/Triangle.csproj b/Triangle.NET/Triangle/Triangle.csproj index 64c436b..07e5998 100644 --- a/Triangle.NET/Triangle/Triangle.csproj +++ b/Triangle.NET/Triangle/Triangle.csproj @@ -58,6 +58,12 @@ + + + + + + diff --git a/Triangle.NET/Triangle/Triangle.csproj.vspscc b/Triangle.NET/Triangle/Triangle.csproj.vspscc new file mode 100644 index 0000000..feffdec --- /dev/null +++ b/Triangle.NET/Triangle/Triangle.csproj.vspscc @@ -0,0 +1,10 @@ +"" +{ +"FILE_VERSION" = "9237" +"ENLISTMENT_CHOICE" = "NEVER" +"PROJECT_FILE_RELATIVE_PATH" = "" +"NUMBER_OF_EXCLUDED_FILES" = "0" +"ORIGINAL_PROJECT_FILE_PATH" = "" +"NUMBER_OF_NESTED_PROJECTS" = "0" +"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" +}