Merging r47740 through r47782 from trunk into soc-2011-tomato
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 12 Jun 2012 11:41:06 +0000 (11:41 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 12 Jun 2012 11:41:06 +0000 (11:41 +0000)
77 files changed:
CMakeLists.txt
doc/python_api/sphinx_doc_gen.sh
extern/libmv/libmv-capi.cpp
extern/libmv/libmv-capi.h
extern/libmv/libmv/tracking/track_region.cc
extern/libmv/libmv/tracking/track_region.h
extern/libmv/third_party/ceres/internal/ceres/collections_port.h
extern/libmv/third_party/ceres/patches/collections_port.h.mingw.patch [new file with mode: 0644]
intern/cycles/blender/blender_shader.cpp
release/scripts/startup/bl_ui/properties_object_constraint.py
release/scripts/startup/bl_ui/space_clip.py
release/scripts/startup/bl_ui/space_userpref.py
release/scripts/templates/operator_node.py
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/BKE_tracking.h
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/tracking.c
source/blender/compositor/COM_defines.h
source/blender/compositor/intern/COM_CompositorContext.cpp
source/blender/compositor/intern/COM_CompositorContext.h
source/blender/compositor/intern/COM_ExecutionGroup.cpp
source/blender/compositor/intern/COM_ExecutionSystem.cpp
source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp
source/blender/compositor/intern/COM_ExecutionSystemHelper.h
source/blender/compositor/intern/COM_Node.cpp
source/blender/compositor/intern/COM_Node.h
source/blender/compositor/intern/COM_NodeOperation.h
source/blender/compositor/intern/COM_OutputSocket.cpp
source/blender/compositor/nodes/COM_GroupNode.cpp
source/blender/compositor/nodes/COM_MuteNode.cpp
source/blender/compositor/nodes/COM_SplitViewerNode.cpp
source/blender/compositor/nodes/COM_ViewerNode.cpp
source/blender/compositor/operations/COM_BokehBlurOperation.cpp
source/blender/compositor/operations/COM_BokehImageOperation.cpp
source/blender/compositor/operations/COM_CompositorOperation.cpp
source/blender/compositor/operations/COM_PreviewOperation.h
source/blender/compositor/operations/COM_ReadBufferOperation.cpp
source/blender/compositor/operations/COM_ReadBufferOperation.h
source/blender/compositor/operations/COM_RotateOperation.cpp
source/blender/compositor/operations/COM_RotateOperation.h
source/blender/compositor/operations/COM_SetVectorOperation.cpp
source/blender/compositor/operations/COM_SocketProxyOperation.cpp
source/blender/compositor/operations/COM_TranslateOperation.cpp
source/blender/compositor/operations/COM_TranslateOperation.h
source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp
source/blender/compositor/operations/COM_WriteBufferOperation.cpp
source/blender/compositor/operations/COM_WriteBufferOperation.h
source/blender/editors/include/ED_clip.h
source/blender/editors/interface/interface_draw.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/mask/mask_ops.c
source/blender/editors/space_clip/clip_draw.c
source/blender/editors/space_clip/clip_editor.c
source/blender/editors/space_clip/space_clip.c
source/blender/editors/space_node/node_edit.c
source/blender/editors/space_node/node_intern.h
source/blender/editors/space_node/node_ops.c
source/blender/editors/space_node/space_node.c
source/blender/gpu/GPU_draw.h
source/blender/gpu/intern/gpu_draw.c
source/blender/imbuf/intern/divers.c
source/blender/imbuf/intern/jp2.c
source/blender/makesdna/DNA_constraint_types.h
source/blender/makesdna/DNA_movieclip_types.h
source/blender/makesdna/DNA_tracking_types.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/intern/rna_constraint.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_tracking.c
source/blender/makesrna/intern/rna_userdef.c
source/blender/nodes/intern/node_common.c
source/blender/nodes/intern/node_common.h
source/blender/python/mathutils/mathutils_Vector.c
source/blender/windowmanager/intern/wm_init_exit.c

index 191fb61e1b4f593c21f3197f6895ce3aeb6a39dd..5b70110947be116620b116c620a3840baf1c6201 100644 (file)
@@ -1605,6 +1605,20 @@ if(CMAKE_COMPILER_IS_GNUCC)
                ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_ERROR_UNUSED_BUT_SET_VARIABLE -Wno-error=unused-but-set-variable)
        endif()
 
+elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+
+       ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ALL -Wall)
+       ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_AUTOLOGICAL_COMPARE -Wno-tautological-compare)
+       ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
+       ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
+
+       ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS C_WARN_ALL -Wall)
+       ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_AUTOLOGICAL_COMPARE -Wno-tautological-compare)
+       ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
+       ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
+       ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_OVERLOADED_VIRTUAL -Wno-overloaded-virtual)  # we get a lot of these, if its a problem a dev needs to look into it.
+       ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
+
 elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
 
        ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ALL -Wall)
index ccb293d7a0e287de42d12a5ba5fd34d7c6b99f4a..924619619204b7eafff675c46a670e4e9c052fd8 100755 (executable)
@@ -61,7 +61,7 @@ if $DO_OUT_HTML ; then
 
        # annoying bug in sphinx makes it very slow unless we do this. should report.
        cd $SPHINXBASE
-       sphinx-build -n -b html sphinx-in sphinx-out
+       sphinx-build -b html sphinx-in sphinx-out
 
        # XXX, saves space on upload and zip, should move HTML outside
        # and zip up there, for now this is OK
index 8751e1e190b5595b0ba6a72b390fa1e54e2f6193..3d3b7398c9bc23aedf766ee168c63b22dc11820c 100644 (file)
@@ -243,7 +243,7 @@ void savePNGImage(png_bytep *row_pointers, int width, int height, int depth, int
        fclose(fp);
 }
 
-static void saveImage(char *prefix, libmv::FloatImage image, int x0, int y0)
+static void saveImage(const char *prefix, libmv::FloatImage image, int x0, int y0)
 {
        int x, y;
        png_bytep *row_pointers;
@@ -283,7 +283,7 @@ static void saveImage(char *prefix, libmv::FloatImage image, int x0, int y0)
        free(row_pointers);
 }
 
-static void saveBytesImage(char *prefix, unsigned char *data, int width, int height)
+static void saveBytesImage(const char *prefix, unsigned char *data, int width, int height)
 {
        int x, y;
        png_bytep *row_pointers;
@@ -376,6 +376,8 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options,
        }
 
        libmv::TrackRegionOptions track_region_options;
+       libmv::FloatImage image1_mask;
+
        switch (options->motion_model) {
 #define LIBMV_CONVERT(the_model) \
     case libmv::TrackRegionOptions::the_model: \
@@ -398,6 +400,12 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options,
        track_region_options.use_brute_initialization = options->use_brute;
        track_region_options.use_normalized_intensities = options->use_normalization;
 
+       if (options->image1_mask) {
+               floatBufToImage(options->image1_mask, image1_width, image1_height, 1, &image1_mask);
+
+               track_region_options.image1_mask = &image1_mask;
+       }
+
        /* Convert from raw float buffers to libmv's FloatImage. */
        libmv::FloatImage old_patch, new_patch;
        floatBufToImage(image1, image1_width, image1_height, 1, &old_patch);
@@ -437,15 +445,24 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options,
 
 void libmv_samplePlanarPatch(const float *image, int width, int height,
                              int channels, const double *xs, const double *ys,
-                             int num_samples_x, int num_samples_y, float *patch,
+                             int num_samples_x, int num_samples_y,
+                             const float *mask, float *patch,
                              double *warped_position_x, double *warped_position_y)
 {
-       libmv::FloatImage libmv_image, libmv_patch;
+       libmv::FloatImage libmv_image, libmv_patch, libmv_mask;
+       libmv::FloatImage *libmv_mask_for_sample = NULL;
 
        floatBufToImage(image, width, height, channels, &libmv_image);
 
+       if (mask) {
+               floatBufToImage(mask, width, height, 1, &libmv_mask);
+
+               libmv_mask_for_sample = &libmv_mask;
+       }
+
        libmv::SamplePlanarPatch(libmv_image, xs, ys, num_samples_x, num_samples_y,
-                                &libmv_patch, warped_position_x, warped_position_y);
+                                libmv_mask_for_sample, &libmv_patch,
+                                warped_position_x, warped_position_y);
 
        imageToFloatBuf(&libmv_patch, channels, patch);
 }
index fe759b06fe436b5043e25d628153eb6e372ede64..fc3b6f94f62de582332ee3c2fe49707930c59809 100644 (file)
@@ -52,18 +52,21 @@ void libmv_regionTrackerDestroy(struct libmv_RegionTracker *libmv_tracker);
 
 /* TrackRegion (new planar tracker) */
 struct libmv_trackRegionOptions {
-  int motion_model;
-  int num_iterations;
-  int use_brute;
-  int use_normalization;
-  double minimum_correlation;
-  double sigma;
+       int motion_model;
+       int num_iterations;
+       int use_brute;
+       int use_normalization;
+       double minimum_correlation;
+       double sigma;
+       float *image1_mask;
 };
+
 struct libmv_trackRegionResult {
-  int termination;
-  const char *termination_reason;
-  double correlation;
+       int termination;
+       const char *termination_reason;
+       double correlation;
 };
+
 int libmv_trackRegion(const struct libmv_trackRegionOptions *options,
                       const float *image1, int image1_width, int image1_height,
                       const float *image2, int image2_width, int image2_height,
@@ -73,7 +76,8 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options,
 
 void libmv_samplePlanarPatch(const float *image, int width, int height,
                              int channels, const double *xs, const double *ys,
-                             int num_samples_x, int num_samples_y, float *patch,
+                             int num_samples_x, int num_samples_y,
+                             const float *mask, float *patch,
                              double *warped_position_x, double *warped_position_y);
 
 /* Tracks */
index e65ead50c80bac0140feeb71f170bd6fd6918030..f52919b2a616a5debfa876bd4be1b70dded5d5cf 100644 (file)
@@ -1351,7 +1351,7 @@ void TrackRegion(const FloatImage &image1,
 bool SamplePlanarPatch(const FloatImage &image,
                        const double *xs, const double *ys,
                        int num_samples_x, int num_samples_y,
-                       FloatImage *patch,
+                       FloatImage *mask, FloatImage *patch,
                        double *warped_position_x, double *warped_position_y) {
   // Bail early if the points are outside the image.
   if (!AllInBounds(image, xs, ys)) {
@@ -1376,6 +1376,13 @@ bool SamplePlanarPatch(const FloatImage &image,
       SampleLinear(image, image_position(1),
                    image_position(0),
                    &(*patch)(r, c, 0));
+      if (mask) {
+        float maskValue = SampleLinear(*mask, image_position(1),
+                                       image_position(0), 0);
+
+        for (int d = 0; d < image.Depth(); d++)
+          (*patch)(r, c, d) *= maskValue;
+      }
     }
   }
 
index 0de11239da69b382d8b081a5326d9753e7c35262..22ecfc54a15ba9de1293711d60e7eedf761df2b7 100644 (file)
@@ -135,10 +135,14 @@ void TrackRegion(const FloatImage &image1,
 // pixels of border around them. (so e.g. a corner of the patch cannot lie
 // directly on the edge of the image). Four corners are always required. All
 // channels are interpolated.
+// When mask is not null it'll be used as a pattern mask. Ot should match
+// the size of image.
+// Warped coordinates of marker's position would be returned in
+// warped_position_x and warped_position_y
 bool SamplePlanarPatch(const FloatImage &image,
                        const double *xs, const double *ys,
                        int num_samples_x, int num_samples_y,
-                       FloatImage *patch,
+                       FloatImage *mask, FloatImage *patch,
                        double *warped_position_x, double *warped_position_y);
 
 }  // namespace libmv
index e125f3fffcd2fb0f3be17e6ed94649f80bcdb42b..55f725390237726d0e9ed8f32c3c872796d34543 100644 (file)
@@ -53,7 +53,7 @@ struct HashMap : tr1::unordered_map<K, V> {};
 template<typename K>
 struct HashSet : tr1::unordered_set<K> {};
 
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__MINGW64__) && !defined(__MINGW32__)
 #define GG_LONGLONG(x) x##I64
 #define GG_ULONGLONG(x) x##UI64
 #else
diff --git a/extern/libmv/third_party/ceres/patches/collections_port.h.mingw.patch b/extern/libmv/third_party/ceres/patches/collections_port.h.mingw.patch
new file mode 100644 (file)
index 0000000..bbb366e
--- /dev/null
@@ -0,0 +1,13 @@
+Index: internal/ceres/collections_port.h
+===================================================================
+--- internal/ceres/collections_port.h  (revision 47730)
++++ internal/ceres/collections_port.h  (working copy)
+@@ -53,7 +53,7 @@
+ template<typename K>
+ struct HashSet : tr1::unordered_set<K> {};
+-#ifdef _WIN32
++#if defined(_WIN32) && !defined(__MINGW64__) && !defined(__MINGW32__)
+ #define GG_LONGLONG(x) x##I64
+ #define GG_ULONGLONG(x) x##UI64
+ #else
index 35fe4c67673dbafc03801ef10943965045a49122..d5b58298e18c5fd115844eeed9e452bd888289db 100644 (file)
@@ -75,6 +75,52 @@ static float get_node_output_value(BL::Node b_node, const string& name)
        return sock.default_value();
 }
 
+static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type)
+{
+       switch (b_type) {
+       case BL::NodeSocket::type_VALUE:
+               return SHADER_SOCKET_FLOAT;
+       case BL::NodeSocket::type_VECTOR:
+               return SHADER_SOCKET_VECTOR;
+       case BL::NodeSocket::type_RGBA:
+               return SHADER_SOCKET_COLOR;
+       case BL::NodeSocket::type_SHADER:
+               return SHADER_SOCKET_CLOSURE;
+       
+       case BL::NodeSocket::type_BOOLEAN:
+       case BL::NodeSocket::type_MESH:
+       case BL::NodeSocket::type_INT:
+       default:
+               return SHADER_SOCKET_FLOAT;
+       }
+}
+
+static void set_default_value(ShaderInput *input, BL::NodeSocket sock)
+{
+       /* copy values for non linked inputs */
+       switch(input->type) {
+       case SHADER_SOCKET_FLOAT: {
+               BL::NodeSocketFloatNone value_sock(sock);
+               input->set(value_sock.default_value());
+               break;
+       }
+       case SHADER_SOCKET_COLOR: {
+               BL::NodeSocketRGBA rgba_sock(sock);
+               input->set(get_float3(rgba_sock.default_value()));
+               break;
+       }
+       case SHADER_SOCKET_NORMAL:
+       case SHADER_SOCKET_POINT:
+       case SHADER_SOCKET_VECTOR: {
+               BL::NodeSocketVectorNone vec_sock(sock);
+               input->set(get_float3(vec_sock.default_value()));
+               break;
+       }
+       case SHADER_SOCKET_CLOSURE:
+               break;
+       }
+}
+
 static void get_tex_mapping(TextureMapping *mapping, BL::TexMapping b_mapping)
 {
        if(!b_mapping)
@@ -122,10 +168,18 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph
                /* handled outside this function */
                case BL::ShaderNode::type_GROUP: break;
                /* existing blender nodes */
+               case BL::ShaderNode::type_REROUTE: {
+                       BL::Node::inputs_iterator b_input;
+                       b_node.inputs.begin(b_input);
+                       BL::Node::outputs_iterator b_output;
+                       b_node.outputs.begin(b_output);
+                       ProxyNode *proxy = new ProxyNode(convert_socket_type(b_input->type()), convert_socket_type(b_output->type()));
+                       node = proxy;
+                       break;
+               }
                case BL::ShaderNode::type_CURVE_RGB: {
                        RGBCurvesNode *ramp = new RGBCurvesNode();
                        node = ramp;
-                       break;
                }
                case BL::ShaderNode::type_VALTORGB: {
                        RGBRampNode *ramp = new RGBRampNode();
@@ -488,52 +542,6 @@ static SocketPair node_socket_map_pair(PtrNodeMap& node_map, BL::Node b_node, BL
        return SocketPair(node_map[b_node.ptr.data], name);
 }
 
-static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type)
-{
-       switch (b_type) {
-       case BL::NodeSocket::type_VALUE:
-               return SHADER_SOCKET_FLOAT;
-       case BL::NodeSocket::type_VECTOR:
-               return SHADER_SOCKET_VECTOR;
-       case BL::NodeSocket::type_RGBA:
-               return SHADER_SOCKET_COLOR;
-       case BL::NodeSocket::type_SHADER:
-               return SHADER_SOCKET_CLOSURE;
-       
-       case BL::NodeSocket::type_BOOLEAN:
-       case BL::NodeSocket::type_MESH:
-       case BL::NodeSocket::type_INT:
-       default:
-               return SHADER_SOCKET_FLOAT;
-       }
-}
-
-static void set_default_value(ShaderInput *input, BL::NodeSocket sock)
-{
-       /* copy values for non linked inputs */
-       switch(input->type) {
-       case SHADER_SOCKET_FLOAT: {
-               BL::NodeSocketFloatNone value_sock(sock);
-               input->set(value_sock.default_value());
-               break;
-       }
-       case SHADER_SOCKET_COLOR: {
-               BL::NodeSocketRGBA rgba_sock(sock);
-               input->set(get_float3(rgba_sock.default_value()));
-               break;
-       }
-       case SHADER_SOCKET_NORMAL:
-       case SHADER_SOCKET_POINT:
-       case SHADER_SOCKET_VECTOR: {
-               BL::NodeSocketVectorNone vec_sock(sock);
-               input->set(get_float3(vec_sock.default_value()));
-               break;
-       }
-       case SHADER_SOCKET_CLOSURE:
-               break;
-       }
-}
-
 static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, PtrSockMap& sockets_map)
 {
        /* add nodes */
index bfa2b4f60ef76cff5c2a683c223a15ce3eaaa149..e4da581ab8345ba741a7868ae5064d5e50b6cfc6 100644 (file)
@@ -444,6 +444,7 @@ class ConstraintButtonsPanel():
         col = split.column()
         col.label(text="To Action:")
         col.prop(con, "action", text="")
+        col.prop(con, "use_bone_object_action")
 
         split = layout.split()
 
index 9ab8fcb5655c8c5890dbf458d85bda7a9c22d106..2f2d95f78df7599f768e54ed32d495263b386a99 100644 (file)
@@ -233,6 +233,7 @@ class CLIP_PT_tools_marker(CLIP_PT_tracking_panel, Panel):
             col.prop(settings, "default_motion_model")
             col.prop(settings, "default_use_brute")
             col.prop(settings, "default_use_normalization")
+            col.prop(settings, "default_use_mask")
             col.prop(settings, "default_correlation_min")
 
             col.separator()
@@ -541,6 +542,10 @@ class CLIP_PT_track(CLIP_PT_tracking_panel, Panel):
         sub = row.row()
         sub.prop(act_track, "use_grayscale_preview", text="B/W", toggle=True)
 
+        row.separator()
+        sub = row.row()
+        sub.prop(act_track, "use_alpha_preview", text="", toggle=True, icon='IMAGE_ALPHA')
+
         layout.separator()
 
         row = layout.row(align=True)
@@ -580,6 +585,7 @@ class CLIP_PT_track_settings(CLIP_PT_tracking_panel, Panel):
             col.prop(active, "motion_model")
             col.prop(active, "use_brute")
             col.prop(active, "use_normalization")
+            col.prop(active, "use_mask")
             col.prop(active, "correlation_min")
 
             col.separator()
index dec3960f37685d4cc21cfca146b08342fc368991..2d349931dc48a4086ee616947c682f423375ffdd 100644 (file)
@@ -434,6 +434,7 @@ class USERPREF_PT_system(Panel):
         col.label(text="OpenGL:")
         col.prop(system, "gl_clip_alpha", slider=True)
         col.prop(system, "use_mipmaps")
+        col.prop(system, "use_gpu_mipmap")
         col.prop(system, "use_16bit_textures")
         col.label(text="Anisotropic Filtering")
         col.prop(system, "anisotropic_filter", text="")
index bed2a1300a4ed2395b1714b87d7e82e8cadf1511..5962651995b0233ccc0fbedb4ab7930b5215f622 100644 (file)
@@ -1,5 +1,6 @@
 import bpy
 
+
 def main(operator, context):
     space = context.space_data
     node_tree = space.node_tree
@@ -14,7 +15,7 @@ def main(operator, context):
         return
 
     node_other, = node_selected
-    
+
     # now we have 2 nodes to operate on
     if not node_active.inputs:
         operator.report({'ERROR'}, "Active node has no inputs")
index 73a0d2d375b210c8a847184244d194804c231fc0..dd61a7e4c0fecefdec1da7068b9b2fbb92aa6b64 100644 (file)
@@ -372,6 +372,7 @@ void                        nodeSetActive(struct bNodeTree *ntree, struct bNode *node);
 struct bNode   *nodeGetActive(struct bNodeTree *ntree);
 struct bNode   *nodeGetActiveID(struct bNodeTree *ntree, short idtype);
 int                            nodeSetActiveID(struct bNodeTree *ntree, short idtype, struct ID *id);
+void                   nodeClearActive(struct bNodeTree *ntree);
 void                   nodeClearActiveID(struct bNodeTree *ntree, short idtype);
 struct bNode   *nodeGetActiveTexture(struct bNodeTree *ntree);
 
@@ -447,9 +448,7 @@ struct bNodeSocket *node_group_add_socket(struct bNodeTree *ngroup, const char *
 struct bNodeSocket *node_group_expose_socket(struct bNodeTree *ngroup, struct bNodeSocket *sock, int in_out);
 void node_group_expose_all_sockets(struct bNodeTree *ngroup);
 void node_group_remove_socket(struct bNodeTree *ngroup, struct bNodeSocket *gsock, int in_out);
-
-struct bNode   *node_group_make_from_selected(struct bNodeTree *ntree);
-int                            node_group_ungroup(struct bNodeTree *ntree, struct bNode *gnode);
+struct bNodeSocket *node_group_add_extern_socket(struct bNodeTree *ntree, ListBase *lb, int in_out, struct bNodeSocket *gsock);
 
 /* in node_common.c */
 void register_node_type_frame(struct bNodeTreeType *ttype);
index 716b65408e10706954e9d1ee3315296cd1347215..11013d549513373d4ee61d36159e2f3ae7d736e3 100644 (file)
@@ -72,14 +72,15 @@ void BKE_tracking_join_tracks(struct MovieTrackingTrack *dst_track, struct Movie
 void BKE_tracking_free(struct MovieTracking *tracking);
 
 struct ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height,
-                                                struct ImBuf *struct_ibuf, struct MovieTrackingMarker *marker,
+                                                struct ImBuf *struct_ibuf, struct MovieTrackingTrack *track,
+                                                struct MovieTrackingMarker *marker, int use_mask,
                                                 int num_samples_x, int num_samples_y, float pos[2]);
 struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track,
                                              struct MovieTrackingMarker *marker, int anchored, int disable_channels);
 struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track,
                                             struct MovieTrackingMarker *marker, int anchored, int disable_channels);
-struct ImBuf *BKE_tracking_track_mask_get(struct MovieTracking *tracking, struct MovieTrackingTrack *track,
-                                          struct MovieTrackingMarker *marker, int width, int height);
+float *BKE_tracking_track_mask_get(int frame_width, int frame_height, struct MovieTrackingTrack *track,
+                                   struct MovieTrackingMarker *marker);
 
 void BKE_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track);
 
index 7fc805297533195b07a10ccb1f6ce8f18d471eb4..a0da23a8f8fcbbb0917450fdf44be8c971976f2f 100644 (file)
@@ -1287,9 +1287,11 @@ static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime
                /* check if this driver's curve should be skipped */
                if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
                        /* check if driver itself is tagged for recalculation */
-                       if ((driver) && !(driver->flag & DRIVER_FLAG_INVALID) /*&& (driver->flag & DRIVER_FLAG_RECALC)*/) {  // XXX driver recalc flag is not set yet by depsgraph!
-                               /* evaluate this using values set already in other places */
-                               // NOTE: for 'layering' option later on, we should check if we should remove old value before adding new to only be done when drivers only changed
+                       /* XXX driver recalc flag is not set yet by depsgraph! */
+                       if ((driver) && !(driver->flag & DRIVER_FLAG_INVALID) /*&& (driver->flag & DRIVER_FLAG_RECALC)*/) {
+                               /* evaluate this using values set already in other places
+                                * NOTE: for 'layering' option later on, we should check if we should remove old value before adding
+                                *       new to only be done when drivers only changed */
                                calculate_fcurve(fcu, ctime);
                                ok = animsys_execute_fcurve(ptr, NULL, fcu);
                                
index 9d36a66843b3fc031d4110e00b372f8f0fc1b437..09351f36bdb797bdb321ea368df76a9274dbc2d9 100644 (file)
@@ -822,12 +822,12 @@ static void childof_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
                if (data->flag == CHILDOF_ALL) {
                        
                        /* multiply target (parent matrix) by offset (parent inverse) to get 
-                        * the effect of the parent that will be exherted on the owner
+                        * the effect of the parent that will be exerted on the owner
                         */
                        mult_m4_m4m4(parmat, ct->matrix, data->invmat);
                        
                        /* now multiply the parent matrix by the owner matrix to get the 
-                        * the effect of this constraint (i.e.  owner is 'parented' to parent)
+                        * the effect of this constraint (i.e. owner is 'parented' to parent)
                         */
                        mult_m4_m4m4(cob->matrix, parmat, cob->matrix);
                }
@@ -864,7 +864,7 @@ static void childof_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
                        loc_eulO_size_to_mat4(invmat, loco, eulo, sizo, cob->rotOrder);
                        
                        /* multiply target (parent matrix) by offset (parent inverse) to get 
-                        * the effect of the parent that will be exherted on the owner
+                        * the effect of the parent that will be exerted on the owner
                         */
                        mult_m4_m4m4(parmat, ct->matrix, invmat);
                        
@@ -1620,7 +1620,7 @@ static void rotlike_new_data(void *cdata)
 
 static void rotlike_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
 {
-       bChildOfConstraint *data = con->data;
+       bRotateLikeConstraint *data = con->data;
        
        /* target only */
        func(con, (ID **)&data->tar, FALSE, userdata);
@@ -2159,7 +2159,15 @@ static void actcon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintT
                        printf("do Action Constraint %s - Ob %s Pchan %s\n", con->name, cob->ob->id.name + 2, (cob->pchan) ? cob->pchan->name : NULL);
                
                /* Get the appropriate information from the action */
-               if (cob->type == CONSTRAINT_OBTYPE_BONE) {
+               if (cob->type == CONSTRAINT_OBTYPE_OBJECT || (data->flag & BONE_USE_OBJECT_ACTION)) {
+                       Object workob;
+                       
+                       /* evaluate using workob */
+                       // FIXME: we don't have any consistent standards on limiting effects on object...
+                       what_does_obaction(cob->ob, &workob, NULL, data->act, NULL, t);
+                       BKE_object_to_mat4(&workob, ct->matrix);
+               }
+               else if (cob->type == CONSTRAINT_OBTYPE_BONE) {
                        Object workob;
                        bPose *pose;
                        bPoseChannel *pchan, *tchan;
@@ -2185,14 +2193,6 @@ static void actcon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintT
                        /* Clean up */
                        BKE_pose_free(pose);
                }
-               else if (cob->type == CONSTRAINT_OBTYPE_OBJECT) {
-                       Object workob;
-                       
-                       /* evaluate using workob */
-                       // FIXME: we don't have any consistent standards on limiting effects on object...
-                       what_does_obaction(cob->ob, &workob, NULL, data->act, NULL, t);
-                       BKE_object_to_mat4(&workob, ct->matrix);
-               }
                else {
                        /* behavior undefined... */
                        puts("Error: unknown owner type for Action Constraint");
index 8b91ee29c59d950833313f87e7de0264d2b948b2..92184a386951630f6d2bafd53ad0b15ab15e8f5b 100644 (file)
@@ -1039,6 +1039,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
 
        scopes->marker = NULL;
        scopes->track = NULL;
+       scopes->track_locked = TRUE;
 
        if (clip) {
                MovieTrackingTrack *act_track = BKE_tracking_active_track(&clip->tracking);
@@ -1055,6 +1056,8 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
                                ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, user);
 
                                scopes->track_disabled = FALSE;
+                               scopes->marker = marker;
+                               scopes->track = track;
 
                                if (ibuf && (ibuf->rect || ibuf->rect_float)) {
                                        ImBuf *search_ibuf;
@@ -1087,6 +1090,8 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
 
                                        scopes->frame_width = ibuf->x;
                                        scopes->frame_height = ibuf->y;
+
+                                       scopes->use_track_mask = track->flag & TRACK_PREVIEW_ALPHA;
                                }
 
                                IMB_freeImBuf(ibuf);
@@ -1095,8 +1100,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
                        if ((track->flag & TRACK_LOCKED) == 0) {
                                float pat_min[2], pat_max[2];
 
-                               scopes->marker = marker;
-                               scopes->track = track;
+                               scopes->track_locked = FALSE;
 
                                /* XXX: would work fine with non-transformed patterns, but would likely fail
                                 *      with transformed patterns, but that would be easier to debug when
index 3e5f3f5b24cbc46b5d934f58c79e0c86656ddf42..7fe4016f68000ff4818e208d43b245e073967781 100644 (file)
@@ -1313,6 +1313,17 @@ void nodeClearActiveID(bNodeTree *ntree, short idtype)
                        node->flag &= ~NODE_ACTIVE_ID;
 }
 
+void nodeClearActive(bNodeTree *ntree)
+{
+       bNode *node;
+
+       if (ntree==NULL) return;
+
+       for (node= ntree->nodes.first; node; node= node->next)
+               node->flag &= ~(NODE_ACTIVE | NODE_ACTIVE_ID);
+}
+
+
 /* two active flags, ID nodes have special flag for buttons display */
 void nodeSetActive(bNodeTree *ntree, bNode *node)
 {
index 4cfa8461f2e399f0568202fd6f7bbc6a72c27c8d..a9e754498117826a6f8558d3aac078faf18d43f4 100644 (file)
@@ -1052,6 +1052,8 @@ typedef struct TrackContext {
        int search_area_height;
        int search_area_width;
        int framenr;
+
+       float *mask;
 #else
        int pad;
 #endif
@@ -1158,6 +1160,9 @@ static void track_context_free(void *customdata)
        if (track_context->search_area)
                MEM_freeN(track_context->search_area);
 
+       if (track_context->mask)
+               MEM_freeN(track_context->mask);
+
 #else
        (void)track_context;
 #endif
@@ -1244,14 +1249,16 @@ static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int g
                                            track->flag & TRACK_DISABLE_GREEN, track->flag & TRACK_DISABLE_BLUE, grayscale);
 }
 
-ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height,
-                                         ImBuf *search_ibuf, MovieTrackingMarker *marker,
-                                         int num_samples_x, int num_samples_y, float pos[2])
+ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height, ImBuf *search_ibuf,
+                                         MovieTrackingTrack *track, MovieTrackingMarker *marker,
+                                         int use_mask, int num_samples_x, int num_samples_y,
+                                         float pos[2])
 {
 #ifdef WITH_LIBMV
        ImBuf *pattern_ibuf;
        double src_pixel_x[5], src_pixel_y[5];
        double warped_position_x, warped_position_y;
+       float *mask = NULL;
 
        pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat);
        pattern_ibuf->profile = IB_PROFILE_LINEAR_RGB;
@@ -1262,9 +1269,13 @@ ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height,
 
        get_marker_coords_for_tracking(frame_width, frame_height, marker, src_pixel_x, src_pixel_y);
 
+       if (use_mask) {
+               mask = BKE_tracking_track_mask_get(frame_width, frame_height, track, marker);
+       }
+
        libmv_samplePlanarPatch(search_ibuf->rect_float, search_ibuf->x, search_ibuf->y, 4,
                                src_pixel_x, src_pixel_y, num_samples_x,
-                               num_samples_y, pattern_ibuf->rect_float,
+                               num_samples_y, mask, pattern_ibuf->rect_float,
                                &warped_position_x, &warped_position_y);
 
        if (pos) {
@@ -1272,6 +1283,10 @@ ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height,
                pos[1] = warped_position_y;
        }
 
+       if (mask) {
+               MEM_freeN(mask);
+       }
+
        return pattern_ibuf;
 #else
        ImBuf *pattern_ibuf;
@@ -1310,8 +1325,8 @@ ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, Mo
 
        search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, anchored, disable_channels);
 
-       pattern_ibuf = BKE_tracking_sample_pattern_imbuf(ibuf->x, ibuf->y, search_ibuf, marker,
-                                                        num_samples_x, num_samples_y, NULL);
+       pattern_ibuf = BKE_tracking_sample_pattern_imbuf(ibuf->x, ibuf->y, search_ibuf, track, marker,
+                                                        FALSE, num_samples_x, num_samples_y, NULL);
 
        IMB_freeImBuf(search_ibuf);
 
@@ -1366,8 +1381,21 @@ static bGPDlayer *track_mask_gpencil_layer_get(MovieTrackingTrack *track)
        layer = track->gpd->layers.first;
 
        while (layer) {
-               if (layer->flag & GP_LAYER_ACTIVE)
-                       return layer;
+               if (layer->flag & GP_LAYER_ACTIVE) {
+                       bGPDframe *frame = layer->frames.first;
+                       int ok = FALSE;
+
+                       while (frame) {
+                               if (frame->strokes.first) {
+                                       ok = TRUE;
+                               }
+
+                               frame = frame->next;
+                       }
+
+                       if (ok)
+                               return layer;
+               }
 
                layer = layer->next;
        }
@@ -1375,15 +1403,11 @@ static bGPDlayer *track_mask_gpencil_layer_get(MovieTrackingTrack *track)
        return NULL;
 }
 
-static void track_mask_gpencil_layer_rasterize(MovieTracking *tracking, MovieTrackingMarker *marker,
-                                               bGPDlayer *layer, ImBuf *ibuf, int width, int height)
+static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height,
+                                                                                          MovieTrackingMarker *marker, bGPDlayer *layer,
+                                               float *mask, int mask_width, int mask_height)
 {
        bGPDframe *frame = layer->frames.first;
-       float *mask;
-       int x, y;
-       float aspy = 1.0f / tracking->camera.pixel_aspect;
-
-       mask = MEM_callocN(ibuf->x * ibuf->y * sizeof(float), "track mask");
 
        while (frame) {
                bGPDstroke *stroke = frame->strokes.first;
@@ -1398,11 +1422,11 @@ static void track_mask_gpencil_layer_rasterize(MovieTracking *tracking, MovieTra
                                                               "track mask rasterization points");
 
                                for (i = 0; i < stroke->totpoints; i++, fp += 2) {
-                                       fp[0] = stroke_points[i].x * width / ibuf->x - marker->search_min[0];
-                                       fp[1] = stroke_points[i].y * height * aspy / ibuf->x - marker->search_min[1];
+                                       fp[0] = (stroke_points[i].x - marker->search_min[0]) * frame_width / mask_width;
+                                       fp[1] = (stroke_points[i].y - marker->search_min[1]) * frame_height / mask_height;
                                }
 
-                               PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, ibuf->x, ibuf->y);
+                               PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, mask_width, mask_height);
 
                                MEM_freeN(mask_points);
                        }
@@ -1412,45 +1436,26 @@ static void track_mask_gpencil_layer_rasterize(MovieTracking *tracking, MovieTra
 
                frame = frame->next;
        }
-
-       for (y = 0; y < ibuf->y; y++) {
-               for (x = 0; x < ibuf->x; x++) {
-                       float *pixel = &ibuf->rect_float[4 * (y * ibuf->x + x)];
-                       float val = mask[y * ibuf->x + x];
-
-                       pixel[0] = val;
-                       pixel[1] = val;
-                       pixel[2] = val;
-                       pixel[3] = 1.0f;
-               }
-       }
-
-       MEM_freeN(mask);
-
-       IMB_rect_from_float(ibuf);
 }
 
-ImBuf *BKE_tracking_track_mask_get(MovieTracking *tracking, MovieTrackingTrack *track, MovieTrackingMarker *marker,
-                                   int width, int height)
+float *BKE_tracking_track_mask_get(int frame_width, int frame_height,
+                                   MovieTrackingTrack *track, MovieTrackingMarker *marker)
 {
-       ImBuf *ibuf;
+       float *mask = NULL;
        bGPDlayer *layer = track_mask_gpencil_layer_get(track);
        int mask_width, mask_height;
 
-       mask_width = (marker->search_max[0] - marker->search_min[0]) * width;
-       mask_height = (marker->search_max[1] - marker->search_min[1]) * height;
-
-       ibuf = IMB_allocImBuf(mask_width, mask_height, 32, IB_rect | IB_rectfloat);
+       mask_width = (marker->search_max[0] - marker->search_min[0]) * frame_width;
+       mask_height = (marker->search_max[1] - marker->search_min[1]) * frame_height;
 
        if (layer) {
-               track_mask_gpencil_layer_rasterize(tracking, marker, layer, ibuf, width, height);
-       }
-       else {
-               float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
-               IMB_rectfill(ibuf, white);
+               mask = MEM_callocN(mask_width * mask_height * sizeof(float), "track mask");
+
+               track_mask_gpencil_layer_rasterize(frame_width, frame_height, marker, layer,
+                                                  mask, mask_width, mask_height);
        }
 
-       return ibuf;
+       return mask;
 }
 
 #ifdef WITH_LIBMV
@@ -1676,7 +1681,7 @@ int BKE_tracking_next(MovieTrackingContext *context)
        frame_width = destination_ibuf->x;
        frame_height = destination_ibuf->y;
 
-       #pragma omp parallel for private(a) shared(destination_ibuf, ok) if (map_size>1)
+       //#pragma omp parallel for private(a) shared(destination_ibuf, ok) if (map_size>1)
        for (a = 0; a < map_size; a++) {
                TrackContext *track_context = NULL;
                MovieTrackingTrack *track;
@@ -1724,7 +1729,7 @@ int BKE_tracking_next(MovieTrackingContext *context)
                                double src_pixel_y[5];
 
                                /* settings for the tracker */
-                               struct libmv_trackRegionOptions options;
+                               struct libmv_trackRegionOptions options = {0};
                                struct libmv_trackRegionResult result;
 
                                float *patch_new;
@@ -1744,6 +1749,14 @@ int BKE_tracking_next(MovieTrackingContext *context)
                                        track_context->search_area_width = width;
 
                                        IMB_freeImBuf(reference_ibuf);
+
+                                       if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0) {
+                                               if (track_context->mask)
+                                                       MEM_freeN(track_context->mask);
+
+                                               track_context->mask = BKE_tracking_track_mask_get(frame_width, frame_height,
+                                                                                                 track, marker);
+                                       }
                                }
 
                                /* for now track to the same search area dimension as marker has got for current frame
@@ -1765,6 +1778,9 @@ int BKE_tracking_next(MovieTrackingContext *context)
                                options.minimum_correlation = track->minimum_correlation;
                                options.sigma = 0.9;
 
+                               if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0)
+                                       options.image1_mask = track_context->mask;
+
                                /* Convert the marker corners and center into pixel coordinates in the search/destination images. */
                                get_marker_coords_for_tracking(frame_width, frame_height, &track_context->marker, src_pixel_x, src_pixel_y);
                                get_marker_coords_for_tracking(frame_width, frame_height, marker, dst_pixel_x, dst_pixel_y);
@@ -1790,7 +1806,7 @@ int BKE_tracking_next(MovieTrackingContext *context)
 
                                marker_search_scale_after_tracking(marker, &marker_new);
 
-                               #pragma omp critical
+                               //#pragma omp critical
                                {
                                        if (context->first_time) {
                                                /* check if there's no keyframe/tracked markers before tracking marker.
index f87265c50f5ab202e4f5b83ff68e3bcce38f77c2..1aa023bea3a7ac16ee88ac6fb57fc00589a20fba 100644 (file)
@@ -70,6 +70,7 @@ typedef enum CompositorPriority {
 // chunk size determination
 #define COM_PREVIEW_SIZE 140.0f
 //#define COM_OPENCL_ENABLED
+//#define COM_DEBUG
 
 // workscheduler threading models
 /**
@@ -106,7 +107,4 @@ typedef enum OrderOfChunks {
 
 #define COM_NUMBER_OF_CHANNELS 4
 
-#define COM_DEFAULT_RESOLUTION_WIDTH 640
-#define COM_DEFAULT_RESOLUTION_HEIGHT 480
-
 #endif
index 911de822f80d01d260eb24159e5cd486fd1a5c73..bb8e7d9606d2f1c5632dfd3f21d1eb8dfbfa8e61 100644 (file)
@@ -29,6 +29,7 @@ CompositorContext::CompositorContext()
        this->scene = NULL;
        this->quality = COM_QUALITY_HIGH;
        this->hasActiveOpenCLDevices = false;
+       this->activegNode = NULL;
 }
 
 const int CompositorContext::getFramenumber() const
index 2889f43290e41fdce7d161c2c0091f61b09d8f04..8425030aec2f68a96a9072c265958f46d9dbf8e0 100644 (file)
@@ -63,6 +63,11 @@ private:
          * @see ExecutionSystem
          */
        bNodeTree *bnodetree;
+       
+       /**
+        * @brief activegNode the group node that is currently being edited.
+        */
+       bNode *activegNode;
 
        /**
          * @brief does this system have active opencl devices?
@@ -100,6 +105,16 @@ public:
          */
        const bNodeTree * getbNodeTree() const {return this->bnodetree;}
 
+       /**
+         * @brief set the active groupnode of the context
+         */
+       void setActivegNode(bNode *gnode) {this->activegNode = gnode;}
+
+       /**
+         * @brief get the active groupnode of the context
+         */
+       const bNode * getActivegNode() const {return this->activegNode;}
+
        /**
          * @brief get the scene of the context
          */
index 481b83c81a3f48330a2af7461270607363125c7c..e46b4934217deb4e4f7a3010f9fa8e3f72fb3304 100644 (file)
@@ -184,11 +184,8 @@ void ExecutionGroup::deinitExecution()
 void ExecutionGroup::determineResolution(unsigned int resolution[])
 {
        NodeOperation *operation = this->getOutputNodeOperation();
-       unsigned int preferredResolution[2];
-       preferredResolution[0] = 0;
-       preferredResolution[1] = 0;
-       operation->determineResolution(resolution, preferredResolution);
-       operation->setResolution(resolution);
+       resolution[0] = operation->getWidth();
+       resolution[1] = operation->getHeight();
        this->setResolution(resolution);
 }
 
index 8c0b37a0685f9273cfa59b8bde84bf1afb991e6b..1056c6d3f65297854b0f51003328544ec6ae592a 100644 (file)
 
 ExecutionSystem::ExecutionSystem(bNodeTree *editingtree, bool rendering)
 {
-       this->context.setbNodeTree(editingtree);
+       context.setbNodeTree(editingtree);
+       bNode* gnode;
+       for (gnode = (bNode*)editingtree->nodes.first ; gnode ; gnode = (bNode*)gnode->next) {
+               if (gnode->type == NODE_GROUP && gnode->typeinfo->group_edit_get(gnode)) {
+                       context.setActivegNode(gnode);
+                       break;
+               }
+       }
 
        /* initialize the CompositorContext */
        if (rendering) {
@@ -55,25 +62,25 @@ ExecutionSystem::ExecutionSystem(bNodeTree *editingtree, bool rendering)
 
        Node *mainOutputNode=NULL;
 
-       mainOutputNode = ExecutionSystemHelper::addbNodeTree(*this, 0, editingtree);
+       mainOutputNode = ExecutionSystemHelper::addbNodeTree(*this, 0, editingtree, NULL);
 
        if (mainOutputNode) {
                context.setScene((Scene*)mainOutputNode->getbNode()->id);
                this->convertToOperations();
                this->groupOperations(); /* group operations in ExecutionGroups */
-               vector<ExecutionGroup*> executionGroups;
-               this->findOutputExecutionGroup(&executionGroups);
                unsigned int index;
                unsigned int resolution[2];
-               for (index = 0 ; index < executionGroups.size(); index ++) {
+               for (index = 0 ; index < this->groups.size(); index ++) {
                        resolution[0]=0;
                        resolution[1]=0;
-                       ExecutionGroup *executionGroup = executionGroups[index];
+                       ExecutionGroup *executionGroup = groups[index];
                        executionGroup->determineResolution(resolution);
                }
        }
 
-       if (G.f & G_DEBUG) ExecutionSystemHelper::debugDump(this);
+#ifdef COM_DEBUG
+       ExecutionSystemHelper::debugDump(this);
+#endif
 }
 
 ExecutionSystem::~ExecutionSystem()
@@ -180,11 +187,13 @@ void ExecutionSystem::addReadWriteBufferOperations(NodeOperation *operation)
                                        writeoperation->setbNodeTree(this->getContext().getbNodeTree());
                                        this->addOperation(writeoperation);
                                        ExecutionSystemHelper::addLink(this->getConnections(), fromsocket, writeoperation->getInputSocket(0));
+                                       writeoperation->readResolutionFromInputSocket();
                                }
                                ReadBufferOperation *readoperation = new ReadBufferOperation();
                                readoperation->setMemoryProxy(writeoperation->getMemoryProxy());
                                connection->setFromSocket(readoperation->getOutputSocket());
                                readoperation->getOutputSocket()->addConnection(connection);
+                               readoperation->readResolutionFromWriteBuffer();
                                this->addOperation(readoperation);
                        }
                }
@@ -207,9 +216,11 @@ void ExecutionSystem::addReadWriteBufferOperations(NodeOperation *operation)
                        readoperation->setMemoryProxy(writeOperation->getMemoryProxy());
                        connection->setFromSocket(readoperation->getOutputSocket());
                        readoperation->getOutputSocket()->addConnection(connection);
+                       readoperation->readResolutionFromWriteBuffer();
                        this->addOperation(readoperation);
                }
                ExecutionSystemHelper::addLink(this->getConnections(), outputsocket, writeOperation->getInputSocket(0));
+               writeOperation->readResolutionFromInputSocket();
        }
 }
 
@@ -237,7 +248,16 @@ void ExecutionSystem::convertToOperations()
        // determine all resolutions of the operations (Width/Height)
        for (index = 0 ; index < this->operations.size(); index ++) {
                NodeOperation *operation = this->operations[index];
-               if (operation->isOutputOperation(context.isRendering())) {
+               if (operation->isOutputOperation(context.isRendering()) && !operation->isPreviewOperation()) {
+                       unsigned int resolution[2] = {0,0};
+                       unsigned int preferredResolution[2] = {0,0};
+                       operation->determineResolution(resolution, preferredResolution);
+                       operation->setResolution(resolution);
+               }
+       }
+       for (index = 0 ; index < this->operations.size(); index ++) {
+               NodeOperation *operation = this->operations[index];
+               if (operation->isOutputOperation(context.isRendering()) && operation->isPreviewOperation()) {
                        unsigned int resolution[2] = {0,0};
                        unsigned int preferredResolution[2] = {0,0};
                        operation->determineResolution(resolution, preferredResolution);
index 67554cd464b531512fe0a15539aeeb0860be8cc9..75be8df74de07abdaa0b2d06c0da009a0d993c3c 100644 (file)
 #include "COM_GroupNode.h"
 #include "COM_WriteBufferOperation.h"
 #include "COM_ReadBufferOperation.h"
+#include "COM_ViewerBaseOperation.h"
 
-Node *ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree *tree)
+Node *ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree * tree, bNode *groupnode)
 {
        vector<Node*>& nodes = system.getNodes();
        vector<SocketConnection*>& links = system.getConnections();
        Node *mainnode = NULL;
+       const bNode * activeGroupNode = system.getContext().getActivegNode();
+       bool isActiveGroup = activeGroupNode == groupnode;
+       
        /* add all nodes of the tree to the node list */
        bNode *node = (bNode*)tree->nodes.first;
        while (node != NULL) {
-               Node *execnode = addNode(nodes, node);
+               Node *execnode = addNode(nodes, node, isActiveGroup);
                if (node->type == CMP_NODE_COMPOSITE) {
                        mainnode = execnode;
                }
@@ -77,11 +81,12 @@ void ExecutionSystemHelper::addNode(vector<Node*>& nodes, Node *node)
        nodes.push_back(node);
 }
 
-Node *ExecutionSystemHelper::addNode(vector<Node*>& nodes, bNode *bNode)
+Node *ExecutionSystemHelper::addNode(vector<Node*>& nodes, bNode *bNode, bool inActiveGroup)
 {
        Converter converter;
        Node * node;
        node = converter.convert(bNode);
+       node->setIsInActiveGroup(inActiveGroup);
        if (node != NULL) {
                addNode(nodes, node);
                return node;
@@ -232,7 +237,12 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system)
                        printf("|");
                }
                if (operation->isViewerOperation()) {
-                       printf("Viewer");
+                       ViewerBaseOperation * viewer = (ViewerBaseOperation*)operation;
+                       if (viewer->isActiveViewerOutput()) {
+                               printf("Active viewer");
+                       } else {
+                               printf("Viewer");
+                       }
                }
                else if (operation->isOutputOperation(system->getContext().isRendering())) {
                        printf("Output");
@@ -249,6 +259,7 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system)
                else {
                        printf("O_%p", operation);
                }
+               printf(" (%d,%d)", operation->getWidth(), operation->getHeight());
                tot2 = operation->getNumberOfOutputSockets();
                if (tot2 != 0) {
                        printf("|");
index a72e269115e72b20685fe4dc40a5582b5e885c23..9321cb571e8f93873ed43635a8cb02b3ce26d83f 100644 (file)
@@ -48,7 +48,7 @@ public:
          * @param tree bNodeTree to add
          * @return Node representing the "Compositor node" of the maintree. or NULL when a subtree is added
          */
-       static Node *addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree * tree);
+       static Node *addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree* tree, bNode *groupnode);
        
        /**
          * @brief add an editor node to the system.
@@ -58,7 +58,7 @@ public:
          * @param bNode node to add
          * @return Node that represents the bNode or null when not able to convert.
          */
-       static Node *addNode(vector<Node*>& nodes, bNode *bNode);
+       static Node *addNode(vector<Node*>& nodes, bNode *bNode, bool isInActiveGroup);
        
        /**
          * @brief Add a Node to a list
index 264725b4b2c2718581619777413607c8c32ab33e..2324eacd26cb79fd28cfd09710a5a5051a4f5863 100644 (file)
@@ -85,16 +85,18 @@ void Node::addSetValueOperation(ExecutionSystem *graph, InputSocket *inputsocket
 
 void Node::addPreviewOperation(ExecutionSystem *system, OutputSocket *outputSocket)
 {
-       PreviewOperation *operation = new PreviewOperation();
-       system->addOperation(operation);
-       operation->setbNode(this->getbNode());
-       operation->setbNodeTree(system->getContext().getbNodeTree());
-       this->addLink(system, outputSocket, operation->getInputSocket(0));
+       if (this->isInActiveGroup()) {
+               PreviewOperation *operation = new PreviewOperation();
+               system->addOperation(operation);
+               operation->setbNode(this->getbNode());
+               operation->setbNodeTree(system->getContext().getbNodeTree());
+               this->addLink(system, outputSocket, operation->getInputSocket(0));
+       }
 }
 
 void Node::addPreviewOperation(ExecutionSystem *system, InputSocket *inputSocket)
 {
-       if (inputSocket->isConnected()) {
+       if (inputSocket->isConnected() && this->isInActiveGroup()) {
                OutputSocket *outputsocket = inputSocket->getConnection()->getFromSocket();
                this->addPreviewOperation(system, outputsocket);
        }
index 23744adf64280b40694868ec3e0f980fdc717db9..0546062f79077ee54803a06dbf75ec9c95876805 100644 (file)
@@ -52,6 +52,11 @@ private:
          */
        bNode *editorNode;
 
+       /**
+        * @brief Is this node part of the active group
+        */
+       bool inActiveGroup;
+
 public:
        Node(bNode *editorNode, bool create_sockets=true);
        
@@ -60,6 +65,20 @@ public:
          */
        bNode *getbNode();
        
+       /**
+        * @brief Is this node in the active group (the group that is being edited)
+        * @param isInActiveGroup
+        */
+       void setIsInActiveGroup(bool isInActiveGroup) {this->inActiveGroup = isInActiveGroup; }
+       
+       /**
+        * @brief Is this node part of the active group
+        * the active group is the group that is currently being edited. When no group is edited, 
+        * the active group will be the main tree (all nodes that are not part of a group will be active)
+        * @return bool [false:true]
+        */
+       inline bool isInActiveGroup() {return this->inActiveGroup;}
+       
        /**
          * @brief convert node to operation
          *
index 2219907b0c807fdbde4f344888da1bebf6b1bb38..db1fdda0bcfbb064360ef4e167c3bce5bff6b2c9 100644 (file)
@@ -160,11 +160,22 @@ public:
        virtual void deinitExecution();
        void deinitMutex();
 
+       bool isResolutionSet() {
+               return this->width != 0 && height != 0;
+       }
+
        /**
          * @brief set the resolution
          * @param resolution the resolution to set
          */
-       void setResolution(unsigned int resolution[]) {this->width = resolution[0];this->height = resolution[1];}
+       void setResolution(unsigned int resolution[]) {
+               if (!isResolutionSet()) {
+                       this->width = resolution[0];
+                       this->height = resolution[1];
+               }
+       }
+       
+
        void getConnectedInputSockets(vector<InputSocket*> *sockets);
 
        /**
@@ -221,6 +232,7 @@ public:
        bool isOpenCL() { return this->openCL; }
        
        virtual bool isViewerOperation() {return false;}
+       virtual bool isPreviewOperation() {return false;}
 protected:
        NodeOperation();
 
index 00d3518cd15a28dfabfdaba0a9b8b9a020fd70af..708b2d65d464f9622790748c149431834faa24a1 100644 (file)
@@ -47,8 +47,13 @@ void OutputSocket::determineResolution(unsigned int resolution[], unsigned int p
        NodeBase *node = this->getNode();
        if (node->isOperation()) {
                NodeOperation *operation = (NodeOperation*)node;
-               operation->determineResolution(resolution, preferredResolution);
-               operation->setResolution(resolution);
+               if (operation->isResolutionSet()) {
+                       resolution[0] = operation->getWidth();
+                       resolution[1] = operation->getHeight();
+               } else {
+                       operation->determineResolution(resolution, preferredResolution);
+                       operation->setResolution(resolution);
+               }
        }
 }
 
index ec06a3acd7e0a6c549460f146ea927db2dbc8a1d..8a8c1db86b4ab41612e70326e1e008a0310ebdc6 100644 (file)
@@ -34,6 +34,7 @@ void GroupNode::convertToOperations(ExecutionSystem *graph, CompositorContext *
 
 void GroupNode::ungroup(ExecutionSystem &system)
 {
+       bNode * bnode = this->getbNode();
        vector<InputSocket*> &inputsockets = this->getInputSockets();
        vector<OutputSocket*> &outputsockets = this->getOutputSockets();
        unsigned int index;
@@ -45,7 +46,7 @@ void GroupNode::ungroup(ExecutionSystem &system)
                InputSocket * inputSocket = inputsockets[index];
                bNodeSocket *editorInput = inputSocket->getbNodeSocket();
                if (editorInput->groupsock) {
-                       SocketProxyNode * proxy = new SocketProxyNode(this->getbNode(), editorInput, editorInput->groupsock);
+                       SocketProxyNode * proxy = new SocketProxyNode(bnode, editorInput, editorInput->groupsock);
                        inputSocket->relinkConnections(proxy->getInputSocket(0), index, &system);
                        ExecutionSystemHelper::addNode(system.getNodes(), proxy);
                }
@@ -55,12 +56,12 @@ void GroupNode::ungroup(ExecutionSystem &system)
                OutputSocket * outputSocket = outputsockets[index];
                bNodeSocket *editorOutput = outputSocket->getbNodeSocket();
                if (editorOutput->groupsock) {
-                       SocketProxyNode * proxy = new SocketProxyNode(this->getbNode(), editorOutput->groupsock, editorOutput);
+                       SocketProxyNode * proxy = new SocketProxyNode(bnode, editorOutput->groupsock, editorOutput);
                        outputSocket->relinkConnections(proxy->getOutputSocket(0));
                        ExecutionSystemHelper::addNode(system.getNodes(), proxy);
                }
        }
 
-       bNodeTree *subtree = (bNodeTree*)this->getbNode()->id;
-       ExecutionSystemHelper::addbNodeTree(system, nodes_start, subtree);
+       bNodeTree *subtree = (bNodeTree*)bnode->id;
+       ExecutionSystemHelper::addbNodeTree(system, nodes_start, subtree, bnode);
 }
index 72303a4d6ee5d6bfdd0e1e1be70b055c7c45b076..d02eb2a0b980370119bb2fb927d0cc81d9b02974 100644 (file)
@@ -44,37 +44,38 @@ void MuteNode::reconnect(ExecutionSystem * graph, OutputSocket * output)
                }
        }
        
-       NodeOperation * operation;
+       NodeOperation *operation;
        switch (output->getDataType()) {
-       case COM_DT_VALUE:
-       {
-               SetValueOperation *valueoperation = new SetValueOperation();
-               valueoperation->setValue(0.0f);
-               operation = valueoperation;
-               break;
-       }
-       case COM_DT_VECTOR:
-       {
-               SetVectorOperation *vectoroperation = new SetVectorOperation();
-               vectoroperation->setX(0.0f);
-               vectoroperation->setY(0.0f);
-               vectoroperation->setW(0.0f);
-               operation = vectoroperation;
-               break;
-       }
-       case COM_DT_COLOR:
-       {
-               SetColorOperation *coloroperation = new SetColorOperation();
-               coloroperation->setChannel1(0.0f);
-               coloroperation->setChannel2(0.0f);
-               coloroperation->setChannel3(0.0f);
-               coloroperation->setChannel4(0.0f);
-               operation = coloroperation;
-               break;
-       }
-               /* quiet warnings */
-       case COM_DT_UNKNOWN:
-               break;
+               case COM_DT_VALUE:
+               {
+                       SetValueOperation *valueoperation = new SetValueOperation();
+                       valueoperation->setValue(0.0f);
+                       operation = valueoperation;
+                       break;
+               }
+               case COM_DT_VECTOR:
+               {
+                       SetVectorOperation *vectoroperation = new SetVectorOperation();
+                       vectoroperation->setX(0.0f);
+                       vectoroperation->setY(0.0f);
+                       vectoroperation->setW(0.0f);
+                       operation = vectoroperation;
+                       break;
+               }
+               case COM_DT_COLOR:
+               {
+                       SetColorOperation *coloroperation = new SetColorOperation();
+                       coloroperation->setChannel1(0.0f);
+                       coloroperation->setChannel2(0.0f);
+                       coloroperation->setChannel3(0.0f);
+                       coloroperation->setChannel4(0.0f);
+                       operation = coloroperation;
+                       break;
+               }
+                       /* quiet warnings */
+               case COM_DT_UNKNOWN:
+                       operation = NULL;
+                       break;
        }
 
        if (operation) {
index bf434c164c0205223c8bc89a88012c46a0260f9a..8bf9fd2bf060ff1edb967423f08fa6a991c6314b 100644 (file)
@@ -40,7 +40,7 @@ void SplitViewerNode::convertToOperations(ExecutionSystem *graph, CompositorCont
                SplitViewerOperation *splitViewerOperation = new SplitViewerOperation();
                splitViewerOperation->setImage(image);
                splitViewerOperation->setImageUser(imageUser);
-               splitViewerOperation->setActive(this->getbNode()->flag & NODE_DO_OUTPUT);
+               splitViewerOperation->setActive((this->getbNode()->flag & NODE_DO_OUTPUT) && this->isInActiveGroup());
                splitViewerOperation->setSplitPercentage(this->getbNode()->custom1);
                splitViewerOperation->setXSplit(!this->getbNode()->custom2);
                image1Socket->relinkConnections(splitViewerOperation->getInputSocket(0), 0, graph);
index f5dab52d02169934a66e1feeae8d59a13ec4b14d..67c0df4d6a36d834a3e9262404f2f8f60bd0802d 100644 (file)
@@ -44,7 +44,7 @@ void ViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext *
                viewerOperation->setbNodeTree(context->getbNodeTree());
                viewerOperation->setImage(image);
                viewerOperation->setImageUser(imageUser);
-               viewerOperation->setActive(editorNode->flag & NODE_DO_OUTPUT);
+               viewerOperation->setActive((editorNode->flag & NODE_DO_OUTPUT) && this->isInActiveGroup());
                viewerOperation->setChunkOrder((OrderOfChunks)editorNode->custom1);
                viewerOperation->setCenterX(editorNode->custom3);
                viewerOperation->setCenterY(editorNode->custom4);
index 71a87dce2a72130a7998c94d53dbb6827c04ff70..b4811c89dc59925f35f6436652fae5f6b549e701 100644 (file)
@@ -86,6 +86,7 @@ void BokehBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer *
                float overallmultiplyerr = 0;
                float overallmultiplyerg = 0;
                float overallmultiplyerb = 0;
+               float overallmultiplyera = 0;
                MemoryBuffer *inputBuffer = (MemoryBuffer*)data;
                float *buffer = inputBuffer->getBuffer();
                int bufferwidth = inputBuffer->getWidth();
@@ -115,16 +116,18 @@ void BokehBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer *
                                tempColor[0] += bokeh[0] * buffer[bufferindex];
                                tempColor[1] += bokeh[1] * buffer[bufferindex+1];
                                tempColor[2] += bokeh[2]* buffer[bufferindex+2];
+                               tempColor[3] += bokeh[3]* buffer[bufferindex+3];
                                overallmultiplyerr += bokeh[0];
                                overallmultiplyerg += bokeh[1];
                                overallmultiplyerb += bokeh[2];
+                               overallmultiplyera += bokeh[3];
                                bufferindex +=offsetadd;
                        }
                }
                color[0] = tempColor[0] * (1.0f / overallmultiplyerr);
                color[1] = tempColor[1] * (1.0f / overallmultiplyerg);
                color[2] = tempColor[2] * (1.0f / overallmultiplyerb);
-               color[3] = 1.0f;
+               color[3] = tempColor[3] * (1.0f / overallmultiplyera);
        }
        else {
                inputProgram->read(color, x, y, COM_PS_NEAREST, inputBuffers);
index a0297b129616799ce1d04dfe0d259e0925ff4f17..189ba98aa577bdb14dd910d60b717ca0fdbc26b1 100644 (file)
@@ -105,7 +105,7 @@ void BokehImageOperation::executePixel(float *color, float x, float y, PixelSamp
                color[1] = insideBokehMed;
                color[2] = insideBokehMax;
        }
-       color[3] = 1.0f;
+       color[3] = (insideBokehMax+insideBokehMed+insideBokehMin)/3.0f;
 }
 
 void BokehImageOperation::deinitExecution()
index d75cb39325fa9a5dd6e6e25009557f331eaf8020..c6e8faaa6389cc96c0211be893e2d50bec41c702 100644 (file)
@@ -102,7 +102,7 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber, Mem
        int y1 = rect->ymin;
        int x2 = rect->xmax;
        int y2 = rect->ymax;
-       int offset = (y1*this->getWidth() + x1 ) * 4;
+       int offset = (y1*this->getWidth() + x1 ) * COM_NUMBER_OF_CHANNELS;
        int x;
        int y;
        bool breaked = false;
@@ -117,12 +117,12 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber, Mem
                        buffer[offset+1] = color[1];
                        buffer[offset+2] = color[2];
                        buffer[offset+3] = color[3];
-                       offset +=4;
+                       offset +=COM_NUMBER_OF_CHANNELS;
                        if (tree->test_break && tree->test_break(tree->tbh)) {
                                breaked = true;
                        }
                }
-               offset += (this->getWidth()-(x2-x1))*4;
+               offset += (this->getWidth()-(x2-x1))*COM_NUMBER_OF_CHANNELS;
        }
 }
 
@@ -130,6 +130,19 @@ void CompositorOperation::determineResolution(unsigned int resolution[], unsigne
 {
        int width = this->scene->r.xsch*this->scene->r.size/100;
        int height = this->scene->r.ysch*this->scene->r.size/100;
+       
+       // check actual render resolution with cropping it may differ with cropped border.rendering
+       // FIX for: [31777] Border Crop gives black (easy)
+       Render *re= RE_GetRender(this->scene->id.name);
+       if (re) {
+               RenderResult *rr= RE_AcquireResultRead(re);
+               if (rr) {
+                       width = rr->rectx;
+                       height = rr->recty;
+               }
+               RE_ReleaseResult(re);
+       }
+       
        preferredResolution[0] = width;
        preferredResolution[1] = height;
        
index 3d1cd38a5ea4dea6f8db0f707499d84ddd152933..2b81b9147461e83c0b6d0a39349ed9f88924f67e 100644 (file)
@@ -50,5 +50,7 @@ public:
        void setbNode(bNode *node) { this->node = node;}
        void setbNodeTree(const bNodeTree *tree) { this->tree = tree;}
        bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
+       bool isPreviewOperation() {return true;}
+       
 };
 #endif
index d7f95c10cfb646236b9f89b29c07f7c73b8c5589..14b6db9037bd1cb414a0b8acc8bc8f392cbb9d0c 100644 (file)
@@ -75,3 +75,11 @@ bool ReadBufferOperation::determineDependingAreaOfInterest(rcti * input, ReadBuf
        }
        return false;
 }
+
+void ReadBufferOperation::readResolutionFromWriteBuffer() {
+       if (this->memoryProxy != NULL) {
+               WriteBufferOperation * operation = memoryProxy->getWriteBufferOperation();
+               this->setWidth(operation->getWidth());
+               this->setHeight(operation->getHeight());
+       }
+}
index d58d131264ba4559fe026af5ead662bd45344611..449b4a826185f1098cff5429084321e541de5819 100644 (file)
@@ -45,7 +45,7 @@ public:
        unsigned int getOffset() {return this->offset;}
        bool determineDependingAreaOfInterest(rcti * input, ReadBufferOperation *readOperation, rcti *output);
        MemoryBuffer *getInputMemoryBuffer(MemoryBuffer** memoryBuffers) {return memoryBuffers[offset];}
-       
+       void readResolutionFromWriteBuffer();
 };
 
 #endif
index af2633f0e530a8bfe9e566e71d2bd01f6df83004..a391a26b89c615ea0d35c9fa5bea21a009c524fd 100644 (file)
@@ -32,6 +32,7 @@ RotateOperation::RotateOperation() : NodeOperation()
        this->imageSocket = NULL;
        this->degreeSocket =  NULL;
        this->doDegree2RadConversion = false;
+       this->isDegreeSet = false;
 }
 void RotateOperation::initExecution()
 {
@@ -39,17 +40,6 @@ void RotateOperation::initExecution()
        this->degreeSocket = this->getInputSocketReader(1);
        this->centerX = this->getWidth()/2.0;
        this->centerY = this->getHeight()/2.0;
-       float degree[4];
-       this->degreeSocket->read(degree, 0, 0, COM_PS_NEAREST, NULL);
-       double rad;
-       if (this->doDegree2RadConversion) {
-               rad = DEG2RAD((double)degree[0]);
-       }
-       else {
-               rad = degree[0];
-       }
-       this->cosine = cos(rad);
-       this->sine = sin(rad);
 }
 
 void RotateOperation::deinitExecution()
@@ -58,9 +48,28 @@ void RotateOperation::deinitExecution()
        this->degreeSocket = NULL;
 }
 
+inline void RotateOperation::ensureDegree() {
+       if (!isDegreeSet) {
+               float degree[4];
+               this->degreeSocket->read(degree, 0, 0, COM_PS_NEAREST, NULL);
+               double rad;
+               if (this->doDegree2RadConversion) {
+                  rad = DEG2RAD((double)degree[0]);
+               }
+               else {
+                  rad = degree[0];
+               }
+               this->cosine = cos(rad);
+               this->sine = sin(rad);
+               
+               isDegreeSet = true;
+       }
+}
+
 
 void RotateOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
 {
+       ensureDegree();
        const float dy = y - this->centerY;
        const float dx = x - this->centerX;
        const float nx = this->centerX+(this->cosine*dx + this->sine*dy);
@@ -70,6 +79,7 @@ void RotateOperation::executePixel(float *color,float x, float y, PixelSampler s
 
 bool RotateOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
 {
+       ensureDegree();
        rcti newInput;
        
        const float dxmin = input->xmin - this->centerX;
index 9965d1021daeec98509f9d78203a1552fa866bbb..6afed39908b5e0d994ff0161e8126d169e42fe1c 100644 (file)
@@ -34,6 +34,7 @@ private:
        float cosine;
        float sine;
        bool doDegree2RadConversion;
+       bool isDegreeSet;
 public:
        RotateOperation();
        bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
@@ -41,6 +42,8 @@ public:
        void initExecution();
        void deinitExecution();
        void setDoDegree2RadConversion(bool abool) {this->doDegree2RadConversion = abool;}
+       
+       void ensureDegree();
 };
 
 #endif
index 70477de0514e1321692b22076f01ee50b5e96c70..79c0201733ec05f773adf6de4608302663f83eb5 100644 (file)
@@ -38,12 +38,6 @@ void SetVectorOperation::executePixel(float *outputValue, float x, float y, Pixe
 
 void SetVectorOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[])
 {
-       if (preferredResolution[0] == 0 ||preferredResolution[1]==0) {
-               resolution[0] = COM_DEFAULT_RESOLUTION_WIDTH;
-               resolution[1] = COM_DEFAULT_RESOLUTION_HEIGHT;
-       }
-       else {
-               resolution[0] = preferredResolution[0];
-               resolution[1] = preferredResolution[1];
-       }
+       resolution[0] = preferredResolution[0];
+       resolution[1] = preferredResolution[1];
 }
index 6ed877523d1039a44320c8059db0aaaff37b2064..51b16506dd909aade07b38e1f3c5cc7451f763e4 100644 (file)
@@ -41,5 +41,7 @@ void SocketProxyOperation::deinitExecution()
 
 void SocketProxyOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
 {
-       this->inputOperation->read(color, x, y, sampler, inputBuffers);
+       if (this->inputOperation) {
+               this->inputOperation->read(color, x, y, sampler, inputBuffers);
+       }
 }
index 6d2fdfc11d0051ee94cb321f889b011fefcec044..b9b06d6d356994f3ff037d73c46157fa05fcd9ba 100644 (file)
@@ -32,6 +32,7 @@ TranslateOperation::TranslateOperation() : NodeOperation()
        this->inputOperation = NULL;
        this->inputXOperation = NULL;
        this->inputYOperation = NULL;
+       this->isDeltaSet = false;
 }
 void TranslateOperation::initExecution()
 {
@@ -39,11 +40,6 @@ void TranslateOperation::initExecution()
        this->inputXOperation = this->getInputSocketReader(1);
        this->inputYOperation = this->getInputSocketReader(2);
 
-       float tempDelta[4];
-       this->inputXOperation->read(tempDelta, 0, 0, COM_PS_NEAREST, NULL);
-       this->deltaX = tempDelta[0];
-       this->inputYOperation->read(tempDelta, 0, 0, COM_PS_NEAREST, NULL);
-       this->deltaY = tempDelta[0];
 }
 
 void TranslateOperation::deinitExecution()
@@ -56,11 +52,13 @@ void TranslateOperation::deinitExecution()
 
 void TranslateOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
 {
+       ensureDelta();
        this->inputOperation->read(color, x-this->getDeltaX(), y-this->getDeltaY(), sampler, inputBuffers);
 }
 
 bool TranslateOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
 {
+       ensureDelta();
        rcti newInput;
        
        newInput.xmax = input->xmax - this->getDeltaX();
index eab3391041e48e70b821ab096fffabe5b05cf99c..63d6ee0d0b5ca69acd1d0390c6eecd871e658fe1 100644 (file)
@@ -32,6 +32,7 @@ private:
        SocketReader*inputYOperation;
        float deltaX;
        float deltaY;
+       float isDeltaSet;
 public:
        TranslateOperation();
        bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
@@ -42,6 +43,17 @@ public:
 
        float getDeltaX() {return this->deltaX;}
        float getDeltaY() {return this->deltaY;}
+       
+       inline void ensureDelta() {
+               if (!isDeltaSet) {
+                       float tempDelta[4];
+                       this->inputXOperation->read(tempDelta, 0, 0, COM_PS_NEAREST, NULL);
+                       this->deltaX = tempDelta[0];
+                       this->inputYOperation->read(tempDelta, 0, 0, COM_PS_NEAREST, NULL);
+                       this->deltaY = tempDelta[0];
+                       this->isDeltaSet = true;
+               }
+       }
 };
 
 #endif
index 270fedc174b81830a32ff1100d0818cc3923404b..562b0fc2bb5258447a55a3b1ac30f3e8d1902ca6 100644 (file)
@@ -64,6 +64,7 @@ void VariableSizeBokehBlurOperation::executePixel(float *color, int x, int y, Me
        float overallmultiplyerr = 0;
        float overallmultiplyerg = 0;
        float overallmultiplyerb = 0;
+       float overallmultiplyera = 0;
 
        int miny = y - maxBlur;
        int maxy = y + maxBlur;
@@ -74,16 +75,18 @@ void VariableSizeBokehBlurOperation::executePixel(float *color, int x, int y, Me
                tempColor[0] += readColor[0];
                tempColor[1] += readColor[1];
                tempColor[2] += readColor[2];
+               tempColor[3] += readColor[3];
                overallmultiplyerr += 1;
                overallmultiplyerg += 1;
                overallmultiplyerb += 1;
+               overallmultiplyera += 1;
                
                for (int ny = miny ; ny < maxy ; ny += QualityStepHelper::getStep()) {
                        for (int nx = minx ; nx < maxx ; nx += QualityStepHelper::getStep()) {
                                if (nx >=0 && nx < this->getWidth() && ny >= 0 && ny < getHeight()) {
                                        inputSizeProgram->read(tempSize, nx, ny, COM_PS_NEAREST, inputBuffers);
                                        float size = tempSize[0];
-                                       size += this->threshold;
+//                                     size += this->threshold;
                                        float dx = nx - x;
                                        float dy = ny - y;
                                        if (nx == x && ny == y) {
@@ -94,20 +97,22 @@ void VariableSizeBokehBlurOperation::executePixel(float *color, int x, int y, Me
                                                float v = 256 + dy*256/size;
                                                inputBokehProgram->read(bokeh, u, v, COM_PS_NEAREST, inputBuffers);
                                                inputProgram->read(readColor, nx, ny, COM_PS_NEAREST, inputBuffers);
-                                               tempColor[0] += bokeh[0] * readColor[0];
-                                               tempColor[1] += bokeh[1] * readColor[1];
-                                               tempColor[2] += bokeh[2]* readColor[2];
+                                               tempColor[0] += bokeh[1]*readColor[0];
+                                               tempColor[1] += bokeh[2]*readColor[1];
+                                               tempColor[2] += bokeh[2]*readColor[2];
+                                               tempColor[3] += bokeh[3]*readColor[3];
                                                overallmultiplyerr += bokeh[0];
                                                overallmultiplyerg += bokeh[1];
                                                overallmultiplyerb += bokeh[2];
+                                               overallmultiplyera += bokeh[3];
                                        }
                                }
                        }
                }
-               color[0] = tempColor[0] * (1.0f / overallmultiplyerr);
-               color[1] = tempColor[1] * (1.0f / overallmultiplyerg);
-               color[2] = tempColor[2] * (1.0f / overallmultiplyerb);
-               color[3] = 1.0f;
+               color[0] = tempColor[0] / overallmultiplyerr;
+               color[1] = tempColor[1] / overallmultiplyerg;
+               color[2] = tempColor[2] / overallmultiplyerb;
+               color[3] = tempColor[3] / overallmultiplyera;
        }
 
 }
index 222b879645cd0eb1f195e0b4fe0dfdb232fedd56..8888d30ba2fda11403454c1934a68939b18424b2 100644 (file)
@@ -175,3 +175,9 @@ void WriteBufferOperation::executeOpenCLRegion(cl_context context, cl_program pr
        }
        delete clKernelsToCleanUp;
 }
+
+void WriteBufferOperation::readResolutionFromInputSocket() {
+       NodeOperation* inputOperation = this->getInputOperation(0);
+       this->setWidth(inputOperation->getWidth());
+       this->setHeight(inputOperation->getHeight());
+}
index 6f2c49c49bd616c6106346429bfe5308e3236b16..068adc032934384a8869a8033b2271fff346e47a 100644 (file)
@@ -47,6 +47,7 @@ public:
        void deinitExecution();
        void setbNodeTree(const bNodeTree *tree) {this->tree = tree;}
        void executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, unsigned int chunkNumber, MemoryBuffer** memoryBuffers, MemoryBuffer* outputBuffer);
+       void readResolutionFromInputSocket();
 
 };
 #endif
index 1d42954a416778f699f6d0402cc05f589a0570fc..649266beec7bdda6c5745f5c05f09dce89387e0c 100644 (file)
@@ -69,9 +69,9 @@ struct ImBuf *ED_space_clip_get_stable_buffer(struct SpaceClip *sc, float loc[2]
 void ED_clip_update_frame(const struct Main *mainp, int cfra);
 int ED_clip_view_selection(struct SpaceClip *sc, struct ARegion *ar, int fit);
 
-void ED_clip_point_undistorted_pos(SpaceClip * sc, float co[2], float nco[2]);
+void ED_clip_point_undistorted_pos(SpaceClip * sc, const float co[2], float r_co[2]);
 void ED_clip_point_stable_pos(struct bContext *C, float x, float y, float *xr, float *yr);
-void ED_clip_point_stable_pos__reverse(SpaceClip * sc, ARegion *ar, float co[2], float nco[2]);
+void ED_clip_point_stable_pos__reverse(SpaceClip * sc, ARegion *ar, const float co[2], float r_co[2]);
 void ED_clip_mouse_pos(struct bContext *C, struct wmEvent *event, float co[2]);
 
 int ED_space_clip_texture_buffer_supported(struct SpaceClip *sc);
index 7b69e8204677cd8a187513f445c045e13671dfcc..22aa1031f481f25211d94b8867c2382dee95203a 100644 (file)
@@ -1550,7 +1550,8 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
                        IMB_freeImBuf(scopes->track_preview);
 
                tmpibuf = BKE_tracking_sample_pattern_imbuf(scopes->frame_width, scopes->frame_height,
-                                                           scopes->track_search, &scopes->undist_marker,
+                                                           scopes->track_search, scopes->track,
+                                                           &scopes->undist_marker, scopes->use_track_mask,
                                                            width, height, scopes->track_pos);
 
                if (tmpibuf->rect_float)
@@ -1582,6 +1583,12 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
                if (width > 0 && height > 0) {
                        drawibuf = scopes->track_preview;
 
+                       if (scopes->use_track_mask) {
+                               glColor4f(0.0f, 0.0f, 0.0f, 0.3f);
+                               uiSetRoundBox(15);
+                               uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f);
+                       }
+
                        glaDrawPixelsSafe(rect.xmin, rect.ymin + 1, drawibuf->x, drawibuf->y,
                                          drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect);
 
index a2adbd7a143aec7b1cb5cc65dc172214a65bae48..4615906b0dad8153b0cb402c18a14fb3b5a1596c 100644 (file)
@@ -4201,7 +4201,7 @@ static int ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonDa
                scopes->track_preview_height = (but->y2 - but->y1) + (data->dragstarty - my);
        }
        else {
-               if (scopes->marker) {
+               if (!scopes->track_locked) {
                        if (scopes->marker->framenr != scopes->framenr)
                                scopes->marker = BKE_tracking_ensure_marker(scopes->track, scopes->framenr);
 
index 67fd57ed50bd12d147110b7014d183dbc55bf6bd..7c94b79010c4d48947a6f386e5f69d8354a180b9 100644 (file)
@@ -758,11 +758,10 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event)
                                        }
                                }
 
-                               free_slide_point_data(op->customdata);
-
                                WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask);
                                DAG_id_tag_update(&data->mask->id, 0);
 
+                               free_slide_point_data(op->customdata); /* keep this last! */
                                return OPERATOR_FINISHED;
                        }
 
@@ -771,11 +770,10 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event)
                case ESCKEY:
                        cancel_slide_point(op->customdata);
 
-                       free_slide_point_data(op->customdata);
-
                        WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask);
                        DAG_id_tag_update(&data->mask->id, 0);
 
+                       free_slide_point_data(op->customdata); /* keep this last! */
                        return OPERATOR_CANCELLED;
        }
 
index a9b23d5b939c97eefd6191b2d8a394a6ce06b36f..655a09ec90c4c2ffbb85c7973108b6496bf8ad97 100644 (file)
@@ -1467,9 +1467,11 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d)
 
                                if (track) {
                                        int framenr = sc->user.framenr;
-                                       MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr);
-
-                                       glTranslatef(marker->pos[0], marker->pos[1], 0.0f);
+                                       /* don't get the exact marker since it may not exist for the frame */
+                                       MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
+                                       if (marker) {
+                                               glTranslatef(marker->pos[0], marker->pos[1], 0.0f);
+                                       }
                                }
                        }
 
index 504d96df0729893f5e44fce69421a5008d61afbd..b24ff58e590d818f909723095061c069ac6d4afe 100644 (file)
@@ -425,9 +425,9 @@ int ED_clip_view_selection(SpaceClip *sc, ARegion *ar, int fit)
        return TRUE;
 }
 
-void ED_clip_point_undistorted_pos(SpaceClip *sc, float co[2], float nco[2])
+void ED_clip_point_undistorted_pos(SpaceClip *sc, const float co[2], float r_co[2])
 {
-       copy_v2_v2(nco, co);
+       copy_v2_v2(r_co, co);
 
        if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
                MovieClip *clip = ED_space_clip(sc);
@@ -436,13 +436,13 @@ void ED_clip_point_undistorted_pos(SpaceClip *sc, float co[2], float nco[2])
 
                ED_space_clip_size(sc, &width, &height);
 
-               nco[0] *= width;
-               nco[1] *= height * aspy;
+               r_co[0] *= width;
+               r_co[1] *= height * aspy;
 
-               BKE_tracking_invert_intrinsics(&clip->tracking, nco, nco);
+               BKE_tracking_invert_intrinsics(&clip->tracking, r_co, r_co);
 
-               nco[0] /= width;
-               nco[1] /= height * aspy;
+               r_co[0] /= width;
+               r_co[1] /= height * aspy;
        }
 }
 
@@ -451,7 +451,7 @@ void ED_clip_point_stable_pos(bContext *C, float x, float y, float *xr, float *y
        ARegion *ar = CTX_wm_region(C);
        SpaceClip *sc = CTX_wm_space_clip(C);
        int sx, sy, width, height;
-       float zoomx, zoomy, pos[3] = {0.0f, 0.0f, 0.0f}, imat[4][4];
+       float zoomx, zoomy, pos[3], imat[4][4];
 
        ED_space_clip_zoom(sc, ar, &zoomx, &zoomy);
        ED_space_clip_size(sc, &width, &height);
@@ -460,6 +460,7 @@ void ED_clip_point_stable_pos(bContext *C, float x, float y, float *xr, float *y
 
        pos[0] = (x - sx) / zoomx;
        pos[1] = (y - sy) / zoomy;
+       pos[2] = 0.0f;
 
        invert_m4_m4(imat, sc->stabmat);
        mul_v3_m4v3(pos, imat, pos);
@@ -484,7 +485,7 @@ void ED_clip_point_stable_pos(bContext *C, float x, float y, float *xr, float *y
  * \brief the reverse of ED_clip_point_stable_pos(), gets the marker region coords.
  * better name here? view_to_track / track_to_view or so?
  */
-void ED_clip_point_stable_pos__reverse(SpaceClip *sc, ARegion *ar, float co[2], float nco[2])
+void ED_clip_point_stable_pos__reverse(SpaceClip *sc, ARegion *ar, const float co[2], float r_co[2])
 {
        float zoomx, zoomy;
        float pos[3];
@@ -496,12 +497,13 @@ void ED_clip_point_stable_pos__reverse(SpaceClip *sc, ARegion *ar, float co[2],
        ED_space_clip_zoom(sc, ar, &zoomx, &zoomy);
 
        ED_clip_point_undistorted_pos(sc, co, pos);
+       pos[2] = 0.0f;
 
        /* untested */
        mul_v3_m4v3(pos, sc->stabmat, pos);
 
-       nco[0] = (pos[0] * width  * zoomx) + (float)sx;
-       nco[1] = (pos[1] * height * zoomy) + (float)sy;
+       r_co[0] = (pos[0] * width  * zoomx) + (float)sx;
+       r_co[1] = (pos[1] * height * zoomy) + (float)sy;
 }
 
 void ED_clip_mouse_pos(bContext *C, wmEvent *event, float co[2])
index 6409ad6b17146004e8b766bfe21af7f7e2f8a399..9a8e0de3e84a1b4ffbae6b81fc6bc6a077121d95 100644 (file)
@@ -215,6 +215,15 @@ static void clip_scopes_tag_refresh(ScrArea *sa)
        sc->scopes.ok = FALSE;
 }
 
+static void clip_scopes_check_gpencil_change(ScrArea *sa)
+{
+       SpaceClip *sc = (SpaceClip *)sa->spacedata.first;
+
+       if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
+               clip_scopes_tag_refresh(sa);
+       }
+}
+
 static void clip_stabilization_tag_refresh(ScrArea *sa)
 {
        SpaceClip *sc = (SpaceClip *) sa->spacedata.first;
@@ -400,6 +409,7 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn)
                        switch (wmn->data) {
                                case ND_ANIMPLAY:
                                case ND_GPENCIL:
+                                       clip_scopes_check_gpencil_change(sa);
                                        ED_area_tag_redraw(sa);
                                        break;
                        }
@@ -1101,9 +1111,6 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar)
 
        clip_draw_main(sc, ar, scene);
 
-       /* Grease Pencil */
-       clip_draw_grease_pencil((bContext *)C, 1);
-
        if (sc->mode == SC_MODE_MASKEDIT) {
                int x, y;
                int width, height;
@@ -1147,6 +1154,9 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar)
                glPopMatrix();
        }
 
+       /* Grease Pencil */
+       clip_draw_grease_pencil((bContext *)C, 1);
+
        /* reset view matrix */
        UI_view2d_view_restore(C);
 
index b4e07546fa91d4a221967571e5f42316ba408ffa..81e375f26bc7f79a9b6bdae6990c34c006cc68d8 100644 (file)
 #include "DNA_particle_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_world_types.h"
+#include "DNA_action_types.h"
+#include "DNA_anim_types.h"
 
 #include "BLI_math.h"
 #include "BLI_blenlib.h"
 #include "BLI_utildefines.h"
 
+#include "BKE_action.h"
+#include "BKE_animsys.h"
 #include "BKE_context.h"
 #include "BKE_depsgraph.h"
 #include "BKE_global.h"
@@ -94,6 +98,7 @@
 #include "GPU_material.h"
 
 #include "node_intern.h"
+#include "NOD_socket.h"
 
 static EnumPropertyItem socket_in_out_items[] = {
        { SOCK_IN, "SOCK_IN", 0, "Input", "" },
@@ -1109,6 +1114,155 @@ void NODE_OT_group_socket_move_down(wmOperatorType *ot)
 
 /* ******************** Ungroup operator ********************** */
 
+/* returns 1 if its OK */
+static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
+{
+       bNodeLink *link, *linkn;
+       bNode *node, *nextn;
+       bNodeTree *ngroup, *wgroup;
+       ListBase anim_basepaths = {NULL, NULL};
+       
+       ngroup= (bNodeTree *)gnode->id;
+       if (ngroup==NULL) return 0;
+       
+       /* clear new pointers, set in copytree */
+       for (node= ntree->nodes.first; node; node= node->next)
+               node->new_node= NULL;
+       
+       /* wgroup is a temporary copy of the NodeTree we're merging in
+        *      - all of wgroup's nodes are transferred across to their new home
+        *      - ngroup (i.e. the source NodeTree) is left unscathed
+        */
+       wgroup= ntreeCopyTree(ngroup);
+       
+       /* add the nodes into the ntree */
+       for (node= wgroup->nodes.first; node; node= nextn) {
+               nextn= node->next;
+               
+               /* keep track of this node's RNA "base" path (the part of the path identifying the node) 
+                * if the old nodetree has animation data which potentially covers this node
+                */
+               if (wgroup->adt) {
+                       PointerRNA ptr;
+                       char *path;
+                       
+                       RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr);
+                       path = RNA_path_from_ID_to_struct(&ptr);
+                       
+                       if (path)
+                               BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
+               }
+               
+               /* migrate node */
+               BLI_remlink(&wgroup->nodes, node);
+               BLI_addtail(&ntree->nodes, node);
+               
+               node->locx += gnode->locx;
+               node->locy += gnode->locy;
+               
+               node->flag |= NODE_SELECT;
+       }
+       
+       /* restore external links to and from the gnode */
+       for (link= ntree->links.first; link; link= link->next) {
+               if (link->fromnode==gnode) {
+                       if (link->fromsock->groupsock) {
+                               bNodeSocket *gsock= link->fromsock->groupsock;
+                               if (gsock->link) {
+                                       if (gsock->link->fromnode) {
+                                               /* NB: using the new internal copies here! the groupsock pointer still maps to the old tree */
+                                               link->fromnode = (gsock->link->fromnode ? gsock->link->fromnode->new_node : NULL);
+                                               link->fromsock = gsock->link->fromsock->new_sock;
+                                       }
+                                       else {
+                                               /* group output directly maps to group input */
+                                               bNodeSocket *insock= node_group_find_input(gnode, gsock->link->fromsock);
+                                               if (insock->link) {
+                                                       link->fromnode = insock->link->fromnode;
+                                                       link->fromsock = insock->link->fromsock;
+                                               }
+                                       }
+                               }
+                               else {
+                                       /* copy the default input value from the group socket default to the external socket */
+                                       node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, gsock->type, gsock->default_value);
+                               }
+                       }
+               }
+       }
+       /* remove internal output links, these are not used anymore */
+       for (link=wgroup->links.first; link; link= linkn) {
+               linkn = link->next;
+               if (!link->tonode)
+                       nodeRemLink(wgroup, link);
+       }
+       /* restore links from internal nodes */
+       for (link= wgroup->links.first; link; link= link->next) {
+               /* indicates link to group input */
+               if (!link->fromnode) {
+                       /* NB: can't use find_group_node_input here,
+                        * because gnode sockets still point to the old tree!
+                        */
+                       bNodeSocket *insock;
+                       for (insock= gnode->inputs.first; insock; insock= insock->next)
+                               if (insock->groupsock->new_sock == link->fromsock)
+                                       break;
+                       if (insock->link) {
+                               link->fromnode = insock->link->fromnode;
+                               link->fromsock = insock->link->fromsock;
+                       }
+                       else {
+                               /* copy the default input value from the group node socket default to the internal socket */
+                               node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, insock->type, insock->default_value);
+                               nodeRemLink(wgroup, link);
+                       }
+               }
+       }
+       
+       /* add internal links to the ntree */
+       for (link= wgroup->links.first; link; link= linkn) {
+               linkn= link->next;
+               BLI_remlink(&wgroup->links, link);
+               BLI_addtail(&ntree->links, link);
+       }
+       
+       /* and copy across the animation,
+        * note that the animation data's action can be NULL here */
+       if (wgroup->adt) {
+               LinkData *ld, *ldn=NULL;
+               bAction *waction;
+               
+               /* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */
+               waction = wgroup->adt->action = BKE_action_copy(wgroup->adt->action);
+               
+               /* now perform the moving */
+               BKE_animdata_separate_by_basepath(&wgroup->id, &ntree->id, &anim_basepaths);
+               
+               /* paths + their wrappers need to be freed */
+               for (ld = anim_basepaths.first; ld; ld = ldn) {
+                       ldn = ld->next;
+                       
+                       MEM_freeN(ld->data);
+                       BLI_freelinkN(&anim_basepaths, ld);
+               }
+               
+               /* free temp action too */
+               if (waction) {
+                       BKE_libblock_free(&G.main->action, waction);
+               }
+       }
+       
+       /* delete the group instance. this also removes old input links! */
+       nodeFreeNode(ntree, gnode);
+
+       /* free the group tree (takes care of user count) */
+       BKE_libblock_free(&G.main->nodetree, wgroup);
+       
+       ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
+       
+       return 1;
+}
+
 static int node_group_ungroup_exec(bContext *C, wmOperator *op)
 {
        SpaceNode *snode = CTX_wm_space_node(C);
@@ -1129,7 +1283,10 @@ static int node_group_ungroup_exec(bContext *C, wmOperator *op)
                BKE_report(op->reports, RPT_WARNING, "Not a group");
                return OPERATOR_CANCELLED;
        }
-       else if (!node_group_ungroup(snode->edittree, gnode)) {
+       else if (node_group_ungroup(snode->nodetree, gnode)) {
+               ntreeUpdateTree(snode->nodetree);
+       }
+       else {
                BKE_report(op->reports, RPT_WARNING, "Can't ungroup");
                return OPERATOR_CANCELLED;
        }
@@ -1155,6 +1312,200 @@ void NODE_OT_group_ungroup(wmOperatorType *ot)
        ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+/* ******************** Separate operator ********************** */
+
+/* returns 1 if its OK */
+static int node_group_separate_selected(bNodeTree *ntree, bNode *gnode, int make_copy)
+{
+       bNodeLink *link, *link_next;
+       bNode *node, *node_next, *newnode;
+       bNodeTree *ngroup;
+       ListBase anim_basepaths = {NULL, NULL};
+       
+       ngroup= (bNodeTree *)gnode->id;
+       if (ngroup==NULL) return 0;
+       
+       /* deselect all nodes in the target tree */
+       for (node=ntree->nodes.first; node; node=node->next)
+               node_deselect(node);
+       
+       /* clear new pointers, set in nodeCopyNode */
+       for (node= ngroup->nodes.first; node; node= node->next)
+               node->new_node= NULL;
+       
+       /* add selected nodes into the ntree */
+       for (node= ngroup->nodes.first; node; node= node_next) {
+               node_next = node->next;
+               if (!(node->flag & NODE_SELECT))
+                       continue;
+               
+               if (make_copy) {
+                       /* make a copy */
+                       newnode = nodeCopyNode(ngroup, node);
+               }
+               else {
+                       /* use the existing node */
+                       newnode = node;
+               }
+               
+               /* keep track of this node's RNA "base" path (the part of the path identifying the node) 
+                * if the old nodetree has animation data which potentially covers this node
+                */
+               if (ngroup->adt) {
+                       PointerRNA ptr;
+                       char *path;
+                       
+                       RNA_pointer_create(&ngroup->id, &RNA_Node, newnode, &ptr);
+                       path = RNA_path_from_ID_to_struct(&ptr);
+                       
+                       if (path)
+                               BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
+               }
+               
+               /* ensure valid parent pointers, detach if parent stays inside the group */
+               if (newnode->parent && !(newnode->parent->flag & NODE_SELECT))
+                       nodeDetachNode(newnode);
+               
+               /* migrate node */
+               BLI_remlink(&ngroup->nodes, newnode);
+               BLI_addtail(&ntree->nodes, newnode);
+               
+               newnode->locx += gnode->locx;
+               newnode->locy += gnode->locy;
+       }
+       
+       /* add internal links to the ntree */
+       for (link= ngroup->links.first; link; link= link_next) {
+               int fromselect = (link->fromnode && (link->fromnode->flag & NODE_SELECT));
+               int toselect = (link->tonode && (link->tonode->flag & NODE_SELECT));
+               link_next = link->next;
+               
+               if (make_copy) {
+                       /* make a copy of internal links */
+                       if (fromselect && toselect)
+                               nodeAddLink(ntree, link->fromnode->new_node, link->fromsock->new_sock, link->tonode->new_node, link->tosock->new_sock);
+               }
+               else {
+                       /* move valid links over, delete broken links */
+                       if (fromselect && toselect) {
+                               BLI_remlink(&ngroup->links, link);
+                               BLI_addtail(&ntree->links, link);
+                       }
+                       else if (fromselect || toselect) {
+                               nodeRemLink(ngroup, link);
+                       }
+               }
+       }
+       
+       /* and copy across the animation,
+        * note that the animation data's action can be NULL here */
+       if (ngroup->adt) {
+               LinkData *ld, *ldn=NULL;
+               
+               /* now perform the moving */
+               BKE_animdata_separate_by_basepath(&ngroup->id, &ntree->id, &anim_basepaths);
+               
+               /* paths + their wrappers need to be freed */
+               for (ld = anim_basepaths.first; ld; ld = ldn) {
+                       ldn = ld->next;
+                       
+                       MEM_freeN(ld->data);
+                       BLI_freelinkN(&anim_basepaths, ld);
+               }
+       }
+       
+       ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
+       if (!make_copy)
+               ngroup->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
+       
+       return 1;
+}
+
+typedef enum eNodeGroupSeparateType {
+       NODE_GS_COPY,
+       NODE_GS_MOVE
+} eNodeGroupSeparateType;
+
+/* Operator Property */
+EnumPropertyItem node_group_separate_types[] = {
+    {NODE_GS_COPY, "COPY", 0, "Copy", "Copy to parent node tree, keep group intact"},
+       {NODE_GS_MOVE, "MOVE", 0, "Move", "Move to parent node tree, remove from group"},
+       {0, NULL, 0, NULL, NULL}
+};
+
+static int node_group_separate_exec(bContext *C, wmOperator *op)
+{
+       SpaceNode *snode = CTX_wm_space_node(C);
+       bNode *gnode;
+       int type = RNA_enum_get(op->ptr, "type");
+
+       ED_preview_kill_jobs(C);
+
+       /* are we inside of a group? */
+       gnode= node_tree_get_editgroup(snode->nodetree);
+       if (!gnode) {
+               BKE_report(op->reports, RPT_WARNING, "Not inside node group");
+               return OPERATOR_CANCELLED;
+       }
+       
+       switch (type) {
+       case NODE_GS_COPY:
+               if (!node_group_separate_selected(snode->nodetree, gnode, 1)) {
+                       BKE_report(op->reports, RPT_WARNING, "Can't separate nodes");
+                       return OPERATOR_CANCELLED;
+               }
+               break;
+       case NODE_GS_MOVE:
+               if (!node_group_separate_selected(snode->nodetree, gnode, 0)) {
+                       BKE_report(op->reports, RPT_WARNING, "Can't separate nodes");
+                       return OPERATOR_CANCELLED;
+               }
+               break;
+       }
+       
+       /* switch to parent tree */
+       snode_make_group_editable(snode, NULL);
+       
+       ntreeUpdateTree(snode->nodetree);
+       
+       snode_notify(C, snode);
+       snode_dag_update(C, snode);
+
+       return OPERATOR_FINISHED;
+}
+
+static int node_group_separate_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+{
+       uiPopupMenu *pup = uiPupMenuBegin(C, "Separate", ICON_NONE);
+       uiLayout *layout = uiPupMenuLayout(pup);
+       
+       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
+       uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_COPY);
+       uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_MOVE);
+       
+       uiPupMenuEnd(C, pup);
+       
+       return OPERATOR_CANCELLED;
+}
+
+void NODE_OT_group_separate(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Separate";
+       ot->description = "Separate selected nodes from the node group";
+       ot->idname = "NODE_OT_group_separate";
+       
+       /* api callbacks */
+       ot->invoke = node_group_separate_invoke;
+       ot->exec = node_group_separate_exec;
+       ot->poll = ED_operator_node_active;
+       
+       /* flags */
+       ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+       
+       RNA_def_enum(ot->srna, "type", node_group_separate_types, NODE_GS_COPY, "Type", "");
+}
+
 /* ************************** Node generic ************** */
 
 /* is rct in visible part of node? */
@@ -3249,10 +3600,219 @@ void NODE_OT_render_changed(wmOperatorType *ot)
 
 /* ****************** Make Group operator ******************* */
 
+static int node_group_make_test(bNodeTree *ntree, bNode *gnode)
+{
+       bNode *node;
+       bNodeLink *link;
+       int totnode = 0;
+       
+       /* is there something to group? also do some clearing */
+       for (node= ntree->nodes.first; node; node= node->next) {
+               if (node == gnode)
+                       continue;
+               
+               if (node->flag & NODE_SELECT) {
+                       /* no groups in groups */
+                       if (node->type==NODE_GROUP)
+                               return 0;
+                       totnode++;
+               }
+               
+               node->done = 0;
+       }
+       if (totnode==0) return 0;
+       
+       /* check if all connections are OK, no unselected node has both
+        * inputs and outputs to a selection */
+       for (link= ntree->links.first; link; link= link->next) {
+               if (link->fromnode && link->tonode && link->fromnode->flag & NODE_SELECT && link->fromnode != gnode)
+                       link->tonode->done |= 1;
+               if (link->fromnode && link->tonode && link->tonode->flag & NODE_SELECT && link->tonode != gnode)
+                       link->fromnode->done |= 2;
+       }
+       
+       for (node= ntree->nodes.first; node; node= node->next) {
+               if (node == gnode)
+                       continue;
+               if ((node->flag & NODE_SELECT)==0)
+                       if (node->done==3)
+                               break;
+       }
+       if (node) 
+               return 0;
+       
+       return 1;
+}
+
+static void node_get_selected_minmax(bNodeTree *ntree, bNode *gnode, float *min, float *max)
+{
+       bNode *node;
+       INIT_MINMAX2(min, max);
+       for (node= ntree->nodes.first; node; node= node->next) {
+               if (node == gnode)
+                       continue;
+               if (node->flag & NODE_SELECT) {
+                       DO_MINMAX2((&node->locx), min, max);
+               }
+       }
+}
+
+static int node_group_make_insert_selected(bNodeTree *ntree, bNode *gnode)
+{
+       bNodeTree *ngroup = (bNodeTree *)gnode->id;
+       bNodeLink *link, *linkn;
+       bNode *node, *nextn;
+       bNodeSocket *gsock;
+       ListBase anim_basepaths = {NULL, NULL};
+       float min[2], max[2];
+       
+       /* deselect all nodes in the target tree */
+       for (node = ngroup->nodes.first; node; node=node->next)
+               node_deselect(node);
+       
+       node_get_selected_minmax(ntree, gnode, min, max);
+       
+       /* move nodes over */
+       for (node= ntree->nodes.first; node; node= nextn) {
+               nextn= node->next;
+               if (node == gnode)
+                       continue;
+               if (node->flag & NODE_SELECT) {
+                       /* keep track of this node's RNA "base" path (the part of the pat identifying the node) 
+                        * if the old nodetree has animation data which potentially covers this node
+                        */
+                       if (ntree->adt) {
+                               PointerRNA ptr;
+                               char *path;
+                               
+                               RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
+                               path = RNA_path_from_ID_to_struct(&ptr);
+                               
+                               if (path)
+                                       BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
+                       }
+                       
+                       /* ensure valid parent pointers, detach if parent stays outside the group */
+                       if (node->parent && !(node->parent->flag & NODE_SELECT))
+                               nodeDetachNode(node);
+                       
+                       /* change node-collection membership */
+                       BLI_remlink(&ntree->nodes, node);
+                       BLI_addtail(&ngroup->nodes, node);
+                       
+                       node->locx-= 0.5f*(min[0]+max[0]);
+                       node->locy-= 0.5f*(min[1]+max[1]);
+               }
+       }
+
+       /* move animation data over */
+       if (ntree->adt) {
+               LinkData *ld, *ldn=NULL;
+               
+               BKE_animdata_separate_by_basepath(&ntree->id, &ngroup->id, &anim_basepaths);
+               
+               /* paths + their wrappers need to be freed */
+               for (ld = anim_basepaths.first; ld; ld = ldn) {
+                       ldn = ld->next;
+                       
+                       MEM_freeN(ld->data);
+                       BLI_freelinkN(&anim_basepaths, ld);
+               }
+       }
+       
+       /* node groups don't use internal cached data */
+       ntreeFreeCache(ngroup);
+       
+       /* relink external sockets */
+       for (link= ntree->links.first; link; link= linkn) {
+               int fromselect = (link->fromnode && (link->fromnode->flag & NODE_SELECT) && link->fromnode != gnode);
+               int toselect = (link->tonode && (link->tonode->flag & NODE_SELECT) && link->tonode != gnode);
+               linkn= link->next;
+               
+               if (gnode && ((fromselect && link->tonode == gnode) || (toselect && link->fromnode == gnode))) {
+                       /* remove all links to/from the gnode.
+                        * this can remove link information, but there's no general way to preserve it.
+                        */
+                       nodeRemLink(ntree, link);
+               }
+               else if (fromselect && toselect) {
+                       BLI_remlink(&ntree->links, link);
+                       BLI_addtail(&ngroup->links, link);
+               }
+               else if (toselect) {
+                       gsock = node_group_expose_socket(ngroup, link->tosock, SOCK_IN);
+                       link->tosock->link = nodeAddLink(ngroup, NULL, gsock, link->tonode, link->tosock);
+                       link->tosock = node_group_add_extern_socket(ntree, &gnode->inputs, SOCK_IN, gsock);
+                       link->tonode = gnode;
+               }
+               else if (fromselect) {
+                       /* search for existing group node socket */
+                       for (gsock=ngroup->outputs.first; gsock; gsock=gsock->next)
+                               if (gsock->link && gsock->link->fromsock==link->fromsock)
+                                       break;
+                       if (!gsock) {
+                               gsock = node_group_expose_socket(ngroup, link->fromsock, SOCK_OUT);
+                               gsock->link = nodeAddLink(ngroup, link->fromnode, link->fromsock, NULL, gsock);
+                               link->fromsock = node_group_add_extern_socket(ntree, &gnode->outputs, SOCK_OUT, gsock);
+                       }
+                       else
+                               link->fromsock = node_group_find_output(gnode, gsock);
+                       link->fromnode = gnode;
+               }
+       }
+
+       /* update of the group tree */
+       ngroup->update |= NTREE_UPDATE;
+       /* update of the tree containing the group instance node */
+       ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
+
+       return 1;
+}
+
+static bNode *node_group_make_from_selected(bNodeTree *ntree)
+{
+       bNode *gnode;
+       bNodeTree *ngroup;
+       float min[2], max[2];
+       bNodeTemplate ntemp;
+       
+       node_get_selected_minmax(ntree, NULL, min, max);
+       
+       /* new nodetree */
+       ngroup= ntreeAddTree("NodeGroup", ntree->type, NODE_GROUP);
+       
+       /* make group node */
+       ntemp.type = NODE_GROUP;
+       ntemp.ngroup = ngroup;
+       gnode= nodeAddNode(ntree, &ntemp);
+       gnode->locx= 0.5f*(min[0]+max[0]);
+       gnode->locy= 0.5f*(min[1]+max[1]);
+       
+       node_group_make_insert_selected(ntree, gnode);
+
+       /* update of the tree containing the group instance node */
+       ntree->update |= NTREE_UPDATE_NODES;
+
+       return gnode;
+}
+
+typedef enum eNodeGroupMakeType {
+       NODE_GM_NEW,
+       NODE_GM_INSERT
+} eNodeGroupMakeType;
+
+/* Operator Property */
+EnumPropertyItem node_group_make_types[] = {
+       {NODE_GM_NEW, "NEW", 0, "New", "Create a new node group from selected nodes"},
+       {NODE_GM_INSERT, "INSERT", 0, "Insert", "Insert into active node group"},
+       {0, NULL, 0, NULL, NULL}
+};
+
 static int node_group_make_exec(bContext *C, wmOperator *op)
 {
        SpaceNode *snode = CTX_wm_space_node(C);
        bNode *gnode;
+       int type = RNA_enum_get(op->ptr, "type");
        
        if (snode->edittree!=snode->nodetree) {
                BKE_report(op->reports, RPT_WARNING, "Can not add a new Group in a Group");
@@ -3272,25 +3832,70 @@ static int node_group_make_exec(bContext *C, wmOperator *op)
                        return OPERATOR_CANCELLED;
                }
        }
-
-       ED_preview_kill_jobs(C);
        
-       gnode= node_group_make_from_selected(snode->nodetree);
-       if (gnode==NULL) {
-               BKE_report(op->reports, RPT_WARNING, "Can not make Group");
-               return OPERATOR_CANCELLED;
+       ED_preview_kill_jobs(C);
+
+       switch (type) {
+       case NODE_GM_NEW:
+               if (node_group_make_test(snode->nodetree, NULL)) {
+                       gnode = node_group_make_from_selected(snode->nodetree);
+               }
+               else {
+                       BKE_report(op->reports, RPT_WARNING, "Can not make Group");
+                       return OPERATOR_CANCELLED;
+               }
+               break;
+       case NODE_GM_INSERT:
+               gnode = nodeGetActive(snode->nodetree);
+               if (!gnode || gnode->type != NODE_GROUP) {
+                       BKE_report(op->reports, RPT_WARNING, "No active Group node");
+                       return OPERATOR_CANCELLED;
+               }
+               if (node_group_make_test(snode->nodetree, gnode)) {
+                       node_group_make_insert_selected(snode->nodetree, gnode);
+               }
+               else {
+                       BKE_report(op->reports, RPT_WARNING, "Can not insert into Group");
+                       return OPERATOR_CANCELLED;
+               }
+               break;
        }
-       else {
+
+       if (gnode) {
                nodeSetActive(snode->nodetree, gnode);
-               ntreeUpdateTree(snode->nodetree);
+               snode_make_group_editable(snode, gnode);
        }
        
+       if (gnode)
+               ntreeUpdateTree((bNodeTree *)gnode->id);
+       ntreeUpdateTree(snode->nodetree);
+
        snode_notify(C, snode);
        snode_dag_update(C, snode);
        
        return OPERATOR_FINISHED;
 }
 
+static int node_group_make_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+{
+       SpaceNode *snode = CTX_wm_space_node(C);
+       bNode *act = nodeGetActive(snode->edittree);
+       uiPopupMenu *pup = uiPupMenuBegin(C, "Make Group", ICON_NONE);
+       uiLayout *layout = uiPupMenuLayout(pup);
+       
+       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
+       uiItemEnumO(layout, "NODE_OT_group_make", NULL, 0, "type", NODE_GM_NEW);
+       
+       /* if active node is a group, add insert option */
+       if (act && act->type == NODE_GROUP) {
+               uiItemEnumO(layout, "NODE_OT_group_make", NULL, 0, "type", NODE_GM_INSERT);
+       }
+       
+       uiPupMenuEnd(C, pup);
+       
+       return OPERATOR_CANCELLED;
+}
+
 void NODE_OT_group_make(wmOperatorType *ot)
 {
        /* identifiers */
@@ -3299,11 +3904,14 @@ void NODE_OT_group_make(wmOperatorType *ot)
        ot->idname = "NODE_OT_group_make";
        
        /* api callbacks */
+       ot->invoke = node_group_make_invoke;
        ot->exec = node_group_make_exec;
        ot->poll = ED_operator_node_active;
        
        /* flags */
        ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+       
+       RNA_def_enum(ot->srna, "type", node_group_make_types, NODE_GM_NEW, "Type", "");
 }
 
 /* ****************** Hide operator *********************** */
index 9e873799f1c85dc3bfbf70eddbfb69846fc90a2f..d9dbd646fa52b7daa5fdabb7fc85040d088ca5d4 100644 (file)
@@ -149,6 +149,7 @@ void NODE_OT_add_reroute(struct wmOperatorType *ot);
 
 void NODE_OT_group_make(struct wmOperatorType *ot);
 void NODE_OT_group_ungroup(struct wmOperatorType *ot);
+void NODE_OT_group_separate(struct wmOperatorType *ot);
 void NODE_OT_group_edit(struct wmOperatorType *ot);
 void NODE_OT_group_socket_add(struct wmOperatorType *ot);
 void NODE_OT_group_socket_remove(struct wmOperatorType *ot);
index 8a977d2f112e6ad5fc7fb94a39beff08efa5f492..ff1661f03271f0ee7708bb88e77661f600681920 100644 (file)
@@ -83,6 +83,7 @@ void node_operatortypes(void)
 
        WM_operatortype_append(NODE_OT_group_make);
        WM_operatortype_append(NODE_OT_group_ungroup);
+       WM_operatortype_append(NODE_OT_group_separate);
        WM_operatortype_append(NODE_OT_group_edit);
        WM_operatortype_append(NODE_OT_group_socket_add);
        WM_operatortype_append(NODE_OT_group_socket_remove);
@@ -269,6 +270,7 @@ void node_keymap(struct wmKeyConfig *keyconf)
 
        WM_keymap_add_item(keymap, "NODE_OT_group_make", GKEY, KM_PRESS, KM_CTRL, 0);
        WM_keymap_add_item(keymap, "NODE_OT_group_ungroup", GKEY, KM_PRESS, KM_ALT, 0);
+       WM_keymap_add_item(keymap, "NODE_OT_group_separate", PKEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "NODE_OT_group_edit", TABKEY, KM_PRESS, 0, 0);
        
        WM_keymap_add_item(keymap, "NODE_OT_read_renderlayers", RKEY, KM_PRESS, KM_CTRL, 0);
index c477e2bcdda84ec296a4bb3cf2169e49ffc67406..e069ba2a5fc3e4653d34ec985d7b5f4f202c3ea7 100644 (file)
@@ -492,16 +492,11 @@ static int node_context(const bContext *C, const char *member, bContextDataResul
                return 1;
        }
        else if (CTX_data_equals(member, "active_node")) {
-               bNode *node;
-               
                if (snode->edittree) {
-                       for (node=snode->edittree->nodes.last; node; node=node->prev) {
-                               if (node->flag & NODE_ACTIVE) {
-                                       CTX_data_pointer_set(result, &snode->edittree->id, &RNA_Node, node);
-                                       break;
-                               }
-                       }
+                       bNode *node = nodeGetActive(snode->edittree);
+                       CTX_data_pointer_set(result, &snode->edittree->id, &RNA_Node, node);
                }
+
                CTX_data_type_set(result, CTX_DATA_TYPE_POINTER);
                return 1;
        }
index 89976699114586ba79d069a19e16e61bbade162c..438cfd6b741d6691f5dc8231255dfdbd35831a4f 100644 (file)
@@ -112,6 +112,9 @@ void GPU_paint_set_mipmap(int mipmap);
 void GPU_set_anisotropic(float value);
 float GPU_get_anisotropic(void);
 
+/* enable gpu mipmapping */
+void GPU_set_gpu_mipmapping(int gpu_mipmap);
+
 /* Image updates and free
  * - these deal with images bound as opengl textures */
 
index 3e53f2f3836d62759f336bb16ddebe05d5f06d09..a1bd8dcb3a39bb6260235f4da67e3b48a5bd4227 100644 (file)
@@ -234,11 +234,23 @@ static struct GPUTextureState {
 
        int alphablend;
        float anisotropic;
+       int gpu_mipmap;
        MTFace *lasttface;
-} GTS = {0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 1, 0, 0, -1, 1.f, NULL};
+} GTS = {0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 1, 0, 0, -1, 1.f, 0, NULL};
 
 /* Mipmap settings */
 
+void GPU_set_gpu_mipmapping(int gpu_mipmap){
+       int old_value = GTS.gpu_mipmap;
+
+       /* only actually enable if it's supported */
+       GTS.gpu_mipmap = gpu_mipmap && GLEW_EXT_framebuffer_object;
+
+       if(old_value != GTS.gpu_mipmap) {
+               GPU_free_images();
+       }
+}
+
 void GPU_set_mipmap(int mipmap)
 {
        if (GTS.domipmap != (mipmap != 0)) {
@@ -632,10 +644,19 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
        }
        else {
-               if (use_high_bit_depth)
-                       gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA16, rectw, recth, GL_RGBA, GL_FLOAT, frect);
-               else
-                       gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+               if(GTS.gpu_mipmap) {
+                       if (use_high_bit_depth)
+                               glTexImage2D(GL_TEXTURE_2D, 0,  GL_RGBA16,  rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
+                       else
+                               glTexImage2D(GL_TEXTURE_2D, 0,  GL_RGBA,  rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+
+                       glGenerateMipmapEXT(GL_TEXTURE_2D);
+               } else {
+                       if (use_high_bit_depth)
+                               gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA16, rectw, recth, GL_RGBA, GL_FLOAT, frect);
+                       else
+                               gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+               }
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
 
index 279fd5d59be99960b15c0e8b5ddc6fccffda7226..1b68c520336e93b7112b00e9280911e4490b418b 100644 (file)
@@ -538,12 +538,16 @@ void IMB_rect_from_float(ImBuf *ibuf)
                imb_addrectImBuf(ibuf);
 
        /* determine profiles */
-       if (ibuf->profile == IB_PROFILE_LINEAR_RGB)
+       if (ibuf->profile == IB_PROFILE_LINEAR_RGB) {
                profile_from = IB_PROFILE_LINEAR_RGB;
-       else if (ELEM(ibuf->profile, IB_PROFILE_SRGB, IB_PROFILE_NONE))
+       }
+       else if (ELEM(ibuf->profile, IB_PROFILE_SRGB, IB_PROFILE_NONE)) {
                profile_from = IB_PROFILE_SRGB;
-       else
+       }
+       else {
+               profile_from = IB_PROFILE_SRGB; /* should never happen */
                BLI_assert(0);
+       }
 
        /* do conversion */
        IMB_buffer_byte_from_float((uchar *)ibuf->rect, ibuf->rect_float,
@@ -571,12 +575,16 @@ void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w
                imb_addrectImBuf(ibuf);
 
        /* determine profiles */
-       if (ibuf->profile == IB_PROFILE_LINEAR_RGB)
+       if (ibuf->profile == IB_PROFILE_LINEAR_RGB) {
                profile_from = IB_PROFILE_LINEAR_RGB;
-       else if (ELEM(ibuf->profile, IB_PROFILE_SRGB, IB_PROFILE_NONE))
+       }
+       else if (ELEM(ibuf->profile, IB_PROFILE_SRGB, IB_PROFILE_NONE)) {
                profile_from = IB_PROFILE_SRGB;
-       else
+       }
+       else {
+               profile_from = IB_PROFILE_SRGB; /* should never happen */
                BLI_assert(0);
+       }
 
        /* do conversion */
        rect_float = ibuf->rect_float + (x + y * ibuf->x) * ibuf->channels;
index 7d1d5906dd8cb72572f8c1b1367aee7b6a36ae10..a5826634724e97c1750bd75c367da19b8ffa6454 100644 (file)
@@ -43,6 +43,7 @@
 static char JP2_HEAD[] = {0x0, 0x0, 0x0, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A};
 
 /* We only need this because of how the presets are set */
+/* this typedef is copied from 'openjpeg-1.5.0/applications/codec/image_to_j2k.c' */
 typedef struct img_folder {
        /** The directory path of the folder containing input images*/
        char *imgdirpath;
@@ -92,27 +93,35 @@ static void info_callback(const char *msg, void *client_data)
        fprintf(stdout, "[INFO] %s", msg);
 }
 
+#   define PIXEL_LOOPER_BEGIN(_rect)                                          \
+       for (y = h - 1; y != (unsigned int)(-1); y--) {                           \
+               for (i = y * w, i_next = (y + 1) * w;                                 \
+                    i < i_next;                                                      \
+                    i++, _rect += 4)                                                 \
+               {                                                                     \
 
+#   define PIXEL_LOOPER_END \
+       } \
+       } (void)0 \
 
 struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags)
 {
        struct ImBuf *ibuf = NULL;
        int use_float = FALSE; /* for precision higher then 8 use float */
+       int use_alpha = FALSE;
        
        long signed_offsets[4] = {0, 0, 0, 0};
        int float_divs[4] = {1, 1, 1, 1};
 
-       int index;
-       
-       int w, h, planes;
+       unsigned int i, i_next, w, h, planes;
+       unsigned int y;
+       int *r, *g, *b, *a; /* matching 'opj_image_comp.data' type */
        
        opj_dparameters_t parameters;   /* decompression parameters */
        
        opj_event_mgr_t event_mgr;      /* event manager */
        opj_image_t *image = NULL;
-       
-       int i;
-       
+
        opj_dinfo_t *dinfo = NULL;  /* handle to a decompressor */
        opj_cio_t *cio = NULL;
 
@@ -169,9 +178,11 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags)
                case 1: /* Greyscale */
                case 3: /* Color */
                        planes = 24;
+                       use_alpha = FALSE;
                        break;
                default: /* 2 or 4 - Greyscale or Color + alpha */
                        planes = 32; /* greyscale + alpha */
+                       use_alpha = TRUE;
                        break;
        }
        
@@ -206,64 +217,102 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags)
                float *rect_float = ibuf->rect_float;
 
                if (image->numcomps < 3) {
+                       r = image->comps[0].data;
+                       a = (use_alpha) ? image->comps[1].data : NULL;
+
                        /* greyscale 12bits+ */
-                       for (i = 0; i < w * h; i++, rect_float += 4) {
-                               index = w * h - ((i) / (w) + 1) * w + (i) % (w);
-                               
-                               rect_float[0] = rect_float[1] = rect_float[2] = (float)(image->comps[0].data[index] + signed_offsets[0]) / float_divs[0];
-                               
-                               if (image->numcomps == 2)
-                                       rect_float[3] = (image->comps[1].data[index] + signed_offsets[1]) / float_divs[1];
-                               else
+                       if (use_alpha) {
+                               a = image->comps[1].data;
+                               PIXEL_LOOPER_BEGIN(rect_float) {
+                                       rect_float[0] = rect_float[1] = rect_float[2] = (float)(r[i] + signed_offsets[0]) / float_divs[0];
+                                       rect_float[3] = (a[i] + signed_offsets[1]) / float_divs[1];
+                               }
+                               PIXEL_LOOPER_END;
+                       }
+                       else {
+                               PIXEL_LOOPER_BEGIN(rect_float) {
+                                       rect_float[0] = rect_float[1] = rect_float[2] = (float)(r[i] + signed_offsets[0]) / float_divs[0];
                                        rect_float[3] = 1.0f;
+                               }
+                               PIXEL_LOOPER_END;
                        }
                }
                else {
+                       r = image->comps[0].data;
+                       g = image->comps[1].data;
+                       b = image->comps[2].data;
+
                        /* rgb or rgba 12bits+ */
-                       for (i = 0; i < w * h; i++, rect_float += 4) {
-                               index = w * h - ((i) / (w) + 1) * w + (i) % (w);
-                               
-                               rect_float[0] = (float)(image->comps[0].data[index] + signed_offsets[0]) / float_divs[0];
-                               rect_float[1] = (float)(image->comps[1].data[index] + signed_offsets[1]) / float_divs[1];
-                               rect_float[2] = (float)(image->comps[2].data[index] + signed_offsets[2]) / float_divs[2];
-                               
-                               if (image->numcomps >= 4)
-                                       rect_float[3] = (float)(image->comps[3].data[index] + signed_offsets[3]) / float_divs[3];
-                               else
+                       if (use_alpha) {
+                               a = image->comps[3].data;
+                               PIXEL_LOOPER_BEGIN(rect_float) {
+                                       rect_float[0] = (float)(r[i] + signed_offsets[0]) / float_divs[0];
+                                       rect_float[1] = (float)(g[i] + signed_offsets[1]) / float_divs[1];
+                                       rect_float[2] = (float)(b[i] + signed_offsets[2]) / float_divs[2];
+                                       rect_float[3] = (float)(a[i] + signed_offsets[3]) / float_divs[3];
+                               }
+                               PIXEL_LOOPER_END;
+                       }
+                       else {
+                               PIXEL_LOOPER_BEGIN(rect_float) {
+                                       rect_float[0] = (float)(r[i] + signed_offsets[0]) / float_divs[0];
+                                       rect_float[1] = (float)(g[i] + signed_offsets[1]) / float_divs[1];
+                                       rect_float[2] = (float)(b[i] + signed_offsets[2]) / float_divs[2];
                                        rect_float[3] = 1.0f;
+                               }
+                               PIXEL_LOOPER_END;
                        }
                }
                
        }
        else {
-               unsigned char *rect = (unsigned char *)ibuf->rect;
+               unsigned char *rect_uchar = (unsigned char *)ibuf->rect;
 
                if (image->numcomps < 3) {
+                       r = image->comps[0].data;
+                       a = (use_alpha) ? image->comps[1].data : NULL;
+
                        /* greyscale */
-                       for (i = 0; i < w * h; i++, rect += 4) {
-                               index = w * h - ((i) / (w) + 1) * w + (i) % (w);
-                               
-                               rect[0] = rect[1] = rect[2] = (image->comps[0].data[index] + signed_offsets[0]);
-                               
-                               if (image->numcomps == 2)
-                                       rect[3] = image->comps[1].data[index] + signed_offsets[1];
-                               else
-                                       rect[3] = 255;
+                       if (use_alpha) {
+                               a = image->comps[3].data;
+                               PIXEL_LOOPER_BEGIN(rect_uchar) {
+                                       rect_uchar[0] = rect_uchar[1] = rect_uchar[2] = (r[i] + signed_offsets[0]);
+                                       rect_uchar[3] = a[i] + signed_offsets[1];
+                               }
+                               PIXEL_LOOPER_END;
+                       }
+                       else {
+                               PIXEL_LOOPER_BEGIN(rect_uchar) {
+                                       rect_uchar[0] = rect_uchar[1] = rect_uchar[2] = (r[i] + signed_offsets[0]);
+                                       rect_uchar[3] = 255;
+                               }
+                               PIXEL_LOOPER_END;
                        }
                }
                else {
+                       r = image->comps[0].data;
+                       g = image->comps[1].data;
+                       b = image->comps[2].data;
+
                        /* 8bit rgb or rgba */
-                       for (i = 0; i < w * h; i++, rect += 4) {
-                               int index = w * h - ((i) / (w) + 1) * w + (i) % (w);
-                               
-                               rect[0] = image->comps[0].data[index] + signed_offsets[0];
-                               rect[1] = image->comps[1].data[index] + signed_offsets[1];
-                               rect[2] = image->comps[2].data[index] + signed_offsets[2];
-                               
-                               if (image->numcomps >= 4)
-                                       rect[3] = image->comps[3].data[index] + signed_offsets[3];
-                               else
-                                       rect[3] = 255;
+                       if (use_alpha) {
+                               a = image->comps[3].data;
+                               PIXEL_LOOPER_BEGIN(rect_uchar) {
+                                       rect_uchar[0] = r[i] + signed_offsets[0];
+                                       rect_uchar[1] = g[i] + signed_offsets[1];
+                                       rect_uchar[2] = b[i] + signed_offsets[2];
+                                       rect_uchar[3] = a[i] + signed_offsets[3];
+                               }
+                               PIXEL_LOOPER_END;
+                       }
+                       else {
+                               PIXEL_LOOPER_BEGIN(rect_uchar) {
+                                       rect_uchar[0] = r[i] + signed_offsets[0];
+                                       rect_uchar[1] = g[i] + signed_offsets[1];
+                                       rect_uchar[2] = b[i] + signed_offsets[2];
+                                       rect_uchar[3] = 255;
+                               }
+                               PIXEL_LOOPER_END;
                        }
                }
        }
@@ -286,13 +335,38 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags)
 //static opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, raw_cparameters_t *raw_cp) {
 /* prec can be 8, 12, 16 */
 
+/* use inline because the float passed can be a function call that would end up being called many times */
+#if 0
 #define UPSAMPLE_8_TO_12(_val) ((_val << 4) | (_val & ((1 << 4) - 1)))
 #define UPSAMPLE_8_TO_16(_val) ((_val << 8) + _val)
 
 #define DOWNSAMPLE_FLOAT_TO_8BIT(_val)  (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 255 : (int)(255.0f * (_val)))
 #define DOWNSAMPLE_FLOAT_TO_12BIT(_val) (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 4095 : (int)(4095.0f * (_val)))
 #define DOWNSAMPLE_FLOAT_TO_16BIT(_val) (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 65535 : (int)(65535.0f * (_val)))
+#else
+
+BLI_INLINE int UPSAMPLE_8_TO_12(const unsigned char _val)
+{
+       return (_val << 4) | (_val & ((1 << 4) - 1));
+}
+BLI_INLINE int UPSAMPLE_8_TO_16(const unsigned char _val)
+{
+       return (_val << 8) + _val;
+}
 
+BLI_INLINE int DOWNSAMPLE_FLOAT_TO_8BIT(const float _val)
+{
+       return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 255 : (int)(255.0f * (_val)));
+}
+BLI_INLINE int DOWNSAMPLE_FLOAT_TO_12BIT(const float _val)
+{
+       return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 4095 : (int)(4095.0f * (_val)));
+}
+BLI_INLINE int DOWNSAMPLE_FLOAT_TO_16BIT(const float _val)
+{
+       return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 65535 : (int)(65535.0f * (_val)));
+}
+#endif
 
 /*
  * 2048x1080 (2K) at 24 fps or 48 fps, or 4096x2160 (4K) at 24 fps; 3x12 bits per pixel, XYZ color space
@@ -457,15 +531,15 @@ static void cinema_setup_encoder(opj_cparameters_t *parameters, opj_image_t *ima
 
 static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
 {
-       unsigned char *rect;
+       unsigned char *rect_uchar;
        float *rect_float;
        
-       int subsampling_dx = parameters->subsampling_dx;
-       int subsampling_dy = parameters->subsampling_dy;
+       unsigned int subsampling_dx = parameters->subsampling_dx;
+       unsigned int subsampling_dy = parameters->subsampling_dy;
        
-
-       int i, numcomps, w, h, prec;
-       int x, y, y_row;
+       unsigned int i, i_next, numcomps, w, h, prec;
+       unsigned int y;
+       int *r, *g, *b, *a; /* matching 'opj_image_comp.data' type */
        OPJ_COLOR_SPACE color_space;
        opj_image_cmptparm_t cmptparm[4];   /* maximum of 4 components */
        opj_image_t *image = NULL;
@@ -515,7 +589,7 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
        
        
        /* initialize image components */
-       memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
+       memset(&cmptparm, 0, 4 * sizeof(opj_image_cmptparm_t));
        for (i = 0; i < numcomps; i++) {
                cmptparm[i].prec = prec;
                cmptparm[i].bpp = prec;
@@ -535,78 +609,157 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
        /* set image offset and reference grid */
        image->x0 = parameters->image_offset_x0;
        image->y0 = parameters->image_offset_y0;
-       image->x1 = parameters->image_offset_x0 + (w - 1) * subsampling_dx + 1;
-       image->y1 = parameters->image_offset_y0 + (h - 1) * subsampling_dy + 1;
-       
+       image->x1 = image->x0 + (w - 1) * subsampling_dx + 1 + image->x0;
+       image->y1 = image->y0 + (h - 1) * subsampling_dy + 1 + image->y0;
+
        /* set image data */
-       rect = (unsigned char *) ibuf->rect;
+       rect_uchar = (unsigned char *) ibuf->rect;
        rect_float = ibuf->rect_float;
        
-       if (rect_float && rect && prec == 8) {
+       /* set the destination channels */
+       r = image->comps[0].data;
+       g = image->comps[1].data;
+       b = image->comps[2].data;
+       a = (numcomps == 4) ? image->comps[3].data : NULL;
+
+       if (rect_float && rect_uchar && prec == 8) {
                /* No need to use the floating point buffer, just write the 8 bits from the char buffer */
                rect_float = NULL;
        }
        
-       
        if (rect_float) {
-               float rgb[3];
-               
                switch (prec) {
                        case 8: /* Convert blenders float color channels to 8, 12 or 16bit ints */
-                               for (y = h - 1; y >= 0; y--) {
-                                       y_row = y * w;
-                                       for (x = 0; x < w; x++, rect_float += 4) {
-                                               i = y_row + x;
-
-                                               if (ibuf->profile == IB_PROFILE_LINEAR_RGB)
-                                                       linearrgb_to_srgb_v3_v3(rgb, rect_float);
-                                               else
-                                                       copy_v3_v3(rgb, rect_float);
-
-                                               image->comps[0].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rgb[0]);
-                                               image->comps[1].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rgb[1]);
-                                               image->comps[2].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rgb[2]);
-                                               if (numcomps > 3)
-                                                       image->comps[3].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[3]);
+                               if (numcomps == 4) {
+                                       if (ibuf->profile == IB_PROFILE_LINEAR_RGB) {
+                                               PIXEL_LOOPER_BEGIN(rect_float)
+                                               {
+                                                       r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[0]));
+                                                       g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[1]));
+                                                       b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[2]));
+                                                       a[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[3]);
+                                               }
+                                               PIXEL_LOOPER_END;
+                                       }
+                                       else {
+                                               PIXEL_LOOPER_BEGIN(rect_float)
+                                               {
+                                                       r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[0]);
+                                                       g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[1]);
+                                                       b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[2]);
+                                                       a[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[3]);
+                                               }
+                                               PIXEL_LOOPER_END;
+                                       }
+                               }
+                               else {
+                                       if (ibuf->profile == IB_PROFILE_LINEAR_RGB) {
+                                               PIXEL_LOOPER_BEGIN(rect_float)
+                                               {
+                                                       r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[0]));
+                                                       g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[1]));
+                                                       b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[2]));
+                                               }
+                                               PIXEL_LOOPER_END;
+                                       }
+                                       else {
+                                               PIXEL_LOOPER_BEGIN(rect_float)
+                                               {
+                                                       r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[0]);
+                                                       g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[1]);
+                                                       b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[2]);
+                                               }
+                                               PIXEL_LOOPER_END;
                                        }
                                }
                                break;
                        
                        case 12:
-                               for (y = h - 1; y >= 0; y--) {
-                                       y_row = y * w;
-                                       for (x = 0; x < w; x++, rect_float += 4) {
-                                               i = y_row + x;
-
-                                               if (ibuf->profile == IB_PROFILE_LINEAR_RGB)
-                                                       linearrgb_to_srgb_v3_v3(rgb, rect_float);
-                                               else
-                                                       copy_v3_v3(rgb, rect_float);
-
-                                               image->comps[0].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rgb[0]);
-                                               image->comps[1].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rgb[1]);
-                                               image->comps[2].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rgb[2]);
-                                               if (numcomps > 3)
-                                                       image->comps[3].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[3]);
+                               if (numcomps == 4) {
+                                       if (ibuf->profile == IB_PROFILE_LINEAR_RGB) {
+                                               PIXEL_LOOPER_BEGIN(rect_float)
+                                               {
+                                                       r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[0]));
+                                                       g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[1]));
+                                                       b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[2]));
+                                                       a[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[3]);
+                                               }
+                                               PIXEL_LOOPER_END;
+                                       }
+                                       else {
+                                               PIXEL_LOOPER_BEGIN(rect_float)
+                                               {
+                                                       r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[0]);
+                                                       g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[1]);
+                                                       b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[2]);
+                                                       a[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[3]);
+                                               }
+                                               PIXEL_LOOPER_END;
+                                       }
+                               }
+                               else {
+                                       if (ibuf->profile == IB_PROFILE_LINEAR_RGB) {
+                                               PIXEL_LOOPER_BEGIN(rect_float)
+                                               {
+                                                       r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[0]));
+                                                       g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[1]));
+                                                       b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[2]));
+                                               }
+                                               PIXEL_LOOPER_END;
+                                       }
+                                       else {
+                                               PIXEL_LOOPER_BEGIN(rect_float)
+                                               {
+                                                       r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[0]);
+                                                       g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[1]);
+                                                       b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[2]);
+                                               }
+                                               PIXEL_LOOPER_END;
                                        }
                                }
                                break;
+
                        case 16:
-                               for (y = h - 1; y >= 0; y--) {
-                                       y_row = y * w;
-                                       for (x = 0; x < w; x++, rect_float += 4) {
-                                               i = y_row + x;
-
-                                               if (ibuf->profile == IB_PROFILE_LINEAR_RGB)
-                                                       linearrgb_to_srgb_v3_v3(rgb, rect_float);
-                                               else
-                                                       copy_v3_v3(rgb, rect_float);
-
-                                               image->comps[0].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rgb[0]);
-                                               image->comps[1].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rgb[1]);
-                                               image->comps[2].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rgb[2]);
-                                               if (numcomps > 3)
-                                                       image->comps[3].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[3]);
+                               if (numcomps == 4) {
+                                       if (ibuf->profile == IB_PROFILE_LINEAR_RGB) {
+                                               PIXEL_LOOPER_BEGIN(rect_float)
+                                               {
+                                                       r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[0]));
+                                                       g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[1]));
+                                                       b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[2]));
+                                                       a[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[3]);
+                                               }
+                                               PIXEL_LOOPER_END;
+                                       }
+                                       else {
+                                               PIXEL_LOOPER_BEGIN(rect_float)
+                                               {
+                                                       r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[0]);
+                                                       g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[1]);
+                                                       b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[2]);
+                                                       a[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[3]);
+                                               }
+                                               PIXEL_LOOPER_END;
+                                       }
+                               }
+                               else {
+                                       if (ibuf->profile == IB_PROFILE_LINEAR_RGB) {
+                                               PIXEL_LOOPER_BEGIN(rect_float)
+                                               {
+                                                       r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[0]));
+                                                       g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[1]));
+                                                       b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[2]));
+                                               }
+                                               PIXEL_LOOPER_END;
+                                       }
+                                       else {
+                                               PIXEL_LOOPER_BEGIN(rect_float)
+                                               {
+                                                       r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[0]);
+                                                       g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[1]);
+                                                       b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[2]);
+                                               }
+                                               PIXEL_LOOPER_END;
                                        }
                                }
                                break;
@@ -616,46 +769,68 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
                /* just use rect*/
                switch (prec) {
                        case 8:
-                               for (y = h - 1; y >= 0; y--) {
-                                       y_row = y * w;
-                                       for (x = 0; x < w; x++, rect += 4) {
-                                               i = y_row + x;
-
-                                               image->comps[0].data[i] = rect[0];
-                                               image->comps[1].data[i] = rect[1];
-                                               image->comps[2].data[i] = rect[2];
-                                               if (numcomps > 3)
-                                                       image->comps[3].data[i] = rect[3];
+                               if (numcomps == 4) {
+                                       PIXEL_LOOPER_BEGIN(rect_uchar)
+                                       {
+                                               r[i] = rect_uchar[0];
+                                               g[i] = rect_uchar[1];
+                                               b[i] = rect_uchar[2];
+                                               a[i] = rect_uchar[3];
+                                       }
+                                       PIXEL_LOOPER_END;
+                               }
+                               else {
+                                       PIXEL_LOOPER_BEGIN(rect_uchar)
+                                       {
+                                               r[i] = rect_uchar[0];
+                                               g[i] = rect_uchar[1];
+                                               b[i] = rect_uchar[2];
                                        }
+                                       PIXEL_LOOPER_END;
                                }
                                break;
                        
                        case 12: /* Up Sampling, a bit pointless but best write the bit depth requested */
-                               for (y = h - 1; y >= 0; y--) {
-                                       y_row = y * w;
-                                       for (x = 0; x < w; x++, rect += 4) {
-                                               i = y_row + x;
-
-                                               image->comps[0].data[i] = UPSAMPLE_8_TO_12(rect[0]);
-                                               image->comps[1].data[i] = UPSAMPLE_8_TO_12(rect[1]);
-                                               image->comps[2].data[i] = UPSAMPLE_8_TO_12(rect[2]);
-                                               if (numcomps > 3)
-                                                       image->comps[3].data[i] = UPSAMPLE_8_TO_12(rect[3]);
+                               if (numcomps == 4) {
+                                       PIXEL_LOOPER_BEGIN(rect_uchar)
+                                       {
+                                               r[i] = UPSAMPLE_8_TO_12(rect_uchar[0]);
+                                               g[i] = UPSAMPLE_8_TO_12(rect_uchar[1]);
+                                               b[i] = UPSAMPLE_8_TO_12(rect_uchar[2]);
+                                               a[i] = UPSAMPLE_8_TO_12(rect_uchar[3]);
+                                       }
+                                       PIXEL_LOOPER_END;
+                               }
+                               else {
+                                       PIXEL_LOOPER_BEGIN(rect_uchar)
+                                       {
+                                               r[i] = UPSAMPLE_8_TO_12(rect_uchar[0]);
+                                               g[i] = UPSAMPLE_8_TO_12(rect_uchar[1]);
+                                               b[i] = UPSAMPLE_8_TO_12(rect_uchar[2]);
                                        }
+                                       PIXEL_LOOPER_END;
                                }
                                break;
+
                        case 16:
-                               for (y = h - 1; y >= 0; y--) {
-                                       y_row = y * w;
-                                       for (x = 0; x < w; x++, rect += 4) {
-                                               i = y_row + x;
-
-                                               image->comps[0].data[i] = UPSAMPLE_8_TO_16(rect[0]);
-                                               image->comps[1].data[i] = UPSAMPLE_8_TO_16(rect[1]);
-                                               image->comps[2].data[i] = UPSAMPLE_8_TO_16(rect[2]);
-                                               if (numcomps > 3)
-                                                       image->comps[3].data[i] = UPSAMPLE_8_TO_16(rect[3]);
+                               if (numcomps == 4) {
+                                       PIXEL_LOOPER_BEGIN(rect_uchar)
+                                       {
+                                               r[i] = UPSAMPLE_8_TO_16(rect_uchar[0]);
+                                               g[i] = UPSAMPLE_8_TO_16(rect_uchar[1]);
+                                               b[i] = UPSAMPLE_8_TO_16(rect_uchar[2]);
+                                               a[i] = UPSAMPLE_8_TO_16(rect_uchar[3]);
+                                       }
+                                       PIXEL_LOOPER_END;
+                               }
+                               else {
+                                       PIXEL_LOOPER_BEGIN(rect_uchar)
+                                       {
+                                               r[i] = UPSAMPLE_8_TO_16(rect_uchar[0]);
+                                               g[i] = UPSAMPLE_8_TO_16(rect_uchar[1]);
+                                               b[i] = UPSAMPLE_8_TO_16(rect_uchar[2]);
                                        }
+                                       PIXEL_LOOPER_END;
                                }
                                break;
                }
@@ -720,7 +895,7 @@ int imb_savejp2(struct ImBuf *ibuf, const char *name, int flags)
                opj_cinfo_t *cinfo = opj_create_compress(CODEC_JP2);
 
                /* catch events using our callbacks and give a local context */
-               opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);                   
+               opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);
 
                /* setup the encoder parameters using the current image and using user parameters */
                opj_setup_encoder(cinfo, &parameters, image);
index 59d8e81de3929e2afffe9e930bff3b48649d2038..aae167d05c61c60ce3b51e0a50f4bc4a58119f4a 100644 (file)
@@ -247,7 +247,7 @@ typedef struct bActionConstraint {
        int                     end;
        float           min;
        float           max;
-       int         pad;
+       int                     flag;
        struct bAction  *act;
        char            subtarget[64];  /* MAX_ID_NAME-2 */
 } bActionConstraint;
@@ -561,6 +561,12 @@ typedef enum eSameVolume_Modes {
        SAMEVOL_Z
 } eSameVolume_Modes;
 
+/* bActionConstraint.flag
+ * WARNING: bitwise! */
+typedef enum eAction_flags {
+       BONE_USE_OBJECT_ACTION = 1 << 0, /* Bones use "object" part of target action, instead of "same bone name" part. */
+} eAction_flags;
+
 /* Locked-Axis Values (Locked Track) */
 typedef enum eLockAxis_Modes {
        LOCK_X  = 0,
index b5ab7898bd97f00b41331cb966ccf53b75fd8897..19004dbc8b88ff48b30e50efc94615bdbd802e5b 100644 (file)
@@ -90,7 +90,8 @@ typedef struct MovieClip {
 } MovieClip;
 
 typedef struct MovieClipScopes {
-       int ok;                         /* 1 means scopes are ok and recalculation is unneeded */
+       short ok;                       /* 1 means scopes are ok and recalculation is unneeded */
+       short use_track_mask;           /* whether track's mask should be applied on preview */
        int track_preview_height;       /* height of track preview widget */
        int frame_width, frame_height;  /* width and height of frame for which scopes are calculated */
        struct MovieTrackingMarker undist_marker;   /* undistorted position of marker used for pattern sampling */
@@ -98,7 +99,7 @@ typedef struct MovieClipScopes {
        struct ImBuf *track_preview;    /* ImBuf displayed in track preview */
        float track_pos[2];             /* sub-pizel position of marker in track ImBuf */
        short track_disabled;           /* active track is disabled, special notifier should be drawn */
-       char pad[2];
+       short track_locked;             /* active track is locked, no transformation should be allowed */
        int framenr;                    /* frame number scopes are created for */
        struct MovieTrackingTrack *track;   /* track scopes are created for */
        struct MovieTrackingMarker *marker; /* marker scopes are created for */
index 6ca63f2c1c9e3dcdc1caf9377a4888cbc2369e5b..84ae18357519e5cc118ddbce09ddc395c7aa5a6d 100644 (file)
@@ -287,6 +287,7 @@ enum {
 #define TRACK_USE_2D_STAB   (1 << 8)
 #define TRACK_PREVIEW_GRAYSCALE (1 << 9)
 #define TRACK_DOPE_SEL      (1 << 10)
+#define TRACK_PREVIEW_ALPHA (1 << 11)
 
 /* MovieTrackingTrack->motion_model */
 #define TRACK_MOTION_MODEL_TRANSLATION                 0
@@ -297,8 +298,9 @@ enum {
 #define TRACK_MOTION_MODEL_HOMOGRAPHY                  5
 
 /* MovieTrackingTrack->algorithm_flag */
-#define TRACK_ALGORITHM_FLAG_USE_BRUTE 1
-#define TRACK_ALGORITHM_FLAG_USE_NORMALIZATION 2
+#define TRACK_ALGORITHM_FLAG_USE_BRUTE                 (1 << 0)
+#define TRACK_ALGORITHM_FLAG_USE_NORMALIZATION (1 << 2)
+#define TRACK_ALGORITHM_FLAG_USE_MASK                  (1 << 3)
 
 /* MovieTrackingTrack->adjframes */
 #define TRACK_MATCH_KEYFRAME        0
index 5465dbf6e3c259953af54e4079d7f5671fd4c3ff..1c2844cd8a7b96149970d426903fb16b57fc2aae 100644 (file)
@@ -412,7 +412,7 @@ typedef struct UserDef {
        
        short widget_unit;              /* defaults to 20 for 72 DPI setting */
        short anisotropic_filter;
-       short use_16bit_textures, pad8;
+       short use_16bit_textures, use_gpu_mipmap;
 
        float ndof_sensitivity; /* overall sensitivity of 3D mouse */
        int ndof_flag;                  /* flags for 3D mouse */
index 8e29e5c2e79881ac18cab4d603c2aa9249679933..f02df6c30ed4cf1b87f017590cf02c4e87f5eed9 100644 (file)
@@ -1111,6 +1111,13 @@ static void rna_def_constraint_action(BlenderRNA *brna)
        RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
        RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
 
+       prop = RNA_def_property(srna, "use_bone_object_action", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_USE_OBJECT_ACTION);
+       RNA_def_property_ui_text(prop, "Object Action",
+                                "Bones only: apply the object's transformation channels of the action "
+                                "to the constrained bone, instead of bone's channels");
+       RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+
        prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME);
        RNA_def_property_int_sdna(prop, NULL, "start");
        RNA_def_property_range(prop, MINAFRAME, MAXFRAME);
index d7e16481f40d2235aa4dc210ddae5761f1a3b0e3..af4b3a7e16923ee08c7e0125294227103a1afc2e 100644 (file)
@@ -634,6 +634,23 @@ static EnumPropertyItem *rna_Node_channel_itemf(bContext *UNUSED(C), PointerRNA
        return item;
 }
 
+static PointerRNA rna_NodeTree_active_node_get(PointerRNA *ptr)
+{
+       bNodeTree *ntree = (bNodeTree *)ptr->data;
+       bNode *node = nodeGetActive(ntree);
+       return rna_pointer_inherit_refine(ptr, &RNA_Node, node);
+}
+
+static void rna_NodeTree_active_node_set(PointerRNA *ptr, PointerRNA value)
+{
+       bNodeTree *ntree = (bNodeTree *)ptr->data;
+       bNode *node = (bNode *)value.data;
+       if (node && BLI_findindex(&ntree->nodes, node) != -1)
+               nodeSetActive(ntree, node);
+       else
+               nodeClearActive(ntree);
+}
+
 static bNode *rna_NodeTree_node_new(bNodeTree *ntree, bContext *C, ReportList *reports,
                                     int type, bNodeTree *group)
 {
@@ -1041,6 +1058,7 @@ static void init(void)
        reg_node(NODE_FORLOOP, Category_LoopNode, "FORLOOP", "NodeForLoop", "Node", "ForLoop", "");
        reg_node(NODE_WHILELOOP, Category_LoopNode, "WHILELOOP", "NodeWhileLoop", "Node", "WhileLoop", "");
        reg_node(NODE_FRAME, Category_LayoutNode, "FRAME", "NodeFrame", "Node", "Frame", "");
+       reg_node(NODE_REROUTE, Category_LayoutNode, "REROUTE", "NodeReroute", "Node", "Reroute", "");
 }
 
 static StructRNA *def_node(BlenderRNA *brna, int node_id)
@@ -1058,7 +1076,7 @@ static StructRNA *def_node(BlenderRNA *brna, int node_id)
 static void alloc_node_type_items(EnumPropertyItem *items, int category)
 {
        int i;
-       int count = 3;
+       int count = 4;
        EnumPropertyItem *item  = items;
        
        for (i = 0; i < MaxNodes; i++)
@@ -1088,6 +1106,14 @@ static void alloc_node_type_items(EnumPropertyItem *items, int category)
        
        item++;
        
+       item->value = NODE_REROUTE;
+       item->identifier = "REROUTE";
+       item->icon = 0;
+       item->name = "Reroute";
+       item->description = "";
+       
+       item++;
+       
        /* NOTE!, increase 'count' when adding items here */
        
        memset(item, 0, sizeof(EnumPropertyItem));
@@ -3711,6 +3737,19 @@ static void rna_def_nodetree_link_api(BlenderRNA *brna, PropertyRNA *cprop)
        RNA_def_function_ui_description(func, "remove all node links from the node tree");
 }
 
+/* shared between all note tree types*/
+static void rna_def_nodetree_active_api(StructRNA *srna, PropertyRNA *cprop)
+{
+       PropertyRNA *prop;
+
+       prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
+       RNA_def_property_struct_type(prop, "Node");
+       RNA_def_property_pointer_funcs(prop, "rna_NodeTree_active_node_get", "rna_NodeTree_active_node_set", NULL, NULL);
+       RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
+       RNA_def_property_ui_text(prop, "Active Node", "Active node in this tree");
+       RNA_def_property_update(prop, NC_SCENE | ND_OB_ACTIVE, NULL);
+}
+
 static void rna_def_composite_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop)
 {
        StructRNA *srna;
@@ -3740,6 +3779,8 @@ static void rna_def_composite_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop)
 
        func = RNA_def_function(srna, "clear", "rna_NodeTree_node_clear");
        RNA_def_function_ui_description(func, "Remove all nodes from this node tree");
+
+       rna_def_nodetree_active_api(srna, cprop);
 }
 
 static void rna_def_shader_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop)
@@ -3771,6 +3812,8 @@ static void rna_def_shader_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop)
 
        func = RNA_def_function(srna, "clear", "rna_NodeTree_node_clear");
        RNA_def_function_ui_description(func, "Remove all nodes from this node tree");
+
+       rna_def_nodetree_active_api(srna, cprop);
 }
 
 static void rna_def_texture_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop)
@@ -3802,6 +3845,8 @@ static void rna_def_texture_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop)
 
        func = RNA_def_function(srna, "clear", "rna_NodeTree_node_clear");
        RNA_def_function_ui_description(func, "Remove all nodes from this node tree");
+
+       rna_def_nodetree_active_api(srna, cprop);
 }
 
 static void rna_def_node_socket(BlenderRNA *brna)
@@ -3991,6 +4036,27 @@ static void rna_def_node(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Color", "Custom color of the node body");
        RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
 
+       prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_SELECT);
+       RNA_def_property_ui_text(prop, "Select", "");
+
+       prop = RNA_def_property(srna, "show_options", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_OPTIONS);
+       RNA_def_property_ui_text(prop, "Show Options", "");
+
+       prop = RNA_def_property(srna, "show_preview", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_PREVIEW);
+       RNA_def_property_ui_text(prop, "Show Preview", "");
+
+       prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_HIDDEN);
+       RNA_def_property_ui_text(prop, "Hide", "");
+
+       prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_MUTED);
+       RNA_def_property_ui_text(prop, "Mute", "");
+       RNA_def_property_update(prop, 0, "rna_Node_update");
+
        prop = RNA_def_property(srna, "show_texture", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_ACTIVE_TEXTURE);
        RNA_def_property_ui_text(prop, "Show Texture", "Draw node in viewport textured draw mode");
@@ -4230,6 +4296,7 @@ void RNA_def_nodetree(BlenderRNA *brna)
        define_specific_node(brna, NODE_FORLOOP, def_forloop);
        define_specific_node(brna, NODE_WHILELOOP, def_whileloop);
        define_specific_node(brna, NODE_FRAME, def_frame);
+       define_specific_node(brna, NODE_REROUTE, 0);
        
        /* special socket types */
        rna_def_cmp_output_file_slot_file(brna);
index f1f962f67019cd45b34807ff1bcfeb9ba1f92396..c95d04d005a15d9dc5107cd1341d667fb53af271 100644 (file)
@@ -637,13 +637,19 @@ static void rna_def_trackingSettings(BlenderRNA *brna)
        RNA_def_property_enum_items(prop, tracker_motion_model);
        RNA_def_property_ui_text(prop, "Motion model", "Default motion model to use for tracking");
 
-       /* use_brute */
+       /* default_use_brute */
        prop = RNA_def_property(srna, "default_use_brute", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_BRUTE);
        RNA_def_property_ui_text(prop, "Prepass", "Use a brute-force translation-only initialization when tracking");
        RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
 
-       /* default use_normalization */
+       /* default_use_brute */
+       prop = RNA_def_property(srna, "default_use_mask", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_MASK);
+       RNA_def_property_ui_text(prop, "Use Mask", "Use a grease pencil datablock as a mask to use only specified areas of pattern when tracking");
+       RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
+
+       /* default_use_normalization */
        prop = RNA_def_property(srna, "default_use_normalization", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_NORMALIZATION);
        RNA_def_property_ui_text(prop, "Normalize", "Normalize light intensities while tracking (slower)");
@@ -965,6 +971,12 @@ static void rna_def_trackingTrack(BlenderRNA *brna)
        RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
 
        /* use_brute */
+       prop = RNA_def_property(srna, "use_mask", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "algorithm_flag", TRACK_ALGORITHM_FLAG_USE_MASK);
+       RNA_def_property_ui_text(prop, "Use Mask", "Use a grease pencil datablock as a mask to use only specified areas of pattern when tracking");
+       RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
+
+       /* use_normalization */
        prop = RNA_def_property(srna, "use_normalization", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "algorithm_flag", TRACK_ALGORITHM_FLAG_USE_NORMALIZATION);
        RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -1008,6 +1020,13 @@ static void rna_def_trackingTrack(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Grayscale", "Display what the tracking algorithm sees in the preview");
        RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
 
+       /* preview_alpha */
+       prop = RNA_def_property(srna, "use_alpha_preview", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_PREVIEW_ALPHA);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_ui_text(prop, "Alpha", "Apply track's mask on displaying preview");
+       RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
+
        /* has bundle */
        prop = RNA_def_property(srna, "has_bundle", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_HAS_BUNDLE);
index 84723e95e80d2db2b7af5fed9623a392f9cf02c5..42eb06b137ab10f70757e3767765881b9f7df815 100644 (file)
@@ -144,6 +144,11 @@ static void rna_userdef_anisotropic_update(Main *bmain, Scene *scene, PointerRNA
        rna_userdef_update(bmain, scene, ptr);
 }
 
+static void rna_userdef_gl_gpu_mipmaps(Main *bmain, Scene *scene, PointerRNA *ptr) {
+       GPU_set_gpu_mipmapping(U.use_gpu_mipmap);
+       rna_userdef_update(bmain, scene, ptr);
+}
+
 static void rna_userdef_gl_texture_limit_update(Main *bmain, Scene *scene, PointerRNA *ptr)
 {
        GPU_free_images();
@@ -3143,6 +3148,11 @@ static void rna_def_userdef_system(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "16 Bit Float Textures", "Use 16 bit per component texture for float images");
        RNA_def_property_update(prop, 0, "rna_userdef_gl_use_16bit_textures");
 
+       prop = RNA_def_property(srna, "use_gpu_mipmap", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "use_gpu_mipmap", 1);
+       RNA_def_property_ui_text(prop, "GPU Mipmap Generation", "Generate Image Mipmaps on the GPU");
+       RNA_def_property_update(prop, 0, "rna_userdef_gl_gpu_mipmaps");
+
        prop = RNA_def_property(srna, "use_vertex_buffer_objects", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_VBO);
        RNA_def_property_ui_text(prop, "VBOs",
index 3d1b656fc4e11183e7e46eeb5e4681188f364e1e..150bede4b7c1573de3c9981936e0098f8b41d023 100644 (file)
@@ -32,8 +32,6 @@
 
 #include <string.h>
 
-#include "DNA_action_types.h"
-#include "DNA_anim_types.h"
 #include "DNA_node_types.h"
 
 #include "BLI_listbase.h"
@@ -42,8 +40,6 @@
 
 #include "BLF_translation.h"
 
-#include "BKE_action.h"
-#include "BKE_animsys.h"
 #include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
@@ -112,294 +108,6 @@ bNodeSocket *node_group_add_extern_socket(bNodeTree *UNUSED(ntree), ListBase *lb
        return sock;
 }
 
-bNode *node_group_make_from_selected(bNodeTree *ntree)
-{
-       bNodeLink *link, *linkn;
-       bNode *node, *gnode, *nextn;
-       bNodeTree *ngroup;
-       bNodeSocket *gsock;
-       ListBase anim_basepaths = {NULL, NULL};
-       float min[2], max[2];
-       int totnode=0;
-       bNodeTemplate ntemp;
-       
-       INIT_MINMAX2(min, max);
-       
-       /* is there something to group? also do some clearing */
-       for (node= ntree->nodes.first; node; node= node->next) {
-               if (node->flag & NODE_SELECT) {
-                       /* no groups in groups */
-                       if (node->type==NODE_GROUP)
-                               return NULL;
-                       DO_MINMAX2((&node->locx), min, max);
-                       totnode++;
-               }
-               node->done = FALSE;
-       }
-       if (totnode==0) return NULL;
-       
-       /* check if all connections are OK, no unselected node has both
-        * inputs and outputs to a selection */
-       for (link= ntree->links.first; link; link= link->next) {
-               if (link->fromnode && link->tonode && link->fromnode->flag & NODE_SELECT)
-                       link->tonode->done |= 1;
-               if (link->fromnode && link->tonode && link->tonode->flag & NODE_SELECT)
-                       link->fromnode->done |= 2;
-       }       
-       
-       for (node= ntree->nodes.first; node; node= node->next) {
-               if ((node->flag & NODE_SELECT)==0)
-                       if (node->done==3)
-                               break;
-       }
-       if (node) 
-               return NULL;
-       
-       /* OK! new nodetree */
-       ngroup= ntreeAddTree("NodeGroup", ntree->type, NODE_GROUP);
-       
-       /* move nodes over */
-       for (node= ntree->nodes.first; node; node= nextn) {
-               nextn= node->next;
-               if (node->flag & NODE_SELECT) {
-                       /* keep track of this node's RNA "base" path (the part of the pat identifying the node) 
-                        * if the old nodetree has animation data which potentially covers this node
-                        */
-                       if (ntree->adt) {
-                               PointerRNA ptr;
-                               char *path;
-                               
-                               RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
-                               path = RNA_path_from_ID_to_struct(&ptr);
-                               
-                               if (path)
-                                       BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
-                       }
-                       
-                       /* change node-collection membership */
-                       BLI_remlink(&ntree->nodes, node);
-                       BLI_addtail(&ngroup->nodes, node);
-                       
-                       node->locx-= 0.5f*(min[0]+max[0]);
-                       node->locy-= 0.5f*(min[1]+max[1]);
-               }
-       }
-
-       /* move animation data over */
-       if (ntree->adt) {
-               LinkData *ld, *ldn=NULL;
-               
-               BKE_animdata_separate_by_basepath(&ntree->id, &ngroup->id, &anim_basepaths);
-               
-               /* paths + their wrappers need to be freed */
-               for (ld = anim_basepaths.first; ld; ld = ldn) {
-                       ldn = ld->next;
-                       
-                       MEM_freeN(ld->data);
-                       BLI_freelinkN(&anim_basepaths, ld);
-               }
-       }
-       
-       /* node groups don't use internal cached data */
-       ntreeFreeCache(ngroup);
-       
-       /* make group node */
-       ntemp.type = NODE_GROUP;
-       ntemp.ngroup = ngroup;
-       gnode= nodeAddNode(ntree, &ntemp);
-       gnode->locx= 0.5f*(min[0]+max[0]);
-       gnode->locy= 0.5f*(min[1]+max[1]);
-       
-       /* relink external sockets */
-       for (link= ntree->links.first; link; link= linkn) {
-               linkn= link->next;
-               
-               if (link->fromnode && link->tonode && (link->fromnode->flag & link->tonode->flag & NODE_SELECT)) {
-                       BLI_remlink(&ntree->links, link);
-                       BLI_addtail(&ngroup->links, link);
-               }
-               else if (link->tonode && (link->tonode->flag & NODE_SELECT)) {
-                       gsock = node_group_expose_socket(ngroup, link->tosock, SOCK_IN);
-                       link->tosock->link = nodeAddLink(ngroup, NULL, gsock, link->tonode, link->tosock);
-                       link->tosock = node_group_add_extern_socket(ntree, &gnode->inputs, SOCK_IN, gsock);
-                       link->tonode = gnode;
-               }
-               else if (link->fromnode && (link->fromnode->flag & NODE_SELECT)) {
-                       /* search for existing group node socket */
-                       for (gsock=ngroup->outputs.first; gsock; gsock=gsock->next)
-                               if (gsock->link && gsock->link->fromsock==link->fromsock)
-                                       break;
-                       if (!gsock) {
-                               gsock = node_group_expose_socket(ngroup, link->fromsock, SOCK_OUT);
-                               gsock->link = nodeAddLink(ngroup, link->fromnode, link->fromsock, NULL, gsock);
-                               link->fromsock = node_group_add_extern_socket(ntree, &gnode->outputs, SOCK_OUT, gsock);
-                       }
-                       else
-                               link->fromsock = node_group_find_output(gnode, gsock);
-                       link->fromnode = gnode;
-               }
-       }
-
-       /* update of the group tree */
-       ngroup->update |= NTREE_UPDATE;
-       ntreeUpdateTree(ngroup);
-       /* update of the tree containing the group instance node */
-       ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
-       ntreeUpdateTree(ntree);
-
-       return gnode;
-}
-
-/* returns 1 if its OK */
-int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
-{
-       bNodeLink *link, *linkn;
-       bNode *node, *nextn;
-       bNodeTree *ngroup, *wgroup;
-       ListBase anim_basepaths = {NULL, NULL};
-       
-       ngroup= (bNodeTree *)gnode->id;
-       if (ngroup==NULL) return 0;
-       
-       /* clear new pointers, set in copytree */
-       for (node= ntree->nodes.first; node; node= node->next)
-               node->new_node= NULL;
-       
-       /* wgroup is a temporary copy of the NodeTree we're merging in
-        *      - all of wgroup's nodes are transferred across to their new home
-        *      - ngroup (i.e. the source NodeTree) is left unscathed
-        */
-       wgroup= ntreeCopyTree(ngroup);
-       
-       /* add the nodes into the ntree */
-       for (node= wgroup->nodes.first; node; node= nextn) {
-               nextn= node->next;
-               
-               /* keep track of this node's RNA "base" path (the part of the pat identifying the node) 
-                * if the old nodetree has animation data which potentially covers this node
-                */
-               if (wgroup->adt) {
-                       PointerRNA ptr;
-                       char *path;
-                       
-                       RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr);
-                       path = RNA_path_from_ID_to_struct(&ptr);
-                       
-                       if (path)
-                               BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
-               }
-               
-               /* migrate node */
-               BLI_remlink(&wgroup->nodes, node);
-               BLI_addtail(&ntree->nodes, node);
-               
-               node->locx += gnode->locx;
-               node->locy += gnode->locy;
-               
-               node->flag |= NODE_SELECT;
-       }
-       
-       /* restore external links to and from the gnode */
-       for (link= ntree->links.first; link; link= link->next) {
-               if (link->fromnode==gnode) {
-                       if (link->fromsock->groupsock) {
-                               bNodeSocket *gsock= link->fromsock->groupsock;
-                               if (gsock->link) {
-                                       if (gsock->link->fromnode) {
-                                               /* NB: using the new internal copies here! the groupsock pointer still maps to the old tree */
-                                               link->fromnode = (gsock->link->fromnode ? gsock->link->fromnode->new_node : NULL);
-                                               link->fromsock = gsock->link->fromsock->new_sock;
-                                       }
-                                       else {
-                                               /* group output directly maps to group input */
-                                               bNodeSocket *insock= node_group_find_input(gnode, gsock->link->fromsock);
-                                               if (insock->link) {
-                                                       link->fromnode = insock->link->fromnode;
-                                                       link->fromsock = insock->link->fromsock;
-                                               }
-                                       }
-                               }
-                               else {
-                                       /* copy the default input value from the group socket default to the external socket */
-                                       node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, gsock->type, gsock->default_value);
-                               }
-                       }
-               }
-       }
-       /* remove internal output links, these are not used anymore */
-       for (link=wgroup->links.first; link; link= linkn) {
-               linkn = link->next;
-               if (!link->tonode)
-                       nodeRemLink(wgroup, link);
-       }
-       /* restore links from internal nodes */
-       for (link= wgroup->links.first; link; link= link->next) {
-               /* indicates link to group input */
-               if (!link->fromnode) {
-                       /* NB: can't use find_group_node_input here,
-                        * because gnode sockets still point to the old tree!
-                        */
-                       bNodeSocket *insock;
-                       for (insock= gnode->inputs.first; insock; insock= insock->next)
-                               if (insock->groupsock->new_sock == link->fromsock)
-                                       break;
-                       if (insock->link) {
-                               link->fromnode = insock->link->fromnode;
-                               link->fromsock = insock->link->fromsock;
-                       }
-                       else {
-                               /* copy the default input value from the group node socket default to the internal socket */
-                               node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, insock->type, insock->default_value);
-                               nodeRemLink(wgroup, link);
-                       }
-               }
-       }
-       
-       /* add internal links to the ntree */
-       for (link= wgroup->links.first; link; link= linkn) {
-               linkn= link->next;
-               BLI_remlink(&wgroup->links, link);
-               BLI_addtail(&ntree->links, link);
-       }
-       
-       /* and copy across the animation,
-        * note that the animation data's action can be NULL here */
-       if (wgroup->adt) {
-               LinkData *ld, *ldn=NULL;
-               bAction *waction;
-               
-               /* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */
-               waction = wgroup->adt->action = BKE_action_copy(wgroup->adt->action);
-               
-               /* now perform the moving */
-               BKE_animdata_separate_by_basepath(&wgroup->id, &ntree->id, &anim_basepaths);
-               
-               /* paths + their wrappers need to be freed */
-               for (ld = anim_basepaths.first; ld; ld = ldn) {
-                       ldn = ld->next;
-                       
-                       MEM_freeN(ld->data);
-                       BLI_freelinkN(&anim_basepaths, ld);
-               }
-               
-               /* free temp action too */
-               if (waction) {
-                       BKE_libblock_free(&G.main->action, waction);
-               }
-       }
-       
-       /* delete the group instance. this also removes old input links! */
-       nodeFreeNode(ntree, gnode);
-
-       /* free the group tree (takes care of user count) */
-       BKE_libblock_free(&G.main->nodetree, wgroup);
-       
-       ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
-       ntreeUpdateTree(ntree);
-       
-       return 1;
-}
-
 bNodeSocket *node_group_add_socket(bNodeTree *ngroup, const char *name, int type, int in_out)
 {
        bNodeSocketType *stype = ntreeGetSocketType(type);
@@ -849,7 +557,7 @@ static bNodeSocketTemplate node_reroute_out[]= {
 };
 
 /* simple, only a single input and output here */
-ListBase node_reroute_internal_connect(bNodeTree *ntree, bNode *node)
+static ListBase node_reroute_internal_connect(bNodeTree *ntree, bNode *node)
 {
        bNodeLink *link;
        ListBase ret;
@@ -872,6 +580,23 @@ ListBase node_reroute_internal_connect(bNodeTree *ntree, bNode *node)
        return ret;
 }
 
+static void node_reroute_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+       bNodeSocket *input = node->inputs.first;
+       bNodeSocket *output = node->outputs.first;
+       int type = SOCK_FLOAT;
+       
+       /* determine socket type from unambiguous input/output connection if possible */
+       if (input->limit==1 && input->link)
+               type = input->link->fromsock->type;
+       else if (output->limit==1 && output->link)
+                       type = output->link->tosock->type;
+       
+       /* same type for input/output */
+       nodeSocketSetType(input, type);
+       nodeSocketSetType(output, type);
+}
+
 void register_node_type_reroute(bNodeTreeType *ttype)
 {
        /* frame type is used for all tree types, needs dynamic allocation */
@@ -880,6 +605,7 @@ void register_node_type_reroute(bNodeTreeType *ttype)
        node_type_base(ttype, ntype, NODE_REROUTE, "Reroute", NODE_CLASS_LAYOUT, 0);
        node_type_socket_templates(ntype, node_reroute_in, node_reroute_out);
        node_type_internal_connect(ntype, node_reroute_internal_connect);
+       node_type_update(ntype, node_reroute_update, NULL);
        
        ntype->needs_free = 1;
        nodeRegisterType(ttype, ntype);
index 616221d665809ab92e5e8b36c152e66e1a13bc0b..f1bb837e48310bfdb7f46da415ab8d08d5ca3f29 100644 (file)
@@ -37,8 +37,6 @@
 
 struct bNodeTree;
 
-struct bNodeSocket *node_group_add_extern_socket(struct bNodeTree *ntree, ListBase *lb, int in_out, struct bNodeSocket *gsock);
-
 void node_group_init(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp);
 void node_forloop_init(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp);
 void node_whileloop_init(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp);
index 07bda4c2b9156245b16ac32e1030d9779f39bdce..54044b62e047e69090ae0f45c0a3a0dc03389816 100644 (file)
@@ -2268,6 +2268,11 @@ static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure
        axis_from = 0;
        swizzleClosure = GET_INT_FROM_POINTER(closure);
 
+       /* We must first copy current vec into tvec, else some org values may be lost.
+        * See [#31760].
+        * Assuming self->size can't be higher than MAX_DIMENSIONS! */
+       memcpy(tvec, self->vec, self->size * sizeof(float));
+
        while (swizzleClosure & SWIZZLE_VALID_AXIS) {
                axis_to = swizzleClosure & SWIZZLE_AXIS;
                tvec[axis_to] = vec_assign[axis_from];
@@ -2275,7 +2280,9 @@ static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure
                axis_from++;
        }
 
-       memcpy(self->vec, tvec, axis_from * sizeof(float));
+       /* We must copy back the whole tvec into vec, else some changes may be lost (e.g. xz...).
+        * See [#31760]. */
+       memcpy(self->vec, tvec, self->size * sizeof(float));
        /* continue with BaseMathObject_WriteCallback at the end */
 
        if (BaseMath_WriteCallback(self) == -1)
index ab377d53ec747fcda3837b35c46b5f09529f06c7..c82cae8ac926bcf260a80ba02c847b4a3bc30e61 100644 (file)
@@ -178,7 +178,8 @@ void WM_init(bContext *C, int argc, const char **argv)
                GPU_extensions_init();
                GPU_set_mipmap(!(U.gameflags & USER_DISABLE_MIPMAP));
                GPU_set_anisotropic(U.anisotropic_filter);
-       
+               GPU_set_gpu_mipmapping(U.use_gpu_mipmap);
+
                UI_init();
        }