Repository: opencv/opencv
File: modules/dnn/src/layers/affinegrid_layer.cpp (C++)

Code before:
// Copyright (C) 2025, BigVision LLC, all rights reserved.
// Third party copyrights are property of their respective owners.

#include "../precomp.hpp"
#include "../net_impl.hpp"
#include "layers_common.hpp"
#include <opencv2/dnn/shape_utils.hpp>

// ONNX operator: AffineGrid
// Spec: https://onnx.ai/onnx/operators/onnx__AffineGrid.html
// Supported opsets: 20

namespace cv {
namespace dnn {

class AffineGridLayerImpl CV_FINAL : public AffineGridLayer
{
public:
    AffineGridLayerImpl(const LayerParams& params)
    {
        setParamsFrom(params);
        align_corners = params.get<bool>("align_corners", false);
    }

private:
    template<typename T>
    void computeGrid2D(const Mat& theta, Mat& grid, int N, int H, int W,
                       float xs, float xd, float ys, float yd) const
    {
        const int total = N * H;
        parallel_for_(Range(0, total), [&](const Range& range){
            const int H_ = H;
            const int W_ = W;
            const float xs_ = xs, xd_ = xd, ys_ = ys, yd_ = yd;
            const Mat theta_ = theta;
            Mat grid_ = grid;
            int lastN = -1;
            const T* T0 = nullptr;
            const T* T1 = nullptr;
            for (int nyi = range.start; nyi < range.end; nyi++)
            {
                int n = nyi / H_;
                int y = nyi - n * H_;
                if (n != lastN)
                {
                    int i0[3] = {n, 0, 0};
                    int i1[3] = {n, 1, 0};
                    T0 = theta_.ptr<T>(i0);
                    T1 = theta_.ptr<T>(i1);
                    lastN = n;
                }

Review comment (refactor):
it makes sense to move those methods outside of the class and make functions. That may simplify further re-use of those kernels

Code after:
// Copyright (C) 2025, BigVision LLC, all rights reserved.
// Third party copyrights are property of their respective owners.

#include "../precomp.hpp"
#include "../net_impl.hpp"
#include "layers_common.hpp"
#include <opencv2/dnn/shape_utils.hpp>

// ONNX operator: AffineGrid
// Spec: https://onnx.ai/onnx/operators/onnx__AffineGrid.html
// Supported opsets: 20

namespace cv {
namespace dnn {

namespace {

template<typename T>
void computeGrid2D(const Mat& theta, Mat& grid, int N, int H, int W,
                   float xs, float xd, float ys, float yd)
{
    const int total = N * H;
    parallel_for_(Range(0, total), [&](const Range& range){
        const int H_ = H;
        const int W_ = W;
        const float xs_ = xs, xd_ = xd, ys_ = ys, yd_ = yd;
        const Mat theta_ = theta;
        Mat grid_ = grid;
        int lastN = -1;
        const T* T0 = nullptr;
        const T* T1 = nullptr;
        float T0_0 = 0.f, T1_0 = 0.f;
        for (int nyi = range.start; nyi < range.end; nyi++)
        {
            int n = nyi / H_;
            int y = nyi - n * H_;
            if (n != lastN)
            {
                int i0[3] = {n, 0, 0};
                int i1[3] = {n, 1, 0};
                T0 = theta_.ptr<T>(i0);
                T1 = theta_.ptr<T>(i1);
                T0_0 = (float)T0[0];
                T1_0 = (float)T1[0];
                lastN = n;
            }
            float ny = yd_ + ys_ * y;
            float base0 = (float)T0[1]*ny + (float)T0[2];
            float base1 = (float)T1[1]*ny + (float)T1[2];
            float* out = grid_.ptr<float>(n, y, 0);
            for (int x = 0; x < W_; x++)