From 58f71267a2276c9deadd26a0f70f6fc9e1821431 Mon Sep 17 00:00:00 2001 From: codex Date: Fri, 7 Aug 2026 08:54:31 +0300 Subject: [PATCH] feat: add p-rec-annot interactive line-number preview --- .../src/PRecAnnot.Plant3D2026/EntryPoint.cs | 40 ++++++++++++++++++- .../LineNumberRuntimeConfiguration.cs | 24 +++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/LineNumberRuntimeConfiguration.cs diff --git a/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/EntryPoint.cs b/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/EntryPoint.cs index 3a4c495..f8a4a00 100644 --- a/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/EntryPoint.cs +++ b/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/EntryPoint.cs @@ -1,7 +1,9 @@ using System.Diagnostics; using Autodesk.AutoCAD.ApplicationServices; +using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Runtime; using Autodesk.Windows; +using Autodesk.ProcessPower.PlantInstance; using PRecAnnot.Abstractions; using PRecAnnot.Core; using AcadApplication = Autodesk.AutoCAD.ApplicationServices.Application; @@ -35,7 +37,7 @@ public sealed class EntryPoint : IExtensionApplication [CommandMethod("PXP-OA")] public void OrthoAnnotateCommand() => RunDiagnostic("PXP-OA"); - [CommandMethod("PXP-LN")] public void AnnotateLineNumbersCommand() => RunDiagnostic("PXP-LN"); + [CommandMethod("PXP-LN")] public void AnnotateLineNumbersCommand() => RunLineNumberPreview(); [CommandMethod("PXP-ULN")] public void UpdateLineNumbersCommand() => RunDiagnostic("PXP-ULN"); [CommandMethod("PXP-ESN")] public void EditLineNumberStartCommand() => RunDiagnostic("PXP-ESN"); [CommandMethod("PXP-ELN")] public void EditLineNumbersCommand() => RunDiagnostic("PXP-ELN"); @@ -68,6 +70,42 @@ public sealed class EntryPoint : IExtensionApplication [CommandMethod("PHP_REC_AUTOMATION_FINALIZE", CommandFlags.Session)] public void AutomationFinalizeCommand() => ScriptDrivenFirstApplyAutomation.FinalizeAutomation(); + private static void RunLineNumberPreview() + { + var document = AcadApplication.DocumentManager.MdiActiveDocument; + if (document is null) return; + var editor = document.Editor; + try + { + var configuration = LineNumberRuntimeConfigurationReader.Read(); + var profileDefault = configuration.Annotations.Annotations.OrderBy(value => value.Nickname, StringComparer.Ordinal).First(); + var profilePrompt = new PromptStringOptions($"\nПрофиль номера линии <{profileDefault.Nickname}>: ") { AllowSpaces = false, DefaultValue = profileDefault.Nickname, UseDefaultValue = true }; + var profileInput = editor.GetString(profilePrompt); + if (profileInput.Status != PromptStatus.OK) return; + var profile = configuration.Annotations.Annotations.SingleOrDefault(value => string.Equals(value.Nickname, profileInput.StringResult, StringComparison.OrdinalIgnoreCase)); + if (profile is null) throw new InvalidOperationException("LINE_NUMBER_PROFILE_NOT_FOUND"); + + var selection = editor.GetEntity("\nВыберите компонент Plant 3D для аннотации номера линии: "); + if (selection.Status != PromptStatus.OK) return; + var piping = PlantApplication.ProjectPart("Piping")?.DataLinksManager ?? throw new InvalidOperationException("LINE_NUMBER_PIPING_DATALINKS_UNAVAILABLE"); + var candidate = new PlantLineNumberCandidateReader(piping).Read(selection.ObjectId, configuration.Assets.Marker.Layer, configuration.Assets.Marker.Texts[0].TextStyle); + if (!candidate.Success) throw new InvalidOperationException(candidate.FailureCode); + var preview = new LineNumberCommandPreviewService( + new LineNumberCommandPlanner(new LineNumberAnnotationFormatter()), + new LineNumberFieldResolver(new PlantDataLinksPropertyReader(piping))) + .Preview(profile, [candidate.Candidate!], Array.Empty()); + if (!preview.Success) throw new InvalidOperationException(preview.FailureCode); + var operations = string.Join(", ", preview.Plan!.Operations.Select(value => $"{value.Kind}:{value.Text}")); + editor.WriteMessage($"\nPXP-LN preview: {operations}. DWG не изменён."); + RuntimeDiagnostics.Write("LineNumberPreviewCompleted", commandName: "PXP-LN", resultStatus: "PreviewCompleted", document: document, details: new Dictionary { ["OperationCount"] = preview.Apply.Count }); + } + catch (System.Exception exception) + { + RuntimeDiagnostics.Write("LineNumberPreviewFailed", "ERROR", commandName: "PXP-LN", resultStatus: exception.Message, exception: exception, document: document); + WriteEditor(document, $"\nPXP-LN: {exception.Message}"); + } + } + private static void RunDiagnostic(string commandName) { var operationId = Guid.NewGuid().ToString("N"); diff --git a/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/LineNumberRuntimeConfiguration.cs b/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/LineNumberRuntimeConfiguration.cs new file mode 100644 index 0000000..ad0cbd5 --- /dev/null +++ b/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/LineNumberRuntimeConfiguration.cs @@ -0,0 +1,24 @@ +using PRecAnnot.Abstractions; +using PRecAnnot.Core; + +namespace PRecAnnot.Plant3D2026; + +internal sealed record LineNumberRuntimeConfiguration(LineNumberAnnotationSettings Annotations, AnnotateLineNumbersAssets Assets); + +internal static class LineNumberRuntimeConfigurationReader +{ + public static LineNumberRuntimeConfiguration Read() + { + var annotationPath = RequiredLocalFile("P_REC_ANNOT_LINE_NUMBER_ANNOTATION_SETTINGS_PATH"); + var drawingPath = RequiredLocalFile("P_REC_ANNOT_LINE_NUMBER_DRAWING_SETTINGS_PATH"); + return new(new LineNumberAnnotationSettingsLoader().Load(File.ReadAllText(annotationPath)), new AnnotateLineNumbersSettingsLoader().Load(File.ReadAllText(drawingPath))); + } + + private static string RequiredLocalFile(string variable) + { + var path = Environment.GetEnvironmentVariable(variable); + if (string.IsNullOrWhiteSpace(path) || !Path.IsPathFullyQualified(path) || path.StartsWith("\\\\", StringComparison.Ordinal) || !File.Exists(path)) + throw new InvalidOperationException($"LINE_NUMBER_CONFIGURATION_REQUIRED:{variable}"); + return path; + } +}