Skip to the content.

Engineering diagram document and sheet model

NeqSim can project one canonical process topology into an immutable controlled-document proposal. The document model is separate from process execution scheduling and from every renderer or exchange format. It is the shared semantic layer for native SVG/PDF PFD drawing sets and the existing DEXPI/Proteus P&ID workflow.

The initial model provides:

The automatic partition remains deliberately conservative. It does not choose sheet sizes, grids, symbols, legends, or title-block geometry. Manual layout intent is supplied separately through an EngineeringDiagramLayoutRegister; it is never hidden in the process execution graph.

Content profiles

ContentProfile controls only drawing and sheet membership. getSemanticObjects() always retains the complete canonical model with the same stable identities, properties, units, provenance, and connections, regardless of the selected profile.

Profile Drawing-view content Deliberate omissions
BFD Areas, equipment blocks, boundaries, material ports/nozzles, and material connections Controlled line detail, energy connections, instrumentation, and signal connections
PFD Areas, equipment, boundaries, controlled lines, material and energy ports/connections Instrumentation and signal ports/connections
PID Every visual semantic object currently represented by the canonical model None at the content-policy layer; source-adapter losses remain diagnostic

Parallel material connections remain distinct in all three profiles. Multi-area off-page connector pairs are created only for connections visible in the selected profile, so a BFD does not acquire energy or signal cross-sheet references and a PFD does not acquire signal references. Manual sheet, pinned-position, or protected-route evidence targeting an omitted object is retained in its source register but reported as DIAGRAM_CONTENT_PROFILE_LAYOUT_OMITTED rather than silently changing the profile.

Every document set records DIAGRAM_CONTENT_PROFILE_PROPOSAL_ONLY, and each omitted visual object records DIAGRAM_CONTENT_PROFILE_OBJECT_OMITTED. These are loss/projection diagnostics, not errors; the omitted objects remain available in the canonical semantic snapshot and to other drawing or exchange projections.

The default BFD policy treats current unit operations as conservative functional blocks; it does not infer or aggregate licensed-standard process blocks. The PFD and P&ID policies likewise do not qualify symbols, content, layout, measurement/control conventions, or drawing practice. None of the three profiles claims ISO 10628, ISO 14617, ISA, or project-standard conformance or engineering approval.

Declared BFD aggregation

For explicitly declared process sections, use EngineeringBlockFlowProjection.fromGraph(graph, sectionByOwnerId) before creating the BFD document. Assignments use exact canonical equipment or boundary-stream owner IDs. Unassigned owners stay visible. The projection retains separate material directions, product branches and inter-section returns. Each displayed aggregate connection contains sourceConnectionIds; each block contains sourceOwnerIds and internalConnectionIds. Together these lists account for every original material connection exactly once. Unknown assignments and unresolved material endpoints fail instead of losing a flow. toGraph() returns an independent graph snapshot, and toJson() retains the complete mapping. Section membership never creates a connection.

Material-block rectangles use 4.2 mm label fonts and connection-facing ports, with separate return routes below the main flow. These dimensions are schematic, not vessel dimensions or flow-dependent equipment sizing. Symbol conventions below continue to apply to the ordinary equipment views.

Project symbol conventions

EngineeringDiagramConventionRegister provides an opt-in, immutable project input for native SVG/PDF symbol selection. A convention maps one canonical EngineeringNode.Kind to one of the renderer-native generic vector shapes (RECTANGLE, DIAMOND, or HEXAGON), explicit #RRGGBB stroke/fill colours, source/revision metadata, and a PROPOSED or REVIEWED evidence state. Reviewed entries require reviewer and review-record references; they still do not approve a generated drawing for design or construction.

Two additional opt-in proposal shapes support process reviews without claiming a qualified symbol catalog. PROCESS_EQUIPMENT selects deterministic separator, heat-exchanger, compressor, pump, valve, mixer, splitter, and simulator-recycle families from the canonical javaClass property. LINE_TERMINAL makes canonical LINE objects visible as directional terminal symbols. Unknown equipment classes retain the labelled equipment fallback. These families are renderer-native visual language only; project or standards qualification still requires the traceability and review evidence described below.

Pass the register to NativeEngineeringDiagramRenderer through the additive constructor overloads. An empty register retains byte-compatible legacy rectangle rendering. Once a non-empty register is selected, every visible drawable node kind without an exact convention continues to render with the legacy rectangle and records DIAGRAM_RENDER_SYMBOL_FALLBACK. Proposed mappings record DIAGRAM_RENDER_SYMBOL_CONVENTION_PROPOSAL. Both diagnostics are deterministic and retain the canonical semantic object identity as their subject.

The generic shapes are intentionally project-configurable primitives, not a qualified standards catalog. They do not claim ISO 10628, ISO 14617, ISA, company-standard, or project-standard conformance. Standards-aligned mappings require licensed clause/symbol traceability, versioned fixtures, accountable discipline review, and separate qualification evidence. Existing Classic DOT/Graphviz, controlled-document JSON, DEXPI 2.0, and Proteus/P&ID outputs do not consume this register and remain unchanged.

Fixed-port orthogonal routing

Native rendering retains RoutingMode.LEGACY_CENTER by default. Its center-to-center geometry and font scale are unchanged; both modes now remove duplicate continuation views and order pages by controlled sheet number. Select RoutingMode.FIXED_PORT_ORTHOGONAL through the additive renderer constructors when a controlled drawing view needs explicit canonical port geometry:

NativeEngineeringDiagramRenderer renderer =
    new NativeEngineeringDiagramRenderer(
        documents, NativeEngineeringDiagramRenderer.RoutingMode.FIXED_PORT_ORTHOGONAL);
NativeEngineeringDiagramRenderer.Result result = renderer.render();

The opt-in mode resolves each connection’s stable sourceEndpointId and targetEndpointId, anchors the corresponding port/nozzle at its owner-symbol bound, and exposes the endpoint identity on the SVG port marker. Port slots are sorted by stable identity. Branches therefore retain distinct anchors, connections between the same owner pair receive deterministic parallel lanes, and declared recycle or backward connections receive a deterministic orthogonal return path. Reciprocal off-page connectors remain the cross-sheet boundary. Their lanes follow the local canonical endpoint where space permits and retain deterministic minimum separation when several continuations share one sheet edge. Connection labels are selected from horizontal route segments using deterministic object- and label-collision scoring instead of being placed on a shared vertical trunk. For an unprotected connection, automatic routing evaluates the direct orthogonal path and deterministic page channels. Routes first leave/approach the actual nozzle side, including on reverse-flow rows. Selection penalizes border violations and all object-envelope intersections (including endpoint interiors), then shared track length, label collisions and route length. Endpoint boundary contact is allowed; traversing the endpoint interior is diagnosed. A reviewed protected route remains authoritative and is never replaced by automatic routing. Each fixed-port route also carries a deterministic vector arrowhead in SVG and PDF. When the opt-in LINE_TERMINAL convention is present, each visible off-page label combines the canonical connection designation, directional TO or FROM, and the controlled peer-sheet number. Stable connector and peer-sheet identities remain in the document model and SVG semantic attributes without being exposed as reader-facing drawing text. Long line-terminal identities remain complete and are reduced only as far as 2.2 mm text to fit inside the fixed vector symbol; the renderer never truncates or substitutes a machine identifier. Fixed-port PDF fonts now retain the declared SVG font size in paper units (mm * 72 / 25.4 points), without the previous implicit 22 percent reduction. Legacy-center PDF font scaling is unchanged.

An endpoint may explicitly set diagramPortSide to NORTH, EAST, SOUTH or WEST before document projection. NativeEngineeringDiagramRenderer.PortSide enumerates these exact values. North is upwards in paper coordinates. Undeclared ordinary process endpoints keep east-facing outlets and west-facing inlets. Invalid declarations produce DIAGRAM_RENDER_INVALID_PORT_SIDE and fail the render-completeness gate. This constraint controls attachment geometry; it does not rotate the equipment symbol or establish a reviewed nozzle location.

DIAGRAM_RENDER_FIXED_PORT_UNRESOLVED reports a malformed endpoint that cannot resolve to an owner. A valid peer owner absent from an off-page connection’s current sheet is expected and does not create a false warning. Connector-lane, obstacle-aware route, and route-label placement reduce common congestion but do not suppress the renderer’s whole-sheet collision diagnostics. Fixed-port routing is deterministic proposal geometry; it is not globally obstacle-optimal, standards-qualified, or drawing-approved. Projects should retain protected routes where accountable layout refinement is required.

EngineeringDiagramLayoutRegister.SheetOverviewRegion can place a controlled detail-sheet index on another sheet using source-evidenced paper-millimetre geometry. The native renderer labels the region with the referenced sheet and its canonical equipment membership. It also marks the index as not process connectivity, so the feature cannot be mistaken for duplicated equipment or a synthesized flowsheet. Unknown/self references fail document validation and out-of-bounds regions remain visible with a structured warning.

Source-linked P&ID proposal overlay

The five-argument NativeEngineeringDiagramRenderer constructor accepts an optional EngineeringDiagramPidRegisters snapshot. A non-null snapshot must have the same canonical source graph fingerprint as the rendered document set. The renderer then adds a deterministic, review-required overlay to SVG and PDF with stable semantic identities for proposed nozzles, valves, instruments, declared isolation/drain/vent/relief interfaces, and control or safeguarding signal relationships.

Each register row receives its own symbol and full tag at its source equipment. Category-specific callout rails use stable spacing and distribute repeated connections across deterministic perimeter points on the owning equipment instead of converging on one centre point. Control/safeguarding relationships use deterministic lanes per source/target equipment pair instead of sharing one overlapping centre path. The overlay is still not a substitute for project-approved symbols, routing, data, or discipline checking. Supplying null preserves existing PFD and legacy renderer bytes. The overlay does not alter the document topology or either DEXPI exchange profile, and it does not infer pipe size, class, schedule, material, reducer duty, completed control logic, or safety design.

Java example

EngineeringDiagramDocumentSet documents =
    ProcessDiagramDocumentSetAdapter.fromProcessModel(
        processModel,
        "PLANT-01",
        "A",
        "PFD-01-001",
        "Gas processing facility",
        EngineeringDiagramDocumentSet.ContentProfile.PFD);

if (!documents.isValid()) {
  for (EngineeringDiagramDocumentSet.Diagnostic diagnostic : documents.getDiagnostics()) {
    logger.warn("{}: {}", diagnostic.getCode(), diagnostic.getMessage());
  }
}

String controlledProposalJson = documents.toJson();

Use the overload with a final operating-case ID after a successful process run to retain governed stream results in the same controlled snapshot. Temperature is stored in K, absolute pressure in bara, mass flow in kg/s, and mass-specific enthalpy in J/kg. Each value remains CALCULATED and REVIEW_REQUIRED, identifies its case and source semantic object, and includes simulation-result provenance. The topology-only overloads remain unchanged and do not read live operating values.

Governed stream-table companion

EngineeringDiagramStreamTable creates an immutable, deterministic stream-table companion from one operating-case document snapshot. It reads only canonical LINE and CALCULATION semantic objects; it does not read live process objects or add fields to EngineeringDiagramDocumentSet.toJson(). Every row retains the canonical stream ID, external key, source label, and process area. Temperature, absolute pressure, mass flow, and mass-specific enthalpy retain their explicit unit, quantity basis, engineering state, approval state, source calculation ID, and simulation-result provenance.

A reviewed STREAM_NUMBER designation is preferred as the display identifier and its source reference is retained. Without reviewed evidence, the canonical source label remains visible. Missing cases or quantities, malformed values, duplicate values, and calculation references to unknown streams are reported as structured diagnostics rather than silently invented or discarded.

EngineeringDiagramDocumentSet operatingDocuments =
    ProcessDiagramDocumentSetAdapter.fromProcessModel(
        processModel,
        "PLANT-01",
        "B",
        "PFD-01-001",
        "Gas processing facility",
        EngineeringDiagramDocumentSet.ContentProfile.PFD,
        "NORMAL-01",
        new EngineeringDiagramDesignationRegister());
EngineeringDiagramStreamTable streamTable =
    EngineeringDiagramStreamTable.fromDocumentSet(operatingDocuments, "NORMAL-01");

for (EngineeringDiagramStreamTable.Row row : streamTable.getRows()) {
  EngineeringDiagramStreamTable.Value pressure =
      row.getValues().get(EngineeringDiagramStreamTable.Quantity.PRESSURE);
  if (pressure != null) {
    logger.info("{} pressure: {} {}", row.getDisplayIdentifier(), pressure.getResultValue(),
        pressure.getResultUnit());
  }
}

Explicit-boundary mass and stream-enthalpy balances

EngineeringDiagramBalanceTable aggregates only explicit boundary assignments against a governed stream table. Each assignment records a stable balance ID, canonical stream semantic ID, inlet or outlet direction, source reference, and PROPOSED or REVIEWED evidence state. The aggregator never guesses direction from drawing topology. Unknown or duplicate assignments, missing values, wrong units or bases, negative boundary flow, non-finite results, and source-table losses remain visible as structured diagnostics.

List<EngineeringDiagramBalanceTable.Boundary> boundaries =
    Arrays.asList(
        new EngineeringDiagramBalanceTable.Boundary(
            "BAL-AREA-01",
            feedStreamId,
            EngineeringDiagramBalanceTable.Direction.INLET,
            "project-balance-register:BAL-AREA-01",
            EngineeringDiagramBalanceTable.EvidenceState.PROPOSED),
        new EngineeringDiagramBalanceTable.Boundary(
            "BAL-AREA-01",
            productStreamId,
            EngineeringDiagramBalanceTable.Direction.OUTLET,
            "project-balance-register:BAL-AREA-01",
            EngineeringDiagramBalanceTable.EvidenceState.PROPOSED));
EngineeringDiagramBalanceTable balanceTable =
    EngineeringDiagramBalanceTable.fromStreamTable(streamTable, boundaries);

For each balance, mass residual is inlet mass flow minus outlet mass flow in kg/s. Relative mass residual divides that result by the larger absolute inlet or outlet total and is zero when both totals are zero. Stream enthalpy flow is massFlow [kg/s] * specificEnthalpy [J/kg] in W; its residual is the inlet total minus the outlet total, and its relative residual uses the same larger-total denominator. It intentionally excludes equipment heat duties and shaft work, so it is not a complete energy balance.

Explicit component-resolved mass balances

EngineeringDiagramComponentBalanceTable is an additive companion to an existing explicit-boundary balance table. It binds user-supplied component mass-flow records to the same stable balance and stream identities. Every record retains the source component identity and name, explicit kg/s unit, COMPONENT_MASS basis, source reference, provenance, and PROPOSED or REVIEWED evidence state. A component requires one explicit zero or non-zero value on every declared boundary stream; missing, duplicate, unknown, non-finite, negative, wrongly based, or wrongly unitized values remain visible as structured diagnostics.

List<EngineeringDiagramComponentBalanceTable.ComponentFlow> componentFlows =
    Arrays.asList(
        new EngineeringDiagramComponentBalanceTable.ComponentFlow(
            "BAL-AREA-01",
            feedStreamId,
            "methane",
            "methane",
            8.5,
            "kg/s",
            "COMPONENT_MASS",
            "project-component-register:BAL-AREA-01",
            "simulation-case:NORMAL-01",
            EngineeringDiagramBalanceTable.EvidenceState.PROPOSED),
        new EngineeringDiagramComponentBalanceTable.ComponentFlow(
            "BAL-AREA-01",
            productStreamId,
            "methane",
            "methane",
            8.5,
            "kg/s",
            "COMPONENT_MASS",
            "project-component-register:BAL-AREA-01",
            "simulation-case:NORMAL-01",
            EngineeringDiagramBalanceTable.EvidenceState.PROPOSED));
EngineeringDiagramComponentBalanceTable componentBalances =
    EngineeringDiagramComponentBalanceTable.fromBalanceTable(balanceTable, componentFlows);

For each stable balance/component pair, the projection reports inlet and outlet component mass flow, their residual, the larger-total relative residual, declared and supplied boundary counts, and an explicit completeness flag. It does not derive composition from a live process object, infer omitted zeroes, apply tolerances, reconcile values, or close equipment heat/work terms. The sum of supplied component inlet/outlet totals is also compared with the source total-mass balance; a difference is a warning with no inferred project tolerance. This separation keeps component data provenance explicit and leaves existing stream-table, balance-table, controlled document, Classic DOT/Graphviz, native SVG/PDF, DEXPI 2.0 Process, and Proteus/P&ID outputs unchanged.

Explicit heat-transfer and shaft-work closure

EngineeringDiagramEnergyBalanceTable is an additive companion to an existing explicit-boundary balance table. It closes the source stream-enthalpy terms with explicitly declared heat-transfer and shaft-work ports. Every port retains a stable balance identity, canonical equipment or control-volume identity, distinct stable port identity, energy kind, direction relative to the control volume, source reference, and evidence state. Separate port identities preserve parallel energy connections without collapsing them.

Energy-flow values are non-negative W values on an ENERGY_RATE basis. Direction comes only from the port declaration, never from a sign convention, drawing topology, or live equipment duty. Every declared port requires one explicit zero or non-zero flow with source, provenance, and evidence state.

List<EngineeringDiagramEnergyBalanceTable.EnergyPort> energyPorts =
    Arrays.asList(
        new EngineeringDiagramEnergyBalanceTable.EnergyPort(
            "BAL-AREA-01",
            heaterSemanticObjectId,
            "energy-port:heater-duty",
            EngineeringDiagramEnergyBalanceTable.EnergyKind.HEAT_TRANSFER,
            EngineeringDiagramEnergyBalanceTable.EnergyDirection.INTO_CONTROL_VOLUME,
            "project-energy-register:BAL-AREA-01",
            EngineeringDiagramBalanceTable.EvidenceState.PROPOSED),
        new EngineeringDiagramEnergyBalanceTable.EnergyPort(
            "BAL-AREA-01",
            compressorSemanticObjectId,
            "energy-port:compressor-shaft",
            EngineeringDiagramEnergyBalanceTable.EnergyKind.SHAFT_WORK,
            EngineeringDiagramEnergyBalanceTable.EnergyDirection.INTO_CONTROL_VOLUME,
            "project-energy-register:BAL-AREA-01",
            EngineeringDiagramBalanceTable.EvidenceState.PROPOSED));
List<EngineeringDiagramEnergyBalanceTable.EnergyFlow> energyFlows =
    Arrays.asList(
        new EngineeringDiagramEnergyBalanceTable.EnergyFlow(
            "BAL-AREA-01",
            "energy-port:heater-duty",
            250000.0,
            "W",
            "ENERGY_RATE",
            "simulation-result:NORMAL-01:heater-duty",
            "simulation-case:NORMAL-01",
            EngineeringDiagramBalanceTable.EvidenceState.PROPOSED),
        new EngineeringDiagramEnergyBalanceTable.EnergyFlow(
            "BAL-AREA-01",
            "energy-port:compressor-shaft",
            125000.0,
            "W",
            "ENERGY_RATE",
            "simulation-result:NORMAL-01:compressor-power",
            "simulation-case:NORMAL-01",
            EngineeringDiagramBalanceTable.EvidenceState.PROPOSED));
EngineeringDiagramEnergyBalanceTable energyBalances =
    EngineeringDiagramEnergyBalanceTable.fromBalanceTable(
        balanceTable, energyPorts, energyFlows);

For each balance, total energy input is inlet stream enthalpy flow plus heat transfer and shaft work declared into the control volume. Total energy output is outlet stream enthalpy flow plus heat transfer and shaft work declared out of the control volume. The energy residual is total input minus total output in W; its relative residual divides by the larger absolute total and is zero when both totals are zero. A result is complete only when the source stream-enthalpy balance is complete, the balance has at least one explicit energy port, and every port has one usable flow value.

Unknown or duplicate balances, ports, and flows; missing values; non-finite or negative rates; and wrong units or bases remain visible as structured diagnostics. A zero energy rate must be recorded explicitly. The companion does not read live equipment duties, infer absent heat/work terms, apply a project tolerance, reconcile data, or approve a balance. Existing balance/component APIs, controlled-document JSON, Classic DOT/Graphviz, native SVG/PDF, DEXPI 2.0 Process, and Proteus/P&ID outputs remain unchanged.

Explicit tolerance assessment

EngineeringDiagramBalanceAssessment evaluates existing residuals against explicit, sourced criteria without changing any stream value. Each criterion identifies one stable balance and declares absolute and relative limits for mass residual (kg/s and dimensionless) and stream-enthalpy residual (W and dimensionless). A quantity is WITHIN_TOLERANCE only when both residual magnitudes satisfy their declared limits. Missing, duplicate, unknown, incomplete, or exceeded criteria remain visible through deterministic status values and structured diagnostics.

EngineeringDiagramBalanceAssessment.Criteria criteria =
    new EngineeringDiagramBalanceAssessment.Criteria(
        "BAL-AREA-01",
        0.01,
        0.001,
        1000.0,
        0.01,
        "project-balance-criteria:BAL-AREA-01",
        EngineeringDiagramBalanceTable.EvidenceState.PROPOSED);
EngineeringDiagramBalanceAssessment assessment =
    EngineeringDiagramBalanceAssessment.fromBalanceTable(
        balanceTable, Collections.singletonList(criteria));

The assessment itself is a tolerance check, not statistical data reconciliation. It does not adjust measured or calculated values, supply component balances, close heat/work terms, infer project tolerances, or approve a balance.

Tolerance-gated mass-balance reconciliation

EngineeringDiagramMassBalanceReconciliation is an additive evidence projection over the stream table, balance table, and assessment. It invokes NeqSim’s existing linear weighted-least-squares engine only for a complete mass balance classified OUTSIDE_TOLERANCE. A balance already within its declared limits is retained unchanged and needs no uncertainty declarations.

Every participating boundary stream requires a positive finite standard uncertainty in kg/s on a MASS basis, together with a source reference, provenance, and evidence state. Source fingerprints and document/graph/case identity must match. Unknown, duplicate, invalid, or missing uncertainty records; incomplete or underspecified boundaries; solver failures; negative candidates; and candidates outside the explicit criteria produce structured diagnostics.

List<EngineeringDiagramMassBalanceReconciliation.Uncertainty> uncertainties =
    Arrays.asList(
        new EngineeringDiagramMassBalanceReconciliation.Uncertainty(
            "BAL-AREA-01", inletSemanticId, 0.05, "kg/s", "MASS",
            "instrument-register:FT-101", "calibration certificate CAL-101",
            EngineeringDiagramBalanceTable.EvidenceState.REVIEWED),
        new EngineeringDiagramMassBalanceReconciliation.Uncertainty(
            "BAL-AREA-01", outletSemanticId, 0.08, "kg/s", "MASS",
            "instrument-register:FT-102", "calibration certificate CAL-102",
            EngineeringDiagramBalanceTable.EvidenceState.REVIEWED));
EngineeringDiagramMassBalanceReconciliation reconciliation =
    EngineeringDiagramMassBalanceReconciliation.fromSources(
        streamTable, balanceTable, assessment, uncertainties);

The result contains immutable source-to-candidate adjustments, balance-level residual and statistical evidence, deterministic JSON/fingerprints, and fail-visible diagnostics. It never writes reconciled values back to a ProcessSystem, stream table, balance table, diagram, or exchange file. It does not eliminate gross errors, model covariance, reconcile component or energy balances, or turn reviewed evidence into engineering approval. Those are distinct engineering layers.

Building either companion does not change Classic DOT/Graphviz, native SVG/PDF, DEXPI 2.0 Process exchange, or the Proteus/DEXPI P&ID workflow. REVIEWED boundary or criterion evidence does not approve a PFD, P&ID, simulation result, balance, tolerance, or design data.

Canonical source names and carried connection names are retained as source designations. They are not silently promoted to project-approved equipment tags or line numbers. Project-entered tags and stream numbers require their own provenance and review state before they can supersede those source designations.

Use an EngineeringDiagramDesignationRegister when a project has reviewed designation evidence. The register targets stable semantic-object IDs and supports EQUIPMENT_TAG for equipment plus STREAM_NUMBER for line or pipe-segment objects. An invalid target or designation/object-kind combination produces a structured error and is not attached to the semantic object. The canonical source label remains available alongside the reviewed designation.

EngineeringDiagramDesignationRegister register =
    new EngineeringDiagramDesignationRegister()
        .withDesignation(
            new EngineeringDiagramDesignationRegister.Designation(
                equipmentId,
                EngineeringDiagramDesignationRegister.Kind.EQUIPMENT_TAG,
                "V-101",
                "project-register:equipment-tags",
                EngineeringDiagramDesignationRegister.ReviewState.REVIEWED,
                "Process discipline",
                "review:TAG-42",
                "2026-08-13T07:00:00Z",
                "B"));

EngineeringDiagramDocumentSet reviewedDocuments =
    ProcessDiagramDocumentSetAdapter.fromProcessModel(
        processModel,
        "PLANT-01",
        "B",
        "PFD-01-001",
        "Gas processing facility",
        EngineeringDiagramDocumentSet.ContentProfile.PFD,
        register);

Persistent manual layout intent

Use an EngineeringDiagramLayoutRegister to retain reviewed layout choices across regeneration. The register can add a stable manual sheet, assign an equipment or endpoint object to that sheet, pin an object in millimetres, and protect a connection route with ordered waypoints. Every entry records its source, evidence state, recorder, timestamp, and revision. The document adapter validates all stable IDs and produces structured errors instead of silently applying stale references.

Connection sheet membership is derived from its endpoint locations. Moving equipment also moves its owned ports and nozzles unless an endpoint has an explicit assignment. When the endpoints land on different sheets, the adapter retains one authoritative semantic connection and creates exactly two reciprocal off-page connectors. Protected route geometry is attached to each applicable sheet view; it does not create another process connection.

EngineeringDiagramLayoutRegister layout =
    new EngineeringDiagramLayoutRegister()
        .withSheet(
            new EngineeringDiagramLayoutRegister.SheetDefinition(
                "separator-detail",
                "002",
                "Separator detail",
                "project-layout-register",
                EngineeringDiagramLayoutRegister.EvidenceState.REVIEWED,
                "Process discipline",
                "2026-08-13T12:00:00Z",
                "B"))
        .withAssignment(
            new EngineeringDiagramLayoutRegister.SheetAssignment(
                separatorId,
                "separator-detail",
                "project-layout-register",
                EngineeringDiagramLayoutRegister.EvidenceState.REVIEWED,
                "Process discipline",
                "2026-08-13T12:00:00Z",
                "B"))
        .withPinnedPosition(
            new EngineeringDiagramLayoutRegister.PinnedPosition(
                separatorId,
                "separator-detail",
                180.0,
                95.0,
                EngineeringDiagramLayoutRegister.CoordinateUnit.MILLIMETRE,
                "project-layout-register",
                EngineeringDiagramLayoutRegister.EvidenceState.REVIEWED,
                "Process discipline",
                "2026-08-13T12:00:00Z",
                "B"));

EngineeringDiagramDocumentSet manuallyArranged =
    ProcessDiagramDocumentSetAdapter.fromProcessModel(
        processModel,
        "PLANT-01",
        "B",
        "PFD-01-001",
        "Gas processing facility",
        EngineeringDiagramDocumentSet.ContentProfile.PFD,
        register,
        layout);

Coordinates and waypoints are renderer-neutral proposal data. The register does not assert that a route is physically constructible, that a layout complies with a drawing standard, or that an accountable engineer has approved the result.

Deterministic native SVG/PDF rendering

NativeEngineeringDiagramRenderer projects the controlled document set directly to native SVG and PDF without Graphviz. Both formats consume the same deterministic page plan. The renderer preserves stable sheet and semantic-object IDs, positions pinned in drawing-paper millimetres, protected route waypoints, reciprocal off-page references, drawing/sheet titles, revision, status, issue purpose, and source-graph fingerprint.

NativeEngineeringDiagramRenderer.Result rendered =
    new NativeEngineeringDiagramRenderer(
            manuallyArranged,
            NativeEngineeringDiagramRenderer.SheetFormat.A3_LANDSCAPE)
        .render();

Map<String, String> svgBySheetId = rendered.getSvgBySheetId();
byte[] multiPagePdf = rendered.getPdf();
Map<String, String> visualFingerprints = rendered.getVisualFingerprintsBySheetId();
for (NativeEngineeringDiagramRenderer.Diagnostic diagnostic : rendered.getDiagnostics()) {
  logger.warn("{}: {}", diagnostic.getCode(), diagnostic.getMessage());
}

A3_LANDSCAPE and A1_LANDSCAPE provide controlled paper geometry in millimetres. They identify the paper dimensions only; they do not assert standards conformance. Unpinned objects receive a stable grid position, while out-of-bounds pinned coordinates, protected routes, and automatic layout overflow remain fail-visible through structured diagnostics. Manual geometry is retained unchanged instead of being silently repaired.

SVG output contains stable data-sheet-id, data-semantic-id, and protected-route attributes for machine inspection. Every material, energy, and information connection receives a deterministic primary label at the geometric half-length of its rendered route. PDF output is a deterministic vector drawing set with one page per controlled sheet. Use exportSvg(directory) or exportPdf(path) when files are required. Rendering does not modify the source document set, legacy DOT/Graphviz output, DEXPI 2.0 Process exchange, or the Proteus/DEXPI P&ID workflow.

getVisualFingerprintsBySheetId() exposes one normalized SHA-256 fingerprint per sheet. The fingerprint covers visible page geometry, text, and style shared by SVG and PDF while excluding XML/PDF serialization syntax and invisible semantic identifiers. Store a reviewed fingerprint as a regression baseline only together with the corresponding rendered artifacts and accountable visual review; a hash match is evidence of unchanged rendering, not evidence that the drawing is correct.

The rendering result also carries deterministic drawing-quality diagnostics. It reports overlapping object symbols, symbols clipped by the border/header/title-block boundary, primary labels estimated to exceed their available symbol width, connection routes crossing non-endpoint objects, connection labels overlapping objects or other connection labels, missing connection labels, and missing semantic-object references. Validation now also runs on the completed scene after connectors, symbols, port markers, P&ID markers/signals and title blocks have been added. The DIAGRAM_RENDER_SCENE_* diagnostics cover border clipping, estimated text/text and text/route or marker collisions, marker/process-route and marker/object intersections, and signal/object intersections. DIAGRAM_RENDER_DUPLICATE_ROUTE detects identical repeated physical-route emission; DIAGRAM_RENDER_ROUTE_ENDPOINT_INTERSECTION includes protected endpoint traversal without rewriting the protected geometry. These checks use conservative rectangles and estimated text widths, not measured glyph outlines. Crossing-versus-junction interpretation and reviewed symbol semantics still require additional qualification. Existing controlled-document diagnostics are retained in the same report, including broken reciprocal off-page pairs and stale manual layout references. Errors make Result.isComplete() false; warnings retain the proposed geometry unchanged for review. These geometric and text-width checks are conservative proposal gates, not proof of standards compliance or accountable visual approval.

Compare two revisions of the same document-set and plant identity with baseline.compareTo(revised). The returned EngineeringDiagramRevisionImpact has deterministic added, removed, and modified semantic-object IDs. It projects those changes to the sheets and drawings containing each object in either revision. A cross-sheet stream-number change therefore affects both sheets while retaining one semantic connection identity.

The adapter reuses ProcessDiagramGraphAdapter. It does not modify the source ProcessSystem or ProcessModel, and it does not change legacy toDOT(), ProcessDiagramExporter, native DEXPI 2.0, or Proteus/P&ID output.

Engineering and approval boundary

Generated document sets start with status WORKING and issue purpose ENGINEERING_PROPOSAL. They are not approved for design or construction. The model rejects approved/construction state without an explicit accountable approval reference; a simulation result cannot promote its own engineering state.

Designation and layout registers record review evidence only. They do not represent engineering approval, do not authorize a P&ID or PFD for design or construction, and do not replace project ownership of piping, valve, nozzle, instrument, safeguard, routing, or design data.

The document model and native renderer do not claim ISO 10628, ISO 5457, ISO 7200, ISO 14617, ISA, DEXPI EV, or commercial CAE conformance. Licensed standards mapping, project conventions, qualified symbols, rendered visual review, external-product round trips, and accountable discipline approval remain separate evidence gates. Working proposals carry an explicit not-approved-for-design-or- construction banner in native output.

Validation

Run the focused regression with:

./mvnw -Dtest=ProcessDiagramDocumentSetAdapterTest test
./mvnw -Dtest=NativeEngineeringDiagramRendererTest test
./mvnw -Dtest=EngineeringDiagramStreamTableTest,EngineeringDiagramBalanceTableTest,\
EngineeringDiagramComponentBalanceTableTest,EngineeringDiagramEnergyBalanceTableTest,\
EngineeringDiagramBalanceAssessmentTest,EngineeringDiagramMassBalanceReconciliationTest test

The regression verifies deterministic single- and multi-area output, immutable collections, unchanged Classic DOT output, distinct parallel cross-sheet connections, reciprocal pair cardinality, and fail-visible broken references. It also verifies immutable semantic snapshots, unit/case/provenance retention, rejection of incompletely governed simulation-result values, warning-only diagnostics for pre-existing generic calculation graphs, unchanged topology-only behavior, reviewed designation governance, fail-visible designation mismatches, deterministic cross-sheet revision impact, persistent manual layout evidence, unchanged semantic identities after layout-only revision changes, protected-route retention, and fail-visible stale layout references. The native-renderer regression verifies byte-deterministic SVG/PDF, A3 and A1 geometry, exact pinned coordinates and protected routes, reciprocal off-page references, deterministic connection labels, route/object and route-label obstacle diagnostics, collision, clipping, label-overflow and broken-reference diagnostics, normalized visual fingerprints, multi-page drawing sets, fresh-model determinism, and unchanged Classic DOT and controlled-document JSON.

Exchange-neutral graphical projection

EngineeringGraphicalProjectionBuilder converts the canonical EngineeringGraph into an immutable, restartable EngineeringGraphicalProjection. The projection is deliberately separate from both semantic engineering state and renderer-specific SVG, PDF, or DEXPI objects. It carries:

The generic RECTANGLE, POLYGON, POLYLINE, and TEXT primitives are an adapter contract, not a symbol standard. A REVIEWED projection records reviewed input evidence only; it does not approve a drawing for design or construction. Missing project conventions use an explicit generic rectangle and emit GRAPHICAL_PROJECTION_GENERIC_SYMBOL_FALLBACK. No ISO 10628, ISO 14617, ISA, DEXPI profile, or company-symbol conformance is inferred.

The projection is deterministic JSON (neqsim_engineering_graphical_projection.v1) and can be restored with EngineeringGraphicalProjection.fromJson(...). Native SVG/PDF and DEXPI Core adapters should consume this same projection. Each adapter must preserve supported stable identities and report unsupported primitive, symbol, or semantic-reference mappings as structured losses. DEXPI RepresentationGroup objects must not be emitted as empty placeholders.