Incorrect and Confusing Units for String to Curves Node #102906

Open
opened 2022-12-02 01:36:44 +01:00 by Harley Acheson · 22 comments
Member

System Information
Operating system: Windows-10-10.0.19044-SP0 64 Bits
Graphics card: NVIDIA GeForce GTX 745/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 517.48

Blender Version
Broken: version: 3.5.0 Alpha, branch: Unknown, commit date: Unknown Unknown, hash: rBUnknown
Worked: (newest version of Blender that worked as expected)

Short description of error
Incorrect and Confusing Units for String to Curves Node, depending on Scene / Units

Exact steps for others to reproduce the error
If Scene / Units is set to Metric this node looks like this:

{F13984816,width=100%}
Character spacing is shown in meters, and that is so odd that it might as well be shown in "number of chickens". Our current Character Spacing is already done strangely enough. This value is divided by 2 then 0.5f is subtracted from it. That value is a portion of the font's em square that is added to each character. So a value of 1 means no change to character spacing. 0 means that 0.5 of an em is subtracted from each one. That "1" means default is bad enough, but much worse to show it as one meter.

At minimum we should show this as unitless. Better would be to not do the division and shifting and therefore show "0" as default and add "em" as unit. This would match with CSS letter-spacing.

Word spacing is similar, but is a factor multiplied against each character's advance. So again, "1" means normal, 0 means that a space has no width, a 2 means a space is twice as wide. No relation to grid size. So showing "1 meter" is pretty bad.

This also should be unitless. Ideal would be to change it from a factor to a absolute value added to the width of space characters. That way it can also be "0" by default and show "em" as units. This would match with CSS word-spacing.

For even more oddness, this what it looks like in Imperial

{F13984832,width=100%}

As in normal and default character width and normal word spacing are shown as "3.28 inches"?

**System Information** Operating system: Windows-10-10.0.19044-SP0 64 Bits Graphics card: NVIDIA GeForce GTX 745/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 517.48 **Blender Version** Broken: version: 3.5.0 Alpha, branch: Unknown, commit date: Unknown Unknown, hash: `rBUnknown` Worked: (newest version of Blender that worked as expected) **Short description of error** Incorrect and Confusing Units for String to Curves Node, depending on Scene / Units **Exact steps for others to reproduce the error** If Scene / Units is set to Metric this node looks like this: {[F13984816](https://archive.blender.org/developer/F13984816/image.png),width=100%} Character spacing is shown in meters, and that is so odd that it might as well be shown in "number of chickens". Our current Character Spacing is already done strangely enough. This value is divided by 2 then 0.5f is subtracted from it. That value is a portion of the font's em square that is added to each character. So a value of **1 means no change** to character spacing. 0 means that 0.5 of an em is subtracted from each one. That "1" means default is bad enough, but much worse to show it as one meter. At minimum we should show this as unitless. Better would be to not do the division and shifting and therefore show "0" as default and add "em" as unit. This would match with CSS letter-spacing. Word spacing is similar, but is a factor multiplied against each character's advance. So again, "1" means normal, 0 means that a space has no width, a 2 means a space is twice as wide. No relation to grid size. So showing "1 meter" is pretty bad. This also should be unitless. Ideal would be to change it from a factor to a absolute value added to the width of space characters. That way it can also be "0" by default and show "em" as units. This would match with CSS word-spacing. For even more oddness, this what it looks like in Imperial {[F13984832](https://archive.blender.org/developer/F13984832/image.png),width=100%} As in normal and default character width and normal word spacing are shown as "3.28 inches"?
Author
Member

Added subscriber: @Harley

Added subscriber: @Harley
Author
Member

Line Spacing should also shown as unitless.

Although it seems correct at first. When Size is set to 1 then having Line Spacing set to 1 does give you 1 meter between lines. However, set the size to anything else and you will find that "1 meter" for line spacing is not actually one meter. It is actually 1em or so.

Line Spacing should also shown as unitless. Although it seems correct at first. When `Size` is set to 1 then having Line Spacing set to 1 does give you 1 meter between lines. However, set the size to anything else and you will find that "1 meter" for line spacing is not actually one meter. It is actually 1em or so.
Member

Changed status from 'Needs Triage' to: 'Confirmed'

Changed status from 'Needs Triage' to: 'Confirmed'
Member

Added subscriber: @PratikPB2123

Added subscriber: @PratikPB2123
Harley Acheson was assigned by Pratik Borhade 2022-12-02 17:11:15 +01:00
Member

Added subscriber: @HooglyBoogly

Added subscriber: @HooglyBoogly
Member

While I think some of your points make sense, I think there's some value to having units here, even when they're not perfectly aligned to world units in the end.

Actually, it seems like another way of thinking about it is that the font data scales the input sizes with units. If the font data is unit-less, that even makes sense conceptually.

Maybe a compromise would be to have one or two of these inputs have units, and the rest scale based off of that. For example, "Size" could have units, and the rest of the inputs could scale based on that.

While I think some of your points make sense, I think there's some value to having units here, even when they're not perfectly aligned to world units in the end. Actually, it seems like another way of thinking about it is that the font data scales the input sizes with units. If the font data is unit-less, that even makes sense conceptually. Maybe a compromise would be to have one or two of these inputs have units, and the rest scale based off of that. For example, "Size" could have units, and the rest of the inputs could scale based on that.
Author
Member

Character spacing is something that can be made tighter, or looser, or left the same.

We have made the odd decision of scaling the UI value so that "1" means "keep it the same". With it set that way the character spacing is default and normal. When the user selects "0" it means "make the spacing tighter by subtracting the width of an 'n' from every character. Setting it to "2" means "make the spacing wider by adding the width of an 'n' to each character in the string. Yes, it is that weird.

So the default of "1 meter" or "3.28 feet" has no relationship to real-world units of any kind. This UI setting is treated as "0" under the hood.

Or another way of looking at it... See that the same settings for 3D text objects outside of Geometry Nodes do not show units:

{F13998902,width=100%}

The subtypes were just set incorrectly when copying these to Geometry Nodes.

Character spacing is something that can be made tighter, or looser, or left the same. We have made the *odd* decision of scaling the UI value so that "1" means "keep it the same". With it set that way the character spacing is default and normal. When the user selects "0" it means "make the spacing tighter by subtracting the width of an 'n' from every character. Setting it to "2" means "make the spacing wider by adding the width of an 'n' to each character in the string. Yes, it is that weird. So the default of "1 meter" or "3.28 feet" has no relationship to real-world units of any kind. This UI setting is treated as "0" under the hood. Or another way of looking at it... See that the same settings for 3D text objects outside of Geometry Nodes do not show units: {[F13998902](https://archive.blender.org/developer/F13998902/image.png),width=100%} The subtypes were just set incorrectly when copying these to Geometry Nodes.
Author
Member

Another option is to change the property subtypes to PROP_PERCENTAGE. That would be the best match of what the user sets to the results they get.

Another option is to change the property subtypes to PROP_PERCENTAGE. That would be the best match of what the user sets to the results they get.

Added subscriber: @mod_moder

Added subscriber: @mod_moder

I think still measuring in chickens is not something that is suitable for procedural modeling. The height of the character should at least somewhere be in real units.

I think still measuring in chickens is not something that is suitable for procedural modeling. The height of the character should at least somewhere be in real units.
Member

The node should really give some way of mapping characters to real locations in the resulting geometry. Should letters be 1cm tall in general, or are they on a large billboard where they should be 1m tall?
To me that's a totally reasonable thing for the node to do. I understand the text code is really weird and does stuff like using an "n" for character spacing, but I think the conceptual goal of the sockets is more important for their units.

I'm not saying they should all be units-- sometimes the units really do conflict with each other. For example the "Size" has an influence on the absolute value of the other inputs in the end.
But having no way to map to a size in the world seems to be a regression in friendliness, it requires adding a separate transform node afterwards.
Maybe we just decide to require that, but then the default size of the letters seems very arbitrary, so I don't think that would be better.

The node should really give some way of mapping characters to real locations in the resulting geometry. Should letters be 1cm tall in general, or are they on a large billboard where they should be 1m tall? To me that's a totally reasonable thing for the node to do. I understand the text code is really weird and does stuff like using an "n" for character spacing, but I think the conceptual *goal* of the sockets is more important for their units. I'm not saying they should all be units-- sometimes the units really do conflict with each other. For example the "Size" has an influence on the absolute value of the other inputs in the end. But having no way to map to a size in the world seems to be a regression in friendliness, it requires adding a separate transform node afterwards. Maybe we just decide to require that, but then the default size of the letters seems very arbitrary, so I don't think that would be better.
Author
Member

@mod_moder - I think still measuring in chickens is not something that is suitable for procedural modeling. The height of the character should at least somewhere be in real units.

The font "size" could remain in real units if you like since that is sorta close, some times, maybe. The following fonts are all set to "1", but the heights vary from about 0.2 to about 0.8 meters in height. So not sure how useful showing "1 meter" is. It is really a scaling factor, not a linear measurement.

{F13998997,width=100%}

The other things: Character Spacing, Word Spacing and Line Spacing are just not real-world values. They are either factors or they are values that we have scaled so that they are nearly factors with "1" just being the mid-value, not a linear amount of anything.

> @mod_moder - I think still measuring in chickens is not something that is suitable for procedural modeling. The height of the character should at least somewhere be in real units. The font "size" could remain in real units if you like since that is sorta close, some times, maybe. The following fonts are all set to "1", but the heights vary from about 0.2 to about 0.8 meters in height. So not sure how useful showing "1 meter" is. It is really a scaling factor, not a linear measurement. {[F13998997](https://archive.blender.org/developer/F13998997/vfont2.gif),width=100%} The other things: Character Spacing, Word Spacing and Line Spacing are just not real-world values. They are either factors or they are values that we have scaled so that they are nearly factors with "1" just being the mid-value, not a linear amount of anything.
Member

It is really a scaling factor, not a linear measurement.

I hear your point, but I see the font size as a scaling factor for the size input. The final world units have to come from somewhere. Either they're implicit or they're exposed in a socket.

They are either factors or they are values that we have scaled so that they are nearly factors with "1" just being the mid-value, not a linear amount of anything.

Yeah, that makes sense. Either we change the way it works to use them as real linear values or change the units. The former sounds interesting in the long term, but might be tricky for backwards compatibility.

>It is really a scaling factor, not a linear measurement. I hear your point, but I see the font size as a scaling factor for the size input. The final world units have to come from somewhere. Either they're implicit or they're exposed in a socket. > They are either factors or they are values that we have scaled so that they are nearly factors with "1" just being the mid-value, not a linear amount of anything. Yeah, that makes sense. Either we change the way it works to use them as real linear values or change the units. The former sounds interesting in the long term, but might be tricky for backwards compatibility.

What I mean is that when you print text in any font (on paper), you can usually tell in advance what size the font will be. Often the user does not need to know it after the fact, but enter it directly.

What I mean is that when you print text in any font (on paper), you can usually tell in advance what size the font will be. Often the user does not need to know it after the fact, but enter it directly.
Author
Member

In #102906#1455446, @HooglyBoogly wrote:

It is really a scaling factor, not a linear measurement.

I hear your point, but I see the font size as a scaling factor for the size input. The final world units have to come from somewhere. Either they're implicit or they're exposed in a socket.

This patch makes the font sizes a little closer to each other: D16608: Refactor: VFont Metrics

Either we change the way it works to use them as real linear values...

Factors are always factors. Otherwise you could set that the character spacing is such that 0.02 meters is added to each character. But then the moment you change the font size you'd have to set that again. The same with line height - you don't want to reset that every time you change the size, you want that to be set with factor against the font size.

> In #102906#1455446, @HooglyBoogly wrote: >>It is really a scaling factor, not a linear measurement. > I hear your point, but I see the font size as a scaling factor for the size input. The final world units have to come from somewhere. Either they're implicit or they're exposed in a socket. This patch makes the font sizes a little closer to each other: [D16608: Refactor: VFont Metrics](https://archive.blender.org/developer/D16608) > Either we change the way it works to use them as real linear values... Factors are always factors. Otherwise you could set that the character spacing is such that 0.02 meters is added to each character. But then the moment you change the font size you'd have to set that again. The same with line height - you don't want to reset that every time you change the size, you want that to be set with factor against the font size.
Author
Member

I really feel like this issue has gotten more complex than it really is.

The code in Geometry Nodes does not do anything special; it has the same types of inputs with the same numerical ranges as for (regular old-style) Text Objects, calls the same functions, and gives a similar result.

But Text Objects set property types of "PROP_FLOAT, PROP_NONE" for size, space_line, space_word, and space_character (rna_curve.c) and therefore shows these inputs without units to users in the interface, regardless of scene units.

Geometry nodes sets these same inputs as "PROP_DISTANCE". This means that they display the same if Scene unit is None, but have "m" or "'" appended to the values if you set the scene units to Metric or Imperial. If you want these values to be real distances then you would have to do some further calculation, not just add an "m" to them, since they are factors, not distances.

I would love to discuss how we do this badly now and all the ways we could make it much better. But this problem is that there is accidentally appended "meters" and "feet" to values that are actually multiplication factors. Here is a user being confused by this: #102593 (Geometry nodes/Text Object: negative space character width). This is because he set "0 meters" for character spacing and "0 meters" for word spacing, unware that these were factors and that the units were meaningless.

I really feel like this issue has gotten more complex than it really is. The code in Geometry Nodes does not do anything special; it has the same types of inputs with the same numerical ranges as for (regular old-style) Text Objects, calls the same functions, and gives a similar result. But Text Objects set property types of "PROP_FLOAT, **PROP_NONE**" for size, space_line, space_word, and space_character (rna_curve.c) and therefore shows these inputs without units to users in the interface, regardless of scene units. Geometry nodes sets these same inputs as "PROP_DISTANCE". This means that they display the same if Scene unit is None, but have "m" or "'" appended to the values if you set the scene units to Metric or Imperial. If you want these values to be real distances then you would have to do some further calculation, not just add an "m" to them, since they are factors, not distances. I would *love* to discuss how we do this badly now and all the ways we could make it much better. But this problem is that there is accidentally appended "meters" and "feet" to values that are actually multiplication factors. Here is a user being confused by this: #102593 (Geometry nodes/Text Object: negative space character width). This is because he set "0 meters" for character spacing and "0 meters" for word spacing, unware that these were factors and that the units were meaningless.
Member

Added subscriber: @CharlieJolly

Added subscriber: @CharlieJolly

Added subscriber: @Vyach

Added subscriber: @Vyach

In #102906#1455442, @mod_moder wrote:
I think still measuring in chickens is not something that is suitable for procedural modeling. The height of the character should at least somewhere be in real units.

think, the best way is to have absolute and relative measurements or tools/parameters for these approaches.

As we have Set position with two inputs «position» and «offset» for example.

As far as fonts and characters are different we should use font-relative units as em or string height or may be [hy] height,
also we need relative points as baseline, proper character positions, and character width as metric and em units.
Because for text formatting it is more important to have ems, but when we want to match string with exact length, we need ability to know all real sizes.

@Harley
Yes, this is wide task to match a lot of needs of procedural modelling.
As I told erlier, we need addition to character and word-space width and we need character width multiplicator, to do exactly this (tracking/spacing multiplication):

2022-12-07_03-08-29.mp4

> In #102906#1455442, @mod_moder wrote: > I think still measuring in chickens is not something that is suitable for procedural modeling. The height of the character should at least somewhere be in real units. think, the best way is to have absolute and relative measurements or tools/parameters for these approaches. As we have Set position with two inputs «position» and «offset» for example. As far as fonts and characters are different we should use font-relative units as em or string height or may be [hy] height, also we need relative points as baseline, proper character positions, and character width as metric and em units. Because for text formatting it is more important to have ems, but when we want to match string with exact length, we need ability to know all real sizes. @Harley Yes, this is wide task to match a lot of needs of procedural modelling. As I told erlier, we need addition to character and word-space width and we need character width multiplicator, to do exactly this (tracking/spacing multiplication): [2022-12-07_03-08-29.mp4](https://archive.blender.org/developer/F14004177/2022-12-07_03-08-29.mp4)

In #102906#1455437, @Harley wrote:
Character spacing is something that can be made tighter, or looser, or left the same.

We have made the odd decision of scaling the UI value so that "1" means "keep it the same".

It is not odd, if 1 is a scale.

> In #102906#1455437, @Harley wrote: > Character spacing is something that can be made tighter, or looser, or left the same. > > We have made the *odd* decision of scaling the UI value so that "1" means "keep it the same". It is not odd, if 1 is a scale.
Author
Member

The reason that "1" is odd as the "normal" for character spacing is that it is a "shifted scale" so the under the hood that "1" is treated as zero. This means that a user cannot really select less than zero and they don't know what is happening at that zero point (a reduction in advance of an arbitrary 0.5f em).

Character spacing is best exposed to users like CSS does it (as "letter-spacing'). It is an amount ADDED to the advance of each character. This means that "0" is normal, 1 would be adding 1em to each character, and -1 would be removing 1em. And yes, this could also be exposed as absolute dimensions. This also means that there is no negative limit. https://w3c.github.io/csswg-drafts/css-text/#letter-spacing-property

CSS does similar for word spacing, where it also means an addition to the normal width of a space character (and U+00A0, U+1361, U+10100, U+10101, U+1039F, U+1091F0 . Again, with zero being normal. This also means you can have negative word spacing. https://w3c.github.io/csswg-drafts/css-text/#word-spacing-property

The reason that "1" is odd as the "normal" for character spacing is that it is a "shifted scale" so the under the hood that "1" is treated as zero. This means that a user cannot really select less than zero and they don't know what is happening at that zero point (a reduction in advance of an arbitrary 0.5f em). Character spacing is best exposed to users like CSS does it (as "letter-spacing'). It is an amount ADDED to the advance of each character. This means that "0" is normal, 1 would be adding 1em to each character, and -1 would be removing 1em. And yes, this could also be exposed as absolute dimensions. This also means that there is no negative limit. https://w3c.github.io/csswg-drafts/css-text/#letter-spacing-property CSS does similar for word spacing, where it also means an addition to the normal width of a space character (and U+00A0, U+1361, U+10100, U+10101, U+1039F, U+1091F0 . Again, with zero being normal. This also means you can have negative word spacing. https://w3c.github.io/csswg-drafts/css-text/#word-spacing-property

@Harley got it, thanks.

@Harley got it, thanks.
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
6 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#102906
No description provided.