199 lines
8.9 KiB
C#
199 lines
8.9 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Drawing;
|
|||
|
|
using System.IO;
|
|||
|
|
using System.Linq;
|
|||
|
|
using System.Net;
|
|||
|
|
using System.Reflection;
|
|||
|
|
using System.Text;
|
|||
|
|
using System.Windows;
|
|||
|
|
|
|||
|
|
using Bentley.DgnPlatform;
|
|||
|
|
using Bentley.DgnPlatformNET;
|
|||
|
|
using Bentley.DgnPlatformNET.Elements;
|
|||
|
|
using Bentley.GeometryNET;
|
|||
|
|
using Bentley.MstnPlatformNET;
|
|||
|
|
|
|||
|
|
using Microsoft.Win32;
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
namespace RingPlacementAddin
|
|||
|
|
{
|
|||
|
|
public class Commands
|
|||
|
|
{
|
|||
|
|
public static void PlaceRings(string unparsed)
|
|||
|
|
{
|
|||
|
|
OpenFileDialog dialog = new OpenFileDialog()
|
|||
|
|
{
|
|||
|
|
Filter = "管环定位配置 (*.json)|*.json",
|
|||
|
|
Title = "打开文件",
|
|||
|
|
};
|
|||
|
|
if (dialog.ShowDialog() == true)
|
|||
|
|
{
|
|||
|
|
var jsonFilePath = dialog.FileName;
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
RingData data = RingInfoReader.Read(jsonFilePath);
|
|||
|
|
var dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
|||
|
|
var cellPath = Path.Combine(dir, "Cell", "Ring.cel");
|
|||
|
|
if (!File.Exists(cellPath))
|
|||
|
|
{
|
|||
|
|
MessageBox.Show($"单元库文件不存在:{cellPath}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
//DTransform3d trans = DTransform3d.Identity;
|
|||
|
|
//trans.Translation = new DVector3d(100000, 200000, 300000);
|
|||
|
|
//var ts = DTransform3d.Rotation(DVector3d.FromXYZ(1000, 0, 0), Angle.PI * 0.25);
|
|||
|
|
//var ts1 = DTransform3d.Multiply(ts, trans);
|
|||
|
|
//var matrix3d = ts1.Matrix;
|
|||
|
|
//var de = matrix3d.Determinant();
|
|||
|
|
//var rigid = matrix3d.IsRigid();//刚性
|
|||
|
|
//var diagonal = matrix3d.IsDiagonal();//对角线
|
|||
|
|
//var orthogonal = matrix3d.IsOrthogonal();//正交
|
|||
|
|
//var uniform = matrix3d.IsUniformScale(out var max);
|
|||
|
|
//var rigidWithScale = matrix3d.IsRigidWithScale(out var maxtric, out var s);
|
|||
|
|
double ringWidth = 1.2; //管片宽度,单位米
|
|||
|
|
double uorMeter = Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMeter;
|
|||
|
|
Dictionary<string, object> parameters = new()
|
|||
|
|
{
|
|||
|
|
{ "管片宽度", ringWidth}, //转换为米
|
|||
|
|
};
|
|||
|
|
//CellHelpers.ImportParametricCellElement(cellPath, "管环", ts1);
|
|||
|
|
//return;
|
|||
|
|
|
|||
|
|
var dgnModel = Session.Instance.GetActiveDgnModel();//获取当前激活的model
|
|||
|
|
var points = data.Rings.Select(r => r.Transform3d.Translation).ToArray();
|
|||
|
|
//foreach (var p in points)
|
|||
|
|
//{
|
|||
|
|
// DSegment3d segment = new(p, p);
|
|||
|
|
// //创建直线元素
|
|||
|
|
// var line = new LineElement(dgnModel, null, segment);
|
|||
|
|
// line.AddToModel();
|
|||
|
|
//}
|
|||
|
|
foreach (var ring in data.Rings)
|
|||
|
|
{
|
|||
|
|
CellHelper.ImportParametricCellElement(cellPath, "管环", ring.Transform3d, parameters);
|
|||
|
|
}
|
|||
|
|
var mSBsplineCurve = MSBsplineCurve.CreateFromPoints(points);
|
|||
|
|
CurvePrimitive curvePrimitive = CurvePrimitive.CreateBsplineCurve(mSBsplineCurve);// 使用CurvePrimitive下的静态方法CreateBsplineCurve
|
|||
|
|
|
|||
|
|
Element targetCurve = DraftingElementSchema.ToElement(dgnModel, curvePrimitive, null); //将CurvePrimitive转为Element, 持久化到model中
|
|||
|
|
targetCurve.AddToModel();
|
|||
|
|
|
|||
|
|
//return;
|
|||
|
|
var uor = Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMeter;
|
|||
|
|
CurveVector curveVector = CurvePathQuery.ElementToCurveVector(targetCurve);
|
|||
|
|
var locs = points.Select(curveVector.ClosestPointBoundedXY);
|
|||
|
|
var ordered = locs.OrderBy(curveVector.CurveLocationDetailIndex).ThenBy(loc => loc.Fraction).ToList();
|
|||
|
|
StringBuilder sb = new StringBuilder();
|
|||
|
|
//var pcs = new List<ParametricCellElement>();
|
|||
|
|
foreach (var detail in ordered)
|
|||
|
|
{
|
|||
|
|
sb.AppendLine($"Fraction:{detail.Fraction},ComponentFraction:{detail.ComponentFraction}");
|
|||
|
|
}
|
|||
|
|
//MessageBox.Show(sb.ToString());
|
|||
|
|
|
|||
|
|
curvePrimitive.Length(out var length);
|
|||
|
|
var additionPoints = new List<DPoint3d>();
|
|||
|
|
for (int i = 0; i < ordered.Count - 1; i++)
|
|||
|
|
{
|
|||
|
|
curvePrimitive.SignedDistanceBetweenFractions(ordered[i].Fraction, ordered[i + 1].Fraction, out double distance);
|
|||
|
|
var count = Math.Floor(distance / (uor * ringWidth));
|
|||
|
|
|
|||
|
|
if (count >= 2)
|
|||
|
|
{
|
|||
|
|
for (int j = 0; j < count - 1; j++)
|
|||
|
|
{
|
|||
|
|
//var fraction = ordered[i].Fraction + (j + 1) * (uor * ringWidth) / length;
|
|||
|
|
//curvePrimitive.SignedDistanceBetweenFractions(ordered[i].Fraction, fraction, out double dis);
|
|||
|
|
var detail = curvePrimitive.PointAtSignedDistanceFromFraction(
|
|||
|
|
ordered[i].Fraction,
|
|||
|
|
(j + 1) * (uor * ringWidth),
|
|||
|
|
false);
|
|||
|
|
|
|||
|
|
//curvePrimitive.FractionToPoint(fraction, out var point);
|
|||
|
|
//DTransform3d transform = DTransform3d.Translation(point);
|
|||
|
|
//curvePrimitive.FractionToFrenetFrame(fraction, out var transform);
|
|||
|
|
curvePrimitive.FractionToPoint(detail.Fraction, out var point, out var tangent);
|
|||
|
|
var identity = DTransform3d.Identity;
|
|||
|
|
identity.Translation = point;
|
|||
|
|
//additionPoints.Add(point);
|
|||
|
|
|
|||
|
|
var xAxis = -tangent.CrossProduct(DVector3d.UnitZ);
|
|||
|
|
var zAxis = xAxis.CrossProduct(-tangent);
|
|||
|
|
identity.SetColumns(xAxis, -tangent, zAxis);
|
|||
|
|
ParametricCellElement pc = CellHelper.ImportParametricCellElement(cellPath, "管环", identity, parameters);
|
|||
|
|
//pcs.Add(pc);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//foreach (var item in pcs)
|
|||
|
|
//{
|
|||
|
|
// //sb.AppendLine(item.ElementId.ToString());
|
|||
|
|
// SelectionSetManager.AddElement(item, dgnModel);
|
|||
|
|
//}
|
|||
|
|
//foreach (var point in additionPoints)
|
|||
|
|
//{
|
|||
|
|
// var line = LineString.CreateLine(new DSegment3d(point, point));
|
|||
|
|
// Element lineElement = DraftingElementSchema.ToElement(dgnModel, line, null); //将CurvePrimitive转为Element, 持久化到model中
|
|||
|
|
// lineElement.AddToModel();
|
|||
|
|
//}
|
|||
|
|
//SelectionSetManager.AddElementSet(new ElementSet(pcs));
|
|||
|
|
|
|||
|
|
//CellHelpers.AttachCellLib(cellPath);
|
|||
|
|
|
|||
|
|
//foreach (var ring in data.Rings)
|
|||
|
|
//{
|
|||
|
|
// CellHelpers.CreateParametricCell("管环", null, ring.Transform3d);
|
|||
|
|
//}
|
|||
|
|
//CellHelpers.DetachCellLibs();
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
MessageBox.Show(ex.Message);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
public class ElementSet : IElementSet
|
|||
|
|
{
|
|||
|
|
private readonly List<Element> _elements;
|
|||
|
|
private int _currentIndex;
|
|||
|
|
|
|||
|
|
// 接受 IEnumerable<Element>,这是一个协变接口
|
|||
|
|
public ElementSet(IEnumerable<Element> elements)
|
|||
|
|
{
|
|||
|
|
// 如果传入的 elements 不为 null,则转换为 List;否则创建一个空 List
|
|||
|
|
_elements = elements?.ToList() ?? new List<Element>();
|
|||
|
|
_currentIndex = -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public uint GetCount()
|
|||
|
|
{
|
|||
|
|
return (uint)_elements.Count;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public Element GetFirst()
|
|||
|
|
{
|
|||
|
|
if (_elements.Count == 0)
|
|||
|
|
{
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
_currentIndex = 0;
|
|||
|
|
return _elements[_currentIndex];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public Element GetNext()
|
|||
|
|
{
|
|||
|
|
if (_currentIndex >= 0 && _currentIndex < _elements.Count - 1)
|
|||
|
|
{
|
|||
|
|
_currentIndex++;
|
|||
|
|
return _elements[_currentIndex];
|
|||
|
|
}
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|