Made outline around errored node as well as fixed NativeArray on texture import being disposed
This commit is contained in:
parent
c24a52bee8
commit
499d187c96
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
using UnityEditor.Experimental.GraphView;
|
using UnityEditor.Experimental.GraphView;
|
||||||
using UnityEngine.UIElements;
|
using UnityEngine.UIElements;
|
||||||
|
|
||||||
@ -6,6 +7,8 @@ namespace ImageProcessingGraph.Editor
|
|||||||
{
|
{
|
||||||
public class IPTPort : Port
|
public class IPTPort : Port
|
||||||
{
|
{
|
||||||
|
public FieldInfo fieldInfo;
|
||||||
|
|
||||||
protected IPTPort(Orientation portOrientation, Direction portDirection, Capacity portCapacity, Type type) : base(portOrientation, portDirection, portCapacity, type)
|
protected IPTPort(Orientation portOrientation, Direction portDirection, Capacity portCapacity, Type type) : base(portOrientation, portDirection, portCapacity, type)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ public struct ImageData
|
|||||||
/// <param name="sourceTexture">The source texture to extract pixel data from.</param>
|
/// <param name="sourceTexture">The source texture to extract pixel data from.</param>
|
||||||
public ImageData(Texture2D sourceTexture)
|
public ImageData(Texture2D sourceTexture)
|
||||||
{
|
{
|
||||||
PixelData = sourceTexture.GetPixelData<Color32>(0);
|
PixelData = new NativeArray<Color32>(sourceTexture.GetPixelData<Color32>(0), Allocator.Persistent);
|
||||||
Dimensions = (sourceTexture.width, sourceTexture.height);
|
Dimensions = (sourceTexture.width, sourceTexture.height);
|
||||||
isRGBA = sourceTexture.format == TextureFormat.RGBA32;
|
isRGBA = sourceTexture.format == TextureFormat.RGBA32;
|
||||||
}
|
}
|
||||||
@ -70,7 +70,7 @@ public struct ImageData
|
|||||||
byte[] data = texture.EncodeToPNG();
|
byte[] data = texture.EncodeToPNG();
|
||||||
string thePath;
|
string thePath;
|
||||||
|
|
||||||
if (path.StartsWith("Assets\\"))
|
if (path.StartsWith("Assets/"))
|
||||||
{
|
{
|
||||||
thePath = path.Substring("Assets/".Length);
|
thePath = path.Substring("Assets/".Length);
|
||||||
}
|
}
|
||||||
@ -79,6 +79,8 @@ public struct ImageData
|
|||||||
thePath = path;
|
thePath = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thePath.Replace("/", "\\");
|
||||||
|
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
System.IO.File.WriteAllBytes(Path.Combine(Application.dataPath, thePath), data);
|
System.IO.File.WriteAllBytes(Path.Combine(Application.dataPath, thePath), data);
|
||||||
|
@ -21,6 +21,11 @@ namespace ImageProcessingGraph.Editor
|
|||||||
|
|
||||||
public List<BaseImageNode> Nodes => nodes;
|
public List<BaseImageNode> Nodes => nodes;
|
||||||
public List<GraphConnection> Connections => connections;
|
public List<GraphConnection> Connections => connections;
|
||||||
|
|
||||||
|
public delegate void OnRunEvent();
|
||||||
|
public event OnRunEvent OnRun;
|
||||||
|
public OnRunEvent OnRunEnd;
|
||||||
|
|
||||||
public ImageProcessingGraphAsset()
|
public ImageProcessingGraphAsset()
|
||||||
{
|
{
|
||||||
nodes = new List<BaseImageNode>();
|
nodes = new List<BaseImageNode>();
|
||||||
@ -42,6 +47,8 @@ namespace ImageProcessingGraph.Editor
|
|||||||
|
|
||||||
public void RunGraph()
|
public void RunGraph()
|
||||||
{
|
{
|
||||||
|
OnRun?.Invoke();
|
||||||
|
|
||||||
// Create and start the stopwatch to measure time
|
// Create and start the stopwatch to measure time
|
||||||
Stopwatch stopwatch = new Stopwatch();
|
Stopwatch stopwatch = new Stopwatch();
|
||||||
stopwatch.Start();
|
stopwatch.Start();
|
||||||
@ -49,9 +56,15 @@ namespace ImageProcessingGraph.Editor
|
|||||||
if (runOrder == null)
|
if (runOrder == null)
|
||||||
runOrder = GetExecutionOrder(this.nodes, this.connections);
|
runOrder = GetExecutionOrder(this.nodes, this.connections);
|
||||||
|
|
||||||
|
bool failed = false;
|
||||||
|
|
||||||
foreach (var VARIABLE in runOrder)
|
foreach (var VARIABLE in runOrder)
|
||||||
{
|
{
|
||||||
VARIABLE.RunNode();
|
if (!VARIABLE.RunNode())
|
||||||
|
{
|
||||||
|
failed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop the stopwatch after running the nodes
|
// Stop the stopwatch after running the nodes
|
||||||
|
@ -26,6 +26,9 @@ namespace ImageProcessingGraph.Editor
|
|||||||
|
|
||||||
public ImageProcessingGraphAsset asset;
|
public ImageProcessingGraphAsset asset;
|
||||||
|
|
||||||
|
public delegate void OnFailed();
|
||||||
|
public event OnFailed onFailed;
|
||||||
|
|
||||||
public BaseImageNode()
|
public BaseImageNode()
|
||||||
{
|
{
|
||||||
guid = Guid.NewGuid().ToString();
|
guid = Guid.NewGuid().ToString();
|
||||||
@ -101,10 +104,20 @@ namespace ImageProcessingGraph.Editor
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void RunNode()
|
public bool RunNode()
|
||||||
{
|
{
|
||||||
SetNodeInputs();
|
try
|
||||||
this.Process();
|
{
|
||||||
|
SetNodeInputs();
|
||||||
|
this.Process();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
onFailed?.Invoke();
|
||||||
|
Debug.LogError(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Process()
|
public virtual void Process()
|
||||||
|
@ -23,10 +23,10 @@ namespace ImageProcessingGraph.Editor.Nodes.Fun_Nodes.Texture
|
|||||||
|
|
||||||
public override void Process()
|
public override void Process()
|
||||||
{
|
{
|
||||||
int length = inputTexture.PixelData.Length;
|
int length = inputTexture.PixelData.Length;;
|
||||||
|
|
||||||
// Allocate NativeArrays for the pixel data and the individual RGBA channels
|
// Allocate NativeArrays for the pixel data and the individual RGBA channels
|
||||||
NativeArray<Color32> pixelData = new NativeArray<Color32>(inputTexture.PixelData, Allocator.Persistent);
|
NativeArray<Color32> pixelData = inputTexture.PixelData;
|
||||||
NativeArray<byte> rChannel = new NativeArray<byte>(length, Allocator.Persistent);
|
NativeArray<byte> rChannel = new NativeArray<byte>(length, Allocator.Persistent);
|
||||||
NativeArray<byte> gChannel = new NativeArray<byte>(length, Allocator.Persistent);
|
NativeArray<byte> gChannel = new NativeArray<byte>(length, Allocator.Persistent);
|
||||||
NativeArray<byte> bChannel = new NativeArray<byte>(length, Allocator.Persistent);
|
NativeArray<byte> bChannel = new NativeArray<byte>(length, Allocator.Persistent);
|
||||||
|
@ -6,7 +6,7 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace ImageProcessingGraph.Editor.Nodes.Output
|
namespace ImageProcessingGraph.Editor.Nodes.Output
|
||||||
{
|
{
|
||||||
[NodeInfo("Texture Export", "Export/Texture2D", true)]
|
[NodeInfo("Texture Export", "Export/Export Texture", true)]
|
||||||
public class Texture2DOutput : BaseImageNode
|
public class Texture2DOutput : BaseImageNode
|
||||||
{
|
{
|
||||||
[NodeAttributes.Input("")] public ImageData inputPixels;
|
[NodeAttributes.Input("")] public ImageData inputPixels;
|
||||||
|
@ -23,7 +23,7 @@ namespace ImageProcessingGraph.Editor.Nodes.Types.Image.Utilities
|
|||||||
{
|
{
|
||||||
int pixelCount = Width * Height;
|
int pixelCount = Width * Height;
|
||||||
|
|
||||||
NativeArray<byte> outputData = new NativeArray<byte>(pixelCount * 4, Allocator.TempJob);
|
NativeArray<byte> outputData = new NativeArray<byte>(pixelCount * 4, Allocator.Persistent);
|
||||||
|
|
||||||
CreateSingleColorJob job = new CreateSingleColorJob
|
CreateSingleColorJob job = new CreateSingleColorJob
|
||||||
{
|
{
|
||||||
@ -36,8 +36,6 @@ namespace ImageProcessingGraph.Editor.Nodes.Types.Image.Utilities
|
|||||||
job.Run();
|
job.Run();
|
||||||
|
|
||||||
OutputColor = new SplitChannelData(outputData.ToArray(), (Width, Height));
|
OutputColor = new SplitChannelData(outputData.ToArray(), (Width, Height));
|
||||||
|
|
||||||
outputData.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BurstCompile]
|
[BurstCompile]
|
||||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using ImageProcessingGraph.Editor.Nodes.NodeAttributes;
|
using ImageProcessingGraph.Editor.Nodes.NodeAttributes;
|
||||||
|
using UnityEditor;
|
||||||
using UnityEditor.Experimental.GraphView;
|
using UnityEditor.Experimental.GraphView;
|
||||||
using UnityEditor.UIElements;
|
using UnityEditor.UIElements;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@ -21,6 +22,8 @@ namespace ImageProcessingGraph.Editor.Unity_Image_Processing.Scripts.Editor.Wind
|
|||||||
|
|
||||||
private ImageProcessingGraphViewWindow window;
|
private ImageProcessingGraphViewWindow window;
|
||||||
|
|
||||||
|
private StyleSheet errorStyleSheet;
|
||||||
|
|
||||||
public ImageProcessingGraphNodeVisual(BaseImageNode node, ImageProcessingGraphViewWindow window)
|
public ImageProcessingGraphNodeVisual(BaseImageNode node, ImageProcessingGraphViewWindow window)
|
||||||
{
|
{
|
||||||
this.AddToClassList("image-node-visual");
|
this.AddToClassList("image-node-visual");
|
||||||
@ -66,6 +69,24 @@ namespace ImageProcessingGraph.Editor.Unity_Image_Processing.Scripts.Editor.Wind
|
|||||||
CreateInputPorts(inputFieldInfo);
|
CreateInputPorts(inputFieldInfo);
|
||||||
CreateOutputPorts(outputFieldInfo);
|
CreateOutputPorts(outputFieldInfo);
|
||||||
|
|
||||||
|
errorStyleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/Unity Image Processing/Node.uss");
|
||||||
|
if (errorStyleSheet == null)
|
||||||
|
{
|
||||||
|
errorStyleSheet = EditorGUIUtility.Load("Packages/com.chromium.imageprocessingrah/Node.uss") as StyleSheet;
|
||||||
|
}
|
||||||
|
|
||||||
|
graphNode.onFailed += () =>
|
||||||
|
{
|
||||||
|
styleSheets.Add(errorStyleSheet);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.asset.OnRun += () =>
|
||||||
|
{
|
||||||
|
if (styleSheets.Contains(errorStyleSheet))
|
||||||
|
styleSheets.Remove(errorStyleSheet);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
this.name = typeInfo.Name;
|
this.name = typeInfo.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,10 +95,6 @@ namespace ImageProcessingGraph.Editor.Unity_Image_Processing.Scripts.Editor.Wind
|
|||||||
for (var index = 0; index < fields.Count; index++)
|
for (var index = 0; index < fields.Count; index++)
|
||||||
{
|
{
|
||||||
var field = fields[index];
|
var field = fields[index];
|
||||||
/*
|
|
||||||
Port port = InstantiatePort(Orientation.Horizontal, Direction.Input, Port.Capacity.Multi, field.FieldType);
|
|
||||||
*/
|
|
||||||
|
|
||||||
var port = IPTPort.Create(window.edgeConnectorListener, true, field.FieldType);
|
var port = IPTPort.Create(window.edgeConnectorListener, true, field.FieldType);
|
||||||
|
|
||||||
string label = field.GetCustomAttribute<Input>().Label;
|
string label = field.GetCustomAttribute<Input>().Label;
|
||||||
@ -87,6 +104,7 @@ namespace ImageProcessingGraph.Editor.Unity_Image_Processing.Scripts.Editor.Wind
|
|||||||
|
|
||||||
inputContainer.Add(port);
|
inputContainer.Add(port);
|
||||||
ExposeVariableToPort(port, field);
|
ExposeVariableToPort(port, field);
|
||||||
|
port.fieldInfo = field;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,13 +120,14 @@ namespace ImageProcessingGraph.Editor.Unity_Image_Processing.Scripts.Editor.Wind
|
|||||||
if (label != "")
|
if (label != "")
|
||||||
port.portName = label;
|
port.portName = label;
|
||||||
OutputPorts.Add(port);
|
OutputPorts.Add(port);
|
||||||
|
|
||||||
outputContainer.Add(port);
|
outputContainer.Add(port);
|
||||||
|
|
||||||
|
port.fieldInfo = field;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exposes a variable on the port for editing when it's not connected
|
// Exposes a variable on the port for editing when it's not connected
|
||||||
private void ExposeVariableToPort(Port port, FieldInfo field)
|
public void ExposeVariableToPort(Port port, FieldInfo field)
|
||||||
{
|
{
|
||||||
// Only expose when the port is not connected
|
// Only expose when the port is not connected
|
||||||
if (port.connections.Count() == 0)
|
if (port.connections.Count() == 0)
|
||||||
@ -207,6 +226,13 @@ namespace ImageProcessingGraph.Editor.Unity_Image_Processing.Scripts.Editor.Wind
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If the port is connected, remove the exposed UI element
|
// If the port is connected, remove the exposed UI element
|
||||||
|
List<VisualElement> children = new List<VisualElement>();
|
||||||
|
|
||||||
|
foreach (var child in port.Children())
|
||||||
|
{
|
||||||
|
children.Add(child);
|
||||||
|
}
|
||||||
|
|
||||||
var existingPropertyFieldContainer = port.Q<VisualElement>("property-field-container");
|
var existingPropertyFieldContainer = port.Q<VisualElement>("property-field-container");
|
||||||
if (existingPropertyFieldContainer != null)
|
if (existingPropertyFieldContainer != null)
|
||||||
{
|
{
|
||||||
|
@ -290,15 +290,34 @@ namespace ImageProcessingGraph.Editor
|
|||||||
|
|
||||||
GraphConnection connection = new GraphConnection(inputNode.GraphNode.ID,inputIndex, inputType,outputNode.GraphNode.ID, outputIndex, outputType, edge);
|
GraphConnection connection = new GraphConnection(inputNode.GraphNode.ID,inputIndex, inputType,outputNode.GraphNode.ID, outputIndex, outputType, edge);
|
||||||
|
|
||||||
|
edge.output.Connect(edge);
|
||||||
|
edge.input.Connect(edge);
|
||||||
|
|
||||||
|
IPTPort portIn = (IPTPort)edge.output;
|
||||||
|
IPTPort portOut = (IPTPort)edge.output;
|
||||||
|
|
||||||
|
if (portIn.fieldInfo != null)
|
||||||
|
inputNode.ExposeVariableToPort(edge.input, portOut.fieldInfo);
|
||||||
|
|
||||||
asset.Connections.Add(connection);
|
asset.Connections.Add(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RemoveEdge(Edge variable)
|
private void RemoveEdge(Edge edge)
|
||||||
{
|
{
|
||||||
if (connectionDictionary.TryGetValue(variable, out GraphConnection connection))
|
if (connectionDictionary.TryGetValue(edge, out GraphConnection connection))
|
||||||
{
|
{
|
||||||
asset.Connections.Remove(connection);
|
asset.Connections.Remove(connection);
|
||||||
connectionDictionary.Remove(variable);
|
connectionDictionary.Remove(edge);
|
||||||
|
|
||||||
|
edge.output.Disconnect(edge);
|
||||||
|
edge.input.Disconnect(edge);
|
||||||
|
|
||||||
|
ImageProcessingGraphNodeVisual inputNode = (ImageProcessingGraphNodeVisual)edge.input.node;
|
||||||
|
|
||||||
|
IPTPort portIn = (IPTPort)edge.input;
|
||||||
|
|
||||||
|
if(portIn.fieldInfo != null)
|
||||||
|
inputNode.ExposeVariableToPort(edge.input, portIn.fieldInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,6 +338,8 @@ namespace ImageProcessingGraph.Editor
|
|||||||
Edge edge = inPort.ConnectTo(outPort);
|
Edge edge = inPort.ConnectTo(outPort);
|
||||||
AddElement(edge);
|
AddElement(edge);
|
||||||
connectionDictionary.Add(edge, conn);
|
connectionDictionary.Add(edge, conn);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
7
Node.uss
Normal file
7
Node.uss
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#node-border
|
||||||
|
{
|
||||||
|
border-bottom-color: red;
|
||||||
|
border-left-color: red;
|
||||||
|
border-right-color: red;
|
||||||
|
border-top-color: red;
|
||||||
|
}
|
3
Node.uss.meta
Normal file
3
Node.uss.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f213bce165884ca7ae5d567d6bb7f3cb
|
||||||
|
timeCreated: 1745777804
|
Loading…
x
Reference in New Issue
Block a user