Files
ShrlAlgoToolkit/ShrlAlgoToolkit.RevitAddins/RvIndependent/MetroGauges/ProfileHelper.cs

340 lines
14 KiB
C#
Raw Normal View History

using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
2025-04-24 20:56:44 +08:00
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;
}
}
}