diff options
author | Campbell Barton <ideasman42@gmail.com> | 2014-10-07 12:22:47 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2014-10-07 12:25:29 +0400 |
commit | b09f7dcaa7b487ada53c8dbaa811deaa1201d163 (patch) | |
tree | 0e6bc07122f11b3c219ea334c87c945ebcf03c28 /source | |
parent | 3d00b8dea388788a52d116704ed06b5e29f920df (diff) | |
parent | 5e809c45edf253e828813b417770889f83a95bb6 (diff) |
Merge branch 'master' into dyntopo_holes
Diffstat (limited to 'source')
53 files changed, 730 insertions, 441 deletions
diff --git a/source/blender/avi/intern/avi_rgb.c b/source/blender/avi/intern/avi_rgb.c index c6a78eccce2..632ecad61a6 100644 --- a/source/blender/avi/intern/avi_rgb.c +++ b/source/blender/avi/intern/avi_rgb.c @@ -123,13 +123,12 @@ void *avi_converter_to_avi_rgb(AviMovie *movie, int stream, unsigned char *buffe (void)stream; /* unused */ - *size = movie->header->Height * movie->header->Width * 3; - if (movie->header->Width % 2) *size += movie->header->Height; - - buf = MEM_mallocN(*size, "toavirgbbuf"); - rowstride = movie->header->Width * 3; - if (movie->header->Width % 2) rowstride++; + /* AVI files has uncompressed lines 4-byte aligned */ + rowstride = (rowstride + 3) & ~3; + + *size = movie->header->Height * rowstride; + buf = MEM_mallocN(*size, "toavirgbbuf"); for (y = 0; y < movie->header->Height; y++) { memcpy(&buf[y * rowstride], &buffer[((movie->header->Height - 1) - y) * movie->header->Width * 3], movie->header->Width * 3); diff --git a/source/blender/avi/intern/avi_rgb32.c b/source/blender/avi/intern/avi_rgb32.c index 5c7a4889d97..c9cbcb05bb8 100644 --- a/source/blender/avi/intern/avi_rgb32.c +++ b/source/blender/avi/intern/avi_rgb32.c @@ -74,8 +74,8 @@ void *avi_converter_to_rgb32(AviMovie *movie, int stream, unsigned char *buffer, (void)stream; /* unused */ - buf = MEM_mallocN(movie->header->Height * movie->header->Width * 4, "torgb32buf"); *size = movie->header->Height * movie->header->Width * 4; + buf = MEM_mallocN(*size, "torgb32buf"); memset(buf, 255, *size); diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h index 80d2750fe82..e79822daa4d 100644 --- a/source/blender/blenkernel/BKE_animsys.h +++ b/source/blender/blenkernel/BKE_animsys.h @@ -37,8 +37,10 @@ struct Main; struct AnimData; struct KeyingSet; struct KS_Path; +struct bContext; struct PointerRNA; +struct PropertyRNA; struct ReportList; struct bAction; struct bActionGroup; @@ -127,6 +129,9 @@ void BKE_animdata_separate_by_basepath(struct ID *srcID, struct ID *dstID, struc /* Move F-Curves from src to destination if it's path is based on basepath */ void action_move_fcurves_by_basepath(struct bAction *srcAct, struct bAction *dstAct, const char basepath[]); +char *BKE_animdata_driver_path_hack(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, + char *base_path); + /* ************************************* */ /* Batch AnimData API */ diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index 0e86be9b97c..c377769b271 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -43,6 +43,7 @@ struct DriverVar; struct DriverTarget; struct FCM_EnvelopeData; +struct bContext; struct bAction; struct BezTriple; struct StructRNA; @@ -221,8 +222,12 @@ struct FCurve *id_data_find_fcurve(ID *id, void *data, struct StructRNA *type, c */ int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix, const char *dataName); -/* find an f-curve based on an rna property */ -struct FCurve *rna_get_fcurve(struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex, struct bAction **action, bool *r_driven); +/* find an f-curve based on an rna property. */ +struct FCurve *rna_get_fcurve(struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex, + struct bAction **action, bool *r_driven); +/* Same as above, but takes a context data, temp hack needed for complex paths like texture ones. */ +struct FCurve *rna_get_fcurve_context_ui(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, + int rnaindex, struct bAction **action, bool *r_driven); /* Binary search algorithm for finding where to 'insert' BezTriple with given frame number. * Returns the index to insert at (data already at that index will be offset if replace is 0) diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 4eafdae9ebd..b080ca37e67 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -50,6 +50,7 @@ struct PaintCurve; struct Palette; struct PaletteColor; struct PBVH; +struct ReportList; struct Scene; struct Sculpt; struct StrokeCache; @@ -121,6 +122,9 @@ struct Palette *BKE_paint_palette(struct Paint *paint); void BKE_paint_palette_set(struct Paint *p, struct Palette *palette); void BKE_paint_curve_set(struct Brush *br, struct PaintCurve *pc); +void BKE_paint_data_warning(struct ReportList *reports, bool uvs, bool mat, bool tex, bool stencil); +bool BKE_paint_proj_mesh_data_check(struct Scene *scene, struct Object *ob, bool *uvs, bool *mat, bool *tex, bool *stencil); + /* testing face select mode * Texture paint could be removed since selected faces are not used * however hiding faces is useful */ diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 5ee82bb5842..2fb832dc72d 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -51,18 +51,23 @@ #include "DNA_material_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" #include "DNA_texture_types.h" #include "DNA_world_types.h" #include "BKE_animsys.h" #include "BKE_action.h" +#include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_fcurve.h" #include "BKE_nla.h" #include "BKE_global.h" #include "BKE_main.h" +#include "BKE_material.h" #include "BKE_library.h" #include "BKE_report.h" +#include "BKE_texture.h" #include "RNA_access.h" @@ -551,6 +556,74 @@ void BKE_animdata_separate_by_basepath(ID *srcID, ID *dstID, ListBase *basepaths } } +/** + * Temporary wrapper for driver operators for buttons to make it easier to create + * such drivers by rerouting all paths through the active object instead so that + * they will get picked up by the dependency system. + * + * \param C Context pointer - for getting active data + * \param[in,out] ptr RNA pointer for property's datablock. May be modified as result of path remapping. + * \param prop RNA definition of property to add for + * \return MEM_alloc'd string representing the path to the property from the given #PointerRNA + */ +char *BKE_animdata_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *prop, char *base_path) +{ + ID *id = (ID *)ptr->id.data; + ScrArea *sa = CTX_wm_area(C); + + /* get standard path which may be extended */ + char *basepath = base_path ? base_path : RNA_path_from_ID_to_property(ptr, prop); + char *path = basepath; /* in case no remapping is needed */ + + /* Remapping will only be performed in the Properties Editor, as only this + * restricts the subspace of options to the 'active' data (a manageable state) + */ + /* TODO: watch out for pinned context? */ + if ((sa) && (sa->spacetype == SPACE_BUTS)) { + Object *ob = CTX_data_active_object(C); + + if (ob && id) { + /* only id-types which can be remapped to go through objects should be considered */ + switch (GS(id->name)) { + case ID_TE: /* textures */ + { + Material *ma = give_current_material(ob, ob->actcol); + Tex *tex = give_current_material_texture(ma); + + /* assumes: texture will only be shown if it is active material's active texture it's ok */ + if ((ID *)tex == id) { + char name_esc_ma[(sizeof(ma->id.name) - 2) * 2]; + char name_esc_tex[(sizeof(tex->id.name) - 2) * 2]; + + BLI_strescape(name_esc_ma, ma->id.name + 2, sizeof(name_esc_ma)); + BLI_strescape(name_esc_tex, tex->id.name + 2, sizeof(name_esc_tex)); + + /* create new path */ + // TODO: use RNA path functions to construct step by step instead? + // FIXME: maybe this isn't even needed anymore... + path = BLI_sprintfN("material_slots[\"%s\"].material.texture_slots[\"%s\"].texture.%s", + name_esc_ma, name_esc_tex, basepath); + + /* free old one */ + if (basepath != base_path) + MEM_freeN(basepath); + } + break; + } + } + + /* fix RNA pointer, as we've now changed the ID root by changing the paths */ + if (basepath != path) { + /* rebase provided pointer so that it starts from object... */ + RNA_pointer_create(&ob->id, ptr->type, ptr->data, ptr); + } + } + } + + /* the path should now have been corrected for use */ + return path; +} + /* Path Validation -------------------------------------------- */ /* Check if a given RNA Path is valid, by tracing it from the given ID, and seeing if we can resolve it */ diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 93bb4849718..44a0b93fc01 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -75,6 +75,7 @@ #include "BKE_mball.h" #include "BKE_modifier.h" #include "BKE_object.h" +#include "BKE_paint.h" #include "BKE_particle.h" #include "BKE_pointcache.h" #include "BKE_scene.h" @@ -2509,6 +2510,7 @@ static void dag_id_flush_update(Main *bmain, Scene *sce, ID *id) obt = sce->basact ? sce->basact->object : NULL; if (obt && obt->mode & OB_MODE_TEXTURE_PAINT) { BKE_texpaint_slots_refresh_object(sce, obt); + BKE_paint_proj_mesh_data_check(sce, obt, NULL, NULL, NULL, NULL); GPU_drawobject_free(obt->derivedFinal); } } diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 09c1dcf701d..e90a0891436 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -55,6 +55,7 @@ #include "BKE_action.h" #include "BKE_armature.h" #include "BKE_constraint.h" +#include "BKE_context.h" #include "BKE_curve.h" #include "BKE_global.h" #include "BKE_object.h" @@ -310,19 +311,35 @@ int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix, FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction **action, bool *r_driven) { + return rna_get_fcurve_context_ui(NULL, ptr, prop, rnaindex, action, r_driven); +} + +FCurve *rna_get_fcurve_context_ui(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int rnaindex, + bAction **action, bool *r_driven) +{ FCurve *fcu = NULL; + PointerRNA tptr = *ptr; *r_driven = false; /* there must be some RNA-pointer + property combon */ - if (prop && ptr->id.data && RNA_property_animateable(ptr, prop)) { - AnimData *adt = BKE_animdata_from_id(ptr->id.data); - char *path; + if (prop && tptr.id.data && RNA_property_animateable(&tptr, prop)) { + AnimData *adt = BKE_animdata_from_id(tptr.id.data); + int step = C ? 2 : 1; /* Always 1 in case we have no context (can't check in 'ancestors' of given RNA ptr). */ + char *path = NULL; - if (adt) { + if (!adt && C) { + path = BKE_animdata_driver_path_hack(C, &tptr, prop, NULL); + adt = BKE_animdata_from_id(tptr.id.data); + step--; + } + + while (adt && step--) { if ((adt->action && adt->action->curves.first) || (adt->drivers.first)) { /* XXX this function call can become a performance bottleneck */ - path = RNA_path_from_ID_to_property(ptr, prop); + if (step) { + path = RNA_path_from_ID_to_property(&tptr, prop); + } if (path) { /* animation takes priority over drivers */ @@ -337,13 +354,25 @@ FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction *r_driven = true; } - if (fcu && action) + if (fcu && action) { *action = adt->action; - - MEM_freeN(path); + break; + } + else if (step) { + char *tpath = BKE_animdata_driver_path_hack(C, &tptr, prop, path); + if (tpath && tpath != path) { + MEM_freeN(path); + path = tpath; + adt = BKE_animdata_from_id(tptr.id.data); + } + else { + adt = NULL; + } + } } } } + MEM_SAFE_FREE(path); } return fcu; diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c index e71fe71605c..28c01e0bdee 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.c +++ b/source/blender/blenkernel/intern/pbvh_bmesh.c @@ -1121,15 +1121,16 @@ static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx, PBVH *bvh, return any_subdivided; } -static void pbvh_bmesh_collapse_edge(PBVH *bvh, BMEdge *e, - BMVert *v1, BMVert *v2, - GSet *deleted_verts, - BLI_Buffer *edge_loops, - BLI_Buffer *deleted_faces, - EdgeQueueContext *eq_ctx) +static void pbvh_bmesh_collapse_edge( + PBVH *bvh, BMEdge *e, + BMVert *v1, BMVert *v2, + GSet *deleted_verts, + BLI_Buffer *deleted_faces, + EdgeQueueContext *eq_ctx) { BMIter bm_iter; BMFace *f; + BMLoop *l_adj; BMVert *v_del, *v_conn; int i; float mask_v1 = BM_ELEM_CD_GET_FLOAT(v1, eq_ctx->cd_vert_mask_offset); @@ -1144,15 +1145,11 @@ static void pbvh_bmesh_collapse_edge(PBVH *bvh, BMEdge *e, v_conn = v1; } - /* Get all faces adjacent to the edge */ - pbvh_bmesh_edge_loops(edge_loops, e); - /* Remove the merge vertex from the PBVH */ pbvh_bmesh_vert_remove(bvh, v_del, eq_ctx->cd_vert_node_offset, eq_ctx->cd_face_node_offset); /* Remove all faces adjacent to the edge */ - for (i = 0; i < edge_loops->count; i++) { - BMLoop *l_adj = BLI_buffer_at(edge_loops, BMLoop *, i); + while ((l_adj = e->l)) { BMFace *f_adj = l_adj->f; pbvh_bmesh_face_remove(bvh, f_adj, eq_ctx->cd_vert_node_offset, eq_ctx->cd_face_node_offset); @@ -1230,10 +1227,10 @@ static void pbvh_bmesh_collapse_edge(PBVH *bvh, BMEdge *e, BM_vert_kill(bvh->bm, v_del); } -static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx, - PBVH *bvh, - BLI_Buffer *edge_loops, - BLI_Buffer *deleted_faces) +static bool pbvh_bmesh_collapse_short_edges( + EdgeQueueContext *eq_ctx, + PBVH *bvh, + BLI_Buffer *deleted_faces) { float min_len_squared = bvh->bm_min_edge_len * bvh->bm_min_edge_len; GSet *deleted_verts; @@ -1277,7 +1274,7 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx, any_collapsed = true; pbvh_bmesh_collapse_edge(bvh, e, v1, v2, - deleted_verts, edge_loops, + deleted_verts, deleted_faces, eq_ctx); } @@ -1296,7 +1293,6 @@ static float len_to_tetrahedron_volume(float f) static bool pbvh_bmesh_collapse_small_tetrahedrons( EdgeQueueContext *eq_ctx, PBVH *bvh, - BLI_Buffer *edge_loops, BLI_Buffer *deleted_faces) { /* length as a tetrahedron volume, x1.5x to remove more... gives a bit nicer results */ @@ -1366,7 +1362,7 @@ static bool pbvh_bmesh_collapse_small_tetrahedrons( e_alt = BM_edge_create(bvh->bm, v1_alt, v2_alt, NULL, BM_CREATE_NO_DOUBLE); pbvh_bmesh_collapse_edge(bvh, e_alt, v1_alt, v2_alt, - deleted_verts, edge_loops, + deleted_verts, deleted_faces, eq_ctx); } @@ -2033,7 +2029,7 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode, short_edge_queue_create(&eq_ctx, bvh, center, radius); modified |= !BLI_heap_is_empty(q.heap); - pbvh_bmesh_collapse_short_edges(&eq_ctx, bvh, &edge_loops, + pbvh_bmesh_collapse_short_edges(&eq_ctx, bvh, &deleted_faces); BLI_heap_free(q.heap, NULL); BLI_mempool_destroy(queue_pool); @@ -2060,7 +2056,7 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode, EdgeQueueContext eq_ctx = {&q, queue_pool, bvh->bm, cd_vert_mask_offset, cd_vert_node_offset, cd_face_node_offset}; tetrahedron_edge_queue_create(&eq_ctx, bvh, center, radius); - pbvh_bmesh_collapse_small_tetrahedrons(&eq_ctx, bvh, &edge_loops, &deleted_faces); + pbvh_bmesh_collapse_small_tetrahedrons(&eq_ctx, bvh, &deleted_faces); BLI_heap_free(q.heap, NULL); BLI_mempool_destroy(queue_pool); } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 67b00a8c137..5bfd6e8a120 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -93,9 +93,6 @@ #include "bmesh.h" -//XXX #include "BIF_previewrender.h" -//XXX #include "BIF_editseq.h" - #ifdef WIN32 #else # include <sys/time.h> diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 86371ba3c80..8a272cd9d81 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -339,7 +339,7 @@ int BKE_text_reload(Text *text) char str[FILE_MAX]; BLI_stat_t st; - if (!text || !text->name) return 0; + if (!text->name) return 0; BLI_strncpy(str, text->name, FILE_MAX); BLI_path_abs(str, G.main->name); @@ -647,7 +647,7 @@ int BKE_text_file_modified_check(Text *text) int result; char file[FILE_MAX]; - if (!text || !text->name) + if (!text->name) return 0; BLI_strncpy(file, text->name, FILE_MAX); @@ -676,7 +676,7 @@ void BKE_text_file_modified_ignore(Text *text) int result; char file[FILE_MAX]; - if (!text || !text->name) return; + if (!text->name) return; BLI_strncpy(file, text->name, FILE_MAX); BLI_path_abs(file, G.main->name); @@ -742,9 +742,7 @@ static TextLine *txt_new_linen(const char *str, int n) void txt_clean_text(Text *text) { TextLine **top, **bot; - - if (!text) return; - + if (!text->lines.first) { if (text->lines.last) text->lines.first = text->lines.last; else text->lines.first = text->lines.last = txt_new_line(NULL); @@ -883,8 +881,7 @@ void txt_move_up(Text *text, const bool sel) { TextLine **linep; int *charp; - - if (!text) return; + if (sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; @@ -906,8 +903,7 @@ void txt_move_down(Text *text, const bool sel) { TextLine **linep; int *charp; - - if (!text) return; + if (sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; @@ -929,8 +925,7 @@ void txt_move_left(Text *text, const bool sel) TextLine **linep; int *charp; int tabsize = 0, i = 0; - - if (!text) return; + if (sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; @@ -974,8 +969,7 @@ void txt_move_right(Text *text, const bool sel) TextLine **linep; int *charp, i; bool do_tab = false; - - if (!text) return; + if (sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; @@ -1016,8 +1010,7 @@ void txt_jump_left(Text *text, const bool sel, const bool use_init_step) { TextLine **linep; int *charp; - - if (!text) return; + if (sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; @@ -1033,8 +1026,7 @@ void txt_jump_right(Text *text, const bool sel, const bool use_init_step) { TextLine **linep; int *charp; - - if (!text) return; + if (sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; @@ -1050,8 +1042,7 @@ void txt_move_bol(Text *text, const bool sel) { TextLine **linep; int *charp; - - if (!text) return; + if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; @@ -1065,8 +1056,7 @@ void txt_move_eol(Text *text, const bool sel) { TextLine **linep; int *charp; - - if (!text) return; + if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; @@ -1080,8 +1070,7 @@ void txt_move_bof(Text *text, const bool sel) { TextLine **linep; int *charp; - - if (!text) return; + if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; @@ -1096,8 +1085,7 @@ void txt_move_eof(Text *text, const bool sel) { TextLine **linep; int *charp; - - if (!text) return; + if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; @@ -1119,8 +1107,7 @@ void txt_move_to(Text *text, unsigned int line, unsigned int ch, const bool sel) TextLine **linep; int *charp; unsigned int i; - - if (!text) return; + if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; @@ -1157,7 +1144,6 @@ static void txt_curs_swap(Text *text) static void txt_pop_first(Text *text) { - if (txt_get_span(text->curl, text->sell) < 0 || (text->curl == text->sell && text->curc > text->selc)) { @@ -1186,7 +1172,6 @@ void txt_pop_sel(Text *text) void txt_order_cursors(Text *text, const bool reverse) { - if (!text) return; if (!text->curl) return; if (!text->sell) return; @@ -1216,8 +1201,7 @@ static void txt_delete_sel(Text *text) { TextLine *tmpl; char *buf; - - if (!text) return; + if (!text->curl) return; if (!text->sell) return; @@ -1253,8 +1237,6 @@ static void txt_delete_sel(Text *text) void txt_sel_all(Text *text) { - if (!text) return; - text->curl = text->lines.first; text->curc = 0; @@ -1277,7 +1259,6 @@ void txt_sel_clear(Text *text) void txt_sel_line(Text *text) { - if (!text) return; if (!text->curl) return; text->curc = 0; @@ -1295,8 +1276,7 @@ char *txt_to_buf(Text *text) TextLine *tmp, *linef, *linel; int charf, charl; char *buf; - - if (!text) return NULL; + if (!text->curl) return NULL; if (!text->sell) return NULL; if (!text->lines.first) return NULL; @@ -1358,7 +1338,7 @@ int txt_find_string(Text *text, const char *findstr, int wrap, int match_case) TextLine *tl, *startl; const char *s = NULL; - if (!text || !text->curl || !text->sell) return 0; + if (!text->curl || !text->sell) return 0; txt_order_cursors(text, false); @@ -1398,8 +1378,7 @@ char *txt_sel_to_buf(Text *text) int length = 0; TextLine *tmp, *linef, *linel; int charf, charl; - - if (!text) return NULL; + if (!text->curl) return NULL; if (!text->sell) return NULL; @@ -1480,7 +1459,6 @@ void txt_insert_buf(Text *text, const char *in_buffer) TextLine *add; char *buffer; - if (!text) return; if (!in_buffer) return; txt_delete_sel(text); @@ -2362,8 +2340,7 @@ void txt_split_curline(Text *text) { TextLine *ins; char *left, *right; - - if (!text) return; + if (!text->curl) return; txt_delete_sel(text); @@ -2405,7 +2382,6 @@ void txt_split_curline(Text *text) static void txt_delete_line(Text *text, TextLine *line) { - if (!text) return; if (!text->curl) return; BLI_remlink(&text->lines, line); @@ -2422,8 +2398,6 @@ static void txt_delete_line(Text *text, TextLine *line) static void txt_combine_lines(Text *text, TextLine *linea, TextLine *lineb) { char *tmp, *s; - - if (!text) return; if (!linea || !lineb) return; @@ -2447,7 +2421,7 @@ void txt_duplicate_line(Text *text) { TextLine *textline; - if (!text || !text->curl) return; + if (!text->curl) return; if (text->curl == text->sell) { textline = txt_new_line(text->curl->line); @@ -2463,8 +2437,7 @@ void txt_duplicate_line(Text *text) void txt_delete_char(Text *text) { unsigned int c = '\n'; - - if (!text) return; + if (!text->curl) return; if (txt_has_sel(text)) { /* deleting a selection */ @@ -2507,7 +2480,6 @@ void txt_backspace_char(Text *text) { unsigned int c = '\n'; - if (!text) return; if (!text->curl) return; if (txt_has_sel(text)) { /* deleting a selection */ @@ -2571,8 +2543,7 @@ static bool txt_add_char_intern(Text *text, unsigned int add, bool replace_tabs) { char *tmp, ch[BLI_UTF8_MAX]; size_t add_len; - - if (!text) return 0; + if (!text->curl) return 0; if (add == '\n') { @@ -2631,8 +2602,7 @@ bool txt_replace_char(Text *text, unsigned int add) unsigned int del; size_t del_size = 0, add_size; char ch[BLI_UTF8_MAX]; - - if (!text) return 0; + if (!text->curl) return 0; /* If text is selected or we're at the end of the line just use txt_add_char */ @@ -2686,7 +2656,7 @@ void txt_indent(Text *text) /* hardcoded: TXT_TABSIZE = 4 spaces: */ int spaceslen = TXT_TABSIZE; - if (ELEM(NULL, text, text->curl, text->sell)) { + if (ELEM(NULL, text->curl, text->sell)) { return; } @@ -2753,7 +2723,7 @@ void txt_unindent(Text *text) /* hardcoded: TXT_TABSIZE = 4 spaces: */ int spaceslen = TXT_TABSIZE; - if (ELEM(NULL, text, text->curl, text->sell)) { + if (ELEM(NULL, text->curl, text->sell)) { return; } @@ -2806,8 +2776,7 @@ void txt_comment(Text *text) int len, num; char *tmp; char add = '#'; - - if (!text) return; + if (!text->curl) return; if (!text->sell) return; // Need to change this need to check if only one line is selected to more than one @@ -2854,8 +2823,7 @@ void txt_uncomment(Text *text) { int num = 0; char remove = '#'; - - if (!text) return; + if (!text->curl) return; if (!text->sell) return; @@ -2901,7 +2869,7 @@ void txt_move_lines(struct Text *text, const int direction) BLI_assert(ELEM(direction, TXT_MOVE_LINE_UP, TXT_MOVE_LINE_DOWN)); - if (!text || !text->curl || !text->sell) return; + if (!text->curl || !text->sell) return; txt_order_cursors(text, false); @@ -2934,6 +2902,7 @@ int txt_setcurr_tab_spaces(Text *text, int space) const char *comm = "#"; const char indent = (text->flags & TXT_TABSTOSPACES) ? ' ' : '\t'; static const char *back_words[] = {"return", "break", "continue", "pass", "yield", NULL}; + if (!text->curl) return 0; while (text->curl->line[i] == indent) { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 7aadf4a51ea..aea35963269 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6238,7 +6238,6 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype) rv3d->depths = NULL; rv3d->gpuoffscreen = NULL; - rv3d->ri = NULL; rv3d->render_engine = NULL; rv3d->sms = NULL; rv3d->smooth_timer = NULL; diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index 06d871c8db0..40b756a3f7c 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -89,9 +89,6 @@ #include "NOD_socket.h" -//XXX #include "BIF_butspace.h" // badlevel, for do_versions, patching event codes -//XXX #include "BIF_filelist.h" // badlevel too, where to move this? - elubie -//XXX #include "BIF_previewrender.h" // bedlelvel, for struct RenderInfo #include "BLO_readfile.h" #include "BLO_undofile.h" diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 9a1914b5596..a8e1acd9c71 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -666,49 +666,25 @@ static bool line_crosses_v2f(const float v1[2], const float v2[2], const float v */ bool BM_face_point_inside_test(BMFace *f, const float co[3]) { - int ax, ay; - float co2[2], cent[2] = {0.0f, 0.0f}, out[2] = {FLT_MAX * 0.5f, FLT_MAX * 0.5f}; + float axis_mat[3][3]; + float (*projverts)[2] = BLI_array_alloca(projverts, f->len); + + float co_2d[2]; BMLoop *l_iter; - BMLoop *l_first; - int crosses = 0; - float onepluseps = 1.0f + (float)FLT_EPSILON * 150.0f; + int i; if (is_zero_v3(f->no)) BM_face_normal_update(f); - - /* find best projection of face XY, XZ or YZ: barycentric weights of - * the 2d projected coords are the same and faster to compute - * - * this probably isn't all that accurate, but it has the advantage of - * being fast (especially compared to projecting into the face orientation) - */ - axis_dominant_v3(&ax, &ay, f->no); - - co2[0] = co[ax]; - co2[1] = co[ay]; - - l_iter = l_first = BM_FACE_FIRST_LOOP(f); - do { - cent[0] += l_iter->v->co[ax]; - cent[1] += l_iter->v->co[ay]; - } while ((l_iter = l_iter->next) != l_first); - - mul_v2_fl(cent, 1.0f / (float)f->len); - - l_iter = l_first = BM_FACE_FIRST_LOOP(f); - do { - float v1[2], v2[2]; - - v1[0] = (l_iter->prev->v->co[ax] - cent[0]) * onepluseps + cent[0]; - v1[1] = (l_iter->prev->v->co[ay] - cent[1]) * onepluseps + cent[1]; - - v2[0] = (l_iter->v->co[ax] - cent[0]) * onepluseps + cent[0]; - v2[1] = (l_iter->v->co[ay] - cent[1]) * onepluseps + cent[1]; - - crosses += line_crosses_v2f(v1, v2, co2, out) != 0; - } while ((l_iter = l_iter->next) != l_first); - - return crosses % 2 != 0; + + axis_dominant_v3_to_m3(axis_mat, f->no); + + mul_v2_m3v3(co_2d, axis_mat, co); + + for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l_iter = l_iter->next) { + mul_v2_m3v3(projverts[i], axis_mat, l_iter->v->co); + } + + return isect_point_poly_v2(co_2d, (const float (*)[2])projverts, f->len, false); } /** diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 685e5443583..40e0356e14c 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -311,7 +311,7 @@ BMLoop *BM_vert_find_first_loop(BMVert *v) { BMEdge *e; - if (!v || !v->e) + if (!v->e) return NULL; e = bmesh_disk_faceedge_find_first(v->e, v); diff --git a/source/blender/bmesh/tools/bmesh_region_match.c b/source/blender/bmesh/tools/bmesh_region_match.c index 224e9a15a38..050d5ae4808 100644 --- a/source/blender/bmesh/tools/bmesh_region_match.c +++ b/source/blender/bmesh/tools/bmesh_region_match.c @@ -993,14 +993,14 @@ static SUID_Int bm_face_region_vert_boundary_id(BMVert *v) #define PRIME_VERT_MID_A 103 #define PRIME_VERT_MID_B 131 - unsigned int tot = 0; + int tot = 0; BMIter iter; BMLoop *l; SUID_Int id = PRIME_VERT_MID_A; BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) { const bool is_boundary_vert = (bm_edge_is_region_boundary(l->e) || bm_edge_is_region_boundary(l->prev->e)); - id ^= (unsigned int)l->f->len * (is_boundary_vert ? PRIME_VERT_SMALL_A : PRIME_VERT_SMALL_B); + id ^= l->f->len * (is_boundary_vert ? PRIME_VERT_SMALL_A : PRIME_VERT_SMALL_B); tot += 1; } diff --git a/source/blender/compositor/nodes/COM_BlurNode.cpp b/source/blender/compositor/nodes/COM_BlurNode.cpp index 76e52c14685..f3d0c33d3b3 100644 --- a/source/blender/compositor/nodes/COM_BlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BlurNode.cpp @@ -105,6 +105,7 @@ void BlurNode::convertToOperations(NodeConverter &converter, const CompositorCon GaussianXBlurOperation *operationx = new GaussianXBlurOperation(); operationx->setData(data); operationx->setQuality(quality); + operationx->checkOpenCL(); converter.addOperation(operationx); converter.mapInputSocket(getInputSocket(1), operationx->getInputSocket(1)); @@ -112,6 +113,7 @@ void BlurNode::convertToOperations(NodeConverter &converter, const CompositorCon GaussianYBlurOperation *operationy = new GaussianYBlurOperation(); operationy->setData(data); operationy->setQuality(quality); + operationy->checkOpenCL(); converter.addOperation(operationy); converter.mapInputSocket(getInputSocket(1), operationy->getInputSocket(1)); diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp index 0aefba3bb7c..0838d281de7 100644 --- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp @@ -21,6 +21,7 @@ */ #include "COM_GaussianXBlurOperation.h" +#include "COM_OpenCLDevice.h" #include "BLI_math.h" #include "MEM_guardedalloc.h" @@ -124,6 +125,32 @@ void GaussianXBlurOperation::executePixel(float output[4], int x, int y, void *d mul_v4_v4fl(output, color_accum, 1.0f / multiplier_accum); } +void GaussianXBlurOperation::executeOpenCL(OpenCLDevice *device, + MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, + MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, + list<cl_kernel> *clKernelsToCleanUp) +{ + cl_kernel gaussianXBlurOperationKernel = device->COM_clCreateKernel("gaussianXBlurOperationKernel", NULL); + cl_int filter_size = this->m_filtersize; + + cl_mem gausstab = clCreateBuffer(device->getContext(), + CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, + sizeof(float) * (this->m_filtersize * 2 + 1), + this->m_gausstab, + NULL); + + device->COM_clAttachMemoryBufferToKernelParameter(gaussianXBlurOperationKernel, 0, 1, clMemToCleanUp, inputMemoryBuffers, this->m_inputProgram); + device->COM_clAttachOutputMemoryBufferToKernelParameter(gaussianXBlurOperationKernel, 2, clOutputBuffer); + device->COM_clAttachMemoryBufferOffsetToKernelParameter(gaussianXBlurOperationKernel, 3, outputMemoryBuffer); + clSetKernelArg(gaussianXBlurOperationKernel, 4, sizeof(cl_int), &filter_size); + device->COM_clAttachSizeToKernelParameter(gaussianXBlurOperationKernel, 5, this); + clSetKernelArg(gaussianXBlurOperationKernel, 6, sizeof(cl_mem), &gausstab); + + device->COM_clEnqueueRange(gaussianXBlurOperationKernel, outputMemoryBuffer, 7, this); + + clReleaseMemObject(gausstab); +} + void GaussianXBlurOperation::deinitExecution() { BlurBaseOperation::deinitExecution(); diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.h b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h index e391320a007..d7ae8b1e3dc 100644 --- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h @@ -40,7 +40,12 @@ public: * @brief the inner loop of this program */ void executePixel(float output[4], int x, int y, void *data); - + + void executeOpenCL(OpenCLDevice *device, + MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, + MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, + list<cl_kernel> *clKernelsToCleanUp); + /** * @brief initialize the execution */ @@ -53,5 +58,9 @@ public: void *initializeTileData(rcti *rect); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + + void checkOpenCL() { + this->setOpenCL(m_data.sizex >= 128); + } }; #endif diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp index a05a1ab6a23..6172f954087 100644 --- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp @@ -21,6 +21,7 @@ */ #include "COM_GaussianYBlurOperation.h" +#include "COM_OpenCLDevice.h" #include "BLI_math.h" #include "MEM_guardedalloc.h" @@ -126,6 +127,32 @@ void GaussianYBlurOperation::executePixel(float output[4], int x, int y, void *d mul_v4_v4fl(output, color_accum, 1.0f / multiplier_accum); } +void GaussianYBlurOperation::executeOpenCL(OpenCLDevice *device, + MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, + MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, + list<cl_kernel> *clKernelsToCleanUp) +{ + cl_kernel gaussianYBlurOperationKernel = device->COM_clCreateKernel("gaussianYBlurOperationKernel", NULL); + cl_int filter_size = this->m_filtersize; + + cl_mem gausstab = clCreateBuffer(device->getContext(), + CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, + sizeof(float) * (this->m_filtersize * 2 + 1), + this->m_gausstab, + NULL); + + device->COM_clAttachMemoryBufferToKernelParameter(gaussianYBlurOperationKernel, 0, 1, clMemToCleanUp, inputMemoryBuffers, this->m_inputProgram); + device->COM_clAttachOutputMemoryBufferToKernelParameter(gaussianYBlurOperationKernel, 2, clOutputBuffer); + device->COM_clAttachMemoryBufferOffsetToKernelParameter(gaussianYBlurOperationKernel, 3, outputMemoryBuffer); + clSetKernelArg(gaussianYBlurOperationKernel, 4, sizeof(cl_int), &filter_size); + device->COM_clAttachSizeToKernelParameter(gaussianYBlurOperationKernel, 5, this); + clSetKernelArg(gaussianYBlurOperationKernel, 6, sizeof(cl_mem), &gausstab); + + device->COM_clEnqueueRange(gaussianYBlurOperationKernel, outputMemoryBuffer, 7, this); + + clReleaseMemObject(gausstab); +} + void GaussianYBlurOperation::deinitExecution() { BlurBaseOperation::deinitExecution(); diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.h b/source/blender/compositor/operations/COM_GaussianYBlurOperation.h index 22b6562077d..4b5751c0968 100644 --- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.h @@ -40,7 +40,12 @@ public: * the inner loop of this program */ void executePixel(float output[4], int x, int y, void *data); - + + void executeOpenCL(OpenCLDevice *device, + MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, + MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, + list<cl_kernel> *clKernelsToCleanUp); + /** * @brief initialize the execution */ @@ -53,5 +58,9 @@ public: void *initializeTileData(rcti *rect); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + + void checkOpenCL() { + this->setOpenCL(m_data.sizex >= 128); + } }; #endif diff --git a/source/blender/compositor/operations/COM_MixOperation.h b/source/blender/compositor/operations/COM_MixOperation.h index 479ce161eea..d399edba6e9 100644 --- a/source/blender/compositor/operations/COM_MixOperation.h +++ b/source/blender/compositor/operations/COM_MixOperation.h @@ -76,7 +76,7 @@ public: void setUseValueAlphaMultiply(const bool value) { this->m_valueAlphaMultiply = value; } - bool useValueAlphaMultiply() { return this->m_valueAlphaMultiply; } + inline bool useValueAlphaMultiply() { return this->m_valueAlphaMultiply; } void setUseClamp(bool value) { this->m_useClamp = value; } }; diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl b/source/blender/compositor/operations/COM_OpenCLKernels.cl index 00b3825d8b3..1b965eb8659 100644 --- a/source/blender/compositor/operations/COM_OpenCLKernels.cl +++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl @@ -250,3 +250,66 @@ __kernel void directionalBlurKernel(__read_only image2d_t inputImage, __write_o write_imagef(output, coords, col); } + +// KERNEL --- GAUSSIAN BLUR --- +__kernel void gaussianXBlurOperationKernel(__read_only image2d_t inputImage, + int2 offsetInput, + __write_only image2d_t output, + int2 offsetOutput, + int filter_size, + int2 dimension, + __global float *gausstab, + int2 offset) +{ + float4 color = {0.0f, 0.0f, 0.0f, 0.0f}; + int2 coords = {get_global_id(0), get_global_id(1)}; + coords += offset; + const int2 realCoordinate = coords + offsetOutput; + int2 inputCoordinate = realCoordinate - offsetInput; + float weight = 0.0f; + + int xmin = max(realCoordinate.x - filter_size, 0) - offsetInput.x; + int xmax = min(realCoordinate.x + filter_size + 1, dimension.x) - offsetInput.x; + + for (int nx = xmin, i = max(filter_size - realCoordinate.x, 0); nx < xmax; ++nx, ++i) { + float w = gausstab[i]; + inputCoordinate.x = nx; + color += read_imagef(inputImage, SAMPLER_NEAREST, inputCoordinate) * w; + weight += w; + } + + color *= (1.0f / weight); + + write_imagef(output, coords, color); +} + +__kernel void gaussianYBlurOperationKernel(__read_only image2d_t inputImage, + int2 offsetInput, + __write_only image2d_t output, + int2 offsetOutput, + int filter_size, + int2 dimension, + __global float *gausstab, + int2 offset) +{ + float4 color = {0.0f, 0.0f, 0.0f, 0.0f}; + int2 coords = {get_global_id(0), get_global_id(1)}; + coords += offset; + const int2 realCoordinate = coords + offsetOutput; + int2 inputCoordinate = realCoordinate - offsetInput; + float weight = 0.0f; + + int ymin = max(realCoordinate.y - filter_size, 0) - offsetInput.y; + int ymax = min(realCoordinate.y + filter_size + 1, dimension.y) - offsetInput.y; + + for (int ny = ymin, i = max(filter_size - realCoordinate.y, 0); ny < ymax; ++ny, ++i) { + float w = gausstab[i]; + inputCoordinate.y = ny; + color += read_imagef(inputImage, SAMPLER_NEAREST, inputCoordinate) * w; + weight += w; + } + + color *= (1.0f / weight); + + write_imagef(output, coords, color); +} diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index 481912f4d1f..296a52e7f20 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -426,74 +426,6 @@ bool ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int a /* ************************************************** */ /* UI-Button Interface */ -/** - * Temporary wrapper for driver operators for buttons to make it easier to create - * such drivers by rerouting all paths through the active object instead so that - * they will get picked up by the dependency system. - * - * \param C Context pointer - for getting active data - * \param[in,out] ptr RNA pointer for property's datablock. May be modified as result of path remapping. - * \param prop RNA definition of property to add for - * \return MEM_alloc'd string representing the path to the property from the given #PointerRNA - */ -static char *get_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *prop) -{ - ID *id = (ID *)ptr->id.data; - ScrArea *sa = CTX_wm_area(C); - - /* get standard path which may be extended */ - char *basepath = RNA_path_from_ID_to_property(ptr, prop); - char *path = basepath; /* in case no remapping is needed */ - - - /* Remapping will only be performed in the Properties Editor, as only this - * restricts the subspace of options to the 'active' data (a manageable state) - */ - // TODO: watch out for pinned context? - if ((sa) && (sa->spacetype == SPACE_BUTS)) { - Object *ob = CTX_data_active_object(C); - - if (ob && id) { - /* only id-types which can be remapped to go through objects should be considered */ - switch (GS(id->name)) { - case ID_TE: /* textures */ - { - Material *ma = give_current_material(ob, ob->actcol); - Tex *tex = give_current_material_texture(ma); - - /* assumes: texture will only be shown if it is active material's active texture it's ok */ - if ((ID *)tex == id) { - char name_esc_ma[(sizeof(ma->id.name) - 2) * 2]; - char name_esc_tex[(sizeof(tex->id.name) - 2) * 2]; - - BLI_strescape(name_esc_ma, ma->id.name + 2, sizeof(name_esc_ma)); - BLI_strescape(name_esc_tex, tex->id.name + 2, sizeof(name_esc_tex)); - - /* create new path */ - // TODO: use RNA path functions to construct step by step instead? - // FIXME: maybe this isn't even needed anymore... - path = BLI_sprintfN("material_slots[\"%s\"].material.texture_slots[\"%s\"].texture.%s", - name_esc_ma, name_esc_tex, basepath); - - /* free old one */ - MEM_freeN(basepath); - } - break; - } - } - - /* fix RNA pointer, as we've now changed the ID root by changing the paths */ - if (basepath != path) { - /* rebase provided pointer so that it starts from object... */ - RNA_pointer_create(&ob->id, ptr->type, ptr->data, ptr); - } - } - } - - /* the path should now have been corrected for use */ - return path; -} - /* Add Driver Button Operator ------------------------ */ static int add_driver_button_exec(bContext *C, wmOperator *op) @@ -511,7 +443,7 @@ static int add_driver_button_exec(bContext *C, wmOperator *op) index = -1; if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) { - char *path = get_driver_path_hack(C, &ptr, prop); + char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL); short flags = CREATEDRIVER_WITH_DEFAULT_DVAR; if (path) { @@ -566,7 +498,7 @@ static int remove_driver_button_exec(bContext *C, wmOperator *op) index = -1; if (ptr.id.data && ptr.data && prop) { - char *path = get_driver_path_hack(C, &ptr, prop); + char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL); success = ANIM_remove_driver(op->reports, ptr.id.data, path, index, 0); MEM_freeN(path); @@ -613,7 +545,7 @@ static int copy_driver_button_exec(bContext *C, wmOperator *op) uiContextActiveProperty(C, &ptr, &prop, &index); if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) { - char *path = get_driver_path_hack(C, &ptr, prop); + char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL); if (path) { /* only copy the driver for the button that this was involved for */ @@ -657,7 +589,7 @@ static int paste_driver_button_exec(bContext *C, wmOperator *op) uiContextActiveProperty(C, &ptr, &prop, &index); if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) { - char *path = get_driver_path_hack(C, &ptr, prop); + char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL); if (path) { /* only copy the driver for the button that this was involved for */ diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h index 14595a4c668..ab1dbabe793 100644 --- a/source/blender/editors/include/ED_render.h +++ b/source/blender/editors/include/ED_render.h @@ -35,7 +35,6 @@ struct ID; struct Main; struct MTex; struct Render; -struct RenderInfo; struct Scene; struct ScrArea; struct RegionView3D; @@ -56,18 +55,6 @@ void ED_render_scene_update(struct Main *bmain, struct Scene *scene, int updated void ED_viewport_render_kill_jobs(const struct bContext *C, bool free_database); struct Scene *ED_render_job_get_scene(const struct bContext *C); -/* render_preview.c */ - -/* stores rendered preview - is also used for icons */ -typedef struct RenderInfo { - int pr_rectx; - int pr_recty; - short curtile, tottile; - rcti disprect; /* storage for view3d preview rect */ - unsigned int *rect; - struct Render *re; /* persistent render */ -} RenderInfo; - /* Render the preview * * pr_method: diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c index fa0832b6273..48e54270e95 100644 --- a/source/blender/editors/interface/interface_anim.c +++ b/source/blender/editors/interface/interface_anim.c @@ -61,7 +61,7 @@ static FCurve *ui_but_get_fcurve(uiBut *but, bAction **action, bool *r_driven) * but works well enough in typical cases */ int rnaindex = (but->rnaindex == -1) ? 0 : but->rnaindex; - return rna_get_fcurve(&but->rnapoin, but->rnaprop, rnaindex, action, r_driven); + return rna_get_fcurve_context_ui(but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, action, r_driven); } void ui_but_anim_flag(uiBut *but, float cfra) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index d3c9ec1fafb..9138ac92ab9 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -3111,8 +3111,9 @@ static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, c } } else if (data->state == BUTTON_STATE_WAIT_KEY_EVENT) { - if (event->type == MOUSEMOVE) + if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { return WM_UI_HANDLER_CONTINUE; + } if (event->val == KM_PRESS) { if (WM_key_event_string(event->type)[0]) diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 76c41adf444..f5a7e82a8a8 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -2157,7 +2157,7 @@ static ListBase *find_hole(KnifeTool_OpData *kcd, ListBase *fedges) static bool find_hole_chains(KnifeTool_OpData *kcd, ListBase *hole, BMFace *f, ListBase **mainchain, ListBase **sidechain) { - float **fco, **hco; + float (*fco)[2], (*hco)[2]; BMVert **fv; KnifeVert **hv; KnifeEdge **he; @@ -2179,8 +2179,8 @@ static bool find_hole_chains(KnifeTool_OpData *kcd, ListBase *hole, BMFace *f, L /* Gather 2d projections of hole and face vertex coordinates. * Use best-axis projection - not completely accurate, maybe revisit */ axis_dominant_v3(&ax, &ay, f->no); - hco = BLI_memarena_alloc(kcd->arena, nh * sizeof(float *)); - fco = BLI_memarena_alloc(kcd->arena, nf * sizeof(float *)); + hco = BLI_memarena_alloc(kcd->arena, nh * sizeof(float[2])); + fco = BLI_memarena_alloc(kcd->arena, nf * sizeof(float[2])); hv = BLI_memarena_alloc(kcd->arena, nh * sizeof(KnifeVert *)); fv = BLI_memarena_alloc(kcd->arena, nf * sizeof(BMVert *)); he = BLI_memarena_alloc(kcd->arena, nh * sizeof(KnifeEdge *)); @@ -2198,7 +2198,6 @@ static bool find_hole_chains(KnifeTool_OpData *kcd, ListBase *hole, BMFace *f, L kfv = kfvother; BLI_assert(kfv == kfe->v1 || kfv == kfe->v2); } - hco[i] = BLI_memarena_alloc(kcd->arena, 2 * sizeof(float)); hco[i][0] = kfv->co[ax]; hco[i][1] = kfv->co[ay]; hv[i] = kfv; @@ -2208,7 +2207,6 @@ static bool find_hole_chains(KnifeTool_OpData *kcd, ListBase *hole, BMFace *f, L j = 0; BM_ITER_ELEM (v, &iter, f, BM_VERTS_OF_FACE) { - fco[j] = BLI_memarena_alloc(kcd->arena, 2 * sizeof(float)); fco[j][0] = v->co[ax]; fco[j][1] = v->co[ay]; fv[j] = v; diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index bf8559add6f..68471bfc2ba 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -47,6 +47,7 @@ #include "BKE_library.h" #include "BKE_main.h" #include "BKE_mesh.h" +#include "BKE_paint.h" #include "BKE_report.h" #include "BKE_editmesh.h" @@ -502,6 +503,12 @@ static int mesh_uv_texture_add_exec(bContext *C, wmOperator *UNUSED(op)) if (ED_mesh_uv_texture_add(me, NULL, true) == -1) return OPERATOR_CANCELLED; + if (ob->mode & OB_MODE_TEXTURE_PAINT) { + Scene *scene = CTX_data_scene(C); + BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); + WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL); + } + return OPERATOR_FINISHED; } @@ -622,6 +629,12 @@ static int mesh_uv_texture_remove_exec(bContext *C, wmOperator *UNUSED(op)) if (!ED_mesh_uv_texture_remove_active(me)) return OPERATOR_CANCELLED; + if (ob->mode & OB_MODE_TEXTURE_PAINT) { + Scene *scene = CTX_data_scene(C); + BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); + WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL); + } + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 0d58eaee5fa..abc0516cf2b 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2411,10 +2411,13 @@ static int drop_named_material_invoke(bContext *C, wmOperator *op, const wmEvent return OPERATOR_CANCELLED; assign_material(base->object, ma, 1, BKE_MAT_ASSIGN_USERPREF); - + + DAG_id_tag_update(&base->object->id, OB_RECALC_OB); + + WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, base->object); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma); - + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 01f00a8458a..70c9e3c4306 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -751,12 +751,6 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs if (sp->pr_rect) RE_ResultGet32(re, sp->pr_rect); } - else { - /* validate owner */ - //if (ri->rect == NULL) - // ri->rect= MEM_mallocN(sizeof(int) * ri->pr_rectx*ri->pr_recty, "BIF_previewrender"); - //RE_ResultGet32(re, ri->rect); - } /* unassign the pointers, reset vars */ preview_prepare_scene(sp->scene, NULL, GS(id->name), sp); diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 72b4da64c3e..6c996bcbd67 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -58,6 +58,7 @@ #include "BKE_linestyle.h" #include "BKE_main.h" #include "BKE_material.h" +#include "BKE_paint.h" #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_texture.h" @@ -102,8 +103,15 @@ static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op)) if (!ob) return OPERATOR_CANCELLED; - + object_add_material_slot(ob); + + if (ob->mode & OB_MODE_TEXTURE_PAINT) { + Scene *scene = CTX_data_scene(C); + BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); + WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL); + } + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob); WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob); @@ -138,8 +146,15 @@ static int material_slot_remove_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode"); return OPERATOR_CANCELLED; } - + object_remove_material_slot(ob); + + if (ob->mode & OB_MODE_TEXTURE_PAINT) { + Scene *scene = CTX_data_scene(C); + BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); + WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL); + } + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob); diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index 6b58d3d55aa..df7ca9f11b2 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -166,7 +166,6 @@ void ED_render_engine_changed(Main *bmain) bScreen *sc; ScrArea *sa; Scene *scene; - Material *ma; for (sc = bmain->screen.first; sc; sc = sc->id.next) for (sa = sc->areabase.first; sa; sa = sa->next) @@ -176,13 +175,6 @@ void ED_render_engine_changed(Main *bmain) for (scene = bmain->scene.first; scene; scene = scene->id.next) ED_render_id_flush_update(bmain, &scene->id); - - /* reset texture painting. Sending one dependency graph signal for any material should - * refresh any texture slots */ - ma = bmain->mat.first; - if (ma) { - DAG_id_tag_update(&ma->id, 0); - } } /***************************** Updates *********************************** @@ -482,15 +474,22 @@ static void image_changed(Main *bmain, Image *ima) texture_changed(bmain, tex); } -static void scene_changed(Main *bmain, Scene *UNUSED(scene)) +static void scene_changed(Main *bmain, Scene *scene) { Object *ob; Material *ma; /* glsl */ - for (ob = bmain->object.first; ob; ob = ob->id.next) + for (ob = bmain->object.first; ob; ob = ob->id.next) { if (ob->gpulamp.first) GPU_lamp_free(ob); + + if (ob->mode & OB_MODE_TEXTURE_PAINT) { + BKE_texpaint_slots_refresh_object(scene, ob); + BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); + GPU_drawobject_free(ob->derivedFinal); + } + } for (ma = bmain->mat.first; ma; ma = ma->id.next) if (ma->gpumaterial.first) diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 87866f764bc..f4189b512e5 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -57,6 +57,7 @@ #include "BKE_context.h" #include "BKE_depsgraph.h" +#include "BKE_DerivedMesh.h" #include "BKE_brush.h" #include "BKE_image.h" #include "BKE_main.h" @@ -87,6 +88,7 @@ #include "RNA_enum_types.h" #include "GPU_draw.h" +#include "GPU_buffers.h" #include "BIF_gl.h" #include "BIF_glutil.h" @@ -752,14 +754,16 @@ static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, const flo copy_v2_v2(pop->prevmouse, mouse); copy_v2_v2(pop->startmouse, mouse); - if ((brush->imagepaint_tool == PAINT_TOOL_FILL) && (brush->flag & BRUSH_USE_GRADIENT)) { - pop->cursor = WM_paint_cursor_activate(CTX_wm_manager(C), image_paint_poll, gradient_draw_line, pop); - } - /* initialize from context */ if (CTX_wm_region_view3d(C)) { Object *ob = OBACT; - paint_proj_mesh_data_ensure(C, ob, op); + bool uvs, mat, tex, stencil; + if (!BKE_paint_proj_mesh_data_check(scene, ob, &uvs, &mat, &tex, &stencil)) { + BKE_paint_data_warning(op->reports, uvs, mat, tex, stencil); + MEM_freeN(pop); + WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL); + return NULL; + } pop->mode = PAINT_MODE_3D_PROJECT; pop->custom_paint = paint_proj_new_stroke(C, ob, mouse, mode); } @@ -773,6 +777,10 @@ static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, const flo return NULL; } + if ((brush->imagepaint_tool == PAINT_TOOL_FILL) && (brush->flag & BRUSH_USE_GRADIENT)) { + pop->cursor = WM_paint_cursor_activate(CTX_wm_manager(C), image_paint_poll, gradient_draw_line, pop); + } + settings->imapaint.flag |= IMAGEPAINT_DRAWING; ED_undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name, ED_image_undo_restore, ED_image_undo_free, NULL); @@ -1381,29 +1389,31 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op) * cache in case we are loading a file */ BKE_texpaint_slots_refresh_object(scene, ob); - paint_proj_mesh_data_ensure(C, ob, op); - + BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); + /* entering paint mode also sets image to editors */ if (imapaint->mode == IMAGEPAINT_MODE_MATERIAL) { Material *ma = give_current_material(ob, ob->actcol); /* set the current material active paint slot on image editor */ - if (ma->texpaintslot) + if (ma && ma->texpaintslot) ima = ma->texpaintslot[ma->paint_active_slot].ima; } else if (imapaint->mode == IMAGEPAINT_MODE_MATERIAL) { ima = imapaint->canvas; } - for (sc = bmain->screen.first; sc; sc = sc->id.next) { - ScrArea *sa; - for (sa = sc->areabase.first; sa; sa = sa->next) { - SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { - if (sl->spacetype == SPACE_IMAGE) { - SpaceImage *sima = (SpaceImage *)sl; - - if (!sima->pin) - ED_space_image_set(sima, scene, scene->obedit, ima); + if (ima) { + for (sc = bmain->screen.first; sc; sc = sc->id.next) { + ScrArea *sa; + for (sa = sc->areabase.first; sa; sa = sa->next) { + SpaceLink *sl; + for (sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_IMAGE) { + SpaceImage *sima = (SpaceImage *)sl; + + if (!sima->pin) + ED_space_image_set(sima, scene, scene->obedit, ima); + } } } } @@ -1420,7 +1430,7 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op) toggle_paint_cursor(C, 1); } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + GPU_drawobject_free(ob->derivedFinal); WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene); return OPERATOR_FINISHED; diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index be9a614a6fe..f9124db7a5e 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -74,6 +74,7 @@ #include "BKE_material.h" #include "BKE_mesh.h" #include "BKE_mesh_mapping.h" +#include "BKE_node.h" #include "BKE_paint.h" #include "BKE_report.h" #include "BKE_scene.h" @@ -84,6 +85,7 @@ #include "ED_image.h" #include "ED_mesh.h" +#include "ED_node.h" #include "ED_paint.h" #include "ED_screen.h" #include "ED_uvedit.h" @@ -362,7 +364,7 @@ static TexPaintSlot *project_paint_face_paint_slot(const ProjPaintState *ps, int { MFace *mf = ps->dm_mface + face_index; Material *ma = ps->dm->mat[mf->mat_nr]; - return ma->texpaintslot + ma->paint_active_slot; + return ma ? ma->texpaintslot + ma->paint_active_slot : NULL; } static Image *project_paint_face_paint_image(const ProjPaintState *ps, int face_index) @@ -373,7 +375,7 @@ static Image *project_paint_face_paint_image(const ProjPaintState *ps, int face_ else { MFace *mf = ps->dm_mface + face_index; Material *ma = ps->dm->mat[mf->mat_nr]; - TexPaintSlot *slot = ma->texpaintslot + ma->paint_active_slot; + TexPaintSlot *slot = ma ? ma->texpaintslot + ma->paint_active_slot : NULL; return slot ? slot->ima : ps->canvas_ima; } } @@ -382,14 +384,14 @@ static TexPaintSlot *project_paint_face_clone_slot(const ProjPaintState *ps, int { MFace *mf = ps->dm_mface + face_index; Material *ma = ps->dm->mat[mf->mat_nr]; - return ma->texpaintslot + ma->paint_clone_slot; + return ma ? ma->texpaintslot + ma->paint_clone_slot : NULL; } static Image *project_paint_face_clone_image(const ProjPaintState *ps, int face_index) { MFace *mf = ps->dm_mface + face_index; Material *ma = ps->dm->mat[mf->mat_nr]; - TexPaintSlot *slot = ma->texpaintslot + ma->paint_clone_slot; + TexPaintSlot *slot = ma ? ma->texpaintslot + ma->paint_clone_slot : NULL; return slot ? slot->ima : ps->clone_ima; } @@ -4665,13 +4667,18 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op) IDProperty *idgroup; IDProperty *view_data = NULL; Object *ob = OBACT; + bool uvs, mat, tex; if (ob == NULL || ob->type != OB_MESH) { BKE_report(op->reports, RPT_ERROR, "No active mesh object"); return OPERATOR_CANCELLED; } - paint_proj_mesh_data_ensure(C, ob, op); + if (!BKE_paint_proj_mesh_data_check(scene, ob, &uvs, &mat, &tex, NULL)) { + BKE_paint_data_warning(op->reports, uvs, mat, tex, true); + WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL); + return OPERATOR_CANCELLED; + } project_state_init(C, ob, &ps, BRUSH_STROKE_NORMAL); @@ -4863,110 +4870,78 @@ void PAINT_OT_image_from_view(wmOperatorType *ot) * Data generation for projective texturing * * *******************************************/ +void BKE_paint_data_warning(struct ReportList *reports, bool uvs, bool mat, bool tex, bool stencil) +{ + BKE_reportf(reports, RPT_WARNING, "Missing%s%s%s%s detected!", + !uvs ? " UVs," : "", + !mat ? " Materials," : "", + !tex ? " Textures," : "", + !stencil ? " Stencil," : "" + ); +} /* Make sure that active object has a material, and assign UVs and image layers if they do not exist */ -void paint_proj_mesh_data_ensure(bContext *C, Object *ob, wmOperator *op) +bool BKE_paint_proj_mesh_data_check(Scene *scene, Object *ob, bool *uvs, bool *mat, bool *tex, bool *stencil) { Mesh *me; int layernum; - ImagePaintSettings *imapaint = &(CTX_data_tool_settings(C)->imapaint); - bScreen *sc; - Scene *scene = CTX_data_scene(C); - Main *bmain = CTX_data_main(C); + ImagePaintSettings *imapaint = &scene->toolsettings->imapaint; Brush *br = BKE_paint_brush(&imapaint->paint); + bool hasmat = true; + bool hastex = true; + bool hasstencil = true; + bool hasuvs = true; + imapaint->missing_data = 0; + BLI_assert(ob->type == OB_MESH); - /* no material, add one */ - if (ob->totcol == 0) { - Material *ma = BKE_material_add(CTX_data_main(C), "Material"); - /* no material found, just assign to first slot */ - assign_material(ob, ma, 1, BKE_MAT_ASSIGN_USERPREF); - proj_paint_add_slot(C, ma, NULL); - } - else { - /* there may be material slots but they may be empty, check */ - int i; - - for (i = 1; i < ob->totcol + 1; i++) { - Material *ma = give_current_material(ob, i); - - if (ma) { - if (imapaint->mode == IMAGEPAINT_MODE_MATERIAL) { + if (imapaint->mode == IMAGEPAINT_MODE_MATERIAL) { + /* no material, add one */ + if (ob->totcol == 0) { + hasmat = false; + hastex = false; + } + else { + /* there may be material slots but they may be empty, check */ + int i; + hasmat = false; + hastex = false; + + for (i = 1; i < ob->totcol + 1; i++) { + Material *ma = give_current_material(ob, i); + + if (ma) { + hasmat = true; if (!ma->texpaintslot) { /* refresh here just in case */ BKE_texpaint_slot_refresh_cache(scene, ma); /* if still no slots, we have to add */ - if (!ma->texpaintslot) { - proj_paint_add_slot(C, ma, NULL); - - if (ma->texpaintslot) { - for (sc = bmain->screen.first; sc; sc = sc->id.next) { - ScrArea *sa; - for (sa = sc->areabase.first; sa; sa = sa->next) { - SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { - if (sl->spacetype == SPACE_IMAGE) { - SpaceImage *sima = (SpaceImage *)sl; - - if (!sima->pin) - ED_space_image_set(sima, scene, scene->obedit, ma->texpaintslot[0].ima); - } - } - } - } - } + if (ma->texpaintslot) { + hastex = true; + break; } } + else { + hastex = true; + break; + } } } - else { - Material *ma = BKE_material_add(CTX_data_main(C), "Material"); - /* no material found, just assign to first slot */ - assign_material(ob, ma, i, BKE_MAT_ASSIGN_USERPREF); - proj_paint_add_slot(C, ma, NULL); - } } } - - if (imapaint->mode == IMAGEPAINT_MODE_IMAGE) { + else if (imapaint->mode == IMAGEPAINT_MODE_IMAGE) { if (imapaint->canvas == NULL) { - int width; - int height; - Main *bmain = CTX_data_main(C); - float color[4] = {0.0, 0.0, 0.0, 1.0}; - - width = 1024; - height = 1024; - imapaint->canvas = BKE_image_add_generated(bmain, width, height, "Canvas", 32, false, IMA_GENTYPE_BLANK, color); - - GPU_drawobject_free(ob->derivedFinal); - - for (sc = bmain->screen.first; sc; sc = sc->id.next) { - ScrArea *sa; - for (sa = sc->areabase.first; sa; sa = sa->next) { - SpaceLink *sl; - for (sl = sa->spacedata.first; sl; sl = sl->next) { - if (sl->spacetype == SPACE_IMAGE) { - SpaceImage *sima = (SpaceImage *)sl; - - if (!sima->pin) - ED_space_image_set(sima, scene, scene->obedit, imapaint->canvas); - } - } - } - } + hastex = false; } } - + me = BKE_mesh_from_object(ob); layernum = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY); if (layernum == 0) { - BKE_reportf(op->reports, RPT_WARNING, "Object did not have UV map, manual unwrap recommended"); - - ED_mesh_uv_texture_add(me, "UVMap", true); + hasuvs = false; } /* Make sure we have a stencil to paint on! */ @@ -4974,16 +4949,29 @@ void paint_proj_mesh_data_ensure(bContext *C, Object *ob, wmOperator *op) imapaint->flag |= IMAGEPAINT_PROJECT_LAYER_STENCIL; if (imapaint->stencil == NULL) { - int width; - int height; - Main *bmain = CTX_data_main(C); - float color[4] = {0.0, 0.0, 0.0, 1.0}; - - width = 1024; - height = 1024; - imapaint->stencil = BKE_image_add_generated(bmain, width, height, "Stencil", 32, false, IMA_GENTYPE_BLANK, color); + hasstencil = false; } } + + if (!hasuvs) imapaint->missing_data |= IMAGEPAINT_MISSING_UVS; + if (!hasmat) imapaint->missing_data |= IMAGEPAINT_MISSING_MATERIAL; + if (!hastex) imapaint->missing_data |= IMAGEPAINT_MISSING_TEX; + if (!hasstencil) imapaint->missing_data |= IMAGEPAINT_MISSING_STENCIL; + + if (uvs) { + *uvs = hasuvs; + } + if (mat) { + *mat = hasmat; + } + if (tex) { + *tex = hastex; + } + if (stencil) { + *stencil = hasstencil; + } + + return hasuvs && hasmat && hastex && hasstencil; } /* Add layer operator */ @@ -5006,30 +4994,74 @@ static EnumPropertyItem layer_type_items[] = { {0, NULL, 0, NULL, NULL} }; -bool proj_paint_add_slot(bContext *C, Material *ma, wmOperator *op) +static Image *proj_paint_image_create(wmOperator *op, Main *bmain) +{ + Image *ima; + float color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + char imagename[MAX_ID_NAME - 2] = "Material Diffuse Color"; + int width = 1024; + int height = 1024; + bool use_float = false; + short gen_type = IMA_GENTYPE_BLANK; + bool alpha = false; + + if (op) { + width = RNA_int_get(op->ptr, "width"); + height = RNA_int_get(op->ptr, "height"); + use_float = RNA_boolean_get(op->ptr, "float"); + gen_type = RNA_enum_get(op->ptr, "generated_type"); + RNA_float_get_array(op->ptr, "color", color); + alpha = RNA_boolean_get(op->ptr, "alpha"); + RNA_string_get(op->ptr, "name", imagename); + } + ima = BKE_image_add_generated(bmain, width, height, imagename, alpha ? 32 : 24, use_float, + gen_type, color); + + return ima; +} + +static bool proj_paint_add_slot(bContext *C, wmOperator *op) { Object *ob = CTX_data_active_object(C); Scene *scene = CTX_data_scene(C); + Material *ma; bool is_bi = BKE_scene_uses_blender_internal(scene); + Image *ima = NULL; if (!ob) return false; - if (!ma) - ma = give_current_material(ob, ob->actcol); + ma = give_current_material(ob, ob->actcol); if (ma) { + Main *bmain = CTX_data_main(C); - if (!is_bi || ma->use_nodes) { - /* not supported for now */ + if (!is_bi && BKE_scene_use_new_shading_nodes(scene)) { + bNode *imanode; + bNodeTree *ntree = ma->nodetree; + + if (!ntree) { + ED_node_shader_default(C, &ma->id); + ntree = ma->nodetree; + } + + ma->use_nodes = true; + + /* try to add an image node */ + imanode = nodeAddStaticNode(C, ntree, SH_NODE_TEX_IMAGE); + + ima = proj_paint_image_create(op, bmain); + imanode->id = &ima->id; + + nodeSetActive(ntree, imanode); + + ntreeUpdateTree(CTX_data_main(C), ntree); } else { MTex *mtex = add_mtex_id(&ma->id, -1); /* successful creation of mtex layer, now create set */ if (mtex) { - Main *bmain = CTX_data_main(C); - Image *ima; int type = MAP_COL; int type_id = 0; @@ -5049,47 +5081,36 @@ bool proj_paint_add_slot(bContext *C, Material *ma, wmOperator *op) mtex->mapto = type; if (mtex->tex) { - float color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; - char imagename[MAX_ID_NAME - 2] = "Material Diffuse Color"; - int width = 1024; - int height = 1024; - bool use_float = false; - short gen_type = IMA_GENTYPE_BLANK; - bool alpha = false; - - if (op) { - width = RNA_int_get(op->ptr, "width"); - height = RNA_int_get(op->ptr, "height"); - use_float = RNA_boolean_get(op->ptr, "float"); - gen_type = RNA_enum_get(op->ptr, "generated_type"); - RNA_float_get_array(op->ptr, "color", color); - alpha = RNA_boolean_get(op->ptr, "alpha"); - RNA_string_get(op->ptr, "name", imagename); - } - - ima = mtex->tex->ima = BKE_image_add_generated(bmain, width, height, imagename, alpha ? 32 : 24, use_float, - gen_type, color); - - BKE_texpaint_slot_refresh_cache(scene, ma); - BKE_image_signal(ima, NULL, IMA_SIGNAL_USER_NEW_IMAGE); - WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, mtex->tex); - WM_event_add_notifier(C, NC_IMAGE | NA_ADDED, ima); - DAG_id_tag_update(&ma->id, 0); - ED_area_tag_redraw(CTX_wm_area(C)); + ima = mtex->tex->ima = proj_paint_image_create(op, bmain); } WM_event_add_notifier(C, NC_TEXTURE, CTX_data_scene(C)); - return true; } + WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, mtex->tex); + } + + if (ima) { + BKE_texpaint_slot_refresh_cache(scene, ma); + BKE_image_signal(ima, NULL, IMA_SIGNAL_USER_NEW_IMAGE); + WM_event_add_notifier(C, NC_IMAGE | NA_ADDED, ima); + DAG_id_tag_update(&ma->id, 0); + ED_area_tag_redraw(CTX_wm_area(C)); + + return true; } } - + return false; } static int texture_paint_add_texture_paint_slot_exec(bContext *C, wmOperator *op) { - return proj_paint_add_slot(C, NULL, op); + if (proj_paint_add_slot(C, op)) { + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } } @@ -5100,6 +5121,12 @@ static int texture_paint_add_texture_paint_slot_invoke(bContext *C, wmOperator * Material *ma = give_current_material(ob, ob->actcol); int type = RNA_enum_get(op->ptr, "type"); + if (!ma) { + ma = BKE_material_add(CTX_data_main(C), "Material"); + /* no material found, just assign to first slot */ + assign_material(ob, ma, ob->actcol, BKE_MAT_ASSIGN_USERPREF); + } + type = RNA_enum_from_value(layer_type_items, type); /* get the name of the texture layer type */ diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 5e1ac0cf8a8..c3b7ec60e71 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -169,8 +169,6 @@ void *paint_proj_new_stroke(struct bContext *C, struct Object *ob, const float m void paint_proj_stroke(const struct bContext *C, void *ps, const float prevmval_i[2], const float mval_i[2], const bool eraser, float pressure, float distance, float size); void paint_proj_redraw(const struct bContext *C, void *pps, bool final); void paint_proj_stroke_done(void *ps); -void paint_proj_mesh_data_ensure(bContext *C, struct Object *ob, struct wmOperator *op); -bool proj_paint_add_slot(bContext *C, struct Material *ma, struct wmOperator *op); void paint_brush_color_get(struct Scene *scene, struct Brush *br, bool color_correction, bool invert, float distance, float pressure, float color[3], struct ColorManagedDisplay *display); bool paint_use_opacity_masking(struct Brush *brush); diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index f34d0ff3f7b..e03c8a5f106 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -395,7 +395,7 @@ static Image *imapaint_face_image(DerivedMesh *dm, int face_index) Image *ima; MFace *mf = dm->getTessFaceArray(dm) + face_index; Material *ma = dm->mat[mf->mat_nr]; - ima = ma->texpaintslot[ma->paint_active_slot].ima; + ima = ma ? ma->texpaintslot[ma->paint_active_slot].ima : NULL; return ima; } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 32a71312240..c1f52c58793 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -192,8 +192,8 @@ typedef struct StrokeCache { float true_location[3]; float location[3]; - float pen_flip; - float invert; + bool pen_flip; + bool invert; float pressure; float mouse[2]; float bstrength; diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index cd95e67f070..58b56e99119 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -49,17 +49,20 @@ #include "BKE_colortools.h" #include "BKE_context.h" #include "BKE_depsgraph.h" +#include "BKE_DerivedMesh.h" #include "BKE_icons.h" #include "BKE_image.h" #include "BKE_global.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_packedFile.h" +#include "BKE_paint.h" #include "BKE_report.h" #include "BKE_screen.h" #include "BKE_sound.h" #include "GPU_draw.h" +#include "GPU_buffers.h" #include "IMB_colormanagement.h" #include "IMB_imbuf.h" @@ -1905,6 +1908,12 @@ void IMAGE_OT_reload(wmOperatorType *ot) /********************** new image operator *********************/ #define IMA_DEF_NAME N_("Untitled") +enum { + GEN_CONTEXT_NONE = 0, + GEN_CONTEXT_PAINT_CANVAS = 1, + GEN_CONTEXT_PAINT_STENCIL = 2 +}; + static int image_new_exec(bContext *C, wmOperator *op) { SpaceImage *sima; @@ -1918,6 +1927,7 @@ static int image_new_exec(bContext *C, wmOperator *op) char *name = _name; float color[4]; int width, height, floatbuf, gen_type, alpha; + int gen_context; /* retrieve state */ sima = CTX_wm_space_image(C); @@ -1937,6 +1947,7 @@ static int image_new_exec(bContext *C, wmOperator *op) gen_type = RNA_enum_get(op->ptr, "generated_type"); RNA_float_get_array(op->ptr, "color", color); alpha = RNA_boolean_get(op->ptr, "alpha"); + gen_context = RNA_enum_get(op->ptr, "gen_context"); if (!alpha) color[3] = 1.0f; @@ -1961,6 +1972,40 @@ static int image_new_exec(bContext *C, wmOperator *op) else if (sima) { ED_space_image_set(sima, scene, obedit, ima); } + else if (gen_context == GEN_CONTEXT_PAINT_CANVAS) { + bScreen *sc; + Object *ob = CTX_data_active_object(C); + + GPU_drawobject_free(ob->derivedFinal); + if (scene->toolsettings->imapaint.canvas) + id_us_min(&scene->toolsettings->imapaint.canvas->id); + scene->toolsettings->imapaint.canvas = ima; + + for (sc = bmain->screen.first; sc; sc = sc->id.next) { + ScrArea *sa; + for (sa = sc->areabase.first; sa; sa = sa->next) { + SpaceLink *sl; + for (sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_IMAGE) { + SpaceImage *sima = (SpaceImage *)sl; + + if (!sima->pin) + ED_space_image_set(sima, scene, scene->obedit, ima); + } + } + } + } + BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); + WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL); + } + else if (gen_context == GEN_CONTEXT_PAINT_STENCIL) { + Object *ob = CTX_data_active_object(C); + if (scene->toolsettings->imapaint.stencil) + id_us_min(&scene->toolsettings->imapaint.stencil->id); + scene->toolsettings->imapaint.stencil = ima; + BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); + WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL); + } else { Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data; if (tex && tex->type == TEX_IMAGE) { @@ -1991,6 +2036,13 @@ void IMAGE_OT_new(wmOperatorType *ot) { PropertyRNA *prop; static float default_color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + + static EnumPropertyItem gen_context_items[] = { + {GEN_CONTEXT_NONE, "NONE", 0, "None", ""}, + {GEN_CONTEXT_PAINT_CANVAS, "PAINT_CANVAS", 0, "Paint Canvas", ""}, + {GEN_CONTEXT_PAINT_STENCIL, "PAINT_STENCIL", 0, "Paint Stencil", ""}, + {0, NULL, 0, NULL, NULL} + }; /* identifiers */ ot->name = "New Image"; @@ -2017,7 +2069,7 @@ void IMAGE_OT_new(wmOperatorType *ot) RNA_def_enum(ot->srna, "generated_type", image_generated_type_items, IMA_GENTYPE_BLANK, "Generated Type", "Fill the image with a grid for UV map testing"); RNA_def_boolean(ot->srna, "float", 0, "32 bit Float", "Create image with 32 bit floating point bit depth"); - prop = RNA_def_boolean(ot->srna, "texstencil", 0, "Stencil", "Set Image as stencil"); + prop = RNA_def_enum(ot->srna, "gen_context", gen_context_items, 0, "Gen Context", "Generation context"); RNA_def_property_flag(prop, PROP_HIDDEN); } diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index fb97a6ac9f4..fa9ba23e454 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -279,10 +279,10 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material * if (!ma && BKE_image_has_alpha(texface->tpage)) alphablend = GPU_BLEND_ALPHA; } - else if (texpaint && ma) { + else if (texpaint) { if (gtexdraw.texpaint_material) - ima = ma->texpaintslot ? ma->texpaintslot[ma->paint_active_slot].ima : NULL; - else + ima = ma && ma->texpaintslot ? ma->texpaintslot[ma->paint_active_slot].ima : NULL; + else ima = gtexdraw.canvas; } else @@ -315,6 +315,14 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material * glActiveTexture(GL_TEXTURE1); glEnable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS); glBindTexture(GL_TEXTURE_2D, ima->bindcode); glActiveTexture(GL_TEXTURE0); } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 8b76ec3a56d..0e3621aa91f 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -698,10 +698,6 @@ static void view3d_main_area_free(ARegion *ar) if (rv3d->localvd) MEM_freeN(rv3d->localvd); if (rv3d->clipbb) MEM_freeN(rv3d->clipbb); - if (rv3d->ri) { - // XXX BIF_view3d_previewrender_free(rv3d); - } - if (rv3d->render_engine) RE_engine_free(rv3d->render_engine); @@ -735,7 +731,6 @@ static void *view3d_main_area_duplicate(void *poin) new->depths = NULL; new->gpuoffscreen = NULL; - new->ri = NULL; new->render_engine = NULL; new->sms = NULL; new->smooth_timer = NULL; diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index cff6761d628..f54e7ae06f6 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -3423,7 +3423,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op) /* find the closest Z pixel */ depth_close = view3d_depth_near(&depth_temp); - MEM_freeN(depth_temp.depths); + MEM_SAFE_FREE(depth_temp.depths); } cent[0] = (((double)rect.xmin) + ((double)rect.xmax)) / 2; @@ -4640,7 +4640,7 @@ static float view_autodist_depth_margin(ARegion *ar, const int mval[2], int marg view3d_update_depths_rect(ar, &depth_temp, &rect); depth_close = view3d_depth_near(&depth_temp); - if (depth_temp.depths) MEM_freeN(depth_temp.depths); + MEM_SAFE_FREE(depth_temp.depths); return depth_close; } diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index c7ff9f0089f..24499688835 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -271,7 +271,8 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy) r_vec[0] = dx; r_vec[1] = dy; } - else { const float mval_f[2] = {(float)dx, (float)dy}; + else { + const float mval_f[2] = {(float)dx, (float)dy}; ED_view3d_win_to_delta(t->ar, mval_f, r_vec, t->zfac); } } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index b7098085ac2..47adbb6d16d 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1711,7 +1711,9 @@ static void createTransLatticeVerts(TransInfo *t) if (bp->f1 & SELECT) { td->flag = TD_SELECTED; } - else td->flag = 0; + else { + td->flag = 0; + } copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 39babcb2536..0e0eed5ffcb 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -836,7 +836,7 @@ typedef struct Paint { typedef struct ImagePaintSettings { Paint paint; - short flag, pad; + short flag, missing_data; /* for projection painting only */ short seam_bleed, normal_angle; @@ -1737,6 +1737,11 @@ typedef enum ImagePaintMode { #define IMAGEPAINT_PROJECT_LAYER_STENCIL 256 #define IMAGEPAINT_PROJECT_LAYER_STENCIL_INV 512 +#define IMAGEPAINT_MISSING_UVS (1 << 0) +#define IMAGEPAINT_MISSING_MATERIAL (1 << 1) +#define IMAGEPAINT_MISSING_TEX (1 << 2) +#define IMAGEPAINT_MISSING_STENCIL (1 << 3) + /* toolsettings->uvcalc_flag */ #define UVCALC_FILLHOLES 1 #define UVCALC_NO_ASPECT_CORRECT 2 /* would call this UVCALC_ASPECT_CORRECT, except it should be default with old file */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 6f57f549efb..a267217abf6 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -57,7 +57,6 @@ struct Scopes; struct Histogram; struct SpaceIpo; struct BlendHandle; -struct RenderInfo; struct bNodeTree; struct uiBlock; struct FileList; diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 98c12e9cc11..3efba488299 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -41,7 +41,6 @@ struct Base; struct BoundBox; struct MovieClip; struct MovieClipUser; -struct RenderInfo; struct RenderEngine; struct bGPdata; struct SmoothView3DStore; @@ -102,7 +101,6 @@ typedef struct RegionView3D { struct BoundBox *clipbb; struct RegionView3D *localvd; /* allocated backup of its self while in localview */ - struct RenderInfo *ri; struct RenderEngine *render_engine; struct ViewDepths *depths; void *gpuoffscreen; diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 83fe56102ac..51d81295f8c 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -60,11 +60,14 @@ EnumPropertyItem id_type_items[] = { {ID_LI, "LIBRARY", ICON_LIBRARY_DATA_DIRECT, "Library", ""}, {ID_LS, "LINESTYLE", ICON_LINE_DATA, "Line Style", ""}, {ID_LT, "LATTICE", ICON_LATTICE_DATA, "Lattice", ""}, + {ID_MSK, "MASK", ICON_MOD_MASK, "Mask", ""}, {ID_MA, "MATERIAL", ICON_MATERIAL_DATA, "Material", ""}, {ID_MB, "META", ICON_META_DATA, "MetaBall", ""}, {ID_ME, "MESH", ICON_MESH_DATA, "Mesh", ""}, {ID_NT, "NODETREE", ICON_NODETREE, "NodeTree", ""}, {ID_OB, "OBJECT", ICON_OBJECT_DATA, "Object", ""}, + {ID_PC, "PAINTCURVE", ICON_CURVE_BEZCURVE, "Paint Curve", ""}, + {ID_PAL, "PALETTE", ICON_COLOR, "Palette", ""}, {ID_PA, "PARTICLE", ICON_PARTICLE_DATA, "Particle", ""}, {ID_SCE, "SCENE", ICON_SCENE_DATA, "Scene", ""}, {ID_SCR, "SCREEN", ICON_SPLITSCREEN, "Screen", ""}, diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 6146b507902..a68c98ff27c 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -308,12 +308,22 @@ static void rna_ImaPaint_mode_update(Main *UNUSED(bmain), Scene *scene, PointerR BKE_texpaint_slots_refresh_object(scene, ob); /* we assume that changing the current mode will invalidate the uv layers so we need to refresh display */ - GPU_drawobject_free(ob->derivedFinal); - WM_main_add_notifier(NC_GEOM | ND_DATA, &ob->id); + GPU_drawobject_free(ob->derivedFinal); + BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); + WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL); +} + +static void rna_ImaPaint_stencil_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr)) +{ + Object *ob = OBACT; + GPU_drawobject_free(ob->derivedFinal); + BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); + WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL); } static void rna_ImaPaint_canvas_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr)) { + Object *ob = OBACT; bScreen *sc; Image *ima = scene->toolsettings->imapaint.canvas; @@ -331,9 +341,16 @@ static void rna_ImaPaint_canvas_update(Main *bmain, Scene *scene, PointerRNA *UN } } } - + + GPU_drawobject_free(ob->derivedFinal); + BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL); } + +static int rna_ImaPaint_detect_data(ImagePaintSettings *imapaint) +{ + return imapaint->missing_data == 0; +} #else static void rna_def_palettecolor(BlenderRNA *brna) @@ -616,6 +633,7 @@ static void rna_def_image_paint(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; + FunctionRNA *func; static EnumPropertyItem paint_type_items[] = { {IMAGEPAINT_MODE_MATERIAL, "MATERIAL", 0, @@ -629,6 +647,13 @@ static void rna_def_image_paint(BlenderRNA *brna) RNA_def_struct_sdna(srna, "ImagePaintSettings"); RNA_def_struct_path_func(srna, "rna_ImagePaintSettings_path"); RNA_def_struct_ui_text(srna, "Image Paint", "Properties of image and texture painting mode"); + + /* functions */ + func = RNA_def_function(srna, "detect_data", "rna_ImaPaint_detect_data"); + RNA_def_function_ui_description(func, "Check if required texpaint data exist"); + + /* return type */ + RNA_def_function_return(func, RNA_def_boolean(func, "ok", 1, "", "")); /* booleans */ prop = RNA_def_property(srna, "use_occlude", PROP_BOOLEAN, PROP_NONE); @@ -660,7 +685,7 @@ static void rna_def_image_paint(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "stencil"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Stencil Image", "Image used as stencil"); - RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_viewport_update"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_stencil_update"); prop = RNA_def_property(srna, "canvas", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_EDITABLE); @@ -702,7 +727,32 @@ static void rna_def_image_paint(BlenderRNA *brna) prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, paint_type_items); RNA_def_property_ui_text(prop, "Mode", "Mode of operation for projection painting"); - RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_mode_update"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_mode_update"); + + /* Missing data */ + prop = RNA_def_property(srna, "missing_uvs", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "missing_data", IMAGEPAINT_MISSING_UVS); + RNA_def_property_ui_text(prop, "Missing UVs", + "A UV layer is missing on the mesh"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop = RNA_def_property(srna, "missing_materials", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "missing_data", IMAGEPAINT_MISSING_MATERIAL); + RNA_def_property_ui_text(prop, "Missing Materials", + "The mesh is missing materials"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop = RNA_def_property(srna, "missing_stencil", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "missing_data", IMAGEPAINT_MISSING_STENCIL); + RNA_def_property_ui_text(prop, "Missing Stencil", + "Image Painting does not have a stencil"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop = RNA_def_property(srna, "missing_texture", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "missing_data", IMAGEPAINT_MISSING_TEX); + RNA_def_property_ui_text(prop, "Missing Texture", + "Image Painting does not have a texture to paint on"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); } static void rna_def_particle_edit(BlenderRNA *brna) diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index 4dbe28e8a59..40db49afef2 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -609,10 +609,13 @@ static DerivedMesh *arrayModifier_doArray( int target = full_doubles_map[prev_chunk_index]; if (target != -1) { target += chunk_nverts; /* translate mapping */ - if (!with_follow) { - /* The rule here is to not follow mapping to chunk N-2, which could be too far - * so if target vertex was itself mapped, then this vertex is not mapped */ - if (full_doubles_map[target] != -1) { + if (full_doubles_map[target] != -1) { + if (with_follow) { + target = full_doubles_map[target]; + } + else { + /* The rule here is to not follow mapping to chunk N-2, which could be too far + * so if target vertex was itself mapped, then this vertex is not mapped */ target = -1; } } diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 748303f9082..1abe000a86c 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -589,8 +589,12 @@ static void wm_keymap_patch(wmKeyMap *km, wmKeyMap *diff_km) /* add item */ if (kmdi->add_item) { + /* Do not re-add an already existing keymap item! See T42088. */ + kmi_add = wm_keymap_find_item_equals(km, kmdi->add_item); + if (!kmi_add) + kmi_add = wm_keymap_find_item_equals_result(km, kmdi->add_item); /* only if nothing to remove or item to remove found */ - if (!kmdi->remove_item || kmi_remove) { + if (!kmi_add && (!kmdi->remove_item || kmi_remove)) { kmi_add = wm_keymap_item_copy(kmdi->add_item); kmi_add->flag |= KMI_USER_MODIFIED; diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 84cd47ca61a..649ea1f59c7 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -142,6 +142,7 @@ struct wmWindowManager; #include "../../intern/dualcon/dualcon.h" #include "../../intern/elbeem/extern/elbeem.h" #include "../blender/blenkernel/BKE_modifier.h" +#include "../blender/blenkernel/BKE_paint.h" #include "../blender/collada/collada.h" #include "../blender/compositor/COM_compositor.h" #include "../blender/editors/include/ED_armature.h" @@ -247,6 +248,9 @@ struct Render *RE_GetRender(const char *name) RET_NULL float RE_lamp_get_data(struct ShadeInput *shi, struct Object *lamp_obj, float col[4], float lv[3], float *dist, float shadow[4]) RET_ZERO /* blenkernel */ +bool BKE_paint_proj_mesh_data_check(struct Scene *scene, struct Object *ob, bool *uvs, bool *mat, bool *tex, bool *stencil) RET_ZERO + +/* render */ void RE_FreeRenderResult(struct RenderResult *res) RET_NONE void RE_FreeAllRenderResults(void) RET_NONE struct RenderResult *RE_MultilayerConvert(void *exrhandle, const char *colorspace, bool predivide, int rectx, int recty) RET_NULL diff --git a/source/creator/creator.c b/source/creator/creator.c index 9d1ef49d969..458afb2d131 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -1604,7 +1604,7 @@ int main( #ifdef WITH_LIBMV libmv_initLogging(argv[0]); -#elif defined(WITH_CYCLES_DEBUG) +#elif defined(WITH_CYCLES_LOGGING) CCL_init_logging(argv[0]); #endif |