233 lines
9.8 KiB
C#
233 lines
9.8 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using Autodesk.Revit.DB;
|
||
using Autodesk.Revit.DB.Structure;
|
||
|
||
namespace uBIM_EarthTools
|
||
{
|
||
class Common
|
||
{
|
||
/// <summary>
|
||
/// 三角剖分
|
||
/// </summary>
|
||
/// <param name="boreholeList">钻孔列表</param>
|
||
/// <param name="tolerance">排除过长三角形边边长</param>
|
||
/// <returns>钻孔编号索引</returns>
|
||
public static List<int[]> Delaunay(List<Borehole> boreholeList, double tolerance)
|
||
{
|
||
List<int[]> list = new List<int[]>();
|
||
List<XYZ> xyzList = boreholeList.Select(x => new XYZ(x.ValueList[0].Point.X, x.ValueList[0].Point.Y, 0)).ToList();
|
||
TriangleNet.Mesh mesh = new TriangleNet.Mesh();
|
||
TriangleNet.Geometry.InputGeometry inputGeometry = new TriangleNet.Geometry.InputGeometry(boreholeList.Count);
|
||
|
||
foreach (XYZ item in xyzList)
|
||
{
|
||
inputGeometry.AddPoint(item.X, item.Y);
|
||
}
|
||
mesh.Triangulate(inputGeometry);
|
||
foreach (TriangleNet.Data.Triangle item in mesh.Triangles)
|
||
{
|
||
if (IsCollinear(item) || MaxEdge(item) > tolerance)
|
||
continue;
|
||
int[] index = new int[3];
|
||
index[0] = item.P0;
|
||
index[1] = item.P1;
|
||
index[2] = item.P2;
|
||
list.Add(index);
|
||
}
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 判断三角形三点是否接近共线
|
||
/// </summary>
|
||
/// <param name="triangle"></param>
|
||
/// <returns></returns>
|
||
public static bool IsCollinear(TriangleNet.Data.Triangle triangle)
|
||
{
|
||
XYZ p0 = new XYZ(triangle.GetVertex(0).X, triangle.GetVertex(0).Y, 0);
|
||
XYZ p1 = new XYZ(triangle.GetVertex(1).X, triangle.GetVertex(1).Y, 0);
|
||
XYZ p2 = new XYZ(triangle.GetVertex(2).X, triangle.GetVertex(2).Y, 0);
|
||
Line line1 = Line.CreateUnbound(p0, p1 - p0);
|
||
Line line2 = Line.CreateUnbound(p1, p2 - p1);
|
||
Line line3 = Line.CreateUnbound(p2, p0 - p2);
|
||
double d1 = line1.Project(p2).Distance / p0.DistanceTo(p1);
|
||
double d2 = line2.Project(p0).Distance / p1.DistanceTo(p2);
|
||
double d3 = line3.Project(p1).Distance / p2.DistanceTo(p0);
|
||
if (Math.Min(Math.Min(d1, d2), d3) < 0.02)
|
||
return true;
|
||
else
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 三角形最长边长度
|
||
/// </summary>
|
||
/// <param name="triangle"></param>
|
||
/// <returns></returns>
|
||
public static double MaxEdge(TriangleNet.Data.Triangle triangle)
|
||
{
|
||
XYZ p0 = new XYZ(triangle.GetVertex(0).X, triangle.GetVertex(0).Y, 0);
|
||
XYZ p1 = new XYZ(triangle.GetVertex(1).X, triangle.GetVertex(1).Y, 0);
|
||
XYZ p2 = new XYZ(triangle.GetVertex(2).X, triangle.GetVertex(2).Y, 0);
|
||
return Math.Max(Math.Max(p0.DistanceTo(p1), p1.DistanceTo(p2)), p0.DistanceTo(p2));
|
||
}
|
||
|
||
public static int IsTypeEquals(List<Borehole> boreholeList)
|
||
{
|
||
List<string> typeList = boreholeList.Select(x => x.CurrentType).ToList();
|
||
if (typeList[0].Equals(typeList[1]) && typeList[0].Equals(typeList[2]))
|
||
return 1;
|
||
else if (typeList[0].Equals(typeList[1]) && !typeList[0].Equals(typeList[2]))
|
||
return 2;
|
||
else if (typeList[0].Equals(typeList[2]) && !typeList[0].Equals(typeList[1]))
|
||
return 3;
|
||
else if (typeList[1].Equals(typeList[2]) && !typeList[0].Equals(typeList[2]))
|
||
return 4;
|
||
else
|
||
return 0;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 点1在XY平面(忽略Z值)绕中心点逆时针旋转到点2的弧度[0,2Π]
|
||
/// </summary>
|
||
/// <param name="firstPoint"></param>
|
||
/// <param name="centerPoint"></param>
|
||
/// <param name="lastPoint"></param>
|
||
/// <returns></returns>
|
||
public static double AngleOfThreePoint(XYZ firstPoint, XYZ centerPoint, XYZ lastPoint)
|
||
{
|
||
XYZ vector1 = firstPoint - centerPoint;
|
||
XYZ vector2 = lastPoint - centerPoint;
|
||
double angle = Math.Atan2(vector2.Y, vector2.X) - Math.Atan2(vector1.Y, vector1.X);
|
||
if (angle < 0)
|
||
{
|
||
return angle += Math.PI * 2;
|
||
}
|
||
else if (angle == 0)
|
||
{
|
||
return angle = Math.PI * 2;
|
||
}
|
||
else
|
||
return angle;
|
||
}
|
||
|
||
public static double PointToLinePedal(XYZ lineFirstPoint, XYZ lineSecondPoint, XYZ point)
|
||
{
|
||
double A = lineSecondPoint.Y - lineFirstPoint.Y;
|
||
double B= lineSecondPoint.X - lineFirstPoint.X;
|
||
double C = lineSecondPoint.X * lineFirstPoint.Y - lineFirstPoint.X*lineSecondPoint.Y;
|
||
return (A * point.X + B * point.Y + C) / Math.Sqrt(A * A + B * B);
|
||
}
|
||
|
||
|
||
|
||
public static double PointToLineDistance(XYZ lineFirstPoint, XYZ lineSecondPoint, XYZ point)
|
||
{
|
||
double A = lineSecondPoint.Y - lineFirstPoint.Y;
|
||
double B = lineSecondPoint.X - lineFirstPoint.X;
|
||
double C = lineSecondPoint.X * lineFirstPoint.Y - lineFirstPoint.X * lineSecondPoint.Y;
|
||
return (A * point.X + B * point.Y + C) / Math.Sqrt(A * A + B * B);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建材质
|
||
/// </summary>
|
||
/// <param name="doc">Autodesk.Revit.DB.Document</param>
|
||
/// <param name="name">材质名称</param>
|
||
/// <returns></returns>
|
||
public static Material CreateMaterial(Document doc, string name)
|
||
{
|
||
Material material = null;
|
||
ElementId materialId = Material.Create(doc, name);
|
||
material = doc.GetElement(materialId) as Material;
|
||
StructuralAsset strucAsset = new StructuralAsset("uBIM", StructuralAssetClass.Undefined);
|
||
strucAsset.Behavior = StructuralBehavior.Isotropic;
|
||
PropertySetElement propertySet = PropertySetElement.Create(doc, strucAsset);
|
||
propertySet.get_Parameter(BuiltInParameter.PROPERTY_SET_NAME).Set(name);
|
||
propertySet.get_Parameter(BuiltInParameter.PHY_MATERIAL_PARAM_CLASS).Set((int)StructuralMaterialType.Undefined);
|
||
propertySet.get_Parameter(BuiltInParameter.PHY_MATERIAL_PARAM_UNIT_WEIGHT).Set(232);
|
||
material.SetMaterialAspectByPropertySet(Autodesk.Revit.DB.MaterialAspect.Structural, propertySet.Id);
|
||
return material;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建材质
|
||
/// </summary>
|
||
/// <param name="doc">Autodesk.Revit.DB.Document</param>
|
||
/// <param name="materialNameList">材质名称列表</param>
|
||
/// <returns></returns>
|
||
public static IList<Element> CreateMaterialElements(Document doc, List<string> materialNameList)
|
||
{
|
||
Transaction transaction = new Transaction(doc);
|
||
IList<Element> mtset = new FilteredElementCollector(doc)
|
||
.WherePasses(new ElementClassFilter(typeof(Material))).ToElements();
|
||
transaction.Start("Create Material");
|
||
foreach (string type in materialNameList)
|
||
{
|
||
if (mtset.Select(x => x.Name).ToList().Contains(type))
|
||
continue;
|
||
else
|
||
{
|
||
Material material = CreateMaterial(doc, type);
|
||
Random randomNumFirst = new Random((int)DateTime.Now.Ticks);
|
||
System.Threading.Thread.Sleep(randomNumFirst.Next(50));
|
||
Random randomNumSencond = new Random((int)DateTime.Now.Ticks);
|
||
int intRed = randomNumFirst.Next(256);
|
||
int intGreen = randomNumSencond.Next(256);
|
||
int intBlue = (intRed + intGreen > 400) ? 0 : 400 - intRed - intGreen;
|
||
intBlue = (intBlue > 255) ? 255 : intBlue;
|
||
material.Color = new Color((byte)intRed, (byte)intGreen, (byte)intBlue);
|
||
material.MaterialClass = "地质材质";
|
||
mtset.Add(material);
|
||
}
|
||
}
|
||
transaction.Commit();
|
||
return mtset;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Transaction设置
|
||
/// </summary>
|
||
/// <param name="trans">Transaction</param>
|
||
public static void SetTransaction(Transaction trans)
|
||
{
|
||
FailureHandlingOptions failureHandlingOptions = trans.GetFailureHandlingOptions();
|
||
FailureHandler failureHandler = new FailureHandler();
|
||
failureHandlingOptions.SetFailuresPreprocessor(failureHandler);
|
||
failureHandlingOptions.SetClearAfterRollback(true);
|
||
trans.SetFailureHandlingOptions(failureHandlingOptions);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 求某点处的textnote,在textnote_list范围内
|
||
/// </summary>
|
||
/// <param name="p">寻找点</param>
|
||
/// <param name="textnoteList">TextNote列表</param>
|
||
/// <param name="tolerance">误差范围,单位mm</param>
|
||
/// <returns>textnote</returns>
|
||
public static TextNote Textnote_At_Point(XYZ p, List<TextNote> textnoteList, double tolerance)
|
||
{
|
||
TextNote tn = null;
|
||
XYZ newXyz = new XYZ(p.X, p.Y, textnoteList[0].Coord.Z);
|
||
foreach (TextNote tntmp in textnoteList)
|
||
{
|
||
if (Math.Round(tntmp.Coord.DistanceTo(newXyz), 5) < (tolerance / 304.8))
|
||
{
|
||
tn = tntmp;
|
||
}
|
||
}
|
||
return tn;
|
||
}
|
||
public static void Swap<T>(ref T x, ref T y)
|
||
{
|
||
T temp = x;
|
||
x = y;
|
||
y = temp;
|
||
}
|
||
}
|
||
}
|