using System.Drawing; using System.Drawing.Imaging; using System.IO; using Rhino.Display; using Rhino.DocObjects; using Rhino.Geometry; namespace RhMcp.Tools; [McpServerToolType] public static class GetViewportImageTool { [McpServerTool("get_viewport_image", "Capture Viewport Image", false, false)] [Description("Capture the active Rhino viewport as JPG. Returns the image plus a JSON metadata block describing the resulting camera, display mode, framed scene bounds, and on-screen object count — use the metadata to diagnose empty/off-screen captures without re-shooting.")] public static IEnumerable GetViewportImage( RhinoDoc doc, [Description("Image width pixels (default 480) (max 1280) increase sparingly")] int width = 480, [Description("Image height pixels (default 270) (max 720) increase sparingly")] int height = 270, [Description("Standard view: top, bottom, left, right, front, back, perspective")] string? view = null, [Description("Display mode by English name: Wireframe, Shaded, Rendered, Ghosted, X-Ray, Technical, Artistic, Pen, Monochrome, Arctic, Raytraced")] string? displayMode = null, [Description("Camera position {x,y,z}")] Vector3d? cameraLocation = null, [Description("Camera look-at point {x,y,z}")] Vector3d? target = null, [Description("Frame this bounding box (min corner). Pair with boxMax. Replaces zoom — agent supplies what to frame, tool computes how far back to stand.")] Vector3d? boxMin = null, [Description("Frame this bounding box (max corner). Pair with boxMin.")] Vector3d? boxMax = null, [Description("Magnification factor: >1 zoom in, 0 s.ToLowerInvariant() switch { "top" => DefinedViewportProjection.Top, "bottom" => DefinedViewportProjection.Bottom, "left" => DefinedViewportProjection.Left, "right" => DefinedViewportProjection.Right, "front" => DefinedViewportProjection.Front, "back" => DefinedViewportProjection.Back, "perspective" => DefinedViewportProjection.Perspective, _ => DefinedViewportProjection.None, }; private static DisplayModeDescription? FindDisplayMode(string name) { foreach (var mode in DisplayModeDescription.GetDisplayModes()) { if (string.Equals(mode.EnglishName, name, StringComparison.OrdinalIgnoreCase)) return mode; } return null; } }