pi-revit 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +167 -0
- package/CHANGELOG.md +465 -430
- package/README.md +604 -548
- package/bin/pi-revit.js +9 -9
- package/docs/architecture.md +271 -0
- package/docs/evaluation.md +434 -0
- package/docs/invariants.json +147 -0
- package/extensions/pi-revit/completion-monitor.ts +55 -0
- package/extensions/pi-revit/contracts.ts +146 -0
- package/extensions/pi-revit/discovery.ts +93 -0
- package/extensions/pi-revit/index.ts +342 -255
- package/extensions/pi-revit/instance-router.ts +86 -86
- package/extensions/pi-revit/platform-prompt.ts +40 -0
- package/extensions/pi-revit/scope-monitor.ts +114 -0
- package/extensions/pi-revit/script-library.ts +144 -144
- package/extensions/pi-revit/tool-catalog.ts +113 -14
- package/extensions/pi-revit/tool-documentation.ts +72 -0
- package/extensions/pi-revit/tool-schema.ts +8 -0
- package/package.json +8 -2
- package/scripts/build.ps1 +9 -9
- package/scripts/check-sdk.ps1 +66 -66
- package/scripts/check-tool-documentation.mjs +287 -0
- package/scripts/deploy.ps1 +16 -16
- package/scripts/generate-contracts.mjs +80 -0
- package/scripts/lib/platform.mjs +226 -0
- package/scripts/test-extension.mjs +15 -0
- package/skills/pi-revit/SKILL.md +30 -218
- package/skills/pi-revit/contracts.generated.json +3524 -0
- package/skills/pi-revit/references/execution-rules.md +41 -0
- package/skills/pi-revit/references/model-audit-export.md +38 -27
- package/skills/pi-revit/references/operation-recovery.md +33 -0
- package/skills/pi-revit/references/room-documentation.md +37 -26
- package/skills/pi-revit/references/tool-index.md +89 -0
- package/skills/pi-revit/references/tools/capture_view.md +62 -0
- package/skills/pi-revit/references/tools/change_element_types.md +65 -0
- package/skills/pi-revit/references/tools/create_tags.md +85 -0
- package/skills/pi-revit/references/tools/delete_elements.md +66 -0
- package/skills/pi-revit/references/tools/execute_csharp.md +81 -0
- package/skills/pi-revit/references/tools/export_documents.md +75 -0
- package/skills/pi-revit/references/tools/find_revit_tools.md +96 -0
- package/skills/pi-revit/references/tools/get_element_details.md +66 -0
- package/skills/pi-revit/references/tools/get_element_relationships.md +61 -0
- package/skills/pi-revit/references/tools/get_element_types.md +67 -0
- package/skills/pi-revit/references/tools/get_elements.md +87 -0
- package/skills/pi-revit/references/tools/get_linked_elements.md +79 -0
- package/skills/pi-revit/references/tools/get_linked_models.md +57 -0
- package/skills/pi-revit/references/tools/get_model_coordinates.md +64 -0
- package/skills/pi-revit/references/tools/get_model_health.md +53 -0
- package/skills/pi-revit/references/tools/get_model_overview.md +57 -0
- package/skills/pi-revit/references/tools/get_revit_operation.md +54 -0
- package/skills/pi-revit/references/tools/get_schedule_fields.md +62 -0
- package/skills/pi-revit/references/tools/get_schedules.md +71 -0
- package/skills/pi-revit/references/tools/manage_element_sets.md +92 -0
- package/skills/pi-revit/references/tools/manage_revit_instances.md +63 -0
- package/skills/pi-revit/references/tools/manage_revit_scripts.md +109 -0
- package/skills/pi-revit/references/tools/manage_schedules.md +90 -0
- package/skills/pi-revit/references/tools/manage_selection.md +66 -0
- package/skills/pi-revit/references/tools/manage_sheet_placements.md +82 -0
- package/skills/pi-revit/references/tools/manage_sheets.md +71 -0
- package/skills/pi-revit/references/tools/manage_views.md +95 -0
- package/skills/pi-revit/references/tools/measure_geometry.md +71 -0
- package/skills/pi-revit/references/tools/open_view.md +59 -0
- package/skills/pi-revit/references/tools/ping.md +41 -0
- package/skills/pi-revit/references/tools/query_spatial_elements.md +74 -0
- package/skills/pi-revit/references/tools/read_revit_result.md +53 -0
- package/skills/pi-revit/references/tools/search_api_docs.md +65 -0
- package/skills/pi-revit/references/tools/set_parameters.md +75 -0
- package/skills/pi-revit/references/tools/summarize_elements.md +64 -0
- package/skills/pi-revit/references/tools/transform_elements.md +79 -0
- package/skills/pi-revit/references/visual-verification.md +36 -0
- package/skills/pi-revit/tool-manifest.json +338 -0
- package/src/Revit/BridgeServer.cs +93 -87
- package/src/Revit/OperationStore.cs +178 -178
- package/src/Revit/ToolRegistry.cs +88 -57
- package/src/Revit/Tools/CaptureView.cs +10 -2
- package/src/Revit/Tools/ChangeElementTypes.cs +74 -60
- package/src/Revit/Tools/ChangeSet.cs +39 -0
- package/src/Revit/Tools/CreateTags.cs +107 -95
- package/src/Revit/Tools/DeleteElements.cs +53 -44
- package/src/Revit/Tools/DocumentGuard.cs +74 -64
- package/src/Revit/Tools/ElementNames.cs +103 -0
- package/src/Revit/Tools/ElementQueryScope.cs +27 -27
- package/src/Revit/Tools/ElementTraits.cs +53 -0
- package/src/Revit/Tools/ExecuteCsharp.cs +54 -45
- package/src/Revit/Tools/ExportDocuments.cs +129 -121
- package/src/Revit/Tools/GetElementDetails.cs +37 -41
- package/src/Revit/Tools/GetElementRelationships.cs +82 -76
- package/src/Revit/Tools/GetElementTypes.cs +8 -0
- package/src/Revit/Tools/GetElements.cs +75 -86
- package/src/Revit/Tools/GetLinkedElements.cs +89 -82
- package/src/Revit/Tools/GetLinkedModels.cs +73 -66
- package/src/Revit/Tools/GetModelCoordinates.cs +56 -49
- package/src/Revit/Tools/GetModelHealth.cs +7 -0
- package/src/Revit/Tools/GetModelOverview.cs +185 -158
- package/src/Revit/Tools/GetScheduleFields.cs +44 -37
- package/src/Revit/Tools/GetSchedules.cs +96 -89
- package/src/Revit/Tools/InheritedState.Summary.cs +57 -0
- package/src/Revit/Tools/InheritedState.cs +144 -0
- package/src/Revit/Tools/ManageElementSets.cs +114 -106
- package/src/Revit/Tools/ManageSchedules.cs +174 -164
- package/src/Revit/Tools/ManageSelection.cs +45 -37
- package/src/Revit/Tools/ManageSheetPlacements.cs +113 -97
- package/src/Revit/Tools/ManageSheets.cs +72 -63
- package/src/Revit/Tools/ManageViews.cs +115 -100
- package/src/Revit/Tools/MeasureGeometry.cs +60 -54
- package/src/Revit/Tools/ModelChanges.cs +154 -0
- package/src/Revit/Tools/ModelEditBatch.cs +105 -102
- package/src/Revit/Tools/ModelEditInputs.cs +49 -49
- package/src/Revit/Tools/OpenView.cs +9 -2
- package/src/Revit/Tools/ParameterResolver.cs +94 -0
- package/src/Revit/Tools/QuerySpatialElements.cs +70 -63
- package/src/Revit/Tools/SearchApiDocs.cs +72 -4
- package/src/Revit/Tools/SetParameters.cs +60 -79
- package/src/Revit/Tools/SpatialBounds.cs +30 -30
- package/src/Revit/Tools/SummarizeElements.cs +94 -87
- package/src/Revit/Tools/ToolContract.cs +48 -0
- package/src/Revit/Tools/ToolSupport.cs +5 -1
- package/src/Revit/Tools/TransformElements.cs +72 -57
- package/workspace/AGENTS.md +26 -20
|
@@ -1,97 +1,113 @@
|
|
|
1
|
-
using System.Text.Json;
|
|
2
|
-
using Autodesk.Revit.DB;
|
|
3
|
-
|
|
4
|
-
namespace RevitBridge.Tools;
|
|
5
|
-
|
|
6
|
-
internal sealed class ManageSheetPlacements : ITool
|
|
7
|
-
{
|
|
8
|
-
public string Name => "manage_sheet_placements";
|
|
9
|
-
public string
|
|
10
|
-
public string
|
|
11
|
-
public
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
1
|
+
using System.Text.Json;
|
|
2
|
+
using Autodesk.Revit.DB;
|
|
3
|
+
|
|
4
|
+
namespace RevitBridge.Tools;
|
|
5
|
+
|
|
6
|
+
internal sealed class ManageSheetPlacements : ITool
|
|
7
|
+
{
|
|
8
|
+
public string Name => "manage_sheet_placements";
|
|
9
|
+
public IReadOnlyList<string> DocumentKinds => DocumentKind.ProjectOnly;
|
|
10
|
+
public IReadOnlyList<string> Keywords => new[] { "viewport", "place view on sheet", "sheet layout", "move viewport", "schedule on sheet", "arrange sheet" };
|
|
11
|
+
public IReadOnlyList<ToolLimit> Limits => new[]
|
|
12
|
+
{
|
|
13
|
+
new ToolLimit("Creating the source view or schedule", "tool", "manage_views; manage_schedules"),
|
|
14
|
+
new ToolLimit("Rotating schedule instances", "api", "ScheduleSheetInstance.Rotation"),
|
|
15
|
+
new ToolLimit("Changing the titleblock", "tool", "change_element_types on the titleblock instance"),
|
|
16
|
+
};
|
|
17
|
+
public string? Verification => "capture";
|
|
18
|
+
public string Label => "Manage Sheet Placements";
|
|
19
|
+
public string Tier => "advanced";
|
|
20
|
+
public bool Write => true;
|
|
21
|
+
public string Description => "List, place or move viewports and schedule instances on a sheet. Positions are paper-space sheet coordinates with explicit length units, [x,y,0]; never multiply by view scale. For viewports position is the box center excluding its label; for schedules it is the insertion point. Place requires sheet_id/view_id, move requires placement_id. Viewports may rotate none/clockwise/counterclockwise; schedule rotation is not supported. preview=true commit-validates then rolls back; new placement IDs are temporary. List includes viewports, schedules and the titleblock's own revision schedules (kind titleblock_revision_schedule: part of the titleblock, not placed content), with paging and per-kind counts over the whole sheet. Exact document identity is required for every action.";
|
|
22
|
+
public object ParametersSchema => new
|
|
23
|
+
{
|
|
24
|
+
type = "object", properties = new
|
|
25
|
+
{
|
|
26
|
+
action = new { type = "string", @enum = new[] { "list", "place", "move" } },
|
|
27
|
+
sheet_id = new { type = "integer", minimum = 1 }, view_id = new { type = "integer", minimum = 1 }, placement_id = new { type = "integer", minimum = 1 },
|
|
28
|
+
position = ModelEditInputs.VectorSchema("Sheet paper-space [x,y,0] in unit."), unit = ModelEditInputs.LengthUnitSchema,
|
|
29
|
+
rotation = new { type = "string", @enum = new[] { "none", "clockwise", "counterclockwise" } },
|
|
30
|
+
offset = new { type = "integer", minimum = 0 }, limit = new { type = "integer", minimum = 1, maximum = 200 }, preview = ModelEditInputs.PreviewSchema,
|
|
31
|
+
}, required = new[] { "action" },
|
|
32
|
+
};
|
|
33
|
+
public object Execute(JsonElement args, ToolContext context)
|
|
34
|
+
{
|
|
35
|
+
var doc = context.Document ?? throw new NoActiveDocumentException();
|
|
36
|
+
string action = JsonArgs.GetString(args, "action") ?? "";
|
|
37
|
+
ElementId Id(string name) => new(JsonArgs.GetLong(args, name) is long id && id > 0 ? id : throw new ArgumentException($"{name} must be a positive ID."));
|
|
38
|
+
if (action == "list")
|
|
39
|
+
{
|
|
40
|
+
var sheet = doc.GetElement(Id("sheet_id")) as ViewSheet ?? throw new ArgumentException("sheet_id is not a sheet.");
|
|
41
|
+
var items = new FilteredElementCollector(doc).OwnedByView(sheet.Id).WhereElementIsNotElementType()
|
|
42
|
+
.Where(e => e is Viewport or ScheduleSheetInstance).OrderBy(e => e.Id.Value).ToArray();
|
|
43
|
+
int offset = JsonArgs.GetInt(args, "offset", 0), limit = JsonArgs.GetInt(args, "limit", 100);
|
|
44
|
+
if (offset < 0 || limit is < 1 or > 200) throw new ArgumentException("Invalid paging range.");
|
|
45
|
+
var page = items.Skip(offset).Take(limit).Select(Describe).ToArray();
|
|
46
|
+
// Counts cover the whole sheet, so "is anything placed?" never depends on paging
|
|
47
|
+
// or on mistaking the titleblock's revision schedule for placed content.
|
|
48
|
+
var kinds = items.Select(ElementTraits.PlacementKind).ToArray();
|
|
49
|
+
var counts = new { viewports = kinds.Count(k => k == "viewport"), schedules = kinds.Count(k => k == "schedule"),
|
|
50
|
+
titleblock_revision_schedules = kinds.Count(k => k == "titleblock_revision_schedule") };
|
|
51
|
+
return new { sheet_id = sheet.Id.Value, total_count = items.Length, counts, offset, returned_count = page.Length, next_offset = offset + page.Length < items.Length ? (int?)(offset + page.Length) : null, placements = page, coordinate_system = "sheet_paper", unit = "feet" };
|
|
52
|
+
}
|
|
53
|
+
if (action is not ("place" or "move")) throw new ArgumentException("action must be list, place or move.");
|
|
54
|
+
var point = ModelEditInputs.Vector(args, "position").Multiply(ModelEditInputs.LengthScale(args));
|
|
55
|
+
if (Math.Abs(point.Z) > 1e-9) throw new ArgumentException("Sheet position Z must be zero.");
|
|
56
|
+
var rotation = JsonArgs.GetString(args, "rotation") switch
|
|
57
|
+
{
|
|
58
|
+
null => (ViewportRotation?)null, "none" => ViewportRotation.None, "clockwise" => ViewportRotation.Clockwise,
|
|
59
|
+
"counterclockwise" => ViewportRotation.Counterclockwise, _ => throw new ArgumentException("Invalid rotation."),
|
|
60
|
+
};
|
|
61
|
+
return ModelEditBatch.Run(doc, Name, args, new[] { new ModelEditBatch.Step(new() { ["action"] = action }, () =>
|
|
62
|
+
{
|
|
63
|
+
Element placement;
|
|
64
|
+
object? before = null;
|
|
65
|
+
if (action == "place")
|
|
66
|
+
{
|
|
67
|
+
var sheet = doc.GetElement(Id("sheet_id")) as ViewSheet ?? throw new ArgumentException("sheet_id is not a sheet.");
|
|
68
|
+
if (sheet.IsPlaceholder) throw new ArgumentException("Cannot place content on a placeholder sheet.");
|
|
69
|
+
var view = doc.GetElement(Id("view_id")) as View ?? throw new ArgumentException("view_id is not a view or schedule.");
|
|
70
|
+
if (view is ViewSchedule schedule)
|
|
71
|
+
{
|
|
72
|
+
if (rotation != null) throw new ArgumentException("Schedules do not support viewport rotation.");
|
|
73
|
+
placement = ScheduleSheetInstance.Create(doc, sheet.Id, schedule.Id, point);
|
|
74
|
+
}
|
|
75
|
+
else
|
|
76
|
+
{
|
|
77
|
+
if (!Viewport.CanAddViewToSheet(doc, sheet.Id, view.Id)) throw new ArgumentException("This view cannot be added to that sheet; it may already be placed.");
|
|
78
|
+
placement = Viewport.Create(doc, sheet.Id, view.Id, point);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else
|
|
82
|
+
{
|
|
83
|
+
placement = doc.GetElement(Id("placement_id")) ?? throw new ArgumentException("placement_id was not found.");
|
|
84
|
+
if (args.TryGetProperty("sheet_id", out _) && placement.OwnerViewId != Id("sheet_id")) throw new ArgumentException("The placement does not belong to the expected sheet_id.");
|
|
85
|
+
if (placement.Pinned) throw new ArgumentException("Placement is pinned; it was not unpinned.");
|
|
86
|
+
if (ElementTraits.PlacementKind(placement) == "titleblock_revision_schedule")
|
|
87
|
+
throw new ArgumentException("This is the titleblock's revision schedule; it belongs to the titleblock family and is not moved as a placement.");
|
|
88
|
+
before = Describe(placement);
|
|
89
|
+
if (placement is Viewport viewport) viewport.SetBoxCenter(point);
|
|
90
|
+
else if (placement is ScheduleSheetInstance schedule)
|
|
91
|
+
{
|
|
92
|
+
if (rotation != null) throw new ArgumentException("Schedules do not support viewport rotation.");
|
|
93
|
+
schedule.Point = point;
|
|
94
|
+
}
|
|
95
|
+
else throw new ArgumentException("placement_id must identify a viewport or schedule instance.");
|
|
96
|
+
}
|
|
97
|
+
if (rotation != null && placement is Viewport target) target.Rotation = rotation.Value;
|
|
98
|
+
doc.Regenerate();
|
|
99
|
+
if (placement is Viewport positioned) { positioned.SetBoxCenter(point); doc.Regenerate(); }
|
|
100
|
+
return new() { ["before"] = before, ["placement"] = Describe(placement), ["created"] = action == "place", ["id_is_temporary"] = action == "place" && JsonArgs.GetBool(args, "preview", false) };
|
|
101
|
+
}) }).Payload;
|
|
102
|
+
}
|
|
103
|
+
private static object Describe(Element element)
|
|
104
|
+
{
|
|
105
|
+
static double[] Point(XYZ p) => new[] { p.X, p.Y, p.Z };
|
|
106
|
+
return element switch
|
|
107
|
+
{
|
|
108
|
+
Viewport v => new { id = v.Id.Value, unique_id = v.UniqueId, kind = ElementTraits.PlacementKind(v), sheet_id = v.SheetId.Value, view_id = v.ViewId.Value, position = Point(v.GetBoxCenter()), position_kind = "box_center_excluding_label", rotation = v.Rotation.ToString(), unit = "feet", traits = ElementTraits.For(v) } as object,
|
|
109
|
+
ScheduleSheetInstance s => new { id = s.Id.Value, unique_id = s.UniqueId, kind = ElementTraits.PlacementKind(s), sheet_id = s.OwnerViewId.Value, view_id = s.ScheduleId.Value, position = Point(s.Point), position_kind = "insertion_point", unit = "feet", traits = ElementTraits.For(s) },
|
|
110
|
+
_ => throw new ArgumentException("Element is not a sheet placement."),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -1,63 +1,72 @@
|
|
|
1
|
-
using System.Text.Json;
|
|
2
|
-
using Autodesk.Revit.DB;
|
|
3
|
-
|
|
4
|
-
namespace RevitBridge.Tools;
|
|
5
|
-
|
|
6
|
-
internal sealed class ManageSheets : ITool
|
|
7
|
-
{
|
|
8
|
-
public string Name => "manage_sheets";
|
|
9
|
-
public string
|
|
10
|
-
public string
|
|
11
|
-
public
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
public object
|
|
23
|
-
{
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (action
|
|
36
|
-
|
|
37
|
-
{
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
1
|
+
using System.Text.Json;
|
|
2
|
+
using Autodesk.Revit.DB;
|
|
3
|
+
|
|
4
|
+
namespace RevitBridge.Tools;
|
|
5
|
+
|
|
6
|
+
internal sealed class ManageSheets : ITool
|
|
7
|
+
{
|
|
8
|
+
public string Name => "manage_sheets";
|
|
9
|
+
public IReadOnlyList<string> DocumentKinds => DocumentKind.ProjectOnly;
|
|
10
|
+
public IReadOnlyList<string> Keywords => new[] { "sheet", "drawing sheet", "sheet number", "rename sheet", "renumber", "titleblock", "new sheet" };
|
|
11
|
+
public IReadOnlyList<ToolLimit> Limits => new[]
|
|
12
|
+
{
|
|
13
|
+
new ToolLimit("Placing views or schedules on a sheet", "tool", "manage_sheet_placements"),
|
|
14
|
+
new ToolLimit("Revisions and revision clouds", "api", "Revision.Create; RevisionCloud.Create"),
|
|
15
|
+
new ToolLimit("Deleting sheets", "tool", "delete_elements"),
|
|
16
|
+
};
|
|
17
|
+
public string? Verification => "reread";
|
|
18
|
+
public string Label => "Manage Sheets";
|
|
19
|
+
public string Tier => "advanced";
|
|
20
|
+
public bool Write => true;
|
|
21
|
+
public string Description => "Create or rename/renumber a drawing sheet. Creation requires name and number; optional titleblock_type_id chooses a loaded titleblock FamilySymbol, otherwise creates a sheet without a titleblock. Update requires sheet_id and accepts name/number. Revit validates unique sheet numbers and valid text; sheet names may repeat; the call rolls back on failure. preview=true commit-validates and rolls back, and new preview sheet IDs are temporary. Use manage_sheet_placements for views/schedules, get_elements for querying sheets, and delete_elements for removal.";
|
|
22
|
+
public object ParametersSchema => new
|
|
23
|
+
{
|
|
24
|
+
type = "object", properties = new
|
|
25
|
+
{
|
|
26
|
+
action = new { type = "string", @enum = new[] { "create", "update" } },
|
|
27
|
+
sheet_id = new { type = "integer", minimum = 1 }, name = new { type = "string", minLength = 1 }, number = new { type = "string", minLength = 1 },
|
|
28
|
+
titleblock_type_id = new { type = "integer", minimum = 1, description = "Creation only; omitted means no titleblock." }, preview = ModelEditInputs.PreviewSchema,
|
|
29
|
+
}, required = new[] { "action" },
|
|
30
|
+
};
|
|
31
|
+
public object Execute(JsonElement args, ToolContext context)
|
|
32
|
+
{
|
|
33
|
+
var doc = context.Document ?? throw new NoActiveDocumentException();
|
|
34
|
+
string action = JsonArgs.GetString(args, "action") ?? "";
|
|
35
|
+
if (action is not ("create" or "update")) throw new ArgumentException("action must be create or update.");
|
|
36
|
+
string? ReadText(string key)
|
|
37
|
+
{
|
|
38
|
+
if (!args.TryGetProperty(key, out var value)) return null;
|
|
39
|
+
if (value.ValueKind != JsonValueKind.String || string.IsNullOrWhiteSpace(value.GetString())) throw new ArgumentException($"{key} must be a nonempty string.");
|
|
40
|
+
return value.GetString();
|
|
41
|
+
}
|
|
42
|
+
string? name = ReadText("name"), number = ReadText("number");
|
|
43
|
+
if (action == "create" && (name == null || number == null)) throw new ArgumentException("Sheet creation requires name and number.");
|
|
44
|
+
if (action == "update" && args.TryGetProperty("titleblock_type_id", out _)) throw new ArgumentException("titleblock_type_id is only supported when creating a sheet; use change_element_types on an existing titleblock instance.");
|
|
45
|
+
return ModelEditBatch.Run(doc, Name, args, new[] { new ModelEditBatch.Step(new() { ["action"] = action }, () =>
|
|
46
|
+
{
|
|
47
|
+
ViewSheet sheet;
|
|
48
|
+
object? before = null;
|
|
49
|
+
if (action == "create")
|
|
50
|
+
{
|
|
51
|
+
var typeId = ElementId.InvalidElementId;
|
|
52
|
+
if (args.TryGetProperty("titleblock_type_id", out _))
|
|
53
|
+
{
|
|
54
|
+
typeId = new ElementId(JsonArgs.GetLong(args, "titleblock_type_id") ?? 0);
|
|
55
|
+
var type = doc.GetElement(typeId) as FamilySymbol;
|
|
56
|
+
if (type?.Category?.Id.Value != (long)BuiltInCategory.OST_TitleBlocks) throw new ArgumentException("titleblock_type_id must identify a titleblock FamilySymbol.");
|
|
57
|
+
}
|
|
58
|
+
sheet = ViewSheet.Create(doc, typeId);
|
|
59
|
+
}
|
|
60
|
+
else
|
|
61
|
+
{
|
|
62
|
+
sheet = doc.GetElement(new ElementId(JsonArgs.GetLong(args, "sheet_id") ?? 0)) as ViewSheet ?? throw new ArgumentException("sheet_id is not a sheet.");
|
|
63
|
+
before = Describe(sheet);
|
|
64
|
+
}
|
|
65
|
+
if (number != null) ElementNames.AssignSheetNumber(sheet, number);
|
|
66
|
+
if (name != null) ElementNames.Assign(sheet, name);
|
|
67
|
+
doc.Regenerate();
|
|
68
|
+
return new() { ["before"] = before, ["sheet"] = Describe(sheet), ["created"] = action == "create", ["id_is_temporary"] = action == "create" && JsonArgs.GetBool(args, "preview", false) };
|
|
69
|
+
}) }).Payload;
|
|
70
|
+
}
|
|
71
|
+
private static object Describe(ViewSheet sheet) => new { id = sheet.Id.Value, unique_id = sheet.UniqueId, name = sheet.Name, number = sheet.SheetNumber, placeholder = sheet.IsPlaceholder };
|
|
72
|
+
}
|