feat: add p-rec-annot interactive line-number preview

This commit is contained in:
codex
2026-08-07 08:54:31 +03:00
parent 066a9f3d94
commit 58f71267a2
2 changed files with 63 additions and 1 deletions
@@ -1,7 +1,9 @@
using System.Diagnostics; using System.Diagnostics;
using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.Runtime;
using Autodesk.Windows; using Autodesk.Windows;
using Autodesk.ProcessPower.PlantInstance;
using PRecAnnot.Abstractions; using PRecAnnot.Abstractions;
using PRecAnnot.Core; using PRecAnnot.Core;
using AcadApplication = Autodesk.AutoCAD.ApplicationServices.Application; using AcadApplication = Autodesk.AutoCAD.ApplicationServices.Application;
@@ -35,7 +37,7 @@ public sealed class EntryPoint : IExtensionApplication
[CommandMethod("PXP-OA")] [CommandMethod("PXP-OA")]
public void OrthoAnnotateCommand() => RunDiagnostic("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-ULN")] public void UpdateLineNumbersCommand() => RunDiagnostic("PXP-ULN");
[CommandMethod("PXP-ESN")] public void EditLineNumberStartCommand() => RunDiagnostic("PXP-ESN"); [CommandMethod("PXP-ESN")] public void EditLineNumberStartCommand() => RunDiagnostic("PXP-ESN");
[CommandMethod("PXP-ELN")] public void EditLineNumbersCommand() => RunDiagnostic("PXP-ELN"); [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)] [CommandMethod("PHP_REC_AUTOMATION_FINALIZE", CommandFlags.Session)]
public void AutomationFinalizeCommand() => ScriptDrivenFirstApplyAutomation.FinalizeAutomation(); 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<ExistingLineNumberAnnotation>());
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<string, object?> { ["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) private static void RunDiagnostic(string commandName)
{ {
var operationId = Guid.NewGuid().ToString("N"); var operationId = Guid.NewGuid().ToString("N");
@@ -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;
}
}