Browse Source

Expose Node and Nested Document adjustments

flabbet 1 month ago
parent
commit
547123c549

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Brushes/BrushEngine.cs

@@ -97,7 +97,7 @@ public class BrushEngine : IDisposable
             target.EnqueueClear();
             target.EnqueueClear();
         }
         }
 
 
-        if (requiresSampleTexture)
+        if (requiresSampleTexture && rect.Width > 0 && rect.Height > 0)
         {
         {
             surfaceUnderRect = UpdateSurfaceUnderRect(target, rect, colorSpace, brushNode.AllowSampleStacking.Value);
             surfaceUnderRect = UpdateSurfaceUnderRect(target, rect, colorSpace, brushNode.AllowSampleStacking.Value);
         }
         }

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Interfaces/IReadOnlyNodeGraph.cs

@@ -20,5 +20,5 @@ public interface IReadOnlyNodeGraph : ICacheable, IDisposable
     Queue<IReadOnlyNode> CalculateExecutionQueue(IReadOnlyNode endNode);
     Queue<IReadOnlyNode> CalculateExecutionQueue(IReadOnlyNode endNode);
     public IReadOnlyNodeGraph Clone();
     public IReadOnlyNodeGraph Clone();
     public event Action<NodeOutputsChanged_ChangeInfo> NodeOutputsChanged;
     public event Action<NodeOutputsChanged_ChangeInfo> NodeOutputsChanged;
-    public void Execute(IEnumerable<IReadOnlyNode> exposeVariableNodes, RenderContext context);
+    public void Execute(IEnumerable<IReadOnlyNode> nodes, RenderContext context);
 }
 }

+ 2 - 2
src/PixiEditor.ChangeableDocument/Changeables/Graph/NodeGraph.cs

@@ -184,13 +184,13 @@ public class NodeGraph : IReadOnlyNodeGraph
         Execute(OutputNode, context);
         Execute(OutputNode, context);
     }
     }
 
 
-    public void Execute(IEnumerable<IReadOnlyNode> exposeVariableNodes, RenderContext context)
+    public void Execute(IEnumerable<IReadOnlyNode> nodes, RenderContext context)
     {
     {
         isExecuting = true;
         isExecuting = true;
         if (!CanExecute()) return;
         if (!CanExecute()) return;
 
 
         HashSet<IReadOnlyNode> executedNodes = new();
         HashSet<IReadOnlyNode> executedNodes = new();
-        foreach (var exposeVariableNode in exposeVariableNodes)
+        foreach (var exposeVariableNode in nodes)
         {
         {
             var queue = CalculateExecutionQueueInternal(exposeVariableNode);
             var queue = CalculateExecutionQueueInternal(exposeVariableNode);
 
 

+ 89 - 34
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/NestedDocumentNode.cs

@@ -1,6 +1,7 @@
 using Drawie.Backend.Core;
 using Drawie.Backend.Core;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces;
+using Drawie.Backend.Core.Surfaces.ImageData;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Numerics;
 using Drawie.Numerics;
 using PixiEditor.ChangeableDocument.Changeables.Animations;
 using PixiEditor.ChangeableDocument.Changeables.Animations;
@@ -37,6 +38,9 @@ public class NestedDocumentNode : LayerNode, IInputDependentOutputs, ITransforma
     private string[] builtInOutputs;
     private string[] builtInOutputs;
     private string[] builtInInputs;
     private string[] builtInInputs;
 
 
+    private ExposeValueNode[]? cachedExposeNodes;
+    private BrushOutputNode[]? brushOutputNodes;
+
     public NestedDocumentNode()
     public NestedDocumentNode()
     {
     {
         NestedDocument = CreateInput<DocumentReference>("Document", "DOCUMENT", null)
         NestedDocument = CreateInput<DocumentReference>("Document", "DOCUMENT", null)
@@ -67,25 +71,47 @@ public class NestedDocumentNode : LayerNode, IInputDependentOutputs, ITransforma
         if (document?.DocumentInstance == null)
         if (document?.DocumentInstance == null)
         {
         {
             ClearOutputProperties();
             ClearOutputProperties();
+            ClearInputProperties();
+            cachedExposeNodes = null;
             return;
             return;
         }
         }
+        
+        cachedExposeNodes = document.DocumentInstance.NodeGraph.AllNodes
+            .OfType<ExposeValueNode>().ToArray();
+        
+        brushOutputNodes = document.DocumentInstance.NodeGraph.AllNodes
+            .OfType<BrushOutputNode>().ToArray();
+        
+        Instance?.NodeGraph.Execute(cachedExposeNodes.Concat<IReadOnlyNode>(brushOutputNodes), new RenderContext(
+            (dummyTexture ??= Texture.ForProcessing(VecI.One, Instance.ProcessingColorSpace)).DrawingSurface.Canvas, 0, ChunkResolution.Full,
+            Instance.Size, Instance.Size,
+            Instance.ProcessingColorSpace,
+            SamplingOptions.Default,
+            Instance.NodeGraph) { FullRerender = true });
 
 
-        var brushOutput = document.DocumentInstance.NodeGraph.AllNodes.OfType<BrushOutputNode>().FirstOrDefault();
+        foreach (var input in cachedExposeNodes)
+        {
+            if (input.Name.Value == Output.InternalPropertyName)
+                continue;
 
 
+            if (OutputProperties.Any(x =>
+                    x.InternalPropertyName == input.Name.Value))
+                continue;
 
 
-        if (brushOutput != null)
+            AddOutputProperty(new OutputProperty(this, input.Name.Value, input.Name.Value, input.Value.Value,
+                input.Value.Value?.GetType() ?? typeof(object)));
+        }
+        
+        foreach (var brushOutput in brushOutputNodes)
         {
         {
-            foreach (var input in brushOutput.InputProperties)
-            {
-                if (input.InternalPropertyName == Output.InternalPropertyName)
-                    continue;
-
-                if (OutputProperties.Any(x =>
-                        x.InternalPropertyName == input.InternalPropertyName && x.ValueType == input.ValueType))
-                    continue;
+            if (OutputProperties.Any(x =>
+                    brushOutput.InputProperties.Any(prop => $"{brushOutput.BrushName}_{prop.InternalPropertyName}" == x.InternalPropertyName)))
+                continue;
 
 
-                AddOutputProperty(new OutputProperty(this, input.InternalPropertyName, input.DisplayName, input.Value,
-                    input.ValueType));
+            foreach (var output in brushOutput.InputProperties)
+            {
+                AddOutputProperty(new OutputProperty(this, $"{brushOutput.BrushName}_{output.InternalPropertyName}", output.DisplayName,
+                    output.Value, output.ValueType));
             }
             }
         }
         }
 
 
@@ -105,22 +131,29 @@ public class NestedDocumentNode : LayerNode, IInputDependentOutputs, ITransforma
             if (builtInOutputs.Contains(output.InternalPropertyName))
             if (builtInOutputs.Contains(output.InternalPropertyName))
                 continue;
                 continue;
 
 
-            bool shouldRemove = false;
-            if (brushOutput != null)
+            bool shouldRemove = cachedExposeNodes.All(x => x.Name.Value != output.InternalPropertyName) &&
+                                brushOutputNodes.All(brushOutput => brushOutput.InputProperties
+                                    .All(prop => $"{brushOutput.BrushName}_{prop.InternalPropertyName}" != output.InternalPropertyName));
+            
+            if (shouldRemove)
             {
             {
-                var correspondingInput = brushOutput.InputProperties.FirstOrDefault(x =>
-                    x.InternalPropertyName == output.InternalPropertyName && x.ValueType == output.ValueType);
-                shouldRemove = correspondingInput is null;
+                RemoveOutputProperty(output);
             }
             }
+        }
+        
+        for (int i = InputProperties.Count - 1; i >= 0; i--)
+        {
+            var input = InputProperties[i];
+            if (builtInInputs.Contains(input.InternalPropertyName))
+                continue;
 
 
-            if (!shouldRemove)
+            bool shouldRemove = document.DocumentInstance.NodeGraph.Blackboard.Variables
+                .All(x => x.Key != input.InternalPropertyName ||
+                          x.Value.Type != input.ValueType);
+            
+            if (shouldRemove)
             {
             {
-                bool variableExists = document.DocumentInstance.NodeGraph.Blackboard.Variables
-                    .Any(x => x.Key == output.InternalPropertyName && x.Value.Type == output.ValueType);
-                if (variableExists)
-                    continue;
-
-                RemoveOutputProperty(output);
+                RemoveInputProperty(input);
             }
             }
         }
         }
     }
     }
@@ -135,6 +168,17 @@ public class NestedDocumentNode : LayerNode, IInputDependentOutputs, ITransforma
             RemoveOutputProperty(property);
             RemoveOutputProperty(property);
         }
         }
     }
     }
+    
+    private void ClearInputProperties()
+    {
+        var toRemove = InputProperties
+            .Where(x => !builtInInputs.Contains(x.InternalPropertyName))
+            .ToList();
+        foreach (var property in toRemove)
+        {
+            RemoveInputProperty(property);
+        }
+    }
 
 
     protected override void OnExecute(RenderContext context)
     protected override void OnExecute(RenderContext context)
     {
     {
@@ -143,7 +187,7 @@ public class NestedDocumentNode : LayerNode, IInputDependentOutputs, ITransforma
         if (Instance is null)
         if (Instance is null)
             return;
             return;
 
 
-        if (Instance != lastDocument)
+        if (Instance != lastDocument?.DocumentInstance)
         {
         {
             lastDocument = NestedDocument.Value;
             lastDocument = NestedDocument.Value;
             DocumentChanged(NestedDocument.Value);
             DocumentChanged(NestedDocument.Value);
@@ -160,36 +204,47 @@ public class NestedDocumentNode : LayerNode, IInputDependentOutputs, ITransforma
                 (dummyTexture ??= Texture.ForProcessing(new VecI(1, 1), context.ProcessingColorSpace)).DrawingSurface
                 (dummyTexture ??= Texture.ForProcessing(new VecI(1, 1), context.ProcessingColorSpace)).DrawingSurface
                 .Canvas;
                 .Canvas;
 
 
-            var exposeVariableNodes = Instance?.NodeGraph.AllNodes
-                .OfType<ExposeVariableNode>().ToArray();
-            
-            Instance?.NodeGraph.Execute(exposeVariableNodes, clonedContext);
+            Instance?.NodeGraph.Execute(cachedExposeNodes.Concat<IReadOnlyNode>(brushOutputNodes), clonedContext);
 
 
             foreach (var output in OutputProperties)
             foreach (var output in OutputProperties)
             {
             {
                 if (output.InternalPropertyName == Output.InternalPropertyName)
                 if (output.InternalPropertyName == Output.InternalPropertyName)
                     continue;
                     continue;
 
 
-                var correspondingExposeNode = exposeVariableNodes?
+                var correspondingExposeNode = cachedExposeNodes?
                     .FirstOrDefault(x => x.Name.Value == output.InternalPropertyName &&
                     .FirstOrDefault(x => x.Name.Value == output.InternalPropertyName &&
                                          x.Value.ValueType == output.ValueType);
                                          x.Value.ValueType == output.ValueType);
 
 
                 if (correspondingExposeNode is null)
                 if (correspondingExposeNode is null)
+                {
+                    var correspondingBrushNode = brushOutputNodes?
+                        .FirstOrDefault(brushOutput => brushOutput.InputProperties
+                            .Any(prop => $"{brushOutput.BrushName}_{prop.InternalPropertyName}" == output.InternalPropertyName &&
+                                         prop.ValueType == output.ValueType));
+                    if (correspondingBrushNode is not null)
+                    {
+                        var correspondingProp = correspondingBrushNode.InputProperties
+                            .First(prop => $"{correspondingBrushNode.BrushName}_{prop.InternalPropertyName}" == output.InternalPropertyName &&
+                                           prop.ValueType == output.ValueType);
+                        output.Value = correspondingProp.Value;
+                    }
+                    
                     continue;
                     continue;
+                }
 
 
-                output.Value = correspondingExposeNode.Value;
+                output.Value = correspondingExposeNode.Value.Value;
             }
             }
         }
         }
-        
+
         foreach (var blackboardVariable in Instance?.NodeGraph.Blackboard.Variables)
         foreach (var blackboardVariable in Instance?.NodeGraph.Blackboard.Variables)
         {
         {
             var input = InputProperties.FirstOrDefault(x =>
             var input = InputProperties.FirstOrDefault(x =>
                 x.InternalPropertyName == blackboardVariable.Key &&
                 x.InternalPropertyName == blackboardVariable.Key &&
                 x.ValueType == blackboardVariable.Value.Type);
                 x.ValueType == blackboardVariable.Value.Type);
-                
+
             if (input is null || blackboardVariable.Value is not Variable variable)
             if (input is null || blackboardVariable.Value is not Variable variable)
                 continue;
                 continue;
-                
+
             variable.Value = input.Value;
             variable.Value = input.Value;
         }
         }
 
 

+ 4 - 4
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Workspace/ExposeVariableNode.cs → src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Workspace/ExposeValueNode.cs

@@ -2,13 +2,13 @@
 
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Workspace;
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Workspace;
 
 
-[NodeInfo("ExposeVariable")]
-public class ExposeVariableNode : Node
+[NodeInfo("ExposeValue")]
+public class ExposeValueNode : Node
 {
 {
     public InputProperty<string> Name { get; }
     public InputProperty<string> Name { get; }
     public InputProperty<object?> Value { get; }
     public InputProperty<object?> Value { get; }
 
 
-    public ExposeVariableNode()
+    public ExposeValueNode()
     {
     {
         Name = CreateInput<string>("Name", "NAME", "");
         Name = CreateInput<string>("Name", "NAME", "");
         Value = CreateInput<object?>("Input", "INPUT", null);
         Value = CreateInput<object?>("Input", "INPUT", null);
@@ -21,6 +21,6 @@ public class ExposeVariableNode : Node
 
 
     public override Node CreateCopy()
     public override Node CreateCopy()
     {
     {
-        return new ExposeVariableNode();
+        return new ExposeValueNode();
     }
     }
 }
 }

BIN
src/PixiEditor/Data/BrushTools/Brightness.pixi


+ 2 - 2
src/PixiEditor/ViewModels/Document/Nodes/Workspace/ExposeVariableNodeViewModel.cs → src/PixiEditor/ViewModels/Document/Nodes/Workspace/ExposeValueNodeViewModel.cs

@@ -3,8 +3,8 @@ using PixiEditor.ViewModels.Nodes;
 
 
 namespace PixiEditor.ViewModels.Document.Nodes.Workspace;
 namespace PixiEditor.ViewModels.Document.Nodes.Workspace;
 
 
-[NodeViewModel("EXPOSE_VARIABLE_NODE", "WORKSPACE", null)]
-internal class ExposeVariableNodeViewModel : NodeViewModel<ExposeVariableNode>
+[NodeViewModel("EXPOSE_VALUE_NODE", "WORKSPACE", null)]
+internal class ExposeValueNodeViewModel : NodeViewModel<ExposeValueNode>
 {
 {
     
     
 }
 }