Skip to content

Commit 5a5b918

Browse files
committed
Show only the product being oriented
The orient buttons rotated whichever product was active but left the whole batch on screen, so you were turning something that sat in the middle of everything else. Only Previous and Next hid anything, and only once you had pressed one. Rotating now isolates the active product as well, and does it before the rotation rather than after, since the maths reads matrices off the product and wants it in the view layer first. Isolate Active Product controls this and defaults to on. It applies from its update callback the moment it is ticked, so it does not sit there looking enabled until the next button press. Show All now clears the toggle as well as the state -- unhiding alone meant the next rotation hid everything again, which reads as the button not working. This is viewport state only. Render All already saves the exclude flags, isolates each product in turn and restores them, so leaving isolation on does not change what a batch renders.
1 parent 3070b1f commit 5a5b918

2 files changed

Lines changed: 50 additions & 9 deletions

File tree

‎README.md‎

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,19 @@ vector and an ortho/perspective toggle, and it gets built alongside the rest.
181181
modelled the same way. In practice a few arrive facing the wrong way, and this is where you
182182
turn them by hand.
183183

184-
**Previous** and **Next** step through the batch one product at a time, showing the current
185-
one and excluding the rest. That is the same isolation **Render All** uses, so what you see
186-
is what that product's render will contain. The list wraps, so you can keep pressing
187-
**Next** all the way round. **Show All** brings everything back when you are done.
184+
**Isolate Active Product** (on by default) means you only ever see the one you are working
185+
on. Rotating or stepping hides the others, so a product is never obscured by the rest of the
186+
batch while you are trying to orient it. The checkbox applies the moment you tick it, and
187+
unticking it brings everything back.
188+
189+
That is the same isolation **Render All** uses, so what you see is what that product's
190+
render will contain. It is viewport state only — a batch render saves it, isolates each
191+
product in turn, and puts it back afterwards, so leaving it switched on never changes what
192+
gets rendered.
193+
194+
**Previous** and **Next** step through the batch one product at a time. The list wraps, so
195+
you can keep pressing **Next** all the way round. **Show All** reveals every product and
196+
switches the checkbox off, so the next rotation does not immediately hide them again.
188197

189198
**Left**, **Right**, **Up** and **Down** turn the product that is currently showing:
190199

@@ -284,8 +293,9 @@ Standardize panel with **Rescale** enabled.
284293
the cameras. If only some products are wrong, Front Axis will not help — it moves the whole
285294
batch. Use *Orient Products* to turn the offenders individually, then rebuild.
286295

287-
**Only one product is visible in the viewport**: you left a *Previous* / *Next* review pass
288-
part way through, which excludes the others. Click **Show All** in Cameras / Views.
296+
**Only one product is visible in the viewport**: **Isolate Active Product** is on, which is
297+
the default while orienting. Click **Show All** in Cameras / Views, or untick the box.
298+
Renders are unaffected either way.
289299

290300
**Renders are cropped after rotating products**: rotating changes the bounding box the
291301
framing was measured from. Click *Build Cameras* again.

‎multiview_product_renderer/__init__.py‎

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,18 @@ class MV_CustomView(PropertyGroup):
148148
is_ortho: BoolProperty(name="Ortho", default=False)
149149

150150

151+
def _update_isolate(self, context):
152+
"""Apply the isolate toggle the moment it is ticked, rather than waiting
153+
for the next rotate or step.
154+
155+
Defined up here because the property below references it while the class
156+
body runs; the helpers it calls are resolved at call time, so they can live
157+
further down the file with the rest of the product code.
158+
"""
159+
coll, _ = active_product(context)
160+
isolate_product(context, coll.name if (self.isolate_active and coll) else None)
161+
162+
151163
class MV_Settings(PropertyGroup):
152164
step_files: CollectionProperty(type=MV_StepFileItem)
153165
step_files_index: IntProperty(default=0)
@@ -276,6 +288,13 @@ class MV_Settings(PropertyGroup):
276288
description="Which product the orientation buttons act on",
277289
default=0, min=0,
278290
)
291+
isolate_active: BoolProperty(
292+
name="Isolate Active Product",
293+
description="Show only the product being oriented and hide the rest. "
294+
"Batch renders are unaffected either way",
295+
default=True,
296+
update=_update_isolate,
297+
)
279298
rotate_step: FloatProperty(
280299
name="Rotate Step",
281300
description="How far one press of Left/Right/Up/Down turns the product",
@@ -1430,7 +1449,14 @@ def execute(self, context):
14301449
if coll is None:
14311450
self.report({'ERROR'}, f"No product collections under '{PRODUCT_COLL}'.")
14321451
return {'CANCELLED'}
1433-
step = context.scene.mv_settings.rotate_step
1452+
s = context.scene.mv_settings
1453+
# Isolate first, not after. Rotating reads matrices off the product, so
1454+
# it has to be in the view layer before the maths runs -- and it means
1455+
# you are looking at the thing you are turning while you turn it.
1456+
if s.isolate_active:
1457+
isolate_product(context, coll.name)
1458+
context.view_layer.update()
1459+
step = s.rotate_step
14341460
if not rotate_product(context, coll, self.direction, step):
14351461
self.report({'WARNING'}, f"'{coll.name}' has no geometry to rotate.")
14361462
return {'CANCELLED'}
@@ -1458,13 +1484,14 @@ def execute(self, context):
14581484
# Wraps, so a review pass round a batch never dead-ends on the last one.
14591485
idx = (idx + self.delta) % len(products)
14601486
s.active_product_index = idx
1461-
isolate_product(context, products[idx].name)
1487+
if s.isolate_active:
1488+
isolate_product(context, products[idx].name)
14621489
self.report({'INFO'}, f"{products[idx].name} ({idx + 1}/{len(products)})")
14631490
return {'FINISHED'}
14641491

14651492

14661493
class MV_OT_ShowAllProducts(Operator):
1467-
"""Bring every product back into the view layer"""
1494+
"""Turn isolation off and bring every product back into the view layer"""
14681495
bl_idname = "mv.show_all_products"
14691496
bl_label = "Show All"
14701497
bl_options = {'REGISTER', 'UNDO'}
@@ -1474,6 +1501,9 @@ def execute(self, context):
14741501
if not products:
14751502
self.report({'ERROR'}, f"No product collections under '{PRODUCT_COLL}'.")
14761503
return {'CANCELLED'}
1504+
# Clears the toggle as well as the state. Only unhiding would leave the
1505+
# next rotate to isolate again, which reads as the button not working.
1506+
context.scene.mv_settings.isolate_active = False
14771507
isolate_product(context, None)
14781508
self.report({'INFO'}, f"Showing all {len(products)} product(s).")
14791509
return {'FINISHED'}
@@ -1777,6 +1807,7 @@ def draw(self, context):
17771807
coll, idx = active_product(context)
17781808
box.label(text=f"{coll.name} ({idx + 1}/{len(products)})",
17791809
icon='OUTLINER_COLLECTION')
1810+
box.prop(s, "isolate_active")
17801811
box.prop(s, "rotate_step")
17811812

17821813
col = box.column(align=True)

0 commit comments

Comments
 (0)