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 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(); 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(); 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 _elements; private int _currentIndex; // 接受 IEnumerable,这是一个协变接口 public ElementSet(IEnumerable elements) { // 如果传入的 elements 不为 null,则转换为 List;否则创建一个空 List _elements = elements?.ToList() ?? new List(); _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; } } }