private RoomInfo Getinfo_Room(Document document, Room room) { if (room != null) { var info = new RoomInfo(); info.Room = room; info.RoomName = room.Name; info.RoomLevel = room.Level.Name; info.RoomNumber = room.Number; if (room.Location is LocationPoint location) { XYZ point = location.Point; info.RoomLocation = point; } #region GetHeight SpatialElementBoundaryOptions sebOptions = new SpatialElementBoundaryOptions { SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish }; SpatialElementGeometryCalculator calc = new SpatialElementGeometryCalculator(document, sebOptions); SpatialElementGeometryResults results = calc.CalculateSpatialElementGeometry(room); Solid roomSolid = results.GetGeometry(); var getbb = roomSolid.GetBoundingBox(); var maxZ = getbb.Max.Z; var minZ = getbb.Min.Z; info.RoomHeight = maxZ - minZ; #endregion IList <IList <BoundarySegment> > segments = room.GetBoundarySegments(new SpatialElementBoundaryOptions()); if (null != segments) { foreach (IList <BoundarySegment> segmentList in segments) { foreach (BoundarySegment boundarySegment in segmentList) { if (boundarySegment.GetCurve() is Line) { info.RoomBoundarySegment.Add(new RoomInfo { RoomStartPoint = boundarySegment.GetCurve().GetEndPoint(0), RoomEndPoint = boundarySegment.GetCurve().GetEndPoint(1) }); } if (boundarySegment.GetCurve() is Arc) { TaskDialog.Show("s", boundarySegment.GetCurve().GetType().ToString()); } } } } return(info); } return(null); }
private bool CreateRoomMass(SpatialElement room) { if (!SpatialElementGeometryCalculator.CanCalculateGeometry(room)) { return(false); } try { SpatialElementGeometryResults results; using (var calculator = new SpatialElementGeometryCalculator(doc)) { results = calculator.CalculateSpatialElementGeometry(room); } using (Solid roomSolid = results.GetGeometry()) { var eid = new ElementId(BuiltInCategory.OST_Mass); DirectShape roomShape = DirectShape.CreateElement(doc, eid); if (roomShape != null && roomSolid.Volume > 0 && roomSolid.Faces.Size > 0) { var geomObj = new GeometryObject[] { roomSolid }; if (geomObj.Length > 0) { roomShape.SetShape(geomObj); CopyAllRoomParametersToMasses(room, roomShape); return(true); } } } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } return(false); }
/// <summary> /// Gets intersect element list. /// </summary> /// <param name="room"></param> /// <param name="doc"></param> /// <returns></returns> public static List <Element> GetIntersectElements(this SpatialElement room, Document doc) { if (room is null) { throw new ArgumentNullException(nameof(room)); } if (doc is null) { throw new ArgumentNullException(nameof(doc)); } var opt = new SpatialElementBoundaryOptions { SpatialElementBoundaryLocation = Center }; var calc = new SpatialElementGeometryCalculator(doc, opt); var solid = calc.CalculateSpatialElementGeometry(room).GetGeometry(); var instFilter = new FilteredElementCollector(doc).WhereElementIsNotElementType(); var itstFilter = new ElementIntersectsSolidFilter(solid); return(instFilter.WherePasses(itstFilter).ToList()); }
/// <summary> /// Destroys SpatialElementGeometryCalculator object. /// </summary> public static void DestroySpatialElementGeometryCalculator() { if (s_SpatialElementGeometryCalculator != null) { s_SpatialElementGeometryCalculator.Dispose(); s_SpatialElementGeometryCalculator = null; } }
/// <summary> /// 使用空间计算工具计算房间Solid /// </summary> /// <param name="room"></param> /// <returns></returns> /// <remarks>轮廓上没问题,在高度上可能会出错</remarks> public static Solid GetRoomSolid(this Room room) { var bndOpt = new SpatialElementBoundaryOptions(); SpatialElementGeometryCalculator calculator = new SpatialElementGeometryCalculator(room.Document, bndOpt); SpatialElementGeometryResults results = calculator.CalculateSpatialElementGeometry(room); // compute the room geometry Solid roomSolid = results.GetGeometry(); // get the solid representing the room's geometry return(roomSolid); }
public void Draw() { sortedlocalsTech = sortedlocalsTech.Distinct(new CusComparer()).ToList(); try { for (int i = 0; i < sortedlocalsTech.Count(); i += 1) { foreach (var item in sortedlocalsTech.ElementAt(i)) { var myspace = doc.GetElement(item.Id) as Space; SpatialElementGeometryCalculator calculator = new SpatialElementGeometryCalculator(doc); SpatialElementGeometryResults results = calculator.CalculateSpatialElementGeometry(myspace); // compute the room geometry Solid roomSolid = results.GetGeometry(); results.GetGeometry(); XYZ sp = null, ep = null; ElementId levelId = ElementId.InvalidElementId; Document document = uidoc.Document; Utils.lazyInstance.GetElementLocation(out sp, myspace); BoundingBoxXYZ bbxyz = myspace.get_BoundingBox(null); bbxyz.Enabled = true; List <XYZ> edges = new List <XYZ>(); edges.Add(new XYZ(Math.Round(bbxyz.get_Bounds(0).X, 2), Math.Round(bbxyz.get_Bounds(0).Y, 2), Math.Round(bbxyz.get_Bounds(1).Z, 2))); edges.Add(new XYZ(Math.Round(bbxyz.get_Bounds(1).X, 2), Math.Round(bbxyz.get_Bounds(0).Y, 2), Math.Round(bbxyz.get_Bounds(1).Z, 2))); edges.Add(new XYZ(Math.Round(bbxyz.get_Bounds(0).X, 2), Math.Round(bbxyz.get_Bounds(0).Y, 2), Math.Round(bbxyz.get_Bounds(0).Z, 2))); edges.Add(new XYZ(Math.Round(bbxyz.get_Bounds(1).X, 2), Math.Round(bbxyz.get_Bounds(0).Y, 2), Math.Round(bbxyz.get_Bounds(0).Z, 2))); edges.Add(new XYZ(Math.Round(bbxyz.get_Bounds(0).X, 2), Math.Round(bbxyz.get_Bounds(1).Y, 2), Math.Round(bbxyz.get_Bounds(1).Z, 2))); edges.Add(new XYZ(Math.Round(bbxyz.get_Bounds(1).X, 2), Math.Round(bbxyz.get_Bounds(1).Y, 2), Math.Round(bbxyz.get_Bounds(1).Z, 2))); edges.Add(new XYZ(Math.Round(bbxyz.get_Bounds(0).X, 2), Math.Round(bbxyz.get_Bounds(1).Y, 2), Math.Round(bbxyz.get_Bounds(0).Z, 2))); edges.Add(new XYZ(Math.Round(bbxyz.get_Bounds(1).X, 2), Math.Round(bbxyz.get_Bounds(1).Y, 2), Math.Round(bbxyz.get_Bounds(0).Z, 2))); Utils.lazyInstance.GetLowestAndHighestPolygon(edges, myspace.Level); RevitDataContext.lazyInstance.SpacesInfo.Add(myspace, new Tuple <XYZ, List <XYZ>, List <XYZ>, List <XYZ> >(Utils.lazyInstance.GetCenterOfPolygon(edges), edges, new List <XYZ>(Utils.lazyInstance.lowestPolyg), new List <XYZ>(Utils.lazyInstance.highestPolyg))); ep = sp; } Debug.WriteLine("count(): " + RevitDataContext.lazyInstance.SpacesInfo.Count()); CreateDucts(i); correspSmallestSpaces.Clear(); tiltingSpaces.Clear(); currentConnectors.Clear(); CorrespIntersec.Clear(); RevitDataContext.lazyInstance.SpacesInfo.Clear(); } } catch { TaskDialog.Show("Erreur", "Erreur: Vérifier bien que toutes les gaines ont été correctement assigné. Supprimez tous les espaces non assignés et non clos."); } }
public static List <Panel> Panels(this SpatialElement spatialElement, SpatialElementBoundaryOptions spatialElementBoundaryOptions, Core.Revit.ConvertSettings convertSettings) { if (spatialElement == null || spatialElementBoundaryOptions == null) { return(null); } SpatialElementGeometryCalculator spatialElementGeometryCalculator = new SpatialElementGeometryCalculator(spatialElement.Document, spatialElementBoundaryOptions); return(Panels(spatialElement, spatialElementGeometryCalculator, convertSettings)); }
/***************************************************/ public static Space SpaceFromRevit(this SpatialElement spatialElement, SpatialElementBoundaryOptions spatialElementBoundaryOptions, RevitSettings settings = null, Dictionary <string, List <IBHoMObject> > refObjects = null) { if (spatialElement == null || spatialElementBoundaryOptions == null) { return(new Space()); } SpatialElementGeometryCalculator spatialElementGeometryCalculator = new SpatialElementGeometryCalculator(spatialElement.Document, spatialElementBoundaryOptions); return(SpaceFromRevit(spatialElement, spatialElementGeometryCalculator, settings, refObjects)); }
public double CalculateFamilyInstanceBBRadius() { BoundingBoxXYZ familySolidBB = null; using (Transaction tx = new Transaction(m_doc)) { tx.Start("Transaction Temp"); // Get a bottom face from room solid SpatialElementGeometryCalculator calculator = new SpatialElementGeometryCalculator(m_doc); SpatialElementGeometryResults results = calculator.CalculateSpatialElementGeometry(m_room); Solid roomSolid = results.GetGeometry(); PlanarFace roomFace = GetBottomPlanarFaceFromSolid(roomSolid); // Create family instance temporarily FamilyInstance tempInstance = m_doc.Create.NewFamilyInstance(roomFace.Origin, m_familySymbol, m_level, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); // Get a boudingbox of family instance Options getometryOptions = new Options(); getometryOptions.IncludeNonVisibleObjects = false; getometryOptions.View = m_view; GeometryElement geoElem = tempInstance.get_Geometry(getometryOptions); foreach (GeometryObject geoObject in geoElem) { GeometryInstance geoInst = geoObject as GeometryInstance; foreach (GeometryObject instanceGeoObject in geoInst.GetInstanceGeometry()) { if (instanceGeoObject is Solid) { Solid solid = (Solid)instanceGeoObject; familySolidBB = solid.GetBoundingBox(); } } } tx.RollBack(); } // Calculate perimeter of family instance XYZ familySolidBBMaxPt = familySolidBB.Max; XYZ familySolidBBMinPt = familySolidBB.Min; XYZ minPt = new XYZ(familySolidBBMinPt.X, familySolidBBMinPt.Y, 0.0); XYZ maxPt = new XYZ(familySolidBBMaxPt.X, familySolidBBMaxPt.Y, 0.0); double familySolidBBRadius = (minPt.DistanceTo(maxPt)) / 2; familySolidBBRadius = Math.Round(familySolidBBRadius, 4, MidpointRounding.AwayFromZero); return(familySolidBBRadius); }
public static void MoveRoomToCentroid(Document doc, List <Room> modelRooms) { SpatialElementGeometryCalculator geomCalculator = new SpatialElementGeometryCalculator(doc); bool NotEnclosedRooms = false; //declare variable to detect Not Enclosed rooms foreach (Room r in modelRooms) { if (r.Area == 0) //are there not enclosed rooms? { NotEnclosedRooms = true; continue; } if (r.Area > 0) //hadle exception for Not Enclosed rooms when trying to calculate SpatialElementGeometry { Location rLoc = r.Location; LocationPoint currentLoc = (LocationPoint)r.Location; XYZ currentLocPoint = currentLoc.Point; SpatialElementGeometryResults geomResults = geomCalculator.CalculateSpatialElementGeometry(r); Solid roomSolid = geomResults.GetGeometry(); XYZ roomCentroid = roomSolid.ComputeCentroid(); XYZ moveVector = new XYZ(roomCentroid.X - currentLocPoint.X, roomCentroid.Y - currentLocPoint.Y, roomCentroid.Z - currentLocPoint.Z); // don´t move if centroid is outside of a room if (r.IsPointInRoom(roomCentroid)) { rLoc.Move(moveVector); } } } if (NotEnclosedRooms == true) //warn the user about not enclosed rooms { Form.Form_Main.warningMsgMain = "Warning"; Form.Form_Main.warningMsgBody = string.Format("There are 'Not Enclosed' rooms in this project.{0}{0}" + " This application have ignored them," + " but I strongly recommend you to revise them and amend as appropriate." , Environment.NewLine); using (UI.Info.Form_Warning thisForm = new UI.Info.Form_Warning()) { thisForm.ShowDialog(); } } }
public Elements.Element[] FromRevit(Autodesk.Revit.DB.Element revitElement, Document document) { var geomCalculator = new SpatialElementGeometryCalculator(document); var space = revitElement as Autodesk.Revit.DB.Mechanical.Space; var results = geomCalculator.CalculateSpatialElementGeometry(space); var geometry = results.GetGeometry(); var spaceHeight = Elements.Units.FeetToMeters(space.get_BoundingBox(null).Max.Z - space.get_BoundingBox(null).Min.Z); var downfaces = geometry.GetMostLikelyHorizontalFaces(downwardFacing: true); var allRooms = new List <Room>(); foreach (var face in downfaces) { foreach (var profile in face.GetProfiles(true)) { var room = new Room(profile.Perimeter, Vector3.ZAxis, "", "", "", "", 0, 0, 0, 0, spaceHeight, 0, null, Room.RoomMaterial, null, false, Guid.NewGuid(), ""); allRooms.Add(room); } } return(allRooms.ToArray()); }
/// <summary> /// Creates the element in the model /// </summary> /// <param name="doc"></param> public void CreateLocal(StreamMessage message) { //insert at position? //find space it's in? //find family symbol/type? _dispatcher.QueueAction((uiapp) => { var doc = uiapp.ActiveUIDocument.Document; var node = message.After.AsNode(); var nodeElement = doc.GetElement(node.Id); using (var updatetx = new Transaction(doc, "Update from stream")) { updatetx.Start("Update from stream"); if (node.Labels.Contains("FanCoilUnit")) { if (nodeElement == null) { //create node // //get the space it's in var query = @" query($fcuid:ID!){ FanCoilUnit (Id:$fcuid){ Id ModelElements{ Id UniqueId } Space{ Id } ConnectedTo{ Id Apparent_Load ModelElements{ Id UniqueId } } } }"; var vars = new Dictionary <string, object>(); vars.Add("fcuid", node.Id); var res = _client.ExecuteQuery(query, vars); if (res.FanCoilUnit != null) { var fcu = res.FanCoilUnit[0]; Element modelElm = null; foreach (var modelelemet in fcu.ModelElements) { var id = modelelemet.UniqueId.Value; modelElm = doc.GetElement((string)id); if (modelElm != null) { break; } } if (fcu.Space != null) { var spaceId = fcu.Space.Id.Value; //find space var spaceElm = doc.GetElement((string)spaceId) as SpatialElement; if (spaceElm != null) { //find center MEPRevitNode rv = new MEPRevitNode(spaceElm); var sbopt = new SpatialElementBoundaryOptions(); sbopt.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish; sbopt.StoreFreeBoundaryFaces = true; SpatialElementGeometryCalculator sg = new SpatialElementGeometryCalculator(doc, sbopt); var spgets = sg.CalculateSpatialElementGeometry(spaceElm); var spgeo = spgets.GetGeometry(); var center = spgeo.ComputeCentroid(); var bbox = spgeo.GetBoundingBox(); var heightOfUnit = 1; var randomOffset = (bbox.Max.X - bbox.Min.X) / 2 * (new Random().NextDouble() - 0.5); var inspoint = new XYZ(center.X + randomOffset, center.Y, bbox.Max.Z - heightOfUnit); FilteredElementCollector famFilter = new FilteredElementCollector(doc); //this is static for this example. We will need to discover the type and pull the family //from a family library service. string familyName = "HL_FanCoilUnit_HotandChilledWaterSoffit3HorizontalRoundConnections"; Family foundFam = famFilter.OfClass(typeof(Family)).ToElements().OfType <Family>().FirstOrDefault(fm => fm.Name == familyName); var fcuSymbol = doc.GetElement(foundFam.GetFamilySymbolIds().FirstOrDefault()) as FamilySymbol; var newElm = doc.Create.NewFamilyInstance(inspoint, fcuSymbol, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); //var props = MEPGraphUtils.GetNodePropsWithElementProps(new Client.Model.ModelElement(), newElm); //var newnode = _client.Push("ModelElement", props); //_client.Relate(new PendingNode(node), newnode, Client.Model.MEPEdgeTypes.REALIZED_BY, null); var nodeparamers = node.ExtendedProperties; foreach (var param in newElm.Parameters.OfType <Parameter>()) { if (param.IsReadOnly) { continue; } var hp = new HLRevitParameter(param); var paramName = Utils.GetGraphQLCompatibleFieldName(param.Definition.Name); if (nodeparamers.ContainsKey(paramName)) { var incommingValue = nodeparamers[paramName]; var currentValue = MEPGraphUtils.RevitToGraphValue(hp); if (incommingValue != currentValue) { hp.Value = incommingValue; } } } if (fcu.ConnectedTo != null) { string fcuName = "FCU"; Family foundfcuFam = famFilter.OfClass(typeof(Family)).ToElements().OfType <Family>().FirstOrDefault(fm => fm.Name == fcuName); var fcueSymbol = doc.GetElement(foundFam.GetFamilySymbolIds().FirstOrDefault()) as FamilySymbol; var fcuEinspt = inspoint + new XYZ(1, 0, 0); var newFuceElm = doc.Create.NewFamilyInstance(fcuEinspt, fcuSymbol, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); foreach (var param in newFuceElm.Parameters.OfType <Parameter>()) { if (param.IsReadOnly) { continue; } var hp = new HLRevitParameter(param); var paramName = Utils.GetGraphQLCompatibleFieldName(param.Definition.Name); if (fcu.ConnectedTo[paramName] != null) { var incommingValue = fcu.ConnectedTo[paramName].Value; var currentValue = MEPGraphUtils.RevitToGraphValue(hp); if (incommingValue != currentValue) { hp.Value = incommingValue; } } } } } } } } } updatetx.Commit(); } }); }
/// <summary> /// Test whether each room has a roof to bound it. /// </summary> /// <param name="message">Error message to be dumped.</param> /// <param name="elements">Some elements to return.</param> /// <returns></returns> private bool FindRoomBoundingRoofs(ref string message, Autodesk.Revit.DB.ElementSet elements) { // Get all rooms List <Element> rooms = GetRoomsElements(); if (rooms.Count == 0) { message = "Unable to identify any rooms, please create room first!"; return(false); } // Represents the criteria for boundary elements to be considered bounding roofs LogicalOrFilter categoryFilter = new LogicalOrFilter(new ElementCategoryFilter(BuiltInCategory.OST_Roofs), new ElementCategoryFilter(BuiltInCategory.OST_RoofSoffit)); // Calculator for room/space geometry. SpatialElementGeometryCalculator calculator = new SpatialElementGeometryCalculator(m_document); // Stores the resulting room->roof relationships Dictionary <Element, List <ElementId> > roomsAndRoofs = new Dictionary <Element, List <ElementId> >(); foreach (Element room in rooms) { // Get room geometry & boundaries SpatialElementGeometryResults results = calculator.CalculateSpatialElementGeometry((SpatialElement)room); // Get solid geometry so we can examine each face Solid geometry = results.GetGeometry(); foreach (Face face in geometry.Faces) { // Get list of roof boundary subfaces for a given face IList <SpatialElementBoundarySubface> boundaryFaces = results.GetBoundaryFaceInfo(face); foreach (SpatialElementBoundarySubface boundaryFace in boundaryFaces) { // Get boundary element LinkElementId boundaryElementId = boundaryFace.SpatialBoundaryElement; // Only considering local file room bounding elements ElementId localElementId = boundaryElementId.HostElementId; // Evaluate if element meets criteria using PassesFilter() if (localElementId != ElementId.InvalidElementId && categoryFilter.PassesFilter(m_document, localElementId)) { // Room already has roofs, add more if (roomsAndRoofs.ContainsKey(room)) { List <ElementId> roofs = roomsAndRoofs[room]; if (!roofs.Contains(localElementId)) { roofs.Add(localElementId); } } // Room found first roof else { List <ElementId> roofs = new List <ElementId>(); roofs.Add(localElementId); roomsAndRoofs.Add(room, roofs); } break; } } } } // Format results if (roomsAndRoofs.Count > 0) { String logs = String.Format("Rooms that have a bounding roof:"); message += logs + "\t\r\n"; Trace.WriteLine(logs); foreach (KeyValuePair <Element, List <ElementId> > kvp in roomsAndRoofs) { // remove this room from all rooms list rooms.Remove(kvp.Key); List <ElementId> roofs = kvp.Value; String roofsString; // Single roof boundary if (roofs.Count == 1) { Element roof = m_document.GetElement(roofs[0]); roofsString = String.Format("Roof: Id = {0}, Name = {1}", roof.Id.IntegerValue, roof.Name); } // Multiple roofs else { roofsString = "Roofs ids = " + string.Join(", ", Array.ConvertAll <ElementId, string>(roofs.ToArray(), i => i.ToString())); } // Save results logs = String.Format( " Room: Id = {0}, Name = {1} --> {2}", kvp.Key.Id.IntegerValue, kvp.Key.Name, roofsString); message += logs + "\t\r\n"; Trace.WriteLine(logs); } } // Format the rooms that have no bounding roof Trace.WriteLine("Geometry relationship checking finished..."); if (rooms.Count != 0) { String logs = String.Format("Below rooms don't have bounding roofs:"); message += logs + "\t\r\n"; Trace.WriteLine(logs); foreach (Element room in rooms) { elements.Insert(room); logs = String.Format(" Room Id: {0}, Room Name: {1}", room.Id.IntegerValue, room.Name); message += logs + "\t\r\n"; Trace.WriteLine(logs); } } return(true); }
public void ParseFrom(Element elm, MEPRevitGraphWriter writer) { var space = elm as Autodesk.Revit.DB.Mechanical.Space; if (space == null) { return; } if (space.Volume < 0.5) { return; } var scannedElements = writer.Cache.ParsedElements; var cpTree = writer.Cache.connectorsCache; var geoTree = writer.Cache.geoCache; var maxDepth = writer.Cache.MaxDepth; var graph = writer.Graph; var lvl = space.Level; if (lvl != null) { graph.AddConnection(elm, lvl, MEPPathConnectionType.Proximity, MEPEdgeTypes.IS_ON); } //get elements in the space //get areas with edges and add to walls var sbopt = new SpatialElementBoundaryOptions(); sbopt.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish; sbopt.StoreFreeBoundaryFaces = true; //var geoOpt = new Options(); //var spgeo = space.get_Geometry(geoOpt); //get nearby spaces by extending bb of space //foreach each face of space geometry //split into uv gripd //construct line from each point //get intersect with faces on nearby faces //if it hits increment area count for direction var doc = space.Document; SpatialElementGeometryCalculator sg = new SpatialElementGeometryCalculator(doc, sbopt); var spgets = sg.CalculateSpatialElementGeometry(space); var spgeo = spgets.GetGeometry(); //var spbb = spgeo.GetBoundingBox(); var spbb = elm.get_BoundingBox(null); //var spbbhl = new HLBoundingBoxXYZ(spbb); //spbbhl.Size = spbbhl.Size + new XYZ(2, 2, 4); //get faces var uvdensity = 0.75; var maxDistance = 4D; //var nearbyFaces = nearbySpaces.OfType<SolidGeometrySegment>().Where(spc => spc.OriginatingElement != space.Id).SelectMany(sp => sp.Geometry.Faces.OfType<Face>()); var rayIncidents = new HashSet <FaceIntersectRay>(); //get all the faces in the geometry var spfaces = spgeo.Faces.OfType <Face>().ToList(); foreach (var gface in spfaces) { //extract the faces which bound with other elements (Walls, floors, ceilings, windows etc) var sfaceInfos = spgets.GetBoundaryFaceInfo(gface); foreach (var sfaceInfo in sfaceInfos) { //get the geo face and element of this bounding face var sface = sfaceInfo.GetSubface(); var elmId = sfaceInfo.SpatialBoundaryElement; var lelm = GetElementFromLinkedElement(elmId, doc); var docIdent = string.Empty; //if (lelm == null) continue; //ignore this face if it doesn't resolve to a valid element //find the bounding uv box so we can work out a grid of points var fbb = sface.GetBoundingBox(); var uExt = uvdensity; // (fbb.Max.U - fbb.Min.U) / uvdensity; var vExt = uvdensity; // (fbb.Max.V - fbb.Min.V) / uvdensity; var u = fbb.Min.U; var v = fbb.Min.V; //var sb = new GeoLib.C2DPolygon(); //construct grid for ray tracing Stack <UV> gridPoints = new Stack <UV>(); while (u <= fbb.Max.U) { v = fbb.Min.V; while (v <= fbb.Max.V) { var uvp = new UV(u, v); v += uvdensity; if (!sface.IsInside(uvp)) { continue; //only include points that are actually on this face } gridPoints.Push(uvp); } u += uvdensity; } var nerbyCheckCats = new int[] { }; IList <ElementId> hostElms = new List <ElementId>(); if (lelm != null && !(lelm is HostObject)) { var n = lelm; } if (lelm != null) { docIdent = DocUtils.GetDocumentIdent(lelm.Document); //get cutting elemtns if it's a wall so we can find door and windows if (lelm is HostObject) { var whost = lelm as HostObject; hostElms = whost.FindInserts(true, true, true, true); //build oct tree of hostelems so we can quickly ray trace them later foreach (var hostElm in hostElms) { //ignoring any link and transform for now var ehl = whost.Document.GetElement(hostElm); writer.Cache.geoCacheWriter.AddElement(ehl, true); } } //we need the nearby check to find the cut out elements nerbyCheckCats = new int[] { (int)BuiltInCategory.OST_Doors, (int)BuiltInCategory.OST_Windows }; } else { nerbyCheckCats = new int[] { (int)BuiltInCategory.OST_Doors, (int)BuiltInCategory.OST_Windows, (int)BuiltInCategory.OST_Floors, (int)BuiltInCategory.OST_Walls, (int)BuiltInCategory.OST_Roofs }; //we need the nearby check to find the bounding element switch (sfaceInfo.SubfaceType) { case SubfaceType.Bottom: nerbyCheckCats = new int[] { (int)BuiltInCategory.OST_Floors }; break; case SubfaceType.Top: nerbyCheckCats = new int[] { (int)BuiltInCategory.OST_Roofs, (int)BuiltInCategory.OST_Floors, (int)BuiltInCategory.OST_Windows }; break; case SubfaceType.Side: nerbyCheckCats = new int[] { (int)BuiltInCategory.OST_Doors, (int)BuiltInCategory.OST_Windows, (int)BuiltInCategory.OST_Walls }; break; } } //option 1 - brute force ray trace //option 2 - construct 2d polygon from edges of each face, translate each face into the same plane, then boolean intersect, get area of each intersect //calc space boundaries at midpoint? Face optLastIntermeidateFace = null; SolidGeometrySegment optLastIntermeidateSegment = null; Face optLastHitFace = null; SolidGeometrySegment optLastHitSegment = null; var arWeight = sface.Area / gridPoints.Count; while (gridPoints.Count > 0) { var pt = gridPoints.Pop(); var rayIncident = new FaceIntersectRay(); var nv = sface.ComputeNormal(pt).Normalize(); //var mx = sface.ComputeSecondDerivatives(pt).MixedDerivative.Normalize(); rayIncident.SourceElement = space; rayIncident.SourceFace = sface; rayIncident.SourceUV = pt; rayIncident.RayVecotor = nv; rayIncident.IntermediatDocIdent = docIdent; rayIncident.IntermeidateElement = lelm != null ? lelm.Id : ElementId.InvalidElementId; rayIncident.AreaWeight = arWeight; rayIncident.SubFaceType = sfaceInfo.SubfaceType; rayIncidents.Add(rayIncident); var sp = sface.Evaluate(pt); rayIncident.SourceXYZ = sp; var ray = Line.CreateBound(sp, sp + nv * 4); var rayBB = new HLBoundingBoxXYZ(sp, (sp + nv * 4), true); //rayBB.Size = rayBB.Size + new XYZ(0.5, 0.5, 0.5); //Plane geoPlane = Plane.c(sp, sp + nv * 5, sp + nv * 5 + (mx * 0.2)); //SketchPlane skPlane = SketchPlane.Create(doc, geoPlane); //doc.Create.NewModelCurve(ray, skPlane); //check cache for hit on otherside, if there is one nearby on this face we can ignore it as we're not including both sides //var nearbyrayHits = writer.Cache.rayhitCache.GetNearby(ray, 0.4F); //var validSimilarHit = nearbyrayHits.FirstOrDefault(rh => rh.HittingSegment != null && rh.HittingSegment.OriginatingElement == space.Id && rh.IntermeidateElement == rayIncident.IntermeidateElement); //if (validSimilarHit != null && sface.IsInside(validSimilarHit.HittingUV)) //{ // rayIncident.Ignore = true; // log.Info("Got hit on other side, ignoring"); // continue; // } if (optLastIntermeidateFace != null) { IntersectionResultArray issRes = null; var issGeoHit = getIntersect(pt, optLastIntermeidateFace, sface, maxDistance, out issRes, out double distance, nv, doc); if (issGeoHit) { rayIncident.IntermediatDocIdent = optLastIntermeidateSegment.OriginatingDocIdent; rayIncident.IntermeidateElement = optLastIntermeidateSegment.OriginatingElement; } else { optLastIntermeidateFace = null; optLastIntermeidateSegment = null; } } GeometrySegment[] nearbyElements = null; if (optLastIntermeidateFace == null) { nearbyElements = geoTree.GetColliding(rayBB); var nearbyCutoutElements = nearbyElements.Where(iel => (hostElms.Count == 0 || hostElms.Contains(iel.OriginatingElement)) && nerbyCheckCats.Contains(iel.OriginatingElementCategory.IntegerValue)) .OfType <SolidGeometrySegment>(); IntersectionResultArray isRes = null; bool isGeoHit = false; foreach (var extSegment in nearbyCutoutElements) { foreach (var extFace in extSegment.Geometry.Faces.OfType <Face>()) { isGeoHit = getIntersect(pt, extFace, sface, maxDistance, out isRes, out double distance, nv, doc); if (isGeoHit) { rayIncident.IntermediatDocIdent = extSegment.OriginatingDocIdent; rayIncident.IntermeidateElement = extSegment.OriginatingElement; optLastIntermeidateFace = extFace; optLastIntermeidateSegment = extSegment; break; } } if (isGeoHit) { break; } } } if (optLastHitFace != null) { var isHit = getIntersect(pt, optLastHitFace, sface, maxDistance, out var isRe, out double distance, nv, doc); var isRes = isRe; //project point onto other face instead? var srcXYZ = sface.Evaluate(pt); var otXYZRes = optLastHitFace.Project(srcXYZ); if (isHit) { var itx = isRes.OfType <IntersectionResult>().FirstOrDefault(); rayIncident.HittingFace = optLastHitFace; rayIncident.HittingSegment = optLastHitSegment; rayIncident.HittingUV = itx.UVPoint; rayIncident.HittingXYZ = itx.XYZPoint; rayIncident.Distance = distance; nv = sface.ComputeNormal(pt).Normalize(); continue; //shortcut if we find a hit on the same face again } else { optLastHitFace = null; optLastHitSegment = null; } } if (nearbyElements == null) { nearbyElements = geoTree.GetColliding(rayBB, (ob) => { return(ob.OriginatingElementCategory.IntegerValue == (int)BuiltInCategory.OST_MEPSpaces); }); } //BoundingBoxIntersectsFilter bif = new BoundingBoxIntersectsFilter(new Outline(sp - new XYZ(0.1, 0.1, 0.1), (sp + nv * 2) + new XYZ(0.1, 0.1, 0.1))); //var sfv = new FilteredElementCollector(space.Document); //var sepl = sfv.WherePasses(bif).ToElements(); var nearbySpaces = nearbyElements.Where(ne => ne.OriginatingElementCategory.IntegerValue == (int)BuiltInCategory.OST_MEPSpaces).OfType <SolidGeometrySegment>().Distinct().ToList(); //find the extents of this face which face faces on other nearby faces (whaaat?) //check each face of each nearby space for intersect with ray foreach (var nearSpace in nearbySpaces) { var isHit = false; foreach (var otFace in nearSpace.Geometry.Faces.OfType <Face>()) { isHit = getIntersect(pt, otFace, sface, maxDistance, out var isRe, out double distance, nv, doc); var isRes = isRe; //project point onto other face instead? var srcXYZ = sface.Evaluate(pt); var otXYZRes = otFace.Project(srcXYZ); if (isHit) { if (nearSpace.OriginatingElement.IntegerValue != elm.Id.IntegerValue) { var itx = isRes.OfType <IntersectionResult>().FirstOrDefault(); rayIncident.HittingFace = otFace; rayIncident.HittingSegment = nearSpace; rayIncident.HittingUV = itx.UVPoint; rayIncident.HittingXYZ = itx.XYZPoint; rayIncident.Distance = distance; nv = sface.ComputeNormal(pt).Normalize(); //optimization: check this face again first for the next ray check, since it's likely to be another hit optLastHitFace = otFace; optLastHitSegment = nearSpace; rayIncident.Ignore = false; } else { if (distance < 0.1) { isHit = false; //looks like we hit our own face, ouch! } rayIncident.Ignore = true; } break; } } if (isHit) { break; } } } } /* * space * face * intermediate element (Wall/window/door) * face (space) * face * * * add connection * this space -> section -> other space * wall ------------^ */ } //var ec = new elmComparer(); var srcNode = graph.AddElement(space); double minIncluedArea = 4; VectorBucketiser vbw = new VectorBucketiser(8, 5); var includeRays = rayIncidents.Where(r => !r.Ignore); var outsideNode = graph.Nodes.FirstOrDefault(n => n.Name == "Outside"); var groundNode = graph.Nodes.FirstOrDefault(n => n.Name == "Ground"); //group by the intermediate element (wall/floor/etc) foreach (var docGroup in includeRays.GroupBy(ri => ri.IntermediatDocIdent))//, ec)) { var sdoc = DocUtils.GetDocument(docGroup.Key, elm.Document.Application); foreach (var intermediateElemGroup in docGroup.GroupBy(ri => ri.IntermeidateElement.IntegerValue))//, ec)) { var selmid = new ElementId(intermediateElemGroup.Key); Element selm = sdoc != null?sdoc.GetElement(selmid) : null; //group similar vectors into buckets foreach (var rayVectorBuckets in intermediateElemGroup.GroupBy(ri => vbw.GetBucket(ri.RayVecotor))) { var rg = rayVectorBuckets.ToList(); var gs = rg.GroupBy(vr => vr.HittingSegment == null ? null : vr.HittingSegment.OriginatingElement).ToList(); //group each vector and intermediate element by the element it hits foreach (var orgElmGroup in gs) { //find a section already matching this section //actually easier to treat each path as separate sections //var edNodes = graph.GetEdges(intermediateElemGroup.Key).Where(ed => ed.NextNode.AsAbstractNode.Name == "Surface" //&& ed.NextNode.Connections.Any(cn => cn.NextNode.OriginId == spNode.OriginId)).Where(ed => ed.; var apporxIntersect = orgElmGroup.Sum(et => et.AreaWeight); var vector = orgElmGroup.First().RayVecotor; if (apporxIntersect < minIncluedArea) { continue; } var direction = VectorBucketiser.GetZeroClamppedPoint(orgElmGroup.First().RayVecotor); //should be rayVectorGroup.Key.AverageVector, but not yet implemented; MEPRevitNode spNode = null; if (orgElmGroup.Key != null) { var otherSpace = doc.GetElement(orgElmGroup.Key); spNode = graph.AddElement(otherSpace); } else { if (selm != null && (selm.Name.ToLower().Contains("exterior") || selm is Autodesk.Revit.DB.Opening || selm.Name.ToLower().Contains("window") || selm is Autodesk.Revit.DB.RoofBase)) { if (outsideNode == null) { outsideNode = new MEPRevitNode("Outside", "Boundary", "OutsideBoundary", new MEPGraph.Model.Environment()); } spNode = outsideNode; } else if (selm != null && (selm.Name.ToLower().Contains("floor") || selm is Autodesk.Revit.DB.Floor)) { if (groundNode == null) { groundNode = new MEPRevitNode("Ground", "Boundary", "GroundBoundary", new MEPGraph.Model.Environment()); } spNode = groundNode; } else { spNode = new MEPRevitNode("Void", "Boundary", "OtherBoundary", new MEPGraph.Model.VoidVolume()); continue; //ignore void boundaries for now } } var sectionN = graph.NewSection(selm, MEPGraph.Model.MEPEdgeTypes.IS_ON); if (selm == null) { var emptyBondary = new MEPRevitNode(); emptyBondary.AsAbstractNode.Name = "OpenBoundary"; var cl = graph.AddConnection(emptyBondary, sectionN, MEPPathConnectionType.SectionOf, MEPGraph.Model.MEPEdgeTypes.IS_ON); cl.AsNodeEdge.ExtendedProperties.Add("rvid", intermediateElemGroup.Key); } sectionN.AsAbstractNode.Name = "Surface"; var edgesf = graph.AddConnection(srcNode, sectionN, MEPPathConnectionType.Analytical, MEPGraph.Model.MEPEdgeTypes.BOUNDED_BY); //total up intersecting area var sampleIntersect = orgElmGroup.First(); edgesf.SetWeight("Area", apporxIntersect); //edgesf.SetWeight("Direction", new HoareLea.MEPGraph.Model.MEPPoint(direction.X, direction.Y, direction.Z)); edgesf.SetWeight("DirectionX", direction.X); edgesf.SetWeight("DirectionY", direction.Y); edgesf.SetWeight("DirectionZ", direction.Z); edgesf.SetWeight("SubFaceType", (int)sampleIntersect.SubFaceType); /* * HLBoundingBoxXYZ bb = new HLBoundingBoxXYZ(); * foreach (var et in orgElmGroup) * { * if (et.HittingXYZ != null) * { * bb.ExpandToContain(et.HittingXYZ); * } * } * if (!bb.IsInvalid) * { * sectionN.BoundingBox = bb; * var avgCenterPoint = bb.MidPoint; * var size = bb.Size; * sectionN.SetProperty("OriginX", avgCenterPoint.X); * sectionN.SetProperty("OriginY", avgCenterPoint.Y); * sectionN.SetProperty("OriginZ", avgCenterPoint.Z); * sectionN.SetProperty("SizeX", size.X); * sectionN.SetProperty("SizeY", size.Y); * sectionN.SetProperty("SizeZ", size.Z); * }*/ var edgest = graph.AddConnection(sectionN, spNode, MEPPathConnectionType.Analytical, MEPGraph.Model.MEPEdgeTypes.BOUNDED_BY); var directionn = direction;//.Negate(); edgest.SetWeight("Area", apporxIntersect); edgest.SetWeight("DirectionX", directionn.X); edgest.SetWeight("DirectionY", directionn.Y); edgest.SetWeight("DirectionZ", directionn.Z); edgest.SetWeight("SubFaceType", (int)sampleIntersect.SubFaceType); } } } } }
/// <summary> /// Initializes SpatialElementGeometryCalculator object. /// </summary> /// <param name="document"> /// The Revit document. /// </param> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> public static void InitializeSpatialElementGeometryCalculator(Document document, ExporterIFC exporterIFC) { SpatialElementBoundaryOptions options = GetSpatialElementBoundaryOptions(null); s_SpatialElementGeometryCalculator = new SpatialElementGeometryCalculator(document, options); }
public static List <Panel> Panels(this SpatialElement spatialElement, SpatialElementGeometryCalculator spatialElementGeometryCalculator, Core.Revit.ConvertSettings convertSettings) { if (spatialElement == null || spatialElementGeometryCalculator == null) { return(null); } SpatialElementGeometryResults spatialElementGeometryResults = spatialElementGeometryCalculator.CalculateSpatialElementGeometry(spatialElement); if (spatialElementGeometryResults == null) { return(null); } Solid solid = spatialElementGeometryResults.GetGeometry(); if (solid == null) { return(null); } List <Tuple <Face, LinkElementId, SubfaceType> > tuples = new List <Tuple <Face, LinkElementId, SubfaceType> >(); foreach (Face face in solid.Faces) { IList <SpatialElementBoundarySubface> spatialElementBoundarySubfaces = spatialElementGeometryResults.GetBoundaryFaceInfo(face); if (spatialElementBoundarySubfaces == null || spatialElementBoundarySubfaces.Count == 0) { tuples.Add(new Tuple <Face, LinkElementId, SubfaceType>(face, null, SubfaceType.Side)); continue; } foreach (SpatialElementBoundarySubface spatialElementBoundarySubface in spatialElementBoundarySubfaces) { if (spatialElementBoundarySubface == null) { continue; } Face face_Subface = spatialElementBoundarySubface.GetSubface(); //Face face_Subface = spatialElementBoundarySubface.GetSpatialElementFace(); LinkElementId linkElementId = spatialElementBoundarySubface.SpatialBoundaryElement; tuples.Add(new Tuple <Face, LinkElementId, SubfaceType>(face_Subface, linkElementId, spatialElementBoundarySubface.SubfaceType)); } } List <Panel> result = new List <Panel>(); foreach (Tuple <Face, LinkElementId, SubfaceType> tuple in tuples) { List <Geometry.Spatial.Face3D> face3Ds = Geometry.Revit.Convert.ToSAM(tuple.Item1); if (face3Ds == null || face3Ds.Count == 0) { continue; } foreach (Geometry.Spatial.Face3D face3D in face3Ds) { PanelType panelType = PanelType.Undefined; Construction construction = null; Panel panel = null; if (tuple.Item2 != null) { Element element = Core.Revit.Query.Element(spatialElement.Document, tuple.Item2); if (element != null) { HostObject hostObject = element as HostObject; if (hostObject != null) { List <Panel> panels = hostObject.ToSAM(convertSettings); if (panels != null && panels.Count > 0) { panel = panels[0]; } if (panel != null) { construction = panel.Construction; panelType = Analytical.Query.PanelType(construction?.Name); if (panelType == PanelType.Undefined) { panelType = panel.PanelType; } } if (panelType == PanelType.Undefined) { panelType = Query.PanelType(hostObject); } if (construction == null) { ElementId elementId_Type = hostObject.GetTypeId(); if (elementId_Type != null && elementId_Type != ElementId.InvalidElementId) { construction = ((HostObjAttributes)hostObject.Document.GetElement(elementId_Type)).ToSAM(convertSettings); } } } } } if (panelType == PanelType.Undefined) { panelType = Analytical.Query.PanelType(face3D.GetPlane()?.Normal); } if (panelType == PanelType.Undefined) { switch (tuple.Item3) { case SubfaceType.Bottom: panelType = PanelType.Floor; break; case SubfaceType.Top: panelType = PanelType.Roof; break; case SubfaceType.Side: panelType = PanelType.Wall; break; } } if (construction == null) { construction = Analytical.Query.DefaultConstruction(panelType); //Default Construction } if (panel == null) { panel = Analytical.Create.Panel(construction, panelType, face3D); } else { panel = Analytical.Create.Panel(panel.Guid, panel, face3D); } result.Add(panel); } } return(result); }
public static Dictionary <ElementId, double> MaterialsAreas(this SpatialElement spatialElement, double minArea = 0, SpatialElementGeometryCalculator spatialElementGeometryCalculator = null) { if (spatialElement == null) { return(null); } if (double.IsNaN(spatialElement.Area) || spatialElement.Area < minArea) { return(null); } if (spatialElementGeometryCalculator == null) { SpatialElementBoundaryOptions spatialElementBoundaryOptions = new SpatialElementBoundaryOptions() { SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish, StoreFreeBoundaryFaces = false }; spatialElementGeometryCalculator = new SpatialElementGeometryCalculator(spatialElement.Document, spatialElementBoundaryOptions); } SpatialElementGeometryResults spatialElementGeometryResults = spatialElementGeometryCalculator.CalculateSpatialElementGeometry(spatialElement); if (spatialElementGeometryResults == null) { return(null); } Solid solid = spatialElementGeometryResults.GetGeometry(); if (solid == null) { return(null); } Dictionary <ElementId, double> result = new Dictionary <ElementId, double>(); foreach (Face face in solid.Faces) { if (face.Area < minArea) { continue; } foreach (SpatialElementBoundarySubface spatialElementBoundarySubface in spatialElementGeometryResults.GetBoundaryFaceInfo(face)) { Face face_SpatialElement = spatialElementBoundarySubface.GetSpatialElementFace(); if (face_SpatialElement == null) { continue; } if (face_SpatialElement.Area < minArea) { continue; } Face face_BoundingElement = spatialElementBoundarySubface.GetBoundingElementFace(); if (face_BoundingElement == null) { continue; } ElementId elementId = face_BoundingElement.MaterialElementId; if (elementId != null && elementId != Autodesk.Revit.DB.ElementId.InvalidElementId) { if (result.ContainsKey(elementId)) { result[elementId] += face_SpatialElement.Area; } else { result[elementId] = face_SpatialElement.Area; } } } } return(result); }
/// <summary> /// Collect relationship information from Ceiling to Room to be used later to determine whether a Ceiling can be contained in a Room /// </summary> /// <param name="spatialElement">The revit spatial object to process</param> /// <returns></returns> static private bool getCeilingSpaceBoundary(SpatialElement spatialElement) { // Represents the criteria for boundary elements to be considered bounding Ceiling LogicalOrFilter categoryFilter = new LogicalOrFilter(new ElementCategoryFilter(BuiltInCategory.OST_Ceilings), new ElementCategoryFilter(BuiltInCategory.OST_Ceilings)); SpatialElementGeometryCalculator calculator = new SpatialElementGeometryCalculator(spatialElement.Document); SpatialElementGeometryResults results = calculator.CalculateSpatialElementGeometry((SpatialElement)spatialElement); Solid geometry = results.GetGeometry(); // Go through the boundary faces to identify whether it is bounded by a Ceiling. If it is Ceiling, add into the Cache foreach (Face face in geometry.Faces) { IList<SpatialElementBoundarySubface> boundaryFaces = results.GetBoundaryFaceInfo(face); foreach (SpatialElementBoundarySubface boundaryFace in boundaryFaces) { // Get boundary element LinkElementId boundaryElementId = boundaryFace.SpatialBoundaryElement; // Only considering local file room bounding elements ElementId localElementId = boundaryElementId.HostElementId; // Evaluate if element meets criteria using PassesFilter() if (localElementId != ElementId.InvalidElementId && categoryFilter.PassesFilter(spatialElement.Document, localElementId)) { if (ExporterCacheManager.CeilingSpaceRelCache.ContainsKey(localElementId)) { // The ceiling already exists in the Dictionary, add the Space into list IList<ElementId> roomlist = ExporterCacheManager.CeilingSpaceRelCache[localElementId]; roomlist.Add(spatialElement.Id); } else { // The first time this Ceiling Id appears IList<ElementId> roomlist = new List<ElementId>(); roomlist.Add(spatialElement.Id); ExporterCacheManager.CeilingSpaceRelCache.Add(localElementId, roomlist); } } } } return true; }
/***************************************************/ public static Space SpaceFromRevit(this SpatialElement spatialElement, SpatialElementGeometryCalculator spatialElementGeometryCalculator, RevitSettings settings = null, Dictionary <string, List <IBHoMObject> > refObjects = null) { if (spatialElement == null || spatialElementGeometryCalculator == null) { return(new Space()); } settings = settings.DefaultIfNull(); Space space = refObjects.GetValue <Space>(spatialElement.Id); if (space != null) { return(space); } //Create the Space space = new Space(); space.Name = Query.Name(spatialElement); PolyCurve pcurve = spatialElement.Perimeter(settings).FirstOrDefault(); if (pcurve != null) { space.Location = pcurve.Centroid(); space.Perimeter = pcurve; } else if (spatialElement.Location != null && spatialElement.Location is LocationPoint) { space.Location = ((LocationPoint)spatialElement.Location).FromRevit(); } //Set ExtendedProperties OriginContextFragment originContext = new OriginContextFragment() { ElementID = spatialElement.Id.IntegerValue.ToString(), TypeName = Query.Name(spatialElement) }; originContext.SetProperties(spatialElement, settings.ParameterSettings); space.AddFragment(originContext); SpaceAnalyticalFragment spaceAnalytical = new SpaceAnalyticalFragment(); spaceAnalytical.SetProperties(spatialElement, settings.ParameterSettings); space.AddFragment(spaceAnalytical); SpaceContextFragment spaceContext = new SpaceContextFragment(); spaceContext.SetProperties(spatialElement, settings.ParameterSettings); //TODO: Implement ConnectedElements space.AddFragment(spaceContext); //Set identifiers, parameters & custom data space.SetIdentifiers(spatialElement); space.CopyParameters(spatialElement, settings.ParameterSettings); space.SetProperties(spatialElement, settings.ParameterSettings); refObjects.AddOrReplace(spatialElement.Id, space); return(space); }
// defines the Main Method with 1 argument: ActiveUIDoc public void SetRoomFinishingParameters(UIDocument ActiveUIDoc) { //Active document in Revit application Document doc = ActiveUIDoc.Document; //Get collection of Rooms in indicated level IEnumerable <Element> collector = FindRooms(ActiveUIDoc); //List of RoomData List <RoomData> roomDataList = new List <RoomData>(); foreach (Room r in collector) { #region Retrieving of Room Data //List of RoomBoudingElements List <Element> roomBoundingElems = new List <Element>(); // Calculate a room's geometry and find its boundary faces SpatialElementGeometryCalculator calculator = new SpatialElementGeometryCalculator(doc); SpatialElementGeometryResults results = calculator.CalculateSpatialElementGeometry(r); // compute the room geometry Solid roomSolid = results.GetGeometry(); // get the solid representing the room's geometry // Go through the boundary faces to add this element to the list of roomBoundingElems foreach (Face face in roomSolid.Faces) { IList <SpatialElementBoundarySubface> boundaryFaces = results.GetBoundaryFaceInfo(face); foreach (SpatialElementBoundarySubface boundaryFace in boundaryFaces) { // Get boundary element LinkElementId boundaryElementId = boundaryFace.SpatialBoundaryElement; // Only considering local file room bounding elements ElementId localElementId = boundaryElementId.HostElementId; Element elem = doc.GetElement(localElementId); //Add Room Bounding Element to list roomBoundingElems.Add(elem); } } //List of all Element Types of the Room Bounding Elements List <Element> elemsType = new List <Element>(); foreach (Element elem in roomBoundingElems) { ElementId id = elem.GetTypeId(); Element elemType = doc.GetElement(id); elemsType.Add(elemType); } //List of all unique Element Types of the Room Bounding Elements List <Element> elemsTypeDist = elemsType.Distinct(new ElemTypeIdEqualityComparer()).ToList(); //List of all unique Element Types of the Room Bounding Elements with the Floors Assembly Code indicated IEnumerable <Element> finishingFloorsElemsTypes = GetFinishingElemsTypes(elemsTypeDist, finishingFloorsAssemblyCode); //Dictionary with Key values and Keynote Texts Dictionary <string, string> finishingFloorsKeynote = GetKeynote(finishingFloorsElemsTypes, ActiveUIDoc); //Dictionary<string, string> //List of all unique Element Types of the Room Bounding Elements with the Floors Assembly Code indicated IEnumerable <Element> finishingWallsElemsTypes = GetFinishingElemsTypes(elemsTypeDist, finishingWallsAssemblyCode); //Dictionary with Key values and Keynote Texts Dictionary <string, string> finishingWallsKeynote = GetKeynote(finishingWallsElemsTypes, ActiveUIDoc); //List of all unique Element Types of the Room Bounding Elements with the Floors Assembly Code indicated IEnumerable <Element> ceilingsElemsTypes = GetFinishingElemsTypes(elemsTypeDist, ceilingsAssemblyCode); //Dictionary with Key values and Keynote Texts Dictionary <string, string> ceilingsKeynote = GetKeynote(ceilingsElemsTypes, ActiveUIDoc); #endregion // Retrieving of Room Data //new RoomData class per room var RD = new RoomData { room = r, elems = roomBoundingElems, finishingFloors = finishingFloorsKeynote, finishingWalls = finishingWallsKeynote, ceilings = ceilingsKeynote, }; //Adds Room Data to Room Data List roomDataList.Add(RD); } //Fills Parameters FillParameters(roomDataList, doc); }
public static Result ExecuteCalculations(ExternalCommandData commandData) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; Document doc = uidoc.Document; List <string> roomNames = new List <string>(); List <string> areaType = new List <string>(); List <string> areaValue = new List <string>(); List <string> levelNames = new List <string>(); List <string> areaValueCalc = new List <string>(); using (Transaction t = new Transaction(doc, "Turn on volume calculation")) { t.Start(); AreaVolumeSettings settings = AreaVolumeSettings.GetAreaVolumeSettings(doc); settings.ComputeVolumes = true; t.Commit(); } // setup spacial properties SpatialElementBoundaryOptions sebOptions = new SpatialElementBoundaryOptions(); // get all rooms FilteredElementCollector room_collector = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).WhereElementIsNotElementType(); IList <ElementId> room_eids = room_collector.ToElementIds() as IList <ElementId>; foreach (ElementId eid in room_eids) { Room room = doc.GetElement(eid) as Room; { // grab room spacial calculations sebOptions.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Center; SpatialElementGeometryCalculator centerCalc = new SpatialElementGeometryCalculator(doc, sebOptions); SpatialElementGeometryResults center = centerCalc.CalculateSpatialElementGeometry(room); sebOptions.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish; SpatialElementGeometryCalculator finishCalc = new SpatialElementGeometryCalculator(doc, sebOptions); SpatialElementGeometryResults finish = finishCalc.CalculateSpatialElementGeometry(room); // get room properties roomNames.Add(room.Name); areaType.Add("Center"); levelNames.Add(room.Level.Name); areaValue.Add(center.GetGeometry().SurfaceArea.ToString()); TaskDialog.Show("Revit", room.Name + room.Level.Name + center.GetGeometry().SurfaceArea.ToString()); roomNames.Add(room.Name); areaType.Add("Finish"); levelNames.Add(room.Level.Name); areaValue.Add(finish.GetGeometry().SurfaceArea.ToString()); TaskDialog.Show("Revit", room.Name + room.Level.Name + finish.GetGeometry().SurfaceArea.ToString()); } } return(Result.Succeeded); }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Document doc = uidoc.Document; Selection sel = uidoc.Selection; var collector = new FilteredElementCollector(doc); //var rooms = collector.OfClass(typeof(Room)); //var phases = doc.Phases; //foreach (Phase phase in phases) //{ // MessageBox.Show(phase.Name.ToString()); //} if (!(doc.ActiveView is ViewPlan)) { MessageBox.Show("请转到平面视图"); return(Result.Cancelled); } //创建房间(根据墙围成的闭合图形生成房间) var rooms = new List <SpatialElement>(); doc.Invoke(m => { Createrooms(doc, doc.ActiveView.GenLevel, doc.Phases.get_Item(1)); }, "当前视图楼层创建房间"); //下一步用创建的房间进行标高分析 rooms = doc.TCollector <SpatialElement>().ToList(); MessageBox.Show(rooms.Count.ToString()); var names = rooms.Select(m => m.Name); var namestring = string.Join("\n", names); MessageBox.Show(namestring); var geometrys = new List <GeometryObject>(); foreach (SpatialElement spatialElement in rooms) { var geometry = default(GeometryObject); if (SpatialElementGeometryCalculator.IsRoomOrSpace(spatialElement)) { MessageBox.Show(spatialElement.Name + "is roomOrSpace"); } else { MessageBox.Show(spatialElement.Name + "is not roomOrSpace"); } try { geometry = new SpatialElementGeometryCalculator(doc).CalculateSpatialElementGeometry(spatialElement) .GetGeometry(); } catch (Exception e) { var boundaries = spatialElement.GetBoundarySegments(new SpatialElementBoundaryOptions()); MessageBox.Show(boundaries.Count.ToString()); foreach (var boundarySegments in boundaries) { foreach (var boundarySegment in boundarySegments) { var curve = boundarySegment.GetCurve() as Line; if (curve == null) { MessageBox.Show("curve is null"); } doc.NewLine(curve); } } MessageBox.Show("wrong Message Skip this loop"); continue; } //geometrys.Add(geometry); var geometrys1 = new List <GeometryObject>() { geometry }; doc.Invoke(m => { var directShape = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel)); directShape.AppendShape(geometrys1); }, "创建内建模型"); } //SpatialElementGeometryCalculator spatialGeometryCal = new SpatialElementGeometryCalculator(doc); //foreach (Room room in rooms) //{ // var roomGeo = spatialGeometryCal.CalculateSpatialElementGeometry(room); //} return(Result.Succeeded); }
/// <summary> /// Test whether each room has a roof to bound it. /// </summary> /// <param name="message">Error message to be dumped.</param> /// <param name="elements">Some elements to return.</param> /// <returns></returns> private bool FindRoomBoundingRoofs(ref string message, Autodesk.Revit.DB.ElementSet elements) { // Get all rooms List<Element> rooms = GetRoomsElements(); if (rooms.Count == 0) { message = "Unable to identify any rooms, please create room first!"; return false; } // Represents the criteria for boundary elements to be considered bounding roofs LogicalOrFilter categoryFilter = new LogicalOrFilter(new ElementCategoryFilter(BuiltInCategory.OST_Roofs), new ElementCategoryFilter(BuiltInCategory.OST_RoofSoffit)); // Calculator for room/space geometry. SpatialElementGeometryCalculator calculator = new SpatialElementGeometryCalculator(m_document); // Stores the resulting room->roof relationships Dictionary<Element, List<ElementId>> roomsAndRoofs = new Dictionary<Element, List<ElementId>>(); foreach (Element room in rooms) { // Get room geometry & boundaries SpatialElementGeometryResults results = calculator.CalculateSpatialElementGeometry((SpatialElement)room); // Get solid geometry so we can examine each face Solid geometry = results.GetGeometry(); foreach (Face face in geometry.Faces) { // Get list of roof boundary subfaces for a given face IList<SpatialElementBoundarySubface> boundaryFaces = results.GetBoundaryFaceInfo(face); foreach (SpatialElementBoundarySubface boundaryFace in boundaryFaces) { // Get boundary element LinkElementId boundaryElementId = boundaryFace.SpatialBoundaryElement; // Only considering local file room bounding elements ElementId localElementId = boundaryElementId.HostElementId; // Evaluate if element meets criteria using PassesFilter() if (localElementId != ElementId.InvalidElementId && categoryFilter.PassesFilter(m_document, localElementId)) { // Room already has roofs, add more if (roomsAndRoofs.ContainsKey(room)) { List<ElementId> roofs = roomsAndRoofs[room]; if (!roofs.Contains(localElementId)) roofs.Add(localElementId); } // Room found first roof else { List<ElementId> roofs = new List<ElementId>(); roofs.Add(localElementId); roomsAndRoofs.Add(room, roofs); } break; } } } } // Format results if (roomsAndRoofs.Count > 0) { String logs = String.Format("Rooms that have a bounding roof:"); message += logs + "\t\r\n"; Trace.WriteLine(logs); foreach (KeyValuePair<Element, List<ElementId>> kvp in roomsAndRoofs) { // remove this room from all rooms list rooms.Remove(kvp.Key); List<ElementId> roofs = kvp.Value; String roofsString; // Single roof boundary if (roofs.Count == 1) { Element roof = m_document.get_Element(roofs[0]); roofsString = String.Format("Roof: Id = {0}, Name = {1}", roof.Id.IntegerValue, roof.Name); } // Multiple roofs else { roofsString = "Roofs ids = " + string.Join(", ", Array.ConvertAll<ElementId, string>(roofs.ToArray(), i => i.ToString())); } // Save results logs = String.Format( " Room: Id = {0}, Name = {1} --> {2}", kvp.Key.Id.IntegerValue, kvp.Key.Name, roofsString); message += logs + "\t\r\n"; Trace.WriteLine(logs); } } // Format the rooms that have no bounding roof Trace.WriteLine("Geometry relationship checking finished..."); if (rooms.Count != 0) { String logs = String.Format("Below rooms don't have bounding roofs:"); message += logs + "\t\r\n"; Trace.WriteLine(logs); foreach (Element room in rooms) { elements.Insert(room); logs = String.Format(" Room Id: {0}, Room Name: {1}", room.Id.IntegerValue, room.Name); message += logs + "\t\r\n"; Trace.WriteLine(logs); } } return true; }
private void CreateDucts(int jndex) { if (sortedlocalsTech.ElementAt(jndex).ElementAt(0).Name.Contains("GT24")) { Debug.WriteLine("TEST GAINE 24"); } Debug.WriteLine(jndex); ElementId levelId = ElementId.InvalidElementId; tiltingSpaces.Clear(); GetBestPath(); GetTiltingSpace(); GetBestPosition(); currentConn = null; for (int i = 0; i < sortedlocalsTech.ElementAt(jndex).Count();) { if (sortedlocalsTech.ElementAt(jndex).Count() == 1) { Debug.WriteLine("i: " + i); break; } Element e = doc.GetElement(sortedlocalsTech.ElementAt(jndex).ElementAt(i).Id); var space = doc.GetElement(sortedlocalsTech.ElementAt(jndex).ElementAt(i).Id) as Space; try { if (i >= RevitDataContext.lazyInstance.SpacesInfo.Count()) { break; } SpatialElementGeometryCalculator calculator = new SpatialElementGeometryCalculator(doc); SpatialElementGeometryResults results = calculator.CalculateSpatialElementGeometry(space); // compute the room geometry Solid roomSolid = results.GetGeometry(); List <Face> lf = new List <Face>(); List <XYZ> Edges = new List <XYZ>(); List <XYZ> temp = new List <XYZ>(); foreach (Face face in roomSolid.Faces) { foreach (EdgeArray item in face.EdgeLoops) { List <XYZ> lc = JtBoundingBoxXyzExtensionMethods.GetPolygon(item); foreach (var subitem in lc) { temp.Add(subitem); } } } XYZ tempXYZ = null; #region delete identical points, Distinct() linq not that smart foreach (var item in temp) { if (tempXYZ == null) { tempXYZ = item; Edges.Add(item); } else { bool isPresent = false; foreach (var item2 in Edges) { if (item.X == item2.X && item.Y == item2.Y && item.Z == item2.Z) { isPresent = true; } } if (isPresent == false) { Edges.Add(item); } } } #endregion Level currentLevel = null; //Get the duct Type FilteredElementCollector collector1 = new FilteredElementCollector(doc); collector1.OfClass(typeof(DuctType)); DuctType ductType = null; foreach (Element elem in collector1) { /** * Raccord avec té et coude droit * Raccord par té avec coude segmenté * Raccord par piquage et coude segmenté * Raccord par té et coude droit * Raccord par piquage et coude droit * Raccord avec té et coude segmenté * Raccord par piquage et coude à rayon * Raccord par piquage et coude segmenté * Raccord par piquage et coude droit * Raccord par piquage et coude lisse * Raccord avec té et coude lisse * Synoptique de désenfumage * Raccord par piquage et coude droit chanfreiné * Raccord avec té et coude à rayon **/ if (elem.Name == "Raccord avec té et coude lisse" || elem.Name == "Connection with tee and smooth elbow") // gerer english { ductType = elem as DuctType; } } FilteredElementCollector collector2 = new FilteredElementCollector(doc); collector2.OfClass(typeof(MechanicalSystemType)).OfCategory(BuiltInCategory.OST_DuctSystem); MechanicalSystemType mechType = null; foreach (Element e1 in collector2) { /** * Désenfumage air neuf * Conduit de Fumée * Soufflage * Reprise * Extraction * VMC * Desenfumage Extraction * Air Neuf * Rejet * Desenfumage Air Neuf * Soufflage Recylage * Reprise Recyclage * Soufflage VC * Soufflage CTA * .. **/ if (e1.Name == "VMC" || e1.Name == "CMV") // gerer english { mechType = e1 as MechanicalSystemType; } } /** * Get next space **/ bool GetMe = false; int at = 0; foreach (var key in RevitDataContext.lazyInstance.SpacesInfo.Keys) { if (key.Number == space.Number) { GetMe = true; } if (GetMe == true) { if (at != 0) { at -= 1; } break; } at += 1; } currentLevel = e.Document.GetElement(e.LevelId) as Level; XYZ startingPoint = null; XYZ endingPoint = null; /** * Get the starting point shifted depending on next space location * */ Utils.lazyInstance.GetLowestAndHighestPolygon(RevitDataContext.lazyInstance.SpacesInfo.ElementAt(i).Value.Item2, space.Level); List <XYZ> test1 = new List <XYZ>(); List <XYZ> test2 = new List <XYZ>(); test1 = Utils.lazyInstance.lowestPolyg; test2 = Utils.lazyInstance.highestPolyg; if (test1.Count() != 0 && test2.Count() != 0) { startingPoint = Utils.lazyInstance.GetCenterOfPolygon(test1); endingPoint = Utils.lazyInstance.GetCenterOfPolygon(test2); } Utils.lazyInstance.GetLowestAndHighestPolygon(RevitDataContext.lazyInstance.SpacesInfo.ElementAt(correspSmallestSpaces[i]).Value.Item2, RevitDataContext.lazyInstance.SpacesInfo.ElementAt(correspSmallestSpaces[i]).Key.Level); List <XYZ> test5 = new List <XYZ>(); List <XYZ> test6 = new List <XYZ>(); test5 = Utils.lazyInstance.lowestPolyg; test6 = Utils.lazyInstance.highestPolyg; XYZ SendingPoint = Utils.lazyInstance.GetCenterOfPolygon(test6); startingPoint = Utils.lazyInstance.GetCenterOfPolygon(test5); Duct duct = null; Connector ductStart = null; Connector ductEnd = null; Utils.lazyInstance.GetLowestAndHighestPolygon(RevitDataContext.lazyInstance.SpacesInfo.ElementAt(i).Value.Item2, RevitDataContext.lazyInstance.SpacesInfo.ElementAt(i).Key.Level); List <XYZ> test3 = new List <XYZ>(); List <XYZ> test4 = new List <XYZ>(); test3 = Utils.lazyInstance.lowestPolyg; test4 = Utils.lazyInstance.highestPolyg; endingPoint = new XYZ(SendingPoint.X, SendingPoint.Y, Utils.lazyInstance.GetCenterOfPolygon(test4).Z); if (tiltingSpaces.Contains(correspSmallestSpaces[i]) && i != RevitDataContext.lazyInstance.SpacesInfo.Count() - 1) { XYZ nSt = new XYZ(startingPoint.X - 0.1, startingPoint.Y, startingPoint.Z - 0.8); startingPoint = nSt; } Debug.WriteLine("i: " + i); if (!tiltingSpaces.Contains(i) || i == 0 || i == tiltingSpaces.LastOrDefault()) { if (currentConn != null) { XYZ nStart1 = currentConnOrigin; endingPoint = nStart1; } using (Transaction tr = new Transaction(doc)) { tr.Start("Create New Duct"); { if (currentConn == null) { duct = Duct.Create(doc, mechType.Id, ductType.Id, RevitDataContext.lazyInstance.SpacesInfo.ElementAt(i).Key.LevelId, startingPoint, endingPoint); } else { duct = Duct.Create(doc, ductType.Id, RevitDataContext.lazyInstance.SpacesInfo.ElementAt(i).Key.LevelId, currentConn, startingPoint); Debug.WriteLine("currentConn.Origin: " + currentConn.Origin); Debug.WriteLine("startingPoint Origin: " + startingPoint); } Parameter parameter = duct.get_Parameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM); parameter.Set(diameter); List <Connector> lC = new List <Connector>(); foreach (Connector conn in duct.ConnectorManager.Connectors) { if (conn.ConnectorType == ConnectorType.End) { lC.Add(conn); } } if (lC.ElementAt(0).Origin.Z > lC.ElementAt(1).Origin.Z) { ductStart = lC.ElementAt(1); ductEnd = lC.ElementAt(0); } else { ductStart = lC.ElementAt(0); ductEnd = lC.ElementAt(1); } if (currentConn == null) { currentConnectors.Add("start" + i, ductStart); currentConnectors.Add("end" + i, ductEnd); } else { currentConnectors.Add("start" + i, currentConn); currentConnectors.Add("end" + i, ductEnd); doc.Create.NewElbowFitting(ductStart, currentConn); } Debug.WriteLine("Passed, ductStart.Origin : " + ductStart.Origin); tr.Commit(); currentConn = ductEnd; } } } // is getting tilted if (tiltingSpaces.Contains(correspSmallestSpaces[i]) && i != RevitDataContext.lazyInstance.SpacesInfo.Count() - 1 && correspSmallestSpaces[i] != RevitDataContext.lazyInstance.SpacesInfo.Count() - 1) { Utils.lazyInstance.GetLowestAndHighestPolygon(RevitDataContext.lazyInstance.SpacesInfo.ElementAt(correspSmallestSpaces[i + 1]).Value.Item2, RevitDataContext.lazyInstance.SpacesInfo.ElementAt(correspSmallestSpaces[i + 1]).Key.Level); List <XYZ> test7 = new List <XYZ>(); test7 = Utils.lazyInstance.lowestPolyg; var tempZ = startingPoint.Z; endingPoint = new XYZ(Utils.lazyInstance.GetCenterOfPolygon(test7).X, Utils.lazyInstance.GetCenterOfPolygon(test7).Y, tempZ); if (currentConn != null) { Utils.lazyInstance.GetLowestAndHighestPolygon(RevitDataContext.lazyInstance.SpacesInfo.ElementAt(correspSmallestSpaces[correspSmallestSpaces[i] + 1]).Value.Item2, RevitDataContext.lazyInstance.SpacesInfo.ElementAt(correspSmallestSpaces[i + 1]).Key.Level); List <XYZ> test77 = new List <XYZ>(); test77 = Utils.lazyInstance.lowestPolyg; var tempZZ = startingPoint.Z; endingPoint = new XYZ(Utils.lazyInstance.GetCenterOfPolygon(test77).X, Utils.lazyInstance.GetCenterOfPolygon(test77).Y, tempZ); } using (Transaction tr2 = new Transaction(doc)) { tr2.Start("Create New Tilting Duct"); { duct = Duct.Create(doc, mechType.Id, ductType.Id, RevitDataContext.lazyInstance.SpacesInfo.ElementAt(i).Key.LevelId, startingPoint, endingPoint); Debug.WriteLine("startingPoint Origin: " + startingPoint); Debug.WriteLine("endingPoint.Origin: " + endingPoint); Parameter parameter = duct.get_Parameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM); parameter.Set(diameter); List <Connector> lC = new List <Connector>(); foreach (Connector conn in duct.ConnectorManager.Connectors) { if (conn.ConnectorType == ConnectorType.End) { lC.Add(conn); } } int tempi = i + 1; if (i != 0) { tempi = correspSmallestSpaces[correspSmallestSpaces[i] + 1]; } // getting the right start and end duct Utils.lazyInstance.GetLowestAndHighestPolygon(RevitDataContext.lazyInstance.SpacesInfo.ElementAt(tempi).Value.Item2, RevitDataContext.lazyInstance.SpacesInfo.ElementAt(tempi).Key.Level); List <XYZ> test8 = new List <XYZ>(); test8 = Utils.lazyInstance.lowestPolyg; lC = Utils.lazyInstance.GetClosestConnector(lC, Utils.lazyInstance.GetCenterOfPolygon(test8)); ductStart = lC.ElementAt(0); ductEnd = lC.ElementAt(1); currentConnOrigin = ductStart.Origin; test11 = ductEnd.Origin; Debug.WriteLine("Start of tilting is :" + ductStart.Origin); Debug.WriteLine("end of tilting is :" + ductEnd.Origin); currentConn = ductStart; doc.Create.NewElbowFitting(ductEnd, currentConnectors.ElementAt(currentConnectors.Count() - 1).Value); currentConnectors.Add("startTilted" + i, ductStart); currentConnectors.Add("endTilted" + i, ductEnd); } tr2.Commit(); } } i = correspSmallestSpaces[i] + 1; currentElement = e; } catch (Exception ex) { break; } } }