Browse Source

Vector layer node now applies all layer elements properly

flabbet 11 months ago
parent
commit
cfbc7137ad

+ 35 - 129
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/ImageLayerNode.cs

@@ -21,7 +21,7 @@ public class ImageLayerNode : LayerNode, IReadOnlyImageNode
 
 
     private VecI size;
     private VecI size;
     private ChunkyImage layerImage => keyFrames[0]?.Data as ChunkyImage;
     private ChunkyImage layerImage => keyFrames[0]?.Data as ChunkyImage;
-    
+
 
 
     protected Dictionary<(ChunkResolution, int), Texture> workingSurfaces =
     protected Dictionary<(ChunkResolution, int), Texture> workingSurfaces =
         new Dictionary<(ChunkResolution, int), Texture>();
         new Dictionary<(ChunkResolution, int), Texture>();
@@ -58,140 +58,46 @@ public class ImageLayerNode : LayerNode, IReadOnlyImageNode
 
 
     protected override Texture? OnExecute(RenderingContext context)
     protected override Texture? OnExecute(RenderingContext context)
     {
     {
-        if (!IsVisible.Value || Opacity.Value <= 0 || IsEmptyMask())
-        {
-            Output.Value = Background.Value;
-            return Output.Value;
-        }
-
-        var frameImage = GetFrameWithImage(context.FrameTime);
-
-        blendPaint.Color = new Color(255, 255, 255, 255);
-        blendPaint.BlendMode = DrawingApi.Core.Surfaces.BlendMode.Src;
-
-        var renderedSurface = RenderImage(frameImage.Data as ChunkyImage, context);
-
-        Output.Value = renderedSurface;
-
-        return Output.Value;
-    }
-
-    private Texture RenderImage(ChunkyImage frameImage, RenderingContext context)
-    {
-        bool shouldClear = Background.Value == null;
-
-        if (FilterlessOutput.Connections.Count > 0)
-        {
-            var filterlessWorkingSurface = TryInitWorkingSurface(frameImage.LatestSize, context, 1);
-
-            if (Background.Value != null)
-            {
-                DrawBackground(filterlessWorkingSurface, context);
-                blendPaint.BlendMode = RenderingContext.GetDrawingBlendMode(BlendMode.Value);
-            }
-
-            DrawLayer(frameImage, context, filterlessWorkingSurface, shouldClear, useFilters: false);
-            blendPaint.BlendMode = DrawingApi.Core.Surfaces.BlendMode.Src;
-
-            FilterlessOutput.Value = filterlessWorkingSurface;
-        }
+        var rendered = base.OnExecute(context);
 
 
         if (RawOutput.Connections.Count > 0)
         if (RawOutput.Connections.Count > 0)
         {
         {
-            var rawWorkingSurface = TryInitWorkingSurface(frameImage.LatestSize, context, 2);
-            DrawLayer(frameImage, context, rawWorkingSurface, true, useFilters: false);
+            var rawWorkingSurface = TryInitWorkingSurface(GetTargetSize(context), context, 2);
+            DrawLayer(context, rawWorkingSurface, true, useFilters: false);
 
 
             RawOutput.Value = rawWorkingSurface;
             RawOutput.Value = rawWorkingSurface;
         }
         }
 
 
-        if (Output.Connections.Count > 0)
-        {
-            var outputWorkingSurface = TryInitWorkingSurface(frameImage.LatestSize, context, 0);
-
-            if (!HasOperations())
-            {
-                if (Background.Value != null)
-                {
-                    DrawBackground(outputWorkingSurface, context);
-                    blendPaint.BlendMode = RenderingContext.GetDrawingBlendMode(BlendMode.Value);
-                }
-
-                DrawLayer(frameImage, context, outputWorkingSurface, shouldClear);
-
-                Output.Value = outputWorkingSurface;
-
-                return outputWorkingSurface;
-            }
-
-            DrawLayer(frameImage, context, outputWorkingSurface, true);
-
-            // shit gets downhill with mask on big canvases, TODO: optimize
-            ApplyMaskIfPresent(outputWorkingSurface, context);
-
-            if (Background.Value != null)
-            {
-                Texture tempSurface = RequestTexture(4, outputWorkingSurface.Size, true);
-                DrawBackground(tempSurface, context);
-                ApplyRasterClip(outputWorkingSurface, tempSurface);
-                blendPaint.BlendMode = RenderingContext.GetDrawingBlendMode(BlendMode.Value);
-                tempSurface.DrawingSurface.Canvas.DrawSurface(outputWorkingSurface.DrawingSurface, 0, 0, blendPaint);
-                Output.Value = tempSurface;
-                return tempSurface;
-            }
-
-            Output.Value = outputWorkingSurface;
-
-            return outputWorkingSurface;
-        }
-
-        return null;
+        return rendered;
     }
     }
 
 
-    protected Texture TryInitWorkingSurface(VecI imageSize, RenderingContext context, int id)
+    protected override VecI GetTargetSize(RenderingContext ctx)
     {
     {
-        ChunkResolution targetResolution = context.ChunkResolution;
-        bool hasSurface = workingSurfaces.TryGetValue((targetResolution, id), out Texture workingSurface);
-        VecI targetSize = (VecI)(imageSize * targetResolution.Multiplier());
-
-        if (!hasSurface || workingSurface.Size != targetSize || workingSurface.IsDisposed)
-        {
-            workingSurfaces[(targetResolution, id)] = new Texture(targetSize);
-            workingSurface = workingSurfaces[(targetResolution, id)];
-        }
-
-        return workingSurface;
+        return (GetFrameWithImage(ctx.FrameTime).Data as ChunkyImage).LatestSize;
     }
     }
 
 
-    private void DrawLayer(ChunkyImage frameImage, RenderingContext context, Texture workingSurface, bool shouldClear,
-        bool useFilters = true)
+    protected override void DrawWithoutFilters(RenderingContext ctx, Texture workingSurface, bool shouldClear,
+        Paint paint)
     {
     {
-        blendPaint.Color = blendPaint.Color.WithAlpha((byte)Math.Round(Opacity.Value * 255));
-
-        if (useFilters && Filters.Value != null)
+        var frameImage = GetFrameWithImage(ctx.FrameTime).Data as ChunkyImage;
+        if (!frameImage.DrawMostUpToDateChunkOn(
+                ctx.ChunkToUpdate,
+                ctx.ChunkResolution,
+                workingSurface.DrawingSurface,
+                ctx.ChunkToUpdate * ctx.ChunkResolution.PixelSize(),
+                blendPaint) && shouldClear)
         {
         {
-            DrawWithFilters(frameImage, context, workingSurface, shouldClear);
-        }
-        else
-        {
-            blendPaint.SetFilters(null);
-
-            if (!frameImage.DrawMostUpToDateChunkOn(
-                    context.ChunkToUpdate,
-                    context.ChunkResolution,
-                    workingSurface.DrawingSurface,
-                    context.ChunkToUpdate * context.ChunkResolution.PixelSize(),
-                    blendPaint) && shouldClear)
-            {
-                workingSurface.DrawingSurface.Canvas.DrawRect(CalculateDestinationRect(context), clearPaint);
-            }
+            workingSurface.DrawingSurface.Canvas.DrawRect(CalculateDestinationRect(ctx), clearPaint);
         }
         }
     }
     }
 
 
     // Draw with filters is a bit tricky since some filters sample data from chunks surrounding the chunk being drawn,
     // Draw with filters is a bit tricky since some filters sample data from chunks surrounding the chunk being drawn,
     // this is why we need to do intermediate drawing to a temporary surface and then apply filters to that surface
     // this is why we need to do intermediate drawing to a temporary surface and then apply filters to that surface
-    private void DrawWithFilters(ChunkyImage frameImage, RenderingContext context, Texture workingSurface,
-        bool shouldClear)
+    protected override void DrawWithFilters(RenderingContext context, Texture workingSurface,
+        bool shouldClear, Paint paint)
     {
     {
+        var frameImage = GetFrameWithImage(context.FrameTime).Data as ChunkyImage;
+        
         VecI imageChunksSize = frameImage.LatestSize / context.ChunkResolution.PixelSize();
         VecI imageChunksSize = frameImage.LatestSize / context.ChunkResolution.PixelSize();
         bool requiresTopLeft = context.ChunkToUpdate.X > 0 || context.ChunkToUpdate.Y > 0;
         bool requiresTopLeft = context.ChunkToUpdate.X > 0 || context.ChunkToUpdate.Y > 0;
         bool requiresTop = context.ChunkToUpdate.Y > 0;
         bool requiresTop = context.ChunkToUpdate.Y > 0;
@@ -240,51 +146,51 @@ public class ImageLayerNode : LayerNode, IReadOnlyImageNode
 
 
         if (requiresTopLeft)
         if (requiresTopLeft)
         {
         {
-            DrawChunk(frameImage, context, tempSurface, new VecI(-1, -1));
+            DrawChunk(frameImage, context, tempSurface, new VecI(-1, -1), paint);
         }
         }
 
 
         if (requiresTop)
         if (requiresTop)
         {
         {
-            DrawChunk(frameImage, context, tempSurface, new VecI(0, -1));
+            DrawChunk(frameImage, context, tempSurface, new VecI(0, -1), paint);
         }
         }
 
 
         if (requiresLeft)
         if (requiresLeft)
         {
         {
-            DrawChunk(frameImage, context, tempSurface, new VecI(-1, 0));
+            DrawChunk(frameImage, context, tempSurface, new VecI(-1, 0), paint);
         }
         }
 
 
         if (requiresTopRight)
         if (requiresTopRight)
         {
         {
-            DrawChunk(frameImage, context, tempSurface, new VecI(1, -1));
+            DrawChunk(frameImage, context, tempSurface, new VecI(1, -1), paint);
         }
         }
 
 
         if (requiresRight)
         if (requiresRight)
         {
         {
-            DrawChunk(frameImage, context, tempSurface, new VecI(1, 0));
+            DrawChunk(frameImage, context, tempSurface, new VecI(1, 0), paint);
         }
         }
 
 
         if (requiresBottomRight)
         if (requiresBottomRight)
         {
         {
-            DrawChunk(frameImage, context, tempSurface, new VecI(1, 1));
+            DrawChunk(frameImage, context, tempSurface, new VecI(1, 1), paint);
         }
         }
 
 
         if (requiresBottom)
         if (requiresBottom)
         {
         {
-            DrawChunk(frameImage, context, tempSurface, new VecI(0, 1));
+            DrawChunk(frameImage, context, tempSurface, new VecI(0, 1), paint);
         }
         }
 
 
         if (requiresBottomLeft)
         if (requiresBottomLeft)
         {
         {
-            DrawChunk(frameImage, context, tempSurface, new VecI(-1, 1));
+            DrawChunk(frameImage, context, tempSurface, new VecI(-1, 1), paint);
         }
         }
 
 
-        DrawChunk(frameImage, context, tempSurface, new VecI(0, 0));
+        DrawChunk(frameImage, context, tempSurface, new VecI(0, 0), paint);
 
 
-        blendPaint.SetFilters(Filters.Value);
-        workingSurface.DrawingSurface.Canvas.DrawSurface(tempSurface.DrawingSurface, VecI.Zero, blendPaint);
+        workingSurface.DrawingSurface.Canvas.DrawSurface(tempSurface.DrawingSurface, VecI.Zero, paint);
     }
     }
 
 
-    private void DrawChunk(ChunkyImage frameImage, RenderingContext context, Texture tempSurface, VecI vecI)
+    private void DrawChunk(ChunkyImage frameImage, RenderingContext context, Texture tempSurface, VecI vecI,
+        Paint paint)
     {
     {
         VecI chunkPos = context.ChunkToUpdate + vecI;
         VecI chunkPos = context.ChunkToUpdate + vecI;
         if (frameImage.LatestOrCommittedChunkExists(chunkPos))
         if (frameImage.LatestOrCommittedChunkExists(chunkPos))
@@ -294,7 +200,7 @@ public class ImageLayerNode : LayerNode, IReadOnlyImageNode
                 context.ChunkResolution,
                 context.ChunkResolution,
                 tempSurface.DrawingSurface,
                 tempSurface.DrawingSurface,
                 chunkPos * context.ChunkResolution.PixelSize(),
                 chunkPos * context.ChunkResolution.PixelSize(),
-                blendPaint);
+                paint);
         }
         }
     }
     }
 
 
@@ -313,7 +219,7 @@ public class ImageLayerNode : LayerNode, IReadOnlyImageNode
     protected override bool CacheChanged(RenderingContext context)
     protected override bool CacheChanged(RenderingContext context)
     {
     {
         var frame = GetFrameWithImage(context.FrameTime);
         var frame = GetFrameWithImage(context.FrameTime);
-        
+
         return base.CacheChanged(context) || frame?.RequiresUpdate == true;
         return base.CacheChanged(context) || frame?.RequiresUpdate == true;
     }
     }
 
 

+ 125 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/LayerNode.cs

@@ -1,9 +1,134 @@
 using PixiEditor.ChangeableDocument.Changeables.Animations;
 using PixiEditor.ChangeableDocument.Changeables.Animations;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
+using PixiEditor.ChangeableDocument.Helpers;
+using PixiEditor.ChangeableDocument.Rendering;
+using PixiEditor.DrawingApi.Core;
+using PixiEditor.DrawingApi.Core.ColorsImpl;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 using PixiEditor.Numerics;
 
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 
 
 public abstract class LayerNode : StructureNode, IReadOnlyLayerNode
 public abstract class LayerNode : StructureNode, IReadOnlyLayerNode
 {
 {
+    protected Dictionary<(ChunkResolution, int), Texture> workingSurfaces =
+        new Dictionary<(ChunkResolution, int), Texture>();
+
+    protected override Texture? OnExecute(RenderingContext context)
+    {
+        if (!IsVisible.Value || Opacity.Value <= 0 || IsEmptyMask())
+        {
+            Output.Value = Background.Value;
+            return Output.Value;
+        }
+
+        blendPaint.Color = new Color(255, 255, 255, 255);
+        blendPaint.BlendMode = DrawingApi.Core.Surfaces.BlendMode.Src;
+
+        VecI targetSize = GetTargetSize(context);
+        bool shouldClear = Background.Value == null;
+
+        if (FilterlessOutput.Connections.Count > 0)
+        {
+            var filterlessWorkingSurface = TryInitWorkingSurface(targetSize, context, 0);
+
+            if (Background.Value != null)
+            {
+                DrawBackground(filterlessWorkingSurface, context);
+                blendPaint.BlendMode = RenderingContext.GetDrawingBlendMode(BlendMode.Value);
+            }
+
+            DrawLayer(context, filterlessWorkingSurface, shouldClear, useFilters: false);
+            blendPaint.BlendMode = DrawingApi.Core.Surfaces.BlendMode.Src;
+
+            FilterlessOutput.Value = filterlessWorkingSurface;
+        }
+
+        var rendered = RenderImage(targetSize, context, shouldClear);
+        Output.Value = rendered;
+
+        return rendered;
+    }
+
+    private Texture RenderImage(VecI size, RenderingContext context, bool shouldClear)
+    {
+        if (Output.Connections.Count > 0)
+        {
+            var outputWorkingSurface = TryInitWorkingSurface(size, context, 1);
+
+            if (!HasOperations())
+            {
+                if (Background.Value != null)
+                {
+                    DrawBackground(outputWorkingSurface, context);
+                    blendPaint.BlendMode = RenderingContext.GetDrawingBlendMode(BlendMode.Value);
+                }
+
+                DrawLayer(context, outputWorkingSurface, shouldClear);
+
+                return outputWorkingSurface;
+            }
+
+            DrawLayer(context, outputWorkingSurface, true);
+
+            // shit gets downhill with mask on big canvases, TODO: optimize
+            ApplyMaskIfPresent(outputWorkingSurface, context);
+
+            if (Background.Value != null)
+            {
+                Texture tempSurface = RequestTexture(4, outputWorkingSurface.Size, true);
+                DrawBackground(tempSurface, context);
+                ApplyRasterClip(outputWorkingSurface, tempSurface);
+                blendPaint.BlendMode = RenderingContext.GetDrawingBlendMode(BlendMode.Value);
+                tempSurface.DrawingSurface.Canvas.DrawSurface(outputWorkingSurface.DrawingSurface, 0, 0,
+                    blendPaint);
+
+                return tempSurface;
+            }
+
+            return outputWorkingSurface;
+        }
+
+        return null;
+    }
+
+    protected abstract VecI GetTargetSize(RenderingContext ctx);
+
+    protected virtual void DrawLayer(RenderingContext ctx, Texture workingSurface, bool shouldClear,
+        bool useFilters = true)
+    {
+        blendPaint.Color = blendPaint.Color.WithAlpha((byte)Math.Round(Opacity.Value * 255));
+
+        if (useFilters && Filters.Value != null)
+        {
+            blendPaint.SetFilters(Filters.Value);
+            DrawWithFilters(ctx, workingSurface, shouldClear, blendPaint);
+        }
+        else
+        {
+            blendPaint.SetFilters(null);
+            DrawWithoutFilters(ctx, workingSurface, shouldClear, blendPaint);
+        }
+    }
+    
+    protected abstract void DrawWithoutFilters(RenderingContext ctx, Texture workingSurface, bool shouldClear,
+        Paint paint);
+    
+    protected abstract void DrawWithFilters(RenderingContext ctx, Texture workingSurface, bool shouldClear,
+        Paint paint);
+
+    protected Texture TryInitWorkingSurface(VecI imageSize, RenderingContext context, int id)
+    {
+        ChunkResolution targetResolution = context.ChunkResolution;
+        bool hasSurface = workingSurfaces.TryGetValue((targetResolution, id), out Texture workingSurface);
+        VecI targetSize = (VecI)(imageSize * targetResolution.Multiplier());
+
+        if (!hasSurface || workingSurface.Size != targetSize || workingSurface.IsDisposed)
+        {
+            workingSurfaces[(targetResolution, id)] = new Texture(targetSize);
+            workingSurface = workingSurfaces[(targetResolution, id)];
+        }
+
+        return workingSurface;
+    }
 }
 }

+ 3 - 2
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/Data/EllipseVectorData.cs

@@ -1,5 +1,6 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces.Shapes;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces.Shapes;
 using PixiEditor.DrawingApi.Core.Surfaces;
 using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.DrawingApi.Core.Surfaces.Vector;
 using PixiEditor.DrawingApi.Core.Surfaces.Vector;
 using PixiEditor.Numerics;
 using PixiEditor.Numerics;
 
 
@@ -23,7 +24,7 @@ public class EllipseVectorData : ShapeVectorData, IReadOnlyEllipseData
         Radius = radius;
         Radius = radius;
     }
     }
 
 
-    public override void Rasterize(DrawingSurface drawingSurface, ChunkResolution resolution)
+    public override void Rasterize(DrawingSurface drawingSurface, ChunkResolution resolution, Paint paint)
     {
     {
         var imageSize = (VecI)(Radius * 2);
         var imageSize = (VecI)(Radius * 2);
         
         
@@ -44,7 +45,7 @@ public class EllipseVectorData : ShapeVectorData, IReadOnlyEllipseData
         int num = drawingSurface.Canvas.Save();
         int num = drawingSurface.Canvas.Save();
         drawingSurface.Canvas.SetMatrix(TransformationMatrix);
         drawingSurface.Canvas.SetMatrix(TransformationMatrix);
 
 
-        img.DrawMostUpToDateRegionOn(region, resolution, drawingSurface, topLeft);
+        img.DrawMostUpToDateRegionOn(region, resolution, drawingSurface, topLeft, paint);
         
         
         drawingSurface.Canvas.RestoreToCount(num);
         drawingSurface.Canvas.RestoreToCount(num);
     }
     }

+ 2 - 2
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/Data/LineVectorData.cs

@@ -31,7 +31,7 @@ public class LineVectorData(VecD startPos, VecD pos) : ShapeVectorData, IReadOnl
     public override ShapeCorners TransformationCorners => new ShapeCorners(GeometryAABB)
     public override ShapeCorners TransformationCorners => new ShapeCorners(GeometryAABB)
         .WithMatrix(TransformationMatrix);
         .WithMatrix(TransformationMatrix);
 
 
-    public override void Rasterize(DrawingSurface drawingSurface, ChunkResolution resolution)
+    public override void Rasterize(DrawingSurface drawingSurface, ChunkResolution resolution, Paint paint)
     {
     {
         RectD adjustedAABB = GeometryAABB.RoundOutwards().Inflate(1);
         RectD adjustedAABB = GeometryAABB.RoundOutwards().Inflate(1);
         var imageSize = (VecI)adjustedAABB.Size;
         var imageSize = (VecI)adjustedAABB.Size;
@@ -60,7 +60,7 @@ public class LineVectorData(VecD startPos, VecD pos) : ShapeVectorData, IReadOnl
         int num = drawingSurface.Canvas.Save();
         int num = drawingSurface.Canvas.Save();
         drawingSurface.Canvas.SetMatrix(TransformationMatrix);
         drawingSurface.Canvas.SetMatrix(TransformationMatrix);
         
         
-        img.DrawMostUpToDateRegionOn(region, resolution, drawingSurface, topLeft);
+        img.DrawMostUpToDateRegionOn(region, resolution, drawingSurface, topLeft, paint);
         
         
         drawingSurface.Canvas.RestoreToCount(num);
         drawingSurface.Canvas.RestoreToCount(num);
     }
     }

+ 1 - 2
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/Data/PointsVectorData.cs

@@ -18,9 +18,8 @@ public class PointsVectorData : ShapeVectorData
     public override ShapeCorners TransformationCorners => new ShapeCorners(
     public override ShapeCorners TransformationCorners => new ShapeCorners(
         GeometryAABB).WithMatrix(TransformationMatrix); 
         GeometryAABB).WithMatrix(TransformationMatrix); 
 
 
-    public override void Rasterize(DrawingSurface drawingSurface, ChunkResolution resolution)
+    public override void Rasterize(DrawingSurface drawingSurface, ChunkResolution resolution, Paint paint)
     {
     {
-        using Paint paint = new Paint();
         paint.Color = FillColor;
         paint.Color = FillColor;
         paint.StrokeWidth = StrokeWidth;
         paint.StrokeWidth = StrokeWidth;
         
         

+ 3 - 2
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/Data/RectangleVectorData.cs

@@ -1,5 +1,6 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces.Shapes;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces.Shapes;
 using PixiEditor.DrawingApi.Core.Surfaces;
 using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.DrawingApi.Core.Surfaces.Vector;
 using PixiEditor.DrawingApi.Core.Surfaces.Vector;
 using PixiEditor.Numerics;
 using PixiEditor.Numerics;
 
 
@@ -22,7 +23,7 @@ public class RectangleVectorData : ShapeVectorData, IReadOnlyRectangleData
         Size = size;
         Size = size;
     }
     }
     
     
-    public override void Rasterize(DrawingSurface drawingSurface, ChunkResolution resolution)
+    public override void Rasterize(DrawingSurface drawingSurface, ChunkResolution resolution, Paint paint)
     {
     {
         var imageSize = (VecI)Size; 
         var imageSize = (VecI)Size; 
 
 
@@ -41,7 +42,7 @@ public class RectangleVectorData : ShapeVectorData, IReadOnlyRectangleData
         int num = drawingSurface.Canvas.Save();
         int num = drawingSurface.Canvas.Save();
         drawingSurface.Canvas.SetMatrix(TransformationMatrix);
         drawingSurface.Canvas.SetMatrix(TransformationMatrix);
 
 
-        img.DrawMostUpToDateRegionOn(region, resolution, drawingSurface, topLeft);
+        img.DrawMostUpToDateRegionOn(region, resolution, drawingSurface, topLeft, paint);
 
 
         drawingSurface.Canvas.RestoreToCount(num);
         drawingSurface.Canvas.RestoreToCount(num);
     }
     }

+ 2 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/Data/ShapeVectorData.cs

@@ -3,6 +3,7 @@ using PixiEditor.Common;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surfaces;
 using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 using PixiEditor.Numerics;
 
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes.Data;
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes.Data;
@@ -18,7 +19,7 @@ public abstract class ShapeVectorData : ICacheable, ICloneable, IReadOnlyShapeVe
     public RectD TransformedAABB => new ShapeCorners(GeometryAABB).WithMatrix(TransformationMatrix).AABBBounds;
     public RectD TransformedAABB => new ShapeCorners(GeometryAABB).WithMatrix(TransformationMatrix).AABBBounds;
     public abstract ShapeCorners TransformationCorners { get; } 
     public abstract ShapeCorners TransformationCorners { get; } 
 
 
-    public abstract void Rasterize(DrawingSurface drawingSurface, ChunkResolution resolution);
+    public abstract void Rasterize(DrawingSurface drawingSurface, ChunkResolution resolution, Paint? paint);
     public abstract bool IsValid();
     public abstract bool IsValid();
     public abstract int GetCacheHash();
     public abstract int GetCacheHash();
     public abstract int CalculateHash();
     public abstract int CalculateHash();

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/RasterizeShapeNode.cs

@@ -35,7 +35,7 @@ public class RasterizeShapeNode : Node
         var size = context.DocumentSize;
         var size = context.DocumentSize;
         var image = RequestTexture(0, size);
         var image = RequestTexture(0, size);
         
         
-        shape.Rasterize(image.DrawingSurface, context.ChunkResolution);
+        shape.Rasterize(image.DrawingSurface, context.ChunkResolution, null);
 
 
         Image.Value = image;
         Image.Value = image;
         
         

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/ShapeNode.cs

@@ -33,7 +33,7 @@ public abstract class ShapeNode<T> : Node where T : ShapeVectorData
     {
     {
         Texture texture = RequestTexture(0, size);
         Texture texture = RequestTexture(0, size);
         
         
-        vectorData.Rasterize(texture.DrawingSurface, ChunkResolution.Full);
+        vectorData.Rasterize(texture.DrawingSurface, ChunkResolution.Full, null);
         
         
         return texture;
         return texture;
     }
     }

+ 29 - 6
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/VectorLayerNode.cs

@@ -8,6 +8,7 @@ using PixiEditor.ChangeableDocument.Rendering;
 using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surfaces;
 using PixiEditor.DrawingApi.Core.Surfaces;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 using PixiEditor.Numerics;
 
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
@@ -44,13 +45,35 @@ public class VectorLayerNode : LayerNode, ITransformableObject, IReadOnlyVectorN
             return null;
             return null;
         }
         }
         
         
-        Texture texture = RequestTexture(0, context.DocumentSize);
+        var rendered = base.OnExecute(context);
+        Output.Value = rendered;
+        
+        return rendered;
+    }
 
 
-        ShapeData.Rasterize(texture.DrawingSurface, context.ChunkResolution);
+    protected override VecI GetTargetSize(RenderingContext ctx)
+    {
+        return ctx.DocumentSize;
+    }
+
+    protected override void DrawWithoutFilters(RenderingContext ctx, Texture workingSurface, bool shouldClear, Paint paint)
+    {
+        if(shouldClear)
+        {
+            workingSurface.DrawingSurface.Canvas.Clear();
+        }
         
         
-        Output.Value = texture;
+        Rasterize(workingSurface.DrawingSurface, ctx.ChunkResolution, paint);
+    }
+
+    protected override void DrawWithFilters(RenderingContext ctx, Texture workingSurface, bool shouldClear, Paint paint)
+    {
+        if(shouldClear)
+        {
+            workingSurface.DrawingSurface.Canvas.Clear();
+        }
         
         
-        return texture;
+        Rasterize(workingSurface.DrawingSurface, ctx.ChunkResolution, paint);
     }
     }
 
 
     public override void SerializeAdditionalData(Dictionary<string, object> additionalData)
     public override void SerializeAdditionalData(Dictionary<string, object> additionalData)
@@ -87,9 +110,9 @@ public class VectorLayerNode : LayerNode, ITransformableObject, IReadOnlyVectorN
         return ShapeData?.TransformationCorners ?? new ShapeCorners();
         return ShapeData?.TransformationCorners ?? new ShapeCorners();
     }
     }
 
 
-    public void Rasterize(DrawingSurface surface, ChunkResolution resolution)
+    public void Rasterize(DrawingSurface surface, ChunkResolution resolution, Paint paint)
     {
     {
-        ShapeData?.Rasterize(surface, resolution);
+        ShapeData?.Rasterize(surface, resolution, paint);
     }
     }
 
 
     public override Node CreateCopy()
     public override Node CreateCopy()

+ 2 - 1
src/PixiEditor.ChangeableDocument/Changeables/Interfaces/IRasterizable.cs

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

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changes/Structure/RasterizeMember_Change.cs

@@ -48,7 +48,7 @@ internal class RasterizeMember_Change : Change
         target.NodeGraph.AddNode(imageLayer);
         target.NodeGraph.AddNode(imageLayer);
         
         
         using Surface surface = new Surface(target.Size);
         using Surface surface = new Surface(target.Size);
-        rasterizable.Rasterize(surface.DrawingSurface, ChunkResolution.Full);
+        rasterizable.Rasterize(surface.DrawingSurface, ChunkResolution.Full, null);
         
         
         var image = imageLayer.GetLayerImageAtFrame(0);
         var image = imageLayer.GetLayerImageAtFrame(0);
         image.EnqueueDrawImage(VecI.Zero, surface);
         image.EnqueueDrawImage(VecI.Zero, surface);