public static Panel SimilarPanel(this Geometry.Spatial.Face3D face3D, Dictionary <Panel, Geometry.Spatial.Face3D> panelsDictionary, double distanceTolerance = Core.Tolerance.MacroDistance, double coplanarTolerance = Core.Tolerance.MacroDistance) { if (face3D == null || panelsDictionary == null) { return(null); } Geometry.Spatial.Plane plane = face3D.GetPlane(); double area = face3D.GetArea(); Geometry.Planar.IClosed2D closed2D_1 = Geometry.Spatial.Query.Convert(plane, face3D.GetExternalEdge3D()); Geometry.Planar.Point2D point2D_Internal = closed2D_1.GetInternalPoint2D(); double areaDifferece_Min = double.MaxValue; Panel result = null; foreach (KeyValuePair <Panel, Geometry.Spatial.Face3D> keyValuePair in panelsDictionary) { if (keyValuePair.Value == null) { continue; } double areaDifference = System.Math.Abs(keyValuePair.Value.GetArea() - area); if (areaDifferece_Min < areaDifference) { continue; } Geometry.Spatial.Face3D face3D_Temp = keyValuePair.Value; Geometry.Spatial.Plane plane_Temp = face3D_Temp.GetPlane(); if (!plane.Coplanar(plane_Temp, coplanarTolerance)) { continue; } Geometry.Spatial.Point3D point3D_Origin = plane_Temp.Origin; Geometry.Spatial.Point3D point3D_Project = Geometry.Spatial.Query.Project(plane, point3D_Origin); if (point3D_Origin.Distance(point3D_Project) > distanceTolerance) { continue; } Geometry.Planar.IClosed2D closed2D_2 = Geometry.Spatial.Query.Convert(plane, face3D_Temp.GetExternalEdge3D()); if (closed2D_2.Inside(point2D_Internal)) { result = keyValuePair.Key; areaDifferece_Min = areaDifference; } } return(result); }
public static List <Panel> SimilarPanels(this Geometry.Spatial.Face3D face3D, Dictionary <Panel, Geometry.Spatial.Face3D> panelsDictionary, double distanceTolerance = Tolerance.MacroDistance, double coplanarTolerance = Tolerance.MacroDistance) { if (face3D == null || panelsDictionary == null) { return(null); } Geometry.Spatial.Plane plane = face3D.GetPlane(); Geometry.Planar.IClosed2D closed2D_1 = Geometry.Spatial.Query.Convert(plane, face3D.GetExternalEdge3D()); Geometry.Planar.Point2D point2D_Internal = closed2D_1.GetInternalPoint2D(); double area = face3D.GetArea(); List <Tuple <Panel, double> > tuples = new List <Tuple <Panel, double> >(); foreach (KeyValuePair <Panel, Geometry.Spatial.Face3D> keyValuePair in panelsDictionary) { if (keyValuePair.Value == null) { continue; } Geometry.Spatial.Face3D face3D_Temp = keyValuePair.Value; Geometry.Spatial.Plane plane_Temp = face3D_Temp.GetPlane(); if (!plane.Coplanar(plane_Temp, coplanarTolerance)) { continue; } Geometry.Spatial.Point3D point3D_Origin = plane_Temp.Origin; Geometry.Spatial.Point3D point3D_Project = Geometry.Spatial.Query.Project(plane, point3D_Origin); if (point3D_Origin.Distance(point3D_Project) > distanceTolerance) { continue; } Geometry.Planar.IClosed2D closed2D_2 = Geometry.Spatial.Query.Convert(plane, face3D_Temp.GetExternalEdge3D()); if (closed2D_2.Inside(point2D_Internal)) { tuples.Add(new Tuple <Panel, double>(keyValuePair.Key, Math.Abs(keyValuePair.Value.GetArea() - area))); } } if (tuples == null || tuples.Count == 0) { return(null); } if (tuples.Count == 1) { return new List <Panel>() { tuples.First().Item1 } } ; tuples.Sort((x, y) => x.Item2.CompareTo(y.Item2)); double areatolerance = distanceTolerance * 10; List <Panel> result = tuples.FindAll(x => x.Item2 < areatolerance).ConvertAll(x => x.Item1); if (result != null && result.Count > 0) { return(result); } return(new List <Panel>() { tuples.First().Item1 }); } }
/// <summary> /// Converts Face3D to Wall /// </summary> /// <param name="face3D">SAM Geometry Face3D</param> /// <param name="document">Revit Document</param> /// <param name="wallType">Revit WallType. Default WallType will be used if null</param> /// <param name="level">Revit Level. Low Level for Face3D will be used if null</param> /// <returns>Revit Wall</returns> public static Autodesk.Revit.DB.Wall ToRevit_Wall(this Geometry.Spatial.Face3D face3D, Document document, Autodesk.Revit.DB.WallType wallType = null, Level level = null) { if (face3D == null || document == null) { return(null); } if (face3D.GetArea() < Core.Tolerance.MacroDistance) { return(null); } Geometry.Spatial.Vector3D normal = face3D.GetPlane().Normal; if (normal == null) { return(null); } if (wallType == null) { ElementId elementId = document.Settings.Categories.get_Item(BuiltInCategory.OST_Walls).Id; if (elementId != null && elementId != ElementId.InvalidElementId) { elementId = document.GetDefaultFamilyTypeId(elementId); if (elementId != null && elementId != ElementId.InvalidElementId) { wallType = document.GetElement(elementId) as Autodesk.Revit.DB.WallType; } } } if (wallType == null) { return(null); } if (level == null) { double elevation = Geometry.Revit.Convert.ToRevit(face3D.GetBoundingBox().Min).Z; level = Core.Revit.Query.LowLevel(document, elevation); } if (level == null) { return(null); } List <CurveLoop> curveLoops = Geometry.Revit.Convert.ToRevit(face3D); curveLoops?.RemoveAll(x => x == null); if (curveLoops == null || curveLoops.Count == 0) { return(null); } XYZ xyz_Normal = Geometry.Revit.Convert.ToRevit(normal, false); if (curveLoops.Count == 1) { return(Autodesk.Revit.DB.Wall.Create(document, curveLoops[0].ToList(), wallType.Id, level.Id, false, xyz_Normal)); } //The Wall.Create method requires the curveLoops to be in either all counter-clockwise direction or all clockwise direction. for (int i = 0; i < curveLoops.Count; i++) { if (curveLoops[i].IsCounterclockwise(xyz_Normal)) { curveLoops[i].Flip(); } } List <Curve> curves = new List <Curve>(); //According to https://forums.autodesk.com/t5/revit-api-forum/wall-create-by-profile/td-p/8961085 //CurveLoops have to be organised in correct order. Hypothesis : //If the curveLoop contains 1 (or more) vertical Line(s), the vertical line should be the first to add to the List. foreach (CurveLoop curveLoop in curveLoops) { List <Curve> curves_Temp = curveLoop?.ToList(); if (curveLoop == null) { continue; } List <Curve> curves_Postponed = new List <Curve>(); int startindex = 0; while (startindex < curves_Temp.Count) { Curve curve = curves_Temp[startindex]; if (!(curve is Line)) { curves_Postponed.Add(curve); startindex++; continue; } XYZ dir = curve.GetEndPoint(1).Subtract(curve.GetEndPoint(0)).Normalize(); if (!dir.IsAlmostEqualTo(XYZ.BasisZ) && !dir.IsAlmostEqualTo(XYZ.BasisZ.Negate())) { curves_Postponed.Add(curve); startindex++; } else { break; } } for (int i = startindex; i < curves_Temp.Count; i++) { Curve curve = curves_Temp[i]; curves.Add(curve); } if (curves_Postponed.Count > 0) { curves.AddRange(curves_Postponed); } } if (curves == null || curves.Count == 0) { return(null); } return(Autodesk.Revit.DB.Wall.Create(document, curves, wallType.Id, level.Id, false, xyz_Normal)); }
public static List <TBD.SurfaceShade> UpdateSurfaceShades(this TBD.Building building, List <TBD.DaysShade> daysShades, TBD.zoneSurface zoneSurface, AnalyticalModel analyticalModel, Geometry.SolarCalculator.SolarFaceSimulationResult solarFaceSimulationResult, double tolerance = 0.01) { if (daysShades == null || analyticalModel == null || solarFaceSimulationResult == null || zoneSurface == null) { return(null); } Panel panel = analyticalModel.GetRelatedObjects <Panel>(solarFaceSimulationResult)?.FirstOrDefault(); if (panel == null) { return(null); } Geometry.Spatial.Face3D face3D = panel.Face3D; if (face3D == null) { return(null); } double area = face3D.GetArea(); if (double.IsNaN(area) || area == 0) { return(null); } List <TBD.SurfaceShade> result = new List <TBD.SurfaceShade>(); List <DateTime> dateTimes = solarFaceSimulationResult.DateTimes; if (dateTimes == null || dateTimes.Count == 0) { return(result); } foreach (DateTime dateTime in dateTimes) { double sunExposureArea = solarFaceSimulationResult.GetSunExposureArea(dateTime); if (double.IsNaN(sunExposureArea) || sunExposureArea == 0) { continue; } int dayIndex = dateTime.DayOfYear; TBD.DaysShade daysShade = daysShades.Find(x => x.day == dayIndex); if (daysShade == null) { daysShade = building.AddDaysShade(); daysShade.day = dayIndex; daysShades.Add(daysShade); } float proportion = System.Convert.ToSingle(Core.Query.Round(sunExposureArea / area, tolerance)); if (proportion <= tolerance) { proportion = 0; } TBD.SurfaceShade surfaceShade = daysShade.AddSurfaceShade(System.Convert.ToInt16(dateTime.Hour)); surfaceShade.proportion = proportion; surfaceShade.surface = zoneSurface; result.Add(surfaceShade); } return(result); }