Modifiers: include the object & modifier when logging errors

Without this, there was no way of finding out which object, modifier
combination caused the error, making the logs not very useful
for debugging.
This commit is contained in:
Campbell Barton 2020-10-26 17:07:58 +11:00
parent aa77689f77
commit e4facbbea5
Notes: blender-bot 2023-02-14 02:13:08 +01:00
Referenced by commit ed4855ecb4, Modifiers: Fix wrong object when setting error in modifier
30 changed files with 202 additions and 130 deletions

View File

@ -364,6 +364,7 @@ struct Mesh *editbmesh_get_eval_cage_and_final(struct Depsgraph *depsgraph,
float (*editbmesh_vert_coords_alloc(struct BMEditMesh *em, int *r_vert_len))[3];
bool editbmesh_modifier_is_enabled(struct Scene *scene,
const struct Object *ob,
struct ModifierData *md,
bool has_prev_mesh);
void makeDerivedMesh(struct Depsgraph *depsgraph,

View File

@ -427,8 +427,10 @@ bool BKE_modifier_is_non_geometrical(ModifierData *md);
bool BKE_modifier_is_enabled(const struct Scene *scene,
struct ModifierData *md,
int required_mode);
void BKE_modifier_set_error(struct ModifierData *md, const char *format, ...)
ATTR_PRINTF_FORMAT(2, 3);
void BKE_modifier_set_error(const struct Object *ob,
struct ModifierData *md,
const char *format,
...) ATTR_PRINTF_FORMAT(3, 4);
bool BKE_modifier_is_preview(struct ModifierData *md);
void BKE_modifiers_foreach_ID_link(struct Object *ob, IDWalkFunc walk, void *userData);

View File

@ -167,7 +167,7 @@ typedef struct PTCacheID {
* (the cfra parameter is just for using same function pointer with totwrite). */
int (*totpoint)(void *calldata, int cfra);
/* report error if number of points does not match */
void (*error)(void *calldata, const char *message);
void (*error)(const struct ID *owner_id, void *calldata, const char *message);
/* number of points written for current cache frame */
int (*totwrite)(void *calldata, int cfra);

View File

@ -1021,7 +1021,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) &&
have_non_onlydeform_modifiers_appled) {
BKE_modifier_set_error(md, "Modifier requires original data, bad stack position");
BKE_modifier_set_error(ob, md, "Modifier requires original data, bad stack position");
continue;
}
@ -1047,10 +1047,10 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
if (unsupported) {
if (sculpt_dyntopo) {
BKE_modifier_set_error(md, "Not supported in dyntopo");
BKE_modifier_set_error(ob, md, "Not supported in dyntopo");
}
else {
BKE_modifier_set_error(md, "Not supported in sculpt mode");
BKE_modifier_set_error(ob, md, "Not supported in sculpt mode");
}
continue;
}
@ -1378,7 +1378,10 @@ float (*editbmesh_vert_coords_alloc(BMEditMesh *em, int *r_vert_len))[3]
return cos;
}
bool editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, bool has_prev_mesh)
bool editbmesh_modifier_is_enabled(Scene *scene,
const Object *ob,
ModifierData *md,
bool has_prev_mesh)
{
const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
const int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
@ -1388,7 +1391,7 @@ bool editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, bool has_prev
}
if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && has_prev_mesh) {
BKE_modifier_set_error(md, "Modifier requires original data, bad stack position");
BKE_modifier_set_error(ob, md, "Modifier requires original data, bad stack position");
return false;
}
@ -1522,7 +1525,7 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
for (int i = 0; md; i++, md = md->next, md_datamask = md_datamask->next) {
const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
if (!editbmesh_modifier_is_enabled(scene, md, mesh_final != NULL)) {
if (!editbmesh_modifier_is_enabled(scene, ob, md, mesh_final != NULL)) {
continue;
}

View File

@ -55,7 +55,7 @@
/* Prototypes for internal functions.
*/
static void cloth_to_object(Object *ob, ClothModifierData *clmd, float (*vertexCos)[3]);
static void cloth_from_mesh(ClothModifierData *clmd, Mesh *mesh);
static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh);
static bool cloth_from_object(
Object *ob, ClothModifierData *clmd, Mesh *mesh, float framenr, int first);
static void cloth_update_springs(ClothModifierData *clmd);
@ -234,13 +234,13 @@ static bool do_init_cloth(Object *ob, ClothModifierData *clmd, Mesh *result, int
if (clmd->clothObject == NULL) {
if (!cloth_from_object(ob, clmd, result, framenr, 1)) {
BKE_ptcache_invalidate(cache);
BKE_modifier_set_error(&(clmd->modifier), "Can't initialize cloth");
BKE_modifier_set_error(ob, &(clmd->modifier), "Can't initialize cloth");
return false;
}
if (clmd->clothObject == NULL) {
BKE_ptcache_invalidate(cache);
BKE_modifier_set_error(&(clmd->modifier), "Null cloth object");
BKE_modifier_set_error(ob, &(clmd->modifier), "Null cloth object");
return false;
}
@ -742,7 +742,7 @@ static bool cloth_from_object(
clmd->clothObject->edgeset = NULL;
}
else {
BKE_modifier_set_error(&(clmd->modifier), "Out of memory on allocating clmd->clothObject");
BKE_modifier_set_error(ob, &(clmd->modifier), "Out of memory on allocating clmd->clothObject");
return false;
}
@ -751,7 +751,7 @@ static bool cloth_from_object(
return false;
}
cloth_from_mesh(clmd, mesh);
cloth_from_mesh(clmd, ob, mesh);
/* create springs */
clmd->clothObject->springs = NULL;
@ -814,7 +814,7 @@ static bool cloth_from_object(
if (!cloth_build_springs(clmd, mesh)) {
cloth_free_modifier(clmd);
BKE_modifier_set_error(&(clmd->modifier), "Cannot build springs");
BKE_modifier_set_error(ob, &(clmd->modifier), "Cannot build springs");
return false;
}
@ -831,7 +831,7 @@ static bool cloth_from_object(
return true;
}
static void cloth_from_mesh(ClothModifierData *clmd, Mesh *mesh)
static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh)
{
const MLoop *mloop = mesh->mloop;
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh);
@ -844,8 +844,8 @@ static void cloth_from_mesh(ClothModifierData *clmd, Mesh *mesh)
"clothVertex");
if (clmd->clothObject->verts == NULL) {
cloth_free_modifier(clmd);
BKE_modifier_set_error(&(clmd->modifier),
"Out of memory on allocating clmd->clothObject->verts");
BKE_modifier_set_error(
ob, &(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts");
printf("cloth_free_modifier clmd->clothObject->verts\n");
return;
}
@ -861,8 +861,8 @@ static void cloth_from_mesh(ClothModifierData *clmd, Mesh *mesh)
clmd->clothObject->tri = MEM_mallocN(sizeof(MVertTri) * looptri_num, "clothLoopTris");
if (clmd->clothObject->tri == NULL) {
cloth_free_modifier(clmd);
BKE_modifier_set_error(&(clmd->modifier),
"Out of memory on allocating clmd->clothObject->looptri");
BKE_modifier_set_error(
ob, &(clmd->modifier), "Out of memory on allocating clmd->clothObject->looptri");
printf("cloth_free_modifier clmd->clothObject->looptri\n");
return;
}

View File

@ -273,7 +273,7 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra
for (i = 0; md && i <= cageIndex; i++, md = md->next) {
const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
if (!editbmesh_modifier_is_enabled(scene, md, me != NULL)) {
if (!editbmesh_modifier_is_enabled(scene, ob, md, me != NULL)) {
continue;
}
@ -302,7 +302,7 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra
}
for (; md && i <= cageIndex; md = md->next, i++) {
if (editbmesh_modifier_is_enabled(scene, md, me != NULL) &&
if (editbmesh_modifier_is_enabled(scene, ob, md, me != NULL) &&
BKE_modifier_is_correctable_deformed(md)) {
numleft++;
}

View File

@ -389,7 +389,7 @@ bool BKE_modifier_is_non_geometrical(ModifierData *md)
return (mti->type == eModifierTypeType_NonGeometrical);
}
void BKE_modifier_set_error(ModifierData *md, const char *_format, ...)
void BKE_modifier_set_error(const Object *ob, ModifierData *md, const char *_format, ...)
{
char buffer[512];
va_list ap;
@ -406,7 +406,16 @@ void BKE_modifier_set_error(ModifierData *md, const char *_format, ...)
md->error = BLI_strdup(buffer);
CLOG_STR_ERROR(&LOG, md->error);
#ifndef NDEBUG
if ((md->mode & eModifierMode_Virtual) == 0) {
/* Ensure correct object is passed in. */
const Object *ob_orig = (Object *)DEG_get_original_id((ID *)&ob->id);
const ModifierData *md_orig = md->orig_modifier_data ? md->orig_modifier_data : md;
BLI_assert(BLI_findindex(&ob_orig->modifiers, md_orig) != -1);
}
#endif
CLOG_ERROR(&LOG, "Object: \"%s\", Modifier: \"%s\", %s", ob->id.name + 2, md->name, md->error);
}
/* used for buttons, to find out if the 'draw deformed in editmode' option is

View File

@ -256,7 +256,9 @@ static int ptcache_softbody_totpoint(void *soft_v, int UNUSED(cfra))
SoftBody *soft = soft_v;
return soft->totpoint;
}
static void ptcache_softbody_error(void *UNUSED(soft_v), const char *UNUSED(message))
static void ptcache_softbody_error(const ID *UNUSED(owner_id),
void *UNUSED(soft_v),
const char *UNUSED(message))
{
/* ignored for now */
}
@ -471,7 +473,9 @@ static int ptcache_particle_totpoint(void *psys_v, int UNUSED(cfra))
return psys->totpart;
}
static void ptcache_particle_error(void *UNUSED(psys_v), const char *UNUSED(message))
static void ptcache_particle_error(const ID *UNUSED(owner_id),
void *UNUSED(psys_v),
const char *UNUSED(message))
{
/* ignored for now */
}
@ -642,10 +646,11 @@ static int ptcache_cloth_totpoint(void *cloth_v, int UNUSED(cfra))
return clmd->clothObject ? clmd->clothObject->mvert_num : 0;
}
static void ptcache_cloth_error(void *cloth_v, const char *message)
static void ptcache_cloth_error(const ID *owner_id, void *cloth_v, const char *message)
{
ClothModifierData *clmd = cloth_v;
BKE_modifier_set_error(&clmd->modifier, "%s", message);
BLI_assert(GS(owner_id->name) == ID_OB);
BKE_modifier_set_error((Object *)owner_id, &clmd->modifier, "%s", message);
}
static int ptcache_dynamicpaint_totpoint(void *sd, int UNUSED(cfra))
@ -659,7 +664,9 @@ static int ptcache_dynamicpaint_totpoint(void *sd, int UNUSED(cfra))
return surface->data->total_points;
}
static void ptcache_dynamicpaint_error(void *UNUSED(sd), const char *UNUSED(message))
static void ptcache_dynamicpaint_error(const ID *UNUSED(owner_id),
void *UNUSED(sd),
const char *UNUSED(message))
{
/* ignored for now */
}
@ -853,7 +860,9 @@ static int ptcache_rigidbody_totpoint(void *rb_v, int UNUSED(cfra))
return rbw->numbodies;
}
static void ptcache_rigidbody_error(void *UNUSED(rb_v), const char *UNUSED(message))
static void ptcache_rigidbody_error(const struct ID *UNUSED(owner_id),
void *UNUSED(rb_v),
const char *UNUSED(message))
{
/* ignored for now */
}
@ -2098,19 +2107,19 @@ static int ptcache_read_stream(PTCacheID *pid, int cfra)
}
if (!ptcache_file_header_begin_read(pf)) {
pid->error(pid->calldata, "Failed to read point cache file");
pid->error(pid->owner_id, pid->calldata, "Failed to read point cache file");
error = 1;
}
else if (pf->type != pid->type) {
pid->error(pid->calldata, "Point cache file has wrong type");
pid->error(pid->owner_id, pid->calldata, "Point cache file has wrong type");
error = 1;
}
else if (!pid->read_header(pf)) {
pid->error(pid->calldata, "Failed to read point cache file header");
pid->error(pid->owner_id, pid->calldata, "Failed to read point cache file header");
error = 1;
}
else if (pf->totpoint != pid->totpoint(pid->calldata, cfra)) {
pid->error(pid->calldata, "Number of points in cache does not match mesh");
pid->error(pid->owner_id, pid->calldata, "Number of points in cache does not match mesh");
error = 1;
}
@ -2119,7 +2128,7 @@ static int ptcache_read_stream(PTCacheID *pid, int cfra)
/* We have stream reading here. */
if (!pid->read_stream(pf, pid->calldata)) {
pid->error(pid->calldata, "Failed to read point cache file data");
pid->error(pid->owner_id, pid->calldata, "Failed to read point cache file data");
error = 1;
}
}
@ -2155,7 +2164,7 @@ static int ptcache_read(PTCacheID *pid, int cfra)
int pid_totpoint = pid->totpoint(pid->calldata, cfra);
if (totpoint != pid_totpoint) {
pid->error(pid->calldata, "Number of points in cache does not match mesh");
pid->error(pid->owner_id, pid->calldata, "Number of points in cache does not match mesh");
totpoint = MIN2(totpoint, pid_totpoint);
}
}
@ -2211,7 +2220,7 @@ static int ptcache_interpolate(PTCacheID *pid, float cfra, int cfra1, int cfra2)
int pid_totpoint = pid->totpoint(pid->calldata, (int)cfra);
if (totpoint != pid_totpoint) {
pid->error(pid->calldata, "Number of points in cache does not match mesh");
pid->error(pid->owner_id, pid->calldata, "Number of points in cache does not match mesh");
totpoint = MIN2(totpoint, pid_totpoint);
}
}

View File

@ -1547,7 +1547,8 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind
}
}
else {
BKE_modifier_set_error(&mmd->modifier, "Failed to find bind solution (increase precision?)");
BKE_modifier_set_error(
mmd->object, &mmd->modifier, "Failed to find bind solution (increase precision?)");
error("Mesh Deform: failed to find bind solution.");
break;
}

View File

@ -508,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");
}
@ -518,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");
}

View File

@ -208,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;
}

View File

@ -189,7 +189,7 @@ static int bm_face_isect_pair(BMFace *f, void *UNUSED(user_data))
return BM_elem_flag_test(f, BM_FACE_TAG) ? 1 : 0;
}
static bool BMD_error_messages(ModifierData *md, Collection *col)
static bool BMD_error_messages(const Object *ob, ModifierData *md, Collection *col)
{
BooleanModifierData *bmd = (BooleanModifierData *)md;
@ -202,21 +202,21 @@ static bool BMD_error_messages(ModifierData *md, Collection *col)
#ifndef WITH_GMP
/* If compiled without GMP, return a error. */
if (use_exact) {
BKE_modifier_set_error(md, "Compiled without GMP, using fast solver");
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(md, "Cannot execute, intersect only available using exact solver");
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(md, "Cannot execute, fast solver and empty collection");
BKE_modifier_set_error(ob, md, "Cannot execute, fast solver and empty collection");
error_returns_result = true;
}
@ -225,7 +225,7 @@ static bool BMD_error_messages(ModifierData *md, Collection *col)
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (col, operand_ob) {
if (operand_ob->type != OB_MESH) {
BKE_modifier_set_error(
md, "Cannot execute, the selected collection contains non mesh objects");
ob, md, "Cannot execute, the selected collection contains non mesh objects");
error_returns_result = true;
}
}
@ -587,7 +587,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
return result;
}
BMD_error_messages(md, NULL);
BMD_error_messages(ctx->object, md, NULL);
Object *operand_ob = bmd->object;
@ -615,7 +615,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* 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");
BKE_modifier_set_error(object, md, "Cannot execute boolean operation");
}
}
}
@ -626,7 +626,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
/* Return result for certain errors. */
if (BMD_error_messages(md, col) == confirm_return) {
if (BMD_error_messages(ctx->object, md, col) == confirm_return) {
return result;
}
@ -669,7 +669,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* 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");
BKE_modifier_set_error(object, md, "Cannot execute boolean operation");
}
}
}

View File

@ -615,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");
}
}
@ -625,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;
}
@ -633,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 {
@ -648,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;
}
}

View File

@ -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;

View File

@ -140,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;
}

View File

@ -684,14 +684,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);
}
@ -704,8 +705,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) {
@ -725,7 +728,7 @@ 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");
}
}

View File

@ -82,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,

View File

@ -273,8 +273,8 @@ static Volume *modifyVolume(ModifierData *md, const ModifierEvalContext *ctx, Vo
return volume;
#else
UNUSED_VARS(md, ctx);
BKE_modifier_set_error(md, "Compiled without OpenVDB");
UNUSED_VARS(md);
BKE_modifier_set_error(ctx->object, md, "Compiled without OpenVDB");
return input_volume;
#endif
}

View File

@ -171,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! */
@ -216,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;

View File

@ -373,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;
}
@ -388,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) {
@ -405,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;
}

View File

@ -127,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;
}
}
@ -170,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)) {

View File

@ -216,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;
@ -300,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

View File

@ -476,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;
}
@ -491,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;
}
@ -506,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;
}

View File

@ -1760,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;
@ -1802,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
@ -1848,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;
@ -1878,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) {
@ -1904,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;
@ -1914,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;
@ -1934,11 +1938,25 @@ static void initData(ModifierData *md)
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 (!(result = final_skin((SkinModifierData *)md, mesh))) {
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 == NULL) {
return mesh;
}
return result;

View File

@ -2501,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);

View File

@ -254,7 +254,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
SubsurfModifierData *smd = (SubsurfModifierData *)md;
@ -309,7 +309,7 @@ static void deformMatrices(ModifierData *md,
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

View File

@ -1009,7 +1009,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 +1031,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 +1052,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 +1070,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 +1098,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 +1117,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 +1138,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 +1235,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 +1247,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 +1257,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 +1271,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,11 +1280,12 @@ 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;
}

View File

@ -307,7 +307,7 @@ static Volume *modifyVolume(ModifierData *md, const ModifierEvalContext *ctx, Vo
return volume;
#else
UNUSED_VARS(md, ctx);
BKE_modifier_set_error(md, "Compiled without OpenVDB");
BKE_modifier_set_error(ctx->object, md, "Compiled without OpenVDB");
return volume;
#endif
}

View File

@ -281,7 +281,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
VolumeGrid *volume_grid = BKE_volume_grid_find(volume, vmmd->grid_name);
if (volume_grid == nullptr) {
BKE_modifier_set_error(md, "Cannot find '%s' grid", vmmd->grid_name);
BKE_modifier_set_error(vmmd->object, md, "Cannot find '%s' grid", vmmd->grid_name);
return input_mesh;
}
@ -290,7 +290,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
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(md, "Expected a scalar grid");
BKE_modifier_set_error(ctx->object, md, "Expected a scalar grid");
return input_mesh;
}
@ -301,8 +301,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
return mesh;
#else
UNUSED_VARS(md, ctx);
BKE_modifier_set_error(md, "Compiled without OpenVDB");
UNUSED_VARS(md);
BKE_modifier_set_error(ctx->object, md, "Compiled without OpenVDB");
return input_mesh;
#endif
}

View File

@ -574,7 +574,8 @@ 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;
}