using CaeGlobals; using CaeKnowledge; using CaeKnowledge.Data; using CaeKnowledge.View; using CaeMesh; using Plankton; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using CaeModel; // ReSharper disable SuggestVarOrType_SimpleTypes // ReSharper disable SuggestVarOrType_BuiltInTypes // ReSharper disable SuggestVarOrType_Elsewhere // ReSharper disable InvertIf namespace CPSO.Forms._92_Knowledge { public partial class FrmStepsManager : UserControls.FrmProperties { private readonly Controller Self; public FrmStepsManager(Controller self) { InitializeComponent(); Self = self; } public void PrepareForm() { if (propertyGrid.SelectedObject is ViewSteps steps) { steps.PopulateDropDownList(); } } private void FrmAddLoad_Load(object sender, EventArgs e) { var view = new ViewSteps(Self); view.ToolPositionList.Clear(); if (Self?.ToolPositions != null) { view.ToolPositionList.AddRange(Self.ToolPositions); } propertyGrid.SelectedObject = view; } private readonly Dictionary _nodeToVertexMapping = new Dictionary(); private readonly Dictionary _vertexToNodeMapping = new Dictionary(); private readonly Dictionary _cellToFaceMapping = new Dictionary(); protected override async void OnApply(bool onOkAddNew) { try { if (!(propertyGrid.SelectedObject is ViewSteps steps)) return; _nodeToVertexMapping.Clear(); _vertexToNodeMapping.Clear(); _cellToFaceMapping.Clear(); Step step = Self.GetStep(steps.Step); if (step == null) throw new CaeException($"无法找到对应的计算步:{steps.Step}"); if (!Self.Model.Mesh.Surfaces.TryGetValue(steps.Surface, out var surface)) throw new CaeException($"无法找到对应的曲面集:{steps.Surface}"); Self.Form.SetStateWorking(@"构建切削力分析模型..."); List jobs = new List(); await Task.Run(() => { var mesh = LoadMesh(surface); Self.ToolPositions.ForEach(tp => { int vertId = GetClosedVertex(mesh, tp.Base); if (vertId >= 0) { // 1.最接近节点 int nodeId = _vertexToNodeMapping[vertId]; FeNode node = Self.Model.Mesh.Nodes[nodeId]; // 2.最近节点周围的面单元 List faces = new List(); foreach (var f in mesh.Vertices.GetVertexFaces(vertId)) { if(_cellToFaceMapping.TryGetValue(f, out var face)) faces.Add(face); } jobs.Add(new ProcessingJob(step.Name, tp.Base, node, faces.ToArray()) { NewStepName = steps.NewStep }); } }); Self.ProcessingJobs.Clear(); jobs.ForEach(job => { Self.ProcessingJobs.Add(new ViewProcessingJob(job)); }); }); Self.Form.SetStateReady(@"构建切削力分析模型..."); } catch (Exception ex) { ExceptionTools.Show(ex); } } // 计算最接近的点 private static int GetClosedVertex(PlanktonMesh mesh, ToolPosition toolPosition) { int closedVertexIndex = -1; double x1 = toolPosition.X; double y1 = toolPosition.Y; double z1 = toolPosition.Z; double minimumDistance = double.MaxValue; int id = 0; foreach (var vertex in mesh.Vertices) { double x2 = vertex.X; double y2 = vertex.Y; double z2 = vertex.Z; double dst = MeshTools.Distance(x1, y1, z1, x2, y2, z2); // 如果距离小于当前最小距离,则更新最近点索引 if (dst < minimumDistance) { minimumDistance = dst; closedVertexIndex = id; } id++; } return closedVertexIndex; } private PlanktonMesh LoadMesh(FeSurface surface) { // 计算面列表 var faceList = (from faceId in surface.FaceIds let element = Self.Model.Mesh.Elements[faceId / 10] let faceName = (FeFaceName)(faceId % 10 + 1) select new FeFace(element, faceName)).ToList(); // 节点列表 var hashSet = new HashSet(); faceList.ForEach(face => { var ids = face.NodeIds; hashSet.Add(ids[0]); hashSet.Add(ids[1]); hashSet.Add(ids[2]); }); var mesh = new PlanktonMesh(); foreach (var nodeId in hashSet.OrderBy(x => x)) { double x = Self.Model.Mesh.Nodes[nodeId].X; double y = Self.Model.Mesh.Nodes[nodeId].Y; double z = Self.Model.Mesh.Nodes[nodeId].Z; int vertId = mesh.Vertices.Add(x, y, z); _nodeToVertexMapping.Add(nodeId, vertId); _vertexToNodeMapping.Add(vertId, nodeId); } faceList.ForEach(face => { var ids = face.NodeIds; int i = _nodeToVertexMapping[ids[0]]; int j = _nodeToVertexMapping[ids[1]]; int k = _nodeToVertexMapping[ids[2]]; int cellId = mesh.Faces.AddFace(i, j, k); _cellToFaceMapping.Add(cellId, face); }); return mesh; } } }