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;
}
}
}