Browse Source

Added node preview render filtering

flabbet 10 months ago
parent
commit
ee5c51ee63

+ 2 - 1
src/PixiEditor/Models/DocumentModels/ActionAccumulator.cs

@@ -114,7 +114,8 @@ internal class ActionAccumulator
                     undoBoundaryPassed || viewportRefreshRequest);
                     undoBoundaryPassed || viewportRefreshRequest);
             }
             }
 
 
-            previewUpdater.UpdatePreviews(undoBoundaryPassed, affectedAreas.ImagePreviewAreas.Keys, affectedAreas.MaskPreviewAreas.Keys);
+            previewUpdater.UpdatePreviews(undoBoundaryPassed, affectedAreas.ImagePreviewAreas.Keys, affectedAreas.MaskPreviewAreas.Keys,
+                affectedAreas.ChangedNodes);
 
 
             // force refresh viewports for better responsiveness
             // force refresh viewports for better responsiveness
             foreach (var (_, value) in internals.State.Viewports)
             foreach (var (_, value) in internals.State.Viewports)

+ 28 - 2
src/PixiEditor/Models/Rendering/AffectedAreasGatherer.cs

@@ -33,6 +33,7 @@ internal class AffectedAreasGatherer
     
     
 
 
     private KeyFrameTime ActiveFrame { get; set; }
     private KeyFrameTime ActiveFrame { get; set; }
+    public List<Guid> ChangedNodes { get; set; } = new();
 
 
     public AffectedAreasGatherer(KeyFrameTime activeFrame, DocumentChangeTracker tracker,
     public AffectedAreasGatherer(KeyFrameTime activeFrame, DocumentChangeTracker tracker,
         IReadOnlyList<IChangeInfo> changes)
         IReadOnlyList<IChangeInfo> changes)
@@ -64,21 +65,25 @@ internal class AffectedAreasGatherer
                     AddToMainImage(info.Area);
                     AddToMainImage(info.Area);
                     AddToImagePreviews(info.Id, info.Area, true);
                     AddToImagePreviews(info.Id, info.Area, true);
                     AddToMaskPreview(info.Id, info.Area);
                     AddToMaskPreview(info.Id, info.Area);
+                    AddToNodePreviews(info.Id);
                     break;
                     break;
                 case LayerImageArea_ChangeInfo info:
                 case LayerImageArea_ChangeInfo info:
                     if (info.Area.Chunks is null)
                     if (info.Area.Chunks is null)
                         throw new InvalidOperationException("Chunks must not be null");
                         throw new InvalidOperationException("Chunks must not be null");
                     AddToMainImage(info.Area);
                     AddToMainImage(info.Area);
                     AddToImagePreviews(info.Id, info.Area);
                     AddToImagePreviews(info.Id, info.Area);
+                    AddToNodePreviews(info.Id);
                     break;
                     break;
                 case TransformObject_ChangeInfo info:
                 case TransformObject_ChangeInfo info:
                     AddToMainImage(info.Area);
                     AddToMainImage(info.Area);
                     AddToImagePreviews(info.NodeGuid, info.Area);
                     AddToImagePreviews(info.NodeGuid, info.Area);
+                    AddToNodePreviews(info.NodeGuid);
                     break;
                     break;
                 case CreateStructureMember_ChangeInfo info:
                 case CreateStructureMember_ChangeInfo info:
                     AddAllToMainImage(info.Id, 0);
                     AddAllToMainImage(info.Id, 0);
                     AddAllToImagePreviews(info.Id, 0);
                     AddAllToImagePreviews(info.Id, 0);
                     AddAllToMaskPreview(info.Id);
                     AddAllToMaskPreview(info.Id);
+                    AddToNodePreviews(info.Id);
                     break;
                     break;
                 case DeleteStructureMember_ChangeInfo info:
                 case DeleteStructureMember_ChangeInfo info:
                     AddWholeCanvasToMainImage();
                     AddWholeCanvasToMainImage();
@@ -100,26 +105,32 @@ internal class AffectedAreasGatherer
                     AddWholeCanvasToMainImage();
                     AddWholeCanvasToMainImage();
                     AddWholeCanvasToMaskPreview(info.Id);
                     AddWholeCanvasToMaskPreview(info.Id);
                     AddWholeCanvasToImagePreviews(info.Id, true);
                     AddWholeCanvasToImagePreviews(info.Id, true);
+                    AddToNodePreviews(info.Id);
                     break;
                     break;
                 case StructureMemberBlendMode_ChangeInfo info:
                 case StructureMemberBlendMode_ChangeInfo info:
                     AddAllToMainImage(info.Id, ActiveFrame);
                     AddAllToMainImage(info.Id, ActiveFrame);
                     AddAllToImagePreviews(info.Id, ActiveFrame, true);
                     AddAllToImagePreviews(info.Id, ActiveFrame, true);
+                    AddToNodePreviews(info.Id);
                     break;
                     break;
                 case StructureMemberClipToMemberBelow_ChangeInfo info:
                 case StructureMemberClipToMemberBelow_ChangeInfo info:
                     AddAllToMainImage(info.Id, ActiveFrame);
                     AddAllToMainImage(info.Id, ActiveFrame);
                     AddAllToImagePreviews(info.Id, ActiveFrame, true);
                     AddAllToImagePreviews(info.Id, ActiveFrame, true);
+                    AddToNodePreviews(info.Id);
                     break;
                     break;
                 case StructureMemberOpacity_ChangeInfo info:
                 case StructureMemberOpacity_ChangeInfo info:
                     AddAllToMainImage(info.Id, ActiveFrame);
                     AddAllToMainImage(info.Id, ActiveFrame);
                     AddAllToImagePreviews(info.Id, ActiveFrame, true);
                     AddAllToImagePreviews(info.Id, ActiveFrame, true);
+                    AddToNodePreviews(info.Id);
                     break;
                     break;
                 case StructureMemberIsVisible_ChangeInfo info:
                 case StructureMemberIsVisible_ChangeInfo info:
                     AddAllToMainImage(info.Id, ActiveFrame);
                     AddAllToMainImage(info.Id, ActiveFrame);
                     AddAllToImagePreviews(info.Id, ActiveFrame, true);
                     AddAllToImagePreviews(info.Id, ActiveFrame, true);
+                    AddToNodePreviews(info.Id);
                     break;
                     break;
                 case StructureMemberMaskIsVisible_ChangeInfo info:
                 case StructureMemberMaskIsVisible_ChangeInfo info:
                     AddAllToMainImage(info.Id, ActiveFrame, false);
                     AddAllToMainImage(info.Id, ActiveFrame, false);
                     AddAllToImagePreviews(info.Id, ActiveFrame, true);
                     AddAllToImagePreviews(info.Id, ActiveFrame, true);
+                    AddToNodePreviews(info.Id);
                     break;
                     break;
                 case CreateRasterKeyFrame_ChangeInfo info:
                 case CreateRasterKeyFrame_ChangeInfo info:
                     if (info.CloneFromExisting)
                     if (info.CloneFromExisting)
@@ -150,13 +161,20 @@ internal class AffectedAreasGatherer
                     AddWholeCanvasToMainImage();
                     AddWholeCanvasToMainImage();
                     AddWholeCanvasToEveryImagePreview();
                     AddWholeCanvasToEveryImagePreview();
                     break;
                     break;
-                case ConnectProperty_ChangeInfo:
+                case ConnectProperty_ChangeInfo info:
                     AddWholeCanvasToMainImage();
                     AddWholeCanvasToMainImage();
                     AddWholeCanvasToEveryImagePreview();
                     AddWholeCanvasToEveryImagePreview();
+                    AddToNodePreviews(info.InputNodeId);
+                    if (info.OutputNodeId.HasValue)
+                    {
+                        AddToNodePreviews(info.OutputNodeId.Value);
+                    }
+                    
                     break;
                     break;
-                case PropertyValueUpdated_ChangeInfo:
+                case PropertyValueUpdated_ChangeInfo info:
                     AddWholeCanvasToMainImage();
                     AddWholeCanvasToMainImage();
                     AddWholeCanvasToEveryImagePreview();
                     AddWholeCanvasToEveryImagePreview();
+                    AddToNodePreviews(info.NodeId);
                     break;
                     break;
                 case ToggleOnionSkinning_PassthroughAction:
                 case ToggleOnionSkinning_PassthroughAction:
                     AddWholeCanvasToMainImage();
                     AddWholeCanvasToMainImage();
@@ -167,11 +185,19 @@ internal class AffectedAreasGatherer
                 case VectorShape_ChangeInfo info:
                 case VectorShape_ChangeInfo info:
                     AddToMainImage(info.Affected);
                     AddToMainImage(info.Affected);
                     AddToImagePreviews(info.LayerId, info.Affected);
                     AddToImagePreviews(info.LayerId, info.Affected);
+                    AddToNodePreviews(info.LayerId);
                     break;
                     break;
             }
             }
         }
         }
     }
     }
 
 
+    private void AddToNodePreviews(Guid nodeId)
+    {
+        ChangedNodes ??= new List<Guid>();
+        if (!ChangedNodes.Contains(nodeId))
+            ChangedNodes.Add(nodeId);
+    }
+
     private void AddAllToImagePreviews(Guid memberGuid, KeyFrameTime frame, bool ignoreSelf = false)
     private void AddAllToImagePreviews(Guid memberGuid, KeyFrameTime frame, bool ignoreSelf = false)
     {
     {
         var member = tracker.Document.FindMember(memberGuid);
         var member = tracker.Document.FindMember(memberGuid);

+ 10 - 5
src/PixiEditor/Models/Rendering/MemberPreviewUpdater.cs

@@ -28,12 +28,12 @@ internal class MemberPreviewUpdater
     }
     }
 
 
     public void UpdatePreviews(bool rerenderPreviews, IEnumerable<Guid> membersToUpdate,
     public void UpdatePreviews(bool rerenderPreviews, IEnumerable<Guid> membersToUpdate,
-        IEnumerable<Guid> masksToUpdate)
+        IEnumerable<Guid> masksToUpdate, IEnumerable<Guid> nodesToUpdate)
     {
     {
         if (!rerenderPreviews)
         if (!rerenderPreviews)
             return;
             return;
 
 
-        UpdatePreviewPainters(membersToUpdate, masksToUpdate);
+        UpdatePreviewPainters(membersToUpdate, masksToUpdate, nodesToUpdate);
     }
     }
 
 
     /// <summary>
     /// <summary>
@@ -41,14 +41,16 @@ internal class MemberPreviewUpdater
     /// </summary>
     /// </summary>
     /// <param name="members">Members that should be rendered</param>
     /// <param name="members">Members that should be rendered</param>
     /// <param name="masksToUpdate">Masks that should be rendered</param>
     /// <param name="masksToUpdate">Masks that should be rendered</param>
-    private void UpdatePreviewPainters(IEnumerable<Guid> members, IEnumerable<Guid> masksToUpdate)
+    private void UpdatePreviewPainters(IEnumerable<Guid> members, IEnumerable<Guid> masksToUpdate, IEnumerable<Guid> nodesToUpdate)
     {
     {
         Guid[] memberGuids = members as Guid[] ?? members.ToArray();
         Guid[] memberGuids = members as Guid[] ?? members.ToArray();
         Guid[] maskGuids = masksToUpdate as Guid[] ?? masksToUpdate.ToArray();
         Guid[] maskGuids = masksToUpdate as Guid[] ?? masksToUpdate.ToArray();
+        Guid[] nodesGuids = nodesToUpdate as Guid[] ?? nodesToUpdate.ToArray();
+        
         RenderWholeCanvasPreview();
         RenderWholeCanvasPreview();
         RenderMainPreviews(memberGuids);
         RenderMainPreviews(memberGuids);
         RenderMaskPreviews(maskGuids);
         RenderMaskPreviews(maskGuids);
-        RenderNodePreviews(); //TODO: maybe find nodes to render, instead of rendering all?
+        RenderNodePreviews(nodesGuids);
     }
     }
 
 
     /// <summary>
     /// <summary>
@@ -222,7 +224,7 @@ internal class MemberPreviewUpdater
         }
         }
     }
     }
 
 
-    private void RenderNodePreviews()
+    private void RenderNodePreviews(Guid[] nodesGuids)
     {
     {
         var outputNode = internals.Tracker.Document.NodeGraph.OutputNode;
         var outputNode = internals.Tracker.Document.NodeGraph.OutputNode;
 
 
@@ -237,6 +239,9 @@ internal class MemberPreviewUpdater
         {
         {
             if (node is null)
             if (node is null)
                 continue;
                 continue;
+            
+            if (!nodesGuids.Contains(node.Id))
+                continue;
 
 
             var nodeVm = doc.StructureHelper.FindNode<INodeHandler>(node.Id);
             var nodeVm = doc.StructureHelper.FindNode<INodeHandler>(node.Id);
 
 

+ 31 - 5
src/PixiEditor/Views/Nodes/NodeView.cs

@@ -36,14 +36,16 @@ public class NodeView : TemplatedControl
         AvaloniaProperty.Register<NodeView, ObservableRangeCollection<INodePropertyHandler>>(
         AvaloniaProperty.Register<NodeView, ObservableRangeCollection<INodePropertyHandler>>(
             nameof(Outputs));
             nameof(Outputs));
 
 
-    public static readonly StyledProperty<PreviewPainter> ResultPreviewProperty = AvaloniaProperty.Register<NodeView, PreviewPainter>(
-        nameof(ResultPreview));
+    public static readonly StyledProperty<PreviewPainter> ResultPreviewProperty =
+        AvaloniaProperty.Register<NodeView, PreviewPainter>(
+            nameof(ResultPreview));
 
 
     public static readonly StyledProperty<bool> IsSelectedProperty = AvaloniaProperty.Register<NodeView, bool>(
     public static readonly StyledProperty<bool> IsSelectedProperty = AvaloniaProperty.Register<NodeView, bool>(
         nameof(IsSelected));
         nameof(IsSelected));
 
 
-    public static readonly StyledProperty<IBrush> CategoryBackgroundBrushProperty = AvaloniaProperty.Register<NodeView, IBrush>(
-        nameof(CategoryBackgroundBrush));
+    public static readonly StyledProperty<IBrush> CategoryBackgroundBrushProperty =
+        AvaloniaProperty.Register<NodeView, IBrush>(
+            nameof(CategoryBackgroundBrush));
 
 
     public static readonly StyledProperty<ICommand> SelectNodeCommandProperty =
     public static readonly StyledProperty<ICommand> SelectNodeCommandProperty =
         AvaloniaProperty.Register<NodeView, ICommand>("SelectNodeCommand");
         AvaloniaProperty.Register<NodeView, ICommand>("SelectNodeCommand");
@@ -140,11 +142,14 @@ public class NodeView : TemplatedControl
     }
     }
 
 
     private bool captured;
     private bool captured;
-    public static readonly StyledProperty<int> ActiveFrameProperty = AvaloniaProperty.Register<NodeView, int>("ActiveFrame");
+
+    public static readonly StyledProperty<int> ActiveFrameProperty =
+        AvaloniaProperty.Register<NodeView, int>("ActiveFrame");
 
 
     static NodeView()
     static NodeView()
     {
     {
         IsSelectedProperty.Changed.Subscribe(NodeSelectionChanged);
         IsSelectedProperty.Changed.Subscribe(NodeSelectionChanged);
+        ResultPreviewProperty.Changed.Subscribe(PreviewPainterChanged);
     }
     }
 
 
     protected override void OnPointerPressed(PointerPressedEventArgs e)
     protected override void OnPointerPressed(PointerPressedEventArgs e)
@@ -251,4 +256,25 @@ public class NodeView : TemplatedControl
             nodeView.PseudoClasses.Set(":selected", e.NewValue.Value);
             nodeView.PseudoClasses.Set(":selected", e.NewValue.Value);
         }
         }
     }
     }
+
+    private static void PreviewPainterChanged(AvaloniaPropertyChangedEventArgs<PreviewPainter> e)
+    {
+        if (e.Sender is NodeView nodeView)
+        {
+            if (e.OldValue.Value != null)
+            {
+                e.OldValue.Value.RequestRepaint -= nodeView.OnPainterRenderRequest;
+            }
+
+            if (e.NewValue.Value != null)
+            {
+                e.NewValue.Value.RequestRepaint += nodeView.OnPainterRenderRequest;
+            }
+        }
+    }
+    
+    private void OnPainterRenderRequest()
+    {
+        InvalidateVisual();
+    }
 }
 }