layer.create: the instance copy takes the source's Solo switch

A soloed model keeps its Solo switch with its video off, and any_solo
hides non-soloed layers: the copy was excluded and the comp rendered
blank. The copy now takes the Solo over; the source's video stays off.
Covered by instance3d_keeps_the_copy_visible_when_the_source_is_soloed.
This commit is contained in:
Minher0
2026-10-27 09:46:32 +00:00
parent db1f798455
commit 36a50a6366
2 changed files with 27 additions and 0 deletions
+3
View File
@@ -52,6 +52,9 @@ fn create(s: &mut Session, p: &Value) -> Result<Value> {
ItemKind::Solid(Solid { color: [1.0, 1.0, 1.0], width: comp.width, height: comp.height, pixel_aspect: 1.0 }),
);
let mut l = build::layer(proj, &comp, &name, LayerSource::Solid { item: sid }, (comp.width, comp.height), None);
// A soloed source keeps its Solo switch with video off, and any_solo hides
// the non-soloed copy: the copy takes the Solo over to stay visible.
l.switches.solo = src.switches.solo;
// CC Composite referencing the 3D layer: the solid shows its render (the 2D
// copy).
let fx = effectcraft_effects::find("ec.channel.cccomposite").ok_or_else(|| bad("layer.create", "the CC Composite effect is missing"))?;
+24
View File
@@ -231,3 +231,27 @@ fn instance3d_shows_nothing_outside_the_source_layer_range() {
let outside = s.render(comp, Tick::from_seconds_f64(1.5), RenderOpts::default());
assert!(outside.data.iter().all(|p| p[3] < 1e-3), "transparent after the source's out point: {:?}", px(&outside, 320, 180));
}
#[test]
fn instance3d_keeps_the_copy_visible_when_the_source_is_soloed() {
let mut s = session();
let model = triangle_model(&mut s);
let comp = cid(&s);
// Solo the model, then create the instance: any_solo hides non-soloed layers and the
// source's video goes off, so the copy has to take the Solo over.
s.edit("solo", None, |p, _| {
p.comp_mut(comp).unwrap().layer_mut(LayerId(model)).unwrap().switches.solo = true;
Ok(())
})
.unwrap();
let before = s.render(comp, Tick::ZERO, RenderOpts::default());
assert!(px(&before, 320, 180)[3] > 0.9, "the soloed model shows: {:?}", px(&before, 320, 180));
s.execute("layer.select", json!({"layers": [model]})).unwrap();
let r = s.execute("layer.create", json!({"op": "instance3d"})).unwrap();
let solid = r["layers"][0].as_u64().unwrap();
assert!(layer_in(&s, comp, solid).switches.solo, "the copy takes the source's Solo switch");
assert!(!layer_in(&s, comp, model).switches.video, "the source keeps its video off");
let after = s.render(comp, Tick::ZERO, RenderOpts::default());
assert!(px(&after, 320, 180)[3] > 0.9, "the soloed copy shows the model: {:?}", px(&after, 320, 180));
assert!(close(&before, &after, 2e-2), "the comp renders the same through the copy:\n{:?}\n{:?}", px(&before, 320, 180), px(&after, 320, 180));
}