public void GetWallGrossAreaAndRollBack() { var testModel = Utils.GetTestModel("walls.rvt"); var doc = xru.OpenDoc(testModel); var walls = new FilteredElementCollector(doc).WhereElementIsNotElementType().OfCategory(BuiltInCategory.OST_Walls).ToElements(); var wall = walls[0] as Wall; double grossArea = 0; var inserts = wall.FindInserts(true, true, true, true); xru.Run(() => { using (Transaction transaction = new Transaction(doc, "Temporary - only to get gross area")) { transaction.Start(); foreach (ElementId insertId in inserts) { doc.Delete(insertId); } doc.Regenerate(); var wallFaceReference = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior); var face = doc.GetElement(wallFaceReference.First()).GetGeometryObjectFromReference(wallFaceReference.First()) as PlanarFace; var wallFaceEdges = face.GetEdgesAsCurveLoops(); grossArea = ExporterIFCUtils.ComputeAreaOfCurveLoops(wallFaceEdges); transaction.RollBack(); } }, doc).Wait(); Assert.True(grossArea > 0); }
public int Compare(CurveArray x, CurveArray y) { IList <CurveLoop> curveLoopX = new List <CurveLoop> { CurveArrayToCurveLoop(x) }; double areaX = ExporterIFCUtils.ComputeAreaOfCurveLoops(curveLoopX); IList <CurveLoop> curveLoopY = new List <CurveLoop> { CurveArrayToCurveLoop(y) }; double areaY = ExporterIFCUtils.ComputeAreaOfCurveLoops(curveLoopY); if (areaX < areaY) { return(1); } if (areaX > areaY) { return(-1); } else { return(0); } }
/// <summary> /// 获取房间最外圈的CurveLoop /// </summary> /// <param name="room"></param> /// <returns></returns> public static CurveLoop GetRoomMaxCurveLoop(this Room room) { var loops = GetRoomBoundaryAsCurveLoopArray(room); if (loops != null && loops.Count > 0) { return(loops.OrderBy(x => ExporterIFCUtils.ComputeAreaOfCurveLoops(new List <CurveLoop> { x })).LastOrDefault()); } return(null); }
/// <summary> /// Calculates a CurveArray that corresponds the perimeter of a building given all its internal loops. /// The building MUST be surround by walls. /// </summary> /// <returns> /// Returns a CurveArray that corresponds to the house perimeter. /// </returns> public CurveArray GetHousePerimeter() { foreach (Room room in Rooms) { // if there more than 1 loop, that means that this circuit represents the external area IList <IList <BoundarySegment> > loops = GetRoomLoops(room); if (loops.Count > 1) { // first of all we find the closed loop with the smaller area double minArea = double.MaxValue; IList <BoundarySegment> perimeterSegments = null; foreach (IList <BoundarySegment> singleLoop in loops) { double area = 0; // transforms the boundary segments into a CurveLoop CurveLoop currentCurve = new CurveLoop(); foreach (BoundarySegment seg in singleLoop) { currentCurve.Append(seg.GetCurve()); } // save the segments with the smaller area, which represents the house perimeter IList <CurveLoop> curveLoopList = new List <CurveLoop> { currentCurve }; area = ExporterIFCUtils.ComputeAreaOfCurveLoops(curveLoopList); if (area < minArea) { minArea = area; perimeterSegments = singleLoop; } } // and then we create a curve array with the boundary segments of that loop return(BoundarySegmentToCurveArray(perimeterSegments)); } } return(null); }
/// <summary> /// Creates an opening from extrusion data. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="hostObjHnd">The host handle.</param> /// <param name="hostPlacement">The host placement.</param> /// <param name="hostElement">The host element.</param> /// <param name="insertElement">The opening element.</param> /// <param name="openingGUID">The opening GUID.</param> /// <param name="extrusionData">The extrusion data.</param> /// <param name="plane">The plane.</param> /// <param name="isRecess">True if it is a recess.</param> /// <returns>The opening handle.</returns> static public IFCAnyHandle CreateOpening(ExporterIFC exporterIFC, IFCAnyHandle hostObjHnd, IFCAnyHandle hostPlacement, Element hostElement, Element insertElement, string openingGUID, IFCExtrusionData extrusionData, Plane plane, bool isRecess, PlacementSetter setter, ProductWrapper localWrapper) { IFCFile file = exporterIFC.GetFile(); IList <CurveLoop> curveLoops = extrusionData.GetLoops(); if (curveLoops.Count == 0) { return(null); } if (plane == null) { // assumption: first curve loop defines the plane. if (!curveLoops[0].HasPlane()) { return(null); } plane = curveLoops[0].GetPlane(); } ElementId catId = CategoryUtil.GetSafeCategoryId(insertElement); IFCAnyHandle openingProdRepHnd = RepresentationUtil.CreateExtrudedProductDefShape(exporterIFC, insertElement, catId, curveLoops, plane, extrusionData.ExtrusionDirection, extrusionData.ScaledExtrusionLength); string openingObjectType = isRecess ? "Recess" : "Opening"; IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string openingName = NamingUtil.GetNameOverride(insertElement, null); if (string.IsNullOrEmpty(openingName)) { openingName = NamingUtil.GetNameOverride(hostElement, NamingUtil.CreateIFCObjectName(exporterIFC, hostElement)); } IFCAnyHandle openingHnd = IFCInstanceExporter.CreateOpeningElement(file, openingGUID, ownerHistory, openingName, null, openingObjectType, ExporterUtil.CreateLocalPlacement(file, hostPlacement, null), openingProdRepHnd, null); IFCExtrusionCreationData ecData = null; if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities) { double height, width; ecData = new IFCExtrusionCreationData(); if (GeometryUtil.ComputeHeightWidthOfCurveLoop(curveLoops[0], plane, out height, out width)) { ecData.ScaledHeight = UnitUtil.ScaleLength(height); ecData.ScaledWidth = UnitUtil.ScaleLength(width); } else { double area = ExporterIFCUtils.ComputeAreaOfCurveLoops(curveLoops); ecData.ScaledArea = UnitUtil.ScaleArea(area); } PropertyUtil.CreateOpeningQuantities(exporterIFC, openingHnd, ecData); } if (localWrapper != null) { Element elementForProperties = null; if (GUIDUtil.IsGUIDFor(insertElement, openingGUID)) { elementForProperties = insertElement; } localWrapper.AddElement(elementForProperties, openingHnd, setter, ecData, true); } string voidGuid = GUIDUtil.CreateGUID(); IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null, hostObjHnd, openingHnd); return(openingHnd); }
/// <summary> /// 计算多边形的面积 /// </summary> /// <param name="loops"></param> /// <returns></returns> public static double ComputeArea(this IList <CurveLoop> loops) { return(ExporterIFCUtils.ComputeAreaOfCurveLoops(loops)); }
/// <summary> /// 计算面积 /// </summary> /// <param name="loop"></param> /// <returns></returns> public static double ComputeArea(this CurveLoop loop) { return(ExporterIFCUtils.ComputeAreaOfCurveLoops(new List <CurveLoop> { loop })); }
public double GetWallCutArea( FamilyInstance fi, Wall wall) { Document doc = fi.Document; XYZ cutDir = null; CurveLoop curveLoop = ExporterIFCUtils.GetInstanceCutoutFromWall( fi.Document, wall, fi, out cutDir); IList <CurveLoop> loops = new List <CurveLoop>(1); loops.Add(curveLoop); if (!wall.IsStackedWallMember) { return(ExporterIFCUtils.ComputeAreaOfCurveLoops(loops)); } else { // Will not get multiple stacked walls with // varying thickness due to the nature of rooms. // Use ReferenceIntersector if we can identify // those missing room faces...open for suggestions. SolidHandler solHandler = new SolidHandler(); Options optCompRef = doc.Application.Create.NewGeometryOptions(); if (null != optCompRef) { optCompRef.ComputeReferences = true; optCompRef.DetailLevel = ViewDetailLevel.Medium; } GeometryElement geomElemHost = wall.get_Geometry(optCompRef) as GeometryElement; Solid solidOpening = GeometryCreationUtilities .CreateExtrusionGeometry(loops, cutDir.Negate(), .1); Solid solidHost = solHandler.CreateSolidFromBoundingBox( null, geomElemHost.GetBoundingBox(), null); // We dont really care about the boundingbox // rotation as we only need the intersected solid. if (solidHost == null) { return(0); } Solid intersectSolid = BooleanOperationsUtils .ExecuteBooleanOperation(solidOpening, solidHost, BooleanOperationsType.Intersect); if (intersectSolid.Faces.Size.Equals(0)) { solidOpening = GeometryCreationUtilities .CreateExtrusionGeometry(loops, cutDir, .1); intersectSolid = BooleanOperationsUtils .ExecuteBooleanOperation(solidOpening, solidHost, BooleanOperationsType.Intersect); } if (DebugHandler.EnableSolidUtilityVolumes) { using (Transaction t = new Transaction(doc)) { t.Start("Stacked1"); ShapeCreator.CreateDirectShape(doc, intersectSolid, "stackedOpening"); t.Commit(); } } return(solHandler.GetLargestFaceArea( intersectSolid)); } }