From 41f4a062dcd612fe705d0282f9881aa4f8d29a30 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Thu, 2 Jul 2026 23:25:02 +0300 Subject: [PATCH] feat(properties): resolve Hyperlink (XDATA) and custom Material name Fill the two placeholder rows added earlier. Read the General group's Hyperlink from the entity's XDATA (the "PE_URL" application record's first string). When an entity carries an explicit material (material_flags == 3), resolve its material_handle to the Material object's name and show it in the 3D Visualization group instead of "Custom". Co-Authored-By: Claude Opus 4.8 --- src/app/properties.rs | 33 +++++++++++++++++++++++++++++++++ src/scene/cache/properties.rs | 14 +++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/app/properties.rs b/src/app/properties.rs index 4c9568378..d6a219414 100644 --- a/src/app/properties.rs +++ b/src/app/properties.rs @@ -74,6 +74,39 @@ impl OpenCADStudio { let mut sections = dispatch::properties_sectioned(handle, entity, &text_style_names); + // Resolve a custom material handle (material_flags == 3) to + // its name in the 3D Visualization group. + { + let common = entity.common(); + if common.material_flags == 3 { + if let Some(mh) = common.material_handle { + if let Some(name) = self.tabs[i] + .scene + .document + .objects + .iter() + .find_map(|(h, o)| match o { + acadrust::objects::ObjectType::Material(m) if *h == mh => { + Some(m.name.clone()) + } + _ => None, + }) + { + for section in sections.iter_mut() { + if let Some(row) = + section.props.iter_mut().find(|p| p.field == "material") + { + row.value = + crate::scene::model::object::PropValue::ReadOnly( + name.clone(), + ); + } + } + } + } + } + } + // Inject viewport-only properties that require doc access. if let acadrust::EntityType::Viewport(vp) = entity { let frozen_names: Vec = vp diff --git a/src/scene/cache/properties.rs b/src/scene/cache/properties.rs index 36f6d3c57..ebafc0a67 100644 --- a/src/scene/cache/properties.rs +++ b/src/scene/cache/properties.rs @@ -11,6 +11,18 @@ pub fn general_section(entity: &EntityType) -> PropSection { }; let transp_pct = (common.transparency.alpha() as f64 / 255.0 * 100.0).round() as u32; + // Hyperlink is stored in XDATA under the "PE_URL" application. + let hyperlink = common + .extended_data + .get_record("PE_URL") + .and_then(|r| { + r.values.iter().find_map(|v| match v { + acadrust::xdata::XDataValue::String(s) if !s.is_empty() => Some(s.clone()), + _ => None, + }) + }) + .unwrap_or_default(); + PropSection { title: "General".into(), props: vec![ @@ -64,7 +76,7 @@ pub fn general_section(entity: &EntityType) -> PropSection { Property { label: "Hyperlink".into(), field: "hyperlink", - value: PropValue::ReadOnly(String::new()), + value: PropValue::ReadOnly(hyperlink), }, Property { label: "Invisible".into(),