Files

199 lines
8.9 KiB
C#
Raw Permalink Normal View History

2026-02-28 21:01:57 +08:00
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;
}
}
}