From d4201b499e02d615635dae130259ed0519d89e38 Mon Sep 17 00:00:00 2001 From: Orual Date: Sun, 2 Aug 2026 19:31:12 -0400 Subject: [PATCH] PM-78: fix H2 H5 and H7 - canonical include lookup and instance reflection Epic: PM-86 Task: PM-78 --- crates/polymodel-ldraw-core/src/traversal.rs | 26 +++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/crates/polymodel-ldraw-core/src/traversal.rs b/crates/polymodel-ldraw-core/src/traversal.rs index 34dd00c..16c7854 100644 --- a/crates/polymodel-ldraw-core/src/traversal.rs +++ b/crates/polymodel-ldraw-core/src/traversal.rs @@ -43,6 +43,10 @@ pub(crate) fn traverse( }, } + let mut model_indices = HashMap::::new(); + for (index, model) in models.iter().enumerate() { + model_indices.entry(model.path.clone()).or_insert(index); + } let mut ids = HashMap::::new(); let mut completed = HashSet::::new(); let mut visiting = HashSet::::new(); @@ -55,7 +59,6 @@ pub(crate) fn traverse( let mut scene_quads = 0u64; let mut scene_lines = 0u64; let mut scene_conditional_lines = 0u64; - let mut reflection = false; let root_key = models[0].key.clone(); ids.insert(root_key.clone(), models[0].path.to_string()); @@ -136,8 +139,6 @@ pub(crate) fn traverse( scene_conditional_lines = scene_conditional_lines .checked_add(model.conditional_lines) .ok_or(ParseError::Overflow("scene conditional_lines"))?; - reflection ^= reflected; - stack.push_back(Visit::Exit { key: key.clone() }); for (include_position, include) in model.includes.iter().enumerate().rev() { if options.cancellation.cancelled { @@ -146,15 +147,18 @@ pub(crate) fn traverse( counters .add(LimitKind::Instances, 1, &options.limits) .map_err(|name| limit_error(name, Some(include.span)))?; - let target = models.iter().position(|candidate| { - candidate - .path - .as_str() - .eq_ignore_ascii_case(&include.name.replace('\\', "/")) - }); + let normalized_include = crate::cache::NormalizedPath::new(include.name.as_ref()); + let target = normalized_include + .as_ref() + .ok() + .and_then(|path| model_indices.get(path).copied()); let child_name = target .map(|index| models[index].path.to_string()) - .unwrap_or_else(|| include.name.replace('\\', "/")); + .unwrap_or_else(|| { + normalized_include + .map(|path| path.to_string()) + .unwrap_or_else(|_| include.name.to_string()) + }); let instance_id = format!( "{}→{}#{}", model.path, @@ -236,7 +240,7 @@ pub(crate) fn traverse( lines: scene_lines, conditional_lines: scene_conditional_lines, bounds: scene_bounds, - reflection, + reflection: false, }; Ok((scene, summaries)) } -- 2.51.2