diff options
author | Joseph Eagar <joeedh@gmail.com> | 2011-02-27 09:19:40 +0300 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2011-02-27 09:19:40 +0300 |
commit | f01261d040be27337db9f9996d648a279c89b7c4 (patch) | |
tree | c448230939b3c90d53ce8852dd00925d6052e3a4 /source/blender/editors/util | |
parent | dcaeda5c4e3a0687251b8511de4f2e8b85ef75c0 (diff) | |
parent | 2198cfdb2deec8b2e85e242c74a032f43d0b26ca (diff) |
merge with/from trunk at r35190
Diffstat (limited to 'source/blender/editors/util')
-rw-r--r-- | source/blender/editors/util/CMakeLists.txt | 65 | ||||
-rw-r--r-- | source/blender/editors/util/Makefile | 54 | ||||
-rw-r--r-- | source/blender/editors/util/SConscript | 1 | ||||
-rw-r--r-- | source/blender/editors/util/crazyspace.c | 407 | ||||
-rw-r--r-- | source/blender/editors/util/ed_util.c | 110 | ||||
-rw-r--r-- | source/blender/editors/util/editmode_undo.c | 40 | ||||
-rw-r--r-- | source/blender/editors/util/numinput.c | 3 | ||||
-rw-r--r-- | source/blender/editors/util/undo.c | 144 | ||||
-rw-r--r-- | source/blender/editors/util/util_intern.h | 3 |
9 files changed, 739 insertions, 88 deletions
diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt index b4b2fd12cef..511b1ab49e0 100644 --- a/source/blender/editors/util/CMakeLists.txt +++ b/source/blender/editors/util/CMakeLists.txt @@ -19,16 +19,69 @@ # # ***** END GPL LICENSE BLOCK ***** -FILE(GLOB SRC *.c) - -SET(INC +set(INC + ../include ../../blenkernel + ../../blenloader ../../blenlib - ../include - ../../../../intern/guardedalloc + ../../bmesh ../../makesdna ../../makesrna ../../windowmanager + ../../../../intern/guardedalloc +) + +set(SRC + ed_util.c + editmode_undo.c + numinput.c + undo.c + crazyspace.c + + util_intern.h + # general includes + ../include/BIF_gl.h + ../include/BIF_glutil.h + ../include/ED_anim_api.h + ../include/ED_armature.h + ../include/ED_curve.h + ../include/ED_datafiles.h + ../include/ED_fileselect.h + ../include/ED_fluidsim.h + ../include/ED_gpencil.h + ../include/ED_image.h + ../include/ED_info.h + ../include/ED_keyframes_draw.h + ../include/ED_keyframes_edit.h + ../include/ED_keyframing.h + ../include/ED_lattice.h + ../include/ED_logic.h + ../include/ED_markers.h + ../include/ED_mball.h + ../include/ED_mesh.h + ../include/ED_node.h + ../include/ED_numinput.h + ../include/ED_object.h + ../include/ED_particle.h + ../include/ED_physics.h + ../include/ED_render.h + ../include/ED_screen.h + ../include/ED_screen_types.h + ../include/ED_sculpt.h + ../include/ED_sequencer.h + ../include/ED_sound.h + ../include/ED_space_api.h + ../include/ED_text.h + ../include/ED_transform.h + ../include/ED_types.h + ../include/ED_util.h + ../include/ED_uvedit.h + ../include/ED_view3d.h + ../include/UI_icons.h + ../include/UI_interface.h + ../include/UI_interface_icons.h + ../include/UI_resources.h + ../include/UI_view2d.h ) -BLENDERLIB(bf_editor_util "${SRC}" "${INC}") +blender_add_lib(bf_editor_util "${SRC}" "${INC}") diff --git a/source/blender/editors/util/Makefile b/source/blender/editors/util/Makefile deleted file mode 100644 index 8535b3fb402..00000000000 --- a/source/blender/editors/util/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -# -# $Id$ -# -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# The Original Code is Copyright (C) 2007 Blender Foundation -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): none yet. -# -# ***** END GPL LICENSE BLOCK ***** -# -# Makes module object directory and bounces make to subdirectories. - -LIBNAME = ed_util -DIR = $(OCGDIR)/blender/$(LIBNAME) - -include nan_compile.mk - -CFLAGS += $(LEVEL_1_C_WARNINGS) - -CPPFLAGS += -I$(NAN_GLEW)/include -CPPFLAGS += -I$(OPENGL_HEADERS) - -# not very neat.... -CPPFLAGS += -I../../windowmanager -CPPFLAGS += -I../../blenloader -CPPFLAGS += -I../../blenkernel -CPPFLAGS += -I../../blenlib -CPPFLAGS += -I../../makesdna -CPPFLAGS += -I../../makesrna -CPPFLAGS += -I../../imbuf -CPPFLAGS += -I../../python -CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include - -# own include - -CPPFLAGS += -I../include diff --git a/source/blender/editors/util/SConscript b/source/blender/editors/util/SConscript index 723708b3d31..2d5ee84333b 100644 --- a/source/blender/editors/util/SConscript +++ b/source/blender/editors/util/SConscript @@ -6,5 +6,6 @@ sources = env.Glob('*.c') incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' ../../makesrna ../../bmesh' +incs += ' ../../blenloader' env.BlenderLib ( 'bf_editors_util', sources, Split(incs), [], libtype=['core'], priority=[130] ) diff --git a/source/blender/editors/util/crazyspace.c b/source/blender/editors/util/crazyspace.c new file mode 100644 index 00000000000..6b7292fe6c7 --- /dev/null +++ b/source/blender/editors/util/crazyspace.c @@ -0,0 +1,407 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "MEM_guardedalloc.h" + +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_modifier_types.h" +#include "DNA_meshdata_types.h" + +#include "BKE_DerivedMesh.h" +#include "BKE_modifier.h" +#include "BKE_multires.h" +#include "BKE_mesh.h" +#include "BKE_tessmesh.h" + +#include "BLI_utildefines.h" +#include "BLI_math.h" +#include "BLI_editVert.h" + +#include "ED_util.h" + +#define TAN_MAKE_VEC(a, b, c) a[0]= b[0] + 0.2f*(b[0]-c[0]); a[1]= b[1] + 0.2f*(b[1]-c[1]); a[2]= b[2] + 0.2f*(b[2]-c[2]) +static void set_crazy_vertex_quat(float *quat, float *v1, float *v2, float *v3, float *def1, float *def2, float *def3) +{ + float vecu[3], vecv[3]; + float q1[4], q2[4]; + + TAN_MAKE_VEC(vecu, v1, v2); + TAN_MAKE_VEC(vecv, v1, v3); + tri_to_quat( q1,v1, vecu, vecv); + + TAN_MAKE_VEC(vecu, def1, def2); + TAN_MAKE_VEC(vecv, def1, def3); + tri_to_quat( q2,def1, vecu, vecv); + + sub_qt_qtqt(quat, q2, q1); +} +#undef TAN_MAKE_VEC + +static void make_vertexcos__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s)) +{ + float *vec = userData; + + vec+= 3*index; + VECCOPY(vec, co); +} + +static int modifiers_disable_subsurf_temporary(Object *ob) +{ + ModifierData *md; + int disabled = 0; + + for(md=ob->modifiers.first; md; md=md->next) + if(md->type==eModifierType_Subsurf) + if(md->mode & eModifierMode_OnCage) { + md->mode ^= eModifierMode_DisableTemporary; + disabled= 1; + } + + return disabled; +} + +/* disable subsurf temporal, get mapped cos, and enable it */ +float *crazyspace_get_mapped_editverts(Scene *scene, Object *obedit) +{ + Mesh *me= obedit->data; + DerivedMesh *dm; + float *vertexcos; + + /* disable subsurf temporal, get mapped cos, and enable it */ + if(modifiers_disable_subsurf_temporary(obedit)) { + /* need to make new derivemesh */ + makeDerivedMesh(scene, obedit, me->edit_btmesh, CD_MASK_BAREMESH); + } + + /* now get the cage */ + dm= editbmesh_get_derived_cage(scene, obedit, me->edit_btmesh, CD_MASK_BAREMESH); + + vertexcos= MEM_mallocN(3*sizeof(float)*me->edit_btmesh->bm->totvert, "vertexcos map"); + dm->foreachMappedVert(dm, make_vertexcos__mapFunc, vertexcos); + + dm->release(dm); + + /* set back the flag, no new cage needs to be built, transform does it */ + modifiers_disable_subsurf_temporary(obedit); + + return vertexcos; +} + +void crazyspace_set_quats_editmesh(BMEditMesh *em, float *origcos, float *mappedcos, float *quats) +{ +#if 0 + BMEditVert *eve, *prev; + BMEditFace *efa; + BMIter iter; + float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4; + intptr_t index= 0; + + /* two abused locations in vertices */ + for(eve= em->verts.first; eve; eve= eve->next, index++) { + eve->tmp.p = NULL; + eve->prev= (EditVert *)index; + } + + /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */ + for(efa= em->faces.first; efa; efa= efa->next) { + + /* retrieve mapped coordinates */ + v1= mappedcos + 3*(intptr_t)(efa->v1->prev); + v2= mappedcos + 3*(intptr_t)(efa->v2->prev); + v3= mappedcos + 3*(intptr_t)(efa->v3->prev); + + co1= (origcos)? origcos + 3*(intptr_t)(efa->v1->prev): efa->v1->co; + co2= (origcos)? origcos + 3*(intptr_t)(efa->v2->prev): efa->v2->co; + co3= (origcos)? origcos + 3*(intptr_t)(efa->v3->prev): efa->v3->co; + + if(efa->v2->tmp.p==NULL && efa->v2->f1) { + set_crazy_vertex_quat(quats, co2, co3, co1, v2, v3, v1); + efa->v2->tmp.p= (void*)quats; + quats+= 4; + } + + if(efa->v4) { + v4= mappedcos + 3*(intptr_t)(efa->v4->prev); + co4= (origcos)? origcos + 3*(intptr_t)(efa->v4->prev): efa->v4->co; + + if(efa->v1->tmp.p==NULL && efa->v1->f1) { + set_crazy_vertex_quat(quats, co1, co2, co4, v1, v2, v4); + efa->v1->tmp.p= (void*)quats; + quats+= 4; + } + if(efa->v3->tmp.p==NULL && efa->v3->f1) { + set_crazy_vertex_quat(quats, co3, co4, co2, v3, v4, v2); + efa->v3->tmp.p= (void*)quats; + quats+= 4; + } + if(efa->v4->tmp.p==NULL && efa->v4->f1) { + set_crazy_vertex_quat(quats, co4, co1, co3, v4, v1, v3); + efa->v4->tmp.p= (void*)quats; + quats+= 4; + } + } + else { + if(efa->v1->tmp.p==NULL && efa->v1->f1) { + set_crazy_vertex_quat(quats, co1, co2, co3, v1, v2, v3); + efa->v1->tmp.p= (void*)quats; + quats+= 4; + } + if(efa->v3->tmp.p==NULL && efa->v3->f1) { + set_crazy_vertex_quat(quats, co3, co1, co2, v3, v1, v2); + efa->v3->tmp.p= (void*)quats; + quats+= 4; + } + } + } + + /* restore abused prev pointer */ + for(prev= NULL, eve= em->verts.first; eve; prev= eve, eve= eve->next) + eve->prev= prev; +#endif +} + +void crazyspace_set_quats_mesh(Mesh *me, float *origcos, float *mappedcos, float *quats) +{ + int i; + MVert *mvert; + MFace *mface; + float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4; + + mvert= me->mvert; + for(i=0; i<me->totvert; i++, mvert++) + mvert->flag&= ~ME_VERT_TMP_TAG; + + /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */ + mvert= me->mvert; + mface= me->mface; + for(i=0; i<me->totface; i++, mface++) { + + /* retrieve mapped coordinates */ + v1= mappedcos + 3*mface->v1; + v2= mappedcos + 3*mface->v2; + v3= mappedcos + 3*mface->v3; + + co1= (origcos)? origcos + 3*mface->v1: mvert[mface->v1].co; + co2= (origcos)? origcos + 3*mface->v2: mvert[mface->v2].co; + co3= (origcos)? origcos + 3*mface->v3: mvert[mface->v3].co; + + if((mvert[mface->v2].flag&ME_VERT_TMP_TAG)==0) { + set_crazy_vertex_quat(&quats[mface->v2*4], co2, co3, co1, v2, v3, v1); + mvert[mface->v2].flag|= ME_VERT_TMP_TAG; + } + + if(mface->v4) { + v4= mappedcos + 3*mface->v4; + co4= (origcos)? origcos + 3*mface->v4: mvert[mface->v4].co; + + if((mvert[mface->v1].flag&ME_VERT_TMP_TAG)==0) { + set_crazy_vertex_quat(&quats[mface->v1*4], co1, co2, co4, v1, v2, v4); + mvert[mface->v1].flag|= ME_VERT_TMP_TAG; + } + if((mvert[mface->v3].flag&ME_VERT_TMP_TAG)==0) { + set_crazy_vertex_quat(&quats[mface->v3*4], co3, co4, co2, v3, v4, v2); + mvert[mface->v3].flag|= ME_VERT_TMP_TAG; + } + if((mvert[mface->v4].flag&ME_VERT_TMP_TAG)==0) { + set_crazy_vertex_quat(&quats[mface->v4*4], co4, co1, co3, v4, v1, v3); + mvert[mface->v4].flag|= ME_VERT_TMP_TAG; + } + } + else { + if((mvert[mface->v1].flag&ME_VERT_TMP_TAG)==0) { + set_crazy_vertex_quat(&quats[mface->v1*4], co1, co2, co3, v1, v2, v3); + mvert[mface->v1].flag|= ME_VERT_TMP_TAG; + } + if((mvert[mface->v3].flag&ME_VERT_TMP_TAG)==0) { + set_crazy_vertex_quat(&quats[mface->v3*4], co3, co1, co2, v3, v1, v2); + mvert[mface->v3].flag|= ME_VERT_TMP_TAG; + } + } + } +} + +int editbmesh_get_first_deform_matrices(Scene *scene, Object *ob, BMEditMesh *em, + float (**deformmats)[3][3], float (**deformcos)[3]) +{ + ModifierData *md; + DerivedMesh *dm; + int i, a, numleft = 0, numVerts = 0; + int cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1); + float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL; + + modifiers_clearErrors(ob); + + dm = NULL; + md = modifiers_getVirtualModifierList(ob); + + /* compute the deformation matrices and coordinates for the first + modifiers with on cage editing that are enabled and support computing + deform matrices */ + for(i = 0; md && i <= cageIndex; i++, md = md->next) { + ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if(!editbmesh_modifier_is_enabled(scene, md, dm)) + continue; + + if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatricesEM) { + if(!defmats) { + dm= getEditDerivedBMesh(em, ob, NULL); + deformedVerts= editbmesh_get_vertex_cos(em, &numVerts); + defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats"); + + for(a=0; a<numVerts; a++) + unit_m3(defmats[a]); + } + + mti->deformMatricesEM(md, ob, em, dm, deformedVerts, defmats, + numVerts); + } + else + break; + } + + for(; md && i <= cageIndex; md = md->next, i++) + if(editbmesh_modifier_is_enabled(scene, md, dm) && modifier_isCorrectableDeformed(md)) + numleft++; + + if(dm) + dm->release(dm); + + *deformmats= defmats; + *deformcos= deformedVerts; + + return numleft; +} + +int sculpt_get_first_deform_matrices(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3]) +{ + ModifierData *md; + DerivedMesh *dm; + int a, numVerts= 0; + float (*defmats)[3][3]= NULL, (*deformedVerts)[3]= NULL; + MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0); + int has_multires = mmd != NULL && mmd->sculptlvl > 0; + int numleft= 0; + + if(has_multires) { + *deformmats= NULL; + *deformcos= NULL; + return numleft; + } + + dm= NULL; + md= modifiers_getVirtualModifierList(ob); + + for(; md; md= md->next) { + ModifierTypeInfo *mti= modifierType_getInfo(md->type); + + if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue; + + if(mti->type==eModifierTypeType_OnlyDeform) { + if(!defmats) { + Mesh *me= (Mesh*)ob->data; + dm= mesh_create_derived(me, ob, NULL); + deformedVerts= mesh_getVertexCos(me, &numVerts); + defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats"); + + for(a=0; a<numVerts; a++) + unit_m3(defmats[a]); + } + + if(mti->deformMatrices) mti->deformMatrices(md, ob, dm, deformedVerts, defmats, numVerts); + else break; + } + } + + for(; md; md= md->next) { + ModifierTypeInfo *mti= modifierType_getInfo(md->type); + + if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue; + + if(mti->type==eModifierTypeType_OnlyDeform) + numleft++; + } + + if(dm) + dm->release(dm); + + *deformmats= defmats; + *deformcos= deformedVerts; + + return numleft; +} + +void crazyspace_build_sculpt(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3]) +{ + int totleft= sculpt_get_first_deform_matrices(scene, ob, deformmats, deformcos); + + if(totleft) { + /* there are deformation modifier which doesn't support deformation matricies + calculation. Need additional crazyspace correction */ + + float (*deformedVerts)[3]= *deformcos; + float (*origVerts)[3]= MEM_dupallocN(deformedVerts); + float *quats= NULL; + int i, deformed= 0; + ModifierData *md= modifiers_getVirtualModifierList(ob); + Mesh *me= (Mesh*)ob->data; + + for(; md; md= md->next) { + ModifierTypeInfo *mti= modifierType_getInfo(md->type); + + if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue; + + if(mti->type==eModifierTypeType_OnlyDeform) { + /* skip leading modifiers which have been alredy + handled in sculpt_get_first_deform_matrices */ + if(mti->deformMatrices && !deformed) + continue; + + mti->deformVerts(md, ob, NULL, deformedVerts, me->totvert, 0, 0); + deformed= 1; + } + } + + quats= MEM_mallocN(me->totvert*sizeof(float)*4, "crazy quats"); + + crazyspace_set_quats_mesh(me, (float*)origVerts, (float*)deformedVerts, quats); + + for(i=0; i<me->totvert; i++) { + float qmat[3][3], tmat[3][3]; + + quat_to_mat3(qmat, &quats[i*4]); + mul_m3_m3m3(tmat, qmat, (*deformmats)[i]); + copy_m3_m3((*deformmats)[i], tmat); + } + + MEM_freeN(origVerts); + MEM_freeN(quats); + } +} diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index 8e2a30b4a69..314fcdc601b 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -27,18 +27,23 @@ */ #include <stdlib.h> +#include <string.h> #include <math.h> #include "MEM_guardedalloc.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_packedFile_types.h" #include "BLI_blenlib.h" #include "BLI_editVert.h" #include "BKE_context.h" +#include "BKE_global.h" #include "BKE_main.h" +#include "BKE_utildefines.h" +#include "BKE_packedFile.h" #include "ED_armature.h" #include "ED_mesh.h" @@ -48,6 +53,11 @@ #include "UI_interface.h" +#include "WM_types.h" +#include "RNA_access.h" + + + /* ********* general editor util funcs, not BKE stuff please! ********* */ void ED_editors_init(bContext *C) @@ -91,8 +101,8 @@ void ED_editors_exit(bContext *C) Object *ob= sce->obedit; /* global in meshtools... */ - mesh_octree_table(NULL, NULL, NULL, 'e'); - mesh_mirrtopo_table(NULL, 'e'); + //BMESH_TODO mesh_octree_table(NULL, NULL, NULL, 'e'); + //BMESH_TODO mesh_mirrtopo_table(NULL, 'e'); if(ob) { if(ob->type==OB_MESH) { @@ -120,8 +130,8 @@ void ED_editors_exit(bContext *C) /* if weight-painting is on, free mesh octree data */ if(ob->mode & OB_MODE_WEIGHT_PAINT) { - mesh_octree_table(NULL, NULL, NULL, 'e'); - mesh_mirrtopo_table(NULL, 'e'); + //BMESH_TODO mesh_octree_table(NULL, NULL, NULL, 'e'); + //BMESH_TODO mesh_mirrtopo_table(NULL, 'e'); } } } @@ -152,7 +162,7 @@ void apply_keyb_grid(int shift, int ctrl, float *val, float fac1, float fac2, fl } -int GetButStringLength(char *str) +int GetButStringLength(const char *str) { int rt; @@ -161,3 +171,91 @@ int GetButStringLength(char *str) return rt + 15; } + +void unpack_menu(bContext *C, const char *opname, const char *id_name, const char *abs_name, const char *folder, struct PackedFile *pf) +{ + PointerRNA props_ptr; + uiPopupMenu *pup; + uiLayout *layout; + char line[FILE_MAXDIR + FILE_MAXFILE + 100]; + + pup= uiPupMenuBegin(C, "Unpack file", ICON_NULL); + layout= uiPupMenuLayout(pup); + + sprintf(line, "Remove Pack"); + props_ptr= uiItemFullO(layout, opname, line, ICON_NULL, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + RNA_enum_set(&props_ptr, "method", PF_REMOVE); + RNA_string_set(&props_ptr, "id", id_name); + + if(G.relbase_valid) { + char local_name[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX]; + + BLI_strncpy(local_name, abs_name, sizeof(local_name)); + BLI_splitdirstring(local_name, fi); + sprintf(local_name, "//%s/%s", folder, fi); + if(strcmp(abs_name, local_name)!=0) { + switch(checkPackedFile(local_name, pf)) { + case PF_NOFILE: + sprintf(line, "Create %s", local_name); + props_ptr= uiItemFullO(layout, opname, line, ICON_NULL, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL); + RNA_string_set(&props_ptr, "id", id_name); + + break; + case PF_EQUAL: + sprintf(line, "Use %s (identical)", local_name); + //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_LOCAL); + props_ptr= uiItemFullO(layout, opname, line, ICON_NULL, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL); + RNA_string_set(&props_ptr, "id", id_name); + + break; + case PF_DIFFERS: + sprintf(line, "Use %s (differs)", local_name); + //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_LOCAL); + props_ptr= uiItemFullO(layout, opname, line, ICON_NULL, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL); + RNA_string_set(&props_ptr, "id", id_name); + + sprintf(line, "Overwrite %s", local_name); + //uiItemEnumO(layout, opname, line, 0, "method", PF_WRITE_LOCAL); + props_ptr= uiItemFullO(layout, opname, line, ICON_NULL, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL); + RNA_string_set(&props_ptr, "id", id_name); + break; + } + } + } + + switch(checkPackedFile(abs_name, pf)) { + case PF_NOFILE: + sprintf(line, "Create %s", abs_name); + //uiItemEnumO(layout, opname, line, 0, "method", PF_WRITE_ORIGINAL); + props_ptr= uiItemFullO(layout, opname, line, ICON_NULL, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL); + RNA_string_set(&props_ptr, "id", id_name); + break; + case PF_EQUAL: + sprintf(line, "Use %s (identical)", abs_name); + //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_ORIGINAL); + props_ptr= uiItemFullO(layout, opname, line, ICON_NULL, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL); + RNA_string_set(&props_ptr, "id", id_name); + break; + case PF_DIFFERS: + sprintf(line, "Use %s (differs)", abs_name); + //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_ORIGINAL); + props_ptr= uiItemFullO(layout, opname, line, ICON_NULL, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL); + RNA_string_set(&props_ptr, "id", id_name); + + sprintf(line, "Overwrite %s", abs_name); + //uiItemEnumO(layout, opname, line, 0, "method", PF_WRITE_ORIGINAL); + props_ptr= uiItemFullO(layout, opname, line, ICON_NULL, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL); + RNA_string_set(&props_ptr, "id", id_name); + break; + } + + uiPupMenuEnd(C, pup); +} diff --git a/source/blender/editors/util/editmode_undo.c b/source/blender/editors/util/editmode_undo.c index 564439a7bb3..1e6f7cd8804 100644 --- a/source/blender/editors/util/editmode_undo.c +++ b/source/blender/editors/util/editmode_undo.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -37,25 +37,29 @@ #include "DNA_object_types.h" #include "DNA_screen_types.h" -#include "BKE_context.h" -#include "BKE_depsgraph.h" -#include "BKE_global.h" - #include "BLI_blenlib.h" #include "BLI_dynstr.h" +#include "BLI_utildefines.h" +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_global.h" + +#include "ED_util.h" #include "ED_mesh.h" #include "UI_interface.h" #include "UI_resources.h" +#include "util_intern.h" + /* ***************** generic editmode undo system ********************* */ /* Add this in your local code: -void undo_editmode_push(bContext *C, char *name, +void undo_editmode_push(bContext *C, const char *name, void * (*getdata)(bContext *C), // use context to retrieve current editdata void (*freedata)(void *), // pointer to function freeing data void (*to_editmode)(void *, void *), // data to editmode conversion @@ -74,7 +78,7 @@ void undo_editmode_menu(void) // history menu /* ********************************************************************* */ /* ****** XXX ***** */ -void error(const char *dummy) {} +static void error(const char *UNUSED(arg)) {} /* ****** XXX ***** */ @@ -108,7 +112,7 @@ static void undo_restore(UndoElem *undo, void *editdata, void *obdata) } /* name can be a dynamic string */ -void undo_editmode_push(bContext *C, char *name, +void undo_editmode_push(bContext *C, const char *name, void * (*getdata)(bContext *C), void (*freedata)(void *), void (*to_editmode)(void *, void *, void *), @@ -268,7 +272,7 @@ void undo_editmode_step(bContext *C, int step) EDBM_selectmode_to_scene(CTX_data_scene(C), obedit); } - DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); + DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); /* XXX notifiers */ } @@ -313,6 +317,20 @@ void undo_editmode_name(bContext *C, const char *undoname) } } +/* undoname optionally, if NULL it just checks for existing undo steps */ +int undo_editmode_valid(const char *undoname) +{ + if(undoname) { + UndoElem *uel; + + for(uel= undobase.last; uel; uel= uel->prev) { + if(strcmp(undoname, uel->name)==0) + break; + } + return uel != NULL; + } + return undobase.last != undobase.first; +} /* ************** for interaction with menu/pullown */ @@ -341,7 +359,7 @@ void undo_editmode_menu(bContext *C) if(event>0) undo_number(C, event); } -static void do_editmode_undohistorymenu(bContext *C, void *arg, int event) +static void do_editmode_undohistorymenu(bContext *C, void *UNUSED(arg), int event) { Object *obedit= CTX_data_edit_object(C); @@ -351,7 +369,7 @@ static void do_editmode_undohistorymenu(bContext *C, void *arg, int event) } -uiBlock *editmode_undohistorymenu(bContext *C, ARegion *ar, void *arg_unused) +uiBlock *editmode_undohistorymenu(bContext *C, ARegion *ar, void *UNUSED(arg)) { uiBlock *block; UndoElem *uel; diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c index 868aa8ac6af..6ae5963564e 100644 --- a/source/blender/editors/util/numinput.c +++ b/source/blender/editors/util/numinput.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -30,6 +30,7 @@ #include <math.h> /* fabs */ #include <stdio.h> /* for sprintf */ +#include "BLI_utildefines.h" #include "WM_types.h" diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c index e5128ea784a..c2f8ae16cb8 100644 --- a/source/blender/editors/util/undo.c +++ b/source/blender/editors/util/undo.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -36,13 +36,15 @@ #include "DNA_object_types.h" -#include "BKE_blender.h" -#include "BKE_context.h" - #include "BLI_blenlib.h" #include "BLI_editVert.h" #include "BLI_dynstr.h" +#include "BLI_utildefines.h" +#include "BKE_blender.h" +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_screen.h" #include "ED_armature.h" #include "ED_particle.h" @@ -58,12 +60,16 @@ #include "WM_api.h" #include "WM_types.h" +#include "RNA_access.h" +#include "RNA_define.h" #include "util_intern.h" +#define MAXUNDONAME 64 /* XXX, make common define */ + /* ***************** generic undo system ********************* */ -void ED_undo_push(bContext *C, char *str) +void ED_undo_push(bContext *C, const char *str) { wmWindowManager *wm= CTX_wm_manager(C); Object *obedit= CTX_data_edit_object(C); @@ -156,9 +162,10 @@ static int ed_undo_step(bContext *C, int step, const char *undoname) if(do_glob_undo) { if(U.uiflag & USER_GLOBALUNDO) { -#ifndef DISABLE_PYTHON + // note python defines not valid here anymore. + //#ifdef WITH_PYTHON // XXX BPY_scripts_clear_pyobjects(); -#endif + //#endif if(undoname) BKE_undo_name(C, undoname); else @@ -196,18 +203,73 @@ void ED_undo_pop_op(bContext *C, wmOperator *op) ed_undo_step(C, 0, op->type->name); } -static int ed_undo_exec(bContext *C, wmOperator *op) +/* name optionally, function used to check for operator redo panel */ +int ED_undo_valid(const bContext *C, const char *undoname) +{ + Object *obedit= CTX_data_edit_object(C); + Object *obact= CTX_data_active_object(C); + ScrArea *sa= CTX_wm_area(C); + + if(sa && sa->spacetype==SPACE_IMAGE) { + SpaceImage *sima= (SpaceImage *)sa->spacedata.first; + + if((obact && obact->mode & OB_MODE_TEXTURE_PAINT) || sima->flag & SI_DRAWTOOL) { + return 1; + } + } + + if(sa && sa->spacetype==SPACE_TEXT) { + return 1; + } + else if(obedit) { + if ELEM7(obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE) { + return undo_editmode_valid(undoname); + } + } + else { + + /* if below tests fail, global undo gets executed */ + + if(obact && obact->mode & OB_MODE_TEXTURE_PAINT) { + if( ED_undo_paint_valid(UNDO_PAINT_IMAGE, undoname) ) + return 1; + } + else if(obact && obact->mode & OB_MODE_SCULPT) { + if( ED_undo_paint_valid(UNDO_PAINT_MESH, undoname) ) + return 1; + } + else if(obact && obact->mode & OB_MODE_PARTICLE_EDIT) { + return PE_undo_valid(CTX_data_scene(C)); + } + + if(U.uiflag & USER_GLOBALUNDO) { + return BKE_undo_valid(undoname); + } + } + return 0; +} + +static int ed_undo_exec(bContext *C, wmOperator *UNUSED(op)) { /* "last operator" should disappear, later we can tie ths with undo stack nicer */ WM_operator_stack_clear(C); return ed_undo_step(C, 1, NULL); } -static int ed_redo_exec(bContext *C, wmOperator *op) +static int ed_undo_push_exec(bContext *C, wmOperator *op) +{ + char str[MAXUNDONAME]; + RNA_string_get(op->ptr, "message", str); + ED_undo_push(C, str); + return OPERATOR_FINISHED; +} + +static int ed_redo_exec(bContext *C, wmOperator *UNUSED(op)) { return ed_undo_step(C, -1, NULL); } +#if 0 /* UNUSED */ void ED_undo_menu(bContext *C) { Object *obedit= CTX_data_edit_object(C); @@ -232,6 +294,7 @@ void ED_undo_menu(bContext *C) } } } +#endif /* ********************** */ @@ -247,6 +310,19 @@ void ED_OT_undo(wmOperatorType *ot) ot->poll= ED_operator_screenactive; } +void ED_OT_undo_push(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Undo Push"; + ot->description= "Add an undo state (internal use only)"; + ot->idname= "ED_OT_undo_push"; + + /* api callbacks */ + ot->exec= ed_undo_push_exec; + + RNA_def_string(ot->srna, "message", "Add an undo step *function may be moved*", MAXUNDONAME, "Undo Message", ""); +} + void ED_OT_redo(wmOperatorType *ot) { /* identifiers */ @@ -260,3 +336,53 @@ void ED_OT_redo(wmOperatorType *ot) } +/* ui callbacks should call this rather then calling WM_operator_repeat() themselves */ +int ED_undo_operator_repeat(bContext *C, struct wmOperator *op) +{ + int ret= 0; + + if(op) { + ARegion *ar= CTX_wm_region(C); + ARegion *ar1= BKE_area_find_region_type(CTX_wm_area(C), RGN_TYPE_WINDOW); + + if(ar1) + CTX_wm_region_set(C, ar1); + + if(WM_operator_repeat_check(C, op) && WM_operator_poll(C, op->type)) { + int retval; + + if (G.f & G_DEBUG) + printf("redo_cb: operator redo %s\n", op->type->name); + ED_undo_pop_op(C, op); + retval= WM_operator_repeat(C, op); + if((retval & OPERATOR_FINISHED)==0) { + if (G.f & G_DEBUG) + printf("redo_cb: operator redo failed: %s, return %d\n", op->type->name, retval); + ED_undo_redo(C); + } + else { + ret= 1; + } + } + + /* set region back */ + CTX_wm_region_set(C, ar); + } + else { + if (G.f & G_DEBUG) { + printf("redo_cb: WM_operator_repeat_check returned false %s\n", op->type->name); + } + } + + return ret; +} + +void ED_undo_operator_repeat_cb(bContext *C, void *arg_op, void *UNUSED(arg_unused)) +{ + ED_undo_operator_repeat(C, (wmOperator *)arg_op); +} + +void ED_undo_operator_repeat_cb_evt(bContext *C, void *arg_op, int UNUSED(arg_event)) +{ + ED_undo_operator_repeat(C, (wmOperator *)arg_op); +} diff --git a/source/blender/editors/util/util_intern.h b/source/blender/editors/util/util_intern.h index 73675ab4ef9..c448377f6b0 100644 --- a/source/blender/editors/util/util_intern.h +++ b/source/blender/editors/util/util_intern.h @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -34,6 +34,7 @@ /* editmode_undo.c */ void undo_editmode_clear(void); void undo_editmode_name(bContext *C, const char *undoname); +int undo_editmode_valid(const char *undoname); #endif /* ED_UTIL_INTERN_H */ |