From 734c7e2182e952487b9934f791ba9764fe8a6c35 Mon Sep 17 00:00:00 2001 From: katehryhorenko Date: Mon, 30 Oct 2023 16:44:03 -0300 Subject: [PATCH 1/7] Added optional snapping points generation; --- .../src/CoreModels/ElementRepresentation.cs | 28 +++++++++++++++++-- .../src/CoreModels/RepresentationInstance.cs | 27 ++++++++++++++++-- Elements/src/CoreModels/SnappingPoints.cs | 25 +++++++++++++++++ .../src/CoreModels/SnappingPointsSource.cs | 24 ++++++++++++++++ Elements/src/Geometry/Solids/Extrude.cs | 25 +++++++++++++++++ Elements/src/Geometry/Solids/Lamina.cs | 13 +++++++++ .../src/Geometry/Solids/SolidOperation.cs | 6 ++++ Elements/src/Geometry/Solids/Sweep.cs | 6 ++++ .../Representations/ContentRepresentation.cs | 4 +-- .../Representations/CurveRepresentation.cs | 9 ++++++ .../Representations/SolidRepresentation.cs | 13 +++++++++ .../src/Serialization/glTF/GltfExtensions.cs | 17 +++++++++-- 12 files changed, 188 insertions(+), 9 deletions(-) create mode 100644 Elements/src/CoreModels/SnappingPoints.cs create mode 100644 Elements/src/CoreModels/SnappingPointsSource.cs diff --git a/Elements/src/CoreModels/ElementRepresentation.cs b/Elements/src/CoreModels/ElementRepresentation.cs index 535badb4e..e570de929 100644 --- a/Elements/src/CoreModels/ElementRepresentation.cs +++ b/Elements/src/CoreModels/ElementRepresentation.cs @@ -23,8 +23,32 @@ public abstract class ElementRepresentation : SharedObject public abstract bool TryToGraphicsBuffers(GeometricElement element, out List graphicsBuffers, out string id, out MeshPrimitive.ModeEnum? mode); - internal virtual List GetNodeExtensions(GeometricElement element) + internal virtual List GetNodeExtensions(GeometricElement element, RepresentationInstance representationInstance) { - return new List(); + var extensions = new List(); + if (representationInstance.SnappingPointsSource == SnappingPointsSource.None) + { + return extensions; + } + + var snappingPointsDict = new Dictionary() { { "source", representationInstance.SnappingPointsSource } }; + if (representationInstance.SnappingPointsSource == SnappingPointsSource.ElementRepresentation) + { + var snappingPoints = CreateSnappingPoints(element); + snappingPointsDict.Add("points", snappingPoints); + } + + extensions.Add(new NodeExtension("HYPAR_snapping_points", snappingPointsDict)); + return extensions; + } + + /// + ///Creates the set of snapping points + /// + /// The element with this representation. + /// + public virtual List CreateSnappingPoints(GeometricElement element) + { + return new List(); } } \ No newline at end of file diff --git a/Elements/src/CoreModels/RepresentationInstance.cs b/Elements/src/CoreModels/RepresentationInstance.cs index c98ebe486..612b45a68 100644 --- a/Elements/src/CoreModels/RepresentationInstance.cs +++ b/Elements/src/CoreModels/RepresentationInstance.cs @@ -9,6 +9,25 @@ namespace Elements /// public class RepresentationInstance { + /// + /// The source of the snapping points. + /// + public SnappingPointsSource SnappingPointsSource { get; set; } + + + /// + /// Initializes a new instance of RepresentationInstance class. + /// + /// The element representation. + /// The material applied to the element representation. + /// Indicates if this representation is default. + /// The set of representation type names that can be used by view or by other parts of the sysetem to identify + /// if this element representation is suitable for display. + public RepresentationInstance(ElementRepresentation representation, Material material, bool isDefault = true, params string[] representationTypes) : + this(representation, material, isDefault, SnappingPointsSource.None, representationTypes) + { + } + /// /// Initializes a new instance of RepresentationInstance class. /// @@ -16,7 +35,7 @@ public class RepresentationInstance /// The material applied to the element representation. /// Indicates if this representation is default. public RepresentationInstance(ElementRepresentation representation, Material material, bool isDefault = true) : - this(representation, material, isDefault, "") + this(representation, material, isDefault, SnappingPointsSource.None, "") { } @@ -26,14 +45,16 @@ public RepresentationInstance(ElementRepresentation representation, Material mat /// The element representation. /// The material applied to the element representation. /// Indicates if this representation is default. + /// The snapping points source. /// The set of representation type names that can be used by view or by other parts of the sysetem to identify /// if this element representation is suitable for display. public RepresentationInstance(ElementRepresentation representation, Material material, - bool isDefault = true, params string[] representationTypes) + bool isDefault = true, SnappingPointsSource snappingPointsSource = SnappingPointsSource.None, params string[] representationTypes) { Representation = representation; Material = material; IsDefault = isDefault; + SnappingPointsSource = snappingPointsSource; foreach (var type in representationTypes) { RepresentationTypes.Add(type); @@ -58,7 +79,7 @@ public RepresentationInstance(ElementRepresentation representation, Material mat public List RepresentationTypes { get; set; } = new List(); /// - /// Indicates if this element representation instance is displayed by default. + /// Indicates if this element representation instance is displayed by default. /// Element can have several default representations. /// public bool IsDefault { get; set; } = true; diff --git a/Elements/src/CoreModels/SnappingPoints.cs b/Elements/src/CoreModels/SnappingPoints.cs new file mode 100644 index 000000000..e20a27def --- /dev/null +++ b/Elements/src/CoreModels/SnappingPoints.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using Elements.Geometry; + +namespace Elements +{ + /// + /// Provides information about snapping points. + /// + public class SnappingPoints + { + /// + /// Initializes a new instance of SnappingPoints class. + /// + /// The set of points. + public SnappingPoints(IEnumerable points) + { + Points.AddRange(points); + } + + /// + /// Snapping points. + /// + public List Points { get; } = new List(); + } +} \ No newline at end of file diff --git a/Elements/src/CoreModels/SnappingPointsSource.cs b/Elements/src/CoreModels/SnappingPointsSource.cs new file mode 100644 index 000000000..c8b12a3bb --- /dev/null +++ b/Elements/src/CoreModels/SnappingPointsSource.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Elements +{ + /// + /// The source of snapping points + /// + public enum SnappingPointsSource + { + /// + /// Elements doesn't have snapping points + /// + None, + /// + /// The ElementRepresentation. + /// + ElementRepresentation, + //TODO: add glb source + // Glb + } +} \ No newline at end of file diff --git a/Elements/src/Geometry/Solids/Extrude.cs b/Elements/src/Geometry/Solids/Extrude.cs index 04ce5d007..eeb509372 100644 --- a/Elements/src/Geometry/Solids/Extrude.cs +++ b/Elements/src/Geometry/Solids/Extrude.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Elements.Validators; using Newtonsoft.Json; @@ -108,6 +109,30 @@ public Extrude(Profile profile, double height, Vector3 direction, bool isVoid = UpdateGeometry(); } + internal override List CreateSnappingPoints(GeometricElement element) + { + var result = new List(); + var localTransform = new Transform(Direction * Height); + var bottomVertices = new List(); + result.Add(new SnappingPoints(Profile.Perimeter.Vertices)); + bottomVertices.AddRange(Profile.Perimeter.Vertices); + result.Add(new SnappingPoints(Profile.Perimeter.TransformedPolygon(localTransform).Vertices)); + + foreach (var item in Profile.Voids) + { + result.Add(new SnappingPoints(item.Vertices)); + bottomVertices.AddRange(item.Vertices); + result.Add(new SnappingPoints(item.TransformedPolygon(localTransform).Vertices)); + } + + foreach (var item in bottomVertices) + { + result.Add(new SnappingPoints(new List { item, localTransform.OfPoint(item) })); + } + + return result; + } + private void UpdateGeometry() { this._solid = Kernel.Instance.CreateExtrude(this._profile, this._height, this._direction, this._reverseWinding); diff --git a/Elements/src/Geometry/Solids/Lamina.cs b/Elements/src/Geometry/Solids/Lamina.cs index 58f90dc0e..478fbef02 100644 --- a/Elements/src/Geometry/Solids/Lamina.cs +++ b/Elements/src/Geometry/Solids/Lamina.cs @@ -82,6 +82,19 @@ public Lamina(Profile profile, bool isVoid = false) : this(profile.Perimeter, pr } + internal override List CreateSnappingPoints(GeometricElement element) + { + var result = new List(); + result.Add(new SnappingPoints(Perimeter.Vertices)); + + foreach (var item in Voids) + { + result.Add(new SnappingPoints(item.Vertices)); + } + + return result; + } + private void UpdateGeometry() { this._solid = Kernel.Instance.CreateLamina(this._perimeter, this._voids); diff --git a/Elements/src/Geometry/Solids/SolidOperation.cs b/Elements/src/Geometry/Solids/SolidOperation.cs index 497d4c9ee..3a88192d6 100644 --- a/Elements/src/Geometry/Solids/SolidOperation.cs +++ b/Elements/src/Geometry/Solids/SolidOperation.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using Newtonsoft.Json; namespace Elements.Geometry.Solids @@ -53,5 +54,10 @@ protected virtual void RaisePropertyChanged([System.Runtime.CompilerServices.Cal if (handler != null) handler(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } + + internal virtual List CreateSnappingPoints(GeometricElement element) + { + return new List(); + } } } \ No newline at end of file diff --git a/Elements/src/Geometry/Solids/Sweep.cs b/Elements/src/Geometry/Solids/Sweep.cs index 683a5efb2..689144a47 100644 --- a/Elements/src/Geometry/Solids/Sweep.cs +++ b/Elements/src/Geometry/Solids/Sweep.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using Newtonsoft.Json; namespace Elements.Geometry.Solids @@ -109,6 +110,11 @@ public double ProfileRotation } } + internal override List CreateSnappingPoints(GeometricElement element) + { + return base.CreateSnappingPoints(element); + } + private void UpdateGeometry() { this._solid = Kernel.Instance.CreateSweepAlongCurve(this._profile, this._curve, this._startSetback, this._endSetback, this._profileRotation); diff --git a/Elements/src/Representations/ContentRepresentation.cs b/Elements/src/Representations/ContentRepresentation.cs index 2ec792384..acbb85e28 100644 --- a/Elements/src/Representations/ContentRepresentation.cs +++ b/Elements/src/Representations/ContentRepresentation.cs @@ -77,9 +77,9 @@ public override bool TryToGraphicsBuffers(GeometricElement element, out List GetNodeExtensions(GeometricElement element) + internal override List GetNodeExtensions(GeometricElement element, RepresentationInstance representationInstance) { - var extensions = base.GetNodeExtensions(element); + var extensions = base.GetNodeExtensions(element, representationInstance); extensions.Add(new NodeExtension("HYPAR_referenced_content", "contentUrl", GlbLocation)); return extensions; } diff --git a/Elements/src/Representations/CurveRepresentation.cs b/Elements/src/Representations/CurveRepresentation.cs index b2e8a3731..aeaf61e16 100644 --- a/Elements/src/Representations/CurveRepresentation.cs +++ b/Elements/src/Representations/CurveRepresentation.cs @@ -45,5 +45,14 @@ public override bool TryToGraphicsBuffers(GeometricElement element, out List + public override List CreateSnappingPoints(GeometricElement element) + { + var snappingPoints = new List(); + var curvePoints = _curve.RenderVertices(); + snappingPoints.Add(new SnappingPoints(curvePoints)); + return snappingPoints; + } } } \ No newline at end of file diff --git a/Elements/src/Representations/SolidRepresentation.cs b/Elements/src/Representations/SolidRepresentation.cs index 5832a154a..d8521056c 100644 --- a/Elements/src/Representations/SolidRepresentation.cs +++ b/Elements/src/Representations/SolidRepresentation.cs @@ -191,5 +191,18 @@ public List> CalculateIntersectionPoints(GeometricElement element, return intersectionPoints; } + + /// + public override List CreateSnappingPoints(GeometricElement element) + { + var snappingPoints = new List(); + + foreach (var solidOperation in SolidOperations) + { + snappingPoints.AddRange(solidOperation.CreateSnappingPoints(element)); + } + + return snappingPoints; + } } } \ No newline at end of file diff --git a/Elements/src/Serialization/glTF/GltfExtensions.cs b/Elements/src/Serialization/glTF/GltfExtensions.cs index 0ad8f3324..3d38264ff 100644 --- a/Elements/src/Serialization/glTF/GltfExtensions.cs +++ b/Elements/src/Serialization/glTF/GltfExtensions.cs @@ -452,6 +452,19 @@ private static void AddExtension(Gltf gltf, glTFLoader.Schema.Node gltfNode, str gltfNode.Extensions.Add(extensionName, extensionAttributes); } + /// + /// Add a custom Mesh extension. + /// + private static void AddExtension(Gltf gltf, glTFLoader.Schema.Mesh gltfMesh, string extensionName, Dictionary extensionAttributes) + { + if (gltfMesh.Extensions == null) + { + gltfMesh.Extensions = new Dictionary(); + } + AddExtension(gltf, extensionName, extensionAttributes); + gltfMesh.Extensions.Add(extensionName, extensionAttributes); + } + /// /// Add a generic custom extension. /// @@ -1302,7 +1315,7 @@ private static void GetRenderDataForElement(Element e, { NodeUtilities.SetRepresentationInfo(nodes[index], representation); NodeUtilities.SetElementInfo(nodes[index], element.Id); - foreach (var nodeExtension in representation.Representation.GetNodeExtensions(element)) + foreach (var nodeExtension in representation.Representation.GetNodeExtensions(element, representation)) { AddExtension(gltf, nodes[index], nodeExtension.Name, nodeExtension.Attributes); } @@ -1344,7 +1357,7 @@ private static void GetRenderDataForElement(Element e, { NodeUtilities.SetRepresentationInfo(nodes[index], representation); NodeUtilities.SetElementInfo(nodes[index], element.Id); - foreach (var nodeExtension in representation.Representation.GetNodeExtensions(element)) + foreach (var nodeExtension in representation.Representation.GetNodeExtensions(element, representation)) { AddExtension(gltf, nodes[index], nodeExtension.Name, nodeExtension.Attributes); } From 4dbb895766e0efb147aa725e4587be757c4199e9 Mon Sep 17 00:00:00 2001 From: katehryhorenko Date: Mon, 30 Oct 2023 21:40:15 -0300 Subject: [PATCH 2/7] Added IsPolygon property (do we need to connect first and last points) --- Elements/src/CoreModels/SnappingPoints.cs | 13 ++++++++++++- Elements/src/Geometry/Solids/Extrude.cs | 12 ++++++++---- Elements/src/Geometry/Solids/Lamina.cs | 4 ++-- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/Elements/src/CoreModels/SnappingPoints.cs b/Elements/src/CoreModels/SnappingPoints.cs index e20a27def..25eba5fce 100644 --- a/Elements/src/CoreModels/SnappingPoints.cs +++ b/Elements/src/CoreModels/SnappingPoints.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using Elements.Geometry; +using Newtonsoft.Json; namespace Elements { @@ -12,14 +13,24 @@ public class SnappingPoints /// Initializes a new instance of SnappingPoints class. /// /// The set of points. - public SnappingPoints(IEnumerable points) + /// Indicates if snapping points create polygon. + public SnappingPoints(IEnumerable points, bool isPolygon = false) { Points.AddRange(points); + IsPolygon = isPolygon; } /// /// Snapping points. /// + [JsonProperty("points")] public List Points { get; } = new List(); + + /// + /// Indicates if snapping points create polygon. + /// If true, the first and the last points will be connected. + /// + [JsonProperty("isPolygon")] + public bool IsPolygon { get; set; } } } \ No newline at end of file diff --git a/Elements/src/Geometry/Solids/Extrude.cs b/Elements/src/Geometry/Solids/Extrude.cs index eeb509372..27b409d08 100644 --- a/Elements/src/Geometry/Solids/Extrude.cs +++ b/Elements/src/Geometry/Solids/Extrude.cs @@ -114,17 +114,21 @@ internal override List CreateSnappingPoints(GeometricElement ele var result = new List(); var localTransform = new Transform(Direction * Height); var bottomVertices = new List(); - result.Add(new SnappingPoints(Profile.Perimeter.Vertices)); + // add perimeter bottom points + result.Add(new SnappingPoints(Profile.Perimeter.Vertices, true)); bottomVertices.AddRange(Profile.Perimeter.Vertices); - result.Add(new SnappingPoints(Profile.Perimeter.TransformedPolygon(localTransform).Vertices)); + // add perimeter top points + result.Add(new SnappingPoints(Profile.Perimeter.TransformedPolygon(localTransform).Vertices, true)); + // add each void foreach (var item in Profile.Voids) { - result.Add(new SnappingPoints(item.Vertices)); + result.Add(new SnappingPoints(item.Vertices, true)); bottomVertices.AddRange(item.Vertices); - result.Add(new SnappingPoints(item.TransformedPolygon(localTransform).Vertices)); + result.Add(new SnappingPoints(item.TransformedPolygon(localTransform).Vertices, true)); } + // connect top and bottom points foreach (var item in bottomVertices) { result.Add(new SnappingPoints(new List { item, localTransform.OfPoint(item) })); diff --git a/Elements/src/Geometry/Solids/Lamina.cs b/Elements/src/Geometry/Solids/Lamina.cs index 478fbef02..7827ed958 100644 --- a/Elements/src/Geometry/Solids/Lamina.cs +++ b/Elements/src/Geometry/Solids/Lamina.cs @@ -85,11 +85,11 @@ public Lamina(Profile profile, bool isVoid = false) : this(profile.Perimeter, pr internal override List CreateSnappingPoints(GeometricElement element) { var result = new List(); - result.Add(new SnappingPoints(Perimeter.Vertices)); + result.Add(new SnappingPoints(Perimeter.Vertices, true)); foreach (var item in Voids) { - result.Add(new SnappingPoints(item.Vertices)); + result.Add(new SnappingPoints(item.Vertices, true)); } return result; From bfdc9622c6c5a887fce39934946ca30ac71efc63 Mon Sep 17 00:00:00 2001 From: katehryhorenko Date: Mon, 30 Oct 2023 23:11:07 -0300 Subject: [PATCH 3/7] Keep SnappingPoints.Points as double[] inside glb; --- Elements/src/CoreModels/SnappingPoints.cs | 2 ++ .../JSON/VectorListToByteArrayConverter.cs | 34 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 Elements/src/Serialization/JSON/VectorListToByteArrayConverter.cs diff --git a/Elements/src/CoreModels/SnappingPoints.cs b/Elements/src/CoreModels/SnappingPoints.cs index 25eba5fce..a0f031467 100644 --- a/Elements/src/CoreModels/SnappingPoints.cs +++ b/Elements/src/CoreModels/SnappingPoints.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using Elements.Geometry; +using Elements.Serialization.JSON; using Newtonsoft.Json; namespace Elements @@ -24,6 +25,7 @@ public SnappingPoints(IEnumerable points, bool isPolygon = false) /// Snapping points. /// [JsonProperty("points")] + [JsonConverter(typeof(VectorListToByteArrayConverter))] public List Points { get; } = new List(); /// diff --git a/Elements/src/Serialization/JSON/VectorListToByteArrayConverter.cs b/Elements/src/Serialization/JSON/VectorListToByteArrayConverter.cs new file mode 100644 index 000000000..848f4fe75 --- /dev/null +++ b/Elements/src/Serialization/JSON/VectorListToByteArrayConverter.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using Elements.Geometry; +using Newtonsoft.Json; + +namespace Elements.Serialization.JSON +{ + internal class VectorListToByteArrayConverter : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return objectType == typeof(List); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + throw new NotImplementedException(); + + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var points = value as List; + var valueAsArray = new double[points.Count * 3]; + for (int i = 0; i < points.Count; i++) + { + valueAsArray[i * 3] = points[i].X; + valueAsArray[i * 3 + 1] = points[i].Y; + valueAsArray[i * 3 + 2] = points[i].Z; + } + serializer.Serialize(writer, valueAsArray); + } + } +} \ No newline at end of file From 50d65358649ccd3e7d48133d9c20beaef15e2459 Mon Sep 17 00:00:00 2001 From: katehryhorenko Date: Tue, 31 Oct 2023 18:19:36 -0300 Subject: [PATCH 4/7] Replaced isPolygon with SnappingEdgeMode --- Elements/src/Geometry/Solids/Extrude.cs | 13 ++++++---- Elements/src/Geometry/Solids/Lamina.cs | 4 +-- Elements/src/Snapping/SnappingEdgeMode.cs | 25 +++++++++++++++++++ .../SnappingPoints.cs | 13 +++++----- .../SnappingPointsSource.cs | 11 +++----- 5 files changed, 44 insertions(+), 22 deletions(-) create mode 100644 Elements/src/Snapping/SnappingEdgeMode.cs rename Elements/src/{CoreModels => Snapping}/SnappingPoints.cs (65%) rename Elements/src/{CoreModels => Snapping}/SnappingPointsSource.cs (57%) diff --git a/Elements/src/Geometry/Solids/Extrude.cs b/Elements/src/Geometry/Solids/Extrude.cs index 27b409d08..4af71ef56 100644 --- a/Elements/src/Geometry/Solids/Extrude.cs +++ b/Elements/src/Geometry/Solids/Extrude.cs @@ -115,24 +115,27 @@ internal override List CreateSnappingPoints(GeometricElement ele var localTransform = new Transform(Direction * Height); var bottomVertices = new List(); // add perimeter bottom points - result.Add(new SnappingPoints(Profile.Perimeter.Vertices, true)); + result.Add(new SnappingPoints(Profile.Perimeter.Vertices, SnappingEdgeMode.LineLoop)); bottomVertices.AddRange(Profile.Perimeter.Vertices); // add perimeter top points - result.Add(new SnappingPoints(Profile.Perimeter.TransformedPolygon(localTransform).Vertices, true)); + result.Add(new SnappingPoints(Profile.Perimeter.TransformedPolygon(localTransform).Vertices, SnappingEdgeMode.LineLoop)); // add each void foreach (var item in Profile.Voids) { - result.Add(new SnappingPoints(item.Vertices, true)); + result.Add(new SnappingPoints(item.Vertices, SnappingEdgeMode.LineLoop)); bottomVertices.AddRange(item.Vertices); - result.Add(new SnappingPoints(item.TransformedPolygon(localTransform).Vertices, true)); + result.Add(new SnappingPoints(item.TransformedPolygon(localTransform).Vertices, SnappingEdgeMode.LineLoop)); } // connect top and bottom points + var edges = new List(); foreach (var item in bottomVertices) { - result.Add(new SnappingPoints(new List { item, localTransform.OfPoint(item) })); + edges.Add(item); + edges.Add(localTransform.OfPoint(item)); } + result.Add(new SnappingPoints(edges, SnappingEdgeMode.Lines)); return result; } diff --git a/Elements/src/Geometry/Solids/Lamina.cs b/Elements/src/Geometry/Solids/Lamina.cs index 7827ed958..e9e8331b4 100644 --- a/Elements/src/Geometry/Solids/Lamina.cs +++ b/Elements/src/Geometry/Solids/Lamina.cs @@ -85,11 +85,11 @@ public Lamina(Profile profile, bool isVoid = false) : this(profile.Perimeter, pr internal override List CreateSnappingPoints(GeometricElement element) { var result = new List(); - result.Add(new SnappingPoints(Perimeter.Vertices, true)); + result.Add(new SnappingPoints(Perimeter.Vertices, SnappingEdgeMode.LineLoop)); foreach (var item in Voids) { - result.Add(new SnappingPoints(item.Vertices, true)); + result.Add(new SnappingPoints(item.Vertices, SnappingEdgeMode.LineLoop)); } return result; diff --git a/Elements/src/Snapping/SnappingEdgeMode.cs b/Elements/src/Snapping/SnappingEdgeMode.cs new file mode 100644 index 000000000..63ffb38d5 --- /dev/null +++ b/Elements/src/Snapping/SnappingEdgeMode.cs @@ -0,0 +1,25 @@ +namespace Elements +{ + /// + /// Enumerates the modes for creating snap edges. + /// + public enum SnappingEdgeMode + { + /// + /// No edges are created; only individual point snaps. + /// + Points, + /// + /// A snap edge is drawn between every pair of points, creating a network of edges. + /// + Lines, + /// + /// Snap edges connect each subsequent point and also close the shape by connecting the last to the first point. + /// + LineLoop, + /// + /// Snap edges connect each subsequent point, without closing the shape. + /// + LineStrip + } +} \ No newline at end of file diff --git a/Elements/src/CoreModels/SnappingPoints.cs b/Elements/src/Snapping/SnappingPoints.cs similarity index 65% rename from Elements/src/CoreModels/SnappingPoints.cs rename to Elements/src/Snapping/SnappingPoints.cs index a0f031467..8c00dfe61 100644 --- a/Elements/src/CoreModels/SnappingPoints.cs +++ b/Elements/src/Snapping/SnappingPoints.cs @@ -14,11 +14,11 @@ public class SnappingPoints /// Initializes a new instance of SnappingPoints class. /// /// The set of points. - /// Indicates if snapping points create polygon. - public SnappingPoints(IEnumerable points, bool isPolygon = false) + /// The mode for creating snap edges. + public SnappingPoints(IEnumerable points, SnappingEdgeMode edgeMode = SnappingEdgeMode.LineStrip) { Points.AddRange(points); - IsPolygon = isPolygon; + EdgeMode = edgeMode; } /// @@ -29,10 +29,9 @@ public SnappingPoints(IEnumerable points, bool isPolygon = false) public List Points { get; } = new List(); /// - /// Indicates if snapping points create polygon. - /// If true, the first and the last points will be connected. + /// The modes for creating snap edges. /// - [JsonProperty("isPolygon")] - public bool IsPolygon { get; set; } + [JsonProperty("edgeMode")] + public SnappingEdgeMode EdgeMode { get; set; } } } \ No newline at end of file diff --git a/Elements/src/CoreModels/SnappingPointsSource.cs b/Elements/src/Snapping/SnappingPointsSource.cs similarity index 57% rename from Elements/src/CoreModels/SnappingPointsSource.cs rename to Elements/src/Snapping/SnappingPointsSource.cs index c8b12a3bb..b0e8e62af 100644 --- a/Elements/src/CoreModels/SnappingPointsSource.cs +++ b/Elements/src/Snapping/SnappingPointsSource.cs @@ -1,24 +1,19 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - namespace Elements { /// - /// The source of snapping points + /// The source of snapping points. /// public enum SnappingPointsSource { /// - /// Elements doesn't have snapping points + /// Elements doesn't have snapping points. /// None, /// /// The ElementRepresentation. /// ElementRepresentation, - //TODO: add glb source + //TODO: add glb source. // Glb } } \ No newline at end of file From fbb9d0aa090354cfd64e79b75e18866af5804d54 Mon Sep 17 00:00:00 2001 From: katehryhorenko Date: Mon, 6 Nov 2023 11:51:21 -0400 Subject: [PATCH 5/7] Moved snapping points to the mesh user data; Moved snapping source to the representation info; Added mesh index to teh representation info; --- .../src/CoreModels/ElementRepresentation.cs | 18 ++---------------- .../Representations/ContentRepresentation.cs | 4 ++-- .../src/Serialization/glTF/GltfExtensions.cs | 9 +++++++-- .../src/Serialization/glTF/NodeUtilities.cs | 12 +++++++++--- Elements/src/Snapping/SnappingPointsSource.cs | 8 +++++--- 5 files changed, 25 insertions(+), 26 deletions(-) diff --git a/Elements/src/CoreModels/ElementRepresentation.cs b/Elements/src/CoreModels/ElementRepresentation.cs index e570de929..4545df75f 100644 --- a/Elements/src/CoreModels/ElementRepresentation.cs +++ b/Elements/src/CoreModels/ElementRepresentation.cs @@ -23,23 +23,9 @@ public abstract class ElementRepresentation : SharedObject public abstract bool TryToGraphicsBuffers(GeometricElement element, out List graphicsBuffers, out string id, out MeshPrimitive.ModeEnum? mode); - internal virtual List GetNodeExtensions(GeometricElement element, RepresentationInstance representationInstance) + internal virtual List GetNodeExtensions(GeometricElement element) { - var extensions = new List(); - if (representationInstance.SnappingPointsSource == SnappingPointsSource.None) - { - return extensions; - } - - var snappingPointsDict = new Dictionary() { { "source", representationInstance.SnappingPointsSource } }; - if (representationInstance.SnappingPointsSource == SnappingPointsSource.ElementRepresentation) - { - var snappingPoints = CreateSnappingPoints(element); - snappingPointsDict.Add("points", snappingPoints); - } - - extensions.Add(new NodeExtension("HYPAR_snapping_points", snappingPointsDict)); - return extensions; + return new List(); } /// diff --git a/Elements/src/Representations/ContentRepresentation.cs b/Elements/src/Representations/ContentRepresentation.cs index acbb85e28..2ec792384 100644 --- a/Elements/src/Representations/ContentRepresentation.cs +++ b/Elements/src/Representations/ContentRepresentation.cs @@ -77,9 +77,9 @@ public override bool TryToGraphicsBuffers(GeometricElement element, out List GetNodeExtensions(GeometricElement element, RepresentationInstance representationInstance) + internal override List GetNodeExtensions(GeometricElement element) { - var extensions = base.GetNodeExtensions(element, representationInstance); + var extensions = base.GetNodeExtensions(element); extensions.Add(new NodeExtension("HYPAR_referenced_content", "contentUrl", GlbLocation)); return extensions; } diff --git a/Elements/src/Serialization/glTF/GltfExtensions.cs b/Elements/src/Serialization/glTF/GltfExtensions.cs index 3d38264ff..f2221edb3 100644 --- a/Elements/src/Serialization/glTF/GltfExtensions.cs +++ b/Elements/src/Serialization/glTF/GltfExtensions.cs @@ -1315,7 +1315,7 @@ private static void GetRenderDataForElement(Element e, { NodeUtilities.SetRepresentationInfo(nodes[index], representation); NodeUtilities.SetElementInfo(nodes[index], element.Id); - foreach (var nodeExtension in representation.Representation.GetNodeExtensions(element, representation)) + foreach (var nodeExtension in representation.Representation.GetNodeExtensions(element)) { AddExtension(gltf, nodes[index], nodeExtension.Name, nodeExtension.Attributes); } @@ -1341,6 +1341,11 @@ private static void GetRenderDataForElement(Element e, var meshIdList = new List { meshId }; representationsMap.Add(combinedId, meshIdList); addedNodes.AddRange(NodeUtilities.AddNodes(nodes, meshIdList, elementNodeId)); + var snappingPoints = representation.Representation.CreateSnappingPoints(element); + if (snappingPoints.Any()) + { + AddExtension(gltf, meshes[meshId], "HYPAR_snapping_points", new Dictionary() { { "points", snappingPoints } }); + } } } else @@ -1357,7 +1362,7 @@ private static void GetRenderDataForElement(Element e, { NodeUtilities.SetRepresentationInfo(nodes[index], representation); NodeUtilities.SetElementInfo(nodes[index], element.Id); - foreach (var nodeExtension in representation.Representation.GetNodeExtensions(element, representation)) + foreach (var nodeExtension in representation.Representation.GetNodeExtensions(element)) { AddExtension(gltf, nodes[index], nodeExtension.Name, nodeExtension.Attributes); } diff --git a/Elements/src/Serialization/glTF/NodeUtilities.cs b/Elements/src/Serialization/glTF/NodeUtilities.cs index 91ee6214e..3fd57dece 100644 --- a/Elements/src/Serialization/glTF/NodeUtilities.cs +++ b/Elements/src/Serialization/glTF/NodeUtilities.cs @@ -90,7 +90,7 @@ internal static Node AddInstanceAsCopyOfNode( // Two new nodes are created: a top-level node, which has the // element's Transform, and one just below that, which handles // flipping the orientation of the glb to have Z up. That node has - // the node to copy as its only child. + // the node to copy as its only child. // We use the node to copy exactly as is, with an unmodified // transform. // We need the outermost node to be "purely" the element's @@ -109,7 +109,7 @@ internal static Node AddInstanceAsCopyOfNode( var rootTransform = new Transform(); // glb has Y up. transform it to have Z up so we // can create instances of it in a Z up world. It will get switched - // back to Y up further up in the node hierarchy. + // back to Y up further up in the node hierarchy. rootTransform.Rotate(new Vector3(1, 0, 0), 90.0); float[] glbOrientationTransform = TransformToMatrix(rootTransform); var elementOrientationNode = new glTFLoader.Schema.Node(); @@ -237,9 +237,15 @@ public static void SetRepresentationInfo(this Node node, RepresentationInstance var extensionDict = new Dictionary { {"isDefault", representationInstance.IsDefault}, - {"representationType", representationInstance.RepresentationTypes} + {"representationType", representationInstance.RepresentationTypes}, + {"snappingSource", representationInstance.SnappingPointsSource}, }; + if (node.Mesh.HasValue) + { + extensionDict.Add("mesh", node.Mesh.Value); + } + node.Extensions["HYPAR_representation_info"] = extensionDict; } } diff --git a/Elements/src/Snapping/SnappingPointsSource.cs b/Elements/src/Snapping/SnappingPointsSource.cs index b0e8e62af..4fd3de98b 100644 --- a/Elements/src/Snapping/SnappingPointsSource.cs +++ b/Elements/src/Snapping/SnappingPointsSource.cs @@ -6,14 +6,16 @@ namespace Elements public enum SnappingPointsSource { /// - /// Elements doesn't have snapping points. + /// Element doesn't have snapping points. /// None, /// /// The ElementRepresentation. /// ElementRepresentation, - //TODO: add glb source. - // Glb + /// + /// Automatically generate snapping points based on the element's edges. + /// + AutoGenerated } } \ No newline at end of file From 8efe6ceee6309397061efcf559411aeec57c891b Mon Sep 17 00:00:00 2001 From: katehryhorenko Date: Mon, 6 Nov 2023 14:54:18 -0400 Subject: [PATCH 6/7] Code clean up; --- .../src/Serialization/JSON/VectorListToByteArrayConverter.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Elements/src/Serialization/JSON/VectorListToByteArrayConverter.cs b/Elements/src/Serialization/JSON/VectorListToByteArrayConverter.cs index 848f4fe75..35feb04c0 100644 --- a/Elements/src/Serialization/JSON/VectorListToByteArrayConverter.cs +++ b/Elements/src/Serialization/JSON/VectorListToByteArrayConverter.cs @@ -7,6 +7,8 @@ namespace Elements.Serialization.JSON { internal class VectorListToByteArrayConverter : JsonConverter { + public override bool CanRead => false; + public override bool CanConvert(Type objectType) { return objectType == typeof(List); From e8bbdab03ec3ce2e2ad2bf511a6d191a87d838e0 Mon Sep 17 00:00:00 2001 From: katehryhorenko Date: Tue, 7 Nov 2023 10:52:24 -0400 Subject: [PATCH 7/7] Removed snapping points source; --- .../src/CoreModels/RepresentationInstance.cs | 25 ++----------------- .../src/Serialization/glTF/NodeUtilities.cs | 1 - Elements/src/Snapping/SnappingPointsSource.cs | 21 ---------------- 3 files changed, 2 insertions(+), 45 deletions(-) delete mode 100644 Elements/src/Snapping/SnappingPointsSource.cs diff --git a/Elements/src/CoreModels/RepresentationInstance.cs b/Elements/src/CoreModels/RepresentationInstance.cs index 612b45a68..29914c2e8 100644 --- a/Elements/src/CoreModels/RepresentationInstance.cs +++ b/Elements/src/CoreModels/RepresentationInstance.cs @@ -9,25 +9,6 @@ namespace Elements /// public class RepresentationInstance { - /// - /// The source of the snapping points. - /// - public SnappingPointsSource SnappingPointsSource { get; set; } - - - /// - /// Initializes a new instance of RepresentationInstance class. - /// - /// The element representation. - /// The material applied to the element representation. - /// Indicates if this representation is default. - /// The set of representation type names that can be used by view or by other parts of the sysetem to identify - /// if this element representation is suitable for display. - public RepresentationInstance(ElementRepresentation representation, Material material, bool isDefault = true, params string[] representationTypes) : - this(representation, material, isDefault, SnappingPointsSource.None, representationTypes) - { - } - /// /// Initializes a new instance of RepresentationInstance class. /// @@ -35,7 +16,7 @@ public RepresentationInstance(ElementRepresentation representation, Material mat /// The material applied to the element representation. /// Indicates if this representation is default. public RepresentationInstance(ElementRepresentation representation, Material material, bool isDefault = true) : - this(representation, material, isDefault, SnappingPointsSource.None, "") + this(representation, material, isDefault, "") { } @@ -45,16 +26,14 @@ public RepresentationInstance(ElementRepresentation representation, Material mat /// The element representation. /// The material applied to the element representation. /// Indicates if this representation is default. - /// The snapping points source. /// The set of representation type names that can be used by view or by other parts of the sysetem to identify /// if this element representation is suitable for display. public RepresentationInstance(ElementRepresentation representation, Material material, - bool isDefault = true, SnappingPointsSource snappingPointsSource = SnappingPointsSource.None, params string[] representationTypes) + bool isDefault = true, params string[] representationTypes) { Representation = representation; Material = material; IsDefault = isDefault; - SnappingPointsSource = snappingPointsSource; foreach (var type in representationTypes) { RepresentationTypes.Add(type); diff --git a/Elements/src/Serialization/glTF/NodeUtilities.cs b/Elements/src/Serialization/glTF/NodeUtilities.cs index 3fd57dece..7e521c856 100644 --- a/Elements/src/Serialization/glTF/NodeUtilities.cs +++ b/Elements/src/Serialization/glTF/NodeUtilities.cs @@ -238,7 +238,6 @@ public static void SetRepresentationInfo(this Node node, RepresentationInstance { {"isDefault", representationInstance.IsDefault}, {"representationType", representationInstance.RepresentationTypes}, - {"snappingSource", representationInstance.SnappingPointsSource}, }; if (node.Mesh.HasValue) diff --git a/Elements/src/Snapping/SnappingPointsSource.cs b/Elements/src/Snapping/SnappingPointsSource.cs deleted file mode 100644 index 4fd3de98b..000000000 --- a/Elements/src/Snapping/SnappingPointsSource.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Elements -{ - /// - /// The source of snapping points. - /// - public enum SnappingPointsSource - { - /// - /// Element doesn't have snapping points. - /// - None, - /// - /// The ElementRepresentation. - /// - ElementRepresentation, - /// - /// Automatically generate snapping points based on the element's edges. - /// - AutoGenerated - } -} \ No newline at end of file