public static void MakeBezierCurve(this IBiaNodeLink self, Span <ImmutableVec2_float> result) { var item1 = self.ItemSlot1.Item ?? throw new NullReferenceException(); var item2 = self.ItemSlot2.Item ?? throw new NullReferenceException(); var pos1 = item1.MakeSlotPosDefault(self.InternalData().Slot1 !); var pos2 = item2.MakeSlotPosDefault(self.InternalData().Slot2 !); var pos1C = BiaNodeEditorHelper.MakeBezierControlPoint(pos1, self.InternalData().Slot1 !.Dir); var pos2C = BiaNodeEditorHelper.MakeBezierControlPoint(pos2, self.InternalData().Slot2 !.Dir); result[0] = new ImmutableVec2_float((float)pos1.X, (float)pos1.Y); result[1] = new ImmutableVec2_float((float)pos1C.X, (float)pos1C.Y); result[2] = new ImmutableVec2_float((float)pos2C.X, (float)pos2C.Y); result[3] = new ImmutableVec2_float((float)pos2.X, (float)pos2.Y); }
private void DrawCurves(DeviceContext target, bool isDrawArrow, float lineWidth) { if (_parent.LinksSource is null) { return; } var arrowSize = BaseArrowSize / (float)_parent.ScaleTransform.ScaleX; var inflate = arrowSize; var viewport = _parent.TransformRect(ActualWidth, ActualHeight); var lineCullingRect = new ImmutableRect_float( (float)viewport.X - inflate, (float)viewport.Y - inflate, (float)viewport.Width + inflate * 2f, (float)viewport.Height + inflate * 2f ); var hasHighlightCurves = false; var borderKey = HashCodeMaker.To32(ByteColor.Black.HashCode); if (ResourceCache.TryGetValue(borderKey, out var borderBrushObj) == false) { borderBrushObj = ResourceCache.Add(borderKey, t => ColorToBrushConv(t, ByteColor.Black)); } var borderBrush = borderBrushObj as Brush; Span <ImmutableVec2_float> bezier = stackalloc ImmutableVec2_float[4]; using var curves = new TempBuffer <(PathGeometry Geom, GeometrySink Sink, IBiaNodeLink Link)>(256); foreach (IBiaNodeLink?link in _parent.LinksSource) { if (link is null) { continue; } if (link.IsVisible == false) { continue; } if (link.IsLinked() == false) { continue; } var isHighlight = link.IsHighlight(); if (isHighlight) { hasHighlightCurves = true; } // ハイライトがあれば、非ハイライトを表示しない if (hasHighlightCurves && isHighlight == false) { continue; } link.MakeBezierCurve(bezier); var keyBezier = MakeHashCode(bezier); if (_boundingBoxCache.TryGetValue(keyBezier, out var bb) == false) { bb = BiaNodeEditorHelper.MakeBoundingBox(bezier); _boundingBoxCache.Add(keyBezier, bb); } if (bb.IntersectsWith(lineCullingRect) == false) { continue; } var curveGeom = new PathGeometry(target.Factory); var curveSink = curveGeom.Open(); curveSink.SetFillMode(FillMode.Winding); curveSink.BeginFigure(Unsafe.As <ImmutableVec2_float, RawVector2>(ref bezier[0]), FigureBegin.Hollow); curveSink.AddBezier(Unsafe.As <ImmutableVec2_float, BezierSegment>(ref bezier[1])); curveSink.EndFigure(FigureEnd.Open); if (isDrawArrow) { DrawArrow(curveSink, bezier, arrowSize); } curveSink.Close(); // ReSharper disable once PossiblyImpureMethodCallOnReadonlyVariable curves.Add((curveGeom, curveSink, link)); } foreach (var(geom, sink, link) in curves.Buffer) { var isHighlight = link.IsHighlight(); if (hasHighlightCurves == false || isHighlight) { var key = HashCodeMaker.Make(link.Color, isHighlight); var resKey = HashCodeMaker.To32(key); if (ResourceCache.TryGetValue(resKey, out var brush) == false) { brush = ResourceCache.Add(resKey, t => ColorToBrushConv(t, link.Color)); } target.DrawGeometry(geom, borderBrush, lineWidth * 2f); target.DrawGeometry(geom, brush as Brush, lineWidth); target.FillGeometry(geom, brush as Brush); } sink.Dispose(); geom.Dispose(); } }