Browse Source

GetLayerAt wip

flabbet 1 year ago
parent
commit
9f406fcfe5

+ 1 - 1
src/PixiEditor.AvaloniaUI/ViewModels/Document/DocumentViewModel.Serialization.cs

@@ -120,7 +120,7 @@ internal partial class DocumentViewModel
     {
         var result = document.GetLayerRasterizedImage(layer.GuidValue, 0);
 
-        var tightBounds = document.GetChunkAlignedLayerBounds(layer.GuidValue);
+        var tightBounds = document.GetChunkAlignedLayerBounds(layer.GuidValue, 0);
         using var data = result?.DrawingSurface.Snapshot().Encode();
         byte[] bytes = data?.AsSpan().ToArray();
         var serializable = new ImageLayer

+ 3 - 2
src/PixiEditor.AvaloniaUI/ViewModels/Document/DocumentViewModel.cs

@@ -444,7 +444,8 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
         RectI? memberImageBounds;
         try
         {
-            memberImageBounds = layer.LayerImage.FindChunkAlignedMostUpToDateBounds();
+            // TODO: Make sure it must be GetLayerImageAtFrame rather than Rasterize()
+            memberImageBounds = layer.GetLayerImageAtFrame(AnimationDataViewModel.ActiveFrameBindable).FindChunkAlignedMostUpToDateBounds();
         }
         catch (ObjectDisposedException)
         {
@@ -466,7 +467,7 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
         output.DrawingSurface.Canvas.ClipPath(clipPath);
         try
         {
-            layer.LayerImage.DrawMostUpToDateRegionOn(bounds, ChunkResolution.Full, output.DrawingSurface, VecI.Zero);
+            layer.GetLayerImageAtFrame(AnimationDataViewModel.ActiveFrameBindable).DrawMostUpToDateRegionOn(bounds, ChunkResolution.Full, output.DrawingSurface, VecI.Zero);
         }
         catch (ObjectDisposedException)
         {

+ 1 - 1
src/PixiEditor.AvaloniaUI/ViewModels/Document/StructureMemberViewModel.cs

@@ -52,7 +52,7 @@ internal abstract class StructureMemberViewModel : ObservableObject, IStructureM
     }
 
     private bool maskIsVisible;
-    public RectI? TightBounds => Internals.Tracker.Document.FindMember(GuidValue)?.GetTightBounds();
+    public RectI? TightBounds => Internals.Tracker.Document.FindMember(GuidValue)?.GetTightBounds(Document.AnimationDataViewModel.ActiveFrameBindable);
 
     public void SetMaskIsVisible(bool maskIsVisible)
     {

+ 0 - 5
src/PixiEditor.ChangeableDocument/Changeables/Animations/GroupKeyFrame.cs

@@ -18,11 +18,6 @@ internal class GroupKeyFrame : KeyFrame, IKeyFrameChildrenContainer
     {
         Id = layerGuid;
         this.document = document;
-        
-        if (document.TryFindMember<RasterLayer>(LayerGuid, out var layer))
-        {
-            originalLayerImage = layer.LayerImage;
-        }
     }
 
     protected override void OnVisibilityChanged()

+ 2 - 4
src/PixiEditor.ChangeableDocument/Changeables/Animations/KeyFrameTime.cs

@@ -2,14 +2,12 @@
 
 public record KeyFrameTime
 {
-    public KeyFrameTime(int Frame, float NormalizedTime)
+    public KeyFrameTime(int Frame)
     {
         this.Frame = Frame;
-        this.NormalizedTime = NormalizedTime;
     }
 
     public int Frame { get; init; }
-    public float NormalizedTime { get; init; }
     
-    public static implicit operator KeyFrameTime(int frame) => new KeyFrameTime(frame, 0);
+    public static implicit operator KeyFrameTime(int frame) => new KeyFrameTime(frame);
 }

+ 3 - 3
src/PixiEditor.ChangeableDocument/Changeables/Document.cs

@@ -61,7 +61,7 @@ internal class Document : IChangeable, IReadOnlyDocument, IDisposable
             throw new ArgumentException(@"The given guid does not belong to a layer.", nameof(layerGuid));
 
 
-        RectI? tightBounds = layer.GetTightBounds();
+        RectI? tightBounds = layer.GetTightBounds(frame);
 
         if (tightBounds is null)
             return null;
@@ -78,7 +78,7 @@ internal class Document : IChangeable, IReadOnlyDocument, IDisposable
         return surface;
     }
 
-    public RectI? GetChunkAlignedLayerBounds(Guid layerGuid)
+    public RectI? GetChunkAlignedLayerBounds(Guid layerGuid, int frame)
     {
         var layer = (IReadOnlyLayer?)FindMember(layerGuid);
 
@@ -86,7 +86,7 @@ internal class Document : IChangeable, IReadOnlyDocument, IDisposable
             throw new ArgumentException(@"The given guid does not belong to a layer.", nameof(layerGuid));
 
 
-        return layer.GetTightBounds();
+        return layer.GetTightBounds(frame);
     }
     
     public void ForEveryReadonlyMember(Action<IReadOnlyStructureMember> action) => ForEveryReadonlyMember(StructureRoot, action);

+ 3 - 3
src/PixiEditor.ChangeableDocument/Changeables/Folder.cs

@@ -14,17 +14,17 @@ internal class Folder : StructureMember, IReadOnlyFolder
     public ImmutableList<StructureMember> Children { get; set; } = ImmutableList<StructureMember>.Empty;
     IReadOnlyList<IReadOnlyStructureMember> IReadOnlyFolder.Children => Children;
 
-    public override RectI? GetTightBounds()
+    public override RectI? GetTightBounds(int frame)
     {
         if (Children.Count == 0)
         {
             return null;
         }
 
-        var bounds = Children[0].GetTightBounds();
+        var bounds = Children[0].GetTightBounds(frame);
         for (var i = 1; i < Children.Count; i++)
         {
-            var childBounds = Children[i].GetTightBounds();
+            var childBounds = Children[i].GetTightBounds(frame);
             if (childBounds == null)
             {
                 continue;

+ 0 - 7
src/PixiEditor.ChangeableDocument/Changeables/Interfaces/IChunkyImageEvaluable.cs

@@ -1,7 +0,0 @@
-namespace PixiEditor.ChangeableDocument.Changeables.Interfaces;
-
-public interface IChunkyImageProperty : IKeyFrameProperty
-{
-    public IReadOnlyChunkyImage LayerImage { get; }
-}
-

+ 0 - 6
src/PixiEditor.ChangeableDocument/Changeables/Interfaces/IKeyFrameProperty.cs

@@ -1,6 +0,0 @@
-namespace PixiEditor.ChangeableDocument.Changeables.Interfaces;
-
-public interface IKeyFrameProperty
-{
-    
-}

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Interfaces/IReadOnlyDocument.cs

@@ -49,7 +49,7 @@ public interface IReadOnlyDocument
     void ForEveryReadonlyMember(Action<IReadOnlyStructureMember> action);
     
     public Surface? GetLayerRasterizedImage(Guid layerGuid, int frame);
-    public RectI? GetChunkAlignedLayerBounds(Guid layerGuid);
+    public RectI? GetChunkAlignedLayerBounds(Guid layerGuid, int frame);
 
     /// <summary>
     /// Finds the member with the <paramref name="guid"/> or returns null if not found

+ 2 - 2
src/PixiEditor.ChangeableDocument/Changeables/Interfaces/IReadOnlyRasterLayer.cs

@@ -1,9 +1,9 @@
 namespace PixiEditor.ChangeableDocument.Changeables.Interfaces;
 
-public interface IReadOnlyRasterLayer : ITransparencyLockable, IChunkyImageProperty
+public interface IReadOnlyRasterLayer : ITransparencyLockable
 {
     /// <summary>
     /// The chunky image of the layer
     /// </summary>
-    IReadOnlyChunkyImage LayerImage { get; }
+    IReadOnlyChunkyImage GetLayerImageAtFrame(int frame);
 }

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Interfaces/IReadOnlyStructureMember.cs

@@ -46,5 +46,5 @@ public interface IReadOnlyStructureMember
     ///     The tight bounds of the member. The bounds are the smallest rectangle that contains all the pixels of the member.
     /// </summary>
     /// <returns>The tight bounds of the member</returns>
-    public RectI? GetTightBounds();
+    public RectI? GetTightBounds(int frame);
 }

+ 28 - 22
src/PixiEditor.ChangeableDocument/Changeables/RasterLayer.cs

@@ -10,23 +10,17 @@ internal class RasterLayer : Layer, IReadOnlyRasterLayer
     // Don't forget to update CreateLayer_ChangeInfo, DocumentUpdater.ProcessCreateStructureMember and Layer.Clone when adding new properties
     public bool LockTransparency { get; set; } = false;
 
-    public ChunkyImage LayerImage
-    {
-         get
-    }
-    IReadOnlyChunkyImage IReadOnlyRasterLayer.LayerImage => LayerImage;
-    IReadOnlyChunkyImage IChunkyImageProperty.LayerImage => LayerImage;
-    
+
     private List<ImageFrame> frameImages = new();
-    
+
     public RasterLayer(VecI size)
     {
         frameImages.Add(new ImageFrame(0, 0, new(size)));
     }
 
-    public RasterLayer(ChunkyImage image)
+    public RasterLayer(List<ImageFrame> frames)
     {
-        LayerImage = image;
+        frameImages = frames;
     }
 
     /// <summary>
@@ -34,7 +28,6 @@ internal class RasterLayer : Layer, IReadOnlyRasterLayer
     /// </summary>
     public override void Dispose()
     {
-        LayerImage.Dispose();
         Mask?.Dispose();
         foreach (var frame in frameImages)
         {
@@ -42,21 +35,28 @@ internal class RasterLayer : Layer, IReadOnlyRasterLayer
         }
     }
 
+    IReadOnlyChunkyImage IReadOnlyRasterLayer.GetLayerImageAtFrame(int frame) => GetLayerImageAtFrame(frame);
+    
+    public ChunkyImage GetLayerImageAtFrame(int frame)
+    {
+        return Rasterize(frame);
+    }
+
     public override ChunkyImage Rasterize(KeyFrameTime frameTime)
     {
         if (frameImages.Count == 0)
         {
-            return LayerImage;
+            return frameImages[0].Image;
         }
-        
+
         ImageFrame frame = frameImages.FirstOrDefault(x => x.IsInFrame(frameTime.Frame));
-        
-        return frame?.Image ?? LayerImage;
+
+        return frame?.Image ?? frameImages[0].Image;
     }
 
-    public override RectI? GetTightBounds()
+    public override RectI? GetTightBounds(int frame)
     {
-        return LayerImage.FindTightCommittedBounds();
+        return Rasterize(frame).FindTightCommittedBounds();
     }
 
     /// <summary>
@@ -64,7 +64,13 @@ internal class RasterLayer : Layer, IReadOnlyRasterLayer
     /// </summary>
     internal override RasterLayer Clone()
     {
-        return new RasterLayer(LayerImage.CloneFromCommitted())
+        List<ImageFrame> clonedFrames = new();
+        foreach (var frame in frameImages)
+        {
+            clonedFrames.Add(new ImageFrame(frame.StartFrame, frame.EndFrame, frame.Image.CloneFromCommitted()));
+        }
+        
+        return new RasterLayer(clonedFrames)
         {
             GuidValue = GuidValue,
             IsVisible = IsVisible,
@@ -81,17 +87,17 @@ internal class RasterLayer : Layer, IReadOnlyRasterLayer
 
 class ImageFrame
 {
-    int StartFrame { get; set; }
-    int EndFrame { get; set; }
+    public int StartFrame { get; set; }
+    public int EndFrame { get; set; }
     public ChunkyImage Image { get; set; }
-    
+
     public ImageFrame(int startFrame, int endFrame, ChunkyImage image)
     {
         StartFrame = startFrame;
         EndFrame = endFrame;
         Image = image;
     }
-    
+
     public bool IsInFrame(int frame)
     {
         return frame >= StartFrame && frame <= EndFrame;

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/StructureMember.cs

@@ -16,7 +16,7 @@ internal abstract class StructureMember : IChangeable, IReadOnlyStructureMember,
     public BlendMode BlendMode { get; set; } = BlendMode.Normal;
     public Guid GuidValue { get; set; }
     public ChunkyImage? Mask { get; set; } = null;
-    public abstract RectI? GetTightBounds();
+    public abstract RectI? GetTightBounds(int frame);
 
     public bool MaskIsVisible { get; set; } = true;
     IReadOnlyChunkyImage? IReadOnlyStructureMember.Mask => Mask;

+ 2 - 2
src/PixiEditor.ChangeableDocument/Changes/Drawing/DrawingChangeHelper.cs

@@ -22,7 +22,7 @@ internal static class DrawingChangeHelper
         return area;
     }
 
-    public static ChunkyImage GetTargetImageOrThrow(Document target, Guid memberGuid, bool drawOnMask)
+    public static ChunkyImage GetTargetImageOrThrow(Document target, Guid memberGuid, bool drawOnMask, int frame)
     {
         // TODO: Figure out if this should work only for raster layers or should rasterize any
         var member = target.FindMemberOrThrow(memberGuid);
@@ -44,7 +44,7 @@ internal static class DrawingChangeHelper
             throw new InvalidOperationException("Trying to draw on a non-raster layer member");
         }
         
-        return layer.LayerImage;
+        return layer.GetLayerImageAtFrame(frame);
     }
 
     public static void ApplyClipsSymmetriesEtc(Document target, ChunkyImage targetImage, Guid targetMemberGuid, bool drawOnMask)