Skip to content

feat(migrate): lay out migrated views from an MTIP export with -layout - #538

Merged
HuiJun merged 7 commits into
developfrom
feature/mtip-layout-augment
Sep 23, 2026
Merged

HuiJun merged 7 commits into
developfrom
feature/mtip-layout-augment

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

What and why

sysml <model>.mdzip -convert sysml -layout <mtip-export.xml> lays out the views a SysML v1 migration writes from the diagram geometry an MTIP (HUDS XML) export of the same project records. The XMI carries no diagram geometry, so migrated views were auto-laid-out and the arrangement an engineer settled on was lost; the export holds exactly that layer. It is read as an augment, never as a second model input: the .mdzip/.xmi stays the one source of structure and behavior.

  • New package internal/translate/mtip: a streaming encoding/xml reader that keeps the packet's metadata and its diagram records (those with relationships/element or relationships/diagramConnector) and ignores every model record. Placements are transformed on read — Cameo stores y negated, so x = left, y = -top, width = right - left, height = top - bottom gives y-down pixels from the top left; negative values are written as-is. Connector waypoints are emitted source to target: clientPoint, breakpoints reversed, supplierPoint. Malformed placements/connectors are recorded per record, not fatal; unknown relationship_metadata tags (colors, fonts, images) are counted by tag and dropped.
  • migrate.Options{Layout, LayoutSource}, MigrateOptions and FromModelOptions; Migrate/FromModel are zero-option wrappers. Diagram records join sysmlv1.Diagram.ID by the record id (the xmi:id). An export with diagram records none of which joins is refused: <layout>: none of its N diagram records matches a diagram of <model>; the layout file was exported from a different project.
  • writeView writes, after the expose lines, @DiagramLayout::Canvas { unit = "px"; … } sized by the bounding box of what is written, metadata DiagramLayout::Layout about <ref> { x; y; width; height; } and metadata DiagramLayout::Route about <ref> { points = (…); }$::DiagramLayout:: where a member shadows the library, like Views::. Geometry is written only for what the view exposes: a placement whose element resolves and whose reference is one of the view's exposes, a route whose connector has an exposable name. Everything else is counted. To make a named connector exposable, written() now treats a named Connector whose ends resolve as a member (an anonymous connect a to b; still is not); this changes no existing golden and the TMT migration without -layout is byte-identical before and after.
  • Report: Report.Layout *LayoutSummary (records, joined, unmatched, views without layout, placements/routes written / not exposed / dangling, malformed, unsupported by tag), a ## layout section in the text report, the JSON field, a clause appended to Summary(), each laid-out diagram's own note extended, and an unmapped Layout row per unmatched record (matching no diagram, or a diagram the migration writes no view for), and per malformed record. Joined is counted in the write path, so joined + unmatched always equals the record count; non-finite bounds and a diagram record without <id> are malformed, never written.
  • CLI: -layout FILE, validated like -migration-report (XMI/.mdzip input only; may not name the model, -o, the report or the results; requires -convert). convert.Migrate takes migrate.Options; all callers migrated. Usage, the man page, the migration reference (a "Layout from an MTIP export" subsection), the roadmap paragraph and a changelog fragment are updated.

Measured on the OpenMBEE TMT model (TMT.mdzip) with its MTIP export (2022x v1.0.0, Cameo 2022x Refresh2), neither committed:

diagrams 721, joined 721, unmatched 0, views without layout 625 (of 1346)
placements 10374: written 4196, not exposed 6020, dangling 158
routes     4792: written 9,    not exposed 4783, dangling 0
malformed 0, unsupported {}

laid out 721 of 1346 diagrams from TMT_mtip.xml: 4,196 elements positioned, 9 connectors routed. The 625 uncovered views are export scope (Sandbox, profiles, document packages). The exposed-only rule is what leaves 6,020 placements and 4,783 routes unwritten: activity and state nodes, states written inside bodies and table rows have no exposable name — naming them so a view can expose them is the follow-up the roadmap paragraph names, not part of this change.

Specification basis

Presentation only: the DiagramLayout standard library package (docs/project/diagram-layout-annotations.md) already defines Layout, Route and Canvas; this writes them. No row of docs/project/spec-compliance.md moves.

How it was verified

  • internal/translate/mtip unit tests: bound transform, route order with 0/1/2 breakpoints and an absent breakPoint, malformed records recorded not fatal, unsupported tags counted, non-diagram records ignored, metadata read, ill-formed XML fails with a position.
  • tests/migrate: new layout.xmi + layout.layout.xml pair (BDD and IBD, a shown-but-unexposed element, a dangling id, a connector of an unwritten element, a record matching no diagram, a malformed placement, an unsupported fillColor) with notation and report goldens, analysed clean; the fixture is also pinned without -layout. Byte-identity of MigrateOptions(…, Options{}) against Migrate for every existing fixture; the project-mismatch error; an opt-in tests/migrate/tmt_layout_test.go gate (OPENSYSML_TMT_MDZIP, OPENSYSML_TMT_MTIP) asserting 721 joined, 0 unmatched, 0 malformed, clean analysis — run locally with the pair above.
  • cmd/sysml: -layout validation tests beside the -migration-report ones and an end-to-end run on the fixture pair.
  • Every existing golden under tests/migrate/testdata/xmi is untouched. go build ./..., go vet ./..., gofmt -l . (empty), go test ./... with the corpus require variables set and the corpora downloaded, make lint, make man-check, python3 scripts/changelog.py check, check-doc-links.py, check-doc-ids.py all pass.

Checklist

  • make test and make lint pass locally
  • Tests added or updated for the change
  • Documentation extended where it already covers the surface (see CONTRIBUTING.md)
  • Changelog entry added as changes/unreleased/<slug>.<section>.md, not as an edit to CHANGELOG.md
  • baselines regenerated and make docs-counts run if a gate count moved (compliance rows need nothing: the census is counted at docs build)
  • No internal work-item labels (waves, slices, F4, K5) in the body, docs, or changelog

devin-ai-integration Bot and others added 5 commits September 22, 2026 22:09
A Cameo/MagicDraw export's XMI does not carry its diagrams' geometry;
Open-MBEE's MTIP plugin writes that layer into its HUDS XML. The new
internal/translate/mtip package parses the export's diagram records
(placements, connector routes, unsupported presentation properties,
malformed records), and migrate.Options now carries the parsed export:
MigrateOptions/FromModelOptions join each record to a migrated diagram
by element identifier and write its geometry into the view usages as
DiagramLayout metadata — Layout per exposed element, Route per exposed
connector, Canvas sized by what was written — while counting what the
view does not expose, what resolves to no element, and each unmatched
or malformed record in a LayoutSummary on the report. A layout that
joins no diagram of the model is refused as exported from a different
project; without it the migration is byte-identical to before.

A named connector whose ends resolve is a referable member and so is
exposable in a view, which is what routes its geometry.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
-laug accompanies -convert (XMI input only, validated like
-migration-report); the export is parsed and handed to the migration
as an augment, and its summary is printed with the migration's.
Usage, the -convert paragraph and the generated manual cover it.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
layout.xmi + layout.layout.xml exercise placements, connector routes
with breakpoints, unexposed and dangling references, a malformed
record, an unsupported property and an unmatched diagram record;
golden and report files pin the emitted geometry, a zero-Options run
matches Migrate byte-for-byte, a foreign-project layout is refused,
the summary counts are asserted, and an opt-in gate over a real
model/MTIP pair (OPENSYSML_TMT_MDZIP/OPENSYSML_TMT_MTIP) joins all
721 records cleanly. cmd/sysml gains flag-validation cases and an
end-to-end -layout conversion; the layering table assigns mtip.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
The migration reference gains a 'Layout from an MTIP export' section —
the join, the coordinate transform, the exposed-only rule and the
report fields — the roadmap marks the item landed with the real-pair
join confirmed and the unexposed-element follow-up noted, and a
changelog fragment describes -layout.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration
devin-ai-integration Bot marked this pull request as ready for review September 22, 2026 22:57
devin-ai-integration[bot]

This comment was marked as resolved.

…TIP reader

A diagram record with no <id> panicked the reader; it is kept now with
the missing id recorded as malformed, and a bound or coordinate that
parses to NaN or an infinity is malformed rather than an invalid token
written into a view.

A record matching a diagram the migration does not write as a view —
its host written without a body — was counted as laid out while its
geometry vanished. DiagramsJoined is counted where a written view
consumes the record, an unwritten-view match is a Layout row saying so
and counts as unmatched, and joined + unmatched always equals the
record count.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

Any well-formed XML parsed as an empty export, so a wrong -layout file
silently disabled layout. Parse now requires the root element to be
<packet> and refuses a document with no root element at all; a real
packet with metadata and no diagram records stays a valid export.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@HuiJun
HuiJun merged commit 7024e4b into develop Sep 23, 2026
15 checks passed
@HuiJun
HuiJun deleted the feature/mtip-layout-augment branch September 23, 2026 01:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant