Selaa lähdekoodia

Fixed brush live shape update

Krzysztof Krysiński 1 päivä sitten
vanhempi
commit
b4da8b71e3

+ 2 - 1
src/PixiEditor.ChangeableDocument/Changes/Drawing/LineBasedPen_UpdateableChange.cs

@@ -77,7 +77,7 @@ internal class LineBasedPen_UpdateableChange : UpdateableChange
     }
 
     [UpdateChangeMethod]
-    public void Update(VecI pos, float strokeWidth, float spacing, PointerInfo pointerInfo)
+    public void Update(VecI pos, float strokeWidth, float spacing, PointerInfo pointerInfo, BrushData brushData)
     {
         if (points.Count > 0)
         {
@@ -88,6 +88,7 @@ internal class LineBasedPen_UpdateableChange : UpdateableChange
         this.strokeWidth = strokeWidth;
         this.pointerInfo = pointerInfo;
         this.spacing = spacing;
+        this.brushData = brushData;
         UpdateBrushData();
     }
 

+ 57 - 20
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/PenToolExecutor.cs

@@ -1,7 +1,10 @@
 using Avalonia.Input;
+using ChunkyImageLib.DataHolders;
+using Drawie.Backend.Core;
 using PixiEditor.ChangeableDocument.Actions;
 using PixiEditor.ChangeableDocument.Actions.Generated;
 using Drawie.Backend.Core.ColorsImpl;
+using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Vector;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Models.Handlers;
@@ -14,6 +17,9 @@ using PixiEditor.ChangeableDocument.Changeables.Graph;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces.Shapes;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Brushes;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes.Data;
+using PixiEditor.ChangeableDocument.Rendering;
+using PixiEditor.Models.BrushEngine;
 using PixiEditor.Models.Controllers.InputDevice;
 using PixiEditor.ViewModels.Document.Nodes.Brushes;
 using PixiEditor.ViewModels.Nodes;
@@ -27,19 +33,22 @@ internal class PenToolExecutor : UpdateableChangeExecutor
     public double ToolSize => penToolbar.ToolSize;
     public bool SquareBrush => penToolbar.PaintShape == PaintBrushShape.Square;
     public float Spacing => penToolbar.Spacing;
+    public BrushData BrushData => brushData ??= GetBrushFromToolbar(penToolbar);
     public override bool BlocksOtherActions => controller.LeftMousePressed;
 
     private bool drawOnMask;
     private bool pixelPerfect;
     private bool antiAliasing;
     private bool transparentErase;
-    private BrushData brushData;
 
-    private INodePropertyHandler vectorShapeInput;
+    private InputProperty<ShapeVectorData> vectorShapeInput;
 
     private IPenToolbar penToolbar;
     private IPenToolHandler handler;
 
+    private BrushData? brushData;
+    private Guid brushOutputGuid = Guid.Empty;
+
     public override ExecutionState Start()
     {
         IStructureMemberHandler? member = document!.SelectedStructureMember;
@@ -66,27 +75,18 @@ internal class PenToolExecutor : UpdateableChangeExecutor
             colorsHandler.AddSwatch(new PaletteColor(color.R, color.G, color.B));
         }
 
-        if(toolbar.Brush == null)
+        if (toolbar.Brush == null)
             return ExecutionState.Error;
 
-        var pipe = toolbar.Brush.Document.ShareGraph();
-        brushData = new BrushData(pipe.TryAccessData());
-        pipe.Dispose();
-
-        /*
-        vectorShapeInput =
-            (document.NodeGraphHandler.NodeLookup[brushOutputGuid] as BrushOutputNodeViewModel).Inputs
-            .FirstOrDefault(x => x.PropertyName == "VectorShape");
-            */
+        UpdateBrushNodes();
 
         transparentErase = color.A == 0;
-        //vectorShapeInput.UpdateComputedValue();
         if (controller.LeftMousePressed)
         {
             IAction? action = pixelPerfect switch
             {
                 false => new LineBasedPen_Action(guidValue, color, controller!.LastPixelPosition, (float)ToolSize,
-                    transparentErase, antiAliasing, Spacing, brushData, drawOnMask,
+                    transparentErase, antiAliasing, Spacing, BrushData, drawOnMask,
                     document!.AnimationHandler.ActiveFrameBindable, controller.LastPointerInfo, controller.EditorData),
                 true => new PixelPerfectPen_Action(guidValue, controller!.LastPixelPosition, color, drawOnMask,
                     document!.AnimationHandler.ActiveFrameBindable)
@@ -94,18 +94,46 @@ internal class PenToolExecutor : UpdateableChangeExecutor
             internals!.ActionAccumulator.AddActions(action);
         }
 
-        //handler.FinalBrushShape = (vectorShapeInput.ComputedValue as IReadOnlyShapeVectorData)?.ToPath(true);
+        handler.FinalBrushShape = vectorShapeInput.Value?.ToPath(true);
 
         return ExecutionState.Success;
     }
 
+    private void UpdateBrushNodes()
+    {
+        BrushOutputNode brushOutputNode = BrushData.BrushGraph.AllNodes
+            .FirstOrDefault(x => x is BrushOutputNode) as BrushOutputNode;
+        brushOutputGuid = brushOutputNode.Id;
+
+        vectorShapeInput =
+            brushOutputNode.InputProperties
+                .FirstOrDefault(x => x.InternalPropertyName == "VectorShape") as InputProperty<ShapeVectorData>;
+    }
+
+    private BrushData GetBrushFromToolbar(IPenToolbar toolbar)
+    {
+        var pipe = toolbar.Brush.Document.ShareGraph();
+        var data = new BrushData(pipe.TryAccessData());
+        pipe.Dispose();
+        return data;
+    }
+
+    public override void OnSettingsChanged(string name, object value)
+    {
+        if (name == nameof(penToolbar.Brush))
+        {
+            brushData = GetBrushFromToolbar(penToolbar);
+            UpdateBrushNodes();
+        }
+    }
+
     public override void OnLeftMouseButtonDown(MouseOnCanvasEventArgs args)
     {
         base.OnLeftMouseButtonDown(args);
         IAction? action = pixelPerfect switch
         {
             false => new LineBasedPen_Action(guidValue, color, controller!.LastPixelPosition, (float)ToolSize,
-                transparentErase, antiAliasing, Spacing, brushData, drawOnMask,
+                transparentErase, antiAliasing, Spacing, BrushData, drawOnMask,
                 document!.AnimationHandler.ActiveFrameBindable, controller.LastPointerInfo, controller.EditorData),
             true => new PixelPerfectPen_Action(guidValue, controller!.LastPixelPosition, color, drawOnMask,
                 document!.AnimationHandler.ActiveFrameBindable)
@@ -118,10 +146,19 @@ internal class PenToolExecutor : UpdateableChangeExecutor
         base.OnPrecisePositionChange(args);
         if (!controller.LeftMousePressed)
         {
-            //vectorShapeInput.UpdateComputedValue();
+            var outputNode = BrushData.BrushGraph.AllNodes.FirstOrDefault(x => x.Id == brushOutputGuid) as BrushOutputNode;
+            using Texture surf = new(VecI.One);
+            brushData.Value.BrushGraph.Execute(
+                outputNode,
+                new RenderContext(surf.DrawingSurface, document.AnimationHandler.ActiveFrameTime, ChunkResolution.Full,
+                    surf.Size, document.SizeBindable, document.ProcessingColorSpace, SamplingOptions.Default)
+                {
+                    PointerInfo = controller.LastPointerInfo,
+                    EditorData = controller.EditorData,
+                });
         }
 
-        //handler.FinalBrushShape = (vectorShapeInput.ComputedValue as IReadOnlyShapeVectorData)?.ToPath(true);
+        handler.FinalBrushShape = vectorShapeInput?.Value.ToPath(true);
     }
 
     public override void OnPixelPositionChange(VecI pos, MouseOnCanvasEventArgs args)
@@ -131,7 +168,7 @@ internal class PenToolExecutor : UpdateableChangeExecutor
             IAction? action = pixelPerfect switch
             {
                 false => new LineBasedPen_Action(guidValue, color, pos, (float)ToolSize, transparentErase, antiAliasing,
-                    Spacing, brushData, drawOnMask, document!.AnimationHandler.ActiveFrameBindable,
+                    Spacing, BrushData, drawOnMask, document!.AnimationHandler.ActiveFrameBindable,
                     controller.LastPointerInfo, controller.EditorData),
                 true => new PixelPerfectPen_Action(guidValue, pos, color, drawOnMask,
                     document!.AnimationHandler.ActiveFrameBindable)
@@ -143,7 +180,7 @@ internal class PenToolExecutor : UpdateableChangeExecutor
     public override void OnConvertedKeyDown(Key key)
     {
         base.OnConvertedKeyDown(key);
-        //handler.FinalBrushShape = (vectorShapeInput.ComputedValue as IReadOnlyShapeVectorData)?.ToPath(true);
+        handler.FinalBrushShape = vectorShapeInput.Value?.ToPath(true);
     }
 
     public override void OnLeftMouseButtonUp(VecD argsPositionOnCanvas)

+ 1 - 0
src/PixiEditor/Models/Handlers/IDocument.cs

@@ -51,6 +51,7 @@ internal interface IDocument : IHandler, Extensions.CommonApi.Documents.IDocumen
     public ISnappingHandler SnappingHandler { get; }
     public IReadOnlyCollection<Guid> SelectedMembers { get; }
     public PreviewPainter? MiniPreviewPainter { get; set; }
+    public ColorSpace ProcessingColorSpace { get; }
     public void RemoveSoftSelectedMember(IStructureMemberHandler member);
     public void ClearSoftSelectedMembers();
     public void AddSoftSelectedMember(IStructureMemberHandler member);

+ 2 - 0
src/PixiEditor/ViewModels/Document/DocumentViewModel.cs

@@ -1091,6 +1091,8 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
         OnPropertyChanged(nameof(SoftSelectedStructureMembers));
     }
 
+    public ColorSpace ProcessingColorSpace => UsesSrgbBlending ? ColorSpace.CreateSrgb() : ColorSpace.CreateSrgbLinear();
+
     public void RemoveSoftSelectedMember(IStructureMemberHandler member)
     {
         softSelectedStructureMembers.Remove(member);