Merge branch 'master' into blender2.8
This commit is contained in:
@@ -240,7 +240,7 @@ void Device::draw_pixels(
|
||||
{
|
||||
const bool use_fallback_shader = (draw_params.bind_display_space_shader_cb == NULL);
|
||||
|
||||
assert(mem.type == MEM_PIXELS);
|
||||
assert(rgba.type == MEM_PIXELS);
|
||||
mem_copy_from(rgba, y, w, h, rgba.memory_elements_size(1));
|
||||
|
||||
GLuint texid;
|
||||
|
@@ -303,7 +303,7 @@ public:
|
||||
data_width = width;
|
||||
data_height = height;
|
||||
data_depth = depth;
|
||||
assert(device_ptr == 0);
|
||||
assert(device_pointer == 0);
|
||||
|
||||
return get_data();
|
||||
}
|
||||
@@ -331,7 +331,7 @@ public:
|
||||
data_width = width;
|
||||
data_height = height;
|
||||
data_depth = depth;
|
||||
assert(device_ptr == 0);
|
||||
assert(device_pointer == 0);
|
||||
|
||||
return get_data();
|
||||
}
|
||||
|
@@ -251,26 +251,36 @@ public:
|
||||
if(!tiles[i].buffers) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If the tile was rendered on another device, copy its memory to
|
||||
* to the current device now, for the duration of the denoising task.
|
||||
* Note that this temporarily modifies the RenderBuffers and calls
|
||||
* the device, so this function is not thread safe. */
|
||||
device_vector<float> &mem = tiles[i].buffers->buffer;
|
||||
if(mem.device != sub_device) {
|
||||
tiles[i].buffers->copy_from_device();
|
||||
/* Only copy from device to host once. This is faster, but
|
||||
* also required for the case where a CPU thread is denoising
|
||||
* a tile rendered on the GPU. In that case we have to avoid
|
||||
* overwriting the buffer being denoised by the CPU thread. */
|
||||
if(!tiles[i].buffers->map_neighbor_copied) {
|
||||
tiles[i].buffers->map_neighbor_copied = true;
|
||||
mem.copy_from_device(0, mem.data_size, 1);
|
||||
}
|
||||
|
||||
Device *original_device = mem.device;
|
||||
device_ptr original_ptr = mem.device_pointer;
|
||||
size_t original_size = mem.device_size;
|
||||
|
||||
mem.device = sub_device;
|
||||
mem.device_pointer = 0;
|
||||
mem.device_size = 0;
|
||||
|
||||
sub_device->mem_alloc(mem);
|
||||
sub_device->mem_copy_to(mem);
|
||||
mem.copy_to_device();
|
||||
tiles[i].buffer = mem.device_pointer;
|
||||
|
||||
mem.device = original_device;
|
||||
mem.device_pointer = original_ptr;
|
||||
mem.device_size = original_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -293,7 +303,7 @@ public:
|
||||
|
||||
/* Copy denoised tile to the host. */
|
||||
if(i == 4) {
|
||||
tiles[i].buffers->copy_from_device();
|
||||
mem.copy_from_device(0, mem.data_size, 1);
|
||||
}
|
||||
|
||||
sub_device->mem_free(mem);
|
||||
|
@@ -35,6 +35,25 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
class OpenCLSplitKernel;
|
||||
|
||||
namespace {
|
||||
|
||||
/* Copy dummy KernelGlobals related to OpenCL from kernel_globals.h to
|
||||
* fetch its size.
|
||||
*/
|
||||
typedef struct KernelGlobalsDummy {
|
||||
ccl_constant KernelData *data;
|
||||
ccl_global char *buffers[8];
|
||||
|
||||
#define KERNEL_TEX(type, name) \
|
||||
TextureInfo name;
|
||||
# include "kernel/kernel_textures.h"
|
||||
#undef KERNEL_TEX
|
||||
SplitData split_data;
|
||||
SplitParams split_param_data;
|
||||
} KernelGlobalsDummy;
|
||||
|
||||
} // namespace
|
||||
|
||||
static string get_build_options(OpenCLDeviceBase *device, const DeviceRequestedFeatures& requested_features)
|
||||
{
|
||||
string build_options = "-D__SPLIT_KERNEL__ ";
|
||||
@@ -110,24 +129,8 @@ public:
|
||||
else if(task->type == DeviceTask::RENDER) {
|
||||
RenderTile tile;
|
||||
|
||||
/* Copy dummy KernelGlobals related to OpenCL from kernel_globals.h to
|
||||
* fetch its size.
|
||||
*/
|
||||
typedef struct KernelGlobals {
|
||||
ccl_constant KernelData *data;
|
||||
ccl_global char *buffers[8];
|
||||
|
||||
#define KERNEL_TEX(type, name) \
|
||||
TextureInfo name;
|
||||
#include "kernel/kernel_textures.h"
|
||||
#undef KERNEL_TEX
|
||||
|
||||
SplitData split_data;
|
||||
SplitParams split_param_data;
|
||||
} KernelGlobals;
|
||||
|
||||
/* Allocate buffer for kernel globals */
|
||||
device_only_memory<KernelGlobals> kgbuffer(this, "kernel_globals");
|
||||
device_only_memory<KernelGlobalsDummy> kgbuffer(this, "kernel_globals");
|
||||
kgbuffer.alloc_to_device(1);
|
||||
|
||||
/* Keep rendering tiles until done. */
|
||||
|
@@ -115,7 +115,8 @@ RenderTile::RenderTile()
|
||||
/* Render Buffers */
|
||||
|
||||
RenderBuffers::RenderBuffers(Device *device)
|
||||
: buffer(device, "RenderBuffers", MEM_READ_WRITE)
|
||||
: buffer(device, "RenderBuffers", MEM_READ_WRITE),
|
||||
map_neighbor_copied(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -74,6 +74,7 @@ public:
|
||||
|
||||
/* float buffer */
|
||||
device_vector<float> buffer;
|
||||
bool map_neighbor_copied;
|
||||
|
||||
explicit RenderBuffers(Device *device);
|
||||
~RenderBuffers();
|
||||
|
@@ -22,12 +22,17 @@ set(INC
|
||||
)
|
||||
|
||||
set(ALL_CYCLES_LIBRARIES
|
||||
cycles_render
|
||||
cycles_device
|
||||
cycles_kernel
|
||||
cycles_render
|
||||
cycles_bvh
|
||||
cycles_graph
|
||||
cycles_subd
|
||||
cycles_util
|
||||
extern_clew
|
||||
${BLENDER_GL_LIBRARIES}
|
||||
${BLENDER_GLEW_LIBRARIES}
|
||||
${CYCLES_APP_GLEW_LIBRARY}
|
||||
${OPENIMAGEIO_LIBRARIES}
|
||||
)
|
||||
if(WITH_CYCLES_OSL)
|
||||
@@ -52,6 +57,15 @@ if(WITH_CYCLES_OPENSUBDIV)
|
||||
${OPENSUBDIV_LIBRARIES}
|
||||
)
|
||||
endif()
|
||||
if(WITH_CUDA_DYNLOAD)
|
||||
list(APPEND ALL_CYCLES_LIBRARIES extern_cuew)
|
||||
else()
|
||||
list(APPEND ALL_CYCLES_LIBRARIES ${CUDA_CUDA_LIBRARY})
|
||||
endif()
|
||||
if(NOT CYCLES_STANDALONE_REPOSITORY)
|
||||
list(APPEND ALL_CYCLES_LIBRARIES bf_intern_glew_mx bf_intern_guardedalloc ${GLEW_LIBRARY})
|
||||
endif()
|
||||
|
||||
list(APPEND ALL_CYCLES_LIBRARIES
|
||||
${BOOST_LIBRARIES}
|
||||
${PNG_LIBRARIES}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -341,9 +341,9 @@ enum {
|
||||
/* spare tag, assumed dirty, use define in each function to name based on use */
|
||||
// _BM_ELEM_TAG_ALT = (1 << 6), // UNUSED
|
||||
/**
|
||||
* for low level internal API tagging,
|
||||
* since tools may want to tag verts and
|
||||
* not have functions clobber them */
|
||||
* For low level internal API tagging,
|
||||
* since tools may want to tag verts and not have functions clobber them.
|
||||
* Leave cleared! */
|
||||
BM_ELEM_INTERNAL_TAG = (1 << 7),
|
||||
};
|
||||
|
||||
|
@@ -2090,25 +2090,33 @@ BMFace *bmesh_kernel_join_face_kill_edge(BMesh *bm, BMFace *f1, BMFace *f2, BMEd
|
||||
}
|
||||
|
||||
/* validate no internal join */
|
||||
for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f1); i < f1len; i++, l_iter = l_iter->next) {
|
||||
BM_elem_flag_disable(l_iter->v, BM_ELEM_INTERNAL_TAG);
|
||||
}
|
||||
for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f2); i < f2len; i++, l_iter = l_iter->next) {
|
||||
BM_elem_flag_disable(l_iter->v, BM_ELEM_INTERNAL_TAG);
|
||||
}
|
||||
{
|
||||
bool is_dupe = false;
|
||||
|
||||
for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f1); i < f1len; i++, l_iter = l_iter->next) {
|
||||
if (l_iter != l_f1) {
|
||||
BM_elem_flag_enable(l_iter->v, BM_ELEM_INTERNAL_TAG);
|
||||
/* TODO: skip clearing once this is ensured. */
|
||||
for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f2); i < f2len; i++, l_iter = l_iter->next) {
|
||||
BM_elem_flag_disable(l_iter->v, BM_ELEM_INTERNAL_TAG);
|
||||
}
|
||||
}
|
||||
for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f2); i < f2len; i++, l_iter = l_iter->next) {
|
||||
if (l_iter != l_f2) {
|
||||
/* as soon as a duplicate is found, bail out */
|
||||
if (BM_elem_flag_test(l_iter->v, BM_ELEM_INTERNAL_TAG)) {
|
||||
return NULL;
|
||||
|
||||
for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f1); i < f1len; i++, l_iter = l_iter->next) {
|
||||
BM_elem_flag_set(l_iter->v, BM_ELEM_INTERNAL_TAG, l_iter != l_f1);
|
||||
}
|
||||
for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f2); i < f2len; i++, l_iter = l_iter->next) {
|
||||
if (l_iter != l_f2) {
|
||||
/* as soon as a duplicate is found, bail out */
|
||||
if (BM_elem_flag_test(l_iter->v, BM_ELEM_INTERNAL_TAG)) {
|
||||
is_dupe = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Cleanup tags. */
|
||||
for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f1); i < f1len; i++, l_iter = l_iter->next) {
|
||||
BM_elem_flag_disable(l_iter->v, BM_ELEM_INTERNAL_TAG);
|
||||
}
|
||||
if (is_dupe) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* join the two loop */
|
||||
|
@@ -33,6 +33,7 @@
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_mempool.h"
|
||||
#include "BLI_utildefines_iter.h"
|
||||
#include "BLI_stack.h"
|
||||
|
||||
#include "bmesh.h"
|
||||
|
||||
@@ -141,28 +142,36 @@ int BM_mesh_edgeloops_find(
|
||||
}
|
||||
|
||||
/* first flush edges to tags, and tag verts */
|
||||
BLI_Stack *edge_stack = BLI_stack_new(sizeof(BMEdge *), __func__);
|
||||
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
|
||||
BLI_assert(!BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG));
|
||||
if (test_fn(e, user_data)) {
|
||||
BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG);
|
||||
BM_elem_flag_enable(e->v1, BM_ELEM_INTERNAL_TAG);
|
||||
BM_elem_flag_enable(e->v2, BM_ELEM_INTERNAL_TAG);
|
||||
BLI_stack_push(edge_stack, (void *)&e);
|
||||
}
|
||||
else {
|
||||
BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
|
||||
}
|
||||
}
|
||||
|
||||
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
|
||||
const uint edges_len = BLI_stack_count(edge_stack);
|
||||
BMEdge **edges = MEM_mallocN(sizeof(*edges) * edges_len, __func__);
|
||||
BLI_stack_pop_n_reverse(edge_stack, edges, BLI_stack_count(edge_stack));
|
||||
BLI_stack_free(edge_stack);
|
||||
|
||||
for (uint i = 0; i < edges_len; i += 1) {
|
||||
e = edges[i];
|
||||
if (BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG)) {
|
||||
BMEdgeLoopStore *el_store = MEM_callocN(sizeof(BMEdgeLoopStore), __func__);
|
||||
|
||||
/* add both directions */
|
||||
if (bm_loop_build(el_store, e->v1, e->v2, 1) &&
|
||||
bm_loop_build(el_store, e->v2, e->v1, -1) &&
|
||||
el_store->len > 1)
|
||||
bm_loop_build(el_store, e->v2, e->v1, -1) &&
|
||||
el_store->len > 1)
|
||||
{
|
||||
BLI_addtail(r_eloops, el_store);
|
||||
BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
|
||||
count++;
|
||||
}
|
||||
else {
|
||||
@@ -170,6 +179,15 @@ int BM_mesh_edgeloops_find(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint i = 0; i < edges_len; i += 1) {
|
||||
e = edges[i];
|
||||
BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
|
||||
BM_elem_flag_disable(e->v1, BM_ELEM_INTERNAL_TAG);
|
||||
BM_elem_flag_disable(e->v2, BM_ELEM_INTERNAL_TAG);
|
||||
}
|
||||
|
||||
MEM_freeN(edges);
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -267,6 +285,7 @@ bool BM_mesh_edgeloops_find_path(
|
||||
{
|
||||
BMIter iter;
|
||||
BMEdge *e;
|
||||
bool found = false;
|
||||
|
||||
BLI_assert(v_src != v_dst);
|
||||
|
||||
@@ -274,28 +293,43 @@ bool BM_mesh_edgeloops_find_path(
|
||||
BMVert *v;
|
||||
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
BM_elem_index_set(v, 0);
|
||||
BM_elem_flag_disable(v, BM_ELEM_INTERNAL_TAG);
|
||||
}
|
||||
}
|
||||
bm->elem_index_dirty |= BM_VERT;
|
||||
|
||||
/* first flush edges to tags, and tag verts */
|
||||
int edges_len;
|
||||
BMEdge **edges;
|
||||
|
||||
if (test_fn) {
|
||||
BLI_Stack *edge_stack = BLI_stack_new(sizeof(BMEdge *), __func__);
|
||||
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
|
||||
if (test_fn(e, user_data)) {
|
||||
BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG);
|
||||
BM_elem_flag_enable(e->v1, BM_ELEM_INTERNAL_TAG);
|
||||
BM_elem_flag_enable(e->v2, BM_ELEM_INTERNAL_TAG);
|
||||
BLI_stack_push(edge_stack, (void *)&e);
|
||||
}
|
||||
else {
|
||||
BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
|
||||
}
|
||||
}
|
||||
edges_len = BLI_stack_count(edge_stack);
|
||||
edges = MEM_mallocN(sizeof(*edges) * edges_len, __func__);
|
||||
BLI_stack_pop_n_reverse(edge_stack, edges, BLI_stack_count(edge_stack));
|
||||
BLI_stack_free(edge_stack);
|
||||
}
|
||||
else {
|
||||
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
|
||||
int i = 0;
|
||||
edges_len = bm->totedge;
|
||||
edges = MEM_mallocN(sizeof(*edges) * edges_len, __func__);
|
||||
|
||||
BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
|
||||
BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG);
|
||||
BM_elem_flag_enable(e->v1, BM_ELEM_INTERNAL_TAG);
|
||||
BM_elem_flag_enable(e->v2, BM_ELEM_INTERNAL_TAG);
|
||||
edges[i] = e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,11 +388,19 @@ bool BM_mesh_edgeloops_find_path(
|
||||
|
||||
BLI_addtail(r_eloops, el_store);
|
||||
|
||||
return true;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
for (uint i = 0; i < edges_len; i += 1) {
|
||||
e = edges[i];
|
||||
BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
|
||||
BM_elem_flag_disable(e->v1, BM_ELEM_INTERNAL_TAG);
|
||||
BM_elem_flag_disable(e->v2, BM_ELEM_INTERNAL_TAG);
|
||||
}
|
||||
MEM_freeN(edges);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
@@ -753,19 +795,29 @@ bool BM_edgeloop_overlap_check(struct BMEdgeLoopStore *el_store_a, struct BMEdge
|
||||
{
|
||||
LinkData *node;
|
||||
|
||||
/* init */
|
||||
for (node = el_store_a->verts.first; node; node = node->next) {
|
||||
BM_elem_flag_disable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG);
|
||||
}
|
||||
for (node = el_store_b->verts.first; node; node = node->next) {
|
||||
BM_elem_flag_enable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG);
|
||||
/* A little more efficient if 'a' as smaller. */
|
||||
if (el_store_a->len > el_store_b->len) {
|
||||
SWAP(BMEdgeLoopStore *, el_store_a, el_store_b);
|
||||
}
|
||||
|
||||
/* check 'a' */
|
||||
/* init */
|
||||
for (node = el_store_a->verts.first; node; node = node->next) {
|
||||
if (BM_elem_flag_test((BMVert *)node->data, BM_ELEM_INTERNAL_TAG)) {
|
||||
BM_elem_flag_enable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG);
|
||||
}
|
||||
for (node = el_store_b->verts.first; node; node = node->next) {
|
||||
BM_elem_flag_disable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG);
|
||||
}
|
||||
|
||||
/* Check 'a' (clear as we go). */
|
||||
for (node = el_store_a->verts.first; node; node = node->next) {
|
||||
if (!BM_elem_flag_test((BMVert *)node->data, BM_ELEM_INTERNAL_TAG)) {
|
||||
/* Finish clearing 'a', leave tag clean. */
|
||||
while ((node = node->next)) {
|
||||
BM_elem_flag_disable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
BM_elem_flag_disable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@@ -957,7 +957,7 @@ static void bm_loop_walk_add(struct LoopWalkCtx *lwc, BMLoop *l)
|
||||
{
|
||||
const int i = BM_elem_index_get(l);
|
||||
const float w = lwc->loop_weights[i];
|
||||
BM_elem_flag_enable(l, BM_ELEM_INTERNAL_TAG);
|
||||
BM_elem_flag_disable(l, BM_ELEM_INTERNAL_TAG);
|
||||
lwc->data_array[lwc->data_len] = BM_ELEM_CD_GET_VOID_P(l, lwc->cd_layer_offset);
|
||||
lwc->data_index_array[lwc->data_len] = i;
|
||||
lwc->weight_array[lwc->data_len] = w;
|
||||
@@ -976,7 +976,7 @@ static void bm_loop_walk_data(struct LoopWalkCtx *lwc, BMLoop *l_walk)
|
||||
int i;
|
||||
|
||||
BLI_assert(CustomData_data_equals(lwc->type, lwc->data_ref, BM_ELEM_CD_GET_VOID_P(l_walk, lwc->cd_layer_offset)));
|
||||
BLI_assert(BM_elem_flag_test(l_walk, BM_ELEM_INTERNAL_TAG) == false);
|
||||
BLI_assert(BM_elem_flag_test(l_walk, BM_ELEM_INTERNAL_TAG));
|
||||
|
||||
bm_loop_walk_add(lwc, l_walk);
|
||||
|
||||
@@ -988,7 +988,7 @@ static void bm_loop_walk_data(struct LoopWalkCtx *lwc, BMLoop *l_walk)
|
||||
l_other = l_other->next;
|
||||
}
|
||||
BLI_assert(l_other->v == l_walk->v);
|
||||
if (!BM_elem_flag_test(l_other, BM_ELEM_INTERNAL_TAG)) {
|
||||
if (BM_elem_flag_test(l_other, BM_ELEM_INTERNAL_TAG)) {
|
||||
if (CustomData_data_equals(lwc->type, lwc->data_ref, BM_ELEM_CD_GET_VOID_P(l_other, lwc->cd_layer_offset))) {
|
||||
bm_loop_walk_data(lwc, l_other);
|
||||
}
|
||||
@@ -1012,9 +1012,10 @@ LinkNode *BM_vert_loop_groups_data_layer_create(
|
||||
lwc.loop_weights = loop_weights;
|
||||
lwc.arena = arena;
|
||||
|
||||
/* Enable 'BM_ELEM_INTERNAL_TAG', leaving the flag clean on completion. */
|
||||
loop_num = 0;
|
||||
BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
|
||||
BM_elem_flag_disable(l, BM_ELEM_INTERNAL_TAG);
|
||||
BM_elem_flag_enable(l, BM_ELEM_INTERNAL_TAG);
|
||||
BM_elem_index_set(l, loop_num); /* set_dirty! */
|
||||
loop_num++;
|
||||
}
|
||||
@@ -1026,7 +1027,7 @@ LinkNode *BM_vert_loop_groups_data_layer_create(
|
||||
lwc.weight_array = BLI_memarena_alloc(lwc.arena, sizeof(float) * loop_num);
|
||||
|
||||
BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
|
||||
if (!BM_elem_flag_test(l, BM_ELEM_INTERNAL_TAG)) {
|
||||
if (BM_elem_flag_test(l, BM_ELEM_INTERNAL_TAG)) {
|
||||
struct LoopGroupCD *lf = BLI_memarena_alloc(lwc.arena, sizeof(*lf));
|
||||
int len_prev = lwc.data_len;
|
||||
|
||||
|
@@ -1236,6 +1236,8 @@ bool BM_face_split_edgenet_connect_islands(
|
||||
BMLoop *l_iter, *l_first;
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
do {
|
||||
BLI_assert(!BM_elem_flag_test(l_iter->v, VERT_NOT_IN_STACK));
|
||||
BLI_assert(!BM_elem_flag_test(l_iter->e, EDGE_NOT_IN_STACK));
|
||||
edge_arr[i++] = l_iter->e;
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
BLI_assert(i == edge_arr_len);
|
||||
|
@@ -2108,7 +2108,8 @@ bool BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len)
|
||||
|
||||
if (tot_tag == 0) {
|
||||
/* no faces use only boundary verts, quit early */
|
||||
return false;
|
||||
ok = false;
|
||||
goto finally;
|
||||
}
|
||||
|
||||
/* 2) loop over non-boundary edges that use boundary verts,
|
||||
@@ -2143,6 +2144,12 @@ bool BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len)
|
||||
}
|
||||
}
|
||||
|
||||
finally:
|
||||
/* Cleanup */
|
||||
for (i = 0; i < len; i++) {
|
||||
BM_elem_flag_disable(varr[i], BM_ELEM_INTERNAL_TAG);
|
||||
BM_elem_flag_disable(earr[i], BM_ELEM_INTERNAL_TAG);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@@ -50,5 +50,5 @@ void bmo_split_edges_exec(BMesh *bm, BMOperator *op)
|
||||
/* this is where everything happens */
|
||||
BM_mesh_edgesplit(bm, use_verts, true, false);
|
||||
|
||||
BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_INTERNAL_TAG);
|
||||
BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_TAG);
|
||||
}
|
||||
|
@@ -1085,6 +1085,8 @@ typedef struct tNearestVertInfo {
|
||||
int dist; /* distance from mouse to vert */
|
||||
|
||||
eAnim_ChannelType ctype; /* type of animation channel this FCurve comes from */
|
||||
|
||||
float frame; /* frame that point was on when it matched (global time) */
|
||||
} tNearestVertInfo;
|
||||
|
||||
/* Tags for the type of graph vert that we have */
|
||||
@@ -1151,6 +1153,8 @@ static void nearest_fcurve_vert_store(
|
||||
nvi->hpoint = hpoint;
|
||||
nvi->dist = dist;
|
||||
|
||||
nvi->frame = bezt->vec[1][0]; /* currently in global time... */
|
||||
|
||||
nvi->sel = BEZT_ISSEL_ANY(bezt); // XXX... should this use the individual verts instead?
|
||||
|
||||
/* add to list of matches if appropriate... */
|
||||
@@ -1435,10 +1439,7 @@ static void graphkeys_mselect_column(bAnimContext *ac, const int mval[2], short
|
||||
|
||||
/* get frame number on which elements should be selected */
|
||||
// TODO: should we restrict to integer frames only?
|
||||
if (nvi->bezt)
|
||||
selx = nvi->bezt->vec[1][0];
|
||||
else if (nvi->fpt)
|
||||
selx = nvi->fpt->vec[0];
|
||||
selx = nvi->frame;
|
||||
|
||||
/* if select mode is replace, deselect all keyframes first */
|
||||
if (select_mode == SELECT_REPLACE) {
|
||||
|
@@ -3872,7 +3872,7 @@ void *BPy_BMElem_PySeq_As_Array_FAST(
|
||||
BMesh *bm = (r_bm && *r_bm) ? *r_bm : NULL;
|
||||
PyObject **seq_fast_items = PySequence_Fast_ITEMS(seq_fast);
|
||||
const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast);
|
||||
Py_ssize_t i;
|
||||
Py_ssize_t i, i_last_dirty = PY_SSIZE_T_MAX;
|
||||
|
||||
BPy_BMElem *item;
|
||||
BMElem **alloc;
|
||||
@@ -3921,6 +3921,7 @@ void *BPy_BMElem_PySeq_As_Array_FAST(
|
||||
|
||||
if (do_unique_check) {
|
||||
BM_elem_flag_enable(item->ele, BM_ELEM_INTERNAL_TAG);
|
||||
i_last_dirty = i;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3937,6 +3938,8 @@ void *BPy_BMElem_PySeq_As_Array_FAST(
|
||||
}
|
||||
|
||||
if (ok == false) {
|
||||
/* Cleared above. */
|
||||
i_last_dirty = PY_SSIZE_T_MAX;
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"%s: found the same %.200s used multiple times",
|
||||
error_prefix, BPy_BMElem_StringFromHType(htype));
|
||||
@@ -3949,6 +3952,11 @@ void *BPy_BMElem_PySeq_As_Array_FAST(
|
||||
return alloc;
|
||||
|
||||
err_cleanup:
|
||||
if (do_unique_check && (i_last_dirty != PY_SSIZE_T_MAX)) {
|
||||
for (i = 0; i <= i_last_dirty; i++) {
|
||||
BM_elem_flag_disable(alloc[i], BM_ELEM_INTERNAL_TAG);
|
||||
}
|
||||
}
|
||||
PyMem_FREE(alloc);
|
||||
return NULL;
|
||||
|
||||
|
Reference in New Issue
Block a user