예제 #1
0
        /// <summary>
        /// The EnvelopeBySite function.
        /// </summary>
        /// <param name="model">The input model.</param>
        /// <param name="input">The arguments to the execution.</param>
        /// <returns>A EnvelopeBySiteOutputs instance containing computed results and the model with any new elements.</returns>
        public static EnvelopeBySiteOutputs Execute(Dictionary <string, Model> inputModels, EnvelopeBySiteInputs input)
        {
            // Retrieve site information from incoming models.
            var sites = new List <Site>();

            inputModels.TryGetValue("Site", out var model);
            if (model == null)
            {
                throw new ArgumentException("No Site found.");
            }
            sites.AddRange(model.AllElementsOfType <Site>());
            sites = sites.OrderByDescending(e => e.Perimeter.Area()).ToList();
            var output = new EnvelopeBySiteOutputs(input.BuildingHeight, input.FoundationDepth);

            foreach (var site in sites)
            {
                var perims = site.Perimeter.Offset(input.SiteSetback * -1);
                if (perims.Count() == 0)
                {
                    continue;
                }
                perims = perims.OrderByDescending(p => p.Area()).ToArray();
                var perimeter = perims.First();
                if (perimeter.Area() < input.MinimumTierArea)
                {
                    continue;
                }

                // Create the foundation Envelope.
                var extrude = new Elements.Geometry.Solids.Extrude(perimeter, input.FoundationDepth, Vector3.ZAxis, false);
                var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>()
                {
                    extrude
                });
                var fndMatl   = new Material("foundation", Palette.Gray, 0.0f, 0.0f);
                var envMatl   = new Material("envelope", Palette.Aqua, 0.0f, 0.0f);
                var envelopes = new List <Envelope>()
                {
                    new Envelope(perimeter, input.FoundationDepth * -1, input.FoundationDepth, Vector3.ZAxis,
                                 0.0, new Transform(0.0, 0.0, input.FoundationDepth * -1), fndMatl, geomRep, false, Guid.NewGuid(), "")
                };

                // Create the Envelope at the location's zero plane.
                var tiers      = Math.Floor(input.BuildingHeight / input.SetbackInterval);
                var tierHeight = tiers > 0 ? input.BuildingHeight / tiers : input.BuildingHeight;
                extrude = new Elements.Geometry.Solids.Extrude(perimeter, tierHeight, Vector3.ZAxis, false);
                geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>()
                {
                    extrude
                });
                envelopes.Add(new Envelope(perimeter, 0.0, tierHeight, Vector3.ZAxis, 0.0,
                                           new Transform(), envMatl, geomRep, false, Guid.NewGuid(), ""));

                // Create the remaining Envelope Elements.
                var offsFactor = -1;
                var elevFactor = 1;
                for (int i = 0; i < tiers; i++)
                {
                    var tryPer = perimeter.Offset(input.SetbackDepth * offsFactor);
                    if (tryPer.Count() == 0 || tryPer.First().Area() < input.MinimumTierArea)
                    {
                        break;
                    }
                    tryPer  = tryPer.OrderByDescending(p => p.Area()).ToArray();
                    extrude = new Elements.Geometry.Solids.Extrude(tryPer.First(), tierHeight, Vector3.ZAxis, false);
                    geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>()
                    {
                        extrude
                    });
                    envelopes.Add(new Envelope(tryPer.First(), tierHeight * elevFactor, tierHeight, Vector3.ZAxis, 0.0,
                                               new Transform(0.0, 0.0, tierHeight * elevFactor), envMatl, geomRep, false, Guid.NewGuid(), ""));
                    offsFactor--;
                    elevFactor++;
                }
                envelopes = envelopes.OrderBy(e => e.Elevation).ToList();
                foreach (var item in envelopes)
                {
                    output.Model.AddElement(item);
                }
            }
            return(output);
        }