using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.Polybrush;
namespace UnityEditor.Polybrush
{
///
/// Base class for brush modes that modify the mesh.
///
[System.Serializable]
internal abstract class BrushModeMesh : BrushMode
{
// All meshes that have ever been modified, ever. Kept around to refresh mesh vertices
// on Undo/Redo since Unity doesn't.
private HashSet modifiedMeshes = new HashSet();
private HashSet modifiedPbMeshes = new HashSet();
internal override void OnBrushBeginApply(BrushTarget brushTarget, BrushSettings brushSettings)
{
base.OnBrushBeginApply(brushTarget, brushSettings);
}
internal override void OnBrushApply(BrushTarget brushTarget, BrushSettings brushSettings)
{
// false means no ToMesh or Refresh, true does. Optional addl bool runs pb_Object.Optimize()
brushTarget.editableObject.Apply(true);
if (ProBuilderBridge.ProBuilderExists() && brushTarget.editableObject.isProBuilderObject)
ProBuilderBridge.Refresh(brushTarget.gameObject);
UpdateTempComponent(brushTarget, brushSettings);
}
internal override void RegisterUndo(BrushTarget brushTarget)
{
if (ProBuilderBridge.IsValidProBuilderMesh(brushTarget.gameObject))
{
UnityEngine.Object pbMesh = ProBuilderBridge.GetProBuilderComponent(brushTarget.gameObject);
if (pbMesh != null)
{
Undo.RegisterCompleteObjectUndo(pbMesh, UndoMessage);
modifiedPbMeshes.Add(brushTarget.gameObject);
}
else
{
Undo.RegisterCompleteObjectUndo(brushTarget.editableObject.polybrushMesh, UndoMessage);
modifiedMeshes.Add(brushTarget.editableObject.polybrushMesh.polyMesh);
}
}
else
{
Undo.RegisterCompleteObjectUndo(brushTarget.editableObject.polybrushMesh, UndoMessage);
modifiedMeshes.Add(brushTarget.editableObject.polybrushMesh.polyMesh);
}
brushTarget.editableObject.isDirty = true;
}
internal override void UndoRedoPerformed(List modified)
{
modifiedMeshes = new HashSet(modifiedMeshes.Where(x => x != null));
if (ProBuilderBridge.ProBuilderExists())
{
// delete & undo causes cases where object is not null but the reference to it's pb_Object is
HashSet remove = new HashSet();
foreach (GameObject pb in modifiedPbMeshes)
{
try
{
ProBuilderBridge.ToMesh(pb);
ProBuilderBridge.Refresh(pb);
ProBuilderBridge.Optimize(pb);
}
catch
{
remove.Add(pb);
}
}
if (remove.Count() > 0)
modifiedPbMeshes.SymmetricExceptWith(remove);
}
foreach (PolyMesh m in modifiedMeshes)
{
m.UpdateMeshFromData();
}
base.UndoRedoPerformed(modified);
}
}
}