Merged changes in the trunk up to revision 53584.
Conflicts resolved: release/scripts/startup/bl_ui/properties_render.py source/blender/blenloader/intern/readfile.c source/blender/editors/interface/interface_templates.c source/blender/makesrna/RNA_enum_types.h Also made additional code updates for: r53355 UIList - Python-extendable list of UI items r53460 Alpha premul pipeline cleanup
This commit is contained in:
@@ -61,6 +61,7 @@ struct Scene;
|
||||
#define RE_ENGINE_DO_DRAW 4
|
||||
#define RE_ENGINE_DO_UPDATE 8
|
||||
#define RE_ENGINE_RENDERING 16
|
||||
#define RE_ENGINE_HIGHLIGHT_TILES 32
|
||||
|
||||
extern ListBase R_engines;
|
||||
|
||||
@@ -130,5 +131,7 @@ void RE_engines_exit(void);
|
||||
|
||||
RenderEngineType *RE_engines_find(const char *idname);
|
||||
|
||||
void RE_engine_get_current_tiles(struct Render *re, int *total_tiles_r, rcti **tiles_r);
|
||||
|
||||
#endif /* __RE_ENGINE_H__ */
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ void render_result_rect_from_ibuf(struct RenderResult *rr, struct RenderData *rd
|
||||
struct ImBuf *ibuf);
|
||||
|
||||
void render_result_rect_fill_zero(struct RenderResult *rr);
|
||||
void render_result_rect_get_pixels(struct RenderResult *rr, struct RenderData *rd,
|
||||
void render_result_rect_get_pixels(struct RenderResult *rr,
|
||||
unsigned int *rect, int rectx, int recty,
|
||||
const struct ColorManagedViewSettings *view_settings,
|
||||
const struct ColorManagedDisplaySettings *display_settings);
|
||||
|
||||
@@ -104,13 +104,19 @@ typedef struct RenderPart {
|
||||
|
||||
rcti disprect; /* part coordinates within total picture */
|
||||
int rectx, recty; /* the size */
|
||||
short crop, ready; /* crop is amount of pixels we crop, for filter */
|
||||
short crop, status; /* crop is amount of pixels we crop, for filter */
|
||||
short sample, nr; /* sample can be used by zbuffers, nr is partnr */
|
||||
short thread; /* thread id */
|
||||
|
||||
char *clipflag; /* clipflags for part zbuffering */
|
||||
} RenderPart;
|
||||
|
||||
enum {
|
||||
PART_STATUS_NONE = 0,
|
||||
PART_STATUS_IN_PROGRESS = 1,
|
||||
PART_STATUS_READY = 2
|
||||
};
|
||||
|
||||
/* controls state of render, everything that's read-only during render stage */
|
||||
struct Render
|
||||
{
|
||||
|
||||
@@ -59,12 +59,16 @@ typedef struct VertTableNode {
|
||||
float *tangent;
|
||||
float *stress;
|
||||
float *winspeed;
|
||||
/* Index of vertex in source mesh (before modifiers). */
|
||||
int *origindex;
|
||||
} VertTableNode;
|
||||
|
||||
typedef struct VlakTableNode {
|
||||
struct VlakRen *vlak;
|
||||
struct MTFace *mtface;
|
||||
struct MCol *mcol;
|
||||
/* Index of mpoly in source mesh (before tessellation). */
|
||||
int *origindex;
|
||||
int totmtface, totmcol;
|
||||
float *surfnor;
|
||||
float *tangent;
|
||||
@@ -114,9 +118,11 @@ float *RE_vertren_get_rad(struct ObjectRen *obr, struct VertRen *ver, int verify
|
||||
float *RE_vertren_get_strand(struct ObjectRen *obr, struct VertRen *ver, int verify);
|
||||
float *RE_vertren_get_tangent(struct ObjectRen *obr, struct VertRen *ver, int verify);
|
||||
float *RE_vertren_get_winspeed(struct ObjectInstanceRen *obi, struct VertRen *ver, int verify);
|
||||
int *RE_vertren_get_origindex(struct ObjectRen *obr, VertRen *ver, int verify);
|
||||
|
||||
struct MTFace *RE_vlakren_get_tface(struct ObjectRen *obr, VlakRen *ren, int n, char **name, int verify);
|
||||
struct MCol *RE_vlakren_get_mcol(struct ObjectRen *obr, VlakRen *ren, int n, char **name, int verify);
|
||||
int *RE_vlakren_get_origindex(struct ObjectRen *obr, VlakRen *vlak, int verify);
|
||||
float *RE_vlakren_get_surfnor(struct ObjectRen *obr, VlakRen *ren, int verify);
|
||||
float *RE_vlakren_get_nmap_tangent(struct ObjectRen *obr, VlakRen *ren, int verify);
|
||||
RadFace **RE_vlakren_get_radface(struct ObjectRen *obr, VlakRen *ren, int verify);
|
||||
|
||||
@@ -173,13 +173,13 @@ static int RE_rayobject_instance_intersect(RayObject *o, Isect *isec)
|
||||
|
||||
static void RE_rayobject_instance_free(RayObject *o)
|
||||
{
|
||||
InstanceRayObject *obj = (InstanceRayObject*)o;
|
||||
InstanceRayObject *obj = (InstanceRayObject *)o;
|
||||
MEM_freeN(obj);
|
||||
}
|
||||
|
||||
static float RE_rayobject_instance_cost(RayObject *o)
|
||||
{
|
||||
InstanceRayObject *obj = (InstanceRayObject*)o;
|
||||
InstanceRayObject *obj = (InstanceRayObject *)o;
|
||||
return RE_rayobject_cost(obj->target) + RE_COST_INSTANCE;
|
||||
}
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ static HaloRen *initstar(Render *re, ObjectRen *obr, const float vec[3], float h
|
||||
*/
|
||||
|
||||
void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void),
|
||||
void (*vertexfunc)(float*), void (*termfunc)(void))
|
||||
void (*vertexfunc)(float *), void (*termfunc)(void))
|
||||
{
|
||||
extern unsigned char hash[512];
|
||||
ObjectRen *obr= NULL;
|
||||
@@ -3258,7 +3258,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
|
||||
CustomDataMask mask;
|
||||
float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3],
|
||||
float *orco=0;
|
||||
int need_orco=0, need_stress=0, need_nmap_tangent=0, need_tangent=0;
|
||||
int need_orco=0, need_stress=0, need_nmap_tangent=0, need_tangent=0, need_origindex=0;
|
||||
int a, a1, ok, vertofs;
|
||||
int end, do_autosmooth = FALSE, totvert = 0;
|
||||
int use_original_normals = FALSE;
|
||||
@@ -3308,6 +3308,10 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
|
||||
need_nmap_tangent= 1;
|
||||
}
|
||||
|
||||
/* origindex currently only used when baking to vertex colors */
|
||||
if(re->flag & R_BAKING && re->r.bake_flag & R_BAKE_VCOL)
|
||||
need_origindex= 1;
|
||||
|
||||
/* check autosmooth and displacement, we then have to skip only-verts optimize */
|
||||
do_autosmooth |= (me->flag & ME_AUTOSMOOTH);
|
||||
if (do_autosmooth)
|
||||
@@ -3345,6 +3349,15 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
|
||||
make_render_halos(re, obr, me, totvert, mvert, ma, orco);
|
||||
}
|
||||
else {
|
||||
const int *index_vert_orig = NULL;
|
||||
const int *index_mf_to_mpoly = NULL;
|
||||
const int *index_mp_to_orig = NULL;
|
||||
if (need_origindex) {
|
||||
index_vert_orig = dm->getVertDataArray(dm, CD_ORIGINDEX);
|
||||
/* double lookup for faces -> polys */
|
||||
index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
|
||||
index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
|
||||
}
|
||||
|
||||
for (a=0; a<totvert; a++, mvert++) {
|
||||
ver= RE_findOrAddVert(obr, obr->totvert++);
|
||||
@@ -3361,6 +3374,18 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
|
||||
ver->orco= orco;
|
||||
orco+=3;
|
||||
}
|
||||
|
||||
if (need_origindex) {
|
||||
int *origindex;
|
||||
origindex = RE_vertren_get_origindex(obr, ver, 1);
|
||||
|
||||
/* Use orig index array if it's available (e.g. in the presence
|
||||
* of modifiers). */
|
||||
if (index_vert_orig)
|
||||
*origindex = index_vert_orig[a];
|
||||
else
|
||||
*origindex = a;
|
||||
}
|
||||
}
|
||||
|
||||
if (!timeoffset) {
|
||||
@@ -3514,6 +3539,21 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (need_origindex) {
|
||||
/* Find original index of mpoly for this tessface. Options:
|
||||
- Modified mesh; two-step look up from tessface -> modified mpoly -> original mpoly
|
||||
- OR Tesselated mesh; look up from tessface -> mpoly
|
||||
- OR Failsafe; tessface == mpoly. Could probably assert(false) in this case? */
|
||||
int *origindex;
|
||||
origindex = RE_vlakren_get_origindex(obr, vlr, 1);
|
||||
if (index_mf_to_mpoly && index_mp_to_orig)
|
||||
*origindex = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a);
|
||||
else if (index_mf_to_mpoly)
|
||||
*origindex = index_mf_to_mpoly[a];
|
||||
else
|
||||
*origindex = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,6 +150,23 @@ void RE_engine_free(RenderEngine *engine)
|
||||
|
||||
/* Render Results */
|
||||
|
||||
static RenderPart *get_part_from_result(Render *re, RenderResult *result)
|
||||
{
|
||||
RenderPart *pa;
|
||||
|
||||
for (pa = re->parts.first; pa; pa = pa->next) {
|
||||
if (result->tilerect.xmin == pa->disprect.xmin - re->disprect.xmin &&
|
||||
result->tilerect.ymin == pa->disprect.ymin - re->disprect.ymin &&
|
||||
result->tilerect.xmax == pa->disprect.xmax - re->disprect.xmin &&
|
||||
result->tilerect.ymax == pa->disprect.ymax - re->disprect.ymin)
|
||||
{
|
||||
return pa;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h, const char *layername)
|
||||
{
|
||||
Render *re = engine->re;
|
||||
@@ -179,12 +196,19 @@ RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w,
|
||||
|
||||
/* can be NULL if we CLAMP the width or height to 0 */
|
||||
if (result) {
|
||||
RenderPart *pa;
|
||||
|
||||
BLI_addtail(&engine->fullresult, result);
|
||||
|
||||
result->tilerect.xmin += re->disprect.xmin;
|
||||
result->tilerect.xmax += re->disprect.xmin;
|
||||
result->tilerect.ymin += re->disprect.ymin;
|
||||
result->tilerect.ymax += re->disprect.ymin;
|
||||
|
||||
pa = get_part_from_result(re, result);
|
||||
|
||||
if (pa)
|
||||
pa->status = PART_STATUS_IN_PROGRESS;
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -203,7 +227,6 @@ void RE_engine_update_result(RenderEngine *engine, RenderResult *result)
|
||||
void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel)
|
||||
{
|
||||
Render *re = engine->re;
|
||||
RenderPart *pa;
|
||||
|
||||
if (!result) {
|
||||
return;
|
||||
@@ -212,15 +235,10 @@ void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel
|
||||
/* merge. on break, don't merge in result for preview renders, looks nicer */
|
||||
if (!cancel) {
|
||||
/* for exr tile render, detect tiles that are done */
|
||||
for (pa = re->parts.first; pa; pa = pa->next) {
|
||||
if (result->tilerect.xmin == pa->disprect.xmin &&
|
||||
result->tilerect.ymin == pa->disprect.ymin &&
|
||||
result->tilerect.xmax == pa->disprect.xmax &&
|
||||
result->tilerect.ymax == pa->disprect.ymax)
|
||||
{
|
||||
pa->ready = 1;
|
||||
}
|
||||
}
|
||||
RenderPart *pa = get_part_from_result(re, result);
|
||||
|
||||
if (pa)
|
||||
pa->status = PART_STATUS_READY;
|
||||
|
||||
if (re->result->do_exr_tile)
|
||||
render_result_exr_file_merge(re->result, result);
|
||||
@@ -310,6 +328,47 @@ void RE_engine_report(RenderEngine *engine, int type, const char *msg)
|
||||
BKE_report(engine->reports, type, msg);
|
||||
}
|
||||
|
||||
void RE_engine_get_current_tiles(Render *re, int *total_tiles_r, rcti **tiles_r)
|
||||
{
|
||||
RenderPart *pa;
|
||||
int total_tiles = 0;
|
||||
rcti *tiles = NULL;
|
||||
int allocation_size = 0, allocation_step = BLENDER_MAX_THREADS;
|
||||
|
||||
if (re->engine && (re->engine->flag & RE_ENGINE_HIGHLIGHT_TILES) == 0) {
|
||||
*total_tiles_r = 0;
|
||||
*tiles_r = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
for (pa = re->parts.first; pa; pa = pa->next) {
|
||||
if (pa->status == PART_STATUS_IN_PROGRESS) {
|
||||
if (total_tiles >= allocation_size) {
|
||||
if (tiles == NULL)
|
||||
tiles = MEM_mallocN(allocation_step * sizeof(rcti), "current engine tiles");
|
||||
else
|
||||
tiles = MEM_reallocN(tiles, (total_tiles + allocation_step) * sizeof(rcti));
|
||||
|
||||
allocation_size += allocation_step;
|
||||
}
|
||||
|
||||
tiles[total_tiles] = pa->disprect;
|
||||
|
||||
if (pa->crop) {
|
||||
tiles[total_tiles].xmin += pa->crop;
|
||||
tiles[total_tiles].ymin += pa->crop;
|
||||
tiles[total_tiles].xmax -= pa->crop;
|
||||
tiles[total_tiles].ymax -= pa->crop;
|
||||
}
|
||||
|
||||
total_tiles++;
|
||||
}
|
||||
}
|
||||
|
||||
*total_tiles_r = total_tiles;
|
||||
*tiles_r = tiles;
|
||||
}
|
||||
|
||||
/* Render */
|
||||
|
||||
int RE_engine_render(Render *re, int do_all)
|
||||
@@ -354,9 +413,7 @@ int RE_engine_render(Render *re, int do_all)
|
||||
|
||||
if (!engine) {
|
||||
engine = RE_engine_create(type);
|
||||
|
||||
if (persistent_data)
|
||||
re->engine = engine;
|
||||
re->engine = engine;
|
||||
}
|
||||
|
||||
engine->flag |= RE_ENGINE_RENDERING;
|
||||
|
||||
@@ -102,6 +102,11 @@ static void ibuf_get_color(float col[4], struct ImBuf *ibuf, int x, int y)
|
||||
col[1] = ((float)rect[1])*(1.0f/255.0f);
|
||||
col[2] = ((float)rect[2])*(1.0f/255.0f);
|
||||
col[3] = ((float)rect[3])*(1.0f/255.0f);
|
||||
|
||||
/* bytes are internally straight, however render pipeline seems to expect premul */
|
||||
col[0] *= col[3];
|
||||
col[1] *= col[3];
|
||||
col[2] *= col[3];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,10 +224,8 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
|
||||
}
|
||||
|
||||
/* keep this before interpolation [#29761] */
|
||||
if (tex->imaflag & TEX_USEALPHA) {
|
||||
if ((tex->imaflag & TEX_CALCALPHA) == 0) {
|
||||
texres->talpha = TRUE;
|
||||
}
|
||||
if ((tex->imaflag & TEX_CALCALPHA) == 0) {
|
||||
texres->talpha = TRUE;
|
||||
}
|
||||
|
||||
/* interpolate */
|
||||
@@ -710,9 +713,10 @@ static int ibuf_get_color_clip(float col[4], ImBuf *ibuf, int x, int y, int extf
|
||||
}
|
||||
else {
|
||||
char *rect = (char *)(ibuf->rect + x + y*ibuf->x);
|
||||
col[0] = rect[0]*(1.f/255.f);
|
||||
col[1] = rect[1]*(1.f/255.f);
|
||||
col[2] = rect[2]*(1.f/255.f);
|
||||
float inv_alpha_fac = (1.0f / 255.0f) * rect[3] * (1.0f / 255.0f);
|
||||
col[0] = rect[0] * inv_alpha_fac;
|
||||
col[1] = rect[1] * inv_alpha_fac;
|
||||
col[2] = rect[2] * inv_alpha_fac;
|
||||
col[3] = clip ? 0.f : rect[3]*(1.f/255.f);
|
||||
}
|
||||
return clip;
|
||||
@@ -1088,7 +1092,8 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
|
||||
/* mipmap test */
|
||||
image_mipmap_test(tex, ibuf);
|
||||
|
||||
if ((tex->imaflag & TEX_USEALPHA) && ((tex->imaflag & TEX_CALCALPHA) == 0)) texres->talpha = 1;
|
||||
if ((tex->imaflag & TEX_CALCALPHA) == 0)
|
||||
texres->talpha = 1;
|
||||
texr.talpha = texres->talpha;
|
||||
|
||||
if (tex->imaflag & TEX_IMAROT) {
|
||||
@@ -1501,13 +1506,8 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
|
||||
/* mipmap test */
|
||||
image_mipmap_test(tex, ibuf);
|
||||
|
||||
if (tex->imaflag & TEX_USEALPHA) {
|
||||
if (tex->imaflag & TEX_CALCALPHA) {
|
||||
/* pass */
|
||||
}
|
||||
else {
|
||||
texres->talpha = TRUE;
|
||||
}
|
||||
if ((tex->imaflag & TEX_CALCALPHA) == 0) {
|
||||
texres->talpha = TRUE;
|
||||
}
|
||||
|
||||
texr.talpha= texres->talpha;
|
||||
|
||||
@@ -233,8 +233,8 @@ static void set_rast_triangle(const MBakeRast *bake_rast, const int x, const int
|
||||
|
||||
if (x >= 0 && x < w && y >= 0 && y < h) {
|
||||
if ((bake_rast->texels[y * w + x]) == 0) {
|
||||
flush_pixel(bake_rast->data, x, y);
|
||||
bake_rast->texels[y * w + x] = FILTER_MASK_USED;
|
||||
flush_pixel(bake_rast->data, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,7 +341,7 @@ void RE_ResultGet32(Render *re, unsigned int *rect)
|
||||
RenderResult rres;
|
||||
|
||||
RE_AcquireResultImage(re, &rres);
|
||||
render_result_rect_get_pixels(&rres, &re->r, rect, re->rectx, re->recty, &re->scene->view_settings, &re->scene->display_settings);
|
||||
render_result_rect_get_pixels(&rres, rect, re->rectx, re->recty, &re->scene->view_settings, &re->scene->display_settings);
|
||||
RE_ReleaseResultImage(re);
|
||||
}
|
||||
|
||||
@@ -660,7 +660,9 @@ static int render_display_draw_enabled(Render *re)
|
||||
static void *do_part_thread(void *pa_v)
|
||||
{
|
||||
RenderPart *pa = pa_v;
|
||||
|
||||
|
||||
pa->status = PART_STATUS_IN_PROGRESS;
|
||||
|
||||
/* need to return nicely all parts on esc */
|
||||
if (R.test_break(R.tbh) == 0) {
|
||||
|
||||
@@ -691,7 +693,7 @@ static void *do_part_thread(void *pa_v)
|
||||
}
|
||||
}
|
||||
|
||||
pa->ready = 1;
|
||||
pa->status = PART_STATUS_READY;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -732,7 +734,7 @@ static RenderPart *find_next_pano_slice(Render *re, int *minx, rctf *viewplane)
|
||||
|
||||
/* most left part of the non-rendering parts */
|
||||
for (pa = re->parts.first; pa; pa = pa->next) {
|
||||
if (pa->ready == 0 && pa->nr == 0) {
|
||||
if (pa->status == PART_STATUS_NONE && pa->nr == 0) {
|
||||
if (pa->disprect.xmin < *minx) {
|
||||
best = pa;
|
||||
*minx = pa->disprect.xmin;
|
||||
@@ -770,7 +772,7 @@ static RenderPart *find_next_part(Render *re, int minx)
|
||||
|
||||
/* find center of rendered parts, image center counts for 1 too */
|
||||
for (pa = re->parts.first; pa; pa = pa->next) {
|
||||
if (pa->ready) {
|
||||
if (pa->status == PART_STATUS_READY) {
|
||||
centx += BLI_rcti_cent_x(&pa->disprect);
|
||||
centy += BLI_rcti_cent_y(&pa->disprect);
|
||||
tot++;
|
||||
@@ -781,7 +783,7 @@ static RenderPart *find_next_part(Render *re, int minx)
|
||||
|
||||
/* closest of the non-rendering parts */
|
||||
for (pa = re->parts.first; pa; pa = pa->next) {
|
||||
if (pa->ready == 0 && pa->nr == 0) {
|
||||
if (pa->status == PART_STATUS_NONE && pa->nr == 0) {
|
||||
long long int distx = centx - BLI_rcti_cent_x(&pa->disprect);
|
||||
long long int disty = centy - BLI_rcti_cent_y(&pa->disprect);
|
||||
distx = (long long int)sqrt(distx * distx + disty * disty);
|
||||
@@ -838,7 +840,7 @@ static void threaded_tile_processor(Render *re)
|
||||
|
||||
if (re->result == NULL)
|
||||
return;
|
||||
|
||||
|
||||
/* warning; no return here without closing exr file */
|
||||
|
||||
RE_parts_init(re, TRUE);
|
||||
@@ -889,7 +891,7 @@ static void threaded_tile_processor(Render *re)
|
||||
rendering = 0;
|
||||
hasdrawn = 0;
|
||||
for (pa = re->parts.first; pa; pa = pa->next) {
|
||||
if (pa->ready) {
|
||||
if (pa->status == PART_STATUS_READY) {
|
||||
|
||||
BLI_remove_thread(&threads, pa);
|
||||
|
||||
@@ -1108,7 +1110,7 @@ static void do_render_blur_3d(Render *re)
|
||||
|
||||
blurfac = 1.0f / (float)(re->r.mblur_samples - blur);
|
||||
|
||||
merge_renderresult_blur(rres, re->result, blurfac, re->r.alphamode & R_ALPHAKEY);
|
||||
merge_renderresult_blur(rres, re->result, blurfac, FALSE);
|
||||
if (re->test_break(re->tbh)) break;
|
||||
}
|
||||
|
||||
@@ -1253,7 +1255,7 @@ static void do_render_fields_blur_3d(Render *re)
|
||||
Object *camera = RE_GetCamera(re);
|
||||
/* also check for camera here */
|
||||
if (camera == NULL) {
|
||||
printf("ERROR: Cannot render, no camera\n");
|
||||
BKE_report(re->reports, RPT_ERROR, "Cannot render, no camera");
|
||||
G.is_break = TRUE;
|
||||
return;
|
||||
}
|
||||
@@ -2209,7 +2211,7 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr
|
||||
}
|
||||
else {
|
||||
char name[FILE_MAX];
|
||||
BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra, scene->r.im_format.imtype, scene->r.scemode & R_EXTENSION, FALSE);
|
||||
BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, FALSE);
|
||||
|
||||
/* reports only used for Movie */
|
||||
do_write_image_or_movie(re, bmain, scene, NULL, name);
|
||||
@@ -2279,7 +2281,7 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie
|
||||
if (name_override)
|
||||
BLI_strncpy(name, name_override, sizeof(name));
|
||||
else
|
||||
BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra, scene->r.im_format.imtype, scene->r.scemode & R_EXTENSION, TRUE);
|
||||
BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, TRUE);
|
||||
|
||||
if (re->r.im_format.imtype == R_IMF_IMTYPE_MULTILAYER) {
|
||||
if (re->result) {
|
||||
@@ -2307,7 +2309,7 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie
|
||||
|
||||
if (BLI_testextensie(name, ".exr"))
|
||||
name[strlen(name) - 4] = 0;
|
||||
BKE_add_image_extension(name, R_IMF_IMTYPE_JPEG90);
|
||||
BKE_add_image_extension(name, &imf);
|
||||
ibuf->planes = 24;
|
||||
|
||||
IMB_colormanagement_imbuf_for_write(ibuf, TRUE, FALSE, &scene->view_settings,
|
||||
@@ -2412,7 +2414,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
|
||||
/* Touch/NoOverwrite options are only valid for image's */
|
||||
if (BKE_imtype_is_movie(scene->r.im_format.imtype) == 0) {
|
||||
if (scene->r.mode & (R_NO_OVERWRITE | R_TOUCH))
|
||||
BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra, scene->r.im_format.imtype, scene->r.scemode & R_EXTENSION, TRUE);
|
||||
BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, TRUE);
|
||||
|
||||
if (scene->r.mode & R_NO_OVERWRITE && BLI_exists(name)) {
|
||||
printf("skipping existing frame \"%s\"\n", name);
|
||||
|
||||
@@ -81,7 +81,7 @@ extern struct Render R;
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
static int test_break(void *data)
|
||||
{
|
||||
Render *re = (Render*)data;
|
||||
Render *re = (Render *)data;
|
||||
return re->test_break(re->tbh);
|
||||
}
|
||||
|
||||
@@ -250,9 +250,9 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)
|
||||
//Create Ray cast accelaration structure
|
||||
raytree = rayobject_create( re, re->r.raytrace_structure, faces );
|
||||
if ( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) )
|
||||
vlakprimitive = obr->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "ObjectRen primitives");
|
||||
vlakprimitive = obr->rayprimitives = (VlakPrimitive *)MEM_callocN(faces * sizeof(VlakPrimitive), "ObjectRen primitives");
|
||||
else
|
||||
face = obr->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "ObjectRen faces");
|
||||
face = obr->rayfaces = (RayFace *)MEM_callocN(faces * sizeof(RayFace), "ObjectRen faces");
|
||||
|
||||
obr->rayobi = obi;
|
||||
|
||||
@@ -345,10 +345,10 @@ static void makeraytree_single(Render *re)
|
||||
raytree = re->raytree = rayobject_create( re, re->r.raytrace_structure, faces+special );
|
||||
|
||||
if ( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) ) {
|
||||
vlakprimitive = re->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "Raytrace vlak-primitives");
|
||||
vlakprimitive = re->rayprimitives = (VlakPrimitive *)MEM_callocN(faces * sizeof(VlakPrimitive), "Raytrace vlak-primitives");
|
||||
}
|
||||
else {
|
||||
face = re->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "Render ray faces");
|
||||
face = re->rayfaces = (RayFace *)MEM_callocN(faces * sizeof(RayFace), "Render ray faces");
|
||||
}
|
||||
|
||||
for (obi=re->instancetable.first; obi; obi=obi->next)
|
||||
@@ -496,8 +496,8 @@ static void shade_ray_set_derivative(ShadeInput *shi)
|
||||
|
||||
void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
|
||||
{
|
||||
ObjectInstanceRen *obi= (ObjectInstanceRen*)is->hit.ob;
|
||||
VlakRen *vlr= (VlakRen*)is->hit.face;
|
||||
ObjectInstanceRen *obi = (ObjectInstanceRen *)is->hit.ob;
|
||||
VlakRen *vlr = (VlakRen *)is->hit.face;
|
||||
|
||||
/* set up view vector */
|
||||
copy_v3_v3(shi->view, is->dir);
|
||||
|
||||
@@ -438,7 +438,7 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
|
||||
rr->renrect.xmin = 0; rr->renrect.xmax = rectx - 2 * crop;
|
||||
/* crop is one or two extra pixels rendered for filtering, is used for merging and display too */
|
||||
rr->crop = crop;
|
||||
|
||||
|
||||
/* tilerect is relative coordinates within render disprect. do not subtract crop yet */
|
||||
rr->tilerect.xmin = partrct->xmin - re->disprect.xmin;
|
||||
rr->tilerect.xmax = partrct->xmax - re->disprect.xmin;
|
||||
@@ -931,7 +931,7 @@ static void save_empty_result_tiles(Render *re)
|
||||
IMB_exrtile_clear_channels(rl->exrhandle);
|
||||
|
||||
for (pa = re->parts.first; pa; pa = pa->next) {
|
||||
if (pa->ready == 0) {
|
||||
if (pa->status != PART_STATUS_READY) {
|
||||
int party = pa->disprect.ymin - re->disprect.ymin + pa->crop;
|
||||
int partx = pa->disprect.xmin - re->disprect.xmin + pa->crop;
|
||||
IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0);
|
||||
@@ -1084,8 +1084,7 @@ int render_result_exr_file_read_path(RenderResult *rr, RenderLayer *rl_single, c
|
||||
|
||||
ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd)
|
||||
{
|
||||
int flags = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE) ? IB_cm_predivide : 0;
|
||||
ImBuf *ibuf = IMB_allocImBuf(rr->rectx, rr->recty, rd->im_format.planes, flags);
|
||||
ImBuf *ibuf = IMB_allocImBuf(rr->rectx, rr->recty, rd->im_format.planes, 0);
|
||||
|
||||
/* if not exists, BKE_imbuf_write makes one */
|
||||
ibuf->rect = (unsigned int *)rr->rect32;
|
||||
@@ -1155,17 +1154,15 @@ void render_result_rect_fill_zero(RenderResult *rr)
|
||||
rr->rect32 = MEM_callocN(sizeof(int) * rr->rectx * rr->recty, "render_seq rect");
|
||||
}
|
||||
|
||||
void render_result_rect_get_pixels(RenderResult *rr, RenderData *rd, unsigned int *rect, int rectx, int recty,
|
||||
void render_result_rect_get_pixels(RenderResult *rr, unsigned int *rect, int rectx, int recty,
|
||||
const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings)
|
||||
{
|
||||
if (rr->rect32) {
|
||||
memcpy(rect, rr->rect32, sizeof(int) * rr->rectx * rr->recty);
|
||||
}
|
||||
else if (rr->rectf) {
|
||||
int predivide = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
|
||||
|
||||
IMB_display_buffer_transform_apply((unsigned char *) rect, rr->rectf, rr->rectx, rr->recty, 4,
|
||||
view_settings, display_settings, predivide);
|
||||
view_settings, display_settings, TRUE);
|
||||
}
|
||||
else
|
||||
/* else fill with black */
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*
|
||||
* Contributors: Hos, Robert Wenzlaff.
|
||||
* Contributors: 2004/2005/2006 Blender Foundation, full recode
|
||||
* Contributors: Vertex color baking, Copyright 2011 AutoCRC
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
@@ -51,9 +52,12 @@
|
||||
#include "DNA_image_types.h"
|
||||
#include "DNA_lamp_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_group_types.h"
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_main.h"
|
||||
@@ -710,9 +714,11 @@ static void sky_tile(RenderPart *pa, RenderLayer *rl)
|
||||
|
||||
if (pass[3]==0.0f) {
|
||||
copy_v4_v4(pass, col);
|
||||
pass[3] = 1.0f;
|
||||
}
|
||||
else {
|
||||
addAlphaUnderFloat(pass, col);
|
||||
pass[3] = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -981,29 +987,6 @@ static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
|
||||
}
|
||||
}
|
||||
|
||||
static void convert_to_key_alpha(RenderPart *pa, RenderLayer *rl)
|
||||
{
|
||||
RenderLayer *rlpp[RE_MAX_OSA];
|
||||
int y, sample, totsample;
|
||||
|
||||
totsample= get_sample_layers(pa, rl, rlpp);
|
||||
|
||||
for (sample= 0; sample<totsample; sample++) {
|
||||
float *rectf= rlpp[sample]->rectf;
|
||||
|
||||
for (y= pa->rectx*pa->recty; y>0; y--, rectf+=4) {
|
||||
if (rectf[3] >= 1.0f) {
|
||||
/* pass */
|
||||
}
|
||||
else if (rectf[3] > 0.0f) {
|
||||
rectf[0] /= rectf[3];
|
||||
rectf[1] /= rectf[3];
|
||||
rectf[2] /= rectf[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* clamp alpha and RGB to 0..1 and 0..inf, can go outside due to filter */
|
||||
static void clamp_alpha_rgb_range(RenderPart *pa, RenderLayer *rl)
|
||||
{
|
||||
@@ -1172,7 +1155,7 @@ typedef struct ZbufSolidData {
|
||||
|
||||
static void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data)
|
||||
{
|
||||
ZbufSolidData *sdata= (ZbufSolidData*)data;
|
||||
ZbufSolidData *sdata = (ZbufSolidData *)data;
|
||||
ListBase *lb= sdata->psmlist;
|
||||
intptr_t *rd= pa->rectdaps;
|
||||
int *ro= zspan->recto;
|
||||
@@ -1312,10 +1295,6 @@ void zbufshadeDA_tile(RenderPart *pa)
|
||||
/* clamp alpha to 0..1 range, can go outside due to filter */
|
||||
clamp_alpha_rgb_range(pa, rl);
|
||||
|
||||
/* de-premul alpha */
|
||||
if (R.r.alphamode & R_ALPHAKEY)
|
||||
convert_to_key_alpha(pa, rl);
|
||||
|
||||
/* free stuff within loop! */
|
||||
MEM_freeN(pa->rectdaps); pa->rectdaps= NULL;
|
||||
freeps(&psmlist);
|
||||
@@ -1476,10 +1455,6 @@ void zbufshade_tile(RenderPart *pa)
|
||||
if (rl->passflag & SCE_PASS_VECTOR)
|
||||
reset_sky_speed(pa, rl);
|
||||
|
||||
/* de-premul alpha */
|
||||
if (R.r.alphamode & R_ALPHAKEY)
|
||||
convert_to_key_alpha(pa, rl);
|
||||
|
||||
if (edgerect) MEM_freeN(edgerect);
|
||||
edgerect= NULL;
|
||||
|
||||
@@ -1740,7 +1715,7 @@ void zbufshade_sss_tile(RenderPart *pa)
|
||||
#if 0
|
||||
if (rs) {
|
||||
/* for each sample in this pixel, shade it */
|
||||
for (ps=(PixStr*)*rs; ps; ps=ps->next) {
|
||||
for (ps = (PixStr *)(*rs); ps; ps=ps->next) {
|
||||
ObjectInstanceRen *obi= &re->objectinstance[ps->obi];
|
||||
ObjectRen *obr= obi->obr;
|
||||
vlr= RE_findOrAddVlak(obr, (ps->facenr-1) & RE_QUAD_MASK);
|
||||
@@ -2032,6 +2007,12 @@ typedef struct BakeShade {
|
||||
|
||||
float dir[3];
|
||||
Object *actob;
|
||||
|
||||
/* Output: vertex color or image data. If vcol is not NULL, rect and
|
||||
* rect_float should be NULL. */
|
||||
MPoly *mpoly;
|
||||
MLoop *mloop;
|
||||
MLoopCol *vcol;
|
||||
|
||||
unsigned int *rect;
|
||||
float *rect_float;
|
||||
@@ -2208,7 +2189,7 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua
|
||||
}
|
||||
}
|
||||
|
||||
if (bs->rect_float) {
|
||||
if (bs->rect_float && !bs->vcol) {
|
||||
float *col= bs->rect_float + 4*(bs->rectx*y + x);
|
||||
copy_v3_v3(col, shr.combined);
|
||||
if (bs->type==RE_BAKE_ALL || bs->type==RE_BAKE_TEXTURE) {
|
||||
@@ -2219,7 +2200,8 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua
|
||||
}
|
||||
}
|
||||
else {
|
||||
unsigned char *col= (unsigned char *)(bs->rect + bs->rectx*y + x);
|
||||
/* Target is char (LDR). */
|
||||
unsigned char col[4];
|
||||
|
||||
if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) {
|
||||
float rgb[3];
|
||||
@@ -2239,6 +2221,19 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua
|
||||
else {
|
||||
col[3]= 255;
|
||||
}
|
||||
|
||||
if (bs->vcol) {
|
||||
/* Vertex colour baking. Vcol has no useful alpha channel (it exists
|
||||
* but is used only for vertex painting). */
|
||||
bs->vcol->r = col[0];
|
||||
bs->vcol->g = col[1];
|
||||
bs->vcol->b = col[2];
|
||||
}
|
||||
else {
|
||||
unsigned char *imcol= (unsigned char *)(bs->rect + bs->rectx*y + x);
|
||||
copy_v4_v4_char((char *)imcol, (char *)col);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (bs->rect_mask) {
|
||||
@@ -2258,15 +2253,28 @@ static void bake_displacement(void *handle, ShadeInput *UNUSED(shi), float dist,
|
||||
disp = 0.5f + dist; /* alter the range from [-0.5,0.5] to [0,1]*/
|
||||
}
|
||||
|
||||
if (bs->rect_float) {
|
||||
if (bs->rect_float && !bs->vcol) {
|
||||
float *col= bs->rect_float + 4*(bs->rectx*y + x);
|
||||
col[0] = col[1] = col[2] = disp;
|
||||
col[3]= 1.0f;
|
||||
}
|
||||
else {
|
||||
char *col= (char *)(bs->rect + bs->rectx*y + x);
|
||||
/* Target is char (LDR). */
|
||||
unsigned char col[4];
|
||||
col[0] = col[1] = col[2] = FTOCHAR(disp);
|
||||
col[3]= 255;
|
||||
col[3] = 255;
|
||||
|
||||
if(bs->vcol) {
|
||||
/* Vertex colour baking. Vcol has no useful alpha channel (it exists
|
||||
* but is used only for vertex painting). */
|
||||
bs->vcol->r = col[0];
|
||||
bs->vcol->g = col[1];
|
||||
bs->vcol->b = col[2];
|
||||
}
|
||||
else {
|
||||
char *imcol= (char *)(bs->rect + bs->rectx*y + x);
|
||||
copy_v4_v4_char((char *)imcol, (char *)col);
|
||||
}
|
||||
}
|
||||
if (bs->rect_mask) {
|
||||
bs->rect_mask[bs->rectx*y + x] = FILTER_MASK_USED;
|
||||
@@ -2461,8 +2469,8 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
|
||||
|
||||
/* if hit, we shade from the new point, otherwise from point one starting face */
|
||||
if (hit) {
|
||||
obi= (ObjectInstanceRen*)minisec.hit.ob;
|
||||
vlr= (VlakRen*)minisec.hit.face;
|
||||
obi = (ObjectInstanceRen *)minisec.hit.ob;
|
||||
vlr = (VlakRen *)minisec.hit.face;
|
||||
quad= (minisec.isect == 2);
|
||||
copy_v3_v3(shi->co, minco);
|
||||
|
||||
@@ -2502,13 +2510,55 @@ static int get_next_bake_face(BakeShade *bs)
|
||||
vlr= RE_findOrAddVlak(obr, v);
|
||||
|
||||
if ((bs->actob && bs->actob == obr->ob) || (!bs->actob && (obr->ob->flag & SELECT))) {
|
||||
tface= RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
|
||||
if(R.r.bake_flag & R_BAKE_VCOL) {
|
||||
/* Gather face data for vertex colour bake */
|
||||
Mesh *me;
|
||||
int *origindex, vcollayer;
|
||||
CustomDataLayer *cdl;
|
||||
|
||||
if (tface && tface->tpage) {
|
||||
Image *ima= tface->tpage;
|
||||
ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
|
||||
if(obr->ob->type != OB_MESH)
|
||||
continue;
|
||||
me = obr->ob->data;
|
||||
|
||||
origindex = RE_vlakren_get_origindex(obr, vlr, 0);
|
||||
if(origindex == NULL)
|
||||
continue;
|
||||
if (*origindex >= me->totpoly) {
|
||||
/* Small hack for Array modifier, which gives false
|
||||
original indices - z0r */
|
||||
continue;
|
||||
}
|
||||
#if 0
|
||||
/* Only shade selected faces. */
|
||||
if((me->mface[*origindex].flag & ME_FACE_SEL) == 0)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
vcollayer = CustomData_get_render_layer_index(&me->ldata, CD_MLOOPCOL);
|
||||
if(vcollayer == -1)
|
||||
continue;
|
||||
|
||||
cdl = &me->ldata.layers[vcollayer];
|
||||
bs->mpoly = me->mpoly + *origindex;
|
||||
bs->vcol = ((MLoopCol*)cdl->data) + bs->mpoly->loopstart;
|
||||
bs->mloop = me->mloop + bs->mpoly->loopstart;
|
||||
|
||||
/* Tag mesh for reevaluation. */
|
||||
DAG_id_tag_update(&me->id, 0);
|
||||
}
|
||||
else {
|
||||
Image *ima = NULL;
|
||||
ImBuf *ibuf = NULL;
|
||||
const float vec_alpha[4]= {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
const float vec_solid[4]= {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
|
||||
tface= RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
|
||||
|
||||
if (!tface || !tface->tpage)
|
||||
continue;
|
||||
|
||||
ima = tface->tpage;
|
||||
ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
|
||||
|
||||
if (ibuf==NULL)
|
||||
continue;
|
||||
@@ -2544,20 +2594,17 @@ static int get_next_bake_face(BakeShade *bs)
|
||||
R.bakebuf= ima;
|
||||
}
|
||||
|
||||
/* Tag image for redraw. */
|
||||
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
|
||||
|
||||
bs->obi= obi;
|
||||
bs->vlr= vlr;
|
||||
|
||||
bs->vdone++; /* only for error message if nothing was rendered */
|
||||
v++;
|
||||
|
||||
BLI_unlock_thread(LOCK_CUSTOM1);
|
||||
|
||||
BKE_image_release_ibuf(ima, ibuf, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bs->obi = obi;
|
||||
bs->vlr = vlr;
|
||||
bs->vdone++; /* only for error message if nothing was rendered */
|
||||
v++;
|
||||
BLI_unlock_thread(LOCK_CUSTOM1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2566,6 +2613,73 @@ static int get_next_bake_face(BakeShade *bs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bake_single_vertex(BakeShade *bs, VertRen *vert, float u, float v)
|
||||
{
|
||||
int *origindex, i;
|
||||
MLoopCol *basevcol;
|
||||
MLoop *mloop;
|
||||
|
||||
origindex = RE_vertren_get_origindex(bs->obi->obr, vert, 0);
|
||||
if (!origindex || *origindex == ORIGINDEX_NONE)
|
||||
return;
|
||||
|
||||
/* Search for matching vertex index and apply shading. */
|
||||
for (i = 0; i < bs->mpoly->totloop; i++) {
|
||||
mloop = bs->mloop + i;
|
||||
if (mloop->v != *origindex)
|
||||
continue;
|
||||
basevcol = bs->vcol;
|
||||
bs->vcol = basevcol + i;
|
||||
do_bake_shade(bs, 0, 0, u, v);
|
||||
bs->vcol = basevcol;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Bake all vertices of a face. Actually, this still works on a face-by-face
|
||||
basis, and each vertex on each face is shaded. Vertex colors are a property
|
||||
of loops, not vertices. */
|
||||
static void shade_verts(BakeShade *bs)
|
||||
{
|
||||
VlakRen *vlr = bs->vlr;
|
||||
|
||||
/* Disable baking to image; write to vcol instead. vcol pointer is set in
|
||||
* bake_single_vertex. */
|
||||
bs->ima = NULL;
|
||||
bs->rect = NULL;
|
||||
bs->rect_float = NULL;
|
||||
|
||||
bs->quad = 0;
|
||||
|
||||
/* No anti-aliasing for vertices. */
|
||||
zero_v3(bs->dxco);
|
||||
zero_v3(bs->dyco);
|
||||
|
||||
/* Shade each vertex of the face. u and v are barycentric coordinates; since
|
||||
we're only interested in vertices, these will be 0 or 1. */
|
||||
if ((vlr->flag & R_FACE_SPLIT) == 0) {
|
||||
/* Processing triangle face, whole quad, or first half of split quad. */
|
||||
|
||||
bake_single_vertex(bs, bs->vlr->v1, 1.0f, 0.0f);
|
||||
bake_single_vertex(bs, bs->vlr->v2, 0.0f, 1.0f);
|
||||
bake_single_vertex(bs, bs->vlr->v3, 0.0f, 0.0f);
|
||||
|
||||
if (vlr->v4) {
|
||||
bs->quad = 1;
|
||||
bake_single_vertex(bs, bs->vlr->v4, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Processing second half of split quad. Only one vertex to go. */
|
||||
if (vlr->flag & R_DIVIDE_24) {
|
||||
bake_single_vertex(bs, bs->vlr->v2, 0.0f, 1.0f);
|
||||
}
|
||||
else {
|
||||
bake_single_vertex(bs, bs->vlr->v3, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* already have tested for tface and ima and zspan */
|
||||
static void shade_tface(BakeShade *bs)
|
||||
{
|
||||
@@ -2593,6 +2707,7 @@ static void shade_tface(BakeShade *bs)
|
||||
bs->rect= bs->ibuf->rect;
|
||||
bs->rect_colorspace= bs->ibuf->rect_colorspace;
|
||||
bs->rect_float= bs->ibuf->rect_float;
|
||||
bs->vcol = NULL;
|
||||
bs->quad= 0;
|
||||
|
||||
if (bs->use_mask) {
|
||||
@@ -2636,7 +2751,10 @@ static void *do_bake_thread(void *bs_v)
|
||||
BakeShade *bs= bs_v;
|
||||
|
||||
while (get_next_bake_face(bs)) {
|
||||
shade_tface(bs);
|
||||
if (R.r.bake_flag & R_BAKE_VCOL)
|
||||
shade_verts(bs);
|
||||
else
|
||||
shade_tface(bs);
|
||||
|
||||
/* fast threadsafe break test */
|
||||
if (R.test_break(R.tbh))
|
||||
@@ -2700,14 +2818,16 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
|
||||
use_mask = TRUE;
|
||||
|
||||
/* baker uses this flag to detect if image was initialized */
|
||||
for (ima= G.main->image.first; ima; ima= ima->id.next) {
|
||||
ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
|
||||
ima->id.flag |= LIB_DOIT;
|
||||
ima->flag&= ~IMA_USED_FOR_RENDER;
|
||||
if (ibuf) {
|
||||
ibuf->userdata = NULL; /* use for masking if needed */
|
||||
if ((R.r.bake_flag & R_BAKE_VCOL) == 0) {
|
||||
for (ima = G.main->image.first; ima; ima = ima->id.next) {
|
||||
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
|
||||
ima->id.flag |= LIB_DOIT;
|
||||
ima->flag &= ~IMA_USED_FOR_RENDER;
|
||||
if (ibuf) {
|
||||
ibuf->userdata = NULL; /* use for masking if needed */
|
||||
}
|
||||
BKE_image_release_ibuf(ima, ibuf, NULL);
|
||||
}
|
||||
BKE_image_release_ibuf(ima, ibuf, NULL);
|
||||
}
|
||||
|
||||
BLI_init_threads(&threads, do_bake_thread, re->r.threads);
|
||||
@@ -2731,7 +2851,10 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
|
||||
|
||||
handles[a].type= type;
|
||||
handles[a].actob= actob;
|
||||
handles[a].zspan= MEM_callocN(sizeof(ZSpan), "zspan for bake");
|
||||
if (R.r.bake_flag & R_BAKE_VCOL)
|
||||
handles[a].zspan = NULL;
|
||||
else
|
||||
handles[a].zspan = MEM_callocN(sizeof(ZSpan), "zspan for bake");
|
||||
|
||||
handles[a].use_mask = use_mask;
|
||||
|
||||
@@ -2758,27 +2881,29 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
|
||||
}
|
||||
|
||||
/* filter and refresh images */
|
||||
for (ima= G.main->image.first; ima; ima= ima->id.next) {
|
||||
if ((ima->id.flag & LIB_DOIT)==0) {
|
||||
ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
|
||||
if ((R.r.bake_flag & R_BAKE_VCOL) == 0) {
|
||||
for (ima = G.main->image.first; ima; ima = ima->id.next) {
|
||||
if ((ima->id.flag & LIB_DOIT)==0) {
|
||||
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
|
||||
|
||||
if (ima->flag & IMA_USED_FOR_RENDER)
|
||||
result= BAKE_RESULT_FEEDBACK_LOOP;
|
||||
if (ima->flag & IMA_USED_FOR_RENDER)
|
||||
result = BAKE_RESULT_FEEDBACK_LOOP;
|
||||
|
||||
if (!ibuf)
|
||||
continue;
|
||||
if (!ibuf)
|
||||
continue;
|
||||
|
||||
RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, re->r.bake_filter);
|
||||
RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, re->r.bake_filter);
|
||||
|
||||
ibuf->userflags |= IB_BITMAPDIRTY;
|
||||
BKE_image_release_ibuf(ima, ibuf, NULL);
|
||||
ibuf->userflags |= IB_BITMAPDIRTY;
|
||||
BKE_image_release_ibuf(ima, ibuf, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate return value */
|
||||
for (a = 0; a < re->r.threads; a++) {
|
||||
zbuf_free_span(handles[a].zspan);
|
||||
MEM_freeN(handles[a].zspan);
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate return value */
|
||||
for (a=0; a<re->r.threads; a++) {
|
||||
zbuf_free_span(handles[a].zspan);
|
||||
MEM_freeN(handles[a].zspan);
|
||||
}
|
||||
|
||||
MEM_freeN(handles);
|
||||
|
||||
@@ -105,6 +105,8 @@
|
||||
#define RE_MTFACE_ELEMS 1
|
||||
#define RE_MCOL_ELEMS 4
|
||||
#define RE_UV_ELEMS 2
|
||||
#define RE_VLAK_ORIGINDEX_ELEMS 1
|
||||
#define RE_VERT_ORIGINDEX_ELEMS 1
|
||||
#define RE_SURFNOR_ELEMS 3
|
||||
#define RE_RADFACE_ELEMS 1
|
||||
#define RE_SIMPLIFY_ELEMS 2
|
||||
@@ -192,10 +194,26 @@ float *RE_vertren_get_winspeed(ObjectInstanceRen *obi, VertRen *ver, int verify)
|
||||
return winspeed + ver->index*RE_WINSPEED_ELEMS;
|
||||
}
|
||||
|
||||
int *RE_vertren_get_origindex(ObjectRen *obr, VertRen *ver, int verify)
|
||||
{
|
||||
int *origindex;
|
||||
int nr= ver->index>>8;
|
||||
|
||||
origindex= obr->vertnodes[nr].origindex;
|
||||
if (origindex==NULL) {
|
||||
if (verify)
|
||||
origindex= obr->vertnodes[nr].origindex= MEM_mallocN(256*RE_VERT_ORIGINDEX_ELEMS*sizeof(int), "origindex table");
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
return origindex + (ver->index & 255)*RE_VERT_ORIGINDEX_ELEMS;
|
||||
}
|
||||
|
||||
VertRen *RE_vertren_copy(ObjectRen *obr, VertRen *ver)
|
||||
{
|
||||
VertRen *v1= RE_findOrAddVert(obr, obr->totvert++);
|
||||
float *fp1, *fp2;
|
||||
int *int1, *int2;
|
||||
int index= v1->index;
|
||||
|
||||
*v1= *ver;
|
||||
@@ -221,6 +239,11 @@ VertRen *RE_vertren_copy(ObjectRen *obr, VertRen *ver)
|
||||
fp2= RE_vertren_get_tangent(obr, v1, 1);
|
||||
memcpy(fp2, fp1, RE_TANGENT_ELEMS*sizeof(float));
|
||||
}
|
||||
int1= RE_vertren_get_origindex(obr, ver, 0);
|
||||
if (int1) {
|
||||
int2= RE_vertren_get_origindex(obr, v1, 1);
|
||||
memcpy(int2, int1, RE_VERT_ORIGINDEX_ELEMS*sizeof(int));
|
||||
}
|
||||
return v1;
|
||||
}
|
||||
|
||||
@@ -332,6 +355,21 @@ MCol *RE_vlakren_get_mcol(ObjectRen *obr, VlakRen *vlr, int n, char **name, int
|
||||
return node->mcol + index*RE_MCOL_ELEMS;
|
||||
}
|
||||
|
||||
int *RE_vlakren_get_origindex(ObjectRen *obr, VlakRen *vlak, int verify)
|
||||
{
|
||||
int *origindex;
|
||||
int nr= vlak->index>>8;
|
||||
|
||||
origindex= obr->vlaknodes[nr].origindex;
|
||||
if(origindex==NULL) {
|
||||
if(verify)
|
||||
origindex= obr->vlaknodes[nr].origindex= MEM_callocN(256*RE_VLAK_ORIGINDEX_ELEMS*sizeof(int), "origindex table");
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
return origindex + (vlak->index & 255)*RE_VLAK_ORIGINDEX_ELEMS;
|
||||
}
|
||||
|
||||
float *RE_vlakren_get_surfnor(ObjectRen *obr, VlakRen *vlak, int verify)
|
||||
{
|
||||
float *surfnor;
|
||||
@@ -370,7 +408,7 @@ RadFace **RE_vlakren_get_radface(ObjectRen *obr, VlakRen *vlak, int verify)
|
||||
radface= obr->vlaknodes[nr].radface;
|
||||
if (radface==NULL) {
|
||||
if (verify)
|
||||
radface= obr->vlaknodes[nr].radface= MEM_callocN(256*RE_RADFACE_ELEMS*sizeof(void*), "radface table");
|
||||
radface = obr->vlaknodes[nr].radface= MEM_callocN(256 * RE_RADFACE_ELEMS * sizeof(void *), "radface table");
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
@@ -383,6 +421,7 @@ VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
|
||||
MTFace *mtface, *mtface1;
|
||||
MCol *mcol, *mcol1;
|
||||
float *surfnor, *surfnor1, *tangent, *tangent1;
|
||||
int *origindex, *origindex1;
|
||||
RadFace **radface, **radface1;
|
||||
int i, index = vlr1->index;
|
||||
char *name;
|
||||
@@ -400,6 +439,13 @@ VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
|
||||
memcpy(mcol1, mcol, sizeof(MCol)*RE_MCOL_ELEMS);
|
||||
}
|
||||
|
||||
origindex= RE_vlakren_get_origindex(obr, vlr, 0);
|
||||
if(origindex) {
|
||||
origindex1= RE_vlakren_get_origindex(obr, vlr1, 1);
|
||||
/* Just an int, but memcpy for consistency. */
|
||||
memcpy(origindex1, origindex, sizeof(int)*RE_VLAK_ORIGINDEX_ELEMS);
|
||||
}
|
||||
|
||||
surfnor= RE_vlakren_get_surfnor(obr, vlr, 0);
|
||||
if (surfnor) {
|
||||
surfnor1= RE_vlakren_get_surfnor(obr, vlr1, 1);
|
||||
@@ -725,6 +771,8 @@ void free_renderdata_vertnodes(VertTableNode *vertnodes)
|
||||
MEM_freeN(vertnodes[a].stress);
|
||||
if (vertnodes[a].winspeed)
|
||||
MEM_freeN(vertnodes[a].winspeed);
|
||||
if (vertnodes[a].origindex)
|
||||
MEM_freeN(vertnodes[a].origindex);
|
||||
}
|
||||
|
||||
MEM_freeN(vertnodes);
|
||||
@@ -743,6 +791,8 @@ void free_renderdata_vlaknodes(VlakTableNode *vlaknodes)
|
||||
MEM_freeN(vlaknodes[a].mtface);
|
||||
if (vlaknodes[a].mcol)
|
||||
MEM_freeN(vlaknodes[a].mcol);
|
||||
if(vlaknodes[a].origindex)
|
||||
MEM_freeN(vlaknodes[a].origindex);
|
||||
if (vlaknodes[a].surfnor)
|
||||
MEM_freeN(vlaknodes[a].surfnor);
|
||||
if (vlaknodes[a].tangent)
|
||||
@@ -888,9 +938,9 @@ HaloRen *RE_findOrAddHalo(ObjectRen *obr, int nr)
|
||||
// TABLEINITSIZE, obr->blohalen+TABLEINITSIZE );
|
||||
temp=obr->bloha;
|
||||
|
||||
obr->bloha=(HaloRen**)MEM_callocN(sizeof(void*)*(obr->blohalen+TABLEINITSIZE), "Bloha");
|
||||
if (temp) memcpy(obr->bloha, temp, obr->blohalen*sizeof(void*));
|
||||
memset(&(obr->bloha[obr->blohalen]), 0, TABLEINITSIZE*sizeof(void*));
|
||||
obr->bloha = (HaloRen**)MEM_callocN(sizeof(void *) * (obr->blohalen + TABLEINITSIZE), "Bloha");
|
||||
if (temp) memcpy(obr->bloha, temp, obr->blohalen*sizeof(void *));
|
||||
memset(&(obr->bloha[obr->blohalen]), 0, TABLEINITSIZE * sizeof(void *));
|
||||
obr->blohalen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/
|
||||
if (temp) MEM_freeN(temp);
|
||||
}
|
||||
|
||||
@@ -812,7 +812,7 @@ void makeshadowbuf(Render *re, LampRen *lar)
|
||||
|
||||
static void *do_shadow_thread(void *re_v)
|
||||
{
|
||||
Render *re= (Render*)re_v;
|
||||
Render *re = (Render *)re_v;
|
||||
LampRen *lar;
|
||||
|
||||
do {
|
||||
|
||||
@@ -522,7 +522,7 @@ static APixstrand *addpsAstrand(ZSpan *zspan)
|
||||
|
||||
static void do_strand_fillac(void *handle, int x, int y, float u, float v, float z)
|
||||
{
|
||||
StrandPart *spart= (StrandPart*)handle;
|
||||
StrandPart *spart= (StrandPart *)handle;
|
||||
StrandShadeCache *cache= spart->cache;
|
||||
StrandSegment *sseg= spart->segment;
|
||||
APixstrand *apn, *apnew;
|
||||
|
||||
@@ -493,7 +493,7 @@ typedef struct VolPrecacheQueue {
|
||||
*/
|
||||
static void *vol_precache_part(void *data)
|
||||
{
|
||||
VolPrecacheQueue *queue = (VolPrecacheQueue*)data;
|
||||
VolPrecacheQueue *queue = (VolPrecacheQueue *)data;
|
||||
VolPrecachePart *pa;
|
||||
|
||||
while ((pa = BLI_thread_queue_pop(queue->work))) {
|
||||
|
||||
Reference in New Issue
Block a user