does not work together with "Separate Units" yet
- only for length, area, volume, mass and time for now
I think it would better to get rid of the "Fixed Units" setting, it feels a bit like a setting added onto a design rather than really integrated. Instead we could have an "Adaptive" item in the enums for each.
Is getting Separate Units to work difficult? I would expect it to basically take the fixed unit as the maximum unit to display, but then it can still separate for smaller units.
This unit should also be used as the default unit when typing in values. Right now when you set Length to Centimeters and type in 10, it shows 1000cm which I think is unexpected. This should work in buttons and when typing values while transforming.
There is also this function which might need to be updated: https://docs.blender.org/api/current/bpy.utils.units.html?highlight=to_value#bpy.utils.units.to_value
Will have to check how to do it in a nice way...(like maybe you should be able to pass scene.unit_settings into it? (maybe you can do that already, haven't tested it)
Hi Jacques, Brecht, I have a few points I want to address from a user point of view:
Remove adaptive unit setting
What is the reasoning for keeping legacy behaviour? Adaptive nature of current unit system is why people do not use it.
It would be better for both maintainers and users with adaptive units removed.
No reason to keep them around anymore.
Unit system improvements look marvelous! Great job Jaques!
Thank you, glad you like it.
I'm not sure whether we should remove the adaptive behavior. But I guess you discussed it enough, so I'll remove it :)
Right, the presets should be removed, I did not even know they are there haha
Well people might not know better. It would be interesting to see how many of them would stick to adaptive after this patch goes in.
Then at least let's make "fixed units" the default for every unit type.
I could not tell from the code changes, does units.to_string support "fixed units"?
In 2.7 i get this output:
>>> bpy.utils.units.to_string('METRIC', 'LENGTH', 1) '1m' >>> bpy.utils.units.to_string('METRIC', 'LENGTH', 0.001) '1mm'
With this patch it would be useful to specify the unit:
>>> bpy.utils.units.to_string('METRIC', 'LENGTH', 'MILLIMETERS', 1) '1000mm' >>> bpy.utils.units.to_string('METRIC', 'LENGTH', 'MILLIMETERS', 0.001) '1mm'
Add-ons like 3D Print Toolbox could use that, currently it's a bunch of ugly boilerplate code to do the same.
one thing that is a bit ugly is that I have to use +1 and -1 quite often due to the way units are organized.
A simple fix would be to use a signed data type in the dna, so that Adaptive could mean -1. Unfortunately it looks like signed char is not allowed in the dna.
I could use another type like short, but 2 bytes are not really needed for just ~10 different values.
I'm unsure about what's the best way to extend the to_string method. Just passing in an UnitSettings instance seems relatively easy. In the other side it would definitely be more helpful if an addon developer could use the function the way you describe it, but that would mean we need many kinds of different checks and conversions. (I think)
[EDIT:] Also this function call bpy.utils.units.to_string('METRIC', 'LENGTH', 'MILLIMETERS', 1) is very redundant. Everything could be derived from bpy.utils.units.to_string(1, 'MILLIMETERS'). However that might not work for all units, e.g. 'ton'...
to_string should not be affected by the scene settings (or it should be possible to override them). Or developers would be forced to change scene settings first, before using to_string if they need output in certain units (I hate so much when this happens).
...is very redundant. Everything could be derived from bpy.utils.units.to_string(1, 'MILLIMETERS')
That makes perfect sense!
However it does not make sooo much sense to have this function bpy.utils.units.to_string(1, 'MILLIMETERS') because all it does is appending mm to the number, basically. Also it is not clear what unit the 1 has.
For a setting in the scene, a few bytes of memory usage is not a concern at all. Only for data that is e.g. per vertex do we really care.
Anyway, I think just set ADAPTIVE = 255 should work, or whatever the maximum value is if you increase the size.
I'm unsure about what's the best way to extend the to_string method. Just passing in an UnitSettings instance seems relatively easy. In the other side it would definitely be more helpful if an addon developer could use the function the way you describe it, but that would mean we need many kinds of different checks and conversions.
I think there are just two different use cases that require two different functions. One is to display a length following the rest of the UI, and that can take the scene unit settings. And then the other would be to display it with a specific unit where you pass all the parameters in manually.
In this function input is always a scene unit. In this case function will do some math
with the unit scale value and output 1000mm.
Edit: Unit Scale scene setting does not affect to_string function.
In this case function will do some math with the unit scale value
Correction: currently to_string will always assume Unit Scale to be 1.0, so developers would do Unit Scale conversion manually before passing the value to function. Which makes sense, Unit Scale conversion is not complicated and is optional, so please ignore that part.
Can we change the API in a separate patch?
It feels like a separate change, not directly related to how units are handled in the scene.
My boilerplate code for handling units is not going anywhere, I can wait, so no pressure.
Only very minor comments now.
Code style: use /* */ for comments.
Let's extend this tooltip to explain what this is now useful for, compared to the other units.
"Scale to use when converting between blender units and dimensions. When working at microscopic or astronomical scale, a small or large unit scale respectively can be used to avoid numerical precision problems."
Hi Jacques, hi guys! I just saw Pablo's notification and video and wanted to say big thanks! Been waiting (and probably not alone) for this for so long. Didn't try it yet, but judging from the video, it seems like a nice implementation. Congrats!
One thing i noticed in the video though, is the term 'length'. I could be wrong, since English is not my native, but being in the engineering field i feel the term fell a bit short in that category - as i see it, length is just one of 'dimensional' properties of a certain body, such as height and width.
Could it be that the term 'distance' is a more appropriate and generic term for that property? I feel it corresponds more correctly to a property of 'apartness' between two points - which in itself could include length, width, height of an object as well as the distance between objects.
Don't know, could be wrong, wikipedia leans both ways:
Thanks for your comment. I'm not 100% sure what is correct but I think length is better than distance.
Also because the unit will not only be used for distances but also areas etc.
Here it says the quantity name is "length": https://en.wikipedia.org/wiki/International_System_of_Units
Not directly related, but anyway .. ref 
Maybe we could tackle inconsistency with default values for length in python.
Expecting a single default value to generate same result whatever the unit system, for real-world objects like bolts or mountains.
As it, it is not the case, objects size are unit system dependents -> creating cubes with metric or imperial system lead to different cubes sizes.
Fortunately there is a simple solution to handle this and fix all those issues at once.
Unit conversion must not occur on default values !
We must only divide default by unit scale and always define default values as meter.
This way objects size will remains consistent and correct whatever the unit system is.
default size in meter / unit scale = blender unit.
So a cube with 1 (meter) as default will remains the same cube when created using imperial feet as unit.
 rightclickselect post