Merge branch 'master' into blender2.8

This commit is contained in:
Sergey Sharybin 2017-09-18 15:54:56 +05:00
commit 4c1ee47707
Notes: blender-bot 2023-02-14 08:35:51 +01:00
Referenced by issue #52829, Eevee: Shadows not updated when moving lamp
7 changed files with 321 additions and 156 deletions

View File

@ -25,6 +25,9 @@ typedef struct VolumeState {
} VolumeState;
/* Get PathState ready for use for volume stack evaluation. */
# ifdef __SPLIT_KERNEL__
ccl_addr_space
# endif
ccl_device_inline PathState *shadow_blocked_volume_path_state(
KernelGlobals *kg,
VolumeState *volume_state,
@ -190,6 +193,9 @@ ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg,
int bounce = state->transparent_bounce;
Intersection *isect = hits;
# ifdef __VOLUME__
# ifdef __SPLIT_KERNEL__
ccl_addr_space
# endif
PathState *ps = shadow_blocked_volume_path_state(kg,
&volume_state,
state,
@ -240,6 +246,9 @@ ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg,
# ifdef __VOLUME__
if(!blocked && state->volume_stack[0].shader != SHADER_NONE) {
/* Apply attenuation from current volume shader. */
# ifdef __SPLIT_KERNEL__
ccl_addr_space
# endif
PathState *ps = shadow_blocked_volume_path_state(kg,
&volume_state,
state,
@ -335,6 +344,9 @@ ccl_device bool shadow_blocked_transparent_stepped_loop(
float3 Pend = ray->P + ray->D*ray->t;
int bounce = state->transparent_bounce;
# ifdef __VOLUME__
# ifdef __SPLIT_KERNEL__
ccl_addr_space
# endif
PathState *ps = shadow_blocked_volume_path_state(kg,
&volume_state,
state,
@ -389,6 +401,9 @@ ccl_device bool shadow_blocked_transparent_stepped_loop(
# ifdef __VOLUME__
if(!blocked && state->volume_stack[0].shader != SHADER_NONE) {
/* Apply attenuation from current volume shader. */
# ifdef __SPLIT_KERNEL__
ccl_addr_space
# endif
PathState *ps = shadow_blocked_volume_path_state(kg,
&volume_state,
state,

View File

@ -193,6 +193,17 @@ MINLINE int divide_round_i(int a, int b)
return (2 * a + b) / (2 * b);
}
/**
* Integer division that floors negative result.
* \note This works like Python's int division.
*/
MINLINE int divide_floor_i(int a, int b)
{
int d = a / b;
int r = a % b; /* Optimizes into a single division. */
return r ? d - ((a < 0) ^ (b < 0)) : d;
}
/**
* modulo that handles negative numbers, works the same as Python's.
*/

View File

@ -707,22 +707,40 @@ void BM_edgeloop_expand(
split_swap = !split_swap;
}
/* TODO, move to generic define? */
/**
* Even value distribution.
*
* \a src must be larger than \a dst,
* \a dst defines the number of iterations, their values are evenly spaced.
*
* The following pairs represent (src, dst) arguments and the values they loop over.
* <pre>
* (19, 4) -> [2, 7, 11. 16]
* (100, 5) -> [9, 29, 49, 69, 89]
* (100, 3) -> [16, 49, 83]
* (100, 100) -> [0..99]
* </pre>
* \note this is mainly useful for numbers that might not divide evenly into eachother.
*/
#define BLI_FOREACH_SPARSE_RANGE(src, dst, i) \
for (int _src = (src), _src2 = _src * 2, _dst2 = (dst) * 2, _error = _dst2 - _src, i = 0, _delta; \
((void)(_delta = divide_floor_i(_error, _dst2)), \
(void)(i -= _delta), \
(i < _src)); \
_error -= (_delta * _dst2) + _src2)
if (el_store->len < el_store_len) {
const int step = max_ii(1, el_store->len / (el_store->len % el_store_len));
LinkData *node_first = el_store->verts.first;
LinkData *node_curr = node_first;
LinkData *node_curr = el_store->verts.first;
do {
LinkData *node_curr_init = node_curr;
LinkData *node_curr_copy;
int i = 0;
BLI_LISTBASE_CIRCULAR_FORWARD_BEGIN (&el_store->verts, node_curr, node_curr_init) {
if (i++ < step) {
break;
}
int iter_prev = 0;
BLI_FOREACH_SPARSE_RANGE(el_store->len, (el_store_len - el_store->len), iter) {
while (iter_prev < iter) {
node_curr = node_curr->next;
iter_prev += 1;
}
BLI_LISTBASE_CIRCULAR_FORWARD_END (&el_store->verts, node_curr, node_curr_init);
LinkData *node_curr_copy;
node_curr_copy = MEM_dupallocN(node_curr);
if (split == false) {
BLI_insertlinkafter(&el_store->verts, node_curr, node_curr_copy);
@ -730,7 +748,8 @@ void BM_edgeloop_expand(
}
else {
if (node_curr->next || (el_store->flag & BM_EDGELOOP_IS_CLOSED)) {
EDGE_SPLIT(node_curr_copy, node_curr->next ? node_curr->next : (LinkData *)el_store->verts.first);
EDGE_SPLIT(node_curr_copy,
node_curr->next ? node_curr->next : (LinkData *)el_store->verts.first);
BLI_insertlinkafter(&el_store->verts, node_curr, node_curr_copy);
node_curr = node_curr_copy->next;
}
@ -742,9 +761,11 @@ void BM_edgeloop_expand(
split_swap = !split_swap;
}
el_store->len++;
} while (el_store->len < el_store_len);
iter_prev += 1;
}
}
#undef BKE_FOREACH_SUBSET_OF_RANGE
#undef EDGE_SPLIT
BLI_assert(el_store->len == el_store_len);

View File

@ -55,6 +55,12 @@ extern "C" {
namespace DEG {
enum {
COMPONENT_STATE_NONE = 0,
COMPONENT_STATE_SCHEDULED = 1,
COMPONENT_STATE_DONE = 2,
};
typedef std::deque<OperationDepsNode *> FlushQueue;
static void flush_init_func(void *data_v, int i)
@ -67,7 +73,7 @@ static void flush_init_func(void *data_v, int i)
ComponentDepsNode *comp_node = node->owner;
IDDepsNode *id_node = comp_node->owner;
id_node->done = 0;
comp_node->done = 0;
comp_node->done = COMPONENT_STATE_NONE;
node->scheduled = false;
}
@ -139,7 +145,7 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
lib_id_recalc_data_tag(bmain, id_orig);
}
if (comp_node->done == 0) {
if (comp_node->done == COMPONENT_STATE_DONE) {
#ifdef WITH_COPY_ON_WRITE
/* Currently this is needed to get ob->mesh to be replaced with
* original mesh (rather than being evaluated_mesh).
@ -210,9 +216,21 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
/* TODO : replace with more granular flags */
object->deg_update_flag |= DEG_RUNTIME_DATA_UPDATE;
}
/* When some target changes bone, we might need to re-run the
* whole IK solver, otherwise result might be unpredictable.
*/
if (comp_node->type == DEG_NODE_TYPE_BONE) {
ComponentDepsNode *pose_comp =
id_node->find_component(DEG_NODE_TYPE_EVAL_POSE);
BLI_assert(pose_comp != NULL);
if (pose_comp->done == COMPONENT_STATE_NONE) {
queue.push_front(pose_comp->get_entry_operation());
pose_comp->done = COMPONENT_STATE_SCHEDULED;
}
}
}
id_node->done = 1;
id_node->done = COMPONENT_STATE_DONE;
comp_node->done = 1;
/* Flush to nodes along links... */

View File

@ -2485,7 +2485,9 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
return false;
}
if (!ui_but_is_float(but)) value = (int)floor(value + 0.5);
if (!ui_but_is_float(but)) {
value = floor(value + 0.5);
}
/* not that we use hard limits here */
if (value < (double)but->hardmin) value = but->hardmin;

View File

@ -48,36 +48,24 @@
#define IMAGIC 0732
typedef struct {
unsigned short imagic; /* stuff saved on disk . . */
unsigned short type;
unsigned short dim;
unsigned short xsize;
unsigned short ysize;
unsigned short zsize;
unsigned int min;
unsigned int max;
unsigned int wastebytes;
char name[80];
unsigned int colormap;
int file; /* stuff used in core only */
unsigned short flags;
short dorev;
short x;
short y;
short z;
short cnt;
unsigned short *ptr;
unsigned short *base;
unsigned short *tmpbuf;
unsigned int offset;
unsigned int rleend; /* for rle images */
unsigned int *rowstart; /* for rle images */
const int *rowsize; /* for rle images */
ushort imagic; /* stuff saved on disk . . */
ushort type;
ushort dim;
ushort xsize;
ushort ysize;
ushort zsize;
uint min;
uint max;
uchar _pad1[4];
char name[80];
uint colormap;
uchar _pad2[404];
} IMAGE;
#define HEADER_SIZE 512
BLI_STATIC_ASSERT(sizeof(IMAGE) == HEADER_SIZE, "Invalid header size");
#define RINTLUM (79)
#define GINTLUM (156)
#define BINTLUM (21)
@ -106,68 +94,72 @@ typedef struct {
/* local struct for mem access */
typedef struct MFileOffset {
const uchar *_file_data;
unsigned int _file_offset;
uint _file_offset;
} MFileOffset;
#define MFILE_DATA(inf) ((void)0, (inf)->_file_data + (inf)->_file_offset)
#define MFILE_DATA(inf) ((void)0, ((inf)->_file_data + (inf)->_file_offset))
#define MFILE_STEP(inf, step) { (inf)->_file_offset += step; } ((void)0)
#define MFILE_SEEK(inf, pos) { (inf)->_file_offset = pos; } ((void)0)
/* error flags */
#define DIRTY_FLAG_EOF (1 << 0)
#define DIRTY_FLAG_ENCODING (1 << 1)
/* funcs */
static void readheader(MFileOffset *inf, IMAGE *image);
static int writeheader(FILE *outf, IMAGE *image);
static unsigned short getshort(MFileOffset *inf);
static unsigned int getlong(MFileOffset *inf);
static void putshort(FILE *outf, unsigned short val);
static int putlong(FILE *outf, unsigned int val);
static int writetab(FILE *outf, unsigned int *tab, int len);
static void readtab(MFileOffset *inf, unsigned int *tab, int len);
static ushort getshort(MFileOffset *inf);
static uint getlong(MFileOffset *inf);
static void putshort(FILE *outf, ushort val);
static int putlong(FILE *outf, uint val);
static int writetab(FILE *outf, uint *tab, int len);
static void readtab(MFileOffset *inf, uint *tab, int len);
static void expandrow(unsigned char *optr, const unsigned char *iptr, int z);
static void expandrow2(float *optr, const unsigned char *iptr, int z);
static void interleaverow(unsigned char *lptr, const unsigned char *cptr, int z, int n);
static void interleaverow2(float *lptr, const unsigned char *cptr, int z, int n);
static int compressrow(unsigned char *lbuf, unsigned char *rlebuf, int z, int cnt);
static void lumrow(unsigned char *rgbptr, unsigned char *lumptr, int n);
static int expandrow(uchar *optr, const uchar *optr_end, const uchar *iptr, const uchar *iptr_end, int z);
static int expandrow2(float *optr, const float *optr_end, const uchar *iptr, const uchar *iptr_end, int z);
static void interleaverow(uchar *lptr, const uchar *cptr, int z, int n);
static void interleaverow2(float *lptr, const uchar *cptr, int z, int n);
static int compressrow(uchar *lbuf, uchar *rlebuf, int z, int cnt);
static void lumrow(uchar *rgbptr, uchar *lumptr, int n);
/*
* byte order independent read/write of shorts and ints.
*
*/
static unsigned short getshort(MFileOffset *inf)
static ushort getshort(MFileOffset *inf)
{
const unsigned char *buf;
const uchar *buf;
buf = MFILE_DATA(inf);
MFILE_STEP(inf, 2);
return (buf[0] << 8) + (buf[1] << 0);
return ((ushort)buf[0] << 8) + ((ushort)buf[1] << 0);
}
static unsigned int getlong(MFileOffset *mofs)
static uint getlong(MFileOffset *mofs)
{
const unsigned char *buf;
const uchar *buf;
buf = MFILE_DATA(mofs);
MFILE_STEP(mofs, 4);
return (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + (buf[3] << 0);
return ((uint)buf[0] << 24) + ((uint)buf[1] << 16) + ((uint)buf[2] << 8) + ((uint)buf[3] << 0);
}
static void putshort(FILE *outf, unsigned short val)
static void putshort(FILE *outf, ushort val)
{
unsigned char buf[2];
uchar buf[2];
buf[0] = (val >> 8);
buf[1] = (val >> 0);
fwrite(buf, 2, 1, outf);
}
static int putlong(FILE *outf, unsigned int val)
static int putlong(FILE *outf, uint val)
{
unsigned char buf[4];
uchar buf[4];
buf[0] = (val >> 24);
buf[1] = (val >> 16);
@ -205,7 +197,7 @@ static int writeheader(FILE *outf, IMAGE *image)
return fwrite("no name", 8, 1, outf);
}
static int writetab(FILE *outf, unsigned int *tab, int len)
static int writetab(FILE *outf, uint *tab, int len)
{
int r = 0;
@ -216,7 +208,7 @@ static int writetab(FILE *outf, unsigned int *tab, int len)
return r;
}
static void readtab(MFileOffset *inf, unsigned int *tab, int len)
static void readtab(MFileOffset *inf, uint *tab, int len)
{
while (len) {
*tab++ = getlong(inf);
@ -242,12 +234,12 @@ static void test_endian_zbuf(struct ImBuf *ibuf)
}
/* from misc_util: flip the bytes from x */
#define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1])
#define GS(x) (((uchar *)(x))[0] << 8 | ((uchar *)(x))[1])
/* this one is only def-ed once, strangely... */
#define GSS(x) (((uchar *)(x))[1] << 8 | ((uchar *)(x))[0])
int imb_is_a_iris(const unsigned char *mem)
int imb_is_a_iris(const uchar *mem)
{
return ((GS(mem) == IMAGIC) || (GSS(mem) == IMAGIC));
}
@ -259,46 +251,52 @@ int imb_is_a_iris(const unsigned char *mem)
*
*/
struct ImBuf *imb_loadiris(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
{
unsigned int *base, *lptr = NULL;
uint *base, *lptr = NULL;
float *fbase, *fptr = NULL;
unsigned int *zbase, *zptr;
const unsigned char *rledat;
unsigned int *starttab, *lengthtab;
uint *zbase, *zptr;
const uchar *rledat;
const uchar *mem_end = mem + size;
MFileOffset _inf_data = {mem, 0}, *inf = &_inf_data;
IMAGE image;
int x, y, z, tablen;
int xsize, ysize, zsize;
int bpp, rle, cur, badorder;
ImBuf *ibuf;
uchar dirty_flag = 0;
(void)size; /* unused */
if (!imb_is_a_iris(mem)) return NULL;
if (size < HEADER_SIZE) {
return NULL;
}
if (!imb_is_a_iris(mem)) {
return NULL;
}
/* OCIO_TODO: only tested with 1 byte per pixel, not sure how to test with other settings */
colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
/*printf("new iris\n");*/
readheader(inf, &image);
if (image.imagic != IMAGIC) {
fprintf(stderr, "longimagedata: bad magic number in image file\n");
return(NULL);
}
rle = ISRLE(image.type);
bpp = BPP(image.type);
if (bpp != 1 && bpp != 2) {
fprintf(stderr, "longimagedata: image must have 1 or 2 byte per pix chan\n");
return(NULL);
}
xsize = image.xsize;
ysize = image.ysize;
zsize = image.zsize;
if ((uint)image.zsize > 8) {
fprintf(stderr, "longimagedata: channels over 8 not supported\n");
return(NULL);
}
const int xsize = image.xsize;
const int ysize = image.ysize;
const int zsize = image.zsize;
if (flags & IB_test) {
ibuf = IMB_allocImBuf(image.xsize, image.ysize, 8 * image.zsize, 0);
if (ibuf) ibuf->ftype = IMB_FTYPE_IMAGIC;
@ -306,12 +304,17 @@ struct ImBuf *imb_loadiris(const unsigned char *mem, size_t size, int flags, cha
}
if (rle) {
tablen = ysize * zsize * sizeof(int);
starttab = (unsigned int *)MEM_mallocN(tablen, "iris starttab");
lengthtab = (unsigned int *)MEM_mallocN(tablen, "iris endtab");
MFILE_SEEK(inf, HEADER_SIZE);
uint *starttab = MEM_mallocN(tablen, "iris starttab");
uint *lengthtab = MEM_mallocN(tablen, "iris endtab");
#define MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(p) \
if (UNLIKELY((p) > mem_end)) { dirty_flag |= DIRTY_FLAG_EOF; goto fail_rle; } ((void)0)
MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(MFILE_DATA(inf) + ((4 * 2) * tablen));
readtab(inf, starttab, tablen);
readtab(inf, lengthtab, tablen);
@ -335,7 +338,7 @@ struct ImBuf *imb_loadiris(const unsigned char *mem, size_t size, int flags, cha
ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect);
if (ibuf->planes > 32) ibuf->planes = 32;
base = ibuf->rect;
zbase = (unsigned int *)ibuf->zbuf;
zbase = (uint *)ibuf->zbuf;
if (badorder) {
for (z = 0; z < zsize; z++) {
@ -344,9 +347,11 @@ struct ImBuf *imb_loadiris(const unsigned char *mem, size_t size, int flags, cha
MFILE_SEEK(inf, starttab[y + z * ysize]);
rledat = MFILE_DATA(inf);
MFILE_STEP(inf, lengthtab[y + z * ysize]);
expandrow((uchar *)lptr, rledat, 3 - z);
lptr += xsize;
const uchar *rledat_next = MFILE_DATA(inf);
uint *lptr_next = lptr + xsize;
MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next);
dirty_flag |= expandrow((uchar *)lptr, (uchar *)lptr_next, rledat, rledat_next, 3 - z);
lptr = lptr_next;
}
}
}
@ -354,17 +359,25 @@ struct ImBuf *imb_loadiris(const unsigned char *mem, size_t size, int flags, cha
lptr = base;
zptr = zbase;
for (y = 0; y < ysize; y++) {
uint *lptr_next = lptr + xsize;
uint *zptr_next = zptr + xsize;
for (z = 0; z < zsize; z++) {
MFILE_SEEK(inf, starttab[y + z * ysize]);
rledat = MFILE_DATA(inf);
MFILE_STEP(inf, lengthtab[y + z * ysize]);
if (z < 4) expandrow((uchar *)lptr, rledat, 3 - z);
else if (z < 8) expandrow((uchar *)zptr, rledat, 7 - z);
const uchar *rledat_next = MFILE_DATA(inf);
MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next);
if (z < 4) {
dirty_flag |= expandrow((uchar *)lptr, (uchar *)lptr_next, rledat, rledat_next, 3 - z);
}
else if (z < 8) {
dirty_flag |= expandrow((uchar *)zptr, (uchar *)zptr_next, rledat, rledat_next, 7 - z);
}
}
lptr += xsize;
zptr += xsize;
lptr = lptr_next;
zptr = zptr_next;
}
}
@ -383,14 +396,17 @@ struct ImBuf *imb_loadiris(const unsigned char *mem, size_t size, int flags, cha
MFILE_SEEK(inf, starttab[y + z * ysize]);
rledat = MFILE_DATA(inf);
MFILE_STEP(inf, lengthtab[y + z * ysize]);
expandrow2(fptr, rledat, 3 - z);
fptr += xsize * 4;
const uchar *rledat_next = MFILE_DATA(inf);
MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next);
float *fptr_next = fptr + (xsize * 4);
dirty_flag |= expandrow2(fptr, fptr_next, rledat, rledat_next, 3 - z);
fptr = fptr_next;
}
}
}
else {
fptr = fbase;
float *fptr_next = fptr + (xsize * 4);
for (y = 0; y < ysize; y++) {
@ -398,27 +414,31 @@ struct ImBuf *imb_loadiris(const unsigned char *mem, size_t size, int flags, cha
MFILE_SEEK(inf, starttab[y + z * ysize]);
rledat = MFILE_DATA(inf);
MFILE_STEP(inf, lengthtab[y + z * ysize]);
expandrow2(fptr, rledat, 3 - z);
const uchar *rledat_next = MFILE_DATA(inf);
MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next);
dirty_flag |= expandrow2(fptr, fptr_next, rledat, rledat_next, 3 - z);
}
fptr += xsize * 4;
fptr = fptr_next;
}
}
}
#undef MFILE_CAPACITY_AT_PTR_OK_OR_FAIL
fail_rle:
MEM_freeN(starttab);
MEM_freeN(lengthtab);
}
else {
#define MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(p) \
if (UNLIKELY((p) > mem_end)) { dirty_flag |= DIRTY_FLAG_EOF; goto fail_uncompressed; } ((void)0)
if (bpp == 1) {
ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect);
if (ibuf->planes > 32) ibuf->planes = 32;
base = ibuf->rect;
zbase = (unsigned int *)ibuf->zbuf;
zbase = (uint *)ibuf->zbuf;
MFILE_SEEK(inf, HEADER_SIZE);
rledat = MFILE_DATA(inf);
@ -427,12 +447,13 @@ struct ImBuf *imb_loadiris(const unsigned char *mem, size_t size, int flags, cha
if (z < 4) lptr = base;
else if (z < 8) lptr = zbase;
for (y = 0; y < ysize; y++) {
interleaverow((uchar *)lptr, rledat, 3 - z, xsize);
rledat += xsize;
for (y = 0; y < ysize; y++) {
const uchar *rledat_next = rledat + xsize;
const int z_ofs = 3 - z;
MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next + z_ofs);
interleaverow((uchar *)lptr, rledat, z_ofs, xsize);
rledat = rledat_next;
lptr += xsize;
}
}
@ -450,20 +471,23 @@ struct ImBuf *imb_loadiris(const unsigned char *mem, size_t size, int flags, cha
for (z = 0; z < zsize; z++) {
fptr = fbase;
for (y = 0; y < ysize; y++) {
interleaverow2(fptr, rledat, 3 - z, xsize);
rledat += xsize * 2;
for (y = 0; y < ysize; y++) {
const uchar *rledat_next = rledat + xsize * 2;
const int z_ofs = 3 - z;
MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next + z_ofs);
interleaverow2(fptr, rledat, z_ofs, xsize);
rledat = rledat_next;
fptr += xsize * 4;
}
}
}
#undef MFILE_CAPACITY_AT_PTR_OK_OR_FAIL
fail_uncompressed:
(void)0;
}
if (bpp == 1) {
uchar *rect;
@ -528,6 +552,9 @@ struct ImBuf *imb_loadiris(const unsigned char *mem, size_t size, int flags, cha
}
if (dirty_flag) {
fprintf(stderr, "longimagedata: corrupt file content (%d)\n", dirty_flag);
}
ibuf->ftype = IMB_FTYPE_IMAGIC;
test_endian_zbuf(ibuf);
@ -541,7 +568,7 @@ struct ImBuf *imb_loadiris(const unsigned char *mem, size_t size, int flags, cha
/* static utility functions for longimagedata */
static void interleaverow(unsigned char *lptr, const unsigned char *cptr, int z, int n)
static void interleaverow(uchar *lptr, const uchar *cptr, int z, int n)
{
lptr += z;
while (n--) {
@ -550,7 +577,7 @@ static void interleaverow(unsigned char *lptr, const unsigned char *cptr, int z,
}
}
static void interleaverow2(float *lptr, const unsigned char *cptr, int z, int n)
static void interleaverow2(float *lptr, const uchar *cptr, int z, int n)
{
lptr += z;
while (n--) {
@ -560,19 +587,34 @@ static void interleaverow2(float *lptr, const unsigned char *cptr, int z, int n)
}
}
static void expandrow2(float *optr, const unsigned char *iptr, int z)
static int expandrow2(
float *optr, const float *optr_end,
const uchar *iptr, const uchar *iptr_end, int z)
{
unsigned short pixel, count;
ushort pixel, count;
float pixel_f;
#define EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next) \
if (UNLIKELY(iptr_next > iptr_end)) { goto fail; }
#define EXPAND_CAPACITY_AT_OUTPUT_OK_OR_FAIL(optr_next) \
if (UNLIKELY(optr_next > optr_end)) { goto fail; }
optr += z;
optr_end += z;
while (1) {
const uchar *iptr_next = iptr + 2;
EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next);
pixel = (iptr[0] << 8) | (iptr[1] << 0);
iptr += 2;
iptr = iptr_next;
if (!(count = (pixel & 0x7f)) )
return;
return false;
const float *optr_next = optr + count;
EXPAND_CAPACITY_AT_OUTPUT_OK_OR_FAIL(optr_next);
if (pixel & 0x80) {
iptr_next = iptr + (count * 2);
EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next);
while (count >= 8) {
optr[0 * 4] = ((iptr[0] << 8) | (iptr[1] << 0)) / (float)0xFFFF;
optr[1 * 4] = ((iptr[2] << 8) | (iptr[3] << 0)) / (float)0xFFFF;
@ -591,10 +633,13 @@ static void expandrow2(float *optr, const unsigned char *iptr, int z)
iptr += 2;
optr += 4;
}
BLI_assert(iptr == iptr_next);
}
else {
iptr_next = iptr + 2;
EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next);
pixel_f = ((iptr[0] << 8) | (iptr[1] << 0)) / (float)0xFFFF;
iptr += 2;
iptr = iptr_next;
while (count >= 8) {
optr[0 * 4] = pixel_f;
@ -612,20 +657,45 @@ static void expandrow2(float *optr, const unsigned char *iptr, int z)
*optr = pixel_f;
optr += 4;
}
BLI_assert(iptr == iptr_next);
}
BLI_assert(optr == optr_next);
}
return false;
#undef EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL
#undef EXPAND_CAPACITY_AT_OUTPUT_OK_OR_FAIL
fail:
return DIRTY_FLAG_ENCODING;
}
static void expandrow(unsigned char *optr, const unsigned char *iptr, int z)
static int expandrow(
uchar *optr, const uchar *optr_end,
const uchar *iptr, const uchar *iptr_end, int z)
{
unsigned char pixel, count;
uchar pixel, count;
#define EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next) \
if (UNLIKELY(iptr_next > iptr_end)) { goto fail; }
#define EXPAND_CAPACITY_AT_OUTPUT_OK_OR_FAIL(optr_next) \
if (UNLIKELY(optr_next > optr_end)) { goto fail; }
optr += z;
optr_end += z;
while (1) {
pixel = *iptr++;
const uchar *iptr_next = iptr + 1;
EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next);
pixel = *iptr;
iptr = iptr_next;
if (!(count = (pixel & 0x7f)) )
return;
return false;
const uchar *optr_next = optr + ((int)count * 4);
EXPAND_CAPACITY_AT_OUTPUT_OK_OR_FAIL(optr_next);
if (pixel & 0x80) {
iptr_next = iptr + count;
EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next);
while (count >= 8) {
optr[0 * 4] = iptr[0];
optr[1 * 4] = iptr[1];
@ -643,8 +713,11 @@ static void expandrow(unsigned char *optr, const unsigned char *iptr, int z)
*optr = *iptr++;
optr += 4;
}
BLI_assert(iptr == iptr_next);
}
else {
iptr_next = iptr + 1;
EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next);
pixel = *iptr++;
while (count >= 8) {
optr[0 * 4] = pixel;
@ -662,8 +735,17 @@ static void expandrow(unsigned char *optr, const unsigned char *iptr, int z)
*optr = pixel;
optr += 4;
}
BLI_assert(iptr == iptr_next);
}
BLI_assert(optr == optr_next);
}
return false;
#undef EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL
#undef EXPAND_CAPACITY_AT_OUTPUT_OK_OR_FAIL
fail:
return DIRTY_FLAG_ENCODING;
}
/*
@ -679,14 +761,14 @@ static void expandrow(unsigned char *optr, const unsigned char *iptr, int z)
* Added: zbuf write
*/
static int output_iris(unsigned int *lptr, int xsize, int ysize, int zsize, const char *name, int *zptr)
static int output_iris(uint *lptr, int xsize, int ysize, int zsize, const char *name, int *zptr)
{
FILE *outf;
IMAGE *image;
int tablen, y, z, pos, len = 0;
unsigned int *starttab, *lengthtab;
unsigned char *rlebuf;
unsigned int *lumbuf;
uint *starttab, *lengthtab;
uchar *rlebuf;
uint *lumbuf;
int rlebuflen, goodwrite;
goodwrite = 1;
@ -696,14 +778,14 @@ static int output_iris(unsigned int *lptr, int xsize, int ysize, int zsize, cons
tablen = ysize * zsize * sizeof(int);
image = (IMAGE *)MEM_mallocN(sizeof(IMAGE), "iris image");
starttab = (unsigned int *)MEM_mallocN(tablen, "iris starttab");
lengthtab = (unsigned int *)MEM_mallocN(tablen, "iris lengthtab");
starttab = (uint *)MEM_mallocN(tablen, "iris starttab");
lengthtab = (uint *)MEM_mallocN(tablen, "iris lengthtab");
rlebuflen = 1.05 * xsize + 10;
rlebuf = (unsigned char *)MEM_mallocN(rlebuflen, "iris rlebuf");
lumbuf = (unsigned int *)MEM_mallocN(xsize * sizeof(int), "iris lumbuf");
rlebuf = (uchar *)MEM_mallocN(rlebuflen, "iris rlebuf");
lumbuf = (uint *)MEM_mallocN(xsize * sizeof(int), "iris lumbuf");
memset(image, 0, sizeof(IMAGE));
image->imagic = IMB_FTYPE_IMAGIC;
image->imagic = IMAGIC;
image->type = RLE(1);
if (zsize > 1)
image->dim = 3;
@ -765,7 +847,7 @@ static int output_iris(unsigned int *lptr, int xsize, int ysize, int zsize, cons
/* static utility functions for output_iris */
static void lumrow(unsigned char *rgbptr, unsigned char *lumptr, int n)
static void lumrow(uchar *rgbptr, uchar *lumptr, int n)
{
lumptr += CHANOFFSET(0);
while (n--) {
@ -775,9 +857,9 @@ static void lumrow(unsigned char *rgbptr, unsigned char *lumptr, int n)
}
}
static int compressrow(unsigned char *lbuf, unsigned char *rlebuf, int z, int cnt)
static int compressrow(uchar *lbuf, uchar *rlebuf, int z, int cnt)
{
unsigned char *iptr, *ibufend, *sptr, *optr;
uchar *iptr, *ibufend, *sptr, *optr;
short todo, cc;
int count;
@ -830,7 +912,7 @@ static int compressrow(unsigned char *lbuf, unsigned char *rlebuf, int z, int cn
}
}
*optr++ = 0;
return optr - (unsigned char *)rlebuf;
return optr - (uchar *)rlebuf;
}
int imb_saveiris(struct ImBuf *ibuf, const char *name, int flags)

View File

@ -206,6 +206,8 @@ static DerivedMesh *applyModifier_bmesh(
result = get_quick_derivedMesh(ob, dm, bmd->object, dm_other, bmd->operation);
if (result == NULL) {
const bool is_flip = (is_negative_m4(ob->obmat) != is_negative_m4(bmd->object->obmat));
BMesh *bm;
const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_DM(dm, dm_other);
@ -217,6 +219,16 @@ static DerivedMesh *applyModifier_bmesh(
&((struct BMeshCreateParams){.use_toolflags = false,}));
DM_to_bmesh_ex(dm_other, bm, true);
if (UNLIKELY(is_flip)) {
const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
BMIter iter;
BMFace *efa;
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
BM_face_normal_flip_ex(bm, efa, cd_loop_mdisp_offset, true);
}
}
DM_to_bmesh_ex(dm, bm, true);
/* main bmesh intersection setup */
@ -244,7 +256,6 @@ static DerivedMesh *applyModifier_bmesh(
invert_m4_m4(imat, ob->obmat);
mul_m4_m4m4(omat, imat, bmd->object->obmat);
BMVert *eve;
i = 0;
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
@ -257,8 +268,13 @@ static DerivedMesh *applyModifier_bmesh(
/* we need face normals because of 'BM_face_split_edgenet'
* we could calculate on the fly too (before calling split). */
{
float nmat[4][4];
invert_m4_m4(nmat, omat);
float nmat[3][3];
copy_m3_m4(nmat, omat);
invert_m3(nmat);
if (UNLIKELY(is_flip)) {
negate_m3(nmat);
}
const short ob_src_totcol = bmd->object->totcol;
short *material_remap = BLI_array_alloca(material_remap, ob_src_totcol ? ob_src_totcol : 1);
@ -268,7 +284,7 @@ static DerivedMesh *applyModifier_bmesh(
BMFace *efa;
i = 0;
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
mul_transposed_mat3_m4_v3(nmat, efa->no);
mul_transposed_m3_v3(nmat, efa->no);
normalize_v3(efa->no);
BM_elem_flag_enable(efa, BM_FACE_TAG); /* temp tag to test which side split faces are from */