Browse Source

Fixed always animation cels repainting

Krzysztof Krysiński 4 months ago
parent
commit
87ff305772

+ 19 - 1
src/PixiEditor.ChangeableDocument/Changeables/Document.cs

@@ -94,7 +94,8 @@ internal class Document : IChangeable, IReadOnlyDocument
         if (layer is IReadOnlyImageNode imageNode)
         if (layer is IReadOnlyImageNode imageNode)
         {
         {
             var chunkyImage = imageNode.GetLayerImageAtFrame(frame);
             var chunkyImage = imageNode.GetLayerImageAtFrame(frame);
-            using Surface chunkSurface = Surface.ForProcessing(chunkyImage.CommittedSize, chunkyImage.ProcessingColorSpace);
+            using Surface chunkSurface =
+                Surface.ForProcessing(chunkyImage.CommittedSize, chunkyImage.ProcessingColorSpace);
             chunkyImage.DrawCommittedRegionOn(
             chunkyImage.DrawCommittedRegionOn(
                 new RectI(0, 0, chunkyImage.CommittedSize.X, chunkyImage.CommittedSize.Y),
                 new RectI(0, 0, chunkyImage.CommittedSize.X, chunkyImage.CommittedSize.Y),
                 ChunkResolution.Full,
                 ChunkResolution.Full,
@@ -144,6 +145,23 @@ internal class Document : IChangeable, IReadOnlyDocument
         ProcessingColorSpace = processingColorSpace;
         ProcessingColorSpace = processingColorSpace;
     }
     }
 
 
+    public List<IReadOnlyStructureNode> GetParents(Guid memberGuid)
+    {
+        var childNode = FindNode<StructureNode>(memberGuid);
+        if (childNode == null)
+            return new List<IReadOnlyStructureNode>();
+
+        List<IReadOnlyStructureNode> parents = new();
+        childNode.TraverseForwards((node, input) =>
+        {
+            if (node is IReadOnlyStructureNode parent && input is { InternalPropertyName: FolderNode.ContentInternalName })
+                parents.Add(parent);
+            return true;
+        });
+
+        return parents;
+    }
+
     private void ForEveryReadonlyMember(IReadOnlyNodeGraph graph, Action<IReadOnlyStructureNode> action)
     private void ForEveryReadonlyMember(IReadOnlyNodeGraph graph, Action<IReadOnlyStructureNode> action)
     {
     {
         graph.TryTraverse((node) =>
         graph.TryTraverse((node) =>

+ 36 - 3
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Node.cs

@@ -90,7 +90,8 @@ public abstract class Node : IReadOnlyNode, IDisposable
 
 
         if (CacheTrigger.HasFlag(CacheTriggerFlags.Timeline))
         if (CacheTrigger.HasFlag(CacheTriggerFlags.Timeline))
         {
         {
-            changed |= lastFrameTime.Frame != context.FrameTime.Frame || Math.Abs(lastFrameTime.NormalizedTime - context.FrameTime.NormalizedTime) > float.Epsilon;
+            changed |= lastFrameTime.Frame != context.FrameTime.Frame ||
+                       Math.Abs(lastFrameTime.NormalizedTime - context.FrameTime.NormalizedTime) > float.Epsilon;
         }
         }
 
 
         int contentCacheHash = GetContentCacheHash();
         int contentCacheHash = GetContentCacheHash();
@@ -268,6 +269,39 @@ public abstract class Node : IReadOnlyNode, IDisposable
         }
         }
     }
     }
 
 
+    public void TraverseForwards(Func<IReadOnlyNode, IInputProperty, IOutputProperty, bool> action)
+    {
+        var visited = new HashSet<IReadOnlyNode>();
+        var queueNodes = new Queue<(IReadOnlyNode, IInputProperty, IOutputProperty)>();
+        queueNodes.Enqueue((this, null, null));
+
+        while (queueNodes.Count > 0)
+        {
+            var node = queueNodes.Dequeue();
+
+            if (!visited.Add((node.Item1)))
+            {
+                continue;
+            }
+
+            if (!action(node.Item1, node.Item2, node.Item3))
+            {
+                return;
+            }
+
+            foreach (var outputProperty in node.Item1.OutputProperties)
+            {
+                foreach (var connection in outputProperty.Connections)
+                {
+                    if (connection.Connection != null)
+                    {
+                        queueNodes.Enqueue((connection.Node, connection, outputProperty));
+                    }
+                }
+            }
+        }
+    }
+
     public void RemoveKeyFrame(Guid keyFrameId)
     public void RemoveKeyFrame(Guid keyFrameId)
     {
     {
         keyFrames.RemoveAll(x => x.KeyFrameGuid == keyFrameId);
         keyFrames.RemoveAll(x => x.KeyFrameGuid == keyFrameId);
@@ -365,7 +399,7 @@ public abstract class Node : IReadOnlyNode, IDisposable
 
 
     protected void RemoveInputProperty(InputProperty property)
     protected void RemoveInputProperty(InputProperty property)
     {
     {
-        if(inputs.Remove(property))
+        if (inputs.Remove(property))
         {
         {
             property.ConnectionChanged -= InvokeConnectionsChanged;
             property.ConnectionChanged -= InvokeConnectionsChanged;
         }
         }
@@ -527,7 +561,6 @@ public abstract class Node : IReadOnlyNode, IDisposable
     internal virtual void DeserializeAdditionalData(IReadOnlyDocument target,
     internal virtual void DeserializeAdditionalData(IReadOnlyDocument target,
         IReadOnlyDictionary<string, object> data, List<IChangeInfo> infos)
         IReadOnlyDictionary<string, object> data, List<IChangeInfo> infos)
     {
     {
-
     }
     }
 
 
     private void InvokeConnectionsChanged()
     private void InvokeConnectionsChanged()

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

@@ -104,4 +104,5 @@ public interface IReadOnlyDocument : IDisposable
     public DocumentRenderer Renderer { get; }
     public DocumentRenderer Renderer { get; }
     public ColorSpace ProcessingColorSpace { get; }
     public ColorSpace ProcessingColorSpace { get; }
     public void InitProcessingColorSpace(ColorSpace processingColorSpace);
     public void InitProcessingColorSpace(ColorSpace processingColorSpace);
+    public List<IReadOnlyStructureNode> GetParents(Guid memberGuid);
 }
 }

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

@@ -332,7 +332,8 @@ internal class AffectedAreasGatherer
 
 
     private void AddToImagePreviews(Guid memberGuid, AffectedArea area, bool ignoreSelf = false)
     private void AddToImagePreviews(Guid memberGuid, AffectedArea area, bool ignoreSelf = false)
     {
     {
-        var path = tracker.Document.FindMemberPath(memberGuid);
+        var path = tracker.Document.GetParents(memberGuid);
+        path.Insert(0, tracker.Document.FindMember(memberGuid));
         for (int i = ignoreSelf ? 1 : 0; i < path.Count; i++)
         for (int i = ignoreSelf ? 1 : 0; i < path.Count; i++)
         {
         {
             var member = path[i];
             var member = path[i];

+ 41 - 6
src/PixiEditor/ViewModels/Document/AnimationDataViewModel.cs

@@ -140,7 +140,7 @@ internal class AnimationDataViewModel : ObservableObject, IAnimationHandler
                 frameToCopyFrom ?? -1, toCloneFrom ?? Guid.Empty));
                 frameToCopyFrom ?? -1, toCloneFrom ?? Guid.Empty));
             return newCelGuid;
             return newCelGuid;
         }
         }
-        
+
         return null;
         return null;
     }
     }
 
 
@@ -230,7 +230,7 @@ internal class AnimationDataViewModel : ObservableObject, IAnimationHandler
         {
         {
             cachedFirstFrame = null;
             cachedFirstFrame = null;
             cachedLastFrame = null;
             cachedLastFrame = null;
-            
+
             keyFrame.SetStartFrame(newStartFrame);
             keyFrame.SetStartFrame(newStartFrame);
             keyFrame.SetDuration(newDuration);
             keyFrame.SetDuration(newDuration);
             keyFrames.NotifyCollectionChanged();
             keyFrames.NotifyCollectionChanged();
@@ -274,10 +274,10 @@ internal class AnimationDataViewModel : ObservableObject, IAnimationHandler
         }
         }
 
 
         SortByLayers();
         SortByLayers();
-        
+
         cachedFirstFrame = null;
         cachedFirstFrame = null;
         cachedLastFrame = null;
         cachedLastFrame = null;
-        
+
         OnPropertyChanged(nameof(FirstFrame));
         OnPropertyChanged(nameof(FirstFrame));
         OnPropertyChanged(nameof(LastFrame));
         OnPropertyChanged(nameof(LastFrame));
         OnPropertyChanged(nameof(FramesCount));
         OnPropertyChanged(nameof(FramesCount));
@@ -304,7 +304,7 @@ internal class AnimationDataViewModel : ObservableObject, IAnimationHandler
         });
         });
 
 
         allCels.RemoveAll(x => x.Id == keyFrameId);
         allCels.RemoveAll(x => x.Id == keyFrameId);
-        
+
         cachedFirstFrame = null;
         cachedFirstFrame = null;
         cachedLastFrame = null;
         cachedLastFrame = null;
 
 
@@ -398,8 +398,12 @@ internal class AnimationDataViewModel : ObservableObject, IAnimationHandler
     public void SortByLayers()
     public void SortByLayers()
     {
     {
         var allLayers = Document.StructureHelper.GetAllLayers();
         var allLayers = Document.StructureHelper.GetAllLayers();
+
+        if (!OrderDifferent(keyFrames, allLayers)) return;
+
         var unsortedKeyFrames = keyFrames.ToList();
         var unsortedKeyFrames = keyFrames.ToList();
         var layerKeyFrames = new List<CelGroupViewModel>();
         var layerKeyFrames = new List<CelGroupViewModel>();
+
         foreach (var layer in allLayers)
         foreach (var layer in allLayers)
         {
         {
             var group = unsortedKeyFrames.FirstOrDefault(x =>
             var group = unsortedKeyFrames.FirstOrDefault(x =>
@@ -429,11 +433,42 @@ internal class AnimationDataViewModel : ObservableObject, IAnimationHandler
 
 
     public int GetLastVisibleFrame()
     public int GetLastVisibleFrame()
     {
     {
-        return keyFrames.Count > 0 ? keyFrames.Where(x => x.IsVisible).Max(x => x.StartFrameBindable + x.DurationBindable) : 0;
+        return keyFrames.Count > 0
+            ? keyFrames.Where(x => x.IsVisible).Max(x => x.StartFrameBindable + x.DurationBindable)
+            : 0;
     }
     }
 
 
     public int GetVisibleFramesCount()
     public int GetVisibleFramesCount()
     {
     {
         return GetLastVisibleFrame() - GetFirstVisibleFrame();
         return GetLastVisibleFrame() - GetFirstVisibleFrame();
     }
     }
+
+    private static bool OrderDifferent(IReadOnlyCollection<ICelHandler> keyFrames,
+        IReadOnlyCollection<ILayerHandler> allLayers)
+    {
+        List<ICelGroupHandler> groups = new List<ICelGroupHandler>();
+
+        foreach (var keyFrame in keyFrames)
+        {
+            if (keyFrame is ICelGroupHandler group)
+            {
+                groups.Add(group);
+            }
+        }
+
+        if (groups.Count != allLayers.Count)
+        {
+            return true;
+        }
+
+        for (int i = 0; i < groups.Count; i++)
+        {
+            if (groups[i].LayerGuid != allLayers.ElementAt(i).Id)
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
 }
 }