コード例 #1
0
        public static List <IEnergyPlusClass> ToEnergyPlus(this BHE.Opening opening, string hostName)
        {
            List <IEnergyPlusClass> classes = new List <IEnergyPlusClass>();

            FenestrationSurfaceDetailed fenestrationSurfaceDetailed = new FenestrationSurfaceDetailed();

            fenestrationSurfaceDetailed.Name                = opening.Name == "" ? opening.BHoM_Guid.ToString() : opening.Name;
            fenestrationSurfaceDetailed.SurfaceType         = opening.Type.ToEnergyPlus();
            fenestrationSurfaceDetailed.ConstructionName    = opening.OpeningConstruction.Name;
            fenestrationSurfaceDetailed.BuildingSurfaceName = hostName;

            List <Point> vertices = BH.Engine.Environment.Query.Polyline(opening).ControlPoints();

            vertices.RemoveAt(vertices.Count - 1);
            vertices.Reverse();
            fenestrationSurfaceDetailed.Vertices         = vertices;
            fenestrationSurfaceDetailed.NumberOfVertices = vertices.Count;

            List <IEnergyPlusClass> materialsAndConstruction = ((Construction)opening.OpeningConstruction).ToEnergyPlus();

            classes.Add(fenestrationSurfaceDetailed);
            classes.AddRange(materialsAndConstruction);

            return(classes);
        }
コード例 #2
0
        public static global::OpenStudio.SubSurface ToOSM(this BHE.Opening opening, global::OpenStudio.Surface hostSurface, global::OpenStudio.Construction construction, global::OpenStudio.Model referenceModel)
        {
            Point3dVector openingPts = opening.Polyline().IDiscontinuityPoints().ToOSM();
            SubSurface    osmOpening = new SubSurface(openingPts, referenceModel);

            osmOpening.setSubSurfaceType(opening.Type.ToOSMFenestrationType());

            osmOpening.setSurface(hostSurface);
            osmOpening.setConstruction(construction);

            double oA = osmOpening.azimuth();
            double hA = hostSurface.azimuth();

            if (oA != hA)
            {
                osmOpening.setName("NOT EQUAL AZIMUTH - " + osmOpening.name());
            }

            if (osmOpening.azimuth() < (hostSurface.azimuth() - 1) || osmOpening.azimuth() > (hostSurface.azimuth() + 1))
            {
                osmOpening.setVertices(opening.Polyline().IFlip().ICollapseToPolyline(BHG.Tolerance.Angle).ToOSM());
            }

            return(osmOpening);
        }
コード例 #3
0
ファイル: Opening.cs プロジェクト: MajaLindroth/XML_Toolkit
        public static BHE.Opening ToBHoM(this BHX.Opening gbOpening)
        {
            BHE.Opening opening = new BHE.Opening();

            BHG.Polyline pLine = gbOpening.PlanarGeometry.PolyLoop.ToBHoM();
            opening.Edges = pLine.ToEdges();

            string[] cadSplit = gbOpening.CADObjectID.Split('[');
            if (cadSplit.Length > 0)
            {
                opening.Name = cadSplit[0].Trim();
            }
            if (cadSplit.Length > 1)
            {
                BHP.OriginContextFragment envContext = new BHP.OriginContextFragment();
                envContext.ElementID = cadSplit[1].Split(']')[0].Trim();
                envContext.TypeName  = opening.Name;

                if (opening.Fragments == null)
                {
                    opening.Fragments = new List <IBHoMFragment>();
                }
                opening.Fragments.Add(envContext);
            }

            opening.Type = gbOpening.OpeningType.ToBHoMOpeningType();

            return(opening);
        }
コード例 #4
0
        /***************************************************/

        public static string CADObjectID(this BHE.Opening opening)
        {
            BHP.OriginContextFragment contextProp = opening.FindFragment <BHP.OriginContextFragment>(typeof(BHP.OriginContextFragment));
            if (contextProp == null)
            {
                return("WinInst: SIM_EXT_GLZ [000000]");
            }

            string cadID = "";

            if (contextProp.TypeName == "")
            {
                cadID += "WinInst: SIM_EXT_GLZ";
            }
            else
            {
                cadID += contextProp.TypeName;
            }

            cadID += " [";

            if (contextProp.ElementID == "")
            {
                cadID += "000000";
            }
            else
            {
                cadID += contextProp.ElementID;
            }

            cadID += "]";

            return(cadID);
        }
コード例 #5
0
ファイル: Opening.cs プロジェクト: MajaLindroth/XML_Toolkit
        public static BHX.Opening ToGBXML(this BHE.Opening opening, List <BHE.Panel> space)
        {
            BHX.Opening gbOpening = opening.ToGBXML();

            BHG.Polyline pLine = opening.Polyline();
            if (pLine.NormalAwayFromSpace(space))
            {
                gbOpening.PlanarGeometry.PolyLoop = pLine.Flip().ToGBXML();
            }

            BHP.OriginContextFragment contextProperties = opening.FindFragment <BHP.OriginContextFragment>(typeof(BHP.OriginContextFragment));

            if (contextProperties != null)
            {
                string elementID  = contextProperties.ElementID;
                string familyName = contextProperties.TypeName;

                gbOpening.CADObjectID = opening.CADObjectID();
                gbOpening.OpeningType = opening.Type.ToGBXML();

                if (familyName == "System Panel") //No SAM_BuildingElementType for this one atm
                {
                    gbOpening.OpeningType = "FixedWindow";
                }

                if (gbOpening.OpeningType.Contains("Window") && opening.OpeningConstruction.Name.Contains("SLD")) //Change windows with SLD construction into doors
                {
                    gbOpening.OpeningType = "NonSlidingDoor";
                }
            }

            return(gbOpening);
        }
コード例 #6
0
        public static BHE.Panel OffsetOpening(BHE.Panel panel)
        {
            BHE.Panel energyPlusPanel = new BHE.Panel();
            //Checking if there are openings
            if (panel.Openings.Count == 0)
            {
                return(panel);
            }
            else
            {
                //OpeningArea
                List <BHE.Opening> openings          = panel.Openings;
                List <double>      openingAreas      = new List <double>();
                List <PolyCurve>   openingPolyCurves = new List <PolyCurve>();
                foreach (BHE.Opening opening in panel.Openings)
                {
                    List <ICurve> openingCrvs    = opening.Edges.Select(x => x.Curve).ToList();
                    PolyCurve     openingOutline = BH.Engine.Geometry.Create.PolyCurve(openingCrvs);
                    double        openingArea    = openingOutline.Area();
                    openingAreas.Add(openingArea);
                    openingPolyCurves.Add(openingOutline);
                }
                double totalOpeningArea = openingAreas.Sum();

                //PanelArea
                List <ICurve> panelCrvs    = panel.ExternalEdges.Select(x => x.Curve).ToList();
                PolyCurve     panelOutline = BH.Engine.Geometry.Create.PolyCurve(panelCrvs);
                double        panelArea    = panelOutline.Area();

                //Comparing the total opening area to the panel area, if equal: reduce the area of the opening(s).
                if (totalOpeningArea != panelArea)
                {
                    return(panel);
                }
                else
                {
                    List <BH.oM.Geometry.Polyline>         openingPolylines = new List <BH.oM.Geometry.Polyline>();
                    List <List <BH.oM.Geometry.Polyline> > offsetPolylines  = new List <List <BH.oM.Geometry.Polyline> >();
                    List <BHE.Opening> newOpenings = new List <BHE.Opening>();
                    double             distance    = new double();
                    distance = -0.01;
                    panel.Openings.Clear();
                    foreach (BH.oM.Geometry.PolyCurve openingPolyCurve in openingPolyCurves)
                    {
                        List <BH.oM.Geometry.Point> polyPoints      = openingPolyCurve.IDiscontinuityPoints();
                        BH.oM.Geometry.Polyline     openingPolyLine = BH.Engine.Geometry.Create.Polyline(polyPoints);
                        Polyline        offsetPolyline = Geometry.Modify.Offset(openingPolyLine, distance);
                        List <BHE.Edge> edges          = offsetPolyline.ToEdges().ToList();
                        BHE.Opening     newOpening     = new BHE.Opening()
                        {
                            Edges = edges
                        };
                        panel.Openings.Add(newOpening);
                    }
                    return(panel);
                }
            }
        }
コード例 #7
0
ファイル: Opening.cs プロジェクト: BHoM/TAS_Toolkit
        public static TBD.buildingElement ToTAS(this BHE.Opening opening, TBD.buildingElement tbdBuildingElement, TBD.Construction tbdConstruction)
        {
            BHE.Panel openingAsElement = new BHE.Panel();
            openingAsElement.ExternalEdges = new List <BHE.Edge>(opening.Edges);
            openingAsElement.Fragments     = opening.Fragments;
            openingAsElement.BHoM_Guid     = opening.BHoM_Guid;
            openingAsElement.Name          = opening.Name;

            tbdBuildingElement = openingAsElement.ToTAS(tbdBuildingElement, tbdConstruction);

            return(tbdBuildingElement);
        }
コード例 #8
0
ファイル: Opening.cs プロジェクト: MajaLindroth/XML_Toolkit
        public static BHX.Opening ToGBXML(this BHE.Opening opening)
        {
            BHX.Opening gbOpening = new BHX.Opening();

            BHG.Polyline pLine = opening.Polyline();

            gbOpening.Name = opening.Name;
            gbOpening.ID   = "opening" + opening.BHoM_Guid.ToString().Replace("-", "").Substring(0, 5);
            gbOpening.PlanarGeometry.PolyLoop            = pLine.ToGBXML();
            gbOpening.PlanarGeometry.ID                  = "openingPGeom-" + Guid.NewGuid().ToString().Replace("-", "").Substring(0, 5);
            gbOpening.RectangularGeometry.CartesianPoint = Geometry.Query.Centre(pLine).ToGBXML();
            gbOpening.RectangularGeometry.Height         = Math.Round(opening.Height(), 3);
            //TODO: temporary solution to get valid file to be replaced with correct height
            if (opening.Height() == 0)
            {
                gbOpening.RectangularGeometry.Height = 0.1;
            }
            gbOpening.RectangularGeometry.Width = Math.Round(opening.Width(), 3);
            //if (opening.Width() == 0)
            //    gbOpening.RectangularGeometry.Width = 0.1;
            gbOpening.RectangularGeometry.ID = "rGeomOpening-" + Guid.NewGuid().ToString().Replace("-", "").Substring(0, 5);

            return(gbOpening);
        }
コード例 #9
0
        /***************************************************/
        /**** Public Methods                            ****/
        /***************************************************/

        public static void SerializeCollection(IEnumerable <IEnumerable <Panel> > inputElements, List <Level> levels, List <Panel> openings, BH.oM.XML.GBXML gbx, XMLSettings settings)
        {
            List <List <Panel> > elementsAsSpaces = new List <List <Panel> >();

            foreach (IEnumerable <Panel> input in inputElements)
            {
                elementsAsSpaces.Add(input.ToList());
            }

            List <Panel> uniqueBuildingElements = elementsAsSpaces.UniquePanels();

            List <Panel> allElements = new List <Panel>(uniqueBuildingElements);

            allElements.AddRange(openings);

            //List<BH.oM.Environment.Elements.Space> spaces = elementsAsSpaces.Spaces();

            List <Panel> usedBEs = new List <Panel>();

            List <BH.oM.XML.Construction> usedConstructions = new List <BH.oM.XML.Construction>();
            List <BH.oM.XML.Material>     usedMaterials     = new List <Material>();
            List <BH.oM.XML.Layer>        usedLayers        = new List <Layer>();
            List <string> usedSpaceNames            = new List <string>();
            List <BH.oM.XML.WindowType> usedWindows = new List <WindowType>();

            foreach (List <Panel> space in elementsAsSpaces)
            {
                //For each collection of BuildingElements that define a space, convert the panels to XML surfaces and add to the GBXML
                List <Surface> spaceSurfaces = new List <Surface>();

                for (int x = 0; x < space.Count; x++)
                {
                    if (usedBEs.Where(i => i.BHoM_Guid == space[x].BHoM_Guid).FirstOrDefault() != null)
                    {
                        continue;
                    }

                    //Fix panel type
                    //if(space[x].Type == PanelType.WallExternal && space[x].ConnectedSpaces.Count == 2)
                    //space[x].Type = PanelType.WallInternal;

                    BHP.OriginContextFragment envContextProperties = space[x].FindFragment <BHP.OriginContextFragment>(typeof(BHP.OriginContextFragment));

                    List <List <Panel> > adjacentSpaces = BH.Engine.Environment.Query.AdjacentSpaces(space[x], elementsAsSpaces);

                    Surface srf = space[x].ToGBXML(adjacentSpaces, space);
                    srf.ID   = "Panel-" + gbx.Campus.Surface.Count.ToString().Replace(" ", "").Replace("-", "");
                    srf.Name = "Panel" + gbx.Campus.Surface.Count.ToString().Replace(" ", "").Replace("-", "");

                    if (space[x] != null)
                    {
                        srf.CADObjectID = BH.Engine.XML.Query.CADObjectID(space[x], settings.ReplaceCurtainWalls);
                    }

                    if (settings.IncludeConstructions)
                    {
                        srf.ConstructionIDRef = (envContextProperties != null ? envContextProperties.TypeName.CleanName() : space[x].ConstructionID());
                    }
                    else
                    {
                        srf.ConstructionIDRef = null;
                    }

                    if (settings.ReplaceCurtainWalls)
                    {
                        //If the surface is a basic Wall: SIM_EXT_GLZ so Curtain Wall after CADObjectID translation add the wall as an opening
                        if (srf.CADObjectID.Contains("Curtain") && srf.CADObjectID.Contains("GLZ"))
                        {
                            List <BHG.Polyline> newOpeningBounds = new List <oM.Geometry.Polyline>();
                            if (space[x].Openings.Count > 0)
                            {
                                //This surface already has openings - cut them out of the new opening
                                List <BHG.Polyline> refRegion = space[x].Openings.Where(y => y.Polyline() != null).ToList().Select(z => z.Polyline()).ToList();
                                newOpeningBounds.AddRange((new List <BHG.Polyline> {
                                    space[x].Polyline()
                                }).BooleanDifference(refRegion, 0.01));
                            }
                            else
                            {
                                newOpeningBounds.Add(space[x].Polyline());
                            }

                            BH.oM.Environment.Elements.Opening curtainWallOpening = BH.Engine.Environment.Create.Opening(externalEdges: newOpeningBounds.ToEdges());
                            curtainWallOpening.Name = space[x].Name;
                            BHP.OriginContextFragment curtainWallProperties = new BHP.OriginContextFragment();
                            if (envContextProperties != null)
                            {
                                curtainWallProperties.ElementID = envContextProperties.ElementID;
                                curtainWallProperties.TypeName  = envContextProperties.TypeName;
                            }

                            curtainWallOpening.Type = OpeningType.CurtainWall;
                            curtainWallOpening.OpeningConstruction = space[x].Construction;

                            curtainWallOpening.Fragments.Add(curtainWallProperties);

                            space[x].Openings.Add(curtainWallOpening);

                            //Update the host elements element type
                            srf.SurfaceType  = (adjacentSpaces.Count == 1 ? PanelType.WallExternal : PanelType.WallInternal).ToGBXML();
                            srf.ExposedToSun = BH.Engine.XML.Query.ExposedToSun(srf.SurfaceType).ToString().ToLower();
                        }
                    }
                    else
                    {
                        //Fix surface type for curtain walls
                        if (space[x].Type == PanelType.CurtainWall)
                        {
                            srf.SurfaceType  = (adjacentSpaces.Count == 1 ? PanelType.WallExternal : PanelType.WallInternal).ToGBXML();
                            srf.ExposedToSun = BH.Engine.XML.Query.ExposedToSun(srf.SurfaceType).ToString().ToLower();
                        }
                    }

                    if (settings.FixIncorrectAirTypes && space[x].Type == PanelType.Undefined && space[x].ConnectedSpaces.Count == 1)
                    {
                        //Fix external air types
                        if (space[x].Tilt() == 0)
                        {
                            srf.SurfaceType = PanelType.Roof.ToGBXML();
                        }
                        else if (space[x].Tilt() == 90)
                        {
                            srf.SurfaceType = PanelType.WallExternal.ToGBXML();
                        }
                        else if (space[x].Tilt() == 180)
                        {
                            srf.SurfaceType = PanelType.SlabOnGrade.ToGBXML();
                        }
                    }

                    //Openings
                    if (space[x].Openings.Count > 0)
                    {
                        srf.Opening = SerializeOpenings(space[x].Openings, space, allElements, elementsAsSpaces, gbx, settings).ToArray();
                        foreach (BH.oM.Environment.Elements.Opening o in space[x].Openings)
                        {
                            string nameCheck = "";

                            BHP.OriginContextFragment openingEnvContextProperties = o.FindFragment <BHP.OriginContextFragment>(typeof(BHP.OriginContextFragment));

                            if (openingEnvContextProperties != null)
                            {
                                nameCheck = openingEnvContextProperties.TypeName;
                            }
                            else if (o.OpeningConstruction != null)
                            {
                                nameCheck = o.OpeningConstruction.Name;
                            }

                            var t = usedWindows.Where(a => a.Name == nameCheck).FirstOrDefault();
                            if (t == null && o.OpeningConstruction != null)
                            {
                                usedWindows.Add(o.OpeningConstruction.ToGBXMLWindow(o));
                            }
                        }
                    }

                    gbx.Campus.Surface.Add(srf);

                    usedBEs.Add(space[x]);

                    if (settings.IncludeConstructions && space[x].Construction != null)
                    {
                        BH.oM.XML.Construction conc = space[x].ToGBXMLConstruction();
                        BH.oM.XML.Construction test = usedConstructions.Where(y => y.ID == conc.ID).FirstOrDefault();
                        if (test == null)
                        {
                            List <BH.oM.XML.Material> materials    = new List <Material>();
                            BHC.Construction          construction = space[x].Construction as BHC.Construction;

                            foreach (BHC.Layer l in construction.Layers)
                            {
                                materials.Add(l.ToGBXML());
                            }

                            BH.oM.XML.Layer layer = materials.ToGBXML();
                            conc.LayerID.LayerIDRef = layer.ID;

                            usedConstructions.Add(conc);

                            if (usedLayers.Where(y => y.ID == layer.ID).FirstOrDefault() == null)
                            {
                                usedLayers.Add(layer);
                            }

                            foreach (BH.oM.XML.Material mat in materials)
                            {
                                if (usedMaterials.Where(y => y.ID == mat.ID).FirstOrDefault() == null)
                                {
                                    usedMaterials.Add(mat);
                                }
                            }
                        }
                    }
                }

                BH.oM.XML.Space xmlSpace = new oM.XML.Space();
                xmlSpace.Name        = space.ConnectedSpaceName();
                xmlSpace.ID          = "Space" + xmlSpace.Name.Replace(" ", "").Replace("-", "");
                xmlSpace.CADObjectID = BH.Engine.XML.Query.CADObjectID(space);
                xmlSpace.ShellGeometry.ClosedShell.PolyLoop = BH.Engine.XML.Query.ClosedShellGeometry(space).ToArray();
                xmlSpace.ShellGeometry.ID  = "SpaceShellGeometry-" + Guid.NewGuid().ToString().Replace("-", "").Substring(0, 10);
                xmlSpace.SpaceBoundary     = BH.Engine.XML.Query.SpaceBoundaries(space, uniqueBuildingElements);
                xmlSpace.PlanarGeoemtry.ID = "SpacePlanarGeometry-" + Guid.NewGuid().ToString().Replace("-", "").Substring(0, 10);
                if (BH.Engine.Environment.Query.FloorGeometry(space) != null)
                {
                    xmlSpace.PlanarGeoemtry.PolyLoop = BH.Engine.XML.Convert.ToGBXML(BH.Engine.Environment.Query.FloorGeometry(space));
                    xmlSpace.Area   = BH.Engine.Environment.Query.FloorGeometry(space).Area();
                    xmlSpace.Volume = space.Volume();
                }
                Level spaceLevel = space.Level(levels);
                if (spaceLevel != null)
                {
                    string levelName = "";
                    if (spaceLevel.Name == "")
                    {
                        levelName = spaceLevel.Elevation.ToString();
                    }
                    else
                    {
                        levelName = spaceLevel.Name;
                    }

                    xmlSpace.BuildingStoreyIDRef = "Level-" + levelName.Replace(" ", "").ToLower();
                }

                gbx.Campus.Building[0].Space.Add(xmlSpace);

                usedSpaceNames.Add(xmlSpace.Name);
            }

            //Reorder the spaces
            gbx.Campus.Building[0].Space = gbx.Campus.Building[0].Space.OrderBy(x => x.Name).ToList();

            gbx.Construction = usedConstructions.ToArray();
            gbx.Layer        = usedLayers.ToArray();
            gbx.Material     = usedMaterials.ToArray();

            if (settings.IncludeConstructions)
            {
                gbx.WindowType = usedWindows.ToArray();
            }
            else //We have to force null otherwise WindowType will be created
            {
                gbx.WindowType = null;
            }

            //Set the building area
            List <Panel> floorElements = allElements.Where(x => x.Type == PanelType.Floor || x.Type == PanelType.FloorExposed || x.Type == PanelType.FloorInternal || x.Type == PanelType.FloorRaised || x.Type == PanelType.SlabOnGrade || x.Type == PanelType.UndergroundSlab).ToList();

            double buildingFloorArea = 0;

            foreach (Panel be in floorElements)
            {
                buildingFloorArea += be.Area();
            }

            gbx.Campus.Building[0].Area = buildingFloorArea;
        }
コード例 #10
0
ファイル: Panel.cs プロジェクト: BHoM/XML_Toolkit
        public static BHX.Surface ToGBXML(this BHE.Panel element, GBXMLSettings settings, List <BHE.Panel> space = null)
        {
            BHE.Panel panel = element.DeepClone <BHE.Panel>();

            BHP.OriginContextFragment contextProperties = panel.FindFragment <BHP.OriginContextFragment>(typeof(BHP.OriginContextFragment));

            BHX.Surface surface = new BHX.Surface();

            string idName = "Panel-" + panel.BHoM_Guid.ToString().Replace(" ", "").Replace("-", "").Substring(0, 10);

            surface.ID   = idName;
            surface.Name = idName;

            surface.SurfaceType  = panel.Type.ToGBXML();
            surface.ExposedToSun = BH.Engine.Environment.Query.ExposedToSun(panel).ToString().ToLower();

            surface.CADObjectID = panel.CADObjectID(settings.ReplaceCurtainWalls);

            if (settings.IncludeConstructions)
            {
                surface.ConstructionIDRef = panel.ConstructionID();
            }
            else
            {
                surface.ConstructionIDRef = null;
            }

            BHX.RectangularGeometry geom       = panel.ToGBXMLGeometry(settings);
            BHX.PlanarGeometry      planarGeom = new BHX.PlanarGeometry();
            planarGeom.ID = "PlanarGeometry-" + Guid.NewGuid().ToString().Replace("-", "").Substring(0, 10);

            surface.RectangularGeometry = geom;

            BHG.Polyline pLine = panel.Polyline();
            if (space != null && panel.ConnectedSpaces[0] == space.ConnectedSpaceName() && !pLine.NormalAwayFromSpace(space, settings.PlanarTolerance))
            {
                pLine = pLine.Flip();
                surface.PlanarGeometry.PolyLoop     = pLine.ToGBXML(settings);
                surface.RectangularGeometry.Tilt    = Math.Round(pLine.Tilt(settings.AngleTolerance), settings.RoundingSettings.GeometryTilt);
                surface.RectangularGeometry.Azimuth = Math.Round(pLine.Azimuth(BHG.Vector.YAxis), settings.RoundingSettings.GeometryAzimuth);
            }
            planarGeom.PolyLoop = pLine.ToGBXML(settings);

            surface.PlanarGeometry = planarGeom;

            if (settings.ReplaceCurtainWalls)
            {
                //If the surface is a basic Wall: SIM_EXT_GLZ so Curtain Wall after CADObjectID translation add the wall as an opening
                if (surface.CADObjectID.Contains("Curtain") && surface.CADObjectID.Contains("GLZ"))
                {
                    List <BHG.Polyline> newOpeningBounds = new List <oM.Geometry.Polyline>();
                    if (panel.Openings.Count > 0)
                    {
                        //This surface already has openings - cut them out of the new opening
                        List <BHG.Polyline> refRegion = panel.Openings.Where(y => y.Polyline() != null).ToList().Select(z => z.Polyline()).ToList();

                        newOpeningBounds.AddRange(BH.Engine.Geometry.Triangulation.Compute.DelaunayTriangulation(panel.Polyline(), refRegion, conformingDelaunay: false));
                        BHG.Polyline outer     = panel.Polyline();
                        double       outerArea = panel.Area();
                        for (int z = 0; z > panel.Openings.Count; z++)
                        {
                            BHG.Polyline poly = outer.BooleanDifference(new List <BHG.Polyline> {
                                panel.Openings[z].Polyline()
                            })[0];
                            if (poly.Area() != outerArea)
                            {
                                panel.Openings[z].Edges = panel.Openings[z].Polyline().Offset(settings.OffsetDistance).ToEdges();
                            }
                        }
                    }
                    else
                    {
                        newOpeningBounds.Add(panel.Polyline());
                    }

                    foreach (BHG.Polyline b in newOpeningBounds)
                    {
                        BH.oM.Environment.Elements.Opening curtainWallOpening = new BHE.Opening()
                        {
                            Edges = b.ToEdges()
                        };
                        curtainWallOpening.Name = panel.Name;
                        BHP.OriginContextFragment curtainWallProperties = new BHP.OriginContextFragment();
                        if (contextProperties != null)
                        {
                            curtainWallProperties.ElementID = contextProperties.ElementID;
                            curtainWallProperties.TypeName  = contextProperties.TypeName;
                        }

                        curtainWallOpening.Type = BHE.OpeningType.CurtainWall;
                        curtainWallOpening.OpeningConstruction = panel.Construction;

                        curtainWallOpening.Fragments.Add(curtainWallProperties);

                        panel.Openings.Add(curtainWallOpening);
                    }
                    //Update the host elements element type
                    surface.SurfaceType  = (panel.ConnectedSpaces.Count == 1 ? BHE.PanelType.WallExternal : BHE.PanelType.WallInternal).ToGBXML();
                    surface.ExposedToSun = BH.Engine.Adapters.XML.Query.ExposedToSun(surface.SurfaceType).ToString().ToLower();
                }
            }
            else
            {
                //Fix surface type for curtain walls
                if (panel.Type == BHE.PanelType.CurtainWall)
                {
                    surface.SurfaceType  = (panel.ConnectedSpaces.Count == 1 ? BHE.PanelType.WallExternal : BHE.PanelType.WallInternal).ToGBXML();
                    surface.ExposedToSun = BH.Engine.Adapters.XML.Query.ExposedToSun(surface.SurfaceType).ToString().ToLower();
                }
            }

            if (settings.FixIncorrectAirTypes && panel.Type == BHE.PanelType.Undefined && panel.ConnectedSpaces.Count == 1)
            {
                //Fix external air types
                if (panel.Tilt(settings.AngleTolerance) == 0)
                {
                    surface.SurfaceType = BHE.PanelType.Roof.ToGBXML();
                }
                else if (panel.Tilt(settings.AngleTolerance) == 90)
                {
                    surface.SurfaceType = BHE.PanelType.WallExternal.ToGBXML();
                }
                else if (panel.Tilt(settings.AngleTolerance) == 180)
                {
                    surface.SurfaceType = BHE.PanelType.SlabOnGrade.ToGBXML();
                }
            }

            surface.Opening = new BHX.Opening[panel.Openings.Count];
            for (int x = 0; x < panel.Openings.Count; x++)
            {
                if (panel.Openings[x].Polyline().IControlPoints().Count != 0)
                {
                    surface.Opening[x] = panel.Openings[x].ToGBXML(panel, settings);
                }
            }

            List <BHX.AdjacentSpaceID> adjIDs = new List <BHX.AdjacentSpaceID>();

            foreach (string s in panel.ConnectedSpaces)
            {
                BHX.AdjacentSpaceID adjId = new BHX.AdjacentSpaceID();
                adjId.SpaceIDRef = "Space" + s.Replace(" ", "").Replace("-", "");
                adjIDs.Add(adjId);
            }
            surface.AdjacentSpaceID = adjIDs.ToArray();

            return(surface);
        }
コード例 #11
0
ファイル: Opening.cs プロジェクト: BHoM/TAS_Toolkit
 public static TBD.Polygon ToTAS(this BHE.Opening opening, TBD.Polygon tbdPolygon)
 {
     //TODO:Add properties for Opening
     tbdPolygon = opening.Polyline().ToTASPolygon(tbdPolygon);
     return(tbdPolygon);
 }
コード例 #12
0
ファイル: SAPExport.cs プロジェクト: BHoM/SAP_Toolkit
        public static SAPExport SAPExport(Zone dwelling, List <Space> spaces, List <Panel> panels, List <Panel> balconies, List <Polyline> baseCurves, List <Level> levels, List <BH.oM.Environment.Elements.Opening> frontDoors, double ceilingHeight, double ceilingVoidHeight, double externalWallHeight, double distanceTolerance = BH.oM.Geometry.Tolerance.Distance, double angleTolerance = BH.oM.Geometry.Tolerance.Angle, int crossVentTolerance = 45)
        {
            SAPExport sapExport = new SAPExport();

            levels = levels.OrderBy(x => x.Elevation).ToList(); // need to reorder the levels
            Polyline dwellingPerimeter = dwelling.Perimeter.ICollapseToPolyline(angleTolerance);

            #region General Dwelling Information
            sapExport.Name      = dwelling.Name;
            sapExport.Reference = dwelling.Reference;

            Output <List <List <IRegion> >, List <List <double> >, List <IRegion>, List <IRegion> > mappedRegions = BH.Engine.Environment.Compute.MapRegions(spaces.Select(x => x as IRegion).ToList(), new List <IRegion> {
                dwelling
            }, distanceTolerance, angleTolerance);
            List <Space> spacesInDwelling = mappedRegions.Item1[0].Cast <Space>().ToList();

            sapExport.WetRooms     = spacesInDwelling.Where(x => x.SpaceType == SpaceType.Bathroom).Count();
            sapExport.DwellingBeds = spacesInDwelling.Where(x => x.SpaceType == SpaceType.Bedroom).Count();

            BH.oM.Environment.Elements.Opening doorInDwelling = frontDoors.Where(x => dwellingPerimeter.IIsContaining(x.Bottom(distanceTolerance, angleTolerance))).FirstOrDefault();
            Space        space         = spaces.Where(x => x.Perimeter.IIsContaining(doorInDwelling.Bottom(distanceTolerance, angleTolerance).IControlPoints())).FirstOrDefault();
            List <Panel> panelsInSpace = panels.Where(x => x.ConnectedSpaces.Contains(space.Name)).ToList();
            if (!doorInDwelling.Polyline().NormalAwayFromSpace(panelsInSpace))
            {
                doorInDwelling.Edges = doorInDwelling.Polyline().Flip().ToEdges(); //Make sure the normal of the door is pointing away from its containing space
            }
            int orientation = System.Convert.ToInt32(doorInDwelling.Orientation(0, true).Value.ToDegree());
            sapExport.OrientationDegrees = orientation;
            sapExport.Orientation        = OrientationText.ToOrientationText(orientation);

            Polyline     baseCurve        = baseCurves.Where(y => y.ICurveIntersections(dwellingPerimeter).Count > 0).FirstOrDefault();
            List <Panel> panelsInDwelling = new List <Panel>();
            foreach (Space s in spacesInDwelling)
            {
                panelsInDwelling.AddRange(panels.Where(x => x.ConnectedSpaces.Contains(s.Name)).ToList());
            }

            List <Panel> wallPanels = panelsInDwelling.Where(x => (x.Type == PanelType.Wall || x.Type == PanelType.WallExternal || x.Type == PanelType.WallInternal) && x.Bottom().IControlPoints().Where(y => (y.IIsOnCurve(dwellingPerimeter))).Count() == x.Bottom().IControlPoints().Count()).ToList();
            wallPanels.FlipPanels();

            List <Panel> exteriorWalls = wallPanels.Where(y => y.Bottom().IControlPoints().Where(z => (z.IIsOnCurve(baseCurve))).Count() == y.Bottom().IControlPoints().Count()).ToList();

            List <int> orientations = wallPanels.Select(x =>
            {
                int orientationX = System.Convert.ToInt32(x.Orientation(0, true).Value.ToDegree());
                if (orientationX == 360)
                {
                    orientationX = 0;
                }
                return(orientationX);
            }).Distinct().ToList();

            List <int> wallOrientations = exteriorWalls.Select(x =>
            {
                int wallOrientation = System.Convert.ToInt32(x.Orientation(0, true).Value.ToDegree());
                if (wallOrientation == 360)
                {
                    wallOrientation = 0;
                }
                return(wallOrientation);
            }).Distinct().ToList();

            sapExport.ShelteredSides = orientations.Count - wallOrientations.Count;

            List <BH.oM.Environment.Elements.Opening> openings = panelsInDwelling.SelectMany(x => x.Openings).ToList();
            List <int> openingOrientations = openings.Select(x => System.Convert.ToInt32(x.Orientation(0, true).Value.ToDegree())).Distinct().ToList();

            string crossVent = "False"; //Default position is that there is no cross ventilation
            if (openingOrientations.Count > 1)
            {
                for (int i = 0; i < openingOrientations.Count; i++)
                {
                    for (int j = i + 1; j < openingOrientations.Count; j++)
                    {
                        if (openingOrientations[j] <= 180 && openingOrientations[i] == 360)
                        {
                            openingOrientations[i] = 0;
                        }

                        if (openingOrientations[j] == 360 && openingOrientations[i] <= 180)
                        {
                            openingOrientations[j] = 0;
                        }

                        int dif = Math.Abs(openingOrientations[i] - openingOrientations[j]);
                        if (dif <= 180 + crossVentTolerance && dif >= 180 - crossVentTolerance)
                        {
                            crossVent = "True";
                            break;
                        }
                    }
                }
            }

            sapExport.CrossVentilation = crossVent;
            #endregion

            double roomArea = spacesInDwelling.Select(y => y.Perimeter.IArea()).Sum();
            //Check if the sum of the space areas is equal to the dwelling area
            if (roomArea > dwellingPerimeter.IArea() + distanceTolerance || roomArea < dwellingPerimeter.IArea() - distanceTolerance)
            {
                BH.Engine.Base.Compute.RecordError($"The sum of internal space areas is not equal to the total dwelling area for dwelling {dwelling.Name}.");
            }

            sapExport.TotalArea = dwellingPerimeter.IArea();
            List <string> spacesToAdd         = new List <string>(); //To prevent adding the same space twice
            List <Space>  spacesToInvestigate = spacesInDwelling.Where(x => x.SpaceType == SpaceType.Lounge).ToList();

            while (spacesToInvestigate.Count > 0)
            {
                Space current = spacesToInvestigate[0];
                spacesToInvestigate.RemoveAt(0);
                spacesToAdd.Add(current.Name);

                List <string> spacesConnectedByAir = panels.Where(x => x.ConnectedSpaces.Contains(current.Name) && x.Type == PanelType.Air).SelectMany(x => x.ConnectedSpaces).Where(x => x != current.Name && !spacesToAdd.Contains(x)).Distinct().ToList();
                spacesToInvestigate.AddRange(spacesInDwelling.Where(x => spacesConnectedByAir.Contains(x.Name)));
            }

            spacesToAdd = spacesToAdd.Distinct().ToList();
            spacesToAdd.ForEach(x => sapExport.LivingArea += spacesInDwelling.Where(a => a.Name == x).First().Perimeter.IArea());
            sapExport.CoolingArea = spacesInDwelling.Where(y => y.SpaceType == SpaceType.Kitchen || y.SpaceType == SpaceType.Lounge || y.SpaceType == SpaceType.Bedroom).Select(y => y.Perimeter.IArea()).Sum();

            #region Calculate the external floor and roof area

            Level dwellingLevel = dwelling.RegionLevel(levels, distanceTolerance, angleTolerance);

            if (dwellingPerimeter.IsOnLevel(levels.First(), distanceTolerance))
            {
                foreach (Space s in spacesInDwelling)
                {
                    sapExport.ExternalFloorArea.Add(s.Perimeter.IArea());
                    sapExport.PartyFloor.Add(0);
                }
            }
            else
            {
                //Pull the space down to the level below, if the base curve of the level below does not contain the space then it is an overhang and counts towards external floor area
                Level           levelBelow      = levels[levels.IndexOf(dwellingLevel) - 1];
                List <Polyline> baseCurvesBelow = baseCurves.Where(y => y.IsOnLevel(levelBelow)).ToList();

                foreach (Space room in spacesInDwelling)
                {
                    Polyline roomClone = room.Perimeter.ICollapseToPolyline(angleTolerance).DeepClone();
                    roomClone.ControlPoints = roomClone.IControlPoints().Select(y => new Point {
                        X = y.X, Y = y.Y, Z = levelBelow.Elevation
                    }).ToList();                                                                                                                         //Pull the space down to the level below
                    List <Polyline> externalCurves = roomClone.BooleanDifference(baseCurvesBelow);
                    foreach (Polyline ln in externalCurves)
                    {
                        double value = 0;
                        if (ln != null)
                        {
                            double area = ln.Area();
                            if (area > 0)
                            {
                                value = area;
                            }
                        }

                        sapExport.ExternalFloorArea.Add(value);
                        sapExport.PartyFloor.Add(roomClone.Area() - value);
                    }

                    if (externalCurves.Count == 0)
                    {
                        sapExport.ExternalFloorArea.Add(0);
                        sapExport.PartyFloor.Add(roomClone.Area());
                    }
                }
            }

            Level        levelAbove         = null;
            List <Panel> shadesOnLevelAbove = new List <Panel>();
            if (dwellingPerimeter.IsOnLevel(levels.Last(), distanceTolerance))
            {
                foreach (Space s in spacesInDwelling)
                {
                    sapExport.ExternalRoofArea.Add(s.Perimeter.IArea());
                    sapExport.PartyRoof.Add(0);
                }
            }
            else
            {
                //Do the same as above, but for the roof
                levelAbove = levels[levels.IndexOf(dwellingLevel) + 1];
                List <Polyline> baseCurvesAbove = baseCurves.Where(y => y.IsOnLevel(levelAbove)).ToList();

                foreach (Space room in spacesInDwelling)
                {
                    Polyline roomClone = room.Perimeter.ICollapseToPolyline(angleTolerance).DeepClone();
                    roomClone.ControlPoints = roomClone.IControlPoints().Select(y => new Point {
                        X = y.X, Y = y.Y, Z = levelAbove.Elevation
                    }).ToList();                                                                                                                         //Pull the space down to the level below
                    List <Polyline> externalCurves = roomClone.BooleanDifference(baseCurvesAbove);
                    foreach (Polyline ln in externalCurves)
                    {
                        double value = 0;
                        if (ln != null)
                        {
                            double area = ln.Area();
                            if (area > 0)
                            {
                                value = area;
                            }
                        }

                        sapExport.ExternalRoofArea.Add(value);
                        sapExport.PartyRoof.Add(roomClone.Area() - value);
                    }

                    if (externalCurves.Count == 0)
                    {
                        sapExport.ExternalRoofArea.Add(0);
                        sapExport.PartyRoof.Add(roomClone.Area());
                    }
                }

                shadesOnLevelAbove = balconies.Where(x => x.Polyline().IsOnLevel(levelAbove, distanceTolerance)).ToList();
            }
            #endregion

            if (ceilingHeight + ceilingVoidHeight != externalWallHeight)
            {
                BH.Engine.Base.Compute.RecordError("The sum of ceilingHeight and ceilingVoidHeight is not equal to the external wall height");
            }

            sapExport.CeilingHeight      = ceilingHeight;
            sapExport.CeilingVoidHeight  = ceilingVoidHeight;
            sapExport.ExternalWallHeight = externalWallHeight;
            sapExport.ExternalWallLength = exteriorWalls.Select(x => x.Bottom().ILength()).Sum();

            List <bool>   wideOverhang     = new List <bool>();
            List <double> overhangRatio    = new List <double>();
            List <double> width            = new List <double>();
            List <double> height           = new List <double>();
            List <string> orientationTexts = new List <string>();

            for (int x = 0; x < openings.Count; x++)
            {
                BH.oM.Environment.Elements.Opening o = openings[x];

                wideOverhang.Add(false);
                overhangRatio.Add(0);
                width.Add(o.Width().ToMillimetre());
                height.Add(o.Height().ToMillimetre());
                orientationTexts.Add(OrientationText.ToOrientationText(o.Orientation(0, true).Value.ToDegree()));

                if (levelAbove != null)
                {
                    Point centre = o.Polyline().Centroid();
                    centre.Z = levelAbove.Elevation;
                    //Find a shade which intersects this opening
                    Panel shade = shadesOnLevelAbove.Where(y => y.IsContaining(centre, true)).FirstOrDefault();

                    if (shade != null)
                    {
                        List <Polyline> shadeParts = shade.Polyline().SplitAtPoints(shade.Polyline().IControlPoints());
                        List <double>   lengths    = shadeParts.Select(y => Math.Round(y.Length(), 3)).Distinct().ToList();

                        if (lengths.Max() > o.Width())
                        {
                            wideOverhang[wideOverhang.Count - 1] = true;
                        }

                        overhangRatio[overhangRatio.Count - 1] = (lengths.Min() / o.Height());
                    }
                }
            }

            sapExport.WindowLength      = width;
            sapExport.WindowHeight      = height;
            sapExport.WindowOrientation = orientationTexts;
            sapExport.WideOverhang      = wideOverhang;
            sapExport.OverhangRatio     = overhangRatio;

            return(sapExport);
        }
コード例 #13
0
ファイル: Opening.cs プロジェクト: BHoM/XML_Toolkit
        public static BHX.Opening ToGBXML(this BHE.Opening opening, BHE.Panel hostPanel, GBXMLSettings settings)
        {
            BHX.Opening gbOpening = new BHX.Opening();

            BHG.Polyline pLine = opening.Polyline();

            gbOpening.Name = opening.Name;
            gbOpening.ID   = "opening" + opening.BHoM_Guid.ToString().Replace("-", "").Substring(0, 5);
            gbOpening.PlanarGeometry.PolyLoop            = pLine.ToGBXML(settings);
            gbOpening.PlanarGeometry.ID                  = "openingPGeom-" + Guid.NewGuid().ToString().Replace("-", "").Substring(0, 5);
            gbOpening.RectangularGeometry.CartesianPoint = BH.Engine.Geometry.Query.Centroid(pLine).ToGBXML(settings);
            gbOpening.RectangularGeometry.Height         = Math.Round(opening.Height(), settings.RoundingSettings.GeometryHeight);
            //TODO: temporary solution to get valid file to be replaced with correct height
            if (opening.Height() == 0)
            {
                gbOpening.RectangularGeometry.Height = 0.1;
            }
            gbOpening.RectangularGeometry.Width = Math.Round(opening.Width(), settings.RoundingSettings.GeometryWidth);
            gbOpening.RectangularGeometry.ID    = "rGeomOpening-" + Guid.NewGuid().ToString().Replace("-", "").Substring(0, 5);

            pLine = pLine.CleanPolyline(minimumSegmentLength: settings.DistanceTolerance);
            double openingArea = pLine.Area();
            double panelArea   = hostPanel.Polyline().Area();

            if (openingArea >= panelArea)
            {
                pLine = BH.Engine.Geometry.Modify.Offset(pLine, settings.OffsetDistance);

                if (pLine == null)
                {
                    pLine = opening.Polyline(); //Reset the polyline if something went wrong with the offset
                }
                gbOpening.PlanarGeometry.PolyLoop = pLine.ToGBXML(settings);
            }

            //Normals away from space
            //if (!BH.Engine.Environment.Query.NormalAwayFromSpace(pLine, hostSpace, settings.PlanarTolerance))
            //gbOpening.PlanarGeometry.PolyLoop = pLine.Flip().ToGBXML();

            gbOpening.CADObjectID = opening.CADObjectID();
            gbOpening.OpeningType = opening.Type.ToGBXML();

            BHP.OriginContextFragment contextProperties = opening.FindFragment <BHP.OriginContextFragment>(typeof(BHP.OriginContextFragment));
            string elementID  = "";
            string familyName = "";

            if (contextProperties != null)
            {
                elementID  = contextProperties.ElementID;
                familyName = contextProperties.TypeName;
            }

            if (gbOpening.OpeningType.ToLower() == "fixedwindow" && contextProperties != null && contextProperties.TypeName.ToLower().Contains("skylight"))
            {
                gbOpening.OpeningType = "FixedSkylight";
            }

            if (familyName == "System Panel") //No SAM_BuildingElementType for this one atm
            {
                gbOpening.OpeningType = "FixedWindow";
            }

            if (settings.ReplaceSolidOpeningsIntoDoors && gbOpening.OpeningType.Contains("Window") && (opening.OpeningConstruction != null && opening.OpeningConstruction.Name.Contains("SLD"))) //Change windows with SLD construction into doors for IES
            {
                gbOpening.OpeningType = "NonSlidingDoor";
            }

            if (settings.IncludeConstructions)
            {
                gbOpening.WindowTypeIDRef = "window-" + (contextProperties != null ? contextProperties.TypeName.CleanName() : (opening.OpeningConstruction != null ? opening.OpeningConstruction.Name.CleanName() : ""));
            }
            else
            {
                gbOpening.WindowTypeIDRef = null;
            }

            gbOpening.ConstructionIDRef = null; //ToDo review having this property on an opening?

            return(gbOpening);
        }
コード例 #14
0
        public static BHX.WindowType ToGBXMLWindow(this BHC.Construction construction, BHE.Opening opening)
        {
            BHX.WindowType window = new BHX.WindowType();

            BHP.PanelAnalyticalFragment extraProperties   = opening.FindFragment <BHP.PanelAnalyticalFragment>(typeof(BHP.PanelAnalyticalFragment));
            BHP.OriginContextFragment   contextProperties = opening.FindFragment <BHP.OriginContextFragment>(typeof(BHP.OriginContextFragment));

            window.ID                             = "window-" + (contextProperties == null ? construction.Name.CleanName() : contextProperties.TypeName.CleanName());
            window.Name                           = (contextProperties == null ? construction.Name : contextProperties.TypeName);
            window.UValue.Value                   = (extraProperties == null || extraProperties.UValue == 0 ? construction.UValue().ToString() : extraProperties.UValue.ToString());
            window.Transmittance.Value            = (extraProperties == null ? "0" : extraProperties.LTValue.ToString());
            window.SolarHeatGainCoefficient.Value = (extraProperties == null ? "0" : extraProperties.GValue.ToString());
            if (construction.Layers.Count > 0)
            {
                window.InternalGlaze = (construction.Layers[0]).ToGBXGlazed();
            }
            if (construction.Layers.Count > 1)
            {
                window.Gap = (construction.Layers[1]).ToGBXGap();
            }
            if (construction.Layers.Count > 2)
            {
                window.ExternalGlaze = (construction.Layers[2]).ToGBXGlazed();
            }

            return(window);
        }
コード例 #15
0
 public static BHX.WindowType ToGBXMLWindow(this BHC.IConstruction construction, BHE.Opening opening = null)
 {
     return(ToGBXMLWindow(construction as dynamic, opening));
 }
コード例 #16
0
ファイル: Panel.cs プロジェクト: BHoM/OpenStudio_Toolkit
        public static global::OpenStudio.Surface ToOSM(this BHE.Panel panel, global::OpenStudio.Model modelReference, global::OpenStudio.Space osmSpace, Dictionary <string, global::OpenStudio.Construction> uniqueConstructions, string outsideBoundaryCondition)
        {
            Surface osmElement = new Surface(panel.Polyline().ToOSM(), modelReference);

            osmElement.setName(panel.Name);
            osmElement.setSpace(osmSpace);
            if (outsideBoundaryCondition != "")
            {
                osmElement.setOutsideBoundaryCondition(outsideBoundaryCondition);
            }

            osmElement.setSurfaceType(panel.Type.ToOSMSurfaceType());
            osmElement.setConstruction(uniqueConstructions[panel.Construction.UniqueConstructionName()]);

            BHP.OriginContextFragment envContextProperties = panel.FindFragment <BHP.OriginContextFragment>(typeof(BHP.OriginContextFragment));

            //Fix curtain wall
            if (panel.Type == BHE.PanelType.CurtainWall)
            {
                osmElement.setConstruction(uniqueConstructions["CurtainWallReplacementConstruction"]); //No need for construction on a curtain wall as the opening will handle it

                List <BHG.Polyline> newOpeningBounds = new List <BHG.Polyline>();
                if (panel.Openings.Count > 0)
                {
                    //This surface already has openings - cut them out of the new opening
                    List <BHG.Polyline> refRegion = panel.Openings.Where(y => y.Polyline() != null).ToList().Select(z => z.Polyline()).ToList();
                    newOpeningBounds.AddRange((panel.Polyline().BooleanDifference(refRegion, 0.01)));
                }
                else
                {
                    newOpeningBounds.Add(panel.Polyline());
                }

                BHE.Opening curtainWallOpening = new BHE.Opening()
                {
                    Edges = BH.Engine.Geometry.Create.PolyCurve(newOpeningBounds).ICollapseToPolyline(BH.oM.Geometry.Tolerance.Angle).ToEdges()
                };

                //Scale the bounding curve to comply with IDF rules
                BHG.Polyline crv = curtainWallOpening.Polyline();
                curtainWallOpening.Edges = crv.Scale(crv.Centre(), BH.Engine.Geometry.Create.Vector(0.95, 0.95, 0.95)).ToEdges();

                curtainWallOpening.Name = panel.Name;
                BHP.OriginContextFragment curtainWallProperties = new BHP.OriginContextFragment();

                if (envContextProperties != null)
                {
                    curtainWallProperties.ElementID = envContextProperties.ElementID;
                    curtainWallProperties.TypeName  = envContextProperties.TypeName;
                }

                curtainWallOpening.Type = BHE.OpeningType.CurtainWall;
                curtainWallOpening.OpeningConstruction = panel.Construction;

                panel.Openings = new List <BHE.Opening> {
                    curtainWallOpening
                };
            }

            return(osmElement);
        }