feat(feature): операция Ребро жёсткости (rib)
RibAsync (o3d_ribOperation): SetSketch + index/angle/side + SetThinParam. SketchGeometry.RibSide маппинг (left/right/up/down). Инструмент rib в FeatureTools. Эмпирически: контур ребра висит в зазоре (не касается тела), side=left для косынки. Integration: L-уголок + ребро в углу → объём растёт. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -230,6 +230,41 @@ public sealed partial class PartModeler
|
||||
return id;
|
||||
}, ct);
|
||||
|
||||
/// <summary>Построить ребро жёсткости от разомкнутого контура эскиза до тела.
|
||||
/// thickness — толщина стенки (мм); side — направление достройки (left|right|up|down);
|
||||
/// symmetric — толщина симметрична плоскости эскиза; angle — уклон стенок (градусы).
|
||||
/// Возвращает id операции.</summary>
|
||||
public Task<int> RibAsync(int sketchId, double thickness, string side = "up", bool symmetric = true, double angle = 0, CancellationToken ct = default)
|
||||
=> _dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
if (thickness <= 0) throw new ArgumentOutOfRangeException(nameof(thickness), "Толщина должна быть > 0.");
|
||||
var sideCode = SketchGeometry.RibSide(side);
|
||||
var sketch = RequireSketch(sketchId);
|
||||
CloseSketchCore(sketch); // эскиз должен быть закрыт перед операцией
|
||||
|
||||
var part = GetTopPart();
|
||||
var entity = part.NewEntity((short)Obj3dType.o3d_ribOperation) as ksEntity
|
||||
?? throw new InvalidOperationException("NewEntity(o3d_ribOperation) вернул null.");
|
||||
var def = entity.GetDefinition() as ksRibDefinition
|
||||
?? throw new InvalidOperationException("GetDefinition() ребра вернул не ksRibDefinition.");
|
||||
def.SetSketch(sketch.Entity);
|
||||
def.index = 0; // первый сегмент контура задаёт уклон
|
||||
def.angle = angle;
|
||||
def.side = sideCode;
|
||||
if (symmetric)
|
||||
def.SetThinParam((short)Direction_Type.dtBoth, thickness / 2, thickness / 2);
|
||||
else
|
||||
def.SetThinParam((short)Direction_Type.dtNormal, thickness, 0);
|
||||
|
||||
if (!entity.Create())
|
||||
throw new InvalidOperationException(
|
||||
"Create() ребра вернул FALSE (контур не пересекает тело или неверное направление side?).");
|
||||
|
||||
var id = _nextId++;
|
||||
_features[id] = entity;
|
||||
return id;
|
||||
}, ct);
|
||||
|
||||
/// <summary>Перестроить документ.</summary>
|
||||
public Task RebuildAsync(CancellationToken ct = default)
|
||||
=> _dispatcher.InvokeAsync(() =>
|
||||
|
||||
@@ -9,6 +9,17 @@ public static class SketchGeometry
|
||||
/// <summary>describe для ksRegularPolygon: вписанный (вершины на окружности) → false; описанный → true.</summary>
|
||||
public static bool PolygonDescribe(bool inscribed) => !inscribed;
|
||||
|
||||
/// <summary>Направление достройки ребра жёсткости (ksRibSideEnum): left=0, right=1, up=2, down=3.</summary>
|
||||
public static short RibSide(string side) => side?.Trim().ToLowerInvariant() switch
|
||||
{
|
||||
"left" => 0,
|
||||
"right" => 1,
|
||||
"up" => 2,
|
||||
"down" => 3,
|
||||
_ => throw new ArgumentException(
|
||||
$"Неизвестное направление ребра: '{side}'. Ожидается left|right|up|down.", nameof(side)),
|
||||
};
|
||||
|
||||
/// <summary>Требовать строго положительное значение (радиус, полуось).</summary>
|
||||
public static void RequirePositive(double value, string paramName)
|
||||
{
|
||||
|
||||
@@ -104,6 +104,15 @@ public sealed class FeatureTools(KompasSession session, PartModeler modeler)
|
||||
return $"Оболочка толщиной {thickness} мм создана (удалено граней: {removed}), id={id}.";
|
||||
}
|
||||
|
||||
[McpServerTool(Name = "rib")]
|
||||
[Description("Построить ребро жёсткости от разомкнутого контура эскиза до тела. sketchId — эскиз с разомкнутым контуром (отрезок/ломаная) на плоскости, пересекающей тело. thickness — толщина стенки ребра (мм). side — направление достройки до тела: left|right (вдоль плоскости эскиза) или up|down (ортогонально плоскости). symmetric=true — толщина симметрична плоскости эскиза, false — в одну сторону. angle — уклон стенок (градусы). Возвращает id операции.")]
|
||||
public async Task<string> Rib(int sketchId, double thickness, string side = "up", bool symmetric = true, double angle = 0)
|
||||
{
|
||||
await session.ConnectAsync();
|
||||
var id = await modeler.RibAsync(sketchId, thickness, side, symmetric, angle);
|
||||
return $"Ребро жёсткости толщиной {thickness} мм создано (side={side}), id={id}.";
|
||||
}
|
||||
|
||||
[McpServerTool(Name = "rebuild")]
|
||||
[Description("Перестроить активный документ.")]
|
||||
public async Task<string> Rebuild()
|
||||
|
||||
Reference in New Issue
Block a user