diff options
Diffstat (limited to 'source/blender/editors')
116 files changed, 2233 insertions, 1272 deletions
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 041a2c2216e..09b6e7d2206 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -1546,7 +1546,9 @@ static size_t animdata_filter_ds_linestyle(bAnimContext *ac, ListBase *anim_data for (srl = sce->r.layers.first; srl; srl = srl->next) { for (lineset = srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) { - lineset->linestyle->id.flag |= LIB_DOIT; + if (lineset->linestyle) { + lineset->linestyle->id.flag |= LIB_DOIT; + } } } @@ -1562,8 +1564,11 @@ static size_t animdata_filter_ds_linestyle(bAnimContext *ac, ListBase *anim_data ListBase tmp_data = {NULL, NULL}; size_t tmp_items = 0; - if (!(linestyle->id.flag & LIB_DOIT)) + if ((linestyle == NULL) || + !(linestyle->id.flag & LIB_DOIT)) + { continue; + } linestyle->id.flag &= ~LIB_DOIT; /* add scene-level animation channels */ diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index 3c8576be312..34246427b7e 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -1380,7 +1380,7 @@ static int ed_marker_rename_invoke_wrapper(bContext *C, wmOperator *op, const wm RNA_string_set(op->ptr, "name", marker->name); /* now see if the operator is usable */ - return ed_markers_opwrap_invoke_custom(C, op, event, WM_operator_props_popup); + return ed_markers_opwrap_invoke_custom(C, op, event, WM_operator_props_popup_confirm); } static void MARKER_OT_rename(wmOperatorType *ot) diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c index decbc351cad..71717284d8e 100644 --- a/source/blender/editors/animation/keyframes_edit.c +++ b/source/blender/editors/animation/keyframes_edit.c @@ -396,7 +396,7 @@ void ANIM_editkeyframes_refresh(bAnimContext *ac) int filter; /* when not in graph view, don't use handles */ SpaceIpo *sipo = (ac->spacetype == SPACE_IPO) ? (SpaceIpo *)ac->sl : NULL; - const short use_handle = sipo ? !(sipo->flag & SIPO_NOHANDLES) : FALSE; + const bool use_handle = sipo ? !(sipo->flag & SIPO_NOHANDLES) : false; /* filter animation data */ filter = ANIMFILTER_DATA_VISIBLE; diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 70361f00004..6b9200afb75 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -61,6 +61,7 @@ #include "BKE_depsgraph.h" #include "BKE_fcurve.h" #include "BKE_main.h" +#include "BKE_idcode.h" #include "BKE_nla.h" #include "BKE_global.h" #include "BKE_context.h" @@ -141,9 +142,18 @@ bAction *verify_adt_action(ID *id, short add) /* init action if none available yet */ /* TODO: need some wizardry to handle NLA stuff correct */ if ((adt->action == NULL) && (add)) { + /* init action name from name of ID block */ char actname[sizeof(id->name) - 2]; BLI_snprintf(actname, sizeof(actname), "%sAction", id->name + 2); + + /* create action */ adt->action = add_empty_action(G.main, actname); + + /* set ID-type from ID-block that this is going to be assigned to + * so that users can't accidentally break actions by assigning them + * to the wrong places + */ + adt->action->idroot = GS(id->name); } /* return the action */ @@ -996,6 +1006,34 @@ short insert_keyframe(ReportList *reports, ID *id, bAction *act, const char grou * The flag argument is used for special settings that alter the behavior of * the keyframe deletion. These include the quick refresh options. */ + + + +/** + * \note caller needs to run #BKE_nla_tweakedit_remap to get NLA relative frame. + * caller should also check #BKE_fcurve_is_protected before keying. + */ +static bool delete_keyframe_fcurve(AnimData *adt, FCurve *fcu, float cfra) +{ + bool found; + int i; + + /* try to find index of beztriple to get rid of */ + i = binarysearch_bezt_index(fcu->bezt, cfra, fcu->totvert, &found); + if (found) { + /* delete the key at the index (will sanity check + do recalc afterwards) */ + delete_fcurve_key(fcu, i, 1); + + /* Only delete curve too if it won't be doing anything anymore */ + if ((fcu->totvert == 0) && (list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0)) + ANIM_fcurve_delete_from_animdata(NULL, adt, fcu); + + /* return success */ + return true; + } + return false; +} + short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short UNUSED(flag)) { AnimData *adt = BKE_animdata_from_id(id); @@ -1055,32 +1093,20 @@ short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char grou /* will only loop once unless the array index was -1 */ for (; array_index < array_index_max; array_index++) { FCurve *fcu = verify_fcurve(act, group, &ptr, rna_path, array_index, 0); - bool found; - int i; - + /* check if F-Curve exists and/or whether it can be edited */ if (fcu == NULL) continue; - - if ( (fcu->flag & FCURVE_PROTECTED) || ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ) { - if (G.debug & G_DEBUG) - printf("WARNING: not deleting keyframe for locked F-Curve\n"); + + if (BKE_fcurve_is_protected(fcu)) { + BKE_reportf(reports, RPT_WARNING, + "not deleting keyframe for locked F-Curve '%s' for %s '%s'", + fcu->rna_path, BKE_idcode_to_name(GS(id->name)), id->name + 2); continue; } - - /* try to find index of beztriple to get rid of */ - i = binarysearch_bezt_index(fcu->bezt, cfra, fcu->totvert, &found); - if (found) { - /* delete the key at the index (will sanity check + do recalc afterwards) */ - delete_fcurve_key(fcu, i, 1); - - /* Only delete curve too if it won't be doing anything anymore */ - if ((fcu->totvert == 0) && (list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0)) - ANIM_fcurve_delete_from_animdata(NULL, adt, fcu); - - /* return success */ - ret++; - } + + ret += delete_keyframe_fcurve(adt, fcu, cfra); + } /* return success/failure */ @@ -1158,7 +1184,7 @@ static short clear_keyframe(ReportList *reports, ID *id, bAction *act, const cha if (fcu == NULL) continue; - if ( (fcu->flag & FCURVE_PROTECTED) || ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ) { + if (BKE_fcurve_is_protected(fcu)) { if (G.debug & G_DEBUG) printf("WARNING: not deleting keyframe for locked F-Curve\n"); continue; @@ -1537,14 +1563,22 @@ static int delete_key_v3d_exec(bContext *C, wmOperator *op) AnimData *adt = ob->adt; bAction *act = adt->action; FCurve *fcu, *fcn; + const float cfra_unmap = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP); for (fcu = act->curves.first; fcu; fcu = fcn) { fcn = fcu->next; - + + if (BKE_fcurve_is_protected(fcu)) { + BKE_reportf(op->reports, RPT_WARNING, + "not deleting keyframe for locked F-Curve '%s', object '%s'", + fcu->rna_path, id->name + 2); + continue; + } + /* delete keyframes on current frame * WARNING: this can delete the next F-Curve, hence the "fcn" copying */ - success += delete_keyframe(op->reports, id, NULL, NULL, fcu->rna_path, fcu->array_index, cfra, 0); + success += delete_keyframe_fcurve(adt, fcu, cfra_unmap); } } diff --git a/source/blender/editors/armature/BIF_retarget.h b/source/blender/editors/armature/BIF_retarget.h index 2ea0e0ab0d7..21e85b6fe89 100644 --- a/source/blender/editors/armature/BIF_retarget.h +++ b/source/blender/editors/armature/BIF_retarget.h @@ -29,6 +29,7 @@ #include "BLI_graph.h" #include "BLI_ghash.h" +#include "BLI_task.h" #include "BLI_threads.h" #include "reeb.h" @@ -68,7 +69,8 @@ typedef struct RigGraph { ReebGraph *link_mesh; - struct ThreadedWorker *worker; + TaskScheduler *task_scheduler; + TaskPool *task_pool; GHash *bones_map; /* map of editbones by name */ GHash *controls_map; /* map of rigcontrols by bone pointer */ diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c index 1ee2dc80a97..8745d571a28 100644 --- a/source/blender/editors/armature/armature_naming.c +++ b/source/blender/editors/armature/armature_naming.c @@ -182,16 +182,22 @@ void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *n if (ob->pose) { bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, oldname); if (pchan) { + GHash *gh = ob->pose->chanhash; + + /* remove the old hash entry, and replace with the new name */ + if (gh) { + BLI_assert(BLI_ghash_haskey(gh, pchan->name)); + BLI_ghash_remove(gh, pchan->name, NULL, NULL); + } + BLI_strncpy(pchan->name, newname, MAXBONENAME); - - if (ob->pose->chanhash) { - GHash *gh = ob->pose->chanhash; - - /* remove the old hash entry, and replace with the new name */ - BLI_ghash_remove(gh, oldname, NULL, NULL); + + if (gh) { BLI_ghash_insert(gh, pchan->name, pchan); } } + + BLI_assert(BKE_pose_channels_is_valid(ob->pose) == true); } /* Update any object constraints to use the new bone name */ @@ -294,9 +300,13 @@ static int armature_flip_names_exec(bContext *C, wmOperator *UNUSED(op)) /* since we renamed stuff... */ DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - /* note, notifier might evolve */ - WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); - + /* copied from #rna_Bone_update_renamed */ + /* redraw view */ + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + + /* update animation channels */ + WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, ob->data); + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c index 687455495a1..c03e7861307 100644 --- a/source/blender/editors/armature/editarmature_retarget.c +++ b/source/blender/editors/armature/editarmature_retarget.c @@ -83,7 +83,7 @@ static RigGraph *GLOBAL_RIGG = NULL; /*******************************************************************************************************/ -void *exec_retargetArctoArc(void *param); +void exec_retargetArctoArc(TaskPool *pool, void *taskdata, int threadid); static void RIG_calculateEdgeAngles(RigEdge *edge_first, RigEdge *edge_second); float rollBoneByQuat(EditBone *bone, float old_up_axis[3], float qrot[4]); @@ -235,9 +235,8 @@ void RIG_freeRigGraph(BGraph *rg) BNode *node; BArc *arc; -#ifdef USE_THREADS - BLI_destroy_worker(rigg->worker); -#endif + BLI_task_pool_free(rigg->task_pool); + BLI_task_scheduler_free(rigg->task_scheduler); if (rigg->link_mesh) { REEB_freeGraph(rigg->link_mesh); @@ -284,12 +283,14 @@ static RigGraph *newRigGraph(void) rg->free_node = NULL; #ifdef USE_THREADS - //totthread = BKE_scene_num_threads(G.scene); - totthread = BLI_system_thread_count(); - - rg->worker = BLI_create_worker(exec_retargetArctoArc, totthread, 20); /* fix number of threads */ + totthread = TASK_SCHEDULER_AUTO_THREADS; +#else + totthread = TASK_SCHEDULER_SINGLE_THREAD; #endif - + + rg->task_scheduler = BLI_task_scheduler_create(totthread); + rg->task_pool = BLI_task_pool_create(rg->task_scheduler, NULL); + return rg; } @@ -2133,7 +2134,6 @@ static void retargetArctoArcLength(bContext *C, RigGraph *rigg, RigArc *iarc, Ri static void retargetArctoArc(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start) { -#ifdef USE_THREADS RetargetParam *p = MEM_callocN(sizeof(RetargetParam), "RetargetParam"); p->rigg = rigg; @@ -2141,22 +2141,12 @@ static void retargetArctoArc(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode p->inode_start = inode_start; p->context = C; - BLI_insert_work(rigg->worker, p); -#else - RetargetParam p; - - p.rigg = rigg; - p.iarc = iarc; - p.inode_start = inode_start; - p.context = C; - - exec_retargetArctoArc(&p); -#endif + BLI_task_pool_push(rigg->task_pool, exec_retargetArctoArc, p, true, TASK_PRIORITY_HIGH); } -void *exec_retargetArctoArc(void *param) +void exec_retargetArctoArc(TaskPool *UNUSED(pool), void *taskdata, int UNUSED(threadid)) { - RetargetParam *p = (RetargetParam *)param; + RetargetParam *p = (RetargetParam *)taskdata; RigGraph *rigg = p->rigg; RigArc *iarc = p->iarc; bContext *C = p->context; @@ -2183,12 +2173,6 @@ void *exec_retargetArctoArc(void *param) retargetArctoArcLength(C, rigg, iarc, inode_start); } } - -#ifdef USE_THREADS - MEM_freeN(p); -#endif - - return NULL; } static void matchMultiResolutionNode(RigGraph *rigg, RigNode *inode, ReebNode *top_node) @@ -2414,9 +2398,7 @@ static void retargetSubgraph(bContext *C, RigGraph *rigg, RigArc *start_arc, Rig static void finishRetarget(RigGraph *rigg) { -#ifdef USE_THREADS - BLI_end_worker(rigg->worker); -#endif + BLI_task_pool_work_and_wait(rigg->task_pool); } static void adjustGraphs(bContext *C, RigGraph *rigg) diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c index cb7a699b522..182f94b3693 100644 --- a/source/blender/editors/armature/pose_lib.c +++ b/source/blender/editors/armature/pose_lib.c @@ -638,7 +638,7 @@ static int poselib_rename_invoke(bContext *C, wmOperator *op, const wmEvent *eve } /* part to sync with other similar operators... */ - return WM_operator_props_popup(C, op, event); + return WM_operator_props_popup_confirm(C, op, event); } static int poselib_rename_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/curve/editcurve_add.c b/source/blender/editors/curve/editcurve_add.c index 0bcb550b930..9b858a2c4e9 100644 --- a/source/blender/editors/curve/editcurve_add.c +++ b/source/blender/editors/curve/editcurve_add.c @@ -58,7 +58,7 @@ #include "curve_intern.h" -static float nurbcircle[8][2] = { +static const float nurbcircle[8][2] = { {0.0, -1.0}, {-1.0, -1.0}, {-1.0, 0.0}, {-1.0, 1.0}, {0.0, 1.0}, { 1.0, 1.0}, { 1.0, 0.0}, { 1.0, -1.0} }; diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index b9759e16f20..ac9c338e431 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -981,7 +981,7 @@ void FONT_OT_move_select(wmOperatorType *ot) { /* identifiers */ ot->name = "Move Select"; - ot->description = "Make selection from current cursor position to new cursor position type"; + ot->description = "Move the cursor while selecting"; ot->idname = "FONT_OT_move_select"; /* api callbacks */ diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h index 352a74cf172..dd1995a5428 100644 --- a/source/blender/editors/include/BIF_glutil.h +++ b/source/blender/editors/include/BIF_glutil.h @@ -221,8 +221,5 @@ void glaDrawImBuf_glsl(struct ImBuf *ibuf, float x, float y, int zoomfilter, /* Draw imbuf on a screen, preferably using GLSL display transform */ void glaDrawImBuf_glsl_ctx(const struct bContext *C, struct ImBuf *ibuf, float x, float y, int zoomfilter); -/* Transform buffer from role to scene linear space using GLSL OCIO conversion */ -int glaBufferTransformFromRole_glsl(float *buffer, int width, int height, int role); - #endif /* __BIF_GLUTIL_H__ */ diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h index 3e2dbe255df..8da36f015dc 100644 --- a/source/blender/editors/include/ED_mask.h +++ b/source/blender/editors/include/ED_mask.h @@ -57,7 +57,7 @@ void ED_operatormacros_mask(void); /* mask_draw.c */ void ED_mask_draw(const struct bContext *C, const char draw_flag, const char draw_type); void ED_mask_draw_region(struct Mask *mask, struct ARegion *ar, - const char draw_flag, const char draw_type, + const char draw_flag, const char draw_type, const char overlay_mode, const int width_i, const int height_i, const float aspx, const float aspy, const short do_scale_applied, const short do_draw_cb, diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index b7fd181883b..5d3d72d0e3d 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -152,7 +152,7 @@ void EDBM_select_mirrored(struct BMEditMesh *em, bool extend, void EDBM_automerge(struct Scene *scene, struct Object *ob, bool update, const char hflag); bool EDBM_backbuf_border_init(struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax); -int EDBM_backbuf_check(unsigned int index); +bool EDBM_backbuf_check(unsigned int index); void EDBM_backbuf_free(void); bool EDBM_backbuf_border_mask_init(struct ViewContext *vc, const int mcords[][2], short tot, diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h index bdfbbbb9c74..518bee665ae 100644 --- a/source/blender/editors/include/ED_render.h +++ b/source/blender/editors/include/ED_render.h @@ -40,6 +40,7 @@ struct Scene; struct ScrArea; struct RegionView3D; struct RenderEngine; +struct View3D; /* render_ops.c */ @@ -51,6 +52,7 @@ void ED_render_id_flush_update(struct Main *bmain, struct ID *id); void ED_render_engine_changed(struct Main *bmain); void ED_render_engine_area_exit(struct ScrArea *sa); void ED_render_scene_update(struct Main *bmain, struct Scene *scene, int updated); +void ED_render_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrArea *sa); void ED_viewport_render_kill_jobs(const struct bContext *C, bool free_database); diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index 81308dd84f2..eff79b6a039 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -103,7 +103,7 @@ enum TfmMode { * returns 1 if successful, 0 otherwise (usually means there's no selection) * (if 0 is returns, *vec is unmodified) * */ -int calculateTransformCenter(struct bContext *C, int centerMode, float cent3d[3], int cent2d[2]); +int calculateTransformCenter(struct bContext *C, int centerMode, float cent3d[3], float cent2d[2]); struct TransInfo; struct ScrArea; diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index ce9d3af3013..86abf29c308 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -336,4 +336,7 @@ void ED_view3d_operator_properties_viewmat_set(struct bContext *C, struct wmOper void ED_view3d_operator_properties_viewmat_get(struct wmOperator *op, int *winx, int *winy, float persmat[4][4]); #endif +/* render */ +void ED_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrArea *sa); + #endif /* __ED_VIEW3D_H__ */ diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt index a8b8765a5c6..e13517adbb3 100644 --- a/source/blender/editors/interface/CMakeLists.txt +++ b/source/blender/editors/interface/CMakeLists.txt @@ -40,6 +40,7 @@ set(SRC interface.c interface_anim.c interface_draw.c + interface_eyedropper.c interface_handlers.c interface_icons.c interface_layout.c diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index e02cdf018c0..3bad2577409 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -611,6 +611,9 @@ static void ui_but_update_linklines(uiBlock *block, uiBut *oldbut, uiBut *newbut static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut **butpp) { + /* flags from the buttons we want to refresh, may want to add more here... */ + const int flag_copy = UI_BUT_REDALERT; + uiBlock *oldblock; uiBut *oldbut, *but = *butpp; int found = 0; @@ -659,6 +662,7 @@ static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut /* drawing */ oldbut->icon = but->icon; oldbut->iconadd = but->iconadd; + oldbut->alignnr = but->alignnr; /* typically the same pointers, but not on undo/redo */ /* XXX some menu buttons store button itself in but->poin. Ugly */ @@ -667,6 +671,8 @@ static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut SWAP(void *, oldbut->func_argN, but->func_argN); } + oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy); + /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position * when scrolling without moving mouse (see [#28432]) */ if (ELEM(oldbut->type, ROW, LISTROW)) @@ -2869,7 +2875,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, } /* keep track of UI_interface.h */ - if (ELEM8(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, BUTM, SCROLL, SEPR)) {} + if (ELEM9(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, BUTM, SCROLL, SEPR)) {} else if (but->type >= SEARCH_MENU) {} else but->flag |= UI_BUT_UNDO; diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index cd845da10c6..11062ea2bd2 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -1389,7 +1389,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc if (scopes->track_disabled) { glColor4f(0.7f, 0.3f, 0.3f, 0.3f); - uiSetRoundBox(15); + uiSetRoundBox(UI_CNR_ALL); uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f); ok = 1; @@ -1437,7 +1437,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc if (scopes->use_track_mask) { glColor4f(0.0f, 0.0f, 0.0f, 0.3f); - uiSetRoundBox(15); + uiSetRoundBox(UI_CNR_ALL); uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f); } @@ -1478,7 +1478,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc if (!ok) { glColor4f(0.f, 0.f, 0.f, 0.3f); - uiSetRoundBox(15); + uiSetRoundBox(UI_CNR_ALL); uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f); } diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c new file mode 100644 index 00000000000..783a777a2fe --- /dev/null +++ b/source/blender/editors/interface/interface_eyedropper.c @@ -0,0 +1,642 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/interface/interface_eyedropper.c + * \ingroup edinterface + */ + +#include "MEM_guardedalloc.h" + +#include "DNA_space_types.h" +#include "DNA_screen_types.h" +#include "DNA_object_types.h" + +#include "BLI_blenlib.h" +#include "BLI_math_vector.h" + +#include "BKE_context.h" +#include "BKE_screen.h" +#include "BKE_report.h" +#include "BKE_idcode.h" + +#include "RNA_access.h" + +#include "BIF_gl.h" + +#include "UI_interface.h" + +#include "IMB_colormanagement.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "interface_intern.h" + +/* for HDR color sampling */ +#include "ED_image.h" +#include "ED_node.h" +#include "ED_clip.h" + +/* for ID data eyedropper */ +#include "ED_space_api.h" +#include "ED_screen.h" +#include "ED_view3d.h" + + +/* -------------------------------------------------------------------- */ +/* Eyedropper + */ + +/** \name Eyedropper (RGB Color) + * \{ */ + +typedef struct Eyedropper { + struct ColorManagedDisplay *display; + + PointerRNA ptr; + PropertyRNA *prop; + int index; + + int accum_start; /* has mouse been presed */ + float accum_col[3]; + int accum_tot; +} Eyedropper; + +static int eyedropper_init(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + Eyedropper *eye; + + op->customdata = eye = MEM_callocN(sizeof(Eyedropper), "Eyedropper"); + + uiContextActiveProperty(C, &eye->ptr, &eye->prop, &eye->index); + + if ((eye->ptr.data == NULL) || + (eye->prop == NULL) || + (RNA_property_editable(&eye->ptr, eye->prop) == FALSE) || + (RNA_property_array_length(&eye->ptr, eye->prop) < 3) || + (RNA_property_type(eye->prop) != PROP_FLOAT)) + { + return FALSE; + } + + if (RNA_property_subtype(eye->prop) == PROP_COLOR) { + const char *display_device; + + display_device = scene->display_settings.display_device; + eye->display = IMB_colormanagement_display_get_named(display_device); + } + + return TRUE; +} + +static void eyedropper_exit(bContext *C, wmOperator *op) +{ + WM_cursor_modal_restore(CTX_wm_window(C)); + + if (op->customdata) { + MEM_freeN(op->customdata); + op->customdata = NULL; + } +} + +static int eyedropper_cancel(bContext *C, wmOperator *op) +{ + eyedropper_exit(C, op); + return OPERATOR_CANCELLED; +} + +/* *** eyedropper_color_ helper functions *** */ + +/** + * \brief get the color from the screen. + * + * Special check for image or nodes where we MAY have HDR pixels which don't display. + */ +static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int mx, int my, float r_col[3]) +{ + + /* we could use some clever */ + wmWindow *win = CTX_wm_window(C); + ScrArea *sa; + for (sa = win->screen->areabase.first; sa; sa = sa->next) { + if (BLI_rcti_isect_pt(&sa->totrct, mx, my)) { + if (sa->spacetype == SPACE_IMAGE) { + ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); + if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) { + SpaceImage *sima = sa->spacedata.first; + int mval[2] = {mx - ar->winrct.xmin, + my - ar->winrct.ymin}; + + if (ED_space_image_color_sample(sima, ar, mval, r_col)) { + return; + } + } + } + else if (sa->spacetype == SPACE_NODE) { + ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); + if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) { + SpaceNode *snode = sa->spacedata.first; + int mval[2] = {mx - ar->winrct.xmin, + my - ar->winrct.ymin}; + + if (ED_space_node_color_sample(snode, ar, mval, r_col)) { + return; + } + } + } + else if (sa->spacetype == SPACE_CLIP) { + ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); + if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) { + SpaceClip *sc = sa->spacedata.first; + int mval[2] = {mx - ar->winrct.xmin, + my - ar->winrct.ymin}; + + if (ED_space_clip_color_sample(sc, ar, mval, r_col)) { + return; + } + } + } + } + } + + /* fallback to simple opengl picker */ + glReadBuffer(GL_FRONT); + glReadPixels(mx, my, 1, 1, GL_RGB, GL_FLOAT, r_col); + glReadBuffer(GL_BACK); +} + +/* sets the sample color RGB, maintaining A */ +static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[3]) +{ + float col_conv[4]; + + /* to maintain alpha */ + RNA_property_float_get_array(&eye->ptr, eye->prop, col_conv); + + /* convert from display space to linear rgb space */ + if (eye->display) { + copy_v3_v3(col_conv, col); + IMB_colormanagement_display_to_scene_linear_v3(col_conv, eye->display); + } + else { + copy_v3_v3(col_conv, col); + } + + RNA_property_float_set_array(&eye->ptr, eye->prop, col_conv); + + RNA_property_update(C, &eye->ptr, eye->prop); +} + +/* set sample from accumulated values */ +static void eyedropper_color_set_accum(bContext *C, Eyedropper *eye) +{ + float col[3]; + mul_v3_v3fl(col, eye->accum_col, 1.0f / (float)eye->accum_tot); + eyedropper_color_set(C, eye, col); +} + +/* single point sample & set */ +static void eyedropper_color_sample(bContext *C, Eyedropper *eye, int mx, int my) +{ + float col[3]; + eyedropper_color_sample_fl(C, eye, mx, my, col); + eyedropper_color_set(C, eye, col); +} + +static void eyedropper_color_sample_accum(bContext *C, Eyedropper *eye, int mx, int my) +{ + float col[3]; + eyedropper_color_sample_fl(C, eye, mx, my, col); + /* delay linear conversion */ + add_v3_v3(eye->accum_col, col); + eye->accum_tot++; +} + +/* main modal status check */ +static int eyedropper_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + Eyedropper *eye = (Eyedropper *)op->customdata; + + switch (event->type) { + case ESCKEY: + case RIGHTMOUSE: + return eyedropper_cancel(C, op); + case LEFTMOUSE: + if (event->val == KM_RELEASE) { + if (eye->accum_tot == 0) { + eyedropper_color_sample(C, eye, event->x, event->y); + } + else { + eyedropper_color_set_accum(C, eye); + } + eyedropper_exit(C, op); + return OPERATOR_FINISHED; + } + else if (event->val == KM_PRESS) { + /* enable accum and make first sample */ + eye->accum_start = TRUE; + eyedropper_color_sample_accum(C, eye, event->x, event->y); + } + break; + case MOUSEMOVE: + if (eye->accum_start) { + /* button is pressed so keep sampling */ + eyedropper_color_sample_accum(C, eye, event->x, event->y); + eyedropper_color_set_accum(C, eye); + } + break; + case SPACEKEY: + if (event->val == KM_RELEASE) { + eye->accum_tot = 0; + zero_v3(eye->accum_col); + eyedropper_color_sample_accum(C, eye, event->x, event->y); + eyedropper_color_set_accum(C, eye); + } + break; + } + + return OPERATOR_RUNNING_MODAL; +} + +/* Modal Operator init */ +static int eyedropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + /* init */ + if (eyedropper_init(C, op)) { + WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR); + + /* add temp handler */ + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; + } + else { + eyedropper_exit(C, op); + return OPERATOR_CANCELLED; + } +} + +/* Repeat operator */ +static int eyedropper_exec(bContext *C, wmOperator *op) +{ + /* init */ + if (eyedropper_init(C, op)) { + + /* do something */ + + /* cleanup */ + eyedropper_exit(C, op); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +static int eyedropper_poll(bContext *C) +{ + if (!CTX_wm_window(C)) return 0; + else return 1; +} + +void UI_OT_eyedropper_color(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Eyedropper"; + ot->idname = "UI_OT_eyedropper_color"; + ot->description = "Sample a color from the Blender Window to store in a property"; + + /* api callbacks */ + ot->invoke = eyedropper_invoke; + ot->modal = eyedropper_modal; + ot->cancel = eyedropper_cancel; + ot->exec = eyedropper_exec; + ot->poll = eyedropper_poll; + + /* flags */ + ot->flag = OPTYPE_BLOCKING; + + /* properties */ +} +/** \} */ + + +/* -------------------------------------------------------------------- */ +/* Data Dropper + * + * note: datadropper is only internal name to avoid confusion in this file + */ + +/** \name Eyedropper (ID data-blocks) + * \{ */ + +typedef struct DataDropper { + PointerRNA ptr; + PropertyRNA *prop; + short idcode; + const char *idcode_name; + + ARegionType *art; + void *draw_handle_pixel; + char name[200]; +} DataDropper; + + +static void datadropper_draw_cb(const struct bContext *C, ARegion *ar, void *arg) +{ + DataDropper *ddr = arg; + int width; + const char *name = ddr->name; + wmWindow *win = CTX_wm_window(C); + int x = win->eventstate->x; + int y = win->eventstate->y; + + if ((name[0] == '\0') || + (BLI_rcti_isect_pt(&ar->winrct, x, y) == false)) + { + return; + } + + width = UI_GetStringWidth(name); + x = x - ar->winrct.xmin; + y = y - ar->winrct.ymin; + + y += 20; + + glColor4ub(0, 0, 0, 50); + + uiSetRoundBox(UI_CNR_ALL | UI_RB_ALPHA); + uiRoundBox(x, y, x + width + 8, y + 15, 4); + + glColor4ub(255, 255, 255, 255); + UI_DrawString(x + 4, y + 4, name); +} + + +static int datadropper_init(bContext *C, wmOperator *op) +{ + DataDropper *ddr; + int index_dummy; + StructRNA *type; + + SpaceType *st; + ARegionType *art; + + st = BKE_spacetype_from_id(SPACE_VIEW3D); + art = BKE_regiontype_from_id(st, RGN_TYPE_WINDOW); + + op->customdata = ddr = MEM_callocN(sizeof(DataDropper), "DataDropper"); + + uiContextActiveProperty(C, &ddr->ptr, &ddr->prop, &index_dummy); + + if ((ddr->ptr.data == NULL) || + (ddr->prop == NULL) || + (RNA_property_editable(&ddr->ptr, ddr->prop) == false) || + (RNA_property_type(ddr->prop) != PROP_POINTER)) + { + return false; + } + + ddr->art = art; + ddr->draw_handle_pixel = ED_region_draw_cb_activate(art, datadropper_draw_cb, ddr, REGION_DRAW_POST_PIXEL); + + type = RNA_property_pointer_type(&ddr->ptr, ddr->prop); + ddr->idcode = RNA_type_to_ID_code(type); + BLI_assert(ddr->idcode != 0); + ddr->idcode_name = BKE_idcode_to_name(ddr->idcode); + + return true; +} + +static void datadropper_exit(bContext *C, wmOperator *op) +{ + WM_cursor_modal_restore(CTX_wm_window(C)); + + if (op->customdata) { + DataDropper *ddr = (DataDropper *)op->customdata; + + ED_region_draw_cb_exit(ddr->art, ddr->draw_handle_pixel); + + MEM_freeN(op->customdata); + + op->customdata = NULL; + } +} + +static int datadropper_cancel(bContext *C, wmOperator *op) +{ + datadropper_exit(C, op); + return OPERATOR_CANCELLED; +} + +/* *** datadropper id helper functions *** */ +/** + * \brief get the ID from the screen. + * + */ +static void datadropper_id_sample_pt(bContext *C, DataDropper *ddr, int mx, int my, ID **r_id) +{ + + /* we could use some clever */ + wmWindow *win = CTX_wm_window(C); + ScrArea *sa; + + ScrArea *area_prev = CTX_wm_area(C); + ARegion *ar_prev = CTX_wm_region(C); + + ddr->name[0] = '\0'; + + for (sa = win->screen->areabase.first; sa; sa = sa->next) { + if (BLI_rcti_isect_pt(&sa->totrct, mx, my)) { + if (sa->spacetype == SPACE_VIEW3D) { + ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); + if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) { + int mval[2] = {mx - ar->winrct.xmin, + my - ar->winrct.ymin}; + Base *base; + + CTX_wm_area_set(C, sa); + CTX_wm_region_set(C, ar); + + /* grr, always draw else we leave stale text */ + ED_region_tag_redraw(ar); + + base = ED_view3d_give_base_under_cursor(C, mval); + if (base) { + Object *ob = base->object; + ID *id = NULL; + if (ddr->idcode == ID_OB) { + id = (ID *)ob; + } + else if (ob->data) { + if (GS(((ID *)ob->data)->name) == ddr->idcode) { + id = (ID *)ob->data; + } + else { + BLI_snprintf(ddr->name, sizeof(ddr->name), "Incompatible, expected a %s", + ddr->idcode_name); + } + } + + if (id) { + BLI_snprintf(ddr->name, sizeof(ddr->name), "%s: %s", + ddr->idcode_name, id->name + 2); + *r_id = id; + } + + break; + } + } + } + } + } + + CTX_wm_area_set(C, area_prev); + CTX_wm_region_set(C, ar_prev); +} + +/* sets the ID, returns success */ +static bool datadropper_id_set(bContext *C, DataDropper *ddr, ID *id) +{ + PointerRNA ptr_value; + + RNA_id_pointer_create(id, &ptr_value); + + RNA_property_pointer_set(&ddr->ptr, ddr->prop, ptr_value); + + RNA_property_update(C, &ddr->ptr, ddr->prop); + + ptr_value = RNA_property_pointer_get(&ddr->ptr, ddr->prop); + + return (ptr_value.id.data == id); +} + +/* single point sample & set */ +static bool datadropper_id_sample(bContext *C, DataDropper *ddr, int mx, int my) +{ + ID *id = NULL; + + datadropper_id_sample_pt(C, ddr, mx, my, &id); + return datadropper_id_set(C, ddr, id); +} + +/* main modal status check */ +static int datadropper_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + DataDropper *ddr = (DataDropper *)op->customdata; + + switch (event->type) { + case ESCKEY: + case RIGHTMOUSE: + return datadropper_cancel(C, op); + case LEFTMOUSE: + if (event->val == KM_RELEASE) { + bool success; + + success = datadropper_id_sample(C, ddr, event->x, event->y); + datadropper_exit(C, op); + + if (success) { + return OPERATOR_FINISHED; + } + else { + BKE_report(op->reports, RPT_WARNING, "Failed to set value"); + return OPERATOR_CANCELLED; + } + } + break; + case MOUSEMOVE: + { + ID *id = NULL; + datadropper_id_sample_pt(C, ddr, event->x, event->y, &id); + break; + } + } + + return OPERATOR_RUNNING_MODAL; +} + +/* Modal Operator init */ +static int datadropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + /* init */ + if (datadropper_init(C, op)) { + WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR); + + /* add temp handler */ + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; + } + else { + datadropper_exit(C, op); + return OPERATOR_CANCELLED; + } +} + +/* Repeat operator */ +static int datadropper_exec(bContext *C, wmOperator *op) +{ + /* init */ + if (datadropper_init(C, op)) { + /* cleanup */ + datadropper_exit(C, op); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +static int datadropper_poll(bContext *C) +{ + if (!CTX_wm_window(C)) return 0; + else return 1; +} + +void UI_OT_eyedropper_id(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Eyedropper Datablock"; + ot->idname = "UI_OT_eyedropper_id"; + ot->description = "Sample a color from the Blender Window to store in a property"; + + /* api callbacks */ + ot->invoke = datadropper_invoke; + ot->modal = datadropper_modal; + ot->cancel = datadropper_cancel; + ot->exec = datadropper_exec; + ot->poll = datadropper_poll; + + /* flags */ + ot->flag = OPTYPE_BLOCKING; + + /* properties */ +} + +/** \} */ diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 5d982b60c91..c5faa99e067 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -2227,8 +2227,16 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle break; case AKEY: + /* Ctrl + A: Select all */ - if (event->ctrl && !(event->alt || event->shift || event->oskey)) { +#if defined(__APPLE__) + /* OSX uses cmd-a systemwide, so add it */ + if ((event->oskey && !(event->alt || event->shift || event->ctrl)) || + (event->ctrl && !(event->alt || event->shift || event->oskey))) +#else + if (event->ctrl && !(event->alt || event->shift || event->oskey)) +#endif + { ui_textedit_move(but, data, STRCUR_DIR_PREV, false, STRCUR_JUMP_ALL); ui_textedit_move(but, data, STRCUR_DIR_NEXT, @@ -2613,7 +2621,10 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton { if (data->state == BUTTON_STATE_HIGHLIGHT) { if (ELEM4(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY) && event->val == KM_PRESS) { - if (but->dt == UI_EMBOSSN && !event->ctrl) { + if (ELEM(event->type, PADENTER, RETKEY) && (!ui_is_but_utf8(but))) { + /* pass - allow filesel, enter to execute */ + } + else if (but->dt == UI_EMBOSSN && !event->ctrl) { /* pass */ } else { @@ -2647,13 +2658,8 @@ static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHa BLI_rcti_rctf_copy(&rect, &but->rect); rect.xmin = rect.xmax - (BLI_rcti_size_y(&rect)); - if ( BLI_rcti_isect_pt(&rect, x, y) ) { - /* most likely NULL, but let's check, and give it temp zero string */ - if (data->str == NULL) - data->str = MEM_callocN(16, "temp str"); - data->str[0] = 0; - - ui_apply_but_TEX(C, but, data); + if (BLI_rcti_isect_pt(&rect, x, y)) { + ui_set_but_string(C, but, ""); button_activate_state(C, but, BUTTON_STATE_EXIT); return WM_UI_HANDLER_BREAK; @@ -3579,31 +3585,6 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co return WM_UI_HANDLER_BREAK; } } - else if (but->type == COLOR) { - if (ELEM3(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) { - float *hsv = ui_block_hsv_get(but->block); - float col[3]; - - ui_get_but_vectorf(but, col); - rgb_to_hsv_compat_v(col, hsv); - - if (event->type == WHEELDOWNMOUSE) - hsv[2] = CLAMPIS(hsv[2] - 0.05f, 0.0f, 1.0f); - else if (event->type == WHEELUPMOUSE) - hsv[2] = CLAMPIS(hsv[2] + 0.05f, 0.0f, 1.0f); - else { - float fac = 0.005 * (event->y - event->prevy); - hsv[2] = CLAMPIS(hsv[2] + fac, 0.0f, 1.0f); - } - - hsv_to_rgb_v(hsv, data->vec); - ui_set_but_vectorf(but, data->vec); - - button_activate_state(C, but, BUTTON_STATE_EXIT); - ui_apply_button(C, but->block, but, data, true); - return WM_UI_HANDLER_BREAK; - } - } } else if (data->state == BUTTON_STATE_WAIT_DRAG) { @@ -3691,6 +3672,41 @@ static bool ui_numedit_but_NORMAL(uiBut *but, uiHandleButtonData *data, int mx, return changed; } +static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event) +{ + if (data->state == BUTTON_STATE_HIGHLIGHT) { + if (ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) { + button_activate_state(C, but, BUTTON_STATE_MENU_OPEN); + return WM_UI_HANDLER_BREAK; + } + else if (ELEM3(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) { + float *hsv = ui_block_hsv_get(but->block); + float col[3]; + + ui_get_but_vectorf(but, col); + rgb_to_hsv_compat_v(col, hsv); + + if (event->type == WHEELDOWNMOUSE) + hsv[2] = CLAMPIS(hsv[2] - 0.05f, 0.0f, 1.0f); + else if (event->type == WHEELUPMOUSE) + hsv[2] = CLAMPIS(hsv[2] + 0.05f, 0.0f, 1.0f); + else { + float fac = 0.005 * (event->y - event->prevy); + hsv[2] = CLAMPIS(hsv[2] + fac, 0.0f, 1.0f); + } + + hsv_to_rgb_v(hsv, data->vec); + ui_set_but_vectorf(but, data->vec); + + button_activate_state(C, but, BUTTON_STATE_EXIT); + ui_apply_button(C, but->block, but, data, true); + return WM_UI_HANDLER_BREAK; + } + } + + return WM_UI_HANDLER_CONTINUE; +} + static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { int mx, my; @@ -5092,7 +5108,12 @@ static bool ui_but_menu(bContext *C, uiBut *but) uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT); if (but->rnapoin.data && but->rnaprop) { - bool is_anim = RNA_property_animateable(&but->rnapoin, but->rnaprop); + PointerRNA *ptr = &but->rnapoin; + PropertyRNA *prop = but->rnaprop; + bool is_anim = RNA_property_animateable(ptr, prop); + bool is_editable = RNA_property_editable(ptr, prop); + /*bool is_idprop = RNA_property_is_idprop(prop);*/ /* XXX does not work as expected, not strictly needed */ + bool is_set = RNA_property_is_set(ptr, prop); /* second slower test, saved people finding keyframe items in menus when its not possible */ if (is_anim) @@ -5239,6 +5260,10 @@ static bool ui_but_menu(bContext *C, uiBut *but) uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Reset to Default Value"), ICON_NONE, "UI_OT_reset_default_button", "all", 1); } + if (is_editable /*&& is_idprop*/ && is_set) { + uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Unset"), + ICON_NONE, "UI_OT_unset_property_button"); + } uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Data Path"), ICON_NONE, "UI_OT_copy_data_path_button"); @@ -5380,6 +5405,28 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * else if (event->type == EVT_DROP) { ui_but_drop(C, event, but, data); } + /* handle eyedropper */ + else if ((event->type == EKEY) && (event->val == KM_PRESS)) { + if (event->alt || event->shift || event->ctrl || event->oskey) { + /* pass */ + } + else { + if (but->type == COLOR) { + WM_operator_name_call(C, "UI_OT_eyedropper_color", WM_OP_INVOKE_DEFAULT, NULL); + return WM_UI_HANDLER_BREAK; + } + else if (but->type == SEARCH_MENU_UNLINK) { + if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_POINTER) { + StructRNA *type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop); + const short idcode = RNA_type_to_ID_code(type); + if ((idcode == ID_OB) || OB_DATA_SUPPORT_ID(idcode)) { + WM_operator_name_call(C, "UI_OT_eyedropper_id", WM_OP_INVOKE_DEFAULT, NULL); + return WM_UI_HANDLER_BREAK; + } + } + } + } + } /* handle keyframing */ else if ((event->type == IKEY) && !ELEM(KM_MOD_FIRST, event->ctrl, event->oskey) && @@ -5525,7 +5572,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * if (but->a1 == UI_GRAD_V_ALT) /* signal to prevent calling up color picker */ retval = ui_do_but_EXIT(C, but, data, event); else - retval = ui_do_but_BLOCK(C, but, data, event); + retval = ui_do_but_COLOR(C, but, data, event); break; case BUT_NORMAL: retval = ui_do_but_NORMAL(C, block, but, data, event); @@ -7719,6 +7766,8 @@ static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata) } else if (temp.cancel_func) temp.cancel_func(C, temp.popup_arg); + + WM_event_add_mousemove(C); } else { /* re-enable tooltips */ diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 6382130cbbd..9cc16d82810 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -584,4 +584,8 @@ int ui_but_anim_expression_set(uiBut *but, const char *str); int ui_but_anim_expression_create(uiBut *but, const char *str); void ui_but_anim_autokey(struct bContext *C, uiBut *but, struct Scene *scene, float cfra); -#endif +/* interface_eyedropper.c */ +void UI_OT_eyedropper_color(struct wmOperatorType *ot); +void UI_OT_eyedropper_id(struct wmOperatorType *ot); + +#endif /* __INTERFACE_INTERN_H__ */ diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 424d2231a03..b453a3b8363 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -505,6 +505,14 @@ static void ui_item_enum_expand_handle(bContext *C, void *arg1, void *arg2) static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, const char *uiname, int h, int icon_only) { + /* XXX The way this function currently handles uiname parameter is insane and inconsistent with general UI API: + * * uiname is the *enum property* label. + * * when it is NULL or empty, we do not draw *enum items* labels, this doubles the icon_only parameter. + * * we *never* draw (i.e. really use) the enum label uiname, it is just used as a mere flag! + * Unfortunately, fixing this implies an API "soft break", so better to defer it for later... :/ + * --mont29 + */ + uiBut *but; EnumPropertyItem *item, *item_array; const char *name; @@ -3091,20 +3099,25 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op, /* set various special settings for buttons */ { + uiBlock *block = uiLayoutGetBlock(layout); + const bool is_popup = (block->flag & UI_BLOCK_KEEP_OPEN) != 0; uiBut *but; + - for (but = uiLayoutGetBlock(layout)->buttons.first; but; but = but->next) { + for (but = block->buttons.first; but; but = but->next) { /* no undo for buttons for operator redo panels */ uiButClearFlag(but, UI_BUT_UNDO); -#if 0 /* broken, causes freedback loop, see [#36109] */ + /* only for popups, see [#36109] */ + /* if button is operator's default property, and a text-field, enable focus for it * - this is used for allowing operators with popups to rename stuff with fewer clicks */ - if ((but->rnaprop == op->type->prop) && (but->type == TEX)) { - uiButSetFocusOnEnter(CTX_wm_window(C), but); + if (is_popup) { + if ((but->rnaprop == op->type->prop) && (but->type == TEX)) { + uiButSetFocusOnEnter(CTX_wm_window(C), but); + } } -#endif } } } diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index d714402de9f..36e965e13d2 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -27,20 +27,14 @@ * \ingroup edinterface */ -#include <stdio.h> -#include <math.h> #include <string.h> #include "MEM_guardedalloc.h" -#include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_text_types.h" /* for UI_OT_reports_to_text */ #include "BLI_blenlib.h" -#include "BLI_math_color.h" -#include "BLI_math_vector.h" -#include "BLI_utildefines.h" #include "BLF_api.h" #include "BLF_translation.h" @@ -54,12 +48,8 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "BIF_gl.h" - #include "UI_interface.h" -#include "IMB_colormanagement.h" - #include "interface_intern.h" #include "WM_api.h" @@ -70,282 +60,6 @@ #include "BKE_main.h" #include "BLI_ghash.h" -#include "ED_image.h" /* for HDR color sampling */ -#include "ED_node.h" /* for HDR color sampling */ -#include "ED_clip.h" /* for HDR color sampling */ - -/* ********************************************************** */ - -typedef struct Eyedropper { - struct ColorManagedDisplay *display; - - PointerRNA ptr; - PropertyRNA *prop; - int index; - - int accum_start; /* has mouse been presed */ - float accum_col[3]; - int accum_tot; -} Eyedropper; - -static int eyedropper_init(bContext *C, wmOperator *op) -{ - Scene *scene = CTX_data_scene(C); - Eyedropper *eye; - - op->customdata = eye = MEM_callocN(sizeof(Eyedropper), "Eyedropper"); - - uiContextActiveProperty(C, &eye->ptr, &eye->prop, &eye->index); - - if ((eye->ptr.data == NULL) || - (eye->prop == NULL) || - (RNA_property_editable(&eye->ptr, eye->prop) == FALSE) || - (RNA_property_array_length(&eye->ptr, eye->prop) < 3) || - (RNA_property_type(eye->prop) != PROP_FLOAT)) - { - return FALSE; - } - - if (RNA_property_subtype(eye->prop) == PROP_COLOR) { - const char *display_device; - - display_device = scene->display_settings.display_device; - eye->display = IMB_colormanagement_display_get_named(display_device); - } - - return TRUE; -} - -static void eyedropper_exit(bContext *C, wmOperator *op) -{ - WM_cursor_modal_restore(CTX_wm_window(C)); - - if (op->customdata) - MEM_freeN(op->customdata); - op->customdata = NULL; -} - -static int eyedropper_cancel(bContext *C, wmOperator *op) -{ - eyedropper_exit(C, op); - return OPERATOR_CANCELLED; -} - -/* *** eyedropper_color_ helper functions *** */ - -/** - * \brief get the color from the screen. - * - * Special check for image or nodes where we MAY have HDR pixels which don't display. - */ -static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int mx, int my, float r_col[3]) -{ - - /* we could use some clever */ - wmWindow *win = CTX_wm_window(C); - ScrArea *sa; - for (sa = win->screen->areabase.first; sa; sa = sa->next) { - if (BLI_rcti_isect_pt(&sa->totrct, mx, my)) { - if (sa->spacetype == SPACE_IMAGE) { - ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); - if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) { - SpaceImage *sima = sa->spacedata.first; - int mval[2] = {mx - ar->winrct.xmin, - my - ar->winrct.ymin}; - - if (ED_space_image_color_sample(sima, ar, mval, r_col)) { - return; - } - } - } - else if (sa->spacetype == SPACE_NODE) { - ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); - if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) { - SpaceNode *snode = sa->spacedata.first; - int mval[2] = {mx - ar->winrct.xmin, - my - ar->winrct.ymin}; - - if (ED_space_node_color_sample(snode, ar, mval, r_col)) { - return; - } - } - } - else if (sa->spacetype == SPACE_CLIP) { - ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); - if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) { - SpaceClip *sc = sa->spacedata.first; - int mval[2] = {mx - ar->winrct.xmin, - my - ar->winrct.ymin}; - - if (ED_space_clip_color_sample(sc, ar, mval, r_col)) { - return; - } - } - } - } - } - - /* fallback to simple opengl picker */ - glReadBuffer(GL_FRONT); - glReadPixels(mx, my, 1, 1, GL_RGB, GL_FLOAT, r_col); - glReadBuffer(GL_BACK); -} - -/* sets the sample color RGB, maintaining A */ -static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[3]) -{ - float col_conv[4]; - - /* to maintain alpha */ - RNA_property_float_get_array(&eye->ptr, eye->prop, col_conv); - - /* convert from display space to linear rgb space */ - if (eye->display) { - copy_v3_v3(col_conv, col); - IMB_colormanagement_display_to_scene_linear_v3(col_conv, eye->display); - } - else { - copy_v3_v3(col_conv, col); - } - - RNA_property_float_set_array(&eye->ptr, eye->prop, col_conv); - - RNA_property_update(C, &eye->ptr, eye->prop); -} - -/* set sample from accumulated values */ -static void eyedropper_color_set_accum(bContext *C, Eyedropper *eye) -{ - float col[3]; - mul_v3_v3fl(col, eye->accum_col, 1.0f / (float)eye->accum_tot); - eyedropper_color_set(C, eye, col); -} - -/* single point sample & set */ -static void eyedropper_color_sample(bContext *C, Eyedropper *eye, int mx, int my) -{ - float col[3]; - eyedropper_color_sample_fl(C, eye, mx, my, col); - eyedropper_color_set(C, eye, col); -} - -static void eyedropper_color_sample_accum(bContext *C, Eyedropper *eye, int mx, int my) -{ - float col[3]; - eyedropper_color_sample_fl(C, eye, mx, my, col); - /* delay linear conversion */ - add_v3_v3(eye->accum_col, col); - eye->accum_tot++; -} - -/* main modal status check */ -static int eyedropper_modal(bContext *C, wmOperator *op, const wmEvent *event) -{ - Eyedropper *eye = (Eyedropper *)op->customdata; - - switch (event->type) { - case ESCKEY: - case RIGHTMOUSE: - return eyedropper_cancel(C, op); - case LEFTMOUSE: - if (event->val == KM_RELEASE) { - if (eye->accum_tot == 0) { - eyedropper_color_sample(C, eye, event->x, event->y); - } - else { - eyedropper_color_set_accum(C, eye); - } - eyedropper_exit(C, op); - return OPERATOR_FINISHED; - } - else if (event->val == KM_PRESS) { - /* enable accum and make first sample */ - eye->accum_start = TRUE; - eyedropper_color_sample_accum(C, eye, event->x, event->y); - } - break; - case MOUSEMOVE: - if (eye->accum_start) { - /* button is pressed so keep sampling */ - eyedropper_color_sample_accum(C, eye, event->x, event->y); - eyedropper_color_set_accum(C, eye); - } - break; - case SPACEKEY: - if (event->val == KM_RELEASE) { - eye->accum_tot = 0; - zero_v3(eye->accum_col); - eyedropper_color_sample_accum(C, eye, event->x, event->y); - eyedropper_color_set_accum(C, eye); - } - break; - } - - return OPERATOR_RUNNING_MODAL; -} - -/* Modal Operator init */ -static int eyedropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - /* init */ - if (eyedropper_init(C, op)) { - WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR); - - /* add temp handler */ - WM_event_add_modal_handler(C, op); - - return OPERATOR_RUNNING_MODAL; - } - else { - eyedropper_exit(C, op); - return OPERATOR_CANCELLED; - } -} - -/* Repeat operator */ -static int eyedropper_exec(bContext *C, wmOperator *op) -{ - /* init */ - if (eyedropper_init(C, op)) { - - /* do something */ - - /* cleanup */ - eyedropper_exit(C, op); - - return OPERATOR_FINISHED; - } - else { - return OPERATOR_CANCELLED; - } -} - -static int eyedropper_poll(bContext *C) -{ - if (!CTX_wm_window(C)) return 0; - else return 1; -} - -static void UI_OT_eyedropper(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Eyedropper"; - ot->idname = "UI_OT_eyedropper"; - ot->description = "Sample a color from the Blender Window to store in a property"; - - /* api callbacks */ - ot->invoke = eyedropper_invoke; - ot->modal = eyedropper_modal; - ot->cancel = eyedropper_cancel; - ot->exec = eyedropper_exec; - ot->poll = eyedropper_poll; - - /* flags */ - ot->flag = OPTYPE_BLOCKING; - - /* properties */ -} - /* Reset Default Theme ------------------------ */ static int reset_default_theme_exec(bContext *C, wmOperator *UNUSED(op)) @@ -434,6 +148,28 @@ static void UI_OT_copy_data_path_button(wmOperatorType *ot) /* Reset to Default Values Button Operator ------------------------ */ +static int operator_button_property_finish(bContext *C, PointerRNA *ptr, PropertyRNA *prop) +{ + ID *id = ptr->id.data; + + /* perform updates required for this property */ + RNA_property_update(C, ptr, prop); + + /* as if we pressed the button */ + uiContextActivePropertyHandle(C); + + /* Since we don't want to undo _all_ edits to settings, eg window + * edits on the screen or on operator settings. + * it might be better to move undo's inline - campbell */ + if (id && ID_CHECK_UNDO(id)) { + /* do nothing, go ahead with undo */ + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + static int reset_default_button_poll(bContext *C) { PointerRNA ptr; @@ -449,7 +185,6 @@ static int reset_default_button_exec(bContext *C, wmOperator *op) { PointerRNA ptr; PropertyRNA *prop; - int success = 0; int index, all = RNA_boolean_get(op->ptr, "all"); /* try to reset the nominated setting to its default value */ @@ -457,32 +192,11 @@ static int reset_default_button_exec(bContext *C, wmOperator *op) /* if there is a valid property that is editable... */ if (ptr.data && prop && RNA_property_editable(&ptr, prop)) { - if (RNA_property_reset(&ptr, prop, (all) ? -1 : index)) { - /* perform updates required for this property */ - RNA_property_update(C, &ptr, prop); - - /* as if we pressed the button */ - uiContextActivePropertyHandle(C); - - success = 1; - } + if (RNA_property_reset(&ptr, prop, (all) ? -1 : index)) + return operator_button_property_finish(C, &ptr, prop); } - /* Since we don't want to undo _all_ edits to settings, eg window - * edits on the screen or on operator settings. - * it might be better to move undo's inline - campbell */ - if (success) { - ID *id = ptr.id.data; - if (id && ID_CHECK_UNDO(id)) { - /* do nothing, go ahead with undo */ - } - else { - return OPERATOR_CANCELLED; - } - } - /* end hack */ - - return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED; + return OPERATOR_CANCELLED; } static void UI_OT_reset_default_button(wmOperatorType *ot) @@ -503,6 +217,43 @@ static void UI_OT_reset_default_button(wmOperatorType *ot) RNA_def_boolean(ot->srna, "all", 1, "All", "Reset to default values all elements of the array"); } +/* Unset Property Button Operator ------------------------ */ + +static int unset_property_button_exec(bContext *C, wmOperator *UNUSED(op)) +{ + PointerRNA ptr; + PropertyRNA *prop; + int index; + + /* try to unset the nominated property */ + uiContextActiveProperty(C, &ptr, &prop, &index); + + /* if there is a valid property that is editable... */ + if (ptr.data && prop && RNA_property_editable(&ptr, prop) + /*&& RNA_property_is_idprop(prop)*/ && RNA_property_is_set(&ptr, prop)) + { + RNA_property_unset(&ptr, prop); + return operator_button_property_finish(C, &ptr, prop); + } + + return OPERATOR_CANCELLED; +} + +static void UI_OT_unset_property_button(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Unset property"; + ot->idname = "UI_OT_unset_property_button"; + ot->description = "Clear the property and use default or generated value in operators"; + + /* callbacks */ + ot->poll = ED_operator_regionactive; + ot->exec = unset_property_button_exec; + + /* flags */ + ot->flag = OPTYPE_UNDO; +} + /* Copy To Selected Operator ------------------------ */ static int copy_to_selected_list(bContext *C, PointerRNA *ptr, ListBase *lb, int *use_path) @@ -1077,10 +828,10 @@ static void UI_OT_reloadtranslation(wmOperatorType *ot) void UI_buttons_operatortypes(void) { - WM_operatortype_append(UI_OT_eyedropper); WM_operatortype_append(UI_OT_reset_default_theme); WM_operatortype_append(UI_OT_copy_data_path_button); WM_operatortype_append(UI_OT_reset_default_button); + WM_operatortype_append(UI_OT_unset_property_button); WM_operatortype_append(UI_OT_copy_to_selected_button); WM_operatortype_append(UI_OT_reports_to_textblock); /* XXX: temp? */ @@ -1089,4 +840,8 @@ void UI_buttons_operatortypes(void) WM_operatortype_append(UI_OT_edittranslation_init); #endif WM_operatortype_append(UI_OT_reloadtranslation); + + /* external */ + WM_operatortype_append(UI_OT_eyedropper_color); + WM_operatortype_append(UI_OT_eyedropper_id); } diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 35741618211..15fbd51c6fc 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -2185,7 +2185,7 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper yco = -3.0f * UI_UNIT_Y; if (show_picker) { - bt = uiDefIconButO(block, BUT, "UI_OT_eyedropper", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth + 10, yco, UI_UNIT_X, UI_UNIT_Y, NULL); + bt = uiDefIconButO(block, BUT, "UI_OT_eyedropper_color", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth + 10, yco, UI_UNIT_X, UI_UNIT_Y, NULL); uiButSetFunc(bt, close_popup_cb, bt, NULL); } diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index bd3103e499e..6b6b7114c84 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -3344,7 +3344,7 @@ static void keymap_item_modified(bContext *UNUSED(C), void *kmi_p, void *UNUSED( static void template_keymap_item_properties(uiLayout *layout, const char *title, PointerRNA *ptr) { - uiLayout *flow; + uiLayout *flow, *box, *row; uiItemS(layout); @@ -3356,6 +3356,8 @@ static void template_keymap_item_properties(uiLayout *layout, const char *title, RNA_STRUCT_BEGIN (ptr, prop) { int flag = RNA_property_flag(prop); + bool is_set = RNA_property_is_set(ptr, prop); + uiBut *but; if (flag & PROP_HIDDEN) continue; @@ -3371,8 +3373,22 @@ static void template_keymap_item_properties(uiLayout *layout, const char *title, } } - /* add property */ - uiItemFullR(flow, ptr, prop, -1, 0, 0, NULL, ICON_NONE); + box = uiLayoutBox(flow); + uiLayoutSetActive(box, is_set); + row = uiLayoutRow(box, false); + + /* property value */ + uiItemFullR(row, ptr, prop, -1, 0, 0, NULL, ICON_NONE); + + if (is_set) { + /* unset operator */ + uiBlock *block = uiLayoutGetBlock(row); + uiBlockSetEmboss(block, UI_EMBOSSN); + but = uiDefIconButO(block, BUT, "UI_OT_unset_property_button", WM_OP_EXEC_DEFAULT, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL); + but->rnapoin = *ptr; + but->rnaprop = prop; + uiBlockSetEmboss(block, UI_EMBOSS); + } } RNA_STRUCT_END; } diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 22c20842723..00113666872 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -1374,14 +1374,16 @@ static void VIEW2D_OT_smoothview(wmOperatorType *ot) { /* identifiers */ ot->name = "Smooth View 2D"; - ot->description = "Zoom in the view to the nearest item contained in the border"; + ot->description = ""; ot->idname = "VIEW2D_OT_smoothview"; /* api callbacks */ ot->invoke = view2d_smoothview_invoke; - ot->poll = view2d_poll; + /* flags */ + ot->flag = OPTYPE_INTERNAL; + /* rna */ WM_operator_properties_gesture_border(ot, FALSE); } diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c index 70fa97bebc1..f50e4400b91 100644 --- a/source/blender/editors/io/io_collada.c +++ b/source/blender/editors/io/io_collada.c @@ -96,7 +96,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) int use_object_instantiation; int sort_by_name; int export_transformation_type; - int second_life; + int open_sim; if (!RNA_struct_property_is_set(op->ptr, "filepath")) { BKE_report(op->reports, RPT_ERROR, "No filename given"); @@ -142,7 +142,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) use_object_instantiation = RNA_boolean_get(op->ptr, "use_object_instantiation"); sort_by_name = RNA_boolean_get(op->ptr, "sort_by_name"); export_transformation_type = RNA_enum_get(op->ptr, "export_transformation_type_selection"); - second_life = RNA_boolean_get(op->ptr, "second_life"); + open_sim = RNA_boolean_get(op->ptr, "open_sim"); /* get editmode results */ ED_object_editmode_load(CTX_data_edit_object(C)); @@ -168,7 +168,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) use_object_instantiation, sort_by_name, export_transformation_type, - second_life)) + open_sim)) { return OPERATOR_FINISHED; } @@ -236,7 +236,7 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr) row = uiLayoutRow(box, FALSE); uiItemR(row, imfptr, "deform_bones_only", 0, NULL, ICON_NONE); row = uiLayoutRow(box, FALSE); - uiItemR(row, imfptr, "second_life", 0, NULL, ICON_NONE); + uiItemR(row, imfptr, "open_sim", 0, NULL, ICON_NONE); /* Collada options: */ box = uiLayoutBox(layout); @@ -350,8 +350,8 @@ void WM_OT_collada_export(wmOperatorType *ot) RNA_def_enum(ot->srna, "export_transformation_type_selection", prop_bc_export_transformation_type, 0, "Transform", "Transformation type for translation, scale and rotation"); - RNA_def_boolean(ot->srna, "second_life", 0, "Export for Second Life", - "Compatibility mode for Second Life"); + RNA_def_boolean(ot->srna, "open_sim", 0, "Export for OpenSim", + "Compatibility mode for OpenSim and compatible online worlds"); } diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index fec4ab87996..50d8e653737 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -35,6 +35,7 @@ #include "BLI_utildefines.h" #include "BLI_math.h" #include "BLI_rect.h" +#include "BLI_task.h" #include "BKE_context.h" #include "BKE_mask.h" @@ -48,6 +49,7 @@ #include "ED_mask.h" /* own include */ #include "ED_space_api.h" #include "BIF_gl.h" +#include "BIF_glutil.h" #include "UI_resources.h" #include "UI_view2d.h" @@ -535,10 +537,93 @@ void ED_mask_draw(const bContext *C, draw_masklays(C, mask, draw_flag, draw_type, width, height); } +typedef struct ThreadedMaskRasterizeState { + MaskRasterHandle *handle; + float *buffer; + int width, height; +} ThreadedMaskRasterizeState; + +typedef struct ThreadedMaskRasterizeData { + int start_scanline; + int num_scanlines; +} ThreadedMaskRasterizeData; + +static void mask_rasterize_func(TaskPool *pool, void *taskdata, int UNUSED(threadid)) +{ + ThreadedMaskRasterizeState *state = (ThreadedMaskRasterizeState *) BLI_task_pool_userdata(pool); + ThreadedMaskRasterizeData *data = (ThreadedMaskRasterizeData *) taskdata; + int scanline; + + for (scanline = 0; scanline < data->num_scanlines; scanline++) { + int x, y = data->start_scanline + scanline; + for (x = 0; x < state->width; x++) { + int index = y * state->width + x; + float xy[2]; + + xy[0] = (float) x / state->width; + xy[1] = (float) y / state->height; + + state->buffer[index] = BKE_maskrasterize_handle_sample(state->handle, xy); + } + } +} + +static float *threaded_mask_rasterize(Mask *mask, const int width, const int height) +{ + TaskScheduler *task_scheduler = BLI_task_scheduler_get(); + TaskPool *task_pool; + MaskRasterHandle *handle; + ThreadedMaskRasterizeState state; + float *buffer; + int i, num_threads = BLI_task_scheduler_num_threads(task_scheduler), scanlines_per_thread; + + buffer = MEM_mallocN(sizeof(float) * height * width, "rasterized mask buffer"); + + /* Initialize rasterization handle. */ + handle = BKE_maskrasterize_handle_new(); + BKE_maskrasterize_handle_init(handle, mask, width, height, TRUE, TRUE, TRUE); + + state.handle = handle; + state.buffer = buffer; + state.width = width; + state.height = height; + + task_pool = BLI_task_pool_create(task_scheduler, &state); + + BLI_begin_threaded_malloc(); + + scanlines_per_thread = height / num_threads; + for (i = 0; i < num_threads; i++) { + ThreadedMaskRasterizeData *data = MEM_mallocN(sizeof(ThreadedMaskRasterizeData), + "threaded mask rasterize data"); + + data->start_scanline = i * scanlines_per_thread; + + if (i < num_threads - 1) { + data->num_scanlines = scanlines_per_thread; + } + else { + data->num_scanlines = height - data->start_scanline; + } + + BLI_task_pool_push(task_pool, mask_rasterize_func, data, true, TASK_PRIORITY_LOW); + } + + /* work and wait until tasks are done */ + BLI_task_pool_work_and_wait(task_pool); + + /* Free memory. */ + BLI_task_pool_free(task_pool); + BLI_end_threaded_malloc(); + BKE_maskrasterize_handle_free(handle); + + return buffer; +} + /* sets up the opengl context. * width, height are to match the values from ED_mask_get_size() */ void ED_mask_draw_region(Mask *mask, ARegion *ar, - const char draw_flag, const char draw_type, + const char draw_flag, const char draw_type, const char overlay_mode, const int width_i, const int height_i, /* convert directly into aspect corrected vars */ const float aspx, const float aspy, const short do_scale_applied, const short do_draw_cb, @@ -592,6 +677,37 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar, yofs = ((width - height) / -2.0f) * zoomy; } + if (draw_flag & MASK_DRAWFLAG_OVERLAY) { + float *buffer = threaded_mask_rasterize(mask, width, height); + int format; + + if (overlay_mode == MASK_OVERLAY_ALPHACHANNEL) { + glColor3f(1.0f, 1.0f, 1.0f); + format = GL_LUMINANCE; + } + else { + /* More blending types could be supported in the future. */ + glEnable(GL_BLEND); + glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA); + format = GL_ALPHA; + } + + glPushMatrix(); + glTranslatef(x, y, 0); + glScalef(zoomx, zoomy, 0); + if (stabmat) { + glMultMatrixf(stabmat); + } + glaDrawPixelsTex(0.0f, 0.0f, width, height, format, GL_FLOAT, GL_NEAREST, buffer); + glPopMatrix(); + + if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) { + glDisable(GL_BLEND); + } + + MEM_freeN(buffer); + } + /* apply transformation so mask editing tools will assume drawing from the origin in normalized space */ glPushMatrix(); glTranslatef(x + xofs, y + yofs, 0); diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index 6033e7ee471..97da0047793 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -64,7 +64,7 @@ typedef struct { float shift_factor; /* The current factor when shift is pressed. Negative when shift not active. */ /* modal only */ - int mcenter[2]; + float mcenter[2]; BMBackup mesh_backup; void *draw_handle_pixel; short twtype; diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c index afafd8458c5..5431b1deb1c 100644 --- a/source/blender/editors/mesh/editmesh_bisect.c +++ b/source/blender/editors/mesh/editmesh_bisect.c @@ -300,7 +300,7 @@ void MESH_OT_bisect(struct wmOperatorType *ot) /* identifiers */ ot->name = "Bisect"; - ot->description = "Enforce symmetry (both form and topological) across an axis"; + ot->description = "Cut geometry along a plane"; ot->idname = "MESH_OT_bisect"; /* api callbacks */ diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c index 300fb67ec80..3df4ad738ae 100644 --- a/source/blender/editors/mesh/editmesh_extrude.c +++ b/source/blender/editors/mesh/editmesh_extrude.c @@ -290,7 +290,7 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op) //BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS, "extrude_face_region geom=%hef", BM_ELEM_SELECT); BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS, "translate vec=%v verts=%hv", - (float *)dvec, BM_ELEM_SELECT); + dvec, BM_ELEM_SELECT); //extrudeflag(obedit, em, SELECT, nor); //translateflag(em, SELECT, dvec); } diff --git a/source/blender/editors/mesh/editmesh_inset.c b/source/blender/editors/mesh/editmesh_inset.c index 3966826a5b2..71822868026 100644 --- a/source/blender/editors/mesh/editmesh_inset.c +++ b/source/blender/editors/mesh/editmesh_inset.c @@ -68,7 +68,7 @@ typedef struct { NumInput num_input; /* modal only */ - int mcenter[2]; + float mcenter[2]; BMBackup mesh_backup; void *draw_handle_pixel; short twtype; diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index ea974fc76f5..9d8b283fe1a 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -628,13 +628,13 @@ static int find_connected_linehit(KnifeTool_OpData *kcd, int testi, BMFace *f, i } if (testfaces) { if (ifaces) - shareface = knife_find_common_face(testfaces, ifaces); + shareface = (knife_find_common_face(testfaces, ifaces) != NULL); else if (iface) - shareface = find_ref(testfaces, iface); + shareface = (find_ref(testfaces, iface) != NULL); } else if (ifaces) { if (testface) - shareface = find_ref(ifaces, testface); + shareface = (find_ref(ifaces, testface) != NULL); } else if (testface && iface) { shareface = (testface == iface); @@ -1233,6 +1233,69 @@ static float len_v3_tri_side_max(const float v1[3], const float v2[3], const flo return sqrtf(max_fff(s1, s2, s3)); } +/** + * given a tri, return 3 planes aligned with the tri's normal. + * + * If the triangle were extruded along its normal, + * the planes calculated would be the 3 sides around the extrusion. + */ +static void plane_from_tri_clip3_v3( + float tri_plane_clip[3][4], + const float v0[3], const float v1[3], const float v2[3]) +{ + float tri_norm[3]; + float tvec[3], cross[3]; + + normal_tri_v3(tri_norm, v0, v1, v2); + + sub_v3_v3v3(tvec, v0, v1); + cross_v3_v3v3(cross, tvec, tri_norm); + plane_from_point_normal_v3(tri_plane_clip[0], v0, cross); + + sub_v3_v3v3(tvec, v1, v2); + cross_v3_v3v3(cross, tvec, tri_norm); + plane_from_point_normal_v3(tri_plane_clip[1], v1, cross); + + sub_v3_v3v3(tvec, v2, v0); + cross_v3_v3v3(cross, tvec, tri_norm); + plane_from_point_normal_v3(tri_plane_clip[2], v2, cross); +} + +/** + * Given a line that is planar with a tri, clip the segment by that tri. + * + * This is needed so we end up with both points in the triangle. + */ +static bool isect_line_tri_coplanar_v3( + const float p1[3], const float p2[3], + const float v0[3], const float v1[3], const float v2[3], + float r_isects[2][3], + + /* avoid re-calculating every time */ + float tri_plane[4], float tri_plane_clip[3][4]) +{ + float p1_tmp[3] = {UNPACK3(p1)}; + float p2_tmp[3] = {UNPACK3(p2)}; + + (void)v0, (void)v1, (void)v2; + + /* first check if the points are planar with the tri */ + if ((fabsf(dist_squared_to_plane_v3(p1, tri_plane)) < KNIFE_FLT_EPS_SQUARED) && + (fabsf(dist_squared_to_plane_v3(p2, tri_plane)) < KNIFE_FLT_EPS_SQUARED) && + /* clip the segment by planes around the triangle so we can be sure the points + * aren't outside the triangle */ + (clip_segment_v3_plane_n(p1_tmp, p2_tmp, tri_plane_clip, 3))) + { + copy_v3_v3(r_isects[0], p1_tmp); + copy_v3_v3(r_isects[1], p2_tmp); + + return true; + } + else { + return false; + } +} + static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree, const float v1[3], const float v2[3], const float v3[3], SmallHash *ehash, bglMats *mats, int *count) @@ -1243,9 +1306,11 @@ static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree, BVHTreeOverlap *results, *result; BMLoop **ls; float cos[9], tri_norm[3], tri_plane[4], isects[2][3], lambda; + float tri_plane_clip[3][4]; unsigned int tot = 0; int i, j, n_isects; + /* for comparing distances, error of intersection depends on triangle scale. * need to scale down before squaring for accurate comparison */ const float depsilon = (FLT_EPSILON / 2.0f) * len_v3_tri_side_max(v1, v2, v3); @@ -1255,8 +1320,10 @@ static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree, copy_v3_v3(cos + 3, v2); copy_v3_v3(cos + 6, v3); + /* avoid re-calculation in #isect_line_tri_coplanar_v3 */ normal_tri_v3(tri_norm, v1, v2, v3); plane_from_point_normal_v3(tri_plane, v1, tri_norm); + plane_from_tri_clip3_v3(tri_plane_clip, v1, v2, v3); BLI_bvhtree_insert(tree2, 0, cos, 3); BLI_bvhtree_balance(tree2); @@ -1282,21 +1349,25 @@ static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree, } n_isects = 0; - if (fabsf(dist_to_plane_v3(kfe->v1->cageco, tri_plane)) < KNIFE_FLT_EPS && - fabsf(dist_to_plane_v3(kfe->v2->cageco, tri_plane)) < KNIFE_FLT_EPS) + + if (isect_line_tri_coplanar_v3(kfe->v1->cageco, kfe->v2->cageco, v1, v2, v3, + isects, + /* cached values */ + tri_plane, tri_plane_clip)) { /* both kfe ends are in cutting triangle */ - copy_v3_v3(isects[0], kfe->v1->cageco); - copy_v3_v3(isects[1], kfe->v2->cageco); n_isects = 2; } - else if (isect_line_tri_epsilon_v3(kfe->v1->cageco, kfe->v2->cageco, v1, v2, v3, &lambda, NULL, depsilon)) { + else if (isect_line_tri_epsilon_v3(kfe->v1->cageco, kfe->v2->cageco, v1, v2, v3, + &lambda, NULL, depsilon)) + { /* kfe intersects cutting triangle lambda of the way along kfe */ interp_v3_v3v3(isects[0], kfe->v1->cageco, kfe->v2->cageco, lambda); n_isects = 1; } + for (j = 0; j < n_isects; j++) { - float p[3], no[3], view[3], sp[2]; + float p[3]; copy_v3_v3(p, isects[j]); if (kcd->curr.vert && len_squared_v3v3(kcd->curr.vert->cageco, p) < depsilon_sq) { @@ -1316,16 +1387,18 @@ static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree, continue; } - knife_project_v2(kcd, p, sp); - ED_view3d_unproject(mats, view, sp[0], sp[1], 0.0f); - mul_m4_v3(kcd->ob->imat, view); - if (kcd->cut_through) { f_hit = NULL; } else { /* check if this point is visible in the viewport */ - float p1[3], lambda1; + float p1[3], no[3], view[3], sp[2]; + float lambda1; + + /* screen projection */ + knife_project_v2(kcd, p, sp); + ED_view3d_unproject(mats, view, sp[0], sp[1], 0.0f); + mul_m4_v3(kcd->ob->imat, view); /* if face isn't planer, p may be behind the current tesselated tri, * so move it onto that and then a little towards eye */ @@ -1473,8 +1546,16 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd) knife_project_v2(kcd, v1, s1); knife_project_v2(kcd, v2, s2); - if (len_squared_v2v2(s1, s2) < 1) - return; + if (kcd->is_interactive) { + if (len_squared_v2v2(s1, s2) < 1.0f) { + return; + } + } + else { + if (len_squared_v2v2(s1, s2) < KNIFE_FLT_EPS_SQUARED) { + return; + } + } /* unproject screen line */ ED_view3d_win_to_segment(kcd->ar, kcd->vc.v3d, s1, v1, v3, true); @@ -2050,7 +2131,7 @@ static void knifenet_fill_faces(KnifeTool_OpData *kcd) facenet_entry *entry; ListBase *face_nets = MEM_callocN(sizeof(ListBase) * bm->totface, "face_nets"); BMFace **faces = MEM_callocN(sizeof(BMFace *) * bm->totface, "faces knife"); - MemArena *arena = BLI_memarena_new(1 << 16, "knifenet_fill_faces"); + MemArena *arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "knifenet_fill_faces"); SmallHash shash; RNG *rng; int i, j, k = 0, totface = bm->totface; @@ -3078,7 +3159,7 @@ static void knifetool_init(bContext *C, KnifeTool_OpData *kcd, (only_select ? BMBVH_RESPECT_SELECT : BMBVH_RESPECT_HIDDEN), kcd->cagecos, false); - kcd->arena = BLI_memarena_new(1 << 15, "knife"); + kcd->arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 15), "knife"); kcd->vthresh = KMAXDIST - 1; kcd->ethresh = KMAXDIST; @@ -3444,7 +3525,7 @@ static bool edbm_mesh_knife_face_isect(ARegion *ar, LinkNode *polys, BMFace *f, while (p) { const float (*mval_fl)[2] = p->link; const int mval_tot = MEM_allocN_len(mval_fl) / sizeof(*mval_fl); - isect += (int)isect_point_poly_v2(cent_ss, mval_fl, mval_tot - 1); + isect += (int)isect_point_poly_v2(cent_ss, mval_fl, mval_tot - 1, false); p = p->next; } diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index 892b773b1ba..ae1007cb98a 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -537,7 +537,8 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event) if (event->val == KM_PRESS) { /* finish */ ED_region_tag_redraw(lcd->ar); - + ED_area_headerprint(CTX_wm_area(C), NULL); + if (lcd->eed) { /* set for redo */ BM_mesh_elem_index_ensure(lcd->em->bm, BM_EDGE); @@ -550,9 +551,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event) else { return ringcut_cancel(C, op); } - - ED_area_headerprint(CTX_wm_area(C), NULL); - + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 806ae96cb61..f975d801d10 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -31,6 +31,7 @@ #include "MEM_guardedalloc.h" +#include "BLI_bitmap.h" #include "BLI_listbase.h" #include "BLI_linklist.h" #include "BLI_linklist_stack.h" @@ -184,55 +185,13 @@ void EDBM_automerge(Scene *scene, Object *obedit, bool update, const char hflag) unsigned int bm_solidoffs = 0, bm_wireoffs = 0, bm_vertoffs = 0; /* set in drawobject.c ... for colorindices */ /* facilities for border select and circle select */ -static char *selbuf = NULL; +static BLI_bitmap *selbuf = NULL; -/* opengl doesn't support concave... */ -static void draw_triangulated(const int mcords[][2], const short tot) +static BLI_bitmap *edbm_backbuf_alloc(const int size) { - ListBase lb = {NULL, NULL}; - DispList *dl; - float *fp; - int a; - const float z_up[3] = {0.0f, 0.0f, 1.0f}; - - /* make displist */ - dl = MEM_callocN(sizeof(DispList), "poly disp"); - dl->type = DL_POLY; - dl->parts = 1; - dl->nr = tot; - dl->verts = fp = MEM_callocN(tot * 3 * sizeof(float), "poly verts"); - BLI_addtail(&lb, dl); - - for (a = 0; a < tot; a++, fp += 3) { - fp[0] = (float)mcords[a][0]; - fp[1] = (float)mcords[a][1]; - } - - /* do the fill */ - BKE_displist_fill(&lb, &lb, z_up, false); - - /* do the draw */ - dl = lb.first; /* filldisplist adds in head of list */ - if (dl->type == DL_INDEX3) { - int *index; - - a = dl->parts; - fp = dl->verts; - index = dl->index; - glBegin(GL_TRIANGLES); - while (a--) { - glVertex3fv(fp + 3 * index[0]); - glVertex3fv(fp + 3 * index[1]); - glVertex3fv(fp + 3 * index[2]); - index += 3; - } - glEnd(); - } - - BKE_displist_free(&lb); + return BLI_BITMAP_NEW(size, "selbuf"); } - /* reads rect, and builds selection array for quick lookup */ /* returns if all is OK */ bool EDBM_backbuf_border_init(ViewContext *vc, short xmin, short ymin, short xmax, short ymax) @@ -252,24 +211,31 @@ bool EDBM_backbuf_border_init(ViewContext *vc, short xmin, short ymin, short xma dr = buf->rect; /* build selection lookup */ - selbuf = MEM_callocN(bm_vertoffs + 1, "selbuf"); + selbuf = edbm_backbuf_alloc(bm_vertoffs + 1); a = (xmax - xmin + 1) * (ymax - ymin + 1); while (a--) { - if (*dr > 0 && *dr <= bm_vertoffs) - selbuf[*dr] = 1; + if (*dr > 0 && *dr <= bm_vertoffs) { + BLI_BITMAP_SET(selbuf, *dr); + } dr++; } IMB_freeImBuf(buf); return true; } -int EDBM_backbuf_check(unsigned int index) +bool EDBM_backbuf_check(unsigned int index) { - if (selbuf == NULL) return 1; + /* odd logic, if selbuf is NULL we assume no zbuf-selection is enabled + * and just ignore the depth buffer, this is error prone since its possible + * code doesn't set the depth buffer by accident, but leave for now. - Campbell */ + if (selbuf == NULL) + return true; + if (index > 0 && index <= bm_vertoffs) - return selbuf[index]; - return 0; + return BLI_BITMAP_GET_BOOL(selbuf, index); + + return false; } void EDBM_backbuf_free(void) @@ -278,6 +244,18 @@ void EDBM_backbuf_free(void) selbuf = NULL; } +struct LassoMaskData { + unsigned int *px; + int width; +}; + +static void edbm_mask_lasso_px_cb(int x, int y, void *user_data) +{ + struct LassoMaskData *data = user_data; + data->px[(y * data->width) + x] = true; +} + + /* mcords is a polygon mask * - grab backbuffer, * - draw with black in backbuffer, @@ -286,9 +264,10 @@ void EDBM_backbuf_free(void) */ bool EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax) { - unsigned int *dr, *drm; - struct ImBuf *buf, *bufmask; + unsigned int *dr, *dr_mask, *dr_mask_arr; + struct ImBuf *buf; int a; + struct LassoMaskData lasso_mask_data; /* method in use for face selecting too */ if (vc->obedit == NULL) { @@ -306,49 +285,27 @@ bool EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short dr = buf->rect; - if (vc->rv3d->gpuoffscreen) - GPU_offscreen_bind(vc->rv3d->gpuoffscreen); - - /* draw the mask */ - glDisable(GL_DEPTH_TEST); - - glColor3ub(0, 0, 0); - - /* yah, opengl doesn't do concave... tsk! */ - ED_region_pixelspace(vc->ar); - draw_triangulated(mcords, tot); - - glBegin(GL_LINE_LOOP); /* for zero sized masks, lines */ - for (a = 0; a < tot; a++) { - glVertex2iv(mcords[a]); - } - glEnd(); - - glFinish(); /* to be sure readpixels sees mask */ - - if (vc->rv3d->gpuoffscreen) - GPU_offscreen_unbind(vc->rv3d->gpuoffscreen); - - /* grab mask */ - bufmask = view3d_read_backbuf(vc, xmin, ymin, xmax, ymax); + dr_mask = dr_mask_arr = MEM_callocN(sizeof(*dr_mask) * buf->x * buf->y, __func__); + lasso_mask_data.px = dr_mask; + lasso_mask_data.width = (xmax - xmin) + 1; - if (bufmask == NULL) { - return false; /* only when mem alloc fails, go crash somewhere else! */ - } - else { - drm = bufmask->rect; - } + fill_poly_v2i_n( + xmin, ymin, xmax + 1, ymax + 1, + mcords, tot, + edbm_mask_lasso_px_cb, &lasso_mask_data); /* build selection lookup */ - selbuf = MEM_callocN(bm_vertoffs + 1, "selbuf"); + selbuf = edbm_backbuf_alloc(bm_vertoffs + 1); a = (xmax - xmin + 1) * (ymax - ymin + 1); while (a--) { - if (*dr > 0 && *dr <= bm_vertoffs && *drm == 0) selbuf[*dr] = 1; - dr++; drm++; + if (*dr > 0 && *dr <= bm_vertoffs && *dr_mask == true) { + BLI_BITMAP_SET(selbuf, *dr); + } + dr++; dr_mask++; } IMB_freeImBuf(buf); - IMB_freeImBuf(bufmask); + MEM_freeN(dr_mask_arr); return true; } @@ -380,12 +337,14 @@ bool EDBM_backbuf_circle_init(ViewContext *vc, short xs, short ys, short rads) dr = buf->rect; /* build selection lookup */ - selbuf = MEM_callocN(bm_vertoffs + 1, "selbuf"); + selbuf = edbm_backbuf_alloc(bm_vertoffs + 1); radsq = rads * rads; for (yc = -rads; yc <= rads; yc++) { for (xc = -rads; xc <= rads; xc++, dr++) { if (xc * xc + yc * yc < radsq) { - if (*dr > 0 && *dr <= bm_vertoffs) selbuf[*dr] = 1; + if (*dr > 0 && *dr <= bm_vertoffs) { + BLI_BITMAP_SET(selbuf, *dr); + } } } } @@ -1897,7 +1856,6 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op) BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; BMIter iter; - BMVert *v; BMEdge *e; BMWalker walker; @@ -1911,8 +1869,7 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op) BMFace *efa; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - BM_elem_flag_set(efa, BM_ELEM_TAG, (BM_elem_flag_test(efa, BM_ELEM_SELECT) && - !BM_elem_flag_test(efa, BM_ELEM_HIDDEN))); + BM_elem_flag_set(efa, BM_ELEM_TAG, BM_elem_flag_test(efa, BM_ELEM_SELECT)); } if (limit) { @@ -1932,6 +1889,7 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op) if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { for (efa = BMW_begin(&walker, efa); efa; efa = BMW_step(&walker)) { BM_face_select_set(bm, efa, true); + BM_elem_flag_disable(efa, BM_ELEM_TAG); } } } @@ -1942,13 +1900,10 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op) } } else { + BMVert *v; + BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { - BM_elem_flag_enable(v, BM_ELEM_TAG); - } - else { - BM_elem_flag_disable(v, BM_ELEM_TAG); - } + BM_elem_flag_set(v, BM_ELEM_TAG, BM_elem_flag_test(v, BM_ELEM_SELECT)); } BMW_init(&walker, em->bm, BMW_SHELL, @@ -1960,6 +1915,7 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op) if (BM_elem_flag_test(v, BM_ELEM_TAG)) { for (e = BMW_begin(&walker, v); e; e = BMW_step(&walker)) { BM_edge_select_set(em->bm, e, true); + BM_elem_flag_disable(e, BM_ELEM_TAG); } } } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index f0e5a64b1bd..9e5782c12f2 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -983,12 +983,6 @@ void MESH_OT_flip_normals(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -static const EnumPropertyItem direction_items[] = { - {false, "CW", 0, "Clockwise", ""}, - {true, "CCW", 0, "Counter Clockwise", ""}, - {0, NULL, 0, NULL, NULL} -}; - /* only accepts 1 selected edge, or 2 selected faces */ static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op) { @@ -3008,7 +3002,7 @@ static int edbm_fill_grid_exec(bContext *C, wmOperator *op) } offset = RNA_property_int_get(op->ptr, prop_offset); - offset = mod_i(offset, clamp); + offset = clamp ? mod_i(offset, clamp) : 0; /* in simple cases, move selection for tags, but also support more advanced cases */ edbm_fill_grid_prepare(em->bm, offset, &span, calc_span); @@ -3342,7 +3336,7 @@ void MESH_OT_dissolve_verts(wmOperatorType *ot) { /* identifiers */ ot->name = "Dissolve Vertices"; - ot->description = "Dissolve geometry"; + ot->description = "Dissolve verts, merge edges and faces"; ot->idname = "MESH_OT_dissolve_verts"; /* api callbacks */ @@ -3379,7 +3373,7 @@ void MESH_OT_dissolve_edges(wmOperatorType *ot) { /* identifiers */ ot->name = "Dissolve Edges"; - ot->description = "Dissolve geometry"; + ot->description = "Dissolve edges, merging faces"; ot->idname = "MESH_OT_dissolve_edges"; /* api callbacks */ @@ -3418,7 +3412,7 @@ void MESH_OT_dissolve_faces(wmOperatorType *ot) { /* identifiers */ ot->name = "Dissolve Faces"; - ot->description = "Dissolve geometry"; + ot->description = "Dissolve faces"; ot->idname = "MESH_OT_dissolve_faces"; /* api callbacks */ @@ -4519,7 +4513,7 @@ void MESH_OT_wireframe(wmOperatorType *ot) /* identifiers */ ot->name = "Wire Frame"; ot->idname = "MESH_OT_wireframe"; - ot->description = "Inset new faces into selected faces"; + ot->description = "Create a solid wire-frame from faces"; /* api callbacks */ ot->exec = edbm_wireframe_exec; @@ -4561,7 +4555,8 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_FACE, BM_ELEM_SELECT, true); + /* Delete unused vertices, edges, and faces */ if (RNA_boolean_get(op->ptr, "delete_unused")) { if (!EDBM_op_callf(em, op, "delete geom=%S context=%i", @@ -4584,9 +4579,11 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op) /* Merge adjacent triangles */ if (RNA_boolean_get(op->ptr, "join_triangles")) { - if (!EDBM_op_callf(em, op, "join_triangles faces=%S limit=%f", - &bmop, "geom.out", - RNA_float_get(op->ptr, "limit"))) + if (!EDBM_op_call_and_selectf(em, op, + "faces.out", true, + "join_triangles faces=%S limit=%f", + &bmop, "geom.out", + RNA_float_get(op->ptr, "limit"))) { EDBM_op_finish(em, &bmop, op, true); return OPERATOR_CANCELLED; diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index a64a23a9f4a..e457f7c45af 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -662,10 +662,7 @@ static void undoMesh_to_editbtMesh(void *umv, void *em_v, void *UNUSED(obdata)) UndoMesh *um = umv; BMesh *bm; - const BMAllocTemplate allocsize = {um->me.totvert, - um->me.totedge, - um->me.totloop, - um->me.totpoly}; + const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(&um->me); ob->shapenr = em->bm->shapenr = um->shapenr; diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index efa619bd10c..5ee980ef5cb 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -314,7 +314,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) /* standard data */ CustomData_merge(&me->vdata, &vdata, CD_MASK_MESH, CD_DEFAULT, totvert); - CustomData_copy_data(&me->vdata, &vdata, 0, vertofs, me->totvert); + CustomData_copy_data_named(&me->vdata, &vdata, 0, vertofs, me->totvert); /* vertex groups */ dvert = CustomData_get(&vdata, vertofs, CD_MDEFORMVERT); @@ -415,7 +415,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) if (me->totedge) { CustomData_merge(&me->edata, &edata, CD_MASK_MESH, CD_DEFAULT, totedge); - CustomData_copy_data(&me->edata, &edata, 0, edgeofs, me->totedge); + CustomData_copy_data_named(&me->edata, &edata, 0, edgeofs, me->totedge); for (a = 0; a < me->totedge; a++, medge++) { medge->v1 += vertofs; @@ -437,7 +437,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) } CustomData_merge(&me->ldata, &ldata, CD_MASK_MESH, CD_DEFAULT, totloop); - CustomData_copy_data(&me->ldata, &ldata, 0, loopofs, me->totloop); + CustomData_copy_data_named(&me->ldata, &ldata, 0, loopofs, me->totloop); for (a = 0; a < me->totloop; a++, mloop++) { mloop->v += vertofs; @@ -461,7 +461,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) } CustomData_merge(&me->pdata, &pdata, CD_MASK_MESH, CD_DEFAULT, totpoly); - CustomData_copy_data(&me->pdata, &pdata, 0, polyofs, me->totpoly); + CustomData_copy_data_named(&me->pdata, &pdata, 0, polyofs, me->totpoly); for (a = 0; a < me->totpoly; a++, mpoly++) { mpoly->loopstart += loopofs; diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 8b674cf1e50..4a8097f260e 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -91,20 +91,24 @@ typedef struct MultiresBakerJobData { struct MultiresBakerJobData *next, *prev; DerivedMesh *lores_dm, *hires_dm; - int simple, lvl, tot_lvl; + bool simple; + int lvl, tot_lvl; ListBase images; } MultiresBakerJobData; /* data passing to multires-baker job */ typedef struct { ListBase data; - int bake_clear, bake_filter; - short mode, use_lores_mesh; - int number_of_rays; - float bias; - int raytrace_structure; - int octree_resolution; - int threads; + bool bake_clear; /* Clear the images before baking */ + int bake_filter; /* Bake-filter, aka margin */ + short mode; /* mode of baking (displacement, normals, AO) */ + bool use_lores_mesh; /* Use low-resolution mesh when baking displacement maps */ + int number_of_rays; /* Number of rays to be cast when doing AO baking */ + float bias; /* Bias between object and start ray point when doing AO baking */ + int raytrace_structure; /* Optimization structure to be used for AO baking */ + int octree_resolution; /* Reslution of octotree when using octotree optimization structure */ + int threads; /* Number of threads to be used for baking */ + float user_scale; /* User scale used to scale displacement when baking derivative map. */ } MultiresBakeJob; static bool multiresbake_check(bContext *C, wmOperator *op) @@ -236,7 +240,7 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l return dm; } -static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *lvl, int *simple) +static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *lvl, bool *simple) { Mesh *me = (Mesh *)ob->data; MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); @@ -253,7 +257,7 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l CustomData_set_only_copy(&cddm->polyData, CD_MASK_BAREMESH); *lvl = mmd->totlvl; - *simple = mmd->simple; + *simple = mmd->simple != 0; tmp_mmd.lvl = mmd->totlvl; tmp_mmd.sculptlvl = mmd->totlvl; @@ -264,40 +268,68 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l } typedef enum ClearFlag { - CLEAR_NORMAL = 1 + CLEAR_TANGENT_NORMAL = 1, + CLEAR_DISPLACEMENT = 2 } ClearFlag; -static void clear_images(MTFace *mtface, int totface, ClearFlag flag) +static void clear_single_image(Image *image, ClearFlag flag) { - int a; const float vec_alpha[4] = {0.0f, 0.0f, 0.0f, 0.0f}; const float vec_solid[4] = {0.0f, 0.0f, 0.0f, 1.0f}; const float nor_alpha[4] = {0.5f, 0.5f, 1.0f, 0.0f}; const float nor_solid[4] = {0.5f, 0.5f, 1.0f, 1.0f}; + const float disp_alpha[4] = {0.5f, 0.5f, 0.5f, 0.0f}; + const float disp_solid[4] = {0.5f, 0.5f, 0.5f, 1.0f}; + + if ((image->id.flag & LIB_DOIT) == 0) { + ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL); + + if (flag == CLEAR_TANGENT_NORMAL) + IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid); + else if (flag == CLEAR_DISPLACEMENT) + IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? disp_alpha : disp_solid); + else + IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid); + + image->id.flag |= LIB_DOIT; - for (a = 0; a < totface; a++) + BKE_image_release_ibuf(image, ibuf, NULL); + } +} + +static void clear_images(MTFace *mtface, int totface, ClearFlag flag) +{ + int a; + + for (a = 0; a < totface; a++) { mtface[a].tpage->id.flag &= ~LIB_DOIT; + } for (a = 0; a < totface; a++) { - Image *ima = mtface[a].tpage; + clear_single_image(mtface[a].tpage, flag); + } - if ((ima->id.flag & LIB_DOIT) == 0) { - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); + for (a = 0; a < totface; a++) { + mtface[a].tpage->id.flag &= ~LIB_DOIT; + } +} - if (flag == CLEAR_NORMAL) - IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid); - else - IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid); +static void clear_images_poly(MTexPoly *mtpoly, int totpoly, ClearFlag flag) +{ + int a; - ima->id.flag |= LIB_DOIT; + for (a = 0; a < totpoly; a++) { + mtpoly[a].tpage->id.flag &= ~LIB_DOIT; + } - BKE_image_release_ibuf(ima, ibuf, NULL); - } + for (a = 0; a < totpoly; a++) { + clear_single_image(mtpoly[a].tpage, flag); } - for (a = 0; a < totface; a++) - mtface[a].tpage->id.flag &= ~LIB_DOIT; + for (a = 0; a < totpoly; a++) { + mtpoly[a].tpage->id.flag &= ~LIB_DOIT; + } } static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) @@ -313,14 +345,20 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { Mesh *me; + ClearFlag clear_flag = 0; ob = base->object; me = (Mesh *)ob->data; - if (scene->r.bake_mode == RE_BAKE_NORMALS && scene->r.bake_normal_space == R_BAKE_SPACE_TANGENT) - clear_images(me->mtface, me->totface, CLEAR_NORMAL); - else - clear_images(me->mtface, me->totface, 0); + if (scene->r.bake_mode == RE_BAKE_NORMALS) { + clear_flag = CLEAR_TANGENT_NORMAL; + } + else if (ELEM(scene->r.bake_mode, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE)) { + clear_flag = CLEAR_DISPLACEMENT; + } + + clear_images(me->mtface, me->totface, clear_flag); + clear_images_poly(me->mtpoly, me->totpoly, clear_flag); } CTX_DATA_END; } @@ -342,6 +380,8 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) bkr.raytrace_structure = scene->r.raytrace_structure; bkr.octree_resolution = scene->r.ocres; bkr.threads = BKE_scene_num_threads(scene); + bkr.user_scale = (scene->r.bake_flag & R_BAKE_USERSCALE) ? scene->r.bake_user_scale : -1.0f; + //bkr.reports= op->reports; /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple); @@ -380,6 +420,8 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj) bkj->raytrace_structure = scene->r.raytrace_structure; bkj->octree_resolution = scene->r.ocres; bkj->threads = BKE_scene_num_threads(scene); + bkj->user_scale = (scene->r.bake_flag & R_BAKE_USERSCALE) ? scene->r.bake_user_scale : -1.0f; + //bkj->reports = op->reports; CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { @@ -414,11 +456,16 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa for (data = bkj->data.first; data; data = data->next) { DerivedMesh *dm = data->lores_dm; MTFace *mtface = CustomData_get_layer(&dm->faceData, CD_MTFACE); + ClearFlag clear_flag = 0; + + if (bkj->mode == RE_BAKE_NORMALS) { + clear_flag = CLEAR_TANGENT_NORMAL; + } + else if (ELEM(bkj->mode, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE)) { + clear_flag = CLEAR_DISPLACEMENT; + } - if (bkj->mode == RE_BAKE_NORMALS) - clear_images(mtface, dm->getNumTessFaces(dm), CLEAR_NORMAL); - else - clear_images(mtface, dm->getNumTessFaces(dm), 0); + clear_images(mtface, dm->getNumTessFaces(dm), clear_flag); } } @@ -429,6 +476,8 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa bkr.bake_filter = bkj->bake_filter; bkr.mode = bkj->mode; bkr.use_lores_mesh = bkj->use_lores_mesh; + bkr.user_scale = bkj->user_scale; + //bkr.reports = bkj->reports; /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ bkr.lores_dm = data->lores_dm; @@ -734,7 +783,7 @@ static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), const static int is_multires_bake(Scene *scene) { - if (ELEM3(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT, RE_BAKE_AO)) + if (ELEM4(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE, RE_BAKE_AO)) return scene->r.bake_flag & R_BAKE_MULTIRES; return 0; diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 96144d13519..bd4c2e997fe 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1471,12 +1471,14 @@ static EnumPropertyItem *object_mode_set_itemsf(bContext *C, PointerRNA *UNUSED( ob = CTX_data_active_object(C); if (ob) { + const bool use_mode_particle_edit = (ob->particlesystem.first != NULL) || (ob->soft != NULL) || + (modifiers_findByType(ob, eModifierType_Cloth) != NULL); while (input->identifier) { if ((input->value == OB_MODE_EDIT && OB_TYPE_SUPPORT_EDITMODE(ob->type)) || (input->value == OB_MODE_POSE && (ob->type == OB_ARMATURE)) || - (input->value == OB_MODE_PARTICLE_EDIT && ob->particlesystem.first) || - ((input->value == OB_MODE_SCULPT || input->value == OB_MODE_VERTEX_PAINT || - input->value == OB_MODE_WEIGHT_PAINT || input->value == OB_MODE_TEXTURE_PAINT) && (ob->type == OB_MESH)) || + (input->value == OB_MODE_PARTICLE_EDIT && use_mode_particle_edit) || + (ELEM4(input->value, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, + OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT) && (ob->type == OB_MESH)) || (input->value == OB_MODE_OBJECT)) { RNA_enum_item_add(&item, &totitem, input); diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c index 1f52346222c..a9fd3ce1288 100644 --- a/source/blender/editors/object/object_group.c +++ b/source/blender/editors/object/object_group.c @@ -289,7 +289,7 @@ void GROUP_OT_objects_remove_all(wmOperatorType *ot) { /* identifiers */ ot->name = "Remove From All Groups"; - ot->description = "Remove selected objects from all groups or a selected group"; + ot->description = "Remove selected objects from all groups"; ot->idname = "GROUP_OT_objects_remove_all"; /* api callbacks */ @@ -335,7 +335,7 @@ void GROUP_OT_objects_remove(wmOperatorType *ot) /* identifiers */ ot->name = "Remove From Group"; - ot->description = "Remove selected objects from all groups or a selected group"; + ot->description = "Remove selected objects from a group"; ot->idname = "GROUP_OT_objects_remove"; /* api callbacks */ diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c index 5b20489c9cb..37656f82b25 100644 --- a/source/blender/editors/object/object_hook.c +++ b/source/blender/editors/object/object_hook.c @@ -569,7 +569,7 @@ void OBJECT_OT_hook_add_selob(wmOperatorType *ot) { /* identifiers */ ot->name = "Hook to Selected Object"; - ot->description = "Hook selected vertices to the first selected Object"; + ot->description = "Hook selected vertices to the first selected object"; ot->idname = "OBJECT_OT_hook_add_selob"; /* api callbacks */ @@ -603,7 +603,7 @@ void OBJECT_OT_hook_add_newob(wmOperatorType *ot) { /* identifiers */ ot->name = "Hook to New Object"; - ot->description = "Hook selected vertices to the first selected Object"; + ot->description = "Hook selected vertices to a newly created object"; ot->idname = "OBJECT_OT_hook_add_newob"; /* api callbacks */ diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 917f816d6b1..d6c365e9247 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -47,6 +47,7 @@ #include "DNA_scene_types.h" #include "DNA_particle_types.h" +#include "BLI_alloca.h" #include "BLI_array.h" #include "BLI_math.h" #include "BLI_blenlib.h" @@ -1480,7 +1481,7 @@ bool *ED_vgroup_subset_from_select_type(Object *ob, eVGroupSelect subset_type, i const int def_nr_active = ob->actdef - 1; vgroup_validmap = MEM_mallocN(*r_vgroup_tot * sizeof(*vgroup_validmap), __func__); memset(vgroup_validmap, false, *r_vgroup_tot * sizeof(*vgroup_validmap)); - if (def_nr_active < *r_vgroup_tot) { + if ((def_nr_active >= 0) && (def_nr_active < *r_vgroup_tot)) { *r_subset_count = 1; vgroup_validmap[def_nr_active] = true; } @@ -2000,7 +2001,11 @@ static void vgroup_levels_subset(Object *ob, const bool *vgroup_validmap, const } } -static void vgroup_normalize_all(Object *ob, const bool lock_active) +static void vgroup_normalize_all(Object *ob, + const bool *vgroup_validmap, + const int vgroup_tot, + const int subset_count, + const bool lock_active) { MDeformVert *dv, **dvert_array = NULL; int i, dvert_tot = 0; @@ -2008,7 +2013,7 @@ static void vgroup_normalize_all(Object *ob, const bool lock_active) const int use_vert_sel = vertex_group_use_vert_sel(ob); - if (lock_active && !BLI_findlink(&ob->defbase, def_nr)) { + if ((lock_active && !BLI_findlink(&ob->defbase, def_nr)) || subset_count == 0) { return; } @@ -2029,13 +2034,15 @@ static void vgroup_normalize_all(Object *ob, const bool lock_active) /* in case its not selected */ if ((dv = dvert_array[i])) { if (lock_flags) { - defvert_normalize_lock_map(dv, lock_flags, defbase_tot); + defvert_normalize_lock_map(dv, vgroup_validmap, vgroup_tot, + lock_flags, defbase_tot); } else if (lock_active) { - defvert_normalize_lock_single(dv, def_nr); + defvert_normalize_lock_single(dv, vgroup_validmap, vgroup_tot, + def_nr); } else { - defvert_normalize(dv); + defvert_normalize_subset(dv, vgroup_validmap, vgroup_tot); } } } @@ -2262,7 +2269,8 @@ static void vgroup_blend_subset(Object *ob, const bool *vgroup_validmap, const i MEM_freeN(emap_mem); } - MEM_freeN(dvert_array); + if (dvert_array) + MEM_freeN(dvert_array); BLI_SMALLSTACK_FREE(dv_stack); /* not so efficient to get 'dvert_array' again just so unselected verts are NULL'd */ @@ -2270,7 +2278,8 @@ static void vgroup_blend_subset(Object *ob, const bool *vgroup_validmap, const i ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, true); ED_vgroup_parray_mirror_sync(ob, dvert_array, dvert_tot, vgroup_validmap, vgroup_tot); - MEM_freeN(dvert_array); + if (dvert_array) + MEM_freeN(dvert_array); } } @@ -3471,8 +3480,13 @@ static int vertex_group_normalize_all_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); bool lock_active = RNA_boolean_get(op->ptr, "lock_active"); + eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); - vgroup_normalize_all(ob, lock_active); + int subset_count, vgroup_tot; + + const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + vgroup_normalize_all(ob, vgroup_validmap, vgroup_tot, subset_count, lock_active); + MEM_freeN((void *)vgroup_validmap); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); @@ -3496,6 +3510,7 @@ void OBJECT_OT_vertex_group_normalize_all(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + vgroup_operator_subset_select_props(ot, false); RNA_def_boolean(ot->srna, "lock_active", true, "Lock Active", "Keep the values of the active group while normalizing others"); } diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 1a561efd217..b0e19d04e35 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -4421,7 +4421,7 @@ static int clear_edited_exec(bContext *C, wmOperator *UNUSED(op)) ParticleSystem *psys = psys_get_current(ob); if (psys->edit) { - if (psys->edit->edited || 1) { // XXX okee("Lose changes done in particle mode?")) + if (psys->edit->edited || 1) { PE_free_ptcache_edit(psys->edit); psys->edit = NULL; @@ -4447,6 +4447,11 @@ static int clear_edited_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } +static int clear_edited_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + return WM_operator_confirm_message(C, op, "Lose changes done in particle mode? (no undo)"); +} + void PARTICLE_OT_edited_clear(wmOperatorType *ot) { /* identifiers */ @@ -4457,6 +4462,7 @@ void PARTICLE_OT_edited_clear(wmOperatorType *ot) /* api callbacks */ ot->exec = clear_edited_exec; ot->poll = particle_edit_toggle_poll; + ot->invoke = clear_edited_invoke; /* flags */ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 0f83316edca..df8d5ec4e84 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -564,6 +564,17 @@ static int screen_render_modal(bContext *C, wmOperator *op, const wmEvent *event return OPERATOR_PASS_THROUGH; } +static int screen_render_cancel(bContext *C, wmOperator *op) +{ + wmWindowManager *wm = CTX_wm_manager(C); + Scene *scene = (Scene *) op->customdata; + + /* kill on cancel, because job is using op->reports */ + WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_RENDER); + + return OPERATOR_CANCELLED; +} + /* using context, starts job */ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *event) { @@ -732,6 +743,7 @@ void RENDER_OT_render(wmOperatorType *ot) /* api callbacks */ ot->invoke = screen_render_invoke; ot->modal = screen_render_modal; + ot->cancel = screen_render_cancel; ot->exec = screen_render_exec; /*ot->poll = ED_operator_screenactive;*/ /* this isn't needed, causes failer in background mode */ @@ -1140,7 +1152,7 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C) /* Try using GLSL display transform. */ if (force_fallback == false) { - if (IMB_colormanagement_setup_glsl_draw(NULL, &scene->display_settings, true, false)) { + if (IMB_colormanagement_setup_glsl_draw(&scene->view_settings, &scene->display_settings, true)) { glEnable(GL_BLEND); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glaDrawPixelsTex(rres.xof, rres.yof, rres.rectx, rres.recty, GL_RGBA, GL_FLOAT, @@ -1158,7 +1170,7 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C) "render_view3d_draw"); IMB_colormanagement_buffer_make_display_space(rres.rectf, display_buffer, rres.rectx, rres.recty, - 4, dither, NULL, &scene->display_settings); + 4, dither, &scene->view_settings, &scene->display_settings); glEnable(GL_BLEND); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index cdebbf4e103..21074bdc47c 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -517,7 +517,7 @@ static int screen_opengl_render_anim_initialize(bContext *C, wmOperator *op) return 1; } -static int screen_opengl_render_anim_step(bContext *C, wmOperator *op) +static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); OGLRender *oglrender = op->customdata; @@ -549,12 +549,9 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op) BKE_makepicstring(name, scene->r.pic, oglrender->bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, TRUE); if ((scene->r.mode & R_NO_OVERWRITE) && BLI_exists(name)) { - printf("skipping existing frame \"%s\"\n", name); - - /* go to next frame */ - oglrender->nfra += scene->r.frame_step; - - return 1; + BKE_reportf(op->reports, RPT_INFO, "Skipping existing frame \"%s\"", name); + ok = true; + goto finally; } } @@ -656,6 +653,9 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op) /* movie stats prints have no line break */ printf("\n"); + +finally: /* Step the frame and bail early if needed */ + /* go to next frame */ oglrender->nfra += scene->r.frame_step; @@ -673,7 +673,7 @@ static int screen_opengl_render_modal(bContext *C, wmOperator *op, const wmEvent { OGLRender *oglrender = op->customdata; int anim = RNA_boolean_get(op->ptr, "animation"); - int ret; + bool ret; switch (event->type) { case ESCKEY: @@ -698,11 +698,12 @@ static int screen_opengl_render_modal(bContext *C, wmOperator *op, const wmEvent screen_opengl_render_end(C, op->customdata); return OPERATOR_FINISHED; } - else + else { ret = screen_opengl_render_anim_step(C, op); + } /* stop at the end or on error */ - if (ret == 0) { + if (ret == false) { return OPERATOR_FINISHED; } @@ -750,7 +751,7 @@ static int screen_opengl_render_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } else { - int ret = 1; + bool ret = true; if (!screen_opengl_render_anim_initialize(C, op)) return OPERATOR_CANCELLED; diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 58c244228ed..553a543390f 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -588,6 +588,20 @@ void SCENE_OT_render_layer_remove(wmOperatorType *ot) #ifdef WITH_FREESTYLE +static bool freestyle_linestyle_check_report(FreestyleLineSet *lineset, ReportList *reports) +{ + if (!lineset) { + BKE_report(reports, RPT_ERROR, "No active lineset and associated line style to add the modifier to"); + return false; + } + if (!lineset->linestyle) { + BKE_report(reports, RPT_ERROR, "The active lineset does not have a line style (indicating data corruption)"); + return false; + } + + return true; +} + static int freestyle_active_module_poll(bContext *C) { PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings); @@ -860,8 +874,13 @@ static int freestyle_linestyle_new_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_ERROR, "No active lineset to add a new line style to"); return OPERATOR_CANCELLED; } - lineset->linestyle->id.us--; - lineset->linestyle = BKE_copy_linestyle(lineset->linestyle); + if (lineset->linestyle) { + lineset->linestyle->id.us--; + lineset->linestyle = BKE_copy_linestyle(lineset->linestyle); + } + else { + lineset->linestyle = BKE_new_linestyle("LineStyle", NULL); + } WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); @@ -890,10 +909,10 @@ static int freestyle_color_modifier_add_exec(bContext *C, wmOperator *op) FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig); int type = RNA_enum_get(op->ptr, "type"); - if (!lineset) { - BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style to add the modifier to"); + if (!freestyle_linestyle_check_report(lineset, op->reports)) { return OPERATOR_CANCELLED; } + if (BKE_add_linestyle_color_modifier(lineset->linestyle, type) == NULL) { BKE_report(op->reports, RPT_ERROR, "Unknown line color modifier type"); return OPERATOR_CANCELLED; @@ -929,10 +948,10 @@ static int freestyle_alpha_modifier_add_exec(bContext *C, wmOperator *op) FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig); int type = RNA_enum_get(op->ptr, "type"); - if (!lineset) { - BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style to add the modifier to"); + if (!freestyle_linestyle_check_report(lineset, op->reports)) { return OPERATOR_CANCELLED; } + if (BKE_add_linestyle_alpha_modifier(lineset->linestyle, type) == NULL) { BKE_report(op->reports, RPT_ERROR, "Unknown alpha transparency modifier type"); return OPERATOR_CANCELLED; @@ -968,10 +987,10 @@ static int freestyle_thickness_modifier_add_exec(bContext *C, wmOperator *op) FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig); int type = RNA_enum_get(op->ptr, "type"); - if (!lineset) { - BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style to add the modifier to"); + if (!freestyle_linestyle_check_report(lineset, op->reports)) { return OPERATOR_CANCELLED; } + if (BKE_add_linestyle_thickness_modifier(lineset->linestyle, type) == NULL) { BKE_report(op->reports, RPT_ERROR, "Unknown line thickness modifier type"); return OPERATOR_CANCELLED; @@ -1007,10 +1026,10 @@ static int freestyle_geometry_modifier_add_exec(bContext *C, wmOperator *op) FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig); int type = RNA_enum_get(op->ptr, "type"); - if (!lineset) { - BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style to add the modifier to"); + if (!freestyle_linestyle_check_report(lineset, op->reports)) { return OPERATOR_CANCELLED; } + if (BKE_add_linestyle_geometry_modifier(lineset->linestyle, type) == NULL) { BKE_report(op->reports, RPT_ERROR, "Unknown stroke geometry modifier type"); return OPERATOR_CANCELLED; @@ -1060,8 +1079,7 @@ static int freestyle_modifier_remove_exec(bContext *C, wmOperator *op) PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier); LineStyleModifier *modifier = ptr.data; - if (!lineset) { - BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style the modifier belongs to"); + if (!freestyle_linestyle_check_report(lineset, op->reports)) { return OPERATOR_CANCELLED; } @@ -1110,8 +1128,7 @@ static int freestyle_modifier_copy_exec(bContext *C, wmOperator *op) PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier); LineStyleModifier *modifier = ptr.data; - if (!lineset) { - BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style the modifier belongs to"); + if (!freestyle_linestyle_check_report(lineset, op->reports)) { return OPERATOR_CANCELLED; } @@ -1161,8 +1178,7 @@ static int freestyle_modifier_move_exec(bContext *C, wmOperator *op) LineStyleModifier *modifier = ptr.data; int dir = RNA_enum_get(op->ptr, "direction"); - if (!lineset) { - BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style the modifier belongs to"); + if (!freestyle_linestyle_check_report(lineset, op->reports)) { return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 91d1985cd00..fccce0357a4 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1446,7 +1446,6 @@ void ED_area_newspace(bContext *C, ScrArea *sa, int type) } if (sl) { - /* swap regions */ slold->regionbase = sa->regionbase; sa->regionbase = sl->regionbase; diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index 13befeceee9..d356c3d8de3 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -531,7 +531,7 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, components = 4; else if (format == GL_RGB) components = 3; - else if (format == GL_LUMINANCE) + else if (ELEM(format, GL_LUMINANCE, GL_ALPHA)) components = 1; else { BLI_assert(!"Incompatible format passed to glaDrawPixelsTexScaled"); @@ -1091,18 +1091,15 @@ void glaDrawImBuf_glsl(ImBuf *ibuf, float x, float y, int zoomfilter, if (ibuf->rect_float) { if (ibuf->float_colorspace) { ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings, - ibuf->float_colorspace, - true, false); + ibuf->float_colorspace, true); } else { - ok = IMB_colormanagement_setup_glsl_draw(view_settings, display_settings, - true, false); + ok = IMB_colormanagement_setup_glsl_draw(view_settings, display_settings, true); } } else { ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings, - ibuf->rect_colorspace, - false, false); + ibuf->rect_colorspace, false); } if (ok) { @@ -1160,57 +1157,3 @@ void glaDrawImBuf_glsl_ctx(const bContext *C, ImBuf *ibuf, float x, float y, int glaDrawImBuf_glsl(ibuf, x, y, zoomfilter, view_settings, display_settings); } - -/* Transform buffer from role to scene linear space using GLSL OCIO conversion - * - * See IMB_colormanagement_setup_transform_from_role_glsl description for - * some more details - * - * NOTE: this only works for RGBA buffers! - */ -int glaBufferTransformFromRole_glsl(float *buffer, int width, int height, int role) -{ - GPUOffScreen *ofs; - char err_out[256]; - rcti display_rect; - - ofs = GPU_offscreen_create(width, height, err_out); - - if (!ofs) - return FALSE; - - GPU_offscreen_bind(ofs); - - if (!IMB_colormanagement_setup_transform_from_role_glsl(role, true)) { - GPU_offscreen_unbind(ofs); - GPU_offscreen_free(ofs); - return FALSE; - } - - BLI_rcti_init(&display_rect, 0, width, 0, height); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - - glaDefine2DArea(&display_rect); - - glaDrawPixelsTex(0, 0, width, height, GL_RGBA, GL_FLOAT, - GL_NEAREST, buffer); - - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - - GPU_offscreen_read_pixels(ofs, GL_FLOAT, buffer); - - IMB_colormanagement_finish_glsl_transform(); - - /* unbind */ - GPU_offscreen_unbind(ofs); - GPU_offscreen_free(ofs); - - return TRUE; -} diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 10c2ecd6fd9..356db174c2f 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1009,8 +1009,6 @@ void ED_screen_do_listen(bContext *C, wmNotifier *note) win->screen->do_draw = TRUE; break; case NC_SCREEN: - if (note->data == ND_SUBWINACTIVE) - uiFreeActiveButtons(C, win->screen); if (note->action == NA_EDITED) win->screen->do_draw = win->screen->do_refresh = TRUE; break; @@ -1335,7 +1333,11 @@ void ED_screen_set_subwinactive(bContext *C, wmEvent *event) /* notifier invokes freeing the buttons... causing a bit too much redraws */ if (oldswin != scr->subwinactive) { region_cursor_set(win, scr->subwinactive, TRUE); - WM_event_add_notifier(C, NC_SCREEN | ND_SUBWINACTIVE, scr); + + /* this used to be a notifier, but needs to be done immediate + * because it can undo setting the right button as active due + * to delayed notifier handling */ + uiFreeActiveButtons(C, win->screen); } else region_cursor_set(win, scr->subwinactive, FALSE); diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c index 584d4cef133..dbe1197436b 100644 --- a/source/blender/editors/screen/screendump.c +++ b/source/blender/editors/screen/screendump.c @@ -77,6 +77,18 @@ typedef struct ScreenshotData { ImageFormatData im_format; } ScreenshotData; +static void screenshot_read_pixels(int x, int y, int w, int h, unsigned char *rect) +{ + int i; + + glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rect); + glFinish(); + + /* clear alpha, it is not set to a meaningful value in opengl */ + for (i = 0, rect += 3; i < w * h; i++, rect += 4) + *rect = 255; +} + /* get shot from frontbuffer */ static unsigned int *screenshot(bContext *C, int *dumpsx, int *dumpsy) { @@ -93,8 +105,7 @@ static unsigned int *screenshot(bContext *C, int *dumpsx, int *dumpsy) dumprect = MEM_mallocN(sizeof(int) * (*dumpsx) * (*dumpsy), "dumprect"); glReadBuffer(GL_FRONT); - glReadPixels(x, y, *dumpsx, *dumpsy, GL_RGBA, GL_UNSIGNED_BYTE, dumprect); - glFinish(); + screenshot_read_pixels(x, y, *dumpsx, *dumpsy, (unsigned char*)dumprect); glReadBuffer(GL_BACK); } @@ -316,8 +327,7 @@ static void screenshot_updatejob(void *sjv) if (sj->dumprect == NULL) { dumprect = MEM_mallocN(sizeof(int) * sj->dumpsx * sj->dumpsy, "dumprect"); - glReadPixels(sj->x, sj->y, sj->dumpsx, sj->dumpsy, GL_RGBA, GL_UNSIGNED_BYTE, dumprect); - glFinish(); + screenshot_read_pixels(sj->x, sj->y, sj->dumpsx, sj->dumpsy, (unsigned char *)dumprect); sj->dumprect = dumprect; } diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index c18afd066fa..56143d00afe 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -73,12 +73,38 @@ typedef struct TexSnapshot { GLuint overlay_texture; int winx; int winy; - bool init; int old_size; float old_zoom; bool old_col; } TexSnapshot; +typedef struct CursorSnapshot { + GLuint overlay_texture; + int size; + int zoom; +} CursorSnapshot; + +static TexSnapshot primary_snap = {0}; +static TexSnapshot secondary_snap = {0}; +static CursorSnapshot cursor_snap = {0}; + +/* delete overlay cursor textures to preserve memory and invalidate all overlay flags */ +void paint_cursor_delete_textures(void) +{ + if (primary_snap.overlay_texture) + glDeleteTextures(1, &primary_snap.overlay_texture); + if (secondary_snap.overlay_texture) + glDeleteTextures(1, &secondary_snap.overlay_texture); + if (cursor_snap.overlay_texture) + glDeleteTextures(1, &cursor_snap.overlay_texture); + + memset(&primary_snap, 0, sizeof(TexSnapshot)); + memset(&secondary_snap, 0, sizeof(TexSnapshot)); + memset(&cursor_snap, 0, sizeof(CursorSnapshot)); + + BKE_paint_invalidate_overlay_all(); +} + static int same_tex_snap(TexSnapshot *snap, MTex *mtex, ViewContext *vc, bool col, float zoom) { return (/* make brush smaller shouldn't cause a resample */ @@ -103,9 +129,7 @@ static void make_tex_snap(TexSnapshot *snap, ViewContext *vc, float zoom) static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool primary) { - static int init = 0; - static TexSnapshot primary_snap = {0}; - static TexSnapshot secondary_snap = {0}; + bool init; TexSnapshot *target; MTex *mtex = (primary) ? &br->mtex : &br->mask_mtex; @@ -120,12 +144,14 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima (overlay_flags & PAINT_INVALID_OVERLAY_TEXTURE_SECONDARY); target = (primary) ? &primary_snap : &secondary_snap; - + refresh = !target->overlay_texture || (invalid != 0) || !same_tex_snap(target, mtex, vc, col, zoom); + init = (target->overlay_texture != 0); + if (refresh) { struct ImagePool *pool = NULL; /* stencil is rotated later */ @@ -160,7 +186,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima target->overlay_texture = 0; } - init = 0; + init = false; target->old_size = size; } @@ -267,7 +293,6 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima if (refresh) { if (!init || (target->old_col != col)) { glTexImage2D(GL_TEXTURE_2D, 0, format, size, size, 0, format, GL_UNSIGNED_BYTE, buffer); - init = 1; } else { glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, format, GL_UNSIGNED_BYTE, buffer); @@ -297,10 +322,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom) { - static GLuint overlay_texture = 0; - static int init = 0; - static int old_size = -1; - static int old_zoom = -1; + bool init; OverlayControlFlags overlay_flags = BKE_paint_get_overlay_flags(); GLubyte *buffer = NULL; @@ -310,14 +332,16 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom) int refresh; refresh = - !overlay_texture || + !cursor_snap.overlay_texture || (overlay_flags & PAINT_INVALID_OVERLAY_CURVE) || - old_zoom != zoom; + cursor_snap.zoom != zoom; + + init = (cursor_snap.overlay_texture != 0); if (refresh) { int s, r; - old_zoom = zoom; + cursor_snap.zoom = zoom; s = BKE_brush_size_get(vc->scene, br); r = 1; @@ -330,18 +354,18 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom) if (size < 256) size = 256; - if (size < old_size) - size = old_size; + if (size < cursor_snap.size) + size = cursor_snap.size; - if (old_size != size) { - if (overlay_texture) { - glDeleteTextures(1, &overlay_texture); - overlay_texture = 0; + if (cursor_snap.size != size) { + if (cursor_snap.overlay_texture) { + glDeleteTextures(1, &cursor_snap.overlay_texture); + cursor_snap.overlay_texture = 0; } - init = 0; + init = false; - old_size = size; + cursor_snap.size = size; } buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex"); @@ -383,19 +407,18 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom) } } - if (!overlay_texture) - glGenTextures(1, &overlay_texture); + if (!cursor_snap.overlay_texture) + glGenTextures(1, &cursor_snap.overlay_texture); } else { - size = old_size; + size = cursor_snap.size; } - glBindTexture(GL_TEXTURE_2D, overlay_texture); + glBindTexture(GL_TEXTURE_2D, cursor_snap.overlay_texture); if (refresh) { if (!init) { glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, size, size, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buffer); - init = 1; } else { glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, GL_ALPHA, GL_UNSIGNED_BYTE, buffer); diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index feff02fa121..a5d4ff98b4b 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -792,6 +792,7 @@ static void toggle_paint_cursor(bContext *C, int enable) if (settings->imapaint.paintcursor && !enable) { WM_paint_cursor_end(wm, settings->imapaint.paintcursor); settings->imapaint.paintcursor = NULL; + paint_cursor_delete_textures(); } else if (enable) paint_cursor_start(C, image_paint_poll); @@ -820,6 +821,9 @@ void ED_space_image_paint_update(wmWindowManager *wm, ToolSettings *settings) paint_cursor_start_explicit(&imapaint->paint, wm, image_paint_poll); } + else { + paint_cursor_delete_textures(); + } } /************************ grab clone operator ************************/ @@ -922,9 +926,15 @@ void PAINT_OT_grab_clone(wmOperatorType *ot) } /******************** sample color operator ********************/ +typedef struct { + bool show_cursor; + short event_type; +} SampleColorData; + static int sample_color_exec(bContext *C, wmOperator *op) { - Brush *brush = image_paint_brush(C); + Paint *paint = BKE_paint_get_active_from_context(C); + Brush *brush = BKE_paint_brush(paint); ARegion *ar = CTX_wm_region(C); int location[2]; @@ -938,11 +948,17 @@ static int sample_color_exec(bContext *C, wmOperator *op) static int sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *event) { + Paint *paint = BKE_paint_get_active_from_context(C); + SampleColorData *data = MEM_mallocN(sizeof(SampleColorData), "sample color custom data"); + + data->event_type = event->type; + data->show_cursor = ((paint->flags & PAINT_SHOW_BRUSH) != 0); + op->customdata = data; + paint->flags &= ~PAINT_SHOW_BRUSH; + RNA_int_set_array(op->ptr, "location", event->mval); sample_color_exec(C, op); - op->customdata = SET_INT_IN_POINTER(event->type); - WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; @@ -950,8 +966,18 @@ static int sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *event static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event) { - if (event->type == (intptr_t)(op->customdata) && event->val == KM_RELEASE) + SampleColorData *data = op->customdata; + + if ((event->type == data->event_type) && (event->val == KM_RELEASE)) { + Paint *paint = BKE_paint_get_active_from_context(C); + + if(data->show_cursor) { + paint->flags |= PAINT_SHOW_BRUSH; + } + + MEM_freeN(data); return OPERATOR_FINISHED; + } switch (event->type) { case MOUSEMOVE: @@ -963,24 +989,9 @@ static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -/* same as image_paint_poll but fail when face mask mode is enabled */ -static int image_paint_sample_color_poll(bContext *C) +static int sample_color_poll(bContext *C) { - if (image_paint_poll(C)) { - if (CTX_wm_view3d(C)) { - Object *obact = CTX_data_active_object(C); - if (obact && obact->mode & OB_MODE_TEXTURE_PAINT) { - Mesh *me = BKE_mesh_from_object(obact); - if (me) { - return !(me->editflag & ME_EDIT_PAINT_FACE_SEL); - } - } - } - - return 1; - } - - return 0; + return (image_paint_poll(C) || vertex_paint_poll(C)); } void PAINT_OT_sample_color(wmOperatorType *ot) @@ -994,7 +1005,7 @@ void PAINT_OT_sample_color(wmOperatorType *ot) ot->exec = sample_color_exec; ot->invoke = sample_color_invoke; ot->modal = sample_color_modal; - ot->poll = image_paint_sample_color_poll; + ot->poll = sample_color_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index c90f9756707..4a2046f6682 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -3129,7 +3129,7 @@ static void project_paint_begin(ProjPaintState *ps) ps->thread_tot = 1; for (a = 0; a < ps->thread_tot; a++) { - ps->arena_mt[a] = BLI_memarena_new(1 << 16, "project paint arena"); + ps->arena_mt[a] = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "project paint arena"); } arena = ps->arena_mt[0]; @@ -3841,10 +3841,10 @@ static void *do_projectpaint_thread(void *ph_v) pos_ofs[0] = pos[0] - lastpos[0]; pos_ofs[1] = pos[1] - lastpos[1]; - smearArena = BLI_memarena_new(1 << 16, "paint smear arena"); + smearArena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "paint smear arena"); } else if (tool == PAINT_TOOL_SOFTEN) { - softenArena = BLI_memarena_new(1 << 16, "paint soften arena"); + softenArena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "paint soften arena"); } /* printf("brush bounds %d %d %d %d\n", bucketMin[0], bucketMin[1], bucketMax[0], bucketMax[1]); */ diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 6c13f6efb74..2545328ec65 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -74,6 +74,7 @@ bool paint_space_stroke_enabled(struct Brush *br, enum PaintMode mode); bool paint_supports_dynamic_size(struct Brush *br, enum PaintMode mode); bool paint_supports_dynamic_tex_coords(struct Brush *br, enum PaintMode mode); bool paint_supports_smooth_stroke(struct Brush *br, enum PaintMode mode); +bool paint_supports_texture(enum PaintMode mode); bool paint_supports_jitter(enum PaintMode mode); struct wmKeyMap *paint_stroke_modal_keymap(struct wmKeyConfig *keyconf); @@ -86,6 +87,7 @@ void paint_stroke_set_mode_data(struct PaintStroke *stroke, void *mode_data); int paint_poll(struct bContext *C); void paint_cursor_start(struct bContext *C, int (*poll)(struct bContext *C)); void paint_cursor_start_explicit(struct Paint *p, struct wmWindowManager *wm, int (*poll)(struct bContext *C)); +void paint_cursor_delete_textures(void); /* paint_vertex.c */ int weight_paint_poll(struct bContext *C); diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 0b0607babc1..8b038973831 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -728,9 +728,16 @@ static int stencil_control_modal(bContext *C, wmOperator *op, const wmEvent *eve static int stencil_control_poll(bContext *C) { - Paint *paint = BKE_paint_get_active_from_context(C); - Brush *br = BKE_paint_brush(paint); + PaintMode mode = BKE_paintmode_get_active_from_context(C); + + Paint *paint; + Brush *br; + + if (!paint_supports_texture(mode)) + return false; + paint = BKE_paint_get_active_from_context(C); + br = BKE_paint_brush(paint); return (br && (br->mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL || br->mask_mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL)); diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 973f6555deb..b00b1c3ecff 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -572,6 +572,12 @@ bool paint_supports_smooth_stroke(Brush *br, PaintMode mode) return true; } +bool paint_supports_texture(PaintMode mode) +{ + /* ommit: PAINT_WEIGHT, PAINT_SCULPT_UV, PAINT_INVALID */ + return ELEM4(mode, PAINT_SCULPT, PAINT_VERTEX, PAINT_TEXTURE_PROJECTIVE, PAINT_TEXTURE_2D); +} + /* return true if the brush size can change during paint (normally used for pressure) */ bool paint_supports_dynamic_tex_coords(Brush *br, PaintMode mode) { diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index d376bd3180f..bfc431baea5 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -441,7 +441,7 @@ static int paint_select_linked_pick_invoke(bContext *C, wmOperator *op, const wm void PAINT_OT_face_select_linked_pick(wmOperatorType *ot) { ot->name = "Select Linked Pick"; - ot->description = "Select linked faces"; + ot->description = "Select linked faces under the cursor"; ot->idname = "PAINT_OT_face_select_linked_pick"; ot->invoke = paint_select_linked_pick_invoke; diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 538e8394b1f..1c3caf5d8bc 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -2062,6 +2062,8 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op) /* weight paint spesific */ mesh_octree_table(NULL, NULL, NULL, 'e'); mesh_mirrtopo_table(NULL, 'e'); + + paint_cursor_delete_textures(); } else { ob->mode |= mode_flag; @@ -2684,6 +2686,8 @@ static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op) if (me->editflag & ME_EDIT_PAINT_FACE_SEL) { BKE_mesh_flush_select_from_polys(me); } + + paint_cursor_delete_textures(); } else { ob->mode |= mode_flag; @@ -2784,7 +2788,7 @@ static void vpaint_build_poly_facemap(struct VPaintData *vd, Mesh *me) int *origIndex; int i; - vd->polyfacemap_arena = BLI_memarena_new(1 << 13, "vpaint tmp"); + vd->polyfacemap_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "vpaint tmp"); BLI_memarena_use_calloc(vd->polyfacemap_arena); vd->polyfacemap = BLI_memarena_alloc(vd->polyfacemap_arena, sizeof(ListBase) * me->totpoly); @@ -3480,7 +3484,7 @@ void PAINT_OT_weight_gradient(wmOperatorType *ot) /* identifiers */ ot->name = "Weight Gradient"; ot->idname = "PAINT_OT_weight_gradient"; - ot->description = "Sample a line and show it in Scope panels"; + ot->description = "Draw a line to apply a weight gradient to selected vertices"; /* api callbacks */ ot->invoke = paint_weight_gradient_invoke; diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index a557afcdf3d..2a6b6d4b3d9 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -3795,15 +3795,26 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio Object *ob = CTX_data_active_object(C); float mat[3][3]; float viewDir[3] = {0.0f, 0.0f, 1.0f}; + float max_scale; int i; int mode; ss->cache = cache; /* Set scaling adjustment */ - cache->scale[0] = 1.0f / ob->size[0]; - cache->scale[1] = 1.0f / ob->size[1]; - cache->scale[2] = 1.0f / ob->size[2]; + if (brush->sculpt_tool == SCULPT_TOOL_LAYER) { + max_scale = 1.0f; + } + else { + max_scale = 0.0f; + for (i = 0; i < 3; i ++) { + max_scale = max_ff(max_scale, fabsf(ob->size[i])); + } + } + cache->scale[0] = max_scale / ob->size[0]; + cache->scale[1] = max_scale / ob->size[1]; + cache->scale[2] = max_scale / ob->size[2]; + cache->plane_trim_squared = brush->plane_trim * brush->plane_trim; @@ -4677,10 +4688,7 @@ void sculpt_dynamic_topology_enable(bContext *C) Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; Mesh *me = ob->data; - const BMAllocTemplate allocsize = {me->totvert, - me->totedge, - me->totloop, - me->totpoly}; + const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(me); sculpt_pbvh_clear(ob); @@ -4931,7 +4939,7 @@ int ED_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd) if (mmd && !CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK)) { GridPaintMask *gmask; int level = max_ii(1, mmd->sculptlvl); - int gridsize = ccg_gridsize(level); + int gridsize = BKE_ccg_gridsize(level); int gridarea = gridsize * gridsize; int i, j; @@ -5031,6 +5039,8 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) ob->mode &= ~mode_flag; free_sculptsession(ob); + + paint_cursor_delete_textures(); } else { /* Enter sculptmode */ diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c index d630b6478fb..7a973d8c1ae 100644 --- a/source/blender/editors/sculpt_paint/sculpt_uv.c +++ b/source/blender/editors/sculpt_paint/sculpt_uv.c @@ -45,6 +45,7 @@ #include "BKE_brush.h" #include "BKE_paint.h" +#include "BKE_colortools.h" #include "BKE_context.h" #include "BKE_main.h" #include "BKE_depsgraph.h" @@ -538,6 +539,8 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm op->customdata = data; + curvemapping_initialize(ts->uvsculpt->paint.brush->curve); + if (data) { int counter = 0, i; ARegion *ar = CTX_wm_region(C); diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 0d64a3ce594..f5db34d87d7 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -710,8 +710,14 @@ static unsigned char *prefetch_thread_next_frame(PrefetchQueue *queue, MovieClip if (queue->direction > 0) { current_frame = prefetch_find_uncached_frame(clip, queue->current_frame + 1, queue->end_frame, queue->render_size, queue->render_flag, 1); + /* switch direction if read frames from current up to scene end frames */ + if (current_frame >= queue->end_frame) { + queue->current_frame = queue->initial_frame; + queue->direction = -1; + } } - else { + + if (queue->direction < 0) { current_frame = prefetch_find_uncached_frame(clip, queue->current_frame - 1, queue->start_frame, queue->render_size, queue->render_flag, -1); } @@ -736,12 +742,6 @@ static unsigned char *prefetch_thread_next_frame(PrefetchQueue *queue, MovieClip *queue->do_update = 1; *queue->progress = (float)frames_processed / (queue->end_frame - queue->start_frame); - - /* switch direction if read frames from current up to scene end frames */ - if (current_frame == queue->end_frame) { - queue->current_frame = queue->initial_frame; - queue->direction = -1; - } } } BLI_spin_unlock(&queue->spin); diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 3ede63adb72..adc902bf4ba 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -1191,7 +1191,9 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar) int mask_width, mask_height; ED_mask_get_size(sa, &mask_width, &mask_height); ED_mask_draw_region(mask, ar, - sc->mask_info.draw_flag, sc->mask_info.draw_type, + sc->mask_info.draw_flag, + sc->mask_info.draw_type, + sc->mask_info.overlay_mode, mask_width, mask_height, aspx, aspy, TRUE, TRUE, diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 7a6546053cd..246ea7fe140 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -2405,7 +2405,7 @@ static int set_axis_exec(bContext *C, wmOperator *op) track = tracksbase->first; while (track) { - if (TRACK_VIEW_SELECTED(sc, track)) + if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_HAS_BUNDLE)) break; track = track->next; diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index c10ea96096f..289986d7fba 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -681,6 +681,7 @@ static int console_clear_exec(bContext *C, wmOperator *op) if (history) { while (sc->history.first) console_history_free(sc, sc->history.first); + console_history_verify(C); } console_textview_update_rect(sc, ar); diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index 88a04197847..5c8d1e84fd5 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -317,6 +317,7 @@ static void console_keymap(struct wmKeyConfig *keyconf) RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", BACKSPACEKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_PREV_WORD); WM_keymap_add_item(keymap, "CONSOLE_OT_clear_line", RETKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "CONSOLE_OT_clear_line", PADENTER, KM_PRESS, KM_SHIFT, 0); #ifdef WITH_PYTHON kmi = WM_keymap_add_item(keymap, "CONSOLE_OT_execute", RETKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/space_file/CMakeLists.txt b/source/blender/editors/space_file/CMakeLists.txt index b30f008e1bf..ce0b08c6708 100644 --- a/source/blender/editors/space_file/CMakeLists.txt +++ b/source/blender/editors/space_file/CMakeLists.txt @@ -58,6 +58,10 @@ if(WITH_IMAGE_OPENEXR) add_definitions(-DWITH_OPENEXR) endif() +if(WITH_IMAGE_OPENIMAGEIO) + add_definitions(-DWITH_OPENIMAGEIO) +endif() + if(WITH_IMAGE_TIFF) add_definitions(-DWITH_TIFF) endif() diff --git a/source/blender/editors/space_file/SConscript b/source/blender/editors/space_file/SConscript index e1eadb66a11..d42394454eb 100644 --- a/source/blender/editors/space_file/SConscript +++ b/source/blender/editors/space_file/SConscript @@ -55,6 +55,9 @@ if env['WITH_BF_OPENEXR']: if env['WITH_BF_TIFF']: defs.append('WITH_TIFF') +if env['WITH_BF_OIIO']: + defs.append('WITH_OPENIMAGEIO') + if env['WITH_BF_INTERNATIONAL']: defs.append('WITH_INTERNATIONAL') diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h index 240106d37d5..d01286442be 100644 --- a/source/blender/editors/space_file/file_intern.h +++ b/source/blender/editors/space_file/file_intern.h @@ -65,7 +65,7 @@ void FILE_OT_select_all_toggle(struct wmOperatorType *ot); void FILE_OT_select_border(struct wmOperatorType *ot); void FILE_OT_select_bookmark(struct wmOperatorType *ot); void FILE_OT_bookmark_add(struct wmOperatorType *ot); -void FILE_OT_delete_bookmark(struct wmOperatorType *ot); +void FILE_OT_bookmark_delete(struct wmOperatorType *ot); void FILE_OT_reset_recent(wmOperatorType *ot); void FILE_OT_hidedot(struct wmOperatorType *ot); void FILE_OT_execute(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index e3270d9ce8e..a97b3b1d719 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -503,14 +503,14 @@ static int bookmark_delete_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void FILE_OT_delete_bookmark(wmOperatorType *ot) +void FILE_OT_bookmark_delete(wmOperatorType *ot) { PropertyRNA *prop; /* identifiers */ ot->name = "Delete Bookmark"; ot->description = "Delete selected bookmark"; - ot->idname = "FILE_OT_delete_bookmark"; + ot->idname = "FILE_OT_bookmark_delete"; /* api callbacks */ ot->exec = bookmark_delete_exec; diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c index 0efc7b927a9..f4161c7da1c 100644 --- a/source/blender/editors/space_file/file_panels.c +++ b/source/blender/editors/space_file/file_panels.c @@ -121,7 +121,7 @@ static void file_panel_category(const bContext *C, Panel *pa, FSMenuCategory cat /* create delete button */ if (allow_delete && fsmenu_can_save(fsmenu, category, i)) { uiBlockSetEmboss(block, UI_EMBOSSN); - uiItemIntO(layout, "", ICON_X, "FILE_OT_delete_bookmark", "index", i); + uiItemIntO(layout, "", ICON_X, "FILE_OT_bookmark_delete", "index", i); uiBlockSetEmboss(block, UI_EMBOSS); } } diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 9758e2e9135..1a8565a58b1 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -387,7 +387,7 @@ static void file_operatortypes(void) WM_operatortype_append(FILE_OT_refresh); WM_operatortype_append(FILE_OT_bookmark_toggle); WM_operatortype_append(FILE_OT_bookmark_add); - WM_operatortype_append(FILE_OT_delete_bookmark); + WM_operatortype_append(FILE_OT_bookmark_delete); WM_operatortype_append(FILE_OT_reset_recent); WM_operatortype_append(FILE_OT_hidedot); WM_operatortype_append(FILE_OT_filenum); diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index 7610f7a9192..23c39a5e99a 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -951,7 +951,7 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid /* 1) draw curve line */ { /* set color/drawing style for curve itself */ - if (((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) || (fcu->flag & FCURVE_PROTECTED)) { + if (BKE_fcurve_is_protected(fcu)) { /* protected curves (non editable) are drawn with dotted lines */ setlinestyle(2); } diff --git a/source/blender/editors/space_image/CMakeLists.txt b/source/blender/editors/space_image/CMakeLists.txt index 6509af179e7..2f78818d012 100644 --- a/source/blender/editors/space_image/CMakeLists.txt +++ b/source/blender/editors/space_image/CMakeLists.txt @@ -50,6 +50,10 @@ if(WITH_INTERNATIONAL) add_definitions(-DWITH_INTERNATIONAL) endif() +if(WITH_IMAGE_OPENIMAGEIO) + add_definitions(-DWITH_OPENIMAGEIO) +endif() + if(WITH_IMAGE_OPENJPEG) add_definitions(-DWITH_OPENJPEG) endif() diff --git a/source/blender/editors/space_image/SConscript b/source/blender/editors/space_image/SConscript index 268172b300d..89def32e70f 100644 --- a/source/blender/editors/space_image/SConscript +++ b/source/blender/editors/space_image/SConscript @@ -57,6 +57,8 @@ if env['WITH_BF_TIFF']: defs.append('WITH_TIFF') if env['WITH_BF_CINEON']: defs.append('WITH_CINEON') +if env['WITH_BF_OIIO']: + defs.append('WITH_OPENIMAGEIO') if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'): incs += ' ' + env['BF_PTHREADS_INC'] diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 144d2c14e9f..3ff404d38a9 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -640,7 +640,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char else uiItemO(row, "", ICON_UGLYPACKAGE, "image.pack"); - row = uiLayoutRow(row, FALSE); + row = uiLayoutRow(row, TRUE); uiLayoutSetEnabled(row, ima->packedfile == NULL); uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE); uiItemO(row, "", ICON_FILE_REFRESH, "image.reload"); diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 23c85699b00..89e57955339 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -268,8 +268,6 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def else rgba[3] = linearcol[3]; - (void)color_manage; - if (use_default_view) IMB_colormanagement_pixel_to_display_space_v4(rgba, rgba, NULL, &scene->display_settings); else @@ -360,14 +358,8 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def dx += BLF_width(blf_mono_font, str); } else if (channels >= 3) { - if (fp) { - rgb_to_hsv(fp[0], fp[1], fp[2], &hue, &sat, &val); - rgb_to_yuv(fp[0], fp[1], fp[2], &lum, &u, &v); - } - else if (cp) { - rgb_to_hsv((float)cp[0] / 255.0f, (float)cp[1] / 255.0f, (float)cp[2] / 255.0f, &hue, &sat, &val); - rgb_to_yuv((float)cp[0] / 255.0f, (float)cp[1] / 255.0f, (float)cp[2] / 255.0f, &lum, &u, &v); - } + rgb_to_hsv(finalcol[0], finalcol[1], finalcol[2], &hue, &sat, &val); + rgb_to_yuv(finalcol[0], finalcol[1], finalcol[2], &lum, &u, &v); BLI_snprintf(str, sizeof(str), "H:%-.4f", hue); BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index cbd3917cacb..710d5c8cd81 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1804,6 +1804,8 @@ static int image_new_exec(bContext *C, wmOperator *op) BKE_image_signal(ima, (sima) ? &sima->iuser : NULL, IMA_SIGNAL_USER_NEW_IMAGE); + WM_event_add_notifier(C, NC_IMAGE | NA_ADDED, ima); + return OPERATOR_FINISHED; } @@ -2415,6 +2417,9 @@ static int image_sample_line_exec(bContext *C, wmOperator *op) hist->co[1][0] = x2f; hist->co[1][1] = y2f; + /* enable line drawing */ + hist->flag |= HISTO_FLAG_SAMPLELINE; + BKE_histogram_update_sample_line(hist, ibuf, &scene->view_settings, &scene->display_settings); /* reset y zoom */ diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 5a8292abcab..7b20af340ae 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -674,7 +674,6 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) } else if (sima->mode == SI_MODE_MASK) { mask = ED_space_image_get_mask(sima); - draw_image_cursor(ar, sima->cursor); } ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); @@ -715,7 +714,9 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) BLI_unlock_thread(LOCK_DRAW_IMAGE); ED_mask_draw_region(mask, ar, - sima->mask_info.draw_flag, sima->mask_info.draw_type, + sima->mask_info.draw_flag, + sima->mask_info.draw_type, + sima->mask_info.overlay_mode, width, height, aspx, aspy, TRUE, FALSE, @@ -723,7 +724,9 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) ED_mask_draw_frames(mask, ar, CFRA, mask->sfra, mask->efra); + UI_view2d_view_ortho(v2d); draw_image_cursor(ar, sima->cursor); + UI_view2d_view_restore(C); } /* scrollers? */ diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c index c1cddf092aa..9686c6dfc29 100644 --- a/source/blender/editors/space_info/info_stats.c +++ b/source/blender/editors/space_info/info_stats.c @@ -194,9 +194,9 @@ static void stats_object_edit(Object *obedit, SceneStats *stats) a = nu->pntsu; while (a--) { stats->totvert += 3; - if (bezt->f1) stats->totvertsel++; - if (bezt->f2) stats->totvertsel++; - if (bezt->f3) stats->totvertsel++; + if (bezt->f1 & SELECT) stats->totvertsel++; + if (bezt->f2 & SELECT) stats->totvertsel++; + if (bezt->f3 & SELECT) stats->totvertsel++; bezt++; } } diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 45428425138..ba28f502349 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -86,18 +86,6 @@ static void node_socket_button_label(bContext *UNUSED(C), uiLayout *layout, Poin uiItemL(layout, text, 0); } -static void node_draw_input_default(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *node_ptr) -{ - bNodeSocket *sock = (bNodeSocket *)ptr->data; - sock->typeinfo->draw(C, layout, ptr, node_ptr, IFACE_(sock->name)); -} - -static void node_draw_output_default(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *node_ptr) -{ - bNodeSocket *sock = ptr->data; - node_socket_button_label(C, layout, ptr, node_ptr, IFACE_(sock->name)); -} - /* ****************** BASE DRAW FUNCTIONS FOR NEW OPERATOR NODES ***************** */ @@ -339,7 +327,7 @@ static int node_resize_area_default(bNode *node, int x, int y) /* ****************** BUTTON CALLBACKS FOR COMMON NODES ***************** */ -static void node_uifunc_group(uiLayout *layout, bContext *C, PointerRNA *ptr) +static void node_draw_buttons_group(uiLayout *layout, bContext *C, PointerRNA *ptr) { uiTemplateIDBrowse(layout, C, ptr, "node_tree", NULL, NULL, NULL); } @@ -348,7 +336,7 @@ static void node_uifunc_group(uiLayout *layout, bContext *C, PointerRNA *ptr) * Not ideal to do this in every draw call, but doing as transform callback doesn't work, * since the child node totr rects are not updated properly at that point. */ -static void node_update_frame(const bContext *UNUSED(C), bNodeTree *ntree, bNode *node) +static void node_draw_frame_prepare(const bContext *UNUSED(C), bNodeTree *ntree, bNode *node) { const float margin = 1.5f * U.widget_unit; NodeFrame *data = (NodeFrame *)node->storage; @@ -511,7 +499,7 @@ static int node_resize_area_frame(bNode *node, int x, int y) return dir; } -static void node_buts_frame_details(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +static void node_buts_frame_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiItemR(layout, ptr, "label_size", 0, IFACE_("Label Size"), ICON_NONE); uiItemR(layout, ptr, "shrink", 0, IFACE_("Shrink"), ICON_NONE); @@ -520,7 +508,7 @@ static void node_buts_frame_details(uiLayout *layout, bContext *UNUSED(C), Point #define NODE_REROUTE_SIZE 8.0f -static void node_update_reroute(const bContext *UNUSED(C), bNodeTree *UNUSED(ntree), bNode *node) +static void node_draw_reroute_prepare(const bContext *UNUSED(C), bNodeTree *UNUSED(ntree), bNode *node) { bNodeSocket *nsock; float locx, locy; @@ -571,7 +559,7 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED( */ #if 0 /* body */ - uiSetRoundBox(15); + uiSetRoundBox(UI_CNR_ALL); UI_ThemeColor4(TH_NODE); glEnable(GL_BLEND); uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, size); @@ -632,17 +620,17 @@ static void node_common_set_butfunc(bNodeType *ntype) { switch (ntype->type) { case NODE_GROUP: - ntype->uifunc = node_uifunc_group; + ntype->draw_buttons = node_draw_buttons_group; break; case NODE_FRAME: - ntype->drawfunc = node_draw_frame; - ntype->drawupdatefunc = node_update_frame; - ntype->uifuncbut = node_buts_frame_details; + ntype->draw_nodetype = node_draw_frame; + ntype->draw_nodetype_prepare = node_draw_frame_prepare; + ntype->draw_buttons_ex = node_buts_frame_ex; ntype->resize_area_func = node_resize_area_frame; break; case NODE_REROUTE: - ntype->drawfunc = node_draw_reroute; - ntype->drawupdatefunc = node_update_reroute; + ntype->draw_nodetype = node_draw_reroute; + ntype->draw_nodetype_prepare = node_draw_reroute_prepare; ntype->tweak_area_func = node_tweak_area_reroute; break; } @@ -709,6 +697,8 @@ static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), Poin { uiLayout *row; + uiItemR(layout, ptr, "vector_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + uiItemL(layout, IFACE_("Location:"), ICON_NONE); row = uiLayoutRow(layout, TRUE); uiItemR(row, ptr, "translation", 0, "", ICON_NONE); @@ -737,7 +727,7 @@ static void node_shader_buts_vect_math(uiLayout *layout, bContext *UNUSED(C), Po static void node_shader_buts_vect_transform(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { - uiItemR(layout, ptr, "type", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + uiItemR(layout, ptr, "vector_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE); uiItemR(layout, ptr, "convert_from", 0, "", ICON_NONE); uiItemR(layout, ptr, "convert_to", 0, "", ICON_NONE); } @@ -790,7 +780,7 @@ static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr); } -static void node_shader_buts_tex_image_details(uiLayout *layout, bContext *C, PointerRNA *ptr) +static void node_shader_buts_tex_image_ex(uiLayout *layout, bContext *C, PointerRNA *ptr) { PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user"); uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0); @@ -911,8 +901,16 @@ static void node_shader_buts_glossy(uiLayout *layout, bContext *UNUSED(C), Point uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE); } -static void node_shader_buts_subsurface(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +static void node_shader_buts_subsurface(uiLayout *layout, bContext *C, PointerRNA *ptr) { + /* SSS 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) + uiItemL(layout, IFACE_("SSS not supported on GPU"), ICON_ERROR); + } + uiItemR(layout, ptr, "falloff", 0, "", ICON_NONE); } @@ -943,7 +941,7 @@ static void node_shader_buts_script(uiLayout *layout, bContext *UNUSED(C), Point uiItemO(row, "", ICON_FILE_REFRESH, "node.shader_script_update"); } -static void node_shader_buts_script_details(uiLayout *layout, bContext *C, PointerRNA *ptr) +static void node_shader_buts_script_ex(uiLayout *layout, bContext *C, PointerRNA *ptr) { uiItemS(layout); @@ -961,110 +959,110 @@ static void node_shader_set_butfunc(bNodeType *ntype) switch (ntype->type) { case SH_NODE_MATERIAL: case SH_NODE_MATERIAL_EXT: - ntype->uifunc = node_shader_buts_material; + ntype->draw_buttons = node_shader_buts_material; break; case SH_NODE_TEXTURE: - ntype->uifunc = node_buts_texture; + ntype->draw_buttons = node_buts_texture; break; case SH_NODE_NORMAL: - ntype->uifunc = node_buts_normal; + ntype->draw_buttons = node_buts_normal; break; case SH_NODE_CURVE_VEC: - ntype->uifunc = node_buts_curvevec; + ntype->draw_buttons = node_buts_curvevec; break; case SH_NODE_CURVE_RGB: - ntype->uifunc = node_buts_curvecol; + ntype->draw_buttons = node_buts_curvecol; break; case SH_NODE_MAPPING: - ntype->uifunc = node_shader_buts_mapping; + ntype->draw_buttons = node_shader_buts_mapping; break; case SH_NODE_VALUE: - ntype->uifunc = node_buts_value; + ntype->draw_buttons = node_buts_value; break; case SH_NODE_RGB: - ntype->uifunc = node_buts_rgb; + ntype->draw_buttons = node_buts_rgb; break; case SH_NODE_MIX_RGB: - ntype->uifunc = node_buts_mix_rgb; + ntype->draw_buttons = node_buts_mix_rgb; break; case SH_NODE_VALTORGB: - ntype->uifunc = node_buts_colorramp; + ntype->draw_buttons = node_buts_colorramp; break; case SH_NODE_MATH: - ntype->uifunc = node_buts_math; + ntype->draw_buttons = node_buts_math; break; case SH_NODE_VECT_MATH: - ntype->uifunc = node_shader_buts_vect_math; + ntype->draw_buttons = node_shader_buts_vect_math; break; case SH_NODE_VECT_TRANSFORM: - ntype->uifunc = node_shader_buts_vect_transform; + ntype->draw_buttons = node_shader_buts_vect_transform; break; case SH_NODE_GEOMETRY: - ntype->uifunc = node_shader_buts_geometry; + ntype->draw_buttons = node_shader_buts_geometry; break; case SH_NODE_ATTRIBUTE: - ntype->uifunc = node_shader_buts_attribute; + ntype->draw_buttons = node_shader_buts_attribute; break; case SH_NODE_WIREFRAME: - ntype->uifunc = node_shader_buts_wireframe; + ntype->draw_buttons = node_shader_buts_wireframe; break; case SH_NODE_TEX_SKY: - ntype->uifunc = node_shader_buts_tex_sky; + ntype->draw_buttons = node_shader_buts_tex_sky; break; case SH_NODE_TEX_IMAGE: - ntype->uifunc = node_shader_buts_tex_image; - ntype->uifuncbut = node_shader_buts_tex_image_details; + ntype->draw_buttons = node_shader_buts_tex_image; + ntype->draw_buttons_ex = node_shader_buts_tex_image_ex; break; case SH_NODE_TEX_ENVIRONMENT: - ntype->uifunc = node_shader_buts_tex_environment; + ntype->draw_buttons = node_shader_buts_tex_environment; break; case SH_NODE_TEX_GRADIENT: - ntype->uifunc = node_shader_buts_tex_gradient; + ntype->draw_buttons = node_shader_buts_tex_gradient; break; case SH_NODE_TEX_MAGIC: - ntype->uifunc = node_shader_buts_tex_magic; + ntype->draw_buttons = node_shader_buts_tex_magic; break; case SH_NODE_TEX_BRICK: - ntype->uifunc = node_shader_buts_tex_brick; + ntype->draw_buttons = node_shader_buts_tex_brick; break; case SH_NODE_TEX_WAVE: - ntype->uifunc = node_shader_buts_tex_wave; + ntype->draw_buttons = node_shader_buts_tex_wave; break; case SH_NODE_TEX_MUSGRAVE: - ntype->uifunc = node_shader_buts_tex_musgrave; + ntype->draw_buttons = node_shader_buts_tex_musgrave; break; case SH_NODE_TEX_VORONOI: - ntype->uifunc = node_shader_buts_tex_voronoi; + ntype->draw_buttons = node_shader_buts_tex_voronoi; break; case SH_NODE_TEX_COORD: - ntype->uifunc = node_shader_buts_tex_coord; + ntype->draw_buttons = node_shader_buts_tex_coord; break; case SH_NODE_BUMP: - ntype->uifunc = node_shader_buts_bump; + ntype->draw_buttons = node_shader_buts_bump; break; case SH_NODE_NORMAL_MAP: - ntype->uifunc = node_shader_buts_normal_map; + ntype->draw_buttons = node_shader_buts_normal_map; break; case SH_NODE_TANGENT: - ntype->uifunc = node_shader_buts_tangent; + ntype->draw_buttons = node_shader_buts_tangent; break; case SH_NODE_BSDF_GLOSSY: case SH_NODE_BSDF_GLASS: case SH_NODE_BSDF_REFRACTION: - ntype->uifunc = node_shader_buts_glossy; + ntype->draw_buttons = node_shader_buts_glossy; break; case SH_NODE_SUBSURFACE_SCATTERING: - ntype->uifunc = node_shader_buts_subsurface; + ntype->draw_buttons = node_shader_buts_subsurface; break; case SH_NODE_BSDF_TOON: - ntype->uifunc = node_shader_buts_toon; + ntype->draw_buttons = node_shader_buts_toon; break; case SH_NODE_BSDF_HAIR: - ntype->uifunc = node_shader_buts_hair; + ntype->draw_buttons = node_shader_buts_hair; break; case SH_NODE_SCRIPT: - ntype->uifunc = node_shader_buts_script; - ntype->uifuncbut = node_shader_buts_script_details; + ntype->draw_buttons = node_shader_buts_script; + ntype->draw_buttons_ex = node_shader_buts_script_ex; break; } } @@ -1086,7 +1084,7 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA * node_buts_image_user(layout, C, ptr, &imaptr, &iuserptr); } -static void node_composit_buts_image_details(uiLayout *layout, bContext *C, PointerRNA *ptr) +static void node_composit_buts_image_ex(uiLayout *layout, bContext *C, PointerRNA *ptr) { bNode *node = ptr->data; PointerRNA iuserptr; @@ -1568,46 +1566,6 @@ static void node_composit_buts_id_mask(uiLayout *layout, bContext *UNUSED(C), Po uiItemR(layout, ptr, "use_antialiasing", 0, NULL, ICON_NONE); } -/* draw function for file output node sockets, displays only sub-path and format, no value button */ -static void node_draw_input_file_output(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *node_ptr) -{ - bNodeTree *ntree = ptr->id.data; - bNodeSocket *sock = ptr->data; - uiLayout *row; - PointerRNA inputptr, imfptr; - int imtype; - - row = uiLayoutRow(layout, FALSE); - - imfptr = RNA_pointer_get(node_ptr, "format"); - imtype = RNA_enum_get(&imfptr, "file_format"); - if (imtype == R_IMF_IMTYPE_MULTILAYER) { - NodeImageMultiFileSocket *input = sock->storage; - RNA_pointer_create(&ntree->id, &RNA_NodeOutputFileSlotLayer, input, &inputptr); - - uiItemL(row, input->layer, ICON_NONE); - } - else { - NodeImageMultiFileSocket *input = sock->storage; - PropertyRNA *imtype_prop; - const char *imtype_name; - uiBlock *block; - RNA_pointer_create(&ntree->id, &RNA_NodeOutputFileSlotFile, input, &inputptr); - - uiItemL(row, input->path, ICON_NONE); - - if (!RNA_boolean_get(&inputptr, "use_node_format")) - imfptr = RNA_pointer_get(&inputptr, "format"); - - imtype_prop = RNA_struct_find_property(&imfptr, "file_format"); - RNA_property_enum_name((bContext *)C, &imfptr, imtype_prop, - RNA_property_enum_get(&imfptr, imtype_prop), &imtype_name); - block = uiLayoutGetBlock(row); - uiBlockSetEmboss(block, UI_EMBOSSP); - uiItemL(row, imtype_name, ICON_NONE); - uiBlockSetEmboss(block, UI_EMBOSSN); - } -} static void node_composit_buts_file_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { PointerRNA imfptr = RNA_pointer_get(ptr, "format"); @@ -1619,7 +1577,7 @@ static void node_composit_buts_file_output(uiLayout *layout, bContext *UNUSED(C) uiItemL(layout, IFACE_("Base Path:"), ICON_NONE); uiItemR(layout, ptr, "base_path", 0, "", ICON_NONE); } -static void node_composit_buts_file_output_details(uiLayout *layout, bContext *C, PointerRNA *ptr) +static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, PointerRNA *ptr) { PointerRNA imfptr = RNA_pointer_get(ptr, "format"); PointerRNA active_input_ptr, op_ptr; @@ -1777,7 +1735,7 @@ static void node_composit_buts_colorbalance(uiLayout *layout, bContext *UNUSED(C } } -static void node_composit_buts_colorbalance_but(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +static void node_composit_buts_colorbalance_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiItemR(layout, ptr, "correction_method", 0, NULL, ICON_NONE); @@ -1831,7 +1789,7 @@ static void node_composit_buts_movieclip(uiLayout *layout, bContext *C, PointerR uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL); } -static void node_composit_buts_movieclip_details(uiLayout *layout, bContext *C, PointerRNA *ptr) +static void node_composit_buts_movieclip_ex(uiLayout *layout, bContext *C, PointerRNA *ptr) { bNode *node = ptr->data; PointerRNA clipptr; @@ -1935,7 +1893,7 @@ static void node_composit_buts_colorcorrection(uiLayout *layout, bContext *UNUSE uiItemR(row, ptr, "midtones_end", UI_ITEM_R_SLIDER, NULL, ICON_NONE); } -static void node_composit_buts_colorcorrection_but(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +static void node_composit_buts_colorcorrection_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiLayout *row; @@ -2137,7 +2095,7 @@ static void node_composit_buts_viewer(uiLayout *layout, bContext *UNUSED(C), Poi uiItemR(layout, ptr, "use_alpha", 0, NULL, ICON_NONE); } -static void node_composit_buts_viewer_but(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +static void node_composit_buts_viewer_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiLayout *col; @@ -2285,222 +2243,221 @@ static void node_composit_set_butfunc(bNodeType *ntype) { switch (ntype->type) { case CMP_NODE_IMAGE: - ntype->uifunc = node_composit_buts_image; - ntype->uifuncbut = node_composit_buts_image_details; + ntype->draw_buttons = node_composit_buts_image; + ntype->draw_buttons_ex = node_composit_buts_image_ex; break; case CMP_NODE_R_LAYERS: - ntype->uifunc = node_composit_buts_renderlayers; + ntype->draw_buttons = node_composit_buts_renderlayers; break; case CMP_NODE_NORMAL: - ntype->uifunc = node_buts_normal; + ntype->draw_buttons = node_buts_normal; break; case CMP_NODE_CURVE_VEC: - ntype->uifunc = node_buts_curvevec; + ntype->draw_buttons = node_buts_curvevec; break; case CMP_NODE_CURVE_RGB: - ntype->uifunc = node_buts_curvecol; + ntype->draw_buttons = node_buts_curvecol; break; case CMP_NODE_VALUE: - ntype->uifunc = node_buts_value; + ntype->draw_buttons = node_buts_value; break; case CMP_NODE_RGB: - ntype->uifunc = node_buts_rgb; + ntype->draw_buttons = node_buts_rgb; break; case CMP_NODE_FLIP: - ntype->uifunc = node_composit_buts_flip; + ntype->draw_buttons = node_composit_buts_flip; break; case CMP_NODE_SPLITVIEWER: - ntype->uifunc = node_composit_buts_splitviewer; + ntype->draw_buttons = node_composit_buts_splitviewer; break; case CMP_NODE_MIX_RGB: - ntype->uifunc = node_buts_mix_rgb; + ntype->draw_buttons = node_buts_mix_rgb; break; case CMP_NODE_VALTORGB: - ntype->uifunc = node_buts_colorramp; + ntype->draw_buttons = node_buts_colorramp; break; case CMP_NODE_CROP: - ntype->uifunc = node_composit_buts_crop; + ntype->draw_buttons = node_composit_buts_crop; break; case CMP_NODE_BLUR: - ntype->uifunc = node_composit_buts_blur; + ntype->draw_buttons = node_composit_buts_blur; break; case CMP_NODE_DBLUR: - ntype->uifunc = node_composit_buts_dblur; + ntype->draw_buttons = node_composit_buts_dblur; break; case CMP_NODE_BILATERALBLUR: - ntype->uifunc = node_composit_buts_bilateralblur; + ntype->draw_buttons = node_composit_buts_bilateralblur; break; case CMP_NODE_DEFOCUS: - ntype->uifunc = node_composit_buts_defocus; + ntype->draw_buttons = node_composit_buts_defocus; break; case CMP_NODE_GLARE: - ntype->uifunc = node_composit_buts_glare; + ntype->draw_buttons = node_composit_buts_glare; break; case CMP_NODE_TONEMAP: - ntype->uifunc = node_composit_buts_tonemap; + ntype->draw_buttons = node_composit_buts_tonemap; break; case CMP_NODE_LENSDIST: - ntype->uifunc = node_composit_buts_lensdist; + ntype->draw_buttons = node_composit_buts_lensdist; break; case CMP_NODE_VECBLUR: - ntype->uifunc = node_composit_buts_vecblur; + ntype->draw_buttons = node_composit_buts_vecblur; break; case CMP_NODE_FILTER: - ntype->uifunc = node_composit_buts_filter; + ntype->draw_buttons = node_composit_buts_filter; break; case CMP_NODE_MAP_VALUE: - ntype->uifunc = node_composit_buts_map_value; + ntype->draw_buttons = node_composit_buts_map_value; break; case CMP_NODE_MAP_RANGE: - ntype->uifunc = node_composit_buts_map_range; + ntype->draw_buttons = node_composit_buts_map_range; break; case CMP_NODE_TIME: - ntype->uifunc = node_buts_time; + ntype->draw_buttons = node_buts_time; break; case CMP_NODE_ALPHAOVER: - ntype->uifunc = node_composit_buts_alphaover; + ntype->draw_buttons = node_composit_buts_alphaover; break; case CMP_NODE_HUE_SAT: - ntype->uifunc = node_composit_buts_hue_sat; + ntype->draw_buttons = node_composit_buts_hue_sat; break; case CMP_NODE_TEXTURE: - ntype->uifunc = node_buts_texture; + ntype->draw_buttons = node_buts_texture; break; case CMP_NODE_DILATEERODE: - ntype->uifunc = node_composit_buts_dilateerode; + ntype->draw_buttons = node_composit_buts_dilateerode; break; case CMP_NODE_INPAINT: - ntype->uifunc = node_composit_buts_inpaint; + ntype->draw_buttons = node_composit_buts_inpaint; break; case CMP_NODE_DESPECKLE: - ntype->uifunc = node_composit_buts_despeckle; + ntype->draw_buttons = node_composit_buts_despeckle; break; case CMP_NODE_OUTPUT_FILE: - ntype->uifunc = node_composit_buts_file_output; - ntype->uifuncbut = node_composit_buts_file_output_details; - ntype->drawinputfunc = node_draw_input_file_output; + ntype->draw_buttons = node_composit_buts_file_output; + ntype->draw_buttons_ex = node_composit_buts_file_output_ex; break; case CMP_NODE_DIFF_MATTE: - ntype->uifunc = node_composit_buts_diff_matte; + ntype->draw_buttons = node_composit_buts_diff_matte; break; case CMP_NODE_DIST_MATTE: - ntype->uifunc = node_composit_buts_distance_matte; + ntype->draw_buttons = node_composit_buts_distance_matte; break; case CMP_NODE_COLOR_SPILL: - ntype->uifunc = node_composit_buts_color_spill; + ntype->draw_buttons = node_composit_buts_color_spill; break; case CMP_NODE_CHROMA_MATTE: - ntype->uifunc = node_composit_buts_chroma_matte; + ntype->draw_buttons = node_composit_buts_chroma_matte; break; case CMP_NODE_COLOR_MATTE: - ntype->uifunc = node_composit_buts_color_matte; + ntype->draw_buttons = node_composit_buts_color_matte; break; case CMP_NODE_SCALE: - ntype->uifunc = node_composit_buts_scale; + ntype->draw_buttons = node_composit_buts_scale; break; case CMP_NODE_ROTATE: - ntype->uifunc = node_composit_buts_rotate; + ntype->draw_buttons = node_composit_buts_rotate; break; case CMP_NODE_CHANNEL_MATTE: - ntype->uifunc = node_composit_buts_channel_matte; + ntype->draw_buttons = node_composit_buts_channel_matte; break; case CMP_NODE_LUMA_MATTE: - ntype->uifunc = node_composit_buts_luma_matte; + ntype->draw_buttons = node_composit_buts_luma_matte; break; case CMP_NODE_MAP_UV: - ntype->uifunc = node_composit_buts_map_uv; + ntype->draw_buttons = node_composit_buts_map_uv; break; case CMP_NODE_ID_MASK: - ntype->uifunc = node_composit_buts_id_mask; + ntype->draw_buttons = node_composit_buts_id_mask; break; case CMP_NODE_DOUBLEEDGEMASK: - ntype->uifunc = node_composit_buts_double_edge_mask; + ntype->draw_buttons = node_composit_buts_double_edge_mask; break; case CMP_NODE_MATH: - ntype->uifunc = node_buts_math; + ntype->draw_buttons = node_buts_math; break; case CMP_NODE_INVERT: - ntype->uifunc = node_composit_buts_invert; + ntype->draw_buttons = node_composit_buts_invert; break; case CMP_NODE_PREMULKEY: - ntype->uifunc = node_composit_buts_premulkey; + ntype->draw_buttons = node_composit_buts_premulkey; break; case CMP_NODE_VIEW_LEVELS: - ntype->uifunc = node_composit_buts_view_levels; + ntype->draw_buttons = node_composit_buts_view_levels; break; case CMP_NODE_COLORBALANCE: - ntype->uifunc = node_composit_buts_colorbalance; - ntype->uifuncbut = node_composit_buts_colorbalance_but; + ntype->draw_buttons = node_composit_buts_colorbalance; + ntype->draw_buttons_ex = node_composit_buts_colorbalance_ex; break; case CMP_NODE_HUECORRECT: - ntype->uifunc = node_composit_buts_huecorrect; + ntype->draw_buttons = node_composit_buts_huecorrect; break; case CMP_NODE_ZCOMBINE: - ntype->uifunc = node_composit_buts_zcombine; + ntype->draw_buttons = node_composit_buts_zcombine; break; case CMP_NODE_COMBYCCA: case CMP_NODE_SEPYCCA: - ntype->uifunc = node_composit_buts_ycc; + ntype->draw_buttons = node_composit_buts_ycc; break; case CMP_NODE_MOVIECLIP: - ntype->uifunc = node_composit_buts_movieclip; - ntype->uifuncbut = node_composit_buts_movieclip_details; + ntype->draw_buttons = node_composit_buts_movieclip; + ntype->draw_buttons_ex = node_composit_buts_movieclip_ex; break; case CMP_NODE_STABILIZE2D: - ntype->uifunc = node_composit_buts_stabilize2d; + ntype->draw_buttons = node_composit_buts_stabilize2d; break; case CMP_NODE_TRANSFORM: - ntype->uifunc = node_composit_buts_transform; + ntype->draw_buttons = node_composit_buts_transform; break; case CMP_NODE_TRANSLATE: - ntype->uifunc = node_composit_buts_translate; + ntype->draw_buttons = node_composit_buts_translate; break; case CMP_NODE_MOVIEDISTORTION: - ntype->uifunc = node_composit_buts_moviedistortion; + ntype->draw_buttons = node_composit_buts_moviedistortion; break; case CMP_NODE_COLORCORRECTION: - ntype->uifunc = node_composit_buts_colorcorrection; - ntype->uifuncbut = node_composit_buts_colorcorrection_but; + ntype->draw_buttons = node_composit_buts_colorcorrection; + ntype->draw_buttons_ex = node_composit_buts_colorcorrection_ex; break; case CMP_NODE_SWITCH: - ntype->uifunc = node_composit_buts_switch; + ntype->draw_buttons = node_composit_buts_switch; break; case CMP_NODE_MASK_BOX: - ntype->uifunc = node_composit_buts_boxmask; - ntype->uibackdropfunc = node_composit_backdrop_boxmask; + ntype->draw_buttons = node_composit_buts_boxmask; + ntype->draw_backdrop = node_composit_backdrop_boxmask; break; case CMP_NODE_MASK_ELLIPSE: - ntype->uifunc = node_composit_buts_ellipsemask; - ntype->uibackdropfunc = node_composit_backdrop_ellipsemask; + ntype->draw_buttons = node_composit_buts_ellipsemask; + ntype->draw_backdrop = node_composit_backdrop_ellipsemask; break; case CMP_NODE_BOKEHIMAGE: - ntype->uifunc = node_composit_buts_bokehimage; + ntype->draw_buttons = node_composit_buts_bokehimage; break; case CMP_NODE_BOKEHBLUR: - ntype->uifunc = node_composit_buts_bokehblur; + ntype->draw_buttons = node_composit_buts_bokehblur; break; case CMP_NODE_VIEWER: - ntype->uifunc = node_composit_buts_viewer; - ntype->uifuncbut = node_composit_buts_viewer_but; - ntype->uibackdropfunc = node_composit_backdrop_viewer; + ntype->draw_buttons = node_composit_buts_viewer; + ntype->draw_buttons_ex = node_composit_buts_viewer_ex; + ntype->draw_backdrop = node_composit_backdrop_viewer; break; case CMP_NODE_COMPOSITE: - ntype->uifunc = node_composit_buts_composite; + ntype->draw_buttons = node_composit_buts_composite; break; case CMP_NODE_MASK: - ntype->uifunc = node_composit_buts_mask; + ntype->draw_buttons = node_composit_buts_mask; break; case CMP_NODE_KEYINGSCREEN: - ntype->uifunc = node_composit_buts_keyingscreen; + ntype->draw_buttons = node_composit_buts_keyingscreen; break; case CMP_NODE_KEYING: - ntype->uifunc = node_composit_buts_keying; + ntype->draw_buttons = node_composit_buts_keying; break; case CMP_NODE_TRACKPOS: - ntype->uifunc = node_composit_buts_trackpos; + ntype->draw_buttons = node_composit_buts_trackpos; break; case CMP_NODE_PLANETRACKDEFORM: - ntype->uifunc = node_composit_buts_planetrackdeform; + ntype->draw_buttons = node_composit_buts_planetrackdeform; break; } } @@ -2605,7 +2562,7 @@ static void node_texture_buts_image(uiLayout *layout, bContext *C, PointerRNA *p uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL); } -static void node_texture_buts_image_details(uiLayout *layout, bContext *C, PointerRNA *ptr) +static void node_texture_buts_image_ex(uiLayout *layout, bContext *C, PointerRNA *ptr) { bNode *node = ptr->data; PointerRNA iuserptr; @@ -2623,46 +2580,46 @@ static void node_texture_buts_output(uiLayout *layout, bContext *UNUSED(C), Poin static void node_texture_set_butfunc(bNodeType *ntype) { if (ntype->type >= TEX_NODE_PROC && ntype->type < TEX_NODE_PROC_MAX) { - ntype->uifunc = node_texture_buts_proc; + ntype->draw_buttons = node_texture_buts_proc; } else { switch (ntype->type) { case TEX_NODE_MATH: - ntype->uifunc = node_buts_math; + ntype->draw_buttons = node_buts_math; break; case TEX_NODE_MIX_RGB: - ntype->uifunc = node_buts_mix_rgb; + ntype->draw_buttons = node_buts_mix_rgb; break; case TEX_NODE_VALTORGB: - ntype->uifunc = node_buts_colorramp; + ntype->draw_buttons = node_buts_colorramp; break; case TEX_NODE_CURVE_RGB: - ntype->uifunc = node_buts_curvecol; + ntype->draw_buttons = node_buts_curvecol; break; case TEX_NODE_CURVE_TIME: - ntype->uifunc = node_buts_time; + ntype->draw_buttons = node_buts_time; break; case TEX_NODE_TEXTURE: - ntype->uifunc = node_buts_texture; + ntype->draw_buttons = node_buts_texture; break; case TEX_NODE_BRICKS: - ntype->uifunc = node_texture_buts_bricks; + ntype->draw_buttons = node_texture_buts_bricks; break; case TEX_NODE_IMAGE: - ntype->uifunc = node_texture_buts_image; - ntype->uifuncbut = node_texture_buts_image_details; + ntype->draw_buttons = node_texture_buts_image; + ntype->draw_buttons_ex = node_texture_buts_image_ex; break; case TEX_NODE_OUTPUT: - ntype->uifunc = node_texture_buts_output; + ntype->draw_buttons = node_texture_buts_output; break; } } @@ -2736,14 +2693,12 @@ void ED_node_init_butfuncs(void) extern bNodeSocketType NodeSocketTypeUndefined; /* default ui functions */ - NodeTypeUndefined.drawfunc = node_draw_default; - NodeTypeUndefined.drawupdatefunc = node_update_default; + NodeTypeUndefined.draw_nodetype = node_draw_default; + NodeTypeUndefined.draw_nodetype_prepare = node_update_default; NodeTypeUndefined.select_area_func = node_select_area_default; NodeTypeUndefined.tweak_area_func = node_tweak_area_default; - NodeTypeUndefined.uifunc = NULL; - NodeTypeUndefined.uifuncbut = NULL; - NodeTypeUndefined.drawinputfunc = node_draw_input_default; - NodeTypeUndefined.drawoutputfunc = node_draw_output_default; + NodeTypeUndefined.draw_buttons = NULL; + NodeTypeUndefined.draw_buttons_ex = NULL; NodeTypeUndefined.resize_area_func = node_resize_area_default; NodeSocketTypeUndefined.draw = node_socket_undefined_draw; @@ -2754,14 +2709,12 @@ void ED_node_init_butfuncs(void) /* node type ui functions */ NODE_TYPES_BEGIN(ntype) /* default ui functions */ - ntype->drawfunc = node_draw_default; - ntype->drawupdatefunc = node_update_default; + ntype->draw_nodetype = node_draw_default; + ntype->draw_nodetype_prepare = node_update_default; ntype->select_area_func = node_select_area_default; ntype->tweak_area_func = node_tweak_area_default; - ntype->uifunc = NULL; - ntype->uifuncbut = NULL; - ntype->drawinputfunc = node_draw_input_default; - ntype->drawoutputfunc = node_draw_output_default; + ntype->draw_buttons = NULL; + ntype->draw_buttons_ex = NULL; ntype->resize_area_func = node_resize_area_default; node_common_set_butfunc(ntype); @@ -2783,10 +2736,8 @@ void ED_node_init_butfuncs(void) void ED_init_custom_node_type(bNodeType *ntype) { /* default ui functions */ - ntype->drawfunc = node_draw_default; - ntype->drawupdatefunc = node_update_default; - ntype->drawinputfunc = node_draw_input_default; - ntype->drawoutputfunc = node_draw_output_default; + ntype->draw_nodetype = node_draw_default; + ntype->draw_nodetype_prepare = node_update_default; ntype->resize_area_func = node_resize_area_default; ntype->select_area_func = node_select_area_default; ntype->tweak_area_func = node_tweak_area_default; @@ -2824,13 +2775,60 @@ static void std_node_socket_interface_draw_color(bContext *UNUSED(C), PointerRNA copy_v4_v4(r_color, std_node_socket_colors[type]); } +/* draw function for file output node sockets, displays only sub-path and format, no value button */ +static void node_file_output_socket_draw(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *node_ptr) +{ + bNodeTree *ntree = ptr->id.data; + bNodeSocket *sock = ptr->data; + uiLayout *row; + PointerRNA inputptr, imfptr; + int imtype; + + row = uiLayoutRow(layout, FALSE); + + imfptr = RNA_pointer_get(node_ptr, "format"); + imtype = RNA_enum_get(&imfptr, "file_format"); + if (imtype == R_IMF_IMTYPE_MULTILAYER) { + NodeImageMultiFileSocket *input = sock->storage; + RNA_pointer_create(&ntree->id, &RNA_NodeOutputFileSlotLayer, input, &inputptr); + + uiItemL(row, input->layer, ICON_NONE); + } + else { + NodeImageMultiFileSocket *input = sock->storage; + PropertyRNA *imtype_prop; + const char *imtype_name; + uiBlock *block; + RNA_pointer_create(&ntree->id, &RNA_NodeOutputFileSlotFile, input, &inputptr); + + uiItemL(row, input->path, ICON_NONE); + + if (!RNA_boolean_get(&inputptr, "use_node_format")) + imfptr = RNA_pointer_get(&inputptr, "format"); + + imtype_prop = RNA_struct_find_property(&imfptr, "file_format"); + RNA_property_enum_name((bContext *)C, &imfptr, imtype_prop, + RNA_property_enum_get(&imfptr, imtype_prop), &imtype_name); + block = uiLayoutGetBlock(row); + uiBlockSetEmboss(block, UI_EMBOSSP); + uiItemL(row, imtype_name, ICON_NONE); + uiBlockSetEmboss(block, UI_EMBOSSN); + } +} + static void std_node_socket_draw(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *node_ptr, const char *text) { + bNode *node = node_ptr->data; bNodeSocket *sock = ptr->data; int type = sock->typeinfo->type; /*int subtype = sock->typeinfo->subtype;*/ - if ((sock->flag & SOCK_IN_USE) || (sock->flag & SOCK_HIDE_VALUE)) { + /* XXX not nice, eventually give this node its own socket type ... */ + if (node->type == CMP_NODE_OUTPUT_FILE) { + node_file_output_socket_draw(C, layout, ptr, node_ptr); + } + + if ((sock->in_out == SOCK_OUT) || (sock->flag & SOCK_IN_USE) || (sock->flag & SOCK_HIDE_VALUE)) { node_socket_button_label(C, layout, ptr, node_ptr, text); return; } @@ -3043,8 +3041,8 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b rctf *viewer_border = &snode->nodetree->viewer_border; while (node) { if (node->flag & NODE_SELECT) { - if (node->typeinfo->uibackdropfunc) { - node->typeinfo->uibackdropfunc(snode, ibuf, node, x, y); + if (node->typeinfo->draw_backdrop) { + node->typeinfo->draw_backdrop(snode, ibuf, node, x, y); } } node = node->next; diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 29f796aecb1..65eb75f8523 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -351,7 +351,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) row = uiLayoutRow(layout, 1); uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_RIGHT); - node->typeinfo->drawoutputfunc((bContext *)C, row, &sockptr, &nodeptr); + nsock->typeinfo->draw((bContext *)C, row, &sockptr, &nodeptr, IFACE_(nsock->name)); uiBlockEndAlign(node->block); uiBlockLayoutResolve(node->block, NULL, &buty); @@ -402,7 +402,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) } /* buttons rect? */ - if (node->typeinfo->uifunc && (node->flag & NODE_OPTIONS)) { + if (node->typeinfo->draw_buttons && (node->flag & NODE_OPTIONS)) { dy -= NODE_DYS / 2; /* set this for uifunc() that don't use layout engine yet */ @@ -416,7 +416,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) locx + NODE_DYS, dy, node->butr.xmax, 0, UI_GetStyle()); uiLayoutSetContextPointer(layout, "node", &nodeptr); - node->typeinfo->uifunc(layout, (bContext *)C, &nodeptr); + node->typeinfo->draw_buttons(layout, (bContext *)C, &nodeptr); uiBlockEndAlign(node->block); uiBlockLayoutResolve(node->block, NULL, &buty); @@ -437,7 +437,9 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) uiLayoutSetContextPointer(layout, "node", &nodeptr); uiLayoutSetContextPointer(layout, "socket", &sockptr); - node->typeinfo->drawinputfunc((bContext *)C, layout, &sockptr, &nodeptr); + row = uiLayoutRow(layout, 1); + + nsock->typeinfo->draw((bContext *)C, row, &sockptr, &nodeptr, IFACE_(nsock->name)); uiBlockEndAlign(node->block); uiBlockLayoutResolve(node->block, NULL, &buty); @@ -1115,8 +1117,8 @@ void node_draw_default(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTr static void node_update(const bContext *C, bNodeTree *ntree, bNode *node) { - if (node->typeinfo->drawupdatefunc) - node->typeinfo->drawupdatefunc(C, ntree, node); + if (node->typeinfo->draw_nodetype_prepare) + node->typeinfo->draw_nodetype_prepare(C, ntree, node); } void node_update_nodetree(const bContext *C, bNodeTree *ntree) @@ -1131,8 +1133,8 @@ void node_update_nodetree(const bContext *C, bNodeTree *ntree) static void node_draw(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node, bNodeInstanceKey key) { - if (node->typeinfo->drawfunc) - node->typeinfo->drawfunc(C, ar, snode, ntree, node, key); + if (node->typeinfo->draw_nodetype) + node->typeinfo->draw_nodetype(C, ar, snode, ntree, node, key); } #define USE_DRAW_TOT_UPDATE @@ -1241,7 +1243,7 @@ static void draw_group_overlay(const bContext *C, ARegion *ar) /* shade node groups to separate them visually */ UI_ThemeColorShadeAlpha(TH_NODE_GROUP, 0, -70); glEnable(GL_BLEND); - uiSetRoundBox(0); + uiSetRoundBox(UI_CNR_NONE); uiDrawBox(GL_POLYGON, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 0); glDisable(GL_BLEND); diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index ff6a8e884a6..1d93fe65c09 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -1419,7 +1419,7 @@ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag) if (toggle_flag == NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW) == 0) continue; - if (toggle_flag == NODE_OPTIONS && !(node->typeinfo->uifunc || node->typeinfo->uifuncbut)) + if (toggle_flag == NODE_OPTIONS && !(node->typeinfo->draw_buttons || node->typeinfo->draw_buttons_ex)) continue; if (node->flag & toggle_flag) @@ -1433,7 +1433,7 @@ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag) if (toggle_flag == NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW) == 0) continue; - if (toggle_flag == NODE_OPTIONS && !(node->typeinfo->uifunc || node->typeinfo->uifuncbut)) + if (toggle_flag == NODE_OPTIONS && !(node->typeinfo->draw_buttons || node->typeinfo->draw_buttons_ex)) continue; if ((tot_eq && tot_neq) || tot_eq == 0) @@ -1731,7 +1731,7 @@ static int node_output_file_add_socket_exec(bContext *C, wmOperator *op) node = nodeGetActive(snode->edittree); } - if (!node) + if (!node || node->type != CMP_NODE_OUTPUT_FILE) return OPERATOR_CANCELLED; RNA_string_get(op->ptr, "file_path", file_path); @@ -1777,7 +1777,7 @@ static int node_output_file_remove_active_socket_exec(bContext *C, wmOperator *U node = nodeGetActive(snode->edittree); } - if (!node) + if (!node || node->type != CMP_NODE_OUTPUT_FILE) return OPERATOR_CANCELLED; if (!ntreeCompositOutputFileRemoveActiveSocket(ntree, node)) @@ -1819,7 +1819,7 @@ static int node_output_file_move_active_socket_exec(bContext *C, wmOperator *op) else if (snode && snode->edittree) node = nodeGetActive(snode->edittree); - if (!node) + if (!node || node->type != CMP_NODE_OUTPUT_FILE) return OPERATOR_CANCELLED; nimf = node->storage; diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index 83c11e69d84..a67a8791a64 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -207,7 +207,7 @@ static void node_socket_add_replace(const bContext *C, bNodeTree *ntree, bNode * break; if (node_from) - if (node_from->inputs.first || node_from->typeinfo->uifunc || node_from->typeinfo->uifuncbut) + if (node_from->inputs.first || node_from->typeinfo->draw_buttons || node_from->typeinfo->draw_buttons_ex) node_from = NULL; if (node_prev && node_prev->type == type && node_link_item_compare(node_prev, item)) { @@ -586,13 +586,13 @@ static void ui_node_draw_node(uiLayout *layout, bContext *C, bNodeTree *ntree, b RNA_pointer_create(&ntree->id, &RNA_Node, node, &nodeptr); - if (node->typeinfo->uifunc) { + if (node->typeinfo->draw_buttons) { if (node->type != NODE_GROUP) { split = uiLayoutSplit(layout, 0.35f, FALSE); col = uiLayoutColumn(split, FALSE); col = uiLayoutColumn(split, FALSE); - node->typeinfo->uifunc(col, C, &nodeptr); + node->typeinfo->draw_buttons(col, C, &nodeptr); } } @@ -639,7 +639,7 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree, if (depth > 0) { uiBlockSetEmboss(block, UI_EMBOSSN); - if (lnode && (lnode->inputs.first || (lnode->typeinfo->uifunc && lnode->type != NODE_GROUP))) { + if (lnode && (lnode->inputs.first || (lnode->typeinfo->draw_buttons && lnode->type != NODE_GROUP))) { int icon = (input->flag & SOCK_COLLAPSED) ? ICON_DISCLOSURE_TRI_RIGHT : ICON_DISCLOSURE_TRI_DOWN; uiItemR(row, &inputptr, "show_expanded", UI_ITEM_R_ICON_ONLY, "", icon); } diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c index e4a9c4fa5db..f889a8ec97b 100644 --- a/source/blender/editors/space_node/node_view.c +++ b/source/blender/editors/space_node/node_view.c @@ -373,7 +373,7 @@ void NODE_OT_backimage_fit(wmOperatorType *ot) /* identifiers */ ot->name = "Background Image Fit"; ot->idname = "NODE_OT_backimage_fit"; - ot->description = "Zoom in/out the background image"; + ot->description = "Fit the background image to the view"; /* api callbacks */ ot->exec = backimage_fit_exec; diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index b86fba1398a..10890a305fb 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -384,17 +384,21 @@ static void outliner_add_line_styles(SpaceOops *soops, ListBase *lb, Scene *sce, for (srl = sce->r.layers.first; srl; srl = srl->next) { for (lineset = srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) { - lineset->linestyle->id.flag |= LIB_DOIT; + FreestyleLineStyle *linestyle = lineset->linestyle; + if (linestyle) { + linestyle->id.flag |= LIB_DOIT; + } } } for (srl = sce->r.layers.first; srl; srl = srl->next) { for (lineset = srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) { FreestyleLineStyle *linestyle = lineset->linestyle; - - if (!(linestyle->id.flag & LIB_DOIT)) - continue; - linestyle->id.flag &= ~LIB_DOIT; - outliner_add_element(soops, lb, linestyle, te, 0, 0); + if (linestyle) { + if (!(linestyle->id.flag & LIB_DOIT)) + continue; + linestyle->id.flag &= ~LIB_DOIT; + outliner_add_element(soops, lb, linestyle, te, 0, 0); + } } } } diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index ebec818bb36..cb69a7fe654 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -926,13 +926,13 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq /* stop all running jobs, except screen one. currently previews frustrate Render * needed to make so sequencer's rendering doesn't conflict with compositor */ - WM_jobs_kill_type(CTX_wm_manager(C), WM_JOB_TYPE_COMPOSITE); + WM_jobs_kill_type(CTX_wm_manager(C), NULL, WM_JOB_TYPE_COMPOSITE); if ((scene->r.seq_flag & R_SEQ_GL_PREV) == 0) { /* in case of final rendering used for preview, kill all previews, * otherwise threading conflict will happen in rendering module */ - WM_jobs_kill_type(CTX_wm_manager(C), WM_JOB_TYPE_RENDER_PREVIEW); + WM_jobs_kill_type(CTX_wm_manager(C), NULL, WM_JOB_TYPE_RENDER_PREVIEW); } } @@ -1251,7 +1251,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq height = (scene->r.size * scene->r.ysch) / 100; ED_mask_draw_region(mask, ar, - 0, 0, /* TODO */ + 0, 0, 0, /* TODO */ width, height, aspx, aspy, FALSE, TRUE, diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index d8b4824b528..8b2e7067eb9 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2960,7 +2960,7 @@ void SEQUENCER_OT_view_ghost_border(wmOperatorType *ot) /* identifiers */ ot->name = "Border Offset View"; ot->idname = "SEQUENCER_OT_view_ghost_border"; - ot->description = "Enable border select mode"; + ot->description = "Set the boundaries of the border used for offset-view"; /* api callbacks */ ot->invoke = WM_border_select_invoke; diff --git a/source/blender/editors/space_sequencer/sequencer_modifier.c b/source/blender/editors/space_sequencer/sequencer_modifier.c index 51df21e509a..c8fd6e4b6ea 100644 --- a/source/blender/editors/space_sequencer/sequencer_modifier.c +++ b/source/blender/editors/space_sequencer/sequencer_modifier.c @@ -99,7 +99,7 @@ void SEQUENCER_OT_strip_modifier_add(wmOperatorType *ot) /* identifiers */ ot->name = "Add Strip Modifier"; ot->idname = "SEQUENCER_OT_strip_modifier_add"; - ot->description = "Add a modifier to strip"; + ot->description = "Add a modifier to the strip"; /* api callbacks */ ot->exec = strip_modifier_add_exec; @@ -142,7 +142,7 @@ void SEQUENCER_OT_strip_modifier_remove(wmOperatorType *ot) /* identifiers */ ot->name = "Remove Strip Modifier"; ot->idname = "SEQUENCER_OT_strip_modifier_remove"; - ot->description = "Add a modifier to strip"; + ot->description = "Remove a modifier from the strip"; /* api callbacks */ ot->exec = strip_modifier_remove_exec; diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 254d15341cd..45f05d56076 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -892,7 +892,7 @@ void SEQUENCER_OT_select_border(wmOperatorType *ot) /* identifiers */ ot->name = "Border Select"; ot->idname = "SEQUENCER_OT_select_border"; - ot->description = "Enable border select mode"; + ot->description = "Select strips using border selection"; /* api callbacks */ ot->invoke = WM_border_select_invoke; diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c index 18733d4e409..deb37f8d943 100644 --- a/source/blender/editors/space_sequencer/sequencer_view.c +++ b/source/blender/editors/space_sequencer/sequencer_view.c @@ -220,7 +220,8 @@ static int sample_cancel(bContext *C, wmOperator *op) static int sample_poll(bContext *C) { - return BKE_sequencer_editing_get(CTX_data_scene(C), FALSE) != NULL; + SpaceSeq *sseq = CTX_wm_space_seq(C); + return sseq && BKE_sequencer_editing_get(CTX_data_scene(C), FALSE) != NULL; } void SEQUENCER_OT_sample(wmOperatorType *ot) diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index b04d2b16e8d..c668c8063a8 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -309,6 +309,8 @@ static void text_keymap(struct wmKeyConfig *keyconf) RNA_boolean_set(kmi->ptr, "selection", TRUE); } + WM_keymap_add_item(keymap, "TEXT_OT_properties", TKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "TEXT_OT_jump", JKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "TEXT_OT_find", GKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c index ba61399f6d5..eaba537c0a8 100644 --- a/source/blender/editors/space_text/text_autocomplete.c +++ b/source/blender/editors/space_text/text_autocomplete.c @@ -361,6 +361,7 @@ static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *e } break; case RETKEY: + case PADENTER: if (event->val == KM_PRESS) { if (tools & TOOL_SUGG_LIST) { confirm_suggestion(st->text); diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 2c2a8b255da..c078e612d68 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -1943,7 +1943,7 @@ void TEXT_OT_move_select(wmOperatorType *ot) /* identifiers */ ot->name = "Move Select"; ot->idname = "TEXT_OT_move_select"; - ot->description = "Make selection from current cursor position to new cursor position type"; + ot->description = "Move the cursor while selecting"; /* api callbacks */ ot->exec = text_move_select_exec; @@ -2291,7 +2291,7 @@ void TEXT_OT_scroll(wmOperatorType *ot) * scroll_bar. Both do basically the same thing (aside * from keymaps).*/ ot->idname = "TEXT_OT_scroll"; - ot->description = "Scroll text screen"; + ot->description = ""; /* api callbacks */ ot->exec = text_scroll_exec; @@ -2301,7 +2301,7 @@ void TEXT_OT_scroll(wmOperatorType *ot) ot->poll = text_scroll_poll; /* flags */ - ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER; + ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER | OPTYPE_INTERNAL; /* properties */ RNA_def_int(ot->srna, "lines", 1, INT_MIN, INT_MAX, "Lines", "Number of lines to scroll", -100, 100); @@ -2385,7 +2385,7 @@ void TEXT_OT_scroll_bar(wmOperatorType *ot) * scroll. Both do basically the same thing (aside * from keymaps).*/ ot->idname = "TEXT_OT_scroll_bar"; - ot->description = "Scroll text screen"; + ot->description = ""; /* api callbacks */ ot->invoke = text_scroll_bar_invoke; @@ -2394,7 +2394,7 @@ void TEXT_OT_scroll_bar(wmOperatorType *ot) ot->poll = text_region_scroll_poll; /* flags */ - ot->flag = OPTYPE_BLOCKING; + ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL; /* properties */ RNA_def_int(ot->srna, "lines", 1, INT_MIN, INT_MAX, "Lines", "Number of lines to scroll", -100, 100); diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index 2634dd3ec08..de6fafb2cd8 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -304,7 +304,7 @@ static void set_ebone_glColor(const unsigned int boneflag) /* *************** Armature drawing, helper calls for parts ******************* */ /* half the cube, in Y */ -static float cube[8][3] = { +static const float cube[8][3] = { {-1.0, 0.0, -1.0}, {-1.0, 0.0, 1.0}, {-1.0, 1.0, 1.0}, @@ -440,7 +440,7 @@ static void draw_bonevert_solid(void) glCallList(displist); } -static float bone_octahedral_verts[6][3] = { +static const float bone_octahedral_verts[6][3] = { { 0.0f, 0.0f, 0.0f}, { 0.1f, 0.1f, 0.1f}, { 0.1f, 0.1f, -0.1f}, @@ -449,10 +449,10 @@ static float bone_octahedral_verts[6][3] = { { 0.0f, 1.0f, 0.0f} }; -static unsigned int bone_octahedral_wire_sides[8] = {0, 1, 5, 3, 0, 4, 5, 2}; -static unsigned int bone_octahedral_wire_square[8] = {1, 2, 3, 4, 1}; +static const unsigned int bone_octahedral_wire_sides[8] = {0, 1, 5, 3, 0, 4, 5, 2}; +static const unsigned int bone_octahedral_wire_square[8] = {1, 2, 3, 4, 1}; -static unsigned int bone_octahedral_solid_tris[8][3] = { +static const unsigned int bone_octahedral_solid_tris[8][3] = { {2, 1, 0}, /* bottom */ {3, 2, 0}, {4, 3, 0}, @@ -465,7 +465,7 @@ static unsigned int bone_octahedral_solid_tris[8][3] = { }; /* aligned with bone_octahedral_solid_tris */ -static float bone_octahedral_solid_normals[8][3] = { +static const float bone_octahedral_solid_normals[8][3] = { { 0.70710683f, -0.70710683f, 0.00000000f}, {-0.00000000f, -0.70710683f, -0.70710683f}, {-0.70710683f, -0.70710683f, 0.00000000f}, @@ -599,7 +599,7 @@ static void draw_bone_points(const short dt, int armflag, unsigned int boneflag, } /* 16 values of sin function (still same result!) */ -static float si[16] = { +static const float si[16] = { 0.00000000f, 0.20129852f, 0.39435585f, 0.57126821f, 0.72479278f, @@ -611,7 +611,7 @@ static float si[16] = { 0.10116832f }; /* 16 values of cos function (still same result!) */ -static float co[16] = { +static const float co[16] = { 1.00000000f, 0.97952994f, 0.91895781f, 0.82076344f, 0.68896691f, diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index dc751599c46..612e0fde194 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2043,7 +2043,7 @@ static void draw_dm_face_normals__mapFunc(void *userData, int index, const float if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { if (!data->uniform_scale) { - mul_v3_m3v3(n, data->tmat, (float *) no); + mul_v3_m3v3(n, data->tmat, no); normalize_v3(n); mul_m3_v3(data->imat, n); } @@ -2108,7 +2108,7 @@ static void draw_dm_vert_normals__mapFunc(void *userData, int index, const float } if (!data->uniform_scale) { - mul_v3_m3v3(n, data->tmat, (float *) no); + mul_v3_m3v3(n, data->tmat, no); normalize_v3(n); mul_m3_v3(data->imat, n); } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index f397e869882..9f3da9250cc 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -44,6 +44,7 @@ #include "BKE_context.h" #include "BKE_icons.h" +#include "BKE_main.h" #include "BKE_object.h" #include "BKE_screen.h" @@ -258,6 +259,25 @@ void ED_view3d_check_mats_rv3d(struct RegionView3D *rv3d) } #endif +void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *sa) +{ + wmWindowManager *wm = bmain->wm.first; + + if (v3d->drawtype != OB_RENDER) { + ARegion *ar; + + for (ar = sa->regionbase.first; ar; ar = ar->next) { + RegionView3D *rv3d = ar->regiondata; + + if (rv3d && rv3d->render_engine) { + WM_jobs_kill_type(wm, ar, WM_JOB_TYPE_RENDER_PREVIEW); + RE_engine_free(rv3d->render_engine); + rv3d->render_engine = NULL; + } + } + } +} + /* ******************** default callbacks for view3d space ***************** */ static SpaceLink *view3d_new(const bContext *C) diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 75e7605df6b..eea084b4750 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -682,7 +682,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } BKE_nurb_test2D(nu); - BKE_nurb_handles_test(nu); /* test for bezier too */ + BKE_nurb_handles_test(nu, true); /* test for bezier too */ nu = nu->next; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index cafefb2a769..215d2b387d7 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -113,9 +113,9 @@ static void star_stuff_init_func(void) glPointSize(1.0); glBegin(GL_POINTS); } -static void star_stuff_vertex_func(float *i) +static void star_stuff_vertex_func(const float vec[3]) { - glVertex3fv(i); + glVertex3fv(vec); } static void star_stuff_term_func(void) { diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 5686c500270..67c9ea4599c 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -85,26 +85,23 @@ /* for ndof prints */ // #define DEBUG_NDOF_MOTION -static void view3d_offset_lock_report(ReportList *reports) -{ - BKE_report(reports, RPT_WARNING, "View offset is locked"); -} - bool ED_view3d_offset_lock_check(struct View3D *v3d, struct RegionView3D *rv3d) { return (rv3d->persp != RV3D_CAMOB) && (v3d->ob_centre_cursor || v3d->ob_centre); } -#define VIEW3D_OP_OFS_LOCK_TEST(C, op) \ - { \ - View3D *v3d_tmp = CTX_wm_view3d(C); \ - RegionView3D *rv3d_tmp = CTX_wm_region_view3d(C); \ - if (ED_view3d_offset_lock_check(v3d_tmp, rv3d_tmp)) { \ - view3d_offset_lock_report((op)->reports); \ - return OPERATOR_CANCELLED; \ - } \ - } (void)0 - +static bool view3d_operator_offset_lock_check(bContext *C, wmOperator *op) +{ + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d = CTX_wm_region_view3d(C); + if (ED_view3d_offset_lock_check(v3d, rv3d)) { + BKE_report(op->reports, RPT_WARNING, "View offset is locked"); + return true; + } + else { + return false; + } +} /* ********************** view3d_edit: view manipulations ********************* */ @@ -182,6 +179,27 @@ bool ED_view3d_camera_lock_sync(View3D *v3d, RegionView3D *rv3d) } } +/** + * For viewport operators that exit camera persp. + * + * \note This differs from simply setting ``rv3d->persp = persp`` because it + * sets the ``ofs`` and ``dist`` values of the viewport so it matches the camera, + * otherwise switching out of camera view may jump to a different part of the scene. + */ +static void view3d_persp_switch_from_camera(View3D *v3d, RegionView3D *rv3d, const char persp) +{ + BLI_assert(rv3d->persp == RV3D_CAMOB); + BLI_assert(persp != RV3D_CAMOB); + + if (v3d->camera) { + rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK); + ED_view3d_from_object(v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL); + } + + if (!ED_view3d_camera_lock_check(v3d, rv3d)) { + rv3d->persp = persp; + } +} /* ********************* box view support ***************** */ @@ -378,6 +396,7 @@ void ED_view3d_quadview_update(ScrArea *sa, ARegion *ar, bool do_clip) /* ************************** init for view ops **********************************/ typedef struct ViewOpsData { + /* context pointers (assigned by viewops_data_alloc) */ ScrArea *sa; ARegion *ar; View3D *v3d; @@ -435,10 +454,17 @@ static void calctrackballvec(const rcti *rect, int mx, int my, float vec[3]) } -static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *event) +/* -------------------------------------------------------------------- */ +/* ViewOpsData */ + +/** \name Generic View Operator Custom-Data. + * \{ */ + +/** + * Allocate and fill in context pointers for #ViewOpsData + */ +static void viewops_data_alloc(bContext *C, wmOperator *op) { - static float lastofs[3] = {0, 0, 0}; - RegionView3D *rv3d; ViewOpsData *vod = MEM_callocN(sizeof(ViewOpsData), "viewops data"); /* store data */ @@ -446,7 +472,17 @@ static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *even vod->sa = CTX_wm_area(C); vod->ar = CTX_wm_region(C); vod->v3d = vod->sa->spacedata.first; - vod->rv3d = rv3d = vod->ar->regiondata; + vod->rv3d = vod->ar->regiondata; +} + +/** + * Calculate the values for #ViewOpsData + */ +static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *event) +{ + ViewOpsData *vod = op->customdata; + static float lastofs[3] = {0, 0, 0}; + RegionView3D *rv3d = vod->rv3d; /* set the view from the camera, if view locking is enabled. * we may want to make this optional but for now its needed always */ @@ -589,6 +625,8 @@ static void viewops_data_free(bContext *C, wmOperator *op) if (p && (p->flags & PAINT_FAST_NAVIGATE)) ED_region_tag_redraw(ar); } +/** \} */ + /* ************************** viewrotate **********************************/ @@ -941,37 +979,27 @@ static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event) static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event) { ViewOpsData *vod; - RegionView3D *rv3d; /* makes op->customdata */ + viewops_data_alloc(C, op); viewops_data_create(C, op, event); vod = op->customdata; - rv3d = vod->rv3d; - if (rv3d->viewlock) { /* poll should check but in some cases fails, see poll func for details */ + if (vod->rv3d->viewlock) { /* poll should check but in some cases fails, see poll func for details */ viewops_data_free(C, op); return OPERATOR_PASS_THROUGH; } /* switch from camera view when: */ - if (rv3d->persp != RV3D_PERSP) { + if (vod->rv3d->persp != RV3D_PERSP) { if (U.uiflag & USER_AUTOPERSP) { if (!ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) { - rv3d->persp = RV3D_PERSP; + vod->rv3d->persp = RV3D_PERSP; } } - else if (rv3d->persp == RV3D_CAMOB) { - - /* changed since 2.4x, use the camera view */ - if (vod->v3d->camera) { - rv3d->dist = ED_view3d_offset_distance(vod->v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK); - ED_view3d_from_object(vod->v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL); - } - - if (!ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) { - rv3d->persp = rv3d->lpersp; - } + else if (vod->rv3d->persp == RV3D_CAMOB) { + view3d_persp_switch_from_camera(vod->v3d, vod->rv3d, vod->rv3d->lpersp); } ED_region_tag_redraw(vod->ar); } @@ -983,7 +1011,7 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event) else viewrotate_apply(vod, event->prevx, event->prevy); - ED_view3d_depth_tag_update(rv3d); + ED_view3d_depth_tag_update(vod->rv3d); viewops_data_free(C, op); @@ -992,7 +1020,7 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event) else if (event->type == MOUSEROTATE) { /* MOUSEROTATE performs orbital rotation, so y axis delta is set to 0 */ viewrotate_apply(vod, event->prevx, event->y); - ED_view3d_depth_tag_update(rv3d); + ED_view3d_depth_tag_update(vod->rv3d); viewops_data_free(C, op); @@ -1160,8 +1188,9 @@ static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, RegionView3D static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - if (event->type != NDOF_MOTION) + if (event->type != NDOF_MOTION) { return OPERATOR_CANCELLED; + } else { View3D *v3d = CTX_wm_view3d(C); ViewOpsData *vod; @@ -1170,6 +1199,7 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event) ED_view3d_camera_lock_init(v3d, rv3d); + viewops_data_alloc(C, op); viewops_data_create(C, op, event); vod = op->customdata; @@ -1227,7 +1257,7 @@ void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot) { /* identifiers */ ot->name = "NDOF Orbit View"; - ot->description = "Explore every angle of an object using the 3D mouse"; + ot->description = "Orbit the view using the 3D mouse"; ot->idname = "VIEW3D_OT_ndof_orbit"; /* api callbacks */ @@ -1242,8 +1272,9 @@ void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot) static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - if (event->type != NDOF_MOTION) + if (event->type != NDOF_MOTION) { return OPERATOR_CANCELLED; + } else { ViewOpsData *vod; View3D *v3d = CTX_wm_view3d(C); @@ -1254,6 +1285,7 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev rv3d->rot_angle = 0.f; /* off by default, until changed later this function */ + viewops_data_alloc(C, op); viewops_data_create(C, op, event); vod = op->customdata; @@ -1323,7 +1355,7 @@ void VIEW3D_OT_ndof_orbit_zoom(struct wmOperatorType *ot) { /* identifiers */ ot->name = "NDOF Orbit View with Zoom"; - ot->description = "Explore every angle of an object using the 3D mouse"; + ot->description = "Orbit and zoom the view using the 3D mouse"; ot->idname = "VIEW3D_OT_ndof_orbit_zoom"; /* api callbacks */ @@ -1339,14 +1371,16 @@ void VIEW3D_OT_ndof_orbit_zoom(struct wmOperatorType *ot) */ static int ndof_pan_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - if (event->type != NDOF_MOTION) + if (event->type != NDOF_MOTION) { return OPERATOR_CANCELLED; + } else { View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata; - VIEW3D_OP_OFS_LOCK_TEST(C, op); + if (view3d_operator_offset_lock_check(C, op)) + return OPERATOR_CANCELLED; ED_view3d_camera_lock_init(v3d, rv3d); @@ -1418,7 +1452,7 @@ void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot) { /* identifiers */ ot->name = "NDOF Pan View"; - ot->description = "Position your viewpoint with the 3D mouse"; + ot->description = "Pan the view with the 3D mouse"; ot->idname = "VIEW3D_OT_ndof_pan"; /* api callbacks */ @@ -1439,13 +1473,13 @@ static int ndof_all_invoke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_CANCELLED; } else { - ViewOpsData *vod; RegionView3D *rv3d; View3D *v3d = CTX_wm_view3d(C); wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata; + viewops_data_alloc(C, op); viewops_data_create(C, op, event); vod = op->customdata; rv3d = vod->rv3d; @@ -1509,7 +1543,7 @@ void VIEW3D_OT_ndof_all(struct wmOperatorType *ot) { /* identifiers */ ot->name = "NDOF Move View"; - ot->description = "Position your viewpoint with the 3D mouse"; + ot->description = "Pan and rotate the view with the 3D mouse"; ot->idname = "VIEW3D_OT_ndof_all"; /* api callbacks */ @@ -1644,6 +1678,7 @@ static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event) ViewOpsData *vod; /* makes op->customdata */ + viewops_data_alloc(C, op); viewops_data_create(C, op, event); vod = op->customdata; @@ -2010,6 +2045,7 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event) ViewOpsData *vod; /* makes op->customdata */ + viewops_data_alloc(C, op); viewops_data_create(C, op, event); vod = op->customdata; @@ -2224,12 +2260,34 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event) { ViewOpsData *vod; - VIEW3D_OP_OFS_LOCK_TEST(C, op); + if (view3d_operator_offset_lock_check(C, op)) + return OPERATOR_CANCELLED; /* makes op->customdata */ - viewops_data_create(C, op, event); + viewops_data_alloc(C, op); vod = op->customdata; + if (vod->rv3d->viewlock) { /* poll should check but in some cases fails, see poll func for details */ + viewops_data_free(C, op); + return OPERATOR_PASS_THROUGH; + } + + /* needs to run before 'viewops_data_create' so the backup 'rv3d->ofs' is correct */ + /* switch from camera view when: */ + if (vod->rv3d->persp != RV3D_PERSP) { + if (vod->rv3d->persp == RV3D_CAMOB) { + /* ignore rv3d->lpersp because dolly only makes sense in perspective mode */ + view3d_persp_switch_from_camera(vod->v3d, vod->rv3d, RV3D_PERSP); + } + else { + vod->rv3d->persp = RV3D_PERSP; + } + ED_region_tag_redraw(vod->ar); + } + + viewops_data_create(C, op, event); + + /* if one or the other zoom position aren't set, set from event */ if (!RNA_struct_property_is_set(op->ptr, "mx") || !RNA_struct_property_is_set(op->ptr, "my")) { RNA_int_set(op->ptr, "mx", event->x); @@ -2274,25 +2332,6 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_FINISHED; } -/* like ED_operator_region_view3d_active but check its not in ortho view */ -static int viewdolly_poll(bContext *C) -{ - RegionView3D *rv3d = CTX_wm_region_view3d(C); - - if (rv3d) { - if (rv3d->persp == RV3D_PERSP) { - return 1; - } - else { - View3D *v3d = CTX_wm_view3d(C); - if (ED_view3d_camera_lock_check(v3d, rv3d)) { - return 1; - } - } - } - return 0; -} - static int viewdolly_cancel(bContext *C, wmOperator *op) { viewops_data_free(C, op); @@ -2311,7 +2350,7 @@ void VIEW3D_OT_dolly(wmOperatorType *ot) ot->invoke = viewdolly_invoke; ot->exec = viewdolly_exec; ot->modal = viewdolly_modal; - ot->poll = viewdolly_poll; + ot->poll = ED_operator_region_view3d_active; ot->cancel = viewdolly_cancel; /* flags */ @@ -3703,6 +3742,7 @@ static int viewroll_invoke(bContext *C, wmOperator *op, const wmEvent *event) ViewOpsData *vod; /* makes op->customdata */ + viewops_data_alloc(C, op); viewops_data_create(C, op, event); vod = op->customdata; @@ -3780,7 +3820,8 @@ static int viewpan_exec(bContext *C, wmOperator *op) float zfac; int pandir; - VIEW3D_OP_OFS_LOCK_TEST(C, op); + if (view3d_operator_offset_lock_check(C, op)) + return OPERATOR_CANCELLED; pandir = RNA_enum_get(op->ptr, "type"); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index c812f1084e2..c48ce8a2343 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -160,7 +160,7 @@ static void edbm_backbuf_check_and_select_edges(BMEditMesh *em, const bool selec { BMEdge *eed; BMIter iter; - int index = bm_solidoffs; + unsigned int index = bm_solidoffs; BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { @@ -288,12 +288,12 @@ static int view3d_selectable_data(bContext *C) /* helper also for borderselect */ -static int edge_fully_inside_rect(const rctf *rect, const float v1[2], const float v2[2]) +static bool edge_fully_inside_rect(const rctf *rect, const float v1[2], const float v2[2]) { return BLI_rctf_isect_pt_v(rect, v1) && BLI_rctf_isect_pt_v(rect, v2); } -static int edge_inside_rect(const rctf *rect, const float v1[2], const float v2[2]) +static bool edge_inside_rect(const rctf *rect, const float v1[2], const float v2[2]) { int d1, d2, d3, d4; @@ -725,7 +725,7 @@ static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], sh { const int use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT); Object *ob = vc->obact; - Mesh *me = ob ? ob->data : NULL; + Mesh *me = ob->data; rcti rect; if (me == NULL || me->totvert == 0) @@ -764,7 +764,7 @@ static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], sh static void do_lasso_select_paintface(ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select) { Object *ob = vc->obact; - Mesh *me = ob ? ob->data : NULL; + Mesh *me = ob->data; rcti rect; if (me == NULL || me->totpoly == 0) @@ -2405,13 +2405,13 @@ static void mesh_circle_select(ViewContext *vc, const bool select, const int mva static void paint_facesel_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad) { Object *ob = vc->obact; - Mesh *me = ob ? ob->data : NULL; - /* int bbsel; */ /* UNUSED */ + Mesh *me = ob->data; + bool bbsel; - if (me) { - bm_vertoffs = me->totpoly + 1; /* max index array */ + bm_vertoffs = me->totpoly + 1; /* max index array */ - /* bbsel = */ /* UNUSED */ EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f)); + bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f)); + if (bbsel) { edbm_backbuf_check_and_select_tfaces(me, select); EDBM_backbuf_free(); paintface_flush_flags(ob); @@ -2431,15 +2431,17 @@ static void paint_vertsel_circle_select(ViewContext *vc, const bool select, cons const int use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT); Object *ob = vc->obact; Mesh *me = ob->data; - /* int bbsel; */ /* UNUSED */ + bool bbsel; /* CircleSelectUserData data = {NULL}; */ /* UNUSED */ if (use_zbuf) { bm_vertoffs = me->totvert + 1; /* max index array */ - /* bbsel = */ /* UNUSED */ EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f)); - edbm_backbuf_check_and_select_verts_obmode(me, select); - EDBM_backbuf_free(); + bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f)); + if (bbsel) { + edbm_backbuf_check_and_select_verts_obmode(me, select); + EDBM_backbuf_free(); + } } else { CircleSelectUserData data; diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 5f988edb950..7c29ab01c24 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -143,7 +143,7 @@ static void special_transvert_update(Object *obedit) } BKE_nurb_test2D(nu); - BKE_nurb_handles_test(nu); /* test for bezier too */ + BKE_nurb_handles_test(nu, true); /* test for bezier too */ nu = nu->next; } } diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 7e39c0b6be0..74d72061995 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -378,12 +378,15 @@ void VIEW3D_OT_smoothview(wmOperatorType *ot) /* identifiers */ ot->name = "Smooth View"; + ot->description = ""; ot->idname = "VIEW3D_OT_smoothview"; - ot->description = "The time to animate the change of view (in milliseconds)"; /* api callbacks */ ot->invoke = view3d_smoothview_invoke; + /* flags */ + ot->flag = OPTYPE_INTERNAL; + ot->poll = ED_operator_view3d_active; } @@ -1177,7 +1180,7 @@ static bool view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, Report return ok; } -static void restore_localviewdata(ScrArea *sa, int free) +static void restore_localviewdata(Main *bmain, ScrArea *sa, int free) { ARegion *ar; View3D *v3d = sa->spacedata.first; @@ -1214,12 +1217,7 @@ static void restore_localviewdata(ScrArea *sa, int free) } } - if (v3d->drawtype != OB_RENDER) { - if (rv3d->render_engine) { - RE_engine_free(rv3d->render_engine); - rv3d->render_engine = NULL; - } - } + ED_view3d_shade_update(bmain, v3d, sa); } } } @@ -1234,7 +1232,7 @@ static bool view3d_localview_exit(Main *bmain, Scene *scene, ScrArea *sa) locallay = v3d->lay & 0xFF000000; - restore_localviewdata(sa, 1); /* 1 = free */ + restore_localviewdata(bmain, sa, 1); /* 1 = free */ /* for when in other window the layers have changed */ if (v3d->scenelock) v3d->lay = scene->lay; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 87ef3d6742a..b08f66d0454 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1360,7 +1360,7 @@ int transformEvent(TransInfo *t, const wmEvent *event) } } -int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], int cent2d[2]) +int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], float cent2d[2]) { TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data"); int success; @@ -1390,7 +1390,7 @@ int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], int c calculateCenter(t); if (cent2d) { - copy_v2_v2_int(cent2d, t->center2d); + copy_v2_v2(cent2d, t->center2d); } if (cent3d) { @@ -2600,8 +2600,8 @@ void initWarp(TransInfo *t) t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; - t->snap[1] = 5.0f / 180.0f * (float)M_PI; - t->snap[2] = 1.0f / 180.0f * (float)M_PI; + t->snap[1] = DEG2RAD(5.0); + t->snap[2] = DEG2RAD(1.0); t->num.increment = 1.0f; @@ -3369,8 +3369,8 @@ void initRotation(TransInfo *t) t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; - t->snap[1] = (float)((5.0 / 180) * M_PI); - t->snap[2] = t->snap[1] * 0.2f; + t->snap[1] = DEG2RAD(5.0); + t->snap[2] = DEG2RAD(1.0); t->num.increment = 1.0f; @@ -3701,8 +3701,8 @@ void initTrackball(TransInfo *t) t->idx_max = 1; t->num.idx_max = 1; t->snap[0] = 0.0f; - t->snap[1] = (float)((5.0 / 180) * M_PI); - t->snap[2] = t->snap[1] * 0.2f; + t->snap[1] = DEG2RAD(5.0); + t->snap[2] = DEG2RAD(1.0); t->num.increment = 1.0f; @@ -4149,8 +4149,8 @@ void initTilt(TransInfo *t) t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; - t->snap[1] = (float)((5.0 / 180) * M_PI); - t->snap[2] = t->snap[1] * 0.2f; + t->snap[1] = DEG2RAD(5.0); + t->snap[2] = DEG2RAD(1.0); t->num.increment = t->snap[1]; @@ -4804,6 +4804,26 @@ static BMEdge *get_other_edge(BMVert *v, BMEdge *e) return NULL; } +/* interpoaltes along a line made up of 2 segments (used for edge slide) */ +static void interp_line_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float t) +{ + float t_mid, t_delta; + + /* could be pre-calculated */ + t_mid = line_point_factor_v3(v2, v1, v3); + + t_delta = t - t_mid; + if (fabsf(t_delta) < FLT_EPSILON) { + copy_v3_v3(p, v2); + } + else if (t_delta < 0.0f) { + interp_v3_v3v3(p, v1, v2, t / t_mid); + } + else { + interp_v3_v3v3(p, v2, v3, (t - t_mid) / (1.0f - t_mid)); + } +} + static void len_v3_ensure(float v[3], const float length) { normalize_v3(v); @@ -5716,20 +5736,16 @@ static void drawEdgeSlide(const struct bContext *C, TransInfo *t) /* Non-Prop mode */ if (sld && sld->is_proportional == FALSE) { View3D *v3d = CTX_wm_view3d(C); - float marker[3]; - float v1[3], v2[3]; - float interp_v; + float co_a[3], co_b[3], co_mark[3]; TransDataEdgeSlideVert *curr_sv = &sld->sv[sld->curr_sv_index]; + const float fac = (sld->perc + 1.0f) / 2.0f; const float ctrl_size = UI_GetThemeValuef(TH_FACEDOT_SIZE) + 1.5f; const float guide_size = ctrl_size - 0.5f; const float line_size = UI_GetThemeValuef(TH_OUTLINE_WIDTH) + 0.5f; const int alpha_shade = -30; - add_v3_v3v3(v1, curr_sv->v_co_orig, curr_sv->dir_a); - add_v3_v3v3(v2, curr_sv->v_co_orig, curr_sv->dir_b); - - interp_v = (sld->perc + 1.0f) / 2.0f; - interp_v3_v3v3(marker, v2, v1, interp_v); + add_v3_v3v3(co_a, curr_sv->v_co_orig, curr_sv->dir_a); + add_v3_v3v3(co_b, curr_sv->v_co_orig, curr_sv->dir_b); if (v3d && v3d->zbuf) glDisable(GL_DEPTH_TEST); @@ -5770,7 +5786,12 @@ static void drawEdgeSlide(const struct bContext *C, TransInfo *t) UI_ThemeColorShadeAlpha(TH_SELECT, 255, alpha_shade); glPointSize(guide_size); bglBegin(GL_POINTS); - bglVertex3fv(marker); +#if 0 + interp_v3_v3v3(co_mark, co_b, co_a, fac); + bglVertex3fv(co_mark); +#endif + interp_line_v3_v3v3v3(co_mark, co_b, curr_sv->v_co_orig, co_a, fac); + bglVertex3fv(co_mark); bglEnd(); @@ -5832,10 +5853,10 @@ static int doEdgeSlide(TransInfo *t, float perc) add_v3_v3v3(co_b, sv->v_co_orig, sv->dir_b); if (sld->flipped_vtx) { - interp_v3_v3v3(sv->v->co, co_b, co_a, fac); + interp_line_v3_v3v3v3(sv->v->co, co_b, sv->v_co_orig, co_a, fac); } else { - interp_v3_v3v3(sv->v->co, co_a, co_b, fac); + interp_line_v3_v3v3v3(sv->v->co, co_a, sv->v_co_orig, co_b, fac); } } } @@ -6414,8 +6435,8 @@ void initBoneRoll(TransInfo *t) t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; - t->snap[1] = (float)((5.0 / 180) * M_PI); - t->snap[2] = t->snap[1] * 0.2f; + t->snap[1] = DEG2RAD(5.0); + t->snap[2] = DEG2RAD(1.0); t->num.increment = 1.0f; @@ -7217,7 +7238,7 @@ int TimeSlide(TransInfo *t, const int mval[2]) void initTimeScale(TransInfo *t) { - int center[2]; + float center[2]; /* this tool is only really available in the Action Editor * AND NLA Editor (for strip scaling) @@ -7232,7 +7253,7 @@ void initTimeScale(TransInfo *t) /* recalculate center2d to use CFRA and mouse Y, since that's * what is used in time scale */ t->center[0] = t->scene->r.cfra; - projectIntView(t, t->center, center); + projectFloatView(t, t->center, center); center[1] = t->imval[1]; /* force a reinit with the center2d used here */ diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index a4828317604..9355773c47b 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -271,7 +271,7 @@ typedef struct MouseInput { int imval[2]; /* initial mouse position */ char precision; int precision_mval[2]; /* mouse position when precision key was pressed */ - int center[2]; + float center[2]; float factor; void *data; /* additional data, if needed by the particular function */ } MouseInput; @@ -300,7 +300,7 @@ typedef struct TransInfo { float prop_size; /* proportional circle radius */ char proptext[20]; /* proportional falloff text */ float center[3]; /* center of transformation */ - int center2d[2]; /* center in screen coordinates */ + float center2d[2]; /* center in screen coordinates */ int imval[2]; /* initial mouse position */ short event_type; /* event->type used to invoke transform */ short idx_max; /* maximum index on the input vector */ @@ -687,7 +687,7 @@ typedef enum { INPUT_CUSTOM_RATIO_FLIP } MouseInputMode; -void initMouseInput(TransInfo *t, MouseInput *mi, const int center[2], const int mval[2]); +void initMouseInput(TransInfo *t, MouseInput *mi, const float center[2], const int mval[2]); void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode); int handleMouseInput(struct TransInfo *t, struct MouseInput *mi, const struct wmEvent *event); void applyMouseInput(struct TransInfo *t, struct MouseInput *mi, const int mval[2], float output[3]); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index adfbbc26df2..f5a12fed076 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -123,6 +123,20 @@ #include "transform.h" #include "bmesh.h" +/** + * Transforming around ourselves is no use, fallback to individual origins, + * useful for curve/armatures. + */ +static void transform_around_single_fallback(TransInfo *t) +{ + if ((t->total == 1) && + (ELEM3(t->around, V3D_CENTER, V3D_CENTROID, V3D_ACTIVE)) && + (ELEM3(t->mode, TFM_RESIZE, TFM_ROTATION, TFM_TRACKBALL))) + { + t->around = V3D_LOCAL; + } +} + /* when transforming islands */ struct TransIslandData { float co[3]; @@ -1084,6 +1098,8 @@ static void createTransArmatureVerts(TransInfo *t) if (!t->total) return; + transform_around_single_fallback(t); + copy_m3_m4(mtx, t->obedit->obmat); pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); @@ -1408,6 +1424,8 @@ static void createTransCurveVerts(TransInfo *t) else t->total = countsel; t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Curve EditMode)"); + transform_around_single_fallback(t); + copy_m3_m4(mtx, t->obedit->obmat); pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); @@ -1443,7 +1461,9 @@ static void createTransCurveVerts(TransInfo *t) { copy_v3_v3(td->iloc, bezt->vec[0]); td->loc = bezt->vec[0]; - copy_v3_v3(td->center, bezt->vec[(hide_handles || bezt->f2 & SELECT) ? 1 : 0]); + copy_v3_v3(td->center, bezt->vec[(hide_handles || + (t->around == V3D_LOCAL) || + (bezt->f2 & SELECT)) ? 1 : 0]); if (hide_handles) { if (bezt->f2 & SELECT) td->flag = TD_SELECTED; else td->flag = 0; @@ -1511,7 +1531,9 @@ static void createTransCurveVerts(TransInfo *t) { copy_v3_v3(td->iloc, bezt->vec[2]); td->loc = bezt->vec[2]; - copy_v3_v3(td->center, bezt->vec[(hide_handles || bezt->f2 & SELECT) ? 1 : 2]); + copy_v3_v3(td->center, bezt->vec[(hide_handles || + (t->around == V3D_LOCAL) || + (bezt->f2 & SELECT)) ? 1 : 2]); if (hide_handles) { if (bezt->f2 & SELECT) td->flag = TD_SELECTED; else td->flag = 0; @@ -1552,7 +1574,7 @@ static void createTransCurveVerts(TransInfo *t) * but for now just don't change handle types */ if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT) == 0) { /* sets the handles based on their selection, do this after the data is copied to the TransData */ - BKE_nurb_handles_test(nu); + BKE_nurb_handles_test(nu, !hide_handles); } } else { @@ -2219,7 +2241,7 @@ static void createTransEditVerts(TransInfo *t) /* detect CrazySpace [tm] */ if (modifiers_getCageIndex(t->scene, t->obedit, NULL, 1) >= 0) { int totleft = -1; - if (modifiers_isCorrectableDeformed(t->obedit)) { + if (modifiers_isCorrectableDeformed(t->scene, t->obedit)) { /* check if we can use deform matrices for modifier from the * start up to stack, they are more accurate than quats */ totleft = editbmesh_get_first_deform_matrices(t->scene, t->obedit, em, &defmats, &defcos); @@ -2228,7 +2250,13 @@ static void createTransEditVerts(TransInfo *t) /* if we still have more modifiers, also do crazyspace * correction with quats, relative to the coordinates after * the modifiers that support deform matrices (defcos) */ - if ((totleft > 0) || (totleft == -1)) { + +#if 0 /* TODO, fix crazyspace+extrude so it can be enabled for general use - campbell */ + if ((totleft > 0) || (totleft == -1)) +#else + if (totleft > 0) +#endif + { mappedcos = crazyspace_get_mapped_editverts(t->scene, t->obedit); quats = MEM_mallocN(em->bm->totvert * sizeof(*quats), "crazy quats"); crazyspace_set_quats_editmesh(em, defcos, mappedcos, quats); @@ -3866,7 +3894,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) } /* if handles were not selected, store their selection status */ - if (!(sel1) && !(sel3)) { + if (!(sel1) || !(sel3)) { if (hdata == NULL) hdata = initTransDataCurveHandles(td, bezt); } diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 233ef1d18a5..b6f031614ca 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1484,10 +1484,10 @@ void calculateCenter2D(TransInfo *t) copy_v3_v3(vec, t->center); mul_m4_v3(ob->obmat, vec); - projectIntView(t, vec, t->center2d); + projectFloatView(t, vec, t->center2d); } else { - projectIntView(t, t->center, t->center2d); + projectFloatView(t, t->center, t->center2d); } } @@ -1691,7 +1691,7 @@ void calculateCenter(TransInfo *t) Object *ob = OBACT; if (ob) { copy_v3_v3(t->center, ob->obmat[3]); - projectIntView(t, t->center, t->center2d); + projectFloatView(t, t->center, t->center2d); } } break; @@ -1723,7 +1723,7 @@ void calculateCenter(TransInfo *t) axis[1] = t->center[1] - 6.0f * axis[1]; axis[2] = t->center[2] - 6.0f * axis[2]; - projectIntView(t, axis, t->center2d); + projectFloatView(t, axis, t->center2d); /* rotate only needs correct 2d center, grab needs ED_view3d_calc_zfac() value */ if (t->mode == TFM_TRANSLATION) { diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c index c035b6173c8..db214e1f6db 100644 --- a/source/blender/editors/transform/transform_input.c +++ b/source/blender/editors/transform/transform_input.c @@ -279,7 +279,7 @@ static void InputAngle(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2], output[0] = *angle; } -void initMouseInput(TransInfo *UNUSED(t), MouseInput *mi, const int center[2], const int mval[2]) +void initMouseInput(TransInfo *UNUSED(t), MouseInput *mi, const float center[2], const int mval[2]) { mi->factor = 0; mi->precision = 0; diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 6fecf0d6642..f667a98812b 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -428,12 +428,12 @@ int calc_manipulator_stats(const bContext *C) totsel++; } else { - if (bezt->f1) { - calc_tw_center(scene, bezt->vec[0]); + if (bezt->f1 & SELECT) { + calc_tw_center(scene, bezt->vec[(v3d->around == V3D_LOCAL) ? 1 : 0]); totsel++; } - if (bezt->f3) { - calc_tw_center(scene, bezt->vec[2]); + if (bezt->f3 & SELECT) { + calc_tw_center(scene, bezt->vec[(v3d->around == V3D_LOCAL) ? 1 : 2]); totsel++; } } @@ -1858,11 +1858,12 @@ int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op) * See [#34621], it's a miracle it did not cause more problems!!! */ /* However, we need to copy the "release_confirm" property... */ PointerRNA props_ptr; - WM_operator_properties_create(&props_ptr, "TRANSFORM_OT_trackball"); + wmOperatorType *ot = WM_operatortype_find("TRANSFORM_OT_trackball", true); + WM_operator_properties_create_ptr(&props_ptr, ot); RNA_boolean_set(&props_ptr, "release_confirm", RNA_boolean_get(op->ptr, "release_confirm")); - - WM_operator_name_call(C, "TRANSFORM_OT_trackball", WM_OP_INVOKE_DEFAULT, &props_ptr); - //wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_trackball", 0), event, NULL, NULL, FALSE); + WM_operator_name_call(C, ot->idname, WM_OP_INVOKE_DEFAULT, &props_ptr); + //wm_operator_invoke(C, WM_operatortype_find(ot->idname, 0), event, NULL, NULL, FALSE); + WM_operator_properties_free(&props_ptr); } else if (drawflags & MAN_ROT_C) { switch (drawflags) { diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index e7c22fc0899..2904b37c2e5 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -60,7 +60,7 @@ typedef struct TransformModeItem { void (*opfunc)(wmOperatorType *); } TransformModeItem; -static float VecOne[3] = {1, 1, 1}; +static const float VecOne[3] = {1, 1, 1}; static char OP_TRANSLATION[] = "TRANSFORM_OT_translate"; static char OP_ROTATION[] = "TRANSFORM_OT_rotate"; diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 55d80d63234..cd6a2e6712e 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -728,31 +728,46 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], } } else { + const bool use_handle = (cu->drawflag & CU_HIDE_HANDLES) == 0; + for (nu = nurbs->first; nu; nu = nu->next) { /* only bezier has a normal */ if (nu->type == CU_BEZIER) { bezt = nu->bezt; a = nu->pntsu; while (a--) { + short flag = 0; + +#define SEL_F1 (1 << 0) +#define SEL_F2 (1 << 1) +#define SEL_F3 (1 << 2) + + if (use_handle) { + if (bezt->f1 & SELECT) flag |= SEL_F1; + if (bezt->f2 & SELECT) flag |= SEL_F2; + if (bezt->f3 & SELECT) flag |= SEL_F3; + } + else { + flag = (bezt->f2 & SELECT) ? (SEL_F1 | SEL_F2 | SEL_F3) : 0; + } + /* exception */ - if ((bezt->f1 | bezt->f2 | bezt->f3) & SELECT) { + if (flag) { float tvec[3]; - if ((bezt->f1 & SELECT) + (bezt->f2 & SELECT) + (bezt->f3 & SELECT) > SELECT) { + if ((v3d->around == V3D_LOCAL) || + ELEM3(flag, SEL_F2, SEL_F1 | SEL_F3, SEL_F1 | SEL_F2 | SEL_F3)) + { BKE_nurb_bezt_calc_normal(nu, bezt, tvec); add_v3_v3(normal, tvec); } else { - if (bezt->f1 & SELECT) { + /* ignore bezt->f2 in this case */ + if (flag & SEL_F1) { sub_v3_v3v3(tvec, bezt->vec[0], bezt->vec[1]); normalize_v3(tvec); add_v3_v3(normal, tvec); } - if (bezt->f2 & SELECT) { - sub_v3_v3v3(tvec, bezt->vec[0], bezt->vec[2]); - normalize_v3(tvec); - add_v3_v3(normal, tvec); - } - if (bezt->f3 & SELECT) { + if (flag & SEL_F3) { sub_v3_v3v3(tvec, bezt->vec[1], bezt->vec[2]); normalize_v3(tvec); add_v3_v3(normal, tvec); @@ -762,6 +777,11 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], BKE_nurb_bezt_calc_plane(nu, bezt, tvec); add_v3_v3(plane, tvec); } + +#undef SEL_F1 +#undef SEL_F2 +#undef SEL_F3 + bezt++; } } diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 4a208f6eee1..04bccac2a15 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -134,7 +134,8 @@ bool validSnap(TransInfo *t) bool activeSnap(TransInfo *t) { - return (t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) == MOD_SNAP || (t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) == MOD_SNAP_INVERT; + return ((t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) == MOD_SNAP) || + ((t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) == MOD_SNAP_INVERT); } void drawSnapping(const struct bContext *C, TransInfo *t) diff --git a/source/blender/editors/util/crazyspace.c b/source/blender/editors/util/crazyspace.c index 06a70cf9277..ff65e11f53e 100644 --- a/source/blender/editors/util/crazyspace.c +++ b/source/blender/editors/util/crazyspace.c @@ -40,6 +40,7 @@ #include "BLI_utildefines.h" #include "BLI_math.h" +#include "BLI_bitmap.h" #include "BKE_DerivedMesh.h" #include "BKE_modifier.h" @@ -51,6 +52,7 @@ typedef struct { float (*vertexcos)[3]; + BLI_bitmap *vertex_visit; } MappedUserData; BLI_INLINE void tan_calc_v3(float a[3], const float b[3], const float c[3]) @@ -83,7 +85,14 @@ static void make_vertexcos__mapFunc(void *userData, int index, const float co[3] const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) { MappedUserData *mappedData = (MappedUserData *)userData; - copy_v3_v3(mappedData->vertexcos[index], co); + + if (BLI_BITMAP_GET(mappedData->vertex_visit, index) == 0) { + /* we need coord from prototype vertex, not from copies, + * assume they stored in the beginning of vertex array stored in DM + * (mirror modifier for eg does this) */ + copy_v3_v3(mappedData->vertexcos[index], co); + BLI_BITMAP_SET(mappedData->vertex_visit, index); + } } static int modifiers_disable_subsurf_temporary(Object *ob) @@ -108,6 +117,7 @@ float (*crazyspace_get_mapped_editverts(Scene *scene, Object *obedit))[3] DerivedMesh *dm; float (*vertexcos)[3]; int nverts = me->edit_btmesh->bm->totvert; + BLI_bitmap *vertex_visit; MappedUserData userData; /* disable subsurf temporal, get mapped cos, and enable it */ @@ -120,8 +130,10 @@ float (*crazyspace_get_mapped_editverts(Scene *scene, Object *obedit))[3] dm = editbmesh_get_derived_cage(scene, obedit, me->edit_btmesh, CD_MASK_BAREMESH); vertexcos = MEM_callocN(sizeof(*vertexcos) * nverts, "vertexcos map"); + vertex_visit = BLI_BITMAP_NEW(nverts, "vertexcos flags"); userData.vertexcos = vertexcos; + userData.vertex_visit = vertex_visit; dm->foreachMappedVert(dm, make_vertexcos__mapFunc, &userData, DM_FOREACH_NOP); dm->release(dm); @@ -129,6 +141,8 @@ float (*crazyspace_get_mapped_editverts(Scene *scene, Object *obedit))[3] /* set back the flag, no new cage needs to be built, transform does it */ modifiers_disable_subsurf_temporary(obedit); + MEM_freeN(vertex_visit); + return vertexcos; } diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index 35e6c40c36b..7424acd752f 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -258,7 +258,7 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *ar, void *arg_info) { wmWindow *win = CTX_wm_window(C); - const int *mval_src = (int *)arg_info; + const float *mval_src = (float *)arg_info; const int mval_dst[2] = {win->eventstate->x - ar->winrct.xmin, win->eventstate->y - ar->winrct.ymin}; @@ -266,7 +266,7 @@ void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *ar, void *arg_info setlinestyle(3); glBegin(GL_LINE_STRIP); glVertex2iv(mval_dst); - glVertex2iv(mval_src); + glVertex2fv(mval_src); glEnd(); setlinestyle(0); } diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index b8a54c56c63..2d33a2d3937 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -4123,7 +4123,7 @@ static void p_smooth(PChart *chart) MEM_freeN(nodesx); MEM_freeN(nodesy); - arena = BLI_memarena_new(1 << 16, "param smooth arena"); + arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "param smooth arena"); root = p_node_new(arena, tri, esize * 2, minv, maxv, 0); for (v = chart->verts; v; v = v->nextlink) @@ -4143,7 +4143,7 @@ ParamHandle *param_construct_begin(void) PHandle *handle = MEM_callocN(sizeof(*handle), "PHandle"); handle->construction_chart = p_chart_new(handle); handle->state = PHANDLE_STATE_ALLOCATED; - handle->arena = BLI_memarena_new((1 << 16), "param construct arena"); + handle->arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "param construct arena"); handle->aspx = 1.0f; handle->aspy = 1.0f; handle->do_aspect = FALSE; |