feat: resolve Ortho views to source model drawings

This commit is contained in:
codex
2026-08-03 08:16:11 +03:00
parent 6fa3af6eda
commit 95dba856c8
4 changed files with 167 additions and 4 deletions
@@ -1,6 +1,7 @@
using System.Security.Cryptography;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.ProcessPower.DataLinks;
using Autodesk.ProcessPower.P3dProjectParts;
using Autodesk.ProcessPower.PlantInstance;
@@ -130,7 +131,7 @@ internal sealed class PlantOrthoViewportReader : IOrthoViewportReader
TwistAngle = 0,
IsOn = true,
IsLocked = false,
SourceDrawingName = sheet.DwgName,
SourceDrawingName = ReadSourceDrawingPath(view),
ViewName = view.ViewName
});
}
@@ -149,6 +150,26 @@ internal sealed class PlantOrthoViewportReader : IOrthoViewportReader
var hash = SHA256.HashData(Encoding.UTF8.GetBytes(sheetId + "|" + viewName));
return "vp-" + Convert.ToHexString(hash)[..20];
}
private static string? ReadSourceDrawingPath(object view)
{
// The Plant 3D 2026 view definition owns a DwgQuery. Its ModelFiles are
// the authoritative source-model references; sheet.DwgName is the Ortho
// sheet and must not be used for Piping DataLinks.
try
{
var query = view.GetType().GetProperty("DwgQuery")?.GetValue(view);
var files = query?.GetType().GetProperty("ModelFiles")?.GetValue(query) as System.Collections.IEnumerable;
if (files is null) return null;
foreach (var file in files)
{
var value = file?.GetType().GetProperty("Value")?.GetValue(file)?.ToString();
if (!string.IsNullOrWhiteSpace(value)) return value;
}
}
catch { }
return null;
}
}
internal sealed class PlantObjectReader : IPlantObjectReader
@@ -156,17 +177,22 @@ internal sealed class PlantObjectReader : IPlantObjectReader
public IReadOnlyList<PlantObjectSnapshot> ReadObjects(OrthoViewportInfo viewport, CancellationToken cancellationToken)
{
var document = AcadApplication.DocumentManager.MdiActiveDocument;
if (document is null) return Array.Empty<PlantObjectSnapshot>();
if (document is null || string.IsNullOrWhiteSpace(viewport.SourceDrawingName)) return Array.Empty<PlantObjectSnapshot>();
DataLinksManager? dataLinks;
try { dataLinks = PlantApplication.ProjectPart("Piping")?.DataLinksManager; }
catch { return Array.Empty<PlantObjectSnapshot>(); }
if (dataLinks is null) return Array.Empty<PlantObjectSnapshot>();
if (!Path.IsPathRooted(viewport.SourceDrawingName) || !File.Exists(viewport.SourceDrawingName)) return Array.Empty<PlantObjectSnapshot>();
var snapshots = new List<PlantObjectSnapshot>();
try
{
foreach (var rowId in dataLinks.SelectAcPpRowIds(document.Database))
using var sourceDatabase = new Database(false, true);
sourceDatabase.ReadDwgFile(viewport.SourceDrawingName, FileShare.ReadWrite, true, null);
sourceDatabase.CloseInput(true);
foreach (var rowId in dataLinks.SelectAcPpRowIds(sourceDatabase))
{
try
{
@@ -178,7 +204,7 @@ internal sealed class PlantObjectReader : IPlantObjectReader
string? Value(params string[] names) => properties.FirstOrDefault(x => names.Any(name => string.Equals(name, x.Key, StringComparison.OrdinalIgnoreCase))).Value;
snapshots.Add(new PlantObjectSnapshot
{
SnapshotId = StableId(Path.GetFileName(document.Name), rowId, className),
SnapshotId = StableId(viewport.SourceDrawingName, rowId, className),
ObjectClass = className ?? string.Empty,
Tag = Value("Tag", "TAG"),
LineNumber = Value("Line Number", "LineNumber", "LINENUMBER"),