// ╔════════════════════════════════════════════════════════════════╗
// ║ Copyright © 2025 NWH Coding d.o.o. All rights reserved. ║
// ║ Licensed under Unity Asset Store Terms of Service: ║
// ║ https://unity.com/legal/as-terms ║
// ║ Use permitted only in compliance with the License. ║
// ║ Distributed "AS IS", without warranty of any kind. ║
// ╚════════════════════════════════════════════════════════════════╝
#region
using System.Collections.Generic;
using UnityEngine;
#endregion
namespace NWH.DWP2.MeshDecimation
{
///
/// Represents a vertex in the mesh decimation algorithm.
/// Stores vertex data and relationships for edge collapse operations.
///
public class Vert
{
///
/// Target vertex for edge collapse operation.
///
public Vert collapse;
///
/// Edge collapse cost for this vertex.
///
public float cost;
///
/// Whether this vertex has been deleted.
///
public bool deleted;
///
/// List of triangles that use this vertex.
///
public List face = new();
///
/// Unique identifier for this vertex.
///
public int id;
///
/// List of neighboring vertices connected by edges.
///
public List neighbor = new();
///
/// 3D position of the vertex.
///
public Vector3 position;
///
/// Whether this vertex is marked as selected (prevents collapse if locked).
///
public bool selected;
///
/// Initializes a new vertex with position, ID, and selection status.
///
/// 3D position of the vertex.
/// Unique identifier.
/// Whether the vertex is selected.
public Vert(Vector3 position, int id, bool selected)
{
this.position = position;
this.id = id;
this.selected = selected;
cost = 0f;
collapse = null;
}
///
/// Removes this vertex and breaks all neighbor connections.
///
public void RemoveVert()
{
Vert nb;
while (neighbor.Count > 0)
{
nb = neighbor[0];
nb.neighbor.Remove(this);
neighbor.Remove(nb);
}
deleted = true;
}
///
/// Checks if this vertex is on the mesh border.
/// A vertex is on the border if any of its edges is shared by only one triangle.
///
/// True if the vertex is on the border, false otherwise.
public bool IsBorder()
{
int j;
int n = neighbor.Count;
Vert nb;
int face_len;
Tri f;
int count = 0;
for (int i = 0; i < n; ++i)
{
count = 0;
nb = neighbor[i];
face_len = face.Count;
for (j = 0; j < face_len; ++j)
{
f = face[j];
if (f.HasVertex(nb))
{
++count;
}
}
if (count == 1)
{
return true;
}
}
return false;
}
///
/// Adds a triangle to this vertex's face list.
///
/// Triangle to add.
public void AddFace(Tri f)
{
face.Add(f);
}
///
/// Removes a triangle from this vertex's face list.
///
/// Triangle to remove.
public void RemoveFace(Tri f)
{
face.Remove(f);
}
///
/// Adds a vertex to the neighbor list if not already present.
///
/// Vertex to add as neighbor.
public void AddNeighbor(Vert v)
{
int i;
int foundAt = -1;
int n = neighbor.Count;
for (i = 0; i < n; ++i)
{
if (neighbor[i] == v)
{
foundAt = i;
break;
}
}
if (foundAt == -1)
{
neighbor.Add(v);
}
}
///
/// Removes a vertex from the neighbor list if they no longer share any faces.
///
/// Vertex to potentially remove from neighbors.
public void RemoveIfNonNeighbor(Vert v)
{
int i;
int foundAt = -1;
int n = neighbor.Count;
Tri f;
for (i = 0; i < n; ++i)
{
if (neighbor[i] == v)
{
foundAt = i;
break;
}
}
if (foundAt == -1)
{
return;
}
n = face.Count;
for (i = 0; i < n; ++i)
{
f = face[i];
if (f.HasVertex(v))
{
return;
}
}
neighbor.Remove(v);
}
}
}