Fix Quadtree;
Added topology explorer to test app; git-svn-id: https://triangle.svn.codeplex.com/svn@74355 0e2699bc-83d4-4a8f-98e7-55e24ab8c7a5
This commit is contained in:
+18
@@ -55,6 +55,8 @@
|
||||
this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.menuToolsRcm = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.btnMesh = new MeshExplorer.Controls.DarkButton();
|
||||
this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.menuToolsTopology = new System.Windows.Forms.ToolStripMenuItem();
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
|
||||
this.splitContainer1.Panel1.SuspendLayout();
|
||||
this.splitContainer1.SuspendLayout();
|
||||
@@ -285,6 +287,8 @@
|
||||
this.menuTools.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.menuToolsGen,
|
||||
this.menuToolsCheck,
|
||||
this.toolStripSeparator5,
|
||||
this.menuToolsTopology,
|
||||
this.toolStripSeparator4,
|
||||
this.menuToolsRcm});
|
||||
this.menuTools.Name = "menuTools";
|
||||
@@ -330,6 +334,18 @@
|
||||
this.btnMesh.UseVisualStyleBackColor = true;
|
||||
this.btnMesh.Click += new System.EventHandler(this.btnMesh_Click);
|
||||
//
|
||||
// toolStripSeparator5
|
||||
//
|
||||
this.toolStripSeparator5.Name = "toolStripSeparator5";
|
||||
this.toolStripSeparator5.Size = new System.Drawing.Size(192, 6);
|
||||
//
|
||||
// menuToolsTopology
|
||||
//
|
||||
this.menuToolsTopology.Name = "menuToolsTopology";
|
||||
this.menuToolsTopology.Size = new System.Drawing.Size(195, 22);
|
||||
this.menuToolsTopology.Text = "Topology Explorer";
|
||||
this.menuToolsTopology.Click += new System.EventHandler(this.menuToolsTopology_Click);
|
||||
//
|
||||
// FormMain
|
||||
//
|
||||
this.AllowDrop = true;
|
||||
@@ -394,6 +410,8 @@
|
||||
private Views.MeshControlView meshControlView;
|
||||
private Views.StatisticView statisticView;
|
||||
private Views.AboutView aboutView;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator5;
|
||||
private System.Windows.Forms.ToolStripMenuItem menuToolsTopology;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -738,6 +738,11 @@ namespace MeshExplorer
|
||||
}
|
||||
}
|
||||
|
||||
private void menuToolsTopology_Click(object sender, EventArgs e)
|
||||
{
|
||||
(new FormTopology()).ShowDialog(this);
|
||||
}
|
||||
|
||||
private void menuToolsRcm_Click(object sender, EventArgs e)
|
||||
{
|
||||
Renumber();
|
||||
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
namespace MeshExplorer
|
||||
{
|
||||
partial class FormTopology
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
|
||||
this.renderControl = new MeshExplorer.Topology.TopologyRenderControl();
|
||||
this.topoControlView = new MeshExplorer.Topology.TopologyControlView();
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
|
||||
this.splitContainer1.Panel1.SuspendLayout();
|
||||
this.splitContainer1.Panel2.SuspendLayout();
|
||||
this.splitContainer1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// splitContainer1
|
||||
//
|
||||
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.splitContainer1.IsSplitterFixed = true;
|
||||
this.splitContainer1.Location = new System.Drawing.Point(0, 0);
|
||||
this.splitContainer1.Name = "splitContainer1";
|
||||
//
|
||||
// splitContainer1.Panel1
|
||||
//
|
||||
this.splitContainer1.Panel1.Controls.Add(this.renderControl);
|
||||
//
|
||||
// splitContainer1.Panel2
|
||||
//
|
||||
this.splitContainer1.Panel2.Controls.Add(this.topoControlView);
|
||||
this.splitContainer1.Size = new System.Drawing.Size(674, 455);
|
||||
this.splitContainer1.SplitterDistance = 475;
|
||||
this.splitContainer1.SplitterWidth = 1;
|
||||
this.splitContainer1.TabIndex = 0;
|
||||
//
|
||||
// renderControl
|
||||
//
|
||||
this.renderControl.BackColor = System.Drawing.Color.Black;
|
||||
this.renderControl.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.renderControl.Location = new System.Drawing.Point(0, 0);
|
||||
this.renderControl.Name = "renderControl";
|
||||
this.renderControl.Size = new System.Drawing.Size(475, 455);
|
||||
this.renderControl.TabIndex = 0;
|
||||
this.renderControl.Text = "topologyRenderControl";
|
||||
this.renderControl.MouseClick += new System.Windows.Forms.MouseEventHandler(this.renderControl_MouseClick);
|
||||
//
|
||||
// topoControlView
|
||||
//
|
||||
this.topoControlView.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(76)))), ((int)(((byte)(76)))), ((int)(((byte)(76)))));
|
||||
this.topoControlView.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.topoControlView.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.topoControlView.ForeColor = System.Drawing.Color.White;
|
||||
this.topoControlView.Location = new System.Drawing.Point(0, 0);
|
||||
this.topoControlView.Name = "topoControlView";
|
||||
this.topoControlView.Size = new System.Drawing.Size(198, 455);
|
||||
this.topoControlView.TabIndex = 2;
|
||||
//
|
||||
// FormTopology
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(76)))), ((int)(((byte)(76)))), ((int)(((byte)(76)))));
|
||||
this.ClientSize = new System.Drawing.Size(674, 455);
|
||||
this.Controls.Add(this.splitContainer1);
|
||||
this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.ForeColor = System.Drawing.Color.White;
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "FormTopology";
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.Text = "Triangle.NET - Topology Explorer";
|
||||
this.Load += new System.EventHandler(this.FormTopology_Load);
|
||||
this.splitContainer1.Panel1.ResumeLayout(false);
|
||||
this.splitContainer1.Panel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
|
||||
this.splitContainer1.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.SplitContainer splitContainer1;
|
||||
private Topology.TopologyRenderControl renderControl;
|
||||
private Topology.TopologyControlView topoControlView;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using MeshExplorer.Topology;
|
||||
using TriangleNet;
|
||||
using TriangleNet.Geometry;
|
||||
using TriangleNet.Tools;
|
||||
|
||||
namespace MeshExplorer
|
||||
{
|
||||
public partial class FormTopology : Form
|
||||
{
|
||||
Mesh mesh;
|
||||
QuadTree tree;
|
||||
OrientedTriangle current;
|
||||
|
||||
public FormTopology()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void FormTopology_Load(object sender, EventArgs e)
|
||||
{
|
||||
var geometry = RectanglePolygon.Generate(4);
|
||||
|
||||
mesh = new Mesh();
|
||||
mesh.Triangulate(geometry);
|
||||
|
||||
renderControl.Initialize(mesh);
|
||||
|
||||
topoControlView.PrimitiveCommandInvoked += PrimitiveCommandHandler;
|
||||
|
||||
current = new OrientedTriangle();
|
||||
}
|
||||
|
||||
void PrimitiveCommandHandler(object sender, GenericEventArgs<string> e)
|
||||
{
|
||||
if (current.Triangle != null)
|
||||
{
|
||||
InvokePrimitive(e.Argument);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderControl_MouseClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
var p = e.Location;
|
||||
var size = renderControl.Size;
|
||||
|
||||
var tri = FindTriangleAt(((float)p.X) / size.Width, ((float)p.Y) / size.Height);
|
||||
|
||||
current.Triangle = tri;
|
||||
current.Orientation = 0;
|
||||
|
||||
renderControl.Update(current);
|
||||
|
||||
topoControlView.SetTriangle(current);
|
||||
}
|
||||
|
||||
private ITriangle FindTriangleAt(float x, float y)
|
||||
{
|
||||
// Get mesh coordinates
|
||||
var p = renderControl.Zoom.ScreenToWorld(x, y);
|
||||
|
||||
topoControlView.SetPosition(p);
|
||||
|
||||
if (tree == null)
|
||||
{
|
||||
tree = new QuadTree(mesh, 5, 2);
|
||||
}
|
||||
|
||||
return tree.Query(p.X, p.Y);
|
||||
}
|
||||
|
||||
private bool TriangleContainsPoint(ITriangle triangle, float x, float y)
|
||||
{
|
||||
bool t1, t2, t3;
|
||||
|
||||
t1 = Sign(x, y, triangle.GetVertex(0), triangle.GetVertex(1)) < 0.0;
|
||||
t2 = Sign(x, y, triangle.GetVertex(1), triangle.GetVertex(2)) < 0.0;
|
||||
t3 = Sign(x, y, triangle.GetVertex(2), triangle.GetVertex(0)) < 0.0;
|
||||
|
||||
return (t1 == t2) && (t2 == t3);
|
||||
}
|
||||
|
||||
private double Sign(double x, double y, Point p, Point q)
|
||||
{
|
||||
return (x - q.X) * (p.Y - q.Y) - (p.X - q.X) * (y - q.Y);
|
||||
}
|
||||
|
||||
|
||||
private void InvokePrimitive(string name)
|
||||
{
|
||||
if (name == "sym")
|
||||
{
|
||||
current.Sym();
|
||||
}
|
||||
else if (name == "lnext")
|
||||
{
|
||||
current.Lnext();
|
||||
}
|
||||
else if (name == "lprev")
|
||||
{
|
||||
current.Lprev();
|
||||
}
|
||||
else if (name == "onext")
|
||||
{
|
||||
current.Onext();
|
||||
}
|
||||
else if (name == "oprev")
|
||||
{
|
||||
current.Oprev();
|
||||
}
|
||||
else if (name == "dnext")
|
||||
{
|
||||
current.Dnext();
|
||||
}
|
||||
else if (name == "dprev")
|
||||
{
|
||||
current.Dprev();
|
||||
}
|
||||
else if (name == "rnext")
|
||||
{
|
||||
current.Rnext();
|
||||
}
|
||||
else if (name == "rprev")
|
||||
{
|
||||
current.Rprev();
|
||||
}
|
||||
|
||||
renderControl.Update(current);
|
||||
topoControlView.SetTriangle(current);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<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" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</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" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace MeshExplorer
|
||||
{
|
||||
public class GenericEventArgs<T> : EventArgs
|
||||
{
|
||||
T argument;
|
||||
|
||||
public T Argument
|
||||
{
|
||||
get { return argument; }
|
||||
}
|
||||
|
||||
public GenericEventArgs(T arg)
|
||||
{
|
||||
argument = arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,6 +96,12 @@
|
||||
<Compile Include="FormMain.Designer.cs">
|
||||
<DependentUpon>FormMain.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="FormTopology.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="FormTopology.Designer.cs">
|
||||
<DependentUpon>FormTopology.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Generators\BaseGenerator.cs" />
|
||||
<Compile Include="Generators\BoxWithHole.cs" />
|
||||
<Compile Include="Generators\CircleWithHole.cs" />
|
||||
@@ -104,6 +110,7 @@
|
||||
<Compile Include="Generators\RandomPointsCircle.cs" />
|
||||
<Compile Include="Generators\RingPolygon.cs" />
|
||||
<Compile Include="Generators\StarInBox.cs" />
|
||||
<Compile Include="GenericEventArgs.cs" />
|
||||
<Compile Include="IO\EpsImage.cs" />
|
||||
<Compile Include="IO\FileProcessor.cs" />
|
||||
<Compile Include="IO\Formats\JsonFile.cs" />
|
||||
@@ -116,6 +123,18 @@
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Settings.cs" />
|
||||
<Compile Include="Topology\OrientedTriangle.cs" />
|
||||
<Compile Include="Topology\RectanglePolygon.cs" />
|
||||
<Compile Include="Topology\TopologyControlView.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Topology\TopologyControlView.Designer.cs">
|
||||
<DependentUpon>TopologyControlView.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Topology\TopologyRenderControl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Topology\TopologyRenderer.cs" />
|
||||
<Compile Include="Util.cs" />
|
||||
<Compile Include="Views\AboutView.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
@@ -148,6 +167,12 @@
|
||||
<EmbeddedResource Include="FormMain.resx">
|
||||
<DependentUpon>FormMain.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="FormTopology.resx">
|
||||
<DependentUpon>FormTopology.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Topology\TopologyControlView.resx">
|
||||
<DependentUpon>TopologyControlView.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Views\AboutView.resx">
|
||||
<DependentUpon>AboutView.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
|
||||
namespace MeshExplorer.Topology
|
||||
{
|
||||
using TriangleNet.Data;
|
||||
using TriangleNet.Geometry;
|
||||
|
||||
public class OrientedTriangle
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public ITriangle Triangle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ranges from 0 to 2.
|
||||
/// </summary>
|
||||
public int Orientation { get; set; }
|
||||
|
||||
#region Oriented triangle primitives
|
||||
|
||||
// For fast access
|
||||
static readonly int[] plus1Mod3 = { 1, 2, 0 };
|
||||
static readonly int[] minus1Mod3 = { 2, 0, 1 };
|
||||
|
||||
/// <summary>
|
||||
/// Find the abutting triangle; same edge. [sym(abc) -> ba*]
|
||||
/// </summary>
|
||||
public void Sym()
|
||||
{
|
||||
//this = tri.triangles[Orientation];
|
||||
// decode(ptr, otri);
|
||||
|
||||
var org = this.Org();
|
||||
Triangle = Triangle.GetNeighbor(Orientation);
|
||||
Orientation = GetOrientation(Triangle, org.ID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the next edge (counterclockwise) of a triangle. [lnext(abc) -> bca]
|
||||
/// </summary>
|
||||
public void Lnext()
|
||||
{
|
||||
Orientation = plus1Mod3[Orientation];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the previous edge (clockwise) of a triangle. [lprev(abc) -> cab]
|
||||
/// </summary>
|
||||
public void Lprev()
|
||||
{
|
||||
Orientation = minus1Mod3[Orientation];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the next edge counterclockwise with the same origin. [onext(abc) -> ac*]
|
||||
/// </summary>
|
||||
public void Onext()
|
||||
{
|
||||
Lprev();
|
||||
Sym();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the next edge clockwise with the same origin. [oprev(abc) -> a*b]
|
||||
/// </summary>
|
||||
public void Oprev()
|
||||
{
|
||||
Sym();
|
||||
Lnext();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the next edge counterclockwise with the same destination. [dnext(abc) -> *ba]
|
||||
/// </summary>
|
||||
public void Dnext()
|
||||
{
|
||||
Sym();
|
||||
Lprev();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the next edge clockwise with the same destination. [dprev(abc) -> cb*]
|
||||
/// </summary>
|
||||
public void Dprev()
|
||||
{
|
||||
Lnext();
|
||||
Sym();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the next edge (counterclockwise) of the adjacent triangle. [rnext(abc) -> *a*]
|
||||
/// </summary>
|
||||
public void Rnext()
|
||||
{
|
||||
Sym();
|
||||
Lnext();
|
||||
Sym();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the previous edge (clockwise) of the adjacent triangle. [rprev(abc) -> b**]
|
||||
/// </summary>
|
||||
public void Rprev()
|
||||
{
|
||||
Sym();
|
||||
Lprev();
|
||||
Sym();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Origin [org(abc) -> a]
|
||||
/// </summary>
|
||||
public Vertex Org()
|
||||
{
|
||||
return Triangle.GetVertex(plus1Mod3[Orientation]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destination [dest(abc) -> b]
|
||||
/// </summary>
|
||||
public Vertex Dest()
|
||||
{
|
||||
return Triangle.GetVertex(minus1Mod3[Orientation]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apex [apex(abc) -> c]
|
||||
/// </summary>
|
||||
public Vertex Apex()
|
||||
{
|
||||
return Triangle.GetVertex(Orientation);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private int GetOrientation(ITriangle tri, int org)
|
||||
{
|
||||
if (tri == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tri.P0 == org)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (tri.P1 == org)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
|
||||
namespace MeshExplorer.Topology
|
||||
{
|
||||
using TriangleNet.Geometry;
|
||||
|
||||
internal static class RectanglePolygon
|
||||
{
|
||||
public static InputGeometry Generate(int n, double bounds = 10.0)
|
||||
{
|
||||
var geometry = new InputGeometry((n + 1) * (n + 1));
|
||||
|
||||
double x, y, d = 2 * bounds / n;
|
||||
|
||||
int mark = 0;
|
||||
|
||||
for (int i = 0; i <= n; i++)
|
||||
{
|
||||
y = -bounds + i * d;
|
||||
|
||||
for (int j = 0; j <= n; j++)
|
||||
{
|
||||
x = -bounds + j * d;
|
||||
|
||||
geometry.AddPoint(x, y, mark);
|
||||
}
|
||||
}
|
||||
|
||||
// Add boundary segments
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
// Bottom
|
||||
geometry.AddSegment(i, i + 1);
|
||||
|
||||
// Right
|
||||
geometry.AddSegment(i * (n + 1) + n, (i + 1) * (n + 1) + n);
|
||||
|
||||
// Top
|
||||
geometry.AddSegment(n * (n + 1) + i, n * (n + 1) + (i + 1));
|
||||
|
||||
// Left
|
||||
geometry.AddSegment(i * (n + 1), (i + 1) * (n + 1));
|
||||
}
|
||||
|
||||
return geometry;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,359 @@
|
||||
namespace MeshExplorer.Topology
|
||||
{
|
||||
partial class TopologyControlView
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.lbS2 = new System.Windows.Forms.Label();
|
||||
this.lbS1 = new System.Windows.Forms.Label();
|
||||
this.lbS0 = new System.Windows.Forms.Label();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
this.lbN2 = new System.Windows.Forms.Label();
|
||||
this.lbN1 = new System.Windows.Forms.Label();
|
||||
this.lbN0 = new System.Windows.Forms.Label();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.lbPosition = new System.Windows.Forms.Label();
|
||||
this.lbV2 = new System.Windows.Forms.Label();
|
||||
this.lbV1 = new System.Windows.Forms.Label();
|
||||
this.lbV0 = new System.Windows.Forms.Label();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.lbTriangle = new System.Windows.Forms.Label();
|
||||
this.darkButton9 = new MeshExplorer.Controls.DarkButton();
|
||||
this.darkButton7 = new MeshExplorer.Controls.DarkButton();
|
||||
this.darkButton5 = new MeshExplorer.Controls.DarkButton();
|
||||
this.darkButton3 = new MeshExplorer.Controls.DarkButton();
|
||||
this.darkButton8 = new MeshExplorer.Controls.DarkButton();
|
||||
this.darkButton6 = new MeshExplorer.Controls.DarkButton();
|
||||
this.darkButton4 = new MeshExplorer.Controls.DarkButton();
|
||||
this.darkButton2 = new MeshExplorer.Controls.DarkButton();
|
||||
this.darkButton1 = new MeshExplorer.Controls.DarkButton();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// lbS2
|
||||
//
|
||||
this.lbS2.Location = new System.Drawing.Point(137, 122);
|
||||
this.lbS2.Name = "lbS2";
|
||||
this.lbS2.Size = new System.Drawing.Size(53, 13);
|
||||
this.lbS2.TabIndex = 16;
|
||||
this.lbS2.Text = "-";
|
||||
this.lbS2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
//
|
||||
// lbS1
|
||||
//
|
||||
this.lbS1.Location = new System.Drawing.Point(137, 107);
|
||||
this.lbS1.Name = "lbS1";
|
||||
this.lbS1.Size = new System.Drawing.Size(53, 13);
|
||||
this.lbS1.TabIndex = 15;
|
||||
this.lbS1.Text = "-";
|
||||
this.lbS1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
//
|
||||
// lbS0
|
||||
//
|
||||
this.lbS0.Location = new System.Drawing.Point(137, 92);
|
||||
this.lbS0.Name = "lbS0";
|
||||
this.lbS0.Size = new System.Drawing.Size(53, 13);
|
||||
this.lbS0.TabIndex = 17;
|
||||
this.lbS0.Text = "-";
|
||||
this.lbS0.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
//
|
||||
// label6
|
||||
//
|
||||
this.label6.ImageAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
this.label6.Location = new System.Drawing.Point(134, 71);
|
||||
this.label6.Name = "label6";
|
||||
this.label6.Size = new System.Drawing.Size(57, 13);
|
||||
this.label6.TabIndex = 19;
|
||||
this.label6.Text = "Segments";
|
||||
//
|
||||
// lbN2
|
||||
//
|
||||
this.lbN2.Location = new System.Drawing.Point(66, 122);
|
||||
this.lbN2.Name = "lbN2";
|
||||
this.lbN2.Size = new System.Drawing.Size(57, 13);
|
||||
this.lbN2.TabIndex = 13;
|
||||
this.lbN2.Text = "-";
|
||||
this.lbN2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
//
|
||||
// lbN1
|
||||
//
|
||||
this.lbN1.Location = new System.Drawing.Point(66, 107);
|
||||
this.lbN1.Name = "lbN1";
|
||||
this.lbN1.Size = new System.Drawing.Size(57, 13);
|
||||
this.lbN1.TabIndex = 14;
|
||||
this.lbN1.Text = "-";
|
||||
this.lbN1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
//
|
||||
// lbN0
|
||||
//
|
||||
this.lbN0.Location = new System.Drawing.Point(66, 92);
|
||||
this.lbN0.Name = "lbN0";
|
||||
this.lbN0.Size = new System.Drawing.Size(57, 13);
|
||||
this.lbN0.TabIndex = 12;
|
||||
this.lbN0.Text = "-";
|
||||
this.lbN0.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
//
|
||||
// label5
|
||||
//
|
||||
this.label5.ImageAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
this.label5.Location = new System.Drawing.Point(63, 71);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(61, 13);
|
||||
this.label5.TabIndex = 10;
|
||||
this.label5.Text = "Neighbors";
|
||||
//
|
||||
// lbPosition
|
||||
//
|
||||
this.lbPosition.AutoSize = true;
|
||||
this.lbPosition.Location = new System.Drawing.Point(70, 15);
|
||||
this.lbPosition.Name = "lbPosition";
|
||||
this.lbPosition.Size = new System.Drawing.Size(11, 13);
|
||||
this.lbPosition.TabIndex = 11;
|
||||
this.lbPosition.Text = "-";
|
||||
//
|
||||
// lbV2
|
||||
//
|
||||
this.lbV2.Location = new System.Drawing.Point(16, 122);
|
||||
this.lbV2.Name = "lbV2";
|
||||
this.lbV2.Size = new System.Drawing.Size(38, 13);
|
||||
this.lbV2.TabIndex = 6;
|
||||
this.lbV2.Text = "-";
|
||||
this.lbV2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
//
|
||||
// lbV1
|
||||
//
|
||||
this.lbV1.Location = new System.Drawing.Point(16, 107);
|
||||
this.lbV1.Name = "lbV1";
|
||||
this.lbV1.Size = new System.Drawing.Size(38, 13);
|
||||
this.lbV1.TabIndex = 5;
|
||||
this.lbV1.Text = "-";
|
||||
this.lbV1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
//
|
||||
// lbV0
|
||||
//
|
||||
this.lbV0.Location = new System.Drawing.Point(16, 92);
|
||||
this.lbV0.Name = "lbV0";
|
||||
this.lbV0.Size = new System.Drawing.Size(38, 13);
|
||||
this.lbV0.TabIndex = 7;
|
||||
this.lbV0.Text = "-";
|
||||
this.lbV0.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.ImageAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
this.label4.Location = new System.Drawing.Point(8, 71);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(47, 13);
|
||||
this.label4.TabIndex = 9;
|
||||
this.label4.Text = "Vertices";
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(6, 15);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(52, 13);
|
||||
this.label1.TabIndex = 8;
|
||||
this.label1.Text = "Position:";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(7, 37);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(51, 13);
|
||||
this.label2.TabIndex = 8;
|
||||
this.label2.Text = "Triangle:";
|
||||
//
|
||||
// lbTriangle
|
||||
//
|
||||
this.lbTriangle.AutoSize = true;
|
||||
this.lbTriangle.Location = new System.Drawing.Point(70, 37);
|
||||
this.lbTriangle.Name = "lbTriangle";
|
||||
this.lbTriangle.Size = new System.Drawing.Size(11, 13);
|
||||
this.lbTriangle.TabIndex = 11;
|
||||
this.lbTriangle.Text = "-";
|
||||
//
|
||||
// darkButton9
|
||||
//
|
||||
this.darkButton9.Location = new System.Drawing.Point(99, 367);
|
||||
this.darkButton9.Name = "darkButton9";
|
||||
this.darkButton9.Size = new System.Drawing.Size(78, 23);
|
||||
this.darkButton9.TabIndex = 21;
|
||||
this.darkButton9.Text = "Rprev";
|
||||
this.darkButton9.UseVisualStyleBackColor = true;
|
||||
this.darkButton9.Click += new System.EventHandler(this.btnPrimitive_Click);
|
||||
//
|
||||
// darkButton7
|
||||
//
|
||||
this.darkButton7.Location = new System.Drawing.Point(99, 338);
|
||||
this.darkButton7.Name = "darkButton7";
|
||||
this.darkButton7.Size = new System.Drawing.Size(78, 23);
|
||||
this.darkButton7.TabIndex = 22;
|
||||
this.darkButton7.Text = "Dprev";
|
||||
this.darkButton7.UseVisualStyleBackColor = true;
|
||||
this.darkButton7.Click += new System.EventHandler(this.btnPrimitive_Click);
|
||||
//
|
||||
// darkButton5
|
||||
//
|
||||
this.darkButton5.Location = new System.Drawing.Point(99, 309);
|
||||
this.darkButton5.Name = "darkButton5";
|
||||
this.darkButton5.Size = new System.Drawing.Size(78, 23);
|
||||
this.darkButton5.TabIndex = 23;
|
||||
this.darkButton5.Text = "Oprev";
|
||||
this.darkButton5.UseVisualStyleBackColor = true;
|
||||
this.darkButton5.Click += new System.EventHandler(this.btnPrimitive_Click);
|
||||
//
|
||||
// darkButton3
|
||||
//
|
||||
this.darkButton3.Location = new System.Drawing.Point(99, 280);
|
||||
this.darkButton3.Name = "darkButton3";
|
||||
this.darkButton3.Size = new System.Drawing.Size(78, 23);
|
||||
this.darkButton3.TabIndex = 24;
|
||||
this.darkButton3.Text = "Lprev";
|
||||
this.darkButton3.UseVisualStyleBackColor = true;
|
||||
this.darkButton3.Click += new System.EventHandler(this.btnPrimitive_Click);
|
||||
//
|
||||
// darkButton8
|
||||
//
|
||||
this.darkButton8.Location = new System.Drawing.Point(11, 367);
|
||||
this.darkButton8.Name = "darkButton8";
|
||||
this.darkButton8.Size = new System.Drawing.Size(78, 23);
|
||||
this.darkButton8.TabIndex = 25;
|
||||
this.darkButton8.Text = "Rnext";
|
||||
this.darkButton8.UseVisualStyleBackColor = true;
|
||||
this.darkButton8.Click += new System.EventHandler(this.btnPrimitive_Click);
|
||||
//
|
||||
// darkButton6
|
||||
//
|
||||
this.darkButton6.Location = new System.Drawing.Point(11, 338);
|
||||
this.darkButton6.Name = "darkButton6";
|
||||
this.darkButton6.Size = new System.Drawing.Size(78, 23);
|
||||
this.darkButton6.TabIndex = 26;
|
||||
this.darkButton6.Text = "Dnext";
|
||||
this.darkButton6.UseVisualStyleBackColor = true;
|
||||
this.darkButton6.Click += new System.EventHandler(this.btnPrimitive_Click);
|
||||
//
|
||||
// darkButton4
|
||||
//
|
||||
this.darkButton4.Location = new System.Drawing.Point(11, 309);
|
||||
this.darkButton4.Name = "darkButton4";
|
||||
this.darkButton4.Size = new System.Drawing.Size(78, 23);
|
||||
this.darkButton4.TabIndex = 27;
|
||||
this.darkButton4.Text = "Onext";
|
||||
this.darkButton4.UseVisualStyleBackColor = true;
|
||||
this.darkButton4.Click += new System.EventHandler(this.btnPrimitive_Click);
|
||||
//
|
||||
// darkButton2
|
||||
//
|
||||
this.darkButton2.Location = new System.Drawing.Point(11, 280);
|
||||
this.darkButton2.Name = "darkButton2";
|
||||
this.darkButton2.Size = new System.Drawing.Size(78, 23);
|
||||
this.darkButton2.TabIndex = 28;
|
||||
this.darkButton2.Text = "Lnext";
|
||||
this.darkButton2.UseVisualStyleBackColor = true;
|
||||
this.darkButton2.Click += new System.EventHandler(this.btnPrimitive_Click);
|
||||
//
|
||||
// darkButton1
|
||||
//
|
||||
this.darkButton1.Location = new System.Drawing.Point(11, 251);
|
||||
this.darkButton1.Name = "darkButton1";
|
||||
this.darkButton1.Size = new System.Drawing.Size(166, 23);
|
||||
this.darkButton1.TabIndex = 20;
|
||||
this.darkButton1.Text = "Sym";
|
||||
this.darkButton1.UseVisualStyleBackColor = true;
|
||||
this.darkButton1.Click += new System.EventHandler(this.btnPrimitive_Click);
|
||||
//
|
||||
// TopoControlView
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(76)))), ((int)(((byte)(76)))), ((int)(((byte)(76)))));
|
||||
this.Controls.Add(this.darkButton9);
|
||||
this.Controls.Add(this.darkButton7);
|
||||
this.Controls.Add(this.darkButton5);
|
||||
this.Controls.Add(this.darkButton3);
|
||||
this.Controls.Add(this.darkButton8);
|
||||
this.Controls.Add(this.darkButton6);
|
||||
this.Controls.Add(this.darkButton4);
|
||||
this.Controls.Add(this.darkButton2);
|
||||
this.Controls.Add(this.darkButton1);
|
||||
this.Controls.Add(this.lbS2);
|
||||
this.Controls.Add(this.lbS1);
|
||||
this.Controls.Add(this.lbS0);
|
||||
this.Controls.Add(this.label6);
|
||||
this.Controls.Add(this.lbN2);
|
||||
this.Controls.Add(this.lbN1);
|
||||
this.Controls.Add(this.lbN0);
|
||||
this.Controls.Add(this.label5);
|
||||
this.Controls.Add(this.lbTriangle);
|
||||
this.Controls.Add(this.lbPosition);
|
||||
this.Controls.Add(this.lbV2);
|
||||
this.Controls.Add(this.lbV1);
|
||||
this.Controls.Add(this.lbV0);
|
||||
this.Controls.Add(this.label4);
|
||||
this.Controls.Add(this.label2);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.ForeColor = System.Drawing.Color.White;
|
||||
this.Name = "TopoControlView";
|
||||
this.Size = new System.Drawing.Size(195, 439);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label lbS2;
|
||||
private System.Windows.Forms.Label lbS1;
|
||||
private System.Windows.Forms.Label lbS0;
|
||||
private System.Windows.Forms.Label label6;
|
||||
private System.Windows.Forms.Label lbN2;
|
||||
private System.Windows.Forms.Label lbN1;
|
||||
private System.Windows.Forms.Label lbN0;
|
||||
private System.Windows.Forms.Label label5;
|
||||
private System.Windows.Forms.Label lbPosition;
|
||||
private System.Windows.Forms.Label lbV2;
|
||||
private System.Windows.Forms.Label lbV1;
|
||||
private System.Windows.Forms.Label lbV0;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Label lbTriangle;
|
||||
private Controls.DarkButton darkButton9;
|
||||
private Controls.DarkButton darkButton7;
|
||||
private Controls.DarkButton darkButton5;
|
||||
private Controls.DarkButton darkButton3;
|
||||
private Controls.DarkButton darkButton8;
|
||||
private Controls.DarkButton darkButton6;
|
||||
private Controls.DarkButton darkButton4;
|
||||
private Controls.DarkButton darkButton2;
|
||||
private Controls.DarkButton darkButton1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Windows.Forms;
|
||||
using TriangleNet.Geometry;
|
||||
|
||||
namespace MeshExplorer.Topology
|
||||
{
|
||||
public partial class TopologyControlView : UserControl
|
||||
{
|
||||
public event EventHandler<GenericEventArgs<string>> PrimitiveCommandInvoked;
|
||||
|
||||
public TopologyControlView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void SetPosition(PointF p)
|
||||
{
|
||||
var nfi = NumberFormatInfo.InvariantInfo;
|
||||
|
||||
lbPosition.Text = String.Format(nfi, "X: {0:0.0}, Y: {1:0.0}", p.X, p.Y);
|
||||
}
|
||||
|
||||
public void SetTriangle(OrientedTriangle tri)
|
||||
{
|
||||
var t = tri.Triangle;
|
||||
|
||||
if (t != null)
|
||||
{
|
||||
lbTriangle.Text = t.ID.ToString();
|
||||
|
||||
lbV0.Text = t.P0.ToString();
|
||||
lbV1.Text = t.P1.ToString();
|
||||
lbV2.Text = t.P2.ToString();
|
||||
|
||||
lbN0.Text = t.N0.ToString();
|
||||
lbN1.Text = t.N1.ToString();
|
||||
lbN2.Text = t.N2.ToString();
|
||||
|
||||
lbS0.Text = GetSegmentString(t.GetSegment(0));
|
||||
lbS1.Text = GetSegmentString(t.GetSegment(1));
|
||||
lbS2.Text = GetSegmentString(t.GetSegment(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
lbTriangle.Text = "-";
|
||||
|
||||
lbV0.Text = "-";
|
||||
lbV1.Text = "-";
|
||||
lbV2.Text = "-";
|
||||
|
||||
lbN0.Text = "-";
|
||||
lbN1.Text = "-";
|
||||
lbN2.Text = "-";
|
||||
|
||||
lbS0.Text = "-";
|
||||
lbS1.Text = "-";
|
||||
lbS2.Text = "-";
|
||||
}
|
||||
}
|
||||
|
||||
private string GetSegmentString(ISegment seg)
|
||||
{
|
||||
return seg == null ? "-" : "[" + seg.P0 + " - " + seg.P1 + "]";
|
||||
}
|
||||
|
||||
private void btnPrimitive_Click(object sender, EventArgs e)
|
||||
{
|
||||
var button = sender as Button;
|
||||
|
||||
if (button != null)
|
||||
{
|
||||
var name = button.Text.ToLowerInvariant();
|
||||
|
||||
var handler = PrimitiveCommandInvoked;
|
||||
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new GenericEventArgs<string>(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<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" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</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" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
|
||||
namespace MeshExplorer.Topology
|
||||
{
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Text;
|
||||
using System.Windows.Forms;
|
||||
using MeshRenderer.Core;
|
||||
using TriangleNet;
|
||||
|
||||
public class TopologyRenderControl : Control
|
||||
{
|
||||
// Rendering stuff
|
||||
private BufferedGraphics buffer;
|
||||
private BufferedGraphicsContext context;
|
||||
|
||||
Zoom zoom;
|
||||
TopologyRenderer renderer;
|
||||
|
||||
bool initialized = false;
|
||||
|
||||
public Zoom Zoom
|
||||
{
|
||||
get { return zoom; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RenderControl" /> class.
|
||||
/// </summary>
|
||||
public TopologyRenderControl()
|
||||
{
|
||||
SetStyle(ControlStyles.ResizeRedraw, true);
|
||||
|
||||
this.BackColor = Color.Black;
|
||||
|
||||
zoom = new Zoom(true);
|
||||
context = new BufferedGraphicsContext();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the graphics buffer (should be called in the forms load event).
|
||||
/// </summary>
|
||||
public void Initialize(Mesh mesh)
|
||||
{
|
||||
renderer = new TopologyRenderer(mesh);
|
||||
|
||||
zoom.Initialize(this.ClientRectangle);
|
||||
//zoom.ClipMargin = 10.0f;
|
||||
|
||||
var b = mesh.Bounds;
|
||||
zoom.Update(new BoundingBox((float)b.Xmin, (float)b.Xmax,
|
||||
(float)b.Ymin, (float)b.Ymax));
|
||||
|
||||
InitializeBuffer();
|
||||
|
||||
initialized = true;
|
||||
|
||||
this.Render();
|
||||
}
|
||||
|
||||
public void Update(OrientedTriangle otri)
|
||||
{
|
||||
renderer.SelectTriangle(otri.Triangle == null ? null : otri);
|
||||
this.Render();
|
||||
}
|
||||
|
||||
private void InitializeBuffer()
|
||||
{
|
||||
if (this.Width > 0 && this.Height > 0)
|
||||
{
|
||||
if (buffer != null)
|
||||
{
|
||||
if (this.ClientRectangle == buffer.Graphics.VisibleClipBounds)
|
||||
{
|
||||
this.Invalidate();
|
||||
|
||||
// Bounds didn't change. Probably we just restored the window
|
||||
// from minimized state.
|
||||
return;
|
||||
}
|
||||
|
||||
buffer.Dispose();
|
||||
}
|
||||
|
||||
buffer = context.Allocate(Graphics.FromHwnd(this.Handle), this.ClientRectangle);
|
||||
|
||||
if (initialized)
|
||||
{
|
||||
this.Render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Render()
|
||||
{
|
||||
if (buffer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Graphics g = buffer.Graphics;
|
||||
g.Clear(this.BackColor);
|
||||
|
||||
if (!initialized || renderer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
|
||||
|
||||
renderer.Render(g, zoom);
|
||||
|
||||
this.Invalidate();
|
||||
}
|
||||
|
||||
#region Control overrides
|
||||
|
||||
protected override void OnPaint(PaintEventArgs pe)
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
base.OnPaint(pe);
|
||||
return;
|
||||
}
|
||||
|
||||
buffer.Render();
|
||||
}
|
||||
|
||||
protected override void OnPaintBackground(PaintEventArgs pevent)
|
||||
{
|
||||
// Do nothing
|
||||
if (!initialized)
|
||||
{
|
||||
base.OnPaintBackground(pevent);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
|
||||
namespace MeshExplorer.Topology
|
||||
{
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using MeshRenderer.Core;
|
||||
using TriangleNet;
|
||||
using TriangleNet.Geometry;
|
||||
|
||||
public class TopologyRenderer
|
||||
{
|
||||
Zoom zoom;
|
||||
Mesh mesh;
|
||||
PointF[] points;
|
||||
|
||||
// Colors
|
||||
Color Background = Color.FromArgb(0, 0, 0);
|
||||
Brush Point = new SolidBrush(Color.FromArgb(0, 80, 0));
|
||||
Brush Triangle = new SolidBrush(Color.FromArgb(50, 50, 50));
|
||||
Pen Line = new Pen(Color.FromArgb(30, 30, 30));
|
||||
Pen Segment = new Pen(Color.DarkBlue);
|
||||
|
||||
Brush SelectedTriangle = new SolidBrush(Color.FromArgb(50, 0, 0));
|
||||
Pen SelectedEdge = new Pen(Color.DarkRed, 2.0f);
|
||||
|
||||
Font font, fontTri;
|
||||
|
||||
OrientedTriangle selection;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MeshRenderer" /> class.
|
||||
/// </summary>
|
||||
public TopologyRenderer(Mesh mesh)
|
||||
{
|
||||
this.mesh = mesh;
|
||||
|
||||
points = new PointF[mesh.Vertices.Count];
|
||||
|
||||
int k = 0;
|
||||
|
||||
foreach (var v in mesh.Vertices)
|
||||
{
|
||||
points[k++] = new PointF((float)v.X, (float)v.Y);
|
||||
}
|
||||
|
||||
font = new Font("Arial", 7.5f);
|
||||
fontTri = new Font("Arial", 12f, FontStyle.Bold);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the mesh.
|
||||
/// </summary>
|
||||
public void Render(Graphics g, Zoom zoom)
|
||||
{
|
||||
this.zoom = zoom;
|
||||
|
||||
if (mesh.Edges != null)
|
||||
{
|
||||
this.RenderSelectedTriangle(g);
|
||||
this.RenderEdges(g);
|
||||
this.RenderTriangleIds(g);
|
||||
}
|
||||
else if (mesh.Triangles != null)
|
||||
{
|
||||
this.RenderTriangles(g);
|
||||
}
|
||||
|
||||
if (mesh.Segments != null)
|
||||
{
|
||||
this.RenderSegments(g);
|
||||
}
|
||||
|
||||
RenderSelectedEdge(g);
|
||||
|
||||
if (mesh.Vertices != null)
|
||||
{
|
||||
this.RenderPoints(g);
|
||||
}
|
||||
}
|
||||
|
||||
public void SelectTriangle(OrientedTriangle tri)
|
||||
{
|
||||
selection = tri;
|
||||
}
|
||||
|
||||
#region Helpers
|
||||
|
||||
private PointF GetIncenter(PointF p0, PointF p1, PointF p2)
|
||||
{
|
||||
double cx, cy, a, b, c,
|
||||
dax = p1.X - p0.X,
|
||||
dbx = p2.X - p1.X,
|
||||
dcx = p0.X - p2.X,
|
||||
day = p1.Y - p0.Y,
|
||||
dby = p2.Y - p1.Y,
|
||||
dcy = p0.Y - p2.Y;
|
||||
|
||||
a = Math.Sqrt(dax * dax + day * day);
|
||||
b = Math.Sqrt(dbx * dbx + dby * dby);
|
||||
c = Math.Sqrt(dcx * dcx + dcy * dcy);
|
||||
|
||||
cx = (a * p2.X + b * p0.X + c * p1.X) / (a + b + c);
|
||||
cy = (a * p2.Y + b * p0.Y + c * p1.Y) / (a + b + c);
|
||||
|
||||
return new PointF((float)cx, (float)cy);
|
||||
}
|
||||
|
||||
private PointF GetCentroid(PointF p0, PointF p1, PointF p2)
|
||||
{
|
||||
double cx, cy;
|
||||
|
||||
cx = (p0.X + p1.X + p2.X) / 3;
|
||||
cy = (p0.Y + p1.Y + p2.Y) / 3;
|
||||
|
||||
return new PointF((float)cx, (float)cy);
|
||||
}
|
||||
|
||||
private PointF GetPoint(ITriangle tri, int index)
|
||||
{
|
||||
var v = tri.GetVertex(index);
|
||||
|
||||
return new PointF((float)v.X, (float)v.Y);
|
||||
}
|
||||
|
||||
private PointF GetPoint(ISegment seg, int index)
|
||||
{
|
||||
var v = seg.GetVertex(index);
|
||||
|
||||
return new PointF((float)v.X, (float)v.Y);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void RenderPoints(Graphics g)
|
||||
{
|
||||
int n = points.Length;
|
||||
PointF pt;
|
||||
|
||||
int id = selection != null ? selection.Org().ID : -1;
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
var brush = i == id ? Brushes.DarkRed : Point;
|
||||
|
||||
pt = zoom.WorldToScreen(points[i].X, points[i].Y);
|
||||
g.FillEllipse(brush, pt.X - 10f, pt.Y - 10f, 20, 20);
|
||||
|
||||
pt.X -= i > 9 ? 7 : 4;
|
||||
pt.Y -= 6;
|
||||
g.DrawString(i.ToString(), font, Brushes.White, pt);
|
||||
}
|
||||
}
|
||||
|
||||
private void RenderTriangles(Graphics g)
|
||||
{
|
||||
PointF p0, p1, p2, center;
|
||||
|
||||
var triangles = mesh.Triangles;
|
||||
|
||||
// Draw triangles
|
||||
foreach (var tri in triangles)
|
||||
{
|
||||
p0 = points[tri.P0];
|
||||
p1 = points[tri.P1];
|
||||
p2 = points[tri.P2];
|
||||
|
||||
p0 = zoom.WorldToScreen(p0.X, p0.Y);
|
||||
p1 = zoom.WorldToScreen(p1.X, p1.Y);
|
||||
p2 = zoom.WorldToScreen(p2.X, p2.Y);
|
||||
|
||||
g.DrawLine(Line, p0, p1);
|
||||
g.DrawLine(Line, p1, p2);
|
||||
g.DrawLine(Line, p2, p0);
|
||||
|
||||
center = GetIncenter(p0, p1, p2);
|
||||
center.X -= 5;
|
||||
center.Y -= 5;
|
||||
|
||||
g.DrawString(tri.ID.ToString(), fontTri, Triangle, center);
|
||||
}
|
||||
}
|
||||
|
||||
private void RenderTriangleIds(Graphics g)
|
||||
{
|
||||
PointF p0, p1, p2, center;
|
||||
|
||||
var triangles = mesh.Triangles;
|
||||
|
||||
// Draw triangles
|
||||
foreach (var tri in triangles)
|
||||
{
|
||||
p0 = points[tri.P0];
|
||||
p1 = points[tri.P1];
|
||||
p2 = points[tri.P2];
|
||||
|
||||
p0 = zoom.WorldToScreen(p0.X, p0.Y);
|
||||
p1 = zoom.WorldToScreen(p1.X, p1.Y);
|
||||
p2 = zoom.WorldToScreen(p2.X, p2.Y);
|
||||
|
||||
center = GetIncenter(p0, p1, p2);
|
||||
center.X -= 5;
|
||||
center.Y -= 5;
|
||||
|
||||
g.DrawString(tri.ID.ToString(), fontTri, Triangle, center);
|
||||
}
|
||||
}
|
||||
|
||||
private void RenderEdges(Graphics g)
|
||||
{
|
||||
PointF p0, p1;
|
||||
|
||||
var edges = mesh.Edges;
|
||||
|
||||
// Draw edges
|
||||
foreach (var edge in edges)
|
||||
{
|
||||
p0 = points[edge.P0];
|
||||
p1 = points[edge.P1];
|
||||
|
||||
p0 = zoom.WorldToScreen(p0.X, p0.Y);
|
||||
p1 = zoom.WorldToScreen(p1.X, p1.Y);
|
||||
|
||||
g.DrawLine(Line, p0, p1);
|
||||
}
|
||||
}
|
||||
|
||||
private void RenderSegments(Graphics g)
|
||||
{
|
||||
PointF p0, p1;
|
||||
|
||||
var segments = mesh.Segments;
|
||||
|
||||
foreach (var seg in segments)
|
||||
{
|
||||
p0 = points[seg.P0];
|
||||
p1 = points[seg.P1];
|
||||
|
||||
p0 = zoom.WorldToScreen(p0.X, p0.Y);
|
||||
p1 = zoom.WorldToScreen(p1.X, p1.Y);
|
||||
|
||||
g.DrawLine(Segment, p0, p1);
|
||||
}
|
||||
}
|
||||
|
||||
private void RenderSelectedEdge(Graphics g)
|
||||
{
|
||||
if (selection != null)
|
||||
{
|
||||
PointF p0, p1;
|
||||
|
||||
p0 = points[selection.Org().ID];
|
||||
p1 = points[selection.Dest().ID];
|
||||
|
||||
p0 = zoom.WorldToScreen(p0.X, p0.Y);
|
||||
p1 = zoom.WorldToScreen(p1.X, p1.Y);
|
||||
|
||||
g.DrawLine(SelectedEdge, p0, p1);
|
||||
}
|
||||
}
|
||||
|
||||
private void RenderSelectedTriangle(Graphics g)
|
||||
{
|
||||
if (selection != null)
|
||||
{
|
||||
var tri = selection.Triangle;
|
||||
|
||||
var p = new PointF[3];
|
||||
|
||||
p[0] = points[tri.P0];
|
||||
p[1] = points[tri.P1];
|
||||
p[2] = points[tri.P2];
|
||||
|
||||
p[0] = zoom.WorldToScreen(p[0].X, p[0].Y);
|
||||
p[1] = zoom.WorldToScreen(p[1].X, p[1].Y);
|
||||
p[2] = zoom.WorldToScreen(p[2].X, p[2].Y);
|
||||
|
||||
g.FillPolygon(SelectedTriangle, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ namespace TriangleNet.Tools
|
||||
{
|
||||
QuadNode root;
|
||||
|
||||
internal ITriangle[] triangles;
|
||||
internal Dictionary<int, ITriangle> triangles;
|
||||
|
||||
internal int sizeBound;
|
||||
internal int maxDepth;
|
||||
@@ -42,7 +42,12 @@ namespace TriangleNet.Tools
|
||||
this.maxDepth = maxDepth;
|
||||
this.sizeBound = sizeBound;
|
||||
|
||||
triangles = mesh.Triangles.ToArray();
|
||||
triangles = new Dictionary<int, ITriangle>();
|
||||
|
||||
foreach (var tri in mesh.Triangles)
|
||||
{
|
||||
triangles.Add(tri.id, tri);
|
||||
}
|
||||
|
||||
int currentDepth = 0;
|
||||
|
||||
@@ -64,6 +69,7 @@ namespace TriangleNet.Tools
|
||||
if (IsPointInTriangle(point, tri.GetVertex(0), tri.GetVertex(1), tri.GetVertex(2)))
|
||||
{
|
||||
result.Add(tri);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,11 +166,11 @@ namespace TriangleNet.Tools
|
||||
if (init)
|
||||
{
|
||||
// Allocate memory upfront
|
||||
triangles.Capacity = tree.triangles.Length;
|
||||
triangles.Capacity = tree.triangles.Count;
|
||||
|
||||
foreach (var tri in tree.triangles)
|
||||
foreach (var id in tree.triangles.Keys)
|
||||
{
|
||||
triangles.Add(tri.ID);
|
||||
triangles.Add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -208,10 +214,8 @@ namespace TriangleNet.Tools
|
||||
Point[] triangle = new Point[3];
|
||||
|
||||
// Find region for every triangle vertex
|
||||
foreach (var index in triangles)
|
||||
foreach (var tri in tree.triangles.Values)
|
||||
{
|
||||
ITriangle tri = tree.triangles[index];
|
||||
|
||||
triangle[0] = tri.GetVertex(0);
|
||||
triangle[1] = tri.GetVertex(1);
|
||||
triangle[2] = tri.GetVertex(2);
|
||||
|
||||
Reference in New Issue
Block a user