From 543c64ef74d87e8f824a3b12d9c1e1b548407c0e Mon Sep 17 00:00:00 2001 From: Howard Trickey Date: Wed, 1 Jun 2016 08:51:08 -0400 Subject: Fix bug where corner boundary was straight when it should curve. Some adjustments to how bevel edge 'profiles' are adjusted in some cases. For the bug fix, wanted to handle cases of middle of three coplanar beveled cases to make profile curve rather than linear interpolate. Also undid an earlier decision to make profile plane be perpendicular to beveled edge i the non-coplanar case. --- source/blender/bmesh/tools/bmesh_bevel.c | 75 ++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 17 deletions(-) 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--) { -- cgit v1.2.3 From 8cf8679b53e3aabb325301739d79ee1440977053 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 1 Jun 2016 23:07:52 +1000 Subject: Revert "Correct invalid pointer-pair compare check" This reverts commit d5e0e681cea846facb4f2777921f6612be3ee193. Tsk, these functions return false on a match. --- source/blender/blenlib/intern/BLI_ghash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index 0b5adab3929..857ce1adef2 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)); } -- cgit v1.2.3 From b1704d18a1cc15f0dbb5fe6e27d80f0fae4b9e72 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 1 Jun 2016 15:26:58 +0200 Subject: Fix T48415: Segfault on opening .blend in which a 'surface' force object was saved in Edit mode. In that case, surface modifier won't run (until surface object goes back to Object mode), and its bvhtree remains NULL. --- source/blender/blenkernel/intern/effect.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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]; -- cgit v1.2.3 From 2c5dc66d5effd4072f438afb93d70546891ea98e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 2 Jun 2016 00:04:51 +1000 Subject: Optimize mempool iteration Around ~10% improvement in own tests. --- source/blender/blenlib/intern/BLI_mempool.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c index 38d15750761..b7a51f2c48e 100644 --- a/source/blender/blenlib/intern/BLI_mempool.c +++ b/source/blender/blenlib/intern/BLI_mempool.c @@ -605,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); -- cgit v1.2.3 From 6befc762652998690395083ec29caa801b24a284 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 1 Jun 2016 17:25:05 +0200 Subject: Fix T48466: Multiple passes starting with 'Diffuse' in EXR file breaks its loading in Blender. Issue here is that for Blender, any pass which name starts with 'Diffuse' is considered a diffuse pass - and it does not really support several passes of the same type in renderresult. So for now, passtype_from_name() is now checking whether a pass of same type already exists in render layers, and return 0 (uknown passtype) in this case. --- .../blender/render/intern/source/render_result.c | 76 ++++++++++++---------- 1 file changed, 42 insertions(+), 34 deletions(-) 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 */ -- cgit v1.2.3 From 57d5ddc2519379a16c735edbdc30b9d843f636da Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 1 Jun 2016 17:38:50 +0200 Subject: Revert "BLI_ghash: Fix initial over-allocation of mempool chunks." Useless change in fact, sorry for the noise. This reverts commit b08473680e141ab6f28f99fc3b1dbbc4add89bed. --- source/blender/blenlib/intern/BLI_ghash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index 857ce1adef2..06946e520a8 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -441,7 +441,7 @@ static GHash *ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info, gh->flag = flag; ghash_buckets_reset(gh, nentries_reserve); - gh->entrypool = BLI_mempool_create(GHASH_ENTRY_SIZE(flag & GHASH_FLAG_IS_GSET), 0, 64, BLI_MEMPOOL_NOP); + gh->entrypool = BLI_mempool_create(GHASH_ENTRY_SIZE(flag & GHASH_FLAG_IS_GSET), 64, 64, BLI_MEMPOOL_NOP); return gh; } -- cgit v1.2.3 From 24712b1c0b20c84caab47fcfae83b7998e272aa6 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 1 Jun 2016 20:38:30 +0200 Subject: Usual UI/i18n message cleanup (get rid of last remaining 'addon' too). --- intern/cycles/blender/addon/ui.py | 2 +- release/scripts/modules/bl_i18n_utils/utils_spell_check.py | 8 ++++++-- release/scripts/startup/bl_ui/__init__.py | 2 +- source/blender/editors/animation/drivers.c | 2 +- source/blender/editors/interface/interface_ops.c | 2 +- source/blender/makesrna/intern/rna_userdef.c | 14 +++++++------- source/blender/windowmanager/intern/wm_files.c | 3 +-- 7 files changed, 18 insertions(+), 15 deletions(-) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 023841a7a17..6a109c60ed1 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -704,7 +704,7 @@ class Cycles_PT_mesh_displacement(CyclesButtonsPanel, Panel): col = split.column() sub = col.column(align=True) - sub.label(text="Displacment:") + sub.label(text="Displacement:") sub.prop(cdata, "displacement_method", text="") col = split.column() diff --git a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py index df014e8262b..636b6b0f46b 100644 --- a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py +++ b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py @@ -58,7 +58,7 @@ class SpellChecker: "vertices", # Merged words - "addon", "addons", + #~ "addon", "addons", "antialiasing", "arcsine", "arccosine", "arctangent", "autoclip", @@ -118,6 +118,7 @@ class SpellChecker: "localview", "lookup", "lookups", "mathutils", + "micropolygon", "midlevel", "midground", "mixdown", @@ -127,6 +128,7 @@ class SpellChecker: "multires", "multiresolution", "multisampling", "multitexture", + "multithreaded", "multiuser", "multiview", "namespace", @@ -412,6 +414,7 @@ class SpellChecker: # Blender terms "audaspace", "bbone", + "bendy", # bones "bmesh", "breakdowner", "bspline", @@ -473,9 +476,10 @@ class SpellChecker: "wpaint", "uvwarp", - # Algorithm names + # Algorithm/library names "ashikhmin", # Ashikhmin-Shirley "beckmann", + "blosc", "catmull", "catrom", "chebychev", diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py index 6fc668e67f5..2389be6787d 100644 --- a/release/scripts/startup/bl_ui/__init__.py +++ b/release/scripts/startup/bl_ui/__init__.py @@ -126,7 +126,7 @@ def register(): WindowManager.addon_filter = EnumProperty( items=addon_filter_items, name="Category", - description="Filter addons by category", + description="Filter add-ons by category", ) WindowManager.addon_support = EnumProperty( diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index 51f962d4a1e..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} 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/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/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); } } -- cgit v1.2.3 From c4b23a57a9c4f2ca82a1402d16e44237eaed54b7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 2 Jun 2016 12:51:36 +1000 Subject: Fix T48566: Render-border minor offset issue --- source/blender/editors/space_view3d/view3d_draw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 01e23f26568..445a4cbdfd6 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1179,10 +1179,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); -- cgit v1.2.3 From 1e9b222322a23a8dd516ccb0b22d82a4a1b58590 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 2 Jun 2016 15:12:29 +1000 Subject: ShapeKey was missing lattice-flag missed from 7a8bd2eae --- source/blender/modifiers/intern/MOD_shapekey.c | 1 + 1 file changed, 1 insertion(+) 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, -- cgit v1.2.3 From d931e958a1a2e4080c84ed757e8db00bf64594e0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 2 Jun 2016 15:22:33 +1000 Subject: Minor changes to help text D2040 by @Blendify, also move 'Experimental Features' above more general help text. --- source/creator/creator_args.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) 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[] = " \n" "\tPlayback , only operates this way when not running in background.\n" "\t\t-p \tOpen with lower left corner at , \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 \t\tSpecify FPS to start with\n" "\t\t-j \tSet frame step to \n" "\t\t-s \tPlay from \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) { -- cgit v1.2.3 From 0bd8d6d1949f29d283c6f00d4a316c4c9b2c8a5e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 2 Jun 2016 16:41:41 +1000 Subject: Add extra validation checks to array-store --- source/blender/blenlib/intern/array_store.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c index 7f657f4a048..b559061d2e3 100644 --- a/source/blender/blenlib/intern/array_store.c +++ b/source/blender/blenlib/intern/array_store.c @@ -1640,6 +1640,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) != 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 } { -- cgit v1.2.3 From 7980c7c10f0270843e68bdad3a752aa2154d226a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 2 Jun 2016 18:01:03 +1000 Subject: BLI_array_store: store max size in BArrayInfo --- source/blender/blenlib/intern/array_store.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c index b559061d2e3..2e112576dd2 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 */ @@ -548,6 +550,8 @@ static void bchunk_list_append_data( const ubyte *data, const size_t data_len) { BLI_assert(data_len != 0); + BLI_assert(data_len <= info->chunk_byte_size_max); + // printf("data_len: %d\n", data_len); #ifdef USE_MERGE_CHUNKS if (!BLI_listbase_is_empty(&chunk_list->chunk_refs)) { @@ -1374,6 +1378,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 -- cgit v1.2.3 From 0ce98b1ffbd59ff6d9ee3933afe0d2c7286c70d7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 2 Jun 2016 16:58:29 +1000 Subject: BLI_array_store: Move writing many chunks into a function Minor optimization, avoid some checks each iteration. --- source/blender/blenlib/intern/array_store.c | 163 +++++++++++++++++++--------- 1 file changed, 111 insertions(+), 52 deletions(-) diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c index 2e112576dd2..0b53be05e84 100644 --- a/source/blender/blenlib/intern/array_store.c +++ b/source/blender/blenlib/intern/array_store.c @@ -529,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. */ @@ -544,6 +591,10 @@ 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, @@ -593,6 +644,58 @@ 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) { + const size_t i = info->chunk_byte_size; + bchunk_list_append_data(info, bs_mem, chunk_list, data, i); + size_t 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 + + ASSERT_CHUNKLIST_SIZE(chunk_list, data_len); + ASSERT_CHUNKLIST_DATA(chunk_list, data); +} + static void bchunk_list_append( const BArrayInfo *info, BArrayMemory *bs_mem, BChunkList *chunk_list, @@ -615,37 +718,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); @@ -1224,21 +1301,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 */ @@ -1298,14 +1362,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); -- cgit v1.2.3 From cc7b8170998d2cd85a3572cf8ef18a8425e4af00 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 2 Jun 2016 18:42:09 +1000 Subject: Minor edits to last commit Failed with chunk merging disabled --- source/blender/blenlib/intern/array_store.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c index 0b53be05e84..1bdb37051eb 100644 --- a/source/blender/blenlib/intern/array_store.c +++ b/source/blender/blenlib/intern/array_store.c @@ -601,10 +601,11 @@ static void bchunk_list_append_data( const ubyte *data, const size_t data_len) { BLI_assert(data_len != 0); - BLI_assert(data_len <= info->chunk_byte_size_max); // 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; @@ -691,9 +692,6 @@ static void bchunk_list_append_data_n( BLI_assert(((BChunkRef *)chunk_list->chunk_refs.last)->link->data_len >= info->chunk_byte_size_min); } #endif - - ASSERT_CHUNKLIST_SIZE(chunk_list, data_len); - ASSERT_CHUNKLIST_DATA(chunk_list, data); } static void bchunk_list_append( -- cgit v1.2.3 From 64663b1f736eb0ac234200d74a9e3a78273d939f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 2 Jun 2016 19:48:16 +1000 Subject: Cleanup: warnings in previous commit --- source/blender/blenlib/intern/array_store.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c index 1bdb37051eb..9baccf38fa3 100644 --- a/source/blender/blenlib/intern/array_store.c +++ b/source/blender/blenlib/intern/array_store.c @@ -661,9 +661,13 @@ static void bchunk_list_append_data_n( bchunk_list_calc_trim_len(info, data_len, &data_trim_len, &data_last_chunk_len); if (data_trim_len != 0) { - const size_t i = info->chunk_byte_size; - bchunk_list_append_data(info, bs_mem, chunk_list, data, i); - size_t i_prev = i; + 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; @@ -1703,7 +1707,7 @@ bool BLI_array_store_is_valid( return false; } - if (BLI_listbase_count(&chunk_list->chunk_refs) != chunk_list->chunk_refs_len) { + if (BLI_listbase_count(&chunk_list->chunk_refs) != (int)chunk_list->chunk_refs_len) { return false; } -- cgit v1.2.3 From 664e854af7fa2c4ba6ee81559256f08096f84165 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Thu, 2 Jun 2016 20:19:56 +1000 Subject: Fix leak using UI_BTYPE_TEXT button w/o a callback Moving ownership of the string to the button's 'rename_orig' leaked when the button didn't have a uiAfterFunc. --- source/blender/editors/interface/interface_handlers.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) 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; } -- cgit v1.2.3 From ac8246cd893c417d89dfde9704cc0ae2edbbc936 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 2 Jun 2016 14:00:00 +0200 Subject: Fix for GLSL uniform being update from inside glBegin/glEnd This seems to be illegal and not productive anyway. Do it ahead of a time now, which solves shading issues in edit mode and prevents assert from happening. --- source/blender/blenkernel/intern/editderivedmesh.c | 23 ++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index fbb5069425c..ffd000eed88 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -1406,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 * @@ -1432,7 +1450,6 @@ static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const B glTexCoord3fv(orco); else glVertexAttrib3fv(attribs->orco.gl_index, orco); - glUniform1i(attribs->orco.gl_info_index, 0); } for (i = 0; i < attribs->tottface; i++) { const float *uv; @@ -1449,7 +1466,6 @@ static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const B glTexCoord2fv(uv); else glVertexAttrib2fv(attribs->tface[i].gl_index, uv); - glUniform1i(attribs->tface[i].gl_info_index, 0); } for (i = 0; i < attribs->totmcol; i++) { float col[4]; @@ -1461,7 +1477,6 @@ static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const B col[0] = 0.0f; col[1] = 0.0f; col[2] = 0.0f; col[3] = 0.0f; } glVertexAttrib4fv(attribs->mcol[i].gl_index, col); - glUniform1i(attribs->mcol[i].gl_info_index, GPU_ATTR_INFO_SRGB); } for (i = 0; i < attribs->tottang; i++) { @@ -1473,7 +1488,6 @@ static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const B tang = zero; } glVertexAttrib4fv(attribs->tang[i].gl_index, tang); - glUniform1i(attribs->tang[i].gl_info_index, 0); } } @@ -1532,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); } -- cgit v1.2.3 From 68d1348ca2f4ae7fcd6eff5b7bdbd84d75988ae8 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 2 Jun 2016 15:57:58 +0200 Subject: Fix T47637: Multiple multires objects in Sculpt mode make blender crash. That was a nice and funny hunt, albeit rather time consumming! To summarize, so far code was using a static global gpu_buffer for pbvh vbo drawing of 'grid' types (multires mostly?). There were two issues here: 1) Global gpu buffer was assigned to GPU_PBVH_Buffers->index_buf, but then nearly no check was done when freeing that buffer, to ensure we were not freeing the global one (not totally sure this one was actually causing any issue, but was bad and unsafe anyway). Was solved by adding a flag to GPU_PBVH_Buffers to indicate when we are using some 'common' buffer here, which freeing is handled separately. 2) Main issue: if several multires objects in sculpt mode with different grid size were present simultaneously, the global gpu buffer had to be resized for each object draw (i.e., freed and re-allocated), but then the pbvh nodes from other objects storing freed reference to that global buffer had no way to know that it had been freed, which was causing the segfault & crash. Was solved by getting rid of that global buffer, and instead allocating one 'grid_commmon_gpu_buffer' per pbvh. Told ya baby, globals are *PURE EVIL*! --- source/blender/blenkernel/intern/pbvh.c | 3 +- source/blender/blenkernel/intern/pbvh_intern.h | 5 + source/blender/gpu/GPU_buffers.h | 10 +- source/blender/gpu/intern/gpu_buffers.c | 124 ++++++++++++++----------- source/blender/gpu/intern/gpu_init_exit.c | 1 - 5 files changed, 83 insertions(+), 60 deletions(-) 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/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index ee7abe08aba..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; @@ -160,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, @@ -231,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); @@ -267,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/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index f80ce3c1fab..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; @@ -1009,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; @@ -1226,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 */ @@ -1248,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; } } @@ -1416,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 */ @@ -1439,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_) \ @@ -1476,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; @@ -1506,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; @@ -1522,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 */ @@ -1746,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); @@ -1792,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; } } @@ -1991,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); @@ -2004,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_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; } -- cgit v1.2.3 From c5b2f12b36a048ffe7c78f42ffeed1e190ad8d1d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 3 Jun 2016 01:07:29 +1000 Subject: Fix T48456: 2x pixel size clamps min brush size Using double pixel size prevented 1px brushes D2044 by @jeske --- source/blender/blenkernel/intern/brush.c | 2 +- source/blender/editors/sculpt_paint/paint_cursor.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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/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 */ -- cgit v1.2.3 From a055523899b0d8ba09f5bb3766ef34ce11cefc08 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 3 Jun 2016 01:57:34 +1000 Subject: Theme: 2.4x, correct graph region color --- release/scripts/presets/interface_theme/blender_24x.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/presets/interface_theme/blender_24x.xml b/release/scripts/presets/interface_theme/blender_24x.xml index ae42b605556..90730aeaebc 100644 --- a/release/scripts/presets/interface_theme/blender_24x.xml +++ b/release/scripts/presets/interface_theme/blender_24x.xml @@ -371,7 +371,7 @@ header="#b4b4b4" header_text="#000000" header_text_hi="#ffffff" - button="#727272ff" + button="#b4b4b457" button_title="#000000" button_text="#000000" button_text_hi="#ffffff" -- cgit v1.2.3 From cd768a8df1031cb76fea37dc9984707898f1d61f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 3 Jun 2016 02:43:04 +1000 Subject: Add upstream information to wcwidth library --- extern/wcwidth/README.blender | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 extern/wcwidth/README.blender diff --git a/extern/wcwidth/README.blender b/extern/wcwidth/README.blender new file mode 100644 index 00000000000..27c8574d1d7 --- /dev/null +++ b/extern/wcwidth/README.blender @@ -0,0 +1,5 @@ +Project: WC Width +URL: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c +License: ICS +Upstream version: 2007-05-26 +Local modifications: None -- cgit v1.2.3 From 528539ef599402bf15721548fbce4ce7ea951f5d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 3 Jun 2016 15:11:56 +1000 Subject: Fix T48575: Particle crash using 'Parting' setting --- source/blender/blenkernel/intern/particle.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) 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); -- cgit v1.2.3 From 8c154d67b2c158722242b3ff14c7c814996c7351 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 3 Jun 2016 15:28:32 +1000 Subject: Fix T48111: Auto-run fails w/ empty paths Enabling auto-run, then excluding a path but leaving it set to a blank value would ignore all paths. --- source/blender/blenkernel/intern/autoexec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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; } -- cgit v1.2.3 From e9363483caad3a038237489eea52443b20587bfd Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Fri, 3 Jun 2016 16:26:27 +1000 Subject: Fix possible uninitialized variable in snapping Introduced in 0b5a0d84, thanks to Brecht for spotting. --- .../editors/transform/transform_snap_object.c | 36 ++++++++++------------ 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index 62ca4e515a5..4a79310b753 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) { -- cgit v1.2.3 From e370806b38388bb501ab99f9eb65fe2ff10d9133 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Fri, 3 Jun 2016 16:54:58 +1000 Subject: Cleanup & simplify snapping functions - the name of the enumerator `SNAP_NOT_OBEDIT` was changed to `SNAP_NOT_ACTIVE`. - the parameter `snap_to_flag` was moved to outside `SnapObjectParams`. - the member `use_object_edit` was renamed to `use_object_edit_cage`. - added the arg `params` in `ED_transform_snap_object_project_ray`. - simplifications in the loop of the function `snapObjectsRay`. --- .../blender/editors/armature/editarmature_sketch.c | 9 +- source/blender/editors/curve/editcurve.c | 5 +- source/blender/editors/include/ED_transform.h | 13 ++- .../include/ED_transform_snap_object_context.h | 19 ++-- source/blender/editors/mesh/editmesh_tools.c | 5 +- source/blender/editors/space_view3d/view3d_ruler.c | 10 +- source/blender/editors/space_view3d/view3d_walk.c | 2 + source/blender/editors/transform/transform_snap.c | 39 +++---- .../editors/transform/transform_snap_object.c | 113 ++++++++------------- source/blender/makesrna/intern/rna_scene_api.c | 2 +- 10 files changed, 108 insertions(+), 109 deletions(-) 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_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/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/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..6859ffe5175 100644 --- a/source/blender/editors/space_view3d/view3d_walk.c +++ b/source/blender/editors/space_view3d/view3d_walk.c @@ -424,6 +424,7 @@ static bool walk_floor_distance_get( ret = ED_transform_snap_object_project_ray( walk->snap_context, + &(const struct SnapObjectParams){}, ray_start, ray_normal, r_distance, r_location, r_normal_dummy); @@ -455,6 +456,7 @@ static bool walk_ray_cast( ret = ED_transform_snap_object_project_ray( walk->snap_context, + &(const struct SnapObjectParams){}, ray_start, ray_normal, NULL, r_location, r_normal); diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index e72db4105a4..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); } diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index 4a79310b753..d7486372c36 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -1314,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++, @@ -1354,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; @@ -1383,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, @@ -1500,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); } /** @@ -1527,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; } @@ -1545,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); @@ -1573,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]) { @@ -1581,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); @@ -1595,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]) { @@ -1611,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, @@ -1632,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)) { @@ -1674,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, @@ -1681,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, @@ -1708,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, @@ -1728,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, @@ -1746,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)) @@ -1757,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/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, -- cgit v1.2.3 From f54a98a1c56e40f9d9d2c493fe2086e92da1150d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 3 Jun 2016 10:34:21 +0200 Subject: Cycles: Simplify check for degenerated faces on GPU Still not sure how to properly solve the issue, needs some trickery to get actual optimized values from intersection function (using printf() avoids some optimization and makes stuff render correct). For the time being let's just simplify check. --- intern/cycles/kernel/geom/geom_triangle_intersect.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h index d2957ad5474..4e2f46d58d3 100644 --- a/intern/cycles/kernel/geom/geom_triangle_intersect.h +++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h @@ -160,15 +160,10 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, #endif { #ifdef __KERNEL_GPU__ - float4 a = tri_b - tri_a, b = tri_c - tri_a; - if(len_squared(make_float3(a.y*b.z - a.z*b.y, - a.z*b.x - a.x*b.z, - a.x*b.y - a.y*b.x)) == 0.0f) - { + if(A == B && B == C) { return false; } #endif - /* Normalize U, V, W, and T. */ const float inv_det = 1.0f / det; isect->prim = triAddr; -- cgit v1.2.3 From f71feb34a3d9c0bafb2249d78f66e945ec2378a7 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 3 Jun 2016 11:46:57 +0200 Subject: Make playback invoked form animation editors more usable This covers the following workflow. Animator will disable Update All 3D views in order to get quick playback in a particular 3D editor. However, it also handy to see playback in all editors and image editors to see comparison of animation and reference footage. So the idea here is to refresh reasonable editors when playback is invoked from animation editors. Commit to make Hjalti happy. --- source/blender/editors/include/ED_screen_types.h | 1 + source/blender/editors/screen/screen_edit.c | 5 ++++- source/blender/editors/screen/screen_ops.c | 16 ++++++++-------- 3 files changed, 13 insertions(+), 9 deletions(-) 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/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; } -- cgit v1.2.3 From b406b7be00ceeaa5910ff87a50c1dea11cd4e9d8 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 3 Jun 2016 11:52:08 +0200 Subject: Cycles: Mark which CUDA device is used for display It is really handy to know which one is display when having two cards of same type in the machine. --- intern/cycles/device/device_cuda.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index d7ed7b4f853..2d404918a38 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -1368,6 +1368,7 @@ void device_cuda_info(vector& devices) /* if device has a kernel timeout, assume it is used for display */ if(cuDeviceGetAttribute(&attr, CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT, num) == CUDA_SUCCESS && attr == 1) { + info.description += " (Display)"; info.display_device = true; display_devices.push_back(info); } -- cgit v1.2.3 From 398180439be338dc05fcd07d42974eac77880e22 Mon Sep 17 00:00:00 2001 From: Jens Verwiebe Date: Fri, 3 Jun 2016 12:03:53 +0200 Subject: Fix Playercompile --- source/blenderplayer/bad_level_call_stubs/stubs.c | 1 + 1 file changed, 1 insertion(+) 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 */ -- cgit v1.2.3 From c6cc5993118965ae4208d748c54e7a70a3c5c1d3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 4 Jun 2016 00:54:28 +1000 Subject: Fix T48234: Glitch w/ action constraints sharing an action FCurve evaluation depended on FCurve.curval, which isn't threadsafe. Now only use this value for debug display, and pass the value instead of storing in the FCurve for all but debug-display. --- source/blender/blenkernel/BKE_animsys.h | 2 +- source/blender/blenkernel/BKE_fcurve.h | 2 +- source/blender/blenkernel/intern/anim_sys.c | 20 ++++++++++---------- source/blender/blenkernel/intern/fcurve.c | 9 +++++++-- source/blender/editors/space_action/action_edit.c | 9 ++++++--- source/blender/editors/space_graph/graph_edit.c | 9 ++++++--- source/blender/makesdna/DNA_anim_types.h | 2 +- 7 files changed, 32 insertions(+), 21 deletions(-) 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/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 41950c59a22..c85a2887a09 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -1620,7 +1620,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 +1631,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 +1654,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 +1684,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 +1753,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 +2888,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/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/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/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 */ -- cgit v1.2.3 From fac9f1c8407e3e049c8d9595329a3c2809cfa5b7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 4 Jun 2016 01:00:40 +1000 Subject: Workaround MSVC error --- source/blender/editors/space_view3d/view3d_walk.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c index 6859ffe5175..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,7 +425,9 @@ static bool walk_floor_distance_get( ret = ED_transform_snap_object_project_ray( walk->snap_context, - &(const struct SnapObjectParams){}, + &(const struct SnapObjectParams){ + .snap_select = SNAP_ALL, + }, ray_start, ray_normal, r_distance, r_location, r_normal_dummy); @@ -456,7 +459,9 @@ static bool walk_ray_cast( ret = ED_transform_snap_object_project_ray( walk->snap_context, - &(const struct SnapObjectParams){}, + &(const struct SnapObjectParams){ + .snap_select = SNAP_ALL, + }, ray_start, ray_normal, NULL, r_location, r_normal); -- cgit v1.2.3 From b000a01725aff8715ad24b9202ed711a1edffec5 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Fri, 3 Jun 2016 18:22:56 +0200 Subject: fix T48389 (wip) added warning for loops that define holes (polygons with holes not supported) --- source/blender/collada/MeshImporter.cpp | 28 +++++++++++++++++++++++++--- source/blender/collada/MeshImporter.h | 2 +- 2 files changed, 26 insertions(+), 4 deletions(-) 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 geom_uid_mat_mapping_map; // crazy name! std::multimap 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, -- cgit v1.2.3 From 38410e6e2527574176338fe7ba8711cbfdd2cc91 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Fri, 3 Jun 2016 18:26:12 +0200 Subject: changed use_connect from bool to a 3 state value (-1,0,1) --- source/blender/collada/ArmatureImporter.cpp | 164 ++++++++++++++++++---------- source/blender/collada/ArmatureImporter.h | 8 +- source/blender/collada/DocumentImporter.cpp | 4 +- source/blender/collada/ImportSettings.h | 1 + source/blender/collada/SkinInfo.cpp | 1 + source/blender/collada/collada.cpp | 2 + source/blender/collada/collada.h | 1 + source/blender/collada/collada_utils.h | 2 +- source/blender/editors/io/io_collada.c | 10 ++ 9 files changed, 128 insertions(+), 65 deletions(-) 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::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::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 &ob_arms) { std::vector::iterator ri; std::vector 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 &objects_to_scale) { + std::vector ob_arms; std::map::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::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::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 &layer_labels) +BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Node *node, int sibcount, std::vector &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 &layer_labels); - BoneExtended &add_bone_extended(EditBone *bone, COLLADAFW::Node * node, std::vector &layer_labels); + BoneExtended &add_bone_extended(EditBone *bone, COLLADAFW::Node * node, int sibcount, std::vector &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 &arm_objs); /** TagsMap typedef for uid_tags_map. */ typedef std::map 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 &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 *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/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::mapobject = 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/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)) { @@ -431,6 +434,9 @@ static void uiCollada_importSettings(uiLayout *layout, PointerRNA *imfptr) row = uiLayoutRow(box, false); 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, -- cgit v1.2.3 From 17fbce9549b6c031ae8745354e65c5e5acd308e2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 4 Jun 2016 10:51:34 +1000 Subject: Cleanup: avoid temp string edit --- source/blender/blenkernel/intern/anim_sys.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index c85a2887a09..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 */ -- cgit v1.2.3 From 50f432b1e0f49820db9d67526946bd794e2b05d6 Mon Sep 17 00:00:00 2001 From: Martijn Berger Date: Sat, 4 Jun 2016 11:42:48 +0200 Subject: CMake, minor changes to make Visual studio 2015 use a compatible numpy and the standard cmake CUDA/NVCC arguments flag allowing 2015 build to use msvc 2013 for cuda --- intern/cycles/kernel/CMakeLists.txt | 1 + source/creator/CMakeLists.txt | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 7c2fc1e4b14..61c484df094 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -234,6 +234,7 @@ if(WITH_CYCLES_CUDA_BINARIES) OUTPUT ${cuda_cubin} COMMAND ${CUDA_NVCC_EXECUTABLE} -arch=${arch} + ${CUDA_NVCC_FLAGS} -m${CUDA_BITS} --cubin ${CMAKE_CURRENT_SOURCE_DIR}/kernels/cuda/kernel.cu -o ${CMAKE_CURRENT_BINARY_DIR}/${cuda_cubin} 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 ) -- cgit v1.2.3 From ebbfd92859e70e0ecb2886329cb352a5875f1588 Mon Sep 17 00:00:00 2001 From: Martijn Berger Date: Sat, 4 Jun 2016 12:36:21 +0200 Subject: buildbot work around cuda / msvc compatibility issues --- build_files/buildbot/slave_compile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build_files/buildbot/slave_compile.py b/build_files/buildbot/slave_compile.py index 9a874e92c80..7886824d0c6 100644 --- a/build_files/buildbot/slave_compile.py +++ b/build_files/buildbot/slave_compile.py @@ -77,10 +77,10 @@ if 'cmake' in builder: elif builder.startswith('win'): if builder.endswith('_vc2015'): if builder.startswith('win64'): - cmake_options.extend(['-G', 'Visual Studio 14 2015 Win64']) + cmake_options.extend(['-G', 'Visual Studio 14 2015 Win64', b'-DCUDA_NVCC_FLAGS="-ccbin \\"C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\amd64\\""']) elif builder.startswith('win32'): bits = 32 - cmake_options.extend(['-G', 'Visual Studio 14 2015']) + cmake_options.extend(['-G', 'Visual Studio 14 2015', b'-DCUDA_NVCC_FLAGS="-ccbin \\"C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\""']) else: if builder.startswith('win64'): cmake_options.extend(['-G', 'Visual Studio 12 2013 Win64']) -- cgit v1.2.3 From 1d8637ec69275b4958034b112db81f4cf42cd521 Mon Sep 17 00:00:00 2001 From: Martijn Berger Date: Sat, 4 Jun 2016 17:41:11 +0200 Subject: buildbot work around cuda / msvc compatibility issues attempt 2/ passing a string from python to cmake to nvcc is harder then it looks --- build_files/buildbot/slave_compile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build_files/buildbot/slave_compile.py b/build_files/buildbot/slave_compile.py index 7886824d0c6..4fb879aea3b 100644 --- a/build_files/buildbot/slave_compile.py +++ b/build_files/buildbot/slave_compile.py @@ -77,10 +77,10 @@ if 'cmake' in builder: elif builder.startswith('win'): if builder.endswith('_vc2015'): if builder.startswith('win64'): - cmake_options.extend(['-G', 'Visual Studio 14 2015 Win64', b'-DCUDA_NVCC_FLAGS="-ccbin \\"C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\amd64\\""']) + cmake_options.extend(['-G', 'Visual Studio 14 2015 Win64', b'-DCUDA_NVCC_FLAGS="-ccbin C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\amd64\\"']) elif builder.startswith('win32'): bits = 32 - cmake_options.extend(['-G', 'Visual Studio 14 2015', b'-DCUDA_NVCC_FLAGS="-ccbin \\"C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\""']) + cmake_options.extend(['-G', 'Visual Studio 14 2015', b'-DCUDA_NVCC_FLAGS="-ccbin C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\"']) else: if builder.startswith('win64'): cmake_options.extend(['-G', 'Visual Studio 12 2013 Win64']) -- cgit v1.2.3 From 234801c8dc42f0f24e6f90691451b462942ffe56 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Sat, 4 Jun 2016 21:39:07 +0200 Subject: Fix T48587, constant fold should only be done for Mix Type. --- intern/cycles/render/nodes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 4656b3de9f3..df0fee63113 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -3383,7 +3383,7 @@ void MixNode::compile(OSLCompiler& compiler) bool MixNode::constant_fold(ShaderGraph *graph, ShaderOutput *, ShaderInput *optimized) { - if(type != ustring("Mix")) { + if(type != NODE_MIX_BLEND) { return false; } -- cgit v1.2.3 From 04bcaf07dc945578353a8675e1e5003d1c325102 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 4 Jun 2016 23:20:43 +0200 Subject: Fix T48580: path / branched path UI grayed out with OpenCL device that is not used. --- intern/cycles/blender/addon/ui.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 6a109c60ed1..0961c349fc3 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -76,9 +76,8 @@ def use_cuda(context): def use_branched_path(context): cscene = context.scene.cycles - device_type = context.user_preferences.system.compute_device_type - return (cscene.progressive == 'BRANCHED_PATH' and device_type != 'OPENCL') + return (cscene.progressive == 'BRANCHED_PATH' and not use_opencl(context)) def use_sample_all_lights(context): -- cgit v1.2.3 From 7f57c99be87d6cb1b7ac9f005fa79c374812a8b6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 6 Jun 2016 12:19:58 +1000 Subject: Fix T48579: RNA shadows new custom properties --- release/scripts/startup/bl_operators/wm.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 76d41d91b78..cc8921f1a8e 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1357,7 +1357,10 @@ class WM_OT_properties_add(Operator): return prop_new - prop = unique_name(item.keys()) + prop = unique_name( + {*item.keys(), + *type(item).bl_rna.properties.keys(), + }) item[prop] = 1.0 rna_idprop_ui_prop_update(item, prop) -- cgit v1.2.3 From 9d090ed1cde2ae75c36548ed31daae10f121317a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 6 Jun 2016 12:54:55 +1000 Subject: RNA: disable animating object dimensions --- source/blender/makesrna/intern/rna_object.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 9ebef9db454..a7f5c21cc76 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -2387,6 +2387,8 @@ static void rna_def_object(BlenderRNA *brna) prop = RNA_def_property(srna, "dimensions", PROP_FLOAT, PROP_XYZ_LENGTH); RNA_def_property_array(prop, 3); + /* only for the transform-panel and conflicts with animating scale */ + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_float_funcs(prop, "rna_Object_dimensions_get", "rna_Object_dimensions_set", NULL); RNA_def_property_ui_range(prop, 0.0f, FLT_MAX, 1, 3); RNA_def_property_ui_text(prop, "Dimensions", "Absolute bounding box dimensions of the object"); -- cgit v1.2.3 From b62faa54de70fd8a4125c98cce2d12f3291139fc Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 4 Jun 2016 01:29:13 +0200 Subject: Cycles: Add support of processor groups Currently for windows only, this is an initial commit towards native support of NUMA. Current commit makes it so Cycles will use all logical processors on Windows running on system with more than 64 threads. Reviewers: juicyfruit, dingto, lukasstockner97, maiself, brecht Subscribers: LazyDodo Differential Revision: https://developer.blender.org/D2049 --- intern/cycles/util/CMakeLists.txt | 2 + intern/cycles/util/util_system.cpp | 53 +++++++++++++++++++----- intern/cycles/util/util_system.h | 8 ++++ intern/cycles/util/util_task.cpp | 23 ++++++++++- intern/cycles/util/util_thread.cpp | 66 +++++++++++++++++++++++++++++ intern/cycles/util/util_thread.h | 36 ++++------------ intern/cycles/util/util_windows.cpp | 82 +++++++++++++++++++++++++++++++++++++ intern/cycles/util/util_windows.h | 19 +++++++++ 8 files changed, 248 insertions(+), 41 deletions(-) create mode 100644 intern/cycles/util/util_thread.cpp create mode 100644 intern/cycles/util/util_windows.cpp diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt index cceec8d444c..e6140b3ed09 100644 --- a/intern/cycles/util/CMakeLists.txt +++ b/intern/cycles/util/CMakeLists.txt @@ -19,8 +19,10 @@ set(SRC util_simd.cpp util_system.cpp util_task.cpp + util_thread.cpp util_time.cpp util_transform.cpp + util_windows.cpp ) if(NOT CYCLES_STANDALONE_REPOSITORY) diff --git a/intern/cycles/util/util_system.cpp b/intern/cycles/util/util_system.cpp index 4ff0ee91d73..16f713e1ea6 100644 --- a/intern/cycles/util/util_system.cpp +++ b/intern/cycles/util/util_system.cpp @@ -15,7 +15,9 @@ */ #include "util_system.h" + #include "util_debug.h" +#include "util_logging.h" #include "util_types.h" #include "util_string.h" @@ -33,28 +35,57 @@ CCL_NAMESPACE_BEGIN -int system_cpu_thread_count() +int system_cpu_group_count() { - static uint count = 0; - - if(count > 0) - return count; +#ifdef _WIN32 + util_windows_init_numa_groups(); + return GetActiveProcessorGroupCount(); +#else + /* TODO(sergey): Need to adopt for other platforms. */ + return 1; +#endif +} +int system_cpu_group_thread_count(int group) +{ + /* TODO(sergey): Need make other platforms aware of groups. */ #ifdef _WIN32 - SYSTEM_INFO info; - GetSystemInfo(&info); - count = (uint)info.dwNumberOfProcessors; + util_windows_init_numa_groups(); + return GetActiveProcessorCount(group); #elif defined(__APPLE__) + (void)group; size_t len = sizeof(count); int mib[2] = { CTL_HW, HW_NCPU }; - + + int count; sysctl(mib, 2, &count, &len, NULL, 0); + return count; #else - count = (uint)sysconf(_SC_NPROCESSORS_ONLN); + (void)group; + return sysconf(_SC_NPROCESSORS_ONLN); #endif +} + +int system_cpu_thread_count() +{ + static uint count = 0; - if(count < 1) + if(count > 0) { + return count; + } + + int max_group = system_cpu_group_count(); + VLOG(1) << "Detected " << max_group << " CPU groups."; + for(int group = 0; group < max_group; ++group) { + int num_threads = system_cpu_group_thread_count(group); + VLOG(1) << "Group " << group + << " has " << num_threads << " threads."; + count += num_threads; + } + + if(count < 1) { count = 1; + } return count; } diff --git a/intern/cycles/util/util_system.h b/intern/cycles/util/util_system.h index 4e7e00f85fd..557aab6cbae 100644 --- a/intern/cycles/util/util_system.h +++ b/intern/cycles/util/util_system.h @@ -21,7 +21,15 @@ CCL_NAMESPACE_BEGIN +/* Get number of available CPU groups. */ +int system_cpu_group_count(); + +/* Get number of threads/processors in the specified group. */ +int system_cpu_group_thread_count(int group); + +/* Get total number of threads in all groups. */ int system_cpu_thread_count(); + string system_cpu_brand_string(); int system_cpu_bits(); bool system_cpu_support_sse2(); diff --git a/intern/cycles/util/util_task.cpp b/intern/cycles/util/util_task.cpp index d86aa8a4a46..352ba81c95a 100644 --- a/intern/cycles/util/util_task.cpp +++ b/intern/cycles/util/util_task.cpp @@ -16,6 +16,7 @@ #include "util_debug.h" #include "util_foreach.h" +#include "util_logging.h" #include "util_system.h" #include "util_task.h" #include "util_time.h" @@ -198,12 +199,30 @@ void TaskScheduler::init(int num_threads) /* automatic number of threads */ num_threads = system_cpu_thread_count(); } + VLOG(1) << "Creating pool of " << num_threads << " threads."; /* launch threads that will be waiting for work */ threads.resize(num_threads); - for(size_t i = 0; i < threads.size(); i++) - threads[i] = new thread(function_bind(&TaskScheduler::thread_run, i + 1)); + int num_groups = system_cpu_group_count(); + int thread_index = 0; + for(int group = 0; group < num_groups; ++group) { + /* NOTE: That's not really efficient from threading point of view, + * but it is simple to read and it doesn't make sense to use more + * user-specified threads than logical threads anyway. + */ + int num_group_threads = (group == num_groups - 1) + ? (threads.size() - thread_index) + : system_cpu_group_thread_count(group); + for(int group_thread = 0; + group_thread < num_group_threads && thread_index < threads.size(); + ++group_thread, ++thread_index) + { + threads[thread_index] = new thread(function_bind(&TaskScheduler::thread_run, + thread_index + 1), + group); + } + } } users++; diff --git a/intern/cycles/util/util_thread.cpp b/intern/cycles/util/util_thread.cpp new file mode 100644 index 00000000000..3db8b4bd197 --- /dev/null +++ b/intern/cycles/util/util_thread.cpp @@ -0,0 +1,66 @@ +/* + * Copyright 2011-2016 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "util_thread.h" + +#include "util_system.h" +#include "util_windows.h" + +CCL_NAMESPACE_BEGIN + +thread::thread(function run_cb, int group) + : run_cb_(run_cb), + joined_(false), + group_(group) +{ + pthread_create(&pthread_id_, NULL, run, (void*)this); +} + +thread::~thread() +{ + if(!joined_) { + join(); + } +} + +void *thread::run(void *arg) +{ + thread *self = (thread*)(arg); + if(self->group_ != -1) { +#ifdef _WIN32 + HANDLE thread_handle = GetCurrentThread(); + GROUP_AFFINITY group_affinity = { 0 }; + int num_threads = system_cpu_group_thread_count(self->group_); + group_affinity.Group = self->group_; + group_affinity.Mask = (num_threads == 64) + ? -1 + : (1ull << num_threads) - 1; + if(SetThreadGroupAffinity(thread_handle, &group_affinity, NULL) == 0) { + fprintf(stderr, "Error setting thread affinity.\n"); + } +#endif + } + self->run_cb_(); + return NULL; +} + +bool thread::join() +{ + joined_ = true; + return pthread_join(pthread_id_, NULL) == 0; +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/util/util_thread.h b/intern/cycles/util/util_thread.h index 59575f31c13..427c633d2ce 100644 --- a/intern/cycles/util/util_thread.h +++ b/intern/cycles/util/util_thread.h @@ -52,37 +52,17 @@ typedef boost::condition_variable thread_condition_variable; class thread { public: - thread(function run_cb_) + thread(function run_cb, int group = -1); + ~thread(); - { - joined = false; - run_cb = run_cb_; - - pthread_create(&pthread_id, NULL, run, (void*)this); - } - - ~thread() - { - if(!joined) - join(); - } - - static void *run(void *arg) - { - ((thread*)arg)->run_cb(); - return NULL; - } - - bool join() - { - joined = true; - return pthread_join(pthread_id, NULL) == 0; - } + static void *run(void *arg); + bool join(); protected: - function run_cb; - pthread_t pthread_id; - bool joined; + function run_cb_; + pthread_t pthread_id_; + bool joined_; + int group_; }; /* Own wrapper around pthread's spin lock to make it's use easier. */ diff --git a/intern/cycles/util/util_windows.cpp b/intern/cycles/util/util_windows.cpp new file mode 100644 index 00000000000..6fd259713d9 --- /dev/null +++ b/intern/cycles/util/util_windows.cpp @@ -0,0 +1,82 @@ +/* + * Copyright 2011-2016 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "util_windows.h" + +#ifdef _WIN32 + +CCL_NAMESPACE_BEGIN + +#include + +#if _WIN32_WINNT < 0x0601 +tGetActiveProcessorGroupCount *GetActiveProcessorGroupCount; +tGetActiveProcessorCount *GetActiveProcessorCount; +tSetThreadGroupAffinity *SetThreadGroupAffinity; +#endif + +static WORD GetActiveProcessorGroupCount_stub() +{ + return 1; +} + +static DWORD GetActiveProcessorCount_stub(WORD /*GroupNumber*/) +{ + SYSTEM_INFO info; + GetSystemInfo(&info); + return info.dwNumberOfProcessors; +} + +static BOOL SetThreadGroupAffinity_stub( + HANDLE /*hThread*/, + const GROUP_AFFINITY * /*GroupAffinity*/, + PGROUP_AFFINITY /*PreviousGroupAffinity*/) +{ + return TRUE; +} + +static bool supports_numa() +{ + return IsWindows7OrGreater(); +} + +void util_windows_init_numa_groups() +{ + static bool initialized = false; + if(initialized) { + return; + } + initialized = true; +#if _WIN32_WINNT < 0x0601 + if(!supports_numa()) { + /* Use stubs on platforms which doesn't have rean NUMA/Groups. */ + GetActiveProcessorGroupCount = GetActiveProcessorGroupCount_stub; + GetActiveProcessorCount = GetActiveProcessorCount_stub; + SetThreadGroupAffinity = SetThreadGroupAffinity_stub; + return; + } + HMODULE kernel = GetModuleHandleA("kernel32.dll"); +# define READ_SYMBOL(sym) sym = (t##sym*)GetProcAddress(kernel, #sym) + READ_SYMBOL(GetActiveProcessorGroupCount); + READ_SYMBOL(GetActiveProcessorCount); + READ_SYMBOL(SetThreadGroupAffinity); +# undef READ_SUMBOL +#endif +} + +CCL_NAMESPACE_END + +#endif /* _WIN32 */ diff --git a/intern/cycles/util/util_windows.h b/intern/cycles/util/util_windows.h index f67e34d0f31..ac61d5348c3 100644 --- a/intern/cycles/util/util_windows.h +++ b/intern/cycles/util/util_windows.h @@ -31,6 +31,25 @@ #include +CCL_NAMESPACE_BEGIN + +#if _WIN32_WINNT < 0x0601 +typedef WORD tGetActiveProcessorGroupCount(); +typedef DWORD tGetActiveProcessorCount(WORD GroupNumber); +typedef BOOL tSetThreadGroupAffinity(HANDLE hThread, + const GROUP_AFFINITY *GroupAffinity, + PGROUP_AFFINITY PreviousGroupAffinity); + +extern tGetActiveProcessorGroupCount *GetActiveProcessorGroupCount; +extern tGetActiveProcessorCount *GetActiveProcessorCount; +extern tSetThreadGroupAffinity *SetThreadGroupAffinity; +#endif + +/* Make sure NUMA and processor groups API is initialized. */ +void util_windows_init_numa_groups(); + +CCL_NAMESPACE_END + #endif /* WIN32 */ #endif /* __UTIL_WINDOWS_H__ */ -- cgit v1.2.3 From 6046c03f5c2847f8eaac30fbe1c507e50340aad2 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 6 Jun 2016 09:15:34 +0200 Subject: Cycles: Ignore zero size instances in BVH In certain types of animation it's possible to have some objects scaling to zero. In this case we can save render times by avoid traversing such instances. Better to do ti ahead of a time, so traversal stays simple. Reviewers: lukasstockner97, dingto, brecht Reviewed By: brecht Differential Revision: https://developer.blender.org/D2048 --- intern/cycles/bvh/bvh_build.cpp | 6 ++++++ intern/cycles/render/object.cpp | 10 ++++++++++ intern/cycles/render/object.h | 5 +++++ 3 files changed, 21 insertions(+) diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp index 87a889955fe..d00de007b2d 100644 --- a/intern/cycles/bvh/bvh_build.cpp +++ b/intern/cycles/bvh/bvh_build.cpp @@ -205,6 +205,9 @@ void BVHBuild::add_references(BVHRange& root) foreach(Object *ob, objects) { if(params.top_level) { + if(!ob->is_traceable()) { + continue; + } if(!ob->mesh->is_instanced()) { num_alloc_references += ob->mesh->num_triangles(); num_alloc_references += count_curve_segments(ob->mesh); @@ -226,6 +229,9 @@ void BVHBuild::add_references(BVHRange& root) foreach(Object *ob, objects) { if(params.top_level) { + if(!ob->is_traceable()) { + continue; + } if(!ob->mesh->is_instanced()) add_reference_mesh(bounds, center, ob->mesh, i); else diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 9ee1a9ef7a6..644e581bf4b 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -225,6 +225,16 @@ vector Object::motion_times() return times; } +bool Object::is_traceable() +{ + /* Mesh itself can be empty,can skip all such objects. */ + if (bounds.size() == make_float3(0.0f, 0.0f, 0.0f)) { + return false; + } + /* TODO(sergey): Check for mesh vertices/curves. visibility flags. */ + return true; +} + /* Object Manager */ ObjectManager::ObjectManager() diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index 57614c95580..7ab73f3c91a 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -68,6 +68,11 @@ public: void apply_transform(bool apply_to_motion); vector motion_times(); + + /* Check whether object is traceable and it worth adding it to + * kernel scene. + */ + bool is_traceable(); }; /* Object Manager */ -- cgit v1.2.3 From a97bcc2985feb8e868d5e61cf0acc122107be683 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 6 Jun 2016 17:55:22 +1000 Subject: Cleanup: rename flag -> tag ID's have a flag member too, best avoid confusion here. --- source/blender/blenloader/intern/readfile.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 464fc0a2d49..6a2f80d3ab4 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7880,7 +7880,7 @@ static BHead *read_data_into_oldnewmap(FileData *fd, BHead *bhead, const char *a return bhead; } -static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID **r_id) +static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const short tag, ID **r_id) { /* this routine reads a libblock and its direct data. Use link functions to connect it all */ @@ -7966,7 +7966,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID if (!id) return blo_nextbhead(fd, bhead); - id->tag = flag | LIB_TAG_NEED_LINK; + id->tag = tag | LIB_TAG_NEED_LINK; id->lib = main->curlib; id->us = ID_FAKE_USERS(id); id->icon_id = 0; @@ -9644,7 +9644,7 @@ static void give_base_to_groups( } } -static ID *create_placeholder(Main *mainvar, const char *idname, const short flag) +static ID *create_placeholder(Main *mainvar, const char *idname, const short tag) { const short idcode = GS(idname); ListBase *lb = which_libbase(mainvar, idcode); @@ -9653,7 +9653,7 @@ static ID *create_placeholder(Main *mainvar, const char *idname, const short fla memcpy(ph_id->name, idname, sizeof(ph_id->name)); BKE_libblock_init_empty(ph_id); ph_id->lib = mainvar->curlib; - ph_id->tag = flag | LIB_TAG_MISSING; + ph_id->tag = tag | LIB_TAG_MISSING; ph_id->us = ID_FAKE_USERS(ph_id); ph_id->icon_id = 0; -- cgit v1.2.3 From 894d24fb16eb1dcfc0ef8c5febde4d7fb072f79b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 6 Jun 2016 18:03:45 +1000 Subject: Cleanup: use const for old member in OldNew struct --- source/blender/blenloader/intern/readfile.c | 48 ++++++++++++++--------------- source/blender/blenloader/intern/readfile.h | 6 ++-- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 6a2f80d3ab4..a6fc2a88d3b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -214,7 +214,8 @@ /***/ typedef struct OldNew { - void *old, *newp; + const void *old; + void *newp; int nr; } OldNew; @@ -292,7 +293,7 @@ static void oldnewmap_sort(FileData *fd) } /* nr is zero for data, and ID code for libdata */ -static void oldnewmap_insert(OldNewMap *onm, void *oldaddr, void *newaddr, int nr) +static void oldnewmap_insert(OldNewMap *onm, const void *oldaddr, void *newaddr, int nr) { OldNew *entry; @@ -309,7 +310,7 @@ static void oldnewmap_insert(OldNewMap *onm, void *oldaddr, void *newaddr, int n entry->nr = nr; } -void blo_do_versions_oldnewmap_insert(OldNewMap *onm, void *oldaddr, void *newaddr, int nr) +void blo_do_versions_oldnewmap_insert(OldNewMap *onm, const void *oldaddr, void *newaddr, int nr) { oldnewmap_insert(onm, oldaddr, newaddr, nr); } @@ -364,7 +365,7 @@ static int oldnewmap_lookup_entry_full(const OldNewMap *onm, const void *addr, i return -1; } -static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr, bool increase_users) +static void *oldnewmap_lookup_and_inc(OldNewMap *onm, const void *addr, bool increase_users) { int i; @@ -394,7 +395,7 @@ static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr, bool increase_ } /* for libdata, nr has ID code, no increment */ -static void *oldnewmap_liblookup(OldNewMap *onm, void *addr, void *lib) +static void *oldnewmap_liblookup(OldNewMap *onm, const void *addr, const void *lib) { if (addr == NULL) { return NULL; @@ -402,11 +403,8 @@ static void *oldnewmap_liblookup(OldNewMap *onm, void *addr, void *lib) /* lasthit works fine for non-libdata, linking there is done in same sequence as writing */ if (onm->sorted) { - OldNew entry_s, *entry; - - entry_s.old = addr; - - entry = bsearch(&entry_s, onm->entries, onm->nentries, sizeof(OldNew), verg_oldnewmap); + const OldNew entry_s = {.old = addr}; + OldNew *entry = bsearch(&entry_s, onm->entries, onm->nentries, sizeof(OldNew), verg_oldnewmap); if (entry) { ID *id = entry->newp; @@ -1413,7 +1411,7 @@ BlendThumbnail *BLO_thumbnail_from_file(const char *filepath) /* ************** OLD POINTERS ******************* */ -static void *newdataadr(FileData *fd, void *adr) /* only direct databocks */ +static void *newdataadr(FileData *fd, const void *adr) /* only direct databocks */ { return oldnewmap_lookup_and_inc(fd->datamap, adr, true); } @@ -1430,7 +1428,7 @@ static void *newdataadr(FileData *fd, void *adr) /* only direct databocks */ * fcurve group pointer and keeps lasthit optimal for linking all further * fcurves. */ -static void *newdataadr_ex(FileData *fd, void *adr, bool increase_lasthit) /* only direct databocks */ +static void *newdataadr_ex(FileData *fd, const void *adr, bool increase_lasthit) /* only direct databocks */ { if (increase_lasthit) { return newdataadr(fd, adr); @@ -1443,38 +1441,38 @@ static void *newdataadr_ex(FileData *fd, void *adr, bool increase_lasthit) /* o } } -static void *newdataadr_no_us(FileData *fd, void *adr) /* only direct databocks */ +static void *newdataadr_no_us(FileData *fd, const void *adr) /* only direct databocks */ { return oldnewmap_lookup_and_inc(fd->datamap, adr, false); } -static void *newglobadr(FileData *fd, void *adr) /* direct datablocks with global linking */ +static void *newglobadr(FileData *fd, const void *adr) /* direct datablocks with global linking */ { return oldnewmap_lookup_and_inc(fd->globmap, adr, true); } -static void *newimaadr(FileData *fd, void *adr) /* used to restore image data after undo */ +static void *newimaadr(FileData *fd, const void *adr) /* used to restore image data after undo */ { if (fd->imamap && adr) return oldnewmap_lookup_and_inc(fd->imamap, adr, true); return NULL; } -static void *newmclipadr(FileData *fd, void *adr) /* used to restore movie clip data after undo */ +static void *newmclipadr(FileData *fd, const void *adr) /* used to restore movie clip data after undo */ { if (fd->movieclipmap && adr) return oldnewmap_lookup_and_inc(fd->movieclipmap, adr, true); return NULL; } -static void *newsoundadr(FileData *fd, void *adr) /* used to restore sound data after undo */ +static void *newsoundadr(FileData *fd, const void *adr) /* used to restore sound data after undo */ { if (fd->soundmap && adr) return oldnewmap_lookup_and_inc(fd->soundmap, adr, true); return NULL; } -static void *newpackedadr(FileData *fd, void *adr) /* used to restore packed data after undo */ +static void *newpackedadr(FileData *fd, const void *adr) /* used to restore packed data after undo */ { if (fd->packedmap && adr) return oldnewmap_lookup_and_inc(fd->packedmap, adr, true); @@ -1483,17 +1481,17 @@ static void *newpackedadr(FileData *fd, void *adr) /* used to restore packe } -static void *newlibadr(FileData *fd, void *lib, void *adr) /* only lib data */ +static void *newlibadr(FileData *fd, const void *lib, const void *adr) /* only lib data */ { return oldnewmap_liblookup(fd->libmap, adr, lib); } -void *blo_do_versions_newlibadr(FileData *fd, void *lib, void *adr) /* only lib data */ +void *blo_do_versions_newlibadr(FileData *fd, const void *lib, const void *adr) /* only lib data */ { return newlibadr(fd, lib, adr); } -static void *newlibadr_us(FileData *fd, void *lib, void *adr) /* increases user number */ +static void *newlibadr_us(FileData *fd, const void *lib, const void *adr) /* increases user number */ { ID *id = newlibadr(fd, lib, adr); @@ -1502,12 +1500,12 @@ static void *newlibadr_us(FileData *fd, void *lib, void *adr) /* increases user return id; } -void *blo_do_versions_newlibadr_us(FileData *fd, void *lib, void *adr) /* increases user number */ +void *blo_do_versions_newlibadr_us(FileData *fd, const void *lib, const void *adr) /* increases user number */ { return newlibadr_us(fd, lib, adr); } -static void change_idid_adr_fd(FileData *fd, void *old, void *new) +static void change_idid_adr_fd(FileData *fd, const void *old, void *new) { int i; @@ -7892,8 +7890,8 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const short /* In undo case, most libs and linked data should be kept as is from previous state (see BLO_read_from_memfile). * However, some needed by the snapshot being read may have been removed in previous one, and would go missing. * This leads e.g. to desappearing objects in some undo/redo case, see T34446. - * That means we have to carefully check whether current lib or libdata already exits in old main, if it does - * we merely copy it over into new main area, otherwise we have to do a full read of that bhead... */ + * That means we have to carefully check whether current lib or libdata already exits in old main, if it does + * we merely copy it over into new main area, otherwise we have to do a full read of that bhead... */ if (fd->memfile && ELEM(bhead->code, ID_LI, ID_ID)) { const char *idname = bhead_id_name(fd, bhead); diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h index f5c19f5ee22..42728fd406f 100644 --- a/source/blender/blenloader/intern/readfile.h +++ b/source/blender/blenloader/intern/readfile.h @@ -156,9 +156,9 @@ const char *bhead_id_name(const FileData *fd, const BHead *bhead); void blo_reportf_wrap(struct ReportList *reports, ReportType type, const char *format, ...) ATTR_PRINTF_FORMAT(3, 4); -void blo_do_versions_oldnewmap_insert(struct OldNewMap *onm, void *oldaddr, void *newaddr, int nr); -void *blo_do_versions_newlibadr(struct FileData *fd, void *lib, void *adr); -void *blo_do_versions_newlibadr_us(struct FileData *fd, void *lib, void *adr); +void blo_do_versions_oldnewmap_insert(struct OldNewMap *onm, const void *oldaddr, void *newaddr, int nr); +void *blo_do_versions_newlibadr(struct FileData *fd, const void *lib, const void *adr); +void *blo_do_versions_newlibadr_us(struct FileData *fd, const void *lib, const void *adr); struct PartEff *blo_do_version_give_parteff_245(struct Object *ob); void blo_do_version_old_trackto_to_constraints(struct Object *ob); -- cgit v1.2.3 From 5d45ffc755e3c7961cadd007e7440ec1fe8b6dbe Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 6 Jun 2016 19:03:09 +1000 Subject: readfile: minor optimization, no need to count flags in this case we only need to check if any id's need to be read. --- source/blender/blenloader/intern/readfile.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index a6fc2a88d3b..df36def5ba1 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -9990,21 +9990,22 @@ void *BLO_library_read_struct(FileData *fd, BHead *bh, const char *blockname) /* ************* READ LIBRARY ************** */ -static int mainvar_count_libread_blocks(Main *mainvar) +static int mainvar_id_tag_any_check(Main *mainvar, const short tag) { ListBase *lbarray[MAX_LIBARRAY]; - int a, tot = 0; + int a; a = set_listbasepointers(mainvar, lbarray); while (a--) { ID *id; for (id = lbarray[a]->first; id; id = id->next) { - if (id->tag & LIB_TAG_READ) - tot++; + if (id->tag & tag) { + return true; + } } } - return tot; + return false; } static void read_libraries(FileData *basefd, ListBase *mainlist) @@ -10024,10 +10025,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) /* test 1: read libdata */ mainptr= mainl->next; while (mainptr) { - int tot = mainvar_count_libread_blocks(mainptr); - - // printf("found LIB_TAG_READ %s\n", mainptr->curlib->name); - if (tot) { + if (mainvar_id_tag_any_check(mainptr, LIB_TAG_READ)) { + // printf("found LIB_TAG_READ %s\n", mainptr->curlib->name); + FileData *fd = mainptr->curlib->filedata; if (fd == NULL) { -- cgit v1.2.3 From 24049c8196ccb88eadc5930e780151c1c0da6a27 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 6 Jun 2016 19:09:46 +1000 Subject: readfile: add assert to check libmap isn't sorted --- source/blender/blenloader/intern/readfile.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index df36def5ba1..96a9c4442d9 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -222,7 +222,7 @@ typedef struct OldNew { typedef struct OldNewMap { OldNew *entries; int nentries, entriessize; - int sorted; + bool sorted; int lasthit; } OldNewMap; @@ -288,6 +288,7 @@ static int verg_oldnewmap(const void *v1, const void *v2) static void oldnewmap_sort(FileData *fd) { + BLI_assert(fd->libmap->sorted == false); qsort(fd->libmap->entries, fd->libmap->nentries, sizeof(OldNew), verg_oldnewmap); fd->libmap->sorted = 1; } @@ -1509,6 +1510,9 @@ static void change_idid_adr_fd(FileData *fd, const void *old, void *new) { int i; + /* use a binary search if we have a sorted libmap, for now it's not needed. */ + BLI_assert(fd->libmap->sorted == false); + for (i = 0; i < fd->libmap->nentries; i++) { OldNew *entry = &fd->libmap->entries[i]; -- cgit v1.2.3 From 47d0d9cca4d0c3ccbdc368e97fc24652379fd368 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 6 Jun 2016 12:08:06 +0200 Subject: Depsgraph: Russian electric tape bodge to have multiple proxies work Makes behavior of proxy_from backlink working similar to the old dependency graph. it's nasty, but needed here in the studio to get proxies fixes ASAP. --- source/blender/blenkernel/BKE_object.h | 2 ++ source/blender/blenkernel/intern/object_update.c | 7 +++++++ .../blender/depsgraph/intern/builder/deg_builder_nodes.cc | 13 +++++++++---- .../depsgraph/intern/builder/deg_builder_relations.cc | 8 +++++++- source/blender/depsgraph/intern/eval/deg_eval_flush.cc | 3 +++ 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 7d6096407ff..c591ec2a0aa 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -208,6 +208,8 @@ void BKE_object_eval_uber_data(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); +void BKE_object_eval_proxy_backlink(struct EvaluationContext *eval_ctx, struct Object *ob); + void BKE_object_handle_data_update(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index 03348adeabc..e60ff05ed6c 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -347,3 +347,10 @@ void BKE_object_eval_uber_data(EvaluationContext *eval_ctx, ob->recalc &= ~(OB_RECALC_DATA | OB_RECALC_TIME); } + +void BKE_object_eval_proxy_backlink(EvaluationContext *eval_ctx, Object *ob) +{ + if (ob->proxy) { + ob->proxy->proxy_from = ob; + } +} diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 5359cc8754a..18cfdb3593a 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -296,16 +296,15 @@ void DepsgraphNodeBuilder::build_scene(Main *bmain, Scene *scene) for (Base *base = (Base *)scene->base.first; base; base = base->next) { Object *ob = base->object; - /* object itself */ - build_object(scene, base, ob); - /* object that this is a proxy for */ // XXX: the way that proxies work needs to be completely reviewed! if (ob->proxy) { ob->proxy->proxy_from = ob; - build_object(scene, base, ob->proxy); } + /* object itself */ + build_object(scene, base, ob); + /* Object dupligroup. */ if (ob->dup_group) { build_group(scene, base, ob->dup_group); @@ -486,6 +485,12 @@ void DepsgraphNodeBuilder::build_object(Scene *scene, Base *base, Object *ob) if (ob->gpd) { build_gpencil(ob->gpd); } + + if (ob->proxy != NULL) { + add_operation_node(&ob->id, DEPSNODE_TYPE_PROXY, DEPSOP_TYPE_POST, + function_bind(BKE_object_eval_proxy_backlink, _1, ob), + DEG_OPCODE_PLACEHOLDER, "Parameters Eval"); + } } void DepsgraphNodeBuilder::build_object_transform(Scene *scene, Object *ob) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 10aebb75fbf..874837ff003 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -266,6 +266,13 @@ void DepsgraphRelationBuilder::build_scene(Main *bmain, Scene *scene) for (Base *base = (Base *)scene->base.first; base; base = base->next) { Object *ob = base->object; + /* Object that this is a proxy for. + * Just makes sure backlink is correct. + */ + if (ob->proxy) { + ob->proxy->proxy_from = ob; + } + /* object itself */ build_object(bmain, scene, ob); @@ -433,7 +440,6 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o break; } - case OB_ARMATURE: /* Pose */ if (ob->id.lib != NULL && ob->proxy_from != NULL) { build_proxy_rig(ob); diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index af68f5c55c4..30d243867b0 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -84,6 +84,9 @@ static void flush_init_func(void *data_v, int i) id_node->done = 0; node->scheduled = false; node->owner->flags &= ~DEPSCOMP_FULLY_SCHEDULED; + if (node->owner->type == DEPSNODE_TYPE_PROXY) { + node->flag |= DEPSOP_FLAG_NEEDS_UPDATE; + } } /* Flush updates from tagged nodes outwards until all affected nodes -- cgit v1.2.3 From b277ba5c0d75f241e17bfbd7492dd2f5e3f146b9 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 6 Jun 2016 13:52:57 +0200 Subject: Cycles: Fix compilation error on OSX --- intern/cycles/util/util_system.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/intern/cycles/util/util_system.cpp b/intern/cycles/util/util_system.cpp index 16f713e1ea6..d5fac9a0e34 100644 --- a/intern/cycles/util/util_system.cpp +++ b/intern/cycles/util/util_system.cpp @@ -54,10 +54,9 @@ int system_cpu_group_thread_count(int group) return GetActiveProcessorCount(group); #elif defined(__APPLE__) (void)group; + int count; size_t len = sizeof(count); int mib[2] = { CTL_HW, HW_NCPU }; - - int count; sysctl(mib, 2, &count, &len, NULL, 0); return count; #else -- cgit v1.2.3 From fd7068ee2879c949b5b6e9356702e00201988481 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 6 Jun 2016 13:53:36 +0200 Subject: Fix T48550: Imperfections when Bake displacement map to plane if camera is not in front The issue was caused by non-watertight nature of intersection, which is now addressed. Hopefully it doesn't cause any regression caused by uninitialized precalculated storage. --- .../render/intern/include/rayintersection.h | 5 + .../blender/render/intern/raytrace/rayobject.cpp | 149 +++++---------------- 2 files changed, 36 insertions(+), 118 deletions(-) diff --git a/source/blender/render/intern/include/rayintersection.h b/source/blender/render/intern/include/rayintersection.h index 3607e66a237..1935e4ef59c 100644 --- a/source/blender/render/intern/include/rayintersection.h +++ b/source/blender/render/intern/include/rayintersection.h @@ -38,6 +38,8 @@ extern "C" { #endif +#include "BLI_math_geom.h" + struct RayObject; /* Ray Hints */ @@ -101,6 +103,9 @@ typedef struct Isect { #ifdef RE_RAYCOUNTER RayCounter *raycounter; #endif + + /* Precalculated coefficients for watertight intersection check. */ + struct IsectRayPrecalc isect_precalc; } Isect; /* ray types */ diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp index de6b9139363..f511042749e 100644 --- a/source/blender/render/intern/raytrace/rayobject.cpp +++ b/source/blender/render/intern/raytrace/rayobject.cpp @@ -138,80 +138,29 @@ MALWAYS_INLINE int vlr_check_bake(Isect *is, ObjectInstanceRen *obi, VlakRen *UN /* Ray Triangle/Quad Intersection */ -MALWAYS_INLINE int isec_tri_quad(float start[3], float dir[3], RayFace *face, float uv[2], float *lambda) +MALWAYS_INLINE int isec_tri_quad(float start[3], const struct IsectRayPrecalc *isect_precalc, RayFace *face, float r_uv[2], float *lambda) { - float co1[3], co2[3], co3[3], co4[3]; - float t0[3], t1[3], x[3], r[3], m[3], u, v, divdet, det1, l; - int quad; - - quad = RE_rayface_isQuad(face); - - copy_v3_v3(co1, face->v1); - copy_v3_v3(co2, face->v2); - copy_v3_v3(co3, face->v3); - - copy_v3_v3(r, dir); - - /* intersect triangle */ - sub_v3_v3v3(t0, co3, co2); - sub_v3_v3v3(t1, co3, co1); - - cross_v3_v3v3(x, r, t1); - divdet = dot_v3v3(t0, x); - - sub_v3_v3v3(m, start, co3); - det1 = dot_v3v3(m, x); - - if (divdet != 0.0f) { - divdet = 1.0f / divdet; - v = det1 * divdet; - - if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) { - float cros[3]; - - cross_v3_v3v3(cros, m, t0); - u = divdet * dot_v3v3(cros, r); - - if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON)) { - l = divdet * dot_v3v3(cros, t1); - - /* check if intersection is within ray length */ - if (l > -RE_RAYTRACE_EPSILON && l < *lambda) { - uv[0] = u; - uv[1] = v; - *lambda = l; - return 1; - } - } + float uv[2], l; + + if (isect_ray_tri_watertight_v3(start, isect_precalc, face->v1, face->v2, face->v3, &l, uv)) { + /* check if intersection is within ray length */ + if (l > -RE_RAYTRACE_EPSILON && l < *lambda) { + r_uv[0] = uv[0]; + r_uv[1] = uv[1]; + *lambda = l; + return 1; } } /* intersect second triangle in quad */ - if (quad) { - copy_v3_v3(co4, face->v4); - sub_v3_v3v3(t0, co3, co4); - divdet = dot_v3v3(t0, x); - - if (divdet != 0.0f) { - divdet = 1.0f / divdet; - v = det1 * divdet; - - if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) { - float cros[3]; - - cross_v3_v3v3(cros, m, t0); - u = divdet * dot_v3v3(cros, r); - - if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON)) { - l = divdet * dot_v3v3(cros, t1); - - if (l > -RE_RAYTRACE_EPSILON && l < *lambda) { - uv[0] = u; - uv[1] = -(1.0f + v + u); - *lambda = l; - return 2; - } - } + if (RE_rayface_isQuad(face)) { + if (isect_ray_tri_watertight_v3(start, isect_precalc, face->v1, face->v3, face->v4, &l, uv)) { + /* check if intersection is within ray length */ + if (l > -RE_RAYTRACE_EPSILON && l < *lambda) { + r_uv[0] = uv[0]; + r_uv[1] = uv[1]; + *lambda = l; + return 2; } } } @@ -223,62 +172,23 @@ MALWAYS_INLINE int isec_tri_quad(float start[3], float dir[3], RayFace *face, fl MALWAYS_INLINE int isec_tri_quad_neighbour(float start[3], float dir[3], RayFace *face) { - float co1[3], co2[3], co3[3], co4[3]; - float t0[3], t1[3], x[3], r[3], m[3], u, v, divdet, det1; - int quad; - - quad = RE_rayface_isQuad(face); + float r[3]; + struct IsectRayPrecalc isect_precalc; + float uv[2], l; - copy_v3_v3(co1, face->v1); - copy_v3_v3(co2, face->v2); - copy_v3_v3(co3, face->v3); negate_v3_v3(r, dir); /* note, different than above function */ - /* intersect triangle */ - sub_v3_v3v3(t0, co3, co2); - sub_v3_v3v3(t1, co3, co1); - - cross_v3_v3v3(x, r, t1); - divdet = dot_v3v3(t0, x); - - sub_v3_v3v3(m, start, co3); - det1 = dot_v3v3(m, x); - - if (divdet != 0.0f) { - divdet = 1.0f / divdet; - v = det1 * divdet; - - if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) { - float cros[3]; - - cross_v3_v3v3(cros, m, t0); - u = divdet * dot_v3v3(cros, r); + isect_ray_tri_watertight_v3_precalc(&isect_precalc, r); - if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON)) - return 1; - } + if (isect_ray_tri_watertight_v3(start, &isect_precalc, face->v1, face->v2, face->v3, &l, uv)) { + return 1; } /* intersect second triangle in quad */ - if (quad) { - copy_v3_v3(co4, face->v4); - sub_v3_v3v3(t0, co3, co4); - divdet = dot_v3v3(t0, x); - - if (divdet != 0.0f) { - divdet = 1.0f / divdet; - v = det1 * divdet; - - if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) { - float cros[3]; - - cross_v3_v3v3(cros, m, t0); - u = divdet * dot_v3v3(cros, r); - - if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON)) - return 2; - } + if (RE_rayface_isQuad(face)) { + if (isect_ray_tri_watertight_v3(start, &isect_precalc, face->v1, face->v3, face->v4, &l, uv)) { + return 2; } } @@ -317,7 +227,7 @@ MALWAYS_INLINE int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *i RE_RC_COUNT(is->raycounter->faces.test); dist = is->dist; - ok = isec_tri_quad(is->start, is->dir, face, uv, &dist); + ok = isec_tri_quad(is->start, &is->isect_precalc, face, uv, &dist); if (ok) { @@ -389,6 +299,9 @@ int RE_rayobject_raycast(RayObject *r, Isect *isec) { int i; + /* Pre-calculate orientation for watertight intersection checks. */ + isect_ray_tri_watertight_v3_precalc(&isec->isect_precalc, isec->dir); + RE_RC_COUNT(isec->raycounter->raycast.test); /* setup vars used on raycast */ -- cgit v1.2.3 From c276480b0f289dd36566447368de52ade39b53f1 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 6 Jun 2016 14:01:19 +0200 Subject: Fix compilation error on 32 bit Windows --- intern/cycles/util/util_windows.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/intern/cycles/util/util_windows.cpp b/intern/cycles/util/util_windows.cpp index 6fd259713d9..ee5b3fd73c0 100644 --- a/intern/cycles/util/util_windows.cpp +++ b/intern/cycles/util/util_windows.cpp @@ -20,7 +20,9 @@ CCL_NAMESPACE_BEGIN -#include +#ifdef _M_X64 +# include +#endif #if _WIN32_WINNT < 0x0601 tGetActiveProcessorGroupCount *GetActiveProcessorGroupCount; @@ -50,7 +52,11 @@ static BOOL SetThreadGroupAffinity_stub( static bool supports_numa() { +#ifndef _M_X64 + return false; +#else return IsWindows7OrGreater(); +#endif } void util_windows_init_numa_groups() -- cgit v1.2.3 From 122c59fba49e212717e8c7302ee01d6126dff427 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 6 Jun 2016 14:37:15 +0200 Subject: Fix T48582: Rigidbody simulation issue with new depsgraph Being granular means we need to re-build depsgraph a bit more often.. The issue was caused by rigidbody requiring some special nodes to handle physics which were not created with just tagging object for update. --- source/blender/editors/include/ED_physics.h | 8 ++++---- source/blender/editors/object/object_add.c | 2 +- .../blender/editors/physics/rigidbody_constraint.c | 15 ++++++++++----- source/blender/editors/physics/rigidbody_object.c | 21 ++++++++++++++------- 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/source/blender/editors/include/ED_physics.h b/source/blender/editors/include/ED_physics.h index 584e9a92bb6..fed842c969e 100644 --- a/source/blender/editors/include/ED_physics.h +++ b/source/blender/editors/include/ED_physics.h @@ -45,12 +45,12 @@ int PE_hair_poll(struct bContext *C); int PE_poll_view3d(struct bContext *C); /* rigidbody_object.c */ -bool ED_rigidbody_object_add(struct Scene *scene, struct Object *ob, int type, struct ReportList *reports); -void ED_rigidbody_object_remove(struct Scene *scene, struct Object *ob); +bool ED_rigidbody_object_add(struct Main *bmain, struct Scene *scene, struct Object *ob, int type, struct ReportList *reports); +void ED_rigidbody_object_remove(struct Main *bmain, struct Scene *scene, struct Object *ob); /* rigidbody_constraint.c */ -bool ED_rigidbody_constraint_add(struct Scene *scene, struct Object *ob, int type, struct ReportList *reports); -void ED_rigidbody_constraint_remove(struct Scene *scene, struct Object *ob); +bool ED_rigidbody_constraint_add(struct Main *bmain, struct Scene *scene, struct Object *ob, int type, struct ReportList *reports); +void ED_rigidbody_constraint_remove(struct Main *bmain, struct Scene *scene, struct Object *ob); /* operators */ void ED_operatortypes_physics(void); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 88ab3450b04..09c9442db54 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1601,7 +1601,7 @@ static int convert_exec(bContext *C, wmOperator *op) if (newob->type == OB_CURVE) { BKE_object_free_modifiers(newob); /* after derivedmesh calls! */ - ED_rigidbody_object_remove(scene, newob); + ED_rigidbody_object_remove(bmain, scene, newob); } } else if (ob->type == OB_MESH && ob->modifiers.first) { /* converting a mesh with no modifiers causes a segfault */ diff --git a/source/blender/editors/physics/rigidbody_constraint.c b/source/blender/editors/physics/rigidbody_constraint.c index f95599592b2..1bfc162a331 100644 --- a/source/blender/editors/physics/rigidbody_constraint.c +++ b/source/blender/editors/physics/rigidbody_constraint.c @@ -41,6 +41,7 @@ #include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_group.h" +#include "BKE_main.h" #include "BKE_report.h" #include "BKE_rigidbody.h" @@ -70,7 +71,7 @@ static int ED_operator_rigidbody_con_active_poll(bContext *C) } -bool ED_rigidbody_constraint_add(Scene *scene, Object *ob, int type, ReportList *reports) +bool ED_rigidbody_constraint_add(Main *bmain, Scene *scene, Object *ob, int type, ReportList *reports) { RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene); @@ -81,7 +82,7 @@ bool ED_rigidbody_constraint_add(Scene *scene, Object *ob, int type, ReportList } /* create constraint group if it doesn't already exits */ if (rbw->constraints == NULL) { - rbw->constraints = BKE_group_add(G.main, "RigidBodyConstraints"); + rbw->constraints = BKE_group_add(bmain, "RigidBodyConstraints"); } /* make rigidbody constraint settings */ ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, type); @@ -90,11 +91,12 @@ bool ED_rigidbody_constraint_add(Scene *scene, Object *ob, int type, ReportList /* add constraint to rigid body constraint group */ BKE_group_object_add(rbw->constraints, ob, scene, NULL); + DAG_relations_tag_update(bmain); DAG_id_tag_update(&ob->id, OB_RECALC_OB); return true; } -void ED_rigidbody_constraint_remove(Scene *scene, Object *ob) +void ED_rigidbody_constraint_remove(Main *bmain, Scene *scene, Object *ob) { RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene); @@ -102,6 +104,7 @@ void ED_rigidbody_constraint_remove(Scene *scene, Object *ob) if (rbw) BKE_group_object_unlink(rbw->constraints, ob, scene, NULL); + DAG_relations_tag_update(bmain); DAG_id_tag_update(&ob->id, OB_RECALC_OB); } @@ -112,6 +115,7 @@ void ED_rigidbody_constraint_remove(Scene *scene, Object *ob) static int rigidbody_con_add_exec(bContext *C, wmOperator *op) { + Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene); Object *ob = (scene) ? OBACT : NULL; @@ -124,7 +128,7 @@ static int rigidbody_con_add_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } /* apply to active object */ - changed = ED_rigidbody_constraint_add(scene, ob, type, op->reports); + changed = ED_rigidbody_constraint_add(bmain, scene, ob, type, op->reports); if (changed) { /* send updates */ @@ -160,6 +164,7 @@ void RIGIDBODY_OT_constraint_add(wmOperatorType *ot) static int rigidbody_con_remove_exec(bContext *C, wmOperator *op) { + Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Object *ob = (scene) ? OBACT : NULL; @@ -173,7 +178,7 @@ static int rigidbody_con_remove_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { - ED_rigidbody_constraint_remove(scene, ob); + ED_rigidbody_constraint_remove(bmain, scene, ob); } /* send updates */ diff --git a/source/blender/editors/physics/rigidbody_object.c b/source/blender/editors/physics/rigidbody_object.c index 26d8af82b2d..30597d95497 100644 --- a/source/blender/editors/physics/rigidbody_object.c +++ b/source/blender/editors/physics/rigidbody_object.c @@ -46,6 +46,7 @@ #include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_group.h" +#include "BKE_main.h" #include "BKE_report.h" #include "BKE_rigidbody.h" @@ -87,7 +88,7 @@ static int ED_operator_rigidbody_add_poll(bContext *C) /* ----------------- */ -bool ED_rigidbody_object_add(Scene *scene, Object *ob, int type, ReportList *reports) +bool ED_rigidbody_object_add(Main *bmain, Scene *scene, Object *ob, int type, ReportList *reports) { RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene); @@ -107,7 +108,7 @@ bool ED_rigidbody_object_add(Scene *scene, Object *ob, int type, ReportList *rep scene->rigidbody_world = rbw; } if (rbw->group == NULL) { - rbw->group = BKE_group_add(G.main, "RigidBodyWorld"); + rbw->group = BKE_group_add(bmain, "RigidBodyWorld"); } /* make rigidbody object settings */ @@ -120,12 +121,13 @@ bool ED_rigidbody_object_add(Scene *scene, Object *ob, int type, ReportList *rep /* add object to rigid body group */ BKE_group_object_add(rbw->group, ob, scene, NULL); + DAG_relations_tag_update(bmain); DAG_id_tag_update(&ob->id, OB_RECALC_OB); return true; } -void ED_rigidbody_object_remove(Scene *scene, Object *ob) +void ED_rigidbody_object_remove(Main *bmain, Scene *scene, Object *ob) { RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene); @@ -133,6 +135,7 @@ void ED_rigidbody_object_remove(Scene *scene, Object *ob) if (rbw) BKE_group_object_unlink(rbw->group, ob, scene, NULL); + DAG_relations_tag_update(bmain); DAG_id_tag_update(&ob->id, OB_RECALC_OB); } @@ -143,13 +146,14 @@ void ED_rigidbody_object_remove(Scene *scene, Object *ob) static int rigidbody_object_add_exec(bContext *C, wmOperator *op) { + Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Object *ob = ED_object_active_context(C); int type = RNA_enum_get(op->ptr, "type"); bool changed; /* apply to active object */ - changed = ED_rigidbody_object_add(scene, ob, type, op->reports); + changed = ED_rigidbody_object_add(bmain, scene, ob, type, op->reports); if (changed) { /* send updates */ @@ -186,13 +190,14 @@ void RIGIDBODY_OT_object_add(wmOperatorType *ot) static int rigidbody_object_remove_exec(bContext *C, wmOperator *op) { + Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Object *ob = ED_object_active_context(C); bool changed = false; /* apply to active object */ if (!ELEM(NULL, ob, ob->rigidbody_object)) { - ED_rigidbody_object_remove(scene, ob); + ED_rigidbody_object_remove(bmain, scene, ob); changed = true; } @@ -232,13 +237,14 @@ void RIGIDBODY_OT_object_remove(wmOperatorType *ot) static int rigidbody_objects_add_exec(bContext *C, wmOperator *op) { + Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); int type = RNA_enum_get(op->ptr, "type"); bool changed = false; /* create rigid body objects and add them to the world's group */ CTX_DATA_BEGIN(C, Object *, ob, selected_objects) { - changed |= ED_rigidbody_object_add(scene, ob, type, op->reports); + changed |= ED_rigidbody_object_add(bmain, scene, ob, type, op->reports); } CTX_DATA_END; @@ -277,6 +283,7 @@ void RIGIDBODY_OT_objects_add(wmOperatorType *ot) static int rigidbody_objects_remove_exec(bContext *C, wmOperator *UNUSED(op)) { + Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); bool changed = false; @@ -284,7 +291,7 @@ static int rigidbody_objects_remove_exec(bContext *C, wmOperator *UNUSED(op)) CTX_DATA_BEGIN(C, Object *, ob, selected_objects) { if (ob->rigidbody_object) { - ED_rigidbody_object_remove(scene, ob); + ED_rigidbody_object_remove(bmain, scene, ob); changed = true; } } -- cgit v1.2.3 From 14f9a5aa1de869b0e611880f38c56708d54b6db3 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 6 Jun 2016 15:56:22 +0200 Subject: Fix T48571: Cycles/GPU - A lot of fireflies on SSS+Volume Was some accumulated precision error happening. --- intern/cycles/kernel/kernel_volume.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h index e1ea60f372e..0e313b8e88c 100644 --- a/intern/cycles/kernel/kernel_volume.h +++ b/intern/cycles/kernel/kernel_volume.h @@ -1216,6 +1216,7 @@ ccl_device void kernel_volume_stack_update_for_subsurface(KernelGlobals *kg, # else Intersection isect; int step = 0; + float3 Pend = ray->P + ray->D*ray->t; while(step < 2 * VOLUME_STACK_SIZE && scene_intersect_volume(kg, &volume_ray, @@ -1227,7 +1228,9 @@ ccl_device void kernel_volume_stack_update_for_subsurface(KernelGlobals *kg, /* Move ray forward. */ volume_ray.P = ray_offset(stack_sd->P, -stack_sd->Ng); - volume_ray.t -= stack_sd->ray_length; + if(volume_ray.t != FLT_MAX) { + volume_ray.D = normalize_len(Pend - volume_ray.P, &volume_ray.t); + } ++step; } # endif -- cgit v1.2.3 From 420bd152621aadf363d388c097911159073e12d8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Jun 2016 00:34:03 +1000 Subject: Cleanup: warning --- source/blender/blenkernel/intern/object_update.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index e60ff05ed6c..2468cb8b697 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -348,7 +348,7 @@ void BKE_object_eval_uber_data(EvaluationContext *eval_ctx, ob->recalc &= ~(OB_RECALC_DATA | OB_RECALC_TIME); } -void BKE_object_eval_proxy_backlink(EvaluationContext *eval_ctx, Object *ob) +void BKE_object_eval_proxy_backlink(EvaluationContext *UNUSED(eval_ctx), Object *ob) { if (ob->proxy) { ob->proxy->proxy_from = ob; -- cgit v1.2.3 From 78f7d0b71412da70bdadda2ddaa2d3e94c8d2e43 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Jun 2016 00:34:54 +1000 Subject: Cleanup: remove unused Library.idblock --- source/blender/makesdna/DNA_ID.h | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 0bf3c350263..d3d7d075229 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -142,7 +142,6 @@ typedef struct ID { */ typedef struct Library { ID id; - ID *idblock; struct FileData *filedata; char name[1024]; /* path name used for reading, can be relative and edited in the outliner */ -- cgit v1.2.3 From c8e9e6dda0f9b5bd0a2d07995f8cc0fcc8d334a1 Mon Sep 17 00:00:00 2001 From: Howard Trickey Date: Mon, 6 Jun 2016 13:15:13 -0400 Subject: Added P key toggle to allow mouse movement to control bevel profile (modal). The Shift key can be held while adjusting profile to make finer changes to the profile (just as it already does when adjusting offset). --- source/blender/editors/mesh/editmesh_bevel.c | 51 +++++++++++++++++++++------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index 242cbf79a83..0f871cd4127 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -58,6 +58,9 @@ #define MVAL_PIXEL_MARGIN 5.0f +/* until implement profile = 0 case, need to clamp somewhat above zero */ +#define PROFILE_HARD_MIN 0.15f + typedef struct { BMEditMesh *em; float initial_length; @@ -71,13 +74,14 @@ typedef struct { BMBackup mesh_backup; void *draw_handle_pixel; short twtype; + bool mouse_controls_profile; float segments; /* Segments as float so smooth mouse pan works in small increments */ } BevelData; static void edbm_bevel_update_header(bContext *C, wmOperator *op) { const char *str = IFACE_("Confirm: (Enter/LMB), Cancel: (Esc/RMB), Mode: %s (M), Clamp Overlap: %s (C), " - "Vertex Only: %s (V), Offset: %s, Segments: %d"); + "Vertex Only: %s (V), Profile Control: %s (P), Offset: %s, Segments: %d"); char msg[UI_MAX_DRAW_STR]; ScrArea *sa = CTX_wm_area(C); @@ -101,6 +105,7 @@ static void edbm_bevel_update_header(bContext *C, wmOperator *op) BLI_snprintf(msg, sizeof(msg), str, type_str, WM_bool_as_string(RNA_boolean_get(op->ptr, "clamp_overlap")), WM_bool_as_string(RNA_boolean_get(op->ptr, "vertex_only")), + WM_bool_as_string(opdata->mouse_controls_profile), offset_str, RNA_int_get(op->ptr, "segments")); ED_area_headerprint(sa, msg); @@ -123,6 +128,7 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal) opdata->em = em; opdata->is_modal = is_modal; opdata->shift_factor = -1.0f; + opdata->mouse_controls_profile = false; initNumInput(&opdata->num_input); opdata->num_input.idx_max = 0; @@ -291,7 +297,7 @@ static float edbm_bevel_mval_factor(wmOperator *op, const wmEvent *event) { BevelData *opdata = op->customdata; bool use_dist; - bool is_percent; + bool is_percent, is_profile; float mdiff[2]; float factor; @@ -299,15 +305,20 @@ static float edbm_bevel_mval_factor(wmOperator *op, const wmEvent *event) mdiff[1] = opdata->mcenter[1] - event->mval[1]; is_percent = (RNA_enum_get(op->ptr, "offset_type") == BEVEL_AMT_PERCENT); use_dist = !is_percent; + is_profile = opdata->mouse_controls_profile; factor = ((len_v2(mdiff) - MVAL_PIXEL_MARGIN) - opdata->initial_length) * opdata->pixel_size; /* Fake shift-transform... */ if (event->shift) { if (opdata->shift_factor < 0.0f) { - opdata->shift_factor = RNA_float_get(op->ptr, "offset"); - if (is_percent) { - opdata->shift_factor /= 100.0f; + if (is_profile) + opdata->shift_factor = RNA_float_get(op->ptr, "profile"); + else { + opdata->shift_factor = RNA_float_get(op->ptr, "offset"); + if (is_percent) { + opdata->shift_factor /= 100.0f; + } } } factor = (factor - opdata->shift_factor) * 0.1f + opdata->shift_factor; @@ -316,14 +327,19 @@ static float edbm_bevel_mval_factor(wmOperator *op, const wmEvent *event) opdata->shift_factor = -1.0f; } - /* clamp differently based on distance/factor */ - if (use_dist) { - if (factor < 0.0f) factor = 0.0f; + /* clamp differently based on distance/factor/profile */ + if (is_profile) { + CLAMP(factor, PROFILE_HARD_MIN, 1.0f); } else { - CLAMP(factor, 0.0f, 1.0f); - if (is_percent) { - factor *= 100.0f; + if (use_dist) { + if (factor < 0.0f) factor = 0.0f; + } + else { + CLAMP(factor, 0.0f, 1.0f); + if (is_percent) { + factor *= 100.0f; + } } } @@ -355,7 +371,10 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event) case MOUSEMOVE: if (!has_numinput) { const float factor = edbm_bevel_mval_factor(op, event); - RNA_float_set(op->ptr, "offset", factor); + if (opdata->mouse_controls_profile) + RNA_float_set(op->ptr, "profile", factor); + else + RNA_float_set(op->ptr, "offset", factor); edbm_bevel_calc(op); edbm_bevel_update_header(C, op); @@ -448,6 +467,11 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event) edbm_bevel_update_header(C, op); handled = true; break; + case PKEY: + if (event->val == KM_RELEASE) + break; + opdata->mouse_controls_profile = !opdata->mouse_controls_profile; + break; case VKEY: if (event->val == KM_RELEASE) break; @@ -519,7 +543,8 @@ void MESH_OT_bevel(wmOperatorType *ot) prop = RNA_def_float(ot->srna, "offset", 0.0f, -1e6f, 1e6f, "Amount", "", 0.0f, 1.0f); RNA_def_property_float_array_funcs_runtime(prop, NULL, NULL, mesh_ot_bevel_offset_range_func); RNA_def_int(ot->srna, "segments", 1, 1, 50, "Segments", "Segments for curved edge", 1, 8); - RNA_def_float(ot->srna, "profile", 0.5f, 0.15f, 1.0f, "Profile", "Controls profile shape (0.5 = round)", 0.15f, 1.0f); + RNA_def_float(ot->srna, "profile", 0.5f, PROFILE_HARD_MIN, 1.0f, "Profile", + "Controls profile shape (0.5 = round)", PROFILE_HARD_MIN, 1.0f); RNA_def_boolean(ot->srna, "vertex_only", false, "Vertex Only", "Bevel only vertices"); RNA_def_boolean(ot->srna, "clamp_overlap", false, "Clamp Overlap", "Do not allow beveled edges/vertices to overlap each other"); -- cgit v1.2.3 From ac7feaed3d4d80c60557b3c4af5eee65bef2e4ec Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 6 Jun 2016 21:41:17 +0200 Subject: EditNormal modifier: add some 'maximum angle' limit. Allows to avoid generating flipped faces when using extreme normal modifications. Related to T48576. --- .../startup/bl_ui/properties_data_modifier.py | 1 + source/blender/blenloader/intern/versioning_270.c | 16 ++++++++++++++-- source/blender/makesdna/DNA_modifier_types.h | 2 ++ source/blender/makesrna/intern/rna_modifier.c | 5 +++++ source/blender/modifiers/intern/MOD_normal_edit.c | 22 +++++++++++++--------- 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index aa03863a198..7863c075344 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -1418,6 +1418,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): sub = row.row(align=True) sub.active = has_vgroup sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') + subcol.prop(md, "mix_limit") def CORRECTIVE_SMOOTH(self, layout, ob, md): is_bind = md.is_bind diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 0ea4078a5cb..b7b6ace3c1a 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -1189,9 +1189,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) } } } - } - { for (Camera *camera = main->camera.first; camera != NULL; camera = camera->id.next) { if (camera->stereo.pole_merge_angle_from == 0.0f && camera->stereo.pole_merge_angle_to == 0.0f) @@ -1200,5 +1198,19 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) camera->stereo.pole_merge_angle_to = DEG2RAD(75.0f); } } + + if (!DNA_struct_elem_find(fd->filesdna, "NormalEditModifierData", "float", "mix_limit")) { + Object *ob; + + for (ob = main->object.first; ob; ob = ob->id.next) { + ModifierData *md; + for (md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_NormalEdit) { + NormalEditModifierData *nemd = (NormalEditModifierData *)md; + nemd->mix_limit = DEG2RADF(180.0f); + } + } + } + } } } diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 457db70cd28..a58e995f1c6 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -1518,7 +1518,9 @@ typedef struct NormalEditModifierData { short mix_mode; char pad[2]; float mix_factor; + float mix_limit; float offset[3]; + float pad_f1; } NormalEditModifierData; /* NormalEditModifierData.mode */ diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 0c4b3ba485d..5a2113f3f95 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -4602,6 +4602,11 @@ static void rna_def_modifier_normaledit(BlenderRNA *brna) "How much of generated normals to mix with exiting ones", 0.0f, 1.0f); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_float(srna, "mix_limit", 1.0f, 0.0f, DEG2RADF(180.0f), "Max Angle", + "Maximum angle between old and new normals", 0.0f, DEG2RADF(180.0f)); + RNA_def_property_subtype(prop, PROP_ANGLE); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "defgrp_name"); RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name for selecting/weighting the affected areas"); diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c index 355dd6d6677..d386653d2c6 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.c +++ b/source/blender/modifiers/intern/MOD_normal_edit.c @@ -110,7 +110,7 @@ static void generate_vert_coordinates( /* Note this modifies nos_new in-place. */ static void mix_normals( const float mix_factor, MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup, - const short mix_mode, + const float mix_limit, const short mix_mode, const int num_verts, MLoop *mloop, float (*nos_old)[3], float (*nos_new)[3], const int num_loops) { /* Mix with org normals... */ @@ -143,7 +143,9 @@ static void mix_normals( case MOD_NORMALEDIT_MIX_COPY: break; } - interp_v3_v3v3_slerp_safe(*no_new, *no_old, *no_new, fac); + + interp_v3_v3v3_slerp_safe(*no_new, *no_old, *no_new, + (mix_limit < M_PI) ? min_ff(fac, mix_limit / angle_v3v3(*no_new, *no_old)) : fac); } MEM_SAFE_FREE(facs); @@ -186,7 +188,7 @@ static bool polygons_check_flip( static void normalEditModifier_do_radial( NormalEditModifierData *smd, Object *ob, DerivedMesh *dm, short (*clnors)[2], float (*loopnors)[3], float (*polynors)[3], - const short mix_mode, const float mix_factor, + const short mix_mode, const float mix_factor, const float mix_limit, MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup, MVert *mvert, const int num_verts, MEdge *medge, const int num_edges, MLoop *mloop, const int num_loops, MPoly *mpoly, const int num_polys) @@ -265,7 +267,7 @@ static void normalEditModifier_do_radial( if (loopnors) { mix_normals(mix_factor, dvert, defgrp_index, use_invert_vgroup, - mix_mode, num_verts, mloop, loopnors, nos, num_loops); + mix_limit, mix_mode, num_verts, mloop, loopnors, nos, num_loops); } if (polygons_check_flip(mloop, nos, dm->getLoopDataLayout(dm), mpoly, polynors, num_polys)) { @@ -283,7 +285,7 @@ static void normalEditModifier_do_radial( static void normalEditModifier_do_directional( NormalEditModifierData *smd, Object *ob, DerivedMesh *dm, short (*clnors)[2], float (*loopnors)[3], float (*polynors)[3], - const short mix_mode, const float mix_factor, + const short mix_mode, const float mix_factor, const float mix_limit, MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup, MVert *mvert, const int num_verts, MEdge *medge, const int num_edges, MLoop *mloop, const int num_loops, MPoly *mpoly, const int num_polys) @@ -342,7 +344,7 @@ static void normalEditModifier_do_directional( if (loopnors) { mix_normals(mix_factor, dvert, defgrp_index, use_invert_vgroup, - mix_mode, num_verts, mloop, loopnors, nos, num_loops); + mix_limit, mix_mode, num_verts, mloop, loopnors, nos, num_loops); } if (polygons_check_flip(mloop, nos, dm->getLoopDataLayout(dm), mpoly, polynors, num_polys)) { @@ -384,7 +386,8 @@ static DerivedMesh *normalEditModifier_do(NormalEditModifierData *smd, Object *o const bool use_invert_vgroup = ((smd->flag & MOD_NORMALEDIT_INVERT_VGROUP) != 0); const bool use_current_clnors = !((smd->mix_mode == MOD_NORMALEDIT_MIX_COPY) && (smd->mix_factor == 1.0f) && - (smd->defgrp_name[0] == '\0')); + (smd->defgrp_name[0] == '\0') && + (smd->mix_limit == M_PI)); int defgrp_index; MDeformVert *dvert; @@ -439,13 +442,13 @@ static DerivedMesh *normalEditModifier_do(NormalEditModifierData *smd, Object *o if (smd->mode == MOD_NORMALEDIT_MODE_RADIAL) { normalEditModifier_do_radial( smd, ob, dm, clnors, loopnors, polynors, - smd->mix_mode, smd->mix_factor, dvert, defgrp_index, use_invert_vgroup, + smd->mix_mode, smd->mix_factor, smd->mix_limit, dvert, defgrp_index, use_invert_vgroup, mvert, num_verts, medge, num_edges, mloop, num_loops, mpoly, num_polys); } else if (smd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) { normalEditModifier_do_directional( smd, ob, dm, clnors, loopnors, polynors, - smd->mix_mode, smd->mix_factor, dvert, defgrp_index, use_invert_vgroup, + smd->mix_mode, smd->mix_factor, smd->mix_limit, dvert, defgrp_index, use_invert_vgroup, mvert, num_verts, medge, num_edges, mloop, num_loops, mpoly, num_polys); } @@ -464,6 +467,7 @@ static void initData(ModifierData *md) smd->mix_mode = MOD_NORMALEDIT_MIX_COPY; smd->mix_factor = 1.0f; + smd->mix_limit = M_PI; } static void copyData(ModifierData *md, ModifierData *target) -- cgit v1.2.3 From 7a5a02509bcd6f5c0fdf2df9f06537cbfd76f027 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Mon, 6 Jun 2016 23:38:28 +0200 Subject: Cycles: Use faster ray-quad-intersection test The original quad intersection test works by just testing against the two triangles that define the quad. However, in this case it's actually faster to use the same test that's also used for portals: Determining the distance to the plane in which the quad lies, calculating the hitpoint and checking whether it's in the quad by projecting onto the sides. Reviewers: brecht, sergey, dingto Reviewed By: dingto Differential Revision: https://developer.blender.org/D2045 --- intern/cycles/kernel/kernel_light.h | 17 +++-------------- intern/cycles/util/util_math.h | 28 ++++++++++++++++------------ 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index 675eacfc5ee..736a884f819 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -291,24 +291,13 @@ ccl_device float background_portal_pdf(KernelGlobals *kg, } num_possible++; - float t = -(dot(P, dir) - dot(lightpos, dir)) / dot(direction, dir); - if(t <= 1e-4f) { - /* Either behind the portal or too close. */ - continue; - } - float4 data1 = kernel_tex_fetch(__light_data, (p + kernel_data.integrator.portal_offset)*LIGHT_SIZE + 1); float4 data2 = kernel_tex_fetch(__light_data, (p + kernel_data.integrator.portal_offset)*LIGHT_SIZE + 2); float3 axisu = make_float3(data1.y, data1.z, data1.w); float3 axisv = make_float3(data2.y, data2.z, data2.w); - float3 hit = P + t*direction; - float3 inplane = hit - lightpos; - /* Skip if the the ray doesn't pass through portal. */ - if(fabsf(dot(inplane, axisu) / dot(axisu, axisu)) > 0.5f) - continue; - if(fabsf(dot(inplane, axisv) / dot(axisv, axisv)) > 0.5f) + if(!ray_quad_intersect(P, direction, 1e-4f, FLT_MAX, lightpos, axisu, axisv, dir, NULL, NULL)) continue; portal_pdf += area_light_sample(P, &lightpos, axisu, axisv, 0.0f, 0.0f, false); @@ -729,8 +718,8 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, float3 light_P = make_float3(data0.y, data0.z, data0.w); - if(!ray_quad_intersect(P, D, t, - light_P, axisu, axisv, &ls->P, &ls->t)) + if(!ray_quad_intersect(P, D, 0.0f, t, + light_P, axisu, axisv, Ng, &ls->P, &ls->t)) { return false; } diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index 32924f9a8c2..53944ec1cc4 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -1479,21 +1479,25 @@ ccl_device bool ray_triangle_intersect_uv( return true; } -ccl_device bool ray_quad_intersect(float3 ray_P, float3 ray_D, float ray_t, - float3 quad_P, float3 quad_u, float3 quad_v, +ccl_device bool ray_quad_intersect(float3 ray_P, float3 ray_D, float ray_mint, float ray_maxt, + float3 quad_P, float3 quad_u, float3 quad_v, float3 quad_n, float3 *isect_P, float *isect_t) { - float3 v0 = quad_P - quad_u*0.5f - quad_v*0.5f; - float3 v1 = quad_P + quad_u*0.5f - quad_v*0.5f; - float3 v2 = quad_P + quad_u*0.5f + quad_v*0.5f; - float3 v3 = quad_P - quad_u*0.5f + quad_v*0.5f; + float t = -(dot(ray_P, quad_n) - dot(quad_P, quad_n)) / dot(ray_D, quad_n); + if(t < ray_mint || t > ray_maxt) + return false; - if(ray_triangle_intersect(ray_P, ray_D, ray_t, v0, v1, v2, isect_P, isect_t)) - return true; - else if(ray_triangle_intersect(ray_P, ray_D, ray_t, v0, v2, v3, isect_P, isect_t)) - return true; - - return false; + float3 hit = ray_P + t*ray_D; + float3 inplane = hit - quad_P; + if(fabsf(dot(inplane, quad_u) / dot(quad_u, quad_u)) > 0.5f) + return false; + if(fabsf(dot(inplane, quad_v) / dot(quad_v, quad_v)) > 0.5f) + return false; + + if(isect_P) *isect_P = hit; + if(isect_t) *isect_t = t; + + return true; } /* projections */ -- cgit v1.2.3 From f12c55d2b8070fbb01005a527c4d344b7d136609 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Jun 2016 13:57:50 +1000 Subject: Correct exit-code check --- doc/python_api/sphinx_doc_gen.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/python_api/sphinx_doc_gen.sh b/doc/python_api/sphinx_doc_gen.sh index 7095808f251..1ab6bd5afc7 100755 --- a/doc/python_api/sphinx_doc_gen.sh +++ b/doc/python_api/sphinx_doc_gen.sh @@ -61,7 +61,7 @@ if $DO_EXE_BLENDER ; then --python-exit-code 1 \ --python $SPHINXBASE/sphinx_doc_gen.py - if (($? == 1)) ; then + if (($? != 0)) ; then echo "Generating documentation failed, aborting" exit 1 fi -- cgit v1.2.3 From 2d9d17c031cc651fde2c78e37452e99c9ee6fb77 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Jun 2016 01:54:59 +1000 Subject: readfile: avoid library lookups for every id on undo Instead index libraries, makes minor speedup when using many libraries. --- source/blender/blenloader/intern/readfile.c | 54 ++++++++++++++++------------- source/blender/makesdna/DNA_ID.h | 3 ++ 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 96a9c4442d9..fd105f6aafa 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -485,53 +485,57 @@ void blo_join_main(ListBase *mainlist) } } -static void split_libdata(ListBase *lb, Main *first) +static void split_libdata(ListBase *lb_src, Main **lib_main_array, const unsigned int lib_main_array_len) { - ListBase *lbn; - ID *id, *idnext; - Main *mainvar; - - id = lb->first; - while (id) { + for (ID *id = lb_src->first, *idnext; id; id = idnext) { idnext = id->next; + if (id->lib) { - mainvar = first; - while (mainvar) { - if (mainvar->curlib == id->lib) { - lbn= which_libbase(mainvar, GS(id->name)); - BLI_remlink(lb, id); - BLI_addtail(lbn, id); - break; - } - mainvar = mainvar->next; + if (((unsigned int)id->lib->temp_index < lib_main_array_len) && + /* this check should never fail, just incase 'id->lib' is a dangling pointer. */ + (lib_main_array[id->lib->temp_index]->curlib == id->lib)) + { + Main *mainvar = lib_main_array[id->lib->temp_index]; + ListBase *lb_dst = which_libbase(mainvar, GS(id->name)); + BLI_remlink(lb_src, id); + BLI_addtail(lb_dst, id); + } + else { + printf("%s: invalid library for '%s'\n", __func__, id->name); + BLI_assert(0); } - if (mainvar == NULL) printf("error split_libdata\n"); } - id = idnext; } } void blo_split_main(ListBase *mainlist, Main *main) { - ListBase *lbarray[MAX_LIBARRAY]; - Library *lib; - int i; - mainlist->first = mainlist->last = main; main->next = NULL; if (BLI_listbase_is_empty(&main->library)) return; - for (lib = main->library.first; lib; lib = lib->id.next) { + /* (Library.temp_index -> Main), lookup table */ + const unsigned int lib_main_array_len = BLI_listbase_count(&main->library); + Main **lib_main_array = MEM_mallocN(lib_main_array_len * sizeof(*lib_main_array), __func__); + + int i = 0; + for (Library *lib = main->library.first; lib; lib = lib->id.next, i++) { Main *libmain = BKE_main_new(); libmain->curlib = lib; BLI_addtail(mainlist, libmain); + lib->temp_index = i; + lib_main_array[i] = libmain; } + ListBase *lbarray[MAX_LIBARRAY]; i = set_listbasepointers(main, lbarray); - while (i--) - split_libdata(lbarray[i], main->next); + while (i--) { + split_libdata(lbarray[i], lib_main_array, lib_main_array_len); + } + + MEM_freeN(lib_main_array); } static void read_file_version(FileData *fd, Main *main) diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index d3d7d075229..b0812a81ee1 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -154,6 +154,9 @@ typedef struct Library { struct Library *parent; /* set for indirectly linked libs, used in the outliner and while reading */ struct PackedFile *packedfile; + + int temp_index; + int _pad; } Library; enum eIconSizes { -- cgit v1.2.3 From 3054e33d67c8f524dae915c8f1f016a7bfa63ab0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Jun 2016 16:05:04 +1000 Subject: BLO_idcode: Move ID_ID last This lets us use MAX_LIBARRAY to loop over id-codes in Main. --- source/blender/blenkernel/intern/idcode.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c index 68a741bc3fc..899ed548783 100644 --- a/source/blender/blenkernel/intern/idcode.c +++ b/source/blender/blenkernel/intern/idcode.c @@ -39,6 +39,7 @@ #include "BLT_translation.h" +#include "BKE_library.h" #include "BKE_idcode.h" typedef struct { @@ -54,6 +55,7 @@ typedef struct { /* plural need to match rna_main.c's MainCollectionDef */ /* WARNING! Keep it in sync with i18n contexts in BLT_translation.h */ static IDType idtypes[] = { + /** ID's directly below must all be in #Main, and be kept in sync with #MAX_LIBARRAY (membership, not order) */ { ID_AC, "Action", "actions", BLT_I18NCONTEXT_ID_ACTION, IDTYPE_FLAGS_ISLINKABLE }, { ID_AR, "Armature", "armatures", BLT_I18NCONTEXT_ID_ARMATURE, IDTYPE_FLAGS_ISLINKABLE }, { ID_BR, "Brush", "brushes", BLT_I18NCONTEXT_ID_BRUSH, IDTYPE_FLAGS_ISLINKABLE }, @@ -61,7 +63,6 @@ static IDType idtypes[] = { { ID_CU, "Curve", "curves", BLT_I18NCONTEXT_ID_CURVE, IDTYPE_FLAGS_ISLINKABLE }, { ID_GD, "GPencil", "grease_pencil", BLT_I18NCONTEXT_ID_GPENCIL, IDTYPE_FLAGS_ISLINKABLE }, /* rename gpencil */ { ID_GR, "Group", "groups", BLT_I18NCONTEXT_ID_GROUP, IDTYPE_FLAGS_ISLINKABLE }, - { ID_ID, "ID", "ids", BLT_I18NCONTEXT_ID_ID, 0 }, /* plural is fake */ { ID_IM, "Image", "images", BLT_I18NCONTEXT_ID_IMAGE, IDTYPE_FLAGS_ISLINKABLE }, { ID_IP, "Ipo", "ipos", "", IDTYPE_FLAGS_ISLINKABLE }, /* deprecated */ { ID_KE, "Key", "shape_keys", BLT_I18NCONTEXT_ID_SHAPEKEY, 0 }, @@ -89,8 +90,14 @@ static IDType idtypes[] = { { ID_VF, "VFont", "fonts", BLT_I18NCONTEXT_ID_VFONT, IDTYPE_FLAGS_ISLINKABLE }, { ID_WO, "World", "worlds", BLT_I18NCONTEXT_ID_WORLD, IDTYPE_FLAGS_ISLINKABLE }, { ID_WM, "WindowManager", "window_managers", BLT_I18NCONTEXT_ID_WINDOWMANAGER, 0 }, + + /** Keep last, not an ID exactly, only include for completeness */ + { ID_ID, "ID", "ids", BLT_I18NCONTEXT_ID_ID, 0 }, /* plural is fake */ }; +/* -1 for ID_ID */ +BLI_STATIC_ASSERT((ARRAY_SIZE(idtypes) - 1 == MAX_LIBARRAY), "Missing IDType"); + static IDType *idtype_from_name(const char *str) { int i = ARRAY_SIZE(idtypes); -- cgit v1.2.3