public double GetWallAsOpeningArea( Element elemOpening, Solid solidRoom) { Document doc = elemOpening.Document; Wall wallAsOpening = elemOpening as Wall; // most likely an embedded curtain wall Options options = doc.Application.Create.NewGeometryOptions(); options.ComputeReferences = true; options.IncludeNonVisibleObjects = true; List <Element> walls = new List <Element>(); walls.Add(wallAsOpening); // To my recollection this won't // pick up an edited wall profile List <List <XYZ> > polygons = GetWallProfilePolygons( walls, options); IList <CurveLoop> solidProfile = XYZAsCurveloop(polygons.First()); Solid solidOpening = GeometryCreationUtilities .CreateExtrusionGeometry(solidProfile, wallAsOpening.Orientation, 1); Solid intersectSolid = BooleanOperationsUtils .ExecuteBooleanOperation(solidOpening, solidRoom, BooleanOperationsType.Intersect); if (intersectSolid.Faces.Size.Equals(0)) { // Then we are extruding in the wrong direction solidOpening = GeometryCreationUtilities .CreateExtrusionGeometry(solidProfile, wallAsOpening.Orientation.Negate(), 1); intersectSolid = BooleanOperationsUtils .ExecuteBooleanOperation(solidOpening, solidRoom, BooleanOperationsType.Intersect); } if (DebugHandler.EnableSolidUtilityVolumes) { using (Transaction t = new Transaction(doc)) { t.Start("Test1"); ShapeCreator.CreateDirectShape(doc, intersectSolid, "namesolid"); t.Commit(); } } double openingArea = GetLargestFaceArea( intersectSolid); LogCreator.LogEntry(";_______OPENINGAREA;" + elemOpening.Id.ToString() + ";" + elemOpening.Category.Name + ";" + elemOpening.Name + ";" + (openingArea * 0.09290304).ToString()); return(openingArea); }
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); }
static bool GetProfile( List <List <XYZ> > polygons, Solid solid, XYZ v, XYZ w) { double d, dmax = 0; PlanarFace outermost = null; FaceArray faces = solid.Faces; foreach (Face f in faces) { PlanarFace pf = f as PlanarFace; if (null != pf && Util.IsVertical(pf) && Util.IsZero(v.DotProduct(pf.FaceNormal))) { d = pf.Origin.DotProduct(w); if ((null == outermost) || (dmax < d)) { outermost = pf; dmax = d; } } } if (null != outermost) { XYZ voffset = _offset * w; XYZ p, q = XYZ.Zero; bool first; int i, n; EdgeArrayArray loops = outermost.EdgeLoops; foreach (EdgeArray loop in loops) { List <XYZ> vertices = new List <XYZ>(); first = true; foreach (Edge e in loop) { IList <XYZ> points = e.Tessellate(); p = points[0]; if (!first) { if (!p.IsAlmostEqualTo(q)) { LogCreator.LogEntry("Expected " + "subsequent start point to equal " + "previous end point"); } } n = points.Count; q = points[n - 1]; for (i = 0; i < n - 1; ++i) { XYZ a = points[i]; a += voffset; vertices.Add(a); } } q += voffset; if (!q.IsAlmostEqualTo(vertices[0])) { LogCreator.LogEntry("Expected last end " + "point to equal first start point"); } polygons.Add(vertices); } } return(null != outermost); }