Commit 15284940 authored by Nathan Chambron's avatar Nathan Chambron
Browse files

first commit

parent 8ccb356a
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
using Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows;
using Org.OpenAPITools.Model;
using UnityEditor;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
using UnityEngine.UIElements;

namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Graph
{
    public class ARFEdgeLink : Edge
    {
        public WorldLink worldLink;
        public string GUID;
        public ARFEdgeLink()
        {
            var doubleClickManipulator = new Clickable(clicked);
            doubleClickManipulator.activators.Clear();
            doubleClickManipulator.activators.Add(new ManipulatorActivationFilter { button = MouseButton.LeftMouse, clickCount = 2 });
            this.AddManipulator(doubleClickManipulator);
            this.style.color = new Color(239, 239, 239);
        }

        public void clicked()
        {
            NodeEditorWindow.ShowWindow(this);
        }
    }
}
 No newline at end of file
+11 −0
Original line number Diff line number Diff line
fileFormatVersion: 2
guid: 81a94cf483be20040aa4fe8d9f93d5c5
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData: 
  assetBundleName: 
  assetBundleVariant: 
+466 −108
Original line number Diff line number Diff line
@@ -17,29 +17,192 @@
//
// Last change: June 2022
//
#define USING_OPENAPI_GENERATOR

using System.Collections;
using System.Collections.Generic;
#if USING_OPENAPI_GENERATOR
using Org.OpenAPITools.Api;
using Org.OpenAPITools.Model;
#else
using IO.Swagger.Api;
using IO.Swagger.Model;
#endif
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.Experimental.GraphView;
using System;
using Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Graph;
using ETSI.ARF.WorldStorage.REST;
using UnityEditor;
using Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows;

namespace ETSI.ARF.WorldStorage.UI
{
    public class ARFGraphView : GraphView
    {
        public WorldStorageServer worldStorageServer;
        public WorldStorageUser worldStorageUser;

        public ARFGraphView()
        {
            //GridBackground back = new GridBackground();
            //back.StretchToParentSize();
            //Insert(0, back);
            SetupZoom(ContentZoomer.DefaultMinScale, ContentZoomer.DefaultMaxScale);

            //deleSection
            deleteSelection += DeleteFunc;

            this.AddManipulator(new ContentDragger());
            this.AddManipulator(new SelectionDragger());
            this.AddManipulator(new RectangleSelector());

            AddElement(GenerateEntryPointNode());
        }

        //method called when an element is deleted from the graphview
        public void DeleteFunc(string operationName, AskUser askUser)
        {
            //build the message to list all the deleted elements
            String message = "Are you sure you want to delete ";
            if (selection.Count > 1)
            {
                message += selection.Count + " elements ?";
            }
            else
            {
                message += "this element ?";
            }

            //remove from the graph all the deleted elements
            if (EditorUtility.DisplayDialog("Deleting elements", message, "Yes", "No"))
            {
                if (SaveInfo.instance.elemsToRemove == null)
                {
                    SaveInfo.instance.elemsToRemove = new List<string>();
                }
                foreach (GraphElement elt in selection.ToArray())
                {
                    ARFNodeWorldAnchor nodeAnchor = elt as ARFNodeWorldAnchor;
                    if (nodeAnchor != null)
                    {
                        nodeAnchor.DisconnectAllPorts(this);
                        if (SaveInfo.instance.nodePositions.ContainsKey(nodeAnchor.GUID))
                        {
                            SaveInfo.instance.elemsToRemove.Add(nodeAnchor.GUID);
                        }
                        RemoveElement(elt);
                        continue;
                    }
                    ARFNodeTrackable nodeTrackable = elt as ARFNodeTrackable;
                    if (nodeTrackable != null)
                    {
                        nodeTrackable.DisconnectAllPorts(this);
                        if (SaveInfo.instance.nodePositions.ContainsKey(nodeTrackable.GUID))
                        {
                            SaveInfo.instance.elemsToRemove.Add(nodeTrackable.GUID);
                        }
                        RemoveElement(elt);
                        continue;
                    }
                    ARFEdgeLink edgeLink = elt as ARFEdgeLink;
                    if (edgeLink != null)
                    {
                        edgeLink.input.Disconnect(edgeLink);
                        edgeLink.output.Disconnect(edgeLink);
                        SaveInfo.instance.elemsToRemove.Add(edgeLink.GUID);
                        RemoveElement(elt);
                        continue;
                    }
                }
            }
        }

        public override void BuildContextualMenu(UnityEngine.UIElements.ContextualMenuPopulateEvent evt)
        {
            Vector2 localMousePos = evt.localMousePosition;
            Vector2 actualGraphPosition = viewTransform.matrix.inverse.MultiplyPoint(localMousePos);

            evt.menu.AppendSeparator();
            evt.menu.AppendAction("Reload graph", delegate
            {
                if (positionshaveBeenChanged() && EditorUtility.DisplayDialog("Saving node positions", "The nodes positions have been changed, would you like to save them ?", "Yes", "No"))
                {
                    saveElemPositionsInServer();
                }
                reload();
                SaveInfo.instance.toReFrame = true;
            }, (DropdownMenuAction a) => DropdownMenuAction.Status.Normal);
            evt.menu.AppendAction("Create Trackable", delegate
            {
                //generate the Trackables's attributes
                EncodingInformationStructure trackableEncodingInformation = new EncodingInformationStructure(EncodingInformationStructure.DataFormatEnum.OTHER, "0");

                List<float> localCRS = new List<float>();
                for (int i = 0; i < 16; i++)
                {
                    localCRS.Add(0);
                }

                List<double> trackableSize = new List<double>();
                for (int i = 0; i < 3; i++)
                {
                    trackableSize.Add(0);
                }

                Trackable trackable = new Trackable(Guid.NewGuid(), "Defaulttrackable", Guid.Parse(worldStorageUser.UUID), Trackable.TrackableTypeEnum.OTHER, trackableEncodingInformation, new byte[64], localCRS, UnitSystem.CM, trackableSize, new Dictionary<string, List<string>>());
                createTrackableNode(trackable, actualGraphPosition.x, actualGraphPosition.y);

            }, (DropdownMenuAction a) => DropdownMenuAction.Status.Normal);
            evt.menu.AppendAction("Create World Anchor", delegate
            {
                //generate the worldAnchor attributes

                List<float> localCRS = new List<float>();
                for (int i = 0; i < 16; i++)
                {
                    localCRS.Add(0);
                }

                List<double> worldAnchorSize = new List<double>();
                for (int i = 0; i < 3; i++)
                {
                    worldAnchorSize.Add(0);
                }

                WorldAnchor anchor = new WorldAnchor(Guid.NewGuid(), "DefaultWorldAnchor", Guid.Parse(worldStorageUser.UUID), localCRS, UnitSystem.CM, worldAnchorSize, new Dictionary<string, List<string>>());
                createAnchorNode(anchor, actualGraphPosition.x, actualGraphPosition.y);

            }, (DropdownMenuAction a) => DropdownMenuAction.Status.Normal);
            evt.menu.AppendSeparator();
            if (evt.target is ARFNode || evt.target is Group || evt.target is ARFEdgeLink)
            {
                evt.menu.AppendSeparator();
                evt.menu.AppendAction("Delete", delegate
                {
                    DeleteSelectionCallback(AskUser.AskUser);
                }, (DropdownMenuAction a) => canDeleteSelection ? DropdownMenuAction.Status.Normal : DropdownMenuAction.Status.Disabled);
                evt.menu.AppendSeparator();
            }
            if (evt.target is GraphView)
            {
            }
        }
        private bool positionshaveBeenChanged()
        {
            if (SaveInfo.instance.elemsToRemove.Count != 0)
            {
                return true;
            }
            foreach (ARFNode node in nodes)
            {
                float nodeX = node.GetPosition().x;
                float nodeY = node.GetPosition().y;
                float dataX = SaveInfo.instance.nodePositions[node.GUID].x;
                float dataY = SaveInfo.instance.nodePositions[node.GUID].y;
                if ((nodeX != dataX) || (nodeY != dataY))
                {
                    return true;
                }
            }
            return false;
        }

        public override List<Port> GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter)
@@ -52,58 +215,253 @@ namespace ETSI.ARF.WorldStorage.UI
            return cPorts;
        }

        private Port GeneratePort (ARFNode node, Direction portDirection, Port.Capacity capacity = Port.Capacity.Multi)
        public void paintWorldStorage()
        {
            List<Trackable> trackables = TrackableRequest.GetAllTrackables(worldStorageServer);
            List<WorldAnchor> worldAnchors = WorldAnchorRequest.GetAllWorldAnchors(worldStorageServer);
            List<WorldLink> worldLinks = WorldLinkRequest.GetAllWorldLinks(worldStorageServer);

            foreach (WorldAnchor worldAnchor in worldAnchors)
            {
                var waNode = new ARFNodeWorldAnchor(worldAnchor);

                Rect posTemp = new Rect(26, 93, 160, 77);
                SaveInfo.instance.nodePositions.TryGetValue(worldAnchor.UUID.ToString(), out posTemp);
                waNode.SetPosition(posTemp);

                AddElement(waNode);
            }

            foreach (Trackable trackable in trackables)
            {
                var tracknode = new ARFNodeTrackable(trackable);

                Rect posTemp = new Rect(26, 93, 160, 77);
                SaveInfo.instance.nodePositions.TryGetValue(trackable.UUID.ToString(), out posTemp);
                tracknode.SetPosition(posTemp);

                AddElement(tracknode);
            }
            foreach (WorldLink worldLink in worldLinks)
            {
                var portPair = getPortsFromWorldLink(worldLink);
                ARFEdgeLink edge = portPair.Key.ConnectTo<ARFEdgeLink>(portPair.Value);
                edge.worldLink = worldLink;
                edge.GUID = worldLink.UUID.ToString();

                AddElement(edge);
            }

        }

        internal void createTrackableNode(Trackable track, float posX, float posY)
        {
            return node.InstantiatePort(Orientation.Horizontal, portDirection, capacity, typeof(int)); // dummy
            var tracknode = new ARFNodeTrackable(track);
            Rect pos = new Rect(RoundToNearestHalf(posX), RoundToNearestHalf(posY), 160, 77);
            tracknode.SetPosition(pos);

            AddElement(tracknode);
        }

        private ARFNode GenerateEntryPointNode()
        internal void createAnchorNode(WorldAnchor wa, float posX, float posY)
        {
            var node = new ARFNode
            var waNode = new ARFNodeWorldAnchor(wa);

            Rect pos = new Rect(RoundToNearestHalf(posX), RoundToNearestHalf(posY), 160, 77);
            waNode.SetPosition(pos);

            AddElement(waNode);
        }

        internal void createLink(WorldLink worldLink)
        {
                title = "World Storage",
                text = "EntryPoint",
                GUID = Guid.NewGuid().ToString(),
                entryPoint = true
            };
            var portPair = getPortsFromWorldLink(worldLink);
            ARFEdgeLink edge = portPair.Key.ConnectTo<ARFEdgeLink>(portPair.Value);
            edge.worldLink = worldLink;
            Debug.Log(worldLink.UUID.ToString());
            edge.GUID = worldLink.UUID.ToString();

            var portOut = GeneratePort(node, Direction.Output);
            portOut.portName = "Link";
            node.outputContainer.Add(portOut);
            AddElement(edge);
        }

            node.RefreshExpandedState();
            node.RefreshPorts();
            node.SetPosition(new Rect(50, 100, 200, 150));
            return node;
        public void reload()
        {
            DeleteElements(graphElements);
            paintWorldStorage();
            FrameAllElements();
        }

        public void CreateNode(string name)
        public Dictionary<string, Rect> SavePositions()
        {
            Dictionary<string, Rect> ret = new Dictionary<string, Rect>();
            foreach (ARFNode elem in nodes)
            {
            AddElement(CreateARFNode(name));
                ret.Add(elem.GUID, elem.GetPosition());
            }
            return ret;
        }

        private KeyValuePair<Port, Port> getPortsFromWorldLink(WorldLink worldLink)
        {
            var ret = new KeyValuePair<Port, Port>();

        public ARFNode CreateARFNode(string name)
            //To
            Guid idTo = worldLink.UUIDTo;
            Port portIn = null;
            switch (worldLink.TypeTo)
            {
                case ObjectType.Trackable:
                    foreach (GraphElement node in this.graphElements)
                    {
            var node = new ARFNode
                        ARFNodeTrackable nodeTrackable = node as ARFNodeTrackable;
                        if ((nodeTrackable != null) && (nodeTrackable.trackable.UUID == idTo))
                        {
                            portIn = nodeTrackable.portIn;
                            break;
                        }
                    }
                    break;
                case ObjectType.WorldAnchor:
                    foreach (GraphElement node in this.graphElements)
                    {
                        ARFNodeWorldAnchor nodeAnchor = node as ARFNodeWorldAnchor;
                        if ((nodeAnchor != null) && nodeAnchor.worldAnchor.UUID == idTo)
                        {
                            portIn = nodeAnchor.portIn;
                            break;
                        }
                    }
                    break;
                default:
                    Debug.Log("what are you doing here...");
                    break;
            }

            //From
            Guid idFrom = worldLink.UUIDFrom;
            Port portOut = null;
            switch (worldLink.TypeFrom)
            {
                case ObjectType.Trackable:
                    foreach (GraphElement node in this.graphElements)
                    {
                        ARFNodeTrackable nodeTrackable = node as ARFNodeTrackable;
                        if ((nodeTrackable != null) && (nodeTrackable.trackable.UUID == idFrom))
                        {
                            portOut = nodeTrackable.portOut;
                            break;
                        }
                    }
                    break;
                case ObjectType.WorldAnchor:
                    foreach (GraphElement node in this.graphElements)
                    {
                        ARFNodeWorldAnchor nodeAnchor = node as ARFNodeWorldAnchor;
                        if ((nodeAnchor != null) && nodeAnchor.worldAnchor.UUID == idFrom)
                        {
                            portOut = nodeAnchor.portOut;
                            break;
                        }
                    }
                    break;
                default:
                    Debug.Log("what are you doing here...");
                    break;
            }

            if ((portOut != null) && (portIn != null))
            {
                title = name,
                text = name,
                GUID = Guid.NewGuid().ToString()
            };
                ret = new KeyValuePair<Port, Port>(portOut, portIn);
            }

            var portIn = GeneratePort(node, Direction.Input, Port.Capacity.Multi);
            portIn.portName = "Link"; // "Input";
            node.inputContainer.Add(portIn);
            return ret;
        }

            var portOut = GeneratePort(node, Direction.Output, Port.Capacity.Multi);
            portOut.portName = "Link"; // "Output";
            node.outputContainer.Add(portOut);
        //
        // Rsum:
        //     Calculate the rectangle size and position to fit all elements in graph.
        //
        // Paramtres:
        //   container:
        //     This should be the view container.
        //
        // Retourne:
        //     The calculated rectangle.
        public override Rect CalculateRectToFitAll(VisualElement container)
        {
            Rect rectToFit = container.layout;
            bool reachedFirstChild = false;
            graphElements.ForEach(delegate (GraphElement ge)
            {
                if (!(ge is ARFEdgeLink) && !(ge is Port))
                {
                    if (!reachedFirstChild)
                    {
                        rectToFit = ge.ChangeCoordinatesTo(contentViewContainer, ge.contentRect);
                        reachedFirstChild = true;
                    }
                    else
                    {
                        rectToFit = RectUtils.Encompass(rectToFit, ge.ChangeCoordinatesTo(contentViewContainer, ge.contentRect));
                    }
                }
            });
            return rectToFit;
        }

            node.RefreshExpandedState();
            node.RefreshPorts();
            node.SetPosition(new Rect(200, 100, 200, 150));
        //k_FrameBorder is private readOnly graphView attribute, had to redeclare it to access it
        private readonly int k_FrameBorder = 30;
        public void FrameAllElements()
        {
            Vector3 frameTranslation = Vector3.zero;
            Vector3 frameScaling = Vector3.one;
            var rectToFit = CalculateRectToFitAll(contentViewContainer);
            CalculateFrameTransform(rectToFit, layout, k_FrameBorder, out frameTranslation, out frameScaling);
            Matrix4x4.TRS(frameTranslation, Quaternion.identity, frameScaling);
            UpdateViewTransform(frameTranslation, frameScaling);
        }

            return node;
        //method to predict the position of a node (the float that will be saved in the PositionInfo singleton)
        public static float RoundToNearestHalf(float a)
        {
            return a = Mathf.Round(a * 2f) * 0.5f;
        }

        public void saveElemPositionsInServer()
        {
            foreach (ARFNode node in nodes)
            {
                if (!SaveInfo.instance.nodePositions.ContainsKey(node.GUID))
                {
                    //TODO
                    Debug.Log("need to post " + node.GUID);
                }
                else
                {
                    float xLocal = node.GetPosition().x;
                    float yLocal = node.GetPosition().y;
                    float xServer = SaveInfo.instance.nodePositions[node.GUID].x; ;
                    float yServer = SaveInfo.instance.nodePositions[node.GUID].y;
                    if ((xLocal != xServer) && (yLocal != yServer))
                    {
                        //TODO
                        Debug.Log("need to update " + node.GUID);
                    }
                }
            }
            foreach (ARFEdgeLink edge in edges)
            {
                if (!SaveInfo.instance.linkIds.Contains(edge.GUID))
                {
                    //TODO
                    Debug.Log("need to post link between " + edge.input);
                }
            }
            foreach (String elemId in SaveInfo.instance.elemsToRemove)
            {
                //TODO
                Debug.Log("need to remove " + elemId);
            }
        }
    }
}
 No newline at end of file
+102 −40
Original line number Diff line number Diff line
@@ -17,25 +17,87 @@
//
// Last change: June 2022
//
#define USING_OPENAPI_GENERATOR // alt. is Swagger

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using ETSI.ARF.WorldStorage.REST;

#if USING_OPENAPI_GENERATOR
using Org.OpenAPITools.Api;
using Org.OpenAPITools.Model;
#else
using IO.Swagger.Api;
using IO.Swagger.Model;
#endif
using UnityEngine.UIElements;
using UnityEditor.Experimental.GraphView;
using Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Graph;
using System;

namespace ETSI.ARF.WorldStorage.UI
{
    public class ARFNode : Node
    {
        public string GUID;
        public string text;
        public bool entryPoint = false;

        public Port portOut;
        public Port portIn;
        public GUID id;
        public ARFNode()
        {
            
        }

        public override Port InstantiatePort(Orientation orientation, Direction direction, Port.Capacity capacity, Type type)
        {
            switch (direction)
            {
                case Direction.Input:
                    portIn = Port.Create<ARFEdgeLink>(orientation, direction, capacity, type);
                    return portIn;
                case Direction.Output:
                    portOut = Port.Create<ARFEdgeLink>(orientation, direction, capacity, type);
                    return portOut;
                default:
                    return null;
            }
        }

        public void DisconnectAllPorts(ARFGraphView graphView)
        {
            DisconnectInputPorts(graphView);
            DisconnectOutputPorts(graphView);
        }

        private void DisconnectInputPorts(ARFGraphView graphView)
        {
            DisconnectPorts(inputContainer, graphView);
        }

        private void DisconnectOutputPorts(ARFGraphView graphView)
        {
            DisconnectPorts(outputContainer, graphView);
        }

        private void DisconnectPorts(VisualElement container, ARFGraphView graphView)
        {
            foreach (Port port in container.Children())
            {
                if (!port.connected)
                {
                    continue;
                }

                graphView.DeleteElements(port.connections);
            }
        }

        public Port GeneratePort(ARFNode node, Direction portDirection, Port.Capacity capacity = Port.Capacity.Multi)
        {
            return node.InstantiatePort(Orientation.Horizontal, portDirection, capacity, typeof(int)); // dummy
        }
    }
}
 No newline at end of file
+88 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading