340 lines
14 KiB
C#
340 lines
14 KiB
C#
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;
|
||
}
|
||
}
|
||
}
|