feat: read p-rec-annot connector ports

This commit is contained in:
codex
2026-08-07 09:47:20 +03:00
parent 53d6378cfa
commit acfa6723c9
3 changed files with 70 additions and 2 deletions
@@ -104,12 +104,24 @@ public sealed record PlantConnectorRelationshipSnapshot(
long SecondPartRowId,
long FirstLineGroupRowId,
long SecondLineGroupRowId,
IReadOnlyList<string> Diagnostics);
IReadOnlyList<string> Diagnostics,
string? ConnectorEntityStableId = null);
public sealed record PlantConnectorRelationshipReadResult(bool Success, IReadOnlyList<PlantConnectorRelationshipSnapshot> Connectors, string? FailureCode = null);
public interface IPlantConnectorRelationshipReader
{
PlantConnectorRelationshipReadResult Read();
}
public sealed record PlantConnectorPortSnapshot(
string ConnectorStableId,
Point3Dto FirstPosition,
Point3Dto SecondPosition,
Point3Dto FirstDirection,
Point3Dto SecondDirection);
public sealed record PlantConnectorPortReadResult(bool Success, PlantConnectorPortSnapshot? Ports, string? FailureCode = null);
public interface IPlantConnectorPortReader
{
PlantConnectorPortReadResult Read(PlantConnectorRelationshipSnapshot connector);
}
public sealed record LineNumberOwnedRow(string SourceStableId, int MarkerNumber, string Text, AnnotationPoint MarkerAttributePosition);
public sealed record LineNumberRowMutation(string SourceStableId, int PreviousMarkerNumber, int MarkerNumber, string Text, AnnotationPoint? MarkerAttributePosition);
public sealed record LineNumberTextAsset(string Layer, string TextStyle, double Size, string TextValue, Point2Dto Position);
@@ -0,0 +1,46 @@
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.ProcessPower.PnP3dObjects;
using PRecAnnot.Abstractions;
namespace PRecAnnot.Plant3D2026;
// Reads the actual two Plant Connector ports from the source model database.
// Paper-space projection and viewport filtering deliberately stay in the Ortho
// adapter; this boundary only exposes stable, Autodesk-free model geometry.
internal sealed class PlantConnectorPortReader(Database sourceModelDatabase) : IPlantConnectorPortReader
{
public PlantConnectorPortReadResult Read(PlantConnectorRelationshipSnapshot connector)
{
if (!TryObjectId(connector.ConnectorEntityStableId, out var id)) return new(false, null, "CONNECTOR_ENTITY_HANDLE_UNAVAILABLE");
try
{
using var transaction = sourceModelDatabase.TransactionManager.StartOpenCloseTransaction();
if (transaction.GetObject(id, OpenMode.ForRead) is not Connector entity) return new(false, null, "CONNECTOR_ENTITY_NOT_FOUND");
var ports = entity.GetPorts(PortType.Both);
if (ports.Count != 2) return new(false, null, "CONNECTOR_PORT_COUNT_INVALID");
var first = ports[0];
var second = ports[1];
return new(true, new(
connector.StableId,
Point(first.Position),
Point(second.Position),
Vector(first.Direction),
Vector(second.Direction)));
}
catch (Autodesk.AutoCAD.Runtime.Exception) { return new(false, null, "CONNECTOR_PORT_READ_FAILED"); }
catch (Exception) { return new(false, null, "CONNECTOR_PORT_READ_FAILED"); }
}
private bool TryObjectId(string? stableId, out ObjectId id)
{
id = ObjectId.Null;
const string prefix = "acad:";
if (string.IsNullOrWhiteSpace(stableId) || !stableId.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) ||
!long.TryParse(stableId[prefix.Length..], System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out var handle)) return false;
try { id = sourceModelDatabase.GetObjectId(false, new Handle(handle), 0); return !id.IsNull; }
catch { return false; }
}
private static Point3Dto Point(Autodesk.AutoCAD.Geometry.Point3d point) => new(point.X, point.Y, point.Z);
private static Point3Dto Vector(Autodesk.AutoCAD.Geometry.Vector3d vector) => new(vector.X, vector.Y, vector.Z);
}
@@ -29,11 +29,21 @@ internal sealed class PlantConnectorRelationshipReader(DataLinksManager dataLink
var firstGroups = dataLinks.GetRelatedRowIds("P3dLineGroupPartRelationship", "Part", firstPart, "LineGroup");
var secondGroups = dataLinks.GetRelatedRowIds("P3dLineGroupPartRelationship", "Part", secondPart, "LineGroup");
if (firstGroups.Count != 1 || secondGroups.Count != 1) continue;
result.Add(new($"pnp-connector:{connector}", connector, firstPart, secondPart, firstGroups.First(), secondGroups.First(), Array.Empty<string>()));
result.Add(new($"pnp-connector:{connector}", connector, firstPart, secondPart, firstGroups.First(), secondGroups.First(), Array.Empty<string>(), TryEntityStableId(row)));
}
return new(true, result.OrderBy(value => value.StableId, StringComparer.Ordinal).ToArray());
}
catch (DLException) { return new(false, Array.Empty<PlantConnectorRelationshipSnapshot>(), "CONNECTOR_DATALINKS_READ_FAILED"); }
catch (Exception) { return new(false, Array.Empty<PlantConnectorRelationshipSnapshot>(), "CONNECTOR_RELATIONSHIP_READ_FAILED"); }
}
private static string? TryEntityStableId(dynamic row)
{
try
{
var handle = Convert.ToInt64(row["DwgHandleLow"], System.Globalization.CultureInfo.InvariantCulture);
return handle > 0 ? $"acad:{handle:X}" : null;
}
catch { return null; }
}
}