Progress
This commit is contained in:
parent
c4dc870a45
commit
780d67a133
|
@ -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)
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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]) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
Loading…
Reference in New Issue