From 066a9f3d94b7c38c6cc2fc9d62f5704d7298c015 Mon Sep 17 00:00:00 2001 From: codex Date: Fri, 7 Aug 2026 08:48:42 +0300 Subject: [PATCH] feat: add p-rec-annot Plant line-number candidate reader --- .../src/PRecAnnot.Abstractions/Contracts.cs | 1 + .../PlantLineNumberCandidateReader.cs | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/PlantLineNumberCandidateReader.cs diff --git a/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Abstractions/Contracts.cs b/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Abstractions/Contracts.cs index 5ea7b54..14f2939 100644 --- a/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Abstractions/Contracts.cs +++ b/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Abstractions/Contracts.cs @@ -63,6 +63,7 @@ public sealed record LineNumberApplyPreflight(string StableId, int MarkerNumber, public sealed record LineNumberApplyResult(int Created, int Updated, int Unchanged); public sealed record LineNumberListApplyPreflight(string StableId, AnnotationPoint Position, double Rotation, IReadOnlyList Rows); public sealed record LineNumberPreviewResult(bool Success, LineNumberCommandPlan? Plan, IReadOnlyList Apply, string? FailureCode = null); +public sealed record LineNumberCandidateReadResult(bool Success, LineNumberCandidate? Candidate, string? FailureCode = null); public sealed record LineNumberTextAsset(string Layer, string TextStyle, double Size, string TextValue, Point2Dto Position); public sealed record LineNumberLineAsset(string Layer, Point2Dto Start, Point2Dto End); public sealed record LineNumberMarkerAsset(string Layer, double MaskScaleFactor, IReadOnlyList Texts, IReadOnlyList Lines); diff --git a/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/PlantLineNumberCandidateReader.cs b/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/PlantLineNumberCandidateReader.cs new file mode 100644 index 0000000..a5be578 --- /dev/null +++ b/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/PlantLineNumberCandidateReader.cs @@ -0,0 +1,36 @@ +using Autodesk.AutoCAD.DatabaseServices; +using Autodesk.AutoCAD.Geometry; +using Autodesk.ProcessPower.DataLinks; +using PRecAnnot.Abstractions; + +namespace PRecAnnot.Plant3D2026; + +// Converts an explicit AutoCAD selection to the small, AutoCAD-free candidate +// used by the line-number preview. It deliberately performs no DataLinks or +// DWG write and reports unavailable Plant mappings as typed failures. +internal sealed class PlantLineNumberCandidateReader(DataLinksManager dataLinks) +{ + public LineNumberCandidateReadResult Read(ObjectId selectedId, string layer, string textStyle) + { + if (selectedId.IsNull || !selectedId.IsValid) return new(false, null, "LINE_NUMBER_SELECTION_INVALID"); + if (string.IsNullOrWhiteSpace(layer) || string.IsNullOrWhiteSpace(textStyle)) return new(false, null, "LINE_NUMBER_ASSET_CONTRACT_INVALID"); + try + { + var rowId = dataLinks.FindAcPpRowId(selectedId); + if (rowId <= 0) return new(false, null, "LINE_NUMBER_DATALINKS_ROW_NOT_FOUND"); + var database = selectedId.Database; + using var transaction = database.TransactionManager.StartOpenCloseTransaction(); + if (transaction.GetObject(selectedId, OpenMode.ForRead) is not Entity entity) return new(false, null, "LINE_NUMBER_SELECTION_NOT_ENTITY"); + var extents = entity.GeometricExtents; + var center = new Point3d( + (extents.MinPoint.X + extents.MaxPoint.X) / 2d, + (extents.MinPoint.Y + extents.MaxPoint.Y) / 2d, + (extents.MinPoint.Z + extents.MaxPoint.Z) / 2d); + transaction.Commit(); + return new(true, new($"acad:{selectedId.Handle}", rowId, new(center.X, center.Y, center.Z), 0, layer, textStyle, new Dictionary())); + } + catch (Autodesk.AutoCAD.Runtime.Exception) { return new(false, null, "LINE_NUMBER_SELECTION_GEOMETRY_UNAVAILABLE"); } + catch (DLException) { return new(false, null, "LINE_NUMBER_DATALINKS_ROW_NOT_FOUND"); } + catch (Exception) { return new(false, null, "LINE_NUMBER_CANDIDATE_READ_FAILED"); } + } +}