scale node - framing offset: compatible with camera shiftX/Y and the viewport option.
authorCampbell Barton <ideasman42@gmail.com>
Fri, 15 Jun 2012 07:50:27 +0000 (07:50 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 15 Jun 2012 07:50:27 +0000 (07:50 +0000)
release/scripts/startup/bl_ui/space_view3d.py
source/blender/compositor/nodes/COM_ScaleNode.cpp
source/blender/compositor/operations/COM_ScaleOperation.cpp
source/blender/compositor/operations/COM_ScaleOperation.h
source/blender/editors/space_node/drawnode.c
source/blender/makesrna/intern/rna_nodetree.c

index d7fe7ebbbf72c9c4cff5437098fd02f6e9bc08bd..b525ab922d2bddd0cd72a96fa4dbc07bb99b8719 100644 (file)
@@ -2584,13 +2584,13 @@ class VIEW3D_PT_background_image(Panel):
                         rowsub = col.row()
                         rowsub.prop(bg, "frame_method", expand=True)
 
-                    if bg.view_axis != 'CAMERA':
-                        col.prop(bg, "size")
-
                     row = col.row(align=True)
                     row.prop(bg, "offset_x", text="X")
                     row.prop(bg, "offset_y", text="Y")
 
+                    if bg.view_axis != 'CAMERA':
+                        col.prop(bg, "size")
+
 
 class VIEW3D_PT_transform_orientations(Panel):
     bl_space_type = 'VIEW_3D'
index 85d5644484bad2b5b11eff9c0785d7877ef95e60..870ed8f2484eb5129076575a81f26ae57ee440a6 100644 (file)
@@ -65,8 +65,12 @@ void ScaleNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c
                case CMP_SCALE_RENDERPERCENT: {
                        const RenderData *data = &context->getScene()->r;
                        ScaleFixedSizeOperation *operation = new ScaleFixedSizeOperation();
+
+                       /* framing options */
                        operation->setIsAspect((bnode->custom2 & CMP_SCALE_RENDERSIZE_FRAME_ASPECT) != 0);
                        operation->setIsCrop((bnode->custom2 & CMP_SCALE_RENDERSIZE_FRAME_CROP) != 0);
+                       operation->setOffset(bnode->custom3, bnode->custom4);
+
                        operation->setNewWidth(data->xsch * data->size / 100.0f);
                        operation->setNewHeight(data->ysch * data->size / 100.0f);
                        inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
index aea4da920a0c20f4b605d9b5d2e0b752390196af..45e846998af564dee19ba03116e04709b4bc4be9 100644 (file)
@@ -191,6 +191,21 @@ void ScaleFixedSizeOperation::initExecution()
        this->relX = inputOperation->getWidth() / (float)this->newWidth;
        this->relY = inputOperation->getHeight() / (float)this->newHeight;
 
+
+       /* *** all the options below are for a fairly special case - camera framing *** */
+       if (this->offsetX != 0.0f || this->offsetY != 0.0f) {
+               this->is_offset = true;
+
+               if (this->newWidth > this->newHeight) {
+                       this->offsetX *= this->newWidth;
+                       this->offsetY *= this->newWidth;
+               }
+               else {
+                       this->offsetX *= this->newHeight;
+                       this->offsetY *= this->newHeight;
+               }
+       }
+
        if (this->is_aspect) {
                /* apply aspect from clip */
                const float w_src = inputOperation->getWidth();
@@ -203,9 +218,6 @@ void ScaleFixedSizeOperation::initExecution()
                const float asp_src = w_src / h_src;
                const float asp_dst = w_dst / h_dst;
 
-               this->offsetX = 0.0f;
-               this->offsetY = 0.0f;
-
                if (fabsf(asp_src - asp_dst) >= FLT_EPSILON) {
                        if ((asp_src > asp_dst) == (this->is_crop == true)) {
                                /* fit X */
@@ -219,9 +231,11 @@ void ScaleFixedSizeOperation::initExecution()
                                this->relY /= div;
                                this->offsetY = ((h_src - (h_src * div)) / (h_src / h_dst)) / 2.0f;
                        }
-               }
 
+                       this->is_offset = true;
+               }
        }
+       /* *** end framing options *** */
 }
 
 void ScaleFixedSizeOperation::deinitExecution()
@@ -236,7 +250,7 @@ void ScaleFixedSizeOperation::executePixel(float *color, float x, float y, Pixel
        sampler = COM_PS_BICUBIC;
 #endif
 
-       if (this->is_aspect) {
+       if (this->is_offset) {
                float nx = ((x - this->offsetX) * relX);
                float ny = ((y - this->offsetY) * relY);
                this->inputOperation->read(color, nx, ny, sampler, inputBuffers);
index 3964a5e2f71ebb1474b1498e1372951398b96833..7089f6c10a484135a013b2f1e975bc5f8d3df992 100644 (file)
@@ -69,6 +69,9 @@ class ScaleFixedSizeOperation : public NodeOperation {
        float offsetY;
        bool is_aspect;
        bool is_crop;
+       /* set from other properties on initialization,
+        * check if we need to apply offset */
+       bool is_offset;
 public:
        ScaleFixedSizeOperation();
        bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
@@ -79,8 +82,9 @@ public:
        void deinitExecution();
        void setNewWidth(int width) { this->newWidth = width; }
        void setNewHeight(int height) { this->newHeight = height; }
-       void setIsAspect(int is_aspect) { this->is_aspect = is_aspect; }
-       void setIsCrop(int is_crop) { this->is_crop = is_crop; }
+       void setIsAspect(bool is_aspect) { this->is_aspect = is_aspect; }
+       void setIsCrop(bool is_crop) { this->is_crop = is_crop; }
+       void setOffset(float x, float y) { this->offsetX = x; this->offsetY = y; }
 };
 
 #endif
index e48dd39022ecf454c7b8311f8ae98de1d0c4892b..8aa56823baf821842f687bf6832e0f7ec31665bc 100644 (file)
@@ -2020,7 +2020,11 @@ static void node_composit_buts_scale(uiLayout *layout, bContext *UNUSED(C), Poin
        uiItemR(layout, ptr, "space", 0, "", ICON_NONE);
 
        if (RNA_enum_get(ptr, "space") == CMP_SCALE_RENDERPERCENT) {
+               uiLayout *row;
                uiItemR(layout, ptr, "frame_method", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+               row = uiLayoutRow(layout, TRUE);
+               uiItemR(row, ptr, "offset_x", 0, "X", ICON_NONE);
+               uiItemR(row, ptr, "offset_y", 0, "Y", ICON_NONE);
        }
 }
 
index 9567226f722d1b16bbd9e96b3cd40483c546bdaa..683a49a76902c634b178c7676e5d2cef30744ee0 100644 (file)
@@ -2106,6 +2106,16 @@ static void def_cmp_scale(StructRNA *srna)
        RNA_def_property_enum_items(prop, space_frame_items);
        RNA_def_property_ui_text(prop, "Frame Method", "How the image fits in the camera frame");
        RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+       prop = RNA_def_property(srna, "offset_x", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "custom3");
+       RNA_def_property_ui_text(prop, "X Offset", "Offset image horizontally (factor of image size)");
+       RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+       prop = RNA_def_property(srna, "offset_y", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "custom4");
+       RNA_def_property_ui_text(prop, "Y Offset", "Offset image vertically (factor of image size)");
+       RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 }
 
 static void def_cmp_rotate(StructRNA *srna)