diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2013-01-06 02:24:05 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2013-01-06 02:24:05 +0400 |
commit | feccbaabbd39c18b2f552964ebd8dfab4eeaed89 (patch) | |
tree | 0069f654883a7a02dd320649ce61bd7933748111 /source/blender/render/intern | |
parent | a22096e8019c461128a0907e4026859996ec1b5c (diff) | |
parent | 37ba969c74840142682cf22f34610f3b65b86cf4 (diff) |
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
Diffstat (limited to 'source/blender/render/intern')
16 files changed, 434 insertions, 151 deletions
diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h index 5d61417cbaf..61b39a59b0b 100644 --- a/source/blender/render/intern/include/render_result.h +++ b/source/blender/render/intern/include/render_result.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); diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index c45c6dfc1bc..3b8cd3c6aa5 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -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 { diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h index 24989b13c48..1e81ca20d03 100644 --- a/source/blender/render/intern/include/renderdatabase.h +++ b/source/blender/render/intern/include/renderdatabase.h @@ -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); diff --git a/source/blender/render/intern/raytrace/rayobject_instance.cpp b/source/blender/render/intern/raytrace/rayobject_instance.cpp index f9ed012b117..01e592cba0c 100644 --- a/source/blender/render/intern/raytrace/rayobject_instance.cpp +++ b/source/blender/render/intern/raytrace/rayobject_instance.cpp @@ -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; } diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index cfa6bb0b11d..74aab678ea8 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -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; + } } } } diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 6fdf11ba48c..296c8b6eba8 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -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; diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 7c14e0e5465..4aaa6247478 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -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; diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c index 9785edd3288..b8784685836 100644 --- a/source/blender/render/intern/source/multires_bake.c +++ b/source/blender/render/intern/source/multires_bake.c @@ -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); } } } diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index c7c5fcf354f..43bada3b383 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -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); diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index fb9eb59cbbf..bef5902588c 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -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); diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index 1d84f0e5a94..0587b097f36 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -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 */ diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index bd0061c0e68..14586f16478 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -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(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 - if (tface && tface->tpage) { - Image *ima= tface->tpage; - ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL); + 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); diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index e189d8bdaea..7ca4f01ae47 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -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); } diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index 078c11a2061..87912f546e8 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -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 { diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index 569bac29205..a37ffb1eb28 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -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; diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c index 549148f4e29..a9db197ed48 100644 --- a/source/blender/render/intern/source/volume_precache.c +++ b/source/blender/render/intern/source/volume_precache.c @@ -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))) { |