Commit: 98df4c40407fffa195a301e2492112d84f6a31e3 Author: Erik Date: Thu Oct 28 23:26:49 2021 +0200 Branches: temp-geometry-nodes-text https://developer.blender.org/rB98df4c40407fffa195a301e2492112d84f6a31e3
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 95e94a22d81..04b48dbebf3 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 @@ -56,8 +56,10 @@ static void geo_node_string_to_curves_declare(NodeDeclarationBuilder &b) .default_value(0.0f) .min(0.0f) .subtype(PROP_DISTANCE); - b.add_output<decl::Geometry>(N_("Curves")); + b.add_output<decl::Geometry>(N_("Curve")); b.add_output<decl::String>(N_("Remainder")); + b.add_output<decl::Int>(N_("Line")).field_source(); + b.add_output<decl::Vector>(N_("Pivot Point")).field_source(); } static void geo_node_string_to_curves_layout(uiLayout *layout, struct bContext *C, PointerRNA *ptr) @@ -77,6 +79,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) @@ -87,6 +90,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(); } @@ -107,10 +111,61 @@ static void geo_node_string_to_curves_update(bNodeTree *UNUSED(ntree), bNode *no N_("Text Box Width")); } +static float3 get_pivot_point(GeoNodeExecParams ¶ms, 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; @@ -192,10 +247,12 @@ static TextLayout get_text_layout(GeoNodeExecParams ¶ms) 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); @@ -205,6 +262,12 @@ static TextLayout get_text_layout(GeoNodeExecParams ¶ms) } } + /* 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); @@ -215,15 +278,14 @@ static TextLayout get_text_layout(GeoNodeExecParams ¶ms) /* Returns a mapping of UTF-32 character code to instance handle. */ static Map<int, int> create_curve_instances(GeoNodeExecParams ¶ms, - 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}}; @@ -233,36 +295,103 @@ static Map<int, int> create_curve_instances(GeoNodeExecParams ¶ms, 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.apply_scale(fontsize); + size_matrix.apply_scale(layout.final_font_size); curve_eval->transform(size_matrix); GeometrySet geometry_set_curve = GeometrySet::create_with_curve(curve_eval.re @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs