Page MenuHome

Multi-Button Drag: not working properly for Object Dimensions
Open, Confirmed, MediumPublic

Description

System Information
Windows 7

Blender Version
Broken: 2014-02-11

Short description of error
Multi-Button Drag - https://developer.blender.org/D270 - doesn't work properly in N panel for Dimensions

If you drag over all 3, only X and Z change, Y remains unchanged. As mouse button is released, the first selected property will reset, only the last hovered is kept (and scale changed)

Details

Type
To Do

Related Objects

Event Timeline

codemanx created this task.Feb 11 2014, 2:32 AM
codemanx raised the priority of this task from to Needs Triage by Developer.
codemanx updated the task description. (Show Details)
codemanx set Type to Bug.
codemanx added a subscriber: codemanx.
codemanx renamed this task from Multi-Button Drag: Only X and Z work for Object Dimensions to Multi-Button Drag: not working properly for Object Dimensions.Feb 11 2014, 2:36 AM
codemanx updated the task description. (Show Details)
Joshua Leung (aligorith) lowered the priority of this task from Needs Triage by Developer to Confirmed, Medium.Feb 11 2014, 4:31 AM

Object dimensions are broken and an abuse of RNA, IMHO - the same problem happens from Python and we had it reported too.

Basically they rely on one axis being set, then updating - before the other values are set.

This is in fact the same bug:

However since this is so user visible, it really should be addressed somehow, leaving open.

Uh, well, decided to have a quick look at this one, and I realized BKE_object_dimensions_set() was quite broken (just add two objects, parent one to the other, scale parent e.g. 0.5, and try setting dimension of child…). So I wrote this patch, and to my surprise it seems to also fix that bug!

1diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
2index 0970af4..cbb29d4 100644
3--- a/source/blender/blenkernel/intern/object.c
4+++ b/source/blender/blenkernel/intern/object.c
5@@ -2529,13 +2529,13 @@ void BKE_object_dimensions_set(Object *ob, const float *value)
6
7 mat4_to_size(scale, ob->obmat);
8
9- len[0] = bb->vec[4][0] - bb->vec[0][0];
10- len[1] = bb->vec[2][1] - bb->vec[0][1];
11- len[2] = bb->vec[1][2] - bb->vec[0][2];
12+ len[0] = fabsf(scale[0]) * (bb->vec[4][0] - bb->vec[0][0]);
13+ len[1] = fabsf(scale[1]) * (bb->vec[2][1] - bb->vec[0][1]);
14+ len[2] = fabsf(scale[2]) * (bb->vec[1][2] - bb->vec[0][2]);
15
16- if (len[0] > 0.f) ob->size[0] = value[0] / len[0];
17- if (len[1] > 0.f) ob->size[1] = value[1] / len[1];
18- if (len[2] > 0.f) ob->size[2] = value[2] / len[2];
19+ if (len[0] > 0.f) ob->size[0] *= value[0] / len[0];
20+ if (len[1] > 0.f) ob->size[1] *= value[1] / len[1];
21+ if (len[2] > 0.f) ob->size[2] *= value[2] / len[2];
22 }
23 }
24

Not sure this covers all possible situation (as already said in another related report, dimension can become rather involved in complex setups), but think it makes it at least less broken. ;)

Ok, so @Campbell Barton (campbellbarton) noticed previous patch failed when reaching zero value… Here is a new one, there are still some glitches around 0 in case of "grouped drag", but it’s still better (do not have yet idea to fix completely the zero-issue):

void BKE_object_dimensions_set(Object *ob, const float *value)
{
	BoundBox *bb = NULL;

	bb = BKE_object_boundbox_get(ob);
	if (bb) {
		float scale[3], len[3];
		int i = 3;

		mat4_to_size(scale, ob->obmat);

		len[0] = bb->vec[4][0] - bb->vec[0][0];
		len[1] = bb->vec[2][1] - bb->vec[0][1];
		len[2] = bb->vec[1][2] - bb->vec[0][2];

		while (i--) {
			float l = len[i], s = scale[i], v = value[i];

			if (l > 0.0f) {
				if (ELEM(0.0f, s, ob->size[i])) {
					ob->size[i] = v / l;
				}
				else {
					ob->size[i] *= v / (l * fabsf(s));
				}
			}
		}
	}
}

@Bastien Montagne (mont29), the patch mostly works well, but it has one strange behavior I noticed.

Pasting values into the buttons now fails.

  • Default cube
  • Set X scale to 2.0 (so X dimension is 4.0)
  • Copy the Y scale (1.0) and paste into the Y dimension (2.0) (Ctrl+C, Ctrl+V).
  • Keep pressing Ctrl+V
  • Y dimension cycles between 2.0 and 0.5 but never reaches 1.0.

I really think how this button works is broken, probably it shouldn't be using RNA at all and we could instead use callbacks so each situation can be handled better.

@Campbell Barton (campbellbarton) imho, it’s not RNA the issue here, it’s that (to handle correctly things like parent-related scaling), we need to use ob->obmat to get current object's scale, and yet we set ob->size. The problem is that in some cases (like e.g. pasting values), BKE_object_dimensions_set() is called twice or more without any object update in between, so ob->obmat becomes obsolete.

This quick (and dirty, obviously not a good solution as is, just could not find a nice way to get current scene here) hack “fixes” it:

1void BKE_object_dimensions_set(Object *ob, const float value[3])
2{
3 BoundBox *bb = NULL;
4
5 bb = BKE_object_boundbox_get(ob);
6 if (bb) {
7 float obmat[4][4];
8 float scale[3], len[3];
9 int i = 3;
10
11 mat4_to_size(scale, ob->obmat);
12
13 len[0] = bb->vec[4][0] - bb->vec[0][0];
14 len[1] = bb->vec[2][1] - bb->vec[0][1];
15 len[2] = bb->vec[1][2] - bb->vec[0][2];
16
17 print_v3("value", value);
18 print_v3("scale", scale);
19 print_v3("ob->size", ob->size);
20 print_v3("len", len);
21 printf("\n");
22
23 while (i--) {
24 float l = len[i], s = scale[i], v = value[i];
25
26 if (l > 0.0f) {
27 if (ELEM(0.0f, s, ob->size[i])) {
28 ob->size[i] = v / l;
29 }
30 else {
31 ob->size[i] *= v / (l * fabsf(s));
32 }
33 }
34 }
35 BKE_object_where_is_calc_mat4(G.main->scene.first, ob, ob->obmat);
36 }
37}

Now how to do this properly, I do not know really. Is it possible to get a valid scene from on object pointer? Or, probably better, to flush tagged updates in RNA update func?

@Bastien Montagne (mont29). the hack you propose could be made to work, but I would rather investigate some way to apply all buttons at once.

Or, redo the dimensions in C/ui.
dont use RNA for it, and have whatever hacks that are needed as callback functions for the C defined buttons.

@filip mond (vklidu), please only add useful information in posts.

Setting as TODO because this is an error in the way the RNA attribute works and its not some mistake to correct, The rna code has to work differently to support this for Python and the UI.

http://wiki.blender.org/index.php/Dev:2.5/Source/Development/Todo/UserInterface#UI_Widgets

Sorry, merged them the wrong way.

If you drag over all 3, only X and Z change, Y remains unchanged. As mouse button is released, the first selected property will reset, only the last hovered is kept (and scale changed)

Update (rBca58936f2ff2)
Works in the sidebar for some time, but is now broken in the object properties widget clone created in D5577.