using Autodesk.Revit.DB; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace GraphicsStudy { public static class GeoMethod { /// /// 得到墙的最底面的线 /// /// /// public static List GetGeoEleDownLine(GeometryElement geo) { List geoLineList = new List(); foreach (GeometryObject geoObject in geo) { Solid geoSolid = geoObject as Solid; foreach (Face geoFace in geoSolid.Faces) { PlanarFace temFace = geoFace as PlanarFace; if (Math.Abs(temFace.FaceNormal.X) < 0.01 && Math.Abs(temFace.FaceNormal.Y) < 0.01 && temFace.FaceNormal.Z < 0) { foreach (EdgeArray eArr in temFace.EdgeLoops) { foreach (Edge e in eArr) { try { if (e.AsCurve() is Autodesk.Revit.DB.Line l1) { geoLineList.Add(l1.SetZ()); } } catch { continue; } } } } } } return geoLineList.JoinLines(0.01); } /// /// 得到墙的最底面的面 /// /// /// public static PlanarFace GetGeoEleDownFace(GeometryElement geo) { PlanarFace face = null; foreach (GeometryObject geoObject in geo) { Solid geoSolid = geoObject as Solid; foreach (Face geoFace in geoSolid.Faces) { PlanarFace temFace = geoFace as PlanarFace; if (Math.Abs(temFace.FaceNormal.X) < 0.01 && Math.Abs(temFace.FaceNormal.Y) < 0.01 && temFace.FaceNormal.Z < 0) { face = temFace; break; } } } return face; } /// /// 得到集合体所有的面 /// /// /// public static List GetSolidAllFace(this Solid s) { List allFace = new List(); foreach (Face f in s.Faces) { allFace.Add(f); } return allFace; } /// /// 计算几何体的表面积 /// /// /// public static double CalculatedSurfaceArea(this Solid s) { double surfaceArea = 0; List allFace = s.GetSolidAllFace(); foreach (Face f in allFace) { surfaceArea += f.Area; } return surfaceArea; } /// /// 返回几何体的最底面 /// /// /// public static Face GetSolidDownFace(this Solid solid) { Face face = null; foreach (Face geoFace in solid.Faces) { PlanarFace temFace = geoFace as PlanarFace; if (Math.Abs(temFace.FaceNormal.X) < 0.01 && Math.Abs(temFace.FaceNormal.Y) < 0.01 && temFace.FaceNormal.Z < 0) { face = temFace; break; } } return face; } /// /// 获取构件集合的Solids集合 /// /// 构件集合 /// public static List GetSolidByElements(this List elements) { List result = new List(); Options options = new Options(); elements.ForEach(e => { GeometryElement geometryElement = e.get_Geometry(options); List solids = GetSolids(geometryElement); if (solids.Count > 0) { result.AddRange(solids); } }); return result; } /// /// 获取所有的Solid /// /// /// public static List GetSolids(GeometryElement geometryElement) { List result = new List(); foreach (GeometryObject geomObj in geometryElement) { Solid solid = geomObj as Solid; if (null != solid) { result.Add(solid); continue; } //If this GeometryObject is Instance, call AddCurvesAndSolids GeometryInstance geomInst = geomObj as GeometryInstance; if (null != geomInst) { GeometryElement transformedGeomElem = geomInst.GetInstanceGeometry(geomInst.Transform); result.AddRange(GetSolids(transformedGeomElem)); } } return result; } /// /// Solid布尔操作 /// /// /// /// /// public static Solid SolidBooleanOperation(Solid solidA, Solid solidB, BooleanOperationsType booleanOperationsType) { Solid result = null; try { result = BooleanOperationsUtils.ExecuteBooleanOperation(solidA, solidB, booleanOperationsType); } catch (Exception ex) { result = BooleanOperationsUtils.ExecuteBooleanOperation(solidB, solidA, booleanOperationsType); } return result; } /// /// 计算几何体的中点 /// /// /// public static XYZ GetSolidCenter(this Solid solid) { XYZ centerPoint = null; foreach (Face geoFace in solid.Faces) { PlanarFace temFace = geoFace as PlanarFace; if (Math.Abs(temFace.FaceNormal.X) < 0.01 && Math.Abs(temFace.FaceNormal.Y) < 0.01 && temFace.FaceNormal.Z < 0) { var faceBound = temFace.GetBoundingBox(); UV maxUV = faceBound.Max; UV minUV = faceBound.Min; UV uvPoint = (maxUV + minUV) / 2; centerPoint = temFace.Evaluate(uvPoint).SetZ(); break; } } return centerPoint; } // /// 传入集合的集合体,批量操作 /// /// /// /// public static Solid SolidBatchBoolean(this List solids, BooleanOperationsType booleanOperationsType) { Solid firstSolid = solids[0]; solids.RemoveAt(0); //对所有的几何体进行融合 foreach (var oneSoild in solids) { try { firstSolid = GeoMethod.SolidBooleanOperation(firstSolid, oneSoild, booleanOperationsType); } catch { } } return firstSolid; } } }