Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_image/image_ops.c
| Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BLI_string.h" | #include "BLI_string.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BLT_translation.h" | #include "BLT_translation.h" | ||||
| #include "DNA_camera_types.h" | #include "DNA_camera_types.h" | ||||
| #include "DNA_object_types.h" | #include "DNA_object_types.h" | ||||
| #include "DNA_meshdata_types.h" | |||||
| #include "DNA_node_types.h" | #include "DNA_node_types.h" | ||||
| #include "DNA_packedFile_types.h" | #include "DNA_packedFile_types.h" | ||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||
| #include "DNA_screen_types.h" | #include "DNA_screen_types.h" | ||||
| #include "BKE_colortools.h" | #include "BKE_colortools.h" | ||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_editmesh.h" | |||||
| #include "BKE_icons.h" | #include "BKE_icons.h" | ||||
| #include "BKE_image.h" | #include "BKE_image.h" | ||||
| #include "BKE_image_save.h" | #include "BKE_image_save.h" | ||||
| #include "BKE_layer.h" | |||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_library.h" | #include "BKE_library.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_packedFile.h" | #include "BKE_packedFile.h" | ||||
| #include "BKE_paint.h" | #include "BKE_paint.h" | ||||
| #include "BKE_report.h" | #include "BKE_report.h" | ||||
| #include "BKE_screen.h" | #include "BKE_screen.h" | ||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| Show All 13 Lines | |||||
| #include "RE_pipeline.h" | #include "RE_pipeline.h" | ||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| #include "RNA_define.h" | #include "RNA_define.h" | ||||
| #include "RNA_enum_types.h" | #include "RNA_enum_types.h" | ||||
| #include "ED_image.h" | #include "ED_image.h" | ||||
| #include "ED_mask.h" | #include "ED_mask.h" | ||||
| #include "ED_mesh.h" | |||||
| #include "ED_paint.h" | #include "ED_paint.h" | ||||
| #include "ED_render.h" | #include "ED_render.h" | ||||
| #include "ED_screen.h" | #include "ED_screen.h" | ||||
| #include "ED_space_api.h" | #include "ED_space_api.h" | ||||
| #include "ED_uvedit.h" | #include "ED_uvedit.h" | ||||
| #include "ED_util.h" | #include "ED_util.h" | ||||
| #include "UI_interface.h" | #include "UI_interface.h" | ||||
| ▲ Show 20 Lines • Show All 4,313 Lines • ▼ Show 20 Lines | void IMAGE_OT_tile_add(wmOperatorType *ot) | ||||
| RNA_def_int( | RNA_def_int( | ||||
| ot->srna, "number", 1002, 1001, INT_MAX, "Number", "UDIM number of the tile", 1001, 1099); | ot->srna, "number", 1002, 1001, INT_MAX, "Number", "UDIM number of the tile", 1001, 1099); | ||||
| RNA_def_int(ot->srna, "count", 1, 1, INT_MAX, "Count", "How many tiles to add", 1, 1000); | RNA_def_int(ot->srna, "count", 1, 1, INT_MAX, "Count", "How many tiles to add", 1, 1000); | ||||
| RNA_def_string(ot->srna, "label", NULL, 0, "Label", "Optional tile label"); | RNA_def_string(ot->srna, "label", NULL, 0, "Label", "Optional tile label"); | ||||
| RNA_def_boolean(ot->srna, "fill", true, "Fill", "Fill new tile with a generated image"); | RNA_def_boolean(ot->srna, "fill", true, "Fill", "Fill new tile with a generated image"); | ||||
| def_fill_tile(ot->srna); | def_fill_tile(ot->srna); | ||||
| } | } | ||||
| /* ********************* Tiles from coverage operator****************** */ | |||||
| static bool tiles_from_coverage_poll(bContext *C) | |||||
| { | |||||
| Image *ima = CTX_data_edit_image(C); | |||||
| return (ima != NULL && ima->source == IMA_SRC_TILED && BKE_image_has_ibuf(ima, NULL) && | |||||
| ED_operator_uvedit_space_image(C)); | |||||
| } | |||||
| static int tiles_from_coverage_exec(bContext *C, wmOperator *op) | |||||
| { | |||||
| Image *ima = CTX_data_edit_image(C); | |||||
| ViewLayer *view_layer = CTX_data_view_layer(C); | |||||
| Scene *scene = CTX_data_scene(C); | |||||
| const bool only_selected = RNA_boolean_get(op->ptr, "only_selected"); | |||||
| const bool remove_unused = RNA_boolean_get(op->ptr, "remove_unused"); | |||||
| const bool fill_tile = RNA_boolean_get(op->ptr, "fill"); | |||||
| GSet *covered_tiles = BLI_gset_int_new(__func__); | |||||
| uint objects_len = 0; | |||||
| Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs( | |||||
| view_layer, CTX_wm_view3d(C), &objects_len); | |||||
| /* we need the vert indices */ | |||||
| EDBM_mesh_elem_index_ensure_multi(objects, objects_len, BM_VERT); | |||||
| 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; | |||||
| BMFace *efa; | |||||
| BMLoop *l; | |||||
| BMIter iter, liter; | |||||
| const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); | |||||
| if (cd_loop_uv_offset == -1) { | |||||
| continue; | |||||
| } | |||||
| BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { | |||||
| if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { | |||||
| continue; | |||||
| } | |||||
| bool is_loopsel = !only_selected; | |||||
| float center[2]; | |||||
| zero_v2(center); | |||||
| BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { | |||||
| is_loopsel = is_loopsel || uvedit_uv_select_test(scene, l, cd_loop_uv_offset); | |||||
| const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); | |||||
| add_v2_v2(center, luv->uv); | |||||
| } | |||||
| if (is_loopsel == false) { | |||||
| continue; | |||||
| } | |||||
| mul_v2_fl(center, 1.0f / efa->len); | |||||
| if (center[0] < 0.0f || center[1] < 0.0f || center[0] >= 10.0f) { | |||||
| continue; | |||||
| } | |||||
| int ix = (int)center[0]; | |||||
| int iy = (int)center[1]; | |||||
| int tile_number = 1001 + 10 * iy + ix; | |||||
| BLI_gset_add(covered_tiles, POINTER_FROM_INT(tile_number)); | |||||
| } | |||||
| } | |||||
| MEM_freeN(objects); | |||||
| bool made_change = false; | |||||
| GSET_FOREACH_BEGIN (void *, tile_p, covered_tiles) { | |||||
| int tile_number = POINTER_AS_INT(tile_p); | |||||
| ImageTile *tile = BKE_image_add_tile(ima, tile_number, NULL); | |||||
| if (tile != NULL) { | |||||
| ima->active_tile_index = BLI_findindex(&ima->tiles, tile); | |||||
| if (fill_tile) { | |||||
| do_fill_tile(op->ptr, ima, tile); | |||||
| } | |||||
| made_change = true; | |||||
| } | |||||
| } | |||||
| GSET_FOREACH_END(); | |||||
| if (remove_unused) { | |||||
| LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { | |||||
| if (!BLI_gset_haskey(covered_tiles, POINTER_FROM_INT(tile->tile_number))) { | |||||
| if (BKE_image_remove_tile(ima, tile)) { | |||||
| made_change = true; | |||||
| } | |||||
| } | |||||
| } | |||||
| /* Ensure that the active index is valid. */ | |||||
| ima->active_tile_index = min_ii(ima->active_tile_index, BLI_listbase_count(&ima->tiles) - 1); | |||||
| } | |||||
| if (!made_change) { | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| static void tiles_from_coverage_draw(bContext *UNUSED(C), wmOperator *op) | |||||
| { | |||||
| uiLayout *layout = op->layout; | |||||
| PointerRNA ptr; | |||||
| RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); | |||||
| uiItemR(layout, &ptr, "remove_unused", 0, NULL, ICON_NONE); | |||||
| uiItemR(layout, &ptr, "only_selected", 0, NULL, ICON_NONE); | |||||
| uiItemR(layout, &ptr, "fill", 0, NULL, ICON_NONE); | |||||
| if (RNA_boolean_get(&ptr, "fill")) { | |||||
| draw_fill_tile(&ptr, layout); | |||||
| } | |||||
| } | |||||
| static int tiles_from_coverage_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | |||||
| { | |||||
| return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X, 5 * UI_UNIT_Y); | |||||
| } | |||||
| void IMAGE_OT_tiles_from_coverage(wmOperatorType *ot) | |||||
| { | |||||
| /* identifiers */ | |||||
| ot->name = "Tiles from coverage"; | |||||
| ot->description = "Creates tiles for all spots that are covered by UVs"; | |||||
| ot->idname = "IMAGE_OT_tiles_from_coverage"; | |||||
| /* api callbacks */ | |||||
| ot->poll = tiles_from_coverage_poll; | |||||
| ot->exec = tiles_from_coverage_exec; | |||||
| ot->invoke = tiles_from_coverage_invoke; | |||||
| ot->ui = tiles_from_coverage_draw; | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | |||||
| RNA_def_boolean( | |||||
| ot->srna, "remove_unused", false, "Remove unused", "Remove tiles that are not covered"); | |||||
| RNA_def_boolean( | |||||
| ot->srna, "only_selected", false, "Only selected", "Ignore faces that are not selected"); | |||||
| RNA_def_boolean(ot->srna, "fill", true, "Fill", "Fill new tile with a generated image"); | |||||
| def_fill_tile(ot->srna); | |||||
| } | |||||
| /* ********************* Remove tile operator ****************** */ | /* ********************* Remove tile operator ****************** */ | ||||
| static bool tile_remove_poll(bContext *C) | static bool tile_remove_poll(bContext *C) | ||||
| { | { | ||||
| Image *ima = CTX_data_edit_image(C); | Image *ima = CTX_data_edit_image(C); | ||||
| return (ima != NULL && ima->source == IMA_SRC_TILED && ima->active_tile_index != 0); | return (ima != NULL && ima->source == IMA_SRC_TILED && ima->active_tile_index != 0); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 103 Lines • Show Last 20 Lines | |||||