203 lines
6.4 KiB
C#
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;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|