/// <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);
        }
Beispiel #2
0
        /// <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);
        }