From 762e98918f99dbf80a6af83e66218e85a3c902af Mon Sep 17 00:00:00 2001 From: Luke Miller Date: Fri, 31 Mar 2023 12:12:01 +1100 Subject: [PATCH] Add rotate to array modifier --- .../blender/makesdna/DNA_modifier_defaults.h | 1 + source/blender/makesdna/DNA_modifier_types.h | 3 +++ source/blender/makesrna/intern/rna_modifier.c | 21 +++++++++++++++++++ source/blender/modifiers/intern/MOD_array.cc | 9 ++++++++ 4 files changed, 34 insertions(+) diff --git a/source/blender/makesdna/DNA_modifier_defaults.h b/source/blender/makesdna/DNA_modifier_defaults.h index 44644d7eb78..2be83755690 100644 --- a/source/blender/makesdna/DNA_modifier_defaults.h +++ b/source/blender/makesdna/DNA_modifier_defaults.h @@ -26,6 +26,7 @@ .offset_ob = NULL, \ .offset = {1.0f, 0.0f, 0.0f}, \ .scale = {1.0f, 0.0f, 0.0f}, \ + .rotate = {0.0f, 0.0f, 0.0f}, \ .length = 0.0f, \ .merge_dist = 0.01f, \ .fit_type = MOD_ARR_FIXEDCOUNT, \ diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 7af83f8f888..76089f6b2b3 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -308,6 +308,8 @@ typedef struct ArrayModifierData { * 1 means the duplicates are 1 object-width apart. */ float scale[3]; + /** The amount to rotate each array item in XYZ */ + float rotate[3]; /** The length over which to distribute the duplicates. */ float length; /** The limit below which to merge vertices in adjacent duplicates. */ @@ -335,6 +337,7 @@ typedef struct ArrayModifierData { /** The number of duplicates to generate for #MOD_ARR_FIXEDCOUNT. */ int count; float uv_offset[2]; + float _pad; } ArrayModifierData; /** #ArrayModifierData.fit_type */ diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index cb75eb501a8..08c0864a558 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -2950,6 +2950,27 @@ static void rna_def_modifier_array(BlenderRNA *brna) "The size of the geometry will determine the distance between arrayed items"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "rotate_x", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_float_sdna(prop, NULL, "rotate[0]"); + RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); + RNA_def_property_ui_range(prop, DEG2RAD(-360.0), DEG2RAD(360.0), 10.0, 3); + RNA_def_property_ui_text(prop, "Rotate X", "Amount to rotate array items on the X axis"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "rotate_y", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_float_sdna(prop, NULL, "rotate[1]"); + RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); + RNA_def_property_ui_range(prop, DEG2RAD(-360.0), DEG2RAD(360.0), 10.0, 3); + RNA_def_property_ui_text(prop, "Rotate Y", "Amount to rotate array items on the Y axis"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "rotate_z", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_float_sdna(prop, NULL, "rotate[2]"); + RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); + RNA_def_property_ui_range(prop, DEG2RAD(-360.0), DEG2RAD(360.0), 10.0, 3); + RNA_def_property_ui_text(prop, "Rotate Z", "Amount to rotate array items on the Z axis"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + /* Vertex merging parameters */ prop = RNA_def_property(srna, "use_merge_vertices", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_ARR_MERGE); diff --git a/source/blender/modifiers/intern/MOD_array.cc b/source/blender/modifiers/intern/MOD_array.cc index 017eeb1eb0a..4c38e3326c5 100644 --- a/source/blender/modifiers/intern/MOD_array.cc +++ b/source/blender/modifiers/intern/MOD_array.cc @@ -78,6 +78,7 @@ static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *u static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) { ArrayModifierData *amd = (ArrayModifierData *)md; + bool need_transform_dependency = false; if (amd->start_cap != nullptr) { DEG_add_object_relation( @@ -281,6 +282,7 @@ static void mesh_merge_transform(Mesh *result, const bool recalc_normals_later) { using namespace blender; + int *index_orig; int i; MEdge *edge; @@ -460,6 +462,10 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, for (j = 3; j--;) { offset[3][j] += amd->scale[j] * (max[j] - min[j]); } + + rotate_m4(offset, 'X', amd->rotate[0]); + rotate_m4(offset, 'Y', amd->rotate[1]); + rotate_m4(offset, 'Z', amd->rotate[2]); } if (use_offset_ob) { @@ -880,6 +886,9 @@ static void relative_offset_draw(const bContext * /*C*/, Panel *panel) uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_relative_offset")); uiItemR(col, ptr, "relative_offset_displace", 0, IFACE_("Factor"), ICON_NONE); + uiItemR(col, ptr, "rotate_x", UI_ITEM_R_EXPAND, IFACE_("Rotate X"), ICON_NONE); + uiItemR(col, ptr, "rotate_y", UI_ITEM_R_EXPAND, IFACE_("Y"), ICON_NONE); + uiItemR(col, ptr, "rotate_z", UI_ITEM_R_EXPAND, IFACE_("Z"), ICON_NONE); } static void constant_offset_header_draw(const bContext * /*C*/, Panel *panel) -- 2.30.2