forked from 1b-agent/opencadstudio-upstream
fix(render): colour-7 solid edges contrast with a layout's paper
A solid's edges and silhouettes were drawn in its face colour, and the edge shader read that from the material instead of the edge vertices. Colour 7 is white, so in Wireframe 2D a solid vanished white-on-white in a layout viewport (and on a light model background), while wires and block solids already turned black there. Solids now keep a separate edge colour, colour 7 turned against the background they are drawn on, and the edge shader uses the edge vertices' colour again, which also brings back visual-style edge colours. Shaded faces keep their colour so they still read as lit. (#1446) Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
44c6ddc513
commit
19cc2e1073
6 files changed
+24
-8
No files matched your search
@@ -2549,6 +2549,7 @@ mod tests {
|
|||||||
instance_transform: None,
|
instance_transform: None,
|
||||||
instance_handle: None,
|
instance_handle: None,
|
||||||
instance_color: None,
|
instance_color: None,
|
||||||
|
edge_color: None,
|
||||||
instance_aabb: None,
|
instance_aabb: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1991,6 +1991,7 @@ fn transform_block_mesh_lod_set(set: &MeshLodSet, xform: &codec::types::Transfor
|
|||||||
instance_transform: Some(*xform),
|
instance_transform: Some(*xform),
|
||||||
instance_handle: None,
|
instance_handle: None,
|
||||||
instance_color: set.display_color(),
|
instance_color: set.display_color(),
|
||||||
|
edge_color: set.edge_color,
|
||||||
instance_aabb: bounds
|
instance_aabb: bounds
|
||||||
.iter()
|
.iter()
|
||||||
.all(|value| value.is_finite())
|
.all(|value| value.is_finite())
|
||||||
@@ -8994,6 +8995,12 @@ impl Scene {
|
|||||||
entity,
|
entity,
|
||||||
viewport,
|
viewport,
|
||||||
);
|
);
|
||||||
|
// Colour 7 lines contrast with what the solid is drawn
|
||||||
|
// on; shaded faces keep the colour so they still read as
|
||||||
|
// lit. White edges on a white sheet hid a wireframe solid
|
||||||
|
// in a layout viewport. (#1446)
|
||||||
|
let edge = crate::scene::view::render::adapt_to_bg(style.0, self.current_bg());
|
||||||
|
set.edge_color = (edge != style.0).then_some(edge);
|
||||||
let attached_material = set
|
let attached_material = set
|
||||||
.material
|
.material
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|||||||
@@ -145,6 +145,9 @@ pub struct MeshLodSet {
|
|||||||
pub instance_handle: Option<codec::Handle>,
|
pub instance_handle: Option<codec::Handle>,
|
||||||
/// Effective colour after INSERT inheritance, without copying the mesh.
|
/// Effective colour after INSERT inheritance, without copying the mesh.
|
||||||
pub instance_color: Option<[f32; 4]>,
|
pub instance_color: Option<[f32; 4]>,
|
||||||
|
/// Colour of the edge and silhouette lines when it differs from the
|
||||||
|
/// faces': colour 7 drawn against the background it sits on.
|
||||||
|
pub edge_color: Option<[f32; 4]>,
|
||||||
/// Precise world bounds used by the interaction index.
|
/// Precise world bounds used by the interaction index.
|
||||||
pub instance_aabb: Option<[f64; 6]>,
|
pub instance_aabb: Option<[f64; 6]>,
|
||||||
}
|
}
|
||||||
@@ -249,6 +252,7 @@ impl MeshLodSet {
|
|||||||
instance_transform: None,
|
instance_transform: None,
|
||||||
instance_handle: None,
|
instance_handle: None,
|
||||||
instance_color: None,
|
instance_color: None,
|
||||||
|
edge_color: None,
|
||||||
instance_aabb: None,
|
instance_aabb: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1412,13 +1412,12 @@ fn build_instanced_chunks(
|
|||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
let vertices_at = profile_enabled.then(iced::time::Instant::now);
|
let vertices_at = profile_enabled.then(iced::time::Instant::now);
|
||||||
|
let edge_base = first.set.edge_color.unwrap_or(first.display_color);
|
||||||
let edge_color = first
|
let edge_color = first
|
||||||
.set
|
.set
|
||||||
.visual_style
|
.visual_style
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or(first.display_color, |style| {
|
.map_or(edge_base, |style| style.edge_color(edge_base));
|
||||||
style.edge_color(first.display_color)
|
|
||||||
});
|
|
||||||
let edge_key = (source_handle, edge_color.map(f32::to_bits));
|
let edge_key = (source_handle, edge_color.map(f32::to_bits));
|
||||||
let shared_edge_buffer = (first.include_edges && !split_geometry)
|
let shared_edge_buffer = (first.include_edges && !split_geometry)
|
||||||
.then(|| buffers.edges.get(&edge_key).cloned())
|
.then(|| buffers.edges.get(&edge_key).cloned())
|
||||||
@@ -2215,12 +2214,11 @@ pub fn build_mesh_batch_filtered(
|
|||||||
let uv_mesh = part.uv_mesh;
|
let uv_mesh = part.uv_mesh;
|
||||||
let local_bounds = mesh_bounds(uv_mesh);
|
let local_bounds = mesh_bounds(uv_mesh);
|
||||||
let model_bounds = mesh_bounds(mesh);
|
let model_bounds = mesh_bounds(mesh);
|
||||||
|
let edge_base = set.edge_color.unwrap_or(part.display_color);
|
||||||
let edge_color = set
|
let edge_color = set
|
||||||
.visual_style
|
.visual_style
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or(part.display_color, |style| {
|
.map_or(edge_base, |style| style.edge_color(edge_base));
|
||||||
style.edge_color(part.display_color)
|
|
||||||
});
|
|
||||||
let vtx = |vi: usize,
|
let vtx = |vi: usize,
|
||||||
local_mapping_normal: Option<[f32; 3]>,
|
local_mapping_normal: Option<[f32; 3]>,
|
||||||
model_mapping_normal: Option<[f32; 3]>| {
|
model_mapping_normal: Option<[f32; 3]>| {
|
||||||
|
|||||||
@@ -3191,7 +3191,10 @@ analytic={:.1} regular={:.1} blocks={:.1}",
|
|||||||
let mut slots = rustc_hash::FxHashMap::default();
|
let mut slots = rustc_hash::FxHashMap::default();
|
||||||
let mut groups: Vec<Vec<&crate::scene::model::mesh_model::MeshLodSet>> = Vec::new();
|
let mut groups: Vec<Vec<&crate::scene::model::mesh_model::MeshLodSet>> = Vec::new();
|
||||||
for (index, set) in sets.iter().enumerate() {
|
for (index, set) in sets.iter().enumerate() {
|
||||||
let color = set.display_color().unwrap_or([0.0, 0.0, 0.0, 1.0]);
|
let color = set
|
||||||
|
.edge_color
|
||||||
|
.or_else(|| set.display_color())
|
||||||
|
.unwrap_or([0.0, 0.0, 0.0, 1.0]);
|
||||||
let key = match (&set.instance_source, set.instance_transform) {
|
let key = match (&set.instance_source, set.instance_transform) {
|
||||||
(Some(source), Some(transform)) => {
|
(Some(source), Some(transform)) => {
|
||||||
let matrix = &transform.matrix.m;
|
let matrix = &transform.matrix.m;
|
||||||
|
|||||||
@@ -594,7 +594,10 @@ fn fs_main(in: VertexOut) -> @location(0) vec4<f32> {
|
|||||||
// wireframe and hidden-line edge passes so lines read at their true colour.
|
// wireframe and hidden-line edge passes so lines read at their true colour.
|
||||||
@fragment
|
@fragment
|
||||||
fn fs_edge(in: EdgeVertexOut) -> @location(0) vec4<f32> {
|
fn fs_edge(in: EdgeVertexOut) -> @location(0) vec4<f32> {
|
||||||
return vec4<f32>(surface.face_color.rgb, 1.0);
|
// The edge buffers carry their own colour (keyed by it, so instances
|
||||||
|
// share a buffer only with the same colour): a visual style's edge
|
||||||
|
// colour, or colour 7 turned against the background (#1446).
|
||||||
|
return vec4<f32>(in.color.rgb, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Edge fragment for filled render modes: force black so edges frame the shaded
|
// Edge fragment for filled render modes: force black so edges frame the shaded
|
||||||
|
|||||||
Reference in new issue
Block a user