Merge branch 'master' into refactor-mesh-position-generic

This commit is contained in:
Hans Goudey 2022-12-13 16:53:53 -06:00
commit b0b60df326
36 changed files with 596 additions and 456 deletions

View File

@ -195,9 +195,12 @@ set(TIFF_HASH_TYPE MD5)
set(TIFF_FILE tiff-${TIFF_VERSION}.tar.gz)
set(TIFF_CPE "cpe:2.3:a:libtiff:libtiff:${TIFF_VERSION}:*:*:*:*:*:*:*")
set(OSL_VERSION 1.12.7.1)
set(OSL_URI https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/archive/v${OSL_VERSION}.tar.gz)
set(OSL_HASH 53211da86c34ba6e0344998c1a6d219c)
# Recent commit from 1.13.0.2 under development, which includes string table
# changes that make the Cycles OptiX implementation work. Official 1.12 OSL
# releases should also build but without OptiX support.
set(OSL_VERSION 1a7670600c8b08c2443a78d03c8c27e9a1149140)
set(OSL_URI https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/archive/${OSL_VERSION}.tar.gz)
set(OSL_HASH 7b6d6716b05d1addb92a8f47280bf77f)
set(OSL_HASH_TYPE MD5)
set(OSL_FILE OpenShadingLanguage-${OSL_VERSION}.tar.gz)

View File

@ -167,7 +167,7 @@ add_library(bli_lib
"../../../source/blender/blenlib/intern/rct.c"
"../../../source/blender/blenlib/intern/string.c"
"../../../source/blender/blenlib/intern/string_utf8.c"
"../../../source/blender/blenlib/intern/listbase.c"
"../../../source/blender/blenlib/intern/listbase.cc"
"../../../source/blender/blenlib/intern/math_color.c"
"../../../source/blender/blenlib/intern/math_geom.c"
"../../../source/blender/blenlib/intern/math_matrix.c"

View File

@ -94,6 +94,16 @@ _namespace = globals()
_modules_loaded = [_namespace[name] for name in _modules]
del _namespace
def _addon_support_items():
"""Return the addon support levels suitable for this Blender build."""
items = [
('OFFICIAL', "Official", "Officially supported"),
('COMMUNITY', "Community", "Maintained by community developers"),
]
if bpy.app.version_cycle == 'alpha':
items.append(('TESTING', "Testing", "Newly contributed scripts (excluded from release builds)"))
return items
def register():
from bpy.utils import register_class
@ -141,11 +151,7 @@ def register():
)
WindowManager.addon_support = EnumProperty(
items=[
('OFFICIAL', "Official", "Officially supported"),
('COMMUNITY', "Community", "Maintained by community developers"),
('TESTING', "Testing", "Newly contributed scripts (excluded from release builds)")
],
items=_addon_support_items(),
name="Support",
description="Display support level",
default={'OFFICIAL', 'COMMUNITY'},

View File

@ -421,6 +421,11 @@ inline const bNode *bNodeTree::group_output_node() const
return this->runtime->group_output_node;
}
inline blender::Span<const bNode *> bNodeTree::group_input_nodes() const
{
return this->nodes_by_type("NodeGroupInput");
}
inline blender::Span<const bNodeSocket *> bNodeTree::all_input_sockets() const
{
BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this));

View File

@ -515,6 +515,11 @@ typedef struct SculptAttribute {
int elem_size, elem_num;
bool data_for_bmesh; /* Temporary data store as array outside of bmesh. */
/* Data is a flat array outside the CustomData system.
* This will be true if simple_array is requested in
* SculptAttributeParams, or the PBVH type is PBVH_GRIDS or PBVH_BMESH.
*/
bool simple_array;
/* Data stored per BMesh element. */
int bmesh_cd_offset;

View File

@ -413,7 +413,8 @@ void BKE_pbvh_sync_visibility_from_verts(PBVH *pbvh, struct Mesh *me);
int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
const int *grid_indices,
int totgrid,
int gridsize);
int gridsize,
int display_gridsize);
/**
* Multi-res level, only valid for type == #PBVH_GRIDS.

View File

@ -1436,7 +1436,7 @@ void BKE_fcurve_correct_bezpart(const float v1[2], float v2[2], float v3[2], con
}
/**
* Find roots of cubic equation (c0 x^3 + c1 x^2 + c2 x + c3)
* Find roots of cubic equation (c0 + c1 x + c2 x^2 + c3 x^3)
* \return number of roots in `o`.
*
* \note it is up to the caller to allocate enough memory for `o`.

View File

@ -1358,7 +1358,7 @@ void BKE_mesh_material_index_remove(Mesh *me, short index)
}
MutableVArraySpan<int> indices_span(material_indices.varray);
for (const int i : indices_span.index_range()) {
if (indices_span[i] > 0 && indices_span[i] > index) {
if (indices_span[i] > 0 && indices_span[i] >= index) {
indices_span[i]--;
}
}

View File

@ -426,6 +426,28 @@ void multires_flush_sculpt_updates(Object *object)
}
Mesh *mesh = static_cast<Mesh *>(object->data);
/* Check that the multires modifier still exists.
* Fixes crash when deleting multires modifier
* from within sculpt mode.
*/
ModifierData *md;
MultiresModifierData *mmd = nullptr;
VirtualModifierData virtualModifierData;
for (md = BKE_modifiers_get_virtual_modifierlist(object, &virtualModifierData); md;
md = md->next) {
if (md->type == eModifierType_Multires) {
if (BKE_modifier_is_enabled(nullptr, md, eModifierMode_Realtime)) {
mmd = (MultiresModifierData *)md;
}
}
}
if (!mmd) {
return;
}
multiresModifier_reshapeFromCCG(
sculpt_session->multires.modifier->totlvl, mesh, sculpt_session->subdiv_ccg);

View File

@ -340,7 +340,7 @@ static void determine_group_input_states(
}
/* Check if group inputs are required to be single values, because they are (indirectly)
* connected to some socket that does not support fields. */
for (const bNode *node : tree.nodes_by_type("NodeGroupInput")) {
for (const bNode *node : tree.group_input_nodes()) {
for (const bNodeSocket *output_socket : node->output_sockets().drop_back(1)) {
SocketFieldState &state = field_state_by_socket_id[output_socket->index_in_tree()];
if (state.requires_single) {
@ -349,7 +349,7 @@ static void determine_group_input_states(
}
}
/* If an input does not support fields, this should be reflected in all Group Input nodes. */
for (const bNode *node : tree.nodes_by_type("NodeGroupInput")) {
for (const bNode *node : tree.group_input_nodes()) {
for (const bNodeSocket *output_socket : node->output_sockets().drop_back(1)) {
SocketFieldState &state = field_state_by_socket_id[output_socket->index_in_tree()];
const bool supports_field = new_inferencing_interface.inputs[output_socket->index()] !=

View File

@ -79,7 +79,7 @@ static SculptAttribute *sculpt_attribute_ensure_ex(Object *ob,
const SculptAttributeParams *params,
PBVHType pbvhtype,
bool flat_array_for_bmesh);
void sculptsession_bmesh_add_layers(Object *ob);
static void sculptsession_bmesh_add_layers(Object *ob);
static void palette_init_data(ID *id)
{
@ -2459,7 +2459,7 @@ static bool sculpt_attribute_create(SculptSession *ss,
permanent = (out->params.permanent = false);
}
simple_array = (out->params.simple_array = true);
simple_array = true;
}
BLI_assert(!(simple_array && permanent));
@ -2472,6 +2472,7 @@ static bool sculpt_attribute_create(SculptSession *ss,
out->data = MEM_calloc_arrayN(totelem, elemsize, __func__);
out->data_for_bmesh = ss->bm != nullptr;
out->simple_array = true;
out->bmesh_cd_offset = -1;
out->layer = nullptr;
out->elem_size = elemsize;
@ -2481,6 +2482,8 @@ static bool sculpt_attribute_create(SculptSession *ss,
return true;
}
out->simple_array = false;
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_BMESH: {
CustomData *cdata = nullptr;
@ -2516,8 +2519,6 @@ static bool sculpt_attribute_create(SculptSession *ss,
case PBVH_FACES: {
CustomData *cdata = nullptr;
out->data_for_bmesh = false;
switch (domain) {
case ATTR_DOMAIN_POINT:
cdata = &me->vdata;
@ -2539,10 +2540,10 @@ static bool sculpt_attribute_create(SculptSession *ss,
cdata->layers[index].flag |= CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY;
}
out->data = nullptr;
out->layer = cdata->layers + index;
out->bmesh_cd_offset = -1;
out->data = out->layer->data;
out->data_for_bmesh = false;
out->bmesh_cd_offset = -1;
out->elem_size = CustomData_get_elem_size(out->layer);
break;
@ -2570,31 +2571,36 @@ static bool sculpt_attr_update(Object *ob, SculptAttribute *attr)
bool bad = false;
if (attr->params.simple_array) {
if (attr->data) {
bad = attr->elem_num != elem_num;
if (bad) {
MEM_SAFE_FREE(attr->data);
}
else {
attr->data_for_bmesh = false;
}
}
else {
CustomData *cdata = sculpt_get_cdata(ob, attr->domain);
if (cdata) {
int layer_index = CustomData_get_named_layer_index(cdata, attr->proptype, attr->name);
/* Check if we are a coerced simple array and shouldn't be. */
bad |= attr->simple_array && !attr->params.simple_array &&
!ELEM(BKE_pbvh_type(ss->pbvh), PBVH_GRIDS, PBVH_BMESH);
bad |= (ss->bm != nullptr) != attr->data_for_bmesh;
CustomData *cdata = sculpt_get_cdata(ob, attr->domain);
if (cdata && !attr->simple_array) {
int layer_index = CustomData_get_named_layer_index(cdata, attr->proptype, attr->name);
bad |= layer_index == -1;
bad |= (ss->bm != nullptr) != attr->data_for_bmesh;
if (!bad) {
if (attr->data_for_bmesh) {
attr->bmesh_cd_offset = cdata->layers[layer_index].offset;
}
else {
attr->data = cdata->layers[layer_index].data;
}
}
}
if (bad) {
if (attr->simple_array) {
MEM_SAFE_FREE(attr->data);
}
sculpt_attribute_create(ss,
ob,
attr->domain,
@ -2603,7 +2609,7 @@ static bool sculpt_attr_update(Object *ob, SculptAttribute *attr)
attr,
&attr->params,
BKE_pbvh_type(ss->pbvh),
true);
attr->data_for_bmesh);
}
return bad;
@ -2729,6 +2735,8 @@ static SculptAttribute *sculpt_attribute_ensure_ex(Object *ob,
SculptAttribute *attr = BKE_sculpt_attribute_get(ob, domain, proptype, name);
if (attr) {
sculpt_attr_update(ob, attr);
return attr;
}
@ -2767,7 +2775,7 @@ static void sculptsession_bmesh_attr_update_internal(Object *ob)
}
}
void sculptsession_bmesh_add_layers(Object *ob)
static void sculptsession_bmesh_add_layers(Object *ob)
{
SculptSession *ss = ob->sculpt;
SculptAttributeParams params = {0};
@ -2874,7 +2882,7 @@ bool BKE_sculpt_attribute_destroy(Object *ob, SculptAttribute *attr)
Mesh *me = BKE_object_get_original_mesh(ob);
if (attr->params.simple_array) {
if (attr->simple_array) {
MEM_SAFE_FREE(attr->data);
}
else if (ss->bm) {

View File

@ -383,7 +383,8 @@ static void update_vb(PBVH *pbvh, PBVHNode *node, BBC *prim_bbc, int offset, int
int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
const int *grid_indices,
int totgrid,
int gridsize)
int gridsize,
int display_gridsize)
{
const int gridarea = (gridsize - 1) * (gridsize - 1);
int totquad = 0;
@ -391,13 +392,18 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
/* grid hidden layer is present, so have to check each grid for
* visibility */
int depth1 = (int)(log2((double)gridsize - 1.0) + DBL_EPSILON);
int depth2 = (int)(log2((double)display_gridsize - 1.0) + DBL_EPSILON);
int skip = depth2 < depth1 ? 1 << (depth1 - depth2 - 1) : 1;
for (int i = 0; i < totgrid; i++) {
const BLI_bitmap *gh = grid_hidden[grid_indices[i]];
if (gh) {
/* grid hidden are present, have to check each element */
for (int y = 0; y < gridsize - 1; y++) {
for (int x = 0; x < gridsize - 1; x++) {
for (int y = 0; y < gridsize - skip; y += skip) {
for (int x = 0; x < gridsize - skip; x += skip) {
if (!paint_is_grid_face_hidden(gh, gridsize, x, y)) {
totquad++;
}
@ -414,8 +420,11 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
static void build_grid_leaf_node(PBVH *pbvh, PBVHNode *node)
{
int totquads = BKE_pbvh_count_grid_quads(
pbvh->grid_hidden, node->prim_indices, node->totprim, pbvh->gridkey.grid_size);
int totquads = BKE_pbvh_count_grid_quads(pbvh->grid_hidden,
node->prim_indices,
node->totprim,
pbvh->gridkey.grid_size,
pbvh->gridkey.grid_size);
BKE_pbvh_node_fully_hidden_set(node, (totquads == 0));
BKE_pbvh_node_mark_rebuild_draw(node);
}

View File

@ -362,9 +362,9 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image
}
uv_islands::MeshData mesh_data({pbvh->looptri, pbvh->totprim},
{pbvh->mloop, pbvh->totprim},
{pbvh->mloop, mesh->totloop},
pbvh->totvert,
{ldata_uv, pbvh->totprim});
{ldata_uv, mesh->totloop});
uv_islands::UVIslands islands(mesh_data);
uv_islands::UVIslandsMask uv_masks;

View File

@ -89,7 +89,7 @@ set(SRC
intern/lasso_2d.c
intern/lazy_threading.cc
intern/length_parameterize.cc
intern/listbase.c
intern/listbase.cc
intern/math_base.c
intern/math_base_inline.c
intern/math_base_safe_inline.c

View File

@ -22,56 +22,56 @@
void BLI_movelisttolist(ListBase *dst, ListBase *src)
{
if (src->first == NULL) {
if (src->first == nullptr) {
return;
}
if (dst->first == NULL) {
if (dst->first == nullptr) {
dst->first = src->first;
dst->last = src->last;
}
else {
((Link *)dst->last)->next = src->first;
((Link *)src->first)->prev = dst->last;
((Link *)dst->last)->next = static_cast<Link *>(src->first);
((Link *)src->first)->prev = static_cast<Link *>(dst->last);
dst->last = src->last;
}
src->first = src->last = NULL;
src->first = src->last = nullptr;
}
void BLI_movelisttolist_reverse(ListBase *dst, ListBase *src)
{
if (src->first == NULL) {
if (src->first == nullptr) {
return;
}
if (dst->first == NULL) {
if (dst->first == nullptr) {
dst->first = src->first;
dst->last = src->last;
}
else {
((Link *)src->last)->next = dst->first;
((Link *)dst->first)->prev = src->last;
((Link *)src->last)->next = static_cast<Link *>(dst->first);
((Link *)dst->first)->prev = static_cast<Link *>(src->last);
dst->first = src->first;
}
src->first = src->last = NULL;
src->first = src->last = nullptr;
}
void BLI_addhead(ListBase *listbase, void *vlink)
{
Link *link = vlink;
Link *link = static_cast<Link *>(vlink);
if (link == NULL) {
if (link == nullptr) {
return;
}
link->next = listbase->first;
link->prev = NULL;
link->next = static_cast<Link *>(listbase->first);
link->prev = nullptr;
if (listbase->first) {
((Link *)listbase->first)->prev = link;
}
if (listbase->last == NULL) {
if (listbase->last == nullptr) {
listbase->last = link;
}
listbase->first = link;
@ -79,19 +79,19 @@ void BLI_addhead(ListBase *listbase, void *vlink)
void BLI_addtail(ListBase *listbase, void *vlink)
{
Link *link = vlink;
Link *link = static_cast<Link *>(vlink);
if (link == NULL) {
if (link == nullptr) {
return;
}
link->next = NULL;
link->prev = listbase->last;
link->next = nullptr;
link->prev = static_cast<Link *>(listbase->last);
if (listbase->last) {
((Link *)listbase->last)->next = link;
}
if (listbase->first == NULL) {
if (listbase->first == nullptr) {
listbase->first = link;
}
listbase->last = link;
@ -99,9 +99,9 @@ void BLI_addtail(ListBase *listbase, void *vlink)
void BLI_remlink(ListBase *listbase, void *vlink)
{
Link *link = vlink;
Link *link = static_cast<Link *>(vlink);
if (link == NULL) {
if (link == nullptr) {
return;
}
@ -132,8 +132,8 @@ bool BLI_remlink_safe(ListBase *listbase, void *vlink)
void BLI_listbase_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb)
{
Link *linka = vlinka;
Link *linkb = vlinkb;
Link *linka = static_cast<Link *>(vlinka);
Link *linkb = static_cast<Link *>(vlinkb);
if (!linka || !linkb) {
return;
@ -185,15 +185,15 @@ void BLI_listbase_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb)
void BLI_listbases_swaplinks(ListBase *listbasea, ListBase *listbaseb, void *vlinka, void *vlinkb)
{
Link *linka = vlinka;
Link *linkb = vlinkb;
Link linkc = {NULL};
Link *linka = static_cast<Link *>(vlinka);
Link *linkb = static_cast<Link *>(vlinkb);
Link linkc = {nullptr};
if (!linka || !linkb) {
return;
}
/* The reference to `linkc` assigns NULL, not a dangling pointer so it can be ignored. */
/* The reference to `linkc` assigns nullptr, not a dangling pointer so it can be ignored. */
#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 1201 /* gcc12.1+ only */
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdangling-pointer"
@ -221,7 +221,7 @@ void BLI_listbases_swaplinks(ListBase *listbasea, ListBase *listbaseb, void *vli
void *BLI_pophead(ListBase *listbase)
{
Link *link;
if ((link = listbase->first)) {
if ((link = static_cast<Link *>(listbase->first))) {
BLI_remlink(listbase, link);
}
return link;
@ -230,7 +230,7 @@ void *BLI_pophead(ListBase *listbase)
void *BLI_poptail(ListBase *listbase)
{
Link *link;
if ((link = listbase->last)) {
if ((link = static_cast<Link *>(listbase->last))) {
BLI_remlink(listbase, link);
}
return link;
@ -238,9 +238,9 @@ void *BLI_poptail(ListBase *listbase)
void BLI_freelinkN(ListBase *listbase, void *vlink)
{
Link *link = vlink;
Link *link = static_cast<Link *>(vlink);
if (link == NULL) {
if (link == nullptr) {
return;
}
@ -253,7 +253,7 @@ void BLI_freelinkN(ListBase *listbase, void *vlink)
*/
static void listbase_double_from_single(Link *iter, ListBase *listbase)
{
Link *prev = NULL;
Link *prev = nullptr;
listbase->first = iter;
do {
iter->prev = prev;
@ -281,7 +281,7 @@ static void listbase_double_from_single(Link *iter, ListBase *listbase)
void BLI_listbase_sort(ListBase *listbase, int (*cmp)(const void *, const void *))
{
if (listbase->first != listbase->last) {
Link *head = listbase->first;
Link *head = static_cast<Link *>(listbase->first);
head = listbase_sort_fn(head, cmp);
listbase_double_from_single(head, listbase);
}
@ -292,7 +292,7 @@ void BLI_listbase_sort_r(ListBase *listbase,
void *thunk)
{
if (listbase->first != listbase->last) {
Link *head = listbase->first;
Link *head = static_cast<Link *>(listbase->first);
head = listbase_sort_fn_r(head, cmp, thunk);
listbase_double_from_single(head, listbase);
}
@ -300,25 +300,25 @@ void BLI_listbase_sort_r(ListBase *listbase,
void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink)
{
Link *prevlink = vprevlink;
Link *newlink = vnewlink;
Link *prevlink = static_cast<Link *>(vprevlink);
Link *newlink = static_cast<Link *>(vnewlink);
/* newlink before nextlink */
if (newlink == NULL) {
if (newlink == nullptr) {
return;
}
/* empty list */
if (listbase->first == NULL) {
if (listbase->first == nullptr) {
listbase->first = newlink;
listbase->last = newlink;
return;
}
/* insert at head of list */
if (prevlink == NULL) {
newlink->prev = NULL;
newlink->next = listbase->first;
if (prevlink == nullptr) {
newlink->prev = nullptr;
newlink->next = static_cast<Link *>(listbase->first);
newlink->next->prev = newlink;
listbase->first = newlink;
return;
@ -339,25 +339,25 @@ void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink)
void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink)
{
Link *nextlink = vnextlink;
Link *newlink = vnewlink;
Link *nextlink = static_cast<Link *>(vnextlink);
Link *newlink = static_cast<Link *>(vnewlink);
/* newlink before nextlink */
if (newlink == NULL) {
if (newlink == nullptr) {
return;
}
/* empty list */
if (listbase->first == NULL) {
if (listbase->first == nullptr) {
listbase->first = newlink;
listbase->last = newlink;
return;
}
/* insert at end of list */
if (nextlink == NULL) {
newlink->prev = listbase->last;
newlink->next = NULL;
if (nextlink == nullptr) {
newlink->prev = static_cast<Link *>(listbase->last);
newlink->next = nullptr;
((Link *)listbase->last)->next = newlink;
listbase->last = newlink;
return;
@ -378,14 +378,14 @@ void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink)
void BLI_insertlinkreplace(ListBase *listbase, void *vreplacelink, void *vnewlink)
{
Link *l_old = vreplacelink;
Link *l_new = vnewlink;
Link *l_old = static_cast<Link *>(vreplacelink);
Link *l_new = static_cast<Link *>(vnewlink);
/* update adjacent links */
if (l_old->next != NULL) {
if (l_old->next != nullptr) {
l_old->next->prev = l_new;
}
if (l_old->prev != NULL) {
if (l_old->prev != nullptr) {
l_old->prev->next = l_new;
}
@ -404,7 +404,7 @@ void BLI_insertlinkreplace(ListBase *listbase, void *vreplacelink, void *vnewlin
bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step)
{
Link *link = vlink;
Link *link = static_cast<Link *>(vlink);
Link *hook = link;
const bool is_up = step < 0;
@ -453,7 +453,7 @@ void BLI_freelist(ListBase *listbase)
{
Link *link, *next;
link = listbase->first;
link = static_cast<Link *>(listbase->first);
while (link) {
next = link->next;
free(link);
@ -467,7 +467,7 @@ void BLI_freelistN(ListBase *listbase)
{
Link *link, *next;
link = listbase->first;
link = static_cast<Link *>(listbase->first);
while (link) {
next = link->next;
MEM_freeN(link);
@ -482,7 +482,8 @@ int BLI_listbase_count_at_most(const ListBase *listbase, const int count_max)
Link *link;
int count = 0;
for (link = listbase->first; link && count != count_max; link = link->next) {
for (link = static_cast<Link *>(listbase->first); link && count != count_max;
link = link->next) {
count++;
}
@ -494,7 +495,7 @@ int BLI_listbase_count(const ListBase *listbase)
Link *link;
int count = 0;
for (link = listbase->first; link; link = link->next) {
for (link = static_cast<Link *>(listbase->first); link; link = link->next) {
count++;
}
@ -503,11 +504,11 @@ int BLI_listbase_count(const ListBase *listbase)
void *BLI_findlink(const ListBase *listbase, int number)
{
Link *link = NULL;
Link *link = nullptr;
if (number >= 0) {
link = listbase->first;
while (link != NULL && number != 0) {
link = static_cast<Link *>(listbase->first);
while (link != nullptr && number != 0) {
number--;
link = link->next;
}
@ -518,11 +519,11 @@ void *BLI_findlink(const ListBase *listbase, int number)
void *BLI_rfindlink(const ListBase *listbase, int number)
{
Link *link = NULL;
Link *link = nullptr;
if (number >= 0) {
link = listbase->last;
while (link != NULL && number != 0) {
link = static_cast<Link *>(listbase->last);
while (link != nullptr && number != 0) {
number--;
link = link->prev;
}
@ -533,11 +534,11 @@ void *BLI_rfindlink(const ListBase *listbase, int number)
void *BLI_findlinkfrom(Link *start, int number)
{
Link *link = NULL;
Link *link = nullptr;
if (number >= 0) {
link = start;
while (link != NULL && number != 0) {
while (link != nullptr && number != 0) {
number--;
link = link->next;
}
@ -548,14 +549,14 @@ void *BLI_findlinkfrom(Link *start, int number)
int BLI_findindex(const ListBase *listbase, const void *vlink)
{
Link *link = NULL;
Link *link = nullptr;
int number = 0;
if (vlink == NULL) {
if (vlink == nullptr) {
return -1;
}
link = listbase->first;
link = static_cast<Link *>(listbase->first);
while (link) {
if (link == vlink) {
return number;
@ -570,14 +571,14 @@ int BLI_findindex(const ListBase *listbase, const void *vlink)
void *BLI_findstring(const ListBase *listbase, const char *id, const int offset)
{
Link *link = NULL;
Link *link = nullptr;
const char *id_iter;
if (id == NULL) {
return NULL;
if (id == nullptr) {
return nullptr;
}
for (link = listbase->first; link; link = link->next) {
for (link = static_cast<Link *>(listbase->first); link; link = link->next) {
id_iter = ((const char *)link) + offset;
if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
@ -585,16 +586,16 @@ void *BLI_findstring(const ListBase *listbase, const char *id, const int offset)
}
}
return NULL;
return nullptr;
}
void *BLI_rfindstring(const ListBase *listbase, const char *id, const int offset)
{
/* Same as #BLI_findstring but find reverse. */
Link *link = NULL;
Link *link = nullptr;
const char *id_iter;
for (link = listbase->last; link; link = link->prev) {
for (link = static_cast<Link *>(listbase->last); link; link = link->prev) {
id_iter = ((const char *)link) + offset;
if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
@ -602,15 +603,15 @@ void *BLI_rfindstring(const ListBase *listbase, const char *id, const int offset
}
}
return NULL;
return nullptr;
}
void *BLI_findstring_ptr(const ListBase *listbase, const char *id, const int offset)
{
Link *link = NULL;
Link *link = nullptr;
const char *id_iter;
for (link = listbase->first; link; link = link->next) {
for (link = static_cast<Link *>(listbase->first); link; link = link->next) {
/* exact copy of BLI_findstring(), except for this line */
id_iter = *((const char **)(((const char *)link) + offset));
@ -619,16 +620,16 @@ void *BLI_findstring_ptr(const ListBase *listbase, const char *id, const int off
}
}
return NULL;
return nullptr;
}
void *BLI_rfindstring_ptr(const ListBase *listbase, const char *id, const int offset)
{
/* Same as #BLI_findstring_ptr but find reverse. */
Link *link = NULL;
Link *link = nullptr;
const char *id_iter;
for (link = listbase->last; link; link = link->prev) {
for (link = static_cast<Link *>(listbase->last); link; link = link->prev) {
/* exact copy of BLI_rfindstring(), except for this line */
id_iter = *((const char **)(((const char *)link) + offset));
@ -637,15 +638,15 @@ void *BLI_rfindstring_ptr(const ListBase *listbase, const char *id, const int of
}
}
return NULL;
return nullptr;
}
void *BLI_findptr(const ListBase *listbase, const void *ptr, const int offset)
{
Link *link = NULL;
Link *link = nullptr;
const void *ptr_iter;
for (link = listbase->first; link; link = link->next) {
for (link = static_cast<Link *>(listbase->first); link; link = link->next) {
/* exact copy of BLI_findstring(), except for this line */
ptr_iter = *((const void **)(((const char *)link) + offset));
@ -654,16 +655,16 @@ void *BLI_findptr(const ListBase *listbase, const void *ptr, const int offset)
}
}
return NULL;
return nullptr;
}
void *BLI_rfindptr(const ListBase *listbase, const void *ptr, const int offset)
{
/* Same as #BLI_findptr but find reverse. */
Link *link = NULL;
Link *link = nullptr;
const void *ptr_iter;
for (link = listbase->last; link; link = link->prev) {
for (link = static_cast<Link *>(listbase->last); link; link = link->prev) {
/* exact copy of BLI_rfindstring(), except for this line */
ptr_iter = *((const void **)(((const char *)link) + offset));
@ -672,7 +673,7 @@ void *BLI_rfindptr(const ListBase *listbase, const void *ptr, const int offset)
}
}
return NULL;
return nullptr;
}
void *BLI_listbase_bytes_find(const ListBase *listbase,
@ -680,10 +681,10 @@ void *BLI_listbase_bytes_find(const ListBase *listbase,
const size_t bytes_size,
const int offset)
{
Link *link = NULL;
Link *link = nullptr;
const void *ptr_iter;
for (link = listbase->first; link; link = link->next) {
for (link = static_cast<Link *>(listbase->first); link; link = link->next) {
ptr_iter = (const void *)(((const char *)link) + offset);
if (memcmp(bytes, ptr_iter, bytes_size) == 0) {
@ -691,7 +692,7 @@ void *BLI_listbase_bytes_find(const ListBase *listbase,
}
}
return NULL;
return nullptr;
}
void *BLI_listbase_bytes_rfind(const ListBase *listbase,
const void *bytes,
@ -700,10 +701,10 @@ void *BLI_listbase_bytes_rfind(const ListBase *listbase,
{
/* Same as #BLI_listbase_bytes_find but find reverse. */
Link *link = NULL;
Link *link = nullptr;
const void *ptr_iter;
for (link = listbase->last; link; link = link->prev) {
for (link = static_cast<Link *>(listbase->last); link; link = link->prev) {
ptr_iter = (const void *)(((const char *)link) + offset);
if (memcmp(bytes, ptr_iter, bytes_size) == 0) {
@ -711,7 +712,7 @@ void *BLI_listbase_bytes_rfind(const ListBase *listbase,
}
}
return NULL;
return nullptr;
}
void *BLI_listbase_string_or_index_find(const ListBase *listbase,
@ -719,12 +720,13 @@ void *BLI_listbase_string_or_index_find(const ListBase *listbase,
const size_t string_offset,
const int index)
{
Link *link = NULL;
Link *link_at_index = NULL;
Link *link = nullptr;
Link *link_at_index = nullptr;
int index_iter;
for (link = listbase->first, index_iter = 0; link; link = link->next, index_iter++) {
if (string != NULL && string[0] != '\0') {
for (link = static_cast<Link *>(listbase->first), index_iter = 0; link;
link = link->next, index_iter++) {
if (string != nullptr && string[0] != '\0') {
const char *string_iter = ((const char *)link) + string_offset;
if (string[0] == string_iter[0] && STREQ(string, string_iter)) {
@ -740,11 +742,11 @@ void *BLI_listbase_string_or_index_find(const ListBase *listbase,
int BLI_findstringindex(const ListBase *listbase, const char *id, const int offset)
{
Link *link = NULL;
Link *link = nullptr;
const char *id_iter;
int i = 0;
link = listbase->first;
link = static_cast<Link *>(listbase->first);
while (link) {
id_iter = ((const char *)link) + offset;
@ -761,17 +763,17 @@ int BLI_findstringindex(const ListBase *listbase, const char *id, const int offs
ListBase BLI_listbase_from_link(Link *some_link)
{
ListBase list = {some_link, some_link};
if (some_link == NULL) {
if (some_link == nullptr) {
return list;
}
/* Find the first element. */
while (((Link *)list.first)->prev != NULL) {
while (((Link *)list.first)->prev != nullptr) {
list.first = ((Link *)list.first)->prev;
}
/* Find the last element. */
while (((Link *)list.last)->next != NULL) {
while (((Link *)list.last)->next != nullptr) {
list.last = ((Link *)list.last)->next;
}
@ -783,11 +785,11 @@ void BLI_duplicatelist(ListBase *dst, const ListBase *src)
struct Link *dst_link, *src_link;
/* in this order, to ensure it works if dst == src */
src_link = src->first;
dst->first = dst->last = NULL;
src_link = static_cast<Link *>(src->first);
dst->first = dst->last = nullptr;
while (src_link) {
dst_link = MEM_dupallocN(src_link);
dst_link = static_cast<Link *>(MEM_dupallocN(src_link));
BLI_addtail(dst, dst_link);
src_link = src_link->next;
@ -796,9 +798,9 @@ void BLI_duplicatelist(ListBase *dst, const ListBase *src)
void BLI_listbase_reverse(ListBase *lb)
{
struct Link *curr = lb->first;
struct Link *prev = NULL;
struct Link *next = NULL;
struct Link *curr = static_cast<Link *>(lb->first);
struct Link *prev = nullptr;
struct Link *next = nullptr;
while (curr) {
next = curr->next;
curr->next = prev;
@ -808,7 +810,7 @@ void BLI_listbase_reverse(ListBase *lb)
}
/* swap first/last */
curr = lb->first;
curr = static_cast<Link *>(lb->first);
lb->first = lb->last;
lb->last = curr;
}
@ -816,39 +818,39 @@ void BLI_listbase_reverse(ListBase *lb)
void BLI_listbase_rotate_first(ListBase *lb, void *vlink)
{
/* make circular */
((Link *)lb->first)->prev = lb->last;
((Link *)lb->last)->next = lb->first;
((Link *)lb->first)->prev = static_cast<Link *>(lb->last);
((Link *)lb->last)->next = static_cast<Link *>(lb->first);
lb->first = vlink;
lb->last = ((Link *)vlink)->prev;
((Link *)lb->first)->prev = NULL;
((Link *)lb->last)->next = NULL;
((Link *)lb->first)->prev = nullptr;
((Link *)lb->last)->next = nullptr;
}
void BLI_listbase_rotate_last(ListBase *lb, void *vlink)
{
/* make circular */
((Link *)lb->first)->prev = lb->last;
((Link *)lb->last)->next = lb->first;
((Link *)lb->first)->prev = static_cast<Link *>(lb->last);
((Link *)lb->last)->next = static_cast<Link *>(lb->first);
lb->first = ((Link *)vlink)->next;
lb->last = vlink;
((Link *)lb->first)->prev = NULL;
((Link *)lb->last)->next = NULL;
((Link *)lb->first)->prev = nullptr;
((Link *)lb->last)->next = nullptr;
}
LinkData *BLI_genericNodeN(void *data)
{
LinkData *ld;
if (data == NULL) {
return NULL;
if (data == nullptr) {
return nullptr;
}
/* create new link, and make it hold the given data */
ld = MEM_callocN(sizeof(LinkData), __func__);
ld = MEM_cnew<LinkData>(__func__);
ld->data = data;
return ld;

View File

@ -85,12 +85,14 @@ struct GPUBatch *DRW_pbvh_tris_get(PBVHBatches *batches,
struct PBVHAttrReq *attrs,
int attrs_num,
PBVH_GPU_Args *args,
int *r_prim_count);
int *r_prim_count,
bool do_coarse_grids);
struct GPUBatch *DRW_pbvh_lines_get(struct PBVHBatches *batches,
struct PBVHAttrReq *attrs,
int attrs_num,
PBVH_GPU_Args *args,
int *r_prim_count);
int *r_prim_count,
bool do_coarse_grids);
#ifdef __cplusplus
}

View File

@ -1220,10 +1220,12 @@ static void sculpt_draw_cb(DRWSculptCallbackData *scd,
GPUBatch *geom;
if (!scd->use_wire) {
geom = DRW_pbvh_tris_get(batches, scd->attrs, scd->attrs_num, pbvh_draw_args, &primcount);
geom = DRW_pbvh_tris_get(
batches, scd->attrs, scd->attrs_num, pbvh_draw_args, &primcount, scd->fast_mode);
}
else {
geom = DRW_pbvh_lines_get(batches, scd->attrs, scd->attrs_num, pbvh_draw_args, &primcount);
geom = DRW_pbvh_lines_get(
batches, scd->attrs, scd->attrs_num, pbvh_draw_args, &primcount, scd->fast_mode);
}
short index = 0;

View File

@ -66,6 +66,22 @@ using blender::Vector;
using string = std::string;
static bool valid_pbvh_attr(int type)
{
switch (type) {
case CD_PBVH_CO_TYPE:
case CD_PBVH_NO_TYPE:
case CD_PBVH_FSET_TYPE:
case CD_PBVH_MASK_TYPE:
case CD_PROP_COLOR:
case CD_PROP_BYTE_COLOR:
case CD_MLOOPUV:
return true;
}
return false;
}
struct PBVHVbo {
uint64_t type;
eAttrDomain domain;
@ -99,6 +115,8 @@ struct PBVHBatch {
string key;
GPUBatch *tris = nullptr, *lines = nullptr;
int tris_count = 0, lines_count = 0;
bool is_coarse =
false; /* Coarse multires, will use full-sized VBOs only index buffer changes. */
void sort_vbos(Vector<PBVHVbo> &master_vbos)
{
@ -122,6 +140,10 @@ struct PBVHBatch {
{
key = "";
if (is_coarse) {
key += "c:";
}
sort_vbos(master_vbos);
for (int vbo_i : vbos) {
@ -157,6 +179,12 @@ struct PBVHBatches {
int material_index = 0;
/* Stuff for displaying coarse multires grids. */
GPUIndexBuf *tri_index_coarse = nullptr;
GPUIndexBuf *lines_index_coarse = nullptr;
int coarse_level = 0; /* Coarse multires depth. */
int tris_count_coarse = 0, lines_count_coarse = 0;
int count_faces(PBVH_GPU_Args *args)
{
int count = 0;
@ -178,6 +206,7 @@ struct PBVHBatches {
count = BKE_pbvh_count_grid_quads((BLI_bitmap **)args->grid_hidden,
args->grid_indices,
args->totprim,
args->ccg_key.grid_size,
args->ccg_key.grid_size);
break;
@ -217,9 +246,11 @@ struct PBVHBatches {
GPU_INDEXBUF_DISCARD_SAFE(tri_index);
GPU_INDEXBUF_DISCARD_SAFE(lines_index);
GPU_INDEXBUF_DISCARD_SAFE(tri_index_coarse);
GPU_INDEXBUF_DISCARD_SAFE(lines_index_coarse);
}
string build_key(PBVHAttrReq *attrs, int attrs_num)
string build_key(PBVHAttrReq *attrs, int attrs_num, bool do_coarse_grids)
{
string key;
PBVHBatch batch;
@ -228,6 +259,10 @@ struct PBVHBatches {
for (int i : IndexRange(attrs_num)) {
PBVHAttrReq *attr = attrs + i;
if (!valid_pbvh_attr(attr->type)) {
continue;
}
PBVHVbo vbo(attr->domain, attr->type, string(attr->name));
vbo.build_key();
@ -235,6 +270,7 @@ struct PBVHBatches {
batch.vbos.append(i);
}
batch.is_coarse = do_coarse_grids;
batch.build_key(vbos);
return batch.key;
}
@ -272,18 +308,21 @@ struct PBVHBatches {
return nullptr;
}
bool has_batch(PBVHAttrReq *attrs, int attrs_num)
bool has_batch(PBVHAttrReq *attrs, int attrs_num, bool do_coarse_grids)
{
return batches.contains(build_key(attrs, attrs_num));
return batches.contains(build_key(attrs, attrs_num, do_coarse_grids));
}
PBVHBatch &ensure_batch(PBVHAttrReq *attrs, int attrs_num, PBVH_GPU_Args *args)
PBVHBatch &ensure_batch(PBVHAttrReq *attrs,
int attrs_num,
PBVH_GPU_Args *args,
bool do_coarse_grids)
{
if (!has_batch(attrs, attrs_num)) {
create_batch(attrs, attrs_num, args);
if (!has_batch(attrs, attrs_num, do_coarse_grids)) {
create_batch(attrs, attrs_num, args, do_coarse_grids);
}
return batches.lookup(build_key(attrs, attrs_num));
return batches.lookup(build_key(attrs, attrs_num, do_coarse_grids));
}
void fill_vbo_normal_faces(
@ -484,9 +523,12 @@ struct PBVHBatches {
for (int x = 0; x < gridsize; x++) {
CCGElem *elems[4] = {
CCG_grid_elem(&args->ccg_key, grid, x, y),
CCG_grid_elem(&args->ccg_key, grid, x + 1, y),
CCG_grid_elem(&args->ccg_key, grid, x + 1, y + 1),
CCG_grid_elem(&args->ccg_key, grid, x, y + 1),
CCG_grid_elem(&args->ccg_key, grid, min_ii(x + 1, gridsize - 1), y),
CCG_grid_elem(&args->ccg_key,
grid,
min_ii(x + 1, gridsize - 1),
min_ii(y + 1, gridsize - 1)),
CCG_grid_elem(&args->ccg_key, grid, x, min_ii(y + 1, gridsize - 1)),
};
func(x, y, grid_index, elems, 0);
@ -859,10 +901,10 @@ struct PBVHBatches {
break;
}
default:
BLI_assert(0);
printf("%s: error\n", __func__);
printf("%s: Unsupported attribute type %d\n", __func__, type);
BLI_assert_unreachable();
break;
return;
}
if (need_aliases) {
@ -945,8 +987,10 @@ struct PBVHBatches {
GPU_INDEXBUF_DISCARD_SAFE(tri_index);
GPU_INDEXBUF_DISCARD_SAFE(lines_index);
GPU_INDEXBUF_DISCARD_SAFE(tri_index_coarse);
GPU_INDEXBUF_DISCARD_SAFE(lines_index_coarse);
tri_index = lines_index = nullptr;
tri_index = lines_index = tri_index_coarse = lines_index_coarse = nullptr;
faces_count = tris_count = count;
}
}
@ -1042,7 +1086,7 @@ struct PBVHBatches {
lines_index = GPU_indexbuf_build(&elb_lines);
}
void create_index_grids(PBVH_GPU_Args *args)
void create_index_grids(PBVH_GPU_Args *args, bool do_coarse)
{
int *mat_index = static_cast<int *>(
CustomData_get_layer_named(args->pdata, CD_PROP_INT32, "material_index"));
@ -1054,15 +1098,24 @@ struct PBVHBatches {
needs_tri_index = true;
int gridsize = args->ccg_key.grid_size;
int display_gridsize = gridsize;
int totgrid = args->totprim;
int skip = 1;
const int display_level = do_coarse ? coarse_level : args->ccg_key.level;
if (display_level < args->ccg_key.level) {
display_gridsize = (1 << display_level) + 1;
skip = 1 << (args->ccg_key.level - display_level - 1);
}
for (int i : IndexRange(args->totprim)) {
int grid_index = args->grid_indices[i];
bool smooth = args->grid_flag_mats[grid_index].flag & ME_SMOOTH;
BLI_bitmap *gh = args->grid_hidden[grid_index];
for (int y = 0; y < gridsize - 1; y++) {
for (int x = 0; x < gridsize - 1; x++) {
for (int y = 0; y < gridsize - 1; y += skip) {
for (int x = 0; x < gridsize - 1; x += skip) {
if (gh && paint_is_grid_face_hidden(gh, gridsize, x, y)) {
/* Skip hidden faces by just setting smooth to true. */
smooth = true;
@ -1083,12 +1136,17 @@ struct PBVHBatches {
CCGKey *key = &args->ccg_key;
uint visible_quad_len = BKE_pbvh_count_grid_quads(
(BLI_bitmap **)args->grid_hidden, args->grid_indices, totgrid, key->grid_size);
uint visible_quad_len = BKE_pbvh_count_grid_quads((BLI_bitmap **)args->grid_hidden,
args->grid_indices,
totgrid,
key->grid_size,
display_gridsize);
GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, 2 * visible_quad_len, INT_MAX);
GPU_indexbuf_init(
&elb_lines, GPU_PRIM_LINES, 2 * totgrid * gridsize * (gridsize - 1), INT_MAX);
GPU_indexbuf_init(&elb_lines,
GPU_PRIM_LINES,
2 * totgrid * display_gridsize * (display_gridsize - 1),
INT_MAX);
if (needs_tri_index) {
uint offset = 0;
@ -1099,17 +1157,17 @@ struct PBVHBatches {
BLI_bitmap *gh = args->grid_hidden[args->grid_indices[i]];
for (int j = 0; j < gridsize - 1; j++) {
for (int k = 0; k < gridsize - 1; k++) {
for (int j = 0; j < gridsize - skip; j += skip) {
for (int k = 0; k < gridsize - skip; k += skip) {
/* Skip hidden grid face */
if (gh && paint_is_grid_face_hidden(gh, gridsize, k, j)) {
continue;
}
/* Indices in a Clockwise QUAD disposition. */
v0 = offset + j * gridsize + k;
v1 = v0 + 1;
v2 = v1 + gridsize;
v3 = v2 - 1;
v1 = offset + j * gridsize + k + skip;
v2 = offset + (j + skip) * gridsize + k + skip;
v3 = offset + (j + skip) * gridsize + k;
GPU_indexbuf_add_tri_verts(&elb, v0, v2, v1);
GPU_indexbuf_add_tri_verts(&elb, v0, v3, v2);
@ -1117,7 +1175,7 @@ struct PBVHBatches {
GPU_indexbuf_add_line_verts(&elb_lines, v0, v1);
GPU_indexbuf_add_line_verts(&elb_lines, v0, v3);
if (j + 2 == gridsize) {
if (j / skip + 2 == display_gridsize) {
GPU_indexbuf_add_line_verts(&elb_lines, v2, v3);
}
grid_visible = true;
@ -1132,22 +1190,38 @@ struct PBVHBatches {
else {
uint offset = 0;
const uint grid_vert_len = square_uint(gridsize - 1) * 4;
for (int i = 0; i < totgrid; i++, offset += grid_vert_len) {
bool grid_visible = false;
BLI_bitmap *gh = args->grid_hidden[args->grid_indices[i]];
uint v0, v1, v2, v3;
for (int j = 0; j < gridsize - 1; j++) {
for (int k = 0; k < gridsize - 1; k++) {
for (int j = 0; j < gridsize - skip; j += skip) {
for (int k = 0; k < gridsize - skip; k += skip) {
/* Skip hidden grid face */
if (gh && paint_is_grid_face_hidden(gh, gridsize, k, j)) {
continue;
}
/* VBO data are in a Clockwise QUAD disposition. */
v0 = offset + (j * (gridsize - 1) + k) * 4;
v1 = v0 + 1;
v2 = v0 + 2;
v3 = v0 + 3;
v0 = (j * (gridsize - 1) + k) * 4;
if (skip > 1) {
v1 = (j * (gridsize - 1) + k + skip - 1) * 4;
v2 = ((j + skip - 1) * (gridsize - 1) + k + skip - 1) * 4;
v3 = ((j + skip - 1) * (gridsize - 1) + k) * 4;
}
else {
v1 = v2 = v3 = v0;
}
/* VBO data are in a Clockwise QUAD disposition. Note
* that vertices might be in different quads if we're
* building a coarse index buffer.
*/
v0 += offset;
v1 += offset + 1;
v2 += offset + 2;
v3 += offset + 3;
GPU_indexbuf_add_tri_verts(&elb, v0, v2, v1);
GPU_indexbuf_add_tri_verts(&elb, v0, v3, v2);
@ -1155,7 +1229,7 @@ struct PBVHBatches {
GPU_indexbuf_add_line_verts(&elb_lines, v0, v1);
GPU_indexbuf_add_line_verts(&elb_lines, v0, v3);
if (j + 2 == gridsize) {
if ((j / skip) + 2 == display_gridsize) {
GPU_indexbuf_add_line_verts(&elb_lines, v2, v3);
}
grid_visible = true;
@ -1168,8 +1242,16 @@ struct PBVHBatches {
}
}
tri_index = GPU_indexbuf_build(&elb);
lines_index = GPU_indexbuf_build(&elb_lines);
if (do_coarse) {
tri_index_coarse = GPU_indexbuf_build(&elb);
lines_index_coarse = GPU_indexbuf_build(&elb_lines);
tris_count_coarse = visible_quad_len;
lines_count_coarse = totgrid * display_gridsize * (display_gridsize - 1);
}
else {
tri_index = GPU_indexbuf_build(&elb);
lines_index = GPU_indexbuf_build(&elb_lines);
}
}
void create_index(PBVH_GPU_Args *args)
@ -1182,7 +1264,12 @@ struct PBVHBatches {
create_index_bmesh(args);
break;
case PBVH_GRIDS:
create_index_grids(args);
create_index_grids(args, false);
if (args->ccg_key.level > coarse_level) {
create_index_grids(args, true);
}
break;
}
@ -1208,7 +1295,7 @@ struct PBVHBatches {
}
}
void create_batch(PBVHAttrReq *attrs, int attrs_num, PBVH_GPU_Args *args)
void create_batch(PBVHAttrReq *attrs, int attrs_num, PBVH_GPU_Args *args, bool do_coarse_grids)
{
check_index_buffers(args);
@ -1217,17 +1304,23 @@ struct PBVHBatches {
batch.tris = GPU_batch_create(GPU_PRIM_TRIS,
nullptr,
/* can be nullptr if buffer is empty */
tri_index);
batch.tris_count = tris_count;
do_coarse_grids ? tri_index_coarse : tri_index);
batch.tris_count = do_coarse_grids ? tris_count_coarse : tris_count;
batch.is_coarse = do_coarse_grids;
if (lines_index) {
batch.lines = GPU_batch_create(GPU_PRIM_LINES, nullptr, lines_index);
batch.lines_count = lines_count;
batch.lines = GPU_batch_create(
GPU_PRIM_LINES, nullptr, do_coarse_grids ? lines_index_coarse : lines_index);
batch.lines_count = do_coarse_grids ? lines_count_coarse : lines_count;
}
for (int i : IndexRange(attrs_num)) {
PBVHAttrReq *attr = attrs + i;
if (!valid_pbvh_attr(attr->type)) {
continue;
}
if (!has_vbo(attr->domain, int(attr->type), attr->name)) {
create_vbo(attr->domain, uint32_t(attr->type), attr->name, args);
}
@ -1273,9 +1366,12 @@ GPUBatch *DRW_pbvh_tris_get(PBVHBatches *batches,
PBVHAttrReq *attrs,
int attrs_num,
PBVH_GPU_Args *args,
int *r_prim_count)
int *r_prim_count,
bool do_coarse_grids)
{
PBVHBatch &batch = batches->ensure_batch(attrs, attrs_num, args);
do_coarse_grids &= args->pbvh_type == PBVH_GRIDS;
PBVHBatch &batch = batches->ensure_batch(attrs, attrs_num, args, do_coarse_grids);
*r_prim_count = batch.tris_count;
@ -1286,9 +1382,12 @@ GPUBatch *DRW_pbvh_lines_get(PBVHBatches *batches,
PBVHAttrReq *attrs,
int attrs_num,
PBVH_GPU_Args *args,
int *r_prim_count)
int *r_prim_count,
bool do_coarse_grids)
{
PBVHBatch &batch = batches->ensure_batch(attrs, attrs_num, args);
do_coarse_grids &= args->pbvh_type == PBVH_GRIDS;
PBVHBatch &batch = batches->ensure_batch(attrs, attrs_num, args, do_coarse_grids);
*r_prim_count = batch.lines_count;

View File

@ -1345,6 +1345,11 @@ static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext)
static void sculpt_gesture_trim_begin(bContext *C, SculptGestureContext *sgcontext)
{
Object *object = sgcontext->vc.obact;
SculptSession *ss = object->sculpt;
Mesh *mesh = (Mesh *)object->data;
ss->face_sets = BKE_sculpt_face_sets_ensure(mesh);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
sculpt_gesture_trim_calculate_depth(sgcontext);
sculpt_gesture_trim_geometry_generate(sgcontext);
@ -1369,9 +1374,9 @@ static void sculpt_gesture_trim_end(bContext *UNUSED(C), SculptGestureContext *s
{
Object *object = sgcontext->vc.obact;
SculptSession *ss = object->sculpt;
Mesh *mesh = (Mesh *)object->data;
ss->face_sets = CustomData_get_layer_named(
&((Mesh *)object->data)->pdata, CD_PROP_INT32, ".sculpt_face_set");
ss->face_sets = CustomData_get_layer_named(&mesh->pdata, CD_PROP_INT32, ".sculpt_face_set");
if (ss->face_sets) {
/* Assign a new Face Set ID to the new faces created by the trim operation. */
const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(object->data);

View File

@ -1320,6 +1320,7 @@ static bool sculpt_brush_use_topology_rake(const SculptSession *ss, const Brush
*/
static int sculpt_brush_needs_normal(const SculptSession *ss, Sculpt *sd, const Brush *brush)
{
const MTex *mask_tex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT);
return ((SCULPT_TOOL_HAS_NORMAL_WEIGHT(brush->sculpt_tool) &&
(ss->cache->normal_weight > 0.0f)) ||
SCULPT_automasking_needs_normal(ss, sd, brush) ||
@ -1335,7 +1336,7 @@ static int sculpt_brush_needs_normal(const SculptSession *ss, Sculpt *sd, const
SCULPT_TOOL_ELASTIC_DEFORM,
SCULPT_TOOL_THUMB) ||
(brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA)) ||
(mask_tex->brush_map_mode == MTEX_MAP_MODE_AREA)) ||
sculpt_brush_use_topology_rake(ss, brush);
}
@ -2862,7 +2863,7 @@ static void calc_local_y(ViewContext *vc, const float center[3], float y[3])
mul_m4_v3(ob->world_to_object, y);
}
static void calc_brush_local_mat(const Brush *brush, Object *ob, float local_mat[4][4])
static void calc_brush_local_mat(const MTex *mtex, Object *ob, float local_mat[4][4])
{
const StrokeCache *cache = ob->sculpt->cache;
float tmat[4][4];
@ -2886,7 +2887,7 @@ static void calc_brush_local_mat(const Brush *brush, Object *ob, float local_mat
/* Calculate the X axis of the local matrix. */
cross_v3_v3v3(v, up, cache->sculpt_normal);
/* Apply rotation (user angle, rake, etc.) to X axis. */
angle = brush->mtex.rot - cache->special_rotation;
angle = mtex->rot - cache->special_rotation;
rotate_v3_v3v3fl(mat[0], v, cache->sculpt_normal, angle);
/* Get other axes. */
@ -2933,7 +2934,9 @@ static void update_brush_local_mat(Sculpt *sd, Object *ob)
StrokeCache *cache = ob->sculpt->cache;
if (cache->mirror_symmetry_pass == 0 && cache->radial_symmetry_pass == 0) {
calc_brush_local_mat(BKE_paint_brush(&sd->paint), ob, cache->brush_local_mat);
const Brush *brush = BKE_paint_brush(&sd->paint);
const MTex *mask_tex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT);
calc_brush_local_mat(mask_tex, ob, cache->brush_local_mat);
}
}
@ -3508,7 +3511,8 @@ static void do_brush_action(Sculpt *sd,
update_sculpt_normal(sd, ob, nodes, totnode);
}
if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA) {
const MTex *mask_tex = BKE_brush_mask_texture_get(brush, static_cast<eObjectMode>(ob->mode));
if (mask_tex->brush_map_mode == MTEX_MAP_MODE_AREA) {
update_brush_local_mat(sd, ob);
}
@ -4043,7 +4047,7 @@ static void sculpt_fix_noise_tear(Sculpt *sd, Object *ob)
{
SculptSession *ss = ob->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
MTex *mtex = &brush->mtex;
const MTex *mtex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT);
if (ss->multires.active && mtex->tex && mtex->tex->type == TEX_NOISE) {
multires_stitch_grids(ob);
@ -5192,12 +5196,12 @@ bool SCULPT_stroke_get_location(bContext *C,
static void sculpt_brush_init_tex(Sculpt *sd, SculptSession *ss)
{
Brush *brush = BKE_paint_brush(&sd->paint);
MTex *mtex = &brush->mtex;
const MTex *mask_tex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT);
/* Init mtex nodes. */
if (mtex->tex && mtex->tex->nodetree) {
if (mask_tex->tex && mask_tex->tex->nodetree) {
/* Has internal flag to detect it only does it once. */
ntreeTexBeginExecTree(mtex->tex->nodetree);
ntreeTexBeginExecTree(mask_tex->tex->nodetree);
}
if (ss->tex_pool == nullptr) {
@ -5626,10 +5630,10 @@ static void sculpt_stroke_update_step(bContext *C,
static void sculpt_brush_exit_tex(Sculpt *sd)
{
Brush *brush = BKE_paint_brush(&sd->paint);
MTex *mtex = &brush->mtex;
const MTex *mask_tex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT);
if (mtex->tex && mtex->tex->nodetree) {
ntreeTexEndExecTree(mtex->tex->nodetree->runtime->execdata);
if (mask_tex->tex && mask_tex->tex->nodetree) {
ntreeTexEndExecTree(mask_tex->tex->nodetree->runtime->execdata);
}
}

View File

@ -193,7 +193,8 @@ static float sculpt_expand_max_vertex_falloff_get(ExpandCache *expand_cache)
return expand_cache->max_vert_falloff;
}
if (!expand_cache->brush->mtex.tex) {
const MTex *mask_tex = BKE_brush_mask_texture_get(expand_cache->brush, OB_MODE_SCULPT);
if (!mask_tex->tex) {
return expand_cache->max_vert_falloff;
}
@ -1882,13 +1883,14 @@ static int sculpt_expand_modal(bContext *C, wmOperator *op, const wmEvent *event
}
case SCULPT_EXPAND_MODAL_TEXTURE_DISTORTION_INCREASE: {
if (expand_cache->texture_distortion_strength == 0.0f) {
if (expand_cache->brush->mtex.tex == NULL) {
const MTex *mask_tex = BKE_brush_mask_texture_get(expand_cache->brush, OB_MODE_SCULPT);
if (mask_tex->tex == NULL) {
BKE_report(op->reports,
RPT_WARNING,
"Active brush does not contain any texture to distort the expand boundary");
break;
}
if (expand_cache->brush->mtex.brush_map_mode != MTEX_MAP_MODE_3D) {
if (mask_tex->brush_map_mode != MTEX_MAP_MODE_3D) {
BKE_report(op->reports,
RPT_WARNING,
"Texture mapping not set to 3D, results may be unpredictable");
@ -2052,7 +2054,6 @@ static void sculpt_expand_cache_initial_config_set(bContext *C,
IMB_colormanagement_srgb_to_scene_linear_v3(expand_cache->fill_color, expand_cache->fill_color);
expand_cache->scene = CTX_data_scene(C);
expand_cache->mtex = &expand_cache->brush->mtex;
expand_cache->texture_distortion_strength = 0.0f;
expand_cache->blend_mode = expand_cache->brush->blend;
}

View File

@ -692,7 +692,7 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
CustomData_get_layer(&mesh->edata, CD_CREASE));
sculpt_face_sets_init_flood_fill(
ob, [&](const int /*from_face*/, const int edge, const int /*to_face*/) -> bool {
return creases[edge] < threshold;
return creases ? creases[edge] < threshold : true;
});
break;
}
@ -709,7 +709,7 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
CustomData_get_layer(&mesh->edata, CD_BWEIGHT));
sculpt_face_sets_init_flood_fill(
ob, [&](const int /*from_face*/, const int edge, const int /*to_face*/) -> bool {
return bevel_weights ? bevel_weights[edge] / 255.0f < threshold : true;
return bevel_weights ? bevel_weights[edge] < threshold : true;
});
break;
}

View File

@ -752,7 +752,7 @@ typedef struct ExpandCache {
/* Texture distortion data. */
Brush *brush;
struct Scene *scene;
struct MTex *mtex;
// struct MTex *mtex;
/* Controls how much texture distortion will be applied to the current falloff */
float texture_distortion_strength;

View File

@ -2813,9 +2813,9 @@ static void frame_node_draw_label(TreeDrawContext &tree_draw_ctx,
BLF_wordwrap(fontid, line_width);
LISTBASE_FOREACH (const TextLine *, line, &text->lines) {
ResultBLF info;
if (line->line[0]) {
BLF_position(fontid, x, y, 0);
ResultBLF info;
BLF_draw_ex(fontid, line->line, line->len, &info);
y -= line_spacing * info.lines;
}
@ -2890,10 +2890,8 @@ static void frame_node_draw(const bContext &C,
static void reroute_node_draw(
const bContext &C, ARegion &region, bNodeTree &ntree, bNode &node, uiBlock &block)
{
char showname[128]; /* 128 used below */
const rctf &rct = node.runtime->totr;
/* skip if out of view */
const rctf &rct = node.runtime->totr;
if (rct.xmax < region.v2d.cur.xmin || rct.xmin > region.v2d.cur.xmax ||
rct.ymax < region.v2d.cur.ymin || node.runtime->totr.ymin > region.v2d.cur.ymax) {
UI_block_end(&C, &block);
@ -2902,6 +2900,7 @@ static void reroute_node_draw(
if (node.label[0] != '\0') {
/* draw title (node label) */
char showname[128]; /* 128 used below */
BLI_strncpy(showname, node.label, sizeof(showname));
const short width = 512;
const int x = BLI_rctf_cent_x(&node.runtime->totr) - (width / 2);
@ -2987,7 +2986,7 @@ static void node_draw_nodetree(const bContext &C,
continue;
}
bNodeInstanceKey key = BKE_node_instance_key(parent_key, &ntree, nodes[i]);
const bNodeInstanceKey key = BKE_node_instance_key(parent_key, &ntree, nodes[i]);
node_draw(C, tree_draw_ctx, region, snode, ntree, *nodes[i], *blocks[i], key);
}
@ -3017,7 +3016,7 @@ static void node_draw_nodetree(const bContext &C,
continue;
}
bNodeInstanceKey key = BKE_node_instance_key(parent_key, &ntree, nodes[i]);
const bNodeInstanceKey key = BKE_node_instance_key(parent_key, &ntree, nodes[i]);
node_draw(C, tree_draw_ctx, region, snode, ntree, *nodes[i], *blocks[i], key);
}
}
@ -3025,8 +3024,6 @@ static void node_draw_nodetree(const bContext &C,
/* Draw the breadcrumb on the top of the editor. */
static void draw_tree_path(const bContext &C, ARegion &region)
{
using namespace blender;
GPU_matrix_push_projection();
wmOrtho2_region_pixelspace(&region);
@ -3042,7 +3039,7 @@ static void draw_tree_path(const bContext &C, ARegion &region)
uiLayout *layout = UI_block_layout(
block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, x, y, width, 1, 0, style);
Vector<ui::ContextPathItem> context_path = ed::space_node::context_path_for_space_node(C);
const Vector<ui::ContextPathItem> context_path = ed::space_node::context_path_for_space_node(C);
ui::template_breadcrumbs(*layout, context_path);
UI_block_layout_resolve(block, nullptr, nullptr);
@ -3115,7 +3112,7 @@ static void draw_nodetree(const bContext &C,
SpaceNode *snode = CTX_wm_space_node(&C);
ntree.ensure_topology_cache();
Span<bNode *> nodes = ntree.all_nodes();
const Span<bNode *> nodes = ntree.all_nodes();
Array<uiBlock *> blocks = node_uiblocks_init(C, nodes);
@ -3126,7 +3123,7 @@ static void draw_nodetree(const bContext &C,
tree_draw_ctx.geo_tree_log->ensure_node_warnings();
tree_draw_ctx.geo_tree_log->ensure_node_run_time();
}
WorkSpace *workspace = CTX_wm_workspace(&C);
const WorkSpace *workspace = CTX_wm_workspace(&C);
tree_draw_ctx.active_geometry_nodes_viewer = viewer_path::find_geometry_nodes_viewer(
workspace->viewer_path, *snode);
}

View File

@ -673,146 +673,137 @@ void ED_node_set_active(
}
nodeSetActive(ntree, node);
if (node->type == NODE_GROUP) {
return;
}
if (node->type != NODE_GROUP) {
const bool was_output = (node->flag & NODE_DO_OUTPUT) != 0;
bool do_update = false;
const bool was_output = (node->flag & NODE_DO_OUTPUT) != 0;
bool do_update = false;
/* generic node group output: set node as active output */
if (node->type == NODE_GROUP_OUTPUT) {
/* generic node group output: set node as active output */
if (node->type == NODE_GROUP_OUTPUT) {
for (bNode *node_iter : ntree->all_nodes()) {
if (node_iter->type == NODE_GROUP_OUTPUT) {
node_iter->flag &= ~NODE_DO_OUTPUT;
}
}
node->flag |= NODE_DO_OUTPUT;
if (!was_output) {
do_update = true;
BKE_ntree_update_tag_active_output_changed(ntree);
}
}
/* tree specific activate calls */
if (ntree->type == NTREE_SHADER) {
if (ELEM(node->type,
SH_NODE_OUTPUT_MATERIAL,
SH_NODE_OUTPUT_WORLD,
SH_NODE_OUTPUT_LIGHT,
SH_NODE_OUTPUT_LINESTYLE)) {
for (bNode *node_iter : ntree->all_nodes()) {
if (node_iter->type == NODE_GROUP_OUTPUT) {
if (node_iter->type == node->type) {
node_iter->flag &= ~NODE_DO_OUTPUT;
}
}
node->flag |= NODE_DO_OUTPUT;
if (!was_output) {
do_update = true;
BKE_ntree_update_tag_active_output_changed(ntree);
}
BKE_ntree_update_tag_active_output_changed(ntree);
}
/* tree specific activate calls */
if (ntree->type == NTREE_SHADER) {
if (ELEM(node->type,
SH_NODE_OUTPUT_MATERIAL,
SH_NODE_OUTPUT_WORLD,
SH_NODE_OUTPUT_LIGHT,
SH_NODE_OUTPUT_LINESTYLE)) {
for (bNode *node_iter : ntree->all_nodes()) {
if (node_iter->type == node->type) {
node_iter->flag &= ~NODE_DO_OUTPUT;
}
}
ED_node_tree_propagate_change(nullptr, bmain, ntree);
node->flag |= NODE_DO_OUTPUT;
BKE_ntree_update_tag_active_output_changed(ntree);
}
if ((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) {
/* If active texture changed, free glsl materials. */
LISTBASE_FOREACH (Material *, ma, &bmain->materials) {
if (ma->nodetree && ma->use_nodes && ntreeHasTree(ma->nodetree, ntree)) {
GPU_material_free(&ma->gpumaterial);
ED_node_tree_propagate_change(nullptr, bmain, ntree);
if ((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) {
/* If active texture changed, free glsl materials. */
LISTBASE_FOREACH (Material *, ma, &bmain->materials) {
if (ma->nodetree && ma->use_nodes && ntreeHasTree(ma->nodetree, ntree)) {
GPU_material_free(&ma->gpumaterial);
/* Sync to active texpaint slot, otherwise we can end up painting on a different slot
* than we are looking at. */
if (ma->texpaintslot) {
if (node->id != nullptr && GS(node->id->name) == ID_IM) {
Image *image = (Image *)node->id;
for (int i = 0; i < ma->tot_slots; i++) {
if (ma->texpaintslot[i].ima == image) {
ma->paint_active_slot = i;
}
/* Sync to active texpaint slot, otherwise we can end up painting on a different slot
* than we are looking at. */
if (ma->texpaintslot) {
if (node->id != nullptr && GS(node->id->name) == ID_IM) {
Image *image = (Image *)node->id;
for (int i = 0; i < ma->tot_slots; i++) {
if (ma->texpaintslot[i].ima == image) {
ma->paint_active_slot = i;
}
}
}
}
}
LISTBASE_FOREACH (World *, wo, &bmain->worlds) {
if (wo->nodetree && wo->use_nodes && ntreeHasTree(wo->nodetree, ntree)) {
GPU_material_free(&wo->gpumaterial);
}
}
/* Sync to Image Editor under the following conditions:
* - current image is not pinned
* - current image is not a Render Result or ViewerNode (want to keep looking at these) */
if (node->id != nullptr && GS(node->id->name) == ID_IM) {
Image *image = (Image *)node->id;
ED_space_image_sync(bmain, image, true);
}
if (r_active_texture_changed) {
*r_active_texture_changed = true;
}
ED_node_tree_propagate_change(nullptr, bmain, ntree);
WM_main_add_notifier(NC_IMAGE, nullptr);
}
WM_main_add_notifier(NC_MATERIAL | ND_NODES, node->id);
LISTBASE_FOREACH (World *, wo, &bmain->worlds) {
if (wo->nodetree && wo->use_nodes && ntreeHasTree(wo->nodetree, ntree)) {
GPU_material_free(&wo->gpumaterial);
}
}
/* Sync to Image Editor under the following conditions:
* - current image is not pinned
* - current image is not a Render Result or ViewerNode (want to keep looking at these) */
if (node->id != nullptr && GS(node->id->name) == ID_IM) {
Image *image = (Image *)node->id;
ED_space_image_sync(bmain, image, true);
}
if (r_active_texture_changed) {
*r_active_texture_changed = true;
}
ED_node_tree_propagate_change(nullptr, bmain, ntree);
WM_main_add_notifier(NC_IMAGE, nullptr);
}
else if (ntree->type == NTREE_COMPOSIT) {
/* make active viewer, currently only 1 supported... */
if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
WM_main_add_notifier(NC_MATERIAL | ND_NODES, node->id);
}
else if (ntree->type == NTREE_COMPOSIT) {
/* make active viewer, currently only 1 supported... */
if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
for (bNode *node_iter : ntree->all_nodes()) {
if (ELEM(node_iter->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
node_iter->flag &= ~NODE_DO_OUTPUT;
}
}
node->flag |= NODE_DO_OUTPUT;
if (was_output == 0) {
BKE_ntree_update_tag_active_output_changed(ntree);
ED_node_tree_propagate_change(nullptr, bmain, ntree);
}
/* Adding a node doesn't link this yet. */
node->id = (ID *)BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
}
else if (node->type == CMP_NODE_COMPOSITE) {
if (was_output == 0) {
for (bNode *node_iter : ntree->all_nodes()) {
if (ELEM(node_iter->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
if (node_iter->type == CMP_NODE_COMPOSITE) {
node_iter->flag &= ~NODE_DO_OUTPUT;
}
}
node->flag |= NODE_DO_OUTPUT;
if (was_output == 0) {
BKE_ntree_update_tag_active_output_changed(ntree);
ED_node_tree_propagate_change(nullptr, bmain, ntree);
}
/* Adding a node doesn't link this yet. */
node->id = (ID *)BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
}
else if (node->type == CMP_NODE_COMPOSITE) {
if (was_output == 0) {
for (bNode *node_iter : ntree->all_nodes()) {
if (node_iter->type == CMP_NODE_COMPOSITE) {
node_iter->flag &= ~NODE_DO_OUTPUT;
}
}
node->flag |= NODE_DO_OUTPUT;
BKE_ntree_update_tag_active_output_changed(ntree);
ED_node_tree_propagate_change(nullptr, bmain, ntree);
}
}
else if (do_update) {
BKE_ntree_update_tag_active_output_changed(ntree);
ED_node_tree_propagate_change(nullptr, bmain, ntree);
}
}
else if (ntree->type == NTREE_TEXTURE) {
/* XXX */
#if 0
if (node->id) {
BIF_preview_changed(-1);
allqueue(REDRAWBUTSSHADING, 1);
allqueue(REDRAWIPO, 0);
}
#endif
else if (do_update) {
ED_node_tree_propagate_change(nullptr, bmain, ntree);
}
else if (ntree->type == NTREE_GEOMETRY) {
if (node->type == GEO_NODE_VIEWER) {
if ((node->flag & NODE_DO_OUTPUT) == 0) {
for (bNode *node_iter : ntree->all_nodes()) {
if (node_iter->type == GEO_NODE_VIEWER) {
node_iter->flag &= ~NODE_DO_OUTPUT;
}
}
else if (ntree->type == NTREE_GEOMETRY) {
if (node->type == GEO_NODE_VIEWER) {
if ((node->flag & NODE_DO_OUTPUT) == 0) {
for (bNode *node_iter : ntree->all_nodes()) {
if (node_iter->type == GEO_NODE_VIEWER) {
node_iter->flag &= ~NODE_DO_OUTPUT;
}
node->flag |= NODE_DO_OUTPUT;
}
blender::ed::viewer_path::activate_geometry_node(*bmain, *snode, *node);
node->flag |= NODE_DO_OUTPUT;
}
blender::ed::viewer_path::activate_geometry_node(*bmain, *snode, *node);
}
}
}

View File

@ -534,27 +534,6 @@ static void viewRedrawPost(bContext *C, TransInfo *t)
/* XXX(ton): temp, first hack to get auto-render in compositor work. */
WM_event_add_notifier(C, NC_SCENE | ND_TRANSFORM_DONE, CTX_data_scene(C));
}
#if 0 /* TRANSFORM_FIX_ME */
if (t->spacetype == SPACE_VIEW3D) {
allqueue(REDRAWBUTSOBJECT, 0);
allqueue(REDRAWVIEW3D, 0);
}
else if (t->spacetype == SPACE_IMAGE) {
allqueue(REDRAWIMAGE, 0);
allqueue(REDRAWVIEW3D, 0);
}
else if (ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA, SPACE_GRAPH)) {
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWTIME, 0);
allqueue(REDRAWBUTSOBJECT, 0);
}
scrarea_queue_headredraw(curarea);
#endif
}
/* ************************************************* */

View File

@ -1070,87 +1070,75 @@ void transform_convert_clip_mirror_modifier_apply(TransDataContainer *tc)
{
Object *ob = tc->obedit;
ModifierData *md = ob->modifiers.first;
float tolerance[3] = {0.0f, 0.0f, 0.0f};
int axis = 0;
for (; md; md = md->next) {
if ((md->type == eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) {
MirrorModifierData *mmd = (MirrorModifierData *)md;
if (mmd->flag & MOD_MIR_CLIPPING) {
axis = 0;
if (mmd->flag & MOD_MIR_AXIS_X) {
axis |= 1;
tolerance[0] = mmd->tolerance;
if ((mmd->flag & MOD_MIR_CLIPPING) == 0) {
continue;
}
if ((mmd->flag & (MOD_MIR_AXIS_X | MOD_MIR_AXIS_Y | MOD_MIR_AXIS_Y)) == 0) {
continue;
}
float mtx[4][4], imtx[4][4];
if (mmd->mirror_ob) {
float obinv[4][4];
invert_m4_m4(obinv, mmd->mirror_ob->object_to_world);
mul_m4_m4m4(mtx, obinv, ob->object_to_world);
invert_m4_m4(imtx, mtx);
}
TransData *td = tc->data;
for (int i = 0; i < tc->data_len; i++, td++) {
float loc[3], iloc[3];
if (td->loc == NULL) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
copy_v3_v3(loc, td->loc);
copy_v3_v3(iloc, td->iloc);
if (mmd->mirror_ob) {
mul_m4_v3(mtx, loc);
mul_m4_v3(mtx, iloc);
}
bool is_clipping = false;
if (mmd->flag & MOD_MIR_AXIS_X) {
if (fabsf(iloc[0]) <= mmd->tolerance || loc[0] * iloc[0] < 0.0f) {
loc[0] = 0.0f;
is_clipping = true;
}
}
if (mmd->flag & MOD_MIR_AXIS_Y) {
axis |= 2;
tolerance[1] = mmd->tolerance;
if (fabsf(iloc[1]) <= mmd->tolerance || loc[1] * iloc[1] < 0.0f) {
loc[1] = 0.0f;
is_clipping = true;
}
}
if (mmd->flag & MOD_MIR_AXIS_Z) {
axis |= 4;
tolerance[2] = mmd->tolerance;
if (fabsf(iloc[2]) <= mmd->tolerance || loc[2] * iloc[2] < 0.0f) {
loc[2] = 0.0f;
is_clipping = true;
}
}
if (axis) {
float mtx[4][4], imtx[4][4];
int i;
if (is_clipping) {
if (mmd->mirror_ob) {
float obinv[4][4];
invert_m4_m4(obinv, mmd->mirror_ob->object_to_world);
mul_m4_m4m4(mtx, obinv, ob->object_to_world);
invert_m4_m4(imtx, mtx);
}
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
int clip;
float loc[3], iloc[3];
if (td->loc == NULL) {
break;
}
if (td->flag & TD_SKIP) {
continue;
}
copy_v3_v3(loc, td->loc);
copy_v3_v3(iloc, td->iloc);
if (mmd->mirror_ob) {
mul_m4_v3(mtx, loc);
mul_m4_v3(mtx, iloc);
}
clip = 0;
if (axis & 1) {
if (fabsf(iloc[0]) <= tolerance[0] || loc[0] * iloc[0] < 0.0f) {
loc[0] = 0.0f;
clip = 1;
}
}
if (axis & 2) {
if (fabsf(iloc[1]) <= tolerance[1] || loc[1] * iloc[1] < 0.0f) {
loc[1] = 0.0f;
clip = 1;
}
}
if (axis & 4) {
if (fabsf(iloc[2]) <= tolerance[2] || loc[2] * iloc[2] < 0.0f) {
loc[2] = 0.0f;
clip = 1;
}
}
if (clip) {
if (mmd->mirror_ob) {
mul_m4_v3(imtx, loc);
}
copy_v3_v3(td->loc, loc);
}
mul_m4_v3(imtx, loc);
}
copy_v3_v3(td->loc, loc);
}
}
}

View File

@ -64,6 +64,7 @@ static void viewer_path_for_geometry_node(const SpaceNode &snode,
NodeViewerPathElem *node_elem = BKE_viewer_path_elem_new_node();
node_elem->node_id = node->identifier;
node_elem->node_name = BLI_strdup(node->name);
BLI_addtail(&r_dst.path, node_elem);
}
NodeViewerPathElem *viewer_node_elem = BKE_viewer_path_elem_new_node();
@ -111,7 +112,7 @@ void activate_geometry_node(Main &bmain, SpaceNode &snode, bNode &node)
}
}
/* Enable viewer in one viewport if it is disable in all of them. */
/* Enable viewer in one viewport if it is disabled in all of them. */
if (!found_view3d_with_enabled_viewer && any_view3d_without_viewer != nullptr) {
any_view3d_without_viewer->flag2 |= V3D_SHOW_VIEWER;
}

View File

@ -252,7 +252,8 @@ void *CustomData_get_layer(const struct CustomData * /*data*/, int /*type*/)
int BKE_pbvh_count_grid_quads(BLI_bitmap ** /*grid_hidden*/,
const int * /*grid_indices*/,
int /*totgrid*/,
int /*gridsize*/)
int /*gridsize*/,
int /*display_gridsize*/)
{
BLI_assert_unreachable();
return 0;

View File

@ -177,7 +177,8 @@ void GpencilExporterPDF::export_gpencil_layers()
/* Apply layer thickness change. */
gps_duplicate->thickness += gpl->line_change;
/* Apply object scale to thickness. */
gps_duplicate->thickness *= mat4_to_scale(ob->object_to_world);
const float scalef = mat4_to_scale(ob->object_to_world);
gps_duplicate->thickness = ceilf((float)gps_duplicate->thickness * scalef);
CLAMP_MIN(gps_duplicate->thickness, 1.0f);
/* Fill. */
if ((is_fill) && (params_.flag & GP_EXPORT_FILL)) {
@ -236,7 +237,9 @@ void GpencilExporterPDF::export_stroke_to_polyline(bGPDlayer *gpl,
if (is_stroke && !do_fill) {
HPDF_Page_SetLineJoin(page_, HPDF_ROUND_JOIN);
HPDF_Page_SetLineWidth(page_, MAX2((radius * 2.0f) - gpl->line_change, 1.0f));
const float width = MAX2(
MAX2(gps->thickness + gpl->line_change, (radius * 2.0f) + gpl->line_change), 1.0f);
HPDF_Page_SetLineWidth(page_, width);
}
/* Loop all points. */

View File

@ -198,7 +198,8 @@ void GpencilExporterSVG::export_gpencil_layers()
/* Apply layer thickness change. */
gps_duplicate->thickness += gpl->line_change;
/* Apply object scale to thickness. */
gps_duplicate->thickness *= mat4_to_scale(ob->object_to_world);
const float scalef = mat4_to_scale(ob->object_to_world);
gps_duplicate->thickness = ceilf((float)gps_duplicate->thickness * scalef);
CLAMP_MIN(gps_duplicate->thickness, 1.0f);
const bool is_normalized = ((params_.flag & GP_EXPORT_NORM_THICKNESS) != 0) ||
@ -308,7 +309,9 @@ void GpencilExporterSVG::export_stroke_to_polyline(bGPDlayer *gpl,
color_string_set(gpl, gps, node_gps, do_fill);
if (is_stroke && !do_fill) {
node_gps.append_attribute("stroke-width").set_value((radius * 2.0f) - gpl->line_change);
const float width = MAX2(
MAX2(gps->thickness + gpl->line_change, (radius * 2.0f) + gpl->line_change), 1.0f);
node_gps.append_attribute("stroke-width").set_value(width);
}
std::string txt;

View File

@ -634,6 +634,8 @@ typedef struct bNodeTree {
bool has_undefined_nodes_or_sockets() const;
/** Get the active group output node. */
const bNode *group_output_node() const;
/** Get all input nodes of the node group. */
blender::Span<const bNode *> group_input_nodes() const;
#endif
} bNodeTree;

View File

@ -135,7 +135,7 @@ set(SRC
../../blenlib/intern/BLI_mempool.c
../../blenlib/intern/endian_switch.c
../../blenlib/intern/hash_mm2a.c
../../blenlib/intern/listbase.c
../../blenlib/intern/listbase.cc
${SRC_DNA_DEFAULTS_INC}
)

View File

@ -1401,7 +1401,7 @@ static void attribute_search_update_fn(
}
}
else {
for (const bNode *node : nmd->node_group->nodes_by_type("NodeGroupInput")) {
for (const bNode *node : nmd->node_group->group_input_nodes()) {
for (const bNodeSocket *socket : node->output_sockets()) {
if (socket->type == SOCK_GEOMETRY) {
sockets_to_check.append(socket);

View File

@ -115,7 +115,7 @@ Vector<DOutputSocket> DInputSocket::get_corresponding_group_input_sockets() cons
BLI_assert(child_context != nullptr);
const bNodeTree &child_tree = child_context->btree();
Span<const bNode *> group_input_nodes = child_tree.nodes_by_type("NodeGroupInput");
Span<const bNode *> group_input_nodes = child_tree.group_input_nodes();
const int socket_index = bsocket_->index();
Vector<DOutputSocket> sockets;
for (const bNode *group_input_node : group_input_nodes) {

View File

@ -394,9 +394,10 @@ install(
if(WITH_PYTHON)
# install(CODE "message(\"copying blender scripts...\")")
# exclude addons_contrib if release
# exclude addons_contrib if release branch
if("${BLENDER_VERSION_CYCLE}" STREQUAL "release" OR
"${BLENDER_VERSION_CYCLE}" STREQUAL "rc")
"${BLENDER_VERSION_CYCLE}" STREQUAL "rc" OR
"${BLENDER_VERSION_CYCLE}" STREQUAL "beta")
set(ADDON_EXCLUDE_CONDITIONAL "addons_contrib/*")
else()
set(ADDON_EXCLUDE_CONDITIONAL "_addons_contrib/*") # Dummy, won't do anything.