Move to new question
I am wrting a package with tikz to plot 3d blocks and have made it to plot a grid block.
\documentclass[tikz, border=4mm]{standalone}
\usepackage{dnnplot}
\begin{document}
\begin{tikzpicture}
\node[block={scale=1, x=30mm, y=30mm, z=30mm, grid={(4,3,3)}, back plot}, anchor=back south west] (a) at (0, 0) {};
\end{tikzpicture}
\end{document}
Now I have some trouble when I want to make a grid block to have anchors at grid points. It is kind of like what matrix do in tikz, but actually these anchors are declared in shape's definition. I have referenced this answer. But my case is a little more complex and I have spun myself. The only thing I realize is that when I try to get the value of the key in \declareshape{...} straightly rather than in \anchor{...}, \saveddimen{...} and so on, the value is just what they are initially set. It is not my expected result.
And so sorry for putting all my code here without some simplization... The commented code is my awful attempt. Some explaination about the options is in https://github.com/ZhiyuanLck/dnnplot.
dnnplot.sty
\ProvidesPackage{dnnplot}
\RequirePackage{pdftexcmds}
\RequirePackage{tikz}
\makeatletter
\newif\ifback@plot
\newif\ifplane@block
% #1 parse mode #2 + or -
\def\grid@parse@temp#1#2{
\long\expandafter\def\csname grid@parse@#1@temp\endcsname##1##2{
\pgfmathparse{##1comp(##2)}
\expandafter\pgfmathtruncatemacro\csname
grid@#1@temp##1\endcsname{ifthenelse(\pgfmathresult #2 1, \pgfmathresult #2 1, 0)}
}
}
\grid@parse@temp{line}{-}
\long\def\grid@parse@line(#1){
\grid@parse@line@temp{x}{#1}
\grid@parse@line@temp{y}{#1}
\grid@parse@line@temp{z}{#1}
}
\grid@parse@temp{anchor}{+}
\long\def\grid@parse@anchor(#1){
\grid@parse@anchor@temp{x}{#1}
\grid@parse@anchor@temp{y}{#1}
\grid@parse@anchor@temp{z}{#1}
}
\pgfmathdeclarefunction{xcomp}{3}{
\begingroup
\pgfmathparse{#1}
\pgfmathsmuggle\pgfmathresult
\endgroup
}
\pgfmathdeclarefunction{ycomp}{3}{
\begingroup
\pgfmathparse{#2}
\pgfmathsmuggle\pgfmathresult
\endgroup
}
\pgfmathdeclarefunction{zcomp}{3}{
\begingroup
\pgfmathparse{#3}
\pgfmathsmuggle\pgfmathresult
\endgroup
}
\pgfkeys{/block plot/.cd,
x/.store in=\block@xcoordinate, x=0cm,
y/.store in=\block@ycoordinate, y=0cm,
z/.store in=\block@zcoordinate, z=0cm,
scale/.store in=\block@scale, scale=.5,
pre/.store in=\block@pre, pre=,
back plot/.is if=back@plot,
plane/.is if=plane@block,
zshift/.store in=\block@zshift, zshift=0,
front/.store in=\block@front, front=,
align axis/.store in=\block@align@axis, align axis=x,
hfactor/.store in=\block@hfactor, hfactor=.5,
vfactor/.store in=\block@vfactor, vfactor=.5,
align/.store in=\block@align, align=center,
grid/.store in=\block@grid, grid={(1,1,1)},
% grid/.initial={(1,1,1)},
% grid/.default={(1,1,1)},
}
\pgfdeclareshape{base block}
{
\inheritsavedanchors[from=rectangle]
\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{north}
\inheritanchor[from=rectangle]{south}
\inheritanchor[from=rectangle]{east}
\inheritanchor[from=rectangle]{west}
\inheritanchor[from=rectangle]{north east}
\inheritanchor[from=rectangle]{south west}
\inheritanchor[from=rectangle]{north west}
\inheritanchor[from=rectangle]{south east}
\saveddimen{\offset}{
\pgfmathsetlength\pgf@x{
sqrt(2)/8*\block@scale*\block@zcoordinate
}
}
\saveddimen{\grid@xsep}{
\expandafter\grid@parse@line\block@grid
\typeout{xtemp \grid@line@tempx}
\pgfmathsetlength\pgf@x{\block@scale/(\grid@line@tempx+1)*\block@xcoordinate}
}
\saveddimen{\grid@ysep}{
\expandafter\grid@parse@line\block@grid
\pgfmathsetlength\pgf@x{\block@scale/(\grid@line@tempy+1)*\block@ycoordinate}
}
\saveddimen{\grid@zsep}{
\expandafter\grid@parse@line\block@grid
\pgfmathsetlength\pgf@x{sqrt(2)/4*\block@scale/(\grid@line@tempz+1)*\block@zcoordinate}
}
\anchor{front}{
\pgf@process{\southwest}
\pgf@xa=.5\pgf@x
\pgf@ya=.5\pgf@y
\pgf@process{\northeast}
\pgf@x=.5\pgf@x
\pgf@y=.5\pgf@y
\advance \pgf@x by \pgf@xa
\advance \pgf@y by \pgf@ya
\advance \pgf@x by -\offset
\advance \pgf@y by -\offset
}
\anchor{back}{
\pgf@process{\southwest}
\pgf@xa=.5\pgf@x
\pgf@ya=.5\pgf@y
\pgf@process{\northeast}
\pgf@x=.5\pgf@x
\pgf@y=.5\pgf@y
\advance \pgf@x by \pgf@xa
\advance \pgf@y by \pgf@ya
\advance \pgf@x by \offset
\advance \pgf@y by \offset
}
\anchor{front south west}{
\pgf@process{\southwest}
\advance \pgf@x by -\offset
\advance \pgf@y by -\offset
}
\anchor{back south west}{
\pgf@process{\southwest}
\advance \pgf@x by \offset
\advance \pgf@y by \offset
}
\anchor{front north east}{
\pgf@process{\northeast}
\advance \pgf@x by -\offset
\advance \pgf@y by -\offset
}
\anchor{back north east}{
\pgf@process{\northeast}
\advance \pgf@x by \offset
\advance \pgf@y by \offset
}
\anchor{front south east}{
\pgf@process{\northeast}
\pgf@xa=\pgf@x
\advance \pgf@xa by -\offset
\pgf@process{\southwest}
\advance \pgf@y by -\offset
\pgf@x=\pgf@xa
}
\anchor{back south east}{
\pgf@process{\northeast}
\pgf@xa=\pgf@x
\advance \pgf@xa by \offset
\pgf@process{\southwest}
\advance \pgf@y by \offset
\pgf@x=\pgf@xa
}
\anchor{front north west}{
\pgf@process{\southwest}
\pgf@xa=\pgf@x
\advance \pgf@xa by -\offset
\pgf@process{\northeast}
\advance \pgf@y by -\offset
\pgf@x=\pgf@xa
}
\anchor{back north west}{
\pgf@process{\southwest}
\pgf@xa=\pgf@x
\advance \pgf@xa by \offset
\pgf@process{\northeast}
\advance \pgf@y by \offset
\pgf@x=\pgf@xa
}
% grid anchor
\expandafter\grid@parse@line\block@grid
%output is "expected:3, real:0"
\typeout{expected:3, real:\grid@line@tempx}
% \pgfmathsetlengthmacro\grid@xsep{\block@scale/(\grid@line@tempx+1)*\block@xcoordinate}
% \pgfmathsetlengthmacro\grid@ysep{\block@scale/(\grid@line@tempy+1)*\block@ycoordinate}
% \expandafter\grid@parse@anchor\block@grid
% \foreach \grid@i in {1, ...,\grid@anchor@tempx}{
% \foreach \grid@j in {1, ...,\grid@anchor@tempy}{
% \edef\make@anchor#1#2{
% \anchor{xy+\grid@i-\grid@j}{
% \typeout{xxi: \grid@i}
% \typeout{xxs: \grid@xsep}
% \pgf@process{\southwest}
% \advance \pgf@x by -\offset
% \advance \pgf@y by -\offset
% \pgfmathsetlength\pgf@x{\pgf@x+(\grid@i-1)*\grid@xsep}
% \pgfmathsetlength\pgf@y{\pgf@y+(\grid@i-1)*\grid@ysep}
% }
% }
% }
% }
\backgroundpath{
\pgf@process{\southwest}
\pgfmathsetlengthmacro\block@xa{\pgf@x}
\pgfmathsetlengthmacro\block@ya{\pgf@y}
\pgf@process{\northeast}
\pgfmathsetlengthmacro\block@xb{\pgf@x}
\pgfmathsetlengthmacro\block@yb{\pgf@y}
\def\block@add@offset##1{
\pgfpointadd{##1}{\pgfqpoint{\offset}{\offset}}
}
\def\block@sub@offset##1{
\pgfpointadd{##1}{\pgfqpoint{-\offset}{-\offset}}
}
\def\block@southwest{\pgfqpoint{\block@xa}{\block@ya}}
\def\block@southeast{\pgfqpoint{\block@xb}{\block@ya}}
\def\block@northeast{\pgfqpoint{\block@xb}{\block@yb}}
\def\block@northwest{\pgfqpoint{\block@xa}{\block@yb}}
\ifplane@block
% plane block in y-z plane, x = 0
\ifdim\block@xcoordinate=0pt
\pgfpathmoveto{\block@sub@offset{\block@southwest}}
\pgfpathlineto{\block@add@offset{\block@southwest}}
\pgfpathlineto{\block@add@offset{\block@northwest}}
\pgfpathlineto{\block@sub@offset{\block@northwest}}
\pgfpathclose
\fi
% plane block in x-z plane, y = 0
\ifdim\block@ycoordinate=0pt
\pgfpathmoveto{\block@sub@offset{\block@southwest}}
\pgfpathlineto{\block@sub@offset{\block@southeast}}
\pgfpathlineto{\block@add@offset{\block@southeast}}
\pgfpathlineto{\block@add@offset{\block@southwest}}
\pgfpathclose
\fi
% plane block in x-y plane, z = 0
\ifdim\block@zcoordinate=0pt
\pgfpathmoveto{\block@sub@offset{\block@southwest}}
\pgfpathlineto{\block@sub@offset{\block@southeast}}
\pgfpathlineto{\block@sub@offset{\block@northeast}}
\pgfpathlineto{\block@sub@offset{\block@northwest}}
\pgfpathclose
\fi
\else
% main path
\pgfpathmoveto{\block@sub@offset{\block@southwest}}
\pgfpathlineto{\block@sub@offset{\block@southeast}}
\pgfpathlineto{\block@add@offset{\block@southeast}}
\pgfpathlineto{\block@add@offset{\block@northeast}}
\pgfpathlineto{\block@add@offset{\block@northwest}}
\pgfpathlineto{\block@sub@offset{\block@northwest}}
\pgfpathclose
% other edge
\pgfpathmoveto{\block@sub@offset{\block@northeast}}
\pgfpathlineto{\block@sub@offset{\block@northwest}}
\pgfpathmoveto{\block@sub@offset{\block@northeast}}
\pgfpathlineto{\block@sub@offset{\block@southeast}}
\pgfpathmoveto{\block@sub@offset{\block@northeast}}
\pgfpathlineto{\block@add@offset{\block@northeast}}
\fi
}
\foregroundpath{
\def\back@plot@temp{
\pgfsetdash{{1mm}{1mm}}{0mm}
\pgfpathmoveto{\block@add@offset{\block@southwest}}
\pgfpathlineto{\block@sub@offset{\block@southwest}}
\pgfpathmoveto{\block@add@offset{\block@southwest}}
\pgfpathlineto{\block@add@offset{\block@northwest}}
\pgfpathmoveto{\block@add@offset{\block@southwest}}
\pgfpathlineto{\block@add@offset{\block@southeast}}
\pgfusepath{stroke}
}
\def\if@back@plot{0}
\ifback@plot
\def\if@back@plot{1}
\fi
%grid
\expandafter\grid@parse@line\block@grid
\def\grid@offset##1##2##3##4{
\pgfpointadd{\pgfqpoint{##1}{##2}}{\csname block@##3@offset\endcsname{\csname block@##4\endcsname}}
}
% x axis
\ifnum\grid@line@tempx>0
\foreach \grid@i in {1, ..., \grid@line@tempx}{
\pgfmathsetlengthmacro\grid@for@temp{\grid@i*\grid@xsep}
\pgfscope
\pgfsetlinewidth{.5\pgflinewidth}
\pgfpathmoveto{\grid@offset{\grid@for@temp}{0cm}{sub}{southwest}}
\pgfpathlineto{\grid@offset{\grid@for@temp}{0cm}{sub}{northwest}}
\pgfpathlineto{\grid@offset{\grid@for@temp}{0cm}{add}{northwest}}
\pgfusepath{stroke}
\endpgfscope
% back plot
\ifback@plot
\def\if@back@plot{1}
\pgfscope
\pgfsetlinewidth{.5\pgflinewidth}
\pgfsetdash{{1mm}{1mm}}{0mm}
\pgfpathmoveto{\grid@offset{\grid@for@temp}{0cm}{add}{northwest}}
\pgfpathlineto{\grid@offset{\grid@for@temp}{0cm}{add}{southwest}}
\pgfpathlineto{\grid@offset{\grid@for@temp}{0cm}{sub}{southwest}}
\pgfusepath{stroke}
\endpgfscope
\fi
}
\fi
% y axis
\ifnum\grid@line@tempy>0
\foreach \grid@i in {1, ..., \grid@line@tempy}{
\pgfmathsetlengthmacro\grid@for@temp{\grid@i*\grid@ysep}
\pgfscope
\pgfsetlinewidth{.5\pgflinewidth}
\pgfpathmoveto{\grid@offset{0cm}{\grid@for@temp}{sub}{southwest}}
\pgfpathlineto{\grid@offset{0cm}{\grid@for@temp}{sub}{southeast}}
\pgfpathlineto{\grid@offset{0cm}{\grid@for@temp}{add}{southeast}}
\pgfusepath{stroke}
\endpgfscope
% back plot
\ifback@plot
\def\if@back@plot{1}
\pgfscope
\pgfsetlinewidth{.5\pgflinewidth}
\pgfsetdash{{1mm}{1mm}}{0mm}
\pgfpathmoveto{\grid@offset{0cm}{\grid@for@temp}{add}{southeast}}
\pgfpathlineto{\grid@offset{0cm}{\grid@for@temp}{add}{southwest}}
\pgfpathlineto{\grid@offset{0cm}{\grid@for@temp}{sub}{southwest}}
\pgfusepath{stroke}
\endpgfscope
\fi
}
\fi
% z axis
\ifnum\grid@line@tempz>0
\foreach \grid@i in {1, ..., \grid@line@tempz}{
\pgfmathsetlengthmacro\grid@for@temp{\grid@i*\grid@zsep}
\pgfscope
\pgfsetlinewidth{.5\pgflinewidth}
\pgfpathmoveto{\grid@offset{\grid@for@temp}{\grid@for@temp}{sub}{northwest}}
\pgfpathlineto{\grid@offset{\grid@for@temp}{\grid@for@temp}{sub}{northeast}}
\pgfpathlineto{\grid@offset{\grid@for@temp}{\grid@for@temp}{sub}{southeast}}
\pgfusepath{stroke}
\endpgfscope
% back plot
\ifback@plot
\def\if@back@plot{1}
\pgfscope
\pgfsetlinewidth{.5\pgflinewidth}
\pgfsetdash{{1mm}{1mm}}{0mm}
\pgfpathmoveto{\grid@offset{\grid@for@temp}{\grid@for@temp}{sub}{southeast}}
\pgfpathlineto{\grid@offset{\grid@for@temp}{\grid@for@temp}{sub}{southwest}}
\pgfpathlineto{\grid@offset{\grid@for@temp}{\grid@for@temp}{sub}{northwest}}
\pgfusepath{stroke}
\endpgfscope
\fi
}
\fi
\ifnum\if@back@plot=1
\back@plot@temp
\fi
}
}
\newcommand{\set@xy}[1]{%
\tikz@scan@one@point\pgfutil@firstofone(#1)\relax
}
% factor of length to z coordinate
\pgfmathsetmacro\fc@z{sqrt(2)/4}
\tikzset{
block/.code={\tikzset{/block plot/.cd, #1}
% scale
\pgfmathsetlengthmacro\scaled@xcoordinate{\block@scale*\block@xcoordinate}
\pgfmathsetlengthmacro\scaled@ycoordinate{\block@scale*\block@ycoordinate}
\pgfmathsetlengthmacro\scaled@zcoordinate{\block@scale*\block@zcoordinate}
% shift
% initial shift
\newdimen\block@xshift
\newdimen\block@yshift
\block@xshift=0pt \block@yshift=0pt
% shift in z axis
\pgfmathaddtolength\block@xshift{-\fc@z*\block@zshift}
\pgfmathaddtolength\block@yshift{-\fc@z*\block@zshift}
% pre
\ifx\block@pre\pgfutil@empty
\else
% define total xoffset and yoffset of previous and current node when
% applying alignment in different axis.
% ##1 pre, cur ##2 x, y, z axis ##3 x, y coordinate
\def\define@offset##1##2##3{
\expandafter\newdimen\csname ##1@offset@##2axis@##3\endcsname
}
% although some of them are not needed at all.
\define@offset{pre}{x}{x}
\define@offset{pre}{x}{y}% 0
\define@offset{pre}{y}{x}% 0
\define@offset{pre}{y}{y}
\define@offset{pre}{z}{x}
\define@offset{pre}{z}{y}
\define@offset{cur}{x}{x}
\define@offset{cur}{x}{y}% 0
\define@offset{cur}{y}{x}% 0
\define@offset{cur}{y}{y}
\define@offset{cur}{z}{x}
\define@offset{cur}{z}{y}
% start and end point of offset vector
\def\xaxis@start{back north west}
\def\xaxis@end{back north east}
\def\yaxis@start{back south east}
\def\yaxis@end{back north east}
\def\zaxis@start{front}
\def\zaxis@end{back}
% set total offset by coordinates.
% set offset of previous node
% ##1 x, y, z axis ##2 x, y coordinate
\def\calc@pre@shift##1##2{
\set@xy{\block@pre.\csname ##1axis@start\endcsname}
\csname pgf@##2a\endcsname=\csname pgf@##2\endcsname
\set@xy{\block@pre.\csname ##1axis@end\endcsname}
\advance \csname pgf@##2\endcsname by -\csname pgf@##2a\endcsname
\csname pre@offset@##1axis@##2\endcsname=\csname pgf@##2\endcsname
}
\calc@pre@shift{x}{x}
\calc@pre@shift{x}{y}
\calc@pre@shift{y}{x}
\calc@pre@shift{y}{y}
\calc@pre@shift{z}{x}
\calc@pre@shift{z}{y}
% set offset of current node
\pgfmathsetlength\cur@offset@xaxis@x{\scaled@xcoordinate}
\pgfmathsetlength\cur@offset@yaxis@y{\scaled@ycoordinate}
\pgfmathsetlength\cur@offset@zaxis@x{\fc@z*\scaled@zcoordinate}
\pgfmathsetlength\cur@offset@zaxis@y{\fc@z*\scaled@zcoordinate}
% \cur@offset@xaxis@x=\scaled@xcoordinate
% \cur@offset@yaxis@y=\scaled@ycoordinate
% \cur@offset@zaxis@x=\fc@z\scaled@zcoordinate
% \cur@offset@zaxis@y=\fc@z\scaled@zcoordinate
% x,y coordinates of shift vector (with factor 1)
% ##1 x, y, z axis ##2 x, y coordinate
\def\define@shift##1##2{
\expandafter\newdimen\csname shift@##1axis@##2\endcsname
}
\define@shift{x}{x}
\define@shift{x}{y}% 0
\define@shift{y}{x}% 0
\define@shift{y}{y}
\define@shift{z}{x}
\define@shift{z}{y}
% ##1 x, y, z axis ##2 x, y coordinate
\def\calc@shift##1##2{
\csname shift@##1axis@##2\endcsname=\csname pre@offset@##1axis@##2\endcsname
\advance \csname shift@##1axis@##2\endcsname by -\csname cur@offset@##1axis@##2\endcsname\relax
% \expandafter\pgfmathaddtolength\csname shift@##1axis@##2\endcsname{-\expandafter\the\csname cur@offset@##1axis@##2\endcsname}
}
\calc@shift{x}{x}
\calc@shift{x}{y}
\calc@shift{y}{x}
\calc@shift{y}{y}
\calc@shift{z}{x}
\calc@shift{z}{y}
% front of shift
\ifx\block@front\pgfutil@empty
\else
\pgfkeysalso{at=(\block@pre.front), anchor=back}
\pgfmathaddtolength\block@xshift{-\fc@z*\block@front}
\pgfmathaddtolength\block@yshift{-\fc@z*\block@front}
\fi
% align shift
% align option has higher priority
% ##1 shift style ##2 hfactor ##3 vfactor
\def\shift@style##1##2##3{
\expandafter\def\csname block@shift@##1\endcsname{
\def\block@hfactor{##2}
\def\block@vfactor{##3}
}
}
\shift@style{left}{0}{0.5}
\shift@style{right}{1}{0.5}
\shift@style{down}{0.5}{0}
\shift@style{up}{0.5}{1}
\shift@style{upperleft}{0}{1}
\shift@style{upperright}{1}{1}
\shift@style{lowerleft}{0}{0}
\shift@style{lowerright}{1}{0}
\expandafter\ifcsname block@shift@\block@align\endcsname
\csname block@shift@\block@align\endcsname
\fi
% hshift and vshift in 3 directions
\pgfmathsetmacro\real@hfactor{\block@hfactor-0.5}
\pgfmathsetmacro\real@vfactor{\block@vfactor-0.5}
% ##1 x, y, z axis ##2 hvshift 3 4 shift x, y coordinate
\def\define@hv@shift##1##2##3##4{
\expandafter\newdimen\csname hshift@##1axis@##2\endcsname
\csname hshift@##1axis@##2\endcsname=\real@hfactor\csname shift@##3axis@##2\endcsname
\expandafter\newdimen\csname vshift@##1axis@##2\endcsname
\csname vshift@##1axis@##2\endcsname=\real@vfactor\csname shift@##4axis@##2\endcsname
}
\define@hv@shift{x}{x}{z}{y}
\define@hv@shift{x}{y}{z}{y}
\define@hv@shift{y}{x}{x}{z}
\define@hv@shift{y}{y}{x}{z}
\define@hv@shift{z}{x}{x}{y}
\define@hv@shift{z}{y}{x}{y}
\advance \block@xshift by \csname hshift@\block@align@axis axis@x\endcsname
\advance \block@xshift by \csname vshift@\block@align@axis axis@x\endcsname
\advance \block@yshift by \csname hshift@\block@align@axis axis@y\endcsname
\advance \block@yshift by \csname vshift@\block@align@axis axis@y\endcsname
\fi
% general
\pgfkeysalso{
shift={(\block@xshift, \block@yshift)},
inner sep=0,
base block, draw, fill opacity=.3, thick,
minimum height=\scaled@ycoordinate,
minimum width=\scaled@xcoordinate,
}
}
}
\def\block@label@upperleft@a{front north west}
\def\block@label@upperleft@b{back north west}
\def\block@label@upperright@a{front north east}
\def\block@label@upperright@b{back north east}
\def\block@label@lowerleft@a{front south west}
\def\block@label@lowerleft@b{back south west}
\def\block@label@lowerright@a{front south east}
\def\block@label@lowerright@b{back south east}
\def\block@label@frontwest@a{front south west}
\def\block@label@frontwest@b{front north west}
\def\block@label@fronteast@a{front south east}
\def\block@label@fronteast@b{front north east}
\def\block@label@backwest@a{back south west}
\def\block@label@backwest@b{back north west}
\def\block@label@backeast@a{back south east}
\def\block@label@backeast@b{back north east}
\def\block@label@frontsouth@a{front south west}
\def\block@label@frontsouth@b{front south east}
\def\block@label@frontnorth@a{front north west}
\def\block@label@frontnorth@b{front north east}
\def\block@label@backsouth@a{back south west}
\def\block@label@backsouth@b{back south east}
\def\block@label@backnorth@a{back north west}
\def\block@label@backnorth@b{back north east}
% #1 -- label position
% #2 -- node name
% #3 -- passed string
% #4 -- label text
% #5 -- edge specification
\newcommand{\block@label}[4]{
\path (#2.\csname block@label@#3@a\endcsname) --
node[#1] {#4}
(#2.\csname block@label@#3@b\endcsname);
}
\def\block@label@position@upperleft{left}
\def\block@label@position@upperright{right}
\def\block@label@position@lowerleft{left}
\def\block@label@position@lowerright{right}
\def\block@label@position@frontwest{left}
\def\block@label@position@fronteast{right}
\def\block@label@position@backwest{left}
\def\block@label@position@backeast{right}
\def\block@label@position@frontnorth{above}
\def\block@label@position@frontsouth{below}
\def\block@label@position@backnorth{above}
\def\block@label@position@backsouth{above}
% #1 -- label position, optional
% #2 -- node name
% #3 -- passed string
% #4 -- label text
\newcommand{\blocklabel}[4][]{
\ifcsname block@label@position@#3\endcsname
% \def\block@label@position{#1}
% use default position
% \ifx\block@label@position\pgfutil@empty
\def\block@label@position{\csname block@label@position@#3\endcsname}
% \fi
\block@label{\block@label@position, #1}{#2}{#3}{#4}
\fi
}
\makeatother
\deferredanchorinstead of\anchorbut now the code is so long that I do not really understand the question.) – Nov 18 '19 at 16:15%grid anchor. And I don't find\deferredanchorinpgfmanual.pdfon my computer... – ZhiyuanLck Nov 18 '19 at 16:30\deferredanchoris no p. 1129 of pgfmanual v3.1.4. – Nov 18 '19 at 16:33pgfmoduleshapes.code.tex. – ZhiyuanLck Nov 18 '19 at 16:36xcompand its cousins. If, at a given point, both 3dtools and your package are available, then this will cause an error because these functions are already defined in3dtools. One way to avoid this would be\pgfmathdeclarefunction*`, which overwrites functions. – Nov 18 '19 at 18:21block={grid={(4,3,3)}}is excuted after some step. The key value is correct inside\anchor{...}, but when I try to get the value of the key/block plot/gridoutside\anchor{...}, it is just the initial value , i.e.\block@grid={(1,1,1)}. – ZhiyuanLck Nov 19 '19 at 00:51x/.code={\xdef\block@xcoordinate{#1}}, x=0cm,and so on. I have not tested that. Well, tested now, doesn't fix it. – Nov 19 '19 at 00:56grid/.code={\xdef\block@grid{#1}}aftergrid/.store in=\block@grid, grid={(1,1,1)}, but it doesn't work. – ZhiyuanLck Nov 19 '19 at 01:03