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:
authorJulian Eisel <julian@blender.org>2020-03-26 23:03:42 +0300
committerJulian Eisel <julian@blender.org>2020-03-26 23:18:45 +0300
commitc94b6209861ca7cc3985b53474feed7d94c0221a (patch)
tree752054f0dca1338cda5cf8ad4f6d18573fcca3b9 /source/blender/editors/object/object_remesh.c
parent357ed79cb93f9d655501a828c6cddd68282de62d (diff)
parentafb1a64ccb81b7ed792f64151986f40f53af8da5 (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.c150
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,