@
feat(query): перечисление граней + выбор грани по индексу QueryService.ListFacesAsync: обход EntityCollection(o3d_face), для каждой грани — индекс, тип поверхности (plane/cylinder/cone/sphere/torus/nurbs через ksFaceDefinition.Is*) и площадь (GetArea, мм²). Запись FaceInfo. PartModeler.OpenSketchOnFaceIndexAsync: эскиз на грани по индексу из list_faces — надёжнее выбора по точке (агенту не нужно угадывать координаты). Новые инструменты: list_faces, sketch_create_on_face_index. Тест List_faces_and_sketch_by_index: цилиндр → 3 грани (2 plane + 1 cylinder), площади торца ≈314 мм² и бока ≈1257 мм²; эскиз на торце по индексу → бобышка. Презентация: 28 инструментов, 18 тестов. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> @
This commit is contained in:
@@ -61,6 +61,54 @@ public sealed class QueryService
|
||||
}
|
||||
}, ct);
|
||||
|
||||
// ST_MIX_MM (0x1) — площади граней в мм².
|
||||
private const uint MixMm = 0x1;
|
||||
|
||||
/// <summary>Перечислить грани активной детали: индекс, тип поверхности и площадь (мм²).</summary>
|
||||
public Task<IReadOnlyList<FaceInfo>> ListFacesAsync(CancellationToken ct = default)
|
||||
=> _dispatcher.InvokeAsync<IReadOnlyList<FaceInfo>>(() =>
|
||||
{
|
||||
var doc3d = _session.Kompas.ActiveDocument3D() as ksDocument3D
|
||||
?? throw new InvalidOperationException("Нет активного 3D-документа.");
|
||||
var part = doc3d.GetPart((short)Part_Type.pTop_Part) as ksPart
|
||||
?? throw new InvalidOperationException("Не удалось получить вершинный компонент (ksPart).");
|
||||
try
|
||||
{
|
||||
var faces = part.EntityCollection((short)Obj3dType.o3d_face) as ksEntityCollection
|
||||
?? throw new InvalidOperationException("Не удалось получить коллекцию граней.");
|
||||
|
||||
var count = faces.GetCount();
|
||||
var list = new List<FaceInfo>(count);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (faces.GetByIndex(i) is not ksEntity entity) continue;
|
||||
if (entity.GetDefinition() is not ksFaceDefinition def) continue;
|
||||
list.Add(new FaceInfo
|
||||
{
|
||||
Index = i,
|
||||
Type = FaceType(def),
|
||||
Area = def.GetArea(MixMm),
|
||||
});
|
||||
}
|
||||
return list;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (Marshal.IsComObject(part)) Marshal.ReleaseComObject(part);
|
||||
}
|
||||
}, ct);
|
||||
|
||||
private static string FaceType(ksFaceDefinition def)
|
||||
{
|
||||
if (def.IsPlanar()) return "plane";
|
||||
if (def.IsCylinder()) return "cylinder";
|
||||
if (def.IsCone()) return "cone";
|
||||
if (def.IsSphere()) return "sphere";
|
||||
if (def.IsTorus()) return "torus";
|
||||
if (def.IsNurbsSurface()) return "nurbs";
|
||||
return "other";
|
||||
}
|
||||
|
||||
/// <summary>Габаритный параллелепипед активной детали (по телам), мм.</summary>
|
||||
public Task<BoundingBox> GetBoundingBoxAsync(CancellationToken ct = default)
|
||||
=> _dispatcher.InvokeAsync(() =>
|
||||
|
||||
Reference in New Issue
Block a user