Preparing for beta 2. NO NEED TO DOWNLOAD!

git-svn-id: https://triangle.svn.codeplex.com/svn@67702 0e2699bc-83d4-4a8f-98e7-55e24ab8c7a5
This commit is contained in:
SND\wo80_cp
2012-05-30 18:42:37 +00:00
parent c9dac5d6d1
commit 60cfbcda4e
34 changed files with 1427 additions and 292 deletions
@@ -16,7 +16,7 @@ namespace TestApp.Controls
/// <summary>
/// TODO: Update summary.
/// </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();
@@ -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();
}
@@ -16,7 +16,7 @@ namespace TestApp.Controls
/// <summary>
/// TODO: Update summary.
/// </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();
@@ -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();
@@ -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)
@@ -1,6 +1,6 @@
namespace TestApp
{
partial class Form1
partial class FormMain
{
/// <summary>
/// Required designer variable.
@@ -28,13 +28,13 @@
/// </summary>
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;
}
@@ -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)
@@ -1,6 +1,6 @@
namespace TestApp
{
partial class Form2
partial class FormQuality
{
/// <summary>
/// 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;
}
}
@@ -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();
+97
View File
@@ -0,0 +1,97 @@
// -----------------------------------------------------------------------
// <copyright file="FileProcessor.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------
namespace MeshExplorer.IO
{
using System;
using System.Collections.Generic;
using System.IO;
using MeshExplorer.IO.Formats;
using TriangleNet.IO;
using TriangleNet.Geometry;
using TriangleNet;
/// <summary>
/// Provides static methods to read and write mesh files.
/// </summary>
public static class FileProcessor
{
static Dictionary<string, IMeshFormat> container = new Dictionary<string,IMeshFormat>();
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;
}
}
}
@@ -0,0 +1,69 @@
// -----------------------------------------------------------------------
// <copyright file="DatFile.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------
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;
/// <summary>
/// TODO: Update summary.
/// </summary>
public class DatFile : MeshExplorer.IO.IMeshFormat
{
/// <summary>
/// Gets the supported file extensions.
/// </summary>
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();
}
}
}
+26
View File
@@ -0,0 +1,26 @@
// -----------------------------------------------------------------------
// <copyright file="IMeshFormat.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------
namespace MeshExplorer.IO
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TriangleNet;
using TriangleNet.Geometry;
/// <summary>
/// Defines an interface for mesh file formats.
/// </summary>
public interface IMeshFormat
{
string[] Extensions { get; }
InputGeometry Read(string file);
void Write(string file, Mesh data);
}
}
+408
View File
@@ -0,0 +1,408 @@
// -----------------------------------------------------------------------
// <copyright file="JsonParser.cs" company="">
// fastJSON - http://fastjson.codeplex.com/
// </copyright>
// -----------------------------------------------------------------------
namespace MeshExplorer.IO
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
/// <summary>
/// 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.
/// </summary>
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<string, object> ParseObject()
{
Dictionary<string, object> table = new Dictionary<string, object>();
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);
}
}
}
@@ -8,8 +8,8 @@
<ProjectGuid>{336AAF8A-5316-4303-9E73-5E38BD0B28AF}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>TestApp</RootNamespace>
<AssemblyName>TestApp</AssemblyName>
<RootNamespace>MeshExplorer</RootNamespace>
<AssemblyName>Mesh Explorer</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
@@ -46,64 +46,50 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Controls\ButtonDark.cs">
<Compile Include="Controls\DarkButton.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Controls\CheckBoxDark.cs">
<Compile Include="Controls\DarkCheckBox.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Controls\Histogram.cs">
<Compile Include="Controls\AngleHistogram.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Controls\TextBoxDark.cs">
<Compile Include="Controls\DarkTextBox.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Examples.cs" />
<Compile Include="Form1.cs">
<Compile Include="FormMain.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
<Compile Include="FormMain.Designer.cs">
<DependentUpon>FormMain.cs</DependentUpon>
</Compile>
<Compile Include="Controls\MeshRenderer.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Form2.cs">
<Compile Include="FormQuality.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form2.Designer.cs">
<DependentUpon>Form2.cs</DependentUpon>
<Compile Include="FormQuality.Designer.cs">
<DependentUpon>FormQuality.cs</DependentUpon>
</Compile>
<Compile Include="ImageWriter.cs" />
<Compile Include="IO\FileProcessor.cs" />
<Compile Include="IO\Formats\DatFile.cs" />
<Compile Include="IO\IMeshFormat.cs" />
<Compile Include="IO\JsonParser.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Rendering\MeshDataInternal.cs" />
<Compile Include="Rendering\RenderData.cs" />
<Compile Include="Rendering\Zoom.cs" />
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>
<Compile Include="Util.cs" />
<EmbeddedResource Include="FormMain.resx">
<DependentUpon>FormMain.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Form2.resx">
<DependentUpon>Form2.cs</DependentUpon>
<EmbeddedResource Include="FormQuality.resx">
<DependentUpon>FormQuality.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Triangle\Triangle.csproj">
@@ -111,6 +97,7 @@
<Name>Triangle</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
@@ -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"
}
+1 -1
View File
@@ -15,7 +15,7 @@ namespace TestApp
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
Application.Run(new FormMain());
}
}
}
-63
View File
@@ -1,63 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 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.
// </auto-generated>
//------------------------------------------------------------------------------
namespace TestApp.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TestApp.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}
@@ -1,117 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
-26
View File
@@ -1,26 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 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.
// </auto-generated>
//------------------------------------------------------------------------------
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;
}
}
}
}
@@ -1,7 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>
@@ -14,7 +14,7 @@ namespace TestApp.Rendering
using System.Drawing;
using TriangleNet;
public class MeshDataInternal
public class RenderData
{
public PointF[] Points;
public int[][] Triangles;
+79
View File
@@ -0,0 +1,79 @@
// -----------------------------------------------------------------------
// <copyright file="Util.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------
namespace MeshExplorer
{
using System;
using System.Drawing;
using System.Globalization;
using System.IO;
/// <summary>
/// Utility class.
/// </summary>
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);
}
}
}
+7 -7
View File
@@ -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
+10
View File
@@ -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"
}
@@ -0,0 +1,116 @@
// -----------------------------------------------------------------------
// <copyright file="Bbox_2.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Geometry
{
using System;
/// <summary>
/// A simple bounding box class.
/// </summary>
public class BoundingBox
{
double xmin, ymin, xmax, ymax;
/// <summary>
/// Initializes a new instance of the <see cref="BoundingBox" /> class.
/// </summary>
public BoundingBox()
{
xmin = double.MaxValue;
ymin = double.MaxValue;
xmax = -double.MaxValue;
ymax = -double.MaxValue;
}
/// <summary>
/// Initializes a new instance of the <see cref="BoundingBox" /> class
/// with predefined bounds.
/// </summary>
/// <param name="xmin">Minimum x value.</param>
/// <param name="ymin">Minimum y value.</param>
/// <param name="xmax">Maximum x value.</param>
/// <param name="ymax">Maximum y value.</param>
public BoundingBox(double xmin, double ymin, double xmax, double ymax)
{
this.xmin = xmin;
this.ymin = ymin;
this.xmax = xmax;
this.ymax = ymax;
}
/// <summary>
/// Gets the minimum x value (left boundary).
/// </summary>
public double Xmin
{
get { return xmin; }
}
/// <summary>
/// Gets the minimum y value (bottom boundary).
/// </summary>
public double Ymin
{
get { return ymin; }
}
/// <summary>
/// Gets the maximum x value (right boundary).
/// </summary>
public double Xmax
{
get { return xmax; }
}
/// <summary>
/// Gets the maximum y value (top boundary).
/// </summary>
public double Ymax
{
get { return ymax; }
}
/// <summary>
/// Gets the width of the bounding box.
/// </summary>
public double Width
{
get { return xmax - xmin; }
}
/// <summary>
/// Gets the height of the bounding box.
/// </summary>
public double Height
{
get { return ymax - ymin; }
}
/// <summary>
/// Update bounds.
/// </summary>
/// <param name="x">X coordinate.</param>
/// <param name="y">Y coordinate.</param>
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);
}
/// <summary>
/// Check if given point is inside bounding box.
/// </summary>
/// <param name="pt">Point to check.</param>
/// <returns>Return true, if bounding box contains given point.</returns>
public bool Contains(Point pt)
{
return ((pt.x >= xmin) && (pt.x <= xmax) && (pt.y >= ymin) && (pt.y <= ymax));
}
}
}
+61
View File
@@ -0,0 +1,61 @@
// -----------------------------------------------------------------------
// <copyright file="Edge.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Geometry
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TriangleNet.Data;
/// <summary>
/// Represents a straight line segment in 2D space.
/// </summary>
public class Edge
{
/// <summary>
/// Gets the first endpoints index.
/// </summary>
public int P0
{
get; private set;
}
/// <summary>
/// Gets the second endpoints index.
/// </summary>
public int P1
{
get; private set;
}
/// <summary>
/// Gets the segments boundary mark.
/// </summary>
public int Boundary
{
get; private set;
}
/// <summary>
/// Initializes a new instance of the <see cref="Edge" /> class.
/// </summary>
public Edge(int p0, int p1)
: this(p0, p1, 0)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="Edge" /> class.
/// </summary>
public Edge(int p0, int p1, int boundary)
{
this.P0 = p0;
this.P1 = p1;
this.Boundary = boundary;
}
}
}
@@ -0,0 +1,69 @@
// -----------------------------------------------------------------------
// <copyright file="ITriangle.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Geometry
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
/// <summary>
/// Triangle interface.
/// </summary>
public interface ITriangle
{
/// <summary>
/// The triangle id.
/// </summary>
int ID { get; }
/// <summary>
/// First vertex id of the triangle.
/// </summary>
int P0 { get; }
/// <summary>
/// Second vertex id of the triangle.
/// </summary>
int P1 { get; }
/// <summary>
/// Third vertex id of the triangle.
/// </summary>
int P2 { get; }
/// <summary>
/// Gets the specified vertex id.
/// </summary>
int this[int index] { get; }
/// <summary>
/// True if the triangle implementation contains neighbor information.
/// </summary>
bool SupportsNeighbors { get; }
/// <summary>
/// First neighbor.
/// </summary>
int N0 { get; }
/// <summary>
/// Second neighbor.
/// </summary>
int N1 { get; }
/// <summary>
/// Third neighbor.
/// </summary>
int N2 { get; }
/// <summary>
/// Triangle area constraint.
/// </summary>
double Area { get; }
/// <summary>
/// Triangle atributes.
/// </summary>
double[] Attributes { get; }
}
}
@@ -0,0 +1,187 @@
// -----------------------------------------------------------------------
// <copyright file="InputGeometry.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Geometry
{
using System;
using System.Collections.Generic;
using TriangleNet.Data;
/// <summary>
/// The input geometry which will be triangulated. May represent a
/// pointset or a planar straight line graph.
/// </summary>
public class InputGeometry
{
internal List<Vertex> points;
internal List<Edge> segments;
internal List<Point> holes;
internal List<RegionPointer> regions;
BoundingBox bounds;
/// <summary>
/// Initializes a new instance of the <see cref="InputGeometry" /> class.
/// </summary>
public InputGeometry()
: this(3)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="InputGeometry" /> class.
/// The point list will be initialized with a given capacity.
/// </summary>
/// <param name="capacity">Point list capacity.</param>
public InputGeometry(int capacity)
{
points = new List<Vertex>(capacity);
segments = new List<Edge>();
holes = new List<Point>();
regions = new List<RegionPointer>();
bounds = new BoundingBox();
}
/// <summary>
/// Gets the bounding box of the input geometry.
/// </summary>
public BoundingBox Bounds
{
get { return bounds; }
}
/// <summary>
/// Gets a value indicating whether the geometry should be treated as a PLSG.
/// </summary>
public bool HasSegments
{
get { return segments.Count > 0; }
}
/// <summary>
/// Gets the number of points.
/// </summary>
public int Count
{
get { return points.Count; }
}
/// <summary>
/// Gets the list of input points.
/// </summary>
public IEnumerable<Point> Points
{
get { return null; }
}
/// <summary>
/// Gets the list of input segments.
/// </summary>
public IEnumerable<Edge> Segments
{
get { return segments; }
}
/// <summary>
/// Gets the list of input holes.
/// </summary>
public IEnumerable<Point> Holes
{
get { return holes; }
}
/// <summary>
/// Gets the list of input holes.
/// </summary>
public IEnumerable<RegionPointer> Regions
{
get { return regions; }
}
/// <summary>
/// Clear input geometry.
/// </summary>
public void Clear()
{
points.Clear();
segments.Clear();
holes.Clear();
regions.Clear();
}
/// <summary>
/// Adds a point to the geometry.
/// </summary>
/// <param name="x">X coordinate.</param>
/// <param name="y">Y coordinate.</param>
public void AddPoint(double x, double y)
{
AddPoint(x, y, 0);
}
/// <summary>
/// Adds a point to the geometry.
/// </summary>
/// <param name="x">X coordinate.</param>
/// <param name="y">Y coordinate.</param>
/// <param name="boundary">Boundary marker.</param>
public void AddPoint(double x, double y, int boundary)
{
//points.Add(new Vertex(x, y, boundary));
bounds.Update(x, y);
}
/// <summary>
/// Adds a hole location to the geometry.
/// </summary>
/// <param name="x">X coordinate of the hole.</param>
/// <param name="y">Y coordinate of the hole.</param>
public void AddHole(double x, double y)
{
holes.Add(new Point(x, y));
}
/// <summary>
/// Adds a hole location to the geometry.
/// </summary>
/// <param name="x">X coordinate of the hole.</param>
/// <param name="y">Y coordinate of the hole.</param>
/// <param name="area">The regions area constraint.</param>
/// <param name="attribute">Region attribute.</param>
public void AddRegion(double x, double y, double area, double attribute)
{
regions.Add(new RegionPointer(x, y, area, attribute));
}
/// <summary>
/// Adds a segment to the geometry.
/// </summary>
/// <param name="p0">First endpoint.</param>
/// <param name="p1">Second endpoint.</param>
public void AddSegment(int p0, int p1)
{
AddSegment(p0, p1, 0);
}
/// <summary>
/// Adds a segment to the geometry.
/// </summary>
/// <param name="p0">First endpoint.</param>
/// <param name="p1">Second endpoint.</param>
/// <param name="boundary">Segment marker.</param>
public void AddSegment(int p0, int p1, int boundary)
{
if (p0 == p1)
{
throw new NotSupportedException("Invalid endpoints.");
}
segments.Add(new Edge(p0, p1, boundary));
}
}
}
+152
View File
@@ -0,0 +1,152 @@
// -----------------------------------------------------------------------
// <copyright file="Point2.cs" company="">
// 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/
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Geometry
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
/// <summary>
/// Represents a 2D point.
/// </summary>
public class Point : IComparable<Point>, IEquatable<Point>
{
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
/// <summary>
/// Gets the vertex x coordinate.
/// </summary>
public double X
{
get { return this.x; }
}
/// <summary>
/// Gets the vertex y coordinate.
/// </summary>
public double Y
{
get { return this.y; }
}
/// <summary>
/// Gets the vertex boundary mark.
/// </summary>
public int Boundary
{
get { return this.mark; }
}
/// <summary>
/// Gets the vertex attributes (may be null).
/// </summary>
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);
}
}
}
@@ -0,0 +1,61 @@
// -----------------------------------------------------------------------
// <copyright file="RegionPointer.cs" company="">
// 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/
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Geometry
{
using System;
using System.Collections.Generic;
/// <summary>
/// Pointer to a region in the mesh geometry. A region is a well-defined
/// subset of the geomerty (enclosed by subsegments).
/// </summary>
public class RegionPointer
{
internal Point point;
internal double area;
internal double attribute;
/// <summary>
/// Initializes a new instance of the <see cref="RegionPointer" /> class.
/// </summary>
/// <param name="x">X coordinate of the region.</param>
/// <param name="y">Y coordinate of the region.</param>
/// <param name="area">Area constraint.</param>
/// <param name="attribute">Region attribute.</param>
public RegionPointer(double x, double y, double area, double attribute)
{
this.point = new Point(x, y);
this.area = area;
this.attribute = attribute;
}
/// <summary>
/// Gets the location of the region.
/// </summary>
internal Point Point
{
get { return point; }
}
/// <summary>
/// Gets the area constraint.
/// </summary>
internal double Area
{
get { return area; }
}
/// <summary>
/// Gets the region attribute.
/// </summary>
internal double Attribute
{
get { return attribute; }
}
}
}
+6
View File
@@ -58,6 +58,12 @@
<Compile Include="Data\Triangle.cs" />
<Compile Include="Data\Vertex.cs" />
<Compile Include="Algorithm\Dwyer.cs" />
<Compile Include="Geometry\BoundingBox.cs" />
<Compile Include="Geometry\Edge.cs" />
<Compile Include="Geometry\InputGeometry.cs" />
<Compile Include="Geometry\ITriangle.cs" />
<Compile Include="Geometry\Point.cs" />
<Compile Include="Geometry\RegionPointer.cs" />
<Compile Include="IO\DataReader.cs" />
<Compile Include="IO\FileWriter.cs" />
<Compile Include="IO\VoronoiData.cs" />
@@ -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"
}