Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/uvedit/uvedit_unwrap_ops.c')
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c256
1 files changed, 159 insertions, 97 deletions
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index b50b8d466f1..b80862d4db5 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -87,6 +87,24 @@
#include "uvedit_intern.h"
#include "uvedit_parametrizer.h"
+static void modifier_unwrap_state(Object *obedit, Scene *scene, short *use_subsurf)
+{
+ ModifierData *md;
+ short subsurf = scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF;
+
+ md = obedit->modifiers.first;
+
+ /* subsurf will take the modifier settings only if modifier is first or right after mirror */
+ if (subsurf) {
+ if (md && md->type == eModifierType_Subsurf)
+ subsurf = TRUE;
+ else
+ subsurf = FALSE;
+ }
+
+ *use_subsurf = subsurf;
+}
+
static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit)
{
Main *bmain = CTX_data_main(C);
@@ -103,7 +121,7 @@ static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit)
return 1;
if (em && em->bm->totface && !CustomData_has_layer(&em->bm->pdata, CD_MTEXPOLY))
- ED_mesh_uv_texture_add(C, obedit->data, NULL, TRUE);
+ ED_mesh_uv_texture_add(obedit->data, NULL, true);
if (!ED_uvedit_test(obedit))
return 0;
@@ -143,13 +161,16 @@ static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit)
/****************** Parametrizer Conversion ***************/
-static int uvedit_have_selection(Scene *scene, BMEditMesh *em, short implicit)
+static bool uvedit_have_selection(Scene *scene, BMEditMesh *em, bool implicit)
{
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
+ if (!CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV)) {
+ return (em->bm->totfacesel != 0);
+ }
+
/* verify if we have any selected uv's before unwrapping,
* so we can cancel the operator early */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -157,14 +178,10 @@ static int uvedit_have_selection(Scene *scene, BMEditMesh *em, short implicit)
if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN))
continue;
}
- else if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN) || !BM_elem_flag_test(efa, BM_ELEM_SELECT))
+ else if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
- if (!luv)
- return 1;
-
if (uvedit_uv_select_test(em, scene, l))
break;
}
@@ -172,13 +189,13 @@ static int uvedit_have_selection(Scene *scene, BMEditMesh *em, short implicit)
if (implicit && !l)
continue;
- return 1;
+ return true;
}
- return 0;
+ return false;
}
-static void ED_uvedit_get_aspect(Scene *scene, Object *ob, BMEditMesh *em, float *aspx, float *aspy)
+void uvedit_get_aspect(Scene *scene, Object *ob, BMEditMesh *em, float *aspx, float *aspy)
{
int sloppy = TRUE;
int selected = FALSE;
@@ -208,6 +225,7 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh
short implicit, short fill, short sel,
short correct_aspect)
{
+ BMesh *bm = em->bm;
ScanFillContext sf_ctx;
ParamHandle *handle;
BMFace *efa;
@@ -215,12 +233,15 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh
BMEdge *eed;
BMIter iter, liter;
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+
handle = param_construct_begin();
+
if (correct_aspect) {
float aspx, aspy;
- ED_uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
+ uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
if (aspx != aspy)
param_aspect_ratio(handle, aspx, aspy);
@@ -266,7 +287,7 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh
* about which split is best for unwrapping than scanfill */
i = 0;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
vkeys[i] = (ParamKey)BM_elem_index_get(l->v);
co[i] = l->v->co;
uv[i] = luv->uv;
@@ -314,7 +335,7 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh
ls[2] = sf_tri->v3->tmp.p;
for (i = 0; i < 3; i++) {
- MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, ls[i]->head.data, CD_MLOOPUV);
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(ls[i], cd_loop_uv_offset);
vkeys[i] = (ParamKey)BM_elem_index_get(ls[i]->v);
co[i] = ls[i]->v->co;
uv[i] = luv->uv;
@@ -346,7 +367,8 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh
}
-static void texface_from_original_index(BMFace *efa, int index, float **uv, ParamBool *pin, ParamBool *select, Scene *scene, BMEditMesh *em)
+static void texface_from_original_index(BMFace *efa, int index, float **uv, ParamBool *pin, ParamBool *select,
+ Scene *scene, BMEditMesh *em, const int cd_loop_uv_offset)
{
BMLoop *l;
BMIter liter;
@@ -361,10 +383,11 @@ static void texface_from_original_index(BMFace *efa, int index, float **uv, Para
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (BM_elem_index_get(l->v) == index) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
*uv = luv->uv;
*pin = (luv->flag & MLOOPUV_PINNED) ? 1 : 0;
*select = (uvedit_uv_select_test(em, scene, l) != 0);
+ break;
}
}
}
@@ -379,6 +402,9 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
MEdge *edge;
int i;
+ /* pointers to modifier data for unwrap control */
+ ModifierData *md;
+ SubsurfModifierData *smd_real;
/* modifier initialization data, will control what type of subdivision will happen*/
SubsurfModifierData smd = {{0}};
/* Used to hold subsurfed Mesh */
@@ -397,20 +423,25 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
/* similar to the above, we need a way to map edges to their original ones */
BMEdge **edgeMap;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
handle = param_construct_begin();
if (correct_aspect) {
float aspx, aspy;
- ED_uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
+ uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
if (aspx != aspy)
param_aspect_ratio(handle, aspx, aspy);
}
/* number of subdivisions to perform */
- smd.levels = scene->toolsettings->uv_subsurf_level;
- smd.subdivType = ME_CC_SUBSURF;
+ md = ob->modifiers.first;
+ smd_real = (SubsurfModifierData *)md;
+
+ smd.levels = smd_real->levels;
+ smd.subdivType = smd_real->subdivType;
initialDerived = CDDM_from_editbmesh(em, FALSE, FALSE);
derivedMesh = subsurf_make_derived_from_derived(initialDerived, &smd,
@@ -434,7 +465,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
faceMap = MEM_mallocN(numOfFaces * sizeof(BMFace *), "unwrap_edit_face_map");
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
- EDBM_index_arrays_init(em, 0, 1, 1);
+ EDBM_index_arrays_ensure(em, BM_EDGE | BM_FACE);
/* map subsurfed faces to original editFaces */
for (i = 0; i < numOfFaces; i++)
@@ -445,12 +476,10 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
/* map subsurfed edges to original editEdges */
for (i = 0; i < numOfEdges; i++) {
/* not all edges correspond to an old edge */
- edgeMap[i] = (origEdgeIndices[i] != -1) ?
+ edgeMap[i] = (origEdgeIndices[i] != ORIGINDEX_NONE) ?
EDBM_edge_at_index(em, origEdgeIndices[i]) : NULL;
}
- EDBM_index_arrays_free(em);
-
/* Prepare and feed faces to the solver */
for (i = 0; i < numOfFaces; i++) {
ParamKey key, vkeys[4];
@@ -484,10 +513,10 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
/* This is where all the magic is done. If the vertex exists in the, we pass the original uv pointer to the solver, thus
* flushing the solution to the edit mesh. */
- texface_from_original_index(origFace, origVertIndices[face->v1], &uv[0], &pin[0], &select[0], scene, em);
- texface_from_original_index(origFace, origVertIndices[face->v2], &uv[1], &pin[1], &select[1], scene, em);
- texface_from_original_index(origFace, origVertIndices[face->v3], &uv[2], &pin[2], &select[2], scene, em);
- texface_from_original_index(origFace, origVertIndices[face->v4], &uv[3], &pin[3], &select[3], scene, em);
+ texface_from_original_index(origFace, origVertIndices[face->v1], &uv[0], &pin[0], &select[0], scene, em, cd_loop_uv_offset);
+ texface_from_original_index(origFace, origVertIndices[face->v2], &uv[1], &pin[1], &select[1], scene, em, cd_loop_uv_offset);
+ texface_from_original_index(origFace, origVertIndices[face->v3], &uv[2], &pin[2], &select[2], scene, em, cd_loop_uv_offset);
+ texface_from_original_index(origFace, origVertIndices[face->v4], &uv[3], &pin[3], &select[3], scene, em, cd_loop_uv_offset);
param_face_add(handle, key, 4, vkeys, co, uv, pin, select);
}
@@ -525,17 +554,17 @@ typedef struct MinStretch {
wmTimer *timer;
} MinStretch;
-static int minimize_stretch_init(bContext *C, wmOperator *op)
+static bool minimize_stretch_init(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BMEdit_FromObject(obedit);
MinStretch *ms;
int fill_holes = RNA_boolean_get(op->ptr, "fill_holes");
- short implicit = 1;
+ bool implicit = true;
if (!uvedit_have_selection(scene, em, implicit)) {
- return 0;
+ return false;
}
ms = MEM_callocN(sizeof(MinStretch), "MinStretch");
@@ -554,7 +583,7 @@ static int minimize_stretch_init(bContext *C, wmOperator *op)
op->customdata = ms;
- return 1;
+ return true;
}
static void minimize_stretch_iteration(bContext *C, wmOperator *op, int interactive)
@@ -574,7 +603,7 @@ static void minimize_stretch_iteration(bContext *C, wmOperator *op, int interact
param_flush(ms->handle);
if (sa) {
- BLI_snprintf(str, sizeof(str), "Minimize Stretch. Blend %.2f", ms->blend);
+ BLI_snprintf(str, sizeof(str), "Minimize Stretch. Blend %.2f (Press + and -, or scroll wheel to set)", ms->blend);
ED_area_headerprint(sa, str);
}
@@ -625,7 +654,7 @@ static int minimize_stretch_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int minimize_stretch_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int minimize_stretch_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
MinStretch *ms;
@@ -641,7 +670,7 @@ static int minimize_stretch_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(
return OPERATOR_RUNNING_MODAL;
}
-static int minimize_stretch_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int minimize_stretch_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
MinStretch *ms = op->customdata;
@@ -657,20 +686,24 @@ static int minimize_stretch_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_FINISHED;
case PADPLUSKEY:
case WHEELUPMOUSE:
- if (ms->blend < 0.95f) {
- ms->blend += 0.1f;
- ms->lasttime = 0.0f;
- RNA_float_set(op->ptr, "blend", ms->blend);
- minimize_stretch_iteration(C, op, 1);
+ if (event->val == KM_PRESS) {
+ if (ms->blend < 0.95f) {
+ ms->blend += 0.1f;
+ ms->lasttime = 0.0f;
+ RNA_float_set(op->ptr, "blend", ms->blend);
+ minimize_stretch_iteration(C, op, 1);
+ }
}
break;
case PADMINUS:
case WHEELDOWNMOUSE:
- if (ms->blend > 0.05f) {
- ms->blend -= 0.1f;
- ms->lasttime = 0.0f;
- RNA_float_set(op->ptr, "blend", ms->blend);
- minimize_stretch_iteration(C, op, 1);
+ if (event->val == KM_PRESS) {
+ if (ms->blend > 0.05f) {
+ ms->blend -= 0.1f;
+ ms->lasttime = 0.0f;
+ RNA_float_set(op->ptr, "blend", ms->blend);
+ minimize_stretch_iteration(C, op, 1);
+ }
}
break;
case TIMER:
@@ -728,7 +761,7 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BMEdit_FromObject(obedit);
ParamHandle *handle;
- short implicit = 1;
+ bool implicit = true;
if (!uvedit_have_selection(scene, em, implicit)) {
return OPERATOR_CANCELLED;
@@ -775,7 +808,7 @@ static int average_islands_scale_exec(bContext *C, wmOperator *UNUSED(op))
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BMEdit_FromObject(obedit);
ParamHandle *handle;
- short implicit = 1;
+ bool implicit = true;
if (!uvedit_have_selection(scene, em, implicit)) {
return OPERATOR_CANCELLED;
@@ -815,16 +848,18 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit)
BMEditMesh *em = BMEdit_FromObject(obedit);
short abf = scene->toolsettings->unwrapper == 0;
short fillholes = scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES;
- short use_subsurf = scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF;
+ short use_subsurf;
+
+ modifier_unwrap_state(obedit, scene, &use_subsurf);
if (!ED_uvedit_test(obedit)) {
return;
}
if (use_subsurf)
- liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, 0, 1);
+ liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, FALSE, TRUE);
else
- liveHandle = construct_param_handle(scene, obedit, em, 0, fillholes, 0, 1);
+ liveHandle = construct_param_handle(scene, obedit, em, FALSE, fillholes, FALSE, TRUE);
param_lscm_begin(liveHandle, PARAM_TRUE, abf);
}
@@ -871,16 +906,18 @@ void ED_uvedit_live_unwrap(Scene *scene, Object *obedit)
static void uv_map_transform_center(Scene *scene, View3D *v3d, float *result,
Object *ob, BMEditMesh *em)
{
- BMFace *efa;
- BMLoop *l;
- BMIter iter, liter;
- float min[3], max[3], *cursx;
int around = (v3d) ? v3d->around : V3D_CENTER;
/* only operates on the edit object - this is all that's needed now */
switch (around) {
case V3D_CENTER: /* bounding box center */
+ {
+ BMFace *efa;
+ BMLoop *l;
+ BMIter iter, liter;
+ float min[3], max[3];
+
INIT_MINMAX(min, max);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -892,17 +929,18 @@ static void uv_map_transform_center(Scene *scene, View3D *v3d, float *result,
}
mid_v3_v3v3(result, min, max);
break;
-
+ }
case V3D_CURSOR: /* cursor center */
- cursx = give_cursor(scene, v3d);
+ {
+ const float *curs = give_cursor(scene, v3d);
/* shift to objects world */
- sub_v3_v3v3(result, cursx, ob->obmat[3]);
+ sub_v3_v3v3(result, curs, ob->obmat[3]);
break;
-
+ }
case V3D_LOCAL: /* object center */
case V3D_CENTROID: /* multiple objects centers, only one object here*/
default:
- result[0] = result[1] = result[2] = 0.0;
+ zero_v3(result);
break;
}
}
@@ -938,18 +976,18 @@ static void uv_map_rotation_matrix(float result[4][4], RegionView3D *rv3d, Objec
/* this is "kanonen gegen spatzen", a few plus minus 1 will do here */
/* i wanted to keep the reason here, so we're rotating*/
sideangle = (float)M_PI * (sideangledeg + 180.0f) / 180.0f;
- rotside[0][0] = (float)cos(sideangle);
- rotside[0][1] = -(float)sin(sideangle);
- rotside[1][0] = (float)sin(sideangle);
- rotside[1][1] = (float)cos(sideangle);
- rotside[2][2] = 1.0f;
+ rotside[0][0] = cosf(sideangle);
+ rotside[0][1] = -sinf(sideangle);
+ rotside[1][0] = sinf(sideangle);
+ rotside[1][1] = cosf(sideangle);
+ rotside[2][2] = 1.0f;
upangle = (float)M_PI * upangledeg / 180.0f;
- rotup[1][1] = (float)cos(upangle) / radius;
- rotup[1][2] = -(float)sin(upangle) / radius;
- rotup[2][1] = (float)sin(upangle) / radius;
- rotup[2][2] = (float)cos(upangle) / radius;
- rotup[0][0] = (float)1.0f / radius;
+ rotup[1][1] = cosf(upangle) / radius;
+ rotup[1][2] = -sinf(upangle) / radius;
+ rotup[2][1] = sinf(upangle) / radius;
+ rotup[2][2] = cosf(upangle) / radius;
+ rotup[0][0] = 1.0f / radius;
/* calculate transforms*/
mul_serie_m4(result, rotup, rotside, viewmatrix, rotobj, NULL, NULL, NULL, NULL);
@@ -1020,7 +1058,9 @@ static void correct_uv_aspect(Scene *scene, Object *ob, BMEditMesh *em)
BMFace *efa;
float scale, aspx, aspy;
- ED_uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
+ uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
if (aspx == aspy)
return;
@@ -1029,11 +1069,11 @@ static void correct_uv_aspect(Scene *scene, Object *ob, BMEditMesh *em)
scale = aspy / aspx;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!BM_elem_flag_test(efa, BM_ELEM_SELECT) || BM_elem_flag_test(efa, BM_ELEM_HIDDEN))
+ if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->uv[0] = ((luv->uv[0] - 0.5f) * scale) + 0.5f;
}
}
@@ -1042,11 +1082,11 @@ static void correct_uv_aspect(Scene *scene, Object *ob, BMEditMesh *em)
scale = aspx / aspy;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!BM_elem_flag_test(efa, BM_ELEM_SELECT) || BM_elem_flag_test(efa, BM_ELEM_HIDDEN))
+ if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->uv[1] = ((luv->uv[1] - 0.5f) * scale) + 0.5f;
}
}
@@ -1076,6 +1116,8 @@ static void uv_map_clip_correct(Scene *scene, Object *ob, BMEditMesh *em, wmOper
int clip_to_bounds = RNA_boolean_get(op->ptr, "clip_to_bounds");
int scale_to_bounds = RNA_boolean_get(op->ptr, "scale_to_bounds");
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
/* correct for image aspect ratio */
if (correct_aspect)
correct_uv_aspect(scene, ob, em);
@@ -1088,7 +1130,7 @@ static void uv_map_clip_correct(Scene *scene, Object *ob, BMEditMesh *em, wmOper
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
minmax_v2v2_v2(min, max, luv->uv);
}
}
@@ -1107,7 +1149,7 @@ static void uv_map_clip_correct(Scene *scene, Object *ob, BMEditMesh *em, wmOper
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->uv[0] = (luv->uv[0] - min[0]) * dx;
luv->uv[1] = (luv->uv[1] - min[1]) * dy;
@@ -1121,7 +1163,7 @@ static void uv_map_clip_correct(Scene *scene, Object *ob, BMEditMesh *em, wmOper
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
CLAMP(luv->uv[0], 0.0f, 1.0f);
CLAMP(luv->uv[1], 0.0f, 1.0f);
}
@@ -1139,12 +1181,14 @@ void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel)
const short fill_holes = scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES;
const short correct_aspect = !(scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT);
- const short use_subsurf = scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF;
+ short use_subsurf;
+
+ modifier_unwrap_state(obedit, scene, &use_subsurf);
if (use_subsurf)
handle = construct_param_handle_subsurfed(scene, obedit, em, fill_holes, sel, correct_aspect);
else
- handle = construct_param_handle(scene, obedit, em, 0, fill_holes, sel, correct_aspect);
+ handle = construct_param_handle(scene, obedit, em, FALSE, fill_holes, sel, correct_aspect);
param_lscm_begin(handle, PARAM_FALSE, scene->toolsettings->unwrapper == 0);
param_lscm_solve(handle);
@@ -1167,9 +1211,9 @@ static int unwrap_exec(bContext *C, wmOperator *op)
int fill_holes = RNA_boolean_get(op->ptr, "fill_holes");
int correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect");
int use_subsurf = RNA_boolean_get(op->ptr, "use_subsurf_data");
- int subsurf_level = RNA_int_get(op->ptr, "uv_subsurf_level");
+ short use_subsurf_final;
float obsize[3];
- short implicit = 0;
+ bool implicit = false;
if (!uvedit_have_selection(scene, em, implicit)) {
return OPERATOR_CANCELLED;
@@ -1197,8 +1241,6 @@ static int unwrap_exec(bContext *C, wmOperator *op)
else
RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin);
- scene->toolsettings->uv_subsurf_level = subsurf_level;
-
if (fill_holes) scene->toolsettings->uvcalc_flag |= UVCALC_FILLHOLES;
else scene->toolsettings->uvcalc_flag &= ~UVCALC_FILLHOLES;
@@ -1208,6 +1250,12 @@ static int unwrap_exec(bContext *C, wmOperator *op)
if (use_subsurf) scene->toolsettings->uvcalc_flag |= UVCALC_USESUBSURF;
else scene->toolsettings->uvcalc_flag &= ~UVCALC_USESUBSURF;
+ /* double up the check here but better keep ED_unwrap_lscm interface simple and not
+ * pass operator for warning append */
+ modifier_unwrap_state(obedit, scene, &use_subsurf_final);
+ if (use_subsurf != use_subsurf_final)
+ BKE_report(op->reports, RPT_INFO, "Subsurf modifier needs to be first to work with unwrap");
+
/* execute unwrap */
ED_unwrap_lscm(scene, obedit, TRUE);
@@ -1242,10 +1290,8 @@ void UV_OT_unwrap(wmOperatorType *ot)
"Virtual fill holes in mesh before unwrapping, to better avoid overlaps and preserve symmetry");
RNA_def_boolean(ot->srna, "correct_aspect", 1, "Correct Aspect",
"Map UVs taking image aspect ratio into account");
- RNA_def_boolean(ot->srna, "use_subsurf_data", 0, "Use Subsurf Data",
+ RNA_def_boolean(ot->srna, "use_subsurf_data", 0, "Use Subsurf Modifier",
"Map UVs taking vertex position after subsurf into account");
- RNA_def_int(ot->srna, "uv_subsurf_level", 1, 1, 6, "Subsurf Target",
- "Number of times to subdivide before calculating UVs", 1, 6);
RNA_def_float_factor(ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f);
}
@@ -1265,11 +1311,15 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
MLoopUV *luv;
float rotmat[4][4];
+ int cd_loop_uv_offset;
+
/* add uvs if they don't exist yet */
if (!ED_uvedit_ensure_uvs(C, scene, obedit)) {
return OPERATOR_CANCELLED;
}
+ cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
/* establish the camera object, so we can default to view mapping if anything is wrong with it */
if ((rv3d->persp == RV3D_CAMOB) && (v3d->camera) && (v3d->camera->type == OB_CAMERA)) {
camera = v3d->camera->data;
@@ -1283,7 +1333,7 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
BLI_uvproject_from_view_ortho(luv->uv, l->v->co, rotmat);
}
}
@@ -1297,7 +1347,7 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
BLI_uvproject_from_camera(luv->uv, l->v->co, uci);
}
}
@@ -1313,7 +1363,7 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
BLI_uvproject_from_view(luv->uv, l->v->co, rv3d->persmat, rotmat, ar->winx, ar->winy);
}
}
@@ -1337,7 +1387,7 @@ static int uv_from_view_poll(bContext *C)
return (rv3d != NULL);
}
-void UV_OT_from_view(wmOperatorType *ot)
+void UV_OT_project_from_view(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Project From View";
@@ -1417,11 +1467,11 @@ static void uv_map_mirror(BMEditMesh *em, BMFace *efa, MTexPoly *UNUSED(tf))
float dx;
int i, mi;
- i = 0;
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
+ BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
uvs[i] = luv->uv;
- i++;
}
mi = 0;
@@ -1449,11 +1499,15 @@ static int sphere_project_exec(bContext *C, wmOperator *op)
MLoopUV *luv;
float center[3], rotmat[4][4];
+ int cd_loop_uv_offset;
+
/* add uvs if they don't exist yet */
if (!ED_uvedit_ensure_uvs(C, scene, obedit)) {
return OPERATOR_CANCELLED;
}
+ cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
uv_map_transform(C, op, center, rotmat);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -1461,7 +1515,7 @@ static int sphere_project_exec(bContext *C, wmOperator *op)
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
uv_sphere_project(luv->uv, l->v->co, center, rotmat);
}
@@ -1524,24 +1578,28 @@ static int cylinder_project_exec(bContext *C, wmOperator *op)
MLoopUV *luv;
float center[3], rotmat[4][4];
+ int cd_loop_uv_offset;
+
/* add uvs if they don't exist yet */
if (!ED_uvedit_ensure_uvs(C, scene, obedit)) {
return OPERATOR_CANCELLED;
}
+ cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
uv_map_transform(C, op, center, rotmat);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
uv_cylinder_project(luv->uv, l->v->co, center, rotmat);
}
+ tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
uv_map_mirror(em, efa, tf);
}
@@ -1586,11 +1644,15 @@ static int cube_project_exec(bContext *C, wmOperator *op)
float cube_size, *loc, dx, dy;
int cox, coy;
+ int cd_loop_uv_offset;
+
/* add uvs if they don't exist yet */
if (!ED_uvedit_ensure_uvs(C, scene, obedit)) {
return OPERATOR_CANCELLED;
}
+ cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
loc = obedit->obmat[3];
cube_size = RNA_float_get(op->ptr, "cube_size");
@@ -1608,7 +1670,7 @@ static int cube_project_exec(bContext *C, wmOperator *op)
dx = dy = 0;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->uv[0] = 0.5f + 0.5f * cube_size * (loc[cox] + l->v->co[cox]);
luv->uv[1] = 0.5f + 0.5f * cube_size * (loc[coy] + l->v->co[coy]);