/// <summary> /// Adds facade Panels to one or more Masses named 'envelope'. /// </summary> /// <param name="model">The model. /// Add elements to the model to have them persisted.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A FacadeOutputs instance containing computed results.</returns> public static FacadeByEnvelopeOutputs Execute(Dictionary <string, Model> models, FacadeByEnvelopeInputs input) { List <Envelope> envelopes; List <Level> levels = null; var model = new Model(); var envelopeModel = models[ENVELOPE_MODEL_NAME]; envelopes = envelopeModel.AllElementsOfType <Envelope>().Where(e => e.Elevation >= 0.0).ToList(); if (envelopes.Count() == 0) { throw new Exception("No element of type 'Envelope' could be found in the supplied model."); } var levelsModel = models[LEVELS_MODEL_NAME]; levels = levelsModel.AllElementsOfType <Level>().ToList(); if (levels.Count() == 0) { throw new Exception("No element of type 'Level' could be found in the supplied model."); } levels.Sort(new LevelComparer()); var panelCount = 0; var panelMat = new Material("envelope", new Color(1.0, 1.0, 1.0, 1), 0.5f, 0.5f); List <Level> envLevels = null; var wireframeMaterial = new Material("wireframe", new Color(0.5, 0.5, 0.5, 1.0)); foreach (var envelope in envelopes) { var boundarySegments = envelope.Profile.Perimeter.Segments(); Level last = null; if (envLevels != null) { // If levels don't correspond exactly with the change // in envelopes, then we need the last level of the previous // set to become the first level of the next set. last = envLevels.Last(); } envLevels = levels.Where(l => l.Elevation >= envelope.Elevation && l.Elevation <= envelope.Elevation + envelope.Height).ToList(); if (last != null) { envLevels.Insert(0, last); } for (var i = 0; i < envLevels.Count - 1; i++) { var level1 = envLevels[i]; var level2 = envLevels[i + 1]; foreach (var s in boundarySegments) { FacadePanel masterPanel = null; Panel masterGlazing = null; var d = s.Direction(); var bottomSegments = DivideByLengthFromCenter(s, input.PanelWidth); try { for (var j = 0; j < bottomSegments.Count(); j++) { var bs = bottomSegments[j]; var t = new Transform(bs.Start + new Vector3(0, 0, level1.Elevation), d, d.Cross(Vector3.ZAxis)); var l = bs.Length(); // If the segment width is within Epsilon of // the input panel width, then create a // panel with glazing. if (Math.Abs(l - input.PanelWidth) < Vector3.EPSILON) { if (masterPanel == null) { // Create a master panel for each level. // This panel will be instanced at every location. CreateFacadePanel($"FP_{i}", input.PanelWidth, level2.Elevation - level1.Elevation, input.GlassLeftRightInset, input.GlassTopBottomInset, 0.1, input.PanelWidth, panelMat, t, out masterPanel, out masterGlazing); model.AddElement(masterPanel); model.AddElement(masterGlazing); } // Create a panel instance. var panelInstance = masterPanel.CreateInstance(t, $"FP_{i}_{j}"); model.AddElement(panelInstance, false); var glazingInstance = masterGlazing.CreateInstance(t, $"FG_{i}_{j}"); model.AddElement(glazingInstance, false); } // Otherwise, create a panel with not glazing. else { CreateStandardPanel($"FP_{i}_{j}", l, level2.Elevation - level1.Elevation, 0.1, t, panelMat, out FacadePanel panel); model.AddElement(panel); } panelCount++; } if (i == envLevels.Count - 2) { var parapet = new StandardWall(new Line(new Vector3(s.Start.X, s.Start.Y, level2.Elevation), new Vector3(s.End.X, s.End.Y, level2.Elevation)), 0.1, 0.9, panelMat); model.AddElement(parapet); } } catch (Exception ex) { Console.WriteLine(ex); continue; } } } } var output = new FacadeByEnvelopeOutputs(panelCount); output.model = model; return(output); }
/// <summary> /// Adds facade Panels to one or more Masses named 'envelope'. /// </summary> /// <param name="model">The model. /// Add elements to the model to have them persisted.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A FacadeOutputs instance containing computed results.</returns> public static FacadeByEnvelopeOutputs Execute(Dictionary <string, Model> models, FacadeByEnvelopeInputs input) { List <Envelope> envelopes; List <Level> levels = null; var model = new Model(); var envelopeModel = models[ENVELOPE_MODEL_NAME]; envelopes = envelopeModel.AllElementsOfType <Envelope>().Where(e => e.Elevation >= 0.0).ToList(); if (envelopes.Count() == 0) { throw new Exception("No element of type 'Envelope' could be found in the supplied model."); } var levelsModel = models[LEVELS_MODEL_NAME]; levels = levelsModel.AllElementsOfType <Level>().ToList(); if (levels.Count() == 0) { throw new Exception("No element of type 'Level' could be found in the supplied model."); } levels.Sort(new LevelComparer()); List <Level> envLevels = null; var wireframeMaterial = new Material("wireframe", new Color(0.5, 0.5, 0.5, 1.0)); var panelCount = 0; foreach (var envelope in envelopes) { var boundarySegments = envelope.Profile.Perimeter.Segments(); Level last = null; if (envLevels != null) { // If levels don't correspond exactly with the change // in envelopes, then we need the last level of the previous // set to become the first level of the next set. last = envLevels.Last(); } envLevels = levels.Where(l => l.Elevation >= envelope.Elevation && l.Elevation <= envelope.Elevation + envelope.Height).ToList(); if (last != null) { envLevels.Insert(0, last); } panelCount = PanelLevels(envLevels, boundarySegments, input.PanelWidth, input.GlassLeftRightInset, input.GlassTopBottomInset, model, input.PanelColor); } var groundFloorEnvelope = envelopes.First(e => e.Elevation == 0.0); if (groundFloorEnvelope != null) { var boundarySegments = groundFloorEnvelope.Profile.Perimeter.Offset(-input.GroundFloorSetback)[0].Segments(); var groundLevels = levels.Where(l => l.Elevation >= groundFloorEnvelope.Elevation && l.Elevation <= groundFloorEnvelope.Elevation + groundFloorEnvelope.Height).ToList(); var bottom = groundLevels.First().Elevation; var top = groundLevels.Count > 1 ? groundLevels[1].Elevation : groundFloorEnvelope.Elevation + groundFloorEnvelope.Height; PanelGroundFloor(bottom, top, boundarySegments, input.PanelWidth, model); } var output = new FacadeByEnvelopeOutputs(panelCount); output.Model = model; return(output); }