diff options
author | Jeroen Bakker <jeroen@blender.org> | 2022-04-06 13:24:44 +0300 |
---|---|---|
committer | Jeroen Bakker <jeroen@blender.org> | 2022-04-06 13:24:44 +0300 |
commit | f3f77d217518468b4298782974980bfd1488a588 (patch) | |
tree | d7102efe02f36ff7bf96f933054442f1aac18fe3 /source/blender/blenkernel/intern | |
parent | 093ebb71ee578e5dc367a04c9748b68a268e6284 (diff) | |
parent | 1ec93507e130d9e48aec5b74f84de0f0b2ab29c1 (diff) |
Merge branch 'master' into temp-T96710-pbvh-pixels
Diffstat (limited to 'source/blender/blenkernel/intern')
30 files changed, 1126 insertions, 971 deletions
diff --git a/source/blender/blenkernel/intern/attribute.c b/source/blender/blenkernel/intern/attribute.c index ba33a9fee97..c3d4eb72c0d 100644 --- a/source/blender/blenkernel/intern/attribute.c +++ b/source/blender/blenkernel/intern/attribute.c @@ -19,6 +19,7 @@ #include "DNA_pointcloud_types.h" #include "BLI_string_utf8.h" +#include "BLI_string_utils.h" #include "BKE_attribute.h" #include "BKE_curves.h" @@ -91,7 +92,8 @@ static CustomData *attribute_customdata_find(ID *id, CustomDataLayer *layer) for (AttributeDomain domain = 0; domain < ATTR_DOMAIN_NUM; domain++) { CustomData *customdata = info[domain].customdata; - if (customdata && ARRAY_HAS_ITEM(layer, customdata->layers, customdata->totlayer)) { + if (customdata && + ARRAY_HAS_ITEM((CustomDataLayer *)layer, customdata->layers, customdata->totlayer)) { return customdata; } } @@ -132,6 +134,44 @@ bool BKE_id_attribute_rename(ID *id, return true; } +typedef struct AttrUniqueData { + ID *id; +} AttrUniqueData; + +static bool unique_name_cb(void *arg, const char *name) +{ + AttrUniqueData *data = (AttrUniqueData *)arg; + + DomainInfo info[ATTR_DOMAIN_NUM]; + get_domains(data->id, info); + + for (AttributeDomain domain = ATTR_DOMAIN_POINT; domain < ATTR_DOMAIN_NUM; domain++) { + if (!info[domain].customdata) { + continue; + } + + CustomData *cdata = info[domain].customdata; + for (int i = 0; i < cdata->totlayer; i++) { + CustomDataLayer *layer = cdata->layers + i; + + if (STREQ(layer->name, name)) { + return true; + } + } + } + + return false; +} + +bool BKE_id_attribute_calc_unique_name(ID *id, const char *name, char *outname) +{ + AttrUniqueData data = {.id = id}; + + BLI_strncpy_utf8(outname, name, MAX_CUSTOMDATA_LAYER_NAME); + + return BLI_uniquename_cb(unique_name_cb, &data, NULL, '.', outname, MAX_CUSTOMDATA_LAYER_NAME); +} + CustomDataLayer *BKE_id_attribute_new( ID *id, const char *name, const int type, const AttributeDomain domain, ReportList *reports) { @@ -144,25 +184,30 @@ CustomDataLayer *BKE_id_attribute_new( return NULL; } + char uniquename[MAX_CUSTOMDATA_LAYER_NAME]; + BKE_id_attribute_calc_unique_name(id, name, uniquename); + switch (GS(id->name)) { case ID_ME: { Mesh *me = (Mesh *)id; BMEditMesh *em = me->edit_mesh; if (em != NULL) { - BM_data_layer_add_named(em->bm, customdata, type, name); + BM_data_layer_add_named(em->bm, customdata, type, uniquename); } else { - CustomData_add_layer_named(customdata, type, CD_DEFAULT, NULL, info[domain].length, name); + CustomData_add_layer_named( + customdata, type, CD_DEFAULT, NULL, info[domain].length, uniquename); } break; } default: { - CustomData_add_layer_named(customdata, type, CD_DEFAULT, NULL, info[domain].length, name); + CustomData_add_layer_named( + customdata, type, CD_DEFAULT, NULL, info[domain].length, uniquename); break; } } - const int index = CustomData_get_named_layer_index(customdata, type, name); + const int index = CustomData_get_named_layer_index(customdata, type, uniquename); return (index == -1) ? NULL : &(customdata->layers[index]); } @@ -229,7 +274,7 @@ CustomDataLayer *BKE_id_attribute_find(const ID *id, return NULL; } -int BKE_id_attributes_length(ID *id, const CustomDataMask mask) +int BKE_id_attributes_length(const ID *id, AttributeDomainMask domain_mask, CustomDataMask mask) { DomainInfo info[ATTR_DOMAIN_NUM]; get_domains(id, info); @@ -238,7 +283,8 @@ int BKE_id_attributes_length(ID *id, const CustomDataMask mask) for (AttributeDomain domain = 0; domain < ATTR_DOMAIN_NUM; domain++) { CustomData *customdata = info[domain].customdata; - if (customdata) { + + if (customdata && ((1 << (int)domain) & domain_mask)) { length += CustomData_number_of_layers_typemask(customdata, mask); } } @@ -246,14 +292,15 @@ int BKE_id_attributes_length(ID *id, const CustomDataMask mask) return length; } -AttributeDomain BKE_id_attribute_domain(ID *id, CustomDataLayer *layer) +AttributeDomain BKE_id_attribute_domain(ID *id, const CustomDataLayer *layer) { DomainInfo info[ATTR_DOMAIN_NUM]; get_domains(id, info); for (AttributeDomain domain = 0; domain < ATTR_DOMAIN_NUM; domain++) { CustomData *customdata = info[domain].customdata; - if (customdata && ARRAY_HAS_ITEM(layer, customdata->layers, customdata->totlayer)) { + if (customdata && + ARRAY_HAS_ITEM((CustomDataLayer *)layer, customdata->layers, customdata->totlayer)) { return domain; } } @@ -269,7 +316,8 @@ int BKE_id_attribute_data_length(ID *id, CustomDataLayer *layer) for (AttributeDomain domain = 0; domain < ATTR_DOMAIN_NUM; domain++) { CustomData *customdata = info[domain].customdata; - if (customdata && ARRAY_HAS_ITEM(layer, customdata->layers, customdata->totlayer)) { + if (customdata && + ARRAY_HAS_ITEM((CustomDataLayer *)layer, customdata->layers, customdata->totlayer)) { return info[domain].length; } } @@ -295,7 +343,7 @@ bool BKE_id_attribute_required(ID *id, CustomDataLayer *layer) CustomDataLayer *BKE_id_attributes_active_get(ID *id) { int active_index = *BKE_id_attributes_active_index_p(id); - if (active_index > BKE_id_attributes_length(id, CD_MASK_PROP_ALL)) { + if (active_index > BKE_id_attributes_length(id, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL)) { active_index = 0; } @@ -384,3 +432,237 @@ CustomData *BKE_id_attributes_iterator_next_domain(ID *id, CustomDataLayer *laye return NULL; } + +CustomDataLayer *BKE_id_attribute_from_index(ID *id, + int lookup_index, + AttributeDomainMask domain_mask, + CustomDataMask layer_mask) +{ + DomainInfo info[ATTR_DOMAIN_NUM]; + get_domains(id, info); + + int index = 0; + for (AttributeDomain domain = 0; domain < ATTR_DOMAIN_NUM; domain++) { + CustomData *customdata = info[domain].customdata; + + if (!customdata || !((1 << (int)domain) & domain_mask)) { + continue; + } + + for (int i = 0; i < customdata->totlayer; i++) { + if (!(layer_mask & CD_TYPE_AS_MASK(customdata->layers[i].type)) || + (CD_TYPE_AS_MASK(customdata->layers[i].type) & CD_FLAG_TEMPORARY)) { + continue; + } + + if (index == lookup_index) { + return customdata->layers + i; + } + + index++; + } + } + + return NULL; +} + +/** Get list of domain types but with ATTR_DOMAIN_FACE and + * ATTR_DOMAIN_CORNER swapped. + */ +static void get_domains_types(AttributeDomain domains[ATTR_DOMAIN_NUM]) +{ + for (AttributeDomain i = 0; i < ATTR_DOMAIN_NUM; i++) { + domains[i] = i; + } + + /* Swap corner and face. */ + SWAP(AttributeDomain, domains[ATTR_DOMAIN_FACE], domains[ATTR_DOMAIN_CORNER]); +} + +int BKE_id_attribute_to_index(const struct ID *id, + const CustomDataLayer *layer, + AttributeDomainMask domain_mask, + CustomDataMask layer_mask) +{ + if (!layer) { + return -1; + } + + DomainInfo info[ATTR_DOMAIN_NUM]; + AttributeDomain domains[ATTR_DOMAIN_NUM]; + get_domains_types(domains); + get_domains(id, info); + + int index = 0; + for (int i = 0; i < ATTR_DOMAIN_NUM; i++) { + if (!(domain_mask & (1 << domains[i])) || !info[domains[i]].customdata) { + continue; + } + + CustomData *cdata = info[domains[i]].customdata; + for (int j = 0; j < cdata->totlayer; j++) { + CustomDataLayer *layer_iter = cdata->layers + j; + + if (!(CD_TYPE_AS_MASK(layer_iter->type) & layer_mask) || + (CD_TYPE_AS_MASK(layer_iter->type) & CD_FLAG_TEMPORARY)) { + continue; + } + + if (layer == layer_iter) { + return index; + } + + index++; + } + } + + return -1; +} + +CustomDataLayer *BKE_id_attribute_subset_active_get(const ID *id, + int active_flag, + AttributeDomainMask domain_mask, + CustomDataMask mask) +{ + DomainInfo info[ATTR_DOMAIN_NUM]; + AttributeDomain domains[ATTR_DOMAIN_NUM]; + + get_domains_types(domains); + get_domains(id, info); + + CustomDataLayer *candidate = NULL; + for (int i = 0; i < ARRAY_SIZE(domains); i++) { + if (!((1 << domains[i]) & domain_mask) || !info[domains[i]].customdata) { + continue; + } + + CustomData *cdata = info[domains[i]].customdata; + + for (int j = 0; j < cdata->totlayer; j++) { + CustomDataLayer *layer = cdata->layers + j; + + if (!(CD_TYPE_AS_MASK(layer->type) & mask) || + (CD_TYPE_AS_MASK(layer->type) & CD_FLAG_TEMPORARY)) { + continue; + } + + if (layer->flag & active_flag) { + return layer; + } + + candidate = layer; + } + } + + return candidate; +} + +void BKE_id_attribute_subset_active_set(ID *id, + CustomDataLayer *layer, + int active_flag, + AttributeDomainMask domain_mask, + CustomDataMask mask) +{ + DomainInfo info[ATTR_DOMAIN_NUM]; + AttributeDomain domains[ATTR_DOMAIN_NUM]; + + get_domains_types(domains); + get_domains(id, info); + + for (int i = 0; i < ATTR_DOMAIN_NUM; i++) { + AttributeDomainMask domain_mask2 = (AttributeDomainMask)(1 << domains[i]); + + if (!(domain_mask2 & domain_mask) || !info[domains[i]].customdata) { + continue; + } + + CustomData *cdata = info[domains[i]].customdata; + + for (int j = 0; j < cdata->totlayer; j++) { + CustomDataLayer *layer_iter = cdata->layers + j; + + if (!(CD_TYPE_AS_MASK(layer_iter->type) & mask) || + (CD_TYPE_AS_MASK(layer_iter->type) & CD_FLAG_TEMPORARY)) { + continue; + } + + layer_iter->flag &= ~active_flag; + } + } + + layer->flag |= active_flag; +} + +CustomDataLayer *BKE_id_attributes_active_color_get(const ID *id) +{ + return BKE_id_attribute_subset_active_get( + id, CD_FLAG_COLOR_ACTIVE, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); +} + +void BKE_id_attributes_active_color_set(ID *id, CustomDataLayer *active_layer) +{ + BKE_id_attribute_subset_active_set( + id, active_layer, CD_FLAG_COLOR_ACTIVE, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); +} + +CustomDataLayer *BKE_id_attributes_render_color_get(const ID *id) +{ + return BKE_id_attribute_subset_active_get( + id, CD_FLAG_COLOR_RENDER, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); +} + +void BKE_id_attributes_render_color_set(ID *id, CustomDataLayer *active_layer) +{ + BKE_id_attribute_subset_active_set( + id, active_layer, CD_FLAG_COLOR_RENDER, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); +} + +void BKE_id_attribute_copy_domains_temp(short id_type, + const CustomData *vdata, + const CustomData *edata, + const CustomData *ldata, + const CustomData *pdata, + const CustomData *cdata, + ID *r_id) +{ + CustomData reset; + + CustomData_reset(&reset); + + switch (id_type) { + case ID_ME: { + Mesh *me = (Mesh *)r_id; + memset((void *)me, 0, sizeof(*me)); + + me->edit_mesh = NULL; + + me->vdata = vdata ? *vdata : reset; + me->edata = edata ? *edata : reset; + me->ldata = ldata ? *ldata : reset; + me->pdata = pdata ? *pdata : reset; + + break; + } + case ID_PT: { + PointCloud *pointcloud = (PointCloud *)r_id; + + memset((void *)pointcloud, 0, sizeof(*pointcloud)); + + pointcloud->pdata = vdata ? *vdata : reset; + break; + } + case ID_CV: { + Curves *curves = (Curves *)r_id; + + memset((void *)curves, 0, sizeof(*curves)); + + curves->geometry.point_data = vdata ? *vdata : reset; + curves->geometry.curve_data = cdata ? *cdata : reset; + break; + } + default: + break; + } + + *((short *)r_id->name) = id_type; +} diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index ff07d061a20..b9cd9e1ee59 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -1558,6 +1558,7 @@ void BKE_brush_init_curves_sculpt_settings(Brush *brush) brush->curves_sculpt_settings = MEM_callocN(sizeof(BrushCurvesSculptSettings), __func__); } brush->curves_sculpt_settings->add_amount = 1; + brush->curves_sculpt_settings->minimum_length = 0.01f; } struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode) @@ -1833,7 +1834,8 @@ void BKE_brush_sculpt_reset(Brush *br) br->tip_roundness = 1.0f; br->density = 1.0f; br->flag &= ~BRUSH_SPACE_ATTEN; - zero_v3(br->rgb); + copy_v3_fl(br->rgb, 1.0f); + zero_v3(br->secondary_rgb); break; case SCULPT_TOOL_SMEAR: br->alpha = 1.0f; diff --git a/source/blender/blenkernel/intern/bvhutils.cc b/source/blender/blenkernel/intern/bvhutils.cc index 01e4eb702cc..df266029506 100644 --- a/source/blender/blenkernel/intern/bvhutils.cc +++ b/source/blender/blenkernel/intern/bvhutils.cc @@ -562,6 +562,103 @@ static void mesh_edges_spherecast(void *userdata, */ /* -------------------------------------------------------------------- */ +/** \name Common Utils + * \{ */ + +static void bvhtree_from_mesh_setup_data(BVHTree *tree, + const BVHCacheType bvh_cache_type, + const MVert *vert, + const MEdge *edge, + const MFace *face, + const MLoop *loop, + const MLoopTri *looptri, + const float (*vert_normals)[3], + BVHTreeFromMesh *r_data) +{ + memset(r_data, 0, sizeof(*r_data)); + + r_data->tree = tree; + + r_data->vert = vert; + r_data->edge = edge; + r_data->face = face; + r_data->loop = loop; + r_data->looptri = looptri; + r_data->vert_normals = vert_normals; + + switch (bvh_cache_type) { + case BVHTREE_FROM_VERTS: + case BVHTREE_FROM_LOOSEVERTS: + /* a nullptr nearest callback works fine + * remember the min distance to point is the same as the min distance to BV of point */ + r_data->nearest_callback = nullptr; + r_data->raycast_callback = mesh_verts_spherecast; + break; + + case BVHTREE_FROM_EDGES: + case BVHTREE_FROM_LOOSEEDGES: + r_data->nearest_callback = mesh_edges_nearest_point; + r_data->raycast_callback = mesh_edges_spherecast; + break; + case BVHTREE_FROM_FACES: + r_data->nearest_callback = mesh_faces_nearest_point; + r_data->raycast_callback = mesh_faces_spherecast; + break; + case BVHTREE_FROM_LOOPTRI: + case BVHTREE_FROM_LOOPTRI_NO_HIDDEN: + r_data->nearest_callback = mesh_looptri_nearest_point; + r_data->raycast_callback = mesh_looptri_spherecast; + break; + case BVHTREE_FROM_EM_VERTS: + case BVHTREE_FROM_EM_EDGES: + case BVHTREE_FROM_EM_LOOPTRI: + case BVHTREE_MAX_ITEM: + BLI_assert(false); + break; + } +} + +static void bvhtree_from_editmesh_setup_data(BVHTree *tree, + const BVHCacheType bvh_cache_type, + struct BMEditMesh *em, + BVHTreeFromEditMesh *r_data) +{ + memset(r_data, 0, sizeof(*r_data)); + + r_data->tree = tree; + + r_data->em = em; + + switch (bvh_cache_type) { + case BVHTREE_FROM_EM_VERTS: + r_data->nearest_callback = nullptr; + r_data->raycast_callback = editmesh_verts_spherecast; + break; + case BVHTREE_FROM_EM_EDGES: + r_data->nearest_callback = nullptr; /* TODO */ + r_data->raycast_callback = nullptr; /* TODO */ + break; + case BVHTREE_FROM_EM_LOOPTRI: + r_data->nearest_callback = editmesh_looptri_nearest_point; + r_data->raycast_callback = editmesh_looptri_spherecast; + break; + + case BVHTREE_FROM_VERTS: + case BVHTREE_FROM_LOOSEVERTS: + case BVHTREE_FROM_EDGES: + case BVHTREE_FROM_LOOSEEDGES: + case BVHTREE_FROM_FACES: + case BVHTREE_FROM_LOOPTRI: + case BVHTREE_FROM_LOOPTRI_NO_HIDDEN: + case BVHTREE_MAX_ITEM: + BLI_assert(false); + break; + } +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Vertex Builder * \{ */ @@ -631,69 +728,22 @@ static BVHTree *bvhtree_from_mesh_verts_create_tree(float epsilon, return tree; } -static void bvhtree_from_mesh_verts_setup_data(BVHTreeFromMesh *data, - BVHTree *tree, - const bool is_cached, - const MVert *vert, - const bool vert_allocated) -{ - memset(data, 0, sizeof(*data)); - - data->tree = tree; - data->cached = is_cached; - - /* a nullptr nearest callback works fine - * remember the min distance to point is the same as the min distance to BV of point */ - data->nearest_callback = nullptr; - data->raycast_callback = mesh_verts_spherecast; - - data->vert = vert; - data->vert_allocated = vert_allocated; -} - BVHTree *bvhtree_from_editmesh_verts_ex(BVHTreeFromEditMesh *data, BMEditMesh *em, const BLI_bitmap *verts_mask, int verts_num_active, float epsilon, int tree_type, - int axis, - const BVHCacheType bvh_cache_type, - BVHCache **bvh_cache_p, - ThreadMutex *mesh_eval_mutex) + int axis) { BVHTree *tree = nullptr; + tree = bvhtree_from_editmesh_verts_create_tree( + epsilon, tree_type, axis, em, verts_mask, verts_num_active); - if (bvh_cache_p) { - bool lock_started = false; - data->cached = bvhcache_find( - bvh_cache_p, bvh_cache_type, &data->tree, &lock_started, mesh_eval_mutex); - - if (data->cached == false) { - tree = bvhtree_from_editmesh_verts_create_tree( - epsilon, tree_type, axis, em, verts_mask, verts_num_active); - bvhtree_balance(tree, true); - - /* Save on cache for later use */ - // printf("BVHTree built and saved on cache\n"); - bvhcache_insert(*bvh_cache_p, tree, bvh_cache_type); - data->cached = true; - } - bvhcache_unlock(*bvh_cache_p, lock_started); - } - else { - tree = bvhtree_from_editmesh_verts_create_tree( - epsilon, tree_type, axis, em, verts_mask, verts_num_active); - bvhtree_balance(tree, false); - } + bvhtree_balance(tree, false); - if (tree) { - memset(data, 0, sizeof(*data)); - data->tree = tree; - data->em = em; - data->nearest_callback = nullptr; - data->raycast_callback = editmesh_verts_spherecast; - data->cached = bvh_cache_p != nullptr; + if (data) { + bvhtree_from_editmesh_setup_data(tree, BVHTREE_FROM_EM_VERTS, em, data); } return tree; @@ -702,51 +752,30 @@ BVHTree *bvhtree_from_editmesh_verts_ex(BVHTreeFromEditMesh *data, BVHTree *bvhtree_from_editmesh_verts( BVHTreeFromEditMesh *data, BMEditMesh *em, float epsilon, int tree_type, int axis) { - return bvhtree_from_editmesh_verts_ex( - data, em, nullptr, -1, epsilon, tree_type, axis, BVHTREE_FROM_VERTS, nullptr, nullptr); + return bvhtree_from_editmesh_verts_ex(data, em, nullptr, -1, epsilon, tree_type, axis); } BVHTree *bvhtree_from_mesh_verts_ex(BVHTreeFromMesh *data, const MVert *vert, const int verts_num, - const bool vert_allocated, const BLI_bitmap *verts_mask, int verts_num_active, float epsilon, int tree_type, - int axis, - const BVHCacheType bvh_cache_type, - BVHCache **bvh_cache_p, - ThreadMutex *mesh_eval_mutex) + int axis) { - bool in_cache = false; - bool lock_started = false; BVHTree *tree = nullptr; - if (bvh_cache_p) { - in_cache = bvhcache_find(bvh_cache_p, bvh_cache_type, &tree, &lock_started, mesh_eval_mutex); - } + tree = bvhtree_from_mesh_verts_create_tree( + epsilon, tree_type, axis, vert, verts_num, verts_mask, verts_num_active); - if (in_cache == false) { - tree = bvhtree_from_mesh_verts_create_tree( - epsilon, tree_type, axis, vert, verts_num, verts_mask, verts_num_active); - bvhtree_balance(tree, bvh_cache_p != nullptr); - - if (bvh_cache_p) { - /* Save on cache for later use */ - // printf("BVHTree built and saved on cache\n"); - BVHCache *bvh_cache = *bvh_cache_p; - bvhcache_insert(bvh_cache, tree, bvh_cache_type); - in_cache = true; - } - } + bvhtree_balance(tree, false); - if (bvh_cache_p) { - bvhcache_unlock(*bvh_cache_p, lock_started); + if (data) { + /* Setup BVHTreeFromMesh */ + bvhtree_from_mesh_setup_data( + tree, BVHTREE_FROM_VERTS, vert, nullptr, nullptr, nullptr, nullptr, nullptr, data); } - /* Setup BVHTreeFromMesh */ - bvhtree_from_mesh_verts_setup_data(data, tree, in_cache, vert, vert_allocated); - return tree; } @@ -833,71 +862,22 @@ static BVHTree *bvhtree_from_mesh_edges_create_tree(const MVert *vert, return tree; } -static void bvhtree_from_mesh_edges_setup_data(BVHTreeFromMesh *data, - BVHTree *tree, - const bool is_cached, - const MVert *vert, - const bool vert_allocated, - const MEdge *edge, - const bool edge_allocated) -{ - memset(data, 0, sizeof(*data)); - - data->tree = tree; - - data->cached = is_cached; - - data->nearest_callback = mesh_edges_nearest_point; - data->raycast_callback = mesh_edges_spherecast; - - data->vert = vert; - data->vert_allocated = vert_allocated; - data->edge = edge; - data->edge_allocated = edge_allocated; -} - BVHTree *bvhtree_from_editmesh_edges_ex(BVHTreeFromEditMesh *data, BMEditMesh *em, const BLI_bitmap *edges_mask, int edges_num_active, float epsilon, int tree_type, - int axis, - const BVHCacheType bvh_cache_type, - BVHCache **bvh_cache_p, - ThreadMutex *mesh_eval_mutex) + int axis) { BVHTree *tree = nullptr; + tree = bvhtree_from_editmesh_edges_create_tree( + epsilon, tree_type, axis, em, edges_mask, edges_num_active); - if (bvh_cache_p) { - bool lock_started = false; - data->cached = bvhcache_find( - bvh_cache_p, bvh_cache_type, &data->tree, &lock_started, mesh_eval_mutex); - BVHCache *bvh_cache = *bvh_cache_p; - if (data->cached == false) { - tree = bvhtree_from_editmesh_edges_create_tree( - epsilon, tree_type, axis, em, edges_mask, edges_num_active); - bvhtree_balance(tree, true); - /* Save on cache for later use */ - // printf("BVHTree built and saved on cache\n"); - bvhcache_insert(bvh_cache, tree, bvh_cache_type); - data->cached = true; - } - bvhcache_unlock(bvh_cache, lock_started); - } - else { - tree = bvhtree_from_editmesh_edges_create_tree( - epsilon, tree_type, axis, em, edges_mask, edges_num_active); - bvhtree_balance(tree, false); - } + bvhtree_balance(tree, false); - if (tree) { - memset(data, 0, sizeof(*data)); - data->tree = tree; - data->em = em; - data->nearest_callback = nullptr; /* TODO */ - data->raycast_callback = nullptr; /* TODO */ - data->cached = bvh_cache_p != nullptr; + if (data) { + bvhtree_from_editmesh_setup_data(tree, BVHTREE_FROM_EM_EDGES, em, data); } return tree; @@ -906,58 +886,31 @@ BVHTree *bvhtree_from_editmesh_edges_ex(BVHTreeFromEditMesh *data, BVHTree *bvhtree_from_editmesh_edges( BVHTreeFromEditMesh *data, BMEditMesh *em, float epsilon, int tree_type, int axis) { - return bvhtree_from_editmesh_edges_ex( - data, em, nullptr, -1, epsilon, tree_type, axis, BVHTREE_FROM_VERTS, nullptr, nullptr); + return bvhtree_from_editmesh_edges_ex(data, em, nullptr, -1, epsilon, tree_type, axis); } BVHTree *bvhtree_from_mesh_edges_ex(BVHTreeFromMesh *data, const MVert *vert, - const bool vert_allocated, const MEdge *edge, const int edges_num, - const bool edge_allocated, const BLI_bitmap *edges_mask, int edges_num_active, float epsilon, int tree_type, - int axis, - const BVHCacheType bvh_cache_type, - BVHCache **bvh_cache_p, - ThreadMutex *mesh_eval_mutex) + int axis) { - bool in_cache = false; - bool lock_started = false; BVHTree *tree = nullptr; - if (bvh_cache_p) { - in_cache = bvhcache_find(bvh_cache_p, bvh_cache_type, &tree, &lock_started, mesh_eval_mutex); - } - - if (in_cache == false) { - tree = bvhtree_from_mesh_edges_create_tree( - vert, edge, edges_num, edges_mask, edges_num_active, epsilon, tree_type, axis); + tree = bvhtree_from_mesh_edges_create_tree( + vert, edge, edges_num, edges_mask, edges_num_active, epsilon, tree_type, axis); - if (bvh_cache_p) { - bvhtree_balance(tree, true); - - BVHCache *bvh_cache = *bvh_cache_p; - /* Save on cache for later use */ - // printf("BVHTree built and saved on cache\n"); - bvhcache_insert(bvh_cache, tree, bvh_cache_type); - in_cache = true; - } - else { - bvhtree_balance(tree, false); - } - } + bvhtree_balance(tree, false); - if (bvh_cache_p) { - bvhcache_unlock(*bvh_cache_p, lock_started); + if (data) { + /* Setup BVHTreeFromMesh */ + bvhtree_from_mesh_setup_data( + tree, BVHTREE_FROM_EDGES, vert, edge, nullptr, nullptr, nullptr, nullptr, data); } - /* Setup BVHTreeFromMesh */ - bvhtree_from_mesh_edges_setup_data( - data, tree, in_cache, vert, vert_allocated, edge, edge_allocated); - return tree; } @@ -1014,72 +967,28 @@ static BVHTree *bvhtree_from_mesh_faces_create_tree(float epsilon, return tree; } -static void bvhtree_from_mesh_faces_setup_data(BVHTreeFromMesh *data, - BVHTree *tree, - const bool is_cached, - const MVert *vert, - const bool vert_allocated, - const MFace *face, - const bool face_allocated) -{ - memset(data, 0, sizeof(*data)); - - data->tree = tree; - data->cached = is_cached; - - data->nearest_callback = mesh_faces_nearest_point; - data->raycast_callback = mesh_faces_spherecast; - - data->vert = vert; - data->vert_allocated = vert_allocated; - data->face = face; - data->face_allocated = face_allocated; -} - BVHTree *bvhtree_from_mesh_faces_ex(BVHTreeFromMesh *data, const MVert *vert, - const bool vert_allocated, const MFace *face, const int numFaces, - const bool face_allocated, const BLI_bitmap *faces_mask, int faces_num_active, float epsilon, int tree_type, - int axis, - const BVHCacheType bvh_cache_type, - BVHCache **bvh_cache_p, - ThreadMutex *mesh_eval_mutex) + int axis) { - bool in_cache = false; - bool lock_started = false; BVHTree *tree = nullptr; - if (bvh_cache_p) { - in_cache = bvhcache_find(bvh_cache_p, bvh_cache_type, &tree, &lock_started, mesh_eval_mutex); - } + tree = bvhtree_from_mesh_faces_create_tree( + epsilon, tree_type, axis, vert, face, numFaces, faces_mask, faces_num_active); - if (in_cache == false) { - tree = bvhtree_from_mesh_faces_create_tree( - epsilon, tree_type, axis, vert, face, numFaces, faces_mask, faces_num_active); - bvhtree_balance(tree, bvh_cache_p != nullptr); - - if (bvh_cache_p) { - /* Save on cache for later use */ - // printf("BVHTree built and saved on cache\n"); - BVHCache *bvh_cache = *bvh_cache_p; - bvhcache_insert(bvh_cache, tree, bvh_cache_type); - in_cache = true; - } - } + bvhtree_balance(tree, false); - if (bvh_cache_p) { - bvhcache_unlock(*bvh_cache_p, lock_started); + if (data) { + /* Setup BVHTreeFromMesh */ + bvhtree_from_mesh_setup_data( + tree, BVHTREE_FROM_FACES, vert, nullptr, face, nullptr, nullptr, nullptr, data); } - /* Setup BVHTreeFromMesh */ - bvhtree_from_mesh_faces_setup_data( - data, tree, in_cache, vert, vert_allocated, face, face_allocated); - return tree; } @@ -1183,75 +1092,25 @@ static BVHTree *bvhtree_from_mesh_looptri_create_tree(float epsilon, return tree; } -static void bvhtree_from_mesh_looptri_setup_data(BVHTreeFromMesh *data, - BVHTree *tree, - const bool is_cached, - const MVert *vert, - const bool vert_allocated, - const MLoop *mloop, - const bool loop_allocated, - const MLoopTri *looptri, - const bool looptri_allocated) -{ - memset(data, 0, sizeof(*data)); - - data->tree = tree; - data->cached = is_cached; - - data->nearest_callback = mesh_looptri_nearest_point; - data->raycast_callback = mesh_looptri_spherecast; - - data->vert = vert; - data->vert_allocated = vert_allocated; - data->loop = mloop; - data->loop_allocated = loop_allocated; - data->looptri = looptri; - data->looptri_allocated = looptri_allocated; -} - BVHTree *bvhtree_from_editmesh_looptri_ex(BVHTreeFromEditMesh *data, BMEditMesh *em, const BLI_bitmap *looptri_mask, int looptri_num_active, float epsilon, int tree_type, - int axis, - const BVHCacheType bvh_cache_type, - BVHCache **bvh_cache_p, - ThreadMutex *mesh_eval_mutex) + int axis) { /* BMESH specific check that we have tessfaces, * we _could_ tessellate here but rather not - campbell */ BVHTree *tree = nullptr; - if (bvh_cache_p) { - bool lock_started = false; - bool in_cache = bvhcache_find( - bvh_cache_p, bvh_cache_type, &tree, &lock_started, mesh_eval_mutex); - BVHCache *bvh_cache = *bvh_cache_p; - if (in_cache == false) { - tree = bvhtree_from_editmesh_looptri_create_tree( - epsilon, tree_type, axis, em, looptri_mask, looptri_num_active); - bvhtree_balance(tree, true); - - /* Save on cache for later use */ - // printf("BVHTree built and saved on cache\n"); - bvhcache_insert(bvh_cache, tree, bvh_cache_type); - } - bvhcache_unlock(bvh_cache, lock_started); - } - else { - tree = bvhtree_from_editmesh_looptri_create_tree( - epsilon, tree_type, axis, em, looptri_mask, looptri_num_active); - bvhtree_balance(tree, false); - } + tree = bvhtree_from_editmesh_looptri_create_tree( + epsilon, tree_type, axis, em, looptri_mask, looptri_num_active); - if (tree) { - data->tree = tree; - data->nearest_callback = editmesh_looptri_nearest_point; - data->raycast_callback = editmesh_looptri_spherecast; - data->em = em; - data->cached = bvh_cache_p != nullptr; + bvhtree_balance(tree, false); + + if (data) { + bvhtree_from_editmesh_setup_data(tree, BVHTREE_FROM_EM_LOOPTRI, em, data); } return tree; } @@ -1259,70 +1118,39 @@ BVHTree *bvhtree_from_editmesh_looptri_ex(BVHTreeFromEditMesh *data, BVHTree *bvhtree_from_editmesh_looptri( BVHTreeFromEditMesh *data, BMEditMesh *em, float epsilon, int tree_type, int axis) { - return bvhtree_from_editmesh_looptri_ex( - data, em, nullptr, -1, epsilon, tree_type, axis, BVHTREE_FROM_VERTS, nullptr, nullptr); + return bvhtree_from_editmesh_looptri_ex(data, em, nullptr, -1, epsilon, tree_type, axis); } BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data, const struct MVert *vert, - const bool vert_allocated, const struct MLoop *mloop, - const bool loop_allocated, const struct MLoopTri *looptri, const int looptri_num, - const bool looptri_allocated, const BLI_bitmap *looptri_mask, int looptri_num_active, float epsilon, int tree_type, - int axis, - const BVHCacheType bvh_cache_type, - BVHCache **bvh_cache_p, - ThreadMutex *mesh_eval_mutex) + int axis) { - bool in_cache = false; - bool lock_started = false; BVHTree *tree = nullptr; - if (bvh_cache_p) { - in_cache = bvhcache_find(bvh_cache_p, bvh_cache_type, &tree, &lock_started, mesh_eval_mutex); - } + tree = bvhtree_from_mesh_looptri_create_tree(epsilon, + tree_type, + axis, + vert, + mloop, + looptri, + looptri_num, + looptri_mask, + looptri_num_active); - if (in_cache == false) { - /* Setup BVHTreeFromMesh */ - tree = bvhtree_from_mesh_looptri_create_tree(epsilon, - tree_type, - axis, - vert, - mloop, - looptri, - looptri_num, - looptri_mask, - looptri_num_active); - - bvhtree_balance(tree, bvh_cache_p != nullptr); - - if (bvh_cache_p) { - BVHCache *bvh_cache = *bvh_cache_p; - bvhcache_insert(bvh_cache, tree, bvh_cache_type); - in_cache = true; - } - } + bvhtree_balance(tree, false); - if (bvh_cache_p) { - bvhcache_unlock(*bvh_cache_p, lock_started); + if (data) { + /* Setup BVHTreeFromMesh */ + bvhtree_from_mesh_setup_data( + tree, BVHTREE_FROM_LOOPTRI, vert, nullptr, nullptr, mloop, looptri, nullptr, data); } - /* Setup BVHTreeFromMesh */ - bvhtree_from_mesh_looptri_setup_data(data, - tree, - in_cache, - vert, - vert_allocated, - mloop, - loop_allocated, - looptri, - looptri_allocated); - return tree; } @@ -1410,158 +1238,112 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, const BVHCacheType bvh_cache_type, const int tree_type) { - BVHTree *tree = nullptr; BVHCache **bvh_cache_p = (BVHCache **)&mesh->runtime.bvh_cache; ThreadMutex *mesh_eval_mutex = (ThreadMutex *)mesh->runtime.eval_mutex; - const bool is_cached = bvhcache_find(bvh_cache_p, bvh_cache_type, &tree, nullptr, nullptr); + /* Setup BVHTreeFromMesh */ + bvhtree_from_mesh_setup_data( + nullptr, + bvh_cache_type, + mesh->mvert, + mesh->medge, + mesh->mface, + mesh->mloop, + ELEM(bvh_cache_type, BVHTREE_FROM_LOOPTRI, BVHTREE_FROM_LOOPTRI_NO_HIDDEN) ? + BKE_mesh_runtime_looptri_ensure(mesh) : + nullptr, + BKE_mesh_vertex_normals_ensure(mesh), + data); - if (is_cached && tree == nullptr) { - memset(data, 0, sizeof(*data)); - return tree; + bool lock_started = false; + data->cached = bvhcache_find( + bvh_cache_p, bvh_cache_type, &data->tree, &lock_started, mesh_eval_mutex); + + if (data->cached) { + BLI_assert(lock_started == false); + + /* NOTE: #data->tree can be nullptr. */ + return data->tree; } + /* Create BVHTree. */ + switch (bvh_cache_type) { case BVHTREE_FROM_VERTS: - case BVHTREE_FROM_LOOSEVERTS: - if (is_cached == false) { - BLI_bitmap *loose_verts_mask = nullptr; - int loose_vert_len = -1; - int verts_len = mesh->totvert; - - if (bvh_cache_type == BVHTREE_FROM_LOOSEVERTS) { - loose_verts_mask = loose_verts_map_get( - mesh->medge, mesh->totedge, mesh->mvert, verts_len, &loose_vert_len); - } - - tree = bvhtree_from_mesh_verts_ex(data, - mesh->mvert, - verts_len, - false, - loose_verts_mask, - loose_vert_len, - 0.0f, - tree_type, - 6, - bvh_cache_type, - bvh_cache_p, - mesh_eval_mutex); - - if (loose_verts_mask != nullptr) { - MEM_freeN(loose_verts_mask); - } + case BVHTREE_FROM_LOOSEVERTS: { + BLI_bitmap *loose_verts_mask = nullptr; + int loose_vert_len = -1; + int verts_len = mesh->totvert; + + if (bvh_cache_type == BVHTREE_FROM_LOOSEVERTS) { + loose_verts_mask = loose_verts_map_get( + mesh->medge, mesh->totedge, mesh->mvert, verts_len, &loose_vert_len); } - else { - /* Setup BVHTreeFromMesh */ - bvhtree_from_mesh_verts_setup_data(data, tree, true, mesh->mvert, false); + + data->tree = bvhtree_from_mesh_verts_create_tree( + 0.0f, tree_type, 6, mesh->mvert, verts_len, loose_verts_mask, loose_vert_len); + + if (loose_verts_mask != nullptr) { + MEM_freeN(loose_verts_mask); } - break; + } break; case BVHTREE_FROM_EDGES: - case BVHTREE_FROM_LOOSEEDGES: - if (is_cached == false) { - BLI_bitmap *loose_edges_mask = nullptr; - int loose_edges_len = -1; - int edges_len = mesh->totedge; - - if (bvh_cache_type == BVHTREE_FROM_LOOSEEDGES) { - loose_edges_mask = loose_edges_map_get(mesh->medge, edges_len, &loose_edges_len); - } + case BVHTREE_FROM_LOOSEEDGES: { + BLI_bitmap *loose_edges_mask = nullptr; + int loose_edges_len = -1; + int edges_len = mesh->totedge; - tree = bvhtree_from_mesh_edges_ex(data, - mesh->mvert, - false, - mesh->medge, - edges_len, - false, - loose_edges_mask, - loose_edges_len, - 0.0, - tree_type, - 6, - bvh_cache_type, - bvh_cache_p, - mesh_eval_mutex); - - if (loose_edges_mask != nullptr) { - MEM_freeN(loose_edges_mask); - } + if (bvh_cache_type == BVHTREE_FROM_LOOSEEDGES) { + loose_edges_mask = loose_edges_map_get(mesh->medge, edges_len, &loose_edges_len); } - else { - /* Setup BVHTreeFromMesh */ - bvhtree_from_mesh_edges_setup_data( - data, tree, true, mesh->mvert, false, mesh->medge, false); - } - break; - case BVHTREE_FROM_FACES: - if (is_cached == false) { - int num_faces = mesh->totface; - BLI_assert(!(num_faces == 0 && mesh->totpoly != 0)); - - tree = bvhtree_from_mesh_faces_ex(data, - mesh->mvert, - false, - mesh->mface, - num_faces, - false, - nullptr, - -1, - 0.0, - tree_type, - 6, - bvh_cache_type, - bvh_cache_p, - mesh_eval_mutex); - } - else { - /* Setup BVHTreeFromMesh */ - bvhtree_from_mesh_faces_setup_data( - data, tree, true, mesh->mvert, false, mesh->mface, false); + data->tree = bvhtree_from_mesh_edges_create_tree(mesh->mvert, + mesh->medge, + edges_len, + loose_edges_mask, + loose_edges_len, + 0.0f, + tree_type, + 6); + + if (loose_edges_mask != nullptr) { + MEM_freeN(loose_edges_mask); } - break; + } break; - case BVHTREE_FROM_LOOPTRI: - case BVHTREE_FROM_LOOPTRI_NO_HIDDEN: - if (is_cached == false) { - const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); - int looptri_len = BKE_mesh_runtime_looptri_len(mesh); - - int looptri_mask_active_len = -1; - BLI_bitmap *looptri_mask = nullptr; - if (bvh_cache_type == BVHTREE_FROM_LOOPTRI_NO_HIDDEN) { - looptri_mask = looptri_no_hidden_map_get( - mesh->mpoly, looptri_len, &looptri_mask_active_len); - } + case BVHTREE_FROM_FACES: { + BLI_assert(!(mesh->totface == 0 && mesh->totpoly != 0)); - tree = bvhtree_from_mesh_looptri_ex(data, - mesh->mvert, - false, - mesh->mloop, - false, - mlooptri, - looptri_len, - false, - looptri_mask, - looptri_mask_active_len, - 0.0, - tree_type, - 6, - bvh_cache_type, - bvh_cache_p, - mesh_eval_mutex); - - if (looptri_mask != nullptr) { - MEM_freeN(looptri_mask); - } + data->tree = bvhtree_from_mesh_faces_create_tree( + 0.0f, tree_type, 6, mesh->mvert, mesh->mface, mesh->totface, nullptr, -1); + } break; + + case BVHTREE_FROM_LOOPTRI: + case BVHTREE_FROM_LOOPTRI_NO_HIDDEN: { + int looptri_len = BKE_mesh_runtime_looptri_len(mesh); + + int looptri_mask_active_len = -1; + BLI_bitmap *looptri_mask = nullptr; + if (bvh_cache_type == BVHTREE_FROM_LOOPTRI_NO_HIDDEN) { + looptri_mask = looptri_no_hidden_map_get( + mesh->mpoly, looptri_len, &looptri_mask_active_len); } - else { - /* Setup BVHTreeFromMesh */ - const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); - bvhtree_from_mesh_looptri_setup_data( - data, tree, true, mesh->mvert, false, mesh->mloop, false, mlooptri, false); + + data->tree = bvhtree_from_mesh_looptri_create_tree(0.0f, + tree_type, + 6, + mesh->mvert, + mesh->mloop, + data->looptri, + looptri_len, + looptri_mask, + looptri_mask_active_len); + + if (looptri_mask != nullptr) { + MEM_freeN(looptri_mask); } - break; + } break; case BVHTREE_FROM_EM_VERTS: case BVHTREE_FROM_EM_EDGES: case BVHTREE_FROM_EM_LOOPTRI: @@ -1570,24 +1352,26 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, break; } - if (data->tree != nullptr) { + bvhtree_balance(data->tree, lock_started); + + /* Save on cache for later use */ + // printf("BVHTree built and saved on cache\n"); + BLI_assert(data->cached == false); + data->cached = true; + bvhcache_insert(*bvh_cache_p, data->tree, bvh_cache_type); + bvhcache_unlock(*bvh_cache_p, lock_started); + #ifdef DEBUG + if (data->tree != nullptr) { if (BLI_bvhtree_get_tree_type(data->tree) != tree_type) { printf("tree_type %d obtained instead of %d\n", BLI_bvhtree_get_tree_type(data->tree), tree_type); } -#endif - BLI_assert(data->cached); } - else { - free_bvhtree_from_mesh(data); - memset(data, 0, sizeof(*data)); - } - - data->vert_normals = BKE_mesh_vertex_normals_ensure(mesh); +#endif - return tree; + return data->tree; } BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data, @@ -1597,80 +1381,29 @@ BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data, BVHCache **bvh_cache_p, ThreadMutex *mesh_eval_mutex) { - BVHTree *tree = nullptr; - bool is_cached = false; + bool lock_started = false; - memset(data, 0, sizeof(*data)); + bvhtree_from_editmesh_setup_data(nullptr, bvh_cache_type, em, data); if (bvh_cache_p) { - is_cached = bvhcache_find(bvh_cache_p, bvh_cache_type, &tree, nullptr, nullptr); + data->cached = bvhcache_find( + bvh_cache_p, bvh_cache_type, &data->tree, &lock_started, mesh_eval_mutex); - if (is_cached && tree == nullptr) { - return tree; + if (data->cached) { + BLI_assert(lock_started == false); + return data->tree; } } - data->tree = tree; - data->em = em; - data->cached = is_cached; switch (bvh_cache_type) { case BVHTREE_FROM_EM_VERTS: - if (is_cached == false) { - tree = bvhtree_from_editmesh_verts_ex(data, - em, - nullptr, - -1, - 0.0f, - tree_type, - 6, - bvh_cache_type, - bvh_cache_p, - mesh_eval_mutex); - } - else { - data->nearest_callback = nullptr; - data->raycast_callback = editmesh_verts_spherecast; - } + data->tree = bvhtree_from_editmesh_verts_create_tree(0.0f, tree_type, 6, em, nullptr, -1); break; - case BVHTREE_FROM_EM_EDGES: - if (is_cached == false) { - tree = bvhtree_from_editmesh_edges_ex(data, - em, - nullptr, - -1, - 0.0f, - tree_type, - 6, - bvh_cache_type, - bvh_cache_p, - mesh_eval_mutex); - } - else { - /* Setup #BVHTreeFromMesh */ - data->nearest_callback = nullptr; /* TODO */ - data->raycast_callback = nullptr; /* TODO */ - } + data->tree = bvhtree_from_editmesh_edges_create_tree(0.0f, tree_type, 6, em, nullptr, -1); break; - case BVHTREE_FROM_EM_LOOPTRI: - if (is_cached == false) { - tree = bvhtree_from_editmesh_looptri_ex(data, - em, - nullptr, - -1, - 0.0f, - tree_type, - 6, - bvh_cache_type, - bvh_cache_p, - mesh_eval_mutex); - } - else { - /* Setup #BVHTreeFromMesh */ - data->nearest_callback = editmesh_looptri_nearest_point; - data->raycast_callback = editmesh_looptri_spherecast; - } + data->tree = bvhtree_from_editmesh_looptri_create_tree(0.0f, tree_type, 6, em, nullptr, -1); break; case BVHTREE_FROM_VERTS: case BVHTREE_FROM_EDGES: @@ -1684,22 +1417,28 @@ BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data, break; } - if (data->tree != nullptr) { + bvhtree_balance(data->tree, lock_started); + + if (bvh_cache_p) { + /* Save on cache for later use */ + // printf("BVHTree built and saved on cache\n"); + BLI_assert(data->cached == false); + data->cached = true; + bvhcache_insert(*bvh_cache_p, data->tree, bvh_cache_type); + bvhcache_unlock(*bvh_cache_p, lock_started); + } + #ifdef DEBUG + if (data->tree != nullptr) { if (BLI_bvhtree_get_tree_type(data->tree) != tree_type) { printf("tree_type %d obtained instead of %d\n", BLI_bvhtree_get_tree_type(data->tree), tree_type); } -#endif - BLI_assert(data->cached); - } - else { - free_bvhtree_from_editmesh(data); - memset(data, 0, sizeof(*data)); } +#endif - return tree; + return data->tree; } /** \} */ @@ -1724,22 +1463,6 @@ void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data) BLI_bvhtree_free(data->tree); } - if (data->vert_allocated) { - MEM_freeN((void *)data->vert); - } - if (data->edge_allocated) { - MEM_freeN((void *)data->edge); - } - if (data->face_allocated) { - MEM_freeN((void *)data->face); - } - if (data->loop_allocated) { - MEM_freeN((void *)data->loop); - } - if (data->looptri_allocated) { - MEM_freeN((void *)data->looptri); - } - memset(data, 0, sizeof(*data)); } diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index b840fb1e665..3897df9f05f 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -552,12 +552,11 @@ void BKE_camera_view_frame(const Scene *scene, const Camera *camera, float r_vec typedef struct CameraViewFrameData { float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][4]; /* 4 planes normalized */ float dist_vals[CAMERA_VIEWFRAME_NUM_PLANES]; /* distance (signed) */ + float camera_no[3]; + float z_range[2]; unsigned int tot; - /* Ortho camera only. */ - bool is_ortho; - float camera_no[3]; - float dist_to_cam; + bool do_zrange; /* Not used by callbacks... */ float camera_rotmat[3][3]; @@ -572,9 +571,10 @@ static void camera_to_frame_view_cb(const float co[3], void *user_data) CLAMP_MAX(data->dist_vals[i], nd); } - if (data->is_ortho) { + if (data->do_zrange) { const float d = dot_v3v3(data->camera_no, co); - CLAMP_MAX(data->dist_to_cam, d); + CLAMP_MAX(data->z_range[0], d); + CLAMP_MIN(data->z_range[1], d); } data->tot++; @@ -582,6 +582,7 @@ static void camera_to_frame_view_cb(const float co[3], void *user_data) static void camera_frame_fit_data_init(const Scene *scene, const Object *ob, + const bool do_clip_dists, CameraParams *params, CameraViewFrameData *data) { @@ -626,22 +627,27 @@ static void camera_frame_fit_data_init(const Scene *scene, mul_m4_v4(camera_rotmat_transposed_inversed, data->plane_tx[i]); /* Normalize. */ data->plane_tx[i][3] /= normalize_v3(data->plane_tx[i]); + + data->dist_vals[i] = FLT_MAX; } - copy_v4_fl(data->dist_vals, FLT_MAX); data->tot = 0; - data->is_ortho = params->is_ortho; - if (params->is_ortho) { - /* we want (0, 0, -1) transformed by camera_rotmat, this is a quicker shortcut. */ + data->do_zrange = params->is_ortho || do_clip_dists; + + if (data->do_zrange) { + /* We want (0, 0, -1) transformed by camera_rotmat, this is a quicker shortcut. */ negate_v3_v3(data->camera_no, data->camera_rotmat[2]); - data->dist_to_cam = FLT_MAX; + data->z_range[0] = FLT_MAX; + data->z_range[1] = -FLT_MAX; } } static bool camera_frame_fit_calc_from_data(CameraParams *params, CameraViewFrameData *data, float r_co[3], - float *r_scale) + float *r_scale, + float *r_clip_start, + float *r_clip_end) { float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][4]; @@ -669,37 +675,38 @@ static bool camera_frame_fit_calc_from_data(CameraParams *params, zero_v3(r_co); madd_v3_v3fl(r_co, cam_axis_x, (dists[2] - dists[0]) * 0.5f + params->shiftx * scale_diff); madd_v3_v3fl(r_co, cam_axis_y, (dists[1] - dists[3]) * 0.5f + params->shifty * scale_diff); - madd_v3_v3fl(r_co, cam_axis_z, -(data->dist_to_cam - 1.0f - params->clip_start)); - - return true; + madd_v3_v3fl(r_co, cam_axis_z, -(data->z_range[0] - 1.0f - params->clip_start)); } + else { + float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3]; + float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3]; - float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3]; - float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3]; + float plane_isect_pt_1[3], plane_isect_pt_2[3]; - float plane_isect_pt_1[3], plane_isect_pt_2[3]; + /* apply the dist-from-plane's to the transformed plane points */ + for (int i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) { + float co[3]; + mul_v3_v3fl(co, data->plane_tx[i], data->dist_vals[i]); + plane_from_point_normal_v3(plane_tx[i], co, data->plane_tx[i]); + } - /* apply the dist-from-plane's to the transformed plane points */ - for (int i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) { - float co[3]; - mul_v3_v3fl(co, data->plane_tx[i], data->dist_vals[i]); - plane_from_point_normal_v3(plane_tx[i], co, data->plane_tx[i]); - } + if ((!isect_plane_plane_v3(plane_tx[0], plane_tx[2], plane_isect_1, plane_isect_1_no)) || + (!isect_plane_plane_v3(plane_tx[1], plane_tx[3], plane_isect_2, plane_isect_2_no))) { + return false; + } - if ((!isect_plane_plane_v3(plane_tx[0], plane_tx[2], plane_isect_1, plane_isect_1_no)) || - (!isect_plane_plane_v3(plane_tx[1], plane_tx[3], plane_isect_2, plane_isect_2_no))) { - return false; - } + add_v3_v3v3(plane_isect_1_other, plane_isect_1, plane_isect_1_no); + add_v3_v3v3(plane_isect_2_other, plane_isect_2, plane_isect_2_no); - add_v3_v3v3(plane_isect_1_other, plane_isect_1, plane_isect_1_no); - add_v3_v3v3(plane_isect_2_other, plane_isect_2, plane_isect_2_no); + if (!isect_line_line_v3(plane_isect_1, + plane_isect_1_other, + plane_isect_2, + plane_isect_2_other, + plane_isect_pt_1, + plane_isect_pt_2) != 0) { + return false; + } - if (isect_line_line_v3(plane_isect_1, - plane_isect_1_other, - plane_isect_2, - plane_isect_2_other, - plane_isect_pt_1, - plane_isect_pt_2) != 0) { float cam_plane_no[3]; float plane_isect_delta[3]; float plane_isect_delta_len; @@ -728,15 +735,23 @@ static bool camera_frame_fit_calc_from_data(CameraParams *params, normalize_v3(plane_isect_2_no); madd_v3_v3fl(r_co, plane_isect_2_no, params->shiftx * plane_isect_delta_len * shift_fac); } - - return true; } - return false; + if (r_clip_start && r_clip_end) { + const float z_offs = dot_v3v3(r_co, data->camera_no); + *r_clip_start = data->z_range[0] - z_offs; + *r_clip_end = data->z_range[1] - z_offs; + } + return true; } -bool BKE_camera_view_frame_fit_to_scene( - Depsgraph *depsgraph, const Scene *scene, Object *camera_ob, float r_co[3], float *r_scale) +bool BKE_camera_view_frame_fit_to_scene(Depsgraph *depsgraph, + const Scene *scene, + Object *camera_ob, + float r_co[3], + float *r_scale, + float *r_clip_start, + float *r_clip_end) { CameraParams params; CameraViewFrameData data_cb; @@ -744,12 +759,13 @@ bool BKE_camera_view_frame_fit_to_scene( /* just in case */ *r_scale = 1.0f; - camera_frame_fit_data_init(scene, camera_ob, ¶ms, &data_cb); + camera_frame_fit_data_init(scene, camera_ob, r_clip_start && r_clip_end, ¶ms, &data_cb); /* run callback on all visible points */ BKE_scene_foreach_display_point(depsgraph, camera_to_frame_view_cb, &data_cb); - return camera_frame_fit_calc_from_data(¶ms, &data_cb, r_co, r_scale); + return camera_frame_fit_calc_from_data( + ¶ms, &data_cb, r_co, r_scale, r_clip_start, r_clip_end); } bool BKE_camera_view_frame_fit_to_coords(const Depsgraph *depsgraph, @@ -767,14 +783,14 @@ bool BKE_camera_view_frame_fit_to_coords(const Depsgraph *depsgraph, /* just in case */ *r_scale = 1.0f; - camera_frame_fit_data_init(scene_eval, camera_ob_eval, ¶ms, &data_cb); + camera_frame_fit_data_init(scene_eval, camera_ob_eval, false, ¶ms, &data_cb); /* run callback on all given coordinates */ while (num_cos--) { camera_to_frame_view_cb(cos[num_cos], &data_cb); } - return camera_frame_fit_calc_from_data(¶ms, &data_cb, r_co, r_scale); + return camera_frame_fit_calc_from_data(¶ms, &data_cb, r_co, r_scale, NULL, NULL); } /** \} */ diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc index 26f5d7e9cb4..2d72ad28d18 100644 --- a/source/blender/blenkernel/intern/curve.cc +++ b/source/blender/blenkernel/intern/curve.cc @@ -123,8 +123,6 @@ static void curve_free_data(ID *id) MEM_SAFE_FREE(curve->str); MEM_SAFE_FREE(curve->strinfo); MEM_SAFE_FREE(curve->tb); - - delete curve->curve_eval; } static void curve_foreach_id(ID *id, LibraryForeachIDData *data) diff --git a/source/blender/blenkernel/intern/curve_bezier.cc b/source/blender/blenkernel/intern/curve_bezier.cc index 30a5869c976..dfe462d8566 100644 --- a/source/blender/blenkernel/intern/curve_bezier.cc +++ b/source/blender/blenkernel/intern/curve_bezier.cc @@ -218,6 +218,10 @@ void calculate_evaluated_positions(const Span<float3> positions, { BLI_assert(evaluated_offsets.last() == evaluated_positions.size()); BLI_assert(evaluated_offsets.size() == positions.size()); + if (evaluated_offsets.last() == 1) { + evaluated_positions.first() = positions.first(); + return; + } /* Evaluate the first segment. */ evaluate_segment(positions.first(), diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index 9258c1ffb66..6dd9460aaa9 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -2279,7 +2279,8 @@ bool CustomData_merge(const struct CustomData *source, newlayer->active_rnd = lastrender; newlayer->active_clone = lastclone; newlayer->active_mask = lastmask; - newlayer->flag |= flag & (CD_FLAG_EXTERNAL | CD_FLAG_IN_MEMORY); + newlayer->flag |= flag & (CD_FLAG_EXTERNAL | CD_FLAG_IN_MEMORY | CD_FLAG_COLOR_ACTIVE | + CD_FLAG_COLOR_RENDER); changed = true; if (layer->anonymous_id != nullptr) { diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c index 5be993ca1f7..2369ce88ebc 100644 --- a/source/blender/blenkernel/intern/data_transfer.c +++ b/source/blender/blenkernel/intern/data_transfer.c @@ -19,6 +19,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BKE_attribute.h" #include "BKE_customdata.h" #include "BKE_data_transfer.h" #include "BKE_deform.h" @@ -129,7 +130,10 @@ bool BKE_object_data_transfer_get_dttypes_capacity(const int dtdata_types, case DT_TYPE_UV: ret = true; break; - case DT_TYPE_VCOL: + case DT_TYPE_MPROPCOL_VERT: + case DT_TYPE_MLOOPCOL_VERT: + case DT_TYPE_MPROPCOL_LOOP: + case DT_TYPE_MLOOPCOL_LOOP: *r_advanced_mixing = true; *r_threshold = true; ret = true; @@ -209,12 +213,14 @@ int BKE_object_data_transfer_dttype_to_cdtype(const int dtdata_type) return CD_FAKE_SHARP; case DT_TYPE_FREESTYLE_FACE: return CD_FREESTYLE_FACE; - - case DT_TYPE_VCOL: - return CD_MLOOPCOL; case DT_TYPE_LNOR: return CD_FAKE_LNOR; - + case DT_TYPE_MLOOPCOL_VERT: + case DT_TYPE_MLOOPCOL_LOOP: + return CD_MLOOPCOL; + case DT_TYPE_MPROPCOL_VERT: + case DT_TYPE_MPROPCOL_LOOP: + return CD_PROP_COLOR; default: BLI_assert(0); } @@ -230,8 +236,12 @@ int BKE_object_data_transfer_dttype_to_srcdst_index(const int dtdata_type) return DT_MULTILAYER_INDEX_SHAPEKEY; case DT_TYPE_UV: return DT_MULTILAYER_INDEX_UV; - case DT_TYPE_VCOL: - return DT_MULTILAYER_INDEX_VCOL; + case DT_TYPE_MPROPCOL_VERT: + case DT_TYPE_MLOOPCOL_VERT: + return DT_MULTILAYER_INDEX_VCOL_VERT; + case DT_TYPE_MPROPCOL_LOOP: + case DT_TYPE_MLOOPCOL_LOOP: + return DT_MULTILAYER_INDEX_VCOL_LOOP; default: return DT_MULTILAYER_INDEX_INVALID; } @@ -1231,6 +1241,7 @@ void BKE_object_data_transfer_layout(struct Depsgraph *depsgraph, cddata_type = BKE_object_data_transfer_dttype_to_cdtype(dtdata_type); fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(dtdata_type); + if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) { fromlayers = fromlayers_select[fromto_idx]; tolayers = tolayers_select[fromto_idx]; diff --git a/source/blender/blenkernel/intern/displist.cc b/source/blender/blenkernel/intern/displist.cc index 791e0faab3b..8c1161d6ff6 100644 --- a/source/blender/blenkernel/intern/displist.cc +++ b/source/blender/blenkernel/intern/displist.cc @@ -948,12 +948,11 @@ static void displist_surf_indices(DispList *dl) } } -static void evaluate_surface_object(Depsgraph *depsgraph, - const Scene *scene, - Object *ob, - const bool for_render, - ListBase *r_dispbase, - Mesh **r_final) +static GeometrySet evaluate_surface_object(Depsgraph *depsgraph, + const Scene *scene, + Object *ob, + const bool for_render, + ListBase *r_dispbase) { BLI_assert(ob->type == OB_SURF); const Curve *cu = (const Curve *)ob->data; @@ -1036,8 +1035,7 @@ static void evaluate_surface_object(Depsgraph *depsgraph, if (!geometry_set.has_mesh()) { geometry_set.replace_mesh(BKE_mesh_new_nomain(0, 0, 0, 0, 0)); } - MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>(); - *r_final = mesh_component.release(); + return geometry_set; } static void rotateBevelPiece(const Curve *cu, @@ -1483,9 +1481,8 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph, ListBase *dispbase = &ob->runtime.curve_cache->disp; if (ob->type == OB_SURF) { - Mesh *mesh_eval; - evaluate_surface_object(depsgraph, scene, ob, for_render, dispbase, &mesh_eval); - BKE_object_eval_assign_data(ob, &mesh_eval->id, true); + GeometrySet geometry = evaluate_surface_object(depsgraph, scene, ob, for_render, dispbase); + ob->runtime.geometry_set_eval = new GeometrySet(std::move(geometry)); } else { GeometrySet geometry = evaluate_curve_type_object(depsgraph, scene, ob, for_render, dispbase); @@ -1497,7 +1494,7 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph, * the CurveEval data type was introduced, when an evaluated object's curve data was just a * copy of the original curve and everything else ended up in #CurveCache. */ CurveComponent &curve_component = geometry.get_component_for_write<CurveComponent>(); - cow_curve.curve_eval = curves_to_curve_eval(*curve_component.get_for_read()).release(); + cow_curve.curve_eval = curve_component.get_for_read(); BKE_object_eval_assign_data(ob, &cow_curve.id, false); } diff --git a/source/blender/blenkernel/intern/displist_tangent.c b/source/blender/blenkernel/intern/displist_tangent.c deleted file mode 100644 index eb6bdd8d5e9..00000000000 --- a/source/blender/blenkernel/intern/displist_tangent.c +++ /dev/null @@ -1,269 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/** \file - * \ingroup bke - */ - -#include "BLI_math.h" -#include "BLI_task.h" - -#include "BKE_displist.h" -#include "BKE_displist_tangent.h" - -#include "MEM_guardedalloc.h" - -/* interface */ -#include "mikktspace.h" - -/* -------------------------------------------------------------------- */ -/** \name Internal Types - * \{ */ - -typedef struct { - const DispList *dl; - float (*tangent)[4]; /* destination */ - /** Face normal for flat shading. */ - float (*fnormals)[3]; - /** Use by surfaces. Size of the surface in faces. */ - int u_len, v_len; -} SGLSLDisplistToTangent; - -/** \} */ - -/* ---------------------------------------------------------------------- */ -/** \name DL_INDEX3 tangents - * \{ */ - -static int dl3_ts_GetNumFaces(const SMikkTSpaceContext *pContext) -{ - SGLSLDisplistToTangent *dlt = pContext->m_pUserData; - - return dlt->dl->parts; -} - -static int dl3_ts_GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num) -{ - UNUSED_VARS(pContext, face_num); - - return 3; -} - -static void dl3_ts_GetPosition(const SMikkTSpaceContext *pContext, - float r_co[3], - const int face_num, - const int vert_index) -{ - SGLSLDisplistToTangent *dlt = pContext->m_pUserData; - const float(*verts)[3] = (float(*)[3])dlt->dl->verts; - const int(*idx)[3] = (int(*)[3])dlt->dl->index; - - copy_v3_v3(r_co, verts[idx[face_num][vert_index]]); -} - -static void dl3_ts_GetTextureCoordinate(const SMikkTSpaceContext *pContext, - float r_uv[2], - const int face_num, - const int vert_index) -{ - SGLSLDisplistToTangent *dlt = pContext->m_pUserData; - const int(*idx)[3] = (int(*)[3])dlt->dl->index; - - r_uv[0] = idx[face_num][vert_index] / (float)(dlt->dl->nr - 1); - r_uv[1] = 0.0f; -} - -static void dl3_ts_GetNormal(const SMikkTSpaceContext *pContext, - float r_no[3], - const int face_num, - const int vert_index) -{ - SGLSLDisplistToTangent *dlt = pContext->m_pUserData; - UNUSED_VARS(face_num, vert_index); - - copy_v3_v3(r_no, dlt->dl->nors); -} - -static void dl3_ts_SetTSpace(const SMikkTSpaceContext *pContext, - const float fvTangent[3], - const float fSign, - const int face_num, - const int vert_index) -{ - SGLSLDisplistToTangent *dlt = pContext->m_pUserData; - UNUSED_VARS(face_num, vert_index); - - copy_v3_v3(dlt->tangent[0], fvTangent); - dlt->tangent[0][3] = fSign; -} - -/** \} */ - -/* ---------------------------------------------------------------------- */ -/** \name DL_SURF tangents - * \{ */ - -static int dlsurf_ts_GetNumFaces(const SMikkTSpaceContext *pContext) -{ - SGLSLDisplistToTangent *dlt = pContext->m_pUserData; - - return dlt->v_len * dlt->u_len; -} - -static int dlsurf_ts_GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num) -{ - UNUSED_VARS(pContext, face_num); - - return 4; -} - -static int face_to_vert_index(SGLSLDisplistToTangent *dlt, - const int face_num, - const int vert_index) -{ - int u = face_num % dlt->u_len; - int v = face_num / dlt->u_len; - - if (vert_index == 0) { - u += 1; - } - else if (vert_index == 1) { - u += 1; - v += 1; - } - else if (vert_index == 2) { - v += 1; - } - - /* Cyclic correction. */ - u = u % dlt->dl->nr; - v = v % dlt->dl->parts; - - return v * dlt->dl->nr + u; -} - -static void dlsurf_ts_GetPosition(const SMikkTSpaceContext *pContext, - float r_co[3], - const int face_num, - const int vert_index) -{ - SGLSLDisplistToTangent *dlt = pContext->m_pUserData; - const float(*verts)[3] = (float(*)[3])dlt->dl->verts; - - copy_v3_v3(r_co, verts[face_to_vert_index(dlt, face_num, vert_index)]); -} - -static void dlsurf_ts_GetTextureCoordinate(const SMikkTSpaceContext *pContext, - float r_uv[2], - const int face_num, - const int vert_index) -{ - SGLSLDisplistToTangent *dlt = pContext->m_pUserData; - - int idx = face_to_vert_index(dlt, face_num, vert_index); - - /* NOTE: For some reason the shading U and V are swapped compared to the - * one described in the surface format. */ - r_uv[0] = (idx / dlt->dl->nr) / (float)(dlt->v_len); - r_uv[1] = (idx % dlt->dl->nr) / (float)(dlt->u_len); - - if (r_uv[0] == 0.0f && ELEM(vert_index, 1, 2)) { - r_uv[0] = 1.0f; - } - if (r_uv[1] == 0.0f && ELEM(vert_index, 0, 1)) { - r_uv[1] = 1.0f; - } -} - -static void dlsurf_ts_GetNormal(const SMikkTSpaceContext *pContext, - float r_no[3], - const int face_num, - const int vert_index) -{ - SGLSLDisplistToTangent *dlt = pContext->m_pUserData; - const float(*nors)[3] = (float(*)[3])dlt->dl->nors; - - if (dlt->fnormals) { - copy_v3_v3(r_no, dlt->fnormals[face_num]); - } - else { - copy_v3_v3(r_no, nors[face_to_vert_index(dlt, face_num, vert_index)]); - } -} - -static void dlsurf_ts_SetTSpace(const SMikkTSpaceContext *pContext, - const float fvTangent[3], - const float fSign, - const int face_num, - const int vert_index) -{ - SGLSLDisplistToTangent *dlt = pContext->m_pUserData; - UNUSED_VARS(face_num, vert_index); - - float *r_tan = dlt->tangent[face_num * 4 + vert_index]; - copy_v3_v3(r_tan, fvTangent); - r_tan[3] = fSign; -} - -/** \} */ - -/* ---------------------------------------------------------------------- */ -/** \name Entry point - * \{ */ - -void BKE_displist_tangent_calc(const DispList *dl, float (*fnormals)[3], float (**r_tangent)[4]) -{ - if (dl->type == DL_INDEX3) { - /* INDEX3 have only one tangent so we don't need actual allocation. */ - BLI_assert(*r_tangent != NULL); - - SGLSLDisplistToTangent mesh2tangent = { - .tangent = *r_tangent, - .dl = dl, - }; - SMikkTSpaceContext sContext = {NULL}; - SMikkTSpaceInterface sInterface = {NULL}; - sContext.m_pUserData = &mesh2tangent; - sContext.m_pInterface = &sInterface; - sInterface.m_getNumFaces = dl3_ts_GetNumFaces; - sInterface.m_getNumVerticesOfFace = dl3_ts_GetNumVertsOfFace; - sInterface.m_getPosition = dl3_ts_GetPosition; - sInterface.m_getTexCoord = dl3_ts_GetTextureCoordinate; - sInterface.m_getNormal = dl3_ts_GetNormal; - sInterface.m_setTSpaceBasic = dl3_ts_SetTSpace; - /* 0 if failed */ - genTangSpaceDefault(&sContext); - } - else if (dl->type == DL_SURF) { - SGLSLDisplistToTangent mesh2tangent = { - .dl = dl, - .u_len = dl->nr - ((dl->flag & DL_CYCL_U) ? 0 : 1), - .v_len = dl->parts - ((dl->flag & DL_CYCL_V) ? 0 : 1), - .fnormals = fnormals, - }; - - int loop_len = mesh2tangent.u_len * mesh2tangent.v_len * 4; - - if (*r_tangent == NULL) { - *r_tangent = MEM_mallocN(sizeof(float[4]) * loop_len, "displist tangents"); - } - mesh2tangent.tangent = *r_tangent; - SMikkTSpaceContext sContext = {NULL}; - SMikkTSpaceInterface sInterface = {NULL}; - sContext.m_pUserData = &mesh2tangent; - sContext.m_pInterface = &sInterface; - sInterface.m_getNumFaces = dlsurf_ts_GetNumFaces; - sInterface.m_getNumVerticesOfFace = dlsurf_ts_GetNumVertsOfFace; - sInterface.m_getPosition = dlsurf_ts_GetPosition; - sInterface.m_getTexCoord = dlsurf_ts_GetTextureCoordinate; - sInterface.m_getNormal = dlsurf_ts_GetNormal; - sInterface.m_setTSpaceBasic = dlsurf_ts_SetTSpace; - /* 0 if failed */ - genTangSpaceDefault(&sContext); - } - else { - /* Unsupported. */ - BLI_assert(0); - } -} - -/** \} */ diff --git a/source/blender/blenkernel/intern/geometry_component_curves.cc b/source/blender/blenkernel/intern/geometry_component_curves.cc index b5771cc063f..27c1a2f2f33 100644 --- a/source/blender/blenkernel/intern/geometry_component_curves.cc +++ b/source/blender/blenkernel/intern/geometry_component_curves.cc @@ -128,7 +128,7 @@ const Curve *CurveComponent::get_curve_for_render() const } curve_for_render_ = (Curve *)BKE_id_new_nomain(ID_CU_LEGACY, nullptr); - curve_for_render_->curve_eval = curves_to_curve_eval(*curves_).release(); + curve_for_render_->curve_eval = curves_; return curve_for_render_; } diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index f5ed21af19a..47f7bb00b8f 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -1187,8 +1187,7 @@ class NormalAttributeProvider final : public BuiltinAttributeProvider { static ComponentAttributeProviders create_attribute_providers_for_mesh() { static auto update_custom_data_pointers = [](GeometryComponent &component) { - Mesh *mesh = get_mesh_from_component_for_write(component); - if (mesh != nullptr) { + if (Mesh *mesh = get_mesh_from_component_for_write(component)) { BKE_mesh_update_customdata_pointers(mesh, false); } }; diff --git a/source/blender/blenkernel/intern/geometry_component_pointcloud.cc b/source/blender/blenkernel/intern/geometry_component_pointcloud.cc index 3db4db307a3..400e0ea5e15 100644 --- a/source/blender/blenkernel/intern/geometry_component_pointcloud.cc +++ b/source/blender/blenkernel/intern/geometry_component_pointcloud.cc @@ -125,8 +125,7 @@ static ComponentAttributeProviders create_attribute_providers_for_point_cloud() { static auto update_custom_data_pointers = [](GeometryComponent &component) { PointCloudComponent &pointcloud_component = static_cast<PointCloudComponent &>(component); - PointCloud *pointcloud = pointcloud_component.get_for_write(); - if (pointcloud != nullptr) { + if (PointCloud *pointcloud = pointcloud_component.get_for_write()) { BKE_pointcloud_update_customdata_pointers(pointcloud); } }; diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc index 0b08acf92a3..fc758e12c70 100644 --- a/source/blender/blenkernel/intern/geometry_set.cc +++ b/source/blender/blenkernel/intern/geometry_set.cc @@ -176,20 +176,16 @@ Vector<const GeometryComponent *> GeometrySet::get_components_for_read() const bool GeometrySet::compute_boundbox_without_instances(float3 *r_min, float3 *r_max) const { bool have_minmax = false; - const PointCloud *pointcloud = this->get_pointcloud_for_read(); - if (pointcloud != nullptr) { + if (const PointCloud *pointcloud = this->get_pointcloud_for_read()) { have_minmax |= BKE_pointcloud_minmax(pointcloud, *r_min, *r_max); } - const Mesh *mesh = this->get_mesh_for_read(); - if (mesh != nullptr) { + if (const Mesh *mesh = this->get_mesh_for_read()) { have_minmax |= BKE_mesh_wrapper_minmax(mesh, *r_min, *r_max); } - const Volume *volume = this->get_volume_for_read(); - if (volume != nullptr) { + if (const Volume *volume = this->get_volume_for_read()) { have_minmax |= BKE_volume_min_max(volume, *r_min, *r_max); } - const Curves *curves = this->get_curves_for_read(); - if (curves != nullptr) { + if (const Curves *curves = this->get_curves_for_read()) { std::unique_ptr<CurveEval> curve = curves_to_curve_eval(*curves); /* Using the evaluated positions is somewhat arbitrary, but it is probably expected. */ have_minmax |= curve->bounds_min_max(*r_min, *r_max, true); diff --git a/source/blender/blenkernel/intern/idtype.c b/source/blender/blenkernel/intern/idtype.c index 5b9dfa55c45..e55143d6852 100644 --- a/source/blender/blenkernel/intern/idtype.c +++ b/source/blender/blenkernel/intern/idtype.c @@ -33,7 +33,7 @@ uint BKE_idtype_cache_key_hash(const void *key_v) const IDCacheKey *key = key_v; size_t hash = BLI_ghashutil_uinthash(key->id_session_uuid); hash = BLI_ghashutil_combine_hash(hash, BLI_ghashutil_uinthash((uint)key->offset_in_ID)); - return (uint)BLI_ghashutil_combine_hash(hash, BLI_ghashutil_ptrhash(key->cache_v)); + return (uint)hash; } bool BKE_idtype_cache_key_cmp(const void *key_a_v, const void *key_b_v) @@ -41,7 +41,7 @@ bool BKE_idtype_cache_key_cmp(const void *key_a_v, const void *key_b_v) const IDCacheKey *key_a = key_a_v; const IDCacheKey *key_b = key_b_v; return (key_a->id_session_uuid != key_b->id_session_uuid) || - (key_a->offset_in_ID != key_b->offset_in_ID) || (key_a->cache_v != key_b->cache_v); + (key_a->offset_in_ID != key_b->offset_in_ID); } static IDTypeInfo *id_types[INDEX_ID_MAX] = {NULL}; diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc index 3eade265bf2..b1385eab9cf 100644 --- a/source/blender/blenkernel/intern/image.cc +++ b/source/blender/blenkernel/intern/image.cc @@ -234,7 +234,6 @@ static void image_foreach_cache(ID *id, IDCacheKey key; key.id_session_uuid = id->session_uuid; key.offset_in_ID = offsetof(Image, cache); - key.cache_v = image->cache; function_callback(id, &key, (void **)&image->cache, 0, user_data); auto gputexture_offset = [image](int target, int eye, int resolution) { @@ -253,19 +252,16 @@ static void image_foreach_cache(ID *id, continue; } key.offset_in_ID = gputexture_offset(a, eye, resolution); - key.cache_v = texture; function_callback(id, &key, (void **)&image->gputexture[a][eye][resolution], 0, user_data); } } } key.offset_in_ID = offsetof(Image, rr); - key.cache_v = image->rr; function_callback(id, &key, (void **)&image->rr, 0, user_data); LISTBASE_FOREACH (RenderSlot *, slot, &image->renderslots) { key.offset_in_ID = (size_t)BLI_ghashutil_strhash_p(slot->name); - key.cache_v = slot->render; function_callback(id, &key, (void **)&slot->render, 0, user_data); } } diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index b30d8f92cc6..5afc3c0be3b 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -433,7 +433,7 @@ static const char *cmpcode_to_str(int code) case MESHCMP_DVERT_TOTGROUPMISMATCH: return "Vertex Doesn't Belong To Same Number Of Groups"; case MESHCMP_LOOPCOLMISMATCH: - return "Vertex Color Mismatch"; + return "Color Attribute Mismatch"; case MESHCMP_LOOPUVMISMATCH: return "UV Mismatch"; case MESHCMP_LOOPMISMATCH: diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c index 406372f0113..9a4c01ec7aa 100644 --- a/source/blender/blenkernel/intern/mesh_remap.c +++ b/source/blender/blenkernel/intern/mesh_remap.c @@ -1510,15 +1510,11 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, bvhtree_from_mesh_verts_ex(&treedata[tindex], verts_src, num_verts_src, - false, verts_active, num_verts_active, 0.0, 2, - 6, - 0, - NULL, - NULL); + 6); } MEM_freeN(verts_active); @@ -1549,20 +1545,14 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, } bvhtree_from_mesh_looptri_ex(&treedata[tindex], verts_src, - false, loops_src, - false, looptri_src, num_looptri_src, - false, looptri_active, num_looptri_active, 0.0, 2, - 6, - 0, - NULL, - NULL); + 6); } MEM_freeN(looptri_active); diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 3a93b7cde84..accbca42da6 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -139,12 +139,10 @@ static void movie_clip_foreach_cache(ID *id, IDCacheKey key = { .id_session_uuid = id->session_uuid, .offset_in_ID = offsetof(MovieClip, cache), - .cache_v = movie_clip->cache, }; function_callback(id, &key, (void **)&movie_clip->cache, 0, user_data); key.offset_in_ID = offsetof(MovieClip, tracking.camera.intrinsics); - key.cache_v = movie_clip->tracking.camera.intrinsics; function_callback(id, &key, (void **)&movie_clip->tracking.camera.intrinsics, 0, user_data); } diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index e3fe5d77d63..76b66beaf0d 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -359,7 +359,6 @@ static void node_foreach_cache(ID *id, IDCacheKey key = {0}; key.id_session_uuid = id->session_uuid; key.offset_in_ID = offsetof(bNodeTree, previews); - key.cache_v = nodetree->previews; /* TODO: see also `direct_link_nodetree()` in readfile.c. */ #if 0 @@ -370,7 +369,6 @@ static void node_foreach_cache(ID *id, LISTBASE_FOREACH (bNode *, node, &nodetree->nodes) { if (node->type == CMP_NODE_MOVIEDISTORTION) { key.offset_in_ID = (size_t)BLI_ghashutil_strhash_p(node->name); - key.cache_v = node->storage; function_callback(id, &key, (void **)&node->storage, 0, user_data); } } diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index 6f1c8f09a76..a54e2910b79 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -1897,6 +1897,8 @@ bool BKE_object_is_in_editmode(const Object *ob) case OB_GPENCIL: /* Grease Pencil object has no edit mode data. */ return GPENCIL_EDIT_MODE((bGPdata *)ob->data); + case OB_CURVES: + return ob->mode == OB_MODE_EDIT; default: return false; } @@ -1907,7 +1909,7 @@ bool BKE_object_is_in_editmode_vgroup(const Object *ob) return (OB_TYPE_SUPPORT_VGROUP(ob->type) && BKE_object_is_in_editmode(ob)); } -bool BKE_object_data_is_in_editmode(const ID *id) +bool BKE_object_data_is_in_editmode(const Object *ob, const ID *id) { const short type = GS(id->name); BLI_assert(OB_DATA_SUPPORT_EDITMODE(type)); @@ -1923,6 +1925,11 @@ bool BKE_object_data_is_in_editmode(const ID *id) return ((const Lattice *)id)->editlatt != nullptr; case ID_AR: return ((const bArmature *)id)->edbo != nullptr; + case ID_CV: + if (ob) { + return BKE_object_is_in_editmode(ob); + } + return false; default: BLI_assert_unreachable(); return false; @@ -1970,6 +1977,10 @@ char *BKE_object_data_editmode_flush_ptr_get(struct ID *id) bArmature *arm = (bArmature *)id; return &arm->needs_flush_to_id; } + case ID_CV: { + /* Curves have no edit mode data. */ + return nullptr; + } default: BLI_assert_unreachable(); return nullptr; diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index 327035971d5..0ae8f144583 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -776,32 +776,27 @@ static void make_duplis_geometry_set_impl(const DupliContext *ctx, { int component_index = 0; if (ctx->object->type != OB_MESH || geometry_set_is_instance) { - const Mesh *mesh = geometry_set.get_mesh_for_read(); - if (mesh != nullptr) { + if (const Mesh *mesh = geometry_set.get_mesh_for_read()) { DupliObject *dupli = make_dupli(ctx, ctx->object, parent_transform, component_index++); dupli->ob_data = (ID *)mesh; } } if (ctx->object->type != OB_VOLUME || geometry_set_is_instance) { - const Volume *volume = geometry_set.get_volume_for_read(); - if (volume != nullptr) { + if (const Volume *volume = geometry_set.get_volume_for_read()) { DupliObject *dupli = make_dupli(ctx, ctx->object, parent_transform, component_index++); dupli->ob_data = (ID *)volume; } } if (!ELEM(ctx->object->type, OB_CURVES_LEGACY, OB_FONT) || geometry_set_is_instance) { - const CurveComponent *curve_component = geometry_set.get_component_for_read<CurveComponent>(); - if (curve_component != nullptr) { - const Curve *curve = curve_component->get_curve_for_render(); - if (curve != nullptr) { + if (const CurveComponent *component = geometry_set.get_component_for_read<CurveComponent>()) { + if (const Curve *curve = component->get_curve_for_render()) { DupliObject *dupli = make_dupli(ctx, ctx->object, parent_transform, component_index++); dupli->ob_data = (ID *)curve; } } } if (ctx->object->type != OB_POINTCLOUD || geometry_set_is_instance) { - const PointCloud *pointcloud = geometry_set.get_pointcloud_for_read(); - if (pointcloud != nullptr) { + if (const PointCloud *pointcloud = geometry_set.get_pointcloud_for_read()) { DupliObject *dupli = make_dupli(ctx, ctx->object, parent_transform, component_index++); dupli->ob_data = (ID *)pointcloud; } diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 1c58173f570..80c3ead3039 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -29,6 +29,7 @@ #include "BLT_translation.h" +#include "BKE_attribute.h" #include "BKE_brush.h" #include "BKE_ccg.h" #include "BKE_colortools.h" @@ -1666,7 +1667,28 @@ static void sculpt_update_object(Depsgraph *depsgraph, ss->multires.modifier = NULL; ss->multires.level = 0; ss->vmask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK); - ss->vcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR); + + CustomDataLayer *layer; + AttributeDomain domain; + + if (BKE_pbvh_get_color_layer(me, &layer, &domain)) { + if (layer->type == CD_PROP_COLOR) { + ss->vcol = layer->data; + } + else { + ss->mcol = layer->data; + } + + ss->vcol_domain = domain; + ss->vcol_type = layer->type; + } + else { + ss->vcol = NULL; + ss->mcol = NULL; + + ss->vcol_type = -1; + ss->vcol_domain = ATTR_DOMAIN_NUM; + } } /* Sculpt Face Sets. */ @@ -1692,6 +1714,10 @@ static void sculpt_update_object(Depsgraph *depsgraph, if (need_pmap && ob->type == OB_MESH && !ss->pmap) { BKE_mesh_vert_poly_map_create( &ss->pmap, &ss->pmap_mem, me->mpoly, me->mloop, me->totvert, me->totpoly, me->totloop); + + if (ss->pbvh) { + BKE_pbvh_pmap_set(ss->pbvh, ss->pmap); + } } pbvh_show_mask_set(ss->pbvh, ss->show_mask); @@ -1791,16 +1817,30 @@ void BKE_sculpt_update_object_after_eval(Depsgraph *depsgraph, Object *ob_eval) void BKE_sculpt_color_layer_create_if_needed(struct Object *object) { Mesh *orig_me = BKE_object_get_original_mesh(object); - if (!U.experimental.use_sculpt_vertex_colors) { - return; + + int types[] = {CD_PROP_COLOR, CD_MLOOPCOL}; + bool has_color = false; + + for (int i = 0; i < ARRAY_SIZE(types); i++) { + has_color = CustomData_has_layer(&orig_me->vdata, types[i]) || + CustomData_has_layer(&orig_me->ldata, types[i]); + + if (has_color) { + break; + } } - if (CustomData_has_layer(&orig_me->vdata, CD_PROP_COLOR)) { + if (has_color) { return; } CustomData_add_layer(&orig_me->vdata, CD_PROP_COLOR, CD_DEFAULT, NULL, orig_me->totvert); + CustomDataLayer *layer = orig_me->vdata.layers + + CustomData_get_layer_index(&orig_me->vdata, CD_PROP_COLOR); + BKE_mesh_update_customdata_pointers(orig_me, true); + + BKE_id_attributes_active_color_set(&orig_me->id, layer); DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY_ALL_MODES); } @@ -2173,6 +2213,10 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob) BKE_sculpt_bvh_update_from_ccg(pbvh, subdiv_ccg); } } + + BKE_pbvh_update_active_vcol(pbvh, BKE_object_get_original_mesh(ob)); + BKE_pbvh_pmap_set(pbvh, ob->sculpt->pmap); + return pbvh; } @@ -2192,6 +2236,8 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob) } } + BKE_pbvh_pmap_set(pbvh, ob->sculpt->pmap); + ob->sculpt->pbvh = pbvh; return pbvh; } diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 620943ca3e6..c8d9e0c951b 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -17,8 +17,10 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "BKE_attribute.h" #include "BKE_ccg.h" #include "BKE_mesh.h" +#include "BKE_mesh_mapping.h" #include "BKE_paint.h" #include "BKE_pbvh.h" #include "BKE_subdiv_ccg.h" @@ -599,6 +601,8 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, /* Clear the bitmap so it can be used as an update tag later on. */ BLI_bitmap_set_all(pbvh->vert_bitmap, false, totvert); + + BKE_pbvh_update_active_vcol(pbvh, mesh); } void BKE_pbvh_build_grids(PBVH *pbvh, @@ -667,6 +671,9 @@ void BKE_pbvh_free(PBVH *pbvh) if (node->vert_indices) { MEM_freeN((void *)node->vert_indices); } + if (node->loop_indices) { + MEM_freeN(node->loop_indices); + } if (node->face_vert_indices) { MEM_freeN((void *)node->face_vert_indices); } @@ -1256,6 +1263,30 @@ static int pbvh_get_buffers_update_flags(PBVH *UNUSED(pbvh)) return update_flags; } +bool BKE_pbvh_get_color_layer(const Mesh *me, CustomDataLayer **r_layer, AttributeDomain *r_attr) +{ + CustomDataLayer *layer = BKE_id_attributes_active_color_get((ID *)me); + + if (!layer || !ELEM(layer->type, CD_PROP_COLOR, CD_MLOOPCOL)) { + *r_layer = NULL; + *r_attr = ATTR_DOMAIN_NUM; + return false; + } + + AttributeDomain domain = BKE_id_attribute_domain((ID *)me, layer); + + if (!ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER)) { + *r_layer = NULL; + *r_attr = ATTR_DOMAIN_NUM; + return false; + } + + *r_layer = layer; + *r_attr = domain; + + return true; +} + static void pbvh_update_draw_buffer_cb(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) @@ -1306,18 +1337,25 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata, &pbvh->gridkey, update_flags); break; - case PBVH_FACES: + case PBVH_FACES: { + CustomDataLayer *layer = NULL; + AttributeDomain domain; + + BKE_pbvh_get_color_layer(pbvh->mesh, &layer, &domain); + GPU_pbvh_mesh_buffers_update(node->draw_buffers, pbvh->verts, pbvh->vert_normals, CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK), - CustomData_get_layer(pbvh->ldata, CD_MLOOPCOL), + layer ? layer->data : NULL, + layer ? layer->type : -1, + layer ? domain : ATTR_DOMAIN_AUTO, CustomData_get_layer(pbvh->pdata, CD_SCULPT_FACE_SETS), pbvh->face_sets_color_seed, pbvh->face_sets_color_default, - CustomData_get_layer(pbvh->vdata, CD_PROP_COLOR), update_flags); break; + } case PBVH_BMESH: GPU_pbvh_bmesh_buffers_update(node->draw_buffers, pbvh->bm, @@ -1444,7 +1482,9 @@ void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flag) } if (flag & (PBVH_UpdateColor)) { - /* Do nothing */ + for (int i = 0; i < totnode; i++) { + nodes[i]->flag |= PBVH_UpdateRedraw | PBVH_UpdateDrawBuffers | PBVH_UpdateColor; + } } if (flag & (PBVH_UpdateVisibility)) { @@ -1837,6 +1877,22 @@ void BKE_pbvh_vert_mark_update(PBVH *pbvh, int index) BLI_BITMAP_ENABLE(pbvh->vert_bitmap, index); } +void BKE_pbvh_node_get_loops(PBVH *pbvh, + PBVHNode *node, + const int **r_loop_indices, + const MLoop **r_loops) +{ + BLI_assert(BKE_pbvh_type(pbvh) == PBVH_FACES); + + if (r_loop_indices) { + *r_loop_indices = node->loop_indices; + } + + if (r_loops) { + *r_loops = pbvh->mloop; + } +} + void BKE_pbvh_node_get_verts(PBVH *pbvh, PBVHNode *node, const int **r_vert_indices, @@ -2997,7 +3053,6 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m vi->vert_normals = pbvh->vert_normals; vi->vmask = CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK); - vi->vcol = CustomData_get_layer(pbvh->vdata, CD_PROP_COLOR); } } @@ -3089,3 +3144,81 @@ void BKE_pbvh_respect_hide_set(PBVH *pbvh, bool respect_hide) { pbvh->respect_hide = respect_hide; } +bool BKE_pbvh_is_drawing(const PBVH *pbvh) +{ + return pbvh->is_drawing; +} + +void BKE_pbvh_is_drawing_set(PBVH *pbvh, bool val) +{ + pbvh->is_drawing = val; +} + +void BKE_pbvh_node_num_loops(PBVH *pbvh, PBVHNode *node, int *r_totloop) +{ + UNUSED_VARS(pbvh); + BLI_assert(BKE_pbvh_type(pbvh) == PBVH_FACES); + + if (r_totloop) { + *r_totloop = node->loop_indices_num; + } +} + +void BKE_pbvh_update_active_vcol(PBVH *pbvh, const Mesh *mesh) +{ + BKE_pbvh_get_color_layer(mesh, &pbvh->color_layer, &pbvh->color_domain); +} + +void BKE_pbvh_pmap_set(PBVH *pbvh, const MeshElemMap *pmap) +{ + pbvh->pmap = pmap; +} + +void BKE_pbvh_ensure_node_loops(PBVH *pbvh) +{ + BLI_assert(BKE_pbvh_type(pbvh) == PBVH_FACES); + + int totloop = 0; + + /* Check if nodes already have loop indices. */ + for (int i = 0; i < pbvh->totnode; i++) { + PBVHNode *node = pbvh->nodes + i; + + if (!(node->flag & PBVH_Leaf)) { + continue; + } + + if (node->loop_indices) { + return; + } + + totloop += node->totprim * 3; + } + + BLI_bitmap *visit = BLI_BITMAP_NEW(totloop, __func__); + + /* Create loop indices from node loop triangles. */ + for (int i = 0; i < pbvh->totnode; i++) { + PBVHNode *node = pbvh->nodes + i; + + if (!(node->flag & PBVH_Leaf)) { + continue; + } + + node->loop_indices = MEM_malloc_arrayN(node->totprim * 3, sizeof(int), __func__); + node->loop_indices_num = 0; + + for (int j = 0; j < node->totprim; j++) { + const MLoopTri *mlt = pbvh->looptri + node->prim_indices[j]; + + for (int k = 0; k < 3; k++) { + if (!BLI_BITMAP_TEST(visit, mlt->tri[k])) { + node->loop_indices[node->loop_indices_num++] = mlt->tri[k]; + BLI_BITMAP_ENABLE(visit, mlt->tri[k]); + } + } + } + } + + MEM_SAFE_FREE(visit); +} diff --git a/source/blender/blenkernel/intern/pbvh.cc b/source/blender/blenkernel/intern/pbvh.cc new file mode 100644 index 00000000000..d32a03186e3 --- /dev/null +++ b/source/blender/blenkernel/intern/pbvh.cc @@ -0,0 +1,210 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup bke + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" + +#include "BLI_bitmap.h" +#include "BLI_ghash.h" +#include "BLI_index_range.hh" +#include "BLI_math.h" +#include "BLI_rand.h" +#include "BLI_span.hh" +#include "BLI_task.h" + +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" + +#include "BKE_attribute.h" +#include "BKE_ccg.h" +#include "BKE_mesh.h" +#include "BKE_mesh_mapping.h" +#include "BKE_paint.h" +#include "BKE_pbvh.h" +#include "BKE_subdiv_ccg.h" + +#include "PIL_time.h" + +#include "GPU_buffers.h" + +#include "bmesh.h" + +#include "atomic_ops.h" + +#include "pbvh_intern.h" + +#include <climits> + +using blender::IndexRange; + +namespace blender::bke { + +template<typename Func> +inline void to_static_color_type(const CustomDataType type, const Func &func) +{ + switch (type) { + case CD_PROP_COLOR: + func(MPropCol()); + break; + case CD_MLOOPCOL: + func(MLoopCol()); + break; + default: + BLI_assert_unreachable(); + break; + } +} + +template<typename T> void to_float(const T &src, float dst[4]); + +template<> void to_float(const MLoopCol &src, float dst[4]) +{ + rgba_uchar_to_float(dst, reinterpret_cast<const unsigned char *>(&src)); + srgb_to_linearrgb_v3_v3(dst, dst); +} +template<> void to_float(const MPropCol &src, float dst[4]) +{ + copy_v4_v4(dst, src.color); +} + +template<typename T> void from_float(const float src[4], T &dst); + +template<> void from_float(const float src[4], MLoopCol &dst) +{ + float temp[4]; + linearrgb_to_srgb_v3_v3(temp, src); + temp[3] = src[3]; + rgba_float_to_uchar(reinterpret_cast<unsigned char *>(&dst), temp); +} +template<> void from_float(const float src[4], MPropCol &dst) +{ + copy_v4_v4(dst.color, src); +} + +template<typename T> +static void pbvh_vertex_color_get(const PBVH &pbvh, int vertex, float r_color[4]) +{ + if (pbvh.color_domain == ATTR_DOMAIN_CORNER) { + const MeshElemMap &melem = pbvh.pmap[vertex]; + + int count = 0; + zero_v4(r_color); + for (const int i_poly : Span(melem.indices, melem.count)) { + const MPoly &mp = pbvh.mpoly[i_poly]; + Span<T> colors{static_cast<const T *>(pbvh.color_layer->data) + mp.loopstart, mp.totloop}; + Span<MLoop> loops{pbvh.mloop + mp.loopstart, mp.totloop}; + + for (const int i_loop : IndexRange(mp.totloop)) { + if (loops[i_loop].v == vertex) { + float temp[4]; + to_float(colors[i_loop], temp); + + add_v4_v4(r_color, temp); + count++; + } + } + } + + if (count) { + mul_v4_fl(r_color, 1.0f / (float)count); + } + } + else { + to_float(static_cast<T *>(pbvh.color_layer->data)[vertex], r_color); + } +} + +template<typename T> +static void pbvh_vertex_color_set(PBVH &pbvh, int vertex, const float color[4]) +{ + if (pbvh.color_domain == ATTR_DOMAIN_CORNER) { + const MeshElemMap &melem = pbvh.pmap[vertex]; + + for (const int i_poly : Span(melem.indices, melem.count)) { + const MPoly &mp = pbvh.mpoly[i_poly]; + MutableSpan<T> colors{static_cast<T *>(pbvh.color_layer->data) + mp.loopstart, mp.totloop}; + Span<MLoop> loops{pbvh.mloop + mp.loopstart, mp.totloop}; + + for (const int i_loop : IndexRange(mp.totloop)) { + if (loops[i_loop].v == vertex) { + from_float(color, colors[i_loop]); + } + } + } + } + else { + from_float(color, static_cast<T *>(pbvh.color_layer->data)[vertex]); + } +} + +} // namespace blender::bke + +extern "C" { +void BKE_pbvh_vertex_color_get(const PBVH *pbvh, int vertex, float r_color[4]) +{ + blender::bke::to_static_color_type(CustomDataType(pbvh->color_layer->type), [&](auto dummy) { + using T = decltype(dummy); + blender::bke::pbvh_vertex_color_get<T>(*pbvh, vertex, r_color); + }); +} + +void BKE_pbvh_vertex_color_set(PBVH *pbvh, int vertex, const float color[4]) +{ + blender::bke::to_static_color_type(CustomDataType(pbvh->color_layer->type), [&](auto dummy) { + using T = decltype(dummy); + blender::bke::pbvh_vertex_color_set<T>(*pbvh, vertex, color); + }); +} + +void BKE_pbvh_swap_colors(PBVH *pbvh, + const int *indices, + const int indices_num, + float (*r_colors)[4]) +{ + blender::bke::to_static_color_type(CustomDataType(pbvh->color_layer->type), [&](auto dummy) { + using T = decltype(dummy); + T *pbvh_colors = static_cast<T *>(pbvh->color_layer->data); + for (const int i : IndexRange(indices_num)) { + T temp = pbvh_colors[indices[i]]; + blender::bke::from_float(r_colors[i], pbvh_colors[indices[i]]); + blender::bke::to_float(temp, r_colors[i]); + } + }); +} + +void BKE_pbvh_store_colors(PBVH *pbvh, + const int *indices, + const int indices_num, + float (*r_colors)[4]) +{ + blender::bke::to_static_color_type(CustomDataType(pbvh->color_layer->type), [&](auto dummy) { + using T = decltype(dummy); + T *pbvh_colors = static_cast<T *>(pbvh->color_layer->data); + for (const int i : IndexRange(indices_num)) { + blender::bke::to_float(pbvh_colors[indices[i]], r_colors[i]); + } + }); +} + +void BKE_pbvh_store_colors_vertex(PBVH *pbvh, + const int *indices, + const int indices_num, + float (*r_colors)[4]) +{ + if (pbvh->color_domain == ATTR_DOMAIN_POINT) { + BKE_pbvh_store_colors(pbvh, indices, indices_num, r_colors); + } + else { + blender::bke::to_static_color_type(CustomDataType(pbvh->color_layer->type), [&](auto dummy) { + using T = decltype(dummy); + for (const int i : IndexRange(indices_num)) { + blender::bke::pbvh_vertex_color_get<T>(*pbvh, indices[i], r_colors[i]); + } + }); + } +} +} diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h index 2b95c8dd525..7c4344a30d8 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.h +++ b/source/blender/blenkernel/intern/pbvh_intern.h @@ -20,6 +20,8 @@ typedef struct { float bmin[3], bmax[3], bcentroid[3]; } BBC; +struct MeshElemMap; + /* NOTE: this structure is getting large, might want to split it into * union'd structs */ struct PBVHNode { @@ -64,6 +66,13 @@ struct PBVHNode { const int *vert_indices; unsigned int uniq_verts, face_verts; + /* Array of indices into the Mesh's MLoop array. + * PBVH_FACES only. The first part of the array + * are loops unique to this node, see comment for + * vert_indices for more details.*/ + int *loop_indices; + unsigned int loop_indices_num; + /* An array mapping face corners into the vert_indices * array. The array is sized to match 'totprim', and each of * the face's corners gets an index into the vert_indices @@ -170,6 +179,13 @@ struct PBVH { struct BMLog *bm_log; struct SubdivCCG *subdiv_ccg; + + const struct MeshElemMap *pmap; + + CustomDataLayer *color_layer; + AttributeDomain color_domain; + + bool is_drawing; }; /* pbvh.c */ diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c index 98b680c8054..6d654730bca 100644 --- a/source/blender/blenkernel/intern/report.c +++ b/source/blender/blenkernel/intern/report.c @@ -86,9 +86,7 @@ void BKE_report(ReportList *reports, eReportType type, const char *_message) int len; const char *message = TIP_(_message); - /* in background mode always print otherwise there are cases the errors won't be displayed, - * but still add to the report list since this is used for python exception handling */ - if (G.background || !reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) { + if (BKE_reports_print_test(reports, type)) { printf("%s: %s\n", BKE_report_type_str(type), message); fflush(stdout); /* this ensures the message is printed before a crash */ } @@ -115,7 +113,7 @@ void BKE_reportf(ReportList *reports, eReportType type, const char *_format, ... va_list args; const char *format = TIP_(_format); - if (G.background || !reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) { + if (BKE_reports_print_test(reports, type)) { printf("%s: ", BKE_report_type_str(type)); va_start(args, _format); vprintf(format, args); @@ -258,6 +256,14 @@ char *BKE_reports_string(ReportList *reports, eReportType level) return cstring; } +bool BKE_reports_print_test(const ReportList *reports, eReportType type) +{ + /* In background mode always print otherwise there are cases the errors won't be displayed, + * but still add to the report list since this is used for python exception handling. */ + return (G.background || (reports == NULL) || + ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))); +} + void BKE_reports_print(ReportList *reports, eReportType level) { char *cstring = BKE_reports_string(reports, level); diff --git a/source/blender/blenkernel/intern/scene.cc b/source/blender/blenkernel/intern/scene.cc index cc1204abbfb..4e6191cca6f 100644 --- a/source/blender/blenkernel/intern/scene.cc +++ b/source/blender/blenkernel/intern/scene.cc @@ -858,7 +858,6 @@ static void scene_foreach_cache(ID *id, IDCacheKey key{}; key.id_session_uuid = id->session_uuid; key.offset_in_ID = offsetof(Scene, eevee.light_cache_data); - key.cache_v = scene->eevee.light_cache_data; function_callback(id, &key, @@ -1225,7 +1224,7 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id) } /* Active channels root pointer. */ - if (ed->displayed_channels == old_displayed_channels || ed->displayed_channels == NULL) { + if (ed->displayed_channels == old_displayed_channels || ed->displayed_channels == nullptr) { ed->displayed_channels = &ed->channels; } else { @@ -1260,7 +1259,7 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id) } } - if (ms->old_channels == old_displayed_channels || ms->old_channels == NULL) { + if (ms->old_channels == old_displayed_channels || ms->old_channels == nullptr) { ms->old_channels = &ed->channels; } else { diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index b991805fae8..864a4f3281b 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -112,7 +112,6 @@ static void sound_foreach_cache(ID *id, IDCacheKey key = { .id_session_uuid = id->session_uuid, .offset_in_ID = offsetof(bSound, waveform), - .cache_v = sound->waveform, }; function_callback(id, &key, &sound->waveform, 0, user_data); diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc index 07db0328f56..0c131863edd 100644 --- a/source/blender/blenkernel/intern/volume.cc +++ b/source/blender/blenkernel/intern/volume.cc @@ -569,8 +569,7 @@ static void volume_foreach_cache(ID *id, Volume *volume = (Volume *)id; IDCacheKey key = { /* id_session_uuid */ id->session_uuid, - /*offset_in_ID*/ offsetof(Volume, runtime.grids), - /* cache_v */ volume->runtime.grids, + /* offset_in_ID */ offsetof(Volume, runtime.grids), }; function_callback(id, &key, (void **)&volume->runtime.grids, 0, user_data); |