UV: remove per-UV-map selection data
Replace per UV map selection with a single UV selection for all UV's. This uses the same data as UV sync select, meaning that it's no longer possible to keep a different selection when sync-select is disabled. There is a minor improvement to functionality - previously not possible to de-select a single face surrounding by selected faces. Now this is possible because true face selection is supported. The selection from the active UV-map is converted to use the shared selection data. Ref !147523 Co-authored-by: Hans Goudey <hans@blender.org>
This commit is contained in:
@@ -161,9 +161,5 @@ bool BKE_color_attribute_supported(const struct Mesh &mesh, blender::StringRef n
|
||||
|
||||
std::string BKE_attribute_calc_unique_name(const AttributeOwner &owner, blender::StringRef name);
|
||||
|
||||
[[nodiscard]] blender::StringRef BKE_uv_map_vert_select_name_get(blender::StringRef uv_map_name,
|
||||
char *buffer);
|
||||
[[nodiscard]] blender::StringRef BKE_uv_map_edge_select_name_get(blender::StringRef uv_map_name,
|
||||
char *buffer);
|
||||
[[nodiscard]] blender::StringRef BKE_uv_map_pin_name_get(blender::StringRef uv_map_name,
|
||||
char *buffer);
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 104
|
||||
#define BLENDER_FILE_SUBVERSION 105
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||
|
||||
@@ -41,9 +41,7 @@ enum class AttrDomain : int8_t;
|
||||
* has 4 extra bytes above what can be used for the base layer name, and these
|
||||
* prefixes are placed between 2 '.'s at the start of the layer name.
|
||||
* For example The uv vert selection layer of a layer named `UVMap.001`
|
||||
* will be called `.vs.UVMap.001`. */
|
||||
#define UV_VERTSEL_NAME "vs"
|
||||
#define UV_EDGESEL_NAME "es"
|
||||
* will be called `.pn.UVMap.001`. */
|
||||
#define UV_PINNED_NAME "pn"
|
||||
|
||||
/**
|
||||
@@ -53,13 +51,11 @@ enum class AttrDomain : int8_t;
|
||||
*/
|
||||
struct BMUVOffsets {
|
||||
int uv;
|
||||
int select_vert;
|
||||
int select_edge;
|
||||
int pin;
|
||||
};
|
||||
|
||||
/** All values reference none layers. */
|
||||
#define BMUVOFFSETS_NONE {-1, -1, -1, -1}
|
||||
#define BMUVOFFSETS_NONE {-1, -1}
|
||||
|
||||
/* A data type large enough to hold 1 element from any custom-data layer type. */
|
||||
struct CDBlockBytes {
|
||||
|
||||
@@ -20,6 +20,8 @@ struct CustomDataLayer;
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
void mesh_uv_select_to_single_attribute(Mesh &mesh);
|
||||
|
||||
void mesh_custom_normals_to_generic(Mesh &mesh);
|
||||
|
||||
void mesh_sculpt_mask_to_generic(Mesh &mesh);
|
||||
|
||||
@@ -324,14 +324,6 @@ bool BKE_attribute_rename(AttributeOwner &owner,
|
||||
char buffer_src[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
char buffer_dst[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
|
||||
bke_attribute_rename_if_exists(owner,
|
||||
BKE_uv_map_vert_select_name_get(layer->name, buffer_src),
|
||||
BKE_uv_map_vert_select_name_get(result_name, buffer_dst),
|
||||
reports);
|
||||
bke_attribute_rename_if_exists(owner,
|
||||
BKE_uv_map_edge_select_name_get(layer->name, buffer_src),
|
||||
BKE_uv_map_edge_select_name_get(result_name, buffer_dst),
|
||||
reports);
|
||||
bke_attribute_rename_if_exists(owner,
|
||||
BKE_uv_map_pin_name_get(layer->name, buffer_src),
|
||||
BKE_uv_map_pin_name_get(result_name, buffer_dst),
|
||||
@@ -489,13 +481,6 @@ CustomDataLayer *BKE_attribute_duplicate(AttributeOwner &owner,
|
||||
/* Duplicate UV sub-attributes. */
|
||||
char buffer_src[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
char buffer_dst[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
|
||||
bke_attribute_copy_if_exists(owner,
|
||||
BKE_uv_map_vert_select_name_get(name, buffer_src),
|
||||
BKE_uv_map_vert_select_name_get(uniquename, buffer_dst));
|
||||
bke_attribute_copy_if_exists(owner,
|
||||
BKE_uv_map_edge_select_name_get(name, buffer_src),
|
||||
BKE_uv_map_edge_select_name_get(uniquename, buffer_dst));
|
||||
bke_attribute_copy_if_exists(owner,
|
||||
BKE_uv_map_pin_name_get(name, buffer_src),
|
||||
BKE_uv_map_pin_name_get(uniquename, buffer_dst));
|
||||
@@ -575,10 +560,6 @@ bool BKE_attribute_remove(AttributeOwner &owner, const StringRef name, ReportLis
|
||||
|
||||
if (type == CD_PROP_FLOAT2 && domain == int(AttrDomain::Corner)) {
|
||||
char buffer[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
BM_data_layer_free_named(
|
||||
em->bm, data, BKE_uv_map_vert_select_name_get(name_copy, buffer));
|
||||
BM_data_layer_free_named(
|
||||
em->bm, data, BKE_uv_map_edge_select_name_get(name_copy, buffer));
|
||||
BM_data_layer_free_named(em->bm, data, BKE_uv_map_pin_name_get(name_copy, buffer));
|
||||
}
|
||||
return true;
|
||||
@@ -622,8 +603,6 @@ bool BKE_attribute_remove(AttributeOwner &owner, const StringRef name, ReportLis
|
||||
|
||||
if (metadata->data_type == AttrType::Float2 && metadata->domain == AttrDomain::Corner) {
|
||||
char buffer[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
attributes->remove(BKE_uv_map_vert_select_name_get(name_copy, buffer));
|
||||
attributes->remove(BKE_uv_map_edge_select_name_get(name_copy, buffer));
|
||||
attributes->remove(BKE_uv_map_pin_name_get(name_copy, buffer));
|
||||
}
|
||||
return true;
|
||||
@@ -1070,24 +1049,6 @@ bool BKE_color_attribute_supported(const Mesh &mesh, const StringRef name)
|
||||
return true;
|
||||
}
|
||||
|
||||
StringRef BKE_uv_map_vert_select_name_get(const StringRef uv_map_name, char *buffer)
|
||||
{
|
||||
BLI_assert(strlen(UV_VERTSEL_NAME) == 2);
|
||||
BLI_assert(uv_map_name.size() < MAX_CUSTOMDATA_LAYER_NAME - 4);
|
||||
const auto result = fmt::format_to_n(
|
||||
buffer, MAX_CUSTOMDATA_LAYER_NAME, ".{}.{}", UV_VERTSEL_NAME, uv_map_name);
|
||||
return StringRef(buffer, result.size);
|
||||
}
|
||||
|
||||
StringRef BKE_uv_map_edge_select_name_get(const StringRef uv_map_name, char *buffer)
|
||||
{
|
||||
BLI_assert(strlen(UV_EDGESEL_NAME) == 2);
|
||||
BLI_assert(uv_map_name.size() < MAX_CUSTOMDATA_LAYER_NAME - 4);
|
||||
const auto result = fmt::format_to_n(
|
||||
buffer, MAX_CUSTOMDATA_LAYER_NAME, ".{}.{}", UV_EDGESEL_NAME, uv_map_name);
|
||||
return StringRef(buffer, result.size);
|
||||
}
|
||||
|
||||
StringRef BKE_uv_map_pin_name_get(const StringRef uv_map_name, char *buffer)
|
||||
{
|
||||
BLI_assert(strlen(UV_PINNED_NAME) == 2);
|
||||
|
||||
@@ -219,12 +219,6 @@ bool allow_procedural_attribute_access(StringRef attribute_name)
|
||||
if (attribute_name == ".reference_index") {
|
||||
return false;
|
||||
}
|
||||
if (attribute_name.startswith("." UV_VERTSEL_NAME ".")) {
|
||||
return false;
|
||||
}
|
||||
if (attribute_name.startswith("." UV_EDGESEL_NAME ".")) {
|
||||
return false;
|
||||
}
|
||||
if (attribute_name.startswith("." UV_PINNED_NAME ".")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4272,9 +4272,7 @@ int CustomData_name_maxncpy_calc(const blender::StringRef name)
|
||||
if (name.startswith(".")) {
|
||||
return MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX;
|
||||
}
|
||||
for (const blender::StringRef prefix :
|
||||
{"." UV_VERTSEL_NAME, UV_EDGESEL_NAME ".", UV_PINNED_NAME "."})
|
||||
{
|
||||
for (const blender::StringRef prefix : {UV_PINNED_NAME "."}) {
|
||||
if (name.startswith(prefix)) {
|
||||
return MAX_CUSTOMDATA_LAYER_NAME;
|
||||
}
|
||||
|
||||
@@ -526,8 +526,8 @@ static bool sort_faces_based_on_corners(const IndexMapping &corners,
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* The uv selection / pin layers are ignored in the comparisons because
|
||||
/**
|
||||
* The UV selection & pin layers are ignored in the comparisons because
|
||||
* the original flags they replace were ignored as well. Because of the
|
||||
* lazy creation of these layers it would need careful handling of the
|
||||
* test files to compare these layers. For now it has been decided to
|
||||
@@ -535,8 +535,8 @@ static bool sort_faces_based_on_corners(const IndexMapping &corners,
|
||||
*/
|
||||
static bool ignored_attribute(const StringRef id)
|
||||
{
|
||||
return attribute_name_is_anonymous(id) || id.startswith(".vs.") || id.startswith(".es.") ||
|
||||
id.startswith(".pn.");
|
||||
return attribute_name_is_anonymous(id) || id.startswith(".pn.") ||
|
||||
ELEM(id, ".uv_select_vert", ".uv_select_edge", ".uv_select_face");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1710,15 +1710,7 @@ void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh)
|
||||
[](const uint32_t a, const uint32_t b) { return a | b; });
|
||||
|
||||
float2 *coords = MEM_malloc_arrayN<float2>(size_t(mesh->corners_num), __func__);
|
||||
bool *vert_selection = nullptr;
|
||||
bool *edge_selection = nullptr;
|
||||
bool *pin = nullptr;
|
||||
if (needed_boolean_attributes & MLOOPUV_VERTSEL) {
|
||||
vert_selection = MEM_malloc_arrayN<bool>(size_t(mesh->corners_num), __func__);
|
||||
}
|
||||
if (needed_boolean_attributes & MLOOPUV_EDGESEL) {
|
||||
edge_selection = MEM_malloc_arrayN<bool>(size_t(mesh->corners_num), __func__);
|
||||
}
|
||||
if (needed_boolean_attributes & MLOOPUV_PINNED) {
|
||||
pin = MEM_malloc_arrayN<bool>(size_t(mesh->corners_num), __func__);
|
||||
}
|
||||
@@ -1727,16 +1719,6 @@ void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh)
|
||||
for (const int i : range) {
|
||||
coords[i] = mloopuv[i].uv;
|
||||
}
|
||||
if (vert_selection) {
|
||||
for (const int i : range) {
|
||||
vert_selection[i] = mloopuv[i].flag & MLOOPUV_VERTSEL;
|
||||
}
|
||||
}
|
||||
if (edge_selection) {
|
||||
for (const int i : range) {
|
||||
edge_selection[i] = mloopuv[i].flag & MLOOPUV_EDGESEL;
|
||||
}
|
||||
}
|
||||
if (pin) {
|
||||
for (const int i : range) {
|
||||
pin[i] = mloopuv[i].flag & MLOOPUV_PINNED;
|
||||
@@ -1753,22 +1735,6 @@ void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh)
|
||||
CustomData_add_layer_named_with_data(
|
||||
&mesh->corner_data, CD_PROP_FLOAT2, coords, mesh->corners_num, new_name, nullptr);
|
||||
char buffer[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
if (vert_selection) {
|
||||
CustomData_add_layer_named_with_data(&mesh->corner_data,
|
||||
CD_PROP_BOOL,
|
||||
vert_selection,
|
||||
mesh->corners_num,
|
||||
BKE_uv_map_vert_select_name_get(new_name, buffer),
|
||||
nullptr);
|
||||
}
|
||||
if (edge_selection) {
|
||||
CustomData_add_layer_named_with_data(&mesh->corner_data,
|
||||
CD_PROP_BOOL,
|
||||
edge_selection,
|
||||
mesh->corners_num,
|
||||
BKE_uv_map_edge_select_name_get(new_name, buffer),
|
||||
nullptr);
|
||||
}
|
||||
if (pin) {
|
||||
CustomData_add_layer_named_with_data(&mesh->corner_data,
|
||||
CD_PROP_BOOL,
|
||||
@@ -2621,7 +2587,78 @@ void mesh_custom_normals_to_generic(Mesh &mesh)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void mesh_uv_select_to_single_attribute(Mesh &mesh)
|
||||
{
|
||||
const char *name = CustomData_get_active_layer_name(&mesh.corner_data, CD_PROP_FLOAT2);
|
||||
if (!name) {
|
||||
return;
|
||||
}
|
||||
const std::string uv_select_vert_name_shared = ".uv_select_vert";
|
||||
const std::string uv_select_edge_name_shared = ".uv_select_edge";
|
||||
const std::string uv_select_face_name_shared = ".uv_select_face";
|
||||
|
||||
const std::string uv_select_vert_prefix = ".vs.";
|
||||
const std::string uv_select_edge_prefix = ".es.";
|
||||
|
||||
const std::string uv_select_vert_name = uv_select_vert_prefix + name;
|
||||
const std::string uv_select_edge_name = uv_select_edge_prefix + name;
|
||||
|
||||
const int uv_select_vert = CustomData_get_named_layer_index(
|
||||
&mesh.corner_data, CD_PROP_BOOL, uv_select_vert_name);
|
||||
const int uv_select_edge = CustomData_get_named_layer_index(
|
||||
&mesh.corner_data, CD_PROP_BOOL, uv_select_edge_name);
|
||||
|
||||
if (uv_select_vert != -1 && uv_select_edge != -1) {
|
||||
/* Unlikely either exist but ensure there are no duplicate names. */
|
||||
CustomData_free_layer_named(&mesh.corner_data, uv_select_vert_name_shared);
|
||||
CustomData_free_layer_named(&mesh.corner_data, uv_select_edge_name_shared);
|
||||
CustomData_free_layer_named(&mesh.face_data, uv_select_face_name_shared);
|
||||
|
||||
STRNCPY_UTF8(mesh.corner_data.layers[uv_select_vert].name, uv_select_vert_name_shared.c_str());
|
||||
STRNCPY_UTF8(mesh.corner_data.layers[uv_select_edge].name, uv_select_edge_name_shared.c_str());
|
||||
|
||||
bool *uv_select_face = MEM_malloc_arrayN<bool>(mesh.faces_num, __func__);
|
||||
CustomData_add_layer_named_with_data(&mesh.face_data,
|
||||
CD_PROP_BOOL,
|
||||
uv_select_face,
|
||||
mesh.faces_num,
|
||||
uv_select_face_name_shared,
|
||||
nullptr);
|
||||
|
||||
/* Create a face selection layer (flush from edges). */
|
||||
if (mesh.faces_num > 0) {
|
||||
const OffsetIndices<int> faces = mesh.faces();
|
||||
const Span<bool> uv_select_edge_data(
|
||||
static_cast<bool *>(mesh.corner_data.layers[uv_select_edge].data), mesh.corners_num);
|
||||
threading::parallel_for(faces.index_range(), 1024, [&](const IndexRange range) {
|
||||
for (const int face : range) {
|
||||
uv_select_face[face] = !uv_select_edge_data.slice(faces[face]).contains(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/* Logically a set as names are expected to be unique.
|
||||
* If there are duplicates, this will remove those too. */
|
||||
Vector<std::string> attributes_to_remove;
|
||||
for (const int i : IndexRange(mesh.corner_data.totlayer)) {
|
||||
const CustomDataLayer &layer = mesh.corner_data.layers[i];
|
||||
if (layer.type != CD_PROP_BOOL) {
|
||||
continue;
|
||||
}
|
||||
StringRef layer_name = StringRef(layer.name);
|
||||
if (layer_name.startswith(uv_select_vert_prefix) ||
|
||||
layer_name.startswith(uv_select_edge_prefix))
|
||||
{
|
||||
attributes_to_remove.append(layer.name);
|
||||
}
|
||||
}
|
||||
|
||||
for (const StringRef name_to_remove : attributes_to_remove) {
|
||||
CustomData_free_layer_named(&mesh.corner_data, name_to_remove);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -335,7 +335,7 @@ void BKE_mesh_runtime_clear_geometry(Mesh *mesh)
|
||||
mesh->runtime->subsurf_face_dot_tags.clear_and_shrink();
|
||||
mesh->runtime->subsurf_optimal_display_edges.clear_and_shrink();
|
||||
mesh->runtime->spatial_groups.reset();
|
||||
mesh->flag &= ~ME_NO_OVERLAPPING_TOPOLOGY;
|
||||
mesh->flag &= ~(ME_NO_OVERLAPPING_TOPOLOGY | ME_FLAG_UV_SELECT_SYNC_VALID);
|
||||
}
|
||||
|
||||
void Mesh::tag_edges_split()
|
||||
|
||||
@@ -4662,8 +4662,9 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (Mesh *, me, &bmain->meshes) {
|
||||
me->flag &= ~(ME_FLAG_UNUSED_0 | ME_FLAG_UNUSED_1 | ME_FLAG_UNUSED_3 | ME_FLAG_UNUSED_4 |
|
||||
ME_FLAG_UNUSED_6 | ME_FLAG_UNUSED_7 | ME_REMESH_REPROJECT_ATTRIBUTES);
|
||||
me->flag &= ~(ME_FLAG_UNUSED_0 | ME_FLAG_UNUSED_1 | ME_FLAG_UV_SELECT_SYNC_VALID |
|
||||
ME_FLAG_UNUSED_4 | ME_FLAG_UNUSED_6 | ME_FLAG_UNUSED_7 |
|
||||
ME_REMESH_REPROJECT_ATTRIBUTES);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (Material *, mat, &bmain->materials) {
|
||||
|
||||
@@ -3935,6 +3935,12 @@ void blo_do_versions_500(FileData *fd, Library * /*lib*/, Main *bmain)
|
||||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 105)) {
|
||||
LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
|
||||
bke::mesh_uv_select_to_single_attribute(*mesh);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Always bump subversion in BKE_blender_version.h when adding versioning
|
||||
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.
|
||||
|
||||
@@ -878,25 +878,13 @@ void BM_data_layer_ensure_named(BMesh *bm, CustomData *data, int type, const Str
|
||||
}
|
||||
}
|
||||
|
||||
void BM_uv_map_attr_select_and_pin_ensure(BMesh *bm)
|
||||
void BM_uv_map_attr_pin_ensure_for_all_layers(BMesh *bm)
|
||||
{
|
||||
const int nr_uv_layers = CustomData_number_of_layers(&bm->ldata, CD_PROP_FLOAT2);
|
||||
for (int l = 0; l < nr_uv_layers; l++) {
|
||||
/* NOTE: you can't re-use the return-value of #CustomData_get_layer_name()
|
||||
* because adding layers can invalidate that. */
|
||||
char name[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
BM_data_layer_ensure_named(
|
||||
bm,
|
||||
&bm->ldata,
|
||||
CD_PROP_BOOL,
|
||||
BKE_uv_map_vert_select_name_get(CustomData_get_layer_name(&bm->ldata, CD_PROP_FLOAT2, l),
|
||||
name));
|
||||
BM_data_layer_ensure_named(
|
||||
bm,
|
||||
&bm->ldata,
|
||||
CD_PROP_BOOL,
|
||||
BKE_uv_map_edge_select_name_get(CustomData_get_layer_name(&bm->ldata, CD_PROP_FLOAT2, l),
|
||||
name));
|
||||
BM_data_layer_ensure_named(
|
||||
bm,
|
||||
&bm->ldata,
|
||||
@@ -905,34 +893,13 @@ void BM_uv_map_attr_select_and_pin_ensure(BMesh *bm)
|
||||
}
|
||||
}
|
||||
|
||||
void BM_uv_map_attr_vert_select_ensure(BMesh *bm, const StringRef uv_map_name)
|
||||
{
|
||||
char name[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
BM_data_layer_ensure_named(
|
||||
bm, &bm->ldata, CD_PROP_BOOL, BKE_uv_map_vert_select_name_get(uv_map_name, name));
|
||||
}
|
||||
|
||||
void BM_uv_map_attr_edge_select_ensure(BMesh *bm, const StringRef uv_map_name)
|
||||
{
|
||||
char name[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
BM_data_layer_ensure_named(
|
||||
bm, &bm->ldata, CD_PROP_BOOL, BKE_uv_map_edge_select_name_get(uv_map_name, name));
|
||||
}
|
||||
|
||||
void BM_uv_map_attr_pin_ensure(BMesh *bm, const StringRef uv_map_name)
|
||||
void BM_uv_map_attr_pin_ensure_named(BMesh *bm, const StringRef uv_map_name)
|
||||
{
|
||||
char name[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
BM_data_layer_ensure_named(
|
||||
bm, &bm->ldata, CD_PROP_BOOL, BKE_uv_map_pin_name_get(uv_map_name, name));
|
||||
}
|
||||
|
||||
bool BM_uv_map_attr_vert_select_exists(const BMesh *bm, const StringRef uv_map_name)
|
||||
{
|
||||
char name[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
return (CustomData_get_named_layer_index(
|
||||
&bm->ldata, CD_PROP_BOOL, BKE_uv_map_vert_select_name_get(uv_map_name, name)) != -1);
|
||||
}
|
||||
|
||||
bool BM_uv_map_attr_pin_exists(const BMesh *bm, const StringRef uv_map_name)
|
||||
{
|
||||
char name[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
|
||||
@@ -77,13 +77,9 @@ bool BM_data_layer_has_named(const BMesh *bm,
|
||||
void BM_data_layer_free(BMesh *bm, CustomData *data, int type);
|
||||
|
||||
/** Ensure the dependent boolean layers exist for all face corner #CD_PROP_FLOAT2 layers. */
|
||||
void BM_uv_map_attr_select_and_pin_ensure(BMesh *bm);
|
||||
void BM_uv_map_attr_pin_ensure_for_all_layers(BMesh *bm);
|
||||
|
||||
void BM_uv_map_attr_vert_select_ensure(BMesh *bm, blender::StringRef uv_map_name);
|
||||
void BM_uv_map_attr_edge_select_ensure(BMesh *bm, blender::StringRef uv_map_name);
|
||||
void BM_uv_map_attr_pin_ensure(BMesh *bm, blender::StringRef uv_map_name);
|
||||
|
||||
bool BM_uv_map_attr_vert_select_exists(const BMesh *bm, blender::StringRef uv_map_name);
|
||||
void BM_uv_map_attr_pin_ensure_named(BMesh *bm, blender::StringRef uv_map_name);
|
||||
bool BM_uv_map_attr_pin_exists(const BMesh *bm, blender::StringRef uv_map_name);
|
||||
|
||||
/**
|
||||
|
||||
@@ -243,24 +243,6 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *mesh, const BMeshFromMeshParams *
|
||||
IndexRange(CustomData_number_of_layers(&mesh_ldata, CD_PROP_FLOAT2)))
|
||||
{
|
||||
char buffer[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
{
|
||||
const StringRef name = BKE_uv_map_vert_select_name_get(
|
||||
CustomData_get_layer_name(&mesh_ldata, CD_PROP_FLOAT2, layer_index), buffer);
|
||||
if (CustomData_get_named_layer_index(&mesh_ldata, CD_PROP_BOOL, name) < 0) {
|
||||
CustomData_add_layer_named(
|
||||
&mesh_ldata, CD_PROP_BOOL, CD_SET_DEFAULT, mesh->corners_num, name);
|
||||
temporary_layers_to_delete.append(std::string(name));
|
||||
}
|
||||
}
|
||||
{
|
||||
const StringRef name = BKE_uv_map_edge_select_name_get(
|
||||
CustomData_get_layer_name(&mesh_ldata, CD_PROP_FLOAT2, layer_index), buffer);
|
||||
if (CustomData_get_named_layer_index(&mesh_ldata, CD_PROP_BOOL, name) < 0) {
|
||||
CustomData_add_layer_named(
|
||||
&mesh_ldata, CD_PROP_BOOL, CD_SET_DEFAULT, mesh->corners_num, name);
|
||||
temporary_layers_to_delete.append(std::string(name));
|
||||
}
|
||||
}
|
||||
{
|
||||
const StringRef name = BKE_uv_map_pin_name_get(
|
||||
CustomData_get_layer_name(&mesh_ldata, CD_PROP_FLOAT2, layer_index), buffer);
|
||||
@@ -596,7 +578,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *mesh, const BMeshFromMeshParams *
|
||||
bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); /* Added in order, clear dirty flag. */
|
||||
}
|
||||
|
||||
bm->uv_select_sync_valid = need_uv_select;
|
||||
bm->uv_select_sync_valid = (need_uv_select && (mesh->flag & ME_FLAG_UV_SELECT_SYNC_VALID)) != 0;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* MSelect clears the array elements (to avoid adding multiple times).
|
||||
@@ -1187,8 +1169,6 @@ static void bm_face_loop_table_build(BMesh &bm,
|
||||
Vector<int> &loop_layers_not_to_copy)
|
||||
{
|
||||
const CustomData &ldata = bm.ldata;
|
||||
Vector<int> vert_sel_layers;
|
||||
Vector<int> edge_sel_layers;
|
||||
Vector<int> pin_layers;
|
||||
for (const int i : IndexRange(CustomData_number_of_layers(&ldata, CD_PROP_FLOAT2))) {
|
||||
char const *layer_name = CustomData_get_layer_name(&ldata, CD_PROP_FLOAT2, i);
|
||||
@@ -1199,25 +1179,13 @@ static void bm_face_loop_table_build(BMesh &bm,
|
||||
layers.append(layer_index);
|
||||
}
|
||||
};
|
||||
add_bool_layer(vert_sel_layers, BKE_uv_map_vert_select_name_get(layer_name, sub_layer_name));
|
||||
add_bool_layer(edge_sel_layers, BKE_uv_map_edge_select_name_get(layer_name, sub_layer_name));
|
||||
add_bool_layer(pin_layers, BKE_uv_map_pin_name_get(layer_name, sub_layer_name));
|
||||
}
|
||||
Array<int> vert_sel_offsets(vert_sel_layers.size());
|
||||
Array<int> edge_sel_offsets(edge_sel_layers.size());
|
||||
Array<int> pin_offsets(pin_layers.size());
|
||||
for (const int i : vert_sel_layers.index_range()) {
|
||||
vert_sel_offsets[i] = ldata.layers[vert_sel_layers[i]].offset;
|
||||
}
|
||||
for (const int i : edge_sel_layers.index_range()) {
|
||||
edge_sel_offsets[i] = ldata.layers[edge_sel_layers[i]].offset;
|
||||
}
|
||||
for (const int i : pin_layers.index_range()) {
|
||||
pin_offsets[i] = ldata.layers[pin_layers[i]].offset;
|
||||
}
|
||||
|
||||
Array<bool> need_vert_sel(vert_sel_layers.size(), false);
|
||||
Array<bool> need_edge_sel(edge_sel_layers.size(), false);
|
||||
Array<bool> need_pin(pin_layers.size(), false);
|
||||
char hflag = 0;
|
||||
BMIter iter;
|
||||
@@ -1235,16 +1203,6 @@ static void bm_face_loop_table_build(BMesh &bm,
|
||||
for ([[maybe_unused]] const int i : IndexRange(face->len)) {
|
||||
BM_elem_index_set(loop, loop_i); /* set_inline */
|
||||
loop_table[loop_i] = loop;
|
||||
for (const int i : vert_sel_offsets.index_range()) {
|
||||
if (BM_ELEM_CD_GET_BOOL(loop, vert_sel_offsets[i])) {
|
||||
need_vert_sel[i] = true;
|
||||
}
|
||||
}
|
||||
for (const int i : edge_sel_offsets.index_range()) {
|
||||
if (BM_ELEM_CD_GET_BOOL(loop, edge_sel_offsets[i])) {
|
||||
need_edge_sel[i] = true;
|
||||
}
|
||||
}
|
||||
for (const int i : pin_offsets.index_range()) {
|
||||
if (BM_ELEM_CD_GET_BOOL(loop, pin_offsets[i])) {
|
||||
need_pin[i] = true;
|
||||
@@ -1257,16 +1215,6 @@ static void bm_face_loop_table_build(BMesh &bm,
|
||||
need_select_poly = (hflag & BM_ELEM_SELECT) != 0;
|
||||
need_hide_poly = (hflag & BM_ELEM_HIDDEN) != 0;
|
||||
|
||||
for (const int i : vert_sel_layers.index_range()) {
|
||||
if (!need_vert_sel[i]) {
|
||||
loop_layers_not_to_copy.append(vert_sel_layers[i]);
|
||||
}
|
||||
}
|
||||
for (const int i : edge_sel_layers.index_range()) {
|
||||
if (!need_edge_sel[i]) {
|
||||
loop_layers_not_to_copy.append(edge_sel_layers[i]);
|
||||
}
|
||||
}
|
||||
for (const int i : pin_layers.index_range()) {
|
||||
if (!need_pin[i]) {
|
||||
loop_layers_not_to_copy.append(pin_layers[i]);
|
||||
@@ -1477,6 +1425,12 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *mesh, const BMeshToMeshParam
|
||||
mesh->faces_num = bm->totface;
|
||||
mesh->act_face = -1;
|
||||
|
||||
/* Will have been cleared when clearing geometry. */
|
||||
const bool need_uv_select = CustomData_has_layer(&bm->ldata, CD_PROP_FLOAT2);
|
||||
if (need_uv_select & bm->uv_select_sync_valid) {
|
||||
mesh->flag |= ME_FLAG_UV_SELECT_SYNC_VALID;
|
||||
}
|
||||
|
||||
bool need_select_vert = false;
|
||||
bool need_select_edge = false;
|
||||
bool need_select_poly = false;
|
||||
@@ -1487,11 +1441,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *mesh, const BMeshToMeshParam
|
||||
bool need_sharp_edge = false;
|
||||
bool need_sharp_face = false;
|
||||
bool need_uv_seams = false;
|
||||
const bool need_uv_select = (bm->uv_select_sync_valid &&
|
||||
/* Avoid redundant layer creation if there is no selection,
|
||||
* although a "Select All" / "De-select All" clears
|
||||
* #BMesh::uv_select_sync_valid so it's often not needed. */
|
||||
(bm->totvertsel != 0));
|
||||
Array<const BMVert *> vert_table;
|
||||
Array<const BMEdge *> edge_table;
|
||||
Array<const BMFace *> face_table;
|
||||
@@ -1716,6 +1665,12 @@ void BM_mesh_bm_to_me_compact(BMesh &bm,
|
||||
mesh.corners_num = bm.totloop;
|
||||
mesh.faces_num = bm.totface;
|
||||
|
||||
/* Will have been cleared when clearing geometry. */
|
||||
const bool need_uv_select = CustomData_has_layer(&bm.ldata, CD_PROP_FLOAT2);
|
||||
if (need_uv_select && bm.uv_select_sync_valid) {
|
||||
mesh.flag |= ME_FLAG_UV_SELECT_SYNC_VALID;
|
||||
}
|
||||
|
||||
mesh.runtime->deformed_only = true;
|
||||
|
||||
const bool use_threading = (mesh.faces_num + mesh.edges_num) > 1024;
|
||||
@@ -1733,7 +1688,6 @@ void BM_mesh_bm_to_me_compact(BMesh &bm,
|
||||
bool need_sharp_edge = false;
|
||||
bool need_sharp_face = false;
|
||||
bool need_uv_seams = false;
|
||||
const bool need_uv_select = bm.uv_select_sync_valid;
|
||||
|
||||
Array<const BMVert *> vert_table;
|
||||
Array<const BMEdge *> edge_table;
|
||||
|
||||
@@ -31,10 +31,6 @@ BMUVOffsets BM_uv_map_offsets_from_layer(const BMesh *bm, const int layer)
|
||||
|
||||
BMUVOffsets offsets;
|
||||
offsets.uv = bm->ldata.layers[layer_index].offset;
|
||||
offsets.select_vert = CustomData_get_offset_named(
|
||||
&bm->ldata, CD_PROP_BOOL, BKE_uv_map_vert_select_name_get(name, buffer));
|
||||
offsets.select_edge = CustomData_get_offset_named(
|
||||
&bm->ldata, CD_PROP_BOOL, BKE_uv_map_edge_select_name_get(name, buffer));
|
||||
offsets.pin = CustomData_get_offset_named(
|
||||
&bm->ldata, CD_PROP_BOOL, BKE_uv_map_pin_name_get(name, buffer));
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ void mesh_render_data_face_flag(const MeshRenderData &mr,
|
||||
eattr.v_flag |= VFLAG_FACE_UV_ACTIVE;
|
||||
}
|
||||
if ((offsets.uv != -1) && (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) &&
|
||||
uvedit_face_select_test_ex(mr.toolsettings, mr.bm, efa, offsets))
|
||||
uvedit_face_select_test_ex(mr.toolsettings, mr.bm, efa))
|
||||
{
|
||||
eattr.v_flag |= VFLAG_FACE_UV_SELECT;
|
||||
}
|
||||
|
||||
@@ -520,13 +520,7 @@ void ED_mesh_faces_remove(Mesh *mesh, ReportList *reports, int count);
|
||||
|
||||
void ED_mesh_geometry_clear(Mesh *mesh);
|
||||
|
||||
blender::bke::AttributeWriter<bool> ED_mesh_uv_map_vert_select_layer_ensure(Mesh *mesh,
|
||||
int uv_index);
|
||||
blender::bke::AttributeWriter<bool> ED_mesh_uv_map_edge_select_layer_ensure(Mesh *mesh,
|
||||
int uv_index);
|
||||
blender::bke::AttributeWriter<bool> ED_mesh_uv_map_pin_layer_ensure(Mesh *mesh, int uv_index);
|
||||
blender::VArray<bool> ED_mesh_uv_map_vert_select_layer_get(const Mesh *mesh, int uv_index);
|
||||
blender::VArray<bool> ED_mesh_uv_map_edge_select_layer_get(const Mesh *mesh, int uv_index);
|
||||
blender::VArray<bool> ED_mesh_uv_map_pin_layer_get(const Mesh *mesh, int uv_index);
|
||||
|
||||
void ED_mesh_uv_ensure(Mesh *mesh, const char *name);
|
||||
|
||||
@@ -46,7 +46,7 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf);
|
||||
/**
|
||||
* Be careful when using this, it bypasses all synchronization options.
|
||||
*/
|
||||
void ED_uvedit_select_all(BMesh *bm);
|
||||
void ED_uvedit_select_all(const ToolSettings *ts, BMesh *bm);
|
||||
|
||||
void ED_uvedit_foreach_uv(const Scene *scene,
|
||||
BMesh *bm,
|
||||
@@ -149,10 +149,7 @@ void ED_uvedit_sync_uvselect_ensure_if_needed(const ToolSettings *ts, BMesh *bm)
|
||||
/* Visibility and selection tests. */
|
||||
|
||||
bool uvedit_face_visible_test_ex(const ToolSettings *ts, const BMFace *efa);
|
||||
bool uvedit_face_select_test_ex(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
const BMFace *efa,
|
||||
const BMUVOffsets &offsets);
|
||||
bool uvedit_face_select_test_ex(const ToolSettings *ts, const BMesh *bm, const BMFace *efa);
|
||||
|
||||
bool uvedit_edge_select_test_ex(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
@@ -164,10 +161,7 @@ bool uvedit_uv_select_test_ex(const ToolSettings *ts,
|
||||
const BMUVOffsets &offsets);
|
||||
|
||||
bool uvedit_face_visible_test(const Scene *scene, const BMFace *efa);
|
||||
bool uvedit_face_select_test(const Scene *scene,
|
||||
const BMesh *bm,
|
||||
const BMFace *efa,
|
||||
const BMUVOffsets &offsets);
|
||||
bool uvedit_face_select_test(const Scene *scene, const BMesh *bm, const BMFace *efa);
|
||||
bool uvedit_edge_select_test(const Scene *scene,
|
||||
const BMesh *bm,
|
||||
const BMLoop *l,
|
||||
@@ -179,24 +173,16 @@ bool uvedit_uv_select_test(const Scene *scene,
|
||||
|
||||
/* Low level loop selection, this ignores the selection modes. */
|
||||
|
||||
bool uvedit_loop_vert_select_get(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
const BMLoop *l,
|
||||
const BMUVOffsets &offsets);
|
||||
bool uvedit_loop_edge_select_get(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
const BMLoop *l,
|
||||
const BMUVOffsets &offsets);
|
||||
bool uvedit_loop_vert_select_get(const ToolSettings *ts, const BMesh *bm, const BMLoop *l);
|
||||
bool uvedit_loop_edge_select_get(const ToolSettings *ts, const BMesh *bm, const BMLoop *l);
|
||||
void uvedit_loop_vert_select_set(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
BMLoop *l,
|
||||
const bool select,
|
||||
const BMUVOffsets &offsets);
|
||||
const bool select);
|
||||
void uvedit_loop_edge_select_set(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
BMLoop *l,
|
||||
const bool select,
|
||||
const BMUVOffsets &offsets);
|
||||
const bool select);
|
||||
|
||||
/* Individual UV element selection functions. */
|
||||
|
||||
@@ -205,49 +191,31 @@ void uvedit_loop_edge_select_set(const ToolSettings *ts,
|
||||
*
|
||||
* Changes selection state of a single UV Face.
|
||||
*/
|
||||
void uvedit_face_select_set(
|
||||
const Scene *scene, BMesh *bm, BMFace *efa, bool select, const BMUVOffsets &offsets);
|
||||
void uvedit_face_select_set(const Scene *scene, BMesh *bm, BMFace *efa, bool select);
|
||||
/**
|
||||
* \brief Select UV Edge
|
||||
*
|
||||
* Changes selection state of a single UV Edge.
|
||||
*/
|
||||
void uvedit_edge_select_set(
|
||||
const Scene *scene, BMesh *bm, BMLoop *l, bool select, const BMUVOffsets &offsets);
|
||||
void uvedit_edge_select_set(const Scene *scene, BMesh *bm, BMLoop *l, bool select);
|
||||
/**
|
||||
* \brief Select UV Vertex
|
||||
*
|
||||
* Changes selection state of a single UV vertex.
|
||||
*/
|
||||
void uvedit_uv_select_set(
|
||||
const Scene *scene, BMesh *bm, BMLoop *l, bool select, const BMUVOffsets &offsets);
|
||||
void uvedit_uv_select_set(const Scene *scene, BMesh *bm, BMLoop *l, bool select);
|
||||
|
||||
/* Low level functions for (de)selecting individual UV elements. Ensure UV face visibility before
|
||||
* use. */
|
||||
|
||||
void uvedit_face_select_enable(const Scene *scene,
|
||||
BMesh *bm,
|
||||
BMFace *efa,
|
||||
const BMUVOffsets &offsets);
|
||||
void uvedit_face_select_disable(const Scene *scene,
|
||||
BMesh *bm,
|
||||
BMFace *efa,
|
||||
const BMUVOffsets &offsets);
|
||||
void uvedit_face_select_enable(const Scene *scene, BMesh *bm, BMFace *efa);
|
||||
void uvedit_face_select_disable(const Scene *scene, BMesh *bm, BMFace *efa);
|
||||
|
||||
void uvedit_edge_select_enable(const Scene *scene,
|
||||
BMesh *bm,
|
||||
BMLoop *l,
|
||||
const BMUVOffsets &offsets);
|
||||
void uvedit_edge_select_disable(const Scene *scene,
|
||||
BMesh *bm,
|
||||
BMLoop *l,
|
||||
const BMUVOffsets &offsets);
|
||||
void uvedit_edge_select_enable(const Scene *scene, BMesh *bm, BMLoop *l);
|
||||
void uvedit_edge_select_disable(const Scene *scene, BMesh *bm, BMLoop *l);
|
||||
|
||||
void uvedit_uv_select_enable(const Scene *scene, BMesh *bm, BMLoop *l, const BMUVOffsets &offsets);
|
||||
void uvedit_uv_select_disable(const Scene *scene,
|
||||
BMesh *bm,
|
||||
BMLoop *l,
|
||||
const BMUVOffsets &offsets);
|
||||
void uvedit_uv_select_enable(const Scene *scene, BMesh *bm, BMLoop *l);
|
||||
void uvedit_uv_select_disable(const Scene *scene, BMesh *bm, BMLoop *l);
|
||||
|
||||
/* Sticky mode UV element selection functions. */
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ int ED_mesh_uv_add(
|
||||
}
|
||||
|
||||
BM_data_layer_add_named(em->bm, &em->bm->ldata, CD_PROP_FLOAT2, unique_name.c_str());
|
||||
BM_uv_map_attr_select_and_pin_ensure(em->bm);
|
||||
BM_uv_map_attr_pin_ensure_for_all_layers(em->bm);
|
||||
/* copy data from active UV */
|
||||
if (layernum_dst && do_init) {
|
||||
const int layernum_src = CustomData_get_active_layer(&em->bm->ldata, CD_PROP_FLOAT2);
|
||||
@@ -295,24 +295,6 @@ static blender::VArray<bool> get_corner_boolean_attribute(const Mesh &mesh, cons
|
||||
return *attributes.lookup_or_default<bool>(name, blender::bke::AttrDomain::Corner, false);
|
||||
}
|
||||
|
||||
blender::VArray<bool> ED_mesh_uv_map_vert_select_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->corner_data, CD_PROP_FLOAT2, uv_index);
|
||||
return get_corner_boolean_attribute(*mesh, BKE_uv_map_vert_select_name_get(uv_name, buffer));
|
||||
}
|
||||
blender::VArray<bool> ED_mesh_uv_map_edge_select_layer_get(const Mesh *mesh, const int uv_index)
|
||||
{
|
||||
/* 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. */
|
||||
|
||||
using namespace blender::bke;
|
||||
char buffer[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
const char *uv_name = CustomData_get_layer_name(&mesh->corner_data, CD_PROP_FLOAT2, uv_index);
|
||||
return get_corner_boolean_attribute(*mesh, BKE_uv_map_edge_select_name_get(uv_name, buffer));
|
||||
}
|
||||
|
||||
blender::VArray<bool> ED_mesh_uv_map_pin_layer_get(const Mesh *mesh, const int uv_index)
|
||||
{
|
||||
using namespace blender::bke;
|
||||
@@ -329,22 +311,6 @@ static blender::bke::AttributeWriter<bool> ensure_corner_boolean_attribute(Mesh
|
||||
name, blender::bke::AttrDomain::Corner, blender::bke::AttributeInitDefaultValue());
|
||||
}
|
||||
|
||||
blender::bke::AttributeWriter<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->corner_data, CD_PROP_FLOAT2, uv_index);
|
||||
return ensure_corner_boolean_attribute(*mesh, BKE_uv_map_vert_select_name_get(uv_name, buffer));
|
||||
}
|
||||
blender::bke::AttributeWriter<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->corner_data, CD_PROP_FLOAT2, uv_index);
|
||||
return ensure_corner_boolean_attribute(*mesh, BKE_uv_map_edge_select_name_get(uv_name, buffer));
|
||||
}
|
||||
blender::bke::AttributeWriter<bool> ED_mesh_uv_map_pin_layer_ensure(Mesh *mesh, const int uv_index)
|
||||
{
|
||||
using namespace blender::bke;
|
||||
|
||||
@@ -104,6 +104,29 @@ bool uvedit_vert_is_all_other_faces_selected(const ToolSettings *ts,
|
||||
const BMLoop *l,
|
||||
const BMUVOffsets &offsets);
|
||||
|
||||
[[nodiscard]] bool uvedit_vert_select_get_no_sync(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
const BMLoop *l);
|
||||
[[nodiscard]] bool uvedit_edge_select_get_no_sync(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
const BMLoop *l);
|
||||
[[nodiscard]] bool uvedit_face_select_get_no_sync(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
const BMFace *f);
|
||||
|
||||
void uvedit_vert_select_set_no_sync(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
BMLoop *l,
|
||||
bool select);
|
||||
void uvedit_edge_select_set_no_sync(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
BMLoop *l,
|
||||
bool select);
|
||||
void uvedit_face_select_set_no_sync(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
BMFace *f,
|
||||
bool select);
|
||||
|
||||
/* utility tool functions */
|
||||
|
||||
void uvedit_live_unwrap_update(SpaceImage *sima, Scene *scene, Object *obedit);
|
||||
|
||||
@@ -92,16 +92,14 @@ static bool uvedit_is_face_affected_for_calc_uv_islands(const Scene *scene,
|
||||
const BMesh *bm,
|
||||
BMFace *efa,
|
||||
const bool only_selected_faces,
|
||||
const bool only_selected_uvs,
|
||||
const BMUVOffsets &uv_offsets)
|
||||
const bool only_selected_uvs)
|
||||
{
|
||||
if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
|
||||
return false;
|
||||
}
|
||||
if (only_selected_faces) {
|
||||
if (only_selected_uvs) {
|
||||
return BM_elem_flag_test(efa, BM_ELEM_SELECT) &&
|
||||
uvedit_face_select_test(scene, bm, efa, uv_offsets);
|
||||
return BM_elem_flag_test(efa, BM_ELEM_SELECT) && uvedit_face_select_test(scene, bm, efa);
|
||||
}
|
||||
return BM_elem_flag_test(efa, BM_ELEM_SELECT);
|
||||
}
|
||||
@@ -130,7 +128,7 @@ int bm_mesh_calc_uv_islands(const Scene *scene,
|
||||
BMIter iter;
|
||||
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
|
||||
const bool face_affected = uvedit_is_face_affected_for_calc_uv_islands(
|
||||
scene, bm, f, only_selected_faces, only_selected_uvs, uv_offsets);
|
||||
scene, bm, f, only_selected_faces, only_selected_uvs);
|
||||
BM_elem_flag_set(f, BM_ELEM_TAG, face_affected);
|
||||
}
|
||||
|
||||
|
||||
@@ -257,17 +257,17 @@ bool ED_uvedit_minmax_multi(const Scene *scene,
|
||||
return changed;
|
||||
}
|
||||
|
||||
void ED_uvedit_select_all(BMesh *bm)
|
||||
void ED_uvedit_select_all(const ToolSettings *ts, BMesh *bm)
|
||||
{
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
BMIter iter, liter;
|
||||
const BMUVOffsets offsets = BM_uv_map_offsets_get(bm);
|
||||
|
||||
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
|
||||
uvedit_face_select_set_no_sync(ts, bm, efa, true);
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true);
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true);
|
||||
uvedit_vert_select_set_no_sync(ts, bm, l, true);
|
||||
uvedit_edge_select_set_no_sync(ts, bm, l, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1724,10 +1724,8 @@ static wmOperatorStatus uv_pin_exec(bContext *C, wmOperator *op)
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
BMIter iter, liter;
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
const bool clear = RNA_boolean_get(op->ptr, "clear");
|
||||
const bool invert = RNA_boolean_get(op->ptr, "invert");
|
||||
const bool synced_selection = (ts->uv_flag & UV_FLAG_SELECT_SYNC) != 0;
|
||||
|
||||
Vector<Object *> objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
|
||||
scene, view_layer, nullptr);
|
||||
@@ -1741,20 +1739,12 @@ static wmOperatorStatus uv_pin_exec(bContext *C, wmOperator *op)
|
||||
if (em->bm->totvertsel == 0) {
|
||||
continue;
|
||||
}
|
||||
if (synced_selection) {
|
||||
/* Pass. */
|
||||
}
|
||||
else {
|
||||
if (!BM_uv_map_attr_vert_select_exists(em->bm, active_uv_name)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (clear && !BM_uv_map_attr_pin_exists(em->bm, active_uv_name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BM_uv_map_attr_pin_ensure(em->bm, active_uv_name);
|
||||
BM_uv_map_attr_pin_ensure_named(em->bm, active_uv_name);
|
||||
const BMUVOffsets offsets = BM_uv_map_offsets_get(em->bm);
|
||||
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
@@ -1820,19 +1810,24 @@ static void UV_OT_pin(wmOperatorType *ot)
|
||||
|
||||
/* check if we are selected or unselected based on 'bool_test' arg,
|
||||
* needed for select swap support */
|
||||
#define UV_VERT_SEL_TEST(l, bool_test) (BM_ELEM_CD_GET_BOOL(l, offsets.select_vert) == bool_test)
|
||||
#define UV_VERT_SEL_TEST(ts, bm, l, bool_test) \
|
||||
(uvedit_vert_select_get_no_sync(ts, bm, l) == bool_test)
|
||||
|
||||
#define UV_EDGE_SEL_TEST(l, bool_test) (BM_ELEM_CD_GET_BOOL(l, offsets.select_edge) == bool_test)
|
||||
#define UV_EDGE_SEL_TEST(ts, bm, l, bool_test) \
|
||||
(uvedit_edge_select_get_no_sync(ts, bm, l) == bool_test)
|
||||
|
||||
/* is every UV vert selected or unselected depending on bool_test */
|
||||
static bool bm_face_is_all_uv_sel(BMFace *f, bool select_test, const BMUVOffsets &offsets)
|
||||
static bool bm_face_is_all_uv_sel(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
BMFace *f,
|
||||
bool select_test)
|
||||
{
|
||||
BMLoop *l_iter;
|
||||
BMLoop *l_first;
|
||||
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
do {
|
||||
if (!UV_EDGE_SEL_TEST(l_iter, select_test)) {
|
||||
if (!UV_EDGE_SEL_TEST(ts, bm, l_iter, select_test)) {
|
||||
return false;
|
||||
}
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
@@ -1979,17 +1974,6 @@ static wmOperatorStatus uv_hide_exec(bContext *C, wmOperator *op)
|
||||
BMLoop *l;
|
||||
BMIter iter, liter;
|
||||
|
||||
if (ts->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
/* Pass. */
|
||||
}
|
||||
else {
|
||||
const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata,
|
||||
CD_PROP_FLOAT2);
|
||||
BM_uv_map_attr_vert_select_ensure(em->bm, active_uv_name);
|
||||
BM_uv_map_attr_edge_select_ensure(em->bm, active_uv_name);
|
||||
}
|
||||
const BMUVOffsets offsets = BM_uv_map_offsets_get(em->bm);
|
||||
|
||||
if (ts->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
uv_mesh_hide_sync_select(ts, ob, em, swap);
|
||||
continue;
|
||||
@@ -2004,7 +1988,7 @@ static wmOperatorStatus uv_hide_exec(bContext *C, wmOperator *op)
|
||||
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
|
||||
if (UV_VERT_SEL_TEST(l, !swap) || UV_EDGE_SEL_TEST(l, !swap)) {
|
||||
if (UV_VERT_SEL_TEST(ts, em->bm, l, !swap) || UV_EDGE_SEL_TEST(ts, em->bm, l, !swap)) {
|
||||
hide = 1;
|
||||
break;
|
||||
}
|
||||
@@ -2014,26 +1998,29 @@ static wmOperatorStatus uv_hide_exec(bContext *C, wmOperator *op)
|
||||
if (use_face_center) {
|
||||
if (em->selectmode == SCE_SELECT_FACE) {
|
||||
/* Deselect BMesh face if UV face is (de)selected depending on #swap. */
|
||||
if (bm_face_is_all_uv_sel(efa, !swap, offsets)) {
|
||||
if (bm_face_is_all_uv_sel(ts, em->bm, efa, !swap)) {
|
||||
BM_face_select_set(em->bm, efa, false);
|
||||
}
|
||||
uvedit_face_select_disable(scene, em->bm, efa, offsets);
|
||||
uvedit_face_select_disable(scene, em->bm, efa);
|
||||
}
|
||||
else {
|
||||
if (bm_face_is_all_uv_sel(efa, true, offsets) == !swap) {
|
||||
if (bm_face_is_all_uv_sel(ts, em->bm, efa, true) == !swap) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
/* For both cases rely on edge sel tests, since all vert sel tests are invalid in
|
||||
* case of sticky selections. */
|
||||
if (UV_EDGE_SEL_TEST(l, !swap) && (em->selectmode == SCE_SELECT_EDGE)) {
|
||||
if (UV_EDGE_SEL_TEST(ts, em->bm, l, !swap) && (em->selectmode == SCE_SELECT_EDGE))
|
||||
{
|
||||
BM_edge_select_set(em->bm, l->e, false);
|
||||
}
|
||||
else if (UV_EDGE_SEL_TEST(l, !swap) && (em->selectmode == SCE_SELECT_VERTEX)) {
|
||||
else if (UV_EDGE_SEL_TEST(ts, em->bm, l, !swap) &&
|
||||
(em->selectmode == SCE_SELECT_VERTEX))
|
||||
{
|
||||
BM_vert_select_set(em->bm, l->v, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!swap) {
|
||||
uvedit_face_select_disable(scene, em->bm, efa, offsets);
|
||||
uvedit_face_select_disable(scene, em->bm, efa);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2041,11 +2028,11 @@ static wmOperatorStatus uv_hide_exec(bContext *C, wmOperator *op)
|
||||
/* Deselect BMesh face depending on the type of UV selectmode and the type of UV element
|
||||
* being considered. */
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (UV_EDGE_SEL_TEST(l, !swap) && (ts->uv_selectmode == UV_SELECT_EDGE)) {
|
||||
if (UV_EDGE_SEL_TEST(ts, em->bm, l, !swap) && (ts->uv_selectmode == UV_SELECT_EDGE)) {
|
||||
BM_face_select_set(em->bm, efa, false);
|
||||
break;
|
||||
}
|
||||
if (UV_VERT_SEL_TEST(l, !swap) && (ts->uv_selectmode == UV_SELECT_VERT)) {
|
||||
if (UV_VERT_SEL_TEST(ts, em->bm, l, !swap) && (ts->uv_selectmode == UV_SELECT_VERT)) {
|
||||
BM_face_select_set(em->bm, efa, false);
|
||||
break;
|
||||
}
|
||||
@@ -2054,11 +2041,11 @@ static wmOperatorStatus uv_hide_exec(bContext *C, wmOperator *op)
|
||||
break;
|
||||
}
|
||||
}
|
||||
uvedit_face_select_disable(scene, em->bm, efa, offsets);
|
||||
uvedit_face_select_disable(scene, em->bm, efa);
|
||||
}
|
||||
else {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (UV_EDGE_SEL_TEST(l, !swap) && (ts->uv_selectmode == UV_SELECT_EDGE)) {
|
||||
if (UV_EDGE_SEL_TEST(ts, em->bm, l, !swap) && (ts->uv_selectmode == UV_SELECT_EDGE)) {
|
||||
if (em->selectmode == SCE_SELECT_EDGE) {
|
||||
BM_edge_select_set(em->bm, l->e, false);
|
||||
}
|
||||
@@ -2067,7 +2054,9 @@ static wmOperatorStatus uv_hide_exec(bContext *C, wmOperator *op)
|
||||
BM_vert_select_set(em->bm, l->next->v, false);
|
||||
}
|
||||
}
|
||||
else if (UV_VERT_SEL_TEST(l, !swap) && (ts->uv_selectmode != UV_SELECT_EDGE)) {
|
||||
else if (UV_VERT_SEL_TEST(ts, em->bm, l, !swap) &&
|
||||
(ts->uv_selectmode != UV_SELECT_EDGE))
|
||||
{
|
||||
if (em->selectmode == SCE_SELECT_EDGE) {
|
||||
BM_edge_select_set(em->bm, l->e, false);
|
||||
}
|
||||
@@ -2077,7 +2066,7 @@ static wmOperatorStatus uv_hide_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
}
|
||||
if (!swap) {
|
||||
uvedit_face_select_disable(scene, em->bm, efa, offsets);
|
||||
uvedit_face_select_disable(scene, em->bm, efa);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2145,17 +2134,6 @@ static wmOperatorStatus uv_reveal_exec(bContext *C, wmOperator *op)
|
||||
BMLoop *l;
|
||||
BMIter iter, liter;
|
||||
|
||||
if (ts->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
/* Pass. */
|
||||
}
|
||||
else {
|
||||
const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata,
|
||||
CD_PROP_FLOAT2);
|
||||
BM_uv_map_attr_vert_select_ensure(em->bm, active_uv_name);
|
||||
BM_uv_map_attr_edge_select_ensure(em->bm, active_uv_name);
|
||||
}
|
||||
const BMUVOffsets offsets = BM_uv_map_offsets_get(em->bm);
|
||||
|
||||
/* NOTE: Selecting faces is delayed so that it doesn't select verts/edges and confuse certain
|
||||
* UV selection checks.
|
||||
* This creates a temporary state which breaks certain UV selection functions that do face
|
||||
@@ -2184,9 +2162,10 @@ static wmOperatorStatus uv_reveal_exec(bContext *C, wmOperator *op)
|
||||
BM_elem_flag_disable(efa, BM_ELEM_TAG);
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select);
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select);
|
||||
uvedit_vert_select_set_no_sync(ts, em->bm, l, select);
|
||||
uvedit_edge_select_set_no_sync(ts, em->bm, l, select);
|
||||
}
|
||||
uvedit_face_select_set_no_sync(ts, em->bm, efa, select);
|
||||
// BM_face_select_set(em->bm, efa, true);
|
||||
BM_elem_flag_enable(efa, BM_ELEM_TAG);
|
||||
}
|
||||
@@ -2209,10 +2188,11 @@ static wmOperatorStatus uv_reveal_exec(bContext *C, wmOperator *op)
|
||||
if (!totsel) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select);
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select);
|
||||
uvedit_vert_select_set_no_sync(ts, em->bm, l, select);
|
||||
uvedit_edge_select_set_no_sync(ts, em->bm, l, select);
|
||||
}
|
||||
}
|
||||
uvedit_face_select_set_no_sync(ts, em->bm, efa, select);
|
||||
// BM_face_select_set(em->bm, efa, true);
|
||||
BM_elem_flag_enable(efa, BM_ELEM_TAG);
|
||||
}
|
||||
@@ -2224,9 +2204,10 @@ static wmOperatorStatus uv_reveal_exec(bContext *C, wmOperator *op)
|
||||
BM_elem_flag_disable(efa, BM_ELEM_TAG);
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select);
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select);
|
||||
uvedit_vert_select_set_no_sync(ts, em->bm, l, select);
|
||||
uvedit_edge_select_set_no_sync(ts, em->bm, l, select);
|
||||
}
|
||||
uvedit_face_select_set_no_sync(ts, em->bm, efa, select);
|
||||
// BM_face_select_set(em->bm, efa, true);
|
||||
BM_elem_flag_enable(efa, BM_ELEM_TAG);
|
||||
}
|
||||
@@ -2237,9 +2218,10 @@ static wmOperatorStatus uv_reveal_exec(bContext *C, wmOperator *op)
|
||||
BM_elem_flag_disable(efa, BM_ELEM_TAG);
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select);
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select);
|
||||
uvedit_vert_select_set_no_sync(ts, em->bm, l, select);
|
||||
uvedit_edge_select_set_no_sync(ts, em->bm, l, select);
|
||||
}
|
||||
uvedit_face_select_set_no_sync(ts, em->bm, efa, select);
|
||||
// BM_face_select_set(em->bm, efa, true);
|
||||
BM_elem_flag_enable(efa, BM_ELEM_TAG);
|
||||
}
|
||||
@@ -2553,6 +2535,7 @@ static bool uv_copy_mirrored_faces(
|
||||
|
||||
const BMUVOffsets offsets = BM_uv_map_offsets_get(bm);
|
||||
BLI_assert(offsets.uv != -1);
|
||||
UNUSED_VARS_NDEBUG(offsets);
|
||||
BMVert *v;
|
||||
BMIter iter;
|
||||
|
||||
@@ -2632,9 +2615,7 @@ static bool uv_copy_mirrored_faces(
|
||||
for (const auto &[f_dst, f_src] : face_map.items()) {
|
||||
|
||||
/* Skip unless both faces have all their UVs selected. */
|
||||
if (!uvedit_face_select_test(scene, bm, f_dst, offsets) ||
|
||||
!uvedit_face_select_test(scene, bm, f_src, offsets))
|
||||
{
|
||||
if (!uvedit_face_select_test(scene, bm, f_dst) || !uvedit_face_select_test(scene, bm, f_src)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ static void verttag_set_cb(BMLoop *l, bool val, void *user_data_v)
|
||||
if (verttag_filter_cb(l_iter, user_data)) {
|
||||
const float *luv_iter = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_loop_uv_offset);
|
||||
if (equals_v2v2(luv, luv_iter)) {
|
||||
uvedit_uv_select_set(scene, bm, l_iter, val, user_data->offsets);
|
||||
uvedit_uv_select_set(scene, bm, l_iter, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -776,11 +776,11 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const
|
||||
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
|
||||
bool is_all = true;
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (uvedit_loop_vert_select_get(ts, bm, l, offsets)) {
|
||||
if (uvedit_loop_edge_select_get(ts, bm, l, offsets)) {
|
||||
if (uvedit_loop_vert_select_get(ts, bm, l)) {
|
||||
if (uvedit_loop_edge_select_get(ts, bm, l)) {
|
||||
UL(l)->is_select_edge = true;
|
||||
}
|
||||
else if (!uvedit_loop_edge_select_get(ts, bm, l->prev, offsets)) {
|
||||
else if (!uvedit_loop_edge_select_get(ts, bm, l->prev)) {
|
||||
/* #bm_loop_uv_select_single_vert_validate validates below. */
|
||||
UL(l)->is_select_vert_single = true;
|
||||
is_all = false;
|
||||
@@ -824,12 +824,12 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (!UL(l)->is_select_all) {
|
||||
if (uvedit_loop_vert_select_get(ts, bm, l, offsets)) {
|
||||
uvedit_loop_vert_select_set(ts, bm, l, false, offsets);
|
||||
if (uvedit_loop_vert_select_get(ts, bm, l)) {
|
||||
uvedit_loop_vert_select_set(ts, bm, l, false);
|
||||
changed = true;
|
||||
}
|
||||
if (uvedit_loop_edge_select_get(ts, bm, l, offsets)) {
|
||||
uvedit_loop_edge_select_set(ts, bm, l, false, offsets);
|
||||
if (uvedit_loop_edge_select_get(ts, bm, l)) {
|
||||
uvedit_loop_edge_select_set(ts, bm, l, false);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
@@ -862,7 +862,7 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const
|
||||
BMLoop *l_iter = static_cast<BMLoop *>(BLI_gsetIterator_getKey(&gs_iter));
|
||||
ULData *ul = UL(l_iter);
|
||||
if (ul->side == side_from_cursor) {
|
||||
uvedit_uv_select_disable(scene, bm, l_iter, offsets);
|
||||
uvedit_uv_select_disable(scene, bm, l_iter);
|
||||
changed = true;
|
||||
}
|
||||
/* Ensure we don't operate on these again. */
|
||||
@@ -880,7 +880,7 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const
|
||||
BMLoop *l_iter = static_cast<BMLoop *>(BLI_gsetIterator_getKey(&gs_iter));
|
||||
ULData *ul = UL(l_iter);
|
||||
if (ul->side == side_from_cursor) {
|
||||
uvedit_uv_select_disable(scene, bm, l_iter, offsets);
|
||||
uvedit_uv_select_disable(scene, bm, l_iter);
|
||||
changed = true;
|
||||
}
|
||||
/* Ensure we don't operate on these again. */
|
||||
|
||||
@@ -382,10 +382,7 @@ void ED_uvedit_select_sync_flush(const ToolSettings *ts, BMesh *bm, const bool s
|
||||
}
|
||||
}
|
||||
|
||||
static void uvedit_vertex_select_tagged(BMesh *bm,
|
||||
Scene *scene,
|
||||
bool select,
|
||||
const BMUVOffsets &offsets)
|
||||
static void uvedit_vertex_select_tagged(BMesh *bm, Scene *scene, bool select)
|
||||
{
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
@@ -394,7 +391,7 @@ static void uvedit_vertex_select_tagged(BMesh *bm,
|
||||
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (BM_elem_flag_test(l->v, BM_ELEM_TAG)) {
|
||||
uvedit_uv_select_set(scene, bm, l, select, offsets);
|
||||
uvedit_uv_select_set(scene, bm, l, select);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -412,13 +409,8 @@ bool uvedit_face_visible_test(const Scene *scene, const BMFace *efa)
|
||||
return uvedit_face_visible_test_ex(scene->toolsettings, efa);
|
||||
}
|
||||
|
||||
bool uvedit_face_select_test_ex(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
const BMFace *efa,
|
||||
const BMUVOffsets &offsets)
|
||||
bool uvedit_face_select_test_ex(const ToolSettings *ts, const BMesh *bm, const BMFace *efa)
|
||||
{
|
||||
BLI_assert(offsets.select_vert >= 0);
|
||||
BLI_assert(offsets.select_edge >= 0);
|
||||
if (ts->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
if (bm->uv_select_sync_valid == false || ED_uvedit_sync_uvselect_ignore(ts)) {
|
||||
return BM_elem_flag_test(efa, BM_ELEM_SELECT);
|
||||
@@ -428,23 +420,26 @@ bool uvedit_face_select_test_ex(const ToolSettings *ts,
|
||||
return BM_elem_flag_test(efa, BM_ELEM_SELECT_UV);
|
||||
}
|
||||
|
||||
const int cd_offset = (ts->uv_selectmode & UV_SELECT_VERT) ? offsets.select_vert :
|
||||
offsets.select_edge;
|
||||
if (ts->uv_selectmode == UV_SELECT_FACE) {
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_SELECT_UV)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const char hflag_test = (ts->uv_selectmode & UV_SELECT_VERT) ? BM_ELEM_SELECT_UV :
|
||||
BM_ELEM_SELECT_UV_EDGE;
|
||||
const BMLoop *l_first = BM_FACE_FIRST_LOOP(efa);
|
||||
const BMLoop *l_iter = l_first;
|
||||
do {
|
||||
if (!BM_ELEM_CD_GET_BOOL(l_iter, cd_offset)) {
|
||||
if (!BM_elem_flag_test(l_iter, hflag_test)) {
|
||||
return false;
|
||||
}
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
return true;
|
||||
}
|
||||
bool uvedit_face_select_test(const Scene *scene,
|
||||
const BMesh *bm,
|
||||
const BMFace *efa,
|
||||
const BMUVOffsets &offsets)
|
||||
bool uvedit_face_select_test(const Scene *scene, const BMesh *bm, const BMFace *efa)
|
||||
{
|
||||
return uvedit_face_select_test_ex(scene->toolsettings, bm, efa, offsets);
|
||||
return uvedit_face_select_test_ex(scene->toolsettings, bm, efa);
|
||||
}
|
||||
|
||||
void uvedit_face_select_set_with_sticky(
|
||||
@@ -454,7 +449,7 @@ void uvedit_face_select_set_with_sticky(
|
||||
const char sticky = ts->uv_sticky;
|
||||
if (ts->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
if (ED_uvedit_sync_uvselect_ignore(ts)) {
|
||||
uvedit_face_select_set(scene, bm, efa, select, offsets);
|
||||
uvedit_face_select_set(scene, bm, efa, select);
|
||||
return;
|
||||
}
|
||||
BLI_assert(ED_uvedit_sync_uvselect_is_valid_or_ignore(ts, bm));
|
||||
@@ -466,7 +461,7 @@ void uvedit_face_select_set_with_sticky(
|
||||
* (not part of any face selections). This now uses the sticky location mode logic instead. */
|
||||
switch (sticky) {
|
||||
case UV_STICKY_DISABLE: {
|
||||
uvedit_face_select_set(scene, bm, efa, select, offsets);
|
||||
uvedit_face_select_set(scene, bm, efa, select);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -530,8 +525,9 @@ void uvedit_face_select_shared_vert(const Scene *scene,
|
||||
return;
|
||||
}
|
||||
|
||||
uvedit_face_select_set_no_sync(ts, bm, efa, select);
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select);
|
||||
uvedit_edge_select_set_no_sync(ts, bm, l, select);
|
||||
|
||||
if (select) {
|
||||
uvedit_uv_select_shared_vert(scene, bm, l, select, UV_STICKY_LOCATION, offsets);
|
||||
@@ -544,24 +540,18 @@ void uvedit_face_select_shared_vert(const Scene *scene,
|
||||
}
|
||||
}
|
||||
|
||||
void uvedit_face_select_set(
|
||||
const Scene *scene, BMesh *bm, BMFace *efa, const bool select, const BMUVOffsets &offsets)
|
||||
void uvedit_face_select_set(const Scene *scene, BMesh *bm, BMFace *efa, const bool select)
|
||||
{
|
||||
if (select) {
|
||||
uvedit_face_select_enable(scene, bm, efa, offsets);
|
||||
uvedit_face_select_enable(scene, bm, efa);
|
||||
}
|
||||
else {
|
||||
uvedit_face_select_disable(scene, bm, efa, offsets);
|
||||
uvedit_face_select_disable(scene, bm, efa);
|
||||
}
|
||||
}
|
||||
|
||||
void uvedit_face_select_enable(const Scene *scene,
|
||||
BMesh *bm,
|
||||
BMFace *efa,
|
||||
const BMUVOffsets &offsets)
|
||||
void uvedit_face_select_enable(const Scene *scene, BMesh *bm, BMFace *efa)
|
||||
{
|
||||
BLI_assert(offsets.select_vert >= 0);
|
||||
BLI_assert(offsets.select_edge >= 0);
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
|
||||
if (ts->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
@@ -576,20 +566,16 @@ void uvedit_face_select_enable(const Scene *scene,
|
||||
BMLoop *l;
|
||||
BMIter liter;
|
||||
|
||||
uvedit_face_select_set_no_sync(ts, bm, efa, true);
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true);
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true);
|
||||
uvedit_vert_select_set_no_sync(ts, bm, l, true);
|
||||
uvedit_edge_select_set_no_sync(ts, bm, l, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void uvedit_face_select_disable(const Scene *scene,
|
||||
BMesh *bm,
|
||||
BMFace *efa,
|
||||
const BMUVOffsets &offsets)
|
||||
void uvedit_face_select_disable(const Scene *scene, BMesh *bm, BMFace *efa)
|
||||
{
|
||||
BLI_assert(offsets.select_vert >= 0);
|
||||
BLI_assert(offsets.select_edge >= 0);
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
|
||||
if (ts->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
@@ -604,9 +590,10 @@ void uvedit_face_select_disable(const Scene *scene,
|
||||
BMLoop *l;
|
||||
BMIter liter;
|
||||
|
||||
uvedit_face_select_set_no_sync(ts, bm, efa, false);
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false);
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false);
|
||||
uvedit_vert_select_set_no_sync(ts, bm, l, false);
|
||||
uvedit_edge_select_set_no_sync(ts, bm, l, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -616,8 +603,6 @@ bool uvedit_edge_select_test_ex(const ToolSettings *ts,
|
||||
const BMLoop *l,
|
||||
const BMUVOffsets &offsets)
|
||||
{
|
||||
BLI_assert(offsets.select_vert >= 0);
|
||||
BLI_assert(offsets.select_edge >= 0);
|
||||
if (ts->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
if ((bm->uv_select_sync_valid == false) && (ts->selectmode == SCE_SELECT_FACE)) {
|
||||
/* Face only is a special case that can respect sticky modes. */
|
||||
@@ -657,10 +642,10 @@ bool uvedit_edge_select_test_ex(const ToolSettings *ts,
|
||||
}
|
||||
|
||||
if (ts->uv_selectmode & UV_SELECT_VERT) {
|
||||
return BM_ELEM_CD_GET_BOOL(l, offsets.select_vert) &&
|
||||
BM_ELEM_CD_GET_BOOL(l->next, offsets.select_vert);
|
||||
return uvedit_vert_select_get_no_sync(ts, bm, l) &&
|
||||
uvedit_vert_select_get_no_sync(ts, bm, l->next);
|
||||
}
|
||||
return BM_ELEM_CD_GET_BOOL(l, offsets.select_edge);
|
||||
return uvedit_edge_select_get_no_sync(ts, bm, l);
|
||||
}
|
||||
|
||||
bool uvedit_edge_select_test(const Scene *scene,
|
||||
@@ -681,7 +666,7 @@ void uvedit_edge_select_set_with_sticky(const Scene *scene,
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
if (ts->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
if (ED_uvedit_sync_uvselect_ignore(ts)) {
|
||||
uvedit_edge_select_set(scene, bm, l, select, offsets);
|
||||
uvedit_edge_select_set(scene, bm, l, select);
|
||||
return;
|
||||
}
|
||||
BLI_assert(ED_uvedit_sync_uvselect_is_valid_or_ignore(ts, bm));
|
||||
@@ -691,7 +676,7 @@ void uvedit_edge_select_set_with_sticky(const Scene *scene,
|
||||
switch (sticky) {
|
||||
case UV_STICKY_DISABLE: {
|
||||
if (uvedit_face_visible_test(scene, l->f)) {
|
||||
uvedit_edge_select_set(scene, bm, l, select, offsets);
|
||||
uvedit_edge_select_set(scene, bm, l, select);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -709,8 +694,7 @@ void uvedit_edge_select_set_with_sticky(const Scene *scene,
|
||||
|
||||
static bool UNUSED_FUNCTION(bm_loop_select_vert_check_internal)(const Scene *scene,
|
||||
BMesh *bm,
|
||||
BMLoop *l,
|
||||
const BMUVOffsets &offsets)
|
||||
BMLoop *l)
|
||||
{
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
if (ts->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
@@ -722,13 +706,10 @@ static bool UNUSED_FUNCTION(bm_loop_select_vert_check_internal)(const Scene *sce
|
||||
BLI_assert(!BM_elem_flag_test(l->f, BM_ELEM_HIDDEN));
|
||||
return BM_elem_flag_test_bool(l, BM_ELEM_SELECT_UV);
|
||||
}
|
||||
return BM_ELEM_CD_GET_BOOL(l, offsets.select_vert);
|
||||
return uvedit_vert_select_get_no_sync(ts, bm, l);
|
||||
}
|
||||
|
||||
static bool bm_loop_select_edge_check_internal(const Scene *scene,
|
||||
BMesh *bm,
|
||||
BMLoop *l,
|
||||
const BMUVOffsets &offsets)
|
||||
static bool bm_loop_select_edge_check_internal(const Scene *scene, BMesh *bm, BMLoop *l)
|
||||
{
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
if (ts->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
@@ -740,7 +721,7 @@ static bool bm_loop_select_edge_check_internal(const Scene *scene,
|
||||
BLI_assert(!BM_elem_flag_test(l->f, BM_ELEM_HIDDEN));
|
||||
return BM_elem_flag_test_bool(l, BM_ELEM_SELECT_UV_EDGE);
|
||||
}
|
||||
return BM_ELEM_CD_GET_BOOL(l, offsets.select_edge);
|
||||
return uvedit_edge_select_get_no_sync(ts, bm, l);
|
||||
}
|
||||
|
||||
void uvedit_edge_select_shared_vert(const Scene *scene,
|
||||
@@ -758,13 +739,13 @@ void uvedit_edge_select_shared_vert(const Scene *scene,
|
||||
BMLoop *l_iter = l;
|
||||
do {
|
||||
if (select) {
|
||||
if (bm_loop_select_edge_check_internal(scene, bm, l_iter, offsets)) {
|
||||
if (bm_loop_select_edge_check_internal(scene, bm, l_iter)) {
|
||||
uvedit_uv_select_shared_vert(scene, bm, l_iter, true, UV_STICKY_LOCATION, offsets);
|
||||
uvedit_uv_select_shared_vert(scene, bm, l_iter->next, true, UV_STICKY_LOCATION, offsets);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!bm_loop_select_edge_check_internal(scene, bm, l_iter, offsets)) {
|
||||
if (!bm_loop_select_edge_check_internal(scene, bm, l_iter)) {
|
||||
if (!uvedit_vert_is_edge_select_any_other(scene->toolsettings, bm, l, offsets)) {
|
||||
uvedit_uv_select_shared_vert(scene, bm, l_iter, false, UV_STICKY_LOCATION, offsets);
|
||||
}
|
||||
@@ -787,7 +768,6 @@ void uvedit_edge_select_set_noflush(const Scene *scene,
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
if ((ts->uv_flag & UV_FLAG_SELECT_SYNC) == 0) {
|
||||
BLI_assert(offsets.uv >= 0);
|
||||
BLI_assert(offsets.select_edge >= 0);
|
||||
}
|
||||
BMLoop *l_iter = l;
|
||||
do {
|
||||
@@ -797,38 +777,27 @@ void uvedit_edge_select_set_noflush(const Scene *scene,
|
||||
BM_loop_edge_uvselect_set_noflush(bm, l_iter, select);
|
||||
}
|
||||
else {
|
||||
BM_ELEM_CD_SET_BOOL(l_iter, offsets.select_edge, select);
|
||||
uvedit_edge_select_set_no_sync(ts, bm, l, select);
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (((l_iter = l_iter->radial_next) != l) && (sticky_flag != UV_STICKY_DISABLE));
|
||||
}
|
||||
|
||||
void uvedit_edge_select_set(const Scene *scene,
|
||||
BMesh *bm,
|
||||
BMLoop *l,
|
||||
const bool select,
|
||||
|
||||
const BMUVOffsets &offsets)
|
||||
void uvedit_edge_select_set(const Scene *scene, BMesh *bm, BMLoop *l, const bool select)
|
||||
{
|
||||
if (select) {
|
||||
uvedit_edge_select_enable(scene, bm, l, offsets);
|
||||
uvedit_edge_select_enable(scene, bm, l);
|
||||
}
|
||||
else {
|
||||
uvedit_edge_select_disable(scene, bm, l, offsets);
|
||||
uvedit_edge_select_disable(scene, bm, l);
|
||||
}
|
||||
}
|
||||
|
||||
void uvedit_edge_select_enable(const Scene *scene,
|
||||
BMesh *bm,
|
||||
BMLoop *l,
|
||||
const BMUVOffsets &offsets)
|
||||
void uvedit_edge_select_enable(const Scene *scene, BMesh *bm, BMLoop *l)
|
||||
|
||||
{
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
BLI_assert(offsets.select_vert >= 0);
|
||||
BLI_assert(offsets.select_edge >= 0);
|
||||
|
||||
if (ts->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
if (ED_uvedit_sync_uvselect_ignore(ts)) {
|
||||
if (ts->selectmode & SCE_SELECT_FACE) {
|
||||
@@ -847,16 +816,13 @@ void uvedit_edge_select_enable(const Scene *scene,
|
||||
}
|
||||
}
|
||||
else {
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true);
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true);
|
||||
BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, true);
|
||||
uvedit_vert_select_set_no_sync(ts, bm, l, true);
|
||||
uvedit_vert_select_set_no_sync(ts, bm, l->next, true);
|
||||
uvedit_edge_select_set_no_sync(ts, bm, l, true);
|
||||
}
|
||||
}
|
||||
|
||||
void uvedit_edge_select_disable(const Scene *scene,
|
||||
BMesh *bm,
|
||||
BMLoop *l,
|
||||
const BMUVOffsets &offsets)
|
||||
void uvedit_edge_select_disable(const Scene *scene, BMesh *bm, BMLoop *l)
|
||||
{
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
|
||||
@@ -891,22 +857,19 @@ void uvedit_edge_select_disable(const Scene *scene,
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_assert(offsets.select_vert >= 0);
|
||||
BLI_assert(offsets.select_edge >= 0);
|
||||
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false);
|
||||
uvedit_edge_select_set_no_sync(ts, bm, l, false);
|
||||
if ((ts->uv_selectmode & UV_SELECT_VERT) == 0) {
|
||||
/* Deselect UV vertex if not part of another edge selection */
|
||||
if (!BM_ELEM_CD_GET_BOOL(l->next, offsets.select_edge)) {
|
||||
BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, false);
|
||||
if (!uvedit_edge_select_get_no_sync(ts, bm, l->next)) {
|
||||
uvedit_vert_select_set_no_sync(ts, bm, l->next, false);
|
||||
}
|
||||
if (!BM_ELEM_CD_GET_BOOL(l->prev, offsets.select_edge)) {
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false);
|
||||
if (!uvedit_edge_select_get_no_sync(ts, bm, l->prev)) {
|
||||
uvedit_vert_select_set_no_sync(ts, bm, l, false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false);
|
||||
BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, false);
|
||||
uvedit_vert_select_set_no_sync(ts, bm, l, false);
|
||||
uvedit_vert_select_set_no_sync(ts, bm, l->next, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -916,7 +879,6 @@ bool uvedit_uv_select_test_ex(const ToolSettings *ts,
|
||||
const BMLoop *l,
|
||||
const BMUVOffsets &offsets)
|
||||
{
|
||||
BLI_assert(offsets.select_vert >= 0);
|
||||
if (ts->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
|
||||
if ((bm->uv_select_sync_valid == false) && (ts->selectmode == SCE_SELECT_FACE)) {
|
||||
@@ -989,7 +951,7 @@ bool uvedit_uv_select_test_ex(const ToolSettings *ts,
|
||||
/* Are you looking for `uvedit_edge_select_test(...)` instead? */
|
||||
}
|
||||
|
||||
return BM_ELEM_CD_GET_BOOL(l, offsets.select_vert);
|
||||
return uvedit_vert_select_get_no_sync(ts, bm, l);
|
||||
}
|
||||
|
||||
bool uvedit_uv_select_test(const Scene *scene,
|
||||
@@ -1006,7 +968,7 @@ void uvedit_uv_select_set_with_sticky(
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
if (ts->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
if (ED_uvedit_sync_uvselect_ignore(ts)) {
|
||||
uvedit_uv_select_set(scene, bm, l, select, offsets);
|
||||
uvedit_uv_select_set(scene, bm, l, select);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1015,7 +977,7 @@ void uvedit_uv_select_set_with_sticky(
|
||||
switch (sticky) {
|
||||
case UV_STICKY_DISABLE: {
|
||||
if (uvedit_face_visible_test(scene, l->f)) {
|
||||
uvedit_uv_select_set(scene, bm, l, select, offsets);
|
||||
uvedit_uv_select_set(scene, bm, l, select);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1061,7 +1023,7 @@ void uvedit_uv_select_shared_vert(const Scene *scene,
|
||||
}
|
||||
|
||||
if (do_select) {
|
||||
uvedit_uv_select_set(scene, bm, l_radial_iter, select, offsets);
|
||||
uvedit_uv_select_set(scene, bm, l_radial_iter, select);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1069,22 +1031,17 @@ void uvedit_uv_select_shared_vert(const Scene *scene,
|
||||
} while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, l->v)) != e_first);
|
||||
}
|
||||
|
||||
void uvedit_uv_select_set(const Scene *scene,
|
||||
BMesh *bm,
|
||||
BMLoop *l,
|
||||
const bool select,
|
||||
|
||||
const BMUVOffsets &offsets)
|
||||
void uvedit_uv_select_set(const Scene *scene, BMesh *bm, BMLoop *l, const bool select)
|
||||
{
|
||||
if (select) {
|
||||
uvedit_uv_select_enable(scene, bm, l, offsets);
|
||||
uvedit_uv_select_enable(scene, bm, l);
|
||||
}
|
||||
else {
|
||||
uvedit_uv_select_disable(scene, bm, l, offsets);
|
||||
uvedit_uv_select_disable(scene, bm, l);
|
||||
}
|
||||
}
|
||||
|
||||
void uvedit_uv_select_enable(const Scene *scene, BMesh *bm, BMLoop *l, const BMUVOffsets &offsets)
|
||||
void uvedit_uv_select_enable(const Scene *scene, BMesh *bm, BMLoop *l)
|
||||
{
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
|
||||
@@ -1106,12 +1063,11 @@ void uvedit_uv_select_enable(const Scene *scene, BMesh *bm, BMLoop *l, const BMU
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_assert(offsets.select_vert >= 0);
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true);
|
||||
uvedit_vert_select_set_no_sync(ts, bm, l, true);
|
||||
}
|
||||
}
|
||||
|
||||
void uvedit_uv_select_disable(const Scene *scene, BMesh *bm, BMLoop *l, const BMUVOffsets &offsets)
|
||||
void uvedit_uv_select_disable(const Scene *scene, BMesh *bm, BMLoop *l)
|
||||
{
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
|
||||
@@ -1129,8 +1085,7 @@ void uvedit_uv_select_disable(const Scene *scene, BMesh *bm, BMLoop *l, const BM
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_assert(offsets.select_vert >= 0);
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false);
|
||||
uvedit_vert_select_set_no_sync(ts, bm, l, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1195,23 +1150,17 @@ static BMLoop *uvedit_loop_find_other_boundary_loop_with_visible_face(const Scen
|
||||
/** \name Low Level Selection API
|
||||
* \{ */
|
||||
|
||||
bool uvedit_loop_vert_select_get(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
const BMLoop *l,
|
||||
const BMUVOffsets &offsets)
|
||||
bool uvedit_loop_vert_select_get(const ToolSettings *ts, const BMesh *bm, const BMLoop *l)
|
||||
{
|
||||
if (ts->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
BLI_assert(bm->uv_select_sync_valid);
|
||||
UNUSED_VARS_NDEBUG(bm);
|
||||
return BM_elem_flag_test_bool(l, BM_ELEM_SELECT_UV);
|
||||
}
|
||||
return BM_ELEM_CD_GET_BOOL(l, offsets.select_vert);
|
||||
return uvedit_vert_select_get_no_sync(ts, bm, l);
|
||||
}
|
||||
|
||||
bool uvedit_loop_edge_select_get(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
const BMLoop *l,
|
||||
const BMUVOffsets &offsets)
|
||||
bool uvedit_loop_edge_select_get(const ToolSettings *ts, const BMesh *bm, const BMLoop *l)
|
||||
{
|
||||
if (ts->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
BLI_assert(bm->uv_select_sync_valid);
|
||||
@@ -1220,14 +1169,13 @@ bool uvedit_loop_edge_select_get(const ToolSettings *ts,
|
||||
BLI_assert(!BM_elem_flag_test(l->f, BM_ELEM_HIDDEN));
|
||||
return BM_elem_flag_test_bool(l, BM_ELEM_SELECT_UV_EDGE);
|
||||
}
|
||||
return BM_ELEM_CD_GET_BOOL(l, offsets.select_edge);
|
||||
return uvedit_edge_select_get_no_sync(ts, bm, l);
|
||||
}
|
||||
|
||||
void uvedit_loop_vert_select_set(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
BMLoop *l,
|
||||
const bool select,
|
||||
const BMUVOffsets &offsets)
|
||||
const bool select)
|
||||
{
|
||||
if (ts->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
BLI_assert(bm->uv_select_sync_valid);
|
||||
@@ -1235,14 +1183,13 @@ void uvedit_loop_vert_select_set(const ToolSettings *ts,
|
||||
BM_elem_flag_set(l, BM_ELEM_SELECT_UV, select);
|
||||
return;
|
||||
}
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select);
|
||||
uvedit_vert_select_set_no_sync(ts, bm, l, select);
|
||||
}
|
||||
|
||||
void uvedit_loop_edge_select_set(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
BMLoop *l,
|
||||
const bool select,
|
||||
const BMUVOffsets &offsets)
|
||||
const bool select)
|
||||
{
|
||||
if (ts->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
BLI_assert(bm->uv_select_sync_valid);
|
||||
@@ -1250,7 +1197,7 @@ void uvedit_loop_edge_select_set(const ToolSettings *ts,
|
||||
BM_elem_flag_set(l, BM_ELEM_SELECT_UV_EDGE, select);
|
||||
return;
|
||||
}
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select);
|
||||
uvedit_edge_select_set_no_sync(ts, bm, l, select);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -1650,8 +1597,8 @@ void uvedit_select_prepare_custom_data(const Scene *scene, BMesh *bm)
|
||||
BLI_assert((ts->uv_flag & UV_FLAG_SELECT_SYNC) == 0);
|
||||
UNUSED_VARS_NDEBUG(ts);
|
||||
const char *active_uv_name = CustomData_get_active_layer_name(&bm->ldata, CD_PROP_FLOAT2);
|
||||
BM_uv_map_attr_vert_select_ensure(bm, active_uv_name);
|
||||
BM_uv_map_attr_edge_select_ensure(bm, active_uv_name);
|
||||
BLI_assert(active_uv_name);
|
||||
UNUSED_VARS_NDEBUG(active_uv_name);
|
||||
}
|
||||
|
||||
void uvedit_select_prepare_sync_select(const Scene *scene, BMesh *bm)
|
||||
@@ -1716,7 +1663,7 @@ bool uvedit_edge_is_face_select_any_other(const ToolSettings *ts,
|
||||
continue;
|
||||
}
|
||||
if (BM_loop_uv_share_edge_check(l, l_radial_iter, offsets.uv) &&
|
||||
uvedit_face_select_test_ex(ts, bm, l_radial_iter->f, offsets))
|
||||
uvedit_face_select_test_ex(ts, bm, l_radial_iter->f))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -1738,7 +1685,7 @@ bool uvedit_vert_is_face_select_any_other(const ToolSettings *ts,
|
||||
continue;
|
||||
}
|
||||
if (BM_loop_uv_share_vert_check(l, l_iter, offsets.uv) &&
|
||||
uvedit_face_select_test_ex(ts, bm, l_iter->f, offsets))
|
||||
uvedit_face_select_test_ex(ts, bm, l_iter->f))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -1759,7 +1706,7 @@ bool uvedit_vert_is_all_other_faces_selected(const ToolSettings *ts,
|
||||
continue;
|
||||
}
|
||||
if (BM_loop_uv_share_vert_check(l, l_iter, offsets.uv) &&
|
||||
!uvedit_face_select_test_ex(ts, bm, l_iter->f, offsets))
|
||||
!uvedit_face_select_test_ex(ts, bm, l_iter->f))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1767,11 +1714,9 @@ bool uvedit_vert_is_all_other_faces_selected(const ToolSettings *ts,
|
||||
return true;
|
||||
}
|
||||
|
||||
static void bm_clear_uv_vert_selection(const Scene *scene, BMesh *bm, const BMUVOffsets &offsets)
|
||||
static void bm_clear_uv_vert_selection(const Scene *scene, BMesh *bm)
|
||||
{
|
||||
if (offsets.select_vert == -1) {
|
||||
return;
|
||||
}
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
BMIter iter, liter;
|
||||
@@ -1780,13 +1725,75 @@ static void bm_clear_uv_vert_selection(const Scene *scene, BMesh *bm, const BMUV
|
||||
continue;
|
||||
}
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false);
|
||||
uvedit_vert_select_set_no_sync(ts, bm, l, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name UV Selection Non-Sync API
|
||||
*
|
||||
* \note this is for non-sync selection,
|
||||
* where different rules apply and there is no expectation a selected UV
|
||||
* implies it's base mesh selection flag also be set.
|
||||
*
|
||||
* \{ */
|
||||
|
||||
bool uvedit_vert_select_get_no_sync(const ToolSettings *ts, const BMesh *bm, const BMLoop *l)
|
||||
{
|
||||
BLI_assert(bm && (ts->uv_flag & UV_FLAG_SELECT_SYNC) == 0);
|
||||
UNUSED_VARS_NDEBUG(ts, bm);
|
||||
return BM_elem_flag_test_bool(l, BM_ELEM_SELECT_UV);
|
||||
}
|
||||
bool uvedit_edge_select_get_no_sync(const ToolSettings *ts, const BMesh *bm, const BMLoop *l)
|
||||
{
|
||||
BLI_assert(bm && (ts->uv_flag & UV_FLAG_SELECT_SYNC) == 0);
|
||||
UNUSED_VARS_NDEBUG(ts, bm);
|
||||
return BM_elem_flag_test_bool(l, BM_ELEM_SELECT_UV_EDGE);
|
||||
}
|
||||
bool uvedit_face_select_get_no_sync(const ToolSettings *ts, const BMesh *bm, const BMFace *f)
|
||||
{
|
||||
BLI_assert(bm && (ts->uv_flag & UV_FLAG_SELECT_SYNC) == 0);
|
||||
UNUSED_VARS_NDEBUG(ts, bm);
|
||||
return BM_elem_flag_test_bool(f, BM_ELEM_SELECT_UV);
|
||||
}
|
||||
|
||||
void uvedit_vert_select_set_no_sync(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
BMLoop *l,
|
||||
bool select)
|
||||
{
|
||||
BLI_assert(bm && (ts->uv_flag & UV_FLAG_SELECT_SYNC) == 0);
|
||||
BLI_assert(BM_elem_flag_test(l->f, BM_ELEM_HIDDEN) == 0);
|
||||
UNUSED_VARS_NDEBUG(ts, bm);
|
||||
BM_elem_flag_set(l, BM_ELEM_SELECT_UV, select);
|
||||
}
|
||||
void uvedit_edge_select_set_no_sync(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
BMLoop *l,
|
||||
bool select)
|
||||
{
|
||||
BLI_assert(bm && (ts->uv_flag & UV_FLAG_SELECT_SYNC) == 0);
|
||||
BLI_assert(BM_elem_flag_test(l->f, BM_ELEM_HIDDEN) == 0);
|
||||
UNUSED_VARS_NDEBUG(ts, bm);
|
||||
BM_elem_flag_set(l, BM_ELEM_SELECT_UV_EDGE, select);
|
||||
}
|
||||
|
||||
void uvedit_face_select_set_no_sync(const ToolSettings *ts,
|
||||
const BMesh *bm,
|
||||
BMFace *f,
|
||||
bool select)
|
||||
{
|
||||
BLI_assert(bm && (ts->uv_flag & UV_FLAG_SELECT_SYNC) == 0);
|
||||
BLI_assert(BM_elem_flag_test(f, BM_ELEM_HIDDEN) == 0);
|
||||
UNUSED_VARS_NDEBUG(ts, bm);
|
||||
BM_elem_flag_set(f, BM_ELEM_SELECT_UV, select);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name UV Select Abstraction API
|
||||
*
|
||||
@@ -1909,7 +1916,6 @@ void ED_uvedit_selectmode_flush(const Scene *scene, BMesh *bm)
|
||||
UNUSED_VARS_NDEBUG(ts);
|
||||
|
||||
uvedit_select_prepare_custom_data(scene, bm);
|
||||
const BMUVOffsets offsets = BM_uv_map_offsets_get(bm);
|
||||
|
||||
/* Vertex Mode only. */
|
||||
if (ts->uv_selectmode & UV_SELECT_VERT) {
|
||||
@@ -1920,11 +1926,34 @@ void ED_uvedit_selectmode_flush(const Scene *scene, BMesh *bm)
|
||||
if (!uvedit_face_visible_test(scene, efa)) {
|
||||
continue;
|
||||
}
|
||||
bool select_all = true;
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
bool edge_selected = BM_ELEM_CD_GET_BOOL(l, offsets.select_vert) &&
|
||||
BM_ELEM_CD_GET_BOOL(l->next, offsets.select_vert);
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, edge_selected);
|
||||
bool edge_selected = uvedit_vert_select_get_no_sync(ts, bm, l) &&
|
||||
uvedit_vert_select_get_no_sync(ts, bm, l->next);
|
||||
uvedit_edge_select_set_no_sync(ts, bm, l, edge_selected);
|
||||
if (!edge_selected) {
|
||||
select_all = false;
|
||||
}
|
||||
}
|
||||
uvedit_face_select_set_no_sync(ts, bm, efa, select_all);
|
||||
}
|
||||
}
|
||||
else if (ts->uv_selectmode & UV_SELECT_EDGE) {
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
BMIter iter, liter;
|
||||
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
|
||||
if (!uvedit_face_visible_test(scene, efa)) {
|
||||
continue;
|
||||
}
|
||||
bool select_all = true;
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (!uvedit_edge_select_get_no_sync(ts, bm, l)) {
|
||||
select_all = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
uvedit_face_select_set_no_sync(ts, bm, efa, select_all);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1941,7 +1970,6 @@ void uvedit_select_flush_from_verts(const Scene *scene, BMesh *bm, const bool se
|
||||
BLI_assert((ts->uv_flag & UV_FLAG_SELECT_SYNC) == 0);
|
||||
UNUSED_VARS_NDEBUG(ts);
|
||||
uvedit_select_prepare_custom_data(scene, bm);
|
||||
const BMUVOffsets offsets = BM_uv_map_offsets_get(bm);
|
||||
|
||||
if (select) {
|
||||
/* Careful when using this in face select mode.
|
||||
@@ -1953,12 +1981,19 @@ void uvedit_select_flush_from_verts(const Scene *scene, BMesh *bm, const bool se
|
||||
if (!uvedit_face_visible_test(scene, efa)) {
|
||||
continue;
|
||||
}
|
||||
bool select_all = true;
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (BM_ELEM_CD_GET_BOOL(l, offsets.select_vert) &&
|
||||
BM_ELEM_CD_GET_BOOL(l->next, offsets.select_vert))
|
||||
if (uvedit_vert_select_get_no_sync(ts, bm, l) &&
|
||||
uvedit_vert_select_get_no_sync(ts, bm, l->next))
|
||||
{
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true);
|
||||
uvedit_edge_select_set_no_sync(ts, bm, l, true);
|
||||
}
|
||||
else {
|
||||
select_all = false;
|
||||
}
|
||||
}
|
||||
if (select_all) {
|
||||
uvedit_face_select_set_no_sync(ts, bm, efa, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1970,13 +2005,18 @@ void uvedit_select_flush_from_verts(const Scene *scene, BMesh *bm, const bool se
|
||||
if (!uvedit_face_visible_test(scene, efa)) {
|
||||
continue;
|
||||
}
|
||||
bool select_all = true;
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (!BM_ELEM_CD_GET_BOOL(l, offsets.select_vert) ||
|
||||
!BM_ELEM_CD_GET_BOOL(l->next, offsets.select_vert))
|
||||
if (!uvedit_vert_select_get_no_sync(ts, bm, l) ||
|
||||
!uvedit_vert_select_get_no_sync(ts, bm, l->next))
|
||||
{
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false);
|
||||
uvedit_edge_select_set_no_sync(ts, bm, l, false);
|
||||
select_all = false;
|
||||
}
|
||||
}
|
||||
if (select_all == false) {
|
||||
uvedit_face_select_set_no_sync(ts, bm, efa, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2157,9 +2197,6 @@ static int uv_select_edgeloop(Scene *scene, Object *obedit, UvNearestHit *hit, c
|
||||
/* NOTE: this is a special case, even when sync select is enabled,
|
||||
* the flags are used then flushed to the vertices.
|
||||
* So these need to be ensured even though the layers aren't used afterwards. */
|
||||
const char *active_uv_name = CustomData_get_active_layer_name(&bm->ldata, CD_PROP_FLOAT2);
|
||||
BM_uv_map_attr_vert_select_ensure(bm, active_uv_name);
|
||||
BM_uv_map_attr_edge_select_ensure(bm, active_uv_name);
|
||||
const BMUVOffsets offsets = BM_uv_map_offsets_get(bm);
|
||||
|
||||
if (extend) {
|
||||
@@ -2268,7 +2305,7 @@ static int uv_select_faceloop(Scene *scene, Object *obedit, UvNearestHit *hit, c
|
||||
BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false);
|
||||
|
||||
if (extend) {
|
||||
select = !uvedit_face_select_test(scene, bm, hit->l->f, offsets);
|
||||
select = !uvedit_face_select_test(scene, bm, hit->l->f);
|
||||
}
|
||||
else {
|
||||
select = true;
|
||||
@@ -2505,7 +2542,7 @@ static void uv_select_linked_multi(Scene *scene,
|
||||
* - There are no connected fully selected faces UV-connected to this loop.
|
||||
*/
|
||||
BLI_assert(!select_faces);
|
||||
if (uvedit_face_select_test(scene, bm, l->f, offsets)) {
|
||||
if (uvedit_face_select_test(scene, bm, l->f)) {
|
||||
/* pass */
|
||||
}
|
||||
else {
|
||||
@@ -2513,7 +2550,7 @@ static void uv_select_linked_multi(Scene *scene,
|
||||
BMLoop *l_other;
|
||||
BM_ITER_ELEM (l_other, &liter_other, l->v, BM_LOOPS_OF_VERT) {
|
||||
if ((l != l_other) && !BM_loop_uv_share_vert_check(l, l_other, offsets.uv) &&
|
||||
uvedit_face_select_test(scene, bm, l_other->f, offsets))
|
||||
uvedit_face_select_test(scene, bm, l_other->f))
|
||||
{
|
||||
add_to_stack = false;
|
||||
break;
|
||||
@@ -2622,7 +2659,7 @@ static void uv_select_linked_multi(Scene *scene,
|
||||
} \
|
||||
} \
|
||||
else { \
|
||||
uvedit_face_select_set(scene, bm, efa, value, offsets); \
|
||||
uvedit_face_select_set(scene, bm, efa, value); \
|
||||
} \
|
||||
(void)0
|
||||
|
||||
@@ -2815,14 +2852,14 @@ static wmOperatorStatus uv_select_more_less(bContext *C, const bool select)
|
||||
int sel_state = 0;
|
||||
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (uvedit_loop_vert_select_get(ts, bm, l, offsets)) {
|
||||
if (uvedit_loop_vert_select_get(ts, bm, l)) {
|
||||
sel_state |= NEIGHBORING_FACE_IS_SEL;
|
||||
}
|
||||
else {
|
||||
sel_state |= CURR_FACE_IS_UNSEL;
|
||||
}
|
||||
|
||||
if (!uvedit_loop_edge_select_get(ts, bm, l, offsets)) {
|
||||
if (!uvedit_loop_edge_select_get(ts, bm, l)) {
|
||||
sel_state |= CURR_FACE_IS_UNSEL;
|
||||
}
|
||||
|
||||
@@ -2839,7 +2876,7 @@ static wmOperatorStatus uv_select_more_less(bContext *C, const bool select)
|
||||
#undef CURR_FACE_IS_UNSEL
|
||||
}
|
||||
else {
|
||||
if (!uvedit_face_select_test(scene, bm, efa, offsets)) {
|
||||
if (!uvedit_face_select_test(scene, bm, efa)) {
|
||||
continue;
|
||||
}
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
@@ -2868,7 +2905,7 @@ static wmOperatorStatus uv_select_more_less(bContext *C, const bool select)
|
||||
if (uvedit_face_visible_test(scene, efa)) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
|
||||
if (uvedit_loop_vert_select_get(ts, bm, l, offsets) == select) {
|
||||
if (uvedit_loop_vert_select_get(ts, bm, l) == select) {
|
||||
BM_elem_flag_enable(l->next, BM_ELEM_TAG);
|
||||
BM_elem_flag_enable(l->prev, BM_ELEM_TAG);
|
||||
changed = true;
|
||||
@@ -2967,14 +3004,12 @@ bool uvedit_select_is_any_selected(const Scene *scene, BMesh *bm)
|
||||
return (bm->totvertsel || bm->totedgesel || bm->totfacesel);
|
||||
}
|
||||
|
||||
const BMUVOffsets offsets = BM_uv_map_offsets_get(bm);
|
||||
|
||||
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
|
||||
if (!uvedit_face_visible_test(scene, efa)) {
|
||||
continue;
|
||||
}
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (BM_ELEM_CD_GET_BOOL(l, offsets.select_vert)) {
|
||||
if (uvedit_vert_select_get_no_sync(ts, bm, l)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -3018,15 +3053,15 @@ static void uv_select_all(const Scene *scene, BMEditMesh *em, bool select_all)
|
||||
BMIter iter, liter;
|
||||
|
||||
uvedit_select_prepare_custom_data(scene, bm);
|
||||
const BMUVOffsets offsets = BM_uv_map_offsets_get(bm);
|
||||
|
||||
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
|
||||
if (!uvedit_face_visible_test(scene, efa)) {
|
||||
continue;
|
||||
}
|
||||
uvedit_face_select_set_no_sync(ts, bm, efa, select_all);
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select_all);
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select_all);
|
||||
uvedit_vert_select_set_no_sync(ts, bm, l, select_all);
|
||||
uvedit_edge_select_set_no_sync(ts, bm, l, select_all);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3134,7 +3169,6 @@ static void uv_select_invert(const Scene *scene, BMEditMesh *em)
|
||||
}
|
||||
|
||||
uvedit_select_prepare_custom_data(scene, bm);
|
||||
const BMUVOffsets offsets = BM_uv_map_offsets_get(bm);
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
BMIter iter, liter;
|
||||
@@ -3143,21 +3177,29 @@ static void uv_select_invert(const Scene *scene, BMEditMesh *em)
|
||||
if (!uvedit_face_visible_test(scene, efa)) {
|
||||
continue;
|
||||
}
|
||||
bool select_all = true;
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (uv_selectmode & (UV_SELECT_EDGE | UV_SELECT_FACE)) {
|
||||
/* Use UV edge selection to find vertices and edges that must be selected. */
|
||||
bool es = BM_ELEM_CD_GET_BOOL(l, offsets.select_edge);
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, !es);
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false);
|
||||
bool es = !uvedit_edge_select_get_no_sync(ts, bm, l);
|
||||
uvedit_edge_select_set_no_sync(ts, bm, l, es);
|
||||
uvedit_vert_select_set_no_sync(ts, bm, l, false);
|
||||
if (es == false) {
|
||||
select_all = false;
|
||||
}
|
||||
}
|
||||
/* Use UV vertex selection to find vertices and edges that must be selected. */
|
||||
else {
|
||||
BLI_assert(uv_selectmode & UV_SELECT_VERT);
|
||||
bool vs = BM_ELEM_CD_GET_BOOL(l, offsets.select_vert);
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, !vs);
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false);
|
||||
bool vs = !uvedit_vert_select_get_no_sync(ts, bm, l);
|
||||
uvedit_vert_select_set_no_sync(ts, bm, l, vs);
|
||||
uvedit_edge_select_set_no_sync(ts, bm, l, false);
|
||||
if (vs == false) {
|
||||
select_all = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
uvedit_face_select_set_no_sync(ts, bm, efa, select_all);
|
||||
}
|
||||
|
||||
/* Flush based on uv vert/edge flags and current UV select mode */
|
||||
@@ -3373,7 +3415,7 @@ static bool uv_mouse_select_multi(bContext *C,
|
||||
const BMUVOffsets offsets = BM_uv_map_offsets_get(bm);
|
||||
|
||||
if (selectmode == UV_SELECT_FACE) {
|
||||
is_selected = uvedit_face_select_test(scene, bm, hit.efa, offsets);
|
||||
is_selected = uvedit_face_select_test(scene, bm, hit.efa);
|
||||
}
|
||||
else if (selectmode == UV_SELECT_EDGE) {
|
||||
is_selected = uvedit_edge_select_test(scene, bm, hit.l, offsets);
|
||||
@@ -3385,7 +3427,7 @@ static bool uv_mouse_select_multi(bContext *C,
|
||||
is_selected = uvedit_uv_select_test(scene, bm, hit.l, offsets);
|
||||
}
|
||||
else {
|
||||
is_selected = uvedit_face_select_test(scene, bm, hit.efa, offsets);
|
||||
is_selected = uvedit_face_select_test(scene, bm, hit.efa);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4042,7 +4084,6 @@ static wmOperatorStatus uv_select_split_exec(bContext *C, wmOperator *op)
|
||||
else {
|
||||
uvedit_select_prepare_custom_data(scene, bm);
|
||||
}
|
||||
const BMUVOffsets offsets = BM_uv_map_offsets_get(bm);
|
||||
|
||||
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
|
||||
bool is_sel = false;
|
||||
@@ -4054,8 +4095,8 @@ static wmOperatorStatus uv_select_split_exec(bContext *C, wmOperator *op)
|
||||
|
||||
/* are we all selected? */
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
const bool select_vert = uvedit_loop_vert_select_get(ts, bm, l, offsets);
|
||||
const bool select_edge = uvedit_loop_edge_select_get(ts, bm, l, offsets);
|
||||
const bool select_vert = uvedit_loop_vert_select_get(ts, bm, l);
|
||||
const bool select_edge = uvedit_loop_edge_select_get(ts, bm, l);
|
||||
|
||||
if (select_vert || select_edge) {
|
||||
is_sel = true;
|
||||
@@ -4074,8 +4115,8 @@ static wmOperatorStatus uv_select_split_exec(bContext *C, wmOperator *op)
|
||||
/* No need to deselect the face (with sync-select) as it wont be selected,
|
||||
* since it already has a mixed selection. */
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
uvedit_loop_vert_select_set(ts, bm, l, false, offsets);
|
||||
uvedit_loop_edge_select_set(ts, bm, l, false, offsets);
|
||||
uvedit_loop_vert_select_set(ts, bm, l, false);
|
||||
uvedit_loop_edge_select_set(ts, bm, l, false);
|
||||
}
|
||||
|
||||
changed = true;
|
||||
@@ -4136,7 +4177,7 @@ static void uv_select_tag_update_for_object(Depsgraph *depsgraph,
|
||||
static void uvedit_uv_select_flush_from_tag_sticky_loc_internal(
|
||||
const Scene *scene, BMesh *bm, BMLoop *l, const bool select, const BMUVOffsets &offsets)
|
||||
{
|
||||
uvedit_uv_select_set(scene, bm, l, select, offsets);
|
||||
uvedit_uv_select_set(scene, bm, l, select);
|
||||
|
||||
BMVert *v = l->v;
|
||||
BLI_assert(v->e);
|
||||
@@ -4156,7 +4197,7 @@ static void uvedit_uv_select_flush_from_tag_sticky_loc_internal(
|
||||
continue;
|
||||
}
|
||||
if (BM_loop_uv_share_vert_check(l, l_iter, offsets.uv)) {
|
||||
uvedit_uv_select_set(scene, bm, l_iter, select, offsets);
|
||||
uvedit_uv_select_set(scene, bm, l_iter, select);
|
||||
}
|
||||
} while ((l_iter = l_iter->radial_next) != l_first);
|
||||
} while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v)) != e_first);
|
||||
@@ -4215,9 +4256,12 @@ static void uv_select_flush_from_tag_face(const Scene *scene, Object *obedit, co
|
||||
if (ts->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
BM_face_uvselect_set_noflush(bm, efa, select);
|
||||
}
|
||||
else {
|
||||
uvedit_face_select_set_no_sync(ts, bm, efa, select);
|
||||
}
|
||||
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
uvedit_loop_edge_select_set(ts, bm, l, select, offsets);
|
||||
uvedit_loop_edge_select_set(ts, bm, l, select);
|
||||
|
||||
if (select) {
|
||||
uvedit_uv_select_flush_from_tag_sticky_loc_internal(scene, bm, l, select, offsets);
|
||||
@@ -4235,7 +4279,7 @@ static void uv_select_flush_from_tag_face(const Scene *scene, Object *obedit, co
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) {
|
||||
continue;
|
||||
}
|
||||
uvedit_face_select_set(scene, bm, efa, select, offsets);
|
||||
uvedit_face_select_set(scene, bm, efa, select);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4290,18 +4334,50 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co
|
||||
|
||||
/* now select tagged verts */
|
||||
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
|
||||
bool tag_all = true;
|
||||
bool tag_any = false;
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (BM_elem_flag_test(l->v, BM_ELEM_TAG)) {
|
||||
uvedit_uv_select_set(scene, bm, l, select, offsets);
|
||||
uvedit_uv_select_set(scene, bm, l, select);
|
||||
tag_any = true;
|
||||
}
|
||||
else {
|
||||
tag_all = false;
|
||||
}
|
||||
}
|
||||
if (select) {
|
||||
if (tag_all && uvedit_face_visible_test(scene, efa)) {
|
||||
uvedit_face_select_set_no_sync(ts, bm, efa, true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tag_any && uvedit_face_visible_test(scene, efa)) {
|
||||
uvedit_face_select_set_no_sync(ts, bm, efa, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((use_mesh_select == false) && (ts->uv_sticky == UV_STICKY_LOCATION)) {
|
||||
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
|
||||
bool tag_all = true;
|
||||
bool tag_any = false;
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (BM_elem_flag_test(l, BM_ELEM_TAG)) {
|
||||
uvedit_uv_select_flush_from_tag_sticky_loc_internal(scene, bm, l, select, offsets);
|
||||
tag_any = true;
|
||||
}
|
||||
else {
|
||||
tag_all = false;
|
||||
}
|
||||
}
|
||||
if (select) {
|
||||
if (tag_all && uvedit_face_visible_test(scene, efa)) {
|
||||
uvedit_face_select_set_no_sync(ts, bm, efa, true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tag_any && uvedit_face_visible_test(scene, efa)) {
|
||||
uvedit_face_select_set_no_sync(ts, bm, efa, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4310,7 +4386,7 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co
|
||||
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (BM_elem_flag_test(l, BM_ELEM_TAG)) {
|
||||
uvedit_uv_select_set(scene, bm, l, select, offsets);
|
||||
uvedit_uv_select_set(scene, bm, l, select);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4358,7 +4434,7 @@ static void uv_select_flush_from_loop_edge_flag(const Scene *scene, BMesh *bm)
|
||||
/* Use UV edge selection to identify which verts must to be selected */
|
||||
|
||||
/* Clear UV vert flags */
|
||||
bm_clear_uv_vert_selection(scene, bm, offsets);
|
||||
bm_clear_uv_vert_selection(scene, bm);
|
||||
|
||||
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
|
||||
if (!uvedit_face_visible_test(scene, efa)) {
|
||||
@@ -4368,7 +4444,7 @@ static void uv_select_flush_from_loop_edge_flag(const Scene *scene, BMesh *bm)
|
||||
}
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
/* Select verts based on UV edge flag. */
|
||||
if (BM_ELEM_CD_GET_BOOL(l, offsets.select_edge)) {
|
||||
if (uvedit_edge_select_get_no_sync(ts, bm, l)) {
|
||||
uvedit_uv_select_flush_from_tag_sticky_loc_internal(scene, bm, l, true, offsets);
|
||||
uvedit_uv_select_flush_from_tag_sticky_loc_internal(scene, bm, l->next, true, offsets);
|
||||
}
|
||||
@@ -4381,16 +4457,18 @@ static void uv_select_flush_from_loop_edge_flag(const Scene *scene, BMesh *bm)
|
||||
}
|
||||
else {
|
||||
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
|
||||
bool select_all = true;
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
|
||||
if (BM_ELEM_CD_GET_BOOL(l, offsets.select_edge)) {
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true);
|
||||
BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, true);
|
||||
if (uvedit_edge_select_get_no_sync(ts, bm, l)) {
|
||||
uvedit_vert_select_set_no_sync(ts, bm, l, true);
|
||||
uvedit_vert_select_set_no_sync(ts, bm, l->next, true);
|
||||
}
|
||||
else if (!BM_ELEM_CD_GET_BOOL(l->prev, offsets.select_edge)) {
|
||||
BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, false);
|
||||
else if (!uvedit_edge_select_get_no_sync(ts, bm, l->prev)) {
|
||||
uvedit_vert_select_set_no_sync(ts, bm, l->next, false);
|
||||
select_all = false;
|
||||
}
|
||||
}
|
||||
uvedit_face_select_set_no_sync(ts, bm, efa, select_all);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4455,7 +4533,7 @@ static wmOperatorStatus uv_box_select_exec(bContext *C, wmOperator *op)
|
||||
uvedit_select_prepare_custom_data(scene, bm);
|
||||
if (pinned) {
|
||||
const char *active_uv_name = CustomData_get_active_layer_name(&bm->ldata, CD_PROP_FLOAT2);
|
||||
BM_uv_map_attr_pin_ensure(bm, active_uv_name);
|
||||
BM_uv_map_attr_pin_ensure_named(bm, active_uv_name);
|
||||
}
|
||||
}
|
||||
const BMUVOffsets offsets = BM_uv_map_offsets_get(bm);
|
||||
@@ -4570,14 +4648,14 @@ static wmOperatorStatus uv_box_select_exec(bContext *C, wmOperator *op)
|
||||
if (!pinned || (ts->uv_flag & UV_FLAG_SELECT_SYNC)) {
|
||||
/* UV_FLAG_SELECT_SYNC - can't do pinned selection */
|
||||
if (BLI_rctf_isect_pt_v(&rectf, luv)) {
|
||||
uvedit_uv_select_set(scene, bm, l, select, offsets);
|
||||
uvedit_uv_select_set(scene, bm, l, select);
|
||||
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
|
||||
has_selected = true;
|
||||
}
|
||||
}
|
||||
else if (pinned) {
|
||||
if (BM_ELEM_CD_GET_BOOL(l, offsets.pin) && BLI_rctf_isect_pt_v(&rectf, luv)) {
|
||||
uvedit_uv_select_set(scene, bm, l, select, offsets);
|
||||
uvedit_uv_select_set(scene, bm, l, select);
|
||||
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
@@ -4590,7 +4668,7 @@ static wmOperatorStatus uv_box_select_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
|
||||
if (ts->uv_sticky == UV_STICKY_VERT) {
|
||||
uvedit_vertex_select_tagged(bm, scene, select, offsets);
|
||||
uvedit_vertex_select_tagged(bm, scene, select);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4749,7 +4827,7 @@ static wmOperatorStatus uv_circle_select_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
else {
|
||||
BM_elem_flag_disable(efa, BM_ELEM_TAG);
|
||||
if (select == uvedit_face_select_test(scene, bm, efa, offsets)) {
|
||||
if (select == uvedit_face_select_test(scene, bm, efa)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -4813,7 +4891,7 @@ static wmOperatorStatus uv_circle_select_exec(bContext *C, wmOperator *op)
|
||||
luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
|
||||
if (uv_circle_select_is_point_inside(luv, offset, ellipse)) {
|
||||
changed = true;
|
||||
uvedit_uv_select_set(scene, bm, l, select, offsets);
|
||||
uvedit_uv_select_set(scene, bm, l, select);
|
||||
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
|
||||
has_selected = true;
|
||||
}
|
||||
@@ -4826,7 +4904,7 @@ static wmOperatorStatus uv_circle_select_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
|
||||
if (ts->uv_sticky == UV_STICKY_VERT) {
|
||||
uvedit_vertex_select_tagged(bm, scene, select, offsets);
|
||||
uvedit_vertex_select_tagged(bm, scene, select);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4968,7 +5046,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const Span<int2> mcoords, const
|
||||
}
|
||||
else {
|
||||
BM_elem_flag_disable(efa, BM_ELEM_TAG);
|
||||
if (select == uvedit_face_select_test(scene, bm, efa, offsets)) {
|
||||
if (select == uvedit_face_select_test(scene, bm, efa)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -5062,7 +5140,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const Span<int2> mcoords, const
|
||||
if (select != uvedit_uv_select_test(scene, bm, l, offsets)) {
|
||||
float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
|
||||
if (do_lasso_select_mesh_uv_is_point_inside(region, &rect, mcoords, luv)) {
|
||||
uvedit_uv_select_set(scene, bm, l, select, offsets);
|
||||
uvedit_uv_select_set(scene, bm, l, select);
|
||||
changed = true;
|
||||
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
|
||||
has_selected = true;
|
||||
@@ -5076,7 +5154,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const Span<int2> mcoords, const
|
||||
}
|
||||
|
||||
if (ts->uv_sticky == UV_STICKY_VERT) {
|
||||
uvedit_vertex_select_tagged(bm, scene, select, offsets);
|
||||
uvedit_vertex_select_tagged(bm, scene, select);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5182,7 +5260,7 @@ static wmOperatorStatus uv_select_pinned_exec(bContext *C, wmOperator *op)
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
|
||||
if (BM_ELEM_CD_GET_BOOL(l, offsets.pin)) {
|
||||
uvedit_uv_select_enable(scene, bm, l, offsets);
|
||||
uvedit_uv_select_enable(scene, bm, l);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
@@ -5446,20 +5524,9 @@ static wmOperatorStatus uv_select_overlap(bContext *C, const bool extend)
|
||||
if (scene->toolsettings->uv_flag & UV_FLAG_SELECT_SYNC) {
|
||||
/* Pass. */
|
||||
}
|
||||
else {
|
||||
const char *uv_a_name = CustomData_get_active_layer_name(&bm_a->ldata, CD_PROP_FLOAT2);
|
||||
const char *uv_b_name = CustomData_get_active_layer_name(&bm_b->ldata, CD_PROP_FLOAT2);
|
||||
BM_uv_map_attr_vert_select_ensure(bm_a, uv_a_name);
|
||||
BM_uv_map_attr_vert_select_ensure(bm_b, uv_b_name);
|
||||
BM_uv_map_attr_edge_select_ensure(bm_a, uv_a_name);
|
||||
BM_uv_map_attr_edge_select_ensure(bm_b, uv_b_name);
|
||||
}
|
||||
const BMUVOffsets offsets_a = BM_uv_map_offsets_get(bm_a);
|
||||
const BMUVOffsets offsets_b = BM_uv_map_offsets_get(bm_b);
|
||||
|
||||
/* Skip if both faces are already selected. */
|
||||
if (uvedit_face_select_test(scene, bm_a, face_a, offsets_a) &&
|
||||
uvedit_face_select_test(scene, bm_b, face_b, offsets_b))
|
||||
if (uvedit_face_select_test(scene, bm_a, face_a) &&
|
||||
uvedit_face_select_test(scene, bm_b, face_b))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -5467,8 +5534,8 @@ static wmOperatorStatus uv_select_overlap(bContext *C, const bool extend)
|
||||
/* Main tri-tri overlap test. */
|
||||
const float endpoint_bias = -1e-4f;
|
||||
if (overlap_tri_tri_uv_test(o_a->tri, o_b->tri, endpoint_bias)) {
|
||||
uvedit_face_select_enable(scene, bm_a, face_a, offsets_a);
|
||||
uvedit_face_select_enable(scene, bm_b, face_b, offsets_b);
|
||||
uvedit_face_select_enable(scene, bm_a, face_a);
|
||||
uvedit_face_select_enable(scene, bm_b, face_b);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5786,7 +5853,7 @@ static wmOperatorStatus uv_select_similar_vert_exec(bContext *C, wmOperator *op)
|
||||
const float needle = get_uv_vert_needle(type, l->v, ob_m3, l, offsets);
|
||||
bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare);
|
||||
if (select) {
|
||||
uvedit_uv_select_set(scene, bm, l, select, offsets);
|
||||
uvedit_uv_select_set(scene, bm, l, select);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
@@ -5913,7 +5980,7 @@ static wmOperatorStatus uv_select_similar_edge_exec(bContext *C, wmOperator *op)
|
||||
float needle = get_uv_edge_needle(type, l->e, ob_m3, l, l->next, offsets);
|
||||
bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare);
|
||||
if (select) {
|
||||
uvedit_edge_select_set(scene, bm, l, select, offsets);
|
||||
uvedit_edge_select_set(scene, bm, l, select);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
@@ -5981,7 +6048,7 @@ static wmOperatorStatus uv_select_similar_face_exec(bContext *C, wmOperator *op)
|
||||
if (!uvedit_face_visible_test(scene, face)) {
|
||||
continue;
|
||||
}
|
||||
if (!uvedit_face_select_test(scene, bm, face, offsets)) {
|
||||
if (!uvedit_face_select_test(scene, bm, face)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -6023,7 +6090,7 @@ static wmOperatorStatus uv_select_similar_face_exec(bContext *C, wmOperator *op)
|
||||
if (!uvedit_face_visible_test(scene, face)) {
|
||||
continue;
|
||||
}
|
||||
if (uvedit_face_select_test(scene, bm, face, offsets)) {
|
||||
if (uvedit_face_select_test(scene, bm, face)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -6031,7 +6098,7 @@ static wmOperatorStatus uv_select_similar_face_exec(bContext *C, wmOperator *op)
|
||||
|
||||
bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare);
|
||||
if (select) {
|
||||
uvedit_face_select_set(scene, bm, face, select, offsets);
|
||||
uvedit_face_select_set(scene, bm, face, select);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
@@ -6059,7 +6126,7 @@ static wmOperatorStatus uv_select_similar_face_exec(bContext *C, wmOperator *op)
|
||||
static bool uv_island_selected(const Scene *scene, const BMesh *bm, FaceIsland *island)
|
||||
{
|
||||
BLI_assert(island && island->faces_len);
|
||||
return uvedit_face_select_test(scene, bm, island->faces[0], island->offsets);
|
||||
return uvedit_face_select_test(scene, bm, island->faces[0]);
|
||||
}
|
||||
|
||||
static wmOperatorStatus uv_select_similar_island_exec(bContext *C, wmOperator *op)
|
||||
@@ -6146,7 +6213,7 @@ static wmOperatorStatus uv_select_similar_island_exec(bContext *C, wmOperator *o
|
||||
continue;
|
||||
}
|
||||
for (int j = 0; j < island->faces_len; j++) {
|
||||
uvedit_face_select_set(scene, bm, island->faces[j], select, island->offsets);
|
||||
uvedit_face_select_set(scene, bm, island->faces[j], select);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
@@ -6312,8 +6379,6 @@ void UV_OT_select_similar(wmOperatorType *ot)
|
||||
|
||||
BMFace **ED_uvedit_selected_faces(const Scene *scene, BMesh *bm, int len_max, int *r_faces_len)
|
||||
{
|
||||
const BMUVOffsets offsets = BM_uv_map_offsets_get(bm);
|
||||
|
||||
CLAMP_MAX(len_max, bm->totface);
|
||||
int faces_len = 0;
|
||||
BMFace **faces = MEM_malloc_arrayN<BMFace *>(len_max, __func__);
|
||||
@@ -6322,7 +6387,7 @@ BMFace **ED_uvedit_selected_faces(const Scene *scene, BMesh *bm, int len_max, in
|
||||
BMFace *f;
|
||||
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
|
||||
if (uvedit_face_visible_test(scene, f)) {
|
||||
if (uvedit_face_select_test(scene, bm, f, offsets)) {
|
||||
if (uvedit_face_select_test(scene, bm, f)) {
|
||||
faces[faces_len++] = f;
|
||||
if (faces_len == len_max) {
|
||||
goto finally;
|
||||
@@ -6399,8 +6464,8 @@ finally:
|
||||
|
||||
BMLoop **ED_uvedit_selected_verts(const Scene *scene, BMesh *bm, int len_max, int *r_verts_len)
|
||||
{
|
||||
const ToolSettings *ts = scene->toolsettings;
|
||||
const BMUVOffsets offsets = BM_uv_map_offsets_get(bm);
|
||||
BLI_assert(offsets.select_vert >= 0);
|
||||
BLI_assert(offsets.uv >= 0);
|
||||
|
||||
CLAMP_MAX(len_max, bm->totloop);
|
||||
@@ -6425,7 +6490,7 @@ BMLoop **ED_uvedit_selected_verts(const Scene *scene, BMesh *bm, int len_max, in
|
||||
BMLoop *l_iter;
|
||||
BM_ITER_ELEM (l_iter, &liter, f, BM_LOOPS_OF_FACE) {
|
||||
if (!BM_elem_flag_test(l_iter, BM_ELEM_TAG)) {
|
||||
if (BM_ELEM_CD_GET_BOOL(l_iter, offsets.select_vert)) {
|
||||
if (uvedit_vert_select_get_no_sync(ts, bm, l_iter)) {
|
||||
BM_elem_flag_enable(l_iter->v, BM_ELEM_TAG);
|
||||
|
||||
verts[verts_len++] = l_iter;
|
||||
@@ -6514,10 +6579,10 @@ void ED_uvedit_selectmode_clean(const Scene *scene, Object *obedit)
|
||||
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
|
||||
BM_elem_flag_disable(efa, BM_ELEM_TAG);
|
||||
if (uvedit_face_visible_test(scene, efa)) {
|
||||
if (uvedit_face_select_test(scene, bm, efa, offsets)) {
|
||||
if (uvedit_face_select_test(scene, bm, efa)) {
|
||||
BM_elem_flag_enable(efa, BM_ELEM_TAG);
|
||||
}
|
||||
uvedit_face_select_set(scene, bm, efa, false, offsets);
|
||||
uvedit_face_select_set(scene, bm, efa, false);
|
||||
}
|
||||
}
|
||||
uv_select_flush_from_tag_face(scene, obedit, true);
|
||||
@@ -6525,7 +6590,6 @@ void ED_uvedit_selectmode_clean(const Scene *scene, Object *obedit)
|
||||
|
||||
ED_uvedit_selectmode_flush(scene, bm);
|
||||
}
|
||||
|
||||
void ED_uvedit_selectmode_clean_multi(bContext *C)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
|
||||
@@ -920,7 +920,7 @@ static void stitch_propagate_uv_final_position(Scene *scene,
|
||||
if (final) {
|
||||
copy_v2_v2(luv, final_position[index].uv);
|
||||
|
||||
uvedit_uv_select_enable(scene, state->em->bm, l, offsets);
|
||||
uvedit_uv_select_enable(scene, state->em->bm, l);
|
||||
}
|
||||
else {
|
||||
int face_preview_pos =
|
||||
|
||||
@@ -104,19 +104,16 @@ static bool uvedit_ensure_uvs(Object *obedit)
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
|
||||
BM_uv_map_attr_vert_select_ensure(em->bm, active_uv_name);
|
||||
BM_uv_map_attr_edge_select_ensure(em->bm, active_uv_name);
|
||||
const BMUVOffsets offsets = BM_uv_map_offsets_get(em->bm);
|
||||
|
||||
/* select new UVs (ignore UV_FLAG_SELECT_SYNC in this case) */
|
||||
em->bm->uv_select_sync_valid = false;
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BMIter liter;
|
||||
BMLoop *l;
|
||||
|
||||
BM_elem_flag_enable(l->f, BM_ELEM_SELECT_UV);
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true);
|
||||
BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true);
|
||||
BM_elem_flag_enable(l, BM_ELEM_SELECT_UV);
|
||||
BM_elem_flag_enable(l, BM_ELEM_SELECT_UV_EDGE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2667,7 +2664,7 @@ static void uv_map_clip_correct(const Scene *scene,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (only_selected_uvs && !uvedit_face_select_test(scene, em->bm, efa, offsets)) {
|
||||
if (only_selected_uvs && !uvedit_face_select_test(scene, em->bm, efa)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2684,7 +2681,7 @@ static void uv_map_clip_correct(const Scene *scene,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (only_selected_uvs && !uvedit_face_select_test(scene, em->bm, efa, offsets)) {
|
||||
if (only_selected_uvs && !uvedit_face_select_test(scene, em->bm, efa)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2722,7 +2719,7 @@ static void uv_map_clip_correct(const Scene *scene,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (only_selected_uvs && !uvedit_face_select_test(scene, em->bm, efa, offsets)) {
|
||||
if (only_selected_uvs && !uvedit_face_select_test(scene, em->bm, efa)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3258,8 +3255,8 @@ static wmOperatorStatus smart_project_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
|
||||
if (only_selected_uvs) {
|
||||
if (!uvedit_face_select_test(scene, em->bm, efa, offsets)) {
|
||||
uvedit_face_select_disable(scene, em->bm, efa, offsets);
|
||||
if (!uvedit_face_select_test(scene, em->bm, efa)) {
|
||||
uvedit_face_select_disable(scene, em->bm, efa);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -3851,8 +3848,8 @@ static float uv_sphere_project(const Scene *scene,
|
||||
}
|
||||
|
||||
if (only_selected_uvs) {
|
||||
if (!uvedit_face_select_test(scene, bm, efa, offsets)) {
|
||||
uvedit_face_select_disable(scene, bm, efa, offsets);
|
||||
if (!uvedit_face_select_test(scene, bm, efa)) {
|
||||
uvedit_face_select_disable(scene, bm, efa);
|
||||
continue; /* Unselected UV, ignore. */
|
||||
}
|
||||
}
|
||||
@@ -4027,8 +4024,8 @@ static float uv_cylinder_project(const Scene *scene,
|
||||
}
|
||||
|
||||
if (only_selected_uvs) {
|
||||
if (!uvedit_face_select_test(scene, bm, efa, offsets)) {
|
||||
uvedit_face_select_disable(scene, bm, efa, offsets);
|
||||
if (!uvedit_face_select_test(scene, bm, efa)) {
|
||||
uvedit_face_select_disable(scene, bm, efa);
|
||||
continue; /* Unselected UV, ignore. */
|
||||
}
|
||||
}
|
||||
@@ -4123,8 +4120,8 @@ static wmOperatorStatus cylinder_project_exec(bContext *C, wmOperator *op)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (only_selected_uvs && !uvedit_face_select_test(scene, em->bm, efa, offsets)) {
|
||||
uvedit_face_select_disable(scene, em->bm, efa, offsets);
|
||||
if (only_selected_uvs && !uvedit_face_select_test(scene, em->bm, efa)) {
|
||||
uvedit_face_select_disable(scene, em->bm, efa);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -4208,8 +4205,8 @@ static void uvedit_unwrap_cube_project(const Scene *scene,
|
||||
if (use_select && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
|
||||
continue;
|
||||
}
|
||||
if (only_selected_uvs && !uvedit_face_select_test(scene, bm, efa, offsets)) {
|
||||
uvedit_face_select_disable(scene, bm, efa, offsets);
|
||||
if (only_selected_uvs && !uvedit_face_select_test(scene, bm, efa)) {
|
||||
uvedit_face_select_disable(scene, bm, efa);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -4340,7 +4337,7 @@ void ED_uvedit_add_simple_uvs(Main *bmain, const Scene *scene, Object *ob)
|
||||
BM_mesh_bm_from_me(bm, mesh, &bm_from_me_params);
|
||||
|
||||
/* Select all UVs for cube_project. */
|
||||
ED_uvedit_select_all(bm);
|
||||
ED_uvedit_select_all(scene->toolsettings, bm);
|
||||
/* A cube size of 2.0 maps [-1..1] vertex coords to [0.0..1.0] in UV coords. */
|
||||
uvedit_unwrap_cube_project(scene, bm, 2.0, false, false, nullptr);
|
||||
|
||||
|
||||
@@ -514,7 +514,11 @@ enum {
|
||||
ME_FLAG_UNUSED_0 = 1 << 0, /* cleared */
|
||||
ME_FLAG_UNUSED_1 = 1 << 1, /* cleared */
|
||||
ME_FLAG_DEPRECATED_2 = 1 << 2, /* deprecated */
|
||||
ME_FLAG_UNUSED_3 = 1 << 3, /* cleared */
|
||||
/**
|
||||
* The UV selection is marked as synchronized.
|
||||
* See #BMesh::uv_select_sync_valid for details.
|
||||
*/
|
||||
ME_FLAG_UV_SELECT_SYNC_VALID = 1 << 3,
|
||||
ME_FLAG_UNUSED_4 = 1 << 4, /* cleared */
|
||||
ME_AUTOSMOOTH_LEGACY = 1 << 5, /* deprecated */
|
||||
ME_FLAG_UNUSED_6 = 1 << 6, /* cleared */
|
||||
|
||||
@@ -951,54 +951,6 @@ static PointerRNA bool_layer_ensure(PointerRNA *ptr,
|
||||
return RNA_pointer_create_discrete(&mesh->id, &RNA_BoolAttribute, bool_layer);
|
||||
}
|
||||
|
||||
/* Collection accessors for vert_select. */
|
||||
static void rna_MeshUVLoopLayer_vert_select_begin(CollectionPropertyIterator *iter,
|
||||
PointerRNA *ptr)
|
||||
{
|
||||
bool_layer_begin(iter, ptr, BKE_uv_map_vert_select_name_get);
|
||||
}
|
||||
|
||||
static bool rna_MeshUVLoopLayer_vert_select_lookup_int(PointerRNA *ptr,
|
||||
int index,
|
||||
PointerRNA *r_ptr)
|
||||
{
|
||||
return bool_layer_lookup_int(ptr, index, r_ptr, BKE_uv_map_vert_select_name_get);
|
||||
}
|
||||
|
||||
static int rna_MeshUVLoopLayer_vert_select_length(PointerRNA *ptr)
|
||||
{
|
||||
return bool_layer_length(ptr, BKE_uv_map_vert_select_name_get);
|
||||
}
|
||||
|
||||
static PointerRNA rna_MeshUVLoopLayer_vert_select_ensure(PointerRNA ptr)
|
||||
{
|
||||
return bool_layer_ensure(&ptr, BKE_uv_map_vert_select_name_get);
|
||||
}
|
||||
|
||||
/* Collection accessors for edge_select. */
|
||||
static void rna_MeshUVLoopLayer_edge_select_begin(CollectionPropertyIterator *iter,
|
||||
PointerRNA *ptr)
|
||||
{
|
||||
bool_layer_begin(iter, ptr, BKE_uv_map_edge_select_name_get);
|
||||
}
|
||||
|
||||
static bool rna_MeshUVLoopLayer_edge_select_lookup_int(PointerRNA *ptr,
|
||||
int index,
|
||||
PointerRNA *r_ptr)
|
||||
{
|
||||
return bool_layer_lookup_int(ptr, index, r_ptr, BKE_uv_map_edge_select_name_get);
|
||||
}
|
||||
|
||||
static int rna_MeshUVLoopLayer_edge_select_length(PointerRNA *ptr)
|
||||
{
|
||||
return bool_layer_length(ptr, BKE_uv_map_edge_select_name_get);
|
||||
}
|
||||
|
||||
static PointerRNA rna_MeshUVLoopLayer_edge_selection_ensure(PointerRNA ptr)
|
||||
{
|
||||
return bool_layer_ensure(&ptr, BKE_uv_map_edge_select_name_get);
|
||||
}
|
||||
|
||||
/* Collection accessors for pin. */
|
||||
static void rna_MeshUVLoopLayer_pin_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||
{
|
||||
@@ -1722,56 +1674,6 @@ static bool get_uv_index_and_layer(const PointerRNA *ptr,
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool rna_MeshUVLoop_select_get(PointerRNA *ptr)
|
||||
{
|
||||
const Mesh *mesh = rna_mesh(ptr);
|
||||
int uv_map_index;
|
||||
int loop_index;
|
||||
blender::VArray<bool> select;
|
||||
if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) {
|
||||
select = ED_mesh_uv_map_vert_select_layer_get(mesh, uv_map_index);
|
||||
}
|
||||
return select ? select[loop_index] : false;
|
||||
}
|
||||
|
||||
static void rna_MeshUVLoop_select_set(PointerRNA *ptr, const bool value)
|
||||
{
|
||||
Mesh *mesh = rna_mesh(ptr);
|
||||
int uv_map_index;
|
||||
int loop_index;
|
||||
if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) {
|
||||
blender::bke::AttributeWriter<bool> select = ED_mesh_uv_map_vert_select_layer_ensure(
|
||||
mesh, uv_map_index);
|
||||
select.varray.set(loop_index, value);
|
||||
select.finish();
|
||||
}
|
||||
}
|
||||
|
||||
static bool rna_MeshUVLoop_select_edge_get(PointerRNA *ptr)
|
||||
{
|
||||
const Mesh *mesh = rna_mesh(ptr);
|
||||
int uv_map_index;
|
||||
int loop_index;
|
||||
blender::VArray<bool> select_edge;
|
||||
if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) {
|
||||
select_edge = ED_mesh_uv_map_edge_select_layer_get(mesh, uv_map_index);
|
||||
}
|
||||
return select_edge ? select_edge[loop_index] : false;
|
||||
}
|
||||
|
||||
static void rna_MeshUVLoop_select_edge_set(PointerRNA *ptr, const bool value)
|
||||
{
|
||||
Mesh *mesh = rna_mesh(ptr);
|
||||
int uv_map_index;
|
||||
int loop_index;
|
||||
if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) {
|
||||
blender::bke::AttributeWriter<bool> select_edge = ED_mesh_uv_map_edge_select_layer_ensure(
|
||||
mesh, uv_map_index);
|
||||
select_edge.varray.set(loop_index, value);
|
||||
select_edge.finish();
|
||||
}
|
||||
}
|
||||
|
||||
static bool rna_MeshUVLoop_pin_uv_get(PointerRNA *ptr)
|
||||
{
|
||||
const Mesh *mesh = rna_mesh(ptr);
|
||||
@@ -2400,52 +2302,6 @@ static void rna_def_mloopuv(BlenderRNA *brna)
|
||||
nullptr,
|
||||
nullptr);
|
||||
|
||||
prop = RNA_def_property(srna, "vertex_selection", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "BoolAttributeValue");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "UV Vertex Selection", "Selection state of the face corner the UV editor");
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
|
||||
RNA_def_property_collection_funcs(prop,
|
||||
"rna_MeshUVLoopLayer_vert_select_begin",
|
||||
"rna_iterator_array_next",
|
||||
"rna_iterator_array_end",
|
||||
"rna_iterator_array_get",
|
||||
"rna_MeshUVLoopLayer_vert_select_length",
|
||||
"rna_MeshUVLoopLayer_vert_select_lookup_int",
|
||||
nullptr,
|
||||
nullptr);
|
||||
|
||||
func = RNA_def_function(
|
||||
srna, "vertex_selection_ensure", "rna_MeshUVLoopLayer_vert_select_ensure");
|
||||
RNA_def_function_flag(func, FUNC_SELF_AS_RNA);
|
||||
parm = RNA_def_pointer(func, "layer", "BoolAttribute", "", "The boolean attribute");
|
||||
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_RNAPTR);
|
||||
RNA_def_function_return(func, parm);
|
||||
|
||||
prop = RNA_def_property(srna, "edge_selection", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "BoolAttributeValue");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "UV Edge Selection", "Selection state of the edge in the UV editor");
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
|
||||
RNA_def_property_collection_funcs(prop,
|
||||
"rna_MeshUVLoopLayer_edge_select_begin",
|
||||
"rna_iterator_array_next",
|
||||
"rna_iterator_array_end",
|
||||
"rna_iterator_array_get",
|
||||
"rna_MeshUVLoopLayer_edge_select_length",
|
||||
"rna_MeshUVLoopLayer_edge_select_lookup_int",
|
||||
nullptr,
|
||||
nullptr);
|
||||
|
||||
func = RNA_def_function(
|
||||
srna, "edge_selection_ensure", "rna_MeshUVLoopLayer_edge_selection_ensure");
|
||||
RNA_def_function_flag(func, FUNC_SELF_AS_RNA);
|
||||
parm = RNA_def_pointer(func, "layer", "BoolAttribute", "", "The boolean attribute");
|
||||
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_RNAPTR);
|
||||
RNA_def_function_return(func, parm);
|
||||
|
||||
prop = RNA_def_property(srna, "pin", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "BoolAttributeValue");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
@@ -2481,17 +2337,6 @@ static void rna_def_mloopuv(BlenderRNA *brna)
|
||||
RNA_def_property_boolean_funcs(prop, "rna_MeshUVLoop_pin_uv_get", "rna_MeshUVLoop_pin_uv_set");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "UV Pinned", "");
|
||||
|
||||
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_MeshUVLoop_select_get", "rna_MeshUVLoop_select_set");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "UV Select", "");
|
||||
|
||||
prop = RNA_def_property(srna, "select_edge", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(
|
||||
prop, "rna_MeshUVLoop_select_edge_get", "rna_MeshUVLoop_select_edge_set");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "UV Edge Select", "");
|
||||
}
|
||||
|
||||
static void rna_def_mloopcol(BlenderRNA *brna)
|
||||
|
||||
@@ -84,7 +84,7 @@ static Mesh *create_ico_sphere_mesh(const int subdivisions,
|
||||
/* Make sure the associated boolean layers exists as well. Normally this would be done when
|
||||
* adding a UV layer via python or when copying from Mesh, but when we 'manually' create the UV
|
||||
* layer we need to make sure the boolean layers exist as well. */
|
||||
BM_uv_map_attr_select_and_pin_ensure(bm);
|
||||
BM_uv_map_attr_pin_ensure_for_all_layers(bm);
|
||||
|
||||
BMO_op_callf(bm,
|
||||
BMO_FLAG_DEFAULTS,
|
||||
|
||||
@@ -493,7 +493,7 @@ static PyObject *bpy_bmlayercollection_verify(BPy_BMLayerCollection *self)
|
||||
/* Because adding CustomData layers to a bmesh will invalidate any existing pointers
|
||||
* in Py objects we can't lazily add the associated bool layers. So add them all right
|
||||
* now. */
|
||||
BM_uv_map_attr_select_and_pin_ensure(self->bm);
|
||||
BM_uv_map_attr_pin_ensure_for_all_layers(self->bm);
|
||||
}
|
||||
|
||||
BLI_assert(index >= 0);
|
||||
@@ -544,7 +544,7 @@ static PyObject *bpy_bmlayercollection_new(BPy_BMLayerCollection *self, PyObject
|
||||
/* Because adding CustomData layers to a bmesh will invalidate any existing pointers
|
||||
* in Py objects we can't lazily add the associated bool layers. So add them all right
|
||||
* now. */
|
||||
BM_uv_map_attr_select_and_pin_ensure(self->bm);
|
||||
BM_uv_map_attr_pin_ensure_for_all_layers(self->bm);
|
||||
}
|
||||
|
||||
index = CustomData_number_of_layers(data, eCustomDataType(self->type)) - 1;
|
||||
|
||||
@@ -52,8 +52,6 @@ struct BPy_BMLoopUV {
|
||||
* datablocks (adding a layer re-generates all blocks). But eventually the plan is to lazily
|
||||
* allocate the bool layers 'on demand'. Therefore the code tries to handle all cases where
|
||||
* the layers don't exist. */
|
||||
bool *vert_select;
|
||||
bool *edge_select;
|
||||
bool *pin;
|
||||
BMLoop *loop;
|
||||
};
|
||||
@@ -124,46 +122,6 @@ static int bpy_bmloopuv_pin_uv_set(BPy_BMLoopUV *self, PyObject *value, void * /
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *bpy_bmloopuv_select_get(BPy_BMLoopUV *self, void * /*closure*/)
|
||||
{
|
||||
/* A non existing vert_select layer means nothing is currently selected */
|
||||
return self->vert_select ? PyBool_FromLong(*self->vert_select) : nullptr;
|
||||
}
|
||||
static int bpy_bmloopuv_select_set(BPy_BMLoopUV *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
/* TODO: see comment above on bpy_bmloopuv_pin_uv_set(), the same applies here. */
|
||||
BLI_assert(self->vert_select);
|
||||
if (self->vert_select) {
|
||||
*self->vert_select = PyC_Long_AsBool(value);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"active uv layer has no associated vertex selection layer. This is a bug!");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *bpy_bmloopuv_select_edge_get(BPy_BMLoopUV *self, void * /*closure*/)
|
||||
{
|
||||
/* A non existing edge_select layer means nothing is currently selected */
|
||||
return self->edge_select ? PyBool_FromLong(*self->edge_select) : nullptr;
|
||||
}
|
||||
static int bpy_bmloopuv_select_edge_set(BPy_BMLoopUV *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
/* TODO: see comment above on bpy_bmloopuv_pin_uv_set(), the same applies here. */
|
||||
BLI_assert(self->edge_select);
|
||||
if (self->edge_select) {
|
||||
*self->edge_select = PyC_Long_AsBool(value);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"active uv layer has no associated edge selection layer. This is a bug!");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef bpy_bmloopuv_getseters[] = {
|
||||
/* attributes match rna_def_mloopuv. */
|
||||
{"uv", (getter)bpy_bmloopuv_uv_get, (setter)bpy_bmloopuv_uv_set, bpy_bmloopuv_uv_doc, nullptr},
|
||||
@@ -172,17 +130,6 @@ static PyGetSetDef bpy_bmloopuv_getseters[] = {
|
||||
(setter)bpy_bmloopuv_pin_uv_set,
|
||||
bpy_bmloopuv_pin_uv_doc,
|
||||
nullptr},
|
||||
{"select",
|
||||
(getter)bpy_bmloopuv_select_get,
|
||||
(setter)bpy_bmloopuv_select_set,
|
||||
bpy_bmloopuv_select_doc,
|
||||
nullptr},
|
||||
{"select_edge",
|
||||
(getter)bpy_bmloopuv_select_edge_get,
|
||||
(setter)bpy_bmloopuv_select_edge_set,
|
||||
bpy_bmloopuv_select_edge_doc,
|
||||
nullptr},
|
||||
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
@@ -215,14 +162,6 @@ int BPy_BMLoopUV_AssignPyObject(BMesh *bm, BMLoop *loop, PyObject *value)
|
||||
|
||||
float *luv = BM_ELEM_CD_GET_FLOAT_P(loop, offsets.uv);
|
||||
copy_v2_v2(luv, src->uv);
|
||||
|
||||
if (src->vert_select) {
|
||||
BM_ELEM_CD_SET_BOOL(loop, offsets.select_vert, *src->vert_select);
|
||||
}
|
||||
|
||||
if (src->edge_select) {
|
||||
BM_ELEM_CD_SET_BOOL(loop, offsets.select_edge, *src->edge_select);
|
||||
}
|
||||
if (src->pin) {
|
||||
BM_ELEM_CD_SET_BOOL(loop, offsets.pin, *src->pin);
|
||||
}
|
||||
@@ -236,10 +175,6 @@ PyObject *BPy_BMLoopUV_CreatePyObject(BMesh *bm, BMLoop *loop, int layer)
|
||||
const BMUVOffsets offsets = BM_uv_map_offsets_from_layer(bm, layer);
|
||||
|
||||
self->uv = BM_ELEM_CD_GET_FLOAT_P(loop, offsets.uv);
|
||||
self->vert_select = offsets.select_vert >= 0 ? BM_ELEM_CD_GET_BOOL_P(loop, offsets.select_vert) :
|
||||
nullptr;
|
||||
self->edge_select = offsets.select_edge >= 0 ? BM_ELEM_CD_GET_BOOL_P(loop, offsets.select_edge) :
|
||||
nullptr;
|
||||
self->pin = offsets.pin >= 0 ? BM_ELEM_CD_GET_BOOL_P(loop, offsets.pin) : nullptr;
|
||||
|
||||
return (PyObject *)self;
|
||||
|
||||
Reference in New Issue
Block a user