Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/uvedit/uvedit_texturemargin.c
- This file was added.
| /* | |||||
| * This program is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the GNU General Public License | |||||
| * as published by the Free Software Foundation; either version 2 | |||||
| * of the License, or (at your option) any later version. | |||||
| * | |||||
| * This program is distributed in the hope that it will be useful, | |||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | |||||
| * | |||||
| * You should have received a copy of the GNU General Public License | |||||
| * along with this program; if not, write to the Free Software Foundation, | |||||
| * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||||
| * | |||||
| * The Original Code is Copyright (C) 2008 Blender Foundation. | |||||
| * All rights reserved. | |||||
| */ | |||||
| /** \file | |||||
| * \ingroup edrend | |||||
| */ | |||||
| #include "BKE_customdata.h" | |||||
| #include "BKE_image.h" | |||||
| #include "BKE_report.h" | |||||
| #include "BKE_scene.h" | |||||
| #include "BKE_screen.h" | |||||
| #include "DEG_depsgraph.h" | |||||
| #include "DNA_mesh_types.h" | |||||
| #include "DNA_meshdata_types.h" | |||||
| #include "DNA_scene_types.h" | |||||
| #include "ED_image.h" | |||||
| #include "ED_render.h" | |||||
| #include "ED_space_api.h" | |||||
| #include "ED_uvedit.h" | |||||
| #include "IMB_imbuf.h" | |||||
| #include "IMB_imbuf_types.h" | |||||
| #include "MEM_guardedalloc.h" | |||||
| #include "RE_pipeline.h" | |||||
| #include "RE_texture_margin.h" | |||||
| #include "RNA_access.h" | |||||
| #include "RNA_define.h" | |||||
| #include "WM_api.h" | |||||
| #include "WM_types.h" | |||||
| #include "uvedit_intern.h" | |||||
| static int texture_margin(Object const *ob, | |||||
| int margin, | |||||
| Mesh const *me, | |||||
| MLoopUV const *mloopuv, | |||||
| Image *image, | |||||
| wmOperator *op) | |||||
| { | |||||
| ImBuf *ibuf; | |||||
| int ret = OPERATOR_CANCELLED; | |||||
| void *lock; | |||||
| ibuf = BKE_image_acquire_ibuf(image, NULL, &lock); | |||||
| if (ibuf) { | |||||
| RE_generate_texturemargin_copypixels(ibuf, NULL, margin, me, mloopuv); | |||||
| ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; | |||||
| BKE_image_mark_dirty(image, ibuf); | |||||
| if (ibuf->rect_float) { | |||||
| ibuf->userflags |= IB_RECT_INVALID; | |||||
| } | |||||
| /* force mipmap recalc */ | |||||
| if (ibuf->mipmap[0]) { | |||||
| ibuf->userflags |= IB_MIPMAP_INVALID; | |||||
| imb_freemipmapImBuf(ibuf); | |||||
| } | |||||
| BKE_image_release_ibuf(image, ibuf, lock); | |||||
| /* force GPU texture update */ | |||||
| BKE_image_free_gputextures(image); | |||||
| DEG_id_tag_update(&image->id, 0); | |||||
| ret = OPERATOR_FINISHED; | |||||
| } | |||||
| else { | |||||
| BKE_reportf(op->reports, | |||||
| RPT_ERROR, | |||||
| "Uninitialized image \"%s\" from object \"%s\"", | |||||
| image->id.name + 2, | |||||
| ob->id.name + 2); | |||||
| BKE_image_release_ibuf(image, ibuf, lock); | |||||
| } | |||||
| return ret; | |||||
| } | |||||
| static int texture_margin_exec(bContext *C, wmOperator *op) | |||||
| { | |||||
| Scene *scene = CTX_data_scene(C); | |||||
| SpaceImage *sima = CTX_wm_space_image(C); | |||||
| int margin = RNA_int_get(op->ptr, "margin"); | |||||
| if (margin < 0) { | |||||
| margin = scene->r.bake.margin; | |||||
| } | |||||
| if (margin == 0) { | |||||
| BKE_reportf(op->reports, RPT_ERROR, "Generating a margin of 0 pixels does nothing!"); | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| Object *ob = CTX_data_active_object(C); | |||||
| if (!ob) { | |||||
| BKE_reportf(op->reports, RPT_ERROR, "No valid selected object!"); | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| if (ob->type != OB_MESH) { | |||||
| BKE_reportf(op->reports, RPT_ERROR, "Can only generate texture borders for Mesh objects!"); | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| struct Mesh *me = (Mesh *)ob->data; | |||||
| char *uv_layer = RNA_string_get_alloc(op->ptr, "uv_layer", NULL, 0, 0); | |||||
| const MLoopUV *mloopuv; | |||||
| if ((uv_layer == NULL) || (uv_layer[0] == '\0')) { | |||||
| /* TODO: look up uv layer from material nodetree. */ | |||||
| mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV); | |||||
| } | |||||
| else { | |||||
| int uv_id = CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, uv_layer); | |||||
| mloopuv = CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, uv_id); | |||||
| } | |||||
| if (mloopuv == NULL) { | |||||
| if (uv_layer) { | |||||
| MEM_freeN(uv_layer); | |||||
| } | |||||
| BKE_reportf(op->reports, RPT_ERROR, "No valid UV-map!"); | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| int ret = OPERATOR_CANCELLED; | |||||
| if (sima) { | |||||
| if (sima->image) { | |||||
| ret = texture_margin(ob, margin, me, mloopuv, sima->image, op); | |||||
| } | |||||
| else { | |||||
| BKE_reportf(op->reports, RPT_ERROR, "No image loaded."); | |||||
| } | |||||
| } | |||||
| else { | |||||
| for (int i = 0; i < ob->totcol; i++) { | |||||
| int mat_nr = i + 1; | |||||
| Image *image; | |||||
| ED_object_get_active_image(ob, mat_nr, &image, NULL, NULL, NULL); | |||||
| if (image) { | |||||
| ret = texture_margin(ob, margin, me, mloopuv, image, op); | |||||
| if (ret == OPERATOR_CANCELLED) { | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| if (uv_layer) { | |||||
| MEM_freeN(uv_layer); | |||||
| } | |||||
| WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene); | |||||
| return ret; | |||||
| } | |||||
| void TEXTURE_OT_margin_copypixels(wmOperatorType *ot) | |||||
| { | |||||
| PropertyRNA *prop; | |||||
| /* identifiers */ | |||||
| ot->name = "Margin"; | |||||
| ot->description = "Generate texture margin based on the UV-map and existing texture data"; | |||||
| ot->idname = "RENDER_OT_margin_copypixels"; | |||||
| /* api callbacks */ | |||||
| // ot->invoke = screen_render_invoke; | |||||
| // ot->modal = screen_render_modal; | |||||
| // ot->cancel = screen_render_cancel; | |||||
| ot->exec = texture_margin_exec; | |||||
| // ot->poll = ED_operator_screenactive; | |||||
| prop = RNA_def_int(ot->srna, | |||||
| "margin", | |||||
| -1, | |||||
| -1, | |||||
| 128, | |||||
| "", // ui name | |||||
| "", // ui desc | |||||
| 0, | |||||
| 16); | |||||
| RNA_def_property_flag(prop, PROP_SKIP_SAVE); | |||||
| prop = RNA_def_string( | |||||
| ot->srna, "uv_layer", NULL, RE_MAXNAME, "UV-layer", "UV-layer to use to generate margin"); | |||||
| RNA_def_property_flag(prop, PROP_SKIP_SAVE); | |||||
| } | |||||