forked from 1b-agent/opencadstudio-upstream
fix(render): share repeated block meshes
Keep placement transforms and bounds separate from immutable mesh data to prevent large drawings from exhausting memory or stalling selection.
This commit is contained in:
1 parent
5e773fbcce
commit
7b4af0aa75
6 files changed
+408
-399
No files matched your search
@@ -221,8 +221,12 @@ impl MeshMaterial {
|
||||
}
|
||||
|
||||
pub fn apply_to(&self, set: &mut super::mesh_model::MeshLodSet) {
|
||||
for lod in &mut set.lods {
|
||||
lod.color = self.diffuse;
|
||||
if set.instance_source.is_some() {
|
||||
set.instance_color = Some(self.diffuse);
|
||||
} else {
|
||||
for lod in &mut set.lods {
|
||||
lod.color = self.diffuse;
|
||||
}
|
||||
}
|
||||
set.material = Some(self.clone());
|
||||
}
|
||||
@@ -236,7 +240,7 @@ impl MeshMaterial {
|
||||
self.apply_to(set);
|
||||
set.face_materials.clear();
|
||||
let handles: rustc_hash::FxHashSet<Handle> = set
|
||||
.lods
|
||||
.geometry_lods()
|
||||
.iter()
|
||||
.flat_map(|lod| lod.triangle_material_handles.iter().flatten().copied())
|
||||
.collect();
|
||||
|
||||
@@ -104,6 +104,12 @@ pub struct MeshLodSet {
|
||||
pub instance_source: Option<std::sync::Arc<MeshInstanceSource>>,
|
||||
/// Accumulated block-local → world transform for this rendered instance.
|
||||
pub instance_transform: Option<acadrust::types::Transform>,
|
||||
/// Parent INSERT selected for this rendered block instance.
|
||||
pub instance_handle: Option<acadrust::Handle>,
|
||||
/// Effective colour after INSERT inheritance, without copying the mesh.
|
||||
pub instance_color: Option<[f32; 4]>,
|
||||
/// Precise world bounds used by the interaction index.
|
||||
pub instance_aabb: Option<[f64; 6]>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -112,6 +118,7 @@ pub struct MeshInstanceSource {
|
||||
pub lods: Vec<MeshModel>,
|
||||
pub edge_verts: Vec<[f32; 3]>,
|
||||
pub edge_verts_low: Vec<[f32; 3]>,
|
||||
pub curved_gens: Vec<CurvedGen>,
|
||||
}
|
||||
|
||||
/// 3D bounds of every LOD's vertices: `([min_x, min_y, max_x, max_y], [min_z, max_z])`.
|
||||
@@ -225,6 +232,9 @@ impl MeshLodSet {
|
||||
z_aabb,
|
||||
instance_source: None,
|
||||
instance_transform: None,
|
||||
instance_handle: None,
|
||||
instance_color: None,
|
||||
instance_aabb: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,7 +260,35 @@ impl MeshLodSet {
|
||||
lods: self.lods.clone(),
|
||||
edge_verts: self.edge_verts.clone(),
|
||||
edge_verts_low: self.edge_verts_low.clone(),
|
||||
curved_gens: self.curved_gens.clone(),
|
||||
}));
|
||||
self.instance_transform = None;
|
||||
self.instance_handle = None;
|
||||
self.instance_color = None;
|
||||
self.instance_aabb = None;
|
||||
}
|
||||
|
||||
pub fn geometry_lods(&self) -> &[MeshModel] {
|
||||
self.instance_source
|
||||
.as_ref()
|
||||
.map_or(self.lods.as_slice(), |source| source.lods.as_slice())
|
||||
}
|
||||
|
||||
pub fn entity_handle(&self) -> Option<acadrust::Handle> {
|
||||
self.instance_handle.or_else(|| {
|
||||
self.lods
|
||||
.first()
|
||||
.and_then(|mesh| mesh.name.parse::<u64>().ok())
|
||||
.map(acadrust::Handle::new)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn display_color(&self) -> Option<[f32; 4]> {
|
||||
self.instance_color.or_else(|| {
|
||||
self.geometry_lods()
|
||||
.iter()
|
||||
.find(|mesh| !mesh.indices.is_empty())
|
||||
.map(|mesh| mesh.color)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user