[Bf-blender-cvs] [e9cb44f3de4] temp-geometry-nodes-text: Add Line and Pivot outputs to String to Curves

Erik noreply at git.blender.org
Thu Oct 28 23:29:01 CEST 2021


Commit: e9cb44f3de4237f64f82a98226285ea01f3cc711
Author: Erik
Date:   Thu Oct 28 23:26:49 2021 +0200
Branches: temp-geometry-nodes-text
https://developer.blender.org/rBe9cb44f3de4237f64f82a98226285ea01f3cc711

Add Line and Pivot outputs to String to Curves

===================================================================

M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc

===================================================================

diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index d5d2520ddf6..ff02be04351 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1566,7 +1566,8 @@ typedef struct NodeGeometryStringToCurves {
   uint8_t align_x;
   /* GeometryNodeStringToCurvesAlignYMode */
   uint8_t align_y;
-  char _pad[1];
+  /* GeometryNodeStringToCurvesPivotMode */
+  uint8_t pivot_mode;
 } NodeGeometryStringToCurves;
 
 typedef struct NodeGeometryDeleteGeometry {
@@ -2251,6 +2252,16 @@ typedef enum GeometryNodeStringToCurvesAlignYMode {
   GEO_NODE_STRING_TO_CURVES_ALIGN_Y_BOTTOM = 4,
 } GeometryNodeStringToCurvesAlignYMode;
 
+typedef enum GeometryNodeStringToCurvesPivotMode {
+  GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_MIDPOINT = 0,
+  GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_TOP_LEFT = 1,
+  GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_TOP_CENTER = 2,
+  GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_TOP_RIGHT = 3,
+  GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_BOTTOM_LEFT = 4,
+  GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_BOTTOM_CENTER = 5,
+  GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_BOTTOM_RIGHT = 6,
+} GeometryNodeStringToCurvesPivotMode;
+
 typedef enum GeometryNodeDeleteGeometryMode {
   GEO_NODE_DELETE_GEOMETRY_MODE_ALL = 0,
   GEO_NODE_DELETE_GEOMETRY_MODE_EDGE_FACE = 1,
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 6a36ef07dee..52ed8ede82f 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -11030,6 +11030,33 @@ static void def_geo_string_to_curves(StructRNA *srna)
       {0, NULL, 0, NULL, NULL},
   };
 
+  static const EnumPropertyItem rna_node_geometry_string_to_curves_pivot_mode[] = {
+      {GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_MIDPOINT, "MIDPOINT", 0, "Midpoint", "Midpoint"},
+      {GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_TOP_LEFT, "TOP_LEFT", 0, "Top Left", "Top Left"},
+      {GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_TOP_CENTER,
+       "TOP_CENTER",
+       0,
+       "Top Center",
+       "Top Center"},
+      {GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_TOP_RIGHT, "TOP_RIGHT", 0, "Top Right", "Top Right"},
+      {GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_BOTTOM_LEFT,
+       "BOTTOM_LEFT",
+       0,
+       "Bottom Left",
+       "Bottom Left"},
+      {GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_BOTTOM_CENTER,
+       "BOTTOM_CENTER",
+       0,
+       "Bottom Center",
+       "Bottom Center"},
+      {GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_BOTTOM_RIGHT,
+       "BOTTOM_RIGHT",
+       0,
+       "Bottom Right",
+       "Bottom Right"},
+      {0, NULL, 0, NULL, NULL},
+  };
+
   PropertyRNA *prop;
 
   prop = RNA_def_property(srna, "font", PROP_POINTER, PROP_NONE);
@@ -11062,6 +11089,13 @@ static void def_geo_string_to_curves(StructRNA *srna)
   RNA_def_property_enum_default(prop, GEO_NODE_STRING_TO_CURVES_ALIGN_Y_TOP_BASELINE);
   RNA_def_property_ui_text(prop, "Align Y", "");
   RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+  prop = RNA_def_property(srna, "pivot_mode", PROP_ENUM, PROP_NONE);
+  RNA_def_property_enum_sdna(prop, NULL, "pivot_mode");
+  RNA_def_property_enum_items(prop, rna_node_geometry_string_to_curves_pivot_mode);
+  RNA_def_property_enum_default(prop, GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_BOTTOM_LEFT);
+  RNA_def_property_ui_text(prop, "Pivot Point", "The pivot point used when rotating characters");
+  RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 }
 
 static void def_geo_separate_geometry(StructRNA *srna)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc b/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc
index 83526df3ac2..8523e3bc350 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc
@@ -44,8 +44,10 @@ static void geo_node_string_to_curves_declare(NodeDeclarationBuilder &b)
   b.add_input<decl::Float>("Line Spacing").default_value(1.0f).min(0.0f).subtype(PROP_DISTANCE);
   b.add_input<decl::Float>("Text Box Width").default_value(0.0f).min(0.0f).subtype(PROP_DISTANCE);
   b.add_input<decl::Float>("Text Box Height").default_value(0.0f).min(0.0f).subtype(PROP_DISTANCE);
-  b.add_output<decl::Geometry>("Curves");
+  b.add_output<decl::Geometry>("Curve");
   b.add_output<decl::String>("Remainder");
+  b.add_output<decl::Int>("Line").field_source();
+  b.add_output<decl::Vector>("Pivot Point").field_source();
 }
 
 static void geo_node_string_to_curves_layout(uiLayout *layout, struct bContext *C, PointerRNA *ptr)
@@ -65,6 +67,7 @@ static void geo_node_string_to_curves_layout(uiLayout *layout, struct bContext *
   uiItemR(layout, ptr, "overflow", 0, "", ICON_NONE);
   uiItemR(layout, ptr, "align_x", 0, "", ICON_NONE);
   uiItemR(layout, ptr, "align_y", 0, "", ICON_NONE);
+  uiItemR(layout, ptr, "pivot_mode", 0, IFACE_("Pivot Point"), ICON_NONE);
 }
 
 static void geo_node_string_to_curves_init(bNodeTree *UNUSED(ntree), bNode *node)
@@ -75,6 +78,7 @@ static void geo_node_string_to_curves_init(bNodeTree *UNUSED(ntree), bNode *node
   data->overflow = GEO_NODE_STRING_TO_CURVES_MODE_OVERFLOW;
   data->align_x = GEO_NODE_STRING_TO_CURVES_ALIGN_X_LEFT;
   data->align_y = GEO_NODE_STRING_TO_CURVES_ALIGN_Y_TOP_BASELINE;
+  data->pivot_mode = GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_BOTTOM_LEFT;
   node->storage = data;
   node->id = (ID *)BKE_vfont_builtin_get();
 }
@@ -95,10 +99,61 @@ static void geo_node_string_to_curves_update(bNodeTree *UNUSED(ntree), bNode *no
                                                                         N_("Text Box Width"));
 }
 
+static float3 get_pivot_point(GeoNodeExecParams &params, CurveEval &curve)
+{
+  const NodeGeometryStringToCurves &storage =
+      *(const NodeGeometryStringToCurves *)params.node().storage;
+  const GeometryNodeStringToCurvesPivotMode pivot_mode = (GeometryNodeStringToCurvesPivotMode)
+                                                             storage.pivot_mode;
+
+  float3 min(FLT_MAX), max(FLT_MIN), pivot;
+  curve.bounds_min_max(min, max, false);
+
+  /* Check if curve is empty. */
+  if (min.x == FLT_MAX) {
+    return {0.0f, 0.0f, 0.0f};
+  }
+
+  switch (pivot_mode) {
+    case GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_MIDPOINT:
+      pivot = (min + max) / 2;
+      break;
+    case GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_BOTTOM_LEFT:
+      pivot = float3(min.x, min.y, 0.0f);
+      break;
+    case GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_BOTTOM_CENTER:
+      pivot = float3((min.x + max.x) / 2, min.y, 0.0f);
+      break;
+    case GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_BOTTOM_RIGHT:
+      pivot = float3(max.x, min.y, 0.0f);
+      break;
+    case GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_TOP_LEFT:
+      pivot = float3(min.x, max.y, 0.0f);
+      break;
+    case GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_TOP_CENTER:
+      pivot = float3((min.x + max.x) / 2, max.y, 0.0f);
+      break;
+    case GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_TOP_RIGHT:
+      pivot = float3(max.x, max.y, 0.0f);
+      break;
+  }
+
+  return pivot;
+}
+
 struct TextLayout {
   /* Position of each character. */
   Vector<float2> positions;
 
+  /* Line number of each character. */
+  Vector<int> line_numbers;
+
+  /* Map of Pivot point for each character code. */
+  Map<int, float3> pivot_points;
+
+  /* UTF-32 Character codes. */
+  Array<char32_t> char_codes;
+
   /* The text that fit into the text box, with newline character sequences replaced. */
   std::string text;
 
@@ -180,10 +235,12 @@ static TextLayout get_text_layout(GeoNodeExecParams &params)
   Span<CharInfo> info{cu.strinfo, text_len};
   layout.final_font_size = cu.fsize_realtime;
   layout.positions.reserve(text_len);
+  layout.line_numbers.reserve(text_len);
 
   for (const int i : IndexRange(text_len)) {
     CharTrans &ct = chartransdata[i];
     layout.positions.append(float2(ct.xof, ct.yof) * layout.final_font_size);
+    layout.line_numbers.append(ct.linenr);
 
     if ((info[i].flag & CU_CHINFO_OVERFLOW) && (cu.overflow == CU_OVERFLOW_TRUNCATE)) {
       const int offset = BLI_str_utf8_offset_from_index(layout.text.c_str(), i + 1);
@@ -193,6 +250,12 @@ static TextLayout get_text_layout(GeoNodeExecParams &params)
     }
   }
 
+  /* Convert UTF-8 encoded string to UTF-32. */
+  len_chars = BLI_strlen_utf8_ex(layout.text.c_str(), &len_bytes);
+  Array<char32_t> char_codes_with_null(len_chars + 1);
+  BLI_str_utf8_as_utf32(char_codes_with_null.data(), layout.text.c_str(), len_chars + 1);
+  layout.char_codes = char_codes_with_null.as_span().drop_back(1);
+
   MEM_SAFE_FREE(chartransdata);
   MEM_SAFE_FREE(cu.str);
   MEM_SAFE_FREE(cu.strinfo);
@@ -203,15 +266,14 @@ static TextLayout get_text_layout(GeoNodeExecParams &params)
 
 /* Returns a mapping of UTF-32 character code to instance handle. */
 static Map<int, int> create_curve_instances(GeoNodeExecParams &params,
-                                            const float fontsize,
-                                            const Span<char32_t> charcodes,
+                                            TextLayout &layout,
                                             InstancesComponent &instance_component)
 {
   VFont *vfont = (VFont *)params.node().id;
   Map<int, int> handles;
 
-  for (int i : charcodes.index_range()) {
-    if (handles.contains(charcodes[i])) {
+  for (int i : layout.char_codes.index_range()) {
+    if (handles.contains(layout.char_codes[i])) {
       continue;
     }
     Curve cu = {{nullptr}};
@@ -221,36 +283,103 @@ static Map<int, int> create_curve_instances(GeoNodeExecParams &params,
     CharInfo charinfo = {0};
     charinfo.mat_nr = 1;
 
-    BKE_vfont_build_char(&cu, &cu.nurb, charcodes[i], &charinfo, 0, 0, 0, i, 1);
+    BKE_vfont_build_char(&cu, &cu.nurb, layout.char_codes[i], &charinfo, 0, 0, 0, i, 1);
     std::unique_ptr<CurveEval> curve_eval = curve_eval_from_dna_curve(cu);
     BKE_nurbList_free(&cu.nurb);
+
+    float3 pivot_point = get_pivot_point(params, *curve_eval);
+    layout.pivot_points.add_new(layout.char_codes[i], pivot_point);
+
     float4x4 size_matrix = float4x4::identity();
-    size_matrix.app

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list