diff --git a/zUtil_Deformation/GtGrainODFuvwSolver.m b/zUtil_Deformation/GtGrainODFuvwSolver.m
index f668980971291c02af7b646a3f19a8dffb13cff6..6b19033cf7a5c794d2eb1c1633f1375e3603f216 100644
--- a/zUtil_Deformation/GtGrainODFuvwSolver.m
+++ b/zUtil_Deformation/GtGrainODFuvwSolver.m
@@ -1,8 +1,11 @@
 classdef GtGrainODFuvwSolver < GtGrainODFwSolver
     properties
-        voxel_centers = [];
-        rspace_over_sampling = 1;
         size_rspace_volume = [];
+
+        voxel_centers = [];
+
+        rspace_oversampling = 1;
+        rspace_downscaling = 1;
     end
 
     methods (Access = public)
@@ -12,22 +15,27 @@ classdef GtGrainODFuvwSolver < GtGrainODFwSolver
     end
 
     methods (Access = public) % Low Level API
-        function build_orientation_sampling(self, ref_gr, det_index, oversize, oversampling, shape_functions)
-            self.build_orientation_sampling@GtGrainODFwSolver(ref_gr, det_index, oversize, oversampling, shape_functions);
+        function build_orientation_sampling(self, ref_gr, det_index)
+            self.build_orientation_sampling@GtGrainODFwSolver(ref_gr, det_index);
 
             self.chose_voxel_centers();
 
             num_vox_centers = size(self.voxel_centers, 1);
 
             switch (self.shape_functions_type)
-                case 'nw'
+                case 'nw2uvw'
+                    recgeo = self.parameters.recgeo(self.sampler.detector_index);
+
                     sf_nw = gtDefShapeFunctionsCreateNW(self.sampler, 2);
 
                     for ii_v = 1:num_vox_centers
                         fprintf('(%03d/%03d) ', ii_v, num_vox_centers);
                         disp_sampler = self.sampler.regenerate_displaced(self.voxel_centers(ii_v, :));
 
-                        self.shape_functions{ii_v} = gtDefShapeFunctionsNW2UVW(disp_sampler, sf_nw, false);
+                        self.shape_functions{ii_v} = gtDefShapeFunctionsNW2UVW( ...
+                            disp_sampler, sf_nw, 'recenter_sf', false, ...
+                            'rspace_oversampling', self.rspace_downscaling, ...
+                            'rspace_voxel_size', recgeo.voxsize * self.rspace_downscaling);
                     end
                 case 'uvw'
                     shape_functions_name = sprintf('tmp_shape_functions_uvw_%d_%d', ...
@@ -43,7 +51,8 @@ classdef GtGrainODFuvwSolver < GtGrainODFwSolver
                             fprintf('(%3d/%03d) ', ii_v, num_vox_centers);
                             disp_sampler = self.sampler.regenerate_displaced(self.voxel_centers(ii_v, :));
 
-                            self.shape_functions{ii_v} = gtDefShapeFunctionsFwdProjUVW(disp_sampler, 15, [], false);
+                            self.shape_functions{ii_v} = gtDefShapeFunctionsFwdProjUVW( ...
+                                disp_sampler, 'factor', 15, 'recenter_sf', false);
                         end
                         sfs = self.shape_functions;
                         save([shape_functions_name '.mat'], 'sfs', '-v7.3')
@@ -73,7 +82,7 @@ classdef GtGrainODFuvwSolver < GtGrainODFwSolver
 
             with_shape_functions = ~isempty(self.shape_functions);
             if (with_shape_functions)
-                if (any(strcmpi(self.shape_functions_type, {'uvw', 'nw'})))
+                if (any(strcmpi(self.shape_functions_type, {'uvw', 'nw2uvw'})))
                     for ii_o = numel(self.shape_functions{1}):-1:1
                         proj_w_lims(:, :, ii_o) = cat(1, self.shape_functions{1}{ii_o}(:).bbwim);
                     end
@@ -147,10 +156,10 @@ classdef GtGrainODFuvwSolver < GtGrainODFwSolver
             recgeo = self.parameters.recgeo(self.sampler.detector_index);
             ref_gr = self.sampler.get_reference_grain();
             proj = ref_gr.proj(self.sampler.detector_index);
-            r_space_vol_size = [proj.vol_size_y, proj.vol_size_x, proj.vol_size_z];
+            rspace_vol_dims = ceil([proj.vol_size_y, proj.vol_size_x, proj.vol_size_z] / self.rspace_downscaling);
 
-            max_dists_from_center = (r_space_vol_size - 1 ./ self.rspace_over_sampling) / 2;
-            self.size_rspace_volume = r_space_vol_size .* self.rspace_over_sampling;
+            max_dists_from_center = (rspace_vol_dims - 1 ./ self.rspace_oversampling) / 2;
+            self.size_rspace_volume = rspace_vol_dims .* self.rspace_oversampling;
             tot_voxels = prod(self.size_rspace_volume);
 
             self.voxel_centers = zeros(tot_voxels, 3);
@@ -161,7 +170,7 @@ classdef GtGrainODFuvwSolver < GtGrainODFwSolver
                 for ss_y = linspace(-max_dists_from_center(2), max_dists_from_center(2), self.size_rspace_volume(2))
                     for ss_x = linspace(-max_dists_from_center(1), max_dists_from_center(1), self.size_rspace_volume(1))
 
-                        offset_voxel = [ss_x, ss_y, ss_z] .* recgeo.voxsize;
+                        offset_voxel = [ss_x, ss_y, ss_z] .* recgeo.voxsize * self.rspace_downscaling;
 
                         self.voxel_centers(counter, :) = ref_gr.center + offset_voxel;
 
diff --git a/zUtil_Deformation/GtGrainODFwSolver.m b/zUtil_Deformation/GtGrainODFwSolver.m
index 0bc928b5874577e1797133e460f061e2f1ee7be7..fe9ae474f5e863b6fca7dab7eb1bdb72095ddf46 100644
--- a/zUtil_Deformation/GtGrainODFwSolver.m
+++ b/zUtil_Deformation/GtGrainODFwSolver.m
@@ -25,6 +25,9 @@ classdef GtGrainODFwSolver < handle
         verbose = false;
 
         data_type = 'double';
+
+        ospace_oversize = 1;
+        ospace_oversampling = 1;
     end
 
     methods (Access = public)
@@ -40,25 +43,16 @@ classdef GtGrainODFwSolver < handle
         % INPUT (varargin):
         %     'algorithm': {'cplsnn'} | 'sirt' | 'cplsl1nn' | 'cpl1nn'
         %     'lambda': 1e-2
-        %     'ospace_oversize': 1
-        %     'ospace_oversampling': 1
-        %     'shape_functions': {'none'} | 'w' | 'nw' | 'uvw'
         %     'det_index': 1
         %
 
             conf = struct( ...
                 'algorithm', 'cplsnn', ...
                 'lambda', 1e-2, ...
-                'ospace_oversize', 1, ...
-                'ospace_oversampling', 1, ...
-                'rspace_oversampling', 1, ...
-                'shape_functions', 'none', ...
                 'det_index', 1 );
             [conf, ~] = parse_pv_pairs(conf, varargin);
 
-            self.build_orientation_sampling(ref_gr, conf.det_index, ...
-                conf.ospace_oversize, conf.ospace_oversampling, ...
-                conf.shape_functions );
+            self.build_orientation_sampling(ref_gr, conf.det_index);
 
             self.build_sinogram();
             self.build_projection_matrices();
@@ -88,29 +82,24 @@ classdef GtGrainODFwSolver < handle
     end
 
     methods (Access = public) % Low Level API
-        function build_orientation_sampling(self, ref_gr, det_index, oversize, oversampling, shape_functions)
+        function build_orientation_sampling(self, ref_gr, det_index)
             if (~exist('det_index', 'var') || isempty(det_index))
                 det_index = 1;
             end
-            if (~exist('oversampling', 'var') || isempty(oversampling))
-                oversampling = 0;
-            end
 
             self.sampler = GtOrientationSampling(self.parameters, ref_gr, ...
                 'detector_index', det_index);
             % 'verbose', self.verbose,
 
-            self.sampler.make_grid_estim_ODF_resoluion('cubic', -oversampling, oversize);
+            self.sampler.make_grid_estim_ODF_resoluion('cubic', ...
+                -self.ospace_oversampling, self.ospace_oversize);
             self.size_volume = size(self.sampler.lattice.gr);
 
-            if (exist('shape_functions', 'var') && ~isempty(shape_functions))
-                switch (shape_functions)
-                    case 'none'
-                        self.shape_functions = [];
-                    case 'w'
-                        self.shape_functions = gtDefShapeFunctionsCreateW(self.sampler);
-                end
-                self.shape_functions_type = shape_functions;
+            switch (self.shape_functions_type)
+                case 'none'
+                    self.shape_functions = [];
+                case 'w'
+                    self.shape_functions = gtDefShapeFunctionsCreateW(self.sampler);
             end
         end
 
@@ -197,7 +186,7 @@ classdef GtGrainODFwSolver < handle
                     self.build_projection_matrices_sf_none();
                 case 'w'
                     self.build_projection_matrices_sf_w();
-                case {'nw', 'uvw'}
+                case {'nw2uvw', 'uvw'}
                     self.build_projection_matrices_sf_uvw();
             end
             fprintf('\b\b: Done in %f seconds.\n', toc(c));
diff --git a/zUtil_Deformation/gtDefShapeFunctionsFwdProjUVW.m b/zUtil_Deformation/gtDefShapeFunctionsFwdProjUVW.m
index 5f559e5cfde32a372e6d4fb8d6d61ec77aedd665..7d60a3f1ef5eb216deaa6be2069d90a4e30547fc 100644
--- a/zUtil_Deformation/gtDefShapeFunctionsFwdProjUVW.m
+++ b/zUtil_Deformation/gtDefShapeFunctionsFwdProjUVW.m
@@ -1,14 +1,13 @@
-function shape_funcs = gtDefShapeFunctionsFwdProjUVW(sampler, factor, dtype, recenter_sf)
+function shape_funcs = gtDefShapeFunctionsFwdProjUVW(sampler, varargin)
 
-    if (~exist('dtype', 'var') || isempty(dtype))
-        dtype = 'single';
-    end
-
-    if (~exist('recenter_sf', 'var') || isempty(recenter_sf))
-        recenter_sf = true;
-    end
-
-    interpolated_voxel = false;
+    conf = struct( ...
+        'recenter_sf', true, ...
+        'dtype', [], ...
+        'factor', 1, ...
+        'rspace_oversampling', 1, ...
+        'rspace_voxel_size', [1 1 1], ...
+        'interpolated_voxel', false);
+    conf = parse_pv_pairs(conf, varargin);
 
     num_detectors = numel(sampler.parameters.detgeo);
     det_ind = sampler.detector_index;
@@ -18,14 +17,14 @@ function shape_funcs = gtDefShapeFunctionsFwdProjUVW(sampler, factor, dtype, rec
     sampler.parameters.labgeo = labgeo;
 
     fed_pars_detector = struct(...
-        'blobsizeadd', [0 0 0], 'psf', [], 'apply_uv_shift', recenter_sf);
+        'blobsizeadd', [0 0 0], 'psf', [], 'apply_uv_shift', conf.recenter_sf);
     fedpars = struct( ...
-        'bltype', dtype, ...
+        'bltype', conf.dtype, ...
         'dcomps', [1 1 1 0 0 0 0 0 0] == 1, ...
         'defmethod', 'rod_rightstretch', ...
         'detector', repmat( fed_pars_detector, [num_detectors, 1]));
 
-    voxel_factor = factor([1 1 1]);
+    voxel_factor = conf.factor([1 1 1]);
     num_sub_voxels = prod(voxel_factor);
     ones_nsv = ones(num_sub_voxels, 1);
 
@@ -35,11 +34,11 @@ function shape_funcs = gtDefShapeFunctionsFwdProjUVW(sampler, factor, dtype, rec
     gv.ind = gv.ind';
 
     ref_gr = sampler.get_reference_grain();
-    gv.cs = ref_gr.center(ones_nsv, :)';
+    gv.cs = compute_centers(ref_gr.center, conf.rspace_voxel_size, conf.rspace_oversampling)';
 
     % computing the subsampling, used to deterine the shape functions
     voxel_size = sampler.stats.sampling.gaps;
-    if (interpolated_voxel)
+    if (conf.interpolated_voxel)
         half_voxel_size = voxel_size; % Enlarging to neighbours
         steps = voxel_size ./ voxel_factor * 2;
     else
@@ -69,10 +68,10 @@ function shape_funcs = gtDefShapeFunctionsFwdProjUVW(sampler, factor, dtype, rec
         end
     end
 
-    if (interpolated_voxel)
+    if (conf.interpolated_voxel)
         gv.pow = prod(1 - abs(gv.d ./ half_voxel_size(ones_nsv, :)'), 1);
     else
-        gv.pow = ones(1, num_sub_voxels, dtype);
+        gv.pow = ones(1, num_sub_voxels, conf.dtype);
     end
     gv.pow = gv.pow / sum(gv.pow);
 
@@ -99,3 +98,26 @@ function shape_funcs = gtDefShapeFunctionsFwdProjUVW(sampler, factor, dtype, rec
 
     fprintf('Done in %g seconds.\n', toc(c))
 end
+
+function centers = compute_centers(ref_center, rspace_voxel_size, rspace_oversampling)
+    if (numel(rspace_oversampling) == 1)
+        rspace_oversampling = rspace_oversampling([1 1 1]);
+    end
+    max_dists_from_center = rspace_voxel_size .* (1 - 1 ./ rspace_oversampling) / 2;
+    tot_voxels = prod(rspace_oversampling);
+
+    centers = zeros(tot_voxels, 3);
+
+    counter = 1;
+
+    for ss_z = linspace(-max_dists_from_center(3), max_dists_from_center(3), rspace_oversampling(3))
+        for ss_y = linspace(-max_dists_from_center(2), max_dists_from_center(2), rspace_oversampling(2))
+            for ss_x = linspace(-max_dists_from_center(1), max_dists_from_center(1), rspace_oversampling(1))
+
+                centers(counter, :) = ref_center + [ss_x, ss_y, ss_z];
+
+                counter = counter + 1;
+            end
+        end
+    end
+end
diff --git a/zUtil_Deformation/gtDefShapeFunctionsNW2UVW.m b/zUtil_Deformation/gtDefShapeFunctionsNW2UVW.m
index 868b86107bcb861616d9ce4c58dac98d6ac3e0dc..03cfe4beb35bb2aaece08172fc70b1c9858113ce 100644
--- a/zUtil_Deformation/gtDefShapeFunctionsNW2UVW.m
+++ b/zUtil_Deformation/gtDefShapeFunctionsNW2UVW.m
@@ -1,10 +1,13 @@
-function sfs_uvw = gtDefShapeFunctionsNW2UVW(sampler, sfs_nw, recenter_sf)
-% FUNCTION sfs_uvw = gtDefShapeFunctionsNW2UVW(sampler, sfs_nw)
+function sfs_uvw = gtDefShapeFunctionsNW2UVW(sampler, sfs_nw, varargin)
+% FUNCTION sfs_uvw = gtDefShapeFunctionsNW2UVW(sampler, sfs_nw, varargin)
 %
 
-    if (~exist('recenter_sf', 'var') || isempty(recenter_sf))
-        recenter_sf = true;
-    end
+    conf = struct( ...
+        'recenter_sf', true, ...
+        'dtype', [], ...
+        'rspace_oversampling', 1, ...
+        'rspace_voxel_size', [1 1 1] );
+    conf = parse_pv_pairs(conf, varargin);
 
     det_ind = sampler.detector_index;
 
@@ -13,6 +16,7 @@ function sfs_uvw = gtDefShapeFunctionsNW2UVW(sampler, sfs_nw, recenter_sf)
     samgeo = p.samgeo;
     detgeo = p.detgeo(det_ind);
 
+    ref_gr = sampler.get_reference_grain();
     ors = sampler.get_orientations();
 
     ref_sel = sampler.selected;
@@ -25,6 +29,9 @@ function sfs_uvw = gtDefShapeFunctionsNW2UVW(sampler, sfs_nw, recenter_sf)
             'Mismatching number of orientations and shape functions passed')
     end
 
+    centers = compute_centers(ref_gr.center, conf.rspace_voxel_size, conf.rspace_oversampling);
+    tot_centers = size(centers, 1);
+
     sfs_uvw = cell(tot_orientations, 1);
 
     rotcomp_w = gtMathsRotationMatrixComp(labgeo.rotdir, 'row');
@@ -48,7 +55,7 @@ function sfs_uvw = gtDefShapeFunctionsNW2UVW(sampler, sfs_nw, recenter_sf)
         blobs_nw_sizes = cat(1, sfs_in(:).bbsize);
 
         or_uv = ors{ii_o}.allblobs.detector(det_ind).uvw(ref_sel, 1:2);
-        if (recenter_sf)
+        if (conf.recenter_sf)
             or_uv_shift = or_uv;
         else
             or_uv_shift = round(or_uv);
@@ -89,12 +96,9 @@ function sfs_uvw = gtDefShapeFunctionsNW2UVW(sampler, sfs_nw, recenter_sf)
 
         % Calculating all the sample center positions at each omega inside
         % the blobs
-        ones_all_w = ones(numel(all_ws), 1);
-        gcsam_v_all = ors{ii_o}.center(ones_all_w, :);
-
         rot_s2l_all = gtMathsRotationTensor(all_ws, rotcomp_w);
-        gclab_v_all = gtGeoSam2Lab(gcsam_v_all, rot_s2l_all, labgeo, samgeo, false);
-        gclab_v_all = permute(gclab_v_all, [2 3 1]);
+        gclab_v_all = gtGeoSam2Lab(centers, rot_s2l_all, labgeo, samgeo, false, [], false);
+        gclab_v_all = reshape(gclab_v_all', 3, 1, tot_ws, []);
 
         %%% Here we put the scattering vectors and center positions
         %%% together
@@ -102,9 +106,9 @@ function sfs_uvw = gtDefShapeFunctionsNW2UVW(sampler, sfs_nw, recenter_sf)
         uv_min = zeros(tot_blobs, 2);
         uv_max = zeros(tot_blobs, 2);
 
-        blobs_nw_area_sizes = prod(blobs_nw_sizes, 2);
+        blobs_nw_area_sizes = prod(blobs_nw_sizes, 2) * tot_centers;
 
-        chunk = 32;
+        chunk = 16;
         for ii_base_b = 0:chunk:tot_blobs-1
             chunk_size = min(chunk, tot_blobs-ii_base_b);
 
@@ -120,7 +124,7 @@ function sfs_uvw = gtDefShapeFunctionsNW2UVW(sampler, sfs_nw, recenter_sf)
                 ii_b = ii_base_b + ii_var_b;
 
                 ones_n = ones(blobs_nw_sizes(ii_b, 1), 1);
-                ones_w = ones(blobs_nw_sizes(ii_b, 2), 1);
+                ones_w = ones(blobs_nw_sizes(ii_b, 2) * tot_centers, 1);
 
                 inds_bl_chunk = inds_chunk(ii_var_b, 1):inds_chunk(ii_var_b, 2);
 
@@ -128,7 +132,8 @@ function sfs_uvw = gtDefShapeFunctionsNW2UVW(sampler, sfs_nw, recenter_sf)
                 dveclab = dveclab(:, :, ones_w);
                 dveclab_chunk(:, inds_bl_chunk) = reshape(dveclab, 3, []);
 
-                gclab_v = gclab_v_all(:, :, inds_w(ii_b, 1):inds_w(ii_b, 2));
+                gclab_v = gclab_v_all(:, :, inds_w(ii_b, 1):inds_w(ii_b, 2), :);
+                gclab_v = reshape(gclab_v, size(gclab_v, 1), size(gclab_v, 2), []);
                 gclab_v = gclab_v(:, ones_n, :);
                 gclab_v_chunk(:, inds_bl_chunk) = reshape(gclab_v, 3, []);
             end
@@ -161,10 +166,22 @@ function sfs_uvw = gtDefShapeFunctionsNW2UVW(sampler, sfs_nw, recenter_sf)
             ws = 1:blobs_nw_sizes(ii_b, 2);
             ws = ws(ones(blobs_nw_sizes(ii_b, 1), 1), :);
             ws = reshape(ws, [], 1);
+            ws = reshape(ws(:, ones(tot_centers, 1)), [], 1);
 
-            ones_nw = ones(prod(blobs_nw_sizes(ii_b, :)), 1);
+            ones_nw = ones(blobs_nw_area_sizes(ii_b), 1);
 
             uv_bl = uv{ii_b} + uv_shift(ones_nw, :);
+            ints = reshape(sfs_in(ii_b).intm, [], 1);
+
+            if (isempty(conf.dtype))
+                uv_bl = cast(uv_bl, 'like', sfs_in(ii_b).intm);
+            else
+                uv_bl = cast(uv_bl, conf.dtype);
+                ints = cast(ints, conf.dtype);
+            end
+
+            ints = ints / tot_centers;
+            ints = reshape(ints(:, ones(tot_centers, 1)), [], 1);
 
             uv_l = floor(uv_bl); % lower pixel indices
             uv_h = uv_l + 1;     % higher pixel indices
@@ -176,10 +193,9 @@ function sfs_uvw = gtDefShapeFunctionsNW2UVW(sampler, sfs_nw, recenter_sf)
                 [uv_h(:, 1), uv_l(:, 2), ws]; ...
                 [uv_h, ws] ];
 
-            uv_l_c = cast(uv_h - uv_bl, 'like', sfs_in(ii_b).intm);
+            uv_l_c = uv_h - uv_bl;
             uv_h_c = 1 - uv_l_c;
 
-            ints = reshape(sfs_in(ii_b).intm, [], 1);
             ints4 = [ ...
                 uv_l_c(:, 1) .* uv_l_c(:, 1) .* ints; ...
                 uv_l_c(:, 1) .* uv_h_c(:, 2) .* ints; ...
@@ -206,3 +222,27 @@ function sfs_uvw = gtDefShapeFunctionsNW2UVW(sampler, sfs_nw, recenter_sf)
     fprintf(repmat('\b', [1, num_chars]));
     fprintf('Done in %g seconds.\n', toc(c))
 end
+
+function centers = compute_centers(ref_center, rspace_voxel_size, rspace_oversampling)
+    if (numel(rspace_oversampling) == 1)
+        rspace_oversampling = rspace_oversampling([1 1 1]);
+    end
+    max_dists_from_center = rspace_voxel_size .* (1 - 1 ./ rspace_oversampling) / 2;
+    tot_voxels = prod(rspace_oversampling);
+
+    centers = zeros(tot_voxels, 3);
+
+    counter = 1;
+
+    for ss_z = linspace(-max_dists_from_center(3), max_dists_from_center(3), rspace_oversampling(3))
+        for ss_y = linspace(-max_dists_from_center(2), max_dists_from_center(2), rspace_oversampling(2))
+            for ss_x = linspace(-max_dists_from_center(1), max_dists_from_center(1), rspace_oversampling(1))
+
+                centers(counter, :) = ref_center + [ss_x, ss_y, ss_z];
+
+                counter = counter + 1;
+            end
+        end
+    end
+end
+