Browse Source

Moved bounds inside renderable

flabbet 10 months ago
parent
commit
66ec430a33

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

@@ -6,6 +6,7 @@ namespace PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 
 public interface IPreviewRenderable
 {
+    public RectD? GetPreviewBounds(string elementToRenderName = "", int frame = 0); 
     public bool RenderPreview(DrawingSurface renderOn, ChunkResolution resolution, int frame,
         string elementToRenderName);
 }

+ 16 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/FolderNode.cs

@@ -164,9 +164,24 @@ public class FolderNode : StructureNode, IReadOnlyFolderNode, IClipSource, IPrev
         }
     }
 
-    public bool RenderPreview(DrawingSurface renderOn, ChunkResolution resolution, int frame,
+    public override RectD? GetPreviewBounds(string elementFor = "", int frame = 0)
+    {
+        if (elementFor == nameof(EmbeddedMask))
+        {
+            return base.GetPreviewBounds(elementFor);
+        }
+
+        return GetTightBounds(frame);
+    }
+
+    public override bool RenderPreview(DrawingSurface renderOn, ChunkResolution resolution, int frame,
         string elementToRenderName)
     {
+        if (elementToRenderName == nameof(EmbeddedMask))
+        {
+            return base.RenderPreview(renderOn, resolution, frame, elementToRenderName);
+        }
+        
         if (Content.Connection != null)
         {
             var executionQueue = GraphUtils.CalculateExecutionQueue(Content.Connection.Node);

+ 10 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/ImageLayerNode.cs

@@ -111,6 +111,16 @@ public class ImageLayerNode : LayerNode, IReadOnlyImageNode
         workingSurface.Canvas.RestoreToCount(saved);
     }
 
+    public override RectD? GetPreviewBounds(string elementFor = "", int frame = 0)
+    {
+        if (elementFor == nameof(EmbeddedMask))
+        {
+            return base.GetPreviewBounds(elementFor);
+        }
+        
+        return (RectD?)GetLayerImageAtFrame(frame).FindTightCommittedBounds();
+    }
+
     public override bool RenderPreview(DrawingSurface renderOnto, ChunkResolution resolution, int frame,
         string elementToRenderName)
     {

+ 10 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/StructureNode.cs

@@ -286,6 +286,16 @@ public abstract class StructureNode : Node, IReadOnlyStructureNode, IRenderInput
         blendPaint.Dispose();
     }
 
+    public virtual RectD? GetPreviewBounds(string elementFor = "", int frame = 0)
+    {
+        if (elementFor == nameof(EmbeddedMask) && EmbeddedMask != null)
+        {
+            return new RectD(VecD.Zero, EmbeddedMask.LatestSize);
+        }
+
+        return null;
+    }
+
     public virtual bool RenderPreview(DrawingSurface renderOn, ChunkResolution resolution, int frame,
         string elementToRenderName)
     {

+ 2 - 0
src/PixiEditor.ChangeableDocument/Rendering/DocumentRenderer.cs

@@ -300,6 +300,8 @@ public class DocumentRenderer : IPreviewRenderable
         return chunk;
     }
 
+    public RectD? GetPreviewBounds(string elementNameToRender = "", int frame = 0) => new(0, 0, Document.Size.X, Document.Size.Y); 
+
     public bool RenderPreview(DrawingSurface renderOn, ChunkResolution resolution, int frame, string elementToRenderName)
     {
         using RenderContext context = new(renderOn, frame, resolution, Document.Size);

+ 0 - 3
src/PixiEditor/Models/DocumentModels/ActionAccumulator.cs

@@ -74,11 +74,9 @@ internal class ActionAccumulator
 
         while (queuedActions.Count > 0)
         {
-            // select actions to be processed
             var toExecute = queuedActions;
             queuedActions = new();
 
-            // pass them to changeabledocument for processing
             List<IChangeInfo?> changes;
             if (AreAllPassthrough(toExecute))
             {
@@ -89,7 +87,6 @@ internal class ActionAccumulator
                 changes = await internals.Tracker.ProcessActions(toExecute);
             }
 
-            // update viewmodels based on changes
             List<IChangeInfo> optimizedChanges = ChangeInfoListOptimizer.Optimize(changes);
             bool undoBoundaryPassed =
                 toExecute.Any(static action => action.action is ChangeBoundary_Action or Redo_Action or Undo_Action);

+ 2 - 1
src/PixiEditor/Models/Handlers/INodeHandler.cs

@@ -5,6 +5,7 @@ using ChunkyImageLib;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 using PixiEditor.ChangeableDocument.ChangeInfos.NodeGraph;
 using PixiEditor.DrawingApi.Core;
+using PixiEditor.Models.Rendering;
 using PixiEditor.Models.Structures;
 using PixiEditor.Numerics;
 
@@ -19,7 +20,7 @@ public interface INodeHandler : INotifyPropertyChanged
     public NodeMetadata Metadata { get; set; }
     public ObservableRangeCollection<INodePropertyHandler> Inputs { get; }
     public ObservableRangeCollection<INodePropertyHandler> Outputs { get; }
-    public Texture? ResultPreview { get; set; }
+    public PreviewPainter? ResultPainter { get; set; }
     public VecD PositionBindable { get; set; }
     public bool IsSelected { get; set; }
     public void TraverseBackwards(Func<INodeHandler, bool> func);

+ 14 - 43
src/PixiEditor/Models/Rendering/MemberPreviewUpdater.cs

@@ -5,6 +5,7 @@ using ChunkyImageLib;
 using ChunkyImageLib.DataHolders;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
+using PixiEditor.ChangeableDocument.Rendering;
 using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Surfaces;
 using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
@@ -26,7 +27,8 @@ internal class MemberPreviewUpdater
         this.internals = internals;
     }
 
-    public void UpdatePreviews(bool rerenderPreviews, IEnumerable<Guid> membersToUpdate, IEnumerable<Guid> masksToUpdate)
+    public void UpdatePreviews(bool rerenderPreviews, IEnumerable<Guid> membersToUpdate,
+        IEnumerable<Guid> masksToUpdate)
     {
         if (!rerenderPreviews)
             return;
@@ -59,12 +61,11 @@ internal class MemberPreviewUpdater
 
         if (doc.PreviewPainter == null)
         {
-            doc.PreviewPainter = new PreviewPainter(doc.Renderer, new RectD(VecD.Zero, doc.SizeBindable));
+            doc.PreviewPainter = new PreviewPainter(doc.Renderer);
             doc.PreviewPainter.Repaint();
         }
         else
         {
-            doc.PreviewPainter.Bounds = new RectD(VecD.Zero, doc.SizeBindable);
             doc.PreviewPainter.Repaint();
         }
     }
@@ -85,12 +86,11 @@ internal class MemberPreviewUpdater
                         continue;
 
                     structureMemberHandler.PreviewPainter =
-                        new PreviewPainter(previewRenderable, structureMemberHandler.TightBounds);
+                        new PreviewPainter(previewRenderable);
                     structureMemberHandler.PreviewPainter.Repaint();
                 }
                 else
                 {
-                    structureMemberHandler.PreviewPainter.Bounds = structureMemberHandler.TightBounds;
                     structureMemberHandler.PreviewPainter.Repaint();
                 }
             }
@@ -202,22 +202,20 @@ internal class MemberPreviewUpdater
             {
                 if (!members.Contains(node.Id))
                     continue;
-                
+
                 var member = internals.Tracker.Document.FindMember(node.Id);
                 if (member is not IPreviewRenderable previewRenderable)
                     continue;
-                
+
                 if (structureMemberHandler.MaskPreviewPainter == null)
                 {
                     structureMemberHandler.MaskPreviewPainter = new PreviewPainter(
                         previewRenderable,
-                        member.EmbeddedMask != null ? new RectD(VecD.Zero, member.EmbeddedMask.LatestSize) : null,
                         nameof(StructureNode.EmbeddedMask));
                     structureMemberHandler.MaskPreviewPainter.Repaint();
                 }
                 else
                 {
-                    structureMemberHandler.MaskPreviewPainter.Bounds = member.EmbeddedMask != null ? new RectD(VecD.Zero, member.EmbeddedMask.LatestSize) : null;
                     structureMemberHandler.MaskPreviewPainter.Repaint();
                 }
             }
@@ -226,14 +224,17 @@ internal class MemberPreviewUpdater
 
     private void RenderNodePreviews()
     {
-        /*using RenderingContext previewContext = new(doc.AnimationHandler.ActiveFrameTime,  VecI.Zero, ChunkResolution.Full, doc.SizeBindable);
+        /*using RenderContext previewContext = new(doc.AnimationHandler.ActiveFrameTime, VecI.Zero, ChunkResolution.Full,
+            doc.SizeBindable);
 
         var outputNode = internals.Tracker.Document.NodeGraph.OutputNode;
 
         if (outputNode is null)
             return;
 
-        var executionQueue = internals.Tracker.Document.NodeGraph.AllNodes; //internals.Tracker.Document.NodeGraph.CalculateExecutionQueue(outputNode);
+        var executionQueue =
+            internals.Tracker.Document.NodeGraph
+                .AllNodes; //internals.Tracker.Document.NodeGraph.CalculateExecutionQueue(outputNode);
 
         foreach (var node in executionQueue)
         {
@@ -247,40 +248,10 @@ internal class MemberPreviewUpdater
                 continue;
             }
 
-            Texture evaluated = node.Execute(previewContext);
-
-            if (evaluated == null)
-            {
-                nodeVm.ResultPreview?.Dispose();
-                nodeVm.ResultPreview = null;
-                continue;
-            }
-
-            if (nodeVm.ResultPreview == null)
+            if (nodeVm.ResultPainter == null && node is IPreviewRenderable renderable)
             {
-                nodeVm.ResultPreview =
-                    new Texture(StructureHelpers.CalculatePreviewSize(internals.Tracker.Document.Size, 150));
+                nodeVm.ResultPainter = new PreviewPainter(renderable);
             }
-
-            float scalingX = (float)nodeVm.ResultPreview.Size.X / evaluated.Size.X;
-            float scalingY = (float)nodeVm.ResultPreview.Size.Y / evaluated.Size.Y;
-
-            QueueRender(() =>
-            {
-                if(nodeVm.ResultPreview == null || nodeVm.ResultPreview.IsDisposed)
-                    return;
-
-                nodeVm.ResultPreview.DrawingSurface.Canvas.Save();
-                nodeVm.ResultPreview.DrawingSurface.Canvas.Scale(scalingX, scalingY);
-
-                nodeVm.ResultPreview.DrawingSurface.Canvas.DrawSurface(evaluated.DrawingSurface, 0, 0, ReplacingPaint);
-
-                nodeVm.ResultPreview.DrawingSurface.Canvas.Restore();
-
-                evaluated.Dispose();
-            });
-
-            infos.Add(new NodePreviewDirty_RenderInfo(node.Id));
         }*/
     }
 }

+ 2 - 4
src/PixiEditor/Models/Rendering/PreviewPainter.cs

@@ -8,21 +8,19 @@ namespace PixiEditor.Models.Rendering;
 
 public class PreviewPainter
 {
-    public RectD? Bounds { get; set; }
     public string ElementToRenderName { get; set; }
     public IPreviewRenderable PreviewRenderable { get; set; }
     public event Action RequestRepaint;
     
-    public PreviewPainter(IPreviewRenderable previewRenderable, RectD? tightBounds, string elementToRenderName = "")
+    public PreviewPainter(IPreviewRenderable previewRenderable, string elementToRenderName = "")
     {
         PreviewRenderable = previewRenderable;
-        Bounds = tightBounds;
         ElementToRenderName = elementToRenderName;
     }
 
     public void Paint(DrawingSurface renderOn, ChunkResolution resolution, KeyFrameTime frame) 
     {
-        if (PreviewRenderable == null || Bounds == null)
+        if (PreviewRenderable == null)
         {
             return;
         }

+ 1 - 1
src/PixiEditor/Styles/Templates/NodeGraphView.axaml

@@ -53,7 +53,7 @@
                                         RelativeSource={RelativeSource FindAncestor, AncestorType=nodes:NodeGraphView}}"
                                         SocketDropCommand="{Binding SocketDropCommand,
                                         RelativeSource={RelativeSource FindAncestor, AncestorType=nodes:NodeGraphView}}"
-                                        ResultPreview="{Binding ResultPreview}" />
+                                        ResultPreview="{Binding ResultPainter}" />
                                 </DataTemplate>
                             </ItemsControl.ItemTemplate>
                             <ItemsControl.ItemContainerTheme>

+ 0 - 5
src/PixiEditor/ViewModels/Document/DocumentViewModel.cs

@@ -188,12 +188,7 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
         get => previewSurface;
         set
         {
-            VecI? oldSize = (VecI?)previewSurface?.Bounds?.Size;
             SetProperty(ref previewSurface, value);
-            if (oldSize != null && value is { Bounds: not null } && oldSize != value.Bounds.Value.Size)
-            {
-                RaiseSizeChanged(new DocumentSizeChangedEventArgs(this, oldSize.Value, (VecI)value.Bounds.Value.Size));
-            }
         }
     }
 

+ 5 - 4
src/PixiEditor/ViewModels/Nodes/NodeViewModel.cs

@@ -13,6 +13,7 @@ using PixiEditor.DrawingApi.Core;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Models.DocumentModels;
 using PixiEditor.Models.Handlers;
+using PixiEditor.Models.Rendering;
 using PixiEditor.Models.Structures;
 using PixiEditor.Numerics;
 using PixiEditor.ViewModels.Document;
@@ -27,7 +28,7 @@ internal abstract class NodeViewModel : ObservableObject, INodeHandler
     private VecD position;
     private ObservableRangeCollection<INodePropertyHandler> inputs = new();
     private ObservableRangeCollection<INodePropertyHandler> outputs = new();
-    private Texture resultPreview;
+    private PreviewPainter resultPainter;
     private bool isSelected;
 
     protected Guid id;
@@ -110,10 +111,10 @@ internal abstract class NodeViewModel : ObservableObject, INodeHandler
         set => SetProperty(ref outputs, value);
     }
 
-    public Texture ResultPreview
+    public PreviewPainter ResultPainter
     {
-        get => resultPreview;
-        set => SetProperty(ref resultPreview, value);
+        get => resultPainter;
+        set => SetProperty(ref resultPainter, value);
     }
     
     public bool IsSelected

+ 1 - 0
src/PixiEditor/Views/Layers/LayerControl.axaml

@@ -109,6 +109,7 @@
                              <visuals:PreviewPainterControl 
                                     PreviewPainter="{Binding Layer.MaskPreviewPainter, ElementName=uc}" 
                                     Width="30" Height="30"
+                                    ClipToBounds="True"
                                     FrameToRender="{Binding Path=Layer.Document.AnimationHandler.ActiveFrameBindable, ElementName=uc}"
                                     RenderOptions.BitmapInterpolationMode="None" IsHitTestVisible="False"/>
                             <Path

+ 8 - 7
src/PixiEditor/Views/Visuals/PreviewPainterControl.cs

@@ -81,19 +81,20 @@ internal class DrawPreviewOperation : SkiaDrawOperation
 
     public override void Render(ISkiaSharpApiLease lease)
     {
-        if (PreviewPainter == null || PreviewPainter.Bounds == null)
+        RectD? previewBounds = PreviewPainter.PreviewRenderable.GetPreviewBounds(PreviewPainter.ElementToRenderName);
+        if (PreviewPainter == null || previewBounds == null)
         {
             return;
         }
 
         DrawingSurface target = DrawingSurface.FromNative(lease.SkSurface);
 
-        float x = (float)PreviewPainter.Bounds.Value.Width;
-        float y = (float)PreviewPainter.Bounds.Value.Height;
+        float x = (float)previewBounds.Value.Width; 
+        float y = (float)previewBounds.Value.Height; 
 
         target.Canvas.Save();
 
-        UniformScale(x, y, target);
+        UniformScale(x, y, target, previewBounds.Value);
 
         // TODO: Implement ChunkResolution and frame
         PreviewPainter.Paint(target, ChunkResolution.Full, frame);
@@ -103,15 +104,15 @@ internal class DrawPreviewOperation : SkiaDrawOperation
         DrawingSurface.Unmanage(target);
     }
 
-    private void UniformScale(float x, float y, DrawingSurface target)
+    private void UniformScale(float x, float y, DrawingSurface target, RectD previewBounds)
     {
         float scaleX = (float)Bounds.Width / x;
         float scaleY = (float)Bounds.Height / y;
         var scale = Math.Min(scaleX, scaleY);
         float dX = (float)Bounds.Width / 2 / scale - x / 2;
-        dX -= (float)PreviewPainter.Bounds.Value.X;
+        dX -= (float)previewBounds.X; 
         float dY = (float)Bounds.Height / 2 / scale - y / 2;
-        dY -= (float)PreviewPainter.Bounds.Value.Y;
+        dY -= (float)previewBounds.Y;
         target.Canvas.Scale(scale, scale);
         target.Canvas.Translate(dX, dY);
     }

+ 2 - 2
src/PixiEditor/Views/Visuals/PreviewPainterImage.cs

@@ -9,7 +9,7 @@ public class PreviewPainterImage : IImage
     public PreviewPainter PreviewPainter { get; set; }
     
     public int FrameToRender { get; set; }
-    public Size Size => new Size(PreviewPainter.Bounds?.Size.X ?? 0, PreviewPainter.Bounds?.Size.Y ?? 0); 
+    public Size Size => new Size(PreviewPainter.PreviewRenderable.GetPreviewBounds()?.Size.X ?? 0, PreviewPainter.PreviewRenderable.GetPreviewBounds()?.Size.Y ?? 0); 
     
     public PreviewPainterImage(PreviewPainter previewPainter, int frameToRender)
     {
@@ -19,7 +19,7 @@ public class PreviewPainterImage : IImage
     
     public void Draw(DrawingContext context, Rect sourceRect, Rect destRect)
     {
-        if (PreviewPainter.Bounds == null) return;
+        if (PreviewPainter.PreviewRenderable.GetPreviewBounds() == null) return;
         
         using DrawPreviewOperation drawPreviewOperation = new DrawPreviewOperation(destRect, PreviewPainter, FrameToRender); 
         context.Custom(drawPreviewOperation);