Browse Source

Fixed folder previews

flabbet 1 year ago
parent
commit
3c792a386d

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

@@ -5,5 +5,5 @@ namespace PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 
 
 public interface IReadOnlyFolderNode : IReadOnlyStructureNode
 public interface IReadOnlyFolderNode : IReadOnlyStructureNode
 {
 {
-    InputProperty<Texture?> Content { get; }
+    public HashSet<Guid> GetLayerNodeGuids();
 }
 }

+ 36 - 26
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/FolderNode.cs

@@ -104,33 +104,43 @@ public class FolderNode : StructureNode, IReadOnlyFolderNode
 
 
     public override RectI? GetTightBounds(KeyFrameTime frameTime)
     public override RectI? GetTightBounds(KeyFrameTime frameTime)
     {
     {
-        // TODO: Implement GetTightBounds
+        RectI bounds = new RectI();
+        if(Content.Connection != null)
+        {
+            Content.Connection.Node.TraverseBackwards((n) =>
+            {
+                if (n is ImageLayerNode imageLayerNode)
+                {
+                    RectI? imageBounds = imageLayerNode.GetTightBounds(frameTime);
+                    if (imageBounds != null)
+                    {
+                        bounds = bounds.Union(imageBounds.Value);
+                    }
+                }
+
+                return true;
+            });
+            
+            return bounds;
+        }
+        
         return RectI.Create(0, 0, Content.Value?.Size.X ?? 0, Content.Value?.Size.Y ?? 0);
         return RectI.Create(0, 0, Content.Value?.Size.X ?? 0, Content.Value?.Size.Y ?? 0);
-        /*if (Children.Count == 0)
-      {
-          return null;
-      }
-
-      var bounds = Children[0].GetTightBounds(frame);
-      for (var i = 1; i < Children.Count; i++)
-      {
-          var childBounds = Children[i].GetTightBounds(frame);
-          if (childBounds == null)
-          {
-              continue;
-          }
-
-          if (bounds == null)
-          {
-              bounds = childBounds;
-          }
-          else
-          {
-              bounds = bounds.Value.Union(childBounds.Value);
-          }
-      }
-
-      return bounds;*/
+    }
+
+    public HashSet<Guid> GetLayerNodeGuids()
+    {
+        HashSet<Guid> guids = new();
+        Content.Connection?.Node.TraverseBackwards((n) =>
+        {
+            if (n is ImageLayerNode imageLayerNode)
+            {
+                guids.Add(imageLayerNode.Id);
+            }
+
+            return true;
+        });
+
+        return guids;
     }
     }
 
 
     /// <summary>
     /// <summary>

+ 6 - 7
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/StructureNode.cs

@@ -107,7 +107,7 @@ public abstract class StructureNode : Node, IReadOnlyStructureNode, IBackgroundI
     protected void DrawSurface(Texture workingSurface, Texture source, RenderingContext context, Filter? filter)
     protected void DrawSurface(Texture workingSurface, Texture source, RenderingContext context, Filter? filter)
     {
     {
         // Maybe clip rect will allow to avoid snapshotting? Idk if it will be faster
         // Maybe clip rect will allow to avoid snapshotting? Idk if it will be faster
-        RectI sourceRect = CalculateSourceRect(source, workingSurface.Size, context);
+        RectI sourceRect = CalculateSourceRect(context);
         RectI targetRect = CalculateDestinationRect(context);
         RectI targetRect = CalculateDestinationRect(context);
         using var snapshot = source.DrawingSurface.Snapshot(sourceRect);
         using var snapshot = source.DrawingSurface.Snapshot(sourceRect);
 
 
@@ -115,16 +115,15 @@ public abstract class StructureNode : Node, IReadOnlyStructureNode, IBackgroundI
         workingSurface.DrawingSurface.Canvas.DrawImage(snapshot, targetRect.X, targetRect.Y, blendPaint);
         workingSurface.DrawingSurface.Canvas.DrawImage(snapshot, targetRect.X, targetRect.Y, blendPaint);
     }
     }
 
 
-    protected RectI CalculateSourceRect(Texture image, VecI targetSize, RenderingContext context)
+    protected RectI CalculateSourceRect(RenderingContext context)
     {
     {
-        float dividerToFit = image.Size.X / (float)targetSize.X;
         int chunkSize = context.ChunkResolution.PixelSize();
         int chunkSize = context.ChunkResolution.PixelSize();
         VecI chunkPos = context.ChunkToUpdate;
         VecI chunkPos = context.ChunkToUpdate;
 
 
-        int x = (int)(chunkPos.X * chunkSize / dividerToFit);
-        int y = (int)(chunkPos.Y * chunkSize / dividerToFit);
-        int width = (int)(chunkSize / dividerToFit);
-        int height = (int)(chunkSize / dividerToFit);
+        int x = (int)(chunkPos.X * chunkSize);
+        int y = (int)(chunkPos.Y * chunkSize);
+        int width = (int)(chunkSize);
+        int height = (int)(chunkSize);
 
 
         return new RectI(x, y, width, height);
         return new RectI(x, y, width, height);
     }
     }

+ 55 - 57
src/PixiEditor.ChangeableDocument/Rendering/DocumentRenderer.cs

@@ -24,51 +24,9 @@ public class DocumentRenderer
         RenderingContext context = new(frameTime, chunkPos, resolution, Document.Size);
         RenderingContext context = new(frameTime, chunkPos, resolution, Document.Size);
         try
         try
         {
         {
-            RectI? transformedClippingRect = TransformClipRect(globalClippingRect, resolution, chunkPos);
+          
+            return RenderChunkOnGraph(chunkPos, resolution, globalClippingRect, Document.NodeGraph, context);
 
 
-            Texture? evaluated = Document.NodeGraph.Execute(context);
-            if (evaluated is null)
-            {
-                return new EmptyChunk();
-            }
-
-            Chunk chunk = Chunk.Create(resolution);
-
-            chunk.Surface.DrawingSurface.Canvas.Save();
-            chunk.Surface.DrawingSurface.Canvas.Clear();
-
-            if (transformedClippingRect is not null)
-            {
-                chunk.Surface.DrawingSurface.Canvas.ClipRect((RectD)transformedClippingRect);
-            }
-
-            VecD pos = chunkPos;
-            int x = (int)(pos.X * ChunkyImage.FullChunkSize * resolution.Multiplier());
-            int y = (int)(pos.Y * ChunkyImage.FullChunkSize * resolution.Multiplier());
-            int width = (int)(ChunkyImage.FullChunkSize * resolution.Multiplier());
-            int height = (int)(ChunkyImage.FullChunkSize * resolution.Multiplier());
-
-            RectD sourceRect = new(x, y, width, height);
-            
-            RectD availableRect = new(0, 0, evaluated.Size.X, evaluated.Size.Y);
-            
-            sourceRect = sourceRect.Intersect(availableRect);
-            
-            if (sourceRect.IsZeroOrNegativeArea)
-            {
-                chunk.Dispose();
-                return new EmptyChunk();
-            }
-
-            using var chunkSnapshot = evaluated.DrawingSurface.Snapshot((RectI)sourceRect);
-            
-            if(context.IsDisposed) return new EmptyChunk();
-
-            chunk.Surface.DrawingSurface.Canvas.DrawImage(chunkSnapshot, 0, 0, context.ReplacingPaintWithOpacity);
-
-            chunk.Surface.DrawingSurface.Canvas.Restore();
-
-            return chunk;
         }
         }
         catch (ObjectDisposedException)
         catch (ObjectDisposedException)
         {
         {
@@ -115,31 +73,71 @@ public class DocumentRenderer
         return (RectI?)rect.Scale(multiplier).Translate(-pixelChunkPos).RoundOutwards();
         return (RectI?)rect.Scale(multiplier).Translate(-pixelChunkPos).RoundOutwards();
     }
     }
 
 
-    public OneOf<Chunk, EmptyChunk> RenderLayersChunk(VecI chunkPos, ChunkResolution resolution, int frame,
+    public OneOf<Chunk, EmptyChunk> RenderLayersChunk(VecI chunkPos, ChunkResolution resolution, KeyFrameTime frame,
         HashSet<Guid> layersToCombine, RectI? globalClippingRect)
         HashSet<Guid> layersToCombine, RectI? globalClippingRect)
     {
     {
         using RenderingContext context = new(frame, chunkPos, resolution, Document.Size);
         using RenderingContext context = new(frame, chunkPos, resolution, Document.Size);
         NodeGraph membersOnlyGraph = ConstructMembersOnlyGraph(layersToCombine, Document.NodeGraph);
         NodeGraph membersOnlyGraph = ConstructMembersOnlyGraph(layersToCombine, Document.NodeGraph);
         try
         try
         {
         {
-            RectI? transformedClippingRect = TransformClipRect(globalClippingRect, resolution, chunkPos);
-            Texture? evaluated = membersOnlyGraph.Execute(context);
-            if (evaluated is null)
-            {
-                return new EmptyChunk();
-            }
-
-            var result = ChunkFromResult(resolution, transformedClippingRect, evaluated.DrawingSurface.Snapshot(), context);
-            
-            membersOnlyGraph.Dispose();
-            return result;
+            return RenderChunkOnGraph(chunkPos, resolution, globalClippingRect, membersOnlyGraph, context);
         }
         }
         catch (ObjectDisposedException)
         catch (ObjectDisposedException)
         {
         {
             return new EmptyChunk();
             return new EmptyChunk();
         }
         }
     }
     }
-    
+
+    private static OneOf<Chunk, EmptyChunk> RenderChunkOnGraph(VecI chunkPos, ChunkResolution resolution, RectI? globalClippingRect,
+        IReadOnlyNodeGraph graph, RenderingContext context)
+    {
+        RectI? transformedClippingRect = TransformClipRect(globalClippingRect, resolution, chunkPos);
+
+        Texture? evaluated = graph.Execute(context);
+        if (evaluated is null)
+        {
+            return new EmptyChunk();
+        }
+
+        Chunk chunk = Chunk.Create(resolution);
+
+        chunk.Surface.DrawingSurface.Canvas.Save();
+        chunk.Surface.DrawingSurface.Canvas.Clear();
+
+        if (transformedClippingRect is not null)
+        {
+            chunk.Surface.DrawingSurface.Canvas.ClipRect((RectD)transformedClippingRect);
+        }
+
+        VecD pos = chunkPos;
+        int x = (int)(pos.X * ChunkyImage.FullChunkSize * resolution.Multiplier());
+        int y = (int)(pos.Y * ChunkyImage.FullChunkSize * resolution.Multiplier());
+        int width = (int)(ChunkyImage.FullChunkSize * resolution.Multiplier());
+        int height = (int)(ChunkyImage.FullChunkSize * resolution.Multiplier());
+
+        RectD sourceRect = new(x, y, width, height);
+            
+        RectD availableRect = new(0, 0, evaluated.Size.X, evaluated.Size.Y);
+            
+        sourceRect = sourceRect.Intersect(availableRect);
+            
+        if (sourceRect.IsZeroOrNegativeArea)
+        {
+            chunk.Dispose();
+            return new EmptyChunk();
+        }
+
+        using var chunkSnapshot = evaluated.DrawingSurface.Snapshot((RectI)sourceRect);
+            
+        if(context.IsDisposed) return new EmptyChunk();
+
+        chunk.Surface.DrawingSurface.Canvas.DrawImage(chunkSnapshot, 0, 0, context.ReplacingPaintWithOpacity);
+
+        chunk.Surface.DrawingSurface.Canvas.Restore();
+
+        return chunk;
+    }
+
     private NodeGraph ConstructMembersOnlyGraph(HashSet<Guid> layersToCombine, IReadOnlyNodeGraph fullGraph)
     private NodeGraph ConstructMembersOnlyGraph(HashSet<Guid> layersToCombine, IReadOnlyNodeGraph fullGraph)
     {
     {
         NodeGraph membersOnlyGraph = new();
         NodeGraph membersOnlyGraph = new();

+ 4 - 4
src/PixiEditor/Models/Rendering/MemberPreviewUpdater.cs

@@ -571,18 +571,18 @@ internal class MemberPreviewUpdater
                 var pos = chunk * ChunkResolution.Full.PixelSize();
                 var pos = chunk * ChunkResolution.Full.PixelSize();
                 // drawing in full res here is kinda slow
                 // drawing in full res here is kinda slow
                 // we could switch to a lower resolution based on (canvas size / preview size) to make it run faster
                 // we could switch to a lower resolution based on (canvas size / preview size) to make it run faster
-                var contentNode = folder.Content.Connection?.Node;
+                HashSet<Guid> layers = folder.GetLayerNodeGuids();
 
 
                 OneOf<Chunk, EmptyChunk> rendered;
                 OneOf<Chunk, EmptyChunk> rendered;
 
 
-                if (contentNode is null)
+                if (layers.Count == 0)
                 {
                 {
                     rendered = new EmptyChunk();
                     rendered = new EmptyChunk();
                 }
                 }
                 else
                 else
                 {
                 {
-                    rendered = doc.Renderer.RenderChunk(chunk, ChunkResolution.Full, contentNode,
-                        doc.AnimationHandler.ActiveFrameBindable);
+                    rendered = doc.Renderer.RenderLayersChunk(chunk, ChunkResolution.Full, doc.AnimationHandler.ActiveFrameTime, layers,
+                        null);
                 }
                 }
 
 
                 if (rendered.IsT0)
                 if (rendered.IsT0)