Page MenuHome
Paste P264

X Mirror Gradient
ActivePublic

Authored by Campbell Barton (campbellbarton) on Sep 25 2015, 4:58 PM.
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 8daad9d..0acbb70 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -2994,22 +2994,69 @@ typedef struct DMGradient_userData {
const float *sco_start; /* [2] */
const float *sco_end; /* [2] */
float sco_line_div; /* store (1.0f / len_v2v2(sco_start, sco_end)) */
- int def_nr;
+ int def_nr, def_nr_mirr;
short is_init;
DMGradient_vertStore *vert_cache;
+ /* only for mirror */
+ int *vert_mirr;
/* only for init */
BLI_bitmap *vert_visit;
/* options */
short use_select;
+ short use_mirror;
short type;
float weightpaint;
} DMGradient_userData;
-static void gradientVert_update(DMGradient_userData *grad_data, int index)
+static void gradientVert_init_weight(DMGradient_userData *grad_data, int def_nr, int index)
{
Mesh *me = grad_data->me;
DMGradient_vertStore *vs = &grad_data->vert_cache[index];
+
+ MDeformVert *dv = &me->dvert[index];
+ MDeformWeight *dw;
+ dw = defvert_find_index(dv, def_nr);
+ if (dw) {
+ vs->weight_orig = dw->weight;
+ vs->flag = VGRAD_STORE_DW_EXIST;
+ }
+ else {
+ vs->weight_orig = 0.0f;
+ vs->flag = VGRAD_STORE_NOP;
+ }
+}
+
+static void gradientVert_assign(Mesh *me, int def_nr, int index, float weight)
+{
+ MDeformVert *dv = &me->dvert[index];
+ MDeformWeight *dw = defvert_verify_index(dv, def_nr);
+
+ BLI_assert(IN_RANGE_INCL(weight, 0.0f, 1.0f));
+ dw->weight = weight;
+}
+
+static void gradientVert_remove(Mesh *me, DMGradient_vertStore *vert_cache, int def_nr, int index)
+{
+ DMGradient_vertStore *vs = &vert_cache[index];
+ MDeformVert *dv = &me->dvert[index];
+ if (vs->flag & VGRAD_STORE_DW_EXIST) {
+ /* normally we NULL check, but in this case we know it exists */
+ MDeformWeight *dw = defvert_find_index(dv, def_nr);
+ dw->weight = vs->weight_orig;
+ }
+ else {
+ /* wasn't originally existing, remove */
+ MDeformWeight *dw = defvert_find_index(dv, def_nr);
+ if (dw) {
+ defvert_remove_group(dv, dw);
+ }
+ }
+}
+
+static void gradientVert_update(DMGradient_userData *grad_data, int index)
+{
+ DMGradient_vertStore *vs = &grad_data->vert_cache[index];
float alpha;
if (grad_data->type == WPAINT_GRADIENT_TYPE_LINEAR) {
@@ -3025,8 +3072,6 @@ static void gradientVert_update(DMGradient_userData *grad_data, int index)
alpha = BKE_brush_curve_strength_clamped(grad_data->brush, alpha, 1.0f);
if (alpha != 0.0f) {
- MDeformVert *dv = &me->dvert[index];
- MDeformWeight *dw = defvert_verify_index(dv, grad_data->def_nr);
// dw->weight = alpha; // testing
int tool = grad_data->brush->vertexpaint_tool;
float testw;
@@ -3034,21 +3079,18 @@ static void gradientVert_update(DMGradient_userData *grad_data, int index)
/* init if we just added */
testw = wpaint_blend_tool(tool, vs->weight_orig, grad_data->weightpaint, alpha * grad_data->brush->alpha);
CLAMP(testw, 0.0f, 1.0f);
- dw->weight = testw;
+
+ gradientVert_assign(grad_data->me, grad_data->def_nr, index, testw);
+
+ if (grad_data->use_mirror && grad_data->vert_mirr[index] != -1) {
+ gradientVert_assign(grad_data->me, grad_data->def_nr_mirr, grad_data->vert_mirr[index], testw);
+ }
}
else {
- MDeformVert *dv = &me->dvert[index];
- if (vs->flag & VGRAD_STORE_DW_EXIST) {
- /* normally we NULL check, but in this case we know it exists */
- MDeformWeight *dw = defvert_find_index(dv, grad_data->def_nr);
- dw->weight = vs->weight_orig;
- }
- else {
- /* wasn't originally existing, remove */
- MDeformWeight *dw = defvert_find_index(dv, grad_data->def_nr);
- if (dw) {
- defvert_remove_group(dv, dw);
- }
+ gradientVert_remove(grad_data->me, grad_data->vert_cache, grad_data->def_nr, index);
+
+ if (grad_data->use_mirror && grad_data->vert_mirr[index] != -1) {
+ gradientVert_remove(grad_data->me, grad_data->vert_cache, grad_data->def_nr_mirr, grad_data->vert_mirr[index]);
}
}
}
@@ -3086,21 +3128,8 @@ static void gradientVertInit__mapFunc(
V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
{
/* ok */
- MDeformVert *dv = &me->dvert[index];
- MDeformWeight *dw;
- dw = defvert_find_index(dv, grad_data->def_nr);
- if (dw) {
- vs->weight_orig = dw->weight;
- vs->flag = VGRAD_STORE_DW_EXIST;
- }
- else {
- vs->weight_orig = 0.0f;
- vs->flag = VGRAD_STORE_NOP;
- }
-
+ gradientVert_init_weight(grad_data, index, grad_data->def_nr);
BLI_BITMAP_ENABLE(grad_data->vert_visit, index);
-
- gradientVert_update(grad_data, index);
}
else {
/* no go */
@@ -3150,6 +3179,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
{
wmGesture *gesture = op->customdata;
DMGradient_vertStore *vert_cache;
+ int *vert_mirr;
struct ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
@@ -3167,11 +3197,18 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
if (is_interactive) {
if (gesture->userdata == NULL) {
+ size_t alloc;
VPaint *wp = scene->toolsettings->wpaint;
- gesture->userdata = MEM_mallocN(sizeof(DMGradient_vertStore) * me->totvert, __func__);
data.is_init = true;
+ alloc = sizeof(DMGradient_vertStore) * me->totvert + 1;
+ if (me->editflag & ME_EDIT_MIRROR_X) {
+ alloc += sizeof(int) * me->totvert;
+ }
+ vert_cache = MEM_mallocN(alloc, __func__);
+ gesture->userdata = vert_cache;
+
copy_wpaint_prev(wp, me->dvert, me->totvert);
/* on init only, convert face -> vert sel */
@@ -3188,9 +3225,11 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
}
data.is_init = true;
- vert_cache = MEM_mallocN(sizeof(DMGradient_vertStore) * me->totvert, __func__);
+ vert_cache = MEM_mallocN(sizeof(DMGradient_vertStore) * me->totvert + 1, __func__);
}
+ vert_mirr = (me->editflag & ME_EDIT_MIRROR_X) ? (void *)&vert_cache[me->totvert] : NULL;
+
data.ar = ar;
data.scene = scene;
data.me = ob->data;
@@ -3198,7 +3237,18 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
data.sco_end = sco_end;
data.sco_line_div = 1.0f / len_v2v2(sco_start, sco_end);
data.def_nr = ob->actdef - 1;
+ if (me->editflag & ME_EDIT_MIRROR_X) {
+ data.def_nr_mirr = wpaint_mirror_vgroup_ensure(ob, data.def_nr);
+ if (data.def_nr_mirr == -1) {
+ data.def_nr_mirr = data.def_nr;
+ }
+ }
+ else {
+ data.def_nr_mirr = -1;
+ }
data.use_select = (me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL));
+ data.use_mirror = (me->editflag & ME_EDIT_MIRROR_X) != 0;
+ data.vert_mirr = vert_mirr;
data.vert_cache = vert_cache;
data.vert_visit = NULL;
data.type = RNA_enum_get(op->ptr, "type");
@@ -3216,17 +3266,52 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
ED_view3d_init_mats_rv3d(ob, ar->regiondata);
+
+
if (data.is_init) {
+
+ if (data.use_mirror) {
+ int index;
+ for (index = 0; index < me->totvert; index++) {
+ DMGradient_vertStore *vs = &data.vert_cache[index];
+ vs->sco[0] = FLT_MAX;
+ vert_mirr[index] = -1;
+ }
+ }
+
data.vert_visit = BLI_BITMAP_NEW(me->totvert, __func__);
dm->foreachMappedVert(dm, gradientVertInit__mapFunc, &data, DM_FOREACH_NOP);
MEM_freeN(data.vert_visit);
data.vert_visit = NULL;
+
+ /* init mirror */
+ if (data.use_mirror) {
+ int index;
+
+ for (index = 0; index < me->totvert; index++) {
+ DMGradient_vertStore *vs = &data.vert_cache[index];
+ if (vs->sco[0] != FLT_MAX) {
+ int index_mirr = mesh_get_x_mirror_vert(ob, index, false);
+ if (index_mirr == index) {
+ index_mirr = -1;
+ }
+ vert_mirr[index] = index_mirr;
+
+ if (index_mirr != -1) {
+ DMGradient_vertStore *vs_mirr = &data.vert_cache[index_mirr];
+ if (vs_mirr->sco[0] == FLT_MAX) {
+ gradientVert_init_weight(&data, index_mirr, data.def_nr_mirr);
+ }
+ }
+ }
+ }
+ }
}
- else {
- dm->foreachMappedVert(dm, gradientVertUpdate__mapFunc, &data, DM_FOREACH_NOP);
- }
+
+ dm->foreachMappedVert(dm, gradientVertUpdate__mapFunc, &data, DM_FOREACH_NOP);
+
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);

Event Timeline

Campbell Barton (campbellbarton) changed the title of this paste from untitled to X Mirror Gradient.
Campbell Barton (campbellbarton) updated the paste's language from autodetect to diff.