Fix incorrect reporting for the quadreflow operator

- When called from Python, the operator would always return
  success even on failure.
- Errors are now reported to the operator or to the job-systems
  wmJobWorkerStatus::reports.
- Failure now returns OPERATOR_CANCELLED;
- Replace magic numbers with an enum.
This commit is contained in:
Campbell Barton
2025-03-11 14:07:19 +11:00
parent f36a3bba81
commit cdea7c32ec

View File

@@ -636,6 +636,13 @@ enum {
QUADRIFLOW_REMESH_FACES,
};
enum eQuadreFlowStatus {
QUADRIFLOW_STATUS_SUCCESS = 1,
QUADRIFLOW_STATUS_FAIL = 0,
QUADRIFLOW_STATUS_CANCELED = -1,
QUADRIFLOW_STATUS_NONMANIFOLD = -2,
};
enum eSymmetryAxes {
SYMMETRY_AXES_X = (1 << 0),
SYMMETRY_AXES_Y = (1 << 1),
@@ -645,8 +652,7 @@ enum eSymmetryAxes {
struct QuadriFlowJob {
/* from wmJob */
Object *owner;
bool *stop, *do_update;
float *progress;
wmJobWorkerStatus *worker_status;
const wmOperator *op;
Scene *scene;
@@ -662,7 +668,7 @@ struct QuadriFlowJob {
bool preserve_attributes;
bool smooth_normals;
int success;
eQuadreFlowStatus status;
bool is_nonblocking_job;
};
@@ -739,13 +745,14 @@ static int quadriflow_break_job(void *customdata)
// return *(qj->stop);
/* this is not nice yet, need to make the jobs list template better
* for identifying/acting upon various different jobs */
* for identifying/acting upon various different jobs canceled */
/* but for now we'll reuse the render break... */
bool should_break = false;
if (qj->is_nonblocking_job) {
bool should_break = (G.is_break);
if (should_break) {
qj->success = -1;
qj->status = QUADRIFLOW_STATUS_CANCELED;
}
}
@@ -764,8 +771,8 @@ static void quadriflow_update_job(void *customdata, float progress, int *cancel)
*cancel = 0;
}
*(qj->do_update) = true;
*(qj->progress) = progress;
qj->worker_status->do_update = true;
qj->worker_status->progress = progress;
}
static Mesh *remesh_symmetry_bisect(Mesh *mesh, eSymmetryAxes symmetry_axes)
@@ -834,10 +841,8 @@ static void quadriflow_start_job(void *customdata, wmJobWorkerStatus *worker_sta
{
QuadriFlowJob *qj = static_cast<QuadriFlowJob *>(customdata);
qj->stop = &worker_status->stop;
qj->do_update = &worker_status->do_update;
qj->progress = &worker_status->progress;
qj->success = 1;
qj->worker_status = worker_status;
qj->status = QUADRIFLOW_STATUS_SUCCESS;
if (qj->is_nonblocking_job) {
G.is_break = false; /* XXX shared with render - replace with job 'stop' switch */
@@ -851,7 +856,7 @@ static void quadriflow_start_job(void *customdata, wmJobWorkerStatus *worker_sta
/* Check if the mesh is manifold. Quadriflow requires manifold meshes */
if (!mesh_is_manifold_consistent(mesh)) {
qj->success = -2;
qj->status = QUADRIFLOW_STATUS_NONMANIFOLD;
return;
}
@@ -880,9 +885,9 @@ static void quadriflow_start_job(void *customdata, wmJobWorkerStatus *worker_sta
if (new_mesh == nullptr) {
worker_status->do_update = true;
worker_status->stop = false;
if (qj->success == 1) {
if (qj->status == QUADRIFLOW_STATUS_SUCCESS) {
/* This is not a user cancellation event. */
qj->success = 0;
qj->status = QUADRIFLOW_STATUS_FAIL;
}
return;
}
@@ -923,22 +928,23 @@ static void quadriflow_end_job(void *customdata)
WM_set_locked_interface(static_cast<wmWindowManager *>(G_MAIN->wm.first), false);
}
switch (qj->success) {
case 1:
ReportList *reports = qj->worker_status->reports;
switch (qj->status) {
case QUADRIFLOW_STATUS_SUCCESS:
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_global_reportf(RPT_INFO, "QuadriFlow: Remeshing completed");
BKE_reportf(reports, RPT_INFO, "QuadriFlow: Remeshing completed");
break;
case 0:
WM_global_reportf(RPT_ERROR, "QuadriFlow: Remeshing failed");
case QUADRIFLOW_STATUS_FAIL:
BKE_reportf(reports, RPT_ERROR, "QuadriFlow: Remeshing failed");
break;
case -1:
WM_global_report(RPT_WARNING, "QuadriFlow: Remeshing canceled");
case QUADRIFLOW_STATUS_CANCELED:
BKE_report(reports, RPT_WARNING, "QuadriFlow: Remeshing canceled");
break;
case -2:
WM_global_report(
RPT_WARNING,
"QuadriFlow: The mesh needs to be manifold and have face normals that point in a "
"consistent direction");
case QUADRIFLOW_STATUS_NONMANIFOLD:
BKE_report(reports,
RPT_WARNING,
"QuadriFlow: The mesh needs to be manifold and have face normals that point in a "
"consistent direction");
break;
}
}
@@ -983,11 +989,15 @@ static int quadriflow_remesh_exec(bContext *C, wmOperator *op)
job->symmetry_axes = (eSymmetryAxes)0;
}
eQuadreFlowStatus status = QUADRIFLOW_STATUS_SUCCESS;
if ((op->flag & OP_IS_INVOKE) == 0) {
/* This is called directly from the exec operator, this operation is now blocking */
job->is_nonblocking_job = false;
wmJobWorkerStatus worker_status = {};
worker_status.reports = op->reports;
quadriflow_start_job(job, &worker_status);
status = job->status;
quadriflow_end_job(job);
quadriflow_free_job(job);
}
@@ -1010,7 +1020,12 @@ static int quadriflow_remesh_exec(bContext *C, wmOperator *op)
WM_jobs_start(CTX_wm_manager(C), wm_job);
}
return OPERATOR_FINISHED;
if (status == QUADRIFLOW_STATUS_SUCCESS) {
return OPERATOR_FINISHED;
}
/* Only ever runs with immediate execution. */
return OPERATOR_CANCELLED;
}
static bool quadriflow_check(bContext *C, wmOperator *op)