Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2012-06-04 20:42:58 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-06-04 20:42:58 +0400
commit68a9dd54ec909d8e56da0da487c6ec3559551edd (patch)
tree9b0949fdc65604fe3e39b765b4085a714b8e7471 /source
parent2230f3346e8a7ac2191690627856a1a8745bd8e9 (diff)
mask mode for clip editor developed by Sergey Sharybin, Pete Larabell and myself.
see: http://wiki.blender.org/index.php/User:Nazg-gul/MaskEditor note - mask editing tools need continued development, feather option is not working 100%
Diffstat (limited to 'source')
-rw-r--r--source/blender/CMakeLists.txt1
-rw-r--r--source/blender/blenkernel/BKE_context.h1
-rw-r--r--source/blender/blenkernel/BKE_library.h2
-rw-r--r--source/blender/blenkernel/BKE_main.h1
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/CMakeLists.txt3
-rw-r--r--source/blender/blenkernel/SConscript1
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c12
-rw-r--r--source/blender/blenkernel/intern/context.c5
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c12
-rw-r--r--source/blender/blenkernel/intern/idcode.c1
-rw-r--r--source/blender/blenkernel/intern/library.c11
-rw-r--r--source/blender/blenkernel/intern/node.c2
-rw-r--r--source/blender/blenkernel/intern/scene.c6
-rw-r--r--source/blender/blenloader/intern/readfile.c125
-rw-r--r--source/blender/blenloader/intern/writefile.c55
-rw-r--r--source/blender/compositor/CMakeLists.txt5
-rw-r--r--source/blender/compositor/intern/COM_Converter.cpp4
-rw-r--r--source/blender/editors/CMakeLists.txt1
-rw-r--r--source/blender/editors/SConscript1
-rw-r--r--source/blender/editors/animation/keyframes_draw.c68
-rw-r--r--source/blender/editors/include/ED_clip.h10
-rw-r--r--source/blender/editors/include/ED_keyframes_draw.h4
-rw-r--r--source/blender/editors/include/ED_object.h1
-rw-r--r--source/blender/editors/include/ED_screen.h1
-rw-r--r--source/blender/editors/include/ED_transform.h1
-rw-r--r--source/blender/editors/interface/interface_templates.c20
-rw-r--r--source/blender/editors/object/object_ops.c8
-rw-r--r--source/blender/editors/screen/screen_ops.c22
-rw-r--r--source/blender/editors/space_api/spacetypes.c4
-rw-r--r--source/blender/editors/space_clip/clip_draw.c28
-rw-r--r--source/blender/editors/space_clip/clip_editor.c127
-rw-r--r--source/blender/editors/space_clip/space_clip.c100
-rw-r--r--source/blender/editors/space_node/drawnode.c9
-rw-r--r--source/blender/editors/space_node/space_node.c7
-rw-r--r--source/blender/editors/transform/transform.c96
-rw-r--r--source/blender/editors/transform/transform.h1
-rw-r--r--source/blender/editors/transform/transform_conversions.c230
-rw-r--r--source/blender/editors/transform/transform_generics.c66
-rw-r--r--source/blender/makesdna/DNA_ID.h1
-rw-r--r--source/blender/makesdna/DNA_scene_types.h3
-rw-r--r--source/blender/makesdna/DNA_space_types.h11
-rw-r--r--source/blender/makesdna/intern/makesdna.c2
-rw-r--r--source/blender/makesrna/RNA_access.h3
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt1
-rw-r--r--source/blender/makesrna/intern/makesrna.c1
-rw-r--r--source/blender/makesrna/intern/rna_ID.c2
-rw-r--r--source/blender/makesrna/intern/rna_internal.h2
-rw-r--r--source/blender/makesrna/intern/rna_main.c7
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c51
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c12
-rw-r--r--source/blender/makesrna/intern/rna_nodetree_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_scene.c6
-rw-r--r--source/blender/makesrna/intern/rna_space.c63
-rw-r--r--source/blender/nodes/CMakeLists.txt1
-rw-r--r--source/blender/nodes/NOD_composite.h2
-rw-r--r--source/blender/nodes/composite/node_composite_tree.c4
-rw-r--r--source/blender/nodes/composite/node_composite_util.c16
-rw-r--r--source/blender/nodes/composite/node_composite_util.h1
-rw-r--r--source/blender/windowmanager/WM_types.h1
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c2
-rw-r--r--source/blenderplayer/CMakeLists.txt1
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c1
-rw-r--r--source/creator/CMakeLists.txt2
64 files changed, 1180 insertions, 70 deletions
diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt
index ed1308d41ba..a0d840b5de6 100644
--- a/source/blender/CMakeLists.txt
+++ b/source/blender/CMakeLists.txt
@@ -86,6 +86,7 @@ set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_world_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_movieclip_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_tracking_types.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_mask_types.h
)
add_subdirectory(editors)
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 23df246b430..7a1172335d8 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -260,6 +260,7 @@ struct Image *CTX_data_edit_image(const bContext *C);
struct Text *CTX_data_edit_text(const bContext *C);
struct MovieClip *CTX_data_edit_movieclip(const bContext *C);
+struct Mask *CTX_data_edit_mask(const bContext *C);
int CTX_data_selected_nodes(const bContext *C, ListBase *list);
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 3a19d6c9007..3248944dae8 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -66,7 +66,7 @@ void id_clear_lib_data(struct Main *bmain, struct ID *id);
struct ListBase *which_libbase(struct Main *mainlib, short type);
-#define MAX_LIBARRAY 40
+#define MAX_LIBARRAY 41
int set_listbasepointers(struct Main *main, struct ListBase **lb);
void BKE_libblock_free(struct ListBase *lb, void *idv);
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index 09c91a59ac5..3074e1c0e63 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -86,6 +86,7 @@ typedef struct Main {
ListBase wm;
ListBase gpencil;
ListBase movieclip;
+ ListBase mask;
char id_tag_update[256];
} Main;
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index d093c9108b6..b9d0076c7c8 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -658,6 +658,7 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat);
#define CMP_NODE_MOVIEDISTORTION 265
#define CMP_NODE_DOUBLEEDGEMASK 266
#define CMP_NODE_OUTPUT_MULTI_FILE__DEPRECATED 267 /* DEPRECATED multi file node has been merged into regular CMP_NODE_OUTPUT_FILE */
+#define CMP_NODE_MASK 268
#define CMP_NODE_GLARE 301
#define CMP_NODE_TONEMAP 302
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index d207a08c6cb..056a6bf5866 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -43,6 +43,7 @@ set(INC
../../../intern/memutil
../../../intern/mikktspace
../../../intern/opennl/extern
+ ../../../intern/raskter
# XXX - BAD LEVEL CALL WM_api.h
../windowmanager
@@ -100,6 +101,7 @@ set(SRC
intern/lamp.c
intern/lattice.c
intern/library.c
+ intern/mask.c
intern/material.c
intern/mball.c
intern/mesh.c
@@ -187,6 +189,7 @@ set(SRC
BKE_lamp.h
BKE_lattice.h
BKE_library.h
+ BKE_mask.h
BKE_main.h
BKE_material.h
BKE_mball.h
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index ee9e6bc7739..64544adb26d 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -17,6 +17,7 @@ incs += ' #/intern/smoke/extern'
incs += ' #/intern/mikktspace'
incs += ' #/intern/audaspace/intern'
incs += ' #/intern/ffmpeg'
+incs += ' #/intern/raskter'
incs += ' ' + env['BF_OPENGL_INC']
incs += ' ' + env['BF_ZLIB_INC']
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 1358c2e34a8..7fc80529753 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -90,6 +90,7 @@ short id_type_can_have_animdata(ID *id)
case ID_SPK:
case ID_SCE:
case ID_MC:
+ case ID_MSK:
{
return 1;
}
@@ -802,10 +803,13 @@ void BKE_animdata_main_cb(Main *mainptr, ID_AnimData_Edit_Callback func, void *u
/* objects */
ANIMDATA_IDS_CB(mainptr->object.first);
+
+ /* masks */
+ ANIMDATA_IDS_CB(mainptr->mask.first);
/* worlds */
ANIMDATA_IDS_CB(mainptr->world.first);
-
+
/* scenes */
ANIMDATA_NODETREE_IDS_CB(mainptr->scene.first, Scene);
}
@@ -886,6 +890,9 @@ void BKE_all_animdata_fix_paths_rename(ID *ref_id, const char *prefix, const cha
/* objects */
RENAMEFIX_ANIM_IDS(mainptr->object.first);
+
+ /* masks */
+ RENAMEFIX_ANIM_IDS(mainptr->mask.first);
/* worlds */
RENAMEFIX_ANIM_IDS(mainptr->world.first);
@@ -2350,6 +2357,9 @@ void BKE_animsys_evaluate_all_animation(Main *main, Scene *scene, float ctime)
* linked from other (not-visible) scenes will not need their data calculated.
*/
EVAL_ANIM_IDS(main->object.first, 0);
+
+ /* masks */
+ EVAL_ANIM_IDS(main->mask.first, ADT_RECALC_ANIM);
/* worlds */
EVAL_ANIM_NODETREE_IDS(main->world.first, World, ADT_RECALC_ANIM);
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 3c8f29d8440..ff2dd27e0c9 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -973,6 +973,11 @@ struct MovieClip *CTX_data_edit_movieclip(const bContext *C)
return ctx_data_pointer_get(C, "edit_movieclip");
}
+struct Mask *CTX_data_edit_mask(const bContext *C)
+{
+ return ctx_data_pointer_get(C, "edit_mask");
+}
+
struct EditBone *CTX_data_active_bone(const bContext *C)
{
return ctx_data_pointer_get(C, "active_bone");
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index a6ce5daf247..53bc9c4cb7e 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -2611,6 +2611,18 @@ static void dag_id_flush_update(Scene *sce, ID *id)
}
}
+ if (idtype == ID_MSK) {
+ if (sce->nodetree) {
+ bNode *node;
+
+ for (node = sce->nodetree->nodes.first; node; node = node->next) {
+ if (node->id == id) {
+ nodeUpdate(sce->nodetree, node);
+ }
+ }
+ }
+ }
+
/* camera's matrix is used to orient reconstructed stuff,
* so it should happen tracking-related constraints recalculation
* when camera is changing (sergey) */
diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c
index ca10f39246c..30427a81c4b 100644
--- a/source/blender/blenkernel/intern/idcode.c
+++ b/source/blender/blenkernel/intern/idcode.c
@@ -79,6 +79,7 @@ static IDType idtypes[] = {
{ ID_WO, "World", "worlds", IDTYPE_FLAGS_ISLINKABLE},
{ ID_WM, "WindowManager", "window_managers", 0},
{ ID_MC, "MovieClip", "movieclips", IDTYPE_FLAGS_ISLINKABLE},
+ { ID_MSK, "Mask", "masks", IDTYPE_FLAGS_ISLINKABLE},
};
static int nidtypes = sizeof(idtypes) / sizeof(idtypes[0]);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index de67119d850..0abeb483745 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -66,6 +66,7 @@
#include "DNA_world_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_movieclip_types.h"
+#include "DNA_mask_types.h"
#include "BLI_blenlib.h"
#include "BLI_dynstr.h"
@@ -108,6 +109,7 @@
#include "BKE_speaker.h"
#include "BKE_utildefines.h"
#include "BKE_movieclip.h"
+#include "BKE_mask.h"
#include "RNA_access.h"
@@ -486,6 +488,8 @@ ListBase *which_libbase(Main *mainlib, short type)
return &(mainlib->gpencil);
case ID_MC:
return &(mainlib->movieclip);
+ case ID_MSK:
+ return &(mainlib->mask);
}
return NULL;
}
@@ -569,6 +573,7 @@ int set_listbasepointers(Main *main, ListBase **lb)
lb[a++] = &(main->library);
lb[a++] = &(main->wm);
lb[a++] = &(main->movieclip);
+ lb[a++] = &(main->mask);
lb[a] = NULL;
@@ -680,6 +685,9 @@ static ID *alloc_libblock_notest(short type)
case ID_MC:
id = MEM_callocN(sizeof(MovieClip), "Movie Clip");
break;
+ case ID_MSK:
+ id = MEM_callocN(sizeof(Mask), "Mask");
+ break;
}
return id;
}
@@ -888,6 +896,9 @@ void BKE_libblock_free(ListBase *lb, void *idv)
case ID_MC:
BKE_movieclip_free((MovieClip *)id);
break;
+ case ID_MSK:
+ BKE_mask_free((Mask *)id);
+ break;
}
if (id->properties) {
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 22286e57c0a..86a1f715c3c 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1910,6 +1910,8 @@ static void registerCompositNodes(bNodeTreeType *ttype)
register_node_type_cmp_bokehimage(ttype);
register_node_type_cmp_bokehblur(ttype);
register_node_type_cmp_switch(ttype);
+
+ register_node_type_cmp_mask(ttype);
}
static void registerShaderNodes(bNodeTreeType *ttype)
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 62d5459336b..d9f1a6372ee 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -63,6 +63,7 @@
#include "BKE_idprop.h"
#include "BKE_library.h"
#include "BKE_main.h"
+#include "BKE_mask.h"
#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_paint.h"
@@ -1004,6 +1005,9 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
/* update sound system animation */
sound_update_scene(scene);
+
+ /* update masking curves */
+ BKE_mask_update_scene(bmain, scene, FALSE);
}
/* this is called in main loop, doing tagged updates before redraw */
@@ -1074,6 +1078,8 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
* so don't call within 'scene_update_tagged_recursive' */
DAG_scene_update_flags(bmain, sce, lay, TRUE); // only stuff that moves or needs display still
+ BKE_mask_evaluate_all_masks(bmain, ctime, TRUE);
+
/* All 'standard' (i.e. without any dependencies) animation is handled here,
* with an 'local' to 'macro' order of evaluation. This should ensure that
* settings stored nestled within a hierarchy (i.e. settings in a Texture block
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index e41e9ba18a1..826d9d196b8 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -95,6 +95,7 @@
#include "DNA_vfont_types.h"
#include "DNA_world_types.h"
#include "DNA_movieclip_types.h"
+#include "DNA_mask_types.h"
#include "MEM_guardedalloc.h"
@@ -5353,9 +5354,10 @@ static void lib_link_screen(FileData *fd, Main *main)
}
else if (sl->spacetype == SPACE_CLIP) {
SpaceClip *sclip = (SpaceClip *)sl;
-
+
sclip->clip = newlibadr_us(fd, sc->id.lib, sclip->clip);
-
+ sclip->mask = newlibadr_us(fd, sc->id.lib, sclip->mask);
+
sclip->scopes.track_preview = NULL;
sclip->draw_context = NULL;
sclip->scopes.ok = 0;
@@ -5616,9 +5618,10 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
}
else if (sl->spacetype == SPACE_CLIP) {
SpaceClip *sclip = (SpaceClip *)sl;
-
+
sclip->clip = restore_pointer_by_name(newmain, (ID *)sclip->clip, 1);
-
+ sclip->mask = restore_pointer_by_name(newmain, (ID *)sclip->mask, 1);
+
sclip->scopes.ok = 0;
}
}
@@ -6173,6 +6176,88 @@ static void lib_link_movieclip(FileData *fd, Main *main)
}
}
+/* ***************** READ MOVIECLIP *************** */
+
+static void direct_link_mask(FileData *fd, Mask *mask)
+{
+ MaskLayer *masklay;
+
+ mask->adt = newdataadr(fd, mask->adt);
+
+ link_list(fd, &mask->masklayers);
+
+ for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
+ MaskSpline *spline;
+ MaskLayerShape *masklay_shape;
+
+ link_list(fd, &masklay->splines);
+
+ for (spline = masklay->splines.first; spline; spline = spline->next) {
+ int i;
+
+ spline->points = newdataadr(fd, spline->points);
+
+ for (i = 0; i < spline->tot_point; i++) {
+ MaskSplinePoint *point = &spline->points[i];
+
+ if (point->tot_uw)
+ point->uw = newdataadr(fd, point->uw);
+ }
+ }
+
+ link_list(fd, &masklay->splines_shapes);
+
+ for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) {
+ masklay_shape->data = newdataadr(fd, masklay_shape->data);
+ }
+
+ masklay->act_spline = newdataadr(fd, masklay->act_spline);
+ masklay->act_point = newdataadr(fd, masklay->act_point);
+ }
+}
+
+static void lib_link_mask_parent(FileData *fd, Mask *mask, MaskParent *parent)
+{
+ parent->id = newlibadr_us(fd, mask->id.lib, parent->id);
+}
+
+static void lib_link_mask(FileData *fd, Main *main)
+{
+ Mask *mask;
+
+ mask = main->mask.first;
+ while (mask) {
+ if(mask->id.flag & LIB_NEEDLINK) {
+ MaskLayer *masklay;
+
+ if (mask->adt)
+ lib_link_animdata(fd, &mask->id, mask->adt);
+
+ for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
+ MaskSpline *spline;
+
+ spline = masklay->splines.first;
+ while (spline) {
+ int i;
+
+ for (i = 0; i < spline->tot_point; i++) {
+ MaskSplinePoint *point = &spline->points[i];
+
+ lib_link_mask_parent(fd, mask, &point->parent);
+ }
+
+ lib_link_mask_parent(fd, mask, &spline->parent);
+
+ spline = spline->next;
+ }
+ }
+
+ mask->id.flag -= LIB_NEEDLINK;
+ }
+ mask = mask->id.next;
+ }
+}
+
/* ************** GENERAL & MAIN ******************** */
@@ -6378,6 +6463,9 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
case ID_MC:
direct_link_movieclip(fd, (MovieClip *)id);
break;
+ case ID_MSK:
+ direct_link_mask(fd, (Mask *)id);
+ break;
}
/*link direct data of ID properties*/
@@ -7506,7 +7594,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
}
-
+
if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 8))
{
/* set new deactivation values for game settings */
@@ -7533,7 +7621,29 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
}
-
+
+ {
+ bScreen *sc;
+
+ for (sc = main->screen.first; sc; sc = sc->id.next) {
+ ScrArea *sa;
+
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ SpaceLink *sl;
+
+ for (sl = sa->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_CLIP) {
+ SpaceClip *sclip = (SpaceClip *)sl;
+
+ if (sclip->around == 0) {
+ sclip->around = V3D_CENTROID;
+ }
+ }
+ }
+ }
+ }
+ }
+
/* don't forget to set version number in blender.c! */
}
@@ -7576,7 +7686,8 @@ static void lib_link_all(FileData *fd, Main *main)
lib_link_brush(fd, main);
lib_link_particlesettings(fd, main);
lib_link_movieclip(fd, main);
-
+ lib_link_mask(fd, main);
+
lib_link_mesh(fd, main); /* as last: tpage images with users at zero */
lib_link_library(fd, main); /* only init users */
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 4f75e8e5fbf..655adf97b04 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -133,6 +133,7 @@ Any case: direct data is ALWAYS after the lib block
#include "DNA_world_types.h"
#include "DNA_windowmanager_types.h"
#include "DNA_movieclip_types.h"
+#include "DNA_mask_types.h"
#include "MEM_guardedalloc.h" // MEM_freeN
#include "BLI_bitmap.h"
@@ -2752,6 +2753,59 @@ static void write_movieclips(WriteData *wd, ListBase *idbase)
mywrite(wd, MYWRITE_FLUSH, 0);
}
+static void write_masks(WriteData *wd, ListBase *idbase)
+{
+ Mask *mask;
+
+ mask = idbase->first;
+ while (mask) {
+ if (mask->id.us > 0 || wd->current) {
+ MaskLayer *masklay;
+
+ writestruct(wd, ID_MSK, "Mask", 1, mask);
+
+ if (mask->adt)
+ write_animdata(wd, mask->adt);
+
+ for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
+ MaskSpline *spline;
+ MaskLayerShape *masklay_shape;
+
+ writestruct(wd, DATA, "MaskLayer", 1, masklay);
+
+ for (spline = masklay->splines.first; spline; spline = spline->next) {
+ int i;
+
+ void *points_deform = spline->points_deform;
+ spline->points_deform = NULL;
+
+ writestruct(wd, DATA, "MaskSpline", 1, spline);
+ writestruct(wd, DATA, "MaskSplinePoint", spline->tot_point, spline->points);
+
+ spline->points_deform = points_deform;
+
+ for (i = 0; i < spline->tot_point; i++) {
+ MaskSplinePoint *point = &spline->points[i];
+
+ if (point->tot_uw)
+ writestruct(wd, DATA, "MaskSplinePointUW", point->tot_uw, point->uw);
+ }
+ }
+
+ for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) {
+ writestruct(wd, DATA, "MaskLayerShape", 1, masklay_shape);
+ writedata(wd, DATA, masklay_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, masklay_shape->data);
+ }
+ }
+ }
+
+ mask = mask->id.next;
+ }
+
+ /* flush helps the compression for undo-save */
+ mywrite(wd, MYWRITE_FLUSH, 0);
+}
+
/* context is usually defined by WM, two cases where no WM is available:
* - for forward compatibility, curscreen has to be saved
* - for undofile, curscene needs to be saved */
@@ -2836,6 +2890,7 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
write_screens (wd, &mainvar->screen);
}
write_movieclips (wd, &mainvar->movieclip);
+ write_masks (wd, &mainvar->mask);
write_scenes (wd, &mainvar->scene);
write_curves (wd, &mainvar->curve);
write_mballs (wd, &mainvar->mball);
diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt
index dc28328e867..27bf7df8142 100644
--- a/source/blender/compositor/CMakeLists.txt
+++ b/source/blender/compositor/CMakeLists.txt
@@ -129,6 +129,8 @@ set(SRC
nodes/COM_MovieClipNode.h
nodes/COM_OutputFileNode.cpp
nodes/COM_OutputFileNode.h
+ nodes/COM_MaskNode.cpp
+ nodes/COM_MaskNode.h
# output nodes
nodes/COM_CompositorNode.cpp
@@ -594,6 +596,9 @@ operations/COM_ConvertDepthToRadiusOperation.cpp
operations/COM_AntiAliasOperation.cpp
operations/COM_AntiAliasOperation.h
+
+ operations/COM_MaskOperation.cpp
+ operations/COM_MaskOperation.h
)
blender_add_lib(bf_compositor "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp
index 3cb297801ca..dc6409e7b86 100644
--- a/source/blender/compositor/intern/COM_Converter.cpp
+++ b/source/blender/compositor/intern/COM_Converter.cpp
@@ -111,6 +111,7 @@
#include "COM_DefocusNode.h"
#include "COM_DoubleEdgeMaskNode.h"
#include "COM_CropNode.h"
+#include "COM_MaskNode.h"
Node *Converter::convert(bNode *bNode)
{
@@ -347,6 +348,9 @@ case CMP_NODE_OUTPUT_FILE:
case CMP_NODE_CROP:
node = new CropNode(bNode);
break;
+ case CMP_NODE_MASK:
+ node = new MaskNode(bNode);
+ break;
/* not inplemented yet */
default:
node = new MuteNode(bNode);
diff --git a/source/blender/editors/CMakeLists.txt b/source/blender/editors/CMakeLists.txt
index 088376b20ef..67ed77bcc4b 100644
--- a/source/blender/editors/CMakeLists.txt
+++ b/source/blender/editors/CMakeLists.txt
@@ -24,6 +24,7 @@ if(WITH_BLENDER)
add_subdirectory(curve)
add_subdirectory(gpencil)
add_subdirectory(interface)
+ add_subdirectory(mask)
add_subdirectory(mesh)
add_subdirectory(metaball)
add_subdirectory(object)
diff --git a/source/blender/editors/SConscript b/source/blender/editors/SConscript
index ed66a76a324..d08b496f0ef 100644
--- a/source/blender/editors/SConscript
+++ b/source/blender/editors/SConscript
@@ -8,6 +8,7 @@ SConscript(['datafiles/SConscript',
'interface/SConscript',
'animation/SConscript',
'armature/SConscript',
+ 'mask/SConscript',
'mesh/SConscript',
'metaball/SConscript',
'object/SConscript',
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index cb7dc7ac206..cee8d15a807 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -60,6 +60,7 @@
#include "DNA_speaker_types.h"
#include "DNA_world_types.h"
#include "DNA_gpencil_types.h"
+#include "DNA_mask_types.h"
#include "BKE_key.h"
#include "BKE_material.h"
@@ -184,6 +185,50 @@ static void nupdate_ak_gpframe(void *node, void *data)
ak->modified += 1;
}
+/* ......... */
+
+/* Comparator callback used for ActKeyColumns and GPencil frame */
+static short compare_ak_masklayshape(void *node, void *data)
+{
+ ActKeyColumn *ak = (ActKeyColumn *)node;
+ MaskLayerShape *masklay_shape = (MaskLayerShape *)data;
+
+ if (masklay_shape->frame < ak->cfra)
+ return -1;
+ else if (masklay_shape->frame > ak->cfra)
+ return 1;
+ else
+ return 0;
+}
+
+/* New node callback used for building ActKeyColumns from GPencil frames */
+static DLRBT_Node *nalloc_ak_masklayshape(void *data)
+{
+ ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF");
+ MaskLayerShape *masklay_shape = (MaskLayerShape *)data;
+
+ /* store settings based on state of BezTriple */
+ ak->cfra = masklay_shape->frame;
+ ak->sel = (masklay_shape->flag & SELECT) ? SELECT : 0;
+
+ /* set 'modified', since this is used to identify long keyframes */
+ ak->modified = 1;
+
+ return (DLRBT_Node *)ak;
+}
+
+/* Node updater callback used for building ActKeyColumns from GPencil frames */
+static void nupdate_ak_masklayshape(void *node, void *data)
+{
+ ActKeyColumn *ak = (ActKeyColumn *)node;
+ MaskLayerShape *masklay_shape = (MaskLayerShape *)data;
+
+ /* set selection status and 'touched' status */
+ if (masklay_shape->flag & SELECT) ak->sel = SELECT;
+ ak->modified += 1;
+}
+
+
/* --------------- */
/* Add the given BezTriple to the given 'list' of Keyframes */
@@ -204,6 +249,15 @@ static void add_gpframe_to_keycolumns_list(DLRBT_Tree *keys, bGPDframe *gpf)
BLI_dlrbTree_add(keys, compare_ak_gpframe, nalloc_ak_gpframe, nupdate_ak_gpframe, gpf);
}
+/* Add the given MaskLayerShape Frame to the given 'list' of Keyframes */
+static void add_masklay_to_keycolumns_list(DLRBT_Tree *keys, MaskLayerShape *masklay_shape)
+{
+ if (ELEM(NULL, keys, masklay_shape))
+ return;
+ else
+ BLI_dlrbTree_add(keys, compare_ak_masklayshape, nalloc_ak_masklayshape, nupdate_ak_masklayshape, masklay_shape);
+}
+
/* ActBeztColumns (Helpers for Long Keyframes) ------------------------------ */
/* maximum size of default buffer for BezTriple columns */
@@ -940,3 +994,17 @@ void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, DLRBT_Tree *keys)
}
}
+void mask_to_keylist(bDopeSheet *UNUSED(ads), MaskLayer *masklay, DLRBT_Tree *keys)
+{
+ MaskLayerShape *masklay_shape;
+
+ if (masklay && keys) {
+ for (masklay_shape = masklay->splines_shapes.first;
+ masklay_shape;
+ masklay_shape = masklay_shape->next)
+ {
+ add_masklay_to_keycolumns_list(keys, masklay_shape);
+ }
+ }
+}
+
diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h
index 7943a17c377..7e1505b652f 100644
--- a/source/blender/editors/include/ED_clip.h
+++ b/source/blender/editors/include/ED_clip.h
@@ -36,6 +36,7 @@ struct bContext;
struct bScreen;
struct ImBuf;
struct Main;
+struct Mask;
struct MovieClip;
struct SpaceClip;
struct wmEvent;
@@ -48,12 +49,19 @@ int ED_space_clip_view_clip_poll(struct bContext *C);
int ED_space_clip_tracking_poll(struct bContext *C);
int ED_space_clip_tracking_size_poll(struct bContext *C);
int ED_space_clip_tracking_frame_poll(struct bContext *C);
+int ED_space_clip_maskediting_poll(struct bContext *C);
+int ED_space_clip_maskediting_mask_poll(bContext *C);
void ED_space_clip_set(struct bContext *C, struct bScreen *screen, struct SpaceClip *sc, struct MovieClip *clip);
struct MovieClip *ED_space_clip(struct SpaceClip *sc);
+struct Mask *ED_space_clip_mask(struct SpaceClip *sc);
void ED_space_clip_size(struct SpaceClip *sc, int *width, int *height);
void ED_space_clip_zoom(struct SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy);
void ED_space_clip_aspect(struct SpaceClip *sc, float *aspx, float *aspy);
+void ED_space_clip_aspect_dimension_aware(struct SpaceClip *sc, float *aspx, float *aspy);
+
+void ED_space_clip_mask_size(struct SpaceClip *sc, int *width, int *height);
+void ED_space_clip_mask_aspect(struct SpaceClip *sc, float *aspx, float *aspy);
struct ImBuf *ED_space_clip_get_buffer(struct SpaceClip *sc);
struct ImBuf *ED_space_clip_get_stable_buffer(struct SpaceClip *sc, float loc[2], float *scale, float *angle);
@@ -72,6 +80,8 @@ void ED_space_clip_unload_movieclip_buffer(struct SpaceClip *sc);
void ED_space_clip_free_texture_buffer(struct SpaceClip *sc);
int ED_space_clip_show_trackedit(struct SpaceClip *sc);
+int ED_space_clip_show_maskedit(struct SpaceClip *sc);
+void ED_space_clip_set_mask(struct bContext *C, struct SpaceClip *sc, struct Mask *mask);
/* clip_ops.c */
void ED_operatormacros_clip(void);
diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h
index cd64427de78..e24c21bc133 100644
--- a/source/blender/editors/include/ED_keyframes_draw.h
+++ b/source/blender/editors/include/ED_keyframes_draw.h
@@ -42,6 +42,7 @@ struct bActionGroup;
struct Object;
struct ListBase;
struct bGPDlayer;
+struct MaskLayer;
struct Scene;
struct View2D;
struct DLRBT_Tree;
@@ -139,6 +140,9 @@ void summary_to_keylist(struct bAnimContext *ac, struct DLRBT_Tree *keys, struct
/* Grease Pencil Layer */
// XXX not restored
void gpl_to_keylist(struct bDopeSheet *ads, struct bGPDlayer *gpl, struct DLRBT_Tree *keys);
+/* Mask */
+// XXX not restored
+void mask_to_keylist(struct bDopeSheet *UNUSED(ads), struct MaskLayer *masklay, struct DLRBT_Tree *keys);
/* ActKeyColumn API ---------------- */
/* Comparator callback used for ActKeyColumns and cframe float-value pointer */
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 8dc83df2977..9c10a270ef8 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -90,6 +90,7 @@ struct Base *ED_object_scene_link(struct Scene *scene, struct Object *ob);
void ED_keymap_proportional_cycle(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap);
void ED_keymap_proportional_obmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap);
+void ED_keymap_proportional_maskmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap);
void ED_keymap_proportional_editmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap,
const short do_connected);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 464f2db30a2..4faf82eec36 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -170,6 +170,7 @@ int ED_operator_editmball(struct bContext *C);
int ED_operator_uvedit(struct bContext *C);
int ED_operator_uvmap(struct bContext *C);
int ED_operator_posemode(struct bContext *C);
+int ED_operator_mask(struct bContext *C);
/* default keymaps, bitflags */
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index 3bef1f56655..d867532b273 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -96,6 +96,7 @@ enum {
#define CTX_BMESH 64
#define CTX_NDOF 128
#define CTX_MOVIECLIP 256
+#define CTX_MASK 512
/* Standalone call to get the transformation center corresponding to the current situation
* returns 1 if successful, 0 otherwise (usually means there's no selection)
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 59ef0c00283..daba096696c 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -579,8 +579,10 @@ void uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, co
row = uiLayoutRow(layout, 1);
/* Label - either use the provided text, or will become "ID-Block:" */
- if (text)
- uiItemL(row, text, ICON_NONE);
+ if (text) {
+ if (text[0])
+ uiItemL(row, text, ICON_NONE);
+ }
else
uiItemL(row, "ID-Block:", ICON_NONE);
@@ -2239,6 +2241,20 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
uiItemL(split, name, ICON_OBJECT_DATA);
}
}
+ else if (itemptr->type == &RNA_MaskLayer) {
+ split = uiLayoutSplit(sub, 0.66f, 0);
+
+ uiItemL(split, name, icon);
+
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+ row = uiLayoutRow(split, 1);
+ // uiItemR(row, itemptr, "alpha", 0, "", ICON_NONE); // enable when used
+ uiItemR(row, itemptr, "hide", 0, "", 0);
+ uiItemR(row, itemptr, "hide_select", 0, "", 0);
+ uiItemR(row, itemptr, "hide_render", 0, "", 0);
+
+ uiBlockSetEmboss(block, UI_EMBOSS);
+ }
/* There is a last chance to display custom controls (in addition to the name/label):
* If the given item property group features a string property named as prop_list,
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 6e653eff57c..d0a93302b7f 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -441,6 +441,14 @@ void ED_keymap_proportional_obmode(struct wmKeyConfig *UNUSED(keyconf), struct w
RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_proportional_edit_objects");
}
+void ED_keymap_proportional_maskmode(struct wmKeyConfig *UNUSED(keyconf), struct wmKeyMap *keymap)
+{
+ wmKeyMapItem *kmi;
+
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", OKEY, KM_PRESS, 0, 0);
+ RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_proportional_edit_mask");
+}
+
void ED_keymap_proportional_editmode(struct wmKeyConfig *UNUSED(keyconf), struct wmKeyMap *keymap,
const short do_connected)
{
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 8baca253519..89c7896d53c 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -46,6 +46,7 @@
#include "DNA_scene_types.h"
#include "DNA_meta_types.h"
#include "DNA_mesh_types.h"
+#include "DNA_mask_types.h"
#include "DNA_userdef_types.h"
#include "BKE_context.h"
@@ -59,6 +60,7 @@
#include "BKE_screen.h"
#include "BKE_tessmesh.h"
#include "BKE_sound.h"
+#include "BKE_mask.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -71,6 +73,7 @@
#include "ED_screen_types.h"
#include "ED_keyframes_draw.h"
#include "ED_view3d.h"
+#include "ED_clip.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -453,6 +456,13 @@ int ED_operator_editmball(bContext *C)
return 0;
}
+int ED_operator_mask(bContext *C)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+
+ return ED_space_clip_show_maskedit(sc);
+}
+
/* *************************** action zone operator ************************** */
/* operator state vars used:
@@ -1937,7 +1947,17 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
if (ob)
ob_to_keylist(&ads, ob, &keys, NULL);
-
+
+ {
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ if (sc) {
+ if ((sc->mode == SC_MODE_MASKEDITING) && sc->mask) {
+ MaskLayer *masklay = BKE_mask_layer_active(sc->mask);
+ mask_to_keylist(&ads, masklay, &keys);
+ }
+ }
+ }
+
/* build linked-list for searching */
BLI_dlrbTree_linkedlist_sync(&keys);
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 956aee84fd3..fa77249a7a1 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -62,6 +62,7 @@
#include "ED_mball.h"
#include "ED_logic.h"
#include "ED_clip.h"
+#include "ED_mask.h"
/* only call once on startup, storage is global in BKE kernel listbase */
void ED_spacetypes_init(void)
@@ -111,6 +112,7 @@ void ED_spacetypes_init(void)
ED_operatortypes_sound();
ED_operatortypes_render();
ED_operatortypes_logic();
+ ED_operatortypes_mask();
UI_view2d_operatortypes();
UI_buttons_operatortypes();
@@ -133,6 +135,7 @@ void ED_spacetypes_init(void)
ED_operatormacros_action();
ED_operatormacros_clip();
ED_operatormacros_curve();
+ ED_operatormacros_mask();
/* register dropboxes (can use macros) */
spacetypes = BKE_spacetypes_list();
@@ -164,6 +167,7 @@ void ED_spacetypes_keymap(wmKeyConfig *keyconf)
ED_keymap_physics(keyconf);
ED_keymap_metaball(keyconf);
ED_keymap_paint(keyconf);
+ ED_keymap_mask(keyconf);
ED_marker_keymap(keyconf);
UI_view2d_keymap(keyconf);
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index c00359f0f32..6ac5ec59742 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -33,12 +33,14 @@
#include "DNA_movieclip_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h" /* SELECT */
+#include "DNA_mask_types.h"
#include "MEM_guardedalloc.h"
#include "BKE_context.h"
#include "BKE_movieclip.h"
#include "BKE_tracking.h"
+#include "BKE_mask.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -194,6 +196,32 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
glRecti(x, 0, x + framelen, 8);
clip_draw_curfra_label(sc, x, 8.0f);
+
+ /* movie clip animation */
+ if ((sc->mode == SC_MODE_MASKEDITING) && sc->mask) {
+ MaskLayer *masklay = BKE_mask_layer_active(sc->mask);
+ if (masklay) {
+ MaskLayerShape *masklay_shape;
+
+ glColor4ub(255, 175, 0, 255);
+ glBegin(GL_LINES);
+
+ for (masklay_shape = masklay->splines_shapes.first;
+ masklay_shape;
+ masklay_shape = masklay_shape->next)
+ {
+ i = masklay_shape->frame;
+
+ /* glRecti((i - sfra) * framelen, 0, (i - sfra + 1) * framelen, 4); */
+
+ /* use a line so we always see the keyframes */
+ glVertex2i((i - sfra) * framelen, 0);
+ glVertex2i((i - sfra) * framelen, (i == CFRA) ? 22 : 10);
+ }
+
+ glEnd();
+ }
+ }
}
static void draw_movieclip_notes(SpaceClip *sc, ARegion *ar)
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index a477a7435fd..f16ef21b707 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -34,10 +34,12 @@
#include "MEM_guardedalloc.h"
#include "BKE_main.h"
+#include "BKE_mask.h"
#include "BKE_movieclip.h"
#include "BKE_context.h"
#include "BKE_tracking.h"
+#include "DNA_mask_types.h"
#include "DNA_object_types.h" /* SELECT */
#include "BLI_utildefines.h"
@@ -127,6 +129,32 @@ int ED_space_clip_tracking_frame_poll(bContext *C)
return FALSE;
}
+int ED_space_clip_maskediting_poll(bContext *C)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+
+ if (sc && sc->clip) {
+ return ED_space_clip_show_maskedit(sc);
+ }
+
+ return FALSE;
+}
+
+int ED_space_clip_maskediting_mask_poll(bContext *C)
+{
+ if (ED_space_clip_maskediting_poll(C)) {
+ MovieClip *clip = CTX_data_edit_movieclip(C);
+
+ if (clip) {
+ SpaceClip *sc= CTX_wm_space_clip(C);
+
+ return sc->mask != NULL;
+ }
+ }
+
+ return FALSE;
+}
+
/* ******** editing functions ******** */
void ED_space_clip_set(bContext *C, bScreen *screen, SpaceClip *sc, MovieClip *clip)
@@ -170,6 +198,11 @@ MovieClip *ED_space_clip(SpaceClip *sc)
return sc->clip;
}
+Mask *ED_space_clip_mask(SpaceClip *sc)
+{
+ return sc->mask;
+}
+
ImBuf *ED_space_clip_get_buffer(SpaceClip *sc)
{
if (sc->clip) {
@@ -214,6 +247,51 @@ void ED_space_clip_size(SpaceClip *sc, int *width, int *height)
}
}
+void ED_space_clip_mask_size(SpaceClip *sc, int *width, int *height)
+{
+ /* quite the same as ED_space_clip_size, but it also runs aspect correction on output resolution
+ * this is needed because mask should be rasterized with exactly the same resolution as
+ * currently displaying frame and it doesn't have access to aspect correction currently
+ * used for display. (sergey)
+ */
+
+ if (!sc->mask) {
+ *width = 0;
+ *height = 0;
+ } else {
+ float aspx, aspy;
+
+ ED_space_clip_size(sc, width, height);
+ ED_space_clip_aspect(sc, &aspx, &aspy);
+
+ *width *= aspx;
+ *height *= aspy;
+ }
+}
+
+void ED_space_clip_mask_aspect(SpaceClip *sc, float *aspx, float *aspy)
+{
+ int w, h;
+
+ ED_space_clip_aspect(sc, aspx, aspy);
+ ED_space_clip_size(sc, &w, &h);
+
+ /* now this is not accounted for! */
+#if 0
+ *aspx *= (float)w;
+ *aspy *= (float)h;
+#endif
+
+ if(*aspx < *aspy) {
+ *aspy= *aspy / *aspx;
+ *aspx= 1.0f;
+ }
+ else {
+ *aspx= *aspx / *aspy;
+ *aspy= 1.0f;
+ }
+}
+
void ED_space_clip_zoom(SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy)
{
int width, height;
@@ -234,6 +312,33 @@ void ED_space_clip_aspect(SpaceClip *sc, float *aspx, float *aspy)
*aspx = *aspy = 1.0f;
}
+void ED_space_clip_aspect_dimension_aware(SpaceClip *sc, float *aspx, float *aspy)
+{
+ int w, h;
+
+ /* most of tools does not require aspect to be returned with dimensions correction
+ * due to they're invariant to this stuff, but some transformation tools like rotation
+ * should be aware of aspect correction caused by different resolution in different
+ * directions.
+ * mainly this is sued for transformation stuff
+ */
+
+ ED_space_clip_aspect(sc, aspx, aspy);
+ ED_space_clip_size(sc, &w, &h);
+
+ *aspx *= (float)w;
+ *aspy *= (float)h;
+
+ if(*aspx < *aspy) {
+ *aspy= *aspy / *aspx;
+ *aspx= 1.0f;
+ }
+ else {
+ *aspx= *aspx / *aspy;
+ *aspy= 1.0f;
+ }
+}
+
void ED_clip_update_frame(const Main *mainp, int cfra)
{
wmWindowManager *wm;
@@ -562,6 +667,8 @@ void ED_space_clip_free_texture_buffer(SpaceClip *sc)
}
}
+/* ******** masking editing related functions ******** */
+
int ED_space_clip_show_trackedit(SpaceClip *sc)
{
if (sc) {
@@ -570,3 +677,23 @@ int ED_space_clip_show_trackedit(SpaceClip *sc)
return FALSE;
}
+
+int ED_space_clip_show_maskedit(SpaceClip *sc)
+{
+ if (sc) {
+ return sc->mode == SC_MODE_MASKEDITING;
+ }
+
+ return FALSE;
+}
+
+void ED_space_clip_set_mask(bContext *C, SpaceClip *sc, Mask *mask)
+{
+ sc->mask = mask;
+
+ if(sc->mask && sc->mask->id.us==0)
+ sc->clip->id.us = 1;
+
+ if(C)
+ WM_event_add_notifier(C, NC_MASK|NA_SELECTED, mask);
+}
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index a6fda200ff4..5e04d5c99cd 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -33,7 +33,9 @@
#include <stdio.h>
#include "DNA_scene_types.h"
+#include "DNA_mask_types.h"
#include "DNA_movieclip_types.h"
+#include "DNA_view3d_types.h" /* for pivot point */
#include "MEM_guardedalloc.h"
@@ -49,6 +51,8 @@
#include "IMB_imbuf_types.h"
+#include "ED_mask.h"
+#include "ED_space_api.h"
#include "ED_screen.h"
#include "ED_clip.h"
#include "ED_transform.h"
@@ -237,6 +241,7 @@ static SpaceLink *clip_new(const bContext *C)
sc->zoom = 1.0f;
sc->path_length = 20;
sc->scopes.track_preview_height = 120;
+ sc->around = V3D_LOCAL;
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for clip");
@@ -361,6 +366,24 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn)
break;
}
break;
+ case NC_MASK:
+ switch(wmn->data) {
+ case ND_SELECT:
+ case ND_DATA:
+ case ND_DRAW:
+ ED_area_tag_redraw(sa);
+ break;
+ }
+ switch(wmn->action) {
+ case NA_SELECTED:
+ clip_scopes_tag_refresh(sa);
+ ED_area_tag_redraw(sa);
+ break;
+ case NA_EDITED:
+ ED_area_tag_redraw(sa);
+ break;
+ }
+ break;
case NC_GEOM:
switch (wmn->data) {
case ND_SELECT:
@@ -532,7 +555,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
/* ******** Hotkeys avalaible for main region only ******** */
keymap = WM_keymap_find(keyconf, "Clip Editor", SPACE_CLIP, 0);
-
+// keymap->poll = ED_space_clip_tracking_poll;
/* ** View/navigation ** */
WM_keymap_add_item(keymap, "CLIP_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
@@ -715,7 +738,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
RNA_boolean_set(kmi->ptr, "extend", TRUE); /* toggle */
}
-const char *clip_context_dir[] = {"edit_movieclip", NULL};
+const char *clip_context_dir[] = {"edit_movieclip", "edit_mask", NULL};
static int clip_context(const bContext *C, const char *member, bContextDataResult *result)
{
@@ -729,7 +752,11 @@ static int clip_context(const bContext *C, const char *member, bContextDataResul
else if (CTX_data_equals(member, "edit_movieclip")) {
if (sc->clip)
CTX_data_id_pointer_set(result, &sc->clip->id);
-
+ return TRUE;
+ }
+ else if (CTX_data_equals(member, "edit_mask")) {
+ if (sc->mask)
+ CTX_data_id_pointer_set(result, &sc->mask->id);
return TRUE;
}
@@ -1020,6 +1047,9 @@ static void clip_main_area_init(wmWindowManager *wm, ARegion *ar)
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
/* own keymap */
+ keymap= WM_keymap_find(wm->defaultconf, "Mask Editor", 0, 0);
+ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
+
keymap = WM_keymap_find(wm->defaultconf, "Clip", SPACE_CLIP, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
@@ -1067,6 +1097,49 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar)
/* Grease Pencil */
clip_draw_grease_pencil((bContext *)C, 1);
+ if(sc->mode == SC_MODE_MASKEDITING) {
+ int x, y;
+ int width, height;
+ float zoomx, zoomy, aspx, aspy;
+
+ /* frame image */
+ float maxdim;
+ float xofs, yofs;
+
+ /* find window pixel coordinates of origin */
+ UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y);
+
+ ED_space_clip_size(sc, &width, &height);
+ ED_space_clip_zoom(sc, ar, &zoomx, &zoomy);
+ ED_space_clip_aspect(sc, &aspx, &aspy);
+
+ /* frame the image */
+ maxdim = maxf(width, height);
+ if (width == height) {
+ xofs = yofs = 0;
+ }
+ else if (width < height) {
+ xofs = ((height - width) / -2.0f) * zoomx;
+ yofs = 0.0f;
+ }
+ else { /* (width > height) */
+ xofs = 0.0f;
+ yofs = ((width - height) / -2.0f) * zoomy;
+ }
+
+ /* apply transformation so mask editing tools will assume drawing from the origin in normalized space */
+ glPushMatrix();
+ glTranslatef(x + xofs, y + yofs, 0);
+ glScalef(maxdim * zoomx, maxdim * zoomy, 0);
+ glMultMatrixf(sc->stabmat);
+
+ ED_mask_draw((bContext *)C, sc->mask_draw_flag, sc->mask_draw_type);
+
+ ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
+
+ glPopMatrix();
+ }
+
/* reset view matrix */
UI_view2d_view_restore(C);
@@ -1241,6 +1314,26 @@ static void clip_header_area_draw(const bContext *C, ARegion *ar)
ED_region_header(C, ar);
}
+static void clip_header_area_listener(ARegion *ar, wmNotifier *wmn)
+{
+ /* context changes */
+ switch (wmn->category) {
+ case NC_SCENE:
+ switch (wmn->data) {
+ /* for proportional editmode only */
+ case ND_TOOLSETTINGS:
+ /* TODO - should do this when in mask mode only but no datas available */
+ // if(sc->mode == SC_MODE_MASKEDITING)
+ {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ }
+ break;
+ }
+}
+
+
/****************** tools region ******************/
/* add handlers, stuff you only do once or on area/region changes */
@@ -1402,6 +1495,7 @@ void ED_spacetype_clip(void)
art->init = clip_header_area_init;
art->draw = clip_header_area_draw;
+ art->listener = clip_header_area_listener;
BLI_addhead(&st->regiontypes, art);
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 73ca9097610..5a8bc5da324 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -2400,6 +2400,11 @@ static void node_composit_buts_viewer_but(uiLayout *layout, bContext *UNUSED(C),
}
}
+static void node_composit_buts_mask(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ uiTemplateID(layout, C, ptr, "mask", NULL, NULL, NULL);
+}
+
/* only once called */
static void node_composit_set_butfunc(bNodeType *ntype)
{
@@ -2589,7 +2594,9 @@ static void node_composit_set_butfunc(bNodeType *ntype)
ntype->uifuncbut = node_composit_buts_viewer_but;
ntype->uibackdropfunc = node_composit_backdrop_viewer;
break;
-
+ case CMP_NODE_MASK:
+ ntype->uifunc= node_composit_buts_mask;
+ break;
default:
ntype->uifunc = NULL;
}
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index 520a9f1cd22..66919935d48 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -245,6 +245,13 @@ static void node_area_listener(ScrArea *sa, wmNotifier *wmn)
break;
}
break;
+ case NC_MASK:
+ if (wmn->action == NA_EDITED) {
+ if (type==NTREE_COMPOSIT) {
+ ED_area_tag_refresh(sa);
+ }
+ }
+ break;
case NC_IMAGE:
if (wmn->action == NA_EDITED) {
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index e955dae0178..157fe1aa710 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -49,6 +49,7 @@
#include "DNA_constraint_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_mask_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_scene_types.h" /* PET modes */
@@ -162,13 +163,35 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy)
else if (t->spacetype==SPACE_CLIP) {
View2D *v2d = t->view;
float divx, divy;
+ float mulx, muly;
+ float aspx = 1.0f, aspy = 1.0f;
divx = v2d->mask.xmax-v2d->mask.xmin;
divy = v2d->mask.ymax-v2d->mask.ymin;
- r_vec[0] = (v2d->cur.xmax-v2d->cur.xmin)*(dx)/divx;
- r_vec[1] = (v2d->cur.ymax-v2d->cur.ymin)*(dy)/divy;
+ mulx = (v2d->cur.xmax-v2d->cur.xmin);
+ muly = (v2d->cur.ymax-v2d->cur.ymin);
+
+ if (t->options & CTX_MASK) {
+ /* clamp w/h, mask only */
+ divx = divy = maxf(divx, divy);
+ mulx = muly = minf(mulx, muly);
+ }
+
+ r_vec[0] = mulx * (dx) / divx;
+ r_vec[1] = muly * (dy) / divy;
r_vec[2] = 0.0f;
+
+ if (t->options & CTX_MOVIECLIP) {
+ ED_space_clip_aspect_dimension_aware(t->sa->spacedata.first, &aspx, &aspy);
+ }
+ else if (t->options & CTX_MASK) {
+ /* TODO - NOT WORKING, this isnt so bad since its only display aspect */
+ ED_space_clip_mask_aspect(t->sa->spacedata.first, &aspx, &aspy);
+ }
+
+ r_vec[0] *= aspx;
+ r_vec[1] *= aspy;
}
else {
printf("%s: called in an invalid context\n", __func__);
@@ -226,9 +249,18 @@ void projectIntView(TransInfo *t, const float vec[3], int adr[2])
}
else if (t->spacetype==SPACE_CLIP) {
float v[2];
+ float aspx = 1.0f, aspy = 1.0f;
copy_v2_v2(v, vec);
+ if (t->options & CTX_MOVIECLIP)
+ ED_space_clip_aspect_dimension_aware(t->sa->spacedata.first, &aspx, &aspy);
+ else if (t->options & CTX_MASK)
+ ED_space_clip_mask_aspect(t->sa->spacedata.first, &aspx, &aspy);
+
+ v[0] /= aspx;
+ v[1] /= aspy;
+
UI_view2d_to_region_no_clip(t->view, v[0], v[1], adr, adr+1);
}
}
@@ -279,16 +311,23 @@ void applyAspectRatio(TransInfo *t, float vec[2])
vec[1] /= aspy;
}
else if ((t->spacetype==SPACE_CLIP) && (t->mode==TFM_TRANSLATION)) {
- if (t->options & CTX_MOVIECLIP) {
+ if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
SpaceClip *sc = t->sa->spacedata.first;
float aspx, aspy;
- int width, height;
- ED_space_clip_size(sc, &width, &height);
- ED_space_clip_aspect(sc, &aspx, &aspy);
- vec[0] *= width / aspx;
- vec[1] *= height / aspy;
+ if (t->options & CTX_MOVIECLIP) {
+ ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy);
+
+ vec[0] /= aspx;
+ vec[1] /= aspy;
+ }
+ else if (t->options & CTX_MASK) {
+ ED_space_clip_mask_aspect(sc, &aspx, &aspy);
+
+ vec[0] /= aspx;
+ vec[1] /= aspy;
+ }
}
}
}
@@ -312,16 +351,19 @@ void removeAspectRatio(TransInfo *t, float vec[2])
vec[1] *= aspy;
}
else if ((t->spacetype==SPACE_CLIP) && (t->mode==TFM_TRANSLATION)) {
- if (t->options & CTX_MOVIECLIP) {
+ if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
SpaceClip *sc = t->sa->spacedata.first;
- float aspx, aspy;
- int width, height;
+ float aspx = 1.0f, aspy = 1.0f;
- ED_space_clip_size(sc, &width, &height);
- ED_space_clip_aspect(sc, &aspx, &aspy);
+ if (t->options & CTX_MOVIECLIP) {
+ ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy);
+ }
+ else if (t->options & CTX_MASK) {
+ ED_space_clip_mask_aspect(sc, &aspx, &aspy);
+ }
- vec[0] *= aspx / width;
- vec[1] *= aspy / height;
+ vec[0] *= aspx;
+ vec[1] *= aspy;
}
}
}
@@ -367,12 +409,20 @@ static void viewRedrawForce(const bContext *C, TransInfo *t)
}
else if (t->spacetype==SPACE_CLIP) {
SpaceClip *sc = (SpaceClip*)t->sa->spacedata.first;
- MovieClip *clip = ED_space_clip(sc);
- /* objects could be parented to tracking data, so send this for viewport refresh */
- WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+ if (ED_space_clip_show_trackedit(sc)) {
+ MovieClip *clip = ED_space_clip(sc);
+
+ /* objects could be parented to tracking data, so send this for viewport refresh */
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
- WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip);
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip);
+ }
+ else if (ED_space_clip_show_maskedit(sc)) {
+ Mask *mask = ED_space_clip_mask(sc);
+
+ WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask);
+ }
}
}
@@ -728,7 +778,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
t->redraw |= TREDRAW_HARD;
}
else if (t->mode == TFM_TRANSLATION) {
- if (t->options & CTX_MOVIECLIP) {
+ if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
restoreTransObjects(t);
t->flag ^= T_ALT_TRANSFORM;
@@ -738,7 +788,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
break;
case TFM_MODAL_ROTATE:
/* only switch when... */
- if (!(t->options & CTX_TEXTURE) && !(t->options & CTX_MOVIECLIP)) {
+ if (!(t->options & CTX_TEXTURE) && !(t->options & (CTX_MOVIECLIP | CTX_MASK))) {
if ( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) {
resetTransRestrictions(t);
@@ -997,7 +1047,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
break;
case RKEY:
/* only switch when... */
- if (!(t->options & CTX_TEXTURE) && !(t->options & CTX_MOVIECLIP)) {
+ if (!(t->options & CTX_TEXTURE)) {
if ( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) {
resetTransRestrictions(t);
@@ -1459,6 +1509,8 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
{
if (t->obedit)
ts->proportional = proportional;
+ else if (t->options & CTX_MASK)
+ ts->proportional_mask = (proportional != PROP_EDIT_OFF);
else
ts->proportional_objects = (proportional != PROP_EDIT_OFF);
}
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 6051fd2577b..59688f1436e 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -561,6 +561,7 @@ int clipUVTransform(TransInfo *t, float *vec, int resize);
void flushTransNodes(TransInfo *t);
void flushTransSeq(TransInfo *t);
void flushTransTracking(TransInfo *t);
+void flushTransMasking(TransInfo *t);
/*********************** exported from transform_manipulator.c ********** */
int gimbal_axis(struct Object *ob, float gmat[][3]); /* return 0 when no gimbal for selection */
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index a069194d868..9c6d7e49c08 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -53,6 +53,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_movieclip_types.h"
+#include "DNA_mask_types.h"
#include "MEM_guardedalloc.h"
@@ -87,6 +88,7 @@
#include "BKE_sequencer.h"
#include "BKE_tessmesh.h"
#include "BKE_tracking.h"
+#include "BKE_mask.h"
#include "ED_anim_api.h"
@@ -102,6 +104,7 @@
#include "ED_types.h"
#include "ED_uvedit.h"
#include "ED_clip.h"
+#include "ED_mask.h"
#include "ED_util.h" /* for crazyspace correction */
#include "WM_api.h" /* for WM_event_add_notifier to deal with stabilization nodes */
@@ -4897,6 +4900,24 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL);
}
}
+ else if (t->options & CTX_MASK) {
+ SpaceClip *sc = t->sa->spacedata.first;
+ Mask *mask = ED_space_clip_mask(sc);
+
+ if (t->scene->nodetree) {
+ /* tracks can be used for stabilization nodes,
+ * flush update for such nodes */
+ nodeUpdateID(t->scene->nodetree, &mask->id);
+ WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL);
+ }
+
+ /* TODO - dont key all masks... */
+ if (IS_AUTOKEY_ON(t->scene)) {
+ Scene *scene = t->scene;
+
+ ED_mask_layer_shape_auto_key_all(mask, CFRA);
+ }
+ }
}
else if (t->spacetype == SPACE_ACTION) {
SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first;
@@ -5823,6 +5844,206 @@ void flushTransTracking(TransInfo *t)
}
}
+/* * masking * */
+
+typedef struct TransDataMasking{
+ int is_handle;
+
+ float handle[2], orig_handle[2];
+ float vec[3][3];
+ MaskSplinePoint *point;
+} TransDataMasking;
+
+static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point,
+ TransData *td, TransData2D *td2d, TransDataMasking *tdm, int propmode)
+{
+ BezTriple *bezt = &point->bezt;
+ float aspx, aspy;
+ short is_sel_point = MASKPOINT_ISSEL_KNOT(point);
+ short is_sel_any = MASKPOINT_ISSEL_ANY(point);
+
+ tdm->point = point;
+ copy_m3_m3(tdm->vec, bezt->vec);
+
+ ED_space_clip_mask_aspect(sc, &aspx, &aspy);
+
+ if (propmode || is_sel_point) {
+ int i;
+ for (i = 0; i < 3; i++) {
+ /* CV coords are scaled by aspects. this is needed for rotations and
+ * proportional editing to be consistent with the stretched CV coords
+ * that are displayed. this also means that for display and numinput,
+ * and when the the CV coords are flushed, these are converted each time */
+ td2d->loc[0] = bezt->vec[i][0]*aspx;
+ td2d->loc[1] = bezt->vec[i][1]*aspy;
+ td2d->loc[2] = 0.0f;
+ td2d->loc2d = bezt->vec[i];
+
+ td->flag = 0;
+ td->loc = td2d->loc;
+ copy_v3_v3(td->center, td->loc);
+ copy_v3_v3(td->iloc, td->loc);
+
+ memset(td->axismtx, 0, sizeof(td->axismtx));
+ td->axismtx[2][2] = 1.0f;
+
+ td->ext= NULL;
+ td->val= NULL;
+
+ if (is_sel_any) {
+ td->flag |= TD_SELECTED;
+ }
+ td->dist= 0.0;
+
+ unit_m3(td->mtx);
+ unit_m3(td->smtx);
+
+ td++;
+ td2d++;
+ }
+ }
+ else {
+ tdm->is_handle = TRUE;
+
+ BKE_mask_point_handle(point, tdm->handle);
+
+ copy_v2_v2(tdm->orig_handle, tdm->handle);
+
+ td2d->loc[0] = tdm->handle[0]*aspx;
+ td2d->loc[1] = tdm->handle[1]*aspy;
+ td2d->loc[2] = 0.0f;
+ td2d->loc2d = tdm->handle;
+
+ td->flag = 0;
+ td->loc = td2d->loc;
+ copy_v3_v3(td->center, td->loc);
+ copy_v3_v3(td->iloc, td->loc);
+
+ memset(td->axismtx, 0, sizeof(td->axismtx));
+ td->axismtx[2][2] = 1.0f;
+
+ td->ext= NULL;
+ td->val= NULL;
+
+ if (is_sel_any) {
+ td->flag |= TD_SELECTED;
+ }
+
+ td->dist= 0.0;
+
+ unit_m3(td->mtx);
+ unit_m3(td->smtx);
+
+ td++;
+ td2d++;
+ }
+}
+
+static void createTransMaskingData(bContext *C, TransInfo *t)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ Mask *mask = CTX_data_edit_mask(C);
+ MaskLayer *masklay;
+ TransData *td = NULL;
+ TransData2D *td2d = NULL;
+ TransDataMasking *tdm = NULL;
+ int count = 0, countsel = 0;
+ int propmode = t->flag & T_PROP_EDIT;
+
+ /* count */
+ for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
+ MaskSpline *spline = masklay->splines.first;
+
+ if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
+ continue;
+ }
+
+ for (spline = masklay->splines.first; spline; spline = spline->next) {
+ int i;
+
+ for (i = 0; i < spline->tot_point; i++) {
+ MaskSplinePoint *point = &spline->points[i];
+
+ if (MASKPOINT_ISSEL_ANY(point)) {
+ if (MASKPOINT_ISSEL_KNOT(point))
+ countsel += 3;
+ else
+ countsel += 1;
+ }
+
+ if (propmode)
+ count += 3;
+ }
+ }
+ }
+
+ /* note: in prop mode we need at least 1 selected */
+ if (countsel == 0) return;
+
+ t->total = (propmode) ? count: countsel;
+ td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransObData(Mask Editing)");
+ /* for each 2d uv coord a 3d vector is allocated, so that they can be
+ * treated just as if they were 3d verts */
+ td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransObData2D(Mask Editing)");
+ tdm = t->customData = MEM_callocN(t->total*sizeof(TransDataMasking), "TransDataMasking(Mask Editing)");
+
+ t->flag |= T_FREE_CUSTOMDATA;
+
+ /* create data */
+ for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
+ MaskSpline *spline = masklay->splines.first;
+
+ if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
+ continue;
+ }
+
+ for (spline = masklay->splines.first; spline; spline = spline->next) {
+ int i;
+
+ for (i = 0; i < spline->tot_point; i++) {
+ MaskSplinePoint *point = &spline->points[i];
+
+ if (propmode || MASKPOINT_ISSEL_ANY(point)) {
+ MaskPointToTransData(sc, point, td, td2d, tdm, propmode);
+
+ if (propmode || MASKPOINT_ISSEL_KNOT(point)) {
+ td += 3;
+ td2d += 3;
+ tdm += 3;
+ }
+ else {
+ td++;
+ td2d++;
+ tdm++;
+ }
+ }
+ }
+ }
+ }
+}
+
+void flushTransMasking(TransInfo *t)
+{
+ SpaceClip *sc = t->sa->spacedata.first;
+ TransData2D *td;
+ TransDataMasking *tdm;
+ int a;
+ float aspx, aspy, invx, invy;
+
+ ED_space_clip_mask_aspect(sc, &aspx, &aspy);
+ invx = 1.0f/aspx;
+ invy = 1.0f/aspy;
+
+ /* flush to 2d vector from internally used 3d vector */
+ for(a=0, td = t->data2d, tdm = t->customData; a<t->total; a++, td++, tdm++) {
+ td->loc2d[0]= td->loc[0]*invx;
+ td->loc2d[1]= td->loc[1]*invy;
+
+ if (tdm->is_handle)
+ BKE_mask_point_set_handle(tdm->point, td->loc2d, t->flag & T_ALT_TRANSFORM, tdm->orig_handle, tdm->vec);
+ }
+}
+
void createTransData(bContext *C, TransInfo *t)
{
Scene *scene = t->scene;
@@ -5892,6 +6113,15 @@ void createTransData(bContext *C, TransInfo *t)
t->flag |= T_POINTS|T_2D_EDIT;
if (t->options & CTX_MOVIECLIP)
createTransTrackingData(C, t);
+ else if (t->options & CTX_MASK) {
+ createTransMaskingData(C, t);
+
+ if (t->data && (t->flag & T_PROP_EDIT)) {
+ sort_trans_data(t); // makes selected become first in array
+ set_prop_dist(t, TRUE);
+ sort_trans_data_dist(t);
+ }
+ }
}
else if (t->obedit) {
t->ext = NULL;
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 0f742458ed3..3195fb0299d 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -49,6 +49,7 @@
#include "DNA_view3d_types.h"
#include "DNA_modifier_types.h"
#include "DNA_movieclip_types.h"
+#include "DNA_mask_types.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
@@ -638,33 +639,42 @@ static void recalcData_spaceclip(TransInfo *t)
{
SpaceClip *sc = t->sa->spacedata.first;
- MovieClip *clip = ED_space_clip(sc);
- ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking);
- MovieTrackingTrack *track;
-
- flushTransTracking(t);
-
- track = tracksbase->first;
- while (track) {
- if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) {
- if (t->mode == TFM_TRANSLATION) {
- if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT))
- BKE_tracking_clamp_track(track, CLAMP_PAT_POS);
- if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH))
- BKE_tracking_clamp_track(track, CLAMP_SEARCH_POS);
- }
- else if (t->mode == TFM_RESIZE) {
- if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT))
- BKE_tracking_clamp_track(track, CLAMP_PAT_DIM);
- if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH))
- BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM);
+ if (ED_space_clip_show_trackedit(sc)) {
+ MovieClip *clip = ED_space_clip(sc);
+ ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking);
+ MovieTrackingTrack *track;
+
+ flushTransTracking(t);
+
+ track = tracksbase->first;
+ while (track) {
+ if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) {
+ if (t->mode == TFM_TRANSLATION) {
+ if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT))
+ BKE_tracking_clamp_track(track, CLAMP_PAT_POS);
+ if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH))
+ BKE_tracking_clamp_track(track, CLAMP_SEARCH_POS);
+ }
+ else if (t->mode == TFM_RESIZE) {
+ if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT))
+ BKE_tracking_clamp_track(track, CLAMP_PAT_DIM);
+ if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH))
+ BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM);
+ }
}
+
+ track = track->next;
}
- track = track->next;
+ DAG_id_tag_update(&clip->id, 0);
}
+ else if (ED_space_clip_show_maskedit(sc)) {
+ Mask *mask = ED_space_clip_mask(sc);
- DAG_id_tag_update(&clip->id, 0);
+ flushTransMasking(t);
+
+ DAG_id_tag_update(&mask->id, 0);
+ }
}
/* helper for recalcData() - for 3d-view transforms */
@@ -1109,9 +1119,12 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
else if (t->spacetype==SPACE_CLIP) {
SpaceClip *sclip = sa->spacedata.first;
t->view = &ar->v2d;
+ t->around = sclip->around;
if (ED_space_clip_show_trackedit(sclip))
t->options |= CTX_MOVIECLIP;
+ else if (ED_space_clip_show_maskedit(sclip))
+ t->options |= CTX_MASK;
}
else {
if (ar) {
@@ -1174,6 +1187,15 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
t->flag |= T_PROP_CONNECTED;
}
}
+ else if (t->options & CTX_MASK) {
+ if (ts->proportional_mask) {
+ t->flag |= T_PROP_EDIT;
+
+ if (ts->proportional == PROP_EDIT_CONNECTED) {
+ t->flag |= T_PROP_CONNECTED;
+ }
+ }
+ }
else if (t->obedit == NULL && ts->proportional_objects) {
t->flag |= T_PROP_EDIT;
}
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 777fcc2af0c..b6fc4f58bd7 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -206,6 +206,7 @@ typedef struct PreviewImage {
#define ID_GD MAKE_ID2('G', 'D') /* GreasePencil */
#define ID_WM MAKE_ID2('W', 'M') /* WindowManager */
#define ID_MC MAKE_ID2('M', 'C') /* MovieClip */
+#define ID_MSK MAKE_ID2('M', 'S') /* Mask */
/* NOTE! Fake IDs, needed for g.sipo->blocktype or outliner */
#define ID_SEQ MAKE_ID2('S', 'Q')
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 198b6a9bf80..75b0b18879d 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -999,7 +999,8 @@ typedef struct ToolSettings {
short snap_flag, snap_target;
short proportional, prop_mode;
char proportional_objects; /* proportional edit, object mode */
- char pad[5];
+ char proportional_mask; /* proportional edit, object mode */
+ char pad[4];
char auto_normalize; /*auto normalizing mode in wpaint*/
char multipaint; /* paint multiple bones in wpaint */
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 8f3062655b7..e83f1b4495a 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -67,6 +67,7 @@ struct wmOperator;
struct wmTimer;
struct MovieClip;
struct MovieClipScopes;
+struct Mask;
/* SpaceLink (Base) ==================================== */
@@ -1006,7 +1007,14 @@ typedef struct SpaceClip {
short dope_sort; /* sort order in dopesheet view */
short dope_flag; /* dopsheet view flags */
- int pad3;
+ int around; /* pivot point for transforms */
+
+ /* **** mask editing **** */
+ struct Mask *mask;
+ /* draw options */
+ char mask_draw_flag;
+ char mask_draw_type;
+ char pad3[6];
} SpaceClip;
/* SpaceClip->flag */
@@ -1037,6 +1045,7 @@ typedef enum eSpaceClip_Mode {
SC_MODE_TRACKING = 0,
SC_MODE_RECONSTRUCTION,
SC_MODE_DISTORTION,
+ SC_MODE_MASKEDITING,
} eSpaceClip_Mode;
/* SpaceClip->view */
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index 0191847706a..b0f8f02ae9f 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -132,6 +132,7 @@ static const char *includefiles[] = {
"DNA_movieclip_types.h",
"DNA_tracking_types.h",
"DNA_dynamicpaint_types.h",
+ "DNA_mask_types.h",
// empty string to indicate end of includefiles
""
@@ -1241,4 +1242,5 @@ int main(int argc, char **argv)
#include "DNA_movieclip_types.h"
#include "DNA_tracking_types.h"
#include "DNA_dynamicpaint_types.h"
+#include "DNA_mask_types.h"
/* end of list */
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 821fcfb90e6..c9914a35a14 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -145,6 +145,7 @@ extern StructRNA RNA_CompositorNodeLumaMatte;
extern StructRNA RNA_CompositorNodeMapUV;
extern StructRNA RNA_CompositorNodeMapValue;
extern StructRNA RNA_CompositorNodeMath;
+extern StructRNA RNA_CompositorNodeMask;
extern StructRNA RNA_CompositorNodeMixRGB;
extern StructRNA RNA_CompositorNodeNormal;
extern StructRNA RNA_CompositorNodeNormalize;
@@ -304,6 +305,8 @@ extern StructRNA RNA_MaterialStrand;
extern StructRNA RNA_MaterialSubsurfaceScattering;
extern StructRNA RNA_MaterialTextureSlot;
extern StructRNA RNA_MaterialVolume;
+extern StructRNA RNA_Mask;
+extern StructRNA RNA_MaskLayer;
extern StructRNA RNA_Menu;
extern StructRNA RNA_Mesh;
extern StructRNA RNA_MeshColor;
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 0c136a9444a..e7f9977d040 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -55,6 +55,7 @@ set(DEFSRC
rna_lamp.c
rna_lattice.c
rna_main.c
+ rna_mask.c
rna_material.c
rna_mesh.c
rna_meta.c
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 9661a60f779..3741d53c378 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -2681,6 +2681,7 @@ static RNAProcessItem PROCESS_ITEMS[] = {
{"rna_world.c", NULL, RNA_def_world},
{"rna_movieclip.c", NULL, RNA_def_movieclip},
{"rna_tracking.c", NULL, RNA_def_tracking},
+ {"rna_mask.c", NULL, RNA_def_mask},
{NULL, NULL}
};
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 6a54c04b44d..7f851c939d2 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -147,6 +147,7 @@ short RNA_type_to_ID_code(StructRNA *type)
if (RNA_struct_is_a(type, &RNA_World)) return ID_WO;
if (RNA_struct_is_a(type, &RNA_WindowManager)) return ID_WM;
if (RNA_struct_is_a(type, &RNA_MovieClip)) return ID_MC;
+ if (RNA_struct_is_a(type, &RNA_Mask)) return ID_MSK;
return 0;
}
@@ -182,6 +183,7 @@ StructRNA *ID_code_to_RNA_type(short idcode)
case ID_WO: return &RNA_World;
case ID_WM: return &RNA_WindowManager;
case ID_MC: return &RNA_MovieClip;
+ case ID_MSK: return &RNA_Mask;
default: return &RNA_ID;
}
}
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index cb90211eff9..e8e40d307fb 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -179,6 +179,7 @@ void RNA_def_wm(struct BlenderRNA *brna);
void RNA_def_world(struct BlenderRNA *brna);
void RNA_def_movieclip(struct BlenderRNA *brna);
void RNA_def_tracking(struct BlenderRNA *brna);
+void RNA_def_mask(struct BlenderRNA *brna);
/* Common Define functions */
@@ -301,6 +302,7 @@ void RNA_def_main_actions(BlenderRNA *brna, PropertyRNA *cprop);
void RNA_def_main_particles(BlenderRNA *brna, PropertyRNA *cprop);
void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop);
void RNA_def_main_movieclips(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_masks(BlenderRNA *brna, PropertyRNA *cprop);
/* ID Properties */
diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c
index b0981c19835..6ac032e5d99 100644
--- a/source/blender/makesrna/intern/rna_main.c
+++ b/source/blender/makesrna/intern/rna_main.c
@@ -253,6 +253,12 @@ static void rna_Main_movieclips_begin(CollectionPropertyIterator *iter, PointerR
rna_iterator_listbase_begin(iter, &bmain->movieclip, NULL);
}
+static void rna_Main_masks_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ Main *bmain= (Main*)ptr->data;
+ rna_iterator_listbase_begin(iter, &bmain->mask, NULL);
+}
+
#ifdef UNIT_TEST
static PointerRNA rna_Test_test_get(PointerRNA *ptr)
@@ -316,6 +322,7 @@ void RNA_def_main(BlenderRNA *brna)
{"particles", "ParticleSettings", "rna_Main_particle_begin", "Particles", "Particle datablocks", RNA_def_main_particles},
{"grease_pencil", "GreasePencil", "rna_Main_gpencil_begin", "Grease Pencil", "Grease Pencil datablocks", RNA_def_main_gpencil},
{"movieclips", "MovieClip", "rna_Main_movieclips_begin", "Movie Clips", "Movie Clip datablocks", RNA_def_main_movieclips},
+ {"masks", "Mask", "rna_Main_masks_begin", "Masks", "Masks datablocks", RNA_def_main_masks},
{NULL, NULL, NULL, NULL, NULL, NULL}
};
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index 024265c3d18..98b3c0ab9f4 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -33,6 +33,8 @@
#include <stdio.h>
#include <errno.h>
+#include "DNA_ID.h"
+
#include "RNA_define.h"
#include "RNA_access.h"
#include "RNA_enum_types.h"
@@ -67,6 +69,7 @@
#include "BKE_depsgraph.h"
#include "BKE_speaker.h"
#include "BKE_movieclip.h"
+#include "BKE_mask.h"
#include "DNA_armature_types.h"
#include "DNA_camera_types.h"
@@ -87,6 +90,7 @@
#include "DNA_vfont_types.h"
#include "DNA_node_types.h"
#include "DNA_movieclip_types.h"
+#include "DNA_mask_types.h"
#include "ED_screen.h"
@@ -539,6 +543,22 @@ void rna_Main_movieclips_remove(Main *bmain, MovieClip *clip)
/* XXX python now has invalid pointer? */
}
+Mask *rna_Main_mask_new(Main *UNUSED(bmain), const char *name)
+{
+ Mask *mask;
+
+ mask = BKE_mask_new("Mask");
+
+ return mask;
+}
+
+void rna_Main_masks_remove(Main *bmain, Mask *mask)
+{
+ BKE_mask_unlink(bmain, mask);
+ BKE_libblock_free(&bmain->mask, mask);
+ /* XXX python now has invalid pointer? */
+}
+
/* tag functions, all the same */
void rna_Main_cameras_tag(Main *bmain, int value) { tag_main_lb(&bmain->camera, value); }
void rna_Main_scenes_tag(Main *bmain, int value) { tag_main_lb(&bmain->scene, value); }
@@ -569,6 +589,7 @@ void rna_Main_actions_tag(Main *bmain, int value) { tag_main_lb(&bmain->action,
void rna_Main_particles_tag(Main *bmain, int value) { tag_main_lb(&bmain->particle, value); }
void rna_Main_gpencil_tag(Main *bmain, int value) { tag_main_lb(&bmain->gpencil, value); }
void rna_Main_movieclips_tag(Main *bmain, int value) { tag_main_lb(&bmain->movieclip, value); }
+void rna_Main_masks_tag(Main *bmain, int value) { tag_main_lb(&bmain->mask, value); }
static int rna_Main_cameras_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_CA); }
static int rna_Main_scenes_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_SCE); }
@@ -1520,4 +1541,34 @@ void RNA_def_main_movieclips(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_function_return(func, parm);
}
+void RNA_def_main_masks(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "BlendDataMasks");
+ srna= RNA_def_struct(brna, "BlendDataMasks", NULL);
+ RNA_def_struct_sdna(srna, "Main");
+ RNA_def_struct_ui_text(srna, "Main Masks", "Collection of masks");
+
+ func= RNA_def_function(srna, "tag", "rna_Main_masks_tag");
+ parm= RNA_def_boolean(func, "value", 0, "Value", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ /* new func */
+ func = RNA_def_function(srna, "new", "rna_Main_mask_new");
+ RNA_def_function_ui_description(func, "Add a new mask with a given name to the main database");
+ parm = RNA_def_string_file_path(func, "name", "", MAX_ID_NAME - 2, "Mask", "Name of new mask datablock");
+ /* return type */
+ parm = RNA_def_pointer(func, "mask", "Mask", "", "New mask datablock");
+ RNA_def_function_return(func, parm);
+
+ /* remove func */
+ func= RNA_def_function(srna, "remove", "rna_Main_masks_remove");
+ RNA_def_function_ui_description(func, "Remove a masks from the current blendfile.");
+ parm= RNA_def_pointer(func, "mask", "Mask", "", "Mask to remove");
+ RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
+}
+
#endif
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 466a9b80c50..30c705fb7fa 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -3030,6 +3030,18 @@ static void def_cmp_moviedistortion(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
+static void def_cmp_mask(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "mask", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "id");
+ RNA_def_property_struct_type(prop, "Mask");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Mask", "");
+}
+
+
static void dev_cmd_transform(StructRNA *srna)
{
PropertyRNA *prop;
diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h
index 351c6d93514..d5b33f0d01b 100644
--- a/source/blender/makesrna/intern/rna_nodetree_types.h
+++ b/source/blender/makesrna/intern/rna_nodetree_types.h
@@ -165,6 +165,7 @@ DefNode( CompositorNode, CMP_NODE_MASK_ELLIPSE, def_cmp_ellipsemask, "ELLIP
DefNode( CompositorNode, CMP_NODE_BOKEHIMAGE, def_cmp_bokehimage, "BOKEHIMAGE" ,BokehImage, "Bokeh image", "" )
DefNode( CompositorNode, CMP_NODE_SWITCH, def_cmp_switch, "SWITCH" ,Switch, "Switch", "" )
DefNode( CompositorNode, CMP_NODE_COLORCORRECTION,def_cmp_colorcorrection,"COLORCORRECTION",ColorCorrection, "ColorCorrection", "" )
+DefNode( CompositorNode, CMP_NODE_MASK, def_cmp_mask, "MASK", Mask, "Mask", "" )
DefNode( TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" )
DefNode( TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" )
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 25f2bd7132c..9eb313204f7 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1565,6 +1565,12 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_ui_icon(prop, ICON_PROP_OFF, 1);
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
+ prop = RNA_def_property(srna, "use_proportional_edit_mask", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "proportional_mask", 0);
+ RNA_def_property_ui_text(prop, "Proportional Editing Objects", "Proportional editing mask mode");
+ RNA_def_property_ui_icon(prop, ICON_PROP_OFF, 1);
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
+
prop = RNA_def_property(srna, "proportional_edit_falloff", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "prop_mode");
RNA_def_property_enum_items(prop, proportional_falloff_items);
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 9b4dcd03c79..8fe33f3e80f 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -45,6 +45,7 @@
#include "DNA_object_types.h"
#include "DNA_space_types.h"
#include "DNA_sequence_types.h"
+#include "DNA_mask_types.h"
#include "DNA_view3d_types.h"
#include "WM_api.h"
@@ -120,6 +121,7 @@ EnumPropertyItem viewport_shade_items[] = {
#ifdef RNA_RUNTIME
#include "DNA_anim_types.h"
+#include "DNA_mask_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -1037,6 +1039,13 @@ static void rna_SpaceClipEditor_clip_set(PointerRNA *ptr, PointerRNA value)
ED_space_clip_set(NULL, screen, sc, (MovieClip *)value.data);
}
+static void rna_SpaceClipEditor_mask_set(PointerRNA *ptr, PointerRNA value)
+{
+ SpaceClip *sc= (SpaceClip*)(ptr->data);
+
+ ED_space_clip_set_mask(NULL, sc, (Mask*)value.data);
+}
+
static void rna_SpaceClipEditor_clip_mode_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
SpaceClip *sc = (SpaceClip *)(ptr->data);
@@ -1060,6 +1069,14 @@ static void rna_SpaceClipEditor_view_type_update(Main *UNUSED(bmain), Scene *UNU
#else
+static EnumPropertyItem dt_uv_items[] = {
+ {SI_UVDT_OUTLINE, "OUTLINE", 0, "Outline", "Draw white edges with black outline"},
+ {SI_UVDT_DASH, "DASH", 0, "Dash", "Draw dashed black-white edges"},
+ {SI_UVDT_BLACK, "BLACK", 0, "Black", "Draw black edges"},
+ {SI_UVDT_WHITE, "WHITE", 0, "White", "Draw white edges"},
+ {0, NULL, 0, NULL, NULL}
+};
+
static void rna_def_space(BlenderRNA *brna)
{
StructRNA *srna;
@@ -1091,14 +1108,6 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
- static EnumPropertyItem dt_uv_items[] = {
- {SI_UVDT_OUTLINE, "OUTLINE", 0, "Outline", "Draw white edges with black outline"},
- {SI_UVDT_DASH, "DASH", 0, "Dash", "Draw dashed black-white edges"},
- {SI_UVDT_BLACK, "BLACK", 0, "Black", "Draw black edges"},
- {SI_UVDT_WHITE, "WHITE", 0, "White", "Draw white edges"},
- {0, NULL, 0, NULL, NULL}
- };
-
static EnumPropertyItem dt_uvstretch_items[] = {
{SI_UVDT_STRETCH_ANGLE, "ANGLE", 0, "Angle", "Angular distortion between UV and 3D angles"},
{SI_UVDT_STRETCH_AREA, "AREA", 0, "Area", "Area distortion between UV and 3D faces"},
@@ -2974,6 +2983,7 @@ static void rna_def_space_clip(BlenderRNA *brna)
{SC_MODE_RECONSTRUCTION, "RECONSTRUCTION", ICON_SNAP_FACE, "Reconstruction",
"Show tracking/reconstruction tools"},
{SC_MODE_DISTORTION, "DISTORTION", ICON_GRID, "Distortion", "Show distortion tools"},
+ {SC_MODE_MASKEDITING, "MASKEDITING", ICON_MOD_MASK, "Mask editing", "Show mask editing tools"},
{0, NULL, 0, NULL, NULL}
};
@@ -2991,6 +3001,16 @@ static void rna_def_space_clip(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem pivot_items[] = {
+ {V3D_CENTER, "BOUNDING_BOX_CENTER", ICON_ROTATE, "Bounding Box Center",
+ "Pivot around bounding box center of selected object(s)"},
+ {V3D_LOCAL, "INDIVIDUAL_ORIGINS", ICON_ROTATECOLLECTION,
+ "Individual Origins", "Pivot around each object's own origin"},
+ {V3D_CENTROID, "MEDIAN_POINT", ICON_ROTATECENTER, "Median Point",
+ "Pivot around the median point of selected objects"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
srna = RNA_def_struct(brna, "SpaceClipEditor", "Space");
RNA_def_struct_sdna(srna, "SpaceClip");
RNA_def_struct_ui_text(srna, "Space Clip Editor", "Clip editor space data");
@@ -3011,6 +3031,26 @@ static void rna_def_space_clip(BlenderRNA *brna)
"Parameters defining which frame of the movie clip is displayed");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL);
+ /* mask */
+ prop= RNA_def_property(srna, "mask", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Mask", "Mask displayed and edited in this space");
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceClipEditor_mask_set", NULL, NULL);
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+ /* mask drawing */
+ prop = RNA_def_property(srna, "mask_draw_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "mask_draw_type");
+ RNA_def_property_enum_items(prop, dt_uv_items);
+ RNA_def_property_ui_text(prop, "Edge Draw Type", "Draw type for mask splines");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+ prop = RNA_def_property(srna, "show_mask_smooth", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mask_draw_flag", MASK_DRAWFLAG_SMOOTH);
+ RNA_def_property_ui_text(prop, "Draw Smooth Splines", "");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+
/* mode */
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mode");
@@ -3170,6 +3210,13 @@ static void rna_def_space_clip(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames");
RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
+ /* pivot point */
+ prop = RNA_def_property(srna, "pivot_point", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "around");
+ RNA_def_property_enum_items(prop, pivot_items);
+ RNA_def_property_ui_text(prop, "Pivot Point", "Pivot center for rotation/scaling");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL);
+
/* ** dopesheet ** */
/* dopesheet sort */
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 6bae6cdd473..c637e3606f1 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -82,6 +82,7 @@ set(SRC
composite/nodes/node_composite_mapUV.c
composite/nodes/node_composite_mapValue.c
composite/nodes/node_composite_math.c
+ composite/nodes/node_composite_mask.c
composite/nodes/node_composite_mixrgb.c
composite/nodes/node_composite_movieclip.c
composite/nodes/node_composite_moviedistortion.c
diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h
index ca925c82afd..f850ea91f12 100644
--- a/source/blender/nodes/NOD_composite.h
+++ b/source/blender/nodes/NOD_composite.h
@@ -50,6 +50,7 @@ void register_node_type_cmp_value(struct bNodeTreeType *ttype);
void register_node_type_cmp_rgb(struct bNodeTreeType *ttype);
void register_node_type_cmp_curve_time(struct bNodeTreeType *ttype);
void register_node_type_cmp_movieclip(struct bNodeTreeType *ttype);
+void register_node_type_cmp_usermask(struct bNodeTreeType *ttype);
void register_node_type_cmp_composite(struct bNodeTreeType *ttype);
void register_node_type_cmp_viewer(struct bNodeTreeType *ttype);
@@ -115,6 +116,7 @@ void register_node_type_cmp_mapuv(struct bNodeTreeType *ttype);
void register_node_type_cmp_transform(struct bNodeTreeType *ttype);
void register_node_type_cmp_stabilize2d(struct bNodeTreeType *ttype);
void register_node_type_cmp_moviedistortion(struct bNodeTreeType *ttype);
+void register_node_type_cmp_mask(struct bNodeTreeType *ttype);
void register_node_type_cmp_glare(struct bNodeTreeType *ttype);
void register_node_type_cmp_tonemap(struct bNodeTreeType *ttype);
diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c
index 8f8f702e8ae..457322929b0 100644
--- a/source/blender/nodes/composite/node_composite_tree.c
+++ b/source/blender/nodes/composite/node_composite_tree.c
@@ -890,6 +890,10 @@ int ntreeCompositTagAnimated(bNodeTree *ntree)
nodeUpdate(ntree, node);
tagged= 1;
}
+ else if (node->type==CMP_NODE_MASK) {
+ nodeUpdate(ntree, node);
+ tagged= 1;
+ }
}
return tagged;
diff --git a/source/blender/nodes/composite/node_composite_util.c b/source/blender/nodes/composite/node_composite_util.c
index 3806cf4543a..ff223ac83cf 100644
--- a/source/blender/nodes/composite/node_composite_util.c
+++ b/source/blender/nodes/composite/node_composite_util.c
@@ -568,6 +568,22 @@ CompBuf *valbuf_from_rgbabuf(CompBuf *cbuf, int channel)
return valbuf;
}
+void valbuf_to_rgbabuf(CompBuf *valbuf, CompBuf *cbuf, int channel)
+{
+ float *valf, *rectf;
+ int tot;
+
+ valf= valbuf->rect;
+
+ /* defaults to returning alpha channel */
+ if ((channel < CHAN_R) || (channel > CHAN_A)) channel = CHAN_A;
+
+ rectf = cbuf->rect + channel;
+
+ for (tot= cbuf->x*cbuf->y; tot>0; tot--, valf++, rectf+=4)
+ *rectf = *valf;
+}
+
static CompBuf *generate_procedural_preview(CompBuf *cbuf, int newx, int newy)
{
CompBuf *outbuf;
diff --git a/source/blender/nodes/composite/node_composite_util.h b/source/blender/nodes/composite/node_composite_util.h
index 8f42a9bbe47..cab60caaae7 100644
--- a/source/blender/nodes/composite/node_composite_util.h
+++ b/source/blender/nodes/composite/node_composite_util.h
@@ -157,6 +157,7 @@ void composit4_pixel_processor(bNode *node, CompBuf *out, CompBuf *src1_buf, flo
int src1_type, int fac1_type, int src2_type, int fac2_type);
CompBuf *valbuf_from_rgbabuf(CompBuf *cbuf, int channel);
+void valbuf_to_rgbabuf(CompBuf *valbuf, CompBuf *cbuf, int channel);
void generate_preview(void *data, bNode *node, CompBuf *stackbuf);
void do_copy_rgba(bNode *node, float *out, float *in);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 7cbeab6a02e..25abc171057 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -167,6 +167,7 @@ typedef struct wmNotifier {
#define NC_ID (18<<24)
#define NC_LOGIC (19<<24)
#define NC_MOVIECLIP (20<<24)
+#define NC_MASK (21<<24)
/* data type, 256 entries is enough, it can overlap */
#define NOTE_DATA 0x00FF0000
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 42787be8e02..d7d55885f37 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -3853,6 +3853,7 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_assign(keymap, "VIEW3D_OT_select_circle");
WM_modalkeymap_assign(keymap, "UV_OT_circle_select");
WM_modalkeymap_assign(keymap, "CLIP_OT_select_circle");
+ WM_modalkeymap_assign(keymap, "MASK_OT_select_circle");
}
@@ -3936,6 +3937,7 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_assign(keymap, "UV_OT_select_border");
WM_modalkeymap_assign(keymap, "CLIP_OT_select_border");
WM_modalkeymap_assign(keymap, "CLIP_OT_graph_select_border");
+ WM_modalkeymap_assign(keymap, "MASK_OT_select_border");
WM_modalkeymap_assign(keymap, "VIEW2D_OT_zoom_border");
WM_modalkeymap_assign(keymap, "VIEW3D_OT_clip_border");
WM_modalkeymap_assign(keymap, "VIEW3D_OT_render_border");
diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt
index 674d5540c8b..9fb0c103f1d 100644
--- a/source/blenderplayer/CMakeLists.txt
+++ b/source/blenderplayer/CMakeLists.txt
@@ -152,6 +152,7 @@ endif()
bf_blenkernel # duplicate for linking
bf_intern_mikktspace
extern_recastnavigation
+ bf_intern_raskter
)
if(WITH_MOD_CLOTH_ELTOPO)
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 86567873256..4c45099808c 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -228,6 +228,7 @@ void ED_space_image_uv_sculpt_update(struct wmWindowManager *wm, struct ToolSett
void ED_screen_set_scene(struct bContext *C, struct Scene *scene) {}
void ED_space_clip_set(struct bContext *C, struct SpaceClip *sc, struct MovieClip *clip) {}
+void ED_space_clip_set_mask(struct bContext *C, struct SpaceClip *sc, struct Mask *mask){}
void ED_area_tag_redraw_regiontype(struct ScrArea *sa, int regiontype) {}
void ED_render_engine_changed(struct Main *bmain) {}
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index 74ccda8ce0e..ac52acc3043 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -823,6 +823,7 @@ endif()
bf_editor_sound
bf_editor_animation
bf_editor_datafiles
+ bf_editor_mask
bf_render
bf_intern_opennl
@@ -894,6 +895,7 @@ endif()
cycles_subd
bf_compositor #added for opencl compositor
bf_opencl #added for opencl compositor
+ bf_intern_raskter
)
if(WITH_LIBMV)