Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHimanshi Kalra <himanshikalra98@gmail.com>2020-12-17 15:06:26 +0300
committerHimanshi Kalra <himanshikalra98@gmail.com>2020-12-17 15:06:26 +0300
commit167eace0e73bef77cf362af04f1f0dd47c492a92 (patch)
tree715217755512456fab8dfa8e38f63d5065a1ccc1 /source/blender/blenkernel/intern
parentf066bf923c234f52a6159d51f4978bf1072edaf1 (diff)
parentcf2ebaf27c78b3f8f79d9d014ca2261228f87e70 (diff)
Merge branch 'master' into soc-2020-testing-frameworks
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/appdir.c12
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc21
-rw-r--r--source/blender/blenkernel/intern/brush.c9
-rw-r--r--source/blender/blenkernel/intern/customdata.c16
-rw-r--r--source/blender/blenkernel/intern/icons.cc72
-rw-r--r--source/blender/blenkernel/intern/image_gpu.c2
-rw-r--r--source/blender/blenkernel/intern/layer.c2
-rw-r--r--source/blender/blenkernel/intern/lib_override.c38
-rw-r--r--source/blender/blenkernel/intern/mesh_fair.cc505
-rw-r--r--source/blender/blenkernel/intern/multires_unsubdivide.h2
-rw-r--r--source/blender/blenkernel/intern/node.c3
-rw-r--r--source/blender/blenkernel/intern/scene.c12
12 files changed, 640 insertions, 54 deletions
diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c
index a6b3985e80d..ae0c27635a6 100644
--- a/source/blender/blenkernel/intern/appdir.c
+++ b/source/blender/blenkernel/intern/appdir.c
@@ -906,14 +906,20 @@ bool BKE_appdir_program_python_search(char *fullpath,
const char *python_build_def = STRINGIFY(PYTHON_EXECUTABLE_NAME);
#endif
const char *basename = "python";
+#if defined(WIN32) && !defined(NDEBUG)
+ const char *basename_debug = "python_d";
+#endif
char python_version[16];
/* Check both possible names. */
const char *python_names[] = {
#ifdef PYTHON_EXECUTABLE_NAME
- python_build_def,
+ python_build_def,
+#endif
+#if defined(WIN32) && !defined(NDEBUG)
+ basename_debug,
#endif
- python_version,
- basename,
+ python_version,
+ basename,
};
bool is_found = false;
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index 282e9bc2962..623335f65a1 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -392,6 +392,8 @@ const blender::fn::CPPType *custom_data_type_to_cpp_type(const CustomDataType ty
return &CPPType::get<int>();
case CD_PROP_COLOR:
return &CPPType::get<Color4f>();
+ case CD_PROP_BOOL:
+ return &CPPType::get<bool>();
default:
return nullptr;
}
@@ -415,6 +417,9 @@ CustomDataType cpp_type_to_custom_data_type(const blender::fn::CPPType &type)
if (type.is<Color4f>()) {
return CD_PROP_COLOR;
}
+ if (type.is<bool>()) {
+ return CD_PROP_BOOL;
+ }
return static_cast<CustomDataType>(-1);
}
@@ -449,6 +454,9 @@ static ReadAttributePtr read_attribute_from_custom_data(const CustomData &custom
case CD_PROP_COLOR:
return std::make_unique<ArrayReadAttribute<Color4f>>(
domain, Span(static_cast<Color4f *>(layer.data), size));
+ case CD_PROP_BOOL:
+ return std::make_unique<ArrayReadAttribute<bool>>(
+ domain, Span(static_cast<bool *>(layer.data), size));
}
}
}
@@ -490,6 +498,9 @@ static WriteAttributePtr write_attribute_from_custom_data(
case CD_PROP_COLOR:
return std::make_unique<ArrayWriteAttribute<Color4f>>(
domain, MutableSpan(static_cast<Color4f *>(layer.data), size));
+ case CD_PROP_BOOL:
+ return std::make_unique<ArrayWriteAttribute<bool>>(
+ domain, MutableSpan(static_cast<bool *>(layer.data), size));
}
}
}
@@ -751,6 +762,7 @@ bool PointCloudComponent::attribute_domain_with_type_supported(
const AttributeDomain domain, const CustomDataType data_type) const
{
return domain == ATTR_DOMAIN_POINT && ELEM(data_type,
+ CD_PROP_BOOL,
CD_PROP_FLOAT,
CD_PROP_FLOAT2,
CD_PROP_FLOAT3,
@@ -874,8 +886,13 @@ bool MeshComponent::attribute_domain_with_type_supported(const AttributeDomain d
if (!this->attribute_domain_supported(domain)) {
return false;
}
- return ELEM(
- data_type, CD_PROP_FLOAT, CD_PROP_FLOAT2, CD_PROP_FLOAT3, CD_PROP_INT32, CD_PROP_COLOR);
+ return ELEM(data_type,
+ CD_PROP_BOOL,
+ CD_PROP_FLOAT,
+ CD_PROP_FLOAT2,
+ CD_PROP_FLOAT3,
+ CD_PROP_INT32,
+ CD_PROP_COLOR);
}
int MeshComponent::attribute_domain_size(const AttributeDomain domain) const
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 33686cea4fc..9a954a89cad 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1834,6 +1834,14 @@ void BKE_brush_sculpt_reset(Brush *br)
br->flag &= ~BRUSH_SPACE_ATTEN;
br->curve_preset = BRUSH_CURVE_SPHERE;
break;
+ case SCULPT_TOOL_DISPLACEMENT_SMEAR:
+ br->alpha = 1.0f;
+ br->spacing = 5;
+ br->hardness = 0.7f;
+ br->flag &= ~BRUSH_ALPHA_PRESSURE;
+ br->flag &= ~BRUSH_SPACE_ATTEN;
+ br->curve_preset = BRUSH_CURVE_SMOOTHER;
+ break;
default:
break;
}
@@ -1898,6 +1906,7 @@ void BKE_brush_sculpt_reset(Brush *br)
case SCULPT_TOOL_MASK:
case SCULPT_TOOL_DRAW_FACE_SETS:
case SCULPT_TOOL_DISPLACEMENT_ERASER:
+ case SCULPT_TOOL_DISPLACEMENT_SMEAR:
br->add_col[0] = 0.75f;
br->add_col[1] = 0.75f;
br->add_col[2] = 0.75f;
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index fdb3e246382..1e2bc570c65 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -1837,6 +1837,21 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
layerMultiply_propfloat2,
NULL,
layerAdd_propfloat2},
+ /* 50: CD_PROP_POOL */
+ {sizeof(bool),
+ "bool",
+ 1,
+ N_("Boolean"),
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
};
static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
@@ -1892,6 +1907,7 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
"CDPropCol",
"CDPropFloat3",
"CDPropFloat2",
+ "CDPropBoolean",
};
const CustomData_MeshMasks CD_MASK_BAREMESH = {
diff --git a/source/blender/blenkernel/intern/icons.cc b/source/blender/blenkernel/intern/icons.cc
index 48f5e11778c..fbf69357478 100644
--- a/source/blender/blenkernel/intern/icons.cc
+++ b/source/blender/blenkernel/intern/icons.cc
@@ -78,7 +78,7 @@ enum {
static CLG_LogRef LOG = {"bke.icons"};
/* Protected by gIconMutex. */
-static GHash *gIcons = NULL;
+static GHash *gIcons = nullptr;
/* Protected by gIconMutex. */
static int gNextIconId = 1;
@@ -89,7 +89,7 @@ static int gFirstIconId = 1;
std::mutex gIconMutex;
/* Not mutex-protected! */
-static GHash *gCachedPreviews = NULL;
+static GHash *gCachedPreviews = nullptr;
/* Queue of icons for deferred deletion. */
typedef struct DeferredIconDeleteNode {
@@ -149,7 +149,7 @@ static void icon_free_data(int icon_id, Icon *icon)
}
else if (icon->obj_type == ICON_DATA_STUDIOLIGHT) {
StudioLight *sl = (StudioLight *)icon->obj;
- if (sl != NULL) {
+ if (sl != nullptr) {
BKE_studiolight_unset_icon_id(sl, icon_id);
}
}
@@ -166,7 +166,7 @@ static Icon *icon_ghash_lookup(int icon_id)
/* create an id for a new icon and make sure that ids from deleted icons get reused
* after the integer number range is used up */
-static int get_next_free_id(void)
+static int get_next_free_id()
{
std::scoped_lock lock(gIconMutex);
int startId = gFirstIconId;
@@ -214,13 +214,13 @@ void BKE_icons_free(void)
BLI_assert(BLI_thread_is_main());
if (gIcons) {
- BLI_ghash_free(gIcons, NULL, icon_free);
- gIcons = NULL;
+ BLI_ghash_free(gIcons, nullptr, icon_free);
+ gIcons = nullptr;
}
if (gCachedPreviews) {
BLI_ghash_free(gCachedPreviews, MEM_freeN, BKE_previewimg_freefunc);
- gCachedPreviews = NULL;
+ gCachedPreviews = nullptr;
}
BLI_linklist_lockfree_free(&g_icon_delete_queue, MEM_freeN);
@@ -232,9 +232,9 @@ void BKE_icons_deferred_free(void)
for (DeferredIconDeleteNode *node =
(DeferredIconDeleteNode *)BLI_linklist_lockfree_begin(&g_icon_delete_queue);
- node != NULL;
+ node != nullptr;
node = node->next) {
- BLI_ghash_remove(gIcons, POINTER_FROM_INT(node->icon_id), NULL, icon_free);
+ BLI_ghash_remove(gIcons, POINTER_FROM_INT(node->icon_id), nullptr, icon_free);
}
BLI_linklist_lockfree_clear(&g_icon_delete_queue, MEM_freeN);
}
@@ -296,7 +296,7 @@ void BKE_previewimg_free(PreviewImage **prv)
{
if (prv && (*prv)) {
BKE_previewimg_freefunc(*prv);
- *prv = NULL;
+ *prv = nullptr;
}
}
@@ -321,7 +321,7 @@ void BKE_previewimg_clear(struct PreviewImage *prv)
PreviewImage *BKE_previewimg_copy(const PreviewImage *prv)
{
- PreviewImage *prv_img = NULL;
+ PreviewImage *prv_img = nullptr;
if (prv) {
prv_img = (PreviewImage *)MEM_dupallocN(prv);
@@ -329,7 +329,7 @@ PreviewImage *BKE_previewimg_copy(const PreviewImage *prv)
if (prv->rect[i]) {
prv_img->rect[i] = (uint *)MEM_dupallocN(prv->rect[i]);
}
- prv_img->gputexture[i] = NULL;
+ prv_img->gputexture[i] = nullptr;
}
}
return prv_img;
@@ -345,7 +345,7 @@ void BKE_previewimg_id_copy(ID *new_id, const ID *old_id)
PreviewImage **new_prv_p = BKE_previewimg_id_get_p(new_id);
if (old_prv_p && *old_prv_p) {
- BLI_assert(new_prv_p != NULL && ELEM(*new_prv_p, NULL, *old_prv_p));
+ BLI_assert(new_prv_p != nullptr && ELEM(*new_prv_p, nullptr, *old_prv_p));
// const int new_icon_id = get_next_free_id();
// if (new_icon_id == 0) {
@@ -379,13 +379,13 @@ PreviewImage **BKE_previewimg_id_get_p(const ID *id)
break;
}
- return NULL;
+ return nullptr;
}
PreviewImage *BKE_previewimg_id_get(const ID *id)
{
PreviewImage **prv_p = BKE_previewimg_id_get_p(id);
- return prv_p ? *prv_p : NULL;
+ return prv_p ? *prv_p : nullptr;
}
void BKE_previewimg_id_free(ID *id)
@@ -401,13 +401,13 @@ PreviewImage *BKE_previewimg_id_ensure(ID *id)
PreviewImage **prv_p = BKE_previewimg_id_get_p(id);
if (prv_p) {
- if (*prv_p == NULL) {
+ if (*prv_p == nullptr) {
*prv_p = BKE_previewimg_create();
}
return *prv_p;
}
- return NULL;
+ return nullptr;
}
void BKE_previewimg_id_custom_set(ID *id, const char *path)
@@ -464,7 +464,7 @@ PreviewImage *BKE_previewimg_cached_ensure(const char *name)
{
BLI_assert(BLI_thread_is_main());
- PreviewImage *prv = NULL;
+ PreviewImage *prv = nullptr;
void **key_p, **prv_p;
if (!BLI_ghash_ensure_p_ex(gCachedPreviews, name, &key_p, &prv_p)) {
@@ -488,7 +488,7 @@ PreviewImage *BKE_previewimg_cached_thumbnail_read(const char *name,
{
BLI_assert(BLI_thread_is_main());
- PreviewImage *prv = NULL;
+ PreviewImage *prv = nullptr;
void **prv_p;
prv_p = BLI_ghash_lookup_p(gCachedPreviews, name);
@@ -599,7 +599,7 @@ ImBuf *BKE_previewimg_to_imbuf(PreviewImage *prv, const int size)
const unsigned int h = prv->h[size];
const unsigned int *rect = prv->rect[size];
- ImBuf *ima = NULL;
+ ImBuf *ima = nullptr;
if (w > 0 && h > 0 && rect) {
/* first allocate imbuf for copying preview into it */
@@ -627,7 +627,7 @@ void BKE_previewimg_blend_write(BlendWriter *writer, const PreviewImage *prv)
* but not doing so would causes all previews to be re-rendered after
* undo which is too expensive. */
- if (prv == NULL) {
+ if (prv == nullptr) {
return;
}
@@ -636,7 +636,7 @@ void BKE_previewimg_blend_write(BlendWriter *writer, const PreviewImage *prv)
if (!(U.flag & USER_SAVE_PREVIEWS)) {
prv_copy.w[1] = 0;
prv_copy.h[1] = 0;
- prv_copy.rect[1] = NULL;
+ prv_copy.rect[1] = nullptr;
}
BLO_write_struct_at_address(writer, PreviewImage, prv, &prv_copy);
if (prv_copy.rect[0]) {
@@ -649,7 +649,7 @@ void BKE_previewimg_blend_write(BlendWriter *writer, const PreviewImage *prv)
void BKE_previewimg_blend_read(BlendDataReader *reader, PreviewImage *prv)
{
- if (prv == NULL) {
+ if (prv == nullptr) {
return;
}
@@ -657,7 +657,7 @@ void BKE_previewimg_blend_read(BlendDataReader *reader, PreviewImage *prv)
if (prv->rect[i]) {
BLO_read_data_address(reader, &prv->rect[i]);
}
- prv->gputexture[i] = NULL;
+ prv->gputexture[i] = nullptr;
/* For now consider previews read from file as finished to not confuse File Browser preview
* loading. That could be smarter and check if there's a preview job running instead.
* If the preview is tagged as changed, it needs to be updated anyway, so don't remove the tag.
@@ -676,7 +676,7 @@ void BKE_previewimg_blend_read(BlendDataReader *reader, PreviewImage *prv)
void BKE_icon_changed(const int icon_id)
{
- Icon *icon = NULL;
+ Icon *icon = nullptr;
if (!icon_id || G.background) {
return;
@@ -714,8 +714,8 @@ static Icon *icon_create(int icon_id, int obj_type, void *obj)
new_icon->flag = 0;
/* next two lines make sure image gets created */
- new_icon->drawinfo = NULL;
- new_icon->drawinfo_free = NULL;
+ new_icon->drawinfo = nullptr;
+ new_icon->drawinfo_free = nullptr;
{
std::scoped_lock lock(gIconMutex);
@@ -867,11 +867,11 @@ ImBuf *BKE_icon_imbuf_get_buffer(int icon_id)
Icon *icon = icon_ghash_lookup(icon_id);
if (!icon) {
CLOG_ERROR(&LOG, "no icon for icon ID: %d", icon_id);
- return NULL;
+ return nullptr;
}
if (icon->obj_type != ICON_DATA_IMBUF) {
CLOG_ERROR(&LOG, "icon ID does not refer to an imbuf icon: %d", icon_id);
- return NULL;
+ return nullptr;
}
return (ImBuf *)icon->obj;
@@ -881,13 +881,13 @@ Icon *BKE_icon_get(const int icon_id)
{
BLI_assert(BLI_thread_is_main());
- Icon *icon = NULL;
+ Icon *icon = nullptr;
icon = icon_ghash_lookup(icon_id);
if (!icon) {
CLOG_ERROR(&LOG, "no icon for icon ID: %d", icon_id);
- return NULL;
+ return nullptr;
}
return icon;
@@ -930,7 +930,7 @@ void BKE_icon_id_delete(struct ID *id)
BKE_icons_deferred_free();
std::scoped_lock lock(gIconMutex);
- BLI_ghash_remove(gIcons, POINTER_FROM_INT(icon_id), NULL, icon_free);
+ BLI_ghash_remove(gIcons, POINTER_FROM_INT(icon_id), nullptr, icon_free);
}
/**
@@ -944,7 +944,7 @@ bool BKE_icon_delete(const int icon_id)
}
std::scoped_lock lock(gIconMutex);
- if (Icon *icon = (Icon *)BLI_ghash_popkey(gIcons, POINTER_FROM_INT(icon_id), NULL)) {
+ if (Icon *icon = (Icon *)BLI_ghash_popkey(gIcons, POINTER_FROM_INT(icon_id), nullptr)) {
icon_free_data(icon_id, icon);
icon_free(icon);
return true;
@@ -962,7 +962,7 @@ bool BKE_icon_delete_unmanaged(const int icon_id)
std::scoped_lock lock(gIconMutex);
- Icon *icon = (Icon *)BLI_ghash_popkey(gIcons, POINTER_FROM_INT(icon_id), NULL);
+ Icon *icon = (Icon *)BLI_ghash_popkey(gIcons, POINTER_FROM_INT(icon_id), nullptr);
if (icon) {
if (UNLIKELY(icon->flag & ICON_FLAG_MANAGED)) {
BLI_ghash_insert(gIcons, POINTER_FROM_INT(icon_id), icon);
@@ -1041,8 +1041,8 @@ struct Icon_Geom *BKE_icon_geom_from_file(const char *filename)
BLI_assert(BLI_thread_is_main());
size_t data_len;
uchar *data = (uchar *)BLI_file_read_binary_as_mem(filename, 0, &data_len);
- if (data == NULL) {
- return NULL;
+ if (data == nullptr) {
+ return nullptr;
}
return BKE_icon_geom_from_memory(data, data_len);
}
diff --git a/source/blender/blenkernel/intern/image_gpu.c b/source/blender/blenkernel/intern/image_gpu.c
index 9ed233ab34c..50138b34fa3 100644
--- a/source/blender/blenkernel/intern/image_gpu.c
+++ b/source/blender/blenkernel/intern/image_gpu.c
@@ -62,7 +62,7 @@ bool BKE_image_has_gpu_texture_premultiplied_alpha(Image *image, ImBuf *ibuf)
return ibuf->rect_float != NULL;
}
}
- else if (ibuf) {
+ if (ibuf) {
if (ibuf->rect_float) {
return image ? (image->alpha_mode != IMA_ALPHA_STRAIGHT) : false;
}
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 8a699e31f37..fbad0d920ed 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -2054,7 +2054,7 @@ static void bke_view_layer_verify_aov_cb(void *userdata,
const char *name,
int UNUSED(channels),
const char *UNUSED(chanid),
- int UNUSED(type))
+ eNodeSocketDatatype UNUSED(type))
{
GHash *name_count = userdata;
void **value_p;
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index d82315a0e7f..cabc80d4024 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -369,6 +369,7 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain)
static bool lib_override_hierarchy_recursive_tag(Main *bmain,
ID *id,
const uint tag,
+ const uint missing_tag,
Library *override_group_lib_reference)
{
void **entry_vp = BLI_ghash_lookup_p(bmain->relations->id_user_to_used, id);
@@ -377,9 +378,16 @@ static bool lib_override_hierarchy_recursive_tag(Main *bmain,
return (id->tag & tag) != 0;
}
+ /* Note: in case some reference ID is missing from linked data (and therefore its override uses
+ * a placeholder as reference), use `missing_tag` instead of `tag` for this override. */
if (override_group_lib_reference != NULL && ID_IS_OVERRIDE_LIBRARY_REAL(id) &&
id->override_library->reference->lib == override_group_lib_reference) {
- id->tag |= tag;
+ if (id->override_library->reference->tag & LIB_TAG_MISSING) {
+ id->tag |= missing_tag;
+ }
+ else {
+ id->tag |= tag;
+ }
}
/* This way we won't process again that ID, should we encounter it again through another
@@ -397,7 +405,7 @@ static bool lib_override_hierarchy_recursive_tag(Main *bmain,
/* We only consider IDs from the same library. */
if (entry->id_pointer != NULL && (*entry->id_pointer)->lib == id->lib) {
if (lib_override_hierarchy_recursive_tag(
- bmain, *entry->id_pointer, tag, override_group_lib_reference) &&
+ bmain, *entry->id_pointer, tag, missing_tag, override_group_lib_reference) &&
override_group_lib_reference == NULL) {
id->tag |= tag;
}
@@ -430,7 +438,7 @@ void BKE_lib_override_library_dependencies_tag(Main *bmain,
/* We tag all intermediary data-blocks in-between two overridden ones (e.g. if a shape-key
* has a driver using an armature object's bone, we need to override the shape-key/obdata,
* the objects using them, etc.) */
- lib_override_hierarchy_recursive_tag(bmain, id_root, tag, NULL);
+ lib_override_hierarchy_recursive_tag(bmain, id_root, tag, 0, NULL);
BKE_main_relations_free(bmain);
}
@@ -447,6 +455,7 @@ void BKE_lib_override_library_dependencies_tag(Main *bmain,
void BKE_lib_override_library_override_group_tag(Main *bmain,
ID *id_root,
const uint tag,
+ const uint missing_tag,
const bool do_create_main_relashionships)
{
if (do_create_main_relashionships) {
@@ -456,7 +465,7 @@ void BKE_lib_override_library_override_group_tag(Main *bmain,
/* We tag all liboverride data-blocks from the same library as reference one,
* being used by the root ID. */
lib_override_hierarchy_recursive_tag(
- bmain, id_root, tag, id_root->override_library->reference->lib);
+ bmain, id_root, tag, missing_tag, id_root->override_library->reference->lib);
BKE_main_relations_free(bmain);
}
@@ -492,8 +501,9 @@ static int lib_override_library_make_tag_ids_cb(LibraryIDLinkCallbackData *cb_da
}
/* We tag all collections and objects for override. And we also tag all other data-blocks which
- * would use one of those. */
- if (ELEM(GS(id->name), ID_OB, ID_GR)) {
+ * would use one of those.
+ * Note: missing IDs (aka placeholders) are never overridden. */
+ if (ELEM(GS(id->name), ID_OB, ID_GR) && !(id->tag & LIB_TAG_MISSING)) {
id->tag |= LIB_TAG_DOIT;
}
@@ -692,6 +702,12 @@ bool BKE_lib_override_library_proxy_convert(Main *bmain,
&ob_proxy->proxy->id;
ID *id_reference = is_override_instancing_object ? &ob_proxy_group->id : &ob_proxy->id;
+ /* In some cases the instance collection of a proxy object may be local (see e.g. T83875). Not
+ * sure this is a valid state, but for now just abort the overriding process. */
+ if (!ID_IS_OVERRIDABLE_LIBRARY(id_root)) {
+ return false;
+ }
+
/* We manually convert the proxy object into a library override, further override handling will
* then be handled by `BKE_lib_override_library_create()` just as for a regular override
* creation.
@@ -725,7 +741,7 @@ bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_
/* Make a mapping 'linked reference IDs' -> 'Local override IDs' of existing overrides, and tag
* linked reference ones to be overridden again. */
- BKE_lib_override_library_override_group_tag(bmain, id_root, LIB_TAG_DOIT, true);
+ BKE_lib_override_library_override_group_tag(bmain, id_root, LIB_TAG_DOIT, LIB_TAG_MISSING, true);
GHash *linkedref_to_old_override = BLI_ghash_new(
BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
@@ -835,6 +851,12 @@ bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_
}
id->tag &= ~LIB_TAG_DOIT;
}
+ /* Also cleanup old overrides that went missing in new linked data. */
+ else if (id->tag & LIB_TAG_MISSING && !ID_IS_LINKED(id)) {
+ BLI_assert(ID_IS_OVERRIDE_LIBRARY(id));
+ id->tag |= LIB_TAG_DOIT;
+ id->tag &= ~LIB_TAG_MISSING;
+ }
}
FOREACH_MAIN_ID_END;
BKE_id_multi_tagged_delete(bmain);
@@ -876,7 +898,7 @@ void BKE_lib_override_library_delete(Main *bmain, ID *id_root)
id_root->tag |= LIB_TAG_DOIT;
/* Tag all library overrides in the chains of dependencies from the given root one. */
- BKE_lib_override_library_override_group_tag(bmain, id_root, LIB_TAG_DOIT, true);
+ BKE_lib_override_library_override_group_tag(bmain, id_root, LIB_TAG_DOIT, LIB_TAG_DOIT, true);
ID *id;
FOREACH_MAIN_ID_BEGIN (bmain, id) {
diff --git a/source/blender/blenkernel/intern/mesh_fair.cc b/source/blender/blenkernel/intern/mesh_fair.cc
new file mode 100644
index 00000000000..527288d06cf
--- /dev/null
+++ b/source/blender/blenkernel/intern/mesh_fair.cc
@@ -0,0 +1,505 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Mesh Fairing algorithm designed by Brett Fedack, used in the addon "Mesh Fairing":
+ * https://github.com/fedackb/mesh-fairing.
+ */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include "BLI_map.hh"
+#include "BLI_math.h"
+#include "BLI_vector.hh"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+
+#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
+#include "BKE_mesh.h"
+#include "BKE_mesh_fair.h"
+#include "BKE_mesh_mapping.h"
+
+#include "bmesh.h"
+#include "bmesh_tools.h"
+
+#include "MEM_guardedalloc.h"
+#include "eigen_capi.h"
+
+using blender::Map;
+using blender::Vector;
+using std::array;
+
+class VertexWeight {
+ public:
+ virtual float weight_at_index(const int index) = 0;
+ virtual ~VertexWeight() = default;
+};
+
+class LoopWeight {
+ public:
+ virtual float weight_at_index(const int index) = 0;
+ virtual ~LoopWeight() = default;
+};
+
+class FairingContext {
+ public:
+ /* Get coordinates of vertices which are adjacent to the loop with specified index. */
+ virtual void adjacents_coords_from_loop(const int loop,
+ float r_adj_next[3],
+ float r_adj_prev[3]) = 0;
+
+ /* Get the other vertex index for a loop. */
+ virtual int other_vertex_index_from_loop(const int loop, const unsigned int v) = 0;
+
+ int vertex_count_get()
+ {
+ return totvert_;
+ }
+
+ int loop_count_get()
+ {
+ return totvert_;
+ }
+
+ MeshElemMap *vertex_loop_map_get(const int v)
+ {
+ return &vlmap_[v];
+ }
+
+ float *vertex_deformation_co_get(const int v)
+ {
+ return co_[v];
+ }
+
+ virtual ~FairingContext() = default;
+
+ void fair_vertices(bool *affected,
+ const eMeshFairingDepth depth,
+ VertexWeight *vertex_weight,
+ LoopWeight *loop_weight)
+ {
+
+ fair_vertices_ex(affected, (int)depth, vertex_weight, loop_weight);
+ }
+
+ protected:
+ Vector<float *> co_;
+
+ int totvert_;
+ int totloop_;
+
+ MeshElemMap *vlmap_;
+ int *vlmap_mem_;
+
+ private:
+ void fair_setup_fairing(const int v,
+ const int i,
+ LinearSolver *solver,
+ float multiplier,
+ const int depth,
+ Map<int, int> &vert_col_map,
+ VertexWeight *vertex_weight,
+ LoopWeight *loop_weight)
+ {
+ if (depth == 0) {
+ if (vert_col_map.contains(v)) {
+ const int j = vert_col_map.lookup(v);
+ EIG_linear_solver_matrix_add(solver, i, j, -multiplier);
+ return;
+ }
+ for (int j = 0; j < 3; j++) {
+ EIG_linear_solver_right_hand_side_add(solver, j, i, multiplier * co_[v][j]);
+ }
+ return;
+ }
+
+ float w_ij_sum = 0;
+ const float w_i = vertex_weight->weight_at_index(v);
+ MeshElemMap *vlmap_elem = &vlmap_[v];
+ for (int l = 0; l < vlmap_elem->count; l++) {
+ const int l_index = vlmap_elem->indices[l];
+ const int other_vert = other_vertex_index_from_loop(l_index, v);
+ const float w_ij = loop_weight->weight_at_index(l_index);
+ w_ij_sum += w_ij;
+ fair_setup_fairing(other_vert,
+ i,
+ solver,
+ w_i * w_ij * multiplier,
+ depth - 1,
+ vert_col_map,
+ vertex_weight,
+ loop_weight);
+ }
+ fair_setup_fairing(v,
+ i,
+ solver,
+ -1 * w_i * w_ij_sum * multiplier,
+ depth - 1,
+ vert_col_map,
+ vertex_weight,
+ loop_weight);
+ }
+
+ void fair_vertices_ex(bool *affected,
+ const int order,
+ VertexWeight *vertex_weight,
+ LoopWeight *loop_weight)
+ {
+ Map<int, int> vert_col_map;
+ int num_affected_vertices = 0;
+ for (int i = 0; i < totvert_; i++) {
+ if (!affected[i]) {
+ continue;
+ }
+ vert_col_map.add(i, num_affected_vertices);
+ num_affected_vertices++;
+ }
+
+ /* Early return, nothing to do. */
+ if (num_affected_vertices == 0 || num_affected_vertices == totvert_) {
+ return;
+ }
+
+ /* Setup fairing matrices */
+ LinearSolver *solver = EIG_linear_solver_new(num_affected_vertices, num_affected_vertices, 3);
+ for (auto item : vert_col_map.items()) {
+ const int v = item.key;
+ const int col = item.value;
+ fair_setup_fairing(v, col, solver, 1.0f, order, vert_col_map, vertex_weight, loop_weight);
+ }
+
+ /* Solve linear system */
+ EIG_linear_solver_solve(solver);
+
+ /* Copy the result back to the mesh */
+ for (auto item : vert_col_map.items()) {
+ const int v = item.key;
+ const int col = item.value;
+ for (int j = 0; j < 3; j++) {
+ co_[v][j] = EIG_linear_solver_variable_get(solver, j, col);
+ }
+ }
+
+ /* Free solver data */
+ EIG_linear_solver_delete(solver);
+ }
+};
+
+class MeshFairingContext : public FairingContext {
+ public:
+ MeshFairingContext(Mesh *mesh, MVert *deform_mverts)
+ {
+ totvert_ = mesh->totvert;
+ totloop_ = mesh->totloop;
+
+ medge_ = mesh->medge;
+ mpoly_ = mesh->mpoly;
+ mloop_ = mesh->mloop;
+ BKE_mesh_vert_loop_map_create(&vlmap_,
+ &vlmap_mem_,
+ mesh->mpoly,
+ mesh->mloop,
+ mesh->totvert,
+ mesh->totpoly,
+ mesh->totloop);
+
+ /* Deformation coords. */
+ co_.reserve(mesh->totvert);
+ if (deform_mverts) {
+ for (int i = 0; i < mesh->totvert; i++) {
+ co_[i] = deform_mverts[i].co;
+ }
+ }
+ else {
+ for (int i = 0; i < mesh->totvert; i++) {
+ co_[i] = mesh->mvert[i].co;
+ }
+ }
+
+ loop_to_poly_map_.reserve(mesh->totloop);
+ for (int i = 0; i < mesh->totpoly; i++) {
+ for (int l = 0; l < mesh->mpoly[i].totloop; l++) {
+ loop_to_poly_map_[l + mesh->mpoly[i].loopstart] = i;
+ }
+ }
+ }
+
+ ~MeshFairingContext()
+ {
+ MEM_SAFE_FREE(vlmap_);
+ MEM_SAFE_FREE(vlmap_mem_);
+ }
+
+ virtual void adjacents_coords_from_loop(const int loop,
+ float r_adj_next[3],
+ float r_adj_prev[3]) override
+ {
+ const int vert = mloop_[loop].v;
+ const MPoly *p = &mpoly_[loop_to_poly_map_[loop]];
+ const int corner = poly_find_loop_from_vert(p, &mloop_[p->loopstart], vert);
+ copy_v3_v3(r_adj_next, co_[ME_POLY_LOOP_NEXT(mloop_, p, corner)->v]);
+ copy_v3_v3(r_adj_prev, co_[ME_POLY_LOOP_PREV(mloop_, p, corner)->v]);
+ }
+
+ virtual int other_vertex_index_from_loop(const int loop, const unsigned int v) override
+ {
+ MEdge *e = &medge_[mloop_[loop].e];
+ if (e->v1 == v) {
+ return e->v2;
+ }
+ return e->v1;
+ }
+
+ protected:
+ Mesh *mesh_;
+ MLoop *mloop_;
+ MPoly *mpoly_;
+ MEdge *medge_;
+ Vector<int> loop_to_poly_map_;
+};
+
+class BMeshFairingContext : public FairingContext {
+ public:
+ BMeshFairingContext(BMesh *bm)
+ {
+ this->bm = bm;
+ totvert_ = bm->totvert;
+ totloop_ = bm->totloop;
+
+ BM_mesh_elem_table_ensure(bm, BM_VERT);
+ BM_mesh_elem_index_ensure(bm, BM_LOOP);
+
+ /* Deformation coords. */
+ co_.reserve(bm->totvert);
+ for (int i = 0; i < bm->totvert; i++) {
+ BMVert *v = BM_vert_at_index(bm, i);
+ co_[i] = v->co;
+ }
+
+ bmloop_.reserve(bm->totloop);
+ vlmap_ = (MeshElemMap *)MEM_calloc_arrayN(sizeof(MeshElemMap), bm->totvert, "bmesh loop map");
+ vlmap_mem_ = (int *)MEM_malloc_arrayN(sizeof(int), bm->totloop, "bmesh loop map mempool");
+
+ BMVert *v;
+ BMLoop *l;
+ BMIter iter;
+ BMIter loop_iter;
+ int index_iter = 0;
+
+ /* This initializes both the bmloop and the vlmap for bmesh in a single loop. */
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ int loop_count = 0;
+ const int vert_index = BM_elem_index_get(v);
+ vlmap_[vert_index].indices = &vlmap_mem_[index_iter];
+ BM_ITER_ELEM (l, &loop_iter, v, BM_LOOPS_OF_VERT) {
+ const int loop_index = BM_elem_index_get(l);
+ bmloop_[loop_index] = l;
+ vlmap_mem_[index_iter] = loop_index;
+ index_iter++;
+ loop_count++;
+ }
+ vlmap_[vert_index].count = loop_count;
+ }
+ }
+
+ ~BMeshFairingContext()
+ {
+ MEM_SAFE_FREE(vlmap_);
+ MEM_SAFE_FREE(vlmap_mem_);
+ }
+
+ virtual void adjacents_coords_from_loop(const int loop,
+ float r_adj_next[3],
+ float r_adj_prev[3]) override
+ {
+ copy_v3_v3(r_adj_next, bmloop_[loop]->next->v->co);
+ copy_v3_v3(r_adj_prev, bmloop_[loop]->prev->v->co);
+ }
+
+ virtual int other_vertex_index_from_loop(const int loop, const unsigned int v) override
+ {
+ BMLoop *l = bmloop_[loop];
+ BMVert *bmvert = BM_vert_at_index(bm, v);
+ BMVert *bm_other_vert = BM_edge_other_vert(l->e, bmvert);
+ return BM_elem_index_get(bm_other_vert);
+ }
+
+ protected:
+ BMesh *bm;
+ Vector<BMLoop *> bmloop_;
+};
+
+class UniformVertexWeight : public VertexWeight {
+ public:
+ UniformVertexWeight(FairingContext *fairing_context)
+ {
+ const int totvert = fairing_context->vertex_count_get();
+ vertex_weights_.reserve(totvert);
+ for (int i = 0; i < totvert; i++) {
+ const int tot_loop = fairing_context->vertex_loop_map_get(i)->count;
+ if (tot_loop != 0) {
+ vertex_weights_[i] = 1.0f / tot_loop;
+ }
+ else {
+ vertex_weights_[i] = FLT_MAX;
+ }
+ }
+ }
+ ~UniformVertexWeight() = default;
+
+ float weight_at_index(const int index) override
+ {
+ return vertex_weights_[index];
+ }
+
+ private:
+ Vector<float> vertex_weights_;
+};
+
+class VoronoiVertexWeight : public VertexWeight {
+
+ public:
+ VoronoiVertexWeight(FairingContext *fairing_context)
+ {
+
+ const int totvert = fairing_context->vertex_count_get();
+ vertex_weights_.reserve(totvert);
+ for (int i = 0; i < totvert; i++) {
+
+ float area = 0.0f;
+ float a[3];
+ copy_v3_v3(a, fairing_context->vertex_deformation_co_get(i));
+ const float acute_threshold = M_PI_2;
+
+ MeshElemMap *vlmap_elem = fairing_context->vertex_loop_map_get(i);
+ for (int l = 0; l < vlmap_elem->count; l++) {
+ const int l_index = vlmap_elem->indices[l];
+
+ float b[3], c[3], d[3];
+ fairing_context->adjacents_coords_from_loop(l_index, b, c);
+
+ if (angle_v3v3v3(c, fairing_context->vertex_deformation_co_get(i), b) < acute_threshold) {
+ calc_circumcenter(d, a, b, c);
+ }
+ else {
+ add_v3_v3v3(d, b, c);
+ mul_v3_fl(d, 0.5f);
+ }
+
+ float t[3];
+ add_v3_v3v3(t, a, b);
+ mul_v3_fl(t, 0.5f);
+ area += area_tri_v3(a, t, d);
+
+ add_v3_v3v3(t, a, c);
+ mul_v3_fl(t, 0.5f);
+ area += area_tri_v3(a, d, t);
+ }
+
+ vertex_weights_[i] = area != 0.0f ? 1.0f / area : 1e12;
+ }
+ }
+ ~VoronoiVertexWeight() = default;
+
+ float weight_at_index(const int index) override
+ {
+ return vertex_weights_[index];
+ }
+
+ private:
+ Vector<float> vertex_weights_;
+
+ void calc_circumcenter(float r[3], const float a[3], const float b[3], const float c[3])
+ {
+ float ab[3];
+ sub_v3_v3v3(ab, b, a);
+
+ float ac[3];
+ sub_v3_v3v3(ac, c, a);
+
+ float ab_cross_ac[3];
+ cross_v3_v3v3(ab_cross_ac, ab, ac);
+
+ if (len_squared_v3(ab_cross_ac) > 0.0f) {
+ float d[3];
+ cross_v3_v3v3(d, ab_cross_ac, ab);
+ mul_v3_fl(d, len_squared_v3(ac));
+
+ float t[3];
+ cross_v3_v3v3(t, ac, ab_cross_ac);
+ mul_v3_fl(t, len_squared_v3(ab));
+
+ add_v3_v3(d, t);
+
+ mul_v3_fl(d, 1.0f / (2.0f * len_squared_v3(ab_cross_ac)));
+
+ add_v3_v3v3(r, a, d);
+ return;
+ }
+ copy_v3_v3(r, a);
+ }
+};
+
+class UniformLoopWeight : public LoopWeight {
+ public:
+ float weight_at_index(const int UNUSED(index)) override
+ {
+ return 1.0f;
+ }
+};
+
+static void prefair_and_fair_vertices(FairingContext *fairing_context,
+ bool *affected_vertices,
+ const eMeshFairingDepth depth)
+{
+ /* Prefair. */
+ UniformVertexWeight *uniform_vertex_weights = new UniformVertexWeight(fairing_context);
+ UniformLoopWeight *uniform_loop_weights = new UniformLoopWeight();
+ fairing_context->fair_vertices(
+ affected_vertices, depth, uniform_vertex_weights, uniform_loop_weights);
+ delete uniform_vertex_weights;
+
+ /* Fair. */
+ VoronoiVertexWeight *voronoi_vertex_weights = new VoronoiVertexWeight(fairing_context);
+ /* TODO: Implemente cotangent loop weights. */
+ fairing_context->fair_vertices(
+ affected_vertices, depth, voronoi_vertex_weights, uniform_loop_weights);
+
+ delete uniform_loop_weights;
+ delete voronoi_vertex_weights;
+}
+
+void BKE_mesh_prefair_and_fair_vertices(struct Mesh *mesh,
+ struct MVert *deform_mverts,
+ bool *affect_vertices,
+ const eMeshFairingDepth depth)
+{
+ MeshFairingContext *fairing_context = new MeshFairingContext(mesh, deform_mverts);
+ prefair_and_fair_vertices(fairing_context, affect_vertices, depth);
+ delete fairing_context;
+}
+
+void BKE_bmesh_prefair_and_fair_vertices(struct BMesh *bm,
+ bool *affect_vertices,
+ const eMeshFairingDepth depth)
+{
+ BMeshFairingContext *fairing_context = new BMeshFairingContext(bm);
+ prefair_and_fair_vertices(fairing_context, affect_vertices, depth);
+ delete fairing_context;
+}
diff --git a/source/blender/blenkernel/intern/multires_unsubdivide.h b/source/blender/blenkernel/intern/multires_unsubdivide.h
index 39c6da0b6c8..0a03387282f 100644
--- a/source/blender/blenkernel/intern/multires_unsubdivide.h
+++ b/source/blender/blenkernel/intern/multires_unsubdivide.h
@@ -26,10 +26,8 @@
#include "BLI_sys_types.h"
struct BMesh;
-struct Depsgraph;
struct Mesh;
struct MultiresModifierData;
-struct Object;
typedef struct MultiresUnsubdivideGrid {
/* For sanity checks. */
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 87997198334..415eb14be66 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -4737,10 +4737,11 @@ static void registerGeometryNodes(void)
register_node_type_geo_point_distribute();
register_node_type_geo_point_instance();
register_node_type_geo_object_info();
- register_node_type_geo_random_attribute();
+ register_node_type_geo_attribute_randomize();
register_node_type_geo_attribute_math();
register_node_type_geo_join_geometry();
register_node_type_geo_attribute_mix();
+ register_node_type_geo_attribute_color_ramp();
}
static void registerFunctionNodes(void)
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index f63d443d29f..cc192c1c3c0 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -222,6 +222,7 @@ static void scene_init_data(ID *id)
/* Curve Profile */
scene->toolsettings->custom_bevel_profile_preset = BKE_curveprofile_add(PROF_PRESET_LINE);
+ scene->toolsettings->sequencer_tool_settings = SEQ_tool_settings_init();
for (size_t i = 0; i < ARRAY_SIZE(scene->orientation_slots); i++) {
scene->orientation_slots[i].index_custom = -1;
@@ -862,6 +863,9 @@ static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_addres
if (tos->custom_bevel_profile_preset) {
BKE_curveprofile_blend_write(writer, tos->custom_bevel_profile_preset);
}
+ if (tos->sequencer_tool_settings) {
+ BLO_write_struct(writer, SequencerToolSettings, tos->sequencer_tool_settings);
+ }
BKE_paint_blend_write(writer, &tos->imapaint.paint);
@@ -1121,6 +1125,8 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
if (sce->toolsettings->custom_bevel_profile_preset) {
BKE_curveprofile_blend_read(reader, sce->toolsettings->custom_bevel_profile_preset);
}
+
+ BLO_read_data_address(reader, &sce->toolsettings->sequencer_tool_settings);
}
if (sce->ed) {
@@ -1792,6 +1798,8 @@ ToolSettings *BKE_toolsettings_copy(ToolSettings *toolsettings, const int flag)
ts->gp_sculpt.cur_primitive = BKE_curvemapping_copy(ts->gp_sculpt.cur_primitive);
ts->custom_bevel_profile_preset = BKE_curveprofile_copy(ts->custom_bevel_profile_preset);
+
+ ts->sequencer_tool_settings = SEQ_tool_settings_copy(ts->sequencer_tool_settings);
return ts;
}
@@ -1850,6 +1858,10 @@ void BKE_toolsettings_free(ToolSettings *toolsettings)
BKE_curveprofile_free(toolsettings->custom_bevel_profile_preset);
}
+ if (toolsettings->sequencer_tool_settings) {
+ SEQ_tool_settings_free(toolsettings->sequencer_tool_settings);
+ }
+
MEM_freeN(toolsettings);
}