diff options
author | Julian Eisel <julian@blender.org> | 2020-03-26 23:03:42 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2020-03-26 23:18:45 +0300 |
commit | c94b6209861ca7cc3985b53474feed7d94c0221a (patch) | |
tree | 752054f0dca1338cda5cf8ad4f6d18573fcca3b9 /source/blender/editors/object/object_remesh.c | |
parent | 357ed79cb93f9d655501a828c6cddd68282de62d (diff) | |
parent | afb1a64ccb81b7ed792f64151986f40f53af8da5 (diff) |
Merge branch 'master' into wm-drag-drop-rewrite
Diffstat (limited to 'source/blender/editors/object/object_remesh.c')
-rw-r--r-- | source/blender/editors/object/object_remesh.c | 150 |
1 files changed, 91 insertions, 59 deletions
diff --git a/source/blender/editors/object/object_remesh.c b/source/blender/editors/object/object_remesh.c index 73fd45693a2..a9f2319d926 100644 --- a/source/blender/editors/object/object_remesh.c +++ b/source/blender/editors/object/object_remesh.c @@ -21,11 +21,11 @@ * \ingroup edobj */ +#include <ctype.h> +#include <float.h> +#include <math.h> #include <stdlib.h> #include <string.h> -#include <math.h> -#include <float.h> -#include <ctype.h> #include "MEM_guardedalloc.h" @@ -33,26 +33,26 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "DNA_scene_types.h" -#include "DNA_object_types.h" -#include "DNA_meshdata_types.h" #include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "BKE_context.h" +#include "BKE_customdata.h" #include "BKE_global.h" -#include "BKE_library.h" +#include "BKE_lib_id.h" #include "BKE_main.h" #include "BKE_mesh.h" -#include "BKE_mesh_runtime.h" #include "BKE_mesh_mirror.h" +#include "BKE_mesh_remesh_voxel.h" +#include "BKE_mesh_runtime.h" #include "BKE_modifier.h" #include "BKE_object.h" #include "BKE_paint.h" #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_shrinkwrap.h" -#include "BKE_customdata.h" -#include "BKE_mesh_remesh_voxel.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" @@ -68,12 +68,15 @@ #include "RNA_enum_types.h" #include "WM_api.h" -#include "WM_types.h" #include "WM_message.h" #include "WM_toolsystem.h" +#include "WM_types.h" #include "object_intern.h" // own include +/* TODO(sebpa): unstable, can lead to unrecoverable errors. */ +// #define USE_MESH_CURVATURE + static bool object_remesh_poll(bContext *C) { Object *ob = CTX_data_active_object(C); @@ -83,18 +86,18 @@ static bool object_remesh_poll(bContext *C) } if (BKE_object_is_in_editmode(ob)) { - CTX_wm_operator_poll_msg_set(C, "The remesher cannot run from edit mode."); + CTX_wm_operator_poll_msg_set(C, "The remesher cannot run from edit mode"); return false; } if (ob->mode == OB_MODE_SCULPT && ob->sculpt->bm) { - CTX_wm_operator_poll_msg_set(C, "The remesher cannot run with dyntopo activated."); + CTX_wm_operator_poll_msg_set(C, "The remesher cannot run with dyntopo activated"); return false; } if (modifiers_usesMultires(ob)) { CTX_wm_operator_poll_msg_set( - C, "The remesher cannot run with a Multires modifier in the modifier stack."); + C, "The remesher cannot run with a Multires modifier in the modifier stack"); return false; } @@ -109,7 +112,7 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op) Mesh *new_mesh; if (mesh->remesh_voxel_size <= 0.0f) { - BKE_report(op->reports, RPT_ERROR, "Voxel remesher cannot run with a voxel size of 0.0."); + BKE_report(op->reports, RPT_ERROR, "Voxel remesher cannot run with a voxel size of 0.0"); return OPERATOR_CANCELLED; } @@ -122,7 +125,7 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op) mesh, mesh->remesh_voxel_size, mesh->remesh_voxel_adaptivity, isovalue); if (!new_mesh) { - BKE_report(op->reports, RPT_ERROR, "Voxel remesher failed to create mesh."); + BKE_report(op->reports, RPT_ERROR, "Voxel remesher failed to create mesh"); return OPERATOR_CANCELLED; } @@ -135,16 +138,23 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op) BKE_mesh_calc_normals(new_mesh); } - if (mesh->flag & ME_REMESH_REPROJECT_VOLUME) { + if (mesh->flag & ME_REMESH_REPROJECT_VOLUME || mesh->flag & ME_REMESH_REPROJECT_PAINT_MASK || + mesh->flag & ME_REMESH_REPROJECT_SCULPT_FACE_SETS) { BKE_mesh_runtime_clear_geometry(mesh); + } + + if (mesh->flag & ME_REMESH_REPROJECT_VOLUME) { BKE_shrinkwrap_remesh_target_project(new_mesh, mesh, ob); } if (mesh->flag & ME_REMESH_REPROJECT_PAINT_MASK) { - BKE_mesh_runtime_clear_geometry(mesh); BKE_mesh_remesh_reproject_paint_mask(new_mesh, mesh); } + if (mesh->flag & ME_REMESH_REPROJECT_SCULPT_FACE_SETS) { + BKE_remesh_reproject_sculpt_face_sets(new_mesh, mesh); + } + BKE_mesh_nomain_to_mesh(new_mesh, mesh, ob, &CD_MASK_MESH, true); if (mesh->flag & ME_REMESH_SMOOTH_NORMALS) { @@ -197,7 +207,6 @@ typedef enum eSymmetryAxes { typedef struct QuadriFlowJob { /* from wmJob */ struct Object *owner; - struct Main *bmain; short *stop, *do_update; float *progress; @@ -214,6 +223,7 @@ typedef struct QuadriFlowJob { bool smooth_normals; int success; + bool is_nonblocking_job; } QuadriFlowJob; static bool mesh_is_manifold_consistent(Mesh *mesh) @@ -307,13 +317,13 @@ static void quadriflow_update_job(void *customdata, float progress, int *cancel) *(qj->progress) = progress; } -static Mesh *remesh_symmetry_bisect(Main *bmain, Mesh *mesh, eSymmetryAxes symmetry_axes) +static Mesh *remesh_symmetry_bisect(Mesh *mesh, eSymmetryAxes symmetry_axes) { MirrorModifierData mmd = {{0}}; mmd.tolerance = QUADRIFLOW_MIRROR_BISECT_TOLERANCE; Mesh *mesh_bisect, *mesh_bisect_temp; - mesh_bisect = BKE_mesh_copy(bmain, mesh); + mesh_bisect = BKE_mesh_copy_for_eval(mesh, false); int axis; float plane_co[3], plane_no[3]; @@ -331,12 +341,12 @@ static Mesh *remesh_symmetry_bisect(Main *bmain, Mesh *mesh, eSymmetryAxes symme mesh_bisect = BKE_mesh_mirror_bisect_on_mirror_plane( &mmd, mesh_bisect, axis, plane_co, plane_no); if (mesh_bisect_temp != mesh_bisect) { - BKE_id_free(bmain, mesh_bisect_temp); + BKE_id_free(NULL, mesh_bisect_temp); } } } - BKE_id_free(bmain, mesh); + BKE_id_free(NULL, mesh); return mesh_bisect; } @@ -377,7 +387,9 @@ static void quadriflow_start_job(void *customdata, short *stop, short *do_update qj->progress = progress; qj->success = 1; - G.is_break = false; /* XXX shared with render - replace with job 'stop' switch */ + if (qj->is_nonblocking_job) { + G.is_break = false; /* XXX shared with render - replace with job 'stop' switch */ + } Object *ob = qj->owner; Mesh *mesh = ob->data; @@ -392,28 +404,32 @@ static void quadriflow_start_job(void *customdata, short *stop, short *do_update /* Run Quadriflow bisect operations on a copy of the mesh to keep the code readable without * freeing the original ID */ - bisect_mesh = BKE_mesh_copy(qj->bmain, mesh); + bisect_mesh = BKE_mesh_copy_for_eval(mesh, false); /* Bisect the input mesh using the paint symmetry settings */ - bisect_mesh = remesh_symmetry_bisect(qj->bmain, bisect_mesh, qj->symmetry_axes); - - new_mesh = BKE_mesh_remesh_quadriflow_to_mesh_nomain(bisect_mesh, - qj->target_faces, - qj->seed, - qj->use_preserve_sharp, - qj->use_preserve_boundary || - qj->use_paint_symmetry, - qj->use_mesh_curvature, - quadriflow_update_job, - (void *)qj); - - BKE_id_free(qj->bmain, bisect_mesh); + bisect_mesh = remesh_symmetry_bisect(bisect_mesh, qj->symmetry_axes); + + new_mesh = BKE_mesh_remesh_quadriflow_to_mesh_nomain( + bisect_mesh, + qj->target_faces, + qj->seed, + qj->use_preserve_sharp, + (qj->use_preserve_boundary || qj->use_paint_symmetry), +#ifdef USE_MESH_CURVATURE + qj->use_mesh_curvature, +#else + false, +#endif + quadriflow_update_job, + (void *)qj); + + BKE_id_free(NULL, bisect_mesh); if (new_mesh == NULL) { *do_update = true; *stop = 0; if (qj->success == 1) { - /* This is not a user cancelation event */ + /* This is not a user cancellation event. */ qj->success = 0; } return; @@ -456,23 +472,25 @@ static void quadriflow_end_job(void *customdata) Object *ob = qj->owner; - WM_set_locked_interface(G_MAIN->wm.first, false); + if (qj->is_nonblocking_job) { + WM_set_locked_interface(G_MAIN->wm.first, false); + } switch (qj->success) { case 1: DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); - WM_reportf(RPT_INFO, "QuadriFlow: Completed remeshing!"); + WM_reportf(RPT_INFO, "QuadriFlow: Remeshing completed"); break; case 0: - WM_reportf(RPT_ERROR, "QuadriFlow: remeshing failed!"); + WM_reportf(RPT_ERROR, "QuadriFlow: Remeshing failed"); break; case -1: - WM_report(RPT_WARNING, "QuadriFlow: remeshing canceled!"); + WM_report(RPT_WARNING, "QuadriFlow: Remeshing cancelled"); break; case -2: WM_report(RPT_WARNING, "QuadriFlow: The mesh needs to be manifold and have face normals that point in a " - "consistent direction."); + "consistent direction"); break; } } @@ -482,7 +500,6 @@ static int quadriflow_remesh_exec(bContext *C, wmOperator *op) QuadriFlowJob *job = MEM_mallocN(sizeof(QuadriFlowJob), "QuadriFlowJob"); job->owner = CTX_data_active_object(C); - job->bmain = CTX_data_main(C); job->target_faces = RNA_int_get(op->ptr, "target_faces"); job->seed = RNA_int_get(op->ptr, "seed"); @@ -492,7 +509,9 @@ static int quadriflow_remesh_exec(bContext *C, wmOperator *op) job->use_preserve_sharp = RNA_boolean_get(op->ptr, "use_preserve_sharp"); job->use_preserve_boundary = RNA_boolean_get(op->ptr, "use_preserve_boundary"); +#ifdef USE_MESH_CURVATURE job->use_mesh_curvature = RNA_boolean_get(op->ptr, "use_mesh_curvature"); +#endif job->preserve_paint_mask = RNA_boolean_get(op->ptr, "preserve_paint_mask"); job->smooth_normals = RNA_boolean_get(op->ptr, "smooth_normals"); @@ -513,21 +532,34 @@ static int quadriflow_remesh_exec(bContext *C, wmOperator *op) job->symmetry_axes = 0; } - wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C), - CTX_wm_window(C), - CTX_data_scene(C), - "QuadriFlow Remesh", - WM_JOB_PROGRESS, - WM_JOB_TYPE_QUADRIFLOW_REMESH); + if (op->flag == 0) { + /* This is called directly from the exec operator, this operation is now blocking */ + job->is_nonblocking_job = false; + short stop = 0, do_update = true; + float progress; + quadriflow_start_job(job, &stop, &do_update, &progress); + quadriflow_end_job(job); + quadriflow_free_job(job); + } + else { + /* Non blocking call. For when the operator has been called from the gui */ + job->is_nonblocking_job = true; - WM_jobs_customdata_set(wm_job, job, quadriflow_free_job); - WM_jobs_timer(wm_job, 0.1, NC_GEOM | ND_DATA, NC_GEOM | ND_DATA); - WM_jobs_callbacks(wm_job, quadriflow_start_job, NULL, NULL, quadriflow_end_job); + wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C), + CTX_wm_window(C), + CTX_data_scene(C), + "QuadriFlow Remesh", + WM_JOB_PROGRESS, + WM_JOB_TYPE_QUADRIFLOW_REMESH); - WM_set_locked_interface(CTX_wm_manager(C), true); + WM_jobs_customdata_set(wm_job, job, quadriflow_free_job); + WM_jobs_timer(wm_job, 0.1, NC_GEOM | ND_DATA, NC_GEOM | ND_DATA); + WM_jobs_callbacks(wm_job, quadriflow_start_job, NULL, NULL, quadriflow_end_job); - WM_jobs_start(CTX_wm_manager(C), wm_job); + WM_set_locked_interface(CTX_wm_manager(C), true); + WM_jobs_start(CTX_wm_manager(C), wm_job); + } return OPERATOR_FINISHED; } @@ -640,7 +672,7 @@ void OBJECT_OT_quadriflow_remesh(wmOperatorType *ot) "use_paint_symmetry", true, "Use Paint Symmetry", - "Generates a symmetrycal mesh using the paint symmetry configuration"); + "Generates a symmetrical mesh using the paint symmetry configuration"); RNA_def_boolean(ot->srna, "use_preserve_sharp", @@ -653,13 +685,13 @@ void OBJECT_OT_quadriflow_remesh(wmOperatorType *ot) false, "Preserve Mesh Boundary", "Try to preserve mesh boundary on the mesh"); - +#ifdef USE_MESH_CURVATURE RNA_def_boolean(ot->srna, "use_mesh_curvature", false, "Use Mesh Curvature", "Take the mesh curvature into account when remeshing"); - +#endif RNA_def_boolean(ot->srna, "preserve_paint_mask", false, |