feat: коническое отверстие (hole_conic) — ksHTConic + IConicHoleParameters
- ConicHoleAsync (ksHTConic + IConicHoleParameters: ConicType=ksCNAngle, ConicAngle) - инструмент hole_conic (diameter у дна, conicAngle 0..180); тот же HoleCore-паттерн - интеграционный тест (конус удаляет больше цилиндра Ø10); типы отверстий завершены - 70 инструментов, 119 тестов
This commit is contained in:
@@ -71,6 +71,23 @@ public sealed class HoleService
|
||||
});
|
||||
}, ct);
|
||||
|
||||
/// <summary>Коническое отверстие (ksHTConic): конусность задаётся углом conicAngle (градусы).
|
||||
/// diameter — диаметр у дна, конус расширяется к поверхности.</summary>
|
||||
public Task ConicHoleAsync(double x, double y, double z, double diameter, double depth, bool throughAll,
|
||||
double conicAngle, CancellationToken ct = default)
|
||||
=> _dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
if (!double.IsFinite(conicAngle) || conicAngle <= 0 || conicAngle >= 180)
|
||||
throw new ArgumentOutOfRangeException(nameof(conicAngle), "Угол конуса должен быть в (0; 180) градусов.");
|
||||
HoleCore(x, y, z, diameter, depth, throughAll, ksHoleTypeEnum.ksHTConic, hole =>
|
||||
{
|
||||
var p = hole.HoleParameters as IConicHoleParameters
|
||||
?? throw new InvalidOperationException("HoleParameters не приводится к IConicHoleParameters.");
|
||||
p.ConicType = ksConicTypeEnum.ksCNAngle;
|
||||
p.ConicAngle = conicAngle;
|
||||
});
|
||||
}, ct);
|
||||
|
||||
private void HoleCore(double x, double y, double z, double diameter, double depth, bool throughAll,
|
||||
ksHoleTypeEnum holeType, Action<IHole3D>? configure)
|
||||
{
|
||||
|
||||
@@ -244,6 +244,21 @@ public sealed class FeatureTools(KompasSession session, PartModeler modeler, Hol
|
||||
return $"Отверстие с зенковкой Ø{diameter} (зенковка Ø{sinkDiameter}, угол {sinkAngle}°, {kind}) создано в точке ({x}, {y}, {z}).";
|
||||
}
|
||||
|
||||
[McpServerTool(Name = "hole_conic")]
|
||||
[Description("Коническое (конусное) отверстие на грани в точке (x,y,z — центр). diameter — диаметр у дна (мм). conicAngle — угол конуса (градусы, строго 0 < conicAngle < 180); отверстие расширяется к поверхности. depth/throughAll — как у hole. Направление в тело — авто.")]
|
||||
public async Task<string> HoleConic(
|
||||
double x, double y, double z,
|
||||
[Description("Диаметр у дна, мм")] double diameter,
|
||||
[Description("Угол конуса, градусы (0 < conicAngle < 180)")] double conicAngle,
|
||||
[Description("Глубина отверстия, мм (если throughAll=false)")] double depth = 0,
|
||||
[Description("Сквозное отверстие")] bool throughAll = false)
|
||||
{
|
||||
await session.ConnectAsync();
|
||||
await holes.ConicHoleAsync(x, y, z, diameter, depth, throughAll, conicAngle);
|
||||
var kind = throughAll ? "сквозное" : $"глубина {depth} мм";
|
||||
return $"Коническое отверстие Ø{diameter} (угол {conicAngle}°, {kind}) создано в точке ({x}, {y}, {z}).";
|
||||
}
|
||||
|
||||
[McpServerTool(Name = "rebuild")]
|
||||
[Description("Перестроить активный документ.")]
|
||||
public async Task<string> Rebuild()
|
||||
|
||||
@@ -147,4 +147,28 @@ public sealed class HoleTests
|
||||
}
|
||||
finally { await _docs.CloseAsync(save: false); }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Conic_hole_removes_tapered_volume()
|
||||
{
|
||||
await _docs.CreateAsync(KompasDocumentType.Part);
|
||||
try
|
||||
{
|
||||
var s = await _modeler.OpenSketchAsync(BasePlane.XOY);
|
||||
await _modeler.AddRectangleAsync(s, -20, -20, 20, 20);
|
||||
await _modeler.CloseSketchAsync(s);
|
||||
await _modeler.ExtrudeAsync(s, depth: 20);
|
||||
var before = (await _query.GetPartInfoAsync()).Volume;
|
||||
|
||||
// Коническое Ø10 у дна, угол 20°, глухое на 15 мм по центру верхней грани.
|
||||
await _holes.ConicHoleAsync(0, 0, 20, diameter: 10, depth: 15, throughAll: false, conicAngle: 20);
|
||||
var removed = before - (await _query.GetPartInfoAsync()).Volume;
|
||||
|
||||
// Конус расширяется к поверхности → объём больше цилиндра Ø10×15 (π·25·15≈1178) и в разумных пределах.
|
||||
var baseCyl = Math.PI * 25 * 15;
|
||||
Assert.True(removed > baseCyl, "Конусное отверстие должно удалить больше цилиндра Ø10.");
|
||||
Assert.True(removed < baseCyl * 4, "Объём конуса в разумных пределах.");
|
||||
}
|
||||
finally { await _docs.CloseAsync(save: false); }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user