From 3878ba5fff88dfa20bb88109c15fe0df6196c834 Mon Sep 17 00:00:00 2001 From: Dmytro Muravskyi Date: Tue, 28 Nov 2023 17:01:16 +0200 Subject: [PATCH] Add AdaptiveGrid.Clone --- CHANGELOG.md | 1 + .../src/Spatial/AdaptiveGrid/AdaptiveGrid.cs | 38 ++++++++++++++++++- Elements/src/Spatial/AdaptiveGrid/Edge.cs | 2 +- Elements/test/AdaptiveGridTests.cs | 31 +++++++++++++++ 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c4dded2e..c1a31c9a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ - `Elements.Door` - `ComponentBase.UseRepresentationInstances` - an option flag to make generating fitting models faster/smaller. - `ContentConfiguration.AllowRotatation` +- `AdaptiveGrid.Clone` ### Fixed diff --git a/Elements/src/Spatial/AdaptiveGrid/AdaptiveGrid.cs b/Elements/src/Spatial/AdaptiveGrid/AdaptiveGrid.cs index b9dfb7f86..356714b1a 100644 --- a/Elements/src/Spatial/AdaptiveGrid/AdaptiveGrid.cs +++ b/Elements/src/Spatial/AdaptiveGrid/AdaptiveGrid.cs @@ -765,6 +765,42 @@ public void InsertSnapshot( } } + /// + /// Perform deep cloning of the AdaptiveGrid. + /// New grid will have the same ids but can be edited independently. + /// + /// Cloned AdaptiveGrid + public AdaptiveGrid Clone() + { + AdaptiveGrid clone = new AdaptiveGrid(new Transform(Transform)); + clone._edgeId = _edgeId; + clone._vertexId = _vertexId; + + clone._edges = _edges.ToDictionary( + e => e.Key, + e => new Edge(e.Value.Id, e.Value.StartId, e.Value.EndId)); + + clone._vertices = _vertices.ToDictionary( + e => e.Key, + e => { + var v = new Vertex(e.Value.Id, e.Value.Point); + foreach (var edge in e.Value.Edges) + { + v.Edges.Add(clone._edges[edge.Id]); + } + return v; + }); + + clone._edgesLookup = _edgesLookup.ToDictionary(e => e.Key, e => e.Value); + + clone._xyzLookup = _xyzLookup.ToDictionary( + xyz => xyz.Key, xyz => xyz.Value.ToDictionary( + yz => yz.Key, yz => yz.Value.ToDictionary( + z => z.Key, z => z.Value))); + + return clone; + } + #endregion #region Private logic @@ -799,7 +835,7 @@ private Edge AddInsertEdge(ulong vertexId1, ulong vertexId2) throw new ArgumentException("Can't create edge. End vertex id is not present in the grid.", $"{vertexId2}"); } - var edge = new Edge(this, this._edgeId, vertexId1, vertexId2); + var edge = new Edge(this._edgeId, vertexId1, vertexId2); edgeId = edge.Id; this._edgesLookup[hash] = edgeId; diff --git a/Elements/src/Spatial/AdaptiveGrid/Edge.cs b/Elements/src/Spatial/AdaptiveGrid/Edge.cs index 670758254..33e99b0f3 100644 --- a/Elements/src/Spatial/AdaptiveGrid/Edge.cs +++ b/Elements/src/Spatial/AdaptiveGrid/Edge.cs @@ -27,7 +27,7 @@ public class Edge /// public ulong Id { get; internal set; } - internal Edge(AdaptiveGrid adaptiveGrid, ulong id, ulong vertexId1, ulong vertexId2) + internal Edge(ulong id, ulong vertexId1, ulong vertexId2) { Id = id; this.SetVerticesFromIds(vertexId1, vertexId2); diff --git a/Elements/test/AdaptiveGridTests.cs b/Elements/test/AdaptiveGridTests.cs index 52bf4da2f..bd05f23bc 100644 --- a/Elements/test/AdaptiveGridTests.cs +++ b/Elements/test/AdaptiveGridTests.cs @@ -1146,6 +1146,37 @@ public void EdgeInfoFlagsTest() Assert.True(horizontalEdgeInfo.HasAnyFlag(EdgeFlags.UserDefinedHint2D | EdgeFlags.UserDefinedHint3D)); } + [Fact] + public void AdaptiveGridClone() + { + var grid = SampleGrid(); + var clone = grid.Clone(); + + grid.GetVertex(4).Point.IsAlmostEqualTo(new Vector3(5, 5)); + clone.GetVertex(4).Point.IsAlmostEqualTo(new Vector3(5, 5)); + + grid.AddVertex(new Vector3(5, -5), + new ConnectVertexStrategy(grid.GetVertex(1), grid.GetVertex(3)), cut: false); + clone.RemoveVertex(clone.GetVertex(5)); + clone.AddEdge(grid.GetVertex(2), grid.GetVertex(4)); + + Assert.True(grid.TryGetVertexIndex((5, 2), out var index)); + Assert.False(clone.TryGetVertexIndex((5, 2), out index)); + + Assert.True(grid.TryGetVertexIndex((5, -5), out index)); + Assert.False(clone.TryGetVertexIndex((5, 2), out index)); + + var v = grid.GetVertex(4); + Assert.Equal(2, grid.GetVertex(4).Edges.Count); + Assert.Null(v.GetEdge(2)); + + Assert.True(clone.TryGetVertexIndex((5, 5), out index)); + Assert.Equal(4u, index); + v = clone.GetVertex(index); + Assert.Equal(3, v.Edges.Count); + Assert.NotNull(v.GetEdge(2)); + } + // (4) // / \ // / \