Page MenuHome

UV unwrap: Adjust cube projection size to fit object size
AbandonedPublic

Authored by Robert Guetzkow (rjg) on Mar 1 2021, 9:39 PM.

Details

Summary

This is patch is supposed to fix T85379. For the UV unwrapping method cube projection, Blender calculates the size of the cube improperly. For a cube object with 1m length in all dimensions (or any object with a bounding box of such dimension), the calculated cube size as displayed in the operator's properties, should be 1.0f. However, without this patch it is 2.0f. This patch fixes the calculation of cube_size to match the dimensions of the bounding box.

Diff Detail

Repository
rB Blender
Branch
2021-03-01-cube-proj (branched from master)
Build Status
Buildable 13183
Build 13183: arc lint + arc unit

Event Timeline

Robert Guetzkow (rjg) requested review of this revision.Mar 1 2021, 9:39 PM
Robert Guetzkow (rjg) created this revision.

This patch will likely need an update as ED_uvedit_add_simple_uvs also uses uvedit_unwrap_cube_project.

Robert Guetzkow (rjg) updated this revision to Diff 34616.EditedMar 1 2021, 10:47 PM
  • Adjust cube size for ED_uvedit_add_simple_uvs to match previous output

This has to do with the fact that blender primitives are always of size 2 by default, but that often needs to map to 1 somewhere else.
Just had another case today where this could cause problems, see D10632: Fix T86347: Add Primitive Tool fails for 1x1x1 scale

I think this just means that we cannot really read cube_size as being worldsize units.
If we do, than this patch improves the situation, but taking a step back I was wondering if this should not be reversed in the first place?
Isnt either the property description wrong or blender is doing it wrong?

Size of the cube to project on

I would expect my UVs to occupy less space if I increase the "size of the cube I am projecting on"?
And it would also mean that we could present the "real" size to the User.

For a 2x2x2 cube:

  • without this patch you are presented with a calculated cube size of 1
  • with this patch you are presented with a calculated cube size of 0.5

For a 1x1x1 cube:

  • without this patch you are presented with a calculated cube size of 2
  • with this patch you are presented with a calculated cube size of 1

dont want to hijack this, but what I mean is the following (which gives us the size from the bounds in the UI and scales UVs down when you increase the cube you are projecting on):

1
2
3diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
4index fc5f41e8ed5..ed927f41af8 100644
5--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
6+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
7@@ -2734,6 +2734,8 @@ static void uvedit_unwrap_cube_project(BMesh *bm,
8 zero_v3(loc);
9 }
10
11+ const float cube_size_inv = 1.0f / cube_size;
12+
13 /* choose x,y,z axis for projection depending on the largest normal
14 * component, but clusters all together around the center of map. */
15
16@@ -2746,8 +2748,8 @@ static void uvedit_unwrap_cube_project(BMesh *bm,
17
18 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
19 luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
20- luv->uv[0] = 0.5f + 0.5f * cube_size * (l->v->co[cox] - loc[cox]);
21- luv->uv[1] = 0.5f + 0.5f * cube_size * (l->v->co[coy] - loc[coy]);
22+ luv->uv[0] = 0.5f + cube_size_inv * (l->v->co[cox] - loc[cox]);
23+ luv->uv[1] = 0.5f + cube_size_inv * (l->v->co[coy] - loc[coy]);
24 }
25 }
26 }
27@@ -2793,7 +2795,7 @@ static int cube_project_exec(bContext *C, wmOperator *op)
28 float dims[3];
29 sub_v3_v3v3(dims, bounds[1], bounds[0]);
30 cube_size = max_fff(UNPACK3(dims));
31- cube_size = cube_size ? 2.0f / cube_size : 1.0f;
32+ cube_size = cube_size ? cube_size : 1.0f;
33 if (ob_index == 0) {
34 /* This doesn't fit well with, multiple objects. */
35 RNA_property_float_set(op->ptr, prop_cube_size, cube_size);
36@@ -2867,7 +2869,7 @@ void ED_uvedit_add_simple_uvs(Main *bmain, const Scene *scene, Object *ob)
37 }));
38 /* select all uv loops first - pack parameters needs this to make sure charts are registered */
39 ED_uvedit_select_all(bm);
40- uvedit_unwrap_cube_project(bm, 1.0, false, NULL);
41+ uvedit_unwrap_cube_project(bm, 2.0, false, NULL);
42 /* set the margin really quickly before the packing operation*/
43 scene->toolsettings->uvcalc_margin = 0.001f;
44 uvedit_pack_islands(scene, ob, bm);

@Philipp Oeser (lichtwerk) You're raising good points and I very much appreciate your input. If this is a more general issue that happens in other parts as well, perhaps this is something that should be discussed with the modeling module, so that we can decide how to solve this consistently?

OTOH, doing it like I suggested would probably need Addons to be updated? [ afaict, Blenderkit uses bpy.ops.uv.cube_project -- but already complains about the size of a unit cube as well ;) ]

@Philipp Oeser (lichtwerk) You're raising good points and I very much appreciate your input. If this is a more general issue that happens in other parts as well, perhaps this is something that should be discussed with the modeling module, so that we can decide how to solve this consistently?

Dropped a note in #modeling-module on https://blender.chat