Loading Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFEdgeLink.cs 0 → 100644 +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 Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFEdgeLink.cs.meta 0 → 100644 +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: Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFGraphView.cs +466 −108 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -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 Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNode.cs +102 −40 Original line number Diff line number Diff line Loading @@ -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 Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeTrackable.cs 0 → 100644 +88 −0 File added.Preview size limit exceeded, changes collapsed. Show changes Loading
Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFEdgeLink.cs 0 → 100644 +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
Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFEdgeLink.cs.meta 0 → 100644 +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:
Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFGraphView.cs +466 −108 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -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
Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNode.cs +102 −40 Original line number Diff line number Diff line Loading @@ -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
Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeTrackable.cs 0 → 100644 +88 −0 File added.Preview size limit exceeded, changes collapsed. Show changes