uBIMEarthTools/uBIMEarthTools/Utils/Common.cs
2018-10-22 19:40:36 +08:00

233 lines
9.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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