diff options
Diffstat (limited to 'source/blender/modifiers/intern')
-rw-r--r-- | source/blender/modifiers/intern/MOD_array.c | 4 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_curve.c | 2 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_displace.c | 3 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_nodes.cc | 6 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_normal_edit.c | 4 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_solidify_extrude.c | 6 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_solidify_nonmanifold.c | 307 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_subsurf.c | 14 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_ui_common.c | 2 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_util.c | 2 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_uvproject.c | 3 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_volume_displace.cc | 6 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_weightvgmix.c | 6 |
13 files changed, 215 insertions, 150 deletions
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index 2cc3bb8c916..ea42ac761ea 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -371,7 +371,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, int tot_doubles; const bool use_merge = (amd->flags & MOD_ARR_MERGE) != 0; - const bool use_recalc_normals = (mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) || 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); int start_cap_nverts = 0, start_cap_nedges = 0, start_cap_npolys = 0, start_cap_nloops = 0; @@ -819,7 +819,7 @@ static bool isDisabled(const struct Scene *UNUSED(scene), * In other cases it should be impossible to have a type mismatch. */ - if (amd->curve_ob && amd->curve_ob->type != OB_CURVE) { + if (amd->curve_ob && amd->curve_ob->type != OB_CURVES_LEGACY) { return true; } if (amd->start_cap && amd->start_cap->type != OB_MESH) { diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c index ca5d59433f0..d1c7dd43f15 100644 --- a/source/blender/modifiers/intern/MOD_curve.c +++ b/source/blender/modifiers/intern/MOD_curve.c @@ -71,7 +71,7 @@ static bool isDisabled(const Scene *UNUSED(scene), ModifierData *md, bool UNUSED * * In other cases it should be impossible to have a type mismatch. */ - return !cmd->object || cmd->object->type != OB_CURVE; + return !cmd->object || cmd->object->type != OB_CURVES_LEGACY; } static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData) diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c index 0411bcd7c34..ddbed4f498e 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -313,8 +313,7 @@ static void displaceModifier_do(DisplaceModifierData *dmd, if (CustomData_has_layer(ldata, CD_CUSTOMLOOPNORMAL)) { float(*clnors)[3] = NULL; - if ((mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) || - !CustomData_has_layer(ldata, CD_NORMAL)) { + if (!CustomData_has_layer(ldata, CD_NORMAL)) { BKE_mesh_calc_normals_split(mesh); } diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index f54ed8f5a25..210a7edac54 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -454,6 +454,10 @@ static IDProperty *id_property_create_from_socket(const bNodeSocket &socket) ui_data->base.rna_subtype = PROP_COLOR; ui_data->default_array = (double *)MEM_mallocN(sizeof(double[4]), __func__); ui_data->default_array_len = 4; + ui_data->min = 0.0; + ui_data->max = FLT_MAX; + ui_data->soft_min = 0.0; + ui_data->soft_max = 1.0; for (const int i : IndexRange(4)) { ui_data->default_array[i] = double(value->value[i]); } @@ -1381,7 +1385,7 @@ static void add_attribute_search_button(const bContext &C, 0.0f, 0.0f, 0.0f, - ""); + socket.description); const Object *object = ED_object_context(&C); BLI_assert(object != nullptr); diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c index e6aebbfeb56..3649808f4f0 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.c +++ b/source/blender/modifiers/intern/MOD_normal_edit.c @@ -535,8 +535,8 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, CustomData *ldata = &result->ldata; - const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh); - const float(*poly_normals)[3] = BKE_mesh_poly_normals_ensure(mesh); + const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(result); + const float(*poly_normals)[3] = BKE_mesh_poly_normals_ensure(result); clnors = CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL); if (use_current_clnors) { diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.c b/source/blender/modifiers/intern/MOD_solidify_extrude.c index 0313c37283a..fdaf7bd41d1 100644 --- a/source/blender/modifiers/intern/MOD_solidify_extrude.c +++ b/source/blender/modifiers/intern/MOD_solidify_extrude.c @@ -953,7 +953,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } /* must recalculate normals with vgroups since they can displace unevenly T26888. */ - if ((mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) || do_rim || dvert) { + if (BKE_mesh_vertex_normals_are_dirty(mesh) || do_rim || dvert) { BKE_mesh_normals_tag_dirty(result); } else if (do_shell) { @@ -1009,9 +1009,9 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex #define SOLIDIFY_SIDE_NORMALS #ifdef SOLIDIFY_SIDE_NORMALS - /* NOTE(@sybren): due to the code setting cd_dirty_vert a few lines above, + /* NOTE(@sybren): due to the code setting normals dirty a few lines above, * do_side_normals is always false. */ - const bool do_side_normals = !(result->runtime.cd_dirty_vert & CD_MASK_NORMAL); + const bool do_side_normals = !BKE_mesh_vertex_normals_are_dirty(result); /* annoying to allocate these since we only need the edge verts, */ float(*edge_vert_nos)[3] = do_side_normals ? MEM_calloc_arrayN(numVerts, sizeof(float[3]), __func__) : diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c index ed7acef4cdc..ff25c1afd49 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c @@ -1405,21 +1405,26 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, for (uint j = 0; g->valid; j++, g++) { if (!g->is_singularity) { float *nor = g->no; + /* During vertex position calculation, the algorithm decides if it wants to disable the + * boundary fix to maintain correct thickness. If the used algorithm does not produce a + * free move direction (move_nor), it can use approximate_free_direction to decide on + * a movement direction based on the connected edges. */ float move_nor[3] = {0, 0, 0}; bool disable_boundary_fix = (smd->nonmanifold_boundary_mode == MOD_SOLIDIFY_NONMANIFOLD_BOUNDARY_MODE_NONE || (g->is_orig_closed || g->split)); + bool approximate_free_direction = false; /* Constraints Method. */ if (smd->nonmanifold_offset_mode == MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_CONSTRAINTS) { NewEdgeRef *first_edge = NULL; NewEdgeRef **edge_ptr = g->edges; /* Contains normal and offset [nx, ny, nz, ofs]. */ - float(*normals_queue)[4] = MEM_malloc_arrayN( - g->edges_len + 1, sizeof(*normals_queue), "normals_queue in solidify"); + float(*planes_queue)[4] = MEM_malloc_arrayN( + g->edges_len + 1, sizeof(*planes_queue), "planes_queue in solidify"); uint queue_index = 0; - float face_nors[3][3]; - float nor_ofs[3]; + float fallback_nor[3]; + float fallback_ofs = 0.0f; const bool cycle = (g->is_orig_closed && !g->split) || g->is_even_split; for (uint k = 0; k < g->edges_len; k++, edge_ptr++) { @@ -1436,17 +1441,17 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } if (!null_faces[face->index]) { - /* And normal to the queue. */ - mul_v3_v3fl(normals_queue[queue_index], + /* And plane to the queue. */ + mul_v3_v3fl(planes_queue[queue_index], poly_nors[face->index], face->reversed ? -1 : 1); - normals_queue[queue_index++][3] = ofs; + planes_queue[queue_index++][3] = ofs; } else { /* Just use this approximate normal of the null face if there is no other * normal to use. */ - mul_v3_v3fl(face_nors[0], poly_nors[face->index], face->reversed ? -1 : 1); - nor_ofs[0] = ofs; + mul_v3_v3fl(fallback_nor, poly_nors[face->index], face->reversed ? -1 : 1); + fallback_ofs = ofs; } } } @@ -1455,131 +1460,173 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } } } - uint face_nors_len = 0; - const float stop_explosion = 0.999f - fabsf(smd->offset_fac) * 0.05f; - while (queue_index > 0) { - if (face_nors_len == 0) { - if (queue_index <= 2) { - for (uint k = 0; k < queue_index; k++) { - copy_v3_v3(face_nors[k], normals_queue[k]); - nor_ofs[k] = normals_queue[k][3]; + if (queue_index > 2) { + /* Find the two most different normals. */ + float min_p = 2.0f; + uint min_n0 = 0; + uint min_n1 = 0; + for (uint k = 0; k < queue_index; k++) { + for (uint m = k + 1; m < queue_index; m++) { + float p = dot_v3v3(planes_queue[k], planes_queue[m]); + if (p < min_p) { + min_p = p; + min_n0 = k; + min_n1 = m; } - face_nors_len = queue_index; - queue_index = 0; } - else { - /* Find most different two normals. */ - float min_p = 2; - uint min_n0 = 0; - uint min_n1 = 0; - for (uint k = 0; k < queue_index; k++) { - for (uint m = k + 1; m < queue_index; m++) { - float p = dot_v3v3(normals_queue[k], normals_queue[m]); - if (p <= min_p + FLT_EPSILON) { - min_p = p; - min_n0 = m; - min_n1 = k; - } - } - } - copy_v3_v3(face_nors[0], normals_queue[min_n0]); - copy_v3_v3(face_nors[1], normals_queue[min_n1]); - nor_ofs[0] = normals_queue[min_n0][3]; - nor_ofs[1] = normals_queue[min_n1][3]; - face_nors_len = 2; - queue_index--; - memmove(normals_queue + min_n0, - normals_queue + min_n0 + 1, - (queue_index - min_n0) * sizeof(*normals_queue)); - queue_index--; - memmove(normals_queue + min_n1, - normals_queue + min_n1 + 1, - (queue_index - min_n1) * sizeof(*normals_queue)); - min_p = 1; - min_n1 = 0; - float max_p = -1; - for (uint k = 0; k < queue_index; k++) { - max_p = -1; - for (uint m = 0; m < face_nors_len; m++) { - float p = dot_v3v3(face_nors[m], normals_queue[k]); - if (p > max_p + FLT_EPSILON) { - max_p = p; - } - } - if (max_p <= min_p + FLT_EPSILON) { - min_p = max_p; - min_n1 = k; - } - } - if (min_p < 0.8) { - copy_v3_v3(face_nors[2], normals_queue[min_n1]); - nor_ofs[2] = normals_queue[min_n1][3]; - face_nors_len++; - queue_index--; - memmove(normals_queue + min_n1, - normals_queue + min_n1 + 1, - (queue_index - min_n1) * sizeof(*normals_queue)); + } + /* Put the two found normals, first in the array queue. */ + if (min_n1 != 0) { + swap_v4_v4(planes_queue[min_n0], planes_queue[0]); + swap_v4_v4(planes_queue[min_n1], planes_queue[1]); + } + else { + swap_v4_v4(planes_queue[min_n0], planes_queue[1]); + } + /* Find the third most important/different normal. */ + min_p = 1.0f; + min_n1 = 2; + float max_p = -1.0f; + for (uint k = 2; k < queue_index; k++) { + max_p = max_ff(dot_v3v3(planes_queue[0], planes_queue[k]), + dot_v3v3(planes_queue[1], planes_queue[k])); + if (max_p <= min_p) { + min_p = max_p; + min_n1 = k; + } + } + swap_v4_v4(planes_queue[min_n1], planes_queue[2]); + } + /* Remove/average duplicate normals in planes_queue. */ + while (queue_index > 2) { + uint best_n0 = 0; + uint best_n1 = 0; + float best_p = -1.0f; + float best_ofs_diff = 0.0f; + for (uint k = 0; k < queue_index; k++) { + for (uint m = k + 1; m < queue_index; m++) { + float p = dot_v3v3(planes_queue[m], planes_queue[k]); + float ofs_diff = fabsf(planes_queue[m][3] - planes_queue[k][3]); + if (p > best_p + FLT_EPSILON || (p >= best_p && ofs_diff < best_ofs_diff)) { + best_p = p; + best_ofs_diff = ofs_diff; + best_n0 = k; + best_n1 = m; } } } - else { - uint best = 0; - uint best_group = 0; - float best_p = -1.0f; - for (uint k = 0; k < queue_index; k++) { - for (uint m = 0; m < face_nors_len; m++) { - float p = dot_v3v3(face_nors[m], normals_queue[k]); - if (p > best_p + FLT_EPSILON) { - best_p = p; - best = m; - best_group = k; + /* Make sure there are no equal planes. This threshold is crucial for the + * methods below to work without numerical issues. */ + if (best_p < 0.98f) { + break; + } + add_v3_v3(planes_queue[best_n0], planes_queue[best_n1]); + normalize_v3(planes_queue[best_n0]); + planes_queue[best_n0][3] = (planes_queue[best_n0][3] + planes_queue[best_n1][3]) * + 0.5f; + queue_index--; + memmove(planes_queue + best_n1, + planes_queue + best_n1 + 1, + (queue_index - best_n1) * sizeof(*planes_queue)); + } + const uint size = queue_index; + /* If there is more than 2 planes at this vertex, the boundary fix should be disabled + * to stay at the correct thickness for all the faces. This is not very good in + * practice though, since that will almost always disable the boundary fix. Instead + * introduce a threshold which decides whether the boundary fix can be used without + * major thickness changes. If the following constant is 1.0, it would always + * prioritize correct thickness. At 0.7 the thickness is allowed to change a bit if + * necessary for the fix (~10%). Note this only applies if a boundary fix is used. */ + const float boundary_fix_threshold = 0.7f; + if (size > 3) { + /* Use the most general least squares method to find the best position. */ + float mat[3][3]; + zero_m3(mat); + for (int k = 0; k < 3; k++) { + for (int m = 0; m < size; m++) { + madd_v3_v3fl(mat[k], planes_queue[m], planes_queue[m][k]); + } + /* Add a small epsilon to ensure the invert is going to work. + * This addition makes the inverse more stable and the results + * seem to get more precise. */ + mat[k][k] += 5e-5f; + } + /* NOTE: this matrix invert fails if there is less than 3 different normals. */ + invert_m3(mat); + zero_v3(nor); + for (int k = 0; k < size; k++) { + madd_v3_v3fl(nor, planes_queue[k], planes_queue[k][3]); + } + mul_v3_m3v3(nor, mat, nor); + + if (!disable_boundary_fix) { + /* Figure out if the approximate boundary fix can get use here. */ + float greatest_angle_cos = 1.0f; + for (uint k = 0; k < 2; k++) { + for (uint m = 2; m < size; m++) { + float p = dot_v3v3(planes_queue[m], planes_queue[k]); + if (p < greatest_angle_cos) { + greatest_angle_cos = p; } } } - add_v3_v3(face_nors[best], normals_queue[best_group]); - normalize_v3(face_nors[best]); - nor_ofs[best] = (nor_ofs[best] + normals_queue[best_group][3]) * 0.5f; - queue_index--; - memmove(normals_queue + best_group, - normals_queue + best_group + 1, - (queue_index - best_group) * sizeof(*normals_queue)); + if (greatest_angle_cos > boundary_fix_threshold) { + approximate_free_direction = true; + } + else { + disable_boundary_fix = true; + } } } - MEM_freeN(normals_queue); - - /* When up to 3 constraint normals are found. */ - if (ELEM(face_nors_len, 2, 3)) { - const float q = dot_v3v3(face_nors[0], face_nors[1]); + else if (size > 1) { + /* When up to 3 constraint normals are found, there is a simple solution. */ + const float stop_explosion = 0.999f - fabsf(smd->offset_fac) * 0.05f; + const float q = dot_v3v3(planes_queue[0], planes_queue[1]); float d = 1.0f - q * q; - cross_v3_v3v3(move_nor, face_nors[0], face_nors[1]); + cross_v3_v3v3(move_nor, planes_queue[0], planes_queue[1]); + normalize_v3(move_nor); if (d > FLT_EPSILON * 10 && q < stop_explosion) { d = 1.0f / d; - mul_v3_fl(face_nors[0], (nor_ofs[0] - nor_ofs[1] * q) * d); - mul_v3_fl(face_nors[1], (nor_ofs[1] - nor_ofs[0] * q) * d); + mul_v3_fl(planes_queue[0], (planes_queue[0][3] - planes_queue[1][3] * q) * d); + mul_v3_fl(planes_queue[1], (planes_queue[1][3] - planes_queue[0][3] * q) * d); } else { d = 1.0f / (fabsf(q) + 1.0f); - mul_v3_fl(face_nors[0], nor_ofs[0] * d); - mul_v3_fl(face_nors[1], nor_ofs[1] * d); + mul_v3_fl(planes_queue[0], planes_queue[0][3] * d); + mul_v3_fl(planes_queue[1], planes_queue[1][3] * d); } - add_v3_v3v3(nor, face_nors[0], face_nors[1]); - if (face_nors_len == 3) { - float *free_nor = move_nor; - mul_v3_fl(face_nors[2], nor_ofs[2]); - d = dot_v3v3(face_nors[2], free_nor); - if (LIKELY(fabsf(d) > FLT_EPSILON)) { - sub_v3_v3v3(face_nors[0], nor, face_nors[2]); /* Override face_nor[0]. */ - mul_v3_fl(free_nor, dot_v3v3(face_nors[2], face_nors[0]) / d); - sub_v3_v3(nor, free_nor); + add_v3_v3v3(nor, planes_queue[0], planes_queue[1]); + if (size == 3) { + d = dot_v3v3(planes_queue[2], move_nor); + /* The following threshold ignores the third plane if it is almost orthogonal to + * the still free direction. */ + if (fabsf(d) > 0.02f) { + float tmp[3]; + madd_v3_v3v3fl(tmp, nor, planes_queue[2], -planes_queue[2][3]); + mul_v3_v3fl(tmp, move_nor, dot_v3v3(planes_queue[2], tmp) / d); + sub_v3_v3(nor, tmp); + /* Disable boundary fix if the constraints would be majorly unsatisfied. */ + if (fabsf(d) > 1.0f - boundary_fix_threshold) { + disable_boundary_fix = true; + } } + } + approximate_free_direction = false; + } + else if (size == 1) { + /* Face corner case. */ + mul_v3_v3fl(nor, planes_queue[0], planes_queue[0][3]); + if (g->edges_len > 2) { disable_boundary_fix = true; + approximate_free_direction = true; } } else { - BLI_assert(face_nors_len < 2); - mul_v3_v3fl(nor, face_nors[0], nor_ofs[0]); + /* Fallback case for null faces. */ + mul_v3_v3fl(nor, fallback_nor, fallback_ofs); disable_boundary_fix = true; } + MEM_freeN(planes_queue); } /* Fixed/Even Method. */ else { @@ -1707,26 +1754,29 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } /* Set move_nor for boundary fix. */ if (!disable_boundary_fix && g->edges_len > 2) { - edge_ptr = g->edges + 1; - float tmp[3]; - uint k; - for (k = 1; k + 1 < g->edges_len; k++, edge_ptr++) { - MEdge *e = orig_medge + (*edge_ptr)->old_edge; - sub_v3_v3v3( - tmp, orig_mvert_co[vm[e->v1] == i ? e->v2 : e->v1], orig_mvert_co[i]); - add_v3_v3(move_nor, tmp); - } - if (k == 1) { - disable_boundary_fix = true; - } - else { - disable_boundary_fix = normalize_v3(move_nor) == 0.0f; - } + approximate_free_direction = true; } else { disable_boundary_fix = true; } } + if (approximate_free_direction) { + /* Set move_nor for boundary fix. */ + NewEdgeRef **edge_ptr = g->edges + 1; + float tmp[3]; + int k; + for (k = 1; k + 1 < g->edges_len; k++, edge_ptr++) { + MEdge *e = orig_medge + (*edge_ptr)->old_edge; + sub_v3_v3v3(tmp, orig_mvert_co[vm[e->v1] == i ? e->v2 : e->v1], orig_mvert_co[i]); + add_v3_v3(move_nor, tmp); + } + if (k == 1) { + disable_boundary_fix = true; + } + else { + disable_boundary_fix = normalize_v3(move_nor) == 0.0f; + } + } /* Fix boundary verts. */ if (!disable_boundary_fix) { /* Constraint normal, nor * constr_nor == 0 after this fix. */ @@ -1743,8 +1793,11 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, orig_mvert_co[i]); if (smd->nonmanifold_boundary_mode == MOD_SOLIDIFY_NONMANIFOLD_BOUNDARY_MODE_FLAT) { cross_v3_v3v3(constr_nor, e0, e1); + normalize_v3(constr_nor); } else { + BLI_assert(smd->nonmanifold_boundary_mode == + MOD_SOLIDIFY_NONMANIFOLD_BOUNDARY_MODE_ROUND); float f0[3]; float f1[3]; if (g->edges[0]->faces[0]->reversed) { @@ -1766,9 +1819,11 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, normalize_v3(n0); normalize_v3(n1); add_v3_v3v3(constr_nor, n0, n1); + normalize_v3(constr_nor); } float d = dot_v3v3(constr_nor, move_nor); - if (LIKELY(fabsf(d) > FLT_EPSILON)) { + /* Only allow the thickness to increase about 10 times. */ + if (fabsf(d) > 0.1f) { mul_v3_fl(move_nor, dot_v3v3(constr_nor, nor) / d); sub_v3_v3(nor, move_nor); } diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index cad36959f2b..b791e28d15b 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -234,7 +234,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * * assigned at this stage of modifier stack evaluation. */ const bool is_editmode = (mesh->edit_mesh != NULL); const int required_mode = BKE_subsurf_modifier_eval_required_mode(is_render_mode, is_editmode); - if (BKE_subsurf_modifier_can_do_gpu_subdiv_ex(scene, ctx->object, smd, required_mode, false)) { + if (BKE_subsurf_modifier_can_do_gpu_subdiv_ex( + scene, ctx->object, mesh, smd, required_mode, false)) { subdiv_cache_cpu_evaluation_settings(ctx, mesh, smd); return result; } @@ -246,9 +247,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* Happens on bad topology, but also on empty input mesh. */ return result; } - const bool use_clnors = (smd->flags & eSubsurfModifierFlag_UseCustomNormals) && - (mesh->flag & ME_AUTOSMOOTH) && - CustomData_has_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); + const bool use_clnors = BKE_subsurf_modifier_use_custom_loop_normals(smd, mesh); if (use_clnors) { /* If custom normals are present and the option is turned on calculate the split * normals and clear flag so the normals get interpolated to the result mesh. */ @@ -412,6 +411,13 @@ static void panel_draw(const bContext *C, Panel *panel) uiItemR(layout, ptr, "show_only_control_edges", 0, NULL, ICON_NONE); + SubsurfModifierData *smd = ptr->data; + Object *ob = ob_ptr.data; + Mesh *mesh = ob->data; + if (BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(smd, mesh)) { + uiItemL(layout, "Autosmooth or custom normals detected, disabling GPU subdivision", ICON_INFO); + } + modifier_panel_end(layout, ptr); } diff --git a/source/blender/modifiers/intern/MOD_ui_common.c b/source/blender/modifiers/intern/MOD_ui_common.c index 94482742831..90652c180c6 100644 --- a/source/blender/modifiers/intern/MOD_ui_common.c +++ b/source/blender/modifiers/intern/MOD_ui_common.c @@ -324,7 +324,7 @@ static void modifier_panel_header(const bContext *C, Panel *panel) buttons_number++; } } /* Tessellation point for curve-typed objects. */ - else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { + else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) { /* Some modifiers can work with pre-tessellated curves only. */ if (ELEM(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) { /* Add button (appearing to be ON) and add tip why this can't be changed. */ diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index 41b600e386b..a8c52108cc0 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -204,7 +204,7 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob, BKE_mesh_orco_ensure(ob, mesh); } } - else if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) { + else if (ELEM(ob->type, OB_FONT, OB_CURVES_LEGACY, OB_SURF)) { /* TODO(sybren): get evaluated mesh from depsgraph once * that's properly generated for curves. */ mesh = BKE_mesh_new_nomain_from_curve(ob); diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c index 51ec0a46d32..d6f493267f8 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.c +++ b/source/blender/modifiers/intern/MOD_uvproject.c @@ -285,9 +285,6 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, mesh->runtime.is_original = false; - /* Mark tessellated CD layers as dirty. */ - mesh->runtime.cd_dirty_vert |= CD_MASK_TESSLOOPNORMAL; - return mesh; } diff --git a/source/blender/modifiers/intern/MOD_volume_displace.cc b/source/blender/modifiers/intern/MOD_volume_displace.cc index 3e71d1fb106..5ce76046294 100644 --- a/source/blender/modifiers/intern/MOD_volume_displace.cc +++ b/source/blender/modifiers/intern/MOD_volume_displace.cc @@ -189,10 +189,8 @@ struct DisplaceGridOp { template<typename GridType> void operator()() { - if constexpr (blender::is_same_any_v<GridType, - openvdb::points::PointDataGrid, - openvdb::StringGrid, - openvdb::MaskGrid>) { + if constexpr (blender:: + is_same_any_v<GridType, openvdb::points::PointDataGrid, openvdb::MaskGrid>) { /* We don't support displacing these grid types yet. */ return; } diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c index 1078ebfaeb2..1b6472e2d42 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.c +++ b/source/blender/modifiers/intern/MOD_weightvgmix.c @@ -105,6 +105,12 @@ static float mix_weight(float weight, float weight2, char mix_mode) if (mix_mode == MOD_WVG_MIX_AVG) { return (weight + weight2) * 0.5f; } + if (mix_mode == MOD_WVG_MIX_MIN) { + return (weight < weight2 ? weight : weight2); + } + if (mix_mode == MOD_WVG_MIX_MAX) { + return (weight > weight2 ? weight : weight2); + } return weight2; } |