diff options
Diffstat (limited to 'source')
75 files changed, 577 insertions, 234 deletions
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index ec595320d6a..c6f6579ec48 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -49,7 +49,7 @@ extern "C" { /* used by packaging tools */ /* can be left blank, otherwise a,b,c... etc with no quotes */ -#define BLENDER_VERSION_CHAR +#define BLENDER_VERSION_CHAR a /* alpha/beta/rc/release, docs use this */ #define BLENDER_VERSION_CYCLE release diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index a9d5ea75208..e85f594daba 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -144,6 +144,7 @@ void BKE_nurb_knot_calc_v(struct Nurb *nu); /* nurb checks if they can be drawn, also clamp order func */ bool BKE_nurb_check_valid_u(struct Nurb *nu); bool BKE_nurb_check_valid_v(struct Nurb *nu); +bool BKE_nurb_check_valid_uv(struct Nurb *nu); bool BKE_nurb_order_clamp_u(struct Nurb *nu); bool BKE_nurb_order_clamp_v(struct Nurb *nu); diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h index 05bb01a4490..5652e714209 100644 --- a/source/blender/blenkernel/BKE_depsgraph.h +++ b/source/blender/blenkernel/BKE_depsgraph.h @@ -157,7 +157,7 @@ void DAG_print_dependencies(struct Main *bmain, struct Scene *scene, struct Obje /* ************************ DAG querying ********************* */ struct Object *DAG_get_node_object(void *node_v); -const char *DAG_get_node_name(void *node_v); +const char *DAG_get_node_name(struct Scene *scene, void *node_v); short DAG_get_eval_flags_for_object(struct Scene *scene, void *object); bool DAG_is_acyclic(struct Scene *scene); diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index 5c92cc7b34b..44a9885cd87 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -49,6 +49,7 @@ struct PropertyRNA; void *BKE_libblock_alloc(struct Main *bmain, short type, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); void *BKE_libblock_copy_ex(struct Main *bmain, struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +void *BKE_libblock_copy_nolib(struct ID *id) ATTR_NONNULL(); void *BKE_libblock_copy(struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); void BKE_libblock_copy_data(struct ID *id, const struct ID *id_from, const bool do_action); diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 72c4c21d587..2ad6c54fb67 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -167,7 +167,8 @@ void BKE_object_tfm_protected_restore(struct Object *ob, void BKE_object_handle_update(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); void BKE_object_handle_update_ex(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, - struct RigidBodyWorld *rbw); + struct RigidBodyWorld *rbw, + const bool do_proxy_update); void BKE_object_sculpt_modifiers_changed(struct Object *ob); int BKE_object_obdata_texspace_get(struct Object *ob, short **r_texflag, float **r_loc, float **r_size, float **r_rot); diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 0cbb9215868..ea47f0ba47d 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -99,6 +99,7 @@ typedef struct SeqRenderData { int motion_blur_samples; float motion_blur_shutter; bool skip_cache; + bool is_proxy_render; } SeqRenderData; SeqRenderData BKE_sequencer_new_render_data(struct EvaluationContext *eval_ctx, struct Main *bmain, diff --git a/source/blender/blenkernel/depsgraph_private.h b/source/blender/blenkernel/depsgraph_private.h index e61d47e87f4..0ab633701c1 100644 --- a/source/blender/blenkernel/depsgraph_private.h +++ b/source/blender/blenkernel/depsgraph_private.h @@ -129,6 +129,7 @@ typedef struct DagForest { int numNodes; bool is_acyclic; int time; /* for flushing/tagging, compare with node->lasttime */ + bool ugly_hack_sorry; /* prevent type check */ } DagForest; // queue operations diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 3088f2ccf9b..b0c293720c4 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -894,7 +894,7 @@ void BKE_animdata_main_cb(Main *mainptr, ID_AnimData_Edit_Callback func, void *u AnimData *adt = BKE_animdata_from_id(id); \ NtId_Type *ntp = (NtId_Type *)id; \ if (ntp->nodetree) { \ - AnimData *adt2 = BKE_animdata_from_id((ID *)ntp); \ + AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \ if (adt2) func(id, adt2, user_data); \ } \ if (adt) func(id, adt, user_data); \ diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 1fe01fa9637..cb15b5dbd78 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -3798,6 +3798,16 @@ bool BKE_nurb_check_valid_v(struct Nurb *nu) return true; } +bool BKE_nurb_check_valid_uv(struct Nurb *nu) +{ + if (!BKE_nurb_check_valid_u(nu)) + return false; + if ((nu->pntsv > 1) && !BKE_nurb_check_valid_v(nu)) + return false; + + return true; +} + bool BKE_nurb_order_clamp_u(struct Nurb *nu) { bool changed = false; diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index af321302984..dc467a5f215 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -305,6 +305,7 @@ DagForest *dag_init(void) DagForest *forest; /* use callocN to init all zero */ forest = MEM_callocN(sizeof(DagForest), "DAG root"); + forest->ugly_hack_sorry = true; return forest; } @@ -995,7 +996,6 @@ DagNode *dag_find_node(DagForest *forest, void *fob) return NULL; } -static int ugly_hack_sorry = 1; /* prevent type check */ static int dag_print_dependencies = 0; /* debugging */ /* no checking of existence, use dag_find_node first or dag_get_node */ @@ -1008,7 +1008,7 @@ DagNode *dag_add_node(DagForest *forest, void *fob) node->ob = fob; node->color = DAG_WHITE; - if (ugly_hack_sorry) node->type = GS(((ID *) fob)->name); /* sorry, done for pose sorting */ + if (forest->ugly_hack_sorry) node->type = GS(((ID *) fob)->name); /* sorry, done for pose sorting */ if (forest->numNodes) { ((DagNode *) forest->DagNode.last)->next = node; forest->DagNode.last = node; @@ -1116,28 +1116,28 @@ void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel fob1->child = itA; } -static const char *dag_node_name(DagNode *node) +static const char *dag_node_name(DagForest *dag, DagNode *node) { if (node->ob == NULL) return "null"; - else if (ugly_hack_sorry) + else if (dag->ugly_hack_sorry) return ((ID *)(node->ob))->name + 2; else return ((bPoseChannel *)(node->ob))->name; } -static void dag_node_print_dependencies(DagNode *node) +static void dag_node_print_dependencies(DagForest *dag, DagNode *node) { DagAdjList *itA; - printf("%s depends on:\n", dag_node_name(node)); + printf("%s depends on:\n", dag_node_name(dag, node)); for (itA = node->parent; itA; itA = itA->next) - printf(" %s through %s\n", dag_node_name(itA->node), itA->name); + printf(" %s through %s\n", dag_node_name(dag, itA->node), itA->name); printf("\n"); } -static int dag_node_print_dependency_recurs(DagNode *node, DagNode *endnode) +static int dag_node_print_dependency_recurs(DagForest *dag, DagNode *node, DagNode *endnode) { DagAdjList *itA; @@ -1150,8 +1150,8 @@ static int dag_node_print_dependency_recurs(DagNode *node, DagNode *endnode) return 1; for (itA = node->parent; itA; itA = itA->next) { - if (dag_node_print_dependency_recurs(itA->node, endnode)) { - printf(" %s depends on %s through %s.\n", dag_node_name(node), dag_node_name(itA->node), itA->name); + if (dag_node_print_dependency_recurs(dag, itA->node, endnode)) { + printf(" %s depends on %s through %s.\n", dag_node_name(dag, node), dag_node_name(dag, itA->node), itA->name); return 1; } } @@ -1166,8 +1166,8 @@ static void dag_node_print_dependency_cycle(DagForest *dag, DagNode *startnode, for (node = dag->DagNode.first; node; node = node->next) node->color = DAG_WHITE; - printf(" %s depends on %s through %s.\n", dag_node_name(endnode), dag_node_name(startnode), name); - dag_node_print_dependency_recurs(startnode, endnode); + printf(" %s depends on %s through %s.\n", dag_node_name(dag, endnode), dag_node_name(dag, startnode), name); + dag_node_print_dependency_recurs(dag, startnode, endnode); printf("\n"); } @@ -1201,7 +1201,7 @@ static void dag_check_cycle(DagForest *dag) /* debugging print */ if (dag_print_dependencies) for (node = dag->DagNode.first; node; node = node->next) - dag_node_print_dependencies(node); + dag_node_print_dependencies(dag, node); /* tag nodes unchecked */ for (node = dag->DagNode.first; node; node = node->next) @@ -2836,7 +2836,7 @@ void DAG_pose_sort(Object *ob) int skip = 0; dag = dag_init(); - ugly_hack_sorry = 0; /* no ID structs */ + dag->ugly_hack_sorry = false; /* no ID structs */ rootnode = dag_add_node(dag, NULL); /* node->ob becomes NULL */ @@ -2963,8 +2963,6 @@ void DAG_pose_sort(Object *ob) free_forest(dag); MEM_freeN(dag); - - ugly_hack_sorry = 1; } /* ************************ DAG FOR THREADED UPDATE ********************* */ @@ -3083,14 +3081,14 @@ Object *DAG_get_node_object(void *node_v) } /* Returns node name, used for debug output only, atm. */ -const char *DAG_get_node_name(void *node_v) +const char *DAG_get_node_name(Scene *scene, void *node_v) { DagNode *node = node_v; - return dag_node_name(node); + return dag_node_name(scene->theDag, node); } -short DAG_get_eval_flags_for_object(struct Scene *scene, void *object) +short DAG_get_eval_flags_for_object(Scene *scene, void *object) { DagNode *node; diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 9582d87c540..af3246a1b61 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1212,7 +1212,7 @@ void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase, curve_calc_modifiers_pre(scene, ob, &nubase, forRender, renderResolution); for (nu = nubase.first; nu; nu = nu->next) { - if (forRender || nu->hide == 0) { + if ((forRender || nu->hide == 0) && BKE_nurb_check_valid_uv(nu)) { int resolu = nu->resolu, resolv = nu->resolv; if (renderResolution) { diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index b3e0bfa387b..c2ddd0cac4b 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -1744,10 +1744,8 @@ static void statvis_calc_overhang( bool is_max; /* fallback */ - const char col_fallback[2][4] = { - {64, 64, 64, 255}, /* gray */ - {0, 0, 0, 255}, /* max color */ - }; + unsigned char col_fallback[4] = {64, 64, 64, 255}; /* gray */ + unsigned char col_fallback_max[4] = {0, 0, 0, 255}; /* max color */ BLI_assert(min <= max); @@ -1762,7 +1760,7 @@ static void statvis_calc_overhang( { float fcol[3]; weight_to_rgb(fcol, 1.0f); - rgb_float_to_uchar((unsigned char *)col_fallback[1], fcol); + rgb_float_to_uchar(col_fallback_max, fcol); } /* now convert into global space */ @@ -1779,7 +1777,8 @@ static void statvis_calc_overhang( rgb_float_to_uchar(r_face_colors[index], fcol); } else { - copy_v4_v4_char((char *)r_face_colors[index], (const char *)(col_fallback[is_max])); + unsigned char *fallback = is_max ? col_fallback_max : col_fallback; + copy_v4_v4_char((char *)r_face_colors[index], (const char *)fallback); } } } diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index b8b126c4c8e..35751867b1a 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -3058,7 +3058,6 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r) if (ima->type == IMA_TYPE_MULTILAYER) /* keeps render result, stores ibufs in listbase, allows saving */ ibuf = image_get_ibuf_multilayer(ima, iuser); - } else if (ima->source == IMA_SRC_GENERATED) { /* generated is: ibuf is allocated dynamically */ @@ -3076,9 +3075,6 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r) /* always verify entirely, and potentially * returns pointer to release later */ ibuf = image_get_render_result(ima, iuser, lock_r); - if (ibuf) { - ibuf->userflags |= IB_PERSISTENT; - } } else if (ima->type == IMA_TYPE_COMPOSITE) { /* requires lock/unlock, otherwise don't return image */ @@ -3097,10 +3093,14 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r) ibuf = IMB_allocImBuf(256, 256, 32, IB_rect); image_assign_ibuf(ima, ibuf, 0, frame); } - ibuf->userflags |= IB_PERSISTENT; } } } + + /* We only want movies and sequences to be memory limited. */ + if (ibuf != NULL && !ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { + ibuf->userflags |= IB_PERSISTENT; + } } BKE_image_tag_time(ima); diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 0bd1f97a279..f831378ca5a 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -808,6 +808,32 @@ void *BKE_libblock_copy_ex(Main *bmain, ID *id) return idn; } +void *BKE_libblock_copy_nolib(ID *id) +{ + ID *idn; + size_t idn_len; + + idn = alloc_libblock_notest(GS(id->name)); + assert(idn != NULL); + + BLI_strncpy(idn->name, id->name, sizeof(idn->name)); + + idn_len = MEM_allocN_len(idn); + if ((int)idn_len - (int)sizeof(ID) > 0) { /* signed to allow neg result */ + const char *cp = (const char *)id; + char *cpn = (char *)idn; + + memcpy(cpn + sizeof(ID), cp + sizeof(ID), idn_len - sizeof(ID)); + } + + id->newid = idn; + idn->flag |= LIB_NEW; + + BKE_libblock_copy_data(idn, id, false); + + return idn; +} + void *BKE_libblock_copy(ID *id) { return BKE_libblock_copy_ex(G.main, id); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 9b7886ece97..d08b7316e61 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -734,6 +734,7 @@ Mask *BKE_mask_new(Main *bmain, const char *name) return mask; } +/* TODO(sergey): Use generic BKE_libblock_copy_nolib() instead. */ Mask *BKE_mask_copy_nolib(Mask *mask) { Mask *mask_new; diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 5f6331315f8..f3e38d84c33 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -256,8 +256,7 @@ Material *localize_material(Material *ma) Material *man; int a; - man = BKE_libblock_copy(&ma->id); - BLI_remlink(&G.main->mat, man); + man = BKE_libblock_copy_nolib(&ma->id); /* no increment for texture ID users, in previewrender.c it prevents decrement */ for (a = 0; a < MAX_MTEX; a++) { diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index a41b47809eb..c8fe99bab91 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -279,17 +279,8 @@ static ImBuf *movieclip_load_movie_file(MovieClip *clip, MovieClipUser *user, in movieclip_open_anim_file(clip); if (clip->anim) { - int dur; - int fra; - - dur = IMB_anim_get_duration(clip->anim, tc); - fra = framenr - clip->start_frame + clip->frame_offset; - - if (fra < 0) - fra = 0; - - if (fra > (dur - 1)) - fra = dur - 1; + int dur = IMB_anim_get_duration(clip->anim, tc); + int fra = framenr - clip->start_frame + clip->frame_offset; ibuf = IMB_anim_absolute(clip->anim, fra, tc, proxy); } diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index d6225560e32..4fbc5c3f2d9 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1114,20 +1114,13 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, Main *bmain, bool do_ if (ntree == NULL) return NULL; - if (bmain) { - /* is ntree part of library? */ - if (BLI_findindex(&bmain->nodetree, ntree) != -1) - newtree = BKE_libblock_copy(&ntree->id); - else - newtree = NULL; + /* is ntree part of library? */ + if (bmain && BLI_findindex(&bmain->nodetree, ntree) >= 0) { + newtree = BKE_libblock_copy(&ntree->id); } - else - newtree = NULL; - - if (newtree == NULL) { - newtree = MEM_dupallocN(ntree); + else { + newtree = BKE_libblock_copy_nolib(&ntree->id); newtree->id.lib = NULL; /* same as owning datablock id.lib */ - BKE_libblock_copy_data(&newtree->id, &ntree->id, true); /* copy animdata and ID props */ } id_us_plus((ID *)newtree->gpd); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 0970af46a6b..674c16383af 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2843,7 +2843,8 @@ bool BKE_object_parent_loop_check(const Object *par, const Object *ob) /* Ideally we shouldn't have to pass the rigid body world, but need bigger restructuring to avoid id */ void BKE_object_handle_update_ex(EvaluationContext *eval_ctx, Scene *scene, Object *ob, - RigidBodyWorld *rbw) + RigidBodyWorld *rbw, + const bool do_proxy_update) { if (ob->recalc & OB_RECALC_ALL) { /* speed optimization for animation lookups */ @@ -3036,8 +3037,10 @@ void BKE_object_handle_update_ex(EvaluationContext *eval_ctx, /* the no-group proxy case, we call update */ if (ob->proxy_group == NULL) { - // printf("call update, lib ob %s proxy %s\n", ob->proxy->id.name, ob->id.name); - BKE_object_handle_update(eval_ctx, scene, ob->proxy); + if (do_proxy_update) { + // printf("call update, lib ob %s proxy %s\n", ob->proxy->id.name, ob->id.name); + BKE_object_handle_update(eval_ctx, scene, ob->proxy); + } } } } @@ -3048,7 +3051,7 @@ void BKE_object_handle_update_ex(EvaluationContext *eval_ctx, */ void BKE_object_handle_update(EvaluationContext *eval_ctx, Scene *scene, Object *ob) { - BKE_object_handle_update_ex(eval_ctx, scene, ob, NULL); + BKE_object_handle_update_ex(eval_ctx, scene, ob, NULL, true); } void BKE_object_sculpt_modifiers_changed(Object *ob) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 3a6e710d68c..ed0f8b2d8e4 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -3779,7 +3779,7 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int face_index, co return 0; if (pa) { - i = (pa->num_dmcache == DMCACHE_NOTFOUND) ? pa->num : pa->num_dmcache; + i = ELEM(pa->num_dmcache, DMCACHE_NOTFOUND, DMCACHE_ISCHILD) ? pa->num : pa->num_dmcache; if (i >= dm->getNumTessFaces(dm)) i = -1; } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 110e91711f0..37eba4657ff 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1270,7 +1270,7 @@ static void scene_update_all_bases(EvaluationContext *eval_ctx, Scene *scene, Sc for (base = scene->base.first; base; base = base->next) { Object *object = base->object; - BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world); + BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world, true); if (object->dup_group && (object->transflag & OB_DUPLIGROUP)) BKE_group_handle_recalc_and_update(eval_ctx, scene_parent, object, object->dup_group); @@ -1304,9 +1304,11 @@ static void scene_update_object_func(TaskPool *pool, void *taskdata, int threadi double start_time = 0.0; bool add_to_stats = false; - PRINT("Thread %d: update object %s\n", threadid, object->id.name); - if (G.debug & G_DEBUG_DEPSGRAPH) { + if (object->recalc & OB_RECALC_ALL) { + printf("Thread %d: update object %s\n", threadid, object->id.name); + } + start_time = PIL_check_seconds_timer(); if (object->recalc & OB_RECALC_ALL) { @@ -1319,7 +1321,7 @@ static void scene_update_object_func(TaskPool *pool, void *taskdata, int threadi * separately from main thread because of we've got no idea about * dependencies inside the group. */ - BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world); + BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world, false); /* Calculate statistics. */ if (add_to_stats) { @@ -1335,7 +1337,7 @@ static void scene_update_object_func(TaskPool *pool, void *taskdata, int threadi } else { PRINT("Threda %d: update node %s\n", threadid, - DAG_get_node_name(node)); + DAG_get_node_name(scene, node)); } /* Update will decrease child's valency and schedule child with zero valency. */ diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 86cf04eded8..7b9262320af 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -1467,8 +1467,8 @@ static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, i ibuf = seq_render_strip(context, seq, cfra); - rectx = (proxy_render_size * context->scene->r.xsch) / 100; - recty = (proxy_render_size * context->scene->r.ysch) / 100; + rectx = (proxy_render_size * ibuf->x) / 100; + recty = (proxy_render_size * ibuf->y) / 100; if (ibuf->x != rectx || ibuf->y != recty) { IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty); @@ -1562,6 +1562,7 @@ void BKE_sequencer_proxy_rebuild(SeqIndexBuildContext *context, short *stop, sho (scene->r.size * (float) scene->r.xsch) / 100.0f + 0.5f, (scene->r.size * (float) scene->r.ysch) / 100.0f + 0.5f, 100); render_context.skip_cache = true; + render_context.is_proxy_render = true; for (cfra = seq->startdisp + seq->startstill; cfra < seq->enddisp - seq->endstill; cfra++) { if (context->size_flags & IMB_PROXY_25) { @@ -1919,10 +1920,14 @@ void BKE_sequencer_color_balance_apply(StripColorBalance *cb, ImBuf *ibuf, float * - Premultiply */ -int BKE_sequencer_input_have_to_preprocess(const SeqRenderData *UNUSED(context), Sequence *seq, float UNUSED(cfra)) +int BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context, Sequence *seq, float UNUSED(cfra)) { float mul; + if (context->is_proxy_render) { + return FALSE; + } + if (seq->flag & (SEQ_FILTERY | SEQ_USE_CROP | SEQ_USE_TRANSFORM | SEQ_FLIPX | SEQ_FLIPY | SEQ_MAKE_FLOAT)) { return TRUE; } @@ -2806,8 +2811,12 @@ static ImBuf *seq_render_strip(const SeqRenderData *context, Sequence *seq, floa if (ibuf == NULL) ibuf = do_render_strip_uncached(context, seq, cfra); - if (ibuf) + if (ibuf) { + if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP)) { + is_proxy_image = (context->preview_render_size != 100); + } BKE_sequencer_preprocessed_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf); + } } } @@ -2826,8 +2835,11 @@ static ImBuf *seq_render_strip(const SeqRenderData *context, Sequence *seq, floa sequencer_imbuf_assign_spaces(context->scene, ibuf); } - if (ibuf->x != context->rectx || ibuf->y != context->recty) + if (context->is_proxy_render == false && + (ibuf->x != context->rectx || ibuf->y != context->recty)) + { use_preprocess = TRUE; + } if (use_preprocess) ibuf = input_preprocess(context, seq, cfra, ibuf, is_proxy_image, is_preprocessed); @@ -4011,11 +4023,19 @@ void BKE_sequencer_offset_animdata(Scene *scene, Sequence *seq, int ofs) for (fcu = scene->adt->action->curves.first; fcu; fcu = fcu->next) { if (strstr(fcu->rna_path, "sequence_editor.sequences_all[") && strstr(fcu->rna_path, str)) { unsigned int i; - for (i = 0; i < fcu->totvert; i++) { - BezTriple *bezt = &fcu->bezt[i]; - bezt->vec[0][0] += ofs; - bezt->vec[1][0] += ofs; - bezt->vec[2][0] += ofs; + if (fcu->bezt) { + for (i = 0; i < fcu->totvert; i++) { + BezTriple *bezt = &fcu->bezt[i]; + bezt->vec[0][0] += ofs; + bezt->vec[1][0] += ofs; + bezt->vec[2][0] += ofs; + } + } + if (fcu->fpt) { + for (i = 0; i < fcu->totvert; i++) { + FPoint *fpt = &fcu->fpt[i]; + fpt->vec[0] += ofs; + } } } } diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index a7e3c12e5d7..1dfdc5c3c74 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -205,14 +205,16 @@ bool BM_disk_dissolve(BMesh *bm, BMVert *v) return false; } - /* get remaining two faces */ - f = e->l->f; - f2 = e->l->radial_next->f; - - if (f != f2) { - /* join two remaining faces */ - if (!BM_faces_join_pair(bm, f, f2, e, true)) { - return false; + if (e->l) { + /* get remaining two faces */ + f = e->l->f; + f2 = e->l->radial_next->f; + + if (f != f2) { + /* join two remaining faces */ + if (!BM_faces_join_pair(bm, f, f2, e, true)) { + return false; + } } } } diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c index a255c534736..29522b62707 100644 --- a/source/blender/bmesh/operators/bmo_inset.c +++ b/source/blender/bmesh/operators/bmo_inset.c @@ -395,6 +395,9 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op) const float thickness = BMO_slot_float_get(op->slots_in, "thickness"); const float depth = BMO_slot_float_get(op->slots_in, "depth"); + /* store vert coords in normals, needed for 'use_edge_rail' */ +#define USE_VERTNORMAL_HACK + int edge_info_len = 0; BMIter iter; @@ -453,6 +456,11 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op) BM_elem_index_set(e, -1); /* set_dirty! */ } + +#ifdef USE_VERTNORMAL_HACK + copy_v3_v3(e->v1->no, e->v1->co); + copy_v3_v3(e->v2->no, e->v2->co); +#endif } bm->elem_index_dirty |= BM_EDGE; @@ -564,6 +572,9 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op) /* in some cases the edge doesn't split off */ if (r_vout_len == 1) { +#ifdef USE_VERTNORMAL_HACK + copy_v3_v3(vout[0]->no, vout[0]->co); +#endif MEM_freeN(vout); continue; } @@ -575,6 +586,10 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op) int vert_edge_tag_tot = 0; int vecpair[2]; +#ifdef USE_VERTNORMAL_HACK + copy_v3_v3(v_split->no, v_split->co); +#endif + /* find adjacent */ BM_ITER_ELEM (e, &iter, v_split, BM_EDGES_OF_VERT) { if (BM_elem_flag_test(e, BM_ELEM_TAG) && @@ -628,9 +643,22 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op) if (l_other_a->v == l_other_b->v) { /* both edges faces are adjacent, but we don't need to know the shared edge * having both verts is enough. */ - sub_v3_v3v3(tvec, l_other_a->v->co, v_split->co); + const float *co_other; + + /* note that we can't use 'l_other_a->v' directly since it + * may be inset and give a feedback loop. */ +#ifdef USE_VERTNORMAL_HACK + co_other = l_other_a->v->no; +#else + co_other = l_other_a->v->co; +#endif + + sub_v3_v3v3(tvec, co_other, v_split->co); is_mid = false; } + + /* distable gives odd results at times, see [#39288] */ +#if 0 else if (compare_v3v3(f_a->no, f_b->no, 0.001f) == false) { /* epsilon increased to fix [#32329] */ @@ -645,6 +673,7 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op) copy_v3_v3(tvec, tno); is_mid = false; } +#endif } normalize_v3(tvec); diff --git a/source/blender/bmesh/tools/bmesh_wireframe.c b/source/blender/bmesh/tools/bmesh_wireframe.c index db4601d6134..824a4164559 100644 --- a/source/blender/bmesh/tools/bmesh_wireframe.c +++ b/source/blender/bmesh/tools/bmesh_wireframe.c @@ -529,8 +529,62 @@ void BM_mesh_wireframe( } if (use_replace) { - for (i = 0; i < totvert_orig; i++) { - BM_vert_kill(bm, verts_src[i]); + + if (use_tag) { + /* only remove faces which are original and used to make wire, + * use 'verts_pos' and 'verts_neg' to avoid a feedback loop. */ + + /* vertex must be from 'verts_src' */ +#define VERT_DUPE_TEST_ORIG(v) (verts_neg[BM_elem_index_get(v)] != NULL) +#define VERT_DUPE_TEST(v) (verts_pos[BM_elem_index_get(v)] != NULL) +#define VERT_DUPE_CLEAR(v) { verts_pos[BM_elem_index_get(v)] = NULL; } (void)0 + + /* first ensure we keep all verts which are used in faces that weren't + * entirely made into wire. */ + BM_ITER_MESH (f_src, &iter, bm, BM_FACES_OF_MESH) { + int mix_flag = 0; + BMLoop *l_iter, *l_first; + + /* skip new faces */ + if (BM_elem_index_get(f_src) == -1) { + continue; + } + + l_iter = l_first = BM_FACE_FIRST_LOOP(f_src); + do { + mix_flag |= (VERT_DUPE_TEST_ORIG(l_iter->v) ? 1 : 2); + if (mix_flag == (1 | 2)) { + break; + } + } while ((l_iter = l_iter->next) != l_first); + + if (mix_flag == (1 | 2)) { + l_iter = l_first = BM_FACE_FIRST_LOOP(f_src); + do { + VERT_DUPE_CLEAR(l_iter->v); + } while ((l_iter = l_iter->next) != l_first); + } + } + + /* now remove any verts which were made into wire by all faces */ + for (i = 0; i < totvert_orig; i++) { + v_src = verts_src[i]; + BLI_assert(i == BM_elem_index_get(v_src)); + if (VERT_DUPE_TEST(v_src)) { + BM_vert_kill(bm, v_src); + } + } + +#undef VERT_DUPE_TEST_ORIG +#undef VERT_DUPE_TEST +#undef VERT_DUPE_CLEAR + + } + else { + /* simple case, no tags - replace all */ + for (i = 0; i < totvert_orig; i++) { + BM_vert_kill(bm, verts_src[i]); + } } } diff --git a/source/blender/compositor/COM_defines.h b/source/blender/compositor/COM_defines.h index 3b0e9f239bb..6c07aadc3aa 100644 --- a/source/blender/compositor/COM_defines.h +++ b/source/blender/compositor/COM_defines.h @@ -109,4 +109,13 @@ typedef enum OrderOfChunks { #define COM_BLUR_BOKEH_PIXELS 512 +/** + * The fast gaussien blur is not an accurate blur. + * This setting can be used to increase/decrease the + * amount of the input data. (dependent area of interest) + * + * Fix for: T39307 + */ +#define COM_FAST_GAUSSIAN_MULTIPLIER 3 + #endif /* __COM_DEFINES_H__ */ diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp index a6be9254f6f..ff53ef22e29 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp @@ -47,10 +47,11 @@ bool FastGaussianBlurOperation::getDAI(rcti *rect, rcti *output) { // m_data->sizex * m_size should be enough? For some reason there // seem to be errors in the boundary between tiles. - int sx = this->m_data->sizex * this->m_size * 2; + float size = this->m_size * COM_FAST_GAUSSIAN_MULTIPLIER; + int sx = this->m_data->sizex * size; if (sx < 1) sx = 1; - int sy = this->m_data->sizey * this->m_size * 2; + int sy = this->m_data->sizey * size; if (sy < 1) sy = 1; diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 0aff3b81ec9..1cd41bd110d 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -93,6 +93,8 @@ void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist void ED_view3d_from_object(struct Object *ob, float ofs[3], float quat[4], float *dist, float *lens); void ED_view3d_to_object(struct Object *ob, const float ofs[3], const float quat[4], const float dist); +void ED_view3d_lastview_store(struct RegionView3D *rv3d); + /* Depth buffer */ void ED_view3d_depth_update(struct ARegion *ar); float ED_view3d_depth_read_cached(struct ViewContext *vc, int x, int y); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index f1c0df23fc9..0768d556911 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -2374,6 +2374,11 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data) data->selextend = 0; data->selstartx = 0.0f; +#ifdef USE_DRAG_MULTINUM + /* this can happen from multi-drag */ + data->applied_interactive = false; +#endif + /* set cursor pos to the end of the text */ but->editstr = data->str; but->pos = len; @@ -3477,10 +3482,21 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton } } else if (event->type == LEFTMOUSE && event->val != KM_PRESS) { - if (data->dragchange) - button_activate_state(C, but, BUTTON_STATE_EXIT); - else + if (data->dragchange) { +#ifdef USE_DRAG_MULTINUM + /* if we started multibutton but didnt drag, then edit */ + if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) { + click = 1; + } + else +#endif + { + button_activate_state(C, but, BUTTON_STATE_EXIT); + } + } + else { click = 1; + } } else if (event->type == MOUSEMOVE) { const enum eSnapType snap = ui_event_to_snap(event); @@ -3763,10 +3779,21 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton } } else if (event->type == LEFTMOUSE && event->val != KM_PRESS) { - if (data->dragchange) - button_activate_state(C, but, BUTTON_STATE_EXIT); - else + if (data->dragchange) { +#ifdef USE_DRAG_MULTINUM + /* if we started multibutton but didnt drag, then edit */ + if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) { + click = 1; + } + else +#endif + { + button_activate_state(C, but, BUTTON_STATE_EXIT); + } + } + else { click = 1; + } } else if (event->type == MOUSEMOVE) { #ifdef USE_DRAG_MULTINUM diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index b5255eb0516..55f35a93692 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -888,7 +888,7 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname EnumPropertyItem *item, *item_array = NULL; bool free; uiLayout *split = uiLayoutSplit(layout, 0.0f, false); - uiLayout *column = uiLayoutColumn(split, false); + uiLayout *column = uiLayoutColumn(split, layout->align); RNA_property_enum_items_gettexted(block->evil_C, &ptr, prop, &item_array, NULL, &free); for (item = item_array; item->identifier; item++) { @@ -912,7 +912,7 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname if (item->name) { uiBut *but; if (item != item_array) { - column = uiLayoutColumn(split, false); + column = uiLayoutColumn(split, layout->align); /* inconsistent, but menus with labels do not look good flipped */ block->flag |= UI_BLOCK_NO_FLIP; } diff --git a/source/blender/editors/mesh/editmesh_inset.c b/source/blender/editors/mesh/editmesh_inset.c index 2ca5301c89c..aa3a2c83243 100644 --- a/source/blender/editors/mesh/editmesh_inset.c +++ b/source/blender/editors/mesh/editmesh_inset.c @@ -503,7 +503,7 @@ void MESH_OT_inset(wmOperatorType *ot) RNA_def_boolean(ot->srna, "use_boundary", true, "Boundary", "Inset face boundaries"); RNA_def_boolean(ot->srna, "use_even_offset", true, "Offset Even", "Scale the offset to give more even thickness"); RNA_def_boolean(ot->srna, "use_relative_offset", false, "Offset Relative", "Scale the offset by surrounding geometry"); - RNA_def_boolean(ot->srna, "use_edge_rail", true, "Edge Rail", "Inset the region along existing edges"); + RNA_def_boolean(ot->srna, "use_edge_rail", false, "Edge Rail", "Inset the region along existing edges"); prop = RNA_def_float(ot->srna, "thickness", 0.01f, 0.0f, FLT_MAX, "Thickness", "", 0.0f, 10.0f); /* use 1 rather then 10 for max else dragging the button moves too far */ diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index b29fafea90d..182a9f70968 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1478,8 +1478,13 @@ static void curvetomesh(Main *bmain, Scene *scene, Object *ob) convert_ensure_curve_cache(bmain, scene, ob); BKE_mesh_from_nurbs(ob); /* also does users */ - if (ob->type == OB_MESH) + if (ob->type == OB_MESH) { BKE_object_free_modifiers(ob); + + /* Game engine defaults for mesh objects */ + ob->body_type = OB_BODY_TYPE_STATIC; + ob->gameflag = OB_PROP | OB_COLLISION; + } } static int convert_poll(bContext *C) diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 66fa5787e5d..23ead971cd3 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1514,19 +1514,22 @@ void ED_screen_set(bContext *C, bScreen *sc) /* we put timer to sleep, so screen_exit has to think there's no timer */ oldscreen->animtimer = NULL; - if (wt) + if (wt) { WM_event_timer_sleep(wm, win, wt, true); - + } + ED_screen_exit(C, win, oldscreen); /* Same scene, "transfer" playback to new screen. */ - if (oldscene == sc->scene) { - sc->animtimer = wt; - } - /* Else, stop playback. */ - else { - oldscreen->animtimer = wt; - ED_screen_animation_play(C, 0, 0); + if (wt) { + if (oldscene == sc->scene) { + sc->animtimer = wt; + } + /* Else, stop playback. */ + else { + oldscreen->animtimer = wt; + ED_screen_animation_play(C, 0, 0); + } } win->screen = sc; diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 2cb28ebba90..0d0ce259174 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2848,6 +2848,10 @@ static void region_quadview_init_rv3d(ScrArea *sa, ARegion *ar, { RegionView3D *rv3d = ar->regiondata; + if (persp == RV3D_CAMOB) { + ED_view3d_lastview_store(rv3d); + } + rv3d->viewlock = viewlock; rv3d->view = view; rv3d->persp = persp; diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index 1a5ccc8f8bd..a3e69a1024b 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -45,6 +45,7 @@ #include "BKE_brush.h" #include "BKE_context.h" #include "BKE_image.h" +#include "BKE_node.h" #include "BKE_paint.h" #include "BKE_colortools.h" @@ -60,6 +61,10 @@ * removed eventually (TODO) */ #include "sculpt_intern.h" +#ifdef _OPENMP +#include <omp.h> +#endif + /* TODOs: * * Some of the cursor drawing code is doing non-draw stuff @@ -197,6 +202,9 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima pool = BKE_image_pool_new(); + if (mtex->tex && mtex->tex->nodetree) + ntreeTexBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */ + #pragma omp parallel for schedule(static) for (j = 0; j < size; j++) { int i; @@ -241,7 +249,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima if (col) { float rgba[4]; - paint_get_tex_pixel_col(mtex, x, y, rgba, pool); + paint_get_tex_pixel_col(mtex, x, y, rgba, pool, omp_get_thread_num()); buffer[index * 4] = rgba[0] * 255; buffer[index * 4 + 1] = rgba[1] * 255; @@ -249,7 +257,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima buffer[index * 4 + 3] = rgba[3] * 255; } else { - float avg = paint_get_tex_pixel(mtex, x, y, pool); + float avg = paint_get_tex_pixel(mtex, x, y, pool, omp_get_thread_num()); avg += br->texture_sample_bias; @@ -272,6 +280,9 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima } } + if (mtex->tex && mtex->tex->nodetree) + ntreeTexEndExecTree(mtex->tex->nodetree->execdata); + if (pool) BKE_image_pool_free(pool); diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 6dd42380a11..af9ac6dd89d 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -198,8 +198,8 @@ void paint_calc_redraw_planes(float planes[4][4], const struct rcti *screen_rect); float paint_calc_object_space_radius(struct ViewContext *vc, const float center[3], float pixel_radius); -float paint_get_tex_pixel(struct MTex *mtex, float u, float v, struct ImagePool *pool); -void paint_get_tex_pixel_col(struct MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool); +float paint_get_tex_pixel(struct MTex *mtex, float u, float v, struct ImagePool *pool, int thread); +void paint_get_tex_pixel_col(struct MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool, int thread); int imapaint_pick_face(struct ViewContext *vc, const int mval[2], unsigned int *index, unsigned int totface); void imapaint_pick_uv(struct Scene *scene, struct Object *ob, unsigned int faceindex, const int xy[2], float uv[2]); void brush_drawcursor_texpaint_uvsculpt(struct bContext *C, int x, int y, void *customdata); diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index e6efba4fa0c..de09709fcce 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -164,26 +164,25 @@ float paint_calc_object_space_radius(ViewContext *vc, const float center[3], return len_v3(delta) / scale; } -float paint_get_tex_pixel(MTex *mtex, float u, float v, struct ImagePool *pool) +float paint_get_tex_pixel(MTex *mtex, float u, float v, struct ImagePool *pool, int thread) { float intensity, rgba[4]; float co[3] = {u, v, 0.0f}; externtex(mtex, co, &intensity, - rgba, rgba + 1, rgba + 2, rgba + 3, 0, pool); + rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool); return intensity; } -void paint_get_tex_pixel_col(MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool) +void paint_get_tex_pixel_col(MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool, int thread) { float co[3] = {u, v, 0.0f}; int hasrgb; float intensity; hasrgb = externtex(mtex, co, &intensity, - rgba, rgba + 1, rgba + 2, rgba + 3, 0, pool); - + rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool); if (!hasrgb) { rgba[0] = intensity; rgba[1] = intensity; diff --git a/source/blender/editors/sculpt_paint/paint_vertex_proj.c b/source/blender/editors/sculpt_paint/paint_vertex_proj.c index a04e15d3729..ae729248f7e 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_proj.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_proj.c @@ -153,6 +153,10 @@ static void vpaint_proj_dm_map_cosnos_update__map_cb(void *userData, int index, vp_handle->dists_sq[index] = dist_sq; } + else if (vp_handle->dists_sq[index] != FLT_MAX) { + /* already initialized & couldn't project this 'co' */ + return; + } } /* continue with regular functionality */ diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index d74e9c9e17b..35de6af2531 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -104,6 +104,19 @@ #include <omp.h> #endif +#if defined(__APPLE__) +#include <sys/sysctl.h> + +/* Query how many cores not counting HT aka physical cores we've got. */ +static int system_physical_thread_count(void) +{ + int pcount; + size_t pcount_len = sizeof(pcount); + sysctlbyname("hw.physicalcpu", &pcount, &pcount_len, NULL, 0); + return pcount; +} +#endif /* __APPLE__ */ + void ED_sculpt_get_average_stroke(Object *ob, float stroke[3]) { if (ob->sculpt->last_stroke_valid && ob->sculpt->average_stroke_counter > 0) { @@ -230,7 +243,7 @@ typedef struct StrokeCache { float initial_mouse[2]; /* Pre-allocated temporary storage used during smoothing */ - int num_threads; + int num_threads, max_threads; float (**tmpgrid_co)[3], (**tmprow_co)[3]; float **tmpgrid_mask, **tmprow_mask; @@ -924,6 +937,7 @@ static float tex_strength(SculptSession *ss, Brush *br, MTex *mtex = &br->mtex; float avg = 1; float rgba[4]; + int thread_num; if (!mtex->tex) { avg = 1; @@ -966,7 +980,12 @@ static float tex_strength(SculptSession *ss, Brush *br, x += br->mtex.ofs[0]; y += br->mtex.ofs[1]; - avg = paint_get_tex_pixel(&br->mtex, x, y, ss->tex_pool); +#ifdef _OPENMP + thread_num = omp_get_thread_num(); +#else + thread_num = 0; +#endif + avg = paint_get_tex_pixel(&br->mtex, x, y, ss->tex_pool, thread_num); avg += br->texture_sample_bias; } @@ -3766,16 +3785,21 @@ static void sculpt_omp_start(Sculpt *sd, SculptSession *ss) * Justification: Empirically I've found that two threads per * processor gives higher throughput. */ if (sd->flags & SCULPT_USE_OPENMP) { - cache->num_threads = 2 * omp_get_num_procs(); - omp_set_num_threads(cache->num_threads); - } - else +#if defined(__APPLE__) + cache->num_threads = system_physical_thread_count(); +#else + cache->num_threads = omp_get_num_procs(); #endif - { - (void)sd; + } + else { cache->num_threads = 1; } - + cache->max_threads = omp_get_max_threads(); + omp_set_num_threads(cache->num_threads); +#else + (void)sd; + cache->num_threads = 1; +#endif if (ss->multires) { int i, gridsize, array_mem_size; BKE_pbvh_node_get_grids(ss->pbvh, NULL, NULL, NULL, NULL, @@ -3802,6 +3826,10 @@ static void sculpt_omp_start(Sculpt *sd, SculptSession *ss) static void sculpt_omp_done(SculptSession *ss) { +#ifdef _OPENMP + omp_set_num_threads(ss->cache->max_threads); +#endif + if (ss->multires) { int i; diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 18652aabefe..d417776b1f2 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -974,6 +974,10 @@ static bool prefetch_check_early_out(const bContext *C) int first_uncached_frame, end_frame; int clip_len; + if (clip == NULL) { + return true; + } + clip_len = BKE_movieclip_get_duration(clip); /* check whether all the frames from prefetch range are cached */ diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index bb6c50d6224..0e152dbebcf 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -110,10 +110,21 @@ static void sclip_zoom_set(const bContext *C, float zoom, float location[2]) } if ((U.uiflag & USER_ZOOM_TO_MOUSEPOS) && location) { + float dx, dy; + ED_space_clip_get_size(sc, &width, &height); - sc->xof += ((location[0] - 0.5f) * width - sc->xof) * (sc->zoom - oldzoom) / sc->zoom; - sc->yof += ((location[1] - 0.5f) * height - sc->yof) * (sc->zoom - oldzoom) / sc->zoom; + dx = ((location[0] - 0.5f) * width - sc->xof) * (sc->zoom - oldzoom) / sc->zoom; + dy= ((location[1] - 0.5f) * height - sc->yof) * (sc->zoom - oldzoom) / sc->zoom; + + if (sc->flag & SC_LOCK_SELECTION) { + sc->xlockof += dx; + sc->ylockof += dy; + } + else { + sc->xof += dx; + sc->yof += dy; + } } } diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 2f1d78b2ccd..c56bc33ef15 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -577,7 +577,10 @@ static void clip_keymap(struct wmKeyConfig *keyconf) RNA_boolean_set(kmi->ptr, "sequence", TRUE); /* mode */ - WM_keymap_add_menu(keymap, "CLIP_MT_select_mode", TABKEY, KM_PRESS, 0, 0); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", TABKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.mode"); + RNA_string_set(kmi->ptr, "value_1", "TRACKING"); + RNA_string_set(kmi->ptr, "value_2", "MASK"); WM_keymap_add_item(keymap, "CLIP_OT_solve_camera", SKEY, KM_PRESS, KM_SHIFT, 0); diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 6f44b47ed61..2b7bb01cea1 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -1309,10 +1309,13 @@ static void track_markers_updatejob(void *tmv) static void track_markers_endjob(void *tmv) { TrackMarkersJob *tmj = (TrackMarkersJob *)tmv; + wmWindowManager *wm = tmj->main->wm.first; tmj->clip->tracking_context = NULL; tmj->scene->r.cfra = BKE_movieclip_remap_clip_to_scene_frame(tmj->clip, tmj->lastfra); - ED_update_for_newframe(tmj->main, tmj->scene, 0); + if (wm != NULL) { + ED_update_for_newframe(tmj->main, tmj->scene, 0); + } BKE_tracking_context_sync(tmj->context); BKE_tracking_context_finish(tmj->context); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index effb8eb7de5..f51d6cc3660 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -37,6 +37,7 @@ #include "DNA_object_types.h" #include "DNA_space_types.h" #include "DNA_screen_types.h" +#include "DNA_userdef_types.h" #include "BKE_context.h" #include "BKE_curve.h" @@ -923,7 +924,7 @@ static void node_shader_buts_subsurface(uiLayout *layout, bContext *C, PointerRN PointerRNA scene = CTX_data_pointer_get(C, "scene"); if (scene.data) { PointerRNA cscene = RNA_pointer_get(&scene, "cycles"); - if (cscene.data && RNA_enum_get(&cscene, "device") == 1) + if (cscene.data && (RNA_enum_get(&cscene, "device") == 1 && U.compute_device_type != 0)) uiItemL(layout, IFACE_("SSS not supported on GPU"), ICON_ERROR); } @@ -933,12 +934,12 @@ static void node_shader_buts_subsurface(uiLayout *layout, bContext *C, PointerRN static void node_shader_buts_volume(uiLayout *layout, bContext *C, PointerRNA *UNUSED(ptr)) { - /* SSS does not work on GPU yet */ + /* Volume does not work on GPU yet */ PointerRNA scene = CTX_data_pointer_get(C, "scene"); if (scene.data) { PointerRNA cscene = RNA_pointer_get(&scene, "cycles"); - if (cscene.data && RNA_enum_get(&cscene, "device") == 1) + if (cscene.data && (RNA_enum_get(&cscene, "device") == 1 && U.compute_device_type != 0)) uiItemL(layout, IFACE_("Volumes not supported on GPU"), ICON_ERROR); } } diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index d44a3e60a3f..4db63a462e7 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -481,7 +481,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname) char newname[sizeof(bone->name)]; /* always make current object active */ - tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL); + tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL, true); ob = OBACT; /* restore bone name */ @@ -498,8 +498,10 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname) char newname[sizeof(pchan->name)]; /* always make current pose-bone active */ - tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL); + tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL, true); ob = OBACT; + + BLI_assert(ob->type == OB_ARMATURE); /* restore bone name */ BLI_strncpy(newname, pchan->name, sizeof(pchan->name)); @@ -1154,7 +1156,7 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa active = OL_DRAWSEL_NORMAL; } else { - active = tree_element_active(C, scene, soops, te, OL_SETSEL_NONE); + active = tree_element_active(C, scene, soops, te, OL_SETSEL_NONE, false); } } else { @@ -1295,7 +1297,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene active = OL_DRAWSEL_ACTIVE; } else { - if (tree_element_active(C, scene, soops, te, OL_SETSEL_NONE)) { + if (tree_element_active(C, scene, soops, te, OL_SETSEL_NONE, false)) { glColor4ub(220, 220, 255, alpha); active = OL_DRAWSEL_ACTIVE; } diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index b1278c7cc07..317d33dd3e2 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -180,9 +180,8 @@ void restrictbutton_gr_restrict_flag(void *poin, void *poin2, int flag); eOLDrawState tree_element_type_active( struct bContext *C, struct Scene *scene, struct SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set, bool recursive); -eOLDrawState tree_element_active( - struct bContext *C, struct Scene *scene, SpaceOops *soops, - TreeElement *te, const eOLSetState set); +eOLDrawState tree_element_active(struct bContext *C, struct Scene *scene, SpaceOops *soops, + TreeElement *te, const eOLSetState set, const bool handle_all_types); int outliner_item_do_activate(struct bContext *C, int x, int y, bool extend, bool recursive); /* outliner_edit.c ---------------------------------------------- */ diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 688695e3ded..51db965b791 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -801,14 +801,17 @@ static eOLDrawState tree_element_active_keymap_item( /* ---------------------------------------------- */ /* generic call for ID data check or make/check active in UI */ -eOLDrawState tree_element_active( - bContext *C, Scene *scene, SpaceOops *soops, - TreeElement *te, const eOLSetState set) +eOLDrawState tree_element_active(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, + const eOLSetState set, const bool handle_all_types) { - switch (te->idcode) { - /* Note: no ID_OB: objects are handled specially to allow multiple + /* Note: ID_OB only if handle_all_type is true, else objects are handled specially to allow multiple * selection. See do_outliner_item_activate. */ + case ID_OB: + if (handle_all_types) { + return tree_element_set_active_object(C, scene, soops, te, set, false); + } + break; case ID_MA: return tree_element_active_material(C, scene, soops, te, set); case ID_WO: @@ -952,7 +955,7 @@ static bool do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, Sp WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL); } else { // rest of types - tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL); + tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL, false); } } diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 1464d39ff23..3a9d97001fb 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2296,7 +2296,7 @@ static int sequencer_view_zoom_ratio_exec(bContext *C, wmOperator *op) float facx = BLI_rcti_size_x(&v2d->mask) / winx; float facy = BLI_rcti_size_y(&v2d->mask) / winy; - BLI_rctf_resize(&v2d->cur, (int)(winx * facx * ratio) + 1, (int)(winy * facy * ratio) + 1); + BLI_rctf_resize(&v2d->cur, floorf(winx * facx * ratio + 0.5f), floorf(winy * facy * ratio + 0.5f)); ED_region_tag_redraw(CTX_wm_region(C)); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index ea81bb2b857..57d6f053426 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -3590,9 +3590,8 @@ static int viewnumpad_exec(bContext *C, wmOperator *op) if (!rv3d->smooth_timer) { /* store settings of current view before allowing overwriting with camera view * only if we're not currently in a view transition */ - copy_qt_qt(rv3d->lviewquat, rv3d->viewquat); - rv3d->lview = rv3d->view; - rv3d->lpersp = rv3d->persp; + + ED_view3d_lastview_store(rv3d); } #if 0 @@ -4733,6 +4732,18 @@ void ED_view3d_to_object(Object *ob, const float ofs[3], const float quat[4], co BKE_object_apply_mat4(ob, mat, true, true); } +/** + * Use to store the last view, before entering camera view. + */ +void ED_view3d_lastview_store(RegionView3D *rv3d) +{ + copy_qt_qt(rv3d->lviewquat, rv3d->viewquat); + rv3d->lview = rv3d->view; + if (rv3d->persp != RV3D_CAMOB) { + rv3d->lpersp = rv3d->persp; + } +} + BGpic *ED_view3D_background_image_new(View3D *v3d) { BGpic *bgpic = MEM_callocN(sizeof(BGpic), "Background Image"); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 83e4f112a8c..20ef59708a6 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -417,11 +417,7 @@ static int view3d_camera_to_view_exec(bContext *C, wmOperator *UNUSED(op)) ED_view3d_context_user_region(C, &v3d, &ar); rv3d = ar->regiondata; - copy_qt_qt(rv3d->lviewquat, rv3d->viewquat); - rv3d->lview = rv3d->view; - if (rv3d->persp != RV3D_CAMOB) { - rv3d->lpersp = rv3d->persp; - } + ED_view3d_lastview_store(rv3d); BKE_object_tfm_protected_backup(v3d->camera, &obtfm); diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index 24f51635e07..5eca44c1ba5 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -137,7 +137,7 @@ static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3]) snapGridIncrement(t, vec); - if (t->num.flag & T_NULL_ONE) { + if (t->flag & T_NULL_ONE) { if (!(t->con.mode & CON_AXIS0)) vec[0] = 1.0f; @@ -970,13 +970,13 @@ static void setNearestAxis3d(TransInfo *t) sub_v2_v2v2(axis, axis_2d, t->center2d); axis[2] = 0.0f; - if (normalize_v3(axis) != 0.0f) { + if (normalize_v3(axis) > 1e-3f) { project_v3_v3v3(proj, mvec, axis); sub_v3_v3v3(axis, mvec, proj); len[i] = normalize_v3(axis); } else { - len[i] = 10000000000.0f; + len[i] = 1e10f; } } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index bb0a74f1e09..e49e5c941a6 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -3845,13 +3845,13 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) } /* special hack (must be done after initTransDataCurveHandles(), as that stores handle settings to restore...): - * - Check if we've got entire BezTriple selected and we're rotating that point, + * - Check if we've got entire BezTriple selected and we're scaling/rotating that point, * then check if we're using auto-handles. * - If so, change them auto-handles to aligned handles so that handles get affected too */ - if ((t->mode == TFM_ROTATION) && - ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) && - ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) + if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) && + ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM) && + ELEM(t->mode, TFM_ROTATION, TFM_RESIZE)) { if (hdata && (sel1) && (sel3)) { bezt->h1 = HD_ALIGN; diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c index 1f3725a961a..4c097ca7da6 100644 --- a/source/blender/editors/util/numinput.c +++ b/source/blender/editors/util/numinput.c @@ -321,8 +321,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event) n->val_org[idx] = n->val[idx]; n->val_flag[idx] &= ~(NUM_NEGATE | NUM_INVERSE); - idx += event->ctrl ? -1 : 1; - idx %= idx_max + 1; + idx = (idx + idx_max + (event->ctrl ? 0 : 2)) % (idx_max + 1); n->idx = idx; n->val[idx] = n->val_org[idx]; if (n->val_flag[idx] & NUM_EDITED) { @@ -334,42 +333,48 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event) } return true; case PADPERIOD: + case PERIODKEY: /* Force numdot, some OSs/countries generate a comma char in this case, sic... (T37992) */ ascii[0] = '.'; utf8_buf = ascii; break; +#if 0 /* Those keys are not directly accessible in all layouts, preventing to generate matching events. + * So we use a hack (ascii value) instead, see below. + */ case EQUALKEY: - /* XXX Advanced mode toggle, hack around keyboards without direct access to '=' nor '*'... */ - ascii[0] = '='; - break; case PADASTERKEY: - /* XXX Advanced mode toggle, hack around keyboards without direct access to '=' nor '*'... */ - ascii[0] = '*'; + if (!(n->flag & NUM_EDIT_FULL)) { + n->flag |= NUM_EDIT_FULL; + n->val_flag[idx] |= NUM_EDITED; + return true; + } + else if (event->ctrl) { + n->flag &= ~NUM_EDIT_FULL; + return true; + } break; +#endif case PADMINUS: case MINUSKEY: if (event->ctrl || !(n->flag & NUM_EDIT_FULL)) { n->val_flag[idx] ^= NUM_NEGATE; updated = true; - break; } - /* fall-through */ + break; case PADSLASHKEY: case SLASHKEY: if (event->ctrl || !(n->flag & NUM_EDIT_FULL)) { n->val_flag[idx] ^= NUM_INVERSE; updated = true; - break; } - /* fall-through */ + break; case CKEY: if (event->ctrl) { /* Copy current str to the copypaste buffer. */ WM_clipboard_text_set(n->str, 0); updated = true; - break; } - /* fall-through */ + break; case VKEY: if (event->ctrl) { /* extract the first line from the clipboard */ @@ -377,9 +382,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event) char *pbuf = WM_clipboard_text_get_firstline(false, &pbuf_len); if (pbuf) { - bool success; - - success = editstr_insert_at_cursor(n, pbuf, pbuf_len); + const bool success = editstr_insert_at_cursor(n, pbuf, pbuf_len); MEM_freeN(pbuf); if (!success) { @@ -389,15 +392,17 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event) n->val_flag[idx] |= NUM_EDITED; } updated = true; - break; } - /* fall-through */ + break; default: - utf8_buf = event->utf8_buf; - ascii[0] = event->ascii; break; } + if (!updated && !utf8_buf && (event->utf8_buf[0] || event->ascii)) { + utf8_buf = event->utf8_buf; + ascii[0] = event->ascii; + } + /* XXX Hack around keyboards without direct access to '=' nor '*'... */ if (ELEM(ascii[0], '=', '*')) { if (!(n->flag & NUM_EDIT_FULL)) { @@ -411,7 +416,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event) } } - if (utf8_buf && !utf8_buf[0] && ascii[0]) { + if ((!utf8_buf || !utf8_buf[0]) && ascii[0]) { /* Fallback to ascii. */ utf8_buf = ascii; } diff --git a/source/blender/freestyle/intern/geometry/FitCurve.cpp b/source/blender/freestyle/intern/geometry/FitCurve.cpp index e517bf4f196..fbfa5b331e6 100644 --- a/source/blender/freestyle/intern/geometry/FitCurve.cpp +++ b/source/blender/freestyle/intern/geometry/FitCurve.cpp @@ -557,17 +557,20 @@ void FitCurveWrapper::FitCubic(Vector2 *d, int first, int last, Vector2 tHat1, V if (maxError < iterationError) { for (i = 0; i < maxIterations; i++) { uPrime = Reparameterize(d, first, last, u, bezCurve); - bezCurve = GenerateBezier(d, first, last, uPrime, tHat1, tHat2); - maxError = ComputeMaxError(d, first, last, - bezCurve, uPrime, &splitPoint); + + free((void *)u); + free((void *)bezCurve); + u = uPrime; + + bezCurve = GenerateBezier(d, first, last, u, tHat1, tHat2); + maxError = ComputeMaxError(d, first, last, bezCurve, u, &splitPoint); + if (maxError < error) { DrawBezierCurve(3, bezCurve); free((void *)u); free((void *)bezCurve); return; } - free((void *)u); - u = uPrime; } } diff --git a/source/blender/freestyle/intern/geometry/GeomUtils.cpp b/source/blender/freestyle/intern/geometry/GeomUtils.cpp index abe13b85cd2..a750cf2f7cf 100644 --- a/source/blender/freestyle/intern/geometry/GeomUtils.cpp +++ b/source/blender/freestyle/intern/geometry/GeomUtils.cpp @@ -577,10 +577,10 @@ void transformVertex(const Vec3r& vert, const Matrix44r& matrix, Vec3r& res) void transformVertices(const vector<Vec3r>& vertices, const Matrix44r& trans, vector<Vec3r>& res) { - for (vector<Vec3r>::const_iterator v = vertices.begin(); v != vertices.end(); v++) { - Vec3r *res_tmp = new Vec3r; - transformVertex(*v, trans, *res_tmp); - res.push_back(*res_tmp); + size_t i; + res.resize(vertices.size()); + for (i = 0; i < vertices.size(); i++) { + transformVertex(vertices[i], trans, res[i]); } } diff --git a/source/blender/imbuf/intern/IMB_allocimbuf.h b/source/blender/imbuf/intern/IMB_allocimbuf.h index 02b738cc2cd..f4d6d869f1b 100644 --- a/source/blender/imbuf/intern/IMB_allocimbuf.h +++ b/source/blender/imbuf/intern/IMB_allocimbuf.h @@ -35,6 +35,9 @@ struct ImBuf; +void imb_refcounter_lock_init(void); +void imb_refcounter_lock_exit(void); + bool imb_addencodedbufferImBuf(struct ImBuf *ibuf); bool imb_enlargeencodedbufferImBuf(struct ImBuf *ibuf); diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c index d7ca381bae6..d0e81f2f383 100644 --- a/source/blender/imbuf/intern/allocimbuf.c +++ b/source/blender/imbuf/intern/allocimbuf.c @@ -49,6 +49,19 @@ #include "MEM_CacheLimiterC-Api.h" #include "BLI_utildefines.h" +#include "BLI_threads.h" + +static SpinLock refcounter_spin; + +void imb_refcounter_lock_init(void) +{ + BLI_spin_init(&refcounter_spin); +} + +void imb_refcounter_lock_exit(void) +{ + BLI_spin_end(&refcounter_spin); +} void imb_freemipmapImBuf(ImBuf *ibuf) { @@ -154,10 +167,18 @@ void IMB_freezbuffloatImBuf(ImBuf *ibuf) void IMB_freeImBuf(ImBuf *ibuf) { if (ibuf) { + bool needs_free = false; + + BLI_spin_lock(&refcounter_spin); if (ibuf->refcounter > 0) { ibuf->refcounter--; } else { + needs_free = true; + } + BLI_spin_unlock(&refcounter_spin); + + if (needs_free) { imb_freerectImBuf(ibuf); imb_freerectfloatImBuf(ibuf); imb_freetilesImBuf(ibuf); @@ -177,7 +198,9 @@ void IMB_freeImBuf(ImBuf *ibuf) void IMB_refImBuf(ImBuf *ibuf) { + BLI_spin_lock(&refcounter_spin); ibuf->refcounter++; + BLI_spin_unlock(&refcounter_spin); } ImBuf *IMB_makeSingleUser(ImBuf *ibuf) diff --git a/source/blender/imbuf/intern/module.c b/source/blender/imbuf/intern/module.c index 9141dad6f9c..4097deb00ed 100644 --- a/source/blender/imbuf/intern/module.c +++ b/source/blender/imbuf/intern/module.c @@ -26,12 +26,17 @@ #include <stddef.h> + +#include "BLI_utildefines.h" + +#include "IMB_allocimbuf.h" #include "IMB_imbuf.h" #include "IMB_filetype.h" #include "IMB_colormanagement_intern.h" void IMB_init(void) { + imb_refcounter_lock_init(); imb_filetypes_init(); imb_tile_cache_init(); colormanagement_init(); @@ -42,5 +47,6 @@ void IMB_exit(void) imb_tile_cache_exit(); imb_filetypes_exit(); colormanagement_exit(); + imb_refcounter_lock_exit(); } diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c index 07ce3c39d73..f699afd3475 100644 --- a/source/blender/imbuf/intern/moviecache.c +++ b/source/blender/imbuf/intern/moviecache.c @@ -200,6 +200,18 @@ static size_t IMB_get_size_in_memory(ImBuf *ibuf) int a; size_t size = 0, channel_size = 0; + /* Persistent images should have no affect on how "normal" + * images are cached. + * + * This is a bit arbitrary, but would make it so only movies + * and sequences are memory limited, keeping textures in the + * memory in order to avoid constant file reload on viewport + * update. + */ + if (ibuf->userflags & IB_PERSISTENT) { + return 0; + } + size += sizeof(ImBuf); if (ibuf->rect) diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c index 05e9a4fa134..eb8f94cbc6e 100644 --- a/source/blender/imbuf/intern/tiff.c +++ b/source/blender/imbuf/intern/tiff.c @@ -859,7 +859,7 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags) TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); if (TIFFWriteEncodedStrip(image, 0, (bitspersample == 16) ? (unsigned char *)pixels16 : pixels, - ibuf->x * ibuf->y * samplesperpixel * bitspersample / 8) == -1) + (size_t)ibuf->x * ibuf->y * samplesperpixel * bitspersample / 8) == -1) { fprintf(stderr, "imb_savetiff: Could not write encoded TIFF.\n"); diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 7efd0223368..087f26dda44 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -179,6 +179,7 @@ const char *imb_ext_audio[] = { ".aif", ".aiff", ".m4a", + ".mka", NULL }; diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 86ef2f1b74f..2f867fe95e1 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -2035,7 +2035,7 @@ void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values) BLI_assert(RNA_property_array_check(prop) != false); if ((idprop = rna_idproperty_check(&prop, ptr))) { - BLI_assert(idprop->len == RNA_property_array_length(ptr, prop)); + BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY)); if (prop->arraydimension == 0) values[0] = RNA_property_int_get(ptr, prop); else @@ -2124,7 +2124,7 @@ void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *v BLI_assert(RNA_property_array_check(prop) != false); if ((idprop = rna_idproperty_check(&prop, ptr))) { - BLI_assert(idprop->len == RNA_property_array_length(ptr, prop)); + BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY)); if (prop->arraydimension == 0) IDP_Int(idprop) = values[0]; else @@ -2297,7 +2297,7 @@ void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *val BLI_assert(RNA_property_array_check(prop) != false); if ((idprop = rna_idproperty_check(&prop, ptr))) { - BLI_assert(idprop->len == RNA_property_array_length(ptr, prop)); + BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY)); if (prop->arraydimension == 0) values[0] = RNA_property_float_get(ptr, prop); else if (idprop->subtype == IDP_FLOAT) { @@ -2392,7 +2392,7 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const floa BLI_assert(RNA_property_array_check(prop) != false); if ((idprop = rna_idproperty_check(&prop, ptr))) { - BLI_assert(idprop->len == RNA_property_array_length(ptr, prop)); + BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY)); if (prop->arraydimension == 0) { if (idprop->type == IDP_FLOAT) IDP_Float(idprop) = values[0]; diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index 408f99bd96a..a55be8e285f 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -62,6 +62,7 @@ #include "ED_node.h" #include "IMB_colormanagement.h" +#include "IMB_imbuf.h" static int rna_CurveMapping_curves_length(PointerRNA *ptr) { @@ -609,10 +610,24 @@ static void rna_ColorManagedColorspaceSettings_reload_update(Main *UNUSED(bmain) } if (seq_found) { + if (seq->anim) { + IMB_free_anim(seq->anim); + seq->anim = NULL; + } + BKE_sequence_invalidate_cache(scene, seq); BKE_sequencer_preprocessed_cache_cleanup_sequence(seq); } else { + SEQ_BEGIN(scene->ed, seq); + { + if (seq->anim) { + IMB_free_anim(seq->anim); + seq->anim = NULL; + } + } + SEQ_END; + BKE_sequencer_cache_cleanup(); BKE_sequencer_preprocessed_cache_cleanup(); } diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 31e87f44a6a..f6f133c5114 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -475,7 +475,8 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, Rep if (particle_no < totpart) { /* get uvco & mcol */ - num = particle->num_dmcache; + num = (ELEM(particle->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND)) ? + particle->num : particle->num_dmcache; if (num == DMCACHE_NOTFOUND) if (particle->num < modifier->dm->getNumTessFaces(modifier->dm)) diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index 479f70531e5..ae0841b4e28 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -821,7 +821,9 @@ static EnumPropertyItem *rna_EnumProperty_default_itemf(bContext *C, PointerRNA (ptr->type == &RNA_EnumProperty) || (C == NULL)) { - return eprop->item; + if (eprop->item) { + return eprop->item; + } } return eprop->itemf(C, ptr, prop, r_free); diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c index 16f51bdd34f..142e5cadfd1 100644 --- a/source/blender/python/mathutils/mathutils_geometry.c +++ b/source/blender/python/mathutils/mathutils_geometry.c @@ -1515,7 +1515,7 @@ static PyObject *M_Geometry_box_pack_2d(PyObject *UNUSED(self), PyObject *boxlis ret = PyTuple_New(2); PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(tot_width)); - PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(tot_width)); + PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(tot_height)); return ret; } diff --git a/source/blender/render/intern/source/bake.c b/source/blender/render/intern/source/bake.c index 977c30ff20a..59a2a0d78fc 100644 --- a/source/blender/render/intern/source/bake.c +++ b/source/blender/render/intern/source/bake.c @@ -981,6 +981,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up int a, vdone = false, result = BAKE_RESULT_OK; bool use_mask = false; bool use_displacement_buffer = false; + bool do_manage = BKE_scene_check_color_management_enabled(re->scene); re->scene_color_manage = BKE_scene_check_color_management_enabled(re->scene); @@ -1040,6 +1041,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up } handles[a].ssamp.shi[0].combinedflag = ~(SCE_PASS_SPEC); handles[a].ssamp.shi[0].thread = a; + handles[a].ssamp.shi[0].do_manage = do_manage; handles[a].ssamp.tot = 1; handles[a].type = type; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 0d09fa0401e..7d662f8f338 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -5873,7 +5873,9 @@ void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay, re->lay= lay; /* renderdata setup and exceptions */ - re->r= scene->r; + BLI_freelistN(&re->r.layers); + re->r = scene->r; + BLI_duplicatelist(&re->r.layers, &scene->r.layers); RE_init_threadcount(re); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 74768f925f8..4bf65879ad6 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1413,7 +1413,6 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) if (op->type->flag & OPTYPE_MACRO) { for (op = op->macro.first; op; op = op->next) { - uiItemL(layout, RNA_struct_ui_name(op->type->srna), ICON_NONE); uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE); } } @@ -1816,14 +1815,14 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar /* label for 'a' bugfix releases, or 'Release Candidate 1'... * avoids recreating splash for version updates */ - if (false) { + if (true) { /* placed after the version number in the image, * placing y is tricky to match baseline */ int x = 260 - (2 * UI_DPI_WINDOW_FAC); int y = 242 + (4 * UI_DPI_WINDOW_FAC); int w = 240; - const char *version_suffix = "Release Candidate"; + const char *version_suffix = "a"; /* hack to have text draw 'text_sel' */ diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 6a2ef471be0..9fa64bf65b3 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -373,15 +373,20 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win) if (win->eventstate == NULL) win->eventstate = MEM_callocN(sizeof(wmEvent), "window event state"); +#ifdef __APPLE__ + /* set the state here, else OSX would nor recignize changed screen resolution */ + GHOST_SetWindowState(ghostwin, (GHOST_TWindowState)win->windowstate); +#endif /* store actual window size in blender window */ bounds = GHOST_GetClientBounds(win->ghostwin); win->sizex = GHOST_GetWidthRectangle(bounds); win->sizey = GHOST_GetHeightRectangle(bounds); GHOST_DisposeRectangle(bounds); - - /* set the state */ + +#ifndef __APPLE__ + /* set the state here, so minimized state comes up correct on windows */ GHOST_SetWindowState(ghostwin, (GHOST_TWindowState)win->windowstate); - +#endif /* until screens get drawn, make it nice gray */ glClearColor(0.55, 0.55, 0.55, 0.0); /* Crash on OSS ATI: bugs.launchpad.net/ubuntu/+source/mesa/+bug/656100 */ diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 0ec54412485..365bce34a60 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -938,11 +938,12 @@ static RAS_MaterialBucket *material_from_mesh(Material *ma, MFace *mface, MTFace // this way only one KX_BlenderMaterial object has to exist per bucket bool bucketCreated; RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated); - if (bucketCreated) { - // this is needed to free up memory afterwards - converter->RegisterPolyMaterial(polymat); - converter->RegisterBlenderMaterial(bl_mat); - } + + // this is needed to free up memory afterwards. + // the converter will also prevent duplicates from being registered, + // so just register everything. + converter->RegisterPolyMaterial(polymat); + converter->RegisterBlenderMaterial(bl_mat); return bucket; } diff --git a/source/gameengine/Converter/BlenderWorldInfo.cpp b/source/gameengine/Converter/BlenderWorldInfo.cpp index be85d89775f..75beb5d0e0e 100644 --- a/source/gameengine/Converter/BlenderWorldInfo.cpp +++ b/source/gameengine/Converter/BlenderWorldInfo.cpp @@ -61,6 +61,7 @@ #include "BLI_math.h" #include "BKE_global.h" +#include "BKE_scene.h" /* end of blender include block */ @@ -86,7 +87,7 @@ BlenderWorldInfo::BlenderWorldInfo(struct Scene *blenderscene, struct World *ble copy_v3_v3(m_backgroundcolor, &blenderworld->horr); copy_v3_v3(m_ambientcolor, &blenderworld->ambr); - if (blenderscene->r.color_mgt_flag & R_COLOR_MANAGEMENT) { + if (BKE_scene_check_color_management_enabled(blenderscene)) { linearrgb_to_srgb_v3_v3(m_mistcolor, m_mistcolor); linearrgb_to_srgb_v3_v3(m_backgroundcolor, m_backgroundcolor); linearrgb_to_srgb_v3_v3(m_ambientcolor, m_ambientcolor); diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index c0c28d15ad3..854e9fe7327 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -233,8 +233,7 @@ Scene *KX_BlenderSceneConverter::GetBlenderSceneForName(const STR_String& name) Scene *sce; /** - * Find the specified scene by name, or the first - * scene if nothing matches (shouldn't happen). + * Find the specified scene by name, or NULL if nothing matches. */ if ((sce= (Scene *)BLI_findstring(&m_maggie->scene, name.ReadPtr(), offsetof(ID, name) + 2))) return sce; @@ -246,7 +245,7 @@ Scene *KX_BlenderSceneConverter::GetBlenderSceneForName(const STR_String& name) return sce; } - return (Scene*)m_maggie->scene.first; + return NULL; } diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 3aa5a9f4f0e..e6b22420d90 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -1702,6 +1702,8 @@ KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene, bool libloading) KX_Scene* KX_KetsjiEngine::CreateScene(const STR_String& scenename) { Scene *scene = m_sceneconverter->GetBlenderSceneForName(scenename); + if (!scene) + return NULL; return CreateScene(scene); } @@ -1717,8 +1719,12 @@ void KX_KetsjiEngine::AddScheduledScenes() { STR_String scenename = *scenenameit; KX_Scene* tmpscene = CreateScene(scenename); - m_scenes.push_back(tmpscene); - PostProcessScene(tmpscene); + if (tmpscene) { + m_scenes.push_back(tmpscene); + PostProcessScene(tmpscene); + } else { + printf("warning: scene %s could not be found, not added!\n",scenename.ReadPtr()); + } } m_addingOverlayScenes.clear(); } @@ -1731,9 +1737,12 @@ void KX_KetsjiEngine::AddScheduledScenes() { STR_String scenename = *scenenameit; KX_Scene* tmpscene = CreateScene(scenename); - m_scenes.insert(m_scenes.begin(),tmpscene); - PostProcessScene(tmpscene); - + if (tmpscene) { + m_scenes.insert(m_scenes.begin(),tmpscene); + PostProcessScene(tmpscene); + } else { + printf("warning: scene %s could not be found, not added!\n",scenename.ReadPtr()); + } } m_addingBackgroundScenes.clear(); } diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp index e85b57f1769..abbe65738d4 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp @@ -395,10 +395,8 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas) return; const int *viewport = canvas->GetViewPort(); - RAS_Rect rect = canvas->GetWindowArea(); - int rect_width = rect.GetWidth()+1, rect_height = rect.GetHeight()+1; - if (texturewidth != rect_width || textureheight != rect_height) + if (texturewidth != viewport[2] || textureheight != viewport[3]) { UpdateOffsetMatrix(canvas); UpdateCanvasTextureCoord(viewport); @@ -414,22 +412,22 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas) if (need_depth) { glActiveTextureARB(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texname[1]); - glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, rect.GetLeft(), rect.GetBottom(), rect_width, rect_height, 0); + glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, viewport[0], viewport[1], viewport[2], viewport[3], 0); } if (need_luminance) { glActiveTextureARB(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, texname[2]); - glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, rect.GetLeft(), rect.GetBottom(), rect_width, rect_height, 0); + glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, viewport[0], viewport[1], viewport[2], viewport[3], 0); } // reverting to texunit 0, without this we get bug [#28462] glActiveTextureARB(GL_TEXTURE0); - canvas->SetViewPort(0, 0, rect_width-1, rect_height-1); // We do this to make side-by-side stereo rendering work correctly with 2D filters. It would probably be nicer to just set the viewport, // but it can be easier for writing shaders to have the coordinates for the whole screen instead of just part of the screen. RAS_Rect scissor_rect = canvas->GetDisplayArea(); + glScissor(scissor_rect.GetLeft() + viewport[0], scissor_rect.GetBottom() + viewport[1], scissor_rect.GetWidth() + 1, @@ -459,7 +457,7 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas) glActiveTextureARB(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texname[0]); - glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rect.GetLeft(), rect.GetBottom(), rect_width, rect_height, 0); // Don't use texturewidth and textureheight in case we don't have NPOT support + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, viewport[0], viewport[1], viewport[2], viewport[3], 0); // Don't use texturewidth and textureheight in case we don't have NPOT support glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_QUADS); @@ -473,8 +471,6 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas) } glEnable(GL_DEPTH_TEST); - //We can't pass the results of canvas->GetViewPort() directly because canvas->SetViewPort() does some extra math [#34517] - canvas->SetViewPort(0, 0, viewport[2]-1, viewport[3]-1); EndShaderProgram(); glPopMatrix(); glMatrixMode(GL_MODELVIEW); |