Found while planning #322 (p6-s8).
The gap
A prop instance stores its model as the OpenDRIVE <object @name> string, and
nothing else links the two (reader: core/src/xodr/reader.cpp:1143; writer:
core/src/xodr/writer.cpp:660-661). The mesh builder resolves it and, on a miss,
silently skips the object:
// core/src/mesh/mesh_builder.cpp:651-655
const props::PropModel* prop_model = props::model(object.name);
if (prop_model == nullptr) {
continue;
}
Before p6-s8 this was nearly harmless: every resolvable name was compiled in,
so a miss meant a foreign file naming a model we do not have. After p6-s8 it
is a data-visibility hole in our own files. Open a scene that uses imported
props without its project — a bare .xodr handed to a colleague, or the same
scene opened outside the project — and the props vanish from the viewport and
from both exports, with no diagnostic anywhere. The <object> records are
still in the file and still round-trip; nothing is lost on disk. But the user is
shown a scene that is missing content and told nothing.
This is the same class of failure as the header <geoReference> drop
(#324) and the root-scope
<userData> drop (#326):
silent, not lossy, and worse for being silent. The parser doctrine at
core/include/roadmaker/xodr/diagnostic.hpp:31-33 — "anything skipped or
coerced produces an entry here" — is not honoured here.
Why it is not a one-liner
Mesh building has no diagnostic channel. build_object_instances returns
void, build_network_mesh returns a NetworkMesh, and neither carries a
std::vector<Diagnostic>. Adding one touches the full-build and incremental
paths (mesh_builder.cpp:1017 and :1089), the editor's rebuild plumbing, and
the Python bindings. The design question — whether mesh diagnostics accumulate
per build, or unresolved-model names are reported once by the document on load —
is the actual work.
Scope
- Decide where the report belongs (mesh-build diagnostics vs. a document-level
load check) and record it.
- Report each unresolvable
@name once per build, per name — not per
instance; a district import can place thousands.
- Message names the model id, the count of affected objects, and the likely cause
("this scene uses assets from a project that is not open").
- Test: a scene referencing a project-backed model, built with no project overlay
registered, produces exactly one diagnostic naming that model.
Found while planning #322 (
p6-s8).The gap
A prop instance stores its model as the OpenDRIVE
<object @name>string, andnothing else links the two (reader:
core/src/xodr/reader.cpp:1143; writer:core/src/xodr/writer.cpp:660-661). The mesh builder resolves it and, on a miss,silently skips the object:
Before
p6-s8this was nearly harmless: every resolvable name was compiled in,so a miss meant a foreign file naming a model we do not have. After
p6-s8itis a data-visibility hole in our own files. Open a scene that uses imported
props without its project — a bare
.xodrhanded to a colleague, or the samescene opened outside the project — and the props vanish from the viewport and
from both exports, with no diagnostic anywhere. The
<object>records arestill in the file and still round-trip; nothing is lost on disk. But the user is
shown a scene that is missing content and told nothing.
This is the same class of failure as the header
<geoReference>drop(#324) and the root-scope
<userData>drop (#326):silent, not lossy, and worse for being silent. The parser doctrine at
core/include/roadmaker/xodr/diagnostic.hpp:31-33— "anything skipped orcoerced produces an entry here" — is not honoured here.
Why it is not a one-liner
Mesh building has no diagnostic channel.
build_object_instancesreturnsvoid,build_network_meshreturns aNetworkMesh, and neither carries astd::vector<Diagnostic>. Adding one touches the full-build and incrementalpaths (
mesh_builder.cpp:1017and:1089), the editor's rebuild plumbing, andthe Python bindings. The design question — whether mesh diagnostics accumulate
per build, or unresolved-model names are reported once by the document on load —
is the actual work.
Scope
load check) and record it.
@nameonce per build, per name — not perinstance; a district import can place thousands.
("this scene uses assets from a project that is not open").
registered, produces exactly one diagnostic naming that model.