Esempio n. 1
0
        public static double HydraulicDiameter(this Face3D face3D, double tolerance = Core.Tolerance.Distance)
        {
            Plane plane_Face3D = face3D?.GetPlane();

            if (plane_Face3D == null)
            {
                return(double.NaN);
            }
            Plane plane = Plane.WorldXY;

            if (plane.Perpendicular(plane_Face3D, tolerance))
            {
                return(0);
            }

            Face3D face3D_Project = plane.Project(face3D);

            if (face3D_Project == null || !face3D_Project.IsValid())
            {
                return(0);
            }

            Planar.ISegmentable2D segmentable2D = face3D_Project.ExternalEdge2D as Planar.ISegmentable2D;
            if (segmentable2D == null)
            {
                throw new System.NotImplementedException();
            }

            double area = face3D_Project.GetArea();

            if (area <= tolerance)
            {
                return(0);
            }

            //return (4 * area) / segmentable2D.GetLength();
            return(segmentable2D.GetLength());
        }
Esempio n. 2
0
        public static Building TogbXML(this AdjacencyCluster adjacencyCluster, string name, string description, double tolerance = Tolerance.MicroDistance)
        {
            List <Panel> panels = adjacencyCluster?.GetPanels();

            if (panels == null || panels.Count == 0)
            {
                return(null);
            }

            List <Space> spaces = adjacencyCluster.GetSpaces();

            if (spaces == null)
            {
                return(null);
            }

            //Dictionary of Minimal Elevations and List of Panels
            Dictionary <double, List <Panel> > dictionary_MinElevations = Analytical.Query.MinElevationDictionary(panels, true, Tolerance.MacroDistance);

            //Dictionary of gbXML BuildingStoreys and its elevations
            Dictionary <BuildingStorey, double> dictionary_buildingStoreys = new Dictionary <BuildingStorey, double>();

            //Dictionary of SAM Panels related buildingSorey, minimal elevation and maximal elevation
            Dictionary <Panel, Tuple <BuildingStorey, double, double, double> > dictionary_Panels = new Dictionary <Panel, Tuple <BuildingStorey, double, double, double> >();

            foreach (KeyValuePair <double, List <Panel> > keyValuePair in dictionary_MinElevations)
            {
                BuildingStorey buildingStorey = Architectural.Create.Level(keyValuePair.Key).TogbXML(tolerance);
                dictionary_buildingStoreys[buildingStorey] = keyValuePair.Key;
                foreach (Panel panel in keyValuePair.Value)
                {
                    dictionary_Panels[panel] = new Tuple <BuildingStorey, double, double, double> (buildingStorey, keyValuePair.Key, panel.MinElevation(), panel.MaxElevation());
                }
            }

            List <gbXMLSerializer.Space>     spaces_gbXML = new List <gbXMLSerializer.Space>();
            Dictionary <Guid, SpaceBoundary> dictionary   = new Dictionary <Guid, SpaceBoundary>();

            foreach (Space space in spaces)
            {
                List <Panel> panels_Space = adjacencyCluster.GetRelatedObjects <Panel>(space);
                if (panels_Space == null || panels_Space.Count == 0)
                {
                    continue;
                }

                double         elevation_Level = panels_Space.ConvertAll(x => dictionary_Panels[x].Item2).Min();
                double         elevation_Min   = panels_Space.ConvertAll(x => dictionary_Panels[x].Item3).Min();
                double         elevation_Max   = panels_Space.ConvertAll(x => dictionary_Panels[x].Item4).Max();
                BuildingStorey buildingStorey  = null;
                foreach (KeyValuePair <BuildingStorey, double> keyValuePair in dictionary_buildingStoreys)
                {
                    if (keyValuePair.Value.Equals(elevation_Level))
                    {
                        buildingStorey = keyValuePair.Key;
                        break;
                    }
                }

                if (buildingStorey == null)
                {
                    continue;
                }

                List <Panel> panels_PlanarGeometry = panels_Space.FindAll(x => x.PanelType.PanelGroup() == PanelGroup.Floor || (x.Normal.AlmostSimilar(Vector3D.WorldZ.GetNegated()) && dictionary_Panels[x].Item3 == elevation_Min));
                panels_PlanarGeometry = panels_PlanarGeometry?.MergeCoplanarPanels(Tolerance.MacroDistance, false, false, Tolerance.MacroDistance);
                if (panels_PlanarGeometry == null || panels_PlanarGeometry.Count == 0)
                {
                    continue;
                }

                panels_PlanarGeometry.Sort((x, y) => y.GetArea().CompareTo(x.GetArea()));

                Face3D face3D = panels_PlanarGeometry.First().PlanarBoundary3D?.GetFace3D();
                if (face3D == null)
                {
                    continue;
                }

                double area = face3D.GetArea();
                if (area < Tolerance.MacroDistance)
                {
                    continue;
                }

                double volume = Math.Abs(elevation_Max - elevation_Min) * area;
                if (volume < Tolerance.MacroDistance)
                {
                    continue;
                }

                List <SpaceBoundary> spaceBoundaries = new List <SpaceBoundary>();
                foreach (Panel panel in panels_Space)
                {
                    if (panel == null)
                    {
                        continue;
                    }

                    SpaceBoundary spaceBoundary = null;
                    if (!dictionary.TryGetValue(panel.Guid, out spaceBoundary))
                    {
                        spaceBoundary          = panel.TogbXML_SpaceBoundary(tolerance);
                        dictionary[panel.Guid] = spaceBoundary;
                    }

                    spaceBoundaries.Add(spaceBoundary);
                }

                gbXMLSerializer.Space space_gbXML = new gbXMLSerializer.Space();
                space_gbXML.Name      = space.Name;
                space_gbXML.spacearea = new Area()
                {
                    val = area.ToString()
                };
                space_gbXML.spacevol = new Volume()
                {
                    val = volume.ToString()
                };
                space_gbXML.buildingStoreyIdRef = buildingStorey.id;
                space_gbXML.cadid = new CADObjectId()
                {
                    id = space.Guid.ToString()
                };
                space_gbXML.PlanarGeo = face3D.TogbXML(tolerance);
                space_gbXML.id        = Core.gbXML.Query.Id(space, typeof(gbXMLSerializer.Space));
                space_gbXML.spbound   = spaceBoundaries.ToArray();
                space_gbXML.ShellGeo  = panels_Space.TogbXML(space, tolerance);

                spaces_gbXML.Add(space_gbXML);
            }

            Building building = new Building();

            building.id           = Core.gbXML.Query.Id(adjacencyCluster, typeof(Building));
            building.Name         = name;
            building.Description  = description;
            building.bldgStories  = dictionary_buildingStoreys.Keys.ToArray();
            building.Area         = Analytical.Query.Area(panels, PanelGroup.Floor);
            building.buildingType = buildingTypeEnum.Office;
            building.Spaces       = spaces_gbXML.ToArray();

            return(building);
        }
Esempio n. 3
0
        public static List <Aperture> ToSAM_Apertures(this FamilyInstance familyInstance, ConvertSettings convertSettings)
        {
            if (familyInstance == null)
            {
                return(null);
            }

            List <Aperture> result = convertSettings?.GetObjects <Aperture>(familyInstance.Id);

            if (result != null)
            {
                return(result);
            }

            if (Core.Revit.Query.Simplified(familyInstance))
            {
                result = Core.Revit.Query.IJSAMObjects <Aperture>(familyInstance);
                if (result != null)
                {
                    convertSettings?.Add(familyInstance.Id, result);
                    return(result);
                }
            }

            Point3D point3D_Location = Geometry.Revit.Query.LocationPoint3D(familyInstance);

            if (point3D_Location == null)
            {
                List <Solid> solids = Core.Revit.Query.Solids(familyInstance, new Options());
                solids?.RemoveAll(x => x.Volume == 0);
                if (solids == null || solids.Count == 0)
                {
                    return(null);
                }

                if (solids.Count > 1)
                {
                    solids.Sort((x, y) => y.Volume.CompareTo(x.Volume));
                }

                point3D_Location = solids[0].ComputeCentroid()?.ToSAM();
            }

            if (point3D_Location == null)
            {
                return(null);
            }

            List <Face3D> face3Ds = null;


            PanelType       panelType_Host       = PanelType.Undefined;
            BuiltInCategory builtInCategory_Host = BuiltInCategory.INVALID;
            HostObject      hostObject           = null;

            if (familyInstance.Host != null)
            {
                hostObject = familyInstance.Host as HostObject;

                if (hostObject != null)
                {
                    builtInCategory_Host = (BuiltInCategory)hostObject.Category.Id.IntegerValue;
                }
            }

            //Method 1 of extracting Geometry
            if (face3Ds == null || face3Ds.Count == 0)
            {
                Vector3D axisX  = null;
                Vector3D normal = null;
                Vector3D axisY  = null;
                if (builtInCategory_Host == BuiltInCategory.OST_Roofs)
                {
                    axisX  = familyInstance.HandOrientation.ToSAM_Vector3D(false);
                    axisY  = familyInstance.FacingOrientation.ToSAM_Vector3D(false);
                    normal = Geometry.Spatial.Query.AxisY(axisY, axisX);
                }
                else
                {
                    axisX  = familyInstance.HandOrientation.ToSAM_Vector3D(false);
                    normal = familyInstance.FacingOrientation.ToSAM_Vector3D(false);
                    axisY  = Geometry.Spatial.Query.AxisY(normal, axisX);
                }

                Geometry.Spatial.Plane plane = Geometry.Spatial.Create.Plane(point3D_Location, axisX, axisY);
                if (!plane.Normal.SameHalf(normal))
                {
                    plane.FlipZ(false);
                }

                List <Shell> shells = Geometry.Revit.Convert.ToSAM_Geometries <Shell>(familyInstance);
                if (shells == null || shells.Count == 0)
                {
                    return(null);
                }

                List <Point2D> point2Ds = new List <Point2D>();
                foreach (Shell shell in shells)
                {
                    List <Face3D> face3Ds_Shell = shell?.Face3Ds;
                    if (face3Ds_Shell == null || face3Ds_Shell.Count == 0)
                    {
                        continue;
                    }

                    foreach (Face3D face3D_Temp in face3Ds_Shell)
                    {
                        ISegmentable3D segmentable3D = face3D_Temp.GetExternalEdge3D() as ISegmentable3D;
                        if (segmentable3D == null)
                        {
                            continue;
                        }

                        segmentable3D?.GetPoints()?.ForEach(x => point2Ds.Add(plane.Convert(x)));
                    }
                }

                Face3D face3D = new Face3D(plane, Geometry.Planar.Create.Rectangle2D(point2Ds));
                if (face3D != null && face3D.IsValid() && face3D.GetArea() > Core.Tolerance.MacroDistance)
                {
                    face3Ds = new List <Face3D>()
                    {
                        face3D
                    };
                }
            }

            //Method 2 of extracting Geometry
            if (hostObject != null)
            {
                builtInCategory_Host = (BuiltInCategory)hostObject.Category.Id.IntegerValue;

                Geometry.Spatial.Plane plane_Host = null;
                if (hostObject is CurtainSystem && familyInstance is Autodesk.Revit.DB.Panel)
                {
                    Autodesk.Revit.DB.Panel panel = (Autodesk.Revit.DB.Panel)familyInstance;
                    ElementId uGridLineElementId  = null;
                    ElementId vGridLineElementId  = null;

                    panel.GetRefGridLines(ref uGridLineElementId, ref vGridLineElementId);

                    CurtainSystem curtainSystem = (CurtainSystem)hostObject;

                    List <Polygon3D> polygon3Ds = curtainSystem.CurtainCell(uGridLineElementId, vGridLineElementId)?.Polygon3Ds();
                    if (polygon3Ds != null && polygon3Ds.Count != 0)
                    {
                        polygon3Ds.Sort((x, y) => y.GetArea().CompareTo(x.GetArea()));
                        plane_Host = polygon3Ds[0].GetPlane();
                    }
                }
                else
                {
                    List <Face3D> face3Ds_Temp = hostObject.Profiles();
                    if (face3Ds_Temp != null && face3Ds_Temp.Count != 0)
                    {
                        plane_Host = face3Ds_Temp.Closest(point3D_Location)?.GetPlane();
                    }
                }

                if (plane_Host != null)
                {
                    face3Ds          = face3Ds?.ConvertAll(x => plane_Host.Project(x));
                    point3D_Location = plane_Host.Project(point3D_Location);
                }


                HostObjAttributes hostObjAttributes = familyInstance.Document.GetElement(hostObject.GetTypeId()) as HostObjAttributes;
                if (hostObjAttributes != null)
                {
                    panelType_Host = hostObjAttributes.PanelType();
                }

                if (panelType_Host == PanelType.Undefined)
                {
                    panelType_Host = hostObject.PanelType();
                }

                List <Face3D> face3Ds_Profiles = hostObject.Profiles(familyInstance.Id);
                face3Ds_Profiles?.RemoveAll(x => x == null || !x.IsValid());
                if (face3Ds_Profiles != null && face3Ds_Profiles.Count > 0)
                {
                    if (face3Ds == null || (face3Ds != null && face3Ds_Profiles.ConvertAll(x => x.GetArea()).Sum() <= face3Ds.ConvertAll(x => x.GetArea()).Sum()))
                    {
                        face3Ds = face3Ds_Profiles;
                    }
                }
            }

            ApertureConstruction apertureConstruction = ToSAM_ApertureConstruction(familyInstance, convertSettings);

            if (apertureConstruction == null && panelType_Host != PanelType.Undefined)
            {
                apertureConstruction = Analytical.Query.DefaultApertureConstruction(panelType_Host, familyInstance.ApertureType()); //Default Aperture Construction
            }
            if (face3Ds == null || face3Ds.Count == 0)
            {
                return(result);
            }

            //TODO: Working on SAM Families (requested by Michal)

            string parameterName_Height = Core.Revit.Query.Name(ActiveSetting.Setting, typeof(Aperture), typeof(FamilyInstance), "GetHeight");
            string parameterName_Width  = Core.Revit.Query.Name(ActiveSetting.Setting, typeof(Aperture), typeof(FamilyInstance), "GetWidth");

            if (!string.IsNullOrWhiteSpace(parameterName_Height) && !string.IsNullOrWhiteSpace(parameterName_Width))
            {
                Parameter parameter_Height = familyInstance.LookupParameter(parameterName_Height);
                Parameter parameter_Width  = familyInstance.LookupParameter(parameterName_Width);
                if (parameter_Height != null && parameter_Width != null && parameter_Height.HasValue && parameter_Width.HasValue && parameter_Height.StorageType == StorageType.Double && parameter_Width.StorageType == StorageType.Double)
                {
#if Revit2017 || Revit2018 || Revit2019 || Revit2020
                    double height = UnitUtils.ConvertFromInternalUnits(parameter_Height.AsDouble(), DisplayUnitType.DUT_METERS);
                    double width  = UnitUtils.ConvertFromInternalUnits(parameter_Width.AsDouble(), DisplayUnitType.DUT_METERS);
#else
                    double height = UnitUtils.ConvertFromInternalUnits(parameter_Height.AsDouble(), UnitTypeId.Meters);
                    double width  = UnitUtils.ConvertFromInternalUnits(parameter_Width.AsDouble(), UnitTypeId.Meters);
#endif
                }
            }

            result = new List <Aperture>();
            foreach (Face3D face3D_Temp in face3Ds)
            {
                Aperture aperture = Analytical.Create.Aperture(apertureConstruction, face3D_Temp);
                if (aperture == null)
                {
                    continue;
                }

                aperture.UpdateParameterSets(familyInstance, ActiveSetting.Setting.GetValue <Core.TypeMap>(Core.Revit.ActiveSetting.Name.ParameterMap));
                result.Add(aperture);
            }

            convertSettings?.Add(familyInstance.Id, result);

            return(result);
        }
Esempio n. 4
0
        public static TBD.Building ToTBD(this AnalyticalModel analyticalModel, TBD.TBDDocument tBDDocument)
        {
            if (analyticalModel == null)
            {
                return(null);
            }

            TBD.Building result = tBDDocument.Building;
            if (result == null)
            {
                return(null);
            }

            AdjacencyCluster adjacencyCluster = analyticalModel.AdjacencyCluster;

            if (adjacencyCluster == null)
            {
                return(null);
            }

            List <Space> spaces = adjacencyCluster.GetSpaces();

            if (spaces == null)
            {
                return(result);
            }

            MaterialLibrary materialLibrary = analyticalModel.MaterialLibrary;

            Plane plane = Plane.WorldXY;

            List <TBD.DaysShade> daysShades = new List <TBD.DaysShade>();

            result.ClearShadingData();

            Dictionary <System.Guid, List <TBD.zoneSurface> > dictionary_Panel    = new Dictionary <System.Guid, List <TBD.zoneSurface> >();
            Dictionary <System.Guid, List <TBD.zoneSurface> > dictionary_Aperture = new Dictionary <System.Guid, List <TBD.zoneSurface> >();

            foreach (Space space in spaces)
            {
                Shell shell = adjacencyCluster.Shell(space);
                if (shell == null)
                {
                    return(null);
                }

                TBD.zone zone = result.AddZone();
                zone.name   = space.Name;
                zone.volume = System.Convert.ToSingle(shell.Volume());

                if (space.TryGetValue(SpaceParameter.Color, out SAMColor sAMColor) && sAMColor != null)
                {
                    zone.colour = Core.Convert.ToUint(sAMColor.ToColor());
                }

                List <Face3D> face3Ds = Geometry.Spatial.Query.Section(shell, 0.01, false);
                if (face3Ds != null && face3Ds.Count != 0)
                {
                    face3Ds.RemoveAll(x => x == null || !x.IsValid());
                    zone.floorArea        = System.Convert.ToSingle(face3Ds.ConvertAll(x => x.GetArea()).Sum());
                    zone.exposedPerimeter = System.Convert.ToSingle(face3Ds.ConvertAll(x => Geometry.Planar.Query.Perimeter(x.ExternalEdge2D)).Sum());
                    zone.length           = System.Convert.ToSingle(face3Ds.ConvertAll(x => Geometry.Tas.Query.Length(x)).Sum());
                }

                TBD.room room = zone.AddRoom();

                List <TBD.buildingElement> buildingElements = result.BuildingElements();
                List <TBD.Construction>    constructions    = result.Constructions();

                List <Panel> panels = adjacencyCluster?.GetPanels(space);
                if (panels != null || panels.Count != 0)
                {
                    foreach (Panel panel in panels)
                    {
                        string name_Panel = panel.Name;
                        if (string.IsNullOrWhiteSpace(name_Panel))
                        {
                            continue;
                        }

                        Face3D face3D_Panel = panel.Face3D;
                        if (face3D_Panel == null)
                        {
                            continue;
                        }

                        BoundingBox3D boundingBox3D_Panel = face3D_Panel.GetBoundingBox();

                        TBD.zoneSurface zoneSurface_Panel = zone.AddSurface();
                        zoneSurface_Panel.orientation = System.Convert.ToSingle(Geometry.Spatial.Query.Azimuth(panel, Vector3D.WorldY));
                        zoneSurface_Panel.inclination = System.Convert.ToSingle(Geometry.Spatial.Query.Tilt(panel));

                        zoneSurface_Panel.altitude              = System.Convert.ToSingle(boundingBox3D_Panel.GetCentroid().Z);
                        zoneSurface_Panel.altitudeRange         = System.Convert.ToSingle(boundingBox3D_Panel.Max.Z - boundingBox3D_Panel.Min.Z);
                        zoneSurface_Panel.area                  = System.Convert.ToSingle(face3D_Panel.GetArea());
                        zoneSurface_Panel.planHydraulicDiameter = System.Convert.ToSingle(Geometry.Tas.Query.HydraulicDiameter(face3D_Panel));

                        TBD.RoomSurface roomSurface_Panel = room.AddSurface();
                        roomSurface_Panel.area        = zoneSurface_Panel.area;
                        roomSurface_Panel.zoneSurface = zoneSurface_Panel;

                        Geometry.SolarCalculator.SolarFaceSimulationResult solarFaceSimulationResult = analyticalModel.GetResults <Geometry.SolarCalculator.SolarFaceSimulationResult>(panel)?.FirstOrDefault();
                        if (solarFaceSimulationResult != null)
                        {
                            List <TBD.SurfaceShade> surfaceShades = Modify.UpdateSurfaceShades(result, daysShades, zoneSurface_Panel, analyticalModel, solarFaceSimulationResult);
                        }

                        TBD.Perimeter perimeter_Panel = Geometry.Tas.Convert.ToTBD(panel.GetFace3D(true), roomSurface_Panel);
                        if (perimeter_Panel == null)
                        {
                            continue;
                        }

                        PanelType panelType = panel.PanelType;

                        TBD.buildingElement buildingElement_Panel = buildingElements.Find(x => x.name == name_Panel);
                        if (buildingElement_Panel == null)
                        {
                            TBD.Construction construction_TBD = null;

                            Construction construction = panel.Construction;
                            if (construction != null)
                            {
                                construction_TBD = constructions.Find(x => x.name == construction.Name);
                                if (construction_TBD == null)
                                {
                                    construction_TBD      = result.AddConstruction(null);
                                    construction_TBD.name = construction.Name;

                                    if (construction.Transparent(materialLibrary))
                                    {
                                        construction_TBD.type = TBD.ConstructionTypes.tcdTransparentConstruction;
                                    }

                                    List <ConstructionLayer> constructionLayers = construction.ConstructionLayers;
                                    if (constructionLayers != null && constructionLayers.Count != 0)
                                    {
                                        int index = 1;
                                        foreach (ConstructionLayer constructionLayer in constructionLayers)
                                        {
                                            Material material = analyticalModel?.MaterialLibrary?.GetMaterial(constructionLayer.Name) as Core.Material;
                                            if (material == null)
                                            {
                                                continue;
                                            }

                                            TBD.material material_TBD = construction_TBD.AddMaterial(material);
                                            if (material_TBD != null)
                                            {
                                                material_TBD.width = System.Convert.ToSingle(constructionLayer.Thickness);
                                                construction_TBD.materialWidth[index] = System.Convert.ToSingle(constructionLayer.Thickness);
                                                index++;
                                            }
                                        }
                                    }

                                    constructions.Add(construction_TBD);
                                }

                                if (panelType == PanelType.Undefined && construction != null)
                                {
                                    panelType = construction.PanelType();
                                    if (panelType == PanelType.Undefined && construction.TryGetValue(ConstructionParameter.DefaultPanelType, out string panelTypeString))
                                    {
                                        panelType = Core.Query.Enum <PanelType>(panelTypeString);
                                    }
                                }
                            }

                            buildingElement_Panel        = result.AddBuildingElement();
                            buildingElement_Panel.name   = name_Panel;
                            buildingElement_Panel.colour = Core.Convert.ToUint(Analytical.Query.Color(panelType));
                            buildingElement_Panel.BEType = Query.BEType(panelType.Text());
                            buildingElement_Panel.AssignConstruction(construction_TBD);
                            buildingElements.Add(buildingElement_Panel);
                        }

                        if (buildingElement_Panel != null)
                        {
                            zoneSurface_Panel.buildingElement = buildingElement_Panel;
                        }

                        zoneSurface_Panel.type = TBD.SurfaceType.tbdExposed;

                        List <Aperture> apertures = panel.Apertures;
                        if (apertures != null && apertures.Count != 0)
                        {
                            bool @internal = adjacencyCluster.Internal(panel);

                            foreach (Aperture aperture in apertures)
                            {
                                string name_Aperture = aperture.Name;
                                if (string.IsNullOrWhiteSpace(name_Aperture))
                                {
                                    continue;
                                }

                                name_Aperture = string.Format("{0} -pane", aperture.Name);

                                Face3D face3D_Aperture = aperture.Face3D;
                                if (face3D_Aperture == null)
                                {
                                    continue;
                                }

                                BoundingBox3D boundingBox3D_Aperture = face3D_Aperture.GetBoundingBox();

                                float area = System.Convert.ToSingle(face3D_Aperture.GetArea());

                                TBD.zoneSurface zoneSurface_Aperture = zoneSurface_Panel.AddChildSurface(area);
                                if (zoneSurface_Aperture == null)
                                {
                                    continue;
                                }

                                zoneSurface_Aperture.orientation           = zoneSurface_Panel.orientation;
                                zoneSurface_Aperture.inclination           = zoneSurface_Panel.inclination;
                                zoneSurface_Aperture.altitude              = System.Convert.ToSingle(boundingBox3D_Aperture.GetCentroid().Z);
                                zoneSurface_Aperture.altitudeRange         = System.Convert.ToSingle(boundingBox3D_Aperture.Max.Z - boundingBox3D_Aperture.Min.Z);
                                zoneSurface_Aperture.planHydraulicDiameter = System.Convert.ToSingle(Geometry.Tas.Query.HydraulicDiameter(face3D_Aperture));
                                //zoneSurface_Aperture.area = System.Convert.ToSingle(face3D_Aperture.GetArea());

                                zoneSurface_Aperture.type = @internal ? TBD.SurfaceType.tbdLink : zoneSurface_Panel.type;

                                TBD.RoomSurface roomSurface_Aperture = room.AddSurface();
                                roomSurface_Aperture.area        = zoneSurface_Aperture.area;
                                roomSurface_Aperture.zoneSurface = zoneSurface_Aperture;

                                TBD.Perimeter perimeter_Aperture = Geometry.Tas.Convert.ToTBD(face3D_Aperture, roomSurface_Aperture);
                                if (perimeter_Aperture == null)
                                {
                                    continue;
                                }

                                TBD.buildingElement buildingElement_Aperture = buildingElements.Find(x => x.name == name_Aperture);
                                if (buildingElement_Aperture == null)
                                {
                                    TBD.Construction construction_TBD = null;

                                    ApertureConstruction apertureConstruction = aperture.ApertureConstruction;
                                    if (apertureConstruction != null)
                                    {
                                        construction_TBD = constructions.Find(x => x.name == apertureConstruction.Name);
                                        if (construction_TBD == null)
                                        {
                                            construction_TBD      = result.AddConstruction(null);
                                            construction_TBD.name = name_Aperture;

                                            if (apertureConstruction.Transparent(materialLibrary))
                                            {
                                                construction_TBD.type = TBD.ConstructionTypes.tcdTransparentConstruction;
                                            }

                                            List <ConstructionLayer> constructionLayers = apertureConstruction.PaneConstructionLayers;
                                            if (constructionLayers != null && constructionLayers.Count != 0)
                                            {
                                                int index = 1;
                                                foreach (ConstructionLayer constructionLayer in constructionLayers)
                                                {
                                                    Core.Material material = materialLibrary?.GetMaterial(constructionLayer.Name) as Material;
                                                    if (material == null)
                                                    {
                                                        continue;
                                                    }

                                                    TBD.material material_TBD = construction_TBD.AddMaterial(material);
                                                    if (material_TBD != null)
                                                    {
                                                        material_TBD.width = System.Convert.ToSingle(constructionLayer.Thickness);
                                                        construction_TBD.materialWidth[index] = System.Convert.ToSingle(constructionLayer.Thickness);
                                                        index++;
                                                    }
                                                }
                                            }

                                            constructions.Add(construction_TBD);
                                        }
                                    }

                                    ApertureType apertureType = aperture.ApertureType;

                                    buildingElement_Aperture        = result.AddBuildingElement();
                                    buildingElement_Aperture.name   = name_Aperture;
                                    buildingElement_Aperture.colour = Core.Convert.ToUint(Analytical.Query.Color(apertureType));
                                    buildingElement_Aperture.BEType = Query.BEType(apertureType, false);
                                    buildingElement_Aperture.AssignConstruction(construction_TBD);
                                    buildingElements.Add(buildingElement_Aperture);
                                }

                                if (buildingElement_Aperture != null)
                                {
                                    zoneSurface_Aperture.buildingElement = buildingElement_Aperture;
                                }

                                if (!dictionary_Aperture.TryGetValue(aperture.Guid, out List <TBD.zoneSurface> zoneSurfaces_Aperture) || zoneSurfaces_Aperture == null)
                                {
                                    zoneSurfaces_Aperture = new List <TBD.zoneSurface>();
                                    dictionary_Aperture[aperture.Guid] = zoneSurfaces_Aperture;
                                }

                                zoneSurfaces_Aperture.Add(zoneSurface_Aperture);
                            }
                        }

                        zoneSurface_Panel.type = Query.SurfaceType(panelType);

                        if (!dictionary_Panel.TryGetValue(panel.Guid, out List <TBD.zoneSurface> zoneSurfaces_Panel) || zoneSurfaces_Panel == null)
                        {
                            zoneSurfaces_Panel           = new List <TBD.zoneSurface>();
                            dictionary_Panel[panel.Guid] = zoneSurfaces_Panel;
                        }

                        zoneSurfaces_Panel.Add(zoneSurface_Panel);
                    }
                }
            }

            foreach (KeyValuePair <System.Guid, List <TBD.zoneSurface> > keyValuePair in dictionary_Panel)
            {
                if (keyValuePair.Value == null || keyValuePair.Value.Count <= 1)
                {
                    continue;
                }

                keyValuePair.Value[1].linkSurface = keyValuePair.Value[0];
                keyValuePair.Value[0].linkSurface = keyValuePair.Value[1];

                if (keyValuePair.Value[0].inclination == 0 || keyValuePair.Value[0].inclination == 180)
                {
                    float inclination = keyValuePair.Value[1].inclination;
                    inclination -= 180;
                    if (inclination < 0)
                    {
                        inclination += 360;
                    }

                    keyValuePair.Value[1].inclination = inclination;
                    keyValuePair.Value[1].reversed    = 1;
                }
                else
                {
                    float orientation = keyValuePair.Value[1].orientation;
                    orientation += 180;
                    if (orientation >= 360)
                    {
                        orientation -= 360;
                    }

                    keyValuePair.Value[1].orientation = orientation;
                    keyValuePair.Value[1].reversed    = 1;

                    float inclination = keyValuePair.Value[1].inclination;
                    if (inclination > 180)
                    {
                        inclination -= 180;
                    }
                    keyValuePair.Value[1].inclination = inclination;
                }
            }

            foreach (KeyValuePair <System.Guid, List <TBD.zoneSurface> > keyValuePair in dictionary_Aperture)
            {
                if (keyValuePair.Value == null || keyValuePair.Value.Count <= 1)
                {
                    continue;
                }

                keyValuePair.Value[1].linkSurface = keyValuePair.Value[0];
                keyValuePair.Value[0].linkSurface = keyValuePair.Value[1];

                if (keyValuePair.Value[0].inclination == 0 || keyValuePair.Value[0].inclination == 180)
                {
                    float inclination = keyValuePair.Value[0].inclination;
                    inclination -= 180;
                    if (inclination < 0)
                    {
                        inclination += 360;
                    }

                    keyValuePair.Value[0].inclination = inclination;
                    keyValuePair.Value[0].reversed    = 1;
                }
                else
                {
                    float orientation = keyValuePair.Value[1].orientation;
                    orientation += 180;
                    if (orientation >= 360)
                    {
                        orientation -= 360;
                    }

                    keyValuePair.Value[1].orientation = orientation;
                    keyValuePair.Value[1].reversed    = 1;
                }
            }

            return(result);
        }