diff options
29 files changed, 158 insertions, 123 deletions
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h index 51b12fe4e45..acb50ce6faa 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h @@ -42,7 +42,7 @@ ccl_device_inline float D_ggx_aniso(const float3 wm, const float2 alpha) /* Sample slope distribution (based on page 14 of the supplemental implementation). */ ccl_device_inline float2 mf_sampleP22_11(const float cosI, const float2 randU) { - if(cosI > 0.9999f) { + if(cosI > 0.9999f || cosI < 1e-6f) { const float r = sqrtf(randU.x / (1.0f - randU.x)); const float phi = M_2PI_F * randU.y; return make_float2(r*cosf(phi), r*sinf(phi)); @@ -117,7 +117,7 @@ ccl_device_inline float3 mf_eval_phase_glossy(const float3 w, const float lambda if(dotW_WH < 0.0f) return make_float3(0.0f, 0.0f, 0.0f); - float phase = max(0.0f, dotW_WH) * 0.25f / (pArea * dotW_WH); + float phase = max(0.0f, dotW_WH) * 0.25f / max(pArea * dotW_WH, 1e-7f); if(alpha.x == alpha.y) phase *= D_ggx(wh, alpha.x); else @@ -200,9 +200,9 @@ ccl_device_inline float mf_lambda(const float3 w, const float2 alpha) if(w.z > 0.9999f) return 0.0f; else if(w.z < -0.9999f) - return -1.0f; + return -0.9999f; - const float inv_wz2 = 1.0f / (w.z*w.z); + const float inv_wz2 = 1.0f / max(w.z*w.z, 1e-7f); const float2 wa = make_float2(w.x, w.y)*alpha; float v = sqrtf(1.0f + dot(wa, wa) * inv_wz2); if(w.z <= 0.0f) @@ -271,7 +271,10 @@ ccl_device_inline float mf_ggx_albedo(float r) ccl_device_inline float mf_ggx_pdf(const float3 wi, const float3 wo, const float alpha) { - return 0.25f * D_ggx(normalize(wi+wo), alpha) / ((1.0f + mf_lambda(wi, make_float2(alpha, alpha))) * wi.z) + (1.0f - mf_ggx_albedo(alpha)) * wo.z; + float D = D_ggx(normalize(wi+wo), alpha); + float lambda = mf_lambda(wi, make_float2(alpha, alpha)); + float albedo = mf_ggx_albedo(alpha); + return 0.25f * D / max((1.0f + lambda) * wi.z, 1e-7f) + (1.0f - albedo) * wo.z; } ccl_device_inline float mf_ggx_aniso_pdf(const float3 wi, const float3 wo, const float2 alpha) @@ -406,6 +409,10 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals *kg, const ShaderC *eval *= *pdf; *omega_in = X*localO.x + Y*localO.y + Z*localO.z; +#ifdef __RAY_DIFFERENTIALS__ + *domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx; + *domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy; +#endif return LABEL_REFLECT|LABEL_GLOSSY; } @@ -463,10 +470,23 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals *kg, const S *eval *= *pdf; *omega_in = X*localO.x + Y*localO.y + Z*localO.z; - if(localO.z*localI.z > 0.0f) + if(localO.z*localI.z > 0.0f) { +#ifdef __RAY_DIFFERENTIALS__ + *domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx; + *domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy; +#endif return LABEL_REFLECT|LABEL_GLOSSY; - else + } + else { +#ifdef __RAY_DIFFERENTIALS__ + float cosI = dot(Z, I); + float dnp = max(sqrtf(1.0f - (sc->data2 * sc->data2 * (1.0f - cosI*cosI))), 1e-7f); + *domega_in_dx = -(sc->data2 * dIdx) + ((sc->data2 - sc->data2 * sc->data2 * cosI / dnp) * dot(dIdx, Z)) * Z; + *domega_in_dy = -(sc->data2 * dIdy) + ((sc->data2 - sc->data2 * sc->data2 * cosI / dnp) * dot(dIdy, Z)) * Z; +#endif + return LABEL_TRANSMIT|LABEL_GLOSSY; + } } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h index caa6c9d9a5b..eb0decc800b 100644 --- a/intern/cycles/kernel/geom/geom_triangle_intersect.h +++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h @@ -342,9 +342,16 @@ ccl_device_inline float3 triangle_refine(KernelGlobals *kg, float3 tvec = make_float3(P.x - tri_c.x, P.y - tri_c.y, P.z - tri_c.z); float3 qvec = cross(tvec, edge1); float3 pvec = cross(D, edge2); - float rt = dot(edge2, qvec) / dot(edge1, pvec); - - P = P + D*rt; + float det = dot(edge1, pvec); + if(det != 0.0f) { + /* If determinant is zero it means ray lies in the plane of + * the triangle. It is possible in theory due to watertight + * nature of triangle intersection. For suc hcases we simply + * don't refine intersection hoping it'll go all fine. + */ + float rt = dot(edge2, qvec) / det; + P = P + D*rt; + } if(isect->object != OBJECT_NONE) { # ifdef __OBJECT_MOTION__ @@ -400,9 +407,16 @@ ccl_device_inline float3 triangle_refine_subsurface(KernelGlobals *kg, float3 tvec = make_float3(P.x - tri_c.x, P.y - tri_c.y, P.z - tri_c.z); float3 qvec = cross(tvec, edge1); float3 pvec = cross(D, edge2); - float rt = dot(edge2, qvec) / dot(edge1, pvec); - - P = P + D*rt; + float det = dot(edge1, pvec); + if(det != 0.0f) { + /* If determinant is zero it means ray lies in the plane of + * the triangle. It is possible in theory due to watertight + * nature of triangle intersection. For such cases we simply + * don't refine intersection hoping it'll go all fine. + */ + float rt = dot(edge2, qvec) / det; + P = P + D*rt; + } #endif /* __INTERSECTION_REFINE__ */ if(isect->object != OBJECT_NONE) { diff --git a/intern/opensubdiv/gpu_shader_opensubd_display.glsl b/intern/opensubdiv/gpu_shader_opensubd_display.glsl index cc9e05a11c8..5193d3a71dc 100644 --- a/intern/opensubdiv/gpu_shader_opensubd_display.glsl +++ b/intern/opensubdiv/gpu_shader_opensubd_display.glsl @@ -242,6 +242,7 @@ void main() vec3 L_diffuse = vec3(0.0); vec3 L_specular = vec3(0.0); +#ifdef USE_LIGHTING #ifndef USE_COLOR_MATERIAL /* Assume NUM_SOLID_LIGHTS directional lights. */ for (int i = 0; i < NUM_SOLID_LIGHTS; i++) { @@ -312,6 +313,9 @@ void main() L_specular += light_specular * specular_bsdf * intensity; } #endif /* USE_COLOR_MATERIAL */ +#else /* USE_LIGHTING */ + L_diffuse = vec3(1.0); +#endif /* Compute diffuse color. */ #ifdef USE_TEXTURE_2D diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc index 752dce7744c..0cf6fcfef43 100644 --- a/intern/opensubdiv/opensubdiv_gpu_capi.cc +++ b/intern/opensubdiv/opensubdiv_gpu_capi.cc @@ -100,6 +100,12 @@ static GLuint g_flat_fill_solid_program = 0; static GLuint g_flat_fill_texture2d_program = 0; static GLuint g_smooth_fill_solid_program = 0; static GLuint g_smooth_fill_texture2d_program = 0; + +static GLuint g_flat_fill_solid_shadeless_program = 0; +static GLuint g_flat_fill_texture2d_shadeless_program = 0; +static GLuint g_smooth_fill_solid_shadeless_program = 0; +static GLuint g_smooth_fill_texture2d_shadeless_program = 0; + static GLuint g_wireframe_program = 0; static GLuint g_lighting_ub = 0; @@ -425,21 +431,45 @@ bool openSubdiv_osdGLDisplayInit(void) g_flat_fill_solid_program = linkProgram( version, "#define USE_COLOR_MATERIAL\n" + "#define USE_LIGHTING\n" "#define FLAT_SHADING\n"); g_flat_fill_texture2d_program = linkProgram( version, "#define USE_COLOR_MATERIAL\n" + "#define USE_LIGHTING\n" "#define USE_TEXTURE_2D\n" "#define FLAT_SHADING\n"); g_smooth_fill_solid_program = linkProgram( version, "#define USE_COLOR_MATERIAL\n" + "#define USE_LIGHTING\n" "#define SMOOTH_SHADING\n"); g_smooth_fill_texture2d_program = linkProgram( version, "#define USE_COLOR_MATERIAL\n" + "#define USE_LIGHTING\n" "#define USE_TEXTURE_2D\n" "#define SMOOTH_SHADING\n"); + + g_flat_fill_solid_shadeless_program = linkProgram( + version, + "#define USE_COLOR_MATERIAL\n" + "#define FLAT_SHADING\n"); + g_flat_fill_texture2d_shadeless_program = linkProgram( + version, + "#define USE_COLOR_MATERIAL\n" + "#define USE_TEXTURE_2D\n" + "#define FLAT_SHADING\n"); + g_smooth_fill_solid_shadeless_program = linkProgram( + version, + "#define USE_COLOR_MATERIAL\n" + "#define SMOOTH_SHADING\n"); + g_smooth_fill_texture2d_shadeless_program = linkProgram( + version, + "#define USE_COLOR_MATERIAL\n" + "#define USE_TEXTURE_2D\n" + "#define SMOOTH_SHADING\n"); + g_wireframe_program = linkProgram( version, "#define WIREFRAME\n"); @@ -464,21 +494,24 @@ void openSubdiv_osdGLDisplayDeinit(void) if (g_lighting_ub != 0) { glDeleteBuffers(1, &g_lighting_ub); } - if (g_flat_fill_solid_program) { - glDeleteProgram(g_flat_fill_solid_program); - } - if (g_flat_fill_texture2d_program) { - glDeleteProgram(g_flat_fill_texture2d_program); - } - if (g_smooth_fill_solid_program) { - glDeleteProgram(g_flat_fill_solid_program); - } - if (g_smooth_fill_texture2d_program) { - glDeleteProgram(g_smooth_fill_texture2d_program); - } - if (g_wireframe_program) { - glDeleteProgram(g_wireframe_program); - } +#define SAFE_DELETE_PROGRAM(program) \ + do { \ + if (program) { \ + glDeleteProgram(program); \ + } \ + } while (false) + + SAFE_DELETE_PROGRAM(g_flat_fill_solid_program); + SAFE_DELETE_PROGRAM(g_flat_fill_texture2d_program); + SAFE_DELETE_PROGRAM(g_smooth_fill_solid_program); + SAFE_DELETE_PROGRAM(g_smooth_fill_texture2d_program); + SAFE_DELETE_PROGRAM(g_flat_fill_solid_shadeless_program); + SAFE_DELETE_PROGRAM(g_flat_fill_texture2d_shadeless_program); + SAFE_DELETE_PROGRAM(g_smooth_fill_solid_shadeless_program); + SAFE_DELETE_PROGRAM(g_smooth_fill_texture2d_shadeless_program); + SAFE_DELETE_PROGRAM(g_wireframe_program); + +#undef SAFE_DELETE_PROGRAM } void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl, @@ -599,23 +632,32 @@ static GLuint prepare_patchDraw(OpenSubdiv_GLMesh *gl_mesh, if (fill_quads) { int model; - GLboolean use_texture_2d; + GLboolean use_texture_2d, use_lighting; glGetIntegerv(GL_SHADE_MODEL, &model); glGetBooleanv(GL_TEXTURE_2D, &use_texture_2d); + glGetBooleanv(GL_LIGHTING, &use_lighting); if (model == GL_FLAT) { if (use_texture_2d) { - program = g_flat_fill_texture2d_program; + program = use_lighting + ? g_flat_fill_texture2d_program + : g_flat_fill_texture2d_shadeless_program; } else { - program = g_flat_fill_solid_program; + program = use_lighting + ? g_flat_fill_solid_program + : g_flat_fill_solid_shadeless_program; } } else { if (use_texture_2d) { - program = g_smooth_fill_texture2d_program; + program = use_lighting + ? g_smooth_fill_texture2d_program + : g_smooth_fill_texture2d_shadeless_program; } else { - program = g_smooth_fill_solid_program; + program = use_lighting + ? g_smooth_fill_solid_program + : g_smooth_fill_solid_shadeless_program; } } } diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index fddadae3f36..95d50fbd396 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -88,6 +88,7 @@ bool id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, s bool id_copy(struct Main *bmain, struct ID *id, struct ID **newid, bool test); void id_sort_by_name(struct ListBase *lb, struct ID *id); void BKE_id_expand_local(struct ID *id); +void BKE_id_copy_ensure_local(struct Main *bmain, struct ID *old_id, struct ID *new_id); bool new_id(struct ListBase *lb, struct ID *id, const char *name); void id_clear_lib_data(struct Main *bmain, struct ID *id); diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 8f82610a8bb..470098f8c7c 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -156,10 +156,7 @@ bAction *BKE_action_copy(Main *bmain, bAction *src) } } - if (ID_IS_LINKED_DATABLOCK(src)) { - BKE_id_expand_local(&dst->id); - BKE_id_lib_local_paths(bmain, src->id.lib, &dst->id); - } + BKE_id_copy_ensure_local(bmain, &src->id, &dst->id); return dst; } diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 790272c4411..c644fe09364 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -194,10 +194,7 @@ bArmature *BKE_armature_copy(Main *bmain, bArmature *arm) newArm->act_edbone = NULL; newArm->sketch = NULL; - if (ID_IS_LINKED_DATABLOCK(arm)) { - BKE_id_expand_local(&newArm->id); - BKE_id_lib_local_paths(bmain, arm->id.lib, &newArm->id); - } + BKE_id_copy_ensure_local(bmain, &arm->id, &newArm->id); return newArm; } diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 9027287a457..8ef1fae1155 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -197,10 +197,7 @@ Brush *BKE_brush_copy(Main *bmain, Brush *brush) /* enable fake user by default */ id_fake_user_set(&brush->id); - if (ID_IS_LINKED_DATABLOCK(brush)) { - BKE_id_expand_local(&brushn->id); - BKE_id_lib_local_paths(bmain, brush->id.lib, &brushn->id); - } + BKE_id_copy_ensure_local(bmain, &brush->id, &brushn->id); return brushn; } diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index 4229b2a727e..85ce399b770 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -99,10 +99,7 @@ Camera *BKE_camera_copy(Main *bmain, Camera *cam) camn = BKE_libblock_copy(bmain, &cam->id); - if (ID_IS_LINKED_DATABLOCK(cam)) { - BKE_id_expand_local(&camn->id); - BKE_id_lib_local_paths(bmain, cam->id.lib, &camn->id); - } + BKE_id_copy_ensure_local(bmain, &cam->id, &camn->id); return camn; } diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 07f4e4f1610..90a514781d7 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -207,10 +207,7 @@ Curve *BKE_curve_copy(Main *bmain, Curve *cu) id_us_plus((ID *)cun->vfonti); id_us_plus((ID *)cun->vfontbi); - if (ID_IS_LINKED_DATABLOCK(cu)) { - BKE_id_expand_local(&cun->id); - BKE_id_lib_local_paths(bmain, cu->id.lib, &cun->id); - } + BKE_id_copy_ensure_local(bmain, &cu->id, &cun->id); return cun; } diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c index f58d26f47dc..9b011dbb003 100644 --- a/source/blender/blenkernel/intern/group.c +++ b/source/blender/blenkernel/intern/group.c @@ -97,10 +97,7 @@ Group *BKE_group_copy(Main *bmain, Group *group) /* Do not copy group's preview (same behavior as for objects). */ groupn->preview = NULL; - if (ID_IS_LINKED_DATABLOCK(group)) { - BKE_id_expand_local(&groupn->id); - BKE_id_lib_local_paths(bmain, group->id.lib, &groupn->id); - } + BKE_id_copy_ensure_local(bmain, &group->id, &groupn->id); return groupn; } diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 017eb41cd49..ea28dabb945 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -462,10 +462,7 @@ Image *BKE_image_copy(Main *bmain, Image *ima) BKE_previewimg_id_copy(&nima->id, &ima->id); - if (ID_IS_LINKED_DATABLOCK(ima)) { - BKE_id_expand_local(&nima->id); - BKE_id_lib_local_paths(bmain, ima->id.lib, &nima->id); - } + BKE_id_copy_ensure_local(bmain, &ima->id, &nima->id); return nima; } diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index a524f927cad..6cdeaf5e59b 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -170,10 +170,7 @@ Key *BKE_key_copy(Main *bmain, Key *key) kb = kb->next; } - if (ID_IS_LINKED_DATABLOCK(key)) { - BKE_id_expand_local(&keyn->id); - BKE_id_lib_local_paths(bmain, key->id.lib, &keyn->id); - } + BKE_id_copy_ensure_local(bmain, &key->id, &keyn->id); return keyn; } diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c index 35fcf211b05..e9d039ad480 100644 --- a/source/blender/blenkernel/intern/lamp.c +++ b/source/blender/blenkernel/intern/lamp.c @@ -138,10 +138,7 @@ Lamp *BKE_lamp_copy(Main *bmain, Lamp *la) BKE_previewimg_id_copy(&lan->id, &la->id); - if (ID_IS_LINKED_DATABLOCK(la)) { - BKE_id_expand_local(&lan->id); - BKE_id_lib_local_paths(bmain, la->id.lib, &lan->id); - } + BKE_id_copy_ensure_local(bmain, &la->id, &lan->id); return lan; } diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 82b179d4f1c..b0671f33094 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -297,10 +297,7 @@ Lattice *BKE_lattice_copy(Main *bmain, Lattice *lt) ltn->editlatt = NULL; - if (ID_IS_LINKED_DATABLOCK(lt)) { - BKE_id_expand_local(<n->id); - BKE_id_lib_local_paths(bmain, lt->id.lib, <n->id); - } + BKE_id_copy_ensure_local(bmain, <->id, <n->id); return ltn; } diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 79ebc97747e..4d708cbea70 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -276,6 +276,17 @@ void BKE_id_expand_local(ID *id) } /** + * Ensure new (copied) ID is fully made local. + */ +void BKE_id_copy_ensure_local(Main *bmain, ID *old_id, ID *new_id) +{ + if (ID_IS_LINKED_DATABLOCK(old_id)) { + BKE_id_expand_local(new_id); + BKE_id_lib_local_paths(bmain, old_id->lib, new_id); + } +} + +/** * Generic 'make local' function, works for most of datablock types... */ void BKE_id_make_local_generic(Main *bmain, ID *id, const bool id_in_mainlist, const bool lib_local) diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c index 1aff5d502f8..430935a5fad 100644 --- a/source/blender/blenkernel/intern/linestyle.c +++ b/source/blender/blenkernel/intern/linestyle.c @@ -218,10 +218,7 @@ FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, FreestyleLineStyle *l for (m = (LineStyleModifier *)linestyle->geometry_modifiers.first; m; m = m->next) BKE_linestyle_geometry_modifier_copy(new_linestyle, m); - if (ID_IS_LINKED_DATABLOCK(linestyle)) { - BKE_id_expand_local(&new_linestyle->id); - BKE_id_lib_local_paths(bmain, linestyle->id.lib, &new_linestyle->id); - } + BKE_id_copy_ensure_local(bmain, &linestyle->id, &new_linestyle->id); return new_linestyle; } diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 014461e0d22..21023d9f53c 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -853,10 +853,7 @@ Mask *BKE_mask_copy(Main *bmain, Mask *mask) /* enable fake user by default */ id_fake_user_set(&mask->id); - if (ID_IS_LINKED_DATABLOCK(mask)) { - BKE_id_expand_local(&mask_new->id); - BKE_id_lib_local_paths(bmain, mask->id.lib, &mask_new->id); - } + BKE_id_copy_ensure_local(bmain, &mask->id, &mask_new->id); return mask_new; } diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 62aba1af694..0be32c9b84c 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -247,10 +247,7 @@ Material *BKE_material_copy(Main *bmain, Material *ma) BLI_listbase_clear(&man->gpumaterial); - if (ID_IS_LINKED_DATABLOCK(ma)) { - BKE_id_expand_local(&man->id); - BKE_id_lib_local_paths(bmain, ma->id.lib, &man->id); - } + BKE_id_copy_ensure_local(bmain, &ma->id, &man->id); return man; } diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 7e363e5600f..8d024ea9aa5 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -119,10 +119,7 @@ MetaBall *BKE_mball_copy(Main *bmain, MetaBall *mb) mbn->editelems = NULL; mbn->lastelem = NULL; - if (ID_IS_LINKED_DATABLOCK(mb)) { - BKE_id_expand_local(&mbn->id); - BKE_id_lib_local_paths(bmain, mb->id.lib, &mbn->id); - } + BKE_id_copy_ensure_local(bmain, &mb->id, &mbn->id); return mbn; } diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 2b35cdc9d64..733e9030056 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -531,10 +531,7 @@ Mesh *BKE_mesh_copy(Main *bmain, Mesh *me) men->key->from = (ID *)men; } - if (ID_IS_LINKED_DATABLOCK(me)) { - BKE_id_expand_local(&men->id); - BKE_id_lib_local_paths(bmain, me->id.lib, &men->id); - } + BKE_id_copy_ensure_local(bmain, &me->id, &men->id); return men; } diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 8bae0484920..2b88ae4823c 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1290,10 +1290,7 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, Main *bmain, bool ski /* node tree will generate its own interface type */ newtree->interface_type = NULL; - if (ID_IS_LINKED_DATABLOCK(ntree)) { - BKE_id_expand_local(&newtree->id); - BKE_id_lib_local_paths(bmain, ntree->id.lib, &newtree->id); - } + BKE_id_copy_ensure_local(bmain, &ntree->id, &newtree->id); return newtree; } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 9c48fdfbf08..d736a455163 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1169,10 +1169,7 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches) /* Copy runtime surve data. */ obn->curve_cache = NULL; - if (ID_IS_LINKED_DATABLOCK(ob)) { - BKE_id_expand_local(&obn->id); - BKE_id_lib_local_paths(bmain, ob->id.lib, &obn->id); - } + BKE_id_copy_ensure_local(bmain, &ob->id, &obn->id); /* Do not copy object's preview (mostly due to the fact renderers create temp copy of objects). */ obn->preview = NULL; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 9fef220bcc9..42b818b35a5 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -3335,10 +3335,7 @@ ParticleSettings *BKE_particlesettings_copy(Main *bmain, ParticleSettings *part) BLI_duplicatelist(&partn->dupliweights, &part->dupliweights); - if (ID_IS_LINKED_DATABLOCK(part)) { - BKE_id_expand_local(&partn->id); - BKE_id_lib_local_paths(bmain, part->id.lib, &partn->id); - } + BKE_id_copy_ensure_local(bmain, &part->id, &partn->id); return partn; } diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c index 80ee6d50d7e..ee6886e3fb2 100644 --- a/source/blender/blenkernel/intern/speaker.c +++ b/source/blender/blenkernel/intern/speaker.c @@ -77,10 +77,7 @@ Speaker *BKE_speaker_copy(Main *bmain, Speaker *spk) if (spkn->sound) id_us_plus(&spkn->sound->id); - if (ID_IS_LINKED_DATABLOCK(spk)) { - BKE_id_expand_local(&spkn->id); - BKE_id_lib_local_paths(G.main, spk->id.lib, &spkn->id); - } + BKE_id_copy_ensure_local(bmain, &spk->id, &spkn->id); return spkn; } diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 10a0a39fcdd..04bcd366c3f 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -3424,15 +3424,18 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, int current_patch = 0; int mat_nr = -1; int start_draw_patch = 0, num_draw_patches = 0; + bool draw_smooth = false; for (i = 0; i < num_base_faces; ++i) { const int num_face_verts = ccgSubSurf_getNumGLMeshBaseFaceVerts(ss, i); const int num_patches = (num_face_verts == 4) ? face_patches : num_face_verts * grid_patches; if (faceFlags) { - mat_nr = faceFlags[i].mat_nr + 1; + mat_nr = faceFlags[i].mat_nr; + draw_smooth = (faceFlags[i].flag & ME_SMOOTH); } else { mat_nr = 0; + draw_smooth = false; } if (drawParams != NULL) { @@ -3447,8 +3450,13 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == num_base_faces - 1); + const int next_face = min_ii(i + 1, num_base_faces - 1); if (!flush && compareDrawOptions) { - flush |= compareDrawOptions(userData, i, min_ii(i + 1, num_base_faces - 1)) == 0; + flush |= compareDrawOptions(userData, i, next_face) == 0; + } + if (!flush && faceFlags) { + bool new_draw_smooth = (faceFlags[next_face].flag & ME_SMOOTH); + flush |= (new_draw_smooth != draw_smooth); } current_patch += num_patches; @@ -3458,6 +3466,7 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, num_draw_patches += num_patches; } if (num_draw_patches != 0) { + glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT); ccgSubSurf_drawGLMesh(ss, true, start_draw_patch, diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 82c3132d73e..1636042f479 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -491,10 +491,7 @@ Text *BKE_text_copy(Main *bmain, Text *ta) init_undo_text(tan); - if (ID_IS_LINKED_DATABLOCK(ta)) { - BKE_id_expand_local(&tan->id); - BKE_id_lib_local_paths(bmain, ta->id.lib, &tan->id); - } + BKE_id_copy_ensure_local(bmain, &ta->id, &tan->id); return tan; } diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index ed7f32b938f..2d3ecad19ad 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -873,10 +873,7 @@ Tex *BKE_texture_copy(Main *bmain, Tex *tex) BKE_previewimg_id_copy(&texn->id, &tex->id); - if (ID_IS_LINKED_DATABLOCK(tex)) { - BKE_id_expand_local(&texn->id); - BKE_id_lib_local_paths(bmain, tex->id.lib, &texn->id); - } + BKE_id_copy_ensure_local(bmain, &tex->id, &texn->id); return texn; } diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 78342e9919a..de1e3187a70 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -142,10 +142,7 @@ World *BKE_world_copy(Main *bmain, World *wrld) BLI_listbase_clear(&wrldn->gpumaterial); - if (ID_IS_LINKED_DATABLOCK(wrld)) { - BKE_id_expand_local(&wrldn->id); - BKE_id_lib_local_paths(bmain, wrld->id.lib, &wrldn->id); - } + BKE_id_copy_ensure_local(bmain, &wrld->id, &wrldn->id); return wrldn; } |