forked from 1b-agent/opencadstudio-upstream
perf(render): instance block geometry
Share source buffers across block placements and render nested content with GPU instance transforms.\n\nChunk silhouettes and compact mesh material data so large drawings stay under device buffer limits and remain responsive.
This commit is contained in:
1 parent
7bfb617745
commit
4fd9b98da4
68 files changed
+3417
-547
No files matched your search
@@ -155,6 +155,7 @@ pub const GPU_BOUNDARY_SEP: f32 = 1.0e30;
|
||||
/// A hatched region defined by a closed polygon boundary.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct HatchModel {
|
||||
pub render_instance: Option<super::instance_model::RenderInstance>,
|
||||
/// World XY anchor (in the same offset-relative coordinate space as
|
||||
/// the rest of the scene — `world_offset` already subtracted, but
|
||||
/// kept at f64 precision). Boundary vertices are stored as f32
|
||||
|
||||
@@ -82,6 +82,7 @@ fn clip_triangles_px(img: &acadrust::entities::RasterImage) -> Vec<[f64; 2]> {
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ImageModel {
|
||||
pub render_instance: Option<super::instance_model::RenderInstance>,
|
||||
/// Original file path (used for reload / display in properties).
|
||||
pub file_path: String,
|
||||
/// RGBA8 pixel data in row-major order. Arc-wrapped so cloning ImageModel
|
||||
@@ -168,6 +169,7 @@ impl ImageModel {
|
||||
|
||||
let decoded = resolve_image(&img.file_path)?;
|
||||
Some(Self {
|
||||
render_instance: None,
|
||||
file_path: img.file_path.clone(),
|
||||
pixels: decoded.pixels,
|
||||
width: decoded.width,
|
||||
@@ -278,6 +280,7 @@ impl ImageModel {
|
||||
.collect();
|
||||
|
||||
Some(Self {
|
||||
render_instance: None,
|
||||
file_path: def.file_path.clone(),
|
||||
pixels: raster.pixels.clone(),
|
||||
width: raster.width,
|
||||
@@ -334,6 +337,7 @@ impl ImageModel {
|
||||
let corners_low = [l0, l1, l2, l3];
|
||||
let verts = quad_verts(&corners, &corners_low);
|
||||
Some(Self {
|
||||
render_instance: None,
|
||||
file_path: "OLE2FRAME".to_string(),
|
||||
pixels: Arc::new(pixels),
|
||||
width,
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
static NEXT_SOURCE_ID: AtomicU64 = AtomicU64::new(1);
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct RenderInstance {
|
||||
pub source_id: u64,
|
||||
pub translation: [f64; 3],
|
||||
}
|
||||
|
||||
pub fn next_source_id() -> u64 {
|
||||
NEXT_SOURCE_ID.fetch_add(1, Ordering::Relaxed)
|
||||
}
|
||||
@@ -3,6 +3,7 @@ pub mod gdi;
|
||||
pub mod hatch_model;
|
||||
pub mod hatch_patterns;
|
||||
pub mod image_model;
|
||||
pub mod instance_model;
|
||||
pub mod material_model;
|
||||
pub mod ole_pres;
|
||||
pub mod pdf_raster;
|
||||
|
||||
@@ -156,6 +156,8 @@ pub struct WireModel {
|
||||
/// `true` only for a planar SOLID entity's interior. Wireframe 3D omits
|
||||
/// this fill while preserving its perimeter and every other 2-D overlay.
|
||||
pub fill_is_2d_solid: bool,
|
||||
/// Shared block-render source and this placement's translation.
|
||||
pub render_instance: Option<super::instance_model::RenderInstance>,
|
||||
}
|
||||
|
||||
impl WireModel {
|
||||
@@ -208,6 +210,7 @@ impl WireModel {
|
||||
depth_override: None,
|
||||
fill_is_3d: false,
|
||||
fill_is_2d_solid: false,
|
||||
render_instance: None,
|
||||
pick_tris: Vec::new(),
|
||||
pick_tris_low: Vec::new(),
|
||||
text_verts: Vec::new(),
|
||||
@@ -467,6 +470,7 @@ impl Default for WireModel {
|
||||
depth_override: None,
|
||||
fill_is_3d: false,
|
||||
fill_is_2d_solid: false,
|
||||
render_instance: None,
|
||||
pick_tris: Vec::new(),
|
||||
pick_tris_low: Vec::new(),
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user