Fix #100957: Dyntopo shows false positive data loss warnings #104535
@ -2289,26 +2289,12 @@ bool CustomData_merge(const CustomData *source,
|
|||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool attribute_stored_in_bmesh_flag(const StringRef name)
|
|
||||||
{
|
|
||||||
return ELEM(name,
|
|
||||||
"position",
|
|
||||||
".hide_vert",
|
|
||||||
".hide_edge",
|
|
||||||
".hide_poly",
|
|
||||||
".select_vert",
|
|
||||||
".select_edge",
|
|
||||||
".select_poly",
|
|
||||||
"material_index",
|
|
||||||
"sharp_edge");
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomData CustomData_shallow_copy_remove_non_bmesh_attributes(const CustomData *src,
|
CustomData CustomData_shallow_copy_remove_non_bmesh_attributes(const CustomData *src,
|
||||||
const eCustomDataMask mask)
|
const eCustomDataMask mask)
|
||||||
{
|
{
|
||||||
Vector<CustomDataLayer> dst_layers;
|
Vector<CustomDataLayer> dst_layers;
|
||||||
for (const CustomDataLayer &layer : Span<CustomDataLayer>{src->layers, src->totlayer}) {
|
for (const CustomDataLayer &layer : Span<CustomDataLayer>{src->layers, src->totlayer}) {
|
||||||
if (attribute_stored_in_bmesh_flag(layer.name)) {
|
if (BM_attribute_stored_in_bmesh_builtin(layer.name)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!(mask & CD_TYPE_AS_MASK(layer.type))) {
|
if (!(mask & CD_TYPE_AS_MASK(layer.type))) {
|
||||||
|
@ -133,6 +133,20 @@ static char bm_face_flag_to_mflag(const BMFace *f)
|
|||||||
return ((hflag & BM_ELEM_SMOOTH) ? ME_SMOOTH : 0);
|
return ((hflag & BM_ELEM_SMOOTH) ? ME_SMOOTH : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BM_attribute_stored_in_bmesh_builtin(const StringRef name)
|
||||||
|
{
|
||||||
|
return ELEM(name,
|
||||||
|
"position",
|
||||||
|
".hide_vert",
|
||||||
|
".hide_edge",
|
||||||
|
".hide_poly",
|
||||||
|
".select_vert",
|
||||||
|
".select_edge",
|
||||||
|
".select_poly",
|
||||||
|
"material_index",
|
||||||
|
"sharp_edge");
|
||||||
|
}
|
||||||
|
|
||||||
/* Static function for alloc (duplicate in modifiers_bmesh.c) */
|
/* Static function for alloc (duplicate in modifiers_bmesh.c) */
|
||||||
static BMFace *bm_face_create_from_mpoly(BMesh &bm,
|
static BMFace *bm_face_create_from_mpoly(BMesh &bm,
|
||||||
Span<MLoop> loops,
|
Span<MLoop> loops,
|
||||||
|
@ -9,6 +9,16 @@
|
|||||||
|
|
||||||
#include "bmesh.h"
|
#include "bmesh.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
# include "BLI_string_ref.hh"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \return Whether attributes with the given name are stored in special flags or fields in BMesh
|
||||||
|
* rather than in the regular custom data blocks.
|
||||||
|
*/
|
||||||
|
bool BM_attribute_stored_in_bmesh_builtin(const blender::StringRef name);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -274,15 +274,14 @@ static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator * /*op*/)
|
|||||||
|
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dyntopo_warning_popup(bContext *C, wmOperatorType *ot, enum eDynTopoWarnFlag flag)
|
static int dyntopo_warning_popup(bContext *C, wmOperatorType *ot, enum eDynTopoWarnFlag flag)
|
||||||
{
|
{
|
||||||
uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Warning!"), ICON_ERROR);
|
uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Warning!"), ICON_ERROR);
|
||||||
uiLayout *layout = UI_popup_menu_layout(pup);
|
uiLayout *layout = UI_popup_menu_layout(pup);
|
||||||
|
|
||||||
if (flag & (DYNTOPO_WARN_VDATA | DYNTOPO_WARN_EDATA | DYNTOPO_WARN_LDATA)) {
|
if (flag & (DYNTOPO_WARN_VDATA | DYNTOPO_WARN_EDATA | DYNTOPO_WARN_LDATA)) {
|
||||||
const char *msg_error = TIP_("Vertex Data Detected!");
|
const char *msg_error = TIP_("Attribute Data Detected");
|
||||||
const char *msg = TIP_("Dyntopo will not preserve vertex colors, UVs, or other customdata");
|
const char *msg = TIP_("Dyntopo will not preserve colors, UVs, or other attributes");
|
||||||
uiItemL(layout, msg_error, ICON_INFO);
|
uiItemL(layout, msg_error, ICON_INFO);
|
||||||
uiItemL(layout, msg, ICON_NONE);
|
uiItemL(layout, msg, ICON_NONE);
|
||||||
uiItemS(layout);
|
uiItemS(layout);
|
||||||
@ -305,6 +304,24 @@ static int dyntopo_warning_popup(bContext *C, wmOperatorType *ot, enum eDynTopoW
|
|||||||
return OPERATOR_INTERFACE;
|
return OPERATOR_INTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool dyntopo_supports_customdata_type(const CustomDataLayer &layer)
|
||||||
|
{
|
||||||
|
if (CD_TYPE_AS_MASK(layer.type) & CD_MASK_PROP_ALL) {
|
||||||
|
if (layer.name[0] == '\0') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* Some data is stored as generic attributes on #Mesh but in flags or field on #BMesh. */
|
||||||
|
return BM_attribute_stored_in_bmesh_builtin(layer.name);
|
||||||
|
}
|
||||||
|
/* Some layers just encode #Mesh topology or are handled as special cases for dyntopo. */
|
||||||
|
return ELEM(layer.type, CD_MEDGE, CD_MFACE, CD_MLOOP, CD_MPOLY, CD_PAINT_MASK, CD_ORIGINDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool dyntopo_supports_customdata_layers(const blender::Span<CustomDataLayer> layers)
|
||||||
|
{
|
||||||
|
return std::all_of(layers.begin(), layers.end(), dyntopo_supports_customdata_type);
|
||||||
|
}
|
||||||
|
|
||||||
enum eDynTopoWarnFlag SCULPT_dynamic_topology_check(Scene *scene, Object *ob)
|
enum eDynTopoWarnFlag SCULPT_dynamic_topology_check(Scene *scene, Object *ob)
|
||||||
{
|
{
|
||||||
Mesh *me = static_cast<Mesh *>(ob->data);
|
Mesh *me = static_cast<Mesh *>(ob->data);
|
||||||
@ -315,18 +332,17 @@ enum eDynTopoWarnFlag SCULPT_dynamic_topology_check(Scene *scene, Object *ob)
|
|||||||
BLI_assert(ss->bm == nullptr);
|
BLI_assert(ss->bm == nullptr);
|
||||||
UNUSED_VARS_NDEBUG(ss);
|
UNUSED_VARS_NDEBUG(ss);
|
||||||
|
|
||||||
for (int i = 0; i < CD_NUMTYPES; i++) {
|
if (!dyntopo_supports_customdata_layers({me->vdata.layers, me->vdata.totlayer})) {
|
||||||
if (!ELEM(i, CD_MEDGE, CD_MFACE, CD_MLOOP, CD_MPOLY, CD_PAINT_MASK, CD_ORIGINDEX)) {
|
|
||||||
if (CustomData_has_layer(&me->vdata, i)) {
|
|
||||||
flag |= DYNTOPO_WARN_VDATA;
|
flag |= DYNTOPO_WARN_VDATA;
|
||||||
}
|
}
|
||||||
if (CustomData_has_layer(&me->edata, i)) {
|
if (!dyntopo_supports_customdata_layers({me->edata.layers, me->edata.totlayer})) {
|
||||||
flag |= DYNTOPO_WARN_EDATA;
|
flag |= DYNTOPO_WARN_EDATA;
|
||||||
}
|
}
|
||||||
if (CustomData_has_layer(&me->ldata, i)) {
|
if (!dyntopo_supports_customdata_layers({me->pdata.layers, me->pdata.totlayer})) {
|
||||||
flag |= DYNTOPO_WARN_LDATA;
|
flag |= DYNTOPO_WARN_LDATA;
|
||||||
}
|
}
|
||||||
}
|
if (!dyntopo_supports_customdata_layers({me->ldata.layers, me->ldata.totlayer})) {
|
||||||
|
flag |= DYNTOPO_WARN_LDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user