diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-12-21 13:43:28 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-12-21 18:34:08 +0300 |
commit | e56aa4ff0c6b2a1746d5c39e297c9f6f56c4b492 (patch) | |
tree | 2dfe9e2dd8de893bf3988abe213db1041822e1fe /source/blender/editors/uvedit | |
parent | bf168a05cd388c02359e52e4ae674c89f13c96a6 (diff) |
Fix T59668: UV unwrap pinning bugs.
With multi object editing it creates the charts twice, which broke some
logic in the unwrapper.
Diffstat (limited to 'source/blender/editors/uvedit')
-rw-r--r-- | source/blender/editors/uvedit/uvedit_parametrizer.c | 33 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_parametrizer.h | 4 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_unwrap_ops.c | 61 |
3 files changed, 67 insertions, 31 deletions
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index c2775014519..ded4a4899c7 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -208,7 +208,7 @@ typedef struct PChart { } PChart; enum PChartFlag { - PCHART_NOPACK = 1 + PCHART_HAS_PINS = 1 }; enum PHandleState { @@ -996,6 +996,10 @@ static void p_split_vert(PChart *chart, PEdge *e) PVert *v = e->vert; PBool copy = P_TRUE; + if (e->flag & PEDGE_PIN) { + chart->flag |= PCHART_HAS_PINS; + } + if (e->flag & PEDGE_VERTEX_SPLIT) return; @@ -3062,9 +3066,6 @@ static void p_chart_lscm_begin(PChart *chart, PBool live, PBool abf) chart->u.lscm.pin1 = pin1; chart->u.lscm.pin2 = pin2; } - else { - chart->flag |= PCHART_NOPACK; - } for (v = chart->verts; v; v = v->nextlink) v->u.id = id++; @@ -4350,7 +4351,7 @@ void param_lscm_solve(ParamHandle *handle) if (chart->u.lscm.context) { result = p_chart_lscm_solve(phandle, chart); - if (result && !(chart->flag & PCHART_NOPACK)) + if (result && !(chart->flag & PCHART_HAS_PINS)) p_chart_rotate_minimum_area(chart); if (!result || (chart->u.lscm.pin1)) @@ -4457,7 +4458,7 @@ void param_smooth_area(ParamHandle *handle) } /* don't pack, just rotate (used for better packing) */ -static void param_pack_rotate(ParamHandle *handle) +static void param_pack_rotate(ParamHandle *handle, bool ignore_pinned) { PChart *chart; int i; @@ -4470,7 +4471,7 @@ static void param_pack_rotate(ParamHandle *handle) chart = phandle->charts[i]; - if (chart->flag & PCHART_NOPACK) { + if (ignore_pinned && (chart->flag & PCHART_HAS_PINS)) { continue; } @@ -4490,7 +4491,7 @@ static void param_pack_rotate(ParamHandle *handle) } } -void param_pack(ParamHandle *handle, float margin, bool do_rotate) +void param_pack(ParamHandle *handle, float margin, bool do_rotate, bool ignore_pinned) { /* box packing variables */ BoxPack *boxarray, *box; @@ -4508,7 +4509,7 @@ void param_pack(ParamHandle *handle, float margin, bool do_rotate) /* this could be its own function */ if (do_rotate) { - param_pack_rotate(handle); + param_pack_rotate(handle, ignore_pinned); } if (phandle->aspx != phandle->aspy) @@ -4521,7 +4522,7 @@ void param_pack(ParamHandle *handle, float margin, bool do_rotate) for (i = 0; i < phandle->ncharts; i++) { chart = phandle->charts[i]; - if (chart->flag & PCHART_NOPACK) { + if (ignore_pinned && (chart->flag & PCHART_HAS_PINS)) { unpacked++; continue; } @@ -4537,7 +4538,7 @@ void param_pack(ParamHandle *handle, float margin, bool do_rotate) box->w = chart->u.pack.size[0] + trans[0]; box->h = chart->u.pack.size[1] + trans[1]; - box->index = i; /* warning this index skips PCHART_NOPACK boxes */ + box->index = i; /* warning this index skips PCHART_HAS_PINS boxes */ if (margin > 0.0f) area += (double)sqrtf(box->w * box->h); @@ -4552,7 +4553,7 @@ void param_pack(ParamHandle *handle, float margin, bool do_rotate) for (i = 0; i < phandle->ncharts; i++) { chart = phandle->charts[i]; - if (chart->flag & PCHART_NOPACK) { + if (ignore_pinned && (chart->flag & PCHART_HAS_PINS)) { unpacked++; continue; } @@ -4588,7 +4589,7 @@ void param_pack(ParamHandle *handle, float margin, bool do_rotate) param_scale(handle, phandle->aspx, phandle->aspy); } -void param_average(ParamHandle *handle) +void param_average(ParamHandle *handle, bool ignore_pinned) { PChart *chart; int i; @@ -4604,8 +4605,9 @@ void param_average(ParamHandle *handle) PFace *f; chart = phandle->charts[i]; - if (chart->flag & PCHART_NOPACK) + if (ignore_pinned && (chart->flag & PCHART_HAS_PINS)) { continue; + } chart->u.pack.area = 0.0f; /* 3d area */ chart->u.pack.rescale = 0.0f; /* UV area, abusing rescale for tmp storage, oh well :/ */ @@ -4629,8 +4631,9 @@ void param_average(ParamHandle *handle) for (i = 0; i < phandle->ncharts; i++) { chart = phandle->charts[i]; - if (chart->flag & PCHART_NOPACK) + if (ignore_pinned && (chart->flag & PCHART_HAS_PINS)) { continue; + } if (chart->u.pack.area != 0.0f && chart->u.pack.rescale != 0.0f) { fac = chart->u.pack.area / chart->u.pack.rescale; diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.h b/source/blender/editors/uvedit/uvedit_parametrizer.h index e42944f3da4..1930e0a9e8e 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.h +++ b/source/blender/editors/uvedit/uvedit_parametrizer.h @@ -98,11 +98,11 @@ void param_smooth_area(ParamHandle *handle); /* Packing */ -void param_pack(ParamHandle *handle, float margin, bool do_rotate); +void param_pack(ParamHandle *handle, float margin, bool do_rotate, bool ignore_pinned); /* Average area for all charts */ -void param_average(ParamHandle *handle); +void param_average(ParamHandle *handle, bool ignore_pinned); /* Simple x,y scale */ diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 55026c9e788..6c818a6a75e 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -838,23 +838,23 @@ void UV_OT_minimize_stretch(wmOperatorType *ot) /* ******************** Pack Islands operator **************** */ -void ED_uvedit_pack_islands(Scene *scene, Object *ob, BMesh *bm, bool selected, bool correct_aspect, bool do_rotate) +static void uvedit_pack_islands(Scene *scene, Object *ob, BMesh *bm) { ParamHandle *handle; - handle = construct_param_handle(scene, ob, bm, true, false, selected, correct_aspect); - param_pack(handle, scene->toolsettings->uvcalc_margin, do_rotate); + handle = construct_param_handle(scene, ob, bm, true, false, false, false); + param_pack(handle, scene->toolsettings->uvcalc_margin, true, false); param_flush(handle); param_delete(handle); } -void ED_uvedit_pack_islands_multi( +static void uvedit_pack_islands_multi( Scene *scene, Object **objects, const uint objects_len, - bool selected, bool correct_aspect, bool do_rotate, bool implicit) + bool do_rotate, bool implicit, bool ignore_pinned) { ParamHandle *handle; handle = construct_param_handle_multi( - scene, objects, objects_len, implicit, false, selected, correct_aspect); - param_pack(handle, scene->toolsettings->uvcalc_margin, do_rotate); + scene, objects, objects_len, implicit, false, true, true); + param_pack(handle, scene->toolsettings->uvcalc_margin, do_rotate, ignore_pinned); param_flush(handle); param_delete(handle); } @@ -878,7 +878,7 @@ static int pack_islands_exec(bContext *C, wmOperator *op) else RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin); - ED_uvedit_pack_islands_multi(scene, objects, objects_len, true, true, do_rotate, true); + uvedit_pack_islands_multi(scene, objects, objects_len, do_rotate, true, false); for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; @@ -929,7 +929,7 @@ static int average_islands_scale_exec(bContext *C, wmOperator *UNUSED(op)) } handle = construct_param_handle_multi(scene, objects, objects_len, implicit, false, true, true); - param_average(handle); + param_average(handle, false); param_flush(handle); param_delete(handle); @@ -1406,10 +1406,10 @@ void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel, const bool pa param_lscm_solve(handle); param_lscm_end(handle); - param_average(handle); + param_average(handle, true); if (pack) { - param_pack(handle, scene->toolsettings->uvcalc_margin, false); + param_pack(handle, scene->toolsettings->uvcalc_margin, false, true); } param_flush(handle); @@ -1516,7 +1516,7 @@ static int unwrap_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); } - ED_uvedit_pack_islands_multi(scene, objects, objects_len, true, true, true, implicit); + uvedit_pack_islands_multi(scene, objects, objects_len, true, implicit, true); MEM_freeN(objects); @@ -1981,7 +1981,7 @@ void UV_OT_cylinder_project(wmOperatorType *ot) /******************* Cube Project operator ****************/ -void ED_uvedit_unwrap_cube_project(BMesh *bm, float cube_size, bool use_select, const float center[3]) +static void uvedit_unwrap_cube_project(BMesh *bm, float cube_size, bool use_select, const float center[3]) { BMFace *efa; BMLoop *l; @@ -2066,7 +2066,7 @@ static int cube_project_exec(bContext *C, wmOperator *op) } } - ED_uvedit_unwrap_cube_project(em->bm, cube_size, true, center); + uvedit_unwrap_cube_project(em->bm, cube_size, true, center); uv_map_clip_correct(scene, obedit, op); @@ -2095,3 +2095,36 @@ void UV_OT_cube_project(wmOperatorType *ot) RNA_def_float(ot->srna, "cube_size", 1.0f, 0.0f, FLT_MAX, "Cube Size", "Size of the cube to project on", 0.001f, 100.0f); uv_map_clip_correct_properties(ot); } + +/************************* Simple UVs for texture painting *****************/ + +void ED_uvedit_add_simple_uvs(Main *bmain, Scene *scene, Object *ob) +{ + Mesh *me = ob->data; + bool sync_selection = (scene->toolsettings->uv_flag & UV_SYNC_SELECTION) != 0; + + BMesh *bm = BM_mesh_create( + &bm_mesh_allocsize_default, + &((struct BMeshCreateParams){.use_toolflags = false,})); + + /* turn sync selection off, since we are not in edit mode we need to ensure only the uv flags are tested */ + scene->toolsettings->uv_flag &= ~UV_SYNC_SELECTION; + + ED_mesh_uv_texture_ensure(me, NULL); + + BM_mesh_bm_from_me( + bm, me, (&(struct BMeshFromMeshParams){ + .calc_face_normal = true, + })); + /* select all uv loops first - pack parameters needs this to make sure charts are registered */ + ED_uvedit_select_all(bm); + uvedit_unwrap_cube_project(bm, 1.0, false, NULL); + /* set the margin really quickly before the packing operation*/ + scene->toolsettings->uvcalc_margin = 0.001f; + uvedit_pack_islands(scene, ob, bm); + BM_mesh_bm_to_me(bmain, bm, me, (&(struct BMeshToMeshParams){0})); + BM_mesh_free(bm); + + if (sync_selection) + scene->toolsettings->uv_flag |= UV_SYNC_SELECTION; +} |