Files
Shrlalgo.RvKits/ShrlAlgoToolkit.RevitAddins/RvIndependent/MetroGauges/ProfileHelper.cs
2025-04-24 20:56:44 +08:00

340 lines
14 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 Autodesk.Revit.DB;
using Autodesk.Revit.UI;
namespace ShrlAlgoToolkit.RevitAddins.RvIndependent.MetroGauges
{
public class ProfileHelper
{
/// <summary>
/// 获取除受电弓以外的坐标
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public List<XYZ> GetXmlOthersPt(string path)
{
Loader load = new Loader();
XmlData ptData = load.XMLLoad(path);
List<XYZ> pts = new List<XYZ>();
for (int i = 0; i < ptData.parts.Count; i++)
{
//获取节点的类
Type tp = ptData.parts[i].GetType();
//判断节点所属的类
if (tp == typeof(Cd))
{
Cd cd = (Cd)ptData.parts[i];
for (int j = 0; j < cd.pts.Count; j++)
{
XYZ pt = new XYZ(cd.pts[j].X / 304.8, cd.pts[j].Y / 304.8, 0.0);
//ReferencePoint refpt = doc.FamilyCreate.NewReferencePoint(pt);
pts.Add(pt);
}
}
else if (tp == typeof(Cdkt))
{
Cdkt cdkt = (Cdkt)ptData.parts[i];
for (int j = 0; j < cdkt.pts.Count; j++)
{
XYZ pt = new XYZ(cdkt.pts[j].X / 304.8, cdkt.pts[j].Y / 304.8, 0.0);
//ReferencePoint refpt = doc.FamilyCreate.NewReferencePoint(pt);
pts.Add(pt);
}
}
else if (tp == typeof(Cj))
{
Cj cj = (Cj)ptData.parts[i];
for (int j = 0; j < cj.pts.Count; j++)
{
XYZ pt = new XYZ(cj.pts[j].X / 304.8, cj.pts[j].Y / 304.8, 0.0);
//ReferencePoint refpt = doc.FamilyCreate.NewReferencePoint(pt);
pts.Add(pt);
}
}
else if (tp == typeof(Xhd))
{
Xhd xhd = (Xhd)ptData.parts[i];
for (int j = 0; j < xhd.pts.Count; j++)
{
XYZ pt = new XYZ(xhd.pts[j].X / 304.8, xhd.pts[j].Y / 304.8, 0.0);
//ReferencePoint refpt = doc.FamilyCreate.NewReferencePoint(pt);
pts.Add(pt);
}
}
else if (tp == typeof(Cq))
{
Cq cq = (Cq)ptData.parts[i];
for (int j = 0; j < cq.pts.Count; j++)
{
XYZ pt = new XYZ(cq.pts[j].X / 304.8, cq.pts[j].Y / 304.8, 0.0);
//ReferencePoint refpt = doc.FamilyCreate.NewReferencePoint(pt);
pts.Add(pt);
}
}
else if (tp == typeof(Zxj))
{
Zxj zxj = (Zxj)ptData.parts[i];
for (int j = 0; j < zxj.pts.Count; j++)
{
XYZ pt = new XYZ(zxj.pts[j].X / 304.8, zxj.pts[j].Y / 304.8, 0.0);
//ReferencePoint refpt = doc.FamilyCreate.NewReferencePoint(pt);
pts.Add(pt);
}
}
else if (tp == typeof(Tm))
{
Tm tm = (Tm)ptData.parts[i];
for (int j = 0; j < tm.pts.Count; j++)
{
XYZ pt = new XYZ(tm.pts[j].X / 304.8, tm.pts[j].Y / 304.8, 0.0);
//ReferencePoint refpt = doc.FamilyCreate.NewReferencePoint(pt);
pts.Add(pt);
}
}
else if (tp == typeof(Ly))
{
Ly ly = (Ly)ptData.parts[i];
for (int j = 0; j < ly.pts.Count; j++)
{
XYZ pt = new XYZ(ly.pts[j].X / 304.8, ly.pts[j].Y / 304.8, 0.0);
//ReferencePoint refpt = doc.FamilyCreate.NewReferencePoint(pt);
pts.Add(pt);
}
}
else if (tp == typeof(Gj1))
{
Gj1 gj1 = (Gj1)ptData.parts[i];
for (int j = 0; j < gj1.pts.Count; j++)
{
XYZ pt = new XYZ(gj1.pts[j].X / 304.8, gj1.pts[j].Y / 304.8, 0.0);
//ReferencePoint refpt = doc.FamilyCreate.NewReferencePoint(pt);
pts.Add(pt);
}
}
else if (tp == typeof(Hx))
{
Hx hx = (Hx)ptData.parts[i];
for (int j = 0; j < hx.pts.Count; j++)
{
XYZ pt = new XYZ(hx.pts[j].X / 304.8, hx.pts[j].Y / 304.8, 0.0);
//ReferencePoint refpt = doc.FamilyCreate.NewReferencePoint(pt);
pts.Add(pt);
}
}
else if (tp == typeof(Gj2))
{
Gj2 gj2 = (Gj2)ptData.parts[i];
for (int j = 0; j < gj2.pts.Count; j++)
{
XYZ pt = new XYZ(gj2.pts[j].X / 304.8, gj2.pts[j].Y / 304.8, 0.0);
//ReferencePoint refpt = doc.FamilyCreate.NewReferencePoint(pt);
pts.Add(pt);
}
}
}
return pts;
}
/// <summary>
/// 获取受电弓点坐标
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public List<XYZ> GetXmlsdgPt(string path)
{
Loader load = new Loader();
XmlData ptData = load.XMLLoad(path);
List<XYZ> pts = new List<XYZ>();
for (int i = 0; i < ptData.parts.Count; i++)
{
//获取节点的类
Type tp = ptData.parts[i].GetType();
//判断节点所属的类
if (tp == typeof(Sdg))
{
//强制将父类转换成子类
Sdg sdg = (Sdg)ptData.parts[i];
//循环该类节点下的所有Point节点添加到DataTable中
for (int j = 0; j < sdg.pts.Count; j++)
{
XYZ pt = new XYZ(sdg.pts[j].X / 304.8, sdg.pts[j].Y / 304.8, 0.0);
pts.Add(pt);
}
}
}
return pts;
}
/// <summary>
/// 从族文件提取几何线生成断面
/// </summary>
/// <param name="uiapp"></param>
/// <param name="curve"></param>
/// <param name="reg"></param>
/// <param name="paramenter"></param>
/// <returns></returns>
public ReferenceArray ProfileFromRfa(UIApplication uiapp, CurveByPoints curve, Region reg, int paramenter)
{
Document revitDoc = uiapp.Application.OpenDocumentFile(reg.FilePathStart);
Document doc = uiapp.ActiveUIDocument.Document;
FilteredElementCollector modelCurveCollector = new FilteredElementCollector(revitDoc);
List<ModelCurve> modelCurveList = modelCurveCollector
.OfCategory(BuiltInCategory.OST_Lines)
.OfClass(typeof(CurveElement))
.ToList()
.ConvertAll(x => x as ModelCurve);
ReferenceArray profile = new ReferenceArray();
XYZ tan;
if (paramenter == 0)
{
tan = (curve.GeometryCurve as HermiteSpline)?.Tangents[0];
}
else
{
tan = (curve.GeometryCurve as HermiteSpline)?.Tangents.Last();
}
XYZ horizonNor = new XYZ(tan.X, tan.Y, 0);
XYZ orign = curve.GeometryCurve.GetEndPoint(paramenter);
//curve在xy平面上的投影某点的工作平面
//Plane horiCurPl = Plane.CreateByNormalAndOrigin(horizonNor, orign);
//XYZ xVect = horiCurPl.XVec;
XYZ xAxis = horizonNor.CrossProduct(new XYZ(0, 0, 1)).Normalize();
//在curve上的工作平面
Plane pl = Plane.CreateByNormalAndOrigin(tan, orign);
SketchPlane skp = SketchPlane.Create(doc, pl);
//XYZ xVect = pl.XVec;//z=0
//求出curve上某点工作平面的y向量
XYZ yAxis = xAxis.CrossProduct(pl.Normal).Normalize(); //z>0
if (yAxis.Z < 0)
{
//xVect = horiCurPl.XVec.Negate();
xAxis = xAxis.Negate();
yAxis = yAxis.Negate();
}
foreach (ModelCurve c in modelCurveList)
{
if (c.GetType() == typeof(ModelLine))
{
ModelLine ml = (ModelLine)c;
var startpt = ml.GeometryCurve.GetEndPoint(0);
var endpt = ml.GeometryCurve.GetEndPoint(1);
XYZ stapt = startpt.X * xAxis + orign + startpt.Y * yAxis;
XYZ enpt = endpt.X * xAxis + orign + endpt.Y * yAxis;
Line l = Line.CreateBound(stapt, enpt);
ModelCurve modelCurve = doc.FamilyCreate.NewModelCurve(l, skp);
profile.Append(modelCurve.GeometryCurve.Reference);
}
else if (c.GetType() == typeof(ModelArc))
{
ModelArc marc = (ModelArc)c;
Arc ar = (Arc)marc.GeometryCurve;
//XYZ startpt = marc.GeometryCurve.GetEndPoint(0);
//XYZ centpt = marc.GeometryCurve.Evaluate(0.5, true);
//XYZ endpt = marc.GeometryCurve.GetEndPoint(1);
Arc arc;
if (marc.GeometryCurve.IsBound)
{
XYZ startpt = ar.GetEndPoint(0);
XYZ centpt = ar.Evaluate(0.5, true);
XYZ endpt = ar.GetEndPoint(1);
XYZ stapt = startpt.X * xAxis + orign + startpt.Y * yAxis;
XYZ cept = centpt.X * xAxis + orign + centpt.Y * yAxis;
XYZ enpt = endpt.X * xAxis + orign + endpt.Y * yAxis;
arc = Arc.Create(stapt, enpt, cept);
}
else
{
XYZ center = ar.Center.X * xAxis + orign + ar.Center.Y * yAxis;
arc = Arc.Create(center, ar.Radius, 0, 2 * Math.PI, xAxis, yAxis);
//arc = Arc.Create(pl, ar.Radius, 0, 2 * Math.PI);
}
ModelCurve newModelCurve = doc.FamilyCreate.NewModelCurve(arc, skp);
profile.Append(newModelCurve.GeometryCurve.Reference);
}
}
//foreach (ModelCurve modelCurve in modelCurveList)
//{
// Reference referenceFunc = modelCurve.GeometryCurve.Reference;
//}
revitDoc.Close(false);
return profile;
}
/// <summary>
/// 限界坐标点生成横断面轮廓
/// </summary>
/// <param name="doc"></param>
/// <param name="curve"></param>
/// <param name="reg"></param>
/// <param name="GaugesPt"></param>
/// <returns></returns>
public ReferenceArray ProfileFromXml(
Document doc,
CurveByPoints curve,
Region reg,
List<XYZ> GaugesPt,
int paramenter
)
{
ReferenceArray profile = new ReferenceArray();
XYZ keyPtNor;
if (paramenter == 0)
{
keyPtNor = (curve.GeometryCurve as HermiteSpline)?.Tangents[0];
}
else
{
keyPtNor = (curve.GeometryCurve as HermiteSpline)?.Tangents.Last();
}
XYZ horizonNor = new XYZ(keyPtNor.X, keyPtNor.Y, 0);
XYZ orign = curve.GeometryCurve.GetEndPoint(paramenter);
Plane horiCurPl = Plane.CreateByNormalAndOrigin(horizonNor, orign);
XYZ xVect = horiCurPl.XVec;
Plane pl = Plane.CreateByNormalAndOrigin(keyPtNor, curve.GeometryCurve.GetEndPoint(paramenter));
SketchPlane skp = SketchPlane.Create(doc, pl);
XYZ ori = pl.Origin;
//XYZ xVect = pl.XVec;//z=0
XYZ yVect = xVect.CrossProduct(pl.Normal); //z>0
//pl.Normal.Normalize();//单位化
//XYZ.IsWithinLengthLimits;
if (yVect.Z < 0)
{
xVect = horiCurPl.XVec.Negate();
yVect = yVect.Negate();
}
//if (xVect.X<0)
//{
//}
List<XYZ> profPt = new List<XYZ>();
for (int i = 0; i < GaugesPt.Count; i++)
{
XYZ pt = GaugesPt[i].X * xVect + ori + GaugesPt[i].Y * yVect;
profPt.Add(pt);
}
for (int i = 0; i < profPt.Count - 1; i++)
{
Line l = Line.CreateBound(profPt[i], profPt[i + 1]);
ModelCurve ml = doc.FamilyCreate.NewModelCurve(l, skp);
profile.Append(ml.GeometryCurve.Reference);
}
return profile;
}
}
}