Browse Source

Added rasterize layer

flabbet 11 months ago
parent
commit
6ffad7bb88

+ 11 - 3
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/VectorLayerNode.cs

@@ -7,12 +7,13 @@ using PixiEditor.ChangeableDocument.ChangeInfos.Vectors;
 using PixiEditor.ChangeableDocument.Rendering;
 using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
+using PixiEditor.DrawingApi.Core.Surfaces;
 using PixiEditor.Numerics;
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 
 [NodeInfo("VectorLayer")]
-public class VectorLayerNode : LayerNode, ITransformableObject, IReadOnlyVectorNode
+public class VectorLayerNode : LayerNode, ITransformableObject, IReadOnlyVectorNode, IRasterizable
 {
     public Matrix3X3 TransformationMatrix
     {
@@ -86,9 +87,16 @@ public class VectorLayerNode : LayerNode, ITransformableObject, IReadOnlyVectorN
         return ShapeData?.TransformationCorners ?? new ShapeCorners();
     }
 
-    public override Node CreateCopy()
+    public void Rasterize(DrawingSurface surface, ChunkResolution resolution)
     {
-        return new VectorLayerNode();
+        ShapeData?.Rasterize(surface, resolution);
     }
 
+    public override Node CreateCopy()
+    {
+        return new VectorLayerNode()
+        {
+            ShapeData = (ShapeVectorData?)ShapeData?.Clone(),
+        };
+    }
 }

+ 8 - 0
src/PixiEditor.ChangeableDocument/Changeables/Interfaces/IRasterizable.cs

@@ -0,0 +1,8 @@
+using PixiEditor.DrawingApi.Core.Surfaces;
+
+namespace PixiEditor.ChangeableDocument.Changeables.Interfaces;
+
+public interface IRasterizable
+{
+    public void Rasterize(DrawingSurface surface, ChunkResolution resolution);
+}

+ 108 - 0
src/PixiEditor.ChangeableDocument/Changes/Structure/RasterizeMember_Change.cs

@@ -0,0 +1,108 @@
+using PixiEditor.ChangeableDocument.Changeables.Graph;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
+using PixiEditor.ChangeableDocument.Changeables.Interfaces;
+using PixiEditor.ChangeableDocument.ChangeInfos.NodeGraph;
+using PixiEditor.ChangeableDocument.Changes.NodeGraph;
+using PixiEditor.DrawingApi.Core;
+using PixiEditor.Numerics;
+
+namespace PixiEditor.ChangeableDocument.Changes.Structure;
+
+internal class RasterizeMember_Change : Change
+{
+    private Guid memberId;
+    
+    private Node originalNode;
+    private Guid createdNodeId;
+    
+    private ConnectionsData originalConnections;
+    
+    [GenerateMakeChangeAction]
+    public RasterizeMember_Change(Guid memberId)
+    {
+        this.memberId = memberId;
+    }
+    
+    public override bool InitializeAndValidate(Document target)
+    {
+        if (target.TryFindMember(memberId, out var member) 
+            && member is not IReadOnlyImageNode && member is IRasterizable)
+        {
+            originalNode = member.Clone();
+            originalConnections = NodeOperations.CreateConnectionsData(member);
+            return true;
+        }
+        
+        return false;
+    }
+
+    public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target, bool firstApply, out bool ignoreInUndo)
+    {
+        Node node = target.FindMember(memberId);
+        
+        IRasterizable rasterizable = (IRasterizable)node;
+        
+        ImageLayerNode imageLayer = new ImageLayerNode(target.Size);
+
+        target.NodeGraph.AddNode(imageLayer);
+        
+        using Surface surface = new Surface(target.Size);
+        rasterizable.Rasterize(surface.DrawingSurface, ChunkResolution.Full);
+        
+        var image = imageLayer.GetLayerImageAtFrame(0);
+        image.EnqueueDrawImage(VecI.Zero, surface);
+        image.CommitChanges();
+
+        OutputProperty<Texture>? outputConnection = node.OutputProperties.FirstOrDefault(x => x is OutputProperty<Texture>) as OutputProperty<Texture>;
+        InputProperty<Texture>? outputConnectedInput =
+            outputConnection?.Connections.FirstOrDefault(x => x is InputProperty<Texture>) as InputProperty<Texture>;
+
+        InputProperty<Texture> backgroundInput = imageLayer.Background;
+        OutputProperty<Texture> toAddOutput = imageLayer.Output;
+
+        List<IChangeInfo> changeInfos = new();
+        changeInfos.Add(CreateNode_ChangeInfo.CreateFromNode(imageLayer));
+        changeInfos.AddRange(NodeOperations.AppendMember(outputConnectedInput, toAddOutput, backgroundInput, imageLayer.Id));
+        changeInfos.AddRange(NodeOperations.DetachNode(target.NodeGraph, node));
+        
+        node.Dispose();
+        target.NodeGraph.RemoveNode(node);
+        
+        changeInfos.Add(new DeleteNode_ChangeInfo(node.Id));
+        
+        createdNodeId = imageLayer.Id;
+        
+        ignoreInUndo = false;
+        return changeInfos;
+    }
+
+    public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
+    {
+        Node node = target.FindMember(createdNodeId);
+        
+        List<IChangeInfo> changeInfos = new();
+        changeInfos.AddRange(NodeOperations.DetachNode(target.NodeGraph, node));
+        
+        node.Dispose();
+        target.NodeGraph.RemoveNode(node);
+        
+        changeInfos.Add(new DeleteNode_ChangeInfo(node.Id));
+        
+        var restoredNode = originalNode.Clone();
+        restoredNode.Id = memberId;
+        
+        target.NodeGraph.AddNode(restoredNode);
+        
+        changeInfos.Add(CreateNode_ChangeInfo.CreateFromNode(restoredNode));
+        
+        changeInfos.AddRange(NodeOperations.ConnectStructureNodeProperties(originalConnections, restoredNode, target.NodeGraph));
+        
+        return changeInfos;   
+    }
+
+    public override void Dispose()
+    {
+        originalNode.Dispose();
+    }
+}

+ 8 - 0
src/PixiEditor/Models/DocumentModels/Public/DocumentOperationsModule.cs

@@ -716,4 +716,12 @@ internal class DocumentOperationsModule : IDocumentOperations
 
         return parent.Id;
     }
+
+    public void Rasterize(Guid memberId)
+    {
+        if (Internals.ChangeController.IsChangeActive)
+            return;
+
+        Internals.ActionAccumulator.AddFinishedActions(new RasterizeMember_Action(memberId));    
+    }
 }

+ 11 - 0
src/PixiEditor/ViewModels/SubViewModels/LayersViewModel.cs

@@ -431,6 +431,17 @@ internal class LayersViewModel : SubViewModel<ViewModelMain>
 
         doc.Operations.ResetReferenceLayerPosition();
     }
+    
+    [Command.Basic("PixiEditor.Layer.RasterizeActiveLayer", "RASTERIZE_ACTIVE_LAYER", "RASTERIZE_ACTIVE_LAYER", CanExecute = "PixiEditor.Layer.SelectedMemberIsLayer")]
+    public void RasterizeActiveLayer()
+    {
+        var doc = Owner.DocumentManagerSubViewModel.ActiveDocument;
+        var member = doc?.SelectedStructureMember;
+        if (member is null)
+            return;
+        
+        doc!.Operations.Rasterize(member.Id);
+    }
 
     [Evaluator.Icon("PixiEditor.Layer.ToggleReferenceLayerTopMostIcon")]
     public IImage GetAboveEverythingReferenceLayerIcon()