This patch adds a node that generates a text paragraph as curve instances.
Details
Diff Detail
- Repository
- rB Blender
Event Timeline
Some thoughts:
- This is great!
- In "Truncate" mode it would be really cool to have a string output of all the text that didn't fit into the box
- The "Rotation" input seems to make the other inputs not work
- The fields can have PROP_TRANSLATION, PROP_EULER, and PROP_XYZ
- "Char Spacing" should be "Character Spacing"
- The node could be a bit wider by default, it looks very vertical right now
- Maybe "Charcode Offset" is useful in some cases, but I don't think we should expose it like that. I think it's better to separate the intricacies of string processing into separate nodes or separate design discussions.
- Proper description in the RNA properties would be helpful
- The node could output anonymous attributes on the spline domain for character index, word index, and line index for further processing afterwards
- I guess the internal pointcloud is to make the field evaluation work? Hopefully that won't be necessary in the proper fields implementation ;)
Great idea.
- The "Rotation" input seems to make the other inputs not work
Yeah, something is wrong with that.
- Maybe "Charcode Offset" is useful in some cases, but I don't think we should expose it like that. I think it's better to separate the intricacies of string processing into separate nodes or separate design discussions.
Yes that makes sense.
Are you using a debug build? I had some assert fail when changing the min width, in truncate mode I think.
BLI_assert failed: source/blender/blenkernel/intern/font.c:970, vfont_to_curve(), at 'compare_ff_relative(x_used, x_available, 1.19209289550781250000000000000000000e-7F, 64)'
| source/blender/depsgraph/intern/builder/deg_builder_nodes.cc | ||
|---|---|---|
| 1776 ↗ | (On Diff #41830) | Looks like this debug print should be removed. |
| source/blender/makesdna/DNA_node_types.h | ||
| 1452–1455 ↗ | (On Diff #41830) | Include comments above the variables mentioning the enum types, like other structs above. |
| source/blender/makesrna/intern/rna_nodetree.c | ||
| 572–578 | These should have proper descriptions. Some initial suggestions based on the behavior I'm observing:
| |
| 576 | Property names should be title case. | |
| 583–620 | Maybe just copy the descriptions from the text object RNA here? | |
Is that with or without rB56f8d7c70597: Fix T89241: Scale to fit overflows into a second line
?
See @Philipp Oeser (lichtwerk)’s comment here:
T91401#1219885
Rewritten to output instances of curves for each character instead of one single curve. This will make it much easier to manipulate the text further.
| source/blender/nodes/geometry/nodes/node_geo_string_to_curve.cc | ||
|---|---|---|
| 58 ↗ | (On Diff #41878) | Does this mean we can no longer separate by lines? |
- I'm getting an assert in truncate mode: BLI_assert failed: source/blender/nodes/geometry/nodes/node_geo_string_to_curve.cc:311, add_instances_from_component(), at 'charcodes.length() == domain_size'
- Type asdf asdf
- Switch to truncate mode
- Make max width greater than 0
- Increasing max width tends to move the characters to the right, when I think they should stay centered in this case
- Jacques has been working on D12557: Geometry Nodes: New Transform Instances node (WIP). to transform instances. We discussed moving the per-character transforms there-- maybe that makes sense to do? It would definitely be nice to make this node simpler!
- If we go this way, seems to me like we basically have something similar to the old named attribute workflow back here, but just so much better.
| source/blender/nodes/geometry/nodes/node_geo_string_to_curve.cc | ||
|---|---|---|
| 112 ↗ | (On Diff #42048) | const StringRef text |
| 113 ↗ | (On Diff #42048) | Floats can be passed by value |
| 166–167 ↗ | (On Diff #42048) | These aren't return variables, since they're local functions. Suggest text_size and text_free |
| 169–170 ↗ | (On Diff #42048) | Looking at this code path, it looks like the curve data is generated for every single character here, only to be created later again when you call BKE_vfont_build_char The API is pretty awful, but I wonder if one of the options like FO_DUPLI calculate only the character positions to avoid the extra work here. |
| 181 ↗ | (On Diff #42048) | for (const int i : IndexRange(text_size)) {
CharTrans &ct = char_trans_data[i];
...
} |
| 204–205 ↗ | (On Diff #42048) | Generally it's preferable to use StringRef instead of a const reference to a string. Though I won't speak for the strings of non-char types elsewhere in this file. |
| 280 ↗ | (On Diff #42048) | add_overwrite seems wrong here, since you already tested with contains above. We should really avoid generating the same character twice |
| 304–305 ↗ | (On Diff #42048) | I don't think this is true, this node creates an instances component from scratch. |
| 58 ↗ | (On Diff #41878) | Right, that would wait until we support attributes on the instances component, which shouldn't be too hard. |
- Fixed all review comments.
- Text now line-breaks at all characters above extended ascii.
- I think this is close, it's certainly nice how this patch keep getting simpler!
- Pivot mode can be removed for now, we can add it back later when it's useful.
- The fix for line wrapping with non-ascii characters should be a separate patch, not part of this one.
- Mostly small comments about the code inline.
| source/blender/makesrna/intern/rna_nodetree.c | ||
|---|---|---|
| 571–666 | These enums can be defined directly in def_geo_string_to_curve. | |
| 576–587 | The final periods are added to descriptions automatically and don't need to be added here. | |
| 10507–10511 | The pivot point property doesn't do anything in the patch now, and should be removed. | |
| source/blender/nodes/geometry/nodes/node_geo_string_to_curve.cc | ||
| 138 ↗ | (On Diff #42205) | I would suggest returning a struct like this rather than changing the input parameters: struct TextLayout {
Vector<float3> positions;
/* The part of the input curve that didn't fit in the text box. Only set in truncate mode. */
std::optional<StringRef> truncated_text;
/* This should have a comment about what it means. */
float size;
};This way it's more clear what is an input and what is an output. |
| 157–158 ↗ | (On Diff #42205) | const |
| 192 ↗ | (On Diff #42205) | If you're just freeing the r_text after the function, do you have to give it as an argument? Or could you just pass null? |
| 194 ↗ | (On Diff #42205) | Add a comment about the FO_DUPLI argument, and the reason for that. (Did you verify that it does what I thought?) |
| 204 ↗ | (On Diff #42205) | Here you can reserve text_size size in the vector to avoid reallocation when it grows. |
| 236 ↗ | (On Diff #42205) | What's the runtime of std::string::replace? I wonder if it would be more efficient to build a separate string, since this might require moving the characters after the replacement? |
| 241 ↗ | (On Diff #42205) | Add a comment about the meaning of the map this function returns. |
| 271 ↗ | (On Diff #42205) | Is calling this necessary? I'm not sure what the purpose would be. |
| 289–290 ↗ | (On Diff #42205) | It seems simpler to avoid assigning a temporary value here. |
| 305 ↗ | (On Diff #42205) | Zero size is what the vector gets by default, no need to do that explicitly. |
| 322 ↗ | (On Diff #42205) | Pivot points are unused, the related functions and variables should be removed for now. |
It's so fast now with curve fill, this is great! Pretty close now, the only issue I found this time was this one with newlines:
Here are some smaller cleanups to this patch: P2423
- Use float2 for position vector
- Don't use unique_ptr for text layout, just return directly
- Reorder some things, remove unnecessary checks
- Add float4x4 from location constructor, use "apply_scale" instead of creating the matrix from a 0 rotation
| source/blender/nodes/geometry/nodes/node_geo_string_to_curve.cc | ||
|---|---|---|
| 101 ↗ | (On Diff #42260) | Always use braces: https://wiki.blender.org/wiki/Style_Guide/C_Cpp#Braces |
| 258 ↗ | (On Diff #42260) | Span is small (16 bytes) and should be passed by value, otherwise it adds another pointer indirection to element access (if not optimized away). |
- Applied patch supplied by Hans (thanks!)
- Removed all special handling of the newline character. This simplifies the code and also means the input string length will match the number of instances added to the output.
The code looks good now. The newline character patch is essential now, but that can be committed just before this.
I'll bring this up at the meeting tomorrow before committing it. Actually, if you could update the patch before with a comment about the size of the allocations, that would be great!
Nice job, this has really come a long way!
| source/blender/makesrna/intern/rna_nodetree.c | ||
|---|---|---|
| 10405 | fits -> fit I think "for the text" is obvious here and could be dropped to make the description shorter. Also there is an unnecessary line break here. | |
| source/blender/nodes/geometry/nodes/node_geo_string_to_curve.cc | ||
| 21 ↗ | (On Diff #42322) | The pointcloud includes are unused now. |
| 160–161 ↗ | (On Diff #42322) | Maybe it's worth adding a comment about + sizeof(char32_t) and + 4 here. |
I made a couple changes when committing:
- Hide max height in overflow mode, change socket label for width
- Rename an enum to be a bit shorter
- Add a comment about unknown reason for 1 character over-allocation.


