Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flip override #59

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

696 changes: 1 addition & 695 deletions LayoutFunctions/ClassroomLayout/ClassroomConfigurations.json

Large diffs are not rendered by default.

2,532 changes: 2,532 additions & 0 deletions LayoutFunctions/ClassroomLayout/catalog-old 8.2023.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion LayoutFunctions/ClassroomLayout/catalog.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,16 @@ public partial class Overrides
public Overrides() { }

[Newtonsoft.Json.JsonConstructor]
public Overrides(IList<FurnitureLocationsOverride> @furnitureLocations)
public Overrides(IList<FurnitureLocationsOverride> @furnitureLocations, IList<SpaceSettingsOverride> @spaceSettings)
{
var validator = Validator.Instance.GetFirstValidatorForType<Overrides>();
if(validator != null)
{
validator.PreConstruct(new object[]{ @furnitureLocations});
validator.PreConstruct(new object[]{ @furnitureLocations, @spaceSettings});
}

this.FurnitureLocations = @furnitureLocations ?? this.FurnitureLocations;
this.SpaceSettings = @spaceSettings ?? this.SpaceSettings;

if(validator != null)
{
Expand All @@ -83,6 +84,9 @@ public Overrides(IList<FurnitureLocationsOverride> @furnitureLocations)
[Newtonsoft.Json.JsonProperty("Furniture Locations", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public IList<FurnitureLocationsOverride> FurnitureLocations { get; set; } = new List<FurnitureLocationsOverride>();

[Newtonsoft.Json.JsonProperty("Space Settings", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public IList<SpaceSettingsOverride> SpaceSettings { get; set; } = new List<SpaceSettingsOverride>();

}

[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v13.0.0.0)")]
Expand Down Expand Up @@ -122,6 +126,41 @@ public FurnitureLocationsOverride(string @id, FurnitureLocationsIdentity @identi

[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v13.0.0.0)")]

public partial class SpaceSettingsOverride

{
[Newtonsoft.Json.JsonConstructor]
public SpaceSettingsOverride(string @id, SpaceSettingsIdentity @identity, SpaceSettingsValue @value)
{
var validator = Validator.Instance.GetFirstValidatorForType<SpaceSettingsOverride>();
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 SpaceSettingsIdentity Identity { get; set; }

[Newtonsoft.Json.JsonProperty("Value", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public SpaceSettingsValue Value { get; set; }

}

[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v13.0.0.0)")]

public partial class FurnitureLocationsIdentity

{
Expand Down Expand Up @@ -177,4 +216,62 @@ public FurnitureLocationsValue(Transform @transform)
public Transform Transform { get; set; }

}

[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v13.0.0.0)")]

public partial class SpaceSettingsIdentity

{
[Newtonsoft.Json.JsonConstructor]
public SpaceSettingsIdentity(Vector3 @parentCentroid)
{
var validator = Validator.Instance.GetFirstValidatorForType<SpaceSettingsIdentity>();
if(validator != null)
{
validator.PreConstruct(new object[]{ @parentCentroid});
}

this.ParentCentroid = @parentCentroid;

if(validator != null)
{
validator.PostConstruct(this);
}
}

[Newtonsoft.Json.JsonProperty("ParentCentroid", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public Vector3 ParentCentroid { get; set; }

}

[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.21.0 (Newtonsoft.Json v13.0.0.0)")]

public partial class SpaceSettingsValue

{
[Newtonsoft.Json.JsonConstructor]
public SpaceSettingsValue(bool @primaryAxisFlipLayout, bool @secondaryAxisFlipLayout)
{
var validator = Validator.Instance.GetFirstValidatorForType<SpaceSettingsValue>();
if(validator != null)
{
validator.PreConstruct(new object[]{ @primaryAxisFlipLayout, @secondaryAxisFlipLayout});
}

this.PrimaryAxisFlipLayout = @primaryAxisFlipLayout;
this.SecondaryAxisFlipLayout = @secondaryAxisFlipLayout;

if(validator != null)
{
validator.PostConstruct(this);
}
}

[Newtonsoft.Json.JsonProperty("Primary Axis Flip Layout", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public bool PrimaryAxisFlipLayout { get; set; } = false;

[Newtonsoft.Json.JsonProperty("Secondary Axis Flip Layout", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public bool SecondaryAxisFlipLayout { get; set; } = false;

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Elements;

namespace ClassroomLayout
{
public partial class SpaceSettingsValue : ISpaceSettingsOverrideFlipValue
{
}

public partial class SpaceSettingsOverride : ISpaceSettingsOverride<SpaceSettingsValue>
{
public SpaceSettingsOverride()
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using Elements;
using System.Collections.Generic;
using System;
using System.Linq;

namespace ClassroomLayout
{
/// <summary>
/// Override metadata for SpaceSettingsOverride
/// </summary>
public partial class SpaceSettingsOverride : IOverride
{
public static string Name = "Space Settings";
public static string Dependency = "Space Planning Zones";
public static string Context = "[*discriminator=Elements.SpaceBoundary&Name=Classroom]";
public static string Paradigm = "Edit";

/// <summary>
/// Get the override name for this override.
/// </summary>
public string GetName() {
return Name;
}

public object GetIdentity() {

return Identity;
}

}
public static class SpaceSettingsOverrideExtensions
{
/// <summary>
/// Apply Space Settings edit overrides to a collection of existing elements
/// </summary>
/// <param name="overrideData">The Space Settings Overrides to apply</param>
/// <param name="existingElements">A collection of existing elements to which to apply the overrides.</param>
/// <param name="identityMatch">A function returning a boolean which indicates whether an element is a match for an override's identity.</param>
/// <param name="modifyElement">A function to modify a matched element, returning the modified element.</param>
/// <typeparam name="T">The element type this override applies to. Should match the type(s) in the override's context.</typeparam>
/// <returns>A collection of elements, including unmodified and modified elements from the supplied collection.</returns>
public static List<T> Apply<T>(
this IList<SpaceSettingsOverride> overrideData,
IEnumerable<T> existingElements,
Func<T, SpaceSettingsIdentity, bool> identityMatch,
Func<T, SpaceSettingsOverride, T> modifyElement) where T : Element
{
var resultElements = new List<T>(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;
}

/// <summary>
/// Apply Space Settings edit overrides to a collection of existing elements
/// </summary>
/// <param name="existingElements">A collection of existing elements to which to apply the overrides.</param>
/// <param name="overrideData">The Space Settings Overrides to apply — typically `input.Overrides.SpaceSettings`</param>
/// <param name="identityMatch">A function returning a boolean which indicates whether an element is a match for an override's identity.</param>
/// <param name="modifyElement">A function to modify a matched element, returning the modified element.</param>
/// <typeparam name="T">The element type this override applies to. Should match the type(s) in the override's context.</typeparam>
/// <returns>A collection of elements, including unmodified and modified elements from the supplied collection.</returns>
public static void ApplyOverrides<T>(
this List<T> existingElements,
IList<SpaceSettingsOverride> overrideData,
Func<T, SpaceSettingsIdentity, bool> identityMatch,
Func<T, SpaceSettingsOverride, T> modifyElement
) where T : Element
{
var updatedElements = overrideData.Apply(existingElements, identityMatch, modifyElement);
existingElements.Clear();
existingElements.AddRange(updatedElements);
}

}


}
20 changes: 20 additions & 0 deletions LayoutFunctions/ClassroomLayout/hypar.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,26 @@
"$ref": "https://schemas.hypar.io/Transform.json"
}
}
},
"Space Settings": {
"dependency": "Space Planning Zones",
"context": "[*discriminator=Elements.SpaceBoundary&Name=Classroom]",
"identity": {
"ParentCentroid": {
"$ref": "https://hypar.io/Schemas/Geometry/Vector3.json"
}
},
"paradigm": "edit",
"schema": {
"Primary Axis Flip Layout": {
"type": "boolean",
"default": false
},
"Secondary Axis Flip Layout": {
"type": "boolean",
"default": false
}
}
}
},
"element_types": [
Expand Down
52 changes: 33 additions & 19 deletions LayoutFunctions/ClassroomLayout/src/ClassroomLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ namespace ClassroomLayout
{
public static class ClassroomLayout
{
private static readonly List<ElementProxy<SpaceBoundary>> proxies = new List<ElementProxy<SpaceBoundary>>();

/// <summary>
/// The ClassroomLayout function.
/// </summary>
Expand All @@ -21,6 +23,7 @@ public static class ClassroomLayout
/// <returns>A ClassroomLayoutOutputs instance containing computed results and the model with any new elements.</returns>
public static ClassroomLayoutOutputs Execute(Dictionary<string, Model> inputModels, ClassroomLayoutInputs input)
{
proxies.Clear();
Elements.Serialization.glTF.GltfExtensions.UseReferencedContentExtension = true;
var spacePlanningZones = inputModels["Space Planning Zones"];

Expand All @@ -41,37 +44,34 @@ public static ClassroomLayoutOutputs Execute(Dictionary<string, Model> inputMode
var output = new ClassroomLayoutOutputs();
var configJson = File.ReadAllText("./ClassroomConfigurations.json");
var configs = JsonConvert.DeserializeObject<SpaceConfiguration>(configJson);
FlippedConfigurations.Init(configs);

int totalCountableSeats = 0;
int seatsAtDesk = 0;
var deskConfig = configs["Desk"];
string[] countableSeats = new[] { "Steelcase Turnstone - Shortcut X Base - Chair - Chair",
"Steelcase Turnstone - Shortcut - Stool - Chair" };
foreach (var item in deskConfig.ContentItems)
{
foreach (var countableSeat in countableSeats)
{
if (item.ContentElement.Name != null && item.ContentElement.Name.Contains(countableSeat))
{
seatsAtDesk++;
}
}
}

var overridesBySpaceBoundaryId = OverrideUtilities.GetOverridesBySpaceBoundaryId<SpaceSettingsOverride, SpaceBoundary, LevelElements>(input.Overrides?.SpaceSettings, (ov) => ov.Identity.ParentCentroid, levels);
foreach (var lvl in levels)
{
var corridors = lvl.Elements.OfType<CirculationSegment>();
var corridorSegments = corridors.SelectMany(p => p.Profile.Segments());
var meetingRmBoundaries = lvl.Elements.OfType<SpaceBoundary>().Where(z => z.Name == "Classroom");
var meetingRmBoundaryProxies = meetingRmBoundaries.Proxies(OverrideUtilities.SpaceBoundaryOverrideDependencyName);
var levelVolume = levelVolumes.FirstOrDefault(l =>
(lvl.AdditionalProperties.TryGetValue("LevelVolumeId", out var levelVolumeId) &&
levelVolumeId as string == l.Id.ToString())) ??
lvl.AdditionalProperties.TryGetValue("LevelVolumeId", out var levelVolumeId) &&
levelVolumeId as string == l.Id.ToString()) ??
levelVolumes.FirstOrDefault(l => l.Name == lvl.Name);
var wallCandidateLines = new List<(Line line, string type)>();
foreach (var room in meetingRmBoundaries)
{
var seatsCount = 0;
var spaceBoundary = room.Boundary;
var config = OverrideUtilities.MatchApplicableOverride(
overridesBySpaceBoundaryId,
OverrideUtilities.GetSpaceBoundaryProxy(room, meetingRmBoundaryProxies),
new SpaceSettingsValue(false, false),
proxies);
var selectedConfigs = FlippedConfigurations.GetConfigs(config.Value.PrimaryAxisFlipLayout, config.Value.SecondaryAxisFlipLayout);

var levelInvertedTransform = levelVolume?.Transform.Inverted() ?? new Transform();
var roomWallCandidatesLines = WallGeneration.FindWallCandidates(room, levelVolume?.Profile, corridorSegments, out Line orientationGuideEdge)
.Select(c => (c.line.TransformedLine(levelInvertedTransform), c.type));
Expand All @@ -91,7 +91,7 @@ public static ClassroomLayoutOutputs Execute(Dictionary<string, Model> inputMode
var trimmedGeo = cell.GetTrimmedCellGeometry();
if (!cell.IsTrimmed() && trimmedGeo.Count() > 0)
{
var componentInstance = InstantiateLayout(configs, width, depth, rect, room.Transform);
var componentInstance = InstantiateLayout(selectedConfigs, width, depth, rect, room.Transform);
LayoutStrategies.SetLevelVolume(componentInstance, levelVolume?.Id);
output.Model.AddElement(componentInstance);
}
Expand All @@ -101,18 +101,32 @@ public static ClassroomLayoutOutputs Execute(Dictionary<string, Model> inputMode
var cinchedVertices = rect.Vertices.Select(v => largestTrimmedShape.Vertices.OrderBy(v2 => v2.DistanceTo(v)).First()).ToList();
var cinchedPoly = new Polygon(cinchedVertices);

var componentInstance = InstantiateLayout(configs, width, depth, cinchedPoly, room.Transform);
var componentInstance = InstantiateLayout(selectedConfigs, width, depth, cinchedPoly, room.Transform);
LayoutStrategies.SetLevelVolume(componentInstance, levelVolume?.Id);
output.Model.AddElement(componentInstance);
}
try
{
if (cell.U.Curve.Length() > 5.6)
{
cell.U.SplitAtOffset(2.3, false, true);
var deskConfig = selectedConfigs["Desk"];
string[] countableSeats = new[] { "Steelcase Turnstone - Shortcut X Base - Chair - Chair",
"Steelcase Turnstone - Shortcut - Stool - Chair" };
foreach (var item in deskConfig.ContentItems)
{
foreach (var countableSeat in countableSeats)
{
if (item.ContentElement.Name != null && item.ContentElement.Name.Contains(countableSeat))
{
seatsAtDesk++;
}
}
}

cell.U.SplitAtOffset(2.3, config.Value.SecondaryAxisFlipLayout, true);
cell.V.SplitAtOffset(0.5, false, true);
cell.V.SplitAtOffset(0.5, true, true);
var classroomSide = cell[1, 1];
var classroomSide = cell[config.Value.SecondaryAxisFlipLayout ? 0 : 1, 1];
classroomSide.U.DivideByFixedLength(deskConfig.Width, FixedDivisionMode.RemainderAtBothEnds);
classroomSide.V.DivideByFixedLength(deskConfig.Depth, FixedDivisionMode.RemainderAtBothEnds);
foreach (var individualDesk in classroomSide.GetCells())
Expand Down
Loading
Loading