Fix T59668: UV unwrap pinning bugs.
With multi object editing it creates the charts twice, which broke some logic in the unwrapper.
This commit is contained in:
@@ -126,14 +126,7 @@ void ED_uvedit_live_unwrap_re_solve(void);
|
||||
void ED_uvedit_live_unwrap_end(short cancel);
|
||||
|
||||
void ED_uvedit_live_unwrap(struct Scene *scene, struct Object *obedit);
|
||||
void ED_uvedit_pack_islands(
|
||||
struct Scene *scene, struct Object *ob, struct BMesh *bm,
|
||||
bool selected, bool correct_aspect, bool do_rotate);
|
||||
void ED_uvedit_pack_islands_multi(
|
||||
struct Scene *scene, struct Object **objects, const uint objects_len,
|
||||
bool selected, bool correct_aspect, bool do_rotate, bool implicit);
|
||||
void ED_uvedit_unwrap_cube_project(
|
||||
struct BMesh *bm, float cube_size, bool use_select, const float center[3]);
|
||||
void ED_uvedit_add_simple_uvs(struct Main *bmain, struct Scene *scene, struct Object *ob);
|
||||
|
||||
/* single call up unwrap using scene settings, used for edge tag unwrapping */
|
||||
void ED_unwrap_lscm(struct Scene *scene, struct Object *obedit, const short sel, const bool pack);
|
||||
|
||||
@@ -5937,33 +5937,8 @@ static int add_simple_uvs_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
Main *bmain = CTX_data_main(C);
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Mesh *me = ob->data;
|
||||
bool synch_selection = (scene->toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
|
||||
|
||||
BMesh *bm = BM_mesh_create(
|
||||
&bm_mesh_allocsize_default,
|
||||
&((struct BMeshCreateParams){.use_toolflags = false,}));
|
||||
|
||||
/* turn synch 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);
|
||||
ED_uvedit_unwrap_cube_project(bm, 1.0, false, NULL);
|
||||
/* set the margin really quickly before the packing operation*/
|
||||
scene->toolsettings->uvcalc_margin = 0.001f;
|
||||
ED_uvedit_pack_islands(scene, ob, bm, false, false, true);
|
||||
BM_mesh_bm_to_me(bmain, bm, me, (&(struct BMeshToMeshParams){0}));
|
||||
BM_mesh_free(bm);
|
||||
|
||||
if (synch_selection)
|
||||
scene->toolsettings->uv_flag |= UV_SYNC_SELECTION;
|
||||
ED_uvedit_add_simple_uvs(bmain, scene, ob);
|
||||
|
||||
BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user