예제 #1
0
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            Document      doc   = uiapp.ActiveUIDocument.Document;
            Result        rc;

            try
            {
                SpatialElementBoundaryOptions sebOptions
                    = new SpatialElementBoundaryOptions
                    {
                    SpatialElementBoundaryLocation
                        = SpatialElementBoundaryLocation.Finish
                    };

                IEnumerable <Element> rooms
                    = new FilteredElementCollector(doc)
                      .OfClass(typeof(SpatialElement))
                      .Where <Element>(e => (e is Room));

                List <string>  compareWallAndRoom = new List <string>();
                OpeningHandler openingHandler     = new OpeningHandler();

                List <SpatialBoundaryCache> lstSpatialBoundaryCache
                    = new List <SpatialBoundaryCache>();

                foreach (Room room in rooms)
                {
                    if (room == null)
                    {
                        continue;
                    }
                    if (room.Location == null)
                    {
                        continue;
                    }
                    if (room.Area.Equals(0))
                    {
                        continue;
                    }

                    Autodesk.Revit.DB.SpatialElementGeometryCalculator calc =
                        new Autodesk.Revit.DB.SpatialElementGeometryCalculator(
                            doc, sebOptions);

                    SpatialElementGeometryResults results
                        = calc.CalculateSpatialElementGeometry(
                              room);

                    Solid roomSolid = results.GetGeometry();

                    foreach (Face face in results.GetGeometry().Faces)
                    {
                        IList <SpatialElementBoundarySubface> boundaryFaceInfo
                            = results.GetBoundaryFaceInfo(face);

                        foreach (var spatialSubFace in boundaryFaceInfo)
                        {
                            if (spatialSubFace.SubfaceType
                                != SubfaceType.Side)
                            {
                                continue;
                            }

                            SpatialBoundaryCache spatialData
                                = new SpatialBoundaryCache();

                            Wall wall = doc.GetElement(spatialSubFace
                                                       .SpatialBoundaryElement.HostElementId)
                                        as Wall;

                            if (wall == null)
                            {
                                continue;
                            }

                            WallType wallType = doc.GetElement(
                                wall.GetTypeId()) as WallType;

                            if (wallType.Kind == WallKind.Curtain)
                            {
                                // Leave out, as curtain walls are not painted.

                                LogCreator.LogEntry("WallType is CurtainWall");

                                continue;
                            }

                            HostObject hostObject = wall as HostObject;

                            IList <ElementId> insertsThisHost
                                = hostObject.FindInserts(
                                      true, false, true, true);

                            double openingArea = 0;

                            foreach (ElementId idInsert in insertsThisHost)
                            {
                                string countOnce = room.Id.ToString()
                                                   + wall.Id.ToString() + idInsert.ToString();

                                if (!compareWallAndRoom.Contains(countOnce))
                                {
                                    Element elemOpening = doc.GetElement(
                                        idInsert) as Element;

                                    openingArea = openingArea
                                                  + openingHandler.GetOpeningArea(
                                        wall, elemOpening, room, roomSolid);

                                    compareWallAndRoom.Add(countOnce);
                                }
                            }

                            // Cache SpatialElementBoundarySubface info.

                            spatialData.roomName   = room.Name;
                            spatialData.idElement  = wall.Id;
                            spatialData.idMaterial = spatialSubFace
                                                     .GetBoundingElementFace().MaterialElementId;
                            spatialData.dblNetArea = Util.sqFootToSquareM(
                                spatialSubFace.GetSubface().Area - openingArea);
                            spatialData.dblOpeningArea = Util.sqFootToSquareM(
                                openingArea);

                            lstSpatialBoundaryCache.Add(spatialData);
                        } // end foreach subface from which room bounding elements are derived
                    }     // end foreach Face
                }         // end foreach Room

                List <string> t = new List <string>();

                List <SpatialBoundaryCache> groupedData
                    = SortByRoom(lstSpatialBoundaryCache);

                foreach (SpatialBoundaryCache sbc in groupedData)
                {
                    t.Add(sbc.roomName
                          + "; all wall types and materials: "
                          + sbc.AreaReport);
                }

                Util.InfoMsg2("Total Net Area in m2 by Room",
                              string.Join(System.Environment.NewLine, t));

                t.Clear();

                groupedData = SortByRoomAndWallType(
                    lstSpatialBoundaryCache);

                foreach (SpatialBoundaryCache sbc in groupedData)
                {
                    Element elemWall = doc.GetElement(
                        sbc.idElement) as Element;

                    t.Add(sbc.roomName + "; " + elemWall.Name
                          + "(" + sbc.idElement.ToString() + "): "
                          + sbc.AreaReport);
                }

                Util.InfoMsg2("Net Area in m2 by Wall Type",
                              string.Join(System.Environment.NewLine, t));

                t.Clear();

                groupedData = SortByRoomAndMaterial(
                    lstSpatialBoundaryCache);

                foreach (SpatialBoundaryCache sbc in groupedData)
                {
                    string materialName
                        = (sbc.idMaterial == ElementId.InvalidElementId)
              ? string.Empty
              : doc.GetElement(sbc.idMaterial).Name;

                    t.Add(sbc.roomName + "; " + materialName + ": "
                          + sbc.AreaReport);
                }

                Util.InfoMsg2(
                    "Net Area in m2 by Outer Layer Material",
                    string.Join(System.Environment.NewLine, t));

                rc = Result.Succeeded;
            }
            catch (Exception ex)
            {
                TaskDialog.Show("Room Boundaries",
                                ex.Message + "\r\n" + ex.StackTrace);

                rc = Result.Failed;
            }
            return(rc);
        }
예제 #2
0
        /// <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);
        }
        /// <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>
        /// <param name="results">The results of the CalculateSpatialElementGeometry call, for caching for later use.</param>
        /// <returns>True if it found a ceiling, false otherwise.</returns>
        static private bool GetCeilingSpaceBoundary(SpatialElement spatialElement, out SpatialElementGeometryResults results)
        {
            results = null;
            
            // Areas don't have a 3D rep, so no ceiling space boundaries.
            if (spatialElement is Area)
                return false;

            // 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));

            try
            {
                results = s_SpatialElementGeometryCalculator.CalculateSpatialElementGeometry(spatialElement);
            }
            catch
            {
                return false;
            }
            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;
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
        // 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);
        }