From e571609a7fc7cec91acfe6e25af0129fab9894ba Mon Sep 17 00:00:00 2001 From: Orual Date: Wed, 5 Aug 2026 12:30:56 -0400 Subject: [PATCH] PM-78: count occurrence-local oracle geometry Count each visited model occurrence using its local tokenized geometry before descending through child occurrences, preserving repeated references and active-path cycle cuts. Regenerate oracle-backed expected records from the standalone generator. Epic: PM-86 Task: PM-78 --- .../expected/bfc-invertnext.expected.json | 2 +- .../expected/colours-ldconfig.expected.json | 2 +- .../expected/conditional-lines.expected.json | 2 +- .../expected/external-ldr-tools.expected.json | 2 +- .../expected/external-thomas.expected.json | 2 +- .../expected/graph-instances.expected.json | 2 +- .../h-conditional-ambiguous.expected.json | 2 +- .../h-conditional-degenerate.expected.json | 2 +- .../h-conditional-interior.expected.json | 2 +- .../h-conditional-visible.expected.json | 2 +- .../expected/path-contexts.expected.json | 2 +- .../corpus/expected/path-policy.expected.json | 2 +- .../expected/profile-matrix.expected.json | 2 +- .../expected/steps-transforms.expected.json | 2 +- .../expected/syntax-all-types.expected.json | 10 ++++----- .../expected/syntax-types.expected.json | 10 ++++----- .../expected/texmap-events.expected.json | 4 ++-- tools/ldraw-oracle/oracle.cpp | 21 +++++++++++-------- 18 files changed, 38 insertions(+), 35 deletions(-) diff --git a/crates/polymodel-ldraw-testkit/corpus/expected/bfc-invertnext.expected.json b/crates/polymodel-ldraw-testkit/corpus/expected/bfc-invertnext.expected.json index 9b4d1b5..eb09334 100644 --- a/crates/polymodel-ldraw-testkit/corpus/expected/bfc-invertnext.expected.json +++ b/crates/polymodel-ldraw-testkit/corpus/expected/bfc-invertnext.expected.json @@ -243,7 +243,7 @@ "projection_rule_version": "pm-78-oracle-only-v4", "resolved_geometry": { "conditional_lines": 0, - "includes": 0, + "includes": 89, "lines": 0, "quads": 0, "triangle_positions": [], diff --git a/crates/polymodel-ldraw-testkit/corpus/expected/colours-ldconfig.expected.json b/crates/polymodel-ldraw-testkit/corpus/expected/colours-ldconfig.expected.json index 0f06e19..2e62e25 100644 --- a/crates/polymodel-ldraw-testkit/corpus/expected/colours-ldconfig.expected.json +++ b/crates/polymodel-ldraw-testkit/corpus/expected/colours-ldconfig.expected.json @@ -243,7 +243,7 @@ "projection_rule_version": "pm-78-oracle-only-v4", "resolved_geometry": { "conditional_lines": 0, - "includes": 0, + "includes": 181, "lines": 0, "quads": 0, "triangle_positions": [], diff --git a/crates/polymodel-ldraw-testkit/corpus/expected/conditional-lines.expected.json b/crates/polymodel-ldraw-testkit/corpus/expected/conditional-lines.expected.json index 26e4094..4f62976 100644 --- a/crates/polymodel-ldraw-testkit/corpus/expected/conditional-lines.expected.json +++ b/crates/polymodel-ldraw-testkit/corpus/expected/conditional-lines.expected.json @@ -242,7 +242,7 @@ "patch_identity": "ldparse-oracle-access.patch@pm-78-v2", "projection_rule_version": "pm-78-oracle-only-v4", "resolved_geometry": { - "conditional_lines": 0, + "conditional_lines": 1, "includes": 0, "lines": 0, "quads": 0, diff --git a/crates/polymodel-ldraw-testkit/corpus/expected/external-ldr-tools.expected.json b/crates/polymodel-ldraw-testkit/corpus/expected/external-ldr-tools.expected.json index 0c0bb1a..1611422 100644 --- a/crates/polymodel-ldraw-testkit/corpus/expected/external-ldr-tools.expected.json +++ b/crates/polymodel-ldraw-testkit/corpus/expected/external-ldr-tools.expected.json @@ -715,7 +715,7 @@ "projection_rule_version": "pm-78-oracle-only-v4", "resolved_geometry": { "conditional_lines": 0, - "includes": 0, + "includes": 25, "lines": 0, "quads": 0, "triangle_positions": [], diff --git a/crates/polymodel-ldraw-testkit/corpus/expected/external-thomas.expected.json b/crates/polymodel-ldraw-testkit/corpus/expected/external-thomas.expected.json index 240ef74..9fe5d13 100644 --- a/crates/polymodel-ldraw-testkit/corpus/expected/external-thomas.expected.json +++ b/crates/polymodel-ldraw-testkit/corpus/expected/external-thomas.expected.json @@ -419,7 +419,7 @@ "projection_rule_version": "pm-78-oracle-only-v4", "resolved_geometry": { "conditional_lines": 0, - "includes": 0, + "includes": 126, "lines": 0, "quads": 0, "triangle_positions": [], diff --git a/crates/polymodel-ldraw-testkit/corpus/expected/graph-instances.expected.json b/crates/polymodel-ldraw-testkit/corpus/expected/graph-instances.expected.json index ce3336d..7f552cc 100644 --- a/crates/polymodel-ldraw-testkit/corpus/expected/graph-instances.expected.json +++ b/crates/polymodel-ldraw-testkit/corpus/expected/graph-instances.expected.json @@ -419,7 +419,7 @@ "projection_rule_version": "pm-78-oracle-only-v4", "resolved_geometry": { "conditional_lines": 0, - "includes": 0, + "includes": 126, "lines": 0, "quads": 0, "triangle_positions": [], diff --git a/crates/polymodel-ldraw-testkit/corpus/expected/h-conditional-ambiguous.expected.json b/crates/polymodel-ldraw-testkit/corpus/expected/h-conditional-ambiguous.expected.json index f857bf5..70896d0 100644 --- a/crates/polymodel-ldraw-testkit/corpus/expected/h-conditional-ambiguous.expected.json +++ b/crates/polymodel-ldraw-testkit/corpus/expected/h-conditional-ambiguous.expected.json @@ -242,7 +242,7 @@ "patch_identity": "ldparse-oracle-access.patch@pm-78-v2", "projection_rule_version": "pm-78-oracle-only-v4", "resolved_geometry": { - "conditional_lines": 0, + "conditional_lines": 1, "includes": 0, "lines": 0, "quads": 0, diff --git a/crates/polymodel-ldraw-testkit/corpus/expected/h-conditional-degenerate.expected.json b/crates/polymodel-ldraw-testkit/corpus/expected/h-conditional-degenerate.expected.json index 5346bf1..f78cb87 100644 --- a/crates/polymodel-ldraw-testkit/corpus/expected/h-conditional-degenerate.expected.json +++ b/crates/polymodel-ldraw-testkit/corpus/expected/h-conditional-degenerate.expected.json @@ -242,7 +242,7 @@ "patch_identity": "ldparse-oracle-access.patch@pm-78-v2", "projection_rule_version": "pm-78-oracle-only-v4", "resolved_geometry": { - "conditional_lines": 0, + "conditional_lines": 1, "includes": 0, "lines": 0, "quads": 0, diff --git a/crates/polymodel-ldraw-testkit/corpus/expected/h-conditional-interior.expected.json b/crates/polymodel-ldraw-testkit/corpus/expected/h-conditional-interior.expected.json index 1d515ff..c58026f 100644 --- a/crates/polymodel-ldraw-testkit/corpus/expected/h-conditional-interior.expected.json +++ b/crates/polymodel-ldraw-testkit/corpus/expected/h-conditional-interior.expected.json @@ -242,7 +242,7 @@ "patch_identity": "ldparse-oracle-access.patch@pm-78-v2", "projection_rule_version": "pm-78-oracle-only-v4", "resolved_geometry": { - "conditional_lines": 0, + "conditional_lines": 1, "includes": 0, "lines": 0, "quads": 0, diff --git a/crates/polymodel-ldraw-testkit/corpus/expected/h-conditional-visible.expected.json b/crates/polymodel-ldraw-testkit/corpus/expected/h-conditional-visible.expected.json index 799a66b..67c399f 100644 --- a/crates/polymodel-ldraw-testkit/corpus/expected/h-conditional-visible.expected.json +++ b/crates/polymodel-ldraw-testkit/corpus/expected/h-conditional-visible.expected.json @@ -242,7 +242,7 @@ "patch_identity": "ldparse-oracle-access.patch@pm-78-v2", "projection_rule_version": "pm-78-oracle-only-v4", "resolved_geometry": { - "conditional_lines": 0, + "conditional_lines": 1, "includes": 0, "lines": 0, "quads": 0, diff --git a/crates/polymodel-ldraw-testkit/corpus/expected/path-contexts.expected.json b/crates/polymodel-ldraw-testkit/corpus/expected/path-contexts.expected.json index 534666a..ca1d32f 100644 --- a/crates/polymodel-ldraw-testkit/corpus/expected/path-contexts.expected.json +++ b/crates/polymodel-ldraw-testkit/corpus/expected/path-contexts.expected.json @@ -254,7 +254,7 @@ "projection_rule_version": "pm-78-oracle-only-v4", "resolved_geometry": { "conditional_lines": 0, - "includes": 0, + "includes": 1, "lines": 0, "quads": 0, "triangle_positions": [], diff --git a/crates/polymodel-ldraw-testkit/corpus/expected/path-policy.expected.json b/crates/polymodel-ldraw-testkit/corpus/expected/path-policy.expected.json index aac4f81..c2d9f63 100644 --- a/crates/polymodel-ldraw-testkit/corpus/expected/path-policy.expected.json +++ b/crates/polymodel-ldraw-testkit/corpus/expected/path-policy.expected.json @@ -243,7 +243,7 @@ "projection_rule_version": "pm-78-oracle-only-v4", "resolved_geometry": { "conditional_lines": 0, - "includes": 0, + "includes": 1, "lines": 0, "quads": 0, "triangle_positions": [], diff --git a/crates/polymodel-ldraw-testkit/corpus/expected/profile-matrix.expected.json b/crates/polymodel-ldraw-testkit/corpus/expected/profile-matrix.expected.json index 859afe2..3808521 100644 --- a/crates/polymodel-ldraw-testkit/corpus/expected/profile-matrix.expected.json +++ b/crates/polymodel-ldraw-testkit/corpus/expected/profile-matrix.expected.json @@ -243,7 +243,7 @@ "projection_rule_version": "pm-78-oracle-only-v4", "resolved_geometry": { "conditional_lines": 0, - "includes": 0, + "includes": 1, "lines": 0, "quads": 0, "triangle_positions": [], diff --git a/crates/polymodel-ldraw-testkit/corpus/expected/steps-transforms.expected.json b/crates/polymodel-ldraw-testkit/corpus/expected/steps-transforms.expected.json index e197f8c..b63af2e 100644 --- a/crates/polymodel-ldraw-testkit/corpus/expected/steps-transforms.expected.json +++ b/crates/polymodel-ldraw-testkit/corpus/expected/steps-transforms.expected.json @@ -243,7 +243,7 @@ "projection_rule_version": "pm-78-oracle-only-v4", "resolved_geometry": { "conditional_lines": 0, - "includes": 0, + "includes": 89, "lines": 0, "quads": 0, "triangle_positions": [], diff --git a/crates/polymodel-ldraw-testkit/corpus/expected/syntax-all-types.expected.json b/crates/polymodel-ldraw-testkit/corpus/expected/syntax-all-types.expected.json index 2aa8a67..ea17c8e 100644 --- a/crates/polymodel-ldraw-testkit/corpus/expected/syntax-all-types.expected.json +++ b/crates/polymodel-ldraw-testkit/corpus/expected/syntax-all-types.expected.json @@ -242,12 +242,12 @@ "patch_identity": "ldparse-oracle-access.patch@pm-78-v2", "projection_rule_version": "pm-78-oracle-only-v4", "resolved_geometry": { - "conditional_lines": 0, - "includes": 0, - "lines": 0, - "quads": 0, + "conditional_lines": 1, + "includes": 1, + "lines": 1, + "quads": 1, "triangle_positions": [], - "triangles": 0 + "triangles": 1 }, "root_model": { "certify": "uncertified", diff --git a/crates/polymodel-ldraw-testkit/corpus/expected/syntax-types.expected.json b/crates/polymodel-ldraw-testkit/corpus/expected/syntax-types.expected.json index 67822a2..7b76b06 100644 --- a/crates/polymodel-ldraw-testkit/corpus/expected/syntax-types.expected.json +++ b/crates/polymodel-ldraw-testkit/corpus/expected/syntax-types.expected.json @@ -242,12 +242,12 @@ "patch_identity": "ldparse-oracle-access.patch@pm-78-v2", "projection_rule_version": "pm-78-oracle-only-v4", "resolved_geometry": { - "conditional_lines": 0, - "includes": 0, - "lines": 0, - "quads": 0, + "conditional_lines": 1, + "includes": 1, + "lines": 1, + "quads": 1, "triangle_positions": [], - "triangles": 0 + "triangles": 1 }, "root_model": { "certify": "uncertified", diff --git a/crates/polymodel-ldraw-testkit/corpus/expected/texmap-events.expected.json b/crates/polymodel-ldraw-testkit/corpus/expected/texmap-events.expected.json index 324eece..1bdf80e 100644 --- a/crates/polymodel-ldraw-testkit/corpus/expected/texmap-events.expected.json +++ b/crates/polymodel-ldraw-testkit/corpus/expected/texmap-events.expected.json @@ -245,9 +245,9 @@ "conditional_lines": 0, "includes": 0, "lines": 0, - "quads": 0, + "quads": 1, "triangle_positions": [], - "triangles": 0 + "triangles": 2 }, "root_model": { "certify": "uncertified", diff --git a/tools/ldraw-oracle/oracle.cpp b/tools/ldraw-oracle/oracle.cpp index 9d85b42..19471bf 100644 --- a/tools/ldraw-oracle/oracle.cpp +++ b/tools/ldraw-oracle/oracle.cpp @@ -181,19 +181,22 @@ std::optional tokenize_file(const std::filesystem::path& p using ModelCounts = std::map; -void resolve_model_occurrences(const LDParse::Model& model, const ModelCounts& source_counts, +void add_model_local_counts(ResolvedCounts& counts, const LDParse::Model& model, + const ModelCounts& local_counts) { + const auto found = local_counts.find(model.name()); + if (found != local_counts.end()) add_counts(counts, found->second); +} + +void resolve_model_occurrences(const LDParse::Model& model, const ModelCounts& local_counts, std::set& active, ResolvedCounts& counts) { - const auto key = lowercase(model.getPath()); - if (const auto found = source_counts.find(key); found != source_counts.end()) { - add_counts(counts, found->second); - } if (!active.insert(&model).second) return; + add_model_local_counts(counts, model, local_counts); for (const auto& [index, bfc, transform, child] : model.children()) { (void)index; (void)bfc; (void)transform; - if (child) resolve_model_occurrences(*child, source_counts, active, counts); + if (child) resolve_model_occurrences(*child, local_counts, active, counts); } active.erase(&model); } @@ -585,14 +588,14 @@ int run_one(const std::string& path) { return 0; } - ModelCounts source_counts; + ModelCounts local_counts; for (const auto& [model_name, line_stream] : models) { LDParse::ModelStream one_model{{model_name, line_stream}}; - source_counts.emplace(lowercase(model_name), count_geometry(one_model)); + local_counts.emplace(model_name, count_geometry(one_model)); } ResolvedCounts resolved; std::set active; - resolve_model_occurrences(*root, source_counts, active, resolved); + resolve_model_occurrences(*root, local_counts, active, resolved); std::cout << success_json(path, names, *root, models, diagnostics, t_tri, t_quad, t_line, t_cond, t_incl, resolved, tri_positions) << '\n'; -- 2.51.2