Browse Source

Shape rasterizing finally makes sense

flabbet 10 months ago
parent
commit
5f2ccdde94

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

@@ -12,7 +12,7 @@ public interface IReadOnlyStructureNode : IReadOnlyNode, ISceneObject
     public InputProperty<bool> IsVisible { get; }
     public InputProperty<bool> IsVisible { get; }
     public bool ClipToPreviousMember { get; }
     public bool ClipToPreviousMember { get; }
     public InputProperty<BlendMode> BlendMode { get; }
     public InputProperty<BlendMode> BlendMode { get; }
-    public InputProperty<DrawingSurface?> CustomMask { get; }
+    public InputProperty<Texture?> CustomMask { get; }
     public InputProperty<bool> MaskIsVisible { get; }
     public InputProperty<bool> MaskIsVisible { get; }
     public string MemberName { get; set; }
     public string MemberName { get; set; }
     public RectD? GetTightBounds(KeyFrameTime frameTime);
     public RectD? GetTightBounds(KeyFrameTime frameTime);

+ 1 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/ImageLayerNode.cs

@@ -96,6 +96,7 @@ public class ImageLayerNode : LayerNode, IReadOnlyImageNode
         int scaled = workingSurface.Canvas.Save();
         int scaled = workingSurface.Canvas.Save();
         float multiplier = (float)ctx.ChunkResolution.InvertedMultiplier();
         float multiplier = (float)ctx.ChunkResolution.InvertedMultiplier();
         VecD shiftToCenter = SceneSize - renderedSurfaces[ctx.ChunkResolution].Size;
         VecD shiftToCenter = SceneSize - renderedSurfaces[ctx.ChunkResolution].Size;
+        workingSurface.Canvas.Translate(ScenePosition);
         workingSurface.Canvas.Scale(multiplier, multiplier);
         workingSurface.Canvas.Scale(multiplier, multiplier);
         workingSurface.Canvas.Translate(shiftToCenter / 2f);
         workingSurface.Canvas.Translate(shiftToCenter / 2f);
         base.DrawLayer(ctx, workingSurface, useFilters);
         base.DrawLayer(ctx, workingSurface, useFilters);

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

@@ -11,6 +11,7 @@ namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes.Data;
 public class EllipseVectorData : ShapeVectorData, IReadOnlyEllipseData
 public class EllipseVectorData : ShapeVectorData, IReadOnlyEllipseData
 {
 {
     public VecD Radius { get; set; }
     public VecD Radius { get; set; }
+    
     public VecD Center { get; set; }
     public VecD Center { get; set; }
 
 
     public override RectD GeometryAABB =>
     public override RectD GeometryAABB =>
@@ -26,7 +27,7 @@ public class EllipseVectorData : ShapeVectorData, IReadOnlyEllipseData
         Radius = radius;
         Radius = radius;
     }
     }
 
 
-    public override void RasterizeGeometry(DrawingSurface drawingSurface, ChunkResolution resolution, Paint? paint)
+    public override void RasterizeGeometry(DrawingSurface drawingSurface, ChunkResolution resolution, Paint paint)
     {
     {
         Rasterize(drawingSurface, paint, false);
         Rasterize(drawingSurface, paint, false);
     }
     }
@@ -47,12 +48,12 @@ public class EllipseVectorData : ShapeVectorData, IReadOnlyEllipseData
 
 
         paint.Color = FillColor;
         paint.Color = FillColor;
         paint.Style = PaintStyle.Fill;
         paint.Style = PaintStyle.Fill;
-        drawingSurface.Canvas.DrawOval(VecD.Zero, Radius, paint);
+        drawingSurface.Canvas.DrawOval(Center, Radius, paint);
 
 
         paint.Color = StrokeColor;
         paint.Color = StrokeColor;
         paint.Style = PaintStyle.Stroke;
         paint.Style = PaintStyle.Stroke;
         paint.StrokeWidth = StrokeWidth;
         paint.StrokeWidth = StrokeWidth;
-        drawingSurface.Canvas.DrawOval(VecD.Zero, Radius - new VecD(StrokeWidth / 2f), paint);
+        drawingSurface.Canvas.DrawOval(Center, Radius - new VecD(StrokeWidth / 2f), paint);
 
 
         if (applyTransform)
         if (applyTransform)
         {
         {

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

@@ -59,23 +59,7 @@ public class LineVectorData(VecD startPos, VecD pos) : ShapeVectorData, IReadOnl
         paint.Style = PaintStyle.Stroke;
         paint.Style = PaintStyle.Stroke;
         paint.StrokeWidth = StrokeWidth;
         paint.StrokeWidth = StrokeWidth;
 
 
-        double startX;
-        double startY;
-        double endX;
-        double endY;
-
-        VecD halfSize = new VecD(GeometryAABB.Size.X / 2f - StrokeWidth, GeometryAABB.Size.Y / 2f - StrokeWidth);
-
-        startX = Start.X <= End.X ? -halfSize.X : halfSize.X;
-        endX = Start.X <= End.X ? halfSize.X : -halfSize.X;
-
-        startY = Start.Y <= End.Y ? -halfSize.Y : halfSize.Y;
-        endY = Start.Y <= End.Y ? halfSize.Y : -halfSize.Y;
-
-        VecD localStart = new VecD(startX, startY);
-        VecD localEnd = new VecD(endX, endY);
-
-        drawingSurface.Canvas.DrawLine(localStart, localEnd, paint);
+        drawingSurface.Canvas.DrawLine(Start, End, paint);
 
 
         if (applyTransform)
         if (applyTransform)
         {
         {

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

@@ -46,12 +46,12 @@ public class RectangleVectorData : ShapeVectorData, IReadOnlyRectangleData
 
 
         paint.Color = FillColor;
         paint.Color = FillColor;
         paint.Style = PaintStyle.Fill;
         paint.Style = PaintStyle.Fill;
-        drawingSurface.Canvas.DrawRect(RectD.FromCenterAndSize(VecD.Zero, Size), paint);
+        drawingSurface.Canvas.DrawRect(RectD.FromCenterAndSize(Center, Size), paint);
 
 
         paint.Color = StrokeColor;
         paint.Color = StrokeColor;
         paint.Style = PaintStyle.Stroke;
         paint.Style = PaintStyle.Stroke;
         paint.StrokeWidth = StrokeWidth;
         paint.StrokeWidth = StrokeWidth;
-        drawingSurface.Canvas.DrawRect(RectD.FromCenterAndSize(VecD.Zero, Size - new VecD(StrokeWidth)), paint);
+        drawingSurface.Canvas.DrawRect(RectD.FromCenterAndSize(Center, Size - new VecD(StrokeWidth)), paint);
 
 
         if (applyTransform)
         if (applyTransform)
         {
         {

+ 3 - 5
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/Data/ShapeVectorData.cs

@@ -23,15 +23,13 @@ public abstract class ShapeVectorData : ICacheable, ICloneable, IReadOnlyShapeVe
     {
     {
         Matrix3X3 canvasMatrix = drawingSurface.Canvas.TotalMatrix;
         Matrix3X3 canvasMatrix = drawingSurface.Canvas.TotalMatrix;
 
 
-        Matrix3X3 final = TransformationMatrix with { TransX = 0, TransY = 0 };
-
-        final = canvasMatrix.Concat(final);
+        Matrix3X3 final = canvasMatrix.Concat(TransformationMatrix);
 
 
         drawingSurface.Canvas.SetMatrix(final);
         drawingSurface.Canvas.SetMatrix(final);
     }
     }
 
 
-    public abstract void RasterizeGeometry(DrawingSurface drawingSurface, ChunkResolution resolution, Paint? paint);
-    public abstract void RasterizeTransformed(DrawingSurface drawingSurface, ChunkResolution resolution, Paint? paint);
+    public abstract void RasterizeGeometry(DrawingSurface drawingSurface, ChunkResolution resolution, Paint paint);
+    public abstract void RasterizeTransformed(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();

+ 3 - 3
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/EllipseNode.cs

@@ -8,7 +8,7 @@ namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes;
 [NodeInfo("Ellipse")]
 [NodeInfo("Ellipse")]
 public class EllipseNode : ShapeNode<EllipseVectorData>
 public class EllipseNode : ShapeNode<EllipseVectorData>
 {
 {
-    public InputProperty<VecD> Position { get; }
+    public InputProperty<VecD> Center { get; }
     public InputProperty<VecD> Radius { get; }
     public InputProperty<VecD> Radius { get; }
     public InputProperty<Color> StrokeColor { get; }
     public InputProperty<Color> StrokeColor { get; }
     public InputProperty<Color> FillColor { get; }
     public InputProperty<Color> FillColor { get; }
@@ -16,7 +16,7 @@ public class EllipseNode : ShapeNode<EllipseVectorData>
 
 
     public EllipseNode()
     public EllipseNode()
     {
     {
-        Position = CreateInput<VecD>("Position", "POSITION", VecI.Zero);
+        Center = CreateInput<VecD>("Position", "POSITION", VecI.Zero);
         Radius = CreateInput<VecD>("Radius", "RADIUS", new VecD(32, 32)).WithRules(
         Radius = CreateInput<VecD>("Radius", "RADIUS", new VecD(32, 32)).WithRules(
             v => v.Min(new VecD(1)));
             v => v.Min(new VecD(1)));
         StrokeColor = CreateInput<Color>("StrokeColor", "STROKE_COLOR", new Color(0, 0, 0, 255));
         StrokeColor = CreateInput<Color>("StrokeColor", "STROKE_COLOR", new Color(0, 0, 0, 255));
@@ -26,7 +26,7 @@ public class EllipseNode : ShapeNode<EllipseVectorData>
 
 
     protected override EllipseVectorData? GetShapeData(RenderContext context)
     protected override EllipseVectorData? GetShapeData(RenderContext context)
     {
     {
-        return new EllipseVectorData(Position.Value, Radius.Value)
+        return new EllipseVectorData(Center.Value, Radius.Value)
             { StrokeColor = StrokeColor.Value, FillColor = FillColor.Value, StrokeWidth = StrokeWidth.Value };
             { StrokeColor = StrokeColor.Value, FillColor = FillColor.Value, StrokeWidth = StrokeWidth.Value };
     }
     }
 
 

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

@@ -18,6 +18,7 @@ public class RasterizeShapeNode : Node
 
 
     protected override bool AffectedByChunkResolution => true;
     protected override bool AffectedByChunkResolution => true;
 
 
+    private Paint rasterizePaint = new Paint();
 
 
     public RasterizeShapeNode()
     public RasterizeShapeNode()
     {
     {
@@ -34,8 +35,12 @@ public class RasterizeShapeNode : Node
 
 
         var size = context.DocumentSize;
         var size = context.DocumentSize;
         var image = RequestTexture(0, size);
         var image = RequestTexture(0, size);
+
+        image.DrawingSurface.Canvas.Save();
+
+        shape.RasterizeTransformed(image.DrawingSurface, context.ChunkResolution, rasterizePaint);
         
         
-        shape.RasterizeTransformed(image.DrawingSurface, context.ChunkResolution, null);
+        image.DrawingSurface.Canvas.Restore();
 
 
         Image.Value = image;
         Image.Value = image;
         
         

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

@@ -2,6 +2,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes.Data;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes.Data;
 using PixiEditor.ChangeableDocument.Rendering;
 using PixiEditor.ChangeableDocument.Rendering;
 using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core;
+using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
 using PixiEditor.Numerics;
 
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes;
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes;
@@ -14,6 +15,8 @@ public abstract class ShapeNode<T> : Node where T : ShapeVectorData
     {
     {
         Output = CreateOutput<T>("Output", "OUTPUT", null);
         Output = CreateOutput<T>("Output", "OUTPUT", null);
     }
     }
+    
+    private static readonly Paint rasterizePreviewPaint = new Paint();
 
 
     protected override void OnExecute(RenderContext context)
     protected override void OnExecute(RenderContext context)
     {
     {
@@ -33,7 +36,7 @@ public abstract class ShapeNode<T> : Node where T : ShapeVectorData
     {
     {
         Texture texture = RequestTexture(0, size);
         Texture texture = RequestTexture(0, size);
         
         
-        vectorData.RasterizeTransformed(texture.DrawingSurface, ChunkResolution.Full, null);
+        vectorData.RasterizeTransformed(texture.DrawingSurface, ChunkResolution.Full, rasterizePreviewPaint);
         
         
         return texture;
         return texture;
     }
     }

+ 8 - 12
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/StructureNode.cs

@@ -24,7 +24,7 @@ public abstract class StructureNode : Node, IReadOnlyStructureNode, IBackgroundI
     public InputProperty<bool> IsVisible { get; }
     public InputProperty<bool> IsVisible { get; }
     public bool ClipToPreviousMember { get; set; }
     public bool ClipToPreviousMember { get; set; }
     public InputProperty<BlendMode> BlendMode { get; }
     public InputProperty<BlendMode> BlendMode { get; }
-    public InputProperty<DrawingSurface?> CustomMask { get; }
+    public InputProperty<Texture?> CustomMask { get; }
     public InputProperty<bool> MaskIsVisible { get; }
     public InputProperty<bool> MaskIsVisible { get; }
     public InputProperty<Filter> Filters { get; }
     public InputProperty<Filter> Filters { get; }
     public OutputProperty<DrawingSurface?> Output { get; }
     public OutputProperty<DrawingSurface?> Output { get; }
@@ -55,7 +55,7 @@ public abstract class StructureNode : Node, IReadOnlyStructureNode, IBackgroundI
         Opacity = CreateInput<float>("Opacity", "OPACITY", 1);
         Opacity = CreateInput<float>("Opacity", "OPACITY", 1);
         IsVisible = CreateInput<bool>("IsVisible", "IS_VISIBLE", true);
         IsVisible = CreateInput<bool>("IsVisible", "IS_VISIBLE", true);
         BlendMode = CreateInput("BlendMode", "BLEND_MODE", Enums.BlendMode.Normal);
         BlendMode = CreateInput("BlendMode", "BLEND_MODE", Enums.BlendMode.Normal);
-        CustomMask = CreateInput<DrawingSurface?>("Mask", "MASK", null);
+        CustomMask = CreateInput<Texture?>("Mask", "MASK", null);
         MaskIsVisible = CreateInput<bool>("MaskIsVisible", "MASK_IS_VISIBLE", true);
         MaskIsVisible = CreateInput<bool>("MaskIsVisible", "MASK_IS_VISIBLE", true);
         Filters = CreateInput<Filter>(nameof(Filters), "FILTERS", null);
         Filters = CreateInput<Filter>(nameof(Filters), "FILTERS", null);
 
 
@@ -73,10 +73,9 @@ public abstract class StructureNode : Node, IReadOnlyStructureNode, IBackgroundI
 
 
         DrawingSurface sceneSurface = Background.Value ?? context.TargetSurface;
         DrawingSurface sceneSurface = Background.Value ?? context.TargetSurface;
 
 
-        int savedNum = sceneSurface.Canvas.Save();  
-        
+        int savedNum = sceneSurface.Canvas.Save();
+
         sceneSurface.Canvas.ClipRect(new RectD(ScenePosition - (SceneSize / 2f), SceneSize));
         sceneSurface.Canvas.ClipRect(new RectD(ScenePosition - (SceneSize / 2f), SceneSize));
-        sceneSurface.Canvas.Translate((float)ScenePosition.X, (float)ScenePosition.Y);
 
 
         SceneObjectRenderContext renderObjectContext = new SceneObjectRenderContext(sceneSurface, localBounds,
         SceneObjectRenderContext renderObjectContext = new SceneObjectRenderContext(sceneSurface, localBounds,
             context.FrameTime, context.ChunkResolution, context.DocumentSize);
             context.FrameTime, context.ChunkResolution, context.DocumentSize);
@@ -96,18 +95,16 @@ public abstract class StructureNode : Node, IReadOnlyStructureNode, IBackgroundI
         {
         {
             if (CustomMask.Value != null)
             if (CustomMask.Value != null)
             {
             {
-                surface.Canvas.DrawSurface(CustomMask.Value, 0, 0, maskPaint);
+                surface.Canvas.DrawSurface(CustomMask.Value.DrawingSurface, 0, 0, maskPaint);
             }
             }
             else if (EmbeddedMask != null)
             else if (EmbeddedMask != null)
             {
             {
-                // TODO: Handle mask
                 /*EmbeddedMask.DrawMostUpToDateChunkOn(
                 /*EmbeddedMask.DrawMostUpToDateChunkOn(
                     context.ChunkToUpdate.Value,
                     context.ChunkToUpdate.Value,
                     context.ChunkResolution,
                     context.ChunkResolution,
                     surface,
                     surface,
                     context.ChunkToUpdate.Value * context.ChunkResolution.PixelSize(),
                     context.ChunkToUpdate.Value * context.ChunkResolution.PixelSize(),
-                    maskPaint);
-            }*/
+                    maskPaint);*/
             }
             }
         }
         }
     }
     }
@@ -184,7 +181,7 @@ public abstract class StructureNode : Node, IReadOnlyStructureNode, IBackgroundI
         y = Math.Clamp(y, 0, Math.Max(sourceSize.Y - height, 0));
         y = Math.Clamp(y, 0, Math.Max(sourceSize.Y - height, 0));
 
 
         return new RectI(x, y, width, height);*/
         return new RectI(x, y, width, height);*/
-        
+
         return new RectI(0, 0, sourceSize.X, sourceSize.Y);
         return new RectI(0, 0, sourceSize.X, sourceSize.Y);
     }
     }
 
 
@@ -199,13 +196,12 @@ public abstract class StructureNode : Node, IReadOnlyStructureNode, IBackgroundI
         int height = chunkSize;
         int height = chunkSize;
 
 
         return new RectI(x, y, width, height);*/
         return new RectI(x, y, width, height);*/
-        
+
         return new RectI(0, 0, context.DocumentSize.X, context.DocumentSize.Y);
         return new RectI(0, 0, context.DocumentSize.X, context.DocumentSize.Y);
     }
     }
 
 
     public abstract RectD? GetTightBounds(KeyFrameTime frameTime);
     public abstract RectD? GetTightBounds(KeyFrameTime frameTime);
 
 
-
     public override void SerializeAdditionalData(Dictionary<string, object> additionalData)
     public override void SerializeAdditionalData(Dictionary<string, object> additionalData)
     {
     {
         base.SerializeAdditionalData(additionalData);
         base.SerializeAdditionalData(additionalData);