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/bmesh/operators')
-rw-r--r--source/blender/bmesh/operators/bmo_utils.c164
1 files changed, 109 insertions, 55 deletions
diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c
index c79eecaf1a0..60a893ab5da 100644
--- a/source/blender/bmesh/operators/bmo_utils.c
+++ b/source/blender/bmesh/operators/bmo_utils.c
@@ -9,12 +9,16 @@
#include "MEM_guardedalloc.h"
+#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
#include "BLI_alloca.h"
#include "BLI_math.h"
+#include "BKE_attribute.h"
#include "BKE_customdata.h"
+#include "BKE_object.h"
#include "bmesh.h"
@@ -553,6 +557,28 @@ void bmo_reverse_uvs_exec(BMesh *bm, BMOperator *op)
/**************************************************************************** *
* Cycle colors for a face
**************************************************************************** */
+static void bmo_get_loop_color_ref(BMesh *bm,
+ int index,
+ int *r_cd_color_offset,
+ int *r_cd_color_type)
+{
+ Mesh me_query;
+
+ BKE_id_attribute_copy_domains_temp(ID_ME, &bm->vdata, NULL, &bm->ldata, NULL, NULL, &me_query.id);
+
+ CustomDataLayer *layer = BKE_id_attribute_from_index(
+ &me_query.id, index, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
+
+ if (!layer || BKE_id_attribute_domain(&me_query.id, layer) != ATTR_DOMAIN_CORNER) {
+ *r_cd_color_offset = -1;
+ return;
+ }
+
+ int layer_i = CustomData_get_layer_index(&bm->ldata, layer->type);
+
+ *r_cd_color_offset = bm->ldata.layers[layer_i].offset;
+ *r_cd_color_type = layer->type;
+}
void bmo_rotate_colors_exec(BMesh *bm, BMOperator *op)
{
@@ -561,57 +587,67 @@ void bmo_rotate_colors_exec(BMesh *bm, BMOperator *op)
BMIter l_iter; /* iteration loop */
const bool use_ccw = BMO_slot_bool_get(op->slots_in, "use_ccw");
- const int cd_loop_color_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPCOL);
- if (cd_loop_color_offset != -1) {
- BMO_ITER (fs, &fs_iter, op->slots_in, "faces", BM_FACE) {
- if (use_ccw == false) { /* same loops direction */
- BMLoop *lf; /* current face loops */
- MLoopCol *f_lcol; /* first face loop color */
- MLoopCol p_col; /* previous color */
- MLoopCol t_col; /* tmp color */
+ const int color_index = BMO_slot_int_get(op->slots_in, "color_index");
- int n = 0;
- BM_ITER_ELEM (lf, &l_iter, fs, BM_LOOPS_OF_FACE) {
- /* current loop color is the previous loop color */
- MLoopCol *lcol = BM_ELEM_CD_GET_VOID_P(lf, cd_loop_color_offset);
- if (n == 0) {
- f_lcol = lcol;
- p_col = *lcol;
- }
- else {
- t_col = *lcol;
- *lcol = p_col;
- p_col = t_col;
- }
- n++;
- }
+ int cd_loop_color_offset;
+ int cd_loop_color_type;
- *f_lcol = p_col;
- }
- else { /* counter loop direction */
- BMLoop *lf; /* current face loops */
- MLoopCol *p_lcol; /* previous loop color */
- MLoopCol *lcol;
- MLoopCol t_col; /* current color */
+ bmo_get_loop_color_ref(bm, color_index, &cd_loop_color_offset, &cd_loop_color_type);
- int n = 0;
- BM_ITER_ELEM (lf, &l_iter, fs, BM_LOOPS_OF_FACE) {
- /* previous loop color is the current loop color */
- lcol = BM_ELEM_CD_GET_VOID_P(lf, cd_loop_color_offset);
- if (n == 0) {
- p_lcol = lcol;
- t_col = *lcol;
- }
- else {
- *p_lcol = *lcol;
- p_lcol = lcol;
- }
- n++;
+ if (cd_loop_color_offset == -1) {
+ BMO_error_raise(bm, op, BMO_ERROR_CANCEL, "color_index is invalid");
+ return;
+ }
+
+ const size_t size = cd_loop_color_type == CD_PROP_COLOR ? sizeof(MPropCol) : sizeof(MLoopCol);
+ void *p_col; /* previous color */
+ void *t_col = alloca(size); /* tmp color */
+
+ BMO_ITER (fs, &fs_iter, op->slots_in, "faces", BM_FACE) {
+ if (use_ccw == false) { /* same loops direction */
+ BMLoop *lf; /* current face loops */
+ void *f_lcol; /* first face loop color */
+
+ int n = 0;
+ BM_ITER_ELEM (lf, &l_iter, fs, BM_LOOPS_OF_FACE) {
+ /* current loop color is the previous loop color */
+ void *lcol = BM_ELEM_CD_GET_VOID_P(lf, cd_loop_color_offset);
+
+ if (n == 0) {
+ f_lcol = lcol;
+ p_col = lcol;
}
+ else {
+ memcpy(t_col, lcol, size);
+ memcpy(lcol, p_col, size);
+ memcpy(p_col, t_col, size);
+ }
+ n++;
+ }
- *lcol = t_col;
+ memcpy(f_lcol, p_col, size);
+ }
+ else { /* counter loop direction */
+ BMLoop *lf; /* current face loops */
+ void *lcol, *p_lcol;
+
+ int n = 0;
+ BM_ITER_ELEM (lf, &l_iter, fs, BM_LOOPS_OF_FACE) {
+ /* previous loop color is the current loop color */
+ lcol = BM_ELEM_CD_GET_VOID_P(lf, cd_loop_color_offset);
+ if (n == 0) {
+ p_lcol = lcol;
+ memcpy(t_col, lcol, size);
+ }
+ else {
+ memcpy(p_lcol, lcol, size);
+ p_lcol = lcol;
+ }
+ n++;
}
+
+ memcpy(lcol, t_col, size);
}
}
}
@@ -619,35 +655,53 @@ void bmo_rotate_colors_exec(BMesh *bm, BMOperator *op)
/*************************************************************************** *
* Reverse colors for a face
*************************************************************************** */
-static void bm_face_reverse_colors(BMFace *f, const int cd_loop_color_offset)
+static void bm_face_reverse_colors(BMFace *f,
+ const int cd_loop_color_offset,
+ const int cd_loop_color_type)
{
BMIter iter;
BMLoop *l;
int i;
- MLoopCol *cols = BLI_array_alloca(cols, f->len);
+ const size_t size = cd_loop_color_type == CD_PROP_COLOR ? sizeof(MPropCol) : sizeof(MLoopCol);
+
+ char *cols = alloca(size * f->len);
+ char *col = cols;
BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) {
- MLoopCol *lcol = BM_ELEM_CD_GET_VOID_P(l, cd_loop_color_offset);
- cols[i] = *lcol;
+ void *lcol = BM_ELEM_CD_GET_VOID_P(l, cd_loop_color_offset);
+ memcpy((void *)col, lcol, size);
+ col += size;
}
/* now that we have the uvs in the array, reverse! */
BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) {
/* current loop uv is the previous loop color */
- MLoopCol *lcol = BM_ELEM_CD_GET_VOID_P(l, cd_loop_color_offset);
- *lcol = cols[(f->len - i - 1)];
+ void *lcol = BM_ELEM_CD_GET_VOID_P(l, cd_loop_color_offset);
+
+ col = cols + (f->len - i - 1) * size;
+ memcpy(lcol, (void *)col, size);
}
}
+
void bmo_reverse_colors_exec(BMesh *bm, BMOperator *op)
{
BMOIter iter;
BMFace *f;
- const int cd_loop_color_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPCOL);
- if (cd_loop_color_offset != -1) {
- BMO_ITER (f, &iter, op->slots_in, "faces", BM_FACE) {
- bm_face_reverse_colors(f, cd_loop_color_offset);
- }
+ const int color_index = BMO_slot_int_get(op->slots_in, "color_index");
+
+ int cd_loop_color_offset;
+ int cd_loop_color_type;
+
+ bmo_get_loop_color_ref(bm, color_index, &cd_loop_color_offset, &cd_loop_color_type);
+
+ if (cd_loop_color_offset == -1) {
+ BMO_error_raise(bm, op, BMO_ERROR_CANCEL, "color_index is invalid");
+ return;
+ }
+
+ BMO_ITER (f, &iter, op->slots_in, "faces", BM_FACE) {
+ bm_face_reverse_colors(f, cd_loop_color_offset, cd_loop_color_type);
}
}