Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey@blender.org>2020-11-12 11:26:20 +0300
committerSergey Sharybin <sergey@blender.org>2020-11-12 11:26:20 +0300
commitde6cee4fc1913982b0b2bd786bfd813c935bbe73 (patch)
treea726c0c63bbd1d6c47c90c32119ce14c8048cddc /source/blender/modifiers/intern
parente4d432500a0e2f978fe019da43deb843da405032 (diff)
parent88bb29dea668df8cc46aa7f55895f229748bdbb4 (diff)
Merge branch 'master' into codesign_error_tracker
Diffstat (limited to 'source/blender/modifiers/intern')
-rw-r--r--source/blender/modifiers/intern/MOD_armature.c16
-rw-r--r--source/blender/modifiers/intern/MOD_array.c40
-rw-r--r--source/blender/modifiers/intern/MOD_bevel.c26
-rw-r--r--source/blender/modifiers/intern/MOD_boolean.c670
-rw-r--r--source/blender/modifiers/intern/MOD_build.c9
-rw-r--r--source/blender/modifiers/intern/MOD_cast.c22
-rw-r--r--source/blender/modifiers/intern/MOD_cloth.c22
-rw-r--r--source/blender/modifiers/intern/MOD_collision.c19
-rw-r--r--source/blender/modifiers/intern/MOD_correctivesmooth.c31
-rw-r--r--source/blender/modifiers/intern/MOD_curve.c14
-rw-r--r--source/blender/modifiers/intern/MOD_datatransfer.c31
-rw-r--r--source/blender/modifiers/intern/MOD_decimate.c21
-rw-r--r--source/blender/modifiers/intern/MOD_displace.c24
-rw-r--r--source/blender/modifiers/intern/MOD_dynamicpaint.c11
-rw-r--r--source/blender/modifiers/intern/MOD_edgesplit.c10
-rw-r--r--source/blender/modifiers/intern/MOD_explode.c9
-rw-r--r--source/blender/modifiers/intern/MOD_fluid.c3
-rw-r--r--source/blender/modifiers/intern/MOD_hook.c25
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciandeform.c32
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciansmooth.c16
-rw-r--r--source/blender/modifiers/intern/MOD_lattice.c15
-rw-r--r--source/blender/modifiers/intern/MOD_mask.cc57
-rw-r--r--source/blender/modifiers/intern/MOD_mesh_to_volume.cc315
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache.c23
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_pc2.c2
-rw-r--r--source/blender/modifiers/intern/MOD_meshdeform.c24
-rw-r--r--source/blender/modifiers/intern/MOD_meshsequencecache.c29
-rw-r--r--source/blender/modifiers/intern/MOD_mirror.c16
-rw-r--r--source/blender/modifiers/intern/MOD_multires.c28
-rw-r--r--source/blender/modifiers/intern/MOD_none.c7
-rw-r--r--source/blender/modifiers/intern/MOD_normal_edit.c33
-rw-r--r--source/blender/modifiers/intern/MOD_ocean.c49
-rw-r--r--source/blender/modifiers/intern/MOD_particleinstance.c24
-rw-r--r--source/blender/modifiers/intern/MOD_particlesystem.c13
-rw-r--r--source/blender/modifiers/intern/MOD_remesh.c16
-rw-r--r--source/blender/modifiers/intern/MOD_screw.c34
-rw-r--r--source/blender/modifiers/intern/MOD_shapekey.c7
-rw-r--r--source/blender/modifiers/intern/MOD_shrinkwrap.c20
-rw-r--r--source/blender/modifiers/intern/MOD_simpledeform.c19
-rw-r--r--source/blender/modifiers/intern/MOD_simulation.cc104
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c64
-rw-r--r--source/blender/modifiers/intern/MOD_smooth.c11
-rw-r--r--source/blender/modifiers/intern/MOD_softbody.c3
-rw-r--r--source/blender/modifiers/intern/MOD_solidify.c29
-rw-r--r--source/blender/modifiers/intern/MOD_solidify_extrude.c34
-rw-r--r--source/blender/modifiers/intern/MOD_solidify_nonmanifold.c167
-rw-r--r--source/blender/modifiers/intern/MOD_subsurf.c53
-rw-r--r--source/blender/modifiers/intern/MOD_surface.c13
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c164
-rw-r--r--source/blender/modifiers/intern/MOD_triangulate.c13
-rw-r--r--source/blender/modifiers/intern/MOD_ui_common.c29
-rw-r--r--source/blender/modifiers/intern/MOD_ui_common.h2
-rw-r--r--source/blender/modifiers/intern/MOD_util.c11
-rw-r--r--source/blender/modifiers/intern/MOD_uvproject.c27
-rw-r--r--source/blender/modifiers/intern/MOD_uvwarp.c20
-rw-r--r--source/blender/modifiers/intern/MOD_volume_displace.cc348
-rw-r--r--source/blender/modifiers/intern/MOD_volume_to_mesh.cc355
-rw-r--r--source/blender/modifiers/intern/MOD_warp.c34
-rw-r--r--source/blender/modifiers/intern/MOD_wave.c41
-rw-r--r--source/blender/modifiers/intern/MOD_weighted_normal.c19
-rw-r--r--source/blender/modifiers/intern/MOD_weightvg_util.c9
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgedit.c29
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgmix.c22
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgproximity.c31
-rw-r--r--source/blender/modifiers/intern/MOD_weld.c280
-rw-r--r--source/blender/modifiers/intern/MOD_wireframe.c11
66 files changed, 2560 insertions, 1145 deletions
diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c
index f42f67417c3..38fb19e3233 100644
--- a/source/blender/modifiers/intern/MOD_armature.c
+++ b/source/blender/modifiers/intern/MOD_armature.c
@@ -29,6 +29,7 @@
#include "BLT_translation.h"
#include "DNA_armature_types.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
@@ -65,7 +66,9 @@ static void initData(ModifierData *md)
{
ArmatureModifierData *amd = (ArmatureModifierData *)md;
- amd->deformflag = ARM_DEF_VGROUP;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(amd, modifier));
+
+ MEMCPY_STRUCT_AFTER(amd, DNA_struct_default_get(ArmatureModifierData), modifier);
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
@@ -101,11 +104,11 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
return !amd->object || amd->object->type != OB_ARMATURE;
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
ArmatureModifierData *amd = (ArmatureModifierData *)md;
- walk(userData, ob, &amd->object, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&amd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
@@ -255,7 +258,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(col, ptr, "use_deform_preserve_volume", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "use_multi_modifier", 0, NULL, ICON_NONE);
- col = uiLayoutColumnWithHeading(layout, true, IFACE_("Bind to"));
+ col = uiLayoutColumnWithHeading(layout, true, IFACE_("Bind To"));
uiItemR(col, ptr, "use_vertex_groups", 0, IFACE_("Vertex Groups"), ICON_NONE);
uiItemR(col, ptr, "use_bone_envelopes", 0, IFACE_("Bone Envelopes"), ICON_NONE);
@@ -278,9 +281,11 @@ ModifierTypeInfo modifierType_Armature = {
/* name */ "Armature",
/* structName */ "ArmatureModifierData",
/* structSize */ sizeof(ArmatureModifierData),
+ /* srna */ &RNA_ArmatureModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly |
eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_MOD_ARMATURE,
/* copyData */ copyData,
@@ -300,8 +305,7 @@ ModifierTypeInfo modifierType_Armature = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
/* panelRegister */ panelRegister,
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index 60e1a3de67e..da1754b8ebd 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -32,6 +32,7 @@
#include "BLT_translation.h"
#include "DNA_curve_types.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -63,32 +64,22 @@ static void initData(ModifierData *md)
{
ArrayModifierData *amd = (ArrayModifierData *)md;
- /* default to 2 duplicates distributed along the x-axis by an
- * offset of 1 object-width
- */
- amd->start_cap = amd->end_cap = amd->curve_ob = amd->offset_ob = NULL;
- amd->count = 2;
- zero_v3(amd->offset);
- amd->scale[0] = 1;
- amd->scale[1] = amd->scale[2] = 0;
- amd->length = 0;
- amd->merge_dist = 0.01;
- amd->fit_type = MOD_ARR_FIXEDCOUNT;
- amd->offset_type = MOD_ARR_OFF_RELATIVE;
- amd->flags = 0;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(amd, modifier));
+
+ MEMCPY_STRUCT_AFTER(amd, DNA_struct_default_get(ArrayModifierData), modifier);
/* Open the first subpanel by default, it corresspnds to Relative offset which is enabled too. */
- md->ui_expand_flag = (1 << 0) | (1 << 1);
+ md->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT | UI_SUBPANEL_DATA_EXPAND_1;
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
ArrayModifierData *amd = (ArrayModifierData *)md;
- walk(userData, ob, &amd->start_cap, IDWALK_CB_NOP);
- walk(userData, ob, &amd->end_cap, IDWALK_CB_NOP);
- walk(userData, ob, &amd->curve_ob, IDWALK_CB_NOP);
- walk(userData, ob, &amd->offset_ob, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&amd->start_cap, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&amd->end_cap, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&amd->curve_ob, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&amd->offset_ob, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
@@ -490,7 +481,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
/* 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) {
+ if (ELEM(amd->fit_type, MOD_ARR_FITLENGTH, MOD_ARR_FITCURVE)) {
const float float_epsilon = 1e-6f;
bool offset_is_too_small = false;
float dist = len_v3(offset[3]);
@@ -517,6 +508,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
if (offset_is_too_small) {
BKE_modifier_set_error(
+ ctx->object,
&amd->modifier,
"The offset is too small, we cannot generate the amount of geometry it would require");
}
@@ -527,7 +519,8 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
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,
+ BKE_modifier_set_error(ctx->object,
+ &amd->modifier,
"The amount of copies is too high, we cannot generate the amount of "
"geometry it would require");
}
@@ -1010,10 +1003,12 @@ ModifierTypeInfo modifierType_Array = {
/* name */ "Array",
/* structName */ "ArrayModifierData",
/* structSize */ sizeof(ArrayModifierData),
+ /* srna */ &RNA_ArrayModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode |
eModifierTypeFlag_AcceptsCVs,
+ /* icon */ ICON_MOD_ARRAY,
/* copyData */ BKE_modifier_copydata_generic,
@@ -1033,8 +1028,7 @@ ModifierTypeInfo modifierType_Array = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
/* panelRegister */ panelRegister,
diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c
index ab024bd824d..04ddac338e5 100644
--- a/source/blender/modifiers/intern/MOD_bevel.c
+++ b/source/blender/modifiers/intern/MOD_bevel.c
@@ -30,6 +30,7 @@
#include "BLT_translation.h"
#include "DNA_curveprofile_types.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -63,22 +64,10 @@ static void initData(ModifierData *md)
{
BevelModifierData *bmd = (BevelModifierData *)md;
- bmd->value = 0.1f;
- bmd->res = 1;
- bmd->flags = 0;
- bmd->val_flags = MOD_BEVEL_AMT_OFFSET;
- bmd->lim_flags = 0;
- bmd->e_flags = 0;
- bmd->edge_flags = 0;
- bmd->face_str_mode = MOD_BEVEL_FACE_STRENGTH_NONE;
- bmd->miter_inner = MOD_BEVEL_MITER_SHARP;
- bmd->miter_outer = MOD_BEVEL_MITER_SHARP;
- bmd->affect_type = MOD_BEVEL_AFFECT_EDGES;
- bmd->spread = 0.1f;
- bmd->mat = -1;
- bmd->profile = 0.5f;
- bmd->bevel_angle = DEG2RADF(30.0f);
- bmd->defgrp_name[0] = '\0';
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(bmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(bmd, DNA_struct_default_get(BevelModifierData), modifier);
+
bmd->custom_profile = BKE_curveprofile_add(PROF_PRESET_LINE);
}
@@ -219,7 +208,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
Object *ob = ctx->object;
if (harden_normals && (ob->type == OB_MESH) && !(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH)) {
- BKE_modifier_set_error(md, "Enable 'Auto Smooth' in Object Data Properties");
+ BKE_modifier_set_error(ob, md, "Enable 'Auto Smooth' in Object Data Properties");
harden_normals = false;
}
@@ -446,9 +435,11 @@ ModifierTypeInfo modifierType_Bevel = {
/* name */ "Bevel",
/* structName */ "BevelModifierData",
/* structSize */ sizeof(BevelModifierData),
+ /* srna */ &RNA_BevelModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode |
eModifierTypeFlag_EnableInEditmode | eModifierTypeFlag_AcceptsCVs,
+ /* icon */ ICON_MOD_BEVEL,
/* copyData */ copyData,
/* deformVerts */ NULL,
/* deformMatrices */ NULL,
@@ -465,7 +456,6 @@ ModifierTypeInfo modifierType_Bevel = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c
index bef7d5d8e4f..7fea06ba955 100644
--- a/source/blender/modifiers/intern/MOD_boolean.c
+++ b/source/blender/modifiers/intern/MOD_boolean.c
@@ -28,16 +28,21 @@
#include "BLI_utildefines.h"
#include "BLI_alloca.h"
+#include "BLI_array.h"
#include "BLI_math_geom.h"
#include "BLI_math_matrix.h"
#include "BLT_translation.h"
+#include "DNA_collection_types.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
+#include "BKE_collection.h"
#include "BKE_context.h"
#include "BKE_global.h" /* only to check G.debug */
#include "BKE_lib_id.h"
@@ -65,6 +70,7 @@
#include "tools/bmesh_boolean.h"
#include "tools/bmesh_intersect.h"
+// #define DEBUG_TIME
#ifdef DEBUG_TIME
# include "PIL_time.h"
# include "PIL_time_utildefines.h"
@@ -74,10 +80,9 @@ static void initData(ModifierData *md)
{
BooleanModifierData *bmd = (BooleanModifierData *)md;
- bmd->double_threshold = 1e-6f;
- bmd->operation = eBooleanModifierOp_Difference;
- bmd->solver = eBooleanModifierSolver_Exact;
- bmd->flag = 0;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(bmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(bmd, DNA_struct_default_get(BooleanModifierData), modifier);
}
static bool isDisabled(const struct Scene *UNUSED(scene),
@@ -85,39 +90,55 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
bool UNUSED(useRenderParams))
{
BooleanModifierData *bmd = (BooleanModifierData *)md;
+ Collection *col = bmd->collection;
- /* The object type check is only needed here in case we have a placeholder
- * object assigned (because the library containing the mesh is missing).
- *
- * In other cases it should be impossible to have a type mismatch.
- */
- return !bmd->object || bmd->object->type != OB_MESH;
+ if (bmd->flag & eBooleanModifierFlag_Object) {
+ return !bmd->object || bmd->object->type != OB_MESH;
+ }
+ if (bmd->flag & eBooleanModifierFlag_Collection) {
+ /* The Exact solver tolerates an empty collection. */
+ return !col && bmd->solver != eBooleanModifierSolver_Exact;
+ }
+ return false;
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
BooleanModifierData *bmd = (BooleanModifierData *)md;
- walk(userData, ob, &bmd->object, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&bmd->collection, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&bmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
BooleanModifierData *bmd = (BooleanModifierData *)md;
- if (bmd->object != NULL) {
+ if ((bmd->flag & eBooleanModifierFlag_Object) && bmd->object != NULL) {
DEG_add_object_relation(ctx->node, bmd->object, DEG_OB_COMP_TRANSFORM, "Boolean Modifier");
DEG_add_object_relation(ctx->node, bmd->object, DEG_OB_COMP_GEOMETRY, "Boolean Modifier");
}
+
+ Collection *col = bmd->collection;
+
+ if ((bmd->flag & eBooleanModifierFlag_Collection) && col != NULL) {
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (col, operand_ob) {
+ if (operand_ob->type == OB_MESH && operand_ob != ctx->object) {
+ DEG_add_object_relation(ctx->node, operand_ob, DEG_OB_COMP_TRANSFORM, "Boolean Modifier");
+ DEG_add_object_relation(ctx->node, operand_ob, DEG_OB_COMP_GEOMETRY, "Boolean Modifier");
+ }
+ }
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+ }
/* We need own transformation as well. */
DEG_add_modifier_to_transform_relation(ctx->node, "Boolean Modifier");
}
static Mesh *get_quick_mesh(
- Object *ob_self, Mesh *mesh_self, Object *ob_other, Mesh *mesh_other, int operation)
+ Object *ob_self, Mesh *mesh_self, Object *ob_operand_ob, Mesh *mesh_operand_ob, int operation)
{
Mesh *result = NULL;
- if (mesh_self->totpoly == 0 || mesh_other->totpoly == 0) {
+ if (mesh_self->totpoly == 0 || mesh_operand_ob->totpoly == 0) {
switch (operation) {
case eBooleanModifierOp_Intersect:
result = BKE_mesh_new_nomain(0, 0, 0, 0, 0);
@@ -128,13 +149,13 @@ static Mesh *get_quick_mesh(
result = mesh_self;
}
else {
- BKE_id_copy_ex(NULL, &mesh_other->id, (ID **)&result, LIB_ID_COPY_LOCALIZE);
+ result = (Mesh *)BKE_id_copy_ex(NULL, &mesh_operand_ob->id, NULL, LIB_ID_COPY_LOCALIZE);
float imat[4][4];
float omat[4][4];
invert_m4_m4(imat, ob_self->obmat);
- mul_m4_m4m4(omat, imat, ob_other->obmat);
+ mul_m4_m4m4(omat, imat, ob_operand_ob->obmat);
const int mverts_len = result->totvert;
MVert *mv = result->mvert;
@@ -168,208 +189,489 @@ 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 *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
+static bool BMD_error_messages(const Object *ob, ModifierData *md, Collection *col)
{
BooleanModifierData *bmd = (BooleanModifierData *)md;
- Mesh *result = mesh;
- Mesh *mesh_other;
+ bool error_returns_result = false;
+
+ const bool operand_collection = (bmd->flag & eBooleanModifierFlag_Collection) != 0;
+ const bool use_exact = bmd->solver == eBooleanModifierSolver_Exact;
+ const bool operation_intersect = bmd->operation == eBooleanModifierOp_Intersect;
+
+#ifndef WITH_GMP
+ /* If compiled without GMP, return a error. */
+ if (use_exact) {
+ BKE_modifier_set_error(ob, md, "Compiled without GMP, using fast solver");
+ error_returns_result = false;
+ }
+#endif
+
+ /* If intersect is selected using fast solver, return a error. */
+ if (operand_collection && operation_intersect && !use_exact) {
+ BKE_modifier_set_error(ob, md, "Cannot execute, intersect only available using exact solver");
+ error_returns_result = true;
+ }
+
+ /* If the selected collection is empty and using fast solver, return a error. */
+ if (operand_collection) {
+ if (!use_exact && BKE_collection_is_empty(col)) {
+ BKE_modifier_set_error(ob, md, "Cannot execute, fast solver and empty collection");
+ error_returns_result = true;
+ }
- if (bmd->object == NULL) {
- return result;
+ /* If the selected collection contain non mesh objects, return a error. */
+ if (col) {
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (col, operand_ob) {
+ if (operand_ob->type != OB_MESH) {
+ BKE_modifier_set_error(
+ ob, md, "Cannot execute, the selected collection contains non mesh objects");
+ error_returns_result = true;
+ }
+ }
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+ }
}
- Object *other = bmd->object;
- mesh_other = BKE_modifier_get_evaluated_mesh_from_evaluated_object(other, false);
- if (mesh_other) {
- Object *object = ctx->object;
+ return error_returns_result;
+}
- /* XXX This is utterly non-optimal, we may go from a bmesh to a mesh back to a bmesh!
- * But for 2.90 better not try to be smart here. */
- BKE_mesh_wrapper_ensure_mdata(mesh_other);
+static BMesh *BMD_mesh_bm_create(
+ Mesh *mesh, Object *object, Mesh *mesh_operand_ob, Object *operand_ob, bool *r_is_flip)
+{
+ BMesh *bm;
- /* when one of objects is empty (has got no faces) we could speed up
- * calculation a bit returning one of objects' derived meshes (or empty one)
- * Returning mesh is depended on modifiers operation (sergey) */
- result = get_quick_mesh(object, mesh, other, mesh_other, bmd->operation);
+ *r_is_flip = (is_negative_m4(object->obmat) != is_negative_m4(operand_ob->obmat));
- if (result == NULL) {
- const bool is_flip = (is_negative_m4(object->obmat) != is_negative_m4(other->obmat));
+ const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh, mesh_operand_ob);
- BMesh *bm;
- const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh, mesh_other);
+ bm = BM_mesh_create(&allocsize,
+ &((struct BMeshCreateParams){
+ .use_toolflags = false,
+ }));
-#ifdef DEBUG_TIME
- TIMEIT_START(boolean_bmesh);
+ BM_mesh_bm_from_me(bm,
+ mesh_operand_ob,
+ &((struct BMeshFromMeshParams){
+ .calc_face_normal = true,
+ }));
+
+ if (UNLIKELY(*r_is_flip)) {
+ const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
+ BMIter iter;
+ BMFace *efa;
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ BM_face_normal_flip_ex(bm, efa, cd_loop_mdisp_offset, true);
+ }
+ }
+
+ BM_mesh_bm_from_me(bm,
+ mesh,
+ &((struct BMeshFromMeshParams){
+ .calc_face_normal = true,
+ }));
+
+ return bm;
+}
+
+static void BMD_mesh_intersection(BMesh *bm,
+ ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh_operand_ob,
+ Object *object,
+ Object *operand_ob,
+ bool is_flip)
+{
+ BooleanModifierData *bmd = (BooleanModifierData *)md;
+
+ /* main bmesh intersection setup */
+ /* create tessface & intersect */
+ const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop);
+ int tottri;
+ BMLoop *(*looptris)[3];
+
+ looptris = MEM_malloc_arrayN(looptris_tot, sizeof(*looptris), __func__);
+
+ BM_mesh_calc_tessellation_beauty(bm, looptris, &tottri);
+
+ /* postpone this until after tessellating
+ * so we can use the original normals before the vertex are moved */
+ {
+ BMIter iter;
+ int i;
+ const int i_verts_end = mesh_operand_ob->totvert;
+ const int i_faces_end = mesh_operand_ob->totpoly;
+
+ float imat[4][4];
+ float omat[4][4];
+
+ invert_m4_m4(imat, object->obmat);
+ mul_m4_m4m4(omat, imat, operand_ob->obmat);
+
+ BMVert *eve;
+ i = 0;
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ mul_m4_v3(omat, eve->co);
+ if (++i == i_verts_end) {
+ break;
+ }
+ }
+
+ /* we need face normals because of 'BM_face_split_edgenet'
+ * we could calculate on the fly too (before calling split). */
+ {
+ float nmat[3][3];
+ copy_m3_m4(nmat, omat);
+ invert_m3(nmat);
+
+ if (UNLIKELY(is_flip)) {
+ negate_m3(nmat);
+ }
+
+ const short ob_src_totcol = operand_ob->totcol;
+ short *material_remap = BLI_array_alloca(material_remap, ob_src_totcol ? ob_src_totcol : 1);
+
+ /* 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_object_material_remap_calc(ctx->object, operand_ob, material_remap);
+
+ BMFace *efa;
+ i = 0;
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ mul_transposed_m3_v3(nmat, efa->no);
+ normalize_v3(efa->no);
+
+ /* Temp tag to test which side split faces are from. */
+ BM_elem_flag_enable(efa, BM_FACE_TAG);
+
+ /* remap material */
+ if (LIKELY(efa->mat_nr < ob_src_totcol)) {
+ efa->mat_nr = material_remap[efa->mat_nr];
+ }
+
+ if (++i == i_faces_end) {
+ break;
+ }
+ }
+ }
+ }
+
+ /* not needed, but normals for 'dm' will be invalid,
+ * currently this is ok for 'BM_mesh_intersect' */
+ // BM_mesh_normals_update(bm);
+
+ bool use_separate = false;
+ bool use_dissolve = true;
+ bool use_island_connect = true;
+
+ /* change for testing */
+ if (G.debug & G_DEBUG) {
+ use_separate = (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_Separate) != 0;
+ use_dissolve = (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_NoDissolve) == 0;
+ use_island_connect = (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_NoConnectRegions) == 0;
+ }
+
+#ifdef WITH_GMP
+ const bool use_exact = bmd->solver == eBooleanModifierSolver_Exact;
+ const bool use_self = (bmd->flag & eBooleanModifierFlag_Self) != 0;
+#else
+ const bool use_exact = false;
+ const bool use_self = false;
#endif
- bm = BM_mesh_create(&allocsize,
- &((struct BMeshCreateParams){
- .use_toolflags = false,
- }));
- BM_mesh_bm_from_me(bm,
- mesh_other,
- &((struct BMeshFromMeshParams){
- .calc_face_normal = true,
- }));
+ if (use_exact) {
+ BM_mesh_boolean(
+ bm, looptris, tottri, bm_face_isect_pair, NULL, 2, use_self, false, bmd->operation);
+ }
+ else {
+ BM_mesh_intersect(bm,
+ looptris,
+ tottri,
+ bm_face_isect_pair,
+ NULL,
+ false,
+ use_separate,
+ use_dissolve,
+ use_island_connect,
+ false,
+ false,
+ bmd->operation,
+ bmd->double_threshold);
+ }
+ MEM_freeN(looptris);
+}
+static int bm_face_isect_nary(BMFace *f, void *user_data)
+{
+ int *shape = (int *)user_data;
+ return shape[BM_elem_index_get(f)];
+}
+
+/* The Exact solver can do all operands of a collection at once. */
+static Mesh *collection_boolean_exact(BooleanModifierData *bmd,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh)
+{
+ int i;
+ Mesh *result = mesh;
+ Collection *col = bmd->collection;
+ int num_shapes = 1;
+ Mesh **meshes = NULL;
+ Object **objects = NULL;
+ BLI_array_declare(meshes);
+ BLI_array_declare(objects);
+ BMAllocTemplate bat;
+ bat.totvert = mesh->totvert;
+ bat.totedge = mesh->totedge;
+ bat.totloop = mesh->totloop;
+ bat.totface = mesh->totpoly;
+ BLI_array_append(meshes, mesh);
+ BLI_array_append(objects, ctx->object);
+ Mesh *col_mesh;
+ /* Allow col to be empty: then target mesh will just remove self-intersections. */
+ if (col) {
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (col, ob) {
+ if (ob->type == OB_MESH && ob != ctx->object) {
+ col_mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob, false);
+ /* XXX This is utterly non-optimal, we may go from a bmesh to a mesh back to a bmesh!
+ * But for 2.90 better not try to be smart here. */
+ BKE_mesh_wrapper_ensure_mdata(col_mesh);
+ BLI_array_append(meshes, col_mesh);
+ BLI_array_append(objects, ob);
+ bat.totvert += col_mesh->totvert;
+ bat.totedge += col_mesh->totedge;
+ bat.totloop += col_mesh->totloop;
+ bat.totface += col_mesh->totpoly;
+ ++num_shapes;
+ }
+ }
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+ }
+ int *shape_face_end = MEM_mallocN(num_shapes * sizeof(int), __func__);
+ int *shape_vert_end = MEM_mallocN(num_shapes * sizeof(int), __func__);
+ bool is_neg_mat0 = is_negative_m4(ctx->object->obmat);
+ BMesh *bm = BM_mesh_create(&bat,
+ &((struct BMeshCreateParams){
+ .use_toolflags = false,
+ }));
+ for (i = 0; i < num_shapes; i++) {
+ Mesh *me = meshes[i];
+ Object *ob = objects[i];
+ /* Need normals for triangulation. */
+ BM_mesh_bm_from_me(bm,
+ me,
+ &((struct BMeshFromMeshParams){
+ .calc_face_normal = true,
+ }));
+ shape_face_end[i] = me->totpoly + (i == 0 ? 0 : shape_face_end[i - 1]);
+ shape_vert_end[i] = me->totvert + (i == 0 ? 0 : shape_vert_end[i - 1]);
+ if (i > 0) {
+ bool is_flip = (is_neg_mat0 != is_negative_m4(ob->obmat));
if (UNLIKELY(is_flip)) {
const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
BMIter iter;
BMFace *efa;
+ BM_mesh_elem_index_ensure(bm, BM_FACE);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- BM_face_normal_flip_ex(bm, efa, cd_loop_mdisp_offset, true);
+ if (BM_elem_index_get(efa) >= shape_face_end[i - 1]) {
+ BM_face_normal_flip_ex(bm, efa, cd_loop_mdisp_offset, true);
+ }
}
}
+ }
+ }
- BM_mesh_bm_from_me(bm,
- mesh,
- &((struct BMeshFromMeshParams){
- .calc_face_normal = true,
- }));
+ /* Triangulate the mesh. */
+ const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop);
+ int tottri;
+ BMLoop *(*looptris)[3];
+ looptris = MEM_malloc_arrayN(looptris_tot, sizeof(*looptris), __func__);
+ BM_mesh_calc_tessellation_beauty(bm, looptris, &tottri);
+
+ /* Move the vertices of all but the first shape into transformation space of first mesh.
+ * Do this after tesselation so don't need to recalculate normals.
+ * The Exact solver doesn't need normals on the input faces. */
+ float imat[4][4];
+ float omat[4][4];
+ invert_m4_m4(imat, ctx->object->obmat);
+ int curshape = 0;
+ int curshape_vert_end = shape_vert_end[0];
+ BMVert *eve;
+ BMIter iter;
+ i = 0;
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ if (i == curshape_vert_end) {
+ curshape++;
+ curshape_vert_end = shape_vert_end[curshape];
+ mul_m4_m4m4(omat, imat, objects[curshape]->obmat);
+ }
+ if (curshape > 0) {
+ mul_m4_v3(omat, eve->co);
+ }
+ i++;
+ }
- /* main bmesh intersection setup */
- {
- /* create tessface & intersect */
- const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop);
- int tottri;
- BMLoop *(*looptris)[3];
+ /* Remap the materials. Fill a shape array for test function. Calculate normals. */
+ int *shape = MEM_mallocN(bm->totface * sizeof(int), __func__);
+ curshape = 0;
+ int curshape_face_end = shape_face_end[0];
+ int curshape_ncol = ctx->object->totcol;
+ short *material_remap = NULL;
+ BMFace *efa;
+ i = 0;
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ if (i == curshape_face_end) {
+ curshape++;
+ curshape_face_end = shape_face_end[curshape];
+ if (material_remap != NULL) {
+ MEM_freeN(material_remap);
+ }
+ curshape_ncol = objects[curshape]->totcol;
+ material_remap = MEM_mallocN(curshape_ncol ? curshape_ncol : 1, __func__);
+ BKE_object_material_remap_calc(ctx->object, objects[curshape], material_remap);
+ }
+ shape[i] = curshape;
+ if (curshape > 0) {
+ /* Normals for other shapes changed because vertex positions changed.
+ * Boolean doesn't need these, but post-boolean code (interpolation) does. */
+ BM_face_normal_update(efa);
+ if (LIKELY(efa->mat_nr < curshape_ncol)) {
+ efa->mat_nr = material_remap[efa->mat_nr];
+ }
+ }
+ i++;
+ }
- looptris = MEM_malloc_arrayN(looptris_tot, sizeof(*looptris), __func__);
+ BM_mesh_elem_index_ensure(bm, BM_FACE);
+ BM_mesh_boolean(
+ bm, looptris, tottri, bm_face_isect_nary, shape, num_shapes, true, false, bmd->operation);
- BM_mesh_calc_tessellation_beauty(bm, looptris, &tottri);
+ result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
+ BM_mesh_free(bm);
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- /* postpone this until after tessellating
- * so we can use the original normals before the vertex are moved */
- {
- BMIter iter;
- int i;
- const int i_verts_end = mesh_other->totvert;
- const int i_faces_end = mesh_other->totpoly;
+ MEM_freeN(shape);
+ MEM_freeN(shape_face_end);
+ MEM_freeN(shape_vert_end);
+ MEM_freeN(looptris);
+ if (material_remap != NULL) {
+ MEM_freeN(material_remap);
+ }
+ BLI_array_free(meshes);
+ BLI_array_free(objects);
+ return result;
+}
- float imat[4][4];
- float omat[4][4];
+static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
+{
+ BooleanModifierData *bmd = (BooleanModifierData *)md;
+ Object *object = ctx->object;
+ Mesh *result = mesh;
+ Mesh *mesh_operand_ob;
+ BMesh *bm;
+ Collection *col = bmd->collection;
- invert_m4_m4(imat, object->obmat);
- mul_m4_m4m4(omat, imat, other->obmat);
+ bool is_flip = false;
+ const bool confirm_return = true;
+#ifdef WITH_GMP
+ const bool use_exact = bmd->solver == eBooleanModifierSolver_Exact;
+#else
+ const bool use_exact = false;
+#endif
- BMVert *eve;
- i = 0;
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- mul_m4_v3(omat, eve->co);
- if (++i == i_verts_end) {
- break;
- }
- }
+#ifdef DEBUG_TIME
+ TIMEIT_START(boolean_bmesh);
+#endif
- /* we need face normals because of 'BM_face_split_edgenet'
- * we could calculate on the fly too (before calling split). */
- {
- float nmat[3][3];
- copy_m3_m4(nmat, omat);
- invert_m3(nmat);
-
- if (UNLIKELY(is_flip)) {
- negate_m3(nmat);
- }
-
- const short ob_src_totcol = other->totcol;
- short *material_remap = BLI_array_alloca(material_remap,
- ob_src_totcol ? ob_src_totcol : 1);
-
- /* 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_object_material_remap_calc(ctx->object, other, material_remap);
-
- BMFace *efa;
- i = 0;
- BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- mul_transposed_m3_v3(nmat, efa->no);
- normalize_v3(efa->no);
-
- /* Temp tag to test which side split faces are from. */
- BM_elem_flag_enable(efa, BM_FACE_TAG);
-
- /* remap material */
- if (LIKELY(efa->mat_nr < ob_src_totcol)) {
- efa->mat_nr = material_remap[efa->mat_nr];
- }
-
- if (++i == i_faces_end) {
- break;
- }
- }
- }
- }
+ if (bmd->flag & eBooleanModifierFlag_Object) {
+ if (bmd->object == NULL) {
+ return result;
+ }
- /* not needed, but normals for 'dm' will be invalid,
- * currently this is ok for 'BM_mesh_intersect' */
- // BM_mesh_normals_update(bm);
+ BMD_error_messages(ctx->object, md, NULL);
- bool use_separate = false;
- bool use_dissolve = true;
- bool use_island_connect = true;
+ Object *operand_ob = bmd->object;
- /* change for testing */
- if (G.debug & G_DEBUG) {
- use_separate = (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_Separate) != 0;
- use_dissolve = (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_NoDissolve) == 0;
- use_island_connect = (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_NoConnectRegions) ==
- 0;
- }
+ mesh_operand_ob = BKE_modifier_get_evaluated_mesh_from_evaluated_object(operand_ob, false);
-#ifdef WITH_GMP
- const bool use_exact = bmd->solver == eBooleanModifierSolver_Exact;
- const bool use_self = (bmd->flag & eBooleanModifierFlag_Self) != 0;
-#else
- if (bmd->solver == eBooleanModifierSolver_Exact) {
- BKE_modifier_set_error(md, "Compiled without GMP, using fast solver");
- }
- const bool use_exact = false;
- const bool use_self = false;
-#endif
+ if (mesh_operand_ob) {
+ /* XXX This is utterly non-optimal, we may go from a bmesh to a mesh back to a bmesh!
+ * But for 2.90 better not try to be smart here. */
+ BKE_mesh_wrapper_ensure_mdata(mesh_operand_ob);
+ /* when one of objects is empty (has got no faces) we could speed up
+ * calculation a bit returning one of objects' derived meshes (or empty one)
+ * Returning mesh is depended on modifiers operation (sergey) */
+ result = get_quick_mesh(object, mesh, operand_ob, mesh_operand_ob, bmd->operation);
- if (use_exact) {
- BM_mesh_boolean(
- bm, looptris, tottri, bm_face_isect_pair, NULL, use_self, bmd->operation);
- }
- else {
- BM_mesh_intersect(bm,
- looptris,
- tottri,
- bm_face_isect_pair,
- NULL,
- false,
- use_separate,
- use_dissolve,
- use_island_connect,
- false,
- false,
- bmd->operation,
- bmd->double_threshold);
- }
+ if (result == NULL) {
+ bm = BMD_mesh_bm_create(mesh, object, mesh_operand_ob, operand_ob, &is_flip);
+
+ BMD_mesh_intersection(bm, md, ctx, mesh_operand_ob, object, operand_ob, is_flip);
- MEM_freeN(looptris);
+ result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
+ BM_mesh_free(bm);
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
- result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
+ /* if new mesh returned, return it; otherwise there was
+ * an error, so delete the modifier object */
+ if (result == NULL) {
+ BKE_modifier_set_error(object, md, "Cannot execute boolean operation");
+ }
+ }
+ }
- BM_mesh_free(bm);
+ else {
+ if (col == NULL && !use_exact) {
+ return result;
+ }
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ /* Return result for certain errors. */
+ if (BMD_error_messages(ctx->object, md, col) == confirm_return) {
+ return result;
+ }
-#ifdef DEBUG_TIME
- TIMEIT_END(boolean_bmesh);
-#endif
+ if (use_exact) {
+ result = collection_boolean_exact(bmd, ctx, mesh);
}
+ else {
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (col, operand_ob) {
+ if (operand_ob->type == OB_MESH && operand_ob != ctx->object) {
+
+ mesh_operand_ob = BKE_modifier_get_evaluated_mesh_from_evaluated_object(operand_ob,
+ false);
- /* if new mesh returned, return it; otherwise there was
- * an error, so delete the modifier object */
- if (result == NULL) {
- BKE_modifier_set_error(md, "Cannot execute boolean operation");
+ if (mesh_operand_ob) {
+ /* XXX This is utterly non-optimal, we may go from a bmesh to a mesh back to a bmesh!
+ * But for 2.90 better not try to be smart here. */
+ BKE_mesh_wrapper_ensure_mdata(mesh_operand_ob);
+
+ bm = BMD_mesh_bm_create(mesh, object, mesh_operand_ob, operand_ob, &is_flip);
+
+ BMD_mesh_intersection(bm, md, ctx, mesh_operand_ob, object, operand_ob, is_flip);
+
+ /* Needed for multiple objects to work. */
+ BM_mesh_bm_to_me(NULL,
+ bm,
+ mesh,
+ (&(struct BMeshToMeshParams){
+ .calc_object_remap = false,
+ }));
+
+ result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
+ BM_mesh_free(bm);
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ }
+ }
+ }
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
}
}
+#ifdef DEBUG_TIME
+ TIMEIT_END(boolean_bmesh);
+#endif
+
return result;
}
@@ -392,13 +694,26 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropSep(layout, true);
+ uiItemR(layout, ptr, "operand_type", 0, NULL, ICON_NONE);
+
+ const bool operand_object = RNA_enum_get(ptr, "operand_type") == eBooleanModifierFlag_Object;
+
+ if (operand_object) {
+ uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE);
+ }
+ else {
+ uiItemR(layout, ptr, "collection", 0, NULL, ICON_NONE);
+ }
+
const bool use_exact = RNA_enum_get(ptr, "solver") == eBooleanModifierSolver_Exact;
- uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "solver", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
if (use_exact) {
- uiItemR(layout, ptr, "use_self", 0, NULL, ICON_NONE);
+ /* When operand is collection, we always use_self. */
+ if (operand_object) {
+ uiItemR(layout, ptr, "use_self", 0, NULL, ICON_NONE);
+ }
}
else {
uiItemR(layout, ptr, "double_threshold", 0, NULL, ICON_NONE);
@@ -421,8 +736,10 @@ ModifierTypeInfo modifierType_Boolean = {
/* name */ "Boolean",
/* structName */ "BooleanModifierData",
/* structSize */ sizeof(BooleanModifierData),
+ /* srna */ &RNA_BooleanModifier,
/* type */ eModifierTypeType_Nonconstructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_MOD_BOOLEAN,
/* copyData */ BKE_modifier_copydata_generic,
@@ -442,8 +759,7 @@ ModifierTypeInfo modifierType_Boolean = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
/* panelRegister */ panelRegister,
diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c
index d3caffb819c..96ed0a5d069 100644
--- a/source/blender/modifiers/intern/MOD_build.c
+++ b/source/blender/modifiers/intern/MOD_build.c
@@ -29,6 +29,7 @@
#include "BLI_math_vector.h"
#include "BLI_rand.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -55,8 +56,9 @@ static void initData(ModifierData *md)
{
BuildModifierData *bmd = (BuildModifierData *)md;
- bmd->start = 1.0;
- bmd->length = 100.0;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(bmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(bmd, DNA_struct_default_get(BuildModifierData), modifier);
}
static bool dependsOnTime(ModifierData *UNUSED(md))
@@ -331,8 +333,10 @@ ModifierTypeInfo modifierType_Build = {
/* name */ "Build",
/* structName */ "BuildModifierData",
/* structSize */ sizeof(BuildModifierData),
+ /* srna */ &RNA_BuildModifier,
/* type */ eModifierTypeType_Nonconstructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs,
+ /* icon */ ICON_MOD_BUILD,
/* copyData */ BKE_modifier_copydata_generic,
@@ -352,7 +356,6 @@ ModifierTypeInfo modifierType_Build = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c
index 4f2f6d219d8..185c21af7ad 100644
--- a/source/blender/modifiers/intern/MOD_cast.c
+++ b/source/blender/modifiers/intern/MOD_cast.c
@@ -27,6 +27,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -56,13 +57,9 @@ static void initData(ModifierData *md)
{
CastModifierData *cmd = (CastModifierData *)md;
- cmd->fac = 0.5f;
- cmd->radius = 0.0f;
- cmd->size = 0.0f;
- cmd->flag = MOD_CAST_X | MOD_CAST_Y | MOD_CAST_Z | MOD_CAST_SIZE_FROM_RADIUS;
- cmd->type = MOD_CAST_TYPE_SPHERE;
- cmd->defgrp_name[0] = '\0';
- cmd->object = NULL;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(cmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(cmd, DNA_struct_default_get(CastModifierData), modifier);
}
static bool isDisabled(const struct Scene *UNUSED(scene),
@@ -93,11 +90,11 @@ static void requiredDataMask(Object *UNUSED(ob),
}
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
CastModifierData *cmd = (CastModifierData *)md;
- walk(userData, ob, &cmd->object, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&cmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
@@ -515,7 +512,7 @@ static void deformVertsEM(ModifierData *md,
}
if (mesh && mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA) {
- BLI_assert(mesh_src->totvert == numVerts);
+ BLI_assert(mesh->totvert == numVerts);
}
/* TODO(Campbell): use edit-mode data only (remove this line). */
@@ -579,9 +576,11 @@ ModifierTypeInfo modifierType_Cast = {
/* name */ "Cast",
/* structName */ "CastModifierData",
/* structSize */ sizeof(CastModifierData),
+ /* srna */ &RNA_CastModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly |
eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_MOD_CAST,
/* copyData */ BKE_modifier_copydata_generic,
@@ -601,8 +600,7 @@ ModifierTypeInfo modifierType_Cast = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
/* panelRegister */ panelRegister,
diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c
index 7d0f245ecad..8f876213cd6 100644
--- a/source/blender/modifiers/intern/MOD_cloth.c
+++ b/source/blender/modifiers/intern/MOD_cloth.c
@@ -30,6 +30,7 @@
#include "BLT_translation.h"
#include "DNA_cloth_types.h"
+#include "DNA_defaults.h"
#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
@@ -65,8 +66,12 @@ static void initData(ModifierData *md)
{
ClothModifierData *clmd = (ClothModifierData *)md;
- clmd->sim_parms = MEM_callocN(sizeof(ClothSimSettings), "cloth sim parms");
- clmd->coll_parms = MEM_callocN(sizeof(ClothCollSettings), "cloth coll parms");
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(clmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(clmd, DNA_struct_default_get(ClothModifierData), modifier);
+ clmd->sim_parms = DNA_struct_default_alloc(ClothSimSettings);
+ clmd->coll_parms = DNA_struct_default_alloc(ClothCollSettings);
+
clmd->point_cache = BKE_ptcache_add(&clmd->ptcaches);
/* check for alloc failing */
@@ -74,7 +79,13 @@ static void initData(ModifierData *md)
return;
}
- cloth_init(clmd);
+ if (!clmd->sim_parms->effector_weights) {
+ clmd->sim_parms->effector_weights = BKE_effector_add_weights(NULL);
+ }
+
+ if (clmd->point_cache) {
+ clmd->point_cache->step = 1;
+ }
}
static void deformVerts(ModifierData *md,
@@ -102,7 +113,7 @@ static void deformVerts(ModifierData *md,
else {
/* Not possible to use get_mesh() in this case as we'll modify its vertices
* and get_mesh() would return 'mesh' directly. */
- BKE_id_copy_ex(NULL, (ID *)mesh, (ID **)&mesh_src, LIB_ID_COPY_LOCALIZE);
+ mesh_src = (Mesh *)BKE_id_copy_ex(NULL, (ID *)mesh, NULL, LIB_ID_COPY_LOCALIZE);
}
/* TODO(sergey): For now it actually duplicates logic from DerivedMesh.c
@@ -284,9 +295,11 @@ ModifierTypeInfo modifierType_Cloth = {
/* name */ "Cloth",
/* structName */ "ClothModifierData",
/* structSize */ sizeof(ClothModifierData),
+ /* srna */ &RNA_ClothModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_UsesPointCache |
eModifierTypeFlag_Single,
+ /* icon */ ICON_MOD_CLOTH,
/* copyData */ copyData,
@@ -306,7 +319,6 @@ ModifierTypeInfo modifierType_Cloth = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c
index 863e0ab7395..faba08f9613 100644
--- a/source/blender/modifiers/intern/MOD_collision.c
+++ b/source/blender/modifiers/intern/MOD_collision.c
@@ -27,6 +27,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -62,16 +63,9 @@ static void initData(ModifierData *md)
{
CollisionModifierData *collmd = (CollisionModifierData *)md;
- collmd->x = NULL;
- collmd->xnew = NULL;
- collmd->current_x = NULL;
- collmd->current_xnew = NULL;
- collmd->current_v = NULL;
- collmd->time_x = collmd->time_xnew = -1000;
- collmd->mvert_num = 0;
- collmd->tri_num = 0;
- collmd->is_static = false;
- collmd->bvhtree = NULL;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(collmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(collmd, DNA_struct_default_get(CollisionModifierData), modifier);
}
static void freeData(ModifierData *md)
@@ -121,7 +115,7 @@ static void deformVerts(ModifierData *md,
else {
/* Not possible to use get_mesh() in this case as we'll modify its vertices
* and get_mesh() would return 'mesh' directly. */
- BKE_id_copy_ex(NULL, (ID *)mesh, (ID **)&mesh_src, LIB_ID_COPY_LOCALIZE);
+ mesh_src = (Mesh *)BKE_id_copy_ex(NULL, (ID *)mesh, NULL, LIB_ID_COPY_LOCALIZE);
}
if (!ob->pd) {
@@ -302,8 +296,10 @@ ModifierTypeInfo modifierType_Collision = {
/* name */ "Collision",
/* structName */ "CollisionModifierData",
/* structSize */ sizeof(CollisionModifierData),
+ /* srna */ &RNA_CollisionModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_Single,
+ /* icon */ ICON_MOD_PHYSICS,
/* copyData */ NULL,
@@ -323,7 +319,6 @@ ModifierTypeInfo modifierType_Collision = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c
index 5eee196423e..5884ec0aa17 100644
--- a/source/blender/modifiers/intern/MOD_correctivesmooth.c
+++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c
@@ -29,6 +29,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -56,8 +57,6 @@
#include "BLO_read_write.h"
-#include "BLI_strict_flags.h"
-
#include "DEG_depsgraph_query.h"
// #define DEBUG_TIME
@@ -74,20 +73,15 @@ static void initData(ModifierData *md)
{
CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
- csmd->bind_coords = NULL;
- 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;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(csmd, modifier));
- csmd->defgrp_name[0] = '\0';
+ MEMCPY_STRUCT_AFTER(csmd, DNA_struct_default_get(CorrectiveSmoothModifierData), modifier);
csmd->delta_cache.deltas = NULL;
}
+#include "BLI_strict_flags.h"
+
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
const CorrectiveSmoothModifierData *csmd = (const CorrectiveSmoothModifierData *)md;
@@ -621,7 +615,7 @@ static void correctivesmooth_modifier_do(ModifierData *md,
csmd_orig->bind_coords_num = csmd->bind_coords_num;
}
else {
- BKE_modifier_set_error(md, "Attempt to bind from inactive dependency graph");
+ BKE_modifier_set_error(ob, md, "Attempt to bind from inactive dependency graph");
}
}
@@ -631,7 +625,7 @@ static void correctivesmooth_modifier_do(ModifierData *md,
}
if ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) && (csmd->bind_coords == NULL)) {
- BKE_modifier_set_error(md, "Bind data required");
+ BKE_modifier_set_error(ob, md, "Bind data required");
goto error;
}
@@ -639,14 +633,14 @@ static void correctivesmooth_modifier_do(ModifierData *md,
if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
if (csmd->bind_coords_num != numVerts) {
BKE_modifier_set_error(
- md, "Bind vertex count mismatch: %u to %u", csmd->bind_coords_num, numVerts);
+ ob, md, "Bind vertex count mismatch: %u to %u", csmd->bind_coords_num, numVerts);
goto error;
}
}
else {
/* MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO */
if (ob->type != OB_MESH) {
- BKE_modifier_set_error(md, "Object is not a mesh");
+ BKE_modifier_set_error(ob, md, "Object is not a mesh");
goto error;
}
else {
@@ -654,7 +648,7 @@ static void correctivesmooth_modifier_do(ModifierData *md,
if (me_numVerts != numVerts) {
BKE_modifier_set_error(
- md, "Original vertex count mismatch: %u to %u", me_numVerts, numVerts);
+ ob, md, "Original vertex count mismatch: %u to %u", me_numVerts, numVerts);
goto error;
}
}
@@ -823,7 +817,7 @@ static void blendWrite(BlendWriter *writer, const ModifierData *md)
const CorrectiveSmoothModifierData *csmd = (const CorrectiveSmoothModifierData *)md;
if (csmd->bind_coords) {
- BLO_write_float3_array(writer, (int)csmd->bind_coords_num, (float *)csmd->bind_coords);
+ BLO_write_float3_array(writer, csmd->bind_coords_num, (float *)csmd->bind_coords);
}
}
@@ -844,8 +838,10 @@ ModifierTypeInfo modifierType_CorrectiveSmooth = {
/* name */ "CorrectiveSmooth",
/* structName */ "CorrectiveSmoothModifierData",
/* structSize */ sizeof(CorrectiveSmoothModifierData),
+ /* srna */ &RNA_CorrectiveSmoothModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_MOD_SMOOTH,
/* copyData */ copyData,
@@ -865,7 +861,6 @@ ModifierTypeInfo modifierType_CorrectiveSmooth = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c
index ccbe8ff94d8..bed53cb0f51 100644
--- a/source/blender/modifiers/intern/MOD_curve.c
+++ b/source/blender/modifiers/intern/MOD_curve.c
@@ -27,6 +27,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -60,7 +61,9 @@ static void initData(ModifierData *md)
{
CurveModifierData *cmd = (CurveModifierData *)md;
- cmd->defaxis = MOD_CURVE_POSX;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(cmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(cmd, DNA_struct_default_get(CurveModifierData), modifier);
}
static void requiredDataMask(Object *UNUSED(ob),
@@ -87,11 +90,11 @@ static bool isDisabled(const Scene *UNUSED(scene), ModifierData *md, bool UNUSED
return !cmd->object || cmd->object->type != OB_CURVE;
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
CurveModifierData *cmd = (CurveModifierData *)md;
- walk(userData, ob, &cmd->object, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&cmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
@@ -218,9 +221,11 @@ ModifierTypeInfo modifierType_Curve = {
/* name */ "Curve",
/* structName */ "CurveModifierData",
/* structSize */ sizeof(CurveModifierData),
+ /* srna */ &RNA_CurveModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly |
eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_MOD_CURVE,
/* copyData */ BKE_modifier_copydata_generic,
@@ -240,8 +245,7 @@ ModifierTypeInfo modifierType_Curve = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
/* panelRegister */ panelRegister,
diff --git a/source/blender/modifiers/intern/MOD_datatransfer.c b/source/blender/modifiers/intern/MOD_datatransfer.c
index 6d89b76c9f7..d4c941d144d 100644
--- a/source/blender/modifiers/intern/MOD_datatransfer.c
+++ b/source/blender/modifiers/intern/MOD_datatransfer.c
@@ -122,10 +122,10 @@ static bool dependsOnNormals(ModifierData *md)
return false;
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
DataTransferModifierData *dtmd = (DataTransferModifierData *)md;
- walk(userData, ob, &dtmd->ob_source, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&dtmd->ob_source, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
@@ -198,7 +198,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
(dtmd->data_types & DT_TYPES_AFFECT_MESH)) {
/* 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);
+ result = (Mesh *)BKE_id_copy_ex(NULL, &me_mod->id, NULL, LIB_ID_COPY_LOCALIZE);
}
BKE_reports_init(&reports, RPT_STORE);
@@ -232,16 +232,19 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
if (BKE_reports_contain(&reports, RPT_ERROR)) {
const char *report_str = BKE_reports_string(&reports, RPT_ERROR);
- BKE_modifier_set_error(md, "%s", report_str);
+ BKE_modifier_set_error(ctx->object, md, "%s", report_str);
MEM_freeN((void *)report_str);
}
else if ((dtmd->data_types & DT_TYPE_LNOR) && !(me->flag & ME_AUTOSMOOTH)) {
- BKE_modifier_set_error((ModifierData *)dtmd, "Enable 'Auto Smooth' in Object Data Properties");
+ BKE_modifier_set_error(
+ ctx->object, (ModifierData *)dtmd, "Enable 'Auto Smooth' in Object Data Properties");
}
else if (result->totvert > HIGH_POLY_WARNING ||
((Mesh *)(ob_source->data))->totvert > HIGH_POLY_WARNING) {
BKE_modifier_set_error(
- md, "Source or destination object has a high polygon count, computation might be slow");
+ ctx->object,
+ md,
+ "Source or destination object has a high polygon count, computation might be slow");
}
return result;
@@ -264,11 +267,18 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(sub, ptr, "use_object_transform", 0, "", ICON_ORIENTATION_GLOBAL);
uiItemR(layout, ptr, "mix_mode", 0, NULL, ICON_NONE);
- uiItemR(layout, ptr, "mix_factor", 0, NULL, ICON_NONE);
+
+ row = uiLayoutRow(layout, false);
+ uiLayoutSetActive(row,
+ !ELEM(RNA_enum_get(ptr, "mix_mode"),
+ CDT_MIX_NOMIX,
+ CDT_MIX_REPLACE_ABOVE_THRESHOLD,
+ CDT_MIX_REPLACE_BELOW_THRESHOLD));
+ uiItemR(row, ptr, "mix_factor", 0, NULL, ICON_NONE);
modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
- uiItemO(layout, "Generate Data Layers", ICON_NONE, "OBJECT_OT_datalayout_transfer");
+ uiItemO(layout, IFACE_("Generate Data Layers"), ICON_NONE, "OBJECT_OT_datalayout_transfer");
modifier_panel_end(layout, ptr);
}
@@ -470,9 +480,11 @@ ModifierTypeInfo modifierType_DataTransfer = {
/* name */ "DataTransfer",
/* structName */ "DataTransferModifierData",
/* structSize */ sizeof(DataTransferModifierData),
+ /* srna */ &RNA_DataTransferModifier,
/* type */ eModifierTypeType_NonGeometrical,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_UsesPreview,
+ /* icon */ ICON_MOD_DATA_TRANSFER,
/* copyData */ BKE_modifier_copydata_generic,
@@ -492,8 +504,7 @@ ModifierTypeInfo modifierType_DataTransfer = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
/* panelRegister */ panelRegister,
diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c
index 72a868cc6a7..10ed4f8d80b 100644
--- a/source/blender/modifiers/intern/MOD_decimate.c
+++ b/source/blender/modifiers/intern/MOD_decimate.c
@@ -27,6 +27,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -63,9 +64,9 @@ static void initData(ModifierData *md)
{
DecimateModifierData *dmd = (DecimateModifierData *)md;
- dmd->percent = 1.0;
- dmd->angle = DEG2RADF(5.0f);
- dmd->defgrp_factor = 1.0;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(dmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(dmd, DNA_struct_default_get(DecimateModifierData), modifier);
}
static void requiredDataMask(Object *UNUSED(ob),
@@ -139,7 +140,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
if (dmd->face_count <= 3) {
- BKE_modifier_set_error(md, "Modifier requires more than 3 input faces");
+ BKE_modifier_set_error(ctx->object, md, "Modifier requires more than 3 input faces");
return mesh;
}
@@ -234,13 +235,13 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
PointerRNA ob_ptr;
PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr);
- uiLayoutSetPropSep(layout, true);
-
int decimate_type = RNA_enum_get(ptr, "decimate_type");
char count_info[32];
snprintf(count_info, 32, "%s: %d", IFACE_("Face Count"), RNA_int_get(ptr, "face_count"));
- uiItemR(layout, ptr, "decimate_type", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "decimate_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+
+ uiLayoutSetPropSep(layout, true);
if (decimate_type == MOD_DECIM_MODE_COLLAPSE) {
uiItemR(layout, ptr, "ratio", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
@@ -267,7 +268,8 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
}
else { /* decimate_type == MOD_DECIM_MODE_DISSOLVE. */
uiItemR(layout, ptr, "angle_limit", 0, NULL, ICON_NONE);
- uiItemR(layout, ptr, "delimit", 0, NULL, ICON_NONE);
+ uiLayout *col = uiLayoutColumn(layout, false);
+ uiItemR(col, ptr, "delimit", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "use_dissolve_boundaries", 0, NULL, ICON_NONE);
}
uiItemL(layout, count_info, ICON_NONE);
@@ -284,8 +286,10 @@ ModifierTypeInfo modifierType_Decimate = {
/* name */ "Decimate",
/* structName */ "DecimateModifierData",
/* structSize */ sizeof(DecimateModifierData),
+ /* srna */ &RNA_DecimateModifier,
/* type */ eModifierTypeType_Nonconstructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs,
+ /* icon */ ICON_MOD_DECIM,
/* copyData */ BKE_modifier_copydata_generic,
@@ -305,7 +309,6 @@ ModifierTypeInfo modifierType_Decimate = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c
index caee077c475..d432559fcfa 100644
--- a/source/blender/modifiers/intern/MOD_displace.c
+++ b/source/blender/modifiers/intern/MOD_displace.c
@@ -28,6 +28,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -60,7 +61,7 @@
#include "MOD_ui_common.h"
#include "MOD_util.h"
-#include "RE_shader_ext.h"
+#include "RE_texture.h"
/* Displace */
@@ -68,11 +69,9 @@ static void initData(ModifierData *md)
{
DisplaceModifierData *dmd = (DisplaceModifierData *)md;
- dmd->texture = NULL;
- dmd->strength = 1;
- dmd->direction = MOD_DISP_DIR_NOR;
- dmd->midlevel = 0.5;
- dmd->space = MOD_DISP_SPACE_LOCAL;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(dmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(dmd, DNA_struct_default_get(DisplaceModifierData), modifier);
}
static void requiredDataMask(Object *UNUSED(ob),
@@ -113,20 +112,12 @@ static bool dependsOnNormals(ModifierData *md)
return ELEM(dmd->direction, MOD_DISP_DIR_NOR, MOD_DISP_DIR_CLNOR);
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
-{
- DisplaceModifierData *dmd = (DisplaceModifierData *)md;
-
- walk(userData, ob, &dmd->map_object, IDWALK_CB_NOP);
-}
-
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
DisplaceModifierData *dmd = (DisplaceModifierData *)md;
walk(userData, ob, (ID **)&dmd->texture, IDWALK_CB_USER);
-
- foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
+ walk(userData, ob, (ID **)&dmd->map_object, IDWALK_CB_NOP);
}
static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
@@ -502,8 +493,10 @@ ModifierTypeInfo modifierType_Displace = {
/* name */ "Displace",
/* structName */ "DisplaceModifierData",
/* structSize */ sizeof(DisplaceModifierData),
+ /* srna */ &RNA_DisplaceModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_MOD_DISPLACE,
/* copyData */ BKE_modifier_copydata_generic,
@@ -523,7 +516,6 @@ ModifierTypeInfo modifierType_Displace = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ foreachObjectLink,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ foreachTexLink,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c
index 440b4677411..b69179f464d 100644
--- a/source/blender/modifiers/intern/MOD_dynamicpaint.c
+++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c
@@ -19,12 +19,14 @@
*/
#include <stddef.h>
+#include <string.h>
#include "BLI_listbase.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_dynamicpaint_types.h"
#include "DNA_mesh_types.h"
#include "DNA_object_force_types.h"
@@ -57,9 +59,9 @@ static void initData(ModifierData *md)
{
DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
- pmd->canvas = NULL;
- pmd->brush = NULL;
- pmd->type = MOD_DYNAMICPAINT_TYPE_CANVAS;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(pmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(pmd, DNA_struct_default_get(DynamicPaintModifierData), modifier);
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
@@ -203,10 +205,12 @@ ModifierTypeInfo modifierType_DynamicPaint = {
/* name */ "Dynamic Paint",
/* structName */ "DynamicPaintModifierData",
/* structSize */ sizeof(DynamicPaintModifierData),
+ /* srna */ &RNA_DynamicPaintModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
eModifierTypeFlag_UsesPointCache | eModifierTypeFlag_Single |
eModifierTypeFlag_UsesPreview,
+ /* icon */ ICON_MOD_DYNAMICPAINT,
/* copyData */ copyData,
@@ -226,7 +230,6 @@ ModifierTypeInfo modifierType_DynamicPaint = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ foreachTexLink,
/* freeRuntimeData */ freeRuntimeData,
diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c
index 2699896ac67..882d080c08d 100644
--- a/source/blender/modifiers/intern/MOD_edgesplit.c
+++ b/source/blender/modifiers/intern/MOD_edgesplit.c
@@ -32,6 +32,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
@@ -119,9 +120,9 @@ static void initData(ModifierData *md)
{
EdgeSplitModifierData *emd = (EdgeSplitModifierData *)md;
- /* default to 30-degree split angle, sharpness from both angle & flag */
- emd->split_angle = DEG2RADF(30.0f);
- emd->flags = MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(emd, modifier));
+
+ MEMCPY_STRUCT_AFTER(emd, DNA_struct_default_get(EdgeSplitModifierData), modifier);
}
static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh)
@@ -167,10 +168,12 @@ ModifierTypeInfo modifierType_EdgeSplit = {
/* name */ "EdgeSplit",
/* structName */ "EdgeSplitModifierData",
/* structSize */ sizeof(EdgeSplitModifierData),
+ /* srna */ &RNA_EdgeSplitModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs |
eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode |
eModifierTypeFlag_EnableInEditmode,
+ /* icon */ ICON_MOD_EDGESPLIT,
/* copyData */ BKE_modifier_copydata_generic,
@@ -190,7 +193,6 @@ ModifierTypeInfo modifierType_EdgeSplit = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c
index 0858fe9510b..d5e065ad321 100644
--- a/source/blender/modifiers/intern/MOD_explode.c
+++ b/source/blender/modifiers/intern/MOD_explode.c
@@ -30,6 +30,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -64,8 +65,9 @@ static void initData(ModifierData *md)
{
ExplodeModifierData *emd = (ExplodeModifierData *)md;
- emd->facepa = NULL;
- emd->flag |= eExplodeFlag_Unborn + eExplodeFlag_Alive + eExplodeFlag_Dead;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(emd, modifier));
+
+ MEMCPY_STRUCT_AFTER(emd, DNA_struct_default_get(ExplodeModifierData), modifier);
}
static void freeData(ModifierData *md)
{
@@ -1240,8 +1242,10 @@ ModifierTypeInfo modifierType_Explode = {
/* name */ "Explode",
/* structName */ "ExplodeModifierData",
/* structSize */ sizeof(ExplodeModifierData),
+ /* srna */ &RNA_ExplodeModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh,
+ /* icon */ ICON_MOD_EXPLODE,
/* copyData */ copyData,
/* deformVerts */ NULL,
@@ -1260,7 +1264,6 @@ ModifierTypeInfo modifierType_Explode = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_fluid.c b/source/blender/modifiers/intern/MOD_fluid.c
index d9bc78df527..6dc4fe79f88 100644
--- a/source/blender/modifiers/intern/MOD_fluid.c
+++ b/source/blender/modifiers/intern/MOD_fluid.c
@@ -225,8 +225,10 @@ ModifierTypeInfo modifierType_Fluid = {
/* name */ "Fluid",
/* structName */ "FluidModifierData",
/* structSize */ sizeof(FluidModifierData),
+ /* srna */ &RNA_FluidModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_Single,
+ /* icon */ ICON_MOD_FLUIDSIM,
/* copyData */ copyData,
@@ -246,7 +248,6 @@ ModifierTypeInfo modifierType_Fluid = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c
index 94a9a922ff7..e0c362171f2 100644
--- a/source/blender/modifiers/intern/MOD_hook.c
+++ b/source/blender/modifiers/intern/MOD_hook.c
@@ -28,6 +28,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -63,10 +64,11 @@ static void initData(ModifierData *md)
{
HookModifierData *hmd = (HookModifierData *)md;
- hmd->force = 1.0;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(hmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(hmd, DNA_struct_default_get(HookModifierData), modifier);
+
hmd->curfalloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
- hmd->falloff_type = eHook_Falloff_Smooth;
- hmd->flag = 0;
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
@@ -117,11 +119,11 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
return !hmd->object;
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
HookModifierData *hmd = (HookModifierData *)md;
- walk(userData, ob, &hmd->object, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&hmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
@@ -490,11 +492,11 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
if (RNA_enum_get(&ob_ptr, "mode") == OB_MODE_EDIT) {
row = uiLayoutRow(layout, true);
- uiItemO(row, "Reset", ICON_NONE, "OBJECT_OT_hook_reset");
- uiItemO(row, "Recenter", ICON_NONE, "OBJECT_OT_hook_recenter");
+ uiItemO(row, IFACE_("Reset"), ICON_NONE, "OBJECT_OT_hook_reset");
+ uiItemO(row, IFACE_("Recenter"), ICON_NONE, "OBJECT_OT_hook_recenter");
row = uiLayoutRow(layout, true);
- uiItemO(row, "Select", ICON_NONE, "OBJECT_OT_hook_select");
- uiItemO(row, "Assign", ICON_NONE, "OBJECT_OT_hook_assign");
+ uiItemO(row, IFACE_("Select"), ICON_NONE, "OBJECT_OT_hook_select");
+ uiItemO(row, IFACE_("Assign"), ICON_NONE, "OBJECT_OT_hook_assign");
}
modifier_panel_end(layout, ptr);
@@ -558,9 +560,11 @@ ModifierTypeInfo modifierType_Hook = {
/* name */ "Hook",
/* structName */ "HookModifierData",
/* structSize */ sizeof(HookModifierData),
+ /* srna */ &RNA_HookModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly |
eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_HOOK,
/* copyData */ copyData,
/* deformVerts */ deformVerts,
@@ -579,8 +583,7 @@ ModifierTypeInfo modifierType_Hook = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
/* panelRegister */ panelRegister,
diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c
index 8c297f11f7d..a484b4d8147 100644
--- a/source/blender/modifiers/intern/MOD_laplaciandeform.c
+++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c
@@ -31,6 +31,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_screen_types.h"
@@ -665,8 +666,7 @@ static void LaplacianDeformModifier_do(
sysdif = isSystemDifferent(lmd, ob, mesh, numVerts);
sys = lmd->cache_system;
if (sysdif) {
- if (sysdif == LAPDEFORM_SYSTEM_ONLY_CHANGE_ANCHORS ||
- sysdif == LAPDEFORM_SYSTEM_ONLY_CHANGE_GROUP) {
+ if (ELEM(sysdif, LAPDEFORM_SYSTEM_ONLY_CHANGE_ANCHORS, LAPDEFORM_SYSTEM_ONLY_CHANGE_GROUP)) {
filevertexCos = MEM_malloc_arrayN(numVerts, sizeof(float[3]), "TempModDeformCoordinates");
memcpy(filevertexCos, lmd->vertexco, sizeof(float[3]) * numVerts);
MEM_SAFE_FREE(lmd->vertexco);
@@ -683,14 +683,15 @@ static void LaplacianDeformModifier_do(
else {
if (sysdif == LAPDEFORM_SYSTEM_CHANGE_VERTEXES) {
BKE_modifier_set_error(
- &lmd->modifier, "Vertices changed from %d to %d", lmd->total_verts, numVerts);
+ ob, &lmd->modifier, "Vertices changed from %d to %d", lmd->total_verts, numVerts);
}
else if (sysdif == LAPDEFORM_SYSTEM_CHANGE_EDGES) {
BKE_modifier_set_error(
- &lmd->modifier, "Edges changed from %d to %d", sys->total_edges, mesh->totedge);
+ ob, &lmd->modifier, "Edges changed from %d to %d", sys->total_edges, mesh->totedge);
}
else if (sysdif == LAPDEFORM_SYSTEM_CHANGE_NOT_VALID_GROUP) {
- BKE_modifier_set_error(&lmd->modifier,
+ BKE_modifier_set_error(ob,
+ &lmd->modifier,
"Vertex group '%s' is not valid, or maybe empty",
sys->anchor_grp_name);
}
@@ -703,8 +704,10 @@ static void LaplacianDeformModifier_do(
}
else {
if (!isValidVertexGroup(lmd, ob, mesh)) {
- BKE_modifier_set_error(
- &lmd->modifier, "Vertex group '%s' is not valid, or maybe empty", lmd->anchor_grp_name);
+ BKE_modifier_set_error(ob,
+ &lmd->modifier,
+ "Vertex group '%s' is not valid, or maybe empty",
+ lmd->anchor_grp_name);
lmd->flag &= ~MOD_LAPLACIANDEFORM_BIND;
}
else if (lmd->total_verts > 0 && lmd->total_verts == numVerts) {
@@ -724,19 +727,17 @@ static void LaplacianDeformModifier_do(
}
}
if (sys && sys->is_matrix_computed && !sys->has_solution) {
- BKE_modifier_set_error(&lmd->modifier, "The system did not find a solution");
+ BKE_modifier_set_error(ob, &lmd->modifier, "The system did not find a solution");
}
}
static void initData(ModifierData *md)
{
LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)md;
- lmd->anchor_grp_name[0] = '\0';
- lmd->total_verts = 0;
- lmd->repeat = 1;
- lmd->vertexco = NULL;
- lmd->cache_system = NULL;
- lmd->flag = 0;
+
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(lmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(lmd, DNA_struct_default_get(LaplacianDeformModifierData), modifier);
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
@@ -875,8 +876,10 @@ ModifierTypeInfo modifierType_LaplacianDeform = {
/* name */ "LaplacianDeform",
/* structName */ "LaplacianDeformModifierData",
/* structSize */ sizeof(LaplacianDeformModifierData),
+ /* srna */ &RNA_LaplacianDeformModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_MOD_MESHDEFORM,
/* copyData */ copyData,
/* deformVerts */ deformVerts,
@@ -895,7 +898,6 @@ ModifierTypeInfo modifierType_LaplacianDeform = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
index 4c438256661..d51f95bd18d 100644
--- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c
+++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
@@ -27,6 +27,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -81,7 +82,7 @@ struct BLaplacianSystem {
typedef struct BLaplacianSystem LaplacianSystem;
static void required_data_mask(Object *ob, ModifierData *md, CustomData_MeshMasks *r_cddata_masks);
-static bool is_disabled(const struct Scene *UNUSED(scene), ModifierData *md, bool useRenderParams);
+static bool is_disabled(const struct Scene *scene, ModifierData *md, bool useRenderParams);
static float compute_volume(const float center[3],
float (*vertexCos)[3],
const MPoly *mpoly,
@@ -497,12 +498,10 @@ static void laplaciansmoothModifier_do(
static void init_data(ModifierData *md)
{
LaplacianSmoothModifierData *smd = (LaplacianSmoothModifierData *)md;
- smd->lambda = 0.01f;
- smd->lambda_border = 0.01f;
- smd->repeat = 1;
- smd->flag = MOD_LAPLACIANSMOOTH_X | MOD_LAPLACIANSMOOTH_Y | MOD_LAPLACIANSMOOTH_Z |
- MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME | MOD_LAPLACIANSMOOTH_NORMALIZED;
- smd->defgrp_name[0] = '\0';
+
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(smd, modifier));
+
+ MEMCPY_STRUCT_AFTER(smd, DNA_struct_default_get(LaplacianSmoothModifierData), modifier);
}
static bool is_disabled(const struct Scene *UNUSED(scene),
@@ -622,8 +621,10 @@ ModifierTypeInfo modifierType_LaplacianSmooth = {
/* name */ "LaplacianSmooth",
/* structName */ "LaplacianSmoothModifierData",
/* structSize */ sizeof(LaplacianSmoothModifierData),
+ /* srna */ &RNA_LaplacianSmoothModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_MOD_SMOOTH,
/* copyData */ BKE_modifier_copydata_generic,
@@ -643,7 +644,6 @@ ModifierTypeInfo modifierType_LaplacianSmooth = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c
index 75c34b3cc89..5aadc171394 100644
--- a/source/blender/modifiers/intern/MOD_lattice.c
+++ b/source/blender/modifiers/intern/MOD_lattice.c
@@ -27,6 +27,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
@@ -55,7 +56,10 @@
static void initData(ModifierData *md)
{
LatticeModifierData *lmd = (LatticeModifierData *)md;
- lmd->strength = 1.0f;
+
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(lmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(lmd, DNA_struct_default_get(LatticeModifierData), modifier);
}
static void requiredDataMask(Object *UNUSED(ob),
@@ -84,11 +88,11 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
return !lmd->object || lmd->object->type != OB_LATTICE;
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
LatticeModifierData *lmd = (LatticeModifierData *)md;
- walk(userData, ob, &lmd->object, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&lmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
@@ -174,9 +178,11 @@ ModifierTypeInfo modifierType_Lattice = {
/* name */ "Lattice",
/* structName */ "LatticeModifierData",
/* structSize */ sizeof(LatticeModifierData),
+ /* srna */ &RNA_LatticeModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly |
eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_MOD_LATTICE,
/* copyData */ BKE_modifier_copydata_generic,
@@ -196,8 +202,7 @@ ModifierTypeInfo modifierType_Lattice = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
/* panelRegister */ panelRegister,
diff --git a/source/blender/modifiers/intern/MOD_mask.cc b/source/blender/modifiers/intern/MOD_mask.cc
index 52d2bd11748..92ee5a84df9 100644
--- a/source/blender/modifiers/intern/MOD_mask.cc
+++ b/source/blender/modifiers/intern/MOD_mask.cc
@@ -31,6 +31,7 @@
#include "BLT_translation.h"
#include "DNA_armature_types.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -68,6 +69,15 @@ using blender::MutableSpan;
using blender::Span;
using blender::Vector;
+static void initData(ModifierData *md)
+{
+ MaskModifierData *mmd = (MaskModifierData *)md;
+
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(mmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(mmd, DNA_struct_default_get(MaskModifierData), modifier);
+}
+
static void requiredDataMask(Object *UNUSED(ob),
ModifierData *UNUSED(md),
CustomData_MeshMasks *r_cddata_masks)
@@ -75,10 +85,10 @@ static void requiredDataMask(Object *UNUSED(ob),
r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
MaskModifierData *mmd = reinterpret_cast<MaskModifierData *>(md);
- walk(userData, ob, &mmd->ob_arm, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&mmd->ob_arm, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
@@ -312,7 +322,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Return empty or input mesh when there are no vertex groups. */
MDeformVert *dvert = (MDeformVert *)CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT);
- if (dvert == NULL) {
+ if (dvert == nullptr) {
return invert_mask ? mesh : BKE_mesh_new_nomain_from_template(mesh, 0, 0, 0, 0, 0);
}
@@ -408,13 +418,13 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
int mode = RNA_enum_get(ptr, "mode");
- uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
uiLayoutSetPropSep(layout, true);
if (mode == MOD_MASK_MODE_ARM) {
row = uiLayoutRow(layout, true);
- uiItemR(row, ptr, "armature", 0, NULL, ICON_NONE);
+ uiItemR(row, ptr, "armature", 0, nullptr, ICON_NONE);
sub = uiLayoutRow(row, true);
uiLayoutSetPropDecorate(sub, false);
uiItemR(sub, ptr, "invert_vertex_group", 0, "", ICON_ARROW_LEFTRIGHT);
@@ -423,7 +433,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", nullptr);
}
- uiItemR(layout, ptr, "threshold", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "threshold", 0, nullptr, ICON_NONE);
modifier_panel_end(layout, ptr);
}
@@ -437,34 +447,35 @@ ModifierTypeInfo modifierType_Mask = {
/* name */ "Mask",
/* structName */ "MaskModifierData",
/* structSize */ sizeof(MaskModifierData),
+ /* srna */ &RNA_MaskModifier,
/* type */ eModifierTypeType_Nonconstructive,
/* flags */
(ModifierTypeFlag)(eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
eModifierTypeFlag_SupportsEditmode),
+ /* icon */ ICON_MOD_MASK,
/* copyData */ BKE_modifier_copydata_generic,
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
+ /* deformVerts */ nullptr,
+ /* deformMatrices */ nullptr,
+ /* deformVertsEM */ nullptr,
+ /* deformMatricesEM */ nullptr,
/* modifyMesh */ modifyMesh,
- /* modifyHair */ NULL,
- /* modifyPointCloud */ NULL,
- /* modifyVolume */ NULL,
+ /* modifyHair */ nullptr,
+ /* modifyPointCloud */ nullptr,
+ /* modifyVolume */ nullptr,
- /* initData */ NULL,
+ /* initData */ initData,
/* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
+ /* freeData */ nullptr,
/* isDisabled */ isDisabled,
/* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* dependsOnTime */ nullptr,
+ /* dependsOnNormals */ nullptr,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ nullptr,
+ /* freeRuntimeData */ nullptr,
/* panelRegister */ panelRegister,
- /* blendWrite */ NULL,
- /* blendRead */ NULL,
+ /* blendWrite */ nullptr,
+ /* blendRead */ nullptr,
};
diff --git a/source/blender/modifiers/intern/MOD_mesh_to_volume.cc b/source/blender/modifiers/intern/MOD_mesh_to_volume.cc
new file mode 100644
index 00000000000..61d556a64af
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_mesh_to_volume.cc
@@ -0,0 +1,315 @@
+/*
+ * 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.
+ */
+
+/** \file
+ * \ingroup modifiers
+ */
+
+#include <vector>
+
+#include "BKE_lib_query.h"
+#include "BKE_mesh_runtime.h"
+#include "BKE_mesh_wrapper.h"
+#include "BKE_modifier.h"
+#include "BKE_object.h"
+#include "BKE_volume.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_volume_types.h"
+
+#include "DEG_depsgraph.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "BLO_read_write.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "MOD_modifiertypes.h"
+#include "MOD_ui_common.h"
+
+#include "BLI_float4x4.hh"
+#include "BLI_index_range.hh"
+#include "BLI_span.hh"
+
+#include "RNA_access.h"
+
+#ifdef WITH_OPENVDB
+# include <openvdb/openvdb.h>
+# include <openvdb/tools/MeshToVolume.h>
+#endif
+
+#ifdef WITH_OPENVDB
+namespace blender {
+/* This class follows the MeshDataAdapter interface from openvdb. */
+class OpenVDBMeshAdapter {
+ private:
+ Span<MVert> vertices_;
+ Span<MLoop> loops_;
+ Span<MLoopTri> looptris_;
+ float4x4 transform_;
+
+ public:
+ OpenVDBMeshAdapter(Mesh &mesh, float4x4 transform)
+ : vertices_(mesh.mvert, mesh.totvert),
+ loops_(mesh.mloop, mesh.totloop),
+ transform_(transform)
+ {
+ const MLoopTri *looptries = BKE_mesh_runtime_looptri_ensure(&mesh);
+ const int looptries_len = BKE_mesh_runtime_looptri_len(&mesh);
+ looptris_ = Span(looptries, looptries_len);
+ }
+
+ size_t polygonCount() const
+ {
+ return static_cast<size_t>(looptris_.size());
+ }
+
+ size_t pointCount() const
+ {
+ return static_cast<size_t>(vertices_.size());
+ }
+
+ size_t vertexCount(size_t UNUSED(polygon_index)) const
+ {
+ /* All polygons are triangles. */
+ return 3;
+ }
+
+ void getIndexSpacePoint(size_t polygon_index, size_t vertex_index, openvdb::Vec3d &pos) const
+ {
+ const MLoopTri &looptri = looptris_[polygon_index];
+ const MVert &vertex = vertices_[loops_[looptri.tri[vertex_index]].v];
+ const float3 transformed_co = transform_ * float3(vertex.co);
+ pos = &transformed_co.x;
+ }
+};
+} // namespace blender
+#endif
+
+static void initData(ModifierData *md)
+{
+ MeshToVolumeModifierData *mvmd = reinterpret_cast<MeshToVolumeModifierData *>(md);
+ mvmd->object = nullptr;
+ mvmd->resolution_mode = MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT;
+ mvmd->voxel_size = 0.1f;
+ mvmd->voxel_amount = 32;
+ mvmd->fill_volume = true;
+ mvmd->interior_band_width = 0.1f;
+ mvmd->exterior_band_width = 0.1f;
+ mvmd->density = 1.0f;
+}
+
+static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
+{
+ MeshToVolumeModifierData *mvmd = reinterpret_cast<MeshToVolumeModifierData *>(md);
+ DEG_add_modifier_to_transform_relation(ctx->node, "Mesh to Volume Modifier");
+ if (mvmd->object) {
+ DEG_add_object_relation(
+ ctx->node, mvmd->object, DEG_OB_COMP_GEOMETRY, "Mesh to Volume Modifier");
+ DEG_add_object_relation(
+ ctx->node, mvmd->object, DEG_OB_COMP_TRANSFORM, "Mesh to Volume Modifier");
+ }
+}
+
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
+{
+ MeshToVolumeModifierData *mvmd = reinterpret_cast<MeshToVolumeModifierData *>(md);
+ walk(userData, ob, (ID **)&mvmd->object, IDWALK_CB_NOP);
+}
+
+static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+{
+ uiLayout *layout = panel->layout;
+
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
+ MeshToVolumeModifierData *mvmd = static_cast<MeshToVolumeModifierData *>(ptr->data);
+
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+
+ uiItemR(layout, ptr, "object", 0, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "density", 0, nullptr, ICON_NONE);
+
+ {
+ uiLayout *col = uiLayoutColumn(layout, false);
+ uiItemR(col, ptr, "use_fill_volume", 0, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "exterior_band_width", 0, nullptr, ICON_NONE);
+
+ uiLayout *subcol = uiLayoutColumn(col, false);
+ uiLayoutSetActive(subcol, !mvmd->fill_volume);
+ uiItemR(subcol, ptr, "interior_band_width", 0, nullptr, ICON_NONE);
+ }
+ {
+ uiLayout *col = uiLayoutColumn(layout, false);
+ uiItemR(col, ptr, "resolution_mode", 0, nullptr, ICON_NONE);
+ if (mvmd->resolution_mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT) {
+ uiItemR(col, ptr, "voxel_amount", 0, nullptr, ICON_NONE);
+ }
+ else {
+ uiItemR(col, ptr, "voxel_size", 0, nullptr, ICON_NONE);
+ }
+ }
+
+ modifier_panel_end(layout, ptr);
+}
+
+static void panelRegister(ARegionType *region_type)
+{
+ modifier_panel_register(region_type, eModifierType_MeshToVolume, panel_draw);
+}
+
+#ifdef WITH_OPENVDB
+static float compute_voxel_size(const ModifierEvalContext *ctx,
+ const MeshToVolumeModifierData *mvmd,
+ const blender::float4x4 &transform)
+{
+ using namespace blender;
+
+ float volume_simplify = BKE_volume_simplify_factor(ctx->depsgraph);
+ if (volume_simplify == 0.0f) {
+ return 0.0f;
+ }
+
+ if (mvmd->resolution_mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE) {
+ return mvmd->voxel_size / volume_simplify;
+ }
+ if (mvmd->voxel_amount <= 0) {
+ return 0;
+ }
+ /* Compute the voxel size based on the desired number of voxels and the approximated bounding box
+ * of the volume. */
+ const BoundBox *bb = BKE_object_boundbox_get(mvmd->object);
+ const float diagonal = float3::distance(transform * float3(bb->vec[6]),
+ transform * float3(bb->vec[0]));
+ const float approximate_volume_side_length = diagonal + mvmd->exterior_band_width * 2.0f;
+ const float voxel_size = approximate_volume_side_length / mvmd->voxel_amount / volume_simplify;
+ return voxel_size;
+}
+#endif
+
+static Volume *modifyVolume(ModifierData *md, const ModifierEvalContext *ctx, Volume *input_volume)
+{
+#ifdef WITH_OPENVDB
+ using namespace blender;
+
+ MeshToVolumeModifierData *mvmd = reinterpret_cast<MeshToVolumeModifierData *>(md);
+ Object *object_to_convert = mvmd->object;
+
+ if (object_to_convert == nullptr) {
+ return input_volume;
+ }
+ Mesh *mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(object_to_convert, false);
+ if (mesh == nullptr) {
+ return input_volume;
+ }
+ BKE_mesh_wrapper_ensure_mdata(mesh);
+
+ const float4x4 mesh_to_own_object_space_transform = float4x4(ctx->object->imat) *
+ float4x4(object_to_convert->obmat);
+ const float voxel_size = compute_voxel_size(ctx, mvmd, mesh_to_own_object_space_transform);
+ if (voxel_size == 0.0f) {
+ return input_volume;
+ }
+
+ float4x4 mesh_to_index_space_transform;
+ scale_m4_fl(mesh_to_index_space_transform.values, 1.0f / voxel_size);
+ mul_m4_m4_post(mesh_to_index_space_transform.values, mesh_to_own_object_space_transform.values);
+ /* Better align generated grid with the source mesh. */
+ add_v3_fl(mesh_to_index_space_transform.values[3], -0.5f);
+
+ OpenVDBMeshAdapter mesh_adapter{*mesh, mesh_to_index_space_transform};
+
+ /* Convert the bandwidths from object in index space. */
+ const float exterior_band_width = MAX2(0.001f, mvmd->exterior_band_width / voxel_size);
+ const float interior_band_width = MAX2(0.001f, mvmd->interior_band_width / voxel_size);
+
+ openvdb::FloatGrid::Ptr new_grid;
+ if (mvmd->fill_volume) {
+ /* Setting the interior bandwidth to FLT_MAX, will make it fill the entire volume. */
+ new_grid = openvdb::tools::meshToVolume<openvdb::FloatGrid>(
+ mesh_adapter, {}, exterior_band_width, FLT_MAX);
+ }
+ else {
+ new_grid = openvdb::tools::meshToVolume<openvdb::FloatGrid>(
+ mesh_adapter, {}, exterior_band_width, interior_band_width);
+ }
+
+ /* Create a new volume object and add the density grid. */
+ Volume *volume = BKE_volume_new_for_eval(input_volume);
+ VolumeGrid *c_density_grid = BKE_volume_grid_add(volume, "density", VOLUME_GRID_FLOAT);
+ openvdb::FloatGrid::Ptr density_grid = openvdb::gridPtrCast<openvdb::FloatGrid>(
+ BKE_volume_grid_openvdb_for_write(volume, c_density_grid, false));
+
+ /* Merge the generated grid into the density grid. Should be cheap because density_grid has just
+ * been created as well. */
+ density_grid->merge(*new_grid);
+
+ /* Change transform so that the index space is correctly transformed to object space. */
+ density_grid->transform().postScale(voxel_size);
+
+ /* Give each grid cell a fixed density for now. */
+ openvdb::tools::foreach (
+ density_grid->beginValueOn(),
+ [&](const openvdb::FloatGrid::ValueOnIter &iter) { iter.setValue(mvmd->density); });
+
+ return volume;
+
+#else
+ UNUSED_VARS(md);
+ BKE_modifier_set_error(ctx->object, md, "Compiled without OpenVDB");
+ return input_volume;
+#endif
+}
+
+ModifierTypeInfo modifierType_MeshToVolume = {
+ /* name */ "Mesh to Volume",
+ /* structName */ "MeshToVolumeModifierData",
+ /* structSize */ sizeof(MeshToVolumeModifierData),
+ /* srna */ &RNA_MeshToVolumeModifier,
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ static_cast<ModifierTypeFlag>(0),
+ /* icon */ ICON_VOLUME_DATA, /* TODO: Use correct icon. */
+
+ /* copyData */ BKE_modifier_copydata_generic,
+
+ /* deformVerts */ nullptr,
+ /* deformMatrices */ nullptr,
+ /* deformVertsEM */ nullptr,
+ /* deformMatricesEM */ nullptr,
+ /* modifyMesh */ nullptr,
+ /* modifyHair */ nullptr,
+ /* modifyPointCloud */ nullptr,
+ /* modifyVolume */ modifyVolume,
+
+ /* initData */ initData,
+ /* requiredDataMask */ nullptr,
+ /* freeData */ nullptr,
+ /* isDisabled */ nullptr,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ nullptr,
+ /* dependsOnNormals */ nullptr,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ nullptr,
+ /* freeRuntimeData */ nullptr,
+ /* panelRegister */ panelRegister,
+ /* blendWrite */ nullptr,
+ /* blendRead */ nullptr,
+};
diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c
index 456ece7704b..b808d738fe8 100644
--- a/source/blender/modifiers/intern/MOD_meshcache.c
+++ b/source/blender/modifiers/intern/MOD_meshcache.c
@@ -28,6 +28,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -57,16 +58,9 @@ static void initData(ModifierData *md)
{
MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
- mcmd->flag = 0;
- mcmd->type = MOD_MESHCACHE_TYPE_MDD;
- mcmd->interp = MOD_MESHCACHE_INTERP_LINEAR;
- mcmd->frame_scale = 1.0f;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(mcmd, modifier));
- mcmd->factor = 1.0f;
-
- /* (Y, Z). Blender default */
- mcmd->forward_axis = 1;
- mcmd->up_axis = 2;
+ MEMCPY_STRUCT_AFTER(mcmd, DNA_struct_default_get(MeshCacheModifierData), modifier);
}
static bool dependsOnTime(ModifierData *md)
@@ -177,13 +171,13 @@ static void meshcache_do(MeshCacheModifierData *mcmd,
/* we could support any object type */
if (UNLIKELY(ob->type != OB_MESH)) {
- BKE_modifier_set_error(&mcmd->modifier, "'Integrate' only valid for Mesh objects");
+ BKE_modifier_set_error(ob, &mcmd->modifier, "'Integrate' only valid for Mesh objects");
}
else if (UNLIKELY(me->totvert != numVerts)) {
- BKE_modifier_set_error(&mcmd->modifier, "'Integrate' original mesh vertex mismatch");
+ BKE_modifier_set_error(ob, &mcmd->modifier, "'Integrate' original mesh vertex mismatch");
}
else if (UNLIKELY(me->totpoly == 0)) {
- BKE_modifier_set_error(&mcmd->modifier, "'Integrate' requires faces");
+ BKE_modifier_set_error(ob, &mcmd->modifier, "'Integrate' requires faces");
}
else {
/* the moons align! */
@@ -222,7 +216,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd,
/* -------------------------------------------------------------------- */
/* Apply the transformation matrix (if needed) */
if (UNLIKELY(err_str)) {
- BKE_modifier_set_error(&mcmd->modifier, "%s", err_str);
+ BKE_modifier_set_error(ob, &mcmd->modifier, "%s", err_str);
}
else if (ok) {
bool use_matrix = false;
@@ -380,9 +374,11 @@ ModifierTypeInfo modifierType_MeshCache = {
/* name */ "MeshCache",
/* structName */ "MeshCacheModifierData",
/* structSize */ sizeof(MeshCacheModifierData),
+ /* srna */ &RNA_MeshCacheModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly |
eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_MOD_MESHDEFORM, /* TODO: Use correct icon. */
/* copyData */ BKE_modifier_copydata_generic,
@@ -402,7 +398,6 @@ ModifierTypeInfo modifierType_MeshCache = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_meshcache_pc2.c b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
index 120d1d6d71a..0ef9f26f1d7 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_pc2.c
+++ b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
@@ -81,7 +81,7 @@ static bool meshcache_read_pc2_head(FILE *fp,
}
/**
- * Gets the index frange and factor
+ * Gets the index range and factor
*
* currently same as for MDD
*/
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c
index 16b72bb358a..0e530312238 100644
--- a/source/blender/modifiers/intern/MOD_meshdeform.c
+++ b/source/blender/modifiers/intern/MOD_meshdeform.c
@@ -28,6 +28,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -68,7 +69,9 @@ static void initData(ModifierData *md)
{
MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
- mmd->gridsize = 5;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(mmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(mmd, DNA_struct_default_get(MeshDeformModifierData), modifier);
}
static void freeData(ModifierData *md)
@@ -160,11 +163,11 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
return !mmd->object || mmd->object->type != OB_MESH;
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
- walk(userData, ob, &mmd->object, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&mmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
@@ -370,7 +373,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) {
- BKE_modifier_set_error(md, "Cannot get mesh from cage object");
+ BKE_modifier_set_error(ctx->object, md, "Cannot get mesh from cage object");
return;
}
@@ -385,7 +388,7 @@ static void meshdeformModifier_do(ModifierData *md,
if (!mmd->bindcagecos) {
/* progress bar redraw can make this recursive .. */
if (!DEG_is_active(ctx->depsgraph)) {
- BKE_modifier_set_error(md, "Attempt to bind from inactive dependency graph");
+ BKE_modifier_set_error(ob, md, "Attempt to bind from inactive dependency graph");
goto finally;
}
if (!recursive_bind_sentinel) {
@@ -402,16 +405,16 @@ static void meshdeformModifier_do(ModifierData *md,
totcagevert = BKE_mesh_wrapper_vert_len(cagemesh);
if (mmd->totvert != totvert) {
- BKE_modifier_set_error(md, "Vertices changed from %d to %d", mmd->totvert, totvert);
+ BKE_modifier_set_error(ob, md, "Vertices changed from %d to %d", mmd->totvert, totvert);
goto finally;
}
else if (mmd->totcagevert != totcagevert) {
BKE_modifier_set_error(
- md, "Cage vertices changed from %d to %d", mmd->totcagevert, totcagevert);
+ ob, md, "Cage vertices changed from %d to %d", mmd->totcagevert, totcagevert);
goto finally;
}
else if (mmd->bindcagecos == NULL) {
- BKE_modifier_set_error(md, "Bind data missing");
+ BKE_modifier_set_error(ob, md, "Bind data missing");
goto finally;
}
@@ -629,9 +632,11 @@ ModifierTypeInfo modifierType_MeshDeform = {
/* name */ "MeshDeform",
/* structName */ "MeshDeformModifierData",
/* structSize */ sizeof(MeshDeformModifierData),
+ /* srna */ &RNA_MeshDeformModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly |
eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_MOD_MESHDEFORM,
/* copyData */ copyData,
@@ -651,8 +656,7 @@ ModifierTypeInfo modifierType_MeshDeform = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
/* panelRegister */ panelRegister,
diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c
index dc465ee941c..73106b2e816 100644
--- a/source/blender/modifiers/intern/MOD_meshsequencecache.c
+++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c
@@ -26,6 +26,7 @@
#include "BLT_translation.h"
#include "DNA_cachefile_types.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -64,15 +65,9 @@ static void initData(ModifierData *md)
{
MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md;
- mcmd->cache_file = NULL;
- mcmd->object_path[0] = '\0';
- mcmd->read_flag = MOD_MESHSEQ_READ_ALL;
- mcmd->velocity_scale = 1.0f;
- mcmd->vertex_velocities = NULL;
- mcmd->num_vertices = 0;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(mcmd, modifier));
- mcmd->reader = NULL;
- mcmd->reader_object_path[0] = '\0';
+ MEMCPY_STRUCT_AFTER(mcmd, DNA_struct_default_get(MeshSeqCacheModifierData), modifier);
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
@@ -132,7 +127,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
BKE_cachefile_reader_open(cache_file, &mcmd->reader, ctx->object, mcmd->object_path);
if (!mcmd->reader) {
BKE_modifier_set_error(
- md, "Could not create Alembic reader for file %s", cache_file->filepath);
+ ctx->object, md, "Could not create Alembic reader for file %s", cache_file->filepath);
return mesh;
}
}
@@ -153,11 +148,11 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
* flags) and duplicate those too. */
if ((me->mvert == mvert) || (me->medge == medge) || (me->mpoly == mpoly)) {
/* We need to duplicate data here, otherwise we'll modify org mesh, see T51701. */
- BKE_id_copy_ex(NULL,
- &mesh->id,
- (ID **)&mesh,
- LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT |
- LIB_ID_CREATE_NO_DEG_TAG | LIB_ID_COPY_NO_PREVIEW);
+ mesh = (Mesh *)BKE_id_copy_ex(NULL,
+ &mesh->id,
+ NULL,
+ LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT |
+ LIB_ID_CREATE_NO_DEG_TAG | LIB_ID_COPY_NO_PREVIEW);
}
}
@@ -175,7 +170,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
if (err_str) {
- BKE_modifier_set_error(md, "%s", err_str);
+ BKE_modifier_set_error(ctx->object, md, "%s", err_str);
}
if (!ELEM(result, NULL, mesh) && (mesh != org_mesh)) {
@@ -238,6 +233,7 @@ static void panel_draw(const bContext *C, Panel *panel)
if (RNA_enum_get(&ob_ptr, "type") == OB_MESH) {
uiItemR(layout, ptr, "read_data", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_vertex_interpolation", 0, NULL, ICON_NONE);
}
uiItemR(layout, ptr, "velocity_scale", 0, NULL, ICON_NONE);
@@ -261,8 +257,10 @@ ModifierTypeInfo modifierType_MeshSequenceCache = {
/* name */ "MeshSequenceCache",
/* structName */ "MeshSeqCacheModifierData",
/* structSize */ sizeof(MeshSeqCacheModifierData),
+ /* srna */ &RNA_MeshSequenceCacheModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs,
+ /* icon */ ICON_MOD_MESHDEFORM, /* TODO: Use correct icon. */
/* copyData */ copyData,
@@ -282,7 +280,6 @@ ModifierTypeInfo modifierType_MeshSequenceCache = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c
index 75c92bfd815..9346f601981 100644
--- a/source/blender/modifiers/intern/MOD_mirror.c
+++ b/source/blender/modifiers/intern/MOD_mirror.c
@@ -25,6 +25,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -59,16 +60,16 @@ static void initData(ModifierData *md)
{
MirrorModifierData *mmd = (MirrorModifierData *)md;
- mmd->flag |= (MOD_MIR_AXIS_X | MOD_MIR_VGROUP);
- mmd->tolerance = 0.001;
- mmd->mirror_ob = NULL;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(mmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(mmd, DNA_struct_default_get(MirrorModifierData), modifier);
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
MirrorModifierData *mmd = (MirrorModifierData *)md;
- walk(userData, ob, &mmd->mirror_ob, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&mmd->mirror_ob, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
@@ -216,12 +217,14 @@ ModifierTypeInfo modifierType_Mirror = {
/* name */ "Mirror",
/* structName */ "MirrorModifierData",
/* structSize */ sizeof(MirrorModifierData),
+ /* srna */ &RNA_MirrorModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode |
eModifierTypeFlag_AcceptsCVs |
/* this is only the case when 'MOD_MIR_VGROUP' is used */
eModifierTypeFlag_UsesPreview,
+ /* icon */ ICON_MOD_MIRROR,
/* copyData */ BKE_modifier_copydata_generic,
@@ -241,8 +244,7 @@ ModifierTypeInfo modifierType_Mirror = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
/* panelRegister */ panelRegister,
diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c
index 9c7ab50cb61..9f99e036601 100644
--- a/source/blender/modifiers/intern/MOD_multires.c
+++ b/source/blender/modifiers/intern/MOD_multires.c
@@ -29,6 +29,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -68,16 +69,12 @@ static void initData(ModifierData *md)
{
MultiresModifierData *mmd = (MultiresModifierData *)md;
- mmd->lvl = 0;
- mmd->sculptlvl = 0;
- mmd->renderlvl = 0;
- mmd->totlvl = 0;
- mmd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
- mmd->quality = 4;
- mmd->flags |= (eMultiresModifierFlag_UseCrease | eMultiresModifierFlag_ControlEdges);
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(mmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(mmd, DNA_struct_default_get(MultiresModifierData), modifier);
/* Open subdivision panels by default. */
- md->ui_expand_flag = (1 << 0) | (1 << 1);
+ md->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT | UI_SUBPANEL_DATA_EXPAND_1;
}
static void requiredDataMask(Object *UNUSED(ob),
@@ -219,7 +216,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
{
Mesh *result = mesh;
#if !defined(WITH_OPENSUBDIV)
- BKE_modifier_set_error(md, "Disabled, built without OpenSubdiv");
+ BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv");
return result;
#endif
MultiresModifierData *mmd = (MultiresModifierData *)md;
@@ -228,7 +225,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
if (subdiv_settings.level == 0) {
return result;
}
- BKE_subdiv_settings_validate_for_mesh(&subdiv_settings, mesh);
MultiresRuntimeData *runtime_data = multires_ensure_runtime(mmd);
Subdiv *subdiv = subdiv_descriptor_ensure(mmd, &subdiv_settings, mesh);
if (subdiv == NULL) {
@@ -304,7 +300,7 @@ static void deformMatrices(ModifierData *md,
{
#if !defined(WITH_OPENSUBDIV)
- BKE_modifier_set_error(md, "Disabled, built without OpenSubdiv");
+ BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv");
return;
#endif
@@ -325,7 +321,6 @@ static void deformMatrices(ModifierData *md,
return;
}
- BKE_subdiv_settings_validate_for_mesh(&subdiv_settings, mesh);
MultiresRuntimeData *runtime_data = multires_ensure_runtime(mmd);
Subdiv *subdiv = subdiv_descriptor_ensure(mmd, &subdiv_settings, mesh);
if (subdiv == NULL) {
@@ -481,14 +476,14 @@ static void advanced_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropSep(layout, true);
- uiLayoutSetEnabled(layout, !has_displacement);
+ uiLayoutSetActive(layout, !has_displacement);
- uiItemR(layout, ptr, "subdivision_type", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "quality", 0, NULL, ICON_NONE);
col = uiLayoutColumn(layout, false);
- uiLayoutSetEnabled(col, true);
+ uiLayoutSetActive(col, true);
uiItemR(col, ptr, "uv_smooth", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "boundary_smooth", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "use_creases", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "use_custom_normals", 0, NULL, ICON_NONE);
@@ -510,9 +505,11 @@ ModifierTypeInfo modifierType_Multires = {
/* name */ "Multires",
/* structName */ "MultiresModifierData",
/* structSize */ sizeof(MultiresModifierData),
+ /* srna */ &RNA_MultiresModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
eModifierTypeFlag_RequiresOriginalData,
+ /* icon */ ICON_MOD_MULTIRES,
/* copyData */ copyData,
@@ -532,7 +529,6 @@ ModifierTypeInfo modifierType_Multires = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ freeRuntimeData,
diff --git a/source/blender/modifiers/intern/MOD_none.c b/source/blender/modifiers/intern/MOD_none.c
index a84a10f4b6c..02307622d06 100644
--- a/source/blender/modifiers/intern/MOD_none.c
+++ b/source/blender/modifiers/intern/MOD_none.c
@@ -27,6 +27,10 @@
#include "MOD_modifiertypes.h"
+#include "UI_resources.h"
+
+#include "RNA_access.h"
+
/* We only need to define isDisabled; because it always returns 1,
* no other functions will be called
*/
@@ -42,8 +46,10 @@ ModifierTypeInfo modifierType_None = {
/* name */ "None",
/* structName */ "ModifierData",
/* structSize */ sizeof(ModifierData),
+ /* srna */ &RNA_Modifier,
/* type */ eModifierTypeType_None,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs,
+ /* icon */ ICON_NONE,
/* copyData */ NULL,
@@ -63,7 +69,6 @@ ModifierTypeInfo modifierType_None = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c
index 9962d3a55e0..0ec564d2e2d 100644
--- a/source/blender/modifiers/intern/MOD_normal_edit.c
+++ b/source/blender/modifiers/intern/MOD_normal_edit.c
@@ -29,6 +29,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -475,7 +476,15 @@ static bool is_valid_target(NormalEditModifierData *enmd)
if ((enmd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) && enmd->target) {
return true;
}
- BKE_modifier_set_error((ModifierData *)enmd, "Invalid target settings");
+ return false;
+}
+
+static bool is_valid_target_with_error(const Object *ob, NormalEditModifierData *enmd)
+{
+ if (is_valid_target(enmd)) {
+ return true;
+ }
+ BKE_modifier_set_error(ob, (ModifierData *)enmd, "Invalid target settings");
return false;
}
@@ -490,7 +499,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
(enmd->mix_limit == (float)M_PI));
/* Do not run that modifier at all if autosmooth is disabled! */
- if (!is_valid_target(enmd) || mesh->totloop == 0) {
+ if (!is_valid_target_with_error(ctx->object, enmd) || mesh->totloop == 0) {
return mesh;
}
@@ -505,7 +514,8 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
if (!(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH))
#endif
{
- BKE_modifier_set_error((ModifierData *)enmd, "Enable 'Auto Smooth' in Object Data Properties");
+ BKE_modifier_set_error(
+ ob, (ModifierData *)enmd, "Enable 'Auto Smooth' in Object Data Properties");
return mesh;
}
@@ -514,7 +524,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
/* We need to duplicate data here, otherwise setting custom normals
* (which may also affect sharp edges) could
* modify original mesh, see T43671. */
- BKE_id_copy_ex(NULL, &mesh->id, (ID **)&result, LIB_ID_COPY_LOCALIZE);
+ result = (Mesh *)BKE_id_copy_ex(NULL, &mesh->id, NULL, LIB_ID_COPY_LOCALIZE);
}
else {
result = mesh;
@@ -646,11 +656,9 @@ static void initData(ModifierData *md)
{
NormalEditModifierData *enmd = (NormalEditModifierData *)md;
- enmd->mode = MOD_NORMALEDIT_MODE_RADIAL;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(enmd, modifier));
- enmd->mix_mode = MOD_NORMALEDIT_MIX_COPY;
- enmd->mix_factor = 1.0f;
- enmd->mix_limit = M_PI;
+ MEMCPY_STRUCT_AFTER(enmd, DNA_struct_default_get(NormalEditModifierData), modifier);
}
static void requiredDataMask(Object *UNUSED(ob),
@@ -672,11 +680,11 @@ static bool dependsOnNormals(ModifierData *UNUSED(md))
return true;
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
NormalEditModifierData *enmd = (NormalEditModifierData *)md;
- walk(userData, ob, &enmd->target, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&enmd->target, IDWALK_CB_NOP);
}
static bool isDisabled(const struct Scene *UNUSED(scene),
@@ -782,9 +790,11 @@ ModifierTypeInfo modifierType_NormalEdit = {
/* name */ "NormalEdit",
/* structName */ "NormalEditModifierData",
/* structSize */ sizeof(NormalEditModifierData),
+ /* srna */ &RNA_NormalEditModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode,
+ /* icon */ ICON_MOD_NORMALEDIT,
/* copyData */ BKE_modifier_copydata_generic,
@@ -804,8 +814,7 @@ ModifierTypeInfo modifierType_NormalEdit = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
/* panelRegister */ panelRegister,
diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c
index ccd105f8f69..5aef497c0c4 100644
--- a/source/blender/modifiers/intern/MOD_ocean.c
+++ b/source/blender/modifiers/intern/MOD_ocean.c
@@ -30,6 +30,7 @@
#include "BLT_translation.h"
#include "DNA_customdata_types.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -87,54 +88,17 @@ static void initData(ModifierData *md)
#ifdef WITH_OCEANSIM
OceanModifierData *omd = (OceanModifierData *)md;
- /* Render resolution */
- omd->resolution = 7;
- /* Display resolution for the non-render case */
- omd->viewport_resolution = 7;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(omd, modifier));
- omd->spatial_size = 50;
-
- omd->wave_alignment = 0.0;
- omd->wind_velocity = 30.0;
-
- omd->damp = 0.5;
- omd->smallest_wave = 0.01;
- omd->wave_direction = 0.0;
- omd->depth = 200.0;
-
- omd->wave_scale = 1.0;
-
- omd->chop_amount = 1.0;
-
- omd->foam_coverage = 0.0;
-
- 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;
+ MEMCPY_STRUCT_AFTER(omd, DNA_struct_default_get(OceanModifierData), modifier);
BKE_modifier_path_init(omd->cachepath, sizeof(omd->cachepath), "cache_ocean");
- omd->cached = 0;
- omd->bakestart = 1;
- omd->bakeend = 250;
- omd->oceancache = NULL;
- omd->foam_fade = 0.98;
- omd->foamlayername[0] = '\0'; /* layer name empty by default */
- omd->spraylayername[0] = '\0'; /* layer name empty by default */
-
omd->ocean = BKE_ocean_add();
BKE_ocean_init_from_modifier(omd->ocean, omd, omd->viewport_resolution);
simulate_ocean_modifier(omd);
#else /* WITH_OCEANSIM */
- /* unused */
- (void)md;
+ UNUSED_VARS(md);
#endif /* WITH_OCEANSIM */
}
@@ -409,7 +373,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes
BKE_mesh_ensure_normals(result);
}
else if (omd->geometry_mode == MOD_OCEAN_GEOM_DISPLACE) {
- BKE_id_copy_ex(NULL, &mesh->id, (ID **)&result, LIB_ID_COPY_LOCALIZE);
+ result = (Mesh *)BKE_id_copy_ex(NULL, &mesh->id, NULL, LIB_ID_COPY_LOCALIZE);
}
cfra_for_cache = cfra_scene;
@@ -758,9 +722,11 @@ ModifierTypeInfo modifierType_Ocean = {
/* name */ "Ocean",
/* structName */ "OceanModifierData",
/* structSize */ sizeof(OceanModifierData),
+ /* srna */ &RNA_OceanModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode |
eModifierTypeFlag_EnableInEditmode,
+ /* icon */ ICON_MOD_OCEAN,
/* copyData */ copyData,
/* deformMatrices_DM */ NULL,
@@ -780,7 +746,6 @@ ModifierTypeInfo modifierType_Ocean = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c
index 597a61c6c16..f660874a5ea 100644
--- a/source/blender/modifiers/intern/MOD_particleinstance.c
+++ b/source/blender/modifiers/intern/MOD_particleinstance.c
@@ -32,6 +32,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_screen_types.h"
@@ -61,17 +62,9 @@ static void initData(ModifierData *md)
{
ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
- pimd->flag = eParticleInstanceFlag_Parents | eParticleInstanceFlag_Unborn |
- eParticleInstanceFlag_Alive | eParticleInstanceFlag_Dead;
- pimd->psys = 1;
- pimd->position = 1.0f;
- pimd->axis = 2;
- pimd->space = eParticleInstanceSpace_World;
- pimd->particle_amount = 1.0f;
- pimd->particle_offset = 0.0f;
-
- STRNCPY(pimd->index_layer_name, "");
- STRNCPY(pimd->value_layer_name, "");
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(pimd, modifier));
+
+ MEMCPY_STRUCT_AFTER(pimd, DNA_struct_default_get(ParticleInstanceModifierData), modifier);
}
static void requiredDataMask(Object *UNUSED(ob),
@@ -144,11 +137,11 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
}
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
- walk(userData, ob, &pimd->ob, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&pimd->ob, IDWALK_CB_NOP);
}
static bool particle_skip(ParticleInstanceModifierData *pimd, ParticleSystem *psys, int p)
@@ -671,9 +664,11 @@ ModifierTypeInfo modifierType_ParticleInstance = {
/* name */ "ParticleInstance",
/* structName */ "ParticleInstanceModifierData",
/* structSize */ sizeof(ParticleInstanceModifierData),
+ /* srna */ &RNA_ParticleInstanceModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode,
+ /* icon */ ICON_MOD_PARTICLE_INSTANCE,
/* copyData */ BKE_modifier_copydata_generic,
@@ -693,8 +688,7 @@ ModifierTypeInfo modifierType_ParticleInstance = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
/* panelRegister */ panelRegister,
diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c
index c2f411f5247..86480a17083 100644
--- a/source/blender/modifiers/intern/MOD_particlesystem.c
+++ b/source/blender/modifiers/intern/MOD_particlesystem.c
@@ -22,11 +22,13 @@
*/
#include <stddef.h>
+#include <string.h>
#include "BLI_utildefines.h"
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_screen_types.h"
@@ -54,10 +56,10 @@
static void initData(ModifierData *md)
{
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
- psmd->psys = NULL;
- psmd->mesh_final = NULL;
- psmd->mesh_original = NULL;
- psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0;
+
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(psmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(psmd, DNA_struct_default_get(ParticleSystemModifierData), modifier);
}
static void freeData(ModifierData *md)
{
@@ -312,12 +314,14 @@ ModifierTypeInfo modifierType_ParticleSystem = {
/* name */ "ParticleSystem",
/* structName */ "ParticleSystemModifierData",
/* structSize */ sizeof(ParticleSystemModifierData),
+ /* srna */ &RNA_ParticleSystemModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
eModifierTypeFlag_UsesPointCache /* |
eModifierTypeFlag_SupportsEditmode |
eModifierTypeFlag_EnableInEditmode */
,
+ /* icon */ ICON_MOD_PARTICLES,
/* copyData */ copyData,
@@ -337,7 +341,6 @@ ModifierTypeInfo modifierType_ParticleSystem = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c
index 7a58b985429..f8fc4ad658e 100644
--- a/source/blender/modifiers/intern/MOD_remesh.c
+++ b/source/blender/modifiers/intern/MOD_remesh.c
@@ -29,6 +29,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -49,7 +50,6 @@
#include "MOD_modifiertypes.h"
#include "MOD_ui_common.h"
-#include <assert.h>
#include <stdlib.h>
#include <string.h>
@@ -63,14 +63,9 @@ static void initData(ModifierData *md)
{
RemeshModifierData *rmd = (RemeshModifierData *)md;
- rmd->scale = 0.9;
- rmd->depth = 4;
- rmd->hermite_num = 1;
- rmd->flag = MOD_REMESH_FLOOD_FILL;
- rmd->mode = MOD_REMESH_VOXEL;
- rmd->threshold = 1;
- rmd->voxel_size = 0.1f;
- rmd->adaptivity = 0.0f;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(rmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(rmd, DNA_struct_default_get(RemeshModifierData), modifier);
}
#ifdef WITH_MOD_REMESH
@@ -291,9 +286,11 @@ ModifierTypeInfo modifierType_Remesh = {
/* name */ "Remesh",
/* structName */ "RemeshModifierData",
/* structSize */ sizeof(RemeshModifierData),
+ /* srna */ &RNA_RemeshModifier,
/* type */ eModifierTypeType_Nonconstructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs |
eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_MOD_REMESH,
/* copyData */ BKE_modifier_copydata_generic,
@@ -313,7 +310,6 @@ ModifierTypeInfo modifierType_Remesh = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c
index 5842d05da09..6521a0859e5 100644
--- a/source/blender/modifiers/intern/MOD_screw.c
+++ b/source/blender/modifiers/intern/MOD_screw.c
@@ -31,6 +31,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -54,6 +55,15 @@
#include "MOD_modifiertypes.h"
#include "MOD_ui_common.h"
+static void initData(ModifierData *md)
+{
+ ScrewModifierData *ltmd = (ScrewModifierData *)md;
+
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(ltmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(ltmd, DNA_struct_default_get(ScrewModifierData), modifier);
+}
+
#include "BLI_strict_flags.h"
/* used for gathering edge connectivity */
@@ -177,19 +187,6 @@ static Mesh *mesh_remove_doubles_on_axis(Mesh *result,
return result;
}
-static void initData(ModifierData *md)
-{
- ScrewModifierData *ltmd = (ScrewModifierData *)md;
- ltmd->ob_axis = NULL;
- ltmd->angle = (float)(M_PI * 2.0);
- ltmd->axis = 2;
- ltmd->flag = MOD_SCREW_SMOOTH_SHADING;
- ltmd->steps = 16;
- ltmd->render_steps = 16;
- ltmd->iter = 1;
- ltmd->merge_dist = 0.01f;
-}
-
static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *meshData)
{
Mesh *mesh = meshData;
@@ -361,7 +358,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
step_tot = ((step_tot + 1) * ltmd->iter) - (ltmd->iter - 1);
/* Will the screw be closed?
- * Note! smaller then `FLT_EPSILON * 100`
+ * Note! smaller than `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) && step_tot > 3) {
@@ -1161,11 +1158,11 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
}
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
ScrewModifierData *ltmd = (ScrewModifierData *)md;
- walk(userData, ob, &ltmd->ob_axis, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&ltmd->ob_axis, IDWALK_CB_NOP);
}
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
@@ -1247,10 +1244,12 @@ ModifierTypeInfo modifierType_Screw = {
/* name */ "Screw",
/* structName */ "ScrewModifierData",
/* structSize */ sizeof(ScrewModifierData),
+ /* srna */ &RNA_ScrewModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs |
eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode,
+ /* icon */ ICON_MOD_SCREW,
/* copyData */ BKE_modifier_copydata_generic,
@@ -1270,8 +1269,7 @@ ModifierTypeInfo modifierType_Screw = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
/* panelRegister */ panelRegister,
diff --git a/source/blender/modifiers/intern/MOD_shapekey.c b/source/blender/modifiers/intern/MOD_shapekey.c
index 801995d6dbc..bb267386dfb 100644
--- a/source/blender/modifiers/intern/MOD_shapekey.c
+++ b/source/blender/modifiers/intern/MOD_shapekey.c
@@ -31,8 +31,12 @@
#include "BKE_key.h"
#include "BKE_particle.h"
+#include "RNA_access.h"
+
#include "MOD_modifiertypes.h"
+#include "UI_resources.h"
+
static void deformVerts(ModifierData *UNUSED(md),
const ModifierEvalContext *ctx,
Mesh *UNUSED(mesh),
@@ -121,9 +125,11 @@ ModifierTypeInfo modifierType_ShapeKey = {
/* name */ "ShapeKey",
/* structName */ "ShapeKeyModifierData",
/* structSize */ sizeof(ShapeKeyModifierData),
+ /* srna */ &RNA_Modifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly |
eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_DOT,
/* copyData */ NULL,
@@ -143,7 +149,6 @@ ModifierTypeInfo modifierType_ShapeKey = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c
index fb045cf8923..dddabb12f61 100644
--- a/source/blender/modifiers/intern/MOD_shrinkwrap.c
+++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c
@@ -27,6 +27,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
@@ -56,12 +57,10 @@ static bool dependsOnNormals(ModifierData *md);
static void initData(ModifierData *md)
{
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
- smd->shrinkType = MOD_SHRINKWRAP_NEAREST_SURFACE;
- smd->shrinkOpts = MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR;
- smd->keepDist = 0.0f;
- smd->target = NULL;
- smd->auxTarget = NULL;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(smd, modifier));
+
+ MEMCPY_STRUCT_AFTER(smd, DNA_struct_default_get(ShrinkwrapModifierData), modifier);
}
static void requiredDataMask(Object *UNUSED(ob),
@@ -102,12 +101,12 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
return false;
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
- walk(userData, ob, &smd->target, IDWALK_CB_NOP);
- walk(userData, ob, &smd->auxTarget, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&smd->target, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&smd->auxTarget, IDWALK_CB_NOP);
}
static void deformVerts(ModifierData *md,
@@ -278,10 +277,12 @@ ModifierTypeInfo modifierType_Shrinkwrap = {
/* name */ "Shrinkwrap",
/* structName */ "ShrinkwrapModifierData",
/* structSize */ sizeof(ShrinkwrapModifierData),
+ /* srna */ &RNA_ShrinkwrapModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs |
eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode |
eModifierTypeFlag_EnableInEditmode,
+ /* icon */ ICON_MOD_SHRINKWRAP,
/* copyData */ BKE_modifier_copydata_generic,
@@ -301,8 +302,7 @@ ModifierTypeInfo modifierType_Shrinkwrap = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
/* panelRegister */ panelRegister,
diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c
index a0bd4e2f20f..ec89176f97e 100644
--- a/source/blender/modifiers/intern/MOD_simpledeform.c
+++ b/source/blender/modifiers/intern/MOD_simpledeform.c
@@ -27,6 +27,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -378,14 +379,9 @@ static void initData(ModifierData *md)
{
SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
- smd->mode = MOD_SIMPLEDEFORM_MODE_TWIST;
- smd->axis = 0;
- smd->deform_axis = 0;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(smd, modifier));
- smd->origin = NULL;
- smd->factor = DEG2RADF(45.0f);
- smd->limit[0] = 0.0f;
- smd->limit[1] = 1.0f;
+ MEMCPY_STRUCT_AFTER(smd, DNA_struct_default_get(SimpleDeformModifierData), modifier);
}
static void requiredDataMask(Object *UNUSED(ob),
@@ -400,10 +396,10 @@ static void requiredDataMask(Object *UNUSED(ob),
}
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
- walk(userData, ob, &smd->origin, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&smd->origin, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
@@ -540,11 +536,13 @@ ModifierTypeInfo modifierType_SimpleDeform = {
/* name */ "SimpleDeform",
/* structName */ "SimpleDeformModifierData",
/* structSize */ sizeof(SimpleDeformModifierData),
+ /* srna */ &RNA_SimpleDeformModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs |
eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode |
eModifierTypeFlag_EnableInEditmode,
+ /* icon */ ICON_MOD_SIMPLEDEFORM,
/* copyData */ BKE_modifier_copydata_generic,
@@ -564,8 +562,7 @@ ModifierTypeInfo modifierType_SimpleDeform = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
/* panelRegister */ panelRegister,
diff --git a/source/blender/modifiers/intern/MOD_simulation.cc b/source/blender/modifiers/intern/MOD_simulation.cc
index d009eef00e6..0766c59cda6 100644
--- a/source/blender/modifiers/intern/MOD_simulation.cc
+++ b/source/blender/modifiers/intern/MOD_simulation.cc
@@ -32,6 +32,7 @@
#include "BLI_string.h"
#include "BLI_utildefines.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -64,18 +65,28 @@
using blender::float3;
-static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
+static void initData(ModifierData *md)
+{
+ SimulationModifierData *smd = (SimulationModifierData *)md;
+
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(smd, modifier));
+
+ MEMCPY_STRUCT_AFTER(smd, DNA_struct_default_get(SimulationModifierData), modifier);
+}
+
+static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *UNUSED(ctx))
{
SimulationModifierData *smd = reinterpret_cast<SimulationModifierData *>(md);
- if (smd->simulation) {
- DEG_add_simulation_relation(ctx->node, smd->simulation, "Accessed Simulation");
- }
+ UNUSED_VARS(smd);
}
-static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md,
+ Object *UNUSED(ob),
+ IDWalkFunc UNUSED(walk),
+ void *UNUSED(userData))
{
SimulationModifierData *smd = reinterpret_cast<SimulationModifierData *>(md);
- walk(userData, ob, (ID **)&smd->simulation, IDWALK_CB_USER);
+ UNUSED_VARS(smd);
}
static bool isDisabled(const struct Scene *UNUSED(scene),
@@ -83,41 +94,16 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
bool UNUSED(useRenderParams))
{
SimulationModifierData *smd = reinterpret_cast<SimulationModifierData *>(md);
- return smd->simulation == nullptr;
-}
-
-static const ParticleSimulationState *find_particle_state(SimulationModifierData *smd)
-{
- return reinterpret_cast<const ParticleSimulationState *>(
- BKE_simulation_state_try_find_by_name_and_type(
- smd->simulation, smd->data_path, SIM_TYPE_NAME_PARTICLE_SIMULATION));
+ UNUSED_VARS(smd);
+ return false;
}
static PointCloud *modifyPointCloud(ModifierData *md,
const ModifierEvalContext *UNUSED(ctx),
- PointCloud *input_pointcloud)
+ PointCloud *pointcloud)
{
SimulationModifierData *smd = reinterpret_cast<SimulationModifierData *>(md);
- const ParticleSimulationState *state = find_particle_state(smd);
- if (state == nullptr) {
- return input_pointcloud;
- }
-
- PointCloud *pointcloud = BKE_pointcloud_new_for_eval(input_pointcloud, state->tot_particles);
- if (state->tot_particles == 0) {
- return pointcloud;
- }
-
- const float3 *positions = static_cast<const float3 *>(
- CustomData_get_layer_named(&state->attributes, CD_PROP_FLOAT3, "Position"));
- const float *radii = static_cast<const float *>(
- CustomData_get_layer_named(&state->attributes, CD_PROP_FLOAT, "Radius"));
- memcpy(pointcloud->co, positions, sizeof(float3) * state->tot_particles);
-
- for (int i = 0; i < state->tot_particles; i++) {
- pointcloud->radius[i] = radii[i];
- }
-
+ UNUSED_VARS(smd);
return pointcloud;
}
@@ -131,8 +117,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
- uiItemR(layout, ptr, "simulation", 0, NULL, ICON_NONE);
- uiItemR(layout, ptr, "data_path", 0, NULL, ICON_NONE);
+ uiItemL(layout, "This modifier does nothing currently", ICON_INFO);
modifier_panel_end(layout, ptr);
}
@@ -145,63 +130,64 @@ static void panelRegister(ARegionType *region_type)
static void blendWrite(BlendWriter *writer, const ModifierData *md)
{
const SimulationModifierData *smd = reinterpret_cast<const SimulationModifierData *>(md);
- BLO_write_string(writer, smd->data_path);
+ UNUSED_VARS(smd, writer);
}
static void blendRead(BlendDataReader *reader, ModifierData *md)
{
SimulationModifierData *smd = reinterpret_cast<SimulationModifierData *>(md);
- BLO_read_data_address(reader, &smd->data_path);
+ UNUSED_VARS(smd, reader);
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
const SimulationModifierData *smd = reinterpret_cast<const SimulationModifierData *>(md);
SimulationModifierData *tsmd = reinterpret_cast<SimulationModifierData *>(target);
+ UNUSED_VARS(smd, tsmd);
BKE_modifier_copydata_generic(md, target, flag);
- if (smd->data_path != nullptr) {
- tsmd->data_path = BLI_strdup(smd->data_path);
- }
}
static void freeData(ModifierData *md)
{
SimulationModifierData *smd = reinterpret_cast<SimulationModifierData *>(md);
- if (smd->data_path) {
- MEM_freeN(smd->data_path);
- }
+ UNUSED_VARS(smd);
}
ModifierTypeInfo modifierType_Simulation = {
/* name */ "Simulation",
/* structName */ "SimulationModifierData",
/* structSize */ sizeof(SimulationModifierData),
+#ifdef WITH_GEOMETRY_NODES
+ /* srna */ &RNA_SimulationModifier,
+#else
+ /* srna */ &RNA_Modifier,
+#endif
/* type */ eModifierTypeType_None,
/* flags */ (ModifierTypeFlag)0,
+ /* icon */ ICON_PHYSICS, /* TODO: Use correct icon. */
/* copyData */ copyData,
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* modifyMesh */ NULL,
- /* modifyHair */ NULL,
+ /* deformVerts */ nullptr,
+ /* deformMatrices */ nullptr,
+ /* deformVertsEM */ nullptr,
+ /* deformMatricesEM */ nullptr,
+ /* modifyMesh */ nullptr,
+ /* modifyHair */ nullptr,
/* modifyPointCloud */ modifyPointCloud,
- /* modifyVolume */ NULL,
+ /* modifyVolume */ nullptr,
- /* initData */ NULL,
- /* requiredDataMask */ NULL,
+ /* initData */ initData,
+ /* requiredDataMask */ nullptr,
/* freeData */ freeData,
/* isDisabled */ isDisabled,
/* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
+ /* dependsOnTime */ nullptr,
+ /* dependsOnNormals */ nullptr,
/* foreachIDLink */ foreachIDLink,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* foreachTexLink */ nullptr,
+ /* freeRuntimeData */ nullptr,
/* panelRegister */ panelRegister,
/* blendWrite */ blendWrite,
/* blendRead */ blendRead,
diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c
index f9d9e206914..6936f5a53f8 100644
--- a/source/blender/modifiers/intern/MOD_skin.c
+++ b/source/blender/modifiers/intern/MOD_skin.c
@@ -63,6 +63,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -802,7 +803,7 @@ static int calc_edge_subdivisions(const MVert *mvert,
const MEdge *e,
const int *degree)
{
- /* prevent memory errors [#38003] */
+ /* prevent memory errors T38003. */
#define NUM_SUBDIVISIONS_MAX 128
const MVertSkin *evs[2] = {&nodes[e->v1], &nodes[e->v2]};
@@ -997,8 +998,8 @@ static void add_poly(SkinOutput *so, BMVert *v1, BMVert *v2, BMVert *v3, BMVert
BMVert *verts[4] = {v1, v2, v3, v4};
BMFace *f;
- BLI_assert(v1 != v2 && v1 != v3 && v1 != v4);
- BLI_assert(v2 != v3 && v2 != v4);
+ BLI_assert(!ELEM(v1, v2, v3, v4));
+ BLI_assert(!ELEM(v2, v3, v4));
BLI_assert(v3 != v4);
BLI_assert(v1 && v2 && v3);
@@ -1413,7 +1414,7 @@ static void quad_from_tris(BMEdge *e, BMFace *adj[2], BMVert *ndx[4])
/* Find what the second tri has that the first doesn't */
for (i = 0; i < 3; i++) {
- if (tri[1][i] != tri[0][0] && tri[1][i] != tri[0][1] && tri[1][i] != tri[0][2]) {
+ if (!ELEM(tri[1][i], tri[0][0], tri[0][1], tri[0][2])) {
opp = tri[1][i];
break;
}
@@ -1759,13 +1760,19 @@ static bool skin_output_branch_hulls(
return result;
}
+typedef enum eSkinErrorFlag {
+ SKIN_ERROR_NO_VALID_ROOT = (1 << 0),
+ SKIN_ERROR_HULL = (1 << 1),
+} eSkinErrorFlag;
+
static BMesh *build_skin(SkinNode *skin_nodes,
int totvert,
const MeshElemMap *emap,
const MEdge *medge,
int totedge,
const MDeformVert *input_dvert,
- SkinModifierData *smd)
+ SkinModifierData *smd,
+ eSkinErrorFlag *r_error)
{
SkinOutput so;
int v;
@@ -1801,7 +1808,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)) {
- BKE_modifier_set_error(&smd->modifier, "Hull error");
+ *r_error |= SKIN_ERROR_HULL;
}
/* Merge triangles here in the hope of providing better target
@@ -1847,7 +1854,7 @@ static void skin_set_orig_indices(Mesh *mesh)
* 2) Generate node frames
* 3) Output vertices and polygons from frames, connections, and hulls
*/
-static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd)
+static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd, eSkinErrorFlag *r_error)
{
Mesh *result;
MVertSkin *nodes;
@@ -1877,16 +1884,14 @@ static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd)
MEM_freeN(emat);
emat = NULL;
- bm = build_skin(skin_nodes, totvert, emap, medge, totedge, dvert, smd);
+ bm = build_skin(skin_nodes, totvert, emap, medge, totedge, dvert, smd, r_error);
MEM_freeN(skin_nodes);
MEM_freeN(emap);
MEM_freeN(emapmem);
if (!has_valid_root) {
- BKE_modifier_set_error(
- &smd->modifier,
- "No valid root vertex found (you need one per mesh island you want to skin)");
+ *r_error |= SKIN_ERROR_NO_VALID_ROOT;
}
if (!bm) {
@@ -1903,7 +1908,7 @@ static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd)
return result;
}
-static Mesh *final_skin(SkinModifierData *smd, Mesh *mesh)
+static Mesh *final_skin(SkinModifierData *smd, Mesh *mesh, eSkinErrorFlag *r_error)
{
Mesh *result;
@@ -1913,7 +1918,7 @@ static Mesh *final_skin(SkinModifierData *smd, Mesh *mesh)
}
mesh = subdivide_base(mesh);
- result = base_skin(mesh, smd);
+ result = base_skin(mesh, smd, r_error);
BKE_id_free(NULL, mesh);
return result;
@@ -1925,19 +1930,33 @@ static void initData(ModifierData *md)
{
SkinModifierData *smd = (SkinModifierData *)md;
- /* Enable in editmode by default */
- md->mode |= eModifierMode_Editmode;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(smd, modifier));
+
+ MEMCPY_STRUCT_AFTER(smd, DNA_struct_default_get(SkinModifierData), modifier);
- smd->branch_smoothing = 0;
- smd->flag = 0;
- smd->symmetry_axes = MOD_SKIN_SYMM_X;
+ /* Enable in editmode by default. */
+ md->mode |= eModifierMode_Editmode;
}
-static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh)
+static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- Mesh *result;
+ eSkinErrorFlag error = 0;
+ Mesh *result = final_skin((SkinModifierData *)md, mesh, &error);
+
+ if (error & SKIN_ERROR_NO_VALID_ROOT) {
+ error &= ~SKIN_ERROR_NO_VALID_ROOT;
+ BKE_modifier_set_error(
+ ctx->object,
+ md,
+ "No valid root vertex found (you need one per mesh island you want to skin)");
+ }
+ if (error & SKIN_ERROR_HULL) {
+ error &= ~SKIN_ERROR_HULL;
+ BKE_modifier_set_error(ctx->object, md, "Hull error");
+ }
+ BLI_assert(error == 0);
- if (!(result = final_skin((SkinModifierData *)md, mesh))) {
+ if (result == NULL) {
return mesh;
}
return result;
@@ -2011,8 +2030,10 @@ ModifierTypeInfo modifierType_Skin = {
/* name */ "Skin",
/* structName */ "SkinModifierData",
/* structSize */ sizeof(SkinModifierData),
+ /* srna */ &RNA_SkinModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_MOD_SKIN,
/* copyData */ BKE_modifier_copydata_generic,
@@ -2032,7 +2053,6 @@ ModifierTypeInfo modifierType_Skin = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c
index 1939437d717..e73a59f1ae8 100644
--- a/source/blender/modifiers/intern/MOD_smooth.c
+++ b/source/blender/modifiers/intern/MOD_smooth.c
@@ -29,6 +29,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_screen_types.h"
@@ -55,10 +56,9 @@ static void initData(ModifierData *md)
{
SmoothModifierData *smd = (SmoothModifierData *)md;
- smd->fac = 0.5f;
- smd->repeat = 1;
- smd->flag = MOD_SMOOTH_X | MOD_SMOOTH_Y | MOD_SMOOTH_Z;
- smd->defgrp_name[0] = '\0';
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(smd, modifier));
+
+ MEMCPY_STRUCT_AFTER(smd, DNA_struct_default_get(SmoothModifierData), modifier);
}
static bool isDisabled(const struct Scene *UNUSED(scene),
@@ -272,9 +272,11 @@ ModifierTypeInfo modifierType_Smooth = {
/* name */ "Smooth",
/* structName */ "SmoothModifierData",
/* structSize */ sizeof(SmoothModifierData),
+ /* srna */ &RNA_SmoothModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs |
eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_MOD_SMOOTH,
/* copyData */ BKE_modifier_copydata_generic,
@@ -294,7 +296,6 @@ ModifierTypeInfo modifierType_Smooth = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_softbody.c b/source/blender/modifiers/intern/MOD_softbody.c
index e688ec8470c..4bdb3ba60b1 100644
--- a/source/blender/modifiers/intern/MOD_softbody.c
+++ b/source/blender/modifiers/intern/MOD_softbody.c
@@ -104,10 +104,12 @@ ModifierTypeInfo modifierType_Softbody = {
/* name */ "Softbody",
/* structName */ "SoftbodyModifierData",
/* structSize */ sizeof(SoftbodyModifierData),
+ /* srna */ &RNA_SoftBodyModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly |
eModifierTypeFlag_RequiresOriginalData | eModifierTypeFlag_Single |
eModifierTypeFlag_UsesPointCache,
+ /* icon */ ICON_MOD_SOFT,
/* copyData */ NULL,
@@ -127,7 +129,6 @@ ModifierTypeInfo modifierType_Softbody = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index 2c84def73b0..8886d3718c9 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -27,6 +27,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_screen_types.h"
@@ -44,10 +45,6 @@
#include "MOD_solidify_util.h"
-#ifdef __GNUC__
-# pragma GCC diagnostic error "-Wsign-conversion"
-#endif
-
static bool dependsOnNormals(ModifierData *md)
{
const SolidifyModifierData *smd = (SolidifyModifierData *)md;
@@ -60,16 +57,16 @@ static bool dependsOnNormals(ModifierData *md)
static void initData(ModifierData *md)
{
SolidifyModifierData *smd = (SolidifyModifierData *)md;
- smd->offset = 0.01f;
- smd->offset_fac = -1.0f;
- smd->flag = MOD_SOLIDIFY_RIM;
- 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;
+
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(smd, modifier));
+
+ MEMCPY_STRUCT_AFTER(smd, DNA_struct_default_get(SolidifyModifierData), modifier);
}
+#ifdef __GNUC__
+# pragma GCC diagnostic error "-Wsign-conversion"
+#endif
+
static void requiredDataMask(Object *UNUSED(ob),
ModifierData *md,
CustomData_MeshMasks *r_cddata_masks)
@@ -233,8 +230,9 @@ static void vertex_group_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropSep(layout, true);
col = uiLayoutColumn(layout, false);
- uiItemPointerR(col, ptr, "shell_vertex_group", &ob_ptr, "vertex_groups", "Shell", ICON_NONE);
- uiItemPointerR(col, ptr, "rim_vertex_group", &ob_ptr, "vertex_groups", "Rim", ICON_NONE);
+ uiItemPointerR(
+ col, ptr, "shell_vertex_group", &ob_ptr, "vertex_groups", IFACE_("Shell"), ICON_NONE);
+ uiItemPointerR(col, ptr, "rim_vertex_group", &ob_ptr, "vertex_groups", IFACE_("Rim"), ICON_NONE);
}
static void panelRegister(ARegionType *region_type)
@@ -260,11 +258,13 @@ ModifierTypeInfo modifierType_Solidify = {
/* name */ "Solidify",
/* structName */ "SolidifyModifierData",
/* structSize */ sizeof(SolidifyModifierData),
+ /* srna */ &RNA_SolidifyModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs |
eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode |
eModifierTypeFlag_EnableInEditmode,
+ /* icon */ ICON_MOD_SOLIDIFY,
/* copyData */ BKE_modifier_copydata_generic,
@@ -284,7 +284,6 @@ ModifierTypeInfo modifierType_Solidify = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.c b/source/blender/modifiers/intern/MOD_solidify_extrude.c
index 818327e120b..c8b357b34c8 100644
--- a/source/blender/modifiers/intern/MOD_solidify_extrude.c
+++ b/source/blender/modifiers/intern/MOD_solidify_extrude.c
@@ -59,7 +59,7 @@ BLI_INLINE void madd_v3v3short_fl(float r[3], const short a[3], const float f)
/** \name High Quality Normal Calculation Function
* \{ */
-/* skip shell thickness for non-manifold edges, see [#35710] */
+/* skip shell thickness for non-manifold edges, see T35710. */
#define USE_NONMANIFOLD_WORKAROUND
/* *** derived mesh high quality normal calculation function *** */
@@ -981,7 +981,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
MEM_freeN(vert_nors);
}
- /* must recalculate normals with vgroups since they can displace unevenly [#26888] */
+ /* must recalculate normals with vgroups since they can displace unevenly T26888. */
if ((mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) || do_rim || dvert) {
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
@@ -1004,23 +1004,23 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
&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 (dvert != NULL) {
+ 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 (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;
+ }
}
}
}
diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
index 1e0269617ec..8acf07f9181 100644
--- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
+++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
@@ -366,41 +366,73 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
if (edge_adj_faces_len[i] > 0) {
uint v1 = vm[ed->v1];
uint v2 = vm[ed->v2];
- if (v1 != v2) {
- 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 (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[v2];
- vert_adj_edges_len[v2] = 0;
- combined_verts[v1] += combined_verts[v2] + 1;
+ if (v1 == v2) {
+ continue;
+ }
- if (do_shell) {
- numNewLoops -= edge_adj_faces_len[i] * 2;
+ 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 (orig_edge_lengths[i] <= merge_tolerance_sqr) {
+ /* Merge verts. But first check if that would create a higher poly count. */
+ /* This check is very slow. It would need the vertex edge links to get
+ * accelerated that are not yet available at this point. */
+ bool can_merge = true;
+ for (uint k = 0; k < numEdges && can_merge; k++) {
+ if (k != i && edge_adj_faces_len[k] > 0 &&
+ (ELEM(vm[orig_medge[k].v1], v1, v2) != ELEM(vm[orig_medge[k].v2], v1, v2))) {
+ for (uint j = 0; j < edge_adj_faces[k]->faces_len && can_merge; j++) {
+ mp = orig_mpoly + edge_adj_faces[k]->faces[j];
+ uint changes = 0;
+ int cur = mp->totloop - 1;
+ for (int next = 0; next < mp->totloop && changes <= 2; next++) {
+ uint cur_v = vm[orig_mloop[mp->loopstart + cur].v];
+ uint next_v = vm[orig_mloop[mp->loopstart + next].v];
+ changes += (ELEM(cur_v, v1, v2) != ELEM(next_v, v1, v2));
+ cur = next;
+ }
+ can_merge = can_merge && changes <= 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]);
+
+ if (!can_merge) {
+ orig_edge_lengths[i] = 0.0f;
vert_adj_edges_len[v1]++;
vert_adj_edges_len[v2]++;
+ continue;
}
+
+ 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[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]++;
}
}
}
@@ -619,7 +651,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
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) {
+ if (e_adj_faces_faces != adj_faces->faces) {
/* Find index of e in #adj_faces. */
for (face_index = 0;
face_index < faces_len && e_adj_faces_faces[face_index] != face;
@@ -684,8 +716,49 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(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_co[v2], orig_mvert_co[v1]);
- mul_v3_fl(edgedir, 1.0f / orig_edge_lengths[i]);
+ if (LIKELY(orig_edge_lengths[i] > FLT_EPSILON)) {
+ sub_v3_v3v3(edgedir, orig_mvert_co[v2], orig_mvert_co[v1]);
+ mul_v3_fl(edgedir, 1.0f / orig_edge_lengths[i]);
+ }
+ else {
+ /* Smart fallback. */
+ /* This makes merging non essential, but correct
+ * merging will still give way better results. */
+ float pos[3];
+ copy_v3_v3(pos, orig_mvert_co[v2]);
+
+ OldVertEdgeRef *link1 = vert_adj_edges[v1];
+ float v1_dir[3];
+ zero_v3(v1_dir);
+ for (int j = 0; j < link1->edges_len; j++) {
+ uint e = link1->edges[j];
+ if (edge_adj_faces_len[e] > 0 && e != i) {
+ uint other_v =
+ vm[vm[orig_medge[e].v1] == v1 ? orig_medge[e].v2 : orig_medge[e].v1];
+ sub_v3_v3v3(edgedir, orig_mvert_co[other_v], pos);
+ add_v3_v3(v1_dir, edgedir);
+ }
+ }
+ OldVertEdgeRef *link2 = vert_adj_edges[v2];
+ float v2_dir[3];
+ zero_v3(v2_dir);
+ for (int j = 0; j < link2->edges_len; j++) {
+ uint e = link2->edges[j];
+ if (edge_adj_faces_len[e] > 0 && e != i) {
+ uint other_v =
+ vm[vm[orig_medge[e].v1] == v2 ? orig_medge[e].v2 : orig_medge[e].v1];
+ sub_v3_v3v3(edgedir, orig_mvert_co[other_v], pos);
+ add_v3_v3(v2_dir, edgedir);
+ }
+ }
+ sub_v3_v3v3(edgedir, v2_dir, v1_dir);
+ float len = normalize_v3(edgedir);
+ if (len == 0.0f) {
+ edgedir[0] = 0.0f;
+ edgedir[1] = 0.0f;
+ edgedir[2] = 1.0f;
+ }
+ }
OldEdgeFaceRef *adj_faces = edge_adj_faces[i];
const uint adj_len = adj_faces->faces_len;
@@ -1327,6 +1400,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
scalar_vgroup = min_ff(BKE_defvert_find_weight(dv, defgrp_index), scalar_vgroup);
}
}
+ scalar_vgroup = offset_fac_vg + (scalar_vgroup * offset_fac_vg_inv);
face_weight[i] = scalar_vgroup;
}
}
@@ -2189,8 +2263,10 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
NewEdgeRef *edge1 = new_edges[0];
NewEdgeRef *edge2 = new_edges[1];
- const bool v1_singularity = edge1->link_edge_groups[0]->is_singularity;
- const bool v2_singularity = edge1->link_edge_groups[1]->is_singularity;
+ const bool v1_singularity = edge1->link_edge_groups[0]->is_singularity &&
+ edge2->link_edge_groups[0]->is_singularity;
+ const bool v2_singularity = edge1->link_edge_groups[1]->is_singularity &&
+ edge2->link_edge_groups[1]->is_singularity;
if (v1_singularity && v2_singularity) {
continue;
}
@@ -2391,7 +2467,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(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 + (fr->reversed ? mat_ofs : 0);
+ mpoly[poly_index].mat_nr = fr->face->mat_nr + (fr->reversed != do_flip ? 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) {
@@ -2425,16 +2501,25 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
MEM_freeN(face_edges);
}
if (edge_index != numNewEdges) {
- BKE_modifier_set_error(
- md, "Internal Error: edges array wrong size: %u instead of %u", numNewEdges, edge_index);
+ BKE_modifier_set_error(ctx->object,
+ md,
+ "Internal Error: edges array wrong size: %u instead of %u",
+ numNewEdges,
+ edge_index);
}
if (poly_index != numNewPolys) {
- BKE_modifier_set_error(
- md, "Internal Error: polys array wrong size: %u instead of %u", numNewPolys, poly_index);
+ BKE_modifier_set_error(ctx->object,
+ md,
+ "Internal Error: polys array wrong size: %u instead of %u",
+ numNewPolys,
+ poly_index);
}
if (loop_index != numNewLoops) {
- BKE_modifier_set_error(
- md, "Internal Error: loops array wrong size: %u instead of %u", numNewLoops, loop_index);
+ BKE_modifier_set_error(ctx->object,
+ md,
+ "Internal Error: loops array wrong size: %u instead of %u",
+ numNewLoops,
+ loop_index);
}
BLI_assert(edge_index == numNewEdges);
BLI_assert(poly_index == numNewPolys);
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c
index 1972f857877..1aa015682dd 100644
--- a/source/blender/modifiers/intern/MOD_subsurf.c
+++ b/source/blender/modifiers/intern/MOD_subsurf.c
@@ -30,6 +30,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -71,11 +72,9 @@ static void initData(ModifierData *md)
{
SubsurfModifierData *smd = (SubsurfModifierData *)md;
- smd->levels = 1;
- smd->renderLevels = 2;
- smd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
- smd->quality = 3;
- smd->flags |= (eSubsurfModifierFlag_UseCrease | eSubsurfModifierFlag_ControlEdges);
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(smd, modifier));
+
+ MEMCPY_STRUCT_AFTER(smd, DNA_struct_default_get(SubsurfModifierData), modifier);
}
static void requiredDataMask(Object *UNUSED(ob),
@@ -154,13 +153,21 @@ static int subdiv_levels_for_modifier_get(const SubsurfModifierData *smd,
return get_render_subsurf_level(&scene->r, requested_levels, use_render_params);
}
-static void subdiv_settings_init(SubdivSettings *settings, const SubsurfModifierData *smd)
+static void subdiv_settings_init(SubdivSettings *settings,
+ const SubsurfModifierData *smd,
+ const ModifierEvalContext *ctx)
{
+ const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER);
+ const int requested_levels = (use_render_params) ? smd->renderLevels : smd->levels;
+
settings->is_simple = (smd->subdivType == SUBSURF_TYPE_SIMPLE);
- settings->is_adaptive = true;
- settings->level = settings->is_simple ? 1 : smd->quality;
+ settings->is_adaptive = !(smd->flags & eSubsurfModifierFlag_UseRecursiveSubdivision);
+ settings->level = settings->is_simple ?
+ 1 :
+ (settings->is_adaptive ? smd->quality : requested_levels);
settings->use_creases = (smd->flags & eSubsurfModifierFlag_UseCrease);
- settings->vtx_boundary_interpolation = SUBDIV_VTX_BOUNDARY_EDGE_ONLY;
+ settings->vtx_boundary_interpolation = BKE_subdiv_vtx_boundary_interpolation_from_subsurf(
+ smd->boundary_smooth);
settings->fvar_linear_interpolation = BKE_subdiv_fvar_interpolation_from_uv_smooth(
smd->uv_smooth);
}
@@ -247,16 +254,15 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
{
Mesh *result = mesh;
#if !defined(WITH_OPENSUBDIV)
- BKE_modifier_set_error(md, "Disabled, built without OpenSubdiv");
+ BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv");
return result;
#endif
SubsurfModifierData *smd = (SubsurfModifierData *)md;
SubdivSettings subdiv_settings;
- subdiv_settings_init(&subdiv_settings, smd);
+ subdiv_settings_init(&subdiv_settings, smd, ctx);
if (subdiv_settings.level == 0) {
return result;
}
- BKE_subdiv_settings_validate_for_mesh(&subdiv_settings, mesh);
SubsurfRuntimeData *runtime_data = subsurf_ensure_runtime(smd);
Subdiv *subdiv = subdiv_descriptor_ensure(smd, &subdiv_settings, mesh);
if (subdiv == NULL) {
@@ -296,14 +302,14 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
static void deformMatrices(ModifierData *md,
- const ModifierEvalContext *UNUSED(ctx),
+ const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertex_cos)[3],
float (*deform_matrices)[3][3],
int num_verts)
{
#if !defined(WITH_OPENSUBDIV)
- BKE_modifier_set_error(md, "Disabled, built without OpenSubdiv");
+ BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv");
return;
#endif
@@ -312,11 +318,10 @@ static void deformMatrices(ModifierData *md,
SubsurfModifierData *smd = (SubsurfModifierData *)md;
SubdivSettings subdiv_settings;
- subdiv_settings_init(&subdiv_settings, smd);
+ subdiv_settings_init(&subdiv_settings, smd, ctx);
if (subdiv_settings.level == 0) {
return;
}
- BKE_subdiv_settings_validate_for_mesh(&subdiv_settings, mesh);
SubsurfRuntimeData *runtime_data = subsurf_ensure_runtime(smd);
Subdiv *subdiv = subdiv_descriptor_ensure(smd, &subdiv_settings, mesh);
if (subdiv == NULL) {
@@ -345,6 +350,11 @@ static bool get_show_adaptive_options(const bContext *C, Panel *panel)
return false;
}
+ /* Don't show adaptive options if regular subdivision used*/
+ if (!RNA_boolean_get(ptr, "use_limit_surface")) {
+ return false;
+ }
+
/* Don't show adaptive options if the cycles experimental feature set is disabled. */
Scene *scene = CTX_data_scene(C);
PointerRNA scene_ptr;
@@ -452,8 +462,14 @@ static void advanced_panel_draw(const bContext *C, Panel *panel)
uiLayoutSetPropSep(layout, true);
uiLayoutSetActive(layout, !(show_adaptive_options && ob_use_adaptive_subdivision));
- uiItemR(layout, ptr, "quality", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_limit_surface", 0, NULL, ICON_NONE);
+
+ uiLayout *col = uiLayoutColumn(layout, true);
+ uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_limit_surface"));
+ uiItemR(col, ptr, "quality", 0, NULL, ICON_NONE);
+
uiItemR(layout, ptr, "uv_smooth", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "boundary_smooth", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "use_creases", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "use_custom_normals", 0, NULL, ICON_NONE);
}
@@ -476,10 +492,12 @@ ModifierTypeInfo modifierType_Subsurf = {
/* name */ "Subdivision",
/* structName */ "SubsurfModifierData",
/* structSize */ sizeof(SubsurfModifierData),
+ /* srna */ &RNA_SubsurfModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode |
eModifierTypeFlag_AcceptsCVs,
+ /* icon */ ICON_MOD_SUBSURF,
/* copyData */ copyData,
@@ -499,7 +517,6 @@ ModifierTypeInfo modifierType_Subsurf = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ freeRuntimeData,
diff --git a/source/blender/modifiers/intern/MOD_surface.c b/source/blender/modifiers/intern/MOD_surface.c
index a20ba3f899e..72f19efe3a4 100644
--- a/source/blender/modifiers/intern/MOD_surface.c
+++ b/source/blender/modifiers/intern/MOD_surface.c
@@ -27,6 +27,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -59,10 +60,9 @@ static void initData(ModifierData *md)
{
SurfaceModifierData *surmd = (SurfaceModifierData *)md;
- surmd->bvhtree = NULL;
- surmd->mesh = NULL;
- surmd->x = NULL;
- surmd->v = NULL;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(surmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(surmd, DNA_struct_default_get(SurfaceModifierData), modifier);
}
static void copyData(const ModifierData *md_src, ModifierData *md_dst, const int flag)
@@ -126,7 +126,7 @@ static void deformVerts(ModifierData *md,
if (mesh) {
/* Not possible to use get_mesh() in this case as we'll modify its vertices
* and get_mesh() would return 'mesh' directly. */
- BKE_id_copy_ex(NULL, (ID *)mesh, (ID **)&surmd->mesh, LIB_ID_COPY_LOCALIZE);
+ surmd->mesh = (Mesh *)BKE_id_copy_ex(NULL, (ID *)mesh, NULL, LIB_ID_COPY_LOCALIZE);
}
else {
surmd->mesh = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, NULL, numVerts, false, false);
@@ -226,9 +226,11 @@ ModifierTypeInfo modifierType_Surface = {
/* name */ "Surface",
/* structName */ "SurfaceModifierData",
/* structSize */ sizeof(SurfaceModifierData),
+ /* srna */ &RNA_SurfaceModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs |
eModifierTypeFlag_NoUserAdd,
+ /* icon */ ICON_MOD_PHYSICS,
/* copyData */ copyData,
@@ -248,7 +250,6 @@ ModifierTypeInfo modifierType_Surface = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index 6fc2bd29add..5407397e3bf 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -26,6 +26,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -69,6 +70,9 @@ typedef struct SDefAdjacencyArray {
uint num; /* Careful, this is twice the number of polygons (avoids an extra loop) */
} SDefAdjacencyArray;
+/**
+ * Polygons per edge (only 2, any more will exit calculation).
+ */
typedef struct SDefEdgePolys {
uint polys[2], num;
} SDefEdgePolys;
@@ -82,37 +86,67 @@ typedef struct SDefBindCalcData {
const MPoly *const mpoly;
const MEdge *const medge;
const MLoop *const mloop;
+ /** Coordinates to bind to, transformed into local space (compatible with `vertexCos`). */
float (*const targetCos)[3];
+ /** Coordinates to bind (reference to the modifiers input argument). */
float (*const vertexCos)[3];
float imat[4][4];
const float falloff;
int success;
} SDefBindCalcData;
+/**
+ * This represents the relationship between a point (a source coordinate)
+ * and the face-corner it's being bound to (from the target mesh).
+ *
+ * \note Some of these values could be de-duplicated however these are only
+ * needed once when running bind, so optimizing this structure isn't a priority.
+ */
typedef struct SDefBindPoly {
+ /** Coordinates copied directly from the modifiers inptut. */
float (*coords)[3];
+ /** Coordinates projected into 2D space using `normal`. */
float (*coords_v2)[2];
+ /** The point being queried projected into 2D space using `normal`. */
float point_v2[2];
float weight_angular;
float weight_dist_proj;
float weight_dist;
float weight;
float scales[2];
+ /** Center of `coords` */
float centroid[3];
+ /** Center of `coords_v2` */
float centroid_v2[2];
+ /**
+ * The calculated normal of coords (could be shared between faces).
+ */
float normal[3];
float cent_edgemid_vecs_v2[2][2];
+ /**
+ * The unsigned angle of this face-corner in `[0.0 .. PI]` range,
+ * where a small value is a thin corner. PI is is a straight line.
+ * Take care dividing by this value as it can approach zero.
+ */
float edgemid_angle;
float point_edgemid_angles[2];
float corner_edgemid_angles[2];
float dominant_angle_weight;
+ /** Index of the input polygon. */
uint index;
+ /** Number of vertices in this face. */
uint numverts;
+ /**
+ * This polygons loop-start.
+ * \note that we could look this up from the polygon.
+ */
uint loopstart;
uint edge_inds[2];
uint edge_vert_inds[2];
+ /** The index of this corner in the face (starting at zero). */
uint corner_ind;
uint dominant_edge;
+ /** When true `point_v2` is inside `coords_v2`. */
bool inside;
} SDefBindPoly;
@@ -150,11 +184,10 @@ enum {
static void initData(ModifierData *md)
{
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
- smd->target = NULL;
- smd->verts = NULL;
- smd->flags = 0;
- smd->falloff = 4.0f;
- smd->strength = 1.0f;
+
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(smd, modifier));
+
+ MEMCPY_STRUCT_AFTER(smd, DNA_struct_default_get(SurfaceDeformModifierData), modifier);
}
static void requiredDataMask(Object *UNUSED(ob),
@@ -218,11 +251,11 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla
}
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
- walk(userData, ob, &smd->target, IDWALK_NOP);
+ walk(userData, ob, (ID **)&smd->target, IDWALK_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
@@ -256,7 +289,7 @@ static int buildAdjacencyMap(const MPoly *poly,
{
const MLoop *loop;
- /* Fing polygons adjacent to edges */
+ /* Find polygons adjacent to edges. */
for (int i = 0; i < numpoly; i++, poly++) {
loop = &mloop[poly->loopstart];
@@ -424,15 +457,9 @@ static void freeBindData(SDefBindWeightData *const bwdata)
MEM_freeN(bwdata);
}
-BLI_INLINE float computeAngularWeight(const float point_angle, const float edgemid_angle)
+BLI_INLINE float computeAngularWeight(const float point_angle)
{
- float weight;
-
- weight = point_angle;
- weight /= edgemid_angle;
- weight *= M_PI_2;
-
- return sinf(weight);
+ return sinf(point_angle * M_PI_2);
}
BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
@@ -472,7 +499,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
bwdata->bind_polys = bpoly;
/* Loop over all adjacent edges,
- * and build the SDefBindPoly data for each poly adjacent to those. */
+ * and build the #SDefBindPoly data for each poly adjacent to those. */
for (vedge = vert_edges; vedge; vedge = vedge->next) {
uint edge_ind = vedge->index;
@@ -481,7 +508,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
bpoly = bwdata->bind_polys;
for (int j = 0; j < bwdata->numpoly; bpoly++, j++) {
- /* If coords isn't allocated, we have reached the first uninitialized bpoly */
+ /* If coords isn't allocated, we have reached the first uninitialized `bpoly`. */
if ((bpoly->index == edge_polys[edge_ind].polys[i]) || (!bpoly->coords)) {
break;
}
@@ -536,7 +563,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
}
}
- /* Compute poly's parametric data */
+ /* Compute polygons parametric data. */
mid_v3_v3_array(bpoly->centroid, bpoly->coords, poly->totloop);
normal_poly_v3(bpoly->normal, bpoly->coords, poly->totloop);
@@ -546,7 +573,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
cross_v3_v3v3(axis, bpoly->normal, world);
normalize_v3(axis);
- /* Map coords onto 2d normal plane */
+ /* Map coords onto 2d normal plane. */
map_to_plane_axis_angle_v2_v3v3fl(bpoly->point_v2, point_co, axis, angle);
zero_v2(bpoly->centroid_v2);
@@ -601,7 +628,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
bpoly->corner_edgemid_angles[1] = angle_normalized_v2v2(tmp_vec_v2,
bpoly->cent_edgemid_vecs_v2[1]);
- /* Check for inifnite weights, and compute angular data otherwise */
+ /* Check for infinite weights, and compute angular data otherwise. */
if (bpoly->weight_dist < FLT_EPSILON) {
inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ;
inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST;
@@ -658,15 +685,12 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
/* Compute angular weight component */
if (epolys->num == 1) {
- ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]],
- bpolys[0]->edgemid_angle);
+ ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]]);
bpolys[0]->weight_angular *= ang_weights[0] * ang_weights[0];
}
else if (epolys->num == 2) {
- ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]],
- bpolys[0]->edgemid_angle);
- ang_weights[1] = computeAngularWeight(bpolys[1]->point_edgemid_angles[edge_on_poly[1]],
- bpolys[1]->edgemid_angle);
+ ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]]);
+ ang_weights[1] = computeAngularWeight(bpolys[1]->point_edgemid_angles[edge_on_poly[1]]);
bpolys[0]->weight_angular *= ang_weights[0] * ang_weights[1];
bpolys[1]->weight_angular *= ang_weights[0] * ang_weights[1];
@@ -674,10 +698,10 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
}
}
- /* Compute scalings and falloff.
- * Scale all weights if no infinite weight is found,
- * scale only unprojected weight if projected weight is infinite,
- * scale none if both are infinite. */
+ /* Compute scaling and falloff:
+ * - Scale all weights if no infinite weight is found.
+ * - Scale only un-projected weight if projected weight is infinite.
+ * - Scale none if both are infinite. */
if (!inf_weight_flags) {
bpoly = bwdata->bind_polys;
@@ -707,9 +731,14 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
bpoly->dominant_angle_weight = sinf(bpoly->dominant_angle_weight * M_PI_2);
/* Compute quadratic angular scale interpolation weight */
- scale_weight = bpoly->point_edgemid_angles[bpoly->dominant_edge] / bpoly->edgemid_angle;
- scale_weight /= scale_weight +
- (bpoly->point_edgemid_angles[!bpoly->dominant_edge] / bpoly->edgemid_angle);
+ {
+ const float edge_angle_a = bpoly->point_edgemid_angles[bpoly->dominant_edge];
+ const float edge_angle_b = bpoly->point_edgemid_angles[!bpoly->dominant_edge];
+ /* Clamp so skinny faces with near zero `edgemid_angle`
+ * won't cause numeric problems. see T81988. */
+ scale_weight = edge_angle_a / max_ff(edge_angle_a, bpoly->edgemid_angle);
+ scale_weight /= scale_weight + (edge_angle_b / max_ff(edge_angle_b, bpoly->edgemid_angle));
+ }
sqr = scale_weight * scale_weight;
inv_sqr = 1.0f - scale_weight;
@@ -776,6 +805,11 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
bpoly->weight = 1.0f / bpoly->weight_angular / bpoly->weight_dist_proj / bpoly->weight_dist;
}
+ /* Apply after other kinds of scaling so the faces corner angle is always
+ * scaled in a uniform way, preventing heavily sub-divided triangle fans
+ * from having a lop-sided influence on the weighting, see T81988. */
+ bpoly->weight *= bpoly->edgemid_angle / M_PI;
+
tot_weight += bpoly->weight;
}
@@ -891,7 +925,7 @@ static void bindVert(void *__restrict userdata,
interp_weights_poly_v2(
sdbind->vert_weights, bpoly->coords_v2, bpoly->numverts, bpoly->point_v2);
- /* Reproject vert based on weights and original poly verts,
+ /* Re-project vert based on weights and original poly verts,
* to reintroduce poly non-planarity */
zero_v3(point_co_proj);
for (int j = 0; j < bpoly->numverts; j++, loop++) {
@@ -1009,7 +1043,8 @@ static void bindVert(void *__restrict userdata,
freeBindData(bwdata);
}
-static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig,
+static bool surfacedeformBind(Object *ob,
+ SurfaceDeformModifierData *smd_orig,
SurfaceDeformModifierData *smd_eval,
float (*vertexCos)[3],
uint numverts,
@@ -1030,20 +1065,20 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig,
vert_edges = MEM_calloc_arrayN(tnumverts, sizeof(*vert_edges), "SDefVertEdgeMap");
if (vert_edges == NULL) {
- BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory");
+ BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory");
return false;
}
adj_array = MEM_malloc_arrayN(tnumedges, 2 * sizeof(*adj_array), "SDefVertEdge");
if (adj_array == NULL) {
- BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory");
+ BKE_modifier_set_error(ob, (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) {
- BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory");
+ BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory");
MEM_freeN(vert_edges);
MEM_freeN(adj_array);
return false;
@@ -1051,14 +1086,14 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig,
smd_orig->verts = MEM_malloc_arrayN(numverts, sizeof(*smd_orig->verts), "SDefBindVerts");
if (smd_orig->verts == NULL) {
- BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory");
+ BKE_modifier_set_error(ob, (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) {
- BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory");
+ BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory");
freeAdjacencyMap(vert_edges, adj_array, edge_polys);
MEM_freeN(smd_orig->verts);
smd_orig->verts = NULL;
@@ -1069,8 +1104,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) {
- BKE_modifier_set_error((ModifierData *)smd_eval,
- "Target has edges with more than two polygons");
+ BKE_modifier_set_error(
+ ob, (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);
@@ -1097,7 +1132,7 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig,
};
if (data.targetCos == NULL) {
- BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory");
+ BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory");
freeData((ModifierData *)smd_orig);
return false;
}
@@ -1116,20 +1151,20 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig,
MEM_freeN(data.targetCos);
if (data.success == MOD_SDEF_BIND_RESULT_MEM_ERR) {
- BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory");
+ BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory");
freeData((ModifierData *)smd_orig);
}
else if (data.success == MOD_SDEF_BIND_RESULT_NONMANY_ERR) {
- BKE_modifier_set_error((ModifierData *)smd_eval,
- "Target has edges with more than two polygons");
+ BKE_modifier_set_error(
+ ob, (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) {
- BKE_modifier_set_error((ModifierData *)smd_eval, "Target contains concave polygons");
+ BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Target contains concave polygons");
freeData((ModifierData *)smd_orig);
}
else if (data.success == MOD_SDEF_BIND_RESULT_OVERLAP_ERR) {
- BKE_modifier_set_error((ModifierData *)smd_eval, "Target contains overlapping vertices");
+ BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Target contains overlapping vertices");
freeData((ModifierData *)smd_orig);
}
else if (data.success == MOD_SDEF_BIND_RESULT_GENERIC_ERR) {
@@ -1137,7 +1172,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 */
- BKE_modifier_set_error((ModifierData *)smd_eval, "Target contains invalid polygons");
+ BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Target contains invalid polygons");
freeData((ModifierData *)smd_orig);
}
@@ -1234,7 +1269,7 @@ static void surfacedeformModifier_do(ModifierData *md,
if (!(smd->flags & MOD_SDEF_BIND)) {
if (smd->verts != NULL) {
if (!DEG_is_active(ctx->depsgraph)) {
- BKE_modifier_set_error(md, "Attempt to bind from inactive dependency graph");
+ BKE_modifier_set_error(ob, md, "Attempt to bind from inactive dependency graph");
return;
}
ModifierData *md_orig = BKE_modifier_get_original(md);
@@ -1246,7 +1281,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) {
- BKE_modifier_set_error(md, "No valid target mesh");
+ BKE_modifier_set_error(ob, md, "No valid target mesh");
return;
}
@@ -1256,7 +1291,7 @@ static void surfacedeformModifier_do(ModifierData *md,
/* If not bound, execute bind. */
if (smd->verts == NULL) {
if (!DEG_is_active(ctx->depsgraph)) {
- BKE_modifier_set_error(md, "Attempt to unbind from inactive dependency graph");
+ BKE_modifier_set_error(ob, md, "Attempt to unbind from inactive dependency graph");
return;
}
@@ -1270,7 +1305,7 @@ static void surfacedeformModifier_do(ModifierData *md,
/* Avoid converting edit-mesh data, binding is an exception. */
BKE_mesh_wrapper_ensure_mdata(target);
- if (!surfacedeformBind(smd_orig, smd, vertexCos, numverts, tnumpoly, tnumverts, target)) {
+ if (!surfacedeformBind(ob, smd_orig, smd, vertexCos, numverts, tnumpoly, tnumverts, target)) {
smd->flags &= ~MOD_SDEF_BIND;
}
/* Early abort, this is binding 'call', no need to perform whole evaluation. */
@@ -1279,17 +1314,17 @@ static void surfacedeformModifier_do(ModifierData *md,
/* Poly count checks */
if (smd->numverts != numverts) {
- BKE_modifier_set_error(md, "Vertices changed from %u to %u", smd->numverts, numverts);
+ BKE_modifier_set_error(ob, md, "Vertices changed from %u to %u", smd->numverts, numverts);
return;
}
if (smd->numpoly != tnumpoly) {
- BKE_modifier_set_error(md, "Target polygons changed from %u to %u", smd->numpoly, tnumpoly);
+ BKE_modifier_set_error(
+ ob, 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.
- */
+ /* 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;
}
@@ -1453,8 +1488,7 @@ static void blendWrite(BlendWriter *writer, const ModifierData *md)
BLO_write_uint32_array(
writer, smd->verts[i].binds[j].numverts, smd->verts[i].binds[j].vert_inds);
- if (smd->verts[i].binds[j].mode == MOD_SDEF_MODE_CENTROID ||
- smd->verts[i].binds[j].mode == MOD_SDEF_MODE_LOOPTRI) {
+ if (ELEM(smd->verts[i].binds[j].mode, MOD_SDEF_MODE_CENTROID, MOD_SDEF_MODE_LOOPTRI)) {
BLO_write_float3_array(writer, 1, smd->verts[i].binds[j].vert_weights);
}
else {
@@ -1482,8 +1516,7 @@ static void blendRead(BlendDataReader *reader, ModifierData *md)
BLO_read_uint32_array(
reader, smd->verts[i].binds[j].numverts, &smd->verts[i].binds[j].vert_inds);
- if (smd->verts[i].binds[j].mode == MOD_SDEF_MODE_CENTROID ||
- smd->verts[i].binds[j].mode == MOD_SDEF_MODE_LOOPTRI) {
+ if (ELEM(smd->verts[i].binds[j].mode, MOD_SDEF_MODE_CENTROID, MOD_SDEF_MODE_LOOPTRI)) {
BLO_read_float3_array(reader, 1, &smd->verts[i].binds[j].vert_weights);
}
else {
@@ -1500,8 +1533,10 @@ ModifierTypeInfo modifierType_SurfaceDeform = {
/* name */ "SurfaceDeform",
/* structName */ "SurfaceDeformModifierData",
/* structSize */ sizeof(SurfaceDeformModifierData),
+ /* srna */ &RNA_SurfaceDeformModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_MOD_MESHDEFORM,
/* copyData */ copyData,
@@ -1521,8 +1556,7 @@ ModifierTypeInfo modifierType_SurfaceDeform = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
/* panelRegister */ panelRegister,
diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c
index 87ca067fba9..5a07c4e5e64 100644
--- a/source/blender/modifiers/intern/MOD_triangulate.c
+++ b/source/blender/modifiers/intern/MOD_triangulate.c
@@ -18,12 +18,15 @@
* \ingroup modifiers
*/
+#include <string.h>
+
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -107,11 +110,12 @@ static void initData(ModifierData *md)
{
TriangulateModifierData *tmd = (TriangulateModifierData *)md;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(tmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(tmd, DNA_struct_default_get(TriangulateModifierData), modifier);
+
/* Enable in editmode by default */
md->mode |= eModifierMode_Editmode;
- tmd->quad_method = MOD_TRIANGULATE_QUAD_SHORTEDGE;
- tmd->ngon_method = MOD_TRIANGULATE_NGON_BEAUTY;
- tmd->min_vertices = 4;
}
static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh)
@@ -152,10 +156,12 @@ ModifierTypeInfo modifierType_Triangulate = {
/* name */ "Triangulate",
/* structName */ "TriangulateModifierData",
/* structSize */ sizeof(TriangulateModifierData),
+ /* srna */ &RNA_TriangulateModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode |
eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_EnableInEditmode |
eModifierTypeFlag_AcceptsCVs,
+ /* icon */ ICON_MOD_TRIANGULATE,
/* copyData */ BKE_modifier_copydata_generic,
@@ -175,7 +181,6 @@ ModifierTypeInfo modifierType_Triangulate = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_ui_common.c b/source/blender/modifiers/intern/MOD_ui_common.c
index a79e270af93..ba43434aeb3 100644
--- a/source/blender/modifiers/intern/MOD_ui_common.c
+++ b/source/blender/modifiers/intern/MOD_ui_common.c
@@ -17,9 +17,8 @@
* \ingroup modifiers
*/
-#include <string.h>
-
#include "BLI_listbase.h"
+#include "BLI_string.h"
#include "MEM_guardedalloc.h"
@@ -230,14 +229,14 @@ static void modifier_ops_extra_draw(bContext *C, uiLayout *layout, void *md_v)
/* Apply as shapekey. */
if (BKE_modifier_is_same_topology(md) && !BKE_modifier_is_non_geometrical(md)) {
uiItemBooleanO(layout,
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply As Shapekey"),
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply as Shape Key"),
ICON_SHAPEKEY_DATA,
"OBJECT_OT_modifier_apply_as_shapekey",
"keep_modifier",
false);
uiItemBooleanO(layout,
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Save As Shapekey"),
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Save as Shape Key"),
ICON_SHAPEKEY_DATA,
"OBJECT_OT_modifier_apply_as_shapekey",
"keep_modifier",
@@ -406,10 +405,10 @@ PanelType *modifier_panel_register(ARegionType *region_type, ModifierType type,
PanelType *panel_type = MEM_callocN(sizeof(PanelType), panel_idname);
- strcpy(panel_type->idname, panel_idname);
- strcpy(panel_type->label, "");
- strcpy(panel_type->context, "modifier");
- strcpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ BLI_strncpy(panel_type->idname, panel_idname, BKE_ST_MAXNAME);
+ BLI_strncpy(panel_type->label, "", BKE_ST_MAXNAME);
+ BLI_strncpy(panel_type->context, "modifier", BKE_ST_MAXNAME);
+ BLI_strncpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA, BKE_ST_MAXNAME);
panel_type->draw_header = modifier_panel_header;
panel_type->draw = draw;
@@ -442,16 +441,14 @@ PanelType *modifier_subpanel_register(ARegionType *region_type,
{
/* Create the subpanel's ID name. */
char panel_idname[BKE_ST_MAXNAME];
- strcpy(panel_idname, parent->idname);
- strcat(panel_idname, "_");
- strcat(panel_idname, name);
+ BLI_snprintf(panel_idname, BKE_ST_MAXNAME, "%s_%s", parent->idname, name);
PanelType *panel_type = MEM_callocN(sizeof(PanelType), panel_idname);
- strcpy(panel_type->idname, panel_idname);
- strcpy(panel_type->label, label);
- strcpy(panel_type->context, "modifier");
- strcpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ BLI_strncpy(panel_type->idname, panel_idname, BKE_ST_MAXNAME);
+ BLI_strncpy(panel_type->label, label, BKE_ST_MAXNAME);
+ BLI_strncpy(panel_type->context, "modifier", BKE_ST_MAXNAME);
+ BLI_strncpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA, BKE_ST_MAXNAME);
panel_type->draw_header = draw_header;
panel_type->draw = draw;
@@ -459,7 +456,7 @@ PanelType *modifier_subpanel_register(ARegionType *region_type,
panel_type->flag = (PNL_DEFAULT_CLOSED | PNL_DRAW_BOX);
BLI_assert(parent != NULL);
- strcpy(panel_type->parent_id, parent->idname);
+ BLI_strncpy(panel_type->parent_id, parent->idname, BKE_ST_MAXNAME);
panel_type->parent = parent;
BLI_addtail(&parent->children, BLI_genericNodeN(panel_type));
BLI_addtail(&region_type->paneltypes, panel_type);
diff --git a/source/blender/modifiers/intern/MOD_ui_common.h b/source/blender/modifiers/intern/MOD_ui_common.h
index 24ada426635..e7f801049b8 100644
--- a/source/blender/modifiers/intern/MOD_ui_common.h
+++ b/source/blender/modifiers/intern/MOD_ui_common.h
@@ -30,8 +30,8 @@ extern "C" {
#endif
struct ARegionType;
-struct bContext;
struct PanelType;
+struct bContext;
struct uiLayout;
typedef void (*PanelDrawFn)(const bContext *, struct Panel *);
diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c
index cc844e53603..e0802dc5fb4 100644
--- a/source/blender/modifiers/intern/MOD_util.c
+++ b/source/blender/modifiers/intern/MOD_util.c
@@ -202,10 +202,10 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob,
/* TODO(sybren): after modifier conversion of DM to Mesh is done, check whether
* we really need a copy here. Maybe the CoW ob->data can be directly used. */
Mesh *mesh_prior_modifiers = BKE_object_get_pre_modified_mesh(ob);
- BKE_id_copy_ex(NULL,
- &mesh_prior_modifiers->id,
- (ID **)&mesh,
- (LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_CD_REFERENCE));
+ mesh = (Mesh *)BKE_id_copy_ex(NULL,
+ &mesh_prior_modifiers->id,
+ NULL,
+ (LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_CD_REFERENCE));
mesh->runtime.deformed_only = 1;
}
@@ -343,5 +343,8 @@ void modifier_type_init(ModifierTypeInfo *types[])
INIT_TYPE(SurfaceDeform);
INIT_TYPE(WeightedNormal);
INIT_TYPE(Simulation);
+ INIT_TYPE(MeshToVolume);
+ INIT_TYPE(VolumeDisplace);
+ INIT_TYPE(VolumeToMesh);
#undef INIT_TYPE
}
diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c
index 426ba640f2f..bfbc27abb88 100644
--- a/source/blender/modifiers/intern/MOD_uvproject.c
+++ b/source/blender/modifiers/intern/MOD_uvproject.c
@@ -31,6 +31,7 @@
#include "BLT_translation.h"
#include "DNA_camera_types.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -61,9 +62,9 @@ static void initData(ModifierData *md)
{
UVProjectModifierData *umd = (UVProjectModifierData *)md;
- umd->num_projectors = 1;
- umd->aspectx = umd->aspecty = 1.0f;
- umd->scalex = umd->scaley = 1.0f;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(umd, modifier));
+
+ MEMCPY_STRUCT_AFTER(umd, DNA_struct_default_get(UVProjectModifierData), modifier);
}
static void requiredDataMask(Object *UNUSED(ob),
@@ -74,23 +75,12 @@ static void requiredDataMask(Object *UNUSED(ob),
r_cddata_masks->lmask |= CD_MLOOPUV;
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
-{
- UVProjectModifierData *umd = (UVProjectModifierData *)md;
- int i;
-
- for (i = 0; i < MOD_UVPROJECT_MAXPROJECTORS; i++) {
- walk(userData, ob, &umd->projectors[i], IDWALK_CB_NOP);
- }
-}
-
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
-#if 0
UVProjectModifierData *umd = (UVProjectModifierData *)md;
-#endif
-
- foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
+ for (int i = 0; i < MOD_UVPROJECT_MAXPROJECTORS; i++) {
+ walk(userData, ob, (ID **)&umd->projectors[i], IDWALK_CB_NOP);
+ }
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
@@ -366,9 +356,11 @@ ModifierTypeInfo modifierType_UVProject = {
/* name */ "UVProject",
/* structName */ "UVProjectModifierData",
/* structSize */ sizeof(UVProjectModifierData),
+ /* srna */ &RNA_UVProjectModifier,
/* type */ eModifierTypeType_NonGeometrical,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode,
+ /* icon */ ICON_MOD_UVPROJECT,
/* copyData */ BKE_modifier_copydata_generic,
@@ -388,7 +380,6 @@ ModifierTypeInfo modifierType_UVProject = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c
index f583709f311..b326494815e 100644
--- a/source/blender/modifiers/intern/MOD_uvwarp.c
+++ b/source/blender/modifiers/intern/MOD_uvwarp.c
@@ -27,6 +27,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -63,10 +64,10 @@ static void uv_warp_from_mat4_pair(float uv_dst[2],
static void initData(ModifierData *md)
{
UVWarpModifierData *umd = (UVWarpModifierData *)md;
- umd->axis_u = 0;
- umd->axis_v = 1;
- copy_v2_fl(umd->center, 0.5f);
- copy_v2_fl(umd->scale, 1.0f);
+
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(umd, modifier));
+
+ MEMCPY_STRUCT_AFTER(umd, DNA_struct_default_get(UVWarpModifierData), modifier);
}
static void requiredDataMask(Object *UNUSED(ob),
@@ -240,12 +241,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
return mesh;
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
UVWarpModifierData *umd = (UVWarpModifierData *)md;
- walk(userData, ob, &umd->object_dst, IDWALK_CB_NOP);
- walk(userData, ob, &umd->object_src, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&umd->object_dst, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&umd->object_src, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
@@ -326,9 +327,11 @@ ModifierTypeInfo modifierType_UVWarp = {
/* name */ "UVWarp",
/* structName */ "UVWarpModifierData",
/* structSize */ sizeof(UVWarpModifierData),
+ /* srna */ &RNA_UVWarpModifier,
/* type */ eModifierTypeType_NonGeometrical,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode |
eModifierTypeFlag_EnableInEditmode,
+ /* icon */ ICON_MOD_UVPROJECT, /* TODO: Use correct icon. */
/* copyData */ BKE_modifier_copydata_generic,
@@ -348,8 +351,7 @@ ModifierTypeInfo modifierType_UVWarp = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
/* panelRegister */ panelRegister,
diff --git a/source/blender/modifiers/intern/MOD_volume_displace.cc b/source/blender/modifiers/intern/MOD_volume_displace.cc
new file mode 100644
index 00000000000..f4e1936713c
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_volume_displace.cc
@@ -0,0 +1,348 @@
+/*
+ * 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.
+ */
+
+/** \file
+ * \ingroup modifiers
+ */
+
+#include "BKE_lib_query.h"
+#include "BKE_mesh_runtime.h"
+#include "BKE_modifier.h"
+#include "BKE_object.h"
+#include "BKE_texture.h"
+#include "BKE_volume.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_texture_types.h"
+#include "DNA_volume_types.h"
+
+#include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph_query.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "BLO_read_write.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "MOD_modifiertypes.h"
+#include "MOD_ui_common.h"
+
+#include "RE_texture.h"
+
+#include "RNA_access.h"
+
+#include "BLI_math_vector.h"
+
+#ifdef WITH_OPENVDB
+# include <openvdb/openvdb.h>
+# include <openvdb/tools/Interpolation.h>
+# include <openvdb/tools/Morphology.h>
+# include <openvdb/tools/Prune.h>
+# include <openvdb/tools/ValueTransformer.h>
+#endif
+
+static void initData(ModifierData *md)
+{
+ VolumeDisplaceModifierData *vdmd = reinterpret_cast<VolumeDisplaceModifierData *>(md);
+ vdmd->texture = nullptr;
+ vdmd->strength = 0.5f;
+ copy_v3_fl(vdmd->texture_mid_level, 0.5f);
+ vdmd->texture_sample_radius = 1.0f;
+}
+
+static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
+{
+ VolumeDisplaceModifierData *vdmd = reinterpret_cast<VolumeDisplaceModifierData *>(md);
+ if (vdmd->texture != nullptr) {
+ DEG_add_generic_id_relation(ctx->node, &vdmd->texture->id, "Volume Displace Modifier");
+ }
+ if (vdmd->texture_map_mode == MOD_VOLUME_DISPLACE_MAP_OBJECT) {
+ if (vdmd->texture_map_object != nullptr) {
+ DEG_add_object_relation(
+ ctx->node, vdmd->texture_map_object, DEG_OB_COMP_TRANSFORM, "Volume Displace Modifier");
+ }
+ }
+}
+
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
+{
+ VolumeDisplaceModifierData *vdmd = reinterpret_cast<VolumeDisplaceModifierData *>(md);
+ walk(userData, ob, (ID **)&vdmd->texture, IDWALK_CB_USER);
+ walk(userData, ob, (ID **)&vdmd->texture_map_object, IDWALK_CB_USER);
+}
+
+static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
+{
+ walk(userData, ob, md, "texture");
+}
+
+static bool dependsOnTime(ModifierData *md)
+{
+ VolumeDisplaceModifierData *vdmd = reinterpret_cast<VolumeDisplaceModifierData *>(md);
+ if (vdmd->texture) {
+ return BKE_texture_dependsOnTime(vdmd->texture);
+ }
+ return false;
+}
+
+static void panel_draw(const bContext *C, Panel *panel)
+{
+ uiLayout *layout = panel->layout;
+
+ PointerRNA ob_ptr;
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr);
+ VolumeDisplaceModifierData *vdmd = static_cast<VolumeDisplaceModifierData *>(ptr->data);
+
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+
+ uiTemplateID(layout, C, ptr, "texture", "texture.new", nullptr, nullptr, 0, ICON_NONE, nullptr);
+ uiItemR(layout, ptr, "texture_map_mode", 0, "Texture Mapping", ICON_NONE);
+
+ if (vdmd->texture_map_mode == MOD_VOLUME_DISPLACE_MAP_OBJECT) {
+ uiItemR(layout, ptr, "texture_map_object", 0, "Object", ICON_NONE);
+ }
+
+ uiItemR(layout, ptr, "strength", 0, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "texture_sample_radius", 0, "Sample Radius", ICON_NONE);
+ uiItemR(layout, ptr, "texture_mid_level", 0, "Mid Level", ICON_NONE);
+
+ modifier_panel_end(layout, ptr);
+}
+
+static void panelRegister(ARegionType *region_type)
+{
+ modifier_panel_register(region_type, eModifierType_VolumeDisplace, panel_draw);
+}
+
+#ifdef WITH_OPENVDB
+
+static openvdb::Mat4s matrix_to_openvdb(const float m[4][4])
+{
+ /* OpenVDB matrices are transposed Blender matrices, i.e. the translation is in the last row
+ * instead of in the last column. However, the layout in memory is the same, because OpenVDB
+ * matrices are row major (compared to Blender's column major matrices). */
+ openvdb::Mat4s new_matrix{reinterpret_cast<const float *>(m)};
+ return new_matrix;
+}
+
+template<typename GridType> struct DisplaceOp {
+ /* Has to be copied for each thread. */
+ typename GridType::ConstAccessor accessor;
+ const openvdb::Mat4s index_to_texture;
+
+ Tex *texture;
+ const double strength;
+ const openvdb::Vec3d texture_mid_level;
+
+ void operator()(const typename GridType::ValueOnIter &iter) const
+ {
+ const openvdb::Coord coord = iter.getCoord();
+ const openvdb::Vec3d displace_vector = this->compute_displace_vector(coord);
+ /* Subtract vector because that makes the result more similar to advection and the mesh
+ * displace modifier. */
+ const openvdb::Vec3d sample_coord = coord.asVec3d() - displace_vector;
+ const auto new_value = openvdb::tools::BoxSampler::sample(this->accessor, sample_coord);
+ iter.setValue(new_value);
+ }
+
+ openvdb::Vec3d compute_displace_vector(const openvdb::Coord &coord) const
+ {
+ if (this->texture != nullptr) {
+ const openvdb::Vec3f texture_pos = coord.asVec3s() * this->index_to_texture;
+ const openvdb::Vec3d texture_value = this->evaluate_texture(texture_pos);
+ const openvdb::Vec3d displacement = (texture_value - this->texture_mid_level) *
+ this->strength;
+ return displacement;
+ }
+ return openvdb::Vec3d{0, 0, 0};
+ }
+
+ openvdb::Vec3d evaluate_texture(const openvdb::Vec3f &pos) const
+ {
+ TexResult texture_result = {0};
+ BKE_texture_get_value(
+ nullptr, this->texture, const_cast<float *>(pos.asV()), &texture_result, false);
+ return {texture_result.tr, texture_result.tg, texture_result.tb};
+ }
+};
+
+static float get_max_voxel_side_length(const openvdb::GridBase &grid)
+{
+ const openvdb::Vec3d voxel_size = grid.voxelSize();
+ const float max_voxel_side_length = std::max({voxel_size[0], voxel_size[1], voxel_size[2]});
+ return max_voxel_side_length;
+}
+
+struct DisplaceGridOp {
+ /* This is the grid that will be displaced. The output is copied back to the original grid. */
+ openvdb::GridBase &base_grid;
+
+ VolumeDisplaceModifierData &vdmd;
+ const ModifierEvalContext &ctx;
+
+ template<typename GridType> void operator()()
+ {
+ if constexpr (std::is_same_v<GridType, openvdb::points::PointDataGrid> ||
+ std::is_same_v<GridType, openvdb::StringGrid> ||
+ std::is_same_v<GridType, openvdb::MaskGrid>) {
+ /* We don't support displacing these grid types yet. */
+ return;
+ }
+ else {
+ this->displace_grid<GridType>();
+ }
+ }
+
+ template<typename GridType> void displace_grid()
+ {
+ GridType &grid = static_cast<GridType &>(base_grid);
+
+ /* Make a copy of the original grid to work on. This will replace the original grid. */
+ typename GridType::Ptr temp_grid = grid.deepCopy();
+
+ /* Dilate grid, because the currently inactive cells might become active during the displace
+ * operation. The quality of the approximation of the has a big impact on performance. */
+ const float max_voxel_side_length = get_max_voxel_side_length(grid);
+ const float sample_radius = vdmd.texture_sample_radius * std::abs(vdmd.strength) /
+ max_voxel_side_length / 2.0f;
+ openvdb::tools::dilateActiveValues(temp_grid->tree(),
+ static_cast<int>(std::ceil(sample_radius)),
+ openvdb::tools::NN_FACE_EDGE,
+ openvdb::tools::EXPAND_TILES);
+
+ const openvdb::Mat4s index_to_texture = this->get_index_to_texture_transform();
+
+ /* Construct the operator that will be executed on every cell of the dilated grid. */
+ DisplaceOp<GridType> displace_op{grid.getConstAccessor(),
+ index_to_texture,
+ vdmd.texture,
+ vdmd.strength / max_voxel_side_length,
+ openvdb::Vec3d{vdmd.texture_mid_level}};
+
+ /* Run the operator. This is multi-threaded. It is important that the operator is not shared
+ * between the threads, because it contains a non-thread-safe accessor for the old grid. */
+ openvdb::tools::foreach (temp_grid->beginValueOn(),
+ displace_op,
+ true,
+ /* Disable sharing of the operator. */ false);
+
+ /* It is likely that we produced too many active cells. Those are removed here, to avoid
+ * slowing down subsequent operations. */
+ typename GridType::ValueType prune_tolerance{0};
+ openvdb::tools::deactivate(*temp_grid, temp_grid->background(), prune_tolerance);
+ openvdb::tools::prune(temp_grid->tree());
+
+ /* Overwrite the old volume grid with the new grid. */
+ grid.clear();
+ grid.merge(*temp_grid);
+ }
+
+ openvdb::Mat4s get_index_to_texture_transform() const
+ {
+ const openvdb::Mat4s index_to_object{
+ base_grid.transform().baseMap()->getAffineMap()->getMat4()};
+
+ switch (vdmd.texture_map_mode) {
+ case MOD_VOLUME_DISPLACE_MAP_LOCAL: {
+ return index_to_object;
+ }
+ case MOD_VOLUME_DISPLACE_MAP_GLOBAL: {
+ const openvdb::Mat4s object_to_world = matrix_to_openvdb(ctx.object->obmat);
+ return index_to_object * object_to_world;
+ }
+ case MOD_VOLUME_DISPLACE_MAP_OBJECT: {
+ if (vdmd.texture_map_object == nullptr) {
+ return index_to_object;
+ }
+ const openvdb::Mat4s object_to_world = matrix_to_openvdb(ctx.object->obmat);
+ const openvdb::Mat4s world_to_texture = matrix_to_openvdb(vdmd.texture_map_object->imat);
+ return index_to_object * object_to_world * world_to_texture;
+ }
+ }
+ BLI_assert(false);
+ return {};
+ }
+};
+
+#endif
+
+static Volume *modifyVolume(ModifierData *md, const ModifierEvalContext *ctx, Volume *volume)
+{
+#ifdef WITH_OPENVDB
+ VolumeDisplaceModifierData *vdmd = reinterpret_cast<VolumeDisplaceModifierData *>(md);
+
+ /* Iterate over all grids and displace them one by one. */
+ BKE_volume_load(volume, DEG_get_bmain(ctx->depsgraph));
+ const int grid_amount = BKE_volume_num_grids(volume);
+ for (int grid_index = 0; grid_index < grid_amount; grid_index++) {
+ VolumeGrid *volume_grid = BKE_volume_grid_get(volume, grid_index);
+ BLI_assert(volume_grid != nullptr);
+
+ openvdb::GridBase::Ptr grid = BKE_volume_grid_openvdb_for_write(volume, volume_grid, false);
+ VolumeGridType grid_type = BKE_volume_grid_type(volume_grid);
+
+ DisplaceGridOp displace_grid_op{*grid, *vdmd, *ctx};
+ BKE_volume_grid_type_operation(grid_type, displace_grid_op);
+ }
+
+ return volume;
+#else
+ UNUSED_VARS(md, ctx);
+ BKE_modifier_set_error(ctx->object, md, "Compiled without OpenVDB");
+ return volume;
+#endif
+}
+
+ModifierTypeInfo modifierType_VolumeDisplace = {
+ /* name */ "Volume Displace",
+ /* structName */ "VolumeDisplaceModifierData",
+ /* structSize */ sizeof(VolumeDisplaceModifierData),
+ /* srna */ &RNA_VolumeDisplaceModifier,
+ /* type */ eModifierTypeType_NonGeometrical,
+ /* flags */ static_cast<ModifierTypeFlag>(0),
+ /* icon */ ICON_VOLUME_DATA, /* TODO: Use correct icon. */
+
+ /* copyData */ BKE_modifier_copydata_generic,
+
+ /* deformVerts */ nullptr,
+ /* deformMatrices */ nullptr,
+ /* deformVertsEM */ nullptr,
+ /* deformMatricesEM */ nullptr,
+ /* modifyMesh */ nullptr,
+ /* modifyHair */ nullptr,
+ /* modifyPointCloud */ nullptr,
+ /* modifyVolume */ modifyVolume,
+
+ /* initData */ initData,
+ /* requiredDataMask */ nullptr,
+ /* freeData */ nullptr,
+ /* isDisabled */ nullptr,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ nullptr,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ foreachTexLink,
+ /* freeRuntimeData */ nullptr,
+ /* panelRegister */ panelRegister,
+ /* blendWrite */ nullptr,
+ /* blendRead */ nullptr,
+};
diff --git a/source/blender/modifiers/intern/MOD_volume_to_mesh.cc b/source/blender/modifiers/intern/MOD_volume_to_mesh.cc
new file mode 100644
index 00000000000..e008dc3f140
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_volume_to_mesh.cc
@@ -0,0 +1,355 @@
+/*
+ * 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.
+ */
+
+/** \file
+ * \ingroup modifiers
+ */
+
+#include <vector>
+
+#include "BKE_lib_query.h"
+#include "BKE_mesh.h"
+#include "BKE_modifier.h"
+#include "BKE_volume.h"
+
+#include "MOD_modifiertypes.h"
+#include "MOD_ui_common.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_volume_types.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "RNA_access.h"
+
+#include "BLI_float4x4.hh"
+#include "BLI_math_vector.h"
+#include "BLI_span.hh"
+#include "BLI_timeit.hh"
+
+#include "DEG_depsgraph_query.h"
+
+#ifdef WITH_OPENVDB
+# include <openvdb/tools/GridTransformer.h>
+# include <openvdb/tools/VolumeToMesh.h>
+#endif
+
+using blender::float3;
+using blender::float4x4;
+using blender::Span;
+
+static void initData(ModifierData *md)
+{
+ VolumeToMeshModifierData *vmmd = reinterpret_cast<VolumeToMeshModifierData *>(md);
+ vmmd->object = nullptr;
+ vmmd->threshold = 0.1f;
+ strncpy(vmmd->grid_name, "density", MAX_NAME);
+ vmmd->adaptivity = 0.0f;
+ vmmd->resolution_mode = VOLUME_TO_MESH_RESOLUTION_MODE_GRID;
+ vmmd->voxel_amount = 32;
+ vmmd->voxel_size = 0.1f;
+ vmmd->flag = 0;
+}
+
+static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
+{
+ VolumeToMeshModifierData *vmmd = reinterpret_cast<VolumeToMeshModifierData *>(md);
+ DEG_add_modifier_to_transform_relation(ctx->node, "Volume to Mesh Modifier");
+ if (vmmd->object) {
+ DEG_add_object_relation(
+ ctx->node, vmmd->object, DEG_OB_COMP_GEOMETRY, "Volume to Mesh Modifier");
+ DEG_add_object_relation(
+ ctx->node, vmmd->object, DEG_OB_COMP_TRANSFORM, "Volume to Mesh Modifier");
+ }
+}
+
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
+{
+ VolumeToMeshModifierData *vmmd = reinterpret_cast<VolumeToMeshModifierData *>(md);
+ walk(userData, ob, (ID **)&vmmd->object, IDWALK_CB_NOP);
+}
+
+static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+{
+ uiLayout *layout = panel->layout;
+
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
+ VolumeToMeshModifierData *vmmd = static_cast<VolumeToMeshModifierData *>(ptr->data);
+
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+
+ {
+ uiLayout *col = uiLayoutColumn(layout, false);
+ uiItemR(col, ptr, "object", 0, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "grid_name", 0, nullptr, ICON_NONE);
+ }
+
+ {
+ uiLayout *col = uiLayoutColumn(layout, false);
+ uiItemR(col, ptr, "resolution_mode", 0, nullptr, ICON_NONE);
+ if (vmmd->resolution_mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_AMOUNT) {
+ uiItemR(col, ptr, "voxel_amount", 0, nullptr, ICON_NONE);
+ }
+ else if (vmmd->resolution_mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE) {
+ uiItemR(col, ptr, "voxel_size", 0, nullptr, ICON_NONE);
+ }
+ }
+
+ {
+ uiLayout *col = uiLayoutColumn(layout, false);
+ uiItemR(col, ptr, "threshold", 0, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "adaptivity", 0, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "use_smooth_shade", 0, nullptr, ICON_NONE);
+ }
+
+ modifier_panel_end(layout, ptr);
+}
+
+static void panelRegister(ARegionType *region_type)
+{
+ modifier_panel_register(region_type, eModifierType_VolumeToMesh, panel_draw);
+}
+
+#ifdef WITH_OPENVDB
+
+struct VolumeToMeshOp {
+ const openvdb::GridBase &base_grid;
+ VolumeToMeshModifierData &vmmd;
+ const ModifierEvalContext &ctx;
+ std::vector<openvdb::Vec3s> verts;
+ std::vector<openvdb::Vec3I> tris;
+ std::vector<openvdb::Vec4I> quads;
+
+ template<typename GridType> bool operator()()
+ {
+ if constexpr (std::is_scalar_v<typename GridType::ValueType>) {
+ this->generate_mesh_data<GridType>();
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ template<typename GridType> void generate_mesh_data()
+ {
+ /* Make a new transform from the index space into the mesh object space. */
+ openvdb::math::Transform::Ptr transform = this->base_grid.transform().copy();
+ transform->postMult(openvdb::Mat4d((float *)vmmd.object->obmat));
+ openvdb::Mat4d imat = openvdb::Mat4d((float *)ctx.object->imat);
+ /* `imat` had floating point issues and wasn't affine. */
+ imat.setCol(3, openvdb::Vec4d(0, 0, 0, 1));
+ transform->postMult(imat);
+
+ /* Create a new grid with a different transform. The underlying tree is shared. */
+ typename GridType::ConstPtr grid = openvdb::gridConstPtrCast<GridType>(
+ this->base_grid.copyGridReplacingTransform(transform));
+
+ if (this->vmmd.resolution_mode == VOLUME_TO_MESH_RESOLUTION_MODE_GRID) {
+ this->grid_to_mesh(*grid);
+ return;
+ }
+
+ const float resolution_factor = this->compute_resolution_factor(*grid);
+ typename GridType::Ptr temp_grid = this->create_grid_with_changed_resolution(
+ *grid, resolution_factor);
+ this->grid_to_mesh(*temp_grid);
+ }
+
+ template<typename GridType>
+ typename GridType::Ptr create_grid_with_changed_resolution(const GridType &old_grid,
+ const float resolution_factor)
+ {
+ BLI_assert(resolution_factor > 0.0f);
+
+ openvdb::Mat4R xform;
+ xform.setToScale(openvdb::Vec3d(resolution_factor));
+ openvdb::tools::GridTransformer transformer{xform};
+
+ typename GridType::Ptr new_grid = GridType::create();
+ transformer.transformGrid<openvdb::tools::BoxSampler>(old_grid, *new_grid);
+ new_grid->transform() = old_grid.transform();
+ new_grid->transform().preScale(1.0f / resolution_factor);
+ return new_grid;
+ }
+
+ float compute_resolution_factor(const openvdb::GridBase &grid) const
+ {
+ const openvdb::Vec3s voxel_size{grid.voxelSize()};
+ const float current_voxel_size = std::max({voxel_size[0], voxel_size[1], voxel_size[2]});
+ const float desired_voxel_size = this->compute_desired_voxel_size(grid);
+ return current_voxel_size / desired_voxel_size;
+ }
+
+ float compute_desired_voxel_size(const openvdb::GridBase &grid) const
+ {
+ if (this->vmmd.resolution_mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE) {
+ return this->vmmd.voxel_size;
+ }
+ const openvdb::CoordBBox coord_bbox = base_grid.evalActiveVoxelBoundingBox();
+ const openvdb::BBoxd bbox = grid.transform().indexToWorld(coord_bbox);
+ const float max_extent = bbox.extents()[bbox.maxExtent()];
+ const float voxel_size = max_extent / this->vmmd.voxel_amount;
+ return voxel_size;
+ }
+
+ template<typename GridType> void grid_to_mesh(const GridType &grid)
+ {
+ openvdb::tools::volumeToMesh(
+ grid, this->verts, this->tris, this->quads, this->vmmd.threshold, this->vmmd.adaptivity);
+ }
+};
+
+static Mesh *new_mesh_from_openvdb_data(Span<openvdb::Vec3s> verts,
+ Span<openvdb::Vec3I> tris,
+ Span<openvdb::Vec4I> quads)
+{
+ const int tot_loops = 3 * tris.size() + 4 * quads.size();
+ const int tot_polys = tris.size() + quads.size();
+
+ Mesh *mesh = BKE_mesh_new_nomain(verts.size(), 0, 0, tot_loops, tot_polys);
+
+ /* Write vertices. */
+ for (const int i : verts.index_range()) {
+ const blender::float3 co = blender::float3(verts[i].asV());
+ copy_v3_v3(mesh->mvert[i].co, co);
+ }
+
+ /* Write triangles. */
+ for (const int i : tris.index_range()) {
+ mesh->mpoly[i].loopstart = 3 * i;
+ mesh->mpoly[i].totloop = 3;
+ for (int j = 0; j < 3; j++) {
+ /* Reverse vertex order to get correct normals. */
+ mesh->mloop[3 * i + j].v = tris[i][2 - j];
+ }
+ }
+
+ /* Write quads. */
+ const int poly_offset = tris.size();
+ const int loop_offset = tris.size() * 3;
+ for (const int i : quads.index_range()) {
+ mesh->mpoly[poly_offset + i].loopstart = loop_offset + 4 * i;
+ mesh->mpoly[poly_offset + i].totloop = 4;
+ for (int j = 0; j < 4; j++) {
+ /* Reverse vertex order to get correct normals. */
+ mesh->mloop[loop_offset + 4 * i + j].v = quads[i][3 - j];
+ }
+ }
+
+ BKE_mesh_calc_edges(mesh, false, false);
+ BKE_mesh_calc_normals(mesh);
+ return mesh;
+}
+#endif
+
+static Mesh *create_empty_mesh(const Mesh *input_mesh)
+{
+ Mesh *new_mesh = BKE_mesh_new_nomain(0, 0, 0, 0, 0);
+ BKE_mesh_copy_settings(new_mesh, input_mesh);
+ return new_mesh;
+}
+
+static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *input_mesh)
+{
+#ifdef WITH_OPENVDB
+ VolumeToMeshModifierData *vmmd = reinterpret_cast<VolumeToMeshModifierData *>(md);
+ if (vmmd->object == nullptr) {
+ return create_empty_mesh(input_mesh);
+ }
+ if (vmmd->object->type != OB_VOLUME) {
+ return create_empty_mesh(input_mesh);
+ }
+ if (vmmd->resolution_mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE &&
+ vmmd->voxel_size == 0.0f) {
+ return create_empty_mesh(input_mesh);
+ }
+ if (vmmd->resolution_mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_AMOUNT &&
+ vmmd->voxel_amount == 0) {
+ return create_empty_mesh(input_mesh);
+ }
+
+ Volume *volume = static_cast<Volume *>(vmmd->object->data);
+
+ BKE_volume_load(volume, DEG_get_bmain(ctx->depsgraph));
+ VolumeGrid *volume_grid = BKE_volume_grid_find(volume, vmmd->grid_name);
+ if (volume_grid == nullptr) {
+ BKE_modifier_set_error(ctx->object, md, "Cannot find '%s' grid", vmmd->grid_name);
+ return create_empty_mesh(input_mesh);
+ }
+
+ const openvdb::GridBase::ConstPtr grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
+
+ const VolumeGridType grid_type = BKE_volume_grid_type(volume_grid);
+ VolumeToMeshOp to_mesh_op{*grid, *vmmd, *ctx};
+ if (!BKE_volume_grid_type_operation(grid_type, to_mesh_op)) {
+ BKE_modifier_set_error(ctx->object, md, "Expected a scalar grid");
+ return create_empty_mesh(input_mesh);
+ }
+
+ Mesh *mesh = new_mesh_from_openvdb_data(to_mesh_op.verts, to_mesh_op.tris, to_mesh_op.quads);
+ BKE_mesh_copy_settings(mesh, input_mesh);
+ if (vmmd->flag & VOLUME_TO_MESH_USE_SMOOTH_SHADE) {
+ BKE_mesh_smooth_flag_set(mesh, true);
+ }
+ return mesh;
+#else
+ UNUSED_VARS(md);
+ BKE_modifier_set_error(ctx->object, md, "Compiled without OpenVDB");
+ return create_empty_mesh(input_mesh);
+#endif
+}
+
+ModifierTypeInfo modifierType_VolumeToMesh = {
+ /* name */ "Volume to Mesh",
+ /* structName */ "VolumeToMeshModifierData",
+ /* structSize */ sizeof(VolumeToMeshModifierData),
+ /* srna */ &RNA_VolumeToMeshModifier,
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh,
+ /* icon */ ICON_VOLUME_DATA, /* TODO: Use correct icon. */
+
+ /* copyData */ BKE_modifier_copydata_generic,
+
+ /* deformVerts */ nullptr,
+ /* deformMatrices */ nullptr,
+ /* deformVertsEM */ nullptr,
+ /* deformMatricesEM */ nullptr,
+ /* modifyMesh */ modifyMesh,
+ /* modifyHair */ nullptr,
+ /* modifyPointCloud */ nullptr,
+ /* modifyVolume */ nullptr,
+
+ /* initData */ initData,
+ /* requiredDataMask */ nullptr,
+ /* freeData */ nullptr,
+ /* isDisabled */ nullptr,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ nullptr,
+ /* dependsOnNormals */ nullptr,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ nullptr,
+ /* freeRuntimeData */ nullptr,
+ /* panelRegister */ panelRegister,
+ /* blendWrite */ nullptr,
+ /* blendRead */ nullptr,
+};
diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c
index bb0896994b1..53e41484606 100644
--- a/source/blender/modifiers/intern/MOD_warp.c
+++ b/source/blender/modifiers/intern/MOD_warp.c
@@ -28,6 +28,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -56,7 +57,7 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
-#include "RE_shader_ext.h"
+#include "RE_texture.h"
#include "MOD_ui_common.h"
#include "MOD_util.h"
@@ -65,12 +66,11 @@ static void initData(ModifierData *md)
{
WarpModifierData *wmd = (WarpModifierData *)md;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(wmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(wmd, DNA_struct_default_get(WarpModifierData), modifier);
+
wmd->curfalloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
- wmd->texture = NULL;
- wmd->strength = 1.0f;
- wmd->falloff_radius = 1.0f;
- wmd->falloff_type = eWarp_Falloff_Smooth;
- wmd->flag = 0;
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
@@ -142,22 +142,14 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
return !(wmd->object_from && wmd->object_to);
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
-{
- WarpModifierData *wmd = (WarpModifierData *)md;
-
- walk(userData, ob, &wmd->object_from, IDWALK_CB_NOP);
- walk(userData, ob, &wmd->object_to, IDWALK_CB_NOP);
- walk(userData, ob, &wmd->map_object, IDWALK_CB_NOP);
-}
-
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
WarpModifierData *wmd = (WarpModifierData *)md;
walk(userData, ob, (ID **)&wmd->texture, IDWALK_CB_USER);
-
- foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
+ walk(userData, ob, (ID **)&wmd->object_from, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&wmd->object_to, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&wmd->map_object, IDWALK_CB_NOP);
}
static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
@@ -279,8 +271,9 @@ static void warpModifier_do(WarpModifierData *wmd,
/* skip if no vert group found */
if (defgrp_index != -1) {
dv = &dvert[i];
- weight = invert_vgroup ? 1.0f - BKE_defvert_find_weight(dv, defgrp_index) * strength :
- BKE_defvert_find_weight(dv, defgrp_index) * strength;
+ weight = (invert_vgroup ? (1.0f - BKE_defvert_find_weight(dv, defgrp_index)) :
+ BKE_defvert_find_weight(dv, defgrp_index)) *
+ strength;
if (weight <= 0.0f) {
continue;
}
@@ -532,9 +525,11 @@ ModifierTypeInfo modifierType_Warp = {
/* name */ "Warp",
/* structName */ "WarpModifierData",
/* structSize */ sizeof(WarpModifierData),
+ /* srna */ &RNA_WarpModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly |
eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_MOD_WARP,
/* copyData */ copyData,
/* deformVerts */ deformVerts,
@@ -553,7 +548,6 @@ ModifierTypeInfo modifierType_Warp = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ foreachTexLink,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c
index ae0c59ed9ef..45f06a7778c 100644
--- a/source/blender/modifiers/intern/MOD_wave.c
+++ b/source/blender/modifiers/intern/MOD_wave.c
@@ -27,6 +27,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -50,7 +51,8 @@
#include "RNA_access.h"
#include "MEM_guardedalloc.h"
-#include "RE_shader_ext.h"
+
+#include "RE_texture.h"
#include "MOD_modifiertypes.h"
#include "MOD_ui_common.h"
@@ -61,23 +63,11 @@
static void initData(ModifierData *md)
{
- WaveModifierData *wmd = (WaveModifierData *)md; // whadya know, moved here from Iraq
-
- wmd->flag |= (MOD_WAVE_X | MOD_WAVE_Y | MOD_WAVE_CYCL | MOD_WAVE_NORM_X | MOD_WAVE_NORM_Y |
- MOD_WAVE_NORM_Z);
-
- wmd->objectcenter = NULL;
- wmd->texture = NULL;
- wmd->map_object = NULL;
- wmd->height = 0.5f;
- wmd->width = 1.5f;
- wmd->speed = 0.25f;
- wmd->narrow = 1.5f;
- wmd->lifetime = 0.0f;
- wmd->damp = 10.0f;
- wmd->falloff = 0.0f;
- wmd->texmapping = MOD_DISP_MAP_LOCAL;
- wmd->defgrp_name[0] = 0;
+ WaveModifierData *wmd = (WaveModifierData *)md;
+
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(wmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(wmd, DNA_struct_default_get(WaveModifierData), modifier);
}
static bool dependsOnTime(ModifierData *UNUSED(md))
@@ -85,21 +75,13 @@ static bool dependsOnTime(ModifierData *UNUSED(md))
return true;
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
-{
- WaveModifierData *wmd = (WaveModifierData *)md;
-
- walk(userData, ob, &wmd->objectcenter, IDWALK_CB_NOP);
- walk(userData, ob, &wmd->map_object, IDWALK_CB_NOP);
-}
-
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
WaveModifierData *wmd = (WaveModifierData *)md;
walk(userData, ob, (ID **)&wmd->texture, IDWALK_CB_USER);
-
- foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
+ walk(userData, ob, (ID **)&wmd->objectcenter, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&wmd->map_object, IDWALK_CB_NOP);
}
static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
@@ -495,9 +477,11 @@ ModifierTypeInfo modifierType_Wave = {
/* name */ "Wave",
/* structName */ "WaveModifierData",
/* structSize */ sizeof(WaveModifierData),
+ /* srna */ &RNA_WaveModifier,
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly |
eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_MOD_WAVE,
/* copyData */ BKE_modifier_copydata_generic,
@@ -517,7 +501,6 @@ ModifierTypeInfo modifierType_Wave = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ foreachObjectLink,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ foreachTexLink,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.c b/source/blender/modifiers/intern/MOD_weighted_normal.c
index fc7ac822874..bd15d909834 100644
--- a/source/blender/modifiers/intern/MOD_weighted_normal.c
+++ b/source/blender/modifiers/intern/MOD_weighted_normal.c
@@ -26,6 +26,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -573,12 +574,13 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
if (!(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH))
#endif
{
- BKE_modifier_set_error((ModifierData *)wnmd, "Enable 'Auto Smooth' in Object Data Properties");
+ BKE_modifier_set_error(
+ ctx->object, (ModifierData *)wnmd, "Enable 'Auto Smooth' in Object Data Properties");
return mesh;
}
Mesh *result;
- BKE_id_copy_ex(NULL, &mesh->id, (ID **)&result, LIB_ID_COPY_LOCALIZE);
+ result = (Mesh *)BKE_id_copy_ex(NULL, &mesh->id, NULL, LIB_ID_COPY_LOCALIZE);
const int numVerts = result->totvert;
const int numEdges = result->totedge;
@@ -686,10 +688,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
static void initData(ModifierData *md)
{
WeightedNormalModifierData *wnmd = (WeightedNormalModifierData *)md;
- wnmd->mode = MOD_WEIGHTEDNORMAL_MODE_FACE;
- wnmd->weight = 50;
- wnmd->thresh = 1e-2f;
- wnmd->flag = 0;
+
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(wnmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(wnmd, DNA_struct_default_get(WeightedNormalModifierData), modifier);
}
static void requiredDataMask(Object *UNUSED(ob),
@@ -731,7 +733,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "keep_sharp", 0, NULL, ICON_NONE);
- uiItemR(col, ptr, "face_influence", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_face_influence", 0, NULL, ICON_NONE);
modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
@@ -747,9 +749,11 @@ ModifierTypeInfo modifierType_WeightedNormal = {
/* name */ "WeightedNormal",
/* structName */ "WeightedNormalModifierData",
/* structSize */ sizeof(WeightedNormalModifierData),
+ /* srna */ &RNA_WeightedNormalModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode,
+ /* icon */ ICON_MOD_VERTEX_WEIGHT,
/* copyData */ BKE_modifier_copydata_generic,
@@ -769,7 +773,6 @@ ModifierTypeInfo modifierType_WeightedNormal = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c
index 4ee1f9f669a..c5e2ecb9660 100644
--- a/source/blender/modifiers/intern/MOD_weightvg_util.c
+++ b/source/blender/modifiers/intern/MOD_weightvg_util.c
@@ -55,7 +55,7 @@
#include "MOD_ui_common.h"
#include "MOD_util.h"
#include "MOD_weightvg_util.h"
-#include "RE_shader_ext.h" /* Texture masking. */
+#include "RE_texture.h" /* Texture masking. */
/* Maps new_w weights in place, using either one of the predefined functions, or a custom curve.
* Return values are in new_w.
@@ -249,9 +249,10 @@ 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 = invert_vgroup_mask ?
- 1.0f - BKE_defvert_find_weight(&dvert[idx], ref_didx) * fact :
- BKE_defvert_find_weight(&dvert[idx], ref_didx) * fact;
+ const float f = (invert_vgroup_mask ?
+ (1.0f - BKE_defvert_find_weight(&dvert[idx], ref_didx)) :
+ 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! */
}
diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c
index 4cc19ab895e..df554f6bc4e 100644
--- a/source/blender/modifiers/intern/MOD_weightvgedit.c
+++ b/source/blender/modifiers/intern/MOD_weightvgedit.c
@@ -21,6 +21,8 @@
* \ingroup modifiers
*/
+#include <string.h>
+
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
@@ -30,6 +32,7 @@
#include "BLT_translation.h"
#include "DNA_color_types.h" /* CurveMapping. */
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -67,19 +70,13 @@
static void initData(ModifierData *md)
{
WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
- wmd->edit_flags = 0;
- wmd->falloff_type = MOD_WVG_MAPPING_NONE;
- wmd->default_weight = 0.0f;
- wmd->cmap_curve = BKE_curvemapping_add(1, 0.0, 0.0, 1.0, 1.0);
- BKE_curvemapping_init(wmd->cmap_curve);
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(wmd, modifier));
- wmd->rem_threshold = 0.01f;
- wmd->add_threshold = 0.01f;
+ MEMCPY_STRUCT_AFTER(wmd, DNA_struct_default_get(WeightVGEditModifierData), modifier);
- wmd->mask_constant = 1.0f;
- wmd->mask_tex_use_channel = MOD_WVG_MASK_TEX_USE_INT; /* Use intensity by default. */
- wmd->mask_tex_mapping = MOD_DISP_MAP_LOCAL;
+ wmd->cmap_curve = BKE_curvemapping_add(1, 0.0, 0.0, 1.0, 1.0);
+ BKE_curvemapping_init(wmd->cmap_curve);
}
static void freeData(ModifierData *md)
@@ -125,19 +122,12 @@ static bool dependsOnTime(ModifierData *md)
return false;
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
-{
- WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
- walk(userData, ob, &wmd->mask_tex_map_obj, IDWALK_CB_NOP);
-}
-
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
walk(userData, ob, (ID **)&wmd->mask_texture, IDWALK_CB_USER);
-
- foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
+ walk(userData, ob, (ID **)&wmd->mask_tex_map_obj, IDWALK_CB_NOP);
}
static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
@@ -423,9 +413,11 @@ ModifierTypeInfo modifierType_WeightVGEdit = {
/* name */ "VertexWeightEdit",
/* structName */ "WeightVGEditModifierData",
/* structSize */ sizeof(WeightVGEditModifierData),
+ /* srna */ &RNA_VertexWeightEditModifier,
/* type */ eModifierTypeType_NonGeometrical,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_UsesPreview,
+ /* icon */ ICON_MOD_VERTEX_WEIGHT,
/* copyData */ copyData,
@@ -445,7 +437,6 @@ ModifierTypeInfo modifierType_WeightVGEdit = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ foreachTexLink,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c
index 81d4a04fa78..9be36fe6846 100644
--- a/source/blender/modifiers/intern/MOD_weightvgmix.c
+++ b/source/blender/modifiers/intern/MOD_weightvgmix.c
@@ -28,6 +28,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -131,14 +132,9 @@ static void initData(ModifierData *md)
{
WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;
- wmd->default_weight_a = 0.0f;
- wmd->default_weight_b = 0.0f;
- wmd->mix_mode = MOD_WVG_MIX_SET;
- wmd->mix_set = MOD_WVG_SET_AND;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(wmd, modifier));
- wmd->mask_constant = 1.0f;
- wmd->mask_tex_use_channel = MOD_WVG_MASK_TEX_USE_INT; /* Use intensity by default. */
- wmd->mask_tex_mapping = MOD_DISP_MAP_LOCAL;
+ MEMCPY_STRUCT_AFTER(wmd, DNA_struct_default_get(WeightVGMixModifierData), modifier);
}
static void requiredDataMask(Object *UNUSED(ob),
@@ -168,19 +164,12 @@ static bool dependsOnTime(ModifierData *md)
return false;
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
-{
- WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;
- walk(userData, ob, &wmd->mask_tex_map_obj, IDWALK_CB_NOP);
-}
-
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;
walk(userData, ob, (ID **)&wmd->mask_texture, IDWALK_CB_USER);
-
- foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
+ walk(userData, ob, (ID **)&wmd->mask_tex_map_obj, IDWALK_CB_NOP);
}
static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
@@ -510,9 +499,11 @@ ModifierTypeInfo modifierType_WeightVGMix = {
/* name */ "VertexWeightMix",
/* structName */ "WeightVGMixModifierData",
/* structSize */ sizeof(WeightVGMixModifierData),
+ /* srna */ &RNA_VertexWeightMixModifier,
/* type */ eModifierTypeType_NonGeometrical,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_UsesPreview,
+ /* icon */ ICON_MOD_VERTEX_WEIGHT,
/* copyData */ BKE_modifier_copydata_generic,
@@ -532,7 +523,6 @@ ModifierTypeInfo modifierType_WeightVGMix = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ foreachTexLink,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c
index 994f2c04921..9b21c77268e 100644
--- a/source/blender/modifiers/intern/MOD_weightvgproximity.c
+++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c
@@ -31,6 +31,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -45,6 +46,7 @@
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_wrapper.h"
#include "BKE_modifier.h"
#include "BKE_screen.h"
#include "BKE_texture.h" /* Texture masking. */
@@ -315,15 +317,9 @@ static void initData(ModifierData *md)
{
WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
- wmd->proximity_mode = MOD_WVG_PROXIMITY_OBJECT;
- wmd->proximity_flags = MOD_WVG_PROXIMITY_GEOM_VERTS;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(wmd, modifier));
- wmd->falloff_type = MOD_WVG_MAPPING_NONE;
-
- wmd->mask_constant = 1.0f;
- wmd->mask_tex_use_channel = MOD_WVG_MASK_TEX_USE_INT; /* Use intensity by default. */
- wmd->mask_tex_mapping = MOD_DISP_MAP_LOCAL;
- wmd->max_dist = 1.0f; /* vert arbitrary distance, but don't use 0 */
+ MEMCPY_STRUCT_AFTER(wmd, DNA_struct_default_get(WeightVGProximityModifierData), modifier);
}
static void requiredDataMask(Object *UNUSED(ob),
@@ -353,20 +349,13 @@ static bool dependsOnTime(ModifierData *md)
return 0;
}
-static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
-{
- WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
- walk(userData, ob, &wmd->proximity_ob_target, IDWALK_CB_NOP);
- walk(userData, ob, &wmd->mask_tex_map_obj, IDWALK_CB_NOP);
-}
-
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
walk(userData, ob, (ID **)&wmd->mask_texture, IDWALK_CB_USER);
-
- foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
+ walk(userData, ob, (ID **)&wmd->proximity_ob_target, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&wmd->mask_tex_map_obj, IDWALK_CB_NOP);
}
static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
@@ -552,6 +541,11 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* We must check that we do have a valid target_mesh! */
if (target_mesh != NULL) {
+
+ /* TODO: edit-mode versions of the BVH lookup functions are available so it could be
+ * avoided. */
+ BKE_mesh_wrapper_ensure_mdata(target_mesh);
+
SpaceTransform loc2trgt;
float *dists_v = use_trgt_verts ? MEM_malloc_arrayN(numIdx, sizeof(float), "dists_v") :
NULL;
@@ -713,9 +707,11 @@ ModifierTypeInfo modifierType_WeightVGProximity = {
/* name */ "VertexWeightProximity",
/* structName */ "WeightVGProximityModifierData",
/* structSize */ sizeof(WeightVGProximityModifierData),
+ /* srna */ &RNA_VertexWeightProximityModifier,
/* type */ eModifierTypeType_NonGeometrical,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_UsesPreview,
+ /* icon */ ICON_MOD_VERTEX_WEIGHT,
/* copyData */ BKE_modifier_copydata_generic,
@@ -735,7 +731,6 @@ ModifierTypeInfo modifierType_WeightVGProximity = {
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ foreachTexLink,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_weld.c b/source/blender/modifiers/intern/MOD_weld.c
index 855f96df82f..1a25c24fedc 100644
--- a/source/blender/modifiers/intern/MOD_weld.c
+++ b/source/blender/modifiers/intern/MOD_weld.c
@@ -27,23 +27,32 @@
* - Review weight and vertex color interpolation.;
*/
+//#define USE_WELD_DEBUG
+//#define USE_WELD_NORMALS
+//#define USE_BVHTREEKDOP
+
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
#include "BLI_alloca.h"
-#include "BLI_kdopbvh.h"
+#include "BLI_bitmap.h"
+#include "BLI_kdtree.h"
#include "BLI_math.h"
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
-#include "BKE_bvhutils.h"
+#ifdef USE_BVHTREEKDOP
+# include "BKE_bvhutils.h"
+#endif
+
#include "BKE_context.h"
#include "BKE_deform.h"
#include "BKE_mesh.h"
@@ -60,9 +69,6 @@
#include "MOD_modifiertypes.h"
#include "MOD_ui_common.h"
-//#define USE_WELD_DEBUG
-//#define USE_WELD_NORMALS
-
/* Indicates when the element was not computed. */
#define OUT_OF_CONTEXT (uint)(-1)
/* Indicates if the edge or face will be collapsed. */
@@ -136,9 +142,6 @@ typedef struct WeldMesh {
/* Group of vertices to be merged. */
struct WeldGroup *vert_groups;
uint *vert_groups_buffer;
- /* From the original index of the vertex, this indicates which group it is or is going to be
- * merged. */
- uint *vert_groups_map;
/* Group of edges to be merged. */
struct WeldGroupEdge *edge_groups;
@@ -202,21 +205,6 @@ static bool weld_iter_loop_of_poly_begin(WeldLoopOfPolyIter *iter,
static bool weld_iter_loop_of_poly_next(WeldLoopOfPolyIter *iter);
-static void weld_assert_vert_dest_map_setup(const BVHTreeOverlap *overlap,
- const uint overlap_len,
- const uint *vert_dest_map)
-{
- const BVHTreeOverlap *overlap_iter = &overlap[0];
- for (uint i = overlap_len; i--; overlap_iter++) {
- uint indexA = overlap_iter->indexA;
- uint indexB = overlap_iter->indexB;
- uint va_dst = vert_dest_map[indexA];
- uint vb_dst = vert_dest_map[indexB];
-
- BLI_assert(va_dst == vb_dst);
- }
-}
-
static void weld_assert_edge_kill_len(const WeldEdge *wedge,
const uint wedge_len,
const uint supposed_kill_len)
@@ -383,69 +371,10 @@ static void weld_assert_poly_len(const WeldPoly *wp, const WeldLoop *wloop)
* \{ */
static void weld_vert_ctx_alloc_and_setup(const uint mvert_len,
- const BVHTreeOverlap *overlap,
- const uint overlap_len,
uint *r_vert_dest_map,
WeldVert **r_wvert,
- uint *r_wvert_len,
- uint *r_vert_kill_len)
+ uint *r_wvert_len)
{
- uint *v_dest_iter = &r_vert_dest_map[0];
- for (uint i = mvert_len; i--; v_dest_iter++) {
- *v_dest_iter = OUT_OF_CONTEXT;
- }
-
- uint vert_kill_len = 0;
- const BVHTreeOverlap *overlap_iter = &overlap[0];
- for (uint i = 0; i < overlap_len; i++, overlap_iter++) {
- uint indexA = overlap_iter->indexA;
- uint indexB = overlap_iter->indexB;
-
- BLI_assert(indexA < indexB);
-
- uint va_dst = r_vert_dest_map[indexA];
- uint vb_dst = r_vert_dest_map[indexB];
- if (va_dst == OUT_OF_CONTEXT) {
- if (vb_dst == OUT_OF_CONTEXT) {
- vb_dst = indexA;
- r_vert_dest_map[indexB] = vb_dst;
- }
- r_vert_dest_map[indexA] = vb_dst;
- vert_kill_len++;
- }
- else if (vb_dst == OUT_OF_CONTEXT) {
- r_vert_dest_map[indexB] = va_dst;
- vert_kill_len++;
- }
- else if (va_dst != vb_dst) {
- uint v_new, v_old;
- if (va_dst < vb_dst) {
- v_new = va_dst;
- v_old = vb_dst;
- }
- else {
- v_new = vb_dst;
- v_old = va_dst;
- }
- BLI_assert(r_vert_dest_map[v_old] == v_old);
- BLI_assert(r_vert_dest_map[v_new] == v_new);
- vert_kill_len++;
-
- const BVHTreeOverlap *overlap_iter_b = &overlap[0];
- for (uint j = i + 1; j--; overlap_iter_b++) {
- indexA = overlap_iter_b->indexA;
- indexB = overlap_iter_b->indexB;
- va_dst = r_vert_dest_map[indexA];
- vb_dst = r_vert_dest_map[indexB];
- if (ELEM(v_old, vb_dst, va_dst)) {
- r_vert_dest_map[indexA] = v_new;
- r_vert_dest_map[indexB] = v_new;
- }
- }
- BLI_assert(r_vert_dest_map[v_old] == v_new);
- }
- }
-
/* Vert Context. */
uint wvert_len = 0;
@@ -453,7 +382,7 @@ static void weld_vert_ctx_alloc_and_setup(const uint mvert_len,
wvert = MEM_mallocN(sizeof(*wvert) * mvert_len, __func__);
wv = &wvert[0];
- v_dest_iter = &r_vert_dest_map[0];
+ uint *v_dest_iter = &r_vert_dest_map[0];
for (uint i = 0; i < mvert_len; i++, v_dest_iter++) {
if (*v_dest_iter != OUT_OF_CONTEXT) {
wv->vert_dest = *v_dest_iter;
@@ -463,13 +392,8 @@ static void weld_vert_ctx_alloc_and_setup(const uint mvert_len,
}
}
-#ifdef USE_WELD_DEBUG
- weld_assert_vert_dest_map_setup(overlap, overlap_len, r_vert_dest_map);
-#endif
-
*r_wvert = MEM_reallocN(wvert, sizeof(*wvert) * wvert_len);
*r_wvert_len = wvert_len;
- *r_vert_kill_len = vert_kill_len;
}
static void weld_vert_groups_setup(const uint mvert_len,
@@ -1395,8 +1319,8 @@ static void weld_poly_loop_ctx_setup(const MLoop *mloop,
* \{ */
static void weld_mesh_context_create(const Mesh *mesh,
- BVHTreeOverlap *overlap,
- const uint overlap_len,
+ uint *vert_dest_map,
+ const uint vert_kill_len,
WeldMesh *r_weld_mesh)
{
const MEdge *medge = mesh->medge;
@@ -1407,19 +1331,13 @@ static void weld_mesh_context_create(const Mesh *mesh,
const uint mloop_len = mesh->totloop;
const uint mpoly_len = mesh->totpoly;
- uint *vert_dest_map = MEM_mallocN(sizeof(*vert_dest_map) * mvert_len, __func__);
uint *edge_dest_map = MEM_mallocN(sizeof(*edge_dest_map) * medge_len, __func__);
struct WeldGroup *v_links = MEM_callocN(sizeof(*v_links) * mvert_len, __func__);
WeldVert *wvert;
uint wvert_len;
- weld_vert_ctx_alloc_and_setup(mvert_len,
- overlap,
- overlap_len,
- vert_dest_map,
- &wvert,
- &wvert_len,
- &r_weld_mesh->vert_kill_len);
+ r_weld_mesh->vert_kill_len = vert_kill_len;
+ weld_vert_ctx_alloc_and_setup(mvert_len, vert_dest_map, &wvert, &wvert_len);
uint *edge_ctx_map;
WeldEdge *wedge;
@@ -1462,7 +1380,6 @@ static void weld_mesh_context_create(const Mesh *mesh,
&r_weld_mesh->edge_groups_buffer,
&r_weld_mesh->edge_groups);
- r_weld_mesh->vert_groups_map = vert_dest_map;
r_weld_mesh->edge_groups_map = edge_dest_map;
MEM_freeN(v_links);
MEM_freeN(wvert);
@@ -1474,7 +1391,6 @@ static void weld_mesh_context_free(WeldMesh *weld_mesh)
{
MEM_freeN(weld_mesh->vert_groups);
MEM_freeN(weld_mesh->vert_groups_buffer);
- MEM_freeN(weld_mesh->vert_groups_map);
MEM_freeN(weld_mesh->edge_groups);
MEM_freeN(weld_mesh->edge_groups_buffer);
@@ -1633,6 +1549,7 @@ static void customdata_weld(
/** \name Weld Modifier Main
* \{ */
+#ifdef USE_BVHTREEKDOP
struct WeldOverlapData {
const MVert *mvert;
float merge_dist_sq;
@@ -1648,6 +1565,7 @@ static bool bvhtree_weld_overlap_cb(void *userdata, int index_a, int index_b, in
}
return false;
}
+#endif
static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContext *ctx, Mesh *mesh)
{
@@ -1661,7 +1579,6 @@ static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContex
const MLoop *mloop;
const MPoly *mpoly, *mp;
uint totvert, totedge, totloop, totpoly;
- uint i;
mvert = mesh->mvert;
totvert = mesh->totvert;
@@ -1675,7 +1592,7 @@ static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContex
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++) {
+ for (uint i = 0; i < totvert; i++, dv++) {
const bool found = BKE_defvert_find_weight(dv, defgrp_index) > 0.0f;
if (found != invert_vgroup) {
BLI_BITMAP_ENABLE(v_mask, i);
@@ -1685,48 +1602,113 @@ static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContex
}
}
- /* Get overlap map. */
- /* TODO: For a better performanse use KD-Tree. */
- struct BVHTreeFromMesh treedata;
- BVHTree *bvhtree = bvhtree_from_mesh_verts_ex(&treedata,
- mvert,
- totvert,
- false,
- v_mask,
- v_mask_act,
- wmd->merge_dist / 2,
- 2,
- 6,
- 0,
- NULL,
- NULL);
+ /* From the original index of the vertex.
+ * This indicates which vert it is or is going to be merged. */
+ uint *vert_dest_map = MEM_malloc_arrayN(totvert, sizeof(*vert_dest_map), __func__);
+ uint vert_kill_len = 0;
+#ifdef USE_BVHTREEKDOP
+ {
+ /* Get overlap map. */
+ struct BVHTreeFromMesh treedata;
+ BVHTree *bvhtree = bvhtree_from_mesh_verts_ex(&treedata,
+ mvert,
+ totvert,
+ false,
+ v_mask,
+ v_mask_act,
+ wmd->merge_dist / 2,
+ 2,
+ 6,
+ 0,
+ NULL,
+ NULL);
+
+ if (bvhtree) {
+ struct WeldOverlapData data;
+ data.mvert = mvert;
+ data.merge_dist_sq = square_f(wmd->merge_dist);
+
+ uint overlap_len;
+ BVHTreeOverlap *overlap = BLI_bvhtree_overlap_ex(bvhtree,
+ bvhtree,
+ &overlap_len,
+ bvhtree_weld_overlap_cb,
+ &data,
+ 1,
+ BVH_OVERLAP_RETURN_PAIRS);
+
+ free_bvhtree_from_mesh(&treedata);
+ if (overlap) {
+ range_vn_u(vert_dest_map, totvert, 0);
+
+ const BVHTreeOverlap *overlap_iter = &overlap[0];
+ for (uint i = 0; i < overlap_len; i++, overlap_iter++) {
+ uint indexA = overlap_iter->indexA;
+ uint indexB = overlap_iter->indexB;
+
+ BLI_assert(indexA < indexB);
+
+ uint va_dst = vert_dest_map[indexA];
+ while (va_dst != vert_dest_map[va_dst]) {
+ va_dst = vert_dest_map[va_dst];
+ }
+ uint vb_dst = vert_dest_map[indexB];
+ while (vb_dst != vert_dest_map[vb_dst]) {
+ vb_dst = vert_dest_map[vb_dst];
+ }
+ if (va_dst == vb_dst) {
+ continue;
+ }
+ if (va_dst > vb_dst) {
+ SWAP(uint, va_dst, vb_dst);
+ }
+ vert_kill_len++;
+ vert_dest_map[vb_dst] = va_dst;
+ }
- if (v_mask) {
- MEM_freeN(v_mask);
- }
+ /* Fix #r_vert_dest_map for next step. */
+ for (uint i = 0; i < totvert; i++) {
+ if (i == vert_dest_map[i]) {
+ vert_dest_map[i] = OUT_OF_CONTEXT;
+ }
+ else {
+ uint v = i;
+ while (v != vert_dest_map[v] && vert_dest_map[v] != OUT_OF_CONTEXT) {
+ v = vert_dest_map[v];
+ }
+ vert_dest_map[v] = v;
+ vert_dest_map[i] = v;
+ }
+ }
- if (bvhtree == NULL) {
- return result;
+ MEM_freeN(overlap);
+ }
+ }
}
+#else
+ {
+ KDTree_3d *tree = BLI_kdtree_3d_new(v_mask ? v_mask_act : totvert);
+ for (uint i = 0; i < totvert; i++) {
+ if (!v_mask || BLI_BITMAP_TEST(v_mask, i)) {
+ BLI_kdtree_3d_insert(tree, i, mvert[i].co);
+ }
+ vert_dest_map[i] = OUT_OF_CONTEXT;
+ }
- struct WeldOverlapData data;
- data.mvert = mvert;
- data.merge_dist_sq = square_f(wmd->merge_dist);
-
- uint overlap_len;
- BVHTreeOverlap *overlap = BLI_bvhtree_overlap_ex(bvhtree,
- bvhtree,
- &overlap_len,
- bvhtree_weld_overlap_cb,
- &data,
- wmd->max_interactions,
- BVH_OVERLAP_RETURN_PAIRS);
+ BLI_kdtree_3d_balance(tree);
+ vert_kill_len = BLI_kdtree_3d_calc_duplicates_fast(
+ tree, wmd->merge_dist, false, (int *)vert_dest_map);
+ BLI_kdtree_3d_free(tree);
+ }
+#endif
- free_bvhtree_from_mesh(&treedata);
+ if (v_mask) {
+ MEM_freeN(v_mask);
+ }
- if (overlap_len) {
+ if (vert_kill_len) {
WeldMesh weld_mesh;
- weld_mesh_context_create(mesh, overlap, overlap_len, &weld_mesh);
+ weld_mesh_context_create(mesh, vert_dest_map, vert_kill_len, &weld_mesh);
mloop = mesh->mloop;
mpoly = mesh->mpoly;
@@ -1745,10 +1727,10 @@ static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContex
/* Vertices */
- uint *vert_final = weld_mesh.vert_groups_map;
+ uint *vert_final = vert_dest_map;
uint *index_iter = &vert_final[0];
int dest_index = 0;
- for (i = 0; i < totvert; i++, index_iter++) {
+ for (uint i = 0; i < totvert; i++, index_iter++) {
int source_index = i;
int count = 0;
while (i < totvert && *index_iter == OUT_OF_CONTEXT) {
@@ -1783,7 +1765,7 @@ static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContex
uint *edge_final = weld_mesh.edge_groups_map;
index_iter = &edge_final[0];
dest_index = 0;
- for (i = 0; i < totedge; i++, index_iter++) {
+ for (uint i = 0; i < totedge; i++, index_iter++) {
int source_index = i;
int count = 0;
while (i < totedge && *index_iter == OUT_OF_CONTEXT) {
@@ -1831,7 +1813,7 @@ static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContex
uint r_i = 0;
int loop_cur = 0;
uint *group_buffer = BLI_array_alloca(group_buffer, weld_mesh.max_poly_len);
- for (i = 0; i < totpoly; i++, mp++) {
+ for (uint i = 0; i < totpoly; i++, mp++) {
int loop_start = loop_cur;
uint poly_ctx = weld_mesh.poly_map[i];
if (poly_ctx == OUT_OF_CONTEXT) {
@@ -1877,7 +1859,7 @@ static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContex
}
WeldPoly *wp = &weld_mesh.wpoly_new[0];
- for (i = 0; i < weld_mesh.wpoly_new_len; i++, wp++) {
+ for (uint i = 0; i < weld_mesh.wpoly_new_len; i++, wp++) {
int loop_start = loop_cur;
WeldLoopOfPolyIter iter;
if (!weld_iter_loop_of_poly_begin(
@@ -1918,7 +1900,7 @@ static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContex
weld_mesh_context_free(&weld_mesh);
}
- MEM_freeN(overlap);
+ MEM_freeN(vert_dest_map);
return result;
}
@@ -1932,9 +1914,9 @@ static void initData(ModifierData *md)
{
WeldModifierData *wmd = (WeldModifierData *)md;
- wmd->merge_dist = 0.001f;
- wmd->max_interactions = 1;
- wmd->defgrp_name[0] = '\0';
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(wmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(wmd, DNA_struct_default_get(WeldModifierData), modifier);
}
static void requiredDataMask(Object *UNUSED(ob),
@@ -1959,7 +1941,6 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropSep(layout, true);
uiItemR(layout, ptr, "merge_threshold", 0, IFACE_("Distance"), ICON_NONE);
- uiItemR(layout, ptr, "max_interactions", 0, NULL, ICON_NONE);
modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
modifier_panel_end(layout, ptr);
@@ -1974,10 +1955,12 @@ ModifierTypeInfo modifierType_Weld = {
/* name */ "Weld",
/* structName */ "WeldModifierData",
/* structSize */ sizeof(WeldModifierData),
+ /* srna */ &RNA_WeldModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode |
eModifierTypeFlag_AcceptsCVs,
+ /* icon */ ICON_AUTOMERGE_OFF, /* TODO: Use correct icon. */
/* copyData */ BKE_modifier_copydata_generic,
@@ -1997,7 +1980,6 @@ ModifierTypeInfo modifierType_Weld = {
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_wireframe.c b/source/blender/modifiers/intern/MOD_wireframe.c
index 602e0bf3eda..206c514826c 100644
--- a/source/blender/modifiers/intern/MOD_wireframe.c
+++ b/source/blender/modifiers/intern/MOD_wireframe.c
@@ -24,6 +24,7 @@
#include "BLT_translation.h"
+#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
@@ -47,9 +48,10 @@
static void initData(ModifierData *md)
{
WireframeModifierData *wmd = (WireframeModifierData *)md;
- wmd->offset = 0.02f;
- wmd->flag = MOD_WIREFRAME_REPLACE | MOD_WIREFRAME_OFS_EVEN;
- wmd->crease_weight = 1.0f;
+
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(wmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(wmd, DNA_struct_default_get(WireframeModifierData), modifier);
}
static void requiredDataMask(Object *UNUSED(ob),
@@ -180,8 +182,10 @@ ModifierTypeInfo modifierType_Wireframe = {
/* name */ "Wireframe",
/* structName */ "WireframeModifierData",
/* structSize */ sizeof(WireframeModifierData),
+ /* srna */ &RNA_WireframeModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
+ /* icon */ ICON_MOD_WIREFRAME,
/* copyData */ BKE_modifier_copydata_generic,
@@ -201,7 +205,6 @@ ModifierTypeInfo modifierType_Wireframe = {
/* updateDepgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,