diff options
Diffstat (limited to 'source/blender/modifiers')
68 files changed, 2473 insertions, 1367 deletions
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index cec7ddb4b68..8ab7d35070b 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -59,7 +59,7 @@ set(SRC intern/MOD_laplaciandeform.c intern/MOD_laplaciansmooth.c intern/MOD_lattice.c - intern/MOD_mask.c + intern/MOD_mask.cc intern/MOD_meshcache.c intern/MOD_meshcache_mdd.c intern/MOD_meshcache_pc2.c @@ -78,6 +78,7 @@ set(SRC intern/MOD_shapekey.c intern/MOD_shrinkwrap.c intern/MOD_simpledeform.c + intern/MOD_simulation.cc intern/MOD_skin.c intern/MOD_smooth.c intern/MOD_softbody.c @@ -116,7 +117,7 @@ set(LIB if(WITH_ALEMBIC) add_definitions(-DWITH_ALEMBIC) list(APPEND INC - ../alembic + ../io/alembic ) list(APPEND LIB bf_alembic diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h index 7dd1ce830aa..ba676bbe459 100644 --- a/source/blender/modifiers/MOD_modifiertypes.h +++ b/source/blender/modifiers/MOD_modifiertypes.h @@ -23,6 +23,10 @@ #include "BKE_modifier.h" +#ifdef __cplusplus +extern "C" { +#endif + /* ****************** Type structures for all modifiers ****************** */ extern ModifierTypeInfo modifierType_None; @@ -82,8 +86,13 @@ extern ModifierTypeInfo modifierType_CorrectiveSmooth; extern ModifierTypeInfo modifierType_MeshSequenceCache; extern ModifierTypeInfo modifierType_SurfaceDeform; extern ModifierTypeInfo modifierType_WeightedNormal; +extern ModifierTypeInfo modifierType_Simulation; /* MOD_util.c */ void modifier_type_init(ModifierTypeInfo *types[]); +#ifdef __cplusplus +} +#endif + #endif /* __MOD_MODIFIERTYPES_H__ */ diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c index 9f3802a4fa1..29d456e5126 100644 --- a/source/blender/modifiers/intern/MOD_armature.c +++ b/source/blender/modifiers/intern/MOD_armature.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -23,18 +23,18 @@ #include <string.h> -#include "BLI_utildefines.h" #include "BLI_listbase.h" +#include "BLI_utildefines.h" #include "DNA_armature_types.h" -#include "DNA_object_types.h" #include "DNA_mesh_types.h" +#include "DNA_object_types.h" #include "BKE_action.h" #include "BKE_editmesh.h" #include "BKE_lattice.h" -#include "BKE_library.h" -#include "BKE_library_query.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" #include "BKE_mesh.h" #include "BKE_modifier.h" @@ -61,7 +61,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla #endif ArmatureModifierData *tamd = (ArmatureModifierData *)target; - modifier_copyData_generic(md, target, flag); + BKE_modifier_copydata_generic(md, target, flag); tamd->prevCos = NULL; } @@ -234,7 +234,7 @@ static void deformMatrices(ModifierData *md, amd->defgrp_name, NULL); - if (mesh_src != mesh) { + if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); } } @@ -244,7 +244,7 @@ ModifierTypeInfo modifierType_Armature = { /* structName */ "ArmatureModifierData", /* structSize */ sizeof(ArmatureModifierData), /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice | + /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, /* copyData */ copyData, @@ -253,7 +253,10 @@ ModifierTypeInfo modifierType_Armature = { /* deformMatrices */ deformMatrices, /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ deformMatricesEM, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index 3b50cfe704a..fc127c48fc9 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -35,12 +35,12 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "BKE_displist.h" #include "BKE_curve.h" -#include "BKE_library.h" -#include "BKE_library_query.h" -#include "BKE_modifier.h" +#include "BKE_displist.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" #include "BKE_mesh.h" +#include "BKE_modifier.h" #include "BKE_object_deform.h" #include "MOD_util.h" @@ -353,7 +353,6 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, const ModifierEvalContext *ctx, Mesh *mesh) { - const float eps = 1e-6f; const MVert *src_mvert; MVert *mv, *mv_prev, *result_dm_verts; @@ -473,20 +472,51 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, } } + /* About 67 million vertices max seems a decent limit for now. */ + const size_t max_num_vertices = 1 << 26; + /* calculate the maximum number of copies which will fit within the * prescribed length */ if (amd->fit_type == MOD_ARR_FITLENGTH || amd->fit_type == MOD_ARR_FITCURVE) { + const float float_epsilon = 1e-6f; + bool offset_is_too_small = false; float dist = len_v3(offset[3]); - if (dist > eps) { + if (dist > float_epsilon) { /* this gives length = first copy start to last copy end * add a tiny offset for floating point rounding errors */ - count = (length + eps) / dist + 1; + count = (length + float_epsilon) / dist + 1; + + /* Ensure we keep things to a reasonable level, in terms of rough total amount of generated + * vertices. + */ + if (((size_t)count * (size_t)chunk_nverts + (size_t)start_cap_nverts + + (size_t)end_cap_nverts) > max_num_vertices) { + count = 1; + offset_is_too_small = true; + } } else { /* if the offset has no translation, just make one copy */ count = 1; + offset_is_too_small = true; } + + if (offset_is_too_small) { + BKE_modifier_set_error( + &amd->modifier, + "The offset is too small, we cannot generate the amount of geometry it would require"); + } + } + /* Ensure we keep things to a reasonable level, in terms of rough total amount of generated + * vertices. + */ + else if (((size_t)count * (size_t)chunk_nverts + (size_t)start_cap_nverts + + (size_t)end_cap_nverts) > max_num_vertices) { + count = 1; + BKE_modifier_set_error(&amd->modifier, + "The amount of copies is too high, we cannot generate the amount of " + "geometry it would require"); } if (count < 1) { @@ -761,7 +791,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, return result; } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { ArrayModifierData *amd = (ArrayModifierData *)md; return arrayModifier_doArray(amd, ctx, mesh); @@ -801,13 +831,16 @@ ModifierTypeInfo modifierType_Array = { eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode | eModifierTypeFlag_AcceptsCVs, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ NULL, diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index f5bb1cb0ef8..fb1b3cd219e 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -27,11 +27,11 @@ #include "BLI_math.h" +#include "DNA_curveprofile_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "DNA_curveprofile_types.h" #include "BKE_deform.h" #include "BKE_mesh.h" @@ -39,9 +39,9 @@ #include "MOD_util.h" +#include "BKE_curveprofile.h" #include "bmesh.h" #include "bmesh_tools.h" -#include "BKE_curveprofile.h" #include "DEG_depsgraph_query.h" @@ -72,7 +72,7 @@ static void copyData(const ModifierData *md_src, ModifierData *md_dst, const int const BevelModifierData *bmd_src = (const BevelModifierData *)md_src; BevelModifierData *bmd_dst = (BevelModifierData *)md_dst; - modifier_copyData_generic(md_src, md_dst, flag); + BKE_modifier_copydata_generic(md_src, md_dst, flag); bmd_dst->custom_profile = BKE_curveprofile_copy(bmd_src->custom_profile); } @@ -91,7 +91,7 @@ static void requiredDataMask(Object *UNUSED(ob), /* * This calls the new bevel code (added since 2.64) */ -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { Mesh *result; BMesh *bm; @@ -118,6 +118,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes const float spread = bmd->spread; const bool use_custom_profile = (bmd->flags & MOD_BEVEL_CUSTOM_PROFILE); const int vmesh_method = bmd->vmesh_method; + const bool invert_vgroup = (bmd->flags & MOD_BEVEL_INVERT_VGROUP) != 0; bm = BKE_mesh_to_bmesh_ex(mesh, &(struct BMeshCreateParams){0}, @@ -146,7 +147,10 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes } } else if (vgroup != -1) { - weight = defvert_array_find_weight_safe(dvert, BM_elem_index_get(v), vgroup); + weight = invert_vgroup ? + 1.0f - + BKE_defvert_array_find_weight_safe(dvert, BM_elem_index_get(v), vgroup) : + BKE_defvert_array_find_weight_safe(dvert, BM_elem_index_get(v), vgroup); /* Check is against 0.5 rather than != 0.0 because cascaded bevel modifiers will * interpolate weights for newly created vertices, and may cause unexpected "selection" */ if (weight < 0.5f) { @@ -180,8 +184,14 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes } } else if (vgroup != -1) { - weight = defvert_array_find_weight_safe(dvert, BM_elem_index_get(e->v1), vgroup); - weight2 = defvert_array_find_weight_safe(dvert, BM_elem_index_get(e->v2), vgroup); + weight = invert_vgroup ? + 1.0f - BKE_defvert_array_find_weight_safe( + dvert, BM_elem_index_get(e->v1), vgroup) : + BKE_defvert_array_find_weight_safe(dvert, BM_elem_index_get(e->v1), vgroup); + weight2 = invert_vgroup ? 1.0f - BKE_defvert_array_find_weight_safe( + dvert, BM_elem_index_get(e->v2), vgroup) : + BKE_defvert_array_find_weight_safe( + dvert, BM_elem_index_get(e->v2), vgroup); if (weight < 0.5f || weight2 < 0.5f) { continue; } @@ -196,7 +206,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes Object *ob = ctx->object; if (harden_normals && (ob->type == OB_MESH) && !(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH)) { - modifier_setError(md, "Enable 'Auto Smooth' option in mesh settings for hardening"); + BKE_modifier_set_error(md, "Enable 'Auto Smooth' in Object Data Properties"); harden_normals = false; } @@ -265,7 +275,10 @@ ModifierTypeInfo modifierType_Bevel = { /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, /* freeData */ freeData, diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c index 9868395c0e8..d8b375b0ee9 100644 --- a/source/blender/modifiers/intern/MOD_boolean.c +++ b/source/blender/modifiers/intern/MOD_boolean.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -36,8 +36,8 @@ #include "DNA_object_types.h" #include "BKE_global.h" /* only to check G.debug */ -#include "BKE_library.h" -#include "BKE_library_query.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" #include "BKE_material.h" #include "BKE_mesh.h" #include "BKE_modifier.h" @@ -153,7 +153,7 @@ static int bm_face_isect_pair(BMFace *f, void *UNUSED(user_data)) return BM_elem_flag_test(f, BM_FACE_TAG) ? 1 : 0; } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { BooleanModifierData *bmd = (BooleanModifierData *)md; Mesh *result = mesh; @@ -260,7 +260,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes /* Using original (not evaluated) object here since we are writing to it. */ /* XXX Pretty sure comment above is fully wrong now with CoW & co ? */ - BKE_material_remap_object_calc(ctx->object, other, material_remap); + BKE_object_material_remap_calc(ctx->object, other, material_remap); BMFace *efa; i = 0; @@ -330,7 +330,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes /* if new mesh returned, return it; otherwise there was * an error, so delete the modifier object */ if (result == NULL) { - modifier_setError(md, "Cannot execute boolean operation"); + BKE_modifier_set_error(md, "Cannot execute boolean operation"); } } @@ -351,15 +351,18 @@ ModifierTypeInfo modifierType_Boolean = { /* structName */ "BooleanModifierData", /* structSize */ sizeof(BooleanModifierData), /* type */ eModifierTypeType_Nonconstructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_UsesPointCache, + /* flags */ eModifierTypeFlag_AcceptsMesh, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c index e61f6877d09..2cd52005362 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -29,8 +29,8 @@ #include "BLI_math_vector.h" #include "BLI_rand.h" -#include "DNA_meshdata_types.h" #include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DEG_depsgraph_query.h" @@ -55,7 +55,7 @@ static bool dependsOnTime(ModifierData *UNUSED(md)) return true; } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, struct Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct Mesh *mesh) { Mesh *result; BuildModifierData *bmd = (BuildModifierData *)md; @@ -282,13 +282,16 @@ ModifierTypeInfo modifierType_Build = { /* type */ eModifierTypeType_Nonconstructive, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ NULL, diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c index b070a3c7127..5f2043d8c09 100644 --- a/source/blender/modifiers/intern/MOD_cast.c +++ b/source/blender/modifiers/intern/MOD_cast.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -31,8 +31,8 @@ #include "BKE_deform.h" #include "BKE_editmesh.h" -#include "BKE_library.h" -#include "BKE_library_query.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" #include "BKE_mesh.h" #include "BKE_modifier.h" @@ -153,7 +153,9 @@ static void sphere_do(CastModifierData *cmd, /* 3) if we were given a vertex group name, * only those vertices should be affected */ - MOD_get_vgroup(ob, mesh, cmd->defgrp_name, &dvert, &defgrp_index); + if (cmd->defgrp_name[0] != '\0') { + MOD_get_vgroup(ob, mesh, cmd->defgrp_name, &dvert, &defgrp_index); + } if (flag & MOD_CAST_SIZE_FROM_RADIUS) { len = cmd->radius; @@ -199,8 +201,9 @@ static void sphere_do(CastModifierData *cmd, } if (dvert) { - const float weight = invert_vgroup ? 1.0f - defvert_find_weight(&dvert[i], defgrp_index) : - defvert_find_weight(&dvert[i], defgrp_index); + const float weight = invert_vgroup ? + 1.0f - BKE_defvert_find_weight(&dvert[i], defgrp_index) : + BKE_defvert_find_weight(&dvert[i], defgrp_index); if (weight == 0.0f) { continue; @@ -243,11 +246,12 @@ static void cuboid_do(CastModifierData *cmd, int numVerts) { MDeformVert *dvert = NULL; + int defgrp_index; const bool invert_vgroup = (cmd->flag & MOD_CAST_INVERT_VGROUP) != 0; Object *ctrl_ob = NULL; - int i, defgrp_index; + int i; bool has_radius = false; short flag; float fac = cmd->fac; @@ -272,7 +276,9 @@ static void cuboid_do(CastModifierData *cmd, /* 3) if we were given a vertex group name, * only those vertices should be affected */ - MOD_get_vgroup(ob, mesh, cmd->defgrp_name, &dvert, &defgrp_index); + if (cmd->defgrp_name[0] != '\0') { + MOD_get_vgroup(ob, mesh, cmd->defgrp_name, &dvert, &defgrp_index); + } if (ctrl_ob) { if (flag & MOD_CAST_USE_OB_TRANSFORM) { @@ -370,8 +376,9 @@ static void cuboid_do(CastModifierData *cmd, } if (dvert) { - const float weight = invert_vgroup ? 1.0f - defvert_find_weight(&dvert[i], defgrp_index) : - defvert_find_weight(&dvert[i], defgrp_index); + const float weight = invert_vgroup ? + 1.0f - BKE_defvert_find_weight(&dvert[i], defgrp_index) : + BKE_defvert_find_weight(&dvert[i], defgrp_index); if (weight == 0.0f) { continue; @@ -489,10 +496,15 @@ static void deformVertsEM(ModifierData *md, int numVerts) { CastModifierData *cmd = (CastModifierData *)md; - Mesh *mesh_src = MOD_deform_mesh_eval_get( - ctx->object, editData, mesh, NULL, numVerts, false, false); + Mesh *mesh_src = NULL; - BLI_assert(mesh_src->totvert == numVerts); + if (cmd->defgrp_name[0] != '\0') { + mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false); + } + + if (mesh_src) { + BLI_assert(mesh_src->totvert == numVerts); + } if (cmd->type == MOD_CAST_TYPE_CUBOID) { cuboid_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts); @@ -501,7 +513,7 @@ static void deformVertsEM(ModifierData *md, sphere_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts); } - if (mesh_src != mesh) { + if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); } } @@ -511,16 +523,19 @@ ModifierTypeInfo modifierType_Cast = { /* structName */ "CastModifierData", /* structSize */ sizeof(CastModifierData), /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice | + /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ deformVerts, /* deformMatrices */ NULL, /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c index cc91e345c8f..da7485b5a2d 100644 --- a/source/blender/modifiers/intern/MOD_cloth.c +++ b/source/blender/modifiers/intern/MOD_cloth.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -30,8 +30,8 @@ #include "DNA_cloth_types.h" #include "DNA_key_types.h" #include "DNA_mesh_types.h" -#include "DNA_scene_types.h" #include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "MEM_guardedalloc.h" @@ -39,8 +39,8 @@ #include "BKE_effect.h" #include "BKE_global.h" #include "BKE_key.h" -#include "BKE_library.h" -#include "BKE_library_query.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_pointcache.h" @@ -179,7 +179,11 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla } else { tclmd->point_cache = BKE_ptcache_add(&tclmd->ptcaches); - tclmd->point_cache->step = 1; + if (clmd->point_cache != NULL) { + tclmd->point_cache->step = clmd->point_cache->step; + tclmd->point_cache->startframe = clmd->point_cache->startframe; + tclmd->point_cache->endframe = clmd->point_cache->endframe; + } } tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms); @@ -263,7 +267,10 @@ ModifierTypeInfo modifierType_Cloth = { /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c index 56e84423db4..0c6133ed7a6 100644 --- a/source/blender/modifiers/intern/MOD_collision.c +++ b/source/blender/modifiers/intern/MOD_collision.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -25,15 +25,15 @@ #include "BLI_math.h" -#include "DNA_object_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_object_types.h" #include "MEM_guardedalloc.h" #include "BKE_collision.h" #include "BKE_global.h" -#include "BKE_library.h" +#include "BKE_lib_id.h" #include "BKE_mesh.h" #include "BKE_mesh_runtime.h" #include "BKE_modifier.h" @@ -231,7 +231,7 @@ static void deformVerts(ModifierData *md, } } - if (mesh_src != mesh) { + if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); } } @@ -254,7 +254,10 @@ ModifierTypeInfo modifierType_Collision = { /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ NULL, diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c index ff241550bdc..6224cf6b1fc 100644 --- a/source/blender/modifiers/intern/MOD_correctivesmooth.c +++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -27,17 +27,17 @@ #include "BLI_math.h" -#include "DNA_scene_types.h" +#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" -#include "DNA_mesh_types.h" +#include "DNA_scene_types.h" #include "MEM_guardedalloc.h" #include "BKE_deform.h" -#include "BKE_mesh.h" #include "BKE_editmesh.h" -#include "BKE_library.h" +#include "BKE_lib_id.h" +#include "BKE_mesh.h" #include "MOD_modifiertypes.h" #include "MOD_util.h" @@ -64,6 +64,7 @@ static void initData(ModifierData *md) csmd->bind_coords_num = 0; csmd->lambda = 0.5f; + csmd->scale = 1.0f; csmd->repeat = 5; csmd->flag = 0; csmd->smooth_type = MOD_CORRECTIVESMOOTH_SMOOTH_SIMPLE; @@ -78,7 +79,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla const CorrectiveSmoothModifierData *csmd = (const CorrectiveSmoothModifierData *)md; CorrectiveSmoothModifierData *tcsmd = (CorrectiveSmoothModifierData *)target; - modifier_copyData_generic(md, target, flag); + BKE_modifier_copydata_generic(md, target, flag); if (csmd->bind_coords) { tcsmd->bind_coords = MEM_dupallocN(csmd->bind_coords); @@ -124,7 +125,7 @@ static void mesh_get_weights(MDeformVert *dvert, uint i; for (i = 0; i < numVerts; i++, dvert++) { - const float w = defvert_find_weight(dvert, defgrp_index); + const float w = BKE_defvert_find_weight(dvert, defgrp_index); if (use_invert_vgroup == false) { smooth_weights[i] = w; @@ -601,12 +602,12 @@ static void correctivesmooth_modifier_do(ModifierData *md, BLI_assert(csmd->bind_coords != NULL); /* Copy bound data to the original modifier. */ CorrectiveSmoothModifierData *csmd_orig = (CorrectiveSmoothModifierData *) - modifier_get_original(&csmd->modifier); + BKE_modifier_get_original(&csmd->modifier); csmd_orig->bind_coords = MEM_dupallocN(csmd->bind_coords); csmd_orig->bind_coords_num = csmd->bind_coords_num; } else { - modifier_setError(md, "Attempt to bind from inactive dependency graph"); + BKE_modifier_set_error(md, "Attempt to bind from inactive dependency graph"); } } @@ -616,14 +617,14 @@ static void correctivesmooth_modifier_do(ModifierData *md, } if ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) && (csmd->bind_coords == NULL)) { - modifier_setError(md, "Bind data required"); + BKE_modifier_set_error(md, "Bind data required"); goto error; } /* If the number of verts has changed, the bind is invalid, so we do nothing */ if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) { if (csmd->bind_coords_num != numVerts) { - modifier_setError( + BKE_modifier_set_error( md, "Bind vertex count mismatch: %u to %u", csmd->bind_coords_num, numVerts); goto error; } @@ -631,14 +632,15 @@ static void correctivesmooth_modifier_do(ModifierData *md, else { /* MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO */ if (ob->type != OB_MESH) { - modifier_setError(md, "Object is not a mesh"); + BKE_modifier_set_error(md, "Object is not a mesh"); goto error; } else { uint me_numVerts = (uint)((em) ? em->bm->totvert : ((Mesh *)ob->data)->totvert); if (me_numVerts != numVerts) { - modifier_setError(md, "Original vertex count mismatch: %u to %u", me_numVerts, numVerts); + BKE_modifier_set_error( + md, "Original vertex count mismatch: %u to %u", me_numVerts, numVerts); goto error; } } @@ -696,7 +698,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, uint i; float(*tangent_spaces)[3][3]; - + const float scale = csmd->scale; /* calloc, since values are accumulated */ tangent_spaces = MEM_calloc_arrayN(numVerts, sizeof(float[3][3]), __func__); @@ -710,7 +712,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, #endif mul_v3_m3v3(delta, tangent_spaces[i], csmd->delta_cache.deltas[i]); - add_v3_v3(vertexCos[i], delta); + madd_v3_v3fl(vertexCos[i], delta, scale); } MEM_freeN(tangent_spaces); @@ -739,7 +741,7 @@ static void deformVerts(ModifierData *md, correctivesmooth_modifier_do( md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (uint)numVerts, NULL); - if (mesh_src != mesh) { + if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); } } @@ -757,7 +759,7 @@ static void deformVertsEM(ModifierData *md, correctivesmooth_modifier_do( md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (uint)numVerts, editData); - if (mesh_src != mesh) { + if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); } } @@ -775,7 +777,10 @@ ModifierTypeInfo modifierType_CorrectiveSmooth = { /* deformMatrices */ NULL, /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c index f9137572d6f..238c8223799 100644 --- a/source/blender/modifiers/intern/MOD_curve.c +++ b/source/blender/modifiers/intern/MOD_curve.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -26,13 +26,13 @@ #include "BLI_utildefines.h" #include "DNA_mesh_types.h" -#include "DNA_scene_types.h" #include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "BKE_editmesh.h" #include "BKE_lattice.h" -#include "BKE_library.h" -#include "BKE_library_query.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" #include "BKE_mesh.h" #include "BKE_modifier.h" @@ -119,8 +119,14 @@ static void deformVerts(ModifierData *md, /* silly that defaxis and curve_deform_verts are off by 1 * but leave for now to save having to call do_versions */ - curve_deform_verts( - cmd->object, ctx->object, vertexCos, numVerts, dvert, defgrp_index, cmd->defaxis - 1); + curve_deform_verts(cmd->object, + ctx->object, + vertexCos, + numVerts, + dvert, + defgrp_index, + cmd->flag, + cmd->defaxis - 1); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); @@ -148,16 +154,19 @@ ModifierTypeInfo modifierType_Curve = { /* structName */ "CurveModifierData", /* structSize */ sizeof(CurveModifierData), /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice | + /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ deformVerts, /* deformMatrices */ NULL, /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_datatransfer.c b/source/blender/modifiers/intern/MOD_datatransfer.c index bb032f9725c..dea4bad6999 100644 --- a/source/blender/modifiers/intern/MOD_datatransfer.c +++ b/source/blender/modifiers/intern/MOD_datatransfer.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2014 Blender Foundation. @@ -32,8 +32,8 @@ #include "BKE_customdata.h" #include "BKE_data_transfer.h" -#include "BKE_library.h" -#include "BKE_library_query.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" #include "BKE_mesh_mapping.h" #include "BKE_mesh_remap.h" #include "BKE_modifier.h" @@ -156,7 +156,7 @@ static bool isDisabled(const struct Scene *UNUSED(scene), (DT_TYPE_BWEIGHT_VERT | DT_TYPE_BWEIGHT_EDGE | DT_TYPE_CREASE | DT_TYPE_SHARP_EDGE | \ DT_TYPE_LNOR | DT_TYPE_SHARP_FACE) -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *me_mod) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *me_mod) { DataTransferModifierData *dtmd = (DataTransferModifierData *)md; struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); @@ -184,7 +184,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes if (((result == me) || (me->mvert == result->mvert) || (me->medge == result->medge)) && (dtmd->data_types & DT_TYPES_AFFECT_MESH)) { - /* We need to duplicate data here, otherwise setting custom normals, edges' shaprness, etc., + /* We need to duplicate data here, otherwise setting custom normals, edges' sharpness, etc., * could modify org mesh, see T43671. */ BKE_id_copy_ex(NULL, &me_mod->id, (ID **)&result, LIB_ID_COPY_LOCALIZE); } @@ -217,16 +217,15 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes &reports); if (BKE_reports_contain(&reports, RPT_ERROR)) { - modifier_setError(md, "%s", BKE_reports_string(&reports, RPT_ERROR)); + BKE_modifier_set_error(md, "%s", BKE_reports_string(&reports, RPT_ERROR)); } else if ((dtmd->data_types & DT_TYPE_LNOR) && !(me->flag & ME_AUTOSMOOTH)) { - modifier_setError((ModifierData *)dtmd, "Enable 'Auto Smooth' option in mesh settings"); + BKE_modifier_set_error((ModifierData *)dtmd, "Enable 'Auto Smooth' in Object Data Properties"); } else if (result->totvert > HIGH_POLY_WARNING || ((Mesh *)(ob_source->data))->totvert > HIGH_POLY_WARNING) { - modifier_setError( - md, - "You are using a rather high poly as source or destination, computation might be slow"); + BKE_modifier_set_error( + md, "Source or destination object has a high polygon count, computation might be slow"); } return result; @@ -243,13 +242,16 @@ ModifierTypeInfo modifierType_DataTransfer = { /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_UsesPreview, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index c113a2767a0..3958713f7a8 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -25,9 +25,9 @@ #include "BLI_math.h" -#include "DNA_object_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_object_types.h" #include "MEM_guardedalloc.h" @@ -73,7 +73,7 @@ static DecimateModifierData *getOriginalModifierData(const DecimateModifierData const ModifierEvalContext *ctx) { Object *ob_orig = DEG_get_original_object(ctx->object); - return (DecimateModifierData *)modifiers_findByName(ob_orig, dmd->modifier.name); + return (DecimateModifierData *)BKE_modifiers_findny_name(ob_orig, dmd->modifier.name); } static void updateFaceCount(const ModifierEvalContext *ctx, @@ -89,7 +89,7 @@ static void updateFaceCount(const ModifierEvalContext *ctx, } } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *meshData) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *meshData) { DecimateModifierData *dmd = (DecimateModifierData *)md; Mesh *mesh = meshData, *result = NULL; @@ -128,7 +128,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes } if (dmd->face_count <= 3) { - modifier_setError(md, "Modifier requires more than 3 input faces"); + BKE_modifier_set_error(md, "Modifier requires more than 3 input faces"); return mesh; } @@ -147,12 +147,12 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes if (dmd->flag & MOD_DECIM_FLAG_INVERT_VGROUP) { for (i = 0; i < vert_tot; i++) { - vweights[i] = 1.0f - defvert_find_weight(&dvert[i], defgrp_index); + vweights[i] = 1.0f - BKE_defvert_find_weight(&dvert[i], defgrp_index); } } else { for (i = 0; i < vert_tot; i++) { - vweights[i] = defvert_find_weight(&dvert[i], defgrp_index); + vweights[i] = BKE_defvert_find_weight(&dvert[i], defgrp_index); } } } @@ -222,13 +222,16 @@ ModifierTypeInfo modifierType_Decimate = { /* type */ eModifierTypeType_Nonconstructive, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c index 9cb694be88b..514ea185ede 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -31,15 +31,15 @@ #include "DNA_object_types.h" #include "BKE_customdata.h" +#include "BKE_deform.h" #include "BKE_editmesh.h" -#include "BKE_library.h" -#include "BKE_library_query.h" #include "BKE_image.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" #include "BKE_mesh.h" #include "BKE_modifier.h" -#include "BKE_texture.h" -#include "BKE_deform.h" #include "BKE_object.h" +#include "BKE_texture.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" @@ -134,19 +134,28 @@ static bool isDisabled(const struct Scene *UNUSED(scene), static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) { DisplaceModifierData *dmd = (DisplaceModifierData *)md; - if (dmd->map_object != NULL && dmd->texmapping == MOD_DISP_MAP_OBJECT) { - DEG_add_modifier_to_transform_relation(ctx->node, "Displace Modifier"); - DEG_add_object_relation( - ctx->node, dmd->map_object, DEG_OB_COMP_TRANSFORM, "Displace Modifier"); - } - if (dmd->texmapping == MOD_DISP_MAP_GLOBAL || - (ELEM( - dmd->direction, MOD_DISP_DIR_X, MOD_DISP_DIR_Y, MOD_DISP_DIR_Z, MOD_DISP_DIR_RGB_XYZ) && - dmd->space == MOD_DISP_SPACE_GLOBAL)) { - DEG_add_modifier_to_transform_relation(ctx->node, "Displace Modifier"); + bool need_transform_relation = false; + + if (dmd->space == MOD_DISP_SPACE_GLOBAL && + ELEM(dmd->direction, MOD_DISP_DIR_X, MOD_DISP_DIR_Y, MOD_DISP_DIR_Z, MOD_DISP_DIR_RGB_XYZ)) { + need_transform_relation = true; } + if (dmd->texture != NULL) { DEG_add_generic_id_relation(ctx->node, &dmd->texture->id, "Displace Modifier"); + + if (dmd->map_object != NULL && dmd->texmapping == MOD_DISP_MAP_OBJECT) { + MOD_depsgraph_update_object_bone_relation( + ctx->node, dmd->map_object, dmd->map_bone, "Displace Modifier"); + need_transform_relation = true; + } + if (dmd->texmapping == MOD_DISP_MAP_GLOBAL) { + need_transform_relation = true; + } + } + + if (need_transform_relation) { + DEG_add_modifier_to_transform_relation(ctx->node, "Displace Modifier"); } } @@ -174,6 +183,7 @@ static void displaceModifier_do_task(void *__restrict userdata, DisplaceUserdata *data = (DisplaceUserdata *)userdata; DisplaceModifierData *dmd = data->dmd; MDeformVert *dvert = data->dvert; + const bool invert_vgroup = (dmd->flag & MOD_DISP_INVERT_VGROUP) != 0; float weight = data->weight; int defgrp_index = data->defgrp_index; int direction = data->direction; @@ -192,7 +202,8 @@ static void displaceModifier_do_task(void *__restrict userdata, float local_vec[3]; if (dvert) { - weight = defvert_find_weight(dvert + iter, defgrp_index); + weight = invert_vgroup ? 1.0f - BKE_defvert_find_weight(dvert + iter, defgrp_index) : + BKE_defvert_find_weight(dvert + iter, defgrp_index); if (weight == 0.0f) { return; } @@ -410,13 +421,16 @@ ModifierTypeInfo modifierType_Displace = { /* type */ eModifierTypeType_OnlyDeform, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ deformVerts, /* deformMatrices */ NULL, /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c index 83d8439f046..3cace5745e6 100644 --- a/source/blender/modifiers/intern/MOD_dynamicpaint.c +++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ @@ -20,17 +20,18 @@ #include <stddef.h> +#include "BLI_listbase.h" #include "BLI_utildefines.h" #include "DNA_dynamicpaint_types.h" -#include "DNA_object_types.h" +#include "DNA_mesh_types.h" #include "DNA_object_force_types.h" +#include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "DNA_mesh_types.h" #include "BKE_dynamicpaint.h" #include "BKE_layer.h" -#include "BKE_library_query.h" +#include "BKE_lib_query.h" #include "BKE_mesh.h" #include "BKE_modifier.h" @@ -100,7 +101,7 @@ static void requiredDataMask(Object *UNUSED(ob), } } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md; @@ -123,8 +124,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md; /* Add relation from canvases to all brush objects. */ if (pmd->canvas != NULL && pmd->type == MOD_DYNAMICPAINT_TYPE_CANVAS) { - for (DynamicPaintSurface *surface = pmd->canvas->surfaces.first; surface; - surface = surface->next) { + LISTBASE_FOREACH (DynamicPaintSurface *, surface, &pmd->canvas->surfaces) { if (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) { DEG_add_forcefield_relations( ctx->node, ctx->object, surface->effector_weights, true, 0, "Dynamic Paint Field"); @@ -187,7 +187,10 @@ ModifierTypeInfo modifierType_DynamicPaint = { /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c index 69ba4aa2795..dd5669cd10c 100644 --- a/source/blender/modifiers/intern/MOD_edgesplit.c +++ b/source/blender/modifiers/intern/MOD_edgesplit.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -113,7 +113,7 @@ static void initData(ModifierData *md) emd->flags = MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG; } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh) { Mesh *result; EdgeSplitModifierData *emd = (EdgeSplitModifierData *)md; @@ -136,13 +136,16 @@ ModifierTypeInfo modifierType_EdgeSplit = { eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ NULL, diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 5f0bbc8ecf1..747269f4c80 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -28,14 +28,14 @@ #include "BLI_math.h" #include "BLI_rand.h" +#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" -#include "DNA_scene_types.h" #include "DNA_object_types.h" -#include "DNA_mesh_types.h" +#include "DNA_scene_types.h" #include "BKE_deform.h" #include "BKE_lattice.h" -#include "BKE_library.h" +#include "BKE_lib_id.h" #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_particle.h" @@ -67,7 +67,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla #endif ExplodeModifierData *temd = (ExplodeModifierData *)target; - modifier_copyData_generic(md, target, flag); + BKE_modifier_copydata_generic(md, target, flag); temd->facepa = NULL; } @@ -97,6 +97,7 @@ static void createFacepa(ExplodeModifierData *emd, ParticleSystemModifierData *p float center[3], co[3]; int *facepa = NULL, *vertpa = NULL, totvert = 0, totface = 0, totpart = 0; int i, p, v1, v2, v3, v4 = 0; + const bool invert_vgroup = (emd->flag & eExplodeFlag_INVERT_VGROUP) != 0; mvert = mesh->mvert; mface = mesh->mface; @@ -129,7 +130,9 @@ static void createFacepa(ExplodeModifierData *emd, ParticleSystemModifierData *p for (i = 0; i < totvert; i++, dvert++) { float val = BLI_rng_get_float(rng); val = (1.0f - emd->protect) * val + emd->protect * 0.5f; - if (val < defvert_find_weight(dvert, defgrp_index)) { + const float weight = invert_vgroup ? 1.0f - BKE_defvert_find_weight(dvert, defgrp_index) : + BKE_defvert_find_weight(dvert, defgrp_index); + if (val < weight) { vertpa[i] = -1; } } @@ -974,7 +977,6 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, explode = BKE_mesh_new_nomain_from_template(mesh, totdup, 0, totface - delface, 0, 0); mtface = CustomData_get_layer_named(&explode->fdata, CD_MTFACE, emd->uvname); - /*dupvert = CDDM_get_verts(explode);*/ /* getting back to object space */ invert_m4_m4(imat, ctx->object->obmat); @@ -1121,7 +1123,7 @@ static ParticleSystemModifierData *findPrecedingParticlesystem(Object *ob, Modif } return psmd; } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { ExplodeModifierData *emd = (ExplodeModifierData *)md; ParticleSystemModifierData *psmd = findPrecedingParticlesystem(ctx->object, md); @@ -1184,7 +1186,10 @@ ModifierTypeInfo modifierType_Explode = { /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_fluid.c b/source/blender/modifiers/intern/MOD_fluid.c index b48c80d8e32..d3f05ee714f 100644 --- a/source/blender/modifiers/intern/MOD_fluid.c +++ b/source/blender/modifiers/intern/MOD_fluid.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -28,17 +28,16 @@ #include "BLI_utildefines.h" #include "DNA_collection_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" #include "DNA_fluid_types.h" -#include "DNA_object_force_types.h" #include "DNA_mesh_types.h" +#include "DNA_object_force_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" -#include "BKE_cdderivedmesh.h" +#include "BKE_fluid.h" #include "BKE_layer.h" -#include "BKE_library_query.h" +#include "BKE_lib_query.h" #include "BKE_modifier.h" -#include "BKE_fluid.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" @@ -102,7 +101,7 @@ static void requiredDataMask(Object *UNUSED(ob), } } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *me) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *me) { #ifndef WITH_FLUID UNUSED_VARS(md, ctx); @@ -160,7 +159,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte ctx->object, mmd->domain->effector_weights, true, - PFIELD_SMOKEFLOW, + PFIELD_FLUIDFLOW, "Fluid Force Field"); if (mmd->domain->guide_parent != NULL) { @@ -208,7 +207,10 @@ ModifierTypeInfo modifierType_Fluid = { /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c index 1a62010abe7..d93b3c56e5a 100644 --- a/source/blender/modifiers/intern/MOD_hook.c +++ b/source/blender/modifiers/intern/MOD_hook.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -30,13 +30,13 @@ #include "DNA_object_types.h" #include "BKE_action.h" +#include "BKE_colortools.h" +#include "BKE_deform.h" #include "BKE_editmesh.h" -#include "BKE_library.h" -#include "BKE_library_query.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" #include "BKE_mesh.h" #include "BKE_modifier.h" -#include "BKE_deform.h" -#include "BKE_colortools.h" #include "DEG_depsgraph_query.h" @@ -59,7 +59,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla const HookModifierData *hmd = (const HookModifierData *)md; HookModifierData *thmd = (HookModifierData *)target; - modifier_copyData_generic(md, target, flag); + BKE_modifier_copydata_generic(md, target, flag); thmd->curfalloff = BKE_curvemapping_copy(hmd->curfalloff); @@ -143,6 +143,8 @@ struct HookData_cb { float mat_uniform[3][3]; float mat[4][4]; + + bool invert_vgroup; }; static float hook_falloff(const struct HookData_cb *hd, const float len_sq) @@ -236,7 +238,8 @@ static void hook_co_apply(struct HookData_cb *hd, const int j) if (fac) { if (hd->dvert) { - fac *= defvert_find_weight(&hd->dvert[j], hd->defgrp_index); + fac *= hd->invert_vgroup ? 1.0f - BKE_defvert_find_weight(&hd->dvert[j], hd->defgrp_index) : + BKE_defvert_find_weight(&hd->dvert[j], hd->defgrp_index); } if (fac) { @@ -259,6 +262,7 @@ static void deformVerts_do(HookModifierData *hmd, float dmat[4][4]; int i, *index_pt; struct HookData_cb hd; + const bool invert_vgroup = (hmd->flag & MOD_HOOK_INVERT_VGROUP) != 0; if (hmd->curfalloff == NULL) { /* should never happen, but bad lib linking could cause it */ @@ -277,12 +281,14 @@ static void deformVerts_do(HookModifierData *hmd, hd.falloff_type = hmd->falloff_type; hd.falloff = (hmd->falloff_type == eHook_Falloff_None) ? 0.0f : hmd->falloff; - hd.falloff_sq = SQUARE(hd.falloff); + hd.falloff_sq = square_f(hd.falloff); hd.fac_orig = hmd->force; hd.use_falloff = (hd.falloff_sq != 0.0f); hd.use_uniform = (hmd->flag & MOD_HOOK_UNIFORM_SPACE) != 0; + hd.invert_vgroup = invert_vgroup; + if (hd.use_uniform) { copy_m3_m4(hd.mat_uniform, hmd->parentinv); mul_v3_m3v3(hd.cent, hd.mat_uniform, hmd->cent); @@ -310,7 +316,7 @@ static void deformVerts_do(HookModifierData *hmd, * This should always be true and I don't generally like * "paranoid" style code like this, but old files can have * indices that are out of range because old blender did - * not correct them on exit editmode. - zr + * not correct them on exit edit-mode. - zr */ if (hmd->force == 0.0f) { @@ -387,7 +393,7 @@ ModifierTypeInfo modifierType_Hook = { /* structName */ "HookModifierData", /* structSize */ sizeof(HookModifierData), /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice | + /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, /* copyData */ copyData, @@ -395,7 +401,10 @@ ModifierTypeInfo modifierType_Hook = { /* deformMatrices */ NULL, /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c index 0fc2e0971da..095ca95594b 100644 --- a/source/blender/modifiers/intern/MOD_laplaciandeform.c +++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2013 by the Blender Foundation. @@ -34,7 +34,7 @@ #include "BKE_deform.h" #include "BKE_editmesh.h" -#include "BKE_library.h" +#include "BKE_lib_id.h" #include "BKE_mesh_mapping.h" #include "BKE_mesh_runtime.h" #include "BKE_particle.h" @@ -528,6 +528,7 @@ static void initSystem( MDeformVert *dvert = NULL; MDeformVert *dv = NULL; LaplacianSystem *sys; + const bool invert_vgroup = (lmd->flag & MOD_LAPLACIANDEFORM_INVERT_VGROUP) != 0; if (isValidVertexGroup(lmd, ob, mesh)) { int *index_anchors = MEM_malloc_arrayN(numVerts, sizeof(int), __func__); /* over-alloc */ @@ -542,7 +543,8 @@ static void initSystem( BLI_assert(dvert != NULL); dv = dvert; for (i = 0; i < numVerts; i++) { - wpaint = defvert_find_weight(dv, defgrp_index); + wpaint = invert_vgroup ? 1.0f - BKE_defvert_find_weight(dv, defgrp_index) : + BKE_defvert_find_weight(dv, defgrp_index); dv++; if (wpaint > 0.0f) { STACK_PUSH(index_anchors, i); @@ -596,6 +598,7 @@ static int isSystemDifferent(LaplacianDeformModifierData *lmd, MDeformVert *dvert = NULL; MDeformVert *dv = NULL; LaplacianSystem *sys = (LaplacianSystem *)lmd->cache_system; + const bool invert_vgroup = (lmd->flag & MOD_LAPLACIANDEFORM_INVERT_VGROUP) != 0; if (sys->total_verts != numVerts) { return LAPDEFORM_SYSTEM_CHANGE_VERTEXES; @@ -612,7 +615,8 @@ static int isSystemDifferent(LaplacianDeformModifierData *lmd, } dv = dvert; for (i = 0; i < numVerts; i++) { - wpaint = defvert_find_weight(dv, defgrp_index); + wpaint = invert_vgroup ? 1.0f - BKE_defvert_find_weight(dv, defgrp_index) : + BKE_defvert_find_weight(dv, defgrp_index); dv++; if (wpaint > 0.0f) { total_anchors++; @@ -663,17 +667,17 @@ static void LaplacianDeformModifier_do( } else { if (sysdif == LAPDEFORM_SYSTEM_CHANGE_VERTEXES) { - modifier_setError( + BKE_modifier_set_error( &lmd->modifier, "Vertices changed from %d to %d", lmd->total_verts, numVerts); } else if (sysdif == LAPDEFORM_SYSTEM_CHANGE_EDGES) { - modifier_setError( + BKE_modifier_set_error( &lmd->modifier, "Edges changed from %d to %d", sys->total_edges, mesh->totedge); } else if (sysdif == LAPDEFORM_SYSTEM_CHANGE_NOT_VALID_GROUP) { - modifier_setError(&lmd->modifier, - "Vertex group '%s' is not valid, or maybe empty", - sys->anchor_grp_name); + BKE_modifier_set_error(&lmd->modifier, + "Vertex group '%s' is not valid, or maybe empty", + sys->anchor_grp_name); } } } @@ -684,7 +688,7 @@ static void LaplacianDeformModifier_do( } else { if (!isValidVertexGroup(lmd, ob, mesh)) { - modifier_setError( + BKE_modifier_set_error( &lmd->modifier, "Vertex group '%s' is not valid, or maybe empty", lmd->anchor_grp_name); lmd->flag &= ~MOD_LAPLACIANDEFORM_BIND; } @@ -705,7 +709,7 @@ static void LaplacianDeformModifier_do( } } if (sys && sys->is_matrix_computed && !sys->has_solution) { - modifier_setError(&lmd->modifier, "The system did not find a solution"); + BKE_modifier_set_error(&lmd->modifier, "The system did not find a solution"); } } @@ -725,7 +729,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla const LaplacianDeformModifierData *lmd = (const LaplacianDeformModifierData *)md; LaplacianDeformModifierData *tlmd = (LaplacianDeformModifierData *)target; - modifier_copyData_generic(md, target, flag); + BKE_modifier_copydata_generic(md, target, flag); tlmd->vertexco = MEM_dupallocN(lmd->vertexco); tlmd->cache_system = NULL; @@ -810,7 +814,10 @@ ModifierTypeInfo modifierType_LaplacianDeform = { /* deformMatrices */ NULL, /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c index 86d4124e5db..2fefca68bad 100644 --- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c +++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -33,7 +33,7 @@ #include "BKE_deform.h" #include "BKE_editmesh.h" -#include "BKE_library.h" +#include "BKE_lib_id.h" #include "BKE_mesh.h" #include "BKE_modifier.h" @@ -378,6 +378,7 @@ static void laplaciansmoothModifier_do( float w, wpaint; int i, iter; int defgrp_index; + const bool invert_vgroup = (smd->flag & MOD_LAPLACIANSMOOTH_INVERT_VGROUP) != 0; sys = init_laplacian_system(mesh->totedge, mesh->totpoly, mesh->totloop, numVerts); if (!sys) { @@ -420,7 +421,8 @@ static void laplaciansmoothModifier_do( EIG_linear_solver_right_hand_side_add(sys->context, 2, i, vertexCos[i][2]); if (iter == 0) { if (dv) { - wpaint = defvert_find_weight(dv, defgrp_index); + wpaint = invert_vgroup ? 1.0f - BKE_defvert_find_weight(dv, defgrp_index) : + BKE_defvert_find_weight(dv, defgrp_index); dv++; } else { @@ -572,13 +574,16 @@ ModifierTypeInfo modifierType_LaplacianSmooth = { /* type */ eModifierTypeType_OnlyDeform, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ deformVerts, /* deformMatrices */ NULL, /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ init_data, /* requiredDataMask */ required_data_mask, diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c index a73e96da975..8dd507d51a4 100644 --- a/source/blender/modifiers/intern/MOD_lattice.c +++ b/source/blender/modifiers/intern/MOD_lattice.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -29,8 +29,8 @@ #include "BKE_editmesh.h" #include "BKE_lattice.h" -#include "BKE_library.h" -#include "BKE_library_query.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" #include "BKE_mesh.h" #include "BKE_modifier.h" @@ -101,8 +101,14 @@ static void deformVerts(ModifierData *md, MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */ - lattice_deform_verts( - lmd->object, ctx->object, mesh_src, vertexCos, numVerts, lmd->name, lmd->strength); + lattice_deform_verts(lmd->object, + ctx->object, + mesh_src, + vertexCos, + numVerts, + lmd->flag, + lmd->name, + lmd->strength); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); @@ -131,16 +137,19 @@ ModifierTypeInfo modifierType_Lattice = { /* structName */ "LatticeModifierData", /* structSize */ sizeof(LatticeModifierData), /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice | + /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ deformVerts, /* deformMatrices */ NULL, /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c deleted file mode 100644 index cf7d227e898..00000000000 --- a/source/blender/modifiers/intern/MOD_mask.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2005 by the Blender Foundation. - * All rights reserved. - */ - -/** \file - * \ingroup modifiers - */ - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" - -#include "BLI_listbase.h" -#include "BLI_ghash.h" - -#include "DNA_armature_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_modifier_types.h" -#include "DNA_object_types.h" - -#include "BKE_action.h" /* BKE_pose_channel_find_name */ -#include "BKE_customdata.h" -#include "BKE_library_query.h" -#include "BKE_mesh.h" -#include "BKE_modifier.h" -#include "BKE_deform.h" - -#include "DEG_depsgraph_build.h" -#include "DEG_depsgraph_query.h" - -#include "MOD_modifiertypes.h" - -#include "BLI_strict_flags.h" - -static void requiredDataMask(Object *UNUSED(ob), - ModifierData *UNUSED(md), - CustomData_MeshMasks *r_cddata_masks) -{ - r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; -} - -static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData) -{ - MaskModifierData *mmd = (MaskModifierData *)md; - walk(userData, ob, &mmd->ob_arm, IDWALK_CB_NOP); -} - -static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) -{ - MaskModifierData *mmd = (MaskModifierData *)md; - if (mmd->ob_arm) { - bArmature *arm = (bArmature *)mmd->ob_arm->data; - /* Tag relationship in depsgraph, but also on the armature. */ - /* TODO(sergey): Is it a proper relation here? */ - DEG_add_object_relation(ctx->node, mmd->ob_arm, DEG_OB_COMP_TRANSFORM, "Mask Modifier"); - arm->flag |= ARM_HAS_VIZ_DEPS; - DEG_add_modifier_to_transform_relation(ctx->node, "Mask Modifier"); - } -} - -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) -{ - MaskModifierData *mmd = (MaskModifierData *)md; - Object *ob = ctx->object; - const bool found_test = (mmd->flag & MOD_MASK_INV) == 0; - Mesh *result = NULL; - GHash *vertHash = NULL, *edgeHash, *polyHash; - GHashIterator gh_iter; - MDeformVert *dvert, *dv; - int numPolys = 0, numLoops = 0, numEdges = 0, numVerts = 0; - int maxVerts, maxEdges, maxPolys; - int i; - - const MVert *mvert_src; - const MEdge *medge_src; - const MPoly *mpoly_src; - const MLoop *mloop_src; - - MPoly *mpoly_dst; - MLoop *mloop_dst; - MEdge *medge_dst; - MVert *mvert_dst; - - int *loop_mapping; - - dvert = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT); - if (dvert == NULL) { - return found_test ? BKE_mesh_new_nomain_from_template(mesh, 0, 0, 0, 0, 0) : mesh; - } - - /* Overview of Method: - * 1. Get the vertices that are in the vertexgroup of interest. - * 2. Filter out unwanted geometry (i.e. not in vertexgroup), - * by populating mappings with new vs old indices. - * 3. Make a new mesh containing only the mapping data. - */ - - /* get original number of verts, edges, and faces */ - maxVerts = mesh->totvert; - maxEdges = mesh->totedge; - maxPolys = mesh->totpoly; - - /* check if we can just return the original mesh - * - must have verts and therefore verts assigned to vgroups to do anything useful - */ - if (!(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) || (maxVerts == 0) || - BLI_listbase_is_empty(&ob->defbase)) { - return mesh; - } - - /* if mode is to use selected armature bones, aggregate the bone groups */ - if (mmd->mode == MOD_MASK_MODE_ARM) { /* --- using selected bones --- */ - Object *oba = mmd->ob_arm; - bPoseChannel *pchan; - bDeformGroup *def; - bool *bone_select_array; - int bone_select_tot = 0; - const int defbase_tot = BLI_listbase_count(&ob->defbase); - - /* check that there is armature object with bones to use, otherwise return original mesh */ - if (ELEM(NULL, oba, oba->pose, ob->defbase.first)) { - return mesh; - } - - /* Determine whether each vertex-group is associated with a selected bone or not: - * - Each cell is a boolean saying whether bone corresponding to the i'th group selected. - * - Groups that don't match a bone are treated as not existing - * (along with the corresponding un-grouped verts). - */ - bone_select_array = MEM_malloc_arrayN((size_t)defbase_tot, sizeof(char), "mask array"); - - for (i = 0, def = ob->defbase.first; def; def = def->next, i++) { - pchan = BKE_pose_channel_find_name(oba->pose, def->name); - if (pchan && pchan->bone && (pchan->bone->flag & BONE_SELECTED)) { - bone_select_array[i] = true; - bone_select_tot++; - } - else { - bone_select_array[i] = false; - } - } - - /* verthash gives mapping from original vertex indices to the new indices - * (including selected matches only): - * key = oldindex, value = newindex - */ - vertHash = BLI_ghash_int_new_ex("mask vert gh", (uint)maxVerts); - - /* add vertices which exist in vertexgroups into vertHash for filtering - * - dv = for each vertex, what vertexgroups does it belong to - * - dw = weight that vertex was assigned to a vertexgroup it belongs to - */ - for (i = 0, dv = dvert; i < maxVerts; i++, dv++) { - MDeformWeight *dw = dv->dw; - bool found = false; - int j; - - /* check the groups that vertex is assigned to, and see if it was any use */ - for (j = 0; j < dv->totweight; j++, dw++) { - if (dw->def_nr < defbase_tot) { - if (bone_select_array[dw->def_nr]) { - if (dw->weight > mmd->threshold) { - found = true; - break; - } - } - } - } - - if (found_test != found) { - continue; - } - - /* add to ghash for verts (numVerts acts as counter for mapping) */ - BLI_ghash_insert(vertHash, POINTER_FROM_INT(i), POINTER_FROM_INT(numVerts)); - numVerts++; - } - - /* free temp hashes */ - MEM_freeN(bone_select_array); - } - else { /* --- Using Nominated VertexGroup only --- */ - int defgrp_index = defgroup_name_index(ob, mmd->vgroup); - - /* if no vgroup (i.e. dverts) found, return the initial mesh */ - if (defgrp_index == -1) { - return mesh; - } - - /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */ - vertHash = BLI_ghash_int_new_ex("mask vert2 bh", (uint)maxVerts); - - /* add vertices which exist in vertexgroup into ghash for filtering */ - for (i = 0, dv = dvert; i < maxVerts; i++, dv++) { - const bool found = defvert_find_weight(dv, defgrp_index) > mmd->threshold; - if (found_test != found) { - continue; - } - - /* add to ghash for verts (numVerts acts as counter for mapping) */ - BLI_ghash_insert(vertHash, POINTER_FROM_INT(i), POINTER_FROM_INT(numVerts)); - numVerts++; - } - } - - /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */ - edgeHash = BLI_ghash_int_new_ex("mask ed2 gh", (uint)maxEdges); - polyHash = BLI_ghash_int_new_ex("mask fa2 gh", (uint)maxPolys); - - mvert_src = mesh->mvert; - medge_src = mesh->medge; - mpoly_src = mesh->mpoly; - mloop_src = mesh->mloop; - - /* overalloc, assume all polys are seen */ - loop_mapping = MEM_malloc_arrayN((size_t)maxPolys, sizeof(int), "mask loopmap"); - - /* loop over edges and faces, and do the same thing to - * ensure that they only reference existing verts - */ - for (i = 0; i < maxEdges; i++) { - const MEdge *me = &medge_src[i]; - - /* only add if both verts will be in new mesh */ - if (BLI_ghash_haskey(vertHash, POINTER_FROM_INT(me->v1)) && - BLI_ghash_haskey(vertHash, POINTER_FROM_INT(me->v2))) { - BLI_ghash_insert(edgeHash, POINTER_FROM_INT(i), POINTER_FROM_INT(numEdges)); - numEdges++; - } - } - for (i = 0; i < maxPolys; i++) { - const MPoly *mp_src = &mpoly_src[i]; - const MLoop *ml_src = &mloop_src[mp_src->loopstart]; - bool ok = true; - int j; - - for (j = 0; j < mp_src->totloop; j++, ml_src++) { - if (!BLI_ghash_haskey(vertHash, POINTER_FROM_INT(ml_src->v))) { - ok = false; - break; - } - } - - /* all verts must be available */ - if (ok) { - BLI_ghash_insert(polyHash, POINTER_FROM_INT(i), POINTER_FROM_INT(numPolys)); - loop_mapping[numPolys] = numLoops; - numPolys++; - numLoops += mp_src->totloop; - } - } - - /* now we know the number of verts, edges and faces, - * we can create the new (reduced) mesh - */ - result = BKE_mesh_new_nomain_from_template(mesh, numVerts, numEdges, 0, numLoops, numPolys); - - mpoly_dst = result->mpoly; - mloop_dst = result->mloop; - medge_dst = result->medge; - mvert_dst = result->mvert; - - /* using ghash-iterators, map data into new mesh */ - /* vertices */ - GHASH_ITER (gh_iter, vertHash) { - const MVert *v_src; - MVert *v_dst; - const int i_src = POINTER_AS_INT(BLI_ghashIterator_getKey(&gh_iter)); - const int i_dst = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter)); - - v_src = &mvert_src[i_src]; - v_dst = &mvert_dst[i_dst]; - - *v_dst = *v_src; - CustomData_copy_data(&mesh->vdata, &result->vdata, i_src, i_dst, 1); - } - - /* edges */ - GHASH_ITER (gh_iter, edgeHash) { - const MEdge *e_src; - MEdge *e_dst; - const int i_src = POINTER_AS_INT(BLI_ghashIterator_getKey(&gh_iter)); - const int i_dst = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter)); - - e_src = &medge_src[i_src]; - e_dst = &medge_dst[i_dst]; - - CustomData_copy_data(&mesh->edata, &result->edata, i_src, i_dst, 1); - *e_dst = *e_src; - e_dst->v1 = POINTER_AS_UINT(BLI_ghash_lookup(vertHash, POINTER_FROM_UINT(e_src->v1))); - e_dst->v2 = POINTER_AS_UINT(BLI_ghash_lookup(vertHash, POINTER_FROM_UINT(e_src->v2))); - } - - /* faces */ - GHASH_ITER (gh_iter, polyHash) { - const int i_src = POINTER_AS_INT(BLI_ghashIterator_getKey(&gh_iter)); - const int i_dst = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter)); - const MPoly *mp_src = &mpoly_src[i_src]; - MPoly *mp_dst = &mpoly_dst[i_dst]; - const int i_ml_src = mp_src->loopstart; - const int i_ml_dst = loop_mapping[i_dst]; - const MLoop *ml_src = &mloop_src[i_ml_src]; - MLoop *ml_dst = &mloop_dst[i_ml_dst]; - - CustomData_copy_data(&mesh->pdata, &result->pdata, i_src, i_dst, 1); - CustomData_copy_data(&mesh->ldata, &result->ldata, i_ml_src, i_ml_dst, mp_src->totloop); - - *mp_dst = *mp_src; - mp_dst->loopstart = i_ml_dst; - for (i = 0; i < mp_src->totloop; i++) { - ml_dst[i].v = POINTER_AS_UINT(BLI_ghash_lookup(vertHash, POINTER_FROM_UINT(ml_src[i].v))); - ml_dst[i].e = POINTER_AS_UINT(BLI_ghash_lookup(edgeHash, POINTER_FROM_UINT(ml_src[i].e))); - } - } - - MEM_freeN(loop_mapping); - - /* why is this needed? - campbell */ - /* recalculate normals */ - result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; - - /* free hashes */ - BLI_ghash_free(vertHash, NULL, NULL); - BLI_ghash_free(edgeHash, NULL, NULL); - BLI_ghash_free(polyHash, NULL, NULL); - - /* return the new mesh */ - return result; -} - -static bool isDisabled(const struct Scene *UNUSED(scene), - ModifierData *md, - bool UNUSED(useRenderParams)) -{ - MaskModifierData *mmd = (MaskModifierData *)md; - - /* The object type check is only needed here in case we have a placeholder - * object assigned (because the library containing the armature is missing). - * - * In other cases it should be impossible to have a type mismatch. - */ - return mmd->ob_arm && mmd->ob_arm->type != OB_ARMATURE; -} - -ModifierTypeInfo modifierType_Mask = { - /* name */ "Mask", - /* structName */ "MaskModifierData", - /* structSize */ sizeof(MaskModifierData), - /* type */ eModifierTypeType_Nonconstructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | - eModifierTypeFlag_SupportsEditmode, - - /* copyData */ modifier_copyData_generic, - - /* deformVerts */ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, - - /* initData */ NULL, - /* requiredDataMask */ requiredDataMask, - /* freeData */ NULL, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachObjectLink */ foreachObjectLink, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, -}; diff --git a/source/blender/modifiers/intern/MOD_mask.cc b/source/blender/modifiers/intern/MOD_mask.cc new file mode 100644 index 00000000000..a458e4dd8bc --- /dev/null +++ b/source/blender/modifiers/intern/MOD_mask.cc @@ -0,0 +1,420 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 by the Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup modifiers + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" + +#include "BLI_ghash.h" +#include "BLI_listbase.h" + +#include "DNA_armature_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" + +#include "BKE_action.h" /* BKE_pose_channel_find_name */ +#include "BKE_customdata.h" +#include "BKE_deform.h" +#include "BKE_lib_query.h" +#include "BKE_mesh.h" +#include "BKE_modifier.h" + +#include "DEG_depsgraph_build.h" +#include "DEG_depsgraph_query.h" + +#include "MOD_modifiertypes.h" + +#include "BLI_array.hh" +#include "BLI_listbase_wrapper.hh" +#include "BLI_vector.hh" + +using BLI::Array; +using BLI::ArrayRef; +using BLI::IndexRange; +using BLI::ListBaseWrapper; +using BLI::MutableArrayRef; +using BLI::Vector; + +static void requiredDataMask(Object *UNUSED(ob), + ModifierData *UNUSED(md), + CustomData_MeshMasks *r_cddata_masks) +{ + r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; +} + +static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData) +{ + MaskModifierData *mmd = (MaskModifierData *)md; + walk(userData, ob, &mmd->ob_arm, IDWALK_CB_NOP); +} + +static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) +{ + MaskModifierData *mmd = (MaskModifierData *)md; + if (mmd->ob_arm) { + bArmature *arm = (bArmature *)mmd->ob_arm->data; + /* Tag relationship in depsgraph, but also on the armature. */ + /* TODO(sergey): Is it a proper relation here? */ + DEG_add_object_relation(ctx->node, mmd->ob_arm, DEG_OB_COMP_TRANSFORM, "Mask Modifier"); + arm->flag |= ARM_HAS_VIZ_DEPS; + DEG_add_modifier_to_transform_relation(ctx->node, "Mask Modifier"); + } +} + +/* A vertex will be in the mask if a selected bone influences it more than a certain threshold. */ +static void compute_vertex_mask__armature_mode(MDeformVert *dvert, + Object *ob, + Object *armature_ob, + float threshold, + MutableArrayRef<bool> r_vertex_mask) +{ + /* Element i is true if there is a selected bone that uses vertex group i. */ + Vector<bool> selected_bone_uses_group; + + for (bDeformGroup *def : ListBaseWrapper<bDeformGroup>(ob->defbase)) { + bPoseChannel *pchan = BKE_pose_channel_find_name(armature_ob->pose, def->name); + bool bone_for_group_exists = pchan && pchan->bone && (pchan->bone->flag & BONE_SELECTED); + selected_bone_uses_group.append(bone_for_group_exists); + } + + ArrayRef<bool> use_vertex_group = selected_bone_uses_group; + + for (int i : r_vertex_mask.index_range()) { + ArrayRef<MDeformWeight> weights(dvert[i].dw, dvert[i].totweight); + r_vertex_mask[i] = false; + + /* check the groups that vertex is assigned to, and see if it was any use */ + for (const MDeformWeight &dw : weights) { + if (use_vertex_group.get(dw.def_nr, false)) { + if (dw.weight > threshold) { + r_vertex_mask[i] = true; + break; + } + } + } + } +} + +/* A vertex will be in the mask if the vertex group influences it more than a certain threshold. */ +static void compute_vertex_mask__vertex_group_mode(MDeformVert *dvert, + int defgrp_index, + float threshold, + MutableArrayRef<bool> r_vertex_mask) +{ + for (int i : r_vertex_mask.index_range()) { + const bool found = BKE_defvert_find_weight(&dvert[i], defgrp_index) > threshold; + r_vertex_mask[i] = found; + } +} + +static void invert_boolean_array(MutableArrayRef<bool> array) +{ + for (bool &value : array) { + value = !value; + } +} + +static void compute_masked_vertices(ArrayRef<bool> vertex_mask, + MutableArrayRef<int> r_vertex_map, + uint *r_num_masked_vertices) +{ + BLI_assert(vertex_mask.size() == r_vertex_map.size()); + + uint num_masked_vertices = 0; + for (uint i_src : r_vertex_map.index_range()) { + if (vertex_mask[i_src]) { + r_vertex_map[i_src] = num_masked_vertices; + num_masked_vertices++; + } + else { + r_vertex_map[i_src] = -1; + } + } + + *r_num_masked_vertices = num_masked_vertices; +} + +static void computed_masked_edges(const Mesh *mesh, + ArrayRef<bool> vertex_mask, + MutableArrayRef<int> r_edge_map, + uint *r_num_masked_edges) +{ + BLI_assert(mesh->totedge == r_edge_map.size()); + + uint num_masked_edges = 0; + for (int i : IndexRange(mesh->totedge)) { + const MEdge &edge = mesh->medge[i]; + + /* only add if both verts will be in new mesh */ + if (vertex_mask[edge.v1] && vertex_mask[edge.v2]) { + r_edge_map[i] = num_masked_edges; + num_masked_edges++; + } + else { + r_edge_map[i] = -1; + } + } + + *r_num_masked_edges = num_masked_edges; +} + +static void computed_masked_polygons(const Mesh *mesh, + ArrayRef<bool> vertex_mask, + Vector<int> &r_masked_poly_indices, + Vector<int> &r_loop_starts, + uint *r_num_masked_polys, + uint *r_num_masked_loops) +{ + BLI_assert(mesh->totvert == vertex_mask.size()); + + r_masked_poly_indices.reserve(mesh->totpoly); + r_loop_starts.reserve(mesh->totloop); + + uint num_masked_loops = 0; + for (int i : IndexRange(mesh->totpoly)) { + const MPoly &poly_src = mesh->mpoly[i]; + + bool all_verts_in_mask = true; + ArrayRef<MLoop> loops_src(&mesh->mloop[poly_src.loopstart], poly_src.totloop); + for (const MLoop &loop : loops_src) { + if (!vertex_mask[loop.v]) { + all_verts_in_mask = false; + break; + } + } + + if (all_verts_in_mask) { + r_masked_poly_indices.append_unchecked(i); + r_loop_starts.append_unchecked(num_masked_loops); + num_masked_loops += poly_src.totloop; + } + } + + *r_num_masked_polys = r_masked_poly_indices.size(); + *r_num_masked_loops = num_masked_loops; +} + +static void copy_masked_vertices_to_new_mesh(const Mesh &src_mesh, + Mesh &dst_mesh, + ArrayRef<int> vertex_map) +{ + BLI_assert(src_mesh.totvert == vertex_map.size()); + for (const int i_src : vertex_map.index_range()) { + const int i_dst = vertex_map[i_src]; + if (i_dst == -1) { + continue; + } + + const MVert &v_src = src_mesh.mvert[i_src]; + MVert &v_dst = dst_mesh.mvert[i_dst]; + + v_dst = v_src; + CustomData_copy_data(&src_mesh.vdata, &dst_mesh.vdata, i_src, i_dst, 1); + } +} + +static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh, + Mesh &dst_mesh, + ArrayRef<int> vertex_map, + ArrayRef<int> edge_map) +{ + BLI_assert(src_mesh.totvert == vertex_map.size()); + BLI_assert(src_mesh.totedge == edge_map.size()); + for (const int i_src : IndexRange(src_mesh.totedge)) { + const int i_dst = edge_map[i_src]; + if (i_dst == -1) { + continue; + } + + const MEdge &e_src = src_mesh.medge[i_src]; + MEdge &e_dst = dst_mesh.medge[i_dst]; + + CustomData_copy_data(&src_mesh.edata, &dst_mesh.edata, i_src, i_dst, 1); + e_dst = e_src; + e_dst.v1 = vertex_map[e_src.v1]; + e_dst.v2 = vertex_map[e_src.v2]; + } +} + +static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, + Mesh &dst_mesh, + ArrayRef<int> vertex_map, + ArrayRef<int> edge_map, + ArrayRef<int> masked_poly_indices, + ArrayRef<int> new_loop_starts) +{ + for (const int i_dst : masked_poly_indices.index_range()) { + const int i_src = masked_poly_indices[i_dst]; + + const MPoly &mp_src = src_mesh.mpoly[i_src]; + MPoly &mp_dst = dst_mesh.mpoly[i_dst]; + const int i_ml_src = mp_src.loopstart; + const int i_ml_dst = new_loop_starts[i_dst]; + + CustomData_copy_data(&src_mesh.pdata, &dst_mesh.pdata, i_src, i_dst, 1); + CustomData_copy_data(&src_mesh.ldata, &dst_mesh.ldata, i_ml_src, i_ml_dst, mp_src.totloop); + + const MLoop *ml_src = src_mesh.mloop + i_ml_src; + MLoop *ml_dst = dst_mesh.mloop + i_ml_dst; + + mp_dst = mp_src; + mp_dst.loopstart = i_ml_dst; + for (int i : IndexRange(mp_src.totloop)) { + ml_dst[i].v = vertex_map[ml_src[i].v]; + ml_dst[i].e = edge_map[ml_src[i].e]; + } + } +} + +/* Components of the algorithm: + * 1. Figure out which vertices should be present in the output mesh. + * 2. Find edges and polygons only using those vertices. + * 3. Create a new mesh that only uses the found vertices, edges and polygons. + */ +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +{ + MaskModifierData *mmd = (MaskModifierData *)md; + Object *ob = ctx->object; + const bool invert_mask = mmd->flag & MOD_MASK_INV; + + /* Return empty or input mesh when there are no vertex groups. */ + MDeformVert *dvert = (MDeformVert *)CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT); + if (dvert == NULL) { + return invert_mask ? mesh : BKE_mesh_new_nomain_from_template(mesh, 0, 0, 0, 0, 0); + } + + /* Quick test to see if we can return early. */ + if (!(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) || (mesh->totvert == 0) || + BLI_listbase_is_empty(&ob->defbase)) { + return mesh; + } + + Array<bool> vertex_mask; + if (mmd->mode == MOD_MASK_MODE_ARM) { + Object *armature_ob = mmd->ob_arm; + + /* Return input mesh if there is no armature with bones. */ + if (ELEM(NULL, armature_ob, armature_ob->pose, ob->defbase.first)) { + return mesh; + } + + vertex_mask = Array<bool>(mesh->totvert); + compute_vertex_mask__armature_mode(dvert, ob, armature_ob, mmd->threshold, vertex_mask); + } + else { + int defgrp_index = BKE_object_defgroup_name_index(ob, mmd->vgroup); + + /* Return input mesh if the vertex group does not exist. */ + if (defgrp_index == -1) { + return mesh; + } + + vertex_mask = Array<bool>(mesh->totvert); + compute_vertex_mask__vertex_group_mode(dvert, defgrp_index, mmd->threshold, vertex_mask); + } + + if (invert_mask) { + invert_boolean_array(vertex_mask); + } + + Array<int> vertex_map(mesh->totvert); + uint num_masked_vertices; + compute_masked_vertices(vertex_mask, vertex_map, &num_masked_vertices); + + Array<int> edge_map(mesh->totedge); + uint num_masked_edges; + computed_masked_edges(mesh, vertex_mask, edge_map, &num_masked_edges); + + Vector<int> masked_poly_indices; + Vector<int> new_loop_starts; + uint num_masked_polys; + uint num_masked_loops; + computed_masked_polygons(mesh, + vertex_mask, + masked_poly_indices, + new_loop_starts, + &num_masked_polys, + &num_masked_loops); + + Mesh *result = BKE_mesh_new_nomain_from_template( + mesh, num_masked_vertices, num_masked_edges, 0, num_masked_loops, num_masked_polys); + + copy_masked_vertices_to_new_mesh(*mesh, *result, vertex_map); + copy_masked_edges_to_new_mesh(*mesh, *result, vertex_map, edge_map); + copy_masked_polys_to_new_mesh( + *mesh, *result, vertex_map, edge_map, masked_poly_indices, new_loop_starts); + + /* Tag to recalculate normals later. */ + result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; + + return result; +} + +static bool isDisabled(const struct Scene *UNUSED(scene), + ModifierData *md, + bool UNUSED(useRenderParams)) +{ + MaskModifierData *mmd = (MaskModifierData *)md; + + /* The object type check is only needed here in case we have a placeholder + * object assigned (because the library containing the armature is missing). + * + * In other cases it should be impossible to have a type mismatch. + */ + return mmd->ob_arm && mmd->ob_arm->type != OB_ARMATURE; +} + +ModifierTypeInfo modifierType_Mask = { + /* name */ "Mask", + /* structName */ "MaskModifierData", + /* structSize */ sizeof(MaskModifierData), + /* type */ eModifierTypeType_Nonconstructive, + /* flags */ + (ModifierTypeFlag)(eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | + eModifierTypeFlag_SupportsEditmode), + + /* copyData */ BKE_modifier_copydata_generic, + + /* deformVerts */ NULL, + /* deformMatrices */ NULL, + /* deformVertsEM */ NULL, + /* deformMatricesEM */ NULL, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, + + /* initData */ NULL, + /* requiredDataMask */ requiredDataMask, + /* freeData */ NULL, + /* isDisabled */ isDisabled, + /* updateDepsgraph */ updateDepsgraph, + /* dependsOnTime */ NULL, + /* dependsOnNormals */ NULL, + /* foreachObjectLink */ foreachObjectLink, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, + /* freeRuntimeData */ NULL, +}; diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c index e01f07584ee..219de1569b3 100644 --- a/source/blender/modifiers/intern/MOD_meshcache.c +++ b/source/blender/modifiers/intern/MOD_meshcache.c @@ -26,10 +26,10 @@ #include "BLI_path_util.h" #include "BLI_string.h" -#include "DNA_scene_types.h" -#include "DNA_object_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "BKE_main.h" #include "BKE_mesh.h" @@ -167,13 +167,13 @@ static void meshcache_do(MeshCacheModifierData *mcmd, /* we could support any object type */ if (UNLIKELY(ob->type != OB_MESH)) { - modifier_setError(&mcmd->modifier, "'Integrate' only valid for Mesh objects"); + BKE_modifier_set_error(&mcmd->modifier, "'Integrate' only valid for Mesh objects"); } else if (UNLIKELY(me->totvert != numVerts)) { - modifier_setError(&mcmd->modifier, "'Integrate' original mesh vertex mismatch"); + BKE_modifier_set_error(&mcmd->modifier, "'Integrate' original mesh vertex mismatch"); } else if (UNLIKELY(me->totpoly == 0)) { - modifier_setError(&mcmd->modifier, "'Integrate' requires faces"); + BKE_modifier_set_error(&mcmd->modifier, "'Integrate' requires faces"); } else { /* the moons align! */ @@ -212,7 +212,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd, /* -------------------------------------------------------------------- */ /* Apply the transformation matrix (if needed) */ if (UNLIKELY(err_str)) { - modifier_setError(&mcmd->modifier, "%s", err_str); + BKE_modifier_set_error(&mcmd->modifier, "%s", err_str); } else if (ok) { bool use_matrix = false; @@ -292,16 +292,19 @@ ModifierTypeInfo modifierType_MeshCache = { /* structName */ "MeshCacheModifierData", /* structSize */ sizeof(MeshCacheModifierData), /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice | + /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ deformVerts, /* deformMatrices */ NULL, /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ NULL, diff --git a/source/blender/modifiers/intern/MOD_meshcache_mdd.c b/source/blender/modifiers/intern/MOD_meshcache_mdd.c index a3ab0120ff9..60376f61708 100644 --- a/source/blender/modifiers/intern/MOD_meshcache_mdd.c +++ b/source/blender/modifiers/intern/MOD_meshcache_mdd.c @@ -18,9 +18,9 @@ * \ingroup modifiers */ +#include <errno.h> #include <stdio.h> #include <string.h> -#include <errno.h> #include "BLI_utildefines.h" @@ -155,12 +155,12 @@ bool MOD_meshcache_read_mdd_index(FILE *fp, return false; } - if (fseek(fp, mdd_head.frame_tot * sizeof(int), SEEK_CUR) != 0) { + if (BLI_fseek(fp, mdd_head.frame_tot * sizeof(int), SEEK_CUR) != 0) { *err_str = "Header seek failed"; return false; } - if (fseek(fp, sizeof(float) * 3 * index * mdd_head.verts_tot, SEEK_CUR) != 0) { + if (BLI_fseek(fp, sizeof(float) * 3 * index * mdd_head.verts_tot, SEEK_CUR) != 0) { *err_str = "Failed to seek frame"; return false; } @@ -234,7 +234,7 @@ bool MOD_meshcache_read_mdd_frame(FILE *fp, if (index_range[0] == index_range[1]) { /* read single */ - if ((fseek(fp, 0, SEEK_SET) == 0) && + if ((BLI_fseek(fp, 0, SEEK_SET) == 0) && MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str)) { return true; } @@ -244,9 +244,9 @@ bool MOD_meshcache_read_mdd_frame(FILE *fp, } else { /* read both and interpolate */ - if ((fseek(fp, 0, SEEK_SET) == 0) && + if ((BLI_fseek(fp, 0, SEEK_SET) == 0) && MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str) && - (fseek(fp, 0, SEEK_SET) == 0) && + (BLI_fseek(fp, 0, SEEK_SET) == 0) && MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[1], factor, err_str)) { return true; } diff --git a/source/blender/modifiers/intern/MOD_meshcache_pc2.c b/source/blender/modifiers/intern/MOD_meshcache_pc2.c index 7b8ad0bd705..60011458c67 100644 --- a/source/blender/modifiers/intern/MOD_meshcache_pc2.c +++ b/source/blender/modifiers/intern/MOD_meshcache_pc2.c @@ -18,9 +18,9 @@ * \ingroup modifiers */ +#include <errno.h> #include <stdio.h> #include <string.h> -#include <errno.h> #include "BLI_utildefines.h" @@ -146,7 +146,7 @@ bool MOD_meshcache_read_pc2_index(FILE *fp, return false; } - if (fseek(fp, sizeof(float) * 3 * index * pc2_head.verts_tot, SEEK_CUR) != 0) { + if (BLI_fseek(fp, sizeof(float) * 3 * index * pc2_head.verts_tot, SEEK_CUR) != 0) { *err_str = "Failed to seek frame"; return false; } @@ -209,7 +209,7 @@ bool MOD_meshcache_read_pc2_frame(FILE *fp, if (index_range[0] == index_range[1]) { /* read single */ - if ((fseek(fp, 0, SEEK_SET) == 0) && + if ((BLI_fseek(fp, 0, SEEK_SET) == 0) && MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str)) { return true; } @@ -219,9 +219,9 @@ bool MOD_meshcache_read_pc2_frame(FILE *fp, } else { /* read both and interpolate */ - if ((fseek(fp, 0, SEEK_SET) == 0) && + if ((BLI_fseek(fp, 0, SEEK_SET) == 0) && MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str) && - (fseek(fp, 0, SEEK_SET) == 0) && + (BLI_fseek(fp, 0, SEEK_SET) == 0) && MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[1], factor, err_str)) { return true; } diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index 21fdc010a1d..c5ed6363415 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -31,14 +31,14 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "BKE_deform.h" +#include "BKE_editmesh.h" #include "BKE_global.h" -#include "BKE_library.h" -#include "BKE_library_query.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" #include "BKE_mesh.h" #include "BKE_mesh_runtime.h" #include "BKE_modifier.h" -#include "BKE_deform.h" -#include "BKE_editmesh.h" #include "MEM_guardedalloc.h" @@ -93,7 +93,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla const MeshDeformModifierData *mmd = (const MeshDeformModifierData *)md; MeshDeformModifierData *tmmd = (MeshDeformModifierData *)target; - modifier_copyData_generic(md, target, flag); + BKE_modifier_copydata_generic(md, target, flag); if (mmd->bindinfluences) { tmmd->bindinfluences = MEM_dupallocN(mmd->bindinfluences); @@ -161,6 +161,8 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte DEG_add_object_relation(ctx->node, mmd->object, DEG_OB_COMP_TRANSFORM, "Mesh Deform Modifier"); DEG_add_object_relation(ctx->node, mmd->object, DEG_OB_COMP_GEOMETRY, "Mesh Deform Modifier"); } + /* We need own transformation as well. */ + DEG_add_modifier_to_transform_relation(ctx->node, "Mesh Deform Modifier"); } static float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float (*dco)[3], float vec[3]) @@ -284,7 +286,7 @@ static void meshdeform_vert_task(void *__restrict userdata, } if (dvert) { - fac = defvert_find_weight(&dvert[iter], defgrp_index); + fac = BKE_defvert_find_weight(&dvert[iter], defgrp_index); if (mmd->flag & MOD_MDEF_INVERT_VGROUP) { fac = 1.0f - fac; @@ -361,7 +363,7 @@ static void meshdeformModifier_do(ModifierData *md, Object *ob_target = mmd->object; cagemesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob_target, false); if (cagemesh == NULL) { - modifier_setError(md, "Cannot get mesh from cage object"); + BKE_modifier_set_error(md, "Cannot get mesh from cage object"); return; } @@ -376,7 +378,7 @@ static void meshdeformModifier_do(ModifierData *md, if (!mmd->bindcagecos) { /* progress bar redraw can make this recursive .. */ if (!DEG_is_active(ctx->depsgraph)) { - modifier_setError(md, "Attempt to bind from inactive dependency graph"); + BKE_modifier_set_error(md, "Attempt to bind from inactive dependency graph"); goto finally; } if (!recursive_bind_sentinel) { @@ -393,15 +395,15 @@ static void meshdeformModifier_do(ModifierData *md, totcagevert = cagemesh->totvert; if (mmd->totvert != totvert) { - modifier_setError(md, "Verts changed from %d to %d", mmd->totvert, totvert); + BKE_modifier_set_error(md, "Verts changed from %d to %d", mmd->totvert, totvert); goto finally; } else if (mmd->totcagevert != totcagevert) { - modifier_setError(md, "Cage verts changed from %d to %d", mmd->totcagevert, totcagevert); + BKE_modifier_set_error(md, "Cage verts changed from %d to %d", mmd->totcagevert, totcagevert); goto finally; } else if (mmd->bindcagecos == NULL) { - modifier_setError(md, "Bind data missing"); + BKE_modifier_set_error(md, "Bind data missing"); goto finally; } @@ -486,7 +488,7 @@ static void deformVertsEM(ModifierData *md, #define MESHDEFORM_MIN_INFLUENCE 0.00001f -void modifier_mdef_compact_influences(ModifierData *md) +void BKE_modifier_mdef_compact_influences(ModifierData *md) { MeshDeformModifierData *mmd = (MeshDeformModifierData *)md; float weight, *weights, totweight; @@ -556,7 +558,7 @@ ModifierTypeInfo modifierType_MeshDeform = { /* structName */ "MeshDeformModifierData", /* structSize */ sizeof(MeshDeformModifierData), /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice | + /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, /* copyData */ copyData, @@ -565,7 +567,10 @@ ModifierTypeInfo modifierType_MeshDeform = { /* deformMatrices */ NULL, /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c index 0f57b759e38..51275c4e58f 100644 --- a/source/blender/modifiers/intern/MOD_meshsequencecache.c +++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c @@ -20,8 +20,8 @@ #include <string.h> -#include "BLI_utildefines.h" #include "BLI_string.h" +#include "BLI_utildefines.h" #include "DNA_cachefile_types.h" #include "DNA_mesh_types.h" @@ -31,7 +31,7 @@ #include "DNA_scene_types.h" #include "BKE_cachefile.h" -#include "BKE_library_query.h" +#include "BKE_lib_query.h" #include "BKE_scene.h" #include "DEG_depsgraph_build.h" @@ -42,7 +42,7 @@ #ifdef WITH_ALEMBIC # include "ABC_alembic.h" # include "BKE_global.h" -# include "BKE_library.h" +# include "BKE_lib_id.h" #endif static void initData(ModifierData *md) @@ -64,7 +64,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla #endif MeshSeqCacheModifierData *tmcmd = (MeshSeqCacheModifierData *)target; - modifier_copyData_generic(md, target, flag); + BKE_modifier_copydata_generic(md, target, flag); tmcmd->reader = NULL; tmcmd->reader_object_path[0] = '\0'; @@ -90,7 +90,7 @@ static bool isDisabled(const struct Scene *UNUSED(scene), return (mcmd->cache_file == NULL) || (mcmd->object_path[0] == '\0'); } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { #ifdef WITH_ALEMBIC MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md; @@ -109,7 +109,8 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes STRNCPY(mcmd->reader_object_path, mcmd->object_path); BKE_cachefile_reader_open(cache_file, &mcmd->reader, ctx->object, mcmd->object_path); if (!mcmd->reader) { - modifier_setError(md, "Could not create Alembic reader for file %s", cache_file->filepath); + BKE_modifier_set_error( + md, "Could not create Alembic reader for file %s", cache_file->filepath); return mesh; } } @@ -141,7 +142,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes Mesh *result = ABC_read_mesh(mcmd->reader, ctx->object, mesh, time, &err_str, mcmd->read_flag); if (err_str) { - modifier_setError(md, "%s", err_str); + BKE_modifier_set_error(md, "%s", err_str); } if (!ELEM(result, NULL, mesh) && (mesh != org_mesh)) { @@ -197,7 +198,10 @@ ModifierTypeInfo modifierType_MeshSequenceCache = { /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ NULL, diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c index fe3e608fcbe..bbbcac262ca 100644 --- a/source/blender/modifiers/intern/MOD_mirror.c +++ b/source/blender/modifiers/intern/MOD_mirror.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -27,12 +27,12 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" -#include "BKE_library.h" -#include "BKE_library_query.h" +#include "BKE_deform.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" #include "BKE_mesh.h" #include "BKE_mesh_mirror.h" #include "BKE_modifier.h" -#include "BKE_deform.h" #include "bmesh.h" #include "bmesh_tools.h" @@ -100,7 +100,7 @@ static Mesh *mirrorModifier__doMirror(MirrorModifierData *mmd, return result; } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { Mesh *result; MirrorModifierData *mmd = (MirrorModifierData *)md; @@ -124,13 +124,16 @@ ModifierTypeInfo modifierType_Mirror = { /* this is only the case when 'MOD_MIR_VGROUP' is used */ eModifierTypeFlag_UsesPreview, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ NULL, diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index 883c17aa1e1..5174a996480 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -33,8 +33,8 @@ #include "BKE_cdderivedmesh.h" #include "BKE_mesh.h" -#include "BKE_multires.h" #include "BKE_modifier.h" +#include "BKE_multires.h" #include "BKE_paint.h" #include "BKE_subdiv.h" #include "BKE_subdiv_ccg.h" @@ -60,13 +60,13 @@ static void initData(ModifierData *md) mmd->renderlvl = 0; mmd->totlvl = 0; mmd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS; - mmd->quality = 3; - mmd->flags |= eMultiresModifierFlag_UseCrease; + mmd->quality = 4; + mmd->flags |= (eMultiresModifierFlag_UseCrease | eMultiresModifierFlag_ControlEdges); } static void copyData(const ModifierData *md_src, ModifierData *md_dst, const int flag) { - modifier_copyData_generic(md_src, md_dst, flag); + BKE_modifier_copydata_generic(md_src, md_dst, flag); } static void freeRuntimeData(void *runtime_data_v) @@ -119,11 +119,17 @@ static Mesh *multires_as_mesh(MultiresModifierData *mmd, Mesh *result = mesh; const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER); const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY); + const bool ignore_control_edges = (ctx->flag & MOD_APPLY_TO_BASE_MESH); const Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); Object *object = ctx->object; SubdivToMeshSettings mesh_settings; - BKE_multires_subdiv_mesh_settings_init( - &mesh_settings, scene, object, mmd, use_render_params, ignore_simplify); + BKE_multires_subdiv_mesh_settings_init(&mesh_settings, + scene, + object, + mmd, + use_render_params, + ignore_simplify, + ignore_control_edges); if (mesh_settings.resolution < 3) { return result; } @@ -166,11 +172,11 @@ static Mesh *multires_as_ccg(MultiresModifierData *mmd, return result; } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { Mesh *result = mesh; #if !defined(WITH_OPENSUBDIV) - modifier_setError(md, "Disabled, built without OpenSubdiv"); + BKE_modifier_set_error(md, "Disabled, built without OpenSubdiv"); return result; #endif MultiresModifierData *mmd = (MultiresModifierData *)md; @@ -205,7 +211,9 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes if (ctx->object->sculpt != NULL) { SculptSession *sculpt_session = ctx->object->sculpt; sculpt_session->subdiv_ccg = result->runtime.subdiv_ccg; - sculpt_session->multires = mmd; + sculpt_session->multires.active = true; + sculpt_session->multires.modifier = mmd; + sculpt_session->multires.level = mmd->sculptlvl; sculpt_session->totvert = mesh->totvert; sculpt_session->totpoly = mesh->totpoly; sculpt_session->mvert = NULL; @@ -237,7 +245,7 @@ static void deformMatrices(ModifierData *md, { #if !defined(WITH_OPENSUBDIV) - modifier_setError(md, "Disabled, built without OpenSubdiv"); + BKE_modifier_set_error(md, "Disabled, built without OpenSubdiv"); return; #endif @@ -278,7 +286,10 @@ ModifierTypeInfo modifierType_Multires = { /* deformMatrices */ deformMatrices, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ NULL, diff --git a/source/blender/modifiers/intern/MOD_none.c b/source/blender/modifiers/intern/MOD_none.c index 9be422afab9..84c9fc1d726 100644 --- a/source/blender/modifiers/intern/MOD_none.c +++ b/source/blender/modifiers/intern/MOD_none.c @@ -51,7 +51,10 @@ ModifierTypeInfo modifierType_None = { /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ NULL, /* requiredDataMask */ NULL, diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c index 10852ed6148..1521cfab356 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.c +++ b/source/blender/modifiers/intern/MOD_normal_edit.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ @@ -27,14 +27,14 @@ #include "BLI_bitmap.h" #include "BLI_math.h" -#include "DNA_object_types.h" -#include "DNA_meshdata_types.h" #include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" -#include "BKE_library.h" -#include "BKE_library_query.h" -#include "BKE_mesh.h" #include "BKE_deform.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" +#include "BKE_mesh.h" #include "DEG_depsgraph_query.h" @@ -464,7 +464,7 @@ static bool is_valid_target(NormalEditModifierData *enmd) else if ((enmd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) && enmd->target) { return true; } - modifier_setError((ModifierData *)enmd, "Invalid target settings"); + BKE_modifier_set_error((ModifierData *)enmd, "Invalid target settings"); return false; } @@ -494,7 +494,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, if (!(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH)) #endif { - modifier_setError((ModifierData *)enmd, "Enable 'Auto Smooth' option in mesh settings"); + BKE_modifier_set_error((ModifierData *)enmd, "Enable 'Auto Smooth' in Object Data Properties"); return mesh; } @@ -502,7 +502,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, if (mesh->medge == ((Mesh *)ob->data)->medge) { /* We need to duplicate data here, otherwise setting custom normals * (which may also affect sharp edges) could - * modify org mesh, see T43671. */ + * modify original mesh, see T43671. */ BKE_id_copy_ex(NULL, &mesh->id, (ID **)&result, LIB_ID_COPY_LOCALIZE); } else { @@ -527,18 +527,13 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, float(*polynors)[3]; CustomData *ldata = &result->ldata; - if (CustomData_has_layer(ldata, CD_NORMAL)) { - loopnors = CustomData_get_layer(ldata, CD_NORMAL); - } - else { - loopnors = CustomData_add_layer(ldata, CD_NORMAL, CD_CALLOC, NULL, num_loops); - } /* Compute poly (always needed) and vert normals. */ CustomData *pdata = &result->pdata; polynors = CustomData_get_layer(pdata, CD_NORMAL); if (!polynors) { polynors = CustomData_add_layer(pdata, CD_NORMAL, CD_CALLOC, NULL, num_polys); + CustomData_set_layer_flag(pdata, CD_NORMAL, CD_FLAG_TEMPORARY); } BKE_mesh_calc_normals_poly(mvert, NULL, @@ -552,8 +547,10 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, result->runtime.cd_dirty_vert &= ~CD_MASK_NORMAL; + clnors = CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL); if (use_current_clnors) { clnors = CustomData_duplicate_referenced_layer(ldata, CD_CUSTOMLOOPNORMAL, num_loops); + loopnors = MEM_malloc_arrayN((size_t)num_loops, sizeof(*loopnors), __func__); BKE_mesh_normals_loop_split(mvert, num_verts, @@ -572,7 +569,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, NULL); } - if (!clnors) { + if (clnors == NULL) { clnors = CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, num_loops); } @@ -625,6 +622,10 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, num_polys); } + /* Currently Modifier stack assumes there is no poly normal data passed around... */ + CustomData_free_layers(pdata, CD_NORMAL, num_polys); + MEM_SAFE_FREE(loopnors); + return result; } @@ -683,7 +684,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte } } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { return normalEditModifier_do((NormalEditModifierData *)md, ctx, ctx->object, mesh); } @@ -696,13 +697,16 @@ ModifierTypeInfo modifierType_NormalEdit = { /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index 97be42367d4..4c7c644952b 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -28,13 +28,13 @@ #include "BLI_task.h" #include "DNA_customdata_types.h" -#include "DNA_object_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" +#include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "BKE_library.h" +#include "BKE_lib_id.h" #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_ocean.h" @@ -46,7 +46,7 @@ #ifdef WITH_OCEANSIM static void init_cache_data(Object *ob, struct OceanModifierData *omd) { - const char *relbase = modifier_path_relbase_from_global(ob); + const char *relbase = BKE_modifier_path_relbase_from_global(ob); omd->oceancache = BKE_ocean_init_cache(omd->cachepath, relbase, @@ -92,11 +92,15 @@ static void initData(ModifierData *md) omd->seed = 0; omd->time = 1.0; + omd->spectrum = MOD_OCEAN_SPECTRUM_PHILLIPS; + omd->sharpen_peak_jonswap = 0.0f; + omd->fetch_jonswap = 120.0f; + omd->size = 1.0; omd->repeat_x = 1; omd->repeat_y = 1; - modifier_path_init(omd->cachepath, sizeof(omd->cachepath), "cache_ocean"); + BKE_modifier_path_init(omd->cachepath, sizeof(omd->cachepath), "cache_ocean"); omd->cached = 0; omd->bakestart = 1; @@ -137,7 +141,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla # endif OceanModifierData *tomd = (OceanModifierData *)target; - modifier_copyData_generic(md, target, flag); + BKE_modifier_copydata_generic(md, target, flag); /* The oceancache object will be recreated for this copy * automatically when cached=true */ @@ -478,7 +482,7 @@ static Mesh *doOcean(ModifierData *UNUSED(md), const ModifierEvalContext *UNUSED } #endif /* WITH_OCEANSIM */ -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { Mesh *result; @@ -505,7 +509,10 @@ ModifierTypeInfo modifierType_Ocean = { /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index f4c2e78d1ac..644962ab71c 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -25,8 +25,8 @@ #include "BLI_utildefines.h" -#include "BLI_math.h" #include "BLI_listbase.h" +#include "BLI_math.h" #include "BLI_rand.h" #include "BLI_string.h" @@ -35,7 +35,7 @@ #include "BKE_effect.h" #include "BKE_lattice.h" -#include "BKE_library_query.h" +#include "BKE_lib_query.h" #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_particle.h" @@ -110,7 +110,7 @@ static bool isDisabled(const struct Scene *scene, ModifierData *md, bool useRend required_mode = eModifierMode_Realtime; } - if (!modifier_isEnabled(scene, ob_md, required_mode)) { + if (!BKE_modifier_is_enabled(scene, ob_md, required_mode)) { return true; } @@ -204,7 +204,7 @@ static void store_float_in_vcol(MLoopCol *vcol, float float_value) vcol->a = 1.0f; } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { Mesh *result; ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md; @@ -554,13 +554,16 @@ ModifierTypeInfo modifierType_ParticleInstance = { /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index 67a64921bbc..fc5359c953f 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -29,8 +29,8 @@ #include "DNA_mesh_types.h" #include "BKE_editmesh.h" +#include "BKE_lib_id.h" #include "BKE_mesh.h" -#include "BKE_library.h" #include "BKE_modifier.h" #include "BKE_particle.h" @@ -61,7 +61,7 @@ static void freeData(ModifierData *md) psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0; /* ED_object_modifier_remove may have freed this first before calling - * modifier_free (which calls this function) */ + * BKE_modifier_free (which calls this function) */ if (psmd->psys) { psmd->psys->flag |= PSYS_DELETE; } @@ -74,7 +74,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla #endif ParticleSystemModifierData *tpsmd = (ParticleSystemModifierData *)target; - modifier_copyData_generic(md, target, flag); + BKE_modifier_copydata_generic(md, target, flag); tpsmd->mesh_final = NULL; tpsmd->mesh_original = NULL; @@ -189,7 +189,7 @@ static void deformVerts(ModifierData *md, BKE_mesh_tessface_ensure(psmd->mesh_original); } - if (mesh_src != psmd->mesh_final && mesh_src != mesh) { + if (!ELEM(mesh_src, NULL, mesh, psmd->mesh_final)) { BKE_id_free(NULL, mesh_src); } @@ -216,7 +216,7 @@ static void deformVerts(ModifierData *md, if (DEG_is_active(ctx->depsgraph)) { Object *object_orig = DEG_get_original_object(ctx->object); - ModifierData *md_orig = modifiers_findByName(object_orig, psmd->modifier.name); + ModifierData *md_orig = BKE_modifiers_findny_name(object_orig, psmd->modifier.name); BLI_assert(md_orig != NULL); ParticleSystemModifierData *psmd_orig = (ParticleSystemModifierData *)md_orig; psmd_orig->flag = psmd->flag; @@ -264,7 +264,10 @@ ModifierTypeInfo modifierType_ParticleSystem = { /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c index df84f3db55c..5a262adf47c 100644 --- a/source/blender/modifiers/intern/MOD_remesh.c +++ b/source/blender/modifiers/intern/MOD_remesh.c @@ -25,15 +25,17 @@ #include "BLI_utildefines.h" #include "BLI_math_base.h" +#include "BLI_threads.h" +#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" -#include "DNA_mesh_types.h" #include "MOD_modifiertypes.h" #include "BKE_mesh.h" +#include "BKE_mesh_remesh_voxel.h" #include "BKE_mesh_runtime.h" #include <assert.h> @@ -54,8 +56,10 @@ static void initData(ModifierData *md) rmd->depth = 4; rmd->hermite_num = 1; rmd->flag = MOD_REMESH_FLOOD_FILL; - rmd->mode = MOD_REMESH_SHARP_FEATURES; + rmd->mode = MOD_REMESH_VOXEL; rmd->threshold = 1; + rmd->voxel_size = 0.1f; + rmd->adaptivity = 0.0f; } #ifdef WITH_MOD_REMESH @@ -133,7 +137,7 @@ static void dualcon_add_quad(void *output_v, const int vert_indices[4]) output->curface++; } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh) { RemeshModifierData *rmd; DualConOutput *output; @@ -144,36 +148,56 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *UNUSED(c rmd = (RemeshModifierData *)md; - init_dualcon_mesh(&input, mesh); - - if (rmd->flag & MOD_REMESH_FLOOD_FILL) { - flags |= DUALCON_FLOOD_FILL; + if (rmd->mode == MOD_REMESH_VOXEL) { + /* OpenVDB modes. */ + if (rmd->voxel_size == 0.0f) { + return NULL; + } + result = BKE_mesh_remesh_voxel_to_mesh_nomain(mesh, rmd->voxel_size, rmd->adaptivity, 0.0f); } + else { + /* Dualcon modes. */ + init_dualcon_mesh(&input, mesh); - switch (rmd->mode) { - case MOD_REMESH_CENTROID: - mode = DUALCON_CENTROID; - break; - case MOD_REMESH_MASS_POINT: - mode = DUALCON_MASS_POINT; - break; - case MOD_REMESH_SHARP_FEATURES: - mode = DUALCON_SHARP_FEATURES; - break; - } + if (rmd->flag & MOD_REMESH_FLOOD_FILL) { + flags |= DUALCON_FLOOD_FILL; + } - output = dualcon(&input, - dualcon_alloc_output, - dualcon_add_vert, - dualcon_add_quad, - flags, - mode, - rmd->threshold, - rmd->hermite_num, - rmd->scale, - rmd->depth); - result = output->mesh; - MEM_freeN(output); + switch (rmd->mode) { + case MOD_REMESH_CENTROID: + mode = DUALCON_CENTROID; + break; + case MOD_REMESH_MASS_POINT: + mode = DUALCON_MASS_POINT; + break; + case MOD_REMESH_SHARP_FEATURES: + mode = DUALCON_SHARP_FEATURES; + break; + case MOD_REMESH_VOXEL: + /* Should have been processed before as an OpenVDB operation. */ + BLI_assert(false); + break; + } + /* TODO(jbakker): Dualcon crashes when run in parallel. Could be related to incorrect + * input data or that the library isn't thread safe. This was identified when changing the task + * isolations during T76553. */ + static ThreadMutex dualcon_mutex = BLI_MUTEX_INITIALIZER; + BLI_mutex_lock(&dualcon_mutex); + output = dualcon(&input, + dualcon_alloc_output, + dualcon_add_vert, + dualcon_add_quad, + flags, + mode, + rmd->threshold, + rmd->hermite_num, + rmd->scale, + rmd->depth); + BLI_mutex_unlock(&dualcon_mutex); + + result = output->mesh; + MEM_freeN(output); + } if (rmd->flag & MOD_REMESH_SMOOTH_SHADING) { MPoly *mpoly = result->mpoly; @@ -193,9 +217,9 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *UNUSED(c #else /* !WITH_MOD_REMESH */ -static Mesh *applyModifier(ModifierData *UNUSED(md), - const ModifierEvalContext *UNUSED(ctx), - Mesh *mesh) +static Mesh *modifyMesh(ModifierData *UNUSED(md), + const ModifierEvalContext *UNUSED(ctx), + Mesh *mesh) { return mesh; } @@ -210,13 +234,16 @@ ModifierTypeInfo modifierType_Remesh = { /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ NULL, diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index 773cbf72d5b..d3d42068812 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -26,21 +26,21 @@ #include "BLI_utildefines.h" -#include "BLI_math.h" #include "BLI_alloca.h" +#include "BLI_math.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" -#include "BKE_library_query.h" +#include "BKE_lib_query.h" #include "BKE_mesh.h" #include "DEG_depsgraph_build.h" #include "DEG_depsgraph_query.h" -#include "MOD_modifiertypes.h" #include "MEM_guardedalloc.h" +#include "MOD_modifiertypes.h" #include "BLI_strict_flags.h" @@ -112,7 +112,7 @@ static Mesh *mesh_remove_doubles_on_axis(Mesh *result, const float axis_offset[3], const float merge_threshold) { - const float merge_threshold_sq = SQUARE(merge_threshold); + const float merge_threshold_sq = square_f(merge_threshold); const bool use_offset = axis_offset != NULL; uint tot_doubles = 0; for (uint i = 0; i < totvert; i += 1) { @@ -178,7 +178,7 @@ static void initData(ModifierData *md) ltmd->merge_dist = 0.01f; } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *meshData) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *meshData) { Mesh *mesh = meshData; Mesh *result; @@ -352,12 +352,9 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes * Note! smaller then `FLT_EPSILON * 100` * gives problems with float precision so its never closed. */ if (fabsf(screw_ofs) <= (FLT_EPSILON * 100.0f) && - fabsf(fabsf(angle) - ((float)M_PI * 2.0f)) <= (FLT_EPSILON * 100.0f)) { + fabsf(fabsf(angle) - ((float)M_PI * 2.0f)) <= (FLT_EPSILON * 100.0f) && step_tot > 3) { close = 1; step_tot--; - if (step_tot < 3) { - step_tot = 3; - } maxVerts = totvert * step_tot; /* -1 because we're joining back up */ maxEdges = (totvert * step_tot) + /* these are the edges between new verts */ @@ -368,8 +365,8 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes } else { close = 0; - if (step_tot < 3) { - step_tot = 3; + if (step_tot < 2) { + step_tot = 2; } maxVerts = totvert * step_tot; /* -1 because we're joining back up */ @@ -1090,7 +1087,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes /* validate loop edges */ #if 0 { - unsigned i = 0; + uint i = 0; printf("\n"); for (; i < maxPolys * 4; i += 4) { uint ii; @@ -1168,13 +1165,16 @@ ModifierTypeInfo modifierType_Screw = { /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ NULL, diff --git a/source/blender/modifiers/intern/MOD_shapekey.c b/source/blender/modifiers/intern/MOD_shapekey.c index 69db6f5565d..abab0aff927 100644 --- a/source/blender/modifiers/intern/MOD_shapekey.c +++ b/source/blender/modifiers/intern/MOD_shapekey.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -25,8 +25,8 @@ #include "BLI_math.h" -#include "DNA_mesh_types.h" #include "DNA_key_types.h" +#include "DNA_mesh_types.h" #include "BKE_key.h" #include "BKE_particle.h" @@ -122,7 +122,7 @@ ModifierTypeInfo modifierType_ShapeKey = { /* structName */ "ShapeKeyModifierData", /* structSize */ sizeof(ShapeKeyModifierData), /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice | + /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, /* copyData */ NULL, @@ -131,7 +131,10 @@ ModifierTypeInfo modifierType_ShapeKey = { /* deformMatrices */ deformMatrices, /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ deformMatricesEM, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ NULL, /* requiredDataMask */ NULL, diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c index 6e4b0edb004..bb8519b01ea 100644 --- a/source/blender/modifiers/intern/MOD_shrinkwrap.c +++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -29,8 +29,8 @@ #include "DNA_object_types.h" #include "BKE_editmesh.h" -#include "BKE_library.h" -#include "BKE_library_query.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_shrinkwrap.h" @@ -136,12 +136,17 @@ static void deformVertsEM(ModifierData *md, { ShrinkwrapModifierData *swmd = (ShrinkwrapModifierData *)md; struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); - Mesh *mesh_src = MOD_deform_mesh_eval_get( - ctx->object, editData, mesh, NULL, numVerts, false, false); + Mesh *mesh_src = NULL; + + if ((swmd->vgroup_name[0] != '\0') || (swmd->shrinkType == MOD_SHRINKWRAP_PROJECT)) { + mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false); + } struct MDeformVert *dvert = NULL; int defgrp_index = -1; - MOD_get_vgroup(ctx->object, mesh_src, swmd->vgroup_name, &dvert, &defgrp_index); + if (swmd->vgroup_name[0] != '\0') { + MOD_get_vgroup(ctx->object, mesh_src, swmd->vgroup_name, &dvert, &defgrp_index); + } shrinkwrapModifier_deform( swmd, ctx, scene, ctx->object, mesh_src, dvert, defgrp_index, vertexCos, numVerts); @@ -199,16 +204,19 @@ ModifierTypeInfo modifierType_Shrinkwrap = { /* structSize */ sizeof(ShrinkwrapModifierData), /* type */ eModifierTypeType_OnlyDeform, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | - eModifierTypeFlag_AcceptsLattice | eModifierTypeFlag_SupportsEditmode | + eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ deformVerts, /* deformMatrices */ NULL, /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c index d10d74da453..0bd16a318ae 100644 --- a/source/blender/modifiers/intern/MOD_simpledeform.c +++ b/source/blender/modifiers/intern/MOD_simpledeform.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -29,12 +29,12 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" +#include "BKE_deform.h" #include "BKE_editmesh.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" #include "BKE_mesh.h" -#include "BKE_library.h" -#include "BKE_library_query.h" #include "BKE_modifier.h" -#include "BKE_deform.h" #include "DEG_depsgraph_query.h" @@ -316,7 +316,7 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, axis_map_table[(smd->mode != MOD_SIMPLEDEFORM_MODE_BEND) ? deform_axis : 2]; for (i = 0; i < numVerts; i++) { - float weight = defvert_array_find_weight_safe(dvert, i, vgroup); + float weight = BKE_defvert_array_find_weight_safe(dvert, i, vgroup); if (invert_vgroup) { weight = 1.0f - weight; @@ -454,16 +454,19 @@ ModifierTypeInfo modifierType_SimpleDeform = { /* type */ eModifierTypeType_OnlyDeform, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | - eModifierTypeFlag_AcceptsLattice | eModifierTypeFlag_SupportsEditmode | + eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ deformVerts, /* deformMatrices */ NULL, /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_simulation.cc b/source/blender/modifiers/intern/MOD_simulation.cc new file mode 100644 index 00000000000..f52daf53186 --- /dev/null +++ b/source/blender/modifiers/intern/MOD_simulation.cc @@ -0,0 +1,109 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 by the Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup modifiers + */ + +#include <iostream> +#include <string> + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" + +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" +#include "DNA_pointcloud_types.h" +#include "DNA_scene_types.h" +#include "DNA_simulation_types.h" + +#include "BKE_customdata.h" +#include "BKE_lib_query.h" +#include "BKE_mesh.h" +#include "BKE_modifier.h" + +#include "DEG_depsgraph_build.h" +#include "DEG_depsgraph_query.h" + +#include "MOD_modifiertypes.h" + +static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) +{ + SimulationModifierData *smd = (SimulationModifierData *)md; + if (smd->simulation) { + DEG_add_simulation_relation(ctx->node, smd->simulation, "Accessed Simulation"); + } +} + +static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData) +{ + SimulationModifierData *smd = (SimulationModifierData *)md; + walk(userData, ob, (ID **)&smd->simulation, IDWALK_CB_USER); +} + +static bool isDisabled(const struct Scene *UNUSED(scene), + ModifierData *md, + bool UNUSED(useRenderParams)) +{ + SimulationModifierData *smd = (SimulationModifierData *)md; + return smd->simulation == nullptr; +} + +static PointCloud *modifyPointCloud(ModifierData *md, + const ModifierEvalContext *UNUSED(ctx), + PointCloud *pointcloud) +{ + SimulationModifierData *smd = (SimulationModifierData *)md; + UNUSED_VARS(smd); + return pointcloud; +} + +ModifierTypeInfo modifierType_Simulation = { + /* name */ "Simulation", + /* structName */ "SimulationModifierData", + /* structSize */ sizeof(SimulationModifierData), + /* type */ eModifierTypeType_None, + /* flags */ (ModifierTypeFlag)0, + + /* copyData */ BKE_modifier_copydata_generic, + + /* deformVerts */ NULL, + /* deformMatrices */ NULL, + /* deformVertsEM */ NULL, + /* deformMatricesEM */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ modifyPointCloud, + /* modifyVolume */ NULL, + + /* initData */ NULL, + /* requiredDataMask */ NULL, + /* freeData */ NULL, + /* isDisabled */ isDisabled, + /* updateDepsgraph */ updateDepsgraph, + /* dependsOnTime */ NULL, + /* dependsOnNormals */ NULL, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ foreachIDLink, + /* foreachTexLink */ NULL, + /* freeRuntimeData */ NULL, +}; diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index 6e7a0b0dbae..98c7d809f33 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ @@ -63,11 +63,11 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" -#include "DNA_object_types.h" #include "DNA_modifier_types.h" +#include "DNA_object_types.h" #include "BKE_deform.h" -#include "BKE_library.h" +#include "BKE_lib_id.h" #include "BKE_mesh.h" #include "BKE_mesh_mapping.h" #include "BKE_modifier.h" @@ -943,7 +943,7 @@ static Mesh *subdivide_base(Mesh *orig) weight = interpf(vg->w2, vg->w1, t); if (weight > 0) { - defvert_add_index_notest(&outdvert[v], vg->def_nr, weight); + BKE_defvert_add_index_notest(&outdvert[v], vg->def_nr, weight); } } @@ -1058,7 +1058,7 @@ static void output_frames(BMesh *bm, SkinNode *sn, const MDeformVert *input_dver dv = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_MDEFORMVERT); BLI_assert(dv->totweight == 0); - defvert_copy(dv, input_dvert); + BKE_defvert_copy(dv, input_dvert); } } } @@ -1779,7 +1779,7 @@ static BMesh *build_skin(SkinNode *skin_nodes, skin_update_merged_vertices(skin_nodes, totvert); if (!skin_output_branch_hulls(&so, skin_nodes, totvert, emap, medge)) { - modifier_setError(&smd->modifier, "Hull error"); + BKE_modifier_set_error(&smd->modifier, "Hull error"); } /* Merge triangles here in the hope of providing better target @@ -1862,7 +1862,7 @@ static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd) MEM_freeN(emapmem); if (!has_valid_root) { - modifier_setError( + BKE_modifier_set_error( &smd->modifier, "No valid root vertex found (you need one per mesh island you want to skin)"); } @@ -1911,7 +1911,7 @@ static void initData(ModifierData *md) smd->symmetry_axes = MOD_SKIN_SYMM_X; } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh) { Mesh *result; @@ -1935,13 +1935,16 @@ ModifierTypeInfo modifierType_Skin = { /* type */ eModifierTypeType_Constructive, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c index c8bc3aaa484..5b13bee7dac 100644 --- a/source/blender/modifiers/intern/MOD_smooth.c +++ b/source/blender/modifiers/intern/MOD_smooth.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -30,11 +30,11 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "BKE_deform.h" #include "BKE_editmesh.h" -#include "BKE_library.h" +#include "BKE_lib_id.h" #include "BKE_mesh.h" #include "BKE_particle.h" -#include "BKE_deform.h" #include "MOD_modifiertypes.h" #include "MOD_util.h" @@ -101,6 +101,7 @@ static void smoothModifier_do( const float fac_new = smd->fac; const float fac_orig = 1.0f - fac_new; + const bool invert_vgroup = (smd->flag & MOD_SMOOTH_INVERT_VGROUP) != 0; MEdge *medges = mesh->medge; const int num_edges = mesh->totedge; @@ -139,7 +140,9 @@ static void smoothModifier_do( } float *vco_new = accumulated_vecs[i]; - const float f_new = defvert_find_weight(dv, defgrp_index) * fac_new; + const float f_new = invert_vgroup ? + (1.0f - BKE_defvert_find_weight(dv, defgrp_index)) * fac_new : + BKE_defvert_find_weight(dv, defgrp_index) * fac_new; if (f_new <= 0.0f) { continue; } @@ -228,13 +231,16 @@ ModifierTypeInfo modifierType_Smooth = { /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ deformVerts, /* deformMatrices */ NULL, /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_softbody.c b/source/blender/modifiers/intern/MOD_softbody.c index 48ccd9b83ed..92516d3d417 100644 --- a/source/blender/modifiers/intern/MOD_softbody.c +++ b/source/blender/modifiers/intern/MOD_softbody.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -25,9 +25,9 @@ #include "BLI_utildefines.h" -#include "DNA_scene_types.h" #include "DNA_mesh_types.h" #include "DNA_object_force_types.h" +#include "DNA_scene_types.h" #include "BKE_layer.h" #include "BKE_particle.h" @@ -69,6 +69,8 @@ static void updateDepsgraph(ModifierData *UNUSED(md), const ModifierUpdateDepsgr DEG_add_forcefield_relations( ctx->node, ctx->object, ctx->object->soft->effector_weights, true, 0, "Softbody Field"); } + /* We need own transformation as well. */ + DEG_add_modifier_to_transform_relation(ctx->node, "SoftBody Modifier"); } ModifierTypeInfo modifierType_Softbody = { @@ -76,8 +78,9 @@ ModifierTypeInfo modifierType_Softbody = { /* structName */ "SoftbodyModifierData", /* structSize */ sizeof(SoftbodyModifierData), /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice | - eModifierTypeFlag_RequiresOriginalData | eModifierTypeFlag_Single, + /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | + eModifierTypeFlag_RequiresOriginalData | eModifierTypeFlag_Single | + eModifierTypeFlag_UsesPointCache, /* copyData */ NULL, @@ -85,7 +88,10 @@ ModifierTypeInfo modifierType_Softbody = { /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ NULL, /* requiredDataMask */ NULL, diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 8ea0a602b65..01277facacf 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -53,6 +53,8 @@ static void initData(ModifierData *md) smd->mode = MOD_SOLIDIFY_MODE_EXTRUDE; smd->nonmanifold_offset_mode = MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_CONSTRAINTS; smd->nonmanifold_boundary_mode = MOD_SOLIDIFY_NONMANIFOLD_BOUNDARY_MODE_NONE; + smd->merge_tolerance = 0.0001f; + smd->bevel_convex = 0.0f; } static void requiredDataMask(Object *UNUSED(ob), @@ -62,19 +64,22 @@ static void requiredDataMask(Object *UNUSED(ob), SolidifyModifierData *smd = (SolidifyModifierData *)md; /* ask for vertexgroups if we need them */ - if (smd->defgrp_name[0] != '\0') { + if (smd->defgrp_name[0] != '\0' || smd->shell_defgrp_name[0] != '\0' || + smd->rim_defgrp_name[0] != '\0') { r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; } } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { const SolidifyModifierData *smd = (SolidifyModifierData *)md; - if (smd->mode == MOD_SOLIDIFY_MODE_EXTRUDE) { - return MOD_solidify_extrude_applyModifier(md, ctx, mesh); - } - else if (smd->mode == MOD_SOLIDIFY_MODE_NONMANIFOLD) { - return MOD_solidify_nonmanifold_applyModifier(md, ctx, mesh); + switch (smd->mode) { + case MOD_SOLIDIFY_MODE_EXTRUDE: + return MOD_solidify_extrude_modifyMesh(md, ctx, mesh); + case MOD_SOLIDIFY_MODE_NONMANIFOLD: + return MOD_solidify_nonmanifold_modifyMesh(md, ctx, mesh); + default: + BLI_assert(0); } return mesh; } @@ -89,13 +94,16 @@ ModifierTypeInfo modifierType_Solidify = { eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.c b/source/blender/modifiers/intern/MOD_solidify_extrude.c index 8c5a2551c0b..75d2be5292e 100644 --- a/source/blender/modifiers/intern/MOD_solidify_extrude.c +++ b/source/blender/modifiers/intern/MOD_solidify_extrude.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ @@ -29,13 +29,13 @@ #include "MEM_guardedalloc.h" +#include "BKE_deform.h" #include "BKE_mesh.h" #include "BKE_particle.h" -#include "BKE_deform.h" #include "MOD_modifiertypes.h" -#include "MOD_util.h" #include "MOD_solidify_util.h" /* own include */ +#include "MOD_util.h" #ifdef __GNUC__ # pragma GCC diagnostic error "-Wsign-conversion" @@ -183,9 +183,7 @@ static void mesh_calc_hq_normal(Mesh *mesh, float (*poly_nors)[3], float (*r_ver /** \name Main Solidify Function * \{ */ -Mesh *MOD_solidify_extrude_applyModifier(ModifierData *md, - const ModifierEvalContext *ctx, - Mesh *mesh) +Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { Mesh *result; const SolidifyModifierData *smd = (SolidifyModifierData *)md; @@ -224,22 +222,28 @@ Mesh *MOD_solidify_extrude_applyModifier(ModifierData *md, const bool need_poly_normals = (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) || (smd->flag & MOD_SOLIDIFY_EVEN) || - (smd->flag & MOD_SOLIDIFY_OFFSET_ANGLE_CLAMP); + (smd->flag & MOD_SOLIDIFY_OFFSET_ANGLE_CLAMP) || + (smd->bevel_convex != 0); const float ofs_orig = -(((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset); const float ofs_new = smd->offset + ofs_orig; const float offset_fac_vg = smd->offset_fac_vg; const float offset_fac_vg_inv = 1.0f - smd->offset_fac_vg; + const float bevel_convex = smd->bevel_convex; const bool do_flip = (smd->flag & MOD_SOLIDIFY_FLIP) != 0; const bool do_clamp = (smd->offset_clamp != 0.0f); - const bool do_angle_clamp = (smd->flag & MOD_SOLIDIFY_OFFSET_ANGLE_CLAMP) != 0; - const bool do_shell = ((smd->flag & MOD_SOLIDIFY_RIM) && (smd->flag & MOD_SOLIDIFY_NOSHELL)) == - 0; + const bool do_angle_clamp = do_clamp && (smd->flag & MOD_SOLIDIFY_OFFSET_ANGLE_CLAMP) != 0; + const bool do_bevel_convex = bevel_convex != 0.0f; + const bool do_rim = (smd->flag & MOD_SOLIDIFY_RIM) != 0; + const bool do_shell = !(do_rim && (smd->flag & MOD_SOLIDIFY_NOSHELL) != 0); /* weights */ MDeformVert *dvert; const bool defgrp_invert = (smd->flag & MOD_SOLIDIFY_VGROUP_INV) != 0; int defgrp_index; + const int shell_defgrp_index = BKE_object_defgroup_name_index(ctx->object, + smd->shell_defgrp_name); + const int rim_defgrp_index = BKE_object_defgroup_name_index(ctx->object, smd->rim_defgrp_name); /* array size is doubled in case of using a shell */ const uint stride = do_shell ? 2 : 1; @@ -268,7 +272,7 @@ Mesh *MOD_solidify_extrude_applyModifier(ModifierData *md, STACK_INIT(new_vert_arr, numVerts * 2); STACK_INIT(new_edge_arr, numEdges * 2); - if (smd->flag & MOD_SOLIDIFY_RIM) { + if (do_rim) { BLI_bitmap *orig_mvert_tag = BLI_BITMAP_NEW(numVerts, __func__); uint eidx; uint i; @@ -367,6 +371,11 @@ Mesh *MOD_solidify_extrude_applyModifier(ModifierData *md, medge = result->medge; mvert = result->mvert; + if (do_bevel_convex) { + /* Make sure bweight is enabled. */ + result->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT; + } + if (do_shell) { CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)numVerts); CustomData_copy_data(&mesh->vdata, &result->vdata, 0, (int)numVerts, (int)numVerts); @@ -507,62 +516,81 @@ Mesh *MOD_solidify_extrude_applyModifier(ModifierData *md, const float offset = fabsf(smd->offset) * smd->offset_clamp; const float offset_sq = offset * offset; - if (do_clamp) { - uint i; + /* for bevel weight */ + float *edge_angs = NULL; + if (do_clamp) { vert_lens = MEM_malloc_arrayN(numVerts, sizeof(float), "vert_lens"); copy_vn_fl(vert_lens, (int)numVerts, FLT_MAX); - for (i = 0; i < numEdges; i++) { + for (uint i = 0; i < numEdges; i++) { const float ed_len_sq = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co); vert_lens[medge[i].v1] = min_ff(vert_lens[medge[i].v1], ed_len_sq); vert_lens[medge[i].v2] = min_ff(vert_lens[medge[i].v2], ed_len_sq); } + } + + if (do_angle_clamp || do_bevel_convex) { + uint eidx; if (do_angle_clamp) { - uint eidx; vert_angs = MEM_malloc_arrayN(numVerts, sizeof(float), "vert_angs"); copy_vn_fl(vert_angs, (int)numVerts, 0.5f * M_PI); - uint(*edge_user_pairs)[2] = MEM_malloc_arrayN( - numEdges, sizeof(*edge_user_pairs), "edge_user_pairs"); - for (eidx = 0; eidx < numEdges; eidx++) { - edge_user_pairs[eidx][0] = INVALID_UNUSED; - edge_user_pairs[eidx][1] = INVALID_UNUSED; + } + if (do_bevel_convex) { + edge_angs = MEM_malloc_arrayN(numEdges, sizeof(float), "edge_angs"); + if (!do_rim) { + edge_users = MEM_malloc_arrayN(numEdges, sizeof(*edge_users), "solid_mod edges"); } - for (i = 0, mp = orig_mpoly; i < numPolys; i++, mp++) { - ml = orig_mloop + mp->loopstart; - MLoop *ml_prev = ml + (mp->totloop - 1); - - for (int j = 0; j < mp->totloop; j++, ml++) { - /* add edge user */ - eidx = ml_prev->e; - ed = orig_medge + eidx; - BLI_assert(ELEM(ml_prev->v, ed->v1, ed->v2) && ELEM(ml->v, ed->v1, ed->v2)); - char flip = (char)((ml_prev->v > ml->v) == (ed->v1 < ed->v2)); - if (edge_user_pairs[eidx][flip] == INVALID_UNUSED) { - edge_user_pairs[eidx][flip] = i; - } - else { - edge_user_pairs[eidx][0] = INVALID_PAIR; - edge_user_pairs[eidx][1] = INVALID_PAIR; - } - ml_prev = ml; + } + uint(*edge_user_pairs)[2] = MEM_malloc_arrayN( + numEdges, sizeof(*edge_user_pairs), "edge_user_pairs"); + for (eidx = 0; eidx < numEdges; eidx++) { + edge_user_pairs[eidx][0] = INVALID_UNUSED; + edge_user_pairs[eidx][1] = INVALID_UNUSED; + } + mp = orig_mpoly; + for (uint i = 0; i < numPolys; i++, mp++) { + ml = orig_mloop + mp->loopstart; + MLoop *ml_prev = ml + (mp->totloop - 1); + + for (uint j = 0; j < mp->totloop; j++, ml++) { + /* add edge user */ + eidx = ml_prev->e; + ed = orig_medge + eidx; + BLI_assert(ELEM(ml_prev->v, ed->v1, ed->v2) && ELEM(ml->v, ed->v1, ed->v2)); + char flip = (char)((ml_prev->v > ml->v) == (ed->v1 < ed->v2)); + if (edge_user_pairs[eidx][flip] == INVALID_UNUSED) { + edge_user_pairs[eidx][flip] = i; + } + else { + edge_user_pairs[eidx][0] = INVALID_PAIR; + edge_user_pairs[eidx][1] = INVALID_PAIR; } + ml_prev = ml; } - ed = orig_medge; - float e[3]; - for (i = 0; i < numEdges; i++, ed++) { - if (!ELEM(edge_user_pairs[i][0], INVALID_UNUSED, INVALID_PAIR) && - !ELEM(edge_user_pairs[i][1], INVALID_UNUSED, INVALID_PAIR)) { - const float *n0 = poly_nors[edge_user_pairs[i][0]]; - const float *n1 = poly_nors[edge_user_pairs[i][1]]; - sub_v3_v3v3(e, orig_mvert[ed->v1].co, orig_mvert[ed->v2].co); - normalize_v3(e); - const float angle = angle_signed_on_axis_v3v3_v3(n0, n1, e); + } + ed = orig_medge; + float e[3]; + for (uint i = 0; i < numEdges; i++, ed++) { + if (!ELEM(edge_user_pairs[i][0], INVALID_UNUSED, INVALID_PAIR) && + !ELEM(edge_user_pairs[i][1], INVALID_UNUSED, INVALID_PAIR)) { + const float *n0 = poly_nors[edge_user_pairs[i][0]]; + const float *n1 = poly_nors[edge_user_pairs[i][1]]; + sub_v3_v3v3(e, orig_mvert[ed->v1].co, orig_mvert[ed->v2].co); + normalize_v3(e); + const float angle = angle_signed_on_axis_v3v3_v3(n0, n1, e); + if (do_angle_clamp) { vert_angs[ed->v1] = max_ff(vert_angs[ed->v1], angle); vert_angs[ed->v2] = max_ff(vert_angs[ed->v2], angle); } + if (do_bevel_convex) { + edge_angs[i] = angle; + if (!do_rim) { + edge_users[i] = INVALID_PAIR; + } + } } - MEM_freeN(edge_user_pairs); } + MEM_freeN(edge_user_pairs); } if (ofs_new != 0.0f) { @@ -578,10 +606,10 @@ Mesh *MOD_solidify_extrude_applyModifier(ModifierData *md, if (dvert) { MDeformVert *dv = &dvert[i]; if (defgrp_invert) { - scalar_short_vgroup = 1.0f - defvert_find_weight(dv, defgrp_index); + scalar_short_vgroup = 1.0f - BKE_defvert_find_weight(dv, defgrp_index); } else { - scalar_short_vgroup = defvert_find_weight(dv, defgrp_index); + scalar_short_vgroup = BKE_defvert_find_weight(dv, defgrp_index); } scalar_short_vgroup = (offset_fac_vg + (scalar_short_vgroup * offset_fac_vg_inv)) * scalar_short; @@ -625,10 +653,10 @@ Mesh *MOD_solidify_extrude_applyModifier(ModifierData *md, if (dvert) { MDeformVert *dv = &dvert[i]; if (defgrp_invert) { - scalar_short_vgroup = 1.0f - defvert_find_weight(dv, defgrp_index); + scalar_short_vgroup = 1.0f - BKE_defvert_find_weight(dv, defgrp_index); } else { - scalar_short_vgroup = defvert_find_weight(dv, defgrp_index); + scalar_short_vgroup = BKE_defvert_find_weight(dv, defgrp_index); } scalar_short_vgroup = (offset_fac_vg + (scalar_short_vgroup * offset_fac_vg_inv)) * scalar_short; @@ -658,6 +686,33 @@ Mesh *MOD_solidify_extrude_applyModifier(ModifierData *md, } } + if (do_bevel_convex) { + for (uint i = 0; i < numEdges; i++) { + if (edge_users[i] == INVALID_PAIR) { + float angle = edge_angs[i]; + medge[i].bweight = (char)clamp_i( + (int)medge[i].bweight + (int)((angle < M_PI ? clamp_f(bevel_convex, 0.0f, 1.0f) : + clamp_f(bevel_convex, -1.0f, 0.0f)) * + 255), + 0, + 255); + if (do_shell) { + medge[i + numEdges].bweight = (char)clamp_i( + (int)medge[i + numEdges].bweight + + (int)((angle > M_PI ? clamp_f(bevel_convex, 0.0f, 1.0f) : + clamp_f(bevel_convex, -1.0f, 0.0f)) * + 255), + 0, + 255); + } + } + } + if (!do_rim) { + MEM_freeN(edge_users); + } + MEM_freeN(edge_angs); + } + if (do_clamp) { MEM_freeN(vert_lens); if (do_angle_clamp) { @@ -740,20 +795,88 @@ Mesh *MOD_solidify_extrude_applyModifier(ModifierData *md, if (defgrp_invert) { for (i = 0; i < numVerts; i++, dv++) { - scalar = 1.0f - defvert_find_weight(dv, defgrp_index); + scalar = 1.0f - BKE_defvert_find_weight(dv, defgrp_index); scalar = offset_fac_vg + (scalar * offset_fac_vg_inv); vert_angles[i] *= scalar; } } else { for (i = 0; i < numVerts; i++, dv++) { - scalar = defvert_find_weight(dv, defgrp_index); + scalar = BKE_defvert_find_weight(dv, defgrp_index); scalar = offset_fac_vg + (scalar * offset_fac_vg_inv); vert_angles[i] *= scalar; } } } + /* for angle clamp */ + float *vert_angs = NULL; + /* for bevel convex */ + float *edge_angs = NULL; + + if (do_angle_clamp || do_bevel_convex) { + uint eidx; + if (do_angle_clamp) { + vert_angs = MEM_malloc_arrayN(numVerts, sizeof(float), "vert_angs even"); + copy_vn_fl(vert_angs, (int)numVerts, 0.5f * M_PI); + } + if (do_bevel_convex) { + edge_angs = MEM_malloc_arrayN(numEdges, sizeof(float), "edge_angs even"); + if (!do_rim) { + edge_users = MEM_malloc_arrayN(numEdges, sizeof(*edge_users), "solid_mod edges"); + } + } + uint(*edge_user_pairs)[2] = MEM_malloc_arrayN( + numEdges, sizeof(*edge_user_pairs), "edge_user_pairs"); + for (eidx = 0; eidx < numEdges; eidx++) { + edge_user_pairs[eidx][0] = INVALID_UNUSED; + edge_user_pairs[eidx][1] = INVALID_UNUSED; + } + for (i = 0, mp = orig_mpoly; i < numPolys; i++, mp++) { + ml = orig_mloop + mp->loopstart; + MLoop *ml_prev = ml + (mp->totloop - 1); + + for (int j = 0; j < mp->totloop; j++, ml++) { + /* add edge user */ + eidx = ml_prev->e; + ed = orig_medge + eidx; + BLI_assert(ELEM(ml_prev->v, ed->v1, ed->v2) && ELEM(ml->v, ed->v1, ed->v2)); + char flip = (char)((ml_prev->v > ml->v) == (ed->v1 < ed->v2)); + if (edge_user_pairs[eidx][flip] == INVALID_UNUSED) { + edge_user_pairs[eidx][flip] = i; + } + else { + edge_user_pairs[eidx][0] = INVALID_PAIR; + edge_user_pairs[eidx][1] = INVALID_PAIR; + } + ml_prev = ml; + } + } + ed = orig_medge; + float e[3]; + for (i = 0; i < numEdges; i++, ed++) { + if (!ELEM(edge_user_pairs[i][0], INVALID_UNUSED, INVALID_PAIR) && + !ELEM(edge_user_pairs[i][1], INVALID_UNUSED, INVALID_PAIR)) { + const float *n0 = poly_nors[edge_user_pairs[i][0]]; + const float *n1 = poly_nors[edge_user_pairs[i][1]]; + if (do_angle_clamp) { + const float angle = M_PI - angle_normalized_v3v3(n0, n1); + vert_angs[ed->v1] = max_ff(vert_angs[ed->v1], angle); + vert_angs[ed->v2] = max_ff(vert_angs[ed->v2], angle); + } + if (do_bevel_convex) { + sub_v3_v3v3(e, orig_mvert[ed->v1].co, orig_mvert[ed->v2].co); + normalize_v3(e); + edge_angs[i] = angle_signed_on_axis_v3v3_v3(n0, n1, e); + if (!do_rim) { + edge_users[i] = INVALID_PAIR; + } + } + } + } + MEM_freeN(edge_user_pairs); + } + if (do_clamp) { const float clamp_fac = 1 + (do_angle_clamp ? fabsf(smd->offset_fac) : 0); const float offset = fabsf(smd->offset) * smd->offset_clamp * clamp_fac; @@ -767,48 +890,6 @@ Mesh *MOD_solidify_extrude_applyModifier(ModifierData *md, vert_lens_sq[medge[i].v2] = min_ff(vert_lens_sq[medge[i].v2], ed_len); } if (do_angle_clamp) { - uint eidx; - float *vert_angs = MEM_malloc_arrayN(numVerts, sizeof(float), "vert_angs even"); - copy_vn_fl(vert_angs, (int)numVerts, 0.5f * M_PI); - uint(*edge_user_pairs)[2] = MEM_malloc_arrayN( - numEdges, sizeof(*edge_user_pairs), "edge_user_pairs"); - for (eidx = 0; eidx < numEdges; eidx++) { - edge_user_pairs[eidx][0] = INVALID_UNUSED; - edge_user_pairs[eidx][1] = INVALID_UNUSED; - } - for (i = 0, mp = orig_mpoly; i < numPolys; i++, mp++) { - ml = orig_mloop + mp->loopstart; - MLoop *ml_prev = ml + (mp->totloop - 1); - - for (int j = 0; j < mp->totloop; j++, ml++) { - /* add edge user */ - eidx = ml_prev->e; - ed = orig_medge + eidx; - BLI_assert(ELEM(ml_prev->v, ed->v1, ed->v2) && ELEM(ml->v, ed->v1, ed->v2)); - char flip = (char)((ml_prev->v > ml->v) == (ed->v1 < ed->v2)); - if (edge_user_pairs[eidx][flip] == INVALID_UNUSED) { - edge_user_pairs[eidx][flip] = i; - } - else { - edge_user_pairs[eidx][0] = INVALID_PAIR; - edge_user_pairs[eidx][1] = INVALID_PAIR; - } - ml_prev = ml; - } - } - ed = orig_medge; - for (i = 0; i < numEdges; i++, ed++) { - if (!ELEM(edge_user_pairs[i][0], INVALID_UNUSED, INVALID_PAIR) && - !ELEM(edge_user_pairs[i][1], INVALID_UNUSED, INVALID_PAIR)) { - const float *n0 = poly_nors[edge_user_pairs[i][0]]; - const float *n1 = poly_nors[edge_user_pairs[i][1]]; - const float angle = M_PI - angle_normalized_v3v3(n0, n1); - vert_angs[ed->v1] = max_ff(vert_angs[ed->v1], angle); - vert_angs[ed->v2] = max_ff(vert_angs[ed->v2], angle); - } - } - MEM_freeN(edge_user_pairs); - for (i = 0; i < numVerts; i++) { float cos_ang = cosf(vert_angs[i] * 0.5f); if (cos_ang > 0) { @@ -832,6 +913,33 @@ Mesh *MOD_solidify_extrude_applyModifier(ModifierData *md, } } + if (do_bevel_convex) { + for (i = 0; i < numEdges; i++) { + if (edge_users[i] == INVALID_PAIR) { + float angle = edge_angs[i]; + medge[i].bweight = (char)clamp_i( + (int)medge[i].bweight + (int)((angle < M_PI ? clamp_f(bevel_convex, 0, 1) : + clamp_f(bevel_convex, -1, 0)) * + 255), + 0, + 255); + if (do_shell) { + medge[i + numEdges].bweight = (char)clamp_i( + (int)medge[i + numEdges].bweight + + (int)((angle > M_PI ? clamp_f(bevel_convex, 0, 1) : + clamp_f(bevel_convex, -1, 0)) * + 255), + 0, + 255); + } + } + } + if (!do_rim) { + MEM_freeN(edge_users); + } + MEM_freeN(edge_angs); + } + #undef INVALID_UNUSED #undef INVALID_PAIR @@ -874,7 +982,7 @@ Mesh *MOD_solidify_extrude_applyModifier(ModifierData *md, } /* must recalculate normals with vgroups since they can displace unevenly [#26888] */ - if ((mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) || (smd->flag & MOD_SOLIDIFY_RIM) || dvert) { + if ((mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) || do_rim || dvert) { result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; } else if (do_shell) { @@ -886,7 +994,37 @@ Mesh *MOD_solidify_extrude_applyModifier(ModifierData *md, } } - if (smd->flag & MOD_SOLIDIFY_RIM) { + /* Add vertex weights for rim and shell vgroups. */ + if (shell_defgrp_index != -1 || rim_defgrp_index != -1) { + dvert = CustomData_duplicate_referenced_layer(&result->vdata, CD_MDEFORMVERT, result->totvert); + /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */ + if (dvert == NULL) { + /* Add a valid data layer! */ + dvert = CustomData_add_layer( + &result->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, result->totvert); + } + /* Ultimate security check. */ + if (!dvert) { + return result; + } + result->dvert = dvert; + + if (rim_defgrp_index != -1) { + for (uint i = 0; i < rimVerts; i++) { + BKE_defvert_ensure_index(&result->dvert[new_vert_arr[i]], rim_defgrp_index)->weight = 1.0f; + BKE_defvert_ensure_index(&result->dvert[(do_shell ? new_vert_arr[i] : i) + numVerts], + rim_defgrp_index) + ->weight = 1.0f; + } + } + + if (shell_defgrp_index != -1) { + for (uint i = numVerts; i < result->totvert; i++) { + BKE_defvert_ensure_index(&result->dvert[i], shell_defgrp_index)->weight = 1.0f; + } + } + } + if (do_rim) { uint i; /* bugger, need to re-calculate the normals for the new edge faces. @@ -1093,10 +1231,6 @@ Mesh *MOD_solidify_extrude_applyModifier(ModifierData *md, MEM_freeN(poly_nors); } - if (numPolys == 0 && numVerts != 0) { - modifier_setError(md, "Faces needed for useful output"); - } - return result; } diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c index 799c1c966a3..423a6b4458a 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ @@ -27,13 +27,13 @@ #include "MEM_guardedalloc.h" +#include "BKE_deform.h" #include "BKE_mesh.h" #include "BKE_particle.h" -#include "BKE_deform.h" #include "MOD_modifiertypes.h" -#include "MOD_util.h" #include "MOD_solidify_util.h" /* Own include. */ +#include "MOD_util.h" #ifdef __GNUC__ # pragma GCC diagnostic error "-Wsign-conversion" @@ -132,9 +132,9 @@ static int comp_float_int_pair(const void *a, const void *b) return (int)(x->angle > y->angle) - (int)(x->angle < y->angle); } -Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, - const ModifierEvalContext *ctx, - Mesh *mesh) +Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, + const ModifierEvalContext *ctx, + Mesh *mesh) { Mesh *result; const SolidifyModifierData *smd = (SolidifyModifierData *)md; @@ -149,7 +149,6 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, const uint numLoops = (uint)mesh->totloop; if (numPolys == 0 && numVerts != 0) { - modifier_setError(md, "Faces needed for useful output"); return mesh; } @@ -175,12 +174,19 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, 0; const bool do_clamp = (smd->offset_clamp != 0.0f); + const float bevel_convex = smd->bevel_convex; + MDeformVert *dvert; const bool defgrp_invert = (smd->flag & MOD_SOLIDIFY_VGROUP_INV) != 0; int defgrp_index; + const int shell_defgrp_index = BKE_object_defgroup_name_index(ctx->object, + smd->shell_defgrp_name); + const int rim_defgrp_index = BKE_object_defgroup_name_index(ctx->object, smd->rim_defgrp_name); MOD_get_vgroup(ctx->object, mesh, smd->defgrp_name, &dvert, &defgrp_index); + const bool do_flat_faces = dvert && (smd->flag & MOD_SOLIDIFY_NONMANIFOLD_FLAT_FACES); + orig_mvert = mesh->mvert; orig_medge = mesh->medge; orig_mloop = mesh->mloop; @@ -243,6 +249,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, if (mp->totloop > largest_ngon) { largest_ngon = (uint)mp->totloop; } + /* add to final mesh face count */ if (do_shell) { numNewPolys += 2; numNewLoops += (uint)mp->totloop * 2; @@ -272,7 +279,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, /* Edge groups for every original vert. */ EdgeGroup **orig_vert_groups_arr = MEM_calloc_arrayN( numVerts, sizeof(*orig_vert_groups_arr), "orig_vert_groups_arr in solidify"); - /* Duplicate verts map. */ + /* vertex map used to map duplicates. */ uint *vm = MEM_malloc_arrayN(numVerts, sizeof(*vm), "orig_vert_map in solidify"); for (uint i = 0; i < numVerts; i++) { vm[i] = i; @@ -285,10 +292,17 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, bool has_singularities = false; /* Vert edge adjacent map. */ - uint *vert_adj_edges_len = MEM_calloc_arrayN( - numVerts, sizeof(*vert_adj_edges_len), "vert_adj_edges_len in solidify"); OldVertEdgeRef **vert_adj_edges = MEM_calloc_arrayN( numVerts, sizeof(*vert_adj_edges), "vert_adj_edges in solidify"); + /* Original vertex positions (changed for degenerated geometry). */ + float(*orig_mvert_co)[3] = MEM_malloc_arrayN( + numVerts, sizeof(*orig_mvert_co), "orig_mvert_co in solidify"); + /* Fill in the original vertex positions. */ + for (uint i = 0; i < numVerts; i++) { + orig_mvert_co[i][0] = orig_mvert[i].co[0]; + orig_mvert_co[i][1] = orig_mvert[i].co[1]; + orig_mvert_co[i][2] = orig_mvert[i].co[2]; + } /* Create edge to #NewEdgeRef map. */ { @@ -309,15 +323,15 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, BLI_assert(len > 0); uint *adj_faces = MEM_malloc_arrayN( len, sizeof(*adj_faces), "OldEdgeFaceRef::faces in solidify"); - bool *adj_faces_loops_reversed = MEM_malloc_arrayN( - len, sizeof(*adj_faces_loops_reversed), "OldEdgeFaceRef::reversed in solidify"); + bool *adj_faces_reversed = MEM_malloc_arrayN( + len, sizeof(*adj_faces_reversed), "OldEdgeFaceRef::reversed in solidify"); adj_faces[0] = i; for (uint k = 1; k < len; k++) { adj_faces[k] = MOD_SOLIDIFY_EMPTY_TAG; } - adj_faces_loops_reversed[0] = reversed; + adj_faces_reversed[0] = reversed; OldEdgeFaceRef *ref = MEM_mallocN(sizeof(*ref), "OldEdgeFaceRef in solidify"); - *ref = (OldEdgeFaceRef){adj_faces, len, adj_faces_loops_reversed, 1}; + *ref = (OldEdgeFaceRef){adj_faces, len, adj_faces_reversed, 1}; edge_adj_faces[edge] = ref; } else { @@ -334,77 +348,102 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } float edgedir[3] = {0, 0, 0}; + uint *vert_adj_edges_len = MEM_calloc_arrayN( + numVerts, sizeof(*vert_adj_edges_len), "vert_adj_edges_len in solidify"); /* Calculate edge lengths and len vert_adj edges. */ { bool *face_singularity = MEM_calloc_arrayN( numPolys, sizeof(*face_singularity), "face_sides_arr in solidify"); + + const float merge_tolerance_sqr = smd->merge_tolerance * smd->merge_tolerance; + uint *combined_verts = MEM_calloc_arrayN( + numVerts, sizeof(*combined_verts), "combined_verts in solidify"); + ed = orig_medge; for (uint i = 0; i < numEdges; i++, ed++) { if (edge_adj_faces_len[i] > 0) { - const uint v1 = vm[ed->v1]; - const uint v2 = vm[ed->v2]; + uint v1 = vm[ed->v1]; + uint v2 = vm[ed->v2]; if (v1 != v2) { - sub_v3_v3v3(edgedir, orig_mvert[v2].co, orig_mvert[v1].co); + if (v2 < v1) { + SWAP(uint, v1, v2); + } + sub_v3_v3v3(edgedir, orig_mvert_co[v2], orig_mvert_co[v1]); orig_edge_lengths[i] = len_squared_v3(edgedir); - } - if (v1 == v2 || orig_edge_lengths[i] <= FLT_EPSILON) { - if (v2 > v1) { + if (orig_edge_lengths[i] <= merge_tolerance_sqr) { + mul_v3_fl(edgedir, + (combined_verts[v2] + 1) / + (float)(combined_verts[v1] + combined_verts[v2] + 2)); + add_v3_v3(orig_mvert_co[v1], edgedir); for (uint j = v2; j < numVerts; j++) { if (vm[j] == v2) { vm[j] = v1; - vert_adj_edges_len[v1] += vert_adj_edges_len[j]; - vert_adj_edges_len[j] = 0; } } + vert_adj_edges_len[v1] += vert_adj_edges_len[v2]; + vert_adj_edges_len[v2] = 0; + combined_verts[v1] += combined_verts[v2] + 1; + + if (do_shell) { + numNewLoops -= edge_adj_faces_len[i] * 2; + } + + edge_adj_faces_len[i] = 0; + MEM_freeN(edge_adj_faces[i]->faces); + MEM_freeN(edge_adj_faces[i]->faces_reversed); + MEM_freeN(edge_adj_faces[i]); + edge_adj_faces[i] = NULL; + } + else { + orig_edge_lengths[i] = sqrtf(orig_edge_lengths[i]); + vert_adj_edges_len[v1]++; + vert_adj_edges_len[v2]++; } - else if (v2 < v1) { - for (uint j = v1; j < numVerts; j++) { - if (vm[j] == v1) { - vm[j] = v2; - vert_adj_edges_len[v2] += vert_adj_edges_len[j]; - vert_adj_edges_len[j] = 0; + } + } + } + /* remove zero faces in a second pass */ + ed = orig_medge; + for (uint i = 0; i < numEdges; i++, ed++) { + const uint v1 = vm[ed->v1]; + const uint v2 = vm[ed->v2]; + if (v1 == v2 && edge_adj_faces[i]) { + /* Remove polys. */ + for (uint j = 0; j < edge_adj_faces[i]->faces_len; j++) { + const uint face = edge_adj_faces[i]->faces[j]; + if (!face_singularity[face]) { + bool is_singularity = true; + for (uint k = 0; k < orig_mpoly[face].totloop; k++) { + if (vm[orig_mloop[((uint)orig_mpoly[face].loopstart) + k].v] != v1) { + is_singularity = false; + break; } } - } - if (do_shell) { - numNewLoops -= edge_adj_faces_len[i] * 2; - } - if (v1 == v2) { - /* Remove polys. */ - for (uint j = 0; j < edge_adj_faces[i]->faces_len; j++) { - const uint face = edge_adj_faces[i]->faces[j]; - if (!face_singularity[face]) { - bool is_singularity = true; - for (uint k = 0; k < orig_mpoly[face].totloop; k++) { - if (vm[orig_mloop[((uint)orig_mpoly[face].loopstart) + k].v] != v1) { - is_singularity = false; - break; - } - } - if (is_singularity) { - face_singularity[face] = true; - if (do_shell) { - numNewPolys -= 2; - } - } + if (is_singularity) { + face_singularity[face] = true; + /* remove from final mesh poly count */ + if (do_shell) { + numNewPolys -= 2; } } } - edge_adj_faces_len[i] = 0; - MEM_freeN(edge_adj_faces[i]->faces); - MEM_freeN(edge_adj_faces[i]->faces_reversed); - MEM_freeN(edge_adj_faces[i]); - edge_adj_faces[i] = NULL; } - else if (edge_adj_faces_len[i] > 0) { - orig_edge_lengths[i] = sqrtf(orig_edge_lengths[i]); - vert_adj_edges_len[v1]++; - vert_adj_edges_len[v2]++; + + if (do_shell) { + numNewLoops -= edge_adj_faces_len[i] * 2; } + + edge_adj_faces_len[i] = 0; + MEM_freeN(edge_adj_faces[i]->faces); + MEM_freeN(edge_adj_faces[i]->faces_reversed); + MEM_freeN(edge_adj_faces[i]); + edge_adj_faces[i] = NULL; } } + MEM_freeN(face_singularity); + MEM_freeN(combined_verts); } /* Create vert_adj_edges for verts. */ @@ -452,8 +491,8 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } if (invalid_edge_index) { - /* Should never actually be executed. */ if (j == 1) { + /* Should never actually be executed. */ vert_adj_edges[vs[0]]->edges_len--; } break; @@ -461,6 +500,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } } + /* Remove zero faces that are in shape of an edge. */ if (invalid_edge_index) { const uint tmp = invalid_edge_index - 1; invalid_edge_index = i; @@ -478,6 +518,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } } + /* remove from final face count */ if (do_shell) { numNewPolys -= 2 * j; numNewLoops -= 4 * j; @@ -487,6 +528,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, len, sizeof(*adj_faces), "OldEdgeFaceRef::faces in solidify"); bool *adj_faces_loops_reversed = MEM_malloc_arrayN( len, sizeof(*adj_faces_loops_reversed), "OldEdgeFaceRef::reversed in solidify"); + /* Clean merge of adj_faces. */ j = 0; for (uint k = 0; k < i_adj_faces->faces_len; k++) { if (i_adj_faces->faces[k] != MOD_SOLIDIFY_EMPTY_TAG) { @@ -521,13 +563,19 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } + MEM_freeN(vert_adj_edges_len); + /* Filter duplicate polys. */ { ed = orig_medge; + /* Iterate over edges and only check the faces around an edge for duplicates + * (performance optimization). */ for (uint i = 0; i < numEdges; i++, ed++) { if (edge_adj_faces_len[i] > 0) { const OldEdgeFaceRef *adj_faces = edge_adj_faces[i]; uint adj_len = adj_faces->faces_len; + /* Not that #adj_len doesn't need to equal edge_adj_faces_len anymore + * because #adj_len is shared when a face got collapsed to an edge. */ if (adj_len > 1) { /* For each face pair check if they have equal verts. */ for (uint j = 0; j < adj_len; j++) { @@ -564,40 +612,56 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, uint del_loops = 0; for (uint m = 0; m < totloop; m++, ml++) { const uint e = ml->e; - uint face_index = j; - uint *e_adj_faces_faces = edge_adj_faces[e]->faces; - bool *e_adj_faces_reversed = edge_adj_faces[e]->faces_reversed; - const uint faces_len = edge_adj_faces[e]->faces_len; - if (e != i) { - /* Find index of e in #adj_faces. */ - for (face_index = 0; - face_index < faces_len && e_adj_faces_faces[face_index] != face; - face_index++) { - /* Pass. */ + OldEdgeFaceRef *e_adj_faces = edge_adj_faces[e]; + if (e_adj_faces) { + uint face_index = j; + uint *e_adj_faces_faces = e_adj_faces->faces; + bool *e_adj_faces_reversed = e_adj_faces->faces_reversed; + const uint faces_len = e_adj_faces->faces_len; + if (e != i) { + /* Find index of e in #adj_faces. */ + for (face_index = 0; + face_index < faces_len && e_adj_faces_faces[face_index] != face; + face_index++) { + /* Pass. */ + } + /* If not found. */ + if (face_index == faces_len) { + continue; + } + } + else { + /* If we shrink #edge_adj_faces[i] we need to update this field. */ + adj_len--; } - /* If not found. */ - if (face_index == faces_len) { - continue; + memmove(e_adj_faces_faces + face_index, + e_adj_faces_faces + face_index + 1, + (faces_len - face_index - 1) * sizeof(*e_adj_faces_faces)); + memmove(e_adj_faces_reversed + face_index, + e_adj_faces_reversed + face_index + 1, + (faces_len - face_index - 1) * sizeof(*e_adj_faces_reversed)); + e_adj_faces->faces_len--; + if (edge_adj_faces_len[e] > 0) { + edge_adj_faces_len[e]--; + if (edge_adj_faces_len[e] == 0) { + e_adj_faces->used--; + edge_adj_faces[e] = NULL; + } } - } - else { - adj_len--; - } - memmove(e_adj_faces_faces + face_index, - e_adj_faces_faces + face_index + 1, - (faces_len - face_index - 1) * sizeof(*e_adj_faces_faces)); - memmove(e_adj_faces_reversed + face_index, - e_adj_faces_reversed + face_index + 1, - (faces_len - face_index - 1) * sizeof(*e_adj_faces_reversed)); - edge_adj_faces[e]->faces_len--; - if (edge_adj_faces_len[e] > 0) { - edge_adj_faces_len[e]--; - if (edge_adj_faces_len[e] == 0) { - edge_adj_faces[e]->used--; - edge_adj_faces[e] = NULL; + else if (e_adj_faces->used > 1) { + for (uint n = 0; n < numEdges; n++) { + if (edge_adj_faces[n] == e_adj_faces && edge_adj_faces_len[n] > 0) { + edge_adj_faces_len[n]--; + if (edge_adj_faces_len[n] == 0) { + edge_adj_faces[n]->used--; + edge_adj_faces[n] = NULL; + } + break; + } + } } + del_loops++; } - del_loops++; } if (do_shell) { numNewPolys -= 2; @@ -619,7 +683,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, const uint v1 = vm[ed->v1]; const uint v2 = vm[ed->v2]; if (edge_adj_faces_len[i] > 0) { - sub_v3_v3v3(edgedir, orig_mvert[v2].co, orig_mvert[v1].co); + sub_v3_v3v3(edgedir, orig_mvert_co[v2], orig_mvert_co[v1]); mul_v3_fl(edgedir, 1.0f / orig_edge_lengths[i]); OldEdgeFaceRef *adj_faces = edge_adj_faces[i]; @@ -755,8 +819,6 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, MEM_freeN(edge_adj_faces); } - MEM_freeN(vert_adj_edges_len); - /* Create sorted edge groups for every vert. */ { OldVertEdgeRef **adj_edges_ptr = vert_adj_edges; @@ -779,6 +841,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, /* TODO check where the null pointer come from, * because there should not be any... */ if (new_edges) { + /* count the number of new edges around the original vert */ while (*new_edges) { unassigned_edges_len++; new_edges++; @@ -797,8 +860,11 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } + /* An edge group will always contain min 2 edges + * so max edge group count can be calculated. */ + uint edge_groups_len = unassigned_edges_len / 2; edge_groups = MEM_calloc_arrayN( - (unassigned_edges_len / 2) + 1, sizeof(*edge_groups), "edge_groups in solidify"); + edge_groups_len + 1, sizeof(*edge_groups), "edge_groups in solidify"); uint assigned_edges_len = 0; NewEdgeRef *found_edge = NULL; @@ -807,14 +873,16 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, uint eg_capacity = 5; NewFaceRef *eg_track_faces[2] = {NULL, NULL}; NewFaceRef *last_open_edge_track = NULL; - NewEdgeRef *edge = NULL; while (assigned_edges_len < unassigned_edges_len) { found_edge = NULL; insert_at_start = false; if (eg_index >= 0 && edge_groups[eg_index].edges_len == 0) { + /* Called every time a new group was started in the last iteration. */ + /* Find an unused edge to start the next group + * and setup variables to start creating it. */ uint j = 0; - edge = NULL; + NewEdgeRef *edge = NULL; while (!edge && j < unassigned_edges_len) { edge = unassigned_edges[j++]; if (edge && last_open_edge_track && @@ -856,7 +924,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, for (found_edge_index = 0; found_edge_index < unassigned_edges_len; found_edge_index++, edge_ptr++) { if (*edge_ptr) { - edge = *edge_ptr; + NewEdgeRef *edge = *edge_ptr; if (edge->faces[0] == eg_track_faces[1]) { insert_at_start = false; eg_track_faces[1] = edge->faces[1]; @@ -932,8 +1000,10 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } else { + /* called on first iteration to clean up the eg_index = -1 and start the first group, + * or when the current group is found to be complete (no new found_edge) */ eg_index++; - BLI_assert(eg_index < (unassigned_edges_len / 2)); + BLI_assert(eg_index < edge_groups_len); eg_capacity = 5; NewEdgeRef **edges = MEM_calloc_arrayN( eg_capacity, sizeof(*edges), "edge_group in solidify"); @@ -959,7 +1029,11 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, eg_index++; /* #topo_groups is the number of topo groups from here on. */ topo_groups++; + MEM_freeN(unassigned_edges); + + /* TODO reshape the edge_groups array to its actual size + * after writing is finished to save on memory. */ } /* Split of long self intersection groups */ @@ -1232,6 +1306,30 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, /* Calculate EdgeGroup vertex coordinates. */ { + float *face_weight = NULL; + + if (do_flat_faces) { + face_weight = MEM_malloc_arrayN(numPolys, sizeof(*face_weight), "face_weight in solidify"); + + mp = orig_mpoly; + for (uint i = 0; i < numPolys; i++, mp++) { + float scalar_vgroup = 1.0f; + int loopend = mp->loopstart + mp->totloop; + ml = orig_mloop + mp->loopstart; + for (int j = mp->loopstart; j < loopend; j++, ml++) { + MDeformVert *dv = &dvert[ml->v]; + if (defgrp_invert) { + scalar_vgroup = min_ff(1.0f - BKE_defvert_find_weight(dv, defgrp_index), + scalar_vgroup); + } + else { + scalar_vgroup = min_ff(BKE_defvert_find_weight(dv, defgrp_index), scalar_vgroup); + } + } + face_weight[i] = scalar_vgroup; + } + } + mv = orig_mvert; gs_ptr = orig_vert_groups_arr; for (uint i = 0; i < numVerts; i++, mv++, gs_ptr++) { @@ -1264,14 +1362,22 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, NewFaceRef *face = edge->faces[l]; if (face && (first_edge == NULL || (first_edge->faces[0] != face && first_edge->faces[1] != face))) { - const float ofs = face->reversed ? ofs_back_clamped : ofs_front_clamped; + float ofs = face->reversed ? ofs_back_clamped : ofs_front_clamped; + /* Use face_weight here to make faces thinner. */ + if (do_flat_faces) { + ofs *= face_weight[face->index]; + } + if (!null_faces[face->index]) { + /* And normal to the queue. */ mul_v3_v3fl(normals_queue[queue_index], poly_nors[face->index], face->reversed ? -1 : 1); normals_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; } @@ -1373,6 +1479,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } 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]); @@ -1427,6 +1534,11 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, (first_edge->faces[0] != face && first_edge->faces[1] != face))) { float angle = 1.0f; float ofs = face->reversed ? -ofs_back_clamped : ofs_front_clamped; + /* Use face_weight here to make faces thinner. */ + if (do_flat_faces) { + ofs *= face_weight[face->index]; + } + if (smd->nonmanifold_offset_mode == MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_EVEN) { MLoop *ml_next = orig_mloop + face->face->loopstart; @@ -1437,8 +1549,9 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, ml_prev = ml; ml = ml_next; } - angle = angle_v3v3v3( - orig_mvert[vm[ml_prev->v]].co, mv->co, orig_mvert[vm[ml_next->v]].co); + angle = angle_v3v3v3(orig_mvert_co[vm[ml_prev->v]], + orig_mvert_co[i], + orig_mvert_co[vm[ml_next->v]]); if (face->reversed) { total_angle_back += angle * ofs * ofs; } @@ -1532,7 +1645,8 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, 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[vm[e->v1] == i ? e->v2 : e->v1].co, mv->co); + 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) { @@ -1554,10 +1668,12 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, MEdge *e1_edge = orig_medge + g->edges[g->edges_len - 1]->old_edge; float e0[3]; float e1[3]; - sub_v3_v3v3( - e0, orig_mvert[vm[e0_edge->v1] == i ? e0_edge->v2 : e0_edge->v1].co, mv->co); - sub_v3_v3v3( - e1, orig_mvert[vm[e1_edge->v1] == i ? e1_edge->v2 : e1_edge->v1].co, mv->co); + sub_v3_v3v3(e0, + orig_mvert_co[vm[e0_edge->v1] == i ? e0_edge->v2 : e0_edge->v1], + orig_mvert_co[i]); + sub_v3_v3v3(e1, + orig_mvert_co[vm[e1_edge->v1] == i ? e1_edge->v2 : e1_edge->v1], + orig_mvert_co[i]); if (smd->nonmanifold_boundary_mode == MOD_SOLIDIFY_NONMANIFOLD_BOUNDARY_MODE_FLAT) { cross_v3_v3v3(constr_nor, e0, e1); } @@ -1592,13 +1708,13 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } float scalar_vgroup = 1; /* Use vertex group. */ - if (dvert) { + if (dvert && !do_flat_faces) { MDeformVert *dv = &dvert[i]; if (defgrp_invert) { - scalar_vgroup = 1.0f - defvert_find_weight(dv, defgrp_index); + scalar_vgroup = 1.0f - BKE_defvert_find_weight(dv, defgrp_index); } else { - scalar_vgroup = defvert_find_weight(dv, defgrp_index); + scalar_vgroup = BKE_defvert_find_weight(dv, defgrp_index); } scalar_vgroup = offset_fac_vg + (scalar_vgroup * offset_fac_vg_inv); } @@ -1643,16 +1759,21 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } mul_v3_fl(nor, scalar_vgroup); - add_v3_v3v3(g->co, nor, mv->co); + add_v3_v3v3(g->co, nor, orig_mvert_co[i]); } else { - copy_v3_v3(g->co, mv->co); + copy_v3_v3(g->co, orig_mvert_co[i]); } } } } + + if (do_flat_faces) { + MEM_freeN(face_weight); + } } + MEM_freeN(orig_mvert_co); if (null_faces) { MEM_freeN(null_faces); } @@ -1722,6 +1843,23 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, int *origindex_edge = CustomData_get_layer(&result->edata, CD_ORIGINDEX); int *origindex_poly = CustomData_get_layer(&result->pdata, CD_ORIGINDEX); + if (bevel_convex != 0.0f) { + /* make sure bweight is enabled */ + result->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT; + } + + /* Checks that result has dvert data. */ + if (shell_defgrp_index != -1 || rim_defgrp_index != -1) { + dvert = CustomData_duplicate_referenced_layer(&result->vdata, CD_MDEFORMVERT, result->totvert); + /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */ + if (dvert == NULL) { + /* Add a valid data layer! */ + dvert = CustomData_add_layer( + &result->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, result->totvert); + } + result->dvert = dvert; + } + /* Make_new_verts. */ { gs_ptr = orig_vert_groups_arr; @@ -1775,6 +1913,17 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, medge[insert].flag = orig_medge[(*l)->old_edge].flag | ME_EDGEDRAW | ME_EDGERENDER; medge[insert].crease = orig_medge[(*l)->old_edge].crease; medge[insert].bweight = orig_medge[(*l)->old_edge].bweight; + if (bevel_convex != 0.0f && (*l)->faces[1] != NULL) { + medge[insert].bweight = (char)clamp_i( + (int)medge[insert].bweight + (int)(((*l)->angle > M_PI + FLT_EPSILON ? + clamp_f(bevel_convex, 0.0f, 1.0f) : + ((*l)->angle < M_PI - FLT_EPSILON ? + clamp_f(bevel_convex, -1.0f, 0.0f) : + 0)) * + 255), + 0, + 255); + } (*l)->new_edge = insert; } } @@ -1785,13 +1934,32 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, MEM_freeN(singularity_edges); } - /* DEBUG CODE FOR BUGFIXING (can not be removed because every bugfix needs this badly!). */ + /* DEBUG CODE FOR BUG-FIXING (can not be removed because every bug-fix needs this badly!). */ #if 0 { + /* this code will output the content of orig_vert_groups_arr. + * in orig_vert_groups_arr these conditions must be met for every vertex: + * - new_edge value should have no duplicates + * - every old_edge value should appear twice + * - every group should have at least two members (edges) + * Note: that there can be vertices that only have one group. They are called singularities. + * These vertices will only have one side (there is no way of telling apart front + * from back like on a mobius strip) + */ + + /* Debug output format: + * <original vertex id>: + * { + * { <old edge id>/<new edge id>, } \ + * (tg:<topology group id>)(s:<is split group>,c:<is closed group (before splitting)>) + * } + */ gs_ptr = orig_vert_groups_arr; for (uint i = 0; i < numVerts; i++, gs_ptr++) { EdgeGroup *gs = *gs_ptr; + /* check if the vertex is present (may be dissolved because of proximity) */ if (gs) { + printf("%d:\n", i); for (EdgeGroup *g = gs; g->valid; g++) { NewEdgeRef **e = g->edges; for (uint j = 0; j < g->edges_len; j++, e++) { @@ -1799,7 +1967,6 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } printf("(tg:%u)(s:%u,c:%d)\n", g->topo_group, g->split, g->is_orig_closed); } - printf("\n"); } } } @@ -1808,7 +1975,8 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, /* Make boundary edges/faces. */ { gs_ptr = orig_vert_groups_arr; - for (uint i = 0; i < numVerts; i++, gs_ptr++) { + mv = orig_mvert; + for (uint i = 0; i < numVerts; i++, gs_ptr++, mv++) { EdgeGroup *gs = *gs_ptr; if (gs) { EdgeGroup *g = gs; @@ -1830,15 +1998,39 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, max_crease = 0; max_bweight = 0; flag = 0; - for (uint k = 1; k < g->edges_len - 1; k++) { - ed = orig_medge + g->edges[k]->old_edge; - if (ed->crease > max_crease) { - max_crease = ed->crease; + + BLI_assert(g->edges_len >= 2); + + if (g->edges_len == 2) { + max_crease = min_cc(orig_medge[g->edges[0]->old_edge].crease, + orig_medge[g->edges[1]->old_edge].crease); + } + else { + for (uint k = 1; k < g->edges_len - 1; k++) { + ed = orig_medge + g->edges[k]->old_edge; + if (ed->crease > max_crease) { + max_crease = ed->crease; + } + if (g->edges[k]->new_edge != MOD_SOLIDIFY_EMPTY_TAG) { + char bweight = medge[g->edges[k]->new_edge].bweight; + if (bweight > max_bweight) { + max_bweight = bweight; + } + } + flag |= ed->flag; } - if (ed->bweight > max_bweight) { - max_bweight = ed->bweight; + } + + const char bweight_open_edge = min_cc( + orig_medge[g->edges[0]->old_edge].bweight, + orig_medge[g->edges[g->edges_len - 1]->old_edge].bweight); + if (bweight_open_edge > 0) { + max_bweight = min_cc(bweight_open_edge, max_bweight); + } + else { + if (bevel_convex < 0.0f) { + max_bweight = 0; } - flag |= ed->flag; } if (!first_g) { first_g = g; @@ -1860,8 +2052,9 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, medge[edge_index].v2 = g->new_vert; medge[edge_index].flag = ME_EDGEDRAW | ME_EDGERENDER | ((last_flag | flag) & (ME_SEAM | ME_SHARP)); - medge[edge_index].crease = MAX2(last_max_crease, max_crease); - medge[edge_index++].bweight = MAX2(last_max_bweight, max_bweight); + medge[edge_index].crease = min_cc(last_max_crease, max_crease); + medge[edge_index++].bweight = max_cc(mv->bweight, + min_cc(last_max_bweight, max_bweight)); } last_g = g; last_max_crease = max_crease; @@ -1887,8 +2080,9 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, medge[edge_index].v2 = first_g->new_vert; medge[edge_index].flag = ME_EDGEDRAW | ME_EDGERENDER | ((last_flag | first_flag) & (ME_SEAM | ME_SHARP)); - medge[edge_index].crease = MAX2(last_max_crease, first_max_crease); - medge[edge_index++].bweight = MAX2(last_max_bweight, first_max_bweight); + medge[edge_index].crease = min_cc(last_max_crease, first_max_crease); + medge[edge_index++].bweight = max_cc(mv->bweight, + min_cc(last_max_bweight, first_max_bweight)); /* Loop data. */ int *loops = MEM_malloc_arrayN(j, sizeof(*loops), "loops in solidify"); @@ -2027,12 +2221,20 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, MEdge *open_face_edge; uint open_face_edge_index; if (!do_flip) { + if (rim_defgrp_index != -1) { + BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v1], rim_defgrp_index) + ->weight = 1.0f; + } CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1); mloop[loop_index].v = medge[edge1->new_edge].v1; mloop[loop_index++].e = edge1->new_edge; if (!v2_singularity) { open_face_edge_index = edge1->link_edge_groups[1]->open_face_edge; + if (rim_defgrp_index != -1) { + BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v2], rim_defgrp_index) + ->weight = 1.0f; + } CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1); mloop[loop_index].v = medge[edge1->new_edge].v2; open_face_edge = medge + open_face_edge_index; @@ -2044,12 +2246,20 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } + if (rim_defgrp_index != -1) { + BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v2], rim_defgrp_index) + ->weight = 1.0f; + } CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1); mloop[loop_index].v = medge[edge2->new_edge].v2; mloop[loop_index++].e = edge2->new_edge; if (!v1_singularity) { open_face_edge_index = edge2->link_edge_groups[0]->open_face_edge; + if (rim_defgrp_index != -1) { + BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v1], rim_defgrp_index) + ->weight = 1.0f; + } CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1); mloop[loop_index].v = medge[edge2->new_edge].v1; open_face_edge = medge + open_face_edge_index; @@ -2064,6 +2274,10 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, else { if (!v1_singularity) { open_face_edge_index = edge1->link_edge_groups[0]->open_face_edge; + if (rim_defgrp_index != -1) { + BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v1], rim_defgrp_index) + ->weight = 1.0f; + } CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1); mloop[loop_index].v = medge[edge1->new_edge].v1; open_face_edge = medge + open_face_edge_index; @@ -2075,12 +2289,20 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } + if (rim_defgrp_index != -1) { + BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v1], rim_defgrp_index) + ->weight = 1.0f; + } CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1); mloop[loop_index].v = medge[edge2->new_edge].v1; mloop[loop_index++].e = edge2->new_edge; if (!v2_singularity) { open_face_edge_index = edge2->link_edge_groups[1]->open_face_edge; + if (rim_defgrp_index != -1) { + BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v2], rim_defgrp_index) + ->weight = 1.0f; + } CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1); mloop[loop_index].v = medge[edge2->new_edge].v2; open_face_edge = medge + open_face_edge_index; @@ -2092,6 +2314,10 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } + if (rim_defgrp_index != -1) { + BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v2], rim_defgrp_index) + ->weight = 1.0f; + } CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1); mloop[loop_index].v = medge[edge1->new_edge].v2; mloop[loop_index++].e = edge1->new_edge; @@ -2164,11 +2390,15 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, CustomData_copy_data(&mesh->pdata, &result->pdata, (int)(i / 2), (int)poly_index, 1); mpoly[poly_index].loopstart = (int)loop_index; mpoly[poly_index].totloop = (int)k; - mpoly[poly_index].mat_nr = fr->face->mat_nr + mat_ofs; + mpoly[poly_index].mat_nr = fr->face->mat_nr + (fr->reversed ? mat_ofs : 0); CLAMP(mpoly[poly_index].mat_nr, 0, mat_nr_max); mpoly[poly_index].flag = fr->face->flag; if (fr->reversed != do_flip) { for (int l = (int)k - 1; l >= 0; l--) { + if (shell_defgrp_index != -1) { + BKE_defvert_ensure_index(&result->dvert[face_verts[l]], shell_defgrp_index) + ->weight = 1.0f; + } CustomData_copy_data( &mesh->ldata, &result->ldata, (int)face_loops[l], (int)loop_index, 1); mloop[loop_index].v = face_verts[l]; @@ -2194,15 +2424,15 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, MEM_freeN(face_edges); } if (edge_index != numNewEdges) { - modifier_setError( + BKE_modifier_set_error( md, "Internal Error: edges array wrong size: %u instead of %u", numNewEdges, edge_index); } if (poly_index != numNewPolys) { - modifier_setError( + BKE_modifier_set_error( md, "Internal Error: polys array wrong size: %u instead of %u", numNewPolys, poly_index); } if (loop_index != numNewLoops) { - modifier_setError( + BKE_modifier_set_error( md, "Internal Error: loops array wrong size: %u instead of %u", numNewLoops, loop_index); } BLI_assert(edge_index == numNewEdges); diff --git a/source/blender/modifiers/intern/MOD_solidify_util.h b/source/blender/modifiers/intern/MOD_solidify_util.h index 3a9608861dc..6ab4734c451 100644 --- a/source/blender/modifiers/intern/MOD_solidify_util.h +++ b/source/blender/modifiers/intern/MOD_solidify_util.h @@ -22,13 +22,13 @@ #define __MOD_SOLIDIFY_UTIL_H__ /* MOD_solidify_extrude.c */ -Mesh *MOD_solidify_extrude_applyModifier(ModifierData *md, - const ModifierEvalContext *ctx, - Mesh *mesh); +Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, + const ModifierEvalContext *ctx, + Mesh *mesh); /* MOD_solidify_nonmanifold.c */ -Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, - const ModifierEvalContext *ctx, - Mesh *mesh); +Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, + const ModifierEvalContext *ctx, + Mesh *mesh); #endif /* __MOD_SOLIDIFY_UTIL_H__ */ diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index 4a5887c3122..e054e3478ea 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -27,11 +27,10 @@ #include "BLI_utildefines.h" +#include "DNA_mesh_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "DNA_mesh_types.h" -#include "BKE_cdderivedmesh.h" #include "BKE_scene.h" #include "BKE_subdiv.h" #include "BKE_subdiv_ccg.h" @@ -59,7 +58,7 @@ static void initData(ModifierData *md) smd->renderLevels = 2; smd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS; smd->quality = 3; - smd->flags |= eSubsurfModifierFlag_UseCrease; + smd->flags |= (eSubsurfModifierFlag_UseCrease | eSubsurfModifierFlag_ControlEdges); } static void copyData(const ModifierData *md, ModifierData *target, const int flag) @@ -69,7 +68,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla #endif SubsurfModifierData *tsmd = (SubsurfModifierData *)target; - modifier_copyData_generic(md, target, flag); + BKE_modifier_copydata_generic(md, target, flag); tsmd->emCache = tsmd->mCache = NULL; } @@ -149,7 +148,8 @@ static void subdiv_mesh_settings_init(SubdivToMeshSettings *settings, { const int level = subdiv_levels_for_modifier_get(smd, ctx); settings->resolution = (1 << level) + 1; - settings->use_optimal_display = (smd->flags & eSubsurfModifierFlag_ControlEdges); + settings->use_optimal_display = (smd->flags & eSubsurfModifierFlag_ControlEdges) && + !(ctx->flag & MOD_APPLY_TO_BASE_MESH); } static Mesh *subdiv_as_mesh(SubsurfModifierData *smd, @@ -206,11 +206,11 @@ static SubsurfRuntimeData *subsurf_ensure_runtime(SubsurfModifierData *smd) /* Modifier itself. */ -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { Mesh *result = mesh; #if !defined(WITH_OPENSUBDIV) - modifier_setError(md, "Disabled, built without OpenSubdiv"); + BKE_modifier_set_error(md, "Disabled, built without OpenSubdiv"); return result; #endif SubsurfModifierData *smd = (SubsurfModifierData *)md; @@ -249,7 +249,7 @@ static void deformMatrices(ModifierData *md, int num_verts) { #if !defined(WITH_OPENSUBDIV) - modifier_setError(md, "Disabled, built without OpenSubdiv"); + BKE_modifier_set_error(md, "Disabled, built without OpenSubdiv"); return; #endif @@ -290,7 +290,10 @@ ModifierTypeInfo modifierType_Subsurf = { /* deformMatrices */ deformMatrices, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ NULL, diff --git a/source/blender/modifiers/intern/MOD_surface.c b/source/blender/modifiers/intern/MOD_surface.c index 97e6bb9e804..b7449cbe91c 100644 --- a/source/blender/modifiers/intern/MOD_surface.c +++ b/source/blender/modifiers/intern/MOD_surface.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -25,13 +25,13 @@ #include "BLI_math.h" -#include "DNA_scene_types.h" -#include "DNA_object_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "BKE_bvhutils.h" -#include "BKE_library.h" +#include "BKE_lib_id.h" #include "BKE_mesh.h" #include "DEG_depsgraph.h" @@ -56,7 +56,7 @@ static void copyData(const ModifierData *md_src, ModifierData *md_dst, const int { SurfaceModifierData *surmd_dst = (SurfaceModifierData *)md_dst; - modifier_copyData_generic(md_src, md_dst, flag); + BKE_modifier_copydata_generic(md_src, md_dst, flag); surmd_dst->bvhtree = NULL; surmd_dst->mesh = NULL; @@ -196,7 +196,10 @@ ModifierTypeInfo modifierType_Surface = { /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ NULL, diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c index 6ec7d1069de..4169c76272e 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.c +++ b/source/blender/modifiers/intern/MOD_surfacedeform.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Copyright 2017, Blender Foundation. @@ -30,12 +30,14 @@ #include "DNA_scene_types.h" #include "BKE_bvhutils.h" -#include "BKE_mesh_runtime.h" #include "BKE_editmesh.h" -#include "BKE_library.h" -#include "BKE_library_query.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" +#include "BKE_mesh_runtime.h" #include "BKE_modifier.h" +#include "BKE_deform.h" + #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" @@ -110,6 +112,8 @@ typedef struct SDefDeformData { const SDefVert *const bind_verts; float (*const targetCos)[3]; float (*const vertexCos)[3]; + float *const weights; + float const strength; } SDefDeformData; /* Bind result values */ @@ -136,6 +140,19 @@ static void initData(ModifierData *md) smd->verts = NULL; smd->flags = 0; smd->falloff = 4.0f; + smd->strength = 1.0f; +} + +static void requiredDataMask(Object *UNUSED(ob), + ModifierData *md, + CustomData_MeshMasks *r_cddata_masks) +{ + SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; + + /* Ask for vertex groups if we need them. */ + if (smd->defgrp_name[0] != '\0') { + r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; + } } static void freeData(ModifierData *md) @@ -163,7 +180,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla const SurfaceDeformModifierData *smd = (const SurfaceDeformModifierData *)md; SurfaceDeformModifierData *tsmd = (SurfaceDeformModifierData *)target; - modifier_copyData_generic(md, target, flag); + BKE_modifier_copydata_generic(md, target, flag); if (smd->verts) { tsmd->verts = MEM_dupallocN(smd->verts); @@ -1000,20 +1017,20 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig, vert_edges = MEM_calloc_arrayN(tnumverts, sizeof(*vert_edges), "SDefVertEdgeMap"); if (vert_edges == NULL) { - modifier_setError((ModifierData *)smd_eval, "Out of memory"); + BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory"); return false; } adj_array = MEM_malloc_arrayN(tnumedges, 2 * sizeof(*adj_array), "SDefVertEdge"); if (adj_array == NULL) { - modifier_setError((ModifierData *)smd_eval, "Out of memory"); + BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory"); MEM_freeN(vert_edges); return false; } edge_polys = MEM_calloc_arrayN(tnumedges, sizeof(*edge_polys), "SDefEdgeFaceMap"); if (edge_polys == NULL) { - modifier_setError((ModifierData *)smd_eval, "Out of memory"); + BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory"); MEM_freeN(vert_edges); MEM_freeN(adj_array); return false; @@ -1021,14 +1038,14 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig, smd_orig->verts = MEM_malloc_arrayN(numverts, sizeof(*smd_orig->verts), "SDefBindVerts"); if (smd_orig->verts == NULL) { - modifier_setError((ModifierData *)smd_eval, "Out of memory"); + BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory"); freeAdjacencyMap(vert_edges, adj_array, edge_polys); return false; } BKE_bvhtree_from_mesh_get(&treeData, target, BVHTREE_FROM_LOOPTRI, 2); if (treeData.tree == NULL) { - modifier_setError((ModifierData *)smd_eval, "Out of memory"); + BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory"); freeAdjacencyMap(vert_edges, adj_array, edge_polys); MEM_freeN(smd_orig->verts); smd_orig->verts = NULL; @@ -1039,7 +1056,8 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig, mpoly, medge, mloop, tnumpoly, tnumedges, vert_edges, adj_array, edge_polys); if (adj_result == MOD_SDEF_BIND_RESULT_NONMANY_ERR) { - modifier_setError((ModifierData *)smd_eval, "Target has edges with more than two polygons"); + BKE_modifier_set_error((ModifierData *)smd_eval, + "Target has edges with more than two polygons"); freeAdjacencyMap(vert_edges, adj_array, edge_polys); free_bvhtree_from_mesh(&treeData); MEM_freeN(smd_orig->verts); @@ -1066,7 +1084,7 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig, }; if (data.targetCos == NULL) { - modifier_setError((ModifierData *)smd_eval, "Out of memory"); + BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory"); freeData((ModifierData *)smd_orig); return false; } @@ -1085,19 +1103,20 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig, MEM_freeN(data.targetCos); if (data.success == MOD_SDEF_BIND_RESULT_MEM_ERR) { - modifier_setError((ModifierData *)smd_eval, "Out of memory"); + BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory"); freeData((ModifierData *)smd_orig); } else if (data.success == MOD_SDEF_BIND_RESULT_NONMANY_ERR) { - modifier_setError((ModifierData *)smd_eval, "Target has edges with more than two polygons"); + BKE_modifier_set_error((ModifierData *)smd_eval, + "Target has edges with more than two polygons"); freeData((ModifierData *)smd_orig); } else if (data.success == MOD_SDEF_BIND_RESULT_CONCAVE_ERR) { - modifier_setError((ModifierData *)smd_eval, "Target contains concave polygons"); + BKE_modifier_set_error((ModifierData *)smd_eval, "Target contains concave polygons"); freeData((ModifierData *)smd_orig); } else if (data.success == MOD_SDEF_BIND_RESULT_OVERLAP_ERR) { - modifier_setError((ModifierData *)smd_eval, "Target contains overlapping verts"); + BKE_modifier_set_error((ModifierData *)smd_eval, "Target contains overlapping verts"); freeData((ModifierData *)smd_orig); } else if (data.success == MOD_SDEF_BIND_RESULT_GENERIC_ERR) { @@ -1105,7 +1124,7 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig, * to explain this with a reasonably sized message. * Though it shouldn't really matter all that much, * because this is very unlikely to occur */ - modifier_setError((ModifierData *)smd_eval, "Target contains invalid polygons"); + BKE_modifier_set_error((ModifierData *)smd_eval, "Target contains invalid polygons"); freeData((ModifierData *)smd_orig); } @@ -1121,20 +1140,32 @@ static void deformVert(void *__restrict userdata, { const SDefDeformData *const data = (SDefDeformData *)userdata; const SDefBind *sdbind = data->bind_verts[index].binds; + const int num_binds = data->bind_verts[index].numbinds; float *const vertexCos = data->vertexCos[index]; - float norm[3], temp[3]; + float norm[3], temp[3], offset[3]; + const float weight = (data->weights != NULL) ? data->weights[index] : 1.0f; - zero_v3(vertexCos); + /* Check if this vertex will be deformed. If it is not deformed we return and avoid + * unnecessary calculations. */ + if (weight == 0.0f) { + return; + } + + zero_v3(offset); - for (int j = 0; j < data->bind_verts[index].numbinds; j++, sdbind++) { - /* Mode-generic operations (allocate poly coordinates) */ - float(*coords)[3] = MEM_malloc_arrayN(sdbind->numverts, sizeof(*coords), "SDefDoPolyCoords"); + /* Allocate a `coords_buffer` that fits all the temp-data. */ + int max_verts = 0; + for (int j = 0; j < num_binds; j++) { + max_verts = MAX2(max_verts, sdbind[j].numverts); + } + float(*coords_buffer)[3] = MEM_malloc_arrayN(max_verts, sizeof(*coords_buffer), __func__); + for (int j = 0; j < num_binds; j++, sdbind++) { for (int k = 0; k < sdbind->numverts; k++) { - copy_v3_v3(coords[k], data->targetCos[sdbind->vert_inds[k]]); + copy_v3_v3(coords_buffer[k], data->targetCos[sdbind->vert_inds[k]]); } - normal_poly_v3(norm, coords, sdbind->numverts); + normal_poly_v3(norm, coords_buffer, sdbind->numverts); zero_v3(temp); /* ---------- looptri mode ---------- */ @@ -1147,14 +1178,14 @@ static void deformVert(void *__restrict userdata, /* ---------- ngon mode ---------- */ if (sdbind->mode == MOD_SDEF_MODE_NGON) { for (int k = 0; k < sdbind->numverts; k++) { - madd_v3_v3fl(temp, coords[k], sdbind->vert_weights[k]); + madd_v3_v3fl(temp, coords_buffer[k], sdbind->vert_weights[k]); } } /* ---------- centroid mode ---------- */ else if (sdbind->mode == MOD_SDEF_MODE_CENTROID) { float cent[3]; - mid_v3_v3_array(cent, coords, sdbind->numverts); + mid_v3_v3_array(cent, coords_buffer, sdbind->numverts); madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[0]], sdbind->vert_weights[0]); madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[1]], sdbind->vert_weights[1]); @@ -1162,20 +1193,25 @@ static void deformVert(void *__restrict userdata, } } - MEM_freeN(coords); - /* Apply normal offset (generic for all modes) */ madd_v3_v3fl(temp, norm, sdbind->normal_dist); - madd_v3_v3fl(vertexCos, temp, sdbind->influence); + madd_v3_v3fl(offset, temp, sdbind->influence); } + /* Subtract the vertex coord to get the deformation offset. */ + sub_v3_v3(offset, vertexCos); + + /* Add the offset to start coord multiplied by the strength and weight values. */ + madd_v3_v3fl(vertexCos, offset, data->strength * weight); + MEM_freeN(coords_buffer); } static void surfacedeformModifier_do(ModifierData *md, const ModifierEvalContext *ctx, float (*vertexCos)[3], uint numverts, - Object *ob) + Object *ob, + Mesh *mesh) { SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; Mesh *target; @@ -1185,10 +1221,10 @@ static void surfacedeformModifier_do(ModifierData *md, if (!(smd->flags & MOD_SDEF_BIND)) { if (smd->verts != NULL) { if (!DEG_is_active(ctx->depsgraph)) { - modifier_setError(md, "Attempt to bind from inactive dependency graph"); + BKE_modifier_set_error(md, "Attempt to bind from inactive dependency graph"); return; } - ModifierData *md_orig = modifier_get_original(md); + ModifierData *md_orig = BKE_modifier_get_original(md); freeData(md_orig); } return; @@ -1197,7 +1233,7 @@ static void surfacedeformModifier_do(ModifierData *md, Object *ob_target = smd->target; target = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob_target, false); if (!target) { - modifier_setError(md, "No valid target mesh"); + BKE_modifier_set_error(md, "No valid target mesh"); return; } @@ -1207,11 +1243,12 @@ static void surfacedeformModifier_do(ModifierData *md, /* If not bound, execute bind. */ if (smd->verts == NULL) { if (!DEG_is_active(ctx->depsgraph)) { - modifier_setError(md, "Attempt to unbind from inactive dependency graph"); + BKE_modifier_set_error(md, "Attempt to unbind from inactive dependency graph"); return; } - SurfaceDeformModifierData *smd_orig = (SurfaceDeformModifierData *)modifier_get_original(md); + SurfaceDeformModifierData *smd_orig = (SurfaceDeformModifierData *)BKE_modifier_get_original( + md); float tmp_mat[4][4]; invert_m4_m4(tmp_mat, ob->obmat); @@ -1226,19 +1263,52 @@ static void surfacedeformModifier_do(ModifierData *md, /* Poly count checks */ if (smd->numverts != numverts) { - modifier_setError(md, "Verts changed from %u to %u", smd->numverts, numverts); + BKE_modifier_set_error(md, "Verts changed from %u to %u", smd->numverts, numverts); return; } else if (smd->numpoly != tnumpoly) { - modifier_setError(md, "Target polygons changed from %u to %u", smd->numpoly, tnumpoly); + BKE_modifier_set_error(md, "Target polygons changed from %u to %u", smd->numpoly, tnumpoly); + return; + } + + /* Early out if modifier would not affect input at all - still *after* the sanity checks (and + * potential binding) above. + */ + if (smd->strength == 0.0f) { return; } + int defgrp_index; + MDeformVert *dvert; + MOD_get_vgroup(ob, mesh, smd->defgrp_name, &dvert, &defgrp_index); + float *weights = NULL; + const bool invert_group = (smd->flags & MOD_SDEF_INVERT_VGROUP) != 0; + + if (defgrp_index != -1) { + dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, mesh->totvert); + /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */ + if (dvert == NULL) { + /* Add a valid data layer! */ + dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, mesh->totvert); + } + + if (dvert) { + weights = MEM_calloc_arrayN((size_t)numverts, sizeof(*weights), __func__); + MDeformVert *dv = dvert; + for (uint i = 0; i < numverts; i++, dv++) { + weights[i] = invert_group ? (1.0f - BKE_defvert_find_weight(dv, defgrp_index)) : + BKE_defvert_find_weight(dv, defgrp_index); + } + } + } + /* Actual vertex location update starts here */ SDefDeformData data = { .bind_verts = smd->verts, .targetCos = MEM_malloc_arrayN(tnumverts, sizeof(float[3]), "SDefTargetVertArray"), .vertexCos = vertexCos, + .weights = weights, + .strength = smd->strength, }; if (data.targetCos != NULL) { @@ -1255,25 +1325,51 @@ static void surfacedeformModifier_do(ModifierData *md, MEM_freeN(data.targetCos); } + + MEM_SAFE_FREE(weights); } static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, - Mesh *UNUSED(mesh), + Mesh *mesh, float (*vertexCos)[3], int numVerts) { - surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object); + SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; + Mesh *mesh_src = NULL; + + if (smd->defgrp_name[0] != '\0') { + /* Only need to use mesh_src when a vgroup is used. */ + mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false); + } + + surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object, mesh_src); + + if (!ELEM(mesh_src, NULL, mesh)) { + BKE_id_free(NULL, mesh_src); + } } static void deformVertsEM(ModifierData *md, const ModifierEvalContext *ctx, - struct BMEditMesh *UNUSED(editData), - Mesh *UNUSED(mesh), + struct BMEditMesh *em, + Mesh *mesh, float (*vertexCos)[3], int numVerts) { - surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object); + SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; + Mesh *mesh_src = NULL; + + if (smd->defgrp_name[0] != '\0') { + /* Only need to use mesh_src when a vgroup is used. */ + mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false); + } + + surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object, mesh_src); + + if (!ELEM(mesh_src, NULL, mesh)) { + BKE_id_free(NULL, mesh_src); + } } static bool isDisabled(const Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams)) @@ -1302,10 +1398,13 @@ ModifierTypeInfo modifierType_SurfaceDeform = { /* deformMatrices */ NULL, /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, - /* requiredDataMask */ NULL, + /* requiredDataMask */ requiredDataMask, /* freeData */ freeData, /* isDisabled */ isDisabled, /* updateDepsgraph */ updateDepsgraph, diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c index 7fba7e864ae..bb88bda6394 100644 --- a/source/blender/modifiers/intern/MOD_triangulate.c +++ b/source/blender/modifiers/intern/MOD_triangulate.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ @@ -26,8 +26,8 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" -#include "BKE_modifier.h" #include "BKE_mesh.h" +#include "BKE_modifier.h" #include "bmesh.h" #include "bmesh_tools.h" @@ -44,7 +44,7 @@ static Mesh *triangulate_mesh(Mesh *mesh, BMesh *bm; int total_edges, i; MEdge *me; - CustomData_MeshMasks cddata_masks = { + CustomData_MeshMasks cd_mask_extra = { .vmask = CD_MASK_ORIGINDEX, .emask = CD_MASK_ORIGINDEX, .pmask = CD_MASK_ORIGINDEX}; bool keep_clnors = (flag & MOD_TRIANGULATE_KEEP_CUSTOMLOOP_NORMALS) != 0; @@ -53,19 +53,19 @@ static Mesh *triangulate_mesh(Mesh *mesh, BKE_mesh_calc_normals_split(mesh); /* We need that one to 'survive' to/from BMesh conversions. */ CustomData_clear_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); - cddata_masks.lmask |= CD_MASK_NORMAL; + cd_mask_extra.lmask |= CD_MASK_NORMAL; } bm = BKE_mesh_to_bmesh_ex(mesh, &((struct BMeshCreateParams){0}), &((struct BMeshFromMeshParams){ .calc_face_normal = true, - .cd_mask_extra = cddata_masks, + .cd_mask_extra = cd_mask_extra, })); BM_mesh_triangulate(bm, quad_method, ngon_method, min_vertices, false, NULL, NULL, NULL); - result = BKE_mesh_from_bmesh_for_eval_nomain(bm, &cddata_masks, mesh); + result = BKE_mesh_from_bmesh_for_eval_nomain(bm, &cd_mask_extra, mesh); BM_mesh_free(bm); if (keep_clnors) { @@ -103,7 +103,7 @@ static void initData(ModifierData *md) tmd->min_vertices = 4; } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh) { TriangulateModifierData *tmd = (TriangulateModifierData *)md; Mesh *result; @@ -124,13 +124,16 @@ ModifierTypeInfo modifierType_Triangulate = { eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_EnableInEditmode | eModifierTypeFlag_AcceptsCVs, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ NULL, // requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index 0b72c31ad7b..bd453c24a31 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -26,21 +26,22 @@ #include "BLI_utildefines.h" #include "BLI_bitmap.h" -#include "BLI_math_vector.h" #include "BLI_math_matrix.h" +#include "BLI_math_vector.h" #include "DNA_image_types.h" -#include "DNA_meshdata_types.h" #include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "BKE_action.h" /* BKE_pose_channel_find_name */ #include "BKE_deform.h" #include "BKE_editmesh.h" #include "BKE_image.h" #include "BKE_lattice.h" -#include "BKE_library.h" +#include "BKE_lib_id.h" #include "BKE_mesh.h" #include "BKE_object.h" @@ -49,8 +50,8 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" -#include "MOD_util.h" #include "MOD_modifiertypes.h" +#include "MOD_util.h" #include "MEM_guardedalloc.h" @@ -81,12 +82,25 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd, const int numVerts = mesh->totvert; int i; int texmapping = dmd->texmapping; - float mapob_imat[4][4]; + float mapref_imat[4][4]; if (texmapping == MOD_DISP_MAP_OBJECT) { if (dmd->map_object != NULL) { Object *map_object = dmd->map_object; - invert_m4_m4(mapob_imat, map_object->obmat); + if (dmd->map_bone[0] != '\0') { + bPoseChannel *pchan = BKE_pose_channel_find_name(map_object->pose, dmd->map_bone); + if (pchan) { + float mat_bone_world[4][4]; + mul_m4_m4m4(mat_bone_world, map_object->obmat, pchan->pose_mat); + invert_m4_m4(mapref_imat, mat_bone_world); + } + else { + invert_m4_m4(mapref_imat, map_object->obmat); + } + } + else { + invert_m4_m4(mapref_imat, map_object->obmat); + } } else { /* if there is no map object, default to local */ texmapping = MOD_DISP_MAP_LOCAL; @@ -145,7 +159,7 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd, break; case MOD_DISP_MAP_OBJECT: mul_v3_m4v3(*r_texco, ob->obmat, cos != NULL ? *cos : mv->co); - mul_m4_v3(mapob_imat, *r_texco); + mul_m4_v3(mapref_imat, *r_texco); break; } if (cos != NULL) { @@ -235,7 +249,7 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob, void MOD_get_vgroup( Object *ob, struct Mesh *mesh, const char *name, MDeformVert **dvert, int *defgrp_index) { - *defgrp_index = defgroup_name_index(ob, name); + *defgrp_index = BKE_object_defgroup_name_index(ob, name); *dvert = NULL; if (*defgrp_index != -1) { @@ -248,6 +262,22 @@ void MOD_get_vgroup( } } +void MOD_depsgraph_update_object_bone_relation(struct DepsNodeHandle *node, + Object *object, + const char *bonename, + const char *description) +{ + if (object == NULL) { + return; + } + if (bonename[0] != '\0' && object->type == OB_ARMATURE) { + DEG_add_object_relation(node, object, DEG_OB_COMP_EVAL_POSE, description); + } + else { + DEG_add_object_relation(node, object, DEG_OB_COMP_TRANSFORM, description); + } +} + /* only called by BKE_modifier.h/modifier.c */ void modifier_type_init(ModifierTypeInfo *types[]) { @@ -307,5 +337,6 @@ void modifier_type_init(ModifierTypeInfo *types[]) INIT_TYPE(MeshSequenceCache); INIT_TYPE(SurfaceDeform); INIT_TYPE(WeightedNormal); + INIT_TYPE(Simulation); #undef INIT_TYPE } diff --git a/source/blender/modifiers/intern/MOD_util.h b/source/blender/modifiers/intern/MOD_util.h index e1991de3bb8..38e2083082d 100644 --- a/source/blender/modifiers/intern/MOD_util.h +++ b/source/blender/modifiers/intern/MOD_util.h @@ -56,4 +56,8 @@ void MOD_get_vgroup(struct Object *ob, struct MDeformVert **dvert, int *defgrp_index); +void MOD_depsgraph_update_object_bone_relation(struct DepsNodeHandle *node, + struct Object *object, + const char *bonename, + const char *description); #endif /* __MOD_UTIL_H__ */ diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c index 9698e150850..580a065f35e 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.c +++ b/source/blender/modifiers/intern/MOD_uvproject.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -28,13 +28,13 @@ #include "BLI_math.h" #include "BLI_uvproject.h" +#include "DNA_camera_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" -#include "DNA_camera_types.h" #include "DNA_object_types.h" #include "BKE_camera.h" -#include "BKE_library_query.h" +#include "BKE_lib_query.h" #include "BKE_material.h" #include "BKE_mesh.h" @@ -303,7 +303,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, return mesh; } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { Mesh *result; UVProjectModifierData *umd = (UVProjectModifierData *)md; @@ -321,13 +321,16 @@ ModifierTypeInfo modifierType_UVProject = { /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c index 2c5f4b66c23..4ece36d82a4 100644 --- a/source/blender/modifiers/intern/MOD_uvwarp.c +++ b/source/blender/modifiers/intern/MOD_uvwarp.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ @@ -31,25 +31,20 @@ #include "BKE_action.h" /* BKE_pose_channel_find_name */ #include "BKE_deform.h" -#include "BKE_library_query.h" +#include "BKE_lib_query.h" #include "BKE_modifier.h" #include "DEG_depsgraph_query.h" #include "MOD_util.h" -static void uv_warp_from_mat4_pair( - float uv_dst[2], const float uv_src[2], float warp_mat[4][4], int axis_u, int axis_v) +static void uv_warp_from_mat4_pair(float uv_dst[2], const float uv_src[2], float warp_mat[4][4]) { float tuv[3] = {0.0f}; - tuv[axis_u] = uv_src[0]; - tuv[axis_v] = uv_src[1]; - + copy_v2_v2(tuv, uv_src); mul_m4_v3(warp_mat, tuv); - - uv_dst[0] = tuv[axis_u]; - uv_dst[1] = tuv[axis_v]; + copy_v2_v2(uv_dst, tuv); } static void initData(ModifierData *md) @@ -58,6 +53,7 @@ static void initData(ModifierData *md) umd->axis_u = 0; umd->axis_v = 1; copy_v2_fl(umd->center, 0.5f); + copy_v2_fl(umd->scale, 1.0f); } static void requiredDataMask(Object *UNUSED(ob), @@ -92,8 +88,7 @@ typedef struct UVWarpData { int defgrp_index; float (*warp_mat)[4]; - int axis_u; - int axis_v; + bool invert_vgroup; } UVWarpData; static void uv_warp_compute(void *__restrict userdata, @@ -110,28 +105,28 @@ static void uv_warp_compute(void *__restrict userdata, const int defgrp_index = data->defgrp_index; float(*warp_mat)[4] = data->warp_mat; - const int axis_u = data->axis_u; - const int axis_v = data->axis_v; int l; if (dvert) { for (l = 0; l < mp->totloop; l++, ml++, mluv++) { float uv[2]; - const float weight = defvert_find_weight(&dvert[ml->v], defgrp_index); + const float weight = data->invert_vgroup ? + 1.0f - BKE_defvert_find_weight(&dvert[ml->v], defgrp_index) : + BKE_defvert_find_weight(&dvert[ml->v], defgrp_index); - uv_warp_from_mat4_pair(uv, mluv->uv, warp_mat, axis_u, axis_v); + uv_warp_from_mat4_pair(uv, mluv->uv, warp_mat); interp_v2_v2v2(mluv->uv, mluv->uv, uv, weight); } } else { for (l = 0; l < mp->totloop; l++, ml++, mluv++) { - uv_warp_from_mat4_pair(mluv->uv, mluv->uv, warp_mat, axis_u, axis_v); + uv_warp_from_mat4_pair(mluv->uv, mluv->uv, warp_mat); } } } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { UVWarpModifierData *umd = (UVWarpModifierData *)md; int numPolys, numLoops; @@ -141,44 +136,62 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes MDeformVert *dvert; int defgrp_index; char uvname[MAX_CUSTOMDATA_LAYER_NAME]; - float mat_src[4][4]; - float mat_dst[4][4]; - float imat_dst[4][4]; float warp_mat[4][4]; const int axis_u = umd->axis_u; const int axis_v = umd->axis_v; + const bool invert_vgroup = (umd->flag & MOD_UVWARP_INVERT_VGROUP) != 0; /* make sure there are UV Maps available */ if (!CustomData_has_layer(&mesh->ldata, CD_MLOOPUV)) { return mesh; } - else if (ELEM(NULL, umd->object_src, umd->object_dst)) { - modifier_setError(md, "From/To objects must be set"); - return mesh; - } - /* make sure anything moving UVs is available */ - matrix_from_obj_pchan(mat_src, umd->object_src, umd->bone_src); - matrix_from_obj_pchan(mat_dst, umd->object_dst, umd->bone_dst); + if (!ELEM(NULL, umd->object_src, umd->object_dst)) { + float mat_src[4][4]; + float mat_dst[4][4]; + float imat_dst[4][4]; + float shuf_mat[4][4]; - invert_m4_m4(imat_dst, mat_dst); - mul_m4_m4m4(warp_mat, imat_dst, mat_src); + /* make sure anything moving UVs is available */ + matrix_from_obj_pchan(mat_src, umd->object_src, umd->bone_src); + matrix_from_obj_pchan(mat_dst, umd->object_dst, umd->bone_dst); - /* apply warp */ - if (!is_zero_v2(umd->center)) { - float mat_cent[4][4]; - float imat_cent[4][4]; + invert_m4_m4(imat_dst, mat_dst); + mul_m4_m4m4(warp_mat, imat_dst, mat_src); - unit_m4(mat_cent); - mat_cent[3][axis_u] = umd->center[0]; - mat_cent[3][axis_v] = umd->center[1]; + /* apply warp */ + if (!is_zero_v2(umd->center)) { + float mat_cent[4][4]; + float imat_cent[4][4]; - invert_m4_m4(imat_cent, mat_cent); + unit_m4(mat_cent); + mat_cent[3][axis_u] = umd->center[0]; + mat_cent[3][axis_v] = umd->center[1]; - mul_m4_m4m4(warp_mat, warp_mat, imat_cent); - mul_m4_m4m4(warp_mat, mat_cent, warp_mat); + invert_m4_m4(imat_cent, mat_cent); + + mul_m4_m4m4(warp_mat, warp_mat, imat_cent); + mul_m4_m4m4(warp_mat, mat_cent, warp_mat); + } + + int shuf_indices[4] = {axis_u, axis_v, -1, 3}; + shuffle_m4(shuf_mat, shuf_indices); + mul_m4_m4m4(warp_mat, shuf_mat, warp_mat); + transpose_m4(shuf_mat); + mul_m4_m4m4(warp_mat, warp_mat, shuf_mat); + } + else { + unit_m4(warp_mat); } + /* Apply direct 2d transform. */ + translate_m4(warp_mat, umd->center[0], umd->center[1], 0.0f); + const float scale[3] = {umd->scale[0], umd->scale[1], 1.0f}; + rescale_m4(warp_mat, scale); + rotate_m4(warp_mat, 'Z', umd->rotation); + translate_m4(warp_mat, umd->offset[0], umd->offset[1], 0.0f); + translate_m4(warp_mat, -umd->center[0], -umd->center[1], 0.0f); + /* make sure we're using an existing layer */ CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, umd->uvlayer_name, uvname); @@ -199,8 +212,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes .dvert = dvert, .defgrp_index = defgrp_index, .warp_mat = warp_mat, - .axis_u = axis_u, - .axis_v = axis_v, + .invert_vgroup = invert_vgroup, }; TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); @@ -221,26 +233,14 @@ static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, walk(userData, ob, &umd->object_src, IDWALK_CB_NOP); } -static void uv_warp_deps_object_bone_new(struct DepsNodeHandle *node, - Object *object, - const char *bonename) -{ - if (object != NULL) { - if (bonename[0]) { - DEG_add_object_relation(node, object, DEG_OB_COMP_EVAL_POSE, "UVWarp Modifier"); - } - else { - DEG_add_object_relation(node, object, DEG_OB_COMP_TRANSFORM, "UVWarp Modifier"); - } - } -} - static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) { UVWarpModifierData *umd = (UVWarpModifierData *)md; - uv_warp_deps_object_bone_new(ctx->node, umd->object_src, umd->bone_src); - uv_warp_deps_object_bone_new(ctx->node, umd->object_dst, umd->bone_dst); + MOD_depsgraph_update_object_bone_relation( + ctx->node, umd->object_src, umd->bone_src, "UVWarp Modifier"); + MOD_depsgraph_update_object_bone_relation( + ctx->node, umd->object_dst, umd->bone_dst, "UVWarp Modifier"); DEG_add_modifier_to_transform_relation(ctx->node, "UVWarp Modifier"); } @@ -253,13 +253,16 @@ ModifierTypeInfo modifierType_UVWarp = { /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c index 7155498c942..458e2d0caea 100644 --- a/source/blender/modifiers/intern/MOD_warp.c +++ b/source/blender/modifiers/intern/MOD_warp.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ @@ -30,14 +30,15 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" +#include "BKE_action.h" /* BKE_pose_channel_find_name */ +#include "BKE_colortools.h" +#include "BKE_deform.h" #include "BKE_editmesh.h" -#include "BKE_library.h" -#include "BKE_library_query.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" #include "BKE_mesh.h" #include "BKE_modifier.h" -#include "BKE_deform.h" #include "BKE_texture.h" -#include "BKE_colortools.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" @@ -63,7 +64,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla const WarpModifierData *wmd = (const WarpModifierData *)md; WarpModifierData *twmd = (WarpModifierData *)target; - modifier_copyData_generic(md, target, flag); + BKE_modifier_copydata_generic(md, target, flag); twmd->curfalloff = BKE_curvemapping_copy(wmd->curfalloff); } @@ -85,6 +86,22 @@ static void requiredDataMask(Object *UNUSED(ob), } } +static void matrix_from_obj_pchan(float mat[4][4], + const float obinv[4][4], + Object *ob, + const char *bonename) +{ + bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bonename); + if (pchan) { + float mat_bone_world[4][4]; + mul_m4_m4m4(mat_bone_world, ob->obmat, pchan->pose_mat); + mul_m4_m4m4(mat, obinv, mat_bone_world); + } + else { + mul_m4_m4m4(mat, obinv, ob->obmat); + } +} + static bool dependsOnTime(ModifierData *md) { WarpModifierData *wmd = (WarpModifierData *)md; @@ -138,18 +155,31 @@ static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) { WarpModifierData *wmd = (WarpModifierData *)md; + bool need_transform_relation = false; + if (wmd->object_from != NULL && wmd->object_to != NULL) { - DEG_add_modifier_to_transform_relation(ctx->node, "Warplace Modifier"); - DEG_add_object_relation( - ctx->node, wmd->object_from, DEG_OB_COMP_TRANSFORM, "Warp Modifier from"); - DEG_add_object_relation(ctx->node, wmd->object_to, DEG_OB_COMP_TRANSFORM, "Warp Modifier to"); - } - if ((wmd->texmapping == MOD_DISP_MAP_OBJECT) && wmd->map_object != NULL) { - DEG_add_object_relation( - ctx->node, wmd->map_object, DEG_OB_COMP_TRANSFORM, "Warp Modifier map"); + MOD_depsgraph_update_object_bone_relation( + ctx->node, wmd->object_from, wmd->bone_from, "Warp Modifier"); + MOD_depsgraph_update_object_bone_relation( + ctx->node, wmd->object_to, wmd->bone_to, "Warp Modifier"); + need_transform_relation = true; } + if (wmd->texture != NULL) { DEG_add_generic_id_relation(ctx->node, &wmd->texture->id, "Warp Modifier"); + + if ((wmd->texmapping == MOD_DISP_MAP_OBJECT) && wmd->map_object != NULL) { + MOD_depsgraph_update_object_bone_relation( + ctx->node, wmd->map_object, wmd->map_bone, "Warp Modifier"); + need_transform_relation = true; + } + else if (wmd->texmapping == MOD_DISP_MAP_GLOBAL) { + need_transform_relation = true; + } + } + + if (need_transform_relation) { + DEG_add_modifier_to_transform_relation(ctx->node, "Warp Modifier"); } } @@ -169,13 +199,13 @@ static void warpModifier_do(WarpModifierData *wmd, float tmat[4][4]; - const float falloff_radius_sq = SQUARE(wmd->falloff_radius); + const float falloff_radius_sq = square_f(wmd->falloff_radius); float strength = wmd->strength; float fac = 1.0f, weight; int i; int defgrp_index; MDeformVert *dvert, *dv = NULL; - + const bool invert_vgroup = (wmd->flag & MOD_WARP_INVERT_VGROUP) != 0; float(*tex_co)[3] = NULL; if (!(wmd->object_from && wmd->object_to)) { @@ -197,8 +227,9 @@ static void warpModifier_do(WarpModifierData *wmd, invert_m4_m4(obinv, ob->obmat); - mul_m4_m4m4(mat_from, obinv, wmd->object_from->obmat); - mul_m4_m4m4(mat_to, obinv, wmd->object_to->obmat); + /* Checks that the objects/bones are available. */ + matrix_from_obj_pchan(mat_from, obinv, wmd->object_from, wmd->bone_from); + matrix_from_obj_pchan(mat_to, obinv, wmd->object_to, wmd->bone_to); invert_m4_m4(tmat, mat_from); // swap? mul_m4_m4m4(mat_final, tmat, mat_to); @@ -235,7 +266,8 @@ static void warpModifier_do(WarpModifierData *wmd, /* skip if no vert group found */ if (defgrp_index != -1) { dv = &dvert[i]; - weight = defvert_find_weight(dv, defgrp_index) * strength; + weight = invert_vgroup ? 1.0f - BKE_defvert_find_weight(dv, defgrp_index) * strength : + BKE_defvert_find_weight(dv, defgrp_index) * strength; if (weight <= 0.0f) { continue; } @@ -361,7 +393,7 @@ ModifierTypeInfo modifierType_Warp = { /* structName */ "WarpModifierData", /* structSize */ sizeof(WarpModifierData), /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice | + /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, /* copyData */ copyData, @@ -369,7 +401,10 @@ ModifierTypeInfo modifierType_Warp = { /* deformMatrices */ NULL, /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c index 908abeb6f76..fc4b65a7e5c 100644 --- a/source/blender/modifiers/intern/MOD_wave.c +++ b/source/blender/modifiers/intern/MOD_wave.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -32,8 +32,8 @@ #include "BKE_deform.h" #include "BKE_editmesh.h" -#include "BKE_library.h" -#include "BKE_library_query.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" #include "BKE_mesh.h" #include "BKE_scene.h" #include "BKE_texture.h" @@ -98,17 +98,28 @@ static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) { WaveModifierData *wmd = (WaveModifierData *)md; + bool need_transform_relation = false; + if (wmd->objectcenter != NULL) { DEG_add_object_relation(ctx->node, wmd->objectcenter, DEG_OB_COMP_TRANSFORM, "Wave Modifier"); + need_transform_relation = true; } - if (wmd->map_object != NULL) { - DEG_add_object_relation(ctx->node, wmd->map_object, DEG_OB_COMP_TRANSFORM, "Wave Modifier"); - } - if (wmd->objectcenter != NULL || wmd->map_object != NULL) { - DEG_add_modifier_to_transform_relation(ctx->node, "Wave Modifier"); - } + if (wmd->texture != NULL) { DEG_add_generic_id_relation(ctx->node, &wmd->texture->id, "Wave Modifier"); + + if ((wmd->texmapping == MOD_DISP_MAP_OBJECT) && wmd->map_object != NULL) { + MOD_depsgraph_update_object_bone_relation( + ctx->node, wmd->map_object, wmd->map_bone, "Wave Modifier"); + need_transform_relation = true; + } + else if (wmd->texmapping == MOD_DISP_MAP_GLOBAL) { + need_transform_relation = true; + } + } + + if (need_transform_relation) { + DEG_add_modifier_to_transform_relation(ctx->node, "Wave Modifier"); } } @@ -154,6 +165,7 @@ static void waveModifier_do(WaveModifierData *md, const int wmd_axis = wmd->flag & (MOD_WAVE_X | MOD_WAVE_Y); const float falloff = wmd->falloff; float falloff_fac = 1.0f; /* when falloff == 0.0f this stays at 1.0f */ + const bool invert_group = (wmd->flag & MOD_WAVE_INVERT_VGROUP) != 0; if ((wmd->flag & MOD_WAVE_NORM) && (mesh != NULL)) { mvert = mesh->mvert; @@ -213,7 +225,8 @@ static void waveModifier_do(WaveModifierData *md, /* get weights */ if (dvert) { - def_weight = defvert_find_weight(&dvert[i], defgrp_index); + def_weight = invert_group ? 1.0f - BKE_defvert_find_weight(&dvert[i], defgrp_index) : + BKE_defvert_find_weight(&dvert[i], defgrp_index); /* if this vert isn't in the vgroup, don't deform it */ if (def_weight == 0.0f) { @@ -352,16 +365,19 @@ ModifierTypeInfo modifierType_Wave = { /* structName */ "WaveModifierData", /* structSize */ sizeof(WaveModifierData), /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice | + /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ deformVerts, /* deformMatrices */ NULL, /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* modifyMesh */ NULL, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.c b/source/blender/modifiers/intern/MOD_weighted_normal.c index 0accbe607eb..3baf7c878dc 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.c +++ b/source/blender/modifiers/intern/MOD_weighted_normal.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ @@ -20,16 +20,17 @@ #include "MEM_guardedalloc.h" +#include "BLI_bitmap.h" #include "BLI_linklist.h" #include "BLI_math.h" #include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "BKE_cdderivedmesh.h" #include "BKE_deform.h" -#include "BKE_library.h" +#include "BKE_lib_id.h" #include "BKE_mesh.h" #include "MOD_modifiertypes.h" @@ -142,7 +143,7 @@ static void aggregate_item_normal(WeightedNormalModifierData *wnmd, const bool has_vgroup = dvert != NULL; const bool vert_of_group = has_vgroup && - defvert_find_index(&dvert[mv_index], defgrp_index) != NULL; + BKE_defvert_find_index(&dvert[mv_index], defgrp_index) != NULL; if (has_vgroup && ((vert_of_group && use_invert_vgroup) || (!vert_of_group && !use_invert_vgroup))) { @@ -360,7 +361,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, } else { /* TODO: Ideally, we could add an option to BKE_mesh_normals_loop_custom_[from_vertices_]set() - * to keep current clnors instead of resetting them to default autocomputed ones, + * to keep current clnors instead of resetting them to default auto-computed ones, * when given new custom normal is zero-vec. * But this is not exactly trivial change, better to keep this optimization for later... */ @@ -545,7 +546,7 @@ static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalD apply_weights_vertex_normal(wnmd, wn_data); } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { WeightedNormalModifierData *wnmd = (WeightedNormalModifierData *)md; Object *ob = ctx->object; @@ -561,7 +562,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes if (!(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH)) #endif { - modifier_setError((ModifierData *)wnmd, "Enable 'Auto Smooth' option in mesh settings"); + BKE_modifier_set_error((ModifierData *)wnmd, "Enable 'Auto Smooth' in Object Data Properties"); return mesh; } @@ -707,13 +708,16 @@ ModifierTypeInfo modifierType_WeightedNormal = { /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c index 4ff07b21ef4..5dae6bb8505 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.c +++ b/source/blender/modifiers/intern/MOD_weightvg_util.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2011 by Bastien Montagne. @@ -54,20 +54,22 @@ * mapping to the real vertex index (in case the weight tables do not cover the whole vertices...). * cmap might be NULL, in which case curve mapping mode will return unmodified data. */ -void weightvg_do_map(int num, float *new_w, short falloff_type, CurveMapping *cmap, RNG *rng) +void weightvg_do_map( + int num, float *new_w, short falloff_type, const bool do_invert, CurveMapping *cmap, RNG *rng) { int i; /* Return immediately, if we have nothing to do! */ /* Also security checks... */ - if (((falloff_type == MOD_WVG_MAPPING_CURVE) && (cmap == NULL)) || !ELEM(falloff_type, - MOD_WVG_MAPPING_CURVE, - MOD_WVG_MAPPING_SHARP, - MOD_WVG_MAPPING_SMOOTH, - MOD_WVG_MAPPING_ROOT, - MOD_WVG_MAPPING_SPHERE, - MOD_WVG_MAPPING_RANDOM, - MOD_WVG_MAPPING_STEP)) { + if (!do_invert && (((falloff_type == MOD_WVG_MAPPING_CURVE) && (cmap == NULL)) || + !ELEM(falloff_type, + MOD_WVG_MAPPING_CURVE, + MOD_WVG_MAPPING_SHARP, + MOD_WVG_MAPPING_SMOOTH, + MOD_WVG_MAPPING_ROOT, + MOD_WVG_MAPPING_SPHERE, + MOD_WVG_MAPPING_RANDOM, + MOD_WVG_MAPPING_STEP))) { return; } @@ -103,9 +105,14 @@ void weightvg_do_map(int num, float *new_w, short falloff_type, CurveMapping *cm case MOD_WVG_MAPPING_STEP: fac = (fac >= 0.5f) ? 1.0f : 0.0f; break; + case MOD_WVG_MAPPING_NONE: + BLI_assert(do_invert); + break; + default: + BLI_assert(0); } - new_w[i] = fac; + new_w[i] = do_invert ? 1.0f - fac : fac; } } @@ -130,7 +137,9 @@ void weightvg_do_mask(const ModifierEvalContext *ctx, const int tex_use_channel, const int tex_mapping, Object *tex_map_object, - const char *tex_uvlayer_name) + const char *text_map_bone, + const char *tex_uvlayer_name, + const bool invert_vgroup_mask) { int ref_didx; int i; @@ -155,6 +164,7 @@ void weightvg_do_mask(const ModifierEvalContext *ctx, */ t_map.texture = texture; t_map.map_object = tex_map_object; + BLI_strncpy(t_map.map_bone, text_map_bone, sizeof(t_map.map_bone)); BLI_strncpy(t_map.uvlayer_name, tex_uvlayer_name, sizeof(t_map.uvlayer_name)); t_map.texmapping = tex_mapping; @@ -211,7 +221,7 @@ void weightvg_do_mask(const ModifierEvalContext *ctx, MEM_freeN(tex_co); } - else if ((ref_didx = defgroup_name_index(ob, defgrp_name)) != -1) { + else if ((ref_didx = BKE_object_defgroup_name_index(ob, defgrp_name)) != -1) { MDeformVert *dvert = NULL; /* Check whether we want to set vgroup weights from a constant weight factor or a vertex @@ -230,7 +240,9 @@ void weightvg_do_mask(const ModifierEvalContext *ctx, /* For each weight (vertex), make the mix between org and new weights. */ for (i = 0; i < num; i++) { int idx = indices ? indices[i] : i; - const float f = defvert_find_weight(&dvert[idx], ref_didx) * fact; + const float f = invert_vgroup_mask ? + 1.0f - BKE_defvert_find_weight(&dvert[idx], ref_didx) * fact : + BKE_defvert_find_weight(&dvert[idx], ref_didx) * fact; org_w[i] = (new_w[i] * f) + (org_w[i] * (1.0f - f)); /* If that vertex is not in ref vgroup, assume null factor, and hence do nothing! */ } @@ -268,7 +280,7 @@ void weightvg_update_vg(MDeformVert *dvert, float w = weights[i]; MDeformVert *dv = &dvert[indices ? indices[i] : i]; MDeformWeight *dw = dws ? dws[i] : - ((defgrp_idx >= 0) ? defvert_find_index(dv, defgrp_idx) : NULL); + ((defgrp_idx >= 0) ? BKE_defvert_find_index(dv, defgrp_idx) : NULL); /* Never allow weights out of [0.0, 1.0] range. */ CLAMP(w, 0.0f, 1.0f); @@ -276,7 +288,7 @@ void weightvg_update_vg(MDeformVert *dvert, /* If the vertex is in this vgroup, remove it if needed, or just update it. */ if (dw != NULL) { if (do_rem && w < rem_thresh) { - defvert_remove_group(dv, dw); + BKE_defvert_remove_group(dv, dw); } else { dw->weight = w; @@ -284,7 +296,7 @@ void weightvg_update_vg(MDeformVert *dvert, } /* Else, add it if needed! */ else if (do_add && w > add_thresh) { - defvert_add_index_notest(dv, defgrp_idx, w); + BKE_defvert_add_index_notest(dv, defgrp_idx, w); } } } diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.h b/source/blender/modifiers/intern/MOD_weightvg_util.h index 08967b7400d..09a6a1afb3e 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.h +++ b/source/blender/modifiers/intern/MOD_weightvg_util.h @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2011 by Bastien Montagne. @@ -52,8 +52,12 @@ struct Tex; */ #define MOD_WVG_ZEROFLOOR 1.0e-32f -void weightvg_do_map( - int num, float *new_w, short mode, struct CurveMapping *cmap, struct RNG *rng); +void weightvg_do_map(int num, + float *new_w, + short mode, + const bool do_invert, + struct CurveMapping *cmap, + struct RNG *rng); void weightvg_do_mask(const ModifierEvalContext *ctx, const int num, @@ -69,7 +73,9 @@ void weightvg_do_mask(const ModifierEvalContext *ctx, const int tex_use_channel, const int tex_mapping, Object *tex_map_object, - const char *tex_uvlayer_name); + const char *text_map_bone, + const char *tex_uvlayer_name, + const bool invert_vgroup_mask); void weightvg_update_vg(struct MDeformVert *dvert, int defgrp_idx, diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c index 045ba78fab5..1ff8dfbdcca 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.c +++ b/source/blender/modifiers/intern/MOD_weightvgedit.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2011 by Bastien Montagne. @@ -35,7 +35,7 @@ #include "BKE_colortools.h" /* CurveMapping. */ #include "BKE_deform.h" -#include "BKE_library_query.h" +#include "BKE_lib_query.h" #include "BKE_modifier.h" #include "BKE_texture.h" /* Texture masking. */ @@ -44,8 +44,9 @@ #include "MEM_guardedalloc.h" -#include "MOD_weightvg_util.h" #include "MOD_modifiertypes.h" +#include "MOD_util.h" +#include "MOD_weightvg_util.h" /************************************** * Modifiers functions. * @@ -79,7 +80,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla const WeightVGEditModifierData *wmd = (const WeightVGEditModifierData *)md; WeightVGEditModifierData *twmd = (WeightVGEditModifierData *)target; - modifier_copyData_generic(md, target, flag); + BKE_modifier_copydata_generic(md, target, flag); twmd->cmap_curve = BKE_curvemapping_copy(wmd->cmap_curve); } @@ -134,16 +135,23 @@ static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) { WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md; - if (wmd->mask_tex_map_obj != NULL && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) { - DEG_add_object_relation( - ctx->node, wmd->mask_tex_map_obj, DEG_OB_COMP_TRANSFORM, "WeightVGEdit Modifier"); - DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGEdit Modifier"); - } - else if (wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL) { - DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGEdit Modifier"); - } + bool need_transform_relation = false; + if (wmd->mask_texture != NULL) { DEG_add_generic_id_relation(ctx->node, &wmd->mask_texture->id, "WeightVGEdit Modifier"); + + if (wmd->mask_tex_map_obj != NULL && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) { + MOD_depsgraph_update_object_bone_relation( + ctx->node, wmd->mask_tex_map_obj, wmd->mask_tex_map_bone, "WeightVGEdit Modifier"); + need_transform_relation = true; + } + else if (wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL) { + need_transform_relation = true; + } + } + + if (need_transform_relation) { + DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGEdit Modifier"); } } @@ -156,7 +164,7 @@ static bool isDisabled(const struct Scene *UNUSED(scene), return (wmd->defgrp_name[0] == '\0'); } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { BLI_assert(mesh != NULL); @@ -167,6 +175,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes float *org_w; /* Array original weights. */ float *new_w; /* Array new weights. */ int i; + const bool invert_vgroup_mask = (wmd->edit_flags & MOD_WVG_EDIT_INVERT_VGROUP_MASK) != 0; /* Flags. */ const bool do_add = (wmd->edit_flags & MOD_WVG_EDIT_ADD2VG) != 0; @@ -187,7 +196,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes } /* Get vgroup idx from its name. */ - const int defgrp_index = defgroup_name_index(ctx->object, wmd->defgrp_name); + const int defgrp_index = BKE_object_defgroup_name_index(ctx->object, wmd->defgrp_name); if (defgrp_index == -1) { return mesh; } @@ -219,7 +228,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes new_w = MEM_malloc_arrayN(numVerts, sizeof(float), "WeightVGEdit Modifier, new_w"); dw = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGEdit Modifier, dw"); for (i = 0; i < numVerts; i++) { - dw[i] = defvert_find_index(&dvert[i], defgrp_index); + dw[i] = BKE_defvert_find_index(&dvert[i], defgrp_index); if (dw[i]) { org_w[i] = new_w[i] = dw[i]->weight; } @@ -229,14 +238,15 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes } /* Do mapping. */ - if (wmd->falloff_type != MOD_WVG_MAPPING_NONE) { + const bool do_invert_mapping = (wmd->edit_flags & MOD_WVG_INVERT_FALLOFF) != 0; + if (do_invert_mapping || wmd->falloff_type != MOD_WVG_MAPPING_NONE) { RNG *rng = NULL; if (wmd->falloff_type == MOD_WVG_MAPPING_RANDOM) { rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ctx->object->id.name + 2)); } - weightvg_do_map(numVerts, new_w, wmd->falloff_type, wmd->cmap_curve, rng); + weightvg_do_map(numVerts, new_w, wmd->falloff_type, do_invert_mapping, wmd->cmap_curve, rng); if (rng) { BLI_rng_free(rng); @@ -259,7 +269,9 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes wmd->mask_tex_use_channel, wmd->mask_tex_mapping, wmd->mask_tex_map_obj, - wmd->mask_tex_uvlayer_name); + wmd->mask_tex_map_bone, + wmd->mask_tex_uvlayer_name, + invert_vgroup_mask); /* Update/add/remove from vgroup. */ weightvg_update_vg(dvert, @@ -303,7 +315,10 @@ ModifierTypeInfo modifierType_WeightVGEdit = { /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c index 368a6b46c7e..f1db8502d74 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.c +++ b/source/blender/modifiers/intern/MOD_weightvgmix.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2011 by Bastien Montagne. @@ -33,7 +33,7 @@ #include "BKE_customdata.h" #include "BKE_deform.h" -#include "BKE_library_query.h" +#include "BKE_lib_query.h" #include "BKE_modifier.h" #include "BKE_texture.h" /* Texture masking. */ @@ -42,8 +42,9 @@ #include "MEM_guardedalloc.h" -#include "MOD_weightvg_util.h" #include "MOD_modifiertypes.h" +#include "MOD_util.h" +#include "MOD_weightvg_util.h" /** * This mixes the old weight with the new weight factor. @@ -180,19 +181,23 @@ static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) { WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md; - if (wmd->mask_tex_map_obj != NULL && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) { - DEG_add_object_relation( - ctx->node, wmd->mask_tex_map_obj, DEG_OB_COMP_TRANSFORM, "WeightVGMix Modifier"); - DEG_add_object_relation( - ctx->node, wmd->mask_tex_map_obj, DEG_OB_COMP_GEOMETRY, "WeightVGMix Modifier"); + bool need_transform_relation = false; - DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGMix Modifier"); - } - else if (wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL) { - DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGMix Modifier"); - } if (wmd->mask_texture != NULL) { DEG_add_generic_id_relation(ctx->node, &wmd->mask_texture->id, "WeightVGMix Modifier"); + + if (wmd->mask_tex_map_obj != NULL && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) { + MOD_depsgraph_update_object_bone_relation( + ctx->node, wmd->mask_tex_map_obj, wmd->mask_tex_map_bone, "WeightVGMix Modifier"); + need_transform_relation = true; + } + else if (wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL) { + need_transform_relation = true; + } + } + + if (need_transform_relation) { + DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGMix Modifier"); } } @@ -205,7 +210,7 @@ static bool isDisabled(const struct Scene *UNUSED(scene), return (wmd->defgrp_name_a[0] == '\0'); } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { BLI_assert(mesh != NULL); @@ -218,6 +223,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes int *tidx, *indices = NULL; int numIdx = 0; int i; + const bool invert_vgroup_mask = (wmd->flag & MOD_WVG_MIX_INVERT_VGROUP_MASK) != 0; /* Flags. */ #if 0 const bool do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview) != 0; @@ -234,14 +240,14 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes } /* Get vgroup idx from its name. */ - const int defgrp_index = defgroup_name_index(ctx->object, wmd->defgrp_name_a); + const int defgrp_index = BKE_object_defgroup_name_index(ctx->object, wmd->defgrp_name_a); if (defgrp_index == -1) { return mesh; } /* Get second vgroup idx from its name, if given. */ int defgrp_index_other = -1; if (wmd->defgrp_name_b[0] != '\0') { - defgrp_index_other = defgroup_name_index(ctx->object, wmd->defgrp_name_b); + defgrp_index_other = BKE_object_defgroup_name_index(ctx->object, wmd->defgrp_name_b); if (defgrp_index_other == -1) { return mesh; } @@ -277,11 +283,11 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes case MOD_WVG_SET_A: /* All vertices in first vgroup. */ for (i = 0; i < numVerts; i++) { - MDeformWeight *dw = defvert_find_index(&dvert[i], defgrp_index); + MDeformWeight *dw = BKE_defvert_find_index(&dvert[i], defgrp_index); if (dw) { tdw1[numIdx] = dw; tdw2[numIdx] = (defgrp_index_other >= 0) ? - defvert_find_index(&dvert[i], defgrp_index_other) : + BKE_defvert_find_index(&dvert[i], defgrp_index_other) : NULL; tidx[numIdx++] = i; } @@ -291,10 +297,10 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes /* All vertices in second vgroup. */ for (i = 0; i < numVerts; i++) { MDeformWeight *dw = (defgrp_index_other >= 0) ? - defvert_find_index(&dvert[i], defgrp_index_other) : + BKE_defvert_find_index(&dvert[i], defgrp_index_other) : NULL; if (dw) { - tdw1[numIdx] = defvert_find_index(&dvert[i], defgrp_index); + tdw1[numIdx] = BKE_defvert_find_index(&dvert[i], defgrp_index); tdw2[numIdx] = dw; tidx[numIdx++] = i; } @@ -303,9 +309,9 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes case MOD_WVG_SET_OR: /* All vertices in one vgroup or the other. */ for (i = 0; i < numVerts; i++) { - MDeformWeight *adw = defvert_find_index(&dvert[i], defgrp_index); + MDeformWeight *adw = BKE_defvert_find_index(&dvert[i], defgrp_index); MDeformWeight *bdw = (defgrp_index_other >= 0) ? - defvert_find_index(&dvert[i], defgrp_index_other) : + BKE_defvert_find_index(&dvert[i], defgrp_index_other) : NULL; if (adw || bdw) { tdw1[numIdx] = adw; @@ -317,9 +323,9 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes case MOD_WVG_SET_AND: /* All vertices in both vgroups. */ for (i = 0; i < numVerts; i++) { - MDeformWeight *adw = defvert_find_index(&dvert[i], defgrp_index); + MDeformWeight *adw = BKE_defvert_find_index(&dvert[i], defgrp_index); MDeformWeight *bdw = (defgrp_index_other >= 0) ? - defvert_find_index(&dvert[i], defgrp_index_other) : + BKE_defvert_find_index(&dvert[i], defgrp_index_other) : NULL; if (adw && bdw) { tdw1[numIdx] = adw; @@ -332,9 +338,10 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes default: /* Use all vertices. */ for (i = 0; i < numVerts; i++) { - tdw1[i] = defvert_find_index(&dvert[i], defgrp_index); - tdw2[i] = (defgrp_index_other >= 0) ? defvert_find_index(&dvert[i], defgrp_index_other) : - NULL; + tdw1[i] = BKE_defvert_find_index(&dvert[i], defgrp_index); + tdw2[i] = (defgrp_index_other >= 0) ? + BKE_defvert_find_index(&dvert[i], defgrp_index_other) : + NULL; } numIdx = -1; break; @@ -393,7 +400,9 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes wmd->mask_tex_use_channel, wmd->mask_tex_mapping, wmd->mask_tex_map_obj, - wmd->mask_tex_uvlayer_name); + wmd->mask_tex_map_bone, + wmd->mask_tex_uvlayer_name, + invert_vgroup_mask); /* Update (add to) vgroup. * XXX Depending on the MOD_WVG_SET_xxx option chosen, we might have to add vertices to vgroup. @@ -427,13 +436,16 @@ ModifierTypeInfo modifierType_WeightVGMix = { /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_UsesPreview, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c index 553743272a2..3e746403050 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.c +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2011 by Bastien Montagne. @@ -38,8 +38,8 @@ #include "BKE_curve.h" #include "BKE_customdata.h" #include "BKE_deform.h" -#include "BKE_library.h" -#include "BKE_library_query.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_texture.h" /* Texture masking. */ @@ -49,9 +49,9 @@ #include "MEM_guardedalloc.h" -#include "MOD_weightvg_util.h" #include "MOD_modifiertypes.h" #include "MOD_util.h" +#include "MOD_weightvg_util.h" //#define USE_TIMEIT @@ -239,8 +239,13 @@ static float get_ob2ob_distance(const Object *ob, const Object *obr) /** * Maps distances to weights, with an optional "smoothing" mapping. */ -static void do_map( - Object *ob, float *weights, const int nidx, const float min_d, const float max_d, short mode) +static void do_map(Object *ob, + float *weights, + const int nidx, + const float min_d, + const float max_d, + short mode, + const bool do_invert_mapping) { const float range_inv = 1.0f / (max_d - min_d); /* invert since multiplication is faster */ uint i = nidx; @@ -276,14 +281,15 @@ static void do_map( } } - if (!ELEM(mode, MOD_WVG_MAPPING_NONE, MOD_WVG_MAPPING_CURVE)) { + BLI_assert(mode != MOD_WVG_MAPPING_CURVE); + if (do_invert_mapping || mode != MOD_WVG_MAPPING_NONE) { RNG *rng = NULL; if (mode == MOD_WVG_MAPPING_RANDOM) { rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ob->id.name + 2)); } - weightvg_do_map(nidx, weights, mode, NULL, rng); + weightvg_do_map(nidx, weights, mode, do_invert_mapping, NULL, rng); if (rng) { BLI_rng_free(rng); @@ -360,6 +366,8 @@ static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) { WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md; + bool need_transform_relation = false; + if (wmd->proximity_ob_target != NULL) { DEG_add_object_relation( ctx->node, wmd->proximity_ob_target, DEG_OB_COMP_TRANSFORM, "WeightVGProximity Modifier"); @@ -368,17 +376,25 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte DEG_add_object_relation( ctx->node, wmd->proximity_ob_target, DEG_OB_COMP_GEOMETRY, "WeightVGProximity Modifier"); } + need_transform_relation = true; } - if (wmd->mask_tex_map_obj != NULL && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) { - DEG_add_object_relation( - ctx->node, wmd->mask_tex_map_obj, DEG_OB_COMP_TRANSFORM, "WeightVGProximity Modifier"); - DEG_add_object_relation( - ctx->node, wmd->mask_tex_map_obj, DEG_OB_COMP_GEOMETRY, "WeightVGProximity Modifier"); - } + if (wmd->mask_texture != NULL) { DEG_add_generic_id_relation(ctx->node, &wmd->mask_texture->id, "WeightVGProximity Modifier"); + + if (wmd->mask_tex_map_obj != NULL && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) { + MOD_depsgraph_update_object_bone_relation( + ctx->node, wmd->mask_tex_map_obj, wmd->mask_tex_map_bone, "WeightVGProximity Modifier"); + need_transform_relation = true; + } + else if (wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL) { + need_transform_relation = true; + } + } + + if (need_transform_relation) { + DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGProximity Modifier"); } - DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGProximity Modifier"); } static bool isDisabled(const struct Scene *UNUSED(scene), @@ -394,7 +410,7 @@ static bool isDisabled(const struct Scene *UNUSED(scene), return (wmd->proximity_ob_target == NULL); } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { BLI_assert(mesh != NULL); @@ -411,6 +427,8 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes int *tidx, *indices = NULL; int numIdx = 0; int i; + const bool invert_vgroup_mask = (wmd->proximity_flags & MOD_WVG_PROXIMITY_INVERT_VGROUP_MASK) != + 0; /* Flags. */ #if 0 const bool do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview) != 0; @@ -437,7 +455,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes } /* Get vgroup idx from its name. */ - defgrp_index = defgroup_name_index(ob, wmd->defgrp_name); + defgrp_index = BKE_object_defgroup_name_index(ob, wmd->defgrp_name); if (defgrp_index == -1) { return mesh; } @@ -461,7 +479,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes tw = MEM_malloc_arrayN(numVerts, sizeof(float), "WeightVGProximity Modifier, tw"); tdw = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGProximity Modifier, tdw"); for (i = 0; i < numVerts; i++) { - MDeformWeight *_dw = defvert_find_index(&dvert[i], defgrp_index); + MDeformWeight *_dw = BKE_defvert_find_index(&dvert[i], defgrp_index); if (_dw) { tidx[numIdx] = i; tw[numIdx] = _dw->weight; @@ -557,7 +575,13 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes } /* Map distances to weights. */ - do_map(ob, new_w, numIdx, wmd->min_dist, wmd->max_dist, wmd->falloff_type); + do_map(ob, + new_w, + numIdx, + wmd->min_dist, + wmd->max_dist, + wmd->falloff_type, + (wmd->proximity_flags & MOD_WVG_PROXIMITY_INVERT_FALLOFF) != 0); /* Do masking. */ struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); @@ -575,7 +599,9 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes wmd->mask_tex_use_channel, wmd->mask_tex_mapping, wmd->mask_tex_map_obj, - wmd->mask_tex_uvlayer_name); + wmd->mask_tex_map_bone, + wmd->mask_tex_uvlayer_name, + invert_vgroup_mask); /* Update vgroup. Note we never add nor remove vertices from vgroup here. */ weightvg_update_vg(dvert, defgrp_index, dw, numIdx, indices, org_w, false, 0.0f, false, 0.0f); @@ -610,13 +636,16 @@ ModifierTypeInfo modifierType_WeightVGProximity = { /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_UsesPreview, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_weld.c b/source/blender/modifiers/intern/MOD_weld.c index f96ec9a82e5..e21410ad63d 100644 --- a/source/blender/modifiers/intern/MOD_weld.c +++ b/source/blender/modifiers/intern/MOD_weld.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2005 by the Blender Foundation. @@ -37,15 +37,18 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" #include "DNA_object_types.h" -#include "BKE_deform.h" #include "BKE_bvhutils.h" -#include "BKE_modifier.h" +#include "BKE_deform.h" #include "BKE_mesh.h" +#include "BKE_modifier.h" #include "DEG_depsgraph.h" +#include "MOD_modifiertypes.h" + //#define USE_WELD_DEBUG //#define USE_WELD_NORMALS @@ -798,6 +801,33 @@ static bool weld_iter_loop_of_poly_begin(WeldLoopOfPolyIter *iter, iter->loop_map = loop_map; iter->group = group_buffer; + uint group_len = 0; + if (group_buffer) { + /* First loop group needs more attention. */ + uint loop_start, loop_end, l; + loop_start = iter->loop_start; + loop_end = l = iter->loop_end; + while (l >= loop_start) { + const uint loop_ctx = loop_map[l]; + if (loop_ctx != OUT_OF_CONTEXT) { + const WeldLoop *wl = &wloop[loop_ctx]; + if (wl->flag == ELEM_COLLAPSED) { + l--; + continue; + } + } + break; + } + if (l != loop_end) { + group_len = loop_end - l; + int i = 0; + while (l < loop_end) { + iter->group[i++] = ++l; + } + } + } + iter->group_len = group_len; + iter->l_next = iter->loop_start; #ifdef USE_WELD_DEBUG iter->v = OUT_OF_CONTEXT; @@ -810,8 +840,13 @@ static bool weld_iter_loop_of_poly_next(WeldLoopOfPolyIter *iter) uint loop_end = iter->loop_end; const WeldLoop *wloop = iter->wloop; const uint *loop_map = iter->loop_map; - iter->group_len = 0; uint l = iter->l_curr = iter->l_next; + if (l == iter->loop_start) { + /* `grupo_len` is already calculated in the first loop */ + } + else { + iter->group_len = 0; + } while (l <= loop_end) { uint l_next = l + 1; const uint loop_ctx = loop_map[l]; @@ -822,20 +857,6 @@ static bool weld_iter_loop_of_poly_next(WeldLoopOfPolyIter *iter) } if (wl->flag == ELEM_COLLAPSED) { if (iter->group) { - if (l == iter->loop_start) { - uint l_prev = loop_end; - const uint loop_ctx_end = loop_map[l_prev]; - if (loop_ctx_end != OUT_OF_CONTEXT) { - const WeldLoop *wl_prev = &wloop[loop_ctx_end]; - while (wl_prev->flag == ELEM_COLLAPSED) { - iter->group[iter->group_len++] = l_prev--; - wl_prev--; - if (wl_prev->loop_orig != l_prev) { - break; - } - } - } - } iter->group[iter->group_len++] = l; } l = l_next; @@ -1468,6 +1489,8 @@ static void customdata_weld( return; } + CustomData_interp(source, dest, (const int *)src_indices, NULL, NULL, count, dest_index); + int src_i, dest_i; int j; @@ -1500,16 +1523,7 @@ static void customdata_weld( if (dest->layers[dest_i].type == type) { void *src_data = source->layers[src_i].data; - if (CustomData_layer_has_math(dest, dest_i)) { - const int size = CustomData_sizeof(type); - void *dst_data = dest->layers[dest_i].data; - void *v_dst = POINTER_OFFSET(dst_data, (size_t)dest_index * size); - for (j = 0; j < count; j++) { - CustomData_data_add( - type, v_dst, POINTER_OFFSET(src_data, (size_t)src_indices[j] * size)); - } - } - else if (type == CD_MVERT) { + if (type == CD_MVERT) { for (j = 0; j < count; j++) { MVert *mv_src = &((MVert *)src_data)[src_indices[j]]; add_v3_v3(co, mv_src->co); @@ -1531,6 +1545,19 @@ static void customdata_weld( flag |= me_src->flag; } } + else if (CustomData_layer_has_interp(dest, dest_i)) { + /* Already calculated. + * TODO: Optimize by exposing `typeInfo->interp`. */ + } + else if (CustomData_layer_has_math(dest, dest_i)) { + const int size = CustomData_sizeof(type); + void *dst_data = dest->layers[dest_i].data; + void *v_dst = POINTER_OFFSET(dst_data, (size_t)dest_index * size); + for (j = 0; j < count; j++) { + CustomData_data_add( + type, v_dst, POINTER_OFFSET(src_data, (size_t)src_indices[j] * size)); + } + } else { CustomData_copy_layer_type_data(source, dest, type, src_indices[0], dest_index, 1); } @@ -1548,13 +1575,7 @@ static void customdata_weld( for (dest_i = 0; dest_i < dest->totlayer; dest_i++) { CustomDataLayer *layer_dst = &dest->layers[dest_i]; const int type = layer_dst->type; - if (CustomData_layer_has_math(dest, dest_i)) { - const int size = CustomData_sizeof(type); - void *dst_data = layer_dst->data; - void *v_dst = POINTER_OFFSET(dst_data, (size_t)dest_index * size); - CustomData_data_multiply(type, v_dst, fac); - } - else if (type == CD_MVERT) { + if (type == CD_MVERT) { MVert *mv = &((MVert *)layer_dst->data)[dest_index]; mul_v3_fl(co, fac); bweight *= fac; @@ -1583,6 +1604,15 @@ static void customdata_weld( me->bweight = (char)bweight; me->flag = flag; } + else if (CustomData_layer_has_interp(dest, dest_i)) { + /* Already calculated. */ + } + else if (CustomData_layer_has_math(dest, dest_i)) { + const int size = CustomData_sizeof(type); + void *dst_data = layer_dst->data; + void *v_dst = POINTER_OFFSET(dst_data, (size_t)dest_index * size); + CustomData_data_multiply(type, v_dst, fac); + } } } @@ -1626,16 +1656,17 @@ static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContex totvert = mesh->totvert; /* Vertex Group. */ - const int defgrp_index = defgroup_name_index(ob, wmd->defgrp_name); + const int defgrp_index = BKE_object_defgroup_name_index(ob, wmd->defgrp_name); if (defgrp_index != -1) { MDeformVert *dvert, *dv; dvert = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT); if (dvert) { + const bool invert_vgroup = (wmd->flag & MOD_WELD_INVERT_VGROUP) != 0; dv = &dvert[0]; v_mask = BLI_BITMAP_NEW(totvert, __func__); for (i = 0; i < totvert; i++, dv++) { - const bool found = defvert_find_weight(dv, defgrp_index) > 0.0f; - if (found) { + const bool found = BKE_defvert_find_weight(dv, defgrp_index) > 0.0f; + if (found != invert_vgroup) { BLI_BITMAP_ENABLE(v_mask, i); v_mask_act++; } @@ -1659,7 +1690,7 @@ static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContex struct WeldOverlapData data; data.mvert = mvert; - data.merge_dist_sq = SQUARE(wmd->merge_dist); + data.merge_dist_sq = square_f(wmd->merge_dist); uint overlap_len; BVHTreeOverlap *overlap = BLI_bvhtree_overlap_ex(bvhtree, @@ -1871,7 +1902,7 @@ static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContex return result; } -static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { WeldModifierData *wmd = (WeldModifierData *)md; return weldModifier_doWeld(wmd, ctx, mesh); @@ -1886,6 +1917,18 @@ static void initData(ModifierData *md) wmd->defgrp_name[0] = '\0'; } +static void requiredDataMask(Object *UNUSED(ob), + ModifierData *md, + CustomData_MeshMasks *r_cddata_masks) +{ + WeldModifierData *wmd = (WeldModifierData *)md; + + /* Ask for vertexgroups if we need them. */ + if (wmd->defgrp_name[0] != '\0') { + r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; + } +} + ModifierTypeInfo modifierType_Weld = { /* name */ "Weld", /* structName */ "WeldModifierData", @@ -1895,16 +1938,19 @@ ModifierTypeInfo modifierType_Weld = { eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode | eModifierTypeFlag_AcceptsCVs, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, - /* requiredDataMask */ NULL, + /* requiredDataMask */ requiredDataMask, /* freeData */ NULL, /* isDisabled */ NULL, /* updateDepsgraph */ NULL, diff --git a/source/blender/modifiers/intern/MOD_wireframe.c b/source/blender/modifiers/intern/MOD_wireframe.c index 3dd6e00c3a5..4e2e97a2b8b 100644 --- a/source/blender/modifiers/intern/MOD_wireframe.c +++ b/source/blender/modifiers/intern/MOD_wireframe.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ @@ -61,7 +61,7 @@ static Mesh *WireframeModifier_do(WireframeModifierData *wmd, Object *ob, Mesh * Mesh *result; BMesh *bm; - const int defgrp_index = defgroup_name_index(ob, wmd->defgrp_name); + const int defgrp_index = BKE_object_defgroup_name_index(ob, wmd->defgrp_name); bm = BKE_mesh_to_bmesh_ex(mesh, &(struct BMeshCreateParams){0}, @@ -99,9 +99,7 @@ static Mesh *WireframeModifier_do(WireframeModifierData *wmd, Object *ob, Mesh * return result; } -static Mesh *applyModifier(ModifierData *md, - const struct ModifierEvalContext *ctx, - struct Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const struct ModifierEvalContext *ctx, struct Mesh *mesh) { return WireframeModifier_do((WireframeModifierData *)md, ctx->object, mesh); } @@ -113,13 +111,16 @@ ModifierTypeInfo modifierType_Wireframe = { /* type */ eModifierTypeType_Constructive, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, - /* copyData */ modifier_copyData_generic, + /* copyData */ BKE_modifier_copydata_generic, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* modifyMesh */ modifyMesh, + /* modifyHair */ NULL, + /* modifyPointCloud */ NULL, + /* modifyVolume */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, |