From b89c78355d40ec20a6b2b54c624ea2dbae0daaa6 Mon Sep 17 00:00:00 2001 From: Ian Keough Date: Tue, 20 Sep 2022 16:33:35 -0700 Subject: [PATCH 01/16] First commit of sketch grids. --- Grids/SketchGrids/.gitignore | 9 + Grids/SketchGrids/README.md | 16 + Grids/SketchGrids/SketchGrids.sln | 62 ++++ .../dependencies/ConceptualMass.g.cs | 68 ++++ Grids/SketchGrids/dependencies/Envelope.g.cs | 73 ++++ .../dependencies/GridLinesOverride.g.cs | 152 ++++++++ .../GridLinesOverrideAddition.g.cs | 32 ++ .../GridLinesOverrideRemoval.g.cs | 32 ++ Grids/SketchGrids/dependencies/LocalEdge.cs | 83 +++++ .../SketchGrids.Dependencies.csproj | 12 + .../dependencies/SketchGridsInputs.g.cs | 335 ++++++++++++++++++ .../dependencies/SketchGridsOutputs.g.cs | 32 ++ Grids/SketchGrids/hypar.json | 72 ++++ Grids/SketchGrids/src/Function.g.cs | 72 ++++ Grids/SketchGrids/src/SketchGrids.cs | 207 +++++++++++ Grids/SketchGrids/src/SketchGrids.csproj | 11 + .../SketchGrids/src/VectorEqualityComparer.cs | 29 ++ Grids/SketchGrids/test/FunctionTest.g.cs | 24 ++ .../SketchGrids/test/SketchGrids.Tests.csproj | 20 ++ 19 files changed, 1341 insertions(+) create mode 100644 Grids/SketchGrids/.gitignore create mode 100644 Grids/SketchGrids/README.md create mode 100644 Grids/SketchGrids/SketchGrids.sln create mode 100644 Grids/SketchGrids/dependencies/ConceptualMass.g.cs create mode 100644 Grids/SketchGrids/dependencies/Envelope.g.cs create mode 100644 Grids/SketchGrids/dependencies/GridLinesOverride.g.cs create mode 100644 Grids/SketchGrids/dependencies/GridLinesOverrideAddition.g.cs create mode 100644 Grids/SketchGrids/dependencies/GridLinesOverrideRemoval.g.cs create mode 100644 Grids/SketchGrids/dependencies/LocalEdge.cs create mode 100644 Grids/SketchGrids/dependencies/SketchGrids.Dependencies.csproj create mode 100644 Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs create mode 100644 Grids/SketchGrids/dependencies/SketchGridsOutputs.g.cs create mode 100644 Grids/SketchGrids/hypar.json create mode 100644 Grids/SketchGrids/src/Function.g.cs create mode 100644 Grids/SketchGrids/src/SketchGrids.cs create mode 100644 Grids/SketchGrids/src/SketchGrids.csproj create mode 100644 Grids/SketchGrids/src/VectorEqualityComparer.cs create mode 100644 Grids/SketchGrids/test/FunctionTest.g.cs create mode 100644 Grids/SketchGrids/test/SketchGrids.Tests.csproj diff --git a/Grids/SketchGrids/.gitignore b/Grids/SketchGrids/.gitignore new file mode 100644 index 00000000..f1d4f671 --- /dev/null +++ b/Grids/SketchGrids/.gitignore @@ -0,0 +1,9 @@ + +bin/ +obj/ +*.glb +output.json +input.json +.vs/ +server/ +test/Generated/ \ No newline at end of file diff --git a/Grids/SketchGrids/README.md b/Grids/SketchGrids/README.md new file mode 100644 index 00000000..572e9553 --- /dev/null +++ b/Grids/SketchGrids/README.md @@ -0,0 +1,16 @@ + + +# Sketch Grids + +Sketch grid lines. + +|Input Name|Type|Description| +|---|---|---| +|Offset Distance From Conceptual Mass|number|The default grid offset from the conceptual mass.| + + +
+ +|Output Name|Type|Description| +|---|---|---| + diff --git a/Grids/SketchGrids/SketchGrids.sln b/Grids/SketchGrids/SketchGrids.sln new file mode 100644 index 00000000..31e43d88 --- /dev/null +++ b/Grids/SketchGrids/SketchGrids.sln @@ -0,0 +1,62 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SketchGrids", "src\SketchGrids.csproj", "{EAA286E4-3EE3-4017-945A-18189AE2FDDC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SketchGrids.Dependencies", "dependencies\SketchGrids.Dependencies.csproj", "{C3DC1E0D-A438-4CC9-9DBB-61B81DD1929F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SketchGrids.Tests", "test\SketchGrids.Tests.csproj", "{6B5FECA2-A2AB-4D74-B89A-A37E33408D91}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EAA286E4-3EE3-4017-945A-18189AE2FDDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EAA286E4-3EE3-4017-945A-18189AE2FDDC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EAA286E4-3EE3-4017-945A-18189AE2FDDC}.Debug|x64.ActiveCfg = Debug|Any CPU + {EAA286E4-3EE3-4017-945A-18189AE2FDDC}.Debug|x64.Build.0 = Debug|Any CPU + {EAA286E4-3EE3-4017-945A-18189AE2FDDC}.Debug|x86.ActiveCfg = Debug|Any CPU + {EAA286E4-3EE3-4017-945A-18189AE2FDDC}.Debug|x86.Build.0 = Debug|Any CPU + {EAA286E4-3EE3-4017-945A-18189AE2FDDC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EAA286E4-3EE3-4017-945A-18189AE2FDDC}.Release|Any CPU.Build.0 = Release|Any CPU + {EAA286E4-3EE3-4017-945A-18189AE2FDDC}.Release|x64.ActiveCfg = Release|Any CPU + {EAA286E4-3EE3-4017-945A-18189AE2FDDC}.Release|x64.Build.0 = Release|Any CPU + {EAA286E4-3EE3-4017-945A-18189AE2FDDC}.Release|x86.ActiveCfg = Release|Any CPU + {EAA286E4-3EE3-4017-945A-18189AE2FDDC}.Release|x86.Build.0 = Release|Any CPU + {C3DC1E0D-A438-4CC9-9DBB-61B81DD1929F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C3DC1E0D-A438-4CC9-9DBB-61B81DD1929F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C3DC1E0D-A438-4CC9-9DBB-61B81DD1929F}.Debug|x64.ActiveCfg = Debug|Any CPU + {C3DC1E0D-A438-4CC9-9DBB-61B81DD1929F}.Debug|x64.Build.0 = Debug|Any CPU + {C3DC1E0D-A438-4CC9-9DBB-61B81DD1929F}.Debug|x86.ActiveCfg = Debug|Any CPU + {C3DC1E0D-A438-4CC9-9DBB-61B81DD1929F}.Debug|x86.Build.0 = Debug|Any CPU + {C3DC1E0D-A438-4CC9-9DBB-61B81DD1929F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C3DC1E0D-A438-4CC9-9DBB-61B81DD1929F}.Release|Any CPU.Build.0 = Release|Any CPU + {C3DC1E0D-A438-4CC9-9DBB-61B81DD1929F}.Release|x64.ActiveCfg = Release|Any CPU + {C3DC1E0D-A438-4CC9-9DBB-61B81DD1929F}.Release|x64.Build.0 = Release|Any CPU + {C3DC1E0D-A438-4CC9-9DBB-61B81DD1929F}.Release|x86.ActiveCfg = Release|Any CPU + {C3DC1E0D-A438-4CC9-9DBB-61B81DD1929F}.Release|x86.Build.0 = Release|Any CPU + {6B5FECA2-A2AB-4D74-B89A-A37E33408D91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6B5FECA2-A2AB-4D74-B89A-A37E33408D91}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6B5FECA2-A2AB-4D74-B89A-A37E33408D91}.Debug|x64.ActiveCfg = Debug|Any CPU + {6B5FECA2-A2AB-4D74-B89A-A37E33408D91}.Debug|x64.Build.0 = Debug|Any CPU + {6B5FECA2-A2AB-4D74-B89A-A37E33408D91}.Debug|x86.ActiveCfg = Debug|Any CPU + {6B5FECA2-A2AB-4D74-B89A-A37E33408D91}.Debug|x86.Build.0 = Debug|Any CPU + {6B5FECA2-A2AB-4D74-B89A-A37E33408D91}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6B5FECA2-A2AB-4D74-B89A-A37E33408D91}.Release|Any CPU.Build.0 = Release|Any CPU + {6B5FECA2-A2AB-4D74-B89A-A37E33408D91}.Release|x64.ActiveCfg = Release|Any CPU + {6B5FECA2-A2AB-4D74-B89A-A37E33408D91}.Release|x64.Build.0 = Release|Any CPU + {6B5FECA2-A2AB-4D74-B89A-A37E33408D91}.Release|x86.ActiveCfg = Release|Any CPU + {6B5FECA2-A2AB-4D74-B89A-A37E33408D91}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/Grids/SketchGrids/dependencies/ConceptualMass.g.cs b/Grids/SketchGrids/dependencies/ConceptualMass.g.cs new file mode 100644 index 00000000..4f20ef1d --- /dev/null +++ b/Grids/SketchGrids/dependencies/ConceptualMass.g.cs @@ -0,0 +1,68 @@ +//---------------------- +// +// Generated using the NJsonSchema v10.1.21.0 (Newtonsoft.Json v12.0.0.0) (http://NJsonSchema.org) +// +//---------------------- +using Elements; +using Elements.GeoJSON; +using Elements.Geometry; +using Elements.Geometry.Solids; +using Elements.Spatial; +using Elements.Validators; +using Elements.Serialization.JSON; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using Line = Elements.Geometry.Line; +using Polygon = Elements.Geometry.Polygon; + +namespace Elements +{ + #pragma warning disable // Disable all warnings + + /// Represents an early stage building massing volume. Its boundary typically represents the nominal edge of slab, and may be articulated further by subsequent functions. + [JsonConverter(typeof(Elements.Serialization.JSON.JsonInheritanceConverter), "discriminator")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + public partial class ConceptualMass : Envelope + { + [JsonConstructor] + public ConceptualMass(IList @skeleton, string @primaryUseCategory, System.Guid? @building, IList @levelIds, Transform @localCoordinateSystem, Profile @profile, double @elevation, double @height, Vector3 @direction, double @rotation, IList @floorToFloorHeights, Transform @transform, Material @material, Representation @representation, bool @isElementDefinition, System.Guid @id, string @name) + : base(profile, elevation, height, direction, rotation, floorToFloorHeights, transform, material, representation, isElementDefinition, id, name) + { + this.Skeleton = @skeleton; + this.PrimaryUseCategory = @primaryUseCategory; + this.Building = @building; + this.LevelIds = @levelIds; + this.LocalCoordinateSystem = @localCoordinateSystem; + } + + // Empty constructor + public ConceptualMass() + : base() + { + } + + /// A collection of lines which indicate a "centerline" of the mass. + [JsonProperty("Skeleton", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public IList Skeleton { get; set; } + + /// The primary programmatic use for this mass, e.g. Residential, Office, Parking, Retail. Some levels or spaces within the mass may have other uses. + [JsonProperty("Primary Use Category", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string PrimaryUseCategory { get; set; } + + /// The building this mass belongs to, if any. + [JsonProperty("Building", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public System.Guid? Building { get; set; } + + /// The ids of the levels this conceptual mass contains + [JsonProperty("Level Ids", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public IList LevelIds { get; set; } + + /// A transform representing the local coordinate system for this mass + [JsonProperty("Local Coordinate System", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public Transform LocalCoordinateSystem { get; set; } + + + } +} \ No newline at end of file diff --git a/Grids/SketchGrids/dependencies/Envelope.g.cs b/Grids/SketchGrids/dependencies/Envelope.g.cs new file mode 100644 index 00000000..c2546d41 --- /dev/null +++ b/Grids/SketchGrids/dependencies/Envelope.g.cs @@ -0,0 +1,73 @@ +//---------------------- +// +// Generated using the NJsonSchema v10.1.21.0 (Newtonsoft.Json v12.0.0.0) (http://NJsonSchema.org) +// +//---------------------- +using Elements; +using Elements.GeoJSON; +using Elements.Geometry; +using Elements.Geometry.Solids; +using Elements.Spatial; +using Elements.Validators; +using Elements.Serialization.JSON; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using Line = Elements.Geometry.Line; +using Polygon = Elements.Geometry.Polygon; + +namespace Elements +{ + #pragma warning disable // Disable all warnings + + /// Represents one part of a building enclosure. + [JsonConverter(typeof(Elements.Serialization.JSON.JsonInheritanceConverter), "discriminator")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + public partial class Envelope : GeometricElement + { + [JsonConstructor] + public Envelope(Profile @profile, double @elevation, double @height, Vector3 @direction, double @rotation, IList @floorToFloorHeights, Transform @transform = null, Material @material = null, Representation @representation = null, bool @isElementDefinition = false, System.Guid @id = default, string @name = null) + : base(transform, material, representation, isElementDefinition, id, name) + { + this.Profile = @profile; + this.Elevation = @elevation; + this.Height = @height; + this.Direction = @direction; + this.Rotation = @rotation; + this.FloorToFloorHeights = @floorToFloorHeights; + } + + // Empty constructor + public Envelope() + : base() + { + } + + /// The profile to extrude. + [JsonProperty("Profile", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public Profile Profile { get; set; } + + /// The elevation of the envelope. + [JsonProperty("Elevation", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public double Elevation { get; set; } + + /// The height of the envelope. + [JsonProperty("Height", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public double Height { get; set; } + + /// The direction in which to extrude. + [JsonProperty("Direction", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public Vector3 Direction { get; set; } + + /// The rotation of the envelope, in degrees. + [JsonProperty("Rotation", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public double Rotation { get; set; } + + /// An optional list of floor-to-floor heights for this envelope. If provided, levels can be generated from these floor-to-floor heights. + [JsonProperty("Floor To Floor Heights", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public IList FloorToFloorHeights { get; set; } + + + } +} \ No newline at end of file diff --git a/Grids/SketchGrids/dependencies/GridLinesOverride.g.cs b/Grids/SketchGrids/dependencies/GridLinesOverride.g.cs new file mode 100644 index 00000000..02d341fc --- /dev/null +++ b/Grids/SketchGrids/dependencies/GridLinesOverride.g.cs @@ -0,0 +1,152 @@ +using Elements; +using System.Collections.Generic; +using System; +using System.Linq; + +namespace SketchGrids +{ + /// + /// Override metadata for GridLinesOverride + /// + public partial class GridLinesOverride : IOverride + { + public static string Name = "Grid Lines"; + public static string Dependency = null; + public static string Context = "[*discriminator=Elements.GridLine]"; + public static string Paradigm = "Edit"; + + /// + /// Get the override name for this override. + /// + public string GetName() { + return Name; + } + + public object GetIdentity() { + + return Identity; + } + + } + public static class GridLinesOverrideExtensions + { + /// + /// Apply Grid Lines edit overrides to a collection of existing elements + /// + /// The Grid Lines Overrides to apply + /// A collection of existing elements to which to apply the overrides. + /// A function returning a boolean which indicates whether an element is a match for an override's identity. + /// A function to modify a matched element, returning the modified element. + /// The element type this override applies to. Should match the type(s) in the override's context. + /// A collection of elements, including unmodified and modified elements from the supplied collection. + public static List Apply( + this IList overrideData, + IEnumerable existingElements, + Func identityMatch, + Func modifyElement) where T : Element + { + var resultElements = new List(existingElements); + if (overrideData != null) + { + foreach (var overrideValue in overrideData) + { + // Assuming there will only be one match per identity, find the first element that matches. + var matchingElement = existingElements.FirstOrDefault(e => identityMatch(e, overrideValue.Identity)); + // if we found a match, + if (matchingElement != null) + { + // remove the old matching element + resultElements.Remove(matchingElement); + // apply the modification function to it + var modifiedElement = modifyElement(matchingElement, overrideValue); + // set the identity + Identity.AddOverrideIdentity(modifiedElement, overrideValue); + //and re-add it to the collection + resultElements.Add(modifiedElement); + } + } + } + return resultElements; + } + + /// + /// Apply Grid Lines edit overrides to a collection of existing elements + /// + /// A collection of existing elements to which to apply the overrides. + /// The Grid Lines Overrides to apply — typically `input.Overrides.GridLines` + /// A function returning a boolean which indicates whether an element is a match for an override's identity. + /// A function to modify a matched element, returning the modified element. + /// The element type this override applies to. Should match the type(s) in the override's context. + /// A collection of elements, including unmodified and modified elements from the supplied collection. + public static void ApplyOverrides( + this List existingElements, + IList overrideData, + Func identityMatch, + Func modifyElement + ) where T : Element + { + var updatedElements = overrideData.Apply(existingElements, identityMatch, modifyElement); + existingElements.Clear(); + existingElements.AddRange(updatedElements); + } + + /// + /// Create elements from add/removeoverrides, and apply any edits. + /// + /// The collection of edit overrides (Overrides.GridLines) + /// The collection of add overrides (Overrides.Additions.GridLines) + /// The collection of remove overrides (Overrides.Removals.GridLines) /// A function returning a boolean which indicates whether an element is a match for an override's identity. + /// A function to create a new element, returning the created element. + /// A function to modify a matched element, returning the modified element. + /// An optional collection of existing elements to which to apply any edit overrides, or remove if remove overrides are found. + /// The element type this override applies to. Should match the type(s) in the override's context. + /// A collection of elements, including new, unmodified, and modified elements from the supplied collection. + public static List CreateElements( + this IList edits, + IList additions, + IList removals, Func createElement, + Func identityMatch, + Func modifyElement, + IEnumerable existingElements = null + ) where T : Element + { + List resultElements = existingElements == null ? new List() : new List(existingElements); + if (removals != null) + { + foreach (var removedElement in removals) + { + var elementToRemove = resultElements.FirstOrDefault(e => identityMatch(e, removedElement.Identity)); + if (elementToRemove != null) + { + resultElements.Remove(elementToRemove); + } + } + } if (additions != null) + { + foreach (var addedElement in additions) + { + var elementToAdd = createElement(addedElement); + resultElements.Add(elementToAdd); + Identity.AddOverrideIdentity(elementToAdd, addedElement); + } + } + if (edits != null) + { + foreach (var editedElement in edits) + { + var elementToEdit = resultElements.FirstOrDefault(e => identityMatch(e, editedElement.Identity)); + if (elementToEdit != null) + { + resultElements.Remove(elementToEdit); + resultElements.Add(modifyElement(elementToEdit, editedElement)); + Identity.AddOverrideIdentity(elementToEdit, editedElement); + } + } + } + return resultElements; + } + + } + + +} \ No newline at end of file diff --git a/Grids/SketchGrids/dependencies/GridLinesOverrideAddition.g.cs b/Grids/SketchGrids/dependencies/GridLinesOverrideAddition.g.cs new file mode 100644 index 00000000..6f1b6f8b --- /dev/null +++ b/Grids/SketchGrids/dependencies/GridLinesOverrideAddition.g.cs @@ -0,0 +1,32 @@ +using Elements; +using System.Collections.Generic; +using System; +using System.Linq; + +namespace SketchGrids +{ + /// + /// Override metadata for GridLinesOverrideAddition + /// + public partial class GridLinesOverrideAddition : IOverride + { + public static string Name = "Grid Lines Addition"; + public static string Dependency = null; + public static string Context = "[*discriminator=Elements.GridLine]"; + public static string Paradigm = "Edit"; + + /// + /// Get the override name for this override. + /// + public string GetName() { + return Name; + } + + public object GetIdentity() { + + return Identity; + } + + } + +} \ No newline at end of file diff --git a/Grids/SketchGrids/dependencies/GridLinesOverrideRemoval.g.cs b/Grids/SketchGrids/dependencies/GridLinesOverrideRemoval.g.cs new file mode 100644 index 00000000..46e7c6f9 --- /dev/null +++ b/Grids/SketchGrids/dependencies/GridLinesOverrideRemoval.g.cs @@ -0,0 +1,32 @@ +using Elements; +using System.Collections.Generic; +using System; +using System.Linq; + +namespace SketchGrids +{ + /// + /// Override metadata for GridLinesOverrideRemoval + /// + public partial class GridLinesOverrideRemoval : IOverride + { + public static string Name = "Grid Lines Removal"; + public static string Dependency = null; + public static string Context = "[*discriminator=Elements.GridLine]"; + public static string Paradigm = "Edit"; + + /// + /// Get the override name for this override. + /// + public string GetName() { + return Name; + } + + public object GetIdentity() { + + return Identity; + } + + } + +} \ No newline at end of file diff --git a/Grids/SketchGrids/dependencies/LocalEdge.cs b/Grids/SketchGrids/dependencies/LocalEdge.cs new file mode 100644 index 00000000..b76f0b7d --- /dev/null +++ b/Grids/SketchGrids/dependencies/LocalEdge.cs @@ -0,0 +1,83 @@ +using System; + +namespace SketchGrids +{ + /// + /// Provides graph edge info + /// + public class LocalEdge + { + [Flags] + private enum VisitDirections + { + None, + Straight, + Opposite + } + + /// + /// Creates a new instance of Edge class + /// + /// The index of the first vertex + /// The index of the second vertex + public LocalEdge(int vertexIndex1, int vertexIndex2) + { + visitDirections = VisitDirections.None; + VertexIndex1 = vertexIndex1; + VertexIndex2 = vertexIndex2; + } + + public int VertexIndex1 { get; } + public int VertexIndex2 { get; } + + /// + /// Added record that edge was visited from the vertex index + /// + /// The index of the vertex where the edge is visited from + public void MarkAsVisited(int vertexIndex) + { + if (vertexIndex == VertexIndex1) + { + visitDirections |= VisitDirections.Straight; + } + else if (vertexIndex == VertexIndex2) + { + visitDirections |= VisitDirections.Opposite; + } + } + + /// + /// Returns if this edge is between input vertex indeces + /// + /// The index of the first vertex + /// The index of the second vertex + /// Returns True if edge is between input vertex indeces + public bool IsBetweenVertices(int vertexIndex1, int vertexIndex2) + { + return (VertexIndex1 == vertexIndex1 && VertexIndex2 == vertexIndex2) || + (VertexIndex1 == vertexIndex2 && VertexIndex2 == vertexIndex1); + } + + /// + /// Gets if the edge was visited from the vertex + /// + /// The index of the vertex where the edge is visited from + /// Returns True if the edge was visited from the vertex + public bool IsVisitedFromVertex(int vertexIndex) + { + if (VertexIndex1 == vertexIndex) + { + return visitDirections.HasFlag(VisitDirections.Straight); + } + + if (VertexIndex2 == vertexIndex) + { + return visitDirections.HasFlag(VisitDirections.Opposite); + } + + return false; + } + + private VisitDirections visitDirections; + } +} \ No newline at end of file diff --git a/Grids/SketchGrids/dependencies/SketchGrids.Dependencies.csproj b/Grids/SketchGrids/dependencies/SketchGrids.Dependencies.csproj new file mode 100644 index 00000000..9b55480d --- /dev/null +++ b/Grids/SketchGrids/dependencies/SketchGrids.Dependencies.csproj @@ -0,0 +1,12 @@ + + + + + + + + + netcoreapp3.1 + + + diff --git a/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs b/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs new file mode 100644 index 00000000..343dd5de --- /dev/null +++ b/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs @@ -0,0 +1,335 @@ +// This code was generated by Hypar. +// Edits to this code will be overwritten the next time you run 'hypar init'. +// DO NOT EDIT THIS FILE. + +using Elements; +using Elements.GeoJSON; +using Elements.Geometry; +using Elements.Geometry.Solids; +using Elements.Validators; +using Elements.Serialization.JSON; +using Hypar.Functions; +using Hypar.Functions.Execution; +using Hypar.Functions.Execution.AWS; +using Hypar.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using Line = Elements.Geometry.Line; +using Polygon = Elements.Geometry.Polygon; + +namespace SketchGrids +{ + #pragma warning disable // Disable all warnings + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + + public class SketchGridsInputs : S3Args + + { + [Newtonsoft.Json.JsonConstructor] + + public SketchGridsInputs(double @offsetDistanceFromConceptualMass, Overrides @overrides, string bucketName, string uploadsBucket, Dictionary modelInputKeys, string gltfKey, string elementsKey, string ifcKey): + base(bucketName, uploadsBucket, modelInputKeys, gltfKey, elementsKey, ifcKey) + { + var validator = Validator.Instance.GetFirstValidatorForType(); + if(validator != null) + { + validator.PreConstruct(new object[]{ @offsetDistanceFromConceptualMass, @overrides}); + } + + this.OffsetDistanceFromConceptualMass = @offsetDistanceFromConceptualMass; + this.Overrides = @overrides ?? this.Overrides; + + if(validator != null) + { + validator.PostConstruct(this); + } + } + + /// The default grid offset from the conceptual mass. + [Newtonsoft.Json.JsonProperty("Offset Distance From Conceptual Mass", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public double OffsetDistanceFromConceptualMass { get; set; } = 1.5D; + + [Newtonsoft.Json.JsonProperty("overrides", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public Overrides Overrides { get; set; } = new Overrides(); + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + + public partial class Overrides + + { + public Overrides() { } + + [Newtonsoft.Json.JsonConstructor] + public Overrides(OverrideAdditions @additions, OverrideRemovals @removals, IList @gridLines) + { + var validator = Validator.Instance.GetFirstValidatorForType(); + if(validator != null) + { + validator.PreConstruct(new object[]{ @additions, @removals, @gridLines}); + } + + this.Additions = @additions ?? this.Additions; + this.Removals = @removals ?? this.Removals; + this.GridLines = @gridLines ?? this.GridLines; + + if(validator != null) + { + validator.PostConstruct(this); + } + } + + [Newtonsoft.Json.JsonProperty("Additions", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public OverrideAdditions Additions { get; set; } = new OverrideAdditions(); + + [Newtonsoft.Json.JsonProperty("Removals", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public OverrideRemovals Removals { get; set; } = new OverrideRemovals(); + + [Newtonsoft.Json.JsonProperty("Grid Lines", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public IList GridLines { get; set; } = new List(); + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + + public partial class OverrideAdditions + + { + public OverrideAdditions() { } + + [Newtonsoft.Json.JsonConstructor] + public OverrideAdditions(IList @gridLines) + { + var validator = Validator.Instance.GetFirstValidatorForType(); + if(validator != null) + { + validator.PreConstruct(new object[]{ @gridLines}); + } + + this.GridLines = @gridLines ?? this.GridLines; + + if(validator != null) + { + validator.PostConstruct(this); + } + } + + [Newtonsoft.Json.JsonProperty("Grid Lines", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public IList GridLines { get; set; } = new List(); + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + + public partial class OverrideRemovals + + { + public OverrideRemovals() { } + + [Newtonsoft.Json.JsonConstructor] + public OverrideRemovals(IList @gridLines) + { + var validator = Validator.Instance.GetFirstValidatorForType(); + if(validator != null) + { + validator.PreConstruct(new object[]{ @gridLines}); + } + + this.GridLines = @gridLines ?? this.GridLines; + + if(validator != null) + { + validator.PostConstruct(this); + } + } + + [Newtonsoft.Json.JsonProperty("Grid Lines", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public IList GridLines { get; set; } = new List(); + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + + public partial class GridLinesOverride + + { + [Newtonsoft.Json.JsonConstructor] + public GridLinesOverride(string @id, GridLinesIdentity @identity, GridLinesValue @value) + { + var validator = Validator.Instance.GetFirstValidatorForType(); + if(validator != null) + { + validator.PreConstruct(new object[]{ @id, @identity, @value}); + } + + this.Id = @id; + this.Identity = @identity; + this.Value = @value; + + if(validator != null) + { + validator.PostConstruct(this); + } + } + + [Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string Id { get; set; } + + [Newtonsoft.Json.JsonProperty("Identity", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public GridLinesIdentity Identity { get; set; } + + [Newtonsoft.Json.JsonProperty("Value", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public GridLinesValue Value { get; set; } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + + public partial class GridLinesOverrideAddition + + { + [Newtonsoft.Json.JsonConstructor] + public GridLinesOverrideAddition(string @id, GridLinesIdentity @identity, GridLinesOverrideAdditionValue @value) + { + var validator = Validator.Instance.GetFirstValidatorForType(); + if(validator != null) + { + validator.PreConstruct(new object[]{ @id, @identity, @value}); + } + + this.Id = @id; + this.Identity = @identity; + this.Value = @value; + + if(validator != null) + { + validator.PostConstruct(this); + } + } + + [Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string Id { get; set; } + + [Newtonsoft.Json.JsonProperty("Identity", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public GridLinesIdentity Identity { get; set; } + + [Newtonsoft.Json.JsonProperty("Value", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public GridLinesOverrideAdditionValue Value { get; set; } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + + public partial class GridLinesOverrideRemoval + + { + [Newtonsoft.Json.JsonConstructor] + public GridLinesOverrideRemoval(string @id, GridLinesIdentity @identity) + { + var validator = Validator.Instance.GetFirstValidatorForType(); + if(validator != null) + { + validator.PreConstruct(new object[]{ @id, @identity}); + } + + this.Id = @id; + this.Identity = @identity; + + if(validator != null) + { + validator.PostConstruct(this); + } + } + + [Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string Id { get; set; } + + [Newtonsoft.Json.JsonProperty("Identity", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public GridLinesIdentity Identity { get; set; } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + + public partial class GridLinesIdentity + + { + [Newtonsoft.Json.JsonConstructor] + public GridLinesIdentity(System.Guid @creationId) + { + var validator = Validator.Instance.GetFirstValidatorForType(); + if(validator != null) + { + validator.PreConstruct(new object[]{ @creationId}); + } + + this.CreationId = @creationId; + + if(validator != null) + { + validator.PostConstruct(this); + } + } + + [Newtonsoft.Json.JsonProperty("Creation Id", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public System.Guid CreationId { get; set; } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + + public partial class GridLinesValue + + { + [Newtonsoft.Json.JsonConstructor] + public GridLinesValue(Line @curve) + { + var validator = Validator.Instance.GetFirstValidatorForType(); + if(validator != null) + { + validator.PreConstruct(new object[]{ @curve}); + } + + this.Curve = @curve; + + if(validator != null) + { + validator.PostConstruct(this); + } + } + + [Newtonsoft.Json.JsonProperty("Curve", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public Line Curve { get; set; } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + + public partial class GridLinesOverrideAdditionValue + + { + [Newtonsoft.Json.JsonConstructor] + public GridLinesOverrideAdditionValue(Line @curve) + { + var validator = Validator.Instance.GetFirstValidatorForType(); + if(validator != null) + { + validator.PreConstruct(new object[]{ @curve}); + } + + this.Curve = @curve; + + if(validator != null) + { + validator.PostConstruct(this); + } + } + + [Newtonsoft.Json.JsonProperty("Curve", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public Line Curve { get; set; } + + } +} \ No newline at end of file diff --git a/Grids/SketchGrids/dependencies/SketchGridsOutputs.g.cs b/Grids/SketchGrids/dependencies/SketchGridsOutputs.g.cs new file mode 100644 index 00000000..a25a4bed --- /dev/null +++ b/Grids/SketchGrids/dependencies/SketchGridsOutputs.g.cs @@ -0,0 +1,32 @@ +// This code was generated by Hypar. +// Edits to this code will be overwritten the next time you run 'hypar init'. +// DO NOT EDIT THIS FILE. + +using Elements; +using Elements.GeoJSON; +using Elements.Geometry; +using Hypar.Functions; +using Hypar.Functions.Execution; +using Hypar.Functions.Execution.AWS; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.Collections.Generic; + +namespace SketchGrids +{ + public class SketchGridsOutputs: SystemResults + { + + + /// + /// Construct a SketchGridsOutputs with default inputs. + /// This should be used for testing only. + /// + public SketchGridsOutputs() : base() + { + + } + + + } +} \ No newline at end of file diff --git a/Grids/SketchGrids/hypar.json b/Grids/SketchGrids/hypar.json new file mode 100644 index 00000000..68e9e126 --- /dev/null +++ b/Grids/SketchGrids/hypar.json @@ -0,0 +1,72 @@ +{ + "$schema": "https://hypar.io/Schemas/Function.json", + "id": "7b53fd3e-d94a-4333-9127-045722dddbd8", + "name": "Sketch Grids", + "description": "Sketch grid lines.", + "language": "C#", + "input_schema": { + "type": "object", + "properties": { + "Offset Distance From Conceptual Mass": { + "description": "The default grid offset from the conceptual mass.", + "type": "number", + "default": 1.5, + "$hyparUnitType": "length" + } + } + }, + "filters": { + "Grids": { + "context": "[*discriminator=Elements.GridLine]", + "default": true + }, + "Grid Cells": { + "context": "[*discriminator=Elements.Panel]" + } + }, + "overrides": { + "Grid Lines": { + "context": "[*discriminator=Elements.GridLine]", + "identity": { + "Creation Id": { + "type": "string", + "format": "uuid" + } + }, + "schema": { + "Curve": { + "$ref": "https://hypar.io/Schemas/Geometry/Line.json", + "$hyparAllowIntersection": true, + "$hyparContinueDrawing": true + } + }, + "behaviors": { + "add": { + "schema": { + "Curve": { + "$ref": "https://hypar.io/Schemas/Geometry/Line.json", + "$hyparAllowIntersection": true, + "$hyparContinueDrawing": true + } + } + }, + "remove": true + } + } + }, + "outputs": [], + "model_dependencies": [ + { + "name": "Conceptual Mass", + "autohide": false, + "optional": true + } + ], + "element_types": [ + "https://prod-api.hypar.io/schemas/ConceptualMass" + ], + "model_output": "Grids", + "repository_url": "https://github.com/hypar-io/function", + "last_updated": "0001-01-01T00:00:00", + "cli_version": "1.1.1" +} \ No newline at end of file diff --git a/Grids/SketchGrids/src/Function.g.cs b/Grids/SketchGrids/src/Function.g.cs new file mode 100644 index 00000000..d293ff99 --- /dev/null +++ b/Grids/SketchGrids/src/Function.g.cs @@ -0,0 +1,72 @@ +// This code was generated by Hypar. +// Edits to this code will be overwritten the next time you run 'hypar init'. +// DO NOT EDIT THIS FILE. + +using Amazon; +using Amazon.Lambda.Core; +using Hypar.Functions.Execution; +using Hypar.Functions.Execution.AWS; +using System; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))] +namespace SketchGrids +{ + public class Function + { + // Cache the model store for use by subsequent + // executions of this lambda. + private IModelStore store; + + public async Task Handler(SketchGridsInputs args, ILambdaContext context) + { + // Preload dependencies (if they exist), + // so that they are available during model deserialization. + + var sw = System.Diagnostics.Stopwatch.StartNew(); + var asmLocation = this.GetType().Assembly.Location; + var asmDir = Path.GetDirectoryName(asmLocation); + + // Explicitly load the dependencies project, it might have types + // that aren't used in the function but are necessary for correct + // deserialization. + var asmName = Path.GetFileNameWithoutExtension(asmLocation); + var depPath = Path.Combine(asmDir, $"{asmName}.Dependencies.dll"); + if(File.Exists(depPath)) + { + Console.WriteLine($"Loading dependencies assembly from: {depPath}..."); + Assembly.LoadFrom(depPath); + Console.WriteLine("Dependencies assembly loaded."); + } + + // Load all reference assemblies. + Console.WriteLine($"Loading all referenced assemblies."); + foreach (var asm in this.GetType().Assembly.GetReferencedAssemblies()) + { + try + { + Assembly.Load(asm); + } + catch (Exception e) + { + Console.WriteLine($"Failed to load {asm.FullName}"); + Console.WriteLine(e.Message); + } + } + sw.Stop(); + Console.WriteLine($"Time to load assemblies: {sw.Elapsed.TotalSeconds})"); + + if(this.store == null) + { + this.store = new S3ModelStore(RegionEndpoint.USWest1); + } + + var l = new InvocationWrapper(store, SketchGrids.Execute); + var output = await l.InvokeAsync(args); + return output; + } + } +} \ No newline at end of file diff --git a/Grids/SketchGrids/src/SketchGrids.cs b/Grids/SketchGrids/src/SketchGrids.cs new file mode 100644 index 00000000..68072366 --- /dev/null +++ b/Grids/SketchGrids/src/SketchGrids.cs @@ -0,0 +1,207 @@ +using Elements; +using Elements.Annotations; +using Elements.Geometry; +using Elements.Search; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace SketchGrids +{ + public static class SketchGrids + { + /// + /// The SketchGrids function. + /// + /// The input model. + /// The arguments to the execution. + /// A SketchGridsOutputs instance containing computed results and the model with any new elements. + public static SketchGridsOutputs Execute(Dictionary inputModels, SketchGridsInputs input) + { + var output = new SketchGridsOutputs(); + var edgeDisplaySettings = new EdgeDisplaySettings() + { + WidthMode = EdgeDisplayWidthMode.ScreenUnits, + LineWidth = 1, + // DashMode = EdgeDisplayDashMode.ScreenUnits, + // DashSize = 10, + // GapSize = 2 + }; + + var gridMaterial = new Material("Grid Line", Colors.Darkgray) + { + EdgeDisplaySettings = edgeDisplaySettings + }; + + var gridLines = input.Overrides.GridLines.CreateElements(input.Overrides.Additions.GridLines, input.Overrides.Removals.GridLines, (addition) => + { + var gridLine = new GridLine() + { + Curve = addition.Value.Curve, + Material = gridMaterial + }; + gridLine.AdditionalProperties["Creation Id"] = addition.Id; + return gridLine; + }, (gl, gli) => + { + return Guid.Parse((string)gl.AdditionalProperties["Creation Id"]) == gli.CreationId; + }, (gl, glo) => + { + gl.Curve = glo.Value.Curve; + return gl; + }); + + output.Model.AddElements(gridLines); + + if (inputModels.ContainsKey("Conceptual Mass")) + { + var conceptualMasses = inputModels["Conceptual Mass"].AllElementsOfType(); + + // Find the outer bounds of all the conceptual masses. + // This will be used to extend grids to cover the whole mass. + var hull = ConvexHull.FromPolylines(conceptualMasses.Select(m => m.Profile.Perimeter)); + var offsetHull = hull.Offset(2)[0]; + + // TODO: Create an input for structural offset + var allGridLines = new List(); + + var gridIndex = 0; + + foreach (var conceptualMass in conceptualMasses) + { + conceptualMass.UpdateRepresentations(); + conceptualMass.UpdateBoundsAndComputeSolid(); + + if (conceptualMass.Skeleton != null) + { + // Create grids for the skeleton + // foreach (var edge in conceptualMass.Skeleton) + // { + // CheckAndCreateGridline(edge, gridLines, ref gridIndex, gridMaterial); + // } + + var allPerimeters = new List(); + var allVoids = new List(); + var intersectionPlane = new Plane(new Vector3(0, 0, conceptualMass.Transform.Origin.Z), Vector3.ZAxis); + foreach (var so in conceptualMass.Representation.SolidOperations) + { + if (so.Solid.Intersects(intersectionPlane, out var result)) + { + if (so.IsVoid) + { + allVoids.AddRange(result); + } + else + { + allPerimeters.AddRange(result); + } + } + } + + // Offset perimeters to the inside. + foreach (var cutPerimeter in allPerimeters) + { + foreach (var segment in cutPerimeter.Offset(-input.OffsetDistanceFromConceptualMass)[0].Segments()) + { + var newGridLine = segment.ExtendTo(offsetHull); + CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial); + } + } + + // TODO: Are there ever holes in a skeleton mass? + // Offset holes to the outside. + // foreach (var cutVoid in allVoids) + // { + // foreach (var segment in cutVoid.Offset(-structuralOffset)[0].Segments()) + // { + // var newGridLine = segment.ExtendTo(offsetHull); + // CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial); + // } + // } + } + else + { + foreach (var segment in conceptualMass.Profile.Perimeter.Offset(-input.OffsetDistanceFromConceptualMass)[0].Segments()) + { + var newGridLine = segment.ExtendTo(offsetHull); + CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial); + } + + if (conceptualMass.Profile.Voids != null) + { + foreach (var profileVoid in conceptualMass.Profile.Voids) + { + foreach (var segment in profileVoid.Offset(input.OffsetDistanceFromConceptualMass)[0].Segments()) + { + var newGridLine = segment.ExtendTo(offsetHull); + CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial); + } + } + } + } + } + } + + output.Model.AddElements(gridLines); + + var network = Network.FromSegmentableItems(gridLines, (gl) => { return (Line)gl.Curve; }, out var allNodeLocations, out _); + + var r = new Random(); + + var closedRegions = network.FindAllClosedRegions(allNodeLocations); + foreach (var cr in closedRegions) + { + try + { + var p = new Panel(new Polygon(cr.Select(r => allNodeLocations[r]).ToList()), r.NextMaterial()); + output.Model.AddElement(p); + } + catch + { + continue; + } + } + + var bbox = new BBox3(allNodeLocations); + + var vectorEqualityComparer = new VectorEqualityComparer(); + var gridLineGroups = gridLines.GroupBy(gl => (gl.Curve as Line).Direction().Unitized(), vectorEqualityComparer); + var directionComparer = new DirectionComparer(bbox.Min); + + foreach (var gridLineGroup in gridLineGroups) + { + var grids = gridLineGroup.ToList(); + var orderedGrids = grids.OrderByDescending(gl => gl.Curve.PointAt(0), directionComparer).ToList(); + for (var i = 0; i < orderedGrids.Count - 1; i++) + { + var dim = new AlignedDimension(orderedGrids[i].Curve.PointAt(0), orderedGrids[i + 1].Curve.PointAt(0), 0); + output.Model.AddElement(dim); + // output.Model.AddElements(dim.ToModelArrowsAndText(Colors.Black)); + } + } + + return output; + } + + private static void CheckAndCreateGridline(Line newGridLine, List gridLines, ref int gridIndex, Material gridMaterial) + { + var directionReference = new Vector3(1, -1); + + if (gridLines.Any(gl => (gl.Curve as Line).IsAlmostEqualTo(newGridLine, false))) + { + return; + } + var d = newGridLine.Direction(); + var dot = directionReference.Dot(d); + + var gl = new GridLine() + { + Curve = dot >= 0 ? newGridLine : new Line(newGridLine.End, newGridLine.Start), + Name = gridIndex.ToString(), + Material = gridMaterial + }; + gridLines.Add(gl); + gridIndex++; + } + } +} diff --git a/Grids/SketchGrids/src/SketchGrids.csproj b/Grids/SketchGrids/src/SketchGrids.csproj new file mode 100644 index 00000000..f7b90840 --- /dev/null +++ b/Grids/SketchGrids/src/SketchGrids.csproj @@ -0,0 +1,11 @@ + + + + + + + + netcoreapp3.1 + + + diff --git a/Grids/SketchGrids/src/VectorEqualityComparer.cs b/Grids/SketchGrids/src/VectorEqualityComparer.cs new file mode 100644 index 00000000..9028988c --- /dev/null +++ b/Grids/SketchGrids/src/VectorEqualityComparer.cs @@ -0,0 +1,29 @@ +using Elements.Geometry; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace SketchGrids +{ + public class VectorEqualityComparer : IEqualityComparer + { + public bool Equals([AllowNull] Vector3 x, [AllowNull] Vector3 y) + { + return x.IsAlmostEqualTo(y); + } + + public int GetHashCode([DisallowNull] Vector3 obj) + { + // Stolen from the vector 3 class, but using + // less precision to enforce matches. + unchecked + { + int hash = 17; + hash = hash * 23 + Math.Round(obj.X, 5).GetHashCode(); + hash = hash * 23 + Math.Round(obj.Y, 5).GetHashCode(); + hash = hash * 23 + Math.Round(obj.Z, 5).GetHashCode(); + return hash; + } + } + } +} \ No newline at end of file diff --git a/Grids/SketchGrids/test/FunctionTest.g.cs b/Grids/SketchGrids/test/FunctionTest.g.cs new file mode 100644 index 00000000..de92b88c --- /dev/null +++ b/Grids/SketchGrids/test/FunctionTest.g.cs @@ -0,0 +1,24 @@ +// This code was generated by Hypar. +// Edits to this code will be overwritten the next time you run 'hypar init'. +// DO NOT EDIT THIS FILE. + +using Xunit; +using System.IO; +using System.Reflection; +using System.Threading.Tasks; +using Xunit.Abstractions; +using System; +using System.Collections.Generic; + +namespace SketchGrids.Tests +{ + public class FunctionTests + { + private readonly ITestOutputHelper output; + + public FunctionTests(ITestOutputHelper output) + { + this.output = output; + } + } +} \ No newline at end of file diff --git a/Grids/SketchGrids/test/SketchGrids.Tests.csproj b/Grids/SketchGrids/test/SketchGrids.Tests.csproj new file mode 100644 index 00000000..69bce0f4 --- /dev/null +++ b/Grids/SketchGrids/test/SketchGrids.Tests.csproj @@ -0,0 +1,20 @@ + + + + netcoreapp3.1 + + false + + + + + + + + + + + + + + From 64bd62b732c166dd1d037b68d97e9b2f26d70c3c Mon Sep 17 00:00:00 2001 From: Ian Keough Date: Tue, 20 Sep 2022 16:34:19 -0700 Subject: [PATCH 02/16] A little more docs. --- Grids/SketchGrids/hypar.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Grids/SketchGrids/hypar.json b/Grids/SketchGrids/hypar.json index 68e9e126..003c563b 100644 --- a/Grids/SketchGrids/hypar.json +++ b/Grids/SketchGrids/hypar.json @@ -2,7 +2,7 @@ "$schema": "https://hypar.io/Schemas/Function.json", "id": "7b53fd3e-d94a-4333-9127-045722dddbd8", "name": "Sketch Grids", - "description": "Sketch grid lines.", + "description": "Generate grids automatically from conceptual masses or sketch grid lines.", "language": "C#", "input_schema": { "type": "object", From 60e4c9e4fa578388504cd0f759ab621f4ca38e91 Mon Sep 17 00:00:00 2001 From: Ian Keough Date: Tue, 20 Sep 2022 19:40:05 -0700 Subject: [PATCH 03/16] More docs. Correct sort. --- Grids/SketchGrids/README.md | 2 +- Grids/SketchGrids/src/SketchGrids.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Grids/SketchGrids/README.md b/Grids/SketchGrids/README.md index 572e9553..83de62e0 100644 --- a/Grids/SketchGrids/README.md +++ b/Grids/SketchGrids/README.md @@ -2,7 +2,7 @@ # Sketch Grids -Sketch grid lines. +Generate grids automatically from conceptual masses or sketch grid lines. |Input Name|Type|Description| |---|---|---| diff --git a/Grids/SketchGrids/src/SketchGrids.cs b/Grids/SketchGrids/src/SketchGrids.cs index 68072366..f563b878 100644 --- a/Grids/SketchGrids/src/SketchGrids.cs +++ b/Grids/SketchGrids/src/SketchGrids.cs @@ -171,7 +171,7 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, foreach (var gridLineGroup in gridLineGroups) { var grids = gridLineGroup.ToList(); - var orderedGrids = grids.OrderByDescending(gl => gl.Curve.PointAt(0), directionComparer).ToList(); + var orderedGrids = grids.OrderBy(gl => gl.Curve.PointAt(0), directionComparer).ToList(); for (var i = 0; i < orderedGrids.Count - 1; i++) { var dim = new AlignedDimension(orderedGrids[i].Curve.PointAt(0), orderedGrids[i + 1].Curve.PointAt(0), 0); From 6f8c5980de94b59bc1c4cf8b4732624a3d58890e Mon Sep 17 00:00:00 2001 From: Ian Keough Date: Tue, 20 Sep 2022 21:49:03 -0700 Subject: [PATCH 04/16] Handling holes. --- Grids/SketchGrids/src/SketchGrids.cs | 81 +++++++++++++++++++--------- 1 file changed, 57 insertions(+), 24 deletions(-) diff --git a/Grids/SketchGrids/src/SketchGrids.cs b/Grids/SketchGrids/src/SketchGrids.cs index f563b878..4f9693f5 100644 --- a/Grids/SketchGrids/src/SketchGrids.cs +++ b/Grids/SketchGrids/src/SketchGrids.cs @@ -67,6 +67,8 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, var gridIndex = 0; + var allVoids = new List(); + foreach (var conceptualMass in conceptualMasses) { conceptualMass.UpdateRepresentations(); @@ -81,7 +83,6 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, // } var allPerimeters = new List(); - var allVoids = new List(); var intersectionPlane = new Plane(new Vector3(0, 0, conceptualMass.Transform.Origin.Z), Vector3.ZAxis); foreach (var so in conceptualMass.Representation.SolidOperations) { @@ -129,15 +130,47 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, if (conceptualMass.Profile.Voids != null) { - foreach (var profileVoid in conceptualMass.Profile.Voids) + allVoids.AddRange(conceptualMass.Profile.Voids); + } + } + } + + // We process the voids last so that we have all grids + // created from the faces of the conceptual masses to respond + // to. This will create the shortest spanning edge grids for holes. + foreach (var profileVoid in allVoids) + { + var holeGridLines = new List(); + foreach (var segment in profileVoid.Offset(input.OffsetDistanceFromConceptualMass)[0].Segments()) + { + var d = segment.Direction(); + var startRay = new Ray(segment.Start, d.Negate()); + var endRay = new Ray(segment.End, d); + var startX = new List(); + var endX = new List(); + foreach (var gridLine in gridLines) + { + if (startRay.Intersects(gridLine.Curve as Line, out Vector3 startResult)) { - foreach (var segment in profileVoid.Offset(input.OffsetDistanceFromConceptualMass)[0].Segments()) - { - var newGridLine = segment.ExtendTo(offsetHull); - CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial); - } + startX.Add(startResult); + } + if (endRay.Intersects(gridLine.Curve as Line, out Vector3 endResult)) + { + endX.Add(endResult); } } + startX.Sort(new DistanceComparer(segment.Start)); + endX.Sort(new DistanceComparer(segment.End)); + + var newGridLine = new Line(startX[0], endX[0]); + + // Add these to a separate collection so we don't test against them. + holeGridLines.Add(newGridLine); + } + + foreach (var holeGridLine in holeGridLines) + { + CheckAndCreateGridline(holeGridLine, gridLines, ref gridIndex, gridMaterial); } } } @@ -162,23 +195,23 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, } } - var bbox = new BBox3(allNodeLocations); - - var vectorEqualityComparer = new VectorEqualityComparer(); - var gridLineGroups = gridLines.GroupBy(gl => (gl.Curve as Line).Direction().Unitized(), vectorEqualityComparer); - var directionComparer = new DirectionComparer(bbox.Min); - - foreach (var gridLineGroup in gridLineGroups) - { - var grids = gridLineGroup.ToList(); - var orderedGrids = grids.OrderBy(gl => gl.Curve.PointAt(0), directionComparer).ToList(); - for (var i = 0; i < orderedGrids.Count - 1; i++) - { - var dim = new AlignedDimension(orderedGrids[i].Curve.PointAt(0), orderedGrids[i + 1].Curve.PointAt(0), 0); - output.Model.AddElement(dim); - // output.Model.AddElements(dim.ToModelArrowsAndText(Colors.Black)); - } - } + // var bbox = new BBox3(allNodeLocations); + + // var vectorEqualityComparer = new VectorEqualityComparer(); + // var gridLineGroups = gridLines.GroupBy(gl => (gl.Curve as Line).Direction().Unitized(), vectorEqualityComparer); + // var directionComparer = new DirectionComparer(bbox.Min); + + // foreach (var gridLineGroup in gridLineGroups) + // { + // var grids = gridLineGroup.ToList(); + // var orderedGrids = grids.OrderBy(gl => gl.Curve.PointAt(0), directionComparer).ToList(); + // for (var i = 0; i < orderedGrids.Count - 1; i++) + // { + // var dim = new AlignedDimension(orderedGrids[i].Curve.PointAt(0), orderedGrids[i + 1].Curve.PointAt(0), 0); + // output.Model.AddElement(dim); + // // output.Model.AddElements(dim.ToModelArrowsAndText(Colors.Black)); + // } + // } return output; } From 9d3975f197ee2f92e0d8c727ffaf4dc5f7ee9174 Mon Sep 17 00:00:00 2001 From: Ian Keough Date: Tue, 20 Sep 2022 22:17:25 -0700 Subject: [PATCH 05/16] Add skeleton grids. --- Grids/SketchGrids/README.md | 1 + .../SketchGrids/dependencies/SketchGridsInputs.g.cs | 9 +++++++-- Grids/SketchGrids/hypar.json | 5 +++++ Grids/SketchGrids/src/SketchGrids.cs | 12 ++++++++---- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/Grids/SketchGrids/README.md b/Grids/SketchGrids/README.md index 83de62e0..e0092113 100644 --- a/Grids/SketchGrids/README.md +++ b/Grids/SketchGrids/README.md @@ -7,6 +7,7 @@ Generate grids automatically from conceptual masses or sketch grid lines. |Input Name|Type|Description| |---|---|---| |Offset Distance From Conceptual Mass|number|The default grid offset from the conceptual mass.| +|Add Skeleton Grids|boolean|Add grids along conceptual mass skeletons.|
diff --git a/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs b/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs index 343dd5de..3a046184 100644 --- a/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs +++ b/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs @@ -29,16 +29,17 @@ public class SketchGridsInputs : S3Args { [Newtonsoft.Json.JsonConstructor] - public SketchGridsInputs(double @offsetDistanceFromConceptualMass, Overrides @overrides, string bucketName, string uploadsBucket, Dictionary modelInputKeys, string gltfKey, string elementsKey, string ifcKey): + public SketchGridsInputs(double @offsetDistanceFromConceptualMass, bool @addSkeletonGrids, Overrides @overrides, string bucketName, string uploadsBucket, Dictionary modelInputKeys, string gltfKey, string elementsKey, string ifcKey): base(bucketName, uploadsBucket, modelInputKeys, gltfKey, elementsKey, ifcKey) { var validator = Validator.Instance.GetFirstValidatorForType(); if(validator != null) { - validator.PreConstruct(new object[]{ @offsetDistanceFromConceptualMass, @overrides}); + validator.PreConstruct(new object[]{ @offsetDistanceFromConceptualMass, @addSkeletonGrids, @overrides}); } this.OffsetDistanceFromConceptualMass = @offsetDistanceFromConceptualMass; + this.AddSkeletonGrids = @addSkeletonGrids; this.Overrides = @overrides ?? this.Overrides; if(validator != null) @@ -51,6 +52,10 @@ public SketchGridsInputs(double @offsetDistanceFromConceptualMass, Overrides @ov [Newtonsoft.Json.JsonProperty("Offset Distance From Conceptual Mass", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public double OffsetDistanceFromConceptualMass { get; set; } = 1.5D; + /// Add grids along conceptual mass skeletons. + [Newtonsoft.Json.JsonProperty("Add Skeleton Grids", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public bool AddSkeletonGrids { get; set; } = false; + [Newtonsoft.Json.JsonProperty("overrides", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public Overrides Overrides { get; set; } = new Overrides(); diff --git a/Grids/SketchGrids/hypar.json b/Grids/SketchGrids/hypar.json index 003c563b..c2c5a988 100644 --- a/Grids/SketchGrids/hypar.json +++ b/Grids/SketchGrids/hypar.json @@ -12,6 +12,11 @@ "type": "number", "default": 1.5, "$hyparUnitType": "length" + }, + "Add Skeleton Grids": { + "description": "Add grids along conceptual mass skeletons.", + "type": "boolean", + "default": false } } }, diff --git a/Grids/SketchGrids/src/SketchGrids.cs b/Grids/SketchGrids/src/SketchGrids.cs index 4f9693f5..6f9fea85 100644 --- a/Grids/SketchGrids/src/SketchGrids.cs +++ b/Grids/SketchGrids/src/SketchGrids.cs @@ -77,10 +77,14 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, if (conceptualMass.Skeleton != null) { // Create grids for the skeleton - // foreach (var edge in conceptualMass.Skeleton) - // { - // CheckAndCreateGridline(edge, gridLines, ref gridIndex, gridMaterial); - // } + if (input.AddSkeletonGrids) + { + foreach (var edge in conceptualMass.Skeleton) + { + var newGridLine = edge.ExtendTo(hull); + CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial); + } + } var allPerimeters = new List(); var intersectionPlane = new Plane(new Vector3(0, 0, conceptualMass.Transform.Origin.Z), Vector3.ZAxis); From 793324f044e99cd71a1a324654ed9152788c93b9 Mon Sep 17 00:00:00 2001 From: Ian Keough Date: Mon, 10 Oct 2022 15:52:06 -0700 Subject: [PATCH 06/16] Use the profile to get the perimeters and holes. --- Grids/SketchGrids/src/Function.g.cs | 1 + Grids/SketchGrids/src/SketchGrids.cs | 21 ++++++--------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/Grids/SketchGrids/src/Function.g.cs b/Grids/SketchGrids/src/Function.g.cs index d293ff99..0ec28b62 100644 --- a/Grids/SketchGrids/src/Function.g.cs +++ b/Grids/SketchGrids/src/Function.g.cs @@ -48,6 +48,7 @@ public async Task Handler(SketchGridsInputs args, ILambdaCon { try { + Console.WriteLine($"Assembly Name: {asm.FullName}"); Assembly.Load(asm); } catch (Exception e) diff --git a/Grids/SketchGrids/src/SketchGrids.cs b/Grids/SketchGrids/src/SketchGrids.cs index 6f9fea85..687033a4 100644 --- a/Grids/SketchGrids/src/SketchGrids.cs +++ b/Grids/SketchGrids/src/SketchGrids.cs @@ -1,5 +1,4 @@ using Elements; -using Elements.Annotations; using Elements.Geometry; using Elements.Search; using System; @@ -23,9 +22,6 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, { WidthMode = EdgeDisplayWidthMode.ScreenUnits, LineWidth = 1, - // DashMode = EdgeDisplayDashMode.ScreenUnits, - // DashSize = 10, - // GapSize = 2 }; var gridMaterial = new Material("Grid Line", Colors.Darkgray) @@ -87,19 +83,13 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, } var allPerimeters = new List(); - var intersectionPlane = new Plane(new Vector3(0, 0, conceptualMass.Transform.Origin.Z), Vector3.ZAxis); - foreach (var so in conceptualMass.Representation.SolidOperations) + + if (conceptualMass.Profile != null && conceptualMass.Profile.Voids != null) { - if (so.Solid.Intersects(intersectionPlane, out var result)) + allPerimeters.Add(conceptualMass.Profile.Perimeter); + foreach (var profileVoid in conceptualMass.Profile.Voids) { - if (so.IsVoid) - { - allVoids.AddRange(result); - } - else - { - allPerimeters.AddRange(result); - } + allVoids.Add(profileVoid); } } @@ -199,6 +189,7 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, } } + // TODO: Draw some annotations. // var bbox = new BBox3(allNodeLocations); // var vectorEqualityComparer = new VectorEqualityComparer(); From 88558dccfe1531a056685a34d118cb7b55ed8c5c Mon Sep 17 00:00:00 2001 From: Ian Keough Date: Tue, 11 Oct 2022 14:45:00 -0700 Subject: [PATCH 07/16] Update libs and init. --- .../dependencies/Camera.g.cs | 15 ++++++------- .../dependencies/CameraNamedPosition.g.cs | 1 + .../dependencies/CameraProjection.g.cs | 1 + .../dependencies/Grid2dElement.g.cs | 21 ++++++++++++++----- .../dependencies/GridNode.g.cs | 11 +++++----- .../dependencies/LabelConfiguration.g.cs | 15 ++++++------- .../dependencies/LevelPerimeter.g.cs | 11 +++++----- .../dependencies/LevelVolume.g.cs | 13 ++++++------ .../Structure.Dependencies.csproj | 4 ++-- .../dependencies/StructureInputs.g.cs | 2 +- .../dependencies/StructureOutputs.g.cs | 2 +- .../dependencies/ViewScope.g.cs | 19 +++++++++-------- .../StructureByEnvelope/src/Function.g.cs | 1 + .../StructureByEnvelope/src/Structure.csproj | 5 ----- .../test/Structure.tests.csproj | 1 - 15 files changed, 68 insertions(+), 54 deletions(-) diff --git a/Structure/StructureByEnvelope/dependencies/Camera.g.cs b/Structure/StructureByEnvelope/dependencies/Camera.g.cs index f95bad53..aa5169b3 100644 --- a/Structure/StructureByEnvelope/dependencies/Camera.g.cs +++ b/Structure/StructureByEnvelope/dependencies/Camera.g.cs @@ -10,6 +10,7 @@ using Elements.Spatial; using Elements.Validators; using Elements.Serialization.JSON; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; @@ -21,11 +22,11 @@ namespace Elements #pragma warning disable // Disable all warnings /// Represents camera settings - [Newtonsoft.Json.JsonConverter(typeof(Elements.Serialization.JSON.JsonInheritanceConverter), "discriminator")] + [JsonConverter(typeof(Elements.Serialization.JSON.JsonInheritanceConverter), "discriminator")] [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] public partial class Camera { - [Newtonsoft.Json.JsonConstructor] + [JsonConstructor] public Camera(Vector3 @angle, CameraNamedPosition? @namedPosition, CameraProjection @projection) { this.Angle = @angle; @@ -39,17 +40,17 @@ public Camera() } /// A unit vector in model coordinates indicating which direction the camera is pointing. - [Newtonsoft.Json.JsonProperty("angle", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonProperty("angle", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public Vector3 Angle { get; set; } /// Camera positions, viewing from this direction to the opposite direction. Do not set angle if setting this. - [Newtonsoft.Json.JsonProperty("named_position", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] + [JsonProperty("named_position", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] public CameraNamedPosition? NamedPosition { get; set; } /// How the camera collapses the 3d scene into a 2d image - [Newtonsoft.Json.JsonProperty("projection", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] + [JsonProperty("projection", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] public CameraProjection Projection { get; set; } diff --git a/Structure/StructureByEnvelope/dependencies/CameraNamedPosition.g.cs b/Structure/StructureByEnvelope/dependencies/CameraNamedPosition.g.cs index 1cb678d4..3fab89a1 100644 --- a/Structure/StructureByEnvelope/dependencies/CameraNamedPosition.g.cs +++ b/Structure/StructureByEnvelope/dependencies/CameraNamedPosition.g.cs @@ -10,6 +10,7 @@ using Elements.Spatial; using Elements.Validators; using Elements.Serialization.JSON; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; diff --git a/Structure/StructureByEnvelope/dependencies/CameraProjection.g.cs b/Structure/StructureByEnvelope/dependencies/CameraProjection.g.cs index 0e49a5a8..ce95880c 100644 --- a/Structure/StructureByEnvelope/dependencies/CameraProjection.g.cs +++ b/Structure/StructureByEnvelope/dependencies/CameraProjection.g.cs @@ -10,6 +10,7 @@ using Elements.Spatial; using Elements.Validators; using Elements.Serialization.JSON; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; diff --git a/Structure/StructureByEnvelope/dependencies/Grid2dElement.g.cs b/Structure/StructureByEnvelope/dependencies/Grid2dElement.g.cs index e1cb04bf..45e65f74 100644 --- a/Structure/StructureByEnvelope/dependencies/Grid2dElement.g.cs +++ b/Structure/StructureByEnvelope/dependencies/Grid2dElement.g.cs @@ -10,6 +10,7 @@ using Elements.Spatial; using Elements.Validators; using Elements.Serialization.JSON; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; @@ -21,16 +22,18 @@ namespace Elements #pragma warning disable // Disable all warnings /// An element wrapper for Grid2d - [Newtonsoft.Json.JsonConverter(typeof(Elements.Serialization.JSON.JsonInheritanceConverter), "discriminator")] + [JsonConverter(typeof(Elements.Serialization.JSON.JsonInheritanceConverter), "discriminator")] [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] public partial class Grid2dElement : GeometricElement { - [Newtonsoft.Json.JsonConstructor] - public Grid2dElement(Grid2d @grid, IList @gridNodes, Transform @transform = null, Material @material = null, Representation @representation = null, bool @isElementDefinition = false, System.Guid @id = default, string @name = null) + [JsonConstructor] + public Grid2dElement(Grid2d @grid, IList @gridNodes, IList @uGridLines, IList @vGridLines, Transform @transform = null, Material @material = null, Representation @representation = null, bool @isElementDefinition = false, System.Guid @id = default, string @name = null) : base(transform, material, representation, isElementDefinition, id, name) { this.Grid = @grid; this.GridNodes = @gridNodes; + this.UGridLines = @uGridLines; + this.VGridLines = @vGridLines; } // Empty constructor @@ -40,13 +43,21 @@ public Grid2dElement() } /// Contains a Grid2d in absolute space (is not intended to be modified by the transform) - [Newtonsoft.Json.JsonProperty("Grid", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonProperty("Grid", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public Grid2d Grid { get; set; } /// A list of grid intersections that fall within the grid boundaries, in absolute space (is not intended to be modified by the transform) - [Newtonsoft.Json.JsonProperty("GridNodes", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonProperty("GridNodes", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public IList GridNodes { get; set; } + /// List of U GridLine Element IDs + [JsonProperty("U GridLines", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public IList UGridLines { get; set; } + + /// List ofV GridLine Element IDs + [JsonProperty("V GridLines", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public IList VGridLines { get; set; } + } } \ No newline at end of file diff --git a/Structure/StructureByEnvelope/dependencies/GridNode.g.cs b/Structure/StructureByEnvelope/dependencies/GridNode.g.cs index 41f67dce..ff9ac94a 100644 --- a/Structure/StructureByEnvelope/dependencies/GridNode.g.cs +++ b/Structure/StructureByEnvelope/dependencies/GridNode.g.cs @@ -10,6 +10,7 @@ using Elements.Spatial; using Elements.Validators; using Elements.Serialization.JSON; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; @@ -21,11 +22,11 @@ namespace Elements #pragma warning disable // Disable all warnings /// Represents a point at the intersection of two gridlines - [Newtonsoft.Json.JsonConverter(typeof(Elements.Serialization.JSON.JsonInheritanceConverter), "discriminator")] + [JsonConverter(typeof(Elements.Serialization.JSON.JsonInheritanceConverter), "discriminator")] [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] public partial class GridNode : Element { - [Newtonsoft.Json.JsonConstructor] + [JsonConstructor] public GridNode(Transform @location, string @uGridline, string @vGridline, System.Guid @id = default, string @name = null) : base(id, name) { @@ -41,13 +42,13 @@ public GridNode() } /// The location of this grid node. - [Newtonsoft.Json.JsonProperty("Location", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonProperty("Location", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public Transform Location { get; set; } - [Newtonsoft.Json.JsonProperty("U Gridline", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonProperty("U Gridline", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public string UGridline { get; set; } - [Newtonsoft.Json.JsonProperty("V Gridline", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonProperty("V Gridline", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public string VGridline { get; set; } diff --git a/Structure/StructureByEnvelope/dependencies/LabelConfiguration.g.cs b/Structure/StructureByEnvelope/dependencies/LabelConfiguration.g.cs index 23b38c4d..3fe32d66 100644 --- a/Structure/StructureByEnvelope/dependencies/LabelConfiguration.g.cs +++ b/Structure/StructureByEnvelope/dependencies/LabelConfiguration.g.cs @@ -10,6 +10,7 @@ using Elements.Spatial; using Elements.Validators; using Elements.Serialization.JSON; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; @@ -21,11 +22,11 @@ namespace Elements #pragma warning disable // Disable all warnings /// Adjust the settings for labels attached to an object by adding a LabelConfiguration property. - [Newtonsoft.Json.JsonConverter(typeof(Elements.Serialization.JSON.JsonInheritanceConverter), "discriminator")] + [JsonConverter(typeof(Elements.Serialization.JSON.JsonInheritanceConverter), "discriminator")] [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] public partial class LabelConfiguration { - [Newtonsoft.Json.JsonConstructor] + [JsonConstructor] public LabelConfiguration(Color @color, Vector3 @offset, string @customText, string @forceVisible, Vector3 @direction) { this.Color = @color; @@ -41,23 +42,23 @@ public LabelConfiguration() } /// The label background color - [Newtonsoft.Json.JsonProperty("Color", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonProperty("Color", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public Color Color { get; set; } /// A screen-space offset, in pixels, for the label from the object's bounding box center. - [Newtonsoft.Json.JsonProperty("Offset", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonProperty("Offset", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public Vector3 Offset { get; set; } /// A custom format string for the label contents. This will override the selection of any specific Label property. - [Newtonsoft.Json.JsonProperty("Custom Text", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonProperty("Custom Text", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public string CustomText { get; set; } /// If this value is set, then the label will always be visible, regardless of the function's label settings. The content of this property should be the name of the object property you want to render. Specify "Custom" to use the template defined in Custom Text. - [Newtonsoft.Json.JsonProperty("Force Visible", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonProperty("Force Visible", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public string ForceVisible { get; set; } /// The label's world-space orientation which will be projected to screen space. - [Newtonsoft.Json.JsonProperty("Direction", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonProperty("Direction", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public Vector3 Direction { get; set; } diff --git a/Structure/StructureByEnvelope/dependencies/LevelPerimeter.g.cs b/Structure/StructureByEnvelope/dependencies/LevelPerimeter.g.cs index d37b6e3c..5faf6d92 100644 --- a/Structure/StructureByEnvelope/dependencies/LevelPerimeter.g.cs +++ b/Structure/StructureByEnvelope/dependencies/LevelPerimeter.g.cs @@ -10,6 +10,7 @@ using Elements.Spatial; using Elements.Validators; using Elements.Serialization.JSON; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; @@ -21,11 +22,11 @@ namespace Elements #pragma warning disable // Disable all warnings /// A horizontal planer datum with a perimeter. - [Newtonsoft.Json.JsonConverter(typeof(Elements.Serialization.JSON.JsonInheritanceConverter), "discriminator")] + [JsonConverter(typeof(Elements.Serialization.JSON.JsonInheritanceConverter), "discriminator")] [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] public partial class LevelPerimeter : Element { - [Newtonsoft.Json.JsonConstructor] + [JsonConstructor] public LevelPerimeter(double @area, double @elevation, Polygon @perimeter, System.Guid @id = default, string @name = null) : base(id, name) { @@ -41,17 +42,17 @@ public LevelPerimeter() } /// The area of the level perimeter. - [Newtonsoft.Json.JsonProperty("Area", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonProperty("Area", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] [System.ComponentModel.DataAnnotations.Range(0D, double.MaxValue)] public double Area { get; set; } /// The elevation of the level perimeter. - [Newtonsoft.Json.JsonProperty("Elevation", Required = Newtonsoft.Json.Required.Always)] + [JsonProperty("Elevation", Required = Newtonsoft.Json.Required.Always)] [System.ComponentModel.DataAnnotations.Range(0D, double.MaxValue)] public double Elevation { get; set; } /// The perimeter of the level perimeter. - [Newtonsoft.Json.JsonProperty("Perimeter", Required = Newtonsoft.Json.Required.AllowNull)] + [JsonProperty("Perimeter", Required = Newtonsoft.Json.Required.AllowNull)] public Polygon Perimeter { get; set; } diff --git a/Structure/StructureByEnvelope/dependencies/LevelVolume.g.cs b/Structure/StructureByEnvelope/dependencies/LevelVolume.g.cs index 9692a50c..09bff563 100644 --- a/Structure/StructureByEnvelope/dependencies/LevelVolume.g.cs +++ b/Structure/StructureByEnvelope/dependencies/LevelVolume.g.cs @@ -10,6 +10,7 @@ using Elements.Spatial; using Elements.Validators; using Elements.Serialization.JSON; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; @@ -21,11 +22,11 @@ namespace Elements #pragma warning disable // Disable all warnings /// Describes the volume of occupiable space between a level and the next level above it. - [Newtonsoft.Json.JsonConverter(typeof(Elements.Serialization.JSON.JsonInheritanceConverter), "discriminator")] + [JsonConverter(typeof(Elements.Serialization.JSON.JsonInheritanceConverter), "discriminator")] [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] public partial class LevelVolume : GeometricElement { - [Newtonsoft.Json.JsonConstructor] + [JsonConstructor] public LevelVolume(Profile @profile, double @height, double @area, string @buildingName, Transform @transform = null, Material @material = null, Representation @representation = null, bool @isElementDefinition = false, System.Guid @id = default, string @name = null) : base(transform, material, representation, isElementDefinition, id, name) { @@ -42,19 +43,19 @@ public LevelVolume() } /// The profile of the level Volume - [Newtonsoft.Json.JsonProperty("Profile", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonProperty("Profile", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public Profile Profile { get; set; } /// The floor-to-floor height of this level - [Newtonsoft.Json.JsonProperty("Height", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonProperty("Height", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public double Height { get; set; } /// The area of the level's profile. - [Newtonsoft.Json.JsonProperty("Area", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonProperty("Area", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public double Area { get; set; } /// The name of the building or mass this level belongs to (optional) - [Newtonsoft.Json.JsonProperty("Building Name", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonProperty("Building Name", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public string BuildingName { get; set; } diff --git a/Structure/StructureByEnvelope/dependencies/Structure.Dependencies.csproj b/Structure/StructureByEnvelope/dependencies/Structure.Dependencies.csproj index 172e2496..0a669598 100644 --- a/Structure/StructureByEnvelope/dependencies/Structure.Dependencies.csproj +++ b/Structure/StructureByEnvelope/dependencies/Structure.Dependencies.csproj @@ -5,8 +5,8 @@ - - + + diff --git a/Structure/StructureByEnvelope/dependencies/StructureInputs.g.cs b/Structure/StructureByEnvelope/dependencies/StructureInputs.g.cs index ad73b4ff..343f7394 100644 --- a/Structure/StructureByEnvelope/dependencies/StructureInputs.g.cs +++ b/Structure/StructureByEnvelope/dependencies/StructureInputs.g.cs @@ -11,6 +11,7 @@ using Hypar.Functions; using Hypar.Functions.Execution; using Hypar.Functions.Execution.AWS; +using Hypar.Model; using System; using System.Collections.Generic; using System.Linq; @@ -116,7 +117,6 @@ public StructureInputs(double @gridXAxisInterval, double @gridYAxisInterval, dou [Newtonsoft.Json.JsonProperty("Maximum Neighbor Span", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public double MaximumNeighborSpan { get; set; } = 2D; - } [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] diff --git a/Structure/StructureByEnvelope/dependencies/StructureOutputs.g.cs b/Structure/StructureByEnvelope/dependencies/StructureOutputs.g.cs index 66b7a755..8f0ac873 100644 --- a/Structure/StructureByEnvelope/dependencies/StructureOutputs.g.cs +++ b/Structure/StructureByEnvelope/dependencies/StructureOutputs.g.cs @@ -14,7 +14,7 @@ namespace Structure { - public class StructureOutputs: ResultsBase + public class StructureOutputs: SystemResults { /// /// The maximum beam length. diff --git a/Structure/StructureByEnvelope/dependencies/ViewScope.g.cs b/Structure/StructureByEnvelope/dependencies/ViewScope.g.cs index 21abe991..375469f3 100644 --- a/Structure/StructureByEnvelope/dependencies/ViewScope.g.cs +++ b/Structure/StructureByEnvelope/dependencies/ViewScope.g.cs @@ -10,6 +10,7 @@ using Elements.Spatial; using Elements.Validators; using Elements.Serialization.JSON; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; @@ -21,17 +22,17 @@ namespace Elements #pragma warning disable // Disable all warnings /// Represents a preset view attached to an element. - [Newtonsoft.Json.JsonConverter(typeof(Elements.Serialization.JSON.JsonInheritanceConverter), "discriminator")] + [JsonConverter(typeof(Elements.Serialization.JSON.JsonInheritanceConverter), "discriminator")] [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] public partial class ViewScope : Element { - [Newtonsoft.Json.JsonConstructor] - public ViewScope(BBox3 @boundingBox, Camera @camera, bool @inclusive, System.Guid @id = default, string @name = null) + [JsonConstructor] + public ViewScope(BBox3 @boundingBox, Camera @camera, bool? @lockRotation, System.Guid @id = default, string @name = null) : base(id, name) { this.BoundingBox = @boundingBox; this.Camera = @camera; - this.Inclusive = @inclusive; + this.LockRotation = @lockRotation; } // Empty constructor @@ -41,16 +42,16 @@ public ViewScope() } /// The "focus" extent for this view. - [Newtonsoft.Json.JsonProperty("Bounding Box", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonProperty("Bounding Box", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public BBox3 BoundingBox { get; set; } /// The camera to use for this view. - [Newtonsoft.Json.JsonProperty("Camera", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [JsonProperty("Camera", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public Camera Camera { get; set; } - /// Should the bounding box be treated as Inclusive? - [Newtonsoft.Json.JsonProperty("Inclusive", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public bool Inclusive { get; set; } + /// Whether this scope should lock view rotation. True to lock, False to unlock, and null to leave unchanged. + [JsonProperty("Lock Rotation", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public bool? LockRotation { get; set; } } diff --git a/Structure/StructureByEnvelope/src/Function.g.cs b/Structure/StructureByEnvelope/src/Function.g.cs index 1b2f528a..ff0fee88 100644 --- a/Structure/StructureByEnvelope/src/Function.g.cs +++ b/Structure/StructureByEnvelope/src/Function.g.cs @@ -48,6 +48,7 @@ public async Task Handler(StructureInputs args, ILambdaContext { try { + Console.WriteLine($"Assembly Name: {asm.FullName}"); Assembly.Load(asm); } catch (Exception e) diff --git a/Structure/StructureByEnvelope/src/Structure.csproj b/Structure/StructureByEnvelope/src/Structure.csproj index d1f9471c..c7fc4321 100644 --- a/Structure/StructureByEnvelope/src/Structure.csproj +++ b/Structure/StructureByEnvelope/src/Structure.csproj @@ -3,11 +3,6 @@ - - - - - netcoreapp3.1 diff --git a/Structure/StructureByEnvelope/test/Structure.tests.csproj b/Structure/StructureByEnvelope/test/Structure.tests.csproj index 928fe03b..a1b3f5a9 100644 --- a/Structure/StructureByEnvelope/test/Structure.tests.csproj +++ b/Structure/StructureByEnvelope/test/Structure.tests.csproj @@ -10,7 +10,6 @@ - From c4cecedbc1107841f59be7635c81f8c2c6b7b813 Mon Sep 17 00:00:00 2001 From: Ian Keough Date: Wed, 23 Nov 2022 19:37:48 -0800 Subject: [PATCH 08/16] Progress --- Grids/SketchGrids/src/SketchGrids.cs | 64 +++++----- .../StructureByEnvelope/src/Structure.cs | 120 ++++++++++-------- 2 files changed, 98 insertions(+), 86 deletions(-) diff --git a/Grids/SketchGrids/src/SketchGrids.cs b/Grids/SketchGrids/src/SketchGrids.cs index 687033a4..9df1ed9d 100644 --- a/Grids/SketchGrids/src/SketchGrids.cs +++ b/Grids/SketchGrids/src/SketchGrids.cs @@ -55,18 +55,17 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, // Find the outer bounds of all the conceptual masses. // This will be used to extend grids to cover the whole mass. - var hull = ConvexHull.FromPolylines(conceptualMasses.Select(m => m.Profile.Perimeter)); - var offsetHull = hull.Offset(2)[0]; + // var hull = ConvexHull.FromPolylines(conceptualMasses.Select(m => m.Profile.Perimeter)); + // var offsetHull = hull.Offset(2)[0]; // TODO: Create an input for structural offset - var allGridLines = new List(); - var gridIndex = 0; - var allVoids = new List(); foreach (var conceptualMass in conceptualMasses) { + var offsetHull = conceptualMass.Profile.Perimeter.Offset(1)[0]; + conceptualMass.UpdateRepresentations(); conceptualMass.UpdateBoundsAndComputeSolid(); @@ -77,7 +76,7 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, { foreach (var edge in conceptualMass.Skeleton) { - var newGridLine = edge.ExtendTo(hull); + var newGridLine = edge.ExtendTo(offsetHull); CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial); } } @@ -135,31 +134,36 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, foreach (var profileVoid in allVoids) { var holeGridLines = new List(); - foreach (var segment in profileVoid.Offset(input.OffsetDistanceFromConceptualMass)[0].Segments()) + var offsetHull = profileVoid.Offset(1)[0]; + // foreach (var segment in profileVoid.Offset(input.OffsetDistanceFromConceptualMass)[0].Segments()) + // { + // var d = segment.Direction(); + // var startRay = new Ray(segment.Start, d.Negate()); + // var endRay = new Ray(segment.End, d); + // var startX = new List(); + // var endX = new List(); + // foreach (var gridLine in gridLines) + // { + // if (startRay.Intersects(gridLine.Curve as Line, out Vector3 startResult)) + // { + // startX.Add(startResult); + // } + // if (endRay.Intersects(gridLine.Curve as Line, out Vector3 endResult)) + // { + // endX.Add(endResult); + // } + // } + // startX.Sort(new DistanceComparer(segment.Start)); + // endX.Sort(new DistanceComparer(segment.End)); + + // var newGridLine = new Line(startX[0], endX[0]); + + // // Add these to a separate collection so we don't test against them. + // holeGridLines.Add(newGridLine); + // } + foreach (var segment in offsetHull.Segments()) { - var d = segment.Direction(); - var startRay = new Ray(segment.Start, d.Negate()); - var endRay = new Ray(segment.End, d); - var startX = new List(); - var endX = new List(); - foreach (var gridLine in gridLines) - { - if (startRay.Intersects(gridLine.Curve as Line, out Vector3 startResult)) - { - startX.Add(startResult); - } - if (endRay.Intersects(gridLine.Curve as Line, out Vector3 endResult)) - { - endX.Add(endResult); - } - } - startX.Sort(new DistanceComparer(segment.Start)); - endX.Sort(new DistanceComparer(segment.End)); - - var newGridLine = new Line(startX[0], endX[0]); - - // Add these to a separate collection so we don't test against them. - holeGridLines.Add(newGridLine); + holeGridLines.Add(segment); } foreach (var holeGridLine in holeGridLines) diff --git a/Structure/StructureByEnvelope/src/Structure.cs b/Structure/StructureByEnvelope/src/Structure.cs index 6af9d026..342f7065 100644 --- a/Structure/StructureByEnvelope/src/Structure.cs +++ b/Structure/StructureByEnvelope/src/Structure.cs @@ -10,6 +10,7 @@ using Elements.Spatial.CellComplex; using System.Diagnostics; using System.IO; +using Elements.Search; namespace Structure { @@ -287,7 +288,7 @@ public static StructureOutputs Execute(Dictionary models, Structu Column columnDefinition; if (!columnDefintions.ContainsKey((memberLength, columnProfile))) { - columnDefinition = new Column(Vector3.Origin, memberLength, columnProfile, structureMaterial, name: columnProfile.Name) + columnDefinition = new Column(Vector3.Origin, memberLength, null, columnProfile, null, structureMaterial, name: columnProfile.Name) { IsElementDefinition = true }; @@ -434,7 +435,18 @@ public static StructureOutputs Execute(Dictionary models, Structu var length = longestCellEdge.Length(); var remainder = length % input.BeamSpacing; - var beamGrid = new Grid1d(longestCellEdge); + var cellPts = new List(); + foreach (var cellPt in cell.GetEdges().Select(e => cellComplex.GetVertex(e.StartVertexId).Value)) + { + cellPts.Add(cellPt.ClosestPointOn(longestCellEdge, true)); + } + + // We've got all the cell points projected to the line, but we + // want to find the maximum spanning line, so we sort by distance + // relative to a point far away from the start of the line. + cellPts.Sort(new DistanceComparer(longestCellEdge.Start - d * 10000)); + + var beamGrid = new Grid1d(new Line(cellPts.First(), cellPts.Last())); beamGrid.DivideByApproximateLength(input.BeamSpacing, EvenDivisionMode.RoundDown); var cellSeparators = beamGrid.GetCellSeparators(); @@ -446,73 +458,67 @@ public static StructureOutputs Execute(Dictionary models, Structu continue; } + // Project a line across the polygon and trim it + // with the polygon. var pt = cellSeparators[i]; var t = new Transform(pt, d, Vector3.ZAxis); - var r = new Ray(t.Origin, t.YAxis); - foreach (var s in segments) + var testLine = new Line(t.Origin, t.Origin + t.YAxis * 10000); + var trimmedLines = testLine.Trim(p, out _, true); + + foreach (var l in trimmedLines) { - if (s == longestCellEdge) + var beamLength = l.Length(); + if (beamLength < 1) { continue; } - if (r.Intersects(s, out Vector3 xsect)) + GeometricElement beamDefinition; + if (beamProfile != null) { - if (t.Origin.DistanceTo(xsect) < 1) - { - continue; - } - - var l = new Line(t.Origin, xsect); - var beamLength = l.Length(); - - GeometricElement beamDefinition; - if (beamProfile != null) - { - FindOrCreateStructuralFramingDefinition(beamLength, beamProfile, structureMaterial, beamDefinitions, model, out beamDefinition); - } - else + FindOrCreateStructuralFramingDefinition(beamLength, beamProfile, structureMaterial, beamDefinitions, model, out beamDefinition); + } + else + { + // Create a joist + if (!beamJoistDefinitions.ContainsKey((beamLength, beamProfileDepth))) { - // Create a joist - if (!beamJoistDefinitions.ContainsKey((beamLength, beamProfileDepth))) - { - // Beam definitions are defined along the X axis - var cl = new Line(Vector3.Origin, new Vector3(beamLength, 0)); - // if (beamLength < beamProfileDepth) - // { - // continue; - // } - - var cellCount = (int)Math.Ceiling((beamLength - Units.InchesToMeters(24)) / beamProfileDepth); - beamDefinition = new Joist(cl, L3, L3, L2, beamProfileDepth, cellCount, Units.InchesToMeters(2.5), Units.InchesToMeters(12), structureMaterial) - { - IsElementDefinition = true - }; - beamDefinition.Representation.SkipCSGUnion = true; - beamJoistDefinitions.Add((beamLength, beamProfileDepth), beamDefinition); - model.AddElement(beamDefinition, false); - } - else + // Beam definitions are defined along the X axis + var cl = new Line(Vector3.Origin, new Vector3(beamLength, 0)); + // if (beamLength < beamProfileDepth) + // { + // continue; + // } + + var cellCount = (int)Math.Ceiling((beamLength - Units.InchesToMeters(24)) / beamProfileDepth); + beamDefinition = new Joist(cl, L3, L3, L2, beamProfileDepth, cellCount, Units.InchesToMeters(2.5), Units.InchesToMeters(12), structureMaterial) { - beamDefinition = beamJoistDefinitions[(beamLength, beamProfileDepth)]; - } + IsElementDefinition = true + }; + beamDefinition.Representation.SkipCSGUnion = true; + beamJoistDefinitions.Add((beamLength, beamProfileDepth), beamDefinition); + model.AddElement(beamDefinition, false); } - var beamDir = l.Direction(); - var instanceTransform = new Transform(l.Start, beamDir, Vector3.ZAxis); - var beamInstance = beamDefinition.CreateInstance(instanceTransform, $"{beamDefinition.Name}"); - beamInstance.AdditionalProperties.Add(CELL_ID_PROPERTY_NAME, cell.Id); - model.AddElement(beamInstance, false); - var planDirection = beamDir.IsAlmostEqualTo(Vector3.ZAxis) ? Vector3.XAxis : beamDir.Project(xy).Unitized(); - beamInstance.AdditionalProperties.Add("LabelConfiguration", new LabelConfiguration(new Color(1, 1, 1, 0), Vector3.Origin, null, null, planDirection)); - if (beamDefinition is Beam beam) - { - model.AddElement(new ModelCurve(beam.Curve.Transformed(instanceTransform), BuiltInMaterials.ZAxis), false); - } - else if (beamDefinition is Joist joist) + else { - model.AddElement(new ModelCurve(joist.Curve.Transformed(instanceTransform), BuiltInMaterials.ZAxis), false); + beamDefinition = beamJoistDefinitions[(beamLength, beamProfileDepth)]; } } + var beamDir = l.Direction(); + var instanceTransform = new Transform(l.Start, beamDir, Vector3.ZAxis); + var beamInstance = beamDefinition.CreateInstance(instanceTransform, $"{beamDefinition.Name}"); + beamInstance.AdditionalProperties.Add(CELL_ID_PROPERTY_NAME, cell.Id); + model.AddElement(beamInstance, false); + var planDirection = beamDir.IsAlmostEqualTo(Vector3.ZAxis) ? Vector3.XAxis : beamDir.Project(xy).Unitized(); + beamInstance.AdditionalProperties.Add("LabelConfiguration", new LabelConfiguration(new Color(1, 1, 1, 0), Vector3.Origin, null, null, planDirection)); + if (beamDefinition is Beam beam) + { + model.AddElement(new ModelCurve(beam.Curve.Transformed(instanceTransform), BuiltInMaterials.ZAxis), false); + } + else if (beamDefinition is Joist joist) + { + model.AddElement(new ModelCurve(joist.Curve.Transformed(instanceTransform), BuiltInMaterials.ZAxis), false); + } } } } @@ -530,8 +536,10 @@ public static StructureOutputs Execute(Dictionary models, Structu Warnings = warnings }; return output; + } + private static void FindOrCreateStructuralFramingDefinition(double memberLength, Profile framingProfile, Material material, @@ -543,7 +551,7 @@ private static void FindOrCreateStructuralFramingDefinition(double memberLength, { // Beam definitions are defined along the X axis var cl = new Line(Vector3.Origin, new Vector3(memberLength, 0)); - structuralFramingDefinition = new Beam(cl, framingProfile, material, name: framingProfile.Name) + structuralFramingDefinition = new Beam(cl, framingProfile, null, material, name: framingProfile.Name) { IsElementDefinition = true }; From 0d2e3426aaac3e2112056c1538cf15a90848dd19 Mon Sep 17 00:00:00 2001 From: Ian Keough Date: Tue, 28 Nov 2023 15:56:32 -0800 Subject: [PATCH 09/16] Update and init. --- Grids/SketchGrids/README.md | 4 +++ .../dependencies/ConceptualMass.g.cs | 5 ++-- Grids/SketchGrids/dependencies/Envelope.g.cs | 5 ++-- .../dependencies/GridLinesOverride.g.cs | 5 ++-- .../SketchGrids.Dependencies.csproj | 16 +++++------- .../dependencies/SketchGridsInputs.g.cs | 26 +++++++++---------- .../dependencies/SketchGridsOutputs.g.cs | 3 --- Grids/SketchGrids/hypar.json | 2 +- Grids/SketchGrids/src/Function.g.cs | 10 +++---- Grids/SketchGrids/src/SketchGrids.csproj | 8 +++--- .../SketchGrids/test/SketchGrids.Tests.csproj | 10 +++---- 11 files changed, 45 insertions(+), 49 deletions(-) diff --git a/Grids/SketchGrids/README.md b/Grids/SketchGrids/README.md index e0092113..4338cc1f 100644 --- a/Grids/SketchGrids/README.md +++ b/Grids/SketchGrids/README.md @@ -15,3 +15,7 @@ Generate grids automatically from conceptual masses or sketch grid lines. |Output Name|Type|Description| |---|---|---| + +
+ +## Additional Information \ No newline at end of file diff --git a/Grids/SketchGrids/dependencies/ConceptualMass.g.cs b/Grids/SketchGrids/dependencies/ConceptualMass.g.cs index 4f20ef1d..fa933a87 100644 --- a/Grids/SketchGrids/dependencies/ConceptualMass.g.cs +++ b/Grids/SketchGrids/dependencies/ConceptualMass.g.cs @@ -1,6 +1,6 @@ //---------------------- // -// Generated using the NJsonSchema v10.1.21.0 (Newtonsoft.Json v12.0.0.0) (http://NJsonSchema.org) +// Generated using the NJsonSchema v10.1.21.0 (Newtonsoft.Json v13.0.0.0) (http://NJsonSchema.org) // //---------------------- using Elements; @@ -23,7 +23,7 @@ namespace Elements /// Represents an early stage building massing volume. Its boundary typically represents the nominal edge of slab, and may be articulated further by subsequent functions. [JsonConverter(typeof(Elements.Serialization.JSON.JsonInheritanceConverter), "discriminator")] - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v13.0.0.0)")] public partial class ConceptualMass : Envelope { [JsonConstructor] @@ -37,6 +37,7 @@ public ConceptualMass(IList @skeleton, string @primaryUseCategory, System. this.LocalCoordinateSystem = @localCoordinateSystem; } + // Empty constructor public ConceptualMass() : base() diff --git a/Grids/SketchGrids/dependencies/Envelope.g.cs b/Grids/SketchGrids/dependencies/Envelope.g.cs index c2546d41..a5a575de 100644 --- a/Grids/SketchGrids/dependencies/Envelope.g.cs +++ b/Grids/SketchGrids/dependencies/Envelope.g.cs @@ -1,6 +1,6 @@ //---------------------- // -// Generated using the NJsonSchema v10.1.21.0 (Newtonsoft.Json v12.0.0.0) (http://NJsonSchema.org) +// Generated using the NJsonSchema v10.1.21.0 (Newtonsoft.Json v13.0.0.0) (http://NJsonSchema.org) // //---------------------- using Elements; @@ -23,7 +23,7 @@ namespace Elements /// Represents one part of a building enclosure. [JsonConverter(typeof(Elements.Serialization.JSON.JsonInheritanceConverter), "discriminator")] - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v13.0.0.0)")] public partial class Envelope : GeometricElement { [JsonConstructor] @@ -38,6 +38,7 @@ public Envelope(Profile @profile, double @elevation, double @height, Vector3 @di this.FloorToFloorHeights = @floorToFloorHeights; } + // Empty constructor public Envelope() : base() diff --git a/Grids/SketchGrids/dependencies/GridLinesOverride.g.cs b/Grids/SketchGrids/dependencies/GridLinesOverride.g.cs index 02d341fc..2a8fa601 100644 --- a/Grids/SketchGrids/dependencies/GridLinesOverride.g.cs +++ b/Grids/SketchGrids/dependencies/GridLinesOverride.g.cs @@ -138,8 +138,9 @@ public static List CreateElements( if (elementToEdit != null) { resultElements.Remove(elementToEdit); - resultElements.Add(modifyElement(elementToEdit, editedElement)); - Identity.AddOverrideIdentity(elementToEdit, editedElement); + var newElement = modifyElement(elementToEdit, editedElement); + resultElements.Add(newElement); + Identity.AddOverrideIdentity(newElement, editedElement); } } } diff --git a/Grids/SketchGrids/dependencies/SketchGrids.Dependencies.csproj b/Grids/SketchGrids/dependencies/SketchGrids.Dependencies.csproj index 9b55480d..91caf5c0 100644 --- a/Grids/SketchGrids/dependencies/SketchGrids.Dependencies.csproj +++ b/Grids/SketchGrids/dependencies/SketchGrids.Dependencies.csproj @@ -1,12 +1,10 @@ + - - - - - - - netcoreapp3.1 + net6.0 - - + + + + + \ No newline at end of file diff --git a/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs b/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs index 3a046184..a46b742b 100644 --- a/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs +++ b/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs @@ -22,15 +22,15 @@ namespace SketchGrids { #pragma warning disable // Disable all warnings - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v13.0.0.0)")] - public class SketchGridsInputs : S3Args + public class SketchGridsInputs : ArgsBase { [Newtonsoft.Json.JsonConstructor] - public SketchGridsInputs(double @offsetDistanceFromConceptualMass, bool @addSkeletonGrids, Overrides @overrides, string bucketName, string uploadsBucket, Dictionary modelInputKeys, string gltfKey, string elementsKey, string ifcKey): - base(bucketName, uploadsBucket, modelInputKeys, gltfKey, elementsKey, ifcKey) + public SketchGridsInputs(double @offsetDistanceFromConceptualMass, bool @addSkeletonGrids, Overrides @overrides, Dictionary modelInputKeys, string gltfKey, string elementsKey, string ifcKey): + base(modelInputKeys, gltfKey, elementsKey, ifcKey) { var validator = Validator.Instance.GetFirstValidatorForType(); if(validator != null) @@ -61,7 +61,7 @@ public SketchGridsInputs(double @offsetDistanceFromConceptualMass, bool @addSkel } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v13.0.0.0)")] public partial class Overrides @@ -98,7 +98,7 @@ public Overrides(OverrideAdditions @additions, OverrideRemovals @removals, IList } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v13.0.0.0)")] public partial class OverrideAdditions @@ -127,7 +127,7 @@ public OverrideAdditions(IList @gridLines) } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v13.0.0.0)")] public partial class OverrideRemovals @@ -156,7 +156,7 @@ public OverrideRemovals(IList @gridLines) } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v13.0.0.0)")] public partial class GridLinesOverride @@ -191,7 +191,7 @@ public GridLinesOverride(string @id, GridLinesIdentity @identity, GridLinesValue } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v13.0.0.0)")] public partial class GridLinesOverrideAddition @@ -226,7 +226,7 @@ public GridLinesOverrideAddition(string @id, GridLinesIdentity @identity, GridLi } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v13.0.0.0)")] public partial class GridLinesOverrideRemoval @@ -257,7 +257,7 @@ public GridLinesOverrideRemoval(string @id, GridLinesIdentity @identity) } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v13.0.0.0)")] public partial class GridLinesIdentity @@ -284,7 +284,7 @@ public GridLinesIdentity(System.Guid @creationId) } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v13.0.0.0)")] public partial class GridLinesValue @@ -311,7 +311,7 @@ public GridLinesValue(Line @curve) } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v12.0.0.0)")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v13.0.0.0)")] public partial class GridLinesOverrideAdditionValue diff --git a/Grids/SketchGrids/dependencies/SketchGridsOutputs.g.cs b/Grids/SketchGrids/dependencies/SketchGridsOutputs.g.cs index a25a4bed..159d236e 100644 --- a/Grids/SketchGrids/dependencies/SketchGridsOutputs.g.cs +++ b/Grids/SketchGrids/dependencies/SketchGridsOutputs.g.cs @@ -17,16 +17,13 @@ namespace SketchGrids public class SketchGridsOutputs: SystemResults { - /// /// Construct a SketchGridsOutputs with default inputs. /// This should be used for testing only. /// public SketchGridsOutputs() : base() { - } - } } \ No newline at end of file diff --git a/Grids/SketchGrids/hypar.json b/Grids/SketchGrids/hypar.json index c2c5a988..8a6cb9bd 100644 --- a/Grids/SketchGrids/hypar.json +++ b/Grids/SketchGrids/hypar.json @@ -68,7 +68,7 @@ } ], "element_types": [ - "https://prod-api.hypar.io/schemas/ConceptualMass" + "https://schemas.hypar.io/ConceptualMass.json" ], "model_output": "Grids", "repository_url": "https://github.com/hypar-io/function", diff --git a/Grids/SketchGrids/src/Function.g.cs b/Grids/SketchGrids/src/Function.g.cs index 0ec28b62..3d88030c 100644 --- a/Grids/SketchGrids/src/Function.g.cs +++ b/Grids/SketchGrids/src/Function.g.cs @@ -2,7 +2,6 @@ // Edits to this code will be overwritten the next time you run 'hypar init'. // DO NOT EDIT THIS FILE. -using Amazon; using Amazon.Lambda.Core; using Hypar.Functions.Execution; using Hypar.Functions.Execution.AWS; @@ -19,9 +18,9 @@ public class Function { // Cache the model store for use by subsequent // executions of this lambda. - private IModelStore store; + private UrlModelStore store; - public async Task Handler(SketchGridsInputs args, ILambdaContext context) + public async Task Handler(SketchGridsInputs args) { // Preload dependencies (if they exist), // so that they are available during model deserialization. @@ -62,10 +61,11 @@ public async Task Handler(SketchGridsInputs args, ILambdaCon if(this.store == null) { - this.store = new S3ModelStore(RegionEndpoint.USWest1); + this.store = new UrlModelStore(); } + - var l = new InvocationWrapper(store, SketchGrids.Execute); + var l = new InvocationWrapper (store, SketchGrids.Execute); var output = await l.InvokeAsync(args); return output; } diff --git a/Grids/SketchGrids/src/SketchGrids.csproj b/Grids/SketchGrids/src/SketchGrids.csproj index f7b90840..4c86d152 100644 --- a/Grids/SketchGrids/src/SketchGrids.csproj +++ b/Grids/SketchGrids/src/SketchGrids.csproj @@ -1,11 +1,9 @@ + - - - netcoreapp3.1 + net6.0 - - + \ No newline at end of file diff --git a/Grids/SketchGrids/test/SketchGrids.Tests.csproj b/Grids/SketchGrids/test/SketchGrids.Tests.csproj index 69bce0f4..f2953633 100644 --- a/Grids/SketchGrids/test/SketchGrids.Tests.csproj +++ b/Grids/SketchGrids/test/SketchGrids.Tests.csproj @@ -1,20 +1,16 @@ + - - netcoreapp3.1 - + net6.0 false - - - - + \ No newline at end of file From efd81dd1d52948a8e701786e072dfeada2a1a4d9 Mon Sep 17 00:00:00 2001 From: Ian Keough Date: Fri, 8 Dec 2023 06:58:49 -0800 Subject: [PATCH 10/16] Add grid names. --- .../dependencies/SketchGridsInputs.g.cs | 18 ++++++++++++++---- Grids/SketchGrids/hypar.json | 10 +++++++++- Grids/SketchGrids/src/SketchGrids.cs | 18 ++++++++++++++---- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs b/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs index a46b742b..98c59918 100644 --- a/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs +++ b/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs @@ -290,15 +290,16 @@ public partial class GridLinesValue { [Newtonsoft.Json.JsonConstructor] - public GridLinesValue(Line @curve) + public GridLinesValue(Line @curve, string @name) { var validator = Validator.Instance.GetFirstValidatorForType(); if(validator != null) { - validator.PreConstruct(new object[]{ @curve}); + validator.PreConstruct(new object[]{ @curve, @name}); } this.Curve = @curve; + this.Name = @name; if(validator != null) { @@ -309,6 +310,10 @@ public GridLinesValue(Line @curve) [Newtonsoft.Json.JsonProperty("Curve", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public Line Curve { get; set; } + /// The name of the grid line. + [Newtonsoft.Json.JsonProperty("Name", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string Name { get; set; } + } [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v13.0.0.0)")] @@ -317,15 +322,16 @@ public partial class GridLinesOverrideAdditionValue { [Newtonsoft.Json.JsonConstructor] - public GridLinesOverrideAdditionValue(Line @curve) + public GridLinesOverrideAdditionValue(Line @curve, string @name) { var validator = Validator.Instance.GetFirstValidatorForType(); if(validator != null) { - validator.PreConstruct(new object[]{ @curve}); + validator.PreConstruct(new object[]{ @curve, @name}); } this.Curve = @curve; + this.Name = @name; if(validator != null) { @@ -336,5 +342,9 @@ public GridLinesOverrideAdditionValue(Line @curve) [Newtonsoft.Json.JsonProperty("Curve", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public Line Curve { get; set; } + /// The name of the grid line. + [Newtonsoft.Json.JsonProperty("Name", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string Name { get; set; } + } } \ No newline at end of file diff --git a/Grids/SketchGrids/hypar.json b/Grids/SketchGrids/hypar.json index 8a6cb9bd..8b37bda0 100644 --- a/Grids/SketchGrids/hypar.json +++ b/Grids/SketchGrids/hypar.json @@ -22,7 +22,7 @@ }, "filters": { "Grids": { - "context": "[*discriminator=Elements.GridLine]", + "context": "[*discriminator=Elements.ModelText|discriminator=Elements.GridLine]", "default": true }, "Grid Cells": { @@ -43,6 +43,10 @@ "$ref": "https://hypar.io/Schemas/Geometry/Line.json", "$hyparAllowIntersection": true, "$hyparContinueDrawing": true + }, + "Name": { + "description": "The name of the grid line.", + "type": "string" } }, "behaviors": { @@ -52,6 +56,10 @@ "$ref": "https://hypar.io/Schemas/Geometry/Line.json", "$hyparAllowIntersection": true, "$hyparContinueDrawing": true + }, + "Name": { + "description": "The name of the grid line.", + "type": "string" } } }, diff --git a/Grids/SketchGrids/src/SketchGrids.cs b/Grids/SketchGrids/src/SketchGrids.cs index 9df1ed9d..febc90cd 100644 --- a/Grids/SketchGrids/src/SketchGrids.cs +++ b/Grids/SketchGrids/src/SketchGrids.cs @@ -34,7 +34,8 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, var gridLine = new GridLine() { Curve = addition.Value.Curve, - Material = gridMaterial + Material = gridMaterial, + Name = addition.Value.Name }; gridLine.AdditionalProperties["Creation Id"] = addition.Id; return gridLine; @@ -44,11 +45,10 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, }, (gl, glo) => { gl.Curve = glo.Value.Curve; + gl.Name = glo.Value.Name; return gl; }); - output.Model.AddElements(gridLines); - if (inputModels.ContainsKey("Conceptual Mass")) { var conceptualMasses = inputModels["Conceptual Mass"].AllElementsOfType(); @@ -175,9 +175,19 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, output.Model.AddElements(gridLines); + var texts = new List<(Vector3 location, Vector3 facingDirection, Vector3 lineDirection, string text, Color? color)>(); + var start = 0; + foreach (var gridLine in gridLines) + { + var t = gridLine.GetCircleTransform(); + texts.Add(((t.Origin.X, t.Origin.Y), Vector3.ZAxis, Vector3.XAxis, $"{gridLine.Name ?? "XXX"}", Colors.Black)); + start++; + } + output.Model.AddElement(new ModelText(texts, FontSize.PT60, scale: 50)); + var network = Network.FromSegmentableItems(gridLines, (gl) => { return (Line)gl.Curve; }, out var allNodeLocations, out _); - var r = new Random(); + var r = new Random(); // testY var closedRegions = network.FindAllClosedRegions(allNodeLocations); foreach (var cr in closedRegions) From 8b1a94b6de8525d7d1859f7d72ba06b504e9e6f1 Mon Sep 17 00:00:00 2001 From: Ian Keough Date: Sun, 10 Dec 2023 17:16:38 -0800 Subject: [PATCH 11/16] Overrides almost working. --- .../dependencies/SketchGridsInputs.g.cs | 4 +- Grids/SketchGrids/hypar.json | 10 +- Grids/SketchGrids/src/SketchGrids.cs | 274 +++++++++--------- 3 files changed, 151 insertions(+), 137 deletions(-) diff --git a/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs b/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs index 98c59918..5757a4bc 100644 --- a/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs +++ b/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs @@ -312,7 +312,7 @@ public GridLinesValue(Line @curve, string @name) /// The name of the grid line. [Newtonsoft.Json.JsonProperty("Name", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public string Name { get; set; } + public string Name { get; set; } = "XXX"; } @@ -344,7 +344,7 @@ public GridLinesOverrideAdditionValue(Line @curve, string @name) /// The name of the grid line. [Newtonsoft.Json.JsonProperty("Name", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public string Name { get; set; } + public string Name { get; set; } = "XXX"; } } \ No newline at end of file diff --git a/Grids/SketchGrids/hypar.json b/Grids/SketchGrids/hypar.json index 8b37bda0..1a153ecb 100644 --- a/Grids/SketchGrids/hypar.json +++ b/Grids/SketchGrids/hypar.json @@ -42,11 +42,12 @@ "Curve": { "$ref": "https://hypar.io/Schemas/Geometry/Line.json", "$hyparAllowIntersection": true, - "$hyparContinueDrawing": true + "$hyparContinueDrawing": false }, "Name": { "description": "The name of the grid line.", - "type": "string" + "type": "string", + "default": "XXX" } }, "behaviors": { @@ -55,11 +56,12 @@ "Curve": { "$ref": "https://hypar.io/Schemas/Geometry/Line.json", "$hyparAllowIntersection": true, - "$hyparContinueDrawing": true + "$hyparContinueDrawing": false }, "Name": { "description": "The name of the grid line.", - "type": "string" + "type": "string", + "default": "XXX" } } }, diff --git a/Grids/SketchGrids/src/SketchGrids.cs b/Grids/SketchGrids/src/SketchGrids.cs index febc90cd..b045288f 100644 --- a/Grids/SketchGrids/src/SketchGrids.cs +++ b/Grids/SketchGrids/src/SketchGrids.cs @@ -22,6 +22,8 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, { WidthMode = EdgeDisplayWidthMode.ScreenUnits, LineWidth = 1, + DashSize = 40, + // DashMode = EdgeDisplayDashMode.ScreenUnits }; var gridMaterial = new Material("Grid Line", Colors.Darkgray) @@ -29,13 +31,20 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, EdgeDisplaySettings = edgeDisplaySettings }; - var gridLines = input.Overrides.GridLines.CreateElements(input.Overrides.Additions.GridLines, input.Overrides.Removals.GridLines, (addition) => + var gridLines = new List(); + + if (inputModels.ContainsKey("Conceptual Mass")) + { + CreateGridLinesForConceptualMass(inputModels, input, gridMaterial, gridLines); + } + + gridLines = input.Overrides.GridLines.CreateElements(input.Overrides.Additions.GridLines, input.Overrides.Removals.GridLines, (addition) => { var gridLine = new GridLine() { Curve = addition.Value.Curve, Material = gridMaterial, - Name = addition.Value.Name + Name = addition.Value.Name ?? "XXX" }; gridLine.AdditionalProperties["Creation Id"] = addition.Id; return gridLine; @@ -45,143 +54,17 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, }, (gl, glo) => { gl.Curve = glo.Value.Curve; - gl.Name = glo.Value.Name; + gl.Name = glo.Value.Name ?? "XXX"; return gl; - }); - - if (inputModels.ContainsKey("Conceptual Mass")) - { - var conceptualMasses = inputModels["Conceptual Mass"].AllElementsOfType(); - - // Find the outer bounds of all the conceptual masses. - // This will be used to extend grids to cover the whole mass. - // var hull = ConvexHull.FromPolylines(conceptualMasses.Select(m => m.Profile.Perimeter)); - // var offsetHull = hull.Offset(2)[0]; - - // TODO: Create an input for structural offset - var gridIndex = 0; - var allVoids = new List(); - - foreach (var conceptualMass in conceptualMasses) - { - var offsetHull = conceptualMass.Profile.Perimeter.Offset(1)[0]; - - conceptualMass.UpdateRepresentations(); - conceptualMass.UpdateBoundsAndComputeSolid(); - - if (conceptualMass.Skeleton != null) - { - // Create grids for the skeleton - if (input.AddSkeletonGrids) - { - foreach (var edge in conceptualMass.Skeleton) - { - var newGridLine = edge.ExtendTo(offsetHull); - CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial); - } - } - - var allPerimeters = new List(); - - if (conceptualMass.Profile != null && conceptualMass.Profile.Voids != null) - { - allPerimeters.Add(conceptualMass.Profile.Perimeter); - foreach (var profileVoid in conceptualMass.Profile.Voids) - { - allVoids.Add(profileVoid); - } - } - - // Offset perimeters to the inside. - foreach (var cutPerimeter in allPerimeters) - { - foreach (var segment in cutPerimeter.Offset(-input.OffsetDistanceFromConceptualMass)[0].Segments()) - { - var newGridLine = segment.ExtendTo(offsetHull); - CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial); - } - } - - // TODO: Are there ever holes in a skeleton mass? - // Offset holes to the outside. - // foreach (var cutVoid in allVoids) - // { - // foreach (var segment in cutVoid.Offset(-structuralOffset)[0].Segments()) - // { - // var newGridLine = segment.ExtendTo(offsetHull); - // CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial); - // } - // } - } - else - { - foreach (var segment in conceptualMass.Profile.Perimeter.Offset(-input.OffsetDistanceFromConceptualMass)[0].Segments()) - { - var newGridLine = segment.ExtendTo(offsetHull); - CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial); - } - - if (conceptualMass.Profile.Voids != null) - { - allVoids.AddRange(conceptualMass.Profile.Voids); - } - } - } - - // We process the voids last so that we have all grids - // created from the faces of the conceptual masses to respond - // to. This will create the shortest spanning edge grids for holes. - foreach (var profileVoid in allVoids) - { - var holeGridLines = new List(); - var offsetHull = profileVoid.Offset(1)[0]; - // foreach (var segment in profileVoid.Offset(input.OffsetDistanceFromConceptualMass)[0].Segments()) - // { - // var d = segment.Direction(); - // var startRay = new Ray(segment.Start, d.Negate()); - // var endRay = new Ray(segment.End, d); - // var startX = new List(); - // var endX = new List(); - // foreach (var gridLine in gridLines) - // { - // if (startRay.Intersects(gridLine.Curve as Line, out Vector3 startResult)) - // { - // startX.Add(startResult); - // } - // if (endRay.Intersects(gridLine.Curve as Line, out Vector3 endResult)) - // { - // endX.Add(endResult); - // } - // } - // startX.Sort(new DistanceComparer(segment.Start)); - // endX.Sort(new DistanceComparer(segment.End)); - - // var newGridLine = new Line(startX[0], endX[0]); - - // // Add these to a separate collection so we don't test against them. - // holeGridLines.Add(newGridLine); - // } - foreach (var segment in offsetHull.Segments()) - { - holeGridLines.Add(segment); - } - - foreach (var holeGridLine in holeGridLines) - { - CheckAndCreateGridline(holeGridLine, gridLines, ref gridIndex, gridMaterial); - } - } - } + }, gridLines); output.Model.AddElements(gridLines); var texts = new List<(Vector3 location, Vector3 facingDirection, Vector3 lineDirection, string text, Color? color)>(); - var start = 0; foreach (var gridLine in gridLines) { var t = gridLine.GetCircleTransform(); texts.Add(((t.Origin.X, t.Origin.Y), Vector3.ZAxis, Vector3.XAxis, $"{gridLine.Name ?? "XXX"}", Colors.Black)); - start++; } output.Model.AddElement(new ModelText(texts, FontSize.PT60, scale: 50)); @@ -189,7 +72,7 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, var r = new Random(); // testY - var closedRegions = network.FindAllClosedRegions(allNodeLocations); + var closedRegions = network.FindAllClosedRegions(allNodeLocations).SkipLast(1); foreach (var cr in closedRegions) { try @@ -225,6 +108,133 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, return output; } + private static void CreateGridLinesForConceptualMass(Dictionary inputModels, + SketchGridsInputs input, + Material gridMaterial, + List gridLines) + { + var conceptualMasses = inputModels["Conceptual Mass"].AllElementsOfType(); + + // Find the outer bounds of all the conceptual masses. + // This will be used to extend grids to cover the whole mass. + // var hull = ConvexHull.FromPolylines(conceptualMasses.Select(m => m.Profile.Perimeter)); + // var offsetHull = hull.Offset(2)[0]; + + // TODO: Create an input for structural offset + var gridIndex = 0; + var allVoids = new List(); + + foreach (var conceptualMass in conceptualMasses) + { + var offsetHull = conceptualMass.Profile.Perimeter.Offset(1)[0]; + + conceptualMass.UpdateRepresentations(); + conceptualMass.UpdateBoundsAndComputeSolid(); + + if (conceptualMass.Skeleton != null) + { + // Create grids for the skeleton + if (input.AddSkeletonGrids) + { + foreach (var edge in conceptualMass.Skeleton) + { + var newGridLine = edge.ExtendTo(offsetHull); + CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial); + } + } + + var allPerimeters = new List(); + + if (conceptualMass.Profile != null && conceptualMass.Profile.Voids != null) + { + allPerimeters.Add(conceptualMass.Profile.Perimeter); + foreach (var profileVoid in conceptualMass.Profile.Voids) + { + allVoids.Add(profileVoid); + } + } + + // Offset perimeters to the inside. + foreach (var cutPerimeter in allPerimeters) + { + foreach (var segment in cutPerimeter.Offset(-input.OffsetDistanceFromConceptualMass)[0].Segments()) + { + var newGridLine = segment.ExtendTo(offsetHull); + CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial); + } + } + + // TODO: Are there ever holes in a skeleton mass? + // Offset holes to the outside. + // foreach (var cutVoid in allVoids) + // { + // foreach (var segment in cutVoid.Offset(-structuralOffset)[0].Segments()) + // { + // var newGridLine = segment.ExtendTo(offsetHull); + // CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial); + // } + // } + } + else + { + foreach (var segment in conceptualMass.Profile.Perimeter.Offset(-input.OffsetDistanceFromConceptualMass)[0].Segments()) + { + var newGridLine = segment.ExtendTo(offsetHull); + CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial); + } + + if (conceptualMass.Profile.Voids != null) + { + allVoids.AddRange(conceptualMass.Profile.Voids); + } + } + } + + // We process the voids last so that we have all grids + // created from the faces of the conceptual masses to respond + // to. This will create the shortest spanning edge grids for holes. + foreach (var profileVoid in allVoids) + { + var holeGridLines = new List(); + var offsetHull = profileVoid.Offset(1)[0]; + // foreach (var segment in profileVoid.Offset(input.OffsetDistanceFromConceptualMass)[0].Segments()) + // { + // var d = segment.Direction(); + // var startRay = new Ray(segment.Start, d.Negate()); + // var endRay = new Ray(segment.End, d); + // var startX = new List(); + // var endX = new List(); + // foreach (var gridLine in gridLines) + // { + // if (startRay.Intersects(gridLine.Curve as Line, out Vector3 startResult)) + // { + // startX.Add(startResult); + // } + // if (endRay.Intersects(gridLine.Curve as Line, out Vector3 endResult)) + // { + // endX.Add(endResult); + // } + // } + // startX.Sort(new DistanceComparer(segment.Start)); + // endX.Sort(new DistanceComparer(segment.End)); + + // var newGridLine = new Line(startX[0], endX[0]); + + // // Add these to a separate collection so we don't test against them. + // holeGridLines.Add(newGridLine); + // } + foreach (var segment in offsetHull.Segments()) + { + holeGridLines.Add(segment); + } + + foreach (var holeGridLine in holeGridLines) + { + CheckAndCreateGridline(holeGridLine, gridLines, ref gridIndex, gridMaterial); + } + } + } + private static void CheckAndCreateGridline(Line newGridLine, List gridLines, ref int gridIndex, Material gridMaterial) { var directionReference = new Vector3(1, -1); @@ -233,6 +243,7 @@ private static void CheckAndCreateGridline(Line newGridLine, List grid { return; } + var d = newGridLine.Direction(); var dot = directionReference.Dot(d); @@ -242,6 +253,7 @@ private static void CheckAndCreateGridline(Line newGridLine, List grid Name = gridIndex.ToString(), Material = gridMaterial }; + gl.AdditionalProperties["Creation Id"] = Guid.NewGuid().ToString(); gridLines.Add(gl); gridIndex++; } From fdc167f814bbc64525dc4e5f0a3595831d7c9bb5 Mon Sep 17 00:00:00 2001 From: Ian Keough Date: Sun, 10 Dec 2023 17:24:34 -0800 Subject: [PATCH 12/16] Cleanup. --- Grids/SketchGrids/src/SketchGrids.cs | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/Grids/SketchGrids/src/SketchGrids.cs b/Grids/SketchGrids/src/SketchGrids.cs index b045288f..17995e70 100644 --- a/Grids/SketchGrids/src/SketchGrids.cs +++ b/Grids/SketchGrids/src/SketchGrids.cs @@ -86,25 +86,6 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, } } - // TODO: Draw some annotations. - // var bbox = new BBox3(allNodeLocations); - - // var vectorEqualityComparer = new VectorEqualityComparer(); - // var gridLineGroups = gridLines.GroupBy(gl => (gl.Curve as Line).Direction().Unitized(), vectorEqualityComparer); - // var directionComparer = new DirectionComparer(bbox.Min); - - // foreach (var gridLineGroup in gridLineGroups) - // { - // var grids = gridLineGroup.ToList(); - // var orderedGrids = grids.OrderBy(gl => gl.Curve.PointAt(0), directionComparer).ToList(); - // for (var i = 0; i < orderedGrids.Count - 1; i++) - // { - // var dim = new AlignedDimension(orderedGrids[i].Curve.PointAt(0), orderedGrids[i + 1].Curve.PointAt(0), 0); - // output.Model.AddElement(dim); - // // output.Model.AddElements(dim.ToModelArrowsAndText(Colors.Black)); - // } - // } - return output; } From 56acbace971244c17a44363cd582e21e99fc6b88 Mon Sep 17 00:00:00 2001 From: Ian Keough Date: Sun, 10 Dec 2023 19:44:29 -0800 Subject: [PATCH 13/16] Renaming and cleanup. --- Grids/SketchGrids/src/SketchGrids.cs | 48 +++++++--------------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/Grids/SketchGrids/src/SketchGrids.cs b/Grids/SketchGrids/src/SketchGrids.cs index 17995e70..d138b807 100644 --- a/Grids/SketchGrids/src/SketchGrids.cs +++ b/Grids/SketchGrids/src/SketchGrids.cs @@ -38,23 +38,24 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, CreateGridLinesForConceptualMass(inputModels, input, gridMaterial, gridLines); } - gridLines = input.Overrides.GridLines.CreateElements(input.Overrides.Additions.GridLines, input.Overrides.Removals.GridLines, (addition) => + gridLines = input.Overrides.GridLines.CreateElements(input.Overrides.Additions.GridLines, input.Overrides.Removals.GridLines, + (add) => { var gridLine = new GridLine() { - Curve = addition.Value.Curve, + Curve = add.Value.Curve, Material = gridMaterial, - Name = addition.Value.Name ?? "XXX" + Name = add.Value.Name ?? "XXX" }; - gridLine.AdditionalProperties["Creation Id"] = addition.Id; + gridLine.AdditionalProperties["Creation Id"] = add.Id; return gridLine; - }, (gl, gli) => + }, (gl, identity) => { - return Guid.Parse((string)gl.AdditionalProperties["Creation Id"]) == gli.CreationId; - }, (gl, glo) => + return Guid.Parse((string)gl.AdditionalProperties["Creation Id"]) == identity.CreationId; + }, (gl, @override) => { - gl.Curve = glo.Value.Curve; - gl.Name = glo.Value.Name ?? "XXX"; + gl.Curve = @override.Value.Curve; + gl.Name = @override.Value.Name ?? "XXX"; return gl; }, gridLines); @@ -177,33 +178,8 @@ private static void CreateGridLinesForConceptualMass(Dictionary i foreach (var profileVoid in allVoids) { var holeGridLines = new List(); - var offsetHull = profileVoid.Offset(1)[0]; - // foreach (var segment in profileVoid.Offset(input.OffsetDistanceFromConceptualMass)[0].Segments()) - // { - // var d = segment.Direction(); - // var startRay = new Ray(segment.Start, d.Negate()); - // var endRay = new Ray(segment.End, d); - // var startX = new List(); - // var endX = new List(); - // foreach (var gridLine in gridLines) - // { - // if (startRay.Intersects(gridLine.Curve as Line, out Vector3 startResult)) - // { - // startX.Add(startResult); - // } - // if (endRay.Intersects(gridLine.Curve as Line, out Vector3 endResult)) - // { - // endX.Add(endResult); - // } - // } - // startX.Sort(new DistanceComparer(segment.Start)); - // endX.Sort(new DistanceComparer(segment.End)); - - // var newGridLine = new Line(startX[0], endX[0]); - - // // Add these to a separate collection so we don't test against them. - // holeGridLines.Add(newGridLine); - // } + var offsetHull = profileVoid.Offset(input.OffsetDistanceFromConceptualMass)[0]; + foreach (var segment in offsetHull.Segments()) { holeGridLines.Add(segment); From ef3f39868291621d15c3357a83341b0b1328de4f Mon Sep 17 00:00:00 2001 From: Ian Keough Date: Sun, 10 Dec 2023 20:15:06 -0800 Subject: [PATCH 14/16] Fix edit overrides. --- .../dependencies/SketchGridsInputs.g.cs | 10 ++--- Grids/SketchGrids/hypar.json | 5 +-- Grids/SketchGrids/src/SketchGrids.cs | 44 +++++++++++-------- 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs b/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs index 5757a4bc..3a05b48e 100644 --- a/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs +++ b/Grids/SketchGrids/dependencies/SketchGridsInputs.g.cs @@ -263,15 +263,15 @@ public partial class GridLinesIdentity { [Newtonsoft.Json.JsonConstructor] - public GridLinesIdentity(System.Guid @creationId) + public GridLinesIdentity(Line @curve) { var validator = Validator.Instance.GetFirstValidatorForType(); if(validator != null) { - validator.PreConstruct(new object[]{ @creationId}); + validator.PreConstruct(new object[]{ @curve}); } - this.CreationId = @creationId; + this.Curve = @curve; if(validator != null) { @@ -279,8 +279,8 @@ public GridLinesIdentity(System.Guid @creationId) } } - [Newtonsoft.Json.JsonProperty("Creation Id", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public System.Guid CreationId { get; set; } + [Newtonsoft.Json.JsonProperty("Curve", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public Line Curve { get; set; } } diff --git a/Grids/SketchGrids/hypar.json b/Grids/SketchGrids/hypar.json index 1a153ecb..d21f3ea7 100644 --- a/Grids/SketchGrids/hypar.json +++ b/Grids/SketchGrids/hypar.json @@ -33,9 +33,8 @@ "Grid Lines": { "context": "[*discriminator=Elements.GridLine]", "identity": { - "Creation Id": { - "type": "string", - "format": "uuid" + "Curve": { + "$ref": "https://hypar.io/Schemas/Geometry/Line.json" } }, "schema": { diff --git a/Grids/SketchGrids/src/SketchGrids.cs b/Grids/SketchGrids/src/SketchGrids.cs index d138b807..0971c8a7 100644 --- a/Grids/SketchGrids/src/SketchGrids.cs +++ b/Grids/SketchGrids/src/SketchGrids.cs @@ -51,7 +51,7 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, return gridLine; }, (gl, identity) => { - return Guid.Parse((string)gl.AdditionalProperties["Creation Id"]) == identity.CreationId; + return identity.Curve != null && ((Line)gl.Curve).IsAlmostEqualTo(identity.Curve, false); }, (gl, @override) => { gl.Curve = @override.Value.Curve; @@ -97,12 +97,6 @@ private static void CreateGridLinesForConceptualMass(Dictionary i { var conceptualMasses = inputModels["Conceptual Mass"].AllElementsOfType(); - // Find the outer bounds of all the conceptual masses. - // This will be used to extend grids to cover the whole mass. - // var hull = ConvexHull.FromPolylines(conceptualMasses.Select(m => m.Profile.Perimeter)); - // var offsetHull = hull.Offset(2)[0]; - - // TODO: Create an input for structural offset var gridIndex = 0; var allVoids = new List(); @@ -121,7 +115,7 @@ private static void CreateGridLinesForConceptualMass(Dictionary i foreach (var edge in conceptualMass.Skeleton) { var newGridLine = edge.ExtendTo(offsetHull); - CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial); + CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial, input); } } @@ -142,7 +136,7 @@ private static void CreateGridLinesForConceptualMass(Dictionary i foreach (var segment in cutPerimeter.Offset(-input.OffsetDistanceFromConceptualMass)[0].Segments()) { var newGridLine = segment.ExtendTo(offsetHull); - CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial); + CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial, input); } } @@ -162,7 +156,7 @@ private static void CreateGridLinesForConceptualMass(Dictionary i foreach (var segment in conceptualMass.Profile.Perimeter.Offset(-input.OffsetDistanceFromConceptualMass)[0].Segments()) { var newGridLine = segment.ExtendTo(offsetHull); - CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial); + CheckAndCreateGridline(newGridLine, gridLines, ref gridIndex, gridMaterial, input); } if (conceptualMass.Profile.Voids != null) @@ -187,32 +181,46 @@ private static void CreateGridLinesForConceptualMass(Dictionary i foreach (var holeGridLine in holeGridLines) { - CheckAndCreateGridline(holeGridLine, gridLines, ref gridIndex, gridMaterial); + CheckAndCreateGridline(holeGridLine, gridLines, ref gridIndex, gridMaterial, input); } } } - private static void CheckAndCreateGridline(Line newGridLine, List gridLines, ref int gridIndex, Material gridMaterial) + private static void CheckAndCreateGridline(Line newGridLine, + List gridLines, + ref int gridIndex, + Material gridMaterial, + SketchGridsInputs input) { - var directionReference = new Vector3(1, -1); - if (gridLines.Any(gl => (gl.Curve as Line).IsAlmostEqualTo(newGridLine, false))) { return; } - var d = newGridLine.Direction(); - var dot = directionReference.Dot(d); + GridLinesOverride matchingEditOverride = null; + if (input.Overrides?.GridLines != null) + { + matchingEditOverride = input.Overrides.GridLines.FirstOrDefault((glo) => glo.Identity.Curve != null && glo.Identity.Curve.IsAlmostEqualTo(newGridLine, false)); + if (matchingEditOverride != null) + { + Console.WriteLine($"Found matching edit override for grid line {newGridLine}."); + newGridLine = matchingEditOverride.Value.Curve; + } + } var gl = new GridLine() { - Curve = dot >= 0 ? newGridLine : new Line(newGridLine.End, newGridLine.Start), + Curve = newGridLine, Name = gridIndex.ToString(), Material = gridMaterial }; - gl.AdditionalProperties["Creation Id"] = Guid.NewGuid().ToString(); gridLines.Add(gl); gridIndex++; + + if (matchingEditOverride != null) + { + Identity.AddOverrideIdentity(gl, matchingEditOverride); + } } } } From 4ed9cfa359755215b51d33b8027d709a5d3595c9 Mon Sep 17 00:00:00 2001 From: Ian Keough Date: Sun, 10 Dec 2023 20:49:15 -0800 Subject: [PATCH 15/16] Remove a log. --- Grids/SketchGrids/src/SketchGrids.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Grids/SketchGrids/src/SketchGrids.cs b/Grids/SketchGrids/src/SketchGrids.cs index 0971c8a7..39478b8d 100644 --- a/Grids/SketchGrids/src/SketchGrids.cs +++ b/Grids/SketchGrids/src/SketchGrids.cs @@ -203,7 +203,6 @@ private static void CheckAndCreateGridline(Line newGridLine, matchingEditOverride = input.Overrides.GridLines.FirstOrDefault((glo) => glo.Identity.Curve != null && glo.Identity.Curve.IsAlmostEqualTo(newGridLine, false)); if (matchingEditOverride != null) { - Console.WriteLine($"Found matching edit override for grid line {newGridLine}."); newGridLine = matchingEditOverride.Value.Curve; } } From 094c41948c2b1e0ba00b0d025038c442bcd05582 Mon Sep 17 00:00:00 2001 From: Ian Keough Date: Sun, 10 Dec 2023 20:58:43 -0800 Subject: [PATCH 16/16] Remove filters and panel creation. --- Grids/SketchGrids/hypar.json | 9 --------- Grids/SketchGrids/src/SketchGrids.cs | 18 ------------------ 2 files changed, 27 deletions(-) diff --git a/Grids/SketchGrids/hypar.json b/Grids/SketchGrids/hypar.json index d21f3ea7..ab810eef 100644 --- a/Grids/SketchGrids/hypar.json +++ b/Grids/SketchGrids/hypar.json @@ -20,15 +20,6 @@ } } }, - "filters": { - "Grids": { - "context": "[*discriminator=Elements.ModelText|discriminator=Elements.GridLine]", - "default": true - }, - "Grid Cells": { - "context": "[*discriminator=Elements.Panel]" - } - }, "overrides": { "Grid Lines": { "context": "[*discriminator=Elements.GridLine]", diff --git a/Grids/SketchGrids/src/SketchGrids.cs b/Grids/SketchGrids/src/SketchGrids.cs index 39478b8d..8e152629 100644 --- a/Grids/SketchGrids/src/SketchGrids.cs +++ b/Grids/SketchGrids/src/SketchGrids.cs @@ -69,24 +69,6 @@ public static SketchGridsOutputs Execute(Dictionary inputModels, } output.Model.AddElement(new ModelText(texts, FontSize.PT60, scale: 50)); - var network = Network.FromSegmentableItems(gridLines, (gl) => { return (Line)gl.Curve; }, out var allNodeLocations, out _); - - var r = new Random(); // testY - - var closedRegions = network.FindAllClosedRegions(allNodeLocations).SkipLast(1); - foreach (var cr in closedRegions) - { - try - { - var p = new Panel(new Polygon(cr.Select(r => allNodeLocations[r]).ToList()), r.NextMaterial()); - output.Model.AddElement(p); - } - catch - { - continue; - } - } - return output; }