forked from 1b-agent/opencadstudio-upstream
perf(render): batch solid meshes, fix per-pick freezes on heavy 3D models
Opening / navigating a heavy 3D DWG (e.g. a BIM model with ~10k ACIS solids) was effectively frozen. Several independent costs, all addressed here: - Face3D edge/fill buffers were re-uploaded on every camera move (keyed on camera_generation). They are world-space and selection-independent, so gate them on (geometry_epoch, fill_mode) instead — a pan no longer re-walks every wire. - Solid meshes were drawn one buffer + one draw call per solid (~10k draws/ frame), which strangled the GPU front end. Concatenate every solid's LOD0 into a few large buffers (split only to stay under the 256 MB buffer cap) and draw the whole set in a handful of calls. Built once per geometry epoch, so selection / hover never re-pack it. - Selection / hover highlight is now a small tinted overlay of just the picked solids, drawn last with an Always-depth pipeline so it shows on top even when the solid is occluded — instead of re-tinting and re-uploading all meshes. - Hover / pick hit-testing scanned every triangle of every solid each move (seconds on a heavy model). Add a 3D-AABB screen-rect broad phase (MeshLodSet now carries z_aabb) and reuse the renderer's cached expanded mesh set, so picking is O(solids) cheap projections plus the few solids actually under the cursor. - Block-internal hatch hit-testing exploded every INSERT on every hover. Cache the result per geometry epoch and skip blocks that contain no hatch. - Curved-surface (cone/sphere/torus) tessellation tolerance is now radius- relative (CURVE_REL_TOL) so a cylinder's facet count is size-independent and matches the circle/arc wire tessellation, instead of exploding on large radii. Also adds docs/tessellation.md mapping every EntityType to its tessellation path (truck B-rep vs truck curve topology vs direct). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
27896e3401
commit
a994a148fe
10 files changed
+572
-146
No files matched your search
@@ -181,8 +181,7 @@ fn tessellate_sat_lods(
|
||||
if lods.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let world_aabb = mesh_aabb(&lods[0]);
|
||||
Some(MeshLodSet { lods, world_aabb })
|
||||
Some(MeshLodSet::from_lods(lods))
|
||||
}
|
||||
|
||||
/// Extract the body's placement transform from the SAT document: a row-major
|
||||
@@ -243,6 +242,7 @@ fn scale_lod(base: LodConfig, facet_res: f64) -> LodConfig {
|
||||
|
||||
/// World-XY AABB of the mesh — used by the render-pipeline LOD selector
|
||||
/// to pick a level based on projected pixel diagonal.
|
||||
#[allow(dead_code)] // superseded by mesh_model::compute_mesh_aabb (3D); kept for reference
|
||||
pub(crate) fn mesh_aabb(mesh: &MeshModel) -> [f32; 4] {
|
||||
let mut min_x = f32::INFINITY;
|
||||
let mut min_y = f32::INFINITY;
|
||||
|
||||
Reference in new issue
Block a user