using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Mesher.Tools
{
public static class ExtrudeFaceSelectionExtensions
{
/// <summary>
/// Extrudes the vertices of that by the given factor by using mode to describe the extrude direction.
/// </summary>
/// <param name="that"></param>
/// <param name="factor">How far should we extrude</param>
/// <param name="mode">Which direction should we extrude</param>
/// <returns>The sides created by the operation.</returns>
public static FaceSelection Extrude(this FaceSelection that, float factor, MoveMode mode = MoveMode.UseVertexNormal)
{
var sides = that.Bevel(factor, 1.0f, mode);
return sides;
}
/// <summary>
/// Extrudes the vertices of that by the given factor by using mode to describe the extrude direction.
/// </summary>
/// <param name="that"></param>
/// <param name="extrudeDirection">To where should we extrude</param>
/// <param name="mode">Which direction should we extrude</param>
/// <returns>The sides created by the operation.</returns>
public static FaceSelection Extrude(this FaceSelection that, Vector3 extrudeDirection)
{
var sides = that.Bevel(extrudeDirection, 1.0f);
return sides;
}
/// <summary>
/// Extrudes the vertices of that by the given factor by using mode to describe the extrude direction. After this operation has been finished
/// that will be scaled be capScale.
/// </summary>
/// <param name="that"></param>
/// <param name="factor">How far should we extrude</param>
/// <param name="capScale">How much should that be scaled after extruding</param>
/// <param name="mode">Which direction should we extrude</param>
/// <returns>The sides created by the operation.</returns>
public static FaceSelection Bevel(this FaceSelection that, float factor, float capScale, MoveMode mode = MoveMode.UseVertexNormal)
{
return that.Bevel(factor, capScale, mode, null);
}
/// <summary>
/// Extrudes the vertices of that by the given factor by using mode to describe the extrude direction. After this operation has been finished
/// that will be scaled be capScale.
/// </summary>
/// <param name="that"></param>
/// <param name="extrudeDirection">To where should we extrude</param>
/// <param name="capScale">How much should that be scaled after extruding</param>
/// <returns>The sides created by the operation.</returns>
public static FaceSelection Bevel(this FaceSelection that, Vector3 extrudeDirection, float capScale)
{
return that.Bevel(0, capScale, MoveMode.UseCollectionNormal, extrudeDirection);
}
private static FaceSelection Bevel(this FaceSelection that, float factor, float capScale, MoveMode mode, Vector3? extrudeDirectionOverride)
{
if (that.Normal == Vector3.zero && mode == MoveMode.UseCollectionNormal && !extrudeDirectionOverride.HasValue)
return new FaceSelection(new Face[0], that.Owner);
var sideFaces = new List<Face>();
var oldOutlineEdges = that.FindOutlineEdges(true);
var oldToNewVertices = that.Detach();
if (extrudeDirectionOverride.HasValue)
that.Move(extrudeDirectionOverride.Value);
else
that.Move(factor, mode);
var newOutlineEdges = that.FindOutlineEdges(true);
var parentToCloneVertices = new Dictionary<Vertex, Vertex>();
for (int i = 0; i < newOutlineEdges.Length; ++i)
{
var oldEdge = oldOutlineEdges[i];
var newEdge = newOutlineEdges[i];
var relevantFace = newEdge.Faces.First(face => that.Faces.Contains(face));
Vertex original0 = oldEdge.Vertices[0];
Vertex original1 = oldEdge.Vertices[1];
var target0 = oldToNewVertices[oldEdge.Vertices[0]];
var target1 = oldToNewVertices[oldEdge.Vertices[1]];
bool isNewVertex;
var clone0 = CommonFaceSelectionExtensions.CloneVertex(parentToCloneVertices, target0, true, out isNewVertex);
var clone1 = CommonFaceSelectionExtensions.CloneVertex(parentToCloneVertices, target1, true, out isNewVertex);
var sideFace = new Face(new Vertex[]
{
original0,
original1,
clone1,
clone0,
});
if (factor < 0)
{
sideFace = new Face(new Vertex[]
{
clone1,
clone0,
original0,
original1,
});
}
sideFace.CopyProperties(relevantFace);
sideFaces.Add(sideFace);
that.Owner.AddFace(sideFace);
}
//if ((extrudeDirectionOverride.HasValue && extrudeDirectionOverride.Value.magnitude != 0) || factor != 0)
that.WeldVertices();
if (capScale != 1.0f)
that.Scale(capScale, Center.Face);
return new FaceSelection(sideFaces, that.Owner);
}
}
}