feat: bridge settings assets and define fixture matrix
This commit is contained in:
@@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"policy": "controlled-local-only; fail-closed on ambiguous identity; no production DWG/project writes",
|
||||||
|
"fixtures": [
|
||||||
|
{
|
||||||
|
"id": "LINE_NUMBER_ORTHO_OWNED",
|
||||||
|
"requiredDocument": "controlled Plant Ortho DWG copy",
|
||||||
|
"requiredObjects": ["Pipe with DataLinks line number", "owned line-number block", "legacy layers/text styles"],
|
||||||
|
"selection": "exact owned block handle discovered from drawing",
|
||||||
|
"preState": "owned annotation baseline and unchanged Plant source",
|
||||||
|
"mutation": "create/update/delete line annotation",
|
||||||
|
"repeat": "update or AlreadyExists according to command",
|
||||||
|
"undo": "native AutoCAD UNDO restores entity and ownership baseline",
|
||||||
|
"workflows": ["PXP-LN", "PXP-ULN", "PXP-ESN", "PXP-ELN", "PXP-RMP"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "CONNECTOR_TOPOLOGY",
|
||||||
|
"requiredDocument": "controlled Plant project and Ortho copy",
|
||||||
|
"requiredObjects": ["two connected Plant parts", "connector/port snapshot", "P3dPartConnection", "line-group relationships"],
|
||||||
|
"selection": "exact connector source identity; no arbitrary entity fallback",
|
||||||
|
"preState": "no owned connection annotation",
|
||||||
|
"mutation": "orthogonal connection leader and ownership XData",
|
||||||
|
"repeat": "recreate/update without duplicate ownership",
|
||||||
|
"undo": "native AutoCAD UNDO restores pre-annotation state",
|
||||||
|
"workflows": ["PXP-ALC"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ELEVATION_GOLDEN",
|
||||||
|
"requiredDocument": "controlled Plant model plus paper/model context",
|
||||||
|
"requiredObjects": ["positive, negative and zero elevations", "BLOCK_ELEVATION definition", "attribute definitions"],
|
||||||
|
"selection": "exact Plant source object handle",
|
||||||
|
"preState": "source object and annotation baseline",
|
||||||
|
"mutation": "legacy /5, AwayFromZero, *5 elevation annotation",
|
||||||
|
"repeat": "update existing owned annotation",
|
||||||
|
"undo": "native AutoCAD UNDO restores baseline",
|
||||||
|
"workflows": ["PXP-AE", "PXP-IE"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ORTHO_VIEWPORT_EXACT",
|
||||||
|
"requiredDocument": "controlled Plant Ortho DWG with one-to-one source view mapping",
|
||||||
|
"requiredObjects": ["exact viewport handle/ObjectId", "layout membership", "Ortho view identity", "visible Plant candidates"],
|
||||||
|
"selection": "validated AcDbViewport handle and expected Ortho mapping",
|
||||||
|
"preState": "viewport and annotation baseline",
|
||||||
|
"mutation": "view annotation/viewport maintenance operation",
|
||||||
|
"repeat": "deterministic update/no duplicate",
|
||||||
|
"undo": "native AutoCAD UNDO restores viewport/entity baseline",
|
||||||
|
"workflows": ["PXP-AAV", "PXP-COV", "PXP-UOB", "PXP-DJ"],
|
||||||
|
"status": "EXACT_VIEWPORT_FIXTURE_BLOCKED"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "MANUAL_TEMPLATE_EDIT",
|
||||||
|
"requiredDocument": "controlled local Template-derived drawing",
|
||||||
|
"requiredObjects": ["manual annotation blocks", "attributes", "dynamic properties", "required layers/styles", "owned P_REC_ANNOT_MANUAL XData"],
|
||||||
|
"selection": "exact owned annotation handle for edit/reopen",
|
||||||
|
"preState": "palette state and owned annotation baseline",
|
||||||
|
"mutation": "manual insert/update/attribute persistence",
|
||||||
|
"repeat": "restore and update existing owned annotation",
|
||||||
|
"undo": "native AutoCAD UNDO restores entity and manual-state baseline",
|
||||||
|
"workflows": ["mto-ma", "PXP-MA", "CAC", "CAC1", "BJ", "PXP-MAB", "PXP-AC"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ORTHO_BATCH_SAME_NAME",
|
||||||
|
"requiredDocument": "controlled project copy with two relative drawing paths",
|
||||||
|
"requiredObjects": ["same filename in different project-relative directories", "one failing controlled drawing"],
|
||||||
|
"selection": "project-relative identity, never filename-only",
|
||||||
|
"preState": "unchanged controlled copies",
|
||||||
|
"mutation": "per-drawing update with continue-on-error",
|
||||||
|
"repeat": "deterministic ordering and idempotent result",
|
||||||
|
"undo": "per-drawing recovery/cleanup",
|
||||||
|
"workflows": ["PXP-IOD"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
using PRecAnnot.Abstractions;
|
||||||
|
|
||||||
namespace PRecAnnot.Core;
|
namespace PRecAnnot.Core;
|
||||||
|
|
||||||
@@ -21,6 +22,18 @@ public sealed record ProductionSettingsContract(
|
|||||||
LineNumberMarkerSettings? LineNumberMarker,
|
LineNumberMarkerSettings? LineNumberMarker,
|
||||||
SupportTopViewSettings? SupportTopView)
|
SupportTopViewSettings? SupportTopView)
|
||||||
{
|
{
|
||||||
|
public LineNumberMarkerAsset? ToLineNumberMarkerAsset()
|
||||||
|
{
|
||||||
|
if (LineNumberMarker is null) return null;
|
||||||
|
var texts = LineNumberMarker.Text is { } text
|
||||||
|
? new[] { new LineNumberTextAsset(text.Layer ?? string.Empty, text.TextStyle ?? string.Empty, text.Size ?? 0, text.TextValue ?? string.Empty, new(text.PositionX ?? 0, text.PositionY ?? 0)) }
|
||||||
|
: Array.Empty<LineNumberTextAsset>();
|
||||||
|
var lines = LineNumberMarker.Line is { } line
|
||||||
|
? new[] { new LineNumberLineAsset(line.Layer ?? string.Empty, new(line.StartX ?? 0, line.StartY ?? 0), new(line.EndX ?? 0, line.EndY ?? 0)) }
|
||||||
|
: Array.Empty<LineNumberLineAsset>();
|
||||||
|
return new(LineNumberMarker.Layer, LineNumberMarker.MaskScaleFactor ?? 0, texts, lines);
|
||||||
|
}
|
||||||
|
|
||||||
public static ProductionSettingsContract Parse(string xml)
|
public static ProductionSettingsContract Parse(string xml)
|
||||||
{
|
{
|
||||||
var root = XElement.Parse(xml, LoadOptions.PreserveWhitespace);
|
var root = XElement.Parse(xml, LoadOptions.PreserveWhitespace);
|
||||||
@@ -104,5 +117,13 @@ public sealed record LayerSetupRule(string FilterType, string FilterValue, int?
|
|||||||
public sealed record LineNumberMarkerSettings(string Layer, double? MaskScaleFactor, LineGeometrySettings? Line, TextAnnotationSettings? Text);
|
public sealed record LineNumberMarkerSettings(string Layer, double? MaskScaleFactor, LineGeometrySettings? Line, TextAnnotationSettings? Text);
|
||||||
public sealed record LineGeometrySettings(double? StartX, double? StartY, double? EndX, double? EndY, string? Layer);
|
public sealed record LineGeometrySettings(double? StartX, double? StartY, double? EndX, double? EndY, string? Layer);
|
||||||
public sealed record TextAnnotationSettings(string? Layer, string? TextStyle, double? Size, string? TextValue, double? PositionX, double? PositionY);
|
public sealed record TextAnnotationSettings(string? Layer, string? TextStyle, double? Size, string? TextValue, double? PositionX, double? PositionY);
|
||||||
public sealed record SupportTopViewSettings(string? UndefinedSize, IReadOnlyList<SupportRule> Rules);
|
public sealed record SupportTopViewSettings(string? UndefinedSize, IReadOnlyList<SupportRule> Rules)
|
||||||
|
{
|
||||||
|
public SupportRule? Resolve(double nominalDiameter, string nominalUnit, string? selectionValue = null) => Rules
|
||||||
|
.Where(rule => rule.NominalDiameter is not null && Math.Abs(rule.NominalDiameter.Value - nominalDiameter) < 0.0001)
|
||||||
|
.Where(rule => string.Equals(rule.NominalUnit, nominalUnit, StringComparison.OrdinalIgnoreCase))
|
||||||
|
.Where(rule => selectionValue is null || string.Equals(rule.SelectionValue, selectionValue, StringComparison.Ordinal))
|
||||||
|
.OrderBy(rule => rule.LastDigit ?? int.MaxValue)
|
||||||
|
.FirstOrDefault();
|
||||||
|
}
|
||||||
public sealed record SupportRule(string ScriptName, double? NominalDiameter, string? NominalUnit, int? LastDigit, double? Scale, string? SelectionValue);
|
public sealed record SupportRule(string ScriptName, double? NominalDiameter, string? NominalUnit, int? LastDigit, double? Scale, string? SelectionValue);
|
||||||
|
|||||||
@@ -65,5 +65,16 @@ public sealed class ProductionSettingsContractTests
|
|||||||
Assert.Equal(50.0, rule.NominalDiameter);
|
Assert.Equal(50.0, rule.NominalDiameter);
|
||||||
Assert.Equal(0.04, rule.Scale);
|
Assert.Equal(0.04, rule.Scale);
|
||||||
Assert.Equal("DN50", rule.SelectionValue);
|
Assert.Equal("DN50", rule.SelectionValue);
|
||||||
|
Assert.Same(rule, result.SupportTopView.Resolve(50, "mm", "DN50"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void BridgesTypedMarkerIntoProductionAsset()
|
||||||
|
{
|
||||||
|
const string xml = "<Main><CopyMissingObjects/><LayersSetup/><Annotations layer='TEXT' textstyle='GOSTC' multileaderstyle='PXP'/><LinenumberConnections polylinelayer='AXIS' textlayer='TEXT' textstyle='GOSTC'/><Elevations layer='THIN' textstyle='GOSTC'/><LineNumbers><Marker layer='DIM' maskscalefactor='1,10'><Line layer='DIM' startx='-1,0607' starty='-1,0607' endx='1,0607' endy='1,0607'/><Text layer='TEXT' textstyle='GOSTC' size='2,5' textvalue='' positionx='-4.0' positiony='4.4'/></Marker></LineNumbers><SetLayer name='AXIS'/></Main>";
|
||||||
|
var asset = ProductionSettingsContract.Parse(xml).ToLineNumberMarkerAsset();
|
||||||
|
Assert.NotNull(asset);
|
||||||
|
Assert.Equal("DIM", asset!.Layer);
|
||||||
|
Assert.Equal(-1.0607, asset.Lines[0].Start.X);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user