diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-12-08 16:35:14 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-12-08 16:35:14 +0400 |
commit | ec33687d6cf74775e37fdc1a14e22dea08289cb1 (patch) | |
tree | a98875cf3deae05c46cdd70192858b8844ab1ea4 /source/blender | |
parent | 724746dba2deed8e336fc66b36bfc3b5b1858a8e (diff) | |
parent | 7b9adab594d1cc670d642b56ae8d76069ce91107 (diff) |
Merged changes in the trunk up to revision 52815.
Diffstat (limited to 'source/blender')
100 files changed, 1005 insertions, 680 deletions
diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h index ebfbe94802a..9af0d96884a 100644 --- a/source/blender/blenkernel/BKE_icons.h +++ b/source/blender/blenkernel/BKE_icons.h @@ -30,9 +30,7 @@ /** \file BKE_icons.h * \ingroup bke - */ - -/* + * * Resizable Icons for Blender */ diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 515bb37b249..b8f168cbdea 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -314,6 +314,8 @@ void ntreeUserIncrefID(struct bNodeTree *ntree); void ntreeUserDecrefID(struct bNodeTree *ntree); +struct bNodeTree *ntreeFromID(struct ID *id); + void ntreeMakeLocal(struct bNodeTree *ntree); int ntreeHasType(struct bNodeTree *ntree, int type); void ntreeUpdateTree(struct bNodeTree *ntree); diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 11ff3930ffb..6208bb355b1 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -257,13 +257,13 @@ if(WITH_BULLET) add_definitions(-DUSE_BULLET) endif() -if(WITH_MOD_CLOTH_ELTOPO) - list(APPEND INC - ../../../extern/eltopo - ../../../extern/eltopo/eltopo3d - ) - add_definitions(-DWITH_ELTOPO) -endif() +#if(WITH_MOD_CLOTH_ELTOPO) +# list(APPEND INC +# ../../../extern/eltopo +# ../../../extern/eltopo/eltopo3d +# ) +# add_definitions(-DWITH_ELTOPO) +#endif() if(WITH_IMAGE_OPENEXR) add_definitions(-DWITH_OPENEXR) diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 3736395313d..d09bea0f662 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -392,7 +392,7 @@ void DM_ensure_tessface(DerivedMesh *dm) } else if (dm->dirty & DM_DIRTY_TESS_CDLAYERS) { - BLI_assert(CustomData_has_layer(&dm->faceData, CD_ORIGINDEX)); + BLI_assert(CustomData_has_layer(&dm->faceData, CD_ORIGINDEX) || numTessFaces == 0); DM_update_tessface_data(dm); } @@ -1159,119 +1159,64 @@ void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag, ColorBand *coba = stored_cb; /* warning, not a local var */ unsigned char *wtcol_v; -#if 0 /* See coment below. */ - unsigned char *wtcol_f = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL); -#endif unsigned char(*wtcol_l)[4] = CustomData_get_layer(dm->getLoopDataLayout(dm), CD_PREVIEW_MLOOPCOL); -#if 0 /* See coment below. */ - MFace *mf = dm->getTessFaceArray(dm); -#endif MLoop *mloop = dm->getLoopArray(dm), *ml; MPoly *mp = dm->getPolyArray(dm); -#if 0 - int numFaces = dm->getNumTessFaces(dm); -#endif int numVerts = dm->getNumVerts(dm); int totloop; int i, j; -#if 0 /* See comment below */ - /* If no CD_PREVIEW_MCOL existed yet, add a new one! */ - if (!wtcol_f) - wtcol_f = CustomData_add_layer(&dm->faceData, CD_PREVIEW_MCOL, CD_CALLOC, NULL, numFaces); - - if (wtcol_f) { - unsigned char *wtcol_f_step = wtcol_f; -# else -#if 0 - /* XXX We have to create a CD_PREVIEW_MCOL, else it might sigsev (after a SubSurf mod, eg)... */ - if (!dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL)) - CustomData_add_layer(&dm->faceData, CD_PREVIEW_MCOL, CD_CALLOC, NULL, numFaces); -#endif - - { -#endif - - /* Weights are given by caller. */ - if (weights) { - float *w = weights; - /* If indices is not NULL, it means we do not have weights for all vertices, - * so we must create them (and set them to zero)... */ - if (indices) { - w = MEM_callocN(sizeof(float) * numVerts, "Temp weight array DM_update_weight_mcol"); - i = num; - while (i--) - w[indices[i]] = weights[i]; - } - - /* Convert float weights to colors. */ - wtcol_v = calc_colors_from_weights_array(numVerts, w); - - if (indices) - MEM_freeN(w); + /* Weights are given by caller. */ + if (weights) { + float *w = weights; + /* If indices is not NULL, it means we do not have weights for all vertices, + * so we must create them (and set them to zero)... */ + if (indices) { + w = MEM_callocN(sizeof(float) * numVerts, "Temp weight array DM_update_weight_mcol"); + i = num; + while (i--) + w[indices[i]] = weights[i]; } - /* No weights given, take them from active vgroup(s). */ - else - wtcol_v = calc_weightpaint_vert_array(ob, dm, draw_flag, coba); + /* Convert float weights to colors. */ + wtcol_v = calc_colors_from_weights_array(numVerts, w); - /* Now copy colors in all face verts. */ - /* first add colors to the tessellation faces */ - /* XXX Why update that layer? We have to update WEIGHT_MLOOPCOL anyway, - * and tessellation recreates mface layers from mloop/mpoly ones, so no - * need to fill WEIGHT_MCOL here. */ -#if 0 - for (i = 0; i < numFaces; i++, mf++, wtcol_f_step += (4 * 4)) { - /*origindex being NULL means we're operating on original mesh data*/ -#if 0 - unsigned int fidx = mf->v4 ? 3 : 2; - -#else /* better zero out triangles 4th component. else valgrind complains when the buffer's copied */ - unsigned int fidx; - if (mf->v4) { - fidx = 3; - } - else { - fidx = 2; - *(int *)(&wtcol_f_step[3 * 4]) = 0; - } -#endif + if (indices) + MEM_freeN(w); + } - do { - copy_v4_v4_char((char *)&wtcol_f_step[fidx * 4], - (char *)&wtcol_v[4 * (*(&mf->v1 + fidx))]); - } while (fidx--); - } -#endif - /*now add to loops, so the data can be passed through the modifier stack*/ - /* If no CD_PREVIEW_MLOOPCOL existed yet, we have to add a new one! */ - if (!wtcol_l) { - BLI_array_declare(wtcol_l); - totloop = 0; - for (i = 0; i < dm->numPolyData; i++, mp++) { - ml = mloop + mp->loopstart; - - BLI_array_grow_items(wtcol_l, mp->totloop); - for (j = 0; j < mp->totloop; j++, ml++, totloop++) { - copy_v4_v4_char((char *)&wtcol_l[totloop], - (char *)&wtcol_v[4 * ml->v]); - } + /* No weights given, take them from active vgroup(s). */ + else + wtcol_v = calc_weightpaint_vert_array(ob, dm, draw_flag, coba); + + /* now add to loops, so the data can be passed through the modifier stack */ + /* If no CD_PREVIEW_MLOOPCOL existed yet, we have to add a new one! */ + if (!wtcol_l) { + BLI_array_declare(wtcol_l); + totloop = 0; + for (i = 0; i < dm->numPolyData; i++, mp++) { + ml = mloop + mp->loopstart; + + BLI_array_grow_items(wtcol_l, mp->totloop); + for (j = 0; j < mp->totloop; j++, ml++, totloop++) { + copy_v4_v4_char((char *)&wtcol_l[totloop], + (char *)&wtcol_v[4 * ml->v]); } - CustomData_add_layer(&dm->loopData, CD_PREVIEW_MLOOPCOL, CD_ASSIGN, wtcol_l, totloop); } - else { - totloop = 0; - for (i = 0; i < dm->numPolyData; i++, mp++) { - ml = mloop + mp->loopstart; + CustomData_add_layer(&dm->loopData, CD_PREVIEW_MLOOPCOL, CD_ASSIGN, wtcol_l, totloop); + } + else { + totloop = 0; + for (i = 0; i < dm->numPolyData; i++, mp++) { + ml = mloop + mp->loopstart; - for (j = 0; j < mp->totloop; j++, ml++, totloop++) { - copy_v4_v4_char((char *)&wtcol_l[totloop], - (char *)&wtcol_v[4 * ml->v]); - } + for (j = 0; j < mp->totloop; j++, ml++, totloop++) { + copy_v4_v4_char((char *)&wtcol_l[totloop], + (char *)&wtcol_v[4 * ml->v]); } } - MEM_freeN(wtcol_v); } + MEM_freeN(wtcol_v); dm->dirty |= DM_DIRTY_TESS_CDLAYERS; } diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 03698736459..f0d201ea3f7 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -279,7 +279,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath /* this can happen when active scene was lib-linked, and doesn't exist anymore */ if (CTX_data_scene(C) == NULL) { /* in case we don't even have a local scene, add one */ - if(!G.main->scene.first) + if (!G.main->scene.first) BKE_scene_add("Scene"); CTX_data_scene_set(C, G.main->scene.first); diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 54f69a49e70..54bbe4bf495 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -653,12 +653,29 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, else { if (index_mf_to_mpoly) { orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i); - if (orig == ORIGINDEX_NONE) { if (nors) nors += 3; continue; } - if (drawParamsMapped) { draw_option = drawParamsMapped(userData, orig); } - else { if (nors) nors += 3; continue; } + if (orig == ORIGINDEX_NONE) { + /* XXX, this is not really correct + * it will draw the previous faces context for this one when we don't know its settings. + * but better then skipping it altogether. - campbell */ + draw_option = DM_DRAW_OPTION_NORMAL; + } + else if (drawParamsMapped) { + draw_option = drawParamsMapped(userData, orig); + } + else { + if (nors) { + nors += 3; continue; + } + } + } + else if (drawParamsMapped) { + draw_option = drawParamsMapped(userData, i); + } + else { + if (nors) { + nors += 3; continue; + } } - else if (drawParamsMapped) { draw_option = drawParamsMapped(userData, i); } - else { if (nors) nors += 3; continue; } } if (draw_option != DM_DRAW_OPTION_SKIP) { @@ -742,9 +759,12 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, if (index_mf_to_mpoly) { orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace); if (orig == ORIGINDEX_NONE) { - continue; + /* XXX, this is not really correct + * it will draw the previous faces context for this one when we don't know its settings. + * but better then skipping it altogether. - campbell */ + draw_option = DM_DRAW_OPTION_NORMAL; } - if (drawParamsMapped) { + else if (drawParamsMapped) { draw_option = drawParamsMapped(userData, orig); } } diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index e300b5e0f19..97d750854f4 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -84,15 +84,9 @@ #include "BKE_movieclip.h" #ifdef WITH_PYTHON -#include "BPY_extern.h" +# include "BPY_extern.h" #endif -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - - - /* ************************ Constraints - General Utilities *************************** */ /* These functions here don't act on any specific constraints, and are therefore should/will * not require any of the special function-pointers afforded by the relevant constraint diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index d23a608d31f..3ed759392b6 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -1940,13 +1940,13 @@ void DAG_scene_sort(Main *bmain, Scene *sce) static void lib_id_recalc_tag(Main *bmain, ID *id) { id->flag |= LIB_ID_RECALC; - bmain->id_tag_update[id->name[0]] = 1; + DAG_id_type_tag(bmain, GS(id->name)); } static void lib_id_recalc_data_tag(Main *bmain, ID *id) { id->flag |= LIB_ID_RECALC_DATA; - bmain->id_tag_update[id->name[0]] = 1; + DAG_id_type_tag(bmain, GS(id->name)); } /* node was checked to have lasttime != curtime and is if type ID_OB */ @@ -2818,6 +2818,7 @@ void DAG_ids_check_recalc(Main *bmain, Scene *scene, int time) void DAG_ids_clear_recalc(Main *bmain) { ListBase *lbarray[MAX_LIBARRAY]; + bNodeTree *ntree; int a; /* loop over all ID types */ @@ -2830,9 +2831,15 @@ void DAG_ids_clear_recalc(Main *bmain) /* we tag based on first ID type character to avoid * looping over all ID's in case there are no tags */ if (id && bmain->id_tag_update[id->name[0]]) { - for (; id; id = id->next) + for (; id; id = id->next) { if (id->flag & (LIB_ID_RECALC | LIB_ID_RECALC_DATA)) id->flag &= ~(LIB_ID_RECALC | LIB_ID_RECALC_DATA); + + /* some ID's contain semi-datablock nodetree */ + ntree = ntreeFromID(id); + if (ntree && (ntree->id.flag & (LIB_ID_RECALC | LIB_ID_RECALC_DATA))) + ntree->id.flag &= ~(LIB_ID_RECALC | LIB_ID_RECALC_DATA); + } } } @@ -2899,8 +2906,18 @@ void DAG_id_tag_update(ID *id, short flag) } } -void DAG_id_type_tag(struct Main *bmain, short idtype) +void DAG_id_type_tag(Main *bmain, short idtype) { + if (idtype == ID_NT) { + /* stupid workaround so parent datablocks of nested nodetree get looped + * over when we loop over tagged datablock types */ + DAG_id_type_tag(bmain, ID_MA); + DAG_id_type_tag(bmain, ID_TE); + DAG_id_type_tag(bmain, ID_LA); + DAG_id_type_tag(bmain, ID_WO); + DAG_id_type_tag(bmain, ID_SCE); + } + bmain->id_tag_update[((char *)&idtype)[0]] = 1; } diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index bb3836e3c08..ed85e5b627b 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -3366,7 +3366,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, (!hit_found || (brush->flags & MOD_DPAINT_INVERSE_PROX))) { float proxDist = -1.0f; - float hitCo[3]; + float hitCo[3] = {0.0f, 0.0f, 0.0f}; short hQuad; int face; @@ -3723,6 +3723,8 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface, float smooth_range = smooth * (1.0f - strength), dist; /* calculate max range that can have particles with higher influence than the nearest one */ float max_range = smooth - strength * smooth + solidradius; + /* Make gcc happy! */ + dist = max_range; particles = BLI_kdtree_range_search(tree, max_range, bData->realCoord[bData->s_pos[index]].v, NULL, &nearest); diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 70867a45fd7..17dcf34b71f 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -38,9 +38,13 @@ #include "DNA_action_types.h" #include "DNA_anim_types.h" +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" #include "DNA_node_types.h" #include "DNA_node_types.h" #include "DNA_scene_types.h" +#include "DNA_texture_types.h" +#include "DNA_world_types.h" #include "BLI_string.h" #include "BLI_math.h" @@ -1154,6 +1158,18 @@ void ntreeSetOutput(bNodeTree *ntree) * might be different for editor or for "real" use... */ } +bNodeTree *ntreeFromID(ID *id) +{ + switch (GS(id->name)) { + case ID_MA: return ((Material*)id)->nodetree; + case ID_LA: return ((Lamp*)id)->nodetree; + case ID_WO: return ((World*)id)->nodetree; + case ID_TE: return ((Tex*)id)->nodetree; + case ID_SCE: return ((Scene*)id)->nodetree; + default: return NULL; + } +} + typedef struct MakeLocalCallData { ID *group_id; ID *new_id; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index a780a9e8684..90889d7c09e 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2140,16 +2140,22 @@ static void psys_update_effectors(ParticleSimulationData *sim) precalc_guides(sim, sim->psys->effectors); } -static void integrate_particle(ParticleSettings *part, ParticleData *pa, float dtime, float *external_acceleration, void (*force_func)(void *forcedata, ParticleKey *state, float *force, float *impulse), void *forcedata) +static void integrate_particle(ParticleSettings *part, ParticleData *pa, float dtime, float *external_acceleration, + void (*force_func)(void *forcedata, ParticleKey *state, float *force, float *impulse), + void *forcedata) { +#define ZERO_F43 {{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}} + ParticleKey states[5]; - float force[3],acceleration[3],impulse[3],dx[4][3],dv[4][3],oldpos[3]; + float force[3], acceleration[3], impulse[3], dx[4][3] = ZERO_F43, dv[4][3] = ZERO_F43, oldpos[3]; float pa_mass= (part->flag & PART_SIZEMASS ? part->mass * pa->size : part->mass); int i, steps=1; int integrator = part->integrator; +#undef ZERO_F43 + copy_v3_v3(oldpos, pa->state.co); - + /* Verlet integration behaves strangely with moving emitters, so do first step with euler. */ if (pa->prev_state.time < 0.f && integrator == PART_INT_VERLET) integrator = PART_INT_EULER; diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 2e57df844c8..d0af06d9f90 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -408,6 +408,7 @@ Scene *BKE_scene_add(const char *name) sce->r.im_format.planes = R_IMF_PLANES_RGB; sce->r.im_format.imtype = R_IMF_IMTYPE_PNG; sce->r.im_format.quality = 90; + sce->r.im_format.compress = 90; sce->r.displaymode = R_OUTPUT_AREA; sce->r.framapto = 100; diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index e6339d07e66..322b77e0462 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -2019,8 +2019,14 @@ void txt_do_undo(Text *text) /* get and restore the cursors */ txt_undo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + txt_move_to(text, curln, curc, 0); - txt_move_to(text, curln, curc + linep, 1); + txt_move_to(text, selln, selc, 1); + + if ((curln == selln) && (curc == selc)) { + for (i = 0; i < linep; i++) + txt_move_right(text, 1); + } txt_delete_selected(text); @@ -2269,6 +2275,8 @@ void txt_split_curline(Text *text) txt_delete_sel(text); + if (!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, '\n'); + /* Make the two half strings */ left = MEM_mallocN(text->curc + 1, "textline_string"); @@ -2300,7 +2308,6 @@ void txt_split_curline(Text *text) txt_clean_text(text); txt_pop_sel(text); - if (!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, '\n'); } static void txt_delete_line(Text *text, TextLine *line) diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 7be636fe150..4a27036050e 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -129,6 +129,7 @@ set(SRC BLI_math_color.h BLI_math_geom.h BLI_math_inline.h + BLI_math_interp.h BLI_math_matrix.h BLI_math_rotation.h BLI_math_vector.h diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c index 8b63a94951d..8924d03f736 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenlib/intern/bpath.c @@ -501,7 +501,7 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int Material *ma = (Material *)id; bNodeTree *ntree = ma->nodetree; - if(ntree) { + if (ntree) { bNode *node; for (node = ntree->nodes.first; node; node = node->next) { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index b9e23f60881..55ae56ac4e8 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2410,6 +2410,8 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) ntree->adt = newdataadr(fd, ntree->adt); direct_link_animdata(fd, ntree->adt); + ntree->id.flag &= ~(LIB_ID_RECALC|LIB_ID_RECALC_DATA); + link_list(fd, &ntree->nodes); for (node = ntree->nodes.first; node; node = node->next) { node->typeinfo = NULL; @@ -8533,7 +8535,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) for (clip = main->movieclip.first; clip; clip = clip->id.next) { if (clip->tracking.settings.reconstruction_success_threshold == 0.0f) { - clip->tracking.settings.reconstruction_success_threshold = 1e-3; + clip->tracking.settings.reconstruction_success_threshold = 1e-3f; } } } diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index ba5e7569c31..590edc45d07 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -42,8 +42,8 @@ #include "intern/bmesh_private.h" /* used as an extern, defined in bmesh.h */ -BMAllocTemplate bm_mesh_allocsize_default = {512, 1024, 2048, 512}; -BMAllocTemplate bm_mesh_chunksize_default = {512, 1024, 2048, 512}; +const BMAllocTemplate bm_mesh_allocsize_default = {512, 1024, 2048, 512}; +const BMAllocTemplate bm_mesh_chunksize_default = {512, 1024, 2048, 512}; static void bm_mempool_init(BMesh *bm, const BMAllocTemplate *allocsize) { @@ -109,7 +109,7 @@ void BM_mesh_elem_toolflags_clear(BMesh *bm) * * \note ob is needed by multires */ -BMesh *BM_mesh_create(BMAllocTemplate *allocsize) +BMesh *BM_mesh_create(const BMAllocTemplate *allocsize) { /* allocate the structure */ BMesh *bm = MEM_callocN(sizeof(BMesh), __func__); @@ -206,6 +206,11 @@ void BM_mesh_clear(BMesh *bm) bm->stackdepth = 1; bm->totflags = 1; + + CustomData_reset(&bm->vdata); + CustomData_reset(&bm->edata); + CustomData_reset(&bm->ldata); + CustomData_reset(&bm->pdata); } /** diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h index b592f863cd1..8baba568fb8 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.h +++ b/source/blender/bmesh/intern/bmesh_mesh.h @@ -31,7 +31,7 @@ struct BMAllocTemplate; void BM_mesh_elem_toolflags_ensure(BMesh *bm); void BM_mesh_elem_toolflags_clear(BMesh *bm); -BMesh *BM_mesh_create(struct BMAllocTemplate *allocsize); +BMesh *BM_mesh_create(const struct BMAllocTemplate *allocsize); void BM_mesh_free(BMesh *bm); void BM_mesh_data_free(BMesh *bm); @@ -57,8 +57,8 @@ typedef struct BMAllocTemplate { int totvert, totedge, totloop, totface; } BMAllocTemplate; -extern BMAllocTemplate bm_mesh_allocsize_default; -extern BMAllocTemplate bm_mesh_chunksize_default; +extern const BMAllocTemplate bm_mesh_allocsize_default; +extern const BMAllocTemplate bm_mesh_chunksize_default; enum { BM_MESH_CREATE_USE_TOOLFLAGS = (1 << 0) diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index ba38f230f0b..baec0b7745d 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -256,7 +256,7 @@ BMOpSlot *BMO_slot_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identif if (UNLIKELY(slot_code < 0)) { //return &BMOpEmptySlot; BLI_assert(0); - NULL; /* better crash */ + return NULL; /* better crash */ } return &slot_args[slot_code]; diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c index 12edffec213..c7cd1e742d8 100644 --- a/source/blender/bmesh/operators/bmo_connect.c +++ b/source/blender/bmesh/operators/bmo_connect.c @@ -382,18 +382,19 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op) /* compute summed length between vertices in forward direction */ len = 0.0f; - for (j = 0; j < lenv2; j++) { + for (j = 0; (j < lenv2) && (len < min); j++) { len += len_v3v3(vv1[clamp_index(i + j, lenv1)]->co, vv2[j]->co); } if (len < min) { min = len; starti = i; + dir1 = 1; } /* compute summed length between vertices in backward direction */ len = 0.0f; - for (j = 0; j < lenv2; j++) { + for (j = 0; (j < lenv2) && (len < min); j++) { len += len_v3v3(vv1[clamp_index(i - j, lenv1)]->co, vv2[j]->co); } diff --git a/source/blender/bmesh/tools/BME_bevel.c b/source/blender/bmesh/tools/BME_bevel.c index cdfd8372d61..3f2ca21bcee 100644 --- a/source/blender/bmesh/tools/BME_bevel.c +++ b/source/blender/bmesh/tools/BME_bevel.c @@ -689,8 +689,16 @@ static BMFace *BME_bevel_poly(BMesh *bm, BMFace *f, float value, int options, BM BMO_elem_flag_test(bm, l->v, BME_BEVEL_ORIG) && !BMO_elem_flag_test(bm, l->prev->e, BME_BEVEL_BEVEL)) { - max = 1.0f; - l = BME_bevel_vert(bm, l, value, options, up_vec, td); + /* avoid making double vertices [#33438] */ + BME_TransData *vtd; + vtd = BME_get_transdata(td, l->v); + if (vtd->weight == 0.0f) { + BMO_elem_flag_disable(bm, l->v, BME_BEVEL_BEVEL); + } + else { + max = 1.0f; + l = BME_bevel_vert(bm, l, value, options, up_vec, td); + } } } diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index cb35616a1f7..9125800d3e8 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -375,8 +375,9 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, BMVert *v, BMFace *f1, BMFace *f2, float meetco[3]) { - float dir1[3], dir2[3], norm_perp1[3], norm_perp2[3], - off1a[3], off1b[3], off2a[3], off2b[3], isect2[3], co[3]; + float dir1[3], dir2[3], dirmid[3], norm_perp1[3], norm_perp2[3], + off1a[3], off1b[3], off2a[3], off2b[3], isect2[3], co[3], + f1no[3], f2no[3]; int iret; BLI_assert(f1 != NULL && f2 != NULL); @@ -384,17 +385,21 @@ static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, /* get direction vectors for two offset lines */ sub_v3_v3v3(dir1, v->co, BM_edge_other_vert(e1->e, v)->co); sub_v3_v3v3(dir2, BM_edge_other_vert(e2->e, v)->co, v->co); + sub_v3_v3v3(dirmid, BM_edge_other_vert(emid->e, v)->co, v->co); /* get directions into offset planes */ - cross_v3_v3v3(norm_perp1, dir1, f1->no); + /* calculate face normals at corner in case faces are nonplanar */ + cross_v3_v3v3(f1no, dirmid, dir1); + cross_v3_v3v3(f2no, dirmid, dir2); + cross_v3_v3v3(norm_perp1, dir1, f1no); normalize_v3(norm_perp1); - cross_v3_v3v3(norm_perp2, dir2, f2->no); + cross_v3_v3v3(norm_perp2, dir2, f2no); normalize_v3(norm_perp2); /* get points that are offset distances from each line, then another point on each line */ copy_v3_v3(off1a, v->co); madd_v3_v3fl(off1a, norm_perp1, e1->offset); - add_v3_v3v3(off1b, off1a, dir1); + sub_v3_v3v3(off1b, off1a, dir1); copy_v3_v3(off2a, v->co); madd_v3_v3fl(off2a, norm_perp2, e2->offset); add_v3_v3v3(off2b, off2a, dir2); @@ -404,7 +409,7 @@ static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, copy_v3_v3(meetco, off1a); } else { - iret =isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2); + iret = isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2); if (iret == 0) { /* lines colinear: another test says they are parallel. so shouldn't happen */ copy_v3_v3(meetco, off1a); @@ -426,10 +431,10 @@ static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, * from eh's direction. */ static void offset_in_plane(EdgeHalf *e, const float plane_no[3], int left, float r[3]) { - float dir[3], no[3]; + float dir[3], no[3], fdir[3]; BMVert *v; - v = e->is_rev ? e->e->v1 : e->e->v2; + v = e->is_rev ? e->e->v2 : e->e->v1; sub_v3_v3v3(dir, BM_edge_other_vert(e->e, v)->co, v->co); normalize_v3(dir); @@ -444,11 +449,12 @@ static void offset_in_plane(EdgeHalf *e, const float plane_no[3], int left, floa no[1] = 1.0f; } if (left) - cross_v3_v3v3(r, no, dir); + cross_v3_v3v3(fdir, dir, no); else - cross_v3_v3v3(r, dir, no); - normalize_v3(r); - mul_v3_fl(r, e->offset); + cross_v3_v3v3(fdir, no, dir); + normalize_v3(fdir); + copy_v3_v3(r, v->co); + madd_v3_v3fl(r, fdir, e->offset); } /* Calculate coordinates of a point a distance d from v on e->e and return it in slideco */ @@ -563,100 +569,11 @@ static void get_point_on_round_edge(const float uv[2], #else /* USE_ALTERNATE_ADJ */ -#ifdef OLD_ROUND_EDGE -/* - * calculation of points on the round profile - * r - result, coordinate of point on round profile - * method: - * Inscribe a circle in angle va - v -vb - * such that it touches the arms at offset from v. - * Rotate the center-va segment by (i/n) of the - * angle va - center -vb, and put the endpoint - * of that segment in r. - */ -static void get_point_on_round_profile(float r_co[3], float offset, int k, int count, - const float va[3], const float v[3], const float vb[3]) -{ - float vva[3], vvb[3], angle, center[3], rv[3], axis[3], co[3]; - - sub_v3_v3v3(vva, va, v); - sub_v3_v3v3(vvb, vb, v); - normalize_v3(vva); - normalize_v3(vvb); - angle = angle_normalized_v3v3(vva, vvb); - - add_v3_v3v3(center, vva, vvb); - normalize_v3(center); - mul_v3_fl(center, offset * (1.0f / cosf(0.5f * angle))); - add_v3_v3(center, v); /* coordinates of the center of the inscribed circle */ - - - sub_v3_v3v3(rv, va, center); /* radius vector */ - - - sub_v3_v3v3(co, v, center); - cross_v3_v3v3(axis, rv, co); /* calculate axis */ - - sub_v3_v3v3(vva, va, center); - sub_v3_v3v3(vvb, vb, center); - angle = angle_v3v3(vva, vvb); - - rotate_v3_v3v3fl(co, rv, axis, angle * (float)k / (float)count); - - add_v3_v3(co, center); - copy_v3_v3(r_co, co); -} - -/* - * Find the point (/n) of the way around the round profile for e, - * where start point is va, midarc point is vmid, and end point is vb. - * Return the answer in profileco. - * Method: - * Adjust va and vb (along edge direction) so that they are perpendicular - * to edge at v, then use get_point_on_round_profile, then project - * back onto original va - vmid - vb plane. - * If va, vmid, and vb are all on the same plane, just interpolate between va and vb. - */ -static void get_point_on_round_edge(EdgeHalf *e, int k, - const float va[3], const float vmid[3], const float vb[3], - float r_co[3]) -{ - float vva[3], vvb[3], point[3], dir[3], vaadj[3], vbadj[3], p2[3], pn[3]; - int n = e->seg; - - sub_v3_v3v3(vva, va, vmid); - sub_v3_v3v3(vvb, vb, vmid); - if (e->is_rev) - sub_v3_v3v3(dir, e->e->v1->co, e->e->v2->co); - else - sub_v3_v3v3(dir, e->e->v2->co, e->e->v1->co); - normalize_v3(dir); - if (fabsf(angle_v3v3(vva, vvb) - (float)M_PI) > 100.f *(float)BEVEL_EPSILON) { - copy_v3_v3(vaadj, va); - madd_v3_v3fl(vaadj, dir, -len_v3(vva) * cosf(angle_v3v3(vva, dir))); - copy_v3_v3(vbadj, vb); - madd_v3_v3fl(vbadj, dir, -len_v3(vvb) * cosf(angle_v3v3(vvb, dir))); - - get_point_on_round_profile(point, e->offset, k, n, vaadj, vmid, vbadj); - - add_v3_v3v3(p2, point, dir); - cross_v3_v3v3(pn, vva, vvb); - if (!isect_line_plane_v3(r_co, point, p2, vmid, pn, 0)) { - /* TODO: track down why this sometimes fails */ - copy_v3_v3(r_co, point); - } - } - else { - /* planar case */ - interp_v3_v3v3(r_co, va, vb, (float)k / (float)n); - } -} -#else - -/* - * Find the point (/n) of the way around the round profile for e, - * where start point is va, midarc point is vmid, and end point is vb. - * Return the answer in profileco. +/* Fill matrix r_mat so that a point in the sheared parallelogram with corners + * va, vmid, vb (and the 4th that is implied by it being a parallelogram) + * is transformed to the unit square by multiplication with r_mat. + * If it can't be done because the parallelogram is degenerate, return FALSE + * else return TRUE. * Method: * Find vo, the origin of the parallelogram with other three points va, vmid, vb. * Also find vd, which is in direction normal to parallelogram and 1 unit away @@ -668,16 +585,14 @@ static void get_point_on_round_edge(EdgeHalf *e, int k, * (1,1,0) -> vmid * (1,0,0) -> vb * (0,1,1) -> vd - * However if va -- vmid -- vb is approximately a straight line, just - * interpolate along the line. - */ -static void get_point_on_round_edge(EdgeHalf *e, int k, - const float va[3], const float vmid[3], const float vb[3], - float r_co[3]) + * We want M to make M*A=B where A has the left side above, as columns + * and B has the right side as columns - both extended into homogeneous coords. + * So M = B*(Ainverse). Doing Ainverse by hand gives the code below. +*/ +static int make_unit_square_map(const float va[3], const float vmid[3], const float vb[3], + float r_mat[4][4]) { - float vo[3], vd[3], vb_vmid[3], va_vmid[3], vddir[3], p[3], angle; - float m[4][4] = MAT4_UNITY; - int n = e->seg; + float vo[3], vd[3], vb_vmid[3], va_vmid[3], vddir[3]; sub_v3_v3v3(va_vmid, vmid, va); sub_v3_v3v3(vb_vmid, vmid, vb); @@ -688,17 +603,43 @@ static void get_point_on_round_edge(EdgeHalf *e, int k, add_v3_v3v3(vd, vo, vddir); /* The cols of m are: {vmid - va, vmid - vb, vmid + vd - va -vb, va + vb - vmid; - * blender transform matrices are stored such that m[i][*] is ith column; - * the last elements of each col remain as they are in unity matrix */ - sub_v3_v3v3(&m[0][0], vmid, va); - sub_v3_v3v3(&m[1][0], vmid, vb); - add_v3_v3v3(&m[2][0], vmid, vd); - sub_v3_v3(&m[2][0], va); - sub_v3_v3(&m[2][0], vb); - add_v3_v3v3(&m[3][0], va, vb); - sub_v3_v3(&m[3][0], vmid); - - /* Now find point k/(e->seg) along quarter circle from (0,1,0) to (1,0,0) */ + * blender transform matrices are stored such that m[i][*] is ith column; + * the last elements of each col remain as they are in unity matrix */ + sub_v3_v3v3(&r_mat[0][0], vmid, va); + r_mat[0][3] = 0.0f; + sub_v3_v3v3(&r_mat[1][0], vmid, vb); + r_mat[1][3] = 0.0f; + add_v3_v3v3(&r_mat[2][0], vmid, vd); + sub_v3_v3(&r_mat[2][0], va); + sub_v3_v3(&r_mat[2][0], vb); + r_mat[2][3] = 0.0f; + add_v3_v3v3(&r_mat[3][0], va, vb); + sub_v3_v3(&r_mat[3][0], vmid); + r_mat[3][3] = 1.0f; + + return TRUE; + } + else + return FALSE; +} + +/* + * Find the point (/n) of the way around the round profile for e, + * where start point is va, midarc point is vmid, and end point is vb. + * Return the answer in profileco. + * If va -- vmid -- vb is approximately a straight line, just + * interpolate along the line. + */ +static void get_point_on_round_edge(EdgeHalf *e, int k, + const float va[3], const float vmid[3], const float vb[3], + float r_co[3]) +{ + float p[3], angle; + float m[4][4]; + int n = e->seg; + + if (make_unit_square_map(va, vmid, vb, m)) { + /* Find point k/(e->seg) along quarter circle from (0,1,0) to (1,0,0) */ angle = (float)M_PI * (float)k / (2.0f * (float)n); /* angle from y axis */ p[0] = sinf(angle); p[1] = cosf(angle); @@ -706,11 +647,47 @@ static void get_point_on_round_edge(EdgeHalf *e, int k, mul_v3_m4v3(r_co, m, p); } else { - /* planar case */ + /* degenerate case: profile is a line */ interp_v3_v3v3(r_co, va, vb, (float)k / (float)n); } } -#endif /* ! OLD_ROUND_EDGE */ + +/* Calculate a snapped point to the transformed profile of edge e, extended as + * in a cylinder-like surface in the direction of e. + * co is the point to snap and is modified in place. + * va and vb are the limits of the profile (with peak on e). */ +static void snap_to_edge_profile(EdgeHalf *e, const float va[3], const float vb[3], + float co[3]) +{ + float m[4][4], minv[4][4]; + float edir[3], va0[3], vb0[3], vmid0[3], p[3], snap[3]; + + sub_v3_v3v3(edir, e->e->v1->co, e->e->v2->co); + normalize_v3(edir); + + /* project va and vb onto plane P, with normal edir and containing co */ + closest_to_plane_v3(va0, co, edir, va); + closest_to_plane_v3(vb0, co, edir, vb); + project_to_edge(e->e, va0, vb0, vmid0); + if (make_unit_square_map(va0, vmid0, vb0, m)) { + /* Transform co and project it onto the unit circle. + * Projecting is in fact just normalizing the transformed co */ + if (!invert_m4_m4(minv, m)) { + /* shouldn't happen, by angle test and construction of vd */ + BLI_assert(!"failed inverse during profile snap"); + return; + } + mul_v3_m4v3(p, minv, co); + normalize_v3(p); + mul_v3_m4v3(snap, m, p); + copy_v3_v3(co, snap); + } + else { + /* planar case: just snap to line va--vb */ + closest_to_line_segment_v3(p, co, va, vb); + copy_v3_v3(co, p); + } +} #endif /* !USE_ALTERNATE_ADJ */ @@ -748,7 +725,9 @@ static void build_boundary(MemArena *mem_arena, BevVert *bv) slide_dist(e->next, bv->v, e->offset, co); v = add_new_bound_vert(mem_arena, vm, co); v->efirst = v->elast = e->next; - vm->mesh_kind = M_POLY; + e->next->leftv = e->next->rightv = v; + /* could use M_POLY too, but tri-fan looks nicer)*/ + vm->mesh_kind = M_TRI_FAN; return; } @@ -839,7 +818,6 @@ static void build_boundary(MemArena *mem_arena, BevVert *bv) else { vm->mesh_kind = M_ADJ; } - /* TODO: if vm->count == 4 and bv->selcount == 4, use M_CROSS pattern */ } /* @@ -852,9 +830,11 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv) VMesh *vm = bv->vmesh; BoundVert *v, *vprev, *vnext; NewVert *nv, *nvprev, *nvnext; + EdgeHalf *e1, *e2, *epipe; BMVert *bmv, *bmv1, *bmv2, *bmv3, *bmv4; BMFace *f; float co[3], coa[3], cob[3], midco[3]; + float va_pipe[3], vb_pipe[3]; #ifdef USE_ALTERNATE_ADJ /* ordered as follows (orig, prev, center, next)*/ @@ -873,6 +853,29 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv) ns = vm->seg; ns2 = ns / 2; BLI_assert(n > 2 && ns > 1); + + /* special case: two beveled edges are in line and share a face, making a "pipe" */ + epipe = NULL; + if (bv->selcount > 2) { + for (e1 = &bv->edges[0]; epipe == NULL && e1 != &bv->edges[bv->edgecount]; e1++) { + if (e1->is_bev) { + for (e2 = &bv->edges[0]; e2 != &bv->edges[bv->edgecount]; e2++) { + if (e1 != e2 && e2->is_bev) { + if ((e1->fnext == e2->fprev) || (e1->fprev == e2->fnext)) { + float dir1[3], dir2[3]; + sub_v3_v3v3(dir1, bv->v->co, BM_edge_other_vert(e1->e, bv->v)->co); + sub_v3_v3v3(dir2, BM_edge_other_vert(e2->e, bv->v)->co, bv->v->co); + if (angle_v3v3(dir1, dir2) < 100.0f * (float)BEVEL_EPSILON) { + epipe = e1; + break; + } + } + } + } + } + } + } + /* Make initial rings, going between points on neighbors. * After this loop, will have coords for all (i, r, k) where * BoundVert for i has a bevel, 0 <= r <= ns2, 0 <= k <= ns */ @@ -943,6 +946,12 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv) get_point_on_round_edge(v->ebev, k, coa, midco, cob, co); copy_v3_v3(mesh_vert(vm, i, ring, k)->co, co); } + + if (v->ebev == epipe) { + /* save profile extremes for later snapping */ + copy_v3_v3(va_pipe, mesh_vert(vm, i, 0, 0)->co); + copy_v3_v3(vb_pipe, mesh_vert(vm, i, 0, ns)->co); + } #endif } } while ((v = v->next) != vm->boundstart); @@ -968,6 +977,9 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv) nv = mesh_vert(vm, i, ring, k); nvprev = mesh_vert(vm, vprev->index, k, ns - ring); mid_v3_v3v3(co, nv->co, nvprev->co); + if (epipe) + snap_to_edge_profile(epipe, va_pipe, vb_pipe, co); + #ifndef USE_ALTERNATE_ADJ copy_v3_v3(nv->co, co); #endif @@ -1017,6 +1029,8 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv) nvnext = mesh_vert(vm, vnext->index, ns2, k); if (vprev->ebev && vnext->ebev) { mid_v3_v3v3v3(co, nvprev->co, nv->co, nvnext->co); + if (epipe) + snap_to_edge_profile(epipe, va_pipe, vb_pipe, co); #ifndef USE_ALTERNATE_ADJ copy_v3_v3(nv->co, co); #endif @@ -1027,6 +1041,8 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv) } else if (vprev->ebev) { mid_v3_v3v3(co, nvprev->co, nv->co); + if (epipe) + snap_to_edge_profile(epipe, va_pipe, vb_pipe, co); #ifndef USE_ALTERNATE_ADJ copy_v3_v3(nv->co, co); #endif @@ -1037,6 +1053,8 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv) } else if (vnext->ebev) { mid_v3_v3v3(co, nv->co, nvnext->co); + if (epipe) + snap_to_edge_profile(epipe, va_pipe, vb_pipe, co); #ifndef USE_ALTERNATE_ADJ copy_v3_v3(nv->co, co); #endif @@ -1064,6 +1082,8 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv) } } while ((v = v->next) != vm->boundstart); mul_v3_fl(midco, 1.0f / nn); + if (epipe) + snap_to_edge_profile(epipe, va_pipe, vb_pipe, midco); bmv = BM_vert_create(bm, midco, NULL, 0); v = vm->boundstart; do { @@ -1275,39 +1295,27 @@ static void bevel_build_quadstrip(BMesh *bm, BevVert *bv) EdgeHalf *eh_b = next_bev(bv, eh_a->next); /* since (selcount == 2) we know this is valid */ BMLoop *l_a = BM_face_vert_share_loop(f, eh_a->rightv->nv.v); BMLoop *l_b = BM_face_vert_share_loop(f, eh_b->leftv->nv.v); - int seg_count = bv->vmesh->seg; /* ensure we don't walk past the segments */ - - if (l_a == l_b) { - /* step once around if we hit the same loop */ - l_a = l_a->prev; - l_b = l_b->next; - seg_count--; - } - - BLI_assert(l_a != l_b); + int split_count = bv->vmesh->seg + 1; /* ensure we don't walk past the segments */ - while (f->len > 4) { + while (f->len > 4 && split_count > 0) { BMLoop *l_new; BLI_assert(l_a->f == f); BLI_assert(l_b->f == f); - BM_face_split(bm, f, l_a->v, l_b->v, &l_new, NULL, FALSE); - if (seg_count-- == 0) { - break; + if (l_a-> v == l_b->v || l_a->next == l_b) { + /* l_a->v and l_b->v can be the same or such that we'd make a 2-vertex poly */ + l_a = l_a->prev; + l_b = l_b->next; } + else { + BM_face_split(bm, f, l_a->v, l_b->v, &l_new, NULL, FALSE); + f = l_new->f; - /* turns out we don't need this, - * because of how BM_face_split works we always get the loop of the next face */ -#if 0 - if (l_new->f->len < l_new->radial_next->f->len) { - l_new = l_new->radial_next; + /* walk around the new face to get the next verts to split */ + l_a = l_new->prev; + l_b = l_new->next->next; } -#endif - f = l_new->f; - - /* walk around the new face to get the next verts to split */ - l_a = l_new->prev; - l_b = l_new->next->next; + split_count--; } } } diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp index 8337a977b3b..de8d1e85eb9 100644 --- a/source/blender/collada/MeshImporter.cpp +++ b/source/blender/collada/MeshImporter.cpp @@ -589,7 +589,7 @@ void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me) for (int i = 0; i < edge_count; i++, med++) { med->bweight = 0; med->crease = 0; - med->flag = 0; + med->flag |= ME_LOOSEEDGE; med->v1 = indices[2 * i]; med->v2 = indices[2 * i + 1]; } diff --git a/source/blender/collada/TransformReader.cpp b/source/blender/collada/TransformReader.cpp index d10cd7378e9..61793589422 100644 --- a/source/blender/collada/TransformReader.cpp +++ b/source/blender/collada/TransformReader.cpp @@ -84,7 +84,7 @@ void TransformReader::dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[ COLLADAFW::Rotate *ro = (COLLADAFW::Rotate *)tm; COLLADABU::Math::Vector3& axis = ro->getRotationAxis(); const float angle = (float)DEG2RAD(ro->getRotationAngle()); - const float ax[] = {axis[0], axis[1], axis[2]}; + const float ax[] = {(float)axis[0], (float)axis[1], (float)axis[2]}; // float quat[4]; // axis_angle_to_quat(quat, axis, angle); // quat_to_mat4(m, quat); diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index 35844b549de..7bdda387d5e 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -139,7 +139,7 @@ Mesh *bc_to_mesh_apply_modifiers(Scene *scene, Object *ob, BC_export_mesh_type e { Mesh *tmpmesh; CustomDataMask mask = CD_MASK_MESH; - DerivedMesh *dm; + DerivedMesh *dm = NULL; switch (export_mesh_type) { case BC_MESH_TYPE_VIEW: { dm = mesh_create_derived_view(scene, ob, mask); @@ -151,7 +151,7 @@ Mesh *bc_to_mesh_apply_modifiers(Scene *scene, Object *ob, BC_export_mesh_type e } } - tmpmesh = BKE_mesh_add("ColladaMesh"); // name is not important here + tmpmesh = BKE_mesh_add("ColladaMesh"); // name is not important here DM_to_mesh(dm, tmpmesh, ob); dm->release(dm); return tmpmesh; diff --git a/source/blender/compositor/intern/COM_Node.cpp b/source/blender/compositor/intern/COM_Node.cpp index 300d7ef1952..d49bb5f96fb 100644 --- a/source/blender/compositor/intern/COM_Node.cpp +++ b/source/blender/compositor/intern/COM_Node.cpp @@ -137,18 +137,26 @@ void Node::addSetVectorOperation(ExecutionSystem *graph, InputSocket *inputsocke graph->addOperation(operation); } -/* when a node has no valid data (missing image or group pointer) */ +NodeOperation *Node::convertToOperations_invalid_index(ExecutionSystem *graph, int index) +{ + const float warning_color[4] = {1.0f, 0.0f, 1.0f, 1.0f}; + SetColorOperation *operation = new SetColorOperation(); + operation->setChannels(warning_color); + + /* link the operation */ + this->getOutputSocket(index)->relinkConnections(operation->getOutputSocket()); + graph->addOperation(operation); + return operation; +} + +/* when a node has no valid data (missing image / group pointer, or missing renderlayer from EXR) */ void Node::convertToOperations_invalid(ExecutionSystem *graph, CompositorContext *context) { /* this is a really bad situation - bring on the pink! - so artists know this is bad */ - const float warning_color[4] = {1.0f, 0.0f, 1.0f, 1.0f}; int index; vector<OutputSocket *> &outputsockets = this->getOutputSockets(); for (index = 0; index < outputsockets.size(); index++) { - SetColorOperation *operation = new SetColorOperation(); - this->getOutputSocket(index)->relinkConnections(operation->getOutputSocket()); - operation->setChannels(warning_color); - graph->addOperation(operation); + convertToOperations_invalid_index(graph, index); } } diff --git a/source/blender/compositor/intern/COM_Node.h b/source/blender/compositor/intern/COM_Node.h index 468a95ed434..c098d6da32b 100644 --- a/source/blender/compositor/intern/COM_Node.h +++ b/source/blender/compositor/intern/COM_Node.h @@ -106,6 +106,10 @@ public: void addSetVectorOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex); /** + * Create dummy warning operation, use when we can't get the source data. + */ + NodeOperation *convertToOperations_invalid_index(ExecutionSystem *graph, int index); + /** * when a node has no valid data (missing image or a group nodes ID pointer is NULL) * call this function from #convertToOperations, this way the node sockets are converted * into valid outputs, without this the compositor system gets confused and crashes, see [#32490] diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp index 729cb1b70a0..4293e344c65 100644 --- a/source/blender/compositor/nodes/COM_ImageNode.cpp +++ b/source/blender/compositor/nodes/COM_ImageNode.cpp @@ -83,6 +83,7 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c is_multilayer_ok = true; for (index = 0; index < numberOfOutputs; index++) { + NodeOperation *operation = NULL; socket = this->getOutputSocket(index); if (socket->isConnected() || index == 0) { bNodeSocket *bnodeSocket = socket->getbNodeSocket(); @@ -91,7 +92,6 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c RenderPass *rpass = (RenderPass *)BLI_findlink(&rl->passes, passindex); if (rpass) { - NodeOperation *operation = NULL; imageuser->pass = passindex; switch (rpass->channels) { case 1: @@ -105,16 +105,21 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c case 4: operation = doMultilayerCheck(graph, rl, image, imageuser, framenumber, index, passindex, COM_DT_COLOR); break; - default: - /* XXX add a dummy operation? */ + /* dummy operation is added below */ break; } + if (index == 0 && operation) { addPreviewOperation(graph, context, operation->getOutputSocket()); } } } + + /* incase we can't load the layer */ + if (operation == NULL) { + convertToOperations_invalid_index(graph, index); + } } } } diff --git a/source/blender/compositor/nodes/COM_ScaleNode.cpp b/source/blender/compositor/nodes/COM_ScaleNode.cpp index d535e71a33c..6f7bd33db6f 100644 --- a/source/blender/compositor/nodes/COM_ScaleNode.cpp +++ b/source/blender/compositor/nodes/COM_ScaleNode.cpp @@ -39,7 +39,7 @@ void ScaleNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c InputSocket *inputXSocket = this->getInputSocket(1); InputSocket *inputYSocket = this->getInputSocket(2); OutputSocket *outputSocket = this->getOutputSocket(0); - BaseScaleOperation *scaleoperation; + BaseScaleOperation *scaleoperation = NULL; bNode *bnode = this->getbNode(); switch (bnode->custom1) { diff --git a/source/blender/compositor/operations/COM_CropOperation.cpp b/source/blender/compositor/operations/COM_CropOperation.cpp index 16c19f3ebaa..4f9cd771988 100644 --- a/source/blender/compositor/operations/COM_CropOperation.cpp +++ b/source/blender/compositor/operations/COM_CropOperation.cpp @@ -58,6 +58,12 @@ void CropBaseOperation::updateArea() this->m_ymax = max(this->m_settings->y1, this->m_settings->y2) + 1; this->m_ymin = min(this->m_settings->y1, this->m_settings->y2); } + else { + this->m_xmax = 0; + this->m_xmin = 0; + this->m_ymax = 0; + this->m_ymin = 0; + } } void CropBaseOperation::initExecution() diff --git a/source/blender/compositor/operations/COM_ImageOperation.cpp b/source/blender/compositor/operations/COM_ImageOperation.cpp index d4c35f5afaa..84557118a1c 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.cpp +++ b/source/blender/compositor/operations/COM_ImageOperation.cpp @@ -109,7 +109,7 @@ void BaseImageOperation::determineResolution(unsigned int resolution[2], unsigne resolution[1] = stackbuf->y; } - IMB_freeImBuf(stackbuf); + BKE_image_release_ibuf(this->m_image, stackbuf, NULL); } void ImageOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c index a59a3f7a5ec..aee97f40c31 100644 --- a/source/blender/editors/gpencil/editaction_gpencil.c +++ b/source/blender/editors/gpencil/editaction_gpencil.c @@ -49,6 +49,7 @@ #include "ED_anim_api.h" #include "ED_gpencil.h" #include "ED_keyframes_edit.h" +#include "ED_markers.h" #include "gpencil_intern.h" @@ -460,11 +461,12 @@ void paste_gpdata(Scene *scene) /* undo and redraw stuff */ BIF_undo_push("Paste Grease Pencil Frames"); } +#endif /* XXX disabled until Grease Pencil code stabilises again... */ /* -------------------------------------- */ /* Snap Tools */ -static short snap_gpf_nearest(bGPDframe *gpf, Scene *scene) +static short snap_gpf_nearest(bGPDframe *gpf, Scene *UNUSED(scene)) { if (gpf->flag & GP_FRAME_SELECT) gpf->framenum = (int)(floor(gpf->framenum + 0.5)); @@ -475,7 +477,7 @@ static short snap_gpf_nearestsec(bGPDframe *gpf, Scene *scene) { float secf = (float)FPS; if (gpf->flag & GP_FRAME_SELECT) - gpf->framenum = (int)(floor(gpf->framenum / secf + 0.5f) * secf); + gpf->framenum = (int)(floorf(gpf->framenum / secf + 0.5f) * secf); return 0; } @@ -489,33 +491,32 @@ static short snap_gpf_cframe(bGPDframe *gpf, Scene *scene) static short snap_gpf_nearmarker(bGPDframe *gpf, Scene *scene) { if (gpf->flag & GP_FRAME_SELECT) - gpf->framenum = (int)find_nearest_marker_time(&scene->markers, (float)gpf->framenum); + gpf->framenum = (int)ED_markers_find_nearest_marker_time(&scene->markers, (float)gpf->framenum); return 0; } - /* snap selected frames to ... */ -void snap_gplayer_frames(bGPDlayer *gpl, Scene *scene, short mode) +void ED_gplayer_snap_frames(bGPDlayer *gpl, Scene *scene, short mode) { switch (mode) { - case 1: /* snap to nearest frame */ + case SNAP_KEYS_NEARFRAME: /* snap to nearest frame */ ED_gplayer_frames_looper(gpl, scene, snap_gpf_nearest); break; - case 2: /* snap to current frame */ + case SNAP_KEYS_CURFRAME: /* snap to current frame */ ED_gplayer_frames_looper(gpl, scene, snap_gpf_cframe); break; - case 3: /* snap to nearest marker */ + case SNAP_KEYS_NEARMARKER: /* snap to nearest marker */ ED_gplayer_frames_looper(gpl, scene, snap_gpf_nearmarker); break; - case 4: /* snap to nearest second */ + case SNAP_KEYS_NEARSEC: /* snap to nearest second */ ED_gplayer_frames_looper(gpl, scene, snap_gpf_nearestsec); break; default: /* just in case */ - ED_gplayer_frames_looper(gpl, scene, snap_gpf_nearest); break; } } +#if 0 /* XXX disabled until grease pencil code stabilises again */ /* -------------------------------------- */ /* Mirror Tools */ diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index e04bbc1f2bf..8fdca730674 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1815,10 +1815,16 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event) * better in tools that immediately apply * in 3D space. */ - + /* we don't pass on key events, GP is used with key-modifiers - prevents Dkey to insert drivers */ - if (ISKEYBOARD(event->type)) - estate = OPERATOR_RUNNING_MODAL; + if (ISKEYBOARD(event->type)) { + if (ELEM4(event->type, LEFTARROWKEY, DOWNARROWKEY, RIGHTARROWKEY, UPARROWKEY)) { + /* allow some keys - for frame changing: [#33412] */ + } + else { + estate = OPERATOR_RUNNING_MODAL; + } + } //printf("\tGP - handle modal event...\n"); diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index 39dd8822267..5cc1ecade3e 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -97,12 +97,13 @@ void ED_gpencil_select_frame(struct bGPDlayer *gpl, int selx, short select_mode void ED_gplayer_frames_delete(struct bGPDlayer *gpl); void ED_gplayer_frames_duplicate(struct bGPDlayer *gpl); +void ED_gplayer_snap_frames(struct bGPDlayer *gpl, struct Scene *scene, short mode); + #if 0 void free_gpcopybuf(void); void copy_gpdata(void); void paste_gpdata(void); -void snap_gplayer_frames(struct bGPDlayer *gpl, short mode); void mirror_gplayer_frames(struct bGPDlayer *gpl, short mode); #endif diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h index 46ed9798d32..6644f59be94 100644 --- a/source/blender/editors/include/ED_mask.h +++ b/source/blender/editors/include/ED_mask.h @@ -83,12 +83,13 @@ void ED_mask_select_frame(struct MaskLayer *masklay, int selx, short select_mod void ED_masklayer_frames_delete(struct MaskLayer *masklay); void ED_masklayer_frames_duplicate(struct MaskLayer *masklay); +void ED_masklayer_snap_frames(struct MaskLayer *masklay, struct Scene *scene, short mode); + #if 0 void free_gpcopybuf(void); void copy_gpdata(void); void paste_gpdata(void); -void snap_masklayer_frames(struct MaskLayer *masklay, short mode); void mirror_masklayer_frames(struct MaskLayer *masklay, short mode); #endif diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index 10c585aa802..99f7f0856b3 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -97,7 +97,7 @@ DEF_ICON(PLUGIN) /* various ui */ DEF_ICON(HELP) DEF_ICON(GHOST_ENABLED) -DEF_ICON(COLOR) +DEF_ICON(COLOR) /* see COLOR_RED/GREEN/BLUE */ DEF_ICON(LINKED) DEF_ICON(UNLINKED) DEF_ICON(HAND) @@ -428,9 +428,11 @@ DEF_ICON(CURVE_PATH) DEF_ICON(BLANK646) DEF_ICON(BLANK647) DEF_ICON(BLANK648) - DEF_ICON(BLANK649) - DEF_ICON(BLANK650) - DEF_ICON(BLANK651) +#endif +DEF_ICON(COLOR_RED) +DEF_ICON(COLOR_GREEN) +DEF_ICON(COLOR_BLUE) +#ifndef DEF_ICON_BLANK_SKIP DEF_ICON(BLANK652) DEF_ICON(BLANK653) DEF_ICON(BLANK654) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index f5c943fbb87..2dc552d0fce 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -542,7 +542,7 @@ typedef struct uiStringInfo { /* Note: Expects pointers to uiStringInfo structs as parameters. * Will fill them with translated strings, when possible. * Strings in uiStringInfo must be MEM_freeN'ed by caller. */ -void uiButGetStrInfo(struct bContext *C, uiBut *but, int nbr, ...); +void uiButGetStrInfo(struct bContext *C, uiBut *but, ...); /* Edit i18n stuff. */ /* Name of the main py op from i18n addon. */ @@ -817,6 +817,7 @@ void uiTemplateImage(uiLayout *layout, struct bContext *C, struct PointerRNA *pt void uiTemplateImageSettings(uiLayout *layout, struct PointerRNA *imfptr, int color_management); void uiTemplateImageLayers(uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser); void uiTemplateRunningJobs(uiLayout *layout, struct bContext *C); +void uiOperatorSearch_But(uiBut *but); void uiTemplateOperatorSearch(uiLayout *layout); void uiTemplateHeader3D(uiLayout *layout, struct bContext *C); void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 9037afc472a..ce82e064531 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -3797,16 +3797,16 @@ void uiButSetFocusOnEnter(wmWindow *win, uiBut *but) wm_event_add(win, &event); } -void uiButGetStrInfo(bContext *C, uiBut *but, int nbr, ...) +void uiButGetStrInfo(bContext *C, uiBut *but, ...) { va_list args; + uiStringInfo *si; EnumPropertyItem *items = NULL, *item = NULL; int totitems, free_items = FALSE; - va_start(args, nbr); - while (nbr--) { - uiStringInfo *si = (uiStringInfo *) va_arg(args, void *); + va_start(args, but); + while ((si = (uiStringInfo *) va_arg(args, void *))) { int type = si->type; char *tmp = NULL; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 5f01255b8e0..b80025e0d77 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -4633,7 +4633,7 @@ static int ui_but_menu(bContext *C, uiBut *but) uiPopupMenu *pup; uiLayout *layout; int length; - char *name; + const char *name; uiStringInfo label = {BUT_GET_LABEL, NULL}; /* if ((but->rnapoin.data && but->rnaprop) == 0 && but->optype == NULL)*/ @@ -4641,7 +4641,7 @@ static int ui_but_menu(bContext *C, uiBut *but) button_timers_tooltip_remove(C, but); - uiButGetStrInfo(C, but, 1, &label); + uiButGetStrInfo(C, but, &label, NULL); name = label.strinfo; pup = uiPupMenuBegin(C, name, ICON_NONE); diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index e7a5f993d32..e57e52d74b6 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -960,7 +960,6 @@ static int edittranslation_exec(bContext *C, wmOperator *op) const char *root = U.i18ndir; const char *uilng = BLF_lang_get(); - const int bufs_nbr = 10; uiStringInfo but_label = {BUT_GET_LABEL, NULL}; uiStringInfo rna_label = {BUT_GET_RNA_LABEL, NULL}; uiStringInfo enum_label = {BUT_GET_RNAENUM_LABEL, NULL}; @@ -990,8 +989,8 @@ static int edittranslation_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - uiButGetStrInfo(C, but, bufs_nbr, &but_label, &rna_label, &enum_label, &but_tip, &rna_tip, &enum_tip, - &rna_struct, &rna_prop, &rna_enum, &rna_ctxt); + uiButGetStrInfo(C, but, &but_label, &rna_label, &enum_label, &but_tip, &rna_tip, &enum_tip, + &rna_struct, &rna_prop, &rna_enum, &rna_ctxt, NULL); WM_operator_properties_create(&ptr, EDTSRC_I18N_OP_NAME); RNA_string_set(&ptr, "lang", uilng); diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 7c099de9c1e..c13aadee069 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -46,6 +46,7 @@ #include "BKE_context.h" #include "BKE_screen.h" +#include "BKE_idcode.h" #include "BKE_global.h" #include "WM_api.h" @@ -426,7 +427,6 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) rctf rect_fl; rcti rect_i; - const int nbr_info = 6; uiStringInfo but_tip = {BUT_GET_TIP, NULL}; uiStringInfo enum_label = {BUT_GET_RNAENUM_LABEL, NULL}; uiStringInfo enum_tip = {BUT_GET_RNAENUM_TIP, NULL}; @@ -440,50 +440,11 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) /* create tooltip data */ data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData"); - uiButGetStrInfo(C, but, nbr_info, &but_tip, &enum_label, &enum_tip, &op_keymap, &rna_struct, &rna_prop); + uiButGetStrInfo(C, but, &but_tip, &enum_label, &enum_tip, &op_keymap, &rna_struct, &rna_prop, NULL); /* special case, enum rna buttons only have enum item description, * use general enum description too before the specific one */ -#if 0 - if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) { - const char *descr = RNA_property_description(but->rnaprop); - if (descr && descr[0]) { - BLI_strncpy(data->lines[data->totline], descr, sizeof(data->lines[0])); - data->color_id[data->totline] = UI_TIP_LC_MAIN; - data->totline++; - } - - if (ELEM(but->type, ROW, MENU)) { - EnumPropertyItem *item; - int totitem, free; - int value = (but->type == ROW) ? (int)but->hardmax : (int)ui_get_but_val(but); - RNA_property_enum_items_gettexted(C, &but->rnapoin, but->rnaprop, &item, &totitem, &free); - - for (i = 0; i < totitem; i++) { - if (item[i].identifier[0] && item[i].value == value) { - if (item[i].description && item[i].description[0]) { - BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "%s: %s", - item[i].name, item[i].description); - data->color_id[data->totline] = UI_TIP_LC_SUBMENU; - data->totline++; - } - break; - } - } - - if (free) { - MEM_freeN(item); - } - } - } - - if (but->tip && but->tip[0] != '\0') { - BLI_strncpy(data->lines[data->totline], but->tip, sizeof(data->lines[0])); - data->color_id[data->totline] = UI_TIP_LC_MAIN; - data->totline++; - } -#else /* Tip */ if (but_tip.strinfo) { BLI_strncpy(data->lines[data->totline], but_tip.strinfo, sizeof(data->lines[0])); @@ -497,29 +458,13 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) data->color_id[data->totline] = UI_TIP_LC_SUBMENU; data->totline++; } -#endif -#if 0 - if (but->optype && !(but->block->flag & UI_BLOCK_LOOP)) { - /* operator keymap (not menus, they already have it) */ - prop = (but->opptr) ? but->opptr->data : NULL; - - if (WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, TRUE, - buf, sizeof(buf))) - { - BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Shortcut: %s"), buf); - data->color_id[data->totline] = UI_TIP_LC_NORMAL; - data->totline++; - } - } -#else /* Op shortcut */ if (op_keymap.strinfo) { BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Shortcut: %s"), op_keymap.strinfo); data->color_id[data->totline] = UI_TIP_LC_NORMAL; data->totline++; } -#endif if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) { /* full string */ @@ -553,15 +498,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) data->totline++; } } -#if 0 - /* rna info */ - if ((U.flag & USER_TOOLTIPS_PYTHON) == 0) { - BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Python: %s.%s"), - RNA_struct_identifier(but->rnapoin.type), RNA_property_identifier(but->rnaprop)); - data->color_id[data->totline] = UI_TIP_LC_PYTHON; - data->totline++; - } -#endif + if (but->rnapoin.id.data) { ID *id = but->rnapoin.id.data; if (id->lib && id->lib->name) { @@ -603,30 +540,55 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) } } } -#if 0 - else if (ELEM(but->type, MENU, PULLDOWN)) { - if ((U.flag & USER_TOOLTIPS_PYTHON) == 0) { - MenuType *mt = uiButGetMenuType(but); - if (mt) { - BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Python: %s"), mt->idname); - data->color_id[data->totline] = UI_TIP_LC_PYTHON; - data->totline++; - } - } - } -#else if ((U.flag & USER_TOOLTIPS_PYTHON) == 0 && !but->optype && rna_struct.strinfo) { - if (rna_prop.strinfo) + if (rna_prop.strinfo) { /* Struct and prop */ BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), - TIP_("Python: %s.%s"), rna_struct.strinfo, rna_prop.strinfo); - else + TIP_("Python: %s.%s"), + rna_struct.strinfo, rna_prop.strinfo); + } + else { /* Only struct (e.g. menus) */ - BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Python: %s"), rna_struct.strinfo); + BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), + TIP_("Python: %s"), rna_struct.strinfo); + } data->color_id[data->totline] = UI_TIP_LC_PYTHON; data->totline++; + + if (but->rnapoin.id.data) { + /* this could get its own 'BUT_GET_...' type */ + PointerRNA *ptr = &but->rnapoin; + PropertyRNA *prop = but->rnaprop; + ID *id = ptr->id.data; + + char *id_path; + char *data_path = NULL; + + /* never fails */ + id_path = RNA_path_from_ID_python(id); + + if (ptr->id.data && ptr->data && prop) { + data_path = RNA_path_from_ID_to_property(ptr, prop); + } + + if (data_path) { + BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), + "%s.%s", /* no need to translate */ + id_path, data_path); + MEM_freeN(data_path); + } + else if (prop) { + /* can't find the path. be explicit in our ignorance "..." */ + BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), + "%s ... %s", /* no need to translate */ + id_path, rna_prop.strinfo ? rna_prop.strinfo : RNA_property_identifier(prop)); + } + MEM_freeN(id_path); + + data->color_id[data->totline] = UI_TIP_LC_PYTHON; + data->totline++; + } } -#endif /* Free strinfo's... */ if (but_tip.strinfo) @@ -642,7 +604,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) if (rna_prop.strinfo) MEM_freeN(rna_prop.strinfo); - assert(data->totline < MAX_TOOLTIP_LINES); + BLI_assert(data->totline < MAX_TOOLTIP_LINES); if (data->totline == 0) { MEM_freeN(data); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index e90fc1d4695..84ee0ffebe1 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2024,10 +2024,16 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe } if (cmp) { + const float range_clamp[2] = {0.0f, 1.0f}; + const float range_unclamp[2] = {-1000.0f, 1000.0f}; /* arbitrary limits here */ + const float *range = (cumap->flag & CUMA_DO_CLIP) ? range_clamp : range_unclamp; + uiLayoutRow(layout, TRUE); uiBlockSetNFunc(block, curvemap_buttons_update, MEM_dupallocN(cb), cumap); - bt = uiDefButF(block, NUM, 0, "X", 0, 2 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y, &cmp->x, 0.0f, 1.0f, 1, 5, ""); - bt = uiDefButF(block, NUM, 0, "Y", 0, 1 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y, &cmp->y, 0.0f, 1.0f, 1, 5, ""); + bt = uiDefButF(block, NUM, 0, "X", 0, 2 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y, + &cmp->x, range[0], range[1], 1, 5, ""); + bt = uiDefButF(block, NUM, 0, "Y", 0, 1 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y, + &cmp->y, range[0], range[1], 1, 5, ""); } /* black/white levels */ @@ -2087,19 +2093,19 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna PropertyRNA *prop = RNA_struct_find_property(ptr, propname); uiBlock *block = uiLayoutGetBlock(layout); uiLayout *col, *row; - uiBut *but; + uiBut *but = NULL; float softmin, softmax, step, precision; - + if (!prop) { RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); return; } RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision); - + col = uiLayoutColumn(layout, TRUE); row = uiLayoutRow(col, TRUE); - + switch (U.color_picker_type) { case USER_CP_CIRCLE: but = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop, @@ -2118,7 +2124,6 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna -1, 0.0, 0.0, UI_GRAD_HV, 0, ""); break; } - if (lock) { but->flag |= UI_BUT_COLOR_LOCK; @@ -2136,7 +2141,6 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna if (value_slider) { - switch (U.color_picker_type) { case USER_CP_CIRCLE: uiItemS(row); @@ -2159,7 +2163,6 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna -1, softmin, softmax, UI_GRAD_HV + 3, 0, ""); break; } - } } @@ -2785,6 +2788,9 @@ static void operator_search_cb(const bContext *C, void *UNUSED(arg), const char for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) { wmOperatorType *ot = BLI_ghashIterator_getValue(iter); + if ((ot->flag & OPTYPE_INTERNAL) && (G.debug & G_DEBUG_WM) == 0) + continue; + if (BLI_strcasestr(ot->name, str)) { if (WM_operator_poll((bContext *)C, ot)) { char name[256]; @@ -2810,6 +2816,11 @@ static void operator_search_cb(const bContext *C, void *UNUSED(arg), const char BLI_ghashIterator_free(iter); } +void uiOperatorSearch_But(uiBut *but) +{ + uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb, NULL); +} + void uiTemplateOperatorSearch(uiLayout *layout) { uiBlock *block; @@ -2820,7 +2831,7 @@ void uiTemplateOperatorSearch(uiLayout *layout) uiBlockSetCurLayout(block, layout); but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, 0, 0, ""); - uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb, NULL); + uiOperatorSearch_But(but); } /************************* Running Jobs Template **************************/ diff --git a/source/blender/editors/mask/mask_editaction.c b/source/blender/editors/mask/mask_editaction.c index 561ad004a1d..707622fa841 100644 --- a/source/blender/editors/mask/mask_editaction.c +++ b/source/blender/editors/mask/mask_editaction.c @@ -18,13 +18,13 @@ * The Original Code is Copyright (C) 2008, Blender Foundation * This is a new part of Blender * - * Contributor(s): Joshua Leung + * Contributor(s): Campbell Barton * * ***** END GPL LICENSE BLOCK ***** */ /** \file blender/editors/mask/mask_editaction.c - * \ingroup edgpencil + * \ingroup edmask */ #include <stdio.h> @@ -49,17 +49,18 @@ #include "ED_anim_api.h" #include "ED_keyframes_edit.h" #include "ED_mask.h" /* own include */ +#include "ED_markers.h" /* ***************************************** */ /* NOTE ABOUT THIS FILE: - * This file contains code for editing Grease Pencil data in the Action Editor - * as a 'keyframes', so that a user can adjust the timing of Grease Pencil drawings. - * Therefore, this file mostly contains functions for selecting Grease-Pencil frames. + * This file contains code for editing Mask data in the Action Editor + * as a 'keyframes', so that a user can adjust the timing of Mask shapekeys. + * Therefore, this file mostly contains functions for selecting Mask frames (shapekeys). */ /* ***************************************** */ /* Generics - Loopers */ -/* Loops over the gp-frames for a gp-layer, and applies the given callback */ +/* Loops over the mask-frames for a mask-layer, and applies the given callback */ short ED_masklayer_frames_looper(MaskLayer *masklay, Scene *scene, short (*masklay_shape_cb)(MaskLayerShape *, Scene *)) { MaskLayerShape *masklay_shape; @@ -82,7 +83,7 @@ short ED_masklayer_frames_looper(MaskLayer *masklay, Scene *scene, short (*maskl /* ****************************************** */ /* Data Conversion Tools */ -/* make a listing all the gp-frames in a layer as cfraelems */ +/* make a listing all the mask-frames in a layer as cfraelems */ void ED_masklayer_make_cfra_list(MaskLayer *masklay, ListBase *elems, short onlysel) { MaskLayerShape *masklay_shape; @@ -92,7 +93,7 @@ void ED_masklayer_make_cfra_list(MaskLayer *masklay, ListBase *elems, short only if (ELEM(NULL, masklay, elems)) return; - /* loop through gp-frames, adding */ + /* loop through mask-frames, adding */ for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) { if ((onlysel == 0) || (masklay_shape->flag & MASK_SHAPE_SELECT)) { ce = MEM_callocN(sizeof(CfraElem), "CfraElem"); @@ -127,7 +128,7 @@ short ED_masklayer_frame_select_check(MaskLayer *masklay) return 0; } -/* helper function - select gp-frame based on SELECT_* mode */ +/* helper function - select mask-frame based on SELECT_* mode */ static void masklayshape_select(MaskLayerShape *masklay_shape, short select_mode) { if (masklay_shape == NULL) @@ -223,7 +224,7 @@ void ED_masklayer_frames_delete(MaskLayer *masklay) } } -/* Duplicate selected frames from given gp-layer */ +/* Duplicate selected frames from given mask-layer */ void ED_masklayer_frames_duplicate(MaskLayer *masklay) { MaskLayerShape *masklay_shape, *gpfn; @@ -249,3 +250,57 @@ void ED_masklayer_frames_duplicate(MaskLayer *masklay) } } } + +/* -------------------------------------- */ +/* Snap Tools */ + +static short snap_masklayer_nearest(MaskLayerShape *masklay_shape, Scene *UNUSED(scene)) +{ + if (masklay_shape->flag & MASK_SHAPE_SELECT) + masklay_shape->frame = (int)(floor(masklay_shape->frame + 0.5)); + return 0; +} + +static short snap_masklayer_nearestsec(MaskLayerShape *masklay_shape, Scene *scene) +{ + float secf = (float)FPS; + if (masklay_shape->flag & MASK_SHAPE_SELECT) + masklay_shape->frame = (int)(floorf(masklay_shape->frame / secf + 0.5f) * secf); + return 0; +} + +static short snap_masklayer_cframe(MaskLayerShape *masklay_shape, Scene *scene) +{ + if (masklay_shape->flag & MASK_SHAPE_SELECT) + masklay_shape->frame = (int)CFRA; + return 0; +} + +static short snap_masklayer_nearmarker(MaskLayerShape *masklay_shape, Scene *scene) +{ + if (masklay_shape->flag & MASK_SHAPE_SELECT) + masklay_shape->frame = (int)ED_markers_find_nearest_marker_time(&scene->markers, (float)masklay_shape->frame); + return 0; +} + +/* snap selected frames to ... */ +void ED_masklayer_snap_frames(MaskLayer *masklay, Scene *scene, short mode) +{ + switch (mode) { + case SNAP_KEYS_NEARFRAME: /* snap to nearest frame */ + ED_masklayer_frames_looper(masklay, scene, snap_masklayer_nearest); + break; + case SNAP_KEYS_CURFRAME: /* snap to current frame */ + ED_masklayer_frames_looper(masklay, scene, snap_masklayer_cframe); + break; + case SNAP_KEYS_NEARMARKER: /* snap to nearest marker */ + ED_masklayer_frames_looper(masklay, scene, snap_masklayer_nearmarker); + break; + case SNAP_KEYS_NEARSEC: /* snap to nearest second */ + ED_masklayer_frames_looper(masklay, scene, snap_masklayer_nearestsec); + break; + default: /* just in case */ + break; + } +} + diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index cd6063b12d0..eed72935b3c 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -55,6 +55,8 @@ /* ********* add primitive operators ************* */ +/* BMESH_TODO: 'state' is not a good name, should be flipped and called 'was_editmode', + * or at least something more descriptive */ static Object *make_prim_init(bContext *C, const char *idname, float *dia, float mat[][4], int *state, const float loc[3], const float rot[3], const unsigned int layer) @@ -81,16 +83,17 @@ static Object *make_prim_init(bContext *C, const char *idname, static void make_prim_finish(bContext *C, Object *obedit, int *state, int enter_editmode) { BMEditMesh *em = BMEdit_FromObject(obedit); + const int exit_editmode = (*state && !enter_editmode); /* Primitive has all verts selected, use vert select flush * to push this up to edges & faces. */ EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX); /* only recalc editmode tessface if we are staying in editmode */ - EDBM_update_generic(C, em, enter_editmode); + EDBM_update_generic(C, em, !exit_editmode); /* userdef */ - if (*state && !enter_editmode) { + if (exit_editmode) { ED_object_exit_editmode(C, EM_FREEDATA); /* adding EM_DO_UNDO messes up operator redo */ } WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit); diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 9dc68848c69..d5cf174b1a1 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -207,8 +207,12 @@ typedef struct KnifeTool_OpData { static ListBase *knife_get_face_kedges(KnifeTool_OpData *kcd, BMFace *f); +#if 0 static void knife_input_ray_cast(KnifeTool_OpData *kcd, const int mval_i[2], float r_origin[3], float r_ray[3]); +#endif +static void knife_input_ray_segment(KnifeTool_OpData *kcd, const int mval_i[2], const float ofs, + float r_origin[3], float r_dest[3]); static void knife_update_header(bContext *C, KnifeTool_OpData *kcd) { @@ -379,14 +383,13 @@ static void knife_start_cut(KnifeTool_OpData *kcd) if (kcd->prev.vert == NULL && kcd->prev.edge == NULL && is_zero_v3(kcd->prev.cage)) { /* Make prevcage a point on the view ray to mouse closest to a point on model: choose vertex 0 */ - float origin[3], ray[3], co[3]; + float origin[3], origin_ofs[3]; BMVert *v0; - knife_input_ray_cast(kcd, kcd->curr.mval, origin, ray); - add_v3_v3v3(co, origin, ray); + knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, origin, origin_ofs); v0 = BM_vert_at_index(kcd->em->bm, 0); if (v0) { - closest_to_line_v3(kcd->prev.cage, v0->co, co, origin); + closest_to_line_v3(kcd->prev.cage, v0->co, origin_ofs, origin); copy_v3_v3(kcd->prev.co, kcd->prev.cage); /*TODO: do we need this? */ copy_v3_v3(kcd->curr.cage, kcd->prev.cage); copy_v3_v3(kcd->curr.co, kcd->prev.co); @@ -1403,6 +1406,8 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd) BLI_smallhash_release(ehash); } +/* this works but gives numeric problems [#33400] */ +#if 0 static void knife_input_ray_cast(KnifeTool_OpData *kcd, const int mval_i[2], float r_origin[3], float r_ray[3]) { @@ -1433,17 +1438,41 @@ static void knife_input_ray_cast(KnifeTool_OpData *kcd, const int mval_i[2], mul_m4_v3(kcd->ob->imat, r_origin); mul_m3_v3(imat, r_ray); } +#endif + +static void knife_input_ray_segment(KnifeTool_OpData *kcd, const int mval_i[2], const float ofs, + float r_origin[3], float r_origin_ofs[3]) +{ + bglMats mats; + float mval[2]; + + knife_bgl_get_mats(kcd, &mats); + + mval[0] = (float)mval_i[0]; + mval[1] = (float)mval_i[1]; + + /* unproject to find view ray */ + ED_view3d_unproject(&mats, r_origin, mval[0], mval[1], 0.0f); + ED_view3d_unproject(&mats, r_origin_ofs, mval[0], mval[1], ofs); + + /* transform into object space */ + invert_m4_m4(kcd->ob->imat, kcd->ob->obmat); + + mul_m4_v3(kcd->ob->imat, r_origin); + mul_m4_v3(kcd->ob->imat, r_origin_ofs); +} static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float cageco[3], int *is_space) { BMFace *f; float dist = KMAXDIST; float origin[3]; + float origin_ofs[3]; float ray[3]; /* unproject to find view ray */ - knife_input_ray_cast(kcd, kcd->vc.mval, origin, ray); - add_v3_v3v3(co, origin, ray); + knife_input_ray_segment(kcd, kcd->vc.mval, 1.0f, origin, origin_ofs); + sub_v3_v3v3(ray, origin_ofs, origin); f = BMBVH_RayCast(kcd->bmbvh, origin, ray, co, cageco); @@ -1768,12 +1797,12 @@ static int knife_update_active(KnifeTool_OpData *kcd) * Note that drawing lines in `free-space` isn't properly supported * but theres no guarantee (0, 0, 0) has any geometry either - campbell */ if (kcd->curr.vert == NULL && kcd->curr.edge == NULL) { - float origin[3], ray[3], co[3]; + float origin[3]; + float origin_ofs[3]; - knife_input_ray_cast(kcd, kcd->vc.mval, origin, ray); - add_v3_v3v3(co, origin, ray); + knife_input_ray_segment(kcd, kcd->vc.mval, 1.0f, origin, origin_ofs); - closest_to_line_v3(kcd->curr.cage, kcd->prev.cage, co, origin); + closest_to_line_v3(kcd->curr.cage, kcd->prev.cage, origin_ofs, origin); } if (kcd->mode == MODE_DRAGGING) { diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index f886b52e2ce..0988a196fb1 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -643,8 +643,8 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object /* apply transformation of previous parenting */ if (keep_transform) { - /* was removed because of bug [#23577], - * but this can be handy in some cases too [#32616], so make optional */ + /* was removed because of bug [#23577], + * but this can be handy in some cases too [#32616], so make optional */ BKE_object_apply_mat4(ob, ob->obmat, FALSE, FALSE); } diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 9a49a1970a0..f8154f4abda 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -560,10 +560,10 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) rj->iuser.ok = 1; rj->reports = op->reports; - if(v3d) { + if (v3d) { rj->lay = v3d->lay; - if(v3d->localvd) + if (v3d->localvd) rj->lay |= v3d->localvd->lay; } diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index effb984c083..73f8abdf15f 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -481,7 +481,7 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); OGLRender *oglrender = op->customdata; Scene *scene = oglrender->scene; - ImBuf *ibuf; + ImBuf *ibuf, *ibuf_save = NULL; void *lock; char name[FILE_MAX]; int ok = 0; @@ -549,47 +549,46 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op) if (ibuf) { int needs_free = FALSE; - if (is_movie || !BKE_imtype_requires_linear_float(scene->r.im_format.imtype)) { - ImBuf *colormanage_ibuf; + ibuf_save = ibuf; - colormanage_ibuf = IMB_colormanagement_imbuf_for_write(ibuf, TRUE, TRUE, &scene->view_settings, - &scene->display_settings, &scene->r.im_format); + if (is_movie || !BKE_imtype_requires_linear_float(scene->r.im_format.imtype)) { + ibuf_save = IMB_colormanagement_imbuf_for_write(ibuf, TRUE, TRUE, &scene->view_settings, + &scene->display_settings, &scene->r.im_format); - // IMB_freeImBuf(ibuf); /* owned by the image */ - ibuf = colormanage_ibuf; needs_free = TRUE; } /* color -> grayscale */ /* editing directly would alter the render view */ if (scene->r.im_format.planes == R_IMF_PLANES_BW) { - ImBuf *ibuf_bw = IMB_dupImBuf(ibuf); + ImBuf *ibuf_bw = IMB_dupImBuf(ibuf_save); IMB_color_to_bw(ibuf_bw); if (needs_free) - IMB_freeImBuf(ibuf); + IMB_freeImBuf(ibuf_save); - ibuf = ibuf_bw; + ibuf_save = ibuf_bw; } else { /* this is lightweight & doesnt re-alloc the buffers, only do this * to save the correct bit depth since the image is always RGBA */ - ImBuf *ibuf_cpy = IMB_allocImBuf(ibuf->x, ibuf->y, scene->r.im_format.planes, 0); - ibuf_cpy->rect = ibuf->rect; - ibuf_cpy->rect_float = ibuf->rect_float; - ibuf_cpy->zbuf_float = ibuf->zbuf_float; + ImBuf *ibuf_cpy = IMB_allocImBuf(ibuf_save->x, ibuf_save->y, scene->r.im_format.planes, 0); + + ibuf_cpy->rect = ibuf_save->rect; + ibuf_cpy->rect_float = ibuf_save->rect_float; + ibuf_cpy->zbuf_float = ibuf_save->zbuf_float; if (needs_free) { - ibuf_cpy->mall = ibuf->mall; - ibuf->mall = 0; - IMB_freeImBuf(ibuf); + ibuf_cpy->mall = ibuf_save->mall; + ibuf_save->mall = 0; + IMB_freeImBuf(ibuf_save); } - ibuf = ibuf_cpy; + ibuf_save = ibuf_cpy; } if (is_movie) { - ok = oglrender->mh->append_movie(&scene->r, SFRA, CFRA, (int *)ibuf->rect, + ok = oglrender->mh->append_movie(&scene->r, SFRA, CFRA, (int *)ibuf_save->rect, oglrender->sizex, oglrender->sizey, oglrender->reports); if (ok) { printf("Append frame %d", scene->r.cfra); @@ -597,7 +596,7 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op) } } else { - ok = BKE_imbuf_write_stamp(scene, camera, ibuf, name, &scene->r.im_format); + ok = BKE_imbuf_write_stamp(scene, camera, ibuf_save, name, &scene->r.im_format); if (ok == 0) { printf("Write error: cannot save %s\n", name); @@ -609,8 +608,8 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op) } } - /* imbuf knows which rects are not part of ibuf */ - IMB_freeImBuf(ibuf); + if (needs_free) + IMB_freeImBuf(ibuf_save); } BKE_image_release_ibuf(oglrender->ima, ibuf, lock); diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index e9fbb3a0885..1ed1cbb2c6b 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -156,12 +156,16 @@ void ED_render_engine_changed(Main *bmain) /* on changing the render engine type, clear all running render engines */ bScreen *sc; ScrArea *sa; + Scene *scene; for (sc = bmain->screen.first; sc; sc = sc->id.next) for (sa = sc->areabase.first; sa; sa = sa->next) ED_render_engine_area_exit(sa); RE_FreePersistentData(); + + for (scene = bmain->scene.first; scene; scene = scene->id.next) + ED_render_id_flush_update(bmain, &scene->id); } /***************************** Updates *********************************** diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index a929c3ef585..b704414c321 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -3937,7 +3937,7 @@ BLI_INLINE void rgba_float_to_uchar__mul_v3(unsigned char rgba_ub[4], const floa { rgba_ub[0] = f_to_char(rgba[0] * rgb[0]); rgba_ub[1] = f_to_char(rgba[1] * rgb[1]); - rgba_ub[2] = f_to_char(rgba[2] * rgb[3]); + rgba_ub[2] = f_to_char(rgba[2] * rgb[2]); rgba_ub[3] = f_to_char(rgba[3]); } diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index ae78b71f2ad..a80d425b90a 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -52,6 +52,7 @@ #include "BKE_action.h" #include "BKE_fcurve.h" +#include "BKE_global.h" #include "BKE_nla.h" #include "BKE_context.h" #include "BKE_report.h" @@ -493,7 +494,7 @@ static int actkeys_copy_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; /* copy keyframes */ - if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { + if (ac.datatype == ANIMCONT_GPENCIL) { /* FIXME... */ BKE_report(op->reports, RPT_ERROR, "Keyframe pasting is not available for grease pencil mode"); return OPERATOR_CANCELLED; @@ -1308,6 +1309,15 @@ void ACTION_OT_keyframe_type(wmOperatorType *ot) /* ***************** Jump to Selected Frames Operator *********************** */ +static int actkeys_framejump_poll(bContext *C) +{ + /* prevent changes during render */ + if (G.is_rendering) + return 0; + + return ED_operator_action_active(C); +} + /* snap current-frame indicator to 'average time' of selected keyframe */ static int actkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op)) { @@ -1361,7 +1371,7 @@ void ACTION_OT_frame_jump(wmOperatorType *ot) /* api callbacks */ ot->exec = actkeys_framejump_exec; - ot->poll = ED_operator_action_active; + ot->poll = actkeys_framejump_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -1412,15 +1422,20 @@ static void snap_action_keys(bAnimContext *ac, short mode) for (ale = anim_data.first; ale; ale = ale->next) { AnimData *adt = ANIM_nla_mapping_get(ac, ale); - if (adt) { + if (ale->type == ANIMTYPE_GPLAYER) { + ED_gplayer_snap_frames(ale->data, ac->scene, mode); + } + else if (ale->type == ANIMTYPE_MASKLAYER) { + ED_masklayer_snap_frames(ale->data, ac->scene, mode); + } + else if (adt) { ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve); ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); } - //else if (ale->type == ACTTYPE_GPLAYER) - // snap_gplayer_frames(ale->data, mode); - else + else { ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve); + } } BLI_freelistN(&anim_data); @@ -1436,11 +1451,7 @@ static int actkeys_snap_exec(bContext *C, wmOperator *op) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - - /* XXX... */ - if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) - return OPERATOR_PASS_THROUGH; - + /* get snapping mode */ mode = RNA_enum_get(op->ptr, "type"); @@ -1448,7 +1459,8 @@ static int actkeys_snap_exec(bContext *C, wmOperator *op) snap_action_keys(&ac, mode); /* validate keyframes after editing */ - ANIM_editkeyframes_refresh(&ac); + if (!ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) + ANIM_editkeyframes_refresh(&ac); /* set notifier that keyframes have changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index a7f18c9de53..91f069d16de 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -823,12 +823,12 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r ButsContextTexture *ct = sbuts->texuser; PointerRNA *ptr; - if (ct) - return 0; /* new shading system */ - if ((ptr = get_pointer_type(path, &RNA_Material))) { Material *ma = ptr->data; + if (ct) + return 0; /* new shading system */ + /* if we have a node material, get slot from material in material node */ if (ma && ma->use_nodes && ma->nodetree) { /* if there's an active texture node in the node tree, @@ -849,12 +849,18 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r else if ((ptr = get_pointer_type(path, &RNA_Lamp))) { Lamp *la = ptr->data; + if (ct) + return 0; /* new shading system */ + if (la) CTX_data_pointer_set(result, &la->id, &RNA_LampTextureSlot, la->mtex[(int)la->texact]); } else if ((ptr = get_pointer_type(path, &RNA_World))) { World *wo = ptr->data; + if (ct) + return 0; /* new shading system */ + if (wo) CTX_data_pointer_set(result, &wo->id, &RNA_WorldTextureSlot, wo->mtex[(int)wo->texact]); } diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c index f19835b7f85..a215b476094 100644 --- a/source/blender/editors/space_console/console_draw.c +++ b/source/blender/editors/space_console/console_draw.c @@ -146,7 +146,8 @@ static int console_textview_line_get(struct TextViewContext *tvc, const char **l ConsoleLine *cl = (ConsoleLine *)tvc->iter; *line = cl->line; *len = cl->len; - + // printf("'%s' %d\n", *line, cl->len); + BLI_assert(cl->line[cl->len] == '\0' && (cl->len == 0 || cl->line[cl->len - 1] != '\0')); return 1; } diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index bb46135545c..36716aeab95 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -444,7 +444,7 @@ static int console_indent_exec(bContext *C, wmOperator *UNUSED(op)) console_line_verify_length(ci, ci->len + len); - memmove(ci->line + len, ci->line, ci->len); + memmove(ci->line + len, ci->line, ci->len + 1); memset(ci->line, ' ', len); ci->len += len; BLI_assert(ci->len >= 0); diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index 75add570708..be8febdab23 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -170,16 +170,13 @@ static int id_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event static void id_drop_copy(wmDrag *drag, wmDropBox *drop) { - char text[64]; + char *text; ID *id = drag->poin; - char id_esc[(sizeof(id->name) - 2) * 2]; - - BLI_strescape(id_esc, id->name + 2, sizeof(id_esc)); - - BLI_snprintf(text, sizeof(text), "bpy.data.%s[\"%s\"]", BKE_idcode_to_name_plural(GS(id->name)), id_esc); /* copy drag path to properties */ + text = RNA_path_from_ID_python(id); RNA_string_set(drop->ptr, "text", text); + MEM_freeN(text); } static int path_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event)) diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 453549ebf79..21b0ed99f0b 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -56,6 +56,7 @@ #include "BLF_translation.h" #include "BKE_fcurve.h" +#include "BKE_global.h" #include "BKE_nla.h" #include "BKE_context.h" #include "BKE_report.h" @@ -1763,6 +1764,15 @@ void GRAPH_OT_euler_filter(wmOperatorType *ot) /* ***************** Jump to Selected Frames Operator *********************** */ +static int graphkeys_framejump_poll(bContext *C) +{ + /* prevent changes during render */ + if (G.is_rendering) + return 0; + + return graphop_visible_keyframes_poll(C); +} + /* snap current-frame indicator to 'average time' of selected keyframe */ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op)) { @@ -1829,7 +1839,7 @@ void GRAPH_OT_frame_jump(wmOperatorType *ot) /* api callbacks */ ot->exec = graphkeys_framejump_exec; - ot->poll = graphop_visible_keyframes_poll; + ot->poll = graphkeys_framejump_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index 9b031c015a9..54b417e740a 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -39,6 +39,7 @@ #include "BLI_utildefines.h" #include "BKE_context.h" +#include "BKE_global.h" #include "BKE_main.h" #include "BKE_sound.h" @@ -66,6 +67,15 @@ * 2) Value Indicator (stored per Graph Editor instance) */ +static int graphview_cursor_poll(bContext *C) +{ + /* prevent changes during render */ + if (G.is_rendering) + return 0; + + return ED_operator_graphedit_active(C); +} + /* Set the new frame number */ static void graphview_cursor_apply(bContext *C, wmOperator *op) { @@ -172,7 +182,7 @@ static void GRAPH_OT_cursor_set(wmOperatorType *ot) ot->exec = graphview_cursor_exec; ot->invoke = graphview_cursor_invoke; ot->modal = graphview_cursor_modal; - ot->poll = ED_operator_graphedit_active; + ot->poll = graphview_cursor_poll; /* flags */ ot->flag = OPTYPE_BLOCKING | OPTYPE_UNDO; diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c index 04d2947ce89..96ac716f383 100644 --- a/source/blender/editors/space_node/node_add.c +++ b/source/blender/editors/space_node/node_add.c @@ -386,6 +386,9 @@ static int node_add_file_exec(bContext *C, wmOperator *op) node->id = (ID *)ima; id_us_plus(node->id); + BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD); + WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima); + snode_notify(C, snode); snode_dag_update(C, snode); diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 4e2bf982ff3..e7f77db3b9e 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2405,6 +2405,15 @@ static int strip_jump_internal(Scene *scene, return change; } +static int sequencer_strip_jump_poll(bContext *C) +{ + /* prevent changes during render */ + if (G.is_rendering) + return 0; + + return sequencer_edit_poll(C); +} + /* jump frame to edit point operator */ static int sequencer_strip_jump_exec(bContext *C, wmOperator *op) { @@ -2431,7 +2440,7 @@ void SEQUENCER_OT_strip_jump(wmOperatorType *ot) /* api callbacks */ ot->exec = sequencer_strip_jump_exec; - ot->poll = sequencer_edit_poll; + ot->poll = sequencer_strip_jump_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -3076,8 +3085,12 @@ static int sequencer_change_path_invoke(bContext *C, wmOperator *op, wmEvent *UN { Scene *scene = CTX_data_scene(C); Sequence *seq = BKE_sequencer_active_get(scene); + char filepath[FILE_MAX]; + + BLI_join_dirfile(filepath, sizeof(filepath), seq->strip->dir, seq->strip->stripdata->name); RNA_string_set(op->ptr, "directory", seq->strip->dir); + RNA_string_set(op->ptr, "filepath", filepath); /* set default display depending on seq type */ if (seq->type == SEQ_TYPE_IMAGE) { diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index cd6d8719544..5b7f92739ed 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -615,6 +615,8 @@ static int text_run_script(bContext *C, ReportList *reports) } BKE_report(reports, RPT_ERROR, "Python script fail, look in the console for now..."); + + return OPERATOR_FINISHED; } #else (void)C; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 79c34f93a10..f272cb61c26 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -229,7 +229,10 @@ static int check_alpha_pass(Base *base) if (G.f & G_PICKSEL) return 0; - + + if (base->object->mode & OB_MODE_ALL_PAINT) + return 0; + return (base->object->dtx & OB_DRAWTRANSP); } @@ -2595,7 +2598,7 @@ static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitS BMIter iter; int i; - /* make the precision of the pronted value proportionate to the gridsize */ + /* make the precision of the display value proportionate to the gridsize */ if (grid < 0.01f) conv_float = "%.6g"; else if (grid < 0.1f) conv_float = "%.5g"; diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 53f983912ac..cffa53b5dfb 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -221,7 +221,7 @@ static void edbm_backbuf_check_and_select_faces(BMEditMesh *em, int select) } -/* object mode, EM_ prefix is confusing here, rename? */ +/* object mode, edbm_ prefix is confusing here, rename? */ static void edbm_backbuf_check_and_select_verts_obmode(Mesh *me, int select) { MVert *mv = me->mvert; @@ -237,8 +237,8 @@ static void edbm_backbuf_check_and_select_verts_obmode(Mesh *me, int select) } } } -/* object mode, EM_ prefix is confusing here, rename? */ +/* object mode, edbm_ prefix is confusing here, rename? */ static void edbm_backbuf_check_and_select_tfaces(Mesh *me, int select) { MPoly *mpoly = me->mpoly; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index a6fb7e7ed00..2d95e2ecdc6 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -408,9 +408,15 @@ static void initSnappingMode(TransInfo *t) t->tsnap.mode = ts->snap_node_mode; } + else if (t->spacetype == SPACE_IMAGE) { + /* force project off when not supported */ + t->tsnap.project = 0; + + t->tsnap.mode = ts->snap_uv_mode; + } else { /* force project off when not supported */ - if (t->spacetype == SPACE_IMAGE || ts->snap_mode != SCE_SNAP_MODE_FACE) + if (ts->snap_mode != SCE_SNAP_MODE_FACE) t->tsnap.project = 0; t->tsnap.mode = ts->snap_mode; diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 1eec06eee75..1f3f21967f4 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -232,7 +232,7 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh BLI_srand(0); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - ScanFillVert *sf_vert, *sf_vert_last, *sf_vert_first; + ScanFillVert *sf_vert = NULL, *sf_vert_last, *sf_vert_first; ScanFillFace *sf_tri; ParamKey key, vkeys[4]; ParamBool pin[4], select[4]; diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h index 5f6eb45ad70..b26c25558c3 100644 --- a/source/blender/gpu/GPU_draw.h +++ b/source/blender/gpu/GPU_draw.h @@ -116,7 +116,7 @@ void GPU_set_anisotropic(float value); float GPU_get_anisotropic(void); /* enable gpu mipmapping */ -void GPU_set_gpu_mipmapping(void); +void GPU_set_gpu_mipmapping(int gpu_mipmap); /* Image updates and free * - these deal with images bound as opengl textures */ diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index f2ddedcd76c..d466e59452b 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -240,10 +240,16 @@ static struct GPUTextureState { /* Mipmap settings */ -void GPU_set_gpu_mipmapping() +void GPU_set_gpu_mipmapping(int gpu_mipmap) { - /* always enable if it's supported */ - GTS.gpu_mipmap = GLEW_EXT_framebuffer_object; + int old_value = GTS.gpu_mipmap; + + /* only actually enable if it's supported */ + GTS.gpu_mipmap = gpu_mipmap && GLEW_EXT_framebuffer_object; + + if (old_value != GTS.gpu_mipmap) { + GPU_free_images(); + } } void GPU_set_mipmap(int mipmap) @@ -721,8 +727,8 @@ int GPU_upload_dxt_texture(ImBuf *ibuf) GLint format = 0; int blocksize, height, width, i, size, offset = 0; - height = ibuf->x; - width = ibuf->y; + width = ibuf->x; + height = ibuf->y; if (GLEW_EXT_texture_compression_s3tc) { if (ibuf->dds_data.fourcc == FOURCC_DXT1) diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index cef664437b7..7a0ac29c9ab 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -253,6 +253,9 @@ static void GPU_print_framebuffer_error(GLenum status, char err_out[256]) switch (status) { case GL_FRAMEBUFFER_COMPLETE_EXT: break; + case GL_INVALID_OPERATION: + err= "Invalid operation"; + break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: err= "Incomplete attachment"; break; @@ -754,6 +757,7 @@ int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, char err { GLenum status; GLenum attachment; + GLenum error; if (tex->depth) attachment = GL_DEPTH_ATTACHMENT_EXT; @@ -766,6 +770,14 @@ int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, char err glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, tex->target, tex->bindcode, 0); + error = glGetError(); + + if (error == GL_INVALID_OPERATION) { + GPU_framebuffer_restore(); + GPU_print_framebuffer_error(error, err_out); + return 0; + } + if (tex->depth) { glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 497105d94ec..9c48f74bf5f 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -1497,6 +1497,16 @@ static GPUNodeLink *GPU_blender_material(GPUMaterial *mat, Material *ma) return shr.combined; } +static GPUNodeLink *gpu_material_diffuse_bsdf(GPUMaterial *mat, Material *ma) +{ + static float roughness = 0.0f; + GPUNodeLink *outlink; + + GPU_link(mat, "node_bsdf_diffuse", GPU_uniform(&ma->r), GPU_uniform(&roughness), GPU_builtin(GPU_VIEW_NORMAL), &outlink); + + return outlink; +} + GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma) { GPUMaterial *mat; @@ -1516,8 +1526,15 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma) ntreeGPUMaterialNodes(ma->nodetree, mat); } else { - /* create material */ - outlink = GPU_blender_material(mat, ma); + if(BKE_scene_use_new_shading_nodes(scene)) { + /* create simple diffuse material instead of nodes */ + outlink = gpu_material_diffuse_bsdf(mat, ma); + } + else { + /* create blender material */ + outlink = GPU_blender_material(mat, ma); + } + GPU_material_output_link(mat, outlink); } diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp index 5cf762af3e8..903080d5b79 100644 --- a/source/blender/ikplugin/intern/itasc_plugin.cpp +++ b/source/blender/ikplugin/intern/itasc_plugin.cpp @@ -1636,7 +1636,7 @@ static void execute_scene(Scene *blscene, IK_Scene *ikscene, bItasc *ikparam, fl // compute constraint error for (i = ikscene->targets.size(); i > 0; --i) { IK_Target *iktarget = ikscene->targets[i - 1]; - if (!(iktarget->blenderConstraint->flag & CONSTRAINT_OFF)) { + if (!(iktarget->blenderConstraint->flag & CONSTRAINT_OFF) && iktarget->constraint) { unsigned int nvalues; const iTaSC::ConstraintValues *values; values = iktarget->constraint->getControlParameters(&nvalues); diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index 5b64416c309..8dfdbd4fddc 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -821,6 +821,14 @@ static int ffmpeg_decode_video_frame(struct anim *anim) } if (rval == AVERROR_EOF) { + /* this sets size and data fields to zero, + which is necessary to decode the remaining data + in the decoder engine after EOF. It also prevents a memory + leak, since av_read_frame spills out a full size packet even + on EOF... (and: it's save to call on NULL packets) */ + + av_free_packet(&anim->next_packet); + anim->next_packet.size = 0; anim->next_packet.data = 0; diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c index 8d289de9970..f049c404e2d 100644 --- a/source/blender/imbuf/intern/divers.c +++ b/source/blender/imbuf/intern/divers.c @@ -196,7 +196,7 @@ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from, { float tmp[4]; int x, y; - DitherContext *di; + DitherContext *di = NULL; /* we need valid profiles */ BLI_assert(profile_to != IB_PROFILE_NONE); diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c index 38bd28452f3..277f50bcdbc 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -912,6 +912,8 @@ static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context, AVPacket next_packet; uint64_t stream_size; + memset(&next_packet, 0, sizeof(AVPacket)); + in_frame = avcodec_alloc_frame(); stream_size = avio_size(context->iFormatCtx->pb); @@ -959,12 +961,13 @@ static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context, * according to ffmpeg docs using 0-size packets. * * At least, if we haven't already stopped... */ + + /* this creates the 0-size packet and prevents a memory leak. */ + av_free_packet(&next_packet); + if (!*stop) { int frame_finished; - next_packet.size = 0; - next_packet.data = 0; - do { frame_finished = 0; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 3e226135741..8af971b9b65 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1018,7 +1018,7 @@ typedef struct ToolSettings { /* Transform */ char snap_mode, snap_node_mode; - char pad3; + char snap_uv_mode; short snap_flag, snap_target; short proportional, prop_mode; char proportional_objects; /* proportional edit, object mode */ diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 0df6fc41269..e22bffd7db7 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -897,6 +897,7 @@ int RNA_path_resolve_full(PointerRNA *ptr, const char *path, char *RNA_path_from_ID_to_struct(PointerRNA *ptr); char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop); +char *RNA_path_from_ID_python(struct ID *id); /* Quick name based property access * diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 470e87daeea..488dbffc3db 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -46,6 +46,7 @@ #include "BKE_animsys.h" #include "BKE_context.h" +#include "BKE_idcode.h" #include "BKE_idprop.h" #include "BKE_main.h" #include "BKE_report.h" @@ -4163,6 +4164,19 @@ char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop) return path; } +/** + * Get the ID as a python representation, eg: + * bpy.data.foo["bar"] + */ +char *RNA_path_from_ID_python(ID *id) +{ + char id_esc[(sizeof(id->name) - 2) * 2]; + + BLI_strescape(id_esc, id->name + 2, sizeof(id_esc)); + + return BLI_sprintfN("bpy.data.%s[\"%s\"]", BKE_idcode_to_name_plural(GS(id->name)), id_esc); +} + /* Quick name based property access */ int RNA_boolean_get(PointerRNA *ptr, const char *name) diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 06df6c5afbc..a2b0945fb46 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -2207,6 +2207,7 @@ static void rna_def_modifier_smoke(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "type"); RNA_def_property_enum_items(prop, prop_smoke_type_items); RNA_def_property_ui_text(prop, "Type", ""); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, 0, "rna_Smoke_set_type"); } diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index ffcca772764..6527fe29263 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -146,6 +146,11 @@ EnumPropertyItem snap_node_element_items[] = { {0, NULL, 0, NULL, NULL} }; +EnumPropertyItem snap_uv_element_items[] = { + {SCE_SNAP_MODE_INCREMENT, "INCREMENT", ICON_SNAP_INCREMENT, "Increment", "Snap to increments of grid"}, + {SCE_SNAP_MODE_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices"}, + {0, NULL, 0, NULL, NULL} +}; /* workaround for duplicate enums, * have each enum line as a defne then conditionally set it or not @@ -1689,6 +1694,13 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_enum_items(prop, snap_node_element_items); RNA_def_property_ui_text(prop, "Snap Node Element", "Type of element to snap to"); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */ + + /* image editor uses own set of snap modes */ + prop = RNA_def_property(srna, "snap_uv_element", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "snap_uv_mode"); + RNA_def_property_enum_items(prop, snap_uv_element_items); + RNA_def_property_ui_text(prop, "Snap UV Element", "Type of element to snap to"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */ prop = RNA_def_property(srna, "snap_target", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "snap_target"); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 2aa907b72f2..c928e91ea1f 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -2977,10 +2977,9 @@ static void rna_def_space_node(BlenderRNA *brna) {SNODE_USE_ALPHA, "COLOR_ALPHA", ICON_IMAGE_RGB_ALPHA, "Color and Alpha", "Draw image with RGB colors and alpha transparency"}, {SNODE_SHOW_ALPHA, "ALPHA", ICON_IMAGE_ALPHA, "Alpha", "Draw alpha transparency channel"}, - /* XXX, we could use better icons here */ - {SNODE_SHOW_R, "RED", ICON_COLOR, "Red", ""}, - {SNODE_SHOW_G, "GREEN", ICON_COLOR, "Green", ""}, - {SNODE_SHOW_B, "BLUE", ICON_COLOR, "Blue", ""}, + {SNODE_SHOW_R, "RED", ICON_COLOR_RED, "Red", ""}, + {SNODE_SHOW_G, "GREEN", ICON_COLOR_GREEN, "Green", ""}, + {SNODE_SHOW_B, "BLUE", ICON_COLOR_BLUE, "Blue", ""}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index b212879512e..bdf9fa4e436 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -264,19 +264,24 @@ char *rna_TextureSlot_path(PointerRNA *ptr) * may be used multiple times in the same stack */ if (ptr->id.data) { - PointerRNA id_ptr; - PropertyRNA *prop; - - /* find the 'textures' property of the ID-struct */ - RNA_id_pointer_create(ptr->id.data, &id_ptr); - prop = RNA_struct_find_property(&id_ptr, "texture_slots"); - - /* get an iterator for this property, and try to find the relevant index */ - if (prop) { - int index = RNA_property_collection_lookup_index(&id_ptr, prop, ptr); - - if (index >= 0) - return BLI_sprintfN("texture_slots[%d]", index); + if (GS(((ID *)ptr->id.data)->name) == ID_BR) { + return BLI_strdup("texture_slot"); + } + else { + PointerRNA id_ptr; + PropertyRNA *prop; + + /* find the 'textures' property of the ID-struct */ + RNA_id_pointer_create(ptr->id.data, &id_ptr); + prop = RNA_struct_find_property(&id_ptr, "texture_slots"); + + /* get an iterator for this property, and try to find the relevant index */ + if (prop) { + int index = RNA_property_collection_lookup_index(&id_ptr, prop, ptr); + + if (index >= 0) + return BLI_sprintfN("texture_slots[%d]", index); + } } } diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 50341c84b8f..59a3a8c2522 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -144,6 +144,12 @@ static void rna_userdef_anisotropic_update(Main *bmain, Scene *scene, PointerRNA rna_userdef_update(bmain, scene, ptr); } +static void rna_userdef_gl_gpu_mipmaps(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + GPU_set_gpu_mipmapping(U.use_gpu_mipmap); + rna_userdef_update(bmain, scene, ptr); +} + static void rna_userdef_gl_texture_limit_update(Main *bmain, Scene *scene, PointerRNA *ptr) { GPU_free_images(); @@ -3228,6 +3234,11 @@ static void rna_def_userdef_system(BlenderRNA *brna) RNA_def_property_ui_text(prop, "16 Bit Float Textures", "Use 16 bit per component texture for float images"); RNA_def_property_update(prop, 0, "rna_userdef_gl_use_16bit_textures"); + prop = RNA_def_property(srna, "use_gpu_mipmap", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "use_gpu_mipmap", 1); + RNA_def_property_ui_text(prop, "GPU Mipmap Generation", "Generate Image Mipmaps on the GPU"); + RNA_def_property_update(prop, 0, "rna_userdef_gl_gpu_mipmaps"); + prop = RNA_def_property(srna, "use_vertex_buffer_objects", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_VBO); RNA_def_property_ui_text(prop, "VBOs", diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index fbd3c084e70..75e54d77b15 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -750,6 +750,10 @@ static DerivedMesh *applyModifier( CDDM_calc_normals(result); } + if (numFaces == 0 && numEdges != 0) { + modifier_setError(md, "Faces needed for useful output"); + } + return result; } diff --git a/source/blender/nodes/composite/nodes/node_composite_blur.c b/source/blender/nodes/composite/nodes/node_composite_blur.c index b9b2406631b..eb7f7763afb 100644 --- a/source/blender/nodes/composite/nodes/node_composite_blur.c +++ b/source/blender/nodes/composite/nodes/node_composite_blur.c @@ -726,7 +726,9 @@ static void node_composit_exec_blur(void *data, bNode *node, bNodeStack **in, bN static void node_composit_init_blur(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp)) { - node->storage = MEM_callocN(sizeof(NodeBlurData), "node blur data"); + NodeBlurData *data = MEM_callocN(sizeof(NodeBlurData), "node blur data"); + data->filtertype = R_FILTER_GAUSS; + node->storage = data; } void register_node_type_cmp_blur(bNodeTreeType *ttype) diff --git a/source/blender/nodes/composite/nodes/node_composite_outputFile.c b/source/blender/nodes/composite/nodes/node_composite_outputFile.c index 656e2a72c03..214617c91e5 100644 --- a/source/blender/nodes/composite/nodes/node_composite_outputFile.c +++ b/source/blender/nodes/composite/nodes/node_composite_outputFile.c @@ -242,7 +242,7 @@ static void exec_output_file_singlelayer(RenderData *rd, bNode *node, bNodeStack ImageFormatData *format = (sockdata->use_node_format ? &nimf->format : &sockdata->format); char path[FILE_MAX]; char filename[FILE_MAX]; - CompBuf *cbuf; + CompBuf *cbuf = NULL; ImBuf *ibuf; switch (format->planes) { diff --git a/source/blender/nodes/shader/nodes/node_shader_material.c b/source/blender/nodes/shader/nodes/node_shader_material.c index bccf6d349cf..2902bf143c8 100644 --- a/source/blender/nodes/shader/nodes/node_shader_material.c +++ b/source/blender/nodes/shader/nodes/node_shader_material.c @@ -85,7 +85,7 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in, float col[4]; bNodeSocket *sock; char hasinput[NUM_MAT_IN] = {'\0'}; - int i; + int i, mode; /* note: cannot use the in[]->hasinput flags directly, as these are not necessarily * the constant input stack values (e.g. in case material node is inside a group). @@ -142,10 +142,18 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in, nodestack_get_vec(&shi->translucency, SOCK_FLOAT, in[MAT_IN_TRANSLUCENCY]); } + /* make alpha output give results even if transparency is only enabled on + * the material linked in this not and not on the parent material */ + mode = shi->mode; + if(shi->mat->mode & MA_TRANSP) + shi->mode |= MA_TRANSP; + shi->nodes= 1; /* temp hack to prevent trashadow recursion */ node_shader_lamp_loop(shi, &shrnode); /* clears shrnode */ shi->nodes= 0; + shi->mode = mode; + /* write to outputs */ if (node->custom1 & SH_NODE_MAT_DIFF) { copy_v3_v3(col, shrnode.combined); diff --git a/source/blender/python/bmesh/bmesh_py_api.c b/source/blender/python/bmesh/bmesh_py_api.c index 697a9259b37..18f5d895132 100644 --- a/source/blender/python/bmesh/bmesh_py_api.c +++ b/source/blender/python/bmesh/bmesh_py_api.c @@ -153,13 +153,6 @@ static struct PyMethodDef BPy_BM_methods[] = { PyDoc_STRVAR(BPy_BM_doc, "This module provides access to blenders bmesh data structures.\n" "\n" -"\n" -"Submodules:\n" -"\n" -"* :mod:`bmesh.utils`\n" -"* :mod:`bmesh.types`\n" -"\n" -"\n" ".. include:: include__bmesh.rst\n" ); static struct PyModuleDef BPy_BM_module_def = { diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 94cbee383ea..cdecf64c93c 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -268,6 +268,23 @@ void BPY_python_start(int argc, const char **argv) Py_Initialize(); + /* THIS IS BAD: see http://bugs.python.org/issue16129 */ +#if 1 + /* until python provides a reliable way to set the env var */ + PyRun_SimpleString("import sys, io\n" + "sys.__backup_stdio__ = sys.__stdout__, sys.__stderr__\n" /* else we loose the FD's [#32720] */ + "sys.__stdout__ = sys.stdout = io.TextIOWrapper(io.open(sys.stdout.fileno(), 'wb', -1), " + "encoding='utf-8', errors='surrogateescape', newline='\\n', line_buffering=True)\n" + "sys.__stderr__ = sys.stderr = io.TextIOWrapper(io.open(sys.stderr.fileno(), 'wb', -1), " + "encoding='utf-8', errors='surrogateescape', newline='\\n', line_buffering=True)\n"); + if (PyErr_Occurred()) { + PyErr_Print(); + PyErr_Clear(); + } +#endif + /* end the baddness */ + + // PySys_SetArgv(argc, argv); /* broken in py3, not a huge deal */ /* sigh, why do python guys not have a (char **) version anymore? */ { @@ -601,7 +618,7 @@ int BPY_button_exec(bContext *C, const char *expr, double *value, const short ve } } - PyC_MainModule_Backup(&main_mod); + PyC_MainModule_Restore(main_mod); bpy_context_clear(C, &gilstate); diff --git a/source/blender/python/intern/bpy_traceback.c b/source/blender/python/intern/bpy_traceback.c index f7aa6e0880b..48bf65a841b 100644 --- a/source/blender/python/intern/bpy_traceback.c +++ b/source/blender/python/intern/bpy_traceback.c @@ -39,70 +39,80 @@ static const char *traceback_filepath(PyTracebackObject *tb, PyObject **coerce) return PyBytes_AS_STRING((*coerce = PyUnicode_EncodeFSDefault(tb->tb_frame->f_code->co_filename))); } -/* copied from pythonrun.c, 3.2.0 */ +/* copied from pythonrun.c, 3.3.0 */ static int parse_syntax_error(PyObject *err, PyObject **message, const char **filename, int *lineno, int *offset, const char **text) { long hold; PyObject *v; + _Py_IDENTIFIER(msg); + _Py_IDENTIFIER(filename); + _Py_IDENTIFIER(lineno); + _Py_IDENTIFIER(offset); + _Py_IDENTIFIER(text); - /* old style errors */ - if (PyTuple_Check(err)) - return PyArg_ParseTuple(err, "O(ziiz)", message, filename, - lineno, offset, text); + *message = NULL; /* new style errors. `err' is an instance */ - - if (!(v = PyObject_GetAttrString(err, "msg"))) + *message = _PyObject_GetAttrId(err, &PyId_msg); + if (!*message) goto finally; - *message = v; - if (!(v = PyObject_GetAttrString(err, "filename"))) + v = _PyObject_GetAttrId(err, &PyId_filename); + if (!v) goto finally; - if (v == Py_None) + if (v == Py_None) { + Py_DECREF(v); *filename = NULL; - else if (!(*filename = _PyUnicode_AsString(v))) - goto finally; + } + else { + *filename = _PyUnicode_AsString(v); + Py_DECREF(v); + if (!*filename) + goto finally; + } - Py_DECREF(v); - if (!(v = PyObject_GetAttrString(err, "lineno"))) + v = _PyObject_GetAttrId(err, &PyId_lineno); + if (!v) goto finally; hold = PyLong_AsLong(v); Py_DECREF(v); - v = NULL; if (hold < 0 && PyErr_Occurred()) goto finally; *lineno = (int)hold; - if (!(v = PyObject_GetAttrString(err, "offset"))) + v = _PyObject_GetAttrId(err, &PyId_offset); + if (!v) goto finally; if (v == Py_None) { *offset = -1; Py_DECREF(v); - v = NULL; - } - else { + } else { hold = PyLong_AsLong(v); Py_DECREF(v); - v = NULL; if (hold < 0 && PyErr_Occurred()) goto finally; *offset = (int)hold; } - if (!(v = PyObject_GetAttrString(err, "text"))) + v = _PyObject_GetAttrId(err, &PyId_text); + if (!v) goto finally; - if (v == Py_None) + if (v == Py_None) { + Py_DECREF(v); *text = NULL; - else if (!PyUnicode_Check(v) || - !(*text = _PyUnicode_AsString(v))) - goto finally; - Py_DECREF(v); + } + else { + *text = _PyUnicode_AsString(v); + Py_DECREF(v); + if (!*text) + goto finally; + } return 1; finally: - Py_XDECREF(v); + Py_XDECREF(*message); return 0; } /* end copied function! */ diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h index 6aa50cf88de..b5f679b741f 100644 --- a/source/blender/python/intern/bpy_util.h +++ b/source/blender/python/intern/bpy_util.h @@ -27,16 +27,8 @@ #ifndef __BPY_UTIL_H__ #define __BPY_UTIL_H__ -#if PY_VERSION_HEX < 0x03020000 -# error "Python 3.2 or greater is required, you'll need to update your python." -#endif - #if PY_VERSION_HEX < 0x03030000 -# ifdef _MSC_VER -# pragma message("Python 3.2 will be deprecated soon, upgrade to Python 3.3.") -# else -# warning "Python 3.2 will be deprecated soon, upgrade to Python 3.3." -# endif +# error "Python 3.3 or greater is required, you'll need to update your python." #endif struct EnumPropertyItem; diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c index a4a4010005a..202598233b6 100644 --- a/source/blender/python/mathutils/mathutils.c +++ b/source/blender/python/mathutils/mathutils.c @@ -35,7 +35,10 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_dynstr.h" + +#ifndef MATH_STANDALONE +# include "BLI_dynstr.h" +#endif PyDoc_STRVAR(M_Mathutils_doc, "This module provides access to matrices, eulers, quaternions and vectors." @@ -302,7 +305,7 @@ int EXPP_FloatsAreEqual(float af, float bf, int maxDiff) /*---------------------- EXPP_VectorsAreEqual ------------------------- * Builds on EXPP_FloatsAreEqual to test vectors */ -int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps) +int EXPP_VectorsAreEqual(const float *vecA, const float *vecB, int size, int floatSteps) { int x; for (x = 0; x < size; x++) { @@ -312,6 +315,7 @@ int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps) return 1; } +#ifndef MATH_STANDALONE /* dynstr as python string utility funcions, frees 'ds'! */ PyObject *mathutils_dynstr_to_py(struct DynStr *ds) { @@ -324,6 +328,7 @@ PyObject *mathutils_dynstr_to_py(struct DynStr *ds) PyMem_Free(ds_buf); return ret; } +#endif /* silly function, we dont use arg. just check its compatible with __deepcopy__ */ int mathutils_deepcopy_args_check(PyObject *args) diff --git a/source/blender/python/mathutils/mathutils.h b/source/blender/python/mathutils/mathutils.h index d4673d14823..7b03b149459 100644 --- a/source/blender/python/mathutils/mathutils.h +++ b/source/blender/python/mathutils/mathutils.h @@ -74,7 +74,7 @@ void BaseMathObject_dealloc(BaseMathObject * self); PyMODINIT_FUNC PyInit_mathutils(void); int EXPP_FloatsAreEqual(float A, float B, int floatSteps); -int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps); +int EXPP_VectorsAreEqual(const float *vecA, const float *vecB, int size, int floatSteps); #define Py_NEW 1 #define Py_WRAP 2 @@ -120,8 +120,11 @@ int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error int column_vector_multiplication(float rvec[4], VectorObject *vec, MatrixObject *mat); +#ifndef MATH_STANDALONE /* dynstr as python string utility funcions */ PyObject *mathutils_dynstr_to_py(struct DynStr *ds); +#endif + int mathutils_deepcopy_args_check(PyObject *args); #endif /* __MATHUTILS_H__ */ diff --git a/source/blender/python/mathutils/mathutils_Color.c b/source/blender/python/mathutils/mathutils_Color.c index f16b488f9d0..4a29e72418b 100644 --- a/source/blender/python/mathutils/mathutils_Color.c +++ b/source/blender/python/mathutils/mathutils_Color.c @@ -31,7 +31,10 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_dynstr.h" + +#ifndef MATH_STANDALONE +# include "BLI_dynstr.h" +#endif #define COLOR_SIZE 3 @@ -131,6 +134,7 @@ static PyObject *Color_repr(ColorObject *self) return ret; } +#ifndef MATH_STANDALONE static PyObject *Color_str(ColorObject *self) { DynStr *ds; @@ -145,6 +149,7 @@ static PyObject *Color_str(ColorObject *self) return mathutils_dynstr_to_py(ds); /* frees ds */ } +#endif /* ------------------------tp_richcmpr */ /* returns -1 exception, 0 false, 1 true */ @@ -820,7 +825,11 @@ PyTypeObject color_Type = { &Color_AsMapping, /* tp_as_mapping */ NULL, /* tp_hash */ NULL, /* tp_call */ +#ifndef MATH_STANDALONE (reprfunc) Color_str, /* tp_str */ +#else + NULL, /* tp_str */ +#endif NULL, /* tp_getattro */ NULL, /* tp_setattro */ NULL, /* tp_as_buffer */ diff --git a/source/blender/python/mathutils/mathutils_Euler.c b/source/blender/python/mathutils/mathutils_Euler.c index 829d3ee27e1..1be8a5efe28 100644 --- a/source/blender/python/mathutils/mathutils_Euler.c +++ b/source/blender/python/mathutils/mathutils_Euler.c @@ -35,7 +35,10 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_dynstr.h" + +#ifndef MATH_STANDALONE +# include "BLI_dynstr.h" +#endif #define EULER_SIZE 3 @@ -323,6 +326,7 @@ static PyObject *Euler_repr(EulerObject *self) return ret; } +#ifndef MATH_STANDALONE static PyObject *Euler_str(EulerObject *self) { DynStr *ds; @@ -337,6 +341,7 @@ static PyObject *Euler_str(EulerObject *self) return mathutils_dynstr_to_py(ds); /* frees ds */ } +#endif static PyObject *Euler_richcmpr(PyObject *a, PyObject *b, int op) { @@ -663,7 +668,11 @@ PyTypeObject euler_Type = { &Euler_AsMapping, /* tp_as_mapping */ NULL, /* tp_hash */ NULL, /* tp_call */ +#ifndef MATH_STANDALONE (reprfunc) Euler_str, /* tp_str */ +#else + NULL, /* tp_str */ +#endif NULL, /* tp_getattro */ NULL, /* tp_setattro */ NULL, /* tp_as_buffer */ diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index 64112024dd1..05306f230d1 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -35,7 +35,10 @@ #include "BLI_math.h" #include "BLI_utildefines.h" #include "BLI_string.h" -#include "BLI_dynstr.h" + +#ifndef MATH_STANDALONE +# include "BLI_dynstr.h" +#endif typedef enum eMatrixAccess_t { MAT_ACCESS_ROW, @@ -1647,6 +1650,7 @@ static PyObject *Matrix_repr(MatrixObject *self) return NULL; } +#ifndef MATH_STANDALONE static PyObject *Matrix_str(MatrixObject *self) { DynStr *ds; @@ -1682,6 +1686,7 @@ static PyObject *Matrix_str(MatrixObject *self) return mathutils_dynstr_to_py(ds); /* frees ds */ } +#endif static PyObject *Matrix_richcmpr(PyObject *a, PyObject *b, int op) { @@ -2418,7 +2423,11 @@ PyTypeObject matrix_Type = { &Matrix_AsMapping, /*tp_as_mapping*/ NULL, /*tp_hash*/ NULL, /*tp_call*/ +#ifndef MATH_STANDALONE (reprfunc) Matrix_str, /*tp_str*/ +#else + NULL, /*tp_str*/ +#endif NULL, /*tp_getattro*/ NULL, /*tp_setattro*/ NULL, /*tp_as_buffer*/ diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c index cda39932610..c28631e5045 100644 --- a/source/blender/python/mathutils/mathutils_Quaternion.c +++ b/source/blender/python/mathutils/mathutils_Quaternion.c @@ -35,7 +35,10 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_dynstr.h" + +#ifndef MATH_STANDALONE +# include "BLI_dynstr.h" +#endif #define QUAT_SIZE 4 @@ -496,6 +499,7 @@ static PyObject *Quaternion_repr(QuaternionObject *self) return ret; } +#ifndef MATH_STANDALONE static PyObject *Quaternion_str(QuaternionObject *self) { DynStr *ds; @@ -510,6 +514,7 @@ static PyObject *Quaternion_str(QuaternionObject *self) return mathutils_dynstr_to_py(ds); /* frees ds */ } +#endif static PyObject *Quaternion_richcmpr(PyObject *a, PyObject *b, int op) { @@ -1202,7 +1207,11 @@ PyTypeObject quaternion_Type = { &Quaternion_AsMapping, /* tp_as_mapping */ NULL, /* tp_hash */ NULL, /* tp_call */ +#ifndef MATH_STANDALONE (reprfunc) Quaternion_str, /* tp_str */ +#else + NULL, /* tp_str */ +#endif NULL, /* tp_getattro */ NULL, /* tp_setattro */ NULL, /* tp_as_buffer */ diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c index e98af997507..f8159f6f187 100644 --- a/source/blender/python/mathutils/mathutils_Vector.c +++ b/source/blender/python/mathutils/mathutils_Vector.c @@ -35,7 +35,10 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_dynstr.h" + +#ifndef MATH_STANDALONE +# include "BLI_dynstr.h" +#endif #define MAX_DIMENSIONS 4 @@ -1231,6 +1234,7 @@ static PyObject *Vector_repr(VectorObject *self) return ret; } +#ifndef MATH_STANDALONE static PyObject *Vector_str(VectorObject *self) { int i; @@ -1252,7 +1256,7 @@ static PyObject *Vector_str(VectorObject *self) return mathutils_dynstr_to_py(ds); /* frees ds */ } - +#endif /* Sequence Protocol */ /* sequence length len(vector) */ @@ -2816,7 +2820,11 @@ PyTypeObject vector_Type = { NULL, /* hashfunc tp_hash; */ NULL, /* ternaryfunc tp_call; */ +#ifndef MATH_STANDALONE (reprfunc)Vector_str, /* reprfunc tp_str; */ +#else + NULL, /* reprfunc tp_str; */ +#endif NULL, /* getattrofunc tp_getattro; */ NULL, /* setattrofunc tp_setattro; */ diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c index 22317636faa..1db0538eb07 100644 --- a/source/blender/python/mathutils/mathutils_geometry.c +++ b/source/blender/python/mathutils/mathutils_geometry.c @@ -973,12 +973,14 @@ static PyObject *M_Geometry_points_in_planes(PyObject *UNUSED(self), PyObject *a float n1n2[3], n2n3[3], n3n1[3]; float potentialVertex[3]; - char *planes_used = MEM_callocN(sizeof(char) * len, __func__); + char *planes_used = PyMem_Malloc(sizeof(char) * len); /* python */ PyObject *py_verts = PyList_New(0); PyObject *py_plene_index = PyList_New(0); + memset(planes_used, 0, sizeof(char) * len); + for (i = 0; i < len; i++) { const float *N1 = planes[i]; for (j = i + 1; j < len; j++) { @@ -1031,7 +1033,7 @@ static PyObject *M_Geometry_points_in_planes(PyObject *UNUSED(self), PyObject *a Py_DECREF(item); } } - MEM_freeN(planes_used); + PyMem_Free(planes_used); { PyObject *ret = PyTuple_New(2); diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 1b8bcd51564..c9f0bbffc63 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -183,7 +183,7 @@ void WM_init(bContext *C, int argc, const char **argv) GPU_extensions_init(); GPU_set_mipmap(!(U.gameflags & USER_DISABLE_MIPMAP)); GPU_set_anisotropic(U.anisotropic_filter); - GPU_set_gpu_mipmapping(); + GPU_set_gpu_mipmapping(U.use_gpu_mipmap); UI_init(); } diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 4fe1e3b64ab..3739462ac2c 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -392,7 +392,7 @@ int WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi) } BLI_freelinkN(&keymap->items, kmi); - WM_keyconfig_update_tag(keymap, kmi); + WM_keyconfig_update_tag(keymap, NULL); return TRUE; } else { diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 80ceb5700e5..c555f771a48 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1523,49 +1523,6 @@ static void WM_OT_splash(wmOperatorType *ot) /* ***************** Search menu ************************* */ -static void operator_call_cb(struct bContext *C, void *UNUSED(arg1), void *arg2) -{ - wmOperatorType *ot = arg2; - - if (ot) - WM_operator_name_call(C, ot->idname, WM_OP_INVOKE_DEFAULT, NULL); -} - -static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items) -{ - GHashIterator *iter = WM_operatortype_iter(); - - for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) { - wmOperatorType *ot = BLI_ghashIterator_getValue(iter); - - if ((ot->flag & OPTYPE_INTERNAL) && (G.debug & G_DEBUG_WM) == 0) - continue; - - if (BLI_strcasestr(ot->name, str)) { - if (WM_operator_poll((bContext *)C, ot)) { - char name[256]; - int len = strlen(ot->name); - - /* display name for menu, can hold hotkey */ - BLI_strncpy(name, ot->name, sizeof(name)); - - /* check for hotkey */ - if (len < sizeof(name) - 6) { - if (WM_key_event_operator_string(C, ot->idname, WM_OP_EXEC_DEFAULT, NULL, TRUE, - &name[len + 1], sizeof(name) - len - 1)) - { - name[len] = '|'; - } - } - - if (0 == uiSearchItemAdd(items, name, ot, 0)) - break; - } - } - } - BLI_ghashIterator_free(iter); -} - static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *UNUSED(arg_op)) { static char search[256] = ""; @@ -1578,7 +1535,7 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *UNUSED(arg_ uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU); but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 10, 9 * UI_UNIT_X, UI_UNIT_Y, 0, 0, ""); - uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb, NULL); + uiOperatorSearch_But(but); /* fake button, it holds space for search items */ uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL); diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index d29d08a5431..8b387196da7 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -82,7 +82,7 @@ typedef struct PlayState { /* playback state */ short direction; - short next; + short next_frame; short once; short turbo; short pingpong; @@ -207,6 +207,21 @@ static int fromdisk = FALSE; static float zoomx = 1.0, zoomy = 1.0; static double ptottime = 0.0, swaptime = 0.04; +static PlayAnimPict *playanim_step(PlayAnimPict *playanim, int step) +{ + if (step > 0) { + while (step-- && playanim) { + playanim = playanim->next; + } + } + else if (step < 0) { + while (step++ && playanim) { + playanim = playanim->prev; + } + } + return playanim; +} + static int pupdate_time(void) { static double ltime; @@ -485,10 +500,10 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) ps->wait2 = FALSE; if (g_WS.qual & WS_QUAL_SHIFT) { ps->picture = picsbase.first; - ps->next = 0; + ps->next_frame = 0; } else { - ps->next = -1; + ps->next_frame = -1; } } break; @@ -496,10 +511,10 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) if (val) { ps->wait2 = FALSE; if (g_WS.qual & WS_QUAL_SHIFT) { - ps->next = ps->direction = -1; + ps->next_frame = ps->direction = -1; } else { - ps->next = -10; + ps->next_frame = -10; ps->sstep = TRUE; } } @@ -510,10 +525,10 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) ps->wait2 = FALSE; if (g_WS.qual & WS_QUAL_SHIFT) { ps->picture = picsbase.last; - ps->next = 0; + ps->next_frame = 0; } else { - ps->next = 1; + ps->next_frame = 1; } } break; @@ -521,10 +536,10 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) if (val) { ps->wait2 = FALSE; if (g_WS.qual & WS_QUAL_SHIFT) { - ps->next = ps->direction = 1; + ps->next_frame = ps->direction = 1; } else { - ps->next = 10; + ps->next_frame = 10; ps->sstep = TRUE; } } @@ -535,7 +550,8 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) if (val) { if (g_WS.qual & WS_QUAL_SHIFT) { if (ps->curframe_ibuf) - printf(" Name: %s | Speed: %.2f frames/s\n", ps->curframe_ibuf->name, ps->fstep / swaptime); + printf(" Name: %s | Speed: %.2f frames/s\n", + ps->curframe_ibuf->name, ps->fstep / swaptime); } else { swaptime = ps->fstep / 5.0; @@ -668,7 +684,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) } ps->sstep = TRUE; ps->wait2 = FALSE; - ps->next = 0; + ps->next_frame = 0; } break; } @@ -780,7 +796,7 @@ void WM_main_playanim(int argc, const char **argv) /* ps.doubleb = TRUE;*/ /* UNUSED */ ps.go = TRUE; ps.direction = TRUE; - ps.next = 1; + ps.next_frame = 1; ps.once = FALSE; ps.turbo = FALSE; ps.pingpong = FALSE; @@ -1033,7 +1049,7 @@ void WM_main_playanim(int argc, const char **argv) } } - ps.next = ps.direction; + ps.next_frame = ps.direction; while ((hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0) || ps.wait2 != 0)) { @@ -1062,15 +1078,10 @@ void WM_main_playanim(int argc, const char **argv) pupdate_time(); - if (ps.picture && ps.next) { + if (ps.picture && ps.next_frame) { /* always at least set one step */ while (ps.picture) { - if (ps.next < 0) { - ps.picture = ps.picture->prev; - } - else { - ps.picture = ps.picture->next; - } + ps.picture = playanim_step(ps.picture, ps.next_frame); if (ps.once && ps.picture != NULL) { if (ps.picture->next == NULL) { @@ -1085,12 +1096,7 @@ void WM_main_playanim(int argc, const char **argv) ptottime -= swaptime; } if (ps.picture == NULL && ps.sstep) { - if (ps.next < 0) { - ps.picture = picsbase.last; - } - else if (ps.next > 0) { - ps.picture = picsbase.first; - } + ps.picture = playanim_step(ps.picture, ps.next_frame); } } if (ps.go == FALSE) { |