Changeset View
Changeset View
Standalone View
Standalone View
source/blender/modifiers/intern/MOD_array.cc
- This file was moved from source/blender/modifiers/intern/MOD_array.c.
| Show First 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData) | ||||
| walk(userData, ob, (ID **)&amd->curve_ob, IDWALK_CB_NOP); | walk(userData, ob, (ID **)&amd->curve_ob, IDWALK_CB_NOP); | ||||
| walk(userData, ob, (ID **)&amd->offset_ob, IDWALK_CB_NOP); | walk(userData, ob, (ID **)&amd->offset_ob, IDWALK_CB_NOP); | ||||
| } | } | ||||
| static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) | static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) | ||||
| { | { | ||||
| ArrayModifierData *amd = (ArrayModifierData *)md; | ArrayModifierData *amd = (ArrayModifierData *)md; | ||||
| bool need_transform_dependency = false; | bool need_transform_dependency = false; | ||||
| if (amd->start_cap != NULL) { | if (amd->start_cap != nullptr) { | ||||
| DEG_add_object_relation( | DEG_add_object_relation( | ||||
| ctx->node, amd->start_cap, DEG_OB_COMP_GEOMETRY, "Array Modifier Start Cap"); | ctx->node, amd->start_cap, DEG_OB_COMP_GEOMETRY, "Array Modifier Start Cap"); | ||||
| } | } | ||||
| if (amd->end_cap != NULL) { | if (amd->end_cap != nullptr) { | ||||
| DEG_add_object_relation( | DEG_add_object_relation( | ||||
| ctx->node, amd->end_cap, DEG_OB_COMP_GEOMETRY, "Array Modifier End Cap"); | ctx->node, amd->end_cap, DEG_OB_COMP_GEOMETRY, "Array Modifier End Cap"); | ||||
| } | } | ||||
| if (amd->curve_ob) { | if (amd->curve_ob) { | ||||
| DEG_add_object_relation( | DEG_add_object_relation( | ||||
| ctx->node, amd->curve_ob, DEG_OB_COMP_GEOMETRY, "Array Modifier Curve"); | ctx->node, amd->curve_ob, DEG_OB_COMP_GEOMETRY, "Array Modifier Curve"); | ||||
| DEG_add_special_eval_flag(ctx->node, &amd->curve_ob->id, DAG_EVAL_NEED_CURVE_PATH); | DEG_add_special_eval_flag(ctx->node, &amd->curve_ob->id, DAG_EVAL_NEED_CURVE_PATH); | ||||
| } | } | ||||
| if (amd->offset_ob != NULL) { | if (amd->offset_ob != nullptr) { | ||||
| DEG_add_object_relation( | DEG_add_object_relation( | ||||
| ctx->node, amd->offset_ob, DEG_OB_COMP_TRANSFORM, "Array Modifier Offset"); | ctx->node, amd->offset_ob, DEG_OB_COMP_TRANSFORM, "Array Modifier Offset"); | ||||
| need_transform_dependency = true; | need_transform_dependency = true; | ||||
| } | } | ||||
| if (need_transform_dependency) { | if (need_transform_dependency) { | ||||
| DEG_add_depends_on_transform_relation(ctx->node, "Array Modifier"); | DEG_add_depends_on_transform_relation(ctx->node, "Array Modifier"); | ||||
| } | } | ||||
| } | } | ||||
| BLI_INLINE float sum_v3(const float v[3]) | BLI_INLINE float sum_v3(const float v[3]) | ||||
| { | { | ||||
| return v[0] + v[1] + v[2]; | return v[0] + v[1] + v[2]; | ||||
| } | } | ||||
| /* Structure used for sorting vertices, when processing doubles */ | /* Structure used for sorting vertices, when processing doubles */ | ||||
| typedef struct SortVertsElem { | typedef struct SortVertsElem { | ||||
| int vertex_num; /* The original index of the vertex, prior to sorting */ | int vertex_num; /* The original index of the vertex, prior to sorting */ | ||||
| float co[3]; /* Its coordinates */ | float co[3]; /* Its coordinates */ | ||||
| float sum_co; /* `sum_v3(co)`: just so we don't do the sum many times. */ | float sum_co; /* `sum_v3(co)`: just so we don't do the sum many times. */ | ||||
| } SortVertsElem; | } SortVertsElem; | ||||
| static int svert_sum_cmp(const void *e1, const void *e2) | static int svert_sum_cmp(const void *e1, const void *e2) | ||||
| { | { | ||||
| const SortVertsElem *sv1 = e1; | const SortVertsElem *sv1 = static_cast<const SortVertsElem *>(e1); | ||||
| const SortVertsElem *sv2 = e2; | const SortVertsElem *sv2 = static_cast<const SortVertsElem *>(e2); | ||||
| if (sv1->sum_co > sv2->sum_co) { | if (sv1->sum_co > sv2->sum_co) { | ||||
| return 1; | return 1; | ||||
| } | } | ||||
| if (sv1->sum_co < sv2->sum_co) { | if (sv1->sum_co < sv2->sum_co) { | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| Show All 23 Lines | |||||
| static void dm_mvert_map_doubles(int *doubles_map, | static void dm_mvert_map_doubles(int *doubles_map, | ||||
| const MVert *mverts, | const MVert *mverts, | ||||
| const int target_start, | const int target_start, | ||||
| const int target_verts_num, | const int target_verts_num, | ||||
| const int source_start, | const int source_start, | ||||
| const int source_verts_num, | const int source_verts_num, | ||||
| const float dist) | const float dist) | ||||
| { | { | ||||
| const float dist3 = ((float)M_SQRT3 + 0.00005f) * dist; /* Just above sqrt(3) */ | const float dist3 = (float(M_SQRT3) + 0.00005f) * dist; /* Just above sqrt(3) */ | ||||
| int i_source, i_target, i_target_low_bound, target_end, source_end; | int i_source, i_target, i_target_low_bound, target_end, source_end; | ||||
| SortVertsElem *sorted_verts_target, *sorted_verts_source; | |||||
| SortVertsElem *sve_source, *sve_target, *sve_target_low_bound; | SortVertsElem *sve_source, *sve_target, *sve_target_low_bound; | ||||
| bool target_scan_completed; | bool target_scan_completed; | ||||
| target_end = target_start + target_verts_num; | target_end = target_start + target_verts_num; | ||||
| source_end = source_start + source_verts_num; | source_end = source_start + source_verts_num; | ||||
| /* build array of MVerts to be tested for merging */ | /* build array of MVerts to be tested for merging */ | ||||
| sorted_verts_target = MEM_malloc_arrayN(target_verts_num, sizeof(SortVertsElem), __func__); | SortVertsElem *sorted_verts_target = static_cast<SortVertsElem *>( | ||||
| sorted_verts_source = MEM_malloc_arrayN(source_verts_num, sizeof(SortVertsElem), __func__); | MEM_malloc_arrayN(target_verts_num, sizeof(SortVertsElem), __func__)); | ||||
| SortVertsElem *sorted_verts_source = static_cast<SortVertsElem *>( | |||||
| MEM_malloc_arrayN(source_verts_num, sizeof(SortVertsElem), __func__)); | |||||
| /* Copy target vertices index and cos into SortVertsElem array */ | /* Copy target vertices index and cos into SortVertsElem array */ | ||||
| svert_from_mvert(sorted_verts_target, mverts + target_start, target_start, target_end); | svert_from_mvert(sorted_verts_target, mverts + target_start, target_start, target_end); | ||||
| /* Copy source vertices index and cos into SortVertsElem array */ | /* Copy source vertices index and cos into SortVertsElem array */ | ||||
| svert_from_mvert(sorted_verts_source, mverts + source_start, source_start, source_end); | svert_from_mvert(sorted_verts_source, mverts + source_start, source_start, source_end); | ||||
| /* sort arrays according to sum of vertex coordinates (sumco) */ | /* sort arrays according to sum of vertex coordinates (sumco) */ | ||||
| ▲ Show 20 Lines • Show All 125 Lines • ▼ Show 20 Lines | if (!recalc_normals_later) { | ||||
| float(*dst_vert_normals)[3] = BKE_mesh_vertex_normals_for_write(result); | float(*dst_vert_normals)[3] = BKE_mesh_vertex_normals_for_write(result); | ||||
| for (i = 0; i < cap_nverts; i++) { | for (i = 0; i < cap_nverts; i++) { | ||||
| mul_mat3_m4_v3(cap_offset, dst_vert_normals[cap_verts_index + i]); | mul_mat3_m4_v3(cap_offset, dst_vert_normals[cap_verts_index + i]); | ||||
| normalize_v3(dst_vert_normals[cap_verts_index + i]); | normalize_v3(dst_vert_normals[cap_verts_index + i]); | ||||
| } | } | ||||
| } | } | ||||
| /* remap the vertex groups if necessary */ | /* remap the vertex groups if necessary */ | ||||
| if (BKE_mesh_deform_verts(result) != NULL) { | if (BKE_mesh_deform_verts(result) != nullptr) { | ||||
| MDeformVert *dvert = BKE_mesh_deform_verts_for_write(result); | MDeformVert *dvert = BKE_mesh_deform_verts_for_write(result); | ||||
| BKE_object_defgroup_index_map_apply(&dvert[cap_verts_index], cap_nverts, remap, remap_len); | BKE_object_defgroup_index_map_apply(&dvert[cap_verts_index], cap_nverts, remap, remap_len); | ||||
| } | } | ||||
| /* adjust cap edge vertex indices */ | /* adjust cap edge vertex indices */ | ||||
| me = result_edges + cap_edges_index; | me = result_edges + cap_edges_index; | ||||
| for (i = 0; i < cap_nedges; i++, me++) { | for (i = 0; i < cap_nedges; i++, me++) { | ||||
| me->v1 += cap_verts_index; | me->v1 += cap_verts_index; | ||||
| Show All 9 Lines | static void mesh_merge_transform(Mesh *result, | ||||
| /* adjust cap loop vertex and edge indices */ | /* adjust cap loop vertex and edge indices */ | ||||
| ml = result_loops + cap_loops_index; | ml = result_loops + cap_loops_index; | ||||
| for (i = 0; i < cap_nloops; i++, ml++) { | for (i = 0; i < cap_nloops; i++, ml++) { | ||||
| ml->v += cap_verts_index; | ml->v += cap_verts_index; | ||||
| ml->e += cap_edges_index; | ml->e += cap_edges_index; | ||||
| } | } | ||||
| /* Set #CD_ORIGINDEX. */ | /* Set #CD_ORIGINDEX. */ | ||||
| index_orig = CustomData_get_layer(&result->vdata, CD_ORIGINDEX); | index_orig = static_cast<int *>(CustomData_get_layer(&result->vdata, CD_ORIGINDEX)); | ||||
| if (index_orig) { | if (index_orig) { | ||||
| copy_vn_i(index_orig + cap_verts_index, cap_nverts, ORIGINDEX_NONE); | copy_vn_i(index_orig + cap_verts_index, cap_nverts, ORIGINDEX_NONE); | ||||
| } | } | ||||
| index_orig = CustomData_get_layer(&result->edata, CD_ORIGINDEX); | index_orig = static_cast<int *>(CustomData_get_layer(&result->edata, CD_ORIGINDEX)); | ||||
| if (index_orig) { | if (index_orig) { | ||||
| copy_vn_i(index_orig + cap_edges_index, cap_nedges, ORIGINDEX_NONE); | copy_vn_i(index_orig + cap_edges_index, cap_nedges, ORIGINDEX_NONE); | ||||
| } | } | ||||
| index_orig = CustomData_get_layer(&result->pdata, CD_ORIGINDEX); | index_orig = static_cast<int *>(CustomData_get_layer(&result->pdata, CD_ORIGINDEX)); | ||||
| if (index_orig) { | if (index_orig) { | ||||
| copy_vn_i(index_orig + cap_polys_index, cap_npolys, ORIGINDEX_NONE); | copy_vn_i(index_orig + cap_polys_index, cap_npolys, ORIGINDEX_NONE); | ||||
| } | } | ||||
| index_orig = CustomData_get_layer(&result->ldata, CD_ORIGINDEX); | index_orig = static_cast<int *>(CustomData_get_layer(&result->ldata, CD_ORIGINDEX)); | ||||
| if (index_orig) { | if (index_orig) { | ||||
| copy_vn_i(index_orig + cap_loops_index, cap_nloops, ORIGINDEX_NONE); | copy_vn_i(index_orig + cap_loops_index, cap_nloops, ORIGINDEX_NONE); | ||||
| } | } | ||||
| } | } | ||||
| static Mesh *arrayModifier_doArray(ArrayModifierData *amd, | static Mesh *arrayModifier_doArray(ArrayModifierData *amd, | ||||
| const ModifierEvalContext *ctx, | const ModifierEvalContext *ctx, | ||||
| const Mesh *mesh) | const Mesh *mesh) | ||||
| { | { | ||||
| MEdge *me; | MEdge *me; | ||||
| MLoop *ml; | MLoop *ml; | ||||
| MPoly *mp; | MPoly *mp; | ||||
| int i, j, c, count; | int i, j, c, count; | ||||
| float length = amd->length; | float length = amd->length; | ||||
| /* offset matrix */ | /* offset matrix */ | ||||
| float offset[4][4]; | float offset[4][4]; | ||||
| float scale[3]; | float scale[3]; | ||||
| bool offset_has_scale; | bool offset_has_scale; | ||||
| float current_offset[4][4]; | float current_offset[4][4]; | ||||
| float final_offset[4][4]; | float final_offset[4][4]; | ||||
| int *full_doubles_map = NULL; | int *full_doubles_map = nullptr; | ||||
| int tot_doubles; | int tot_doubles; | ||||
| const bool use_merge = (amd->flags & MOD_ARR_MERGE) != 0; | const bool use_merge = (amd->flags & MOD_ARR_MERGE) != 0; | ||||
| const bool use_recalc_normals = BKE_mesh_vertex_normals_are_dirty(mesh) || use_merge; | const bool use_recalc_normals = BKE_mesh_vertex_normals_are_dirty(mesh) || use_merge; | ||||
| const bool use_offset_ob = ((amd->offset_type & MOD_ARR_OFF_OBJ) && amd->offset_ob != NULL); | const bool use_offset_ob = ((amd->offset_type & MOD_ARR_OFF_OBJ) && amd->offset_ob != nullptr); | ||||
| int start_cap_nverts = 0, start_cap_nedges = 0, start_cap_npolys = 0, start_cap_nloops = 0; | int start_cap_nverts = 0, start_cap_nedges = 0, start_cap_npolys = 0, start_cap_nloops = 0; | ||||
| int end_cap_nverts = 0, end_cap_nedges = 0, end_cap_npolys = 0, end_cap_nloops = 0; | int end_cap_nverts = 0, end_cap_nedges = 0, end_cap_npolys = 0, end_cap_nloops = 0; | ||||
| int result_nverts = 0, result_nedges = 0, result_npolys = 0, result_nloops = 0; | int result_nverts = 0, result_nedges = 0, result_npolys = 0, result_nloops = 0; | ||||
| int chunk_nverts, chunk_nedges, chunk_nloops, chunk_npolys; | int chunk_nverts, chunk_nedges, chunk_nloops, chunk_npolys; | ||||
| int first_chunk_start, first_chunk_nverts, last_chunk_start, last_chunk_nverts; | int first_chunk_start, first_chunk_nverts, last_chunk_start, last_chunk_nverts; | ||||
| Mesh *result, *start_cap_mesh = NULL, *end_cap_mesh = NULL; | Mesh *result, *start_cap_mesh = nullptr, *end_cap_mesh = nullptr; | ||||
| int *vgroup_start_cap_remap = NULL; | int *vgroup_start_cap_remap = nullptr; | ||||
| int vgroup_start_cap_remap_len = 0; | int vgroup_start_cap_remap_len = 0; | ||||
| int *vgroup_end_cap_remap = NULL; | int *vgroup_end_cap_remap = nullptr; | ||||
| int vgroup_end_cap_remap_len = 0; | int vgroup_end_cap_remap_len = 0; | ||||
| chunk_nverts = mesh->totvert; | chunk_nverts = mesh->totvert; | ||||
| chunk_nedges = mesh->totedge; | chunk_nedges = mesh->totedge; | ||||
| chunk_nloops = mesh->totloop; | chunk_nloops = mesh->totloop; | ||||
| chunk_npolys = mesh->totpoly; | chunk_npolys = mesh->totpoly; | ||||
| count = amd->count; | count = amd->count; | ||||
| ▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | if (use_offset_ob) { | ||||
| mul_m4_series(result_mat, offset, obinv, amd->offset_ob->object_to_world); | mul_m4_series(result_mat, offset, obinv, amd->offset_ob->object_to_world); | ||||
| copy_m4_m4(offset, result_mat); | copy_m4_m4(offset, result_mat); | ||||
| } | } | ||||
| /* Check if there is some scaling. If scaling, then we will not translate mapping */ | /* Check if there is some scaling. If scaling, then we will not translate mapping */ | ||||
| mat4_to_size(scale, offset); | mat4_to_size(scale, offset); | ||||
| offset_has_scale = !is_one_v3(scale); | offset_has_scale = !is_one_v3(scale); | ||||
| if (amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob != NULL) { | if (amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob != nullptr) { | ||||
| Object *curve_ob = amd->curve_ob; | Object *curve_ob = amd->curve_ob; | ||||
| CurveCache *curve_cache = curve_ob->runtime.curve_cache; | CurveCache *curve_cache = curve_ob->runtime.curve_cache; | ||||
| if (curve_cache != NULL && curve_cache->anim_path_accum_length != NULL) { | if (curve_cache != nullptr && curve_cache->anim_path_accum_length != nullptr) { | ||||
| float scale_fac = mat4_to_scale(curve_ob->object_to_world); | float scale_fac = mat4_to_scale(curve_ob->object_to_world); | ||||
| length = scale_fac * BKE_anim_path_get_length(curve_cache); | length = scale_fac * BKE_anim_path_get_length(curve_cache); | ||||
| } | } | ||||
| } | } | ||||
| /* About 67 million vertices max seems a decent limit for now. */ | /* About 67 million vertices max seems a decent limit for now. */ | ||||
| const size_t max_verts_num = 1 << 26; | const size_t max_verts_num = 1 << 26; | ||||
| ▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | result = BKE_mesh_new_nomain_from_template( | ||||
| mesh, result_nverts, result_nedges, 0, result_nloops, result_npolys); | mesh, result_nverts, result_nedges, 0, result_nloops, result_npolys); | ||||
| MVert *result_verts = BKE_mesh_verts_for_write(result); | MVert *result_verts = BKE_mesh_verts_for_write(result); | ||||
| MEdge *result_edges = BKE_mesh_edges_for_write(result); | MEdge *result_edges = BKE_mesh_edges_for_write(result); | ||||
| MPoly *result_polys = BKE_mesh_polys_for_write(result); | MPoly *result_polys = BKE_mesh_polys_for_write(result); | ||||
| MLoop *result_loops = BKE_mesh_loops_for_write(result); | MLoop *result_loops = BKE_mesh_loops_for_write(result); | ||||
| if (use_merge) { | if (use_merge) { | ||||
| /* Will need full_doubles_map for handling merge */ | /* Will need full_doubles_map for handling merge */ | ||||
| full_doubles_map = MEM_malloc_arrayN(result_nverts, sizeof(int), "mod array doubles map"); | full_doubles_map = static_cast<int *>(MEM_malloc_arrayN(result_nverts, sizeof(int), __func__)); | ||||
| copy_vn_i(full_doubles_map, result_nverts, -1); | copy_vn_i(full_doubles_map, result_nverts, -1); | ||||
| } | } | ||||
| /* copy customdata to original geometry */ | /* copy customdata to original geometry */ | ||||
| CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, chunk_nverts); | CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, chunk_nverts); | ||||
| CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, chunk_nedges); | CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, chunk_nedges); | ||||
| CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, chunk_nloops); | CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, chunk_nloops); | ||||
| CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, chunk_npolys); | CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, chunk_npolys); | ||||
| Show All 11 Lines | if (!CustomData_has_layer(&mesh->pdata, CD_MPOLY)) { | ||||
| memcpy(result_polys, src_polys, sizeof(MPoly) * mesh->totpoly); | memcpy(result_polys, src_polys, sizeof(MPoly) * mesh->totpoly); | ||||
| } | } | ||||
| /* Remember first chunk, in case of cap merge */ | /* Remember first chunk, in case of cap merge */ | ||||
| first_chunk_start = 0; | first_chunk_start = 0; | ||||
| first_chunk_nverts = chunk_nverts; | first_chunk_nverts = chunk_nverts; | ||||
| unit_m4(current_offset); | unit_m4(current_offset); | ||||
| const float(*src_vert_normals)[3] = NULL; | const float(*src_vert_normals)[3] = nullptr; | ||||
| float(*dst_vert_normals)[3] = NULL; | float(*dst_vert_normals)[3] = nullptr; | ||||
| if (!use_recalc_normals) { | if (!use_recalc_normals) { | ||||
| src_vert_normals = BKE_mesh_vertex_normals_ensure(mesh); | src_vert_normals = BKE_mesh_vertex_normals_ensure(mesh); | ||||
| dst_vert_normals = BKE_mesh_vertex_normals_for_write(result); | dst_vert_normals = BKE_mesh_vertex_normals_for_write(result); | ||||
| BKE_mesh_vertex_normals_clear_dirty(result); | BKE_mesh_vertex_normals_clear_dirty(result); | ||||
| } | } | ||||
| for (c = 1; c < count; c++) { | for (c = 1; c < count; c++) { | ||||
| /* copy customdata to new geometry */ | /* copy customdata to new geometry */ | ||||
| ▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | if (use_merge && (c >= 1)) { | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* handle UVs */ | /* handle UVs */ | ||||
| if (chunk_nloops > 0 && is_zero_v2(amd->uv_offset) == false) { | if (chunk_nloops > 0 && is_zero_v2(amd->uv_offset) == false) { | ||||
| const int totuv = CustomData_number_of_layers(&result->ldata, CD_MLOOPUV); | const int totuv = CustomData_number_of_layers(&result->ldata, CD_MLOOPUV); | ||||
| for (i = 0; i < totuv; i++) { | for (i = 0; i < totuv; i++) { | ||||
| MLoopUV *dmloopuv = CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, i); | MLoopUV *dmloopuv = static_cast<MLoopUV *>( | ||||
| CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, i)); | |||||
| dmloopuv += chunk_nloops; | dmloopuv += chunk_nloops; | ||||
| for (c = 1; c < count; c++) { | for (c = 1; c < count; c++) { | ||||
| const float uv_offset[2] = { | const float uv_offset[2] = { | ||||
| amd->uv_offset[0] * (float)c, | amd->uv_offset[0] * float(c), | ||||
| amd->uv_offset[1] * (float)c, | amd->uv_offset[1] * float(c), | ||||
| }; | }; | ||||
| int l_index = chunk_nloops; | int l_index = chunk_nloops; | ||||
| for (; l_index-- != 0; dmloopuv++) { | for (; l_index-- != 0; dmloopuv++) { | ||||
| dmloopuv->uv[0] += uv_offset[0]; | dmloopuv->uv[0] += uv_offset[0]; | ||||
| dmloopuv->uv[1] += uv_offset[1]; | dmloopuv->uv[1] += uv_offset[1]; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 116 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) | static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) | ||||
| { | { | ||||
| ArrayModifierData *amd = (ArrayModifierData *)md; | ArrayModifierData *amd = (ArrayModifierData *)md; | ||||
| return arrayModifier_doArray(amd, ctx, mesh); | return arrayModifier_doArray(amd, ctx, mesh); | ||||
| } | } | ||||
| static bool isDisabled(const struct Scene *UNUSED(scene), | static bool isDisabled(const struct Scene * /*scene*/, ModifierData *md, bool /*useRenderParams*/) | ||||
| ModifierData *md, | |||||
| bool UNUSED(useRenderParams)) | |||||
| { | { | ||||
| ArrayModifierData *amd = (ArrayModifierData *)md; | ArrayModifierData *amd = (ArrayModifierData *)md; | ||||
| /* The object type check is only needed here in case we have a placeholder | /* The object type check is only needed here in case we have a placeholder | ||||
| * object assigned (because the library containing the curve/mesh is missing). | * object assigned (because the library containing the curve/mesh is missing). | ||||
| * | * | ||||
| * In other cases it should be impossible to have a type mismatch. | * In other cases it should be impossible to have a type mismatch. | ||||
| */ | */ | ||||
| if (amd->curve_ob && amd->curve_ob->type != OB_CURVES_LEGACY) { | if (amd->curve_ob && amd->curve_ob->type != OB_CURVES_LEGACY) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| if (amd->start_cap && amd->start_cap->type != OB_MESH) { | if (amd->start_cap && amd->start_cap->type != OB_MESH) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| if (amd->end_cap && amd->end_cap->type != OB_MESH) { | if (amd->end_cap && amd->end_cap->type != OB_MESH) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| static void panel_draw(const bContext *UNUSED(C), Panel *panel) | static void panel_draw(const bContext * /*C*/, Panel *panel) | ||||
| { | { | ||||
| uiLayout *layout = panel->layout; | uiLayout *layout = panel->layout; | ||||
| PointerRNA ob_ptr; | PointerRNA ob_ptr; | ||||
| PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr); | PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr); | ||||
| uiLayoutSetPropSep(layout, true); | uiLayoutSetPropSep(layout, true); | ||||
| uiItemR(layout, ptr, "fit_type", 0, NULL, ICON_NONE); | uiItemR(layout, ptr, "fit_type", 0, nullptr, ICON_NONE); | ||||
| int fit_type = RNA_enum_get(ptr, "fit_type"); | int fit_type = RNA_enum_get(ptr, "fit_type"); | ||||
| if (fit_type == MOD_ARR_FIXEDCOUNT) { | if (fit_type == MOD_ARR_FIXEDCOUNT) { | ||||
| uiItemR(layout, ptr, "count", 0, NULL, ICON_NONE); | uiItemR(layout, ptr, "count", 0, nullptr, ICON_NONE); | ||||
| } | } | ||||
| else if (fit_type == MOD_ARR_FITLENGTH) { | else if (fit_type == MOD_ARR_FITLENGTH) { | ||||
| uiItemR(layout, ptr, "fit_length", 0, NULL, ICON_NONE); | uiItemR(layout, ptr, "fit_length", 0, nullptr, ICON_NONE); | ||||
| } | } | ||||
| else if (fit_type == MOD_ARR_FITCURVE) { | else if (fit_type == MOD_ARR_FITCURVE) { | ||||
| uiItemR(layout, ptr, "curve", 0, NULL, ICON_NONE); | uiItemR(layout, ptr, "curve", 0, nullptr, ICON_NONE); | ||||
| } | } | ||||
| modifier_panel_end(layout, ptr); | modifier_panel_end(layout, ptr); | ||||
| } | } | ||||
| static void relative_offset_header_draw(const bContext *UNUSED(C), Panel *panel) | static void relative_offset_header_draw(const bContext * /*C*/, Panel *panel) | ||||
| { | { | ||||
| uiLayout *layout = panel->layout; | uiLayout *layout = panel->layout; | ||||
| PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); | PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); | ||||
| uiItemR(layout, ptr, "use_relative_offset", 0, NULL, ICON_NONE); | uiItemR(layout, ptr, "use_relative_offset", 0, nullptr, ICON_NONE); | ||||
| } | } | ||||
| static void relative_offset_draw(const bContext *UNUSED(C), Panel *panel) | static void relative_offset_draw(const bContext * /*C*/, Panel *panel) | ||||
| { | { | ||||
| uiLayout *layout = panel->layout; | uiLayout *layout = panel->layout; | ||||
| PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); | PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); | ||||
| uiLayoutSetPropSep(layout, true); | uiLayoutSetPropSep(layout, true); | ||||
| uiLayout *col = uiLayoutColumn(layout, false); | uiLayout *col = uiLayoutColumn(layout, false); | ||||
| uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_relative_offset")); | uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_relative_offset")); | ||||
| uiItemR(col, ptr, "relative_offset_displace", 0, IFACE_("Factor"), ICON_NONE); | uiItemR(col, ptr, "relative_offset_displace", 0, IFACE_("Factor"), ICON_NONE); | ||||
| } | } | ||||
| static void constant_offset_header_draw(const bContext *UNUSED(C), Panel *panel) | static void constant_offset_header_draw(const bContext * /*C*/, Panel *panel) | ||||
| { | { | ||||
| uiLayout *layout = panel->layout; | uiLayout *layout = panel->layout; | ||||
| PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); | PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); | ||||
| uiItemR(layout, ptr, "use_constant_offset", 0, NULL, ICON_NONE); | uiItemR(layout, ptr, "use_constant_offset", 0, nullptr, ICON_NONE); | ||||
| } | } | ||||
| static void constant_offset_draw(const bContext *UNUSED(C), Panel *panel) | static void constant_offset_draw(const bContext * /*C*/, Panel *panel) | ||||
| { | { | ||||
| uiLayout *layout = panel->layout; | uiLayout *layout = panel->layout; | ||||
| PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); | PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); | ||||
| uiLayoutSetPropSep(layout, true); | uiLayoutSetPropSep(layout, true); | ||||
| uiLayout *col = uiLayoutColumn(layout, false); | uiLayout *col = uiLayoutColumn(layout, false); | ||||
| uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_constant_offset")); | uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_constant_offset")); | ||||
| uiItemR(col, ptr, "constant_offset_displace", 0, IFACE_("Distance"), ICON_NONE); | uiItemR(col, ptr, "constant_offset_displace", 0, IFACE_("Distance"), ICON_NONE); | ||||
| } | } | ||||
| /** | /** | ||||
| * Object offset in a subpanel for consistency with the other offset types. | * Object offset in a subpanel for consistency with the other offset types. | ||||
| */ | */ | ||||
| static void object_offset_header_draw(const bContext *UNUSED(C), Panel *panel) | static void object_offset_header_draw(const bContext * /*C*/, Panel *panel) | ||||
| { | { | ||||
| uiLayout *layout = panel->layout; | uiLayout *layout = panel->layout; | ||||
| PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); | PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); | ||||
| uiItemR(layout, ptr, "use_object_offset", 0, NULL, ICON_NONE); | uiItemR(layout, ptr, "use_object_offset", 0, nullptr, ICON_NONE); | ||||
| } | } | ||||
| static void object_offset_draw(const bContext *UNUSED(C), Panel *panel) | static void object_offset_draw(const bContext * /*C*/, Panel *panel) | ||||
| { | { | ||||
| uiLayout *layout = panel->layout; | uiLayout *layout = panel->layout; | ||||
| PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); | PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); | ||||
| uiLayoutSetPropSep(layout, true); | uiLayoutSetPropSep(layout, true); | ||||
| uiLayout *col = uiLayoutColumn(layout, false); | uiLayout *col = uiLayoutColumn(layout, false); | ||||
| uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_object_offset")); | uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_object_offset")); | ||||
| uiItemR(col, ptr, "offset_object", 0, IFACE_("Object"), ICON_NONE); | uiItemR(col, ptr, "offset_object", 0, IFACE_("Object"), ICON_NONE); | ||||
| } | } | ||||
| static void symmetry_panel_header_draw(const bContext *UNUSED(C), Panel *panel) | static void symmetry_panel_header_draw(const bContext * /*C*/, Panel *panel) | ||||
| { | { | ||||
| uiLayout *layout = panel->layout; | uiLayout *layout = panel->layout; | ||||
| PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); | PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); | ||||
| uiItemR(layout, ptr, "use_merge_vertices", 0, IFACE_("Merge"), ICON_NONE); | uiItemR(layout, ptr, "use_merge_vertices", 0, IFACE_("Merge"), ICON_NONE); | ||||
| } | } | ||||
| static void symmetry_panel_draw(const bContext *UNUSED(C), Panel *panel) | static void symmetry_panel_draw(const bContext * /*C*/, Panel *panel) | ||||
| { | { | ||||
| uiLayout *layout = panel->layout; | uiLayout *layout = panel->layout; | ||||
| PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); | PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); | ||||
| uiLayoutSetPropSep(layout, true); | uiLayoutSetPropSep(layout, true); | ||||
| uiLayout *col = uiLayoutColumn(layout, false); | uiLayout *col = uiLayoutColumn(layout, false); | ||||
| uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_merge_vertices")); | uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_merge_vertices")); | ||||
| uiItemR(col, ptr, "merge_threshold", 0, IFACE_("Distance"), ICON_NONE); | uiItemR(col, ptr, "merge_threshold", 0, IFACE_("Distance"), ICON_NONE); | ||||
| uiItemR(col, ptr, "use_merge_vertices_cap", 0, IFACE_("First and Last Copies"), ICON_NONE); | uiItemR(col, ptr, "use_merge_vertices_cap", 0, IFACE_("First and Last Copies"), ICON_NONE); | ||||
| } | } | ||||
| static void uv_panel_draw(const bContext *UNUSED(C), Panel *panel) | static void uv_panel_draw(const bContext * /*C*/, Panel *panel) | ||||
| { | { | ||||
| uiLayout *col; | uiLayout *col; | ||||
| uiLayout *layout = panel->layout; | uiLayout *layout = panel->layout; | ||||
| PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); | PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); | ||||
| uiLayoutSetPropSep(layout, true); | uiLayoutSetPropSep(layout, true); | ||||
| col = uiLayoutColumn(layout, true); | col = uiLayoutColumn(layout, true); | ||||
| uiItemR(col, ptr, "offset_u", UI_ITEM_R_EXPAND, IFACE_("Offset U"), ICON_NONE); | uiItemR(col, ptr, "offset_u", UI_ITEM_R_EXPAND, IFACE_("Offset U"), ICON_NONE); | ||||
| uiItemR(col, ptr, "offset_v", UI_ITEM_R_EXPAND, IFACE_("V"), ICON_NONE); | uiItemR(col, ptr, "offset_v", UI_ITEM_R_EXPAND, IFACE_("V"), ICON_NONE); | ||||
| } | } | ||||
| static void caps_panel_draw(const bContext *UNUSED(C), Panel *panel) | static void caps_panel_draw(const bContext * /*C*/, Panel *panel) | ||||
| { | { | ||||
| uiLayout *col; | uiLayout *col; | ||||
| uiLayout *layout = panel->layout; | uiLayout *layout = panel->layout; | ||||
| PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); | PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); | ||||
| uiLayoutSetPropSep(layout, true); | uiLayoutSetPropSep(layout, true); | ||||
| col = uiLayoutColumn(layout, false); | col = uiLayoutColumn(layout, false); | ||||
| uiItemR(col, ptr, "start_cap", 0, IFACE_("Cap Start"), ICON_NONE); | uiItemR(col, ptr, "start_cap", 0, IFACE_("Cap Start"), ICON_NONE); | ||||
| uiItemR(col, ptr, "end_cap", 0, IFACE_("End"), ICON_NONE); | uiItemR(col, ptr, "end_cap", 0, IFACE_("End"), ICON_NONE); | ||||
| } | } | ||||
| Show All 11 Lines | modifier_subpanel_register(region_type, | ||||
| "", | "", | ||||
| constant_offset_header_draw, | constant_offset_header_draw, | ||||
| constant_offset_draw, | constant_offset_draw, | ||||
| panel_type); | panel_type); | ||||
| modifier_subpanel_register( | modifier_subpanel_register( | ||||
| region_type, "object_offset", "", object_offset_header_draw, object_offset_draw, panel_type); | region_type, "object_offset", "", object_offset_header_draw, object_offset_draw, panel_type); | ||||
| modifier_subpanel_register( | modifier_subpanel_register( | ||||
| region_type, "merge", "", symmetry_panel_header_draw, symmetry_panel_draw, panel_type); | region_type, "merge", "", symmetry_panel_header_draw, symmetry_panel_draw, panel_type); | ||||
| modifier_subpanel_register(region_type, "uv", "UVs", NULL, uv_panel_draw, panel_type); | modifier_subpanel_register(region_type, "uv", "UVs", nullptr, uv_panel_draw, panel_type); | ||||
| modifier_subpanel_register(region_type, "caps", "Caps", NULL, caps_panel_draw, panel_type); | modifier_subpanel_register(region_type, "caps", "Caps", nullptr, caps_panel_draw, panel_type); | ||||
| } | } | ||||
| ModifierTypeInfo modifierType_Array = { | ModifierTypeInfo modifierType_Array = { | ||||
| /* name */ N_("Array"), | /* name */ N_("Array"), | ||||
| /* structName */ "ArrayModifierData", | /* structName */ "ArrayModifierData", | ||||
| /* structSize */ sizeof(ArrayModifierData), | /* structSize */ sizeof(ArrayModifierData), | ||||
| /* srna */ &RNA_ArrayModifier, | /* srna */ &RNA_ArrayModifier, | ||||
| /* type */ eModifierTypeType_Constructive, | /* type */ eModifierTypeType_Constructive, | ||||
| /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | | /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | | ||||
| eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode | | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode | | ||||
| eModifierTypeFlag_AcceptsCVs, | eModifierTypeFlag_AcceptsCVs, | ||||
| /* icon */ ICON_MOD_ARRAY, | /* icon */ ICON_MOD_ARRAY, | ||||
| /* copyData */ BKE_modifier_copydata_generic, | /* copyData */ BKE_modifier_copydata_generic, | ||||
| /* deformVerts */ NULL, | /* deformVerts */ nullptr, | ||||
| /* deformMatrices */ NULL, | /* deformMatrices */ nullptr, | ||||
| /* deformVertsEM */ NULL, | /* deformVertsEM */ nullptr, | ||||
| /* deformMatricesEM */ NULL, | /* deformMatricesEM */ nullptr, | ||||
| /* modifyMesh */ modifyMesh, | /* modifyMesh */ modifyMesh, | ||||
| /* modifyGeometrySet */ NULL, | /* modifyGeometrySet */ nullptr, | ||||
| /* initData */ initData, | /* initData */ initData, | ||||
| /* requiredDataMask */ NULL, | /* requiredDataMask */ nullptr, | ||||
| /* freeData */ NULL, | /* freeData */ nullptr, | ||||
| /* isDisabled */ isDisabled, | /* isDisabled */ isDisabled, | ||||
| /* updateDepsgraph */ updateDepsgraph, | /* updateDepsgraph */ updateDepsgraph, | ||||
| /* dependsOnTime */ NULL, | /* dependsOnTime */ nullptr, | ||||
| /* dependsOnNormals */ NULL, | /* dependsOnNormals */ nullptr, | ||||
| /* foreachIDLink */ foreachIDLink, | /* foreachIDLink */ foreachIDLink, | ||||
| /* foreachTexLink */ NULL, | /* foreachTexLink */ nullptr, | ||||
| /* freeRuntimeData */ NULL, | /* freeRuntimeData */ nullptr, | ||||
| /* panelRegister */ panelRegister, | /* panelRegister */ panelRegister, | ||||
| /* blendWrite */ NULL, | /* blendWrite */ nullptr, | ||||
| /* blendRead */ NULL, | /* blendRead */ nullptr, | ||||
| }; | }; | ||||