feat: complete p-rec-annot line connection pipeline
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
using Autodesk.AutoCAD.ApplicationServices;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Autodesk.AutoCAD.Geometry;
|
||||
using PRecAnnot.Abstractions;
|
||||
|
||||
namespace PRecAnnot.Plant3D2026;
|
||||
|
||||
internal sealed class LineConnectionAnnotationWriter
|
||||
{
|
||||
private const string ApplicationName = "PXP-ALC";
|
||||
|
||||
public LineConnectionApplyResult Replace(Document document, string viewportStableId, IReadOnlyList<LineConnectionBoundaryPlan> plans, LineConnectionAssets assets)
|
||||
{
|
||||
var insertable = plans.Where(plan => plan.Reasons.Count == 0).OrderBy(plan => plan.Position.X).ThenByDescending(plan => plan.Position.Y).ToArray();
|
||||
using var documentLock = document.LockDocument();
|
||||
var database = document.Database;
|
||||
using var transaction = database.TransactionManager.StartTransaction();
|
||||
var blocks = (BlockTable)transaction.GetObject(database.BlockTableId, OpenMode.ForRead);
|
||||
var layers = (LayerTable)transaction.GetObject(database.LayerTableId, OpenMode.ForRead);
|
||||
var styles = (TextStyleTable)transaction.GetObject(database.TextStyleTableId, OpenMode.ForRead);
|
||||
if (!blocks.Has(assets.BlockName)) throw new InvalidOperationException("LINE_CONNECTION_BLOCK_MISSING:" + assets.BlockName);
|
||||
if (!layers.Has(assets.PolylineLayer)) throw new InvalidOperationException("LINE_CONNECTION_POLYLINE_LAYER_MISSING:" + assets.PolylineLayer);
|
||||
if (!layers.Has(assets.TextLayer)) throw new InvalidOperationException("LINE_CONNECTION_TEXT_LAYER_MISSING:" + assets.TextLayer);
|
||||
if (!styles.Has(assets.TextStyle)) throw new InvalidOperationException("LINE_CONNECTION_TEXT_STYLE_MISSING:" + assets.TextStyle);
|
||||
EnsureRegApp(transaction, database);
|
||||
var paper = (BlockTableRecord)transaction.GetObject(blocks[BlockTableRecord.PaperSpace], OpenMode.ForWrite);
|
||||
var deleted = 0;
|
||||
foreach (ObjectId id in paper)
|
||||
{
|
||||
var value = transaction.GetObject(id, OpenMode.ForRead);
|
||||
var data = value.GetXDataForApplication(ApplicationName)?.AsArray();
|
||||
if (data is null || !data.Any(item => item.TypeCode == (int)DxfCode.ExtendedDataAsciiString && string.Equals(item.Value?.ToString(), viewportStableId, StringComparison.Ordinal))) continue;
|
||||
value.UpgradeOpen(); value.Erase(); deleted++;
|
||||
}
|
||||
var definition = (BlockTableRecord)transaction.GetObject(blocks[assets.BlockName], OpenMode.ForRead);
|
||||
foreach (var plan in insertable)
|
||||
{
|
||||
using var reference = new BlockReference(new Point3d(plan.Position.X, plan.Position.Y, plan.Position.Z), definition.ObjectId) { LayerId = layers[assets.PolylineLayer], Rotation = plan.Rotation };
|
||||
reference.XData = Ownership(viewportStableId, plan);
|
||||
paper.AppendEntity(reference); transaction.AddNewlyCreatedDBObject(reference, true);
|
||||
var values = new[] { plan.FirstText ?? string.Empty, plan.SecondText ?? string.Empty };
|
||||
var index = 0;
|
||||
foreach (ObjectId entityId in definition)
|
||||
{
|
||||
if (transaction.GetObject(entityId, OpenMode.ForRead) is not AttributeDefinition source || source.Constant) continue;
|
||||
using var attribute = new AttributeReference();
|
||||
attribute.SetAttributeFromBlock(source, reference.BlockTransform);
|
||||
attribute.TextString = values[Math.Min(index++, 1)].Replace("\n", "\\P", StringComparison.Ordinal);
|
||||
attribute.LayerId = layers[assets.TextLayer]; attribute.TextStyleId = styles[assets.TextStyle];
|
||||
attribute.UpdateMTextAttribute(); reference.AttributeCollection.AppendAttribute(attribute); transaction.AddNewlyCreatedDBObject(attribute, true);
|
||||
}
|
||||
}
|
||||
transaction.Commit();
|
||||
return new(deleted, insertable.Length);
|
||||
}
|
||||
|
||||
private static ResultBuffer Ownership(string viewport, LineConnectionBoundaryPlan plan) => new(
|
||||
new TypedValue((int)DxfCode.ExtendedDataRegAppName, ApplicationName),
|
||||
new TypedValue((int)DxfCode.ExtendedDataAsciiString, viewport),
|
||||
new TypedValue((int)DxfCode.ExtendedDataAsciiString, plan.StableId),
|
||||
new TypedValue((int)DxfCode.ExtendedDataAsciiString, "LINENUMBER1"),
|
||||
new TypedValue((int)DxfCode.ExtendedDataAsciiString, plan.FirstText ?? string.Empty),
|
||||
new TypedValue((int)DxfCode.ExtendedDataAsciiString, "LINENUMBER2"),
|
||||
new TypedValue((int)DxfCode.ExtendedDataAsciiString, plan.SecondText ?? string.Empty));
|
||||
|
||||
private static void EnsureRegApp(Transaction transaction, Database database)
|
||||
{
|
||||
var table = (RegAppTable)transaction.GetObject(database.RegAppTableId, OpenMode.ForRead);
|
||||
if (table.Has(ApplicationName)) return;
|
||||
table.UpgradeOpen(); using var record = new RegAppTableRecord { Name = ApplicationName }; table.Add(record); transaction.AddNewlyCreatedDBObject(record, true);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user