feat: add p-rec-annot Plant component geometry adapter

This commit is contained in:
codex
2026-08-07 09:22:16 +03:00
parent 95ae9dfd18
commit 43c9e42b5b
4 changed files with 90 additions and 0 deletions
@@ -0,0 +1,60 @@
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.ProcessPower.PnP3dObjects;
using PRecAnnot.Abstractions;
namespace PRecAnnot.Plant3D2026;
// Modern Plant 2026 adapter for the production-useful part of legacy
// GetComponentGeometry.IsGeometryRead: Pipe dimensions and Part extents are
// read from the selected source object with explicit unit normalisation.
internal sealed class PlantComponentGeometryReader(Database database) : IPlantComponentGeometryReader
{
public ComponentGeometryReadResult Read(string stableEntityId, bool convertToMetric)
{
if (!TryObjectId(stableEntityId, out var id)) return new(false, null, "COMPONENT_GEOMETRY_STABLE_ID_INVALID");
try
{
using var transaction = database.TransactionManager.StartOpenCloseTransaction();
if (transaction.GetObject(id, OpenMode.ForRead) is not Entity entity) return new(false, null, "COMPONENT_GEOMETRY_ENTITY_NOT_FOUND");
var extents = entity.GeometricExtents;
var bounds = new Bounds3Dto(new(extents.MinPoint.X, extents.MinPoint.Y, extents.MinPoint.Z), new(extents.MaxPoint.X, extents.MaxPoint.Y, extents.MaxPoint.Z));
if (entity is Pipe pipe)
{
var factor = Factor(convertToMetric, pipe.PartSizeProperties.LinearUnit);
var parameters = new Dictionary<string, string>(StringComparer.Ordinal)
{
["D"] = Format(pipe.OuterDiameter * factor),
["L"] = Format(pipe.Length * factor)
};
return new(true, new("CPP", parameters, bounds, factor != 1));
}
if (entity is Part part)
{
var factor = Factor(convertToMetric, part.PartSizeProperties.LinearUnit);
var parameters = new Dictionary<string, string>(StringComparer.Ordinal)
{
["BoundsX"] = Format((extents.MaxPoint.X - extents.MinPoint.X) * factor),
["BoundsY"] = Format((extents.MaxPoint.Y - extents.MinPoint.Y) * factor),
["BoundsZ"] = Format((extents.MaxPoint.Z - extents.MinPoint.Z) * factor)
};
return new(true, new("PART", parameters, bounds, factor != 1));
}
return new(false, null, "COMPONENT_GEOMETRY_UNSUPPORTED_ENTITY");
}
catch (Autodesk.AutoCAD.Runtime.Exception) { return new(false, null, "COMPONENT_GEOMETRY_EXTENTS_UNAVAILABLE"); }
catch (Exception) { return new(false, null, "COMPONENT_GEOMETRY_READ_FAILED"); }
}
private bool TryObjectId(string stableEntityId, out ObjectId id)
{
id = ObjectId.Null;
const string prefix = "acad:";
if (string.IsNullOrWhiteSpace(stableEntityId) || !stableEntityId.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) return false;
if (!long.TryParse(stableEntityId[prefix.Length..], System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out var handle)) return false;
try { id = database.GetObjectId(false, new Handle(handle), 0); return !id.IsNull; }
catch { return false; }
}
private static double Factor(bool convertToMetric, object? unit) => convertToMetric && string.Equals(unit?.ToString(), "Inch", StringComparison.OrdinalIgnoreCase) ? 25.4 : 1d;
private static string Format(double value) => value.ToString("0.###############", System.Globalization.CultureInfo.InvariantCulture);
}