Files
wg_cpso/CPSO/Forms/92_Knowledge/FrmStepsManager.cs
2026-03-25 18:20:24 +08:00

203 lines
6.4 KiB
C#

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<int, int> _nodeToVertexMapping = new Dictionary<int, int>();
private readonly Dictionary<int, int> _vertexToNodeMapping = new Dictionary<int, int>();
private readonly Dictionary<int, FeFace> _cellToFaceMapping = new Dictionary<int, FeFace>();
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<ProcessingJob> jobs = new List<ProcessingJob>();
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<FeFace> faces = new List<FeFace>();
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<int>();
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;
}
}
}