Complete PolygonMesh, PolyfaceMesh and Mesh host model coverage

Maps all three mesh kinds with host validation of grid counts, face indices
and edge topology, and skips sub-record common data in the generator.
A shared run_mesh_lifecycle driver passes the full gate for each kind,
including DWG and DXF reopen with re-edit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Felix RiestraandClaude Sonnet 5 committed 2026-09-20 14:42:42 +02:00
1 parent 0206c7c30b
commit b97d74efa4
11 files changed
+479 -15

No files matched your search

+1 -1
View File
@@ -94,7 +94,7 @@ The host-owned catalog classifies all 48 entity variants and tracks every
traced field, including fields marked `unmapped`. Query it with
`doc.coverage()` or `doc.coverage("Line")`; each row includes source field,
type, access, and current validation status. Geometry edits remain limited to
the 27 mapped kinds.
the 30 mapped kinds.
For any entity, `entity.snapshot` returns a detached dictionary of its raw
CAD fields, including `snapshot["common"]` and kind-specific nested values.
It can inspect an unmapped kind; editing the dictionary does
+11 -1
View File
@@ -218,7 +218,9 @@ fn helper_closure(manifest: &Manifest, registry: &TypeRegistry) -> Vec<String> {
panic!("entity_manifest.json: type {name} (reached transitively) is not in the type registry");
};
for f in &info.fields {
queue.push(f.type_id.as_str().to_string());
if f.type_id.as_str() != "EntityCommon" {
queue.push(f.type_id.as_str().to_string());
}
}
for v in &info.variants {
for f in &v.fields {
@@ -666,6 +668,14 @@ fn gen_struct(name: &str, info: &TypeInfo, registry: &TypeRegistry) -> String {
let mut from_dict_fields = String::new();
let mut default_fields = String::new();
for f in &info.fields {
if f.type_id.as_str() == "EntityCommon" {
// A sub-record's own common data (layer, XDATA, handles) is not part
// of the scripted model; it defaults on the way in.
let default = "acadrust::entities::EntityCommon::default()";
from_dict_fields.push_str(&format!(" {}: {default},\n", f.name));
default_fields.push_str(&format!(" {}: {default},\n", f.name));
continue;
}
let getter = getter_for_field(
registry,
f.type_id.as_str(),
+22 -1
View File
@@ -26,7 +26,10 @@
"MLine",
"Dimension",
"MultiLeader",
"Table"
"Table",
"PolygonMesh",
"PolyfaceMesh",
"Mesh"
],
"manual_kinds": ["Dimension"],
"base_fields": ["handle", "layer", "owner_handle"],
@@ -310,6 +313,24 @@
"legacy_border_line_weights": { "exclude": true },
"legacy_border_visibility": { "exclude": true }
}
},
"PolygonMesh": {
"rust_constructor": "acadrust::entities::PolygonMeshEntity::default()",
"fields": { "vertices": { "required": true } }
},
"PolyfaceMesh": {
"fields": {
"vertices": { "required": true },
"faces": { "required": true },
"seqend_handle": { "read_only": true }
}
},
"Mesh": {
"fields": {
"vertices": { "required": true },
"faces": { "required": true },
"version": { "read_only": true }
}
}
}
}
+1 -1
View File
@@ -4756,7 +4756,7 @@ mod tests {
);
}
}
assert_eq!(emitted.len(), 27);
assert_eq!(emitted.len(), 30);
}
#[cfg(feature = "experimental-host-model")]