It can be done, but requires some (perhaps unadvisable) hacking.
Forest typesets all nodes using PGF's deferred node positioning mechanism (\pgfpositionnodelater
-- pgfpositionnodenow
, see section 107.2.3 of the PGF manual). Using this mechanism, it is possible to typeset the node first (in a box) and position it (anywhere) later. Forest clearly needs (some) such procedure, because it must compute the outlines of the nodes before it can pack them into a tree.
It is two features of the deferred node positioning which conspire to make the normal reference to the PGF/TikZ nodes within these nodes impossible. First, when a deferred node is created, its name is prefixed by not yet positionedPGFINTERNAL
. Second, while the content of a deferred node is typeset, deferred positioning (\ifpgflatenodepositioning
) is in effect and applies to any nodes within the content. In effect, the name of any node (and this includes coordinate
s) within a deferred node (and thus within any Forest node) is prefixed by not yet positionedPGFINTERNAL
.
So in principle, it is possible to refer to nodes within Forest nodes, by manually prefixing them with not yet positionedPGFINTERNAL
, but with a caveat: the coordinates of these inner nodes are relative to the origin of the Forest node. The following code demostrates both. (Look at the final two lines and the definition of \nyp
, the rest is as in the OPs code.)
\documentclass{article}
\usepackage{forest}
\usetikzlibrary{matrix}
\makeatletter
\tikzset{
test n/.store in=\test@n,
test n=3,
pics/test/.style={code={
\tikzset{test/.cd,#1}%
\foreach \x [evaluate=\x as \ang using (\x-1)*360/\test@n] in {1, ..., \test@n} {
{\draw (0, 0) -- (\ang:5mm) coordinate (-\x);}
\pgfkeys{/tikz/test/extra}
}
}},test/.cd,extra/.code={}
}
\makeatother
\begin{document}
\def\nyp{not yet positionedPGFINTERNAL}
\begin{forest}
[pft
[{\pic (a6) [test n=6] {test};\\},matrix,name=matrix6]
[{\pic (a5) [test n=5] {test};\\},matrix,name=matrix5]
]
\fill[red] (matrix6) + (\nyp a6-2) circle [radius=2pt];
\fill[blue] (matrix5) + (\nyp a5-2) circle [radius=2pt];
\end{forest}
\end{document}
Now I don't know nearly enough about PGF/TikZ internals to be able to judge whether \ifpgflatenodepositioning
remaining true when the content of a deferred node is typeset is a feature or a bug. I played a bit and switched it off (\pgflatenodepositioningfalse\pic ...
or even \pgfpositionnodelater{\relax}\pic ...
), and I could then refer to the inner nodes as (a6-2)
and (a5-2)
— but their positions were not the same as above, they seem to be shifted by an offset I can't figure out.
(Only after I already wrote the above I noticed that the blue dot comes a bit off even in the above code. So apparently, some weird shift happens even without the attempt to switch off deferred positioning inside the node.)
If you wanted the normal access to the inner nodes, it is of course possible to precompute them, e.g. like this:
\documentclass{article}
\usepackage{forest}
\usetikzlibrary{matrix}
\makeatletter
\tikzset{
test n/.store in=\test@n,
test n=3,
pics/test/.style={code={
\tikzset{test/.cd,#1}%
\foreach \x [evaluate=\x as \ang using (\x-1)*360/\test@n] in {1, ..., \test@n} {
{\draw (0, 0) -- (\ang:5mm) coordinate (-\x);}
\pgfkeys{/tikz/test/extra}
}
}},test/.cd,extra/.code={}
}
\makeatother
\begin{document}
\def\nyp{not yet positionedPGFINTERNAL}
\begin{forest}
[pft
[{\pic (a6) [test n=6] {test};\\},matrix,name=matrix6]
[{\pic (a5) [test n=5] {test};\\},matrix,name=matrix5]
]
\path
foreach \mn in {6,5} {
(matrix\mn)
foreach \tn in {1,...,5} {
+ (\nyp a\mn-\tn)
coordinate(a\mn-\tn)
}
}
;
\fill[red] (a6-2) circle [radius=2pt];
\fill[blue] (a5-2) circle [radius=2pt];
\end{forest}
\end{document}
It might be also possible automatically collect the names of the inner nodes (by hacking into \pgfmultipartnode
, \pgfcoordinate
etc) and perform the above "\nyp prefix stripping" automatically. But I'd say that's too hacky even for my taste, plus there's still the issue of the mysterious shift, which possibly makes this entire answer completely useless. ;-)
tikzcshack=false
I was not able to come up with a nice, working solution. In the past, some users have used the\subnode
command from thetikzmark
library, which does not get "hacked", but this probably won't lead to a very elegant solution of the "access pic coordinates from outside" problem in this context. That is, I do not know how many users besides Sašo Zivanović and cfr will be able to give a nice answer here.forest cs
and the hack which makes it possible to use it implicitly (e.g. simply!u
for the parent node, instead of(forest cs:!u)
) are actually unrelated to the issue.