Page MenuHome

Quadriflow: Symmetry support
ClosedPublic

Authored by Pablo Dobarro (pablodp606) on Thu, Sep 19, 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

Event Timeline

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

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
435

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.Mon, Sep 23, 3:31 PM
Jeroen Bakker (jbakker) requested changes to this revision.Tue, Sep 24, 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
40–41

Please clean up unneeded includes.

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

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

248

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

254

we use mat or m4 for matrix.

266

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

329

Memory leak

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

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.Wed, Sep 25, 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
193

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.Wed, Sep 25, 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.Wed, Sep 25, 4:38 PM
This revision was automatically updated to reflect the committed changes.