Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/uvedit/uvedit_unwrap_ops.c
| Show First 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | |||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_customdata.h" | #include "BKE_customdata.h" | ||||
| #include "BKE_image.h" | #include "BKE_image.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_material.h" | #include "BKE_material.h" | ||||
| #include "BKE_report.h" | #include "BKE_report.h" | ||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| #include "BKE_editmesh.h" | #include "BKE_editmesh.h" | ||||
| #include "BKE_layer.h" | |||||
| #include "DEG_depsgraph.h" | #include "DEG_depsgraph.h" | ||||
| #include "PIL_time.h" | #include "PIL_time.h" | ||||
| #include "UI_interface.h" | #include "UI_interface.h" | ||||
| #include "ED_image.h" | #include "ED_image.h" | ||||
| ▲ Show 20 Lines • Show All 125 Lines • ▼ Show 20 Lines | if (implicit && !l) | ||||
| continue; | continue; | ||||
| return true; | return true; | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| static bool uvedit_have_selection_multi( | |||||
| Scene *scene, Object **objects, const uint objects_len, bool implicit) | |||||
| { | |||||
| bool have_select = false; | |||||
| for (uint ob_index = 0; ob_index < objects_len; ob_index++) { | |||||
| Object *obedit = objects[ob_index]; | |||||
| BMEditMesh *em = BKE_editmesh_from_object(obedit); | |||||
| if (uvedit_have_selection(scene, em, implicit)) { | |||||
| have_select = true; | |||||
| break; | |||||
| } | |||||
| } | |||||
| return have_select; | |||||
| } | |||||
| void ED_uvedit_get_aspect(Scene *scene, Object *ob, BMesh *bm, float *aspx, float *aspy) | void ED_uvedit_get_aspect(Scene *scene, Object *ob, BMesh *bm, float *aspx, float *aspy) | ||||
| { | { | ||||
| bool sloppy = true; | bool sloppy = true; | ||||
| bool selected = false; | bool selected = false; | ||||
| BMFace *efa; | BMFace *efa; | ||||
| Image *ima; | Image *ima; | ||||
| efa = BM_mesh_active_face_get(bm, sloppy, selected); | efa = BM_mesh_active_face_get(bm, sloppy, selected); | ||||
| Show All 40 Lines | BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { | ||||
| uv[i] = luv->uv; | uv[i] = luv->uv; | ||||
| pin[i] = (luv->flag & MLOOPUV_PINNED) != 0; | pin[i] = (luv->flag & MLOOPUV_PINNED) != 0; | ||||
| select[i] = uvedit_uv_select_test(scene, l, cd_loop_uv_offset); | select[i] = uvedit_uv_select_test(scene, l, cd_loop_uv_offset); | ||||
| } | } | ||||
| param_face_add(handle, key, i, vkeys, co, uv, pin, select, efa->no); | param_face_add(handle, key, i, vkeys, co, uv, pin, select, efa->no); | ||||
| } | } | ||||
| static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMesh *bm, | static ParamHandle *construct_param_handle_single( | ||||
| Scene *scene, Object *ob, BMesh *bm, | |||||
| const bool implicit, const bool fill, const bool sel, | const bool implicit, const bool fill, const bool sel, | ||||
| const bool correct_aspect) | const bool correct_aspect) | ||||
| { | { | ||||
| ParamHandle *handle; | ParamHandle *handle; | ||||
| BMFace *efa; | BMFace *efa; | ||||
| BMLoop *l; | BMLoop *l; | ||||
| BMEdge *eed; | BMEdge *eed; | ||||
| BMIter iter, liter; | BMIter iter, liter; | ||||
| int i; | int i; | ||||
| ▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | if (!implicit) { | ||||
| } | } | ||||
| } | } | ||||
| param_construct_end(handle, fill, implicit); | param_construct_end(handle, fill, implicit); | ||||
| return handle; | return handle; | ||||
| } | } | ||||
| /** | |||||
| * Version of #construct_param_handle_single that handles multiple objects. | |||||
| */ | |||||
| static ParamHandle *construct_param_handle_multi( | |||||
| Scene *scene, Object **objects, const uint objects_len, | |||||
| const bool implicit, const bool fill, const bool sel, | |||||
| const bool correct_aspect) | |||||
| { | |||||
| ParamHandle *handle; | |||||
| BMFace *efa; | |||||
| BMLoop *l; | |||||
| BMEdge *eed; | |||||
| BMIter iter, liter; | |||||
| int i; | |||||
| handle = param_construct_begin(); | |||||
| if (correct_aspect) { | |||||
| Object *ob = objects[0]; | |||||
| BMEditMesh *em = BKE_editmesh_from_object(ob); | |||||
| BMesh *bm = em->bm; | |||||
| float aspx, aspy; | |||||
| ED_uvedit_get_aspect(scene, ob, bm, &aspx, &aspy); | |||||
| if (aspx != aspy) | |||||
| param_aspect_ratio(handle, aspx, aspy); | |||||
| } | |||||
| /* we need the vert indices */ | |||||
| EDBM_mesh_elem_index_ensure_multi(objects, objects_len, BM_VERT); | |||||
| int offset = 0; | |||||
| /* no indent, avoid diff noise */ | |||||
| for (uint ob_index = 0; ob_index < objects_len; ob_index++) { | |||||
| Object *obedit = objects[ob_index]; | |||||
| BMEditMesh *em = BKE_editmesh_from_object(obedit); | |||||
| BMesh *bm = em->bm; | |||||
| const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); | |||||
| BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { | |||||
| if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || (sel && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) { | |||||
| continue; | |||||
| } | |||||
| if (implicit) { | |||||
| bool is_loopsel = false; | |||||
| BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { | |||||
| if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { | |||||
| is_loopsel = true; | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (is_loopsel == false) { | |||||
| continue; | |||||
| } | |||||
| } | |||||
| construct_param_handle_face_add(handle, scene, efa, i + offset, cd_loop_uv_offset); | |||||
| } | |||||
| if (!implicit) { | |||||
| BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { | |||||
| if (BM_elem_flag_test(eed, BM_ELEM_SEAM)) { | |||||
| ParamKey vkeys[2]; | |||||
| vkeys[0] = (ParamKey)BM_elem_index_get(eed->v1); | |||||
| vkeys[1] = (ParamKey)BM_elem_index_get(eed->v2); | |||||
| param_edge_set_seam(handle, vkeys); | |||||
| } | |||||
| } | |||||
| } | |||||
| offset += bm->totface; | |||||
| } /* objects */ | |||||
| param_construct_end(handle, fill, implicit); | |||||
| return handle; | |||||
| } | |||||
| static void texface_from_original_index(BMFace *efa, int index, float **uv, ParamBool *pin, ParamBool *select, | static void texface_from_original_index(BMFace *efa, int index, float **uv, ParamBool *pin, ParamBool *select, | ||||
| Scene *scene, const int cd_loop_uv_offset) | Scene *scene, const int cd_loop_uv_offset) | ||||
| { | { | ||||
| BMLoop *l; | BMLoop *l; | ||||
| BMIter liter; | BMIter liter; | ||||
| MLoopUV *luv; | MLoopUV *luv; | ||||
| ▲ Show 20 Lines • Show All 195 Lines • ▼ Show 20 Lines | static bool minimize_stretch_init(bContext *C, wmOperator *op) | ||||
| ms = MEM_callocN(sizeof(MinStretch), "MinStretch"); | ms = MEM_callocN(sizeof(MinStretch), "MinStretch"); | ||||
| ms->scene = scene; | ms->scene = scene; | ||||
| ms->obedit = obedit; | ms->obedit = obedit; | ||||
| ms->em = em; | ms->em = em; | ||||
| ms->blend = RNA_float_get(op->ptr, "blend"); | ms->blend = RNA_float_get(op->ptr, "blend"); | ||||
| ms->iterations = RNA_int_get(op->ptr, "iterations"); | ms->iterations = RNA_int_get(op->ptr, "iterations"); | ||||
| ms->i = 0; | ms->i = 0; | ||||
| ms->handle = construct_param_handle(scene, obedit, em->bm, implicit, fill_holes, 1, 1); | ms->handle = construct_param_handle_single(scene, obedit, em->bm, implicit, fill_holes, 1, 1); | ||||
| ms->lasttime = PIL_check_seconds_timer(); | ms->lasttime = PIL_check_seconds_timer(); | ||||
| param_stretch_begin(ms->handle); | param_stretch_begin(ms->handle); | ||||
| if (ms->blend != 0.0f) | if (ms->blend != 0.0f) | ||||
| param_stretch_blend(ms->handle, ms->blend); | param_stretch_blend(ms->handle, ms->blend); | ||||
| op->customdata = ms; | op->customdata = ms; | ||||
| ▲ Show 20 Lines • Show All 163 Lines • ▼ Show 20 Lines | void UV_OT_minimize_stretch(wmOperatorType *ot) | ||||
| /* properties */ | /* properties */ | ||||
| RNA_def_boolean(ot->srna, "fill_holes", 1, "Fill Holes", "Virtual fill holes in mesh before unwrapping, to better avoid overlaps and preserve symmetry"); | RNA_def_boolean(ot->srna, "fill_holes", 1, "Fill Holes", "Virtual fill holes in mesh before unwrapping, to better avoid overlaps and preserve symmetry"); | ||||
| RNA_def_float_factor(ot->srna, "blend", 0.0f, 0.0f, 1.0f, "Blend", "Blend factor between stretch minimized and original", 0.0f, 1.0f); | RNA_def_float_factor(ot->srna, "blend", 0.0f, 0.0f, 1.0f, "Blend", "Blend factor between stretch minimized and original", 0.0f, 1.0f); | ||||
| RNA_def_int(ot->srna, "iterations", 0, 0, INT_MAX, "Iterations", "Number of iterations to run, 0 is unlimited when run interactively", 0, 100); | RNA_def_int(ot->srna, "iterations", 0, 0, INT_MAX, "Iterations", "Number of iterations to run, 0 is unlimited when run interactively", 0, 100); | ||||
| } | } | ||||
| /* ******************** Pack Islands operator **************** */ | /* ******************** Pack Islands operator **************** */ | ||||
| void ED_uvedit_pack_islands(Scene *scene, Object *ob, BMesh *bm, bool selected, bool correct_aspect, bool do_rotate) | |||||
| void ED_uvedit_pack_islands_single(Scene *scene, Object *ob, BMesh *bm, bool selected, bool correct_aspect, bool do_rotate) | |||||
| { | |||||
| ParamHandle *handle; | |||||
| handle = construct_param_handle_single(scene, ob, bm, true, false, selected, correct_aspect); | |||||
| param_pack(handle, scene->toolsettings->uvcalc_margin, do_rotate); | |||||
| param_flush(handle); | |||||
| param_delete(handle); | |||||
| } | |||||
| void ED_uvedit_pack_islands_multi( | |||||
| Scene *scene, Object **objects, const uint objects_len, | |||||
| bool selected, bool correct_aspect, bool do_rotate) | |||||
| { | { | ||||
| ParamHandle *handle; | ParamHandle *handle; | ||||
| handle = construct_param_handle(scene, ob, bm, true, false, selected, correct_aspect); | handle = construct_param_handle_multi( | ||||
| scene, objects, objects_len, true, false, selected, correct_aspect); | |||||
| param_pack(handle, scene->toolsettings->uvcalc_margin, do_rotate); | param_pack(handle, scene->toolsettings->uvcalc_margin, do_rotate); | ||||
| param_flush(handle); | param_flush(handle); | ||||
| param_delete(handle); | param_delete(handle); | ||||
| } | } | ||||
| static int pack_islands_exec(bContext *C, wmOperator *op) | static int pack_islands_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| ViewLayer *view_layer = CTX_data_view_layer(C); | |||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| Object *obedit = CTX_data_edit_object(C); | |||||
| BMEditMesh *em = BKE_editmesh_from_object(obedit); | |||||
| bool do_rotate = RNA_boolean_get(op->ptr, "rotate"); | bool do_rotate = RNA_boolean_get(op->ptr, "rotate"); | ||||
| if (!uvedit_have_selection(scene, em, true)) { | uint objects_len = 0; | ||||
| Object **objects = BKE_view_layer_array_from_objects_in_edit_mode( | |||||
| view_layer, &objects_len, | |||||
| .filter_fn = BKE_view_layer_filter_edit_mesh_has_uvs, | |||||
| .no_dupe_data = true); | |||||
| if (!uvedit_have_selection_multi(scene, objects, objects_len, true)) { | |||||
| MEM_SAFE_FREE(objects); | |||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| if (RNA_struct_property_is_set(op->ptr, "margin")) | if (RNA_struct_property_is_set(op->ptr, "margin")) | ||||
| scene->toolsettings->uvcalc_margin = RNA_float_get(op->ptr, "margin"); | scene->toolsettings->uvcalc_margin = RNA_float_get(op->ptr, "margin"); | ||||
| else | else | ||||
| RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin); | RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin); | ||||
| ED_uvedit_pack_islands(scene, obedit, em->bm, true, true, do_rotate); | ED_uvedit_pack_islands_multi(scene, objects, objects_len, true, true, do_rotate); | ||||
| for (uint ob_index = 0; ob_index < objects_len; ob_index++) { | |||||
| Object *obedit = objects[ob_index]; | |||||
| DEG_id_tag_update(obedit->data, 0); | DEG_id_tag_update(obedit->data, 0); | ||||
| WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | ||||
| } | |||||
| MEM_SAFE_FREE(objects); | |||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void UV_OT_pack_islands(wmOperatorType *ot) | void UV_OT_pack_islands(wmOperatorType *ot) | ||||
| { | { | ||||
| /* identifiers */ | /* identifiers */ | ||||
| ot->name = "Pack Islands"; | ot->name = "Pack Islands"; | ||||
| Show All 20 Lines | static int average_islands_scale_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| BMEditMesh *em = BKE_editmesh_from_object(obedit); | BMEditMesh *em = BKE_editmesh_from_object(obedit); | ||||
| ParamHandle *handle; | ParamHandle *handle; | ||||
| bool implicit = true; | bool implicit = true; | ||||
| if (!uvedit_have_selection(scene, em, implicit)) { | if (!uvedit_have_selection(scene, em, implicit)) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| handle = construct_param_handle(scene, obedit, em->bm, implicit, 0, 1, 1); | handle = construct_param_handle_single(scene, obedit, em->bm, implicit, 0, 1, 1); | ||||
| param_average(handle); | param_average(handle); | ||||
| param_flush(handle); | param_flush(handle); | ||||
| param_delete(handle); | param_delete(handle); | ||||
| DEG_id_tag_update(obedit->data, 0); | DEG_id_tag_update(obedit->data, 0); | ||||
| WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| Show All 28 Lines | void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit) | ||||
| if (!ED_uvedit_test(obedit)) { | if (!ED_uvedit_test(obedit)) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (use_subsurf) | if (use_subsurf) | ||||
| liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, false, true); | liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, false, true); | ||||
| else | else | ||||
| liveHandle = construct_param_handle(scene, obedit, em->bm, false, fillholes, false, true); | liveHandle = construct_param_handle_single(scene, obedit, em->bm, false, fillholes, false, true); | ||||
| param_lscm_begin(liveHandle, PARAM_TRUE, abf); | param_lscm_begin(liveHandle, PARAM_TRUE, abf); | ||||
| } | } | ||||
| void ED_uvedit_live_unwrap_re_solve(void) | void ED_uvedit_live_unwrap_re_solve(void) | ||||
| { | { | ||||
| if (liveHandle) { | if (liveHandle) { | ||||
| param_lscm_solve(liveHandle); | param_lscm_solve(liveHandle); | ||||
| Show All 14 Lines | |||||
| void ED_uvedit_live_unwrap(Scene *scene, Object *obedit) | void ED_uvedit_live_unwrap(Scene *scene, Object *obedit) | ||||
| { | { | ||||
| BMEditMesh *em = BKE_editmesh_from_object(obedit); | BMEditMesh *em = BKE_editmesh_from_object(obedit); | ||||
| if (scene->toolsettings->edge_mode_live_unwrap && | if (scene->toolsettings->edge_mode_live_unwrap && | ||||
| CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV)) | CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV)) | ||||
| { | { | ||||
| ED_unwrap_lscm(scene, obedit, false); /* unwrap all not just sel */ | ED_unwrap_lscm(scene, obedit, false, false); /* unwrap all not just sel */ | ||||
| } | } | ||||
| } | } | ||||
| /*************** UV Map Common Transforms *****************/ | /*************** UV Map Common Transforms *****************/ | ||||
| #define VIEW_ON_EQUATOR 0 | #define VIEW_ON_EQUATOR 0 | ||||
| #define VIEW_ON_POLES 1 | #define VIEW_ON_POLES 1 | ||||
| #define ALIGN_TO_OBJECT 2 | #define ALIGN_TO_OBJECT 2 | ||||
| ▲ Show 20 Lines • Show All 305 Lines • ▼ Show 20 Lines | BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* ******************** Unwrap operator **************** */ | /* ******************** Unwrap operator **************** */ | ||||
| /* assumes UV Map is checked, doesn't run update funcs */ | /* assumes UV Map is checked, doesn't run update funcs */ | ||||
| void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel) | void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel, const bool pack) | ||||
| { | { | ||||
| BMEditMesh *em = BKE_editmesh_from_object(obedit); | BMEditMesh *em = BKE_editmesh_from_object(obedit); | ||||
| ParamHandle *handle; | ParamHandle *handle; | ||||
| const bool fill_holes = (scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES) != 0; | const bool fill_holes = (scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES) != 0; | ||||
| const bool correct_aspect = (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) == 0; | const bool correct_aspect = (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) == 0; | ||||
| bool use_subsurf; | bool use_subsurf; | ||||
| modifier_unwrap_state(obedit, scene, &use_subsurf); | modifier_unwrap_state(obedit, scene, &use_subsurf); | ||||
| if (use_subsurf) | if (use_subsurf) | ||||
| handle = construct_param_handle_subsurfed(scene, obedit, em, fill_holes, sel, correct_aspect); | handle = construct_param_handle_subsurfed(scene, obedit, em, fill_holes, sel, correct_aspect); | ||||
| else | else | ||||
| handle = construct_param_handle(scene, obedit, em->bm, false, fill_holes, sel, correct_aspect); | handle = construct_param_handle_single(scene, obedit, em->bm, false, fill_holes, sel, correct_aspect); | ||||
| param_lscm_begin(handle, PARAM_FALSE, scene->toolsettings->unwrapper == 0); | param_lscm_begin(handle, PARAM_FALSE, scene->toolsettings->unwrapper == 0); | ||||
| param_lscm_solve(handle); | param_lscm_solve(handle); | ||||
| param_lscm_end(handle); | param_lscm_end(handle); | ||||
| param_average(handle); | param_average(handle); | ||||
| if (pack) { | |||||
| param_pack(handle, scene->toolsettings->uvcalc_margin, false); | param_pack(handle, scene->toolsettings->uvcalc_margin, false); | ||||
| } | |||||
| param_flush(handle); | param_flush(handle); | ||||
| param_delete(handle); | param_delete(handle); | ||||
| } | } | ||||
| static int unwrap_exec(bContext *C, wmOperator *op) | static int unwrap_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| ViewLayer *view_layer = CTX_data_view_layer(C); | |||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| #if 0 | |||||
| Object *obedit = CTX_data_edit_object(C); | Object *obedit = CTX_data_edit_object(C); | ||||
| BMEditMesh *em = BKE_editmesh_from_object(obedit); | BMEditMesh *em = BKE_editmesh_from_object(obedit); | ||||
| #endif | |||||
| int method = RNA_enum_get(op->ptr, "method"); | int method = RNA_enum_get(op->ptr, "method"); | ||||
| const bool fill_holes = RNA_boolean_get(op->ptr, "fill_holes"); | const bool fill_holes = RNA_boolean_get(op->ptr, "fill_holes"); | ||||
| const bool correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect"); | const bool correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect"); | ||||
| const bool use_subsurf = RNA_boolean_get(op->ptr, "use_subsurf_data"); | const bool use_subsurf = RNA_boolean_get(op->ptr, "use_subsurf_data"); | ||||
| #if 0 | |||||
| bool use_subsurf_final; | bool use_subsurf_final; | ||||
| #endif | |||||
| float obsize[3]; | float obsize[3]; | ||||
| bool implicit = false; | bool implicit = false; | ||||
| if (!uvedit_have_selection(scene, em, implicit)) { | uint objects_len = 0; | ||||
| Object **objects = BKE_view_layer_array_from_objects_in_edit_mode( | |||||
| view_layer, &objects_len, | |||||
| .no_dupe_data = true); | |||||
| if (!uvedit_have_selection_multi(scene, objects, objects_len, implicit)) { | |||||
| MEM_SAFE_FREE(objects); | |||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| /* add uvs if they don't exist yet */ | /* add uvs if they don't exist yet */ | ||||
| for (uint ob_index = 0; ob_index < objects_len; ob_index++) { | |||||
| Object *obedit = objects[ob_index]; | |||||
| if (!ED_uvedit_ensure_uvs(C, scene, obedit)) { | if (!ED_uvedit_ensure_uvs(C, scene, obedit)) { | ||||
| return OPERATOR_CANCELLED; | continue; | ||||
| } | } | ||||
| mat4_to_size(obsize, obedit->obmat); | mat4_to_size(obsize, obedit->obmat); | ||||
| if (!(fabsf(obsize[0] - obsize[1]) < 1e-4f && fabsf(obsize[1] - obsize[2]) < 1e-4f)) | if (!(fabsf(obsize[0] - obsize[1]) < 1e-4f && fabsf(obsize[1] - obsize[2]) < 1e-4f)) | ||||
| BKE_report(op->reports, RPT_INFO, | BKE_report(op->reports, RPT_INFO, | ||||
| "Object has non-uniform scale, unwrap will operate on a non-scaled version of the mesh"); | "Object has non-uniform scale, unwrap will operate on a non-scaled version of the mesh"); | ||||
| else if (is_negative_m4(obedit->obmat)) | else if (is_negative_m4(obedit->obmat)) | ||||
| BKE_report(op->reports, RPT_INFO, | BKE_report(op->reports, RPT_INFO, | ||||
| "Object has negative scale, unwrap will operate on a non-flipped version of the mesh"); | "Object has negative scale, unwrap will operate on a non-flipped version of the mesh"); | ||||
| } | |||||
| /* remember last method for live unwrap */ | /* remember last method for live unwrap */ | ||||
| if (RNA_struct_property_is_set(op->ptr, "method")) | if (RNA_struct_property_is_set(op->ptr, "method")) | ||||
| scene->toolsettings->unwrapper = method; | scene->toolsettings->unwrapper = method; | ||||
| else | else | ||||
| RNA_enum_set(op->ptr, "method", scene->toolsettings->unwrapper); | RNA_enum_set(op->ptr, "method", scene->toolsettings->unwrapper); | ||||
| /* remember packing marging */ | /* remember packing marging */ | ||||
| if (RNA_struct_property_is_set(op->ptr, "margin")) | if (RNA_struct_property_is_set(op->ptr, "margin")) | ||||
| scene->toolsettings->uvcalc_margin = RNA_float_get(op->ptr, "margin"); | scene->toolsettings->uvcalc_margin = RNA_float_get(op->ptr, "margin"); | ||||
| else | else | ||||
| RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin); | RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin); | ||||
| if (fill_holes) scene->toolsettings->uvcalc_flag |= UVCALC_FILLHOLES; | if (fill_holes) scene->toolsettings->uvcalc_flag |= UVCALC_FILLHOLES; | ||||
| else scene->toolsettings->uvcalc_flag &= ~UVCALC_FILLHOLES; | else scene->toolsettings->uvcalc_flag &= ~UVCALC_FILLHOLES; | ||||
| if (correct_aspect) scene->toolsettings->uvcalc_flag &= ~UVCALC_NO_ASPECT_CORRECT; | if (correct_aspect) scene->toolsettings->uvcalc_flag &= ~UVCALC_NO_ASPECT_CORRECT; | ||||
| else scene->toolsettings->uvcalc_flag |= UVCALC_NO_ASPECT_CORRECT; | else scene->toolsettings->uvcalc_flag |= UVCALC_NO_ASPECT_CORRECT; | ||||
| if (use_subsurf) scene->toolsettings->uvcalc_flag |= UVCALC_USESUBSURF; | if (use_subsurf) scene->toolsettings->uvcalc_flag |= UVCALC_USESUBSURF; | ||||
| else scene->toolsettings->uvcalc_flag &= ~UVCALC_USESUBSURF; | else scene->toolsettings->uvcalc_flag &= ~UVCALC_USESUBSURF; | ||||
| #if 0 | |||||
| /* double up the check here but better keep ED_unwrap_lscm interface simple and not | /* double up the check here but better keep ED_unwrap_lscm interface simple and not | ||||
| * pass operator for warning append */ | * pass operator for warning append */ | ||||
| modifier_unwrap_state(obedit, scene, &use_subsurf_final); | modifier_unwrap_state(obedit, scene, &use_subsurf_final); | ||||
| if (use_subsurf != use_subsurf_final) | if (use_subsurf != use_subsurf_final) | ||||
| BKE_report(op->reports, RPT_INFO, "Subdivision Surface modifier needs to be first to work with unwrap"); | BKE_report(op->reports, RPT_INFO, "Subdivision Surface modifier needs to be first to work with unwrap"); | ||||
| #endif | |||||
| /* execute unwrap */ | /* execute unwrap */ | ||||
| ED_unwrap_lscm(scene, obedit, true); | for (uint ob_index = 0; ob_index < objects_len; ob_index++) { | ||||
| Object *obedit = objects[ob_index]; | |||||
| ED_unwrap_lscm(scene, obedit, true, false); | |||||
| DEG_id_tag_update(obedit->data, 0); | DEG_id_tag_update(obedit->data, 0); | ||||
| WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | ||||
| } | |||||
| ED_uvedit_pack_islands_multi(scene, objects, objects_len, true, true, true); | |||||
| MEM_SAFE_FREE(objects); | |||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void UV_OT_unwrap(wmOperatorType *ot) | void UV_OT_unwrap(wmOperatorType *ot) | ||||
| { | { | ||||
| static const EnumPropertyItem method_items[] = { | static const EnumPropertyItem method_items[] = { | ||||
| {0, "ANGLE_BASED", 0, "Angle Based", ""}, | {0, "ANGLE_BASED", 0, "Angle Based", ""}, | ||||
| Show All 38 Lines | static int uv_from_view_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | ||||
| prop = RNA_struct_find_property(op->ptr, "correct_aspect"); | prop = RNA_struct_find_property(op->ptr, "correct_aspect"); | ||||
| if (!RNA_property_is_set(op->ptr, prop)) RNA_property_boolean_set(op->ptr, prop, (camera == NULL)); | if (!RNA_property_is_set(op->ptr, prop)) RNA_property_boolean_set(op->ptr, prop, (camera == NULL)); | ||||
| return uv_from_view_exec(C, op); | return uv_from_view_exec(C, op); | ||||
| } | } | ||||
| static int uv_from_view_exec(bContext *C, wmOperator *op) | static int uv_from_view_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| ViewLayer *view_layer = CTX_data_view_layer(C); | |||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| Object *obedit = CTX_data_edit_object(C); | |||||
| BMEditMesh *em = BKE_editmesh_from_object(obedit); | |||||
| ARegion *ar = CTX_wm_region(C); | ARegion *ar = CTX_wm_region(C); | ||||
| View3D *v3d = CTX_wm_view3d(C); | View3D *v3d = CTX_wm_view3d(C); | ||||
| RegionView3D *rv3d = CTX_wm_region_view3d(C); | RegionView3D *rv3d = CTX_wm_region_view3d(C); | ||||
| Camera *camera = ED_view3d_camera_data_get(v3d, rv3d); | Camera *camera = ED_view3d_camera_data_get(v3d, rv3d); | ||||
| BMFace *efa; | BMFace *efa; | ||||
| BMLoop *l; | BMLoop *l; | ||||
| BMIter iter, liter; | BMIter iter, liter; | ||||
| MLoopUV *luv; | MLoopUV *luv; | ||||
| float rotmat[4][4]; | float rotmat[4][4]; | ||||
| int cd_loop_uv_offset; | |||||
| uint objects_len = 0; | |||||
| Object **objects = BKE_view_layer_array_from_objects_in_edit_mode( | |||||
| view_layer, &objects_len, | |||||
| .no_dupe_data = true); | |||||
| for (uint ob_index = 0; ob_index < objects_len; ob_index++) { | |||||
| Object *obedit = objects[ob_index]; | |||||
| BMEditMesh *em = BKE_editmesh_from_object(obedit); | |||||
| /* add uvs if they don't exist yet */ | /* add uvs if they don't exist yet */ | ||||
| if (!ED_uvedit_ensure_uvs(C, scene, obedit)) { | if (!ED_uvedit_ensure_uvs(C, scene, obedit)) { | ||||
| return OPERATOR_CANCELLED; | continue; | ||||
| } | } | ||||
| cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); | const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); | ||||
| if (RNA_boolean_get(op->ptr, "orthographic")) { | if (RNA_boolean_get(op->ptr, "orthographic")) { | ||||
| uv_map_rotation_matrix(rotmat, rv3d, obedit, 90.0f, 0.0f, 1.0f); | uv_map_rotation_matrix(rotmat, rv3d, obedit, 90.0f, 0.0f, 1.0f); | ||||
| BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { | BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { | ||||
| if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) | if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) | ||||
| continue; | continue; | ||||
| Show All 37 Lines | else { | ||||
| } | } | ||||
| } | } | ||||
| uv_map_clip_correct(scene, obedit, em, op); | uv_map_clip_correct(scene, obedit, em, op); | ||||
| DEG_id_tag_update(obedit->data, 0); | DEG_id_tag_update(obedit->data, 0); | ||||
| WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | ||||
| } | |||||
| MEM_SAFE_FREE(objects); | |||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| static int uv_from_view_poll(bContext *C) | static int uv_from_view_poll(bContext *C) | ||||
| { | { | ||||
| RegionView3D *rv3d = CTX_wm_region_view3d(C); | RegionView3D *rv3d = CTX_wm_region_view3d(C); | ||||
| if (!ED_operator_uvmap(C)) | if (!ED_operator_uvmap(C)) | ||||
| ▲ Show 20 Lines • Show All 348 Lines • Show Last 20 Lines | |||||