2025-02-10 20:53:40 +08:00
|
|
|
|
using Autodesk.Revit.DB;
|
|
|
|
|
|
using Autodesk.Revit.UI;
|
|
|
|
|
|
|
2025-04-24 20:56:44 +08:00
|
|
|
|
namespace ShrlAlgoToolkit.RevitAddins.RvIndependent.MetroGauges
|
2025-02-10 20:53:40 +08:00
|
|
|
|
{
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|