1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Added extension to organize node-graphs

This commit is contained in:
Darth Affe 2022-09-13 21:29:02 +02:00
parent 6ed349d4c8
commit 1c6e7bde46
3 changed files with 115 additions and 0 deletions

View File

@ -93,4 +93,5 @@
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=stores_005Cregistrations/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=utilities/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=visualscripting/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=visualscripting_005Cextensions/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=visualscripting_005Cinterfaces/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@ -0,0 +1,26 @@
using System;
using System.Linq;
namespace Artemis.Core;
public static class NodeExtension
{
#region Methods
public static double EstimateHeight(this INode node)
{
const double PIN_HEIGHT = 26;
const double TITLE_HEIGHT = 46;
int inputPinCount = node.Pins.Count(x => x.Direction == PinDirection.Input)
+ node.PinCollections.Where(x => x.Direction == PinDirection.Input).Sum(x => x.Count() + 1);
int outputPinCount = node.Pins.Count(x => x.Direction == PinDirection.Output)
+ node.PinCollections.Where(x => x.Direction == PinDirection.Output).Sum(x => x.Count() + 1);
return TITLE_HEIGHT + (Math.Max(inputPinCount, outputPinCount) * PIN_HEIGHT);
}
public static double EstimateWidth(this INode node) => 120; // DarthAffe 13.09.2022: For now just assume they are all the same size
#endregion
}

View File

@ -0,0 +1,88 @@
using System.Collections.Generic;
using System.Linq;
namespace Artemis.Core;
public static class NodeScriptExtension
{
#region Methods
public static void Organize(this NodeScript nodeScript)
{
const double SPACING_HORIZONTAL = 160;
const double SPACING_VERTICAL = 20;
Dictionary<INode, int> levels = nodeScript.Nodes.ToDictionary(node => node, _ => -1);
List<INode> currentLevelNodes = nodeScript.Nodes.Where(x => x.IsExitNode).ToList();
foreach (INode currentLevelNode in currentLevelNodes)
levels[currentLevelNode] = 0; // DarthAffe 13.09.2022: Init-exit nodes as zero
int currentLevel = 1;
while (currentLevelNodes.Count > 0)
{
List<INode> nextLevelNodes = currentLevelNodes.SelectMany(node => node.Pins
.Where(x => x.Direction == PinDirection.Input)
.SelectMany(x => x.ConnectedTo)
.Select(x => x.Node)
.Concat(node.PinCollections
.Where(x => x.Direction == PinDirection.Input)
.SelectMany(x => x)
.SelectMany(x => x.ConnectedTo)
.Select(x => x.Node)))
.Distinct()
.ToList();
foreach (INode nextLevelNode in nextLevelNodes)
if (currentLevel > levels[nextLevelNode])
levels[nextLevelNode] = currentLevel;
currentLevelNodes = nextLevelNodes;
currentLevel++;
}
void LayoutLevel(IList<INode> nodes, double posX, double posY)
{
foreach (INode node in nodes)
{
node.X = posX;
node.Y = posY;
posY += SPACING_VERTICAL + node.EstimateHeight();
}
}
List<INode>? unusedNodes = null;
double unusedPosY = 0;
double level0Width = 0;
double positionX = 0;
foreach (IGrouping<int, INode> levelGroup in levels.GroupBy(x => x.Value, x => x.Key).OrderBy(x => x.Key))
{
List<INode> nodes = levelGroup.ToList();
double levelHeight = nodes.Sum(x => x.EstimateHeight()) + ((nodes.Count - 1) * SPACING_VERTICAL);
double levelWidth = nodes.Max(x => x.EstimateWidth());
double positionY = -(levelHeight / 2.0);
if (levelGroup.Key == -1)
{
unusedNodes = nodes;
unusedPosY = positionY;
}
else
{
if (levelGroup.Key == 0)
level0Width = levelWidth;
LayoutLevel(nodes, positionX, positionY);
positionX -= SPACING_HORIZONTAL + levelWidth;
}
}
if (unusedNodes != null)
LayoutLevel(unusedNodes, level0Width + (SPACING_HORIZONTAL / 2.0), unusedPosY);
}
#endregion
}