diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2011-11-07 16:56:05 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2011-11-07 16:56:05 +0400 |
commit | 7b43abb90e2895292e183fcbca7140447025acd7 (patch) | |
tree | 145b1c4a94598cd0810ab999e49bdd5a331367cd /source | |
parent | 27d42c63d9b507b1771ed5a7923c389c719b877b (diff) |
Camera tracking integration
===========================
Rest of changes from camera tracking gsoc project.
This commit includes:
- New compositor nodes:
* Movie Clip input node
* Movie Undistortion node
* Transformation node
* 2D stabilization node
- Slight changes in existing node to prevent code duplication
Diffstat (limited to 'source')
18 files changed, 769 insertions, 24 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 7509205e968..278e57125c5 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -567,6 +567,10 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat); #define CMP_NODE_COLOR_MATTE 259 #define CMP_NODE_COLORBALANCE 260 #define CMP_NODE_HUECORRECT 261 +#define CMP_NODE_MOVIECLIP 262 +#define CMP_NODE_STABILIZE2D 263 +#define CMP_NODE_TRANSFORM 264 +#define CMP_NODE_MOVIEDISTORTION 265 #define CMP_NODE_GLARE 301 #define CMP_NODE_TONEMAP 302 diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index a9b2ffe7529..115591863cc 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1790,6 +1790,7 @@ static void registerCompositNodes(ListBase *ntypelist) register_node_type_cmp_value(ntypelist); register_node_type_cmp_rgb(ntypelist); register_node_type_cmp_curve_time(ntypelist); + register_node_type_cmp_movieclip(ntypelist); register_node_type_cmp_composite(ntypelist); register_node_type_cmp_viewer(ntypelist); @@ -1854,6 +1855,9 @@ static void registerCompositNodes(ListBase *ntypelist) register_node_type_cmp_glare(ntypelist); register_node_type_cmp_tonemap(ntypelist); register_node_type_cmp_lensdist(ntypelist); + register_node_type_cmp_transform(ntypelist); + register_node_type_cmp_stabilize2d(ntypelist); + register_node_type_cmp_moviedistortion(ntypelist); } static void registerShaderNodes(ListBase *ntypelist) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ce7ff489465..9f6ce4eb79b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1254,6 +1254,7 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain) void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain) { MovieClip *clip= oldmain->movieclip.first; + Scene *sce= oldmain->scene.first; fd->movieclipmap= oldnewmap_new(); @@ -1264,6 +1265,15 @@ void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain) if(clip->tracking.camera.intrinsics) oldnewmap_insert(fd->movieclipmap, clip->tracking.camera.intrinsics, clip->tracking.camera.intrinsics, 0); } + + for(; sce; sce= sce->id.next) { + if(sce->nodetree) { + bNode *node; + for(node= sce->nodetree->nodes.first; node; node= node->next) + if(node->type==CMP_NODE_MOVIEDISTORTION) + oldnewmap_insert(fd->movieclipmap, node->storage, node->storage, 0); + } + } } /* set old main movie clips caches to zero if it has been restored */ @@ -1272,6 +1282,7 @@ void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain) { OldNew *entry= fd->movieclipmap->entries; MovieClip *clip= oldmain->movieclip.first; + Scene *sce= oldmain->scene.first; int i; /* used entries were restored, so we put them to zero */ @@ -1284,6 +1295,15 @@ void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain) clip->cache= newmclipadr(fd, clip->cache); clip->tracking.camera.intrinsics= newmclipadr(fd, clip->tracking.camera.intrinsics); } + + for(; sce; sce= sce->id.next) { + if(sce->nodetree) { + bNode *node; + for(node= sce->nodetree->nodes.first; node; node= node->next) + if(node->type==CMP_NODE_MOVIEDISTORTION) + node->storage= newmclipadr(fd, node->storage); + } + } } @@ -2273,7 +2293,11 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) link_list(fd, &node->inputs); link_list(fd, &node->outputs); - node->storage= newdataadr(fd, node->storage); + if(node->type == CMP_NODE_MOVIEDISTORTION) { + node->storage= newmclipadr(fd, node->storage); + } else + node->storage= newdataadr(fd, node->storage); + if(node->storage) { /* could be handlerized at some point */ if(ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB)) diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index f49148342ec..021aa6a8a92 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -711,6 +711,8 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree) write_curvemapping(wd, node->storage); else if(ntree->type==NTREE_TEXTURE && (node->type==TEX_NODE_CURVE_RGB || node->type==TEX_NODE_CURVE_TIME) ) write_curvemapping(wd, node->storage); + else if(ntree->type==NTREE_COMPOSIT && node->type==CMP_NODE_MOVIEDISTORTION) + /* pass */ ; else writestruct(wd, DATA, node->typeinfo->storagename, 1, node->storage); } diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 24ea51567ad..b4d89e1365d 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1679,6 +1679,40 @@ static void node_composit_buts_ycc(uiLayout *layout, bContext *UNUSED(C), Pointe uiItemR(layout, ptr, "mode", 0, "", ICON_NONE); } +static void node_composit_buts_movieclip(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL); +} + +static void node_composit_buts_stabilize2d(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + bNode *node= ptr->data; + + uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL); + + if(!node->id) + return; + + uiItemR(layout, ptr, "filter_type", 0, "", 0); +} + +static void node_composit_buts_transform(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "filter_type", 0, "", 0); +} + +static void node_composit_buts_moviedistortion(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + bNode *node= ptr->data; + + uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL); + + if(!node->id) + return; + + uiItemR(layout, ptr, "distortion_type", 0, "", 0); +} + /* only once called */ static void node_composit_set_butfunc(bNodeType *ntype) { @@ -1829,6 +1863,20 @@ static void node_composit_set_butfunc(bNodeType *ntype) case CMP_NODE_SEPYCCA: ntype->uifunc=node_composit_buts_ycc; break; + case CMP_NODE_MOVIECLIP: + ntype->uifunc= node_composit_buts_movieclip; + break; + case CMP_NODE_STABILIZE2D: + ntype->uifunc= node_composit_buts_stabilize2d; + break; + case CMP_NODE_TRANSFORM: + ntype->uifunc= node_composit_buts_transform; + break; + case CMP_NODE_MOVIEDISTORTION: + ntype->uifunc= node_composit_buts_moviedistortion; + break; + default: + ntype->uifunc= NULL; } if (ntype->uifuncbut == NULL) ntype->uifuncbut = ntype->uifunc; diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index c1e50c112fa..745611c6251 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -2207,8 +2207,14 @@ bNode *node_add_node(SpaceNode *snode, Main *bmain, Scene *scene, bNodeTemplate ED_node_set_active(bmain, snode->edittree, node); if(snode->nodetree->type==NTREE_COMPOSIT) { - if(ELEM4(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS, CMP_NODE_OUTPUT_FILE)) + if(ELEM4(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS, CMP_NODE_OUTPUT_FILE)) { node->id = &scene->id; + } + else if(ELEM3(node->type, CMP_NODE_MOVIECLIP, CMP_NODE_MOVIEDISTORTION, CMP_NODE_STABILIZE2D)) { + if(G.main->movieclip.first == G.main->movieclip.last) { + node->id= G.main->movieclip.first; + } + } ntreeCompositForceHidden(snode->edittree, scene); } diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 1445cf3b537..f024ad3addd 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -2414,6 +2414,84 @@ static void def_cmp_ycc(StructRNA *srna) RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); } +static void def_cmp_movieclip(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "id"); + RNA_def_property_struct_type(prop, "MovieClip"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Movie Clip", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + + RNA_def_struct_sdna_from(srna, "MovieClipUser", "storage"); +} + +static void def_cmp_stabilize2d(StructRNA *srna) +{ + PropertyRNA *prop; + + static EnumPropertyItem filter_type_items[] = { + {0, "NEAREST", 0, "Nearest", ""}, + {1, "BILINEAR", 0, "Bilinear", ""}, + {2, "BICUBIC", 0, "Bicubic", ""}, + {0, NULL, 0, NULL, NULL}}; + + prop = RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "id"); + RNA_def_property_struct_type(prop, "MovieClip"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Movie Clip", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "filter_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, filter_type_items); + RNA_def_property_ui_text(prop, "Filter", "Method to use to filter stabilization"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); +} + +static void def_cmp_moviedistortion(StructRNA *srna) +{ + PropertyRNA *prop; + + static EnumPropertyItem distortion_type_items[] = { + {0, "UNDISTORT", 0, "Undistort", ""}, + {1, "DISTORT", 0, "Distort", ""}, + {0, NULL, 0, NULL, NULL}}; + + prop = RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "id"); + RNA_def_property_struct_type(prop, "MovieClip"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Movie Clip", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "distortion_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, distortion_type_items); + RNA_def_property_ui_text(prop, "Distortion", "Distortion to use to filter image"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); +} + +static void dev_cmd_transform(StructRNA *srna) +{ + PropertyRNA *prop; + + static EnumPropertyItem filter_type_items[] = { + {0, "NEAREST", 0, "Nearest", ""}, + {1, "BILINEAR", 0, "Bilinear", ""}, + {2, "BICUBIC", 0, "Bicubic", ""}, + {0, NULL, 0, NULL, NULL}}; + + prop = RNA_def_property(srna, "filter_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, filter_type_items); + RNA_def_property_ui_text(prop, "Filter", "Method to use to filter transform"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); +} + /* -- Texture Nodes --------------------------------------------------------- */ diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h index 1bbf47db094..2545826cd46 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -117,6 +117,10 @@ DefNode( CompositorNode, CMP_NODE_COLOR_MATTE, def_cmp_color_matte, "COLOR DefNode( CompositorNode, CMP_NODE_DIST_MATTE, def_cmp_distance_matte, "DISTANCE_MATTE", DistanceMatte, "Distance Matte", "" ) DefNode( CompositorNode, CMP_NODE_COLORBALANCE, def_cmp_colorbalance, "COLORBALANCE", ColorBalance, "Color Balance", "" ) DefNode( CompositorNode, CMP_NODE_HUECORRECT, def_cmp_huecorrect, "HUECORRECT", HueCorrect, "Hue Correct", "" ) +DefNode( CompositorNode, CMP_NODE_MOVIECLIP, def_cmp_movieclip, "MOVIECLIP", MovieClip, "MovieClip", "" ) +DefNode( CompositorNode, CMP_NODE_TRANSFORM, dev_cmd_transform, "TRANSFORM", Transform, "Transform", "" ) +DefNode( CompositorNode, CMP_NODE_STABILIZE2D, def_cmp_stabilize2d, "STABILIZE2D", Stabilize, "Stabilize 2D", "" ) +DefNode( CompositorNode, CMP_NODE_MOVIEDISTORTION,def_cmp_moviedistortion,"MOVIEDISTORTION",MovieDistortion, "Movie Distortion", "" ) 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/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 82848c6a5d7..69e7f9cac6b 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -80,6 +80,8 @@ set(SRC composite/nodes/node_composite_mapValue.c composite/nodes/node_composite_math.c composite/nodes/node_composite_mixrgb.c + composite/nodes/node_composite_movieclip.c + composite/nodes/node_composite_moviedistortion.c composite/nodes/node_composite_normal.c composite/nodes/node_composite_normalize.c composite/nodes/node_composite_outputFile.c @@ -93,8 +95,10 @@ set(SRC composite/nodes/node_composite_sepcombYUVA.c composite/nodes/node_composite_setalpha.c composite/nodes/node_composite_splitViewer.c + composite/nodes/node_composite_stabilize2d.c composite/nodes/node_composite_texture.c composite/nodes/node_composite_tonemap.c + composite/nodes/node_composite_transform.c composite/nodes/node_composite_translate.c composite/nodes/node_composite_valToRgb.c composite/nodes/node_composite_value.c diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h index d768a5d794f..f1415a8c8f0 100644 --- a/source/blender/nodes/NOD_composite.h +++ b/source/blender/nodes/NOD_composite.h @@ -52,6 +52,7 @@ void register_node_type_cmp_texture(ListBase *lb); void register_node_type_cmp_value(ListBase *lb); void register_node_type_cmp_rgb(ListBase *lb); void register_node_type_cmp_curve_time(ListBase *lb); +void register_node_type_cmp_movieclip(ListBase *lb); void register_node_type_cmp_composite(ListBase *lb); void register_node_type_cmp_viewer(ListBase *lb); @@ -113,6 +114,9 @@ void register_node_type_cmp_flip(ListBase *lb); void register_node_type_cmp_crop(ListBase *lb); void register_node_type_cmp_displace(ListBase *lb); void register_node_type_cmp_mapuv(ListBase *lb); +void register_node_type_cmp_transform(ListBase *lb); +void register_node_type_cmp_stabilize2d(ListBase *lb); +void register_node_type_cmp_moviedistortion(ListBase *lb); void register_node_type_cmp_glare(ListBase *lb); void register_node_type_cmp_tonemap(ListBase *lb); diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index 2151176f907..d3f4a5b2999 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -45,6 +45,7 @@ #include "BKE_global.h" #include "BKE_main.h" #include "BKE_node.h" +#include "BKE_tracking.h" #include "BKE_utildefines.h" #include "node_exec.h" @@ -168,6 +169,17 @@ static void local_merge(bNodeTree *localtree, bNodeTree *ntree) BKE_image_merge((Image *)lnode->new_node->id, (Image *)lnode->id); } } + else if(lnode->type==CMP_NODE_MOVIEDISTORTION) { + /* special case for distortion node: distortion context is allocating in exec function + and to achive much better performance on further calls this context should be + copied back to original node */ + if(lnode->storage) { + if(lnode->new_node->storage) + BKE_tracking_distortion_destroy(lnode->new_node->storage); + + lnode->new_node->storage= BKE_tracking_distortion_copy(lnode->storage); + } + } for(lsock= lnode->outputs.first; lsock; lsock= lsock->next) { if(ntreeOutputExists(lnode->new_node, lsock->new_sock)) { @@ -806,6 +818,10 @@ int ntreeCompositTagAnimated(bNodeTree *ntree) nodeUpdate(ntree, node); } } + else if(ELEM(node->type, CMP_NODE_MOVIECLIP, CMP_NODE_TRANSFORM)) { + nodeUpdate(ntree, node); + tagged= 1; + } } return tagged; diff --git a/source/blender/nodes/composite/node_composite_util.h b/source/blender/nodes/composite/node_composite_util.h index 6da9b901e76..9cac4c477eb 100644 --- a/source/blender/nodes/composite/node_composite_util.h +++ b/source/blender/nodes/composite/node_composite_util.h @@ -44,6 +44,7 @@ #include "DNA_ID.h" #include "DNA_image_types.h" #include "DNA_material_types.h" +#include "DNA_movieclip_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -63,8 +64,10 @@ #include "BKE_image.h" #include "BKE_main.h" #include "BKE_material.h" +#include "BKE_movieclip.h" #include "BKE_node.h" #include "BKE_texture.h" +#include "BKE_tracking.h" #include "BKE_library.h" #include "BKE_object.h" @@ -210,4 +213,11 @@ CompBuf* qd_downScaledCopy(CompBuf* src, int scale); void IIR_gauss(CompBuf* src, float sigma, int chan, int xy); /* end utility funcs */ +/* transformations */ + +#define CMP_SCALE_MAX 12000 + +CompBuf* node_composit_transform(CompBuf *cbuf, float x, float y, float angle, float scale, int filter_type); +float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc); + #endif diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c index c1e9d28bb4d..41427c42286 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.c +++ b/source/blender/nodes/composite/nodes/node_composite_image.c @@ -58,6 +58,36 @@ static bNodeSocketTemplate cmp_node_rlayers_out[]= { { -1, 0, "" } }; +/* float buffer from the image with matching color management */ +float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc) +{ + float *rect; + + *alloc= FALSE; + + if(rd->color_mgt_flag & R_COLOR_MANAGEMENT) { + if(ibuf->profile != IB_PROFILE_NONE) { + rect= ibuf->rect_float; + } + else { + rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image"); + srgb_to_linearrgb_rgba_rgba_buf(rect, ibuf->rect_float, ibuf->x * ibuf->y); + *alloc= TRUE; + } + } + else { + if(ibuf->profile == IB_PROFILE_NONE) { + rect= ibuf->rect_float; + } + else { + rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image"); + linearrgb_to_srgb_rgba_rgba_buf(rect, ibuf->rect_float, ibuf->x * ibuf->y); + *alloc= TRUE; + } + } + + return rect; +} /* note: this function is used for multilayer too, to ensure uniform handling with BKE_image_get_ibuf() */ @@ -82,26 +112,7 @@ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i /* now we need a float buffer from the image with matching color management */ /* XXX weak code, multilayer is excluded from this */ if(ibuf->channels == 4 && ima->rr==NULL) { - if(rd->color_mgt_flag & R_COLOR_MANAGEMENT) { - if(ibuf->profile != IB_PROFILE_NONE) { - rect= ibuf->rect_float; - } - else { - rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image"); - srgb_to_linearrgb_rgba_rgba_buf(rect, ibuf->rect_float, ibuf->x * ibuf->y); - alloc= TRUE; - } - } - else { - if(ibuf->profile == IB_PROFILE_NONE) { - rect= ibuf->rect_float; - } - else { - rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image"); - linearrgb_to_srgb_rgba_rgba_buf(rect, ibuf->rect_float, ibuf->x * ibuf->y); - alloc= TRUE; - } - } + rect= node_composit_get_float_buffer(rd, ibuf, &alloc); } else { /* non-rgba passes can't use color profiles */ diff --git a/source/blender/nodes/composite/nodes/node_composite_movieclip.c b/source/blender/nodes/composite/nodes/node_composite_movieclip.c new file mode 100644 index 00000000000..8931b899017 --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_movieclip.c @@ -0,0 +1,157 @@ +/* + * ***** 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) 2011 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/nodes/node_composite_movieclip.c + * \ingroup cmpnodes + */ + + +#include "node_composite_util.h" + +static bNodeSocketTemplate cmp_node_movieclip_out[]= { + { SOCK_RGBA, 0, "Image"}, + { SOCK_FLOAT, 1, "Offset X"}, + { SOCK_FLOAT, 1, "Offset Y"}, + { SOCK_FLOAT, 1, "Scale"}, + { SOCK_FLOAT, 1, "Angle"}, + { -1, 0, "" } +}; + +static CompBuf *node_composit_get_movieclip(RenderData *rd, MovieClip *clip, MovieClipUser *user) +{ + ImBuf *ibuf; + CompBuf *stackbuf; + int type; + + float *rect; + int alloc= FALSE; + + ibuf= BKE_movieclip_get_ibuf(clip, user); + + if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) { + IMB_freeImBuf(ibuf); + return NULL; + } + + if (ibuf->rect_float == NULL || ibuf->userflags&IB_RECT_INVALID) { + IMB_float_from_rect(ibuf); + ibuf->userflags&= ~IB_RECT_INVALID; + } + + /* now we need a float buffer from the image with matching color management */ + if(ibuf->channels == 4) { + rect= node_composit_get_float_buffer(rd, ibuf, &alloc); + } + else { + /* non-rgba passes can't use color profiles */ + rect= ibuf->rect_float; + } + /* done coercing into the correct color management */ + + if(!alloc) { + rect= MEM_dupallocN(rect); + alloc= 1; + } + + type= ibuf->channels; + + if(rd->scemode & R_COMP_CROP) { + stackbuf= get_cropped_compbuf(&rd->disprect, rect, ibuf->x, ibuf->y, type); + if(alloc) + MEM_freeN(rect); + } + else { + /* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */ + stackbuf= alloc_compbuf(ibuf->x, ibuf->y, type, FALSE); + stackbuf->rect= rect; + stackbuf->malloc= alloc; + } + + IMB_freeImBuf(ibuf); + + return stackbuf; +} + +static void node_composit_exec_movieclip(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out) +{ + if(node->id) { + RenderData *rd= data; + MovieClip *clip= (MovieClip *)node->id; + MovieClipUser *user= (MovieClipUser *)node->storage; + CompBuf *stackbuf= NULL; + + BKE_movieclip_user_set_frame(user, rd->cfra); + + stackbuf= node_composit_get_movieclip(rd, clip, user); + + if (stackbuf) { + MovieTrackingStabilization *stab= &clip->tracking.stabilization; + + /* put image on stack */ + out[0]->data= stackbuf; + + if(stab->flag&TRACKING_2D_STABILIZATION) { + float loc[2], scale, angle; + + BKE_tracking_stabilization_data(&clip->tracking, rd->cfra, stackbuf->x, stackbuf->y, + loc, &scale, &angle); + + out[1]->vec[0]= loc[0]; + out[2]->vec[0]= loc[1]; + + out[3]->vec[0]= scale; + out[4]->vec[0]= angle; + } + + /* generate preview */ + generate_preview(data, node, stackbuf); + } + } +} + +static void init(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp)) +{ + MovieClipUser *user= MEM_callocN(sizeof(MovieClipUser), "node movie clip user"); + + node->storage= user; + user->framenr= 1; +} + +void register_node_type_cmp_movieclip(ListBase *lb) +{ + static bNodeType ntype; + + node_type_base(&ntype, CMP_NODE_MOVIECLIP, "Movie Clip", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, cmp_node_movieclip_out); + node_type_size(&ntype, 120, 80, 300); + node_type_init(&ntype, init); + node_type_storage(&ntype, "MovieClipUser", node_free_standard_storage, node_copy_standard_storage); + node_type_exec(&ntype, node_composit_exec_movieclip); + + nodeRegisterType(lb, &ntype); +} diff --git a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c new file mode 100644 index 00000000000..439616377a1 --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c @@ -0,0 +1,135 @@ +/* + * ***** 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) 2011 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/nodes/node_composite_moviedistortion.c + * \ingroup cmpnodes + */ + + +#include "node_composite_util.h" + +/* **************** Translate ******************** */ + +static bNodeSocketTemplate cmp_node_moviedistortion_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate cmp_node_moviedistortion_out[]= { + { SOCK_RGBA, 0, "Image"}, + { -1, 0, "" } +}; + +static void exec(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) +{ + if(in[0]->data) { + if(node->id) { + MovieClip *clip= (MovieClip *)node->id; + CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA); + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 0); + ImBuf *ibuf; + + ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0); + + if(ibuf) { + ImBuf *obuf; + MovieTracking *tracking= &clip->tracking; + int width, height; + float overscan= 0.0f; + + ibuf->rect_float= cbuf->rect; + + BKE_movieclip_get_size(clip, NULL, &width, &height); + + if(!node->storage) + node->storage= BKE_tracking_distortion_create(); + + if(node->custom1==0) + obuf= BKE_tracking_distortion_exec(node->storage, tracking, ibuf, width, height, overscan, 1); + else + obuf= BKE_tracking_distortion_exec(node->storage, tracking, ibuf, width, height, overscan, 0); + + stackbuf->rect= obuf->rect_float; + stackbuf->malloc= 1; + + obuf->mall&= ~IB_rectfloat; + obuf->rect_float= NULL; + + IMB_freeImBuf(ibuf); + IMB_freeImBuf(obuf); + } + + /* pass on output and free */ + out[0]->data= stackbuf; + + if(cbuf!=in[0]->data) + free_compbuf(cbuf); + } else { + CompBuf *cbuf= in[0]->data; + CompBuf *stackbuf= pass_on_compbuf(cbuf); + + out[0]->data= stackbuf; + } + } +} + +static const char *label(bNode *node) +{ + if(node->custom1==0) + return "Undistortion"; + else + return "Distortion"; +} + +static void storage_free(bNode *node) +{ + if(node->storage) + BKE_tracking_distortion_destroy(node->storage); + + node->storage= NULL; +} + +void storage_copy(bNode *orig_node, bNode *new_node) +{ + if(orig_node->storage) + new_node->storage= BKE_tracking_distortion_copy(orig_node->storage); +} + +void register_node_type_cmp_moviedistortion(ListBase *lb) +{ + static bNodeType ntype; + + node_type_base(&ntype, CMP_NODE_MOVIEDISTORTION, "Movie Distortion", NODE_CLASS_DISTORT, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_moviedistortion_in, cmp_node_moviedistortion_out); + node_type_size(&ntype, 140, 100, 320); + node_type_label(&ntype, label); + node_type_exec(&ntype, exec); + node_type_storage(&ntype, NULL, storage_free, storage_copy); + + nodeRegisterType(lb, &ntype); +} diff --git a/source/blender/nodes/composite/nodes/node_composite_scale.c b/source/blender/nodes/composite/nodes/node_composite_scale.c index 5eb789ae0c9..37332c9bd7e 100644 --- a/source/blender/nodes/composite/nodes/node_composite_scale.c +++ b/source/blender/nodes/composite/nodes/node_composite_scale.c @@ -34,8 +34,6 @@ /* **************** Scale ******************** */ -#define CMP_SCALE_MAX 12000 - static bNodeSocketTemplate cmp_node_scale_in[]= { { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { SOCK_FLOAT, 1, "X", 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, CMP_SCALE_MAX, PROP_FACTOR}, @@ -110,6 +108,25 @@ static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, b if(cbuf!=in[0]->data) free_compbuf(cbuf); } + else if (node->custom1==CMP_SCALE_ABSOLUTE) { + CompBuf *stackbuf; + int a, x, y; + float *fp; + + x = MAX2((int)in[1]->vec[0], 1); + y = MAX2((int)in[2]->vec[0], 1); + + stackbuf = alloc_compbuf(x, y, CB_RGBA, 1); + fp = stackbuf->rect; + + a = stackbuf->x * stackbuf->y; + while(a--) { + copy_v4_v4(fp, in[0]->vec); + fp += 4; + } + + out[0]->data= stackbuf; + } } void register_node_type_cmp_scale(ListBase *lb) diff --git a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c new file mode 100644 index 00000000000..c5d60e65530 --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c @@ -0,0 +1,79 @@ +/* + * ***** 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) 2011 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/nodes/node_composite_stabilize2d.c + * \ingroup cmpnodes + */ + + +#include "node_composite_util.h" + +/* **************** Translate ******************** */ + +static bNodeSocketTemplate cmp_node_stabilize2d_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate cmp_node_stabilize2d_out[]= { + { SOCK_RGBA, 0, "Image"}, + { -1, 0, "" } +}; + +static void node_composit_exec_stabilize2d(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + if(in[0]->data && node->id) { + RenderData *rd= data; + MovieClip *clip= (MovieClip *)node->id; + CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA); + CompBuf *stackbuf; + float loc[2], scale, angle; + + BKE_tracking_stabilization_data(&clip->tracking, rd->cfra, cbuf->x, cbuf->y, loc, &scale, &angle); + + stackbuf= node_composit_transform(cbuf, loc[0], loc[1], angle, scale, node->custom1); + + /* pass on output and free */ + out[0]->data= stackbuf; + + if(cbuf!=in[0]->data) + free_compbuf(cbuf); + } +} + +void register_node_type_cmp_stabilize2d(ListBase *lb) +{ + static bNodeType ntype; + + node_type_base(&ntype, CMP_NODE_STABILIZE2D, "Stabilize 2D", NODE_CLASS_DISTORT, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_stabilize2d_in, cmp_node_stabilize2d_out); + node_type_size(&ntype, 140, 100, 320); + node_type_exec(&ntype, node_composit_exec_stabilize2d); + + nodeRegisterType(lb, &ntype); +} diff --git a/source/blender/nodes/composite/nodes/node_composite_transform.c b/source/blender/nodes/composite/nodes/node_composite_transform.c new file mode 100644 index 00000000000..de9b8fceaee --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_transform.c @@ -0,0 +1,142 @@ +/* + * ***** 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) 2011 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/nodes/node_composite_transform.c + * \ingroup cmpnodes + */ + +#include "node_composite_util.h" + +/* **************** Transform ******************** */ + +static bNodeSocketTemplate cmp_node_transform_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 1, "X", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + { SOCK_FLOAT, 1, "Y", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + { SOCK_FLOAT, 1, "Angle", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f, PROP_ANGLE}, + { SOCK_FLOAT, 1, "Scale", 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, CMP_SCALE_MAX}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate cmp_node_transform_out[]= { + { SOCK_RGBA, 0, "Image"}, + { -1, 0, "" } +}; + +CompBuf* node_composit_transform(CompBuf *cbuf, float x, float y, float angle, float scale, int filter_type) +{ + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); + ImBuf *ibuf, *obuf; + float mat[4][4], lmat[4][4], rmat[4][4], smat[4][4], cmat[4][4], icmat[4][4]; + float svec[3]= {scale, scale, scale}, loc[2]= {x, y}; + + unit_m4(rmat); + unit_m4(lmat); + unit_m4(smat); + unit_m4(cmat); + + /* image center as rotation center */ + cmat[3][0]= (float)cbuf->x/2.0f; + cmat[3][1]= (float)cbuf->y/2.0f; + invert_m4_m4(icmat, cmat); + + size_to_mat4(smat, svec); /* scale matrix */ + add_v2_v2(lmat[3], loc); /* tranlation matrix */ + rotate_m4(rmat, 'Z', angle); /* rotation matrix */ + + /* compose transformation matrix */ + mul_serie_m4(mat, lmat, cmat, rmat, smat, icmat, NULL, NULL, NULL); + + invert_m4(mat); + + ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0); + obuf= IMB_allocImBuf(stackbuf->x, stackbuf->y, 32, 0); + + if(ibuf && obuf) { + int i, j; + + ibuf->rect_float= cbuf->rect; + obuf->rect_float= stackbuf->rect; + + for(j=0; j<cbuf->y; j++) { + for(i=0; i<cbuf->x;i++) { + float vec[3]= {i, j, 0}; + + mul_v3_m4v3(vec, mat, vec); + + switch(filter_type) { + case 0: + neareast_interpolation(ibuf, obuf, vec[0], vec[1], i, j); + break ; + case 1: + bilinear_interpolation(ibuf, obuf, vec[0], vec[1], i, j); + break; + case 2: + bicubic_interpolation(ibuf, obuf, vec[0], vec[1], i, j); + break; + } + } + } + + IMB_freeImBuf(ibuf); + IMB_freeImBuf(obuf); + } + + /* pass on output and free */ + return stackbuf; +} + +static void node_composit_exec_transform(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) +{ + if(in[0]->data) { + CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA); + CompBuf *stackbuf; + + stackbuf= node_composit_transform(cbuf, in[1]->vec[0], in[2]->vec[0], in[3]->vec[0], in[4]->vec[0], node->custom1); + + /* pass on output and free */ + out[0]->data= stackbuf; + + if(cbuf!=in[0]->data) + free_compbuf(cbuf); + } +} + +void register_node_type_cmp_transform(ListBase *lb) +{ + static bNodeType ntype; + + node_type_base(&ntype, CMP_NODE_TRANSFORM, "Transform", NODE_CLASS_DISTORT, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_transform_in, cmp_node_transform_out); + node_type_size(&ntype, 140, 100, 320); + node_type_exec(&ntype, node_composit_exec_transform); + + nodeRegisterType(lb, &ntype); +} + + |