You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
6.0 KiB
C#
183 lines
6.0 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine.ProBuilder;
|
|
using UnityEngine;
|
|
using UnityEngine.ProBuilder.MeshOperations;
|
|
|
|
namespace UnityEditor.ProBuilder.Actions
|
|
{
|
|
sealed class GrowSelection : MenuAction
|
|
{
|
|
Pref<bool> m_GrowSelectionWithAngle = new Pref<bool>("GrowSelection.useAngle", true);
|
|
Pref<bool> m_GrowSelectionAngleIterative = new Pref<bool>("GrowSelection.iterativeGrow", false);
|
|
Pref<float> m_GrowSelectionAngleValue = new Pref<float>("GrowSelection.angleValue", 15f);
|
|
|
|
public override ToolbarGroup group
|
|
{
|
|
get { return ToolbarGroup.Selection; }
|
|
}
|
|
|
|
public override Texture2D icon
|
|
{
|
|
get { return IconUtility.GetIcon("Toolbar/Selection_Grow", IconSkin.Pro); }
|
|
}
|
|
|
|
public override TooltipContent tooltip
|
|
{
|
|
get { return s_Tooltip; }
|
|
}
|
|
|
|
static readonly TooltipContent s_Tooltip = new TooltipContent
|
|
(
|
|
"Grow Selection",
|
|
@"Adds adjacent elements to the current selection, optionally testing to see if they are within a specified angle.
|
|
|
|
Grow by angle is enabled by Option + Clicking the <b>Grow Selection</b> button.",
|
|
keyCommandAlt, 'G'
|
|
);
|
|
|
|
public override SelectMode validSelectModes
|
|
{
|
|
get { return SelectMode.Vertex | SelectMode.Edge | SelectMode.Face | SelectMode.TextureFace; }
|
|
}
|
|
|
|
public override bool enabled
|
|
{
|
|
get { return base.enabled && VerifyGrowSelection(); }
|
|
}
|
|
|
|
protected override MenuActionState optionsMenuState
|
|
{
|
|
get
|
|
{
|
|
if (enabled && ProBuilderEditor.selectMode == SelectMode.Face)
|
|
return MenuActionState.VisibleAndEnabled;
|
|
|
|
return MenuActionState.Hidden;
|
|
}
|
|
}
|
|
|
|
protected override void OnSettingsGUI()
|
|
{
|
|
GUILayout.Label("Grow Selection Options", EditorStyles.boldLabel);
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
m_GrowSelectionWithAngle.value = EditorGUILayout.Toggle("Restrict to Angle", m_GrowSelectionWithAngle.value);
|
|
|
|
GUI.enabled = m_GrowSelectionWithAngle;
|
|
|
|
m_GrowSelectionAngleValue.value = EditorGUILayout.FloatField("Max Angle", m_GrowSelectionAngleValue);
|
|
|
|
GUI.enabled = m_GrowSelectionWithAngle;
|
|
|
|
bool iterative = m_GrowSelectionWithAngle ? m_GrowSelectionAngleIterative : true;
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
iterative = EditorGUILayout.Toggle("Iterative", iterative);
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
m_GrowSelectionAngleIterative.value = iterative;
|
|
}
|
|
|
|
GUI.enabled = true;
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
ProBuilderSettings.Save();
|
|
|
|
GUILayout.FlexibleSpace();
|
|
|
|
if (GUILayout.Button("Grow Selection"))
|
|
PerformAction();
|
|
}
|
|
|
|
protected override ActionResult PerformActionImplementation()
|
|
{
|
|
if (MeshSelection.selectedObjectCount < 1)
|
|
return ActionResult.NoSelection;
|
|
|
|
UndoUtility.RecordSelection("Grow Selection");
|
|
|
|
int grown = 0;
|
|
bool angleGrow = m_GrowSelectionWithAngle;
|
|
bool iterative = m_GrowSelectionAngleIterative;
|
|
float growSelectionAngle = m_GrowSelectionAngleValue;
|
|
|
|
if (!angleGrow && !iterative)
|
|
iterative = true;
|
|
|
|
foreach (ProBuilderMesh pb in InternalUtility.GetComponents<ProBuilderMesh>(Selection.transforms))
|
|
{
|
|
int previousTriCount = pb.selectedVertexCount;
|
|
|
|
switch (ProBuilderEditor.selectMode)
|
|
{
|
|
case SelectMode.Vertex:
|
|
pb.SetSelectedEdges(ElementSelection.GetConnectedEdges(pb, pb.selectedIndexesInternal));
|
|
break;
|
|
|
|
case SelectMode.Edge:
|
|
pb.SetSelectedEdges(ElementSelection.GetConnectedEdges(pb, pb.selectedIndexesInternal));
|
|
break;
|
|
|
|
case SelectMode.TextureFace:
|
|
case SelectMode.Face:
|
|
|
|
Face[] selectedFaces = pb.GetSelectedFaces();
|
|
|
|
HashSet<Face> sel;
|
|
|
|
if (iterative)
|
|
{
|
|
sel = ElementSelection.GrowSelection(pb, selectedFaces, angleGrow ? growSelectionAngle : -1f);
|
|
sel.UnionWith(selectedFaces);
|
|
}
|
|
else
|
|
{
|
|
sel = ElementSelection.FloodSelection(pb, selectedFaces, angleGrow ? growSelectionAngle : -1f);
|
|
}
|
|
|
|
pb.SetSelectedFaces(sel.ToArray());
|
|
|
|
break;
|
|
}
|
|
|
|
grown += pb.selectedVertexCount - previousTriCount;
|
|
}
|
|
|
|
ProBuilderEditor.Refresh();
|
|
SceneView.RepaintAll();
|
|
|
|
if (grown > 0)
|
|
return new ActionResult(ActionResult.Status.Success, "Grow Selection");
|
|
|
|
return new ActionResult(ActionResult.Status.Failure, "Nothing to Grow");
|
|
}
|
|
|
|
static bool VerifyGrowSelection()
|
|
{
|
|
int sel, max;
|
|
|
|
switch (ProBuilderEditor.selectMode)
|
|
{
|
|
case SelectMode.Face:
|
|
sel = MeshSelection.selectedFaceCount;
|
|
max = MeshSelection.totalFaceCount;
|
|
break;
|
|
|
|
case SelectMode.Edge:
|
|
sel = MeshSelection.selectedEdgeCount;
|
|
max = MeshSelection.totalEdgeCount;
|
|
break;
|
|
|
|
default:
|
|
sel = MeshSelection.selectedVertexCount;
|
|
max = MeshSelection.totalVertexCount;
|
|
break;
|
|
}
|
|
|
|
return sel > 0 && sel < max;
|
|
}
|
|
}
|
|
}
|