/***************************************************/ /**** Public methods ****/ /***************************************************/ public static Floor ToRevitFloor(this oM.Physical.Elements.Floor floor, Document document, RevitSettings settings = null, Dictionary <Guid, List <int> > refObjects = null) { if (floor == null || floor.Construction == null || document == null) { return(null); } Floor revitFloor = refObjects.GetValue <Floor>(document, floor.BHoM_Guid); if (revitFloor != null) { return(revitFloor); } PlanarSurface planarSurface = floor.Location as PlanarSurface; if (planarSurface == null) { return(null); } settings = settings.DefaultIfNull(); FloorType floorType = floor.Construction?.ToRevitElementType(document, new List <BuiltInCategory> { BuiltInCategory.OST_Floors }, settings, refObjects) as FloorType; if (floorType == null) { floorType = floor.ElementType(document, settings); } if (floorType == null) { Compute.ElementTypeNotFoundWarning(floor); return(null); } double bottomElevation = floor.Location.IBounds().Min.Z; Level level = document.LevelBelow(bottomElevation.FromSI(UnitType.UT_Length), settings); oM.Geometry.Plane sketchPlane = new oM.Geometry.Plane { Origin = new BH.oM.Geometry.Point { Z = bottomElevation }, Normal = Vector.ZAxis }; ICurve curve = planarSurface.ExternalBoundary.IProject(sketchPlane); CurveArray curveArray = Create.CurveArray(curve.IToRevitCurves()); BH.oM.Geometry.Plane slabPlane = planarSurface.FitPlane(); if (1 - Math.Abs(Vector.ZAxis.DotProduct(slabPlane.Normal)) <= settings.AngleTolerance) { revitFloor = document.Create.NewFloor(curveArray, floorType, level, true); } else { Vector normal = slabPlane.Normal; if (normal.Z < 0) { normal = -slabPlane.Normal; } double angle = normal.Angle(Vector.ZAxis); double tan = Math.Tan(angle); XYZ dir = normal.Project(oM.Geometry.Plane.XY).ToRevit().Normalize(); BH.oM.Geometry.Line ln = slabPlane.PlaneIntersection(sketchPlane); XYZ start = ln.ClosestPoint(curveArray.get_Item(0).GetEndPoint(0).PointFromRevit(), true).ToRevit(); Autodesk.Revit.DB.Line line = Autodesk.Revit.DB.Line.CreateBound(start, start + dir); revitFloor = document.Create.NewSlab(curveArray, level, line, -tan, true); revitFloor.SetParameter(BuiltInParameter.ELEM_TYPE_PARAM, floorType.Id); } revitFloor.CheckIfNullPush(floor); if (revitFloor == null) { return(null); } document.Regenerate(); if (planarSurface.InternalBoundaries != null) { foreach (ICurve hole in planarSurface.InternalBoundaries) { document.Create.NewOpening(revitFloor, Create.CurveArray(hole.IProject(slabPlane).IToRevitCurves()), true); } } foreach (BH.oM.Physical.Elements.IOpening opening in floor.Openings) { PlanarSurface openingLocation = opening.Location as PlanarSurface; if (openingLocation == null) { BH.Engine.Reflection.Compute.RecordWarning(String.Format("Conversion of a floor opening to Revit failed because its location is not a planar surface. Floor BHoM_Guid: {0}, Opening BHoM_Guid: {1}", floor.BHoM_Guid, opening.BHoM_Guid)); continue; } document.Create.NewOpening(revitFloor, Create.CurveArray(openingLocation.ExternalBoundary.IToRevitCurves()), true); if (!(opening is BH.oM.Physical.Elements.Void)) { BH.Engine.Reflection.Compute.RecordWarning(String.Format("Revit allows only void openings in floors, therefore the BHoM opening of type {0} has been converted to a void opening. Floor BHoM_Guid: {1}, Opening BHoM_Guid: {2}", opening.GetType().Name, floor.BHoM_Guid, opening.BHoM_Guid)); } } double offset = revitFloor.LookupParameterDouble(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM); // Copy parameters from BHoM object to Revit element revitFloor.CopyParameters(floor, settings); // Update the offset in case the level had been overwritten. if (revitFloor.LevelId.IntegerValue != level.Id.IntegerValue) { Level newLevel = document.GetElement(revitFloor.LevelId) as Level; offset += (level.ProjectElevation - newLevel.ProjectElevation).ToSI(UnitType.UT_Length); } revitFloor.SetParameter(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM, offset); refObjects.AddOrReplace(floor, revitFloor); return(revitFloor); }
/***************************************************/ public static Element ToRevit(this oM.Physical.Elements.Floor floor, Document document, RevitSettings settings = null, Dictionary <Guid, List <int> > refObjects = null) { return(floor.ToRevitFloor(document, settings, refObjects)); }
/***************************************************/ /**** Public Methods ****/ /***************************************************/ public static oM.Physical.Elements.Floor FloorFromRevit(this Floor floor, RevitSettings settings = null, Dictionary <string, List <IBHoMObject> > refObjects = null) { if (floor == null) { return(null); } settings = settings.DefaultIfNull(); oM.Physical.Elements.Floor bHoMFloor = refObjects.GetValue <oM.Physical.Elements.Floor>(floor.Id); if (bHoMFloor != null) { return(bHoMFloor); } HostObjAttributes hostObjAttributes = floor.Document.GetElement(floor.GetTypeId()) as HostObjAttributes; string materialGrade = floor.MaterialGrade(settings); oM.Physical.Constructions.Construction construction = hostObjAttributes.ConstructionFromRevit(materialGrade, settings, refObjects); ISurface location = null; List <BH.oM.Physical.Elements.IOpening> openings = new List <oM.Physical.Elements.IOpening>(); Dictionary <PlanarSurface, List <PlanarSurface> > surfaces = null; BoundingBoxXYZ bbox = floor.get_BoundingBox(null); if (bbox != null) { BoundingBoxIntersectsFilter bbif = new BoundingBoxIntersectsFilter(new Outline(bbox.Min, bbox.Max)); IList <ElementId> insertIds = (floor as HostObject).FindInserts(true, true, true, true); List <Element> inserts; if (insertIds.Count == 0) { inserts = new List <Element>(); } else { inserts = new FilteredElementCollector(floor.Document, insertIds).WherePasses(bbif).ToList(); } List <FamilyInstance> windows = inserts.Where(x => x is FamilyInstance && x.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Windows).Cast <FamilyInstance>().ToList(); List <FamilyInstance> doors = inserts.Where(x => x is FamilyInstance && x.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Doors).Cast <FamilyInstance>().ToList(); surfaces = floor.PanelSurfaces(windows.Union(doors).Select(x => x.Id), settings); if (surfaces != null) { List <ISurface> locations = new List <ISurface>(surfaces.Keys); if (locations.Count == 1) { location = locations[0]; } else { location = new PolySurface { Surfaces = locations } }; foreach (List <PlanarSurface> ps in surfaces.Values) { openings.AddRange(ps.Select(x => new BH.oM.Physical.Elements.Void { Location = x })); } foreach (FamilyInstance window in windows) { BH.oM.Physical.Elements.Window bHoMWindow = window.WindowFromRevit(floor, settings, refObjects); if (bHoMWindow != null) { openings.Add(bHoMWindow); } } foreach (FamilyInstance door in doors) { BH.oM.Physical.Elements.Door bHoMDoor = door.DoorFromRevit(floor, settings, refObjects); if (bHoMDoor != null) { openings.Add(bHoMDoor); } } } } if (surfaces == null || surfaces.Count == 0) { floor.NoPanelLocationError(); } bHoMFloor = new oM.Physical.Elements.Floor { Location = location, Openings = openings, Construction = construction }; bHoMFloor.Name = floor.FamilyTypeFullName(); //Set identifiers, parameters & custom data bHoMFloor.SetIdentifiers(floor); bHoMFloor.CopyParameters(floor, settings.ParameterSettings); bHoMFloor.SetProperties(floor, settings.ParameterSettings); refObjects.AddOrReplace(floor.Id, bHoMFloor); return(bHoMFloor); } /***************************************************/ }