瀏覽代碼

Evaluate Path Node

Krzysztof Krysiński 3 月之前
父節點
當前提交
a29e9c0fb6

+ 1 - 1
src/Drawie

@@ -1 +1 @@
-Subproject commit 34ce7ab4d8e14f5dbad86dea076fe4c7cda15da3
+Subproject commit dd8856e3162b4c6aebf8c27ca2baf86ad85b2824

+ 79 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/EvaluatePathNode.cs

@@ -0,0 +1,79 @@
+using Drawie.Backend.Core.Numerics;
+using Drawie.Backend.Core.Vector;
+using Drawie.Numerics;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes.Data;
+using PixiEditor.ChangeableDocument.Rendering;
+
+namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes;
+
+[NodeInfo("EvaluatePath")]
+public class EvaluatePathNode : Node
+{
+    public InputProperty<ShapeVectorData> Shape { get; }
+    public InputProperty<double> Offset { get; }
+    public InputProperty<bool> NormalizeOffset { get; }
+
+    public OutputProperty<VecD> Position { get; }
+    public OutputProperty<VecD> Tangent { get; }
+    public OutputProperty<Matrix3X3> Matrix { get; }
+
+    protected override bool ExecuteOnlyOnCacheChange => true;
+    protected override CacheTriggerFlags CacheTrigger => CacheTriggerFlags.All;
+
+    public EvaluatePathNode()
+    {
+        Shape = CreateInput<ShapeVectorData>("Shape", "SHAPE", null);
+        Offset = CreateInput<double>("NormalizedOffset", "OFFSET", 0.0);
+        NormalizeOffset = CreateInput<bool>("NormalizeOffset", "NORMALIZE_OFFSET", true);
+
+        Position = CreateOutput<VecD>("Position", "POSITION", VecD.Zero);
+        Tangent = CreateOutput<VecD>("Tangent", "TANGENT", VecD.Zero);
+        Matrix = CreateOutput<Matrix3X3>("Matrix", "MATRIX", Matrix3X3.Identity);
+    }
+
+    protected override void OnExecute(RenderContext context)
+    {
+        if(Shape.Value == null)
+        {
+            Position.Value = VecD.Zero;
+            Tangent.Value = VecD.Zero;
+            Matrix.Value = Matrix3X3.Identity;
+            return;
+        }
+
+        double offset = Offset.Value;
+
+        var path = Shape.Value.ToPath(true);
+
+        if (path == null)
+        {
+            Position.Value = VecD.Zero;
+            Tangent.Value = VecD.Zero;
+            Matrix.Value = Matrix3X3.Identity;
+            return;
+        }
+
+        float absoluteOffset = (float)offset;
+
+        if (NormalizeOffset.Value)
+        {
+            offset = Math.Clamp(offset, 0.0, 1.0);
+            double length = path.Length;
+            absoluteOffset = (float)(length * offset);
+        }
+
+        Vec4D data = path.GetPositionAndTangentAtDistance(absoluteOffset, false);
+        Matrix3X3 matrix = path.GetMatrixAtDistance(absoluteOffset, false, PathMeasureMatrixMode.GetPositionAndTangent);
+
+        Position.Value = new VecD(data.X, data.Y);
+        Tangent.Value = new VecD(data.Z, data.W);
+
+        Matrix.Value = matrix;
+    }
+
+    public override Node CreateCopy()
+    {
+        return new EvaluatePathNode();
+    }
+}

二進制
src/PixiEditor.UI.Common/Fonts/PixiPerfect.ttf


+ 1 - 0
src/PixiEditor.UI.Common/Fonts/PixiPerfectIcons.axaml

@@ -182,6 +182,7 @@
             <system:String x:Key="icon-text-underline">&#xE9B8;</system:String>
             <system:String x:Key="icon-timeline">&#xE9A3;</system:String>
             <system:String x:Key="icon-tool">&#xE977;</system:String>
+            <system:String x:Key="icon-train">&#xE9C3;</system:String>
             <system:String x:Key="icon-trash">&#xE978;</system:String>
             <system:String x:Key="icon-twitter">&#xE904;</system:String>
             <system:String x:Key="icon-undo">&#xE979;</system:String>

+ 1 - 0
src/PixiEditor.UI.Common/Fonts/PixiPerfectIcons.axaml.cs

@@ -178,6 +178,7 @@ public static partial class PixiPerfectIcons
     public const string TextUnderline = "\uE9B8";
     public const string Timeline = "\uE9A3";
     public const string Tool = "\uE977";
+    public const string Train = "\uE9C3";
     public const string Trash = "\uE978";
     public const string Twitter = "\uE904";
     public const string Undo = "\uE979";

+ 1 - 0
src/PixiEditor.UI.Common/Fonts/defs.svg

@@ -218,4 +218,5 @@
 <glyph unicode="&#xe9c0;" glyph-name="step-back" data-tags="step-back" d="M810.667 106.667c0-23.552-19.115-42.667-42.667-42.667s-42.667 19.115-42.667 42.667v682.667c0 23.552 19.115 42.667 42.667 42.667s42.667-19.115 42.667-42.667v-682.667zM570.667 73.344l-426.667 341.333c-10.112 8.107-16 20.352-16 33.323s5.888 25.216 16 33.323l426.667 341.333c12.8 10.24 30.379 12.245 45.141 5.12 14.805-7.083 24.192-22.059 24.192-38.443v-682.667c0-16.384-9.387-31.36-24.192-38.443-14.763-7.125-32.341-5.12-45.141 5.12zM554.667 195.456v505.088l-315.691-252.544 315.691-252.544z" />
 <glyph unicode="&#xe9c1;" glyph-name="step-forward" data-tags="step-forward" d="M213.333 789.333c0 23.552 19.115 42.667 42.667 42.667s42.667-19.115 42.667-42.667v-682.667c0-23.552-19.115-42.667-42.667-42.667s-42.667 19.115-42.667 42.667v682.667zM453.333 822.656l426.667-341.333c10.112-8.107 16-20.352 16-33.323s-5.888-25.216-16-33.323l-426.667-341.333c-12.8-10.24-30.379-12.245-45.141-5.12-14.805 7.083-24.192 22.059-24.192 38.443v682.667c0 16.384 9.387 31.36 24.192 38.443 14.763 7.125 32.341 5.12 45.141-5.12zM469.333 700.544v-505.088l315.691 252.544-315.691 252.544z" />
 <glyph unicode="&#xe9c2;" glyph-name="step-end" data-tags="step-end" d="M261.333 822.656l426.667-341.333c10.112-8.107 16-20.352 16-33.323s-5.888-25.216-16-33.323l-426.667-341.333c-12.8-10.24-30.379-12.245-45.141-5.12-14.805 7.083-24.192 22.059-24.192 38.443v682.667c0 16.384 9.387 31.36 24.192 38.443 14.763 7.125 32.341 5.12 45.141-5.12zM277.333 700.544v-505.088l315.691 252.544-315.691 252.544zM746.667 789.333c0 23.552 19.115 42.667 42.667 42.667s42.667-19.115 42.667-42.667v-682.667c0-23.552-19.115-42.667-42.667-42.667s-42.667 19.115-42.667 42.667v682.667z" />
+<glyph unicode="&#xe9c3;" glyph-name="train" data-tags="train-front" d="M298.667 827.733c0 23.552 19.115 42.667 42.667 42.667s42.667-19.115 42.667-42.667v-166.4c0-70.229 57.771-128 128-128s128 57.771 128 128v166.4c0 23.552 19.115 42.667 42.667 42.667s42.667-19.115 42.667-42.667v-166.4c0-117.035-96.299-213.333-213.333-213.333s-213.333 96.299-213.333 213.333v166.4zM414.165 350.165c16.64-16.64 16.64-43.691 0-60.331s-43.691-16.64-60.331 0l-42.667 42.667c-16.64 16.64-16.64 43.691 0 60.331s43.691 16.64 60.331 0l42.667-42.667zM670.165 289.835c-16.64-16.64-43.691-16.64-60.331 0s-16.64 43.691 0 60.331l42.667 42.667c16.64 16.64 43.691 16.64 60.331 0s16.64-43.691 0-60.331l-42.667-42.667zM384 106.667c-143.36 0-256 112.64-256 256v170.667c0 210.645 173.355 384 384 384s384-173.355 384-384v-170.667c0-143.36-112.64-256-256-256h-256zM384 192h256c95.573 0 170.667 75.093 170.667 170.667v170.667c0 163.84-134.827 298.667-298.667 298.667s-298.667-134.827-298.667-298.667v-170.667c0-95.573 75.093-170.667 170.667-170.667zM305.835 173.013c13.056 19.584 39.552 24.875 59.179 11.819 19.584-13.056 24.875-39.552 11.819-59.179l-85.333-128c-13.056-19.584-39.552-24.875-59.179-11.819-19.584 13.056-24.875 39.552-11.819 59.179l85.333 128zM647.168 125.653c-13.056 19.627-7.765 46.123 11.819 59.179 19.627 13.056 46.123 7.765 59.179-11.819l85.333-128c13.056-19.627 7.765-46.123-11.819-59.179-19.627-13.056-46.123-7.765-59.179 11.819l-85.333 128z" />
 </font></defs></svg>

+ 4 - 1
src/PixiEditor/Data/Localization/Languages/en.json

@@ -1066,5 +1066,8 @@
   "MEDIUM_QUALITY_PRESET": "Medium",
   "HIGH_QUALITY_PRESET": "High",
   "VERY_HIGH_QUALITY_PRESET": "Very High",
-  "EXPORT_FRAMES": "Export Frames"
+  "EXPORT_FRAMES": "Export Frames",
+  "NORMALIZE_OFFSET": "Normalize Offset",
+  "TANGENT": "Tangent",
+  "EVALUATE_PATH_NODE": "Evaluate Path"
 }

+ 10 - 0
src/PixiEditor/ViewModels/Document/Nodes/Shapes/EvaluatePathNodeViewModel.cs

@@ -0,0 +1,10 @@
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes;
+using PixiEditor.ViewModels.Nodes;
+
+namespace PixiEditor.ViewModels.Document.Nodes.Shapes;
+
+[NodeViewModel("EVALUATE_PATH_NODE", "SHAPE", PixiPerfectIcons.Train)]
+internal class EvaluatePathNodeViewModel : NodeViewModel<EvaluatePathNode>
+{
+
+}