%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%
%% Observer and Sun positions
%% view is also defined elsewhere
%% The longitude is computed in the Ozx plane, beginning at the Oz axis.
\tikzset{%
  view/.style 2 args={%  observer longitude and latitude (y upwards)
                      %  Remark. lomg=0 means x=0
    z={({-sin(#1)}, {-cos(#1)*sin(#2)})},
    x={({cos(#1)}, {-sin(#1)*sin(#2)})},
    y={(0, {cos(#2)})},
    evaluate={%
      \toxx={sin(#1)*cos(#2)};
      \toyy={sin(#2)};
      \tozz={cos(#1)*cos(#2)};
    },
    longitude = #1,
    latitude = #2
  },
  sun/.style n args={3}{% longitude, latitude, light contrast in [0, 1]
    evaluate={%
      real \sunxx, \sunyy, \sunzz;
      \sunxx = sin(#1)*cos(#2);
      \sunyy = sin(#2);
      \sunzz = cos(#1)*cos(#2);
    },
    sun longitude = #1,
    sun latitude = #2,
    contrast = #3
  }
}
\pgfkeys{/tikz/.cd,
  latitude/.store in=\toLatit,  % observer's latitude
  latitude=0
}
\pgfkeys{/tikz/.cd,
  longitude/.store in=\toLongit,  % observer's longitude
  longitude=0  % corresponds to x=0
}
\pgfkeys{/tikz/.cd,
  sun latitude/.store in=\sunLatit,
  sun latitude = 40
}
\pgfkeys{/tikz/.cd,
  sun longitude/.store in=\sunLongit, 
  sun longitude=-60  % on the left of the Oz axis
}
\pgfkeys{/tikz/.cd,
  contrast/.store in=\lightCtr,  % light contrast \in [0, 1]
  % It is introduced (modified) with the style sun.  The default value
  % allows the styles to know if the sun is on or off.
  % It is used under sor in pic objects with su and s variants.
  contrast=-1
}
\pgfkeys{/tikz/.cd,
  % Value of the inner product of the normal vector with the sun
  % direction for which the color is the local color.
  local color threshold/.store in=\lColorThreshold,
  local color threshold=.2
}
\pgfkeys{/tikz/.cd,
  % max value of the constant c in Color!c!LocalColor
  max color cst/.store in=\maxColorCst,
  max color cst=.99
}
\pgfkeys{/tikz/.cd,  % multiplicative coefficients used in ?? to be seen
  seen key/.store in=\seenKey,
  seen key=1
}
\pgfkeys{/tikz/.cd,
  unseen key/.store in=\unseenKey,
  unseen key=.2
}
\pgfkeys{/tikz/.cd,
  near zero/.store in=\nearZero,
  near zero=.01
}


%%%% bounds of the domain
\pgfkeys{/tikz/.cd,
  initialT/.store in=\initialT,
  initialT=0
}
\pgfkeys{/tikz/.cd,
  finalT/.store in=\finalT,
  finalT=1
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% general functions
\newcommand{\setColorsForRSurface}{%
  \colorlet{rgbLeft{0}}{K}  % not sun
  \colorlet{rgbLeft{1}}{W}  % sun
  \colorlet{rgbRight}{.}
}


\tikzmath{%
  function norm3d(\vectorx, \vrctory, \vectorz) {%
    real \res;
    \res = \vectorx*\vectorx +\vrctory*\vrctory +\vectorz*\vectorz;
    return {pow(\res, .5)};
  };
  function ipFaceAndTo(\nox, \noy, \noz) {%
    return {sign(\nFacex*\toxx +\nFacey*\toyy +\nFacez*\tozz)};
  };
  function whatLayer(\ip, \l1, \l2) {%
    if \ip>=0 then {% if seen
      return \l1;
    } else {%
      return \l2;
    };
  };
  %
  %% The next functions verify if the face is seen and then return a
  % color "number" depending on the sun position.  It is used in
  % rgbConstant.
  function faceColorCstI(\t) {%  I = increasing part [\lColorThreshold, 1]
    \tmpFCCst = \lightCtr* \maxColorCst;
    return \tmpFCCst/(pow(1 -\lColorThreshold, 2))*pow(\t -\lColorThreshold, 2);
  };
  function faceColorCstD(\t) {%  D = decreasing part [-1, \lColorThreshold)
    return -\lightCtr* \maxColorCst/(1 +\lColorThreshold)*(\t -\lColorThreshold);
  };
  function rgbConstant(\ipo, \ips) {%
    % \ipo = inner product with observer's direction
    % \ips =  inner product with sun's direction
    \ipsp = abs(\ips);
    if \ipo*\ips >= 0 then {% if seen in sun or unseen and not in sun
      if \ipsp >= \lColorThreshold then {%
        \tmprgbcst = faceColorCstI(\ipsp);
      } else {%
        \tmprgbcst = faceColorCstD(\ipsp);
      };
    } else {%
      \tmprgbcst = faceColorCstD(-\ipsp);
    };
    return min(int(100*\tmprgbcst), 100);
  };
  function rgbLeftIndex(\ipo, \ips) {%
    % \ipo = inner product with observer's direction
    % \ips =  inner product with sun's direction
    \ipsp = abs(\ips);
    \t = 0;
    if \ipo*\ips >= 0 then {% if seen in sun or unseen and not in sun
      if \ipsp >= \lColorThreshold then {%
        \t = 1;
      };
    };
    return \t;
  };
}



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% layers and show coordinates
\newcommand{\setlayers}[1]{% layers
  \foreach \k in {#1}{%
    \pgfdeclarelayer{\k}
  }
  \pgfsetlayers{#1}
}


\tikzset{%
  pics/showCoordinates/.style n args={3}{%
    %  #1 = length
    %  #2 = fg layer
    %  #3 = bg layer
    code={%
      \tikzmath{%
        integer \xyLayer, \zLayer;
        real \aLen, \aArrow, \aR;
        \aLen = #1;
        \aArrow = #1/6;
        \aR = #1/3;
        \xyLayer = #3;
        \zLayer = #2;
        if \toLongit>90 then {%
          \xyLayer = #2;
          \zLayer = #3;
        };
        if \toLongit<-90 then {%
          \xyLayer = #2;
          \zLayer = #3;
        };        
        {%
          \begin{pgfonlayer}{\xyLayer}
            \begin{scope}[canvas is xy plane at z=0]
              \draw[B, fill=B!60] (0, \aArrow/4) -- ++(\aLen, 0)
              -- ++(0, 3*\aArrow/4)
              -- ++(\aArrow, -\aArrow) -- ++(-\aArrow, -\aArrow)
              -- ++(0, 3*\aArrow/4) -- ++(-\aLen, 0) -- cycle;
              \draw[B, fill=B!60, rotate=90] (0, \aArrow/4) -- ++(\aLen, 0)
              -- ++(0, 3*\aArrow/4)
              -- ++(\aArrow, -\aArrow) -- ++(-\aArrow, -\aArrow)
              -- ++(0, 3*\aArrow/4) -- ++(-\aLen, 0) -- cycle;
              \draw[B, fill=B!60, even odd rule]
              (0, 0) circle (\aR)
              (0, 0) circle (.8*\aR);
            \end{scope}
          \end{pgfonlayer}
          \begin{pgfonlayer}{\zLayer}
            \begin{scope}[canvas is zx plane at y=0]
              \draw[W, line width=4pt] (0, \aArrow/4) -- ++(\aLen, 0)
              -- ++(0, 3*\aArrow/4)
              -- ++(\aArrow, -\aArrow) -- ++(-\aArrow, -\aArrow)
              -- ++(0, 3*\aArrow/4) -- ++(-\aLen, 0);
              \draw[O, fill=O] (0, \aArrow/4) -- ++(\aLen, 0)
              -- ++(0, 3*\aArrow/4)
              -- ++(\aArrow, -\aArrow) -- ++(-\aArrow, -\aArrow)
              -- ++(0, 3*\aArrow/4) -- ++(-\aLen, 0) -- cycle;
            \end{scope}
          \end{pgfonlayer}
        };
      }
    }
  }
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% Code elements
\tikzset{%
  new basis/.code={%
    \tikzmath{%
      \ux = \cay *\caz;
      \uy = \saz;
      \uz = -\say *\caz;
      \vx = -\cay *\saz *\cax +\say *\sax;
      \vy = \caz *\cax;
      \vz = \say *\saz *\cax +\cay *\sax;
      \wx = \cay *\saz *\sax +\say *\cax;
      \wy = -\caz *\sax;
      \wz = -\say *\saz *\sax +\cay *\cax;
    }
  },
  the points/.code={%  It takes one argument, the name of the curve. 
  % It constructs the points \P{\k,\j} with \k defining the meridian
  % and \j the parallel.  There are \NParallels+1 parallels equaly
  % spaced from \initialT to \finalT.  There are \NMeridians (the one
  % with index 0 coincides with the last one, with index \NMeridians).
    \tikzmath{%
      for \j in {0, ..., \NParallels}{% the plane (Ozx) |-> 0
        \s = \initialT +\j/\NParallels*(\finalT -\initialT);
        \yC0 = y#1(\s);
        \zC0 = z#1(\s);
        for \k in {0, ..., \NMeridians}{% (Oz) |-> 0
          \t = \k/\NMeridians*360;
          \wTmp = cos(\t)*\zC0;
          \vTmp = \yC0;
          \uTmp = sin(\t)*\zC0;
          \Px{\k,\j} = \wTmp*\wx +\vTmp*\vx +\uTmp*\ux;
          \Py{\k,\j} = \wTmp*\wy +\vTmp*\vy +\uTmp*\uy;
          \Pz{\k,\j} = \wTmp*\wz +\vTmp*\vz +\uTmp*\uz;
        };
      };
    }
  },
  face normal vector and ips/.code={%
  % It depends on the value of \lightCtr.  If >=0, i.e. if the light
  % source is given, then the inner product with the light direction
  % is computed. 
  % 
  % Elements for each face  \ax, ...
  % \i for meridians (around Oy)
  % \j parallels (from -pi/2 to pi/2 for example)
  % \j = 1 is special
  % 
  % n unit normal vector and the inner products with observer and
  % sun needed for faceColor.
  % 
  % The (a, b, n) vectors  form a direct basis and n points
  % towards the "exterior" of the 3d object to be drawn.
    \tikzmath{%
      integer \i, \tmpInt;
      for \j in {1, ..., \NParallels}{%
        \prevj = \j -1;
        if \j==1 then {%
          \i = \j;
        } else {%
          \i = \prevj;
        };
        for \k in {0, ..., \NMeridians}{%
          \prevk = int(Mod(\k -1, \NMeridians));
          \ax = \Px{\k,\i} -\Px{\prevk,\prevj};
          \ay = \Py{\k,\i} -\Py{\prevk,\prevj};
          \az = \Pz{\k,\i} -\Pz{\prevk,\prevj};
          \aTmpNorm = norm3d(\ax, \ay, \az);
          \ax = \ax/\aTmpNorm;
          \ay = \ay/\aTmpNorm;
          \az = \az/\aTmpNorm;
          \bx = \Px{\prevk,\j} -\Px{\prevk,\prevj};
          \by = \Py{\prevk,\j} -\Py{\prevk,\prevj};
          \bz = \Pz{\prevk,\j} -\Pz{\prevk,\prevj};
          \bTmpNorm = norm3d(\bx, \by, \bz);
          \bx = \bx/\bTmpNorm;
          \by = \by/\bTmpNorm;
          \bz = \bz/\bTmpNorm;        
          \nFacex = \ay*\bz -\az*\by;
          \nFacey = -\ax*\bz +\az*\bx;
          \nFacez = \ax*\by -\ay*\bx;
          \tmp = norm3d(\nFacex, \nFacey, \nFacez);
          \nFacex = \nFacex/\tmp;
          \nFacey = \nFacey/\tmp;
          \nFacez = \nFacez/\tmp; % the normal vector is normalized
          \ipFTo{\k,\j} = \nFacex*\toxx +\nFacey*\toyy +\nFacez*\tozz;
          if \lightCtr>=0 then {%
            \ipFSun{\k,\j} = \nFacex*\sunxx +\nFacey*\sunyy +\nFacez*\sunzz;
          };
        };
      };
    }
  },
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% Main style and pic objects
\tikzset{%
  sor/.style args={name=#1,
    meridians=#2, parallels=#3, t_ini=#4, t_end=#5, rAxis=#6}{%
    % It provides the elements for drawing the quadrilaterals
    % forming a surface of revolution, i.e. the points for the
    % rotating surface obtained by rotating the curve given by #1
    % around the Oy axis. 
    % There are #2 meridians and #3+1 parallels. The variables 
    % \NMeridians, \NParallels, ... act as global  variables.  
    % 
    % #6 is the position of the rotational axis.  It is the image of
    % Oy through a rotation of #6_1 around Ox followed by #6_3 around
    % Oz and by #6_2 around Oy. 
    evaluate={%
      real \a, \s, \t, \ipFTo, \ipFTo;
      real \cax, \sax, \cay, \say, \caz, \saz;
      real \ux, \uy, \uz, \vx, \vy, \vz, \wx, \wy, \wz;
      integer \NMeridians, \NParallels;
      integer \j, \k, \i, \prevj, \prevk; % \prev[] needed in codes 
      \NMeridians = #2;
      \NParallels = #3;
      \initialT = #4;
      \finalT = #5;
      \i = 0; 
      for \tmp in {#6}{%  angles that characterise the axis of
                     %  rotation's position; in fact the new basis
                     %  obtained by the compositon R_\ay R_\az R_\ax.
        \i = \i +1;
        \aVar\i = \tmp;
      };
      \cax = cos(\aVar1);
      \sax = sin(\aVar1);
      \cay = cos(\aVar2);
      \say = sin(\aVar2);
      \caz = cos(\aVar3);
      \saz = sin(\aVar3);
    },
    new basis,
    the points={#1},
    face normal vector and ips
  },
}


\tikzset{%
  pics/meridian/.style args={index=#1, layer=#2}{%
    %  index is in 0, ..., \NMeridians -1
    code={%
      \tikzmath{%
        integer \j;
        {%
          \begin{pgfonlayer}{#2}
            \draw[color=.] (\Px{#1,0}, \Py{#1,0}, \Pz{#1,0})
            \foreach \j in {1, ..., \NParallels}{%
              -- (\Px{#1,\j}, \Py{#1,\j}, \Pz{#1,\j})
            };
          \end{pgfonlayer}
        };
      }
    }
  },  
  pics/parallel/.style args={index=#1, layer=#2}{%
    %  index is in 0, ..., \NParallels
    code={%
      \tikzmath{%
        integer \k;
        {%
          \begin{pgfonlayer}{#2}
            \draw[color=.] (\Px{0,#1}, \Py{0,#1}, \Pz{0,#1})
            \foreach \k in {1, ..., \NMeridians}{%
              -- (\Px{\k,#1}, \Py{\k,#1}, \Pz{\k,#1})
            };
          \end{pgfonlayer}
        };
      }
    }
  },
  pics/meridians/.style args={initial=#1, multiple=#2, layer=#3}{%
    % displays meridians #1 + \i \cdot #2
    code={%
      \tikzmath{%
        integer \i, \j, \k;
        \k = #1;
        for \i in {0, ..., int(\NMeridians/#2) -1}{%
          {%
            \begin{pgfonlayer}{#3}
              \draw[color=.] (\Px{\k,0}, \Py{\k,0}, \Pz{\k,0})
              \foreach \j in {1, ..., \NParallels}{%
                -- (\Px{\k,\j}, \Py{\k,\j}, \Pz{\k,\j})
              };
            \end{pgfonlayer}
          };
          \k = \k + #2;
        };
      }
    }
  },
  pics/parallels/.style args={initial=#1, multiple=#2, layer=#3}{%
    % displays parallels #1 + \i \cdot #2
    code={%
      \tikzmath{%
        integer \i, \j, \k, \bound;
        \j = #1;
        if \j == 0 then {%
          \bound = int(\NParallels/#2);
        } else {%
          \bound = int(\NParallels/#2) -1;
        };
        for \i in {0, ..., \bound}{%
          {%
            \begin{pgfonlayer}{#3}
              \draw[color=.] (\Px{0,\j}, \Py{0,\j}, \Pz{0,\j})
              \foreach \k in {1, ..., \NMeridians}{%
                -- (\Px{\k,\j}, \Py{\k,\j}, \Pz{\k,\j})
              };
            \end{pgfonlayer}
          };
          \j = \j + #2;
        };
      }
    }
  }
}


\tikzset{%
  pics/rSurface/.style args={above=#1, below=#2, actions=#3}{%
    % #1 = fg layer
    % #2 = bg layer
    % #3 = actions 
    code={%
      \tikzmath{%  
        integer \j, \k, \prevk, \prevj, \layerI, \rgbCst;
        %% faces
        for \j in {1, ..., \NParallels}{%
          for \k in {1, ..., \NMeridians}{%
            \prevk = \k -1;
            \prevj = \j -1;
            \layerI = whatLayer(\ipFTo{\k,\j}, #1, #2);
            {%
              \begin{pgfonlayer}{\layerI}
                \path[., #3]
                (\Px{\prevk,\prevj}, \Py{\prevk,\prevj}, \Pz{\prevk,\prevj})
                -- (\Px{\prevk,\j}, \Py{\prevk,\j}, \Pz{\prevk,\j})
                -- (\Px{\k,\j}, \Py{\k,\j}, \Pz{\k,\j})
                -- (\Px{\k,\prevj}, \Py{\k,\prevj}, \Pz{\k,\prevj})
                -- cycle;
              \end{pgfonlayer}
            };
          };
        };
      }
    }
  },
  pics/rSurface L/.style args={above=#1, below=#2, actions=#3}{%
    % #1 = fg layer
    % #2 = bg layer
    % #3 = actions (drawn must be provided if full opacity
    code={% !!
      \setColorsForRSurface
      \tikzmath{%  
        integer \j, \k, \prevk, \prevj, \layerI, \rgbCst, \li;
        real \ipToTmp, \ipSunTmp, \ipSunTmpP;
        %% faces
        for \k in {1, ..., \NMeridians}{% 
          for \j in {1, ..., \NParallels}{%
            \prevk = \k -1;
            \prevj = \j -1;
            \layerI = whatLayer(\ipFTo{\k,\j}, #1, #2);
            \li = rgbLeftIndex(\ipFTo{\k,\j}, \ipFSun{\k,\j});
            \rgbCst = rgbConstant(\ipFTo{\k,\j}, \ipFSun{\k,\j});
            {%
              \begin{pgfonlayer}{\layerI}
                \fill[rgbLeft{\li}!\rgbCst!rgbRight,
                line width=.0001pt, #3]
                (\Px{\prevk,\prevj}, \Py{\prevk,\prevj}, \Pz{\prevk,\prevj})
                -- (\Px{\k,\prevj}, \Py{\k,\prevj}, \Pz{\k,\prevj})
                -- (\Px{\k,\j}, \Py{\k,\j}, \Pz{\k,\j})
                -- (\Px{\prevk,\j}, \Py{\prevk,\j}, \Pz{\prevk,\j})
                -- cycle;
              \end{pgfonlayer}
            };
          };
        };
      }
    }
  },
  pics/partial rSurface/.style args={above=#1, below=#2, actions=#3,
    i from=#4, i to=#5}{%
    % #1 = fg layer
    % #2 = bg layer
    % #3 = actions 
    % #4 = index of the first meridian
    % #5 = index of the last meridian 
    code={%
      \tikzmath{%  
        integer \j, \k, \prevk, \prevj, \layerI, \rgbCst, \kini, \kend;
        if #4 < #5 then {%
          \kini = int(#4 +1);
          \kend = #5;
        } else {%
          \kini = #4;
          \kend = int(#5 +1);          
        };
        %% faces
        for \k in {\kini, ..., \kend}{% 
          for \j in {1, ..., \NParallels}{%
            \prevk = int(Mod(\k -1, \NMeridians));
            \k = int(Mod(\k, \NMeridians));  % when the index is
                                             % bigger than the number of meridians
            if \k==0 then {%
              \k = \NMeridians;
            };
            \prevj = \j -1;
            \layerI = whatLayer(\ipFTo{\k,\j}, #1, #2);
            {%
              \begin{pgfonlayer}{\layerI}
                \path[., #3]
                (\Px{\prevk,\prevj}, \Py{\prevk,\prevj}, \Pz{\prevk,\prevj})
                -- (\Px{\prevk,\j}, \Py{\prevk,\j}, \Pz{\prevk,\j})
                -- (\Px{\k,\j}, \Py{\k,\j}, \Pz{\k,\j})
                -- (\Px{\k,\prevj}, \Py{\k,\prevj}, \Pz{\k,\prevj})
                -- cycle;
              \end{pgfonlayer}
            };
          };
        };
      }
    }
  },
  pics/partial rSurface L/.style args={above=#1, below=#2, actions=#3,
    i from=#4, i to=#5}{%
    % #1 = fg layer
    % #2 = bg layer
    % #3 = actions 
    % #4 = index of the first meridian
    % #5 = index of the last meridian 
    code={%
      \setColorsForRSurface
      \tikzmath{%  
        integer \j, \k, \kini, \kend, \prevk, \prevj, \layerI, \rgbCst;
        %% faces
        if #4 < #5 then {%
          \kini = int(#4 +1);
          \kend = #5;
        } else {%
          \kini = #4;
          \kend = int(#5 +1);          
        };
        for \k in {\kini, ..., \kend}{% 
          for \j in {1, ..., \NParallels}{%
            \prevk = int(Mod(\k -1, \NMeridians));
            \k = int(Mod(\k, \NMeridians));  % when the index is
                                % bigger than the number of meridians
            \prevj = \j -1;
            \layerI = whatLayer(\ipFTo{\k,\j}, #1, #2);
            \li = rgbLeftIndex(\ipFTo{\k,\j}, \ipFSun{\k,\j});
            \rgbCst = rgbConstant(\ipFTo{\k,\j}, \ipFSun{\k,\j});
            {%
              \begin{pgfonlayer}{\layerI}
                \fill[rgbLeft{\li}!\rgbCst!rgbRight,
                line width=.0001pt, #3]
                (\Px{\prevk,\prevj}, \Py{\prevk,\prevj}, \Pz{\prevk,\prevj})
                -- (\Px{\prevk,\j}, \Py{\prevk,\j}, \Pz{\prevk,\j})
                -- (\Px{\k,\j}, \Py{\k,\j}, \Pz{\k,\j})
                -- (\Px{\k,\prevj}, \Py{\k,\prevj}, \Pz{\k,\prevj})
                -- cycle;
              \end{pgfonlayer}
              % \path (-5 +.7*\k, \j +\k/3, 0)
              % node[scale=.8] {\k, \j, \ipFTo{\k,\j}, \rgbCst, \li}; 
            };
          };
        };
      }
    }
  },
  pics/rSurface x/.style args={above=#1, below=#2, actions=#3, factor=#4}{%
    % In this version, only the borders of certain quadrilaterals are
    % drawn.  The choice is done through #4 which is a common factor of
    % \NMeridians and \NParallels.
    %
    % Note that the first parallel (for \j = 0) must be drawn and it
    % is nor obtainable using the previous structure (from rSurface).
    %
    % #1 = fg layer
    % #2 = bg layer
    % #3 = actions
    % #4 = factor
    code={%
      \tikzmath{%  
        integer \j, \k, \prevk, \prevj, \layerI, \rgbCst;
        %% faces
        for \k in {1, ..., \NMeridians}{% 
          for \j in {1, ..., \NParallels}{%
            \prevk = int(Mod(\k -1, \NMeridians));
            \prevj = \j -1;
            \layerI = whatLayer(\ipFTo{\k,\j}, #1, #2);
            {%
              \begin{pgfonlayer}{\layerI}
                \path[#3]
                (\Px{\prevk,\prevj}, \Py{\prevk,\prevj}, \Pz{\prevk,\prevj})
                -- (\Px{\prevk,\j}, \Py{\prevk,\j}, \Pz{\prevk,\j})
                -- (\Px{\k,\j}, \Py{\k,\j}, \Pz{\k,\j})
                -- (\Px{\k,\prevj}, \Py{\k,\prevj}, \Pz{\k,\prevj})
                -- cycle;
              \end{pgfonlayer}
            };
            if \k==1 then {%
              {%
                \begin{pgfonlayer}{\layerI}
                  \draw[.]
                  (\Px{0,\j}, \Py{0,\j}, \Pz{0,\j})
                  -- (\Px{0,\prevj}, \Py{0,\prevj}, \Pz{0,\prevj});
                \end{pgfonlayer}
              };
            };
            if int(Mod(\k, #4))==0 then {%
              {%
                \begin{pgfonlayer}{\layerI}
                  \draw[.]
                  (\Px{\k,\j}, \Py{\k,\j}, \Pz{\k,\j})
                  -- (\Px{\k,\prevj}, \Py{\k,\prevj}, \Pz{\k,\prevj});
                \end{pgfonlayer}
              };
            };
            if \j==1 then {%
              {%
                \begin{pgfonlayer}{\layerI}
                  \draw[.]
                  (\Px{\prevk,0}, \Py{\prevk,0}, \Pz{\prevk,0})
                  -- (\Px{\k,0}, \Py{\k,0}, \Pz{\k,0});
                \end{pgfonlayer}
              };
            };      
            if int(Mod(\j, #4))==0 then {%
              {%
                \begin{pgfonlayer}{\layerI}
                  \draw[.]
                  (\Px{\prevk,\j}, \Py{\prevk,\j}, \Pz{\prevk,\j})
                  -- (\Px{\k,\j}, \Py{\k,\j}, \Pz{\k,\j});
                \end{pgfonlayer}
              };
            };      
          };
        };
      }
    }
  },
}

