% \iffalse meta-comment, etc.
%%
%% Package `pst-gr3d.ins'
%%
%% Denis Girou (CNRS/IDRIS - France) <Denis.Girou@idris.fr>
%% September 16, 1998
%%
% \fi
%
% \changes{v1.2}{1998/09/16}{Standard packaging (.ins + .dtx files).}
% \changes{v1.1}{1998/03/27}{First public release.}
%
% \CheckSum{380}
%
% \DoNotIndex{\\,\^,\@}
% \DoNotIndex{\@PstGridThreeD,\@ifnextchar,\@nameuse,\@ne}
% \DoNotIndex{\advance,\begin,\catcode,\CodelineIndex,\csname}
% \DoNotIndex{\def,\define@key,\divide,\DocInput,\documentclass}
% \DoNotIndex{\edef,\else,\empty,\EnableCrossrefs,\end,\endcsname,\endinput}
% \DoNotIndex{\endpspicture,\fi,\filedate,\fileversion,\GetFileInfo}
% \DoNotIndex{\hbadness,\hfuzz,\ia,\ib,\ifnum,\ifodd,\ifx,\input,\ix,\iy,\iz}
% \DoNotIndex{\let,\m@ne,\message,\multido,\multidocount,\MultidoLoaded}
% \DoNotIndex{\multiply,\newif,\Oldmakeindex,\OnlyDescription}
% \DoNotIndex{\pnode,\ProvidesPackage,\pscircle,\psframebox,\psgrid}
% \DoNotIndex{\pspicture,\psset,\psset@offsetA,\psset@PstDebug,\psset@Rx}
% \DoNotIndex{\psset@Ry,\psset@viewpoint,\psset@XnodesepA}
% \DoNotIndex{\pst@cnta,\pst@cntb,\pst@cntc,\pst@cntd,\pst@cntg,\pst@cnth}
% \DoNotIndex{\pst@getint,\Pst@PictureYmax,\Pst@PictureYmin,\PstAtCode}
% \DoNotIndex{\PSTnodesLoaded,\PSTricksLoaded,\PSTthreeDLoaded}
% \DoNotIndex{\RecordChanges,\relax,\rput,\setkeys,\space}
% \DoNotIndex{\the,\ThreeDput,\tw@,\usepackage,\z@}
%
% \setcounter{IndexColumns}{2}
%
% \newcommand{\PstGrThreeDPackage}{`\textsf{pst-gr3d}'}
% \newcommand{\PstGridThreeDMacro}{\cs{PstGridThreeD}}
%
% ^^A From ltugboat.cls
%
% ^^A Typeset the name of an environment
% \providecommand\env[1]{\textsf{#1}}
% \providecommand\clsname[1]{\textsf{#1}}
% \providecommand\pkgname[1]{\textsf{#1}}
% \providecommand\optname[1]{\textsf{#1}}
% \providecommand\progname[1]{\textsf{#1}}
%
% ^^A A list of options for a package/class
% \newenvironment{optlist}{\begin{description}%
%   \renewcommand\makelabel[1]{%
%     \descriptionlabel{\mdseries\optname{##1}}}%
%   \itemsep0.25\itemsep}%
%  {\end{description}}
%
% ^^A Utility macros
%
%
% ^^A Example macros - adapted from the `fvrb-ex' package
% ^^A ---------------------------------------------------
%
% ^^A Take care that we use here the "W" character as comment character,
% ^^A to avoid to use an 8 bit one which can cause portability problems.
% ^^A But we can't use any more the "W" into the example environments
% ^^A of this documentation.
%
% \makeatletter
% \newcommand{\BeginExample}[1][0]{%
% \parindent=0pt
% \multiply\topsep by 2
% \VerbatimEnvironment
% \begin{VerbatimOut}[gobble=#1]{\jobname.tmp}}
%
% \newcommand{\BelowExample}[1]{%
% \VerbatimInput[gobble=4,commentchar=W,numbersep=3pt,frame=single,
%                numbers=left]{\jobname.tmp}
% \catcode`\W=9\relax%
% #1\par}
%
% \newcommand{\SideBySide@Example}[1]{%
% \@tempdimb=\FV@XRightMargin
% \advance\@tempdimb -5mm
% \vspace{2mm}
% \begin{minipage}[c]{\@tempdimb}
%   \fvset{xrightmargin=0pt}
%   \catcode`\W=9\relax%
%   #1
% \end{minipage}%
% \@tempdimb=\textwidth
% \advance\@tempdimb -\FV@XRightMargin
% \advance\@tempdimb 5mm
% \begin{minipage}[c]{\@tempdimb}
%   \VerbatimInput[commentchar=W,numbersep=3pt,frame=single,
%                  numbers=left,xleftmargin=5mm,xrightmargin=0pt]{\jobname.tmp}
% \end{minipage}
% \vspace{2mm}}
%
% \def\Example{%
% \catcode`\^^M=\active
% \@ifnextchar[{\catcode`\^^M=5\Example@}{\catcode`\^^M=5\Example@@}}
% \def\Example@[#1]{\fvset{#1}\Example@@}
% \def\Example@@{\BeginExample}
% \def\endExample{%
% \end{VerbatimOut}%
% \BelowExample{\input{\jobname.tmp}}}
%
% \def\CenterExample{%
% \catcode`\^^M=\active
% \@ifnextchar[{\catcode`\^^M=5\CenterExample@}
%              {\catcode`\^^M=5\CenterExample@@}}
% \def\CenterExample@[#1]{\fvset{#1}\CenterExample@@}
% \def\CenterExample@@{\BeginExample}
% \def\endCenterExample{%
% \end{VerbatimOut}%
% \center
% \BelowExample{\input{\jobname.tmp}}
% \endcenter}
% 
% \def\SideBySideExample{%
% \catcode`\^^M=\active
% \@ifnextchar[{\catcode`\^^M=5\SideBySideExample@}%
%              {\catcode`\^^M=5\SideBySideExample@@}}
% \def\SideBySideExample@[#1]{\fvset{#1}\SideBySideExample@@}
% \def\SideBySideExample@@{\BeginExample[4]}
% \def\endSideBySideExample{%
% \end{VerbatimOut}%
% \SideBySide@Example{\input{\jobname.tmp}}}
% \makeatother
%
% ^^A End of example macros from `fvrb-ex'
%
% ^^A For the possible index and changes log
% \setlength{\columnseprule}{0.6pt}
%
% ^^A Beginning of the documentation itself
%
% \title{The \PstGrThreeDPackage{} package\\
%        A PSTricks package for three dimensional grids}
% \author{Denis \textsc{Girou}\thanks{CNRS/IDRIS ---
%         Centre National de la Recherche Scientifique /
%         Institut du D\'eveloppement et des Ressources en Informatique
%         Scientifique --- Orsay --- France ---
%         \mbox{\texttt{<Denis.Girou@idris.fr>}}.}}
% \date{Version 1.2\\September 16, 1998\\
%       {\small Documentation revised September 16, 1998}}
%
% \maketitle
%
% \begin{abstract}
%     This package allow to draw three dimensional grids using the macro
%   \PstGridThreeDMacro. We can also specify how nodes of the grid must look
%   like.
% \end{abstract}
%
% \tableofcontents
%
% \section{Introduction}
%
%   \PstGrThreeDPackage{} offer a main unique macro with few parameters to
% interact on it. But we can also use all the relevant PSTricks parameters to
% change the size, the characteristics of lines, etc.
%
%   The syntax is simply:
% \fbox{\PstGridThreeDMacro\texttt{[optional\_parameters](X,Y,Z)}}
%
%   \vspace{1mm}
%   We can define a macro \PstGridThreeDMacro\texttt{HookNode} to specify how
% the nodes at the interconnections must look like, and there are also some
% other \emph{hooks} that can be used for special purposes.
%
%   The default viewpoint is (\texttt{1.2,-0.6,0.8}), but this can of course be
% changed using the standard way.
%
%   The package try to compute approximatively the size of the grid (the
% \texttt{pspicture} parameter, PSTricks speaking), but for three dimensional
% ones it is an impossible task to found it accurately in the general case.
% So, if the exact size is needed or if we change the viewpoint for the
% graphic, the size must be computed \emph{by hand}, using the
% \cs{psframebox[framesep=0]\{...\}} construction to found the correct values
% by attempts and errors --- in practice 5 attempts are often enough...
%
%   As parameters are managed by `keyval' mechanism (from David
% \textsc{Carlisle}), it use a special interface between the `keyval' package
% and PSTricks, done by David \textsc{Carlisle} who rewrite (better!) my
% original version.
%
% \section{Usage}
%
% \subsection{Parameters and hooks}
%
%   The three required parameters specify the lengths in the X, Y and Z
% directions, respectively:
%
% \begin{CenterExample}
%   \PstGridThreeD(4,2,2)\hfill
%   \PstGridThreeD(2,4,2)\hfill
%   \PstGridThreeD(2,2,4)
% \end{CenterExample}
%
%   Of course, we can use all the relevant generic PSTricks parameters,
% specially those applying to grids:
%
% \begin{CenterExample}
%   \PstGridThreeD[unit=1.5](2,2,2)\hfill
%   \PstGridThreeD[viewpoint=1.2 -1.5 0.4,griddots=7](2,4,3)\hfill
%   \PstGridThreeD[gridwidth=0.8mm,gridcolor=red](4,3,3)\hfill
%   \begin{pspicture}(-1.7,0)(0.8,3.6)
%     \PstGridThreeD[viewpoint=-0.4 -0.6 0.8,PstPicture=false](2,4,3)
%   \end{pspicture}
% \end{CenterExample}
%
%   We can draw one and two dimensional grids, using degenerated cases:
%
% \begin{CenterExample}
%   \PstGridThreeD(1,5,1)\hfill
%   \PstGridThreeD[linewidth=0.5mm](1,4,2)\hfill
%   \PstGridThreeD[griddots=5](4,2,1)
% \end{CenterExample}
%
%   To change the way the grids are drawn, we can also use \textbf{eight}
% specific parameters and \textbf{five} specific \emph{hooks}:
%
% \begin{optlist}
%   \item [PstPicture (boolean)]: to define or not a \texttt{pspicture}
%   environment for the grid. We have to define this parameter to \emph{false}
%   mainly if we choose a viewpoint different than the  default one --- see
%   examples later
%   (\emph{Default:~true} --- which is not the case for basic PSTricks
%   objects).
% \end{optlist}
%
% \begin{optlist}
%   \item [GridThreeDXUnit (integer)]: unit coefficient in the X direction
%   (\emph{Default:~1} --- it must be an integer, not a real).
%   \item [GridThreeDYUnit (integer)]: unit coefficient in the Y direction
%   (\emph{Default:~1} --- it must be an integer, not a real).
%   \item [GridThreeDZUnit (integer)]: unit coefficient in the Z direction
%   (\emph{Default:~1} --- it must be an integer, not a real).
% \end{optlist}
%
% \begin{CenterExample}
%   \PstGridThreeD[GridThreeDXUnit=2](2,2,2)\hfill
%   \PstGridThreeD[GridThreeDYUnit=3](2,2,2)\hfill
%   \PstGridThreeD[unit=0.5,GridThreeDZUnit=4](5,4,2)
% \end{CenterExample}
%
% \begin{optlist}
%   \item [GridThreeDXPos (integer)]: position of the origin in the X direction
%   (\emph{Default:~1} --- it must be an integer, not a real).
%   \item [GridThreeDYPos (integer)]: position of the origin in the Y direction
%   (\emph{Default:~1} --- it must be an integer, not a real).
%   \item [GridThreeDZPos (integer)]: position of the origin in the Z direction
%   (\emph{Default:~1} --- it must be an integer, not a real).
% \end{optlist}
%
%   These parameters are in fact mainly useful if we want to superpose grids,
% which can be done easily using the \cs{PstGridThreeDHookEnd} macro (see
% description below):
%
% \begin{CenterExample}
%   \renewcommand{\PstGridThreeDHookEnd}{%
%     \PstGridThreeD[PstPicture=false,gridwidth=1mm,
%                    GridThreeDXPos=2](1,3,2)}
%   \PstGridThreeD(2,4,3)\hfill
%   \renewcommand{\PstGridThreeDHookEnd}{%
%     \PstGridThreeD[PstPicture=false,gridwidth=1mm,
%                    GridThreeDYPos=2](2,3,2)}
%   \PstGridThreeD(2,4,3)\hfill
%   \renewcommand{\PstGridThreeDHookEnd}{%
%     \PstGridThreeD[PstPicture=false,gridwidth=1mm,gridcolor=green,
%                    GridThreeDYPos=3,GridThreeDZPos=2](2,2,2)}
%   \PstGridThreeD(2,4,3)
% \end{CenterExample}
%
% \begin{optlist}
%   \item [GridThreeDNodes (boolean)]: to define or not the nodes at
%   interconnection points of the grid. The nodes are named
%   \texttt{Gr3dNodeXYZ}. We can use the \texttt{Rx} and \texttt{Ry} parameters
%   to position the relevant material relatively to the nodes, specifying the
%   distance in cartesian coordinates. The parameter \texttt{angle} used with
%   \texttt{Rx} allow to use polar ones.
%   (\emph{Default:~false} --- no nodes defined).
% \end{optlist}
%
% \begin{SideBySideExample}[xrightmargin=4cm]
%   \PstGridThreeD[GridThreeDNodes=true](2,4,2)
%   \SpecialCoor
%   \rput*(Gr3dNode241){\footnotesize 241}
%   \rput*(Gr3dNode242){\footnotesize 242}
% \end{SideBySideExample}
%
% \begin{optlist}
%   \item [\cs{PstGridThreeDHookNode} (macro)]: this hook allow to define the
%   form of the nodes. A predefined \cs{PstGridThreeDNodeProcessor} macro
%   exist, which define a circle with a little white circle in it. We can also
%   use the \cs{iy} counter to differentiate the nodes according to the Y
%   faces --- but note that we can't do the same thing for the X or Z faces
%   (\emph{Default:~empty}).
% \end{optlist}
%
% \begin{CenterExample}
%   \renewcommand{\PstGridThreeDHookNode}{%
%     \begin{pspicture}(-0.15,-0.15)(0.15,0.15)
%       \pscircle*[linecolor=magenta]{0.15}
%     \end{pspicture}}
%   \PstGridThreeD(2,3,3)\hfill
%   \definecolor{LightBlue}{rgb}{0.68,0.85,0.9}
%   \renewcommand{\PstGridThreeDHookNode}{%
%     \PstGridThreeDNodeProcessor{LightBlue}}
%   \PstGridThreeD[unit=0.7](3,4,4)\hfill
%   \renewcommand{\PstGridThreeDHookNode}{%
%     \ifcase\iy
%          \PstGridThreeDNodeProcessor{magenta}
%       \or\PstGridThreeDNodeProcessor{yellow}
%       \or\PstGridThreeDNodeProcessor{cyan}
%       \else\PstGridThreeDNodeProcessor{green}
%     \fi}
%   \PstGridThreeD(2,4,2)
% \end{CenterExample}
%
% \begin{optlist}
%   \item [\cs{PstGridThreeDHookEnd} (macro)]: this hook allow to execute a
%   macro at the end of the grid drawing, before the \texttt{pspicture}
%   environment closing. This is specially interesting for instance to
%   superpose grids, if we take care to define the \texttt{PstPicture}
%   parameter to false for them 
%   (\emph{Default:~empty}).
% \end{optlist}
%
% \begin{CenterExample}
%   \renewcommand{\PstGridThreeDHookEnd}{{%
%     \psset{PstPicture=false,gridwidth=1mm}
%     {\renewcommand{\PstGridThreeDHookNode}{%
%        \PstGridThreeDNodeProcessor{blue}}
%      \PstGridThreeD[gridcolor=blue,GridThreeDZPos=4](1,8,1)}
%     {\renewcommand{\PstGridThreeDHookNode}{%
%        \PstGridThreeDNodeProcessor{red}}
%      \PstGridThreeD[gridcolor=red,
%                     GridThreeDXPos=2,GridThreeDZPos=2](1,4,2)}
%     {\renewcommand{\PstGridThreeDHookNode}{%
%        \PstGridThreeDNodeProcessor{green}}
%      \PstGridThreeD[gridcolor=green,GridThreeDYPos=7](2,2,2)}}}
%   \PstGridThreeD(2,8,4)
% \end{CenterExample}
%
% \begin{optlist}
%   \item [\cs{PstGridThreeDHookXFace} (macro)]: this hook allow to execute
%   a macro before to draw the X faces
%   (\emph{Default:~empty}).
%   \item [\cs{PstGridThreeDHookYFace} (macro)]: this hook allow to execute
%   a macro before to draw the Y faces
%   (\emph{Default:~empty}).
%   \item [\cs{PstGridThreeDHookZFace} (macro)]: this hook allow to execute
%   a macro before to draw the Z faces
%   (\emph{Default:~empty}).
% \end{optlist}
%
%   In fact, these hooks are not very powerful, because we can't control the
% order of the faces drawing as we can dream... For instance, we can't use this
% technic to draw objects with only \emph{true} visible lines. Take care also
% that for the Y faces, the direction is negative in the horizontal direction,
% so the coordinates must take this fact in account.
%
% \begin{CenterExample}
%   {\renewcommand{\PstGridThreeDHookXFace}{%
%      \ifnum\multidocount=1\psframe*[linecolor=cyan](3,2)\fi}
%    \PstGridThreeD(2,4,3)}\hfill
%   {\renewcommand{\PstGridThreeDHookYFace}{%
%      \ifnum\multidocount=2\psframe*[linecolor=yellow](-3,0)(0,2)\fi}
%   \PstGridThreeD(4,2,3)}\hfill
%   {\renewcommand{\PstGridThreeDHookZFace}{%
%      \ifnum\multidocount=2
%      \else
%        \psframe*[linecolor=yellow](3,3)
%      \fi}
%    \PstGridThreeD(4,4,3)}
% \end{CenterExample}
%
% \section{Examples}
%
%   We give here more advanced examples, most of them from technical drawings
% describing the architecture of a multiprocessors supercomputer.
%
% \begin{SideBySideExample}[xrightmargin=4cm]
%   \PstGridThreeD[GridThreeDNodes=true](3,3,3)
%   \SpecialCoor
%   \rput*(Gr3dNode113){\tiny 113}
%   \rput*(Gr3dNode332){\tiny 332}
%   \rput([Rx=0.3]Gr3dNode333){\tiny 333}
%   \multido{\i=1+1}{3}{%
%     \rput*([Rx=0.3,Ry=-0.3]Gr3dNode3\i1){3\i1}}
% \end{SideBySideExample}
%
% \begin{SideBySideExample}[xrightmargin=4cm]
%   \definecolor{LightBlue}{rgb}{0.68,0.85,0.9}
%   \renewcommand{\PstGridThreeDHookNode}{%
%     \PstGridThreeDNodeProcessor{LightBlue}}
%   \PstGridThreeD[GridThreeDNodes=true](2,3,3)
%   \SpecialCoor
%   \rput([Rx=-0.15,Ry=0.3]Gr3dNode233){%
%     \psline{<-}(0.5;35)}
%   \rput([Rx=0.35,Ry=0.8]Gr3dNode233){Network}
%   \rput([Rx=0.15,angle=-40]Gr3dNode221){%
%     \psline{<-}(0.8;-60)}
%   \rput([Rx=0.25,angle=-100]Gr3dNode231){%
%     \psline{<-}(0.8;-100)}
%   \rput([Rx=1.5,angle=-55]Gr3dNode121){Nodes}
% \end{SideBySideExample}
%
% \begin{SideBySideExample}[xrightmargin=4cm]
%   \definecolor{Orange}{rgb}{1.,0.65,0.}
%   \renewcommand{\PstGridThreeDHookNode}{%
%     \PstGridThreeDNodeProcessor{Orange}}
%   \psset{unit=1.3}
%   \PstGridThreeD[GridThreeDNodes=true](2,3,3)
%   \SpecialCoor
%   \psset{arrows=<->}
%   \ThreeDput[normal=0 0 -1](0,0,0){%
%     \ncloop[linecolor=red,arm=0.35,
%             loopsize=0.9,angleA=-90,angleB=90]
%            {Gr3dNode133}{Gr3dNode113}
%     \ncloop[linecolor=green,arm=0.7,
%             nodesepA=0.18,nodesepB=0.12,
%             loopsize=-0.5,angleA=180]
%            {Gr3dNode113}{Gr3dNode213}}
% \end{SideBySideExample}
%
% \begin{CenterExample}
%   \renewcommand{\PstGridThreeDHookEnd}{{%
%     \psset{PstPicture=false,gridwidth=1mm}
%     {\renewcommand{\PstGridThreeDHookNode}{%
%        \PstGridThreeDNodeProcessor{blue}}
%      \PstGridThreeD[gridcolor=blue,GridThreeDZPos=4](1,8,1)}
%     {\renewcommand{\PstGridThreeDHookNode}{%
%        \PstGridThreeDNodeProcessor{red}}
%      \PstGridThreeD[gridcolor=red,
%                     GridThreeDXPos=2,GridThreeDZPos=2](1,4,2)}
%     {\renewcommand{\PstGridThreeDHookNode}{%
%        \PstGridThreeDNodeProcessor{green}}
%      \PstGridThreeD[gridcolor=green,GridThreeDYPos=7](2,2,2)}}}
%   \PstGridThreeD[gridwidth=0.4mm,GridThreeDNodes=true](2,8,4)
%   \SpecialCoor
%   \rput([Rx=0.15,angle=140]Gr3dNode144){%
%     \psline[linecolor=blue]{<-}(0.8;150)}
%   \rput([Rx=0.95,angle=140]Gr3dNode144){%
%     \shortstack{1d grid\\\footnotesize (X=8,Y=1,Z=1)}}
%   \rput([Rx=0.15,angle=-50]Gr3dNode232){%
%     \psline[linecolor=red]{<-}(1.2;-50)}
%   \rput([Rx=1.5,angle=-55]Gr3dNode232){%
%     \shortstack{2d grid\\\footnotesize (X=4,Y=2,Z=1)}}
%   \rput([Rx=0.2,angle=-100]Gr3dNode271){%
%     \psline[linecolor=green]{<-}(0.8;-100)}
%   \rput([Rx=1.4,angle=-100]Gr3dNode271){%
%     \shortstack{3d grid\\\footnotesize (X=2,Y=2,Z=2)}}
% \end{CenterExample}
%
%
% \StopEventually{}
%
% ^^A .................... End of the documentation part ....................
%
% \section{Driver file}
%
%   The next bit of code contains the documentation driver file for \TeX{},
% i.e., the file that will produce the documentation you are currently
% reading. It will be extracted from this file by the \texttt{docstrip}
% program.
%
%    \begin{macrocode}
%<*driver>
\documentclass{ltxdoc}
\GetFileInfo{pst-gr3d.dtx}
\usepackage{fancyvrb}
\usepackage{pstcol}
\usepackage{pst-gr3d}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
%\OnlyDescription                % Comment it for implementation details
%\Oldmakeindex                   % Uncomment if your MakeIndex is pre-0.9
\hbadness=7000                  % Over and under full box warnings
\hfuzz=3pt
\begin{document}
  \DocInput{pst-gr3d.dtx}
\end{document}
%</driver>
%    \end{macrocode}
%%
% \section{\PstGrThreeDPackage{} \LaTeX{} wrapper}
%
%    \begin{macrocode}
%<*latex-wrapper>
\ProvidesPackage{pst-gr3d}[1998/09/16 package wrapper for PSTricks pst-gr3d.tex]
\input pst-gr3d.tex
%</latex-wrapper>
%    \end{macrocode}
%
% \section{\PstGrThreeDPackage{} code}
%
%<*pst-gr3d>
%
% \iffalse meta-comment, etc.
%% COPYRIGHT 1998, by Denis Girou, <Denis.Girou@idris.fr>
%%
%% DESCRIPTION:
%%   `pst-gr3d' is PSTricks package to draw three dimensional grids
%%   with various customizations.
%%
% \fi
%
% \subsection{Preambule}
%
%   Who we are:
%
%    \begin{macrocode}
\def\fileversion{1.2}
\def\filedate{98/09/16}
\message{`PST-Grids3d v\fileversion, \filedate\space (Denis Girou)}
\csname PSTGridsThreeD\endcsname
\let\PSTGridsThreeD\endinput
%    \end{macrocode}
%
%   Require PSTricks, pst-node, pst-3d and multido packages:
%
%    \begin{macrocode}
\ifx\PSTricksLoaded\endinput\else\input pstricks.tex\fi
\ifx\PSTnodesLoaded\endinput\else\input pst-node.tex\fi
\ifx\PSTthreeDLoaded\endinput\else\input pst-3d.tex\fi
\ifx\MultidoLoaded\endinput\else\input multido.tex\fi
%    \end{macrocode}
%
%   DPC interface to the `\textsc{keyval'} package (until keyval based version
% of PSTricks):
%
%    \begin{macrocode}
\input pst-key.tex
%    \end{macrocode}
%
%   Catcodes changes:
%
%    \begin{macrocode}
\edef\PstAtCode{\the\catcode`\@}
\catcode`\@=11\relax
%    \end{macrocode}
%
% \subsection{Definition of the parameters}
%
%   For debugging (to debug, set \texttt{PstDebug=1})
%
%    \begin{macrocode}
\def\psset@PstDebug#1{\pst@getint{#1}\psk@PstDebug}
%    \end{macrocode}
%
%   ``\texttt{pspicture}'' environment or not?
%
%    \begin{macrocode}
\newif\ifPst@PstPicture
\define@key{psset}{PstPicture}[true]{\@nameuse{Pst@PstPicture#1}}
%    \end{macrocode}
%
%   Defining nodes?
%
%    \begin{macrocode}
\newif\ifPst@GridThreeDNodes
\define@key{psset}{GridThreeDNodes}[true]{\@nameuse{Pst@GridThreeDNodes#1}}
%    \end{macrocode}
%
%   X, Y and Z units (must be integers):
%
%    \begin{macrocode}
\define@key{psset}{GridThreeDXUnit}{%
\pst@cntg=#1\relax
\edef\psk@GridThreeDXUnit{\the\pst@cntg}}
\define@key{psset}{GridThreeDYUnit}{%
\pst@cntg=#1\relax
\edef\psk@GridThreeDYUnit{\the\pst@cntg}}
\define@key{psset}{GridThreeDZUnit}{%
\pst@cntg=#1\relax
\edef\psk@GridThreeDZUnit{\the\pst@cntg}}
%    \end{macrocode}
%
%   X, Y and Z positions:
%
%    \begin{macrocode}
\define@key{psset}{GridThreeDXPos}{%
\pst@cntg=#1\relax
\edef\psk@GridThreeDXPos{\the\pst@cntg}}
\define@key{psset}{GridThreeDYPos}{%
\pst@cntg=#1\relax
\edef\psk@GridThreeDYPos{\the\pst@cntg}}
\define@key{psset}{GridThreeDZPos}{%
\pst@cntg=#1\relax
\edef\psk@GridThreeDZPos{\the\pst@cntg}}
%    \end{macrocode}
%
%   Aliases for relative moves from nodes:
%
%    \begin{macrocode}
\def\psset@Rx#1{\psset@XnodesepA{#1}}
\def\psset@Ry#1{\psset@offsetA{#1}}
%    \end{macrocode}
%
%   Default values (including \texttt{viewpoint} first):
%
%    \begin{macrocode}
\psset@viewpoint{1.2 -0.6 0.8}
\setkeys{psset}{%
PstDebug=0,PstPicture=true,GridThreeDNodes=false,
GridThreeDXPos=1,GridThreeDYPos=1,GridThreeDZPos=1,
GridThreeDXUnit=1,GridThreeDYUnit=1,GridThreeDZUnit=1}
%    \end{macrocode}
%
% \subsection{Main macro}
%
%   The general macro to draw three dimensional grids:
%
% \begin{macro}{\PstGridThreeD}
%    \begin{macrocode}
\def\PstGridThreeD{%
\@ifnextchar[\@PstGridThreeD{\@PstGridThreeD[]}}
\def\@PstGridThreeD[#1](#2,#3,#4){{%
\psset{dimen=middle}%
\setkeys{psset}{#1}%
%    \end{macrocode}
%
%   First, we try to compute rather accurate values for the
% ``\texttt{pspicture}'' environment (it is not possible to found them in the
% general case, so you must define your own ones, setting \texttt{PstPicture}
% to false before, if the ones automatically computed here are really wrong in
% your case...)
%
%   Ymin pspicture value:
%
%    \begin{macrocode}
\pst@cnta=#2
\advance\pst@cnta\m@ne
\pst@cnth=\pst@cnta
\multiply\pst@cnth\psk@GridThreeDXUnit
\divide\pst@cnth\tw@
\ifodd\pst@cnth
  \edef\Pst@PictureYmin{-\the\pst@cnth}%
\else
  \edef\Pst@PictureYmin{-\the\pst@cnth.5}%
\fi
%    \end{macrocode}
%
%   \cs{pst@cntb} and \cs{pst@cntc} will be used also in loops.
%
%    \begin{macrocode}
\pst@cntb=#3
\advance\pst@cntb\m@ne
\pst@cntc=#4
\advance\pst@cntc\m@ne
%    \end{macrocode}
%
%   Xmax pspicture value (stored in \cs{pst@cntg}):
%
%    \begin{macrocode}
\pst@cntg=\pst@cntb
\multiply\pst@cntg\psk@GridThreeDYUnit
\divide\pst@cnta\tw@
\pst@cnth=\pst@cnta
\multiply\pst@cnth\psk@GridThreeDXUnit
\advance\pst@cntg\pst@cnth
%    \end{macrocode}
%
%   Ymax pspicture value:
%
%    \begin{macrocode}
\pst@cnth=\pst@cntb
\advance\pst@cnth\m@ne
\multiply\pst@cnth\psk@GridThreeDYUnit
\divide\pst@cnth\tw@
\pst@cntd=\pst@cntc
\multiply\pst@cntd\psk@GridThreeDZUnit
\advance\pst@cntd\pst@cnth
\ifnum\pst@cnth=\z@
  \edef\Pst@PictureYmax{\the\pst@cntd.5}%
\else
  \edef\Pst@PictureYmax{\the\pst@cntd}%
\fi
%    \end{macrocode}
%
%   If required, the pspicture environment:
%
%    \begin{macrocode}
\ifPst@PstPicture
%    \end{macrocode}
%
%   If \texttt{PstDebug=1}, we draw a framed box around the grid:
%
%    \begin{macrocode}
  \ifnum\psk@PstDebug>\z@
    \psframebox[framesep=0]{%
  \fi
  \pspicture(0,\Pst@PictureYmin)(\the\pst@cntg,\Pst@PictureYmax)
\fi
\pst@cntd=\psk@GridThreeDXPos
\advance\pst@cntd\m@ne
\multiply\pst@cntd\psk@GridThreeDXUnit
\pst@cntg=\psk@GridThreeDYPos
\advance\pst@cntg\m@ne
\multiply\pst@cntg\psk@GridThreeDYUnit
\pst@cnth=\psk@GridThreeDZPos
\advance\pst@cnth\m@ne
\multiply\pst@cnth\psk@GridThreeDZUnit
%    \end{macrocode}
%
%   Z faces (only if \cs{PstGridThreeDHookZFace} is defined):
%
%    \begin{macrocode}
\ifx\PstGridThreeDHookZFace\empty
\else
  \multido{\iz=\pst@cntc+-\psk@GridThreeDZUnit}{#4}{% Z face hook
    \ThreeDput[normal=0 0 1](\pst@cntd,\pst@cntg,\iz){\PstGridThreeDHookZFace}}
\fi
%    \end{macrocode}
%
%   X faces:
%
%    \begin{macrocode}
\multido{\ix=\pst@cntd+\psk@GridThreeDXUnit}{#2}{%
  \ThreeDput[normal=1 0 0](\ix,\pst@cntg,\pst@cnth){%
%    \end{macrocode}
%
%   with an X face hook:
%
%    \begin{macrocode}
    \PstGridThreeDHookXFace
    \psgrid[xunit=\psk@GridThreeDYUnit,yunit=\psk@GridThreeDZUnit,
            subgriddiv=0,gridlabels=0](\pst@cntb,\pst@cntc)}}
%    \end{macrocode}
%
%   Y faces:
%
%    \begin{macrocode}
\pst@cnta=#3
\advance\pst@cnta\m@ne
\multiply\pst@cnta\psk@GridThreeDYUnit
\advance\pst@cnta\pst@cntg
\multido{\iy=\pst@cnta+-\psk@GridThreeDYUnit}{#3}{%
  \ThreeDput[normal=0 1 0](\pst@cntd,\iy,\pst@cnth){%
    \PstGridThreeDYFace{#2}{#4}{\iy}}}
%    \end{macrocode}
%
%   Hook at the end, if defined:
%
%    \begin{macrocode}
\PstGridThreeD@HookEnd
%    \end{macrocode}
%
%   End of the ``\texttt{pspicture}'' environment, if defined:
%
%    \begin{macrocode}

\ifPst@PstPicture
  \endpspicture
  \ifnum\psk@PstDebug>\z@
%    \end{macrocode}
%
%   End \cs{psframebox}
%
%    \begin{macrocode}
    }
  \fi
\fi}}
%    \end{macrocode}
% \end{macro}
%
%   One face of the three dimensional grid:
%
% \begin{macro}{\PstGridThreeDYFace}
%    \begin{macrocode}
\def\PstGridThreeDYFace#1#2#3{%
\pst@cnta=#1
\advance\pst@cnta\m@ne
\pst@cntb=#2
\advance\pst@cntb\m@ne
%    \end{macrocode}
%
%   Vertical faces.
%
%   First, Y face hook:
%
%    \begin{macrocode}
\PstGridThreeDHookYFace%
\psgrid[xunit=\psk@GridThreeDXUnit,yunit=\psk@GridThreeDZUnit,
        subgriddiv=0,gridlabels=0](-\pst@cnta,\pst@cntb)
\pst@cntg=#3%
\advance\pst@cntg\@ne
\multido{\ia=0+-\psk@GridThreeDXUnit}{#1}{%
  \pst@cnth=\multidocount
  \multido{\ib=0+\psk@GridThreeDZUnit}{#2}{%
%    \end{macrocode}
%
%   Nodes definition:
%
%    \begin{macrocode}
    \ifPst@GridThreeDNodes
      \pnode(\ia,\ib){Gr3dNode\the\pst@cnth\the\pst@cntg\the\multidocount}
    \fi
    \ifx\PstGridThreeDHookNode\empty
    \else
%    \end{macrocode}
%
%   Nodes drawing:
%
%    \begin{macrocode}
      \rput(\ia,\ib){\PstGridThreeDHookNode}
    \fi}}}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Default hooks (empty)}
%
% \begin{macro}{\PstGridThreeDHookNode}
%    \begin{macrocode}
\def\PstGridThreeDHookNode{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\PstGridThreeDHookXFace}
%    \begin{macrocode}
\def\PstGridThreeDHookXFace{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\PstGridThreeDHookYFace}
%    \begin{macrocode}
\def\PstGridThreeDHookYFace{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\PstGridThreeDHookZFace}
%    \begin{macrocode}
\def\PstGridThreeDHookZFace{}
%    \end{macrocode}
% \end{macro}
%
%   For the end hook, we must avoid infinite recursion if the hook contain
% a \cs{PstGridThreeD} macro!
%
% \begin{macro}{\PstGridThreeDHookEnd}
%    \begin{macrocode}
\def\PstGridThreeDHookEnd{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\PstGridThreeD@HookEnd}
%    \begin{macrocode}
\def\PstGridThreeD@HookEnd{%
\def\PstGridThreeD@HookEnd{}%
\PstGridThreeDHookEnd}
%    \end{macrocode}
% \end{macro}
%
%   Default definition of a processor node:
%
% \begin{macro}{\PstGridThreeDNodeProcessor}
%    \begin{macrocode}
\def\PstGridThreeDNodeProcessor#1{%
\psset{unit=0.3}
\pspicture(-0.5,-0.5)(0.5,0.5)
  \pscircle*[linecolor=#1]{0.5}
  \pscircle*[linecolor=white]{0.2}
\endpspicture}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Closing}
%
%   Catcodes restoration:
%
%    \begin{macrocode}
\catcode`\@=\PstAtCode\relax
%    \end{macrocode}
%
%</pst-gr3d>
%
% \Finale
% \PrintIndex
% \PrintChanges
%
\endinput
%% 
%% End of file `pst-gr3d.dtx'
