diff options
author | Clément Fukhaut <turjuque@gmail.com> | 2016-06-05 17:29:41 +0300 |
---|---|---|
committer | Clément Fukhaut <turjuque@gmail.com> | 2016-06-05 17:29:41 +0300 |
commit | db461850d7fc03dbd72252c501f602c953c51d97 (patch) | |
tree | 1fce82d73b684e38a13c83f417414914c0d66947 /source | |
parent | d28c4d4a7cf30f74a6deaf7f148865fe06bae108 (diff) | |
parent | 04bcaf07dc945578353a8675e1e5003d1c325102 (diff) |
Merge branch 'master' of git://git.blender.org/blender
# Conflicts:
# source/blender/gpu/shaders/gpu_shader_material.glsl
Diffstat (limited to 'source')
85 files changed, 1037 insertions, 548 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 2b13a847e14..8ccc4a6eb0e 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -757,22 +757,22 @@ void DM_update_weight_mcol( typedef struct DMVertexAttribs { struct { struct MLoopUV *array; - int em_offset, gl_index, gl_texco; + int em_offset, gl_index, gl_texco, gl_info_index; } tface[MAX_MTFACE]; struct { struct MLoopCol *array; - int em_offset, gl_index; + int em_offset, gl_index, gl_info_index; } mcol[MAX_MCOL]; struct { float (*array)[4]; - int em_offset, gl_index; + int em_offset, gl_index, gl_info_index; } tang[MAX_MTFACE]; struct { float (*array)[3]; - int em_offset, gl_index, gl_texco; + int em_offset, gl_index, gl_texco, gl_info_index; } orco; int tottface, totmcol, tottang, totorco; diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h index dc751747f32..6524afff051 100644 --- a/source/blender/blenkernel/BKE_animsys.h +++ b/source/blender/blenkernel/BKE_animsys.h @@ -177,7 +177,7 @@ void BKE_animsys_evaluate_all_animation(struct Main *main, struct Scene *scene, /* TODO(sergey): This is mainly a temp public function. */ struct FCurve; -bool BKE_animsys_execute_fcurve(struct PointerRNA *ptr, struct AnimMapper *remap, struct FCurve *fcu); +bool BKE_animsys_execute_fcurve(struct PointerRNA *ptr, struct AnimMapper *remap, struct FCurve *fcu, float curval); /* ------------ Specialized API --------------- */ /* There are a few special tools which require these following functions. They are NOT to be used diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index 2022d11d508..bb4eb652ae2 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -279,7 +279,7 @@ void correct_bezpart(float v1[2], float v2[2], float v3[2], float v4[2]); /* evaluate fcurve */ float evaluate_fcurve(struct FCurve *fcu, float evaltime); /* evaluate fcurve and store value */ -void calculate_fcurve(struct FCurve *fcu, float ctime); +float calculate_fcurve(struct FCurve *fcu, float evaltime); /* ************* F-Curve Samples API ******************** */ diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index bb5cc9cb067..0de0e4d7797 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -3673,6 +3673,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, } attribs->tface[a].gl_index = gattribs->layer[b].glindex; + attribs->tface[a].gl_info_index = gattribs->layer[b].glinfoindoex; attribs->tface[a].gl_texco = gattribs->layer[b].gltexco; } else if (type == CD_MCOL) { @@ -3696,6 +3697,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, } attribs->mcol[a].gl_index = gattribs->layer[b].glindex; + attribs->mcol[a].gl_info_index = gattribs->layer[b].glinfoindoex; } else if (type == CD_TANGENT) { /* note, even with 'is_editmesh' this uses the derived-meshes loop data */ @@ -3718,6 +3720,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, } attribs->tang[a].gl_index = gattribs->layer[b].glindex; + attribs->tang[a].gl_info_index = gattribs->layer[b].glinfoindoex; } else if (type == CD_ORCO) { /* original coordinates */ @@ -3737,6 +3740,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, attribs->orco.gl_index = gattribs->layer[b].glindex; attribs->orco.gl_texco = gattribs->layer[b].gltexco; + attribs->orco.gl_info_index = gattribs->layer[b].glinfoindoex; } } } @@ -3765,6 +3769,7 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert, glTexCoord3fv(orco); else glVertexAttrib3fv(attribs->orco.gl_index, orco); + glUniform1i(attribs->orco.gl_info_index, 0); } /* uv texture coordinates */ @@ -3783,6 +3788,7 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert, glTexCoord2fv(uv); else glVertexAttrib2fv(attribs->tface[b].gl_index, uv); + glUniform1i(attribs->tface[b].gl_info_index, 0); } /* vertex colors */ @@ -3798,6 +3804,7 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert, } glVertexAttrib4fv(attribs->mcol[b].gl_index, col); + glUniform1i(attribs->mcol[b].gl_info_index, GPU_ATTR_INFO_SRGB); } /* tangent for normal mapping */ @@ -3807,6 +3814,7 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert, const float *tang = (array) ? array[a * 4 + vert] : zero; glVertexAttrib4fv(attribs->tang[b].gl_index, tang); } + glUniform1i(attribs->tang[b].gl_info_index, 0); } } diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 41950c59a22..99aae6239e8 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -730,14 +730,10 @@ static char *rna_path_rename_fix(ID *owner_id, const char *prefix, const char *o DynStr *ds = BLI_dynstr_new(); const char *postfixPtr = oldNamePtr + oldNameLen; char *newPath = NULL; - char oldChar; - + /* add the part of the string that goes up to the start of the prefix */ if (prefixPtr > oldpath) { - oldChar = prefixPtr[0]; - prefixPtr[0] = 0; - BLI_dynstr_append(ds, oldpath); - prefixPtr[0] = oldChar; + BLI_dynstr_nappend(ds, oldpath, prefixPtr - oldpath); } /* add the prefix */ @@ -1620,7 +1616,7 @@ static bool animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_ind } /* Simple replacement based data-setting of the FCurve using RNA */ -bool BKE_animsys_execute_fcurve(PointerRNA *ptr, AnimMapper *remap, FCurve *fcu) +bool BKE_animsys_execute_fcurve(PointerRNA *ptr, AnimMapper *remap, FCurve *fcu, float curval) { char *path = NULL; bool free_path = false; @@ -1631,7 +1627,7 @@ bool BKE_animsys_execute_fcurve(PointerRNA *ptr, AnimMapper *remap, FCurve *fcu) /* write value to setting */ if (path) - ok = animsys_write_rna_setting(ptr, path, fcu->array_index, fcu->curval); + ok = animsys_write_rna_setting(ptr, path, fcu->array_index, curval); /* free temp path-info */ if (free_path) @@ -1654,8 +1650,8 @@ static void animsys_evaluate_fcurves(PointerRNA *ptr, ListBase *list, AnimMapper if ((fcu->grp == NULL) || (fcu->grp->flag & AGRP_MUTED) == 0) { /* check if this curve should be skipped */ if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) { - calculate_fcurve(fcu, ctime); - BKE_animsys_execute_fcurve(ptr, remap, fcu); + const float curval = calculate_fcurve(fcu, ctime); + BKE_animsys_execute_fcurve(ptr, remap, fcu, curval); } } } @@ -1684,8 +1680,8 @@ static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime /* evaluate this using values set already in other places * NOTE: for 'layering' option later on, we should check if we should remove old value before adding * new to only be done when drivers only changed */ - calculate_fcurve(fcu, ctime); - ok = BKE_animsys_execute_fcurve(ptr, NULL, fcu); + const float curval = calculate_fcurve(fcu, ctime); + ok = BKE_animsys_execute_fcurve(ptr, NULL, fcu, curval); /* clear recalc flag */ driver->flag &= ~DRIVER_FLAG_RECALC; @@ -1753,8 +1749,8 @@ void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup * for (fcu = agrp->channels.first; (fcu) && (fcu->grp == agrp); fcu = fcu->next) { /* check if this curve should be skipped */ if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) { - calculate_fcurve(fcu, ctime); - BKE_animsys_execute_fcurve(ptr, remap, fcu); + const float curval = calculate_fcurve(fcu, ctime); + BKE_animsys_execute_fcurve(ptr, remap, fcu, curval); } } } @@ -2888,8 +2884,8 @@ void BKE_animsys_eval_driver(EvaluationContext *eval_ctx, * NOTE: for 'layering' option later on, we should check if we should remove old value before adding * new to only be done when drivers only changed */ //printf("\told val = %f\n", fcu->curval); - calculate_fcurve(fcu, eval_ctx->ctime); - ok = BKE_animsys_execute_fcurve(&id_ptr, NULL, fcu); + const float curval = calculate_fcurve(fcu, eval_ctx->ctime); + ok = BKE_animsys_execute_fcurve(&id_ptr, NULL, fcu, curval); //printf("\tnew val = %f\n", fcu->curval); /* clear recalc flag */ diff --git a/source/blender/blenkernel/intern/autoexec.c b/source/blender/blenkernel/intern/autoexec.c index d9462cd0262..bde06b02ae8 100644 --- a/source/blender/blenkernel/intern/autoexec.c +++ b/source/blender/blenkernel/intern/autoexec.c @@ -59,7 +59,10 @@ bool BKE_autoexec_match(const char *path) BLI_assert((U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0); for (path_cmp = U.autoexec_paths.first; path_cmp; path_cmp = path_cmp->next) { - if ((path_cmp->flag & USER_PATHCMP_GLOB)) { + if (path_cmp->path[0] == '\0') { + /* pass */ + } + else if ((path_cmp->flag & USER_PATHCMP_GLOB)) { if (fnmatch(path_cmp->path, path, fnmatch_flags) == 0) { return true; } diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 31dac038e43..da7863096e3 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -852,7 +852,7 @@ int BKE_brush_size_get(const Scene *scene, const Brush *brush) UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; int size = (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size; - return (int)((float)size * U.pixelsize); + return size; } int BKE_brush_use_locked_size(const Scene *scene, const Brush *brush) diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index af1ad4900b3..e7e6118813e 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1032,6 +1032,7 @@ static void cdDM_drawMappedFacesGLSL( if (matconv[a].attribs.totorco && matconv[a].attribs.orco.array) { matconv[a].datatypes[numdata].index = matconv[a].attribs.orco.gl_index; + matconv[a].datatypes[numdata].info_index = matconv[a].attribs.orco.gl_info_index; matconv[a].datatypes[numdata].size = 3; matconv[a].datatypes[numdata].type = GL_FLOAT; numdata++; @@ -1039,6 +1040,7 @@ static void cdDM_drawMappedFacesGLSL( for (b = 0; b < matconv[a].attribs.tottface; b++) { if (matconv[a].attribs.tface[b].array) { matconv[a].datatypes[numdata].index = matconv[a].attribs.tface[b].gl_index; + matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tface[b].gl_info_index; matconv[a].datatypes[numdata].size = 2; matconv[a].datatypes[numdata].type = GL_FLOAT; numdata++; @@ -1047,6 +1049,7 @@ static void cdDM_drawMappedFacesGLSL( for (b = 0; b < matconv[a].attribs.totmcol; b++) { if (matconv[a].attribs.mcol[b].array) { matconv[a].datatypes[numdata].index = matconv[a].attribs.mcol[b].gl_index; + matconv[a].datatypes[numdata].info_index = matconv[a].attribs.mcol[b].gl_info_index; matconv[a].datatypes[numdata].size = 4; matconv[a].datatypes[numdata].type = GL_UNSIGNED_BYTE; numdata++; @@ -1055,6 +1058,7 @@ static void cdDM_drawMappedFacesGLSL( for (b = 0; b < matconv[a].attribs.tottang; b++) { if (matconv[a].attribs.tang[b].array) { matconv[a].datatypes[numdata].index = matconv[a].attribs.tang[b].gl_index; + matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tang[b].gl_info_index; matconv[a].datatypes[numdata].size = 4; matconv[a].datatypes[numdata].type = GL_FLOAT; numdata++; diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 6c117447664..ffd000eed88 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -57,6 +57,7 @@ #include "MEM_guardedalloc.h" #include "GPU_glew.h" +#include "GPU_buffers.h" #include "GPU_shader.h" #include "GPU_basic_shader.h" @@ -1405,6 +1406,24 @@ static void emDM_drawMappedFacesTex( emDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData); } +static void emdm_pass_attrib_update_uniforms(const DMVertexAttribs *attribs) +{ + int i; + if (attribs->totorco) { + glUniform1i(attribs->orco.gl_info_index, 0); + } + for (i = 0; i < attribs->tottface; i++) { + glUniform1i(attribs->tface[i].gl_info_index, 0); + } + for (i = 0; i < attribs->totmcol; i++) { + glUniform1i(attribs->mcol[i].gl_info_index, GPU_ATTR_INFO_SRGB); + } + + for (i = 0; i < attribs->tottang; i++) { + glUniform1i(attribs->tang[i].gl_info_index, 0); + } +} + /** * \note * @@ -1449,15 +1468,15 @@ static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const B glVertexAttrib2fv(attribs->tface[i].gl_index, uv); } for (i = 0; i < attribs->totmcol; i++) { - GLubyte col[4]; + float col[4]; if (attribs->mcol[i].em_offset != -1) { const MLoopCol *cp = BM_ELEM_CD_GET_VOID_P(loop, attribs->mcol[i].em_offset); - copy_v4_v4_uchar(col, &cp->r); + rgba_uchar_to_float(col, &cp->r); } else { - col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0; + col[0] = 0.0f; col[1] = 0.0f; col[2] = 0.0f; col[3] = 0.0f; } - glVertexAttrib4ubv(attribs->mcol[i].gl_index, col); + glVertexAttrib4fv(attribs->mcol[i].gl_index, col); } for (i = 0; i < attribs->tottang; i++) { @@ -1527,6 +1546,7 @@ static void emDM_drawMappedFacesGLSL( do_draw = setMaterial(matnr = new_matnr, &gattribs); if (do_draw) { DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); + emdm_pass_attrib_update_uniforms(&attribs); if (UNLIKELY(attribs.tottang && bm->elem_index_dirty & BM_LOOP)) { BM_mesh_elem_index_ensure(bm, BM_LOOP); } diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 6284b3a46fb..f06dd6f9de4 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -566,7 +566,9 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin float cfra = eff->scene->r.cfra; int ret = 0; - if (eff->pd && eff->pd->shape==PFIELD_SHAPE_SURFACE && eff->surmd) { + /* In case surface object is in Edit mode when loading the .blend, surface modifier is never executed + * and bvhtree never built, see T48415. */ + if (eff->pd && eff->pd->shape==PFIELD_SHAPE_SURFACE && eff->surmd && eff->surmd->bvhtree) { /* closest point in the object surface is an effector */ float vec[3]; diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index a2b5a05feac..395161aa6ed 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -2671,7 +2671,7 @@ float evaluate_fcurve(FCurve *fcu, float evaltime) } /* Calculate the value of the given F-Curve at the given frame, and set its curval */ -void calculate_fcurve(FCurve *fcu, float ctime) +float calculate_fcurve(FCurve *fcu, float evaltime) { /* only calculate + set curval (overriding the existing value) if curve has * any data which warrants this... @@ -2680,7 +2680,12 @@ void calculate_fcurve(FCurve *fcu, float ctime) list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE)) { /* calculate and set curval (evaluates driver too if necessary) */ - fcu->curval = evaluate_fcurve(fcu, ctime); + float curval = evaluate_fcurve(fcu, evaltime); + fcu->curval = curval; /* debug display only, not thread safe! */ + return curval; + } + else { + return 0.0f; } } diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 1ae7ca189fb..0b2c844cb2c 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -109,8 +109,8 @@ static void image_add_view(Image *ima, const char *viewname, const char *filepat #define IMA_NO_INDEX 0x7FEFEFEF /* quick lookup: supports 1 million frames, thousand passes */ -#define IMA_MAKE_INDEX(frame, index) ((frame) << 10) + index -#define IMA_INDEX_FRAME(index) (index >> 10) +#define IMA_MAKE_INDEX(frame, index) (((frame) << 10) + (index)) +#define IMA_INDEX_FRAME(index) ((index) >> 10) /* #define IMA_INDEX_PASS(index) (index & ~1023) */ diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 1fec725dbb7..30f82a50ed9 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -1148,7 +1148,6 @@ static void init_render_nodetree(bNodeTree *ntree, Material *basemat, int r_mode /* parses the geom+tex nodes */ ntreeShaderGetTexcoMode(ntree, r_mode, &basemat->texco, &basemat->mode_l); - basemat->nmap_tangent_names_count = 0; for (node = ntree->nodes.first; node; node = node->next) { if (node->id) { if (GS(node->id->name) == ID_MA) { @@ -1199,7 +1198,7 @@ void init_render_material(Material *mat, int r_mode, float *amb) * mode_l will have it set when all node materials are shadeless. */ mat->mode_l = (mat->mode & MA_MODE_PIPELINE) | MA_SHLESS; mat->mode2_l = mat->mode2 & MA_MODE2_PIPELINE; - + mat->nmap_tangent_names_count = 0; init_render_nodetree(mat->nodetree, mat, r_mode, amb); if (!mat->nodetree->execdata) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 7dce237c737..25dd7fff380 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -141,6 +141,11 @@ int count_particles_mod(ParticleSystem *psys, int totgr, int cur) #define PATH_CACHE_BUF_SIZE 1024 +static ParticleCacheKey *pcache_key_segment_endpoint_safe(ParticleCacheKey *key) +{ + return (key->segments > 0) ? (key + (key->segments - 1)) : key; +} + static ParticleCacheKey **psys_alloc_path_cache_buffers(ListBase *bufs, int tot, int totkeys) { LinkData *buf; @@ -2205,20 +2210,22 @@ static void psys_thread_create_path(ParticleTask *task, struct ChildParticle *cp /* modify weights to create parting */ if (p_fac > 0.f) { + const ParticleCacheKey *key_0_last = pcache_key_segment_endpoint_safe(key[0]); for (w = 0; w < 4; w++) { - if (w && weight[w] > 0.f) { + if (w && (weight[w] > 0.f)) { + const ParticleCacheKey *key_w_last = pcache_key_segment_endpoint_safe(key[w]); float d; if (part->flag & PART_CHILD_LONG_HAIR) { /* For long hair use tip distance/root distance as parting factor instead of root to tip angle. */ float d1 = len_v3v3(key[0]->co, key[w]->co); - float d2 = len_v3v3((key[0] + key[0]->segments - 1)->co, (key[w] + key[w]->segments - 1)->co); + float d2 = len_v3v3(key_0_last->co, key_w_last->co); d = d1 > 0.f ? d2 / d1 - 1.f : 10000.f; } else { float v1[3], v2[3]; - sub_v3_v3v3(v1, (key[0] + key[0]->segments - 1)->co, key[0]->co); - sub_v3_v3v3(v2, (key[w] + key[w]->segments - 1)->co, key[w]->co); + sub_v3_v3v3(v1, key_0_last->co, key[0]->co); + sub_v3_v3v3(v2, key_w_last->co, key[w]->co); normalize_v3(v1); normalize_v3(v2); diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index d73f087a3fe..58ec75dc706 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -637,6 +637,7 @@ void BKE_pbvh_free(PBVH *bvh) BLI_gset_free(node->bm_other_verts, NULL); } } + GPU_free_pbvh_buffer_multires(&bvh->grid_common_gpu_buffer); if (bvh->deformed) { if (bvh->verts) { @@ -1100,7 +1101,7 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode) node->totprim, bvh->grid_hidden, bvh->gridkey.grid_size, - &bvh->gridkey); + &bvh->gridkey, &bvh->grid_common_gpu_buffer); break; case PBVH_FACES: node->draw_buffers = diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h index bae323dedef..4d2307c3e12 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.h +++ b/source/blender/blenkernel/intern/pbvh_intern.h @@ -145,6 +145,11 @@ struct PBVH { const DMFlagMat *grid_flag_mats; int totgrid; BLI_bitmap **grid_hidden; + /* index_buf of GPU_PBVH_Buffers can be the same for all 'fully drawn' nodes (same size). + * Previously was stored in a static var in gpu_buffer.c, but this breaks in case we handle several different + * objects in sculpt mode with different sizes at the same time, so now storing that common gpu buffer + * in an opaque pointer per pbvh. See T47637. */ + struct GridCommonGPUBuffer *grid_common_gpu_buffer; /* Only used during BVH build and update, * don't need to remain valid after */ diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index b9f7afb7365..518d8d68919 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -435,7 +435,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, bool for } } else { - if ((aux_tree = bvhtree_from_mesh_looptri(&dmauxdata_stack, calc->target, 0.0, 4, 6)) != NULL) { + if ((aux_tree = bvhtree_from_mesh_looptri(&dmauxdata_stack, auxMesh, 0.0, 4, 6)) != NULL) { aux_callback = dmauxdata_stack.raycast_callback; auxData = &dmauxdata_stack; } diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 5fd418fadfc..88bc3fb9854 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -2996,6 +2996,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, if (matconv[a].attribs.totorco && matconv[a].attribs.orco.array) { matconv[a].datatypes[numdata].index = matconv[a].attribs.orco.gl_index; + matconv[a].datatypes[numdata].info_index = matconv[a].attribs.orco.gl_info_index; matconv[a].datatypes[numdata].size = 3; matconv[a].datatypes[numdata].type = GL_FLOAT; numdata++; @@ -3003,6 +3004,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, for (b = 0; b < matconv[a].attribs.tottface; b++) { if (matconv[a].attribs.tface[b].array) { matconv[a].datatypes[numdata].index = matconv[a].attribs.tface[b].gl_index; + matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tface[b].gl_info_index; matconv[a].datatypes[numdata].size = 2; matconv[a].datatypes[numdata].type = GL_FLOAT; numdata++; @@ -3011,6 +3013,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, for (b = 0; b < matconv[a].attribs.totmcol; b++) { if (matconv[a].attribs.mcol[b].array) { matconv[a].datatypes[numdata].index = matconv[a].attribs.mcol[b].gl_index; + matconv[a].datatypes[numdata].info_index = matconv[a].attribs.mcol[b].gl_info_index; matconv[a].datatypes[numdata].size = 4; matconv[a].datatypes[numdata].type = GL_UNSIGNED_BYTE; numdata++; @@ -3019,6 +3022,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, for (b = 0; b < matconv[a].attribs.tottang; b++) { if (matconv[a].attribs.tottang && matconv[a].attribs.tang[b].array) { matconv[a].datatypes[numdata].index = matconv[a].attribs.tang[b].gl_index; + matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tang[b].gl_info_index; matconv[a].datatypes[numdata].size = 4; matconv[a].datatypes[numdata].type = GL_FLOAT; numdata++; diff --git a/source/blender/blenlib/BLI_stackdefines.h b/source/blender/blenlib/BLI_stackdefines.h index b26dc3e26aa..42b11eb9a2b 100644 --- a/source/blender/blenlib/BLI_stackdefines.h +++ b/source/blender/blenlib/BLI_stackdefines.h @@ -31,28 +31,28 @@ /* only validate array-bounds in debug mode */ #ifdef DEBUG # define STACK_DECLARE(stack) unsigned int _##stack##_index, _##stack##_totalloc -# define STACK_INIT(stack, tot) ((void)stack, (void)((_##stack##_index) = 0), (void)((_##stack##_totalloc) = tot)) -# define _STACK_SIZETEST(stack, off) (BLI_assert((_##stack##_index) + off <= _##stack##_totalloc)) +# define STACK_INIT(stack, tot) ((void)stack, (void)((_##stack##_index) = 0), (void)((_##stack##_totalloc) = (tot))) +# define _STACK_SIZETEST(stack, off) (BLI_assert((_##stack##_index) + (off) <= _##stack##_totalloc)) # define _STACK_SWAP_TOTALLOC(stack_a, stack_b) SWAP(unsigned int, _##stack_a##_totalloc, _##stack_b##_totalloc) #else # define STACK_DECLARE(stack) unsigned int _##stack##_index -# define STACK_INIT(stack, tot) ((void)stack, (void)((_##stack##_index) = 0), (void)(0 ? tot : 0)) +# define STACK_INIT(stack, tot) ((void)stack, (void)((_##stack##_index) = 0), (void)(0 ? (tot) : 0)) # define _STACK_SIZETEST(stack, off) (void)(stack), (void)(off) # define _STACK_SWAP_TOTALLOC(stack_a, stack_b) (void)(stack_a), (void)(stack_b) #endif -#define _STACK_BOUNDSTEST(stack, index) ((void)stack, BLI_assert((unsigned int)index < _##stack##_index)) +#define _STACK_BOUNDSTEST(stack, index) ((void)stack, BLI_assert((unsigned int)(index) < _##stack##_index)) #define STACK_SIZE(stack) ((void)stack, (_##stack##_index)) #define STACK_CLEAR(stack) {(void)stack; _##stack##_index = 0; } ((void)0) /** add item to stack */ -#define STACK_PUSH(stack, val) ((void)stack, _STACK_SIZETEST(stack, 1), ((stack)[(_##stack##_index)++] = val)) +#define STACK_PUSH(stack, val) ((void)stack, _STACK_SIZETEST(stack, 1), ((stack)[(_##stack##_index)++] = (val))) #define STACK_PUSH_RET(stack) ((void)stack, _STACK_SIZETEST(stack, 1), ((stack)[(_##stack##_index)++])) #define STACK_PUSH_RET_PTR(stack) ((void)stack, _STACK_SIZETEST(stack, 1), &((stack)[(_##stack##_index)++])) /** take last item from stack */ #define STACK_POP(stack) ((_##stack##_index) ? ((stack)[--(_##stack##_index)]) : NULL) #define STACK_POP_PTR(stack) ((_##stack##_index) ? &((stack)[--(_##stack##_index)]) : NULL) -#define STACK_POP_DEFAULT(stack, r) ((_##stack##_index) ? ((stack)[--(_##stack##_index)]) : r) +#define STACK_POP_DEFAULT(stack, r) ((_##stack##_index) ? ((stack)[--(_##stack##_index)]) : (r)) /** look at last item (assumes non-empty stack) */ #define STACK_PEEK(stack) (BLI_assert(_##stack##_index), ((stack)[_##stack##_index - 1])) #define STACK_PEEK_PTR(stack) (BLI_assert(_##stack##_index), &((stack)[_##stack##_index - 1])) diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index 05f2d9221ef..06946e520a8 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -1287,7 +1287,7 @@ bool BLI_ghashutil_paircmp(const void *a, const void *b) const GHashPair *A = a; const GHashPair *B = b; - return (BLI_ghashutil_ptrcmp(A->first, B->first) && + return (BLI_ghashutil_ptrcmp(A->first, B->first) || BLI_ghashutil_ptrcmp(A->second, B->second)); } diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c index 7338804c685..b7a51f2c48e 100644 --- a/source/blender/blenlib/intern/BLI_mempool.c +++ b/source/blender/blenlib/intern/BLI_mempool.c @@ -57,12 +57,29 @@ #ifdef __BIG_ENDIAN__ /* Big Endian */ # define MAKE_ID(a, b, c, d) ( (int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d) ) +# define MAKE_ID_8(a, b, c, d, e, f, g, h) \ + ((int64_t)(a) << 56 | (int64_t)(b) << 48 | (int64_t)(c) << 40 | (int64_t)(d) << 32 | \ + (int64_t)(e) << 24 | (int64_t)(f) << 16 | (int64_t)(g) << 8 | (h) ) #else /* Little Endian */ # define MAKE_ID(a, b, c, d) ( (int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a) ) +# define MAKE_ID_8(a, b, c, d, e, f, g, h) \ + ((int64_t)(h) << 56 | (int64_t)(g) << 48 | (int64_t)(f) << 40 | (int64_t)(e) << 32 | \ + (int64_t)(d) << 24 | (int64_t)(c) << 16 | (int64_t)(b) << 8 | (a) ) #endif -#define FREEWORD MAKE_ID('f', 'r', 'e', 'e') +/** + * Important that this value is an is _not_ aligned with ``sizeof(void *)``. + * So having a pointer to 2/4/8... aligned memory is enough to ensure the freeword will never be used. + * To be safe, use a word thats the same in both directions. + */ +#define FREEWORD ((sizeof(void *) > sizeof(int32_t)) ? \ + MAKE_ID_8('e', 'e', 'r', 'f', 'f', 'r', 'e', 'e') : \ + MAKE_ID('e', 'f', 'f', 'e')) + +/** + * The 'used' word just needs to be set to something besides FREEWORD. + */ #define USEDWORD MAKE_ID('u', 's', 'e', 'd') /* currently totalloc isnt used */ @@ -87,7 +104,7 @@ static bool mempool_debug_memset = false; */ typedef struct BLI_freenode { struct BLI_freenode *next; - int freeword; /* used to identify this as a freed node */ + intptr_t freeword; /* used to identify this as a freed node */ } BLI_freenode; /** @@ -588,19 +605,26 @@ void *BLI_mempool_iterstep(BLI_mempool_iter *iter) */ void *BLI_mempool_iterstep(BLI_mempool_iter *iter) { - BLI_freenode *ret; + if (UNLIKELY(iter->curchunk == NULL)) { + return NULL; + } + const unsigned int esize = iter->pool->esize; + BLI_freenode *curnode = POINTER_OFFSET(CHUNK_DATA(iter->curchunk), (esize * iter->curindex)); + BLI_freenode *ret; do { - if (LIKELY(iter->curchunk)) { - ret = (BLI_freenode *)(((char *)CHUNK_DATA(iter->curchunk)) + (iter->pool->esize * iter->curindex)); + ret = curnode; + + if (++iter->curindex != iter->pool->pchunk) { + curnode = POINTER_OFFSET(curnode, esize); } else { - return NULL; - } - - if (UNLIKELY(++iter->curindex == iter->pool->pchunk)) { iter->curindex = 0; iter->curchunk = iter->curchunk->next; + if (iter->curchunk == NULL) { + return NULL; + } + curnode = CHUNK_DATA(iter->curchunk); } } while (ret->freeword == FREEWORD); diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c index 7f657f4a048..9baccf38fa3 100644 --- a/source/blender/blenlib/intern/array_store.c +++ b/source/blender/blenlib/intern/array_store.c @@ -229,7 +229,9 @@ typedef struct BArrayInfo { /* pre-calculated */ size_t chunk_byte_size; + /* min/max limits (inclusive) */ size_t chunk_byte_size_min; + size_t chunk_byte_size_max; size_t accum_read_ahead_bytes; #ifdef USE_HASH_TABLE_ACCUMULATE @@ -455,7 +457,7 @@ static void bchunk_list_ensure_min_size_last( if (MIN2(chunk_prev->data_len, chunk_curr->data_len) < info->chunk_byte_size_min) { const size_t data_merge_len = chunk_prev->data_len + chunk_curr->data_len; /* we could pass, but no need */ - if (data_merge_len <= (info->chunk_byte_size * BCHUNK_SIZE_MAX_MUL)) { + if (data_merge_len <= info->chunk_byte_size_max) { /* we have enough space to merge */ /* remove last from linklist */ @@ -527,6 +529,53 @@ static void bchunk_list_ensure_min_size_last( } #endif /* USE_MERGE_CHUNKS */ + +/** + * Split length into 2 values + * \param r_data_trim_len: Length which is aligned to the #BArrayInfo.chunk_byte_size + * \param r_data_last_chunk_len: The remaining bytes. + * + * \note This function ensures the size of \a r_data_last_chunk_len + * is larger than #BArrayInfo.chunk_byte_size_min. + */ +static void bchunk_list_calc_trim_len( + const BArrayInfo *info, const size_t data_len, + size_t *r_data_trim_len, size_t *r_data_last_chunk_len) +{ + size_t data_last_chunk_len = 0; + size_t data_trim_len = data_len; + +#ifdef USE_MERGE_CHUNKS + /* avoid creating too-small chunks + * more efficient then merging after */ + if (data_len > info->chunk_byte_size) { + data_last_chunk_len = (data_trim_len % info->chunk_byte_size); + data_trim_len = data_trim_len - data_last_chunk_len; + if (data_last_chunk_len) { + if (data_last_chunk_len < info->chunk_byte_size_min) { + /* may be zero and thats OK */ + data_trim_len -= info->chunk_byte_size; + data_last_chunk_len += info->chunk_byte_size; + } + } + } + else { + data_trim_len = 0; + data_last_chunk_len = data_len; + } + + BLI_assert((data_trim_len == 0) || (data_trim_len >= info->chunk_byte_size)); +#else + data_last_chunk_len = (data_trim_len % info->chunk_byte_size); + data_trim_len = data_trim_len - data_last_chunk_len; +#endif + + BLI_assert(data_trim_len + data_last_chunk_len == data_len); + + *r_data_trim_len = data_trim_len; + *r_data_last_chunk_len = data_last_chunk_len; +} + /** * Append and don't manage merging small chunks. */ @@ -542,14 +591,21 @@ static bool bchunk_list_append_only( return chunk; } +/** + * \note This is for writing single chunks, + * use #bchunk_list_append_data_n when writing large blocks of memory into many chunks. + */ static void bchunk_list_append_data( const BArrayInfo *info, BArrayMemory *bs_mem, BChunkList *chunk_list, const ubyte *data, const size_t data_len) { BLI_assert(data_len != 0); + // printf("data_len: %d\n", data_len); #ifdef USE_MERGE_CHUNKS + BLI_assert(data_len <= info->chunk_byte_size_max); + if (!BLI_listbase_is_empty(&chunk_list->chunk_refs)) { BChunkRef *cref = chunk_list->chunk_refs.last; BChunk *chunk_prev = cref->link; @@ -589,6 +645,59 @@ static void bchunk_list_append_data( #endif } +/** + * Similar to #bchunk_list_append_data, but handle multiple chunks. + * Use for adding arrays of arbitrary sized memory at once. + * + * \note This function takes care not to perform redundant chunk-merging checks, + * so we can write succesive fixed size chunks quickly. + */ +static void bchunk_list_append_data_n( + const BArrayInfo *info, BArrayMemory *bs_mem, + BChunkList *chunk_list, + const ubyte *data, size_t data_len) +{ + size_t data_trim_len, data_last_chunk_len; + bchunk_list_calc_trim_len(info, data_len, &data_trim_len, &data_last_chunk_len); + + if (data_trim_len != 0) { + size_t i_prev; + + { + const size_t i = info->chunk_byte_size; + bchunk_list_append_data(info, bs_mem, chunk_list, data, i); + i_prev = i; + } + + while (i_prev != data_trim_len) { + const size_t i = i_prev + info->chunk_byte_size; + BChunk *chunk = bchunk_new_copydata(bs_mem, &data[i_prev], i - i_prev); + bchunk_list_append_only(bs_mem, chunk_list, chunk); + i_prev = i; + } + + if (data_last_chunk_len) { + BChunk *chunk = bchunk_new_copydata(bs_mem, &data[i_prev], data_last_chunk_len); + bchunk_list_append_only(bs_mem, chunk_list, chunk); + // i_prev = data_len; /* UNUSED */ + } + } + else { + /* if we didn't write any chunks previously, + * we may need to merge with the last. */ + if (data_last_chunk_len) { + bchunk_list_append_data(info, bs_mem, chunk_list, data, data_last_chunk_len); + // i_prev = data_len; /* UNUSED */ + } + } + +#ifdef USE_MERGE_CHUNKS + if (data_len > info->chunk_byte_size) { + BLI_assert(((BChunkRef *)chunk_list->chunk_refs.last)->link->data_len >= info->chunk_byte_size_min); + } +#endif +} + static void bchunk_list_append( const BArrayInfo *info, BArrayMemory *bs_mem, BChunkList *chunk_list, @@ -611,37 +720,11 @@ static void bchunk_list_fill_from_array( { BLI_assert(BLI_listbase_is_empty(&chunk_list->chunk_refs)); - size_t data_last_chunk_len = 0; - size_t data_trim_len = data_len; - -#ifdef USE_MERGE_CHUNKS - /* avoid creating too-small chunks - * more efficient then merging after */ - if (data_len > info->chunk_byte_size) { - data_last_chunk_len = (data_trim_len % info->chunk_byte_size); - data_trim_len = data_trim_len - data_last_chunk_len; - if (data_last_chunk_len) { - if (data_last_chunk_len < info->chunk_byte_size_min) { - /* may be zero and thats OK */ - data_trim_len -= info->chunk_byte_size; - data_last_chunk_len += info->chunk_byte_size; - } - } - } - else { - data_trim_len = 0; - data_last_chunk_len = data_len; - } -#else - data_last_chunk_len = (data_trim_len % info->chunk_byte_size); - data_trim_len = data_trim_len - data_last_chunk_len; -#endif - - - BLI_assert(data_trim_len + data_last_chunk_len == data_len); + size_t data_trim_len, data_last_chunk_len; + bchunk_list_calc_trim_len(info, data_len, &data_trim_len, &data_last_chunk_len); size_t i_prev = 0; - while (i_prev < data_trim_len) { + while (i_prev != data_trim_len) { const size_t i = i_prev + info->chunk_byte_size; BChunk *chunk = bchunk_new_copydata(bs_mem, &data[i_prev], i - i_prev); bchunk_list_append_only(bs_mem, chunk_list, chunk); @@ -1220,21 +1303,8 @@ static BChunkList *bchunk_list_from_data_merge( if (cref_found != NULL) { BLI_assert(i < data_len); if (i != i_prev) { - size_t i_step = MIN2(i_prev + info->chunk_byte_size, data_len); - BLI_assert(i_step <= data_len); - - while (i_prev != i) { - i_step = MIN2(i_step, i); - const ubyte *data_slice = &data[i_prev]; - const size_t data_slice_len = i_step - i_prev; - /* First add all previous chunks! */ - i_prev += data_slice_len; - bchunk_list_append_data(info, bs_mem, chunk_list, data_slice, data_slice_len); - BLI_assert(i_prev <= data_len); - ASSERT_CHUNKLIST_SIZE(chunk_list, i_prev); - ASSERT_CHUNKLIST_DATA(chunk_list, data); - i_step += info->chunk_byte_size; - } + bchunk_list_append_data_n(info, bs_mem, chunk_list, &data[i_prev], i - i_prev); + i_prev = i; } /* now add the reference chunk */ @@ -1294,14 +1364,9 @@ static BChunkList *bchunk_list_from_data_merge( * * Trailing chunks, no matches found in table lookup above. * Write all new data. */ - BLI_assert(i_prev <= data_len); - while (i_prev != data_len) { - size_t i = i_prev + info->chunk_byte_size; - i = MIN2(i, data_len); - BLI_assert(i != i_prev); - bchunk_list_append_data(info, bs_mem, chunk_list, &data[i_prev], i - i_prev); - ASSERT_CHUNKLIST_DATA(chunk_list, data); - i_prev = i; + if (i_prev != data_len) { + bchunk_list_append_data_n(info, bs_mem, chunk_list, &data[i_prev], data_len - i_prev); + i_prev = data_len; } BLI_assert(i_prev == data_len); @@ -1374,6 +1439,7 @@ BArrayStore *BLI_array_store_create( bs->info.chunk_byte_size = chunk_count * stride; #ifdef USE_MERGE_CHUNKS bs->info.chunk_byte_size_min = MAX2(1u, chunk_count / BCHUNK_SIZE_MIN_DIV) * stride; + bs->info.chunk_byte_size_max = (chunk_count * BCHUNK_SIZE_MAX_MUL) * stride; #endif #ifdef USE_HASH_TABLE_ACCUMULATE @@ -1640,6 +1706,21 @@ bool BLI_array_store_is_valid( if (!(bchunk_list_size(chunk_list) == chunk_list->total_size)) { return false; } + + if (BLI_listbase_count(&chunk_list->chunk_refs) != (int)chunk_list->chunk_refs_len) { + return false; + } + +#ifdef USE_MERGE_CHUNKS + /* ensure we merge all chunks that could be merged */ + if (chunk_list->total_size > bs->info.chunk_byte_size_min) { + for (BChunkRef *cref = chunk_list->chunk_refs.first; cref; cref = cref->next) { + if (cref->link->data_len < bs->info.chunk_byte_size_min) { + return false; + } + } + } +#endif } { diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c index c3a0c44d7c5..f834c5b4c74 100644 --- a/source/blender/blenlib/intern/noise.c +++ b/source/blender/blenlib/intern/noise.c @@ -1048,8 +1048,8 @@ static float noise3_perlin(float vec[3]) b01 = p[i + by1]; b11 = p[j + by1]; -#define VALUE_AT(rx, ry, rz) (rx * q[0] + ry * q[1] + rz * q[2]) -#define SURVE(t) (t * t * (3.0f - 2.0f * t)) +#define VALUE_AT(rx, ry, rz) ((rx) * q[0] + (ry) * q[1] + (rz) * q[2]) +#define SURVE(t) ((t) * (t) * (3.0f - 2.0f * (t))) /* lerp moved to improved perlin above */ diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index f7e3622e53c..0ed1dffcafb 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -198,6 +198,12 @@ typedef struct BevelParams { // #include "bevdebug.c" +/* some flags to re-enable old behavior for a while, in case fixes broke things not caught by regression tests */ +static int bev_debug_flags = 0; +#define DEBUG_OLD_PLANE_SPECIAL (bev_debug_flags & 1) +#define DEBUG_OLD_PROJ_TO_PERP_PLANE (bev_debug_flags & 2) +#define DEBUG_OLD_FLAT_MID (bev_debug_flags & 4) + /* Make a new BoundVert of the given kind, insert it at the end of the circular linked * list with entry point bv->boundstart, and return it. */ static BoundVert *add_new_bound_vert(MemArena *mem_arena, VMesh *vm, const float co[3]) @@ -1045,15 +1051,21 @@ static void set_profile_params(BevelParams *bp, BevVert *bv, BoundVert *bndv) sub_v3_v3v3(pro->proj_dir, e->e->v1->co, e->e->v2->co); normalize_v3(pro->proj_dir); project_to_edge(e->e, co1, co2, pro->midco); - /* put arc endpoints on plane with normal proj_dir, containing midco */ - add_v3_v3v3(co3, co1, pro->proj_dir); - if (!isect_line_plane_v3(pro->coa, co1, co3, pro->midco, pro->proj_dir)) { - /* shouldn't happen */ - copy_v3_v3(pro->coa, co1); + if (DEBUG_OLD_PROJ_TO_PERP_PLANE) { + /* put arc endpoints on plane with normal proj_dir, containing midco */ + add_v3_v3v3(co3, co1, pro->proj_dir); + if (!isect_line_plane_v3(pro->coa, co1, co3, pro->midco, pro->proj_dir)) { + /* shouldn't happen */ + copy_v3_v3(pro->coa, co1); + } + add_v3_v3v3(co3, co2, pro->proj_dir); + if (!isect_line_plane_v3(pro->cob, co2, co3, pro->midco, pro->proj_dir)) { + /* shouldn't happen */ + copy_v3_v3(pro->cob, co2); + } } - add_v3_v3v3(co3, co2, pro->proj_dir); - if (!isect_line_plane_v3(pro->cob, co2, co3, pro->midco, pro->proj_dir)) { - /* shouldn't happen */ + else { + copy_v3_v3(pro->coa, co1); copy_v3_v3(pro->cob, co2); } /* default plane to project onto is the one with triangle co1 - midco - co2 in it */ @@ -1066,19 +1078,48 @@ static void set_profile_params(BevelParams *bp, BevVert *bv, BoundVert *bndv) if (l <= BEVEL_EPSILON_BIG) { /* co1 - midco -co2 are collinear. * Should be case that beveled edge is coplanar with two boundary verts. + * We want to move the profile to that common plane, if possible. + * That makes the multi-segment bevels curve nicely in that plane, as users expect. + * The new midco should be either v (when neighbor edges are unbeveled) + * or the intersection of the offset lines (if they are). * If the profile is going to lead into unbeveled edges on each side * (that is, both BoundVerts are "on-edge" points on non-beveled edges) - * then in order to get curve in multi-segment case, change projection plane - * to be that common plane, projection dir to be the plane normal, - * and mid to be the original vertex. - * Otherwise, we just want to linearly interpolate between co1 and co2. */ - if (e->prev->is_bev || e->next->is_bev) { + if (DEBUG_OLD_PLANE_SPECIAL && (e->prev->is_bev || e->next->is_bev)) { do_linear_interp = true; } else { - copy_v3_v3(pro->coa, co1); - copy_v3_v3(pro->midco, bv->v->co); + if (DEBUG_OLD_PROJ_TO_PERP_PLANE) { + copy_v3_v3(pro->coa, co1); + copy_v3_v3(pro->cob, co2); + } + if (DEBUG_OLD_FLAT_MID) { + copy_v3_v3(pro->midco, bv->v->co); + } + else { + copy_v3_v3(pro->midco, bv->v->co); + if (e->prev->is_bev && e->next->is_bev && bv->selcount >= 3) { + /* want mid at the meet point of next and prev offset edges */ + float d3[3], d4[3], co4[3], meetco[3], isect2[3]; + int isect_kind; + + sub_v3_v3v3(d3, e->prev->e->v1->co, e->prev->e->v2->co); + sub_v3_v3v3(d4, e->next->e->v1->co, e->next->e->v2->co); + normalize_v3(d3); + normalize_v3(d4); + add_v3_v3v3(co3, co1, d3); + add_v3_v3v3(co4, co2, d4); + isect_kind = isect_line_line_v3(co1, co3, co2, co4, meetco, isect2); + if (isect_kind != 0) { + copy_v3_v3(pro->midco, meetco); + } + else { + /* offset lines are collinear - want linear interpolation */ + mid_v3_v3v3(pro->midco, co1, co2); + do_linear_interp = true; + } + } + } copy_v3_v3(pro->cob, co2); sub_v3_v3v3(d1, pro->midco, co1); normalize_v3(d1); @@ -3436,7 +3477,7 @@ static bool fast_bevel_edge_order(BevVert *bv) } } if (nsucs == 0 || (nsucs == 2 && j != 1) || nsucs > 2 || - (j == bv->edgecount - 1 && !edges_face_connected_at_vert(bmenext, bv->edges[0].e))) + (j == bv->edgecount - 1 && !edges_face_connected_at_vert(bmenext, bv->edges[0].e))) { for (k = 1; k < j; k++) { BM_BEVEL_EDGE_TAG_DISABLE(bv->edges[k].e); @@ -3868,7 +3909,7 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f) /* going cw */ if (vm->seg > 1) { if (vm->mesh_kind == M_ADJ || bp->vertex_only || - (vm->mesh_kind == M_NONE && v->ebev != e && v->ebev != eprev)) + (vm->mesh_kind == M_NONE && v->ebev != e && v->ebev != eprev)) { i = v->prev->index; for (k = vm->seg - 1; k > 0; k--) { diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp index fca9b9ffa55..1bc2bff74e3 100644 --- a/source/blender/collada/ArmatureImporter.cpp +++ b/source/blender/collada/ArmatureImporter.cpp @@ -107,27 +107,39 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon std::vector<COLLADAFW::Node *>::iterator it; it = std::find(finished_joints.begin(), finished_joints.end(), node); if (it != finished_joints.end()) return chain_length; - - // JointData* jd = get_joint_data(node); - // TODO rename from Node "name" attrs later EditBone *bone = ED_armature_edit_bone_add(arm, (char *)bc_get_joint_name(node)); totbone++; - if (skin && skin->get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) { - // get original world-space matrix - invert_m4_m4(mat, joint_inv_bind_mat); + /* + * We use the inv_bind_shape matrix to apply the armature bind pose as its rest pose. + */ + + std::map<COLLADAFW::UniqueId, SkinInfo>::iterator skin_it; + bool bone_is_not_skinned = true; + for (skin_it = skin_by_data_uid.begin(); skin_it != skin_by_data_uid.end(); skin_it++) { + + SkinInfo *b = &skin_it->second; + if (b->get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) { - // And make local to armature - Object *ob_arm = skin->BKE_armature_from_object(); - if (ob_arm) { - float invmat[4][4]; - invert_m4_m4(invmat, ob_arm->obmat); - mul_m4_m4m4(mat, invmat, mat); + // get original world-space matrix + invert_m4_m4(mat, joint_inv_bind_mat); + + // And make local to armature + Object *ob_arm = skin->BKE_armature_from_object(); + if (ob_arm) { + float invmat[4][4]; + invert_m4_m4(invmat, ob_arm->obmat); + mul_m4_m4m4(mat, invmat, mat); + } + + bone_is_not_skinned = false; + break; } } + // create a bone even if there's no joint data for it (i.e. it has no influence) - else { + if (bone_is_not_skinned) { float obmat[4][4]; // bone-space get_node_mat(obmat, node, NULL, NULL); @@ -145,7 +157,7 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon float loc[3], size[3], rot[3][3]; - BoneExtended &be = add_bone_extended(bone, node, layer_labels); + BoneExtended &be = add_bone_extended(bone, node, totchild, layer_labels); int layer = be.get_bone_layers(); if (layer) bone->layer = layer; arm->layer |= layer; // ensure that all populated bone layers are visible after import @@ -168,7 +180,6 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon mat4_to_loc_rot_size(loc, rot, size, mat); mat3_to_vec_roll(rot, NULL, &angle); } - copy_v3_v3(bone->head, mat[3]); add_v3_v3v3(bone->tail, bone->head, tail); //tail must be non zero @@ -434,12 +445,12 @@ ArmatureJoints& ArmatureImporter::get_armature_joints(Object *ob_arm) return armature_joints.back(); } #endif -void ArmatureImporter::create_armature_bones( ) +Object *ArmatureImporter::create_armature_bones(std::vector<Object *> &ob_arms) { std::vector<COLLADAFW::Node *>::iterator ri; std::vector<std::string> layer_labels; + Object *ob_arm = NULL; - leaf_bone_length = FLT_MAX; //if there is an armature created for root_joint next root_joint for (ri = root_joints.begin(); ri != root_joints.end(); ri++) { if (get_armature_for_joint(*ri) != NULL) continue; @@ -467,34 +478,21 @@ void ArmatureImporter::create_armature_bones( ) create_bone(NULL, *ri , NULL, (*ri)->getChildNodes().getCount(), NULL, armature, layer_labels); /* exit armature edit mode to populate the Armature object */ + unskinned_armature_map[(*ri)->getUniqueId()] = ob_arm; ED_armature_from_edit(armature); ED_armature_edit_free(armature); - /* and step back to edit mode to fix the leaf nodes */ - ED_armature_to_edit(armature); - - if (this->import_settings->fix_orientation || this->import_settings->find_chains) { - - if (this->import_settings->find_chains) - connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX); - - if (this->import_settings->fix_orientation) - fix_leaf_bones(armature, (Bone *)armature->bonebase.first); - - // exit armature edit mode - unskinned_armature_map[(*ri)->getUniqueId()] = ob_arm; + int index = std::find(ob_arms.begin(), ob_arms.end(), ob_arm) - ob_arms.begin(); + if (index == 0) { + ob_arms.push_back(ob_arm); } - fix_parent_connect(armature, (Bone *)armature->bonebase.first); - - ED_armature_from_edit(armature); - ED_armature_edit_free(armature); - DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA); } + return ob_arm; } -void ArmatureImporter::create_armature_bones(SkinInfo& skin) +Object *ArmatureImporter::create_armature_bones(SkinInfo& skin) { // just do like so: // - get armature @@ -590,7 +588,6 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin) totbone = 0; // bone_direction_row = 1; // TODO: don't default to Y but use asset and based on it decide on default row - leaf_bone_length = FLT_MAX; // create bones /* @@ -606,6 +603,7 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin) // since root_joints may contain joints for multiple controllers, we need to filter if (skin.uses_joint_or_descendant(*ri)) { + create_bone(&skin, *ri, NULL, (*ri)->getChildNodes().getCount(), NULL, armature, layer_labels); if (joint_parent_map.find((*ri)->getUniqueId()) != joint_parent_map.end() && !skin.get_parent()) @@ -617,18 +615,9 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin) ED_armature_from_edit(armature); ED_armature_edit_free(armature); - /* and step back to edit mode to fix the leaf nodes */ - ED_armature_to_edit(armature); - - if (armature->bonebase.first) { - /* Do this only if Armature has bones */ - //connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX); - //fix_leaf_bones(armature, (Bone *)armature->bonebase.first); - } - // exit armature edit mode - ED_armature_from_edit(armature); - ED_armature_edit_free(armature); DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA); + + return ob_arm; } void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[4][4]) @@ -703,22 +692,42 @@ void ArmatureImporter::add_root_joint(COLLADAFW::Node *node) #endif // here we add bones to armatures, having armatures previously created in write_controller -void ArmatureImporter::make_armatures(bContext *C) +void ArmatureImporter::make_armatures(bContext *C, std::vector<Object *> &objects_to_scale) { + std::vector<Object *> ob_arms; std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it; + + leaf_bone_length = FLT_MAX; /*TODO: Make this work for more than one armature in the import file*/ + for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { SkinInfo& skin = it->second; - create_armature_bones(skin); + Object *ob_arm = create_armature_bones(skin); // link armature with a mesh object const COLLADAFW::UniqueId &uid = skin.get_controller_uid(); const COLLADAFW::UniqueId *guid = get_geometry_uid(uid); if (guid != NULL) { Object *ob = mesh_importer->get_object_by_geom_uid(*guid); - if (ob) + if (ob) { skin.link_armature(C, ob, joint_by_uid, this); + + std::vector<Object *>::iterator ob_it = std::find(objects_to_scale.begin(), objects_to_scale.end(), ob); + + if (ob_it != objects_to_scale.end()) { + int index = ob_it - objects_to_scale.begin(); + objects_to_scale.erase(objects_to_scale.begin() + index); + } + + if (std::find(objects_to_scale.begin(), objects_to_scale.end(), ob_arm) == objects_to_scale.end()) { + objects_to_scale.push_back(ob_arm); + } + + if (std::find(ob_arms.begin(), ob_arms.end(), ob_arm) == ob_arms.end()) { + ob_arms.push_back(ob_arm); + } + } else fprintf(stderr, "Cannot find object to link armature with.\n"); } @@ -735,7 +744,35 @@ void ArmatureImporter::make_armatures(bContext *C) } //for bones without skins - create_armature_bones(); + create_armature_bones(ob_arms); + + // Fix bone relations + std::vector<Object *>::iterator ob_arm_it; + for (ob_arm_it = ob_arms.begin(); ob_arm_it != ob_arms.end(); ob_arm_it++) { + + Object *ob_arm = *ob_arm_it; + bArmature *armature = (bArmature *)ob_arm->data; + + /* and step back to edit mode to fix the leaf nodes */ + ED_armature_to_edit(armature); + + if (this->import_settings->fix_orientation || this->import_settings->find_chains) { + + if (this->import_settings->find_chains) + connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX); + + if (this->import_settings->fix_orientation) + fix_leaf_bones(armature, (Bone *)armature->bonebase.first); + + // exit armature edit mode + + } + + fix_parent_connect(armature, (Bone *)armature->bonebase.first); + + ED_armature_from_edit(armature); + ED_armature_edit_free(armature); + } } #if 0 @@ -922,7 +959,7 @@ bool ArmatureImporter::get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint) return found; } -BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Node *node, std::vector<std::string> &layer_labels) +BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Node *node, int sibcount, std::vector<std::string> &layer_labels) { BoneExtended *be = new BoneExtended(bone); extended_bones[bone->name] = be; @@ -930,11 +967,14 @@ BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Nod TagsMap::iterator etit; ExtraTags *et = 0; etit = uid_tags_map.find(node->getUniqueId().toAscii()); + + bool has_connect = false; + int connect_type = -1; + if (etit != uid_tags_map.end()) { float tail[3] = { FLT_MAX, FLT_MAX, FLT_MAX }; float roll = 0; - int use_connect = -1; std::string layers; et = etit->second; @@ -944,21 +984,29 @@ BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Nod has_tail |= et->setData("tip_y", &tail[1]); has_tail |= et->setData("tip_z", &tail[2]); - bool has_connect = et->setData("connect", &use_connect); - bool has_roll = et->setData("roll", &roll); + has_connect = et->setData("connect", &connect_type); + bool has_roll = et->setData("roll", &roll); layers = et->setData("layer", layers); if (has_tail && !has_connect) { - use_connect = 0; // got a bone tail definition but no connect info -> bone is not connected + /* got a bone tail definition but no connect info -> bone is not connected */ + has_connect = true; + connect_type = 0; } be->set_bone_layers(layers, layer_labels); if (has_tail) be->set_tail(tail); if (has_roll) be->set_roll(roll); - be->set_use_connect(use_connect); } + + if (!has_connect && this->import_settings->auto_connect) { + /* auto connect only whyen parent has exactly one child*/ + connect_type = sibcount == 1; + } + + be->set_use_connect(connect_type); be->set_leaf_bone(true); return *be; diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h index f38bd1a6c66..e006ccbc94a 100644 --- a/source/blender/collada/ArmatureImporter.h +++ b/source/blender/collada/ArmatureImporter.h @@ -108,7 +108,7 @@ private: int create_bone(SkinInfo* skin, COLLADAFW::Node *node, EditBone *parent, int totchild, float parent_mat[4][4], bArmature *arm, std::vector<std::string> &layer_labels); - BoneExtended &add_bone_extended(EditBone *bone, COLLADAFW::Node * node, std::vector<std::string> &layer_labels); + BoneExtended &add_bone_extended(EditBone *bone, COLLADAFW::Node * node, int sibcount, std::vector<std::string> &layer_labels); void clear_extended_boneset(); void fix_leaf_bones(bArmature *armature, Bone *bone); @@ -131,8 +131,8 @@ private: ArmatureJoints& get_armature_joints(Object *ob_arm); #endif - void create_armature_bones(SkinInfo& skin); - void create_armature_bones( ); + Object *create_armature_bones(SkinInfo& skin); + Object *create_armature_bones(std::vector<Object *> &arm_objs); /** TagsMap typedef for uid_tags_map. */ typedef std::map<std::string, ExtraTags*> TagsMap; @@ -145,7 +145,7 @@ public: void add_root_joint(COLLADAFW::Node *node, Object *parent); // here we add bones to armatures, having armatures previously created in write_controller - void make_armatures(bContext *C); + void make_armatures(bContext *C, std::vector<Object *> &objects_to_scale); void make_shape_keys(); diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index 45dcf436473..3a709da78e1 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -239,7 +239,7 @@ void DocumentImporter::finish() mesh_importer.optimize_material_assignements(); armature_importer.set_tags_map(this->uid_tags_map); - armature_importer.make_armatures(mContext); + armature_importer.make_armatures(mContext, *objects_to_scale); armature_importer.make_shape_keys(); DAG_relations_tag_update(bmain); @@ -517,7 +517,7 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA name.c_str()); if (is_joint) { - if (parent_node == NULL) { + if (parent_node == NULL && !is_library_node) { // A Joint on root level is a skeleton without root node. // Here we add the armature "on the fly": par = bc_add_object(sce, OB_ARMATURE, std::string("Armature").c_str()); diff --git a/source/blender/collada/ImportSettings.h b/source/blender/collada/ImportSettings.h index 783f58e6bff..2c52d73e756 100644 --- a/source/blender/collada/ImportSettings.h +++ b/source/blender/collada/ImportSettings.h @@ -33,6 +33,7 @@ struct ImportSettings { public: bool import_units; bool find_chains; + bool auto_connect; bool fix_orientation; int min_chain_length; char *filepath; diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp index 76f24545248..3adddddb8e7 100644 --- a/source/blender/collada/MeshImporter.cpp +++ b/source/blender/collada/MeshImporter.cpp @@ -211,15 +211,27 @@ void VCOLDataWrapper::get_vcol(int v_index, MLoopCol *mloopcol) MeshImporter::MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce) : unitconverter(unitconv), scene(sce), armature_importer(arm) { } -void MeshImporter::set_poly_indices(MPoly *mpoly, MLoop *mloop, int loop_index, unsigned int *indices, int loop_count) +bool MeshImporter::set_poly_indices(MPoly *mpoly, MLoop *mloop, int loop_index, unsigned int *indices, int loop_count) { mpoly->loopstart = loop_index; mpoly->totloop = loop_count; - + bool broken_loop = false; for (int index=0; index < loop_count; index++) { + + /* Test if loop defines a hole */ + if (!broken_loop) { + for (int i = 0; i < index; i++) { + if (indices[i] == indices[index]) { + // duplicate index -> not good + broken_loop = true; + } + } + } + mloop->v = indices[index]; mloop++; } + return broken_loop; } void MeshImporter::set_vcol(MLoopCol *mlc, VCOLDataWrapper &vob, int loop_index, COLLADAFW::IndexList &index_list, int count) @@ -698,6 +710,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me) COLLADAFW::IndexListArray& index_list_array_uvcoord = mp->getUVCoordIndicesArray(); COLLADAFW::IndexListArray& index_list_array_vcolor = mp->getColorIndicesArray(); + int invalid_loop_holes = 0; for (unsigned int j = 0; j < prim_totpoly; j++) { // Vertices in polygon: @@ -705,8 +718,12 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me) if (vcount < 0) { continue; // TODO: add support for holes } - set_poly_indices(mpoly, mloop, loop_index, position_indices, vcount); + bool broken_loop = set_poly_indices(mpoly, mloop, loop_index, position_indices, vcount); + if (broken_loop) + { + invalid_loop_holes += 1; + } for (unsigned int uvset_index = 0; uvset_index < index_list_array_uvcoord.getCount(); uvset_index++) { // get mtface by face index and uv set index @@ -754,6 +771,11 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me) position_indices += vcount; } + + if (invalid_loop_holes > 0) + { + fprintf(stderr, "Collada import: Mesh [%s] : contains %d unsupported loops (holes).\n", me->id.name, invalid_loop_holes); + } } else if (collada_meshtype == COLLADAFW::MeshPrimitive::LINES) { diff --git a/source/blender/collada/MeshImporter.h b/source/blender/collada/MeshImporter.h index 9d5fefb83f2..d6426fbaf56 100644 --- a/source/blender/collada/MeshImporter.h +++ b/source/blender/collada/MeshImporter.h @@ -109,7 +109,7 @@ private: std::map<COLLADAFW::UniqueId, MaterialIdPrimitiveArrayMap> geom_uid_mat_mapping_map; // crazy name! std::multimap<COLLADAFW::UniqueId, COLLADAFW::UniqueId> materials_mapped_to_geom; //< materials that have already been mapped to a geometry. A pair of geom uid and mat uid, one geometry can have several materials - void set_poly_indices(MPoly *mpoly, + bool set_poly_indices(MPoly *mpoly, MLoop *mloop, int loop_index, unsigned int *indices, diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp index 71875d6274a..7242a24523c 100644 --- a/source/blender/collada/SkinInfo.cpp +++ b/source/blender/collada/SkinInfo.cpp @@ -230,6 +230,7 @@ void SkinInfo::link_armature(bContext *C, Object *ob, std::map<COLLADAFW::Unique ModifierData *md = ED_object_modifier_add(NULL, bmain, scene, ob, NULL, eModifierType_Armature); ArmatureModifierData *amd = (ArmatureModifierData *)md; amd->object = ob_arm; + struct bArmature *armature = (bArmature *)ob_arm->data; #if 1 bc_set_parent(ob, ob_arm, C); diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp index e1b8a2dd30a..fe8b1d2320a 100644 --- a/source/blender/collada/collada.cpp +++ b/source/blender/collada/collada.cpp @@ -46,6 +46,7 @@ int collada_import(bContext *C, const char *filepath, int import_units, int find_chains, + int auto_connect, int fix_orientation, int min_chain_length) { @@ -53,6 +54,7 @@ int collada_import(bContext *C, ImportSettings import_settings; import_settings.filepath = (char *)filepath; import_settings.import_units = import_units != 0; + import_settings.auto_connect = auto_connect != 0; import_settings.find_chains = find_chains != 0; import_settings.fix_orientation = fix_orientation != 0; import_settings.min_chain_length = min_chain_length; diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h index db8ea884222..0017c66836a 100644 --- a/source/blender/collada/collada.h +++ b/source/blender/collada/collada.h @@ -57,6 +57,7 @@ int collada_import(struct bContext *C, const char *filepath, int import_units, int find_chains, + int auto_connect, int fix_orientation, int min_chain_length); diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h index 74f8dca1492..ee371f7959e 100644 --- a/source/blender/collada/collada_utils.h +++ b/source/blender/collada/collada_utils.h @@ -120,7 +120,7 @@ private: float roll; int bone_layers; - bool use_connect; + int use_connect; bool has_custom_tail; bool has_custom_roll; diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.cc b/source/blender/depsgraph/intern/nodes/deg_node_component.cc index c529e2ecfe6..7e49fec051f 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.cc @@ -230,6 +230,14 @@ void ComponentDepsNode::tag_update(Depsgraph *graph) foreach (OperationDepsNode *op_node, operations) { op_node->tag_update(graph); } + // It is possible that tag happens before finalization. + if (operations_map != NULL) { + GHASH_FOREACH_BEGIN(OperationDepsNode *, op_node, operations_map) + { + op_node->tag_update(graph); + } + GHASH_FOREACH_END(); + } } OperationDepsNode *ComponentDepsNode::get_entry_operation() diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index afc4e5c9e61..a82cca9e52a 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -753,7 +753,7 @@ EnumPropertyItem prop_driver_create_mapping_types[] = { "Create drivers for each pair of corresponding elements"}, {CREATEDRIVER_MAPPING_NONE_ALL, "NONE_ALL", ICON_HAND, "Manually Create Later", - "Create drivers for all properites without assigning any targets yet"}, + "Create drivers for all properties without assigning any targets yet"}, {CREATEDRIVER_MAPPING_NONE, "NONE_SINGLE", 0, "Manually Create Later (Single)", "Create driver for this property only and without assigning any targets yet"}, {0, NULL, 0, NULL, NULL} @@ -866,7 +866,7 @@ static int add_driver_button_exec(bContext *C, wmOperator *op) } /* Show menu or create drivers */ -static int add_driver_button_invoke(bContext *C, wmOperator *op, const wmEvent *event) +static int add_driver_button_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { PropertyRNA *prop; @@ -877,7 +877,8 @@ static int add_driver_button_invoke(bContext *C, wmOperator *op, const wmEvent * else { /* Show menu */ // TODO: This should get filtered by the enum filter - return WM_menu_invoke(C, op, event); + /* important to execute in the region we're currently in */ + return WM_menu_invoke_ex(C, op, WM_OP_INVOKE_DEFAULT); } } diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 5530e293edd..cc4c1809fbc 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -980,7 +980,11 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S if (ts->snap_mode == SCE_SNAP_MODE_VOLUME) { float size; if (peelObjectsSnapContext( - snap_context, mvalf, SNAP_ALL, + snap_context, mvalf, + &(const struct SnapObjectParams){ + .snap_select = SNAP_NOT_SELECTED, + .use_object_edit_cage = false, + }, (ts->snap_flag & SCE_SNAP_PEEL_OBJECT) != 0, loc, dummy_no, &size)) { @@ -1017,9 +1021,10 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S { if (ED_transform_snap_object_project_view3d( snap_context, + ts->snap_mode, &(const struct SnapObjectParams){ .snap_select = SNAP_NOT_SELECTED, - .snap_to = ts->snap_mode, + .use_object_edit_cage = false, }, mvalf, &dist_px, NULL, loc, dummy_no)) diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 18fdcb546b0..420f72fedb3 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -5004,9 +5004,10 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event) ED_transform_snap_object_project_view3d_mixed( snap_context, + SCE_SELECT_FACE, &(const struct SnapObjectParams){ - .snap_select = SNAP_NOT_OBEDIT, - .snap_to_flag = SCE_SELECT_FACE, + .snap_select = (vc.scene->obedit != NULL) ? SNAP_NOT_ACTIVE : SNAP_ALL, + .use_object_edit_cage = false, }, mval, NULL, true, location, NULL); diff --git a/source/blender/editors/include/ED_screen_types.h b/source/blender/editors/include/ED_screen_types.h index effecf43839..1c41b14a874 100644 --- a/source/blender/editors/include/ED_screen_types.h +++ b/source/blender/editors/include/ED_screen_types.h @@ -42,6 +42,7 @@ typedef struct ScreenAnimData { int sfra; /* frame that playback was started from */ int nextfra; /* next frame to go to (when ANIMPLAY_FLAG_USE_NEXT_FRAME is set) */ double last_duration; /* used for frame dropping */ + bool from_anim_edit; /* playback was invoked from animation editor */ } ScreenAnimData; /* for animplayer */ diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index 933f480a554..ebd2a3dcb7a 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -45,6 +45,7 @@ struct wmKeyMap; struct wmOperatorType; struct Main; struct SnapObjectContext; +struct SnapObjectParams; void transform_keymap_for_space(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap, int spaceid); void transform_operatortypes(void); @@ -161,25 +162,27 @@ void BIF_draw_manipulator(const struct bContext *C); typedef enum SnapSelect { SNAP_ALL = 0, SNAP_NOT_SELECTED = 1, - SNAP_NOT_OBEDIT = 2 + SNAP_NOT_ACTIVE = 2, } SnapSelect; #define SNAP_MIN_DISTANCE 30 bool peelObjectsTransform( - struct TransInfo *t, const float mval[2], - SnapSelect snap_select, bool use_peel_object, + struct TransInfo *t, + const float mval[2], + const bool use_peel_object, /* return args */ float r_loc[3], float r_no[3], float *r_thickness); bool peelObjectsSnapContext( struct SnapObjectContext *sctx, const float mval[2], - SnapSelect snap_select, bool use_peel_object, + const struct SnapObjectParams *params, + const bool use_peel_object, /* return args */ float r_loc[3], float r_no[3], float *r_thickness); bool snapObjectsTransform( - struct TransInfo *t, const float mval[2], SnapSelect snap_select, + struct TransInfo *t, const float mval[2], float *dist_px, /* return args */ float r_loc[3], float r_no[3]); diff --git a/source/blender/editors/include/ED_transform_snap_object_context.h b/source/blender/editors/include/ED_transform_snap_object_context.h index 900b7593f2e..baf4ed574cf 100644 --- a/source/blender/editors/include/ED_transform_snap_object_context.h +++ b/source/blender/editors/include/ED_transform_snap_object_context.h @@ -57,17 +57,12 @@ struct SnapObjectHitDepth { unsigned int ob_uuid; }; +/** parameters that define which objects will be used to snap. */ struct SnapObjectParams { - int snap_select; /* SnapSelect */ - union { - unsigned int snap_to : 4; - /* snap_target_flag: Snap to vert/edge/face. */ - unsigned int snap_to_flag : 4; - }; + /* special context sensitive handling for the active or selected object */ + char snap_select; /* use editmode cage */ - unsigned int use_object_edit : 1; - /* special context sensitive handling for the active object */ - unsigned int use_object_active : 1; + unsigned int use_object_edit_cage : 1; }; enum { @@ -93,6 +88,7 @@ void ED_transform_snap_object_context_set_editmesh_callbacks( bool ED_transform_snap_object_project_ray_ex( struct SnapObjectContext *sctx, + const unsigned short snap_to, const struct SnapObjectParams *params, const float ray_start[3], const float ray_normal[3], float *ray_depth, /* return args */ @@ -100,11 +96,13 @@ bool ED_transform_snap_object_project_ray_ex( struct Object **r_ob, float r_obmat[4][4]); bool ED_transform_snap_object_project_ray( SnapObjectContext *sctx, + const struct SnapObjectParams *params, const float ray_origin[3], const float ray_direction[3], float *ray_depth, float r_co[3], float r_no[3]); bool ED_transform_snap_object_project_ray_all( SnapObjectContext *sctx, + const unsigned short snap_to, const struct SnapObjectParams *params, const float ray_start[3], const float ray_normal[3], float ray_depth, bool sort, @@ -112,12 +110,14 @@ bool ED_transform_snap_object_project_ray_all( bool ED_transform_snap_object_project_view3d_ex( struct SnapObjectContext *sctx, + const unsigned short snap_to, const struct SnapObjectParams *params, const float mval[2], float *dist_px, float *ray_depth, float r_loc[3], float r_no[3], int *r_index); bool ED_transform_snap_object_project_view3d( struct SnapObjectContext *sctx, + const unsigned short snap_to, const struct SnapObjectParams *params, const float mval[2], float *dist_px, float *ray_depth, @@ -125,6 +125,7 @@ bool ED_transform_snap_object_project_view3d( float r_loc[3], float r_no[3]); bool ED_transform_snap_object_project_view3d_mixed( SnapObjectContext *sctx, + const unsigned short snap_to_flag, const struct SnapObjectParams *params, const float mval_fl[2], float *dist_px, bool use_depth, diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 10ab85a6142..5b8b8ae5bdb 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -634,6 +634,15 @@ PointerRNA *ui_handle_afterfunc_add_operator(wmOperatorType *ot, int opcontext, return ptr; } +/** + * Check if a #uiAfterFunc is needed for this button. + */ +static bool ui_afterfunc_check(const uiBlock *block, const uiBut *but) +{ + return (but->func || but->funcN || but->rename_func || but->optype || but->rnaprop || block->handle_func || + (but->type == UI_BTYPE_BUT_MENU && block->butm_func)); +} + static void ui_apply_but_func(bContext *C, uiBut *but) { uiAfterFunc *after; @@ -643,9 +652,7 @@ static void ui_apply_but_func(bContext *C, uiBut *but) * handling is done, i.e. menus are closed, in order to avoid conflicts * with these functions removing the buttons we are working with */ - if (but->func || but->funcN || block->handle_func || but->rename_func || - (but->type == UI_BTYPE_BUT_MENU && block->butm_func) || but->optype || but->rnaprop) - { + if (ui_afterfunc_check(block, but)) { after = ui_afterfunc_new(); if (but->func && ELEM(but, but->func_arg1, but->func_arg2)) { @@ -899,7 +906,8 @@ static void ui_apply_but_TEX(bContext *C, uiBut *but, uiHandleButtonData *data) * having typed something already. */ but->rename_orig = BLI_strdup(data->origstr); } - else { + /* only if there are afterfuncs, otherwise 'renam_orig' isn't freed */ + else if (ui_afterfunc_check(but->block, but)) { but->rename_orig = data->origstr; data->origstr = NULL; } diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 7a9c3e827cf..ff29a6f8e33 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -897,7 +897,7 @@ static int edittranslation_exec(bContext *C, wmOperator *op) } ot = WM_operatortype_find(EDTSRC_I18N_OP_NAME, 0); if (ot == NULL) { - BKE_reportf(op->reports, RPT_ERROR, "Could not find operator '%s'! Please enable ui_translate addon " + BKE_reportf(op->reports, RPT_ERROR, "Could not find operator '%s'! Please enable ui_translate add-on " "in the User Preferences", EDTSRC_I18N_OP_NAME); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 2bbd5b8dde8..d4d3e1af1fd 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -2327,6 +2327,12 @@ static void ui_block_colorpicker(uiBlock *block, float rgba[4], PointerRNA *ptr, RNA_property_float_range(ptr, prop, &hardmin, &hardmax); RNA_property_float_get_array(ptr, prop, rgba); + /* when the softmax isn't defined in the RNA, + * using very large numbers causes sRGB/linear round trip to fail. */ + if (softmax == FLT_MAX) { + softmax = 1.0f; + } + switch (U.color_picker_type) { case USER_CP_SQUARE_SV: ui_colorpicker_square(block, ptr, prop, UI_GRAD_SV, cpicker); diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c index acb8e8e7512..b1ca95efe04 100644 --- a/source/blender/editors/io/io_collada.c +++ b/source/blender/editors/io/io_collada.c @@ -379,6 +379,7 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op) char filename[FILE_MAX]; int import_units; int find_chains; + int auto_connect; int fix_orientation; int min_chain_length; @@ -390,6 +391,7 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op) /* Options panel */ import_units = RNA_boolean_get(op->ptr, "import_units"); find_chains = RNA_boolean_get(op->ptr, "find_chains"); + auto_connect = RNA_boolean_get(op->ptr, "auto_connect"); fix_orientation = RNA_boolean_get(op->ptr, "fix_orientation"); min_chain_length = RNA_int_get(op->ptr, "min_chain_length"); @@ -398,6 +400,7 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op) C, filename, import_units, find_chains, + auto_connect, fix_orientation, min_chain_length)) { @@ -432,6 +435,9 @@ static void uiCollada_importSettings(uiLayout *layout, PointerRNA *imfptr) uiItemR(row, imfptr, "find_chains", 0, NULL, ICON_NONE); row = uiLayoutRow(box, false); + uiItemR(row, imfptr, "auto_connect", 0, NULL, ICON_NONE); + + row = uiLayoutRow(box, false); uiItemR(row, imfptr, "min_chain_length", 0, NULL, ICON_NONE); } @@ -474,6 +480,10 @@ void WM_OT_collada_import(wmOperatorType *ot) "find_chains", 0, "Find Bone Chains", "Find best matching Bone Chains and ensure bones in chain are connected"); + RNA_def_boolean(ot->srna, + "auto_connect", 0, "Auto Connect", + "set use_connect for parent bones which have exactly one child bone"); + RNA_def_int(ot->srna, "min_chain_length", 0, diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index ba17684dd39..efe179790da 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -312,9 +312,10 @@ void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em) if (ED_view3d_project_float_object(ar, eve->co, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { if (ED_transform_snap_object_project_view3d_mixed( snap_context, + SCE_SELECT_FACE, &(const struct SnapObjectParams){ - .snap_select = SNAP_NOT_OBEDIT, - .snap_to_flag = SCE_SELECT_FACE, + .snap_select = SNAP_NOT_ACTIVE, + .use_object_edit_cage = false, }, mval, NULL, true, co_proj, NULL)) diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 23c6aa37a83..a459f982ada 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -2070,7 +2070,10 @@ void ED_screen_animation_timer(bContext *C, int redraws, int refresh, int sync, sad->refresh = refresh; sad->flag |= (enable < 0) ? ANIMPLAY_FLAG_REVERSE : 0; sad->flag |= (sync == 0) ? ANIMPLAY_FLAG_NO_SYNC : (sync == 1) ? ANIMPLAY_FLAG_SYNC : 0; - + + ScrArea *sa = CTX_wm_area(C); + sad->from_anim_edit = (ELEM(sa->spacetype, SPACE_IPO, SPACE_ACTION, SPACE_NLA, SPACE_TIME)); + screen->animtimer->customdata = sad; } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 4111f67553a..f340f716ccb 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3355,24 +3355,24 @@ static int match_area_with_refresh(int spacetype, int refresh) return 0; } -static int match_region_with_redraws(int spacetype, int regiontype, int redraws) +static int match_region_with_redraws(int spacetype, int regiontype, int redraws, bool from_anim_edit) { if (regiontype == RGN_TYPE_WINDOW) { switch (spacetype) { case SPACE_VIEW3D: - if (redraws & TIME_ALL_3D_WIN) + if ((redraws & TIME_ALL_3D_WIN) || from_anim_edit) return 1; break; case SPACE_IPO: case SPACE_ACTION: case SPACE_NLA: - if (redraws & TIME_ALL_ANIM_WIN) + if ((redraws & TIME_ALL_ANIM_WIN) || from_anim_edit) return 1; break; case SPACE_TIME: /* if only 1 window or 3d windows, we do timeline too */ - if (redraws & (TIME_ALL_ANIM_WIN | TIME_REGION | TIME_ALL_3D_WIN)) + if ((redraws & (TIME_ALL_ANIM_WIN | TIME_REGION | TIME_ALL_3D_WIN)) || from_anim_edit) return 1; break; case SPACE_BUTS: @@ -3380,7 +3380,7 @@ static int match_region_with_redraws(int spacetype, int regiontype, int redraws) return 1; break; case SPACE_SEQ: - if (redraws & (TIME_SEQ | TIME_ALL_ANIM_WIN)) + if ((redraws & (TIME_SEQ | TIME_ALL_ANIM_WIN)) || from_anim_edit) return 1; break; case SPACE_NODE: @@ -3388,11 +3388,11 @@ static int match_region_with_redraws(int spacetype, int regiontype, int redraws) return 1; break; case SPACE_IMAGE: - if (redraws & TIME_ALL_IMAGE_WIN) + if ((redraws & TIME_ALL_IMAGE_WIN) || from_anim_edit) return 1; break; case SPACE_CLIP: - if (redraws & TIME_CLIPS) + if ((redraws & TIME_CLIPS) || from_anim_edit) return 1; break; @@ -3572,7 +3572,7 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv if (ar == sad->ar) { redraw = true; } - else if (match_region_with_redraws(sa->spacetype, ar->regiontype, sad->redraws)) { + else if (match_region_with_redraws(sa->spacetype, ar->regiontype, sad->redraws, sad->from_anim_edit)) { redraw = true; } diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index e4e9976c10d..eba9448aa40 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -1016,7 +1016,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) translation[1] = y; outline_alpha = 0.5; outline_col = brush->add_col; - final_radius = BKE_brush_size_get(scene, brush) * zoomx; + final_radius = (BKE_brush_size_get(scene, brush) * zoomx) / U.pixelsize; /* don't calculate rake angles while a stroke is active because the rake variables are global and * we may get interference with the stroke itself. For line strokes, such interference is visible */ diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index c0947dacbf0..8261a211ed0 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -707,10 +707,13 @@ static void insert_action_keys(bAnimContext *ac, short mode) * so it's easier for now to just read the F-Curve directly. * (TODO: add the full-blown PointerRNA relative parsing case here...) */ - if (ale->id && !ale->owner) + if (ale->id && !ale->owner) { insert_keyframe(reports, ale->id, NULL, ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, cfra, ts->keyframe_type, flag); - else - insert_vert_fcurve(fcu, cfra, fcu->curval, ts->keyframe_type, 0); + } + else { + const float curval = evaluate_fcurve(fcu, cfra); + insert_vert_fcurve(fcu, cfra, curval, ts->keyframe_type, 0); + } ale->update |= ANIM_UPDATE_DEFAULT; } diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index f1063996ca3..f38d36853d7 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -606,10 +606,13 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode) * - fcu->driver != NULL: If this is set, then it's a driver. If we don't check for this, we'd end * up adding the keyframes on a new F-Curve in the action data instead. */ - if (ale->id && !ale->owner && !fcu->driver) + if (ale->id && !ale->owner && !fcu->driver) { insert_keyframe(reports, ale->id, NULL, ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, cfra, ts->keyframe_type, flag); - else - insert_vert_fcurve(fcu, cfra, fcu->curval, ts->keyframe_type, 0); + } + else { + const float curval = evaluate_fcurve(fcu, cfra); + insert_vert_fcurve(fcu, cfra, curval, ts->keyframe_type, 0); + } ale->update |= ANIM_UPDATE_DEFAULT; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 727da41890a..9fe4f1cc283 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1181,10 +1181,10 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) if (scene->r.mode & R_BORDER) { float x3, y3, x4, y4; - x3 = x1i + 1 + roundf(scene->r.border.xmin * (x2 - x1)); - y3 = y1i + 1 + roundf(scene->r.border.ymin * (y2 - y1)); - x4 = x1i + 1 + roundf(scene->r.border.xmax * (x2 - x1)); - y4 = y1i + 1 + roundf(scene->r.border.ymax * (y2 - y1)); + x3 = floorf(x1 + (scene->r.border.xmin * (x2 - x1))) - 1; + y3 = floorf(y1 + (scene->r.border.ymin * (y2 - y1))) - 1; + x4 = floorf(x1 + (scene->r.border.xmax * (x2 - x1))) + (U.pixelsize - 1); + y4 = floorf(y1 + (scene->r.border.ymax * (y2 - y1))) + (U.pixelsize - 1); cpack(0x4040FF); sdrawbox(x3, y3, x4, y4); diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c index dfa76753f64..c6951c79609 100644 --- a/source/blender/editors/space_view3d/view3d_ruler.c +++ b/source/blender/editors/space_view3d/view3d_ruler.c @@ -679,9 +679,10 @@ static bool view3d_ruler_item_mousemove( if (ED_transform_snap_object_project_view3d_mixed( ruler_info->snap_context, + SCE_SELECT_FACE, &(const struct SnapObjectParams){ .snap_select = SNAP_ALL, - .snap_to_flag = SCE_SELECT_FACE, + .use_object_edit_cage = true, }, mval_fl, &dist_px, true, co, ray_normal)) @@ -691,6 +692,10 @@ static bool view3d_ruler_item_mousemove( madd_v3_v3v3fl(ray_start, co, ray_normal, eps_bias); ED_transform_snap_object_project_ray( ruler_info->snap_context, + &(const struct SnapObjectParams){ + .snap_select = SNAP_ALL, + .use_object_edit_cage = true, + }, ray_start, ray_normal, NULL, co_other, NULL); } @@ -703,9 +708,10 @@ static bool view3d_ruler_item_mousemove( if (ED_transform_snap_object_project_view3d_mixed( ruler_info->snap_context, + (SCE_SELECT_VERTEX | SCE_SELECT_EDGE) | (use_depth ? SCE_SELECT_FACE : 0), &(const struct SnapObjectParams){ .snap_select = SNAP_ALL, - .snap_to_flag = (SCE_SELECT_VERTEX | SCE_SELECT_EDGE) | (use_depth ? SCE_SELECT_FACE : 0), + .use_object_edit_cage = true, }, mval_fl, &dist_px, use_depth, co, NULL)) diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c index 47f81678699..384da277612 100644 --- a/source/blender/editors/space_view3d/view3d_walk.c +++ b/source/blender/editors/space_view3d/view3d_walk.c @@ -49,6 +49,7 @@ #include "ED_screen.h" #include "ED_space_api.h" +#include "ED_transform.h" #include "ED_transform_snap_object_context.h" #include "PIL_time.h" /* smoothview */ @@ -424,6 +425,9 @@ static bool walk_floor_distance_get( ret = ED_transform_snap_object_project_ray( walk->snap_context, + &(const struct SnapObjectParams){ + .snap_select = SNAP_ALL, + }, ray_start, ray_normal, r_distance, r_location, r_normal_dummy); @@ -455,6 +459,9 @@ static bool walk_ray_cast( ret = ED_transform_snap_object_project_ray( walk->snap_context, + &(const struct SnapObjectParams){ + .snap_select = SNAP_ALL, + }, ray_start, ray_normal, NULL, r_location, r_normal); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 5c0c0bcd6c1..5b1a58497f0 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2863,7 +2863,7 @@ static void initBend(TransInfo *t) //copy_v3_v3(t->center, ED_view3d_cursor3d_get(t->scene, t->view)); calculateCenterCursor(t, t->center); - calculateCenterGlobal(t); + calculateCenterGlobal(t, t->center, t->center_global); t->val = 0.0f; diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 11151a9c65a..0e0d085bf6f 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -369,6 +369,11 @@ typedef struct TransCustomData { unsigned int use_free : 1; } TransCustomData; +typedef struct TransCenterData { + float local[3], global[3]; + unsigned int is_set : 1; +} TransCenterData; + typedef struct TransInfo { int mode; /* current mode */ int flag; /* generic flags for special behaviors */ @@ -396,6 +401,9 @@ typedef struct TransInfo { float center[3]; /* center of transformation (in local-space) */ float center_global[3]; /* center of transformation (in global-space) */ float center2d[2]; /* center in screen coordinates */ + /* Lazy initialize center data for when we need other center values. + * V3D_AROUND_ACTIVE + 1 (static assert checks this) */ + TransCenterData center_cache[5]; short idx_max; /* maximum index on the input vector */ float snap[3]; /* Snapping Gears */ float snap_spatial[3]; /* Spatial snapping gears(even when rotating, scaling... etc) */ @@ -742,8 +750,11 @@ void restoreTransObjects(TransInfo *t); void recalcData(TransInfo *t); void calculateCenter2D(TransInfo *t); -void calculateCenterGlobal(TransInfo *t); +void calculateCenterGlobal( + TransInfo *t, const float center_local[3], + float r_center_global[3]); +const TransCenterData *transformCenter_from_type(TransInfo *t, int around); void calculateCenter(TransInfo *t); /* API functions for getting center points */ diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index ed6477392d8..67740644afe 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1610,16 +1610,18 @@ void calculateCenter2D(TransInfo *t) } } -void calculateCenterGlobal(TransInfo *t) +void calculateCenterGlobal( + TransInfo *t, const float center_local[3], + float r_center_global[3]) { /* setting constraint center */ /* note, init functions may over-ride t->center */ if (t->flag & (T_EDIT | T_POSE)) { Object *ob = t->obedit ? t->obedit : t->poseobj; - mul_v3_m4v3(t->center_global, ob->obmat, t->center); + mul_v3_m4v3(r_center_global, ob->obmat, center_local); } else { - copy_v3_v3(t->center_global, t->center); + copy_v3_v3(r_center_global, center_local); } } @@ -1794,43 +1796,55 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3]) return ok; } - -void calculateCenter(TransInfo *t) +static void calculateCenter_FromAround(TransInfo *t, int around, float r_center[3]) { - switch (t->around) { + switch (around) { case V3D_AROUND_CENTER_BOUNDS: - calculateCenterBound(t, t->center); + calculateCenterBound(t, r_center); break; case V3D_AROUND_CENTER_MEAN: - calculateCenterMedian(t, t->center); + calculateCenterMedian(t, r_center); break; case V3D_AROUND_CURSOR: if (ELEM(t->spacetype, SPACE_IMAGE, SPACE_CLIP)) - calculateCenterCursor2D(t, t->center); + calculateCenterCursor2D(t, r_center); else if (t->spacetype == SPACE_IPO) - calculateCenterCursorGraph2D(t, t->center); + calculateCenterCursorGraph2D(t, r_center); else - calculateCenterCursor(t, t->center); + calculateCenterCursor(t, r_center); break; case V3D_AROUND_LOCAL_ORIGINS: /* Individual element center uses median center for helpline and such */ - calculateCenterMedian(t, t->center); + calculateCenterMedian(t, r_center); break; case V3D_AROUND_ACTIVE: { - if (calculateCenterActive(t, false, t->center)) { + if (calculateCenterActive(t, false, r_center)) { /* pass */ } else { /* fallback */ - calculateCenterMedian(t, t->center); + calculateCenterMedian(t, r_center); } break; } } +} + +void calculateCenter(TransInfo *t) +{ + calculateCenter_FromAround(t, t->around, t->center); + calculateCenterGlobal(t, t->center, t->center_global); + + /* avoid calculating again */ + { + TransCenterData *cd = &t->center_cache[t->around]; + copy_v3_v3(cd->local, t->center); + copy_v3_v3(cd->global, t->center_global); + cd->is_set = true; + } calculateCenter2D(t); - calculateCenterGlobal(t); /* for panning from cameraview */ if (t->flag & T_OBJECT) { @@ -1884,6 +1898,23 @@ void calculateCenter(TransInfo *t) } } +BLI_STATIC_ASSERT(ARRAY_SIZE(((TransInfo *)NULL)->center_cache) == (V3D_AROUND_ACTIVE + 1), "test size"); + +/** + * Lazy initialize transform center data, when we need to access center values from other types. + */ +const TransCenterData *transformCenter_from_type(TransInfo *t, int around) +{ + BLI_assert(around <= V3D_AROUND_ACTIVE); + TransCenterData *cd = &t->center_cache[around]; + if (cd->is_set == false) { + calculateCenter_FromAround(t, around, cd->local); + calculateCenterGlobal(t, cd->local, cd->global); + cd->is_set = true; + } + return cd; +} + void calculatePropRatio(TransInfo *t) { TransData *td = t->data; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 38f1d37acd6..e1cf7436236 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -324,7 +324,7 @@ void applyProject(TransInfo *t) if (ED_view3d_project_float_global(t->ar, iloc, mval_fl, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { if (snapObjectsTransform( - t, mval_fl, t->tsnap.modeSelect, &dist_px, + t, mval_fl, &dist_px, loc, no)) { // if (t->flag & (T_EDIT|T_POSE)) { @@ -553,10 +553,10 @@ static void initSnappingMode(TransInfo *t) { /* Exclude editmesh if using proportional edit */ if ((obedit->type == OB_MESH) && (t->flag & T_PROP_EDIT)) { - t->tsnap.modeSelect = SNAP_NOT_OBEDIT; + t->tsnap.modeSelect = SNAP_NOT_ACTIVE; } else { - t->tsnap.modeSelect = t->tsnap.snap_self ? SNAP_ALL : SNAP_NOT_OBEDIT; + t->tsnap.modeSelect = t->tsnap.snap_self ? SNAP_ALL : SNAP_NOT_ACTIVE; } } /* Particles edit mode*/ @@ -964,14 +964,14 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec)) if (t->tsnap.mode == SCE_SNAP_MODE_VOLUME) { found = peelObjectsTransform( - t, mval, t->tsnap.modeSelect, + t, mval, (t->settings->snap_flag & SCE_SNAP_PEEL_OBJECT) != 0, loc, no, NULL); } else { zero_v3(no); /* objects won't set this */ found = snapObjectsTransform( - t, mval, t->tsnap.modeSelect, &dist_px, + t, mval, &dist_px, loc, no); } @@ -1207,17 +1207,16 @@ static void TargetSnapClosest(TransInfo *t) } bool snapObjectsTransform( - TransInfo *t, const float mval[2], SnapSelect snap_select, + TransInfo *t, const float mval[2], float *dist_px, float r_loc[3], float r_no[3]) { return ED_transform_snap_object_project_view3d_ex( t->tsnap.object_context, + t->scene->toolsettings->snap_mode, &(const struct SnapObjectParams){ - .snap_select = snap_select, - .snap_to = t->scene->toolsettings->snap_mode, - .use_object_edit = (t->flag & T_EDIT) != 0, - .use_object_active = (t->options & CTX_GPENCIL_STROKES) == 0, + .snap_select = ((t->options & CTX_GPENCIL_STROKES) != 0) ? SNAP_NOT_ACTIVE : t->tsnap.modeSelect, + .use_object_edit_cage = (t->flag & T_EDIT) != 0, }, mval, dist_px, NULL, r_loc, r_no, NULL); @@ -1228,18 +1227,16 @@ bool snapObjectsTransform( bool peelObjectsSnapContext( SnapObjectContext *sctx, - const float mval[2], SnapSelect snap_select, bool use_peel_object, + const float mval[2], + const struct SnapObjectParams *params, + const bool use_peel_object, /* return args */ float r_loc[3], float r_no[3], float *r_thickness) { ListBase depths_peel = {0}; ED_transform_snap_object_project_all_view3d_ex( sctx, - &(const struct SnapObjectParams){ - .snap_to = SCE_SNAP_MODE_FACE, - .snap_select = snap_select, - .use_object_edit = true, - }, + params, mval, -1.0f, false, &depths_peel); @@ -1299,13 +1296,19 @@ bool peelObjectsSnapContext( bool peelObjectsTransform( TransInfo *t, - const float mval[2], SnapSelect snap_select, bool use_peel_object, + const float mval[2], + const bool use_peel_object, /* return args */ float r_loc[3], float r_no[3], float *r_thickness) { return peelObjectsSnapContext( t->tsnap.object_context, - mval, snap_select, use_peel_object, + mval, + &(const struct SnapObjectParams){ + .snap_select = ((t->options & CTX_GPENCIL_STROKES) != 0) ? SNAP_NOT_ACTIVE : t->tsnap.modeSelect, + .use_object_edit_cage = (t->flag & T_EDIT) != 0, + }, + use_peel_object, r_loc, r_no, r_thickness); } @@ -1520,11 +1523,21 @@ static void applyGridIncrement(TransInfo *t, float *val, int max_index, const fl /* absolute snapping on grid based on global center */ if ((t->tsnap.snap_spatial_grid) && (t->mode == TFM_TRANSLATION)) { + const float *center_global = t->center_global; + + /* use a fallback for cursor selection, + * this isn't useful as a global center for absolute grid snapping + * since its not based on the position of the selection. */ + if (t->around == V3D_AROUND_CURSOR) { + const TransCenterData *cd = transformCenter_from_type(t, V3D_AROUND_CENTER_MEAN); + center_global = cd->global; + } + for (i = 0; i <= max_index; i++) { /* do not let unconstrained axis jump to absolute grid increments */ if (!(t->con.mode & CON_APPLY) || t->con.mode & (CON_AXIS0 << i)) { const float iter_fac = fac[action] * asp[i]; - val[i] = iter_fac * roundf((val[i] + t->center_global[i]) / iter_fac) - t->center_global[i]; + val[i] = iter_fac * roundf((val[i] + center_global[i]) / iter_fac) - center_global[i]; } } } diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index 62ca4e515a5..d7486372c36 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -992,7 +992,7 @@ static bool snapEditMesh( float imat[4][4]; float timat[3][3]; /* transpose inverse matrix for normals */ float ray_start_local[3], ray_normal_local[3]; - float local_scale, local_depth, len_diff; + float local_scale, local_depth; invert_m4_m4(imat, obmat); transpose_m3_m4(timat, imat); @@ -1089,6 +1089,7 @@ static bool snapEditMesh( * been *inside* boundbox, leading to snap failures (see T38409). * Note also ar might be null (see T38435), in this case we assume ray_start is ok! */ + float len_diff = 0.0f; if (do_ray_start_correction) { /* We *need* a reasonably valid len_diff in this case. * Use BHVTree to find the closest face from ray_start_local. @@ -1098,27 +1099,24 @@ static bool snapEditMesh( nearest.index = -1; nearest.dist_sq = FLT_MAX; /* Compute and store result. */ - BLI_bvhtree_find_nearest( - treedata->tree, ray_start_local, &nearest, treedata->nearest_callback, treedata); - if (nearest.index != -1) { + if (BLI_bvhtree_find_nearest( + treedata->tree, ray_start_local, &nearest, treedata->nearest_callback, treedata) != -1) + { len_diff = sqrtf(nearest.dist_sq); + float ray_org_local[3]; + + copy_v3_v3(ray_org_local, ray_origin); + mul_m4_v3(imat, ray_org_local); + + /* We pass a temp ray_start, set from object's boundbox, to avoid precision issues with very far + * away ray_start values (as returned in case of ortho view3d), see T38358. + */ + len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */ + madd_v3_v3v3fl(ray_start_local, ray_org_local, ray_normal_local, + len_diff - len_v3v3(ray_start_local, ray_org_local)); + local_depth -= len_diff; } } - float ray_org_local[3]; - - copy_v3_v3(ray_org_local, ray_origin); - mul_m4_v3(imat, ray_org_local); - - /* We pass a temp ray_start, set from object's boundbox, to avoid precision issues with very far - * away ray_start values (as returned in case of ortho view3d), see T38358. - */ - len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */ - madd_v3_v3v3fl(ray_start_local, ray_org_local, ray_normal_local, - len_diff - len_v3v3(ray_start_local, ray_org_local)); - local_depth -= len_diff; - } - else { - len_diff = 0.0f; } switch (snap_to) { @@ -1316,39 +1314,28 @@ static bool snapObject( static bool snapObjectsRay( SnapObjectContext *sctx, - SnapSelect snap_select, const short snap_to, + const unsigned short snap_to, const SnapSelect snap_select, + const bool use_object_edit_cage, const float mval[2], float *dist_px, - /* special handling of active and edit objects */ - Base *base_act, Object *obedit, const float ray_start[3], const float ray_normal[3], const float ray_origin[3], float *ray_depth, /* return args */ float r_loc[3], float r_no[3], int *r_index, Object **r_ob, float r_obmat[4][4], ListBase *r_hit_list) { - Base *base; bool retval = false; - bool snap_obedit_first = snap_select == SNAP_ALL && obedit; unsigned int ob_index = 0; - - if (snap_obedit_first) { - Object *ob = obedit; - - retval |= snapObject( - sctx, ob, ob->obmat, true, snap_to, - mval, dist_px, ob_index++, - ray_start, ray_normal, ray_origin, ray_depth, - r_loc, r_no, r_index, r_ob, r_obmat, r_hit_list); - } + Object *obedit = use_object_edit_cage ? sctx->scene->obedit : NULL; /* Need an exception for particle edit because the base is flagged with BA_HAS_RECALC_DATA * which makes the loop skip it, even the derived mesh will never change * * To solve that problem, we do it first as an exception. * */ - base = base_act; - if (base && base->object && base->object->mode & OB_MODE_PARTICLE_EDIT) { - Object *ob = base->object; + Base *base_act = sctx->scene->basact; + if (base_act && base_act->object && base_act->object->mode & OB_MODE_PARTICLE_EDIT) { + Object *ob = base_act->object; + retval |= snapObject( sctx, ob, ob->obmat, false, snap_to, mval, dist_px, ob_index++, @@ -1356,16 +1343,25 @@ static bool snapObjectsRay( r_loc, r_no, r_index, r_ob, r_obmat, r_hit_list); } - for (base = sctx->scene->base.first; base != NULL; base = base->next) { + bool ignore_object_selected = false, ignore_object_active = false; + switch (snap_select) { + case SNAP_ALL: + break; + case SNAP_NOT_SELECTED: + ignore_object_selected = true; + break; + case SNAP_NOT_ACTIVE: + ignore_object_active = true; + break; + } + for (Base *base = sctx->scene->base.first; base != NULL; base = base->next) { if ((BASE_VISIBLE_BGMODE(sctx->v3d_data.v3d, sctx->scene, base)) && (base->flag & (BA_HAS_RECALC_OB | BA_HAS_RECALC_DATA)) == 0 && - ((snap_select == SNAP_NOT_SELECTED && (base->flag & (SELECT | BA_WAS_SEL)) == 0) || - (ELEM(snap_select, SNAP_ALL, SNAP_NOT_OBEDIT) && base != base_act))) + !((ignore_object_selected && (base->flag & (SELECT | BA_WAS_SEL))) || + (ignore_object_active && base == base_act))) { Object *ob = base->object; - Object *ob_snap = ob; - bool use_obedit = false; if (ob->transflag & OB_DUPLI) { DupliObject *dupli_ob; @@ -1385,19 +1381,8 @@ static bool snapObjectsRay( free_object_duplilist(lb); } - if (obedit) { - if ((ob == obedit) && - (snap_obedit_first || (snap_select == SNAP_NOT_OBEDIT))) - { - continue; - } - - if (ob->data == obedit->data) { - /* for linked objects, use the same object but a different matrix */ - use_obedit = true; - ob_snap = obedit; - } - } + bool use_obedit = (obedit != NULL) && (ob->data == obedit->data); + Object *ob_snap = use_obedit ? obedit : ob; retval |= snapObject( sctx, ob_snap, ob->obmat, use_obedit, snap_to, @@ -1502,22 +1487,18 @@ void ED_transform_snap_object_context_set_editmesh_callbacks( bool ED_transform_snap_object_project_ray_ex( SnapObjectContext *sctx, + const unsigned short snap_to, const struct SnapObjectParams *params, const float ray_start[3], const float ray_normal[3], float *ray_depth, float r_loc[3], float r_no[3], int *r_index, Object **r_ob, float r_obmat[4][4]) { - Base *base_act = params->use_object_active ? sctx->scene->basact : NULL; - Object *obedit = params->use_object_edit ? sctx->scene->obedit : NULL; - return snapObjectsRay( sctx, - params->snap_select, params->snap_to, + snap_to, params->snap_select, params->use_object_edit_cage, NULL, NULL, - base_act, obedit, ray_start, ray_normal, ray_start, ray_depth, - r_loc, r_no, r_index, - r_ob, r_obmat, NULL); + r_loc, r_no, r_index, r_ob, r_obmat, NULL); } /** @@ -1529,14 +1510,12 @@ bool ED_transform_snap_object_project_ray_ex( */ bool ED_transform_snap_object_project_ray_all( SnapObjectContext *sctx, + const unsigned short snap_to, const struct SnapObjectParams *params, const float ray_start[3], const float ray_normal[3], float ray_depth, bool sort, ListBase *r_hit_list) { - Base *base_act = params->use_object_active ? sctx->scene->basact : NULL; - Object *obedit = params->use_object_edit ? sctx->scene->obedit : NULL; - if (ray_depth == -1.0f) { ray_depth = BVH_RAYCAST_DIST_MAX; } @@ -1547,9 +1526,8 @@ bool ED_transform_snap_object_project_ray_all( bool retval = snapObjectsRay( sctx, - params->snap_select, params->snap_to, + snap_to, params->snap_select, params->use_object_edit_cage, NULL, NULL, - base_act, obedit, ray_start, ray_normal, ray_start, &ray_depth, NULL, NULL, NULL, NULL, NULL, r_hit_list); @@ -1575,6 +1553,7 @@ bool ED_transform_snap_object_project_ray_all( */ static bool transform_snap_context_project_ray_impl( SnapObjectContext *sctx, + const struct SnapObjectParams *params, const float ray_start[3], const float ray_normal[3], float *ray_depth, float r_co[3], float r_no[3]) { @@ -1583,11 +1562,8 @@ static bool transform_snap_context_project_ray_impl( /* try snap edge, then face if it fails */ ret = ED_transform_snap_object_project_ray_ex( sctx, - &(const struct SnapObjectParams){ - .snap_select = SNAP_ALL, - .snap_to = SCE_SNAP_MODE_FACE, - .use_object_edit = (sctx->scene->obedit != NULL), - }, + SCE_SNAP_MODE_FACE, + params, ray_start, ray_normal, ray_depth, r_co, r_no, NULL, NULL, NULL); @@ -1597,6 +1573,7 @@ static bool transform_snap_context_project_ray_impl( bool ED_transform_snap_object_project_ray( SnapObjectContext *sctx, + const struct SnapObjectParams *params, const float ray_origin[3], const float ray_direction[3], float *ray_depth, float r_co[3], float r_no[3]) { @@ -1613,12 +1590,14 @@ bool ED_transform_snap_object_project_ray( return transform_snap_context_project_ray_impl( sctx, + params, ray_origin, ray_direction, ray_depth, r_co, r_no); } static bool transform_snap_context_project_view3d_mixed_impl( SnapObjectContext *sctx, + const unsigned short snap_to_flag, const struct SnapObjectParams *params, const float mval[2], float *dist_px, bool use_depth, @@ -1634,22 +1613,18 @@ static bool transform_snap_context_project_view3d_mixed_impl( const int elem_type[3] = {SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE, SCE_SNAP_MODE_FACE}; - BLI_assert(params->snap_to_flag != 0); - BLI_assert((params->snap_to_flag & ~(1 | 2 | 4)) == 0); - - struct SnapObjectParams params_temp = *params; + BLI_assert(snap_to_flag != 0); + BLI_assert((snap_to_flag & ~(1 | 2 | 4)) == 0); for (int i = 0; i < 3; i++) { - if ((params->snap_to_flag & (1 << i)) && (is_hit == false || use_depth)) { + if ((snap_to_flag & (1 << i)) && (is_hit == false || use_depth)) { if (use_depth == false) { ray_depth = BVH_RAYCAST_DIST_MAX; } - params_temp.snap_to = elem_type[i]; - if (ED_transform_snap_object_project_view3d( sctx, - ¶ms_temp, + elem_type[i], params, mval, dist_px, &ray_depth, r_co, r_no)) { @@ -1676,6 +1651,7 @@ static bool transform_snap_context_project_view3d_mixed_impl( */ bool ED_transform_snap_object_project_view3d_mixed( SnapObjectContext *sctx, + const unsigned short snap_to_flag, const struct SnapObjectParams *params, const float mval_fl[2], float *dist_px, bool use_depth, @@ -1683,13 +1659,14 @@ bool ED_transform_snap_object_project_view3d_mixed( { return transform_snap_context_project_view3d_mixed_impl( sctx, - params, + snap_to_flag, params, mval_fl, dist_px, use_depth, r_co, r_no); } bool ED_transform_snap_object_project_view3d_ex( SnapObjectContext *sctx, + const unsigned short snap_to, const struct SnapObjectParams *params, const float mval[2], float *dist_px, float *ray_depth, @@ -1710,19 +1687,17 @@ bool ED_transform_snap_object_project_view3d_ex( return false; } - Base *base_act = params->use_object_active ? sctx->scene->basact : NULL; - Object *obedit = params->use_object_edit ? sctx->scene->obedit : NULL; return snapObjectsRay( sctx, - params->snap_select, params->snap_to, + snap_to, params->snap_select, params->use_object_edit_cage, mval, dist_px, - base_act, obedit, ray_start, ray_normal, ray_orgigin, ray_depth, r_loc, r_no, r_index, NULL, NULL, NULL); } bool ED_transform_snap_object_project_view3d( SnapObjectContext *sctx, + const unsigned short snap_to, const struct SnapObjectParams *params, const float mval[2], float *dist_px, float *ray_depth, @@ -1730,6 +1705,7 @@ bool ED_transform_snap_object_project_view3d( { return ED_transform_snap_object_project_view3d_ex( sctx, + snap_to, params, mval, dist_px, ray_depth, @@ -1748,8 +1724,6 @@ bool ED_transform_snap_object_project_all_view3d_ex( { float ray_start[3], ray_normal[3]; - BLI_assert(params->snap_to == SCE_SNAP_MODE_FACE); - if (!ED_view3d_win_to_ray_ex( sctx->v3d_data.ar, sctx->v3d_data.v3d, mval, NULL, ray_normal, ray_start, true)) @@ -1759,6 +1733,7 @@ bool ED_transform_snap_object_project_all_view3d_ex( return ED_transform_snap_object_project_ray_all( sctx, + SCE_SNAP_MODE_FACE, params, ray_start, ray_normal, ray_depth, sort, r_hit_list); diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index a8656c05224..aefaf1a0f54 100644 --- a/source/blender/gpu/GPU_buffers.h +++ b/source/blender/gpu/GPU_buffers.h @@ -49,6 +49,7 @@ struct DerivedMesh; struct GSet; struct GPUVertPointLink; struct GPUDrawObject; +struct GridCommonGPUBuffer; struct PBVH; struct MVert; @@ -147,6 +148,7 @@ typedef struct GPUVertPointLink { /* used for GLSL materials */ typedef struct GPUAttrib { int index; + int info_index; int size; int type; } GPUAttrib; @@ -159,9 +161,6 @@ void GPU_buffer_free(GPUBuffer *buffer); void GPU_drawobject_free(struct DerivedMesh *dm); -/* free special global multires grid buffer */ -void GPU_buffer_multires_free(bool force); - /* flag that controls data type to fill buffer with, a modifier will prepare. */ typedef enum { GPU_BUFFER_VERTEX = 0, @@ -179,6 +178,10 @@ typedef enum { GPU_BINDING_INDEX = 1, } GPUBindingType; +typedef enum { + GPU_ATTR_INFO_SRGB = (1 << 0), +} GPUAttrInfo; + /* called before drawing */ void GPU_vertex_setup(struct DerivedMesh *dm); void GPU_normal_setup(struct DerivedMesh *dm); @@ -226,8 +229,9 @@ GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers( const int *face_indices, const int face_indices_len); -GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid, - unsigned int **grid_hidden, int gridsize, const struct CCGKey *key); +GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers( + int *grid_indices, int totgrid,unsigned int **grid_hidden, int gridsize, const struct CCGKey *key, + struct GridCommonGPUBuffer **grid_common_gpu_buffer); GPU_PBVH_Buffers *GPU_build_bmesh_pbvh_buffers(bool smooth_shading); @@ -262,5 +266,6 @@ void GPU_init_draw_pbvh_BB(void); bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, struct GSet *bm_faces, bool show_diffuse_color); void GPU_free_pbvh_buffers(GPU_PBVH_Buffers *buffers); +void GPU_free_pbvh_buffer_multires(struct GridCommonGPUBuffer **grid_common_gpu_buffer); #endif diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 50a5fddc842..b40a2dbd1ed 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -118,6 +118,7 @@ typedef struct GPUVertexAttribs { struct { int type; int glindex; + int glinfoindoex; int gltexco; int attribid; char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 09d0a383426..2c6f204d9d0 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -107,10 +107,12 @@ static GPUAttrib attribData[MAX_GPU_ATTRIB_DATA] = { { -1, 0, 0 } }; static ThreadMutex buffer_mutex = BLI_MUTEX_INITIALIZER; /* multires global buffer, can be used for many grids having the same grid size */ -static GPUBuffer *mres_glob_buffer = NULL; -static int mres_prev_gridsize = -1; -static GLenum mres_prev_index_type = 0; -static unsigned mres_prev_totquad = 0; +typedef struct GridCommonGPUBuffer { + GPUBuffer *mres_buffer; + int mres_prev_gridsize; + GLenum mres_prev_index_type; + unsigned mres_prev_totquad; +} GridCommonGPUBuffer; void GPU_buffer_material_finalize(GPUDrawObject *gdo, GPUBufferMaterial *matinfo, int totmat) { @@ -407,33 +409,6 @@ void GPU_buffer_free(GPUBuffer *buffer) BLI_mutex_unlock(&buffer_mutex); } -void GPU_buffer_multires_free(bool force) -{ - if (!mres_glob_buffer) { - /* Early output, no need to lock in this case, */ - return; - } - - if (force && BLI_thread_is_main()) { - if (mres_glob_buffer) { - if (mres_glob_buffer->id) - glDeleteBuffers(1, &mres_glob_buffer->id); - MEM_freeN(mres_glob_buffer); - } - } - else { - BLI_mutex_lock(&buffer_mutex); - gpu_buffer_free_intern(mres_glob_buffer); - BLI_mutex_unlock(&buffer_mutex); - } - - mres_glob_buffer = NULL; - mres_prev_gridsize = -1; - mres_prev_index_type = 0; - mres_prev_totquad = 0; -} - - void GPU_drawobject_free(DerivedMesh *dm) { GPUDrawObject *gdo; @@ -822,6 +797,12 @@ void GPU_interleaved_attrib_setup(GPUBuffer *buffer, GPUAttrib data[], int numda for (i = 0; i < numdata; i++) { glEnableVertexAttribArray(data[i].index); + int info = 0; + if (data[i].type == GL_UNSIGNED_BYTE) { + info |= GPU_ATTR_INFO_SRGB; + } + glUniform1i(data[i].info_index, info); + glVertexAttribPointer(data[i].index, data[i].size, data[i].type, GL_TRUE, elementsize, BUFFER_OFFSET(offset)); offset += data[i].size * GPU_typesize(data[i].type); @@ -1003,6 +984,7 @@ struct GPU_PBVH_Buffers { const int *grid_indices; int totgrid; bool has_hidden; + bool is_index_buf_global; /* Means index_buf uses global bvh's grid_common_gpu_buffer, **DO NOT** free it! */ bool use_bmesh; @@ -1220,8 +1202,10 @@ GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers( /* An element index buffer is used for smooth shading, but flat * shading requires separate vertex normals so an index buffer is * can't be used there. */ - if (buffers->smooth) + if (buffers->smooth) { buffers->index_buf = GPU_buffer_alloc(sizeof(unsigned short) * tottri * 3); + buffers->is_index_buf_global = false; + } if (buffers->index_buf) { /* Fill the triangle buffer */ @@ -1242,8 +1226,11 @@ GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers( GPU_buffer_unlock(buffers->index_buf, GPU_BINDING_INDEX); } else { - GPU_buffer_free(buffers->index_buf); + if (!buffers->is_index_buf_global) { + GPU_buffer_free(buffers->index_buf); + } buffers->index_buf = NULL; + buffers->is_index_buf_global = false; } } @@ -1410,22 +1397,33 @@ void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids, } (void)0 /* end FILL_QUAD_BUFFER */ -static GPUBuffer *gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned *totquad) +static GPUBuffer *gpu_get_grid_buffer( + int gridsize, GLenum *index_type, unsigned *totquad, GridCommonGPUBuffer **grid_common_gpu_buffer) { /* used in the FILL_QUAD_BUFFER macro */ BLI_bitmap * const *grid_hidden = NULL; const int *grid_indices = NULL; int totgrid = 1; + GridCommonGPUBuffer *gridbuff = *grid_common_gpu_buffer; + + if (gridbuff == NULL) { + *grid_common_gpu_buffer = gridbuff = MEM_mallocN(sizeof(GridCommonGPUBuffer), __func__); + gridbuff->mres_buffer = NULL; + gridbuff->mres_prev_gridsize = -1; + gridbuff->mres_prev_index_type = 0; + gridbuff->mres_prev_totquad = 0; + } + /* VBO is already built */ - if (mres_glob_buffer && mres_prev_gridsize == gridsize) { - *index_type = mres_prev_index_type; - *totquad = mres_prev_totquad; - return mres_glob_buffer; + if (gridbuff->mres_buffer && gridbuff->mres_prev_gridsize == gridsize) { + *index_type = gridbuff->mres_prev_index_type; + *totquad = gridbuff->mres_prev_totquad; + return gridbuff->mres_buffer; } /* we can't reuse old, delete the existing buffer */ - else if (mres_glob_buffer) { - GPU_buffer_free(mres_glob_buffer); + else if (gridbuff->mres_buffer) { + GPU_buffer_free(gridbuff->mres_buffer); } /* Build new VBO */ @@ -1433,17 +1431,17 @@ static GPUBuffer *gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned if (gridsize * gridsize < USHRT_MAX) { *index_type = GL_UNSIGNED_SHORT; - FILL_QUAD_BUFFER(unsigned short, *totquad, mres_glob_buffer); + FILL_QUAD_BUFFER(unsigned short, *totquad, gridbuff->mres_buffer); } else { *index_type = GL_UNSIGNED_INT; - FILL_QUAD_BUFFER(unsigned int, *totquad, mres_glob_buffer); + FILL_QUAD_BUFFER(unsigned int, *totquad, gridbuff->mres_buffer); } - mres_prev_gridsize = gridsize; - mres_prev_index_type = *index_type; - mres_prev_totquad = *totquad; - return mres_glob_buffer; + gridbuff->mres_prev_gridsize = gridsize; + gridbuff->mres_prev_index_type = *index_type; + gridbuff->mres_prev_totquad = *totquad; + return gridbuff->mres_buffer; } #define FILL_FAST_BUFFER(type_) \ @@ -1470,8 +1468,9 @@ static GPUBuffer *gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned } \ } (void)0 -GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid, - BLI_bitmap **grid_hidden, int gridsize, const CCGKey *key) +GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers( + int *grid_indices, int totgrid, BLI_bitmap **grid_hidden, int gridsize, const CCGKey *key, + GridCommonGPUBuffer **grid_common_gpu_buffer) { GPU_PBVH_Buffers *buffers; int totquad; @@ -1500,8 +1499,10 @@ GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid, } if (totquad == fully_visible_totquad) { - buffers->index_buf = gpu_get_grid_buffer(gridsize, &buffers->index_type, &buffers->tot_quad); + buffers->index_buf = gpu_get_grid_buffer( + gridsize, &buffers->index_type, &buffers->tot_quad, grid_common_gpu_buffer); buffers->has_hidden = false; + buffers->is_index_buf_global = true; } else { buffers->tot_quad = totquad; @@ -1516,6 +1517,7 @@ GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid, } buffers->has_hidden = true; + buffers->is_index_buf_global = false; } /* Build coord/normal VBO */ @@ -1740,8 +1742,9 @@ void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers, const int use_short = (maxvert < USHRT_MAX); /* Initialize triangle index buffer */ - if (buffers->index_buf) + if (buffers->index_buf && !buffers->is_index_buf_global) GPU_buffer_free(buffers->index_buf); + buffers->is_index_buf_global = false; buffers->index_buf = GPU_buffer_alloc((use_short ? sizeof(unsigned short) : sizeof(unsigned int)) * 3 * tottri); @@ -1786,12 +1789,19 @@ void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers, } else { /* Memory map failed */ - GPU_buffer_free(buffers->index_buf); + if (!buffers->is_index_buf_global) { + GPU_buffer_free(buffers->index_buf); + } buffers->index_buf = NULL; + buffers->is_index_buf_global = false; } } else if (buffers->index_buf) { - GPU_buffer_free(buffers->index_buf); + if (!buffers->is_index_buf_global) { + GPU_buffer_free(buffers->index_buf); + } + buffers->index_buf = NULL; + buffers->is_index_buf_global = false; } } @@ -1985,7 +1995,7 @@ void GPU_free_pbvh_buffers(GPU_PBVH_Buffers *buffers) if (buffers) { if (buffers->vert_buf) GPU_buffer_free(buffers->vert_buf); - if (buffers->index_buf && (buffers->tot_tri || buffers->has_hidden)) + if (buffers->index_buf && !buffers->is_index_buf_global) GPU_buffer_free(buffers->index_buf); if (buffers->index_buf_fast) GPU_buffer_free(buffers->index_buf_fast); @@ -1998,6 +2008,20 @@ void GPU_free_pbvh_buffers(GPU_PBVH_Buffers *buffers) } } +void GPU_free_pbvh_buffer_multires(GridCommonGPUBuffer **grid_common_gpu_buffer) +{ + GridCommonGPUBuffer *gridbuff = *grid_common_gpu_buffer; + + if (gridbuff) { + if (gridbuff->mres_buffer) { + BLI_mutex_lock(&buffer_mutex); + gpu_buffer_free_intern(gridbuff->mres_buffer); + BLI_mutex_unlock(&buffer_mutex); + } + MEM_freeN(gridbuff); + *grid_common_gpu_buffer = NULL; + } +} /* debug function, draws the pbvh BB */ void GPU_draw_pbvh_BB(float min[3], float max[3], bool leaf) diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index f8f78566ea2..fae60031589 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -779,6 +779,7 @@ static char *code_generate_vertex(ListBase *nodes, const GPUMatType type) BLI_dynstr_appendf(ds, "%s %s att%d;\n", GLEW_VERSION_3_0 ? "in" : "attribute", GPU_DATATYPE_STR[input->type], input->attribid); + BLI_dynstr_appendf(ds, "uniform int att%d_info;\n", input->attribid); BLI_dynstr_appendf(ds, "%s %s var%d;\n", GLEW_VERSION_3_0 ? "out" : "varying", GPU_DATATYPE_STR[input->type], input->attribid); @@ -832,7 +833,8 @@ static char *code_generate_vertex(ListBase *nodes, const GPUMatType type) BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n"); } #endif - BLI_dynstr_appendf(ds, "\tvar%d = att%d;\n", input->attribid, input->attribid); + BLI_dynstr_appendf(ds, "\tset_var_from_attr(att%d, att%d_info, var%d);\n", + input->attribid, input->attribid, input->attribid); #ifdef WITH_OPENSUBDIV if (is_mtface) { BLI_dynstr_appendf(ds, "#endif\n"); diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c index da4dd65d2e1..8fed6a9ee80 100644 --- a/source/blender/gpu/intern/gpu_init_exit.c +++ b/source/blender/gpu/intern/gpu_init_exit.c @@ -73,7 +73,6 @@ void GPU_exit(void) gpu_codegen_exit(); gpu_extensions_exit(); /* must come last */ - GPU_buffer_multires_free(true); initialized = false; } diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 5fdb9f531ca..9dee35fa7ec 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -278,6 +278,9 @@ static void gpu_material_set_attrib_id(GPUMaterial *material) BLI_snprintf(name, sizeof(name), "att%d", attribs->layer[a].attribid); attribs->layer[a].glindex = GPU_shader_get_attribute(shader, name); + BLI_snprintf(name, sizeof(name), "att%d_info", attribs->layer[a].attribid); + attribs->layer[a].glinfoindoex = GPU_shader_get_uniform(shader, name); + if (attribs->layer[a].glindex >= 0) { attribs->layer[b] = attribs->layer[a]; b++; diff --git a/source/blender/gpu/shaders/gpu_shader_material_new_shading.glsl b/source/blender/gpu/shaders/gpu_shader_material_new_shading.glsl index 953fc03e03f..a92f17879a7 100644 --- a/source/blender/gpu/shaders/gpu_shader_material_new_shading.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material_new_shading.glsl @@ -163,10 +163,10 @@ void node_add_shader(vec4 shader1, vec4 shader2, out vec4 shader) void node_fresnel(float ior, vec3 N, vec3 I, out float result) { /* handle perspective/orthographic */ - vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0)? normalize(I): vec3(0.0, 0.0, -1.0); + vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0); float eta = max(ior, 0.00001); - result = fresnel_dielectric(I_view, N, (gl_FrontFacing)? eta: 1.0/eta); + result = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? eta : 1.0/eta); } /* layer_weight */ @@ -175,15 +175,15 @@ void node_layer_weight(float blend, vec3 N, vec3 I, out float fresnel, out float { /* fresnel */ float eta = max(1.0 - blend, 0.00001); - vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0)? normalize(I): vec3(0.0, 0.0, -1.0); + vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0); fresnel = fresnel_dielectric(I_view, N, (gl_FrontFacing)? 1.0/eta : eta ); /* facing */ facing = abs(dot(I_view, N)); - if(blend != 0.5) { + if (blend != 0.5) { blend = clamp(blend, 0.0, 0.99999); - blend = (blend < 0.5)? 2.0*blend: 0.5/(1.0 - blend); + blend = (blend < 0.5) ? 2.0 * blend : 0.5 / (1.0 - blend); facing = pow(facing, blend); } facing = 1.0 - facing; @@ -195,21 +195,21 @@ void node_gamma(vec4 col, float gamma, out vec4 outcol) { outcol = col; - if(col.r > 0.0) + if (col.r > 0.0) outcol.r = compatible_pow(col.r, gamma); - if(col.g > 0.0) + if (col.g > 0.0) outcol.g = compatible_pow(col.g, gamma); - if(col.b > 0.0) + if (col.b > 0.0) outcol.b = compatible_pow(col.b, gamma); } /* geometry */ -void node_attribute(vec3 attr_uv, out vec4 outcol, out vec3 outvec, out float outf) +void node_attribute(vec3 attr, out vec4 outcol, out vec3 outvec, out float outf) { - outcol = vec4(attr_uv, 1.0); - outvec = attr_uv; - outf = (attr_uv.x + attr_uv.y + attr_uv.z)/3.0; + outcol = vec4(attr, 1.0); + outvec = attr; + outf = (attr.x + attr.y + attr.z) / 3.0; } void node_uvmap(vec3 attr_uv, out vec3 outvec) @@ -256,18 +256,18 @@ void node_geometry(vec3 I, vec3 N, vec3 attr_orco, mat4 toworld, mat4 fromobj, out vec3 true_normal, out vec3 incoming, out vec3 parametric, out float backfacing, out float pointiness) { - position = (toworld*vec4(I, 1.0)).xyz; - normal = (toworld*vec4(N, 0.0)).xyz; + position = (toworld * vec4(I, 1.0)).xyz; + normal = (toworld * vec4(N, 0.0)).xyz; attr_orco = vec3(attr_orco.y * -0.5, attr_orco.x * 0.5, 0.0); node_tangent(N, attr_orco, fromobj, toworld, tangent); true_normal = normal; /* handle perspective/orthographic */ - vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0)? normalize(I): vec3(0.0, 0.0, -1.0); - incoming = -(toworld*vec4(I_view, 0.0)).xyz; + vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0); + incoming = -(toworld * vec4(I_view, 0.0)).xyz; parametric = vec3(0.0); - backfacing = (gl_FrontFacing)? 0.0: 1.0; + backfacing = (gl_FrontFacing) ? 0.0 : 1.0; pointiness = 0.5; } @@ -294,17 +294,17 @@ void node_tex_coord( out vec3 camera, out vec3 window, out vec3 reflection) { generated = attr_orco * 0.5 + vec3(0.5); - normal = normalize((obinvmat*(viewinvmat*vec4(N, 0.0))).xyz); + normal = normalize((obinvmat * (viewinvmat * vec4(N, 0.0))).xyz); uv = attr_uv; - object = (obinvmat*(viewinvmat*vec4(I, 1.0))).xyz; + object = (obinvmat * (viewinvmat * vec4(I, 1.0))).xyz; camera = vec3(I.xy, -I.z); vec4 projvec = gl_ProjectionMatrix * vec4(I, 1.0); - window = vec3(mtex_2d_mapping(projvec.xyz/projvec.w).xy * camerafac.xy + camerafac.zw, 0.0); + window = vec3(mtex_2d_mapping(projvec.xyz / projvec.w).xy * camerafac.xy + camerafac.zw, 0.0); vec3 shade_I; shade_view(I, shade_I); vec3 view_reflection = reflect(shade_I, normalize(N)); - reflection = (viewinvmat*vec4(view_reflection, 0.0)).xyz; + reflection = (viewinvmat * vec4(view_reflection, 0.0)).xyz; } void node_tex_coord_background( @@ -328,8 +328,8 @@ void node_tex_coord_background( camera = vec3(co.xy, -co.z); window = (gl_ProjectionMatrix[3][3] == 0.0) ? - vec3(mtex_2d_mapping(I).xy * camerafac.xy + camerafac.zw, 0.0) : - vec3(vec2(0.5) * camerafac.xy + camerafac.zw, 0.0); + vec3(mtex_2d_mapping(I).xy * camerafac.xy + camerafac.zw, 0.0) : + vec3(vec2(0.5) * camerafac.xy + camerafac.zw, 0.0); reflection = -coords; } @@ -390,11 +390,11 @@ void node_tex_checker(vec3 co, vec4 color1, vec4 color2, float scale, out vec4 c p.y = (p.y + 0.000001) * 0.999999; p.z = (p.z + 0.000001) * 0.999999; - int xi = abs(int(floor(p.x))); - int yi = abs(int(floor(p.y))); - int zi = abs(int(floor(p.z))); + int xi = int(abs(floor(p.x))); + int yi = int(abs(floor(p.y))); + int zi = int(abs(floor(p.z))); - bool check = ((xi % 2 == yi % 2) == bool(zi % 2)); + bool check = ((mod(xi, 2) == mod(yi, 2)) == bool(mod(zi, 2))); color = check ? color1 : color2; fac = check ? 1.0 : 0.0; @@ -479,12 +479,12 @@ void node_tex_environment_mirror_ball(vec3 co, sampler2D ima, out vec4 color) nco.y -= 1.0; - float div = 2.0*sqrt(max(-0.5*nco.y, 0.0)); + float div = 2.0 * sqrt(max(-0.5 * nco.y, 0.0)); if(div > 0.0) nco /= div; - float u = 0.5*(nco.x + 1.0); - float v = 0.5*(nco.z + 1.0); + float u = 0.5 * (nco.x + 1.0); + float v = 0.5 * (nco.z + 1.0); color = texture2D(ima, vec2(u, v)); } @@ -569,6 +569,7 @@ void node_tex_image_box(vec3 texco, weight.x = 1.0; } + color = vec4(0); if (weight.x > 0.0) { color += weight.x * texture2D(ima, texco.yz); } diff --git a/source/blender/gpu/shaders/gpu_shader_vertex.glsl b/source/blender/gpu/shaders/gpu_shader_vertex.glsl index 5824d5a80db..9a6537b4f09 100644 --- a/source/blender/gpu/shaders/gpu_shader_vertex.glsl +++ b/source/blender/gpu/shaders/gpu_shader_vertex.glsl @@ -14,6 +14,68 @@ varying vec3 varnormal; varying float gl_ClipDistance[6]; #endif +float srgb_to_linearrgb(float c) +{ + if (c < 0.04045) + return (c < 0.0) ? 0.0 : c * (1.0 / 12.92); + else + return pow((c + 0.055) * (1.0 / 1.055), 2.4); +} + +void srgb_to_linearrgb(vec3 col_from, out vec3 col_to) +{ + col_to.r = srgb_to_linearrgb(col_from.r); + col_to.g = srgb_to_linearrgb(col_from.g); + col_to.b = srgb_to_linearrgb(col_from.b); +} + +void srgb_to_linearrgb(vec4 col_from, out vec4 col_to) +{ + col_to.r = srgb_to_linearrgb(col_from.r); + col_to.g = srgb_to_linearrgb(col_from.g); + col_to.b = srgb_to_linearrgb(col_from.b); + col_to.a = col_from.a; +} + +bool is_srgb(int info) +{ +#ifdef USE_NEW_SHADING + return (info == 1)? true: false; +#else + return false; +#endif +} + +void set_var_from_attr(float attr, int info, out float var) +{ + var = attr; +} + +void set_var_from_attr(vec2 attr, int info, out vec2 var) +{ + var = attr; +} + +void set_var_from_attr(vec3 attr, int info, out vec3 var) +{ + if (is_srgb(info)) { + srgb_to_linearrgb(attr, var); + } + else { + var = attr; + } +} + +void set_var_from_attr(vec4 attr, int info, out vec4 var) +{ + if (is_srgb(info)) { + srgb_to_linearrgb(attr, var); + } + else { + var = attr; + } +} + void main() { #ifndef USE_OPENSUBDIV diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h index f4763883489..d89393b9903 100644 --- a/source/blender/imbuf/intern/IMB_anim.h +++ b/source/blender/imbuf/intern/IMB_anim.h @@ -83,18 +83,10 @@ # include <libswscale/swscale.h> #endif -/* actually hard coded endianness */ -#define GET_BIG_LONG(x) (((uchar *) (x))[0] << 24 | ((uchar *) (x))[1] << 16 | ((uchar *) (x))[2] << 8 | ((uchar *) (x))[3]) -#define GET_LITTLE_LONG(x) (((uchar *) (x))[3] << 24 | ((uchar *) (x))[2] << 16 | ((uchar *) (x))[1] << 8 | ((uchar *) (x))[0]) -#define SWAP_L(x) (((x << 24) & 0xff000000) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) | ((x >> 24) & 0xff)) -#define SWAP_S(x) (((x << 8) & 0xff00) | ((x >> 8) & 0xff)) - /* more endianness... should move to a separate file... */ #ifdef __BIG_ENDIAN__ -# define GET_ID GET_BIG_LONG # define LITTLE_LONG SWAP_LONG #else -# define GET_ID GET_LITTLE_LONG # define LITTLE_LONG ENDIAN_NOP #endif diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index fdad6aae094..4c1283452ff 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -484,7 +484,7 @@ typedef struct FCurve { unsigned int totvert; /* total number of points which define the curve (i.e. size of arrays in FPoints) */ /* value cache + settings */ - float curval; /* value stored from last time curve was evaluated */ + float curval; /* value stored from last time curve was evaluated (not threadsafe, debug display only!) */ short flag; /* user-editable settings for this curve */ short extend; /* value-extending mode for this curve (does not cover */ diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index eb3204e0018..f42a4587120 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -304,7 +304,7 @@ typedef struct View3D { #define RV3D_VIEW_CAMERA 8 #define RV3D_VIEW_IS_AXIS(view) \ - ((view >= RV3D_VIEW_FRONT) && (view <= RV3D_VIEW_BOTTOM)) + (((view) >= RV3D_VIEW_FRONT) && ((view) <= RV3D_VIEW_BOTTOM)) /* View3d->flag2 (short) */ #define V3D_RENDER_OVERRIDE (1 << 2) diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index d28dd8f7607..cb7a40a9238 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -1009,13 +1009,15 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna) prop = RNA_def_property(srna, "offset_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "xof"); - RNA_def_property_range(prop, -50.0f, 50.0f); + RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); + RNA_def_property_ui_range(prop, -50.0f, 50.0f, 10, 3); RNA_def_property_ui_text(prop, "X Offset", "Horizontal offset from the object origin"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); prop = RNA_def_property(srna, "offset_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "yof"); - RNA_def_property_range(prop, -50.0f, 50.0f); + RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); + RNA_def_property_ui_range(prop, -50.0f, 50.0f, 10, 3); RNA_def_property_ui_text(prop, "Y Offset", "Vertical offset from the object origin"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); @@ -1117,25 +1119,29 @@ static void rna_def_textbox(BlenderRNA *brna) /* number values */ prop = RNA_def_property(srna, "x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "x"); - RNA_def_property_range(prop, -50.0f, 50.0f); + RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); + RNA_def_property_ui_range(prop, -50.0f, 50.0f, 10, 3); RNA_def_property_ui_text(prop, "Textbox X Offset", ""); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); prop = RNA_def_property(srna, "y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "y"); - RNA_def_property_range(prop, -50.0f, 50.0f); + RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); + RNA_def_property_ui_range(prop, -50.0f, 50.0f, 10, 3); RNA_def_property_ui_text(prop, "Textbox Y Offset", ""); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); prop = RNA_def_property(srna, "width", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "w"); - RNA_def_property_range(prop, 0.0f, 50.0f); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 50.0f, 10, 3); RNA_def_property_ui_text(prop, "Textbox Width", ""); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); prop = RNA_def_property(srna, "height", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "h"); - RNA_def_property_range(prop, 0.0f, 50.0f); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 50.0f, 10, 3); RNA_def_property_ui_text(prop, "Textbox Height", ""); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 7cc69831dce..b66556109e6 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -698,7 +698,7 @@ void RNA_api_object(StructRNA *srna) #endif /* NDEBUG */ func = RNA_def_function(srna, "update_from_editmode", "rna_Object_update_from_editmode"); - RNA_def_function_ui_description(func, "Load the objects edit-mode data intp the object data"); + RNA_def_function_ui_description(func, "Load the objects edit-mode data into the object data"); parm = RNA_def_boolean(func, "result", 0, "", "Success"); RNA_def_function_return(func, parm); diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index e1216e3c85f..c3c66625c84 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -151,9 +151,9 @@ static void rna_Scene_ray_cast( bool ret = ED_transform_snap_object_project_ray_ex( sctx, + SCE_SNAP_MODE_FACE, &(const struct SnapObjectParams){ .snap_select = SNAP_ALL, - .snap_to = SCE_SNAP_MODE_FACE, }, origin, direction, &ray_dist, r_location, r_normal, r_index, diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 0fbc1ce1854..5a1607aa7c7 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -408,7 +408,7 @@ static void rna_userdef_addon_remove(ReportList *reports, PointerRNA *path_cmp_p { bAddon *bext = path_cmp_ptr->data; if (BLI_findindex(&U.addons, bext) == -1) { - BKE_report(reports, RPT_ERROR, "Addon is no longer valid"); + BKE_report(reports, RPT_ERROR, "Add-on is no longer valid"); return; } @@ -705,7 +705,7 @@ static StructRNA *rna_AddonPref_register(Main *bmain, ReportList *reports, void BLI_strncpy(dummyapt.idname, dummyaddon.module, sizeof(dummyapt.idname)); if (strlen(identifier) >= sizeof(dummyapt.idname)) { - BKE_reportf(reports, RPT_ERROR, "Registering addon-prefs class: '%s' is too long, maximum length is %d", + BKE_reportf(reports, RPT_ERROR, "Registering add-on preferences class: '%s' is too long, maximum length is %d", identifier, (int)sizeof(dummyapt.idname)); return NULL; } @@ -3195,7 +3195,7 @@ static void rna_def_userdef_addon(BlenderRNA *brna) srna = RNA_def_struct(brna, "Addon", NULL); RNA_def_struct_sdna(srna, "bAddon"); RNA_def_struct_clear_flag(srna, STRUCT_UNDO); - RNA_def_struct_ui_text(srna, "Addon", "Python addons to be loaded automatically"); + RNA_def_struct_ui_text(srna, "Add-on", "Python add-ons to be loaded automatically"); prop = RNA_def_property(srna, "module", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Module", "Module name"); @@ -3232,7 +3232,7 @@ static void rna_def_userdef_addon_pref(BlenderRNA *brna) PropertyRNA *prop; srna = RNA_def_struct(brna, "AddonPreferences", NULL); - RNA_def_struct_ui_text(srna, "Addon Preferences", ""); + RNA_def_struct_ui_text(srna, "Add-on Preferences", ""); RNA_def_struct_sdna(srna, "bAddon"); /* WARNING: only a bAddon during registration */ RNA_def_struct_refine_func(srna, "rna_AddonPref_refine"); @@ -4600,7 +4600,7 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna) RNA_def_property_string_sdna(prop, NULL, "pythondir"); RNA_def_property_ui_text(prop, "Python Scripts Directory", "Alternate script path, matching the default layout with subdirs: " - "startup, addons & modules (requires restart)"); + "startup, add-ons & modules (requires restart)"); /* TODO, editing should reset sys.path! */ prop = RNA_def_property(srna, "i18n_branches_directory", PROP_STRING, PROP_DIRPATH); @@ -4692,7 +4692,7 @@ static void rna_def_userdef_addon_collection(BlenderRNA *brna, PropertyRNA *cpro func = RNA_def_function(srna, "remove", "rna_userdef_addon_remove"); RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove add-on"); - parm = RNA_def_pointer(func, "addon", "Addon", "", "Addon to remove"); + parm = RNA_def_pointer(func, "addon", "Addon", "", "Add-on to remove"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); } @@ -4768,7 +4768,7 @@ void RNA_def_userdef(BlenderRNA *brna) prop = RNA_def_property(srna, "addons", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "addons", NULL); RNA_def_property_struct_type(prop, "Addon"); - RNA_def_property_ui_text(prop, "Addon", ""); + RNA_def_property_ui_text(prop, "Add-on", ""); rna_def_userdef_addon_collection(brna, prop); prop = RNA_def_property(srna, "autoexec_paths", PROP_COLLECTION, PROP_NONE); diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index 41ebd865720..df94975e274 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -73,7 +73,7 @@ typedef struct ScrewVertIter { #define SV_UNUSED (UINT_MAX) #define SV_INVALID ((UINT_MAX) - 1) -#define SV_IS_VALID(v) (v < SV_INVALID) +#define SV_IS_VALID(v) ((v) < SV_INVALID) static void screwvert_iter_init(ScrewVertIter *iter, ScrewVertConnect *array, unsigned int v_init, unsigned int dir) { diff --git a/source/blender/modifiers/intern/MOD_shapekey.c b/source/blender/modifiers/intern/MOD_shapekey.c index a543aac74b9..97aae733532 100644 --- a/source/blender/modifiers/intern/MOD_shapekey.c +++ b/source/blender/modifiers/intern/MOD_shapekey.c @@ -124,6 +124,7 @@ ModifierTypeInfo modifierType_ShapeKey = { /* structSize */ sizeof(ShapeKeyModifierData), /* type */ eModifierTypeType_OnlyDeform, /* flags */ eModifierTypeFlag_AcceptsCVs | + eModifierTypeFlag_AcceptsLattice | eModifierTypeFlag_SupportsEditmode, /* copyData */ NULL, diff --git a/source/blender/python/mathutils/mathutils_Matrix.h b/source/blender/python/mathutils/mathutils_Matrix.h index 9ae5a4bd61d..542a0e349c7 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.h +++ b/source/blender/python/mathutils/mathutils_Matrix.h @@ -41,7 +41,7 @@ extern PyTypeObject matrix_access_Type; # define MATRIX_ITEM_ASSERT(_mat, _row, _col) (void)0 #endif -#define MATRIX_ITEM_INDEX_NUMROW(_totrow, _row, _col) ((_totrow * (_col)) + (_row)) +#define MATRIX_ITEM_INDEX_NUMROW(_totrow, _row, _col) (((_totrow) * (_col)) + (_row)) #define MATRIX_ITEM_INDEX(_mat, _row, _col) (MATRIX_ITEM_ASSERT(_mat, _row, _col),(((_mat)->num_row * (_col)) + (_row))) #define MATRIX_ITEM_PTR( _mat, _row, _col) ((_mat)->matrix + MATRIX_ITEM_INDEX(_mat, _row, _col)) #define MATRIX_ITEM( _mat, _row, _col) ((_mat)->matrix [MATRIX_ITEM_INDEX(_mat, _row, _col)]) diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index 2d26fcf4905..bddd84c45d7 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -359,102 +359,109 @@ static const char *name_from_passtype(int passtype, int channel) return "Unknown"; } -static int passtype_from_name(const char *str) +static int passtype_from_name(const char *str, int passflag) { + /* We do not really support several pass of the same types, so in case we are opening an EXR file with several pass + * names detected as same pass type, only return that pass type the first time, and return 'uknown' for the others. + * See T48466. */ +#define RETURN_PASS(_passtype) return (passflag & (_passtype)) ? 0 : (_passtype) + if (STRPREFIX(str, "Combined")) - return SCE_PASS_COMBINED; + RETURN_PASS(SCE_PASS_COMBINED); if (STRPREFIX(str, "Depth")) - return SCE_PASS_Z; + RETURN_PASS(SCE_PASS_Z); if (STRPREFIX(str, "Vector")) - return SCE_PASS_VECTOR; + RETURN_PASS(SCE_PASS_VECTOR); if (STRPREFIX(str, "Normal")) - return SCE_PASS_NORMAL; + RETURN_PASS(SCE_PASS_NORMAL); if (STRPREFIX(str, "UV")) - return SCE_PASS_UV; + RETURN_PASS(SCE_PASS_UV); if (STRPREFIX(str, "Color")) - return SCE_PASS_RGBA; + RETURN_PASS(SCE_PASS_RGBA); if (STRPREFIX(str, "Emit")) - return SCE_PASS_EMIT; + RETURN_PASS(SCE_PASS_EMIT); if (STRPREFIX(str, "Diffuse")) - return SCE_PASS_DIFFUSE; + RETURN_PASS(SCE_PASS_DIFFUSE); if (STRPREFIX(str, "Spec")) - return SCE_PASS_SPEC; + RETURN_PASS(SCE_PASS_SPEC); if (STRPREFIX(str, "Shadow")) - return SCE_PASS_SHADOW; + RETURN_PASS(SCE_PASS_SHADOW); if (STRPREFIX(str, "AO")) - return SCE_PASS_AO; + RETURN_PASS(SCE_PASS_AO); if (STRPREFIX(str, "Env")) - return SCE_PASS_ENVIRONMENT; + RETURN_PASS(SCE_PASS_ENVIRONMENT); if (STRPREFIX(str, "Indirect")) - return SCE_PASS_INDIRECT; + RETURN_PASS(SCE_PASS_INDIRECT); if (STRPREFIX(str, "Reflect")) - return SCE_PASS_REFLECT; + RETURN_PASS(SCE_PASS_REFLECT); if (STRPREFIX(str, "Refract")) - return SCE_PASS_REFRACT; + RETURN_PASS(SCE_PASS_REFRACT); if (STRPREFIX(str, "IndexOB")) - return SCE_PASS_INDEXOB; + RETURN_PASS(SCE_PASS_INDEXOB); if (STRPREFIX(str, "IndexMA")) - return SCE_PASS_INDEXMA; + RETURN_PASS(SCE_PASS_INDEXMA); if (STRPREFIX(str, "Mist")) - return SCE_PASS_MIST; + RETURN_PASS(SCE_PASS_MIST); if (STRPREFIX(str, "RayHits")) - return SCE_PASS_RAYHITS; + RETURN_PASS(SCE_PASS_RAYHITS); if (STRPREFIX(str, "DiffDir")) - return SCE_PASS_DIFFUSE_DIRECT; + RETURN_PASS(SCE_PASS_DIFFUSE_DIRECT); if (STRPREFIX(str, "DiffInd")) - return SCE_PASS_DIFFUSE_INDIRECT; + RETURN_PASS(SCE_PASS_DIFFUSE_INDIRECT); if (STRPREFIX(str, "DiffCol")) - return SCE_PASS_DIFFUSE_COLOR; + RETURN_PASS(SCE_PASS_DIFFUSE_COLOR); if (STRPREFIX(str, "GlossDir")) - return SCE_PASS_GLOSSY_DIRECT; + RETURN_PASS(SCE_PASS_GLOSSY_DIRECT); if (STRPREFIX(str, "GlossInd")) - return SCE_PASS_GLOSSY_INDIRECT; + RETURN_PASS(SCE_PASS_GLOSSY_INDIRECT); if (STRPREFIX(str, "GlossCol")) - return SCE_PASS_GLOSSY_COLOR; + RETURN_PASS(SCE_PASS_GLOSSY_COLOR); if (STRPREFIX(str, "TransDir")) - return SCE_PASS_TRANSM_DIRECT; + RETURN_PASS(SCE_PASS_TRANSM_DIRECT); if (STRPREFIX(str, "TransInd")) - return SCE_PASS_TRANSM_INDIRECT; + RETURN_PASS(SCE_PASS_TRANSM_INDIRECT); if (STRPREFIX(str, "TransCol")) - return SCE_PASS_TRANSM_COLOR; + RETURN_PASS(SCE_PASS_TRANSM_COLOR); if (STRPREFIX(str, "SubsurfaceDir")) - return SCE_PASS_SUBSURFACE_DIRECT; + RETURN_PASS(SCE_PASS_SUBSURFACE_DIRECT); if (STRPREFIX(str, "SubsurfaceInd")) - return SCE_PASS_SUBSURFACE_INDIRECT; + RETURN_PASS(SCE_PASS_SUBSURFACE_INDIRECT); if (STRPREFIX(str, "SubsurfaceCol")) - return SCE_PASS_SUBSURFACE_COLOR; + RETURN_PASS(SCE_PASS_SUBSURFACE_COLOR); return 0; + +#undef RETURN_PASS } @@ -838,8 +845,9 @@ static void ml_addpass_cb(void *base, void *lay, const char *str, float *rect, i BLI_addtail(&rl->passes, rpass); rpass->channels = totchan; - rpass->passtype = passtype_from_name(str); - if (rpass->passtype == 0) printf("unknown pass %s\n", str); + rpass->passtype = passtype_from_name(str, rl->passflag); + if (rpass->passtype == 0) + printf("unknown pass %s\n", str); rl->passflag |= rpass->passtype; /* channel id chars */ diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index db2547e4fbe..388837af67a 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -220,6 +220,7 @@ void WM_event_timer_sleep(struct wmWindowManager *wm, struct wmWindow *wi /* invoke callback, uses enum property named "type" */ void WM_operator_view3d_unit_defaults(struct bContext *C, struct wmOperator *op); int WM_operator_smooth_viewtx_get(const struct wmOperator *op); +int WM_menu_invoke_ex(struct bContext *C, struct wmOperator *op, int opcontext); int WM_menu_invoke (struct bContext *C, struct wmOperator *op, const struct wmEvent *event); int WM_enum_search_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event); /* invoke callback, confirm menu + exec */ diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 36b819d3495..729af731dfe 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -435,8 +435,7 @@ void wm_file_read_report(bContext *C) } BKE_reportf(reports, RPT_ERROR, - "Engine '%s' not available for scene '%s' " - "(an addon may need to be installed or enabled)", + "Engine '%s' not available for scene '%s' (an add-on may need to be installed or enabled)", sce->r.engine, sce->id.name + 2); } } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 6ef8965a408..b4295bb2607 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1068,7 +1068,7 @@ int WM_operator_smooth_viewtx_get(const wmOperator *op) } /* invoke callback, uses enum property named "type" */ -int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +int WM_menu_invoke_ex(bContext *C, wmOperator *op, int opcontext) { PropertyRNA *prop = op->type->prop; uiPopupMenu *pup; @@ -1090,8 +1090,8 @@ int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE); layout = UI_popup_menu_layout(pup); /* set this so the default execution context is the same as submenus */ - uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN); - uiItemsFullEnumO(layout, op->type->idname, RNA_property_identifier(prop), op->ptr->data, WM_OP_EXEC_REGION_WIN, 0); + uiLayoutSetOperatorContext(layout, opcontext); + uiItemsFullEnumO(layout, op->type->idname, RNA_property_identifier(prop), op->ptr->data, opcontext, 0); UI_popup_menu_end(C, pup); return OPERATOR_INTERFACE; } @@ -1099,6 +1099,11 @@ int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) return OPERATOR_CANCELLED; } +int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + return WM_menu_invoke_ex(C, op, WM_OP_INVOKE_REGION_WIN); +} + /* generic enum search invoke popup */ static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op) diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index 449612bc5fd..e2b95da29a1 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -343,37 +343,38 @@ enum { /* *********** wmEvent.type helpers. ********** */ /* test whether the event is timer event */ -#define ISTIMER(event_type) (event_type >= TIMER && event_type <= TIMERF) +#define ISTIMER(event_type) ((event_type) >= TIMER && (event_type) <= TIMERF) /* for event checks */ /* only used for KM_TEXTINPUT, so assume that we want all user-inputtable ascii codes included */ /* UNUSED - see wm_eventmatch - BUG [#30479] */ -/* #define ISTEXTINPUT(event_type) (event_type >= ' ' && event_type <= 255) */ +/* #define ISTEXTINPUT(event_type) ((event_type) >= ' ' && (event_type) <= 255) */ /* note, an alternative could be to check 'event->utf8_buf' */ /* test whether the event is a key on the keyboard */ #define ISKEYBOARD(event_type) \ - ((event_type >= 0x0020 && event_type <= 0x00ff) || \ - (event_type >= 0x012c && event_type <= 0x013f)) + (((event_type) >= 0x0020 && (event_type) <= 0x00ff) || \ + ((event_type) >= 0x012c && (event_type) <= 0x013f)) /* test whether the event is a modifier key */ -#define ISKEYMODIFIER(event_type) ((event_type >= LEFTCTRLKEY && event_type <= LEFTSHIFTKEY) || event_type == OSKEY) +#define ISKEYMODIFIER(event_type) \ + (((event_type) >= LEFTCTRLKEY && (event_type) <= LEFTSHIFTKEY) || (event_type) == OSKEY) /* test whether the event is a mouse button */ -#define ISMOUSE(event_type) (event_type >= LEFTMOUSE && event_type <= BUTTON7MOUSE) +#define ISMOUSE(event_type) ((event_type) >= LEFTMOUSE && (event_type) <= BUTTON7MOUSE) /* test whether the event is tweak event */ -#define ISTWEAK(event_type) (event_type >= EVT_TWEAK_L && event_type <= EVT_GESTURE) +#define ISTWEAK(event_type) ((event_type) >= EVT_TWEAK_L && (event_type) <= EVT_GESTURE) /* test whether the event is a NDOF event */ -#define ISNDOF(event_type) (event_type >= NDOF_MOTION && event_type < NDOF_LAST) +#define ISNDOF(event_type) ((event_type) >= NDOF_MOTION && (event_type) < NDOF_LAST) /* test whether event type is acceptable as hotkey, excluding modifiers */ #define ISHOTKEY(event_type) \ ((ISKEYBOARD(event_type) || ISMOUSE(event_type) || ISNDOF(event_type)) && \ - (event_type != ESCKEY) && \ - (event_type >= LEFTCTRLKEY && event_type <= LEFTSHIFTKEY) == false && \ - (event_type >= UNKNOWNKEY && event_type <= GRLESSKEY) == false) + ((event_type) != ESCKEY) && \ + ((event_type) >= LEFTCTRLKEY && (event_type) <= LEFTSHIFTKEY) == false && \ + ((event_type) >= UNKNOWNKEY && (event_type) <= GRLESSKEY) == false) /* internal helpers*/ #define _VA_IS_EVENT_MOD2(v, a) (CHECK_TYPE_INLINE(v, wmEvent *), \ diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 90340096a43..95abfdc4f4c 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -530,6 +530,7 @@ SnapObjectContext *ED_transform_snap_object_context_create_view3d( void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx) RET_NONE bool ED_transform_snap_object_project_ray_ex( struct SnapObjectContext *sctx, + const unsigned short snap_to, const struct SnapObjectParams *params, const float ray_start[3], const float ray_normal[3], float *ray_depth, /* return args */ diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index e3cbfbf838b..122c10ef216 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -692,6 +692,10 @@ elseif(WIN32) ) if(WITH_PYTHON_INSTALL_NUMPY) + set(PYTHON_NUMPY_VERSION 1.9) + if(MSVC_VERSION EQUAL 1900) + set(PYTHON_NUMPY_VERSION 1.11) + endif() add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${BLENDER_VERSION}/python/lib/site-packages COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${BLENDER_VERSION}/python/lib/site-packages) @@ -699,9 +703,9 @@ elseif(WIN32) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${BLENDER_VERSION}/python/lib/site-packages/numpy COMMAND ${CMAKE_COMMAND} -E - tar xzvf "${LIBDIR}/release/python${_PYTHON_VERSION_NO_DOTS}_numpy_1.9.tar.gz" + tar xzvf "${LIBDIR}/release/python${_PYTHON_VERSION_NO_DOTS}_numpy_${PYTHON_NUMPY_VERSION}.tar.gz" DEPENDS - ${LIBDIR}/release/python${_PYTHON_VERSION_NO_DOTS}_numpy_1.9.tar.gz + ${LIBDIR}/release/python${_PYTHON_VERSION_NO_DOTS}_numpy_${PYTHON_NUMPY_VERSION}.tar.gz ${CMAKE_CURRENT_BINARY_DIR}/${BLENDER_VERSION}/python/lib/site-packages WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${BLENDER_VERSION}/python/lib/site-packages ) diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c index 69765fc2341..3b27ad6f693 100644 --- a/source/creator/creator_args.c +++ b/source/creator/creator_args.c @@ -583,9 +583,16 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo BLI_argsPrintArgDoc(ba, "--"); + printf("\n"); printf("Other Options:\n"); BLI_argsPrintOtherDoc(ba); + /* keep last args */ + printf("\n"); + printf("Experimental Features:\n"); + BLI_argsPrintArgDoc(ba, "--enable-new-depsgraph"); + + printf("\n"); printf("Argument Parsing:\n"); printf("\tArguments must be separated by white space, eg:\n"); printf("\t# blender -ba test.blend\n"); @@ -619,11 +626,6 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo #endif printf(" $PYTHONHOME Path to the python directory, eg. /usr/lib/python.\n\n"); - /* keep last */ - printf("\n"); - printf("Experimental Features:\n"); - BLI_argsPrintArgDoc(ba, "--enable-new-depsgraph"); - exit(0); return 0; @@ -862,7 +864,7 @@ static const char arg_handle_playback_mode_doc[] = "<options> <file(s)>\n" "\tPlayback <file(s)>, only operates this way when not running in background.\n" "\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>\n" -"\t\t-m\t\tRead from disk (Don't buffer)\n" +"\t\t-m\t\tRead from disk (Do not buffer)\n" "\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with\n" "\t\t-j <frame>\tSet frame step to <frame>\n" "\t\t-s <frame>\tPlay from <frame>\n" @@ -950,10 +952,10 @@ static int arg_handle_start_with_console(int UNUSED(argc), const char **UNUSED(a } static const char arg_handle_register_extension_doc[] = -"\n\tRegister .blend extension, then exit (Windows only)" +"\n\tRegister blend-file extension, then exit (Windows only)" ; static const char arg_handle_register_extension_doc_silent[] = -"\n\tSilently register .blend extension, then exit (Windows only)" +"\n\tSilently register blend-file extension, then exit (Windows only)" ; static int arg_handle_register_extension(int UNUSED(argc), const char **UNUSED(argv), void *data) { |