Page MenuHome

Quadriflow: Symmetry support
ClosedPublic

Authored by Pablo Dobarro (pablodp606) on Sep 19 2019, 5:38 PM.
Tags
None
Tokens
"100" token, awarded by Frozen_Death_Knight."Like" token, awarded by Schamph."Mountain of Wealth" token, awarded by Way."Love" token, awarded by TheAngerSpecialist."Like" token, awarded by franMarz."Love" token, awarded by 3DUnreal."Love" token, awarded by xorrito."Like" token, awarded by cwolf3d."Like" token, awarded by TheRedWaxPolice."Love" token, awarded by Zino."Love" token, awarded by Jaydead."Love" token, awarded by johnsyed."Love" token, awarded by brilliant_ape."Like" token, awarded by capnm."Love" token, awarded by Loner."Love" token, awarded by lopoIsaac."Love" token, awarded by MetinSeven."Love" token, awarded by jmztn."Love" token, awarded by xrg."Like" token, awarded by amonpaike.

Details

Summary

This patch adds paint symmetry support to Quadriflow. It bisects and mirrors the input and the output from the remesher to build the final mesh using the preserve boundary option.
This can be considered a new feature, but I think this is rather important to have for 2.81 because most of the new sculpt tools rely on topology symmetry to keep the symmetry of the sculpt. It is also an important performance improvement in Quadriflow because it only needs to process half of the mesh with half the resolution.

Diff Detail

Repository
rB Blender
Branch
quadriflow-symmetry (branched from master)
Build Status
Buildable 5036
Build 5036: arc lint + arc unit

Event Timeline

Jacques Lucke (JacquesLucke) added inline comments.
source/blender/editors/object/object_remesh.c
250

Looks like a perfect candidate for using a new function instead of a comment. Same below.

Pablo Dobarro (pablodp606) marked an inline comment as done.
  • Move bisect and mirror to functions
source/blender/editors/object/object_remesh.c
399

Perhaps we could just default to "use object Origin and X-mirror" if we are not in sculpt mode?

I'm guessing that the symmetry option could be useful to have available outside of sculpt mode too.

Way awarded a token.Sep 23 2019, 3:31 PM
Jeroen Bakker (jbakker) requested changes to this revision.Sep 24 2019, 9:40 AM
Jeroen Bakker (jbakker) added inline comments.
source/blender/blenkernel/BKE_mirror.h
17

It is not always there, but Copyright should contain year of first publication.

source/blender/blenkernel/intern/mirror.c
41

Please clean up unneeded includes.

source/blender/editors/object/object_remesh.c
182

mirror_planes is a better name and use an enum for this.

237

Add this as a define. It is used in multiple places and needs to be in sync.

243

we use mat or m4 for matrix.

250

Memory leak

255

this does not need any matrix at all.
plane_co is always zero
normal is the negate of a vector that is constructed locally

This revision now requires changes to proceed.Sep 24 2019, 9:40 AM
Pablo Dobarro (pablodp606) marked 6 inline comments as done.
  • Fix memory leaks, review update
source/blender/editors/object/object_remesh.c
182

The variable symm and this way of iterating over the symmetry axes is used a lot in the sculpt code. How can I use a enum here?

Jeroen Bakker (jbakker) requested changes to this revision.Sep 25 2019, 9:36 AM
Jeroen Bakker (jbakker) added inline comments.
source/blender/blenkernel/BKE_mirror.h
29

Gives warning
warning: ‘struct MirrorModifierData’ declared inside parameter list will not be visible outside of this definition or declaration

Also where it is used.
passing argument 1 of ‘BKE_mirror_bisect_on_mirror_plane’ from incompatible pointer type [-Wincompatible-pointer-types]

source/blender/editors/object/object_remesh.c
182

Could be but char symm is bad code style and bad naming.

For example it could look like

1diff --git a/source/blender/editors/object/object_remesh.c b/source/blender/editors/object/object_remesh.c
2index 8eb85a87acb..5fc436165cd 100644
3--- a/source/blender/editors/object/object_remesh.c
4+++ b/source/blender/editors/object/object_remesh.c
5@@ -173,6 +173,11 @@ enum {
6 /****************** quadriflow remesh operator *********************/
7
8 #define QUADRIFLOW_MIRROR_BISECT_TOLERANCE 0.005f
9+typedef enum eSymmetryAxes {
10+ SYMMETRY_AXES_X = (1 << 0),
11+ SYMMETRY_AXES_Y = (1 << 1),
12+ SYMMETRY_AXES_Z = (1 << 2),
13+} eSymmetryAxes;
14
15 typedef struct QuadriFlowJob {
16 /* from wmJob */
17@@ -184,7 +189,7 @@ typedef struct QuadriFlowJob {
18 int target_faces;
19 int seed;
20 bool use_paint_symmetry;
21- char symm;
22+ eSymmetryAxes symmetry_axes;
23:...skipping...
24diff --git a/source/blender/editors/object/object_remesh.c b/source/blender/editors/object/object_remesh.c
25index 8eb85a87acb..5fc436165cd 100644
26--- a/source/blender/editors/object/object_remesh.c
27+++ b/source/blender/editors/object/object_remesh.c
28@@ -173,6 +173,11 @@ enum {
29 /****************** quadriflow remesh operator *********************/
30
31 #define QUADRIFLOW_MIRROR_BISECT_TOLERANCE 0.005f
32+typedef enum eSymmetryAxes {
33+ SYMMETRY_AXES_X = (1 << 0),
34+ SYMMETRY_AXES_Y = (1 << 1),
35+ SYMMETRY_AXES_Z = (1 << 2),
36+} eSymmetryAxes;
37
38 typedef struct QuadriFlowJob {
39 /* from wmJob */
40@@ -184,7 +189,7 @@ typedef struct QuadriFlowJob {
41 int target_faces;
42 int seed;
43 bool use_paint_symmetry;
44- char symm;
45+ eSymmetryAxes symmetry_axes;
46
47 bool use_preserve_sharp;
48 bool use_preserve_boundary;
49@@ -236,7 +241,7 @@ static void quadriflow_update_job(void *customdata, float progress, int *cancel)
50 *(qj->progress) = progress;
51 }
52
53-static Mesh *remesh_symmetry_bisect(Main *bmain, Mesh *mesh, char symm)
54+static Mesh *remesh_symmetry_bisect(Main *bmain, Mesh *mesh, eSymmetryAxes symmetry_axes)
55 {
56 MirrorModifierData mmd = {0};
57 mmd.tolerance = QUADRIFLOW_MIRROR_BISECT_TOLERANCE;
58@@ -249,8 +254,8 @@ static Mesh *remesh_symmetry_bisect(Main *bmain, Mesh *mesh, char symm)
59 zero_v3(plane_co);
60
61 for (char i = 0; i < 3; i++) {
62- char symm_it = 1 << i;
63- if (symm & symm_it) {
64+ eSymmetryAxes symm_it = (eSymmetryAxes)(1 << i);
65+ if (symmetry_axes & symm_it) {
66 axis = i;
67 mmd.flag = 0;
68 mmd.flag &= MOD_MIR_BISECT_AXIS_X << i;
69@@ -317,7 +322,7 @@ static void quadriflow_start_job(void *customdata, short *stop, short *do_update
70 bisect_mesh = BKE_mesh_copy(qj->bmain, mesh);
71
72 /* Bisect the input mesh using the paint symmetry settings */
73- bisect_mesh = remesh_symmetry_bisect(qj->bmain, bisect_mesh, qj->symm);
74+ bisect_mesh = remesh_symmetry_bisect(qj->bmain, bisect_mesh, qj->symmetry_axes);
75
76 new_mesh = BKE_mesh_remesh_quadriflow_to_mesh_nomain(bisect_mesh,
77 qj->target_faces,
78@@ -343,7 +348,7 @@ static void quadriflow_start_job(void *customdata, short *stop, short *do_update
79
80 /* Mirror the Quadriflow result to build the final mesh */
81 if (new_mesh) {
82- new_mesh = remesh_symmetry_mirror(qj->owner, new_mesh, qj->symm);
83+ new_mesh = remesh_symmetry_mirror(qj->owner, new_mesh, qj->symmetry_axes);
84 }
85
86 if (ob->mode == OB_MODE_SCULPT) {
87@@ -426,17 +431,17 @@ static int quadriflow_remesh_exec(bContext *C, wmOperator *op)
88 /* Update the target face count if symmetry is enabled */
89 Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
90 if (sd && job->use_paint_symmetry) {
91- job->symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
92+ job->symmetry_axes = (eSymmetryAxes)(sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL);
93 for (char i = 0; i < 3; i++) {
94- char symm_it = 1 << i;
95- if (job->symm & symm_it) {
96+ eSymmetryAxes symm_it = (eSymmetryAxes)(1 << i);
97+ if (job->symmetry_axes & symm_it) {
98 job->target_faces = job->target_faces / 2;
99 }
100 }
101 }
102 else {
103 job->use_paint_symmetry = false;
104- job->symm = 0;
105+ job->symmetry_axes = 0;
106 }
107
108 wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),

Same code, only more clear what the variables/fields do.

This revision now requires changes to proceed.Sep 25 2019, 9:36 AM
Pablo Dobarro (pablodp606) marked 2 inline comments as done.
  • Use enum, fix warnings
This revision is now accepted and ready to land.Sep 25 2019, 4:38 PM
This revision was automatically updated to reflect the committed changes.