From 6350a3454ce6fb7a6bb36331fc3f3d867c0ece6a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 16 Sep 2011 14:47:32 +0000 Subject: [PATCH] Camera tracking integration =========================== Implemented "Movie Distort" and "Movie Undistort" nodes which uses camera undistortion coefficients. Not perfect for footages shoted on cameras with pixel aspect != 1: there's extra scaling down and scaling up caused by others areas supposing frame aspect x be 1 and multiplying height by 1.0/pixel_aspect. Not so critical but would be nice to solve. --- source/blender/blenkernel/BKE_node.h | 2 + source/blender/blenkernel/intern/node.c | 2 + source/blender/blenkernel/intern/tracking.c | 10 +- source/blender/editors/space_node/drawnode.c | 17 +++ source/blender/makesrna/intern/rna_nodetree.c | 24 ++++ .../makesrna/intern/rna_nodetree_types.h | 2 + source/blender/makesrna/intern/rna_tracking.c | 8 +- source/blender/nodes/CMakeLists.txt | 2 + source/blender/nodes/NOD_composite.h | 2 + .../nodes/node_composite_moviedistort.c | 117 ++++++++++++++++++ .../nodes/node_composite_movieundistort.c | 117 ++++++++++++++++++ .../nodes/node_composite_stabilize2d.c | 2 +- .../nodes/node_composite_transform.c | 2 +- 13 files changed, 297 insertions(+), 10 deletions(-) create mode 100644 source/blender/nodes/composite/nodes/node_composite_moviedistort.c create mode 100644 source/blender/nodes/composite/nodes/node_composite_movieundistort.c diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index aebf9bee74d..60005b396c1 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -567,6 +567,8 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat); #define CMP_NODE_MOVIECLIP 262 #define CMP_NODE_STABILIZE2D 263 #define CMP_NODE_TRANSFORM 264 +#define CMP_NODE_MOVIEUNDISTORT 265 +#define CMP_NODE_MOVIEDISTORT 266 #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 f6509bfe454..d9969b61d5f 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1849,6 +1849,8 @@ static void registerCompositNodes(ListBase *ntypelist) register_node_type_cmp_lensdist(ntypelist); register_node_type_cmp_transform(ntypelist); register_node_type_cmp_stabilize2d(ntypelist); + register_node_type_cmp_moviedistort(ntypelist); + register_node_type_cmp_movieundistort(ntypelist); } static void registerShaderNodes(ListBase *ntypelist) diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 68f69650fb0..704a5e1f18f 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1894,19 +1894,20 @@ ImBuf *BKE_tracking_undistort(MovieTracking *tracking, ImBuf *ibuf) { ImBuf *resibuf; MovieTrackingCamera *camera= &tracking->camera; + float aspy= 1.f/tracking->camera.pixel_aspect; resibuf= IMB_dupImBuf(ibuf); if(ibuf->rect_float) { libmv_undistortFloat(camera->focal, - camera->principal[0], camera->principal[1], + camera->principal[0], camera->principal[1] * aspy, camera->k1, camera->k2, camera->k3, ibuf->rect_float, resibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels); ibuf->userflags|= IB_RECT_INVALID; } else { libmv_undistortByte(camera->focal, - camera->principal[0], camera->principal[1], + camera->principal[0], camera->principal[1] * aspy, camera->k1, camera->k2, camera->k3, (unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect, ibuf->x, ibuf->y, ibuf->channels); } @@ -1918,19 +1919,20 @@ ImBuf *BKE_tracking_distort(MovieTracking *tracking, ImBuf *ibuf) { ImBuf *resibuf; MovieTrackingCamera *camera= &tracking->camera; + float aspy= 1.f/tracking->camera.pixel_aspect; resibuf= IMB_dupImBuf(ibuf); if(ibuf->rect_float) { libmv_distortFloat(camera->focal, - camera->principal[0], camera->principal[1], + camera->principal[0], camera->principal[1] * aspy, camera->k1, camera->k2, camera->k3, ibuf->rect_float, resibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels); ibuf->userflags|= IB_RECT_INVALID; } else { libmv_distortByte(camera->focal, - camera->principal[0], camera->principal[1], + camera->principal[0], camera->principal[1] * aspy, camera->k1, camera->k2, camera->k3, (unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect, ibuf->x, ibuf->y, ibuf->channels); } diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 662386b589e..74e1327d7cb 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1695,6 +1695,17 @@ static void node_composit_buts_transform(uiLayout *layout, bContext *UNUSED(C), uiItemR(layout, ptr, "filter_type", 0, "", 0); } +static void node_composit_buts_movieundistort(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL); + +} + +static void node_composit_buts_moviedistort(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL); +} + /* only once called */ static void node_composit_set_butfunc(bNodeType *ntype) { @@ -1854,6 +1865,12 @@ static void node_composit_set_butfunc(bNodeType *ntype) case CMP_NODE_TRANSFORM: ntype->uifunc= node_composit_buts_transform; break; + case CMP_NODE_MOVIEUNDISTORT: + ntype->uifunc= node_composit_buts_movieundistort; + break; + case CMP_NODE_MOVIEDISTORT: + ntype->uifunc= node_composit_buts_moviedistort; + break; default: ntype->uifunc= NULL; } diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index e77d378bc9d..e053000dec2 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -2445,6 +2445,30 @@ static void def_cmp_stabilize2d(StructRNA *srna) RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); } +static void def_cmp_movieundistort(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"); +} + +static void def_cmp_moviedistort(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"); +} + 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 fc5b8dbce90..d4b0bc66516 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -122,6 +122,8 @@ DefNode( CompositorNode, CMP_NODE_HUECORRECT, def_cmp_huecorrect, "HUECO 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, "Stabelize 2D", "" ) +DefNode( CompositorNode, CMP_NODE_MOVIEDISTORT, def_cmp_moviedistort, "MOVIEDISTORT", MovieDistort, "Movie Distort", "" ) +DefNode( CompositorNode, CMP_NODE_MOVIEUNDISTORT, def_cmp_movieundistort, "MOVIEUNDISTORT", MovieUndistort, "Movie Undistort", "" ) 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_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 84664935b76..433b84d8a37 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -376,19 +376,19 @@ static void rna_def_trackingCamera(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "k1"); RNA_def_property_ui_range(prop, -10, 10, .1, 3); RNA_def_property_ui_text(prop, "K1", ""); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_flushUpdate"); prop= RNA_def_property(srna, "k2", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "k2"); RNA_def_property_ui_range(prop, -10, 10, .1, 3); RNA_def_property_ui_text(prop, "K2", ""); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_flushUpdate"); prop= RNA_def_property(srna, "k3", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "k3"); RNA_def_property_ui_range(prop, -10, 10, .1, 3); RNA_def_property_ui_text(prop, "K3", ""); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_flushUpdate"); /* pixel aspect */ prop= RNA_def_property(srna, "pixel_aspect", PROP_FLOAT, PROP_XYZ); @@ -396,7 +396,7 @@ static void rna_def_trackingCamera(BlenderRNA *brna) RNA_def_property_range(prop, 0.1f, 5000.0f); RNA_def_property_ui_range(prop, 0.1f, 5000.0f, 1, 2); RNA_def_property_ui_text(prop, "Pixel Aspect", "Pixel aspect ratio"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); } static void rna_def_trackingMarker(BlenderRNA *brna) diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 29c523572b2..199a43131d7 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -81,6 +81,8 @@ set(SRC composite/nodes/node_composite_math.c composite/nodes/node_composite_mixrgb.c composite/nodes/node_composite_movieclip.c + composite/nodes/node_composite_moviedistort.c + composite/nodes/node_composite_movieundistort.c composite/nodes/node_composite_normal.c composite/nodes/node_composite_normalize.c composite/nodes/node_composite_outputFile.c diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h index 5d2fc458f32..fce9a18c0ad 100644 --- a/source/blender/nodes/NOD_composite.h +++ b/source/blender/nodes/NOD_composite.h @@ -118,6 +118,8 @@ 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_moviedistort(ListBase *lb); +void register_node_type_cmp_movieundistort(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/nodes/node_composite_moviedistort.c b/source/blender/nodes/composite/nodes/node_composite_moviedistort.c new file mode 100644 index 00000000000..a56a27f5844 --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_moviedistort.c @@ -0,0 +1,117 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2006 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_moviedistort.c + * \ingroup cmpnodes + */ + + +#include "node_composite_util.h" + +/* **************** Translate ******************** */ + +static bNodeSocketTemplate cmp_node_moviedistort_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate cmp_node_moviedistort_out[]= { + { SOCK_RGBA, 0, "Image"}, + { -1, 0, "" } +}; + +static void node_composit_exec_moviedistort(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) +{ + if(in[0]->data && 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; + MovieClipUser *user= (MovieClipUser *)node->storage; + float aspy= 1.f/clip->tracking.camera.pixel_aspect; + int scaled= 0, width, height; + + ibuf->rect_float= cbuf->rect; + + BKE_movieclip_acquire_size(clip, user, &width, &height); + height*= aspy; + + if(ibuf->x!=width || ibuf->y!=height) { + /* TODO: not sure this is really needed, but distortion coefficients are + calculated using camera resolution, so if image with other resolution + is passed to distortion node, it'll be distorted correct (but quality can hurt) + This is also needed to deal when camera pixel aspect isn't 1. Problems in this case + are caused because of how aspect x/y are calculating. Currently. projeciton + matrices and reconstruction stuff are supposing that aspect x is always 1 and + aspect y is less than 1 (if x resolution is larger than y resolution) */ + + IMB_scaleImBuf(ibuf, width, height); + scaled= 1; + } + + obuf= BKE_tracking_distort(&clip->tracking, ibuf); + + if(scaled) + IMB_scaleImBuf(obuf, cbuf->x, cbuf->y); + + 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); + } +} + +void register_node_type_cmp_moviedistort(ListBase *lb) +{ + static bNodeType ntype; + + node_type_base(&ntype, CMP_NODE_MOVIEDISTORT, "Movie Distort", NODE_CLASS_DISTORT, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_moviedistort_in, cmp_node_moviedistort_out); + node_type_size(&ntype, 140, 100, 320); + node_type_exec(&ntype, node_composit_exec_moviedistort); + + nodeRegisterType(lb, &ntype); +} diff --git a/source/blender/nodes/composite/nodes/node_composite_movieundistort.c b/source/blender/nodes/composite/nodes/node_composite_movieundistort.c new file mode 100644 index 00000000000..58902334c59 --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_movieundistort.c @@ -0,0 +1,117 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2006 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_movieundistort.c + * \ingroup cmpnodes + */ + + +#include "node_composite_util.h" + +/* **************** Translate ******************** */ + +static bNodeSocketTemplate cmp_node_movieundistort_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate cmp_node_movieundistort_out[]= { + { SOCK_RGBA, 0, "Image"}, + { -1, 0, "" } +}; + +static void node_composit_exec_movieundistort(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) +{ + if(in[0]->data && 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; + MovieClipUser *user= (MovieClipUser *)node->storage; + float aspy= 1.f/clip->tracking.camera.pixel_aspect; + int scaled= 0, width, height; + + ibuf->rect_float= cbuf->rect; + + BKE_movieclip_acquire_size(clip, user, &width, &height); + height*= aspy; + + if(ibuf->x!=width || ibuf->y!=height) { + /* TODO: not sure this is really needed, but distortion coefficients are + calculated using camera resolution, so if image with other resolution + is passed to undistortion node, it'll be undistorted correct (but quality can hurt) + This is also needed to deal when camera pixel aspect isn't 1. Problems in this case + are caused because of how aspect x/y are calculating. Currently. projeciton + matrices and reconstruction stuff are supposing that aspect x is always 1 and + aspect y is less than 1 (if x resolution is larger than y resolution) */ + + IMB_scaleImBuf(ibuf, width, height); + scaled= 1; + } + + obuf= BKE_tracking_undistort(&clip->tracking, ibuf); + + if(scaled) + IMB_scaleImBuf(obuf, cbuf->x, cbuf->y); + + 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); + } +} + +void register_node_type_cmp_movieundistort(ListBase *lb) +{ + static bNodeType ntype; + + node_type_base(&ntype, CMP_NODE_MOVIEUNDISTORT, "Movie Undistort", NODE_CLASS_DISTORT, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_movieundistort_in, cmp_node_movieundistort_out); + node_type_size(&ntype, 140, 100, 320); + node_type_exec(&ntype, node_composit_exec_movieundistort); + + nodeRegisterType(lb, &ntype); +} diff --git a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c index eafdf3286ad..a0c3a2399fb 100644 --- a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c +++ b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c @@ -28,7 +28,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_translate.c +/** \file blender/nodes/composite/nodes/node_composite_stabilize2d.c * \ingroup cmpnodes */ diff --git a/source/blender/nodes/composite/nodes/node_composite_transform.c b/source/blender/nodes/composite/nodes/node_composite_transform.c index 9ee9cf84cc1..15cee6014a3 100644 --- a/source/blender/nodes/composite/nodes/node_composite_transform.c +++ b/source/blender/nodes/composite/nodes/node_composite_transform.c @@ -28,7 +28,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_translate.c +/** \file blender/nodes/composite/nodes/node_composite_transform.c * \ingroup cmpnodes */ -- 2.28.0