forked from 1b-agent/opencadstudio-upstream
Merge pull request #952 from ramox81/codex/fix-sphere-3d-render
Fix sphere edge rendering in 3D views
This commit is contained in:
2 files changed
+45
-55
No files matched your search
@@ -343,11 +343,11 @@ pub struct MeshBatchChunk {
|
|||||||
/// erase — the geometry behind them.
|
/// erase — the geometry behind them.
|
||||||
pub transp_index_buffer: wgpu::Buffer,
|
pub transp_index_buffer: wgpu::Buffer,
|
||||||
pub transp_index_count: u32,
|
pub transp_index_count: u32,
|
||||||
/// Triangle-edge line list for plain meshes that carry no B-rep edges.
|
/// Expanded triangle-edge line list for plain meshes that carry no B-rep
|
||||||
/// The dedicated vertex buffer matches the edge pipeline layout.
|
/// edges. Keeping the edge endpoints together avoids coupling this buffer
|
||||||
|
/// to the surface mesh's indexing and vertex representation.
|
||||||
pub wire_vertex_buffer: wgpu::Buffer,
|
pub wire_vertex_buffer: wgpu::Buffer,
|
||||||
pub wire_index_buffer: wgpu::Buffer,
|
pub wire_vertex_count: u32,
|
||||||
pub wire_index_count: u32,
|
|
||||||
/// B-rep feature edges of ACIS solids, as a standalone LineList vertex
|
/// B-rep feature edges of ACIS solids, as a standalone LineList vertex
|
||||||
/// buffer (pairs of endpoints), drawn non-indexed. Empty for plain meshes.
|
/// buffer (pairs of endpoints), drawn non-indexed. Empty for plain meshes.
|
||||||
pub edge_vertex_buffer: wgpu::Buffer,
|
pub edge_vertex_buffer: wgpu::Buffer,
|
||||||
@@ -438,7 +438,7 @@ fn make_chunk(
|
|||||||
queue.write_buffer(&buffer, 0, bytemuck::cast_slice(data));
|
queue.write_buffer(&buffer, 0, bytemuck::cast_slice(data));
|
||||||
buffer
|
buffer
|
||||||
};
|
};
|
||||||
let compact_vertices = !material_has_textures(material) && wire_indices.is_empty();
|
let compact_vertices = !material_has_textures(material);
|
||||||
let mk_plain_vertex = |data: &[MeshVertex]| {
|
let mk_plain_vertex = |data: &[MeshVertex]| {
|
||||||
if data.is_empty() {
|
if data.is_empty() {
|
||||||
return stubs.vertex.clone();
|
return stubs.vertex.clone();
|
||||||
@@ -479,18 +479,22 @@ fn make_chunk(
|
|||||||
} else {
|
} else {
|
||||||
instances
|
instances
|
||||||
};
|
};
|
||||||
let wire_vertices: Vec<MeshEdgeVertex> = if wire_indices.is_empty() {
|
let mut wire_vertices = Vec::with_capacity(wire_indices.len());
|
||||||
Vec::new()
|
for line in wire_indices.chunks_exact(2) {
|
||||||
} else {
|
let (Some(start), Some(end)) = (
|
||||||
verts
|
verts.get(line[0] as usize),
|
||||||
.iter()
|
verts.get(line[1] as usize),
|
||||||
.map(|vertex| MeshEdgeVertex {
|
) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
for vertex in [start, end] {
|
||||||
|
wire_vertices.push(MeshEdgeVertex {
|
||||||
position: vertex.position,
|
position: vertex.position,
|
||||||
color: face_color,
|
color: face_color,
|
||||||
position_low: vertex.position_low,
|
position_low: vertex.position_low,
|
||||||
})
|
});
|
||||||
.collect()
|
}
|
||||||
};
|
}
|
||||||
MeshBatchChunk {
|
MeshBatchChunk {
|
||||||
vertex_buffer: vertex_buffer_override.unwrap_or_else(|| {
|
vertex_buffer: vertex_buffer_override.unwrap_or_else(|| {
|
||||||
if compact_vertices {
|
if compact_vertices {
|
||||||
@@ -505,8 +509,7 @@ fn make_chunk(
|
|||||||
transp_index_buffer: mk_index(transp_indices, "mesh.batch.transp_ibuf"),
|
transp_index_buffer: mk_index(transp_indices, "mesh.batch.transp_ibuf"),
|
||||||
transp_index_count: transp_indices.len() as u32,
|
transp_index_count: transp_indices.len() as u32,
|
||||||
wire_vertex_buffer: mk_edge_vertex(&wire_vertices, "mesh.batch.wire_vbuf"),
|
wire_vertex_buffer: mk_edge_vertex(&wire_vertices, "mesh.batch.wire_vbuf"),
|
||||||
wire_index_buffer: mk_index(wire_indices, "mesh.batch.wire_ibuf"),
|
wire_vertex_count: wire_vertices.len() as u32,
|
||||||
wire_index_count: wire_indices.len() as u32,
|
|
||||||
edge_vertex_buffer: edge_buffer_override
|
edge_vertex_buffer: edge_buffer_override
|
||||||
.unwrap_or_else(|| mk_edge_vertex(edge_verts, "mesh.batch.edge_vbuf")),
|
.unwrap_or_else(|| mk_edge_vertex(edge_verts, "mesh.batch.edge_vbuf")),
|
||||||
edge_vertex_count: edge_verts.len() as u32,
|
edge_vertex_count: edge_verts.len() as u32,
|
||||||
@@ -1169,8 +1172,7 @@ fn build_instanced_chunk(
|
|||||||
let material = first.material;
|
let material = first.material;
|
||||||
let color = first.color;
|
let color = first.color;
|
||||||
let source_handle = source.handle.value();
|
let source_handle = source.handle.value();
|
||||||
let compact_vertices = !material_has_textures(material)
|
let compact_vertices = !material_has_textures(material);
|
||||||
&& (!first.include_edges || !source.edge_verts.is_empty());
|
|
||||||
let material_identity = if material_has_textures(material) {
|
let material_identity = if material_has_textures(material) {
|
||||||
material.map_or(0, |material| {
|
material.map_or(0, |material| {
|
||||||
material
|
material
|
||||||
@@ -1582,7 +1584,10 @@ pub fn build_mesh_batch_filtered(
|
|||||||
let budget = hard_budget.min(32 * 1024 * 1024);
|
let budget = hard_budget.min(32 * 1024 * 1024);
|
||||||
let vsize = std::mem::size_of::<MeshVertex>();
|
let vsize = std::mem::size_of::<MeshVertex>();
|
||||||
let max_verts = (budget / vsize).max(3);
|
let max_verts = (budget / vsize).max(3);
|
||||||
let max_tris = (budget / (6 * 4)).max(1); // wire-index buffer: 6 u32 per tri
|
// A triangle contributes three line segments (six standalone edge
|
||||||
|
// vertices). Bound chunks by the largest buffer produced for wire meshes.
|
||||||
|
let max_tris =
|
||||||
|
(budget / (6 * std::mem::size_of::<MeshEdgeVertex>())).max(1);
|
||||||
let stubs = MeshBatchStubs::new(device);
|
let stubs = MeshBatchStubs::new(device);
|
||||||
|
|
||||||
let mut chunks = Vec::new();
|
let mut chunks = Vec::new();
|
||||||
@@ -1796,18 +1801,27 @@ pub fn build_mesh_batch_filtered(
|
|||||||
.len()
|
.len()
|
||||||
.saturating_mul(std::mem::size_of::<MeshVertex>())
|
.saturating_mul(std::mem::size_of::<MeshVertex>())
|
||||||
<= hard_budget
|
<= hard_budget
|
||||||
&& part.indices.len().saturating_mul(2 * std::mem::size_of::<u32>())
|
&& part.indices.len().saturating_mul(std::mem::size_of::<u32>())
|
||||||
<= hard_budget
|
<= hard_budget
|
||||||
&& part
|
&& part
|
||||||
.set
|
.set
|
||||||
.instance_source
|
.instance_source
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.is_some_and(|source| {
|
.is_some_and(|source| {
|
||||||
source
|
let feature_edges_fit = source
|
||||||
.edge_verts
|
.edge_verts
|
||||||
.len()
|
.len()
|
||||||
.saturating_mul(std::mem::size_of::<MeshEdgeVertex>())
|
.saturating_mul(std::mem::size_of::<MeshEdgeVertex>())
|
||||||
<= hard_budget
|
<= hard_budget;
|
||||||
|
let triangle_edges_fit = !part.include_edges
|
||||||
|
|| !source.edge_verts.is_empty()
|
||||||
|
|| part
|
||||||
|
.indices
|
||||||
|
.len()
|
||||||
|
.saturating_mul(2)
|
||||||
|
.saturating_mul(std::mem::size_of::<MeshEdgeVertex>())
|
||||||
|
<= hard_budget;
|
||||||
|
feature_edges_fit && triangle_edges_fit
|
||||||
})
|
})
|
||||||
&& part
|
&& part
|
||||||
.indices
|
.indices
|
||||||
@@ -2152,8 +2166,8 @@ pub fn build_mesh_batch_filtered(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush when adding this mesh would overflow either the vertex buffer
|
// Flush when adding this mesh would overflow either the surface vertex
|
||||||
// or the wire-index buffer.
|
// buffer or the expanded wire-vertex buffer.
|
||||||
if !verts.is_empty()
|
if !verts.is_empty()
|
||||||
&& (verts.len() + mesh.verts.len() > max_verts
|
&& (verts.len() + mesh.verts.len() > max_verts
|
||||||
|| wire_indices.len() / 6 + mesh_tris > max_tris)
|
|| wire_indices.len() / 6 + mesh_tris > max_tris)
|
||||||
|
|||||||
@@ -3750,7 +3750,7 @@ impl Pipeline {
|
|||||||
// Four draw paths share this pass:
|
// Four draw paths share this pass:
|
||||||
// - Solid: `mesh_pipeline` + triangle index buf.
|
// - Solid: `mesh_pipeline` + triangle index buf.
|
||||||
// - Wireframe: `mesh_wireframe_pipeline` + the
|
// - Wireframe: `mesh_wireframe_pipeline` + the
|
||||||
// pre-built `wire_index_buffer`.
|
// pre-built expanded wire vertex buffer.
|
||||||
// - HiddenLine: depth prepass (`mesh_depth_pipeline`,
|
// - HiddenLine: depth prepass (`mesh_depth_pipeline`,
|
||||||
// writes Z, no colour) → wire overlay.
|
// writes Z, no colour) → wire overlay.
|
||||||
// - Solid+Edges: `mesh_pipeline` shaded fill → wire
|
// - Solid+Edges: `mesh_pipeline` shaded fill → wire
|
||||||
@@ -3809,17 +3809,9 @@ impl Pipeline {
|
|||||||
);
|
);
|
||||||
pass.set_vertex_buffer(1, c.instance_buffer.slice(..));
|
pass.set_vertex_buffer(1, c.instance_buffer.slice(..));
|
||||||
// Plain-mesh triangulation edges.
|
// Plain-mesh triangulation edges.
|
||||||
if c.wire_index_count != 0 {
|
if c.wire_vertex_count != 0 {
|
||||||
pass.set_vertex_buffer(0, c.wire_vertex_buffer.slice(..));
|
pass.set_vertex_buffer(0, c.wire_vertex_buffer.slice(..));
|
||||||
pass.set_index_buffer(
|
pass.draw(0..c.wire_vertex_count, 0..c.instance_count);
|
||||||
c.wire_index_buffer.slice(..),
|
|
||||||
wgpu::IndexFormat::Uint32,
|
|
||||||
);
|
|
||||||
pass.draw_indexed(
|
|
||||||
0..c.wire_index_count,
|
|
||||||
0,
|
|
||||||
0..c.instance_count,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
// ACIS solid B-rep feature edges (LineList, non-indexed).
|
// ACIS solid B-rep feature edges (LineList, non-indexed).
|
||||||
if c.edge_vertex_count != 0 {
|
if c.edge_vertex_count != 0 {
|
||||||
@@ -3846,17 +3838,9 @@ impl Pipeline {
|
|||||||
&[],
|
&[],
|
||||||
);
|
);
|
||||||
pass.set_vertex_buffer(1, c.instance_buffer.slice(..));
|
pass.set_vertex_buffer(1, c.instance_buffer.slice(..));
|
||||||
if c.wire_index_count != 0 {
|
if c.wire_vertex_count != 0 {
|
||||||
pass.set_vertex_buffer(0, c.wire_vertex_buffer.slice(..));
|
pass.set_vertex_buffer(0, c.wire_vertex_buffer.slice(..));
|
||||||
pass.set_index_buffer(
|
pass.draw(0..c.wire_vertex_count, 0..c.instance_count);
|
||||||
c.wire_index_buffer.slice(..),
|
|
||||||
wgpu::IndexFormat::Uint32,
|
|
||||||
);
|
|
||||||
pass.draw_indexed(
|
|
||||||
0..c.wire_index_count,
|
|
||||||
0,
|
|
||||||
0..c.instance_count,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if c.edge_vertex_count != 0 {
|
if c.edge_vertex_count != 0 {
|
||||||
pass.set_vertex_buffer(0, c.edge_vertex_buffer.slice(..));
|
pass.set_vertex_buffer(0, c.edge_vertex_buffer.slice(..));
|
||||||
@@ -4002,17 +3986,9 @@ impl Pipeline {
|
|||||||
&[],
|
&[],
|
||||||
);
|
);
|
||||||
pass.set_vertex_buffer(1, c.instance_buffer.slice(..));
|
pass.set_vertex_buffer(1, c.instance_buffer.slice(..));
|
||||||
if c.wire_index_count != 0 {
|
if c.wire_vertex_count != 0 {
|
||||||
pass.set_vertex_buffer(0, c.wire_vertex_buffer.slice(..));
|
pass.set_vertex_buffer(0, c.wire_vertex_buffer.slice(..));
|
||||||
pass.set_index_buffer(
|
pass.draw(0..c.wire_vertex_count, 0..c.instance_count);
|
||||||
c.wire_index_buffer.slice(..),
|
|
||||||
wgpu::IndexFormat::Uint32,
|
|
||||||
);
|
|
||||||
pass.draw_indexed(
|
|
||||||
0..c.wire_index_count,
|
|
||||||
0,
|
|
||||||
0..c.instance_count,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if c.edge_vertex_count != 0 {
|
if c.edge_vertex_count != 0 {
|
||||||
pass.set_vertex_buffer(0, c.edge_vertex_buffer.slice(..));
|
pass.set_vertex_buffer(0, c.edge_vertex_buffer.slice(..));
|
||||||
|
|||||||
Reference in new issue
Block a user