This commit is contained in:
Hans Goudey 2022-08-15 11:08:07 -04:00
parent c4dc870a45
commit 780d67a133
11 changed files with 252 additions and 90 deletions

View File

@ -2346,7 +2346,13 @@ bool CustomData_merge(const CustomData *source,
static bool attribute_stored_in_bmesh_flag(const StringRef name)
{
return ELEM(name, ".hide_vert", ".hide_edge", ".hide_poly");
return ELEM(name,
".hide_vert",
".hide_edge",
".hide_poly",
".selection_vert",
".selection_edge",
".selection_poly");
}
static CustomData shallow_copy_remove_non_bmesh_attributes(const CustomData &src)

View File

@ -1708,6 +1708,8 @@ void BKE_mesh_mselect_clear(Mesh *me)
void BKE_mesh_mselect_validate(Mesh *me)
{
using namespace blender;
using namespace blender::bke;
MSelect *mselect_src, *mselect_dst;
int i_src, i_dst;
@ -1719,25 +1721,33 @@ void BKE_mesh_mselect_validate(Mesh *me)
mselect_dst = (MSelect *)MEM_malloc_arrayN(
(me->totselect), sizeof(MSelect), "Mesh selection history");
const AttributeAccessor attributes = mesh_attributes(*me);
const VArray<bool> selection_vert = attributes.lookup_or_default<bool>(
".selection_vert", ATTR_DOMAIN_POINT, false);
const VArray<bool> selection_edge = attributes.lookup_or_default<bool>(
".selection_edge", ATTR_DOMAIN_EDGE, false);
const VArray<bool> selection_poly = attributes.lookup_or_default<bool>(
".selection_poly", ATTR_DOMAIN_FACE, false);
for (i_src = 0, i_dst = 0; i_src < me->totselect; i_src++) {
int index = mselect_src[i_src].index;
switch (mselect_src[i_src].type) {
case ME_VSEL: {
if (me->mvert[index].flag & SELECT) {
if (selection_vert[index]) {
mselect_dst[i_dst] = mselect_src[i_src];
i_dst++;
}
break;
}
case ME_ESEL: {
if (me->medge[index].flag & SELECT) {
if (selection_edge[index]) {
mselect_dst[i_dst] = mselect_src[i_src];
i_dst++;
}
break;
}
case ME_FSEL: {
if (me->mpoly[index].flag & SELECT) {
if (selection_poly[index]) {
mselect_dst[i_dst] = mselect_src[i_src];
i_dst++;
}

View File

@ -13,6 +13,7 @@
#include "BLI_threads.h"
#include "BLI_timeit.hh"
#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
@ -117,9 +118,10 @@ static void add_polygon_edges_to_hash_maps(Mesh *mesh,
});
}
static void serialize_and_initialize_deduplicated_edges(MutableSpan<EdgeMap> edge_maps,
static void serialize_and_initialize_deduplicated_edges(Mesh &mesh,
MutableSpan<EdgeMap> edge_maps,
MutableSpan<MEdge> new_edges,
short new_edge_flag)
const bool select_new_edges)
{
/* All edges are distributed in the hash tables now. They have to be serialized into a single
* array below. To be able to parallelize this, we have to compute edge index offsets for each
@ -145,12 +147,29 @@ static void serialize_and_initialize_deduplicated_edges(MutableSpan<EdgeMap> edg
/* Initialize new edge. */
new_edge.v1 = item.key.v_low;
new_edge.v2 = item.key.v_high;
new_edge.flag = new_edge_flag;
new_edge.flag = (ME_EDGEDRAW | ME_EDGERENDER);
}
item.value.index = new_edge_index;
new_edge_index++;
}
});
if (select_new_edges) {
SpanAttributeWriter<bool> selection_edge =
mesh_attributes_for_write(mesh).lookup_or_add_for_write_span<bool>(".selection_edge",
ATTR_DOMAIN_EDGE);
threading::parallel_for_each(edge_maps, [&](EdgeMap &edge_map) {
const int task_index = &edge_map - edge_maps.data();
int new_edge_index = edge_index_offsets[task_index];
for (EdgeMap::MutableItem item : edge_map.items()) {
if (item.value.original_edge == nullptr) {
selection_edge.span[new_edge_index] = true;
}
new_edge_index++;
}
});
selection_edge.finish();
}
}
static void update_edge_indices_in_poly_loops(Mesh *mesh,
@ -233,8 +252,8 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select
/* Create new edges. */
MutableSpan<MEdge> new_edges{
static_cast<MEdge *>(MEM_calloc_arrayN(new_totedge, sizeof(MEdge), __func__)), new_totedge};
const short new_edge_flag = (ME_EDGEDRAW | ME_EDGERENDER) | (select_new_edges ? SELECT : 0);
calc_edges::serialize_and_initialize_deduplicated_edges(edge_maps, new_edges, new_edge_flag);
calc_edges::serialize_and_initialize_deduplicated_edges(
*mesh, edge_maps, new_edges, select_new_edges);
calc_edges::update_edge_indices_in_poly_loops(mesh, edge_maps, parallel_mask);
/* Free old CustomData and assign new one. */

View File

@ -21,8 +21,6 @@
#include "bmesh.h"
#include "intern/bmesh_private.h"
#define SELECT 1
bool BM_verts_from_edges(BMVert **vert_arr, BMEdge **edge_arr, const int len)
{
int i, i_prev = len - 1;
@ -720,35 +718,22 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
return bm_new;
}
char BM_vert_flag_from_mflag(const char mflag)
{
return ((mflag & SELECT) ? BM_ELEM_SELECT : 0);
}
char BM_edge_flag_from_mflag(const short mflag)
{
return (((mflag & SELECT) ? BM_ELEM_SELECT : 0) | ((mflag & ME_SEAM) ? BM_ELEM_SEAM : 0) |
return ((((mflag & ME_SEAM) ? BM_ELEM_SEAM : 0) |
((mflag & ME_EDGEDRAW) ? BM_ELEM_DRAW : 0) |
((mflag & ME_SHARP) == 0 ? BM_ELEM_SMOOTH : 0));
}
char BM_face_flag_from_mflag(const char mflag)
{
return (((mflag & ME_FACE_SEL) ? BM_ELEM_SELECT : 0) |
((mflag & ME_SMOOTH) ? BM_ELEM_SMOOTH : 0));
}
char BM_vert_flag_to_mflag(BMVert *v)
{
const char hflag = v->head.hflag;
return (((hflag & BM_ELEM_SELECT) ? SELECT : 0));
return ((mflag & ME_SMOOTH) ? BM_ELEM_SMOOTH : 0);
}
short BM_edge_flag_to_mflag(BMEdge *e)
{
const char hflag = e->head.hflag;
return (((hflag & BM_ELEM_SELECT) ? SELECT : 0) | ((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) |
((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0) |
return (((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) | ((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0) |
((hflag & BM_ELEM_SMOOTH) == 0 ? ME_SHARP : 0) |
(BM_edge_is_wire(e) ? ME_LOOSEEDGE : 0) | /* not typical */
ME_EDGERENDER);
@ -757,6 +742,5 @@ char BM_face_flag_to_mflag(BMFace *f)
{
const char hflag = f->head.hflag;
return (((hflag & BM_ELEM_SELECT) ? ME_FACE_SEL : 0) |
((hflag & BM_ELEM_SMOOTH) ? ME_SMOOTH : 0));
return ((hflag & BM_ELEM_SMOOTH) ? ME_SMOOTH : 0);
}

View File

@ -169,8 +169,5 @@ BMesh *BM_mesh_copy(BMesh *bm_old);
char BM_face_flag_from_mflag(char mflag);
char BM_edge_flag_from_mflag(short mflag);
/* ME -> BM */
char BM_vert_flag_from_mflag(char mflag);
char BM_face_flag_to_mflag(BMFace *f);
short BM_edge_flag_to_mflag(BMEdge *e);
/* BM -> ME */
char BM_vert_flag_to_mflag(BMVert *v);

View File

@ -364,6 +364,13 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
const bool *hide_poly = (const bool *)CustomData_get_layer_named(
&me->pdata, CD_PROP_BOOL, ".hide_poly");
const bool *selection_vert = (const bool *)CustomData_get_layer_named(
&me->vdata, CD_PROP_BOOL, ".selection_vert");
const bool *selection_edge = (const bool *)CustomData_get_layer_named(
&me->edata, CD_PROP_BOOL, ".selection_edge");
const bool *selection_poly = (const bool *)CustomData_get_layer_named(
&me->pdata, CD_PROP_BOOL, ".selection_poly");
Span<MVert> mvert{me->mvert, me->totvert};
Array<BMVert *> vtable(me->totvert);
for (const int i : mvert.index_range()) {
@ -371,14 +378,10 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
bm, keyco ? keyco[i] : mvert[i].co, nullptr, BM_CREATE_SKIP_CD);
BM_elem_index_set(v, i); /* set_ok */
/* Transfer flag. */
v->head.hflag = BM_vert_flag_from_mflag(mvert[i].flag & ~SELECT);
if (hide_vert && hide_vert[i]) {
BM_elem_flag_enable(v, BM_ELEM_HIDDEN);
}
/* This is necessary for selection counts to work properly. */
if (mvert[i].flag & SELECT) {
if (selection_vert && selection_vert[i]) {
BM_vert_select_set(bm, v, true);
}
@ -418,13 +421,11 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
BM_elem_index_set(e, i); /* set_ok */
/* Transfer flags. */
e->head.hflag = BM_edge_flag_from_mflag(medge[i].flag & ~SELECT);
e->head.hflag = BM_edge_flag_from_mflag(medge[i].flag);
if (hide_edge && hide_edge[i]) {
BM_elem_flag_enable(e, BM_ELEM_HIDDEN);
}
/* This is necessary for selection counts to work properly. */
if (medge[i].flag & SELECT) {
if (selection_edge && selection_edge[i]) {
BM_edge_select_set(bm, e, true);
}
@ -474,13 +475,11 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
BM_elem_index_set(f, bm->totface - 1); /* set_ok */
/* Transfer flag. */
f->head.hflag = BM_face_flag_from_mflag(mpoly[i].flag & ~ME_FACE_SEL);
f->head.hflag = BM_face_flag_from_mflag(mpoly[i].flag);
if (hide_poly && hide_poly[i]) {
BM_elem_flag_enable(f, BM_ELEM_HIDDEN);
}
/* This is necessary for selection counts to work properly. */
if (mpoly[i].flag & ME_FACE_SEL) {
if (selection_poly && selection_poly[i]) {
BM_face_select_set(bm, f, true);
}
@ -924,27 +923,20 @@ BLI_INLINE void bmesh_quick_edgedraw_flag(MEdge *med, BMEdge *e)
}
template<typename GetFn>
static void write_elem_flag_to_attribute(blender::bke::MutableAttributeAccessor &attributes,
static void write_elem_flag_to_attribute(blender::bke::MutableAttributeAccessor attributes,
const StringRef attribute_name,
const eAttrDomain domain,
const bool do_write,
const GetFn &get_fn)
{
using namespace blender;
if (do_write) {
bke::SpanAttributeWriter<bool> attribute = attributes.lookup_or_add_for_write_only_span<bool>(
attribute_name, domain);
threading::parallel_for(attribute.span.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
attribute.span[i] = get_fn(i);
}
});
attribute.finish();
}
else {
/* To avoid overhead, remove the hide attribute if possible. */
attributes.remove(attribute_name);
}
bke::SpanAttributeWriter<bool> attribute = attributes.lookup_or_add_for_write_only_span<bool>(
attribute_name, domain);
threading::parallel_for(attribute.span.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
attribute.span[i] = get_fn(i);
}
});
attribute.finish();
}
static void convert_bmesh_hide_flags_to_mesh_attributes(BMesh &bm,
@ -966,18 +958,66 @@ static void convert_bmesh_hide_flags_to_mesh_attributes(BMesh &bm,
bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(mesh);
BM_mesh_elem_table_ensure(&bm, BM_VERT | BM_EDGE | BM_FACE);
write_elem_flag_to_attribute(
attributes, ".hide_vert", ATTR_DOMAIN_POINT, need_hide_vert, [&](const int i) {
return BM_elem_flag_test(BM_vert_at_index(&bm, i), BM_ELEM_HIDDEN);
});
write_elem_flag_to_attribute(
attributes, ".hide_edge", ATTR_DOMAIN_EDGE, need_hide_edge, [&](const int i) {
return BM_elem_flag_test(BM_edge_at_index(&bm, i), BM_ELEM_HIDDEN);
});
write_elem_flag_to_attribute(
attributes, ".hide_poly", ATTR_DOMAIN_FACE, need_hide_poly, [&](const int i) {
return BM_elem_flag_test(BM_face_at_index(&bm, i), BM_ELEM_HIDDEN);
});
if (need_hide_vert) {
BM_mesh_elem_table_ensure(&bm, BM_VERT);
write_elem_flag_to_attribute(attributes, ".hide_vert", ATTR_DOMAIN_POINT, [&](const int i) {
return BM_elem_flag_test(BM_vert_at_index(&bm, i), BM_ELEM_HIDDEN);
});
}
if (need_hide_edge) {
BM_mesh_elem_table_ensure(&bm, BM_EDGE);
write_elem_flag_to_attribute(attributes, ".hide_edge", ATTR_DOMAIN_EDGE, [&](const int i) {
return BM_elem_flag_test(BM_edge_at_index(&bm, i), BM_ELEM_HIDDEN);
});
}
if (need_hide_poly) {
BM_mesh_elem_table_ensure(&bm, BM_FACE);
write_elem_flag_to_attribute(attributes, ".hide_poly", ATTR_DOMAIN_FACE, [&](const int i) {
return BM_elem_flag_test(BM_face_at_index(&bm, i), BM_ELEM_HIDDEN);
});
}
}
static void convert_bmesh_selection_flags_to_mesh_attributes(BMesh &bm,
const bool need_selection_vert,
const bool need_selection_edge,
const bool need_selection_poly,
Mesh &mesh)
{
using namespace blender;
/* The "selection" attributes are stored as flags on #BMesh. */
BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_BOOL, ".selection_vert") == nullptr);
BLI_assert(CustomData_get_layer_named(&bm.edata, CD_PROP_BOOL, ".selection_edge") == nullptr);
BLI_assert(CustomData_get_layer_named(&bm.pdata, CD_PROP_BOOL, ".selection_poly") == nullptr);
if (!(need_selection_vert || need_selection_edge || need_selection_poly)) {
return;
}
bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(mesh);
BM_mesh_elem_table_ensure(&bm, BM_VERT | BM_EDGE | BM_FACE);
if (need_selection_vert) {
BM_mesh_elem_table_ensure(&bm, BM_VERT);
write_elem_flag_to_attribute(
attributes, ".selection_vert", ATTR_DOMAIN_POINT, [&](const int i) {
return BM_elem_flag_test(BM_vert_at_index(&bm, i), BM_ELEM_SELECT);
});
}
if (need_selection_edge) {
BM_mesh_elem_table_ensure(&bm, BM_EDGE);
write_elem_flag_to_attribute(
attributes, ".selection_edge", ATTR_DOMAIN_EDGE, [&](const int i) {
return BM_elem_flag_test(BM_edge_at_index(&bm, i), BM_ELEM_SELECT);
});
}
if (need_selection_poly) {
BM_mesh_elem_table_ensure(&bm, BM_FACE);
write_elem_flag_to_attribute(
attributes, ".selection_poly", ATTR_DOMAIN_FACE, [&](const int i) {
return BM_elem_flag_test(BM_face_at_index(&bm, i), BM_ELEM_SELECT);
});
}
}
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params)
@ -1039,6 +1079,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
bool need_hide_vert = false;
bool need_hide_edge = false;
bool need_hide_poly = false;
bool need_selection_vert = false;
bool need_selection_edge = false;
bool need_selection_poly = false;
/* Clear normals on the mesh completely, since the original vertex and polygon count might be
* different than the BMesh's. */
@ -1053,10 +1096,12 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
copy_v3_v3(mvert->co, v->co);
mvert->flag = BM_vert_flag_to_mflag(v);
if (BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
need_hide_vert = true;
}
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
need_selection_vert = true;
}
BM_elem_index_set(v, i); /* set_inline */
@ -1084,6 +1129,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
if (BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
need_hide_edge = true;
}
if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
need_selection_edge = true;
}
BM_elem_index_set(e, i); /* set_inline */
@ -1116,6 +1164,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
need_hide_poly = true;
}
if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
need_selection_poly = true;
}
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
@ -1210,6 +1261,8 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
convert_bmesh_hide_flags_to_mesh_attributes(
*bm, need_hide_vert, need_hide_edge, need_hide_poly, *me);
convert_bmesh_selection_flags_to_mesh_attributes(
*bm, need_selection_vert, need_selection_edge, need_selection_poly, *me);
BKE_mesh_update_customdata_pointers(me, false);
@ -1307,6 +1360,9 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
bool need_hide_vert = false;
bool need_hide_edge = false;
bool need_hide_poly = false;
bool need_selection_vert = false;
bool need_selection_edge = false;
bool need_selection_poly = false;
/* Clear normals on the mesh completely, since the original vertex and polygon count might be
* different than the BMesh's. */
@ -1321,10 +1377,12 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
BM_elem_index_set(eve, i); /* set_inline */
mv->flag = BM_vert_flag_to_mflag(eve);
if (BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
need_hide_vert = true;
}
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
need_selection_vert = true;
}
if (cd_vert_bweight_offset != -1) {
mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset);
@ -1350,6 +1408,9 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
if (BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
need_hide_edge = true;
}
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
need_selection_edge = true;
}
/* Handle this differently to editmode switching,
* only enable draw for single user edges rather than calculating angle. */
@ -1383,6 +1444,9 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
need_hide_poly = true;
}
if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
need_selection_poly = true;
}
mp->loopstart = j;
mp->mat_nr = efa->mat_nr;
@ -1405,6 +1469,8 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
convert_bmesh_hide_flags_to_mesh_attributes(
*bm, need_hide_vert, need_hide_edge, need_hide_poly, *me);
convert_bmesh_selection_flags_to_mesh_attributes(
*bm, need_selection_vert, need_selection_edge, need_selection_poly, *me);
me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
}

View File

@ -677,7 +677,7 @@ static void draw_subdiv_cache_extra_coarse_face_data_mesh(const MeshRenderData *
if ((mesh->mpoly[i].flag & ME_SMOOTH) != 0) {
flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH;
}
if ((mesh->mpoly[i].flag & ME_FACE_SEL) != 0) {
if (mr->selection_poly && mr->selection_poly[i]) {
flag |= SUBDIV_COARSE_FACE_FLAG_SELECT;
}
if (mr->hide_poly && mr->hide_poly[i]) {

View File

@ -105,7 +105,7 @@ static void extract_pos_nor_iter_poly_mesh(const MeshRenderData *mr,
(mr->v_origindex[ml->v] == ORIGINDEX_NONE))) {
vert->nor.w = -1;
}
else if (mv->flag & SELECT) {
else if (mr->selection_vert && mr->selection_vert[ml->v]) {
vert->nor.w = 1;
}
else {
@ -453,7 +453,7 @@ static void extract_pos_nor_hq_iter_poly_mesh(const MeshRenderData *mr,
(mr->v_origindex[ml->v] == ORIGINDEX_NONE))) {
vert->nor[3] = -1;
}
else if (mv->flag & SELECT) {
else if (mr->selection_vert && mr->selection_vert[ml->v]) {
vert->nor[3] = 1;
}
else {

View File

@ -414,6 +414,7 @@ typedef struct ProjPaintState {
const float (*vert_normals)[3];
const MEdge *medge_eval;
const MPoly *mpoly_eval;
const bool *selection_poly_eval;
const MLoop *mloop_eval;
const MLoopTri *mlooptri_eval;
@ -4060,6 +4061,8 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p
}
ps->mloop_eval = ps->me_eval->mloop;
ps->mpoly_eval = ps->me_eval->mpoly;
ps->selection_poly_eval = (const bool *)CustomData_get_layer_named(
&ps->me_eval->pdata, CD_PROP_BOOL, ".selection_poly");
ps->totvert_eval = ps->me_eval->totvert;
ps->totedge_eval = ps->me_eval->totedge;
@ -4142,6 +4145,7 @@ static bool project_paint_clone_face_skip(ProjPaintState *ps,
typedef struct {
const MPoly *mpoly_orig;
const bool *selection_poly_orig;
const int *index_mp_to_orig;
} ProjPaintFaceLookup;
@ -4150,8 +4154,11 @@ static void proj_paint_face_lookup_init(const ProjPaintState *ps, ProjPaintFaceL
{
memset(face_lookup, 0, sizeof(*face_lookup));
if (ps->do_face_sel) {
Mesh *orig_mesh = (Mesh *)ps->ob->data;
face_lookup->index_mp_to_orig = CustomData_get_layer(&ps->me_eval->pdata, CD_ORIGINDEX);
face_lookup->mpoly_orig = ((Mesh *)ps->ob->data)->mpoly;
face_lookup->mpoly_orig = orig_mesh->mpoly;
face_lookup->selection_poly_orig = CustomData_get_layer_named(
&orig_mesh->pdata, CD_PROP_BOOL, ".selection_poly");
}
}
@ -4162,17 +4169,12 @@ static bool project_paint_check_face_sel(const ProjPaintState *ps,
{
if (ps->do_face_sel) {
int orig_index;
const MPoly *mp;
if ((face_lookup->index_mp_to_orig != NULL) &&
(((orig_index = (face_lookup->index_mp_to_orig[lt->poly]))) != ORIGINDEX_NONE)) {
mp = &face_lookup->mpoly_orig[orig_index];
return face_lookup->selection_poly_orig && face_lookup->selection_poly_orig[orig_index];
}
else {
mp = &ps->mpoly_eval[lt->poly];
}
return ((mp->flag & ME_FACE_SEL) != 0);
return ps->selection_poly_eval && ps->selection_poly_eval[lt->poly];
}
return true;
}

View File

@ -560,7 +560,7 @@ void MeshImporter::mesh_add_edges(Mesh *mesh, int len)
/* set default flags */
medge = &mesh->medge[mesh->totedge];
for (int i = 0; i < len; i++, medge++) {
medge->flag = ME_EDGEDRAW | ME_EDGERENDER | SELECT;
medge->flag = ME_EDGEDRAW | ME_EDGERENDER;
}
mesh->totedge = totedge;

View File

@ -428,6 +428,32 @@ static void rna_MeshVertex_hide_set(PointerRNA *ptr, bool value)
hide_vert[index] = value;
}
static bool rna_MeshVertex_select_get(PointerRNA *ptr)
{
const Mesh *mesh = rna_mesh(ptr);
const bool *selection_vert = (const bool *)CustomData_get_layer_named(
&mesh->vdata, CD_PROP_BOOL, ".selection_vert");
const int index = rna_MeshVertex_index_get(ptr);
return selection_vert == NULL ? false : selection_vert[index];
}
static void rna_MeshVertex_select_set(PointerRNA *ptr, bool value)
{
Mesh *mesh = rna_mesh(ptr);
bool *selection_vert = (bool *)CustomData_duplicate_referenced_layer_named(
&mesh->vdata, CD_PROP_BOOL, ".selection_vert", mesh->totvert);
if (!selection_vert) {
if (!value) {
/* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */
return;
}
selection_vert = (bool *)CustomData_add_layer_named(
&mesh->vdata, CD_PROP_BOOL, CD_CALLOC, NULL, mesh->totvert, ".selection_vert");
}
const int index = rna_MeshVertex_index_get(ptr);
selection_vert[index] = value;
}
static float rna_MeshVertex_bevel_weight_get(PointerRNA *ptr)
{
MVert *mvert = (MVert *)ptr->data;
@ -562,6 +588,32 @@ static void rna_MeshPolygon_hide_set(PointerRNA *ptr, bool value)
hide_poly[index] = value;
}
static bool rna_MeshPolygon_select_get(PointerRNA *ptr)
{
const Mesh *mesh = rna_mesh(ptr);
const bool *selection_poly = (const bool *)CustomData_get_layer_named(
&mesh->pdata, CD_PROP_BOOL, ".selection_poly");
const int index = rna_MeshPolygon_index_get(ptr);
return selection_poly == NULL ? false : selection_poly[index];
}
static void rna_MeshPolygon_select_set(PointerRNA *ptr, bool value)
{
Mesh *mesh = rna_mesh(ptr);
bool *selection_poly = (bool *)CustomData_duplicate_referenced_layer_named(
&mesh->pdata, CD_PROP_BOOL, ".selection_poly", mesh->totpoly);
if (!selection_poly) {
if (!value) {
/* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */
return;
}
selection_poly = (bool *)CustomData_add_layer_named(
&mesh->pdata, CD_PROP_BOOL, CD_CALLOC, NULL, mesh->totpoly, ".selection_poly");
}
const int index = rna_MeshPolygon_index_get(ptr);
selection_poly[index] = value;
}
static void rna_MeshPolygon_center_get(PointerRNA *ptr, float *values)
{
Mesh *me = rna_mesh(ptr);
@ -1298,6 +1350,32 @@ static void rna_MeshEdge_hide_set(PointerRNA *ptr, bool value)
hide_edge[index] = value;
}
static bool rna_MeshEdge_select_get(PointerRNA *ptr)
{
const Mesh *mesh = rna_mesh(ptr);
const bool *selection_edge = (const bool *)CustomData_get_layer_named(
&mesh->edata, CD_PROP_BOOL, ".selection_edge");
const int index = rna_MeshEdge_index_get(ptr);
return selection_edge == NULL ? false : selection_edge[index];
}
static void rna_MeshEdge_select_set(PointerRNA *ptr, bool value)
{
Mesh *mesh = rna_mesh(ptr);
bool *selection_edge = (bool *)CustomData_duplicate_referenced_layer_named(
&mesh->edata, CD_PROP_BOOL, ".selection_edge", mesh->totedge);
if (!selection_edge) {
if (!value) {
/* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */
return;
}
selection_edge = (bool *)CustomData_add_layer_named(
&mesh->edata, CD_PROP_BOOL, CD_CALLOC, NULL, mesh->totedge, ".selection_edge");
}
const int index = rna_MeshEdge_index_get(ptr);
selection_edge[index] = value;
}
static int rna_MeshLoopTriangle_material_index_get(PointerRNA *ptr)
{
const Mesh *me = rna_mesh(ptr);
@ -1914,7 +1992,7 @@ static void rna_def_mvert(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Normal", "Vertex Normal");
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT);
RNA_def_property_boolean_funcs(prop, "rna_MeshVertex_select_get", "rna_MeshVertex_select_set");
RNA_def_property_ui_text(prop, "Select", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
@ -1990,7 +2068,7 @@ static void rna_def_medge(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT);
RNA_def_property_boolean_funcs(prop, "rna_MeshEdge_select_get", "rna_MeshEdge_select_set");
RNA_def_property_ui_text(prop, "Select", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
@ -2203,7 +2281,7 @@ static void rna_def_mpolygon(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_FACE_SEL);
RNA_def_property_boolean_funcs(prop, "rna_MeshPolygon_select_get", "rna_MeshPolygon_select_set");
RNA_def_property_ui_text(prop, "Select", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");