Changeset View
Standalone View
source/blender/editors/mesh/mesh_data.cc
| Show All 30 Lines | |||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| #include "RNA_define.h" | #include "RNA_define.h" | ||||
| #include "RNA_prototypes.h" | #include "RNA_prototypes.h" | ||||
| #include "WM_api.h" | #include "WM_api.h" | ||||
| #include "WM_types.h" | #include "WM_types.h" | ||||
| #include "BLT_translation.h" | |||||
| #include "ED_mesh.h" | #include "ED_mesh.h" | ||||
| #include "ED_object.h" | #include "ED_object.h" | ||||
| #include "ED_paint.h" | #include "ED_paint.h" | ||||
| #include "ED_screen.h" | #include "ED_screen.h" | ||||
| #include "ED_uvedit.h" | #include "ED_uvedit.h" | ||||
| #include "ED_view3d.h" | #include "ED_view3d.h" | ||||
| #include "GEO_mesh_split_edges.hh" | #include "GEO_mesh_split_edges.hh" | ||||
| #include "mesh_intern.h" /* own include */ | #include "mesh_intern.h" /* own include */ | ||||
| using blender::Array; | using blender::Array; | ||||
| using blender::float2; | |||||
| using blender::float3; | using blender::float3; | ||||
| using blender::MutableSpan; | using blender::MutableSpan; | ||||
| using blender::Span; | using blender::Span; | ||||
| static CustomData *mesh_customdata_get_type(Mesh *me, const char htype, int *r_tot) | static CustomData *mesh_customdata_get_type(Mesh *me, const char htype, int *r_tot) | ||||
| { | { | ||||
| CustomData *data; | CustomData *data; | ||||
| BMesh *bm = (me->edit_mesh) ? me->edit_mesh->bm : nullptr; | BMesh *bm = (me->edit_mesh) ? me->edit_mesh->bm : nullptr; | ||||
| ▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | |||||
| #define GET_CD_DATA(me, data) ((me)->edit_mesh ? &(me)->edit_mesh->bm->data : &(me)->data) | #define GET_CD_DATA(me, data) ((me)->edit_mesh ? &(me)->edit_mesh->bm->data : &(me)->data) | ||||
| static void delete_customdata_layer(Mesh *me, CustomDataLayer *layer) | static void delete_customdata_layer(Mesh *me, CustomDataLayer *layer) | ||||
| { | { | ||||
| const int type = layer->type; | const int type = layer->type; | ||||
| CustomData *data; | CustomData *data; | ||||
| int layer_index, tot, n; | int layer_index, tot, n; | ||||
| char htype = BM_FACE; | char htype = BM_FACE; | ||||
| if (ELEM(type, CD_PROP_BYTE_COLOR, CD_MLOOPUV)) { | if (ELEM(type, CD_PROP_BYTE_COLOR, CD_PROP_FLOAT2)) { | ||||
| htype = BM_LOOP; | htype = BM_LOOP; | ||||
| } | } | ||||
| else if (ELEM(type, CD_PROP_COLOR)) { | else if (ELEM(type, CD_PROP_COLOR)) { | ||||
| htype = BM_VERT; | htype = BM_VERT; | ||||
| } | } | ||||
| data = mesh_customdata_get_type(me, htype, &tot); | data = mesh_customdata_get_type(me, htype, &tot); | ||||
| layer_index = CustomData_get_layer_index(data, type); | layer_index = CustomData_get_layer_index(data, type); | ||||
| ▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | |||||
| static void mesh_uv_reset_bmface(BMFace *f, const int cd_loop_uv_offset) | static void mesh_uv_reset_bmface(BMFace *f, const int cd_loop_uv_offset) | ||||
| { | { | ||||
| Array<float *, BM_DEFAULT_NGON_STACK_SIZE> fuv(f->len); | Array<float *, BM_DEFAULT_NGON_STACK_SIZE> fuv(f->len); | ||||
| BMIter liter; | BMIter liter; | ||||
| BMLoop *l; | BMLoop *l; | ||||
| int i; | int i; | ||||
| BM_ITER_ELEM_INDEX (l, &liter, f, BM_LOOPS_OF_FACE, i) { | BM_ITER_ELEM_INDEX (l, &liter, f, BM_LOOPS_OF_FACE, i) { | ||||
| fuv[i] = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset))->uv; | fuv[i] = ((float *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset)); | ||||
| } | } | ||||
| mesh_uv_reset_array(fuv.data(), f->len); | mesh_uv_reset_array(fuv.data(), f->len); | ||||
| } | } | ||||
| static void mesh_uv_reset_mface(const MPoly *mp, MLoopUV *mloopuv) | static void mesh_uv_reset_mface(const MPoly *mp, float2 *mloopuv) | ||||
| { | { | ||||
| Array<float *, BM_DEFAULT_NGON_STACK_SIZE> fuv(mp->totloop); | Array<float *, BM_DEFAULT_NGON_STACK_SIZE> fuv(mp->totloop); | ||||
| for (int i = 0; i < mp->totloop; i++) { | for (int i = 0; i < mp->totloop; i++) { | ||||
| fuv[i] = mloopuv[mp->loopstart + i].uv; | fuv[i] = mloopuv[mp->loopstart + i]; | ||||
| } | } | ||||
| mesh_uv_reset_array(fuv.data(), mp->totloop); | mesh_uv_reset_array(fuv.data(), mp->totloop); | ||||
| } | } | ||||
| void ED_mesh_uv_loop_reset_ex(Mesh *me, const int layernum) | void ED_mesh_uv_loop_reset_ex(Mesh *me, const int layernum) | ||||
| { | { | ||||
| BMEditMesh *em = me->edit_mesh; | BMEditMesh *em = me->edit_mesh; | ||||
| if (em) { | if (em) { | ||||
| /* Collect BMesh UVs */ | /* Collect BMesh UVs */ | ||||
| const int cd_loop_uv_offset = CustomData_get_n_offset(&em->bm->ldata, CD_MLOOPUV, layernum); | const int cd_loop_uv_offset = CustomData_get_n_offset( | ||||
| &em->bm->ldata, CD_PROP_FLOAT2, layernum); | |||||
| BMFace *efa; | BMFace *efa; | ||||
| BMIter iter; | BMIter iter; | ||||
| BLI_assert(cd_loop_uv_offset >= 0); | BLI_assert(cd_loop_uv_offset >= 0); | ||||
| 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; | ||||
| } | } | ||||
| mesh_uv_reset_bmface(efa, cd_loop_uv_offset); | mesh_uv_reset_bmface(efa, cd_loop_uv_offset); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* Collect Mesh UVs */ | /* Collect Mesh UVs */ | ||||
| BLI_assert(CustomData_has_layer(&me->ldata, CD_MLOOPUV)); | BLI_assert(CustomData_has_layer(&me->ldata, CD_PROP_FLOAT2)); | ||||
| MLoopUV *mloopuv = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, layernum); | float2 *mloopuv = static_cast<float2 *>( | ||||
| CustomData_get_layer_n(&me->ldata, CD_PROP_FLOAT2, layernum)); | |||||
| const MPoly *polys = BKE_mesh_polys(me); | const MPoly *polys = BKE_mesh_polys(me); | ||||
| for (int i = 0; i < me->totpoly; i++) { | for (int i = 0; i < me->totpoly; i++) { | ||||
| mesh_uv_reset_mface(&polys[i], mloopuv); | mesh_uv_reset_mface(&polys[i], mloopuv); | ||||
| } | } | ||||
| } | } | ||||
| DEG_id_tag_update(&me->id, 0); | DEG_id_tag_update(&me->id, 0); | ||||
| } | } | ||||
| void ED_mesh_uv_loop_reset(bContext *C, Mesh *me) | void ED_mesh_uv_loop_reset(bContext *C, Mesh *me) | ||||
| { | { | ||||
| /* could be ldata or pdata */ | /* could be ldata or pdata */ | ||||
| CustomData *ldata = GET_CD_DATA(me, ldata); | CustomData *ldata = GET_CD_DATA(me, ldata); | ||||
| const int layernum = CustomData_get_active_layer(ldata, CD_MLOOPUV); | const int layernum = CustomData_get_active_layer(ldata, CD_PROP_FLOAT2); | ||||
| ED_mesh_uv_loop_reset_ex(me, layernum); | ED_mesh_uv_loop_reset_ex(me, layernum); | ||||
| WM_event_add_notifier(C, NC_GEOM | ND_DATA, me); | WM_event_add_notifier(C, NC_GEOM | ND_DATA, me); | ||||
| } | } | ||||
| int ED_mesh_uv_add( | int ED_mesh_uv_add( | ||||
| Mesh *me, const char *name, const bool active_set, const bool do_init, ReportList *reports) | Mesh *me, const char *name, const bool active_set, const bool do_init, ReportList *reports) | ||||
| { | { | ||||
| /* NOTE: keep in sync with #ED_mesh_color_add. */ | /* NOTE: keep in sync with #ED_mesh_color_add. */ | ||||
| BMEditMesh *em; | BMEditMesh *em; | ||||
| int layernum_dst; | int layernum_dst; | ||||
| if (!name) { | |||||
| name = DATA_("UVMap"); | |||||
| } | |||||
| char unique_name[MAX_CUSTOMDATA_LAYER_NAME]; | |||||
| BKE_id_attribute_calc_unique_name(&me->id, name, unique_name); | |||||
| bool is_init = false; | bool is_init = false; | ||||
| if (me->edit_mesh) { | if (me->edit_mesh) { | ||||
| em = me->edit_mesh; | em = me->edit_mesh; | ||||
| layernum_dst = CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPUV); | layernum_dst = CustomData_number_of_layers(&em->bm->ldata, CD_PROP_FLOAT2); | ||||
| if (layernum_dst >= MAX_MTFACE) { | if (layernum_dst >= MAX_MTFACE) { | ||||
| BKE_reportf(reports, RPT_WARNING, "Cannot add more than %i UV maps", MAX_MTFACE); | BKE_reportf(reports, RPT_WARNING, "Cannot add more than %i UV maps", MAX_MTFACE); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| /* CD_MLOOPUV */ | BM_data_layer_add_named(em->bm, &em->bm->ldata, CD_PROP_FLOAT2, unique_name); | ||||
| BM_data_layer_add_named(em->bm, &em->bm->ldata, CD_MLOOPUV, name); | BM_uv_map_ensure_select_and_pin_attrs(em->bm); | ||||
| /* copy data from active UV */ | /* copy data from active UV */ | ||||
| if (layernum_dst && do_init) { | if (layernum_dst && do_init) { | ||||
| const int layernum_src = CustomData_get_active_layer(&em->bm->ldata, CD_MLOOPUV); | const int layernum_src = CustomData_get_active_layer(&em->bm->ldata, CD_PROP_FLOAT2); | ||||
| BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPUV, layernum_src, layernum_dst); | BM_data_layer_copy(em->bm, &em->bm->ldata, CD_PROP_FLOAT2, layernum_src, layernum_dst); | ||||
| is_init = true; | is_init = true; | ||||
| } | } | ||||
| if (active_set || layernum_dst == 0) { | if (active_set || layernum_dst == 0) { | ||||
| CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPUV, layernum_dst); | CustomData_set_layer_active(&em->bm->ldata, CD_PROP_FLOAT2, layernum_dst); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| layernum_dst = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); | layernum_dst = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2); | ||||
| if (layernum_dst >= MAX_MTFACE) { | if (layernum_dst >= MAX_MTFACE) { | ||||
| BKE_reportf(reports, RPT_WARNING, "Cannot add more than %i UV maps", MAX_MTFACE); | BKE_reportf(reports, RPT_WARNING, "Cannot add more than %i UV maps", MAX_MTFACE); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| if (CustomData_has_layer(&me->ldata, CD_MLOOPUV) && do_init) { | if (CustomData_has_layer(&me->ldata, CD_PROP_FLOAT2) && do_init) { | ||||
| CustomData_add_layer_named(&me->ldata, | CustomData_add_layer_named(&me->ldata, | ||||
| CD_MLOOPUV, | CD_PROP_FLOAT2, | ||||
| CD_DUPLICATE, | CD_DUPLICATE, | ||||
| CustomData_get_layer(&me->ldata, CD_MLOOPUV), | CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2), | ||||
| me->totloop, | me->totloop, | ||||
| name); | unique_name); | ||||
| is_init = true; | is_init = true; | ||||
| } | } | ||||
| else { | else { | ||||
| CustomData_add_layer_named( | CustomData_add_layer_named( | ||||
| &me->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, me->totloop, name); | &me->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, nullptr, me->totloop, unique_name); | ||||
| } | } | ||||
| if (active_set || layernum_dst == 0) { | if (active_set || layernum_dst == 0) { | ||||
| CustomData_set_layer_active(&me->ldata, CD_MLOOPUV, layernum_dst); | CustomData_set_layer_active(&me->ldata, CD_PROP_FLOAT2, layernum_dst); | ||||
| } | } | ||||
| } | } | ||||
| /* don't overwrite our copied coords */ | /* don't overwrite our copied coords */ | ||||
| if (!is_init && do_init) { | if (!is_init && do_init) { | ||||
| ED_mesh_uv_loop_reset_ex(me, layernum_dst); | ED_mesh_uv_loop_reset_ex(me, layernum_dst); | ||||
| } | } | ||||
| DEG_id_tag_update(&me->id, 0); | DEG_id_tag_update(&me->id, 0); | ||||
| WM_main_add_notifier(NC_GEOM | ND_DATA, me); | WM_main_add_notifier(NC_GEOM | ND_DATA, me); | ||||
| return layernum_dst; | return layernum_dst; | ||||
| } | } | ||||
| static const bool *mesh_loop_boolean_custom_data_get_by_name(const Mesh &mesh, const char *name) | |||||
campbellbarton: This should use naming consistent with other mesh API's.
On first read it wasn't clear to be… | |||||
| { | |||||
Done Inline ActionsThere doesn't seem to be a good reason to use StringRefNull here (it's converting char * to StringRefNull then using the c_str() method). campbellbarton: There doesn't seem to be a good reason to use `StringRefNull` here (it's converting `char *` to… | |||||
| return static_cast<const bool *>(CustomData_get_layer_named(&mesh.ldata, CD_PROP_BOOL, name)); | |||||
| } | |||||
| const bool *ED_mesh_uv_map_vert_select_layer_get(const Mesh *mesh, const int uv_index) | |||||
| { | |||||
| using namespace blender::bke; | |||||
Done Inline ActionsCapitalized names ED_ are for public editor methods. These can be removed for local (static) functions. campbellbarton: Capitalized names `ED_` are for public editor methods. These can be removed for local (static)… | |||||
Done Inline ActionsThese were meant to be public editor methods. But if that is not wanted I can change them. Baardaap: These were meant to be public editor methods. But if that is not wanted I can change them. | |||||
Done Inline ActionsActually I can't, since these functions are used in mesh_data.cc so they should be public. Baardaap: Actually I can't, since these functions are used in mesh_data.cc so they should be public. | |||||
Done Inline ActionsIn this case they should be moved to ED_mesh API (source/blender/editors/mesh/mesh_data.cc seems appropriate). campbellbarton: In this case they should be moved to ED_mesh API (`source/blender/editors/mesh/mesh_data.cc`… | |||||
Done Inline ActionsBut they are in source/blender/editors/mesh/mesh_data.cc ?? Baardaap: But they are in `source/blender/editors/mesh/mesh_data.cc` ?? | |||||
Done Inline ActionsAh! Was jumping between this an rna_mesh.c & got mixed up, sorry for noise. campbellbarton: Ah! Was jumping between this an `rna_mesh.c` & got mixed up, sorry for noise. | |||||
| char buffer[MAX_CUSTOMDATA_LAYER_NAME]; | |||||
| const char *uv_name = CustomData_get_layer_name(&mesh->ldata, CD_PROP_FLOAT2, uv_index); | |||||
| return mesh_loop_boolean_custom_data_get_by_name( | |||||
| *mesh, BKE_uv_map_vert_select_name_get(uv_name, buffer)); | |||||
| } | |||||
| /* UV map edge selections are stored on face corners (loops) and not on edges | |||||
| * because we need selections per face edge, even when the edge is split in UV space. */ | |||||
| const bool *ED_mesh_uv_map_edge_select_layer_get(const Mesh *mesh, const int uv_index) | |||||
| { | |||||
Done Inline ActionsDo we need to add a comment in here something about "Edge Selection" being a corner attribute for historical reasons, and that it may change in future to be an edge attribute? Or, alternatively, a comment about why "Edge Selection" *cannot* be an edge attribute, with an explanation for why.... chrisbblend: Do we need to add a comment in here something about "Edge Selection" being a corner attribute… | |||||
Done Inline ActionsI think it's for historical reasons indeed.But I'm not really qualified to write such a comment, as I don't really actually know why it is this way... Also it's not something this patch changes compared to master, so Ill just mark it as done for now and pass on. Might be a good idea to revisit later with someone more knowledgeable on the topic. Baardaap: I think it's for historical reasons indeed.But I'm not really qualified to write such a comment… | |||||
Done Inline ActionsI'm pretty sure it's an edge selection stored on corners because you can select split edges in the UV editor even if they actually come from the same edge on the mesh. HooglyBoogly: I'm pretty sure it's an edge selection stored on corners because you can select split edges in… | |||||
Done Inline ActionsTrue! These are 'face edges' not 'mesh edges'. Still wouldn't hurt to document it maybe. I'll have a go a adding a comment. Baardaap: True! These are 'face edges' not 'mesh edges'.
Still wouldn't hurt to document it maybe. I'll… | |||||
| using namespace blender::bke; | |||||
| char buffer[MAX_CUSTOMDATA_LAYER_NAME]; | |||||
| const char *uv_name = CustomData_get_layer_name(&mesh->ldata, CD_PROP_FLOAT2, uv_index); | |||||
| return mesh_loop_boolean_custom_data_get_by_name( | |||||
| *mesh, BKE_uv_map_edge_select_name_get(uv_name, buffer)); | |||||
| } | |||||
| const bool *ED_mesh_uv_map_pin_layer_get(const Mesh *mesh, const int uv_index) | |||||
| { | |||||
| using namespace blender::bke; | |||||
| char buffer[MAX_CUSTOMDATA_LAYER_NAME]; | |||||
| const char *uv_name = CustomData_get_layer_name(&mesh->ldata, CD_PROP_FLOAT2, uv_index); | |||||
| return mesh_loop_boolean_custom_data_get_by_name(*mesh, | |||||
| BKE_uv_map_pin_name_get(uv_name, buffer)); | |||||
| } | |||||
| static bool *ensure_corner_boolean_attribute(Mesh &mesh, const blender::StringRefNull name) | |||||
| { | |||||
| bool *data = static_cast<bool *>(CustomData_duplicate_referenced_layer_named( | |||||
| &mesh.ldata, CD_PROP_BOOL, name.c_str(), mesh.totloop)); | |||||
| if (!data) { | |||||
| data = static_cast<bool *>(CustomData_add_layer_named( | |||||
| &mesh.ldata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, mesh.totpoly, name.c_str())); | |||||
| } | |||||
| return data; | |||||
| } | |||||
| bool *ED_mesh_uv_map_vert_select_layer_ensure(Mesh *mesh, const int uv_index) | |||||
| { | |||||
| using namespace blender::bke; | |||||
| char buffer[MAX_CUSTOMDATA_LAYER_NAME]; | |||||
| const char *uv_name = CustomData_get_layer_name(&mesh->ldata, CD_PROP_FLOAT2, uv_index); | |||||
| return ensure_corner_boolean_attribute(*mesh, BKE_uv_map_vert_select_name_get(uv_name, buffer)); | |||||
| } | |||||
| bool *ED_mesh_uv_map_edge_select_layer_ensure(Mesh *mesh, const int uv_index) | |||||
| { | |||||
| using namespace blender::bke; | |||||
| char buffer[MAX_CUSTOMDATA_LAYER_NAME]; | |||||
| const char *uv_name = CustomData_get_layer_name(&mesh->ldata, CD_PROP_FLOAT2, uv_index); | |||||
| return ensure_corner_boolean_attribute(*mesh, BKE_uv_map_edge_select_name_get(uv_name, buffer)); | |||||
| } | |||||
| bool *ED_mesh_uv_map_pin_layer_ensure(Mesh *mesh, const int uv_index) | |||||
| { | |||||
| using namespace blender::bke; | |||||
| char buffer[MAX_CUSTOMDATA_LAYER_NAME]; | |||||
| const char *uv_name = CustomData_get_layer_name(&mesh->ldata, CD_PROP_FLOAT2, uv_index); | |||||
| return ensure_corner_boolean_attribute(*mesh, BKE_uv_map_pin_name_get(uv_name, buffer)); | |||||
| } | |||||
| void ED_mesh_uv_ensure(Mesh *me, const char *name) | void ED_mesh_uv_ensure(Mesh *me, const char *name) | ||||
| { | { | ||||
| BMEditMesh *em; | BMEditMesh *em; | ||||
| int layernum_dst; | int layernum_dst; | ||||
| if (me->edit_mesh) { | if (me->edit_mesh) { | ||||
| em = me->edit_mesh; | em = me->edit_mesh; | ||||
| layernum_dst = CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPUV); | layernum_dst = CustomData_number_of_layers(&em->bm->ldata, CD_PROP_FLOAT2); | ||||
| if (layernum_dst == 0) { | if (layernum_dst == 0) { | ||||
| ED_mesh_uv_add(me, name, true, true, nullptr); | ED_mesh_uv_add(me, name, true, true, nullptr); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| layernum_dst = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); | layernum_dst = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2); | ||||
| if (layernum_dst == 0) { | if (layernum_dst == 0) { | ||||
| ED_mesh_uv_add(me, name, true, true, nullptr); | ED_mesh_uv_add(me, name, true, true, nullptr); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| bool ED_mesh_uv_remove_index(Mesh *me, const int n) | bool ED_mesh_uv_remove_index(Mesh *me, const int n) | ||||
| { | { | ||||
| CustomData *ldata = GET_CD_DATA(me, ldata); | CustomData *ldata = GET_CD_DATA(me, ldata); | ||||
| CustomDataLayer *cdlu; | CustomDataLayer *cdlu; | ||||
| int index; | int index; | ||||
| index = CustomData_get_layer_index_n(ldata, CD_MLOOPUV, n); | index = CustomData_get_layer_index_n(ldata, CD_PROP_FLOAT2, n); | ||||
| cdlu = (index == -1) ? nullptr : &ldata->layers[index]; | cdlu = (index == -1) ? nullptr : &ldata->layers[index]; | ||||
| if (!cdlu) { | if (!cdlu) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| delete_customdata_layer(me, cdlu); | delete_customdata_layer(me, cdlu); | ||||
| DEG_id_tag_update(&me->id, 0); | DEG_id_tag_update(&me->id, 0); | ||||
| WM_main_add_notifier(NC_GEOM | ND_DATA, me); | WM_main_add_notifier(NC_GEOM | ND_DATA, me); | ||||
| return true; | return true; | ||||
| } | } | ||||
| bool ED_mesh_uv_remove_active(Mesh *me) | bool ED_mesh_uv_remove_active(Mesh *me) | ||||
| { | { | ||||
| CustomData *ldata = GET_CD_DATA(me, ldata); | CustomData *ldata = GET_CD_DATA(me, ldata); | ||||
| const int n = CustomData_get_active_layer(ldata, CD_MLOOPUV); | const int n = CustomData_get_active_layer(ldata, CD_PROP_FLOAT2); | ||||
| if (n != -1) { | if (n != -1) { | ||||
| return ED_mesh_uv_remove_index(me, n); | return ED_mesh_uv_remove_index(me, n); | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| bool ED_mesh_uv_remove_named(Mesh *me, const char *name) | bool ED_mesh_uv_remove_named(Mesh *me, const char *name) | ||||
| { | { | ||||
| CustomData *ldata = GET_CD_DATA(me, ldata); | CustomData *ldata = GET_CD_DATA(me, ldata); | ||||
| const int n = CustomData_get_named_layer(ldata, CD_MLOOPUV, name); | const int n = CustomData_get_named_layer(ldata, CD_PROP_FLOAT2, name); | ||||
| if (n != -1) { | if (n != -1) { | ||||
| return ED_mesh_uv_remove_index(me, n); | return ED_mesh_uv_remove_index(me, n); | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| int ED_mesh_color_add( | int ED_mesh_color_add( | ||||
| Mesh *me, const char *name, const bool active_set, const bool do_init, ReportList *reports) | Mesh *me, const char *name, const bool active_set, const bool do_init, ReportList *reports) | ||||
| ▲ Show 20 Lines • Show All 120 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| if (!layers_poll(C)) { | if (!layers_poll(C)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| Object *ob = ED_object_context(C); | Object *ob = ED_object_context(C); | ||||
| Mesh *me = static_cast<Mesh *>(ob->data); | Mesh *me = static_cast<Mesh *>(ob->data); | ||||
| CustomData *ldata = GET_CD_DATA(me, ldata); | CustomData *ldata = GET_CD_DATA(me, ldata); | ||||
| const int active = CustomData_get_active_layer(ldata, CD_MLOOPUV); | const int active = CustomData_get_active_layer(ldata, CD_PROP_FLOAT2); | ||||
| if (active != -1) { | if (active != -1) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| static int mesh_uv_texture_add_exec(bContext *C, wmOperator *op) | static int mesh_uv_texture_add_exec(bContext *C, wmOperator *op) | ||||
| Show All 24 Lines | void MESH_OT_uv_texture_add(wmOperatorType *ot) | ||||
| /* api callbacks */ | /* api callbacks */ | ||||
| ot->poll = layers_poll; | ot->poll = layers_poll; | ||||
| ot->exec = mesh_uv_texture_add_exec; | ot->exec = mesh_uv_texture_add_exec; | ||||
| /* flags */ | /* flags */ | ||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ||||
| } | } | ||||
| static int mesh_uv_texture_remove_exec(bContext *C, wmOperator * /*op*/) | static int mesh_uv_texture_remove_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Object *ob = ED_object_context(C); | Object *ob = ED_object_context(C); | ||||
| Mesh *me = static_cast<Mesh *>(ob->data); | Mesh *me = static_cast<Mesh *>(ob->data); | ||||
| if (!ED_mesh_uv_remove_active(me)) { | CustomData *ldata = GET_CD_DATA(me, ldata); | ||||
| const char *name = CustomData_get_active_layer_name(ldata, CD_PROP_FLOAT2); | |||||
| if (!BKE_id_attribute_remove(&me->id, name, op->reports)) { | |||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| if (ob->mode & OB_MODE_TEXTURE_PAINT) { | if (ob->mode & OB_MODE_TEXTURE_PAINT) { | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| ED_paint_proj_mesh_data_check(scene, ob, nullptr, nullptr, nullptr, nullptr); | ED_paint_proj_mesh_data_check(scene, ob, nullptr, nullptr, nullptr, nullptr); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, nullptr); | WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, nullptr); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 926 Lines • Show Last 20 Lines | |||||
This should use naming consistent with other mesh API's.
On first read it wasn't clear to be what it did.
e.g. mesh_loop_boolean_custom_data_get_by_name(..).